BUAA_2021_SE_Pair_Work_#3_Review
结对项目第三阶段博客
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2021春季计算机学院软件工程(罗杰 任健) |
这个作业的要求在哪里 | 结对项目-第三阶段 |
我在这个课程的目标是 | 通过课程学习,完成第一个可以称之为“软件”的项目,同时了解软件工程中用到的方法,确定自己的职业目标 |
这个作业在哪个具体方面帮助我实现目标 | 加深对结对编程的实践了解,修复之前的bug |
GitLab 项目地址 | https://gitlab.buaaoo.top/2021_alige_homeworks/pair_works/2021_rui_ma-junjie_dong_pair_work |
学号后四位 | 7155 5044 |
1. 实践反思
本次作业主要是对之前两次作业的修改、补充与反思,接下来我将从以下四个方面来进行总结
1.1 分析问题
第一次作业较为简单,所以在代码结构设计方面出现了一些问题,把完成任务作为了首要目标,完全没考虑后续可能引入的用户系统,和用户系统与文件系统交互等功能,所以第一次作业完成较快,但给后续工作埋了不少定时炸弹。
第二次作业增加的需求较多,所以导致了对第一次作业的不完全重构,这也导致文件系统类结构崩坏,一个类文件高达800多行,幸好本次作业到第二次就结束了,如果后续还需要再这个架构继续开发,可能造成的麻烦将会是灾难性的。
此外,第二次作业由于代码结构过于复杂,导致部分代码难以进行单元测试,最终覆盖率难以到达100%,在测试中也发现一些死代码,并进行了删除。单元测试的不充分直接导致了强测出现问题。
1.2 实践体会
前两次作业主要出现了以下bug:
- 第一次收对指导书的理解不够充分,把"@n"分开出现的情况理解成了两个字符'@'和'n',导致出现了问题,此外,第一次作业还隐藏了一个比较严重的bug,没有注意到指导书中对路径长度有最长的要求,虽然通过了第一次的测试,但是在第二次作业中出现了问题。
- 第二次作业还有一个问题就是对于链接的理解不到位,由于第二次作业指导书过于繁琐,不少同学在语义理解上出现了偏差,我们也不例外,对于硬链接的指向、硬链接的info、带有链接的change directory均出现了一些小问题。
- 最终均成功修复,并通过回归测试
1.3 总结反思
-
关于架构设计,第一次作业由于逻辑简单,并未仔细考虑架构设计与实现,仅仅关注程序功能,并未区分包等,仅仅根据定义创建了几个继承类。到了第二次,由于需求突然增加不少,原有架构难以维持清晰的结构,就不得不重构,由于时间的原因,在第二次中重构的又不是那么的彻底,所以导致了与第一次需求描述不一致或增加需求的指令,出现了不同程度的问题,有的问题在提交时解决了,有的问题在强测后出结果解决的,有的问题可能到现在也没解决。
-
关于质量控制、进度控制,由于采用结对编程,且有清晰的deadline,对于进度控制,不需要进行什么额外的辅助工作,只需要抽出固定的空闲时间进行开发,保证两人大部分工作时间时重合的即可。对于质量控制,在开发时,采用一人写一人看,能在开发时避免单独开发时遇到的80%左右的bug,对于两人理解同时出现问题或没有注意到的问题,两人独立的阅读指导书,分别编写测试样例进行黑盒测试。最后编写单元测试进行测试,达到90%以上覆盖率才可进行下一步的编写,在编写完下一部分内容后,还要对之前进行的测试进行回归测试,防止新增的代码对之前程序有影响。
1.4 提出建议
-
结对编程在一定程度上,确实能够帮助我们提高开发效率,降低开发时遇到不可控问题的可能性。同时在遇到问题时,能够降低解决问题所需时间。两个人可能在不同方面可能有着不同的见解,经过结对编程,通常能得到一个对两个人来说的最优解,在具体开发来说还是十分有帮助的。
-
由于本次作业时预先给定需求再进行开发,那么这样来说,单元测试就显得尤为重要,我们甚至可以不先进行开发,就进行单元测试的编写。但对于实际工程问题,尤其是没有那么多繁杂的、形式化的定义语言来描述的需求时,在何时进行单元测试可能就是我们要讨论的一个点了。
-
不同人的生活习惯可能不一样,这个在结对编程时一定要考虑到,不然可能造成,一个人白天啥都不会,另一个人晚上啥都不会这种局面。
2. CI体验感想
- 本次实验,我们详细体验了Gitlab-CI的使用,经过我的体验,Gitlab-CI是一个对于团队开发控制代码质量的利器,针对不同的成员可能有不同分支进行开发,如果我们预先在CI上部署了编译,单元测试,demo运行等测试,对于每一次push都会进行如上测试,只有测试通过的代码,才能合并进入主分支。
- 对于本次作业,我们由于两人开发,两人使用同一个dev分支进行开发,只有本地通过测试,且pipeline通过,才会合并进入master分支进行提交,对于master分支,我们一般不进行任何改动,只有合并操作,所以操作都在dev分支进行。
- 此外,CI中提供的持久化工具还能帮助我们导出本次运行的测试报告,生成的可执行文件,和本次pipeline的调试信息,我们也可以把CI提供的持久化工具当作我们的发布工具,例如在不同pipeline阶段搭配不同的编译器,生成对不同平台的可执行文件,然后之间发布到release页面,这个功能十分强大。
- 同时配合readme.md我们可以生成一些动态的信息,放入项目的主页进行展示,包括但不限于版本号,构建是否成功,单元测试覆盖率等等。
3. 结对编程感想
说实话,在本次作业之前,我没有接触过结对编程,更多的时在遇到问题的适合请教别人或者上网查看,但这就存在一个问题,给你解决问题的人可能无法复现或者无法理解你的问题描述,从而无法快速定位你所遇到的问题。导致问题解决效率低,网上查询同理。但是当你有一个伙伴与你一起编程,他十分熟悉这个整体体系,一但出现了问题,基本上就可以快速定位问题的位置,从而迅速解决。这就相当于两个人都同时有了一个顾问,同时,如果一个人盯着代码累了,他也可以选择进行测试代码的编写或是阅读需求并给另一个人及时补充。但这都限于两人至少有一个人基础尚可的基础之上,如果两个人对于某一方面都有共同的短板,交给结对编程可能反而不如个人探索的效率高。
总而言之,结对编程时一个输出的过程,目的是两个人合力输出更多的东西,对于编程来说俩人分别编程可能是1+1=1.2,结对编程可能能达到1+1=1.5。但对于学习一个基础知识,如果两人都不懂的情况下,可能1+1<1因为这样可能会造成两个人都一知半解。
关于我的队友,我俩的利益其实很一致,就是按照要求做出这个程序,就足够了,所以我们在交流的时候,更多的是使用的说服和吸引的模式,目的就是找到一个最优解去完成问题,对于他,应该在执行力上比我要好,Java的一些时间间隔理解的也比我深刻。我可能更擅长利用一些工具,配置一些环境,对于gitlab-ci,maven等一些工具就是由我进行配置。所以我们看到了彼此的不足之处,应该向对方的优点进行学习。
关于工具,由于我本人不在北京,为了保证工作的可进展性,我们采用腾讯会议和Jetbrains的CodeWithMe插件,在之前的博客以及提过,此处不再赘述。
关于感悟,前面写了许多,总结下来就是,工具很好用,得学,结对编程或许是个好办法,得辩证的看,时间太少,那咋办么,每门课都认为自己是一门很重要的课,同时也还在不断压缩自己的课时,在教务系统上显示更少的学分,那么更多的工作就得由我们自己在课下进行,同学们也有许多自己需要完成的事务[比如找工作,学语言,考研等]。如何在有限的时间保证一个健康的身体,同时学到更多的知识,这或许得等待医学科学迈上一个新的台阶。
关于结对作业,由于本作业今年是第一次试行,在指导书上出现了一些不影响整体设计的小纰漏是可以容忍的,但是试想一下,如果把此次作业放在面向对象课程的第三单元或是第四单元,那又有什么区别呢,此次作业依然仅仅是为了完成一个"任务"而完成,这个任务是否有什么价值或是作用,涉及的知识点与面向对象是否由重叠,这都可以考虑。虽然评测机很重要,但是对于软件工程课程来说,我们是否应该学习更多工具或者框架,是否应该对我们语言不限,但是要自己完成构建脚本或框架,最终发布成一个可运行的软件包,然后运行呢?[例如课题组提供pull学生上传的docker或是pull学生的仓库地址]不局限于仅仅使用指定镜像,指定语言,指定仓库。给学生在实现上多一些自由考量[参考21系编译实验],最终达到目标即可,这不是更侧重软件工程课程所涉及的内容么?