轮子哥推荐 - 那些伴 vczh 成长的编程书

每位大神的进阶路上都少不了专业书籍的堆砌,支撑我们看世界的书越多,我们看到的世界就越大。

轮子哥就是其中典范。简寻致力于帮助每个程序员找到更好的offer,但是也关心每位程序员的成长。在软件的背后,不是一行行冷冰冰的代码,而是我们有温度的真心。

★★★★

学习C++是一个艰难的过程。如果从我第一次看C++的书算起,现在已经过了11年了。一开始的动机也是很不靠谱的。刚开始我很喜欢用VB6来开发游戏,但是我能找到的资料都是用C++来做例子的,文字部分又不丰富,于是我遇到了很多困难。因此我去三联书店买了本C++的书,想着我如果学会了C++,就可以把这些例子翻译成VB6的代码,然后继续用VB6来写游戏。阴差阳错,我买到的是一本语法手册。不过那个时候我还小,不知道什么是MSDN,也不知道MSDN是可以打印出来卖的:

我们都知道语言参考手册(MSDN里面叫Language Reference)的顺序都是按照类别而不是教学顺序来排列的。刚开始讲什么是表达式的时候,例子就出现了大量的函数和类这种更加复杂的东西。于是我选择重新看一遍,基本的概念就都知道了。当然这个时候完全不能算“学会C++”,编程这种事情就跟下象棋一样,规则都很容易,但是你想要下得好,一定要通过长期的练习才能做到。

我第二次去书店的时候,遇到了下面的这本书《Visual Basic高级图形程序设计教程》:

在这之前我买到的两本VB6的书都是在教你怎么用简单的语法,拖拖界面。然后就做出一个程序来,直到我发现了这本书。我还记得当时的心情。我在书架上随手翻了翻,发现VB竟然也可以写出那么漂亮的图形程序。

因为数学知识缺乏的关系,学习这些基础知识又不可能那么快,所以我把一部分时间投入在了游戏开发里面,尝试自己弄点什么出来。毕竟当时对编程有兴趣,就是因为“说不定游戏也可以用代码写出来”的想法,于是我得到了下面的这本书:

这本书是我觉得21天惊天阴谋系列里面唯一一本良心的书。它并没有只是简单的罗列知识,而是教你利用VB6内置的功能搭建从简单到复杂的游戏程序。

在刚开始学编程的时候,基本上都没有什么固定的方向,都是在书店里面碰到什么就写什么。于是有一次我在书店里看到了《Visual Basic 网络高级编程》

这本书是我在学习VB的过程中最后一本我觉得不错的书了。虽然VB本身也提供了很多访问网络资源的控件,但是这本书并没有让你仅仅会用被人的轮子来写代码,而是一步一步的告诉你这些网络协议的内容,然后让你用Socket来跟这些服务器直接交互。

★★★★

由于程序本身过长,我在开发的过程中觉得已经很难控制了。再加上我发现我的同一个模块里的函数基本上都是下面的形式:

PrefixFunction(var data:DataStructure, other parameters ...)

总觉得跟调用Delphi的类库的时候很像。所以我就想,既然代码都变成了这样,那是不是学习面向对象开发会好一点?在这个过程中我有幸遇到了这本《Delphi6 彻底研究》:

虽然说这本书并没有包含那些深刻的面向对象的知识,但是他详细的介绍了Delphi的语法、基础的类库的用法还有Delphi那套强大的控件库和数据开发的能力。这本书第一次让我知道,Delphi是可以内嵌汇编代码的。这给我对计算机的深入理解打开了一扇门。

学习汇编是一个漫长的过程,这倒不是因为汇编的概念很复杂,而是因为里面的细节实在是太多了。这些知识靠网络上零星的文章实在是无法掌握,于是在常年逛书店的习惯之下,我又遇到了《Windows 汇编语言程序设计教程》。

这本书内容其实并不是很多,但是他给了我一个很好的入门的方法,也讲了一些简单的汇编的技巧,譬如说怎么写循环啊,怎么用REPZ这样的前缀等等,让我可以用汇编写出有意义的程序。汇编和Delphi的结合也促使我开始去思考他们之间的关系,譬如说一段Delphi的代码就经是如何映射到汇编上面的。下面发生的一个小故事让我印象深刻。

那还是一个,我还很喜欢各种不知所谓的奇技淫巧的日子。有一天我在论坛里看到有人说,交换两个integer变量可以用一种奇葩的写法: a:=a xor b;
b:=b xor a;
a:=a xor b;

于是我就理所当然得想,如果我把它改成汇编,那是不是可以更快,并且超过那种需要中间变量的写法?后来我试了一次,发现慢了许多。这个事件打破了我对会变的迷信,当然什么C语言是最快的语言之类的,我从此也就以辩证的眼光去看待了。

纯粹的教程类书籍看多了之后,除了类库用得熟、代码写得多以外,好处并不大。所以当我有一天在书店里发现《凌波微步》的时候,刚翻开好几页,我就被它的内容吸引住了,断然入手。

这本书让我第一次觉得,一个程序写得好和写得烂竟然有如此之大的差别。作者下笔幽默,行文诙谐,把十几个例子用故事一般的形式讲出来。这本书不告诉你什么是好的,而告诉你什么是不好的。每一个案例的开头都给出了写得不好的代码的例子,然后会跟你解释的很清楚,说这么做有什么不好,改要怎么改的同时,为什么好的方法是长那个样子的。这本书也开始让我相信方法论的意义。有理论基础和没有理论基础的程序员之间的区别,不在于一个程序能不能写出来,而在于写出来之后性能是不是好,代码是不是容易看懂的同时还很好改,而且还容易测试。这本书对于我的意义就是给我带来了这么一个观点,从而让我开始想去涉猎类似的内容。

当然,那段时间只是这么想,但是却不知道要看什么。所以在一次偶然之下,我发现了《OpenGL 超级宝典》。当然第一次看的时候还是第二版,后来我又买了第三版。

鉴于以前因为《Visual Basic 高级图形程序设计教程》的缘故,我在看这本书之前已经用Delphi写过一个简单的支持简单光照和贴图的软件渲染程序,于是看起来特别的快。其实OpenGL相比起DirectX,入门级的那部分API(指glBegin(GLTRIANGLESTRIP)这些)是做得比DirectX漂亮的,可惜性能太低,没人会真的在大型游戏里使用。剩下的那部分比DirectX就要烂多了。

虽然说《Visual Basic高级图形程序设计教程》是一本好书,但这只是一本好的入门书,想要深入了解这方面的内容还是免不了花时间看其他材料的。后来我跟何咏一起做图形的时候,知识大部分来源于论文。不过图像方面,还是下面这本冈萨雷斯写的《数字图像处理》给了我相当多的知识。

这本书的特点是,里面没有代码,我很喜欢,不会觉得浪费钱。不过可惜的是在看完这本书之后,我已经没有真的去写什么图像处理的东西了。后面做软件渲染的时候,我也没有把它当成我的主业来做,权当是消磨时间。每当我找不到程序可以写觉得很伤心的时候,就来看看论文,改改我那个软件渲染器,增加点功能之后,我就会发现一个新的课题,然后把时间都花在那上面。

★★★★ 我还记得我们那一年比较特殊,一进去就要军训。军训的时候电脑还没来得及带去学校,学校也不给开网络,所以那一个月的晚上都很无聊,跟同学也还不熟悉,不知道要干什么。所以那段时间每到军训吃晚饭,我就会跑到学校的图书馆里面泡到闭馆为止。于是有一天让我发现了李维写的这本《Inside VCL》。

这本书不仅内容深刻,更重要的是写的一点都不晦涩难懂,所以我看的速度非常快。基本上每个晚上都可以看100页,连续七八天下来这本书就被我翻完了。这带来了一个副作用就是,图书馆的姐姐也认识我了——当然这并没有什么用。

过后我又在书店得到了一本《Delphi 源代码分析》。

这本书跟《Inside VCL》的区别是,《Inside VCL》讲的是VCL的设计是如何精妙,《Delphi 源代码分析》讲的则是Delphi本身的基础设施的内部实现的细节。

★★★★

因为在高三的时候我在不懂得《编译原理》和大部分数据结构的知识的情况下,用Delphi写出了一个Pascal脚本引擎,所以当我听说我大学的班主任是教编译原理的时候,我就很开心,去跟她交流这方面的内容,把我当时的设想也拿给她看。当然我的设想,没有理论基础的知识,都是很糟糕的,于是班主任就给了我一本《编译原理》。当然,这并不是《龙书》,而是一本质量普通的书。不过当我了解了这方面的内容之后,《龙书》的大名也就进入我的耳朵里了:

《龙书》的性质也是跟《Visual Basic 高级图形程序设计教程》一样,是入门类的书籍。用来理解一下编译器的运作过程是没问题的,但是一旦需要用到高级的知识。

有一段时间运气比较背,好的C++书都没给我碰上,直到我看到了《C++语言的设计和演化》

C++他爹写的这本《C++语言的设计和演化》是一本好书,我认为每一个学习C++的人都应该看。《C++语言的设计和演化》讲的是当年C++他爹发明C++的时候如何对语言的各种功能做取舍的故事。

C++知道每一个特性如何正常使用还不够,如果不知道他们是如何实现的,那有可能在非常极端的情况下,写出来的程序会发挥的不好。正如同如果你知道C++编译器、操作系统和CPU内部是如何处理这些东西的细节,如果你顺着他们去写你的程序的话,那性能的提高会特别明显。譬如说在做渲染器的时候,为什么光线追踪要按照希尔伯特顺序来发射光线,为什么KD树可以把每一个节点压缩成8个字节的同时还会建议你按层来排列他们,都是因为这些背后的细节所致。这些细节做得好,渲染器的效率提高一倍是完全没问题的。这些知识固然很多,但是C++的那部分,却包含在了一本《深度探索C++对象模型》里面:
读《深度探索C++对象模型》,不仅仅是为了知道C++在涉及虚拟多重继承基类的成员函数指针结构是怎样的,而且你还可以从中学到很多技巧——当然是指数据结构的技巧。

文章之前的部分有提到过,让我正视理论和方法论的意义的是《凌波微步》,所以当工具都掌握的差不多的时候,总需要花时间补一补这方面的内容。首当其冲当然就是大家喜闻乐见的《算法导论》了。我记得当时是唐良同学推荐给我的这本书,还重点强调了一定要看原文,因为中文的翻译不行。所以我就去广州天河书城,把这本书搞到手。

我通过《算法导论》也学到了如何准确的计算一个函数的时间复杂度和空间复杂度。事实证明这个技能十分重要,不仅可以用来找bug,还可以用来面试。

★★★★

对于一个读计算机的大学生来说,算法懂了,工具会了,接下来就是开眼界了。不过这些东西我觉得是没法强求的,就像下面这本《程序设计语言——实践之路》一样,都是靠运气才到手的——这是一个小师妹送我的生日礼物: 这本书告诉我,这个世界上除了命令是语言,还有各种不同的编程的范式和方法。于是借着这本书的机会,我了解到世界上还有Prolog、Erlang和Haskell这么美妙的语言。

一直以来我都是用一种编程方法来解决所有我遇到的问题的。一开始我的认识还是比较浅,应用这些方法的时候还处于只能了解表面的状态,譬如说曾经流行过几天的Fluent Interface,还有声明式编程啊,AOP等等。直到我遇到了这本全面改变我对C++模板看法的书——《Real World Haskell》:

说实话我用Haskell用的并不熟,而且我也没写过多少个Haskell的大程序,但是Haskell的很多方面我都去花了很长时间去了解,譬如那个著名的Monad。多亏了当时搞明白了Monad,我借助这方面的知识,理解了《Monadic Parser Combinator》这篇论文,还看懂ajoo那篇著名的面向组合子编程系列。

★★★★ 上面所列出来的书,每一本都是对我有深刻的影响的。当然光有深刻的影响是不够的,具体的领域的知识,还是需要更多的资料来深入研究,譬如说下面的一个单子,就是我在学习开发编译器和虚拟机的时候所看过的。内容都很深刻,很适合消磨时间。

虚拟机——系统与进程的通用平台

Garbage Collection——Algorithms for Automatic Dynamic Memory Management

高级编译器设计与实现(鲸书)

程序设计语言理论基础

类型与程序设计语言

Parsing Techniques——A Practical Guide

The Implementation of Functional Programming Languages

简寻技术沙龙 - 前端大咖的前沿技术分享 →
← 专访「轮子哥」—代码为剑,热血如沸