C/C++ 是一门底层、细粒度、功能强大、学习曲线陡峭的语言,虽然在Python等新语言的冲击下略显龙钟老态,但随着AIoT设备的兴起,以及C++社区不断推出新的版本,这门语言又重新焕发了生机。
本文把C++学习划分为入门、熟练、进阶三个阶段,每步提供相应的学习方法和资源,并归纳了每部分需要掌握的知识点供大家复习自检,希望能够帮助大家更好地掌握这门语言。也欢迎大家告诉我更好的学习资源,本文会不断更新来帮助更多的人。
学习新知识有两个关键:快速上手、完整的知识体系,两者缺一不可:上手慢就会打击初学者的积极性,产生劝退效应;而没有完整的知识体系,初学者就是盲人摸象,想要进阶深入就变得困难重重,只会长期停留在入门阶段。我在对比多种学习方法后,认为网课是能够兼容这两点的好方法,所以这部分主要推荐网课,通过高频且较简单的练习巩固知识,符合人的认知曲线,提高学习效率。
C++ 和 C 是不同的语言,但两者通常放在一起学习,C++完全兼容C的特性,并在C基础上加入了面向对象的特性,可以视为 C 语言的升级版,C能做到的事情 C++ 一样可以做到,C 做不到的事情 C++ 也可做到。
初学C++我推荐学堂在线上清华大学郑莉老师的课程:C++语言程序设计基础,C++语言程序设计进阶。在讲课过程中会有弹出的选择、填空题来巩固知识点,每一章结束一般会有三道编程题来进行练习。通过高频且难度不大的练习,将陡峭的学习曲线拉平,进度页面可以看到学习完成的进度,带给大家成就感。我把自己学这门课时的课后习题放在Github上C++语言程序设计课后习题,供大家参考。学完这门课程就会对C++的特性有了整体的了解,并且能够上手编写一些简单的程序,这时候可以去LeetCode 上刷一些 Easy 题目找找存在感了。
这部分主要掌握的知识点是:
掌握编程语言后,就要跟操作系统打交道了。
Windows 和 Ubuntu 是操作系统的两大阵营,大家可以根据自己的需求进行选择。在Windows下编程的同学可以跳过这个部分,因为Visual Studio (Community社区版) 功能已经足够强大,不需要进行任何配置上手即用,关键还是免费的!这里说一声微软牛[哔——]。
如果需要在Linux 下编程的同学,我推荐学堂在线上清华大学乔林老师的课程:基于Linux的C++。学过郑莉老师的C++,乔林老师的这门课程就没有必要全部看下来了,因为前11讲内容都是在重复C++的语言特性,大家只要关注12讲的内容:Linux系统编程基础,系统性的了解 Linux 下编程的特点。后面三章感兴趣的话也可看一看:13.进程编程,14.线程编程,15.网络编程,但不学也不会有什么问题。
这门课程的用户体验没有郑莉老师的课程那么友好,不过用来系统性掌握Linux系统下的编程操作已经足够了。乔林老师讲解并不详细,但胜在体系完整,能够用很短的篇幅帮初学者建立对 Linux 系统完整的认知,这是我推荐这门课程的原因。因为讲解不够详细,遇到不懂问题再配合搜索引擎进行学习吧。
这部分主要掌握的知识点是:
算法与数据结构、计算机网络、操作系统,是计算机考研必备的三门课程,也是整个计算机的基石。修炼好这三部分知识的程序员就像掌握了深厚的内功,无论是学习其他语言还是进行架构设计,都会更加得心应手,事半功倍。
入门阶段不需要花费大量的精力对多种多样的算法和数据结构进行详尽的了解,但是需要掌握进本的算法分析手段,以及算法研究需要解决的问题。这里推荐学堂在线上清华大学邓俊辉老师的课程:数据结构(上),只需要学习第一章绪论部分就可以。后续的章节可以在深入阶段再进行深挖。
需要掌握的知识点:
对于入门而言,这部分内容完全可以略过。只要实践中不涉及网络编程,就可以暂时不做了解。如果需要了解的话,首先应该掌握TCP/IP的五层网络结构,当遇到网络问题时,能够快速定位是哪一层出了问题,然后快速排查。
知识要点:
这里并不需要对操作系统有多么深入的了解,只需要对计算机的硬件结构有初步的认识,了解程序从编译到执行的具体过程,了解堆栈的概念以及函数调用等流程。这部分内容不需要专门学习,我建议在学习C++语言的过程中,参考教材《C++程序设计》(Y.Daniel Liang),这本书中对操作系统有简单的介绍,可以在学习过程中加以了解。刚开始没看懂也没有关系,等语言学一段时间再回来看,相信会有更深的理解。
知识要点:
入门的要求是了解C++这门语言的语法,能够编写一些简单的程序,进阶就要求掌握一定的工程能力,有能力管理一些大型项目。可能有读者就会有疑问,这篇文章不是讲C++学习么,为什么要掌握工程能力?这是由于C++(包括绝大多数编程语言)是为大型项目服务的,许多C++的编程习惯在语法上没有任何问题,但对大型项目很不友好。C++进阶本质上还是要提升自身的编程能力,在C++语言学习的过程中,穿插了解一些大型项目的经验,对编程能力会有很好的提升。
除工程能力外,C++进阶还需要了解这门语言会有哪些坑,并学会怎样避开他们。C++是一门功能强大的语言,它无比强大的能力也会带来许多问题,比如内存泄漏,这些问题一旦出现很难排查,所以需要掌握一定的经验,从程序设计开始就规避这些可能的问题。
说起C++语言的进阶,大家第一时间想到的应该就是《C++ Primer》了,但我个人并不推荐,因为这本书实在是太厚了,可以当工具书但千万不要拿来当课本。因为这样的大部头想要读完都已经不容易了,更何况自己读完也没有办法掌握其中所有的知识点,还需要不断回炉重造。这里推荐一个系列 Scott Mayer 的《Effective C++》 《More Effective C++》 《Effective STL》,这也是《剑指Offer》的作者推荐的书,不少C++面试题目都会考察到其中的知识点。作者Scott Mayer整理了C++编程中需要注意的一些要点,每个部分对初学者来说都可能是深坑。这系列书的特点就是读起来比较轻松,条目之间都比较独立,可以随便选一条从自己感兴趣的开始,而不用像那些大部头一样慢慢地啃。每了解一个知识点都能让你对C++的理解更深一层,这里有我在读这本书过程中记录的笔记:Effective C++ 索引,大家可以通过这个链接快速索引,选择自己感兴趣的条目深入了解。
当然如果要事无巨细地学习C++的所有语法规则,还是要去读《C++ Primer》,不过请事先留好充足的时间,以及反复回炉的心理准备。如何阅读《C++Primer》那么厚的书
怎样检查自己是否掌握C++的高级用法呢?这里建议找一本书的目录,比如Effective C++ 索引,按照目录一条一条去看,能否通过标题想起对应的要点,如果完全理解并且没有任何疑惑,那恭喜你,已经神功初成啦。
应用实践主要关注两个方面:程序编译和程序开发。
程序编译需要掌握编译工具,如make、CMake、ninja、Bazel,make命令比较底层,大部分C++项目使用CMake和ninja,也有Google系的项目采用Bazel进行管理。这部分内容暂时没有找到很好的学习资源,建议结合官方文档使用搜索引擎进行学习掌握。
除了编译工具本身以外,还要掌握怎样在项目中使用第三方库。例如makefile中需要徒手链接库文件,CMakeLists中使用FIND_PACKAGE()命令。毕竟善用第三方库,不反复造轮子,才能提高效率。
这部分内容也没必要掌握得多么精通,只要给出CMakeLists.txt能够看懂,会使用第三方库,能够照猫画虎给自己的工程写出编译文件就可以了。
程序开发就主要根据工作的不同进行专项学习了,这里也不做过多展开,主要介绍几个常用的领域:
注!:游戏开发和后端开发并不是笔者的领域,认识可能比较片面,欢迎大家补充。
不知道大家是否还记得之前推荐的《C++数据结构与算法》(学堂在线),入门阶段我们只了解了复杂度计算的方法,那么进阶就需要把这部分内容啃下来了。邓俊辉老师的课提供大量动画进行讲解,还有大量的练习,还有在线OJ系统,可以快速巩固知识,掌握常用的数据结构和算法知识。
学完这部分内容后,大家应该掌握以下知识点:
如果大家手头有点空余的话,极客时间 上的这门课程是更好的选择,前 Google 工程师王争,从最基础的数据结构出发,结合多年的工程经验,将每一个数据结构与实际的工程应用结合起来,没有网课那么枯燥,学习起来更有趣味和动力。比如在介绍栈的时候,会联系到浏览器的前进后退功能,在介绍散列表的时候,会分享工业级散列表的实现方案,以及散列表扩容时延迟复制的小技巧。总之一句话,愿意花钱的话就买王争老师的课程,一定物超所值。
操作系统进阶就需要了解怎样能更高效地进行计算了,这是发挥C++优势的法宝。要想完全掌握,就一定需要把《深入理解计算机系统》这本书读完。这里给一个链接帮大家啃这本书 CMU:CSAPP,其中有7个动手实验,能够帮大家很好地掌握操作系统的一些知识。
这里推荐Cache Lab和Shell Lab,可以对计算机缓存效率和进程线程调度有直观的认知,方便深入了解C++优化方法。
要点:
计算机网络没必要深入了解过多,完成CMU的Proxy Lab基本就够了。因为目前网络通信协议基本成熟,已经有大量成熟稳定的网络库存在,因此我们不需要投入大量精力在协议实现上,而是需要理解协议为什么要这样设计。比如TCP的连接的三次握手和四次挥手,是面试中的经典题目,虽然在实际开发中从来不会用,但可以用来考察面试者的基本功。相比底层的TCP、UDP协议,HTTP/HTTPS协议以及最近流行的RPC,在应用中会经常遇到,大家可以了解一下这些协议的应用方法和特点。
但如果是运维、IT、架构师之类的岗位,仅仅满足于协议的使用是远远不够的,还需要更深入的了解DNS,防火墙等等协议,这里就不做展开了。
要点:
设计模式没有很好的中文版书籍,大家常提的《大话设计模式》和《设计模式之禅》我并不推荐,这两本书本意是想要通俗地解释设计模式,但只是蜻蜓点水地总结了一下《Design Pattern》这本神作,如果想要深入理解设计模式,还是需要啃《Design Pattern》。这里我推荐一本书《C++编程风格》,这本书分了六个问题,分别从最直接的代码开始,一步一步优化代码,优化过程中解释了为什么要这样做的原因。这本书结合《Design Pattern》中的六大原则,可以帮助我们形成良好的设计思维,当有了设计思维再去理解设计模式会简单很多。
掌握要点:程序设计六大原则
目前文章只完成了入门和进阶的学习路线,深入的学习路线会在整理后更新出来。然而在完成进阶部分的时候,笔者就感觉到自己视野有限,较难从更深更广的维度来指出一条学习路线,也希望大家能够多提供一些自己的学习资源和建议,能够使这个学习路线更加丰满。