Github项目地址:https://github.com/chaseMengdi/wcPro

stage1:代码编写+单元测试

PSP表格

PSP2.1

PSP阶段

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

25

30

Estimate

估计任务需要多少时间

25

30

Development

开发

300

302

Analysis

需求分析

20

20

Design Spec

生成设计文档

20

15

Design Review

设计复审

20

15

Coding Standard

代码规范

20

15

Design

具体设计

20

25

Coding

具体编码

90

80

Code Review

代码复审

20

30

Test

测试

60

80

Reporting

报告

80

95

Test Report

测试报告

30

50

Size Measurement

计算工作量

30

25

Postmortem

总结

20

20

合计

405

430

描述代码设计思路

接口设计

public static HashMap<String, Integer> count(String thefile)

划分统计单词数

接口实现

count()函数传入的是一个文件名,即txt文件名,通过逐行读取文件,先将字符串转换为小写,通过split()函数对字符串进行划分。个人技术有限,发现当字符串的最前面的字符是非字母的时候,split()划分会出现不知名的空,故在使用split()进行划分前需要先去掉字符串最前面的非字母字符,同时还有注意“-”出现的情况,如—word-word---,---,需要去开头的“-”和结尾的“-”,而保留词与词间的“-”。然后进行单词统计,将结果存放在HashMap<String, Integer>中。

// 划分统计单词数public static HashMap<String, Integer> count(String thefile) {File file = new File(thefile);HashMap<String, Integer> map = new HashMap<>();if (file.exists()) {try {FileInputStream fis = new FileInputStream(file);InputStreamReader isr = new InputStreamReader(fis, "UTF-8");BufferedReader br = new BufferedReader(isr);String line = new String("");StringBuffer sb = new StringBuffer();while ((line = br.readLine()) != null) {// 转为小写
line = line.toLowerCase();int k = 0;// 去除行首的非字母单词char first = line.charAt(k);while (!((first >= 'a' && first <= 'z') || first == '-')) {k++;first = line.charAt(k);}line = line.substring(k);// 去除多个空格\\s+
String[] split = line.split("\\s++|0|1|2|3|4|5|6|7|8|9|\\_|\\'|\\.|\\,|\\;|\\(|\\)|\\~|\\!|"+ "\\@|\\#|\\$|\\%|\\&|\\*|\\?|\""+ "|\\[|\\]|\\<|\\>|\\=|\\+|\\*|\\/|\\{|\\}|\\:|\\||\\^|\\`");for (int i = 0; i < split.length; i++) {// 获取到每一个单词
Integer integer = map.get(split[i]);// 考虑末尾为-的单词或开头为---if ((split[i].endsWith("-") || split[i].startsWith("-"))&& !(split[i].equals("-"))) {// 去除多个空格\\s+
String[] sp = split[i].split("\\s++|\\-");// 全部为----if (sp.length == 0) {split[i] = "-";integer = map.get(split[i]);}// 处理--danelse if (split[i].startsWith("-")) {int j = 0;char si = split[i].charAt(0);while (split[i].charAt(j) == si)j++;split[i] = split[i].substring(j);integer = map.get(split[i]);}// 去除多个空格\\s+
sp = split[i].split("\\s+|\\-");// 全部为----if (sp.length == 0) {split[i] = "-";integer = map.get(split[i]);}// 处理dn-dan---else {String tmp = sp[0];for (int j = 1; j < sp.length; j++) {tmp = tmp + "-" + sp[j];}split[i] = tmp;integer = map.get(split[i]);}}if (!split[i].equals("") && !split[i].equals("-")) {// 如果这个单词在map中没有,赋值1if (null == integer) {map.put(split[i], 1);} else {// 如果有,在原来的个数上加上一
map.put(split[i], ++integer);}}}}sb.append(line);br.close();isr.close();fis.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}} else {System.out.print("文件不存在\n");}return map;}

测试设计过程

count()函数的测试设计应以黑盒设计为主,首先创建并初始化一个HashMap<String, Integer>和txt文件,随后将txt文件名传入count(),将实际输出与期望输出利用断言进行对比。

20个测试用例设计如下:

Test Case ID

测试用例编号

Test Item

测试项(即功能模块或函数)

Test Case Title

测试用例标题

Test Criticality

重要级别

Pre-condition

预置条件

Input

输入

Output

预期结果

Result
实际结果

Status
是否通过

Remark

备注

count_01

划分统计单词数

一个单词,小写

L

txt文件存在

01.txt

单词与词频

OK

黑盒测试

count_02

划分统计单词数

多个单词,小写

L

txt文件存在

02.txt

单词与词频

OK

黑盒测试

count_03

划分统计单词数

一个单词,大小写混合

L

txt文件存在

03.txt

单词与词频

OK

黑盒测试

count_04

划分统计单词数

多个单词,大小写混合

L

txt文件存在

04.txt

单词与词频

OK

黑盒测试

count_05

划分统计单词数

一个单词,大小写+连字符混合

L

txt文件存在

05.txt

单词与词频

OK

黑盒测试

count_06

划分统计单词数

多个单词,大小写+连字符混合

L

txt文件存在

06.txt

单词与词频

OK

黑盒测试

count_07

划分统计单词数

一个单词,大小写+连字符(任意位置)混合

L

txt文件存在

07.txt

单词与词频

OK

黑盒测试

count_08

划分统计单词数

多个单词,大小写+连字符(任意位置)混合

L

txt文件存在

08.txt

单词与词频

OK

黑盒测试

count_09

划分统计单词数

一个单词,大小写+单引号混合

L

txt文件存在

09.txt

单词与词频

OK

黑盒测试

count_10

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号混合

L

txt文件存在

10.txt

单词与词频

OK

黑盒测试

count_11

划分统计单词数

一个单词,大小写+连字符+双引号混合

L

txt文件存在

11.txt

单词与词频

OK

黑盒测试

count_12

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号+双引号混合

L

txt文件存在

12.txt

单词与词频

OK

黑盒测试

count_13

划分统计单词数

一个单词,大小写+连字符(任意位置)+双引号+数字混合

M

txt文件存在

13.txt

单词与词频

OK

黑盒测试

count_14

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号+双引号+数字混合

M

txt文件存在

14.txt

单词与词频

OK

黑盒测试

count_15

划分统计单词数

一个单词,大小写+连字符(任意位置)+双引号+数字(任意位置)混合

M

txt文件存在

15.txt

单词与词频

OK

黑盒测试

count_16

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号+双引号+数字(任意位置)混合

M

txt文件存在

16.txt

单词与词频

OK

黑盒测试

count_17

划分统计单词数

一个单词,大小写+连字符(任意位置)+双引号+数字(任意位置)+常见符号混合

M

txt文件存在

17.txt

单词与词频

OK

黑盒测试

count_18

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号+双引号+数字(任意位置)+常见符号混合

H

txt文件存在

18.txt

单词与词频

OK

黑盒测试

count_19

划分统计单词数

一个单词,大小写+连字符(任意位置)+双引号+数字(任意位置)+常见符号混合

H

txt文件存在

19.txt

单词与词频

OK

黑盒测试

count_20

划分统计单词数

多个单词,大小写+连字符(任意位置)+单引号+双引号+数字(任意位置)+常见符号+词频相同混合

H

txt文件存在

20.txt

单词与词频

OK

黑盒测试

测试运行和评价

count(String thefile)的单元测试的数据量和复杂度逐渐增加,符合测试用例设计规范,所有单元测试均通过。

count(String thefile)函数质量水平较高,可以正常的划分字符串和统计单词。

小组贡献

我负责的是划分统计单词数,这是本程序流程的第二步,如果出现错误,将会引起连锁反应致使本程序不能正确运行,所以这部分的正确性是很重要。

刚开始用split()对字符串进行分割,但后来发现如果字符串的开始部分是分割字符将会导致分割到的第一个字符串为空(不知道为什么),故本人加入一个去除以非字母开始的字符直到出现第一个字母。由于出现“-”的单词有几种情况,还需要对它们进行判断处理。

我个人的代码行数占了0.51,主要是要求有点多,需要考虑的情况较多,个人觉得应该还是完成的挺不错的.

stage2:静态测试

开发规范理解

《阿里巴巴Java开发手册》中指出:

2. 【强制】代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。 说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。
正例:alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文。

反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3

理解:

我觉得这点规定非常好,因为正确的英文拼写和语法可以让阅读者易于理解,避免歧义。而拼音英文混合和中文命名代码的方式则不利于读者阅读代码,也不利于性能优化和同行评审。我负责的单词统计模块代码命名均为国机通用的英文,符合《阿里巴巴Java开发手册》第二条的强制规定。

组员代码评价

选择刘博谦(17070)的代码进行分析

// 词频排序public static ArrayList<String> sort(HashMap<String, Integer> map) {// 以Key进行排序TreeMap treemap = new TreeMap(map);// 以value进行排序ArrayList<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(treemap.entrySet());Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {public int compare(Map.Entry<String, Integer> o1,Map.Entry<String, Integer> o2) {// 降序return o2.getValue() - o1.getValue();// 升序 o1.getValue() - o2.getValue())
            }});ArrayList<String> str = new ArrayList<String>();int i = 0;for (Map.Entry<String, Integer> string : list) {// 排除-与空格if (!(string.getKey().equals("")) && !(string.getKey().equals("-"))) {str.add(string.getKey());str.add(string.getValue().toString());// 输出前1000个单词if (i > 1000)break;i++;}}return str;}

刘博谦的代码遵守了《阿里巴巴Java开发手册》第二条的强制规定,代码命名规范,无需改进。

静态代码检查

选择工具:FindBugs 3.0.1

下载链接:http://findbugs.sourceforge.net/

检查结果如下:

String line = new String("");

缺陷信息:

Method invokes inefficient new String(String) constructor

Using the java.lang.String(String) constructor wastes memory because the object so constructed will be functionally indistinguishable from the String passed as a parameter.  Just use the argument String directly.

Bug kind and pattern: Dm - DM_STRING_CTOR

分析:new String("")构造函数效率低,直接line=""即可。

个人代码改进

个人代码符合《阿里巴巴Java开发手册》第二条的强制规定,改正FindBugs指出的缺陷后,代码如下。

(完整代码过于繁琐,下面只贴出缺陷部分代码修改后的结果)

                            FileInputStream fis = new FileInputStream(file);InputStreamReader isr = new InputStreamReader(fis, "UTF-8");BufferedReader br = new BufferedReader(isr);String line = "";StringBuffer sb = new StringBuffer();

小组代码分析

(此部分由本人和刘博谦(17070)完成)

1、FileWriter writer = new FileWriter("result.txt", true);

写文件流可能关闭异常,应该使用try/finally来确保写文件流会被成功关闭。

原有代码中使用了try/catch,但是并未使用finally语句,这就导致如果出现错误跳到catch,程序继续执行的话,写文件流一直会被占用,从而可能引发程序崩溃。

建议添加finally块来关闭写文件流。

2、FileWriter writer = new FileWriter("result.txt", true);

此行语句需要依赖默认编码来正常工作,为防止隐藏bug,应该指定一个编码,考虑到程序需求,指定UTF-8编码。

3、String line = new String("");

new String("")构造函数效率低,直接line=""即可。

4、message += (str.get(i) + " " + str.get(i + 1) + "\r\n");

循环中使用+来连接字符串,时间开销为二次方,建议修改使用StringBUffer.append(String)方法来提高效率。

参考资料

1、单词词频统计降序排序(代码贴)

2、阿里巴巴Java开发手册

转载于:https://www.cnblogs.com/jakejian/p/8735660.html

第4周小组作业:WordCount优化相关推荐

  1. HUST软测1504班第4周小组作业成绩:WordCount优化

    说明 本次公布的成绩为第四周作业的结果: 第4周小组作业:WordCount优化 博客推荐:本次作业有一位同学完成有创意,推荐优秀博客.(优秀博客不会对成绩带来正面或者负面影响)PS:做任何创新的任务 ...

  2. HUST软测1504班第6周小组作业成绩

    说明 本次公布的成绩为第6周小组作业的结果: 第6周小组作业:WordCount(详情见毕博平台) 如果同学对作业结果存在异议,可以: 在毕博平台讨论区的第6周作业第在线答疑区发帖申诉. 或直接在博客 ...

  3. 软件质量与测试--第二周作业 WordCount

    软件质量与测试--第二周作业 WordCount Github地址: https://github.com/RicardoDZX/WordCount PSP: PSP2.1 PSP 阶段 预估耗时 ( ...

  4. 软件测试第4周小组作业:WordCount优化

    小组github地址 https://github.com/whoNamedCody/wcPro  基本任务 一.PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Plan ...

  5. 第4周小组作业:WordCount优化版

    小组github项目地址:https://github.com/Wegnery/New_WordCount 基础功能: 一.PSP表格   PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分 ...

  6. 软件质量与测试第4周小组作业:WordCount优化

    GitHub项目地址 https://github.com/Guchencc/WordCounter 组长: 陈佳文:负责词频统计模块与其他模块 组员: 屈佳烨:负责排序模块 苑子尚:负责输出模块 李 ...

  7. 第四周小组作业:WordCount优化

    github项目地址:https://github.com/Wegnery/New_WordCount 一.基础功能部分:代码编写+单元测试 PSP表格 PSP2.1 PSP阶段 预估耗时(分钟) 实 ...

  8. 软件测试第四周作业WordCount优化

    1.小组github地址:https://github.com/whoNamedCody 小组成员:17048冷福星   17050李慎纲  17039付佳韵  17040康之是 2.psp表格: P ...

  9. 第六周小组作业:软件测试与评估

    一.基础任务部分:功能测试和测试管理 1.1计划说明 (1)对比测试产品为背单词APP:百词斩(基础产品)与扇贝单词(竞品). (2)测试进度表 测试进度表如下表所示(该表参照测试计划中的测试时间进度 ...

最新文章

  1. Python 中的 enumerate 函数
  2. 中文谐音怎么读_AOS中文社区创始人大豪:零隐链是AOS最恰当的中文表达
  3. HTML5 Canvas白板
  4. java五种加密技术理解
  5. 动态规划基础——爬楼梯(Leetcode 70)
  6. 用stack实现括号匹配
  7. 用 Python 创建你自己的加密货币(附源码)
  8. Win10连接上了wifi但是打开浏览器显示网络异常,诊断网络发现错误“远程计算机或者设备将不接受连接
  9. Python模拟简易版淘宝客服机器人
  10. 【同步与补偿】频率偏移
  11. [华为 HCNA ] VLAN的介绍和划分
  12. 弱爆了的鹊桥专用查询接口:taobao.tbk.dg.item.coupon.get( 好券清单API【导购】)接口
  13. Python爬取网易云音乐播放地址
  14. Axure 元件库-原型
  15. Greenplum【集群搭建 02】cgroup工具安装+用户资源组配置+集群资源组配置+数据库资源组配置+资源组相关信息(一篇学会资源组配置)
  16. 神舟电脑装linux双系统,神舟战神肿么装双系统
  17. Mysql安装-Centos7-阿里云虚拟主机
  18. 牛客网——华为题库(61~70)
  19. 献给程序员之如何与陌生人交谈
  20. 【Python】使用you-get下载bilibili视频合集

热门文章

  1. C# 使用FileSystemWatcher来监视文件系统的变化
  2. 架构设计系列-前端模式的后端(BFF)翻译PhilCalçado
  3. Android .mk文件语法解析
  4. hadoop中NameNode、DataNode和Client三者之间协作关系及通信方式介绍
  5. springMVC文件下载
  6. 常用SQL语句和HQL语句写法
  7. BIRCH聚类算法原理
  8. oschina代码仓库远程push,pull免密实操总结
  9. JS URL参数传递 谷歌乱码解决
  10. Remoting 与 Webservice 的区别