一文带你看懂:如何进行一次高质量CR?

news2024/11/15 5:10:37

程序员对代码评审(Code Review)不可谓不熟悉,而代码评审也已经是许多组织的标准化实践。结合笔者的五年多的开发经验,既有经历过零CR的小组织,也有接触过完善CR规范的大厂团队。

对于“如何进行一次--高质量的组内代码CR”,结合最近和同事的讨论交流,包括我本人也有一些实践,在此跟大家一起分享下心得和体会。

1ff9d0b333c99936e819675b3d156f52.png

我经历过怎么样的代码CR

我想起在2018年加入的一个小作坊团队,组内的后台开发一共才6个人(包括2个实习生),全部属于一个leader和一个骨干带飞所有人的情况。彼时,项目进度非常紧,几乎每个周6都要加班,我们用的代码托管工具还是SVN。当时最普遍的CR情况是:每个人提交代码时,都要口头通知一声leader,让技术负责人来过目一遍代码,并针对不合理的逻辑进行“友好的交流”。

02da0ebfda8125ef147d3fc9cec4c041.png

2019年加入了一个更大点的团队(后台组有30个人),每个业务线都有小leader进行分管。彼时,开发内部用上了GitLab的私有化部署,工作节奏是周期性忙碌。当时最普遍的CR情况是:每个人可以直接合入代码到开发分支,同时每2周要对自己的代码进行一次线下的CR,邀请小leader和同事一起加入讨论。

7b56579648dc5d3feecba894843a5a67.png

2021年来了腾讯之后,才明白过去的组内CR在工具和维度上,都太过于“刀耕火种”了,并发现周围很多同事,都把性能和代码最佳实践挂在嘴边;在BG甚至部门级别,腾讯都养了一批专业搞研效的大佬在研究代码质量(我还好几次听过Google的专家讲“如何提交一次Commit”);而后经历“降本增效”大流行的阶段,在面临个人职业生涯存亡之际,内部的提CR的声浪肉眼可见的慢慢降低了。

此时,最普遍的CR情况是:需求评估(会议:研发+产品)->方案评估(会议:研发)->开发质量评估(会议:开发+测试)->上线评估(会议:研发+DBA+测试+产品)->功能验收(会议:产品)。

f1552a6dd9eeed3668c7857e0d5c061c.jpeg

是的,这时候的CR更像是泛CR的概念,代码合入并不是一次CR的终点。同时,每个环节都有专门的平台工具来监控进度(eg,需求管理平台、代码管理平台、缺陷管理平台、流水线发布平台等),也算是把流程化做到极致了。

b687479374f6c8593cac895e21dfbb05.png

如何进行一次高质量的组内CR?

上面提到了3种类型公司的CR环境:有小作坊开发模式,有中型团队的敏捷开发协作,也有大厂标准化流程。

那么,是不是说一定是大厂标准化流程就是最好的呢?

我觉得非也;大公司固然有标准化,但标准化也意味着会逐渐形成一种“政治正确”,如果遇到工期紧的时候(相信我,大业务团队迫切需要的不是严丝合缝的CR,是高效发布以变现的时间),这种标准化过程到最后就是走个过场而已。

那么,是不是说小作坊就不具备进行CR的土壤环境?

我觉得未必,因为技术是相通的,需求是类似的,只是实现不同罢了,同时CR是个向组内同事学习的好机会。

94f78263bd86a7e1233aa228e9fe20e8.png

f5c80369ffe79895ed91a506a8e94129.png

关于CR:5W1H

c2d04fbb492758abcd101b9e9830b475.png

  • 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性能。

c7fe30deaf99bdb78f954b340e52b8cc.png

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条:谨慎的使用本地方法

b1f787350530571d014a3e5d2cb66f30.png

代码性能

真实的基础设施是非常多元复杂的,我们往往需要一个可观测性整体的标准定义。这就引入了一个概念:应用性能观测。

应用性能观测(Application Performance Monitoring),通常简写为APM。我们很难找到一个官方的定义去描述什么是一个应用性能观测软件。但在分布式微服务盛行于后台的今天,在这个领域里应用性能观测通常指用来观测系统的可用性,链路追踪、接口耗时、关键指标等信息的组件。

6d0bd621860b3e27cddd302a151f8e1b.png

  • Trace:分布式链路追踪,记录一个请求从接受到完成全生命周期的路径。它一定伴随着某种可以被整个生命周期一直绑定的标记。

  • Metrics: 关键指标,就如同Prometheus上的Counter, Gauge,Histogram等一样,一定要可以在不同维度特定条件被聚合。

  • Logs: 日志,标记离散事件的记录。比如从MQ消费到一条消息,读取db失败等。

总结:通过完善应用层面的trace,metrics,logs三个父母,即可实现分布式应用的可观测性指标记录。实际上,也确实有很多非常优秀的开源组件给我们使用了,比如:ELK、SkyWalking等,如果你公司的应用是部署在腾讯云或者阿里云,更可以直接使用腾讯云APM和阿里云ARMS。

代码安全

安全类问题往往隐藏在缺乏安全意识的编码逻辑和未经检测或维护的开源依赖组件中,难以在日常开发和代码评审中被及时察觉。

而互联网大厂往往内部会有专门部门来负责代码安全扫描;也有开源的安全规范,比如腾讯语言安全规范:https://github.com/Tencent/secguide

a31a3ec821bd8b9900a7111fb94a95c5.png

代码合规

我们编写的“源代码”是公司的核心竞争力以及核心财产之一,其商业价值及对公司的意义不言而喻。因此如何合规地使用源代码对公司、对个人都尤为重要。

在法律上,源代码属于计算机软件作品一部分,可受著作权法保护。同时代码作为商业秘密,受反不正当竞争法保护。源代码的泄露或不规范使用,可能会给相关业务及整个公司带来损失,同时相关个人可能也会涉嫌触发公司高压线面临公司相应处罚,甚至承担相应法律责任。

c45a9594c5e3a4995b6811a55facac6f.jpeg

另外,使用开源组件势必引入未知漏洞风险,比如2021年在安全圈里堪称核爆级事件的Log4j漏洞。

44e940dcebdd801a2e53346a198182ed.png

我接触过的几款代码合规检测软件分别是国外的Black Duck(黑鸭),国内的清源(CleanSource) SCA。

  • 工具供应商 Black Duck(黑鸭)二进制分析是一款软件组成分析(SCA)解决方案,可帮助您管理与复杂的现代软件供应链相关的持续风险。

  • 势提供的 CleanSource (清源) SCA 是一款综合的软件成分分析解决方案, 旨在帮助企业降低和管理其应用或容器中因使用开源软件和其他第三方代码(软件)引入的安全、质量与许可证合规性风险。

CR度量

代码评审活动开展程度需要量化数据做参考,腾讯代码管理平台提供了代码评审开展的原始数据,然后按需做进一步分析。其中,最重要的就是代码评审指标体系建立。

代码评审指标体系构建思路

d998073d6f111afaf1c0520a28e6fcf2.jpeg

细指标描述:

39439e99672ed50aaaa6514d8f023e98.jpeg

0f6a319634fd3d2f038b71ad06659a5f.jpeg

参考文章:

  • https://juejin.cn/post/6844903760444014600

  • h

    ttps://www.163.com/dy/article/HCIQNMEM055319KQ.html

  • https://developer.aliyun.com/article/763213

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/372525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣-销售员

大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:607. 销售员二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言 …

【测试】自动化测试03(JUnit)

努力经营当下,直至未来明朗! 文章目录JUnit一) 注解1. Test2. BeforeEach3. BeforeAll4. AfterEach5. AfterAll二) 断言(Assertions类)三)用例的执行顺序四)参数化五)测试…

Qt windeployqt.exe 打包qml

Qt系列文章目录 文章目录Qt系列文章目录前言一、遇到的坑二、参考前言 我们在QtCreator下面开发程序,一般都会遇到工程发布给客户使用的情况。我们通常会使用Qt自带的打包工具:windeployqt.exe。 windeployqt.exe是Qt自带的工具,用于创建应用…

使用windwow windbg 吃透64位分页内存管理

前言 分页基础概念是操作系统基础知识,网上已经有太多太多了。所以本文记录使用windwow内核调试工具验证理论知识。 具体可以参阅intel volume3的 4.1.1 Four Paging Modes章节。 简而言之:CR0.PG 0表示不开启分页.并且根据CR4各种标志开启不同类别的…

力扣-变更性别

大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:627. 变更性别二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言…

算法设计与分析期末考试复习(三)

动态规划 动态规划算法与分治法类似,其基本思想也是将待求解问题分成若干个子问题。但是经分解得到的子问题往往不是互相独立的。在用分治法求解时,有些子问题被重复计算机了许多次。 如果能够保存已解决的子问题的答案,而在需要时再找出已求…

Scala-抽象类、匿名子类、伴生对象、单例模式

抽象类 匿名子类 伴生对象(单例对象) 单例设计模式 抽象类 定义抽象类:abstract class Person{} //通过 abstract 关键字标记抽象类定义抽象属性:val|var name:String //一个属性没有初始化,就是抽象属性定义抽象…

应用场景六:同时支持CP343和CP341功能(Modbus连接仪表,以太网连接WINCC)

应用描述: 桥接器同时支持西门子PLC的CP343以太网通讯模块和CP341串口通讯模块的功能。可以同时通过ModbusRTU连接仪表、变频器等串口设备,同时可以通过网口连接组态监控软件WINCC。PLC内部不需要编程,也不需要进行硬件组态配置,…

FME+YOLOV7写DNF自动刷图脚本

目录 前言 一、难点分析 二、实现流程 1.DNF窗口位置获取 2.获取训练数据 3.数据标注 4.数据格式转换 5.数据训练 5.刷图逻辑编写 前言 这是一篇不务正业的研究,首先说明,这不是外挂!这不是外挂!这不是外挂!这只是用a…

【网络原理10】构造HTTP请求、HTTPS加密

目录 一、构造HTTP请求 ①使用form表单构造HTTP请求: form表单是如何提交的 form提交的缺点 ②基于ajax构造http请求 如何使用Jquery框架 二、HTTPS 运营商劫持 HTTP的加密版本:HTTPS ①对称加密:客户端和服务端使用同一把密钥&…

【AcWing】差分及其应用

&#x1f386;音乐分享 光辉岁月 (粤语版)_BEYOND 所谓差分&#xff0c;就是前缀和的逆运算 &#xff08;不懂前缀和的同学可以去C站看一下&#x1f602;&#xff09; 797. 差分 - AcWing题库 代码 #include<iostream> using namespace std; const int N 1e5 10…

怎样选择运动耳机、5款最佳运动蓝牙耳机推荐

你是否在跑步时大幅度抖动让耳机松落&#xff0c;不得不一遍又一遍的塞紧耳机&#xff1f;你是否在游泳时因为耳机进水而懊恼自己大意&#xff1f;没错&#xff0c;在运动过程中这些情况我都有遇到过&#xff01;运动耳机因其使用都是在跑步、游泳、骑行、徒步等场景&#xff0…

Apache Hadoop生态部署-Maxwell(实时数据同步)采集节点安装

目录 Apache Hadoop生态-目录汇总-持续更新 1&#xff1a;安装包准备 2&#xff1a;MySQL 环境准备 2.1&#xff1a;开启MySQL Binlog 2.2&#xff1a;验证mysql配置是否正确 2.3&#xff1a;初始化Maxwell元数据库,分配账号 3&#xff1a;安装 4&#xff1a;测试 Apach…

【开发规范】go项目开发中的[流程,git,代码,目录,微服务仓库管理,静态检查]

文章目录前言一、有哪些规范我们应该遵循二、项目开发流程三、git的代码分支管理1. 分支管理2. commit规范三、go的代码规范四、go项目目录规范五、微服务该采用multi-repo还是mono-repo&#xff1f;1. 引言2. Repos 是什么?3. 什么是 Mono-repo?4. Mono-repo 的劣势5. 什么是…

1、算法导论---时间复杂度、确定性和非确定性图灵机、算法的确定性与非确定性、P问题、NP问题、规约/约化、NPC问题、NP-hard问题

算法导论1、 时间复杂度2、图灵机3、算法的确定性与非确定性4、P问题5、NP问题6、规约/约化7、NPC问题8、NP-Hard问题9、四大问题关系1、 时间复杂度 要想了解算法的问题&#xff0c;首先要知道问题的分类&#xff0c;而要想知道问题的分类&#xff0c;就要先了解时间复杂度。…

_vue-2

v-model实现原理 我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定&#xff0c;我们知道 v-model 本质上不过是语法糖&#xff08;可以看成是value input方法的语法糖&#xff09;&#xff0c;v-model 在内部为不同的输入元素…

什么是原型、原型链?原型和原型链的作用

1、ES6之前&#xff0c;继承都用构造函数来实现&#xff1b;对象的继承,先申明一个对象&#xff0c;里面添加实例成员<!DOCTYPE html> <html><head><meta charset"utf-8" /><title></title></head><body><script…

Ubuntu(虚拟机)的Anaconda 及使用

安装Anaconda 使用firefox打开Ananconda网址Anaconda | The Worlds Most Popular Data Science Platform 下载后有.sh文件&#xff1a; Anaconda3-2022.10-Linux-x86_64.sh 进入所在目录打开终端并输入 $ bash Anaconda3-2022.10-Linux-x86_64.sh 然后开始安装。 对于给…

SAP MM学习笔记1-SAP中扩张的概念,如何将一个物料从工厂A扩张到工厂B

MM中在创建物料的时候&#xff0c;最低也得创建如下5个view。 基本数据1 基本数据2 购买管理 会计1 会计2 1&#xff0c;扩张是什么 有时候&#xff0c;你想增加其他的View&#xff0c;比如保管场所 等&#xff0c;你不能用MM02来做编辑&#xff0c;要用MM01来做扩张。这就是扩…

OSPF的多区域特性 (电子科技大学TCP/IP实验三)

一&#xff0e;实验目的 1、掌握OSPF 协议中区域的类型、特征和作用 2、掌握OSPF 路由器的类型、特征和作用 3、掌握OSPF LSA 分组的类型、特征和作用 4、理解OSPF 区域类型、路由器类型和OSPF LSA 分组类型间的相互关系 二&#xff0e;预备知识 1、静态路由选择和动态路…