软工-提问回顾与个人总结

提问回顾与个人总结

项目 内容
这个作业属于哪个课程 2020春北航计算机学院软件工程(罗杰 任健)
这个作业的要求在哪里 提问回顾与个人总结
我在这个课程的目标是 学习软件工程知识,并进行实践。
这个作业在哪个具体方面帮助我实现目标 回顾学期初提出的问题,总结本学期的软件开发经验。

1. 以前提出的问题

软件工程 - 个人博客作业

2. 尝试解答

  1. 在第二章中,作者提到:

    单元测试必须由最熟悉代码的人(程序的作者)来写。

    的确,代码的原编写者最为理解代码的功能、结构,让他(们)来写单元测试是最稳妥的选择。在Wikipedia中对Unit Test有说明:

    During development, a software developer may code criteria, or results that are known to be good, into the test to verify the unit's correctness. During test case execution, frameworks log tests that fail any criterion and report them in a summary.

    单元测试可以测试出软件的bug。然而,如果原程序员已经不再负责某个软件的维护,而这一软件又出现了原单元测试无法检测到的bug,那么是否只能由其他程序员来位这一软件的问题组件重新编写单元测试呢?在这种情况下,有什么好的方法来确保写出合适的Unit Test呢?

    答:经过这一个学期软件工程的实践,我认识到Unit Test可以在编写代码的时候,同步进行。完成一个部分代码的编写,即可同时编写对应的单元测试部分。那么,在程序员更换之后,只要我们仍旧保持同样的代码习惯,那么就可以保证代码质量足够高,单元测试覆盖率足够广。

  2. 在第二章38页提到:

    软件设计原则……软件实体允许拓展……不允许修改……

    软件实体可以拓展的同时,是不可更改的。这里的“不可更改”是指哪种程度上的不可更改呢?是原模块的代码一字不能动,还是说可以在不改变模块接口的情况下适当改动?恰当地使用设计模式可以提高代码的可维护性和可扩展性,然而在某些特殊情况下是否允许改变原来的设计模式以适应新的需求?

    答:在继续查阅资料后,笔者了解到,软件开发的理论指导实践,要求我们遵循包括面向对象(Objects Oriented)的设计原则、面向组件(Components Oriented)的设计原则等。在这其中,面向对象原则又包含开闭原则,指的是“软件实体应当对拓展开放,对修改关闭”。这一开闭原则(Open Closed Principle, CCP)告诉我们,对于组件功能的拓展是开放的(而且很多时候是有必要的),所以我们被允许拓展功能;而对原本代码的修改是封闭的,即不应该修改原来的代码。为了达到在不修改原有代码的基础上进行功能的扩展,我们要用到抽象化设计的概念,比如在Java, C++中,为系统定义一个抽象的层次,使得不同的实现分配到不同的实现层,利用接口、抽象类等机制,来实现所需要求。

  3. 在第三章53页,作者写道:

    问题——过早优化:……在局部问题上陷进去,花大量时间进行优化……

    所言极是,在笔者有限的程序开发经验中,的确碰到过“聪明反被聪明误”的陷阱。有时花很多时间完成一个局部模块的优化,但是却没有达到想象中的巨大效果,甚至在增加新功能时拖了后腿。但是,的确在很多情况下,局部优化是有必要的,那么,怎么平衡就局部优化和整体优化呢?

    答:对程序的优化主要有算法优化、代码优化、指令优化等方面。在这些优化中,算法优化带来的效益是最大的。有时一个\(O(n^3)\) 的算法,只需要稍微思考,就能优化到\(O(n)\) 。这样的的优化效益是巨大的,我们在编写代码的时候就应该要优先考虑。而有一些局部优化如代码优化有时候是累赘的,甚至编译器已经帮我们实现了。比如Java对switch 语句有优化,在编译过程中实现跳转表,效率高于if-else语句。而笔者曾想通过手动实现跳转表优化性能,这就是无用功。总而言之,开发者要平衡局部优化的效益与时间精力支出,达到全局最优化。

  4. 在第五章103页,有提到:

    温斯顿还指出,用户的及早介入、讨论、复审时很重要的。要让顾客正式地、深入地、持续地参与到项目中来。

    确实,客户的意见对软件的开发必不可少,但是真的有必要让客户深入地、持续地参与到项目中吗?我们知道,在实际工作中经常出现甲乙方直接的矛盾冲突,大部分都是甲乙方对对方领域没有深入的理解和交流。那么在这种情况下,客户的参与是否应该被限制在一定程度之内呢?

    答:在这个学期的实践中,开发团队没有让实际的“客户”参与到开发中。软件的需求、方向,由PM、核心的开发人员进行确定。在一个小型软件的开发过程中,这样的作法是高效的,最大限度减少与客户交流带来的时间成本。但是在复杂的软件开发过程中,可能会遇到更多与客户需求息息相关的问题,那么可能需要与客户进行更多的交流,确保软件在交接时符合对方的需求。

  5. 在第八章173页,作者认为:

    软件需求有必要需求辅助需求。功能有杀手功能外围功能

    毫无疑问,外围功能即良好的UI,平台之间的可移植性。而杀手功能时最核心的技术。但是,外围功能真的“外围”吗?随着用户审美的提高,对软件的界面设计的要求也水涨船高。在大家的核心功能做水准相近的情况下。外围功能也看成为核心竞争力,作为吸引客户的重要因素。

    答:在与助教交流、并进行实践后,笔者认为,在现代软件开发过程中,杀手功能的有无至关重要。在开发过程中,开发团队会把大量精力投入到核心功能的开发中。比如,本团队开发软件课程平台,评测机是我们的杀手功能,所以很多精力会花在如何优化这一功能上。但是与此同时,客户可能看到UI界面与最开始没有什么变化,那么第一印象就会认为团队工作量不大或看不到团队的其他付出。所以外围功能的完善也是十分重要的,是提升用户体验、提高用户黏性的重要一环。

3. 新的疑问

​ 在经过本学期的强制换人过程后,我对软件工程课程要求必须换人产生了疑惑。我们原本的团队所有人都掌握了这一软件开发需要的技术栈,并且没有人主动退出、跟不上团队节奏等。而我们的工程需要Ruby on Rails, JavaScript, Haml, Vue等大量新技术,在强制换人以后,新进来的同学花费大量时间学习新技术,对我们团队整体的进展没有正面的影响。另外,本团队的工程在搭建环境上需要花费很多功夫,即使有我们旧成员的帮助,新同学仍花费了2~3天搭建能正常使用的环境。这并不是新成员的问题,而是我们工程的特性决定的。那么,这一换人要求,对我们学习软件工程和实践,除了认识到现实的“残酷性”还有其他帮助吗?这是笔者在一个学期的实践后发现的疑问。

4. 知识点

  1. 需求
    • 需求分析是软件开发项目成败的重要因素。
    • 在进行需求调研、分析完善需求过程中,我们可以使用NABCD分析法(Need、Approach、Benefit、Competitor 和 Delivery)全面分析客户的需求。
  2. 设计
    • 软件设计要考虑到扩展性、健壮性、可用性、安全性、模块化等要素。
    • 软件设计要完成设计文档,用软件设计满足所以的需求,指定对应的模块。
    • 软件设计要遵循面向对象(OOD)的原则,实现抽象、信息隐藏、模块化。
  3. 实现
    • 开发过程中做好版本管理工作,使用Git维护分支
    • 将issue和commit进行关联,方便问题追踪
  4. 测试
    • 编写Unit Test 进行单元测试
    • 网页(前端)测试功能,检查数据库一致性
  5. 发布
    • 邀请用户测试软件,找到潜在的bug进行修复
    • 发现不足,在下一阶段进行维护
  6. 维护阶段
    • 收集用户反馈,持续进行维护

5. 理解或心得

个人项目

个人项目中,笔者体会到了单凭个人,完成一个没有任何bug的软件的同时,还要提升软件性能,是一项有挑战性的任务。同时在实践中,也锻炼了自己分析问题、进行实现的能力。

结对编程

结对编程中,笔者与队友交换主笔,另一方监察对方的编程错误,提出适当的建议,很少发生争吵,进展顺利。

通过结对编程,我认识到它有如下优缺点:

优点:

  1. 适合知识的分享传递,如一方对某一知识不甚清晰,那么另一方将迅速给予指导
  2. 有助于代码质量的提升,一旦发现bug,很容易被另一方指出
  3. 因为与结对者有约定,提高了编码动力

缺点:

  1. 当两方水平相近,特别是接受的教育都相同,那么很少出现知识的交流,因为两人知识圈几乎重合
  2. 对精力消耗极大,因为两人结对意味着同时都要高度集中注意力,进行长时间开发
  3. 结对编程不意味着bug的完全消失。虽然看的人对代码有一定程度的审核,但是由于两人的思维存在趋同性,仍然导致bug的产生

总的来说,结对编程要求程序员清晰的解析每一行代码的含义,不让开发者“浑水摸鱼”,但是这样的目的也可以由代码复审来完成,还同时避免了两个人长时间思考同一问题导致的严重疲劳。所以,看情况来说,结对编程不一定是开发的最优解,要根据实际状况决定开发方式。

团队编程

团队编程中,我们实际参与了小型团队(7人)的软件开发过程,了解了软件开发的全部流程,对我们今后生产实践起到了很好的指导作用。

在起始阶段,锻炼了我们的快速自学能力。本工程使用Ruby on Rails, JavaScript, Haml, Vue等技术,学习时间周期较长,所以在软件管理上,我们将队伍分配为前后端两个小分队,学习和实现不同部分的工作,最大限度尽快上手。在熟悉各自部分之后,又继续学习另一部分的知识,做到“全栈”的开发。

团队编程锻炼了我们进行代码版本管理的习惯,如合理使用Git 和GitHub,维护代码的干净整洁。

在这一过程中,也使笔者养成了编写代码注释的习惯,这有助于以后的代码维护、以及代码审核等工作。

更重要的是,锻炼了我们团队合作的能力。如何与团队成员进行交流讨论、分配工作、携手并进、克服困难,是我们这段时间的重要课题。经过这一个学期的锻炼,我们感受到了软件工程在软件开发中的重要性,如何确保软件质量,进行快速高效的敏捷开发,带着这些问题进行实践,也使我们获得了新的知识和经验,学习了更多优秀的思想。

你可能感兴趣的:(软工-提问回顾与个人总结)