畲族人

畲族人走了,就跟当时的绵阳人一样,回家。

我甚至连他离开公司的样子都没看到。最后见他的时候是在公司旁边刚开的西餐厅,和其他的几个同事在一起,谈着最近公司发生的事情。从西餐厅出来,我和其他几个同事要回公司处理些事情,他说他去取钱要去另外一个方向,我犹豫了那一秒要不要和他一起过去,后来还是和几个同事一起从另外一个方向走了。那便是最后一幕。

第一幕呢?

那是两年前,2008年7月29日,我大学毕业第一天上班,来到了传说中的格子间。公司的格子间是两个座位一个大格子,坐上去面对格子壁,背后便是格子间的另外一个人。我提着新买的工作单肩包,来到座位前,将包在桌子上,弯下腰启动主机电源,坐在宽大的椅子上。这时感觉有人坐进了后面的座位,XP的启动永远是那么的慢,为了打破“有很多人但是没有声音”的尴尬,我转过头,“你好”。。。。。。这个人有点黑,穿着25元一件的白衬衫,戴着一个黑框眼镜,说话声音很轻。如果不是那眼镜还有那声音的点缀,我觉得这人一定是个莽汉形象,所以也没太仔细看他的正脸。自报家门后,也寒暄地问了他几句,说实话没太注意他说的几句细节,也许这第一次对话本来就是为了等XP桌面出现。

时间转瞬到中午,大家都不说话面对电脑配置些环境,可能新环境的陌生导致大家好像都忘记了该吃饭了。这时候,我忘记是我还是某个人喊了句“一起去吃饭吧”,于是纷纷起身去旁边的小店吃盖饭。吃饭的时候大家放得开很多,因为都是刚刚大学毕业的。吃过饭后回公司,进办公室后我记得我是第一个进格子间区域的,赫然发现我那黑人邻居已经在位置上坐着了,然后我便又随口说了句“你吃了饭吗”。。。。。。那个黑人望着我,“我不是和你一起吃的饭吗”。。。。。。也许是他在吃饭的时候比较低调吧,没怎么留下印象,再加上之前没太仔细看他的正脸,所以我很尴尬。于是怀着抱歉的心情看了看他格子间上的工牌:Alan Lan。

晚上Trainer把我们叫到一个房间做自我介绍,Alan上台,说他叫阿兰,是畲族人,而且“兰”姓的人通常都是畲族人。我才知道,原来我旁边坐的个是少数民族,而且少数民族也会写代码的。。。。。。不知道怎么回事,当时仔细看起来,其实他不是很黑的。后来,大家都叫他阿兰了,而不是英文发音Alan。我想想挺有趣,因为“阿兰”比较符合少数民族的特色。

接下来的一幕,我和阿兰在这两年间经常提起。

那时候的培训项目非常血腥,时间压力紧,周围的一些同事也会因为“表现不好”而被炒鱿鱼。所以如果基础不好的话边学边做压力会非常大,显然,我和阿兰都属于“基础不好”的。幸运的是,在进公司之前的几个月时间里,我自学了面向对象的相关知识,以前在大学学生会里也做过网站,虽然这两者结合的没做过,但是至少心中有个清晰的思路可以指导自己一点点探索的前进。而阿兰就比较杯具了,虽然我不了解他的过去,不过从他的外形我就判断他在大学应该不是个学习型的,和我一样。

于是,这个杯具的一幕终于在一天下午上演了:同事们和我都在电脑前噼里啪啦敲键盘写代码,注意力非常集中在显示器上。这时候从我后面伸过来一张脸,“怎么做啊?”。。。。。。那样子,就跟上学的时候考试同桌凑个头过来看你的试卷,然后小声说“怎么做啊?”。
代码不是考卷,你就是看了你也不可能完全一个字一个字的抄。我跟他简单地讲了下,然后继续编程。
这个时候Trainer杰夫走过来,阿兰问杰夫“怎么做啊?”,杰夫还是老样子,“自己在网上Research(研究)”。。。这句话将阿兰打入冰牢,完全没有基础的他连研究的方向都没有,彻底地绝望了。
他的注意力再没放在屏幕上,而是低着头看着桌子。显然桌子上什么都没有。他绝望地轻叹了口气:看来我不适合做这个。。。。。。
这句话很轻,却在我耳边产生回响。我停止敲键盘,看了看坐在我桌边的邻居,我想起一句话“远亲不如近邻”,还是帮帮他吧,虽然不能把代码拷给他,但是至少要给他活下去的勇气。
他见我扭过头,不知道是自言自语还是跟我说,说他跟他姐姐打了电话,说他不适合做这个,想辞职。
于是我便关上屏幕,一心来试图安慰他说服他让他留下来。原因很简单,我当时以为我们俩应该是周围最差的了,但是我唯一的自信来自于他,因为我觉得我比他要稍微强一些。。。在巨大压力下这点自信非常宝贵,如果他坚持不下去离开了,我不知道我会不会继续自信地坚持下去。所以我把大学时期学的一点点说服力拿出来,告诉他“你是学计算机的而我是学通信的,我都坚持下去你难道坚持不下去吗”,“培训项目不就这几周,不要这么快放弃,努力一把再不行我就支持你走”,“你现在做你专业的事情遇到一点点挫折就放弃,以后也会这样”各种云云。
结果是他又重新打开了屏幕,去买了几本编程书,照着书上依葫芦画瓢一点点地敲代码起来。

这一幕最后成为我与他在一起的时候杀手锏,“记得吗兄弟,以前我救过你”。

下一幕便是他在武汉的日子,他和我分到了一个项目组,换了位置后依然是邻居。成心而论,我觉得他作为一个程序员,对公司的贡献主要体现在编程之外 — 足球队的组织。
那时候阿兰在公司上上下下非常有名,因为他总是组织公司足球队去他们学校踢,联系其他的对手踢球。那个时候我也在足球队,是守门员。我们通常是周六去踢球,踢完球后在他们大学后门堕落街去腐败。
但是作为一个程序员,不编程是不行的。所以在工作中我也有幸和他搭档做过项目,大体风格还是很和谐的,他做事也非常配合,只是我总是烦他喜欢用全局变量。
回想起来,工作中小矛盾偶尔也有一些,但大多数是一种平淡,至少他在我的记忆中这部分是非常平淡的。也许正是因为这个原因,他觉得在这个项目组学不到什么技术,所以向公司提出了申请,成功地调到了一个国内的项目组。

这个国内的项目组是为一个无锡的客户服务的,所以有机会被外派到无锡工作。在我的印象中几乎他在进那个国内项目组不久就被外派到无锡。于是,我找了一个机会请了年假,去无锡找阿兰玩。
那是在太湖边,我们逛累了,坐在了湖边侃大山。那个场景令人印象深刻,有阳光,有树荫,有湖风,有山水,非常地闲适。可能是工作太忙太累的原因,所以我们非常享受那一段安详的时刻。
之后,这个当年的邻居一直在无锡,我一直在武汉。只是偶尔他周末回武汉的时候一起吃个饭,但是这丝毫没能减弱我们的友谊,相反的是对彼此的信赖更加深了。

于是空闲的时候,我们俩会和绵阳人一起逛到光谷软件园的湖边,谈工作,谈理想,谈各自的爱情。绵阳人在湖边说要回四川,畲族
人在湖边说要回福建,武汉人在湖边说要还待在武汉。

再后来,畲族人的无锡项目结束,他又调回武汉。此时此刻,他去意已定,只是悬而未决,直到2011年1月27号,篇头最后一幕的发生。

正如现在看到的这篇文一样,大片的文字都留在了两年前的培训项目上,我想我们之间的友谊也正是那个时候建立起来并打下牢固的信任根基的吧。而且我现在相信,越是经历过磨难,历练的友谊越长久和踏实。特别是,这职业生涯的第一份友谊,第一个邻居。

等等,回忆需要倒带,倒到1月底那最后一幕的前几天,我请他吃“他听说过两年多都没吃过”的番茄鱼。席间,我低头吃着鱼,他问我,你什么时候来福州。我低着头把口中的鱼继续吃完,然后说,合适的时候,现在我也不知道。

 

 

让人“难受”的晨会

自从团队在2010年初发布“敏捷宣言”以来,几乎在每个没有电话会议的早晨团队都会开一个晨会(Daily Meeting)。这个会议时间很短,往往就10多分钟,主要是汇报各子项目组的项目运行进度,今天即将要做什么,碰到什么问题。

为什么每天要有这样的晨会呢?
1. 负责人要了解概况。
整个团队分为5个子项目组,每个项目组做的事情基本独立,项目运营负责人(Tech-lead)需要对每个项目组的情况有个“大概”的了解,在晨会上对每个项目组遍历一遍询问状态(status)是个快速地获得“全局情况”的方法。知道全局情况后便可以采取相应地有必要的措施。
2. 成员彼此需要互相了解。
既然是一个团队,所以5个子项目组不可能完全没有联系。比如平台组昨天测试通过了一个新的平台交付,那么在晨会上便可以告知项目组“你们可以去升级到新的平台了”。平常平台组和项目组各干各的事情,在晨会上可以正式提出一些有必要让对方知道的事情。
3. 练习英语。
我们的晨会是“English stand up daily meeting",意思是所有人必须用英文表达项目组的情况,同时听其他项目组的用英文汇报的情况。站着的原因是坐下来容易散漫,容易陷入细节,站着更容易控制时间,因为站久了会累。
4. 潜意识加强团队意识。
每天的工作基本上是一个子项目组中的几个人(一般两个或以上)合作,跟其他的子项目组运行着不同的项目,如果每天不”聚“一下的话,久而久之潜意识就会认为“自己的团队只有两个人”。

通常在这10分钟左右的晨会结束后,根据不同项目组的情况,可能会加开一些“附属晨会”。附属晨会是针对子项目组的,和晨会的不同点是需要讨论更细节的东西,比如技术细节实现,或者具体的技术难题。附属晨会一般只有具体的项目组参加,其他的项目组可以先回去工作了,因为没必要浪费时间去了解其他项目组的细节。这样的附属晨会通常只会在有4-5个人的”大项目组“中应用,小项目组回办公室后彼此交流交流就好了。
类似晨会,为什么大项目组中每天要有这样的附属晨会呢?
1. 项目负责人要了解概况。
一个项目整体上的进度已经在晨会上汇报了,但是一个项目是有更小的作战单元组成,所以为了确保项目的进度健康,有必要了解每个作战单元的进度。于是项目组负责人需要遍历每个人对自己任务的完成度。
2. 成员彼此之间需要互相了解。
把做项目比喻成爬山,你不是一个人在爬,不但你爬到哪里很重要,也有必要了解队友爬到哪里,毕竟都爬到山顶才算赢。也许队友此刻遇到一个技术问题你曾经遇到过,这样过去拉一把就避免了”重新发明轮子“。
3. 群策群力解决技术难关。
对个别成员遇到的技术难关,大家一起出点子解决。

那为什么说会”难受“呢?了解情况也会让人难受?如果答案是YES,那么可以轻松地推测出”一定不是好情况“,因为人们普遍在”表达坏情况、麻烦“的时候心理上会难受,进而影响身体上难受。

据我大致观察和自己的亲身体验,难受主要表现在如下方面:
1. 团队成员汇报项目进度时”顾左右而言它“
当负责人问: 小明, 你的任务做到百分之几了?这理论上应当是个很简单的答案,因为只用说一个数字就可以了,可是实际情况是小明会直接说:昨天遇到一个技术难题,blah, blah(开始描述技术难题细节)这时候负责人着急了,因为他关注进度多过于细节,并且他有责任控制会议的进度,所以他不得不打断小明说:等一下,你先告诉我进度,然后再说你遇到的技术难题。小明不得不说 50%(也许跟昨天相比没有前进多少),然后再开始说细节。
小明之所以一开始回避进度数字,一来可能是因为他不懂表达的习惯,应该先说”总“,然后再说细节;二来可能是因为他在想”如果说出进度没怎么前进,主管会骂人,其他的同事会鄙视我。“,尽管他想的内容往往不会发生,不过人们都习惯于停留在心理舒适区,而不想难受,所以顾左右而言它,或者直接诉说出了自己的痛处。
解决的办法就如上面所说,负责人应该果断打断他继续描述细节,必须先说完大体进度,才允许说细节。

2. 负责人回避追问项目进度
项目的负责人自己就是一个技术工程师,一般来讲有技术特质的人比较“善良”,善良的意思就是“不想让别人受伤”。所以他会在“打断别人说话”时感到难受,“明知道情况很糟糕而强迫别人报告坏消息“时感到难受。所以这样的结果是:
2.1 负责人和整个会议被带到技术细节,会议节奏被打断并失去控制。
2.2 项目组花了时间开会,却没有效果 –  负责人并不清楚项目的具体进展,这样对项目的控制只建立在”模糊的意识上“。
2.3 负责人对项目失去控制。当某一天觉得不对劲了,”长痛不如短痛“地仔细问进度,发现已经为时已晚,抢救都来不及了。
解决的办法是在初期,由主管在旁边”监督“负责人开会,一旦有负责人回避情况发生立即跳出来干预,然后把会议控制权交还负责人继续。并在会议结束后私下告诉负责人以后应该怎么做。

3. "乐极生悲“的技术讨论
对于工程师来说,在晨会上和大家讨论技术问题是一件很快乐的事情,特别是很乐于表达自己解决不了的技术问题以期待别人能够提供帮助。这时候会有三种情况:
1. 有一种解决方案。某一个人提出解决方案,说出来大家听了之后感觉可行,也没有其他的办法了,所以皆大欢喜,散会。
2. 没有任何解决方案。讨论了半天,总是没有解决方案能够解决根本问题。这个时候会议的时间在悄悄地流失,负责人应该警惕地看着表,一旦到达预期设定的时间线便应该大叫"cut, 这个问题我们之后在讨论,早晨的时间非常宝贵,大家回去先做简单的部分,做完了其他的只剩这一个问题时我们再来讨论”。于是,散会。
3. 有两种解决方案。这种情况发生于两个人同时提出两种解决方案,这两种解决方案都可以达到效果,但是因为两个技术工程师都坚持自己的解决方案是“最好的”(要面子,争强好胜,不妥协),于是会议进入“无休止”的争论期,以“评选”出“最好”的解决方案。其实这是在浪费时间,两个可以进入”无休止争论期“的解决方案按理说应该效果”差不多“,按CEO教的方法便是抛硬币 — 随便选一种,然后执行下去,不用担心

2010岁末iPhone项目总结

这是一篇迟到的总结,原因是此iPhone项目从2010年12月初做到12月底,31日晚上7点才将最后的包交付出去。一般来说项目团队都会精简成2人,但是由于这个项目极具战略意义,客户副总裁是Project Owner,我们将5个人全投入进去,美国那边也投入了全部的资源,所以这个项目还比较有意义。iPhone开发技术见长是一方面,从项目角度来说也学到了不少的东西。

先介绍下背景:
需求方面:11月底来需求,需求不是正规的文档而是一封简单的Email,大体是关于为某行业建立一个全方位的apple平台解决方案,架构是Server + 客户端。这个解决方案以前我们在客户公司平台实现,所以需求较熟悉。
团队方面:能够投入的项目组的有ABCDEF 6个人,其中5个DEV,1个QA。A之前做过一个iPhone项目的UI coding,可认为是高产出DEV,实际他是Tech-Lead,也需要承担沟通的成本。B技术素质好,领悟力高,也做过iPhone项目的自动化测试,有iPhone编程能力,可认为是技术攻关DEV。C也做过iPhone项目,编程技术一般,可认为是一个普通的DEV。D是实习生,聪明但是粗心思考问题不全面,iPhone开发基本不会也错过了之前的iPhone培训,DEV。E是一名成熟的DEV,但是从来没做过iPhone开发,不过他在前期会有其他的事情,所以属于兼职DEV。F实习生QA,没测试过iPhone项目。这里要描述一个事实,人力资源不能变。
设备方面:4台mac mini,2台iPod Touch。意思是最多只有4个DEV可以同时工作。
时间方面:12月底之前完成第一阶段,基本功能实现;之后第二阶段就是把第一阶段做成可配置。

下面是做这个项目的一些经验,感悟和思考:
1. 谁偷走了我的时间?
对于项目而言排一个合理的时间表很重要,一方面是方便追踪项目的进展情况,二方面是给客户信心,因为这是我们团队第一次做iPhone的项目,而且这个项目直接就是重要的战略级产品,客户和我们心里都没底。根据团队方面的背景,有这批没有经验的人开发这么一个产品,我很想把时间线订成2个月,但是事实不行,因为这个产品因为1月份的展览必须12月底交付。
时间线第一个版本就是假设工程师都是成熟的,在12月底可以把所有的功能都交付。我心里没底,但是我知道,如果时间线都不能把所有功能交付,那真实运作起来就一点希望都没有了。
时间线第二个版本是在12月初修改而来,最重要的更新是灵活地根据“复用”原则。比如Functional A 和 Functional B都是非常重要的功能,一般的思维就是重要的功能要先做而且必须做,所以会安排两个工程师一个做Functional A一个做Functional B。但是后来我发现Functional A 和 Functional B从UI上很多东西可以复用,一部分逻辑也可以复用,面对不会iPhone开发的工程师们,可以让有经验的DEV A先做,等做完后,其他的工程师再去“依葫芦画瓢”甚至直接拷贝代码,这样会大大加速Functional B的开发时间。根据这个原则,实际上12月份出这个产品就有很多buffer了,但是这个建立在一个前提下,工程师是成熟的iPhone DEV。
另外一点就是时间线要考虑到工程师的成长性,因为他们的产出不会永远都是“什么都不会的人的水平”。所以一开始就预料到面对这样艰巨的任务,这样的人力资源,要把时间细致地用。比如把一个月分为4个星期,每个星期根据不同的人属性成长安排各不相同。

2. 没有FRD的需求
这个项目没有FRD,基于几个前提:我们团队和客户方项目经理合作两年,彼此间较默契;工程师A和E之前在客户平台上做过类似的系统,对需求很清楚。但是一个项目光知道大体的需求还不行,对于iPhone平台细节的描述是之前没有的,所以有一个FRD则是非常必要的。客户的女项目经理承诺第一周给FRD,后来直到第三周都没能给出来,巧的是团队也刚好从第三周才开始做客户端具体的功能,所以之前影响不大。这个时候QA已经开始抱怨需求不明,对于点一个按钮该如何QA和DEV之间各有各的意见,最后只能求助Tech-Lead。但是诸如此类根据人的判断来定需求毕竟不踏实,于是就发邮件给项目经理要FRD。
以前提到过,项目经理一直忙于1月份展会的事情,所以没能做。有一次电话会议上一向强势的副总裁也帮项目经理低声求情,问能否先不要FRD,有不懂的随时沟通。连副总裁都低头了,再这么也要给个面子啊,于是发邮件给项目经理,大体的意思是“既然你们领导都帮你们求情了,这次就饶过你了吧,不要FRD了,不过我们会加强沟通以确保是你要的”,这邮件让那个女项目经理感激涕零,连夸我们团队专业,让她Very happy。
那怎么加强沟通呢?遇到需求不明的情况,我们会建立一个表格列个矩阵,把所有的情况列出来,然后写入我们的理解再发过去给她确认;或者画流程图,根据FRD屏幕的截图来表示我们对workflow的理解;每天跟她发邮件说今天的情况,以及需要从她那里拿到什么;团队内部每天两个会议,各10分钟或以下,晨会制定今天的任务,晚会总结今天的成果。

3. 你真的做完了吗?
前期DEV A做UI,实习生被安排在DEV A做的UI上面做逻辑(其他的工程师各有各自的安排)。结果实习生很快就来催DEV A做完了UI没有,因为他之前的逻辑做完了, DEV A很高兴因为逻辑做得很快,结果DEV A为了避免耽误实习生做逻辑的时间,特地周末赶来加班把事情提前做完了。结果一测试才发现实习生做完了的意思是“他认为”他做完了,实际上没有,甚至像没有做一样,结果不得不让这次中间版本推延。DEV A就是Tech-lead,因为他的UI做完后其他的工程师可以开始复用,所以DEV A就停止开发,转变为代码评审,专门针对实习生和基础不好的DEV。代码评审结果很不错,找出很多东西,经过总结,各个工程师的开发质量有所提高,也不会再出现“做完了”像没有做一样。

4. 技术能力和项目要求不匹配怎么办?
这个在项目初期就提出了Risk,并有三个解决方案:1. 加班,用时间弥补能力;2. 开通和上海总部资深工程师的沟通渠道;3. 让客户减需求。实际最后这三点解决方案都达到,
加班只用了第二个星期的周末一天,其余每天工作晚一点;
向上海总部的求援信基本都得到回复,而且效果很好;
减需求比较巧妙,不是我们提的,而是副总裁自己提出来的。减的需求都是技术上很困难实现的,我们去问了客户公司一个资深工程师,结果他也说“没想法”,所以副总裁自己就决定这功能不做了。

5. 不同时期,不同角色
DEV A是Tech-Lead,因为有经验所以需要写代码,另外这个项目人员大多不成熟,需求也不明确,所以需要大量的沟通成本。12月的开始两个星期几乎DEV A是最忙的,又要写代码,又要沟通管理团队。直到DEV A的第一个模块UI写完了,DEV A才变身为Tech-Lead,开始做代码评审,开始专注需求分析,沟通,管理。在第二个星期和第三个星期,团队成员开始成长,基本上到第三个星期中期以后,DEV A的角色就彻底消失了,全身