文档属于这个专栏: 现代软件工程讲义 目录_SoftwareTeacher的博客-CSDN博客
备份:现代软件工程课程
参考:各个学校的编程/软工作业列表
-------
软件工程的作业
-------
很多老师反映软件工程的作业题不好出,学生做的“大作业”也是了无新意。怎么办?师生们身处轰轰烈烈的软件产业的大环境,但是在软件工程课上做的题目却是非常简陋,没有起到应有的作用,这的确是一个很有讽刺意义的事情。有很多因素导致这一结果,这些因素都是可以克服的,在这里不再啰嗦吐槽了。怎么出一些有份量,能帮助学生进步的题目? 我们看到,程序 = 算法 + 数据结构;软件 = 程序 + 软件工程,软件工程的编程作业,是不同于 “熟悉某个数据结构/实现某个算法” 这样的算法课作业的。
在全世界范围,这也是一个普遍现象,这个网站: http://nifty.stanford.edu 汇聚了一些有意思的编程/软件工程的作业, 大家可以参考。
怎么打分,很大程度上决定了学生的学习行为,请看:
软件工程课的分数系统,和打分方法_SoftwareTeacher的博客-CSDN博客
备份:
软件工程课的分数系统,和打分方法 - SoftwareTeacher - 博客园 (cnblogs.com)
作业的格式
一个作业并不是一上来就贴代码,UML 图, 它应该是学生在 “健身学员/健身教练”这一个关系下, 刻意练习,向自己目标前进的具体努力的体现。在作业的一开始,应该写:
这个作业属于哪个课程 | <课程的链接> |
这个作业要求在哪里 | <作业要求的链接> |
我在这个课程的目标是 | <写上目标> |
这个作业在哪个具体方面帮助我实现目标 | <写上具体方面> |
作业正文 .... | 注意代码要按格式上传 |
其他参考文献 ... |
增加作业的丰富性
一个简单的程序通常是做这种简单的事情:
对输入数据进行处理,并输出。
此类 “程序”可以从几个维度扩展,成为很有锻炼价值的软件工程作业。下面举例说明。
从数据方面扩展:
- 从数据本身的属性扩展,例如处理“最大子数组的和”的程序,可以扩展到大数(超过64位的数字),这样引入大数的处理。
- 从数据的数量扩展,很多老师出题就假设数组只有六七个元素,直接写死在程序中。如果这个数组有一万个,十万个元素呢?
- 从数据的维度扩展,如果数据是在多维数组中呢?
- 从数据的其它属性扩展,例如,如果你的程序能处理北京的地铁数据,如何改进你的程序,让它能动态处理上海或其他城市的数据呢?这样就引入了工程的需求。
从需求方面扩展,很多程序的需求都是非常抽象,可以用数学公式描述和验证的,例如:“找出数组中的最大值”。下面有几种扩展的方式:
- 不是仅仅要求结果,而是要让程序把计算的过程显示出来。请搜索各种“动画显示排序过程”的程序,我们的同学也做了一个类似的题目。
- 从需求的维度方面扩展,例如学生写了一个“统计程序有多少行” 的程序,我们可以进一步要求,能把注释行,空行,只有一个字符的行去掉么?能处理目录里面的多个文件么?
- 重复一个成熟的、学生比较熟悉的需求,这是也是可行的,关键是要体现 “工程”的特点。 例如做一个文档编辑软件,要求能处理10M 大小的文本文件;做一个图书信息系统,要求有10万本书,100万条借书,还书记录。很多同学做的图书馆信息系统只有不到10本书的记录,这是图书馆么?
- 在已有的需求上增量改进,例如,让文档编辑软件支持markdown 语法,支持无限的“后悔”操作;让图书馆信息系统支持手机客户端。
- 探索创新的方式来满足已有的需求,或即将出现的需求。
从用户的方面扩展,绝大部分大作业都是单机运行,给一个用户(老师)看一次,看完就万事大吉。我们可以考虑下面的扩展方式:
- 单用户第二次使用这个软件的时候,能有什么功能,让单用户更喜欢这个软件?(例如:记住上次的状态,自动展现上次文档最后编辑的地方,等)
- 如果多用户使用这个系统,会出现什么问题,例如,学生的图书馆信息系统考虑到有100人同时查询的情况么?如何模拟这样的测试?
- 用户从世界各地来,怎么办?你的“程序”能提供多种语言的界面么?
- 用户有善意的和恶意的,如何让你的程序更安全?如何测试安全性?
从软件构建方面扩展:
- 如果是改进一个已有的软件,怎么办?
- 大多数的“程序”都是用单一的语言写的,如果软件有多个语言写成的不同模块,如何定义彼此的接口(API)?
- 如果软件已经在服务中(例如图书馆信息系统,如何升级部分模块,同时尽量减少系统下线的时间?)
- 有些老师想给学生出一些数据库方面的团队项目,但是又怕同学全盘抄袭现成的实现。可以考虑这样的方法:我们知道数据库应用一般分三层(数据 | 业务逻辑 | UI 层),老师设计数据库,学生们设计并实现其他两层。 这样可以很容易地检查学生是否能根据别人设计的数据库来做上层的设计。 并且老师可以准备大量数据做大规模的测试。
如何防止抄袭:
很多同学都做同一个作业,这个作业也被之前的很多学生做过,如何确保学生的作业是经过独立思考和设计完成的?在开放式的教学中,这更是一个难题。 我们在实践中总结了很多方法。
- 先把规则讲清楚,一旦发现违规,马上公开处理不搞 “下不为例”。
- 作业可以根据学生的情况进行参数化,个性化,例如,要求把学生的学号作为程序命名的一部分,一个程序必须一开始就要写程序头的注释部分,把学生的信息写在那里。
- 学生的学号可以是程序要求的一部分,例如,一个题目是要处理一个二维数组,那么,二维数组的两个维度可以是学生学号的后四位中的前两位和后两位,如果小于 05 就改为 55. 这样,每个学生要处理的二维数组的维度都不一样。
- 记录工作过程。 很多老师只要求学生提交最终的程序,但是,一个正常的学生在写一个足够复杂的程序时,会从无到有,从简到繁写很多版本。 那么,我们就要求学生在源代码控制 (gitcode.net, github.com) 签入各个版本,例如,至少从最简单的空的源代码框架 (空的 .h .c 文件)到最后解决问题的版本,至少有 5 个版本。 这样,对于一个认真做作业的学生,他只要按时写程序,不断签入代码,那他自然就有较多的版本在几天的时间都有签入。 另外一个要抄袭的学生, 也许他在交卷前最后一小时只有 1 次签入,签入的就是完美的代码,这个显然不符合要求,另外一个学生在交卷前一小时有 5 次签入,每次间隔 1 分钟,几百行代码就写好了,这个记录大家一看就知道是怎么回事了。 当然,现在还有很多检查代码重复度的工具可以使用。
- 记录思路。 要求学生在文档中写 “你认为你程序中最精华的部分是什么,请写源代码和注释说明”。 这样,老师和助教比较各个学生的代码的时候,就只看精华部分,而不用看雷同的非关键代码。 很多非关键代码是非常雷同的(例如打开文件读数据),这个地方,学生即使拷贝网上的代码,我认为也无妨。 我们要考察的,是关键代码。 这对于老师出题也是一个挑战, 你出的题目要有挑战,有难度!如果你出的题目就是 “hello world” 那样简单平凡的,那你要好好反思。(参看上面的 “增加丰富性” 的段落)
- 强调个性化。要求学生写 “你认为你的思路最独特的部分是什么? 你写程序碰到的最困难的点是哪里,你怎么克服的?”。 不同学生应该有很不一样的回答
下面是一些和阅读,提问,分析, 设计,总结相关的作业:
第 0 周,课程的底线; 第一周博客作业
结对调查和分析作业
阅读和调查作业 (中科大的作业实例)
用户体验深入调查和数量化的报告
原型设计,提出项目建议
最后一周总结
和代码相关的作业:
个人项目:
MIT 软件工具基础教程
C++ 基本练习和效能分析 (四则运算)
Java 基本练习和效能分析 (四则运算)
Java 逐步提高练习(用命令行工具逐步练习 Java 技能)
现代软件工程 作业 1: 个人项目
从一维数组求最大子数组和展开训练
个人项目和结对项目练习 地铁
期末作业附加题 (同学的读书笔记)
最大子数组的和 - 及其扩展
结对项目:
两人合作作业的模式
Word Count (wc.exe) 全套练习
四则运算扩展: 模块化,单元测试,回归测试,TDD
动态展现程序的工作过程
英语文件中找到单词词频
结对和团队项目建议 - 黄金点游戏
现代软件工程 作业 2: 结对项目 (电梯调度设计) (如何自动测试电梯调度程序)
有意思的游戏:汉字构成 + 俄罗斯方块 + 2048
团队项目:
团队项目计划
现代软件工程 作业 3: 团队作业
2012 团队作业
团队项目建议 - 英语学习 App
源代码管理的10个问题
团队项目的总结,请看:现代软件工程讲义 11 项目管理 - 事后诸葛亮会议 - SoftwareTeacher - 博客园 (cnblogs.com)
团队项目的评审,请看: 软件工程课的分数系统,和打分方法 - SoftwareTeacher - 博客园 (cnblogs.com)
百花齐放:各个学校的编程/软工作业列表