寒假作业(2/2)
作业基本信息
这个作业属于哪个课程 | 2021春软件工程实践|W班(福州大学) |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 重新阅读《构建之法》并提出自己的问题或理解,初步学习Git完成WordCount编程并用PSP记录 |
作业正文 | 寒假作业2/2 |
其他参考文献 | 《构建之法》,《c++ Primer》,csdn |
PART 1. 阅读《构建之法》并提问
问题一
阅读第1.2.2节时,深有感触,报考专业就见到了这两门不同的学科。经过两年的学习粗略地了解到计算机科学学习内容比较广泛,偏向于硬件方面,而软件工程专精于软件的实践,在阅读此节时又加深了对二者的了解。书中概括了两门课程的侧重点:
计算机科学 | 软件工程 |
---|---|
发现和研究长期的、客观的真理 | 短期的实际效果(具体的软件会过时) |
理想化 | 对各种因素的折衷 |
确定性、完美、通用性 | 对不确定性和风险的管理,足够好,具体的应用 |
各个学科独立深入研究,做出成果 | 关注和应用各个相关学科的知识,解决问题 |
理论的统一 | 百花齐放的实践方法 |
形式化,追求简明的公式 | 在实践中建立起来的灵感和直觉 |
正确性 | 可靠性 |
查阅百度百科可得两者的定义: | |
计算机科学,研究计算机及其周围各种现象和规律的科学,亦即研究计算机系统结构、程序系统(即软件)、人工智能以及计算本身的性质和问题的学科。计算机科学是一门包含各种各样与计算和信息处理相关主题的系统学科,从抽象的算法分析、形式化语法等等,到更具体的主题如编程语言、程序设计、软件和硬件等。计算机科学分为理论计算机科学和实验计算机科学两个部分。后者常称为“计算机科学”而不冠以“实验”二字。前者有其他名称,如计算理论、计算机理论、计算机科学基础、计算机科学数学基础等。数学文献中一般指理论计算机科学。 | |
软件工程是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。它涉及程序设计语言、数据库、软件开发工具、系统平台、标准、设计模式等方面。在现代社会中,软件应用于多个方面。典型的软件有电子邮件、嵌入式系统、人机界面、办公套件、操作系统、编译器、数据库、游戏等。同时,各个行业几乎都有计算机软件的应用,如工业、农业、银行、航空、政府部门等。这些应用促进了经济和社会的发展,也提高了工作效率和生活效率 。 | |
学习计算机科学以后的发展与学习软件工程以后的发展有不同何?资料显示学习计算机技术的也可以转向软件开发之类的行业,那社会为什么还有软件工程方面的人才需求呢? |
问题二
第2.1节提到了单元测试,简单来说这可以保证自己负责的模块的独立和质量。定义:单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。那么所有的模块都需要写单元测试吗?还是说存在不需要的情况?
问题三
2.3节讲到个人开发流程,cmu开发的psp到底包含了什么?对我们开发软件有什么帮助?为什么能迅速地流行起来?
随着软件工程知识的普及,软件工程师都知道,要开发高质量的软件,必须改进软件生产的过程。业界公认由CMU/SEI开发的软件能力成熟度模型SW-CMM是当前最好的软件过程,并且CMM已经成为事实上的软件过程工业标准。但是,CMM虽然提供了一个有力的软件过程改进框架,却只告诉我们"应该做什么",而没有告诉我们"应该怎样做",并未提供有关实现关键过程域所需要的具体知识和技能。为了弥补这个欠缺,Humphrey又主持开发了个体软件过程(Personal Software Process,PSP)。个体软件过程(Personal Software Process,简称PSP)为软件人员进行软件开发提供了一个规范的个人过程框架,PSP过程由一系列方法、表单、脚本等组成,用以指导软件人员计划、度量和管理他们的工作,同时它显示了如何定义过程及如何测量其质量和生产率,这使得psp迅速成为程序员们的得力助手。
问题四
第五章讲到了团队,并给我们推荐了《梦断代码》这本书。它讲述了OSAF开源基金会开发日历管理软件Chandler的过程,前后两打程序员,3年时间,4732个bug,耗费百余万美元,只为了打造(听上去似乎很容易,但想来应该不至于简单)一款全功能的日历软件。这是当时项目的墓志铭,为我们介绍项目失败的全过程,以及从中得到的教训。此外我还在知乎找到了邹欣老师的专栏:梦醒时分 - 梦断代码读后感。这更让我感受到了软件工程的千难万难,软件乃是人类自以为有把握,实则难掌控的技术。但是就如同邹欣老师所说:Build To Win--不管中间有多少挫折,但是我一定要赢。这才是我辈该追求的精神。
问题五
第十三章里描述了各式各样的测试,可以按照设计方法分类,可以按照测试的目的分类......然后阐述了各种测试方法。我想太多不同的测试方法会不会过于冗余?能不能编写一个测试概括了所有的测试方法的功能?再细想之后,这种方案是不可行的。写代码要循序渐进,测试也是从小做起,从一开始的单元测试,到最后外部软件测试人员在实际情况下的测试,相去甚远,测试方法绝不能一概而论。各种测试方法各司其职,最终才能得到让用户较为满意的产品。
问题六
十六章迷思之五:要成为领域的专家,才能创新。这句话我并不是很赞同,书中接下来的阐述也证实了这一点。下面所举的例子也说明了许多行业的重大进步反而离不开“门外汉”的努力。我觉得软件开发也是如此。许多新的项目不就是一些非专家的灵光一现然后投入研究的吗?反之不正是利用创新做出了令人信服的产品才能算为专家吗?所以这句话我不敢苟同。
软件工程发展过程中的冷知识
第一款数字化电脑游戏从未带来任何利润回报
现在的视频游戏已经成为了最受瞩目的程序开发成果,然而历史上第一款数字计算机游戏则遭遇巨大失败。第一个电脑游戏出现于1962年,由麻省理工学院的计算机程序员Steve Russell与其团队一同编写,这款名为《太空大战》的游戏耗费了他们近200个小时。该游戏允许两名玩家分别控制两艘飞船,目标是击中并摧毁对方飞船,并且玩家还需要躲避屏幕中代表星球的小白点。如果玩家撞上这些星球,则游戏失败。虽然Russell和他的团队从未在这个游戏说的任何收益,但必须承认,如果没有这一突破我们可能永远不会拥有如今蓬勃发展的游戏产业。
PART 2. WordCount编程
2.1 Github项目地址
https://github.com/Mr-Qingkong/PersonalProject-C
2.2 PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
• Estimate | • 估计这个任务需要多少时间 | 3day | 1370 |
Development | 开发 | ||
• Analysis | • 需求分析 (包括学习新技术) | 30 | 120 |
• Design Spec | • 生成设计文档 | 20 | 20 |
• Design Review | • 设计复审 | 15 | 15 |
• Coding Standar | • 代码规范 (为目前的开发制定合适的规范) | 30 | 20 |
• Design | • 具体设计 | 60 | 60 |
• Coding | • 具体编码 | 720 | 960 |
• Code Review | • 代码复审 | 30 | 45 |
• Test | • 测试(自我测试,修改代码,提交修改) | 60 | 80 |
Reporting | 报告 | ||
• Test Repor | • 测试报告 | 20 | 20 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 20 |
• 合计 | 1015 | 1370 |
2.3 解题思路描述
采用c++编程。这个项目用到文件输入输出流(I/O),这些知识在大二就已经学习,现在复习并提高相关内容的理解。编写函数统计文件中的字符并实现要求的功能。
- 读取文件
- 统计字符数、单词数、有效行数、统计出现最多的十个单词及词频。
- 关于单词的统计,我一看见这个题目就想起了以前的一题c++实践题:设计一个随机文章生成器,输入一篇文章后可以输出另一篇文章(所用字符相同)。当时使用了vector容器和map存取字符串。这个项目有相似之处,查阅相关资料后,也沿用了这两个容器。
2.4 代码规范制定链接
2.5 设计与实现过程
容器的使用:
vector<string> str;
vector<string> words;
map<string, int> strmap;
map<string, int>::iterator iter;
先画一个简单的结构图
ReadFile函数:利用get函数逐个析取文件中的字符并存放在临时字符串变量temp中;
CountWord函数:由于单词的统计和非空行的统计均涉及了非空白字符的判断所以放到一个函数。
CountMainWord函数:用map遍历计算单词出现次数并输出排行前十的单词及其次数:
iter = strmap.begin();
int min_val = strmap.size() < 10 ? strmap.size() : 10;
for (int s1 = 0; s1 < min_val; s1++)//采用遍历10次的的方式,如果不足十次bool值置false跳出循环
{
if (flag == false)
{
break;
}
flag = true;
time = -1;
while (iter != strmap.end())//采用map进行存取遍历
{
if (iter->second > time)
{
time = iter->second;
mainWord = iter->first;
}
iter++;
}
fout << mainWord << ": " << time << endl;
iter = strmap.begin();
strmap[mainWord] = -9;
}
2.6 性能改进
- 一开始文件只能处于相同目录下,改进为任意位置
- 使用c语言的fopen打开文件可以让读取文件提速
2.7 单元测试与测试覆盖率
对复杂情况进行测试,能正确输出
覆盖率截图
增加异常处理情况就能提高代码覆盖率
2.8 异常处理说明
- 打开文件失败报错
2.9 心路历程与收获
- 用了很多的时间在查阅资料上,真正写代码的时间反而不长。有点本末倒置。
- 真正完成一个项目的感觉与想象中的完全不同,只有亲身经历过才知道就是再简单的项目也要完成每道过程,缺一不可,“麻雀虽小,五脏俱全”。
- 编写自己的代码规范让自己的代码成为“文明人”。
- 很久没有完整的编写一个C++代码,这次实践让我更加熟悉c++流的内容。第一次做单元测试完成的不够好,接下来应该有所长进。
- 完成项目的那一刻整个人都升华了。