本次做业所属课程: 2019BUAA软件工程
本次做业要求: 结对项目
我在本课程的目标: 熟悉结对合做,为团队合做打下基础
本次做业的帮助:理解一个c++ 项目的开发历程html
https://github.com/butub1/WordList
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 50 | 80 |
· Estimate | · 估计这个任务须要多少时间 | 14天 | 14天 |
Development | 开发 | 6天 | 9天 |
· Analysis | · 需求分析 (包括学习新技术) | 1天 | 0.7天 |
· Design Spec | · 生成设计文档 | 180 | 150 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 50 |
· Design | · 具体设计 | 1天 | 1天 |
· Coding | · 具体编码 | 5天 | 5天 |
· Code Review | · 代码复审 | 1天 | 1.5天 |
· Test | · 测试(自我测试,修改代码,提交修改) | 1天 | 1天 |
Reporting | 报告 | 1天 | 1天 |
· Test Report | · 测试报告 | 5小时 | 4小时 |
· Size Measurement | · 计算工做量 | 1小时 | 1小时 |
· Postmortem & Process Improvement Plan | · 过后总结, 并提出过程改进计划 | 0.5天 | 0.5天 |
合计 | 14天 | 13天 |
看教科书和其它资料中关于Information Hiding, Interface Design, Loose Coupling的章节,说明大家在结对编程中是如何利用这些方法对接口进行设计的前端
(1)Information Hiding: 采用了Interface这个类来对数据进行封装。 (2)Interface Design 接口的要求与做业一只
(3)Loose Couplingc++
松耦合,与别的小组互换core、gui和test, 对方封装得足够好,调用起来就很是方便,咱们本身的模块封装性很差,技术上还须要提高。git
设计包括代码如何组织,好比会有几个类,几个函数,他们之间关系如何,关键函数是否须要画出流程图?说明你的算法的关键(没必要列出源代码),以及独到之处
有三个类,word类负责保存单词的基本属性,wordlist类则负责保存单词链,maxtrix的主要做用是用来计算相应的最长单词链。计算最长单词链的算法是用到了拓扑排序,首先将全部单词中的没有办法和其它单词练成链的单词去除。而后构建邻接矩阵。以后经过拓扑排序以及动态规划找出最长的单词链和最多字母的单词链。github
记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展现一张性能分析图(由VS 2015/2017的性能分析工具自动生成),并展现你程序中消耗最大的函数
一开始我采用的算法是,再把全部的单词进行拓扑排序以后,找出全部的链,而后对全部的链进行统计,找出其中最多字母的链。可是当单词数多起来好比达到了9000个单词以后速度特别慢。很长时间都跑不出来结果。
后来我修改了算法,再计算字母最多链的时候,引入了动态规划算法,算出了起始点到终点的最长距离,而且记录了其前驱节点。改进完毕以后速度快了不少,能够正常跑完9000个无环的测试样例。
算法
http://en.wikipedia.org/wiki/Design_by_contract> http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
描述这些作法的优缺点, 说明你是如何把它们融入结对做业中的
契约式设计的优势在于可以明确每一个类的功能,以及类之间的联系。每一个类负责固定的几个功能,而后将其结果供以后的类使用。这样方便了代码的测试,重构,由于每段代码的“合同”都已经完整记录。
在个人设计当中,好比个人一个函数为topuSort,它可以将单词链的图全部的节点进行拓扑排序,而后将这个排序以后的列表返回出来。这个函数指望获得一个图,可以保证将其进行拓扑排序,而后将其结果维持而且返回出来。编程
展现出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试获得的测试覆盖率截图,发表在博客中。要求整体覆盖率到90%以上,不然单元测试部分视做无效。windows
用例:数组
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类的正常功能,这是整个程序中最小最基本的数据抽象封装。ide
用例:
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]); }
结果:正确,测试固定头尾的功能函数的正确性。
覆盖率截图
覆盖率截图
在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。
异常:
1,指令错误
2,不是-r的指令也出现了环
3,文件不存在
4,获得的结果中只有一个单词,没法构成环
目标:
1,输出Instruction error!
2,输出There are one or more circles
3,输出file is not existed!
4,输出Only one word in the chain
单元测试样例:
1,Wordlist.exe -h p -t z F:\VS2017\Worldlist\Debug\test.txt
2,Wordlist.exe -h p -t z -w F:\VS2017\Worldlist\Debug\test.txt,在test.txt里头出现了带环的链
3,Wordlist.exe -h e -t t -c F:\VS2017\Worldlist\Debug\tet.txt
4,Wordlist.exe -h e -t t -c F:\VS2017\Worldlist\Debug\test.txt
此时test里头除了惟一一个以e开头以t结尾的单词以外没有另外的单词
在博客中详细介绍界面模块是如何设计的,并写一些必要的代码说明解释实现过程。
gui使用QT实现,用qt creater这个ide来设计前端的界面,很是方便,能够经过拖拉放置来构建组件,而代码逻辑则能够经过绑定槽来将clicked这种动做连接到这个组件对应的一个函数中去,在函数中写组件须要的功能便可。
界面:
详细地描述UI模块的设计与两个模块的对接,并在博客中截图实现的功能。
这一部分没能成功对接上,主要是生成dll后,在qt creater中导入dll失败了不少次。最后反却是尝试结对解耦合时,改使用visual studio 2017 加上qt的插件,让界面模块能够和计算模块连接起来。
提供非摆拍的两人在讨论的结对照片。
我以为和个人伙伴一块儿合做还算很愉快,你们都愿意为了完成项目而付出热情和汗水,很棒的一次体验。
在博客中指明合做小组两位同窗的学号,分析两组不一样的模块合并以后出现的问题,为什么会出现这样的问题,以及是如何根据反馈改进本身模块的。
合做小组:牛雅哲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的接口
结果:可以正常运行
例如:
http://www.cnblogs.com/xinz/archive/2011/08/07/2130332.html
说明结对编程的优势和缺点。
结对的每个人的优势和缺点在哪里 (要列出至少三个优势和一个缺点)。
结对编程的好处在于,两我的在一块儿开发,测试,两人合做写出的代码质量取决于水平高的那我的。结对时处于不断复审的过程,所以可以节省不少修改测试的时间。缺点在于两我的的沟通和磨合须要较长的时间,若是不可以好好的沟通和反馈,结对编程反而会影响效率。在结对中,个人优势在于善于沟通,思考全面,编码风格较好,缺点在于算法能力较差,须要花费大量的时间在研究实现的算法上。个人同伴的优势在于编码能力强,测试时思考的很全面,善于学习新的东西,缺点在于沟通和反馈,有时候我不太能理解它所说的。总的来讲咱们都很是愿意为共同的项目付出热情和汗水,这是很是可贵的。
实际时间见【2】。