原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。
现在,给你一个机会,来吐槽别人的方案或者代码,该从何开始?
是不是觉得有千言万语想要迸发,弄到最后只想起个代码命名问题?如果你是java,你会想到《粑粑开发规范》,可那还是代码层面的。包括把sonar
给上了,也是发现一些浅显的问题。
现在的开发人员良莠不齐,为了将风险尽量消灭在萌芽中,需要一些手段。其中一种手段就是技术评审,用群众雪亮的眼睛,来悬崖勒马。
1、技术评审分类
技术评审会挤占产品开发的时间,但会提高产品的质量、软件的性能、拥有良好的扩展性、易于重构,长远来看是泽被后人的事情。
如果对单体的研发能力并不能完全掌握,那一定要坚持技术的评审,可以让你免去很多无聊低级的故障和缺陷。
但鉴于目前大部分开会抓不住重点的现状,偏题是常见的。要正确面对技术评审,不要开出火药味,也不要走过场,这是两个极端。
对于技术研发,我大体将研发技术评审分为三类。鉴于篇幅问题,点到为止。
根据一般软件的开发过程。大体可分为:方案评审、设计评审、代码评审。很多时候,我们仅仅关注代码评审,对一些结构问题发现的晚,造成了代码质量很高但整体质量很差的后果。
2、方案评审
2.1、方案背景
1、阐明方案要解决的问题、危害。
也就是简单的立项原因。假如问题不成立,则设计无意义。
2、尽量一个方案解决一个主要问题。
最后把同一周期的问题串联,看是否整体最优。所谓先分后总,不可只照顾自己那一块。
2.2、可落地
1、方案要能够落地,过渡,不能偏离实际,构建一个乌托邦。
要根据公司可协调的资源进行设计。比如,一个不想花大价钱买服务器的公司,并不适合把日志打印的太详细,保存的时间过长。
2、代价要尽量小,能够分步骤进行,可阶段性验收。
对于周期稍长的功能,要有里程碑
,以便对外同步和进度追踪时,能够有章可循。
2.3、是否引入新组件
1、能否利用先有资源完成需求。
理想很丰满,现实很骨感。好的方案并不一定是业界最优方案。引入一个新组件的成本是非常大的,哪怕它很稳定。
2、新组件的调研和维护。
如果确实需要引入一些组件,要有基本的调研,以及对以后组件维护的考量。
2.4、良好的扩展性
1、方案要有前瞻性,避免短期内重构。
这个一般看到2-3年就ok了,但要避免短视,不到半年推翻重来的那种。
2、要有良好的扩展性。
扩展性必然会增加模块的个数和对外接口的数量,要和上面的“可落地”相配合,不能顾此失彼。一般说来,提供能够扩展的接口能力,即表示有不错的扩展性。
2.5、涉及的组和人
1、研发资源的投入。
对参与人员的能力有较好的把控,不定差距太大的目标,这就要求对任务的拆解要详细,能够掌握对难点问题的处理。
2、多部门沟通协调。
如果功能涉及到公司的多个部门,对其他部门的能力和工期考量也要计算在内,主要人员全程参与是必要的。
3、设计评审要点
3.1、提供设计图
1、需要留下能够被看懂的文档设计图。
设计一般会随着问题的深入而产生细微的变化,但整体的思路是不会变的。设计图可以减少一次次沟通的成本,避免重复性的讨论。
2、能够体现设计者的简单意图。
设计图要简洁,突出主要功能。次要功能可以辅以附加图解释,不可喧宾夺主,忽略了主要业务的评审。
3、遵循已有规范和架构。
任何公司都会有自己的规范和架构,水土不服的设计,注定了未来的坎坷。要在充分了解公司现状的前提下,进行设计的修正。
4、是否考虑遗留接口处置。
许多开发人员喜欢开发新功能,对待遗留代码如同臭狗屎。设计阶段就需要考虑这些因素,对于遗留接口的适配、扩展、下线问题,代表了未来bug的数量。
5、是否考虑历史数据处置。
设计方案如果需要修正历史数据,这个过程就危险的多。你的任意一个字段的删减、变更,都可能引起非常严重的后果。大体的设计原则是只加不减进行过渡 。
6、是否考虑新旧方案并行、回退。
很多时候,你的新设计需要和旧的功能并行,这种时候,要考虑旧方案的下线影响和周期;如果你的设计是为了替换旧功能,就要考虑在发生严重问题时的回退,这通常能够保命。
3.2、降低复杂性
1、对复杂性进行评估。
一般情况下,复杂性体现在以下方面:1)调用链过长 2)程序策略复杂无法落地 3)跨库、跨存储 4)使用了缓存 6)使用了异步。
以上每一个点,大多数情况下都是可以进行优化的,也是疑难bug的发生地。邀请几个对业务熟悉的人,以及对分布式应用问题敏感的开发人员参与,可以及早的规避问题。比如,提到缓存,就能想到数据同步、穿透、雪崩、容量等问题,就叫做技术敏感
。
针对设计内用到的每个组件,都可以进行“技术敏感”型评审。
2、裁剪不必要组件。
组件如无特殊必要,不要引入,优先借助公司现有设施完成。不能管生不管养。
3.3、验证方式
1、单元测试设计。
你的设计,能否方便的进行单元测试。如果不能进行单元测试,该如何验证一些逻辑的正确性。
2、接口测试设计。
你的设计,收否将所有的功能揉在了一块,牵一发而动全身,无法进行接口测试。存在此问题的设计有很多,比如使用未知的json(字符串)进行数据传输、一次性传输多个冗余、干扰性数据等。
3.4、高可用(服务)
1、服务分级。
你的设计,以及功能,所处的地位。是否需要更多资源,来保证更高的SLA级别。是否需要弹性部署或者预留资源?是否有不可预料的请求尖峰?
2、上下游影响提醒。
你正在设计的功能,对上下游的影响。对上游,是否可以做到承诺的服务级别(一般SLA会比上游服务的略高)。对下游,就要考虑是突发流量的发源地:一般来源于定时任务、或者多线程。
3.5、高可靠(数据)
1、数据一致性。
发生极端情况(比如某些重要组件死亡)后,数据是否会发生不一致。一般的服务降级,都会引起数据的一致性问题。这部分可以没有自动化的修复方案,但要对修复的难易程度进行初步评审,如果难度过大,要通过记录冗余信息的方式进行解决。
2、模拟演练。
在上线之前,对可能的节点进行模拟演练。可物理演练,也可纸上谈兵。
3.6、资源
1、确定各部门资源。
设计阶段确定详尽的部门协调资源,确定整个流程中的短板部门,进行资源倾斜。
2、排期。
按照里程碑对功能进行拆解、排期,此部门要能够达到估计大体工作量的程度。
3.7、风险
1、是否有技术难点?
技术开发同样存在28原则。几个技术难点,可能会占据你80%的时间。这些问题通常会阻塞到最后才会被解决,你需要找到一个Mock的方式,默认已经打通了这些通道。
2、是否有业务风险?
相关功能是否违反了相关法律法规?是否收集了不该收集的东西?是否某些敏感信息没有做脱敏处理?如果这些都不是你来确认,那就默默的闭嘴。
3、安全。
某些安全问题要提前预知到,比如恶意注册、限流、封禁等。如果资源有限,这些通常是优先级比较低的。在成长为大象之前,能够盯上你的都是蚂蚁。
4、代码评审要点
4.1、自动化代码审查结果
1、哪个级别必须处理。
使用sonar初步扫描,能够发现很多问题。这避免了引经据典(特指开发规范)的情况。自动化的东西总比记在脑子里的东西更加可信。
4.2、double评审
1、审主要处理逻辑。
2、审异常处置。
3、审性能。
4、审提示信息。
5、审注释。
以上,是一个优秀的开发者都需要掌握的内容。处理逻辑的正确性,是功能通过验收的基本,但是出问题的通常是一些比较隐蔽的地方。
一些异常会暴露敏感信息,或者走向了不可预料的分支。一些错误提示会显得不友好
,给使用者造成很多困扰。一些注释信息会偏移实际,尤其是在开发人员不稳定的情况下。
此步骤的评审,360度无死角。
End
许多公司,是没有过剩的能力进行技术评审的,开发人员也如公交车一般上下,这也是时间越久积毒越深的缘故。
不要为了评审而评审,评审是为了解决问题的,不是为了形式。假如你每次都把会开出流水账一般的感觉,所有人都连连点头(瞌睡),那不是流程有问题,是你在官僚的路上中毒已深。
作者简介: 小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。