ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021年软工 结对项目第三阶段总结

2021-04-09 04:33:52  阅读:205  来源: 互联网

标签:结对 代码 编程 单元测试 指令 2021 软工 指导书


一、结对项目实践反思

1.1 问题综述

​ 仅就在测试中出现的Bug而言,大多数Bug都是由于测试不充分导致的(部分路径未覆盖或压力测试的缺失),而这种测试的不充分又是由于时间的紧迫性导致的。我们在分析与编码过程中花费了过多的时间,导致留给测试的时间严重不足,且心理上比较疲乏,最终往往是针对覆盖率写单元测试就万事大吉。而这种在编码过程中花费过量时间的原因,既有对指导书的分析上的,也有架构设计上的,也有具体编码过程中的。

1.2 需求分析实践体会

​ 在这一部分提出一点G同学的个人看法,欢迎助教不吝赐教。

​ 在我看来,软件工程的需求分析是一个开发人员经过调研与分析,准确理解用户和项目的功能、性能、可靠性等具体要求,并将用户的非形式的需求表述转化为完整的需求定义的过程,它强调的是将不明确的需求明确化,甚至帮助用户发现自己都没有意识到的需求的过程。而观察课程组所给出的指导书,可能是出于评测方便的考虑,已经明确给出了各条指令的具体实现方式、异常顺序等一系列内容,观感上比较类似一个规格说明书,对这样的规格说明书不存在所谓需求分析的过程。因此我提出这样一个观点,本次项目的需求分析是由课程组完成的,而结对团队仅是拿到需求分析的结果并进行实现而已。是课程组对于“基于内存的文件系统”这样一个比较宽泛的需求进行了分析,设计了数条指令,规范了指令行为,才形成了指导书,并交予结对团队进行实现。

​ 很多同学都认为第二阶段的指导书让自己体验极差(例如这里),在我看来,这正体现了需求分析对于软件工程全过程的重要性,正是由于指导书(这里仍将指导书理解为需求分析产生的结果)在细节上存在比较多的问题(具体问题将在3.4节中详述),才导致了负责实现的结对团队难以在较短时间内完成一个比较好的版本,且开发体验不佳。当然这并不是在甩锅给课程组,在改革的第一年就形成这样体量的指导书已经是比较大的工作量了。

1.3 架构设计实践体会

​ 在本次结对作业的过程中,我们在架构设计与迭代上出现了比较大的问题。

​ 在第一次指导书发布后,我们首先进行了分别阅读,并由H同学初步设计了整体架构,在此设计中,我们用一个全局的HashMap保存文件系统中的所有文件,实现了一个与文件系统无关的将任意绝对或相对路径转化为一个完美的绝对路径getAbsolutePath方法,文件系统的每个方法都先调用此方法以转化输入的路径后直接从全局Map中取得实体,虽然这样做能满足第一次作业的全部要求,甚至还可以简化文件树结构(不需要存父节点),简化文件系统具体方法实现方式,但实际上已经埋下了巨大的隐患。

​ 击溃这一架构的重要指令便是mkdir -p,由于其路径中出现的部分可能在文件系统中不存在,加之一些其他类似\结尾的问题,导致了我们前文中设计的工具类方法的有关特判大大超出了预期,复杂度过高,代码难以阅读和维护,也难以针对指导书随时的修改而快速修改代码实现,因此我们在讨论后决定更改为实现一棵完整的文件树,将路径视作分步在树上移动的方式。

​ 在更换架构,重写工具类的过程中,我们一心想着赶进度,觉得在第一阶段中构造的myFileSystem各方法的测试已经较完备地覆盖了工具类,因而没有针对新增的TreePath类进行单元测试,两人都默认了这种方式的后果就是此新增类直接忽视了路径的4096字符限制,在第三阶段的测试中造成了错误。

​ 架构的设计是软件工程开发阶段的基石,具有举足轻重的地位,结合自己在此次作业中出现的问题,我们提出以下两点:

  • 在确定架构之前需要进行完整、详细的设计与复审,对于每一个细节都应该进行调研或测试。在结对设计架构的过程中,常常出现双方各执一词的情况,此时不适宜采用一人拍板定论的方式,而应该各自排出论据,详细讨论优劣,以期说服另一方,最终达成一致。
  • 若出于各种原因对架构做出了改变,则对新增的工具类等需要做详细无遗漏的单元测试,保证通过回归测试。架构的变化往往会删除和新增一些重要的工具类,这些工具方法复用度极高,需要优先保证正确率。在结对编程过程中,对这些类与方法要特别注意,必须进行同步复审。

1.4 质量管理实践体会

​ 进度管理上,我们采用了一种类似燃尽图的形式。以第二阶段为例,我们将主要编码工作分为修改数据结构和工具类,增加用户系统类并实现与文件系统交互,实现用户有关指令,实现用户组有关指令,实现硬、软连接指令,实现复制和移动指令等六个阶段,虽然没有按时间顺序具体将燃尽图画出来(考虑到从指导书发布到截止提交只有数天的时间,在真正的软件开发过程中可能只够一次“冲刺”),但我们对已经完成和还未完成的工作量都有了一个大概的认识,有助于估计仍需耗费的时间,便于及时调整进度。但是,在此过程中的一个问题是,我们对每一阶段的任务量估计不够准确,因而没有做到尽量等量划分任务单元(如第五和第六阶段的任务量其实比前四个加起来都多),最终造成了开发时间上的延误,对测试阶段造成了一定的影响。在之后的团队项目中,将继续尝试使用燃尽图方式进行进度管理。

​ 质量管理上,我们在代码实现中使用了很多TODO块。在等待Issue区的助教盖棺定论过程中,亦或是对细节有不清楚的地方而暂时不便打扰另一方时(如在实现一个逻辑比较复杂的方法,需要沉思),亦或是可能需要抽象出重复代码或做性能上的优化时,我们都会先在对应地点加上一个TODO,并详细注明TODO的理由和内容,在一次小的“冲刺”结束后,会针对现有代码中的所有TODO进行讨论,最终达成一致。

图1 分别由H同学和G同学写的TODO示例

​ 此外,我们还尝试过在具体实现代码之前先针对复杂方法写类似JavaDoc的注释的方式,但我们最终发现这种方式效率比较低,且可以被单元测试样例所取代,没有达到预期的效果,遂放弃。

图2 G同学写的某方法的注释

​ 沟通管理上,由于二人可以随时线下交流,因此省去了很多的无效交流时间。对于一些对指导书理解不一致的地方,或者通过Issue区的助教回复,或者通过Ubuntu的现场实验,最终都能达到统一的理解,因而没有在这方面上出现Bug。

1.5 相关建议

​ 《构建之法》中指出:“在结对编程模式下,一对程序员肩并肩、平等地、互补地进行开发工作。他们并排坐在一台电脑前,面对同一个显示器,使用同一个键盘、同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起做单元测试,一起做集成测试,一起写文档,等等”。然而,在结对编程的实践过程中,可以不拘泥于以上的形式和内容,保证适当的独立性也是可以接受的。结对编程的目的是提高工作效率和降低错误率,不需要为了结对编程而结对编程。具体而言,可以尝试使用以下方式进行结对项目的实施与管理:

  • 在合适的时候“分而治之”。虽然结对编程的随时复审特性能极大降低错误率,但它不是万能的,在部分编码过程中实行先分开实现再讨论的传统方式不仅能提高工作效率,而且对错误率不会产生太大的影响。本次项目的第一阶段我们全程结对完成,而在第二阶段,我们在实现具体指令过程中尝试了“一人写测试样例,另一人实现对应方法,下一个方法再进行转换”的方式,这样的方式很契合与文件系统类似的指令之间没有耦合的需求,虽然没有结对,但同一个方法经过了两个人的代码实现和单元测试样例构造过程,只要该方法通过了单元测试,我们就可以认为二人理解已经一致,无形之中完成了复审。
  • 保持良好的沟通。与一些其他组进行交流后我们发现,在结对项目的过程中,一个很大的阻碍便是失联的队友,在队友失联情况下个人完成的代码质量得不到保障,更严重的是会对之后的进度造成影响,如出于对代码熟悉程度的原因再也不放心让队友接手写这一部分的其他代码。在这一点上我们这次做的比较好,大部分时候都处于线下结对状态,在线上完成的针对Issue的小补丁也都及时进行了通知,使得二人始终对所有代码都有较高的熟悉度。

二、CI体验感想

​ 整体而言CI的使用体验较好。虽然在第一次作业提交前花费了一些时间用来配置CI,但在之后的每次提交基本上都不需要对其做出太大的改动。另外,需要感谢my同学提出的#Issue12中对CI单元测试和导出覆盖率的方法分享。

​ 本次项目中的CI仅涉及了build,test,commit等流程,而没有涉及到部署或发布等流程,因此其主要便利之处在于能自动进行单元测试并生成覆盖率报告。能将一部分工作交由CI自动完成,使得我们有更多的时间对代码本身进行思考。

三、结对编程感想

3.1 结对方法评价

​ 本次结对项目中我们主要采用线下实时使用Code With Me插件协作的方式,并且我们认为这种方式很适合结对编程的需求。线上改动代码的情况少之又少,仅在写单元测试的时候出现过一段时间的分治。

​ 与第一阶段总结中提到的一样,经过一整个结对项目的实践,我们认为,结对编程最主要的优势就是其随时复审的特性会使得低级错误的出现率大大降低。在较长时间的编码后,编码者往往会犯一些低级错误,如将 absolutePath 误写为 path ,将 && 误写为 || 等,这样的错误往往在测试前难以发现,且经过漫长的 debug 后发现低级错误也会极大增加挫败感。而两人共同面对同一份代码时同时犯低级错误的概率将远低于单人,节省了大量的测试时间。结对编程的主要缺点就是当两人对某一具体细节各执一词时可能会消耗大量时间用于讨论和争辩,从而造成开发效率上的问题,这一点在面对第二阶段的指导书时尤为严重,我们经常针对到底改不改父目录或子目录的modify_time等问题进行争论,难以盖棺定论,为此消耗了大量时间,延误开发进度。

​ 结对“妙招”已在1.5节中给出,在此不再赘述。

3.2 结对队友评价

Gottfried → Hastune

​ H同学思维敏锐,执行力强,在简要阅读指导书后就可以快速形成基础架构。但是在具体编码过程中犯低级错误的频数有些过高,如同一段代码中上面使用的还是absolutePath,下面就变成了path。如果可以做到形成一套自己的变量命名逻辑,在动手写代码之前想清楚代码目的,写完后先进行一遍自我复审,将极大地提高代码质量,从而缩减debug时间。

​ 丁酱,我的超人。

Hastune → Gottfried

​ G同学无论是在代码的思考构建过程中,还是在代码的编写过程中,都给人一种很细腻的感觉。讨论架构的时候,他会就某一点询问其它方式的可行性,只有在权衡所有方法的优劣之后,他才会做出相应的决策。例如有一次在讨论路径的存储结构应当是字符串还是数组时,我一开始提出应当用字符串进行存储,以便进行更加灵活的处理。但是他首先询问了数组存储的可能性,虽然我一开始觉得还是字符串存储较好,但是在听他说明了数组处理的效率高的特点以及数组结构与路径结构的相匹配性后,我最终决定采用他所说的方法。在我编写代码的过程中,他也会指除我某些逻辑方面的漏洞以及提出更加合理的解决方案。

​ 不过与G同学一起编写代码的过程中,我也发现了他对所使用的编程语言的语法与结构熟悉程度不太高,以至于无法写出一些比较常规的操作。还有就是他在结对编程的过程中表现得不太积极,大部分都是我主动去邀请他进行结对编程,而且他有时还会在结对过程中去偷偷写案例分析作业,这让我很恼火。

标签:结对,代码,编程,单元测试,指令,2021,软工,指导书
来源: https://www.cnblogs.com/gottfriede/p/14635567.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有