寒假作业2/2
🎵提示:点击页面左下角播放背景音乐配合阅读更佳🎵
0. 作业基本信息
这个作业属于哪个课程 | 2021春软件工程实践|W班 (福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 深入阅读《构建之法》+学习Git等新技术+完成WordCount程序编写 |
其他参考文献 | 《构建之法》+廖雪峰的Git教程+CSDN |
目录:
0. 作业基本信息
1. 阅读《构建之法》并提问
2. WordCount编程
2.1 Github项目地址
2.2 PSP表格
2.3 解题思路描述
2.4 代码规范制定链接
2.5 设计与实现过程
2.6 性能改进
2.7 单元测试
2.8 异常处理说明
3. 附加题&心得体会
3.1 附加题
3.2 心得体会
1. 阅读《构建之法》并提问
1.1 问题一
Page69 3.1 个人能力和衡量与发展,提到了软件工程师如何衡量、证明自己的能力?引用了一段别有风趣的回答:
问:职业篮球队员都有很详细的记录说明,作为一个职业软件工程师,你有类似的数据说明你所有的职业活动和成绩么?
答:嗯……没有。唯一的数据是,我的“上场时间”还是挺长的,而且经常打加时赛—加班。什么样的数据能说明一个软件工程师的技术和能力呢?衡量能力有哪些参数?没有量化的指标,就谈不上衡量和比较。我们还是看看搬砖的伙计们,关于工作量,他们:有多少块砖?要搬多远?他们也有简单的指标衡量工作质量。多快搬完?搬的过程中损坏了多少块砖?
感觉职业篮球运动员和搬砖的伙计都不能很好的衡量或证明一个软件工程师的能力。 项目/任务有多大?花了多少时间?质量如何?是文章后续PSP认为的几大因素。这让我联想到了之前在知乎看过的如何在面试中证明自己是优秀的软件测试工程师的问题,就包括了基础的软件技能、测试流程熟悉、问题分析敏锐、善于总结分享等。个人认为,一个软件工程师的能力必来源于不断的学习,项目、博客、github等正是对你所掌握能力的一个证明。只要功夫在,不怕没饭吃。
1.2 问题二
Page33 1.2 提到了软件工程是什么?
软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上的过程。
本学期也开始学习到《设计模式与软件体系结构》这门专业课,特别对北京大学杨芙清老师的《中国软件工程历程与发展》进行学习,进一步理解了软件工程的定义以及软件工程教育为中国软件传业发展提供了有力的人才支撑。也回想到寒假作业1/2中我自己写的为什么当初选择软件工程专业的问题。在我看来,软件工程是应用计算机科学理论与技术以及工程管理原则与方法实现满足用户要求的软件产品的学科。
1.3 问题三
Page181 8.3 获取用户需求——用户调查踢到了软件需求阶段的获取信息手法
开发软件时,我们总想知道用户到底想的是什么,对各种功能的偏好是什么,掌握这些信息,我们就可以按部就班地去满足用户的需求。大家可以靠直觉,靠老板的命令,靠互联网上传来的各种信息,靠拷贝其他软件,靠其他不靠谱的手段……当然我们也可以靠一些经过实践证明行之有效的办法,其中许多具体做法既可以用在软件需求的收集阶段,也可以用在测试阶段。
这反映了从用户需求到软件设计的这么一个过程,大学阶段对于面向对象分析与设计、设计模式与软件体系结构、软件工程的学习也加强了我对用户需求分析的了解。最近我听到很多人都在讨论产品经理及其定位,当产品经理将公司的战略转化为产品的目标后,就需要从中挖掘需求。这些需求不光是来自用户的,还可能是市场需求,公司内部的需求。当然这只是产品经理众多职责的一个部分,我想这也是产品经理在当今软件开发中如此重要的一个原因吧。
1.4 问题四
Page362 16.1.3 提到经典迷因
好的想法会赢学理工科的同学都比较理性,大多会认为,好的想法当然会赢啦。就像解数学题一样,好的解法当然会得高分啦。好主意一定会把不太好的主意都比下去。但是在现实中,好的主意不一定赢。例如,看看我们日常使用的电脑键盘,作者打赌99.9%的键盘都是这样的布局(QWERTY),但是很多研究者认为下面的键盘布局(Dvorak)更有效率。
这便是先入为主对人的影响,经过网络资料的搜索,得出是因为更换成本太高,在“约定俗成”面前,效率完全不构成优势。最近我弟弟一年级做二位数与一位数加减法的时候就有我以前没有学过的“平十法”、“破十法”等,这在我看来就有点打破常规的感觉。在我看来,在软件开发的过程中必定也会遇到各种各样的约定俗成的难以打破的僵局,但这不代表创新越困难,一个能打破僵局的软件产品必定是史诗性的。
1.5 问题五
Page389 16.1.6 提到经典迷因
这个想法对理工科的同学们来说更是自然不过,很多同学孜孜不倦地跟踪某技术各个版本的细节,津津乐道其中奥秘。一些同学的想法大约是——学习各种科学技术,从本科到硕士、博士、博士后,然后创新、齐家治国平天下。例如,我们看看手机的发展历史,哪一次进步不是技术的进步带来的呢?
这引起了我对最近一个新闻热点事件的思考,关于Clubhouse这个软件,“马斯克也在用的 App”,是很多人对这款 App 的最大认知。这已经成为继 Facebook 和 TikTok 之后一个新的现象级社交软件。甚至一时之间,几十款“中国版Clubhouse”都即将面世。这款产品并没有使用多么尖端的技术,在我看来Clubhouse的火爆告诉我们只要精心设计,即使用并不是那么先进的技术也可以打造出爆款的产品。技术的创新固然是关键,但并不是全部原因。
2. WordCount编程
2.1 Github项目地址
2.2 PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
• Estimate | • 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 475 | 610 |
• Analysis | • 需求分析 (包括学习新技术) | 60 | 70 |
• Design Spec | • 生成设计文档 | 30 | 30 |
• Design Review | • 设计复审 | 15 | 15 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 20 | 15 |
• Design | • 具体设计 | 30 | 30 |
• Coding | • 具体编码 | 240 | 300 |
• Code Review | • 代码复审 | 20 | 30 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 120 |
Reporting | 报告 | 110 | 90 |
• Test Repor | • 测试报告 | 50 | 40 |
• Size Measurement | • 计算工作量 | 20 | 20 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 40 | 30 |
合计 | 605 | 730 |
2.3 解题思路描述
当我看到作业的时候第一反应是啥也不会,虽然好像有挺长时间的,但是因为看不懂题目要做什么觉得很慌,但是觉得老师既然这么布置肯定认为我们绝大多数人在这段时间内可以完成新技术的学习和作业的完成,所以我便开始完成作业的规划。首先先看一下不会的技术,包括Git、Github、单元测试、性能分析、PSP表格、参数处理……
技术学习后,决定用Java进行项目的开发,首先想到的是在main函数打开文件并传入几个模块中包括统计字符数、统计行数、统计单词数、统计词频。对于统计词频需要单词和数据的映射,第一时间考虑到HashMap,并搜查了资料了解其对应的有关函数并照着类似的代码打了一遍。
2.4 代码规范制定链接
2.5 设计与实现过程
项目src目录包括2个java文件,其中Lib里包含Lib与CountData两个类。WordCount作为主函数,Lib作为工具类存放程序需要的功能。
其中CountData类用于存储文件的字符数、单词数、行数、词频,应用到下列函数。
void setCountWord(int n);
void setCountLine();
void setCountChar(int n);
void setGetWordFrequency(HashMap<String, Integer> n) ;
int getCountWord();
int getCountLine();
int getCountChar();
List<Map.Entry<String, Integer>> getGetWordFrequency();
Lib类则包含实现功能的主要函数,具体描述如下。
2.5.1 读取文件
统计行数、单词数、词频统计共同由一个openFile()函数调用,统计字符数功能独立调用一次。通过CountData类的实例对象data存储文件的数据。
static void openFile(File input) {
try {
FileReader fr = new FileReader(input);
BufferedReader br = new BufferedReader(fr);
String s = "";
while ((s = br.readLine()) != null) {
data.setCountLine();
data.setCountWord(countWord(s));
data.setGetWordFrequency(getWordFrequency(s));
}
br.close();
fr.close();
return;
}
}
2.5.2 统计字符数
调用read方法从输入流中读取最多len个字节的数据到一个字节数组中。
static int countChar(File file) {
int myCountChar = 0;
try {
byte[] tem = new byte[20 * 1024];
int len = tem.length;
int bytes = 0;
FileInputStream in = new FileInputStream(file);
while ((bytes = in.read(tem, 0, len)) != - 1)
myCountChar += bytes;
data.setCountChar(myCountChar);
in.close();
}
finally {
return myCountChar;
}
}
2.5.3 统计单词数
通过Java自带的方法判断是否为数字、大写字母、小写字母等,同时借此判断存储的字符串是否为单词。
static int countWord(String s) {
int myWordCount = 0;
String word = "";
for (int i = 0; i < s.length(); i++) {
if (Character.isDigit(s.charAt(i)) || Character.isUpperCase(s.charAt(i))
|| Character.isLowerCase(s.charAt(i))) {
word += s.charAt(i);
}
else {
}
return myWordCount;
}
2.5.4 统计词频
将单词存入HashMap,检测是否存在单词的key,若存在,则其value+1,若无插入新的key-value。
static HashMap<String, Integer> getWordFrequency(String s) {
String word = "";
HashMap<String, Integer> myWordCount = new HashMap<String, Integer>();
for (int i = 0; i < s.length(); i++) {
if (Character.isDigit(s.charAt(i)) || Character.isUpperCase(s.charAt(i))
|| Character.isLowerCase(s.charAt(i))) {
word += s.charAt(i);
}
else {
}
}
return myWordCount;
}
2.6 性能改进
-
读取文件过程中用一个函数读取文件,另外两个函数配合,以此提高运行效率。
-
在IO处理上,资料显示读取文件使用BufferedReader会比使用FileReader更合适,故使用了BufferedReader和BufferedWriter类。
-
性能测试截图:
2.7 单元测试
- 测试统计字符数功能(100000个字符)
@Test
BufferedWriter fileWriter = new BufferedWriter(new FileWriter("input.txt"));
Random r = new Random(1);
for(int i = 0; i < 100000; i++){
fileWriter.write( r.nextInt(1000) + " ");
}
fileWriter.close();
}
耗时:582ms
- BBC News某文章测试(现实应用)
characters: 2869
words: 284
lines: 40
nickel:10
caledonia:8
mine:6
will:6
tesla:5
electric:4
agreement:3
control:3
goro:3
mining:3
耗时:786ms
- 测试覆盖率截图:
在编写程序前对功能有着合理的区分、规划,能有效提升其覆盖率。
2.8 异常处理说明
对于IO流的异常处理,如try、catch等。因为项目较小,无自定义异常处理。
3.附加题&心得体会
3.1 附加题
Python由荷兰人Guido van Rossum在1989年发明,据说是为了打发圣诞节的无趣,1991年首次发布,是ABC语言的继承,同时也是一种脚本语言,目前已经很流行。取名时,Guido van Rossum认为它应该“短小,独特,还有一点神秘感”,加上他是英国著名剧团Monty Python的忠实粉丝,所以就是Python了。Python还有巨蟒的意思。
链接:http://kids.codepku.com/article/132
3.2 心得体会
以往我只是简单的觉得自己只会老师教的知识,很少自己去学习课外的本领。嘴上虽然天天说,但是实际却从没有付之行动,在开始本次作业后,我深深的感觉到了无力,Git、GitHub desktop、单元测试、性能优化.....一眼看去基本上都不会,这才开始了新技术的学习,学习效率又很低,最后时间很赶(很多步骤也没有按照正规流程完成),因此我认为本次作业对我最大的收获是为我敲醒了警钟,看清自己与好同学之间的差距,明白自己接下来以怎样的态度去学。同时我也在本次作业中了解了很多的新知识,只要用功本领是会掌握的,但一定要做好时间规划,不要一拖再拖最后压着时间线交。