寒假作业(2/2)

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2020SpringW?page=3
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2020SpringW/homework/10281
这个作业的目标 实现疫情统计小程序
作业正文 寒假作业(2/2)
其他参考文献 ...

1、GitHub仓库地址

作业仓库:(https://github.com/WangDongYu235/InfectStatistic-main)

2、PSP表格

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

3、思路描述

  • 如何思考

    刚看到题目的时候,看了几遍才大概清楚要做什么,处理获取的参数,读取文件,数据统计,写入文件。我首先想的是文件的读写操作,毕竟这个学过,但路径又要是参数设置的,就先固定命令,然后获取参数,测试文件读写。之后就开始处理参数,实现数据统计过程。

  • 如何找资料

    基本上遇到不会的就百度,找教程,找博客。

4、实现过程

用若干个整型变量记录参数输入情况,用一个数组来记录type类型出现的次序,除了省份列表数组外,设2个数组记录省份,一个记录参数指定的,一个记录日志文件读取过程中出现的省份,用二维数组来记录数据各个省份的各个类型的人数。

寒假作业(2/2)_第1张图片

5、代码说明

  • 遍历参数列表,用equals方法判断参数类型,并获取其值
            if (args[i].equals("-log")) {
                logCount++;
                int j = i+1;
                logPath = args[j];
            }
            // "-out"、"-date",方法同上
  • 这个是type类型出现的次序的记录方法,用一个初始值为1的order变量
            if (args[i].equals("-type")) {
                typeCount++;
                int j = i+1;
                int order = 1;
                //从"-type"下一处开始往后寻找参数
                while (true) {
                    if (j == args.length || args[j].charAt(0) == '-') {
                        break;
                    }
                    if (args[j].equals("ip")) {
                        typeAppear[0] = order;
                        order++;
                    }
                    //其他类型同上此处略          
                    j++;
                }
            }
            
  • 省份:获取省份参数,用getIndex方法寻找参数在省份列表中的位置即下标,将相应下标的provinceAppear数组元素置为1,表示出现过
            if (args[i].equals("-province")) {
                provinceCount++;
                int j = i+1;
                //从"-province"下一处开始往后寻找参数,寻找参数在省份列表中的位置
                while (true) {
                    if (j == args.length || args[j].charAt(0) == '-') {
                        break;
                    }
                    int index = getIndex(allProvince,args[j]);
                    //未找到会返回-1
                    if (index >= 0) {
                        provinceAppear[index] = 1;
                    }
                    j++;
                }
            }
        }
    public static int getIndex(String str [],String value) {
        for (int i = 0; i < str.length; i++) {
            if (str[i].equals(value)) {
                return i;
            }
        }
        return -1;
    }
  • 获取文件名列表,并创建2个变量,一个是第一个文件名,另一个是最后一个文件名
            File file = new File(logPath);
            if (file.isDirectory()) {
                String names [] = file.list();
                String nameOfFirst = names[0];
                String nameOfLast = names[names.length-1];
                if (dateCount == 0) {
                    //未指定日期,获取最后一个文件名,即最新日志文件
                    dateInput = nameOfLast;
                } else {
                    dateInput = dateInput + ".log.txt";
                }
                for (String name : names) {
                    
                    //首先与最早日志日期比较
                    int firstRes = dateInput.compareTo(nameOfFirst);
                    if (firstRes < 0) {
                        System.out.println("指定日期"+dateInput+"未出现疫情");
                        break;
                    }
                    //其次与最晚日志日期比较
                    int lastRes = dateInput.compareTo(nameOfLast);
                    if (lastRes > 0) {
                        System.out.println("日期超出范围");
                        break;
                    }
                    int res = dateInput.compareTo(name);
                    if (res < 0) {
                        //指定日期比日志文件的日期早
                        break;
                    } else {
                        //当前日志文件的日期比指定日期(未指定则认为指定日志最后一个日期即最新)早或同一天
                        //读取 String filePath = logPath + "/" + name 文件
                        //处理,统计
                        ......
  • 处理统计部分,用正则表达式匹配读取的每行文本,进行不同操作,大体上先用split方法分割该行文本,然后读取首字符串为省份1,若有省份2则读取下标为3的字符串,对最后一个字符串进行处理,获取变化人数,根据不同的匹配来决定是增加还是减少。
    例子:
                                if (isMatch2) {
                                    //<省> 新增 感染患者 n人,ip
                                    String s = getProvinceOne(lineSplit);
                                    int k = getIndex(allProvince,s);
                                    //表示该省在日志文件中出现过
                                    provinceReade[k] = 1;
                                    int numOfChange = getNumOfPeople(lineSplit);
                                    
                                    //记录
                                    totalTable[k][0] += numOfChange;
                                    totalTable[0][0] += numOfChange;
                                    
                                }
  • getProvinceOne方法和getNumOfPeople方法
    //获取人数
    public static int getNumOfPeople(String lineSplit []) {
        //n人
        String last = lineSplit[lineSplit.length-1];
        String num ="";
        for (int i = 0; i < last.length(); i++) {
            if (last.charAt(i) != '人') {
                num += last.charAt(i);
            }
        }
        
        return Integer.parseInt(num);
    }
    
    //获取省份1
    public static String getProvinceOne(String lineSplit []) {
        return lineSplit[0];
    }
  • 按顺序输出指定类型
                                    for (int m = 0; m < 4; m++) {
                                        int k = m + 1;
                                        for (int n = 0; n < 4; n++) {
                                            if (typeAppear[n] == k) {
                                                fileContent += " " + allType[n] + totalTable[i][n] + "人" ;
                                                break;
                                            } else {
                                                if (n == 4) break;
                                            }
                                        }
                                    }

6、单元测试截图和描述

  • 用提供的数据进行了12个测试
    寒假作业(2/2)_第2张图片
  • 单元测试1

    测试基本list功能,只带有必要的2个参数 -log 和 -out 和相应的值进行测试
    寒假作业(2/2)_第3张图片

  • 单元测试2

    在单元测试1的基础上,增加指定日期 -date 2020-01-23 进行测试
    寒假作业(2/2)_第4张图片

  • 单元测试3

    已知日志文件只有22 23 27 这几天,所以修改指定日期为 -date 2020-01-24 进行测试
    寒假作业(2/2)_第5张图片

  • 单元测试4

    在单元测试2的基础上,增加指定类型 -type ip 进行测试
    寒假作业(2/2)_第6张图片

  • 单元测试5

    在单元测试2的基础上,增加指定类型多参数 -type cure dead ip 进行测试
    寒假作业(2/2)_第7张图片

  • 单元测试6

    在单元测试5的基础上,增加指定省份 -province 福建
    寒假作业(2/2)_第8张图片

  • 单元测试7

    在单元测试5的基础上,增加指定省份 -province 全国 浙江 其中浙江未在日志文件中出现
    寒假作业(2/2)_第9张图片

  • 单元测试8

    在单元测试7的基础上,将指定省份的 2个参数 对换位置 -province 浙江 全国 ,理应按原本顺序输出
    寒假作业(2/2)_第10张图片

  • 单元测试9

    测试在日志中出现的省份进行指定的时候,
    寒假作业(2/2)_第11张图片

  • 单元测试10

    测试按不同顺序的-xxx参数,是否能执行成功
    寒假作业(2/2)_第12张图片

  • 单元测试11

    指定日期为日志最早日期的前一天,进行测试
    寒假作业(2/2)_第13张图片

  • 单元测试12

    指定日期为日志最晚日期的后一天,进行测试
    寒假作业(2/2)_第14张图片

  • 由于单元测试11和12在程序中是跳出统计循环的,所以并没有数据,在控制台上输出了相应的错误情况

7、单元覆盖测试率和性能测试

  • 单元测试覆盖率
    寒假作业(2/2)_第15张图片
  • 性能测试
    寒假作业(2/2)_第16张图片
    描述:对上述2张图的具体意义不是很清楚,不过很明显的就是char[]占用的内存比较大。

8、代码风格

【点击前往】

9、心路历程与收获

初次接触了GitHub,觉得这是一个神奇的网站,不论是操作上,还是丰富的资源。还学会了用Junit进行单元测试,以及JProfile进行性能测试。在构建之法中第二章的psp表格部分,我了解到了,工程师在“需求分析”和“测试”方面要花更多的时间,而不是在编码上,而我在编码上花的时间并不能算少,还需要更加努力

10、第一次作业中技术路线图相关的5个仓库

  1. (https://github.com/Snailclimb/JavaGuide)

    【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。

  2. (https://github.com/chenhaoxiang/Java)

    Java的学习之路,学习JavaEE以及框架时候的一些项目,结合博客和源码,让你受益匪浅,适合Java初学者和刚入门开始学框架者

  3. (https://github.com/singgel/JAVA)

    存放JAVA开发的设计思想、算法:《剑指Offer》、《编程珠玑》、《深入理解Java虚拟机:JVM高级特性与最佳实践》、《重构-改善既有代码的设计 中文版》、《clean_code(中文完整版)》、《Java编程思想(第4版)》、《Java核心技术 卷I (第8版)》、《Quartz_Job+Scheduling_Framework》;

  4. (https://github.com/doocs/advanced-java)

    互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识,后端同学必看,前端同学也可学习

  5. (https://github.com/lenve/JavaEETest)

    一些Spring、SpringMVC、MyBatis、Spring Boot案例 ,比如:一个开源的博客系统、Profile注解使用案例、Spring中的事件发送与处理案例、SpringMVC文件上传案例等等

你可能感兴趣的:(寒假作业(2/2))