《程序设计教学法--以Java程序设计为例》

当老师上的第一门课就是《Java程序设计》,工作以来,断断续续上了近十次课了吧。十几年来,教材、课程内容、教学方法、教学手段不断改变、不断尝试,最近自己才感觉形成了较好的一套方法。教书是人类事业中很少能从自己的过去获益的一类,总结一下过去,也许对自己、对别人都有好处。

教师角色

如何成为卓越的大学老师 》一书中说优秀的老师相信知识是构建出来的,优秀的老师可以构建一个自然的、批判性的学习环境,促进学生成为深度学习者,并对学生的思想、行为和感情产生了持久、真实和积极的影响。实践证明成为满足这样要求的卓越老师真的很难,但我们可以慢慢改进。

现在,教学都要求“以学生为主体、老师为主导”,到底怎么操作才好?我是直到读了邹欣老师的这篇博客,才找到最好的方法,邹老师把师生关系分成了几类:

  • Retailer/customer (餐馆/食客)
  • Boss/employee (老板/雇员)
  • Baby-sitter/babies (保姆/幼儿)
  • Buddies/Buddies (哥们/哥们)
  • Stranger/Stranger (路人甲/路人乙)
  • Prison Guard/Prisoner (狱警/犯人)
  • Trainer/Trainee (健身教练/学员)

并指出理想的师生关系应该是“健身教练/健身学员” 的关系。

周筠老师(知乎,微博,豆瓣)给我推荐了展示教练技术的电影卡特教练(去这看),卡特教练除了球技,还教会了球员怎么做人,让他们远离毒品和暴力。看了之后可以深刻体会教练如何影响学生的思维,促进学员成为深度学习者。

我认为“健身教练/健身学员”的关系定位可以真正做到“以学生为主体、以老师为主导”,结合微课、翻转课堂、SPOC、MOOC等技术进行混合式教学简直就是完美的解决方案,既能发挥教师引导、启发、监控教学过程的主导作用,又要充分体现学生作为学习过程主体的主动性、积极性与创造性。

教练和学员的关系如果确定了,“因才施教”就不是问题了:每一个来学习的学生,都是想学知识的,各人的先天条件不同, 目标也不同,作为实践经验丰富的老师可以根据学生情况制定一套训练计划和练习方法,并且通过交互了解学生学习情况,可以随时指出其进步和不足。Trainer/Trainee (健身教练/学员)推广到工程类教育中可以用大潘(微博)的“医学院-医院”模式来概括。

教学理念

做中学(learning by doing)

张志(秋叶)老师(微博,豆瓣)把知识分为三类

  • 元知识:基础知识
  • 硬知识:死记硬背的知识
  • 软知识:实践类知识

考前划划范围,学生背一背就能过基本上把元知识和软知识都变成了硬知识,学生可能有一个很好的分数,过一段时间背的东西一忘,就真的是什么也没学到。可惜不少课程是这么上的,学生学习的重点是元知识和软知识,结果一锤子买卖的考试彻底把它们变成了硬知识。所以每到教师节总有学生开玩笑“老师,我把跟您学的知识都还给您了,您什么时候把学费还给我啊?”

我也是学计算机的,知道实践的重要性。第一次上《Java程序设计》,最后的考试就是把五个课程实验重做一遍。自己感觉很简单的,做过的实验再做一遍就是考试,结果同学们都哭了。怎么能考实践呢?考试不应该出张卷子划划范围吗?上了一次课,对学生的总体水平有了了解,但对个体还是了解不是很好,因材施教远远没有达到。

这儿出现一个问题:要求如果都降低了,毁了一批优秀的学生,对他们不公平;要求高点,很多人达不到要求,这也不对。原因是上课过程中我们并不完全了解学生的基础和学习状态。

对于程序设计类课程,贯彻“做中学”,“项目驱动”的理念我是坚定不移的,但怎么做好,而自己没有很好的办法。直到看到《程序员的思维训练》中介绍的德雷福期(Dreyfus)模型。

在Dreyfus模型中,学习过程分为五个不同的阶段:

  • 新手(Novice)
  • 高级初学者(Advaned Beginnner)
  • 胜任(Competent)
  • 精通(Proficient)
  • 专家(Expert)

这个模型给我最大的启发是“不同阶段的学习者,教学方法是不一样的”,对于初学者就是详细指导。很多时候我们对学生的要求很高,但是没有深入的实际的接触,不知道学生的基础和水平是什么样子的,这个脱节导致教学效果奇差,反而是类似范飞龙博士(博客微博)写的这些简易教程有良好的教学效果。当然不能四年的学习都是step by step的,否则也只能教出来个初学者,我们就有不少大三、大四的实验,学生按步骤做完,还是什么都不大明白。

这篇文章以Java学习为例子说明了如何从新手到专家,供大家参考。

这个模型给我第二个启发是“五级技能的人数统计不是正态分布的,大多数人的技能是不合格的”,

如果你不刻意训练的话,你的某项技能(包括教学与学习)可能一辈子都是低于高级初学者的水平。这个我做过很多次调查,比如搜索引擎大家都用过,有些人用了十年google后的搜索技能都不如花半小时学学这篇文章图解Google搜索秘籍或花两个小时看看并练练文献管理与信息分析第二讲“搜索引擎与网络”的内容。

搭建个Android开发环境做出个"Hello World"能多困难?大家可以看看这里博客的有关Android开发环境演变的内容,计划一两个小时完成的事情最终可能要花十几个小时。

Java学习时,在Window下约有一半的同学不能独立完成JDK开发环境的搭建,之后的学习效果可想而知了。提供配好的学习环境并提供step by step 的学习步骤是非常重要的。

游戏化(gamification)

玩游戏可以上瘾,学习能不能上瘾?当然可以,我在每天一万步,一周减十斤这篇文章中举了个背单词的例子,过年都没有间断。

前几年,随着智能手机和平板电脑的普及,我迷上了电子书。电子书做笔记方便、查单词词语方便、容易分享、便携。而Amazon上的购买电子书是最方便的。问题来了,看英文原版书需要词汇量过关,当时我自以为自己10000词汇量不少了,但对于读英文原版书来说跟文盲差不多了。后来下定决心使用扇贝背单词背了两年单词,终于让自己看英文书没什么语言障碍了,当然还有其他不少良好的副作用,比如看英文新闻可以促进思考、培养批判性思维。

之后我研究了一下扇贝背单词,发现他们使用了游戏化的做法。游戏化就是将游戏设计的手段应用于非游戏的场景。更简单一点说,就是用游戏的框架,来解决工作生活中一切非游戏的问题。游戏化本质上是一种方法,一种思维方式,它可以应用到任何领域。

游戏化学习将转变“以教师为中心”的传统思路,让学习者在教学活动中主动地建构自己的知识体系,并且能形成学习成瘾系统。游戏化的成瘾作用,孙志岗(博客,微博)老师这篇“即时奖励”的力量有论述:

当某个动作能获得奖励,就会刺激人的大脑分泌“多巴胺”,而“多巴胺会促使人们期待得到奖励”,于是不断去做能获得奖励的事情。动作越简单,刺激越强;奖励越大,刺激越强;随机的奖励,也会产生很大的刺激。假如多巴胺有味道,我相信拉斯维加斯的赌场里一定到处弥漫这种味道。那些不停手机“摇一摇”的人,也一定是多巴胺的俘虏。
如果工作和学习的时候我们也能分泌多巴胺,就会快乐地不停工作和学习了,多美好。

Gamification在教育上的应用也层出不穷,MOOC旗下的在线教育平台Coursera、Udacity、edX等普遍采用了Gamification的理论。在国内教育网站学堂在线、网易公开课、网易云课堂、扇贝背单词等也都采用了Gamification的理论。

结合翻转课堂可以更好的应用游戏化理论:

实践证明,仅仅是应用排行榜就可以促进学生投入更多的学习时间,大家可以参考,还有

当然,配合排行榜还可以有其他玩法,这学期(2015-2016-1)周筠老师(知乎,微博,豆瓣)和人民邮电出版社赞助我们十件设计优美、制作精良的“Learning By Doing”教学理念T恤,每周从排行榜上找出一名同学进行奖励,极大的激发的同学们的学习积极性。

闫佳歆同学送出第一件T恤:

刘蔚然同学送出第二件T恤:

对于Java学习来说,据说可以通过玩游戏来学习的,参考一下Robocode,CodeSpells.

模块化(Modularization)

程序设计中,模块设计有“高内聚、低耦合”的设计原则,教学内容的设计也应该符合这个原则,这样学生才能够循序渐进的学习。王爽(网站)老师提出的知识屏蔽概念非常好的应用了这个原则,他将课程内容拆解到学习线索听各个教学节点(知识点、检测题、问题和分析、实验)中,让学习过程中接触到的每个知识点都是当前唯一需要理解的东西。

王爽(网站)老师设计的两条原则:

  1. 没有通过检测点不要往下学习
  2. 没有完成当前的实验不要往下学习

这完全符合“做中学”的理念,并且是教练对学员最根本的要求,保证学习的“循序渐进”,想想学变游泳,浅水区还没下过就去深水区会怎么样?

我读过的图书中,《汇编语言》和《计算机系统要素》在知识屏蔽上做的非常好的。

教学内容

《Java程序设计》是为有C语言程序设计基础的信息安全专业和信息与计算科学专业开设的专业基础限选课程。

课程的目的是让学生理解应用Java进行系统开发的基本方法、熟练使用Java开发的相关工具、掌握优秀程序设计实践、理解面向对象设计思想,并为专业课的学习培养学生良好的实践能力。同过本课程的学习让学生掌握Java基础知识、掌握面向对象思想方法,培养举一反三学习其他面向对象语言的自学能力。

本课程实践性很强,以“做中学(learning by doing)”和“项目驱动(“project driven”)”为基本方法,不但讲述面向对象的基本概念,基本方法,还介绍已被业界实践证明了的优秀实践、技术和软件过程:版本控制、单元测试、自动化、代码重构、结对编程、设计模式、软件体系结构模式、程序设计框架、UML建模、XP、RUP、PSP等,课程注重理论联系实践,培养学生的创新能力、自学能力、动手能力。

Java语言是动态发展的,课程注意更新教学内容,紧跟Java语言的新进展。

课程具有密码特色,主要表现在授课示例的设计上,课程示例结合密码学算法的实现和密码技术的应用来讲授,注重培养信息安全中“逆向”思维方式。

教学方法

我们的学生不但要编程能力,还要(公文)写作能力,写作同样也是要训练的。学生的创新能力也是培养要求的标配,而组合创新是我认为最容易达到的。

针对各种问题,使用的教学方法与对策:

动手能力差

学生虽然学过C语言,但普遍动手能力还是比较差的,写过的代码还是太少。

解决这个问题要基于“做中学”要求学生多加练习。

但一开始就让学生编写代码太难为他们了,我采取的策略是让学生输入调试教材上的代码,把教材“抄明白”,还给出了具体的抄代码的方法

学生一个月后就可以能找到写代码的感觉,这时可以设计一些结对的项目,让同学之间互相学习,完成构建之法(电子版)中的个人项目和结对项目,团队项目留在《安全软件工程》课程中。

结对项目和团队项目中遇到的打酱油现象,邹欣老师(博客,微博,豆瓣)强制团队中同学的分数不相同的方法基本完美解决问题。

实践环境和实践项目

不少情况下,学生连开发环境都搭建不好,有了实验楼,这个问题基本就解决了。

实验楼是国内首家IT在线实训平台,拥有最丰富的计算机在线实验课,而且全部免费。创业团队对师生的服务非常贴心细致。

《Java程序设计》设计了五个实验,实验一到实验四,都是根据指导初学者的最佳方式设计的,就是step by step的教程,实验五是个综合性实验,给出Socket代码、对称加密、非对称加密、摘要代码,让学生进行代码组合完成一个保密通信系统。

实验一 Java开发环境的熟悉:基本的开发过程和程序调试方法,学完后就可以自己练习教材上的代码了。

实验二 Java面向对象程序设计:面向对象的三要素,SOLID原则的练习。

实验三 敏捷开发与XP实践:敏捷开发的工具使用和实践。

实验四 GUI程序设计:GUI编程的熟悉,要求掌握组件、容器、布局、事件处理的方法,最新的引入Android开发。

实验五 Java网络编程及安全:培养学生组合创新的能力。

基础内容

一锤子买卖的考试导致一个结果是大部分同学平时不听课、不学习,期末找老师划范围,突击背一周就可以考个不错的分数,考完后把背的东西一忘,什么都没有了。

老师上课不知道学生的基础如果,凭自己的感觉满堂灌,学生可能听不懂,然后就不听课,也就不学了,靠期末背一下就混过去了。期末监考总可以捡到一些像新书一样的教材。

课前不预习,课后不复习,导致老师上课听不懂。老师看学生不懂,导致一些基础知识一遍一遍的讲,然后学生抱怨知识点重复。

基于微课的翻转课堂可以完美解决这个问题。翻转课堂翻转了什么?与传统课堂学习知识在课堂,内化知识在课外不同,翻转课堂学习知识在课外,内化知识在课堂。

翻转课堂的理论基础是人性化学习理论。与传统课堂固定45分钟或90分钟时间,固定在某个教师,翻转课堂让学生按照自己的情况进行个性化学习。教师给予学生个性化指导,可以做到因材施教。学生是主体,老师是主导,共同努力提高学生学习绩效。

学生不是不预习吗?我上课就考要你预习的东西,把期末一次考试分散到每节课,每次都花一二十分钟考一下,学生就预习了,然后课堂内容就可以深化了。

分散考试可以让老师尽快了解学生的学习状况,根据学生学习情况调整教学进度,基本上可以因材施教了。一般一个月后就可以前5名和后5名结对学习了。

翻转课堂如果结合一门MOOC就更好了,比如,我上过的《Linux及安全》就使用了孟宁老师的《Linux内核分析》翻转,我给孟老师当助教,效果良好

对翻转课堂感兴趣的老师,建议学习一下这几门MOOC,比参加什么培训的效果要好多了:

代码阅读与逆向

有三千行代码经验后,阅读代码就是程序设计能力快速提升的方法。

开始学编程时,侯捷(网站)老师的深入浅出MFCSTL源码剖析让我阅读代码入了门,侯捷(网站)老师还写了篇指导代码阅读的文章上窮碧落下黃泉 源碼追蹤經驗談

学习Java程序设计时,阅读JUnit的源代码让我对面向对象思想和设计模式的认识有了质的飞跃,《Java》程序设计课上,我一直推荐同学们分析JUnit的代码,学习其他语言时,实现一个简单的XUnit是我学习编程语言的必练项目。另外一个推荐是JHotdraw代码的分析。

当然,对信息安全专业的同学来讲,阅读代码的意义更大,漏洞分析的白盒分析是很重要的技能。

写作能力

我们的学生就业都在党政部门,到用人单位调研,对学生的(公文)写作能力的要求是没有极限的。

写作也是“软知识”,构建之法(电子版)提倡写博客来公开自己的学习成果。

公开的博客一个重大好处是锻炼了学生的写作能力,提升了思考的深度和学习的深度。

公开的博客一个副作用是大大减少了抄袭,如果再加点威慑,效果会更好。

老师评论博客,学生响应改进,这种持续对话相比一锤子买卖的期末考试而言,对学生的成长有极大的帮助。

参考资料

  1. 如何成为卓越的大学老师

  2. 构建之法(电子版)

  3. 学会独立思考:学习篇(电子版)

  4. 《Java程序设计》课程参考资料

  5. 汇编语言

  6. 游戏化思维(电子版)

  7. 现代软件工程讲义

  8. 程序员的思维训练

  9. 代码阅读



《程序设计教学法--以Java程序设计为例》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. XCLNetTools1.0(ASP.NET常用类库)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 2016-01-01开放所有源代码: 项目地址:https://github.com/xucongli1989/XCLNetTools 下载地址: ...

  2. #VSTS日志# 2015/12/10 – 终于可以删除工作项了

    最近的更新不少,废话少说,直接上干货 定制工作项字段 本周的更新后,所有的用户都可以在vsts上直接给工作项添加字段了,具体内容包括– 添加新字段(日期,字符串,整形,数字)– 字段显示位置配置– 过 ...

  3. 快速入门:十分钟学会Python

    初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...

  4. Sqlite学习笔记(一)&&编译安装

    Sqlite简介 sqlite是一个开源的嵌入式文件数据库,sqlite以动态链接库的方式供应用程序调用,所有的数据库对象都存储在同一个文件中. sqlite动态库非常小,最新的3.8.11版本也只有 ...

  5. Java对象的序列化

    1.概念 序列化:把Java对象转换为字节序列的过程. 反序列化:把字节序列恢复为Java对象的过程. 2.用途 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个 ...

  6. Hadoop2.6 datanode配置在线更新

    datanode 的配置可以在线更新了,http://blog.cloudera.com/blog/2015/05/new-in-cdh-5-4-how-swapping-of-hdfs-datano ...

  7. [转] OpenStack Kilo 更新日志

    OpenStack 2015.1.0 (Kilo)更新日志 原文: https://wiki.openstack.org/wiki/ReleaseNotes/Kilo/zh-hans 目录  [隐藏] ...

  8. C#基础---IComparable用法,实现List<T>.sort()排序

    List<T>.sort()可以实现对T的排序,比如List<int>.sort()执行后集合会按照int从小到大排序.如果T是一个自定义的Object,可是我们想按照自己的方 ...

  9. 【2016-10-12】【坚持学习】【Day3】【命令模式】

    今天学习了第二个模式,命令模式 例子: 开关==>发送者 电线==>命令传输 电灯==>接受者 一个开关可以通过不同电线控制不同电器, 结构: 发送者类, 抽象命令类 具体命令类:继 ...

  10. selenium如何高亮某元素和操作隐藏的内容

    高亮元素的思路是: 1.找到要高亮的元素 2.对该元素执行js,更改style达到高亮效果. 操作隐藏的内容思路: 1.可以用Actions的moveToElement,使鼠标悬停在触发隐藏内容的元素 ...