程序员对代码评审(Code Review)不可谓不熟悉,而代码评审也已经是许多组织的标准化实践。结合笔者的五年多的开发经验,既有经历过零CR的小组织,也有接触过完善CR规范的大厂团队。
对于“如何进行一次--高质量的组内代码CR”,结合最近和同事的讨论交流,包括我本人也有一些实践,在此跟大家一起分享下心得和体会。
我经历过怎么样的代码CR
我想起在2018年加入的一个小作坊团队,组内的后台开发一共才6个人(包括2个实习生),全部属于一个leader和一个骨干带飞所有人的情况。彼时,项目进度非常紧,几乎每个周6都要加班,我们用的代码托管工具还是SVN。当时最普遍的CR情况是:每个人提交代码时,都要口头通知一声leader,让技术负责人来过目一遍代码,并针对不合理的逻辑进行“友好的交流”。
2019年加入了一个更大点的团队(后台组有30个人),每个业务线都有小leader进行分管。彼时,开发内部用上了GitLab的私有化部署,工作节奏是周期性忙碌。当时最普遍的CR情况是:每个人可以直接合入代码到开发分支,同时每2周要对自己的代码进行一次线下的CR,邀请小leader和同事一起加入讨论。
2021年来了腾讯之后,才明白过去的组内CR在工具和维度上,都太过于“刀耕火种”了,并发现周围很多同事,都把性能和代码最佳实践挂在嘴边;在BG甚至部门级别,腾讯都养了一批专业搞研效的大佬在研究代码质量(我还好几次听过Google的专家讲“如何提交一次Commit”);而后经历“降本增效”大流行的阶段,在面临个人职业生涯存亡之际,内部的提CR的声浪肉眼可见的慢慢降低了。
此时,最普遍的CR情况是:需求评估(会议:研发+产品)->方案评估(会议:研发)->开发质量评估(会议:开发+测试)->上线评估(会议:研发+DBA+测试+产品)->功能验收(会议:产品)。
是的,这时候的CR更像是泛CR的概念,代码合入并不是一次CR的终点。同时,每个环节都有专门的平台工具来监控进度(eg,需求管理平台、代码管理平台、缺陷管理平台、流水线发布平台等),也算是把流程化做到极致了。
如何进行一次高质量的组内CR?
上面提到了3种类型公司的CR环境:有小作坊开发模式,有中型团队的敏捷开发协作,也有大厂标准化流程。
那么,是不是说一定是大厂标准化流程就是最好的呢?
我觉得非也;大公司固然有标准化,但标准化也意味着会逐渐形成一种“政治正确”,如果遇到工期紧的时候(相信我,大业务团队迫切需要的不是严丝合缝的CR,是高效发布以变现的时间),这种标准化过程到最后就是走个过场而已。
那么,是不是说小作坊就不具备进行CR的土壤环境?
我觉得未必,因为技术是相通的,需求是类似的,只是实现不同罢了,同时CR是个向组内同事学习的好机会。
关于CR:5W1H
What:CR是结对编程相互切磋相互学习的方式。
W
hen:结合DevOps流程,我们的组内CR最好发生在DevOps的前四个阶段(需求->研发-
>测试->发布),CR时间点越靠,此时的风险是能够控制在最低影响范围的。
Where:一个线上腾讯会议,一个线下会议室,都可以聚集起一拨人。
W
ho:按角色划分为:主讲人、评审人、记录者。
Why:提升代码质量、促进人才成长、培养技术情怀。。(格局大了)
How:CR前期准备 + CR中期讨论 + CR后期改进
CR前期准备
外部代码规范性检测:idea的阿里巴巴 Java 规约检测插件,自动发现不符合代码规范的代码并给出修复建议。(这可以让我们提前发现并解决这类小毛病,毕竟一大堆人讨论缩进还是空格,是非常浪费时间口舌的...)
内部自动化检测工具链:主要是复用公司内部安全平台等部门的成果,通过共建代码质量红线,完成对安全、规范等多方面的问题检测。(商业化部门非常重视代码开源,以及安全规范的问题,涉及到业务出海的就更加要规避代码风险了..)
个人CR预演:对产品需求文档,提炼出最多3个功能点(考虑初衷有2个,一个是尽量小的粒度评审;另外一个是作为后面代码走读的切入口),先自己走读一遍代码(以评审人角度评估一下改进空间)。基本上,有了一次自己的CR预演,后续真正讨论时,就不会出现“CR断片”和胡言乱语了..
CR中期讨论
CR工具
:
因为腾讯内部有专门的代码托管工具-工蜂,所以无论线上还是线下的代码CR,几乎离不开这个工具(拥有定制化的CR工具,是相当幸运的事情;因为我了解过其他公司等,除了阿里巴巴以外,很多大厂都是用的GitLab商业版本地部署,甚至花大钱买了国外的成熟软件来用)。
可行性评估:架构师、运维和DBA,会对SQL脚本(包括ES索引变动、DB表结构变动等中间件操作)进行风险评估。这也是判断一个开发者技术底蕴的一个过程,毕竟后台开发可不仅仅是写if..else..,还要对整个架构系统负责。
代码走读:作为开发者,讲解这次功能点:脚本、接口、风险预防。
问题记录:载体多种,主要记录:业务背景、脚本or接口的执行风险。(人多口杂,架构师和DBA也有互相battle的情况,我们最好做好记录,比对之后再选择风险低的、好实现的方案)
上线评估:如果有出现功能漏实现、测试对质量的质疑、产品对设计的质疑等,往往会面临延期上线。
CR后期改进
代码合并:确定了功能上线日期,我们得合入代码了,或许合入分支时还有代码冲突的情况。
灰度监控:代码发布了,功能进入灰度环境,当有流量打入时,我们要验证下数据准确性、接口性能、SQL性能。
CR的“长寿”秘诀
还是那句话,我们得有真本事,才能厚积薄发。自己写代码多了,其实也就很懂自己,哪些地方容易被别人挑刺了。
下面我就从五个方面(代码规范、代码性能、代码安全、代码合规、CR度量)说明下,有这些途径可以让CR变得更好。
代码规范
Java规范文档:https://github.com/alibaba/p3c
Java代码最佳实践(可以参考我的《Effective-java》知识点总结)
winter
一文读懂《Effective Java》第3条:用私有构造器或者枚举类型强化Singleton属性
一文读懂《Effective Java》第4条:通过私有构造器来强化工具类不可实例化的能力
一文读懂《Effective Java》第5条:避免创建不必要的对象 & 性能优化
一文读懂《Effective Java》第6条:消除GC触及不到的过期对象引用
一文读懂《Effective Java》第7条:避免使用终结方法
一文读懂《Effective Java》第19条:接口只用于定义类型
一文读懂《Effective Java》第20条:类层次优于标签类
一文读懂《Effective Java》第23条:不要在新代码中使用原生态类型
一文读懂《Effective Java》第24条:合理使用@SuppressWarining消除非受检警告
一文读懂《Effective Java》第41条:慎用重载
一文读懂《Effective Java》第42条:慎用可变参数
一文读懂《Effective Java》第43条:返回零长度的数组或集合,而不是null
一文读懂《Effective Java》第48条:如果需要精确答案,请避免使用float和double
一文读懂《Effective Java》第52条:通过接口引用对象
一文读懂《Effective Java》第53条:接口优先于反射机制
一文读懂《Effective Java》第54条:谨慎的使用本地方法
代码性能
真实的基础设施是非常多元复杂的,我们往往需要一个可观测性整体的标准定义。这就引入了一个概念:应用性能观测。
应用性能观测(Application Performance Monitoring),通常简写为APM。我们很难找到一个官方的定义去描述什么是一个应用性能观测软件。但在分布式微服务盛行于后台的今天,在这个领域里应用性能观测通常指用来观测系统的可用性,链路追踪、接口耗时、关键指标等信息的组件。
Trace:分布式链路追踪,记录一个请求从接受到完成全生命周期的路径。它一定伴随着某种可以被整个生命周期一直绑定的标记。
Metrics: 关键指标,就如同Prometheus上的Counter, Gauge,Histogram等一样,一定要可以在不同维度特定条件被聚合。
Logs: 日志,标记离散事件的记录。比如从MQ消费到一条消息,读取db失败等。
总结:通过完善应用层面的trace,metrics,logs三个父母,即可实现分布式应用的可观测性指标记录。实际上,也确实有很多非常优秀的开源组件给我们使用了,比如:ELK、SkyWalking等,如果你公司的应用是部署在腾讯云或者阿里云,更可以直接使用腾讯云APM和阿里云ARMS。
代码安全
安全类问题往往隐藏在缺乏安全意识的编码逻辑和未经检测或维护的开源依赖组件中,难以在日常开发和代码评审中被及时察觉。
而互联网大厂往往内部会有专门部门来负责代码安全扫描;也有开源的安全规范,比如腾讯语言安全规范:https://github.com/Tencent/secguide
代码合规
我们编写的“源代码”是公司的核心竞争力以及核心财产之一,其商业价值及对公司的意义不言而喻。因此如何合规地使用源代码对公司、对个人都尤为重要。
在法律上,源代码属于计算机软件作品一部分,可受著作权法保护。同时代码作为商业秘密,受反不正当竞争法保护。源代码的泄露或不规范使用,可能会给相关业务及整个公司带来损失,同时相关个人可能也会涉嫌触发公司高压线面临公司相应处罚,甚至承担相应法律责任。
另外,使用开源组件势必引入未知漏洞风险,比如2021年在安全圈里堪称核爆级事件的Log4j漏洞。
我接触过的几款代码合规检测软件分别是国外的Black Duck(黑鸭),国内的清源(CleanSource) SCA。
工具供应商 Black Duck(黑鸭)二进制分析是一款软件组成分析(SCA)解决方案,可帮助您管理与复杂的现代软件供应链相关的持续风险。
安
势提供的 CleanSource (清源) SCA 是一款综合的软件成分分析解决方案, 旨在帮助企业降低和管理其应用或容器中因使用开源软件和其他第三方代码(软件)引入的安全、质量与许可证合规性风险。
CR度量
代码评审活动开展程度需要量化数据做参考,腾讯代码管理平台提供了代码评审开展的原始数据,然后按需做进一步分析。其中,最重要的就是代码评审指标体系建立。
代码评审指标体系构建思路
详细指标描述:
参考文章:
https://juejin.cn/post/6844903760444014600
h
ttps://www.163.com/dy/article/HCIQNMEM055319KQ.html
https://developer.aliyun.com/article/763213