所有软件开发者都知道,即使九个女人一起努力也不能在一个月里生出小孩。或是如佛瑞德·布鲁克斯(Fred Brooks)更优雅的说法:“无论多少个女人,孕育一个生命也需要九个月。”(《人月神话》,17页)。意思是,有一些软件开发任务是佛瑞德所说的“顺序约束的”。它们需要的时间是一定的,无论多少人参与时间都不会减少。
从另一方面说,是不是一个女人就一定能在九个月生出孩子呢?假设我们要负责一个New Baby项目,就是要在九个月里生出一个小孩。我们如何来安排这个项目的人员?太简单了吧,既然九个女人也不能在一个月里把孩子生出来,我们就没有必要多配人员,所以我们就只需要找一对夫妇,保证他们都有生育能力并且都想要宝宝,这就万事俱备了。但是等一下,他们超出九个月时限一个月以上的几率有多大?事实证明,几率相当高。
通常一个月里一对夫妇怀上宝宝的几率大约是16%。不幸的是,怀上之后的头三个月通常有15%到20%的流产率。所以,现在我们找的夫妇在九个月内生下小孩的几率只有.16 × .85或是13.6%。如果我们想计算一对夫妇生孩子所需的平均时间,可以使用早前一篇帖子的类似数学方法。但是假设我们的时间限制很严,我们必须在九个月生出小孩的话,我们可以做些什么呢?
当然有办法。人海战术。既然找一对夫妇有86.4%的几率超期,那我们找两对夫妇的话,他们都超期的几率就只有 .8642 或74.6%。找三对夫妇的话,超期的几率就会下降到64.4%。要计算出在以几率P保证按时完成项目的条件下需要多少对夫妇,只需要将P带入这个算式:
当然,如果我们要真的保证按时完成项目,代价会很高——实现90%的按时完成率,我们需要16对夫妇。但是,如果New Baby项目足够重要,时间限制足够严格,这样做就是值得的。那么软件开发和生孩子有什么相似之处?让我们看看布鲁克斯是如何比较生孩子和软件开发的吧:
无论多少个母亲,孕育一个生命也需要九个月。由于debug的次序本质,很多软件开发任务也具有这个特征。”(《人月神话》,17页)
不幸的是,我没能找到他在哪里解释过“debug的次序本质”,我却发现debug很像生孩子。而且我说的相似,不是两者都非常痛苦并且完成之后都有巨大的解脱感,而是指发现一个bug和怀孕一样有很大的偶然性。基本上,你找bug时,你在一定时间的尝试中能找到bug的几率是p,就像一对夫妇每个月试图怀孕的成功率只有16%一样。如果你是一个熟手并且对你的代码很了解,p就会高些,但它始终是个随机因素——如果你的排错方向错了,你要过段时间才能意识到,而时间已经损失了,但如果你当初是从另一个方向开始,也许立刻就能发现bug。这就是无法估计发现bug的时间的原因。也许你五分钟过后就能发现它,或是过了五周才能发现。一旦你发现了bug,当然你还得修复它,但修复的随机性就没有那么强了——不像怀孕,怀上之后总是要持续九个月,修复不同bug的工作量或多或少,但你发现它之后通常马上就能知道工作量的大小。而且就算不是对大多数人,至少对于很多人来说找bug是困难的——只要你真正地找到了它,修复一般都是小事情。
上述分析意味着,我们可以运用与New Baby项目一样的技术来加速debug——人海战术。假设还有十天我们就要发布一款软件,它还存在一个严重的bug需要找出来。假设我每天能发现它的概率是10%。我10天都发现不了它的概率就是(1 – .1)10或是约35%。但如果有其他人也能找bug——比如一个编程搭档——他每天发现bug的概率也是10%,我们每天分头工作。那么到发行时bug仍逍遥法外的概率就会降至12%。如果我们的人手还能多几个,漏掉bug的几率还会更小:三个程序员对应4%,四个程序员对应1%,五个程序员对应0.5%。
很明显,这项策略运用的前提在于,多个程序员都要对代码足够的熟悉才能做出贡献。在我看来这是对例如结对编程和代码集体所有权等实践支持的强论证。随之而来的是一个有趣的问题,如果你有足够多的程序员来进行这样的debug,是让他们独立工作好呢,还是因为“三个臭皮匠胜过一个诸葛亮”,而让他们结对工作?