`
thinkerAndThinker
  • 浏览: 288759 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

评审的艺术——谈谈现实中的代码评审

 
阅读更多

曾经写过一点关于代码评审(code review)的文章,比如这篇这篇,现在觉得关于它的认识又有了不少更新。软件工程的技术和实践分成两部分,一部分是和书本知识一致的,大约占一半,这部分基本上在大学里就可以学,自学只要方法得当、刻苦努力也可是途径;但是第二部分来自于实际团队、经验,内容通常无法从书本当中获得,而且难说对错,不同的人和不同的经历造就了不同的认识。代码评审就是第二部分颇具槽点,可以大加讨论的典型。

  代码评审是展现个性和性格的途径

  我本人特别反对一种颇为常见的观点,就是“一个良好运作的项目,不同的人,应该写出一样的代码”。我非常理解这种观点的初衷,一个良好规范约束的团队中,不同的人写出来的代码应当一致。但实际上,能真正这样做的团队,我还根本没有见到过。所谓的一致代码,仔细品味,发现不同的工程师写出来就是不一致。因此“一致”这个词一定是在一定程度内的大体描述而已,并非越一致约好。其实,代码的创造本就是具备个性的。毫无疑问我们应当遵从规约,应当符合习惯,但是一旦试图过度使用它们去约束代码,不但难以落实,而且容易产生无趣、低效和矛盾的氛围。

  再回到代码评审上。代码评审本身,以及基于评审意见的来回沟通,和代码本身比起来,要更难以,也更不应该要求一致。我见过许多代码评审的风格,有人喜欢挑小毛病,有人喜欢展开观点夸夸其谈,有人喜欢给实际例子来证明自己的看法……无论哪一种风格,我都不觉得有什么大的问题。但是,就我个人而言,我可以谈谈我自己的代码评审风格:

  我会关注三种问题,需求和业务上的问题、代码结构的问题、代码风格格式的问题。

  前两种可能存在阻碍我ship代码的“严重”问题(说“ship”就意味着认可代码具备了push到主线分支的条件了)。我已经记不清多少次和代码作者因为这样的问题争论了。争论是个艺术,有时候并不一定能够达成一致,有的人比较容易被说服,有的人则更坚持己见。我不想说哪一种更好,但是确实这是代码评审中展现风格的事实——都是就事论事,但有人害怕或者不喜欢得罪人,就会显得push over一点;有人则不在乎那么多,坚信自己的想法更合适,就会显得defensive一点。我可能属于后者,似乎在职业生涯的各种阶段都会有和我出现代码评审冲突的事例,但是在某些情况下我也会选择disagree and commit(不同意但是执行团队达成的意见)。我相信有些团队会喜欢我的backbone,也会有团队讨厌我的这种风格。下面的内容,也多为基于自己风格的表述。

  坚定自己的意见,但是委婉地表达

  关于这一点,我也在努力地改进。可以提及的点很多,技巧也很多,但是老实说,冲突还是不可避免。在我经历的几乎所有的团队中,有时候会有老好人,但是基本上所有的老好人都缺少对于原则的坚持。沟通是门艺术,在代码评审中也一样体现。

  • 最重要的一条,只针对代码,不针对人。这条很简单,都知道对事不对人的重要性,但是要非常小心不能违背。
  • 对于大多数代码风格格式上的问题,我都会标注这个问题是一个picky或者nit的问题(“挑剔的问题”,这是我在Amazon的时候学到的方式)。这样的好处在于,明确告知对方,我虽然提出了这个问题,但是它没有什么大不了的,如果你坚持不改,我也不打算说服你。或者说,我对这个问题持有不同的看法,但是我也并不坚信我的提议更好。
  • 使用也许、或许、可能、似乎这样表示不确定的语气词(包括使用虚拟语气)。这样的好处是,缓和自己观点表达的语气。比如:“这个地方重构一下,去掉这个循环,也许会更好”。
  • 间接地表达质疑。比如说,看到对方用了一个参数3,但是你觉得不对,但又不很确定,可以这样说:“我有一个疑问,为什么这里要使用3而不是其他值?”对方可能会反应过来这个值选取得不够恰当。
  • 放上例子、讨论的链接,以及其它一些辅助材料证明自己的观点,但是不要直接表述观点,让对方来确认这个观点。比如:“下面的讨论是关于这个逻辑的另一种实现方式,不知你觉得是否会稍简洁一些?”
  • 先肯定,再否定。这个我想很多人一直都在用,先摆事实诚恳地说一些同意和正面的话,然后用however一转,说出相反的情况,这样也就在言论中比较了pros和cons,意味着这是经过trade-off得出的结论。
  • ……

  一些很常见的可以在代码评审中提及的问题

  这样的问题其实有不少,多数和实现的技术无关,但是又很容易不小心略过。它们多数时候是问题,当然也有时候不是。

  • 比如说,我最痛恨的之一,职责过于宽泛或者职责不清的类或模块。我无数次见过这样的类:Helper,或者Utils(注意,它们都没有模型或者模块前缀)。考虑项目的规模,大多数情况下,这样的类很容易变成一个越吹越大的气球,似乎什么东西都可以往里搁,是个十足的违反单一职责原则的糟糕设计。
  • 比如说,在线程使用,容器使用,连接管理……中,缺乏上限控制的设计,在一些情况下导致资源使用过度膨胀。生产者和消费者的队列设计,一旦消费者挂掉或者跟不上,队列里越堆越多,没有拒绝机制。
  • 再比如说,缺少分包、分层,所有的东西都叠在一起,十几个,甚至几十个类文件并列在同一个文件夹下面。
  • 再再比如说,代码缺乏设计,流水账结构,面条型代码,或者简单铺陈几个过程式的方法,这种修改往往代价还不小,自然修改的落实率低,因而令提出问题的人也颇为头疼。
  • ……

  避免一次评审提及过多的问题

  少数情况下,手里拿到一份实在是问题多到令人发指的代码,这时候需要扼制自己想骂人的冲动。先抓问题的主干,不要去挑那些细枝末节的毛病,因为很有可能,这些代码会被改得面目全非,或者重写。写一大堆评审意见,反而容易淹没最重要的问题。

  说说容易,但是这个度有时候并不好掌握。我的习惯是,在明确代码要解决的问题以后,先快速走读一遍代码,判断我是应该粗略地抓主要矛盾呢,还是应该严格地挑刺呢。我也见过一些别的方式。

  不一样的评审要求

  我始终觉得,代码评审的要求不应该完全一致。不要过度追求公平。对于新项目代码,以及新员工写的代码,要适当严格一些。

  新项目的代码是形成后续风格和质量的模板。我们也许都听说过“破窗户原理”,在一块干干净净的代码田地里,新耕种的代码才容易保持一致,也可以避免一些“为了和现有代码风格保持一致”而导致质量妥协的情况出现。

  新员工代码的高质量要求则更多地在于对他们良好习惯养成的负责。软件工程师良好职业习惯的养成,代码可以说是最重要一环,而前三个月的影响举足轻重。

  还不如不做的评审

  有些情况下,代码评审是非常耗时费力的工作。特别是对业务背景不熟悉,对实现技术不熟悉,或者干脆是对方提交上来一大堆修改,阅读非常费力。我不知道哪一种是最难的,但是如果因为这些原因很难做到良好的评审,我会在评审中说明,或者放弃一些评审的工作,保证评审的质量。

  代码评审是建立在团队中影响的好方式。一方面是业务逻辑,一方面是代码结构,我反对在两方面都难以给出足够清晰的评审意见的时候,提一堆风格方面的次要问题。否则很容易达成负面影响。

  先谈到这里,我想还有不少可以涉及的内容,而它们都难以在课堂和书本上学到。争论才有意思,实践出真知大抵如此吧。你有什么一致的看法,或者反驳,欢迎和我讨论。

 

       比较欣赏四火老师的一些观点,所以摘录到自己的博客中,让更多的同道朋友看到,学习,受益!

下面还有2篇关于 评审风格 和 详审的好处的言论,欢迎互踩。

分享到:
评论

相关推荐

    C语言扫雷代码

    最后谈谈写代码吧,也有人不喜欢这种说法,更喜欢那个冠冕堂皇的词——软件设计,或者叫软件开发。其实核心还是写代码(很多经院理论家已经把它变成了写文档,国内公司的文档比代码绝对不少,但基本都是没什么营养的...

    美赛2020latex模板.zip

    在2020年的竞赛中,参赛者们有了一个新的利器——“美赛2020 LaTeX 模板”。这个模板不仅为参赛者提供了便捷的图表代码框架,还具有目录自动变更的特性,使得论文撰写过程更加高效。 首先,让我们谈谈LaTeX,这是一...

    动态电压恢复器(DVR)模型2.0在Matlab Simulink环境下的精细化仿真:全面治理电能质量问题的时序解析,动态电压恢复器(DVR)模型2.0在Matlab Simulink下的电能

    动态电压恢复器(DVR)模型【2.0】在Matlab Simulink环境下的精细化仿真:全面治理电能质量问题的时序解析,动态电压恢复器(DVR)模型【2.0】在Matlab Simulink下的电能质量问题治理详解:全面应对源侧电压暂降、暂升及负载影响,历时1.1秒,动态电压恢复器(DVR)模型【2.0】 Matlab simulink 可用于治理电能质量问题:仿真总时长1.1s,DVR始终接入,具体如下: 0.1-0.2s治理源侧电压暂降; 0.3-0.4s治理源侧电压暂升; 0.5-0.6s治理电机启动引起的电压暂降; 0.7-0.8s治理变压器励磁引起的电压暂降; 0.9-1.0s治理短路故障带来的不平衡问题。 ,DVR模型; Matlab simulink; 治理电能质量问题; 仿真时长; 电压暂降; 电压暂升; 电机启动; 变压器励磁; 短路故障。,Matlab Simulink中的DVR模型2.0:电能质量问题的动态治理策略

    COMSOL仿真技术研究偶极光源特性与应用,COMSOL仿真技术下的偶极光源研究与应用,comsol仿真偶极光源 ,comsol仿真; 偶极光源; 偶极子辐射; 仿真建模,Comsol仿真:偶极光源模

    COMSOL仿真技术研究偶极光源特性与应用,COMSOL仿真技术下的偶极光源研究与应用,comsol仿真偶极光源 ,comsol仿真; 偶极光源; 偶极子辐射; 仿真建模,Comsol仿真:偶极光源模拟与优化研究

    基于FPGA的四轴运动控制IP:逻辑控制代码编写与复杂运动规划功能实现,基于FPGA的四轴运动控制IP实现:逻辑VHDL编程,支持多种运动控制算法与mcx314相当性能,基于FPGA的四轴运动控制IP

    基于FPGA的四轴运动控制IP:逻辑控制代码编写与复杂运动规划功能实现,基于FPGA的四轴运动控制IP实现:逻辑VHDL编程,支持多种运动控制算法与mcx314相当性能,基于FPGA的四轴运动控制IP。 纯逻辑vhdl代码编写。 支持回零,直线圆弧插补,小直线速度前瞻,梯形加减速,S型加减速等。 性能等同于mcx314. ,基于FPGA的四轴运动控制IP; 纯逻辑Vhdl代码编写; 回零功能; 插补功能(直线、圆弧); 速度前瞻; 梯形加减速; S型加减速; 性能等同MCX314。,基于FPGA的Vhdl四轴运动控制IP:高性能、灵活配置的S型加减速插补器

    机器人控制系统及设计程序.zip

    机器人控制系统及设计程序,含仿真程序、控制系统及代码。

    基于STM32的自动寻路消防小车的研究.caj

    1、以上文章可用于参考,请勿直接抄袭,学习、当作参考文献可以,主张借鉴学习 2、资源本身不含 对应项目代码,如需完整项目源码,请私信博主获取

    基于博途1200 PLC与HMI的十层二部电梯控制系统仿真工程:实现集群运行与优化配置的研究实践,基于博途PLC及HMI的十层二部电梯控制系统仿真与优化实践,基于博途1200PLC+HMI十层二部电梯

    基于博途1200 PLC与HMI的十层二部电梯控制系统仿真工程:实现集群运行与优化配置的研究实践,基于博途PLC及HMI的十层二部电梯控制系统仿真与优化实践,基于博途1200PLC+HMI十层二部电梯控制系统仿真 程序: 1、任务:PLC.人机界面控制双部电梯集群运行 2、系统说明: 系统设有上呼、下呼、内呼、手动开关门、光幕、检修、故障、满载、等模拟模式控制, 系统共享厅外召唤信号,集选控制双部电梯运行。 十层二部电梯途仿真工程配套有博途PLC程序+IO点表 +PLC接线图+主电路图+控制流程图, 附赠:设计参考文档(与程序不是配套,仅供参考)。 博途V16+HMI 可直接模拟运行 程序简洁、精炼,注释详细 ,基于博途1200PLC; HMI双部电梯控制; 电梯控制模式; 控制系统仿真; 博途V16+HMI模拟运行。,基于博途1200的十层二部电梯控制系统仿真程序

    COMSOL流体仿真下的流固耦合现象:圆管内流体驱动物块移动与扇叶转动探究,COMSOL流体仿真:流固耦合下的圆管内流体驱动动态模拟-流体驱动物块移动与扇叶转动研究,comsol流体仿真 ,流固耦合

    COMSOL流体仿真下的流固耦合现象:圆管内流体驱动物块移动与扇叶转动探究,COMSOL流体仿真:流固耦合下的圆管内流体驱动动态模拟——流体驱动物块移动与扇叶转动研究,comsol流体仿真 ,流固耦合,圆管内流体驱动物块的移动和 流体驱动扇叶的转动 ,comsol流体仿真;流固耦合;圆管内流体驱动物块移动;流体驱动扇叶转动,Comsol流体仿真:圆管内流固耦合与流体驱动的物块移动及扇叶转动研究

    基于提示工程的 OpenAI GPT-4o 和 DeepSeek R1 在科学文本分类中的比较分析

    本研究探讨了大型语言模型如何通过提示工程对科学论文中的句子进行分类。我们使用两种先进的基于网络的模型,OpenAI 的 GPT-4o 和 DeepSeek R1,将句子分类为预定义的关系类别。DeepSeek R1 已在其技术报告中测试过基准数据集。然而,其在科学文本分类中的性能尚未得到充分探索。为解决这一问题,我们引入了一种专门为该任务设计的新评估方法,并整理了一个来自多个领域的清洁科学论文数据集。该数据集提供了一个比较这两个模型的平台。通过使用此数据集,我们分析了它们在分类中的有效性和一致性。

    【RCS雷达】基于matlab RCS雷达模拟器仿真【含Matlab源码 9808期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    三相逆变整流并网技术:正负序分离消除负序电流,保障光伏风力发电系统电流三相对称的研究,三相逆变整流并网技术的正负序分离与负序电流消除策略在电网电压不平衡跌落中的应用-适用于光伏与风力发电系统,三相逆

    三相逆变整流并网技术:正负序分离消除负序电流,保障光伏风力发电系统电流三相对称的研究,三相逆变整流并网技术的正负序分离与负序电流消除策略在电网电压不平衡跌落中的应用——适用于光伏与风力发电系统,三相逆变 整流并网,正负序分离,在电网电压不平衡跌落 平衡跌落时,消除负序电流,维持电网电流三相对称,可用于光伏和风力发电系统 有参考文献 ,三相逆变;整流并网;正负序分离;电网电压不平衡跌落;消除负序电流;光伏和风力发电系统;参考文献,三相逆变整流并网技术:电网电压不平衡下的负序电流消除策略

    基于51的多参数水质监测与报警系统设计20250304

    题目:基于51单片机的多参数水质监测与报警系统设计 主控:AT89C51 显示:LCD1602 DS18B20温度传感器 浊度传感器(PCF8591+滑动变阻器模拟) PH传感器(ADC0832+滑动变阻器) 声光报警 led*4 功能: 1.实时检测水质温度、浊度、PH 2.实时显示相关数据 3.可以通过按键修改阈值 4.各数值不在标准范围内启动声光报警 5.ph低于下限红色小灯点亮;ph高于上限绿色小灯电亮;温度低于阈值蓝色小灯电亮;浑浊度高于阈值橙色小灯电亮

    【车间调度】基于matlab粒子群算法求解作业车间调度问题(目标函数:机器间隙时间)【含Matlab源码 4178期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    Java网络编程核心技术与实战教程:涵盖基础、高级技术和案例分析

    内容概要:本文档《Java网络编程教程》详细介绍了Java在网络编程中的应用,覆盖了从基础知识到高级技术的各个层面。首先讲解了网络编程的概念和Java提供的相关库如java.net和java.nio,以及基于这两个库的Socket和非阻塞I/O的编程技巧,随后深入探讨了多线程并发处理、数据流的操作及网络数据格式(JSON与XML)。接着文档讨论了实践中常用的技术,如HTTP编程、聊天室应用的开发和异常处理。此外,还介绍了Java NIO的Buffer、Channel和Selector机制及其性能优化策略,分布式系统的RPC、RESTful API、消息队列和分布式缓存等内容。最后,探讨了网络安全方面的知识,包括SSL/TLS协议、数据加密技术和防火墙配置。 适合人群:适合初学者至中级水平的Java程序员,尤其是那些想深入理解和掌握Java在网络编程中的各类应用和技术的人群。 使用场景及目标:文档旨在使开发者深入了解并熟练掌握Java在网络编程领域的应用,从而能够独立开发高可靠性的网络应用程序和服务。无论是创建简单的客户端还是复杂的服务器端程序,或是参与大规模分布式的项目都适用。 其他说

    【车间调度】基于matlab雾凇算法RIME求解零空闲流水车间调度问题NIFSP【含Matlab源码 7981期】.mp4

    海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    基于模型预测控制的车辆换道轨迹跟踪:五次多项式换道轨迹设计与Matlab与Carsim联合仿真研究,基于模型预测控制的车辆换道轨迹跟踪研究:五次多项式换道轨迹与Matlab-Carsim联控应用,基于

    基于模型预测控制的车辆换道轨迹跟踪:五次多项式换道轨迹设计与Matlab与Carsim联合仿真研究,基于模型预测控制的车辆换道轨迹跟踪研究:五次多项式换道轨迹与Matlab-Carsim联控应用,基于模型预测控制(mpc)的车辆道,车辆轨迹跟踪,道轨迹为五次多项式,matlab与carsim联防控制 ,基于模型预测控制(MPC)的车辆换道; 车辆轨迹跟踪; 换道轨迹五次多项式; MATLAB与CARSIM联防控制,基于MPC的车辆换道控制:五次多项式轨迹跟踪与Matlab-CarSim联合仿真

    MATLAB Simulink单相并网逆变器主动移频法(AFD)孤岛检测仿真系统:全面集成高效响应与智能频移的电力安全保障技术,MATLAB Simulink单相并网逆变器主动移频法(AFD)孤岛检测

    MATLAB Simulink单相并网逆变器主动移频法(AFD)孤岛检测仿真系统:全面集成高效响应与智能频移的电力安全保障技术,MATLAB Simulink单相并网逆变器主动移频法(AFD)孤岛检测仿真系统:全面集成高效响应与智能频移的电力安全保障技术,MATLAB simulink单相并网逆变器主动移频法(AFD)孤岛检测仿真系统,附相关说明。 全面仿真架构:本系统集成了单相电网、逆变器、滤波模块、PI控制器、PWM信号发生器、锁相环、AFD控制器S函数以及高精度测量模块,构建了一个完整且精确的仿真环境。 先进检测技术:采用前沿的主动移频法(AFD)进行孤岛检测,该技术通过智能调整逆变器输出电流的频率参考,有效识别孤岛状态,确保电力系统的安全稳定。 高效响应与精准检测:AFD算法设计巧妙,响应速度快,检测精度高,能在第一时间发现并响应孤岛事件,有效防止潜在的安全隐患。 智能频移机制:主动移频法(AFD)的核心在于,它通过在公共点电压频率上施加一个固定偏移量作为逆变器输出电流的参考频率。 电网正常供电时,电流频率受电网频率约束保持稳定;电网失电,逆变器参考电流频率中的偏移量将驱动本地

    基于直驱永磁同步技术的风力发电机MATLAB仿真模型的研究与实现,直驱永磁同步风力发电机的MATLAB仿真模型构建与应用研究,直驱永磁同步风力发电机MATLAB仿真模型 ,直驱永磁; 同步风力; 发电

    基于直驱永磁同步技术的风力发电机MATLAB仿真模型的研究与实现,直驱永磁同步风力发电机的MATLAB仿真模型构建与应用研究,直驱永磁同步风力发电机MATLAB仿真模型 ,直驱永磁; 同步风力; 发电机; MATLAB仿真模型; 核心关键词,MATLAB仿真模型:直驱永磁同步风力发电机

    基于STM32的多功能智慧照明系统设计.pdf

    1、以上文章可用于参考,请勿直接抄袭,学习、当作参考文献可以,主张借鉴学习 2、资源本身不含 对应项目代码,如需完整项目源码,请私信博主获取

Global site tag (gtag.js) - Google Analytics