调试
CIE A-Level 计算机科学· 单元 12:软件开发· 10 分钟阅读
1. 程序错误的类型★★☆☆☆⏱ 3 min
在开始调试之前,必须先对错误进行分类,这会指导你选择合适的调试方法。CIE 9618 经常考察考生区分三种核心程序错误类别的能力。
核心程序错误类别
软件开发过程中遇到的三大错误类别,每种都有不同的症状,需要不同的调试方法。
例:
语法错误、运行时错误、逻辑错误
语法错误:违反编程语言的语法规则,在执行开始前被编译器或解释器捕获,程序完全无法运行。
运行时错误:在程序执行过程中发生的错误,会导致程序意外崩溃或中止,无法完成执行。
逻辑错误:程序可以运行完成不崩溃,但会产生错误输出或出现意外行为。
对以下错误进行分类:一个 Python 程序将用户输入除以零,程序停止执行并输出ZeroDivisionError错误信息。
- 1
步骤 1:确认程序已经成功编译/解释,开始执行后才失败。
- 2
步骤 2:记录结果:程序意外停止执行,而非产生错误输出。
- 3
步骤 3:将症状与错误类型定义进行匹配。
- 4
结论:这是一个运行时错误。
Exam tip:
始终检查程序是否能运行:如果程序能运行但输出错误,那就是逻辑错误,不是运行时错误。
2. 常用调试方法★★★☆☆⏱ 4 min
调试经常被和测试混淆,但这两个过程的目标截然不同。测试确认漏洞存在;调试则定位并修复漏洞。有多种成熟方法可以高效定位漏洞。
调试
定位、识别并解决计算机程序中漏洞(错误)的系统化流程。
人工走查:手动逐行跟踪代码,跟随执行流程和变量值。
打印语句调试:添加临时打印语句,在代码关键点输出变量值。
二分查找调试:反复将代码分成两半,高效缩小漏洞的位置范围。
IDE 工具调试:使用 IDE 内置工具在运行时暂停执行,检查程序状态。
一个 100 行的程序在执行到一半时崩溃。你会如何使用二分查找来定位漏洞?
- 1
步骤 1:在代码中点(第 50 行)添加一个打印语句或断点。
- 2
步骤 2:运行程序。如果程序在到达第 50 行之前崩溃,说明漏洞在前 50 行;如果没有崩溃,说明漏洞在 51–100 行之间。
- 3
步骤 3:对包含漏洞的那一半代码重复该过程,每次缩小范围。
- 4
步骤 4:当你将漏洞范围缩小到单行或小块代码时停止。
3. 调试工具★★★☆☆⏱ 3 min
现代集成开发环境(IDE)包含强大的内置调试工具,比人工方法更快定位运行时错误和逻辑错误。CIE 要求你掌握最常用工具的功能。
断点
设置在代码行上的标记,指示调试器在到达该行时暂停执行,允许你检查当前程序状态。
监视表达式:添加到调试器监视列表的变量或表达式,每当执行暂停时都会显示其当前值。
步入(Step into):执行下一行代码,如果该行调用了函数,则在函数内部暂停执行。
步过(Step over):执行下一行代码,直接运行完所有被调用函数,不会在函数内部暂停。
步出(Step out):继续执行直到当前函数返回,然后再次暂停。
函数 calculateTotal(price, tax) 在输入 price=100,tax=0.2 时,返回了错误的总价 $102,而预期值是 $120。你会如何使用断点和监视功能找到错误?
- 1
步骤 1:在
calculateTotal函数内部的第一行设置一个断点。 - 2
步骤 2:使用测试输入 price = 100,tax = 0.2 运行程序。
- 3
步骤 3:执行暂停后,将
price、tax和当前总价添加到调试器的监视列表。 - 4
步骤 4:逐行单步执行函数的每一行,每次执行后检查总价,看它在哪一步偏离了预期值。
- 5
步骤 5:找到错误行后,修复错误并重新测试函数。
4. 系统化调试流程★★☆☆☆⏱ 3 min
有效的调试遵循可重复的系统化流程,而非猜测问题所在。这能减少耗时,确保漏洞被完全解决,不会引入新问题。
使用最简测试用例稳定复现漏洞
根据错误症状提出关于漏洞位置的假设
通过检查代码和程序状态验证假设
如果假设错误,提出新的假设并重复测试
找到漏洞位置后,实施错误修复
测试修复,确认漏洞已解决,且没有引入新漏洞
检查你对核心概念的理解:
系统化调试的第一步是什么?
修复漏洞
复现漏洞
提出假设
设置断点
显示答案
复现漏洞 —你必须首先能够稳定复现漏洞,才能正确对其进行调查。
以下哪一项属于逻辑错误?
缺少分号导致编译停止
除零错误导致程序崩溃
计算百分比时除以 10 而非 100,输出 1000% 而非 10%
Python 中忘记闭合括号
显示答案
计算百分比时除以 10 而非 100,输出 1000% 而非 10% —逻辑错误可以运行不崩溃,但给出错误输出,符合该情况。
Exam tip:
CIE 经常考察测试和调试的区别:记住测试发现漏洞,调试修复漏洞。
5. 常见陷阱
错误做法:
在考试答案中混淆测试和调试
原因:
测试仅确认漏洞存在,不会定位或修复漏洞
正确做法:
始终明确:测试识别漏洞是否存在,调试定位并解决漏洞
错误做法:
因为输出错误就将逻辑错误归类为运行时错误
原因:
运行时错误一定会导致程序崩溃或中止,逻辑错误不会
正确做法:
如果程序可以运行完成但给出错误输出,那就是逻辑错误
错误做法:
跳过复现漏洞,直接修改代码
原因:
没有稳定复现,你无法确认你的修复是否真的生效
正确做法:
开始调试前,始终先创建一个能复现漏洞的最简测试用例
错误做法:
描述调试器时混淆步入和步过
原因:
混淆这两个概念是常见的考试错误,会丢分
正确做法:
步入会进入函数以便在内部调试;步过会直接运行完函数,不暂停
错误做法:
修复漏洞后不重新测试
原因:
修复一个漏洞可能会在程序其他部分引入新漏洞
正确做法:
修复漏洞后始终运行所有相关测试,确认修复有效
6. 速查表
类别 | 条目 | 考试核心要点 |
|---|---|---|
错误类型 | 语法错误 | 执行前被捕获,程序无法运行 |
错误类型 | 运行时错误 | 执行过程中发生,导致程序崩溃 |
错误类型 | 逻辑错误 | 不崩溃,输出错误,最难调试 |
调试工具 | 断点 | 暂停执行以检查程序状态 |
调试工具 | 步入 | 在被调用函数内部暂停以便检查 |
调试工具 | 步过 | 运行完函数,不在内部暂停 |
调试方法 | 二分查找 | 在大型代码库中快速定位漏洞 |
流程步骤 | 第一步 | 稳定复现漏洞 |
真题中的出现
AI 根据考纲规律估算的考点位置,请对照官方真题核实准确性。仅作复习重点参考。
- 2022 · 12
对程序错误类型进行分类
- 2023 · 11
描述调试工具的功能
- 2021 · 13
概述系统化调试流程
深入阅读
下一步
调试是 CIE A-Level 计算机科学的核心实践和理论技能,建立在你对软件开发生命周期和程序设计的理解之上。你在这里学到的漏洞定位和解决的系统化方法适用于所有编程范式,对考试答题和你自己的实践编程作业都很有用。掌握调试后,你可以通过学习不同类型的软件测试、高级错误处理技术,以及支持协作开发环境中调试的版本控制工具,深化你对软件质量的知识。
