高博,1983年生,上海交通大学计算机科学与工程专业本科、软件工程硕士。现任博晓文化传媒集团总裁,香港卫视科教台台长。职场经历丰富,曾在数家世界500强IT和互联网企业打造明星团队。专业兴趣包括软件测试及大规模自动化、持续交付和基础算法研究。业余爱好写作和翻译,2009年至今翻译超过100万字,包括图灵奖作者高德纳作品《研究之美》和布鲁克斯作品《设计原本》、Jolt生产力大奖作品《元素模式》等,并以译作《信息简史》获中国国家图书馆第九届文津奖。
我从4岁时就开始学习使用计算机进行程序设计,我当时学的语言叫Algo-60,这个语言就是现在的Pascal和C的前身,Algo-60的设计者N. Wirth也是Pascal的设计者。当时的计算机和现在非常的不一样,我们现在完全在使用软件进行计算机的各种配置,这种配置程序在Windows操作系统里被叫作控制面板(control panel)。但是对于当时的计算机(我见过的型号叫709)而言,控制面板是真正的硬件操作台,上面有各种扳手和旋钮。现在很少有人见过、甚至听说过什么是穿纸带。纸带其实就相当于现在的机器码,而机器码就是010101。这些早年的经历,特别是从高级语言编译成低级指令,并且实实在在地变成纸带上的物理小孔的经历,对我今后的计算机学习在原理认识的帮助是很大的。4岁的这一年我还接触到了一个极其重要的东西,就是Internet,当时当然没有万维网,一切都是Telnet(FTP不知道当时有没有,反正我是没有用过的),我当时对于远程控制这件事简直觉得神奇极了,但是上机时间前后加起来也就是半小时不到,大概是怕我这个小孩子把昂贵的设备弄坏了吧。所以,这些印象真的是宝贵极了,我也因此感觉自己是非常幸运的,能够这么早地接触到真正的计算机和Internet。
我在上小学的时候,计算机已经进入了大规模集成电路时代。这个时候绝大多数的家庭还负担不起购置一台计算机的费用,更不用说我所在的那个小县城了。我却幸运地得到了一台当时广告做得铺天盖地的小霸王学习机,使用硬卡提供了最简单的一些软件,并带有10K不到的内存。但是学习机很快就完全无法满足我的要求了,尤其是我当时就早已见过真正的计算机是什么样子。1995年,我在上初一的时候第一次接触了PC,我在宿州市轻工业学校见到了PC和DOS,还有西山DOS中文系统。我已经提前看到了一些书,但上机以后才能体会到书上讲的东西是多么有意思。当时我还一点DOS命令都不会,只能请机房工作人员帮我运行起西山DOS进入中文界面,然后启动WPS来编辑文档。我记得很清楚,当时的输入法已经有了强大的联想功能。安徽省宿城第一中学是我系统地学习程序设计的发端,我在那里比较系统和深入地学习了Pascal语言。
从我个人的学习经历来讲,我感觉一个人在学习数据结构和算法之前,真的应该先掌握至少一门程序设计语言。通过程序设计语言,就可以知道怎么样地和计算机的细部打交道。在学习程序设计语言的时候,有好几项基础内容是需要很多练习才能掌握的,就拿循环来说,很多人实际上就卡在这个环节上,想象不出来循环变量应该怎么样写成一个循环体中的不变式。而跨不过这道坎,不能熟练地写出循环结构,简直就不可能写出任何有意义的程序来了。所以现在的计算机教育中的一个很大的问题在于,教育者们已经忘记了当年自己是怎么样从不懂到懂的一个经历,在一些他们自以为重要的问题上花了大量的问题,而在最简单最基础的内容上,却存在着极其重大的缺失,这让学生痛苦万分——正如IT教育家侯捷所说,勿在浮砂筑高台。你连while循环都不会写,怎么可能写出二叉查找树的遍历程序呢?而考试中如果这样的一个学生真的写出了正确答案,除了死记硬背还有什么可能呢?
我在初中三年学习中,下了狠功夫来了解Pascal和C程序设计语言,还有DOS操作系统。我在为了信息学竞赛的专项训练中,准备是不足的。所以在初中时代表宿州市参加了几次省级信息学竞赛,却一次奖项也没有拿到。但是只要做出一道题并验证通过,我就感觉到有一种实实在在的欣喜,因为我感觉我写出来的程序可读性会比较好一点,结构也比较合理,可惜这些可能都不是信息学竞赛要的,后者主要需要的是程序能够在规定的时间内给出符合格式的结果,所以无疑地对于算法的优化才是重点和核心。
在我上初中的那个年代,铺天盖地地分发和使用的,都是DOS操作系统,后面出了Windows 3.0以后又全都是16位的Windows了(还专门出了个简体中文版的Windows 3.2)。这个时期Linux可以说是完全没有任何渗透率的,我肯定是在2000年上了大学以后才第一次听说了Linux操作系统。如果是现在开始学习程序设计,尤其是小孩子想要开始学习的话,我是非常非常推荐使用Raspberry Pi和上面运行的Debian Linux发行版本的。原因在于,Linux天生是个现代操作系统,再少的系统资源上它也天然地具有现代内存管理机制和多任务等,不像DOS,它上面的限制实在是太多了。分配超过640KB内存就要采用很复杂的层机制,多任务更是只能采用迂回的办法做出非常蹩脚的实现。操作系统所在的层次是包括硬件抽象的,它的设计直接决定了上层应用的诸多限制条件。我在想,如果我当年第一次接触的就是Linux操作系统,我建立起来的计算机基本观念会有多么大的不同!
我的父母在1995年就为我买了人生第一台真正的计算机,是一台486DX。这台计算机配置了1M内存(单位真的是M),504MB硬盘。这个配置当然是非常低了,在当时却是相当先进的。可圈可点之处在于,它配置了一台当时非常少见的彩色CRT显示器。这是很舍得的投资。另一方面,它在计算和存储上简直是最小化的配置,也无意之间让我不可能把大量的精力花在当时对计算和存储资源要求较高的电脑游戏上,而只能是潜心研究程序设计,到了2000年我上大学前夕我还在用这台计算机,不过内存被加到了4M,运行Turbo Pascal和Turbo C是绰绰有余了。可是这台计算机在计算和存储方面给我带来的心理阴影也是巨大的,现在我在购置计算机的时候总是拼命选CPU最快的、存储最大的,而且总是会不断地购买大容量存储,可以看作是这段生活的一个对潜意识的影响。
我上高中以后是作为一个比较活跃的计算机兴趣小组的发起人和组织者来推进计算机学习和研究的。而我的高中生活的大背景则切换到了国际大都市上海,在这里可以更容易地找到一起学习和讨论的同学,而不像在小城市那边始终都是那么几个人。1996年底我接触到了万维网,也随即接触到了HTML和JavaScript,我可能是国内最早接触到JavaScript的一批人。但我还在上高中,如果当时就创业真的难以想象会怎么样吧。这个时候Windows操作系统已经开始爆发流行了,所以几乎一夜之间我学的关于DOS程序设计的东西完全落伍了。时代的发展是非常残酷的,但是在上大学之前,我对这个就有很深的感触了。所以在此后的学习中,我极力去避免和任何软件平台和框架绑定,因为这些东西都是历史的产物,也会随着历史的发展而消失。此前为信息学竞赛而准备的程序设计功底,可能唯一能看得到的回报就是得了一个市级竞赛的奖项,在高考材料里面算得一个亮点,让我被上海交通大学录取到了计算机科学与技术专业。
我在上大学之前,就已经感觉到自己应该投入更多的精力在一些研究“软件生产”上面,而不是在研究“编程技法”上面。上大学以后,我也确实更多地在投身入这个方面的研究。我可能是小时候写了太多代码了,所以我非常明白,想把代码写正确,和期望一致是一件多么困难的事情。而任何一种要交付给客户甚至大众使用的软件,它们背后要下的功夫都是非常可观的。
软件不仅仅包括“代码”,代码是一种静态的、一旦写完就不再改变的事物。而代码运行起来才是真正的考验开始之时。而这个“运行”,学问就大了。任何代码都要经过编译、链接以后才能够加载和运行,这个过程就涉及到库代码、他人撰写的代码,软件的编译器和链接器、软件的软运行环境(主要是操作系统,但有些系统软件或专用环境软件需要考虑更多)、硬件驱动和硬件设备。所有的这一切,都必须在适切的版本、正确的配置以及抽象层次之间紧啮的配合之下,才能够达到“运行起来”这个最简单的目的。而运行起来以后,是否能达成和期望相符的运行结果、交互体验和性能指标,则是每一个细节议题都可以写成厚厚的一大本书的了。
在这其中,有无数的思想和方法论在碰撞,而且会催生很多完整的所谓软件过程、表示、工具的成套设施,从任何一个方面研究下去,都会发现有很多有价值的内容。所有软件工程的基本思想都无外乎“提供一个封装好的抽象层”,把一些细节隐藏起来,作为一个美好的抽象概念暴露出来,让下游的软件工程师能够按照一个预先设定的概念集以事先规定的方式使用自己习惯的软件工具来撰写代码,而把这些隐藏好的细节照顾起来,以适当的方式给下游的程序员以他所在的语境的抽象语言描写的反馈。其实任何软件说到底都是机器代码的执行,在这个最底层的层次上,没有任何秘密可言,容不得任何错误。一切脱离机器码层次的概念都是更高层的概念,对机器而言都是毫无意义的,都是为了人类方便理解机器运行机制而设置的抽象层。但是绝大多数的程序员,对于机器运行机制的理解,也最多只能达到从最顶层的抽象向下探究的两到三个层次而已。
计算机科学的研究和学习有着分形(fractal)的特性。无论在哪个层次上做研究,使用的理论和数学工具都是相似的,其中极有意思的是基本算法和基础数据结构在各个层次上都发挥着作用,并且上一个层次和下一个层次之间还有差异性,有的时候这种差异性会给人以上一层次之一沙会是下一层次之一世界的奇妙层次感,更让身处其境的研究者感觉到选择之无止境。当然,每一个层次又有每一个层次的独特技巧,研究底层技术的研究者会更注意效率和简洁性,而研究上层技术的研究者则更会注意概念完整性和一致性。研究中间层技术的研究性则会产生大量的工具类方法和产品,可是它却又是变化最活跃的层次,并且要对上下游的技术都有完整成熟的理解才能被学术和工业界接受,而高级程序设计语言就恰恰处于这个层次,所以在这个领域里起的纷争也就最多。但我反过来要讲的是,往往我们要搞好这个层次,就非要往上下游的层次去多学一些东西才好,上游是科学理论和方法论,比如数理逻辑、离散数学、设计模式等,下游就是程序设计的机器细节。不过,任何层次上,都不能离于算法与数据结构,尤其是基本算法和基础数据结构,这方面的训练真的是千变万化而又乐趣无穷的,生活中到处都是能够拿来做算法和数据结构训练的实际问题。
任何问题到最后都会落实为人的问题,计算机的问题也会落实到研究者和程序员的身上。这两者的关系是难分难解的,哪怕是一个简单到10行以内的代码可以解决的问题,它也一定有设计、有实现、有验证,也一定有理论价值和工程价值。计算机就是这样的一个领域,如果止步于第一步,也一样可以产生一定的结果,但是深究下去就会发现无处不可拓展、无处不可优化,这也是为什么同样功能的软件,它的成本可以是成百上千倍的差距。大量的功夫是花在人们不能一眼看到的地方的,人们的观感和体验好一分,后面需要付出的研究和工程代价可能是难以想像地大。这些观念,都必须在程序员的最开始阶段的培养和训练上,就要施加影响,让所有的程序员都明白,做事最快的方法是什么,但什么是值得继续深入下去分解成更细的工作,然后在这些方面追求卓越表现。
所有和IT相关的职业,都毫无疑义地需要了解一线生产者,也就是做代码撰写、代码测试、持续集成的工程师们的工作细节的人来担当,而这样的人可以成长到各个方向去,成为产品、运维、甚至市场销售的人才,而只学了工业设计、营销理论或是其他专业知识的人,如果没有通过自学对于IT专业领域的理解达到一定的深度,则至多只能做配合的工作,如果一家以IT产品和服务为核心的企业不是按这个原则来招聘,那末必然会发生严重的问题。