“智商平平”学软件
金旭亮
前几天收到了一个在职普通程序员的邮件,在邮件中他说两次报考我们学校计算机专业研究生,但总是惨败而回,第1年总分考了250,砸在政治和数学上,努力复习了一年,又是砸在数学上,总分才285……。我几乎能真切地体会到他那种沮丧和不甘心——为什么我经过一年的辛苦努力,却还是原地踏步并在同一个地方跌倒两次?同样的疑问我也曾经问过自己无数遍,因为我也是连续考研三次才通过的。
我是一个“智商平平”的人,但还算比较努力,有幸“混入”高校,成了一名讲授软件开发技术的普通教师。任教8年多以来,接触到了相当数量的学生,有了一些教学经验,同时我还阅读了一些有关教育学心理学方面的书籍和文章,一直在思索这样的一个问题:
“智商平平”的人应该如何自学软件技术,而我又应该如何教“智商平平”的人学会软件开发技术?
我觉得“学”与“教”其实是同一个问题的两个不同侧面,都遵循类似的学习与认知规律。
这里首先要对“智商平平”作个界定。
国外比较重视智商测定,并已发展出了比较成熟的智商测试机制,往往能给某人以一个比较准确的智商测试成绩,这些成绩可被用于高校招生、企业录用员工、军队征兵等。但我们中国这一前提就不存在,比如笔者就从未做过智商测试。
尽管无法用数字精确地说明,但我们还是可以凭感觉和观察来得出一些结论——某些人很聪明,某些人则比较笨……,比如在同样一所高中里学习的学生,有的能在全国数学、物理等竞赛中屡屡得奖,不用参加高考就能保送到名校,之后顺理成章地继续攻读研究生,甚至能到国外名校去继续深造,考试对于他们来说实在是小菜一碟,想得个低分都不容易……,而许多普通学生,哪怕每天只睡几个小时,日以继夜地做题,高考也得不了几分。
记得我高考那年有位兄弟就是个典型例子,当我等正在题海中挣扎的时候,这位老兄却捧着本《神雕侠侣》畅游武侠世界,末了人家高考总分还是名列前茅。更有趣的是这位哥们后来学的是经济管理方面专业,毕业后工作没多久突然决定要考研,仅复习半年,就跨专业成为了一名计算机专业研究生……
还有我的一位师兄,在微软研究院“混”,他读博的几年,发论文就象我等编写几个小程序业似的,拿博士学位如探囊取物,这位兄弟给我印象最深的地方在于他曾经想出国准备GRE,一天背300多个单词。我的神啊,我一天能记100个就不错了,而且第2天还没准会忘了80个!
只要留心一下,会发现我们可以在身边找到许多类似的例子,这些例子说明了一点:人与人之间是存在着差异的,各有所长,也各有所短。我觉得大家公认为聪明的人,其智商应该都属于比较高的,可以合理地假设此人的智商属于人群中最高的10%(即十里选一)那一群体,那么正常情况下,他进入重点大学学习深造应该不成问题,如果是百里选一,那么他进入名校应该问题不大。
除了智商偏低的人(应该也有10%),中间约占80%的应该是“不笨也不聪明”的普通人,而我也属于这个群体,所以我最关注的也就是“普通人”的学习问题。
软件行业从业人员中有两种典型的类型:科研人员与软件工程师。个人感觉,从事科研工作并取得相应成就的人,应该是属于人群中那10%的智商最高的群体,而软件工程师这一工作,则80%的普通人经过训练都可以胜任,但要达到一流的水平,对其智商的要求也是相当高的。
科研领域取得成就的人,还有那些优秀的软件工程师,突出的一点是他们的抽象思维能力较高,而体现抽象思维能力水平最直接的标志,就是数学。我发现计算机科学研究弄到后头,来来回回摆弄的都是数学;另一方面,对于高水平的软件系统开发,与数学有很密切联系的计算机算法、数据结构、编译原理等比较抽象复杂的计算机科学理论的作用也开始突显。
前段时间,机械工业出版社送给我了一本《深入计算机系统(第2版)》,这本书以程序员的视角从底向上地介绍计算机系统的各个方面,许多人说这是本好书。有趣的是,在新浪微博上我看到有网友说:“这本书太枯燥了,根本看不下去”。我为此也发了一条微博和他一起交流:
觉得技术书枯燥与没兴趣,可能关键在于你实际开发经验不多,所以缺乏理解这些书所需的一些基础。个人体会,当某本书大多数人说好,而自己觉得很枯燥的,日后很有可能会发现原因在于自己第一次阅读时还没有具备看懂它的基础,无法引发共鸣……
这的确是我亲身体会。许多复杂抽象的计算机科学理论,在自己还没有具备相应的基础前,别去碰它,否则,收获的将只有挫折与失望。
举个例子:还没有使用编程语言亲自编程的体验,《编译原理》是学不会的;有的人高中数学其实都没掌握好,却想通过阅读《算法导论》来成长为一名算法高手,似乎也没这可能;同样的,如果没有足够的开发设计经验,却抱本《设计原本》(The Design of Design: Essays from A Computer Scientist)来啃,我只能对着你长长地叹息一声……
大家都急,想迅速成功,想迅速达到自己的目标,都等不了了,我也一样,但世界自有其规律,主观归主观,客观归客观,客观世界不会“听从”人的主观愿望,“人有多大胆,地有多大产”注定是一个神话……
很明显,每个人都应该想办法弄清楚自己的“家底”,然后选择最适合自己的学习方式。
时间倒推30年,那时只有很少数的人可以上大学,这些人绝大多数属于人群中较聪明的那一族,所以,整个大学教育体制其实偏向于“精英教育”,其主要目的是培养精英和栋梁之才。而21世纪以后,大批的普通智商的学生进入校园,从总体上来说,除了少数名校,大学教育应该转向“平民教育”。 而中国教育最大的问题也在这:由于众所周知的原因,很多大学属于“反应迟缓”并“拒绝改变”的“恐龙”,仍然采用“精英”教育的传统方式方法教学,这本质上就是将原来只针对少数优秀学生的教育方式与方法给“人为放大”,具体现象之一就是原先的十几人的小班变成了几十人甚至是上百人的大班。要知道,近十多年以来中国高等教育的重大变化不仅仅体现在学生规模的激增上,还体现在学生平均智商与素质的“普通化”。
用“放大”的精英模式教育大批的“普通人”,正如没有刘翔的身体素质,却按照刘翔的训练方法训练,用脚思索都会发现这是不太对头的。
拿计算机专业来说,近些年来虽然在不断的调整,但目前仍然是“理论”重于“实践”。前面也说过,复杂抽象的计算机理论课,绝不是那么好学与好理解好掌握的,有些课程,真的应该只针对那些比较聪明的学生来讲,而即使是所有学生都要学的同一门必修课程,针对不同层次的学生,也应该有不同的讲法。
好了,就软件这个领域,“智商平平”的普通人应该如何有效地学习?
我觉得,“智商平平”的普通人学软件,在一开始应该避开那些复杂抽象的要求有较高学习能力的计算机科学理论课程,特别是那些要求有实践作基础的课,应从能“即时反馈”并能“立即用于开发实践”的专业课程与开发技术入手。
举个例子,是否学生要学的第一门编程语言必须要是C语言?这个问题就可以讨论。我个人觉得,尽管从C入手是经典途径,已经多年的实践检验,但这并不排斥可以采用其他的方式。比如,能否一开始就直接学Python?诸如Python这类的动态编程语言,具有语法简单、反馈迅速的特点,很有助于学生理解编程语言,培养软件开发的思维方式。我还尝试过一开始就直接让学生学习面向对象的编程语言(比如C#),哪怕他们没学过C,但使用Visual Studio这种高度智能化的开发环境,以可视化的方式设计软件,最终能开发出真正可以在日常使用的软件,对学生还是有着很强的吸引力,不象C,学了一个学期,学生还只是编写几个“黑底白字”的小程序,根本就不知道现在的可视化软件是怎么写出来的,太有挫败感了。特别是C++,我觉得通过它来给刚学完C的学生讲面向对象编程,实在是个杯具,有几个学生真能在短短的一学期课程中搞得掂C++这么复杂的编程语言,而且还要求他们理解面向对象的思想并能用它写出真正可用的软件?我觉得,学完C之后,用Java或C#课程来帮助学生掌握面向对象的编程语言与思想,要比C++好得多。而且学生通过Java或C#掌握面向对象的基本思想与理论之后,再去学C++就好多了。
计算机科学与技术有很多个子领域,学习顺序其实是很重要的。
我个人认为,计算机专业的学生应该在大一,最晚不要拖到大二,就掌握一门主流的编程语言和开发工具,Java和C#是两个好的选择,为什么要这么做?道理很简单,你掌握了它们,就可以迅速地投身于软件开发实践,并且有助于掌握后继的计算机专业课程理论。
举个例子,在大一大二就使用Java或C#写过多线程程序的学生,在学习《操作系统》这门课程时将要轻松得多,而能在大学低年级就开始编写游戏的学生,往往会对《数据结构》、《人工智能》、《图形图像处理》等理论课程感兴趣,他就会主动地去学习相关的游戏开发平台与工具,学习C++这种复杂的编程语言就会有强大的动力,因为许多游戏引擎是采用C++编写的……。
在“无网不胜”的网络时代,学生掌握了Java、C#或C++之类主流的编程语言之后,他就具备了进军网络开发领域的可能,此时,他再学习《计算机网络》这门课程就水到渠成了,他可以将已具备的软件开发能力与相关计算机网络理论结合起来,自己开发一个Web服务器,自己开发一个QQ,自己开发一个网络游戏,自己写个互联网工具,自己写个跑在手机上的应用……,其所获得的成就感是枯燥的“空对空”理论学习所无法比拟的。
写到这,不妨作个阶段的小结:
软件技术怎么学?如果你属于“智商平平”的普通人,那么,请从动手编写小程序入手,在开发实践的基础上去学习计算机科学理论。
在具体技术领域的学习上,需要谨慎选择学习的方式与材料,当此领域内的某本经典著作你怎么也看不懂或觉得很枯燥时,请另选一本比较浅显的,或者咨询一下这个领域内的人,了解一下掌握这个领域的技术需要哪些前提,把这些欠缺的东西补上之后,这些书你就看得懂了,甚至是看得津津有味。
这里谈谈我的体会。我以前从未觉得有必要去了解各种网络协议的细节,但后来有了一些网络应用程序的开发经验,并且尝试分析.NET基类库中相关网络组件的设计时,就体会到如果不了解网络协议的特点,就难于了解为什么设计者会以这种方式来封装网络功能。
蔡学镛先生曾发过一篇微博,推荐大家看看《HTTP: The Definitive Guide》一书,后来我在网上找到了这本详细介绍HTTP协议各个方面技术细节的书,翻阅之后,对原先的许多有关Web开发的问题有了新的看法,很有收获。然而,如果某人没有开发Web应用程序的经验,恐怕又会说这本书“枯燥”了。
如果阅读本文的还是在校学生,他们可能说:“老师,我们没有选择课程与学习方式的余地,学校安排了这么多的必修课程,不硬着头皮去啃,我怎么毕业啊?”
而另一些已经工作的朋友则会说:“每天都有那么多的工作,很难有这个时间和精力按照你所说的方法去学习。”
这确实是个问题,但我也没解决办法,因为我们所处的环境我们没有选择权。在这里,我只是向大家描绘一下:我认为合理的软件技术学习方式应该是怎样的。而且我也看到了,正是因为违背了这些教育与学习的基本原则,中国大学才被国民“千夫所指”。这么多年来,中国大学在“培养真正的精英与栋梁之才”方面国民是不满意的(不然为什么会有钱学森的“世纪之问”并引发广泛共鸣?)。事实证明,中国大学这么些年来,精英没培养出来,大批的普通学生也没教育好,他们中的许多直到毕业也没有能掌握一些必要的职业技能,高不成低不就的,找工作困难,另一方面,IT企业许多岗位缺人却同样找不到能胜任工作要求的人才,整个一“死循环”……
莫谈国事,还是聊聊“笨”与“聪明”的问题。
前面我说过了,整个人群总可以划分为10%比较聪明的,10%比较“笨”的,余下80%的“普通人”。其实所谓“比较聪明”的人,主要体现在他反应快,记忆力强,抽象思维水平高,学习能力强,掌握新知识、新技能的速度快,投入少而收益大,……,但这并不意味着许多知识与技能只有聪明人才能掌握。
对于占80%的普通人而言,绝大多数聪明人所掌握的知识与技能也是完全可以掌握的,只不过需要更长的时间、更多的精力和更强的毅力,套句老话,就是要“笨鸟先飞”。
如果把智商高的那批人比作兔子,普通人比作乌龟,那么从理论上讲,兔子能到的地方,只要给与足够的时间,乌龟也是能爬到那的。当然,由于人的生命有限,对于那些从不偷懒的兔子,乌龟要达到这些兔子所到达的地方,是不可能的。然而老天比较公平,人性也有弱点,本身跑得快又不偷懒的兔子,在兔子这一群体中比例并不高,许多兔子往往会由于看到那么多的乌龟落在自己的后面,他们做事的方法那么低效那么笨,素质也差,就充满了优越感,往往会变得浮燥,不愿再辛勤努力了,结果他们最终也没有取得大的成就。相反,乌龟就没有任何骄傲的资本,乌龟中的那些上进的人,往往具有很强的坚持精神,不停地爬呀爬的,而且在爬的过程中他们会不断地动脑筋想点子,怎样爬得更快?结果大家都知道,有些乌龟,爬到了许多兔子所没能到达的地方。
金庸先生的名著《射雕英雄传》其实是一个经典的“龟兔赛跑”故事,比较“笨”的郭靖,其最终的成就比“聪明”的杨康要大得多,而小说中所描写的郭靖的学艺过程与心理活动和体验,实在是太切合实际了。我推荐所有的“乌龟”们好好地读读《射雕英雄传》,重点看看郭靖的成长过程。我有时在想,金庸先生是怎样的一个人,能将一个“笨人”的故事讲到这般的精彩?我觉得说金庸先生属于“跑得快的兔子”行列大家应该不会有异议,但我必须同时指出,他绝对是一只不偷懒的兔子,想想看,有几只偷懒的“兔子”能写出14部雅俗共赏的小说?更关键的是,这些小说部部不同,每部都有自己的风格,创新、创新,还是创新,绝不重复昨天的成功,结果让金庸先生在武侠小说领域成为他人难以企及的高峰……。
所以,即使是天才,不努力,也是废材,即使“智商平平”,坚持下去,也能爬得很远,但对于那些勤奋努力的天才,我想,大家一定会怀着敬意地提到他们的名字……
这就是“聪明”与“笨”的辩证法。
=========================================================================
附录:
这个学期我给本校成教学院“高中起点大专班”的学生讲授《C#面向对象程序设计》课程,为此,我设计了一套针对零面向对象编程基础的学生(但要求他们学过C语言)学习面向对象技术的教案,今天发布前两讲《C#程序设计语言与.NET面向对象程序设计概述》和《C#程序设计语言基础》。
欲作其事,先正其意。因此《概述》一讲中我分析了当前计算机教育的现状,介绍了软件技术的学习方法;而在《C#程序设计语言基础》一讲中,我针对学生几乎没有写过程序的现状,我采用了现场编程演示和现场上机练习的教学方式,要求学生自带笔记本电脑,跟着教师同步地在课堂上键入代码,然后马上现场完成一些小的编程任务的方式,有问题及时反馈,现场解决,同时留了课后作业。
我希望这些课程能帮助学生迈入软件开发的大门。
后续的课程教案将陆续发布,可供讲授《C#面向对象程序设计》课程的教师参考,也可以作为C#的初学者的自学资料。
请点击以下链接下载教案及相关源码(在自由互联)。
1 《C#程序设计语言与.NET面向对象程序设计概述》
2 《C#程序设计语言基础》