1、实现语言不限,通过单元测试验证程序的正确性(附测试结果和截图)
2、通过效能分析工具对比代码分析结果
1、什么是单元测试?
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。
在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在像C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。
经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。
②在MaxArry.java类中编写处理数组中最大的子数组之和的程序,代码如下:
package demo; public class MaxArry { public static void main(String[] args) { // TODO Auto-generated method stub int n = 6; int a[] = {1,2,3,-3,2-5}; int result; result = MaxSum(a,n); System.out.println("最大子数组和为:"+ result); } public static int MaxSum(int[] a,int n) { int Max_a = 0; int Max[] = {0,0,0,0,0,0,0}; for(int i = 0;i < n;i++) { int s[] = {0,0,0,0,0,0}; for(int j = 0;j < n - i;j++) { for(int z = j;z <= j + i;z++) { s[j] = s[j] + a[z]; } if(j == 0) { Max[i] = s[j]; } if(s[j] > Max[i]) { Max[i] = s[j]; } } if(Max_a < Max[i]&&i != 0) { Max_a = Max[i]; } } return Max_a; } }
③在测试类(MaxArryTest,java)中编写测试用例,我编写了6个测试类,代码如下:
package demo; import static org.junit.Assert.*; import org.junit.Test; public class MaxArryTest { @Test public void test1() { int[] a1 = {1,2,3,4}; assertEquals(10,new MaxArry().MaxSum(a1,4)); } @Test public void test2() { int[] a2 = {2,22,0,10,17}; assertEquals(51,new MaxArry().MaxSum(a2,5)); } @Test public void test3() { int[] a3 = {-4,-2,0,-12,-1}; assertEquals(0,new MaxArry().MaxSum(a3,5)); } @Test public void test4() { int[] a4 = {-1,20,-5,30,-4}; assertEquals(45,new MaxArry().MaxSum(a4,5)); } @Test public void test5() { int[] a5 = {0,0,0,0,0}; assertEquals(0,new MaxArry().MaxSum(a5,5)); } @Test public void test6() { int[] a6 = {-2,-4,0,1,12}; assertEquals(13,new MaxArry().MaxSum(a6,5)); } }
④运行Java测试类,得到运行结果如下图所示:
由此图可知本次实验的测试类全部成功。
使用Jprofiler工具对上面所写的Java代码进行效能分析。
1、使用可视化工具分析得到的图如下所示:
2、Live momery (内存视图)
JProfiler的内存视图部分可以提供动态的内存使用状况更新视图和显示关于内存分配状况信息的视图。所有的视图都有几个聚集层并且能够显示现有存在的对象和作为垃圾回收的对象。
①All Objects (所有对象)
显示类或在状况统计和尺码信息堆上所有对象的包。你可以标记当前值并显示差异值。
②Record Objects (记录对象 )
显示类或所有已记录对象的包。你可以标记出当前值并且显示差异值。
③Allocation Call Tree (分配访问树)
显示一棵请求树或者方法、类、包或对已选择类有带注释的分配信息的J2EE组件。
④Allocation Hot Spots (分配热点)
显示一个列表,包括方法、类、包或分配已选类的J2EE组件。你可以标注当前值并且显示差异值。对于每个热点都可以显示它的跟踪记录树。
⑤Class Tracker (类追踪器)
类跟踪视图可以包含任意数量的图表,显示选定的类和包的实例与时间。
3、Heap walker (堆遍历)
在JProfiler的堆遍历器(Heap Walker)中,你可以对堆的状况进行快照并且可以通过选择步骤下寻找感兴趣的对象。堆遍历器有五个视图.
①Classes (类 ):
显示所有类和它们的实例,可以右击具体的类"Used Selected Instance"实现进一步跟踪。
②Allocations(分配)
为所有记录对象显示分配树和分配热点。
③References(索引)
为单个对象和“显示到垃圾回收根目录的路径”提供索引图的显示功能。还能提供合并输入视图和输出视图的功能。
④Time(时间)
显示一个对已记录对象的解决时间的柱状图。
⑤Inspections(检查 )
显示了一个数量的操作,将分析当前对象集在某种条件下的子集,实质是一个筛选的过程。
⑥-Graph(图表)
你需要在references视图和biggest视图手动添加对象到图表,它可以显示对象的传入和传出引用,能方便的找到垃圾收集器根源。
4、CPU views(cpu视图)
(1)
JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。
①Call Tree(访问树)
显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分。
②Hot Spots(热点)
显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求,JDBC,JMS和JNDI服务请求以及按照URL请求来进行计算。
③Call Graph(访问图)
显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。
④Method Statistis(方法统计)
显示一段时间内记录的方法的调用时间细节
(2)在快照左侧选择CPU视图,点击到调用树,可以在右侧看到每个函数占用的CPU时间,图片如下:
(3)在快照左侧选择CPU视图,点击到热点图,图片如下:
(4)异常值检测
5、Threads(线程视图)
JProfiler通过对线程历史的监控判断其运行状态,并监控是否有线程阻塞产生,还能将一个线程所管理的方法以树状形式呈现。对线程剖析。
①Thread History(线程历史)
显示一个与线程活动和线程状态在一起的活动时间表。
②Thread Monitor(线程监控)
显示一个列表,包括所有的活动线程以及它们目前的活动状况。
③Thread Dumps(线程转储)
显示所有线程的堆栈跟踪。
6、Monitor &locks
①Current Locking Graph (当前锁定图表)
显示JVM中的当前锁定情况。
②Current Monitors (当前监视器)
显示当前正在等待或阻塞中的线程操作。
③Locking History Graph(锁定历史图表)
显示记录在JVM中的锁定历史。
④Monitor History(监控器历史)
显示等待或者阻塞的历史。
⑤Monitor Usage Statistics(监控器使用统计)
计算统计监控器监控的数据。
通常一个方法的执行时间越长则占用CPU的资源则越多,在JProfiler里就是通过方法的执行时间来描述对CPU的使用情况。
通过CPU views视图的Method Statistics子视图可以看到一段时间里涉及类方法的执行时间,这些时间是从开始记录到查看该视图这段时间所发生的执行时间的合计,如此可以准确反映出真实场景下的方法执行情况。
一般是用LoadRunner压一段时间后再查看该视图,通过占用时间的不同,找出系统里最耗时的类方法进行调优解决问题。
发现执行一次请求,响应时间不能满足需求时,通过这种CPU时间占有的方式分析可优化点是一种简单而有效的方式。
线程的运行情况可以直接反应出系统的瓶颈所在,对线程一般有以下三个关注点:
通过Threads视图可以观察到项目的线程情况,如下图所示:
以上就是本次实验的全部代码以及分析,欢迎大家讨论!
原文:https://www.cnblogs.com/lzw111/p/14523708.html