寒假作业(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个数组记录省份,一个记录参数指定的,一个记录日志文件读取过程中出现的省份,用二维数组来记录数据各个省份的各个类型的人数。
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个测试
- 单元测试1
测试基本list功能,只带有必要的2个参数 -log 和 -out 和相应的值进行测试
- 单元测试2
在单元测试1的基础上,增加指定日期 -date 2020-01-23 进行测试
- 单元测试3
已知日志文件只有22 23 27 这几天,所以修改指定日期为 -date 2020-01-24 进行测试
- 单元测试4
在单元测试2的基础上,增加指定类型 -type ip 进行测试
- 单元测试5
在单元测试2的基础上,增加指定类型多参数 -type cure dead ip 进行测试
- 单元测试6
在单元测试5的基础上,增加指定省份 -province 福建
- 单元测试7
在单元测试5的基础上,增加指定省份 -province 全国 浙江 其中浙江未在日志文件中出现
- 单元测试8
在单元测试7的基础上,将指定省份的 2个参数 对换位置 -province 浙江 全国 ,理应按原本顺序输出
- 单元测试9
测试在日志中出现的省份进行指定的时候,
- 单元测试10
测试按不同顺序的-xxx参数,是否能执行成功
- 单元测试11
指定日期为日志最早日期的前一天,进行测试
- 单元测试12
指定日期为日志最晚日期的后一天,进行测试
-
由于单元测试11和12在程序中是跳出统计循环的,所以并没有数据,在控制台上输出了相应的错误情况
7、单元覆盖测试率和性能测试
- 单元测试覆盖率
- 性能测试
描述:对上述2张图的具体意义不是很清楚,不过很明显的就是char[]占用的内存比较大。
8、代码风格
9、心路历程与收获
初次接触了GitHub,觉得这是一个神奇的网站,不论是操作上,还是丰富的资源。还学会了用Junit进行单元测试,以及JProfile进行性能测试。在构建之法中第二章的psp表格部分,我了解到了,工程师在“需求分析”和“测试”方面要花更多的时间,而不是在编码上,而我在编码上花的时间并不能算少,还需要更加努力
10、第一次作业中技术路线图相关的5个仓库
【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。
Java的学习之路,学习JavaEE以及框架时候的一些项目,结合博客和源码,让你受益匪浅,适合Java初学者和刚入门开始学框架者
存放JAVA开发的设计思想、算法:《剑指Offer》、《编程珠玑》、《深入理解Java虚拟机:JVM高级特性与最佳实践》、《重构-改善既有代码的设计 中文版》、《clean_code(中文完整版)》、《Java编程思想(第4版)》、《Java核心技术 卷I (第8版)》、《Quartz_Job+Scheduling_Framework》;
互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识,后端同学必看,前端同学也可学习
一些Spring、SpringMVC、MyBatis、Spring Boot案例 ,比如:一个开源的博客系统、Profile注解使用案例、Spring中的事件发送与处理案例、SpringMVC文件上传案例等等