软工实践寒假作业2/2

这个作业属于哪个课程 2021春软件工程实践W班(福州大学)
这个作业要求在哪里 寒假作业2/2
这个作业的目标 阅读《构建之法》并提问、完成词频统计个人作业
其他参考文献 CSDN

part1:阅读《构建之法》并提问

1、在书本12.1中提到的用户体验和质量,当两者冲突的时候,是牺牲哪一部分,用户可以接受多少。
比如追求界面的精致和用户的实际体验,又或者某个特定时间才会出现的功能bug,需要牺牲全年的其他部分来完善这个功能吗?所谓衡量的度在哪?
我个人认为这和软件的定位有关系,在保证大多数用户的良好体验的前提下,再进行对质量的提升;当然软件的安全性肯定是放在首位的。

2、在书本16.3中说到
“我们说了两种技术:维持性的技术和颠覆性的技术,但是没有一种技术生来就是维持性的技术,那么如何判断一种技术已经到了维持性的阶段呢?
一个重要的特性就是效能过剩( Performance Oversupply)。”。
如果技术到了维持阶段,但在技术上突破的新技术又增加了学习成本,如何做到适时适当的功能点创新?
我个人觉得是要在维护好旧的系统技术的同时,积极吸纳新的成熟的技术,做好新旧技术的磨合,向旧的系统中注入新鲜的血液,当然这需要我们对新旧技术都有了一定的把握。

3、书上提到初级软件工程师的成长,包括积累软件开发相关的知识,提升技术技能;积累问题领域的知识和经验;对通用的软件设计思想和软件工程思想的理解;
提升职业技能;实际成果。那知道了包括这些方面,如何培养提高核心竞争力或是具体的实施方式是否科学有效?少走弯路。
我个人认为,既然知道了哪些方面需要增强,那么积极的向前辈请教,学习一些优秀的发展路线,让自己走的更快更远。

4、学技术一般都是从前人“师傅”那相传,但又有提到,“70%的创新者说,他们最成功的创新,是在他们的拿手领域之外发现的。”。
我们在学习技术的时候,技术的思维和方法也在影响着我们的思维方式。那怎么深入的学习同时进行技术的创新,迎合发展需求?
这也在提醒着我们,学技术并不是照搬照抄,懂得其中的思维方式,并局限在其中也是很难的。

5、在16.1中提到,“最近几年,我们整个社会似乎对创新都很感兴趣,媒体上充斥着创新型的人才、创新型的学校、创新型的公司、创新型的城市、创新型的社会等名词。”怎么才算创新?
但感觉“创新”这个词变成了一种束缚,我们在面对大的公司和企业,往往很难想到创新的点子,又装进了“创新”的套子中。那我们只能从已有的事物中打磨,但往往创新度不佳。
我们更应该拓宽我们的视野,立足当下,扎稳脚跟,在头脑风暴中寻找灵感。

附加题

WWW的想法是由一个物理学家,蒂姆伯纳斯李,提出来的。这个现在看起来这么顺理成章的想法,为什么是由一个物理学家.而不是计算机学家实现出来的?事实上在wwW/HyperText 协议刚出现时,一些计算机专家非常看不起这个玩意,专家们认为,网页上都不记录状态,这算什么难度,这又是什么创新呢?这能在什么地方发表论文呢?当时计算机科学家在搞COM、DCOM、远程过程调用(Remote ProcedureCall,RPC)这样一些高难度的东西。

part2:WordCount编程

Github项目地址

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 20
• Estimate • 估计这个任务需要多少时间 20 20
Development 开发 330 400
• Analysis • 需求分析 (包括学习新技术) 30 40
• Design Spec • 生成设计文档 10 10
• Design Review • 设计复审 10 10
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 10 10
• Design • 具体设计 20 30
• Coding • 具体编码 200 240
• Code Review • 代码复审 20 30
• Test • 测试(自我测试,修改代码,提交修改) 30 30
Reporting 报告 60 80
• Test Repor • 测试报告 30 50
• Size Measurement • 计算工作量 10 10
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 20 20
合计 410 500

解题思路表述

由题目要求可知,本次任务主要完成
读入文件 ——> 完成四个功能(统计字符总数、单词总数、有效行数、单词频率) ——> 写入文件

首先读入文件,采用java的文件流读入文件内容
再把读取的内容分发给四个独立的函数来处理
(在获取字符总数的时候,进行对字符频率用哈希表进行保存)
把处理后返回的结果进行拼接,写入到输出文件中去

代码规范制定链接

设计与实现过程

总共设计Lib工具类和WordCount主函数入口测试
Lib类实现有六个函数分别为
文件读入和文件写入、获取字符总数、有效行数、单词总数和单词频率
读入和写入都采用字符流的形式

    StringBuffer content = new StringBuffer();
    try {
      BufferedReader br = new BufferedReader(new FileReader(filePath));

      char[] buff = new char[1024];
      int len = -1;
      while( (len = br.read(buff)) != -1 ){
          content.append(new String(buff, 0, len));
      }
    } catch (Exception e) {
      System.out.println("读取文件内容出错");
      e.printStackTrace();
    }

获取有效行数和进行单词的匹配都采用的是正则匹配的形式

    String[] arr = content.split("\n");
    int num = arr.length;
    Pattern pattern = Pattern.compile("\\s*");
    for(String str : arr){
        Matcher matcher = pattern.matcher(str);
        if (matcher.matches()){
            num--;
        }
    }

通过正则表达式将其分割成一个个小的字符串,再进行单词的匹配,匹配成功则单词数增加,再添加进哈希表中
在Lib类中设有Map的成员变量保存单词的情况,使得单词总数和单词频率不用重复工作

    Pattern pattern = Pattern.compile("[^a-zA-Z0-9]");
    Pattern wordPattern = Pattern.compile("^([a-z]|[A-Z]){4}([a-z]|[A-Z]|[0-9])*");
    String[] arr = pattern.split(content);
    for(String str : arr){
        if (str.equals(""))
            continue;
        Matcher m = wordPattern.matcher(str);
        if (m.matches()){
            wordNum++;
            String t = m.group(0).toLowerCase();
            if (map.containsKey(t)){
                map.put(t,(Integer)map.get(t)+1);
            }else{
                map.put(t,1);
            }
        }
    }

性能改进

1、文件读入刚开始用的一行行读入,发现字符流效率更高些
2、在初步完成功能之后,发现单词总数和单词频率进行了重复的工作
所以在Lib类中设有Map成员变量进行数据的保存和再利用,减少了不必要的工作

单元测试

新建LibTest类,对其中关键的功能函数进行测试

在LibTest类中初始化Lib对象

  Lib lib;
  @Before
  public void setUp() throws Exception {
     lib = Lib.getInstance();
  }

通过成员变量lib来调用测试函数等

@Test
    public void getCharTotalCount() {
        String content = lib.readTxt(filePath);
        lib.getCharTotalCount(content);
    }

    @Test
    public void getWordTotalCount() {
        String content = lib.readTxt(filePath);
        lib.getWordTotalCount(content);
    }

展示多次测试结果
以1000w字符数为例

异常处理说明

未传入 输入文件和输出文件
进行文件读写操作可能会出现文件找不到异常

心路历程与收获

1、作业要求在git上提交各部分功能的代码,也体会到了git代码托管平台的便利。各个功能结构也更加清晰。
编程中首次用到单元测试,学习了单元测试的用法,在学习新技术的时候,也带来了新的收获。
2、重新学习了正则表达式的规范使用。将功能函数封装进工具类,以接口的形式提供功能支持。
3、也学会了使用博客来记录一次项目的开发的过程,乃至结果的统计。

posted @ 2021-03-04 13:55  051805124  阅读(107)  评论(4编辑  收藏  举报