代码审查基础:代码审查的目的、代码审查的类型、审查流程

代码审查这件事,我做了十几年嵌入式开发,说实话,它是我见过性价比最高的质量保障手段。你想想看,一个bug在编码阶段发现,改起来可能就几分钟;要是流片前才发现,那得改设计、改PCB、改驱动,折腾好几天;要是到了客户手里才暴露……嗯,那画面太美我不敢看。

我个人习惯把代码审查看作「给代码照X光」。你写代码时觉得自己逻辑完美无缺,但别人一看,往往能发现你根本想不到的问题。这不是你水平不行,而是人对自己写的代码有「盲区」——就像你很难发现自己写的错别字一样。

代码审查的目的

说白了,代码审查不是为了找茬,更不是为了证明谁比谁厉害。它的核心目的就四个:

  • 发现缺陷:逻辑错误、边界条件遗漏、竞态条件、内存泄漏……这些在审查阶段被发现,成本最低。我在项目中遇到过最典型的一个案例:同事写了个定时器回调,里面直接调用了malloc,在中断上下文里搞动态内存分配,结果系统跑着跑着就挂了。这种问题,单靠单元测试很难复现,但人眼一看就发现了。
  • 提升代码可维护性:代码是写给人看的,顺便给机器执行。审查能帮你发现命名混乱、函数过长、耦合过高等「代码坏味道」。我曾经审查过一段代码,一个函数写了800行,里面嵌套了6层if-else,我看了三天才看懂它在干什么——后来我们把它拆成了12个小函数,每个函数只做一件事。
  • 知识传递:新人通过审查老手的代码,能快速学习项目规范和最佳实践;老手通过审查新人的代码,也能了解新思路。我团队里有个规矩:每个新入职的同事,前三个月必须至少参与10次代码审查,效果比看文档好十倍。
  • 建立团队共识:代码风格、命名规范、架构约定,这些光写在文档里没人看。通过审查,大家慢慢就形成了统一的「代码审美」。

核心观点:代码审查不是质量检查的终点,而是质量内建的关键环节。它应该发生在代码合入主线之前,而不是之后。

代码审查的类型

很多人以为代码审查就是「一群人坐在一起看代码」,其实不是。根据正式程度和参与方式,我把它分成三类:

1. 正式审查(Formal Inspection)

这是最严格、最正式的方式。通常由主持人、作者、审查员、记录员组成一个小组,按照预定的流程逐行审查代码。审查前需要准备材料,审查中要记录所有问题,审查后要跟踪整改。

我记得在做一个安全关键系统(IEC 61508 SIL3级别)时,我们不得不采用正式审查。每次审查前,审查员要花2-3小时提前阅读代码,然后开会2小时逐行过。虽然耗时,但确实有效——那次项目交付后,现场运行三年零故障。

适用场景:安全关键系统、高可靠性要求项目、合规性审查(如MISRA C、DO-178C)。

2. 同行评审(Peer Review / Code Review)

这是嵌入式开发中最常用的方式。通常由作者邀请1-3名同事,通过工具(如Gerrit、GitHub Pull Request)进行异步审查。审查员在代码上直接添加评论,作者根据评论修改,来回几轮后合入。

我个人最喜欢这种方式。为什么?因为它灵活。你可以在自己方便的时候看代码,不用凑大家的时间。而且异步审查给了你思考的时间——看到一段可疑代码,你可以去查查手册、跑个测试,再回来评论。

我曾经用这种方式发现过一个极其隐蔽的bug:同事在写I2C驱动时,对寄存器地址做了位运算,但没考虑到地址对齐的问题。我是在审查时随手画了个地址位图,才发现那个偏移量算错了。如果当时是面对面走查,我可能不会那么仔细地去画图。

注意:同行评审最怕「走过场」。我见过有些团队,审查员只看个标题就点「Approved」,那还不如不审。我建议每个审查员至少花15-30分钟认真看代码,别敷衍。

3. 走查(Walkthrough)

走查比较随意。通常是作者在会议室里,对着白板或投影仪,把代码逻辑讲给团队成员听。大家边听边提问,作者边讲边解释。

走查的好处是效率高、氛围轻松。适合用来审查新模块的设计思路,或者复杂算法的实现。我经常在走查时发现:作者讲着讲着,自己就发现bug了——这就是「橡皮鸭调试法」的团队版。

不过走查也有缺点:容易流于表面。大家听着听着就走神了,或者不好意思打断。所以我建议走查时指定一个人专门负责「挑刺」,效果会好很多。

类型 正式程度 参与人数 耗时 适用场景
正式审查 4-6人 长(半天到一天) 安全关键、合规要求
同行评审 2-4人 中(1-2小时) 日常开发、功能模块
走查 3-8人 短(30分钟-1小时) 设计评审、算法讲解

审查流程

不管哪种类型,代码审查的流程都大同小异。我把它总结成五个步骤:

  1. 准备阶段:作者提交代码,附上变更说明。审查员提前阅读代码,记录疑问点。我个人习惯在审查前先跑一遍静态分析工具(比如PC-lint、Coverity),把工具能发现的问题先过滤掉,这样审查时只关注逻辑和设计问题。
  2. 审查会议:如果是正式审查或走查,大家坐在一起逐行过代码。同行评审则通过工具异步进行。这个阶段的目标是「发现问题」,而不是「解决问题」。我曾经犯过一个错误:在审查会上直接帮作者改代码,结果改了半天,其他问题都没看。后来我学乖了——只提问题,不改代码。
  3. 记录问题:所有发现的问题都要记录下来,包括问题描述、严重程度、建议修改方案。我建议用工具管理这些问题,比如Jira、GitHub Issues,方便跟踪。
  4. 修改与验证:作者根据问题列表修改代码,然后提交修改。审查员需要验证修改是否正确。这里有个坑:有些审查员只看修改的部分,不看上下文。我曾经遇到过:同事为了修复一个bug,改了A函数,结果把B函数里依赖A的行为给破坏了。所以验证时一定要看全上下文。
  5. 关闭与复盘:所有问题都解决后,审查关闭。我建议团队定期做审查复盘——统计一下审查发现了多少问题、什么类型的问题最多、哪个模块问题最集中。这些数据能帮你持续改进。

避坑指南:我曾经在一个项目里,因为赶进度,把审查流程压缩成了「提交-看一眼-合入」。结果上线后出了三个严重bug,其中一个导致设备死机,客户投诉到CEO那里。从那以后,我定了个铁律:任何代码合入主线前,必须经过至少一个人的审查,且审查时间不得少于15分钟

嗯,代码审查这件事,说难不难,说简单也不简单。它考验的不是技术能力,而是团队协作的意识和习惯。我见过技术很强的团队,因为不重视审查,代码质量一塌糊涂;也见过技术一般的团队,因为坚持审查,交付的产品稳定可靠。

所以我的建议是:别把审查当成负担,把它当成投资。你花在审查上的每一分钟,都是在为未来的自己减少麻烦。