软工实践寒假作业(2/2)
作业基本信息
摘要
这个作业属于哪个课程 | 课程链接 |
---|---|
这个作业要求在哪里 | 作业链接 |
这个作业的目标 | 阅读《构建之法》并提问,完成词频统计个人作业,撰写博客 |
作业正文 | ... |
其他参考文献 | csdn 百度 |
任务一:阅读《构建之法》并提问
提问
- 书中7.2.4的表7-1 MSF团队模型和关键质量目标里面提到的“出口条件”是什么意思?比如开发的出口条件是:我们是否按照功能说明完成了各项功能。
答:上网查没有查到,我的理解是开发做到了这一点他的任务就完成了。 - 书上8.8.3提到了一个软件团队一开始预计每次天做30小时工作量,做到一半时每天做15小时工作量。我自己在之前的软件编写和大作业上也常常有这样的烦恼。做到后面就要做大量的测试工作,很劳累。和针对测试出的错误修正并确保正确,又很心累。除非快到死线,不然效率都很低。有什么改进的办法吗?
答:我自己做完这次作业想到的是大概按照估计划分时间,比如说预计解决IDEA的git无法push这一bug估计花20分钟,如果给的时间多了就让自己休息一下。如果给少了就再加班加点做完。这样不会有太多的心理障碍。 - 12章的用户体验让我想到了微信。作为被广泛用于社交,办公的软件。他限制了大文件只能在200Mb以下,朋友圈发的图片和视频画质压缩严重。这两方面跟书上说的好的用户体验背道而驰。这是否说明软件发展到一定阶段用户体验反而不太重要了。
答:我觉得微信这种软件,用户群体如此庞大,骂的人多也正常。最重要还是明确自己的产品定位,做好自己优势的功能,其他功能在与同类产品比较差不多就行。 - 15章中提到了在时间不够,功能不能实现时候去砍掉功能。我之前就有一次比赛中一个队友说他想到了一个他刚学会,性能很好的一个方法,做出来肯定二等奖以上。但是3天的比赛我们花了一整天还没有实现,最后只好放弃,而那个队友接下来的时间基本就是在罢工的状态,偶尔还偷偷去做他的功能……遇到这种傻子队友怎么办?
答:我事后想的最好的办法自然是远离傻子队友。要是下一次还遇到,至少除了他以外的人不要被他所影响,也不要指望他能迷途知返。 - 第二章说到单元测试不适合用随机数来做,但应该集成到自动测试框架中,把我有点绕晕了。那自动化单元测试到底是什么?
答:我查了java运行自动化单元测试的资料。在Theories测试中,用户只需给定了一些数据,JUnit自动利用这些数据组合出各种各种可能的组合来执行测试。
任务二:完成词频统计个人作业
Github项目地址
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 20 | 10 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 120 | 150 |
• Design Spec | • 生成设计文档 | 10 | 20 |
• Design Review | • 设计复审 | 20 | 40 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
• Design | • 具体设计 | 80 | 80 |
• Coding | • 具体编码 | 500 | 400 |
• Code Review | • 代码复审 | 60 | 80 |
• Test | • 测试(自我测试,修改代码,提交修改) | 90 | 150 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 15 | 30 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 60 | 80 |
合计 | 1015 | 1080 |
解题思路描述
看到题目之后,就想着大概是用java中的文件类File类来读写文件,字符串处理用String类。经过百度查到文件的读取要用到IO类的BufferedReader。大概就知道要百度什么资料。要求要分成三个模块我就先写一个main函数和在Lib中的函数。根据作业要求也提前看了java使用命令行运行,单元测试,github使用等的知识。
代码规范
计算模块接口的设计与实现过程
项目有两个类:WordCount类和Lib类。
WordCount类中是Main函数
Lib类中是方法函数,有:
- countChars
- countWords
- countMost
- isPartOfWord
- isPartOfAlphaWord
- countLines
关键函数的关系:
Main函数中包含countChars,countWords,countLines,countMost。countWords和countMost中单词判断的部分包含isPartOfWord和isPartOfAlphaWord。关键函数中较为复杂的就是countMost中读取单词后要用HashMap<String, Integer>来存储单词,再用List存储Map,自己重写List的compare方法来实现排序。
关键代码:
- 统计文件的字符数
只统计ASCII码,所以逐个字符读取并判断。使用reader.read()来实现逐字符读取
int tempchar;
while ((tempchar = reader.read()) != -1) {
if (tempchar <= 127 && tempchar >= 0) { //判断是否是ASCII码
charnumber++;
}
}
- 单词按出现次数和字符序排序
重写compare方法来排序。
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(wordarray.entrySet()); //转换为list
list.sort(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
if (o2.getValue() != o1.getValue())
return o2.getValue().compareTo(o1.getValue()); //判断出现次数大小,大的在前面
else
return o1.getKey().compareTo(o2.getKey()); //判断字符序大小
}
});
3.统计行数
一行行读取,再去除空白行。
while (null != (strLine = bufferedReader.readLine())) {
for(int i=0;i<strLine.length();i++)
{
if(strLine.charAt(i)!='\t'&&strLine.charAt(i)!='\r'&&strLine.charAt(i)!=' ') { //空白字符判断要依次判断\t,\r和空格。readline已经省略\n就不用判断了
lineCount++;
break;
}
}
}
4.Main函数中判断输入是否合法
if (args.length == 2) { //只能有两个参数
inputfilename = args[0];
outputfilename = args[1];
//其他代码
}
else {
System.out.println("命令输入错误!");
System.exit(0);
}
性能改进
使用约200,000KB的txt来测试。可以看出程序主要在处理char类和String类。
优化方向以这两个类的IO,处理为主。我更多考虑程序的正确性,暂时没有什么具体的改进想法。
单元测试
部分代码展示:
WordCountTest
public void testMain() throws Exception {
//TODO: Test goes here...
String[] files={"D:\\java\\data.txt","D:\\java\\output.txt"};
WordCount.main(files);
}
public void testMainWrong() throws Exception {
//TODO: Test goes here...
String[] files={"D:\\java\\datawrong.txt","D:\\java\\output.txt"};
try{WordCount.main(files);}
catch (Exception e) {System.out.println("应该出错了");}
}
LibTest
public void testIsPartOfWord() throws Exception {
//TODO: Test goes here...
Lib lib=new Lib();
boolean result1=lib.isPartOfWord('a');
Assert.assertNotNull(result1);
Assert.assertTrue(result1);
boolean result2=lib.isPartOfWord('1');
Assert.assertNotNull(result2);
Assert.assertTrue(result2);
boolean result3=lib.isPartOfWord('\n');
Assert.assertNotNull(result3);
Assert.assertFalse(result3);
}
public void testCountWords() throws Exception {
//TODO: Test goes here...
Lib lib=new Lib();
lib.countWords("D:\\java\\data.txt","D:\\java\\output.txt");
lib.countWords("data.txt","outputTCW.txt");
}
测试截图
使用命令行运行
读取的文件
运行结果
心路历程与收获
本来觉得做软件作业的重点是把代码写完,其他的很快就做完了。做到后面发现做单元测试,代码bug的修复,各种异常状况的处理比想象中花的时间更多。
还有就是不要害怕自己没有做过的事情,毕竟做软件有很多可以查到的资料。看完资料后对改怎么做,大概花多少时间就心里有了底。
之前java课程中也有想过用github管理代码,但做了一段时间就不了了之。而这次作业让我学到了很多github、单元测试的知识,让我懂得了有高的目标才更有完成目标的行动动力。