Code Review 代码审查的调研报告

一、概述
代码审查(Code )是软件开发中常用的手段,和QA测试相比,它更容易发现和架构以及时序相关等较难发现的问题,还可以帮助团队成员提高编程技能,统一编程风格等,目前监控团队虽然提倡代码审查,也有相关的辅助工具,但是一直没有真正的推行起来,这半年的时间里,一些线上的bug如果经过代码审查,基本上可以避免的,大家也逐渐认识到代码审查可以有效地提高代码质量 。
二、代码审查的作用1、提高代码质量 。
通过代码审查来发现bug及代码中的不规范,这是不容置疑的,通过代码审查,代码将更加整洁,有更好的注释,更好的程序结构 。
2、提高开发者开发水平 。
开发者知道自己编写的代码会被同事审查,将会更加认真的编写代码,也将会督促开者不断地学习、向有经验的同事请教 。
3、提高程序的可维护性 。
一份程序代码将会有更多的同事熟悉,更好的代码质量,自然地也增加程序的可维护性 。
4、提高开发者的对编码的责任感 。
如果你在编程,而且知道将会有同事检查你的代码,你编程态度就完全不一样了 。你写出的代码将更加整洁,有更好的注释,更好的程序结构——因为你知道,那个你很在意的人将会查看你的程序 。没有代码审查,你知道人们最终还是会看你的程序 。但这种事情不是立即发生的事,它不会给你带来同等的紧迫感,它不会给你相同的个人评判的那种感受 。
5、传播知识
在很多的开发团队里,经常每一个人负责一个核心模块,每个人都只关注他自己的那个模块 。除非是同事的模块影响了自己的程序,他们从不相互交流 。这种情况的后果是,每个模块只有一个人熟悉里面的代码 。如果这个人休假或——但愿不是——辞职了,其他人则束手无策 。通过代码审查,至少会有两个人熟悉这些程序——作者,以及审查者 。审查者并不能像程序的作者一样对程序十分了解——但他会熟悉程序的设计和架构,这是极其重要的 。
三、代码审查的执行障碍1、缺少代码审查的标准
缺少代码审查的标准,往往审查人员习惯性地根据自身开发经验去进行代码审查,容易变成去挑毛病,找bug,容易产生不良地影响 。
2、资深开发人员的较少,工作过多,缺少代码审查的时间安排
在一个小规模团队里,资深的同事总是忙不过来,因为核心的工作都在等着他做,资深的开发人员少,代码审查的质量自然上不去 。
3、团队成员的技术差距过大
一个团队中往往有不少经验较浅的开发人员,当然编码水平也就相对较差,如果缺少有效的激励手段,往往资深的开发人员是比较讨厌经常去审查经验很浅的开发人员的代码 。
四、代码审查的实践要素 。
虽然代码审查是一个被广泛采纳的实践,但是由于存在很多的实践方式,所以开发团队经常搞不清楚它的最佳实践是什么样的,正确的代码审查应该重点考虑的几个因素有以下几点 。
1、人员结构
在你的团队中有多少同事拥有足够的专业技能来担当合格的代码审查者?作者曾经和多个开发团队沟通过,这些团队都声称本身只有一个资深的开发人员,如果让他来负责所有的代码审查工作,那么团队的核心开发就无法开展了 。作者也遇到过类似的情况 。在一个小规模团队里,资深的同事总是忙不过来,因为核心的工作都在等着他做 。
2、地理位置
你的团队成员是如何分布的?他们是否是分散在世界各地还是坐在同一个敞亮的办公室里? 代码审查需要精力的专注和反馈,如果开发人员能够面对面的沟通,那么审查工作会便于实施 。而物理隔离的远程团队很难达到代码审查的满意结果 。
3、所在领域
你所在的IT领域需要遵守怎样的规则和约束呢?如果你在一个受到严格监管的行业,那么你必须遵循有关审计和报告的规则,这意味着你必须想办法跟踪代码审查的频率和质量 。如果所在的领域把安全性作为重点,那么可能在代码审查过程中要引入安全审计 。
4、复杂性
你的代码复杂性如何?在代码审查时,需要多个不同专业技能的审查者吗?例如,游戏开发可能会引入非常复杂的业务逻辑来处理文字交互和场景跟踪,同时还需要特定的动画处理和内存管理技术 。在审查如此复杂的代码时,应该引入多个审查者从不同角度来检阅代码的质量 。
而且在许多情况下,不同的项目有不同的需求——存在多个团队构建应用,需要不同的配置文件 。这里有一些技巧可以帮助你改进代码审查过程的工具并解决一些可能会面临的问题:
A.促进沟通
任何审查过程,不论是代码还是文档还是绩效,最好是面对面进行 。在你使用工具做完代码审查之后,与相应的开发人员约个时间做口头的反馈 。如果你们不在同一地区,可以利用视频或者电话来进行沟通,但是这种沟通是必要的,你可以以此作为协作和指导的一种手段 。
B.利用专业技能
如果被审查的代码与其他代码领域存在关联,或者对安全、性能、可扩展性等方面存在一定的影响,你可能无法只安排一个人来完成审查工作 。你需要多个人来查看代码以确保所有可能的后果都被考虑在内 。在这种情况下,最好找到一个工具来协助多个人完成审查工作 。该工具的作用包括指定哪个人审查哪个角度并把相应的代码展现出来,而且还可以保存审查人员的注解 。
C. 公开审查意见
审查工具的优点之一是多人可以集中地审查相同的代码 。把所有人叫到一个屋子里做团队审查非常不利于大家考虑各个不同的方面 。但是工具可以帮助你让大家分别查看代码并把所有的意见集中起来:
五、代码审查的一些常用经验与注意事项 。1.代码审查要求团队有良好的文化
团队需要认识到代码审查是为了提高整个团队的能力,而不是针对个体设置的检查“关卡” 。
“A的代码有个bug被B发现,所以A能力不行,B能力更好”,这一类的陷阱很容易被扩散从而影响团队内部的协作,因此需要避免 。
另外,代码审查本身可以提高开发者的能力,让其从自身犯过的错误中学习,从他人的思路中学习 。如果开发者对这个流程有抵触或者反感,这个目的就达不到 。
2.谨慎的使用审查中问题的发现率作为考评标准
在代码审查中如果发现问题,对于问题的发现者来说这是好事,应该予以鼓励 。但对于被发现者,我们不主张使用这个方式予以惩罚 。软件开发中bug在所难免,过度苛求本身有悖常理 。更糟的是,如果造成参与者怕承担责任,不愿意在审查中指出问题,代码审查就没有任何的价值和意义 。
3.控制每次审查的代码数量
根据在思科所作的调查,每次审查200行-400行的代码效果最好 。每次试图审查的代码过多,发现问题的能力就会下降,
我们在实践中发现,随着开发平台和开发语言的不同,最优的代码审查量有所不同 。但是限制每次审查的数量确实非常必要,因为这个过程是高强度的脑力密集型活动 。时间一长,代码在审查者眼里只是字母,无任何逻辑联系,自然不会有太多的产出 。
4.带着问题去进行审查
我们在每次代码审查中,要求审查者利用自身的经验先思考可能会碰到的问题,然后通过审查工作验证这些问题是否已经解决 。一个窍门是,从用户可见的功能出发,假设一个比较复杂的使用场景,在代码阅读中验证这个使用场景是否能够正确工作 。
使用这个技巧,可以让审查者有代入感,真正的沉浸入代码中,提高效率 。大家都知道看武侠小说不容易瞌睡,而看专业书容易瞌睡,原因就是武侠小说更容易产生代入感 。
有的研究建议每次树立目标,控制单位时间内审核的代码数量 。这个方法在我们的实践中显得很机械和流程化,不如上面的方法效果好 。
5.所有的问题和修改,必须由原作者进行确认
如果在审查中发现问题,务必由原作者进行确认 。
这样做有两个目的:
(1)确认问题确实存在,保证问题被解决
(2)让原作者了解问题和不足,帮助其成长
有些时候为了追求效率,有经验的审查者更倾向于直接修改代码乃至重构所有代码,但这样不利于提高团队效率,并且会增加因为重构引入新bug的几率,通常情况下我们不予鼓励 。
6.利用代码审查激活个体 “能动性 "
即使项目进度比较紧张,无法完全的进行代码审查,至少也要进行部分代码的审查,此时随即抽取一些关键部分是个不错的办法 。
背后的逻辑是,软件开发是非常有创造性的工作,开发者都有强烈的自我驱动性和自我实现的要求 。让开发者知道他写的任何代码都可能被其他人阅读和审察,可以促使开发者集中注意力,尤其是避免将质量糟糕,乃至有低级错误的代码提交给同伴审查 。开源软件也很好的利用了这种心态来提高代码质量 。
7.在非正式,轻松的环境下进行代码审查
如前所述,代码审查是一个脑力密集型的工作 。参与者需要在比较轻松的环境下进行该工作 。因此,我们认为像某些实践中建议的那样,以会议的形式进行代码审查效果并不好,不仅因为长时间的会议容易让效率低下,更因为会议上可能出现的争议和思考不利于进行如此复杂的工作 。
8.提交代码前自我审查,添加对代码的说明
所有团队成员在提交代码给其他成员审查前,必须先进行一次审查 。这次自我修正形式的审查除了检查代码的正确性以外,还可以完成如下的工作:
(1)对代码添加注释,说明本次修改背后的原因,方便其他人进行审查 。
(2)修正编码风格,尤其是一些关键数据结构和方法的命名,提高代码的可读性 。
(3)从全局审视设计,是否完整的考虑了所有情景 。在实现之前做的设计如果存在考虑不周的情况,这个阶段可以很好的进行补救 。
我们在实践中发现,即使只有原作者进行代码审查,仍然可以很好的提高代码质量 。
9.实现中记录笔记可以很好的提高问题发现率
成员在编码的时候应做随手记录,包括在代码中用注释的方式表示,或者记录简单的个人文档,这样做有几个好处:
(1)避免遗漏 。在编码时将考虑到的任何问题都记录下来,在审查阶段再次检查这些问题都确认解决 。
(2)根据研究,每个人都习惯犯一些重复性的错误 。这类问题在编码是记录下来,可以在审查的时候用作检查的依据 。
(3)在反复记录笔记并在审查中发现类似的问题后,该类问题出现率会显著下降
10.使用好的工具进行轻量级的代码审查
比如利用进行代码扫描 。
六、实现代码审查的前提条件
(一)、审查制度的执行前提
1、代码审查必须是基本制度,是工作中一部分 。
2、在团队中需要有一份大家接受的代码规范文档 。
3、与业务需求相关的代码修改,需要审查代码的同事熟悉业务需求,参与设计评审,不熟悉需求是不能有效地审查代码 。
4、代码审查是工作中的一部分,需要安排一定的时间来进行,这需要领导在工作安排中合理安排时间 。
(二)、代码审查的执行前提
1、Code 人员是否理解了Code 的概念和Code 将做什么
如果做Code 的人员不能理解Code 对项目成败和代码质量的重要程度,他们的做法可能就会是应付了事 。
2、代码是否已经正确的build,build的目的使得代码已经不存在基本语法错误
我们总不希望高级开发人员或是主管将时间浪费在检查连编译都通不过的代码上吧 。
3、代码执行时功能是否正确
Code 人员也不负责检查代码的功能是否正确,也就是说,需要复查的代码必须由开发人员或质量人员负责该代码的功能的正确性 。
4、人员是否理解了代码
做复查的人员需要对该代码有一个基本的了解,其功能是什么,是拿一方面的代码,涉及到数据库或是通讯,这样才能采取针对性的检查
5、开发人员是否对代码做了单元测试
这一点也是为了保证Code 前一些语法和功能问题已经得到解决,Code 人员可以将精力集中在代码的质量上 。
七、代码审查需要做什么
Code 主要检查代码中是否存在以下方面问题:
代码的一致性、编码风格、代码的安全问题、代码冗余、是否正确设计以满足需求(性能、功能)等等
1完整性检查
代码是否完全实现了设计文档中提出的功能需求
代码是否已按照设计文档进行了集成和Debug
代码是否已创建了需要的数据库,包括正确的初始化数据
代码中是否存在任何没有定义或没有引用到的变量、常数或数据类型
2 一致性检查
代码的逻辑是否符合设计文档
代码中使用的格式、符号、结构等风格是否保持一致
3 正确性检查
代码是否符合制定的标准
所有的变量都被正确定义和使用
所有的注释都是准确的
所有的程序调用都使用了正确的参数个数
4 可修改性检查
代码涉及到的常量是否易于修改(如使用配置、定义为类常量、使用专门的常量类等)
代码中是否包含了交叉说明或数据字典,以描述程序是如何对变量和常量进行访问的
代码是否只有一个出口和一个入口(严重的异常处理除外)
5 可预测性检查
代码所用的开发语言是否具有定义良好的语法和语义
是否代码避免了依赖于开发语言缺省提供的功能
代码是否无意中陷入了死循环
代码是否是否避免了无穷递归
6 健壮性检查
代码是否采取措施避免运行时错误(如数组边界溢出、被零除、值越界、堆栈溢出等)
7 结构性检查
程序的每个功能是否都作为一个可辩识的代码块存在
循环是否只有一个入口
8 可追溯性检查
代码是否对每个程序进行了唯一标识
是否有一个交叉引用的框架可以用来在代码和开发文档之间相互对应
代码是否包括一个修订历史记录,记录中对代码的修改和原因都有记录
是否所有的安全功能都有标识
9 可理解性检查
注释是否足够清晰的描述每个子程序
是否使用到不明确或不必要的复杂代码,它们是否被清楚的注释
使用一些统一的格式化技巧(如缩进、空白等)用来增强代码的清晰度
是否在定义命名规则时采用了便于记忆,反映类型等方法
每个变量都定义了合法的取值范围
代码中的算法是否符合开发文档中描述的数学模型
10可验证性检查
代码中的实现技术是否便于测试
八、代码审查的流程 。
1、在开发之前就需要确认谁来进行代码审查,单个还是多个审查人,确定代码审查的方式( board,面谈讨论沟通) 。
2、确定好审查人后需要让相应的审查人员参与熟悉开发的功能需求(业务需求、性能需求)是什么,以便让审查人知道需要审查的代码实现的功能包含那些要点,在实际的工作中以需求讨论、设计评审来完成审查人员对需求与设计的熟悉 。
【Code Review代码审查的调研报告】3、开发完成后提交到 board中通知代码审查人进行代码审查,代码审查人如果发现有需要代码中有需要修改的地方,在 board中写下原因反馈给开发人员,开发人员按要求进行代码修改后再度提交到 board,继续进行代码审查,直至审查通过 。