大型软件是否有可能达到绝对零错误状态?


71

我说的是20-30 +百万行代码,例如Autodesk Maya规模和复杂性的软件。

如果您只要需要就冻结开发,就可以实际修复所有错误,直到没有一个单独的错误为止(如果可以通过计算机验证此错误)?支持和反对无错误系统的存在是什么?

因为有人认为您所做的每个修复都会产生更多的错误,但是我认为那不是真的。

错误是指从用户界面中最简单的错字,到没有解决方法的更严重的预防性错误。例如,特定的脚本功能无法正确计算法线。同样,即使有解决方法,该问题仍必须解决。因此,您可以说可以手动执行此特定操作,而不使用提供的功能,但是该功能仍必须修复。


11
“是由一些顶级程序员告诉的”-对我来说,他们听起来不像顶级程序员。他们听起来像是顶级黑客。程序员的主要职责之一是了解他们的代码做什么以及它如何影响整个系统。这就是我们拥有TDD,设计模式等的原因。如果无法做到这一点,那么系统就是垃圾-开发过程是以一种混乱,随意,无纪律,不科学的方式完成的。
矢量

51
如果您还不知道存在错误,那么它仍然是错误吗?
Blrfl 2013年

5
@Blrf:更重要的是,如果最终用户不知道存在错误,是否存在?
mattnz

40
“构建软件设计有两种方法。一种方法是使其变得如此简单,以至于显然没有缺陷。而另一种方式是让它如此复杂,没有明显的缺陷。” - CAR Hoare的
安德鲁·刘易斯

5
是的,但是很多人不希望质疑他们的基本信念。
Joan Venge

Answers:


92

正如Mikey提到的那样,编写无错误的代码不是目标。如果这是您的目标,那么对于您来说,我有一些坏消息。

关键是您大大低估了软件的复杂性。

首先,您将无视程序运行的大局。它不能在完美的系统上孤立运行。即使是最基本的“ Hello World”程序也可以在操作系统上运行,因此,即使是最简单的程序也容易受到操作系统中可能存在的错误的影响。

库的存在使这一过程更加复杂。尽管操作系统趋于相当稳定,但就稳定性而言,库是一个杂乱无章的事情。有些很棒。其他...不是很多...如果您希望代码是100%无bug的,那么您还需要确保运行的每个库都是完全无bug的,而且很多时候这根本不可能您可能没有源代码。

然后有一些线程需要考虑。大多数大型程序都在各处使用线程。我们尽量小心,以不会发生竞争条件和死锁的方式编写线程,但是根本无法测试每种可能的代码组合。为了有效地进行测试,您需要检查通过CPU的命令的所有可能顺序。我没有对此进行数学计算,但是我怀疑列举所有可能的国际象棋游戏会更容易。

当我们看着机器本身时,事情从艰难变成不可能。CPU并不完美。RAM并不完美。硬盘并不完美。机器中的所有组件都不是完美的,而是“足够好”的。即使完美的程序也会由于机器的故障而最终失败。您无法阻止它。

底线:您可以编写“臭虫免费软件”吗?

没有

否则告诉您的任何人都是无知的。

只需尝试编写易于理解和维护的软件即可。完成此操作后,就可以称之为一天。


编辑:有人评论了一个我完全忽略的优点:编译器。

除非您使用汇编语言编写,否则编译器很有可能会弄乱您的代码(即使您证明自己的代码“完美”)。

GCC中的错误列表,较常见的编译器之一:http : //gcc.gnu.org/bugzilla/buglist.cgi? product=gcc&component=c%2B%2B&resolution= ---


8
答案仍然是“否”,因为总会有“虫子”在起作用的地方-就像客户或产品所有者不希望它起作用一样。我们中的一些人可能会称这些功能请求,或者是更改行为或添加功能的请求-但是对于每天都被某些“错误”困扰的人来说,使他们烦恼的事情是一个错误。(这是一个长镜头,说情人眼里有一些错误。)免费的错误代码是不可能的。针对足以满足其预期目的的代码。
quick_now 2013年

6
我将更进一步:代码可能具有潜在的缺陷,例如,您可能有未正确检查输入范围的代码。如果输入是出于某种幸运的原因而从未超出范围,则该错误永远不会显现出来。然后,在维护或功能更改的某一天,该代码段被其他地方调用,偶尔会以超出范围的值来执行它。该错误现在可以显示出来-但始终存在。您可能会为此感到疯狂-但是消除错误的各种可能性仍然是不可能的。
quick_now 2013年

11
@ JohnR.Strohm我不确定为什么您认为“消息流调制器”程序(该程序具有556行代码)对理论上的2000万行系统有任何疑问。也许除了要证明证明小程序的正确性有多么困难之外,要证明庞大程序的正确性在天文学上将更加困难。
埃里克·金

9
虽然最初的问题没有这样做,但我想指出,“理论上可能的”和“实践上可能的”之间存在巨大差异。从理论上讲,无错误的2000万行代码库在理论上是可行的,但在当今市场上,几乎可以肯定,这实际上是不可能的。谁知道未来会怎样。
埃里克·金

4
@ JohnR.Strohm您应该更仔细地阅读本文。他们自言自语:It is important to note, however, that even all of these steps provide no guarantee of absolute security. It is tempting to believe that a formally specified and proved program should be absolutely correct, but there are several reasons why a proved program may not behave exactly as expected.-意思是,它不能被证明没有错误,但是,很少有错误。有点像TDD。
2013年

27

数学上MIGHT可能写出如此复杂的“bugless”软件,这取决于你如何定义“错误”。证明它MIGHT也是数学可能,通过设计一个测试系统,将行使的每行代码百般-每一个可能的使用情况。但是我不确定-如果您要处理的系统执行复杂的计算,则可能会遇到“无穷大问题” ...

实际上,在您所讨论的大小和范围的系统中,这是不可能的。编写这样一个“无bug”系统可能要花费1000年,并且编写一个系统以证明它将花费成倍的时间:您必须提出每个可能的用例,并编写一个可以测试每个用例的系统。一个-而且我不认为有办法确定您在一个合理的时间范围内,实际上已经覆盖了您所讨论的大小和范围的系统中的每个用例。

IMO,您的问题有点误导:作为开发人员,我们的目标不是编写“无错”软件。我们的目标是编写可用,灵活,易维护的软件。

可用:系统满足其设计要求。可能存在错误-但它们会出现在“极端情况”中-异常或烦人,而不是损害系统基本原理的错误-健壮。

可维护性:可以轻松地隔离和修复错误,不要创建新的错误。

灵活:您的系统易于更改和扩展,而无需大量重新设计和停机时间:大多数更改只需添加一个新类或模块,使其适合您已经设计好的模式和框架。

良好的设计规范,良好的控制规范,良好的团队合作精神,认真负责的开发人员-这就是GOOD SOFTWARE的公式。(不完美 -但GOOD


3
“通过设计一个可以以各种可能的方式使用每一行代码-每个可能的用例的测试系统,在数学上证明它也可能。”:这种程序通常不存在(可以证明!)。因此,不存在用于证明正确性的通用算法。
Giorgio

3
更正:已实现无错误的软件,具有完整的正式数学证明。它是在1982年完成的。Google是“消息流调制器”。
John R. Strohm 2013年

6
@ JohnR.Strohm:不正确。这只是一句话-有好几篇论文,在很多地方解决了类似的问题:“经常出现的一个问题是“您是否验证了验证者?”也许令人惊讶的是,工程师常常问这个超数学问题,而不仅仅是尖锐的头脑。当然,如果机器回答了“你说谎吗?”的问题,答案就不会比人类回答问题时提供的信息多。
矢量

1
我的意思是,没有适用于任何输入程序和任何输入规范的通用算法。您只能处理特定情况(例如您的示例)。
Giorgio

1
@Giorgio-因此,IMO遵循良好的设计规范比以数学上的正确性来关注自己更为重要:设计代码以确保其可以很好地集成并符合现有的要求-并且足够健壮,可以轻松地处理缺陷。揭露(他们会的)。
矢量

27

根据这篇文章,航天飞机的机载软件非常接近-420,000行程序的最后三个版本每个都只有一个错误。该软件由一组260名男性和女性维护。这些人中有很多是验证者,其唯一目的是发现错误。

升级软件以使航天飞机可以使用全球定位卫星导航,只影响了程序的1.5%,即6366行代码。这项更改的规格需要2,500页。整个程序的规范填充了30卷,运行了40,000页,或每页规范平均十行代码。

预算不是问题-每年$ 3500亿,他们有能力做正确的事情。


25
每个检测到一个错误。谁知道有多少未发现的错误?:)
Andres F.

8
那个“一个错误”是一个特例。Shuttle最初是为两个机器人手臂设计的,并指定了软件。“错误”是那里仍然有代码来支持第二支手臂。
John R. Strohm

4
+1跑了1981年至2011

5
@MarkJ:我们可能不知道航天飞机是否真的没有错误。每个航天飞机的任务都受到数百人的不断监控,并且任何编码错误都将被手动纠正/改写。
Lie Ryan

2
@LieRyan很好地显示了健壮的系统的一大特性-如果它们不会发生灾难性的故障,并且始终允许手动调整,则可以使用冗余系统(例如控制中心的系统)来代替工作。当然,只有在拥有这样的冗余系统并且实际上可以确保正确性和一致性时,这才有意义。在典型的业务应用程序上,崩溃通常比在不一致的状态下操作更可取-这是烦恼和向错误的人汇款之间的区别。还是没有收到钱就收到了钱……
卢安

15

从本质上讲,不,但是您仍然应该尽力而为。我将说明原因(如果您没有足够的耐心,也可以跳过结论)

考虑一个与二进制搜索的实现一样琐碎的问题。一个非常流行的实现有一个错误该错误在大约二十年内未被发现。如果二十行代码要花二十年的时间才能使无缺陷程序得到广泛使用,甚至被证明是正确的,那么我们真的可以期望一个庞大的程序是无缺陷的吗?

无论如何,我们可以期望一个大型程序有多少个错误?我发现的一个数字是“每1000行10个缺陷”(代码完整第二版,第517页-仅使用示例,没有引用任何数据),这使我们的软件中存在大约20万至30万个错误。幸运的是,我们有提高程序质量的方法。众所周知,单元测试,代码审查和常规手动测试可以减少错误的数量。尽管如此,这个数字仍然很高。

如果我们能够解决所有错误中的95%,那将是不可思议的。但是,我们的软件中仍然有10000至15000个错误。

幸运的是,由于该软件被广泛使用(并因此受到广泛测试),因此将发现一些错误。因此,我们将逐渐减少错误。但是,更少的错误也意味着很难发现其余的错误-因此,不要指望在修复错误时会出现线性曲线。发现最后几个错误确实很棘手,并且可能会逃脱几年的检测(假设它们曾经被发现)。

您似乎还错误地认为,如果软件没有更改,就不会出现新的错误。如果该软件依赖于第三方库,则新版本可能会破坏某些功能-即使应用程序的代码仍然相同,也会引入新的错误。新的操作系统也会破坏以前运行良好的应用程序(有关流行示例,请参阅Windows Vista)。还考虑编译器错误等。

尚不清楚代码验证工具是否可以真正解决错误的软件问题。解决任何程序的停顿问题当然是不可能的,但是有可能证明程序的行为符合规定。证明程序可能有错误。规范本身可能存在错误。

显然,我们可以大大减少bug的数量,但是我们几乎不可能达到零。

因为有人认为您所做的每个修复都会产生更多的错误,但是我认为那不是真的。

(添加了重点)

你是对的。这个说法是错误的。这是一个例子:

int main() {
    int x[10];
    x[10] = 8; //Buffer overflow here
    return 0;
}

现在,让我们修复此错误:

int main() {
    int x[11];
    x[10] = 8; //No buffer overflow here
    return 0;
}

看到?我们修复了一个错误,没有引入任何新错误。

但是,每次修复错误时都冒着创建一个新错误的风险,这是正确的,尽管可以减轻这种风险(例如,通过单元测试)。

假设我修复的每100个错误中,我不小心引入了一个新错误。因此,如果我修复了10000个错误,就会引入100个新错误。如果我修复了这些新错误,那么我将介绍一个错误。但是那又怎样呢?该程序现在减少了9 999个错误,因此它可能比以前要好(假设新错误不比以前的错误严重10万倍)。

此外,修复错误可能会暴露新的错误。但是这些错误也可以修复。如果您做对了,最终该软件将比开始时处于更好的状态。

我在一些顶级程序员那里老了,由于我在OP中提到的概念,最好不要修复很多错误。

此行为是过失的。如果有错误,您可以修复它。做吧 当然,您应该尽力防止添加新错误,但是如果我每修复10个严重的错误就引入一个小错误,那不是停止修复错误的正当理由。实际上,这是继续修复错误的充分理由。

因此,您所修复的错误更少,将来会有更少的错误返回给您

您所修复的错误越少,将在您的软件中保留更多的错误,使您的用户烦恼。确实,他们不会“将来再来找您”。他们不会回来,因为他们从来没有离开过。“回来”的概念与回归相关。同样,可以降低回归的风险。

有些错误无法修复,因为它们的用途非常广泛,以至于人们开始依赖它们,而修复这些错误会破坏这些用户的程序。它发生了。但是,在这种情况下,它们真的可以被视为错误吗?

“修复错误,制造错误”的思路可能与那个可怕的怪物有关 -这种代码难以理解和难以维护,仅触摸它便会产生错误。如果您的代码库中有一个怪兽,那么您可能需要先对其取消妖怪化,然后再进行任何操作。

最后,如果您是一个糟糕的程序员,那么碰到的任何东西都会产生新的错误。这显然会使高级程序员感到紧张。但是,说“不要做任何事情。不要触摸任何东西。甚至不要呼吸。” 这可能不是创建健康工作环境的正确方法。教育更好。

结论:

  • 不断获得大量新功能但没有错误修复的软件不可避免地会变得很烂。
  • 具有中等数量的新功能但已修复其错误的软件更有可能被使用。
  • 那些尝试几乎没有错误的人(平均)要比那些不在乎那些错误的人少。
  • 期望程序最终没有错误是不合理的。
  • 高级程序员不一定能胜任。
  • 修复您的错误。
  • 采用可提高软件质量的方法。

+1:我本人正在寻找二进制搜索示例,遭到了殴打;)如果20行经过广泛讨论和传播的代码存在20年的错误,那么建立一个2000万行代码库需要多少时间?几十个忙碌的人会看吗?
scrwtp

谢谢。我想知道这个二进制搜索错误(我以前从未听说过)是否与人们粘贴大量代码而没有考虑太多有关?另外,如果我们有足够多的bug甚至可以枚举,那么也许我们使用的工具和实践不是最佳的?
Joan Venge

1
@JoanVenge我引用了该示例以说明如何发现棘手的错误。在这种情况下,复制粘贴实际上是正确的做法,因为事实证明复制粘贴是正确的,并且从头开始编写实现很可能会出现更多错误。作为整个行业,我们所使用的工具和实践当然不是最佳的。最佳做法很容易被忽略,坏习惯很容易保持。最终,错误将永远存在,因为人类并不完美。但是,我们可以通过竭尽所能并坚持接受高质量的教育来减少错误的数量。
luiscubal

7
我认为二进制搜索代码中的错误说明了这个问题的复杂性。搜索中的潜在错误是一个潜在的整数溢出。这样的“错误”无处不在,因为大多数人都依赖于一个隐含的(有时是不正确的)假设,即输入量不足以引起溢出。它真的是一个错误还是只是一个文档记录不充分的接口合同?您最后一次测量范围的时间是什么时候之后对整数求和或在结果之后检查是否为溢出?
查尔斯·格兰特

4
您的示例服务器突出显示了有关编程语言和工具质量的相当明显的观察结果。使用健壮语言的具有生产质量的编译器应该拒绝编译您的第一个示例,而是返回致命的编译错误。编译这样的可憎性甚至是可能的,它告诉您所有您需要了解的有关这些工具的质量以及使用它们提供无错误软件的可行性的信息。
John R. Strohm

12

编写没有错误的程序的原因大部分是经济的。

数学方法来证明程序的正确性。在高质量的计算机科学课程中,将提到它们。有专门为此目的而发明的编程语言。从理论上讲,没有错误的编程可能的。

是的,有些不完善的硬件有时可能会改变一些值,因为数百万年前从遥远的超新星发射的中微子恰好在正确的位置撞击了您的处理器。好的,每种理论都有其假设和抽象。但是,假设处理器工作正常,则可以使用一些数学工具来确保程序也能正常工作。

在该主题中,一些获得高度评价的答案具有误导性。例如,哥德尔的不完备性定理和停顿问题仅表示您无法拥有例如可以确定任何程序的正确性或不正确性的自动化工具。但是我们不想决定任何程序的正确性,我们只想证明一个特定程序的正确性。

(从逻辑上讲,仅仅因为您不能编写用于自动确定任何数学定理的真相的程序,这并不意味着您不能证明一个特定的数学定理。)

问题是:

尽管从理论上讲可以编写无错误的程序,但是这样做会非常昂贵。编写具有正确性证明的代码比仅在墙上扔东西看是否粘住要复杂得多。即使“看是否坚持”是通过单元测试完成的;而且许多程序员甚至都不会这样做。大多数程序员甚至都不知道该怎么做,这意味着作为一家公司,您将不得不雇用更昂贵的公司。

考虑到所有成本,普通客户更喜欢廉价软件,该软件可以在99%的时间内运行良好(安装附加更新后的时间为99.9%),而不是拥有一千倍的昂贵软件(在100%的运行时间内运行良好)时间。此外,客户希望现在就拥有此软件,而不是十年或二十年内。

因此,人们有意生产出可能会有漏洞的软件,并试图在漏洞不太频繁且不太严重且生产速度足够快且价格便宜的情况下达到最佳组合。在现实生活中提供最大利润的组合。(有时,这甚至意味着在竞争对手发布任何东西之前先发布一个充满错误的软件,并且仅在竞争对手准备发布其第一个体面的版本时才发布更体面的2.0版。)

如果您只要需要就冻结开发,就可以实际修复所有错误,直到没有一个单独的错误为止(如果可以通过计算机验证此错误)?

从数学上讲,您可以。从经济上来讲,为什么会有人这样做?这将意味着花费大约二十年时间和几百万美元。同时,客户需要新功能,而冻结的应用程序无法提供这些功能。因此,当您准备好的版本时,竞争对手已经占领了市场。

经济上的推理是可以的。我们生活在金钱和时间至关重要的世界中。但是,仅仅因为我们出于经济原因不做某事,我们就不应该胡说八道,即使在理论上也做不到。谁知道...也许几年后,我们将拥有一些新的编程语言和工具,可以使正确性的证明变得容易


谢谢,尽管我希望大多数软件在99%的时间内都能正常工作,但我使用的大多数大型软件(如OP中的软件)还是非常容易出错。但我认为垄断和收购竞争对手也将其纳入考虑范围。但我明白你的意思。
Joan Venge

1
“昂贵”是相对的。将发现和修复错误的成本与例如放射治疗机杀死数名患者并致残数名患者的成本进行比较。(Google“ Therac 25”。)
John R. Strohm

6

没有。

戴维·希尔伯特David Hilbert)于1900年提出了他的第二个数学问题,该问题本质上是要求世界证明该算术能够按预期工作。后来,他提出了“ Entscheidungsproblem ”,这在逻辑上提出了类似的要求。 Kurt_Gödel的第一个不完备性定理 ”于1931年证明,基本算术理论不可能既一致又完整。 艾伦·图灵(Alan Turing)将Entscheidungsproblem 问题表示为“ 暂停问题 ”,将问题直接引到了这个问题的核心,在那里他证明无法证明程序是否会运行到完成状态。鉴于无法辨认,也无法证明程序是否有错误。

所有这些都无法使我们中间的实践程序员摆脱没有漏洞的追求。这仅意味着我们一般无法成功。


9
不确定性仅适用于一般情况-有些程序无法证明其正确性或不正确性。但是对于给定的特定程序,通常可以证明正确性(或更常见的是:错误)。这是假设您有一个正式的语言规范,以及一个可证明正确的编译器-尽管CompCert非常接近,但后者对于任何高级编程语言都不存在。
丹尼尔(Daniel)

+1引用相关的理论背景。我还不知道英语中的“ Entscheidungsproblem”是否与德语中的相同!
Peopleware

5
同意丹尼尔。挑战在于一个实例。停顿问题涉及所有可能的情况。暂时int main() { return 0; } 停止并且没有错误。
MSalters

1
停止问题并不是说不可能证明程序是否可以运行完成;它说存在无法证明的程序。常规的日常课程不在此类中。“虽然图灵的证明表明,没有通用的方法或算法来确定算法是否停止,但是该问题的个别情况很容易受到攻击。如果使用特定的算法,则通常可以表明对于任何输入,该算法都必须停止,实际上,计算机科学家通常只是将其作为正确性证明的一部分。”
endolith 2015年

6

人文错误

即使您使用B-method之类的正式语言编写代码,也可以用来数学证明满足要求,

即使您使用正式的规范语言,

总会有人为的步骤,即从一个或多个大脑中提取用户的需求到计算机。

这个人为的步骤很容易出错,蠕虫就在苹果里面。


1
当程序执行要求的内容而不是要执行的内容时,它仍然是错误吗?
MSalters 2013年

我认为是..
Joan Venge

4
@MSalters-当然是。不是从合同的角度来看,而是最终客户没有解决他的问题。您是否会坐飞机,飞机的计算机会执行什么操作,而不是执行什么操作?
mouviciel 2013年

3

我遇到的“错误”的相当一部分可能更恰当地描述为系统设计和客户期望之间的不匹配。

现在,我们是否称这些错误为学术问题,但事实仍然是,大量的维护工作是不完善的沟通和不断变化的客户期望的直接结果。

即使系统在技术上符合规范是“正确的”(尽管对于现实世界的商业软件来说这不太可能),但是您仍然会遇到使软件功能与客户的永远匹配的问题。转移和定义不明确的期望。

简而言之:

没有。


+1开发人员和客户可能对定义“错误”的观点有很大不同。
2013年

但是,如果开发者还是用户呢?我找到那些人一般最好在软件可用性方面,因为他们知道的东西究竟应该如何工作等
琼Venge

2

如果您有足够严格且受限制的规范,则可以证明没有错误,但只能基于无法证明系统中所有其他功能正常运行的假设。这就意味着,没有办法证明提出原始问题的人或使用服务的人都认为规范是正确的。


1

我发现Jim Shore的“ No Bugs”一节中关于该主题的阅读非常有用。简短的形式:如果不产生错误就不可能进行开发-但是我们可以以尽早发现它们的方式进行工作。

在代码本身的生产过程中。例如,通过在开发过程中频繁编写和运行单元测试,我们可以不断确保代码能够实现其应有的功能。同样,以最清楚地表示预期的系统行为的方式永久重写现有代码也很有用。

但是,就您而言,您正在谈论的是已经存在的具有数百万行代码的代码库。如果要免费获得此类系统错误,则首先必须知道该系统的“错误”。您可以编写事后测试套件,以确保系统的功能(如果尚不存在)。这些测试的网络可以作为正确系统行为的近似定义。但是,您拥有的代码越多,此类练习所涉及的工作就越多。因此,大多数公司都做出了妥协:他们生活在不完善的环境中,使用错误列表和维护来从系统中获取最烦人的错误。


1

关于计算机验证部分。

有两种使用计算机验证程序的方法。一种是测试,另一种是使用证明系统。

一旦不可能进行详尽的测试,测试就无法表明程序没有错误,只是有错误。(并且您有一个问题,表明您的测试本身并未在测试是否存在错误)。

要使用证明系统,您要从正式的要求开始(它们本身可能有错误,希望用于要求的语言更适合于说服自己那里没有错误,而不仅仅是使用编程语言),并使用在证明系统的帮助下,该程序没有错误(证明系统中存在错误问题,但事实证明它们是正确的)。当前的最新状态是C子集编译器(并且该子集不是学术性的,“ CompCert支持C的所有MISRA-C 2004子集,以及MISRA排除的许多功能”)。


引用Donald Knuth(从内存中):您可以证明程序没有错误,但这并不意味着它没有错误:-)
gnasher729

1

不可以,因为即使冻结了代码,运行应用程序的计算机和软件环境也会继续发生变化。操作系统会随着修补程序和修补程序以及设备和驱动程序的发展而不断发展。就在您认为自己没有已知错误的时候,AMD或nVidia会发布视频驱动程序更新,从而影响您与视频子系统的交互方式。现在,对于具有特定视频卡或配置(SLI?LOL)的客户,您的应用程序具有视觉缺陷(例如闪烁,闪烁或降低帧速率)。

除了硬件和操作系统之外,在最重要的应用程序下面还存在许多中间件产品,这些中间件产品也将超出您的控制范围,并且就像您使代码达到零缺陷状态一样,在其下层实现了EOL。

随着技术的发展以及利用该技术的业务的发展,“释放”代码的想法是不可能或不可行的。要求新功能集的企业不会很好地响应“我们追逐所有已知的错误时就锁定了代码,并且在X个月内没有人报告有效的软件缺陷”。即使企业购买了该产品线,在X个月后,他们仍会询问新功能的发展情况,答案不可能是“我们决定延长冻结时间,因为Oracle仅发布了补丁程序,我们需要再花X个月的时间证明这一点”。

不,在某个时候,企业将寻找一个更灵活的开发团队,以支持以技术速度前进的需求。这是现代开发团队面临的根本问题。


0

是的,但是您永远不会确定。您越看越努力,就会发现更多。使用的系统越重,使用的边缘情况越多,您越有可能发现与原始意图或规范不匹配。这意味着错误本身并不是一件准确的事情,并且通常取决于解释,某些人评估感知到的异常情况的严重程度。

这是一件模糊的事情。很少有系统指定到最后一位。如果系统运行良好,并且用户没有任何抱怨(他们没有受到任何错误困扰)并且完全适应了该系统,那么您也可以将其称为无错误。


-2

只要有足够的纪律和共享的团队文化,就有可能始终如一地交付无错误的软件。(以及精心设计的模块化代码,一整套全面的自动化测试,检查缺陷和调整您的过程以及许多其他需要付出努力和谦虚但又要付出数千倍回报的事情)

但是,这样做通常不会开始构建20 MLOC系统。如果编写无错误代码不是您的目标,那么任何一个都不应构建许多MLOC系统。

我自己的推理如下:

有人需要实现。一个人(可能是同一个人,可能是一个不同的人)有预算来通过编写软件来满足需求。所有这些人都希望从他们的钱中得到一些好处。

有预算的人会付给某些人(可能是相同的,可能是不同的)所谓的程序员,以便这些程序员将他们同意的时间量转化为软件来满足需求。

因此,这些程序员致力于将别人的钱转化为满足需求的软件。善用这笔钱是他们的责任。

关于您的问题,这具有以下含义:

  • 鉴于该软件中存在错误,您是否会全部修复?您需要程序员来修复错误,程序员会花钱。程序员无法决定是否花钱去做。它是预算持有人的角色。
  • 我可以从头开始构建20MLOC软件,而不会最终留下未解决的错误吗?好吧,开始建造20MLOC需要打算花费大量金钱。这在财务上是愚蠢的。它不是一天建成的。但是软件是满足今天的需求,而不是明天。通过雇用大量程序员,在并行化开发方面将有一个错误的尝试。但是,那么,您很可能不会共享一种文化,随之而来的是错误,错误和浪费将会发生,并且金钱将无法修复它们。我还没有看到任何如此大小的无错误系统。(我见过没有错误的系统和20MLOC系统,但是它们并不相同)
  • 我负责维护我未编写的20MLOC系统。我将能够达到零个已知错误吗?这不依赖于程序员。他们不能决定修复错误,因为这不是他们的钱。有足够的投资回报率来修复其余的错误吗?嗯,该系统已经存在了一段时间,并且用户已经习惯了它,并在日常工作中利用该系统的怪癖来发挥自己的优势。如果您原则上修复错误,那么有钱的人可能必须付费才能重新开发一些未指定的功能,这些功能将从系统中消失,从而花费更多的钱。

都是关于钱的,对的。


-2

是。

但是,正如您所知,这需要太多的努力才能实现。

在捍卫答案之前,我们必须首先定义什么是错误:

  • 错误是与规范相反的行为。
  • 但是,规范中的故障(例如,机器人技术的第0定律)不算作软件错误。
  • 除非规范禁止,否则其他功能均不视为错误。
  • 出于争论的目的,规范中的矛盾也不视为软件错误。

现在,正如您希望已经知道的那样,好的软件体系结构是模块化的,因此每个模块都可以分别进行单元测试(或手动测试,或其他方式)。通过严格的测试和仔细的测试,可以编写没有错误的单个模块。

“可是等等!” 我听到您的抗议,“如果一个模块的意外(但仍然正确)的行为导致另一个模块的错误该怎么办?” 然后,该错误位于第二个模块中。可以将无错误的模块视为API,并且如您所知,API需要谨慎使用才能正确使用。

编写防弹代码要求开发人员对边缘情况和流程逻辑有广泛的了解,而大多数软件开发人员要么不够聪明,要么学习或根本不在乎。或更经常地,他们是在最后期限。

“但是给我一个站立的地方,我将移动世界。” -阿基米德


这需要付出努力,但会有所回报。
洛朗·拉里扎

1
如果将规范错误排除在外,那么整个软件将变得无用:规范只是以相对正式的方式记录用户需求的工具,但最终需要满足用户的是需求,而不是规范。创建规范和编写代码一样,也是软件开发的一部分。毕竟,就像最终代码一样,完整的正式规范将描述系统的行为,但规范不能有效执行。
cmaster
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.