<audio id="audio" title="73 | 程序员练级攻略：编程语言" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/88/74/884383b3b59c2e74e2a9dd46c5d59374.mp3"></audio>

为了进入专业的编程领域，我们需要认真学习以下三方面的知识。

**编程语言**。你需要学习C、C++和Java这三个工业级的编程语言。为什么说它们是工业级的呢？主要是，C和C++语言规范都由ISO标准化过，而且都有工业界厂商组成的标准化委员会来制定工业标准。次要原因是，它们已经在业界应用于许多重要的生产环境中。

<li>
C语言不用多说，现今这个世界上几乎所有重要的软件都跟C有直接和间接的关系，操作系统、网络、硬件驱动等等。说得霸气一点儿，这个世界就是在C语言之上运行的。
</li>
<li>
而对于C++来说，现在主流的浏览器、数据库、Microsoft Office、主流的图形界面、著名的游戏引擎等都是用C++编写的。而且，很多公司都用C++开发核心架构，如Google、腾讯、百度、阿里云等。
</li>
<li>
而金融电商公司则广泛地使用Java语言，因为Java的好处太多了，代码稳定性超过C和C++，生产力远超C和C++。有JVM在，可以轻松地跨平台，做代码优化，做AOP和IoC这样的高级技术。以Spring为首的由庞大的社区开发的高质量的各种轮子让你只需关注业务，是能够快速搭建企业级应用的不二之选。
</li>

此外，我推荐学习Go语言。一方面，Go语言现在很受关注，它是取代C和C++的另一门有潜力的语言。C语言太原始了，C++太复杂了，Java太高级了，所以Go语言就在这个夹缝中出现了。这门语言已经10多年了，其已成为云计算领域事实上的标准语言，尤其是在Docker/Kubernetes等项目中。Go语言社区正在不断地从Java社区移植各种Java的轮子过来，Go社区现在也很不错。

如果你要写一些PaaS层的应用，Go语言会比C和C++更好，目前和Java有一拼。而且，Go语言在国内外一些知名公司中有了一定的应用和实践，所以，是可以学习的（参看：《[Go语言、Docker 和新技术](https://coolshell.cn/articles/18190.html)》一文）。此外，Go语言语法特别简单，你有了C和C++的基础，学习Go的学习成本基本为零。

**理论学科**。你需要学习像算法、数据结构、网络模型、计算机原理等计算机科学专业需要学习的知识。为什么要学好这些理论上的知识呢？

<li>
其一，这些理论知识可以说是计算机科学这门学科最精华的知识了。说得大一点，这些是人类智慧的精华。你只要想成为高手，这些东西是你必需要掌握和学习的。
</li>
<li>
其二，当你在解决一些很复杂或是很难的问题时，这些基础理论知识可以帮到你很多。我过去这20年从这些基础理论知识中受益匪浅。
</li>
<li>
其三，这些理论知识的思维方式可以让你有触类旁通，一通百通的感觉。虽然知识比较难啃，但啃过以后，你将获益终生。
</li>

另外，你千万不要觉得在你的日常工作或是生活当中根本用不上，学了也白学，这样的思维方式千万不要有，因为这是平庸的思维方式。如果你想等我用到了再学也不晚，那么你有必要看一下这篇文章《[程序员的荒谬之言还是至理名言？](https://coolshell.cn/articles/4235.html)》。

**系统知识**。系统知识是理论知识的工程实践，这里面有很多很多的细节。比如像Unix/Linux、TCP/IP、C10K挑战等这样专业的系统知识。这些知识是你能不能把理论应用到实际项目当中，能不能搞定实际问题的重要知识。

当你在编程的时候，如何和系统进行交互或是获取操作系统的资源，如何进行通讯，当系统出了性能问题，当系统出了故障等，你有大量需要落地的事需要处理和解决。这个时候，这些系统知识就会变得尤为关键和重要了。

这些东西，你可以认为是计算机世界的物理世界，上层无论怎么玩，无论是Java NIO，还是Nginx，还是Node.js，它们都逃脱不掉最下层的限制。所以，你要好好学习这方面的知识。

# 编程语言

## Java语言

学习Java语言有以下**入门级的书**（注意：下面一些书在入门篇中有所提及，但为了完整性，还是要在这里提一下，因为可能有朋友是跳着看的）。

<li>
《[Java核心技术：卷1基础知识](https://book.douban.com/subject/26880667/)》，这本书本来是Sun公司的官方用书，是一本Java的入门参考书。对于Java初学者来说，是一本非常不错的值得时常翻阅的技术手册。书中有较多地方进行Java与C++的比较，因为当时Java面世的时候，又被叫作&quot;C++ Killer&quot;。而我在看这本书的时候，发现书中有很多C++的东西，于是又去学习了C++。学习C++的时候，发现有很多C的东西不懂，又顺着去学习了C。然后，C -&gt; C++ -&gt; Java整条线融汇贯通，这对我未来的技术成长有非常大的帮助。
</li>
<li>
有了上述的入门后，Java的Spring框架是你玩Java所无法回避的东西，所以接下来是两本Spring相关的书，《[Spring实战](https://book.douban.com/subject/26767354/)》和《[Spring Boot实战](https://book.douban.com/subject/26857423/)》。前者是传统的Spring，后者是新式的微服务的Spring。如果你只想看一本的话，那么就看后者吧。
</li>

前面推荐的几本书可以帮你成功入门Java，但想要进一步成长，就要看下面我推荐的几本进阶级别的书了。

<li>
接下来，你需要了解了一下如何编写高效的代码，于是必需看一下《[Effective Java](https://book.douban.com/subject/27047716/)》（注意，这里我给的引用是第三版的，也是2017年末出版的书），这本书是模仿Scott Meyers的经典图书《Effective C++》的。Effective这种书基本上都是各种经验之谈，所以，这是一本非常不错的书，你一定要读。这里需要推荐一下 [Google Guava 库](https://github.com/google/guava) ，这个库不但是JDK的升级库，其中有如：集合（collections）、缓存（caching）、原生类型支持（primitives support）、并发库（concurrency libraries）、通用注解（common annotations）、字符串处理（string processing）、I/O 等库，其还是Effective Java这本书中的那些经验的实践代表。
</li>
<li>
《[Java并发编程实战](https://book.douban.com/subject/10484692/)》，是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发，介绍了如何使用类库提供的基本并发构建块，用于避免并发危险、构造线程安全的类及验证线程安全的规则，如何将小的线程安全类组合成更大的线程安全类，如何利用线程来提高并发应用程序的吞吐量，如何识别可并行执行的任务，如何提高单线程子系统的响应性，如何确保并发程序执行预期任务，如何提高并发代码的性能和可伸缩性等内容。最后介绍了一些高级主题，如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。
</li>
<li>
了解如何编写出并发的程序，你还需要了解一下如何优化Java的性能。我推荐《[Java性能权威指南](https://book.douban.com/subject/26740520/)》。通过学习这本书，你可以比较大程度地提升性能测试的效果。其中包括：使用JDK中自带的工具收集Java应用的性能数据，理解JIT编译器的优缺点，调优JVM垃圾收集器以减少对程序的影响，学习管理堆内存和JVM原生内存的方法，了解如何最大程度地优化Java线程及同步的性能，等等。看完这本书后，如果你还有余力，想了解更多的底层细节，那么，你有必要去读一下《[深入理解Java虚拟机](https://book.douban.com/subject/24722612/)》。
</li>
<li>
《[Java编程思想](https://book.douban.com/subject/2130190/)》，真是一本透着编程思想的书。上面的书让你从微观角度了解Java，而这本书则可以让你从一个宏观角度了解Java。这本书和Java核心技术的厚度差不多，但这本书的信息密度比较大。所以，读起来是非常耗大脑的，因为它会让你不断地思考。对于想学好Java的程序员来说，这是一本必读的书。
</li>
<li>
《[精通Spring 4.x](https://book.douban.com/subject/26952826/)》，也是一本很不错的书，就是有点厚，一共有800多页，都是干货。我认为其中最不错的是在分析原理，尤其是针对前面提到的Spring技术，应用与原理都讲得很透彻，IOC和AOP也分析得很棒，娓娓道来。其对任何一个技术都分析得很细致和全面，不足之处就是内容太多了，所以导致很厚，但这并不影响它是一本不错的工具书。
</li>

当然，学Java你一定要学面向对象的设计模式，这里就只有一本经典的书《[设计模式](https://book.douban.com/subject/1052241/)》。如果你觉得有点儿难度了，那么可以看一下《[Head First设计模式](https://book.douban.com/subject/2243615/)》。学习面向对象的设计模式时，你不要迷失在那23个设计模式中，你一定要明白这两个原则：

<li>
**Program to an ‘interface’, not an 'implementation’**
<ul>
- 使用者不需要知道数据类型、结构、算法的细节。
- 使用者不需要知道实现细节，只需要知道提供的接口。
- 利于抽象、封装，动态绑定，多态。符合面向对象的特质和理念。

**Favor ‘object composition’ over 'class inheritance’**

- 继承需要给子类暴露一些父类的设计和实现细节。
- 父类实现的改变会造成子类也需要改变。
- 我们以为继承主要是为了代码重用，但实际上在子类中需要重新实现很多父类的方法。
- 继承更多的应该是为了多态。

至此，如果你把上面的这些知识都融汇贯通的话，那么，你已是一个高级的Java程序员了，我保证你已经超过了绝大多数程序员了。基本上来说，你在技术方面是可以进入到一线公司的，而且还不是一般的岗位，至少是高级程序员或是初级架构师的级别了。

## C/C++语言

不像我出道那个时候，几乎所有的软件都要用C语言来写。现在，可能不会有多少人学习C语言了，因为一方面有Java、Python这样的高级语言为你屏蔽了很多的底层细节，另一方面也有像Go语言这样的新兴语言可以让你更容易地写出来也是高性能的软件。但是，我还是想说，C语言是你必须学习的语言，因为这个世界上绝大多数编程语言都是C-like的语言，也是在不同的方面来解决C语言的各种问题。**这里，我想放个比较武断话——如果你不学C语言，你根本没有资格说你是一个合格的程序员！**

<li>
这里尤其推荐，已故的C语言之父Dennis M. Ritchie和著名科学家Brian W. Kernighan合作的圣经级的教科书《[C程序设计语言](https://book.douban.com/subject/1139336/)》。注意，这本书是C语言原作者写的，其C语言的标准不是我们平时常说的ANSI标准，而是原作者的标准，又被叫作K&amp;R C。但是这本书很轻薄，也简洁，不枯燥，是一本你可以拿着躺在床上看还不会看着看着睡着的书。
</li>
<li>
然后，还有一本非常经典的C语言的书《[C语言程序设计现代方法](https://book.douban.com/subject/2280547/)》。有人说，这本书配合之前的 [The C Programming Language](https://en.wikipedia.org/wiki/The_C_Programming_Language) 那本书简真是无敌。我想说，这本书更实用，也够厚，完整覆盖了C99标准，习题的质量和水准也比较高。更好的是，探讨了现代编译器的实现，以及和C++的兼容，还揭穿了各种古老的C语言的神话和信条……是相当相当干的一本学习C语言的书。
</li>

**对了，千万不要看谭浩强的C语言的书。各种误导，我大学时就是用这本书学的C，后来工作时被坑得不行**。

在学习C语言的过程中，你一定会感到，C语言这么底层，而且代码经常性地崩溃，经过一段时间的挣扎，你才开始觉得你从这个烂泥坑里快要爬出来了。但你还需要看看《[C陷阱与缺陷](https://book.douban.com/subject/2778632/)》这本书，你会发现，这里面的坑不是一般大。

此时，如果你看过我的《编程范式游记》那个系列文章，你可能会发现C语言在泛型编程上的各种问题，这个时候我推荐你学习一下C++语言。可能会有很多人觉得我说的C++是个大坑。是的，这是世界目前来说最复杂也是最难的编程语言了。但是，**C++是目前世界上范式最多的语言了，其做得最好的范式就是&quot;泛型编程&quot;，这在静态语言中，是绝对地划时代的一个事**。

所以，你有必要学习一下C++，看看C++是如何解决C语言中的各种问题的。你可以先看看我的这篇文章 “[C++的坑真的多吗？](https://coolshell.cn/articles/7992.html)” ，有个基本认识。下面推荐几本C++的书。

<li>
《[C++ Primer中文版](https://book.douban.com/subject/25708312/)》，这本书是久负盛名的C++经典教程。书是有点厚，前面1/3讲C语言，后面讲C++。C++的知识点实在是太多了，而且又有点晦涩。但是你主要就看几个点，一个是面向对象的多态，一个是模板和重载操作符，以及一些STL的东西。看看C++是怎么玩泛型和函数式编程的。
</li>
<li>
如果你想继续研究，你需要看另外两本更为经典的书《[Effective C++](https://book.douban.com/subject/5387403/)》和《[More Effective C++](https://book.douban.com/subject/5908727/)》。 这两本书不厚，但是我读了10多年，每过一段时间再读一下，就会发现有更多的收获。这两本书的内容会随着你经历的丰富而变得丰富，这也是对我影响最大的两本书，其中影响最大的不是书中的那些C++的东西，而是作者的思维方式和不断求真的精神，这真是太赞了。
</li>
<li>
<p>学习C/C++都是需要好好了解一下编译器到底干了什么事的。就像Java需要了解JVM一样，所以，这里还有一本非常非常难啃的书你可以挑战一下《<a href="https://book.douban.com/subject/10427315/">深度探索C++对象模型<br />
</a>》。这本书是非常之经典的，看完后，C++对你来说就再也没有什么秘密可言。我以前写过的《[C++虚函数表解析](https://coolshell.cn/articles/12165.html)》，还有《[C++对象内存布局](https://coolshell.cn/articles/12176.html)》属于这个范畴。</p>
</li>
<li>
还有C++的作者 Bjarne Stroustrup 写的 [C++ FAQ](http://www.stroustrup.com/bs_faq.html) （[中文版](http://www.stroustrup.com/bsfaqcn.html)），也是非常值得一读的。
</li>

## 学习Go语言

C语言太原始了，C++太复杂了，Go语言是不二之选。有了C/C++的功底，学习Go语言非常简单。

首推 [Go by Example](https://gobyexample.com/) 作为你的入门教程。然后，[Go 101](https://go101.org/article/101.html) 也是一个很不错的在线电子书。如果你想看纸书的话，[The Go Programming Language](https://book.douban.com/subject/26337545/) 一书在豆瓣上有9.2分，但是国内没有卖的。（当然，我以前也写过两篇入门的供你参考 “[GO 语言简介（上）- 语法](https://coolshell.cn/articles/8460.html)” 和 “[GO 语言简介（下）- 特性](https://coolshell.cn/articles/8489.html)”）。

另外，Go语言官方的 [Effective Go](https://golang.org/doc/effective_go.html) 是必读的，这篇文章告诉你如何更好地使用Go语言，以及Go语言中的一些原理。

Go 语言最突出之处是并发编程，Unix老牌黑客罗勃·派克（Rob Pike）在 Google I/O上的两个分享，可以让你学习到一些并发编程的模式。

- Go Concurrency Patterns（ [幻灯片](https://talks.golang.org/2012/concurrency.slide)和[演讲视频](https://www.youtube.com/watch?v=f6kdp27TYZs)）。
- Advanced Go Concurrency Patterns（[幻灯片](https://talks.golang.org/2013/advconc.slide)、[演讲视频](https://youtu.be/QDDwwePbDtw)）。

然后，Go在 GitHub的wiki上有好多不错的学习资源，你可以从中学习到多。比如：

- [Go精华文章列表](https://github.com/golang/go/wiki/Articles)。
- [Go相关博客列表](https://github.com/golang/go/wiki/Blogs)。
- [Go Talks](https://github.com/golang/go/wiki/GoTalks)。

此外，还有个内容丰富的Go资源列表 [Awesome Go](https://github.com/avelino/awesome-go)，推荐看看。

# 小结

好了，最后我们来总结一些今天分享的内容。在编程语言方面，我推荐学习C、C++、Java和Go四门语言，并分别阐释了推荐的原因。

<li>
我认为，C语言是必须学习的语言，因为这个世界上绝大多数编程语言都是C-like的语言，也是在不同的方面来解决C语言的各种问题。
</li>
<li>
而C++虽然复杂难学，但它几乎是目前世界上范式最多的语言了，其做得最好的范式就是&quot;泛型编程&quot;，这在静态语言中，是绝对地划时代的一个事。尤其要看看C++是如何解决C语言中的各种问题的。
</li>
<li>
Java是我认为综合能力最强的语言。其实我是先学了Java，然后又去学了C++，之后去学了C语言的。C -&gt; C++ -&gt; Java整条线融汇贯通，这对我未来的技术成长有非常大的帮助。
</li>
<li>
在文章最末，我推荐了Go语言，并给出了相关的学习资料。
</li>

我认为，一个合格的程序员应该掌握几门语言。一方面，这会让你对不同的语言进行比较，让你有更多的思考。另一方面，这也是一种学习能力的培养，会让你对于未来的新技术学习得更快。

下篇文章中，我们将分享每个程序员都需要掌握的理论知识。敬请期待。

下面是《程序员练级攻略》系列文章的目录。

- [开篇词](https://time.geekbang.org/column/article/8136)
<li>入门篇
<ul>
- [零基础启蒙](https://time.geekbang.org/column/article/8216)
- [正式入门](https://time.geekbang.org/column/article/8217)

- [程序员修养](https://time.geekbang.org/column/article/8700)

- [编程语言](https://time.geekbang.org/column/article/8701)
- [理论学科](https://time.geekbang.org/column/article/8887)
- [系统知识](https://time.geekbang.org/column/article/8888)

- [软件设计](https://time.geekbang.org/column/article/9369)

- [Linux系统、内存和网络（系统底层知识）](https://time.geekbang.org/column/article/9759)
- [异步I/O模型和Lock-Free编程（系统底层知识）](https://time.geekbang.org/column/article/9851)
- [Java底层知识](https://time.geekbang.org/column/article/10216)
- [数据库](https://time.geekbang.org/column/article/10301)
- [分布式架构入门（分布式架构）](https://time.geekbang.org/column/article/10603)
- [分布式架构经典图书和论文（分布式架构）](https://time.geekbang.org/column/article/10604)
- [分布式架构工程设计(分布式架构)](https://time.geekbang.org/column/article/11232)
- [微服务](https://time.geekbang.org/column/article/11116)
- [容器化和自动化运维](https://time.geekbang.org/column/article/11665)
- [机器学习和人工智能](https://time.geekbang.org/column/article/11669)
- [前端基础和底层原理（前端方向）](https://time.geekbang.org/column/article/12271)
- [前端性能优化和框架（前端方向）](https://time.geekbang.org/column/article/12389)
- [UI/UX设计（前端方向）](https://time.geekbang.org/column/article/12486)
- [技术资源集散地](https://time.geekbang.org/column/article/12561)


