ΠΘVΘΠΙΠΞ

ΠΘVΘΠΙΠΞ

Building a new internet together.

软件漏洞来自哪里?

在我职业生涯的某个时刻,我有幸参与了一个软件系统的开发,该系统的输出决定了卡车的行驶路线。编程一直以来都是有趣和富有创意的,但这是我第一次感到它也可能是危险和可怕的。卡车路线系统中的一个错误意味着现实世界中的物体会出现异常。日程会被错过,资金会被浪费,客户会感到愤怒。此外,与其他软件系统不同,重启或重新部署并不能解决问题 —— 车辆已经在外行驶,由于承诺给客户的日程,重启路线并不是一个选项。

因此,我们非常重视安全和质量。我们有一套非常严格的测试,代码经过高级工程师的仔细审查,还有一支 QA 团队 —— 但这并不意味着我们没有产生错误。

错误!= 编程错误#

作为软件工程师,我们被训练成认为编程错误(例如,空指针、访问数组长度之外的项目等)是我们应该关注的主要错误,因为它们会导致程序崩溃。我们也会产生这类错误,但我很快意识到,尽管这些错误需要防止,但真正的大错误很少会导致崩溃,而是与我们的路由决策有关。空指针可以通过错误跟踪工具捕获,修复可以在几分钟内重新部署。路由错误只能在仔细分析路线性能后捕获,通常需要经过数周的研究来评估一条路线的盈利能力。

错误会发生#

当软件系统达到一定的复杂性阈值时,它们变得难以处理,容易意外引入错误。这种情况发生的部分原因是系统的行为变得无法指定。再也没有一个 “规范” 可以适合任何一个人对系统应如何行为的理解。相反,依赖该系统的多个方会对正确性有不同的定义。

你们中的一些人可能会争辩说,有技术可以防止系统的复杂性水平达到这样的程度,但有时我们会接手那些已经超出复杂性阈值的系统。本文讨论的正是这些类型的系统。

如何安全地开发一个你不理解其规范的系统?#

想象一下,你正在开发一个大型软件系统,没有一个人能够确定 “正确行为” 意味着什么,你如何安全地修改系统?事实证明,有一个简单但有效的技术可以实现这一点,我称之为_三种变更_。

三种变更#

你对代码库所做的每个更改都可以分为三组:删除、添加和行为变更。删除将从系统中移除行为(例如,删除代码)。添加将向系统添加新行为(例如,添加新功能),最后,变更将改变系统的行为。

行为删除的测试策略#

当你进行删除时,只有两种可能性。要么你正在删除在其他地方使用的行为,要么你正在删除在任何地方都未使用的行为。

第一种可能性会产生错误,第二种基本上是在删除死代码。因此,验证删除的正确性相当于确保你正在移除的代码没有被任何人或系统的其他部分使用。类型检查器在这里做了大部分繁重的工作,因此在实践中,纯粹的行为删除通常产生错误的概率较低。

行为添加的测试策略#

向系统添加行为,通常称为 “功能工作”,有一个很好的特性。通常,新行为是由一个或多个紧密合作的个人或团队引入的,在大多数情况下,有一个规范或某种方式来定义新行为的正确性。

这很好,因为这意味着验证添加的正确性相当于验证新行为是否符合规范。

新行为通常也可以以渐进的方式发布(例如,使用功能标志),以进一步减少错误的影响。

行为变更的测试策略#

改变系统的行为是三种变更中风险最大的一种。安全地改变系统的唯一方法是首先充分理解它在许多可能输入下的行为,它可以处于什么状态,以及它是如何失败的。

关键点#

  • 除非你真的理解系统的工作原理,否则不要改变系统的行为。
  • 设计你的系统,使新行为可以独立于现有行为轻松添加。
  • 设计你的系统,使代码在需要时可以轻松删除。@tef 有一篇关于这个主题的文章,标题为编写易于删除而非易于扩展的代码

如何安全地更改软件系统?#

  • 三种变更 你对软件系统所做的每个更改都可以归类为以下三类之一或多类:
  • 行为添加
  • 行为变更
  • 行为删除

bug-table.png

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。