【书籍心得】左耳听风:传奇程序员练级攻略

在阅读该篇文章前,先向咱们的传奇程序员:陈皓(耗哥)致敬!!!

  • 不要乱买书,不要乱追新技术、新名词。基础知识需要长时间去积累,因为它们至少在未来 10 年内仍然通用。
  • 回顾历史,厘清技术发展的时间线,才能预测技术发展的方向。
  • 一定要动手实践,即使例子很简单,也要自己动手编写一遍,并确保理解了其中的细节。
  • 学会思考,思考为什么要这样做,而不是那样做,还要能够举一反三。

你也许会不理解,为什么下面的内容侧重 UNIX/Linux 操作系统。这是因为,基于如下原因,Windows 操作系统下的编程在未来可能没有前途

  1. 现在的用户界面几乎被 Web 和 iOS/Android 移动平台主宰,Windows 的图形界面没那么受欢迎了。
  2. 越来越多的企业使用成本低且性能高的 Linux 和各种开源技术来构建系统,而 Windows 的成本太高了。
  3. 微软的产品变化太快,版本不够持久,程序员的节奏容易被变化所影响。

因此,我个人认为,未来前端的编程方向是 Web + 移动,后端的编程方式是 Linux + 开源。开发领域基本上没有 Windows 什么事情了。

有一个程序员的样子

1. 学习一门脚本语言

学习一门脚本语言,例如 Python 或 Ruby,可以让人摆脱对底层语言的恐惧。脚本语言实在太方便了,下面这些马上就能用来解决问题的小程序,用非脚本语言来编写非常不便,用脚本语言则可以快速实现。而且,还能顺便学会 Print 这类简单直接的调试方式。

  • 处理文本文件或 CSV 文件(如 Python CSV、Python Open、Python
    Sys)的工具,可读取本地文件,并对其逐行处理(例如单词计数或日志处理)。
  • 遍历本地文件系统(sys、os、path)的程序,可统计一个目录下所有文件的信息,并按各种条件排序和保存结果。
  • 与数据库(Python SQLite)交互的小脚本,可统计数据库里的数据条目数。

2. 掌握一种主流编辑器(非 IDE)和一系列基本工具

使用这些工具不是为了炫耀,而是因为这些编辑器可以帮你更快捷、高效地查看和修改代码、配置文件和日志。比如,掌握 Vim、Emacs、Notepad++,学会配置代码补全、外部命令等,Source Insight 或 ctags 62也需要熟悉。

3. 熟悉 UNIX/Linux Shell 和常见的命令行

对于程序员来说,虽然 UNIX/Linux 操作系统比 Windows 操作系统简单得多,但是 UNIX/Linux 的图形界面并不好用,有些情况下用 UNIX/Linux 操作系统会大大降低工作效率。对此,我给出以下建议:

  • 如果使用 Windows 操作系统,至少要学会使用虚拟机运行 Linux。VMware Player 是免费的,也可以安装 Ubuntu 等其他的 Linux 发行版操作系统。
  • 尽量少用图形界面。
  • 学会使用 man 命令来查看帮助文档。
  • 学习文件系统的结构和基本操作,如 ls、chmod、chown、rm、find、ln、cat、mount、mkdir、tar、gzip 等。
  • 学会使用一些文本操作命令,如 sed、awk、grep、tail、less、more 等。
  • 学会使用一些管理命令,如 ps、top、lsof、netstat、kill、tcpdump、iptables、dd 等。
  • 了解 /etc 目录下的各种配置文件,学会查看 /var/log 下的系统日志及 /proc 下的系统运行信息。
  • 了解正则表达式,学会使用它来查找文件。
  • 尽量少用图形界面。
  • 学会使用 man 命令来查看帮助文档。
  • 学习文件系统的结构和基本操作,如 ls、chmod、chown、rm、find、ln、cat、mount、mkdir、tar、gzip 等。
  • 学会使用一些文本操作命令,如 sed、awk、grep、tail、less、more 等。
  • 学会使用一些管理命令,如 ps、top、lsof、netstat、kill、tcpdump、iptables、dd 等。
  • 了解 /etc 目录下的各种配置文件,学会查看 /var/log 下的系统日志及 /proc 下的系统运行信息。
  • 了解正则表达式,学会使用它来查找文件。

4. 学习 Web 基础(HTML/CSS/JavaScript)和服务器端技术(LAMP)

未来必然是 Web 的世界,以下是入门阶段的学习建议。

  • 养成浏览 W3School 网站的习惯。
  • 学习 HTML 的基本语法。
  • 学习 CSS,尽量掌握如何选中 HTML 元素,以及如何应用一些基本样式(关键词是 box model)。
  • 学会用 Firefox+Firebug 或 Chrome 来查看优秀的网页结构并进行动态修改。
  • 学习使用 JavaScript 操纵 HTML 元素,理解 DOM 和动态网页。
  • 学会用 Firefox + Firebug 或 Chrome 来调试 JavaScript 代码(设置断点,查看变量、性能、控制台等)。
  • 能在一台机器上配置 Apache 服务器。
  • 学习 PHP,让后台 PHP 和前台 HTML 进行数据交互,对服务器响应浏览器请求形成初步认识,实现表单提交和反显的功能。
  • 把 PHP 连接到本地或者远程数据库 MySQL,实现 MySQL 和 SQL 语言的现用现查。
  • 学完一门源自名校的网络编程课程。不要觉得总课时长,用业余时间一定可以跟上。
  • 学习 JavaScript 库(如 jQuery 或 ExtJS)、Ajax(异步读入服务器端图片或数据库内容),以及 JSON 数据格式。
  • 读完 HTTP: The Definitive Guide 的前4章,了解用浏览器上网的时候发生了什么。
  • 开发一个小型网站。例如一个简单的留言板,支持用户登录,Cookie/Session,增、删、改、查,上传图片附件和分页显示。
  • 买一个域名,租一个空间,做一个自己的正式网站。

绕不开的硬核技术

1. C 语言和操作系统调用

重新学习 C 语言,理解指针和内存模型,并使用 C 语言实现各种经典算法和数据结构。学习建议如下:

  • 学习麻省理工学院的免费课程:计算机科学和编程导论、C 语言内存管理。
  • 学习 UNIX/Linux 的系统调用(可参考《UNIX 高级环境编程》),了解系统层面的知识:基于操作文件系统和用户,实现一个可以拷贝目录树的小程序;用 fork/wait/waitpid 编写多进程程序,用 pthread 编写带有同步或互斥关系的多线程程序,编写一个多进程的购票程序;用signal/kill/raise/alarm/pause/sigprocmask 实现多进程间基于信号量的通信程序;学会用 gcc 和 gdb 等编译和调试工具;学会用 makefile 来编译文件;在高级编程中实践 IPC 和 Socket 的知识。
  • 学习 Windows SDK 编程:编写一个窗口,了解 WinMain/WinProcedure 和 Windows 的消息机制;编写操作 Windows SDK 中的资源文件或各种图形控件的程序,并进行图形编程;学习使用 MSDN 来查看相关的 SDK 函数、各种 WM_消息及一些例程;不要抄袭书中的例程,试着编写自己的例程。由于 GUI 正被 Web 取代,因此了解 Windows 图形界面的编程即可,但做移动开发需要理解 GUI 的工作原理。

2. Java 语言

学习建议如下:

  • 学习 JDK,掌握 Java API Doc 的使用方法。
  • 了解 Java 这种虚拟机语言和 C 语言、Python 语言在编译和执行上的区别,思考"跨平台"在 C 语言、Java 语言、Python 语言中的应用。
  • 学会使用 Eclipse 等 IDE 来编译、调试和开发 Java 程序。
  • 搭建 Tomcat 网站,尝试用 JSP/Servlet/JDBC/MySQL 进行 Web 开发。尝试用 JSP 和 Servlet 来实现前面提到的 PHP 小项目。

3. Web 安全与架构

学习建议如下:

  • 关注 Web 开发的安全问题。
  • 学习 HTTP Server 的 Rewrite 机制、Nginx 的反向代理机制,Fast CGI 及其实现程序 PHP-FPM;学习 Web 的静态页面缓存技术;学习 Web 的异步工作流、数据 Cache、数据分区、负载均衡、水平扩展的构架。
  • 完成实践任务:利用 HTML5 的 Canvas 制作 Web 动画;尝试对自己开发的 Web 应用进行 SQL 注入、JavaScript 注入及 XSS 攻击;将 Web 应用改为基于 Nginx、PHP-FPM 和静态页面缓存的网站。

4. 关系数据库

学习建议如下:

  • 学习安装 MSSQLServer 或 MySQL 数据库。
  • 学习教科书里的数据库设计范式,如 1NF、2NF、3NF 等。
  • 学习数据库的存储过程、触发器、视图、索引创建等。
  • 学习 SQL 语句,了解表连接的各种概念。
  • 学习如何优化数据库查询。
  • 完成实践任务:设计一个论坛数据库,使用 3NF 设计范式,要求可用 SQL 语句查询本周或本月的最新文章、评论最多的文章、最活跃的用户。

5. 开发工具

学习建议如下:

  • 学会用 SVN 或 Git 来管理程序版本。
  • 学会用 JUnit 来对 Java 进行单元测试。
  • 学习 C 语言和 Java 语言的编程规范或编程准则。

编程知识图谱

我个人认为,要是能学好 C++,学好 Java 就不在话下,理解面向对象编程也是水到渠成的事情,然后就可以深入掌握系统的高级知识了。

1. C++ / Java 语言和面向对象

虽然 C++的学习曲线相当陡峭,但从某种角度来看,它是目前程序员最应该学好的语言。学习 C++的路径如下。

  • 学习麻省理工学院的免费课程"C++面向对象编程",阅读《C++ Primer》《Effective C++》等经典书至少两遍,对 C++的理解要达到较深的程度。
  • 思考 C++的发明者为什么要这样设计 C++,对比 Java 和 C++的不同之处,比如初始化、垃圾回收、接口、异常、虚函数等。
  • 用 C++实现一个 BigInt,支持 128 位的整型加减乘除操作;用 C++封装一个数据结构的容器,比如 Hash Table;用 C++封装并实现一个智能指针,一定要使用模板。
  • 思考 23 种设计模式的应用场景。比如,为什么推崇组合而不是继承,为什么推崇接口而不是实现。
  • 用工厂模式实现一个内存池;使用策略模式制造一个类,要求其可实现文本文件的左对齐、右对齐和中对齐;使用命令模式实现一个命令行计算器,要求支持 Undo 和 Redo;使用修饰模式为酒店实现定价策略,要考虑淡旺季、服务水平、VIP 服务、旅行团服务等影响价格的因素。
  • 学习 STL 的用法及其设计理念,如容器、算法、迭代器、函数子,尽量阅读源码。
  • 尝试用面向对象、STL、设计模式和 Windows SDK 图形编程等各种技能来做一个贪吃蛇或俄罗斯方块游戏,要支持不同的级别和难度。或者做一个文件浏览器,可以浏览目录下的文件,并可以对不同文件执行不同操作;且该文件浏览器可以编辑文本文件,直接执行可执行文件,播放 MP3 或 AVI 文件,以及显示图片文件。
  • 学习 C++的一些类库的设计,如 MFC、Boost、ACE、CPPUnit、STL。
  • 通过 Java 学习面向对象的设计模式,因为 Java 是真正的面向对象编程语言,其中的设计模式也数不胜数。
  • 学习 Spring、Hibernate、Struts 等 Java 框架,从而理解 IoC 等设计思想。
  • 重点学习 J2EE 架构及 JMS、RMI 等消息传递技术和远程调用技术。
  • 学习使用 Java 来做 Web Service。
  • 尝试在 Spring 或 Hibernate 框架下构建一个基于网络 Web Service 的远程调用程序,要支持在两个 Service 之间通过 JMS 传递消息。

学好 C++和 Java 都需要时间。深入研究 C++需要花费更多时间,而学习 Java 则需要广泛涉猎。建议选择其中一门进行深入学习,如有精力,建议深入研究 C++,同时学习 Java 的各种设计模式。

2. 加强对系统的了解

除了阅读《UNIX 编程艺术》,了解 UNIX 设计和开发的思想、原则与经验,理解 TCP、UDP 等网络编程知识,掌握以太网、TCP/IP 协议的运行原理及 TCP 的调优,还要完成以下任务。

  • 理解阻塞(同步 I/O)、非阻塞(异步 I/O)、多路复用(Select、
    Poll、Epoll 机制)的 I/O 技术;编写一个网络聊天程序,要求有聊天服务器和多个聊天客户端,且服务器端用 UDP 对部分或所有聊天客户端进行 Multicast 或 Broadcast 操作;编写一个简易的 HTTP 服务器程序;了解信号量、管道、共享内存、消息等 IPC 概念。
  • 重点实践各种 IPC 进程间通信的方法;编写一个管道程序,支持父子进程通过管道交换数据;编写一个共享内存的程序,要求两个进程通过共享内存交换一个 C 语言的结构体数组。
  • 掌握 CreateProcess、Windows 线程、线程调度、线程同步(Event、信号量、互斥量)、异步 I/O、内存管理、DLL 等要点。
  • 用 CreateProcess 启动记事本或 IE 浏览器,并监控其运行。将之前编写的简易 HTTP 服务器改为线程池模式。编写一个 DLL 钩子程序,监控指定窗口的关闭事件或记录某个窗口的按键。
  • 在掌握了多线程与多进程通信、TCP/IP、套接字、C++与设计模式的基本知识后,可以研究 ACE 编辑器。用 ACE 重写上述聊天程序和 HTTP 服务器程序(带线程池)。
  • 编写一个服务器端程序,向客户端传输大文件,要求将 100M 的带宽利用率提高到 80%以上。注意,磁盘 I/O 和网络 I/O 可能会出现问题,请考虑如何解决,并且注意网络的最大传输单元 MTU。了解 BT 下载的工作原理,用多进程模拟 BT 下载的原理。

3. 系统架构

系统架构涉及如下核心技术。

  • 负载均衡:HASH 式、纯动态式。
  • 多层分布式系统:客户端服务节点层、计算节点层、数据 Cache 层和数据层。J2EE 是经典的多层架构。
  • CDN 系统:就近访问、内容边缘化。
  • P2P 式系统:研究 BT 和电驴的算法,如 DHT。
    左耳听风:传奇程序员练级攻略
  • 服务器备份:了解双机备份系统(Live-Standby 和 Live-Live),两台机器如何通过心跳监测对方,以及如何备份集群的主节点。
  • 虚拟化技术:可像操作系统虚拟化一样用来切换或重新配置、部署应用程序。
  • Thrift:一种二进制的高性能通信中间件,支持数据(对象)序列化和多种类型的 RPC 服务。
  • Hadoop 框架核心的 MapReduce 计算机和 HDFS 文件系统:MapReduce 是任务的分解与结果的汇总,HDFS(Hadoop Distributed File System)为分布式计算存储提供了底层支持。
  • NoSQL 数据库:MemcacheDB、Redis、Tokyo Cabinet(升级版为 Kyoto Cabinet)、Flare、MongoDB、CouchDB、Cassandra、Voldemort 等。由于超大规模及高并发的纯动态网站成为主流,同时 SNS 网站在数据存取过程中有实时性的刚性需求,因此 NoSQL 数据库正在取代关系数据库并逐渐成为主流数据库。

要学的技术真不少,要认真思考后再做选择。而且攻略里提到的都是久经考验的基础技术,只要学会就能找到心仪的工作。在互联网或 IT 领域,无论是打工还是创业,要想让自己和公司更值钱,技术实力首当其冲。

但技术毕竟是工具,不应该过度痴迷它,更不要"死读书",要不时抬起头来看看技术以外的世界。比如,在关注如何使用技术的同时,还要琢磨某项技术为什么会出现并胜出。

高效学习的八种方法

好的学习方法,既要有效,也要高效。我相信只要你和我一样学会用下面的学习方法,你的学习效率一定能够迅速提升。

1. 挑选知识和信息源

在计算机领域,英文知识更接近可靠的信息源。因此,建议用英文关键词查找想要了解的知识,最好能在官方或主流技术社区里和专家直接交流。

在我看来,可靠的信息源应该具备以下几个特质。

  • 应该是一手资料,而不是被别人解释或消化过的二手资料。知识性内容更是如此,应该是原汁原味的,而不是被夸大、粉饰的。
  • 应该有佐证、数据和引用,或者有权威人士、大公司的"背书"。
  • 应该经过时间和实践的检验,或者有小心求证的过程,而不是出自凭空想象。
  • 应该有较高的信息密度,能发人深思,如 Medium 上的文章。
    我经常推荐自己读过的好文章。这些文章是可靠的信息源,质量上乘,不需要我再做解读。我在文章底部添加的大量引用,也是一条学习线路。我希望通过简单的链接为读者打开一个全新的世界,而不是让他们始终需要依赖我,因为那个广阔的世界每天都会产生很多最新、最酷、最有营养的一手资料。

3. 使用知识地图

2000 年我离开昆明开始"沪飘"。刚到上海时我找不到合适的工作,只能埋头学习。但书太多了,根本看不过来。我发现,死记硬背这种使蛮力的方法,很难让人在短时间内学到很多知识。

于是我发明了"联想记忆法",比如,我将《C++ Primer》这本近千页的书分成三部分。

  • C++ 用什么技术来解决 C 语言的问题,包括指针、宏、错误处理、数据拷贝等方面的问题。
  • C++ 的面向对象特性:封装、继承、多态。封装让我想到构造函数、析构函数等,构造函数让我想到依次初始化列表、默认构造函数、拷贝构造函数、new;多态让我想到虚函数、RTTI,进而想到 dynamic_cast 和 typeid 等。
  • C++ 的泛型编程。它让我想到 template、操作符重载、函数对象、STL、数据容器、iterator 和通用算法,等等。

顺藤摸瓜,从知识树的主干开始做广度或深度遍历,我就得到了一整棵知识树。这种记忆方法让我记住了很多知识。最重要的是,当出现一些我不知道的知识点时,我就会把它往知识树上挂,将其纳入我的学习系统,以方便理解和记忆。

在知识的海洋遨游需要一张地图。学习就是为了找到这张地图,因为这张地图中已经标明了通往所有答案的路径。

7. 实践出真知

学以致用,空谈误国。实践过才能深入理解所学的知识。初看《Effective C++》和《More Effective C++》这两本书时,我只是叹服作者不断推翻自己的求知精神,直到积累了很多实践经验和教训,我才真正地理解了实践的真义。这两本书并不厚,但我看了十多年,甚至可以背诵里面的很多章节。我真正想要掌握的不是其中的知识,而是宝贵的思维方式。

"实践出真知"对应的英文表达是"Eat your own dog food."。"只有吃自己做的狗粮",才能真正了解软件的使用情况。有些开发人员写完代码却不进行测试和维护,这样如何能够理解什么是好的设计和好的软件?如果不用自己的产品,"不养育自己的孩子",就感受不到痛苦,也不会有改进的想法;没有改进的压力,也就不会有学习的动力;不学习就没有进步;没有进步就只能继续开发糟糕的软件。这是一种常见的恶性循环。

成长的痛苦很大程度上来自实践,但只有痛苦才会让人反思,而反思最终决定了成长的高度。

上层的 Java NIO、Nginx 或 Node.js 等如何发展,都无法摆脱最底层的限制。这些知识对于将理论应用于实际项目或解决实际问题至关重要,比如编程时与系统交互、获取操作系统资源、实现通信,以及解决性能问题、修复故障。

编程语言

这里推荐 C/C++、Java、Go 这几种语言的学习建议。以下推荐的学习资料有助于我们学习编程语言,包括多本经典教材和在线资源。

1. Java 语言

学习以下与 Java 语言相关的入门图书(注意:下面的图书在入门篇中有所提及,但为了完整性,还是要在这里提一下,因为有的读者可能会选择性地阅读某部分)。

《Java 核心技术·卷 1:基础知识》是 Sun 公司的官方用书,是一本 Java 入门参考书。对于 Java 初学者来说,该书是一本非常不错且值得时常翻阅的技术手册,书中有较多地方将 Java 与 C++ 做比较,这是因为 Java 面世的时候,又被叫作"C++ 杀手"。我在看这本书的时候,发现书中有很多 C++ 的知识,于是去学习了 C++。学习 C++ 的时候,发现有很多 C 的知识看不懂,又顺着去学习了 C。然后,"C→C++→Java"整条学习线路融会贯通,这对我未来的技术成长有非常大的帮助。

Java 的 Spring 框架是你无法回避的,所以有了上述的入门之后,接下来是两本与 Spring 相关的书------《Spring 实战》和《Spring Boot 实战》。前者是传统的 Spring,后者是新式的微服务 Spring,如果你只想看一本,那么就看后者吧。

以上几本图书可以帮助你入门 Java,但如果想要进一步成长,就需要看以下几本进阶图书了。

首先,你需要了解如何编写高效的代码,因此必须看一下 Effective Java (注意,这里我给的引用是原书第三版,也就是 2017 年年末出版的那一版)。这本书模仿了 Scott Meyers 的经典图书 Effective C++ 的。这两本书中的内容都是技术大师的各种经验之谈,非常不错,你一定要读。此处再推荐一下 Google Guava 库,其中核心库有:集合(Collections)、缓存(Caching)、原生类型支持(Primitives Support)、并发库(Concurrency Libraries)、通用注解(Common Annotations)、字符串处理(String Processing)、I/O 等。它不仅是 JDK 的升级库,而且还是 Effective Java 这本书中作者最佳实践经验的代表。

《Java 并发编程实战》是一本完美的 Java 并发参考手册。该书从并发性和线程安全性的基本概念出发,介绍了以下几点:如何使用类库提供的基本并发构建块,将其用来避免并发危险、构造线程安全的类及验证线程安全的规则;如何将小的线程安全类组合成更大的线程安全类;如何利用线程来提高并发应用程序的吞吐量;如何识别可并行执行的任务;如何提高单线程子系统的响应性;如何确保并发程序执行预期任务;如何提高并发代码的性能和可伸缩性;等等。最后,书中介绍了一些高级主题,如显式锁、原子变量、非阻塞算法,以及如何开发自定义的同步工具类。

了解如何编写并发程序后,你还需要了解如何优化 Java 的性能。对此,我推荐《Java 性能权威指南》。通过学习这本书,你可以大幅提升性能测试的效果。其中内容包括:使用 JDK 中自带的工具收集 Java 应用的性能数据;理解 JIT 编译器的优缺点;调优 JVM 垃圾收集器,以减少其对程序的影响;学习管理堆内存和 JVM 原生内存的方法;了解如何最大程度地优化 Java 线程及同步的性能;等等。看完这本书后,如果你还有余力且想了解更多的底层细节,那么,你有必要读一下《深入理解 Java 虚拟机:JVM 高级特性与最佳实践》。

《Java 编程思想》是一本透着编程思想的书。上面提到的书让你从微观角度了解 Java,而这本书则可以让你从宏观角度了解 Java。这本书和《Java 核心技术·卷 1:基础知识》的厚度差不多,但信息密度比较大。因此,读此书非常耗费脑力,它会让你不断思考。对于想要学好 Java 的程序员来说,这是一本必读的书。

《精通 Spring 4.x》也是一本很不错的书,虽然它有点厚,一共有800多页,但内容都是干货。其中最不错的是分析原理,尤其是针对前面提到的 Spring 技术,把应用与原理都讲得很透彻,IoC 和 AOP部分的分析也很棒,娓娓道来。对于任何一项技术,该书都做了细致和全面的介绍。不足之处是内容太多,导致书很厚,但这并不影响它是一本不错的工具书。

当然,学习 Java 时你必须学习面向对象的设计模式。这里有一本经典的书《设计模式》推荐给你。不过,如果你觉得这本书有些难度,可以看一下《Head First 设计模式》。在学习面向对象的设计模式时,你不要迷失在那 23 种设计模式中,而要明白这两个原则:

"Program to an interface, not an implementation."

使用者不需要知道数据类型、结构、算法的细节,也不需要知道实现细节,只需要知道提供的接口。这对抽象、封装、动态绑定和多态有利,符合面向对象的特征和理念。

"Favor object composition over class inheritance."

继承要求给子类暴露一些父类的设计和实现细节。父类实现的改变会影响到子类,因此,在子类中需要重新实现很多父类的方法。我们认为继承主要是为了代码重用,但实际上更多的是为了多态。

2. C/C++语言

与我入行时相比,现在几乎所有的软件都不必使用 C 语言编写。一方面,高级语言如 Java 语言和 Python 语言为你屏蔽了很多底层细节;另一方面,新兴语言如 Go 语言可以让你更轻松地编写高性能的软件。然而,我仍然认为,C 语言是你必须学习的语言,因为世界上绝大多数编程语言都是类似于 C 的语言,它们用不同的方式解决 C 语言的各种问题。在这里,我要说一句武断的话------如果你不学习 C 语言,你根本没有资格称自己为合格的程序员!

我特别推荐已故的 C 语言之父 Dennis M. Ritchie 和著名科学家 Brian W. Kernighan 合作的经典教材《C 程序设计语言》。请注意,这本书是 C 语言的发明者编写的,其中的 C 语言标准不是我们平时所说的 ANSI 标准,而是原作者的标准,也被称为 K&R C。这本书很薄,简洁明了,不枯燥,你可以拿着它躺在床上看,看着看着就睡着了。

此外,还有一本非常经典的 C 语言书籍------《C 语言程序设计:现代方法》。有人说,这本书可搭配之前的 The C Programming Language。但我想说,这本书更实用、更厚,完整覆盖了 C99 标准,并且习题的质量和水平也比较高。更重要的是,本书探讨了现代编译器的实现,以及 C++ 的兼容性,还揭穿了各种古老的 C 语言神话和信条......是一本干货相当多的 C 语言学习图书。

另外,个人不建议看谭浩强老师的 C 语言图书,因为其中存在一些瑕疵。我在大学时就是用这本书学习的 C 语言,后来发现它并不能适应我个人在工作中的需求。

在学习 C 语言的过程中,你一定会发觉 C 语言不仅是底层语言,而且其代码经常性地崩溃。经过一段时间的挣扎,你才开始发现自己快从这个"烂泥坑"里爬出来了。但你还需要看看《C 陷阱与缺陷》这本书,看了以后你会发现,C 语言里面的陷阱非常多。

此时,假如你看过我的"编程范式游记"系列文章,你可能会发现 C 语言在泛型编程上存在各种问题。这个时候,我推荐你学习一下 C++ 语言。可能会有很多人觉得 C++ 是一门很难"啃"的语言,是的,可以说它是世界上目前来说最复杂也是最难的编程语言了。但是,不可忽视的是,C++ 是目前世界上范式最多的语言,其中最好的范式就是"泛型编程"。在静态语言中,这绝对是划时代的事情。

因此,你有必要学习一下 C++,看看 C++ 是如何解决 C 语言中的各种问题的。你可以先看看我的这篇文章"C++ 的坑真的多吗?",对 C++有一个基本认识。下面推荐几本关于 C++ 的图书。

《C++ Primer 中文版》是久负盛名的 C++ 经典教程。这本书有点厚,前面 1/3 的内容讲 C 语言,后面讲 C++。C++ 的知识点实在是太多了,而且有点晦涩。但是你只需要看几个点,一个是面向对象的多态,一个是模板和重载操作符,以及一些 STL 的知识。通过这本书,你可以看看 C++ 是怎么"玩"泛型和函数式编程的。

如果你想继续研究,你需要看另外两本更为经典的书------Effective C++More Effective C++。这两本书不厚,但是我读了 10 多年,每隔一段时间再读一下,就会发现有更多的收获。你会发现,随着你阅历的增长,这两本书的内容也变得丰富起来,可能这就是"常读常新"。它们也是对我影响最大的两本书,其中影响最大的不是书中那些有关 C++的内容,而是作者的思维方式和不断求真的精神,这真是太赞了。

学习 C/C++ 都需要好好了解编译器到底做了什么,就像学习 Java 需要先了解 JVM 一样。因此,这里还有一本非常难"啃"的书,你可以挑战一下《深度探索 C++ 对象模型》。这本书的内容非常经典,看完后,C++ 对你来说就再也没有什么秘密可言了。我以前写过的《C++ 虚函数表解析》和《C++ 对象内存布局》也属于这个范畴。

另外,《C++ 程序设计语言》的作者 Bjarne Stroustrup 写的 C++ FAQ 文档也是非常值得一读的。

3. Go 语言

C 语言相对而言比较原始,C++ 语言过于复杂,Go 语言是最佳选择。有了 C/C++ 作为基础,学习 Go 语言就变得非常容易。

推荐以 Go by Example 程序实践介绍页面作为入门教程。Go 101也是一本不错的在线电子书。如果你喜欢纸质书籍,The Go Programming Language 是不错的选择,它的评分为 9.2 分,但国内没有销售。(当然,我之前也写过两篇入门文章供参考:"GO 语言简介(上)------语法"和"GO 语言简介(下)------特性"。)

此外,Go 语言官方的"Effective Go"是必读的,这篇文章介绍了如何更好地使用 Go 语言和 Go 语言的一些原理。

Go 语言最突出的特点是并发编程。UNIX 老牌黑客罗勃·派克(Rob Pike)在 Google I/O 上分享了两个并发编程模式的演讲,你可以从中学到一些东西。

  • Go Concurrency Patterns(幻灯片、演讲视频)。
  • Advanced Go Concurrency Patterns(幻灯片、演讲视频)。

此外,Go 在 GitHub 的官方维基站点上有许多不错的学习资源。比如:

  • Go 精华文章列表。
  • Go 相关博客列表。
  • Go Talks。

另外,内容丰富的 Go 资源列表 Awesome Go 也值得一看。

在编程语言方面,我推荐学习 C、C++、Java 和 Go 四门语言,并分别阐释了推荐的原因。

我认为,C 语言是必须学习的语言,因为世界上绝大多数编程语言都是"C-like"的语言,它们在不同的方面解决了 C 语言的各种问题。

虽然 C++ 很复杂、难学,但它几乎是目前世界上范式最多的语言。它最出色的特点是"泛型编程",这在静态语言中是一件绝对划时代的事情。尤其要看看 C++ 是如何解决 C 语言中的各种问题的。

我认为 Java 是综合能力最强的一门语言。实际上,我先学了 Java,然后学了 C++,最后学了 C 语言。"C→C++→Java"整条学习线路融会贯通,这对我未来的技术成长有非常大的帮助。我还推荐了 Go 语言,并提供了相关的学习资料。

一名合格的程序员应该掌握几门编程语言。一方面,你学习不同的语言时会对它们有所比较,这会让你有更多的思考。另一方面,掌握多门编程语言是对学习能力的培养,会让你在学习未来的新技术时学得更快。

相关推荐
喝养乐多长不高1 小时前
JAVA微服务脚手架项目详解(三)
java·大数据·微服务·文件·地图·oss
万邦科技Lafite2 小时前
1688图片搜索商品API接口(item_search_img)使用指南
java·前端·数据库·开放api·电商开放平台
落落落sss2 小时前
java实现排序
java·数据结构·算法
czhc11400756632 小时前
c# 1121 构造方法
java·javascript·c#
io_T_T2 小时前
Paddle-CLS图像分类_环境安装
python·日常软硬件经验分享
Z***25802 小时前
Java爬虫框架
java·开发语言·爬虫
晓华-warm2 小时前
Warm-Flow 1.8.4 票签新增多种通过率策略!
java·中间件·流程图·jar·开源软件·工作流
m***11902 小时前
【SpringBoot】Spring Boot 项目的打包配置
java·spring boot·后端
李慕婉学姐2 小时前
Springboot剪纸数字博物馆系统6wd19a3a(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·spring boot·后端