软工实践寒假作业2/2
寒假作业2/2
这个作业属于哪个课程 | 2021春软工程实践 |
---|---|
这个作业的要求在哪里 | 作业要求 |
这个作业的目标 | 作业目标 |
目录
一、根据《构建之法》提出问题
1、结对编程真的能提升效率吗?
在第四章所提及的结对编程中,书中提及Intuit公司两名技术人员因时间和进度大大落后的问题,最终采取结对编程活动完成项目,书中给出了结对编程的优势和例子,但我仍然对结对编程抱有疑惑,结对编程能否提升编程效率。在我个人经验来讲,两人采取共用一鼠标键盘显示屏的编程方式,过程中可能存在任务分配的矛盾,技术使用的争执,思维方式的不同,以及同一电脑两倍工作量的情况,这些都是阻碍编程效率的因素,所以作者的这个观点我不太能赞同,但不可否认,在时间允许的前提之下,编程质量确实取决于水平技术高的一方,能起到提升程序质量的作用。
2、为什么更多的创新是在拿手领域外发现的呢?
在16章1.5中作者提及“70%的创新者说,他们最成功的的创新,是在他们的拿手领域之外发现的”,不禁让我疑惑为什么更多的创新是在拿手领域之外被发现的呢?文中举了蒂姆博纳斯物理学家在计算机领域提出超文本,阿里巴巴以及诺基亚众多例子,但其中并没有给出这一现象的原因;我通过查阅资料,发现这种现在确实并不为少数,甚至有物理学家卢瑟福拿到诺贝尔化学奖。在我个人认为,在自己的拿手领域,可能因为过多的接触而习以为常,反而会发现一些更加新奇有趣的事物在其他方面上,但是即使发现了在拿手领域外的新事物,也需要该领域、的专业知识才能对其继续突破研究。
3、创新时是一个人更有优势还是一个合作的团队更有优势?
当我看到16章中1.7的内容,谈及“成功的团队更容易成功”时,让我不禁对个人创新和团队创新的关系产生疑惑,创新过程中是一个人更加有优势还是一个团体更加有优势?纵观现今各大科技创新似乎都是以团队为单位进行创新,团队更加占有优势,但是我们看向科学发展历史,哥白尼“日心说”,阿基米德福利定律,牛顿爱因斯坦各大力学理论等等都是个人单打独斗,这两者之间让我对个人和团队创新产生了疑惑。在我个人看来,一些真理定理的发现和科学研究的突破,往往个人更加占有优势;而在技术研究创新,新产品的创新上,团队更加具有优势。
4、5.P36页 两张PSP图的对比,工程师应该更加有经验,为什么花在代码测试上的时间反而更多了呢
在第二章中有PSP数据比较表,分别比较了大四学生以及工作三年的软件工程师完成同一项目在各个阶段所用时间百分比。在表格中,软件工程师测试修改阶段所占时间比远大于大学生所花时间,已工作三年的工程师理应更加有经验,为何测试时间却花费更多?是不是因为编码花费时间较少所花费的代价?后来在经过查阅资料发现,1999年,一个软件漏洞使得价值12亿美元的军事卫星发射失败,1985年加拿大一台放射治疗机器因软件bug而导致3人死亡,可见软件测试一直是整个软件周期中比重最大的一块,花在这部分的时间越长,越能减小软件程序问题。所以更加有经验的软件工程师一般在代码测试上花费的时间越多。
5、在一项团队合作的项目中,要怎样去找到一个合适的团队合作模式?
在第五章团队合作章节中,作者提及了数多个软件团队的模式,但是其中并没有说明一个团队在项目接手之后该如何选择一个更加合适高效的团队模式,我对此产生了疑惑。通过对其他例子的分析,我认为大致可以通过以下几种方式:一是通过分析各个模式的优缺点和特点,然后寻找出与即将接手项目较为契合的模式;二是通过以往类似项目,参考先前团队所采用的团队合作模式,去完善升级;三是根据团队之内所分配任务以及主次关系,来寻找对应的团队合作模式。
6、P212 一味地追求扩展性会有很多副作用,那我们该怎样去把握这个度
在第十章中提及“我们要找到用户需求背后的动机”,但“一味地追求扩展性也会有很多副作用”,那么应该如何去把握“追求”扩展性的度呢?在软件项目分析用户需求时,若仅仅只是按照用户意愿设计需求,那么得到的结果往往是不能使得用户满意因此需要去把握“拓展的度量”,我个人认为,我们可以快速地作出软件的大概模型和基本需求,然后再将其展示给用户,让他提出进一步的改进和其他需求,这样有利于我们去把握这个扩展的度,同时又能让用户满意。
大家知道了软件和软件工程的起源,请问软件工程发展的过程中有什么你觉得有趣的冷知识和故事?
世界上第一个可编程的机器是由法国人Joseph MarieJacquard于1801年发明的雅卡尔织布机,使用打孔卡片进行
编程,控制织布机织出不同的图案。由这个故事可以看出,编程史上的发展并非一帆风顺,并且创新和灵感的来源来自于生活。
二、程序设计分析
1、github项目地址
https://github.com/Ye777/PersonalProject-Java
2、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 40 |
• Estimate | • 估计这个任务需要多少时间 | 1800 | 3000 |
Development | 开发 | 600 | 650 |
• Analysis | • 需求分析 (包括学习新技术) | 240 | 250 |
• Design Spec | • 生成设计文档 | 40 | 60 |
• Design Review | • 设计复审 | 30 | 50 |
• Coding Standard | • 代码规范(为目前的开发制定合适的规范) | 30 | 50 |
• Design | • 具体设计 | 100 | 150 |
• Coding | • 具体编码 | 300 | 350 |
• Code Review | • 代码复审 | 30 | 50 |
• Test | •测试(自我测试,修改代码,提交修改) | 600 | 800 |
Reporting | 报告 | 60 | 90 |
• Test Repor | • 测试报告 | 60 | 80 |
• Size Measurement | • 计算工作量 | 20 | 30 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 120 | 150 |
合计 | 2260 | 2800 |
3、解题思路
查看任务需求需需完成四个功能,字符统计,单词统计,行数统计,词频统计,然后将其输出到文本当中,于是决定写两个类,WordCount类含main函数,用于输出,Lib类包含四个功能,分别用四个方法实现。字符统计因需要统计所有字符,想到使用bufferreader类中的read()方法进行统计,查阅了有关File类以及Bufferreader类有关的使用方法;有效行数通过一行一行读取,然后判断是否为有效行,加入总行数,查阅了正则表达式的相关知识;统计单词数通过Map类的键值对方式进行统计,查阅了Map类的相关知识;词频则对Map类已生成的键值对进行排序输出。
4、给出你的代码规范的链接,即你的仓库中的codestyle.md
5、计算模块接口的设计与实现过程
模块接口设计了一个Lib类,其中包括了四个函数分别实现四个功能,charnum
,linenum
,wordnum
三个静态变量分别保存字符数,有效行数,单词数,Treemap类word
用来保存单词和其对应数量的键值对。
(1)countChar():利用bufferreader类的方法read()
一个个读取文件中的字符,每读取一个charnum
加1;
while((result=reader.read())!=-1)
{
charnum+=1;
}
(2)coutline():使用readline()
一行行读取文件字符放入line
变量中,\s匹配所有空白字符,用replace
函数将line中的\s替换成空字符存入s1,再判断s1是否还有长度,若有则linenum
加1
while((line=reader.readLine())!=null)
{
String s1 = line.replaceAll("\\s", "");
if(s1.length()!=0)
linenum+=1;
}
(3)countWord():用readLine()
一行行读取文件字符放入line中,把line中除了字母数字的字符替换成“ ”空格字符,再把多个空格字符替换成一个空格字符,然后用split(" ")
将该字符串按空格切割成多个字符串存储在String数组s3中,遍历s3匹配单词所应满足的条件后放入word键值对中,value设置为0,最后遍历word统计单次数量
while((line=reader.readLine())!=null)
{
String s1 = line.replaceAll("\\W", " ");
String s2 = s1.replaceAll(" +", " ");
String []s3=s2.split(" ");
for(String a:s3)
{
if(a.length()>3&&(a.charAt(0)<'0'||a.charAt(0)>'9'))
{
word.put(a.toLowerCase(),0);
}
}
}
(4)countKeyword():统计词频的方法与countWord类似,在对其进行排序
while((line=reader.readLine())!=null)
{
String s1 = line.replaceAll("\\W", " ");
String s2 = s1.replaceAll(" +", " ");
String []s3=s2.split(" ");
for(String a:s3)
{
a=a.toLowerCase();
if(a.length()>3&&(a.charAt(0)<'0'||a.charAt(0)>'9'))
{
int number=(int)word.get(a);
word.put(a,number+1);
}
}
}
6、计算模块接口部分的性能改进。
如果每一个功能模块都打开文件并读取一遍,其中的过程会消耗一定量时间,通过优化读取文件的次数,来优化性能,如下图是优化前后读取同一份文件所花费的时间
在统计单词总数与词频时,分别进行了两次遍历,通过将两者结合,在一边统计单词总数时统计每个单词出现的次数,以减少遍历次数,优化性能。一下是优化前后读取用一份文件所花费的时间
7、计算模块部分单元测试展示。
测试的函数其中之一为countChar()
,用于统计字符的数量,测试代码如下:
public void countChar() throws IOException {
Lib.countChar("input.txt");
assertEquals(766450,Lib.charnum);
}
通过比较测试函数产生的值与实际值来进行单元测试,同时单元覆盖率如下:
8、计算模块部分异常处理说明。
处理字符流的输入与输入,抛出IOException
在文件读取操作中,如果流还为准备好输入输出,会打印出“流无法读取”
9、心路历程与收获
在这次项目解决的过程中:
我学会了git,github,github desktop 的使用方法,感受到的关于代码数据存储、修改与查阅的方便之处
学会了单元测试的使用,让我在之后的程序设计之中,能够利用单元测试去提高程序的正确性,检测错误并能够及时地修改
对java文件读写进行了重温与回顾,并且加深和巩固了相关知识,同时接触了代码规范,让我的代码能够让他人更加轻易地读懂。
了解了一个项目工程的大致流程,让我对未来的项目开发有了进一步的认识。