这个作业属于哪个课程 | 2020春|S班 (福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 1、学会使用github 2、制定自己的代码规范 3、设计并完成一个疫情统计程序 4、撰写博客 |
作业正文 | 1、github程序 2、本博客 |
其他参考文献 | 1、猴子都能懂得git入门 2、.gitignore配置语法完全版 3、关于单元测试和回归测试 4、工程师的能力评估和发展 5、《码出高效_阿里巴巴Java开发手册》 6、Java核心技术 |
1、Github仓库地址
本次作业的仓库地址:https://github.com/zhyj2017/InfectStatistic-main
2、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 1060 | 1400 |
Analysis | 需求分析 (包括学习新技术) | 60 | 90 |
Design Spec | 生成设计文档 | 60 | 50 |
Design Review | 设计复审 | 60 | 50 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 60 |
Design | 具体设计 | 120 | 120 |
Coding | 具体编码 | 600 | 850 |
Code Review | 代码复审 | 100 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 150 | 120 |
Reporting | 报告 | 160 | 120 |
Test Repor | 测试报告 | 60 | 40 |
Size Measurement | 计算工作量 | 40 | 20 |
Postmortem Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1280 | 1580 |
3、解题思路描述
刚拿到题目时,我从以下几步开始进行题目的分析
3.1 github初使用
首先学习github的学习,通过注册github账号,上网查询关于git和github desktop的使用教程和自身的实际操作测试,对github有了一定的了解,使我的代码能够帮助更多的人,并且能得到有效的管理和开源共享
3.2 代码规范制定
为了让其他同仁可以轻松的阅读我的代码,我参考《码出高效_阿里巴巴Java开发手册》,制定了属于自己的代码规范
3.3 疫情统计程序的分析
(1)数据结构的设计
一个日志文件文件中存在的信息情况如下:
1、 新增 感染患者 n人
2、 新增 疑似患者 n人
3、 感染患者 流入 n人
4、 疑似患者 流入 n人
5、 死亡 n人
6、 治愈 n人
7、 疑似患者 确诊感染 n人
8、 排除 疑似患者 n人
通过分析可以得出,需要统计的信息有省份、患者类型(感染患者、疑似患者、治愈患者、死亡患者)和人数,我决定设计一个类用来存放这些数据,并使用一个类数组存放所有省份的数据。
(2)文件的读写
显然,该疫情统计程序需要文件的读写功能,例如读取指定文件夹D:\log\下所以的日志文件,并通过指定路径输出文本文件。我决定设计一个读文件功能和一个写文件功能的函数进行文件的读写。
对输入文件的内容进行分析,可从下图中看出,一行文本字符串可拆分成长度为3或4或5的字符串数组:。
(3)命令行参数
该程序的一大特点就是可以通过指定的命令和选项运行程序。一个命令list,带有5个选项-log,-out,-date,-type,-province。
其中,-log,-out该两个选项必须附带,-type,-province可携带一到多个参数值,而其他三个选项只能有一个参数值。我决定设计一个函数用来判断读取的命令的正确性来进行相应的操作。
通过上网查询资料得知,命令行参数可通过main方法中的参数args[]数组传入到程序中
4、设计实现过程
4.1 程序流程图
本程序主要由5个步骤组成:
4.2 程序主体框架图
本程序主要由5个主要部分组成:
4.3 关键函数流程图
(1)isRightCommand方法:
(2)readDirectory方法:
(3)readfile方法:
(4)writeFile方法:
5、关键代码说明
5.1 数据结构
使用StatisticsInformation类来存储一个省份的疫情情况信息。
/**
* 统计全国和所有省的情况的类
*/
class StatisticsInformation{
//省份名字
public String name;
//感染患者人数
public int infection;
//疑似患者人数
public int suspect;
//已治愈人数
public int cure;
//已死亡人数
public int dead;
/**
* 构造函数,用于给类成员赋值
* @param name 省份名字
* @param infection 感染患者人数
* @param suspect 疑似患者人数
* @param cure 已治愈人数
* @param dead 已死亡人数
*/
public StatisticsInformation(String name, int infection, int suspect, int cure, int dead){
this.name = name;
this.infection = infection;
this.suspect = suspect;
this.cure = cure;
this.dead = dead;
}
}
5.2 常量和全局变量
设置一个常量存储所有的省份名字并且按拼音排序,设置一个全局变量数组存储所有省份的疫情情况。常量可以用来初始化全局变量数组,也可以用来判断日志中的省份名是否正确和方便排序。
//常量PROVINCE_ARRAY,用于存储所有的省份名字,已按拼音排序
public static String[] PROVINCE_ARRAY = {"安徽", "澳门", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林", "江苏", "江西", "辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海", "四川", "台湾", "天津", "西藏", "香港", "新疆", "云南", "浙江"};
//全局变量statisticsInformationArrayList,存储所有省份的疾病信息
public static ArrayList statisticsInformationArrayList = initStatisticsInformation();
5.3 判断命令行参数的方法
获得命令行参数的字符串数组,对数组中的元素进行检查,若命令合法则返回true,命令不合法返回false。
/**
* 判断是否为合法命令的方法
* @param str 含有命令的字符串数组
* @return boolean 合法命令则返回true,非法命令则返回false
*/
public Boolean isRightCommand(String[] str) {
//没有list,则为错误命令
if (!str[0].equalsIgnoreCase("list")) {
System.out.println("错误的命令");
return false;
}else {
for (int i = 0;i < str.length;i ++) {
//判断在命令行字符串数组中是否有出现相应选项,有则记录
if (str[i].equals("-log")) {
logNum++;
logPosition = i;
}else if (str[i].equals("-out")) {
outNum++;
outPosition = i;
}else if (str[i].equals("-date")) {
dateNum++;
datePosition = i;
}else if (str[i].equals("-type")) {
typeNum++;
typePosition = i;
}else if (str[i].equals("-province")) {
provinceNum++;
provincePosition = i;
}else if (str[i].startsWith("-")) {
//除了以上5种选项,其余选项都是有问题的
System.out.println("错误," + str[i] + "选项不存在");
return false;
}
}
//判断选项是否存在及选项后参数是否正确存在
if (logNum == 0) {
System.out.println("错误,log是必选选项,不可缺少");
return false;
}else if (outNum == 0) {
System.out.println("错误,out是必选选项,不可缺少");
return false;
}else if (logNum > 1 || outNum > 1 || dateNum > 1 || typeNum > 1 || provinceNum > 1) {
System.out.println("错误,选项不可重复");
return false;
}else {
if (logPosition + 2 < str.length && !str[logPosition + 2].startsWith("-")) {
System.out.println("错误,log选项后只能有一个参数");
return false;
}
if (outPosition + 2 < str.length && !str[outPosition + 2].startsWith("-")) {
System.out.println("错误,out选项后只能有一个参数");
return false;
}
if (logPosition + 1 < str.length && str[logPosition + 1].startsWith("-")) {
System.out.println("错误,log选项后必须要有一个参数");
return false;
}
if (outPosition + 1 < str.length && str[outPosition + 1].startsWith("-")) {
System.out.println("错误,out选项后必须要有一个参数");
return false;
}
readfile = str[logPosition + 1];
writefile = str[outPosition + 1];
if (!readfile.endsWith("\\") && !readfile.endsWith("/")){
System.out.println("目录名错误");
return false;
}
if (dateNum == 1) {
if (datePosition + 2 < str.length && !str[datePosition + 2].startsWith("-")) {
System.out.println("错误,date选项后只能有一个参数");
return false;
}else {
datetime = str[datePosition + 1] + ".log.txt";
}
}
if (typeNum == 1) {
typelist = new ArrayList();
int num = getNearLargeNum(typePosition, logPosition, outPosition, datePosition, provincePosition);
//如果type选项不是命令种的最后一个选项
if (num != typePosition) {
for (int i = typePosition + 1; i < num;i ++) {
if (str[i].equals("ip") || str[i].equals("sp") || str[i].equals("cure")
|| str[i].equals("dead")) {
typelist.add(str[i]);
} else {
System.out.println("错误,不存在" + str[i] + "选项");
return false;
}
}
}else {
for (int i = typePosition + 1;i < str.length;i ++) {
if (str[i].equals("ip") || str[i].equals("sp") || str[i].equals("cure")
|| str[i].equals("dead")) {
typelist.add(str[i]);
}else {
System.out.println("错误,不存在" + str[i] + "选项");
return false;
}
}
//判断ip,sp,cure,dead是否重复出现
if (isRepeatValue(typelist)) {
System.out.println("错误,存在重复选项");
return false;
}
}
}
if (provinceNum == 1) {
provincelist = new ArrayList();
int num = getNearLargeNum(provincePosition, logPosition, outPosition, datePosition, typeNum);
//如果province选项不是命令种的最后一个选项
if (num != provincePosition) {
for (int i = provincePosition + 1; i < num;i ++) {
if (isRightProvince(str[i])) {
provincelist.add(str[i]);
} else {
System.out.println("错误,不存在该省份");
return false;
}
}
}else {
for (int i = provincePosition + 1;i < str.length;i ++) {
if (isRightProvince(str[i])) {
provincelist.add(str[i]);
}else {
System.out.println("错误,不存在该省份");
return false;
}
}
//判断省份是否重复出现
if (isRepeatValue(provincelist)) {
System.out.println("错误,存在重复选项");
return false;
}
}
}
}
}
return true;
}
5.4 读取文件
读取指定路径的文件,将文件内容处理后进行相应的操作,改变statisticsInformationArrayList中的数据。
/**
* 读取一个日志文件的方法
* @param filepath
*/
public void readFile(String filepath) {
File file = new File(filepath);
BufferedReader reader = null;
if (file.exists()) {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
String tempString = null;
while ((tempString = reader.readLine()) != null) {
String opString = tempString.trim();
if (opString.startsWith("//")) {
//如果内容带有“//”注释开头,则不读取
}else {
//把读取的每行字符串转换成字符串数组,并进行相应的操作
String[] strArray = convertStrToArray(opString);
if (strArray.length == 3) {
operateArrayThree(strArray);
} else if (strArray.length == 4) {
operateArrayFour(strArray);
} else if (strArray.length == 5) {
operateArrayFive(strArray);
}
}
}
}catch (IOException e) {
e.printStackTrace();
}finally {
if (reader != null) {
try {
reader.close();
}catch (IOException e1) {
e1.printStackTrace();
}
}
}
}else {
System.out.println("错误,文件不存在");
System.exit(0);
}
}
5.5 写入文件
将statisticsInformationArrayList中的数据按照要求写入到指定路径的文件中。
在没有指定省份的情况下,如果该省份的疫情情况都为0,则不写入文件。
/**
* 将统计好的日志信息写入文件的方法
* @param filepath 指定文件路径
*/
public void writeFile(String filepath) {
File file = new File(filepath);
BufferedWriter writer = null;
if (!file.exists()) {
try {
file.createNewFile();
}catch (IOException e) {
e.printStackTrace();
}
}
try {
writer = new BufferedWriter(new FileWriter(filepath));
StatisticsInformation nation = new StatisticsInformation("全国",
0, 0, 0, 0);
//统计目前全国的感染情况
for (int i = 0;i < statisticsInformationArrayList.size();i ++) {
nation.infection += statisticsInformationArrayList.get(i).infection;
nation.suspect += statisticsInformationArrayList.get(i).suspect;
nation.dead += statisticsInformationArrayList.get(i).dead;
nation.cure += statisticsInformationArrayList.get(i).cure;
}
//存储要写到文件里的一行内容
String writeContent = "";
//只有type选项没有province选项的情况
if (typelist != null && provincelist == null){
setType();
writeContent = nation.name;
if (ipNum == 1){
writeContent += " 感染患者" + nation.infection +"人";
}
if (spNum ==1){
writeContent += " 疑似患者" + nation.suspect + "人";
}
if (cureNum == 1){
writeContent += " 治愈" + nation.cure + "人";
}
if (deadNum == 1){
writeContent += " 死亡" + nation.dead + "人";
}
writer.write(writeContent);
writer.newLine();
for (int i = 0; i < statisticsInformationArrayList.size(); i++) {
if (statisticsInformationArrayList.get(i).infection == 0
&& statisticsInformationArrayList.get(i).suspect == 0
&& statisticsInformationArrayList.get(i).dead == 0
&& statisticsInformationArrayList.get(i).cure == 0) {
}else {
writeContent = statisticsInformationArrayList.get(i).name;
if (ipNum == 1){
writeContent += " 感染患者" + statisticsInformationArrayList.get(i).infection +"人";
}
if (spNum ==1){
writeContent += " 疑似患者" + statisticsInformationArrayList.get(i).suspect + "人";
}
if (cureNum == 1){
writeContent += " 治愈" + statisticsInformationArrayList.get(i).cure + "人";
}
if (deadNum == 1){
writeContent += " 死亡" + statisticsInformationArrayList.get(i).dead + "人";
}
writer.write(writeContent);
writer.newLine();
}
}
}else if (typelist == null && provincelist != null){
//只有province选项没有type选项的情况
setProvince();
Collections.sort(provinceCountList);
if (nationNum == 1){
writer.write(nation.name + " 感染患者" + nation.infection + "人 疑似患者" + nation.suspect
+ "人 治愈" + nation.cure + "人 死亡" + nation.dead + "人");
writer.newLine();
}
for (int i = 0; i < provinceCountList.size(); i++){
writer.write(statisticsInformationArrayList.get(provinceCountList.get(i)).name + " 感染患者"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).infection + "人 疑似患者"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).suspect + "人 治愈"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).cure + "人 死亡"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).dead + "人");
writer.newLine();
}
}else if (typelist != null && provincelist != null){
//type选项和province选项都存在的情况
setType();
setProvince();
Collections.sort(provinceCountList);
if (nationNum == 1){
writeContent = nation.name;
if (ipNum == 1){
writeContent += " 感染患者" + nation.infection +"人";
}
if (spNum ==1){
writeContent += " 疑似患者" + nation.suspect + "人";
}
if (cureNum == 1){
writeContent += " 治愈" + nation.cure + "人";
}
if (deadNum == 1){
writeContent += " 死亡" + nation.dead + "人";
}
writer.write(writeContent);
writer.newLine();
}
for (int i = 0; i < provinceCountList.size(); i++) {
writeContent = statisticsInformationArrayList.get(provinceCountList.get(i)).name;
if (ipNum == 1){
writeContent += " 感染患者"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).infection +"人";
}
if (spNum ==1){
writeContent += " 疑似患者"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).suspect + "人";
}
if (cureNum == 1){
writeContent += " 治愈"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).cure + "人";
}
if (deadNum == 1){
writeContent += " 死亡"
+ statisticsInformationArrayList.get(provinceCountList.get(i)).dead + "人";
}
writer.write(writeContent);
writer.newLine();
}
}else {
//type选项和province选项都不存在的情况
writer.write(nation.name + " 感染患者" + nation.infection + "人 疑似患者" + nation.suspect + "人 治愈"
+ nation.cure + "人 死亡" + nation.dead + "人");
writer.newLine();
for (int i = 0; i < statisticsInformationArrayList.size(); i++) {
if (statisticsInformationArrayList.get(i).infection == 0
&& statisticsInformationArrayList.get(i).suspect == 0
&& statisticsInformationArrayList.get(i).dead == 0
&& statisticsInformationArrayList.get(i).cure == 0) {
}else {
writer.write(statisticsInformationArrayList.get(i).name + " 感染患者"
+ statisticsInformationArrayList.get(i).infection + "人 疑似患者"
+ statisticsInformationArrayList.get(i).suspect + "人 治愈"
+ statisticsInformationArrayList.get(i).cure + "人 死亡"
+ statisticsInformationArrayList.get(i).dead + "人");
writer.newLine();
}
}
}
writer.write("// 该文档并非真实数据,仅供测试使用");
writer.newLine();
}catch (IOException e) {
e.printStackTrace();
}finally {
if (writer != null) {
try {
writer.close();
}catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
5.6 整合所有操作的方法
将所有的操作整合在一个函数中。
/**
* 执行所有操作的方法
* @param str 含有命令的字符串数组
*/
public void allOperate(String[] str){
boolean b = isRightCommand(str);
//如果输入的命令有误,错误退出
if (b == false) {
System.exit(0);
}
//读取指定文件夹下所有文件
readDirectory(readfile);
if (datetime == null){
//如果date选项不存在
for (int i = 0;i < fileList.size();i ++) {
readFile(readfile + fileList.get(i));
}
}else{
//如果date选项存在,判断该日期与该文件夹下以日期为命名的所有文件的关系,通过filelist的下标定位
int pos = -1;
for (int i = 0;i < fileList.size();i ++) {
if (datetime.compareTo(fileList.get(i)) < 0){
pos = i;
break;
}
}
if (pos == -1){
pos = fileList.size();
}
for (int i = 0;i < pos;i ++) {
readFile(readfile + fileList.get(i));
}
}
writeFile(writefile);
}
6、单元测试截图和描述
本次单元测试读取的日志为example下的3个log.txt文件,对allOperate()方法进行10个测试用例的单元测试。
测试用例1:模拟“java InfectStatistic -log d:\log -out d:\out\Testout1.txt”命令。
测试用例2:模拟“java InfectStatistic -log d:\log -out d:\out\Testout2.txt -date 2020-01-24”命令。
测试用例3:模拟“java InfectStatistic -log d:\log -out d:\out\Testout3.txt -type ip”命令。
测试用例4:模拟“java InfectStatistic -log d:\log -out d:\out\Testout4.txt -type sp cure”命令。
测试用例5:模拟“java InfectStatistic -log d:\log -out d:\out\Testout5.txt province 全国 福建”命令。
测试用例6:模拟“java InfectStatistic -log d:\log -out d:\out\Testout6.txt -date 2020-01-24 -type ip”命令。
测试用例7:模拟“java InfectStatistic -log d:\log -out d:\out\Testout7.txt -date 2020-01-24 -province 全国 福建”命令。
测试用例8:模拟“java InfectStatistic -log d:\log -out d:\out\Testout8.txt -type ip -province 全国 福建”命令。
测试用例9:模拟“java InfectStatistic -log d:\log -out d:\out\Testout9.txt -type cure dead -date 2020-01-28”命令。
测试用例10:模拟“java InfectStatistic -log d:\log -out d:\out\Testout10.txt -tdate 2020-01-24 -type sp dead -province 全国 福建”命令。
7、单元测试覆盖率优化和性能测试
7.1 优化前的单元测试覆盖率和性能测试图
7.2 代码优化
(1)对类数组进行初始化赋值时,由34条直接赋值语句改为一条循环赋值语句,减少代码量
优化前:
public static ArrayList initStatisticsInformation() {
ArrayList statisticsInformationArrayList = new ArrayList();
statisticsInformationArrayList.add(new StatisticsInformation("安徽", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("澳门", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("北京", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("重庆", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("福建", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("甘肃", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("广东", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("广西", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("贵州", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("海南", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("河北", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("河南", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("黑龙江", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("湖北", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("湖南", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("吉林", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("江苏", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("江西", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("辽宁", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("内蒙古", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("宁夏", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("青海", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("山东", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("山西", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("陕西", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("上海", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("四川", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("台湾", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("天津", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("西藏", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("香港", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("新疆", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("云南", 0, 0, 0, 0));
statisticsInformationArrayList.add(new StatisticsInformation("浙江", 0, 0, 0, 0));
return statisticsInformationArrayList;
}
优化后:
public static ArrayList initStatisticsInformation() {
ArrayList statisticsInformationArrayList = new ArrayList();
for (int i = 0; i < PROVINCE_ARRAY.length; i++) {
statisticsInformationArrayList.add(new StatisticsInformation(PROVINCE_ARRAY[i],
0, 0, 0, 0));
}
return statisticsInformationArrayList;
}
(2)修改writeFile()中的判断type选项和province选项的参数并设置相应标志的重复代码,重新编写另外两个方法进行判断。
优化后:
public void setType(){
for (int i = 0;i < typelist.size();i ++ ){
if (typelist.get(i).equals("ip")){
ipNum = 1;
}else if (typelist.get(i).equals("sp")){
spNum = 1;
}else if (typelist.get(i).equals("cure")){
cureNum = 1;
}else{
deadNum = 1;
}
}
}
public void setProvince(){
for (int i = 0;i < provincelist.size();i ++){
if (provincelist.get(i).equals("全国")){
nationNum = 1;
}else{
for (int j = 0;j < PROVINCE_ARRAY.length;j ++){
if (provincelist.get(i).equals(PROVINCE_ARRAY[j])){
provinceCountList.add(j);
break;
}
}
}
}
}
public void writeFile(String filepath) {
...
try{
...
if (typelist != null && provincelist == null){
//只有type选项没有province选项的情况
setType();
...
}else if (typelist == null && provincelist != null){
//只有province选项没有type选项的情况
setProvince();
...
}else if (typelist != null && provincelist != null){
//type选项和province选项都存在的情况
setType();
setProvince();
...
}else {
...
}
}
...
}
7.3 优化后的单元测试覆盖率和性能测试图
优化后的单元测试覆盖率有和性能有略微提高:
8、代码规范连接
代码规范链接:https://github.com/zhyj2017/InfectStatistic-main/blob/master/221701238/codestyle.md
9、心路历程与收获
本次作业让我重新地认识了软件工程这门课的内容,感受到它的重要性。我学习了软件工程的定义,学习了如何进行单元测试和效能分析以及学习了如何用PSP表格对自己开发本次项目的过程进行分析,还学习了github、Junit、Jprofiler的使用等知识,使我受益匪浅。当然对自我的反省也是非常重要的。我相信,通过不断地学习和努力,我可以向着成为一名优秀的软件工程师的目标前进一大步。
10、技术路线图相关的5个仓库
(1)JavaGuide
链接:https://github.com/zhyj2017/JavaGuide
简介:【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。
(2)JavaEETest
链接:https://github.com/zhyj2017/JavaEETest
简介:包含了一些关于Spring、SpringMVC、MyBatis、Spring Boot案例
(3)JAVAWeb-Project
链接:https://github.com/zhyj2017/JAVAWeb-Project
简介:初学JAVA-WEB开发的小项目,也适合初学者进行练习
(4)spring-boot-examples
链接:https://github.com/zhyj2017/spring-boot-examples
简介:Spring Boot 使用的各种示例,以最简单、最实用为标准,此开源项目中的每个示例都以最小依赖,最简单为标准,帮助初学者快速掌握 Spring Boot 各组件的使用。
(5)3y
链接:https://github.com/zhyj2017/3y
简介:从Java基础、JavaWeb基础到常用的框架再到面试题都有完整的教程,几乎涵盖了Java后端必备的知识点