如何进行正确的 CodeReview

news2025/4/9 18:42:22

软件开发生命周期中至关重要的一步是代码审查。它使开发人员能够显著提升代码质量。它类似于书籍的创作过程。首先,作者写故事,然后经过编辑以确保不会出现诸如混淆“you’re”和“yours”之类的错误。在这个语境中,代码审查指的是检查和评估他人的代码。它基于拉取请求模型,这个模型在开源项目中广受欢迎。

代码审查有不同的好处:

确保设计和实现的一致性,•优化代码以提升性能,•是学习的机会,•知识分享和指导,以及促进团队凝聚力。

代码审查中需要检查的内容

代码审查有不同的好处:

在代码审查中应该查找什么?有许多不同的事项需要检查,从重要性的不同层次自动化的可能性来看:

尝试查找以下内容:

1.功能性和设计 — 这里,我们需要找到答案,比如:这个更改是否遵循我们期望的架构,或者它是否与系统的其他部分集成良好?它的组件之间是否具有高内聚性和低耦合性?它是否遵循了如OO、SOLID、DRY、KISS、YAGNI等健壮的原则?2.实现 — 在这里,我们检查解决方案是否在逻辑上正确(它确实改变了开发人员的意图),如果代码比应有的复杂,等等。这段代码是否必要?我们还要检查是否使用了良好的设计模式。以及关键的内容,例如API入口点。3.测试 — 在这里,我们检查是否所有测试都通过了,我们是否对所有代码路径和行为使用单元测试,并对外部系统(数据库、文件系统等)使用集成测试。我们是否检查了所有边界条件和代码覆盖率在60-80%之间?4.文档 — 我们的PR描述添加了吗?我们的解决方案在存储库的README.md或其他地方是否有文档更新?5.代码风格 — 我们是否遵循了项目的代码风格?您是否知道命名是否良好?开发人员是否为类、方法等选择了确切的名称?代码是否易读?

f61f818808c2167c68734f700f96f144.png
1*pRrZW9PzCcRTWgDuWYOaUQ.png

代码审查金字塔(基于Gunnar Morling的原始作品)

进行代码审查的一些良好实践

以下是进行代码审查时的一些良好实践:

1.尝试首先审查您自己的代码

在将代码发送给同事之前,尝试先阅读和理解它。寻找让您困惑的部分。在IDE之外查看您的代码通常有助于将其视为“新”的东西,从而避免操作性盲点

1.编写更改的简短描述

这应该以高层次解释更改内容以及为何进行这些更改的方式来解释。

1.自动化可以自动化的部分

将所有可以自动化的工作留给系统,例如检查成功构建(CI)、样式更改(代码检查器)、自动化测试和静态代码分析(例如使用SonarQube)。我们已将其集成在PR级别,因此它将在每个PR上运行并为代码合并提供阻碍。这将使我们能够消除不必要的讨论,为更重要的讨论留出空间。

1.为更大的任务与团队成员进行启动会议

如果您开始处理更大的任务,特别是在设计方面,请尝试首先与代码所有者或将成为您的代码审查者的人进行启动会议。这将在实施之前达成共识,并减少在PR审查阶段的工作量,避免出现意外情况。

1.不要着急

您需要了解其周围发生了什么 — 每一行代码。如果需要,逐类多次阅读。应该查看分配给审查的每一行代码。有些代码需要更多的思考,有些则需要更少,但这是我们在审查过程中必须做出的决定。如果需要,为口头讨论保持自己的时间。

1.友善地评论

永远不要提及个人(您),始终将注意力集中在更改上,以问题或建议的形式提出,并留下至少一个积极的评论。用您的话解释“为什么”,并建议如何改进。

1.在足够好时批准PR

不要追求完美,但要保持高标准。不要小题大做。

1.控制审查的规模

我们应该限制一次审查的代码行数。PR应该包含尽可能少的更改文件。我更喜欢更小的增量更改而不是重大的更改。我们的大脑无法一次处理那么多信息。每次审查的核心行数的理想数量是200到400行,通常是60到90分钟。如果任务庞大,请将其细分为可以快速审查的较小子任务。

df4f303abf195fd8b9af72f6c953bca0.png
1*mNzibJnKgyYZcI4SyqkjQw.png

1.使用工具

对于所有代码审查,您应该使用一些工具,例如BitBucket、Azure DevOps、GitHub或GitLab。例如,Microsoft多年来一直使用名为CodeFlow的内部工具,它支持开发人员并指导他们完成所有代码审查步骤。它在代码准备阶段有所帮助,自动通知审阅者,并具有丰富的评论和讨论功能。在后来的几年里,他们转向了GitHub拉取请求。Google也在代码审查方面使用两种解决方案。他们使用Gerrit代码审查工具进行开源代码审查,但在内部代码方面,他们使用名为Critique的内部工具。

代码审查的更好替代方案

除了传统的PR审查之外,还有另一种模型可以帮助您在编码过程中获得更高的效率和速度。它基于一种不同于拉取请求的模型,称为基于主干的开发。在这里,您同步进行代码审查。通过这种方式,所有开发人员都在主线分支上工作,频繁提交更改。这种做法的一个例子是协作编程方法(配对编程和集体编程),是由Kent Beck在90年代作为极限编程技术引入的。

d8e9e9cb48d3a543d6fbb8f0ca319956.jpeg
Image.jpeg

配对编程(来源:Unsplash)

配对编程和集体编程是协作编程方法,涉及两个或多个开发人员共同处理单个任务,共享编写代码时的想法和思路。在这里,一个开发人员充当驱动者(编写代码)的角色,而另一个则充当导航者的角色(确保代码准确性)。在过程中他们会定期交换位置

与传统代码审查相比,这些方法提供了多种好处

实时反馈:配对编程和集体编程使开发人员能够即时获得有关其代码的反馈,从而能够解决问题并改进。这与传统的代码审查不同,后者可能要等到代码审查阶段才会收到反馈。•增强的知识共享:协作编程使开发人员能够从彼此的经验和知识中学习,从而带来更好的代码和技能发展。这在使用新技术或面对新手时特别有用。此外,学习更容易在团队成员之间传播,降低了单个开发人员成为瓶颈的风险。•更快的问题解决鼓励开发人员共同解决问题,从而获得更快、更高效的解决方案。这可以减少开发时间并改善项目结果。•增强的关注和生产力:与另一位开发人员密切合作可以帮助保持专注并减少分心。•提高代码质量:当多个开发人员共同合作时,他们更有可能在开发早期发现错误和设计问题,进而提高代码质量。

这种方法在拥有大部分资深开发人员的团队,必须快速迭代的情况下效果最佳。然而,如果团队主要由初级开发人员组成,或者产品较为复杂需要多人审核代码时,Pull Request 模型更为适用。

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

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

相关文章

云原生架构体系和重点概念解读

【摘要】大部分人对云原生的认识仅限于容器、微服务、DevOps等内容,把容器、微服务、 DevOps就等同于云原生,这显然是不对的。本文梳理了云原生架构体系内容并对重点概念进行了解读,希望对读者有所帮助。 云原生(Cloud-Native&am…

八股文学习日常第一期(20240121)

零、前言 1、目的 帮助掌握面试题,就八股文相关内容展开进行学习和整理,也方便之后的复习和巩固。 2、八股文内容来源 ①https://blog.csdn.net/w20001118/article/details/125724647 一、具体内容分析 1、类的完整书写方式 1.1、类 [Access Mod…

java面试题——多线程01

1.java中线程的实现方式? 常见的一般是4种: 继承Thread类实现Runnable接口通过callable接口,实现有返回值的线程基于线程池的实现 虽说有四种,但究其根本,其实都是实现的Runnable接口 2.java中线程的状态?…

机器学习周报第29周

目录 摘要Abstract一、文献阅读1.论文标题2.论文摘要3.论文背景4.论文方案4.1 多视角自注意力网络4.2 距离感知4.3 方向信息4.4 短语模式 二、self-attention 摘要 本周学习了多视角自注意力网络,在统一的框架下联合学习输入句子的不同语言学方面。具体来说&#x…

高中电学实验4

欧姆表中值电阻为内阻。 满偏电阻e/满偏电流 量程变小,就是满偏电阻变小。 如果量程变为10分之1,满偏电阻变为10分之1。 电动势不变,干路电流变为原来的10倍。 就是分流的电流为量程的9倍。

【现代密码学基础】详解完美安全与不可区分安全

目录 一. 介绍 二. 不可区分性试验 三. 不可区分性与完美安全 四. 例题 五. 小结 一. 介绍 敌手完美不可区分,英文写做perfect adversarial indistinguishability,其中adversarial经常被省略不写,在密码学的论文中经常被简称为IND安全。…

已解决java.lang.ClassNotFoundException——java连接mysql8/mysql5

1.准备工作 1.mysql8下载安装 这里大家没必要去mysql官网安装,可以直接安装phpStudy_pro,毕竟小皮面板的宣言是让天下没有难配的服务器环境,如下是小皮面板的界面(同样的,此次用到的所有资料文末公众号可免费领取)&a…

零食折扣店,注定昙花一现?

年终岁末,又到了各类休闲零食产品一年一度的销售旺季。与过去不同的是,近年来的休闲零食赛道正因大量零食折扣店的涌现而显得热闹非凡。 随着主打折扣、低价的零食折扣店成为消费者特别是三四线下沉市场消费者的新宠,资本开始涌入并快速推动…

循序渐进学 JavaScript <二>

续 <一> 九、JavaScript常见内置类 9.1 原始类型的包装类 基本数据类型也可以调用属性 在理论上来说它们是没有办法获取属性或者调用方法的 原始类型是简单的值&#xff0c;默认并不能调用属性和方法js 为了可以使其获取属性和调用方法&#xff0c;对其封装了对应的包装…

【Java】Maven的基本使用

Maven的基本使用 Maven常用命令 complie&#xff1a;编译clean&#xff1a;清理test&#xff1a;测试package&#xff1a;打包install&#xff1a;安装 mvn complie mvn clean mvn test mvn package mvn installMaven生命周期 IDEA配置Maven Maven坐标 什么是坐标&#xff1f;…

有关Quick BI中当返回值为空值,行标题消失问题

一、Quick BI中的lod_ include函数 lod_ include {维度1[,维度2]...:聚合表达式[:过滤条件]} 作用&#xff1a;将表达式中的维度一起作为分组依据进行订算。其中&#xff0c; 1) 维度1[,维度2]... &#xff1a;声明维度&#xff0c;指定聚合表达式要连接到的一个或多个维…

mac安装部署gitbook教程

mac安装部署gitbook教程 前言一、安装准备二、GitBook安装项目初始化 前言 一些自己实际操作的记录。 一、安装准备 Node.js gitbook基于Node.js&#xff0c;所以需要提前安装。 下载地址&#xff1a;https://nodejs.org/en/&#xff0c;可以下载比较新的版本。(但我的建议是不…

Python正则表达式Regular Expression初探

目录 Regular 匹配规则 单字符匹配 数量匹配 边界匹配 分组匹配 贪婪与懒惰 原版说明 特殊字符 转义序列 模块方法 函数说明 匹配模式 常用匹配规则 1. 匹配出所有整数 2. 匹配11位且13开头的整数 Regular Python的re模块提供了完整的正则表达式功能。正则表达式…

Java Web现代化开发:Spring Boot + Mybatis + Redis二级缓存

Java Web现代化开发&#xff1a;Spring Boot Mybatis Redis二级缓存 背景 Spring-Boot因其提供了各种开箱即用的插件&#xff0c;使得它成为了当今最为主流的Java Web开发框架之一。Mybatis是一个十分轻量好用的ORM框架。Redis是当今十分主流的分布式key-value型数据库&…

【云上探索实验室】使用 Amazon Bedrock 体验构建Stable Diffusion-文本生成图像生成式 AI 应用

生成式人工智能&#xff08;AI&#xff09;正以惊人的速度蓬勃发展&#xff0c;不断推动着科技创新的边界。在前不久的re:Invent 2023大会上&#xff0c;Selipsky为我们重点介绍了全托管式生成式 AI 服务 Amazon Bedrock&#xff0c;并表示Amazon Bedrock 极大地降低了客户从基…

༺༽༾ཊ—设计-简单-02-工厂-模式—ཏ༿༼༻

名称&#xff1a;简单工厂 类型&#xff1a;创建型 目的&#xff1a;用 工厂方法 代替 new操作 创建实例 的方式 缺点&#xff1a;不易扩展 首先我们创建一个接口 定义两个私有方法 并在两个新建类 下继承 实现接口 【注意】&#xff1a;一旦继承接口&#xff0c;必须实现…

计组原理:系统概论与基本组成

系统概论与基本组成 系统概论硬件软件 计算机系统的层次结构系统复杂性的管理方法1&#xff1a;抽象 计算机的基本组成冯诺依曼计算机系统复杂性的管理方法 2&#xff1a;&#xff08;3’Y&#xff09; 计算机的工作步骤上机前的准备&#xff1a;计算机的解题过程存储器的基本组…

结构体内存对齐(面试重点)

结构体内存对齐 1. 结构体类型的声明1.1 结构体的概念1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的自引用 2. 结构体内存对齐2.1 对齐规则2.1.1 练习1:2.1.2 练习2:2.1.3 练习3:2.1.4 练习4: 2.2 offsetof宏的使用2.3 为什么存在内存对齐?2.…

蓝桥杯省赛无忧 编程7

为了解决这个问题&#xff0c;我们可以编写一个函数来计算从编号为1的石头到达编号为n的石头所需的最少步数。问题的关键是理解每一步的移动规则&#xff1a;从当前石头编号n移动到编号为nx的石头上&#xff0c;其中x是n的各位数字之和。因此&#xff0c;我们需要一个辅助函数来…

docker 部署 sentinel

docker 部署 sentinel 环境安装 拉取镜像 目前稳定的版本是1.8.0 docker pull bladex/sentinel-dashboard:1.8.0启动服务 docker run --name sentinel -p 8858:8858 -td bladex/sentinel-dashboard:1.8.0登录 登录的时候账号和密码都是sentinel