我是如何预估工作量的
原始链接: https://www.seangoedecke.com/how-i-estimate-work
在软件行业,一直存在一个心照不宣的谎言:
预估软件项目的耗时很难,但并非不可能。只要投入时间和精力,优秀的工程团队就能学会如何预估交付时间,从而帮助公司制定出色的商业计划。
这当然是假的。经验丰富的软件工程师都知道:准确预估软件项目是不可能的。由于这个谎言与大家都心知肚明的现实存在冲突,导致科技公司里出现了很多奇怪的现象。
比如,很多团队用T恤尺码(如S、M、L)来代替时间进行预估,因为直接给出时间显得太不靠谱了。但自然而然地,当这些尺码汇报给管理层时,又会被立刻转换成具体的小时和天数。
另外,有些真心想给出准确时间的工程师,会用一些荒谬的经验法则,比如“把最初的预估时间翻倍,再加20%”。这基本上等同于摆烂,潜台词是“所有任务都估算为一个月”。
那么,科技公司应该停止预估吗?我的一个核心原则是:当一家科技公司在做一件看似愚蠢的事情时,通常都有其合理的动机。换句话说,那些看似不合理的做法,往往在组织中扮演着更底层、难以被轻易察觉的角色。那么,预估的真正目的是什么?作为软件工程师,你该如何做好预估?
为什么预估是不可能的
在深入探讨之前,我需要稍微解释一下我的核心观点。关于这个问题,大家已经写了 很多 文章,所以我长话短说。
我承认,有时候你可以准确预估软件工作,前提是工作内容非常明确且范围极小。比如,我知道部署一个服务需要半小时,现在要我更新一个链接的文本,我就可以准确预估大约需要45分钟:5分钟提交代码,10分钟等CI(持续集成),30分钟部署1。
但对我们大多数人来说,大部分软件工作并非如此。我们面对的是那些尚未完全理解的系统,无法提前预知究竟需要做些什么。在大型系统中,大部分编程工作其实是研究:查找历史实现、梳理系统逻辑以评估修改带来的影响等等。即使是极小的改动,如果不去看代码,我们根本不知道会牵扯到什么。
支持预估的人认为,这些问题应该在计划阶段解决,把任务拆解得足够小,就能准确预估。我对此不以为然。这让我想起了软件架构师大包大揽的糟糕时代:架构师提前规划好一切,程序员像机器一样照做。现在没人这么干了,因为行不通。必须让接触代码的程序员参与架构决策。就算这种方法管用,也只是把无法预估的部分转移到了计划会议上而已(在会议上你没法写代码测试,自然也回答不了那些问题)。
简而言之:软件工程项目里的大头不是“已知工作”,而是“未知工作”,而未知工作往往占据了90%的时间。由于只有已知工作能被准确预估,因此提前准确预估整个软件项目是不可能的。
预估并不是由工程师做出的
预估并不能帮工程团队更高效地交付工作。我职业生涯中最高产的几年,所在的团队根本不做任何预估:我们要么在做那些“必须完成”的项目(所以不需要预估),要么在做能持续产出价值的项目(可以一直做下去)2。
说到底,预估甚至根本不是工程师做出的。如果工程团队给出一个VP(副总裁)非常想要的项目一个很长的预估时间,他们会被施压缩短时间(或者这个项目会被交给其他更听话的团队)。如果对一个不受欢迎的项目预估时间太短,团队通常会被鼓励把时间拉长,或者经理会直接加上30%的缓冲时间。
唯一的例外是那些在技术上完全不可能,或者极其困难的项目。如果经理一直无法迫使团队给出“正确”的预估,这就释放了一个信号:这个工作可能真的做不了。聪明的领导会尽量避开这类项目。
另一个例外是公司高层根本不关心的边缘部门。在这些清闲的地方,预估流程往往会被严格执行,因为没有领导想插手干预。这也是为什么同一家公司里,不同部门的工程文化可能有天壤之别。你可以想象一下,如果公司重组,这些边缘团队突然成了焦点,后果会怎样。
预估是组织中非工程师的政治工具。它们帮助经理、VP、总监和C级别高管决定哪些项目该投资,哪些项目该取消。
是预估决定了工作内容,而不是反过来
通常人们认为,预估的流程是:先有一个软件需求,然后你去计算需要多长时间。这完全搞反了。 实际情况往往是:团队先拿到一个预估时间,然后去想在这个时间里能交付什么样的软件。
假设你在做大语言模型(LLM)聊天机器人,总监想要一个“与PDF对话”的功能。如果你有6个月的时间,你可能会开发一个强大的文件上传系统,搭建一套对PDF进行分块和嵌入的语义搜索管道,甚至提取PDF页面中的图像以保留格式和图表。但如果你只有1天的时间,你自然会寻找更简单的方案:比如,在客户端把PDF转成纯文本然后直接塞进LLM上下文,或者提供一个纯文本的“PDF搜索”工具。
即使具体到代码层面也是如此。当距离截止日期还有几个月时,你会花大量时间思考如何优雅地重构代码库;当只剩几个小时时,你只会死磕那些能让代码跑起来的方法。解决软件问题永远有很多种途径,因此工程师在实现方式上有很大的自主权。
我是如何做预估的
既然如此,我到底是怎么做预估的呢?
在看代码之前,我会尽可能多地收集政治背景信息。 这个项目压力大吗?是随便问问,还是我们必须做出来?我的领导想要什么样的预估结果?“CTO极其希望一周内上线” 和 “我们想给你们团队找点活儿,这个看起来挺合适” 之间有着天壤之别。
理想情况下,我是带着预期时间去看代码的。我不会问自己“做这个需要多久”(因为有上百种设计方案),而是问自己“哪些方案可以在一周内搞定?”。
我花在担忧“未知”上的时间远多于“已知”。 正如我前面所说,软件项目主要被未知工作占据。这个功能需要触及代码库中越多的“黑暗森林”,我的预估就会越高——或者更具体地说,我需要把方案严格限制在已知的范围内。
最后,我反馈给经理的是风险评估,而不是具体的数字。 我从来不说“这是一个为期四周的项目”。我会这么说:“我不认为我们能在一周内搞定,因为必须保证X、Y、Z都顺利,但其中至少有一个会比我们预期的麻烦得多。” 理想情况下,我会给经理提供一系列方案,而不仅仅是一个:
- 我们直接搞定X、Y、Z,如果顺利就好,但如果翻车,我们可能得耗上一个月。
- 我们完全绕开Y和Z,这会引入其他风险,但可能让我们赶上进度。
- 我们从其他更熟悉X和Y的团队请外援,这样我们只要专注解决Z。
换句话说,我不去“拆解工作来决定它需要多长时间”。我的领导们心里早就知道他们想要多长时间。我的工作是找出与那个预估时间相匹配的软件方案。
有时候根本没有匹配的方案:无论你怎么砍需求,项目就是不可能完成。这种情况下,管理层就需要开会调整需求了。但如果我总是把“不可能”挂在嘴边,经理就会找别人做预估。只有我在平时通过务实的预估积累了足够的信任,在关键时刻说“不”才管用。
回应一些质疑
很多工程师反感这种做法。一个原因是他们不喜欢在不确定的情况下做预估,所以坚持要提前弄清所有未知问题。我在 不愿承诺的工程师 和 我是如何为非技术领导提供技术清晰度的 中写过很多,简而言之,我认为这是一种逃避。如果你拒绝预估,你就是强迫不懂技术的人替你预估。
有些工程师认为他们的职责就是不断与工程管理层对抗,觉得帮经理寻找技术妥协就是背叛了某种神圣的工程信仰。我在 软件工程师应该带点犬儒主义 里提到过,如果你想这样度过职业生涯没问题,但我个人觉得,找到与经理(我遇到的几乎都是好人)合作的方式会更有成就感。
还有些工程师可能会说,他们很少感受到来自领导层修改预估的压力,认为这种压力是工程组织不健康的标志。也许吧!我只能代表我工作过的组织发言。但我怀疑这些工程师只是在“聚光灯之外”工作,那里本来就没有什么压力,团队想怎么玩就怎么玩。这没啥不好的。但我认为,这并不足以让你去给那些身处高压下的工程师提供有效的建议。
总结
我认为大家普遍对软件工程的预估存在误解。
普遍的观点是:经理提出项目,团队评估耗时,经理再据此分配人员和计划。但现实恰恰相反:经理通常是带着预期时间来找团队的(尽管他们可能不承认),然后团队必须弄清楚在这个时间内能做成什么样的项目。
这是因为预估不是为了工程团队做的,而是经理们之间用来协商计划工作的工具。极少数情况下,当一个项目真的无法完成时,预估可以作为团队向上沟通的手段。但这需要信任基础。一个总是推三阻四的团队,在遇到真正不可能的任务时,是没人会相信他们的。
当我做预估时,我会先摸清经理想要的范围,然后再去看代码,想清楚在这段时间内能做什么。我绝不会干巴巴地回复一个“两周”。相反,我会给出几种可能性及其对应的风险,让经理去权衡。
准确预估软件工作是不可能的。 软件项目大部分时间都在解决未知问题,而未知问题定义上就是无法提前预估的。因此,要做好预估,你基本上需要忽略所有已知的工作,转而凭经验去猜测:这里面到底有多少个未知数?每个未知数有多可怕?
修改注:感谢读者 Karthik 发邮件向我询问关于预估的问题,这让我意识到我对此的看法比我以为的要多。
修改注:这篇文章在 Hacker News 上获得了很多评论。一些非工程师指出,拿高薪的专业人士理应为他们的工作提供预估,即使这个预估完全是虚构的。我同意,只要大家都清楚这是虚构的就行!
几位工程师 认为 预估已经是一个被解决的问题了。他们的例子并没有说服我。我同意你可以预估“用 Svelte 构建一个用户流程”,但要想预估“在现有一个庞大代码库的基础上,用 Svelte 构建一个用户流程”就难多了。我在文章中应该说得更清楚些:我认为这才是难点,原因就是大型代码库本来就很难搞,我在博客里已经 无数次 讨论过 这个问题。
修改注:在 Lobste.rs 上也有一些评论,其中有一条很好的 建议:团队的能力显然对预估有巨大影响。根据我的经验,这一点很少被理解:公司期望预估在工程师或团队之间是通用的,但事实上,有些工程师和团队的交付速度能快十倍(而另一些团队无论给多少时间都无法交付)。
另一位评论者 礼貌地建议 我读读 《软件预估:揭秘黑魔法》 这本书,我没听过,我会把它加入书单。
在 Reddit 的 r/programming 节点也有一些 评论:大部分是泛泛地讨论预估,但也有一些关于本文的 有趣轶事 和 中肯的批评。
如果你喜欢这篇文章,可以考虑 订阅 邮件以获取新文章更新,或者 [在 Hacker News 上分享](news.ycombinator.com/submitlink?… I estimate work as a staff software engineer)。这里有一篇相关文章的预览:
我是如何为非技术领导提供技术清晰度的
作为一名主任工程师(Staff Engineer),我的使命是为组织提供技术清晰度。
当然,我也做其他事。我推进项目、写代码、做代码审查等等。但我做的最重要的事情——也就是我的核心价值——是提供技术清晰度。
在组织中,技术清晰度意味着:非技术决策者对他们能够对软件系统做出哪些改变,拥有足够好且务实的理解。
继续阅读...