第四周作业之wcPro输出模块的实现

一、基本任务:代码编写+单元测试

小组github地址

https://github.com/SkateCloud/wcPro

PSP表格

PSP2.1PSP阶段预估耗时(分钟)实际耗时(分钟)
Planning计划3060
Estimate估计任务需要多少时间3060
Development开发180150
Analysis需求分析2030
Design Spec生成设计文档2030
Design Review设计复审2030
Coding Standard代码规范3010
Design具体设计3050
Coding具体编码3040
Code Review代码复审3040
Test测试5010
Reporting报告70240
Test Report测试报告30100
Size Measurement计算工作量2060
Postmortem总结2080
 合计340450

接口设计

  • 接口描述

本人负责的是输出模块,即对结果以合理方式输出,将单词词频排序的结果输出到文件。

  • 设计思路

通过对单词词频排序的结果存入数组表,然后通过文件操作将数组表内容打印至指定文件内

  • 实现过程

由于外部存储机构使用的是Map.Entry<String, Integer>,不便于操作,所以将map转化为List结构

List<Map.Entry<String, Integer>> list = new ArrayList<>();
        list.addAll(words.entrySet());//词组进入list表
        list.sort((lhs, rhs) -> { //比对排序
            int cmp = -lhs.getValue().compareTo(rhs.getValue());
            if (cmp != 0) return cmp;
            else return lhs.getKey().compareTo(rhs.getKey());
        });

然后将排序后的List结果做文件操作写入指定的result.txt文件中

try (FileWriter fout = new FileWriter("result.txt")) {
            int maxsz = Math.min(list.size(), 100);
            for (int i = 0 ; i < maxsz; ++ i) {
                Map.Entry<String, Integer> item = list.get(i);
                fout.write(item.getKey());
                fout.write(' ');
                fout.write(item.getValue().toString());
                if (i != maxsz - 1)
                    fout.write('\n');
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

测试设计

测试用例设计思路:

保证设计的测试用例应至少覆盖函数中所有的可执行语句,同时主要空数组、最差情况、词频排序、字母排序、两者混合等各种情况设计测试用例。

测试清单

单元测试

使用测试脚本进行单元测试,过程如下

测试脚本运行截图

单元测试效果良好,没有报错

小组贡献

我们小组齐心协力, 攻克难关,积极讨论,指出问题,我认为我的小组贡献分是0.3

二.扩展任务:静态测试

1. 代码规范

采用以下Java开发规范

1.1 命名规则

需遵守java基本命名规范,以下列举需要着重注意的地方和我们的一些规则。

l 统一采用驼峰标识。

l 不允许使用汉语拼音命名,特殊含义的除外。

l 遇到缩写如XML时,需全部大写,如loadXMLDocument()。

l 局部变量及输入参数不要与类成员变量同名(set方法与构造函数除外)

l 常量必须都是大写字母,名称包含多个词时,使用下划线来分割,并且保证命名有完整含义,比如PRODUCT_TYPE。枚举值也是常量,遵守该规则。

l 项目名与模块名之间,使用”-”隔开,不再使用”_”。区分代码和项目的命名规则。

l Package名必须全部小写,尽量使用单个单词。

l Interface名统一采用首字母为I。

l 注意单类中,变量名的一致性。例如,在一个service中的几个方法,都定义有useName变量,或者进行简写uname等,不论全写还是简写,前后方法对于同一变量的命名都需要保持一致,便于可读。

l 在同一个方法中,不建议一个变量表示多个意义不同的数值。

1.2 声明规则

1.2.1 修饰符顺序

修饰符应该按照如下顺序排列:public, protected, private, abstract, static, final, transient, volatile, synchronized, native, strictfp。

1.2.2 类定义顺序

类内容定义的顺序

l 静态成员变量 / Static Fields
l 静态初始化块 / Static Initializers
l 成员变量 / Fields
l 初始化块 / Initializers
l 构造器 / Constructors
l 静态成员方法 / Static Methods
l 成员方法 / Methods
l 重载自Object的方法如toString(), hashCode() 和main方法
l 类型(内部类) / Types(Inner Classes)

同等的顺序下,再按public, protected,default, private的顺序排列。

我的编程习惯与以上附录中所述规范大致相同,即使不同,我也会通过编辑器插件进行代码规范化。而在其他如代码审查等重要规范上有待提高。

2. 同组分析

我分析了组长16980的代码,缩进、断行风格整洁,命名简单明了,逻辑清晰易读,但在代码设计规范上,模块化不足,不易于进行团队的coding工作,经常在git操作上发生冲突.

最后决定将团队代码进行整合重构,重构任务由组长16980完成,故最终贴出组长的重构代码

public class wordcount {
    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        new wordcount().start(args);
        long t2 = System.currentTimeMillis();
        long dt = t2 - t1;
        System.out.println(("Elapsed " + dt + "ms"));
    }

    private void start(String[] args) {
        HashMap<String,Integer> words = new HashMap<>();
        String str = readFile(args[0]);
        {
            int state = 0;
            int beginIndex = -1;
            for (int i = 0; i <= str.length(); ++i) {
                char ch = i == str.length() ? ' ' : str.charAt(i);
                boolean isWordChar = ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ch == '-';
                if (state == 0 && isWordChar && ch != '-') {
                    beginIndex = i;
                    state = 1;
                } else if (state == 1 && !isWordChar) {
                    String word = str.substring(beginIndex, i).toLowerCase();
                    words.put(word, words.getOrDefault(word, 0) + 1);
                    state = 0;
                }
            }
        }

        List<Map.Entry<String, Integer>> list = new ArrayList<>();
        list.addAll(words.entrySet());
        list.sort((lhs, rhs) -> {
            int cmp = -lhs.getValue().compareTo(rhs.getValue());
            if (cmp != 0) return cmp;
            else return lhs.getKey().compareTo(rhs.getKey());
        });

        try (FileWriter fout = new FileWriter("result.txt")) {
            int maxsz = Math.min(list.size(), 100);
            for (int i = 0 ; i < maxsz; ++ i) {
                Map.Entry<String, Integer> item = list.get(i);
                fout.write(item.getKey());
                fout.write(' ');
                fout.write(item.getValue().toString());
                if (i != maxsz - 1)
                    fout.write('\n');
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

    private String readFile(String path) { // 读文件
        try {
            byte[] encoded = Files.readAllBytes(Paths.get(path));
            return new String(encoded, "UTF-8");
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }

}

3. 静态代码检查工具

使用的是IDEA的插件Ant Build中的检错功能
Ant Build是一个Java自动化生成工具,其检错功能用来检查类或者jar文件,用来发现可能的问题。检测完成之后会生成一份详细的报告,借助这份报告可以找到潜在的bug.

检测范围

  • 常见代码错误,序列化错误
  • 可能导致错误的代码,如空指针引用
  • 国际化相关问题:如错误的字符串转换
  • 可能受到的恶意攻击,如访问权限修饰符的定义等
  • 多线程的正确性:如多线程编程时常见的同步,线程调度问题。
  • 运行时性能问题:如由变量定义,方法调用导致的代码低效问题

4. 扫描结果

扫描结果

检测结果在右上角,可以看出仅有少量警告,根据IDEA红线标注可发现大多是声明方式不是按照目前使用的java标准,没有发生内存泄露等问题.

5. 小组代码问题说明

  • 由于进行了整合重构,所以模块化程度降低,不易维护,但程序执行效率上升
  • 异常处理的不够全面,应该覆盖大部分的一场情况,以便于检查与调试

三. 高级任务:性能测试和优化

设计,评审,优化
选择10kb,50kb,182kb大小的txt文件进行测试,程序处理时长如下:

      输入输出:1ms,1ms,2ms

      单词统计:20ms,150ms,540ms

      词频排序:6ms,8ms,10ms

  单词统计时间与文件大小呈线性相关,其他两个模块占比较小,故程序性能主要受到文件大小影响。组内共同对代码结构和细节进行详细审查并与其他组程序对比,整理得到如下观点:

    1.整合重构是正确的,不仅增加了代码的可读性和规范性,还大幅增加了程序的性能

    2.将大部分功能模块聚集在一个类方法中,虽然会导致代码耦合度增高,不易于团队维护和再开发,但是减少了模块间相互调用的开销和随之产生的内存开销

小结

通过基本任务、扩展任务、到高级任务的完成以及中间遇到的许多困难,体现出了软件测试对于软件开发的重要性。在开发过程中,使用静态测试工具实时地检测自己的代码,可以改正自己不良的编程习惯,更能防患于未然,减少出现bug的可能;对自己的模块进行单元测试,可以保障自己代码的正确性,更是对其他开发成员和整个任务的负责,使软件开发能够一步一个脚印地稳定开展;对性能的分析与测试,能使软件的质量进一步提高,同事能总结开发经验,使自己设计的模块更加高效。

转载于:https://www.cnblogs.com/Xianbei233/p/8747744.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值