一个普遍现象

软件项目的工期估计,系统性偏低。这不是某个团队的问题,而是行业普遍现象。

为什么这么难

一、软件是"设计"而非"制造"

制造业有成熟的工时标准——组装一个部件需要多久,可以精确测量,因为任务是重复的。

软件开发大多是"一次性的设计工作"——每个功能都不同,每次都在做新的东西。没有可参照的"标准工时"。

更贴切的类比:写软件更像写文章或做设计——你能估算"写一篇文章要多久",但很难精确预测"这篇特定文章什么时候写完"。

二、未知的未知(Unknown Unknowns)

最大的不确定性来自你不知道的东西:

  • 这个第三方库的文档是错的;
  • 旧系统的某个隐藏行为;
  • 需求中隐含的冲突;
  • 某个性能问题的根因比预想的复杂。

你在估计时,只能基于已知的东西。而困难往往藏在未知里。

三、乐观偏差(Optimism Bias)

人天然倾向于:

  • 想象事情会顺利进行;
  • 忽略可能出问题的环节;
  • 只考虑"如果一切顺利"的时间。

这是计划谬误(Planning Fallacy)——由 Kahneman 和 Tversky 提出的概念:人们系统性低估完成任务所需的时间,即使他们知道过去类似任务总是超时。

四、需求本身在变化

在估计时,需求往往还不清晰。随着开发推进,理解加深,需求会调整——这不是"估算错误",而是信息增加后的正常演化。

五、估算压力

"给我一个数字"的压力,会导致人们给出一个"对方想听的"数字,而非真实的估计。

当估算被当作承诺而非估计时,这个问题会加剧——因为承诺会让人倾向于报乐观数字。

六、忽略了非编码时间

估算往往只算了"写代码"的时间,而忽略了:

  • 需求讨论与澄清;
  • 代码评审;
  • 测试与修 bug;
  • 部署与上线;
  • 会议和沟通;
  • 上下文切换。

实际编码可能只占开发者工作时间的相当一部分——其余是协作、沟通、调试。

改善方法

一、分解任务

把大任务拆成更小的单元(理想是 1–2 天内可完成)。

为什么有效:小任务的估算误差小,且更容易发现"哪里想不清楚"。

一个经验:如果一个任务估算超过几天,通常说明它还需要进一步拆解,或者你还没真正理解它。

二、多人独立估计

计划扑克(Planning Poker):团队成员各自独立估计,然后讨论分歧。

价值:暴露不同的假设和理解差异。分歧本身就是有用的信息。

三、用相对估算

故事点(Story Points):不估计"多少天",而是估计"相对复杂度/工作量"——与之前做过的任务对比。

优势:

  • 人对相对大小的判断,比绝对时间的判断更准确;
  • 避开"小时"带来的虚假精确度。

四、基于历史数据

记录实际耗时,与之前的估计对比——用真实数据校准。

速度(Velocity):团队在一个迭代中能完成多少工作量。用它来预测未来,比拍脑袋准确。

五、给出区间而非单点

"3–5 天"比"4 天"更诚实,也更有用——它传达了不确定性。

或者给出一个"有 80% 把握"的时间(而不是"最理想情况"的时间)。

六、预留缓冲

为不确定性预留时间。不是在每个任务上加(那会被"消化"掉),而是在项目层面预留。

七、先做技术验证(Spike)

对于不确定的部分,先花少量时间做探索性验证——把"未知的未知"变成"已知"。

这往往比事后返工便宜得多。

一个心态

估算不是承诺,而是基于当前信息的预测。

好的估算实践应该:

  • 明确表达不确定性(区间、置信度);
  • 随信息增加持续修正;
  • 把"进度"与"估算"分开看待——进度落后时,重要的是找出原因并调整,而不是责怪估算不准。

说明:本文为软件项目管理的知识整理。