在软件工程研究中,被验证得最多的结论就是对于同等经验的两个不同程序员,在效率和质量上可能会有10倍的差距。研究人员还发现,这种差距也适用于团队级别上,也就是说在同一行业内的不同的团队也是如此。
软件开发中的个人效率的变化
首先发现不同人在编程生产力上的巨大差距的研究,是1960年由Sackman、Erikson以及Grant三个人完成的。他们研究了工作经验平均在7年的专业程序员,并发现最好和最差的程序员写新代码的时间比为20∶1;调试次数是25∶1;程序大小是5∶1;程序的执行效率是10∶1。他们还发现,程序员的经验和代码质量或效率并没有关系。
在详细地研究了Sackman、Erickson以及Grant的研究结果之后,我们可以发现他们所使用的方法中有很多缺陷,例如把使用低级程序语言和高级程序语言的程序员合在一起研究等。但是,即便把这些缺陷考虑进来,他们的数据也仍然表明,最好的程序员和最差的程序员之间的差距能达到10倍以上。
那次研究之后,还有很多其他关于专业程序员的相关研究都证明了一个结论:程序员的水平也分三六九等(具体内容参见本书中的参考文献)。
除些之外,很多轶事传闻也支持这种观点。在20世纪80年代中期,当我还在波音公司工作的时候,有个约80个程序员组成的项目组正面临着无法按时完成一项关键任务的风险。这个项目对于波音来说至关重要,所以他们把项目上80个人中的一大半换成了另外1个人,而这位仁兄单枪匹马地完成了所有的编程工作,并按时交付了软件。我并没有在这个项目组中工作,也不认识这位天才,但是这个故事是一位我所信任的人告诉我的,所以我相信这是真的。
这种差距并不仅限于软件行业。Norm Augustine的一份研究指出,在各行各业中,包括写作、橄榄球、发明、警务工作等,都存在一个情况,那就是行业中位列前20%的顶尖人才的产出占到了该行业总产出的50%,无论这些产出是得分、专利、侦破的案件还是软件 。你可以想想看,这还是有道理的。我们都知道,有的学生就是比其他学生优秀,运动员、艺术家甚至家长也是如此。既然这种差别存在于所有人群中,那么软件开发又怎么会例外呢?
巨大的差距带来的负面影响
Augustine的研究发现,由于有些人完全没有任何实质的贡献(例如不能得分的前锋、没有专利的发明家、无法破案的警探等),人与人之间的差距的实际情况可能比上文提到的数据还要大。
在软件行业中似乎就是这样。在多个已发表的关于软件开发效率的研究项目中,大约有10%的实验参与者无法完成实验任务。这些研究报告常常会这样说道:“所以我们从数据集中排除了这些参与者的结果。”但是在现实生活中,如果某个人“无法完成任务”,你就不能简单地“从数据集中排除他们的结果”了。你或者得等他们完成,或者得另外指派一个人完成他们的工作,等等。这里有一个有趣(而又可怕)的暗示,那就是在软件行业中,差不多有10%的人对项目产出的贡献是负数。
和此前一样,这也和我们在现实生活中的感受一致。我相信很多人都能够在共事过的人中找出符合这个描述的人。
什么造就了真正的“10倍程序员”
很多人并不喜欢被贴上“10倍”这样的标签,因为他们觉得人们会说:“我们团队中曾有个超级程序员,他牛哄哄的,每个人都不愿和他来往,要是没有他整体效率反而还要高些。”
通常来说,任何对10倍程序员的实用定义都必须考虑这样的程序员对于团队其他人员的影响。我也知道的确有牛哄哄的超级程序员。但更多的时候,那些牛哄哄的超级程序员其实只是普通水平的一般程序员而已,甚至还达不到普通水平。他们只是用牛哄哄的外表来让自己的表现看上去不那么差而已。我所共事过的真正的超级程序员们除了技术水平以外,通常还有很好的团队精神(虽然有时也有些例外)。
测量程序员的个人生产力的问题
由于很多研究都指出不同程序员的效率可以有10倍的差距,导致很多人产生了一个想法,那就是测量他们在自己组织内的个人效率。无论如何,这种想法所涉及的测量“活的”程序员的生产力和一般研究中所说的生产力有很大不同。
软件工程研究通常用完成某个任务所需的时间、每小时或每个月能写多少行代码或者其他一些标准来测量生产力。但如果你尝试在商业环境中用这些标准来测量生产力,那就会碰到很多问题。
生产力=每月产出的代码行数吗
软件设计是一件非确定性的事情,对同样的一个问题,不同的设计师/开发人员会做出完全不同的解决方案。如果我们用每月产出的代码行数(或者类似的标准)来衡量生产力,那么我们就默认了用10倍的代码来解决同样的问题的程序员就有10倍的生产力。显然事情并非总是如此。比如某个程序员可能会有一个绝妙的设计想法,结果只用10%的代码就解决了普通程序员需要100%的代码才能解决的问题。
有人曾断言,伟大的程序员写的代码总是更简短。事实上,编程水平和代码的简洁性之间可能有着某种关联,但我现在并不想做这样一个宽泛的结论。我只想说,伟大的程序员总是努力把代码写得更清楚,而结果通常就是更简短的代码。不过有时候,最清楚、最简单和最明显的设计和那些更“巧妙”的设计相比,需要更多一点的代码。在这种情况下,我认为伟大的程序员也会用稍微多一点的代码来避免太过于取巧的设计。无论怎么说,用“每月产出代码行数”来衡量生产力的想法都是有问题的。
Dilbert漫画中有一个故事:老板说每发现一个bug就奖励10块钱,大家都高呼这次赚到了,还有人想通过这个办法“写出辆小货车”来 。故事正好说明了这个问题,即如果你用代码的产出量来衡量生产力,有的人就会利用这一点,写很多很多也许完全没有必要的代码。这里的问题并不在于“代码量”这个标准,而在于旧式的管理思想,即“人们只会做会被考察的事情”。但你必须小心不要考察错东西。
生产力=功能点吗
“每个月的代码产出”所带来的问题有一部分可以依靠功能点的标准来衡量程序规模。功能点是一套“合成”的测量程序大小的标准。包括输入、输出、查询、文件数量等都被考虑进来,作为确定程序大小的参数。低效的设计/编程风格并不能产生更多的功能点,所以功能点这个标准不涉及代码量的问题。但是它却有一个更实际的问题,那就是你需要专业人士来计算功能点(很多公司并无这种人才),而且功能点和个人产出的对应也非常粗略,所以无法用于确定程序员的个人生产力。
复杂度呢
管理者常说:“我总是把最困难、最复杂的编程任务交给最好的程序员去做。所以无论用什么方法来衡量,他的生产力好像总是比别人低,但是如果同样的事情让别人来做,就可能花上两倍的时间。”这种现象很正常,但是也会影响我们定义和测量生产力的方式。
到底有没有办法可以测量个人生产力
前文提到的这些困难让很多人认为:要想测量个人生产力简直困难重重,没人可以做到。但我认为要想正确地测量个人生产力是可能的,只是需要注意以下几点。
- 不要指望仅用一个单独的衡量标准就能了解个人生产力的实际整体状况。你可以参照一下那些在体育比赛中搜集的统计数据。我们甚至无法用一个单独的标准来确定棒球比赛中击球手的水平。我们必须考虑打击率、全垒打、跑垒得分、上垒率以及其他种种因素。而且仅有这些数据还不够,我们还得去证明这些数据的意义。如果击球手的优劣无法用简单的标准来评断的话,难道程序员的个人生产力这样复杂的事情就可以吗?我们应该用的不是一个单独的标准,而是一整套标准的组合。这套组合标准的任务,就是让我们对个人生产力有更深入的了解。比如,这套标准可能包括准时完成任务的百分比、管理者的评分1~10、同事的评分1~10、每个月产出的代码行数、每行代码的平均缺陷数量、不当修复的比率,等等。
- 不要认为只要有了某种标准(无论单独或者组合)就可以对不同个体的生产力进行细致的鉴别了。要记住一点:这些个人生产力的标准只是为你找出问题,但是并不会回答这些问题。对这些标准的不当使用,比如用来进行绩效评估,不但会带来管理上的问题,也会造成统计上的问题。
- 整体的趋势常常比某个时间点上的测量结果更重要。将这些测量结果在不同个体间进行横向比较往往是得不出任何有意义的结论的。更有用的做法应该是将某个人的测量结果进行纵向分析,看看这个人有没有随着时间的推移而进步。
- 你要问自己:我测量个人生产力到底是为什么。在研究环境中,研究员们需要评估不同技术的效率,所以需要测量个人生产力。相对于研究环境,在现实项目中使用同样的测量标准产生的问题就要多得多了。在现实项目环境中,你想要用这些测量标准来做什么?绩效评估?这主意不行,原因刚刚才说过。分配任务?但我所访问过的大部分管理者都说他们不必测量也知道谁是他们团队中的明星成员,这一点我也相信。做预算?不行,不同设计方法导致的差距、不同的任务难度以及其他相关的原因使得我们无法有效利用这些标准来做项目预算。
在现实项目中,个人生产力的标准很难找到一个对项目管理有益而又符合统计学规则的用处。根据我的经验,除了做研究之外,人们想对个人效率进行测量的动机通常来自一些在统计学上不能成立的结论。也就是说,虽然我知道在研究中对个人效率的测量非常有意义,但是我认为在实际项目中却很难找到它的合理用处。
软件开发中的团队生产力差距
软件专家们很早就已经发现,团队生产力的差距和个人生产力的差距一样大,是以数量级为单位的。这里有一部分原因是因为物以类聚,人以群分,这一点已经由一次对来自18个组织机构的166个职业程序员的研究证明了。
又比如,在一次对7个完全相同的项目的研究中,研究人员发现,在这些团队中耗费精力最多的是最低的3.4倍,而对于程序的大小,最大的是最小的3倍。虽然生产力有一定差距,但是这次研究中的程序员都来自相似的背景。他们都是科班出身的职业程序员,而且都有多年的经验。我们可以合理地推测,如果研究对象的背景差异再大一些,那么他们之间的差距会更大。早期的一份对编程团队的研究曾指出,对于同样的项目,不同团队所提交的程序大小的比例可以达到5∶1,而所需时间的比例可以达到2.6∶1。
Barry Boehm等研究人员为了确立COCOMO II 成本估算模型而研究了超过20年的数据,并总结到:对于同样的程序,能力评分在15+的团队需要的时间是得分为90+的团队的3.5倍(以100分算)。如果一个团队比另一个团队在程序语言或者应用领域上更有经验,那么这个差距还会更大。
一个具体的例子就是Lotus 1~2~3第三版和微软Excel 3.0开发团队之间的生产率差距。两者都是在1989~1990这个时间段发布的桌面电子表格应用程序。由于很少看到两个公司公布相似项目的数据,所以这种死对头之间的对比就显得尤其有趣了。这两个项目的数据如下:Excel的工作人员总共消耗了50个工年 ,共写了649 000行代码 [8]。而Lotus 1~2~3消耗了260个工年,共写了400 000行代码。Excel的团队每个工年的代码产出是13 000行代码。而Lotus的团队每个工年的产出只有1500行代码。两个团队之间的生产力差距超过了8倍,正好证明了我们此前的主张,即团队的生产力也有差距,并且有着更大量级的差距。
有趣的是,这些量化的结果和局外人对于这些项目的感觉非常贴近。Lotus 123第三版当时是出了名的跳票王,比预期的时间至少晚了两年才发布。而在微软内部,Excel大受赞扬,被誉为是微软最成功的项目之一。对于真实公司的真实项目,这种程度的同类比较恐怕已经是能做到的极致了。
如前所述,这个例子说明了造成生产力差距的各种因素。Lotus和微软都煞费苦心地为各自的项目招募了顶级的人才,所以我怀疑团队生产力的差距并不只是由于团队成员的能力差距造成的,还牵扯到了很多组织结构上的因素,比如产品远景是否清楚、客户需求是否明确以及成员之间是否能同心协力,等等。
组织的因素会影响团队生产力的发挥。杰出的组织中个人能力平庸的团队可以超越平庸组织中个人能力杰出的团队。当然,像杰出的组织+杰出的团队或者平庸的组织+平庸的团队这样的组合也不是没有的。在这种时候,团队生产力(或者叫组织生产力)和个人生产力一样相差10倍也就不足为奇了。