一个普遍现象
软件项目的工期估计,系统性偏低。这不是某个团队的问题,而是行业普遍现象。
为什么这么难
一、软件是"设计"而非"制造"
制造业有成熟的工时标准——组装一个部件需要多久,可以精确测量,因为任务是重复的。
软件开发大多是"一次性的设计工作"——每个功能都不同,每次都在做新的东西。没有可参照的"标准工时"。
更贴切的类比:写软件更像写文章或做设计——你能估算"写一篇文章要多久",但很难精确预测"这篇特定文章什么时候写完"。
二、未知的未知(Unknown Unknowns)
最大的不确定性来自你不知道的东西:
- 这个第三方库的文档是错的;
- 旧系统的某个隐藏行为;
- 需求中隐含的冲突;
- 某个性能问题的根因比预想的复杂。
你在估计时,只能基于已知的东西。而困难往往藏在未知里。
三、乐观偏差(Optimism Bias)
人天然倾向于:
- 想象事情会顺利进行;
- 忽略可能出问题的环节;
- 只考虑"如果一切顺利"的时间。
这是计划谬误(Planning Fallacy)——由 Kahneman 和 Tversky 提出的概念:人们系统性低估完成任务所需的时间,即使他们知道过去类似任务总是超时。
四、需求本身在变化
在估计时,需求往往还不清晰。随着开发推进,理解加深,需求会调整——这不是"估算错误",而是信息增加后的正常演化。
五、估算压力
"给我一个数字"的压力,会导致人们给出一个"对方想听的"数字,而非真实的估计。
当估算被当作承诺而非估计时,这个问题会加剧——因为承诺会让人倾向于报乐观数字。
六、忽略了非编码时间
估算往往只算了"写代码"的时间,而忽略了:
- 需求讨论与澄清;
- 代码评审;
- 测试与修 bug;
- 部署与上线;
- 会议和沟通;
- 上下文切换。
实际编码可能只占开发者工作时间的相当一部分——其余是协作、沟通、调试。
改善方法
一、分解任务
把大任务拆成更小的单元(理想是 1–2 天内可完成)。
为什么有效:小任务的估算误差小,且更容易发现"哪里想不清楚"。
一个经验:如果一个任务估算超过几天,通常说明它还需要进一步拆解,或者你还没真正理解它。
二、多人独立估计
计划扑克(Planning Poker):团队成员各自独立估计,然后讨论分歧。
价值:暴露不同的假设和理解差异。分歧本身就是有用的信息。
三、用相对估算
故事点(Story Points):不估计"多少天",而是估计"相对复杂度/工作量"——与之前做过的任务对比。
优势:
- 人对相对大小的判断,比绝对时间的判断更准确;
- 避开"小时"带来的虚假精确度。
四、基于历史数据
记录实际耗时,与之前的估计对比——用真实数据校准。
速度(Velocity):团队在一个迭代中能完成多少工作量。用它来预测未来,比拍脑袋准确。
五、给出区间而非单点
"3–5 天"比"4 天"更诚实,也更有用——它传达了不确定性。
或者给出一个"有 80% 把握"的时间(而不是"最理想情况"的时间)。
六、预留缓冲
为不确定性预留时间。不是在每个任务上加(那会被"消化"掉),而是在项目层面预留。
七、先做技术验证(Spike)
对于不确定的部分,先花少量时间做探索性验证——把"未知的未知"变成"已知"。
这往往比事后返工便宜得多。
一个心态
估算不是承诺,而是基于当前信息的预测。
好的估算实践应该:
- 明确表达不确定性(区间、置信度);
- 随信息增加持续修正;
- 把"进度"与"估算"分开看待——进度落后时,重要的是找出原因并调整,而不是责怪估算不准。
说明:本文为软件项目管理的知识整理。