Checkstyle, FindBugs, PMD, VisualVM四种代码检测工具的比较与相关心得


l  CheckStyle专注于格式方面的规范,如行内不能有tab符、‘{’前要有空格等。这些要求往往很少和代码逻辑相关,而是更加关心程序员的编码风格和编码习惯,他要求程序员要写出不仅好用,而且好看、好读的代码。由于不同公司,或者说不同标准,对于一个优秀的代码风格拥有不一样的要求,所以不同的配置文件对CheckStyle检测出来的错误影响极大。我们在运用CheckStyle中的谷歌标准检查代码时,曾经检测出来一千多个错误,因为eclipse在每一行都自动加了tab符来控制缩进,这在谷歌标准中是不允许的,所以这一个错误在每一行都出现,一共出现了超过600次。因此,在我们看来,使用CheckStyle来检查代码,选择一个合适的配置文件十分关键。当然,我们可以自己来修改每一项标准,虽然很繁琐,但这样的标准一定最适合我们的要求。

l  PMD更加关注代码执行时可能会产生的潜在错误,它十分严格,会尽量帮你检测出所有可能导致错误的元素。比如说,它要求你不能在循环中实例化对象,不能直接使用数字作为常量,不能调用HashMap和ArrayList这些数据类型,而要直接调用它们的接口。PMD给人的感觉,更像一位谨慎且经验丰富的老者,它能准确的指出所有可能在将来给你带来麻烦的细节,然后指导你去一个一个地改进。有的时候,它似乎显得有些多虑,或者说过于谨小慎微,但这种一丝不苟、对待潜在BUG毫不松懈地精神,却是在以后地代码使用和代码维护中,可以给我们省下大量的时间和精力。另外在个人配置方面,PMD可以通过导入配置文件的方法,来便捷的修改检查标准,当然,我们也可以通过手工修改细节,来使得配置文件满足我们自己的个性化需求。

l  FindBugs专注于处理文件中潜在的BUG。它和前两者查出的错误种类中有部分重合,如在BAD_PRACTICE一类错误中,就会检测一些命名规范的问题,还有在MALICIOUS_CODE一类错误中,可能会提醒你增加final关键字。当然,FindBugs能看到的也远不止这些表层的事情。他会提你考虑到极端情况下可能出现的错误,比如两个数相加之后做除法,它会想到如果两个加数过大,造成溢出,这时的除法结果就可能出错,它会提醒你用更稳定的位运算来在此时实现除法。FindBugs除了检查程序运行时可能出现的错误,还可以帮助你提高代码的时空性能。当你的代码,因为引用了一些不必要的结构,或者创建了不必要的对象,而消耗了更多的时间和空间时,它就会提醒你在相应的位置上做出优化。在相关的配置方面,FindBugs不能像PMD一样通过搜索来迅速选择自己需要调整的配置,因此显得有些繁琐,不过它也依旧可以人为的调整细节配置,可以对代码进行最符合我们要求、最适合我们的检查。

l  VisualVM是一款可视化程序性能分析工具,它可以在程序运行的同时,动态的监听CPU使用情况、内存占用情况等程序性能指标,然后通过可视化界面将其展现出来,通过对这些结果的分析,我们可以更加准确的知晓代码运行时的性能究竟如何。在测试时,我们可以手工的输入各种类型的数据,来更加全面的测试代码的性能。VisualVM也可以给出具体每个函数运行时的性能指标,主要是CPU使用情况和内存占用情况,让我们更加精准的定位到代码内效率较低的点,可以有效的分析代码运行时性能的短板,并作出有针对性的修改,从而提高代码整体的效率。通过VisualVM,我们可以省去大量分析代码时间、空间复杂度的时间,也可以更加精准、更加细致的洞悉代码的效率如何,这为我们的编码工作,提供了很大的便捷,也大大提高了我们所编写的代码的效率。

l  在我看来,“代码是否符合编码规范”是个广义的概念。当然,如果这专指诸如变量命名、首行缩进、’{}’符号的位置等等,这和代码执行时的时间空间复杂性并没有直接的联系,因为代码的时空复杂度时主要是由代码逻辑决定的,代码整洁与否、美观与否,并不能直接影响到代码运行时的效率。或许一段看起来乱七八糟的代码会让维护它的程序员心情很糟、难以下手,但这并不能确定它一定是一段效率很低的代码。

l  但是,如果这里的“编码规范”含义更广一些,比如说,包括了之前三种工具CheckStyle、PMD、FindBugs所能发现的所有错误,那么它必然会直接影响到代码的效率。举个例子,FindBugs中有一种错误叫做PERFORMANCE,其关心的主要就是影响代码运行效率的错误。有时你错误的新建了一个冗余的对象,这就会提高代码的时空复杂度,这个时候,你通过调用函数来实现同样的功能,就能提高代码的效率。再比如说,如果你通过if语句的判断,来决定返回false或者true的话,PMD就会提醒你去掉if语句,直接返回判断的结果,这样也可以有效的提高代码的效率。这样的例子还有很多,一些不好的语法习惯,可能会导致程序性能的降低,因此,在这种情况下,代码是否符合编码规范,和代码的时间空间复杂度是有直接联系的。

l  在我们学习编写代码的初期,代码优化看似是一种繁琐、无趣且累赘的事情,因为那时候的代码比较简单,我们往往可以通过很短的代码,方便地实现目标功能,无须进行代码优化。而当时地代码逻辑也很简单,所以杂乱地代码风格不会影响到我们理解代码,自然而然地,我们就不愿意花时间去注意这些代码规范。但是随着更加深入地学习了编程技术,接触了也尝试动手编写了更加复杂地代码,我们才渐渐意识到了代码风格、代码优化地重要性。因为大型的代码往往逻辑比较复杂,我们很难凭借记忆将其完全记住,另外编写这些代码往往耗时更长,经常会经历几天、几周、甚至几个月。这种情况下,在我们代码编写过程中,可能会发现自己已经忘记了前面的逻辑和思路,此时,如果放在我们面前的,是一团杂乱无章的、没有注释的、变量名没有实际意义的代码,那么这个工程就很难推进下去了。更严重的是,如果这是一个多人合作的项目,那么杂乱的代码会给你们的沟通和协作造成难以跨越的沟壑,你们的团队最终只能分崩离析,工程项目也难以完成。这时,代码风格的重要性就完完全全的体现出来。另外,对于一个复杂的项目,在它真正完工之前,我们往往很难精确的了解它的效率如何,此时,我们需要在最后对其进行代码测试,并根据测试结果对其进行相应的代码优化,排除其中可能存在的BUG,并对它的性能进行改进。这些,在大型项目和多人合作项目中,尤为重要。

最后,在我看来,代码风格的确立,靠的是平时习惯的养成,而不是先随意乱写一通,最后通过代码优化来改进版面,因为这样的工作效率及其低下。在本次实验中,当我们第一次用CheckStyle来检查代码时,报出了超过一千个错误,这对于我们两个人而言,几乎时不可能逐条修改的。因此,在平时编写代码时,就要严格要求自己,时刻遵守编码规范,养成一个良好的代码风格。尽管在一开始,这样的行为可能会暂时降低我们的编码效率,但就长远而言,养成良好的编码习惯,是让一个程序员受益终身的事情。

你可能感兴趣的:(软件工程)