编程的美妙
摘自Linus自传《Just for fun》
为什么对编程这么狂热,我自己也解释不来。我姑且说说看吧:在编程的人看来,编程是世上最有意思的事情了。它要比国际象棋之类的游戏复杂得多,你想要什么规则都可以自己设定。按照你定下的规则,它的结果该是什么,就会是什么。
不过,似乎在外行人看起来,编程简直是地球上最无趣的事。
编程刚刚开始会令人觉得特别刺激,这个原因倒很好解释:因为你让电脑干什么,它就干什么,没有毫厘偏差,并且永远服从、毫无怨言。
这本身就很有意思。
虽说一开始是电脑的盲从让你对编程人迷,但是单靠这一点,并不足以让你真正喜欢上编程。事实上,电脑的盲从很快就会让编程变得无趣。编程真正让人欲罢不能的魅力是:你想要让电脑干什么事之前,必须先弄清楚,怎么样才能让它这么干。
我个人觉得,计算机科学和物理科学有不少相似的地方。它们都是在一个非常基础的层面上,探讨整个学科的运作原理。当然,不同的是,在物理科学上,你得去弄清楚这个已存在的世界是如何正常运转的;而在计算机科学上,你得从零开始创造出一个新世界来,而且还得设法让它正常运转。在计算机的世界里,你就是创世者,对这个世界里发生的一切都有最终决定权如果鼓捣得足够好,你就是这个世界的上帝。当然,这个上帝的地盘就比较小喽。我这么说,恐怕已经得罪地球上近一半的人了。
不过事实就是如此。你在电脑上创造出属于自己的新世界,而唯一的限制就是电脑本身的性能,还有,还有一点在今天尤为重要,那就是你自己的能力
比方说造一间树屋吧。你可以造一个带活板门的树屋,这样实用而稳固。不过这样一间仅为坚固实用而造的朴素树屋,和一间为了外观漂亮而巧用树木特点来精心雕琢的树屋比起来,人人都看得出来两者间的差别。造树屋可是- 种将艺术和工程融合起来的活儿。编程也是如此,也正是因为这个原因,编程才得以成为一件既有魅力又有价值的活儿。编程时,程序员往往优先考虑的是趣味住、美观性及震撼力,而非实用性。编程是一项充满创造力的过程。
最开始吸引我进入编程世界的,是我研究计算机工作原理的那个过程。其间获得的最大乐趣,就是发现了计算机和数学的异曲同工之妙:你可以创造出一个世界来,一个自主制定规则的新世界。在物理科学中,你会被客观存在的规律所约束。但是在数学和编程中,只要合乎逻辑,什么规则都行得通。数学问题只要能在数学世界里逻辑自洽,就可以成立,不必受到外部客观逻辑的约束。正如数学家们众所周知的,只要逻辑处理得当,就完全可以构建出一套新的数学体系,在新体系中等式“3+3=2” 都是可以成立的。事实上,在你自己创造的体系里,想干什么都可以。但是,当这个体系渐渐充实起来,变得越来越复杂,你就得格外注意,可别弄一些和它自相矛盾的逻辑出来。这个美面新世界要继续类下去,就容不得一点瑕疵。编程和数学一样,也是这么一回事。人们之所以会对计算机着迷,原因之一就在于计算机可以让人们游历自己创造的新世界,了解这个新世界能由自己改造后,可以变成什么样子。在数学中,人们往往是开动脑筋,根据经验来假设,从而得出可能住。举个例子,说到几何学,大部分人想到的都是欧几里德几何学。但是计算机能够帮助人们将不同的几何学形象化,而不仅仅局限于欧几里德几何学,有了计算机的辅助,就可以把虚构的世界形象化,亲眼看看这些虚构世界到底是什么样子的。记得曼德勃罗集吗,就是那个基于伯努瓦·曼德勃罗等式的分形图像?分形图像是人们利用计算机,对一个纯粹的数学世界的形象化表述。而在计算机出现之前,像这种纯数学,是绝不可能被形象化的。曼德勃罗就是在他那个本不存在的世界中,人为地制定了一些规则。虽然分形与客观现实毫无关系,但他们却创造出了一些非常棒的形状。通过计算机和编程,你可以构建新的世界。有时机缘巧合,这个新世界还会特别美妙。
不过,大部分时候,你并不是在创造新世界。你写一个程序,其实只是为了让它执行某个任务而已。在这种情况下,你就不是在创造新世界,而是在这个已存在的计算机世界里解决一个具体问题。要解决问题,就得好好恩考问题。但是,光是坐在电脑前盯着屏幕思考,就能把问题想通的,只有一些比较怪异的人才能做到。比如说,像我这种呆子气十足的怪胎就做得到。
计算机上的所有功能要起作用,都得以操作系统为基础。于是,创造一个操作系统就成了终极挑战。你创造操作系统的时候,相当于给所有在这部电脑上跑的程序创造了一个全新的生存环境——从根本上说,其实就是在制定这个世界的规则:什么事可以接受、可以做,什么事不可以接受、不可以做。其实所有的程序都是在制定规则,只不过操作系统制定的规则是最根本的规则。创造一个操作系统。就相当于为自己创造一方土地制定宪法。而在电脑上跑的程序则相当于各式各样的普通法律。有时候这些普通法律根本就行不通,这时就要看你的能耐了。你需要找到解决方案,并且清楚意识到自己已经循着正确的方式找到了正确答案。
还记得学校里那个总能答对问题的家伙吗?他的答案总比其他人来得快,恰恰是因为他没有刻意去寻找正确答案。他井不知道问题本该以什么样的标准思路来解决,只是以一种合理的思路来考虑这个问题。因此别人一听到他的答案,就觉得很合乎逻辑。
编程也是如此。你可以用蛮劲解决问题,跟问题慢慢磨蹭,直到它不再是问题为止,看谁磨得过谁。不过这是个愚蠢的办法。或者你也可以找到正确的方法来解决问题,这样问题就会立马消失。换一个角度看问题,你会突然灵光一闪:问题之所以成为问题,只是因为我原先看问题的方法不对!
要证明这一点,计算机科学方面似乎没有什么好例子,不妨举一个数学的例子吧。故事是这样的,伟大的德国数学家高斯那时候还在上学。有一天,他的老师觉得课本上的题太无趣,为了不让学生们走神,他让大家把从1到100 的数字加起来求和。老师原以为这群小孩子要花一整天的时间来做这道题,没想到这才过了五分钟,我们这位初露头角的小数学家就给出了正确答案:5050。他没有从t 到100 一个数字一个数字简单相加,因为要那样计算,可真是既折腾人又恳蠢到家。原来,他发现1加100 是101,2 加99 也是101 ,3 加98 还是101 ,一对对算下去,直到50 加51得到最后一个101。没多久的时间,他就注意到一共有50 对101,于是答案就出来了,就是5050。这个故事也许是虚构的,道理却十分浅显:伟大的数学家不会采用既繁琐又无趣的方法解决问题,因为他们能理解问题背后的真正内涵,并且利用L 这个内涵找到更为简便的方法,从而得出答案。这个道理放到计算机科学上,1 绝对也是一样的。没错,同样的问题,你可以随便写个程序来求和,就现在1 的计算机技术来看,这就跟打个响指一样简单。但是只有才思敏捷的伟大程序员才知道真正的答案。他们知道怎么样采用全新的方法,写出一个漂亮的程序来攻下某个问题,并且最终会证明这个新方法就是正确的方法。
我还是很难解释清楚,闭门三天冥思苦想却徒劳无功,找不到一个漂亮的好方法来解决难题,这编程到底有什么好着迷的?其实,一旦找到了解决问题的那个漂亮方法,那种感觉就会是无与伦比的。