欢迎来到Gaoann的博客

软工实践寒假作业(2/2)

软工实践寒假作业(2/2)


这个作业属于哪个课程 <福州大学2021春软件工程实践S班>
这个作业要求在哪里 <寒假作业>
这个作业的目标 阅读《构建之法》并提问,完成词频统计个人作业,撰写博客
其他参考文献 《构建之法》

part1. 阅读《构建之法》并提问

前一次作业要求不够详细,部分同学阅读《构建之法》提出的问题过于浅显,没有对提出的问题进行深入思考,因此在本次作业中额外添加了重新阅读《构建之法》并提问这一任务,并布置了更详细的要求。

1. 什么是单元测试

问题来源:
P21中介绍到单元测试是一个对模块质量得到稳定、量化的保证解决方案

我的思考和查证:
思考:
这次作业中提到了要用单元测试,我也在邹欣老师的书里看到了关于单元测试的内容,因为以前都没接触过,就想知道什么是单元测试,他能够帮助我们做什么?
查证:
我查阅了资料得到了以下信息:单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的bai功能是否正确,通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为(这段话来自百度)。单元测试可以使我们的工作变得完善和轻松,会减少最终调试的时间,然后单元测试是一个部分一个部分来的,可以放心的修改这个模块,也可以把这个模块的错误迅速找出来。

2. 在TSP中,个人是否需要灵感和激情

问题来源:
P51~P52中TSP相关内容,书中提到在TSP团队开发的时候,需要理性的工作,个人不需要灵感和激情

我的思考和查证:
思考:我认为在软件开发的过程中,需要保持一定的激情,在我的感受来说,软件开发是一件特别枯燥的事情,如果不能保持激情就会失去兴趣导致效率越来越低甚至开始厌恶,关于灵感我觉得这是一个玄学的东西,你突然就想到了那就很好,灵感可以让你开发出更好的软件,特别是在做一些新的没有样例参考的东西。
查证:
在我通过百度查找相关的资料以及各种不同人士的看法以后,我对这个问题还是比较困惑,希望在以后的经历中能够得到解答。

3. 好的想法一定会赢吗

问题来源:
P350迷思之三:好的想法会赢,关于键盘和国际标准衡量制度的例子

我的思考和查证:
思考:
我一开始看到标题的时候觉得好的方法为什么不会赢?比如书中提到的键盘就很合理,可是最后并没有被采用。还有就是国际标准衡量制度要更合理一些,美国也早就通过了法案,却没有使用,想知道这到底是为什么?
查证:
书中提到了为什么没有使用Dvorak键盘,写的很详细解答了我的疑惑。关于国际标准衡量制度,在我查找资料的过程中发现了这样一段话:“为什么美国仍然是少数几个不使用公制作为主要计量法的国家之一呢?美国人不使用公制的原因很复杂,既有政治、经济方面的考虑,也有民族自豪感。但如果你仔细观察,就会发现SI在美国的影响。最终是否会实现公制还有待观察,但以下是迄今为止,美国不使用公制的主要原因。”也了解到了许多原因,大概了解了为什么好的想法不一定会赢。在现实生活里会有无数创新,可能这个创新是一个特别好的想法,但是因为种种因素无法实现,所以我们在创新的时候应该考虑各个方面的因素。

4.创新者都是一马当先的吗

问题来源:
P351迷思之四:创新者都是一马当先

我的思考和查证:
思考:
创新者为什么不一定是一马当先的?
查证:
书中提到了apple生产的iPod音乐播放器,这个产品我有亲身使用过,在那之前我还用过其他的产品,iPod带我我的体验要比其他的好很多。那iPod的成功是为什么呢?首先是他拥有自己的生态环境,其次他一代一代的更新中不断满足不同用户的需求,并且考虑了真正使用起来会是什么样子。可见,创新不一定要一马当先,创新更多的是要考虑能得到什么,和现有的东西比起来有什么优势,是否符合大众习惯。

5.软件工程为什么能成为一个独立的学科

问题来源:
P10第一章1.1.2软件工程与计算机科学的关系

我的思考和查证:
思考:
一直以来读软件工程这个专业都有些不清不楚,读完邹欣老师构建之法的1.1.2以后发现软件工程更像是一个领域,那他为什么可以成为一个单独的学科呢?我认为可能是因为它是一个应用领域,需要学习与计算机学科其他专业不同的东西来使用它。
查证:
网上有一部分观点是,软件工程是计算机学科的一个分支,但是把它做为一门独立学科也是可以的。我觉得把它作为一门学科的原因是近几年需求变大,感觉也算是一门创新学科,就和前面提到的问题中所说的,创新需要考虑需求还有大众习惯以及它的优势,当社会对软件工程的需求变大以后,就会有越来越多的学校把它开设成一门独立的学科。


part2. WordCount编程

在大数据环境下,搜索引擎,电商系统,服务平台,社交软件等,都会根据用户的输入来判断最近搜索最多的词语,从而分析当前热点,优化自己的服务。首先当然是统计出哪些词语被搜索的频率最高啦,请设计一个程序,能够满足一些词频统计的需求。

1.github项目链接


2.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 30
• Estimate • 估计这个任务需要多少时间 30 30
Development 开发 1200 1800
• Analysis • 需求分析 (包括学习新技术) 200 220
• Design Spec • 生成设计文档 30 30
• Design Review • 设计复审 20 20
• Coding Standard • 代码规范 (为目前的开发制定合适的规范 30 50
• Design • 具体设计 200 240
• Coding • 具体编码 700 900
• Code Review • 代码复审 60 60
• Test • 测试(自我测试,修改代码,提交修改) 60 90
Reporting 报告 120 150
• Test Report • 测试报告 40 60
• Size Measurement • 计算工作量 30 15
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 30 30
合计 2780 3725

3.解题思路

刚开始拿到题目之后有点一头雾水的感觉,因为基础差然后没啥实践,还有些没学过的东西,我就想着一边学一边做,就学着网上的步骤先做了需求分析:

  • 在命令行运行程序
  • 从文件获取输入
  • 统计字符数、单词数、行数还有最多的10个单词及其词频
  • 把统计出来的结果输出到output文件中

然后我就照着需求分析一步一步学习和写程序


4.我的代码规范

我的代码规范


5.计算模块接口的设计与实现过程

根据我的想法,我写了以下几个函数:

  • bool is_digit(char ch) // 判断ch是否是一个数字字符

  • bool is_alpha(char ch) // 判断ch是否是一个字母

  • char lowercase(char ch) // 将ch转换为小写

  • void add_word_to_(WRec &records, const char* word)
    这个函数用来存储把单词放到records结构中便于记录个数

     // 如果是重复单词,重复次数+1 
     if(strcmp(word, records.words[i].word) == 0) {
     	
     	records.words[i].n_word_repeat ++;
     	return;
     }
    
     // 否则作为新的单词添加 
     strcpy(records.words[records.n_word_count].word, word);
     records.words[records.n_word_count].n_word_repeat = 1;
     records.n_word_count ++;
    
  • void sort_WRec(WRec &records)
    这个函数用于排序,按照频率和字典顺序

     	// 单词的频率更大,或评率相同、字典序高的放前 
     	if(records.words[j].n_word_repeat < records.words[j+1].n_word_repeat
     	|| records.words[j].n_word_repeat == records.words[j+1].n_word_repeat && strcmp(records.words[j].word, records.words[j+1].word) > 0) {
     		
     		temp = records.words[j];
     		records.words[j] = records.words[j+1];
     		records.words[j+1] = temp;
     	}
    
  • void wordcount(constcharin_file,constcharout_file)
    这个函数用于对输入文件in_file进行统计,输出到out_file ,思路就是读取文件内容,然后利用之前的函数对每个字符进行识别和操作。文件操作也放在了这个函数里面。一开始因为是按照文本读取文件,换行符没注意,导致结果错误,后来在同学的帮助下把读取文件改成了二进制,解决了这一部分问题


6.性能改进

因为写程序花时间太久,导致没来得及做性能改进


7.单元测试和性能分析

制作了一些文本进行单元测试,文本比较简单。
测试程序如下

TEST_METHOD(TestMethod1)
	{
		wordcount("test.txt", "result1.txt");
		Assert::IsTrue(cmpFile("result1.txt", "expected1.txt"));
	}
	TEST_METHOD(open_file_failed)
	{
		try
		{
			wordcount("test_no_exist.txt", "result3.txt");
			Assert::IsTrue(false);
		}
		catch (std::exception e)
		{
			Assert::IsTrue(true);
		}
	}

此处输入图片的描述

此处输入图片的描述


8.异常处理说明

在文件读写部分做了异常处理,计算部分没有做

  • 传入参数:

     if(argc != 3){		// 参数个数必须为3 
     
     printf("Usage: %s [input_file] [output_file]\n", argv[0]);
     return 1;
     }
    
  • 读写文件:

     input.open(in_file,ios::binary);
     if(!input.is_open() || input.bad()){
     
     printf("文件%s打开失败\n", in_file);
     return;
     }
    

9.心路历程和收获

心路历程

这次作业刚开始我很迷茫,大多数东西都是以前没有接触过的,遇到很多问题,在网上搜索找到解决方法也看不太懂,最后是靠着问同学得到解决,说到底是自己能力不足。我一开始先去写的代码,选择了C++语言,因为我这学期还得重修C++这门课,寒假里也学了一些,也想实践一下,有一些东西我还是没弄懂,于是一边学一边做,程序做的很慢,效率也很低,与PSP表格里面的预计时间差了太多太多。写完程序之后我开始根据作业里的附录学习git、github以及github desktop,由于先写完程序再学的github,commit这一块做的很差。然后我在其中穿插看了《构建之法》,里面有提到团队编程,也许大部分人很期待这个团队编程,但是对于我来说,会带有回避甚至害怕的心理,希望到时候不要拖大家的后腿。看《构建之法》给我最大的感触就是,在我用心看书并提问的过程中,努力做一件事有一种独特的乐趣,看书提问的方式也是我第一次遇到,以前都是全盘接收书本里的知识,我看到一句话叫做尽信书不如无书,这个作业就很好的体现了这一点。

收获

  • 这次实践了解了如何使用Github Desktop、VS2017、github等工具
  • 制订了PSP表格,帮助我在开发的过程中有了一定的架构,提高了效率
  • 学会了做单元测试,这对软件开发过程非常有帮助

这次作业不仅让我有了收获,也让我有了反思,知道了自己水平特别差。这次作业接触了很多新东西,学习并且有收获是特别有成就感的一件事,未来加油!


posted @ 2021-03-05 10:57  Gaoann  阅读(122)  评论(9编辑  收藏  举报