“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

我们如何进行代码审查

  • 2014-01-29
  • 本文字数:2241 字

    阅读完需:约 7 分钟

Jim Bird 是一位经验丰富的软件开发经理、项目经理与 CTO,专注于软件开发与维护、软件质量与安全等领域中疑难问题的解决。在过去的 15 年间,Jim 曾管理过团队建设并主导过高性能的财务系统的建设。他的主要兴趣在于如何提升小团队的效率以构建真正的软件:高质量、安全、可靠、高性能及适应性强。近日,Jim 撰写了一篇博文,谈到了代码审查的价值,如何进行代码审查,代码审查的过程以及在代码审查中需要注意的问题,希望能为大家平日的代码审查带来一些启示。

开始代码审查

从一开始,开发者就会互相帮助,如果测试中遇到了问题或是有新人加入到了团队,领导或是资深开发者就会审查他们的代码。除此之外,我们还聘请了外部专家进行安全代码审查

系统发布后,我们决定更加主动一些,开始了基于风险的审查:项目中有人会编写一些风险较高的代码(比如说框架与安全代码、APIs、核心业务逻辑或是之前曾经出现过问题的地方),我们会审查他们的代码。在这个过程中,代码审查体现出了它的价值,我们收获颇丰。即便如此,我们还是更进一步,让代码审查成为一个标准的实践。

这并不是一夜之间就形成的。让团队相信代码审查的价值并不是什么难事,他们已经通过基于风险的审查获得了收益。不过要想改变人们的工作方式就不是那么简单的事情了,还要确保他们有足够的时间进行代码审查,理解并对反馈作出响应。此外,设计一个高效的代码审查流程也是需要花时间的。

一开始,我们让开发者选择好搭档并安排审查,但结果却有些混乱。有时,开发者会寻找那些好说话或是比较忙的人,这样审查就比较容易通过了;此外,两个开发者还有可能事先商量好,因此审查过程就会很快结束。由于人们并不知道要花费多少时间才能完成代码审查,因此审查经常会拖得很久,常常在代码已经完成测试甚至是发布后才完成。

由于大多数人并没有太多的代码审查经验,因此他们并不确定在审查时应该看什么,如何给出有意义的反馈等信息。开发者常常会被负面的批评搞得很沮丧,有时甚至会心烦意乱。

最后,我们决定由领导来完成大部分审查工作。虽然这会增加领导的工作量,也意味着他们没有太多时间编写代码了,不过这么做却是很有效果的。通常情况下,主开发者会对需求有着更好的理解,对代码的行为有着清晰的认识,这也意味着他们更有可能发现代码中的错误。由于是同一个人完成了大部分的代码审查,因此被审查的开发者会收到一致的反馈信息。

我们如何进行代码审查

在过去的几年间,我们进行代码审查的方式几乎没有发生过什么大的变化。

无论是谁编写的,无论代码的功能是什么,重要的代码变更是一定要审查的。我们并没有一个正式的审查会议,也没发现使用诸如 Code Collaborator、Crucible 等工具有什么必要性,不过现在看起来使用这些工具来管理和追踪审查有助于团队更好的起步。

有时,审查是面对面完成的,不过大多数时候都是离线进行的。审查者与开发者会交换信息,也许通过邮件发送文件,因为我们觉得这种方式更加便捷,也更加方便每一个人安排自己的时间。

随着时间的流逝,审查中的变化之处是审查者该看什么,以及看到的结果。

审查正确性

很多时候,程序员们会花费很多时间争论在代码审查过程中应该看什么,但实际上他们却没有花太多时间完成真正的代码审查。

我们开始代码审查的目的是改进代码质量,寻找测试中没有发现的问题。这么做并不是教授经验不足的开发者如何编写更好的代码,或是如何在团队内分享知识。这些都应该是代码审查所带来的间接好处,不过审查的最终目的应该是确保代码能够正常工作。

相对于使用长长的检查列表,审查者在看代码时首先会问几个问题:

  • 代码的行为是否与预期一致,其逻辑是否是正确无误的?
  • 被审查的代码是否与其他代码拥有类似的结构和功能?

审查可理解性

随着时间的流逝,在代码审查中寻找和得到的东西会发生变化。这是因为代码本身会发生变化,完成这项工作的人——开发者与审查者也可能发生变化。

开发者需要在其 IDE 中装上代码检查工具,同时我们也要使用一些优秀的静态分析工具来自动检查常见的编码 Bug 和不好的编码实践。这意味着审查者的时间可以花在更加重要的设计错误上,比如说并发 Bug、竞态条件和潜在的死锁等,因为这些问题是工具所无法检测到的。

理解,而不是批评

审查的目的是理解代码,确保代码能够正常工作,而不是批评任何人。

在代码审查过程中,请不要掺入诸如“我认为好的代码是什么,你认为好的代码是什么”这样的论战之中。代码审查应该重点关注“我需要完全理解这部分代码才能确保它能够正常工作,如果由我来修复代码中的问题,我是不会这么写的,因此希望你也不要这么来写”。

随着时间的流逝,有些东西会变好,有些则不然

随着时间的流逝,在查看代码时你会发现代码在不断变化。Michael Feathers 发现大部分代码在写完后很少或是从来都不会变化;大部分变更都是发生在代码基中的很小一部分代码上的。

由于审查者会看到相同的代码在不断发生着变化,因此这也会改变他们的审查方式。

避免收益递减

类似于软件开发中的其他实践一样,你最终会发现代码审查有着收益递减的效应,特别是一直在做相同的事情的时候,以相同的方式查看相同的问题。最终会有这样一个阶段,那就是代码审查的价值几乎降到了 0。不过这种情况并没有发生在我们身上,我们依然从代码审查过程中获得了很多收益。

即便改进了工具,增强了测试能力,我们依然进行代码审查,因为 Bug 检查工具、审查与测试会发现不同类型的问题。我们还发现代码审查会让测试更加高效,这是因为如果之前曾经发现过问题,那么开发者与测试者之间就不会出现过多的往复情况。

2014-01-29 03:233584
用户头像

发布了 88 篇内容, 共 258.1 次阅读, 收获喜欢 7 次。

关注

评论

发布
暂无评论
发现更多内容

作业:架构实战营模块 8

Poplar89

「架构实战营」

Go 语言入门很简单:从 goroutine 出发到并发

宇宙之一粟

Go 语言 goroutine 2月月更

工作想法小计(3):2/21 - 2/25

非晓为骁

个人成长 工作

架构实战营 4 期第八模块作业

jialuooooo

架构实战营

「架构实战营」模块八《如何设计贴合业务的高性能高可用中间件系统》作业

DaiChen

作业 「架构实战营」 模块八

不能Hook的人生不值得 jsHook和模拟执行

奋飞安全

安全 js hook jshook

史上最强代码自测方法,没有之一!

万俊峰Kevin

微服务 单元测试 go-zero 测试工具 Go 语言

云原生训练营-Week02

jjn0703

云原生训练营

模块八作业

李晓笛

「架构实战营」

模块八作业-设计消息队列存储消息的MySQL表

CH

架构实战营 #架构实战营 「架构实战营」

Lyft微服务研发效能提升实践 | 3. 利用覆盖机制在预发环境中扩展服务网格

俞凡

研发效能 大厂实践 2月月更 lyft

【架构实战营】模块八:命题作业

wgl

「架构实战营」

[架构实战营]模块八 消息队列Mysql表格设计

Vincent

「架构实战营」

架构训练营模块八作业

沈益飞

架构训练营 架构师训练营 4 期

第八周作业

cqyanbo

日志管理系统,多种方式总结

架构 日志 slf4j logback

如何写好一个Java类?

蜜糖的代码注释

Java 整洁代码 2月月更

Meta启示:AI是通往元宇宙的关键变量

脑极体

模块八

Geek_59dec2

架构训练营模块八作业

zhongwy

消息队列基于Mysql存储表设计

tony

「架构实战营」

模块八 - 消息队列存储数据表结构设计

圈圈gor

架构实战营 「架构实战营」

EventBridge消息路由|高效构建消息路由能力

阿里巴巴云原生

阿里云 云原生 消息队列 EventBridge

架构实战营4期-模块八作业

木几丶

「架构实战营」

模块八作业

hunk

云原生训练营

编写 Kubernetes 部署脚本将 httpserver 部署到 Kubernetes 集群

tom

基于STM32+ESP8266+华为云IoT设计的智能门锁

DS小龙哥

2月月更

分享两个常见的搜索算法:BFS和DFS

华为云开发者联盟

算法 DFS 深度优先搜索 BFS 搜索算法

设计消息队列存储消息数据的 MySQL 表格

AUV

「架构实战营」

卫星商业价值的尽头,谁来善后?

脑极体

架构实战模块八作业

Anlumina

「架构实战营」

我们如何进行代码审查_语言 & 开发_张龙_InfoQ精选文章