[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】计算模块部分异常处理说明。

在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。

异常:

  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结尾的单词之外没有另外的单词

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软工]第一次结对作业的更多相关文章

  1. [BUAA软工]第一次博客作业---阅读《构建之法》

    [BUAA软工]第一次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第1次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...

  2. 软工实践——结对作业2【wordCount进阶需求】

    附录: 队友的博客链接 本次作业的博客链接 同名仓库项目地址 一.具体分工 我负责撰写爬虫爬取信息以及代码整合测试,队友子恒负责写词组词频统计功能的代码. 二.PSP表格 PSP2.1 Persona ...

  3. 【BUAA软工】结对编程作业

    项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程结对编程项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法,锻炼开发能力 作业目标 完 ...

  4. BUAA软工第一次作业-热身

    第一次作业-热身 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) (北京航空航天大学 - 计算机学院) 这个作业的要求在哪里 第一次作业-热身作业(阅读) 我在这个课程 ...

  5. 【BUAA 软工个人项目作业】玩转平面几何

    BUAA 软件工程个人项目作业 项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程个人项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法 ...

  6. [2019BUAA软工]第一次团队作业

    Team V1 团队启动   BUAA Team V1 于2019年3月正式成立,将开始为期四个月的合作. 队员介绍 Name Summary Sefie wxmwy V1-bug制造公司资深工程师精 ...

  7. python简单实现论文查重(软工第一次项目作业)

    前言 软件工程 https://edu.cnblogs.com/campus/gdgy/informationsecurity1812 作业要求 https://edu.cnblogs.com/cam ...

  8. [BUAA软工]第二次博客作业---结对编程

    [BUAA软工]结对作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 2019年软件工程基础-结对项目作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能 ...

  9. [BUAA软工]第零次博客作业---问题回答

    [BUAA软工]第0次博客作业 项目 内容 这个作业属于哪个课程 北航软工 这个作业的要求在哪里 第0次个人作业 我在这个课程的目标是 学习如何以团队的形式开发软件,提升个人软件开发能力 这个作业在哪 ...

随机推荐

  1. 【PAT】A1001A+B Format

    最新想法: 最多是七位数,而且只有一组输入,完全不用考虑算法复杂度. 直接判断是否为负,并输出符号 巧妙的地方:while循环的下一次再添加逗号.(防止出现,999,991的情况) 婼姐的方法真的很巧 ...

  2. beta版本汇总

    deta版本五天汇总 day1 day2 day3 day4 day5 GitHub地址 前端代码github地址 后端代码github地址 这里说明一下我们队伍的安排风格: 第一天:明确安排前后端的 ...

  3. SAP中的ALE, IDOC

    ALE技术:应用链接支持(Application Link Enabling 简称ALE),是一项用于创建和运行分布式应用的技术.ALE是SAP的专有技术. ALE对象——ALE包含了可控的数据消息交 ...

  4. python2.7.15 + PyQt4部署

    安装python模块首先想到的就是 https://pypi.org/,但在上面下载的PyQt4的包却找不到安装的方法,于是找找试其它方法,下面介绍通过pip安装whl的安装方式 1.先打开 http ...

  5. 【C++学习笔记】变量初始化规则

    全局变量和静态变量会自动初始化为0,堆和栈中的局部变量不会初始化而拥有不可预测的值. C++保证了所有对象与对象成员都会初始化,但其中基本数据类型的初始化还得依赖于构造函数(或初始化列表). 成员变量 ...

  6. Vue仿抽屉

    创建VUE项目的步骤: npm install vue-cli -g vue init webpack myproject cd myproject npm run dev 组件:它是可扩展的html ...

  7. 安卓手机ADB驱动干什么的?

    Adb驱动是什么意思? /div> Adb是英文Android Debug Bridge的英文缩写,是debug工具,如果不是写IT的可能也很难理解debug的意思.说的直白一点就是Adb就是手 ...

  8. eclipse中使用svn提交,更新代码。

    在新公司工作,版本管理工具变成了svn,之前一直用git作为版本管理,用的编辑IDE是IntelliJIDEA,在这个编辑器下工作,还是很方便的,但是现在使用eclipse和svn.有点不习惯,但还是 ...

  9. java計算年齡的工具類

    整理一篇Java計算年齡的工具類,方便實用 public static int getAgeByBirth(String birthday) throws ParseException { // 格式 ...

  10. 一篇自己都看不懂的CDQ分治&整体二分学习笔记

    作为一个永不咕咕咕的博主,我来更笔记辣qaq CDQ分治 CDQ分治的思想还是比较简单的.它的基本流程是: \(1.\)将所有修改操作和查询操作按照时间顺序并在一起,形成一段序列.显然,会影响查询操作 ...