9月7日-8日,相约 2023 腾讯全球数字生态大会!聚焦产业未来发展新趋势! 了解详情
写点什么

软件工程预测一直都太不靠谱,如何做到不“打脸”

  • 2019-12-27
  • 本文字数:10087 字

    阅读完需:约 33 分钟

软件工程预测一直都太不靠谱,如何做到不“打脸”

本文要点

  • 在面对不确定性时,说到预测和规划,软件行业一直以来的记录都不太靠谱。

  • 阻碍我们学习的偏误有很多,包括认知偏差和薪酬结构。

  • 使用统计协助预测有可能成功,只要我们努力创建基于学习的模型,比如蒙特卡罗模拟。

  • 使用作为敏捷方法本质的迭代学习模型,是处理高度不确定性环境的最佳手段。

  • 面对极端不确定、难以找到决定因素的环境,最佳手段是使用假设检验(假设驱动开发)这样的增量式学习方法,并且努力接受不确定性带来的不适感。

规划好的最佳方案……

预测很难,尤其是预测未来的时候。


人们常常认为这句话来自物理学家尼尔斯·玻尔。还有人将其归到下列名人之一:马克·吐温、棒球明星尤吉·贝拉(Yogi Berra)、著名电影制作人萨缪尔·高德温(Samuel Goldwyn)、政治家卡尔·克里斯丁·思丹克(Karl Kristian Steincke),或者就是那么一句丹麦老话。这是一句有益的警告:很多时候,事物不是看上去那么简单,当我们了解不断深入,它们会变得越来越复杂。如果我们甚至无法判断是谁提醒我们预测有多难,也许这表示预测本身更让人挠头。


软件行业几乎完全依赖预测。然而,我们却没有多少靠谱的成功。在不同评判标准下[1],大约 60% 到 70% 的软件项目交付时预算超标、时间延期、或是直接取消,而且常常是在花费了大量资金之后。


此种情形原因何在?应该怎么做才能增加预测成功概率?讨论它们之前,我们先看看预测软件开发的原因。


商业需要预算和规划。资本,作为商业的血脉,必须理性分配给提供最佳回报的工作。我们需要回答这样的问题:应该花费多少资金?哪些项目可以批准启动?我们需要分配多少时间?是下次冲刺迭代的两周时间,还是下个财年的 12 个月?


传统而言,要回答资源分配问题,首先需要根据长期项目成本和范围加以估算,围绕估算形成时间表和计划,然后决定哪个计划值得投入资本。出于多种原因,我们下面会讨论一些,一个计划常常在墨水未干之前就已经展开了。


有了诸如 Scrum 这样的敏捷方法,工作规划周期已经减少到两周这么短。既便如此,待办事项列表中哪些故事值得开发,仍然是个问题。但是,即便缩短发布周期,仍旧导致至少 60% 的失望率[1]。那么,到底出了什么问题?为什么我们不能取得进步?为什么我们似乎无法学会做得更好?

为什么我们没有吸取教训

让我们看看,是什么机制让我们继续采取常常失败的策略,从而陷于无法学习改进的死循环中。如果我们可以理解自己行为背后的驱动因素,也许要改变它们就更容易,从而不断学习。

我们不学习也能拿钱

企业中的常见情况是,工作保障和激励与下列因素有关:预测准确、制定规划达成预测、分配稀缺资本、然后按计划交付。而且,要是能低于预测成本、早于预定日期完成,常常能得到财务激励。只要金钱激励与预测和规划未来相关,预测和规划就是商业活动的必备行为,无论是否能产出预期成果。实际上,人们得到复杂的结果,常常是为了证明它的有效性,而不管这样的有效性是否合理。


然而,面对失败的预测,人们的解决方法经常是听上去诱人而又可行的“我们下次会做的更好”。很容易想到的是:要尝试多少次才能彻底掌控?到了某个时点,我们应该意识到:这种策略不成功,应该试试其他办法。之所以不能吸取教训,是因为薪酬常常与不理解背后原因相关联。美国作家 Upton Sinclair 抓住了这种想法的精髓,他写道(性别用词中立):


当一个人的工资取决于他不能理解某件事物的时候,那就很难让他理解该事物。


如果我们希望改善产出,那就需要改变我们的薪酬结构,奖励我们的学习过程,远离奖励我们不去理解事物的薪酬结构。


小故事:有一次,我在向一位公司高管讲述非确定性系统中的不确定截止日期是怎么回事,他看着我,满脸怒气,大拇指和食指分开一英寸,然后说:“你说你不知道何时能完成,直到你距离完成这么近的时候才知道?这是胡说!”这次对话中谁更失望,很难说。是高管吗?因为在他眼中,我看上去不能理解最基本的商业理念和活动。是我吗?因为高管似乎不能理解他的公司的基本数学逻辑。实际上 ,我们都是对的,至少从我们的出发点看来如此。真正的问题,在于我们的薪酬结构系统,迫使我们有彼此不兼容的想法。

简单的诱惑力

无论我们如何实践,软件工程都是一项复杂的商业行为。它一直如此。Fred Brooks 多年前就写过,结论是“没有银弹”[2]可以消除软件开发的内在复杂性和困难。可这么多年过去了,我们还在这里,仍然想要找到复杂性的解决方案,能让它变得更简单的方案。对于简单的渴求让我们制定过于简化的计划,其中低估了出现未知因素的可能性,而当它们突然现身,就会让我们的项目偏离正轨,导致花费大量资金,然后还计划延期。


说到预测,我们很容易相信:存在某种简单的、一劳永逸的解决方案,可以满足所有人的要求,需要做的,就是要严格按照它的实践要点。然而,历史告诉我们:简单方案的队伍来来去去,永无休止,定期出现,此起彼伏。这其中需要理解的是:软件行业的要求复杂,没有简单的“银弹”方案可以满足。作家门肯的奇妙智慧给我们这样的告诫,警告我们简单的诱惑力:


每一种人类的问题,总有一个众所周知的解决方法:优雅、可行,而且错误。

沉没成本谬误

只要我们投入了时间和金钱来建立预测,沉没成本谬误就开始抬头了。沉没成本谬误可以归结为:已经花出去的钱无法收回来,但我们常常看不到这一点,然后继续花更多钱,希望能从前面的开销中获得一些回报。我们倾向于这么做,因为我们的工作保障常常需要我们证明:我们做出了明智的财务决策,可以带来利润回报。更糟糕的是,钱花得越多,我们就越觉得有必要证明这些投入的价值,这就让我们走上越花越多的漩涡之路。所有这样意味着,我们常常花钱来为失败的预测辩护,而此时早已过了放弃的最佳时机,后面的开销本来可以用在更理性的想法上。


自然界中没有沉默成本谬误,可以找到一个有教益的例子。如果某个物种出现问题,如果它无法适应环境,就要承受迅疾、无情的打击——绝灭,被新的物种快速取代。这个例子值得铭记,特别是下一次我们相信自己的预测可以成功的时候,只要再多投点钱进去。

教条的陷阱

无论是有意还是偶然,任何成功的公司都能找到一系列成功的实践,让自己可以开拓市场环境中的某个利基市场。这些实践就会作为规范进入一系列规则系统和组织管理层级中,后者想要保持公司的成功,直到永远。成功时间越长,它的盈利实践就越容易变成教条。如果这些成功实践中存在预测,那么相信预测有效的信念就可能变成教条。


当然,教条的主要问题在于:就其定义而言,教条是无法改变的,从而让我们在变动的环境中视而不闻,而市场环境不存在无法改变的定义。那么,当市场环境变化时,教条不改,那就离消亡更近了一步。要想避免,我们就得拒绝制订教条。


但是在组织中,拒绝教条常常不受欢迎。质疑它的人常被打上“不合群”的标签,或被视为需要“跟上队伍”。典型反应是让他们靠边站,或是除掉这样的人。毕竟,教条在公司内存在,是因为它定下的策略曾指向成功,保护这个成功是组织的主要任务。然而,说到预测,理性的方法建议:指导决策过程的应该是深思熟虑,而不是教条。

残忍的随机性

预测常常有两个内在的错误信念。第一,未来与过去差不多;第二,所有过去的事件都在期望之中。实际上,当过去的事件发生时,塑造将来的那些常常是不可预期的。预测未来时,我们常常假定不存在未知因素,因此不存在未知的未来事件。其中的认知陷阱是:由于新付出的努力和过去类似,这就让我们相信,自己已经事先了解了可能出乎意料的事件。问题在于, 每次新付出的努力在显现时,都是根据自身内在的、而且常常是不为人知的、一系列独特因素。


如果我们知道自己不知道什么,只要增加一个合适的软性因子,就能对付它,然后继续前行,同时满足于自己的规划可以应对未知。不幸的是,我们常常不知道自己的无知,更不用说如何应对未知了。此外,外界鼓励我们找到这样的原因,是它“上次由于 X 因素导致的失败,但我们这次已经留心了”。虽然我们已经留心了上次预测中的 X 因素,但下一次绝不是 X 因素烦恼我们。将会是 Y 或者 Z,或者其它未知原因。虽然字母表是有限的,我们可以覆盖所有原因,但在现实世界中,未知因素可没有上限。


可要是我们运气好,而且因为自己的预测取得偶然的成功呢? 如果无法认识到它的偶然性,那么我们必将倾向于避免采取新策略,因为我们自然相信:成功是源于我们的技能,而不是偶然机会。接下来更有可能发生的是:偶然成功将会被抬高到完美执行了策略和计划的地位,而重复的失败将被合理化为策略和计划执行糟糕。可是,是随机性让我们从幸运的预测得到回报,而我们将会更加努力试图重现这样的预测。研究显示:小小的鸽子很快就能识别出模式——用嘴啄杠杆,就能得到食物[3]。如果没有食物出现,它们很快就会放弃。但要是奖励是随机的,如果没有可以辨识的模式,不知道何时啄杠杆可以得到食物,鸽子很快就会进入迷信的疯狂状态,使劲啄杠杆,想要判断模式。比起我们想要反复让自己的预测成真,这样的行为似乎并无天壤之别。

魅力型人格

再看看另一个人类偏误:我们喜欢自信、有魅力的人。自信、果断的人升职更快,他们会坐到影响整个公司前途的位子上。在那里,他们安排活动,表明自己可以预测未来,制订规划,再按其执行。面对未知因素时,他们手边总有答案和行动规划,即便这样的规划表明他们的能力和信心并不相符。然后,我们就在他们的领导下安排资源,对他们确信无疑,全速前进。相比而言,有的人没那么确信,被问到面对未知因素怎么办时,他们会耸耸肩,回答道:“不知道。咱们做个实验,看看能不能找出办法。”比起他们,我们更容易转向有魅力的人,而不是谨慎的人士。


过度自信偏误就是在这时候生效的。相对同伴而言,魅力型人格和自信的人们更容易认为,自己拥有超出常人的预测能力。理性来看,瞧瞧 70% 的预测失败率,我们还是最好躲开他们,因为我们只有 30% 的成功几率。相反,极其自信的人看法不同,他们无视众多项目的多年统计数据,坚信自己的努力总能在别人失败的地方成功。


小故事:多年前,在互联网第一次泡沫的尾声,我在一家创业公司担任软件开发工作。带领我们的是一个年轻的、能量满满的、充满魅力的 CEO,他浑身散发着自信和掌控力。当时,我们租的办公楼已经见证了一家又一家软件公司租户的倒下,像多米诺骨牌一般。后来,只剩我们少数几个人留下了,整栋楼几乎空无一人,停车场有种诡异的后末世之感。就是在这种情形下,我们的 CEO 召开了全员大会,向焦虑的员工们保证,我们的未来是光明的。我想起他口若悬河,激情四射,充满整个房间,让我们相信可以得偿所愿。


当然,最后我们跟其他无数 dot-com 公司一样,泡沫破灭,我们关门。实际上,就在 CEO 激昂的演讲后不久,我们的结局就降临了,当时我们无法拿到另一轮融资,从而加入了大楼租客离去的行列。


被魅力型领袖的自信和理念所蒙蔽,公司的很多人无法看到显而易见的事实:如果无法盈利,我们就不能生存。事后看来很清晰,但在当时,相信我们跟其他人不同,相信虽然那么多人刚刚失败了但我们终将成功,这好像很合理。这是很有教益的例子,让我面对魅力型人格的时候心存怀疑。

犯错,经常性地

“哎,我们将来不会再犯这样的错误了。我们甚至炒了某些人的鱿鱼,确保它不再出现。”也许如此。我们不会犯同样的错误,因为下一次我们就有所准备了。问题在于,第一个错误出现之前,没人知道它,同样的事情还会发生,不过这次是另一些错误了。使我们成为牺牲品的新的错误,将会不断出现,因为之前没有人知道它们。第二次世界大战即将开始之前,丘吉尔在对议会发言时完美描述了此种情形。当时议员们担心重复一战的错误,希望确保不要再犯。丘吉尔的回答是:


我保证当时的错误不会再重复了;我们也许会犯下新的错误。


我们常常出错,而且不知道自己犯错。出了错还不知道,感觉上就像自己完全正确[4]。实际上,对错常常无法区分,直到证明我们错了。这应该让人们警觉起来,明白错误的不可避免。


在管理层会议和董事会中,常常能听到这样的说法:“决不允许失败。”虽然这么说常常是为了让人们不要敷衍工作,但的确排斥了学习和探索的机会,因为失败是学习的必要过程。这句话同时让人觉得,承认过程意味着承认能力不足,也许会导致失去工作。一旦这样的思考方式固定下来,再加上财务激励的巩固,就会让人们认为:失败,意味着过去一直成功的做法现在临时面临某些问题,我们只要付出双倍努力,它将来就能成功,即便真正的教训是,我们应该换条路走。在这些情形下,承认错误并改变做法,就变得很难了,因为我们坚持过去的思考方式,不可逆转。历史中充满了这样的例子,公司失去学习能力,持续投入越来越多宝贵资本到错误的策略中,即便这些策略把它们拖下悬崖。停下来反思一下,就能让我们醒悟,知道我们并非对此种愚蠢免疫。

利用学习的策略

前面列举的这些原因,说明我们为什么无法学习,而且继续采取让我们失败的策略。但要是可以避免这些陷阱呢?是否有策略把学习作为重点呢?实际上,当然有。

决定性的方法

过去,软件项目使用瀑布开发模型。先收集需求,再根据需求做估算,再从估算创建时间表。这种方法以决定性的观点看待软件项目,认为只要收集足够的数据和分析,我们就能准确预测成本和交付日期。这些项目常常在早期就开始出问题了,需求不足和估算不准是主要原因。对于后者,估算常常出错,是因为它们不是根据严格的统计方法,而是从某些类似于拍脑袋的做法中收集得来。


不过,决定性的观点也有可能成功,只要使用校准过的统计模型,并且从公司的历史软件项目中收集数据。蒙特卡洛分析是常见的统计方法。[5] [6]该方法背后的数学原理非常复杂,不过可简单概括如下:我们收集一系列历史数据,其中常常包括诸如工作量和持续时间这样的参数。然后,我们模拟这个场景几千次,其中随机输入不同参数,以产生概率分布,表明给定数量的工作可以在给定的时间内完成。比如,我们会得到一个分布,表明某个定量工作有 25%的机率在一个月内完成,50%机率两个月内完成,90%的机率在五个月内完成。这里的重点是:我们使用的历史数据,是我们这个组织独有的,用它来校准我们的模型,产生结果机率范围,而不是单一的值。注意,这种方法是很严谨的,而不是像某个人随口一说:“我一个星期就能做完。”


使用此方法,我们就是在选择学习。我们随时间推移收集数据,然后迭代地使用这些数据,并从中了解我们组织的能力如何,以及完成工作需要的成本和时间。当然,模型的准确性,与用来校准它的数据相关。模糊的需求说明、糟糕的工作完成记录,以及其他类似问题会产生让人失望的结果。

伪决定性方法

上述这样的完全决定性的方法要想成功,前提条件是所有的需求都能提前说明,而且不会经常变更,不过这样的项目可不常见。如果我们开发的是更典型的项目,目标不是很明确,需求说明不确定,市场需求也未知,那该怎么办?这些条件下,决定性的预测不太可能产生让人满意的结果。


这就要说到敏捷方法了。


敏捷方法采取伪决定性的手段来交付软件。它脱胎于传统瀑布项目反复失败带来的沮丧之中,放弃采信长期预测和规划,而是聚焦于短期内交付可以用的软件,同时适应不断出现的变化。使用敏捷方法,我们接受这样的思想:需求无法过于提前确定,但必须随着时间不断演化。


Scrum [7] 是常见的敏捷方法。它的两周冲刺迭代缩短了发布的时间周期,从而将项目的错误和偏移降到最低。我们在每个冲刺前重新设定优先级,这么做有效地重置了项目的时钟,让我们可以灵活适应变化。


我们仍然可以使用蒙特卡洛方法,来预测蕴含需求的故事的大小[9],但我们放弃了决定主义的一个表现:用长期规划来决定项目日程。相反,我们用迭代方法发现需要交付的东西,从而再次将重点放在学习上。


但这样做是不是就解决了预测和规划的问题?还是只是将错误预测和规划的影响最小化了?看上去我们还会有同样的问题,只是规模变小了。

演化式的方法

我们从传统方法的长发布周期出发,前进到了敏捷方法的短周期,而且短得多。我们还放弃了长期、固定需求的理念,转而选择关注更小的故事。这些改变可以帮我们迭代式地探索需求,得到更好的结果。这就带来一个明显的问题:如果一小点探索是好事,那么更多的探索是不是要好得多?


这就要说到假设检验。


假设检验(又称为假设驱动测试)的灵感,来源于史上最伟大的实验室:自然演化。自然演化不会假装自己可以预测未来的样子。它只是以频繁实验来应对变化。产生好结果的实验,其奖赏是更长的寿命。糟糕的结果很快就会导致屈辱的灭绝。如果我们愿意放弃自己的预测式思维,就能从自然演化中学习到很多。


使用假设检验,我们就能采用更深思熟虑的做法,而不是单纯依赖演化的随机性。面对未知情况,我们就像科学家一样:形成某个假设,然后在真实世界中度量、失败。如果它是可以被证伪的,但还没有被证伪,至少目前如此,那么它就有价值。


实施假设检验有很多方法[8] [9] [10],不过这里有一个简单的例子。我们形成一个假设,比如“我们相信,客户在数据门户上需要方便左撇子可以用的小部件。如果一周内门户的流量可以增加 5%,我们就认为这个假设是正确的。”如果假设正确,那么我们就会在一周内看到至少 5% 的流量增加。如果没有,我们就错了,应该拒绝假设,同时有可能移除该功能。然后,我们调整该假设,或是考虑其他假设。讨论如何完成假设检验已经超出本文范围,不过文末的资源参考有一些文章链接,其中有手把手的例子和最佳实验。


使用假设检验,我们放弃了预测将来的想法,不去想未来如何展开。相反,我们从底层开始,一边往前走,一边测试每个小部分,将资本风险降到最低,同时可以尽早减少损失。实际上,我们让自己在智识上更谦卑,承认自己对未来的了解不足。我们可以接受:我们不知道自己不知道的事物,而且不太可能提前知道多少东西。我们只能借助实验去探索。


更重要的是,假设检验可以尽可能减少前面提到的偏误,不再让它们耽误我们的学习。有了假设检验,我们挣的钱就是靠学习得来的,而且可以使用客观数据来验证或是证伪我们的想法。我们将沉没成本降至最低,因此就不太可能抱着错误想法不放。我们借助随机性辅助学习,而不是欺骗自己寻找并不存在的奖励。有了客观数据作为度量工具,魅力型人格就没那么有影响了。最后,大家认可错误是一种正常状态,也是实验的一部分。实际上,我们使用的是基于证据的决策系统,而不再是依靠全知全能或者迷信。


我们可以进一步让自己免于偏误,这需要针对假设可以使用的资本,施加严格的、一致的限制,同时要求在短时间周期内验证它们。否则,我们就又回到了老路上:需要“再多那么一点点时间”,或是“再多那么一点点钱”。自然演化不允许这样的豁免。归根结底,我们需要判断:是想自己“正确”,还是要赚钱。有时候,我们想达成前者,而口头上说是要追求后者。


不可否认,这种方法不会激发能让鼓舞人的激情演讲,比如前文预测式方法的“全速前进”!相比而言,“咱们做个实验吧”,听上去不那么热血澎湃。但这么做有可能带来更多利润,也许这样自有其鼓舞作用。

常见的错误策略

亲爱的勃鲁托斯,那错处并不在我们的命运,

而在我们自己。

莎士比亚《裘力斯·凯撒》,第一幕,第二场(译注:朱生豪译本)


也许我们在自己的行业里选取了有偏差的例子,只听到噩梦般的预测和规划,而无视成功案例,从而使我们相信,噩梦场景比比皆是。可是,这么多年来,有这么多人讲出这么多故事,看来那是可以代表很多工作环境的。其中含有最差的选择,几乎必将带来失败的结果。


事情是这样发生的。我们有一个泛泛的、很是模糊的目标,诸如:“明年网站带来的收入增长 10%”。抑或是更明确的:“在我们的数据门户上加入一个左撇子用户的小部件,因为客户会为之买单。”不管是什么,它经常没有明确说明,在前提之下的假设只是假设而已,没有依据。当然,只要我们开始干活了,任何隐藏的细节都会跳出来。我们在过去开发过类似功能,但是,关键在于,我们过去没有做过完全类似的事情。但这作为预测的依据就已经“足够好”了。然后,我们就有了一个,或者两个,开发人员做出预测,跟随意的瞎猜差不多。然后,我们就开工了。在预测性的工作环境中,常常是这样的:


经理:开发那个小部件需要多久?


程序员:我不知道,大概一个月吧。


经理:什么?开玩笑!不可能需要那么久!


程序员:呃,好吧,也许我一周能完成。


经理:这还差不多。我会放到日程表里。下周做吧。


在敏捷环境中,差不多是这样的:


经理:那个小部件的故事,你估计要几个故事点?


程序员:不知道,也许是 13 吧。


经理:什么?开玩笑!不可能那么大!


程序员:呃,好吧,也许是 3 点。


经理:这还差不多。我会更新到待办任务列表里。下个冲刺迭代做吧。


这跟处于强大压力下的瞎猜差不多,而且会营造出最糟糕的情况:模糊的需求说明;没有认真收集的历史数据,无法勇气做出用心的统计分析;来自一两个程序员的武断猜测,然后将猜测变为承诺,要根据时间表交付。不但如此,一旦程序员无法交付,经理还有理由去“拿程序员是问”,而程序员没有意识到自己给出的是一个承诺,而不是猜测,同时,程序员还会担心受到惩罚,因为怕自己的猜测变为承诺后出现错误,这种担心也是可以理解的。那么,要是失败不可避免,这还有什么奇怪的吗?唯一能够按时交付的方法,就是砍功能、狂加班、舍质量。然而,吸取的教训很少是:“这样干不行,我们得试试别的办法。”相反,常常是:“我们得把预测做得更好。”


人们让我们付钱做什么,我们就会做什么。如果要求我们必须用预测制定计划,那我们就必须投入时间和金钱把它做好。如果我们使用敏捷方法,那么交付可用的软件必须优于做出预测。其他做法相当于希望天上掉馅饼。正如热力学第二定律所明言:“世上没有免费的午餐。”(译注:热力学第二定律是表述热力学过程的不可逆性——孤立系统自发地朝着热力学平衡方向──最大熵状态──演化,也表明第二类永动机永不可能实现。来自维基百科。)

了解汝之环境

了解自己的业务开展的环境,很有必要。如果我们开发的是合同驱动的大型项目,时间表已经展开,而且需求已经明确定义,那么定量的预测是生存的必要条件。然而,要是我们身处的环境更常见,需求模糊甚至不存在,市场需求不明确甚至是未知的,时间要求很短而且紧迫,市场份额的竞争很激烈,那么我们就应该考虑使用假设检验方法。


关键问题在于,我们常常误解自己所在环境的底层数学逻辑。我们常常相信,自己处于决定性的世界,付出更多努力就能得到满意的结果。实际上,我们常常是在非决定性的、高度实验性的世界中,它的基础不稳固,会随时间变化。统计学家称这样的问题有“非平稳基数”(non-stationary base),也就是其基本数学逻辑不稳定,而且没有可以落地假设的基础。在这些情况下,固定的、决定性的方法无法成功,除非有十足的运气。由于上面列出的各种偏误,我们几乎无法抗拒这样的想法:我们可以预测并规划,即便实际上做不到。


然而,如果我们不是处于稳定的情况中,那么付出更多努力预测,就会让我们更加相信它的准确性,而不是去改善准确性本身。这样一来,我们就更仰仗自己的智慧,而不是选择自己的疑问。我们更倾向于付出更多资本,以此证明我们的正确,而不是小心保护我们的资源,并且只在数据告诉我们方向正确的时候再去运用这些资源。


了解我们所处的环境,意味着薪酬激励要与在这个环境中成功产出结果的工作方法相一致。我们应该因为学习而受到激励,无论学习在环境中如何体现。

结语

预测的关键困难,在于我们人类不愿意接受不确定性。处于不确定状态中,并由此产生疑问,这让我们极为不适。因此,我们更倾向于拥抱那些信心满满的人,而不是耸耸肩、更愿意做实验验证假设的人。


身边的现实情况是:商业环境常常受制于不确定性、未知的未知因素,还有我们必须依靠最微弱的光芒才能看清方向的黑暗。我们的挑战在于,接受这个环境令人不安的本质,而不是抱着某些舒适的想法不放,这些想法让我们更安心,但却充满误导。


通往知识的路是由不确定性铺成的,必须拥抱它们,才能获得知识。只要我们可以接受它们的不适,就能打开学习之路。改换一句名言:恒久不适乃学习的代价。(译注:此处针对的名言为:


恒久警惕乃自由的代价。Eternal vigilance is the price of liberty. )


作者介绍:


J. Meadows 是一位技术人士,有数十年软件开发、管理和数值分析经验。作者会不时为 InfoQ 供稿。




参考资料


[1] Standish Group 2015 Chaos Report. 


[2] 《没有银弹:软件工程的本质性与附属性工作》 


[3] ‘SUPERSTITION’ IN THE PIGEON", B.F. Skinner, Journal of Experimental Psychology, 38, 168-172. 


[4] 《犯错的价值》by Kathryn Schulz 


[5] “A Gentle Introduction to Monte Carlo Simulation for Project Managers” by Kailash Awati. 


[6] “Web-Based Monte Carlo Simulation for Agile Estimation” by Thomas Betts 


[7] “The Scrum Primer” by Pete Deemer and Gabrielle Benefield. 


[8] 《如何实现假设驱动开发》 by Barry O’Reilly 


[9] “Why hypothesis-driven development is key to DevOps” by Brent Aaron Reed and Willy-Peter Schaub 


[10] “Hypothesis-driven development” by Adrian Cho


活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2019-12-27 09:002152

评论

发布
暂无评论
发现更多内容

Linux之netstat命令

入门小站

Linux

在线年龄计算器

入门小站

工具

一文带你了解 TreeMap ,LinkedHashMap 的主要特点

4ye

Java 后端 hashmap LinkedHashMap 8月日更

Rust从0到1-模式-相关语法

rust 语法 模式 Patterns Syntax

手撸二叉树之将有序数组转换为二叉搜索树

HelloWorld杰少

数据结构与算法 8月日更

失败的小项目-外卖cps

箭上有毒

8月日更

Android开发:获取安卓App版本号的方法步骤

三掌柜

8月日更

Prometheus监控的4个黄金指标

Rubble

Prometheus 8月日更

命令行操作Java程序的那些事~

Bob

Java 命令行 8月日更

oeasy教您玩转vim - 14 - # 行头行尾

o

在openEuler上做开发?这个大赛拿出30万寻找开源的yyds

华为云开发者联盟

开源 操作系统 服务器 openEuler 鲲鹏

从0开始的TypeScriptの五:webpack打包typescript

空城机

JavaScript typescript 大前端 8月日更

Hive企业级性能优化

五分钟学大数据

hive hive性能优化

全球增长最快的对象存储开源系统MinIO

liuzhen007

8月日更

Mybatis自定义拦截器与插件开发

码农参上

8月日更

Django 做个小后台,细节在完善一点点,滚雪球学 Python 第三阶段

梦想橡皮擦

8月日更

金融级IT架构:网商银行是如何进行数字化落地的

博文视点Broadview

MinIO Client 使用(一)

耳东@Erdong

Minio 8月日更 mc minio client

【设计模式】代理模式

Andy阿辉

C# 后端 设计模式 8月日更

Web 框架 Gin | Gin 介绍

xcbeyond

Go 语言 gin 8月日更

netty系列之:自动重连

程序那些事

Java Netty 程序那些事 响应式系统

【LeetCode】从上到下打印二叉树Java题解

Albert

算法 LeetCode 8月日更

七夕赶上服务器架构升级,女朋友的约会怎么办

华为云开发者联盟

华为云 FunctionGraph DevStar Serverless架构 服务器架构

JavaScript Array 方法详解

程序员海军

JavaScript 方法 大前端 array 引航计划

【Flutter 专题】70 图解自定义 ACEStepper 步进器

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 8月日更

Android开发:引入重复包报错Error:Execution failed for task ‘:app:transform...’解决方法

三掌柜

8月日更 8月

如果面试官问你 JVM,额外回答逃逸分析技术会让你加分!

陈皮的JavaLib

Java 面试 JVM 逃逸分析 8月日更

LeetCode题解:781. 森林中的兔子,贪心,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

Go语言那些事儿之管道的关闭

Regan Yue

Go 语言 8月日更 管道

small-spring 代码贡献者3个月,敢说精通Spring了,分享我的总结!

小傅哥

spring 小傅哥 cglib aware BeanPost

Vue进阶(二十七):Vuex 之 getters, mapGetters, ...mapGetters详解

No Silver Bullet

Vue vuex 8月日更

  • 扫码添加小助手
    领取最新资料包
软件工程预测一直都太不靠谱,如何做到不“打脸”_文化 & 方法_J Meadows_InfoQ精选文章