第四周作业wcPro

github地址:https://github.com/muzhailong/wcPro.git

PSP2.1表格

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

 40    20

· Estimate

· 估计这个任务需要多少时间

 30  20

Development

开发

 300  

· Analysis

· 需求分析 (包括学习新技术)

 60  40

· Design Spec

· 生成设计文档

 10  10

· Design Review

· 设计复审 (和同事审核设计文档)

 10  10

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 20  10

· Design

· 具体设计

 40  30

· Coding

· 具体编码

 120  100

· Code Review

· 代码复审

 10  10

· Test

· 测试(自我测试,修改代码,提交修改)

 40  50

Reporting

报告

 20  20

· Test Report

· 测试报告

 10  10

· Size Measurement

· 计算工作量

 10  10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10  10

 

  

 接口实现:

我们小组讲这个工程分成类7大模块:

            param:参数解析模块

               in     :输入模块

               core  :核心处理模块

               out     :输出模块

                ui    :图形界面模块

                util  :工具类模块

                start: 模块集成模块

    我主要负责的是输出模块,各个模块如下图所示:

    

输出控制模块:

public class WordPrinter {
private List<Entry<String, Integer>> res;
private PrintWriter writer;

public WordPrinter(List<Entry<String, Integer>> res,PrintWriter writer) {
this.res = res;
this.writer=writer;
}
public void print() {
int sz=res.size();
Entry<String, Integer> tmp=null;
for(int i=0;i<sz-1;++i) {
tmp=res.get(i);
writer.write(tmp.getKey()+" "+tmp.getValue()+"\r\n");
}
tmp=res.get(sz-1);
writer.write(tmp.getKey()+" "+tmp.getValue());
writer.flush();//刷新缓冲
}
}

为了方便输出,使用Map.Entry类来保存字符的名称,以及出现的频率。

使用Print Writer将要输出的数据写入文件中。

 

测试用例:

 

测试用例的设计主要分模块内测试和模块间测试(集成测试)可以点击查看。

       

 

单元测试截图:

start:

in:

core:

评价单元测试用例效果:

  感觉我做的单元测试用例挺好的大部分都符合单元测试的集合要素(貌似是:自动化,灵活,数据集合,报告记录)。start模块主要采用的是黑盒测试,因为start模块集成了所有的模块,白盒测试部分只是做了一部分的判断逻辑等。in模块应该来说是测试最为复杂的模块,内部方法比较多,针对每一个方法进行测试然后使用套包的方法测试,效率还是挺不错的。core模块相应的逻辑比较少,因为core模块的很多东西都依赖与in模块,所以就对接口的相关地方进行的白盒测试。

 评价被评测模块的质量水平:

  start模块:中

  in模块:高

  core模块:高

开发规范说明:

开发规范采用的是《阿里巴巴Java开发手册终极版v1.3.0.pdf》

  选定的开发规范以及理解(我用以下的规范检查我的代码):

       常量定义

    1. 【强制】不允许任何魔法值(即未经定义的常量)直接出现在代码中。

      理解:就是说常量不能使用变量拼接而成的。

        反例:int c;static int A=c;

 

    2. 【强制】long 或者 Long 初始赋值时,使用大写的 L,不能是小写的 l,小写容易跟数字 1 混 淆,造成误解。

      理解:很简单不解释

      举例:long k=123L;

    3. 【推荐】不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。 说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。

      理解:有时候我们会专门写一个类来维持常量,这样是不好的因为将所有的常量放在一起就像一个大杂烩一样。应该根据功能进行放置,比如说和单词容量有关的常量可以放在单词的工厂类中。

  代码格式

    1. 【强制】大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果 是非空代码块则:

      1) 左大括号前不换行。

       2) 左大括号后换行。

       3) 右大括号前换行。

      4) 右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。

      理解:就是字面意思,不用解释。

      举例:while(i){

          ......

         }

    2. 【强制】 左小括号和字符之间不出现空格;同样,右小括号和字符之间也不出现空格。

      举例:void king();

    3. 【强制】if/for/while/switch/do 等保留字与括号之间都必须加空格。

      说明:格式上看的清晰一点。

      反例:if(t<0){

          .......

         }

    4. 【强制】任何二目、三目运算符的左右两边都需要加一个空格。

      举例:k = i + j;

    5. 【强制】采用 4 个空格缩进,禁止使用 tab 字符。

      说明:很多IDE都可以讲tab设置为4个空格。

    6. 【强制】注释的双斜线与注释内容之间有且仅有一个空格。

      举例:// fjei

    7. 【强制】方法参数在定义和传入时,多个参数逗号后边必须加空格。

      举例:void f(int a, int b, int c)

  OOP 规约

    1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成 本,直接用类名来访问即可。

      理解:静态方法属于类,和类是绑定的,通过对象还要先找到类,在从类找到方法。

      举例:

        public class Test{

          public static int a;

        }

        使用Test.a即可。不需在定义一个引用。

    2. 【强制】所有的覆写方法,必须加@Override 注解。

      理解:Override注解貌似是编译时检查,如果重载出现问题编译时不会通过的。

      举例:

        public class Animal{

          public void voice(){}

        }

        public class Duck extends Animal{

          @Override

          public void voice(){}

        }

    3. 【强制】不能使用过时的类或方法。

      理解:一般来说过时的方法都会有风险,或者效率问题。

      举例:acm中最喜欢用的StreamTokenizer

    4. 【强制】构造方法里面禁止加入任何业务逻辑,如果有初始化逻辑,请放在 init 方法中。

      理解:讲逻辑放在构造方法中会造成构造对象浪费大量的时间,有些对象构造了但不一定会使用。

      举例:略。

    5. 【推荐】循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。

      理解:+相当于使用多个StringBuilder对象,效率很低下。

      举例:String a="asd";

         a=a+"few"+"few";

      正例:StringBuilder a=new StringBuilder();

         a.append("fewf");

         a.append("dsfew"); 

    6. 【推荐】类成员与方法访问控制从严:

       1) 如果不允许外部直接通过 new 来创建对象,那么构造方法必须是 private。

       2) 工具类不允许有 public 或 default 构造方法。

       3) 类非 static 成员变量并且与子类共享,必须是 protected。

      4) 类非 static 成员变量并且仅在本类使用,必须是 private。

       5) 类 static 成员变量如果仅在本类使用,必须是 private。

       6) 若是 static 成员变量,必须考虑是否为 final。

       7) 类成员方法只供类内部调用,必须是 private。

       8) 类成员方法只对继承类公开,那么限制为 protected。

    理解:这个符合最小访问原则。

    1. 【推荐】集合初始化时,指定集合初始值大小。

      理解:ArrayList默认大小是10 Map的默认大小是16,他们一般都会在容量达到75%的时候进行扩容处理,所以如果初始时候知道了容量可以避免扩容的开销,提升效率。

      举例:

        List<String> a = new ArrayList<String>(100); 

    2. 【推荐】使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。

      理解:看过Map源码就知道,HashMap在内部维持了一个Entry的数组,使用entrySet遍历其实就是遍历数组,如果使用keySet就行遍历,是讲所有的key打包成一个set然后再通过遍历key从map中获取相应的value,效率低下。

      举例:

      for(Map.Entry<String,Integer>e : map.entrySet()){

         .....

      }

 

存在的问题:

代码的注释比较少,让人摸不着头脑。

变量命名意义不是很明显。

优化环境
文件大小:40M
默认时间:3.911

优化策略:
in模块
1.改变缓冲区大小,减少读文件次数 默认是1个字节 改变为4k
CACHE_CAPACITY=4*1024;
时间:2.178
2.StringBuilder对象设置为静态的 实现重用
时间:2.124
3.设置StringBuilder对象较大的容量,从而避免频繁的扩展容量:
WORD_LENGTH=10
时间:2.156
WORD_LENGTH=10
时间:2.113
影响不是很大
core模块
1.设置Map较大的容量,从而减少冲突;
默认是16
MP_CAPACITY=1M 时间:2.012 最优
MP_CAPACITY=40M 时间:3.296
MP_CAPACITY=20M 时间:2.581
MP_CAPACITY=16M 时间:2.473
MP_CAPACITY=4M 时间:2.427
MP_CAPACITY=1K 时间:2.241
2.改变排序方法
默认采用堆排序 最优
使用快速排序:慢

总结:

没有软件开发就没有测试,软件开发提供软件测试的对象。

软件开发和软件测试都是软件生命周期中的重要部分。

软件开发和软件测试都是软件过程的重要活动。

软件测试是保证软件开发产物质量的重要手段。

参考:

PrintWriter用法:https://www.cnblogs.com/xiaotiaosi/p/6394147.html

博客排版:http://www.cnblogs.com/kangzhishi0203/p/8691939.html

 

 

posted @ 2018-04-08 22:05  离奇  阅读(174)  评论(2编辑  收藏  举报