项目 | 内容 |
---|---|
作业所属的课程 | 2020春季计算机学院软件工程(罗杰 任健) |
作业的要求 | 提问回顾与个人总结 |
我在这门课程的目标是 | 学会使用软件工程的设计思想和方法,能够设计出高效并且可用性、可维护性、可拓展性较高的软件。 |
这个作业在哪些方面帮助我实现目标 | 回顾之前提出的问题,根据这一学期软件工程课程的学习进行总结和反思。 |
阅读教材并提问的博客 | 软工个人博客作业 |
问题的回答
问题1
单元测试必须由最熟悉代码的人(程序的作者)来写。代码的作者最了解代码的目的、特点和实现的局限性。所以,写单元测试没有比作者更适合的人选了。
选自 第2章 个人技术和流程 2.1.2 好的单元测试的标准
问题:这里我不太明白为什么作者是写单元测试最合适的人选?在我看来,一个项目的团队里应当由人专门负责做测试,他们并不知道具体的代码实现,只知道软件的大致设计思路(例如有哪些主要的类,类中的方法目标是实现什么样的功能),但是应当站在未来软件的用户的角度为软件编写单元测试。
当时缺少实际团队项目的开发经验,对“单元测试”存在一些误解,经历了团队项目开发以及编写单元测试之后对此有了进一步的认识。在团队项目开发时,实际上我们也是如课本所说的,代码的作者编写单元测试,并没有专门抽调人手去写单元测试。
就我的理解而言,单元测试的目的是保证自己所完成的部分能够按照自己的预期完成特定的功能,对于自己的预期,没有人比自己更清楚。而那些真正需要专门的测试人员进行测试的部分,更多应该是单元测试无法保证的地方,毕竟,一个单元不出错不代表整体不会出现问题。例如对整体的功能进行测试以及进行压力测试等等。
问题2
驾驶员和领航员不断轮换角色,不要连续工作超过一小时,每工作一小时休息15分钟。领航员要控制时间。
只有水平上的差距,没有级别上的差异。两人结对,尽管可能大家的级别资历不同,但不管在分析、设计或编码上,双方都拥有平等的决策权利。
选自 第4章 两人合作 4.5 结对编程
问题:二人结对,总会存在水平上的差异,对于同一问题或者设计方案,在双方有不同的想法时如何进行正确的决策?诚然,平等的决策权利固然重要。但是,一个有远见的构想可能会受到另一方的不解甚至反对,但是这时我认为适当听从更有经验、能力更强的一方的经验会更有利于项目的推进。所以,这里想请问,“平等的决策权利”究竟意味着什么?我们在实际结对过程中如何有效处理决策上的冲突?
当时提出这个问题是因为我和我的结对伙伴编程能力差距悬殊,不清楚实际开展时会不会有“平等的决策权利”。我的结对伙伴设计能力、查找资料的能力、编写代码的能力要比我强很多。但是实际进行结对编程之后,发现即使差距悬殊,这种“平等的决策权利”依然是能够得到保证的。
例如,由于结对是基于个人项目的增量开发,因此以谁的个人项目为基础进行开发需要进行决策。我的队友没有直接将他的想法强加于我,而是我们共同对两个人的代码进行分析,了解了队友代码的设计以及运行效率的优势之后,共同决定选择他的代码开始开发。“平等的决策权利”不代表决策结果的平均,而是要在决策过程中充分体现公平性,既然你认为你的决策更加合理,那么就要拿出证据,让对方信服。
保证这种公平性,最重要的手段是充分沟通,遇到了决策上的冲突,要保持冷静和克制,尊重对方观点,同时要有事实依据,要以理服人,这一点在后面的团队项目中也得到了印证。
问题3(仍不解)
在冲刺阶段,外部人士不能直接打扰团队成员。一切交流只能通过Scrum大师(Scrum Master)来完成。这一措施较好地平衡了“交流”和“集中注意力”的矛盾。有任何需求的改变都留待冲刺结束后再讨论。
选自 第6章 敏捷流程 6.1 敏捷的流程
问题:所以我想是否应该根据团队的规模适当地调整Scrum Master的人数,即不是一位Scrum Master,而是一个Scrum Master Group?设置Scrum Master,我认为就是在效率和(由更广泛的交流和协商所保证的)可靠性之间进行权衡。过多的交流不利于集中注意力,但是如果所有的最终决策都依赖于一位Scrum Master,是否有可能会增加因个人的决策失误而影响项目进展?对于人数更多一点的团队,比如7人,可否从中选择两人共同担任Scrum Master,以降低个人决策失误的风险?
在冲刺阶段,我们实际上并没有这样做。对我们的团队项目而言,“外部人士”主要是给我们团队项目提建议的人,即老师、助教或者我们的用户。对于这些反馈,我们都是通过组会讨论共同决定是否采纳以及具体如何加入到计划与安排中的。
我们的团队人数只有7人,与一些更大的开发团队而言相比确实不够有代表性。对于一个更大规模的团队(比如30人),在冲刺阶段通过组会讨论“外部人士”的意见和建议确实效率很低,不现实。需要通过将外部建议进行转化,然后对成员进行直接传达,这在冲刺阶段是很有必要的。但是一个人决策仍感觉有些不妥,由团队中的一小部分人进行交流和决策是否更为妥当?
问题4(仍不解)
(PM)和大家平等工作,推动团队完成软件功能。
(如果让PM也参与开发)可能小船的速率会快一些,但是小船的方向、稳定性会出问题。船是划快了一些,但是划桨的众多队友不能协调一致,船也不稳。
(上述PM指Program Manager)
选自 第9章 项目经理 9.3 PM做开发和测试之外的所有事情
问题:诚然教材中进行了介绍,例如,Project Manager是团队的行政领导,带领大家在项目中工作,Program Manager和大家平等工作,推动团队完成软件的功能。但是,一,虽说“平等工作”,但其工作内容确实与其他开发人员的工作不同,平等工作可以有效增强团队的活力,但是这种平等要如何保证?二,Project Manager确实由于其领导地位,在进行任务布置时可以直接指派任务而不必做过多解释,Program Manager则需要完成质量比较好的产品规格说明书,然而在实际指派任务时,如果不进行清楚的说明,是难以调动下属的积极性的。
在我们的团队项目中,PM同学的职责更像是Project Manager,是团队的行政领导,是团队对外的窗口。由于PM本身担任了汇报、博客以及统筹策划等一系列管理工作,因此并没有直接参与项目的代码编写,对于除了软工这门课程之外还有很多其他课程的学生而言,这种做法是明智的,正如教材所说,“如果让PM也参与开发可能小船的速率会快一些,但是小船的方向、稳定性会出问题。船是划快了一些,但是划桨的众多队友不能协调一致,船也不稳”。这一学期的团队项目,因为有了PM的管理和领导,我们才能进行地比较顺利。
根据这学期开发的经验,我在想,实际开发过程中能否允许Project Manager与Program Manager两个角色并存?在这学期中,我认为我担任的角色应当是后者。我实际参与了开发,学习了相关的技术知识,同时在开发过程中实际执行对项目的计划和任务的设计和分配以及相关技术的帮助等职责,个人感觉在项目的代码层面上比Project Manager要更清楚,但是组织、管理、监督以及在大方向是进行指导的Project Manager的同学。所以,一个人参与了实际开发,好处是能够更加了解项目的实际情况,但是同时也容易因为了解实际情况,过于关注实现细节,有时容易对用户需求、任务进度等大方向不能很好地掌握。同时为了“平等地”进行开发,防止出现一人专断的情况,Program Manager不应该与其他组员形成纵向管理关系,这就需要有一个能够管理整个小组的任务,那就是Project Manager。
问题5
软件功能说明书(Functional Spec),主要用来说明软件的外部功能和用户的交互情况(把软件当作一个黑盒子)。
Spec的最大敌人是什么?是乏味。软件公司的大部分人都不喜欢读文档,更不要说大学生了。
把边界条件规定清楚,理工科思维的工程师们看到这里大脑就兴奋起来了——他们想找出你Spec的破绽!
选自 第10章 典型用户和场景 10.3 规格说明书
问题:这里我想请问如何能够在保证不乏味的基础上仍能够保证边界调剂规定清楚?即,如何处理“可读性”和“严谨性”的平衡?如果有可能的化,我想看一下“把边界条件规定清楚”的实例,在实际书写软件功能说明书,对软件或者其中一个方法的功能描述时,是否使用到了类似JML的形式化语言,如果是,如何避免为严谨而造成的逻辑复杂与可读性的降低;如果不是,如何保证严谨性?
当时提出这个问题,确实是因为没有实际开发的经验。现在来回答这个问题的话,功能规格说明书的目的就是要想用户介绍产品的功能是什么,以及在什么样的限定条件下能够保证我们的工作正常使用,是没有必要使用过于形式化的语言的。在我们项目的功能规格说明书中,我们在介绍产品功能时,使用图文结合的方式,保证了可读性,同时在逻辑结构上我们尽可能按照规格的说明流程,从前置条件(require)到后置条件(ensure)进行了清楚的说明,用户在进行合法的操作后能够保证得到正确的响应,这样保证了严谨性。通过使用生动的语言配以清除的图片保证可读性,同时按照规范的逻辑进行清楚的说明和界定以保证严谨性。
问题6
在我们的全球调查中,我们发现成功公司中有94%每天或至少每周完成构建,而不成功公司绝大多数每月甚至更少去做构建。
选自 第11章 软件设计与实现 11.5 开发阶段的日常管理
问题:我想进一步了解进行一次每日构建需要经历哪些流程?要想开始进行每日构建需要满足哪些条件?在有些时候由于要实现一些比较复杂的功能,所需要的时间比较长,这时再要求一个较高的构建频率是否会对原有的开发计划安排造成影响?为何每日构建(或频率较高的构建)有助于一个公司的成功?
当时不太清楚“构建”的含义。现在来看,我认为“构建”是一个项目功能可用性的版本,即,构建的版本所提供的功能应该是可用的,即便只是最小可用版本。在我们团队项目开发的冲刺阶段,按照此标准,我认为我们达到了进行每日构建的标准。这样的优势在于,保证当前任何时刻GitHub的master分支上的项目代码都是可用的,能够体现项目的质量,能够使项目平稳地过渡到最后的发布阶段。对于一些比较复杂,无法一次性完成的功能,可以采用分部分迭代的方式,不断地提供一部分的可用版,然后横向完善其它部分,纵向对每一部分的可用版进行迭代开发即可。
问题7
其实,大部分成功的创新者都不是先行者,例如搜索引擎,Google是很晚才进入这个领域的。又如Apple的音乐播放器iPod,发布于2001年10月23日,在它之前市面上已经有很多同类产品了。
- 先行者(First Mover),先发优势(First Mover Advantage,FMA)
- 后起者(Second Mover),后发优势(Second Mover Advantage,SMA)
选自 第16章 IT行业的创新 16.1 创新的迷思
问题:所以,我想了解一下“后发优势”具体体现在那些方面,那些诸如Google和Apple这样成功的企业它们是如何利用后发优势超越前人的?特别是在今天,在一些国际知名的企业已经占据了行业的领导地位时,同样的后起之辈如何发掘创新点,打破垄断实现超越?
通过将我们的团队项目软工课程管理平台与其它类似的平台进行对比后对此有了进一步的认识。在我们的软工课程管理平台发布之前,已经有很多类似的课程平台,例如我们在数据结构以及编译技术课程设计中都使用到的六系计算机专业课一体化平台,这个平台集题目、评测以及交流讨论、发布课程信息等诸多功能为一体,服务了多门课程、考试以及竞赛。我们的软工平台作为后起者,又有怎样的优势呢?我认为是我们更加专注于软工,我们的服务对象更小,这使得我们能够在某一特定领域获取竞争优势。例如,我们提供了团队项目管理的功能,例如学生端的看板以及教师端的团队进度监视,这是先有的通用化的课程平台所不具备的。所以,现在回答我之前的疑问,我想,后起者要想有所超越、有所突破,一个可能的思路是,首先从一个小的服务范围做起,特别是现在市场上已经有类似产品的情况下,在这个小范围做到小而精,做到能够更加准确地贴合用户需求。与此同时不能忘记预留好进行拓展的架构,以便在占住一席之地后进一步拓宽市场。
问题8
互联网的先驱蒂姆·伯纳斯-李(Tim Berners-Lee)到史蒂夫·乔布斯的NeXT公司推销他的HTML和互联网远景。但是NeXT公司以乔布斯为首的技术精英们也没有认识到这个创新的价值——“我们就像当时的其他人那样,错过了它。”
选自 第16章 IT行业的创新 16.1 创新的迷思
这里不太清楚企业在创新技术的发展与推广中究竟发挥着怎样的作用?反过来,没有企业的支持,一项技术的创新能够被广为接受和使用的可能性如何?如一个人进行了一项技术的创新但是没有得到来自企业的帮助,如果他认为这项技术确实可以被广为应用而且造福于人,那么他应当如何去做而避免自己的创新被埋没?
对于这一个问题,因为我们的项目没有涉及到全新的技术或是前沿的科技研究,所以这里我想结合我了解的一些事例进行回答。当初我提出这些问题,是担心一项新技术可能会因为没有得到企业的支持而被埋没,所谓良马没有遇到伯乐。但是现在,我认为对于这个问题需要以一种发展的视角来看。外界环境是不断变化的,可能某一项技术在当时的背景下可能看不出其实际价值,但是随着时间的发展和推移,人们的观念在不断变化,一项科技创新可能会展现其价值。例如,机器学期在几十年前由于一些研究中遇到的瓶颈以及处理器计算能力的限制,始终没有得到广泛的应用,直到最近,随着设备计算能力的增强以及相关领域研究的突破,其被广泛应用于生活中的各个领域。所以,我认为价值是具有时间性的,因此不必担心一项科技创新会因为在当时没有得到企业或其他组织的推广而被埋没,只是有可能在当时的条件下并没有能够充分展现其作用。另外,我认为企业在促进一项新技术的推广中发挥着重要的作用,一方面,企业设计制作的产品是最直接接触一般群众的生活的,另一方面,企业因为要获取市场并在与对手的竞争中取得优势,就迫切需要企业进行不断改进,也从一个方面促进了技术的发展。
新的问题
- 结对编程通过两个人一起进行编程,一边编程一边进行复审,同时通过凝聚两个人共同的智慧,减少错误的出现,但是这样的效率如何?实际进行结对编程时,并没有觉得这样能够有多大程度提高代码质量,反而花费了更多时间。通过结对编程,以更多时间换取代码质量的提升,这样是否值得?如何对此进行权衡?
- 在组织团队时,什么样的人适合组成一个团队,是彼此差距比较悬殊,团队中一些成员没有相关的开发经验,同时存在几位富有开发经验、足以carry整个团队的成员,还是彼此水平比较平均,都有一定的经验但是都不足以独当一面?如果是前者,那么这些富有经验的成员应当处于怎样的地位?如果这几个人承担了主要的工作,那么剩下的成员如何发挥其价值?如不然,又如何保证项目的快速推进?对于后者,如果出现了意见分歧,如何进行有效地处理以保证项目进度?
- 在进行团队项目开发时,如何充分调动团队成员的积极性?如何避免出现集体负责变成集体不负责?虽然我在实际团队项目开发中没有遇到这一问题,但是在团队项目阶段开始前有过类似的担心。
- 如何对团队成员彼此之间的独立性与相互之间的整体性进行权衡?团队成员彼此有不同的分工,任务也不尽相同,彼此之间具有一定的独立性,但是作为一个团队,又需要彼此之间相互帮助形成一个整体。例如,成员之间当团队中的某一成员分配的任务遇到了困难,想要寻求其他团队成员的协助时,因为该任务本身并不由其他成员负责,成员认为对此不承担责任,进而使该同学花费很多时间自己一个人解决,耽误了项目的进度,这种情况又如何进行协调?
学习到的知识点
- 需求:学习了常用的如NABCD的需求分析法,并通过对用户需求的科学分析确定了项目中要实现的功能的主次
- 设计:学习了对Vue组件进行封装以进行解耦的设计方式,同时进一步了解了前后端分离的设计方法(后者在我们实际的项目中没有使用,因为我们的项目继承了一位学长之前的毕业设计,因为学长进行的是个人的敏捷开发,因此直接使用Ruby on Rails框架的MVC设计模式进行设计,为了方便团队开发与任务分配而对整个项目进行重构时间比较紧张,我后来自己尝试了使用Vue.js作为前端、以Django作为后端,前端通过对后端的URL发起相应的请求来进行交互的方式进行前后端的分离)
- 实现:学习了使用Qt结合C++进行GUI程序的开发以及动态链接库的使用。学习了Vue.js前端框架、UI框架ElementUI(顺便学习了Vuetify.js等其他UI框架,因为使用方式大致相仿),进一步学习了Ruby on Rails
- 测试:学习了Rails单元测试的相关方法等
- 发布:发布阶段我主要负责了项目的部署,学习了使用Nginx进行反向代理,PostgreSQL数据库的部署和使用,以及对项目使用webpack进行预编译,开启gzip压缩等来提高服务器与浏览器之间数据传递的速度,缩减响应时间
- 维护:学习了阅读分析日志,以及数据库的管理等相关操作
收获与心得
我认为本学期给我带来最多收获的项目是团队项目,所以这里我想主要结合团队项目中的一些经历谈一下我的收获和心得。
为保证团队项目的顺利进行,多进行有效的沟通是非常必要的。这一点也是在团队项目开始时我们采访的学长给我们的建议,我们实际的团队开发也验证了这一点。我们在团队项目阶段基本上能够保证每天都开一次组会(即便不是在Scrum阶段仍然能够保证,偶尔会有一天休整)。这样,一方面方便PM的同学及时了解进度,如果哪里出现了问题或者遇到了困难能够至少以天为单位进行及时的调整,另一方面,组会也能对团队中的成员起到督促作用,防止出现怠工的现象。
团队项目需要由每一位成员共同参与,团队的管理者应当在保证项目进度的前提下让每一位成员都能够发挥自己的作用。一个人的力量是有限的,在一个团队中,学习背景和开发经历不同的同学汇集在一起,一个团队中有可能会有一些对相关技术比较熟悉的同学,同时也会有不太熟悉相关技术的同学。我认为一个团队的管理者应当促进整个团队的均衡化发展,在一个团队中不应当出现掉队的同学。例如,可以安排相对有经验的同学进行一些技术讲解,类似于“与其给其他同学讲解不如直接自己来干”的想法是不对的。虽然短期来看,这样可以一定程度上保持团队项目的进度,但是从长远的角度来看,通过团队成员的相互帮助,团队成员水平差异不断缩小,有越来越多能够独当一面的团队成员的出现,这样能够在后期极大地发挥出整个团队的优势。团队项目不是一个人展现自己的地方,它属于整个团队,属于每一个成员。