链接到以前提问题的博客
- 在之前的博客我曾经提问过以下几个问题
为什么单元测试必须由写程序的人完成?
过早优化,过早泛华:何时为过早?
为何使用goto语句?
用户需求分析:分而治之,如何分?
兼容性测试和配置测试,易用性测试与可访问性测试的区别
请尝试对自己曾经提出的问题进行解答,并阐明,是如何通过看书,实践,或者讨论弄清楚的。
为什么单元测试必须由写程序的人完成?
在经历过本学期的个人项目作业,结对项目作业,团队项目作业后,我认为我对这个问题有了一个比较清晰的答案。
为什么单元测试必须由本人写?我觉得主要有几个原因:
- 首先,在敏捷开发环节,需要在很短的时间内完成一个工作量并不小的项目,每个人都需要耗费大量的时间在自己的设计以及coding上,并没有多余的时间去顾其他人到底有没有写bug
- 自己写的程序只有自己才能在短时间内根据自己的程序结构,设计出比较好的单元测试方式,并且只有自己才能最快的完成单元测试
至于之前在提问博客中提到的程序作者往往太熟悉自己的逻辑结构,在进行测试数据构造时往往会构造一些自己熟悉的数据类型,而作者一些难以想到的数据类型,往往就是自己程序忽略处理的数据类型这个问题,我觉得完全可以由非程序作者提出一些测试的方案(比如测试人员),这些测试方案里可以包含一些“刁钻”的测试逻辑;但是具体的单元测试代码还是需要由完成程序的作者来完成。因为只有程序员才最了解自己的程序结构,他才了解怎样去实施这个测试方案最快且最合理。
过早优化,过早泛化:何时为过早?
教材中提过:一个工程师在写程序的时候,经常容易在某一个局部问题上陷进去,花大量时间对其进行优化,无视这个模块对全局的重要性,甚至还不知道这个“全局”是怎样的。在开学初的博客里我提出了这样的问题:什么时候才算是合适优化,扩大化/泛化的时候呢?在经历过一个学期的实践后,我心里大概也有了点答案。
首先在完成一个具有一定体量的工作时,肯定不能上来就直接码代码,肯定需要实现进行一定的模块设计:设计好模块的接口,设计好模块的功能,大致设计好模块要是用的算法怎么更好的实现,设计好模块之间的松耦合。在经过这样一系列的设计后,对模块能够有更清晰的认识,这样最终写出来的程序,包括各个模块,以及各个模块组合的总体,一般不会出现严重的效率过低,bug过多的问题(如果有,那么肯定是设计没做好)。因此只要设计过程下功夫,就并不会存在说写完全局却发现局部有问题需要重构设计的问题。
那么至于优化和泛化的最佳时机,个人觉得是在模块完成后进行第一次整合的时候。这个时候各个模块已经基本完善,单元测试也做的差不多了,进行第一次整合后也能比较清楚地了解到模块之间工作的效率以及一些问题。这个时候已经可以看到总体的一些问题了,这时再进行一系列优化就能很好的解决这些总体的问题。而如果早于这个时候进行优化,在模块设计时就进行优化,这样不能观察到这样优化后在总体工作的效果,等到进行总体整合时,可能会出现一些意想不到的模块不兼容的问题,甚至会发现模块的优化并没有带来任何的效果,做了无用功。
为何使用goto语句?
关于这个问题我认为在开学初我就已经有比较清晰的答案。当时博客完成后,助教也对我提出的这个问题感到了好奇,并且问我是否有更好的解决方法。我觉得可以这样解决:
- 对于有try-catch机制的面向对象语言
- 可以定义抽象的错误类
- 对代码块进行try,对不同的错误抛出不同的异常,在catch里统一进行处理
- 好处:代码结构清晰,易于读懂什么错误进行什么样的处理;try-catch机制是比较完善的错误处理机制,不仅能够处理程序员所定义的错误,还能处理程序员意想不到的一些错误
- 对于C语言
- 可以定义一套完善的错误码
- 在发生错误的地方返回特定的错误码
- 在调用栈顶部对返回的错误码集中进行处理:
- 使用switch-case机制
- 对于有相同处理方式的错误可以统一到同一程序流
- 避免使用goto导致程序流混乱且不易读懂
兼容性测试和配置测试,易用性测试与可访问性测试区别
经过一学期的团队项目,经历过了两次项目的测试流程,我觉得可以对这几项测试有了比较清晰的认识:
- 兼容性测试:个人认为是在软件更新迭代过程中,老版本的用户数据是否能够跟新版本的用户数据相互兼容,使用老版本是否还能够正常使用老版本的功能;更新到新版本后和之前的系统是否仍然兼容
- 配置测试:软件在各个系统,各个平台上运行是否能够正常运行,如果不行,是否需要进行一定的预配置
- 可访问性测试:是否向残疾用户(这里的残疾也可以指对这方面不熟悉的人,配置存在缺陷的用户)提供一定的辅助性功能,包括便于操作性等;或者对于系统平台等级较低的用户,是否能够访问到部分资源并且进行有效操作
- 易用性测试:是否对普通用户提供一定的用户帮助,帮助用户更快上手,以及便于使用。
是否原来的问题还不明白?如果有,请分析。
用户需求分析:分而治之,如何分?
在学期初我曾对WBS模型如何分治提出疑问,当时认为使用E-R图更可以说明。现在我对这个问题有了更新的疑问。WBS分治模型是基于用户需求以及功能来进行分治的,但是一个功能并不代表一项任务,一个功能是需要多个任务完成,如果仅靠WBS模型分析用户需求进而直接进行团队分工我认为是远远不够的,团队分工不能仅仅停留于功能上,功能并不能完全说明整个任务。因此我们在团队项目分工时,一般没有做具体的分工,而是让每个团队成员各自去对自己的任务进行拆解。因此是否有比WBS模型更好的团队分工模型呢,或者说有没有一个方法,在进行WBS模型分析完用户需求后,对用户需求进行更好的拆解,拆解成各个任务提供给团队成员去完成呢。
是否产生了新的问题?如果有,请提出。
关于PM制度,是否可以划分出多个PM呢,比如一个主PM,一个副PM
对于团队项目环节,大多数团队的PM大部分情况都是在忙于组织成员,组织会议,撰写博客,实际开发工作量很少。但是如果开发工作完成的少,就不能够完全认识到开发的困难性以及工作量,在这方面的衡量就会出现偏差,导致PM决策失误。因此能否划分出多个PM,一方面可以为PM分担部分压力,不至于所有组织工作都集中于一人身上;其次可以让PM融入到开发,测试环节中,了解团队在开发过程中的具体进展以及一些困难,以作出更好的决策。
软件工程这门学问有很多 “知识点”, 这门课强调 “做中学” - 在实践中学习知识点
请问你们在项目的 需求/设计/实现/测试/发布/维护阶段(一共6 个阶段)中都学到了什么“知识点”,每个阶段只要说明一个知识点即可。
- 需求阶段:
- 明白了如何去分析用户需求,如何从一个用户场景具体抽象为一个个要实现的功能(WBS模型分析)
- 了解了用户需求分析不能仅仅停留于团队内部成员,还应该去具体了解真正的用户的真正的想法
- 设计阶段:
- 了解了一些设计的手段,比如通过原型设计,一步步勾勒出产品的原型,一步步推导出要实现的各项功能
- 了解了如何从设计进一步分配到各个开发人员去完成各项功能:
- 从功能角度出发,给每个成员分配一些要完成的功能
- 从前后端出发,分为前端,后端,中间人
- 任务具体划分交由成员自己实现
- 实现阶段:
- 学习了很多Web端的前后端开发知识,包括前端框架,组件库,后端框架
- 学习了很多Web技术栈,包括前端cdn优化,后端负载均衡等
- 对于复杂项目的抽象化,松耦合有了进一步的理解。学会了在开发过程撰写文档
- 测试:
- 了解了很多单元测试框架(Web端)
- 学会了如何从用户场景出发,进行测试,以真实的模拟用户使用的真实情况
- 学会了如何通过罗列测试矩阵,实现在各个平台进行比较完备的测试
- 发布:
- 学会去宣传,去采访用户,获取用户反馈
- 知道怎么从用户反馈出发,进一步改善项目
- 维护:
- 知道怎么去管理用户提出的各种bug,怎么去快速的修复各项bug以保证用户使用的良好体验。
结合自己在个人项目/结对编程/团队项目的经历,谈谈自己的理解或心得。
个人项目
个人项目时候是比较忙碌的时候,因此当时个人项目完成的比较仓促,在算法设计层面,以及最终生成程序执行效率上都出现了比较大的失误。
在算法设计上,由于过度考虑到正确性要求,执意使用有理数去完成设计。但其实有理数的设计虽然能在一定程度上保证正确性,但是会造成算法复杂,导致最终在执行效率上显得十分逊色。并且其实这道题目并不需要有理数的设计,由于输入的数据有一定的约束,因此如果直接使用double类型完成题目,只要在数据范围上,只要对精度做一定的约束,就能够保证正确性。并且使用double可以将大部分的运算进行简化,避免复杂度过高导致算法效率降低。因此这是重大失误之一。
在生成程序质量上,由于对Visual studio并不熟悉,直接使用debug模式下生成的exe文件作为最终提交的文件,导致在执行时间上是大部分人的近10倍。在后续作业里吸取了教训,使用release模式生成最终文件,效率上得到了很大的提升。
在个人项目里,我第一次将单元测试这一要求贯彻到底,完成一个模块后一定要对整个模块尽可能做较高的覆盖率的单元测试,减少bug的出现
结对项目
结对项目第一次体验到了结对编程模式。在结对编程里,我和我的小伙伴看同一份代码,一个人写,一个人复审,互相提出修改意见。在结对编程项目过程中,我们体会到了结对编程的魅力,了解了怎么在结对编程中两位成员共同做好设计,实现,测试等步骤。结对编程不仅让我们每个人写的代码质量更高,并且在设计阶段,两个人共同进行的设计能够拥有更高的可靠性。结对编程里我们也体验到了代码复审的重要性,体会到多个人复审过的代码出现bug几率更低的真相,同时我们也将在结对编程里的代码复审环节应用到了后续的团队项目里。
团队项目
在团队项目阶段,我真正的学习到了如何开发一个复杂项目的一整套流程,如何有规范有效率的去编写代码,而不是即想即写,写完就丢的小程序。
首先是团队会议。每天一次的团队会议确实对团队项目进展有很大的帮助。他不仅能够加强团队成员之间的交流,了解每个人的工作进度,为对方提出bug解决方案或者是优化方案,相互学习,而且还增进了团队之间的友谊。6个人的团队从一开始都很陌生,慢慢的到后面会议次数多了,之前不怎么说话的组员也逐渐活跃起来,整个团队有了更高的凝聚力。
其次是整套开发流程。团队项目第一次让我学到了怎么去规划,去实施开发一个复杂系统。怎么去把一个个复杂的需求做一步步的分解,分解到一个个具体的功能,最终再分解为一个个具体的模块交由各个组员去做实际的开发。团队项目也锻炼了我们使用github的能力,怎么去利用github,去规范一套开发流程,使得在多人同时开发写作过程中,能够更高效率的去完成一个项目;学会了怎么使用PR高效的完成多人开发,解决并行开发的各种冲突问题。
最终是技术方面,团队项目也锻炼了我们每个人的技术栈。从一开始的对Web编程的不熟悉,慢慢地到逐渐去学习,去了解,去应用。在团队项目里,我单人的是中间人角色,前后端都有些许的涉猎。在团队项目里不仅锻炼了我后端使用nodejs框架构建后端服务器的能力,也锻炼了我前端如何使用Vue框架和iview组件库去设计一个前端页面,完善前端功能。