第三章 根除低下的效率
第二节 2002年6月1日:“闲置人手”
你的开发团队两周前达到了“零Bug反弹”(Zero Bug Bounce,ZBB),你突然意识到,你又迎来了一个“工作淡季”。任何一个遇到过零Bug反弹的开发人员——其工作成果(产品)已打包出售,都了解这个“工作淡季”。但如果你的团队是提供互联网服务的,那么你现在可以停止阅读了。(等一下,你一开始读本栏目的时间哪来的?回去干活!)
作者注:零Bug反弹(Zero Bug Bounce,ZBB)指的是项目中所有的功能都已完成并且每个工作项目都已解决的那一刻。这个时刻很少会长时间持续。通过进一步的系统测试,通常在1小时之内就会有新的问题暴露出来,随后团队又必须埋头去工作。尽管如此,零Bug反弹意味着项目在可预见的将来就要结束了。
顺便说一下,我的团队现在做的是一个互联网项目,我们每个月都尽量开展一些激励活动,并分享各自的阅读心得及创意。这是个秘密——精益与敏捷,宝贝!详见第2章。
零Bug反弹标志着团队的掣肘由开发人员变成测试人员(如果问题在项目经理身上就没有类似的这种转变)。在处理完产品出货后两周内新Bug的冲击波后,大部分开发团队进入了“时而赶工,时而空闲”的模式——当有新Bug分配过来的时候奋力去解决它,否则就闲着不知道该做什么了。
最可怕的是,“工作淡季”有时候可能从零Bug反弹开始,一直持续到下一个版本的第一个里程碑。这在大项目中可能有几个月之多!开发经理手上总是忙着各种各样的事情,因而很容易就会忘了其实三分之二的团队成员都闲在那里。你知道他们怎么说闲置人手的——嗯,不是很好听!
宝贝干了件蠢事
以下是闲置的开发人员经常做的一些坏事:
偷猎Bug。零Bug反弹之后,你的团队应该处于“禁闭”状态,这意味着,所有Bug在被修复之前都要通过分诊会议的慎重考量。闲置的开发人员有时坐在他们的位置上,敲击RAID(现在叫Product Studio)上的F5功能键等待Bug的出现。如果通过这种方式没有发现Bug,他们就会把视线转到正在被分诊讨论的那些Bug上,挑一个有趣一点的,然后开始研究它。在你知道之前,他们可能已经有了一个修复方案,并且正伺机悄悄地把代码签入进去呢……这就是偷猎Bug!一个有自尊的开发者不应该做这样的事情。
作者注:在软件工程中,Bug通常是指代码中的错误。然而,微软内部使用Bug这个词泛指跟产品相关的所有增加、删除或者修改。但大家对外一般称这些为“工作条款”,其中有一些也可能是代码错误。我更喜欢“工作条款”的说法,这样就能把那些真正的Bug区分出来。
谁知道分诊团队是否会决定修复那个Bug呢?谁知道哪个真正的Bug被修复了呢,并且会不会引起相关的另一个或大或小的Bug呢?对于潜在的重大问题进行一点调研是可以的,但绝对不要偷猎!
修复尚未登记的Bug。现在有一个Bug通过了分诊,你正在进行修复。这时你注意到,在你修改的代码附近有其他更多的Bug(通常这些Bug是由以前的修复引起的)。但不知怎么搞的,这些Bug还没有被人报出来。你看到了这些代码,而其中的错误也尽收你眼底。为什么不一起把它们都修复了呢?喂!就此打住!
开发团队通过代码复审来避免这种可怕的事情。在“可信计算”时代,团队应该在整个项目周期内复审每一次代码签入。当团队处于“禁闭”状态时,要保证有3双眼睛(即代码改动者本人和另外两个开发者)同时审查每一次的代码改动。至于开发人员在修复一个Bug时发现的其他Bug,至于你发现的其他Bug——登记,会诊,再跟踪处理。
作者注:《凯文与霍布斯》(Calvin and Hobbes)连环漫画系列中有这么一个故事:凯文对一只苍蝇慈悲为怀,打开前门让它飞出去。结果呢?这只苍蝇非但没有飞出去,反而另外3只苍蝇飞了进来。这就是为什么从项目的开始到结束都要对每一个Bug进行研究和分诊的原因了。我的团队曾经在我们的产品发布前一个月的时候改变了一个参数的值,结果一周之后,全公司的测试人员都发现,只要打开CD托盘,所有的应用程序都会停止响应。最后,我们往回追踪到那个看起来无关紧要的参数,并把那个改动撤销了才解决问题。这种事情真实地发生在我们的周围,只是你未必知道而已。
修复标为“延期”的Bug。大家知道,被标为“延期”的Bug在产品发布给生产商(Release To Manufacturing,RTM)之前是不能去修复的。那么,是不是应该在计划下一版产品的时候去修复它们呢?不对!当初在项目的进行过程中,产品的相关团队对“哪些Bug对我们的客户影响最大,因此必须在发布之前修复”作了判断,但这种判断在产品没有真正发布之前是无法验证的。当产品发布之后,你就没必要再去猜了。“产品支持服务”(Product Support Services,PSS)、Watson和“微软咨询服务”(Microsoft Consulting Services,MCS)会告诉你的,它们很中肯。那些标为“延期”的Bug只具有参考价值,用于理解为什么这些Bug当初没有去修复。但是不要猜测客户会怎么想。你要做的是,关注用户反馈,修复真正影响用户的那些Bug。
重写“丑陋”的代码。开发人员讨厌“丑陋”的代码。这些代码常常麻烦不断,可读性差,难以维护。因此,当开发人员手头有空的时候,他们经常自言自语:“哈,我手头没有规范书,因此不能开发新的东西。我为什么不趁此机会重写那些讨厌的丑陋代码呢?”他们知道,如果给第二次机会的话,他们能够做得更好。他们也的确可以做到。他们可以在第二次的时候,重写出漂亮得多、清晰得多的代码,而且比第一次写的时候少了很多Bug。
令人遗憾的是,重写的代码实际上将比当前的丑陋代码带来更多的Bug。因为当前的丑陋代码是在第一次编写的基础上,经过了几个月甚至是几年的测试和修复之后才达到的质量水准。
有时候重写是必要的。重写可以提高代码的性能、扩展性、可靠性、安全性,或者对于新技术的适应能力。在这些情况下,应该把重写当做一个功能来对待;像处理其他功能一样,写一份规范书,然后为它制定时间表。否则,不要做代码重写这种愚蠢的事情,它只会重新引入一大堆令人讨厌的Bug,而且还对客户价值没有丝毫的贡献。