后端 C++ 自学路线(转载总结)

  • 序言
  • 摘要
  • 参考
  • 岗位分析
  • 后端技术栈
  • 学习建议
  • 学习路线
  • 软件基础
    • 1. C++基础
    • 2.数据结构与算法
      • 数据结构
      • 算法
      • 刷题(一直持续到找工作)
    • 3. 操作系统
      • 操作系统&编译原理
      • Linux
      • 内核
    • 4. 计算机网络
    • 5.系统编程和网络编程
    • 6. 数据库
    • 7.设计模式
  • 项目
  • 进阶

序言

作为学习的开始,搜集资料制定路线,并且对所要学习的内容有个大致的了解值得花费几天的时间。

摘要

“工欲善其事,必先利其器”,本文主要介绍了C++技术栈后端开发的岗位,学习方法,主要学习内容,线路以及企业部署的技术点以从宏观层面对其进行掌握。

参考

C++后台开发学习路线(已签腾讯后台开发)-by玩铁的搬砖工
从小白到BAT后端工程师的自学路线-byMutexLock​
这才是你需要的C语言、C++学习路线!-by CodeSheep

岗位分析

了解一下岗位,知道以后能做什么,这个也有利于自己树立学习目标。

C语言和C++属于“造轮子”语言,几乎什么都能做。不过一般来说,C语言和C++主要还是做后台(服务端)开发比较多,包括:

通信公司后台开发
互联网公司后台开发
游戏公司后台开发
……
当然这个后台开发具体职责又有很多细分,比如:

有做数据处理和分析的
有做基础协议和通信的
有做服务端底层应用优化的
甚至还有做后台系统驱动和内核的
……

后端技术栈

写得非常好,必看
后台开发总览

学习建议

如果当初还是小白的时候,就能确定一个比较合理的学习路线,对知识由浅入深的进行学习,学习的过程肯定会顺利一些,效率自然也会更高。

至于后端学习我们可以从如下下考虑:

编程基础:

  • C++基础
  • 数据结构与算法
  • 操作系统
  • 计算机网络
  • 数据库
  • 设计模式

对于技术岗,软件基础知识可以说是个人的硬实力,是你能通过面试的一个大前提。即使后面的东西都没学,基础部分是肯定需要完成的,这也是后面所有应用框架学习的基石;反之,在应用框架的学习时如果感觉吃力,可能非常有必要回过头来再巩固对应的基础知识。然而基础的确不是一蹴而就的,确实需要一定的反复和回炉。面试也主要是这些基础,公司校招一般看基础咋样,可塑性如何,这才是重点。之后才是项目和一些花里胡哨的。

有些很有意思的方向,可以作为进阶学习,对于大部分岗位的面试而言,只是加分项,而非必选项:

  • 分布式系统(感兴趣可以学习,分布式存储、计算等,加分项)
  • 编译原理(很大的魅力,感兴趣可以学,耗时间,加分项)
  • Functional Programming(同上)
  • 云原生、容器、服务编排等(Docker、Kubernetes什么的,加分项)

我们需要有牢固的基础理论知识,一定的代码量积累、实践。主要的学习方式有:

  • 看书(买书不要吝啬)
  • 名校课程(MIT、CMU有很多不错的courses)
  • 刷题(LeetCode)
  • 做笔记,写博客(不仅有助于记忆,还能体现你的技术态度)
  • 开源项目,阅读源码,自己实现(熟练运用google、github)
  • 知乎等平台(参与讨论,会发现很多自己没有思考到的东西)

首先,对于软件基础知识的学习,建议看经典的英文书籍(上进的青年还是啃生肉吧,毕竟原汁原味),看第一遍的时候可以不用太过细致,快速地看,重在了解这本书的知识框架,在把握了整体的逻辑框架之后,第二遍就可以详细学习各章节的细节,这个时候也能根据自己的情况,选择性地去看一些相对重要的章节,效率会更高。对于一些经典技术书籍,只看一两遍很难完全理解其中的精髓,之后可能还要多次地回顾,也可能在实际应用中再来回顾书中的理论知识,也能更深入地进行理解。例如深入理解计算机系统这本书,内容非常经典,很多地方当你再看一遍又会有不一样的理解和体会。总是学习是螺旋上升的复杂过程。

先学习语言和数据结构基础,然后并行学习网络、操作系统和刷题。

准备时间比较短的话,不用将每个知识板块的所有书籍看完,可以先看完基础书籍,例如C++看Primer,数据结构看大话数据结构,网络看谢希仁的计算机网络,操作系统看CSAPP,数据库对于C++岗考察不多,优先级放到最低,可以先暂时不看。看完基础书籍之后,会形成基本的知识,但是深度不够,这个时候再考虑在各个知识板块看一些进阶书籍,建议你至少有一方面学习深入(语言基础或者操作系统)

每看完每本书,都要学会去做笔记,写博客,对自己所学的知识进行总结消化,笔记中的内容才是自己的东西,而且在我们学习的过程中难免会对一些知识点的理解有所偏差和不足,笔记能够很好地帮助我们发现这些问题,然后加以纠正并很好地记录下来。

勤于做笔记、善于写博客,做好技术输出非常重要,这样后面复习、回顾、自查都有章可循了。

本文只是介绍了主要的学习道路,还有一些比较杂的东西(比如git怎么用),可以自行搜索,反正遇事不决就Google。

推荐用Linux或者MacOS来进行学习,或者Windows上装WSL(WSL+VS Code 直接起飞)也可以。但是,经济允许的条件下,最推荐MacBook Pro,因为写代码屏幕看起来最舒服,而且像艺术品一样,看见就爱不释手,学习了起来(仅为原作者观点)。

工具方面,比如编辑器推荐VS Code(加上插件也算是IDE了),IDE推荐JetBrain全家桶(学生可以买免费申请License)。笔记方面CSDN, Typora(markdown 编辑器 .md后置的那种文件)写在博客里面,主要记录:备忘录,笔记,基础理解,踩坑记录。

教程资源可以去看电子版。啥都能在这里弄到电子版 & F R E E!(需要科学上网):Part of Z-Library project. The world’s largest ebook library

学习路线

软件基础

这里的学习不完全顺序进行,有时同时进行。同一段时间交叉学习不同内容会极大增强效率。

1. C++基础

  • C++ Primer 第5版
  • Effective C++Effective Modern C++(EMC没时间不看)
  • STL源码剖析(侯捷 著)
  • STL 源码剖析 Inside the C++ Object Model (侯捷 译)

软件学习中,语言肯定是最基础的。学习C++前最好先学C语言,他是C++的一个子集。推荐:C Primer Plus。这个先导课程学完后可以学习它的进阶课程:数据结构与算法分析(C语言描述) 没时间也可以大话数据结构在学习数据结构与算法的同时,建议同步学习C++语法知识

由于C++较低层,语法非常灵活(比较适合写算法),就导致语法规则比较繁杂,而且涵盖了C语言的内容,学习C++语法相对python、java等其他高级语言时间成本更高一些。但是利用学生的空余时间学习高难度有利于以后迅速学习其他语言!

C++ Primer 第5版,C++语法学习的最权威书籍,以C++11来讲解,非常全面地讲解了C++的语法以及C++11的各种新特性,看完帮助很大,如果有时间建议至少看两遍,时间有限的话,建议至少通读一遍,把握这本书的大体框架,然后结合个人情况选择性地去看一些重点章节。
(另外,学习一下脚本语言也有一些用处,推荐Python,书籍《Python基础教程》,了解下基本语法就好。学习Python之后,可以尝试去做一些比较有意思的项目,例如写个爬虫,这样可以培养自己的编程兴趣,也挺有成就感,写爬虫可以在网上搜一些教程,在学习的过程中,也可以对html、http协议等有一些了解。另外还有Google C++ Style Guide)(时间不够的话就算了)

Effective C++ 这本书主要讲解了编写C++程序的过程中需要注意的一些条款,有助于梳理在编写C++程序时的一些常见错误和注意事项,培养好的C++编程习惯, 也是面试常考的。如果认真读过了C++ Primer,这本书看起来会非常快,其中的很多内容都包含在C++ Primer中了。Effective Modern C++并不是要替代Effective C++。在EC++中还有一些在EMC++中完全没有涉及的信息。EMC++主要用于覆盖c++ 11和c++ 14中的新特性。在编写它时,作者认为你应该已经很好地掌握了EC++中涵盖的所有c++ 98内容。当然,如果你正在使用c++ 11或c++ 14, EC++中的一些内容可能有点过时,不再直接应用,但这并不意味着这本书过时了。

STL 源码剖析这本书讲解了C++底层实现,内容包括C++底层内存管理、各种容器的数据结构实现、常见算法的实现等,建议列为必读,可以帮助深入理解C++底层,同时也是对数据结构的复习和巩固。其中也有很多面试常考的知识点,如内存池的机制、traits技法、一些常用容器的底层数据结构等。读一读《STL源码剖析》和SGI STL源码来看看STL是如何实现的(例如ST-L的内存分配器、很常用的vector容器),不过前提是对模板有一点认知,推荐看《C++ template》的部分内容,C++的模板是一个深坑,了解到偏特化的程度就行了。)。写代码的时候,就常备cppreference吧。

深度探索C++对象模型这本书讲解了C++面向对象特性的底层实现机制,由于是翻译版本,读起来内容会相对晦涩一些,但是内容非常重要,尤其是虚函数底层的实现机制,建议多看几遍加深理解,这个基本是C++必问的知识点。看完这本书,对C++面向对象的理解帮助极大,建议必读。

总之,如果你认真的学习了以上4本书,你会对C++有一个新的认识!相信我,等你学好C++,再学习其他高级语言会觉得轻松许多!

2.数据结构与算法

数据结构

  • 大话数据结构
  • 浙大数据结构网上课程: 数据结构-浙江大学

数据结构可以说是软件设计的精髓,建议将基础打扎实。大话数据结构这本书对于新手,很适合作为入门,用于建立数据结构的知识体系,另外浙大数据结构网上课程也非常不错,B站上直接可以搜到,讲解简明易懂,弥补了大话数据结构中一些讲解不清楚的地方。

算法

  • 算法 第4版(是以java来讲解)
  • 算法导论

在学习了数据结构的基础后,可以开始学习算法4这本书,可以帮助你梳理一些常用算法的原理和应用。后者因为有很多算法复杂度分析,会让人觉得读起来很困难。

建议:算法4需要通读,并且用C++来实现上面的算法(书上都是用Java实现的),然后算法导论看完前面17章即可(到贪心那章),算法复杂度分析的部分可以尝试去看看,如果实在讨厌公式推导也可以跳过,但是要能够掌握推导一些常见算法的复杂度。在学习数据结构与算法的同时,建议同步学习C++语法知识,两者基础都学习完之后,就可以刷题了。

刷题(一直持续到找工作)

  • LeetCode中文网站
  • 剑指offer 第2版(建议至少刷两遍)
  • 程序员代码面试指南(左程云 著)

为了应付公司面试时的算法题,同时也是为了积累自己的代码量,就需要开始刷题,主要就是LeetCode。这个刷题要一直持续到找工作,所以尽量安排好自己的刷题节奏。可以按照题目的tag来刷,这样更容易增强自己的解题能力,最好写三百道以上吧。此外,LeetCode中有一个数据结构的探索专栏,根据难度,分为初级、中级和高级,基本覆盖了各个知识板块的面试高频题,可以帮助新手循序渐进地刷题,培养写代码的感觉。自己选择喜欢的方式吧。

刷题可以和前后面的学习同步进行。在刷题的过程中,可以同步学习STL 源码剖析,有助于你更游刃有余的去使用STL,提高代码效率。

另外的话,剑指offer这本书中也涵盖了很多面试高频题,可以到牛客网的剑指offer专栏中刷题,由于题目难度划分层次不太明确,新手刷起来效率会偏低,建议在刷完LeetCode探索专栏中的初级、中级之后,再去刷剑指offer的题目,其中的题目在面试中出现的非常高频,建议最好刷两遍,熟练掌握每道题的思路和优化方法。最后,作为进阶,可以看左神写的程序员代码面试指南,非常好的一本书,其中讲解的编程题都非常经典,不仅仅限于国内的IT公司,而是面向全球,包含了国外知名IT公司的一些面试高频题,可以帮助开阔视野。

在刷题的过程中,要非常注意方法,一般将刷题方法分为龟系和兔系。

龟系刷法的精髓就是每个题目要注意质量,不要满足于一种解法,各种解法都尝试写一写,并对比它们的时间空间复杂度。但龟系不是说在一道题上耗死。越是龟系越要注意时间上要掌握好分寸,能解出来最好,解不出来也不要倔强。我觉得比较好的一个平衡点差不多是一个小时。如果一个小时还是解决不了,可以看看提示,如果还是解决不了,可以看看讨论区的答案或者网上搜索答案。

兔系刷法精髓就是要暴力,天马流星拳,大力出奇迹。作为兔系选手,讲求的就是要疯,一上来就看答案,照着答案写。这个做法看起来不靠谱,其实它有内在的合理性:大部分算法都不是我们发明的,如动态规划,二叉树,线段树,并查集,贪心算法等等,到后来所谓的不看答案自己做出来,其实都是在用固定套路。另外编程题的知识点很多很杂,LeetCode中将题目分为各种标签,建议对标签按照广度优先的顺序去刷题,刷题尽量覆盖每个标签。我个人更倾向于龟系,这种方法能够更好地理解每道题的方法套路,也能训练自己的思维,毕竟刷题不是题海战术,刷题质量更重要,每刷完一道题,最好将其中的思路方法记录下来,然后定期做总结,对一些常用方法进行总结分类,慢慢的会发现刷来刷去就是那些套路,你会对它们了然如胸。

此时具备了编码的基本能力,可以尝试去做一些项目,例如JSON库、正则引擎,这些都可以在网上找到教程。

3. 操作系统

操作系统&编译原理

  • 深入理解计算机系统 第3版(CSAPP)
  • 操作系统 精髓与设计原理 第8版
  • 程序员的自我修养

Linux

  • 鸟哥的Linux私房菜 第4版(用于了解Linux基本命令)
  • UNIX环境高级编程 第3版(APUE)
  • Linux/UNIX系统编程手册(上下册)

内核

  • Linux内核设计与实现(LKD)
  • 深入理解Linux内核

在语言基础和数据结构之外,操作系统可以说是面试考查最多的内容了,在面试中很可能会问的比较深,毕竟操作系统是很深奥的!

学习操作系统知识,可以先看深入理解计算机系统,操作系统方面的神书,内容非常经典,而且比较通俗易懂,适合入门。初学者会有很多概念都难以理解,建议是尝试检索相关内容去理解,实在学不会就先跳过,继续后面的内容。读书过程中,也不需要一定按照其安排的章节顺序,可以先挑自己喜欢的读,例如为了理解计算机中的cache,就去读第六章。这本书是CMU 152-13的配套书籍,该课程相关的资源也可以用来辅助学习,另外,最精髓的就在于配套的Lab了,难度不低,这个一定要做,如果做的很困难,也要坚持去做,完成后会发现自己的能力有很大的提升。这本书也不用一口气读完,有些章节不太感兴趣,或者读不下去的话,可以留着,等后面知识更加丰富了再回头来看(例如网络那章,我看的是很难理解一些概念,后来学习了计算机网络和网络编程后,就发现读起来比较简单了)。建议先学习第二部分和第三部分,再根据个人情况学习第一部分。然后再学习操作系统 精髓与设计原理,(或推荐OSTEP(网上有免费pdf),中文版是《操作系统导论》,建议通读。额,我暂时选第一个)这本书通俗易懂,可以结合CSAPP一起看,两本书的知识点相互有所弥补。

看完前面两本书,如果想对编译链接的原理进行深入学习,可以参考程序员的自我修养,这本书非常详细的讲解了程序编译过程中的具体细节。

另外,针对Linux进行学习,可以先看鸟哥的Linux私房菜,快速看,主要是了解Linux基本命令。进一步学习系统编程,可以学习APUE,其中讲解了Linux/UNIX常用系统编程接口的使用方法和对应的应用实例,由于这本书有些理论知识讲解地比较简略,而Linux/UNIX系统编程手册讲解更为详细,建议两本书结合着看。

在学习完前面所说的操作系统书籍之后,如果还想对Linux内核原理进行学习,可以看Linux内核设计与实现深入理解Linux内核,由于后者更加偏重理论细节的讲解,看起来比较晦涩难懂,容易陷入细节。而 LKD这本书以实践为主,没有赘述很多细节,主要是结合各个模块,以宏观的视角来讲解,能帮助你快速建立比较完整的的知识框架。建议先学习后者,再学习前者,这样可以更好地去理解各个知识板块的逻辑关系和细节实现。

如果有同学对操作系统底层知识感兴趣,可以看博客底层知识学习记录,总结的非常不错,看完会非常有帮助!

4. 计算机网络

  • 计算机网络 第7版(谢希仁 著) / 计算机网络:自顶向下 Computer Networking:A Top-Down Approach,Sixth Edition
  • TCP/IP详解 原书第2版(卷1)
  • UNIX网络编程 第3版(卷1)

学习网络,可以先看计算机网络这本书,讲解通俗易懂,前面的物理层和链路层可以快速看,了解基本原理即可,重点学习网络层、传输层和应用层,其中传输层的TCP和UDP是面试最常考的,非常重要。网络的知识比较容易理解,但是知识点比较繁杂,一段时间不看就很容易忘记,建议学习之后将各个知识点整理成文档或者笔记,有助于找工作前复习。或者英文版计算机网络:自顶向下 Computer Networking:A Top-Down Approach,Sixth Edition,可以只看前面三章,即应用层和传输层,做下每章后面的lab。

学完计算机网络,可以基本建立计算机网络的知识体系,但是这本书深度不够,建议继续学习TCP/IP详解 卷1,作为对TCP/IP协议的深入,这本书讲解非常细致,看的过程中很容易陷入细节,对整本书系统学习的话比较花时间,如果时间有限的话,可以先选择性地学习一些章节,建议先将传输层的内容看完,有助于对TCP和UDP的深入理解,其他层的内容可以根据个人情况选择性的学习。也是为了节省时间,可以只看TCP相关的章节。这本书英文版是第一版,中文版是第二版学习的时候,建议用wireshark来抓包,感受一下这些协议是怎么工作在这互联世界的网络中的,会很有趣的。

学习完前面两本书的基础知识,就基本掌握了计算机网络的理论知识,建议将这两本书列为必读。另外,如果想要对网络编程进行实践,可以继续学习UNIX网络编程 卷1

5.系统编程和网络编程

前面学习了操作系统和网络是怎么工作的,然后就需要学习怎么通过编程来调用操作系统的接口,来进行系统编程和网络编程。这方面比较经典的是Unix环境高级编程Unix网络编程,这两本书都比较古老,比如现在网络模型中常用的epoll就没有介绍,因为成书早,那个时候Linux内核还没有实现epoll,可惜书的作者早逝,不能更新了。但是也很经典,需要搭配Linux/Unix编程手册。当然,这方面的书籍也不是要通读,只需要精读部分章节就好了。

至此,应该能满足大厂实习面试的要求了,可以去投一投简历了。然后需要丰富一下自己的项目经历,多做一些工程。学习了网络编程后,可以学习Linux多线程服务端编程来学习一些C++在实际中的应用,一些常用的小东西(double-buffer啥的),并且加深自己并发编程的能力,相信在前面的基础学习后,能够很好地理解锁,而且对锁的实现,也会了然于胸。然后,这本书还介绍了现在常用的网络IO模型,自己可以实现一种,做一个网络库,并基于此实现一个http server。另外,还可以阅读该书配套代码,muduo,一方面可以看一看优秀的C++代码应该是怎样的,还可以查漏补缺自己的C++知识。

6. 数据库

  • 数据库系统概念 第6版
  • mysql必知必会

数据库的知识面试问的不多,但是数据库对于以后工作是肯定会用到的,如果有时间建议将基础打好,可以先看数据库系统概念,了解数据库的基础知识,然后阅读mysql必知必会这本书,可以帮助你快速学习 mysql 的基本语法。

7.设计模式

大话设计模式

对于设计模式,如果没有大型软件的项目经验,这方面的能力很难体现出来,所以可以作为知识点的扩展学习,对其进行了解即可,面试常考的有单例模式、工厂模式等常见的设计模式。

项目

基础知识的学习只是丰富你的武器库。经常有这样的问题:为啥我学完了C语言或者C++,却还是啥东西也做不出来?实际上,语言学得就算再精通,它其实也只代表完成了“最小的”那一部分,和实际上手干活之间还是有一个非常大的鸿沟。首先实际企业级开发几乎不可能,所以Linux系统必须要会常见的Linux操作命令、基本的Shell编程,这在上述的操作系统部分有包含。

其次,很多人学C语言、C++都在类似Visual Studio这种集成IDE里进行代码编译,这个其实也用了编译器,只不过是微软自家的MS编译器,而且所有操作均可视化。而企业里开发很少会基于Windows系统,所以Linux平台上的编译器更为重要,最典型的当属 GCC,甚至有些公司有自己定制过的交叉编译工具,但没关系,只要 GCC熟悉,其他问题都不大。

其次,大家自学C语言、C++,都借助类似VS这种IDE,点按钮即可对源文件编译。而企业里实际项目的编译动作叫 make,编译的实际动作和过程都是写在 makefile文件里,所以makefile的书写规则建议学习!

最后说到调试工具,Linux平台上的 GDB调试工具要熟练使用,会借助于它进行调试。英文好的同学可以直接看 GNU官网关于 GCC和 GDB的文档,中文材料可以看:《debuging with gdb》(中文版)和陈皓先生的《跟我一起写makefile》

我们可以在项目中体验实际的开发。项目主要有C/C++领域的练手开源项目,小伙伴们接好 必须要说的是,不像Python,Java等开源项目一般都具备美观的可视化界面、网页、甚至手机App;而C语言和C++写的项目一般非常朴素,大多运行于命令行那个简单的黑乎乎界面,甚至完全运行于后台。

进阶

C++的并发编程,看一看《C++ concurrency in action》(一定不要买中文版,被那个翻译恶心到了

如果想对编译链接的原理进行深入学习,可以参考程序员的自我修养,这本书非常详细的讲解了程序编译过程中的具体细节。(操作系统一节有提到。如果时间充裕,还可以尝试自己去实现一个操作系统,这方面推荐书籍《操作系统真象还原》,或者课程MIT6.828:6.S081 / Fall 2019,两者二选一吧。

如果还有余力,就要向分布式系统进发了。我学的比较浅,推荐学习资料是MIT6.824课程(6.824 Schedule: Spring 2020),做lab看paper吧。书籍方面,很推荐《Design Data Intensive Applications》,另外还读过一个小册子《Distributed System for Fun and Profit》,感觉不是很喜欢。

为了变得更强,还需要看一看工业界中常用的东西,各种中间件,比如Redis,推荐《Redis深度历险》,可以看看它源码中感兴趣的部分。还有消息队列,我最近在看的nats。然后就是LevelDB,这个也是特别值得学习的东西,了解它的原理,看它的源码,了解大神的C++代码是怎样的,也是可以学习到很多东西,例如我之前才学到的clang支持的thread safety annotation。自己也可以实现一个单机版本的kv数据库,可以用最简单的bitcask的方案做存储,再加上自己写的网络库来对外提供服务,做起来也会很有趣。

这部分不太懂,还是先做好以上吧。

更多推荐

后端 C++ 学习路线(转载总结)