结对编程总结

结对编程第三周总结

项目 内容
课程 2021春季计算机学院软件工程(罗杰 任健)
要求 结对作业-总结
项目地址 结对编程gitlab仓库

一、结对项目实践反思

在两周的结对编程过程中,我印象最深的有两个阶段:分析设计阶段和测试阶段。所谓说明书有多长,设计阶段就有多“痛苦”。你的设计有多复杂,测试阶段就有多“痛苦”。当然,这都是夸张的吐槽,但毫不夸张的是,我们组在这两个阶段上花的时间相比coding要多得多。

1. 实践中问题分析

  • 测试相关问题

实不相瞒,我在这一次结对编程前,对于测试这个阶段的工作,重视程度并不高。其实我早应该警醒,因为之前的好多作业(比如OO)都是因为测试不到位出错。或许是过于相信自己的逻辑,或许是偷懒,我在测试方面的工作做的并不好。

但是我的队友很好的弥补了这一点。这并不是因为每次作业覆盖率都要超过90的push,我的队友对于测试重视程度很高,即便是最简单的函数单元测试,他也会测上很多看起来很冗余的情况。(说实话,在这方面我还是抱了他的大腿)

测试程序应该覆盖每一个可达的分支

这是书上的一句话。我们在第一次作业很好的践行了这一点,几乎所有的语句全部覆盖了。唯一一条没有被覆盖的语句,是为了保险,加入的一个抛异常的语句。(其实这个语句根本无法到达,我们并没有删掉)但是我们确实做到了每一个可达的分支,可达的语句都做了测试。

第二次的作业,由于之前分析设计和coding的时间较长,我们的测试覆盖率刚好超过90。但是最终两次作业的强测都全部通过,第三次作业测试也只错了一个点。(错的这个点确实是分支没有覆盖到的地方)

这两周的结对编程我在真正体会到,测试对于一个程序的重要性,肉眼可见的重要性。当然,在编写测试的时候,我们也发现了大大小小的Bug,通过不断的测试,修正过程,我们程序的正确性大大的提高了。

还有在于写测试的,可能是我们的方法不太正确,出现的部分Bug是因为测试程序逻辑写错(其实是测试程序的bug而非程序)。

  • 不太好的编程习惯

在这个阶段,我们发现的bug绝大多数是在编写程序时,程序逻辑与我们所设想的逻辑相悖造成的。比如,我们在写解析文件目录的代码时,喜欢使用复制粘贴,而恰好命令间对于文件目录的作用效果有细微的不同,复制粘贴的代码就出现了错误。导致我们花费了大量的不必要的时间去查找问题,疯狂debug。

  • 统一意见太快,缺少细节性的思考

现在复盘前两次的作业,其实也有很多问题是我们的共性问题。因为我们几乎大部分时间从需求分析开始在进行面对面结对,所以一开始就比较统一,但是正是由于我们的意见太早过于统一,导致我们进入了相同的思维误区,导致了一些Bug的出现,而且自己还很难发现。

2.需求分析实践体会

无止尽的issue,哇,说到这个,真的是非常的佩服我们的助教团队。我能感觉得到,指导书都是经过反复斟酌,各种情况也写的很全。可是“人非圣贤孰能无过”,有的地方总会有差错和不解,这是不可避免的。很少人能够写出完全工整的指导书或需求书。

软件工程,唯一不变的是变化。所以干脆别幻想客户的需求会在第一时刻很明确,然后保持不会变。

我们也深刻的体会到了这一点。影响设计细节的往往是细节,有时细节甚至会影响到设计整体思路。所以在设计分析阶段,我们就曾因为很多不确定的小细节而被迫中断设计的思考。这让我们coding的节奏中断了许多次。

上课的时候,老师给我们举了一个很形象的例子:

一位顾客拿着一张大部分完整的发型照片找到理发师,要求理发师就按着这个照片剪。一段时间后,理发师100%完成了任务。事无巨细地将每一处细节完美还原,当然也把没有被照片截进去的部分一刀切了。

造成这个问题的根本原因,就是双方缺少充足的沟通。

在本次开发实践中,我和队友不断地在针对每一处细节进行讨论。队友间的讨论能有效互换看法,从而得到更优解。而更为重要的是,设计人员与开发人员之间的讨论。

前几天我在田同学的博客有如下评论:

记得之前看到一个笑话:

这个世界上难道就没有一种软件和脑机接口,能够把自己所想的自动转化成代码吗?有啊,乙方。

这个笑话很真实,正因真实,我们可以在当中找到一些现实的影子。

真正的工程中或许留给开发人员决定的部分比较多。

或者说是乙方需要跟甲方不断交流,不断探讨需求书中没有提及的内容,以达到互相合作解决问题的目的。那么从这个角度来讲,一个明确的方向和充足的交流是必须的,细节是次要的。

第二周结对编程就非常好的体现了这个特点,不断地出现,问题不断地被解决。

可是换一个角度来想,在现实中真的有这么多正确答案吗?如果没有正确答案,那issue会不会无止尽地多下去呢?我认为现实工程中,正确答案会很少,更多的应该是Open Questions,比如这个按钮放在上面好还是下面好等等。

计网课上,罗老师说过,现在计算机网络所使用的技术更新很快,因为人们还没有找到最好的。正是因为没有最好的,可是又有那么多人要用,需求大,所以要不断找好用的。

软件的开发或许也如此:需求过大——快速开发的demo——不断更新的功能、不断优化的体验。但也有很多产品,经过了长时间的沉淀,出道即巅峰。同样,这里也就涉及到最小价值产品(MVP)还是完美产品(MBP)的问题了。

而对于我们的程序,大部分功能其实能够根据指导书正常运行,但是可能由于我们对文件管理系统的了解不足和指导书的分析不够到位,issue区的大部分坑点我们都没有想到,于是issue区的易错点成了我们的重灾区,比如硬链接链接软链接的链接文件等坑点。几乎遇上issue的问题都会出或大或小的问题,当然我们在测试部分着重关注了这部分坑点,所以最终的Bug也不是很多。

3. 架构设计体会

在第一部分,我们的设计思路其实非常简单。我们实现的文件系统的主要元素就只有两个:文件和目录。其中目录之间有包含关系(上下层),文件也会存在目录中。所以我们创建了两个类:MyFile类和MyPath类分别表示文件类和目录类。然后对于各个细节的要求,我们就在各个类中完成相应的必需功能并提供给顶层的MyFileSystem类,用来集成实现最终的功能。而对于第二部分,将第一次作业整合进fileSystem包中,将此次作业新增的用户和用户组相关整合进userSystem包中,作为两个相对较为独立的系统进行代码编写和运行。而对于新增的软链接和硬链接,我们采取的方法是是分别新增软链接类和硬链接类,而不是将软链接和硬链接归为文件类统一管理。

在这个架构的基础下,由于对象种类增加,我们对原有代码也进行更新,多了很多对象种类的判断和运行逻辑。而且对于新增的mv, cp, ln等指令,由于有四类对象的存在,所以每次的对象判断,我们都需要对这四类对象进行分别判断和处理,极大的增加代码的复杂度和冗余度,而且Bug频发,后期主要精力也花在这一部分。而且代码冗余的增加进一步的提高了测试的难度,导致我们在debug和测试时都感觉到了一定的困难。这也进一步体现了一个好的架构的重要性。这也是我们在结对部分,在架构设计部分需要进一步提高的问题所在吧。

其实,我们也想过将软链接和硬链接归类为文件对象,但是因为我们第一次作业并未留下这个接口,以及我们认为这样需要更大范围的重构,就并未进行这样的架构修改,现在想想有亿点点后悔。

4.进度、质量和沟通管理实践体会

此处通过PSP流程来总结两次结对编程的进度管理

PSP2.1 Personal Software Process Stages 预计耗时 实际耗时
Planning 计划 20 +10min 10+10min
*· Estimate · 估计任务需要多长时间 20+10min 10+10min
Development 开发 895+1420min 975+2120min
· Analysis · 需求分析 90+90min 120+120min
· Design Spec · 生成设计文档 30+20min 30+20min
· Design Review · 设计复审 10+10min 10+10min
· Coding Standard · 代码规范 5+10min 5+10min
· Design · 具体设计 30+30min 20+60min
· Coding · 具体编码 400+500min 350+720min
· Code Review · 代码复审 30+60min 60+80min
· Test · 测试(自我测试,修改,提交) 200+700min 380+1100min
Reporting 报告 135+110min 110+100min
· Test Report · 测试报告 100+60min 60+40min
· Size Measurement · 计算工作量 20+30min 30+20min
· Postmortem & Process Improvement Plan · 事后总结,提出改进计划 15+20min 20+40min
合计 950+1540min 1095+2230min

由于大部分时间我们都是线下面对面编程,而且我们都甚至自己和对方的生活极为”充实“,所以每次在一开始我们都会对进度进行一定的预测和控制,而且从第一次的结果来看,效果极为不错。但是第二次的难度预估远超我们的预料,所以进度预估和控制把握不是很好,从PSP表上也能看出,差距较大。程序的质量和交流的效果也因线下而效果较为不错。

我们在第二阶段的最后一天,发现了因为两人对于硬链接链接软连接链接这个概念理解出现偏差,程序在弱测中出现了bug。我们花了一些时间对这一细节进行了不大不小的“争论”和探讨。

5.提出建议

在结对编程之前一定要先了解什么是“结对编程”。充分阅读《构建之法》!《构建之法》用了大篇幅来介绍,他从人员配合、分工、过程的每一步都进行了完整的分析。

整个结对编程期间,我与队友很少出现因为时间冲突、性格不合、说话方式而产生矛盾和问题。队伍之间讨论的最多的,除了以上所谈到的一些bug之外,就是细节的设计和实现思路了。

或许在不看这本书之前,与队友的争执会让我有些心浮气躁,但看了这本书之后,我能清楚地意识到我们只是在对于项目的设计进行争论。同样,他也能认识到这一点。

结对编程的伙伴需要对双方的目标、结对方式、心理预期等等做互相的了解。

社会心理学上有一个概念:

“行动—观察者差异”。自己对于某件事的看法,相比别人看见你的行为推测你对于这件事的看法是有差异的。你的行为并不能完全代表你的看法。

这是因为行动者与观察者有着不同的思考、观察角度,所带有的价值就不同。而阅读《构建之法》,相当于在我和我的队友之间建立了相同的价值,我们就能消除这样的“差异”,更加心平气和的去面对“争执”。

二、CI体验感想

我认为CI的作用非常的强大。CI能够进行Junit单元测试程序的自动化测试,并且计算出相应的代码覆盖率。CI的部署让我们省去了很多额外的测试时间。同时,CI强大的功能支持我们通过url下载的官方包进行测试,每次上传代码之后就能够查看结果。但是我们也知道,我们对CI的了解还不是很多,CI还有更多有利的地方等待我们使用和挖掘

三、结对编程感想

1.结对编程方法与经历分享

我们结对大部分都是在线下进行,面对面的分享和交流,从需求分析开始统一意见和目标,然后采用“领航员与驾驶员频繁互换身份的方式”,来完成绝大部分的项目开发。线下交流可以及时解决突发问题,然后继续开发,将影响降到最低,不让问题过夜。

优点:互相学习和问题交流,取长补短,保证项目的稳定进行

缺点:需要一定时间的磨合,虽然我们的开发过程中没什么大的冲突和分歧,但是在小部分还是有很多需要改进的地方

分享部分或许大概就是:线下结对编程应该会是体验最好的方式之一了吧,及时的问题交流和解决,近距离的学习和吸取队友的优点,体验非常不错。一定要统一代码规范,统一规范的代码让队友能够快速的理解和上手,可以极大程度的减少不必要的时间开销。

2.使用工具

交流:宿舍(绝大部分)、微信(后期实在无法线下结对才使用的)

代码编写:IDEA软件,maven项目管理,腾讯会议共享屏幕

单元测试:JUnit4

项目部署:gitlab-ci持续集成(十分感谢讨论区大佬的知识分享)

3.队友评价以及感悟和体会(吐槽)

3821

lhx同学时间管理能力非常令我佩服,在其他工作的压力之下也能够拿出大量时间和我进行线下的分析讨论与面对面编程。同时lhx同学的分析理解与决断能力在这次结对编程中起到了重要作用,经常将理解上误入歧途的我拉回正道。lhx同学优秀的编码规范也是我们能够完成结对作业的一大助力。以及或许在思考问题的细节方面能够再周全和缜密一点,或许能够更好。当然了,这是一次非常愉快的结对合作,希望都能在软工课上收获满满,取得好成绩。

其实总的来说,结对编程的体验还是很不错的。两个人线下面对面,从需求(指导书)分析到设计,从编码到最后的单元测试,都是及时讨论一起解决的。在分析和设计阶段,能够互相帮助理解需求,集思广益进行架构设计(不过好像我们的架构也挺一般的orz);在编码和单元测试阶段,能够及时纠正编码错误,增添对细节点上的测试等。也很幸运有一个优秀的队友,让这次结对体验更加完美。(如果后续的指导书再斟酌、控制一下,那么此次体验就真的perfect了)。

这次结对作业应该算是有初步的需求不断变动的工程体验了。第二次作业上,既要修第一次的bug,又要增添第一次应该考虑但是课程组未测试的细节,还要更新属于第二次的需求。而且第二次作业需求上的不断更新与细化,为了不大范围的变更代码,我们只好就疯狂打补丁,最后代码效果emmmmm(懂得都懂)。这应该是我们需要进一步学习与改进的部分吧。感谢老师和助教在此部分的准备和及时回复,也希望在后面的阶段会有更多的收获。

3676

在文章的开头我就赞扬了我的队友,我从他的身上学习到了非常多优秀工程师的品质。其中最为突出的一点:测试全面,前面已经提及了。他对于小模块的测试也毫不含糊,在结对编程的过程中,这样的一丝不苟不断地影响着我,让我更加重视测试。而在整个过程中,他更像是一种“驾驶员”的角色。他的代码能力比我更强,而我可能在设计上有些有意义的见解。从头到尾,我们之间的合作都是非常愉快的。

接着实践总结部分的最后,我想来谈一谈结对编程任务。

首先,毋庸置疑的是,这两周的经历让我收获非常多。收获不仅在于代码,设计层面的知识,更是在合作,交流的层面。知识固然重要,但学习别人的优点,与优秀的人交谈,领会他们的思维和思想,更是一件幸福的事。我不仅从我的队友身上学到了很多,我还有机会通过博客的方式,与大佬们进行交流。本人代码能力并不强,身边优秀的同学思考得还比我更加深入,我深感惭愧。当然,这也会不断激励着我变得更好。

其实翻看第二周的博客,我似乎在“反思”。可是当我翻看其他同学的博客时,我能感觉的到,他们才是真正的在反思。而我只是发发牢骚,对大量投入的时间和不对等的回报感到不满。在那篇博客中,我将我们比作“小白鼠”,结对编程比作“实验”,而表达我的“痛苦”。看似“理性”的看待,但实则非常感性。所以我在后面的评论中反思道:

抱歉,这个比喻可能有些不恰当。我并没有觉得课程组在我们身上做实验,课程组对于课程的设置一定是经过深思熟虑的。人非圣贤孰能无过,有一些差错完全可以理解。其实我也在反思自己:自己写博客的时候是否是在发牢骚,而不是真正的思考;自己的能力是不是还没有能够达到课程组的要求,所以才花了这么多时间(相比于其他结对小组,我们的时间也高出了不少)。
但是不管怎么样,我可以看到的是,我们和课程组都在不断地进步!“悟已往之不谏,知来者之可追。”过去的已经过去,而为未来做好充分的准备才是现在最重要的事!

既然结对编程已经结束,或许应该好好反思,写一篇博客,好好睡一觉然后重新出发!

posted @ 2021-04-09 00:32  力理利丽黎  阅读(174)  评论(6编辑  收藏  举报