阅读和提问3 - 期中作业
习而学的软件工程教育
这篇博文所提倡的是一种新的软件工程教育方法,和我在本科阶段接受的教育经历密切相关,所以感受比较真切。
“习而学”的教育方法的优点:
我觉得大部分优点不是在博文中已经提及,就是非常显而易见的了。我在这里就简要的概括一下吧。
- 更加重视实践。"learn by doing" 的教育方式,让学生先做项目,再学习理论知识。能够有效地激发学生的学习兴趣,避免学生在枯燥的理论知识中丧失对学科的热情。另一方面,也加强了学生的实践能力,防止”精通理论,但是不会写代码“的情形。
- 理论知识更有侧重点,偏向应用。当学生经过实践后,就会明白自己理论知识的缺陷,以及需要哪些方面的理论知识(这个是理想情况下),从而学习理论知识的时候会更加高效。
我的本科教育与这篇博文提出的方法可谓是完全相反。学校非常重视所谓的”数理基础“,因此在低年级的时候几乎全都是数学,物理课。直到大二下学期才开始有正式的计算机专业课出现。我也听不少同学抱怨过不知道为什么要学那么多的数学物理课,甚至很多课在通过之后的实践,仍然不知道为什么要学,或者说对于计算机专业没有任何帮助,完全是学业上的要求。
那么,”习而学“的教育方案真的可以解决这些问题吗?
我觉得如果按照”习而学“的方案,学生很有可能就真的学不好理论了。文中所提倡的把数学物理课放到高年级去学,是比较不切实际的做法。因为高等物理,微积分,线性代数(这么重要的课竟然放到大四上,我也是服气)这些基础课程的重要性,绝对不是任何”实践“能够反映出来,更不用说让学生通过”实践“感受到了。举例来说,当低年级的专业课程结束,开始上一些高级的专业课时,比如计算机图形学,人工智能,计算机视觉或者其它的交叉学科的应用课程,其中涉及的到的数学基础是必备的。很难指望一个不会线性代数的同学能够听懂这些课程。再者,以我的亲身经历来看,在低年级的时候,同学们的学习积极性是比较高的,纪律也更好,这更加适合去学习较为枯燥的数学,物理课程。等到高年级的时候,同学们经过了很多动手实践,该实习的去实习了,该进实验室的进实验室了,谁还有心思一本正经的来学微积分,线性代数,普通物理?至于”方便考研同学“,这完全是 minor consideration,本科教育又不是为了考研准备,另外学了结果忘光了难到不是自己第一次就没有学好吗?
我不是很了解软件学院的教学方案,但是我觉得,这套方案完全照搬到计算机科学的教育上,是不行的。”习而学“的精神不应该如此牺牲基础课程的地位,而是应该在学好基础课程之后有所体现。我个人对我的本科学校的建议是,把绝大部分基础课程控制到1年之内上完,降低一些基础课程对工科学科的要求(现在还是太多了),从大二上开始就全面开设专业课程的教育。至于”习而学“,可以把这个思想放到每一门有实践的课程中去,让同学们在专业课中有所实践,能够做到这一点就非常好了。
第一流的本科教学课堂该是什么样?
这篇博客带着读者过了一遍美国本科的一门地质课程,真的非常精彩,能够有幸参与到这样的课堂真的让人羡慕。我记得从前第一次听说美国本科的同学说自己一学期选了4门课 loading 就非常重了,觉得十分不可思议,因为自己本科没有哪个学期不是6-7门课,低年级的时候8-9门课都是可能的。仅从这一点就窥见一斑本科课程质量的差距。
我这里最想说的是助教的角色。文中的助教是非常负责的角色,以学生学到东西为自己的责任,并且有提到无论助教多忙,都会非常乐意给学生解答问题。印象特别深的是作者有一题不会做,在助教讲解之后,竟然允许带回去重新做再交,真的不能再nice。
我本科阶段助教的最大角色还是作业批改的对象,input = 作业,output = 成绩,偶尔会有不定期的答疑,但是并不会很多人去参加,去参加也不会有很多人问问题。这其实也不能怪助教,因为课程或者老师对助教的要求就是如此,从这个角度来说,这样的助教已经尽到了职责。另一方面,还是人太多和助教工资太低的原因(恕我直言),导致助教人数非常短缺,一个助教批改几十个人的作业是普遍现象,以更高的要求来衡量助教的工作实在不公平,因此,对于国外这样的课堂,只是遥望在水一方的存在罢了。
但是仍然有不少可以改进的地方,尤其是像计算机学科的专业课程。首先,学院不能把这些专业课再和别的课一样对待了,让一个助教管几十个学生的情况发生。其次,助教要在这样的课程中担当起助教的角色,把教授只是作为自己的职责,在实验中把自己的经验教给低年级的同学们。比如非常具体的建议,布置实验的时候不要就讲一个要求,而是告诉同学们,你们可能会用到什么工具,应该用什么方法,如果是要求实现一个算法,那就要自己规定好输入输出,并且自己写好初步的测试框架,提供给同学们,这样他们只要实现算法就可以了,同时也可以学习怎样写测试框架,而不是上机的时候让同学自己演示一遍就算过。如果只是将一个实验要求,一行实例代码也没有,会让很多同学有畏惧感,非常不友好。我在coursera上过几门国外的计算机相关的课程,其中的实验都是这样布置的,很值得借鉴。
CS != SE ?
首先,很明显 CS != SE,Computer Science 正如它的名字,是关于 computer 的 science, 而 Software Engineering, 是关于 software 的 science,两者的 scope 就明显不同,肯定不是一回事。
其次,CS != SE 绝对不是老师不好好教这门课的理由。无论是做 CS 科研,还是进入工业界工作,SE 的学习都是非常有益的。对于科研工作者来说,SE 的学习不仅对自身代码管理有帮助,还可以了解工业界的流程和规则,对科研本身也很有帮助。另外,尽管科研中不需要 SE 中那么复杂的开发流程,但是多人合作还是非常常见的,SE 能够提供很好的团队合作的练习。因此,SE 是本科CS学习中很重要的一门课。
我本科的软件工程这门课就属于“老师不好好教”的类型。这门课从头到尾可以不用写代码,只需要学理论,然后写文档就可以。这导致这门课非常枯燥,大家也没有兴趣来认真学。老师也没有打算把自己开发软件的经验以实践的方式教给学生。另一方面,学院对软件工程这门课也不是很重视,从只有2.5学分就可以看出来(正常来说,一门重要的专业课是4个学分)。因此,同学们对这门课也不是很重视(现在都是什么课学分多,什么课就很重要)。如果一门2.5学分的课的loading超过了应有的份额,同学们也会对此不满意。
博客中间的建议很好,就是让有工业界经验的老师来教这门课,这样可以不再仅仅是教枯燥的理论了,而是传授经验,然后总结理论的方式,更易于教学和学习。另一方面,软件工程一定要实践,要以布置团队项目的方式来把软件工程的理论用起来才行,至于loading的问题,应该教给学院好好考虑。
The Cathedral and the Bazaar
大教堂与市集是一本很有影响力的描述软件工程方法的书。它主要描述了两种软件工程的方法:大教堂模式和市集模式。
大教堂模式: 原始代码是公开的,但是在软件的每次版本迭代过程是由一个封闭的专属团队负责。比如一开始的 GNU Emacs 和 GCC。
市集模式:原始代码也是公开的。但是软件的所有版本都是开源并且任何人都可以做出贡献。比如 Linux 和 Fetchmail。
作者认为代码公开的越多,公开的范围越广泛,bug被发现和解决的速度越快。因此,在大教堂模式中,团队需要花更多的时间来debug。
这本书影响力非常大,是的大部分的软件开发都使用了市集模式,甚至是原先使用大教堂模式的GNU Emacs 和 GCC 也使用了市集模式。
在软件工程课程中,我感觉很难说我们的开发模式是两者之一。因为一方面我们的软件是完全开源的(在github上),但是另一方面虽然理论上所有人都可以贡献代码,但是只有我们团队在负责版本的开发。不过从团队的内部分工来看,我们团队整体比较像大教堂模式,因为每个模块的功能都由专门负责的人开发,其他人不进行代码的审查和干涉。我觉得这个方案看起来对于小一点的工程(比如我们课程这样)还是不错的,由1-2个人组成的团队专门负责一块功能,这样可以保持每个小团队的敏捷性,同时在代码量不是很大的情况下,保证了debug的效率。不过这种方式有两个限制条件,一个是项目比较小,因为当项目比较大的时候,就很难让一两个人组成一个团队,也不能在保证效率的同时把大的项目细分到如此地步;另一个限制是要有一个了解整个项目的PM,负责整个的架构,分工和协调,对项目来说,PM的责任比较大,也比较依赖PM的能力。
在集市中迷失
这篇文章一阵见血的指出了疯狂的推广市集模式在实际应用中出现的若干弊端。一味的开源,主要导致了两个问题:1. 没有人专门负责一些代码的维护,导致代码的版本管理混乱,review工作不到位。2. 会使得代码不够精简,比如代码越重用,浪费越严重,或者是一个软件全身都是补丁的情况发生。
第一种情况,因为我没有参与过大型开源项目的开发,不能说切身体会到,但是在之前的课程作业中也有类似的经历。由于没有事先很明确的分工,导致几个组员在工作重叠的部分经常会有代码冲突的现象。同时,上一个人改了代码,下一个人没有认真读上一个人的 commit,就接着自己的思路往下写,导致了一些非常低效的情况发生。
第二种情况,在软件工程的课程项目中就发生了。我们开发网站的时候,用了太多别人造好的轮子,导致代码看起来异常臃肿,很多调用语句都不知道是用来干什么的,但是去掉又不行。这就导致我们在优化网站速度的时候无从下手。后来我们决定重新写,能不用轮子就不用,遇到需要的简单模块就自己实现一下,这样代码的可读性也提高了。
市集还是教堂,敏捷还是规范,其实都要在各个不同的项目,不同团队中取得平衡,这篇文章的评论下面也有人指出,其实是有些片面的。因此,在团队项目中要多停下来思考,当前的开发模式是不是合适的,应该向哪个方向修改。