程序员的时间估算:为什么你总是低估工作量
那是一个周五下午,产品经理走过来问我:「这个功能大概几天能做完?」
我扫了一眼需求文档,觉得不复杂,脑子里过了一遍主流程:「三天吧,周二给你。」
实际上线是三周后。
这种事发生在我身上至少有十几次。不是因为我懒,也不是因为我在敷衍。每次说三天,我都是认真盘算过的。但结果每次都差不多——实际时间是估算的两到三倍,偶尔更夸张。
时间久了我开始觉得这不完全是个人问题。查资料才知道,这个现象有个正式名字叫「规划谬误」(Planning Fallacy),是 1979 年 Kahneman 和 Tversky 提出的。大意是:人在估算自己未来的任务时,会系统性地忽略历史数据,只参考「最理想情况下的计划」。
理解了原理不等于能解决问题。但至少让我不再把估时偏差纯粹归罪于自己。
低估的第一个来源:只估了「主流程」
我那个三天的功能,主流程确实三天能写完。但主流程之外还有:
接口对接发现文档和实现不一致,来来回回沟通;写到一半发现数据结构需要调整,老代码改动牵连了另一个模块;测试时发现某个边界情况没覆盖,补了处理逻辑;Code Review 被提了几条意见,改完重新提交;UAT 阶段产品说「这里交互和我想的不一样」,改了两个下午。
这些东西每一个单独看都不大。加起来,超出预期一周都不稀奇。
我有个同事曾经说:「你估的时间是功能开发时间,不是功能交付时间。」这句话很扎心,但是对的。
低估的第二个来源:不知道自己不知道什么
软件工程里有个词叫 unknown unknowns,中文翻成「未知的未知」。意思是:那些你事先完全没有意识到会遇到的问题。
三天那个功能,有一个坑是这样的:第三方支付 SDK 的回调格式在国内和海外部署时不一致。这个坑不是文档里有但我没看,而是文档里根本没提——SDK 的维护者默认所有人都在国内跑。
我没法在估时的时候把这个坑算进去,因为我根本不知道它存在。
所以「未知未知」的处理方式只有一个:在估时里预留缓冲,不是假装能把所有风险都提前识别出来。
「乘以二」是个朴素但有效的方法
在我摸索了很久之后,现在遇到开发任务我的做法是:
先做直觉估算。就是那个「扫一眼觉得几天」的感觉,把它记下来,不要修改。
然后乘以系数。常规任务乘以 1.5,涉及第三方系统乘以 2,碰过或者完全陌生的新技术乘以 2.5。
最后加缓冲。如果估出来是三天,给自己保留半天的 buffer,对外报四天。
这个方法没有什么理论依据,就是我自己踩坑踩出来的经验系数。不同人、不同团队、不同领域的系数可能不一样。但核心思路是:别把直觉估算当成最终答案,直觉估算是起点。
当然这个方法有个副作用:对外报出来的时间比你直觉里的长,有时候会被追问「能不能快点」。
这个时候我的处理方式是不直接妥协,而是把任务拆开谈。「整个功能四天,但如果核心链路先上,两天可以给你一个可测试的版本。」这样产品和老板有了一个可以 check 的节点,我也不用在压力下把 buffer 全压缩掉。
用 AI 之后,我发现估时有个新变量加进来了。
AI 帮我写代码的速度确实快了,某些模块能省掉一半时间。但这带来了一个错觉:觉得整体工期可以压缩。
实际上并不是。省掉的大多是「写」的时间,也就是把已知的东西翻译成代码。但「思考」的时间——弄清楚需求、设计数据结构、排查诡异 Bug、跟人对齐——这些 AI 帮不了多少。而且 AI 生成的代码还需要 Review,偶尔会引入一些我没注意到的边界问题,Review 时间本身也不能省。
所以我对「AI 让开发提速了多少」这个问题的答案是:某些阶段快了,但整体工期的压缩比没有想象中大。大概节省了 20-30%,不是 50%,更不是 80%。
估时这件事,我觉得最重要的一个心态是:估时不是承诺,是沟通。
很多时候低估工作量是因为怕说出大的数字显得自己能力不行,或者怕产品不高兴。但这种心态导致的后果是:截止日期临近时压力猛增,要么连夜赶工,要么延期交付,要么质量缩水。
真正帮到项目的做法,是把估时里面的不确定性说清楚,而不是假装没有不确定性。「三天是最好情况,如果接口文档有偏差可能要四天半,我会提前跟你说进展」——这种沟通方式比直接报一个数更有建设性。
说出来麻烦一点,但比后来解释为什么延期要轻松得多。