作业概述
|
这个作业属于哪个课程 |
|
|
这个作业要求在哪里 |
|
|
这个作业的目标 |
编写代码实现查重功能,学习使用PSP表格,学习commit规范 |
一、github 作业链接
https://github.com/Siomun/Siomun/tree/master/3221005070
二、PSP 表格
|
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
|
Planning |
计划 |
20 |
30 |
|
·Estimate |
估计这个任务需要多少时间 |
300 |
340 |
|
Development |
开发 |
120 |
120 |
|
·Analysis |
·需求分析(包括学习新技术) |
20 |
30 |
|
·Design Sepc |
·生成设计文档 |
10 |
15 |
|
·Design Review |
·设计复审 |
20 |
25 |
|
·Coding Standard |
·代码规范(为目前的开发制定 合适的规范) |
30 |
35 |
|
·Design |
·具体设计 |
20 |
25 |
|
·Coding |
·具体编码 |
30 |
35 |
|
·Coding Review |
·代码复审 |
40 |
50 |
|
·Test |
·测试(自我测试,修改代码,提交修改) |
50 |
60 |
|
Reporting |
报告 |
30 |
40 |
|
·Test Report |
·测试报告 |
30 |
20 |
|
·Size Measurement |
·计算工作量 |
20 |
25 |
|
·Postmortem & Process Improvement Plan |
·事后总结,并提出进程修改计划 |
30 |
35 |
|
·合计 |
800 |
885 |
三、计算模块接口的设计与实现过程
1. 接口的设计及关系
|
类名 |
作用 |
|
PaperCheckMain |
main 方法所在的类 |
|
HammingUtils |
计算海明距离的类 |
|
SimHashUtils |
计算 SimHash 值的类 |
|
TxtIOUtils |
读写 txt 文件的工具类 |
|
ShortStringException |
处理文本内容过短的异常类 |
2. 关键函数流程图

3. 算法的关键及独到之处
引用糊涂工具包的TokenizerEngine,通过hankc作分词处理,遍历词,构建词频树,最后计算查重率:cos值。
查重率cos值具体计算公式如下:

四、计算模块接口部分的性能改进
1. 改进计算模块性能的耗时记录
40mins
2. 描述改进思路
通过各种工具或手段,初步定位性能瓶颈点,通过各种工具或手段,初步定位性能瓶颈点,具体性能优化为getSimHash函数。
3. 性能分析(VS2017/JProfiler)
3.1 性能分析图
3.2 方法调用情况
4. 耗时最大的函数展示

此函数由于调用了HanLP,因此耗时最大。
public static String getSimHash(String str) {
// 用数组表示特征向量,取128位,从 0 1 2 位开始表示从高位到低位
int[] v = new int[128];
// 1、分词
List<String> keywordList = HanLP.extractKeyword(str, str.length());//取出所有关键词
// hash
int size = keywordList.size();
int i = 0;//以i做外层循环
for (String keyword : keywordList) {
// 2、获取hash值
StringBuilder keywordHash = new StringBuilder(getHash(keyword));
if (keywordHash.length() < 128) {
int dif = 128 - keywordHash.length();
for (int j = 0; j < dif; j++) {
keywordHash.append("0");
}
}
// 3、加权、合并
for (int j = 0; j < v.length; j++) {
if (keywordHash.charAt(j) == '1') {
v[j] +=1;
} else {
v[j] -= 1;
}
}
i++;
}
五、计算模块部分单元测试展示
1. 测试函数的说明
// 核心类测试
class SimHashUtilTest {
@Test
void getHash() {
System.out.println(SimHashUtil.getHash("213123"));
}
@Test
void getSimHash() {
System.out.println(SimHashUtil.getSimHash("124123123"));
}
@Test
void getHammingDistance() {
}
@Test
void getSimilarity() {
String simHash1 = SimHashUtil.getSimHash("hasdoihasiodhoiasd");
String simHash2 = SimHashUtil.getSimHash("hasdoihasiodhoiasd");
System.out.println(SimHashUtil.getSimilarity(simHash1,simHash2));
}
2. 测试数据的思路构建
功能测试的测试思路:测试每个部分的功能是否能达到预期结果
2.1 模块接口测试:后台的数据集成在测试框架中,检查测试代码块之间的接口, 和数据的传输等问题。
2.2 执行测试用例:利用下发的测试用例,执行用例将所有需求跑一遍,确认测试需求是否有功能点遗漏,查漏补缺。
3. 单元测试覆盖率(截图)



4. 测试自动化
进入代码运行直接出结果在ansAll.txt中
六、计算模块部分异常处理说明
1. 异常设计目标的介绍
设计目标:为防止文本长度不满足要求而设置的规范长度异常
对应场景:当读取的文本内容少于300字符时将抛出。
2. 异常单元测试样例与检错

七、查重结果
