[BUAA软工]第一次结对作业
[BUAA软工]结对作业
本次作业所属课程: 2019BUAA软件工程
本次作业要求: 结对项目
我在本课程的目标: 熟悉结对合作,为团队合作打下基础
本次作业的帮助:理解一个c++ 项目的开发历程
【1】项目github
Pre
【2】pre -1. PSP 表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
| Planning | 计划 | 60 | 80 |
| · Estimate | · 估计这个任务需要多少时间 | 14天 | 14天 |
| Development | 开发 | 7天 | 9天 |
| · Analysis | · 需求分析 (包括学习新技术) | 0.5天 | 0.7天 |
| · Design Spec | · 生成设计文档 | 120 | 150 |
| · Design Review | · 设计复审 (和同事审核设计文档) | 60 | 60 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 50 |
| · Design | · 具体设计 | 1天 | 1天 |
| · Coding | · 具体编码 | 4天 | 5天 |
| · Code Review | · 代码复审 | 1天 | 1.5天 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 1天 | 1天 |
| Reporting | 报告 | 1天 | 1天 |
| · Test Report | · 测试报告 | 2小时 | 4小时 |
| · Size Measurement | · 计算工作量 | 1小时 | 1小时 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 0.5天 | 0.5天 |
| 合计 | 10天 | 13天 |
【3】pre-2 学习接口设计
看教科书和其它资料中关于Information Hiding, Interface Design, Loose Coupling的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的
(1)Information Hiding:[wiki]In computer science, information hiding is the principle of segregation of the design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change).
我们小组使用类对于数据进行封装,保证稳定的接口,来保护程序的其他部分不受影响。
(2)Interface Design
接口基本与作业要求一致,尽量将不同的实体封装,尽量少使用全局变量,全局函数。
(3)Loose Coupling
松耦合,与别的小组互换core、gui和test, 对方封装得足够好,调用起来就非常方便,我们自己的模块封装性不好,技术上还需要提升。
具体设计
1. Core模块设计
【4】计算模块接口的设计与实现过程。
设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处
设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处
有三个类,word类负责保存单词的基本属性,wordlist类则负责保存单词链,maxtrix的主要作用是用来计算相应的最长单词链。计算最长单词链的算法是用到了拓扑排序,首先将所有单词中的没有办法和其它单词练成链的单词去除。然后构建邻接矩阵。之后通过拓扑排序以及动态规划找出最长的单词链和最多字母的单词链。
第一个版本存在着各式各样的问题:
严重性 代码 说明 项目 文件 行 禁止显示状态
警告 C26495 Variable 'Maxtrix::row' is uninitialized. Always initialize a member variable (type.6). Wordlist c:\users\a\desktop\projects\worldlist(4)\worldlist\worldlist\maxtrix.cpp 6 活动的
......
......
......
警告 C4101 “length”: 未引用的局部变量 Wordlist c:\users\a\desktop\projects\worldlist(4)\worldlist\worldlist\maxtrix.cpp 166
警告 C4101 “maxlength”: 未引用的局部变量 Wordlist c:\users\a\desktop\projects\worldlist(4)\worldlist\worldlist\maxtrix.cpp 242
警告 C4101 “fileWord”: 未引用的局部变量 Wordlist c:\users\a\desktop\projects\worldlist(4)\worldlist\worldlist\main.cpp 28
后续的版本加以改进了。
【5】画UML
阅读有关UML的内容:https://en.wikipedia.org/wiki/Unified_Modeling_Language。画出UML图显示计算模块部分各个实体之间的关系(画一个图即可)。
自动生成的UML

类其实比较简单,Matrix调用Wordlist, Wordlist调用Word.
2.首个版本性能测试
【6】计算模块接口部分的性能改进。
记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2015/2017的性能分析工具自动生成),并展示你程序中消耗最大的函数
一开始我们采用的算法是,再把所有的单词进行拓扑排序之后,找出所有的链,然后对所有的链进行统计,找出其中最多字母的链。但是当单词数多起来比如达到了9000个单词之后速度特别慢。很长时间都跑不出来结果。
后来我修改了算法,再计算字母最多链的时候,引入了动态规划算法,算出了起始点到终点的最长距离,并且记录了其前驱节点。改进完毕之后速度快了很多,可以正常跑完9000个无环的测试样例。

【7】看Design by Contract, Code Contract的内 容:
http://en.wikipedia.org/wiki/Design_by_contract> http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
描述这些做法的优缺点, 说明你是如何把它们融入结对作业中的
契约编程
严格规定前置条件,后置条件,不变项,可以很好的规范程序接口,程序的正确性得到了更大的保证, 但是这一做法比较费时费力,不那么适用于敏捷开发。但是我们可以对于核心的,非常重要的模块进行接口的严格规定,约束程序行为,让开发兼顾开发效率和正确性。
3. 测试用例及结果
【8】计算模块部分单元测试展示。
展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。要求总体覆盖率到90%以上,否则单元测试部分视作无效。
用例:
TEST_METHOD(testWord)
{ Word* w = new Word();
w->setWordName("abc");
w->setIndegree(0);
w->setMaxLength(strlen("abc"));
w->setSearched(true);
w->setTopuLevel(3);
Assert::AreEqual(w->getFirstAlp(), 'a');
Assert::AreEqual(w->getLastAlp(), 'c');
Assert::AreEqual(w->getWordLength(), 3);
free(w);
结果:正确,构造这条数据验证Word类的正常功能,这是整个程序中最小最基本的数据抽象封装。
用例:
TEST_METHOD(testWordlist)
{ Wordlist *wl = new Wordlist();
char* set[] = { "hello","on","next","take","err" };
for (int i = 0; i < 5; i++) {
wl->add(set[i]);
}
Assert::AreEqual(wl->getAlpNum(),18);
Assert::AreEqual(wl->getFirstLetter(), 'h');
Assert::AreEqual(wl->getLastLetter(), 'r');
free(wl);
}
结果:正确, 测试wordlist类的正常功能,这个类用来表示计算得到的最长链
用例:
TEST_METHOD(testMaxtrix) {
Maxtrix m //= new Maxtrix();
char* set[] = { "hello","on","next","take","aaa" ,"abbc","dd" };
char* result[] = { "hello","on","next","take" };
for (int i = 0; i < 7; i++) {
m->setWord(set[i], i);
}
m.deleteOutlier();
m.initialMatrix();
m.createMatrix();
m.topuSort();
m.findInMaxtrix();
m.findMaxLengthChain();
for (int i = 0; i < m->wordChain.wordNum; i++) {
Assert::AreEqual(m->wordChain.wordList[i], result[i]);
}
}
结果1:错误,需要注意的问题是,在main.cpp中声明了一个全局的Maxtrix对象matrix,但是Maxtrix.h中设定max_word_num = 10005;而且有一个属性int maxtrix[max_word_num][max_word_num];作为邻接矩阵, 这么大的二维数组放在全局空间是没有问题的, 但是在测试的时候,声明一个maxtrix是会爆栈的,Exception Code: C00000FD, 还是用new 或者malloc来管理内存吧。
在默认情况下,栈只能得到1M大小的内存,全局静态储存可以得到2G,而在32位和64位下的堆则可以得到2G和无限内存(一般不会用到16T)。
结果2:
结果 StackTrace:
at strcpy_s<1000>() in c:\program files (x86)\windows kits\10\include\10.0.17763.0\ucrt\string.h:line 124
at Wordlist::add() in c:\users\xxx\desktop\worldlist(4)\worldlist(4)\worldlist\worldlist\wordlist.cpp:line 11
at Maxtrix::findMaxLengthChain() in c:\users\xxx\desktop\worldlist(4)\worldlist(4)\worldlist\worldlist\maxtrix.cpp:line 168
at UnitTest1::UnitTest1::testMaxtrix() in c:\users\xxx\desktop\worldlist(4)\worldlist(4)\worldlist\unittest1\unittest1.cpp:line 59
结果 消息: Invalid parameter detected in function common_tcscpy_s, minkernel\crts\ucrt\inc\corecrt_internal_string_templates.h line 81. Expression: (L"Buffer is too small" && 0)
用例:
TEST_METHOD(testMaxtrix) {
Maxtrix* m = new Maxtrix();
char* set[] = { "Algebra","Apple","Zoo","Elephant","Under","Fox",
"Dog","Moon","Leaf","Trick","Pseudopseudohypoparathyroidism" };
char* result[] = { "Algebra","Apple","Elephant" };
Assert::AreEqual(1, 1);
for (int i = 0; i < 7; i++) {
m->setWord(set[i], i);
}
m->deleteOutlier();
m->initialMatrix();
m->createMatrix();
m->topuSort();
m->findInMaxtrix();
m->findDesignatedChain('a', 't', 2);
for (int i = 0; i < m->wordChain.wordNum; i++) {
Assert::AreEqual(m->wordChain.wordList[i], result[i]);
}
结果:正确,测试固定头尾的功能函数的正确性。
覆盖率截图

4.【9】异常处理
【9】计算模块部分异常处理说明。
在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。
异常:
- 指令错误
- 不是-r的指令也出现了环
- 文件不存在
- 得到的结果中只有一个单词,无法构成环
目标:
1. 输出Instruction error!
2. 输出There are one or more circles
3. 输出file is not existed!
4. 输出Only one word in the chain
单元测试样例:
- Wordlist.exe -h p -t z F:\VS2017\Worldlist\Debug\test.txt
- Wordlist.exe -h p -t z -w F:\VS2017\Worldlist\Debug\test.txt,在test.txt里头出现了带环的链
- Wordlist.exe -h e -t t -c F:\VS2017\Worldlist\Debug\tet.txt
- Wordlist.exe -h e -t t -c F:\VS2017\Worldlist\Debug\test.txt,此时test里头除了唯一一个以e开头以t结尾的单词之外没有另外的单词
5.GUI设计
【10】界面模块的详细设计过程。
在博客中详细介绍界面模块是如何设计的,并写一些必要的代码说明解释实现过程。
gui使用QT实现,用qt creater这个ide来设计前端的界面,非常方便,可以通过拖拉放置来构建组件,而代码逻辑则可以通过绑定槽来将clicked这种动作链接到这个组件对应的一个函数中去,在函数中写组件需要的功能即可。
界面:

【11】界面模块与计算模块的对接。
详细地描述UI模块的设计与两个模块的对接,并在博客中截图实现的功能。
这一部分没能成功对接上,主要是生成dll后,在qt creater中导入dll失败了很多次。最后反倒是尝试结对解耦合时,改使用visual studio 2017 加上qt的插件,让界面模块可以和计算模块链接起来。
【12】描述结对的过程,
提供非摆拍的两人在讨论的结对照片。
结对是在群里找队友,恰好两个人都没有队友,我觉得这个结对作业两个人一起做也不会太累,自己也菜,就一起组队了。合作还是挺愉快的。

6.松耦合
在博客中指明合作小组两位同学的学号,分析两组不同的模块合并之后出现的问题,为何会出现这样的问题,以及是如何根据反馈改进自己模块的。
合作小组:16131059
本组GUI+对方的核心模块Core
问题:核心Core的接口不同,合并需要修改一些逻辑,Core中自定义了参数类型和错误类型,接口为se_errcode Calculate(const string& input_text, string& output_text, LongestWordChainType& longest_type, const char& head, const char& tail, bool enable_circle); 按照这个接口写了一个版本,后来合作小组改成作业要求的标准接口了int gen_chain_word(char* words[], int len, char* result[], char head, char tail, bool enable_loop) 和int gen_chain_char(char* words[], int len, char* result[], char head, char tail, bool enable_loop)
处理:修改GUI调用接口的逻辑,匹配核心Core的接口
结果:能够正常运行

7.【13】
【13】看教科书和其它参考书,网站中关于结对编程的章节,
例如:http://www.cnblogs.com/xinz/archive/2011/08/07/2130332.html 说明结对编程的优点和缺点。结对的每一个人的优点和缺点在哪里 (要列出至少三个优点和一个缺点)。
优点:
- 相互review,相互学习
- 可以提升程序的质量
- 合理组队可以让团队发挥1+1>2的作用
缺点:
- 有的人就是喜欢一个人完整构建整个工程,工程代码的一致性、完整性也很好
- 两人意见分歧的时候,因为只有两个人,更加容易形成对立,分工不合理也可能造成矛盾
- 只有两个人,如果两个人都比较菜,技能点又都相似, 那么结对编程也很难发挥优势。
我的结对的同学,首先一点就是态度非常好,非常愿意付出时间和汗水去把结对这个事情做好,第二是很容易沟通,很和善的一个人。第三是解决问题的能力也比较强,能够独立去思考和解决编程中遇到的bug。如果非要说有缺点的话,那么可能代码的风格还需要注意一点,然后就是一些编程的细节需要注意一下,那对于我来说,就已经是很好的队友了。
我的话学东西比较快,也相对容易沟通,知道一点工程上需要注意的东西。但是我比较倾向于做相对有趣的东西,不是很喜欢私钻算法,偶尔也容易急躁。
【14】在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间。
答: 在文章首部
[BUAA软工]第一次结对作业的更多相关文章
- [BUAA软工]第一次博客作业---阅读《构建之法》
[BUAA软工]第一次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第1次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...
- 软工实践——结对作业2【wordCount进阶需求】
附录: 队友的博客链接 本次作业的博客链接 同名仓库项目地址 一.具体分工 我负责撰写爬虫爬取信息以及代码整合测试,队友子恒负责写词组词频统计功能的代码. 二.PSP表格 PSP2.1 Persona ...
- 【BUAA软工】结对编程作业
项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程结对编程项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法,锻炼开发能力 作业目标 完 ...
- BUAA软工第一次作业-热身
第一次作业-热身 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) (北京航空航天大学 - 计算机学院) 这个作业的要求在哪里 第一次作业-热身作业(阅读) 我在这个课程 ...
- 【BUAA 软工个人项目作业】玩转平面几何
BUAA 软件工程个人项目作业 项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程个人项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法 ...
- [2019BUAA软工]第一次团队作业
Team V1 团队启动 BUAA Team V1 于2019年3月正式成立,将开始为期四个月的合作. 队员介绍 Name Summary Sefie wxmwy V1-bug制造公司资深工程师精 ...
- python简单实现论文查重(软工第一次项目作业)
前言 软件工程 https://edu.cnblogs.com/campus/gdgy/informationsecurity1812 作业要求 https://edu.cnblogs.com/cam ...
- [BUAA软工]第二次博客作业---结对编程
[BUAA软工]结对作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 2019年软件工程基础-结对项目作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能 ...
- [BUAA软工]第零次博客作业---问题回答
[BUAA软工]第0次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第0次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...
随机推荐
- [bug] 验证selenium的显式和隐式等待而发现的一个低级错误
隐式等待:如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步.按照这说法举了个例子为啥不会按照预期执行了,难不成是这个定义有问题(~~~~~直接否定不是定义的问题,相信它 ...
- JS获取本周、本季度、本月、上月的开始日期、结束日期
/** * 获取本周.本季度.本月.上月的开始日期.结束日期 */ var now = new Date(); //当前日期 var nowDayOfWeek = ...
- JS操作DOM节点大全
1.Javascript删除节点 在Javascript中,只提供了一种删除节点的方法:removeChild(). removeChild() 方法用来删除父节点的一个子节点. 语法:parent. ...
- CF1045G:AI robots(CDQ分治)
Description 火星上有$n$个机器人排成一行,第$i$个机器人的位置为$x_i$,视野为$r_i$,智商为$q_i$.我们认为第$i$个机器人可以看到的位置是$[x_i−r_i,x_i+ ...
- 【洛谷】【搜索+剪枝】P1731 [NOI1999]生日蛋糕
[题目背景:] 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. [题目描述:] 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri ...
- BugFree设置邮箱通知(这里以163邮箱为例)
公司用bugfree在进行新建Bug指派抄送给同事的时候,总是有人不及时登录BugFree去查看指派给自己的,所以要加一个邮箱通知,这样可以及时通知到被指派的同事. 百度上很多用的是QQ邮箱来实现的, ...
- docker swarm英文文档学习-11-上锁你的集群来保护你的加密密钥
Lock your swarm to protect its encryption key上锁你的集群来保护你的加密密钥 在Docker 1.13及更高版本中,默认情况下,群管理器使用的Raft日志在 ...
- rac添加新节点的步骤与方法
[转载] https://www.cnblogs.com/hankyoon/p/5174465.html OS: [root@rac ~]# more /etc/oracle-releaseOracl ...
- Linux安装consul
1.下载并解压consul # cd /opt/ # mkdir consul # chmod 777 consul #cd consul #wget https://releases.hashico ...
- wordpress之插件安装和主题安装(包含常见问题)
问题描述:安装WordPress主题及插件需要输入FTP问题,要执行请求的操作,WordPress需要访问您网页服务器的权限.请输入您的FTP登陆凭据以继续 执行如下两条命令即可安装成功: sudo ...