本文重点介绍开发人员在进行估算时头脑中发生的事情,为什么很难修复,以及我个人如何弄清楚如何生活和编写软件(对于非常快乐的企业主),即使我的估算同样残酷一如既往的不可靠。
但首先,一个故事。
那是
因此,在自然过程中,我必须运行自己的项目。客户经理大致解释了客户的需求,我们商量了一下,我说,“那应该是大约 3 周的工作。” “听起来不错,”他说。所以我开始编码。
您认为这个项目需要多长时间?四周?也许五个?
嗯,实际上:三个月。
我对那段时间记忆犹新——我的自我形象被包裹在成为“一名优秀的程序员”中,而在这里我只是可怕地失败了。我失眠了。我有这些小小的恐慌发作。它只是会。不是。结尾。我记得和那位客户经理谈话时,我心里很不舒服,一遍又一遍地解释说我仍然没有什么可以展示的。
在其中一个黑暗时期,我下定决心不再犯错。
不幸的是,在我的职业生涯中,我学到了一些非常艰难的东西:我总是错的。
实际上,我学到了更好的东西:我们都错了。
最近,我读了 Daniel Kahneman 的《思考,快与慢》,这是一篇关于心理学对人类认知的了解、其惊人的优势及其(令人惊讶地可预测的)失败的广泛调查。
我最喜欢的部分是过度自信。可以这么说,这与开发人员进行估算的方式有一些联系。
为什么你不擅长估算,第 I 部分:编写软件 = 学习你开始时不知道的东西
我认为我们之所以如此不擅长估算,确实有两个原因。第一种是不可简化的:编写软件涉及到计算出非常精确的细节,以至于你可以告诉计算机如何去做。问题在于,在您不完全理解的部分中常常隐藏着问题,这些问题会爆炸并完全搞砸您。
这确实是不可简化的。如果您确实“完全理解”某事,那么您有一个库或现有的软件可以做那件事,而您没有写任何东西。否则,就会有不确定性,而且它经常会爆炸……而这些爆炸可能需要一天到一年的时间,甚至超过宇宙的热寂才能解决。
这些错误可能以多种形式出现,也许关键的第 3 方服务被证明是不可靠的……所以您需要编写一个完整的重试/故障跟踪层……或者数据库可能无法理解某些关键字符集编码……所以您必须从头开始重建所有模式……或者,真正的经典:当您向客户展示软件时,他们并不完全想要他们要求的东西,他们想要的只是一点点不同。
当你第一次遇到这些痛苦时,你会想“我们应该在规范阶段更加小心”。但事实证明这很失败。为什么?核心原因是,正如您从上面的示例中看到的那样,如果您要编写一个能够捕获这些问题的详细说明,那么您将编写软件并且实际上没有办法解决这个问题(如果,当你读到这篇文章时,你正试图讨价还价,我必须告诉你 – 真的,真的,真的没有办法解决这个问题。完整的规格是一个糟糕的经济想法。下面我将列出更好的经济选择)
但这就是它变得有趣的地方:每个在现实世界中工作超过几个月的程序员都遇到过我上面描述的问题。
然而……我们继续做出这些极其糟糕的估计。
更糟糕的是,我们相信自己的估计。每当我制作它们时,我仍然相信自己。
所以,等等,我是不是在暗示所有开发人员都会以某种方式陷入同样的、可预测的思维错误?
是的,这正是我的建议。
为什么你不擅长估算,第二部分:过度自信
卡尼曼详细讨论了“专家”做出预测的问题。在令人震惊的各种各样的情况下,这些预测被证明是完全无用的。具体来说,在很多很多情况下,以下三点是成立的:
1-“专家”对某些未来事件的预测完全不可靠,基本上毫无意义
2- 有问题的专家对他们预测的准确性非常有信心
3-似乎没有什么能够削弱专家们的信心
最后一个真的很了不起:即使专家们试图诚实地面对他们过去失败的证据,即使他们深刻理解人类认知中的这一缺陷……他们仍然会对自己的预测的准确性深信不疑。
正如 Kahneman 解释的那样,在讲述了一个关于他自己在这方面失败的惊人故事之后:
“即使您相信每一个字,您对未来判断的信心也不会因您刚刚阅读的内容而减弱。”
有趣的是,有些情况下专家的预测非常好——下面我将解释如何利用这些情况来破解你自己的开发过程。但在我这样做之前,我想详细了解一下有缺陷的过度自信是如何在实地发生作用的,这样你也许可以从自己身上认识到这一点。
犯错是什么感觉:系统 I 和 II,以及 3 周和 3 个月的问题
在《思考快与慢》一书中,卡尼曼将大量心理学解释为支配我们思想的两个“系统”之间的相互作用:系统 I 和系统 II。我的过于简短的总结是“系统 I 进行快速、启发式、模式匹配思考,而系统 II 进行仔细、理性、分析性思考。”
而且,至关重要的是,就好像进化设计了整个事物,其关键目标是让系统 II 不必做太多事情。从进化的角度来看,这是很有意义的——系统 II 像糖蜜一样缓慢,而且成本高得令人难以置信,它应该只在非常非常罕见的情况下部署。但毫无疑问,您看到了问题:无需思考,您的大脑如何知道何时调用 System II?从这个角度来看,许多心理学的“认知偏见”作为解决现实世界残酷问题的优雅工程解决方案是有意义的:如何实时分配注意力。
为了了解系统 I 和 II 之间的相互作用如何导致真正可怕但诚实地相信的估计,我将把麦克风简要地交给我的朋友Edmund Jorgensen。他在一封电子邮件中向我描述如下:
当我问自己“这个项目需要多长时间”系统时,我不知道,但想有一个想法,并翻译了这个问题。进入什么?我怀疑它变成了诸如“我对自己能做这件事有多自信”之类的东西,然后将其转化为时间估计,并带有一些相当个人化的乘数(例如,当 Bob 的信心水平为 X 时,他总是说 3 周;当 Suzy 的信心水平为 X 时,她总是说 5 周)。
如果您逐渐意识到自己有两个“大”时间估计,请举手?对我来说,是“3 周”和“3 个月”。前者的意思是“这看起来很复杂,但我基本上认为我知道怎么做”,而后者的意思是“哇,这很难,我不确定涉及到什么,但我敢打赌我能弄明白。”
也就是说,我认为埃德蒙是完全正确的。
(对于那些在家玩的人:我的“3 周”项目似乎需要 5-15 周,我的“3 个月”项目通常需要 1-3 年,很少有人愿意继续付钱给我) .
好吧,所以让我们停止过于自信!
此时你可能会想:“好吧,我明白 Dan 的意思了:我们必须以某种方式来应对这些估算挑战,让系统 II 而不是系统 I。这样,我们细心的分析思维将产生更好的估算”
恭喜,您刚刚发明了瀑布。
这基本上是“开始编码前的完整规范”方法的承诺:不允许团队进行直觉估计,迫使每个人都仔细地进行分析,并提出详细的规范,并将估计分解成更小的部分。
但这完全失败了。像往常一样。
这里真正的麻烦是估计误差的两个来源之间的相互作用:人类对过度自信的偏见,以及任何实际软件项目中固有的不确定性。这种不确定性非常严重,以至于即使是谨慎、理性的系统 II 也无法做出准确的预测。
幸运的是,有一种方法既可以发挥您自己的认知优势,又可以应对现实世界的强烈变化。
首先,如何发挥你头脑的优势。
什么时候专家是对的,以及如何利用它来发挥你的优势
卡尼曼和其他研究人员已经能够识别出专家判断并不完全糟糕的情况。正如他所说:
“要知道你是否可以相信一个特定的直觉判断,你应该问两个问题:做出判断的环境是否足够规律,可以根据现有证据做出预测?对诊断专家来说答案是肯定的,对选股者来说不是。专业人士是否有足够的机会学习这些线索和规律?”
“足够的机会”意味着大量的预测练习,以及紧密的反馈循环以了解其准确性。
现在,6-18 个月的软件项目在所有这些标准上都惨遭失败。正如我在上面所讨论的,环境非常不“常规”。此外,专家无法同时进行大量预测和快速反馈。如果某件事需要一年或更长时间,反馈循环太长而无法训练你的直觉(而且你需要很多实例)。
然而,软件开发中有一种评估形式确实符合该要求——0-12 小时的任务,然后立即执行。在那个规模上,事情会有所不同:
尽管仍然存在很多变数(更多内容见下文),但“环境中的规律性”确实存在一些希望。两个四小时的任务往往比两个六个月的项目有更多的共同点。
你可以期望在几年内做出数百次这样的估计。
你会很快得到关于你的准确性的反馈
我曾经待过的速度最快的团队进行了一周的冲刺,并将所有内容分解为基本上是 0、2、4 或 8 小时(而且对于 8 小时的团队总是有一些怀疑——比如,我们d 非常努力地将它们分解成更小的块)。我们对这些进行了非常快速和随意的估计——我们甚至没有使用Planning Poker风格的形式主义。
在这一点上,你正在使用系统 I 的优势——它有机会接受训练,它看到大量的例子,并且有有意义的模式可以收集。而且,由于冲刺时间较短,您可以非常快速地获得有关估算质量的反馈。
等等,等等,让我们来估算一千个 4 小时!
我怎么能声称你们可以做出这些微观尺度的估计,但不知何故不能将它们汇总成 6-18 个月的估计?错误不会平均吗?
基本上,虽然我认为这种规模的估计通常是正确的,但当它们出错时,它们的错误程度是无限的。用数学术语来说,我怀疑实际时间遵循幂律分布。而且,幂律分布以没有稳定的均值和无限方差而著称。坦率地说,这正是那些大瀑布项目估算给我的感觉。
您可能会想:您预计需要 4 个小时的事情怎么可能需要一两个月呢?
这种情况一直在发生:你在某件事上采取了最后一步,发现了一些可怕的阻止者,它完全改变了范围。例如,在最近的一家初创公司中,为了尝试从我们的系统中消除单点故障,我们在我们编写的 IMAP 服务器之前放置了一个负载平衡器。我们的目标是,当一台服务器机器挂掉时,负载均衡器会顺利地故障转移到另一台机器上,而客户不会看到任何影响。
这似乎是一个 4 小时左右的任务。
但是当我们真正去做的时候,我们意识到/记住了 IMAP 服务器,与我们习惯于保持连接状态的所有 HTTP 服务器不同。因此,如果我们希望能够透明地故障转移到另一台服务器,我们必须以某种方式在两台服务器上维护该状态,或者在 IMAP 服务器前面编写某种状态感知代理负载平衡器。
这对我们来说就像一个为期 3 个月的项目。
短冲刺绝对是所有这一切的关键部分还有另一个原因:它们对可怕的错误估计的成本设置了硬性限制。
我们都被搞砸了吗?
那么我们该怎么办?只是接受我们所有的项目都注定要失败?因为我们总是无法兑现我们的承诺,所以我们会破坏公司其他部门的关系?
关键是你首先要接受准确的长期估计是根本不可能的。一旦你做到了这一点,你就可以应对一个虽然极其困难但可以应对的挑战:即使你无法做出有意义的长期估计,你的开发团队如何才能产生大量价值?
我们所得出的结论基本上是对为什么各种敏捷方法风靡全球的第一性原理的解释。