去年我数过一次。团队每天推到我面前的代码变更,大概在1500到2500行之间。一年前这个数字是600行左右。团队没扩编,产出翻了几倍——AI助手让所有人写代码变快了,但没人让我读代码变快。
于是我做了大多数技术负责人都干过的事:扫一眼,找明显的错,确认测试过了,留两条命名建议,点通过。然后一个bug上了生产。它藏在一个我逐行读完、格式干净、整整300行的变更里。代码不聪明,也不隐蔽,就是没被看出来。
那一刻我认了一件事:逐行审查这套方法,已经撑不住了。假装它还行,比承认它不行更糟。
为什么逐行读会失效
代码审查诞生在一个"写代码才是慢环节"的世界里。开发者花一天做功能,审查者花三十分钟读,这个比例成立。现在这个比例没了——一个人一小时能产出过去一天的量,diff看起来工整、变量名合理、读起来像好代码,而这恰恰是问题所在。
AI写的代码,错法和人不一样:
- 人犯的是脏错误。拼写、别扭的逻辑、半截思路,一眼就能看出不对劲。
- AI犯的是干净错误。少一个权限校验、循环里塞了条查询、事务没盖住该盖的那一步。它们看起来完全正确。
当一切都看起来正确,逐行读就变成了"找看起来不对的东西"。而真正危险的bug,看起来是对的。
我现在审什么
我没停止认真审查,只是换了把力气花在哪。读第一行之前,我先问五个问题,每个问题都把注意力钉在真正出事的地方。
- 数据变了什么?迁移、模型改动、任何写库的操作,永远是我的第一站。代码几分钟能回滚,数据不能。我会盯:锁大表的迁移、旧代码还在依赖却被改名或删掉的字段、本该在事务里却没进去的写入、会悄悄填满几百万行的默认值。数据层错了,这个PR里其他东西都不重要。
- 谁被允许做这件事?第二贵的bug是权限bug。每个新接口或视图,我只问一句:用户能不能碰到不属于他的数据?查询有没有按当前用户或组织收窄,还是只拿请求里的ID过滤了一下。AI生成的视图很擅长返回正确的对象,但不太可靠地只返回正确的对象。
- 数据量放大100倍会怎样?在开发者笔记本上跑20毫秒的查询,生产环境能跑20秒。我找循环里的查询、缺失的关联预加载、没建索引的过滤字段、把整张表读进内存的操作。不用逐行读,只要找出所有碰数据库的地方,慢慢读那几处。
- 失败的时候会怎样?顺利路径好审,生产活在倒霉路径里。外部接口超时呢?异步任务跑两遍呢?用户双击按钮呢?如果答案是"大概不会发生",它就会发生,通常还在周末。
- 作者能讲清楚吗?这条跟代码无关。任何非琐碎的改动,我会让作者用两三句话讲思路。不是考他,是看这个设计是他的,还是他直接接受的。讲得清楚,后面整个diff我更信;讲不清楚,我就知道该在哪慢下来。
我不再审查代码,我审查风险。代码只是风险待着的地方。
我主动放掉的东西
换焦点意味着有意识地少在乎一些事。格式和风格基本不评论了,linter和formatter干得比我好;命名偏好也不提了,除非名字会主动误导人;"换我会写成别的样子"——只要正确、安全、可读,我的偏好不重要。
一开始很难。风格评论感觉很有产出,看得见,好写。但我花在变量名上的每一分钟,都是从"少一个权限校验"那里偷来的。
这五个问题后来还改了团队写PR的方式。大家知道审查者会从数据、权限、规模、失败、解释这五处开始,就提前把答案写好了。我们在PR模板里加了一小段"风险说明":数据改动、权限影响、性能顾虑、失败处理、以及我不确定的地方。最后那条最值钱——有人写下"我不确定重试逻辑对不对",等于直接告诉我该看哪。
审查变快了,而且很长一段时间以来第一次,同时变好了。
我一度以为,好的审查者是读完全部、什么都没漏的人。这从来不现实,AI进了流程之后,更不可能。今天好的审查者,是知道坑通常埋在哪的人:数据层、权限边界、放大就崩的查询、没人规划过的失败。把注意力花在那里,剩下的交给工具。
AI让写代码变便宜了,让判断变贵了。审查,就是这份判断被花掉的地方。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.