【linux C++】技术学到多厉害,才能顺利进入 BAT?

2023-12-15 19:25:28

在这篇文章中,BAT 某厂 C++ 研发工程师分享了他是如何学好 Linux、C++,并搞定 BAT 面试的。一起来看看吧,希望他的经历与经验能够给大家带来一定的启发。

起始于 Linux、C++ 的技术进阶之路

本科时,我对 Linux 特别感兴趣,心中一直向往成为一名运维工程师,就开始没日没夜地看相关的书籍。

到了大约 2013 年前后,发现 DevOps 开始流行起来了,就开始学习 Python 希望成为一名 DevOps 工程师。但后来出去实习才发现,从事运维相关的工作并不是我的追求。

苦于在合肥这样的城市真的很难找到一份专职做 DevOps 的地方(当时在科大讯飞时,做的就是纯运维的工作,该公司的 DevOps 也才有个雏形)。

所以我萌生了考研的想法,希望在 Linux 内核这个层面做深造。最终,我选择了西安邮电大学,因为该校的陈莉君老师是我比较崇拜的对象,一直在拜读她的《深入理解 Linux 内核》一书。

后来上了研究生后,我开始专注 Linux 内核、C/C++ 服务端开发等工作。至于为何选择 C/C++,理由很简单 —— 大家都去学 Java 了,我要是也去学 Java,那么我的优势何在?而且,C/C++ 也更偏向底层,是我比较感兴趣的地方,所以最终选择了 C/C++。

我的研究生三年所有的心思都投入到了 C/C++ 以及 Linux 内核上,不敢说对 C/C++有什么独特的见解,至少我觉得自己的学习经历还是可以给大家作为一个参考。

Linux 从运维到 DevOps

先简单花一些篇幅介绍下我的这段学习经历。我的 Linux 启蒙老师,还是要源于培训,大学那会经常有一些培训公司会来我们学习做免费培训,想让我们花钱去培训。记得当时最流行的两个证书一个是 RHCE(RedHat 相关的认证),另外一个则是 CCNA、CCNP(思科网络相关的认证),彼时的我深深地被 Linux、OpenSource、Linux 那酷炫的黑框框吸引了。

我理想中的 Hacker 应该就是整天在黑框框中敲着一堆看不懂的字符。就这样,开始一头扎到 Linux 的世界中,我的第一本入门书是大学图书馆借的一本 Linux 用户指南,具体的书名已经记不起来了。

后来开始读鸟哥的私房菜,这本书在当时真的很好,我没有想太多,只知道疯狂地读完整本书,一遍、二遍……就这样我读了五遍,上面的实验不停地练习、命令不停地练习。

但入门后,我开始迷茫了,因为不知道下一步该学什么,便又疯狂地开始寻找下一个目标,也就有了“西安鹏程 Linux 网络服务视频”带领着我进入到 Linux 最神秘的世界。

在这里,我发现 Linux 能做很多很多有趣的事情,便开始搭建 Apache 服务器了,居然可以运行一个网站了。此外,我还学会了用 Linux 做 DHCP 服务器、DNS 服务器、VSFTP 服务器。一时间,我像是打开了一个新世界,后来,开始接触网络、搭建路由器、防火墙等等。

当时,觉得 Linux 真的很奇妙,我还利用 Linux 搭建了 HTTP 代理服务器,然后在宿舍通过学校实验室部署的 HTTP 代理服务器来免费上网。

后来开始出去实习,我就已经可以实现不看任何文档,从头源码编译 LNMP,并搭建 Discuz! 论坛,就靠这个本事我找到了第一份实习,工资是 1800 块。

不过我却发现工作了就没有心思学习,所以又回到了学校,再好好巩固自己的基础,并下定决心开始考研深入学习 Linux。在考研的期间,我发现了马哥 Linux,这又是我人生中另外一个起点。

马老师讲课注重原理和实践,七分原理三分实践,通过他的课程我的 Linux 水平提升了一个很大的档次,他的全套课程我完整地听过三遍,每一个课程上的实验都做了至少五遍以上,这奠定了我的 Linux 和 Shell 脚本的基础。此后,在我的职业生涯中,Shell 脚本一直是我最强有力的助手,在研究生阶段我还专门做过 Shell 脚本相关的分享。

在 2013 到 2014 年这段时间开始流行自动化运维、Python,于是我开始学习 Python,还有现在比较流行的 Flask 框架,自认为应该是最早一批 Flask 框架的用户了。

当时国外人出的一本《Flask Web 开发:基于 Python 的 Web 应用开发实战》书,我也是第一时间从某宝上买到并阅读,只可惜后面转到 C++ 后就没再看过了,这期间用 Flask 做过一个博客。

在研究生阶段,还帮同学和一些朋友运维过一些网站,做一些简单的调优和加固。到此为止,我的 DevOps 之路终结了,从此走向了 Linux C/C++ 的路上。

通过上面我的这些经历,给大家简单地总结下 —— 我认为学好 Linux 运维需要做到以下几点:

  1. 多做实验,实验环境完全可以通过 VMware 来模拟,模拟私有网络,模拟多台机器,要搞懂 VMware 提供的集中网络模式的工作原理(桥接网络、宿主机网络、NAT 等),这对整个 Linux 后续的学习帮助都非常之大,还可以通过虚拟机模拟 Grub 损坏并进行修复、模拟忘记密码并通过单用户模式修改密码等等。

  2. LNMP、DHCP、DNS、MySQL 等等这些网络服务需要完全基于源码来编译,这样更加有体感,对于编译的参数要理解,因为通过 Yum 安装的软件包都是上一个稳定版本,并不是最新稳定版本,还有另外一点就是编译安装可以通过编译参数对软件进行一定的优化。

  3. Linux 基础要扎实,底层原理要理解,典型的文件系统的组成、inode 和数据存放的位置、Linux 进程是如何调度的、调度算法有哪些、磁盘调度算法有哪些、TCP/IP 的三次握手和四次挥手的过程是如何的,网络中的数据是如何流向的(参考《构建高性能 Web 站点》),iptables 的三表五链、Nginx 的网络 IO 模型(这个很重要,你要能讲清楚为什么 Nginx 要比 Apache 好),马哥 Linux 对于这个部分的内容讲解是我最喜欢的,我强力推荐大家都去听一听马哥的视频。

  4. 英文文档的阅读能力,阅读各类开源软件的官方文档是必经之路,这个也是了解一个开源软件最快的捷径,如果你没有一定的英文阅读能力,那么你只能等到有人把这些文章翻译成中文后你才能学习到。

  5. 写博客,很多时候,看了视频和书后,如果你不能讲这些知识用你的语言表达出来,那么很大可能,你并没有真正的理解这些知识,通过写博客的方式会逼迫你回忆知识,然后总结出来,博客被大量人访问也会在一定程度上激励你,让你有一定的成就感,促使你把博客写的更好。

  6. Shell 脚本的要熟悉,运维这条路上脚本会帮我们省掉不少体力活,此外必须要学习一门编程语言 Python、Golang 等。

C++ 从小白到入门

C++ 我是从研究生入学前的两个月开始学习,基本算是零基础吧,就大学那会学了一些 C 的知识,经常写一个程序一堆“烫烫烫”,真的是到了本科毕业还没搞懂 C 语言。

然后在这两个月我开窍了,突然发现对 C 语言融汇贯通了, 而这一切要归功于《C 和指针》这本书。总结一下,我认为 C 语言要学好必须理解三个概念。

  1. 什么是指针?指针和数组的关系。

  2. 程序分为哪几个段,能说清楚全局变量,局部变量,静态变量等分别属于哪个段,各个段的特点是什么?

  3. C 语言的编译和链的接过程。

另外,真心不推荐在 Windows 上来学习 C 语言,因为它屏蔽了太多的细节,而这些细节却又是 C 程序员不可或缺的一部分。

C 语言这个阶段过去后,我开始学习 Linux C 系统编程这个部分,最开始接触的一本书就是《Unix/Linux 编程实践教程》强力推荐给大家,这本书会给你介绍如何通过 man 手册来帮助编程,如何去实现 who、cat、ls、ps 等系统命令。通过这本书的学习会让你对 Linux 上很多的原理有一个深刻的认识。

这本书学完后我就开始看 UNP 和 APUE,其中 APUE 我并不推荐给大家,我推荐给大家的是《Linux/UNIX 系统编程手册》这本书的内容更全面,更新。

建议大家在看这些书的时候可以做详细的笔记和代码练习。

系统编程 ok 后,就要重点看 UNP 了,看这本书的时候要找重点看,里面有的章节已经过时了,还有一些章节对于我们目前来说用途并不大,比如 STCP 的部分。对于这本书重点有三个部分。

  1. 各个 socket API 的对应到 OS,做了哪些事情,比如 connect 后,做了哪些事情?,accept 呢?,什么是 RST 报文?,什么是 SIGPIPE,如何触发的?

  2. 网络 IO 模型,同步和异步,阻塞和非阻塞的概念,Linux 上各种网络 IO 模型的优缺点对比,epoll、select、信号驱动 IO 等。

  3. 服务器的网络编程模型,多线程、多进程、线程池等,各自优缺点。

学完这个后,剩下的就靠多实践和多读一些开源的项目来积累自己的经验了,这里推荐 cjson、webbench、Tinyhttpd 等,代码量都不大,很容易读懂,在读懂的基础上可以进行适当的改造和重写。

C 语言和 Linux 系统编程这个部分结束后,就要开始踏入 C++ 的世界了,自从 C++11 出来后,我觉得 C++ 易学了,但是苦于现存的老的 C++ 代码还是有很多。

所以我们不得不去学习 C++98 相关的知识,这里我推荐《C++ primer》一书,注意是 C++ primer,不是《C++ primer plus》我看书的方法都比较老套,第一遍力求看懂,第二遍开始抄代码,练习,第三遍开始总结写博客。

所以这本书我前前后后看了大半年, 后面又看了 C++编程思想上册,Effective C++、深度理解 C++ 对象模型、Exceptional C++、深入理解 C++11 等经典书籍,看书的模式基本上都是二到三遍,通过抄书上的代码和写博客来加深记忆。

看完这些书说真的,我觉得我的 C++ 还只是一个小白,真正蜕变要从读《Linux C++ 服务端编程》这本书开始,通过这本书,我的 C++ 水平有了一个质的飞跃。我理解 C++ 有以下几个要点(只是部分):

  1. RAII,这个很重要,是 C++ 的核心,很多学习了 C++ 的人都不知道 RAII;

  2. 值语义和对象语义,这个决定了你如何写好一个 C++类

  3. 对象的生命周期,类的生命周期要清晰;

  4. 智能指针,现代 C++ 编程几乎不太可能出现 delete 语句,内存泄漏的问题真的很少会出现;

  5. 各种 STL 和 C++ 的一些坑,比如迭代器遍历过程中如何删除元素、std::list 的 size 接口的复杂度居然是 O(N)(C++11 已经修正)等等;

  6. 善用 std::bind 和 std::function;

  7. 基于对象编程和面向对象编程的区别;

  8. 移动语义很重要;

  9. Lambda 的捕获表达式;

  10. 搞清楚 C++ 的三五法则;

  11. std::string 的实现方式,是否是线程安全的;

  12. std::map 和 std::set 的底层数据结构等。

到了这个阶段后我就开始找工作了,上面的全部过程花费了研究生两年的时间,后来找到了某 BAT 实习的工作后,我就一边实习,一边读《Effective Modern C++》,这本书我重点推荐给大家,这本书讲了很多 C++11 种的一些实现细节、坑以及建议。最后推荐一些 Linux 内核相关的书籍和学习方法。

  1. 《深入理解 Linux 内核架构》

  2. 《Linux 环境编程 从应用到内核》

  3. lwn.net

  4. 重点找自己感兴趣的模块来看,比如我就对文件系统。

  5. 通过内核模块来探索,不能只看代码不练习。

网络上有很多从头开始编写一个内存文件系统的文章,通过编写 Linux 内核模块可以做很多有趣的事情,比如系统调用拦截、网络拦截、做安全审计等等,通过编写内核模块可以提高对 Linux 内核学习的兴趣。

linux内核学习推荐视频

高级程序员的殿堂:深入剖析linux内核源码(进程管理、内存管理、网络协议栈、文件系统、设备驱动)icon-default.png?t=N7T8https://www.bilibili.com/video/BV14a4y1U7UJ/

BAT 求职之路

研究生阶段我主要面试了阿里巴巴、腾讯、网易都是 C++ 研发工程师,只有网易拿到的是实习 Offer,其他都是拿到了实习和正式的 Offer,就 C++ 这个岗位来说,阿里巴巴的要求明显高于腾讯和网易,网易的 C++ 面试相对容易一些,问的很基础,感觉就是走个过场,都没问什么太难的问题,可能因为是招实习吧。

腾讯的 C++ 面试偏基础,从 OS、网络、编译原理、算法等,问题都不太难,问的比较广,阿里巴巴更侧重知识面、底层原理、解决问题的能力等。

我阿里巴巴一共面了五面,问了很多 C++、算法、Linux 内核等知识,在整个求职过程中,我做了以下几件事:

  1. 刷 leetcode 的题目;

  2. 从牛客网和 Google 上搜集面试题,分门别类地进行整理,每天都回顾一下;

  3. 拓宽自己的知识面,学习一些新的知识,比如当时流行的 Docker,更侧重学习其原理;

  4. 加深自己对一些底层的 OS 知识的理解,比如 epoll 的原理、Docker 的 cgroup 机制和 namespace 机制的实现、文件系统 VFS 的实现、Linux 信号、管道等的实现。

整理面试题和学习一些底层的 OS 知识对我整个面试过程中帮助很大,正常情况下如果你只学习 Java 或者 C++ 是很难拿到阿里巴巴的 Offer,阿里巴巴对应届生的知识面、知识的理解程度要求还是比较高的。

在我的整个 C++ 面试过程中,问的最多的就是 IO 复用、智能指针、内存泄漏的问题如何解决、如何排查 Load 高的问题、Linux 内核相关的知识等,而这些问题对我来说早已得心应手,在搜集面试题的时候很多问题都是反复被提及到的,我只需要好好总结即可。

另外一点就是大家在准备面试题的时候不能只记一个结论,多问问为什么,举个例子,TCP/IP 的三次握手和四次挥手的过程是什么样的,我们不光要知道这个问题的结论,还要知道为什么是三次握手,四次挥手,为什么不是二次?

当被问及到 epoll、select 的区别时,你应该从使用方法、可移植性、性能、优缺点、内核实现等多个方面分析和总结。而不是简简单单的就提及一个优缺点就完事了。 你擅长的地方你应该多多引导你的面试官去问。

工作心得

在公司实习了大约 1 年,今年七月份正式入职,在这整个过程中我也零散的做了很多小需求,对 C++ 的理解更加深刻,尤其是对软件工程有了一个新的理解,在此我想分享给大家。

  1. 要有造轮子的能力,但是不要轻易去造轮子;

  2. 单元测试的重要性,通过单元测试也可以提高程序员的信心,为了更好的写单测,会逼迫我们将模块之间的耦合降到最低,这样可以方便单测;

  3. 写易读的、可维护的代码;

  4. Google 的 C++ 编程规范,每一条都值得细细品味;

  5. Chromium 开源项目有很多值得我们借鉴的地方;

  6. 画 UML 图是程序员的基本素质,要有好的设计,设计要做评审;

  7. CodeReview 一定要有的;

  8. 类名和变量名的易读性。

可能对于很多人来说编码规范、CodeReview、UML、单测好像都是说说而已,我起初也是这么认为,感触并不是很深刻。直到我的同事开始带我的时候,我自己亲身去体验的时候才发现这其中奥妙无穷。我们团队使用 Chromium 的 base 库作为自己的基础库,编码规范、全都 follow Chromium。

至于为什么不用 boost,我的理由则是,boost 是一个我无法驾驭的怪兽,而 chromium 的 base 库是我可以驾驭的,可以打组合拳,代码的稳定性已经经过上亿人的考验,值得我们信赖。

推荐大家看看 chromium 的 base 库,源代码很易读。通过阅读它的代码可以学习到很多知识。

推荐一本书给大家《C++ API 设计》,讲解了很多软件工程、设计层面的知识。

总结

上面说了很多,更侧重分享了我的学习经历,和一些感悟,可能我说的比较简单,实际上理解上面这些东西,是存在一个过程的,是一个从量变到质变的过程,在整个过程中我理解到,学习要坚持,不是一蹴而就的,要经历量变到质变的过程。

最后给大家推荐一个linux c/c++开发的完整学习路线(取自零声教育课程大纲)

首先一起来看看一些往期的录播视频,感受一下讲师的技术水平(讲师均来自大厂,经验丰富)

C++网络编程(tcp/ip、epoll、reactor、协程、io_uring、websocket、libevent)icon-default.png?t=N7T8https://www.bilibili.com/video/BV16w411S75s/

c++后端基础组件(线程池、内存池、数据库连接池、自旋锁、死锁、内存泄漏检测、分布式锁...),大厂面试高频技术点icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Do4y1z7VR/

【linux c/c++全栈开发】如何提升c/c++编程水平?这9个c/c++实战项目,一定不要错过!!!(实操+代码实现)icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Jg4y1X73Y/

下面来看看linux c/c++后端服务器开发究竟需要学习哪些知识

1.精进基石专栏

1.1 数据结构与算法

1.1.1 随处可见的红黑树

  • 红黑树的应用场景进程调度cfs,内存管理

  • 红黑树的数学证明与推导

  • 手撕红黑树的左旋与右旋

  • 红黑树添加的实现与添加三种情况的证明

  • 红黑树删除的实现与删除四种情况的证明

  • 红黑树的线程安全的做法

  • 分析红黑树工程实用的特点

1.1.2 磁盘存储链式的B树与B+树

  • 磁盘结构分析与数据存储原理

  • 多叉树的运用以及B树的定义证明

  • B树插入的两种分裂

  • B树删除的前后借位与节点合并

  • 手撕B树的插入,删除,遍历,查找

  • B+树的定义与实现

  • B+树叶子节点的前后指针

  • B+树的应用场景与实用特点

  • B+树的线程安全做法

1.1.3 海量数据去重的Hash与BloomFilter,bitmap

  • hash的原理与hash函数的实现

  • hash的应用场景

  • 分布式hash的实现原理

  • 海量数据去重布隆过滤器

  • 布隆过滤的数学推导与证明

1.2 设计模式

1.2.1 创建型设计模式

  • 单例模式

  • 策略模式

  • 观察者模式

  • 工厂方法模式与抽象工厂模式

  • 原型模式

1.2.2 结构型设计模式

  • 适配器模式

  • 代理模式

  • 责任链模式

  • 状态模式

  • 桥接模式

  • 组合模式

1.3 c++新特性

1.3.1 stI容器,智能指针,正则表达式

  • unordered_map

  • stl容器

  • hash的用法与原理

  • shared_ptr,unique_ptr

  • basic_regex, sub_match

  • 函数对象模板function,bind

1.3.2 新特性的线程,协程,原子操作,lamda表达式

  • atomic的用法与原理

  • thread_local 与condition_variable

  • 异常处理exception_ptr

  • 错误处理error_category

  • coroutine的用法与原理

1.4 Linux工程管管理

1.4.1 Makefile/cmake/configure

  • Makefile的规则与make的工作原理,

  • 单文件编译与多文件编译

  • Makefile的参数传递

  • 多目录文件夹递归编译与嵌套执行make

  • Makefile的通配符,伪目标,文件搜索

  • Makefile的操作函数与特殊语法

  • configure生成makefile的原则

  • cmake的写法

1.4.2 分布式版本控制git

  • git的工作流程

  • 创建操作与基本操作

  • 分支管理,查看提交历史

  • git服务器搭建

1.4.3 Linux系统运行时参数命令

  • 进程间通信设施状态 ipcs

  • Linux系统运行时长 uptime

  • CPU平均负载和磁盘活动 iostat

  • 监控,收集和汇报系统活动 Sar

  • 监控多处理器使用情况 mpstat

  • 监控进程的内存使用情况 pmap

  • 系统管理员调优和基准测量工具 nmon

  • 密切关注L inux系统glances

  • 查看系统调用 strace

  • ftp服务器基本信息 ftptop

  • 电量消耗和电源管理 powertop

  • 监控mysql的线程和性能 mytop

  • 系统运行参数分析 htop/ top/atop

  • Linux网络统计监控工具 netstat

  • 显示和修改网络接口控制器 ethtool

  • 网络数据包分析利刃 tcpdump

  • 远程登陆服务的标准协议 telnet

  • 获取实时网络统计信息 iptraf

  • 显示主机上网络接口带宽使用情况 iftop

2.高性能网络设计专栏

2.1 网络编程异步网络库 zvnet

2.1.1 网络io与io多路复用select/poll/epoll

  • socket与文件描述符的关联

  • 多路复用select/poll

  • 代码实现LT/ET的区别

2.1.2 事件驱动reactor的原理与实现

  • reactor针对业务实现的优点

  • epoll封装send_cb/recv_cb/accept_cb

  • reactor 多核实现

  • 跨平台(select/epoll/kqueue)的封装reactor

  • redis,memcached,nginx网络组件

2.1.3 http服务器的实现

  • reactor sendbuffer 与recvbuffer 封装http协议

  • http协议格式

  • 有限状态机fsm解析http

  • 其他协议websocket,tcp文件传输

2.2 网络原理

2.2.1 服务器百万并发实现(实操)

  • 同步处理与异步处理的数据差异

  • 网络io线程池异步处理

  • ulimit的fd的百万级别支持

  • sysctl. conf的rmem与wmem的调优

  • conntrack的原理分析

2.2.3 Posix API与网络协议栈

  • connect,listen,accept与三次握手

  • listen参数backlog

  • syn泛洪的解决方案

  • close与四次挥手

  • 11个状态迁移

  • 大量close_ wait与time_ wait的原因与解决方案

  • tcp keepalive与应用层心跳包

  • 拥塞控制与滑动窗口

2.2.4 UDP的可靠传输协议QUIC

  • udp的优缺点

  • udp高并发的设计方案

  • qq早期为什么选择udp作为通信协议

  • udp可靠传输原理

  • quic协议的设计原理

  • quic的开源方案quiche

  • kcp的设计方案与算法原理

2.3 自研框架:协程框架NtyCo的实现(已开源)

2.3.1 协程设计原理与汇编实现

  • 协程存在的3个原因

  • 同步与异步性能,服务端异步处理,客户端异步请求

  • 协程原语switch, resume, yield

  • 协程切换的三种实现方式,setjmp/longjmp,ucontext,汇编实现

  • 汇编实现寄存器讲解

  • 协程初始启动eip寄存器设置

  • 协程栈空间定义,独立栈与共享栈的做法

  • 协程结构体定义

2.3.2 协程调度器实现与性能测试

  • 调度器的定义分析

  • 超时集合,就绪队列,io等待集合的实现

  • 协程调度的执行流程

  • 协程接口实现,异步流程实现

  • hook钩子的实现

  • 协程实现mysql请求

  • 协程多核方案分析

  • 协程性能测试

2.4 自研框架:基于dpdk的用户态协议栈的实现(已开源)

2.4.1 用户态协议栈设计实现

  • 用户态协议栈的存在场景与实现原理

  • netmap开源框架

  • eth协议,ip协议, udp协议实现

  • arp协议实现

  • icmp协议实现

2.4.2 应用层posix api的具体实现

  • socket/bind/listen的实现

  • accept实现

  • recv/send的实现

  • 滑动窗口/慢启动讲解

  • 重传定时器,坚持定时器,time_wait定时器,keepalive定时器

2.4.3 手把手设计实现epoll

  • epoll数据结构封装与线程安全实现

  • 协议栈fd就绪回调实现

  • epoll接口实现

  • LT/ET的实现

2.5 高性能异步io机制 io_uring

2.5.1 与epoll媲美的io_uring

  • io_uring系统调用io_uring_setup,io_uring_register, io_ur ing_enter

  • I iburng的io_uring的关系

  • io_uring与epoll性能对比

  • io_uring的共享内存机制

2.5.2 io_ uring的使用场景

  • io_ur ing的accept,connect,recv,send实现机制

  • io_uring网络读写

  • io_uring磁盘读写

  • proactor的实现

3.基础组件设计专栏

3.1 池式组件

3.1.1 手写线程池与性能分析(项目)

  • 线程池的异步处理使用场景

  • 线程池的组成任务队列执行队列

  • 任务回调与条件等待

  • 线程池的动态防缩

  • 扩展:nginx线程池实现对比分析

3.1.2 内存池的实现与场景分析(项目)

  • 内存池的应用场景与性能分析

  • 内存小块分配与管理

  • 内存大块分配与管理

  • 手写内存池,结构体封装与API实现

  • 避免内存泄漏的两种万能方法

  • 定位内存泄漏的3种工具

  • 扩展:nginx内存池实现

3.2 高性能组件

3.2.1 原子操作CAS与锁实现(项目)

  • 互斥锁的使用场景与原理

  • 自旋锁的性能分析

  • 原子操作的汇编实现

3.2.2 无锁消息队列实现(项目)

  • 有锁无锁队列性能

  • 内存屏障Barrier

  • 数组无锁队列设计实现

  • 链表无锁队列设计实现

3.2.3 网络缓冲区设计

  • RingBuffer设计

  • 定长消息包

  • ChainBuffer 设计

  • 双缓冲区设计

3.2.4 定时器方案红黑树,时间轮,最小堆(项目)

  • 定时器的使用场景

  • 定时器的红黑树存储

  • 时间轮的实现

  • 最小堆的实现

  • 分布式定时器的实现

3.2.5 手写死锁检测组件(项目)

  • 死锁的现象以及原理

  • pthread_mutex_lock/pthread_mutex_unlock dlsym的 实现

  • 有向图的构建

  • 有向图dfs判断环的存在

  • 三个原语操作lock_before,lock_after, unlock_after

  • 死锁检测线程的实现

3.2.6 手写内存泄漏检测组件(项目)

  • 内存泄漏现象

  • 第三方内存泄漏与代码内存泄漏

  • malloc与free的dlsym实现

  • 内存检测策略

  • 应用场景测试

3.2.7手把手实现分布式锁(项目)

  • 多线程资源竞争互斥锁,自旋锁

  • 加锁的异常情况

  • 非公平锁的实现

  • 公平锁的实现

3.3 开源组件

3.3.1 异步日志方案spdlog (项目)

  • 日志库性能瓶颈分析

  • 异步日志库设计与实现

  • 批量写入与双缓存冲机制

  • 奔溃后的日志找回

3.3.2 应用层协议设计ProtoBuf (项目)

  • IM,云平台,nginx, http, redis协议设计

  • 如何保证消息完整性

  • 手撕protobuf IM通 信协议

  • protobuf序列化与反序列化

  • protobuf编码原理 4.中间件开发专栏

4.1 Redis

4.1.1 Redis相关命令详解及其原理

  • string,set , zset,list, hash

  • 分布式锁的实现

  • lua脚本解决ACID原子性

  • Redis事务的ACID性质分析

4.1.2 Redis协议与异步方式

  • Redis协议解析

  • 特殊协议操作订阅发布

  • 手撕异步redis协议

4.1.3 存储原理与数据模型

  • string的三种编码方式 int, raw, embstr

  • 双向链表的list实现

  • 字典的实现,hash函数

  • 解决 键冲突与 rehash

  • 跳表的实现 与数据论证

  • 整数集合实现

  • 压缩列表原理证明

4.1.4 主从同步与对象模型

  • 对象的类型与编码

  • 字符串对象

  • 列表对象

  • 哈希对象

  • 集合对象

  • 有序集合

  • 类型检测与命令多态

  • 内存回收

  • 对象共享

  • 对象空转时长

  • redis的3种集群方式 主从复制,sentinel,cluster

  • 4种持久化方案

4.2 MySQL

4.2.1 SQL语句, 索引,视图,存储过程, 触发器

  • MySQL体系结构,SQL执行流程

  • SQL CURD与高级查询

  • 视图,触发器,存储过程

  • MySQL权限管理

4.2.2 MySQL索引原理以及SQL优化

  • 索引,约束以及之间的区别

  • B+树,聚集索引和辅助索引

  • 最左匹配原则以及覆盖索引

  • 索引失效以及索引优化原则

  • EXPLAIN执行计划以及优化选择过程分析

4.2.3 MySQL事务原理分析

  • 事务的ACID特性

  • MySQL并发问题脏读,不可重复读,幻读

  • 事务隔离级别

  • 锁的类型,锁算法实现以及锁操作对象

  • S锁 X锁 IS锁 IX锁

  • 记录锁,间隙锁, next-key lock

  • 插入意向锁,自增锁

  • MVCC原理剖析

4.2.4 MySQL缓存策略

  • 读写分离,连接池的场景以及其局限a

  • 缓存策略问题分析

  • 缓存策略强一致性解决方案

  • 缓存策略最终一致性解决方案

  • 2种mysql缓存同步方案从数据库与触发器+udf

  • 缓存同步开源方案go-mysql-transfer

  • 缓存同步开源方案canal原理分析

  • 3种缓存故障,缓存击穿,缓存穿透,缓存雪崩

4.3 Kafka

4.3.1 Kafka使用场景与设计原理

  • 发布订阅模式

  • 点对点消息传递

  • Kafka Brokers原理

  • Topics 和 Partition

4.3.2Kafka存储机制

  • Partition存储分布

  • Partition文件存储机制

  • Segment文件存储结构

  • offset查找message

  • 高效文件存储设计

4.4 微服务之间通信基石gRPC

4.4.1 gRPC的内部组件关联

  • ClientSide与ServerSide, Channel,Serivce,Stub的概念

  • 异步gRPC的实现

  • 回调方式的异步调用

  • Server 与Client 对RPC的实现

4.4.2 基于http2的gRPC通信协议

  • 基于http协议构造

  • ABNF语法

  • 请求协议 Request-Headers

  • gRPC上下文传递

4.5 Nginx

4.5.1 Nginx反 向代理与系统参数配置conf原理

  • Nginx静态文件的配置

  • Nginx动态接口代理配置

  • Nginx 对Mqtt协议转发

  • Nginx对Rtmp推拉流

  • Openresty对Redis缓 存数据代理

  • shmem的 三种实现方式

  • 原子操作

  • nginx channel

  • 信号

  • 信号量

4.5.2 Nginx过滤器模块实现

  • Nginx Filter模块运行原理

  • 过滤链表的顺序

  • 模块开发数据结构ngx_str_t,ngx_list_t,ngx_buf_t, ngx_chain_t

  • error日志的用法

  • ngx_comond_t的讲解

  • ngx_http_module_t的执行流程

  • 文件锁,互斥锁

  • slab共享内存

  • 如何解决"惊群"问题

  • 如何实现负载均衡

4.5.3 Nginx Handler模 块实现

  • Nginx Handler模块运行原理

  • ngx_module_t/ngx_http_module_t的讲解

  • ngx_http_top_body_filter/ngx_http_top_header_filter的 原理

  • ngx_rbtree_t的使用方法

  • ngx_rbtree自定义添加方法

  • Nginx的核心数据结构ngx_cycle_t,ngx_event_moule_t

  • http请求的11个处理阶段

  • http包体处理

  • http响应发送

  • Nginx Upstream机制的设计与实现

  • 模块性能测试

5.开源框架专栏

5.1 游戏服务器开发skynet (录播答疑)

5.1.1 Skynet设计原理

  • 多核并发编程-多线程, 多进程,csp模型, actor模型

  • actor模型实现-lua服务和c服务

  • 消息队列实现

  • actor消息调度

5.1.2 skynet网络层封装以及lua/c接口编程

  • skynet reactor 网络模型封装

  • socket/socketchannel 封装

  • 手撕高性能c服务

  • lua编程以及lua/c接口编程

5.1.3 skynet重要组件以及手撕游戏项目

  • 基础接口 skynet.send , skynet.call , skynet.response

  • 广播组件 multicastd

  • 数据共享组件sharedatad datasheet

  • 手撕万人同时在线游戏

5.2 分布式API网关

5.2.1 高性能web网关Openresty

  • Nginx与lua模块

  • Openresty访问Redis,MySQL

  • Restful API接口开发

  • Openresty性能分析

5.2.2 Kong动态负载均衡与服务发现

  • nginx,openresty , Kong之 间的“苟且”

  • 动态负载均衡的原理

  • 服务发现实现的原理

  • Serverless

  • 监控,故障检测与恢复

  • 代理层缓存与响应服务

  • 系统日志

5.3 SPDK助力MySQL数据落盘,让性能腾飞( 基础设施)

5.3.1 SPDK文件系统设计与实现

  • NVMe与PCle的原理

  • NVMe Controller 与bdev之间的rpc

  • blobstore与blob的关系

5.3.2 文件系统的posix api实现

  • 4层结构设计vfs

  • spdk的异步改造posix同步api

  • open/write/read/close的实现

5.3.3 文件系统的性能测试与承接mysq|业务

  • LD_PRELOAD更好mysql系统调用实现

  • iodepth讲解

  • 随机读,随机写,顺序读,顺序写

5.4 高性能计算CUDA (录播答疑)

5.4.1 gpu并行计算cuda的开发流程

  • cpu+gpu的异构计算

  • 计算机体系结构中的gpu

  • cuda的环境搭建nvcc与srun的使用

  • cuda的向量加法与矩阵乘法

  • MPI与CUDA

5.4.2 音视频编解码中的并行计算

  • cuda的h264编解码

  • cuda的mpeg编解码

  • ffmpeg的cuda支持

5.5 并行计算与异步网络引擎workflow

5.5.1 workflow的应用场景

  • workflow的编程范式与设计理念

  • mysql/redi s/kafka/dns的请求实现

  • parallel处理与任务组装

5.5.2 workflow的组件实现

  • 线程池实现

  • DAG图任务

  • msgqueue的实现

  • 纯c的jsonparser实现

5.6 物联网通信协议mqtt的实现框架mosquitto

5.6.1 mqtt的高效使用场景

  • mqtt的发布订阅模式

  • 解决低带宽网络环境的数据传输

  • 3种Qos等级

  • 0Auth与JWT的安全认证

5.6.2 mqtt的broker

  • mqtt的遗嘱机制

  • 发布订阅的过滤器

  • mosquitto的docker部署

  • mqtt的日志实时监控

想要学习完整课程,赶快加老师咨询吧!!!

添加图片注释,不超过 140 字(可选)

6. 云原生专栏

6.1 Docker

6.1.1. Docker风光下的内核功能(录播答疑)

  • 进程 namespace

  • UTS namespace

  • IPC namespace

  • 网络namespace

  • 文件系统namesapce

  • cgroup的资源控制

6. 1.2. Docker容器管理与镜像操作(录播答疑)

  • Docker 镜像下载与镜像运行

  • Docker 存储管理

  • Docker 数据卷

  • Docker 与容器安全

6.1.3. Docker网络管理(项目)

  • 5种Docker网络驱动

  • pipework跨主机通信

  • 0vS划分vlan与隧道模式

  • GRE实现跨主机Docker间通信

6.1.4. Docker云与容器编排(项目)

  • Dockerfile的语法流程

  • 编排神器Fig/Compose

  • Flynn体系架构

  • Docker改变了什么?

6.2. Kubernetes

6.2.1 k8s环境搭建(录播答疑)

  • k8s集群安全设置

  • k8s集群网络设置

  • k8s核心服务配置

  • kubectl命令工具

  • yaml文件语法

6.2.2 Pod与Service的用法(录播答疑)

  • Pod的管理配置

  • Pod升级与回滚

  • DNS服务之于k8s

  • http 7层策略与TLS安全设置

6.2.3 k8s集群管理的那些事儿(项目)

  • Node的管理

  • namespace隔离机制

  • k8s集群日志管理

  • k8s集群监控

6.2.4 k8s二次开发与k8s API(项目)

  • RESTful接口

  • API聚合机制

  • API组

  • Go访问k8s API

7.性能分析专栏

7.1 性能与测试工具

7.1.1 测试框架gtest以及内存泄漏检测(录播答疑)

  • googletest与googlemock文件

  • 函数检测以及类测试

  • test fixture测试夹具

  • 类型参数化

  • 事件测试

  • 内存泄漏

  • 设置期望,期待参数,调用次数,满足期望

7.1.2 性能工具与性能分析(录播答疑)

  • MySQL性能测试工具mysqlslap

  • Redis性能测试工具redis-benchmark

  • http性能测试工具wrk

  • Tcp性能测试工具TCPBenchmarks

  • 磁盘,内存,网络性能分析

7.1.3 火焰图的生成原理与构建方式

  • 火焰图工具讲解

  • 火焰图使用场景与原理

  • nginx 动态火焰图

  • MySQL 火焰图

  • Redis 火焰图

7.2 观测技术bpf与ebpf

7.2.1 内核bpf的实现原理

  • 跟踪,嗅探,采样,可观测的理解

  • 动态hook: kprobe/ uprobe

  • 静态hook: tracepoint和USDT

  • 性能监控计时器PMC模式

  • cpu的观测taskset的使 用

  • BPF工具bpftrace, BCC

7.2.2 bpf对内核功能的观测

  • 内存观测 kmalloc与vm_area_struct

  • 文件系统观测vfs的状态

  • 磁盘io的观测bitesize,mdflush

  • bpf对网络流量的统计

  • bpf对redis-server观测

  • 网络观测tcp_connect, tcp_accept, tcp_close

7.3 内核源码机制

7.3.1 进程调度机制哪些事儿

  • qemu调试内存

  • 进程调度cfs与其他的四个调度类

  • task_struct结构体

  • RCU机制与内存优化屏障

7.3.2 内核内存管理运行机制

  • 虚拟内存地址布局

  • SMP/ NUMA模型

  • 页表与页表缓存原理

  • 伙伴系统实现

  • 块分配(Slab/Slub/Slob) 原理实现

  • brk/kmalloc/vmalloc系统调用流程

7.3.3 文件系统组件

  • 虚拟文件系统vfs

  • Proc文件系统

  • super_block与inode结构体

  • 文件描述符与挂载流程

8. 分布式架构专栏

8.1 分布式数据库

8.1.1 不一样的kv存储RocksDB的使用场景

  • 前缀搜索

  • 低优先级写入

  • 生存时间的支持

  • Transact ions

  • 快照存储

  • 日志结构的数据库引擎

8.2.1 TiDB存储引擎的原理

  • TiKV的Key-Value存储引擎

  • 基于RBAC的权限管理

  • 数据加密

8.2.2 TiDB集群方案与Replication原理

  • 集群三个组件TiDB Server, PD Server, TiKV Server

  • Raft协议讲解

  • OLTP与0LAP

8.2分布式文件系统(录播答疑)

8.2.1 内核级支持的分布式存储Ceph

  • ceph的集群部署

  • monitor与0SD

  • ceph5个核心组件

  • ceph集群监控

  • ceph性能调调优与benchmark

8.2.2 分布式ceph存储集群部署

  • 同步机制

  • 线性扩容

  • 如何实现高可用

  • 负载均衡

8.3 分布式协同

8.3.1 注册服务中心Etcd

  • etcd配置服务、服务发现、集群监控、leader选举、分布式锁

  • etcd体系结构详解(gRPC,WAL,Snapshot、 BoItDB、 Raft)

  • etcd存储原理深入剖析(B树、 B+树)

  • etcd读写机制以及事务的acid特性分析

  • raft共识算法详解(leader选举+日志复制)

8.3.2 协同事件用户态文件系统fuse (项目)

  • fuse的使用场景

  • 文件系统读写事件

  • fuse的实现原理

  • /dev/fuse的作用

8.3.3快播核心技术揭秘P2P框架的实现(录播答疑)

  • 网关NAT表分析

  • NAT类型,完全锥型NAT,对称NAT,端口限制锥形NAT,IP限制锥型NAT

  • 代码逻辑实现NAT类型检测

  • 网络穿透的原理

  • 网络穿透的3种情况

9. 上线项目实战

9.1 dkvstore实现(上线项目)

9.1.1 kv存储的架构设计

  • 存储节点定义

  • tcp server/client

  • hash数据存储

  • list数据存储

  • skiptable数据存储

  • rbtree数据存储

9.1.2 网络同步与事务序列化

  • 序列化与反序列化格式

  • 建立事务与释放事务

  • 线程安全的处理

9.1.3 内存池的使用与LRU的实现

  • 大块与小块分配策略

  • 内存回收机制

  • 数据持久化

9.1.4 KV存储的性能测试

  • 网络测试tps

  • 吞吐量测试

  • go, lua, java多语言支持

  • hash/list/skiptable/rbtree测试

9.2 图床共享云存储(上线项目)

9.2.1 ceph架构分析和配置

  • ceph架构分析

  • 快速配置ceph

  • 上传文件逻辑分析

  • 下载文件逻辑分析

9.2.2 文件传输和接口设计

  • http接口设计

  • 图床数据库设计

  • 图床文件上传,下载,分享功能实现

  • 业务流程实现

9.2.3 容器化docker部署

  • crontab定时清理数据

  • docker server服务

  • grpc连接池管理

9.2.4 产品上云公网发布/测试用例

  • 使用云服务器的各种坑分析

  • fiddler 监控http请求,postman模拟请求

  • wrk测试接口吞吐量

  • jmeter压力测试

9.3 微服务即时通讯(上线项目)

9.3.1 IM即时通讯项目框架分析和部署

  • 即时通讯应用场景分析

  • 即时通讯自研和使用第三方SDK优缺点

  • 即时通讯数据库设计

  • 接入层、 逻辑层、路由层、数据层架构.

  • 即时通讯项目部署

  • 即时通讯web账号注册源码分析

9.3.2 IM消息服务器/文件传输服务器

  • protobuf通信协议设计

  • reactor模型C++实现

  • login_ server 负载均衡手写代码实现

  • 用户登录请求验证密码+混淆码MD5匹对

  • 如何全量、增量拉取好友列表、用户信息

  • 知乎、b站小红点点未读消息如何实现

9.3.3 IM消息服务器和路由服务器设计

  • 请求登录逻辑

  • 最近联系会话逻辑

  • 查询用户在线主题

  • 未读消息机制

  • 单聊消息推拉机制

  • 群聊消息推拉机制

  • 路由转发机制

9.3.4 数据库代理服务器设计

  • main函数主流程

  • reactor+线程池+连接池处理逻辑分

  • redis缓存实现消息计数(单聊和群聊)

  • redis实现未读消息机制

  • 如何实现群消息的推送

  • 单聊消息推送、拉取优缺点

9.3.5 文件服务器和docker部署

  • 在线文件传输机制分析

  • 离线文件传输机制分析

  • etcd微服务注册与发现

  • docker制作与部署

9.3.6 产品上云公网发布/公网测试上线

  • 单元测试案例

  • testbench如何设计

  • IM项目性能压测

  • 定制私有功能

  • 拓展新功能(代码)

  • 云服务器部署

9.4 零声教学AI助手一代(上线项目)

9.4.1 AI助手架构设计与需求分析

  • chatgpt的构想 与需求分析

  • 基于开源项目初步构建项目

  • gin框架实现代理服务

9.4.2 接口功能设计

  • grpc与protobuf的使用流程

  • token计数器与tokenizer的服务封装

  • 敏感词识别服务

9.4.3 向量数据库与连接池设计

  • redis实现上下文管理

  • 问题记录保存

  • web端协议解析

  • OneBot协议

9.4.4 服务部署上线

  • docker stack 服务部署

  • wrk接口吞吐量测试

  • 线上节点监控

9.5 魔兽世界后端TrinityCore (上线项目)

9.5.1 网络模块实现

  • boost. asio 跨平台网络库

  • boost. asio 核心命名空间以及异步io接口

  • boost. asio 在 TrinityCore 中的封装

  • 网络模块应用实践

9.5.2 地图模块实现

  • 地图模块抽象: map、 area、 grid、 cell

  • 地图模块驱动方式

  • A0I 核心算法实现

  • AABB碰撞检测实现

  • A*寻路算法实现

9.5.3战斗模块实现

  • 技能设计以及实现

  • AI设计

  • 怪物管理

  • 副本设计

9.5.4 TrinityCore 玩法实现

  • 用户玩法实现-任务系统

  • 数据配置以及数据库设计

  • 触发机制实现

  • 多人玩法实现-工会设计

文章来源:https://blog.csdn.net/qq_40989769/article/details/135022551
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。