现代软件工程 习而学的软件工程教育
茅于轼先生写了一篇博客 ( 链接1 链接2 ) 纪念茅以升先生提出的 习而学的工程教育:
把颠倒了的工程教育顺序恢复过来,即他称之谓“习而学的工程教育”。
以桥梁建筑专业为例,大学一年级先学施工条例,二年级则学设计规范。这些学习内容不必解释条例和规范的理论基础,只说明其内在的联系。到三年级可以学结构力学,四年级则学微积分、线性代数、概率论和普通物理。但桥梁专业的微积分和物理学可以不同于机械系的,它们各有侧重点,有各自的例题和习题。学生越是到高年级,越是明白自己在低年级所学的道理,也就明白还有哪些道理至今在科学上还没有办法解释。于是学习成为一个自然的延续过程,成为一种终身的事业:活到老、学到老。
从我个人的学习和教学经历来看, 我认为给学生具体的, 能实践的, 能马上看到因果关系的教材和练习, 是激发学生兴趣和求知欲的好方法。 我就是这样学习编程和软件开发的 (见下面的注解 三文鱼模型)。 所以我对 “习而学”的方法很有好感。软件工程有理论的部分, 有工程的部分; 有艺术的部分,还有手艺的部分; 在同学们达到理论/艺术的阶段之前, 大量的练习是必须的。
大家不妨看看这个陶艺课的故事,把学生分成两组,一组以出产的陶罐的量来评分,一组不要求数量, 纯粹以质评分。一个学期后,真正好的陶艺作品反而是出现在那以量评分的组里。各种道理值得大家思考。
抽象的理论和推导, 不是不能学, 但是我在学习和教学的过程中, 总是有 “学这些抽象的理论到底是为什么? ” 的疑问。 有些学生非常喜欢理论, 或者有些学生能克服自己的厌恶情绪, 把理论和推导学好, 记牢, 至少到考试结束前, 像下面这个图那样。 这些学生的考试成绩很好, 理论基础也很扎实, 也许能在广阔的 IT 行业找到自己的发展道路 (希望如此!)。
对于工程类的学科来说, 教导学生理论本身并非终点,引导学生将所学技能自如运用于现实世界才是我们的目标。 那怎么引导呢? 大学老师们关心此事么?
最近软件工程这一门学问在中国提升到了 “一级学科”, 我想起几年前去某大学开会, 某软件学院的老教授对大家说, 他一直在忙“一级学科” 的事儿, 大家问此事为何如此重要。 他说, 如果搞到一级学科, 他的博士生们答辩就不用去计算机系, 不用穿别人给的*鞋了! 我当时似懂非懂。 其实这事不光计算机界有,我所尊敬的科学家韦钰老师在回忆她科研的经历时说: ...
中国这个问题是很严重的。我们建立第一个学科的时候,我遇到了很大的困难。这些困难都不是来自政治界的,而是来自学术界本身,来自学术界某些权威。有位权威就是不同意给我立题和资助,说“你怎么能研究这个,你怎么能进到我的领域来” ...
后来看到更多中国高校的情况, 其实大家都在争一个自己可以占山为王的地界罢了。 至于科学啊, 培养人才啊, 技术的浪潮啊, 社会的进步啊... 呵呵.
从我有限的了解来看, 大学的管理人员比较在乎自己的学校是哪个级别 (某部直属/211/985/...), 一些大陆的科学家比较在乎自己的学科是局级还是厅级, 我不知道世界级的科学家是否在乎自己的学科是一级、二级、还是三级, 我也有幸和一些世界级的计算机科学家接触过, 这个话题好像没人提起过。 作为一个写软件为生的工程师, 我倒是想实验一下, 如果我们用茅以升先生的 “习而学的工程教育”方法来改进软件学院的教育模式, 会有什么样的情况。
我用一个中国211大学的软件学院的本科教学计划为基础 (此大学以工科见长, 印象中此学校水*应该在中国大陆排十名左右), 做了如下修改:
- 把基础实践课放到大一, 一开始就要动手。不光是动手写程序, 还要动手写文章(请看学者薛涌 的 读写的重要性)。
- 所有的课程的上机时间都加倍, 相应减少授课时间。老师在讲台上反复讲 “数组从0开始…”,不如在电脑上试试。
- 把 <计算机新技术与产业发展> 放到大一上学期, 并用 <浪潮之巅>, 等反映行业变化, 生动活泼的著作作为教材 (原教学计划无教材)。 希望能让大一的同学知道 “学计算机软件能做什么?” “计算机行业是怎样一个有意思的行业”。
- 把基本的测试技术作为 “软件测试技术入门”, 放到大一。 其余的部分作为 <高级软件测试技术>
- 针对软件工程的毕业生职业发展, 调整了两门课程的 必修/选修性质。 (例如: 把 <形式化方法> 变为选修课, 把软件项目管理, 人机交互技术变成必修课 )
- 大部分数学和物理课都推迟一到两个学年上课, 这样到了大三同学们可以根据实践的体会, 更好地学习。 另外有同学在大三时决定考研, 他们正好可以好好学习高等代数, 争取考个好分数。如果是大一就学了, 那大四都忘了, 还要从头学一遍, 浪费时间。 离散数学对于计算机软件专业的学习还是很有用的, 仍然保持在第一学期。
- 专业选修课放到大二下学期 - 大四上学期。
- 在软件工程课中, 强调团队合作 (见讲义) , 在其它编程语言课程中适当引入结对编程, 代码复审等方法。 [注4]
- 对学生学习编程语言有明确代码量的要求, (每种语言 3000 行以上. 程序行数不包括空行, 注释行, 单字符行)。学生要学会用源代码管理工具,最好能参与一些社区项目。
- 对学生要有明确的实训/实习要求, 要到高水*的企业去, 而不是去低水*的企业混日子。 可以在短学期安排, 学生也可以自行安排。 [注3]
- 争取所有学生能用主流程序设计语言 (C, C++, Java, C#, 网页前端语言 JS, php, 基本数据库, 基本文件系统) 写实用的软件。
- 要求所有学生在入学时就建立一个自己的专业博客, 记载自己的作业, 专业上的成长与体会, 毕业找工作时展现这个博客即可。
- 教学资源的建设, 老师和学生一起, 持续地把关于这门课的课件/资料/问答 都汇集起来形成结构化的wiki.
表一是所有专业必修课的安排:
软件工程 习而学的教学计划 | 各学期周学时分配 | ||||||||||||||||||
一年级 | 二年级 | 三年级 | 四年级 | ||||||||||||||||
类别 | 名称 | 学分 | 总学时 | 授课 | 实验 | 上机 | 实践 | 学期安排 | 上 | 下 | 短 | 上 | 下 | 短 | 上 | 下 | 短 | 上 | 下 |
必 | 计算机导论 | 1.5 | 24 | 18 | 6 | 1 | 1.5 | ||||||||||||
必 | 数据结构 (C 语言) | 4 | 64 | 48 | 16 | 1 | 4 | ||||||||||||
必 | 计算机新技术与产业发展 | 1 | 16 | 16 | 1 | 1 | |||||||||||||
必 | 数字逻辑 | 2 | 40 | 24 | 16 | 1 | 2 | ||||||||||||
必 | C/C++ 程序设计 | 3.5 | 64 | 48 | 16 | 2 | 4 | ||||||||||||
必 | 汇编语言程序设计 | 2 | 32 | 16 | 16 | 2 | 2 | ||||||||||||
必 | 软件测试技术入门 | 1 | 16 | 8 | 8 | 2 | 1 | ||||||||||||
限选 | Java语言程序设计 | 2 | 32 | 16 | 16 | 2 | 2 | ||||||||||||
必 | C++ 高级程序设计 | 3 | 56 | 40 | 16 | 3 | 3 | ||||||||||||
必 | 计算机组成原理 | 4 | 64 | 52 | 12 | 3 | 4 | ||||||||||||
限选 | C# 与 .Net框架基础 | 2 | 32 | 16 | 16 | 3 | 2 | ||||||||||||
限选 | Web 前端技术开发 | 3 | 48 | 24 | 24 | 4 | 3 | ||||||||||||
必 | 操作系统实践 (基于 Linux) | 2 | 32 | 16 | 16 | 4 | 2 | ||||||||||||
限选 | 人机交互技术 | 2 | 32 | 16 | 16 | 4 | 2 | ||||||||||||
必 | 高级软件测试技术 | 2 | 32 | 16 | 16 | 4 | 2 | ||||||||||||
限选 | 移动*台应用开发 | 2 | 32 | 16 | 16 | 5 | 2 | ||||||||||||
必 | 数据库原理及应用 | 3 | 48 | 32 | 16 | 5 | 3 | ||||||||||||
必 | 计算机网络 | 3 | 48 | 32 | 16 | 5 | 3 | ||||||||||||
限选 | 算法分析 | 2 | 32 | 24 | 8 | 6 | 2 | ||||||||||||
必 | 软件工程 | 4 | 64 | 32 | 32 | 6 | 4 | ||||||||||||
必 | 信息安全技术 | 2 | 32 | 24 | 8 | 6 | 2 | ||||||||||||
必 | 操作系统原理 | 3 | 48 | 40 | 8 | 7 | 3 | ||||||||||||
必 | 编译原理 | 3 | 56 | 40 | 16 | 7 | 3 | ||||||||||||
必 | 高级软件工程 | 2 | 32 | 24 | 8 | 7 | 2 | ||||||||||||
必 | 毕业设计(论文或实际项目) | 12 | 16周 | 8 | 12 |
限选意味着学生必须在几门课中选择。
高级软件工程:学习内容包括, 软件体系架构,软件项目管理,软件运维,软件需求分析,等。学生作为一个技术领导带领低年级的学生(上软件工程)完成一个项目。
表二是专业选修课的安排 (大部分课程是学校提供的):
课程 | 学分 | 总学时 | 授课 | 实验 | 上机 | 实践 | 学期 | |
选 | 科技英语(英) | 1.5 | 24 | 16 | 8 | 4 | ||
选 | 计算机游戏设计 | 2 | 32 | 24 | 8 | 4 | ||
选 | 嵌入式程序设计 | 2 | 32 | 24 | 8 | 4 | ||
选 | 人工智能 | 2 | 32 | 24 | 8 | 5 | ||
选 | 计算机视觉 | 2 | 32 | 24 |
8 |
5 | ||
选 | 图像处理 | 2 | 32 | 24 | 8 | 5 | ||
选 | 自然语言处理 | 2 | 32 | 16 | 16 | 5 | ||
选 | 数据仓库与数据挖掘 | 2 | 32 | 24 | 8 | 6 | ||
选 | 虚拟化技术与云计算 | 1.5 | 32 | 16 | 16 | 6 | ||
选 | 地理信息系统导论 | 2 | 32 | 24 | 8 | 6 | ||
选 | 系统仿真与虚拟现实 | 2 | 32 | 24 | 8 | 6 | ||
选 | 形式化方法 | 2.5 | 40 | 40 | 7 | |||
选 | 计算机图形技术 | 2 | 32 | 24 | 8 | 7 | ||
选 | 并行计算 | 2 | 32 | 24 | 8 | 7 |
科技英语也要增加实践的内容, 学生为什么不能用学到的科技英语读论文,写摘要, 做翻译, 写博客, 做英语课件?
表三是数学物理课程的安排:
软件工程 习而学 教学安排 (数学物理) | 各学期周学时分配 | ||||||||||||||||||
一年级 | 二年级 | 三年级 | 四年级 | ||||||||||||||||
类别 | 名称 | 学分 | 总学时 | 授课 | 实验 | 上机 | 实践 | 学期安排 | 上 | 下 | 短 | 上 | 下 | 短 | 上 | 下 | 短 | 上 | 下 |
必 | 高等数学2A | 5 | 80 | 80 | 2 | 3 | |||||||||||||
必 | 高等数学2B | 6 | 96 | 96 | 3 | 3 | |||||||||||||
必 | 线性代数及其应用 | 3.5 | 56 | 56 | 3.5 | ||||||||||||||
必 | 离散数学导论1 | 3 | 48 | 48 | 3 | ||||||||||||||
必 | 概率论与数理统计1 | 3 | 48 | 48 | 3 | ||||||||||||||
必 | 大学物理2A-B | 7 | 112 | 112 | 4 | 3 | |||||||||||||
必 | 物理实验A | 1 | 27 | 3 | 24 | 1 | |||||||||||||
必 | 物理实验B | 1 | 27 | 27 | 1 |
不应该忽略的还有必须学习的各种政治思想课:
课程性质 | 课程名称 | 课程编号 | 学分 | 总学时 | 授课学时 | 实验学时 | 上机学时 | 实践学时 | 各学期周学时分配 | ||||||||||
第一学年 | 第二学年 | 第三学年 | 第四学年 | ||||||||||||||||
1 | 2 | 短 | 1 | 2 | 短 | 1 | 2 | 短 | 1 | 2 | |||||||||
16 | 352 | 311 | 41 | ||||||||||||||||
必 | 思想道德修养与法律基础 | 3 | 48 | 48 | 3 | ||||||||||||||
必 | 中国近现代史纲要 | 2 | 32 | 30 | 2 | 2 | |||||||||||||
必 | 马克思主义基本原理 | 3 | 48 | 48 | 3 | ||||||||||||||
必 | *.*.*思想、*.*.*理论与“三个代表”重要思想概论 | 6 | 96 | 57 | 39 | 3 | |||||||||||||
必 | 形势与政策教育 | 2 | 128 | 128 | 0.5 | 0.5 | 0.5 | 0.5 |
我对于政治思想课是外行, 唯一的建议是: 在上 <三个代表> 课程的时候, 要求学生针对校内的 IT 系统, 采访群众, 搞清楚下面的问题:
我校的信息服务系统是否代表了先进生产力的发展要求?
是否代表先进文化的前进方向?
是否代表我校广大师生的根本利益?
具体表现在哪里?
然后发表博客。
------------------------------------------------
注1:
“Learning by Doing” :
我以前接触过韦钰老师的 “做中学”/ “Learning by Doing” 理念, 虽然它强调的是儿童和少年时期的学习, 但是我想这种方法对于任何年龄的人都适用。
注2:
大马哈鱼洄游模型, 三文鱼模型 见博客:
注3:
有些人也许觉得这种方式太创新了, 其实加拿大的 滑铁卢大学 计算机系 早就在做类似的事情, 甚至更工业化, 更系统化。 他们计算机系的学生本科就是一年有三个学期, 一个学期 (4 个月) 的课程学习, 然后接着一个学期的工作 (Co-op, internship, 实习生), 我的一个同事就是这样完成本科教育 - 上了8个学期的课, 穿插了6 个学期的实习生工作。 官方介绍:
注4:
我们都知道要练习, 但是怎么练习? 这里有探讨: http://www.douban.com/note/260623954/
引文: 学习科学大量研究表明,成人的最佳学习方式并非独自练习,而是在情境中学习。有效学习是进入相关情景,找到自己的【学习共同体】,然后学习者刚开始围绕重要成员转,做一些外围的工作,随着技能增长,进入学习共同体圈子的核心,逐步做更重要的工作,最终成为专家。
这就是学习科学日益主流的观念:从【情景学习】出发,当一名【认知学徒】,它的要点有:
* 找到学习共同体:因为大量知识存在于学习共同体的实践中,不是书本中,所以有效的学习不是关门苦练,而是找到属于自己的学习*团体。如程序员在类似于github这样的网站练习编程。
* 隐性知识显性化:隐性知识是使人们有能力利用概念、事实以及程序来解决现实问题的知识。
* 模仿榜样:榜样可以是现实生活中的导师,也可以是网上的导师;
* 培养多样性:在多种情境中实践,以此强调学习广阔的应用范围。如裁缝出师并不是已经练习了一万*时,而是能够缝制出足够好的,各种各样的衣服。