在Andrew Hay的博客文章中,提出了以下公理:
在项目结束时修复错误的成本要比在项目早期修复相同的错误高得多。
但是,这似乎还不确定,尤其是在阅读了有关Less Wrong的博客文章之后,并且我所看到的支持它的数据非常古老。
今天这仍然公理准确吗?
在Andrew Hay的博客文章中,提出了以下公理:
在项目结束时修复错误的成本要比在项目早期修复相同的错误高得多。
但是,这似乎还不确定,尤其是在阅读了有关Less Wrong的博客文章之后,并且我所看到的支持它的数据非常古老。
今天这仍然公理准确吗?
Answers:
我见过的唯一硬数据是Boehm和Papaccio,《了解和控制软件成本》。
这可以追溯到1988年,是对大约80个软件项目的研究。他们得出的结论是,较早作出决定并较迟作出决定的费用可能是如果较早作出更正的费用的50-200倍。但是,他们所谈论的非常早期的决定是运行哪种操作系统以及使用哪种语言和数据库。
因此,相对于当今的软件开发而言,这些数字可能有些过头。但是,现在我们在该领域拥有丰富的经验,并且本能地知道它仍然适用。
在极端情况下,我们知道,如果在上线生产之前就发现了需求失败,这会导致大量的返工,并导致项目延迟或确实取消,如果在执行任何工作之前就发现了问题,我们很好。
编辑:布朗博士在他的评论中提出了一个很好的观点。
Boehm的研究是在COBOL和FORTRAN项目上进行的,当时编译和运行时间非常慢。我的职业生涯始于90年代初期的COBOL上,过去的编译和测试周期花了很长时间,因此值得在整个周期之前(或至少在构建阶段)对代码进行干测试。您可以抓到一些东西并尽早取消,这样可以节省一个小时左右)。
反过来,我们的老板过去常常嘲笑我们的抱怨,因为不久之前,他们不得不将一盒手工分类的打孔卡带到服务器机房,并在那里呆一天。
因此,那肯定比现在更真实。
然而,最近,我已经看到博客重用了史蒂夫·麦康奈尔(Steve McConnell)对这个问题的可视化效果(参考文献,日期为1996年),好像该图实际上是基于硬数字一样。不是。这是一种可视化,简单地解释了他的观点。
我认为,在OP所引用的文章中,Morendil的前提是一个很好的前提。我们在这个问题上拥有的科学是落后和过时的,但仍被视为经典。但是我也认为它很有效并且听起来很真实,因为我们从痛苦的经验中知道它至少在一定程度上还是正确的。而且我认为他戏剧性的“病态纪律”措辞对他没有任何帮助。
虽然我不知道有任何硬数据或其他证据可以支持这一说法,但至少我还是认为这是常识。
如果您有一个具有相互依赖的子系统的复杂系统(就像大多数非平凡应用程序所做的那样),请考虑可能由于对任何一个系统进行更改而导致的连锁问题。如果子系统被证明是正确的(通过单元测试等)并尽早修复,则仅通过早期修复就可以减少仅由于连锁反应而导致的错误数量。
另外,如果您要尽早修复错误,则开发人员仍然可以想到新的实现。根据任何给定项目的长度,如果最后要修复错误,则开发人员将需要花费时间弄清楚他们编写的内容以及(也许)他们的代码所依赖的子系统如何工作。重新学习的时间= $。
我怀疑是否有可能提出一种科学的,严格的方法来衡量这一点-涉及的因素太多,而且没有两个项目具有足够的可比性来进行案例研究。逻辑思维应该可以帮助您。一些争论:
这是系统工程学中公认的基本知识-适用于任何形式的技术开发(例如建造桥梁,导弹,战舰或软件)。
本质上,随着您进入开发阶段,事物的成本会增加大约一个数量级。
在构思这个想法时要花费10美元才能修复的东西...
如果您需要更新规格,将花费100美元左右。
或花费约1000美元(如果已实施某些措施),并且您需要在此时进行更改(并更新规格,获得批准等),但它尚未经过某种形式的正式接受/抛售测试
否则,如果已实施某些措施并获得客户接受,则费用约为10000美元,并且您需要在此时进行更改(并更新规格,获得批准,重新测试并重新运行客户接受度和资格,等等)
部署/推出/投入服务后的成本甚至更高。
示例比比皆是,而且易于理解:在您拥有25,000名员工之后,如果银行系统发生了严重的范围变更,那么这将花费大量的培训时间……甚至在您进行范围界定,编码,测试,回归,等等等等
显然,您的里程数会有所不同:更改Fred Nurke的电子袜子保暖电子商务网站的成本和影响与更改飞机飞行控制计算机上的软件的成本有所不同。
我无权访问硬数据或事实,因此我只能向您提供我过去20年从事IT工作的轶事。
我相信,与20年前相比,如今大多数开发人员创建软件的方式之间存在巨大差异。随着敏捷运动获得了巨大的动力,尤其是在过去的5-6年中,我已经看到了工作场所态度的真正转变。如此之多,以至于我们的工作质量似乎每年都在飞速增长,并且随着每个项目的应用,我们从各个项目中学到的经验教训都将得到应用。精益流程与注重测试优先开发的结合已从非常有争议的地方发展到了平凡的地方。如此之多,以至于今天进入许多公司,如果您对敏捷不满意,您会很幸运,如果他们不向您展示这扇门。
那么这产生了什么影响。首先,我注意到问题的确常常被更早地发现。通常情况下,如果问题看起来不太严重,有时可以无限期地搁置它。在极少数情况下,我看到那些被认为是琐碎的错误在以后解决时会成为严重的问题,因为一些当时根本没有考虑的基本问题变得显而易见。有时,这可能会导致确定的修复周期,并且在一定程度上可能会造成高昂的成本,但通常在资源方面衡量的成本较低,而在对客户与开发人员之间的关系的影响方面,成本往往更高。客户逐渐习惯了这种敏捷的思维方式,比以往更快地将结果返回给他们,高度迭代的开发冲刺以及请求和实现之间的快速周转,因此他们对我们抱有很大的期望。就实际的错误而言,修复错误的时间通常会大大减少,这是因为有了一套可靠的测试来支持更改,并且能够创建新的测试以提供见解和解决方案。报告的问题。
因此,总的来说,如果有一套可靠的测试套件以及确保测试仍然是开发人员工作重点的过程,但看起来在大多数情况下,修复漏洞的总精力似乎已减少,但是实际成本却很高。在某些方面至少部分地从实施转移到业务的其他领域,因为在某些方面,关注点也从纯供需转移到关系管理。
另一件事已经变得显而易见,那就是几年前我们的直觉表明,敏捷可以减少我们的维护周期,这一事实在某种程度上是对还是错。正确的意义是可靠的测试使得在很大程度上可以更轻松地调试和修复我们的代码,并从总体上减少了发布到生产代码中的错误的数量;而在正确的意义上来说,我们现在正在更加努力地避免需要通过不断地重构代码并改进体系结构来维护旧代码,以至于我们很少需要从头开始完全开发新产品,这一点变得越来越少。
那么,最后,对《任择议定书》的问题意味着什么?好吧,这意味着答案确实不像我们曾经认为的那样简单。15年前,我可能会回答“ 是”,但现在我觉得说实证性的衡量真的太困难了,因为从那时起我们开始问自己OP的问题以来,我们开发软件的工作性质已经发生了很大变化。在某些方面,我们越是提高自己作为一个行业的技术和技能,问题就越从确定的问题扩展到一个点,我怀疑在短短几年内我们会说这无关紧要当我们修复错误时,由于我们的测试和流程将更加健壮,因此,修复错误的时间将更少地受到节省预算的努力的驱动,而更多地取决于满足客户需求的优先级,并且相对成本将在上下文中变得几乎毫无意义。
但是正如我所说,这不是硬数据支持的证据,只是我对过去几年的观察,而且我的直觉告诉我,将会有更多突破性的智慧来改善我们做事的方式。
早期的错误会传播到系统的其他部分,因此,当您修复错误时,可能会被迫重写依赖于错误本身的系统某些部分。
除了时间,您还将了解程序的某些部分是如何构建的,并且需要提醒自己。这是某种形式的技术债务(如果您在较早的阶段就着急进行该项目,由于您所采取的捷径,您将难以完成该项目)。
就这么简单,没有任何证据可以证明。
我认为您正在尝试尽快完成该项目,以便为您的员工提供一些可行的解决方案。好消息是您将很快得到它,坏消息是,如果您只是保持尽可能快的速写并计划在几个月内修复所有问题,那么就可能在没有完全重写的情况下永远无法完成它。您甚至可能无法重构它。
好吧,我可能无法为您提供确定的证据,但我可以将我的工作中发生的最近一起事件联系起来。
我们添加了一项功能,该功能为我们的产品提供了工作流管理功能。典型的BDUF物料,规格经客户签署并批准。根据规格实施。从部署第一天开始的投诉。
我们并没有与客户进行真正的可用性演练,只是按照他们的意愿做了。结果:数百小时的返工-必须重做分析,设计,实施和质量检查。都是因为规范错过了特定的用例。规范中的错误(如果有)。
当链中某人做出的假设与最终用户的假设不同时,我在以前的工作中也看到过类似的事情。如果在发生时就将它们捕获起来,则直截了当的编码错误相对容易处理,但是设计错误会杀死整个系统。
问英特尔奔腾Bug花费了多少,阿丽亚娜5火箭就是另一个很好的例子。这些错误已在项目结束时修复。我在一个系统上工作,该系统的软件版本“尝试”预算为6位数字。在这些极端情况下,很容易看到成本。在其他(大多数?)情况下,成本被噪音掩盖了,但仍然存在。
毫无疑问,虫子存在时会花费金钱。缺陷报告中的一项,就像重复一样,花费时间进行编译,分类和关闭,时间就是金钱,因此,一个打开的bug会产生持续的成本。因此,延后错误修复的成本必须比尽快修复错误的成本高。
如果一个错误逃脱了,代价将是一步一步的跳跃……是在软件发布之前还是之后的“项目结束”?
我曾经读过一篇有两个有趣观点的文章(不幸的是,我所拥有的参考文献早已不复存在,因此我只需要在这里假设)。他们提出的第一点是,需求规范中引入了约50%的所有错误,而在UAT或系统测试中发现了约90%的所有错误。
他们的第二点是,对于V模型中的每个阶段,成本都会增加10倍。我认为该因素是否正确无关紧要,但最昂贵的错误是当您的设计基于错误的假设时。这导致大量的重写。由于该假设而起作用但在应用正确的假设时失败的所有代码都必须重写。
由于需求规范中的一个错误假设,我经历了必须重写整个域模型的经历。如果提早发现了这样的错误,即在检查需求规格时成本非常低。在这种特殊情况下,它将需要十行文本。如果是在UAT期间发现的,则成本很高(在给定的示例中,项目成本增加了50%)
没有统计数据,但有个人经验:
我正在研究的火箭发动机控制代码的行像 powerCutoff = someCondition && debugOptions.cutoffIsAllowed;
。默认选项是不允许截断。“最终”构建应该删除所有调试选项,因此该行已修改为powerCutoff = someCondition;
。
您在代码审查期间是否捕获到该错误?我们没有。首次发生触发条件而导致意外中断的测试是在第一次飞行前几个月。
如果在审核期间发现该错误,则花费不到一个小时。如果在集成过程中被捕获,则可能要花费一两天的时间,从而导致一次测试重复。如果在正式资格认证期间被发现,则可能会导致一两个星期的时间,因为要使用新版本重新启动完整的测试系列。
实际上,成本下降了。首先,我们设计并进行了测试,以确定飞行单元是否甚至可以触发条件。在确定确实可行之后,需要为最佳修复的工程,管理和客户分析,发布新版本,创建并执行新的回归测试计划,在多个单元和模拟器中进行系统测试而付出成本。总而言之,它花费了数千甚至数万个工时。再加上原来的15分钟,即可实际更改正确的代码。
可悲的是,就像很多事情一样,这取决于。
如果对话框消息拼写错误,则修复(更新字符串,重建/打包,重新部署)可能是“琐碎的”。或者,如果布局需要更新,则对.css文件的修改可能就足够了。
如果错误是具有100多个页面规格和证据的关键方法的输出错误,则调查本身可能需要数小时或数天。这就是旧的“公理”的含义,以及TDD和敏捷正在试图避免的其他事情(很早就失败了,显然是,取得了安全的渐进进步,yada)。
根据我最近在单个项目中的多团队团队的经验,“错误”通常是合并/集成问题,仅在发布结束时才出现,因为功能分支被提升为稳定版本。这是最糟糕的情况,因为在团队忙于完成自己的目标时,冲突通常需要跨团队的支持,但是我不知道它们比其他错误要昂贵得多,因为它们会在发生时发生:发布,但尽早可以。那就是使他们最糟糕的原因。