代码评审核心要点:7大类检查清单,提升代码质量与安全性
2026/9/20 9:13:50 网站建设 项目流程

2. 核心要点拆解:到底在查什么

我自己在做这套流程时,把检查清单固定成7大类,每一类背后都有对应的失败案例在支撑,不是拍脑袋定的:

2.1 逻辑正确性

这是review的第一优先项。逻辑错了,后面全是白搭。具体看几个点:

  • 边界条件有没有想清楚?比如数组越界、字符串为空、集合只有1个元素、数值为0或负数、时间戳刚好是整点等,这些边界最容易出bug。
  • 分支判断是否覆盖了所有可能性?if-else写全了吗?有没有隐含的else分支(即“默认情况”)会走错逻辑?
  • 循环终止条件是否正确?会不会死循环?会不会少循环一次?
  • 异步场景下的竞态条件:有没有可能在回调还没回来时,另一个请求已经改了状态?

我举个真实例子:某次review发现一个支付回调处理函数,订单状态判断用的是if (status == 1)而不是if (status == 1 || status == 2),结果用户在“已支付”状态下再次收到回调时,直接走入了异常分支,订单被标记成“支付失败”。这种bug靠测试都很难发现,因为测试只覆盖了正常流程。

2.2 代码规范与风格一致性

规范问题看似小,但累积起来会让代码库迅速腐烂。团队里只要有一个人不守规范,其他人为了“保持风格统一”往往会直接骂人而不是帮他改。所以在review时需要关注:

  • 命名是否清晰达意:变量名、函数名、类名是否体现了它们各自的职责?datatempflag这类命名其实都应该被标红。
  • 格式是否与团队规范一致:缩进、空格、换行、引号风格、是否加分号等。这类问题最好交给linter自动检查,人工review不应该浪费精力在纯格式问题上。
  • 函数长度与圈复杂度:一个函数超过50行、if嵌套超过3层时,基本就该考虑拆分了。圈复杂度(Cyclomatic Complexity)过高意味着测试难度和出错概率都在上升。
  • 是否重复造轮子:同样逻辑写了三遍?能不能提取成公共函数?有没有现成的工具库可用而没用?

2.3 安全性审查

安全在review中往往是最容易被忽略的,因为很多安全漏洞在功能测试阶段看不出来,等到上线才会被人利用。我总结了几类高频问题:

  • 输入校验缺失:用户输入直接被拼接到SQL或命令中,导致SQL注入、命令注入。最典型的就是把用户传来的ID直接拼到SQL里,而不用参数化查询。
  • XSS漏洞:用户输入没有转义就直接渲染到前端页面,或者innerHTML直接拼接不可信数据。
  • 鉴权/越权问题:接口有没有校验当前登录用户的权限?普通用户能不能访问管理员的接口?ID从请求参数里取,导致水平越权(同一级别用户互访数据)。
  • 敏感信息泄露:日志里打了密码或密钥?接口返回了多余的敏感字段?前端代码里硬编码了API密钥?这些一旦上生产就是事故。
  • 文件上传安全:上传的文件类型校验是否可信?是不是只检查了Content-Type?有没有限制文件大小?上传目录是否可执行?

我在实践中发现,很多团队review时根本不看安全问题,默认“有别人会看”。但代码评审恰恰是安全防线最前、成本最低的一环,比上线后靠WAF和漏洞扫描来兜底有效得多。

2.4 可读性与可维护性

代码写出来不是给机器看的,机器反正都认识0和1。真正要给你自己、你的同事、三个月后的你看的。所以我review时非常关注可读性:

  • 有没有注释?注释是否跟实际行为一致?最讨厌的是“改了代码没改注释”,注释描述的是旧逻辑,直接误导。我一般会要求“注释宁缺毋滥”,但必须准确,不能跟代码打架。
  • 命名是否自解释:一个叫作isValid()的函数一看就知道返回值是布尔。processData()这种谁都看不出来具体干什么的名字,其实等于没名字。
  • 代码块的职责是否单一:一个模块/函数能不能在一句话里说清楚它做什么?如果说要两句话才能说清楚,那这个函数大概率“多管闲事”了。

2.5 错误处理与边界值处理

很多崩溃性问题归根到底都是“该处理的情况没处理”。我每次review都会专门盯几个方向:

  • 外部依赖不可靠:第三方接口超时、数据库连接偶尔失败、Redis挂掉,代码到底怎么退避重试?会不会无限制重试导致雪崩?
  • 空值处理:从接口返回的数据,直接.length.toString()前是不是先判断了空指针?防御式编程该不该用?要用在哪一层?
  • 异常与错误码:异常信息是否可读?是否能把上下文(比如:哪个用户、哪个订单、哪个时间)带出来?错误码能不能直接定位到具体错误位置?
  • 日志记录:出错时报不报日志?日志级别选对没有?有没有可能在日志里打印隐私数据?

2.6 性能与资源管理

性能问题在review阶段就能发现一大半,不用等到压测。我关注的主要是:

  • 循环里的慢操作:for循环里有没有发HTTP请求、查数据库?这种通常应该提到循环外面或合并批量查询。
  • N+1查询问题:ORM框架下先查了10个用户,再循环去查每个用户的订单,产生10次查询。正确做法是IN一次查出所有人的订单,再在内存里分组。
  • 重复计算:循环里反复计算同一个不变的值?应该提到外面缓存。
  • 资源未释放:文件流、数据库连接、HTTP连接、定时器,用完之后关没关?在异常路径上关没关?用不用try-with-resources?
  • 大对象持有:从大文件或大表里一次性加载所有数据到内存?考虑分批处理或流式处理。

2.7 变更影响范围

这一点我特别想强调,但是很多review清单里都没有单独列出来。每次提交PR,你都要问三个问题:

  • 这个改动是否影响已有功能?有没有关联的老测试被改坏了?
  • 这个改动是否涉及公共接口(API、数据库表结构、消息格式等)的变更?下游系统知道吗?
  • 这个改动是否针对当前任务?如果顺手改了好几处无关代码,review时很难评估真实影响,建议拆分为多个PR。

我自己遇到过一次事故:一个同事在修bug时,顺手改了一个“看起来没用”的工具函数内部逻辑,结果这个工具函数被十几个模块复用,直接导致线上另外两个功能挂了。这就是典型的“影响范围不明确”。所以review时如果看到与本次需求无关的改动,必须要求发起人说明理由,说不清楚就打回。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询