第4周小组作业:WordCount优化
Posted Nathon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第4周小组作业:WordCount优化相关的知识,希望对你有一定的参考价值。
github地址:https://github.com/JarrySmith/WordCountPro
PSP表格:
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
10 | 10 |
· Estimate |
· 估计这个任务需要多少时间 |
10 | 10 |
Development |
开发 |
110 | 120 |
· Analysis |
· 需求分析 (包括学习新技术) |
10 | 5 |
· Design Spec |
· 生成设计文档 |
5 | 5 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
5 | 5 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
5 | 5 |
· Design |
· 具体设计 |
5 | 5 |
· Coding |
· 具体编码 |
40 | 40 |
· Code Review |
· 代码复审 |
10 | 15 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
30 | 40 |
Reporting |
报告 |
25 | 20 |
· Test Report |
· 测试报告 |
10 | 10 |
· Size Measurement |
· 计算工作量 |
5 | 5 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
10 | 5 |
合计 |
145 | 150 |
接口的实现与说明:
我负责的是输出模块,需要实现两个接口:outPutToText(String s)以及sort(Map<String,Integer> list)。
前者的功能是将结果输出到txt,后者则是对Map里面的值与键按要求排序,需求描述为:单词按频次从大到小排序,相同频次的按字典顺序排序。
sort()函数:
/** * 按频次(value)排序,相同频次的按字典顺序排序 */ public static String sort(Map<String,Integer> wordsFrequency){ String s=""; List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(wordsFrequency.entrySet()); int flag=0; Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { return o1.getKey().compareTo(o2.getKey()); } }); Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { //升序排序 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); for (Map.Entry<String, Integer> mapping : list) { //降序排序 s=s+mapping.getKey()+" "+mapping.getValue()+"\\n"; flag++; if(flag==100){ break; } } if(s.length()>0){ s = s.substring(0,s.length() - 1); } return s; }
sort函数输入Map,Map里保存的是单词及对应的频次。使用一个list来保存排序后的Map,先对单词(value)按升序排序,然后再对频次(key)降序排序,同时将结果存入字符串s里。使用java的compare进行排序能够保证稳定性,即要比较的对象相等时,不会改变其的相对位置,所以可以先对单词排序,再按频次排序。返回的字符串结果将传给输出函数进行输出。
outPutToText()函数:
1 /** 2 * 排序后输出到result.txt 3 */ 4 public static void outPutToText(String result) throws IOException{ 5 String outPutPath="result.txt"; 6 File file = new File(outPutPath); 7 FileWriter out = new FileWriter(file,false); 8 out.write(result); 9 out.close(); 10 }
此函数相对简单,只要接收sort传入的String,然后输出即可。
测试用例的设计:
对于sort()函数考虑如下多种情况的组合:单字符还是多字符的字符串、单一频次还是不同频次还是有不同频次也有相同频次、频次在Map中是顺序,乱序还是逆序、单词在Map中是顺序,乱序还是逆序?将以上情况全部考虑进测试用例中,能对输入的各种情况全覆盖。
对于outPutToText()函数,测试三种情况:空输入时的输出,单行输入时的输出,多行输入时的输出。
测试用例如下:
单元测试运行截图与质量评价:
单元测试的覆盖率很高,但是冗余度大,效率不高。
被测试模块的sort函数使用了两次compare排序,开辟了一个与传入的Map大小相等的list空间,运行效率满足要求,质量基本达标。
小组贡献分:0.22
扩展任务
开发规范及理解:
根据邹欣老师在讲义“现代软件工程讲义 3 代码规范与代码复审”中所讨论的有关代码规范,代码的格式需要规范,每一个语句单独一行,这样在debug是才能快速找到有错误的代码,同时还要使用合适的缩进,使别人能清晰地看出不同代码所属的块,利于理解程序。
他人代码评价:
我评价的是17092的代码:
我认为他代码的问题是注释不合理,有的注释在代码块之前另起一行进行注释,但有的注释又是直接紧跟在代码块的第一行后面注释,并且对于关键的函数之前没有注释说明该函数的用处及其中公开的参数。
他的代码好的规范是每一条语句都单独一行,每一个{ }也单独一行,结构清晰。
静态代码检查工具:
选择的工具:Alibaba Java Coding Guidelines
下载地址:https://github.com/alibaba/p3c
静态检测结果:
按照检测结果即可修正:对每一个函数都在其之前按照javadoc规范给出注释,便于java生成api;使用注释时另起一行,并与代码对齐;使用StringBuilder替换String,可以提升程序效率,缩小内存占用。
小组代码存在的问题:
整个小组的代码主要存在的问题是注释太少了虽然细读代码能够看得懂,但是最好还是在方法之前加上较为详细的注释,解释方法的主要工作,其中用到的参数等等,使编译器能自动生成有关方法的api。
高级任务
设计测试数据集的思路:
思路:测试数据集要足够大,这样才能测试软件的性能,并且,数据集的内容不能是单调、单一的,需要有许多个形式不一,出现频率不一的单词数据,保证测试结果的一般性。
优化前程序性能指标:
优化前的测试性能指标是对于扫描的文件在五秒内给出正确结果。
同行评审:
由全体组员参与,组员徐江南主持,所有人一同评审小组的全部代码,经过讨论,一致认定在循环内定义变量会增加额外开销。另外,在读取txt内容时只会读取合法字符,方法内对非法字符的判断删去不会影响程序的正确性,但是反而会影响程序的性能,因此需要删去输入类中方法内对非法字符的判断。
优化设计思路:
将代码循环内定义的变量外提,删去对非法字符判断等工作后,程序效率大约提升了20%,与同行评审的结论一致。
总结:
通过本次作业实践,从基本功能到扩展功能在到高级功能,是对软件质量的不断提高,基本功能保证的是软件开发的正确性,保证所开发的软件满足需求,而扩展功能的静态测试则是代码的可读性提高,也对性能有一定的帮助,最后高级功能里的性能测试、同行评审、优化则大幅提升软件质量。最终,一个符合需求描述,同时性能、效率也比较优的产品才算开发完成。
以上是关于第4周小组作业:WordCount优化的主要内容,如果未能解决你的问题,请参考以下文章