说说我的经历,在 C++ 和 Java 之间我经历了这么几个阶段:
作为过来人,我的建议是:
如果你是学生或有大把空余时间,那建议你把 C++ 学好,C++ 被称为程序员的九阳神功是有一定的道理的,并不是说 C++ 有多难学,而是 C++ 技术栈的学习讲究的是其背后的一系列操作系统原理,你把 C++ 学好了,就意味着你把这些背后的原理学好了,你之后再学其他任何语言和机制都轻松很多;
如果你急着找工作,或者对编程没多大兴趣,只是为了糊口饭吃,那么你可以优先选 Java,甚至 Java 的八股文面经背一背,如果运气不错的话,也能找到一份不错的工作。
C/C++ 这门语言与其他高级语言不同,它是离操作系统较近的语言。所以学好 C/C++ 体系的技术栈必须结合操作系统的运行机制来学习,通俗地说,就是你必须掌握操作系统层面的几大基础知识,他们是汇编、编译链接与运行时体系、狭义的操作系统原理、多线程、网络编程,只有这样学习,你才能学的懂、学的通透、学以致用。咱们学习 C++ 不是为了理论研究,而是付诸实践,投入生产是吧。
用一张图来概括一下 C++ 技术栈吧:
C++ 面试关于语法部分一般会问以下一些问题,当然这些问题也是 C++ 开发必备:
部分同学对以上问题总是搞不清楚,但是又不知道如何学习,于是从网上找各种文章来学习,造成这块的知识非常零碎,无法构成体系,其实这与其在网上花费大量时间,不如系统地看一下侯捷老师翻译的《深度探索 C++ 对象模型》一书。 这本书专注于 C++ 面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得多么大的效率。对于 C++ 底层机制感兴趣的读者,这是一本让你大呼过瘾的绝妙好书。
另外,时至今日,各大企业虽然项目中未必用到 C++11/14/17 常用的语言特性和类库,但是面试还是对这些有一定的要求的,常问的有:
C++11/14 网上的资料已经很多了,C++17 的资料不多,重头戏还是 C++11 引入的各种实用特性,这就给读者推荐一些我读过的不错的书籍:
当你学习好了 C++ 语言本身,你可以学习一下 C++ 的一些常见惯用法和高性能编码实践,这里我推荐一本经典书籍叫《提高 C++ 性能的编程技术》,这本书详细讨论了临时对象、内存管理、继承、虚函数、内联、引用计数以及 stl 等一切有可能提升 C++ 效率的细节内容。最终,该书将c++性能提升的各种终极利器,完美地呈现在读者的面前!最关键的是,这本书非常薄,但是书中介绍的每个专题都是实战中常用的技术,强烈推荐。
在掌握了 C++ 常用语法和语言背后的实现机制和常用惯用法后,我强烈推荐另外两本书,一本是 《C++ API 设计》 和《大规模 C++ 程序设计》,前者从细粒度地教你在实际开发中如何设计 C++ API 接口,后者告诉你大型 C++ 程序小到单个 .h/cpp 文件如何编写,大到大型 C++ 项目如何组织的最佳实践。这两本书都是工程实践的图书,书中的技术可以实实在在地用于一线开发。
第一个基础知识是汇编。
我们学习汇编不是一定要用汇编来写代码,就像我们学习 C/C++ 也不一定单纯为了面试和找工作。
对于 C/C++ 的同学来说,汇编是建议一定要掌握的,只有这样,你才能在书写 C++ 代码的时候,清楚地知道你的每一行C++代码背后对应着什么样的机器指令,if/for/while 等基本程序结构如何实现的,函数的返回值如何返回的,为什么整型变量的数学运算不是原子的,最终你知道如何书写代码才能做到效率最高。掌握了汇编,你可以明白,在 C++ 中,一个栈对象从构造到析构,其整个生命周期里,开发者的代码、编译器和操作系统分别做了什么。
掌握了汇编,你可以理解函数调用是如何实现的,你可以理解函数的几种调用方法,为什么printf这样的函数其调用方式不能是 __stdcall,而必须是 __cdecl。掌握了汇编,你就能明白为什么一个类对象增加一个方法不会增加其实际占的内存空间。推荐的书籍是王爽老师的《汇编(第三版)》 和韩宏老师的《老码识途 从机器码到框架的系统观逆向修炼之路》 。
第二个基础知识是编译、链接与运行时体系知识。
作为一个开发者,要清楚地知道我们写的 C/C++ 程序是如何通过预处理、编译与链接等步骤最终变成可执行的二进制文件,操作系统如何识别一个文件为可执行文件,一个可执行文件包含什么内容,执行时如何加载到进程的地址空间,程序的每一个变量和数据位于进程地址空间的什么位置,如何引用到。一个进程的地址空间有些什么内容,各段地址分布着什么内容,为什么读写空指针或者野指针会有内存问题。一个进程如何装在各个 so 或 dll 文件的,这些文件被加载到进程地址空间的什么位置,如何被执行,数据如何被交换。
第三个基础知识是狭义的操作系统原理。这里加上“狭义”二字是因为从广义上来讲,以上所说的内容都是操作系统原理的范畴。狭义的操作系统原理这里包括操作系统如何管理进程与线程,虚拟内存与物理内存之间的对应关系,何为内存映射文件,进程之间如何通信等等。
这两者推荐的书单:《程序员的自我修养》和 《Windows 核心编程》,尤其是《程序员的自我修养》,搞 C++ 开发不看此书,读尽 C++ 语言书也枉然!
第四个基础知识是多线程知识。
严格来说,这点已经包括在第三点之中了,我之所以将其单独列出来,是因为多线程编程是我们做应用服务最常用的技术之一。最近面试过几个学历非常好的同学,对于一个进程中如果某个线程因为内存问题而退出,是否会导致整个进程退出的问题答不好,实在不应该。多线程知识其实不难学,立足于理解与实践而不是应付面试,可以学的很好。无论是 Windows 还是 Linux 操作系统,操作系统提供的线程同步对象就那么几种,Windows 常用的有临界区(关键端)、Event、互斥体、信号量等,Linux 有互斥体、信号量、读写锁、条件变量,这些知识点学过则会,不学则不会。这些线程同步原语花上几天就能搞得清楚,大多数同学不是学不会,而是不愿意学,但是偏偏喜欢在简历上写上自己熟悉多线程编程。面试的时候,被问到条件变量的虚假唤醒机制都说不清楚,非要说自己用过条件变量。这是一些同学犯的很低级的错误,如果真用过条件变量,如果不知道虚假唤醒机制,那一定写的代码是不对的。市场上目前没有任何一本图书对以上知识形成体系的介绍,当然,我的本书填补了这一空缺,你将从本书中获得从进程与线程的关系,再到常用的线程同步原语的区别与使用场景,再到线程池以及基于生产者消费者模型的消息队列,以及对协程思想介绍的相关知识。
掌握了常见的多线程同步原语之后,接下来可以找一些带多线程的项目去学习一下,不管是否带 UI 的都行。我推荐的一种方式是,使用 gdb 或者 Visual Studio 调试器将你需要学习的多线程程序中断下来,在多线程面板,看看这个进程一共有多少个正在运行的线程,分析每个线程的作用,然后研究下这些线程在何时何地创建的,为什么需要创建新的线程。尝试爱过几个人,面对爱情你会诚实很多;尝试研究几个多线程项目,面对多线程你会熟练许多。
推荐的书单 《C++ 服务器开发精髓》。
第五个是网络编程,直白地说就是 Socket 编程。操作系统层面提供的 API 会在相当长的时间内保持接口不变,一旦学成,终生受用。理解和掌握常用的基础 socket API 不仅可以最大化地去定制各种网络通信框架,更不用说使用市面上流行的网络通信库了,最重要的是,它会是你排查各种网络疑难杂症坚实的技术保障。操作系统层面提供的网络模型就那么几种,无论像 Java/Go/Python 等语言如何封装,作为技术的源头,我们有什么理由不去掌握它呢?推荐的书单 《TCP/IP 网络编程》和《Linux 高性能服务器编程》 。
以上是基于 C++ 技术栈来说,并没有包括算法与数据结构、数据库等方面的基本功。总而言之,学习 C++ 不能只盯着 C++ 语法本身,还要熟悉 C++ 技术栈背后的一系列操作系统原理。
光纯粹通过看书,可能学习效果不一定好,你一定要装一个 C/C++ 语言开发工具实际去写一写 C/C++ 代码,
Windows 上我推荐学习 Visual Studio 编译、调试和运行 C/C++ 代码,以下是一些步骤:
Visual Studio 2019 启动画面
新建一个工程
创建一个控制台程序
给控制台程序起一个名字
如果学习C语言,可以将 .cpp 文件扩展名改成 .c
编译项目
添加程序断点
启动调试
学会在“监视窗口”查看运行过程中的变量名
学会在“堆栈窗口”查看程序调用堆栈
学会在“内存窗口”查看程序变量的内存值
调试状态下,需要熟悉的一些窗口
如果你不想只用 C 语言写一些黑洞洞的命令行程序,可以看一下《Windows 程序设计(第五版)》这本书,这本书从零教你如何编写 Windows 界面程序:
这本书是一本经典的 Windows 编程圣经,曾经伴随着近 50 万 Windows 程序员步入编程殿堂,成长为 IT 时代的技术精英,可以这么说,中国常用的 QQ、360 安全卫士的开发者都是靠这本书启蒙的。
如果你在 Linux 下使用 C 语言编写服务程序,要学会 gcc、Makefile、CMake 等工具,推荐一下《GNU Make 手册》:
链接: https://pan.baidu.com/s/11NZs2IPi8sMZu4n8LRgttA 提取码: hcj6
和《CMake 最佳实践》这两本书:
链接: https://pan.baidu.com/s/1flVSq6bwu0n-Y7vXheVpkw 提取码: 44ta
编译好程序之后,你可以使用 GDB 进行调试,GDB 掌握常用命令即可,这个很容易学,实际上手操作一下,几分钟就学会了,GDB 常用命令:
GDB 常用命令
学习 GDB 推荐《Debugging with GDB》一书:
链接: https://pan.baidu.com/s/1e3toHeLoQrnEr1KS7Rhn7g 提取码: h0d3
如何阅读开源项目可以看这里:
如何调试开源 C/C++ 项目的代码可以看这里:
2016 年的时候,我无意中发现我用了多年的 FTP 软件 Filezilla 竟然用 C++ 11 重写了。
Filezilla界面
FileZilla 的源码是一个德国开发者写的,其代码质量也不错,而且使用的是 C++11 写的。可以一边调试一边学习,学完后,我的 C++11 功能得到了大大增强。
不怕你笑话,我在上学的时候,曾看过 Filezilla 0.x 版本的代码,那个时候 UI 界面用的还是 MFC。
贴一下 Filezilla 的部分代码,红框标出来的部分为 C++11 的语法特性:
代码质量总体很不错。我修改了下让其可以在 Visual Studio 中调试,这样你可以一边调试一边学习。
一套源码如果能够容易编译、调试,同时其业务是容易理解的(通俗地说,就是这套代码的功能是什么的),那么才利于新手学习。
我已经将环境和依赖都配置好了,代码获取方式:
打开关注后回复“获取Filezilla源码”得到下载链接
3.6.2. uWebSocket
uWebSocket 是一款开源的 WebSocket 库,最新版使用了大量 C++17 的语法,代码量非常少。
下载地址:https://github.com/uNetworking/uWebSockets
我们改造了这个项目,用于我们的交易系统的行情推送服务器。
TeamTalk 是蘑菇街开源的一款用于企业内部的即时通信工具,其代码下载地址是:
https://github.com/balloonwj/TeamTalk
POCO C++ Libraries - Simplify C++ Development poco 库是一个代码质量非常高,且文档比较丰富的 C++ 库,实现了常用的一些功能,可以根据自己的喜好挨个看。
https://pocoproject.org/
https://github.com/balloonwj/flamingo
我为 Flamingo 专门录制了 3 部高清技术讲解视频以方便读者学习,视频中介绍了 Flamingo 的编译和部署方法、整体架构、各个模块的技术实现细节以及如何学习Flamingo的方法,需要视频教程下载链接:
链接: https://pan.baidu.com/s/1p_dBPJqgsvpLXvVyCotjUg 提取码: ah6c
https://github.com/balloonwj/TinySTL
学好 C/C++ 并非一朝一夕之功,需要不断坚持加努力,一旦学成,奇妙无穷,加油!!
Java 的基础知识包括如下部分:
学习 Java 基础知识推荐以下两本书:
有人提到《Thinking In Java》这本书,那就说一下这本书,这个书出版的年代比较久远了,加上 JDK 已经更新换代很多年了,各种新的特性和接口被加进来,这本书中部分内容已经过时了,加上这本书比较厚,如果时间不是很充足,不建议使用这本书学习。
Java 并发编程首推《Java并发编程实战》:
另外《Java并发编程的艺术》这一本也不错。
无论是 Java 面试还是想成为 Java 高手或者在一些项目中进行性能调优都必须掌握的知识,一般需要掌握以下内容:
推荐的书是《深入理解Java虚拟机》,周志明老师的这本书现在已成了 Java 虚拟机中的经典的经典,建议从事 Java 开发的同学一定要好好看一看。
另外,《揭秘Java虚拟机——JVM设计原理与实现》这本书也不错。
搞 Java 的如果不熟悉 Netty 框架,那很难成为高手,虽然我们平常开发基本不会直接用到 netty,但是各种框架底层基本上都用的是 Netty,学习 Netty 可以分两步走:
现在 Java 的主流开发基本使用 SSM 框架,所谓 SSM 框架指的是 Spring + Spring MVC + MyBatis。关于 SSM 的书,其实没有特别好的,可以自己搭个框架,边看边调试,或者结合一些网络实例视频来学习。推荐
需要注意的是,无论学 C++ 还是 Java,想要在技术之路走的远,一定不要疏忽数据结构算法、操作系统原理、计算机网络、设计模式、数据库等基础知识的学习。
原创不易,如果觉得有用,请给 @张小方 点个赞吧。
你好,我是张小方,畅销书《C++服务器开发精髓》作者,多年 C/C++/Java/Golang 开发经验,大厂技术专家、面试官,擅长客户端和高性能高并发服务开发。
我创作了专辑《C++高级进阶》《后端开发面试题》《多线程重难点解析》《网络编程重难点解析》《网络通信协议深度解析》《服务器开发进阶》《面试、offer 与薪资那些事儿》《职业规划》《张小方的故事》。