导读:本文来自 reay z 的编译投稿,英文原文《Teaching Java in school is just as controversial as an interview with Justice Gray》写于2008年7月,原文中某些观点,现在看来可能不妥。另外,译文中有些不妥之处,伯乐在线已改进。以下为全文。
今天我读了一篇好文,这是对纽约大学计算机科学教授 Robert Dewar采访的一篇跟进文章。我等您读完再继续说。读完了?好的,现在我们能好好交流下了。我必须说,我完全同意 Dewa r教授对当今毕业生的主要观点。(自爆下,我拿到了华盛顿大学的计算机和软件系统学位,但我在学校主要用C++ 。)
他的一个主要观点是Java有很多库。从上文中引用Dewar博客的一段话:
“如果你去商店买本关于Java的书,你会发现在1200页中,有300页是关于Java语言,有900页是讲各方面库。 用Java,你是可以很轻松地快速做东西(但不是很仔细)……故而你是可以用最少知识匆匆拼凑做东西, ”他说。“但对我来说,这不是软件工程,倒像是某种“干耗级别”(consuming-level )的编程。”
首先他说的对,Java强大的原因之一就是它有很多库。还有 PHP、.Net 和 Perl 也有很多库。当然他们都不能用来驱动飞机或者火箭发射。但他们用在电子商务、管理公司、守护私人健康数据 、运行军队的装备和建立无用的社交网站。那么问题是什么?是不是Java不再是商业世界的流行语言?(当然不是)。是不是Java不是适宜用来教学生学习编程的语言?(当然不是)。是不是我们没有用正确的方法教计算机科学。因为你在看这个博客,所以我假设你是想知道这个答案的,所以我的答案是:
我们并没有用正确的工具来教正确的东西。
允许我稍微解释一下:
计算机科学太难了,所以只有带点神经质的书呆子才能掌握。
CS(计算机科学)这个专业吓倒了不少人。计算机很吓人,计算机很复杂,计算机是给那些盯着命令行一整天的神经质呆子。这是我从学其他非 CS 专业的人那里听来的全部。
除数学、化学、物理专业的人,才需要上 CS 课。
当我在学校的时候,有很多学科拿毕业证需要读过入门编程(在华盛顿大学那是CSE 142 和后续 CSE 143 )。当我上高中时,我通过社区大学的running start项目读了相当于 CSE 142 的课程。那门课是用C++,通过一年的学习,我获得了相当于 CSE 142的学分。所以我解放了大学一年级,闲了一年。那门课有挑战性,但并不过分而且那门课只有20-25人参加,所以每个人都有很多机会从教授那里得到个人辅导。
我选了 CSE 143 在我上华盛顿大学的第一年(那是1999年,所以现在可以算出我的岁数了)而且在那时那门课用的是C++。我当时已经懂C++了,但那门课对我来说依旧颇具挑战性。我想起当时我们的第一次考试,满分100分我考了44分,但仍然高于平均分。有很多人放弃了那门课。还记得我们的一个项目陷入 dll 地狱,没有一个人能让这代码 Build 和链接。连助教也无法让它运行。我的朋友Kevin,他是CS的高年级学生,他也无法让它运行起来。教授最后让我们交上来我们所有的东西,即使他不能编译和运行。这几乎让我讨厌计算机。这让很多学生说,靠,这糟透了,然后放弃这门课。
这正是Java试图解决的问题
Java没有“dll地狱”。有一个良好支持Java的IDE。它是免费的。它能运行在所有的平台上,并且不需要为此改变代码。语法很友好。它有很多库,你能用那些库里的类来实现大多数数据结构和算法,例如linked-lists, b-trees, heaps, hashtables等等还有常见的搜索、排序算法。现在学生只需要关于代码和如何让代码运行起来。像过去那样,鼓捣编译器使其运行和担心编程环境的情况,没有了(或最少化了)。如果一个学生喜欢用代码来解决问题,他们也许会选择这样做而不是被调试编译工具和IDE弄得无比沮丧。大学应该首先让CS看起来不那么恐怖,我认为Java可以做到这一点。
Java是如何至少导致了10个新问题
第一个问题是如何用Java教学生。Java有100000个不同的库,并不意味者你必须使用他们。而且大多数库都是用Java写的,难道不是吗?所以这是第一个问题:当你开始教数据结构和算法时,你必须实实在在地教它们,你不能简单第让学生用那些库去建立程序。也许教哈希表的一个好例子就是展示 Java HashTable的类,写一个程序来从一个HashTable中存取值。现在,自己写一个 HashTable类实现Map接口,并且输出实现。重复这样做以学习其他的数据接哦股和算法。喔,问题解决了。
所以既然学生学了Java,我们可以用Java做任何事,是吗?
不是的。你不能教Java里的所有东西。你只能教Java里的一些东西。我曾上过一个50%课堂内容是教Java的操作系统课,这么做是因为演示多线程概念用Java比C++更简单。但这并不意味着我不会用C++中多线程编程,而是在Java中debug它更简单一些,这可以让我专注于其他事情上。同样,在我们必须实现的虚拟文件系统的文件 IO 上,Java通过操作实际的文件 IO 让虚拟文件系统实现更容易,但是我们只有一个超大文件,而且在这个文件中有我们的inodes和数据,我们必须建立一个“文件”实现,它模仿读写我们的超大文件。再说一次,在不需要关心格式化实际硬盘驱动和与之互动的情况下,帮助我理解概念。这是重点:
Java允许你专注于问题的解决,而不需要关心工具和编程环境。如果专注于概念不依靠工具和编程环境,那么Java是一个好的选择。
通过一个对你来说很难管理内存的编程语言,来学习内存管理
这估计是Java作为一个学习工具最大的问题。作为一个开发人员,你必须对机器如何操作东西例如内存或者其他东西有深刻的理解。在Java中你完全不需要关心内存,所以这使得Java不是一个合适学习内存管理的工具。像C那样的语言真是一个最好的学习工具,因为它必须手动地做任何事情。实际上,我认为理解内存如何运作的最好方法,是去你能实际上看到地址模型和它们之间不同的地方。这帮助我理解指针,胜过任何其他的东西。这带领我们到:
这无法学习机器语言,除非通过一个真实的机器
Java是一个虚拟机,但我们想要理解真正的机器。计算机如何运作,背后原则的知识很重要,特别是当一些东西往坏地方发展的时候。在你离开学校后的职业生涯中,你也许并不会再使用汇编。你未来也不会写驱动或者编译器。但如果你正在用这些工具(我认为编译器也是一种工具),理解他们如何工作很重要,否则它们一旦不工作时,你将不能找出原因。你需要通过真正看到硬件如何工作来学习它。你需要能真正这几一个相对简单的逻辑线圈。你需要知道这些线圈如何用来组装一台计算机。这些东西并不难如果教的好的话。汇编语言是关于硬件和软件接口的,所以学好它很重要。我学了motorola68000汇编,它比 x86汇编简单,但还是很好地演示了指针。现在我知道:
1 2 3 4 5 |
|
的区别,在机器内部这是由汇编命令表达的。这帮我理解内存如何工作,而且这使我写出的程序不会发生内存泄漏。
但是,这些东西在教育系统中消失了
我(和很多人)认为Java是一个好的面向对象语言。很多人有一个或二个星期来完成关于多态的作业。这很酷,但你并不理解继承。他们不会教你为什么用继承和如何正确地使用它。他们不教任何东西关于模式、重构,或者简单地教授一些用对象编程的内容。我认为这些本应该被教的内容是很重要,很多大学毕业生因为不曾被教这些东西而不具备这些知识。我认为Java是一个好的工具去教这些东西。
还有测试
没有人教如何测试代码或者甚至如何使代码可测试。我并不是在讲运行应用程序并检查输入和输出。我在将单元测试,整合测试和自动化测试。知道必须测试和单元测试很重要是远远不够的。你需要理解累死test doubles, test automation等类似的东西,和如何写代码使之能单独被测试。Java是一个很好工具做这些。
其他一些东西
你如何建立一个大项目?如何自动化建立?如何管理源代码?分支是什么?有很多东西是有经验的程序员认为理所当然的,但我们必须在一些地方学到这些东西。也许我们在经历了这些问题后明白了这些东西,或者在工作中其他人告诉我们。这需要在学校就开始。别专注于一个特别的技术,而是要学习这些概念和了解这些概念为什么重要。代码在这种课堂中并不是最重要的,你可以使用你想用的任何语言。但是,记得这门课的目地是管理代码,而不是写代码,所以别给学生制造代码上的难题。用一些已有代码,做细微改动,迫使学生用版本管理工具,去改变构建过程,去考虑更复杂的东西。
最后的想法
很多大学坚持Java,因为很多学生已经知道它,这是最小公分母。如果你想让你学生从世界程序员的最小公分母中出来也没问题。程序员的一个重要技能就是学习新语言。这有助于在科技更新中保持劳力竞争力。如果你只教Java,那么问题将会是你的学生将没机会快速掌握一门新语言。
所以我的解决方案是:
●使用本学科最适宜的语言教授课程。入门课程应当教些能让程序编译并运行的东西。Java是一个理想选择,但 C# 也可以。入门课程的重点是编程的入门,而不是如何鼓捣编译器的入门。
●每个学生应该被要求在校时用最少4种编程语言。其中之一应该是汇编,其中之一还应该是面向对象编程语言。HTML不是一种编程语言。
●教如何编写出色代码。漂亮的代码不等于带注释的代码。这需要强制在每门课中执行。但这本身就是一个门具体课程中执行,并且最好是学生生涯开始之初尽快执行。课程内容应覆盖设计模式、OO设计的原则、单元测试等等。
●要求学生在通过入门课程后,在每堂课中都使用版本管理工具。大学应该提供学校的vcs给每个同学。这并不像听起来那么困难。
●编译器、硬件、操作系统课程应该是强制的(有时候,其中部分并非需强制)。在硬件课程的最后一个项目中,我曾写过一个反汇编程序用汇编语言。这很难,但并非不可能。班上每个成员至少能收获能工作的东西。我的反汇编程序,也能正确地反汇编自身。
●学生应该被强制与同班的其他人合作。合作可以包括一起工作,但也可能包括代码审查(code review)和结对编程。
●永远不要在全班面前强制 review 一个学生的代码,除非那个学生同意这么做,但匿名代码审查和在私人场合review都是可以的。我知道这在商业世界是不必遵守的,但我们在学校,而且我们并不想疏远学生。我认为这是一个折中策略,我们将仍可以传授代码审查的价值,并引导学生,并且不让学生有要放弃这个课程的念头。
●所有的课程都应该落实到写一些代码。
●在课堂上,教授应该至少提供一块漂亮代码,用于演示。这有助于学生去阅读漂亮的代码。这同样有助于学生阅读糟糕的代码,并知道它不好在哪里。
最后,如果你是一位教授、大学管理人员或者其他相似的,如果你想要与我细谈关于这个主题,我将很高兴在任何时间与你聊聊。我谈了这么多,是因为我热烈地相信这很重要,我将会尽一切力量去让计算机科学教育变得更好。如果你正在读这些,我建议你也将这作为优先做的事情。去和你本地的大学谈谈,给你的教授写邮件,去当地学校,特别是高中和社区大学演讲,鼓励学生去计算机科学系。除非你做点什么,否则你是不会知道你对别人的影响力有多大。
【伯乐在线注】:为了更好校对这篇译文,费了不少时间,尤其是原文标题中提到的 Justice Gray(法官葛雷),搜索好久,才找到他所涉及的有争议案件,就是一件美国排华案件,即:1893年冯越亭诉美国案。
简要摘编:1892年制定的吉尔里法案,是美国有史以来对华人最严厉的法案,其他国家的移民都不须带任何身分证明文件,但在美华人必须申请居民许可证并随身携带,若未携带就会被认定是非法居留而被逮捕,需先服一年苦役后,再被驱逐出境。
此案一出,立即受到华人社会的反对,中华会馆( Six Companies )呼吁华人不要去注册,认为此法案是违宪的法案,没有法律效力,这个种族歧视的法案违反了美国宪法的权利宣言( Bill of Rights )。与其缴费注册,不如把钱集资打官司。
冯越亭是 1879 年到美国的劳工,没有入籍,是居住在纽约市的合法永久居民,没有任何回国定居的计划。冯越亭响应中华会馆的号召,拒绝按照侮辱人身的种族歧视法律去注册。由于没有注册证,美国宪兵在没有逮捕令的情况下不经过正当程序就逮捕了冯越亭。
中华会馆请律师为冯打官司,认为吉尔里法案违宪,一直上诉到最高法院。 但最高法院大法官以五票对三票判决冯越亭等败诉。这五票中,就有 Gray 的一票。他认定吉尔里法案有效,并称“美国是一个主权国家,有权利排斥任何人、任何种族,并将之驱逐出境。” ——摘编自《美国华人法律史》