现代软件工程 作业汇总
-------
软件工程的作业
-------
很多老师反映软件工程的作业题不好出,学生做的“大作业”也是了无新意。怎么办?师生们身处轰轰烈烈的软件产业的大环境,但是在软件工程课上做的题目却是非常简陋,没有起到应有的作用,这的确是一个很有讽刺意义的事情。有很多因素导致这一结果,这些因素都是可以克服的,在这里不再啰嗦吐槽了。怎么出一些有份量,能帮助学生进步的题目? 我们看到,程序 = 算法 + 数据结构;软件 = 程序 + 软件工程,软件工程的编程作业,是不同于 “熟悉某个数据结构/实现某个算法” 这样的算法课作业的。
怎么打分,很大程度上决定了学生的学习行为,请看:
软件工程课的分数系统,和打分方法 - SoftwareTeacher - 博客园 (cnblogs.com)
作业的格式
一个作业并不是一上来就贴代码,贴 UML 图, 它应该是学生在 “健身学员/健身教练”这一个关系下, 刻意练习,向自己目标前进的具体努力的体现。它应该是属于学生自己提高的一系列工作中的一环,因此,在作业的一开始,应该写:
这个作业属于哪个课程 | <课程的链接> |
这个作业要求在哪里 | <作业要求的链接> |
我在这个课程的目标是 | <写上目标> |
这个作业在哪个具体方面帮助我实现目标 | <写上具体方面> |
作业正文 .... | 注意代码要按格式上传 |
其他参考文献 ... |
作业的难度
首先还是要重申:大学的作业,就是有难度的。 这是在 【健身教练 / 健身学员】关系中,学员要变强,那么教练就要给学员上重量,上难度。大家都知道人的学习有下面三个区域:
-
舒适区 (稍微动动脑筋就会,很简单。 就像老师把知识点的水果洗干净,切成小块送到学生的桌上)
-
学习区(需要集中精力,学习新知识和技能来解决问题, 老师指出果子就在不远的果园里,介绍了几种方法, 但是学生要自己琢磨怎么才能摘到树上的果子)
-
恐慌区(自己的技能和知识远远达不到能解决问题的程度。 老师说果子在山的那一边,需要连夜爬山 ... ... 学生想...干脆放弃算了, 我要回家... )
老师给学生的作业也许一开始看起来有点难,这个 “必要困难” (参见 “必要困难”理论:如何成为一个超级学习者-虎嗅网 (huxiu.com) )是很有价值的,学生后续可以回来重温这些有困难的题目,而且可以再补做这些作业。 老师的作用是帮助学生度过这个困难时段,让学生逐渐建立信心,这样他们才能从 “恐慌区” 过度到 “学习区” 开始学习。
通过 【克服必要困难】来学习
UCLA 的罗伯特·比约克(Robert Bjork)教授和伊丽莎白·比约克(Elizabeth Bjork)教授提出了的“适度困难” (Desirable Difficulties)学习理论。“适度困难”理论指在学习时故意制造适度的、可克服的挫败感,这种良好的困难度可以使大脑对学习材料的处理更深入,记忆更持久。
https://thelearnerlab.com/desirable-difficulties
就像体育锻炼一样,刚开始会觉得肌肉酸痛,但长期坚持下去,身体素质自然会越来越好。
不幸的是, 学生们在学习时往往倾向于使用那些既轻松又不费力的学习技巧:
-- 看老师放 PPT,心想:看了就等于学到了,
-- 或者拍照老师的 PPT,“以后我会好好学的”,
-- 边读边划重点、绘制五颜六色的思维导图 ...
这些是基本方法,但是对我们的大脑来说都不够具有挑战性,说白了,很乏味! 它们不会帮学生把课程材料转化为对知识的长期记忆。我们都是大学生了,来点学习方法的干货吧!
必要困难之一: 学前就提问
《现代软件工程》课的第一个作业是:快速阅读全书,提出五个你还不知道答案的问题。很多同学说,我刚上这门课,软件工程还不知道啊,我怎么提问哪?! 在几十个学校的实践表面,这个方法很好地锻炼了学生的提问和分析能力。 另外, 心理学研究表明,即使你在一个新领域中的快速阅读后,一个问题都没答对,这个集中精力的提问阶段也能让大脑做好准备,在后来的学习过程有针对性地吸收信息。而且,由于你在前期的认真思考,你对问题和答案的印象会很深刻。 关键:要把你不懂的地方有条理地描写出来 -- 你要向大家说明 -- 你懂得了你现在不懂什么。
必要困难之二: 教同伴
必要困难之三: 有条理地点评
适度困难之四:通过错误学习
通过犯错和纠正错误的过程来促进更深层次的学习和理解。
提高作业质量 - 增加作业的丰富性
一个简单的程序通常是做这种简单的事情:
对输入数据进行处理,并输出。
此类 “程序”可以从几个维度扩展,成为很有锻炼价值的软件工程作业。下面举例说明。
从数据方面扩展:
- 从数据本身的属性扩展,例如处理“最大子数组的和”的程序,可以扩展到大数(超过64位的数字),这样引入大数的处理。
- 从数据的数量扩展,很多老师出题就假设数组只有六七个元素,直接写死在程序中。如果这个数组有一万个,十万个元素呢?
- 从数据的维度扩展,如果数据是在多维数组中呢?
- 从数据的其它属性扩展,例如,如果你的程序能处理北京的地铁数据,如何改进你的程序,让它能动态处理上海或其他城市的数据呢?这样就引入了工程的需求。
从需求方面扩展:很多程序的需求都是非常抽象,可以用数学公式描述和验证的,例如:“找出数组中的最大值”。下面有几种扩展的方式:
- 不是仅仅要求结果,而是要让程序把计算的过程显示出来。请搜索各种“动画显示排序过程”的程序,我们的同学也做了一个类似的题目。
- 从需求的维度方面扩展,例如学生写了一个“统计程序有多少行” 的程序,我们可以进一步要求,能把注释行,空行,只有一个字符的行去掉么?能处理目录里面的多个文件么?
- 重复一个成熟的、学生比较熟悉的需求,这是也是可行的,关键是要体现 “工程”的特点。 例如做一个文档编辑软件,要求能处理10M 大小的文本文件;做一个图书信息系统,要求有10万本书,100万条借书,还书记录。很多同学做的图书馆信息系统只有不到10本书的记录,这是图书馆么?
- 在已有的需求上增量改进,例如,让文档编辑软件支持markdown 语法,支持无限的“后悔”操作;让图书馆信息系统支持手机客户端。
- 探索创新的方式来满足已有的需求,或即将出现的需求。
从用户的方面扩展,绝大部分大作业都是单机运行,给一个用户(老师)看一次,看完就万事大吉。我们可以考虑下面的扩展方式:
- 单用户第二次使用这个软件的时候,能有什么功能,让单用户更喜欢这个软件?(例如:记住上次的状态,自动展现上次文档最后编辑的地方,等)
- 如果多用户使用这个系统,会出现什么问题,例如,学生的图书馆信息系统考虑到有100人同时查询的情况么?如何模拟这样的测试?
- 用户从世界各地来,怎么办?你的“程序”能提供多种语言的界面么?
- 用户有善意的和恶意的,如何让你的程序更安全?如何测试安全性?
从软件构建方面扩展:
- 如果是改进一个已有的软件,怎么办?
- 大多数的“程序”都是用单一的语言写的,如果软件有多个语言写成的不同模块,如何定义彼此的接口(API)?
- 如果软件已经在服务中(例如图书馆信息系统,如何升级部分模块,同时尽量减少系统下线的时间?)
- 有些老师想给学生出一些数据库方面的团队项目,但是又怕同学全盘抄袭现成的实现。可以考虑这样的方法:我们知道数据库应用一般分三层(数据 | 业务逻辑 | UI 层),老师设计数据库,学生们设计并实现其他两层。 这样可以很容易地检查学生是否能根据别人设计的数据库来做上层的设计。 并且老师可以准备大量数据做大规模的测试。
下面是一些和阅读,提问,分析, 设计,总结相关的作业:
和代码相关的作业:
个人项目:
Java 逐步提高练习(用命令行工具逐步练习 Java 技能)
结对项目:
现代软件工程 作业 2: 结对项目 (电梯调度设计) (如何自动测试电梯调度程序)
团队项目:
团队项目的总结,请看:现代软件工程讲义 11 项目管理 - 事后诸葛亮会议 - SoftwareTeacher - 博客园 (cnblogs.com)
团队项目的评审,请看: 软件工程课的分数系统,和打分方法 - SoftwareTeacher - 博客园 (cnblogs.com)
百花齐放:各个学校的编程/软工作业列表