跳到正文
IGCSE·Tuition
学习帮助

做出最小的可重现学习示例

你的程序运行时没有报错,也打印了答案,答案却是错的,而错误就藏在你自己写的四十行里。

本页内容
  1. 为什么 bug 会藏在长程序里?
  2. 怎样缩小程序
  3. 例题
  4. 要留意的错误
  5. 自我检测
  6. 接下来

要做出最小的可重现示例,复制程序,删掉所有不必要的部分,并保留错误的结果。写下你预期的结果和实际得到的结果。当问题能缩进五行之内,原因通常就看得见了。

这是最有用的调试(debugging)习惯之一,因为它用测试取代猜测。它也适用于 Computer Science 里的追踪和解释题,这类题要求你说出一段代码做了什么。

为什么 bug 会藏在长程序里?

程序越长,bug 越容易躲起来。你也容易最信任自己写得最仔细的那几行,而错误常常就在那里。

缩小就是把不相干的行清走,剩下的几行没有地方可以躲。

怎样缩小程序

  1. 各用一行写下预期结果和实际结果。
  2. 复制程序,以免弄坏原件。
  3. 把真实输入换成很小的自编输入,但仍然出错。
  4. 每次删除一部分,每删一次就重新运行。
  5. 如果错误的结果消失了,就撤销这次删除。你删掉的部分很重要。
  6. 当再删任何东西都会改变结果时就停下来,用一句话解释原因。

例题

原程序。老师规定及格分是 50,刚好 50 分算及格:

names = ["Aiman", "Bee Ling", "Chandran", "Dina"]
marks = [72, 50, 38, 65]
pass_mark = 50
passed = 0
total = 0
for i in range(len(marks)):
    total = total + marks[i]
    if marks[i] > pass_mark:
        passed = passed + 1
average = total / len(marks)
print("Average:", average)
print("Passed:", passed)

预期:3 人及格(72、50 和 65)。实际:2。平均分 225 ÷ 4 = 56.25 是对的,所以计算平均分的代码没有问题。

删掉 names 列表、total 和 average。及格人数仍然是错的。再把四个分数换成一个:50。

marks = [50]
passed = 0
for m in marks:
    if m > 50:
        passed = passed + 1
print(passed)

预期:1。实际:0。只剩五行,而且只有一行可以怪罪:m > 50 把刚好 50 分排除在外,但题目说 50 分算及格。

要留意的错误

有学生随意删行,直到错误答案不再出现,就断定最后删掉的那一行是 bug。但他同时也把分数列表里的 50 删掉了,问题正是因此才消失。

修正方法:每删一次就重新运行,检查是否仍得到同样的错误结果。如果结果变了,就撤销这次删除。可重现的示例必须和原程序以同样的方式出错。

自我检测

1. 为什么缩小之前要先写下预期结果?

显示答案

没有它,你就无法判断某次删除是否保住了 bug。你需要一个固定的目标,来和每一次重新运行的结果比较。

2. 删掉一个循环后,程序打印的是 1,而不是之前错误的 0。你该怎么做?

显示答案

撤销这次删除。错误的结果改变了,说明这个循环是问题的一部分。

3. 某程序统计 50 个分数的列表中有多少个至少是 60,结果不对。写出两个缩小的步骤。

显示答案

改用只有两三个分数的列表,其中包含一个刚好 60 的分数。然后删掉不影响统计的打印语句和额外计算。

接下来

这个习惯与修正差一错误(off-by-one)以及运行代码前先说明预期结果相连。接着,用改代码之前先设计边界测试把 bug 变成测试。你可以在安全的 Python 推理沙盒里练习自己的小题目。

如果你能缩小 bug,却仍难以解释,一对一 Computer Science 补习可以让老师陪你追踪那个小示例。Computer Science 学习指南显示了调试在课程大纲中的位置。

常见问题

什么是最小可重现示例?

它是仍然表现出同样错误行为的最小程序,只含触发问题所需的几行、简单的自编数据,并注明你预期什么、实际得到什么。做这个示例的过程,往往在你问别人之前就揭示了原因。

为什么不直接把整个程序再读一遍?

读四十行时,你的眼睛会跳过自认为正确的那一行。缩小迫使你逐一测试每个部分。某次删除让错误答案消失时,你就知道哪一行起了作用。

这一定要用 Python 吗?

这个方法在任何语言里都适用,在纸上用伪代码也行。请查看你所报考科目的 Cambridge 课程大纲,确认考试要求的语言和写法,并用你会被考核的形式练习缩小。

请别人给出改好的程序,等于学会了吗?

不等于。改好的程序不会告诉你当初为什么错。最小示例加上你自己对原因的解释,才能迁移到下一个 bug,也才能应对要求找出并改正错误的考试题。

资料来源

  1. Cambridge IGCSE Computer Science 0478 课程大纲页面

更新于:

下一步

如果你能把 bug 缩小,却仍然说不清为什么会这样,一对一的 Computer Science 老师可以陪你追踪这个小示例,帮你用自己的话解释原因。

一小时付费试听课,按所安排老师确认的收费,RM80 起。

补习由家长或监护人安排。用 WhatsApp 把这页发给他们,他们就可以替你咨询。

家长:在这里咨询

  • 已通过我们的服务帮助 9,000+ 名学生
  • 9+ 年帮助 IGCSE 学生