Return to Video

01-18 How Failures Come To Be

  • 0:00 - 0:05
    我们可以把程序看作一些连续的程序状态。
  • 0:05 - 0:09
    每个程序状态包括若干带值的变量。
  • 0:09 - 0:14
    程序运行时,它处理这些状态,并把它们转到新的状态。
  • 0:14 - 0:19
    比如,通过读写变量。这是操作的正常模式。
  • 0:19 - 0:24
    然而,因为一开始我们有标准的输入,最后却得到一个失败。
  • 0:24 - 0:29
    就一定是我们程序某处的一个defect,引发的这个问题。
  • 0:29 - 0:33
    所以先假设我们这里执行的这个声明有一个defect缺陷。
  • 0:33 - 0:38
    现在就是,执行时,它就引入
  • 0:38 - 0:42
    一个错误到程序状态中,我们把这个称为infection感染。
  • 0:42 - 0:47
    这个感染点现在可能会传染到别的状态,
  • 0:47 - 0:52
    最后形成一个可视的失败,反馈给用户。
  • 0:52 - 0:56
    我们这里就得到一个完整的诱因-影响 的关系链。
  • 0:56 - 1:01
    你看,这些失败和感染,是由之前的感染状态引起的,
  • 1:01 - 1:11
    如果一个状态的感染没有更早的源头,即输入状态相同,
  • 1:11 - 1:16
    输出却被感染,则在此状态前面执行的那个声明
  • 1:16 - 1:20
    导致了从正常状态到感染状态的转变,
  • 1:20 - 1:26
    就是这个声明语句引发了感染,它有缺陷。
  • 1:26 - 1:31
    当我们现在调试时,我们就要识别这条因果链,
  • 1:31 - 1:36
    不只是识别,还要斩断这条因果链。
  • 1:36 - 1:42
    如果我们可以破坏这条缺陷到失败之间的因果链,则算完成了调试。
  • 1:42 - 1:47
    所以这一切看起来很简单,然而,现实中,比这复杂得多。
  • 1:47 - 1:51
    一来,不是每个缺陷都会自动导致失败。
  • 1:51 - 1:56
    可能缺陷引起了感染,但感染后,
  • 1:56 - 1:59
    并没有像现实中的传染病那样传染。
  • 1:59 - 2:03
    所以,感染点没有传染,就不会被用户看到。
  • 2:03 - 2:08
    它甚至完全不会导致失败,或有缺陷的声明甚至没有执行
  • 2:08 - 2:14
    还可能只在特定的环境下会引发感染,进而失败。
  • 2:14 - 2:18
    这就是测试的问题了。你可以一遍遍地运行程序,
  • 2:18 - 2:24
    从不失败,却仍有缺陷。但是,如果程序失败了,
  • 2:24 - 2:33
    即我们看到一个失败了,却总能追溯到引发失败的缺陷。
  • 2:33 - 2:38
    所以如果程序失败,我们总能修复它,沿着因果链去追寻。
  • 2:38 - 2:43
    但下一问题就是,这些状态太多了。
  • 2:43 - 2:50
    这里我们有12个变量,已经是很少了。
  • 2:50 - 2:57
    现实中,我们有一万个变量,除了这一万个变量,
  • 2:57 - 3:02
    在缺陷和失败之间还经过了一万步的执行。
  • 3:02 - 3:06
    所以追踪这条因果链就变得
  • 3:06 - 3:10
    非常复杂,远非简单情况可比。
  • 3:10 - 3:14
    因果链越长,用于追踪的时间就越长,
  • 3:14 - 3:19
    追踪的状态就越多,调试就越难。
  • 3:19 - 3:23
    同样,状态越大,查找感染需要的一切就越多。
  • 3:23 - 3:27
    这也会让调试变得越来越难。
  • 3:27 - 3:31
    就好像在一个稻草堆里找根针,并且这个稻草堆
  • 3:31 - 3:35
    可能比你在地球上见过的所有稻草堆还要大。
Title:
01-18 How Failures Come To Be
Video Language:
English
Team:
Udacity
Project:
CS259 - Software Debugging
Duration:
03:36
秀隆 杨 added a translation

Chinese, Simplified subtitles

Revisions