调试技巧与 AI 排错:当侦探遇上 AI 助手
写代码的时间分配大概是这样的:10% 写新功能,90% 搞清楚"为什么不行"。
调试(debugging)就是"找 bug"的过程。这个词的来历很有趣——1947 年哈佛大学的程序员在计算机里真的找到了一只飞蛾(bug),卡在继电器里导致故障。从此 bug 就成了程序错误的代名词。
print 大法:最朴素也最好用
别笑。不管你用什么高级调试工具,print / console.log 永远是你最忠实的伙伴。
print 调试的要点:
- 标记输出——加上
[DEBUG]前缀,方便和正常输出区分 - 关键节点打印——函数入口、循环内部、条件分支、返回前
- 打印变量的值和类型——有时候 bug 就是类型不对
- 调完记得删——别把 debug 的 print 留在最终代码里
JS 的 console 全家桶
JS 的 console 不只有 log,还有一堆好用的方法:
在浏览器的 DevTools 里,
console.table会生成一个漂亮的表格,console.warn是黄色背景,console.error是红色背景。这些在我们的代码编辑器里可能看不出区别,但在实际开发中非常好用。
读懂错误信息
错误信息就像医生的诊断书——你得学会读。来看看错误信息的结构:
读错误信息的三步法:
- 看错误类型——
TypeError?KeyError?这告诉你出了什么种类的问题 - 看错误消息——
'int' object has no attribute 'upper',这告诉你具体出了什么问题 - 看堆栈跟踪(stack trace)——从下往上读,最底下的那行就是出错的位置
Python 的错误信息通常比 JS 更详细、更友好。JS 的错误信息有时候很"简约",需要你自己推理。
Python 的 traceback 阅读指南
Python 的错误输出叫 traceback(回溯),从上往下是调用链,最后一行才是出错的地方:
Traceback (most recent call last):
File "main.py", line 10, in <module> ← 起点:main.py 第 10 行
result = process(data)
File "main.py", line 5, in process ← 经过:process 函数第 5 行
return transform(item)
File "main.py", line 2, in transform ← 出事地点!第 2 行
return item.upper()
TypeError: 'int' object has no attribute 'upper' ← 什么错
读法:从最后一行开始读——先看"什么错",再往上看"在哪出的错"。就像交通事故报告,先看"翻车了",再看"在哪个路口翻的"。
常见 bug 模式
来看几个经典的"翻车现场"和修复方法:
AI 辅助排错
现在是 2026 年了,你有一个强大的调试帮手——AI。但"把错误信息扔给 AI"和"有效地用 AI 排错"之间有很大区别。
给 AI 报 bug 的正确姿势
差的问法:
"我的代码报错了,帮我看看"
好的问法:
"我在写一个计算平均分的函数,预期输入
[88, 92, 55]应该返回78.33,但实际返回了None。以下是我的代码和完整的错误信息:[粘贴代码和报错]"
好的 bug 报告包含这些要素:
- 你想做什么——"计算平均分"
- 预期行为——"应该返回 78.33"
- 实际行为——"返回了 None"
- 完整代码——不是截图,是可以复制的文本
- 完整报错信息——包括 traceback / stack trace
试试把下面这段"bug 报告"发给 AI:
"我写了一个函数统计列表中正数的个数,但结果总是 0。代码如下:
def count_positive(numbers):
count = 0
for n in numbers:
if n > 0:
count += 1
return 0 # 这里有 bug,你能发现吗?
print(count_positive([1, -2, 3, -4, 5]))
请帮我找出 bug 并解释原因。"
看看 AI 能多快定位到问题。然后想想:如果你只说"我的函数不对",AI 还能帮你吗?
用 AI 排错的进阶技巧
AI 排错清单
当你遇到 bug 时,按这个步骤来:
- 先自己读错误信息——80% 的 bug 都能从错误信息直接看出来
- 加 print 缩小范围——找到"从哪一行开始出错的"
- 构造最小复现——删掉所有无关代码,只留出 bug 的最少代码
- 问 AI 时提供完整上下文——代码 + 报错 + 预期行为 + 实际行为
- 理解 AI 的修复方案——不要无脑复制粘贴,搞懂为什么这样修
下面这段代码有 3 个 bug,尝试用本节学到的调试技巧找出来:
def calculate_grade(scores):
total = 0
for score in scores:
total += score
average = total / len(scores)
if average >= 90:
grade = "A"
elif average >= 80:
grade = "B"
elif average >= 70:
grade = "C"
elif average >= 60:
grade = "D"
return grade
# 测试
print(calculate_grade([95, 88, 92])) # 应该输出 "A"
print(calculate_grade([])) # 应该输出 "无成绩"
print(calculate_grade([45, 52, 38])) # 应该输出 "F"
提示:
- Bug 1:空列表会怎样?
- Bug 2:所有分支都覆盖了吗?
- Bug 3:如果不进任何 if 分支呢?
先自己找,实在找不到再把代码和问题描述一起发给 AI。记住:先自己想,再问 AI。这样你学到的更多。
Python 的 pdb 和 JS 的 DevTools
除了 print 大法,还有更专业的调试工具。这里简单介绍一下,等你需要的时候再深入学:
Python: pdb(Python Debugger)
import pdb
def buggy_function(data):
result = []
pdb.set_trace() # 程序会在这里暂停,进入交互模式
for item in data:
result.append(item * 2)
return result
在 pdb 交互模式中,你可以:
n(next)——执行下一行p variable——打印变量值c(continue)——继续运行q(quit)——退出调试
pdb 是命令行下的调试器,适合在终端里用。更好用的是 IDE 自带的可视化调试器(比如 VS Code 的 Debug 面板),可以设断点、看变量、单步执行。
JavaScript: 浏览器 DevTools
在浏览器里按 F12 打开 DevTools,这是前端开发者最好的朋友:
- Console 面板——看
console.log输出和错误信息 - Sources 面板——设断点、单步调试
- Network 面板——查看网络请求
- Elements 面板——查看和修改 HTML/CSS
在代码中写 debugger 语句,浏览器执行到那里时会自动暂停:
function buggyFunction(data) {
debugger // 浏览器会在这里暂停
return data.map(item => item * 2)
}
调试心态
最后说几句"非技术"的建议:
- 错误信息是朋友——它在帮你定位问题,不是在骂你
- 橡皮鸭调试法——对着一只橡皮鸭(或任何物体)大声解释你的代码在干什么。很多时候说着说着你就发现 bug 了
- 休息一下——有时候盯了一小时找不到的 bug,去喝杯水回来一眼就看到了
- 版本控制是后悔药——经常 commit,改崩了可以回退(我们后面会学 Git)
- 每个 bug 都是学习机会——修完 bug,花 30 秒想想"为什么会犯这个错",下次就不会了
小结
| 技巧 | Python | JavaScript |
|---|---|---|
| 打印调试 | print() | console.log() |
| 类型检查 | type(x) | typeof x |
| 表格输出 | 手动格式化 | console.table() |
| 断点调试 | pdb.set_trace() / IDE | debugger / DevTools |
| 计时 | time 模块 | console.time() |
一句话总结:调试能力 = 阅读错误信息 + 缩小问题范围 + 有效求助(AI 或同事)。 这三个技能,比写代码本身还重要。