少于 1 分钟读完

准确估算软件项目的时间有什么价值?低估和高估哪个危害更大?为什么准确估算很困难?我们又该如何实现准确估算?本文将探讨这些问题。

准确估算的价值

准确估算的价值,我认为主要体现在两个方面:成效信任image.png

首先说一下成效。需要厘清的是,成效(effective)不等于效率(efficiency)。成效是一个结果指标,体现结果的价值(一般指商业价值),常用投资回报率(ROI)来衡量。而效率是一个过程指标,体现过程中资源利用率的优化程度,常用生产率(productivity)来衡量。

注释:「结果指标」和「过程指标 」这两个装逼名词是我从知乎著名产品经理 —— 产品经理胡笛笛—— 那里偷师来的,我认为笛笛的表达切中肯綮。

理想情况下,成效和效率是相辅相成的关系 —— 高效率促进高成效,高成效追求高效率。然而现实中,常常会发生高效率低成效的情况。比如在项目开发过程中,一个程序员消失了一周,用一周时间高效地完成了一项原本需要两周时间的代码重构工作,但由于这项工作和正在进行的项目无关,反而耽误了项目进展,导致项目延期,造成了营收损失。显然,在这个例子中,这个任性的重构工作就是高效率低成效的。(程序员常常会误认为重构代码会在长期内降低开发成本,然而这些收益要等到项目结束后很长的一段时间才能兑现,却又实实在在影响了我们当前项目按时按质交付的目标。)

那么,准确估算对成效的帮助体现在哪呢?

本质上,项目时间估算是对项目成本(之一)—— 人力成本 —— 的估算。项目成本是公司决定资源投入的重要依据。公司倾向于投入高成效的项目。如果估算不准确,误导了公司的投入方向,会导致公司和个人的成效都会很低。因此,准确估算可以说是高成效的一个必要条件。

其次说一下准确估算影响的第二个方面 —— 信任。尽管在程序员看来,估算只是对项目时间的猜测,但实际上,当我们把估算的时间告诉领导和客户时,他们往往会把这个时间视为一个「届时完成」的承诺。虽然这种看法是不正确的,但游戏规则就是如此。

我们需要完成「承诺」以获得他人的信任。获得领导的信任能让你在职场如鱼得水,获得客户的信任则能增加客户复购产品的信心。信任成为人脉,而人脉具有复利效应,从长期利益角度看,毫无疑问对我们的发展帮助非常大。因此,我们得尽量把时间估得再准点,成为一个他人眼中值得信任的人。

低估和高估,哪个危害更大

帕金森定律:在工作能够完成的时限内,工作量会一直增加,直到所有可用时间都被填充为止。(人话翻译:工作预估的时间内,即便工作事实上完成了,也会没事找事,用其他的的事项填充掉剩余的时间。)

学生综合征:如果给开发人员过多的时间,他们就会一直拖延到项目快结束的时候才匆忙赶工, 结果反而很可能无法按时完成项目。—— Goldratt

准确的估算可以帮助我们取得高成效和他人的信任,而不准确的估算——低估或者高估——会给我们造成损失。那么低估和高估,哪个损失更大呢? image.png 《软件估算的艺术》中给出的分析如上图所示。书中认为,低估造成的损失更大。因为低估的损失呈指数型增长,而高估的损失仅仅是线性增长。

低估造成的问题可能有:

  1. 降低项目计划的有效性。例如组建的团队规模小于实际的需要,也会破坏小组间协调能力 —— 一个小组工作未完成,其他小组工作无法集成。
  2. 未做好前期基础工作导致结果更差。低估会导致在开发的上游活动(需求和设计)上花费的时间太少,后期需要重新设计和返工。相较于在前期解决这些问题,后期解决的代价可能是 10x,甚至 100x。
  3. 后期破坏性的变因(dynamic)导致项目结果更差。因为项目一旦进入延误状态,就需要大量的额外活动,例如开会讨论挽救措施,重新估算项目,修复先前为缓解进度压力而投机取巧导致的一些问题等。 显然,这些问题造成的损失会显著提高项目的实际成本,大大延缓项目时间。

而高估带来的损失主要是人力成本的损失,原因是「帕金森定律」和「学生综合征」。这是有上界的线性损失 —— 工作会花掉所有预估的时间,但不会进一步占用更多的时间。

准确估算的困难和办法

侯世达定律:做事所花费的时间总是比你预期的要长,即使你的预期中考虑了侯世达定律。  —— 侯世达, 《哥德尔、埃舍尔、巴赫》

大数定律:样本数量越多,则其算术平均值就有越高的概率接近期望

在许多人看来,估算只是一个单点的数值,但更科学的理解应该是将其视为一个区间,也就是 [最乐观估计,最悲观估计]。最乐观估计假设天上掉馅饼,一切都顺利。最悲观估计假设天上下刀子,凡事都倒霉(想象一下你写的每行代码都有 bug)。 image.png

直觉上,人们往往认为进度(完成时间)在这个区间内的概率大约呈正态分布。如上图所示,中点附近是概率最高的最可能的估计,两头是概率很低的最乐观估计和最悲观估计。

image.png
然而《软件估算的艺术》中给出了一个更合理的曲线。如上图所示,这是一个偏态分布(skewed distribution)。理由是最乐观的情况是有限制的,而最悲观的情况是无限制的(例如项目过程中地球爆炸了,永远完不成了)。

如果可以的话,程序员最好以区间的形式告诉别人估算时间,包括最可能的时间,以及大约一个 σ 标准差(50% 把握)的较乐观和较悲观时间。然而,真实的困难在于程序员常常被要求提供一个保证完成的单点估算值。但从概率分布曲线上可以看到,任何一个单点的估算值都不能 100% 保证完成。这是客观存在的困难。

除此之外,估算值还会受到主观人为因素的一些干扰。程序员在估算时可能会采取一些错误的估算方法:

  1. 即兴估算。会议上,领导拍脑袋安排任务,程序员也拍脑袋给出估算时间,拍胸脯说保证搞定。会后仔细分析,拍大腿暗道坏了,根本搞不定,最后只能拍屁股走人了 :)
  2. 锚定估算。一个可能需要几个月时间的项目,领导故意问你两周能不能搞定。受锚定效应影响,程序员只敢给出三周 —— 比两周多一周的时间。
  3. 乐观估算。程序员给出了最乐观估计,然而概率分布曲线告诉我们,这几乎是不可能的。
  4. 逞强估算。为了表现自己,故意压低估算时间。很多刚毕业的年轻人喜欢这么干,我曾经也是如此,因此付出了很多惨痛的的代价。
  5. 压力估算。领导说客户必须在某个时间点要。程序员无奈,只好修改估算值。 上述 1 ~ 4 属于估算方法不正确,5 属于没有坚持估算值。

解决这些问题的办法是针对性的。我们只需做到两点:一是使用正确的估算方法,二是坚持第一点,一百年不动摇。

首先说一下正确的估算方法。我认为,正确的估算方法包含两步,第一步是估算基本工作量,第二步是乘以一个风险系数,最终算出一个相对准确的估算值(其实大多数人应该也是这么认为的),再将这个估算值告诉领导和客户。

估算基本工作量,一种常用的方法是拆解估算法:大任务拆解成小任务,先估算小任务的工作量,然后累加得出大任务的工作量。这相对于直接估算大任务总体的工作量会更准确一点,直接估算大任务偏差会很大,而估算小任务虽然也会有高有低,但当估算的小任务数量足够大时,估算会更加贴近期望值,这体现了大数定律。

在任务拆解上,我的经验是拆解的粒度一定要细,尽量细化到每个人日。这不仅会增加小任务的数量使得大数定律更有效,同时也有助于自己清晰项目的细节以避免意外的风险。

另一种估算方法来自《人月神话》。作者提供了一个估算基本工作量的经验法则:

  • 1/3 计划
  • 1/6 编码
  • 1/4 构件测试和早期系统测试
  • 1/4 系统测试,所有的构件已完成 在我看来,考虑到实际情况,往往估算时计划已经完成,那么编码时间可以视做基本工作量的 1/4(而不是 1/6,剩余两部分同理)。也就是说,我们先估算下编码时间,然后乘以 4 得到总的工作量。

以上是第一步 —— 估计基本工作量,接下来第二步是给出一个合理的风险系数。

一种方式是按实际的工程日来给,比如假设一个工程日等于两个自然日。公式为:

公式 0:估算时间 = 工作量 * 2

这个假设基于一周内去除开会,code review,团建,休假等等因素,平均只有 2.5 天的实际工作时间。当然,系数 2 是因人而异的,视情况调整。

另一种方式是 PERT 估算法。公式为:

公式 1: 估算时间 = [最乐观估计 + ( 4 * 最可能估计) + 最悲观估计 ] / 6

第一步估出来的工作量可以视为最可能估计(当然你可以把它当做最乐观估计),然后再给出 1 个 σ 标准差的最乐观估计和最悲观估计,最后用公式计算得到估算时间。

考虑到最可能估计往往也是偏乐观的,那么就可以给最悲观估计增加点权重。优化版本的 PERT 估算法如下:

公式 2: 估算时间 = [最乐观估计 + ( 3 * 最可能估计) + (2 * 最悲观估计) ] / 6

掌握正确的估算方法后,我们还需要做好第二点,坚持它一百年不动摇。

换句话说,原则上,估算结果不容谈判。话虽如此,很多时候领导和客户很可能不认可我们的估算结果,并会对我们施压。这时我们一定要坚持原则,不能妥协,也不能争吵。我们需要带上同理心和逻辑与领导沟通(同理心和逻辑是我认为的沟通能力最重要的两个工具)。

从同理心的角度,可以先思考领导和客户的需求是什么。通常来说,领导和客户需求是希望客户在某个时间点能够用上一些产品功能。从逻辑的角度,我们和领导以及客户的目标是一致的,绝对存在共赢的可能性。我们需要找到一些变通的方法实现目标。寻求变通方法可以利用另一个工具 —— 产品-进度-成本三角。 image.png

产品-进度-成本三角的含义是,如果想要提升进度,一种办法是牺牲产品(的功能或质量)—— 缩小功能 scope 或者允许一些非关键 bug,另一种办法是增加成本 —— 例如在项目早期增加人手。这两个办法都是空间换时间思想的一种体现。

当把这两个办法摆给领导和客户的时候,我相信一定能取得一些理解,最终共同讨论出可行的办法。如果不被理解,那么要么你得再锻炼下沟通能力(提升我提到的同理心和逻辑),要么考虑下请领导吃炒鱿鱼,把天赋带到下一家值得的公司 :)

无论什么情况,请始终记住,使用正确的估算方法并坚持它。一旦妥协,必定会在成效和信任上受到损失。毫无疑问,这是更为惨痛的代价。

总结

本文探讨了准确估算的价值,分析了低估和高估的危害以及准确估算的困难,并提出了一些解决方法。尽管这些方法并不是银弹(也不存在银弹),但在估算准确性的提升方面绝对是有效的。希望对我的读者有所帮助。

参考

  1. 《软件估算的艺术》
  2. 《快速开发》
  3. 《人月神话》

留下评论