百度高效研发实战训练营-Step4

百度高效研发实战训练营-Step4


4.1 代码检测规则:Java案例详解

以Java的案例进行代码检查规则解释,代码检测规则可以分为以下十类:

4.1.1 源文件规范

该类规范,主要为从文件名、文件编码、特殊字符等三个方面制定的规则。

  • 文件名方面:Java源文件名,必须和它包含的顶层类名保持一致,包括大小写,并以.java作为后缀名。

  • 文件编码方面:为了保持编码风格的一致性,避免编码不一致导致的乱码问题,要求所有源文件编码必须使用UTF-8格式。

  • 特殊字符方面:针对换行、缩进、空格等操作而制定,有以下强制规则:

    • 1 换行符以外,ASCII空格(0x20)是唯一合法的空格字符。

    • 2 由于不同系统将Tab转换成空格的数目不一致,统一使用空格进行缩进。

    • 3 文件的换行符统一使用Unix格式(\n),而不要使用Windows格式(\r\n)

4.1.2 源文件组织结构规范

这一大类规则规定了源文件所应包含的具体组成部分,和各个部分间应遵循的一系列规则。
对于源文件的组成部分,规定如下:
源文件,必须按照顺序包含以下内容,许可证或版权声明、package、import、唯一的顶层类四个方面的内容。同时,每两个部分之间用一个空行进行分隔,不允许出现多余空行,对于以上四个方面的内容,每个组成部分又有相应的编码规则。

1 许可证或版权声明

  • 如果文件有许可证或版权声明,应放在最开头,如果没有,则可以忽略这部分。

2 package语句

  • package语句一定单独占一行不换行
  • 允许超过Java的120字符列宽限制

3 import语句

  • 对于所有非静态导入,禁止使用通配符import
  • 所有未使用的import语句均应删除,并且与package语句相同
  • 每条import语句单独占据一行不换行,允许超出120字符列宽限制

4 唯一的顶层类

类声明规范

  • 每个源文件只允许包含唯一一个顶层类,若需要定义其他的类,可将多余的类放在另外一个独立的源文件中,或者可将其作为一个内部类,定义在顶层类中来使用
  • 重载的方法必须放在一起,即同名的构造函数或方法之间禁止插入其他成员

4.1.3 代码结构规范

这一部分规则,主要是对花括号(即大括号),缩进与换行、空行的一系列规范和其他说明。

1 花括号

花括号,经常在类和方法定义以及代码块划分中使用,花括号在使用中常需要合理的换行操作进行配合,规定为:

  • 在非空代码块中使用花括号时,要遵循K&R风格(Kernighan and Ritchie Style)。

三个主要原则为:

  • ①在左花括号({})前不能换行,在其后换行
  • ②在右花括号(})前应有尽有
  • ③表示终止的右花括号(})后必须换行,否则,右花括号后不换行。

2 缩进与换行

缩进与换行,主要是为了保证代码风格的一致性,提升代码的可维护性。
主要规范有:

  • ①每次开始书写一个新代码块时,使用四个空格进行缩进,在代码块结束时,恢复之前的缩进级别。

  • ②每条语句之后都要换行,每行只能有一条完整语句

  • ③除package语句import语句外,单行代码字符数限制不超过120个。
    超出则需要换行,换行时,遵循如下五条原则:

    (1) 第二行相对于第一行缩进四个空格,从第三行开始,不再继续缩进。
    (2) 运算符与下文一起换行,即运算符位于行首

    (3) 方法调用的点符号与下文一起换行

    (4) 方法调用中的多个参数需要换行时,在逗号后进行
    (5) 在括号前不要换行

3 空行

合理使用空行,可以提高代码的可读性,有利于后期维护。
对于空行的使用,有如下规范进行约束:

  • ①在类的不同成员间增加空行,包括:成员函数、构造函数、方法、内部类、静态初始化块、实例初始化块等。
  • ②在两个成员变量声明之间可以不加空行。空行通常用于成员变量进行逻辑分组。
  • ③方法体内,按需增加空行,以便从逻辑上对语句进行分组。
  • ④使用空行时,禁止使用连续的空行。

4 其他说明

Java中有两种数组定义形式,为规范代码书写形式,要求为:

  • 类型与中括号紧挨相连来表示数组,即中括号写在数组名之前

而当注解与注释同时存在时,统一的规范要求为:

  • 添加在类、方法、构造函数、成员属性上的注解,直接写在注释块之后,每个注解独占一行

当同时存在多个修饰符时,需要按照顺序书写,顺序要求如下:

  • 排在首位的一定是访问修饰符,随后是abstract,即抽象类或抽象方法,紧接着是staticfinal。这是常见的几类修饰符,对于其他的修饰符,可以参考以上列举的顺序书写。

    public protected private abstract static final 
    transient volatile synchronized native strictfp
    

为避免小写字母,l与1混淆,有如下规定:

  • 常整型数字必须使用大写字母L结尾,以便于和数字1进行区分

4.1.4 命名规范

在Java中,无论是方法名还是类名,均需使用驼峰命名格式进行命名。

1 驼峰命名格式

对于两种驼峰命名格式的使用范围,有如下规范:

  • ①方法名、参数名、成员变量、局部变量都统一使用lowerCaeCase风格,即首字母小写的驼峰命名格式
  • ②类名使用UpperCamelCame风格,即首字母大写的驼峰命名格式,以下情形例外:DO/BO/DTO/VO/AO/PO/UID等。

2 类的命名格式

除此之外,对于一些类,命名格式有更加具体的规范要求:

  • ①抽象类命名,使用Abstact或Base开头
  • ②异常类命名使用Exception结尾
  • ③测试类命名以它要测试的类的名称开始,以Test结尾。

3 常量命名格式

对于常量的命名规范,与上述所述有所不同:

  • ①常量命名全部大写,单词间用下划线隔开;
  • ②不允许任何未经定义的常量直接出现在代码中。

4.1.5 OOP规约

OOP规约,主要是针对面向对象编程过程中,定义的一些类所制定的一些规则,包含的强制规范要求有

  • ①所有POJO类属性,必须使用包装数据类型,禁止使用基本类型。
  • ②所有的覆写方法,必须加@Override注解
  • ③Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals
  • ④定义DO/DTO/VO等POJO类时,均不要设定任何属性默认值。

4.1.6 集合处理规范

集合和数组,是我们开发过程中使用频度最高的两个数据结构。
对于二者的使用,也有严格的强制规范:

  • ①当需要将集合转换为数组时,必须使用集合的toArray方法,传入的是类型完全一样的数组,大小是list.size()。
  • ②对一个集合求子集合时,需高度注意对原集合元素的增加或删除,均会导致子列表的遍历、增加、删除,产生ConcurrentModificationException异常。应通过对子集合进行相应操作,来反射到原集合,从而避免异常的发生。
  • ③不要在循环体内部进行集合元素remove/add操作。remove元素请使用Iterator(迭代器)方式,如果并发操作,需要对Iterator对象加锁。

4.1.7 控制语句规范

Java中的控制语句主要有Switch、if、else、while。这些语句的使用在编码过程中需要遵循以下规范:

  • (1)在一个switch块内,每个case要么通过break/return等来终止,要么注释说明程序将继续执行到哪一个case为止;在一个stitch块内,都必须包含一个default语句并且放在最后。
  • (2)使用if/else/while/do语句必须使用花括号。即使只有一行代码,避免采用单行的编码方式。
  • (3)在高并发场景中,避免使用“等于”判断作为中断或退出的条件。防止在击穿现象下,程序无法正常中断或退出的情况发生。

4.1.8 注释规约

合理使用注释可以提高程序可读性,从而便于后期的维护。
注释可以是程序说明,也可以是编程思路。
Java中的注释主要分三种形式:文档注释、单行注释和多行注释
注释规约包括:

  • ①类、类属性、类方法的注释必须使用文档注释形式,即使用\(/**内容**/\)格式,不得使用单行注释的格式。单行注释和多行注释主要使用在方法体内。
  • ②方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释,使用\(/*内部*/\),注释与代码对齐。

4.1.9 异常处理规范

在Java中,我们通常使用try catch来进行捕获异常处理,而Java中的异常又分为运行时异常和非运行时异常。对于处理运行时异常,有如下规范:

  • ①Java类库中定义的可以通过预检查方式规避的RuntimeException异常不应该通过try catch的方式来处理,比如:空指针异常和数组越界异常等等。
  • ②对于捕获后异常的处理,有如下规范:捕获异常是为了处理异常,不要捕获后不进行任何处理而将其抛弃。
    若不想进行异常的处理,则应将该异常抛给它的调用者。
    最外层的业务使用者必须处理异常,将其转化为用户可以理解的内容。
    即对于捕获后的异常,要么继续向上抛,要么自己进行处理。
  • ③异常处理的规范要求还包括:不能在finally块中使用return语句。

4.1.10 缺陷检测规则

缺陷检测要是对Java源代码进行静态分析,扫描其中潜在的缺陷,比如空指针异常、死循环等。

这一阶段所应遵循的规则包括:

  • (1) 不能使用单个字符定义StringBuffer和StringBuilder;
  • (2) 任何上锁的对象均需保证其锁可以被释放
  • (3) 严格避免死循环的发生
  • (4) 对于字符串中的点号(".")、竖线("|")和文件分隔符("File.separator")进行替代时,需要注意其特殊含义。
    “.”:匹配任意单个字符。在replaceAll中使用,它匹配所有内容。
    “|”:通常用作选项分隔符,它匹配字符间的空格。
    “File.separator”:匹配特定平台的文件路径分隔符。在Windows上,这将被视为转义字符。
  • (5) 当synchronize对成员变量进行上锁时,该成员变量必须是final类型的。
  • (6) synchronize上锁的成员变量类型一定不能是装箱类型。
  • (7) 所有被spring托管的类,其成员属性的初始化均要使用注入的方式。
  • (8) 当使用try catch方式进行异常捕获,且需要在catch中对异常信息进行输出时,不得使用printStackTrace的方式。
    这种方式会导致后期分析代码困难。而应采用一些Log框架,方便用户检索和浏览日志。
  • (9) 方式返回值包含操作状态代码时,该状态码不应被忽略
  • (10) 【%s】数组具有协变性,元素赋值类型与初始化类型不一致,此种情况可通过编译,但运行阶段会发生错误。
  • (11) 对于用户名和密码不应直接写在Java的文件中,避免泄露。而应将相信关键信息写在配置文件中进行读取。
  • (12) 方法和成员变量的命名不应相同,也不应通过大小写进行区分。

4.2 单元测试之Java实践

如何写单元测试,这部分包括四个方面,基本流程、测试替身、设计思路、断言(Assertions)。

4.2.1 如何写单元测试

1 基本流程

单元测试的基本流程如下,首先,环境初始化,其次准备输入参数,再次,调用待测试方法,然后检查输出,最后测试完成后环境复原。

环境初始化=>准备输入参数=>调用待测试方法=>检查输出=>测试完成后环境复原。

2 测试替身

下面来介绍一下什么是测试替身。
测试替身,可用于隔离被测试的代码,加速执行顺序,使得随机行为变得确定,模拟特殊情况,以及能够使测试访问隐藏信息等。
在Java代码开发过程中,替身测试能够保证单元测试的独立性与重复性。
常见的测试替身有四类:桩(Stub)、伪造对象(Fake)、测试间谍(Spy)、模拟对象(Mock)等。

对于以上四个类别:

1 桩(Stub)

对于桩,一般什么都不做,实现空的方法调用或者简单的硬编码返回即可。

2 伪造对象(Fake)

真实数据的简单版本,伪造真实对象的欣慰,但是没有副作用或者使用真实事物的其他后果。比如替换数据库的对象,而得到虚假的伪造对象。

3 测试间谍(Spy)

需要得到封闭对象内部状态的时候,就要用到测试间谍,事先学会反馈信息,然后潜入对象内部去获取对象的状态。测试间谍是一种测试替身,它用于记录过去发生的情况,这样测试在事后就能知道所发生的一切。

4 模拟对象(Mock)

模拟对象是一个特殊的测试间谍。是一个在特定的情况下可以配置行为的对象,规定了在什么情况下,返回什么样的值的一种测试替身。目前Mock已经有了非常成熟的对象库,包括JMock、Mockito和EasyMock等。

下面重点讲一下,模拟对象(Mock)。

假如我们有业务逻辑,数据存取,数据这三层逻辑。
现在需要对业务逻辑层进行单元测试,那么我们可以使用Mock,对数据存取和数据层的内容进行模拟,从而使上面的单元测试是独立的。

3 设计思路

下面来讲解怎样通过测试替身来写单元测试:
单元测试case的核心与当前函数的功能实现,对于输出数据做出具体的预期,即可把全部待测试的分支都罗列出来。
应用场景+输入数据+功能实现=输出数据。

4 断言(Assertions)

断言,是一种在Java单元测试中经常使用的测试方法,在单元测试中,我们使用断言,来检验当前的测试结果是成功还是失败。

常见的断言有:Assert.assertNotNull、Assert.assertEquals、Assert.assertTrue、Assert.assertFalse、Assert.fail。无需人工对单元测试结果进行判断。

4.2.2 单元测试的运行

单元测试的运行:
单元测试的运行分为手动与自动两种,第一种是手动方式:

  • 直接在IDE中执行
    在开发编码完成之后,开发人员可以直接在自己的环境和编译器内运行单元测试。
  • 使用Maven的mvn test
    Maven是目前Java开发中最流行的项目构建工具,它包含了很多功能,非常全面。mvn test这个测试模型就可以为我们的单元测试提供极大的便利。

第二种方式是自动运行:

  • 持续集成(Jenkins)
    自动化持续集成是我们在项目中常用的一种单元测试的方法。通用工具为Jenkins,Jenkins是一种持续集成的工具,它的功能非常强大。他的主要的功能有软件发布和版本测试、外部调用测试。

4.2.3 如何判断单元测试的质量

首先来看一下,单元测试的衡量标准。
从主观层面,优秀的单元测试可读性高、易于维护、值得信赖。
从客观层面,使用单元测试代码覆盖率来衡量,覆盖率工具包括:集成IDE和单独部署。


4.3 如何做好Code Review

4.3.1 为什么要做好Code Review

1 Code Review是提升代码质量的最好方法

Code Review是提升代码质量的最好方法,是提升代码质量的第一选择,在代码开发过程中,我们越早发现问题,定位问题,在修复问题时付出的成本越小,大约有50%以上的Bug,都是在做Code Review时发现的。

前期做好Code Review,后期将会减少反复修改等不必要的复工。

2 Code Review能够在团队内传递知识

从知识传递的角度来看,Code Review是极为重要的。
做好Code Review,能够帮助团队传递知识、沟通交流、互相学习、能够提升学习能力、提升编写代码能力、提升代码质量、提升工作效率、降低项目风险。另外基于Codebase可以使我们了解项目全局,培养系统的思考方式。

3 Code Review是辅导怎么写代码的最好方法

我们要意识到,做Code Review可以学习到别人的经验,同时向别人传递我们的经验,如果我们想辅导别人,最好的办法就是让对方先写一段代码,我们对他的的代码进行Code Review,在辅导他人的过程中,我们可以快速的发现问题,从而帮助改进。

4 做好Code Review可以增加公司对最顶级开发者的吸引力

工作中是否有Code Review,对于公司或团队来说非常重要,不但对于公司或团队内的人员有提升,而且能够吸引出色的开发者加入开发团队。
未做好Code Review的公司或团队,有如下特点:

  • 1 代码质量差
  • 2 团队内人员备份差
  • 3 团队开发人员得不到有效的辅导,提高慢

5 为什么要提高代码质量

为什么要提高代码质量的若干理由,如下:

  • ①提高代码质量,可以提高代码的可读性
  • ②提高代码质量,可以提高代码的复用性和参考性
  • ③提高代码质量,可以减少Bug出现的风险
  • ④提高代码质量,可以减少后期补丁的风险
  • ⑤提高代码质量,可以降低代码失控的风险
  • ⑥提高代码质量,可以降低项目重构和升级的麻烦

6 为什么要提高写代码的能力

为什么要提高写代码的能力的若干理由,如下:

  • ①代码能力如果停滞不前,对于个人而言,将导致职业危机。
  • ②代码能力如果停滞不前,对于团队而言,将意味着团队没有成长。

Code Review是一个非常重要的,提升代码质量和代码能力的手段。
无论是从个人发展角度还是团队发展角度,我们都需要重视Code Review。

4.3.2 如何做好Code Review

我们将从以下几个维度进行阐述,如何进行Code Review。

1 在Code Review中可能发现的问题

在Code Review中可以发现如下问题:

  • ①拼写错误
  • ②未优化的代码
  • ③不必要的复杂代码
  • ④已经实现过的代码又重复实现
  • ⑤注释不全
  • ⑥case没有覆盖全
  • ⑦...

2 在Code Review中应有的态度

基于以上问题,在Code Review中要有一个好的态度。
这就要求我们要做到以下几点:

  • ①对所有检查的代码逻辑要做到“完全看懂”
    对于审核的代码,熟悉程度要做到如数家珍,如果在审核代码后,对代码的逻辑和背后的原因仍然很模糊,则是一次失败的Code Review。
  • ②好代码的标准,不仅仅是可以运行通过,在正确性、可读性、可复用性、可运维性等方面上,都需要综合考虑。
  • ③建立Code Review和写代码一样重要的意识。
    (1) 即Code Review和写代码一样,也有产出,即产出更高质量的代码;
    (2) 审核代码,在很多情况下比写代码还要辛苦,需要理解和找出问题等。
  • ④以提升代码质量为最终目标
  • ⑤要投入足够的时间和重视
    (1) 审核代码花费的时间,经常和写代码一样多。有时甚至比写代码的时间更多,因此要有时间意识。
    (2) 要有责任意识,如果出现Bug不仅仅是写代码人员的职责,也不仅仅是QA的职责,代码审核者也需要承担相当大的责任。

3 在Code Review之前,需要了解一流代码的特性

除了态度之外,在Code Review之前,需要了解一流代码的特性。
一流代码有以下特性:

  • (1) 高效性
  • (2) 鲁棒性
  • (3) 简洁
  • (4) 简短
  • (5) 可共享
  • (6) 可测试
  • (7) 可移植
  • (8) 可监控
  • (9) 可运维
  • (10) 可扩展

将以上十条标准进行总结精简,可归纳为:

  • 1 代码的正确和性能
  • 2 代码的可读和可维护性
  • 3 代码的可运维和可运营
  • 4 代码的可共享和可重用

在Code Review时,综合考虑以上一流代码的特性,可以快速提升代码质量,提升编写代码的能力等。

4 在Code Review时,需要有对bad code进行简单判断的能力

除了要了解一流代码的特性之外,在Code Review时,需要有对Bad Code进行简单判断的能力。
通常bad code有以下特点:

  • ①5分钟内不能看懂的代码
    不能快速看懂的代码,一定是有问题的代码。
    可以先抛回给编写代码人员进行修正。
    一般一个函数的操作,不能超过6个Step,如果超过这个数量,则需要重新调整编码逻辑。

  • ②需要思考才能看懂的代码
    好的代码阅读时基本不用动脑子,甚至看注释就能看懂。

  • ③需要来回翻屏才能看懂的代码
    好的代码,经常在一屏内就是一个完整的逻辑。

  • ④没有空行或注释的代码

    在Code Review时,在发现不会用段落,不会写注释的代码,肯定部署好的程序员写的代码。可以直接打回给编写代码人员进行修正。

5 Code Review的注意事项

在Code Review时有以下注意事项:

  • 1 在必要时,Review的双方做面对面的沟通
    面对面沟通,并不是单指当面沟通,还包括云共享、电话、视频沟通等。
    在沟通时,对于背景、关键点等应进行说明,便于reviewer的理解。
    在必要时,应提供设计文档。
  • 2 对于关键模块,应该建立owner制度,所有提交的代码,必须由owner做最终确认,由owner做最终确认,并建立明确的责任关系。
  • 3 对于Review检查中发现的问题,要一追到底。
  • 4 要注意细节
    对每一行提交的代码,都要进行检查。
  • 5 Code Review的方式,要小步快跑。
    每次调教review的代码量不要太多,降低复杂度。
    在特殊情况时,比如一个新模块的构建,最好逐步完成,通过多次进行提交。
  • 6 要为Code Review预留出足够的时间
    Code Review VS Coding的时间,有时可能达到1:1。
    在这里需要考虑到有时会做大的修改,科学地规划工作量,尽量避免出现时间倒排。
  • 7 注意每天review代码的数量,不宜过多。

6 Code Review的步骤

Code Review的步骤,主要为以下几点:

  • Step1 先看系统全貌
    不深究细节,浏览系统全貌,理清模块划分的逻辑、模块间的关系、如何构成的整个系统等。
  • Step2 进入模块级别
    同样不深究细节,浏览模块内的全貌,判断模块切分是否合理、理清模块内的逻辑、明确关键数据、关键的类和函数等。
  • Step3 理清类、函数内部的逻辑
  • Step4 进入细节
    比如Layout、命名等。

7 人为因素

除了代码上的问题,在Code Review过程中,还会有一些人为因素。
比如:

  • 1 QA人员
    好的QA人员,不仅仅会发现系统中的Bug,还会质疑或提出产品需求。挑战或优化系统架构和实现方式。

  • 2 Code Reviewer

好的代码审核人员,不仅仅指出代码表面的问题。
还会检查系统需求分析的质量、接口或函数定义的合理性、模块划分的合理性、系统关键机制的合理性等。

4.3.3 例子:Python代码的Code Review

我们从Phthon的编码规范和Python编程规范的部分说明。
两个维度,来看一下Code Review的细节。
这些Code Review的细节,在其他语言中基本都是相通的。

1 Python的编程规范

  • (1) 代码要写的漂亮

  • (2) 代码要明确直接
    明确直接,不要含蓄表达。

  • (3) 代码要简洁
    一个函数可以实现的功能,就不要写两个函数。

  • (4) 代码深奥胜过代码复杂
    代码可以写的深奥难懂,但是不能写的过于复杂。

  • (5) 代码要平铺直叙
    平铺直叙,不要层层嵌套

  • (6) 代码要做到合理间隔

  • (7) 代码可读性非常重要

  • (8) 代码要有普适性
    尽量规避代码特殊性,用最简洁的代码来实现。

  • (9) 代码要实用

  • (10) 要重视所有发现的错误

  • (11) 代码逻辑要清晰
    在含糊混乱的面前,我们要拒绝猜测。读写代码时,不要出现好像、可能、似乎等猜测。
    当一段代码很难懂的时候,代码一定存在问题。

  • (12) 写代码要注重行动

  • (13) 代码实现方法要简洁
    如果一个方法很难解释,就意味着这个方法存在一定的问题。

  • (14) 要重视命名空间的使用

2 关于Python编程规范的部分说明

在关于Python编程规范的部分说明中,下面将从九个维度进行展开,分别是:

  • 模块的划分
  • 数据的封装
  • import
  • 异常
  • 构造函数
  • 函数返回值
  • 代码长度
  • 空行、空格
  • 注释

(1) 模块的划分

首先来看模块的划分,我们要对模块有概念,这是整个系统的基础。

  • ①一个.py文件是一个模块
  • ②模块的划分,对软件的长期维护非常重要
  • ③每个模块都应该有特定的功能
    例如:配置文件的读取
    网页文件的写入
    网页文件的解析
    一个内存数据表
    一个抓取的线程
  • ④多个本应独立的模块,写到一个.py文件中是常见的错误。

从Code Review角度看,首先就是要看模块切分的对不对。

(2) 数据的封装

不管理好数据,是程序错误的重要来源,常见的程序错误是数据未封装。
在Code Review时,要着重注意这一点。

(3) import

import在使用过程中,有以下注意事项:

  • 禁止使用from xxx import yyy语法直接导入类或函数。
  • 禁止使用from xxx import *这样的方法
    这样做的目的是,容易判断代码中使用外部变量或函数的来源。
    如果使用禁止中的语法,会大大增加判断来源的难度,以及代码阅读的难度。

在Code Review时,在遇到这种情况,应及时将代码打回给编程人员进行修正。

(4) 异常

对于异常的处理,有以下几点需要注意:

  • 1 异常的使用
    使用异常前,需要详细了解异常的行为。不要主动抛出异常,使用返回值。如果一定要抛异常,需要注释进行说明。
  • 2 异常的获取强制
    除非重新抛出异常,否则禁止使用except:捕获所有异常,不建议捕获Exception或StandardError。

在实际编码中,建议Try中的代码尽可能少,避免catch住未预期的异常,掩藏掉真正的错误。
底线是至少要打印异常的日志,而不是捕获后直接pass通过。

在对异常进行处理时,尽量针对特定操作的特定异常来捕获。
常犯的错误是,一是对IO等操作不捕获异常,二是捕获异常区域很大。

  • 3 函数的返回值
    如果函数会抛出异常,需要在注释中明确说明。

在Code Review时,需要注意上述问题,及时返回给编程人员进行修正。

(5) 构造函数

对于构造函数,有以下几点需要注意:

1 规范

  • 类构造函数,应该尽量简单,不能包含可能失败或过于复杂的操作。

2 解读

  • 在构造函数中,常出现的错误是:无法判断、或捕获异常。

(6) 函数返回值

对于函数返回值,有以下几点需要注意:

1 规范

  • 函数返回值,必须小于等于3个。
    返回值超过3个时,必须通过class/namedtuple/dict等具名形式进行包装。

2 解读

  • a.多数情况下的错误,是很多人不会思考和设计函数的语义。
    函数描述涉及的三要素为:功能描述、传入参数描述和返回值描述。
    每个函数都应该有足够明确的语义。
    基于函数的语义,函数的返回值有三种类型:
    (1) 在“逻辑判断型”函数中,返回布尔类型的值。——True或False,表示“真”或“假”。
    (2) 在“操作型”函数中,作为一个动作,返回成功或失败的结果。——OK或ERROR。
    (3) 在“获取型”函数中,返回一个“数据”,或者返回“无数据/获取数据失败”。
  • b.函数需要有返回值,对于正确或错误的情况,在返回值中要有体现。
  • c.还有一个问题是:Python的数据格式不需要定义,过于灵活。
    当程序规模变大、维护周期变长时,会导致后期极难维护。
    应对措施是:多写注释,写清楚返回值说明、参数说明。

在Code Review时,注释未写清楚的代码,一定要打回给编程人员,进行修正、补注释。

(7) 代码长度

关于代码长度,有以下几点需要注意:

  • 1 每行不得超过120个字符
    避免在终端上显示出现折行
  • 2 函数长度不得超出100行
    函数过长会增加理解函数逻辑的难度
    Python的函数应尽量控制在30~40行之间。

在Code Review时,代码过长,建议全部打回给编程人员进行修正。

(8) 空行、空格

关于空行、空格,有以下几点需要注意:

  • 1 文件及定义之间间隔两个空行

    比如类或全局函数、类方法之间隔一个空行。

  • 2 空格
    逗号、分号、冒号前不加空格。后边加一个空格。
    所有二元运算符前后各加一个空格。

在Code Review时,要着重注意空行和空格。
空行和空格并不是可有可无的。
空行和空格的存在,是为了增加可读性。
不好读的代码,一律打回给编程人员进行修正。

(9) 注释

关于注释,有以下几点需要注意:

  • Python中的注释有一个特殊之处是docstring,docstring要和“#”注意区分开。
    相关规范有:
    1 使用docstring描述module、function、class和method接口时,docstring必须用三个双引号括起来。
    2 对外接口部分,必须用docstring描述。内部接口视情况自行决定是否写docstring。
    3 接口的docstring描述,至少包括功能简介、参数、返回值。如果可能抛出异常,必须使用注释进行说明。
    4 每个文件都必须有文件声明,文件声明必须包括以下信息:版权声明、功能和用途简介、修改人及联系方式。
  • 不符合上述规则的,直接打回给编程人员进行修正。

4.3.4 如何成为一个好的reviewer

如何成为一个好的reviewer。
代码审核的质量,和审核者的代码能力直接相关。
代码审核的质量差,反映的是审核者的代码水平。
如果作为一个代码审核员,不会写代码,就要承认事实真相,并且要不断提高自己的代码能力。

在这里推荐一些学习资料,来帮助大家进行学习。
1 关于代码的书籍
《编写可读代码的艺术》
《代码整洁之道》

2 综合的书籍
《代码大全》
《201 principles of software development》

3 其他
《代码的艺术》
《Python Good Coder考试指南》

4.3.5 公司针对Code Review的措施

1 建立高效可运营的代码审核机制

  • 提升代码质量
  • 降低代码评审成本

(1) 基于平台
icode+bugbye
(2) 代码检查规则分级
分为ERROR、WARNING、ADVICE三类。

  • 对于ERROR级别,阻塞提交。

(3) 通过统计数据驱动代码检测规则的优化

2 通过工程能力地图考察项目的Code Review情况

3 提供良好的工具或平台
所有的Code Review行为,都基于icode平台进行。
良好的工具或平台,可以帮助更好的进行代码审核。

4.3.6 Code Review课程总结

这本文内容中,分别从为什么要做好Code Review、如何做好Code Review、Python代码的Code Review、如何成为一个好的Reviewer、公司针对Code Review的措施几个维度,学习了Code Review的相关知识,清楚了Code Review的重要性、方法步骤和注意事项。

posted @ 2022-06-13 22:18  Xu_Lin  阅读(155)  评论(0编辑  收藏  举报