逝者已逝,众恶徒已正法,然天下居庙堂者与处江湖者,当以此为鉴,牢记生命之重,人权之重,民主之重,法治之重,无使天下善良百姓,徒为鱼肉。 ——孙志刚墓志铭
  • 记得去年5月11号,项目第一个迭代结束的时候,我在日记中写到:

    整体感觉很无力。

    几十个project组成的遗留系统,改点东西要翻天覆地的找代码;无数的存储过程,繁琐的手工的deploy、 release步骤;需求不清晰,客户非抵抗不合作。

    迭代的起止没有任何明确的标志。show case是下个迭代的第一天做,回顾是下个迭代的第二天做。没有kickoff meeting。计划在哪里,在mingle上。

    但情况也一点点变好,渐渐熟悉了遗留系统、IIS和Tomcat的结合、部署流程。自动化脚本也增加了起来。

    大半年过去了,回头看看前三个迭代的回顾墙,不免五味杂陈。

    我们基本上不会再出现一个story做一个迭代的盛况了;

    也不需要每次迭代都要反复提及“提前做spike,分一个pair专门做spike”之类的话题了;

    一开始发布domain的时候要瞪着屏幕瞪10分钟,后来有了Autoit的脚本,到后来domain也不需要发布了;

    后来有了自动化功能测试,然后又没了,最后又有了;

    代码删啊删,测试加啊加,有个项目的覆盖率超过80%了;

    某个机器上应该还有inception之前搭起来的本地持续集成吧,那上面还有dbdeploy + sqlplus的自动化数据migration呢。客户的tech lead离开北京的时候答应说把这套东西在伦敦搞好,可是到他离职的那天,还没在mingle上建卡呢;

    该走的客户还没走,不该走的客户却走了;从一开始就对客户的协作态度不满意,回顾的Action上写着“PM催;PM继续催;PM想办法催;PM找CP催”,但一直也没成功过;

    有的人来了就没有走;有的人来了又走了,然后就再没回来过;

    快要2011年了,更快要离开项目了,只想说一句话:

    回头望,每个人都看那世事无常
    向前闯,一颗心比谁都还要坚强
  • 在TW西安办公室有这样一支团队,他们近一年来没有加过班,一直在维护风险墙,一直在消除风险。

    他们项目中每个刚毕业的大学生都跟国外客户谈过需求。

    在项目结束的时候,他们培养出了一个能写程序的测试,两个能做测试的dev,一个能管项目的dev,一个能做UI的dev。

    想知道这样一支团队是如何炼成的,请期待胡凯 的文章完稿。

  • 平时常常需要打开Mingle看故事卡的内容:需求描述、AC等等。每次都要开一个新窗口,输地址等待自动补全,把自动补全的地址改成需要的number,回车。这一系列的操作是手动而且重复的。按照《卓有成效程序员》的说法,是典型的应该被自动化的环节。

    于是有了这些脚本。

    Firefox.au3

    $firefoxClass = "[CLASS:MozillaUIWindowClass]"
    $firefoxOpened = WinExists($firefoxClass)
    $firefoxExecutable = "C:\Program Files\Mozilla Firefox\firefox.exe"

    Func run_firefox()
        If $firefoxOpened Then
            active_firefox()
        Else
            open_firefox()
        EndIf
    EndFunc

    Func active_firefox()
        WinActivate($firefoxClass)
    EndFunc

    Func open_firefox()
        Run($firefoxExecutable)
    EndFunc

    Func wait_util_firefox_opened()
        WinWaitActive($firefoxClass)
    EndFunc

    Func open_new_tab()
        Send("^t")
        Sleep(500)
    EndFunc

    MingleCard.au3

    #include <firefox.au3>
    $cardnumber = $CmdLine[1]

    run_firefox()
    wait_util_firefox_opened()
    open_new_tab()
    enter_card_url()

    Func enter_card_url()
        Send("http://localhost:8080/projects/projectname/cards/")
        Send($cardnumber)
        Send("{ENTER}")
    EndFunc

    show.bat

    minglecard.au3 %1

    把show.bat加入PATH以后,只需要输入show 20这样的命令,就可以直接打开序号为20的这张卡了。

  • 五月书单 - [朝花夕拾]

    2010-05-31

    1. 《六顶思考帽

    在用系统反馈图的方式来剖析问题成因、改善点、观测点的时候,有一点相当重要,那就是要头脑风暴。每个人都有自己的知识局限性、认知差异,所以有的人会摸到象腿,有的人会摸到身子,或者尾巴。只有每个人都可以无阻碍的把自己的理解呈现出来,这个团队才能建立一个趋向于分析系统全貌的思考方式。

    思考》跟《系统思考》有很多异曲同工之处,但它给出了一种更具有可操作性的团队协作方式。

    书的开篇就指出:因为每个人各自的关注点不同,再加上背景和知识结构的差异,往往会出现很多不必要的争论。而这些争论丝毫无益于得出一个建设性的共识,无益于团队中的智力资源整合。

    作者提出的解决方案很简单:所有思考者在同一时间只做一件事情,把逻辑、情感、创造、信息等等区分开。我们有不同颜色的子,戴上不同颜色的子,表示换一个看问题的角度。

    通过这种方式,我们可以更多的关注于“我们能够做什么”,而不是谁对谁错。

    2. 《软件随想录──Joel谈软件》

    前两天荣浩说起他在看微观经济学,我随口问了句谁推荐的,然后荣浩、晓庆和我三个异口同声说,“Joel”。Joel是个很有煽动力的八卦er,至少在我这个没有把1940年以来的重要论文或者图灵演讲集都读过一遍的人眼中看来,他还是很能把各种史事信手拈来挥洒如意的。

    3. 《常识

    常识是本很沉重的书,作者在封底说,“如果时事评论的目的是改变现实,那么现实的屹立不变就是对它的最大嘲讽了”。然而正如某历史系女博士所说,“人不会变得更好,他们只是变得更聪明。人变聪明之后,不会停止拔飞虫的翅膀,只会为这种行为想出一个更好的理由。”

  • 精益絮语 - [敏捷开发]

    2010-03-25

    等你发现一件产品有缺陷的时候,这个缺陷其实已经在设计或生产过程中被埋在产品里了。只有组织内的每一个人,都承诺绝不将有问题的产出物或不完整的信息送到下一个环节,我们才能获得质量。所以要有Autonomation。

    改善的起点在哪里?在现场。说得更细致一点,就是在最靠近客户的地方,也就是在哪里把产品交付给客户。因为那里是产品价值兑现的时刻。你的交付物从哪里来?答案毫无疑问是CI。所以我们会选择CI作为切入点啊。

    当我们保证了准时交货以后,下一步再来减少库存。这也就是说,从接近客户的地方开始,逐渐倒推,逐个查找问题的所在。在建立CI保证主线常绿的过程中,整个流程都会被带动着改善,就是这个道理。

    所谓单件流:每次生产和转移一个;尽可能的连续流动;上下工序刚刚好的衔接。

    形成单件流的前提:按客户需求同步节拍生产(不过量生产等);标准化(没有行为影响价值流的流畅);Autonomation;执行5S;具备形成流的环境。

    实施改善的25点心得。4. 反复试验;8. 永远将今天作为起点;9.身处现场;19.寻求根本原因,多问五个为什么;20. 改善永无止境。 24.当前作业的目的是让后续作业更容易;──《丰田改善力》

  • 开心餐厅跟开心网推出的很多组件一样,例如争车位、偷菜等等,都是无限消磨时间的游戏。我也曾在上面花过很多时间,昨天晚上忽然想到,不如就做个外挂吧,让它来炒菜、升级、赚钱,然后不就失去游戏的乐趣了么?然后不就可以把时间省出来了么?

    于是动手写了个ruby程序,共88行代码,还是相当简单的。

    快速炒菜升级的需求很简单,不停的炒宫爆鸡丁,到时间就收菜,然后再炒宫爆鸡丁,无限循环下去。

    程序地址见:http://github.com/xiaodao/kaixin_restaurant

    运行方式:进入wap.kaixin001.com,点击组件,点击开心餐厅,把得到的url填到lib/restaurant.rb里面去,在命令行下运行lib/restaurant就行了。

  • 女人的考验 - [朝花夕拾]

    2010-02-13

    郭冬临的小品让我想起多年前的一个故事。

    那是一个雷雨的夜里,我跟同学在路边的一个小烧烤店喝酒。

    同学收到同事老婆的一条短信:“xx今天没回家吃饭,他跟你在一起么?” 同学本想直接回复说在一起,但转念一想,如果同事需要圆场的话,就肯定会提前打招呼的,既然没打招呼,那就是不需要圆场。于是回复说“我们没在一起”。 结果十多分钟之后,便收到了一条令我们错愕又捧腹的短信:”恭喜你通过了考验,只有你说实话了。以后我只让xx跟你一起玩。”

    恭喜你通过了考验。。。恭喜你通过了考验。。。!!

  • 三次僵局 - [敏捷开发]

    2010-02-05

    第一次,没有AC

    第二次,没有设计

    第三次,过度设计

  • 今天平安夜,跟老婆女儿skype。

    听女儿能够清晰的说出一连串的字来:“白北极熊”;“白兔,把门开开,快点开开,进来”;“1、2、3、4、5、6、7、8、9”;“爸爸抱抱我,亲亲我”;“爸爸再见”;“鞋掉了,鞋掉了”。

    她穿着白底红花的棉袄,有时候挤眉弄眼,有时候吐小舌头,有时候就冲我清脆的笑。

  • 今天胡凯同学在客户现场留意到这样一个现象:一个角落里面摆放着四台饮水机,但大多数时间都只有一个桶里面有水,其他桶往往都是空着的。

    于是跟透明一起,我们三个就这个现象画了一次系统循环图。

    从图中可以看到,有水的桶数越多,每个人换桶的动力就会越小,而每个人换桶的动力越小,又会导致有水的桶数减少,这个回路是一个调节回路;而另外一个回路呢,有水的桶数减少,会导致打水的等待时间变长,等待时间变长,会导致个人换桶的动力增加,从而又导致了有水的桶数增加,于是又形成了一个调节回路。

    因为调节回路的存在,所以会导致回路外的系统影响被调节回路给消化掉。不管打水的人数增加还是减少,它对“有水的桶数”的影响进入调节回路以后,这个回路还是会最终趋于一个平衡点,也就是只有一个桶有水。即便是我们通过增加“负罪感”来提高换桶的动力也是如此。

    所以当系统结构是一个调节回路,而我们又想让某个方面向我们所期望的方向倾斜时,我们能够做到的就是打破这个系统结构。也许我们可以发现在图中还没有发现的元素,它可以跟现有元素构成增强回路,然后我们想办法改变新元素的性质;也许我们可以改变系统现状,让它不再成之为调节回路。

    我们今天暂时所想到的,就是第二个做法,改变系统现状:把四个饮水机分散开,放到办公大厅的不同地方去,这样子“有水的桶数”就不会跟“个人换桶的动力”形成调节回路了。

  • 刘未鹏的博客上这样写:

    好资料,坏资料。好资料的特点:从问题出发;重点介绍方法背后的理念( rationale ),注重直观解释,而不是方法的技术细节;按照方法被发明的时间流程来介绍(先是遇到了什么什么问题,然后怎样分析,推理,最后发现目前所使用的方法)。 坏资料的特点是好资料的反面:上来就讲方法细节,仿佛某方法是从天上掉下来的,他们往往这样写“我们定义… 我们称… 我们进行以下几个步骤… ”。根本不讲为什么要用这个方法,人们最初是因为面对什么问题才想到这个方法的,其间又是怎样才想出了这么个方法的,方法背后的直观思想又是什么。实际上 一个方法如果将其最终最简洁的形式直接表达出来往往丢失掉了绝大多数信息,这个丢掉的信息就是问题解决背后的思维过程。

    知道了资料的好坏之分,我们也就可以知道如何更好的写文章,讲道理。

    学习一个东西之前,首先在大脑中积累充分的“疑惑感”。即弄清面临的问题到底是什么,在浏览方法本身之前,最好先使劲问 问自己能想到什么方法。一个公认的事实是,你对问题的疑惑越大,在之前做的自己的思考越多,当看到解答之后印象就越深刻。记得大学里面的课本总是瀑布式地把整个知识结构一览无余地放在面前,读的过程倒是挺爽,连连点头,读完了很快又忘掉了,为什么?因为没有带着疑问去学习。

    这跟我上一篇博客所讲的“主动思考”是一致的。

  • 月夜怀思 - [朝花夕拾]

    2009-10-01

    多少年过去了,乡村的夜晚还是一如既往的黑。

    也正因为如此,每次回到家里,总能看到星斗漫天,依稀可见银河的模样,或是明月高悬,旁边伴着一颗孤零零的小星。

    我最爱这样的夜,站在空荡荡的庭院里,陶醉于清凉的星光月色,任寒气侵上身来,每每第二天便鼻子透不过气。

    忽然想起十多年前的一个夜里,该是凌晨一点多钟的时候,我睡不着觉,便趁着月色骑车行了十多里地去看同学,到了村口,发现几天前的大雨留下的泥泞实在穿不过去,兴致也已尽,便作回转。那天,便只有这样一碧如洗的夜空,和不知照过多少深夜行人的明月,跟我一起走了两个来小时的路。

    以后还会有很多很多这样的夜色,只是到哪里去寻有着同样精力同样兴致的莽撞少年呢?

  • 昨天听默默的讲座,清一色的头脑风暴,完事以后大家都感觉特累。

    在一个头脑风暴里,当时是要每个组都给四天的课程安排agenda,我们组的人讲完以后,dreamhead说:我其实特别关注你的思路,因为你现在不是跟客户讲,而是跟公司内部的人讲课程安排,所以思路就很重要,你是出于什么目的来这样安排课程,这样安排会带来什么样的好处,这些一开始就是需要讲清楚的。

    唔,其实何止是没讲清楚,我很怀疑大家有没有自己想清楚为什么要这样安排课程;当时team的人都是匆匆忙忙的往白板上贴纸条,后来我强调了一下,告诉大家别只顾着零零碎碎的贴,自己心里得有谱,有一条线索把你贴上去的这些东西能够串起来,自己能按照这些纸条把几天的课讲完。

    不过dreamhead的话还是让我感触很深,在服从习惯做这样那样的事情的时候,一定要多问自己几个问题:为什么要做这样的事情?它给自己或是别人带来什么样的好处?有没有更好的方式来做这件事情?比如我现在用blogbus的编辑器写博客,旁边dreamhead就在用文本文件写,写完以后再往上贴。

    以后要时时提醒自己,让自己做事更有效率一些。

  • 首先是装mysql,参见http://2tbsp.com/content/install_and_configure_mysql_5_macports

    1. installation

    sudo port install mysql5 +server

    2. create databases

    sudo /opt/local/lib/mysql5/bin/mysql_install_db --user=mysql

    3. start mysql

    sudo /opt/local/share/mysql5/mysql/mysql.server start

    or

    alias mysqlstart='sudo /opt/local/bin/mysqld_safe5

    4. stop mysql

    /opt/local/bin/mysqladmin5 -u root -p shutdown

    然后就是装mysql的adapter,这里因为是用macports装的mysql,所以会装到/opt/local下面去,跟默认的/usr/local/mysql不同,用gem装就行不通了,参考官网说明:http://www.tmtm.org/en/mysql/ruby/,这里只需要把第一步的参数修改一下:

    ruby extconf.rb --with-mysql-lib=/opt/local/lib/mysql5/mysql/ --with-mysql-include=/opt/local/include/mysql5/mysql/

    然后再一步步走下去就好了。

  • 1. svnadmin create /home/jacky/repository/test (Note that this directory should be accessable by accounts other than root)

    2. svnserve -d --listen-port 8099 -r /home/jacky/repository

    3. vim svnserve.conf

    anon-access=none

    auth-access=write

    password-db=passwd

    4. vim passwd

    test=test

    5. vim authz

    [/]

    test=test

    6. cd /$cchome/projects, mkdir test, cd test, svn co svn://localhost:8099/test .

    7. edit /$cchome/config.xml, add "test" project

    8. commit something to svn://localhost:8099/test, and force build on cc