推荐序1
给自己从底层重修的胆量
拿到新一版《编程卓越之道》的第一卷《深入理解计算机》的稿子,心里非常感慨:上次读这本书,已经是16年前,还留下了幼稚的读后感[ https://blog.csdn.net/gzlaiyonghao/article/details/766912]。今天回头看书稿和自己当年的文字,汇编语言以及WebAssembly等底层技术的新面貌再度翻红,而程序员的基本功仍然是与同行拉开距离的最大因素,花时间与精力深入理解计算机还是回报率最高的“投资”。
以此来看,2006年我在博客上留下的印记仍然有适用性,仍然值得新的读者参考,所以大胆地编辑了一下,作为推荐序。
本书是《编程卓越之道》(英文名:Write Great Code)四卷本中文版的第一卷。这本书是好书,作者Randall Hyde对计算机系统的深入理解跃然纸上,从数值在计算机中的表示到二进制算术和位运算从浮点数表示到字符表示及字符串组织,从内存的组织与访问到CPU体系结构,从指令集到输入/输出,娓娓道来,它们的优缺点和瓶颈了然于胸。
作者并没有教你优化的方法,而是告诉你哪里会有陷阱。记得《C++编程规范》里有一条规范是避免代码劣化,这本书全书都在印证这一说法——如果你没有能力优化,起码要保持它没有被劣化。参加过一些代码评审,有时候会看到一两段代码写得比较耗CPU和内存,比如在局面重置时全部生成新的对象,或者在条件判断时把不太可能发生的情况放在前面。当评审人指出问题时,听到的最多的辩解是:“嗯,这里是有问题,因为项目刚开始,代码不成熟,我们打算在正式版(下一版)优化它。”但我想说的是:“你不是在做优化,只是把劣化的代码改正过来而已。”同样是来自《C++编程规范》,有一句话说得很好:优化应该在代码稳定成熟了之后再做,防止劣化却要时刻进行(大意如此)。阅读本书能使你大大减少踩入劣化的陷阱。
作为以编写卓越代码为目标的程序员,精读《编程卓越之道》四卷本的意义绝不止于加固基础那么简单,我更大的感触是它让我认识到基础的重要性。从小学到大学,胸无大志的我耍着几分小聪明就轻松过关。而正是这当年引以为傲的小聪明,让我不重视基础,以为生活和工作也会像考试一样逃不出自己的聪明脑袋。大学毕业校招进了网易游戏部门,身边高手如云,想奋起直追时才知道自己下盘不稳、根基不牢。因为自己害怕离开自己熟悉的语言和平台不能让自己发挥小聪明,让人识破自己是只纸糊的“老虎”,心魔成了追求进步的最大障碍。直到工作了很久之后,才有胆量卸下“偶像包袱”,给自己从底层重修的胆量,慢慢走上自我修身之路。而《编程卓越之道》是很好的“修”技术之“身”的书,我打算四卷全读。
读完第一卷,我的感想是,做大事要有做大事的策略,但天下大事必作于细,没有坚实的基础知识,是没有掌控大事的能力的。所以,要放好心态,给自己慢慢来的胆量,一步一步来,从底层重修。
——小红花技术领袖俱乐部创始人 赖勇浩
推荐序2
什么是卓越代码(Great Code)?场景不同,角色不同,对卓越的定义自然有所不同。既然没有统一的标准,似乎可以放过不提。然而,本书系列题为《编程卓越之道》,又如何可以轻易放过对卓越的认识?细品作者Randall Hyde采纳的定义:
卓越代码是按照一套一致的优秀软件特征编写出来的,首要考虑的是优秀软件特征。特别是,卓越代码要遵循一套规则,这套规则能够指导程序员在用源码实现算法时的决策。
单就定义而言,依旧语焉不详。关于什么是优秀软件特征,或许大家可以从书中寻觅到答案。而我却透过书名,隐隐捕捉到Randall Hyde的一个观点——没有深谙计算机底层原理,不可能写出卓越的代码。——这也正是本书(卷1)的核心思想:深入理解计算机。
听听作者自己的解释:
了解了计算机如何表示数据,就了解了高级语言的数据类型是被如何转换到机器层次的;了解了CPU如何执行机器指令,就了解了高级语言应用程序中各种操作的代价;了解了内存性能,就了解了如何组织高级语言中的变量和其他数据,让缓存和内存的访问最优。
此言非虚。正如要学好Java,就有必要了解JVM的工作原理,而要彻底了解JVM,怎能不知道计算机的底层原理?以指令集为例,这是汇编程序员天天使用的基本编程要素,而Java程序员就鲜少涉猎。殊不知,这些Java程序员编写的每行代码都会被编译为运行在JVM中的指令。对照来看,恰好本书介绍了短指令和长指令在空间、性能与复杂度的取舍,而JVM则采用了折中的变长指令,允许操作码后跟零字节或多字节的操作数(operand)。同一条知识,打通了从计算机底层到高级语言开发的通路。
作为一名汇编语言高手,Randall Hyde极为推崇汇编语言对程序员的助力。他在本书后记中建议:“有一种强迫自己在机器层次编写代码的方法就是使用汇编语言。”许多新生代的程序员对此建议或许不以为然,毕竟,如今使用汇编语言的机会可谓少之又少,它的重要性已经淡化。
遥想当年,在我的大学时代,汇编语言还是计算机专业最重要的一门编程语言课,当然,也是公认最难啃的硬骨头。当时还能熟练编写汇编程序的我,早已不记得这门语言的大部分语法了。我不知道,学习和使用汇编语言是否真的有助于写出卓越代码?我也不知道,我之所以没能写出什么卓越代码,是否与我汇编水平不高有关?但我深信,倘若具有高超的汇编开发能力,必然理解计算机底层运行的细节;倘若能很好地掌握汇编语言,学习任何一门高级语言,也就不在话下。
当软件系统规模如滚雪球一般变得越来越大时,我们已不可能像当初求伯君那样用汇编语言去写十几万行的WPS。虽然使用的语言不同,编程态度却应该一以贯之。然而,当我们写出动辄数百万行代码的应用系统时,是否真的思考过每条语句背后的代价?——问程序员,有多少人以写出卓越代码为己任?问代码,又有多少是深谙计算机底层原理的程序员写出来的?我们这个行业,因为竞争加剧的原因,程序员变得更加地浮躁。没有办法让自己静下来,沉心打磨基础;当开发技能成为一种快餐时,还有谁会力求编码的精益求精?又有多少人舍得花费宝贵的时间来深入理解计算机?然则,“九尺之台起于垒土”,没有扎实的基础,开发的能力究竟能提升多高,编程的生涯究竟能走多远,我深表怀疑。
真的非常钦佩Randall Hyde多年如一日孜孜于《编程卓越之道》系列的写作,使之成为计算机图书中不朽的经典。而作者并不满足已经取得的成就,推陈出新,出版了本书的第2版。第2版加入了新鲜的元素,却又不损经典质量的一分一毫。如果你刚刚踏上编程之旅,我强烈推荐你阅读本书。正所谓“磨刀不误砍柴工”,这些底层原理和底层细节,看似对你的开发没有直接帮助,但它真的可能会决定你未来的高度!是为推荐序。
——《解构领域驱动设计》作者 张逸
译者序
回顾21世纪初以来计算机产业的发展,移动互联网的普及一定是绕不开的话题。计算机的性能按照摩尔的预测每18个月就提升一倍,计算机中的集成电路体积反而越来越小。从个人计算机进入手机、嵌入式设备时代,终端变得无处不在。网络技术的发展让终端能力可以近乎无限地扩展。
随着计算机性能的提升和应用的扩展,软件的规模和复杂度也在呈指数级增长,开发工作面临的挑战也越来越大。不断出现的新的高级编程语言通过先进的语法特性和编程范式来简化软件开发者的工作。利用这些高级编程语言提供的抽象技术,编写代码这项活动越来越接近人类对问题的分析和描述,与计算机内部的运行机制渐行渐远。我们对卓越代码的追求似乎过于重视优雅地让人理解代码背后的意图,逐渐忽略了代码在计算机上的运行效率,所以才有了对安迪比尔定律的吐槽:新软件总是会耗尽新硬件提升的全部计算能力。笔者作为一名移动应用开发者,对于应用动辄成百上千兆的体积和一段时间后磕磕跘跘的体验,着实汗颜。
好在计算机的基本组成在这20年中并没有发生根本性的变化。由中央处理器、存储、输入/输出设备构成的冯·诺依曼体系结构目前仍然是计算机界的绝对主流。本书的第1版于21世纪初面世,文笔浅显易懂,代码示例详尽,同时避免了晦涩难懂的汇编语言,是一部介绍计算机体系结构的佳作。现在本书第2版的出版恰逢其时,提醒我们不要忘记卓越的代码一定也是高效的。在保留第1版深入浅出特点的同时,作者对过去这些年计算机体系结构的发展和新兴的设备进行了总结,对原有的内容进行了删减和增补。第2版中的示例代码也采用近些年涌现出来的高级编程语言进行了重写,让年轻的读者朋友读起来更加亲切。阅读本书了解代码背后的运行原理,进而在编写代码时做出正确的选择,未为晚矣。
本书打开了笔者的记忆,仿佛又回到了大学时代学习计算机组成原理、模拟和数字电路的时光。有了第1版翻译的珠玉在前,第2版的翻译工作笔者不敢怠慢。一些当时新鲜的概念现在已成了业界主流,因此在第2版的翻译中对部分译法进行了更新。笔者也期望像作者那样与时俱进,但百密终有一疏,翻译中出现的错误也请读者们海涵并斧正。
最后,感谢在背后支持笔者完成翻译工作的家人和朋友们!
——覃宇