• 中午吃饭之前同事问我如何在redis中批量删除一些内容,聊着聊着就聊到了redis的pipeline(管道)的功能。这个功能在redis的命令行中没有,但是redis却是支持pipeline,而且在各个语言版本的client中都有相应的实现。

    pipeline我们在linux使用中是经常会碰到的,比如 ps -ef|grep python这样查看当前python进程情况的命令,在redis中使用基本原理也是一样。pipeline让我们可以一次性将多条命令直接交给redis来执行,然后一次性返回所有操作的结果。当我们需要批量读写redis的时候,它能够帮我们提高程序的效率。下面我就写了一个python脚本来简单的测试比较一下使用和没有使用pipeline的差别。

    Python代码 
    1. #!/usr/bin/env python  
    2. import redis  
    3. import time  
    4.   
    5. def without_pipeline():  
    6.     r = redis.Redis()  
    7.     for i in range(10000):  
    8.         r.ping()  
    9.   
    10.     return  
    11.   
    12. def with_pipeline():  
    13.     r = redis.Redis()  
    14.     pipeline = r.pipeline()  
    15.     for i in range(10000):  
    16.         pipeline.ping()  
    17.   
    18.     pipeline.execute()  
    19.     return  
    20.   
    21. def bench(desc):  
    22.     start = time.clock()  
    23.     desc()  
    24.     stop =time.clock()  
    25.     diff = stop - start  
    26.     print("%s has token %s"%(desc.func_name,str(diff)))  
    27.   
    28. if __name__=='__main__':  
    29.     bench(without_pipeline)  
    30.     bench(with_pipeline)   

    最后执行结果如下,使用pipeline之后,基本上能够提高一倍的效率(当然,这个仅仅只是一个简单的测试,结果仅作参考):

    without_pipeline has token 0.537095

    with_pipeline has token 0.221126

  • 在实际的工作中我们经常会用到Linux的Shell脚本或者其他的脚本语言来帮助我们更好的完成工作,但是有时候,我们也会碰到一些很古怪的问题。比如,下面这样的问题:

    我写了一个python的脚本,来求两个集合的差集,但是执行的时候发现报错了。

    tonydeng@nexus-service:statisticus $ ./difference_set.py
    : 没有该文件或目录on

    通过file的比较,发现这个不能执行的python脚本和其他可以执行的python有些区别。

    tonydeng@nexus-service:statisticus $ file difference_set.py
    difference_set.py: a python\015 script text executable
    tonydeng@nexus-service:statisticus$ file act_diff.py
    act_diff.py: a python script text executable

    经过请教google大神,原来是由于保存文件时的格式不是unix的问题。

    要将其转化成unix格式也很容易,下面有两条很简单的方法:

    1. 修改文件: sed -i 's/\r$//' WikidPad.py
    2. vim打开文件后,命令模式执行 :set ff=unix  , 然后保存就行了.

    由于我比较喜欢使用Sublime Text作为编辑器使用,那么就需要研究一下如何设置Sublime Text保存时的格式为unix。

    修改Sublime Text的Default File Type.sublime-options配置,将system改成unix就可以了。
    #defaultLineEnding system
    defaultLineEnding unix

  • 在实际的项目中,我们经常会碰到这样的需求:“通过执行某条命令搞定一些的事情”。


    如果开发人员比较擅长一些脚本语言,那么很幸运,他可以直接写好脚本,然后直接在命令行执行就好了。

    如果开发人员恰好只擅长一些静态语言,比如Java、C......,也可以借助一些工具来生成最终可以执行的文件,然后直接在命令行中调用就好了。

    那 这样看来,好像没有什么难的事情。的确,如果事情仅仅只是这样,当然比较简单,关键问题是经常开发环境与测试环境还有生产环境往往不是完全一样。那么我们 需要经常在不同的环境下更改配置来达到当前环境的要求,这样一来,需要手工操作的事情就比较多了,尤其是在测试与多方联调时,部署的人员肯定要骂人了。

    好吧,说了这么多废话,我们现在开始正式面对这样的问题并且用一种相对优雅的方式来解决它吧。


    假设,我们现在使用Java来做这件事情。那我们会按照迭代的方式来慢慢来做。

    首 先我们先做一个可以执行的jar。这个比较简单,大部分的程序员都可以直接使用自己的IDE来直接将项目导出成一个可以执行的jar。但是现在已经不是一 个人就可以完成所有事情的时代,在注重团队配合的年代,我们当然要选择一种不依赖开发人员个人环境的方式来完成这件事情。很庆幸,我们有maven 。我们可以在maven中很轻易的完成这样的事情,同时也不会依赖某个人的环境。

    我们需要在pom.xml中加上下面的配置就OK了。

    Java代码  收藏代码
    1. <plugin>   
    2.      <artifactId>maven-assembly-plugin</artifactId>   
    3.      <version>2.2 -beta- 5 </version>   
    4.      <configuration>   
    5.           <archive>  
    6.                <manifest>  
    7.                     <mainClass>com.wolf.Process</mainClass>  
    8.                </manifest>  
    9.           </archive>  
    10.           <descriptorRefs>   
    11.                <descriptorRef>jar-with-dependencies</descriptorRef>   
    12.           </descriptorRefs>   
    13.      </configuration>   
    14. </plugin>  
     
    OK,根据上面的配置,我们可以很轻易的使用 mvn:assembly:assembly 这个命令得到一个可以执行的jar,并且这个jar中还会将这个项目说要依赖的第三方的jar都打到这个jar中,我们可以直接使用java -jar xxxx.jar来执行我们指定的代码了。

    如果,我们需要在生成这个可执行的jar的事情做一些更加个性化的东西应该怎么办呢?比如,项目中需要依赖spring,但是这样直接生成的 jar在执行的时候,却报一个schema namespace的错误,原因是自动生成的jar中的META-INF目录中包含的spring-schemas和spring-handlers文件 缺少一些我们需要的schema的定义和解析方式。那其实也很好解决,我们可以指定assembly.xml让maven 帮我们处理这个问题。具体配置如下:

    Java代码  收藏代码
    1. pom.xml  
    2.   
    3. <build>  
    4.      <plugins>  
    5.           <plugin>  
    6.                <artifactId>maven-assembly-plugin</artifactId>  
    7.                <configuration>  
    8.                     <archive>  
    9.                          <manifest>  
    10.                               <mainClass>com.wolf.Process</mainClass>  
    11.                          </manifest>  
    12.                     </archive>  
    13.                     <descriptors>  
    14.                          <descriptor>src/main/resources/META-INF/assemble.xml</descriptor>  
    15.                     </descriptors>  
    16.                </configuration>  
    17.           </plugin>  
    18.      </plugins>  
    19. </build>  
    20.   
    21.   
    22. assemble.xml  
    23.   
    24. <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"   
    25.           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    26.           xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd" >  
    27.     <id>jar-with-dependencies</id>  
    28.     <formats>  
    29.         <format>jar</format>  
    30.     </formats>  
    31.     <includeBaseDirectory>false </includeBaseDirectory>  
    32.     <dependencySets>  
    33.         <dependencySet>  
    34.             <outputDirectory>/</outputDirectory>  
    35.             <unpack>true </unpack>  
    36.             <unpackOptions>  
    37.                 <excludes>  
    38.                     <exclude>META-INF/spring.handlers</exclude>  
    39.                     <exclude>META-INF/spring.schemas</exclude>  
    40.                 </excludes>  
    41.             </unpackOptions>  
    42.             <scope>runtime</scope>  
    43.         </dependencySet>  
    44.     </dependencySets>  
    45.     <files>  
    46.         <file>  
    47.             <source>src/main/resources/META-INF/spring.handlers</source>  
    48.             <outputDirectory>META-INF</outputDirectory>  
    49.         </file>  
    50.         <file>  
    51.             <source>src/main/resources/META-INF/spring.schemas</source>  
    52.             <outputDirectory>META-INF</outputDirectory>  
    53.         </file>  
    54.     </files>  
    55. </assembly>  
     
    现在我们第一个需求解决了,可以用一种通用的方式来生成一个可以执行的jar,那么我们接下来要解决的是另外一个问题,如何生成指定目标环境的jar。

    其实也很简单,我们只要引入maven 的profile配置就可以了。具体配置如下:

    Java代码  收藏代码
    1. pom.xml  
    2.   
    3. <profiles>  
    4.      <profile>  
    5.           <id>windows</id>  
    6.           <build>  
    7.                <plugins>  
    8.                     <plugin>  
    9.                          <artifactId>maven-assembly-plugin</artifactId>  
    10.                          <configuration>  
    11.                               <descriptors>  
    12.                                    <descriptor>src/main/resources/META-INF/assemble-linux.xml</descriptor>  
    13.                               </descriptors>  
    14.                          </configuration>  
    15.                     </plugin>  
    16.                </plugins>  
    17.           </build>  
    18.           <activation>  
    19.                <property><name>windows</name></property>  
    20.           </activation>  
    21.      </profile>  
    22.      <profile>  
    23.           <id>linux</id>  
    24.           <build>  
    25.                <plugins>  
    26.                     <plugin>  
    27.                          <artifactId>maven-assembly-plugin</artifactId>  
    28.                          <configuration>  
    29.                               <descriptors>  
    30.                                    <descriptor>src/main/resources/META-INF/assemble-linux.xml</descriptor>  
    31.                               </descriptors>  
    32.                          </configuration>  
    33.                     </plugin>  
    34.                </plugins>  
    35.           </build>  
    36.           <activation>  
    37.                <property><name>linux</name></property>  
    38.           </activation>  
    39.      </profile>  
    40. </profiles>  
     

    这样,我们只要执行mvn -Dwindwos assembly:assembly 或者 mvn -Dlinux assembly:assembly 就可以生成指定目标环境的可执行的jar了。

    PS:如果你想不同目标环境jar的名字不同,我们可以在相应的assemble.xml文件中更改那个id的值就可以了。
  • 2011-05-07

    MessagePack研究 - [developer]

    MessagePack简称msgpack,官方网站是http://msgpack.org/ ,代码可以在github上查看 https://github.com/msgpack。

    官方介绍是“Extremely efficient object serialization library for cross-language communication.It's like JSON, but very fast and small.”,是一种跨语言的基于二进制的数据格式。从官方的介绍来看,它能够比google protocol buffers快4倍,比json快10倍多。

    比较还是Java出身的,所以在使用的时候,还是最新选择用Java的版本。用maven创建了一个msgpack-demo的项目,然后在pom.xml中加入相应的依赖和仓库,就可以直接使用了。

    <dependency>
         <groupId>org.msgpack</groupId>
    <artifactId>msgpack</artifactId>
          <version>0.5.2-devel</version>
    </dependency>
    
    <repository>
         <id>msgpack.org</id>
         <name>MessagePack Repository for Maven</name>
         <url>http://msgpack.org/maven2</url>
    </repository>
    
    public class SampleTest {
      @MessagePackMessage
      public static class MyClassVersion1{
        public String name;
        @Nullable
        public String nickName;
      }
      @MessagePackMessage
      public static class MyClassVersion2{
        public String name;
        @Nullable
        public String nickName;
        @Optional
        public int age = -1;
      }
      @MessagePackMessage
      public static class MyClassVersion3{
        public String name;
        @Nullable
        public String nickName;
        public int age = -1;
        @Optional
        public String school;
      }
      @Test
      public void testBackwardCompatibility(){
        MyClassVersion1 v1 = new MyClassVersion1();
        v1.name = "Tao Deng";
        v1.nickName = "Tony";
    
        byte[] bytes = MessagePack.pack(v1);
    
        MyClassVersion2 v2 = MessagePack.unpack(bytes,MyClassVersion2.class);
        assertEquals(v1.name, v2.name);
        assertEquals(v1.nickName, v2.nickName);
        assertEquals(v2.age, -1);
      }
    
      @Test
      public void testForwardCompatibility() throws Exception {
        MyClassVersion2 v2 = new MyClassVersion2();
        v2.name = "Tao Deng";
        v2.nickName = "Tony";
        v2.age = 31;
    
        byte[] bytes = MessagePack.pack(v2);
    
        MyClassVersion1 v1 = MessagePack.unpack(bytes, MyClassVersion1.class);
    
        assertEquals(v2.name, v1.name);
        assertEquals(v2.nickName, v1.nickName);
      }
    
      @Test
      public void testNullFields01() throws Exception {
        MyClassVersion1 src = new MyClassVersion1();
        src.name = "Tao Deng";
        src.nickName = null;
    
        byte[] bytes = MessagePack.pack(src);
    
        MyClassVersion1 dst = MessagePack.unpack(bytes, MyClassVersion1.class);
    
        assertEquals(dst.name, src.name);
        assertEquals(dst.nickName, src.nickName);
      }
    
      @Test
      public void testNullFields02() throws Exception {
        MyClassVersion1 src = new MyClassVersion1();
        src.name = null;
        src.nickName = "Tony";
    
        try {
          byte[] bytes = MessagePack.pack(src);
        } catch (Exception e) {
          assertTrue(true);
          return;
        }
        assertTrue(false);
      }
    
      @Test
      public void testNullFields03() throws Exception {
        List<String> src = new ArrayList<String>();
        src.add(null);
        src.add("Tony");
    
        byte[] bytes = MessagePack.pack(src);
    
        try {
          MyClassVersion1 dst = MessagePack.unpack(bytes, MyClassVersion1.class);
        } catch (Exception e) {
          assertTrue(true);
          return;
        }
        assertTrue(false);
      }
    
      @Test
      public void testNullFields04() throws Exception {
        MyClassVersion3 src = new MyClassVersion3();
        src.name = "Tao Deng";
        src.nickName = null;
        src.age = 23;
        src.school = null;
    
        byte[] bytes = MessagePack.pack(src);
    
        MyClassVersion3 dst = MessagePack.unpack(bytes, MyClassVersion3.class);
    
        assertEquals(dst.name, src.name);
        assertEquals(dst.nickName, src.nickName);
      }
    }
    

    写了一个简单的test来看看msgpack的一些特点,发现在java中使用还是比较方便的,只要在class上加入 @MessagePackMessage这样的Annotaions就可以了。另外,如果你对class中有些属性有特别的要求的话,可以通过别的 Annotaions来标识。比如@Nullable、@Optional。

    在Java中简单试验完了之后,然后又选择了Python作为我的第二个突破口来测试。在python中使用msgpack也非常简单,只要你安装了msgpack这个模块就可以直接import进来使用了。

    你可以用easy_install python来直接安装,也可以下载msgpack模块自己通过python setup.py install来安装。

    由于我之前通过java在redis里面set了一个key为img_key的msgpack序列化的对象,现在我通过python在redis将这个key的值get出来,然后unpack回真实的数据。

    >>> import redis,msgpack #引入redis与msgpack模块
    >>> r=redis.Redis(host="192.168.1.52") #设置redis的服务器
    >>> print msgpack.unpackb(r.get('img_key')) #在终端打印get img_key的value并且反序列化的值
    ('msgPack', 100.0, 10)
    >>> print msgpack.unpackb(r.get('img_key'))
    ('msgPack', 10, 100.0)  //在Java中调整了model属性的顺序
    >>> print msgpack.unpackb(r.get('img_key'))
    ('msgPack', None, 100.0) //在Java中设置属性的可以为空,并且没有给该属性赋值
    >>> r.set('img_key',msgpack.packb(('msgPack123', 20, 100.0)))  #在python中通过msgpack序列化一个数据结构,并且set到redis
    True     //redis返回set的状态
    >>> print msgpack.unpackb(r.get('img_key'))   #在终端中打印刚才set的序列化的值并且反序列化
    ('msgPack123', 20, 100.0)
    

    刚才在python中序列化好的值,在java也能够正常的反序列化回来。

    从刚才的试验中,发现几个需要注意的地方。
    1.msgpack的序列化和反序列化都是通过数据结构中的value的顺序来进行定位的,和其他的数据结构有些不一样,比如json和xml都是有key和value来定义。
    2.第一条已经描述了原因,那么我们在不同项目中使用不同语言定义的数据结构就需要保证结构顺序的一致性。
    3.现在msgpack只能支持基本的数据类型,支持list和map,但是自定义的数据结构就是一个问题了。

    与JSON的比较
    优势:
    1.序列化和反序列化所需要的时间少。通过30000条的记录来测试,msgpack序列化的时间比使用jason来序列化JSON的时间要少三分之一;而反序列化的时间则要少一半。
    2.生成的文件体积小。同样也是基于30000条记录来测试,msgpack序列化后生成的二进制文件比用jason序列化出来的时间要少一半。

    劣势:
    1.msgpack对复杂的数据类型(List、Map)支持的不够,序列化没有问题,但是反序列化回来就很麻烦,尤其是对于java开发人员。
    2.在上面也提到过,msgpack是通过value的顺序来定位属性的,那么需要在不同的语言中都要维护同样的模型以及模型中属性的顺序。这个会让开发人员很困扰。
    3.msgpack无法支持在模型中包含和嵌套其他自定义的模型(如weibo模型中包含comment的列表)。

  • 2011-04-01

    浮夸 - [share]

    这首《浮夸》是Eason在2005年《U87》专辑中的一首经典粤语歌曲,我非常喜欢。后来又有多为歌手来翻唱这首歌曲,不过总觉得唱的不如Eason那么直入人心。

    这首歌的歌词写的非常棒,一句句的词就像敲击着你的心一样,让你不由得陷入这首歌里面。

    《U87》

    《DUO 陈奕迅2010演唱会》

    有人问我我就会讲
    但是无人来
    我期待到无奈
    有话要讲得不到装载
    我的心情犹像樽盖等被揭开
    咀巴却在养青苔
    人潮内愈文静
    愈变得不受理睬
    自己要搅出意外
    像突然地高歌
    任何地方也像开四面台
    着最闪的衫扮十分感慨
    有人来拍照要记住插袋
    你当我是浮夸吧
    夸张只因我很怕
    似木头似石头的话
    得到注意吗
    其实怕被忘记
    至放大来演吧
    很不安怎去优雅
    世上还赞颂沉默吗
    不够爆炸
    怎么有话题让我夸
    做大娱乐家

    那年十八母校舞会
    站着如喽罗
    那时候我含泪
    发誓各位必须看到我
    在世间平凡又普通的路太多
    无知你住哪一座
    情爱中工作中
    受过的忽视太多
    自尊已饱经跌堕
    重视能治肚饿
    未曾获得过便知我为何
    大动作很多犯下这些错
    搏人们看着我算病态么
    幸运儿并不多
    若然未当过就知我为何
    用十倍苦心做突出一个
    正常人够我富议论性么
    你叫我做浮夸吧
    加几声嘘声也不怕
    我在场有闷场的话
    表演你看吗够歇斯底里吗
    以眼泪淋花吧
    一心只想你惊讶
    我旧时似未存在吗
    加重注码青筋也现形
    话我知现在存在吗
    凝视我别再只看天花
    我非你杯茶也可尽情地喝吧
    别遗忘有人在为你声

  • 自从开始玩twitter以后,就好久没有写blog了,但是在twitter这种产品上自己产生的信息太杂乱了,自己查找起来都比较麻烦,看来还是应该多写写blog。

    最近由于业务变更,需要在将之前的所有maven项目中的镜像更改成最新的镜像地址。那一个一个的更改是一件现实的事情,其实在linux下可以很方便的批量修改文件的内容,一条命令足以,都不用管道符。

    find -name 'pom.xml' -exec sed -i "s/oldurl/newurl/g" {} \;

  • 前段时间还在和@juvenxu 讨论Maven 3.0会不会跳票,没有想到这么快就已经正式发布出来了,感谢Maven项目组所有成员的辛苦努力。

    http://www.sonatype.com/people/2010/10/maven-3-0-has-landed/

    关于Maven 3.0整个发布历史以及新特性,大家可以到@juvenxu 的blog来看看吧。具体地址如下:

    http://www.juvenxu.com/2010/10/08/maven-30-released/

     

  • 原文地址:http://springnotes.javaeye.com/blog/487237

    不过,我倒是没有用这个release plugin主要是用了mvn的scm配置。

    原文如下:

    使用Maven Release Plugin, 我们可以将项目开发中必不可少的tag, branch等源码版本控制操作集成于Maven环境之中. 以下是使用Maven Release Plugin在Subversion中创建Tag的基本步骤和注意事项.

    1) Maven Release Plugin通过调用svn命令行与Subversion服务器交互,因此我们首先需要安装和配置Subversion客户端命令行程 序. 当Subversion服务器需要用户名和密码进行校验时, 比较简单的方法实在svn配置文件中使用PUTTY plink.exe 或TortoisePlink.exe, 并通过 -l 和 -pw 命令行参数来定义用户名和密码.

    2) 在项目pom文件中添加Subversion服务器配置, 定义Subversion中的trunk路径.

    Xml代 码
    1.    
    2. <scm>  
    3.     <connection>  
    4.         scm:svn:svn+ssh://path/trunk  
    5.     </connection>  
    6.     <developerConnection>  
    7.         scm:svn:svn+ssh://path/trunk  
    8.     </developerConnection>  
    9.     <url>  
    10.         http://Subversion URL  
    11.     </url>  
    12. </scm>  


    3) 在项目pom文件中添加Maven Release Plugin配置.
    Xml代 码
    1. <build>  
    2.     <plugins>  
    3.         <plugin>  
    4.             <groupId>org.apache.maven.plugins</groupId>  
    5.             <artifactId>maven-release-plugin</artifactId>  
    6.             <version>2.0-beta-9</version>  
    7.             <configuration>     
    8.                 <!-- 
    9.                 <tag>${version}</tag> 
    10.                 -->  
    11.                 <tagBase>  
    12.                     svn+ssh://path/tags  
    13.                 </tagBase>  
    14.             </configuration>  
    15.         </plugin>  
    16.     </plugins>  
    17. </build>  


    以上配置使用Maven Release Plugin 2.0-beta-9. tagBase定义了Subversion中的tag路径.

    4) 使用以下命令行来检查各项设置是否正确

    引用

    mvn release:prepare -DdryRun=true



    5) 使用以下命令行来创建Subversion Tag, 当此命令行运行时,Maven会提示询问下一个版本号, 并自动更新项目pom文件.

    引用

    mvn release:clean release:prepare


    几个注意事项

    1) 在使用Maven Release之前,必须check-in所有源码. 如果存在本地更改,Maven Release会报错并中止.

    2) 项目中的所有的dependency必须是发布版本, 不能使用SNAPSHOT.

    3) 上述的命令行会执行项目中的单元测试, 如果需要跳过单元测试, 可以使用以下参数

    引用

    -DpreparationGoals=clean


    4) Maven Release在运行过程中,会修改scm中的connection设置, 如果release异常中止的话, 需要恢复原来的pom文件,才能再次运行. 因此在试验阶段, 最好准备一个本地备份.

    5) 2.0-beta-9的tag设置中的变量处理存在问题 (见以上示例中注释掉的部分), 不过已经有人提供了Patch

  • 上周我们team内部做了一次关于在通行证项目中使用的一些技术的分享,主讲的同学是吴永照同学(这个是他的twitter帐号@webwyz,大家使劲可以follower他)。

    分享的内容主要是针对我们在通行证项目中的一些新技术框架的尝试以及一些小的开发技巧分享。

    其实ppt中仅仅只是一个大纲而已,更多的精彩内容是在分享的过程以及大家讨论中。可惜我当时由于别的事情,没有办法完整的参与,错过了不少精彩内容,实在是太可惜了。

    在这个项目中,与其他的项目有主要的几个改变。

    1)我们第一次采用maven的多模块多层次的项目结构,不过,从后来的效果来看,这个并不是一个太合适的方式,至少针对我们现在的情况,可能分为几个项目会更合适一些,以后在其他的项目中要注意这样的情况。

    2)我们在前端的应用服务使用了spring3.0.2来做开发,主要是利用了spring3.0.2中对REST的支持,在后端的项目中,我们依然还是使用spring2.5.6来开发。这次的尝试,让我们发现spring3.0.2中很多不错的功能,的确能够让我们的开发效率以及运行效率得到提升,让我们在接下来的项目中引入spring3.0打下了坚实的基础。

    3)在memcached的客户端的选择上,我们开始在正式的产品上采用了性能更好的XMemCached来代替Memcached官方提供的java客户端版本。而且XMemCached作者(@killme2008)还是咱们中国的程序员。

    4)另外在数据校验方面,我们也引入了JSR303的标准来对数据进行校验。

     

  •       本周大家都是在是太忙了,永照准备了一部分的分享的内容,但是没有时间来整理和分享,那没有办法,我只能拿出我之前写的一个简单的ppt拿出来给大家分享分享。

          不过,我也是很忙,只有赶在各个会议的间歇时间,给大家分享一下《版本控制》这个主题。其中还有一个小插曲,由于我没有时间给大家发邮件通知,让永照帮我来发一个这样的邮件,结果他把分享主题改成《Maven版本管理》,让大家误解了。不过,从某种角度来看,可能大家对这个主题也是很关心的。看来我应该准备准备这样的主题了。

          这次的主题是《版本控制》,不过,我觉得,应该叫做《程序员应该了解的版本控制的相关知识》会更加确切一些。这些知识的确是每一个程序员都应该了解和掌握的,不过,也可能大家对这个主题的内容也会有自己的见解和认识,可惜这次的分享时间太短,没有充分的沟通和讨论,比上次内部分享的效果要差多了。希望下次有更充分的时间来给大家讲讲这个主题。

     

  • 上周在公司项目组内部给大家分享了一下《Maven的简单介绍及基本应用》以及《程序员的SQL语句的优化》,主讲人是我和张贺同学。

    现在将ppt分享出来。

  •       三天的QCon Beijing 2010大会终于结束了,估计泰稳他们的团队也是累坏了,先在这儿谢谢泰稳和他的团队的辛勤工作,才让我们这群国内的技术人员有这么一个与国内网顶级技术人员交流的这么一个平台。

          这三天来收获不少,笔记记了一大堆,这段时间好好整理一下。毕竟我还是背负着任务来参加QCon的,回去以后,还要给公司其他人分享一下我这几天的收获。

          今天先写写一些这几天发生的一些有意思的,让我记忆深刻的事情。

          第一天是精神最好的一天,不过,自己也犯了些很低级的错误,早上去会场和晚上回家居然都坐过站了,早上是地铁转车车的时候,最后坐回来;晚上是坐公交回家,也坐过了,最后只能走回去。看来是太兴奋了。这一天的收获也是蛮多的。从演讲来说,Michael Nygard的第一场演讲《失败来了的征兆》收获最多(相比较起来他下午的那一场《设计可扩展的架构》就比较平淡一些,最后提问的人都没有)。最喜欢的还是douban的洪强宁@hongqn,被我们从演讲完毕后一直缠着问问题,差点采访迟到,也是很耐心的回答我们的问题。最后悔的是选择听李伟的《系统架构与最佳实践及创新的关系》,被这个题目吸引了,可惜演讲基本上没有什么内容,或者说内容太高级了,不是我们这个层次能够明白。早知道,我应该去听听麦天志同学的《如何在团队中有效的TDD》,可能会对我帮助更大一些。最遗憾的事情是由于公司的事情,只能早点回公司处理事情,要不然就去参加奇遇花园咖啡的推友聚会了,错过了一次和那么多推上的名人见面交流的机会,实在是太可惜了。

          第二天是内容最有料的一天,今天即有FacebookTwitter两位工程师来分享他们网站核心的架构设计,也有国内的互联网大腕们分享他们的网站的架构以及发展演进历程。今天也是参加人数最多的一天,特别是在上午的两场演讲(Facebook的Marc Kwiatkowski演讲的《Facebook的扩展 Memcached实战》和Twitter的Nick Kallen演讲的《Twitter的可伸缩性数据架构》)中两边的过道上都坐满的技术人员,座位后面也都站着不少人。估计泰稳看到这样的情况也是很自豪吧,毕竟这次的QCon是历来人数最多的一次。不过今天的投影也是很不给面子,在这么多人的关注压力下,宕机了好几回。

          第三天的内容就差了很多,尤其是上午的两场产品广告演讲微软的《云计算平台的应用与发展》和Oracle的《内存数据网格》,简直是太对不起大家的热情以及付出的报名费。今天很多人的注意力都放在给微软的演讲来贴小蓝脸,很多人都是将自己的小蓝脸毫不吝啬的给了微软,甚至有人将整版的蓝脸都贴上去来表示自己的愤怒。在中午吃饭的时间里,由于反馈墙上还没有贴出那场演讲的照片,已经有人等不及了,直接在反馈墙上用小蓝脸贴出了Microsoft的字样,有图为证。除了这两场广告以外,其他的演讲内容都是很不错的。

           虽然每天的感受不一样,但是总的来说,还是有一些共同的特点来。1)参加QCon的人里面推友特别多,看来如果想做一个相对资深的技术人员,翻墙的技术是必须要去掌握的。2)技术人员真的是很单纯的,只要你真的开放心态的和他们分享技术和心得,那么技术人员会从心底对你产生好感。如果,你仅仅只是想利用或欺骗他们,那么他们也会完全抛弃你。

           好了,先写到这儿,明天还要上班呢!

  • 记录一下

    netstat -n | awk '/^tcp/{++S[$NF]} END {for(a in S) print a,S[a]}'

  • 原文地址:http://www.alibuybuy.com/15288.html

    一、拥有自信和风度

    男人到了二十几岁后,就要开始学着用心去经营自己了,它体现在自己的思想与 涵养上。自信是一个男人最重要的品质,自信的男人就你像一只在暴风雨中战斗的海鸥。海鸥所要说的只有一句话“让暴风雨来的再猛烈些吧”,只因为它无所畏 惧。一个自信的男人,总是能够感染别人,无论这些人是朋友还是敌人。要使别人对你有信心,就必须要先对自己充满信心。自信的男人可以战胜一切困难。

    一个有风度的男人就像一片大海,不拒点滴,又包容江河。有风度使男人得到更多的青睐,不争眼前才能够放眼世界,给予别人才能够受益无穷。正所谓“宰相肚里能撑船”,一个心如大海的男人,肚中不知能撑多少船呀!风度偏偏让男人看上去潇洒万千。

    二、养成看书和写作的习惯

    男 人到了二十几岁后,就开始要走入社会了,在与别人交往的过程中,谈吐与修养是最能征服别人的。一个有知识的男人一定是常看书的,一个有智慧的男人一定是常 写作的。无论自己多忙,都要抽出时间来看看书,写写文章。因为这样做能够改变一个男人的思想与行为。一个男人要改变自己思想首先要做的就是读一本好书,读 一本书就像交了一个好朋友,他能够帮助你走好自己的路。读书的生活是最丰富多彩的,写作的时光是最能启迪智慧的。

    喜欢看书和写作的男人,一 定能够培养出一个好的心态。因为知识与智慧的海洋是无边无际的,但喜欢看书和写作的男人却能做到执著追求。追求是一个男人的思想,也是一个男人的行动,永 不放弃地追求,无时不刻的在激励的男人去战斗。在这种战斗中,使一个男人能够经历风雨的洗礼,成长为一棵参天大树。读书使男人变得的冷静,写作使男人变得 成熟。

    三、要试着发现生活里的真、善、美

    男人到了二十几岁后,就要学会如何去面对生活。 什么是“真”,现在的男人越来越不懂,那是因为现在的男人都很浮躁,他们不懂什么才是“真心”地去生活。 “真”,就是对自己实事求是,不要骗自己,也不要骗别人。“真”,就是诚实做人,诚实做事,诚实的男人最可爱。“善”,自然是善良的意思了。善待别人,就 是在善待自己的生活。“善”其实就在我们每一个人的身边,不要为难别人,不要挖苦别人,不要侮辱别人,就是善良的行为。有时你的一点点善意就能结出一个善 果,使你的生活因此而变得幸福。

    哲人说,“生活中本不缺少美,缺少的是发现美的眼睛”。是的,生活也的确是如此。不要总在惦记着自己的不 幸,这样做只能使你生活的更加不幸。你觉得“不幸”是因为你无法乐观的面对生活,生活总是充满着希望的。只要你常常抬抬头,看看阳光,你就能感受到温暖。 在温暖中乐观地去追美好的人生,你自然能够发现美。

    四、与有思想的人交朋友

    男人到了二十 几岁后,就要开始有目的性的去选择朋友了。社会中的人脉关系是非常重要的,你的朋友圈子将对你的人生起着很大的影响。男人要广交朋友,多交诤友,不交损 友。所谓诤友就是那些对你有帮助的朋友,而这些人往往自身也很优秀。多交诤友对一个人的生活、工作都是非常有益的。但真正的诤友也不易结交,因为这种朋友 需要你付出极大的真诚,发自内心的真诚。

    有思想的朋友,他很清楚你有没有把他当作朋友。如果你只是在利用他,他在心中是不会把你当作朋友来 看待的。交朋友有时并没有什么目的性,你只是觉得这个人很有思想,值得你与之相交。但往往就是这些有思想的朋友,在你最困难的时候向你伸出他的手。朋友, 是一个男人生命中最重要的元素的之一。一个男人要想使自己像一人真正的男人那样活着,就一定要广交朋友,多交诤友。

    五、必须改掉自身的不良习惯

    男 人到了二十几岁后,就必须要改掉自身的不良习惯。不良的习惯是养成的,良好的习惯也是养成。培养自己拥有良好的习惯,就是在改掉自身的不良习惯。如果一个 男人到了二十几岁后,身上还有这样那样的不良习惯,那就是一件非常糟糕的事情了。这些不良的习惯会阻碍你人生的发展,生活会因此而失去不少光彩,事业也会 因此难以取得更大的成功。

    如果你到现在还爱睡懒觉,那么清晨的第一抹阳光永远也不会照到你的笑脸上。如果你到现在还总是拖拖拉拉的,那么你 将永远也无法站在冠军的位置上。如果你到现在还不会主动的去学习和工作,那么你的前途只能是一片暗淡无光的灰色。我相信没有哪一个男人想要灰色的人生,所 有的男人都期望自己能有一个绚丽多彩的人生。所以为了使自己的人生绚丽多彩,男人到了二十几岁后,就必须要改掉自身的不良习惯。

    六、学会忍耐与宽容

    男 人到了二十几岁后,就要学会忍耐与宽容。在社会中常有许多你无法接受的事情,但这些事情你又不得不接受时,这就需要你的忍耐。忍耐别人其实也是在宽容别 人,一个能够宽容别人的男人会显得很大度。成功的男人往往也是一个能够忍辱负重的男人。耐得住寂寞的男人从不甘寂寞,男人的忍耐是为了更好的爆发。

    对那些说我们是傻瓜的人,说一句“我就是傻瓜”,使他们不知所措吧!对于那些无故指责我们的人,不要与他们争论,因为这样只会使自己变的愤怒。与其去伤害别人,不如去宽容别人,宽容是治疗他人伤口最好的灵丹圣药。

    七、保持良好的心态,重视自己的身体

    男 人到了二十几岁后,就要学会调节自己的心态,重视自己的身体。身体是革命的本钱,心态是验钞机。男人要想获取更多的财富就要拥有一副强健的体魄,男人要想 长久的做首富就要拥有一种积极乐观的心态。注意饮食,经常锻练,充足的睡眼,是健康身体的保证。不要患得患失,勤奋拼搏,让心态决定一切。

    你 可以不用天天去晨跑,其实那也不会占用你多长的时间,需要的只是恒心和毅力。但你一定要时常去运动一下你的身体,散步是一种不错的选择,这样做会使你充满 力量。你在冬天可以不用冷水洗澡,其实那也没有什么大不了的,因为我也曾坚持过一个冬天。但你在冬天一定要经常用冷水洗洗脸,这样做不仅可以防止感冒,还 能保持一个清醒的头脑。你可以失败,但你永远要保持一种求胜的心态,战胜自己你就没有敌人。

    八、时刻保持你的微笑,让礼貌成为你的名片

    男人到了二十几岁后,要时刻保持你的微笑。笑脸迎人,说明你是一个善良的人,所有的人都愿意与善良的人打交道。不要把苦闷写在你的脸上,这样只会使别人远离你。你是什么样的人,别人通过你是否微笑着与他打招呼来判断。而这种判断对你在人家心中的印象起着很重要的作用。

    人们常说“细节决定成败”,而这细节往往就反应在你是不是一个有礼貌的人。有礼貌的人,知道关心别人。别人也会因为你的礼貌与关心,而给你走向成功的机会。男人的名片是微笑与礼貌,它是男人成就事业的通行证。

    九、追求一个自己真正爱的女人,你一辈子也不会后悔

    男 人到了二十几岁后,慢慢地就会极渴望爱情。这是非常正常的事情,千万不压抑自己这种发自内心的情感。一个男人最傻最可爱的时候就是当他爱上了一个女人的时 候。当你爱上一个女人却不知道她会不会爱上你的时候,你一定要选择一个恰当的时间向他表白。至于他是选择接受还选择拒绝那就要看你们之间的缘份和你的努力 了。男人一定要明白,女人最渴望的一定是一个深爱着她的男人。

    爱情这种事不能强求,男人一定要明白。千万不要因为得不到你的爱情就让你的友 情轻易的失去,能与一个自己曾经爱过的女人成为朋友是一件不可多得的好事。爱情之所以神圣不可侵犯,是因为它是人最心甘情愿的选择,它体现的人与人之间的 尊重与信任。所以男人一定要尊重你爱着的那个女人的选择,相信她的选择是为了她自己的幸福而做出的决定。只要你曾经追求一个自己真正爱的女人,那么你一辈 子也不会后悔。

    十、为了自己的事业付出一切

    男人到了二十几岁后,一定要为了自己的事业 去努力拼搏。男人最重要的就是事业,没有事业的男人不能算作真正的男人。男人的事业不定要轰轰烈烈,但一定要有所成就,能使自己感到骄傲和自豪。一个事业 心强的男人,也是一个求胜心与责任心同样强的男人。求胜心强的男人,从不甘平庸。责任心强的男人,从不惧困难。男人因自己成功的事业而变得高大,从而获得 别人的尊重和信任。

    作为一个男人,就要为了自己的事业付出一切。要想成功你必须付出,而付出就意味你要失去一些东西。如果你不想为事业付出任何代价,那么你只能失去更多的东西,而且最后还一无所获。

    十一、爱情跟事业是可以共同拥有的

    男 人到了二十几岁后,就应该努力做到爱情跟事业的双丰收。人们常说一个男人如果选择了爱情就会失去事业,如果选择了事业就得不到爱情。我却偏偏不这样认为, 我反而觉得爱情越甜蜜的男人,事业越成功。其实爱情和事业本就是两回事,爱得轰轰烈烈的男人,一点也不会妨碍其获得成功的事业。一个有爱情滋润的男人一定 比一个不知爱情是什么味道的男人更成熟,更有魅力,更有干一番事业的决心。

    二十几岁的男人们,千万不要相信那些偏激的人所说的话。就像人们 常说的“婚姻是爱情的坟墓”,这种说法太偏激了。婚姻与爱情的区别只是多了一些“柴米油盐”,可以说婚姻才是一种完整的爱情,之前的爱情只是处在一种恋爱 的阶段。也只有通过婚姻才能使男人和女人彻底的认识什么是爱情。爱情就是相互理解,相互鼓励,相互支持。在生活上彼此帮助,在事业上彼此帮助,让爱情跟事 业可以双丰收。

    十二、一定要努力比女人做的更好

    男人到了二十几岁后,在任何事上一定要努 力比女人做的更好。即使在一些不可能比女人做的更好的事情上,也要努力做的和女人一样好。在这里这不是想说男人天生就应该比女人强,而是要说男人天生就应 该比女人做的更好。因为只要女人努力了,就很容易超越男人,所以男人应该知道努力比女人做的更好是天经地义的事情。在如今的社会,女人的地位越来越高了, 女人第一次有了选择男人的权力。所以如果作为男人的你,不能比女人做的更好,那么女人凭什么选择你呢?

    女人们常说 “女子能顶半边天”,而且现在的女人在本属于男人的某些领域里比男人做的更出色。所以男人不仅要在属于自己的领域里做的非常出色,而且也要能在本属于女人的领域里做得一样的出色。

    十三、努力帮自己的妻子实现她的梦想

    男 人到了二十几岁后,如果你已经结婚了,那就请你一定要努力帮自己的妻子实现她的梦想。人们学说“男人靠征服世界来征服女人,女人靠征服男人来征服世界”, 所以一个已经征服了你的女人,你一定要努力帮她征服世界。女人的梦想从不会因为和一个男人生活在一起了而消失掉,只会因此而变得更加强烈。女人这种强烈的 愿望和梦想也许不会表现在你的面前,但你的心中一定要明白。

    妻子是一个男人生命的核心,妻子生活得是否幸福,男人一定要关心。不要以为妻子取回家,就是来为你服务的。每一个男人的妻子都会关心自己的丈夫,每一个男人也要学会关心自己的妻子。而最关心妻子的事,莫过于关心她的梦想是什么,怎么做才能帮妻子实现她的梦想。

    十四、学会勇敢一些,去承担起自己肩上的责任

    男 人到了二十几岁后,要学会勇敢一些,挻起自己的肩膀去承担起属于自己的那份义不容辞的责任。孝顺父母是一个男人责任,疼爱妻儿是一个男人的责任,成就事业 也是一个男人的责任。男人的责任不外乎家庭和事业。这些责任的确比较沉重,但作为一个男人你必须挻起自己的肩膀去承担。没有什么原因,只因为你是一个男 人。

    男人一样有权力哭泣,但却没有权力哭出声音来。男人一样有权力流泪,但却没有权力在父母妻儿面前流泪。男人一样有权力放弃,但却没有权力放弃家庭与事业上的责任。作为一个男人,你别无选择,你只能选择承担,用你的肩膀去承担。

    十五、永远不要放弃自己,相信自己一定能行

    男 人到了二十几岁后,就必须做到永远不要放弃自己。别人之所以放弃你,那就因为你已经先放弃了自己。相信只要你不放弃自己,没有哪个人会放弃你或者说没有哪 个人能放弃你。相信自己是一个男人战胜一切的力量之源,不相信自己的男人没有成功的理由,因为他的一脚已经跨到了失败的坟墓中。

    有一句广告语,这样说“相信自己,力量在心中”。还有一句广告语,这样说“我能”。是的,我想,我也相信只要每一个男人能够做到相信自己,你就一定能行。

  • 2010-01-31

    Bells of Freedom - [my live]

    我们依然还会发出自由的钟声!

  • xwindows换成gnome后,eclipse出现了按钮无法响应的问题。

    在网上查了一下,应该是eclipse和gdk某些地方不兼容的问题。

    解决办法很简单,写一个脚本,设置一下启动eclipse的sub shell的环境就可以了。

    脚本如下:

    #!/bin/bash

    export GDK_NATIVE_WINDOWS=1

    cd /opt/eclipse

    ./eclipse &

  • 在我们使用XML Schema描述数据模型的时候,XSD提供了很多的强大的功能,比如对数据内容的Restriction(约束)功能。

    Restrictions是用来限制(或者说定义)Element或Attribute可接受值的。而对于Element的Restrictions通常又称为Facets。
    下面通过一些常见的约束例子来说明Restrictions的用法和语法。

    数值型范围限制

    <xs:element name="age"><xs:simpleType>
    <xs:restriction base="xs:integer">
    <xs:minInclusive value="0"/>
    <xs:maxInclusive value="120"/>
    </xs:restriction>
    </xs:simpleType></xs:element>

    该约束定义age元素的值是整形而且值要在0到120之间。

    枚举限制

    <xs:element name="car">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:enumeration value="Audi"/>
    <xs:enumeration value="Golf"/>
    <xs:enumeration value="BMW"/>
    </xs:restriction>
    </xs:simpleType>
    </xs:element>

    这里约束了car的值是string,而且只能为“Audi”、“Golf”和“BMW”中的一个。
    可以使用另一种写法:

    <xs:element name="car" type="carType"/>
    <xs:simpleType name="carType">
    <xs:restriction base="xs:string">
    <xs:enumeration value="Audi"/>
    <xs:enumeration value="Golf"/>
    <xs:enumeration value="BMW"/>
    </xs:restriction>
    </xs:simpleType>

    这种写法的好处是,上面的Restriction不是定义在Element中的,可以被其他的Element很方便的调用。

    使用正则表达式(RegularExpression)约束

    <xs:element name="letter">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:pattern value="[a-z]"/>
    </xs:restriction>
    </xs:simpleType>
    </xs:element>

    这里<xs:pattern>的value属性的值是一个正则表达式正则表达式的语法则不再本文介绍的范围。使用RegularExpression你可以规定任何格式的string约束。

    空格字符(Whitespace Characters)约束

    <xs:element name="address">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:whiteSpace value="preserve"/>
    </xs:restriction>
    </xs:simpleType>
    </xs:element>

    以上例子对address中的所有空格字符进行保留。关键是value="preserve"。XML语法本来就是保留空格的。
    当值为“replace”时
    XML processer会用空间来代替所有的空格字符。
    当值为“collapse”时
    会将连续的空格合并成一个。

    长度约束

    <xs:element name="password">
    <xs:simpleType>
    <xs:restriction base="xs:string">
    <xs:length value="8"/>
    </xs:restriction>
    </xs:simpleType>
    </xs:element>

    以上例子限定了password元素的长度为8。当然也可以使用 <xs:minLength value="?"/>和<xs:maxLength value="?"/>来限定最长最短值。

    更多的内容请看http://www.w3schools.com/schema/schema_elements_ref.asp

  • 周六的时候参加了douban组织的2009年北京Python用户组(BPUG)第3次聚会的活动。具体的活动信息大家可以移步到这儿查看。感谢douban,感谢组织者xyb,感谢三位主讲人梁冰,王云鹏,黄冬。

    想进入参加活动名单还不是很容易的,一共才有30个人的名额,好多同学报了名也遗憾的没有参加。

    这次活动有三个话题,基本上都是架构方面的话题,与python没有太多的关系,这样的主题我很喜欢(因为python我基本不懂),在三位主讲人的分享下,收获颇多,也不枉费我来回4个小时,60多公里的路程。

    当你的系统进入一个高并发,高负载的时候,你的架构设计就不能仅仅只是某一门语言的问题。你需要了解和深入很多领域的知识,比如操作系统,网络协议,多种语言的组合和对比(在不同场合使用最适应本场合的语言),硬件系统。只有这样,你才能设计出来一个合乎需求的系统。所以,对于一个架构师(或者想要成为架构师的同学)来说,需要学习的东西还是很多的。

    有些话题由于某些原因不方便参加者宣传和传播,我也就不在blog上做文字的记载,就把我在当天回家的路上整理的mind生成图片放到blog中,如果有感兴趣的同学,可以查看图片

    Beijing Python User Group聚会收获

    另外:附上这次聚会中的一些照片,更多的照片请点击这儿

    Tony Deng

    路标

    douban logo

    梁冰

    黄冬

     

  • 同事老焦最近的项目中碰到一个JSON与Java Object之间转换的性能问题。

    上网查了一下,果然我们现在使用的JSON-Lib这个框架的性能是公认的差,可能之前一直没有意识到这个问题,只是觉得这个Lib用的挺顺手的,所以一直在用它。这里有两篇文章对现在的三种JSON转换的框架的性能有一个比较具体的分析(《Java: JSON Parser Performance》、《JVM性能调优记录》)。

    我们试了上面的另外两种框架,但是都不能达到我们的需求,关键是对我们自定义的Object转换会有问题,需要我们提供扩展的方案才行。

    正在头疼中,海龙给我们推荐了google-gson这个有google提供的JSON框架。我在pom.xml中加上google-gson的依赖,写了几个测试用例测试了一下,条件是任意多个java对象数据集合转换成JSON字符串。在同样的条件下,google-gson性能比JSON-Lib提高了两倍以上,特别是在对一个很大的、有冗余的Object做转换时性能更是能提高3-4倍。而且,API使用也很方便,一个gson.toJSON(obj)就可以完成转换的操作。

    在这里特地给大家推荐一下google-gson

  • 2009-11-07

    REST系列分享 - [developer]

    我在公司发起了一个关于REST的系列分享,现在已经进行到第二期了。主要关注于RESTFul应用的开发,基本上会从RESTFul的概念入手,慢慢深入的讨论如何在项目中如何开发RESTFul的应用、如何更好的理解RESTFul的理念。

    这两期的分享主题分别是《什么是REST风格应用》,《使用JSR311规范快速构建REST应用》。基本上每次的分享时间都有两个小时左右。虽然我会把每次分享的PPT都会给大家,但是毕竟PPT只是一个简单的大纲而已,更多的内容还是在大家互相讨论交流中。

    REST系列分享活动简介如下:
        这个活动是由程序员自动发起,非官方的身份决定我们不会有太多的资源来支持活动,希望大家能够在完成(安排好)手头的工作之后来加入活动。
        同时,可能由于时间的关系,我们允许分享人可以不准备ppt,但是要保证可以通过别的方式(如白板)来将你要分享的内容表达清楚。
        我们希望通过我们的分享和交流能够让大家对REST有更深入的了解,毕竟REST也是一个很庞大的话题,不是一次两次的培训和分享能够说明的。
        我们欢迎有自己的想法,有疑问,习惯质疑,喜欢分享的程序员加入活动中来。
        在活动中有任何的疑问和反对意见都可以随时提出来。

    下面是我之前分享内容的ppt。

     

  • 我们在Windows下使用Maven来编译项目的时候,经常会发现Maven给出这样的提示:[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!

    当你看见这样的提示的时候,你就要小心你项目中资源文件的中文会出现乱码的现象了。你可能会有疑问,我的文件的格式是UTF-8的,文件编码也是UTF-8的,为什么还会出现中文乱码的问题呢?

    其实原因Maven已经告诉你了。由于我们使用的Windows默认是GBK编码的,那用GBK的编码重新读写UTF-8的文件,那肯定是会出现乱码的。

    那么我们怎么样才能解决这个问题呢?其实很简单,只需要在相应的项目的pom.xml中加上一个Maven插件就可以了。

    <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                     <encoding>UTF-8</encoding>
                  </configuration>
    </plugin>


  • 2009-10-27

    Unix 设计哲学 - [developer]

    现在所有常用的操作系统基本上都是在Unix的基础上衍生(最少是借鉴)出来的,而且基本上大学的操作系统的课程也是拿Unix系统来讲解的。在这里我转载了Unix的设计哲学和思路,一起学习参考。

    原文地址:http://cgfundamentalism.spaces.live.com/Blog/cns!A938DB4347919AD9!406.entry

    (节选自 《Unix 编程艺术》)

    Unix哲学中更多的内容不是这些先哲们口头表述出来的,而是由他们所作的一切和Unix本身所作出的榜样体现出来的。从整体上来说,可以概括为以下几点:

    1. 模块原则:使用简洁的接口拼合简单的部件。
    2. 清晰原则:清晰胜于机巧。
    3. 组合原则:设计时考虑拼接组合。
    4. 分离原则:策略同机制分离,接口同引擎分离。
    5. 简洁原则:设计要简洁,复杂度能低则低。
    6. 吝啬原则:除非确无他法,不要编写庞大的程序。
    7. 透明性原则:设计要可见,以便审查和调试。
    8. 健壮原则:健壮源于透明与简洁。
    9. 表示原则:把知识叠入数据以求逻辑质朴而健壮。
    10.通俗原则:接口设计避免标新立异。
    11.缄默原则:如果一个程序没什么好说的,就沉默。
    12.补救原则:出现异常时,马上退出并给出足够错误信息。
    13.经济原则:宁花机器一分,不花程序员一秒。
    14.生成原则:避免手工hack,尽量编写程序去生成程序。

  • 这两天看了一个这样的文章《软件工程师的十个“不职业”行为》,是陈尚义老师整理分享的。看完之后,抚心自问,自己还是比较职业的软件工程师。

    现在将这十条不职业的行为摘录下来,时刻提醒自己。

    行为一:对外交付半成品。

    行为二:不遵守标准和规范。

    行为三:不积极帮助他人。

    行为四:版权意识不敏感。(这点要注意)

    行为五:对待计划不严肃。

    行为六:公事私事想混淆。

    行为七:不注意更新自己。

    行为八:不主动与人沟通。

    行为九:不遵守职场规则。

    行为十:不够诚实和正直

    原文地址:http://www.programmer.com.cn/1041/

  • 其实我们都是从菜鸟成长起来的,感谢在这个过程中给予我们帮助的人!

    下面的文字转自: http://www.ideawu.net/blog/?p=428

    最近, 网上盛传一个笑话, 一般名字叫做"围观不会设置Java User-Agent的菜鸟". 讲的是国外一个用Java开发Web爬虫获取网页
    的菜鸟, 不知道怎么设置自己虫子的User-Agent字段, 该字段可以告诉Web服务器, 对方用的是什么工具或者软件. 这个笑话中的事情确有
    其事, 见下面URL:

    https://groups.google.com/group/comp.lang.java/browse_thread/thread/6923c024ed392c85

    这个帖子(邮件)的发贴人使用的邮箱后缀是cs.stanford.edu, 他是斯坦福大学的学生. 发贴的时间是1996年1月, 使用的Java
    是1.0beta2. 当时, Web爬虫技术应该是非常稀有的技术, Java/1.0beta2的HTTP相关库也应该非常难用. 现在看来, 那
    时的人, 那时的技术, 都像是婴儿. 所以, 这看起来像个笑话.

    但是, "笑话"的笑点在这里吗? 我相信, 大家在看到这个所谓的笑话时, 可能会心里或者面上露出笑, 但应该是感悟的笑, 自嘲的笑, 无奈的
    笑, 思索的笑...肯定不会有快乐的笑. 为什么? 因为发贴的人是Larray Page, 是Google公司的创始人之一. 他创造了全球许多
    技术人员的上帝, 他创造了巨大的财富, 他创造了技术和商业神话. 可是, 他曾经做过的事, 使用的技术, 开发出的产品, 遇到的无法逾越的问
    题, 向人讨教时的心情, 和我们那么接近, 甚至对我们大部分技术人员简直是小菜一碟. 在每一个人心中, 这都是一个历史笑话, 让我们思考技术的
    本质.

    我把这封邮件引用在这里, 做个留念:

       I have a web robot which is a Java app. I need to be able to set
    the User-Agent field in the HTTP header in order to be a good net
    citizen (so people know who is accessing their server). Anyone have
    any ideas?

       Right now, Java sends a request that includes something like:

       User-Agent: Java/1.0beta2

       I'd rather not rewrite all the HTTP stuff myself. I tried just
    searching in the JDK for the Java/1.0beta2 figuring I could just
    change the string, but I couldn't find it. Perhaps it is stored as a
    unicode string?

       An easy method of setting the User-Agent field should probably be
    added to Java, so people can properly identify their programs.

       Thanks, Larry Page

  • Kseniya Simonova,乌克兰人,80后的沙画艺术家。

    人美,画更美。下面两个沙画作品是她在《乌克兰达人》这个选秀节目中的表演。每个作品都讲述了一个故事。

    比赛中的表演令现场观众看她作画居然会为之泪下。她的沙画艺术是对艺术与灵魂的诠释,看她作画的过程,能够让人感觉身心得到净化和升华,难以想象这竟然是在一场选秀节目中的表演。

    这个作品讲述的是德国二战期间侵略乌克兰历史。最后她写的字意思是“永远和你们在一起”。 结尾部分的背景音乐是“nothing else matters”。


    这个作品表达了宇宙、人生、亲情。孩子从出生到变成画家,出名后和父母很少联系,老母亲只能在电视里看着儿子的身影,最后孤独的死去。 


    Kseniya Simonova在录像最后用俄语写了:“Don't be late...; 别晚了...”,意思是要赶紧和家人联系,等到家人都走了就晚了。

  • 原文地址:漫天风

    培养员工的主动性和敬业精神可以从几大方面入手:

    1、 最基本的是创造一个积极的,宽松的,自组织的工作环境和氛围。在这个环境中,倡导学习型团队文化。

    2、 积极建设阶梯型、多样化的人才团队。一个团队如果能形成良好的人才梯队,不仅仅有利于团队形成强大的竞争力,而且一定程度上能激发不同成员的主动性和积极性。

    3、 完善的角色和明确的工作职责。一个团队,如果缺乏某个特定的角色,不仅仅在这个特定领域中会成为团队的短板,而且往往需要团队Leader去弥补或救火,这样会成为团队发展的瓶颈,这个是限制员工发挥主动性的重要因素。

    4、 合理的授权。团队领导应该成为教练,并从中帮助团队各个角色更好的协作,更好的发挥每个人的优势。授权是一门管理艺术,信任每个员工,并给他们充分的权力,有助于提升员工的主动性和敬业精神。

    5、 激励。当团队的目标达成时,当某个员工表现突出时,适当的激励将会使团队焕发激情,同时也是对每个员工的一种肯定和鼓励。善于使用激励的领导,将会让他的员工充满积极主动性。

  • 2009-09-24

    想念 - [my live]

    好久没有听齐秦的歌了,突然这首歌在耳边响起,把我的思绪带回到了02年刚来北京的时候。正如在这首歌中齐秦慢慢的唱道:

    我在异乡的夜半醒来
    看着完全陌生的窗外
    没有一盏熟悉的灯可以打开
    原来习惯是那么难改

    只为了和你再见一面
    我会不分昼夜的想念

    《想念》这首歌是收录在齐秦的1997年《丝路》这张专辑中,由袁惟仁(小胖)创作。

     

  • 今天给大家分享了一下,在实现社区积分系统时使用设计模式的思路,同时也分享了一下我们怎么样去选择设计模式。

    谢谢大家的支持和讨论。

    在这里把刚才分享的Strategy、State、Chain of Responsibility的不同的地方概括说明一下:

    Strategy:主要应用于在一次操作中存在着多种算法的选择。

    State:主要应用于在同一事物状态转换的描述。

    Chain of Responsiblity:主要用于对某一次操作有一系列可选择的处理。

     

  • 大乔小乔在《消失的光年》中唱道:“每个人是每个人的过客,每个人是每个人的思念。眼中的日月星辰,消失在心中的光年”。每次听到小乔用稚嫩的童音来唱这首歌,心中都有莫名的惆怅,可能这个就是他们的目的,用代表纯真的童音来唱出成年人的感伤。

    不过,我这里并不是想来做一个文艺青年来感伤时间的流逝,而是想感谢我生命中的每一个过客。在茫茫人海中能够擦肩而过也是一种缘分,更何况这些在我的生命中陪伴我走过某一段时间的人呢?

    转眼来到北京已经7年多了,其中也更换了多个工作,也经历过自己创业,也笑过,也哭过,有沮丧过,也有欣喜过。我的这些变化,身边的走过的这些同事朋友们都一一见证过。我真心的感谢你们,陪伴我成长。

    想想,这些年里面,几乎每个公司都有一个或多个人对我影响挺大。

    罗涛先生,谢谢你给我在北京第一份工作,让我能够留在这个实现梦想城市。

    米长泊(米哥),谢谢你让我学会怎样与人沟通,学会怎样对不正常的要求说不,同时也包容了我在工作中犯下的错误。这段时间,我也把北京的交通也摸熟了。

    魏一才先生,谢谢你给我一个反面的案例,教育我千万千万不要成为你这样的人,千万千万不要和你一样在一个虚假的环境里面把自己给废掉。

    郭家清(郭工),谢谢你让我看到一个人放下已拥有的所有,向自己的梦想的目标坚定的前行的勇气,并实现自己的梦想,拿到了CCIE的Cisco的最高认证。谢谢您对我的鼓励,让我勇敢的追求梦想前行。

    林宇泽(小林),虽然你比我大,但是已经习惯叫你小林,想想这样叫你,应该让你更年轻一些,所以你就接受吧。谢谢你帮我进入了互联网这个领域。

    田玉林,很想念当时咱们一帮人共同创业的时光,想到最后由于资金的问题,大家各自解散时,作为领头人的你流下的泪水。过了这么些年,这个情景经常会在我脑海中浮现。这几年过去,大家都应该提高了不少了吧。希望还有机会能够一起合作。

    郭应寿老师,谢谢您带我进入了一个全新的境界,让我知道原来软件开发是这样有意思的一个工作。谢谢您对这个行业有了全新的认识,让我愿意为之付出一生的时间。

     

  • 通过这次沟通分享,大家达成这样的共识。
    1.使用trunk,branches,tags的方式来管理Subversion的版本。
    2.使用分层的方式来拆分技术团队,分为REST层以及前端表现层。
    3.使用maven来管理项目的生命周期。

    这次的分享,很高兴得到大家的认可,感觉心中的憋着的一股气泻下去不少。

      希望以后能够越来越好!