众所周知,在团队中进行代码审查(Code Review)可以提升代码质量,分享项目知识、明确责任,最终达到构建更好的软件、更好的团队。如果你花几秒钟搜索代码审查的相关信息,你会看到许多关于代码审查带来的价值的文章。也有许多方法来进行代码审查:在GitHub中提pull request,或使用像JetBrains的Upsource之类的工具。然而即使拥有清晰的流程和正确的工具,还遗留了一个大问题需要解决——我们需要找寻哪些问题。
可能没有明确关于“我们需要找寻哪些问题”的文章,是因为有许多不同的要点需要考虑。正如任何其他的需求,各个团队对各个方面都有不同的优先级。
本文的目标是列出一些审查者可以找寻的要点,而各个方面的优先级就因各个团队而异了。
在我们继续之前,让我们考虑一下大家在代码审查时会讨论到的问题。对于代码的格式、样式和命名以及缺少测试这些问题是很常见的几点。如果你想拥有可持续的、可维护的代码,这些是有用的检查点。然而,在代码审查时讨论这些就有些浪费时间,因为很多这样的检查可以(也应该)被自动化。
那哪些要点是只能由人工进行审查而不能依靠工具的呢?
回答是有惊人数量的点只能由人工进行审查。在本文剩下的部分,我们会覆盖一系列广泛的特性,并深入其中的两点具体的区域:性能和安全。
让我们深入探讨下性能,这是一个真正能从代码审查中获益的方面。
系统对性能方面的非功能性需求应当同所有架构、设计的领域一样被置于重要位置。无论你是开发只容许纳秒级延时的低延迟交易系统,还是管理“待办事项”的手机应用,你都应该了解用户所认为的“太慢”。
在考虑我们是否需要就代码性能进行代码审查之前,我们应该问自己几个关于具体需求是什么的问题。虽然一些应用确实不需要考虑每毫秒都花费在哪里,对于大部分应用,花费几个小时的折腾进行优化来获得的些许CPU下降的价值也是有限的,但有些地方还是审查者可以检查一下的,进而确保代码不会有一些常见可避免的性能缺陷。
接受审查的代码是否涉及之前发布的服务等级协议(SLA)?或这个需求本身有特别的性能需求?
如果代码导致“登录页面加载太慢”,那原始的开发者需要找出合适的加载时间是多久,不然审查者或作者本人如何确保改进后的速度足够快?
如果有硬性的需求,是否有测试能证明满足了该需求?任何注重性能的系统应该就性能提供自动化测试,这能确保发布的SLA达到预期(如所有订单请求要在10毫秒内处理)。没有这些,你只能依靠你的用户来告诉你没有达到对应的SLA。这不仅是一种糟糕的用户体验,还会带来原本可避免的罚金和支出。
如果你定期运行性能测试或有测试套件可以按需运行它们,那你就需要检查新的代码是否使得性能关键区域的系统性能有所下降。这可以是一个自动化的流程,但由于在持续集成环境中更常运行单元测试而不是性能测试,所以值得特别指出可以在代码审查中检查这项。
任何通过网路来使用外部系统的方式通常会比没有很好优化的方法有更差的性能。考虑以下几点:
代码是否用锁来控制共享资源的访问?这是否会导致性能降低或死锁?
锁是一个性能开销大户,并在多线程环境中很难理清。考虑使用以下模式:单线程写或修改值,其余线程只读,或使用无锁算法。
一些代码一眼就能看出存在潜在性能问题。这依赖于所使用的语言和类库。
这些不一定影响系统的性能,但是它们与多线程环境运行关系密切,所以和这个主题有关:
对大部分并不是要构建低延时应用的机构来说,代码级优化往往是过早优化,所以首先要知道代码级优化是否必要。
Java代码中有一些简单的东西可以供审查者寻找,这些会使JVM很好地替你优化你的代码:
你在构建一个安全、稳固的系统所花费的精力,和花在其他特性上的一样,取决于项目本身,项目运行的地方、它使用的用户、需要访问的数据等。我们现在着重看一些你可能在代码审查时关注的地方。
有惊人数量的安全检查可以被自动化,而不需要人工干预。安全测试不一定要启动所有系统进行完整的渗透测试,一些问题可以在代码级就能被发现。
常见问题如SQL注入或跨站脚本可以在持续集成环境通过相应工具检查出。你也能通过OWASP依赖检测工具自动化检查你依赖中已知的漏洞。
对有的校验你可以简单回答“是”或“否”,有时你需要一个工具指出潜在的问题,之后再由人工来决定这个是否需要解决。这也正是Upsource真正的闪光点。Upsource显示代码检查结果,审查者可以利用这些来决定代码是否需要改动或还可以接受目前的情况。
第三方类库是侵蚀系统安全并引起漏洞的一个途径。当审查代码时至少你要检查是否引入了新的依赖(如第三方类库)。如果你还没有自动化检查漏洞,你应该检查新引入的类库中已知的问题。
你也应该尝试着最小化每个类库的版本,当然如果其他依赖有一个额外的间接依赖,这点可能达不到。但最简单的最小化自己代码暴露在他人代码的(通过类库或服务)安全问题中的方法有:
无论你开发web应用、提供web服务或一些其他需要认证的API,当你增加一个新的URI或服务时,你应该确保它不能在没有认证的情况下被访问(假设认证是你系统的需求)。你只要简单地检查代码的开发者写了合适的测试用例来展示进行了认证。
你应该不只针对使用用户名和密码的人类用户来考虑认证。其他系统或自动化流程来访问你的应用或服务也会需要认证。这可能影响你们系统中对“用户”的定义。
当你保存一些数据到磁盘或通过线缆传输,你需要了解数据是否应该被加密。显然密码永远不应该是简单文本,但是有诸多其他情况数据需要加密。如果被审查的代码通过线缆来传送数据或保存在某地或以其他方式离开你的系统,且你不知道它是否应该被加密,尝试询问下你组织中可以回答这个问题的人。
这里的密码包含密码(如用户密码、数据库密码或其他系统的密码)、秘钥、令牌等等。这些永远不应该存放在会提交到源码控制系统的代码或配置文件中,有其他方式管理这些密码,例如通过密码服务器(secret server)。当审查代码时,要确保这些密码不会悄悄进入你的版本控制系统中。
日志和监控需求因各个项目而不同,一些需要合规,一些拥有比别人严格的行为、事件日志规范。如果你有规章规定哪些需要记录日志,何时、如何记录,那么作为代码审查者你应该检查提交的代码是否满足要求。如果你没有固定的规章,那么就考虑:
安全是个很大的话题,大到足以让你的公司聘请技术安全专家。我们有安全专家就可以获得他们的帮助,如,邀请他们参加代码审查,或邀请他们在审查代码时和我们结对。如果这个无法实现,我们可以充分学习我们系统的环境,来理解我们有哪种安全需求(面向内部的企业级应用和面向客户的网页应用有不同的标准),所以我们可以更好地理解我们应该在代码审查中看什么。
代码审查是一个很好的方式,不仅确保了代码质量和一致性,也在团队中或团队间分享了项目知识。即使你已经自动化了基础的校验,还有许多不同代码、设计的方面需要考虑。代码审查工具,如Upsource,通过在每个代码提交的检查中高亮可疑的代码并分析哪些问题已经被修复,新引入哪些问题,可以帮你定位一些潜在的问题。工具也可以简化流程,因为它提供了一个平台来讨论设计和代码实现,也可以邀请审查者、作者和其他相关人员参加讨论直到达成共识。
最后,团队需要花时间决定代码质量的哪些因素对他们是重要的,也需要专家人工决定哪些规则应用到各个代码审查中,参与到审查中的每个人都应该具备并使用人际交往的技巧,如积极的反馈、谈判妥协以达到最终的共识,即代码应该怎么样才“足够好”可以通过审查。
【作者简介:Trisha Gee为一系列行业开发Java应用程序,包括金融、制造业、软件和非盈利组织,包括各种规模的公司。她在开发Java高性能系统上有丰富经验,并积极帮助开发者使他们拥有高生产率,她也涉足开源开发。Trisha是Sevilla Java用户组和Java Champion的带头人,她信任社区并分享自己的观点,帮助我们从错误中学习,并在成功的基础上继续发展。她是JetBrains技术推广人,也就是说她会不断分享所有有趣的发现。 】
原文来自:聊聊架构
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。
根据给定的手机号、姓名、身份证、人像图片核验是否一致
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。
IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。
结合权威身份认证的精准人脸风险查询服务,提升人脸应用及身份认证生态的安全性。人脸风险情报库,覆盖范围广、准确性高,数据权威可靠。