软工个人总结
项目 | 内容 |
---|---|
所属课程:北航-2020-春-软件工程 | 博客园班级博客链接 |
作业要求 | 课程回顾与个人总结 |
我在这个课程的目标 | 提升在团队合作中开发“好软件”的能力 |
这个作业在哪个具体方面帮助我实现目标 | 学期末的回顾、反思与总结 |
第一次作业连接 | [敏捷软工个人博客]通读教材、提问与相关调研 |
一、对以前问题的回答
问题1:计算机领域的学习与依赖“调包”的关系?
在第一次作业中我写下了如下观点。
我大体上支持上述资料的观点。的确数学分析和大学物理中学习的很多证明方法和公式定理我已经忘却,但是数学分析给我带来不同且有效的分析问题的方法和看待问题的视角。就在教材《构建之法》第16章中,作者通过动量和加速度形象地描述了技术产品在不同发展时期所具有的趋势。对于思维方式的训练,怎么都是不嫌多的。所以我认为应该趁着大学时光好好学习基础课程和原理性的课程,这种机会不常有。
这一段论述讨论的对象是大学中学习的数理基础,以及数理基础型的“包”,例如numpy
。但是在经过alpha和beta两阶段的敏捷软工项目开发之后,我发现“包”的定义与刚才的讨论对象偏差很大。我们小组使用的前端方案为vue+js+elementUI
,后端方案为Rails+gitlab+ningx
。这些“包”中只有很小一部分是与数理相关的,而大部分都为具体功能的实现。我在学习这些“包”的时候,发现大多数时间都花费在学习如何使用,而原理、实现等却很少涉及。
我想,我的学习经历也与一些软件工程师的学习经历相似,也能很容易地理解为什么软件工程师们将自己戏称为“调包侠”。这种学习方式实属无奈之举,因为项目的进度是最重要的,而新加入的“包”如何使用又内容繁多需要花费大量时间学习。但只是将“包”当作黑盒看待,会极大的限制软件工程师对bug的处理能力和对性能的追求。而对“包”原理的理解又能加深软件工程师对项目方式的理解,从而提高推进项目的效率和质量以及学习类似技术的速度。
综上所述,我认为软件工程师对“包”背后原理的学习十分必要。但是软件工程师又面临项目进度的压力,这时候该怎么办呢?我得出的经验是三四三时间分配,即“三分学习、四分构建、三分交流”。三分学习指的是在每天的构建工作开始之前不妨阅读一些文档、“包”的源码或其他学习资料,从而加深对项目的理解。四分构建是指每个工作日花费大约40%的精力进行写代码、写文档等推进项目进度的工作。而三分交流是指将一天中最后30%的时间花在代码review、组会等事务上,从而达成较好的协作效果。
这个经验仍然十分粗糙,主要有三个问题。
- 公司是否会允许工程师每天花费时间在学习原理上,并且时间并无直接产出。
- 三四三的时间分配是否合理,不同的工作环境和项目要求应该会对应不同的时间分配比例。
- 学习+构建+交流是否是软件工程师工作的全部,是否有其他必要工作没有考虑。
虽然这个经验十分不完善,但这是现阶段我所能给出的最好答案。
问题2:软件设计原则如何在实践中应用?
在两阶段的开发经历后,我对如何掌握软件设计原则有了自己的认识,即“实践 + 反思”。诸多软件设计原则十分抽象,它们是在软件工程中自然提炼而出的,是软件工程的普遍规律。对于愚笨的我来说,只依靠软件设计原则的定义和示例并不能构建出“好”软件。
软件设计原则是在多人合作的软件工程实践中总结出的,需要在实践中才能得到更深的理解。以开放-封闭原则和单一职责原则为例,在经历过需求变一变,重构火葬场之后,我产生了自己的理解。开放-封闭原则和单一职责原则的目的都是让软件拥有更强的可拓展性,也即在需求变更时尽量不修改已有源码。在这方面操作系统是一个很好的例子,系统调用能够应对各种各样的应用场景,但系统调本身却又不常改变。我认为其根本原因是参数化、模块化和组合:一个模块提供的接口应尽量参数化从而具有灵活性,而构建复杂模块的较好方式为用功能简单的模块组装而成。
就像乐高积木一般,只需要提供少许特化的积木和几种通用的积木就能拼装出无限可能的形状。其原因在于乐高积木本身接口的灵活性及单个积木足够的单一职责。软件工程亦是如此,许多接口灵活的简单模块能够拼接出复杂的模块。
例如在此次软工项目中,我们需要实现一个多评测机的功能。很自然的设计选择为先设计好评测机、评测点、分数计算等模块,再将这些模块进行组装。在添加展示评测机的功能中,只需要使用评测机模块;而在添加评测点功能中,需要组合评测机、评测点、分数技术三大模块;在提交评测功能中,同样需要组合三大模块。实现每一个功能都只使用底层模块的一部分接口,而底层模块并不需要改动。这个过程中体现出的就是开放-封闭原则和单一职责原则。
问题3:为什么有这么多PM?
在《构建之法》第九章,P185,出现了Program 和 Project Manager之间的对比表格。
Project Manager Program Manager 是团队的行政领导,带领大家在项目中工作。 和大家平等工作,推动团队完成软件的功能。 通常是团队和外界打交道的唯一代表。 一个团队可以有多个PM 对项目的功能有最后的决定权 带领团队成员一起形成决议 管事也管人 管事不管人 不一定做具体工作 一定做具体工作
我的理解是团队成员的职能分配取决于团队所处的环境。环境具体指:市场环境、公司环境、产品特性等。根据作业1博客中的论述,Project Manager偏重于需求分析、市场分析和行政领导,而Program Manager则偏重于技术领导、项目管理。
这两种PM都有其合理性,Project Manager是中国互联网公司的一般选择,这与中国市场环境息息相关。中国互联网市场成熟度还很低,很多产品的成功依赖于“先发优势”。这表明软件团队成功与否的关键在于软件是否契合市场需求,以及能不能发掘出新的需求。这并不是在论述中国互联网市场环境下软件质量不重要,而是在论述为什么中国互联网公司以Project Manager作为普遍选择。竞争无处不在,良好的软件质量是用户留存的关键。
Program Manager是微软的选择,这也正符合微软项目的特点。微软的项目中有相当部分为内部项目,用户群体为微软公司的其他员工。这使得项目需求明确,质量要求高,从而使得软件团队需要将工作重点落在技术上,落在项目完成的质量上。另一方面,微软面向普通群众的项目,例如office系列软件,也对软件质量有着很高的要求。
综上所述,软件团队所处的环境对自身有着很强的塑造力,PM所扮演的角色也会被塑造。
该问题答案主要来源于小组讨论。
问题4:为何一些闭源的项目最终会开源?开源的魅力到底在哪里?
在作业1的博客中通过查询资料给出答案:”开源项目的意义能够被表述为可控、教育、安全和稳定“。这个答案我认为已经十分完整,结合两阶段的敏捷软工开发经验,我对开源项目所具有的教育功能深有感触。在两阶段开发过程中,阅读各种开源代码能极大地解决在项目开发中产生的疑问。不论是“包”的源代码,还是其他项目类似功能的实现,都对我很有启发。
问题5:技术发展周期下的创新?
作业1的博客中对创新进行了讨论,但是细读《构建之法》第16章,教材的指向应该更偏向于敏捷软工团队对技术发展的认识和态度。软件工程领域的特性是技术导向型强,新技术对市场具有较强的引导作用。软工团队需要根据自身特征决定相关技术的选用。
教科书上关于该方面的内容十分抽象,关于团队具体如何面对技术创新的内容存在缺失,这让入门者丈二和尚摸不着头脑。教材中澄清了诸多关于创新的误区,但关于创新的正面细节描写十分稀少。或许这是因为创新本来的性质,难以预测、捉摸不透。另一方面,创新本就是动态过程,在短暂的两个开发阶段中难以有深刻的体会,或许十年后我能给出自己的答案。
二、产生的新问题
- 新项目建立时如何确定学习的优先级?新项目建立时,大量的新知识被摆在面前等待学习。但是人的精力是有限的,再加上对新项目的不了解,很难确定按照何种顺序学习新知识。那么如何科学地选则新知识的学习路径呢?
- 项目进行中很难进行真正意义上的压力测试,那么怎样才能科学地确定项目上线时正常运行所需的软硬件资源呢?
三、敏捷软工课程中学到的知识点
- 需求
- 典型用户与典型场景分析
- 典型用户和典型场景分析可以作为功能具体形态和功能整合的依据。在组会时我们经常就如何整合功能发生意见分析,这时候祭出典型场景分析一般能够解决问题。
- 设计
- 功能驱动的设计
- 构建总体模型→构造功能列表→制定开发计划→功能设计阶段→实现具体功能。这个过程对我们小组的软件设计过程很有启发,我们小组直接继承前人的项目,总体模型和构造功能列表已经由前任完成。我们实际上开发的过程为:构造新增功能列表→制定开发计划→小组自行决定功能的设计与实现。因为我们是线上工作,又是新人团队,团队合作没有那么紧凑,所以将很多团队活动下放到小组。
- 实现
- 成熟项目下的多小组并发
- 在《构建之法》中提到了代码管理的问题,在我们小组中代码管理比较松散,只要保证不出现同时签入的情况即可。这是因为我们的项目继承自学长,而学长的设计符合开闭原则和单一职责原则。这使得不同小组在开发不同功能时很少修改相同的文件,从而很少遇见合并冲突的情况。我们小组采用多小组并发开发的形式,即加快了项目进度,由使组员的开发时间更加自由。
- 测试
- 基于典型场景的测试用例
- 在回归测试等自动化测试的基础上,基于典型场景的人工测试覆盖面更广,也更灵活。自动化测试很难对项目进行整体性的测试,功能整合情况和用户使用体验难以用自动化测试表示。在基于典型场景的测试用例下,我们能够在组会上提出更多关于功能整合和用户体验的议题,从而使测试也能对项目的方向有所反馈。
- 发布
- 降低用户的入门成本
- 在alpha阶段的发布时,我们遇到了用户因为复杂的入门操作而放弃使用的问题。alpha版本中,用户入门的流程为:注册账户→加入班级→提交个人项目和结对项目代码→加入团队→提交团队代码。在beta版本中,我们放出了试用账号,用户登陆账号即可体验项目的核心功能(issue、博客、任务进度等),从而减小了用户入门成本,能够向用户展示我们的杀手功能。
- 维护
- 用户反馈
- 项目上线后,用户反馈能让团队认识到自身的思维误区和盲区及体现出用户更加真实的需求,从而推动团队在下一次迭代中做出更好的设计。
- 出现重大bug应及时修复,小bug集中在下一版本修复。
四、个人理解和心得
- 个人项目
- 个人项目有对于性能和可扩展性的要求,但是当时并没有对可扩展性有很好的认识,所以将大部分精力放在了性能上,可扩展性则简单地由几何对象的继承类表示。但是,现在看来,类的继承对于软件的可拓展性远远不够,候续新功能的添加导致源代码的大量重构。
- 结对项目
- 结对编程的方式十分新颖,的确能够在结对过程中有更清晰的思路,更快地解决问题。但是结对编程受限于双方的时间安排,使编程的灵活性收到限制。结对过程中我们意识到结对编程适用于关键代码的开发,而独立性强、模块性强、 关键性低的代码则更适合个人开发签入review的形式。
- 团队项目
- 我们团队人数为7人,合作时间为3个月。说实话,这样长时间、大规模的团队协作我是首次体验。我所感受到的最大不同是团队任务不止编码,文档、展示等与外界交流的任务同样十分重要。PM(或其他团队项目进度的把控者)在团队中尤为重要,他们需要考虑到团队整体情况。对于一般的组员来说,由于PM把控着项目整体进度,他们能够把更多精力投入到所负责任务的开发上。
- 我们小组采用多小组并行式开发,7个人分为3-4个开发小组,分别负责不同的功能。小组在做中学,开发过程中逐渐掌握了新语言、 新框架,对项目整体有所了解。在beta阶段几乎每一位小组成员都达到了全栈水平,能够独立负责新功能的开发。
- 除了技术上的学习,我也学会了与团队成员的沟通协作,并收获了十分宝贵的团队协作经历。在项目进度推进的过程中,我与团队成员之间逐渐结成朋友关系,并能够在学习生活等方面互帮互助。
- 总之,不论是能力培养、技术锻炼还是团队经历,这次敏捷软工的团队项目开发经历都对我十分宝贵。