首页 > 技术文章 > 开发中Design Review和Code Review

rxysg 2021-12-09 16:40 原文

一.Design Review

详解

翻译为设计评审,也就是对需求设计进行审核,防止出现异常问题,例如下面的这些

可用性

  • 外部依赖有哪些?如果这些外部依赖崩溃了我们有什么处理措施?
  • 我们SLA是什么?主要是指可用性目标几个9? 50/90/99分位数的响应时间是多少? QPS是多少?
  • 我们的超时、重试、过载保护、服务降级机制是什么?如何避免雪崩
  • 我们的调用方有哪些?分别有什么服务配额?是否需要对关键的服务调用方单独部署?

运维

  • 我们都有配置了哪些监控?如果出现问题,我们需要查看哪些信息?这些信息是否都有记录?
  • 报警的处理流程是什么?
  • 系统上线流程和步骤是什么,出了问题后是否可以回滚,以及怎么回滚?

安全

  • XSS,CSRF,SQL注入这些是否需要处理?
  • 3防怎么搞:防抓,防DDOS,防恶意访问
  • 是否有请安全团队review
  • 是否有风控的需求?
  • 信息存储时是否设计到密码,信用卡,身份证等敏感信息,这些信息是怎么存储和访问的?
  • 系统是否符合公司的安全规范(SSO, 接口认证)?关键业务操作是否可审计(可回溯谁在什么时间干了什么操作)

扩展性

  • 分层,分模块怎么拆分比较合理?拆分出来的模块可以搞成服务单独部署吗?
  • 应用层可以水平扩展吗?有用session吗?可以去掉session吗?
  • 如果系统的负载提升到以前的3到10倍,当前系统是否依然可用
  • 存储层面如果需要扩展存储怎么做?
  • 系统中有哪些上下依赖的节点/系统/服务?这些依赖是否会导致无法并行开发?能否去掉这些依赖?
  • 是否有数据访问API? 数据API的设计对性能的考虑是什么?数据API对异常数据(超大数据集、空数据集、错误数据、schema异常...)的处理是什么?

存储

  • 数据计划怎么存储?会有可能的性能瓶颈吗?需要考虑一些缓存方案吗?
  • 有什么复杂SQL可能会导致慢查询吗?
  • 数据库的操作什么地方用了事务?什么情况会导致锁竞争?我们的锁策略是什么?一致性和可用性如何平衡?未来如果分库分表会有什么影响?
  • 缓存失效会有什么影响?缓存大量失效会有什么影响?冷启动有问题吗?有热点数据吗?多个缓存节点需要权衡可用性和一致性吗?
  • 存储时,是否需要分库,分表,选择的理由是什么?

技术选型

  • 开发语言是什么,框架是什么为什么用他们?
  • 缓存用什么(tair/medis/redis/memached),web server用什么?(nginx+php fpm, apach php扩展,jetty,tomcat,jboss),消息队列用什么(rebbitmq/beanstalk/kafka/mafka)?为什么用它们?
  • DB是否可以用、以及用哪种no sql(hbase, tair)来优化?
  • 业界或者其他团队是否有处理过类似问题?他们是怎么处理的?是否可以copy或者借鉴?

服务调用和服务治理

  • 请求同步处理还是异步队列处理比较好?
  • 服务接口的URI设计合理吗?可以向下兼容吗?
  • 服务间的调用协议是什么?有公司标准的调用协议可以用吗?
  • 客户端和服务端的调用协议是什么?有公司标准的调用协议可以用吗?
  • 有什么服务治理相关的要考虑的吗?
  • 能否接入otco或者sg做服务治理?

业务监控

  • 正常的业务逻辑外,可能会有哪些奇葩或者恶意的操作?我们应该怎么处理?
  • 除了系统上的监控外,需要什么业务维度的监控吗?
  • log是怎么记的?如果要debug能有什么开关迅速打开吗?log怎么rotate?log会影响性能吗?

复用

  • 项目中有用什么新技术吗?为什么要用新技术?未来其他人接手容易吗?
  • 项目中有什么复杂计算的地方吗?这些计算可以用什么算法优化吗?
  • 这个项目可以抽象出来什么可以复用的东西吗?
  • 项目中的什么可以不用自己做,调用现成服务吗?

推荐方法

根据需求我们需要给出实现方案,如Db 表设计,消息队列设计,代码组织,模块划分,单元测试等等,这是我目前了解到的,我开发的时候还没有做到这么细,也是自己后面努力的方向。

设计好方案以后需要思考是否可以满足我们这次开发的业务需求:

  • 功能是否完善
  • QPS是否合格,当然这个是在我们项目对性能有要求的前提下
  • 线上出了问题是否方面定位和分析
  • 使用是否好用

给出设计方案以后,我们可以思考一下,然后隔一天自己Review一下,如果自己觉得没有什么大的问题的时候,请团队内的同事或者产品经理帮忙Review一下自己的设计和分析,在和同事交流和分析的时候,我们往往会get到我们没有注意到的细节和问题,这也就是Design Review 的重要性了,根据我们讨论和分析得到的问题,给出解决方法和方案,然后再Review一下,如果没有问题,我们接下来就可以进入开发阶段了。

在Design Review的过程中帮我们暴露了我们没有考虑到的问题,提前解决总比我们开发到一半才发现自己的设计有问题,需要重新设计要好的多。同时,不要害怕被指出问题,提早暴露问题总比线上出了问题好的多,还有要有开放和空杯的心态,和同事一起分析和解决问题是成长最快的。

二.Code Review

详解

翻译为代码审查,大白话就是在代码提交后,由管理员或几个人对提交的差异内容进行审核,一般包括如下
常规项:

  1. 代码能够工作么?它有没有实现预期的功能,逻辑是否正确等。
  2. 所有的代码是否简单易懂?
  3. 代码符合你所遵循的编程规范么?这通常包括大括号的位置,变量名和函数名,行的长度,缩进,格式和注释。
  4. 是否存在多余的或者重复的代码?
  5. 代码是否尽可能的模块化了?
  6. 是否有可以被替换的全局变量?
  7. 是否有被注释掉的代码?
  8. 循环是否设置了长度和正确的终止条件?
  9. 是否有可以被库函数替代的代码?
  10. 是否有可以删除的日志或调试代码?

安全:

  1. 所有的数据输入是否都进行了检查(检测正确的类型,长度,格式和范围)并且进行了编码?
  2. 在哪里使用了第三方工具,返回的错误是否被捕获?
  3. 输出的值是否进行了检查并且编码?
  4. 无效的参数值是否能够处理?

文档:

  1. 是否有注释,并且描述了代码的意图?
  2. 所有的函数都有注释吗?
  3. 对非常规行为和边界情况处理是否有描述?
  4. 第三方库的使用和函数是否有文档?
  5. 数据结构和计量单位是否进行了解释?
  6. 是否有未完成的代码?如果是的话,是不是应该移除,或者用合适的标记进行标记比如‘TODO’?

测试:

  1. 代码是否可以测试?比如,不要添加太多的或是隐藏的依赖关系,不能够初始化对象,测试框架可以使用方法等。
  2. 是否存在测试,它们是否可以被理解?比如,至少达到你满意的代码覆盖(code coverage)。
  3. 单元测试是否真正的测试了代码是否可以完成预期的功能?
  4. 是否检查了数组的“越界“错误?
  5. 是否有可以被已经存在的API所替代的测试代码?

推荐方法

Code Review的目的除了提高代码质量,提前发现bug外,还包括统一团队的代码规范,比如经常会碰到有人说你这个变量命名不对,或者这里缩进不应该用tab,甚至这里应当多加一个空白行。而类似架构或者设计模式这样的“大”问题,我个人觉得并不适合在code review的时候去讨论。如果这方面有问题,那说明之前design review没有做好或者有可能根本没有做design review。

像我软内部,我所知道的范围内所有代码都是需要code review的。具体的规则可能每个部门各不相同,比如有的部门给每个组件规定几个owner,改到那块代码必须找至少一个owner做review。有的部门还规定每次code review至少要有一个senior级别以上的码农参与,等等。

从工具上来说,现在的码农还是比较幸福的了。n年以前做code review,就是自己做个bbpack发到邮件上,其实就是一个diff,reviewer就看着windiff,有意见的就拿个小本本记下来:某某行号,某某问题,然后email沟通。

后来车库计划(利用员工闲暇时间随便做点什么的一个计划)里面有人做了一个新的code review工具,叫CodeFlow,极大改善了我们做code review的体验,病毒式地传播到了公司各个部门,可以算是车库计划最成功的项目了。
file

CodeFlow主要把code review的过程做成了一个聊天式的体验,你对哪段code有意见,直接选取那段code然后加个comment,对方就需要对此做出回应。比如你说这个函数名字起的不够优雅,对方可以采取你的意见修改并把这个comment设置成fixed;当然他也可以认为没必要改而设成won't fix;当然你也可以继续和他撕下去。

当review的作者按照意见修改了一遍代码后,他可以发出一个新的iteration(迭代),然后reviewer们在新的iteration基础上可以再次提出新的意见。

最后每个reviewer可以设置此次review的状态,比如reviewing(正在review),或者waiting(在等作者修改),设成signed off就表示通过了。

总的来说大家对CodeFlow还是挺满意的,它的功能现在基本上都在Visual Studio里面整合了,其他答案也已经有人提到Visual Studio的code review功能了。

经验

code review这事儿,与具体的项目以及人员息息相关。人多真的力量大么?其实不尽然。

就我所知道的范围,比较硬核(强制性)的code review基本上都是发生在一个软件产品的后半段。也就是,软件自身已经成型了,甚至是已经交付了,后续的维护以及版本升级阶段。

如果是从零构建一个全新的软件,以我个人的经验来说,大部分情况下不会也不应该enforce(强制)很hardcore(重量级的)code review,因为那是在浪费时间和精力。为啥?因为在软件还未成型的时候,需求往往也是没有完全理清楚的,每个人理解都不同。一群同床异梦的人聚在一起review,往往最后是一群乌合之众。对于这种情况,我个人是倾向于仰仗个人的(也就是靠大牛)。当然,规模大的话也需要一个团队,适当的review需要,但是不是那种一二三四五死板板的做法,主要是团队leader检查实际的实现是否达到预设要求,我管这种叫单向的review,简单来说,水平好的review差的,大牛的代码大牛自己review即可。

不管是项目前期还是后期,要多构建自动化测试,多构建测试用例。前期因为项目需求不确定,测试难以割裂出来交给专门的团队,这时主要是代码编写者自己写测试代码自测。项目定型之后,就可以也应该组建专门的QA团队负责这个事情了。

其实对于大项目,理想上最牛的码农应该都是QA,并且在项目的初期就介入,进行白盒测试(也就是code review)。但是事实上能做到的应该不多。因为实际的软件开发很多都是需求变来变去,设计和编码是交错在一起的,多大的项目最终落实到个人头上都是一人多角色,即是运动员也是裁判。虽然从软件工程和项目管理角度这样很不好,但是确实是普遍存在。

当然诸如下面许多回答答主所在的软件巨头的成熟产品团队,自然是另外一番景象。我写这个回答的目的只是表达那只是事实的一部分,而且很可能是一小部分。

推荐阅读