让 AI 生成一段代码并不难。真正麻烦的是,代码拿到手之后,怎么判断它能不能用。
代码只要看起来完整,就很容易让人产生一种已经解决问题的错觉。尤其是学习或处理陌生内容时,AI 往往会把回答写得比较肯定,但代码是否适合当前环境,还需要自己继续确认。
能运行不等于正确
一段代码能够编译、能够运行,只能说明它满足了某些基本条件,不代表它符合实际需求。
例如下面这个通用方法可以计算一个整数列表的总和:
public int sum(int[] values) {
int result = 0;
for (int value : values) {
result += value;
}
return result;
}它对普通的小整数数组可能没有问题,但验证时还可以继续问:空数组是否应该返回 0,整数相加是否可能溢出,参数为 null 时应该怎么处理,调用方是否允许传入很大的数据。
代码能跑通只是第一步。真正需要确认的是,它在需求允许的输入范围内是否都表现正确。
AI 不知道完整上下文
AI 生成代码时,能够看到的内容取决于我提供了什么。如果只描述一个方法需要完成的目标,它并不知道项目中的类关系、数据库结构、异常处理方式和编码习惯。
同一句“帮我写一个查询方法”,在不同项目中可能对应完全不同的实现:
- 返回单个对象还是列表;
- 查不到数据时返回空值还是抛出异常;
- 是否需要分页;
- 是否需要校验用户权限;
- 是否允许直接拼接输入;
- 事务和日志应该由哪一层处理。
因此,生成的代码最多是一个起点。它没有自动获得项目上下文,也不能替我决定业务规则。
我会检查哪些内容
拿到一段 AI 生成的代码后,我会先看它是否真的回答了原问题,再看几个容易被忽略的地方:
- 参数是否可能为空;
- 返回值是否覆盖正常和异常情况;
- 循环、分页和边界条件是否正确;
- 异常是否被吞掉;
- 数据库和文件等资源是否正确关闭;
- 是否引入了不必要的依赖;
- 是否存在明显的安全问题;
- 命名和结构是否符合当前项目。
这些检查不一定一次全部完成,但至少要知道代码的假设是什么。若代码依赖某个版本的 API,还需要回到对应文档确认。
用最小示例验证
如果代码比较复杂,我不会一开始就把它放进完整项目里。可以先准备一个小输入,验证最基本的路径,再逐步增加边界条件。
正常输入
-> 空输入
-> 最大或最小边界
-> 非法输入
-> 异常路径
-> 对照预期结果这样做的好处是,问题出现时更容易知道是代码本身的问题,还是项目环境、配置和调用方式的问题。
但这里的示例是通用验证方法,不是某次具体项目测试的记录。文章不把它写成已经发生的内部故障或测试结果。
不要被完整解释影响判断
AI 的回答通常会同时给出代码、解释和使用方式。解释写得很顺时,代码看起来也更可信,但表达流畅并不能证明实现正确。
我会把回答中的内容分开看:
- 代码本身是否符合语法和 API 约束;
- 解释是否真正对应代码的执行过程;
- 示例输入是否覆盖了边界;
- 推荐方案是否符合当前业务上下文。
如果这几部分之间互相矛盾,就不能直接采用。即使没有明显矛盾,也应该通过编译、运行、查资料或阅读调用方来确认。
最终责任还是开发者
AI 可以帮助我减少重复输入,也可以提供一种不熟悉的写法。但代码进入项目之后,真正需要承担后果的仍然是开发者。
所以,我不会把“AI 生成的代码”当成已经完成的功能,而是把它当作一份需要阅读和验证的候选实现。先理解它做了什么,再检查它没有做什么,最后才决定是否保留、修改或舍弃。
AI 生成的代码为什么还需要自己验证?因为代码的正确性不只取决于能不能运行,还取决于它是否满足需求、是否适合上下文,以及在异常和边界情况下是否仍然可靠。