四年祭

 
2008年7月29号–2012年7月29日。工作四年,相当于又一个大学毕业。
 
前两天,四年前的一个同期生,发了一封邮件题为"四年祭"。本来最近连续五个星期没休息,每天沉醉于一百多封邮件中,以及时时刻刻在项目时间线以及客户咆哮的压力下的焦虑,让我无心想到这一茬。可是在众多邮件中发现了这封,还是让我心中泛起一阵涟漪。
 
四年前那天早晨,从和高中同学合租的房子里爬起来,这是我第一次告别校园象牙塔走进职场。
 
走进公司,领了工牌,在会议室里和一群陌生人坐在一起,彼此之间互相熟悉。依稀记得上午浑浑噩噩过去,开了电脑不知道应该干嘛。中午一个小时休息,立马回合租屋淋浴将早上的紧张和压力洗掉,又和同学胡乱吃了点,下午一点全员工大会。
 
在全员工大会上,发现大家早早地来了,以至于中后排位置被坐满,无奈只好坐第一排。
 
期间总监在上面讲服装令,说了一些关于着装不能太随意的内容,还想和新同学互动问问大家觉得应该穿什么。当然,没人举手。于是,经理出来点人。我好奇的看看经理在不知道名字的情况下是如何点人。于是,杯具了,我没有从大学课堂中吸取经验–老师点人的时候是不能和老师发生目光接触的。
 
我被经理点起来,问我叫什么名字。我看了看发给我的大白信封, Kenny,并解释说这不是我想要的名字。随后就阐述我对服装令的观点,我说软件工程师在企业的后台,不见客户,所以不用穿太正式,而且穿太正式容易限制自己的思维云云。
 
总监问,那你觉得今天在场的各位谁穿的比较得体呢?一下把我问住了,我回头扫射了下大家,又看了看自己,心想不能空白太久,只好说,穿成我这样就可以了。全场都笑了。
 
我依稀记得那天我穿的是有领休闲白衬衫加牛仔裤旅游鞋,我真心觉得这一套应该比较实在。
 
随后,几个trainer被经理叫到了台前一致排开,经理说让大家来找茬,看看他们穿衣有什么不合理。这下有些同学举手了,上来了几位,还差人,经理又点了两个,最后还差一个人。良久没人。当你杯具过一次后,一定有第二次。我又被拉上了。
 
我被分配了一个男trainer马文,他穿着很专业,所以找茬难度很高。最后到我回答时,我还是发现了他身上衣服有明显褶皱。经理兴奋地问我是不是QA,我摇头,我说我是。。。我是干嘛的?写代码的?她说那你是Dev。
 
于是,我的Dev生涯开始了。之后便是大家熟悉的一切:没日没夜地培训,然后进入一个企业级信息化团队写一种说出去没人知道的代码。
 
当时想过要不要换一个热门的编程语言,可是一来项目没做完,二来又没多的人过来接手。于是就待下来了。之后,乔布斯掀起了苹果风暴,我们不是一直做没人问津的移动开发吗?一下子野鸡变凤凰。我心想这算是人生第一次经过大落大起了。
 
第一个iOS项目起来时,勇敢地接手成为一个iOS开发者。当时武汉分公司这边没人知道,耐着性子求教美国和上海的工程师,总算把项目做完了。
 
随后又做了好几个iOS项目,直到2011年11月,把服务的美国公司做到被另一个巨头公司收购。歇了半年,团队猛然扩张一倍。
 
三年来一直做项目,今年6月一次偶然的机会,调到产品组,换了一个新的角色,在巨大的压力下工作到前天,总算落地。
 
这些故事让我自我感觉就是屌丝一枚,却总幸运地上演逆袭的故事。屌丝逆袭俨然成为一种风格,勇敢飞过客户和公司中间的各种风浪,却没有结束。项目组从4年前的5人发展到现在的将近50人规模,一下成为公司第三大项目组。这些成为我一路辛苦下来的欣慰。
 
四年大学毕业,重新启动后进职场;四年职场拼杀,重新启动后即将以新角色登场,任重道远。
 
一路向前,勇敢飞,与诸君共勉。

阴错阳差的结对编程实践

 

我所在的团队服务于一个美国创业型公司,聚焦于企业级移动信息化。团队兢兢业业做了3年,让该公司被一个更大的支付公司给收购。期间有幸和美国的顶尖架构师,咨询,以及项目经理合作,收获颇多。
 
团队里面的项目组规模始终保持在极小规模,2个开发或者一个测试一个开发再或者一个测试两个开发,捣鼓一个月便将一个项目搞起,接下来转战另一个项目。同时,随着时间的推移,每个项目组身上除了新开发的项目外还负担着历史项目的维护。
 
该创业型公司对“流程重视程度不高”,我不确定是不是类似的创业公司都如此,但这一点我相信也是有充分存在理由的:
1. 创业型公司人少。流程一般针对于大规模团队有很好的实践价值,因为人多,应当用流程管人而不是人管人。基本的流程当然也应该有,不过大多数都是用“简单真实的对话”取代了复杂繁琐的流程。
2. 创业型公司人精。人人都是多面手,养不起闲人。大团队里面每个人接近螺丝钉,所以鸟瞰下是流程让每个零件正常地运转;小团队里面每个人处理几方面的事情,所以鸟瞰下是人将事情连起来,人去推动事情发展。
3. 创业型公司成本意识。创业型公司资源不如大公司多,所以更快。同样一个项目,可能大公司有底气一做半年保证“高品质”(结果怎么样再议);创业型公司则赶紧开始,然后在过程中不断地去调整自己的目标。
4. 创业型公司变化大。不管是人还是环境还是项目,当变化产生时,相应地就需要变化对策。而流程,从字面意思来说就是个固定的产物。如果制定一个流程,反复修改,所带来的时间成本不如没有一个写在纸上的流程,只有目标 — 用任何可行合理合法的手段达到目标。
 
一. 从流程改进谈起
我所在的公司很重视流程,很重视质量,甚至每个团队都会配备一名全职或者兼职的质量管理监督专员(SQA:见软件开发中的角色扮演)。SQA主要是为团队制定流程,发现问题。
 
正如前文所说,现在我们的团队和美国的顶尖架构师工程师一起合作开发解决方案级别的产品。既然是合作开发,我们的代码都是彼此共享,这样美国那边的工程师架构师就会偶尔“自发地“代码评审一下。坦白说,中国工程师的代码质量总体来说不如美国那边的,再加上不同地区的代码风格不会完全一样,所以美国那边发来一份代码评审的结果。
 
这份结果发来,引起了双方领导的“高度重视”,立马开会整理流程。总体来说,为了确保我们团队的质量,要把FTR重新做起来。
 
二. 所谓的FTR
FTR, Formal Technical Review, 正式代码评审。大体上来说分为以下几个步骤:
1. 需要被代码评审的项目组首先发出一封正式的Email,里面会写有要被评审的内容,正式代码评审大会的时间,附件里面有需要被评审的代码。
2. 收到邮件的工程师需要在正式代码评审大会之前完成代码评审的任务,同时有个模板可以记录你发现的错误。
3. 在正式代码评审大会上,大家围坐在一个会议室里,用投影打开代码,顺便对着合并好的代码评审记录一条条过错误。在大会上,只确定每条错误到底是不是错误,如果是,则跳下一条,然后工程师回去改进;如果不是则标记一下。
4. 正式代码评审大会后,被代码评审的项目组需要将提到的错误全部改进,然后再以邮件的形式发回给代码评审的人。
5. 代码评审的人需要对结果进行验证(Verify),看是不是改好了。这一步形式多样,有的时候开会,有的时候就“看看”。
 
三. 代码评审的好处
根据SQA的记载统计,大部分有价值,高隐蔽性的代码缺陷是从代码评审查出来的,而不是QA测试出来的。而且坊间有很多传说,比如Google公司所有的代码必须经过代码评审才能被Check in.
 
从一个团队的构成角度上来看,一般有少数高级工程师,加上普通工程师,可能再加上一些刚毕业的小弟小妹们。分工也各有不同,不如小弟小妹们可能会被分配做一些单独的简单的模块。所以,由高级工程师领导的针对小弟小妹以及普通工程师的代码评审就显得价值非常高,因为往往可以极大地优化原来的代码。
 
四. 代码评审的尴尬之处
尴尬一:时间紧张
作为创业团队, 每天的任务很紧张,有的时候甚至需要当天交付,就算不当天交付,也需要在当天的结束交付一个报告汇报进度。如果赶工,那么质量得不到保证,所以必须要代码评审。而FTR,正如那一节所说,虽然看起来很正规,实际上每一个步骤所耗费的时间不少,而这些时间成本对于一个每天任务很紧张的团队实在难以接受,同时美国那边的管理团队也不太愿意一天的时间有半天在代码评审,因为他们也背负着客户极高的产出压力。
 
尴尬二:业务不熟
文章前面提到,我们的项目团队是分为小组,每个项目组做不一样的项目,业务关系基本不一致。所以试想当一个工程师,突然收到一份FTR的邮件,里面放了20几个.java文件,说“你看吧”,从哪儿看起?每个.java类方法干什么用都不知道。于是这样的FTR经常的结果是:只能找出一些Coding style(代码规范)的问题。
 
尴尬三:为了流程而流程
有的时候一个高级工程师和一个普通工程师在一个项目组,这个高级工程师会去代码评审这个普通工程师。因为只有两个人,所以可能就在座位上两个人对着一个屏幕解决了。而这个时候SQA对FTR的流程判定是需要有一个代码评审的结果,否则谁知道你代码评审了没有?所以即使两个人可以很快解决,也需要再写一份文档把错误结果先填上去,然后另外一个人全标记为"Fixed".
 
五. 结对编程实践
当时在流程讨论会上,联想到代码评审的三个尴尬,于是我建议我们做一个新的尝试:
1. 搬两台机器到会议室,一台机器连投影仪,一台机器连一个普通的LCD。
2. 连投影仪的机器显示代码的开发环境,最好接上网线和办公室内网连接。连LCD的机器只显示代码评审结果的文档,由记录员控制。
3. 代码评审开始后,被评审的人会向各位评审员展示自己项目的代码,并且边展示边讲解,他的目标便是把整个需要评审的代码从头到尾都讲完。
4. 代码评审员会随时打断他的讲解,并提出疑问或者改进办法,如果一旦确定有一个错误,则……
5. (关键步骤)被评审的人会当场修改代码,因为连接的是开发环境;同时,记录员随手记录这个错误。
6. 一直循环第3步到第5步,直到代码都被评审完。
 
这样结对编程式的代码评审好处:
1. 一次会议,两份产出:改良后的代码和评审错误记录。改良后的代码可以直接提交给客户,评审错误记录可以直接交给SQA,并对他说&ldq
uo;我能”。
2. 评审过程中,被评审的人自己写的代码当然熟悉业务逻辑,于是在讲解过程中,来自其他项目组的评审员一来可以了解代码所实现的业务逻辑,二来可以丰富自己的视野 — 多参加几次不同项目组的评审基本上可以对很多项目有所了解,而评审员通常是高级工程师,所以可以在关键人力不足的时候成为重要备份。
3. 评审过程中,有一段时间是被评审的人当场修改代码,评审员看着他改并提出指导意见。这不是结对编程吗?取代了以前看冷冰冰的评审结果,而且身为高级工程师的评审员会对他的编程技巧/思路进行当场指导,参与过的普通工程师大呼过瘾,从高级工程师那里学到了很多以前自己一个人编程学不到的东西。在此过程中,经验无损耗的传输,不但是评审了代码,更是培养了新人。
4. 关于时间问题,这样的会议第一次会费时一些,大概2-3个小时评审一个项目。不过相比较原来的FTR还是要效率高一些,区别只是大家在不同的时间地点和在同一个时间地点。从第二个星期开始便快好多,因为只评审改动的代码,同时评审员也对这个项目的业务逻辑有所了解。需要注意的是,因为每次代码评审投入的人很多,所以一定要保持清醒头脑和敏捷的思维,保证第一次的2-3个小时是有效果的!这个和结对编程对两个人的要求一致。
 
六. 流程大会后
就当我写会议纪要时,我才猛然想到“结对编程”这样的概念,然后满心欣喜。因为现实工作中的一些窘迫和紧张的时间,逼迫我们“出此下策”,没想到就碰巧成就了传说中的一种我们想尝试却因为没有这样的人力和时间成本尝试的编程方法!
 
是为记。