软工——提问回顾
软工——提问回顾
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2021春季学期软件工程(罗杰、任健) |
这个作业的要求在哪里 | 提问与个人总结 |
我在这个课程的目标是 | 和团队成员一起成功开发出一款具有实用性的软件,了解软件开发的流程并掌握软件开发过程的 |
这个作业在哪个具体方面帮助我实现目标 | 对本学期的软工课程做一定的总结与回顾 |
一、提问回顾
此前提出的问题在这里
Q1: 教材P27
单元测试应覆盖所测单元的所有代码路径,包括错误处理路径。为了保证代码覆盖率,单元测试必须测试公开的和私有的函数/方法。
书中提到单元测试应该覆盖所有代码路径,由此我有一点疑惑是如何提高单元测试的覆盖率(尤其是对于经验不足的新人)。这篇博客提到常用的代码覆盖度量有语句覆盖、判定覆盖、条件覆盖、路径覆盖几种。根据我不多的测试相关的经验,感觉一开始很容易将语句覆盖作为衡量的标准,语句覆盖率实际上并不能真正达到我们想要的测试效果,路径覆盖才是最强力的测试依据,但是当代码的分支和嵌套比较多时,路径覆盖所需的样例数量会变得非常多,那么在这种情况下我们只能通过人力进行排列组合吗(是否有相关的工具可以使用)?或者我们应该考虑的是对代码的结构进行优化?
A1:
在结对编程的过程中,我们也编写了单元测试,对单元测试有了更多的理解。在一开始时根据代码的结构编写测试样例以覆盖尽可能多的语句是全面测试的有效方法。但是这种方法的前提是代码的编写者已经考虑了可能出现的所有情况,没考虑到情况自然也不会被测试样例覆盖。因此,这种方法的测试作用比较有限,我在实践中认为直接根据需求设计测试样例会更加全面,同时若代码的编写符合要求,在良好的样例下覆盖率其实自然就能达到要求。
Q2: 教材P37
回头看我们在第一章提高的软件的特殊性,可以看出这些题目缺乏两个基本的要素:复杂性和易变性。我们提到,程序=算法+数据结构与;软件=程序+软件工程。软件工程的编程作业,不仅仅是程序,而是要加入软件工程的要素(复杂性、易变性和其他),有价值的软件工程的作业必须要触及这两个基本要素。
针对这一段话我有几个疑惑。
首先复杂性和易变性是软件的基本要素。假设有一个客户有一个明确的需求,开发一款仅支持四则运算的计算器,在我看来这是一个需求十分明确,而且也并不复杂的软件(但不可否认的是开发过程也有可能存在没预想到的困难)。那么这个计算器的开发就不需要运用软件工程的相关方法来辅助了吗?
其次我十分赞同有价值的软件工程作业需要满足复杂性和易变性。但是在操作时可能会遇到以下困难:
- 在选题时可能会因为功能的复杂导致不敢轻易选择,很有可能最后还是选择了自己能实现的功能而不是更有实用价值但可能需要一定的学习才能实现的功能。出现这个问题的原因我想主要是因为在考虑需求的时候往往会不由自主的思考需求背后的技术问题,最后就不变成了技术驱动需求而非需求驱动技术了。
- 在软件开发的作业中,我们实际上不仅扮演了乙方,也扮演了甲方。那么在需求提出的时候,我们往往会不自觉的提出甲方(实际上也是我们自己)所想的需求。这样的需求往往不会有很大的变化,那么易变性又从何谈起?
所以我的疑惑在于怎么能够提出有价值同时是我们的团队能够高质量完成的选题?
A2:
在我们的团队项目的选择过程中,我们主要从选题的现实意义以及实现的难度上进行考量。第一点就是我们的产品会有人使用吗,如果有用户对我们的产品有所需求就可以说我们的选题有一定的价值。另外还要充分考虑,本小组是否有充足的技术实力完成项目,选题时我们也对小组成员的技术背景做了了解,选取了我们有一定经验但是也有一定挑战性的题目作为选题。从开发的过程来看,由于成员对工作有一定的了解,因此上手是比较快的,另外对于比较有挑战性的部分,也能在合理的时间内进行解决并保证质量。
Q3: 教材P48
分析麻痹:一种极端的情况是想弄清楚所有细节、所有依赖关系之后再动手,心理上过于悲观,不想修复问题,出了问题都来在相关问题上。分析太多,腿都麻了,没法起步前进,故得名“分析麻痹”。
通过之前几年的实践,我发现理想和现实的差距往往会很大。比如在编译技术的大作业中,我提前计划好了要如何组织不同的文件和函数。但是在实际的操作过程中,由于之前没有想到的问题(或许是没有正确衡量一个功能的难度,或者是coding的太嗨就没顾上之前的设计又懒得重构等)。最后的成品和理想中完全不一样。对于软件工程的作业来说,我想可能会存在更多的不可控因素,那么如何合理的提出预期的计划呢?或者说最后的成果与计划如果存在一定的偏差的话,是否有一个范围是我们可以容忍的(就像物理实验中的误差)?
A3:
软件工程并不只包含代码的编写工作,在每次的开发之前都会编写相关的需求规格说明书和技术规格说明书,在这两项的指导下,实际上的开发工作已经被分解的比较明确了,因此在开发过程中,只要按部就班做好相关的工作其实都能完成预计的目标。
Q4: 教材P69
函数最好有单一的出口,为了达成这一目的,可以使用goto。只要有助于程序逻辑的清晰体现,什么方法都可以用,包括goto。
在这里我的疑惑主要在于在我大一的C语言课程中,对goto的态度是尽量不能不要使用,容易造成程序结构的混乱,使得程序难以理解和维护。在我的实践中,实际并没有使用过goto语句。我认为出现这种矛盾的原因是两本教材面向的人群不一样吧,一个成熟的程序员应该可以很好的掌握语言的特性方便开发。那么我应该如何合理的定位自己的能力水平呢?
A4:
我认为对自己的定位是一件浮动的事情,在不同的团队里面应该要有不同的定位。也许在这一团队中你充当的是主要的角色,那么就应该对自己提出更高的要求,在另一团队中,你充当的是查缺补漏的角色,那么就应该针对缺漏进行定位。对于goto语句的使用,我现在认为其实不必过度四班,更多的还是要遵循团队的开发规范。
Q5: 教材P131
阿超:这样做有什么好处?好处有两点:
(1)被授权的人会承担起自己对项目的责任,同时也期望同事们也同样对项目负责;
我的疑惑在于这样的表述是否过于理想化,仿佛成员得到授权之后就能自然承担起自己对项目的责任。本人虽然开发工作做得不多,但是做了很多的学生工作,从我的经验来看,能否把工作做好和得到充分的授权不是充要条件的关系,做好工作需要得到充分授权但不意味着得到充分授权就能做好工作,项目也是一样。我任务做好项目的驱动力在于个人对工作的重视程度和责任心。这种重视态度可能来于自己本身、负责的组长、课程的压力等。所以我并不认同上面的那句话。
Q6: 教材P173
软件工程师在长期的实践中,摸索出一套经验公式:实际时间话费主要取决于两个因素——对某件事的估计时间X,以及他做过类似开发工作的次数N。
$Y = X \plusmn X / N $
从公式中不难看出,如果一个人从来没有做过类似的工作,那么估计时间将会是无穷大。书中接下来也提到,从来没有做过网站的用户管理模块的果冻,在项目时间内压根做不了这个模块。这样来说,可能很多同学都没有做过完整的软件,那么在项目时间内根本做不完,那又如何是好呢?但是这种情况根本不会发生,我相信绝大多数的同学还是能在项目的规定时间内完成任务的,只不过过程可能痛苦了点或者质量低了一点。所以估计时间的时候难道不应该将人的学习能力也作为考量的指标吗?简单的除0似乎过于粗暴了。
A6:
在实际的开发过程中,我也感受到完成工作的时间和预期的时间往往会有一定的差距,但是我仍然不认同书中的计算方式。我也了解到有其他的计算方式,比如:
$Y= (a + 4b +c)/6$
其中,$a$是最快完成时间,$b$是最可能完成时间,$c$是最晚完成时间。
我认为这种计算方式更加贴合实际,不过重要的是我们要认识到预计完成时间和实际往往会存在偏差。
二、新的问题
在实际的开发过程中,由于经验和时间的问题,在对开发工具的理解上往往会存在很多不足(比如在Beta的项目展示中,助教提出我们对flask的使用并不规范,没有良好的拓展性)。然而真实的情况是,在开发开始时,我们所接触到的相关教程以及文档并没有更规范的用法,因此我们就一直沿用了并不规范的写法。因此在刚开始时如何能获取对开发工具更多更规范的知识呢?
三、学到的知识
3.1 需求
对软件的需求,可以从多个角度进行划分:
- 对产品的功能性的需求:产品必须实现的某些功能
- 对产品开发过程的需求:要求软件的开发流程必须满足某些约束条件
- 非功能需求:也叫“服务质量需求”,比如软件的响应速度、并发性等
- 综合需求:一个软件模块不能解决的需求,往往需要多个模块的配合
在实际的需求分析过程中,我们更多的关注的是功能性需求以及综合需求,对非功能需求的比较少。在开发的结果出来之前,我们的软件性能如何谁也不能估计。但由于我们的软件目前用户量有限,因此在这方面没有出现重大问题,但在设计大型软件时这一点显然是不能忽略的。
3.2 设计
前期的设计和实际的开发过程很难做到完全一致,在设计阶段我们要做的是将功能的定义和说明尽可能的完善,以减少开发过程产生不一致的情况。同时设计是一定要和需求密切相关的,但是也不能只须局限于如何满足功能,还需要注意用户的使用体验以及美观。
3.3 实现
在代码的编写过程中如果只对功能做出要求,对其他部分没有要求就很可能导致代码的质量不符合要求。比如在在我们的开发过程中,数据库部分有一个方法的要求是返回所有国家的概要数据。在只有这个说明的情况下,数据库采取每次都对数据库进行查询的操作,导致响应速度很慢,在发现这一问题之后,我们追加了要求,将结果村雨内存中,每次直接返回,之后才满足了我们的要求。
3.4 测试
代码编写完成只意味着开发工作完成了一部分,测试工作也同样工作,测试工作的好坏直接影响着之后的用户体验。在Alpha阶段,由于经验不足,测试工作做的比较混乱,就出现了在发布之后有用户反馈了比较明显的bug。在Beta阶段我们吸取教训了,对测试工作进行了一定的规划,就没有出现Alpha阶段的情况。因此,我认为测试计划其实和开发计划同等重要。
3.5 发布
软件发布的一大重点就是良好的宣传工作,我们需要让目标用户群体了解到我们的产品。在宣传方面,我们主要利用的是个人的社交网络,发送认识的人进行使用。为了弥补用户来源的多样性,我们也在CSDN、知乎等平台进行了宣传文章的投放,当然碍于账号的影响力,对这两部分用户的引流效果比较一般,但也有一定效果。如果是作为一个更加成熟的商业项目的话,就需要更多的宣传投入,包括广告的投放、各大平台的推广等,因此实际上宣传的预算也占有比较大的比重(尤其在当下的市场氛围之下)。
3.6 维护
软件发布之后,在用户的使用过程当中往往会发现测试工作中没有发现的bug,或者用户会对功能等做出更多的建议。因此维护的工作不仅要保证软件能正常提供服务,也需要对用户的反馈进行必要修复和优化,这是一项长期的工作。在我们的实践中,我们对Alpha阶段中用户提出的意见就进行的一定的处理,但是长期的维护过程还没能体验到。
四、个人感悟与收获
在这一学期的软工课程当中,我经历了个人作业、结对编程、团队项目三个阶段。现在进行回顾,发现其实一个学期的时间还是做了不少的事情。首先,自己的编码能力有所提升,不管在结对编程还是团队项目中,所写的代码都会被其他人审阅查看,因此无形中使我更加的注意了代码的可读性,在函数、变量的命名上都没有偷懒orz。另外,在团队项目中,我也担任了PM。相比其他PM,我在技术实力上并没有那么的强,因此我更多的不是在技术上进行把关(技术上的问题往往会给成员更多的自由度),我更多的是关注整个项目的进度以及开发过程中管理工作。经过两个阶段的团队项目,我觉得自己的PM工作做的算是有得有失吧。先说做的好的一方面,在项目过程中,团队的氛围一直比较良好,同时开发的进度把握的也比较到位,基本上都按照预定计划完成了工作;做的不好的一方面,在项目过程中对技术规范的关注有些不够,因此也被助教指出了很多的问题,我们也虚心的接受了,以后会更加注意开发的规范性。最后,在软工课程的过程中,我觉得有一点贯穿始终的是合作。也正因为结对编程和团队项目,我认识了一群优秀又可爱的队友,他们给我这学期的软工课程增加了不少的色彩,我也很感谢他们对我的帮助。
最后再聊一聊我的感悟吧。这一学期的软工课程可以说过得很充实,不管怎么说,在工程能力上对我的锻炼是很大的,学习了新的工具、接触了新的项目。但是我觉得有一点的问题在于课程的内容并不能很好的指导实践,实际的开发过程多少还是有一些摸着石头过河的感觉(虽然助教的存在很大程度上的弥补了这一点)。所以我在这里也给出一点小小的建议,希望理论课能和实践有更多的联系。