把一套完整的 Java 老项目源码交给 AI 做代码审查,它能找出多少真正需要修的问题?一位开发者基于「企业融合评估平台」的真实源码做了一次实测:要求 AI 找出 20 个“坑”,包括安全漏洞、性能隐患和设计缺陷,再由人工逐条复核。结果是 AI 报了 20 个问题,开发者认可 15 个,否定 5 个;如果把其中 1 条“半对”的建议也算入有效项,有效率为 80%。
这次测试的价值不在命中率本身,而在于它呈现了 AI 代码审查在遗留系统中的真实边界:哪些问题可以放心交给 AI 扫出来,哪些问题看似合理却不值得立即动手,以及人工复核应该重点看什么。
AI 找到的 15 个“真坑”:多为可验证的安全与工程问题
被确认的问题大多属于“实锤型”缺陷,即只要具备一定 Java 开发经验,看到证据后基本都会认可。例如,项目使用 fastjson 1.2.37,该版本存在多个 autoType 绕过漏洞,可能被构造恶意 JSON 实现远程代码执行,被列为最高优先级修复项。
安全层面还包括 AES/ECB 模式加密和密钥硬编码。项目前后端登录密码加密使用了 AES/ECB/PKCS5Padding,相同明文块会产生相同密文块,攻击者可通过密文模式分析推断明文结构;同时密钥直接写在源码中,任何能访问代码仓库的人都能获取。作者建议改为 AES/CBC 或 AES/GCM,并通过配置中心或环境变量注入密钥。
工程与并发问题同样不少。全项目扫出 25 处 printStackTrace,异常信息进入 stdout 后难以在生产环境检索;多处使用 Executors.newFixedThreadPool,其内部依赖无界 LinkedBlockingQueue,任务堆积时可能引发 OOM;还有 static ThreadLocal 与线程池复用结合,可能导致上一个请求的上下文数据泄漏到下一个请求。
最隐蔽的问题出现在事务处理上。一个带有 @Transactional 的删除方法内部用 try-catch 吞掉异常,导致 Spring 无法感知异常,事务不会回滚。代码表面上有 @Transactional 和 rollbackFor,但实际效果等于没有事务保护,删除一半数据后可能留下脏数据。此外,项目还有 10 处 @Transactional 未显式指定 rollbackFor,受检异常发生时事务会静默不回滚。
其他被确认的问题还包括:Guava Cache maximumSize=50 导致第 51 个用户登录时最早会话被踢出;定时任务捕获所有异常后只打日志、无告警,任务持续失败也可能长期无人发现;synchronized 锁整个类导致高并发场景下串行化;System.out.println 代替日志;以及 catch 后返回 null,让前端无法区分“没有数据”和“发生错误”。
5 条误报的共同点:技术上正确,上下文里错误
被否定的 5 条建议并非完全胡说,反而都带有某种“规则上的正确性”。问题在于,AI 没有结合变量作用域、框架默认行为、项目架构和改造成本进行判断。
- SimpleDateFormat 线程不安全:AI 按照常见规则报警,但项目中的 SimpleDateFormat 都是方法内 new 出来的局部变量,不存在共享。真正的优化点不是线程安全,而是重复创建对象,可考虑提取为 ThreadLocal 或使用 DateTimeFormatter。
- @Transactional 不应出现在 Controller 层:从分层原则看有道理,但 Spring 事务基于 AOP 代理,只要不是同类内部自调用,放在 Controller 层技术上可以生效。对遗留系统来说,为“分层纯洁性”调整可正常运行的事务边界,风险可能大于收益。
- 全链路 JSONObject 参数丢失类型安全:这条建议忽视了项目现实。JSONObject 并非某个接口偷懒,而是贯穿 Controller、Service、Mapper、XML 的既有架构决策。只改 Controller 层会增加转换成本,全链路改造又可能波及 80 个文件;在没有测试的项目中,这种改动风险很高。
- count++ 存在竞态条件:AI 看到共享可变状态和非原子操作就报警,但 Spring @Scheduled 默认使用 ScheduledThreadPoolExecutor,核心线程数为 1,同一时刻只有一个定时任务执行,该场景下 count++ 是安全的。
- 导出方法返回 null 违反 RESTful 规范:相关方法已通过 HttpServletResponse 直接写入 Excel 二进制流,执行到 return null 时响应可能已经完成。AI 只看到了返回值形式,没有识别出实际响应路径。
这些误报呈现出同一规律:AI 容易把通用规则直接映射到代码片段上,却缺少对项目上下文、框架行为和改造成本的判断。它可能发现“理论风险”,但无法判断这个风险在当前系统里是否真的会发生,也无法评估修复是否值得。
人机协作的 code review:AI 适合扫已知模式,人负责判断优先级
这次实测给出的方法论并不是“AI 能不能替代 code review”,而是“AI 在 code review 中应该放在什么位置”。从结果看,AI 对已知模式的问题识别能力较强,尤其是安全漏洞、常见反模式、日志异常处理、事务配置缺失等。这类问题往往有明确证据,也容易被工具化规则覆盖。
但涉及上下文判断时,人工复核仍然不可省略。作者总结的误报原因包括:按关键词匹配规则而不看变量作用域;把代码规范问题与功能缺陷混为一谈;只看代码形式而忽略改造成本和项目约束;不了解框架默认行为,把理论风险当成实际 bug。
由此可以整理出一份适用于遗留系统的 AI 代码审查复核清单:
- 先分级:安全漏洞、数据一致性、线上可用性相关问题优先处理;纯规范类建议后置。
- 看作用域:线程安全类问题要确认变量是否真的被共享,而不是只根据类名报警。
- 看框架行为:涉及 Spring 事务、定时任务、线程池、AOP 的建议,要确认框架默认机制和实际调用路径。
- 看改动成本:对于贯穿多层的设计问题,不能只从单文件合理性出发,要评估是否有测试、是否会影响大量文件、是否能分阶段迁移。
- 看生产后果:日志、异常、返回值等问题要结合实际运维方式判断,例如是否能被监控发现、是否会污染日志系统、是否影响前端处理。
该实测还指出,AI 的价值不只是“找到问题”。在遗留系统里,真正稀缺的是判断哪些问题值得修、哪些可以暂时接受、哪些改动会引入更大风险。AI 可以帮助开发者更快扫描已知问题模式,但最终的严重性评估、修复优先级和工程取舍,仍需要熟悉项目背景的人来完成。
原创文章,作者:点点,如若转载,请注明出处:https://www.dian8dian.com/ai-dai-ma-shen-zha-shi-ce-yi-ge-2022-nian-java-lao-xiang-mu