软工实践寒假作业(2/2)
这个作业属于哪个课程 <2021软件工程实践>
这个作业要求在哪里 <软工实践寒假作业(2/2)>
这个作业的目标 学会使用git、gthub,学习《构建之法》有所感悟
其他参考文献 《构建之法》《廖雪峰的git教程》

作业描述

  • 任务一:阅读《构建之法》并提问
    前一次作业要求不够详细,部分同学阅读《构建之法》提出的问题过于浅显,没有对提出的问题进行深入思考,因此在本次作业中额外添加了重新阅读《构建之法》并提问这一任务,并布置了更详细的要求。
  • 任务二:完成词频统计个人认任务
    在大数据环境下,搜索引擎,电商系统,服务平台,社交软件等,都会根据用户的输入来判断最近搜索最多的词语,从而分析当前热点,优化自己的服务。首先当然是统计出哪些词语被搜索的频率最高啦,请设计一个程序,能够满足一些词频统计的需求。
    • 需求:
      假设有一个软件每隔一小段时间会记录一次用户的搜索记录,记录为英文。
      输入文件和输出文件以命令行参数传入。
      1. 统计文件的字符数(
      2. 统计文件的单词总数
      3. 统计文件的有效行数
      4. 统计文件中各单词的出现次数,最终只输出频率最高的10个。

任务一:阅读构建之法并提问及附加题

阅读并提问

  • 文中说列举了结对编程的好处,其中有“结对编程能够提供更好的设计质量和代码质量,两个人合作能有更强的解决文通的能力。”……后文又说“任何一段代码至少被两双眼睛看过,两个脑袋思考过。”
    • 问题:大多数人的思维方式是不一样的,一个问题解决也有多个解决方法,两个人结对编程过程中自己在解决问题,同时也在看对方解决问题,思维在自己和对方的解题思路中不断跳跃,这样花费的时间不会更多吗?怎样才能找到适合结对编程的搭档呢?怎么和搭在合作中达到1+1>2的效果呢?关于如何结对编程有相关的理论方法吗?比如如何达到高效合作。
  • 书中介绍了很多开发流程的方式比如:写了再改、瀑布模型、瀑布的各种变形等。
    • 问题:一个刚组成的软件开发团队,彼此都还不是很了解,如何选择适合的开发流程呢?这几种开发方式有比较低风险的吗?如果在团队合作过程中,发现一开始的方式有问题,但内部的调动又会消耗大量的精力,这值得半途换开发流程模式吗?
  • 文中写道“自己最喜欢的一个项目是微软学术搜索,尽管许多用户觉得它的UI不错,它仍有很多可以改进的地方,一个叫西乔的同学就给提出了下面的建议:建议采用不同的样式,将submit按钮突出,Cancel按钮样式弱化,降低用户丢失操作的可能性。”
    • 问题:我联想到,如果存在这样希望降低用户损失(但不是很大的影响)更改界面,但是会使界面变得不美观的情况,应当如何选择?
  • 文中说“光看用户的表面语言或者行动是不够的。我们还要找到用户语言行动背后的动机!”
    • 问题:文中列举了好几个例子,可以看出,在这阶段也投入了大量的时间和精力,软件开发每一个阶段都很重要,我想到,那在实际项目中,整个团队在每个阶段的时间怎么分配才合理呢?哪个阶段的时间应该花最多的时间和精力。
  • 文中说现代软件工程,其实还是人的问题,其中说到“林子大了,什么鸟都有,作为万物之灵的人类,是不能满足于仅仅只有三种花样的。很快,我们可以看到第四,第五类人的出现”。
    • 问题:团队里出现‘不做事’、‘不让别人做事’等之类的人,应该怎么办呢,是耐心的沟通交流,还是粗暴的踢出。

附加题

Therac-25事件(来源网络):

Therac-25是一台于1985年制造的放疗设备,一台用来给癌症病人做放射性治疗的设备。由加拿大原子能公司(AECL)制造。它核心的软件程序是用来控制放疗的辐射量。 这台机器的投入使用的短短18个月内,因为软件的重大bug,造成了4人死亡,2人重伤,震惊了软件界。迫使软件工程进行巨大的改进,制定了软件测试标准。

Therac-25事件


任务二:词频统计个人作业

Github地址

zzong-coder

PSP表格

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

解题思路描述

  • 首先学了作业博客中提供的廖雪峰的git教程,学习了git的使用,也看了些git和GitHub的介绍,了解了git和GitHub的作用
  • 然后粗略的复习了java知识,就开始编程了,后来发现了这样做的缺点,没有根据最优方法解题
  • 首先将功能分成四大块:
    1. 统计字符数
    2. 统计单词数
    3. 统计单词频数
    4. 统计行数
  • 每个大功能封装为一个方法,后实现命令行运行程序和写入文件
  • 认真看了邹欣老师的博客,学习《构建之法》,阅读并思考后提出了5个问题

代码规范定制链接

代码规范

设计与实现过程

  • 主要功能分别封装在四个方法中
    1. CharCount (BufferedReader bufferedReader)实现文件中字符统计
      不考虑中文,只统计ASCII码,空格和水平制表符换行符都算字符,通过判断符号的ASCII码值来统计,方法返回有多少个字符。

      while ((ch=bufferedReader.read()) != -1){
                      if (ch <= 127 && ch >= 0){
                          num++;
                      }
                  }
      
    2. WordsCount(BufferedReader bufferedReader)方法实现统计文件单词数
      先将单词分解出来:

      if(ch>='a'&&ch<='z' || ch>='0'&&ch<='9'
                             || ch>='A'&&ch<='Z'){
                         str += ch;
                     }
      

      然后判断单词是否合法,通过IsWord方法判断,合法则计数

      if(str != null && IsWord(str)) {
                              num++;
                          }
      
    3. FileLines(BufferedReader bufferedReader)方法实现文件行数统计
      只统计有单词或字母数字的行数,若是空白行则不统计

      while ((line = bufferedReader.readLine()) != null) {
                      String temp = line.replaceAll("\\s*","");
      
                      if (line.length() != 0) {
                          rows++;
                      }
                  }
      
    4. WordsNum(BufferedReader bufferedReader,int n)方法实现单词频数统计
      统计文件中各个单词的出现次数,最终只输出频率最高的10个,频率相同的单词,优先输出字典序考前的单词,这个函数核心代码如下:

      if (!IfSame(words , temp , counts) && j<words.length) {
                                  words[j] = str;
                                  counts[j]++;
                                  j++;
                              }
      

      涉及方法及关系如下(在一些方法下还有一些小方法未在此体现出):
      alt

    5. 同时有IsWord()方法判断单词是否合法;IfSame()方法判断是否有相同的单词;WordChange()方法将单词全部转换成小写;SortWords()方法根据单词出现频数排序;

性能改进

  • 使用BufferReader作为输入
  • 计划使用map,应该会提高性能

单元测试

  • 主要测试Lib.java中的方法,WordCount.java中只有main方法,其中是其他方法的使用。部分单元测试代码:
       @Test
       public void sortWords() {
           String[] words = {"hello","he"};
           int[] counts = {1,1};
   
           Lib lib = new Lib();
           lib.SortWords(words,counts);
   
           String[] word = lib.GetWords();
           String[] rightWords = {"he","hello"};
   
           for (int i=0; i<2; i++) {
               assertEquals(rightWords[i],word[i]);
           }
       }   
    @Test
    public void ifSame() {
        String[] words = {"hello"};
        int[] counts = {0};
        assertEquals(true,new Lib().IfSame(words,"hello",counts));
    }

测试结果:

覆盖率:

  • 测试用例及结果:
    1. 空文件情况:
      alt
    2. 少量单词:
      alt
    3. 十个以上单词:
      alt
    4. 大量数据:
      alt

异常处理说明

  • 对BufferReader操作或写文件等操作会产生异常的,用try-catch捕获:
    try{
        //代码块
    } catch (Exception e) {
        //处理
    }

心路历程与收获

  • 刚开始看这个作业的要求时,除了任务一之外明白了,其他的大半作业要求都觉得看不懂。内心开始有点抵触。
  • 后来认认真真研究了作业要求,才理解要怎么做。脑子里大概总结了一下这次作业的步骤,然后开始动手。之前一直用的eclipse,这次换了idea,才开始用也研究了一下idea。
  • 看了很多教程,包括作业中提供的和自己找的,勉勉强强学会了git和GitHub的使用,现在还不熟练,开始学这个的时候感觉模模糊糊的,看了很久才有了大致的概念。
  • 由于之前代码基础较弱,写代码前也只是构思了代码的大概框架,导致没有写出优质的代码,只是实现了作业要求的功能,并且绕了很多弯路,深刻认识到平时的积累很重要。
  • 后来写博客的时候整理了一下自己的代码思路,发现比一边写代码一边想下一步该怎么写简单很多,而且比较严谨不会出错。以后一定要多多写代码提升自己的能力。
  • 写代码过程中遇到很多bug,改代码的过程很自闭,一直在反思自己的代码能力为什么这么弱。之前一直在做与代码关系不大的事情,意识到在学习其他东西的时候也要学习好自己的专业知识,拥有牢靠的专业基础知识。
  • 总结的时候觉得自己收获良多,学会了git和GitHub的使用,也认识到了自己的很多不足之处,心态也改变了很多。
posted on 2021-03-05 15:27  zzong  阅读(166)  评论(4编辑  收藏  举报