超时:当你审查代码时,你可能不知道一个操作合适的超时时间,但是你要想一下“如果超时了,会对系统其他部分造成什么影响?”。作为审查者你应该考虑最坏的情况:当发生5分钟的延时,应用是否会阻塞?如果超时时间设置成1秒钟最坏的情况会是怎么样的?如果代码作者不能确定超时长度,你作为审查者也不知道一个选定的时间的好坏,那么是时候找一个理解这其中影响的人参与代码审查了。 并行:代码是否使用多线程来运行一个简单的操作?这样是否花费了更多的时间以及复杂度而并没有提升性能?如果使用现代化的Java,那其中潜在的问题相较于显示创建线程中的问题更不容易被发现:代码是否使用Java 8新的并行流计算但并没有从并行中获益?比如,在少量元素上使用并行流计算,或者只是运行非常简单的操作,这可能比在顺序流上运算还要慢。 正确性 这些不一定影响系统的性能,但是它们与多线程环境运行关系密切,所以和这个主题有关: 代码是否使用了正确的适合多线程的数据结构。 代码是否存在竞态条件(race conditions)?多线程环境中代码非常容易造成不明显的竞态条件。作为审查者,可以查看不是原子操作的get和set。 代码是否正确使用锁?和竞态条件相关,作为审查者你应该检查被审代码是否允许多个线程修改变量导致程序崩溃。代码可能需要同步、锁、原子变量来对代码块进行控制。 代码的性能测试是否有价值?很容易将小型的性能测试代码写得很糟糕,或者使用不能代表生产环境数据的测试数据,这样只会得到错误的结果。 缓存:虽然缓存是一种能防止过多高消耗请求的方式,但其本身也存在一些挑战。如果审查的代码使用了缓存,你应该关注一些常见的问题,如,不正确的缓存失效方式。 代码级优化 对大部分并不是要构建低延时应用的机构来说,代码级优化往往是过早优化,所以首先要知道代码级优化是否必要。 代码是否在不需要的地方使用同步或锁操作?如果代码始终运行在单线程中,锁往往是不必要的。 代码是否可以使用原子变量替代锁或同步操作? 代码是否使用了不必要的线程安全的数据结构?比如是否可以使用ArrayList替代Vector? 代码是否在通用的操作中使用了低性能的数据结构?如在经常需要查找某个特定元素的地方使用链表。 代码是否可以使用懒加载并从中获得性能提升? 条件判断语句或其他逻辑是否可以将最高效的求值语句放在前面来使其他语句短路? 代码是否存在许多字符串格式化?是否有方法可以使之更高效? 日志语句是否使用了字符串格式化?是否先使用条件判断语句校验了日志等级,或使用延迟求值? 简单的代码即高效的代码 Java代码中有一些简单的东西可以供审查者寻找,这些会使JVM很好地替你优化你的代码: 短小的方法和类。 简单的逻辑,即消除嵌套的条件或循环语句。 越是人类可读的代码,JIT编译器越有可能理解你的代码并进行优化。这应该在代码审查中很容易定位,如果代码看上去易理解且整洁,它运行时效率也会越好。 关于安全 你在构建一个安全、稳固的系统所花费的精力,和花在其他特性上的一样,取决于项目本身,项目运行的地方、它使用的用户、需要访问的数据等。我们现在着重看一些你可能在代码审查时关注的地方。 尽可能使用自动化 有惊人数量的安全检查可以被自动化,而不需要人工干预。安全测试不一定要启动所有系统进行完整的渗透测试,一些问题可以在代码级就能被发现。 常见问题如SQL注入或跨站脚本可以在持续集成环境通过相应工具检查出。你也能通过OWASP依赖检测工具自动化检查你依赖中已知的漏洞。 有时需要“看情况” 对有的校验你可以简单回答“是”或“否”,有时你需要一个工具指出潜在的问题,之后再由人工来决定这个是否需要解决。这也正是Upsource真正的闪光点。Upsource显示代码检查结果,审查者可以利用这些来决定代码是否需要改动或还可以接受目前的情况。 理解你用到的依赖 (责任编辑:本港台直播) |