分享

奇安信C++后端面经,问的很奇怪!

 深度Linux 2023-10-29 发布于湖南
大家好,我是深度Linux
在这个“金秋十月”,也是一个收获的季节。各大公司在这个时候都陆续开奖了,特别是前几天团子的开奖,还是超出了很多人的预期。
当然,几家欢喜几家愁,都没关系,因为找工作本来就是一个战线较长的任务。尽管你现在只有小公司offer,或者0offer,其实都没有必要焦虑。
你只管做你的,好好进行复盘总结,面过的,就好好复盘面经,没面过的,就好好学基础知识,刷算法题,再加上持续性的投递,你一定会有满意的offer!

1、简单介绍一下webserver

Web服务器是一种软件或应用程序,负责接收客户端请求并向其提供相应的资源。它充当客户端和后端服务器之间的中介,通过HTTP协议进行通信。

Web服务器的主要功能包括:

  1. 接受和处理客户端请求:Web服务器监听指定的端口,接受来自客户端(例如浏览器)发送的HTTP请求。它解析请求,识别所需资源,并采取适当的操作来响应请求。

  2. 资源管理:Web服务器负责管理和提供各种资源,如HTML文件、图像、CSS样式表、JavaScript脚本等。它能够从磁盘上的文件系统中获取这些资源,并将其发送给客户端。

  3. 处理动态内容:除了静态资源外,Web服务器还可以与后台应用程序(如CGI脚本、PHP脚本、ASP.NET等)交互以生成动态内容。它可以将请求转发给适当的后台处理程序,并将生成的结果返回给客户端。

  4. 连接管理:Web服务器需要管理并保持与多个客户端之间的连接。它可以使用不同的策略来处理连接池、线程池或事件驱动等方式来高效地处理并发请求。

  5. 安全性和身份验证:为了保护网站和数据安全,Web服务器通常具有各种安全功能,如HTTPS支持、SSL证书配置、身份验证和访问控制等。

  6. 日志记录:Web服务器可以记录每个请求的详细信息,包括访问时间、客户端IP地址、请求路径、响应状态等。这些日志对于分析和监视网站流量以及故障排除非常有用。

常见的Web服务器软件包括Apache HTTP Server、Nginx、Microsoft IIS等。它们在性能、可靠性和扩展性方面都有不同的特点,开发人员可以根据实际需求选择适合自己项目的Web服务器。

2、这个webserver并发连接多少

这个取决于具体的web server的实现和配置。一般来说,web server可以通过多线程、多进程或异步IO等方式处理并发连接。不同的实现方式和硬件环境都会对并发连接数产生影响。有些服务器可以处理成千上万个并发连接,而另一些可能只能处理几百个。因此,并发连接数是相对灵活可调的,取决于特定情况下所使用的服务器架构和配置。

3、线程池和线程个数怎么设置

置线程池的大小需要考虑多个因素,包括系统资源、任务类型和负载情况等。以下是一些常见的设置原则:

  1. CPU核心数:通常线程池的大小应该与CPU核心数相近或略大,这样可以最大程度地利用CPU资源。

  2. 任务类型和执行时间:如果任务属于I/O密集型,即涉及到等待外部资源(如网络请求、文件读写等),可以设置较大的线程池来充分利用CPU空闲时间。而对于计算密集型任务,由于存在CPU竞争,适当减少线程池大小可能更有效。

  3. 内存限制:每个线程都需要一定的内存开销,在确定线程池大小时要考虑系统可用内存。避免过多线程导致内存耗尽和频繁的内存交换。

  4. 平均负载:根据当前系统平均负载情况动态调整线程池大小。例如使用指标如CPU利用率、请求处理速度等来监控系统负载,根据阈值自动调整线程池大小。

总体来说,合理地设置线程池大小可以提高程序性能和资源利用率。但要注意避免过度设置导致资源浪费或系统性能下降。

4、线程模型怎么搭配epoll进行使用

在线程模型中,可以使用epoll作为事件驱动的I/O多路复用机制,以提高服务器的并发性能。

一种常见的搭配方式是,使用一个主线程负责监听新连接,并将新连接分配给工作线程处理。具体步骤如下:

  1. 创建一个epoll实例,并设置感兴趣的事件类型(如可读事件)。

  2. 在主线程中创建监听套接字,并将其加入到epoll实例中。

  3. 进入循环,调用epoll_wait()函数等待事件发生。

  4. 当有新连接到来时,在主线程中接收连接请求,并根据一定的策略选择一个空闲的工作线程。

  5. 将新连接的套接字添加到该工作线程的epoll实例中,并设置相应的回调函数或处理逻辑。

  6. 工作线程从自己所属的epoll实例中获取就绪事件,并执行相应的操作(如读取数据、处理业务逻辑等)。

  7. 回到第3步,继续等待新事件。

这样,通过将连接分配给不同的工作线程进行处理,可以提高系统对并发请求的处理能力。

需要注意以下几点:

  • 主线程只负责监听新连接,不直接处理具体请求。工作线程才是真正处理业务逻辑和响应客户端请求的地方。

  • 每个工作线程都需要拥有自己的epoll实例,以避免竞争和阻塞。每个工作线程独立负责处理自己所分配的连接。

  • 在具体实现时,还需考虑连接管理、线程池、数据同步等方面的细节。

以上是一种常见的搭配方式,根据实际情况和需求,也可以选择其他线程模型(如多线程、异步IO等)结合epoll使用。

5、怎么理解io多路复用

O多路复用是一种通过同时监听多个IO事件的机制,使得一个进程能够同时处理多个IO请求。它利用操作系统提供的select、poll、epoll等函数,在一个线程内监听多个文件描述符(socket)上是否有数据可读或可写,从而避免了使用多线程或多进程来处理并发IO请求的开销。

通过IO多路复用,可以将大量的网络连接集中到少数几个线程或进程上进行管理和处理,提高了系统的并发性能。当某个文件描述符就绪时(例如有数据可读),应用程序会得到通知并可以立即对其进行读取操作,这样就能更高效地利用CPU资源。

6、epoll的边沿触发和水平触发

在Linux中,epoll是一种高效的I/O事件通知机制。它提供了两种触发模式:边沿触发(Edge Triggered)和水平触发(Level Triggered)。

边沿触发(Edge Triggered)模式:

  • 当文件描述符上有可读/可写事件发生时,只会触发一次通知。

  • 如果不立即处理该事件,下次调用epoll_wait()时将不再返回该事件,直到有新的事件再次发生。

  • 边缘触发适合于非阻塞的、以消息为单位进行处理的场景。

水平触发(Level Triggered)模式:

  • 当文件描述符上有可读/可写事件发生时,如果没有处理完全部数据,下次调用epoll_wait()时仍然会返回该事件。

  • 直到该文件描述符上没有待处理的数据或者被关闭才不再返回该事件。

  • 水平触发适合于阻塞式的、基于流的传输协议,如TCP。

选择使用边沿触发还是水平触发取决于具体场景和应用需求。一般来说,在高并发且非阻塞的网络服务器中,边缘触发能够更好地控制事件通知频率和减少无效循环检查。而对于普通应用程序或者阻塞式的IO操作,水平触发则是更常见和常用的模式。

7、你两种模式都使用过,那两种使用起来有什么区别吗

边沿触发(Edge Triggered)模式和水平触发(Level Triggered)模式是在事件驱动系统中常见的两种触发方式。

区别如下:

  1. 边沿触发模式:当输入信号从低电平变为高电平或从高电平变为低电平时,会产生一个触发事件。只有在状态改变瞬间才会触发事件。例如,边沿触发模式可用于处理硬件中断信号。

  2. 水平触发模式:只要输入信号保持在指定的电平上,就会持续触发事件。无论输入信号处于何种状态,只要满足条件就会持续触发事件。例如,在网络编程中,水平触发模式可用于处理socket数据的读取。

总体而言,边沿触发更适合处理瞬时状态变化的场景,而水平触发则更适合连续性地监测和响应特定状态。

8、有观察过这两种的区别从连接到传数据(没有)

边沿触发(Edge Triggered)和水平触发(Level Triggered)是指在数字电子系统中用于触发事件的不同方式。

在边沿触发模式下,只有在输入信号的状态从低电平到高电平或者从高电平到低电平的瞬间时,才会产生触发事件。换句话说,只有在信号变化的边沿时刻才会被触发。

而在水平触发模式下,只要输入信号保持为高电平或者低电平状态,就会持续地产生触发事件。无论输入信号是否有变化,在达到预设的水平时都会触发事件。

区别主要体现在连接和传输数据方面:

  1. 连接:对于边沿触发模式,通常需要一个外部时钟或者专门的边沿检测器来检测输入信号的变化,并将结果传递给系统。而水平触发模式则可以直接使用输入信号作为事件的条件。

  2. 传输数据:在边沿触发模式下,当边沿变化时才会进行数据传输。而在水平触发模式下,一旦满足了预设条件,数据传输就会立即开始。

9、有观察过http的包吗(没有)

是的,我可以观察和解析HTTP的包。HTTP(Hypertext Transfer Protocol)是一种用于在Web浏览器和Web服务器之间传输数据的协议。通过分析HTTP包,我们可以了解请求和响应的头部信息、请求方法、URL、状态码等内容,以及实际传输的数据。这对于网络调试、安全分析和性能优化都非常有用。

10、有看过http的报文的头吗(回答了一下对应的头的内容)

HTTP报文的头部包含了一些重要的信息。通常有以下几个常见的头字段:

  1. 请求行:包含了请求方法(GET、POST等)、URI路径和HTTP协议版本。

  2. 响应行:包含了响应状态码和对应的状态描述。

  3. 请求头:包含了客户端向服务器发送请求时附带的各种信息,例如User-Agent、Accept、Content-Type等。

  4. 响应头:包含了服务器返回给客户端的响应相关信息,例如Server、Content-Type、Content-Length等。

  5. 实体头:包含了实体主体部分(可选)的附加信息,例如Content-Encoding、Last-Modified等。

通过解析这些报文头部可以获得请求或响应的相关信息,以便进行适当的处理和解析。

11、除了Get和post其他方法见过吗(没有)

除了常见的GET和POST方法,还有一些其他HTTP请求方法,例如:

  1. PUT:用于创建或更新资源。通常用于向服务器发送数据,并将其存储在指定的URI下。

  2. DELETE:用于删除指定的资源。

  3. PATCH:用于部分更新资源。与PUT不同,PATCH仅对资源进行部分更改。

  4. HEAD:类似于GET请求,但只返回响应头信息,而不返回实际内容。

  5. OPTIONS:获取目标URL所支持的通信选项。

这些是HTTP协议中常见的一些请求方法。具体使用哪个方法取决于你要实现的功能和服务端的支持情况。

12、get和post有什么区别吗

GET和POST是HTTP协议中两种常用的请求方法,它们在以下几个方面有区别:

1. 参数传递方式:GET请求通过URL参数传递数据,参数会附加在URL的末尾;而POST请求将数据放在请求体中进行传递,不会显示在URL上。

2. 数据大小限制:由于GET请求将参数暴露在URL上,因此对于数据大小有限制。而POST请求没有明确的大小限制,可以传递大量的数据。

3. 安全性:由于GET请求参数直接暴露在URL上,所以相对来说比较不安全,容易被拦截和篡改。POST请求把参数放在请求体中,相对更安全一些。

4. 缓存机制:GET请求默认可缓存结果,浏览器会缓存返回的页面或资源;而POST请求默认不可缓存。

13、URL组成,uri是什么

URL(Uniform Resource Locator)是统一资源定位符的缩写,它是用来标识和定位互联网上资源的字符串。一个完整的URL通常包括以下几个部分:

  1. 协议(Protocol):指示要使用的传输协议,如HTTP、HTTPS、FTP等。

  2. 主机名(Hostname):表示资源所在的主机或服务器的名称。

  3. 端口号(Port number):可选项,指定访问服务器时所使用的端口号,默认根据协议自动确定。

  4. 路径(Path):指示服务器上特定资源的路径或位置。

  5. 查询参数(Query parameters):可选项,用于传递额外的参数给服务器。

  6. 锚点(Anchor):可选项,在HTML中使用锚点进行页面内导航。

URI(Uniform Resource Identifier)是统一资源标识符的缩写,它是一个用来唯一标识和引用某个资源的字符串。URI包括两种形式:

  1. URL(Uniform Resource Locator),可以被用来直接访问并获取某个资源;

  2. URN(Uniform Resource Name),仅用于标识资源而不提供直接访问。

因此,URI是URL和URN的总称。

15、线程池用到那些线程间通讯

线程池通常使用以下几种线程间通讯方式:

  1. 任务队列(Task Queue):线程池中的线程从任务队列中获取待执行的任务。通过将任务放入任务队列,可以实现生产者-消费者模型,在多个线程之间传递任务。

  2. 线程同步机制:在多个工作线程同时处理任务时,可能需要使用互斥锁、条件变量等线程同步机制来保证数据的一致性和避免竞态条件。

  3. 回调函数(Callback):当一个任务完成后,可以通过回调函数将结果返回给调用方或者通知其他相关的模块。

  4. 线程间信号量(Thread Synchronization Primitives):通过信号量等同步原语,可以实现多个线程之间的协调与控制。

  5. 共享内存(Shared Memory):多个线程可以通过共享内存来进行数据交换,但需要注意对共享数据的访问控制,以避免竞态条件。

这些通讯方式可以帮助线程池中的线程协作执行任务,并且能够有效地管理和分配工作负载。具体使用哪种通讯方式取决于应用程序的需求和设计。

16、C++类型转化

在C++中,类型转换可以通过以下方式进行:

  1. 隐式类型转换(Implicit Conversion):在不需要显式指定的情况下,编译器会自动进行类型转换。例如,将一个整数赋值给浮点数类型变量时,编译器会自动进行从整型到浮点型的隐式转换。

  2. 显式类型转换(Explicit Conversion):有时需要手动指定将一个数据类型转换为另一个数据类型。C++提供了几种显式类型转换操作符:

  • static_cast:用于执行静态类型检查的转换,在合理范围内允许不同但相关的数据类型之间的转换。

  • dynamic_cast:用于执行安全向下造型(downcasting),主要用于基类和派生类之间的转换。

  • const_cast:用于去除常量属性或添加常量属性。

  • reinterpret_cast:一种底层强制类型转换,通常用于将指针或引用重新解释为其他指针或引用。

注意,在使用显式类型转换时,请确保转换是安全且符合语义逻辑。错误的使用可能导致运行时错误或未定义行为。

17、C++中的堆和栈的区别

在C++中,堆(Heap)和栈(Stack)是两种不同的内存分配方式,它们有以下区别:

  1. 分配方式:栈上的变量是通过系统自动进行分配和释放的,而堆上的内存则需要手动进行分配和释放。

  2. 内存管理:栈内存由编译器自动管理,它会在变量超出作用域时自动释放。而堆内存需要手动分配和释放,在不再使用时必须显式地调用 delete 或 delete[] 进行回收。

  3. 大小限制:栈通常比较小,并且大小固定。而堆则没有固定大小限制,可以动态地分配所需大小的内存空间。

  4. 访问速度:由于栈上的变量是连续分配的,因此访问速度相对较快。而堆上的内存分散在各个地址上,访问速度相对较慢。

  5. 生命周期:栈上的变量生命周期受到作用域控制,当离开作用域时会自动销毁。而堆上的对象在手动释放之前一直存在。

18、指针和引用的区别

指针和引用是C++中的两个重要概念,它们都可以用于间接访问对象或变量。下面是它们的区别:

  1. 定义和使用方式:指针使用*来声明和解引用,而引用使用&来声明,不需要解引用。

  2. 空值:指针可以为空(nullptr),表示没有指向任何对象或变量,而引用必须始终引用有效的对象。

  3. 可变性:指针本身可以重新赋值为另一个地址,即改变所指向的对象或变量;而引用一旦初始化后就不能再改变所引用的对象。

  4. 对象关系:指针可以指向多个不同类型的对象,并且可以通过运算符修改所指向对象的值;而引用始终与特定类型的对象相关联,并且无法更改为引用其他类型的对象。

  5. 空间占用:通常情况下,指针需要占据内存空间来存储地址信息;而引用本质上只是原对象的一个别名,并不需要额外的空间。

19、关键字static的使用

关键字 "static" 在 C++ 中有多种用法,以下是其中几个常见的用法:

1.静态变量(Static Variables):在函数内部声明的静态变量具有静态生存期,即它们在整个程序执行期间都存在,并且只会初始化一次。例如:

void foo() {
static int count = 0; // 静态局部变量
count++;
cout << "Count: " << count << endl;
}

2.静态成员变量(Static Member Variables):静态成员变量属于类本身而不是类的实例,并且在所有类对象之间共享。例如:

class MyClass {
public:
static int sharedVariable; // 静态成员变量声明
};

int MyClass::sharedVariable = 10; // 静态成员变量定义

int main() {
cout << MyClass::sharedVariable << endl; // 访问静态成员变量
return 0;
}

3.静态成员函数(Static Member Functions):静态成员函数属于类本身而不是类的实例,可以直接通过类名来调用,而不需要创建对象实例。例如:

class MyClass {
public:
static void myStaticFunction() {
cout << "This is a static member function." << endl;
}
};

int main() {
MyClass::myStaticFunction(); // 调用静态成员函数
return 0;
}

除了以上几种用法,"static" 还可以用于限制变量或函数的作用域为当前文件(称为内部链接)以及在类模板中声明静态数据成员等。具体使用取决于上下文和需求。

20、webserver出现bug的debug思路

当一个Web服务器出现bug时,以下是一些常见的debug思路:

  1. 检查日志:查看服务器日志文件,特别是错误日志,以获取有关bug的更多信息。日志通常会记录请求和响应的详细信息,包括错误消息和异常堆栈跟踪。

  2. 排查输入数据:检查传递给服务器的输入数据,包括HTTP请求参数、表单数据等。验证输入数据是否符合预期,并确保它们正确解析和处理。

  3. 分步调试:使用适当的调试工具,在代码中设置断点并逐步执行程序,观察变量值的变化以及程序流程。这可以帮助您找到可能引发bug的特定代码段。

  4. 异常处理:确保适当地捕获和处理异常。对于抛出异常的部分进行详细调试,并尝试理解异常触发的原因。

  5. 代码审查:仔细审查代码逻辑、函数调用和算法实现。检查潜在的逻辑错误、边界情况和不恰当的函数使用。

  6. 环境配置检查:确认所需软件库和依赖项是否正确安装和配置。有时,问题可能与环境相关,例如缺少必要的依赖项或不正确的配置文件。

  7. 测试用例编写:编写针对各种情况的测试用例,包括正常情况和边界条件。这有助于重现bug,并确认修复是否成功。

  8. 借助工具:使用适当的工具进行性能分析、内存泄漏检测或代码覆盖率分析等。这些工具可以帮助您找到隐藏的问题或优化性能。

21、gdb使用过吗,调试过多线程吗

在使用gdb调试多线程程序时,你可以按照以下步骤进行操作:

  1. 使用编译选项 -g 编译你的程序,以便生成调试信息。

  2. 在终端中运行 gdb your_program 命令启动gdb,并加载你的可执行文件。

  3. 运行 set follow-fork-mode child 命令设置跟踪子进程。

  4. 运行 break main 命令设置一个断点在主函数入口处(或者其他你希望设置断点的地方)。

  5. 运行 run 命令启动程序执行,当程序停在断点处时,表示已经开始调试。

  6. 使用 thread <thread-id> 命令切换到指定线程进行调试。可以使用 info threads 查看当前所有线程的信息和ID。

  7. 可以使用常见的gdb命令如 nextstepprint 等来逐步执行代码,并查看变量值等信息。

注意事项:

  • 多线程调试可能会涉及并发问题,请小心处理共享数据访问和同步问题。

  • 在不同线程之间切换时,需要保证正在被切换到的线程是处于暂停状态。

这些是基本的操作步骤,具体根据你的实际情况和需求进行调整和扩展。

22、linux上ping命令能确认那些内容

在Linux上,使用ping命令可以确认以下内容:

  1. 目标主机的可达性:通过发送ICMP Echo请求,ping命令会等待目标主机的回应。如果能够收到回应,则说明目标主机是可达的;否则,表示目标主机不可达。

  2. 往返延迟时间(RTT):ping命令会显示往返延迟时间,也就是从发送请求到接收响应所经过的时间。通过观察RTT可以评估网络的延迟情况。

  3. 数据包丢失率:ping命令还会显示数据包丢失率,即发送的请求中未收到响应的比例。高丢包率可能表示网络连接存在问题。

  4. TTL(Time to Live)值:每个发送出去的ICMP Echo请求都带有一个TTL值,在经过路由器时逐渐减小。当TTL为0时,路由器将丢弃该数据包并返回一个“Time Exceeded”错误消息。

  5. 网络拓扑分析:通过连续向不同IP地址发送ping请求,并观察结果,可以获取一些关于网络拓扑结构和路由路径方面的信息。

这些是ping命令常用来确认的内容,在诊断网络连接和故障排查时非常有用。

23、ping的底层实现

Ping是一种网络诊断工具,用于测试主机之间的连通性。在底层实现上,Ping使用ICMP协议(Internet Control Message Protocol)来发送探测包并接收目标主机的响应。

具体而言,Ping的底层实现可以分为以下几个步骤:

  1. 创建一个原始套接字(Raw Socket)。

  2. 构建ICMP报文,其中包括类型字段(通常为8表示请求Echo Request,或0表示回复Echo Reply)、校验和字段、标识符、序列号等信息。

  3. 设置IP头部信息,包括源IP地址和目标IP地址。

  4. 计算校验和,并将ICMP报文发送到目标主机。

  5. 等待目标主机响应,如果收到相应的Echo Reply报文,则表示目标主机可达;如果超时未收到响应,则表示目标主机不可达。

  6. 根据收到的响应时间计算往返时间(Round Trip Time, RTT),并显示或记录结果。

需要注意的是,具体操作系统或平台上对Ping命令的实现可能有所差异,但基本原理都是通过ICMP协议进行网络连通性测试。

24、C++中map,如果key不存在,使用[]形式遍历能成功吗

在C++中,使用[]操作符形式访问一个map时,如果key不存在,会自动创建该key,并将其与一个默认值关联起来。因此,遍历一个map并使用[]形式访问时,如果key不存在,会在该位置插入新的键值对。请注意,在使用[]操作符访问时要确保map是可写的(非const)。

25、tcp编程常用的api

在C/C++中,进行TCP编程常用的API包括:

  1. socket():创建套接字

  2. bind():将套接字绑定到一个地址和端口

  3. listen():监听传入的连接请求

  4. accept():接受传入的连接请求并返回新的套接字

  5. connect():建立与远程服务器的连接

  6. send()/sendto():发送数据到已连接或未连接的套接字

  7. recv()/recvfrom():从已连接或未连接的套接字接收数据

  8. close():关闭套接字

这些是基本的TCP编程API,可以使用它们来实现TCP服务器和客户端程序

26、tcp三次握手、四次挥手

TCP三次握手(Three-way Handshake)是建立TCP连接的过程,具体步骤如下:

  1. 客户端向服务器发送一个SYN报文段,指示请求建立连接,并选择一个初始序列号。

  2. 服务器收到SYN报文段后,回复客户端一个SYN+ACK报文段,表示同意建立连接,并选择自己的初始序列号。

  3. 客户端收到服务器的SYN+ACK报文段后,再向服务器发送一个ACK报文段,确认连接建立。此时双方可以开始正式传输数据。

TCP四次挥手(Four-way Handshake)是关闭TCP连接的过程,具体步骤如下:

  1. 主动关闭方(一般是客户端)发送一个FIN报文段给被动关闭方(一般是服务器),表示要关闭连接。

  2. 被动关闭方收到FIN报文段后,回复一个ACK报文段进行确认。

  3. 被动关闭方进入TIME_WAIT状态,在等待一段时间(一般为两个最大报文生存时间)后才能彻底关闭连接。

  4. 主动关闭方收到ACK报文段后,也进入CLOSED状态。此时连接已经完全关闭。

这样通过三次握手建立连接和四次挥手断开连接,确保了可靠的数据传输和双方对连接状态的准确掌握。

27、输入一个url会出现那些过程

当你输入一个URL(统一资源定位符),通常会经历以下过程:

  1. DNS解析:计算机将URL中的域名解析为对应的IP地址,以便进行网络通信。

  2. 建立TCP连接:使用IP地址与服务器建立TCP连接,确保可靠的数据传输。

  3. 发送HTTP请求:发送HTTP请求报文给服务器,包含请求方法(GET、POST等)、路径、头部信息和可能的请求体。

  4. 服务器处理请求:服务器接收到请求后,根据路径找到相应的资源,并执行相关处理逻辑。

  5. 返回HTTP响应:服务器将处理结果封装成HTTP响应报文返回给客户端。响应报文包含状态码、头部信息和响应体(可能是HTML、图片、JSON等)。

  6. 客户端渲染:客户端接收到响应后,根据响应内容进行页面渲染或其他操作。如果是网页,则浏览器会解析HTML、CSS和JavaScript,并呈现出最终的页面效果。

28、写服务器碰到过死锁吗

死锁在服务器开发中是一个常见的问题。死锁指的是多个线程或进程因为相互等待对方所持有的资源而陷入无限等待的状态。在服务器编程中,使用多线程或多进程处理并发请求时,如果不正确地管理锁和资源,就容易导致死锁情况的发生。

解决死锁问题可以采取以下几种方法:

  1. 避免使用过多的锁:减少并发操作所需要的锁数量,尽量简化代码逻辑。

  2. 使用良好的锁策略:合理选择和管理锁,在保证数据安全性的前提下尽量减小临界区范围。

  3. 按顺序获取锁:确保每个线程按照相同的顺序获取锁,避免出现循环等待情况。

  4. 设置超时时间:为每个请求设置合理的超时时间,并在超时后释放所有占用资源,防止长时间阻塞导致整体性能下降。

  5. 使用专门工具进行分析:借助死锁检测工具来识别和解决潜在的死锁问题。

注意,在服务器开发中预防和解决死锁问题需要综合考虑系统架构、并发设计、线程安全等方面,以确保系统的稳定性和性能。

29、http和https的区别

HTTP(Hypertext Transfer Protocol)和HTTPS(Hypertext Transfer Protocol Secure)是用于在Web浏览器和服务器之间传输数据的两种协议。

  1. 安全性:最显著的区别是安全性。HTTP不加密数据传输,而HTTPS通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对数据进行加密来保护数据的安全性。

  2. 端口号:HTTP默认使用端口号80进行通信,而HTTPS默认使用端口号443进行通信。

  3. 数据传输方式:HTTP的数据传输是明文的,可以被拦截并查看内容。而HTTPS通过加密技术保护数据传输,使得拦截者无法轻易解读或修改传输的内容。

  4. 证书要求:为了建立HTTPS连接,服务器需要具有数字证书。这个证书由受信任的证书颁发机构(CA)签发,以确认服务器身份和公钥的有效性。

30、https的认证是谁认证谁

在 HTTPS 中,认证是由第三方机构颁发的数字证书来实现的。这个机构通常被称为证书颁发机构(Certificate Authority,CA)。当网站使用 HTTPS 时,它需要向证书颁发机构申请数字证书。证书颁发机构会对网站进行验证,并签发包含公钥及其他信息的数字证书。当用户访问这个网站时,浏览器会检查该数字证书是否有效并且与域名匹配。如果验证通过,则建立安全连接。如果数字证书无效或不可信,则浏览器会给出警告提示。

因此,HTTPS 认证是由受信任的第三方机构(即证书颁发机构)对网站的身份进行认证,并确保通信过程中数据传输的安全性和完整性。

还不熟悉的朋友,这里可以先领取一份Linux c/c++开发新手学习资料包(入坑不亏):

【后端开发】
  1. 编程基本功扎实,掌握 C/C++/JAVA 等开发语言、常用算法和数据结构;
  2. 熟悉 TCP/UDP 网络协议及相关编程、进程间通讯编程;
  3. 了解 Python、Shell、Perl 等脚本语言;
  4. 了解 MYSQL 及 SQL 语言、编程,了解 NoSQL, key-value 存储原理;
  5. 全面、扎实的软件知识结构,掌握操作系统、软件工程、设计模式、数据结构、数据库系统、网络安全等专业知识;
  6. 了解分布式系统设计与开发、负载均衡技术,系统容灾设计,高可用系统等知识。

这里给大家推荐零声教育全网独家的【Linux C/C++开发】课程体系,通过原理技术+源码分析+案例分析+项目实战,全面解析Linux C/C++,8个上线项目,2W+行手写代码,全面解析:

Linux C/C++开发

1、精进基石专栏

(一)数据结构与算法

  • 随处可见的红黑树

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

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

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

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

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

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

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

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

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

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

  • B树插入的两种分裂

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

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

  • B+树的定义与实现

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

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

  • B+树的线程安全做法

  • 海量数据去重的abhloriter bitap

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

  • hash的应用场景

  • 分布式hash的实现原理

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

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

(二)设计模式

  • 创建型设计模式

  • 单例模式

  • 策略模式

  • 观察者模式

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

  • 原型模式

  • 结构型设计模式

  • 适配器模式

  • 代理模式

  • 责任链模式

  • 状态模式

  • 桥接模式

  • 组合模式

(三)c++新特性

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

  • unordered_ _map

  • stl容器

  • hash的用法与原理

  • shared_ ptr,unique_ ptr

  • basic_ regex,sub_ match

  • 函数对象模板function, bind

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

  • atomic的用法与原理

  • thread_ local 与condition_ var iable

  • 异常处理exception_ _ptr

  • 错误处理error _ category

  • coroutine的用法与原理

(四)Linux工程管理

  • Makefi le/ cmake/conf igure

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

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

  • Makefile的参数传递

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

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

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

  • configure生成makefile的原则

  • cmake的写法

  • 分布式版本控制git

  • git的工作流程

  • 创建操作与基本操作

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

  • git服务器搭建

  • Linux系统运行时参数命令

  • 进程间通信设施状态ipcs

  • Linux系统运行时长upt ime

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

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

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

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

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

  • 密切关注Linux系统glances

  • 查看系统调用strace

  • ftp服务器基本信息ftptop

  • 电量消耗和电源管理powertop

  • 监控mysq| 的线程和性能mytop

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

  • Linux网络统计监控工具netstat

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

  • 网络数据包分析利刃tcpdump

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

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

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

2、高性能网络设计专栏

(一)网络编程异步网络库zvnet

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

  • socket与文件描述符的关联

  • 多路复用select/poll

  • 代码实现LT/ET的区别

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

  • reactor针对业务实现的优点

  • poll封装send_ cb/recv_ _cb/ accept_ _cb

  • reactor多核实现

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

  • redis,memcached, nginx网 络组件

  • http服务器的实现

  • reactor sendbuffer与recvbuffer封装http协议

  • http协议格式

  • 有限状 态机fsm解析http

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

(二)网络原理

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

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

  • 网络io线程池异步处理

  • ulimit的fd的百万级别支持

  • sysctI. conf的rmem与wmem的调优

  • conntrack的原理分析

  • Posix API与网络协议栈

  • connect,listen, accept与三次握 手

  • listen参数backlog

  • syn泛洪的解决方案

  • close与四次挥手

  • 11个状态迁移

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

  • tcp keepalive与 应用层心跳包

  • 拥塞控制与滑动窗口

  • UDP的可靠传输协议QUIC

  • udp的优缺点

  • udp高并发的设计方案

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

  • udp可靠传输原理

  • quic协议的设计原理

  • quic的开源方案quiche

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

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

  • 调度器的定义分析

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

  • 协程调度的执行流程

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

  • hook钩子的实现

  • 协程实现mysql请求

  • 协程多核方案分析

  • 协程性能测试

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

  • 用户态协议栈设计实现

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

  • netmap开源框架

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

  • arp协议实现

  • icmp协议实现

  • 应用层posix api的具体实现

  • socket/bind/listen的实现

  • accept实现

  • recv/send的实现

  • 滑动窗口/慢启动讲解

  • 重传定时器,坚持定时器,time_ wait定时器,keepalive定时器

  • 手把手设计实现epoll

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

  • 协议栈fd就绪回调实现

  • epoll接口实现

  • LT/ET的实现

  • 高性能异步io机制io_ _uring

  • 与epo1l媲美的io_ uring

  • io_ _uring系统调用io_ _uring_ setup, io_ _ur ing_ register, io_ _ur ing_ enter

  • liburng的io_ uring的关系

  • io_ uring与epoll性能对比

  • io_ _uring的共享内存机制

  • io_ uring的使用场景

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

  • io_ uring网络读写

  • io_ uring磁盘读写

  • proactor的实现

3、基础组件设计专栏

(一)池式组件

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

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

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

  • 任务回调与条件等待

  • 线程池的动态防缩

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

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

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

  • 内存小块分配与管理

  • 内存大块分配与管理

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

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

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

  • 扩展:nginx内存池实现

  • mysq|连接池的实现(项目)

  • 连接池性能的影响的2个因素,top连接和mysq|认证

  • 连接请求归还策略

  • 连接超时未归还策略

  • 链接断开重连策略

  • 连接数量最优策略

(二)高性能组件

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

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

  • 自旋锁的性能分析

  • 原子操作的汇编实现

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

  • 有锁无锁队列性能

  • 内存屏障Barrier

  • 数组无锁队列设计实现

  • 链表无锁队列设计实现

  • 网络缓冲区设计

  • RingBuffer设计

  • 定长消息包

  • ChainBuffer 设计

  • 双缓冲区设计

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

  • 定时器的使用场景

  • 定时器的红黑树存储

  • 时间轮的实现

  • 最小堆的实现

  • 分布式定时器的实现

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

  • 死锁的现象以及原理

  • pthread_ _mutex_ lock/pthread_ _mutex_ _unlock dIsym的实现

  • 有向图的构建

  • 有向图dfs判断环的存在

  • 三个原语操作 lock before, lock_ after, unlock_ after

  • 死锁检测线程的实现

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

  • 内存泄漏现象

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

  • malloc与free的dIsym实现

  • 内存检测策略

  • 应用场景测试

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

  • 多线程资源竞争互斥锁

  • 自旋锁

  • 加锁的异常情况

  • 非公平锁的实现

  • 公平锁的实现

(三)开源组件

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

  • 日志库性能瓶颈分析

  • 异步日志库设计与实现

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

  • 奔溃后的日志找回

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

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

  • 如何保证消息完整性

  • 手撕protobuf IM通信 协议

  • protobuf序列化与反序列化

  • protobuf编码原理

4、中间件开发专栏

(一)Redis

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

  • string,set, zset, Iist,hash

  • 分布式锁的实现

  • Lua脚本解决ACID原子性

  • Redis事务的ACID性质分析

  • Redis协议与异步方式

  • Redis协议解析

  • 特殊协议操作订阅发布

  • 手撕异步redis协议

  • 存储原理与数据模型

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

  • 双向链表的list实现

  • 字典的实现,hash函数

  • 解决键冲突与rehash

  • 跳表的实现 与数据论证

  • 整数集合实现

  • 压缩列表原理证明

  • 主从同步与对象模型

  • 对象的类型与编码

  • 广字符串对象

  • 列表对象

  • 哈希对象

  • 集合对象

  • 有序集合

  • 类型检测与命令多态

  • 内存回收

  • 对象共享

  • 对象空转时长

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

  • 4种持久化方案

(二)MySQL

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

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

  • SQL CURD与高 级查询

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

  • MySQL权限管理

  • MySQL索引原理以及SQL优化

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

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

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

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

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

  • MySQL事务原理分析

  • 事务的ACID特性

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

  • 事务隔离级别

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

  • S锁X锁|S锁IX锁

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

  • 插入意向锁,自增锁

  • MVCC原理剖析

  • MySQL缓存策略

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

  • 缓存策略问题分析

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

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

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

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

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

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

(三)Kafka

  • Kafka使 用场景与设计原理

  • 发布订阅模式

  • 点对点消息传递

  • Kafka Brokers原 理

  • Topi cs和Partition

  • Kafka存 储机制

  • Partition存储分布

  • Partition文件存储机制

  • Segment文件存储结构

  • offset查找message

  • 高效文件存储设计

  • 微服务之间通信基石gRPC

  • gRPC的 内部组件关联

  • CI ientS ide与ServerSide, Channel, Ser ivce, Stub的概念

  • 异步gRPC的实现

  • 回调方式的异步调用

  • Server 与CI ient对RPC的实现

  • 基于http2的gRPC通信协议

  • 基于http协 议构造

  • ABNF语法

  • 请求协议Request-Headers

  • gRPC上下文传递

(四)Nginx

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

  • Nginx静态文件的配置

  • Nginx动态接口代理配置

  • Nginx对Mqtt协议转发

  • Nginx对Rtmp推拉流

  • Openresty对Redis缓存数据代理

  • shmem的三种实现方式

  • 原子操作

  • nginx channel

  • 信号

  • 信号量

  • Nginx过滤 器模块实现

  • Nginx Filter模块运行原理

  • 过滤链表的顺序

  • 模块开发数据结构 ngx_ str_ _t,ngx_ list_ t,ngx_ buf_ t,ngx_ chain_ t

  • error日志的用法

  • ngx_ comond_ t的讲解

  • ngx_ http_ _module_ _t的执行流程

  • 文件锁,互斥锁

  • slab共享内存

  • 如何解决 "惊群”问题

  • 如何实现负载均衡

  • 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、开源框架专栏

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

  • Skynet设计原理

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

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

  • 消息队列实现

  • actor消息调度

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

  • skynet reactor 网络模型封装

  • socket/ socketchanne|封装

  • 手撕高性能c服务

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

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

  • 基础接口 skynet. send, skynet. cal I, skynet. response

  • 广播组件multicastd

  • 数据共享组件 sharedatad datasheet

  • 手撕万人同时在线游戏

(二)分布式API网关

  • 高性能web网关Openresty

  • Nginx与lua模块

  • Openresty访问Redis,MySQL

  • Restful API接口开发

  • Openresty性能分析

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

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

  • 动态 负载均衡的原理

  • 服务发现实现的原理

  • Serverless

  • 监控,故障检测与恢复

  • 二代理层缓存与响应服务

  • 系统日志

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

  • SPDK文件系统设计与实现

  • NVMe与PCle的原理

  • NVMe Controller 与bdev之间的rpc

  • blobstore与blob的关系

  • 文件系统的posix api实现

  • 4层结构设计vfs

  • spdk的 异步改造posix同步api

  • open/wr ite/read/close的实现

  • 文件系统的性能测试与承接mysql业务

  • LD_ PRELOAD更好mysql系统调用实现

  • iodepth讲解

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

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

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

  • cpu+gpu的异构计算

  • 计算机体系结构中的gpu

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

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

  • MPI与CUDA

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

  • cuda的h264编解码

  • cuda的mpeg编解码

  • ffmpeg的cuda支持

(五)并行计算与异步网络引擎workflow

  • workflow的应用场景

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

  • mysq/redis/kafka/dns的请求实现

  • parallel处理与任务组装

  • workf low的组件实现

  • 线程池实现

  • DAG图任务

  • msgqueue的实现

  • 纯c的jsonparser实现

(六)物联网通信协议mqtt的实现框架mosquitto

  • mqtt的高效使用场景

  • mqtt的 发布订阅模式

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

  • 3种Qos等级

  • 0Auth与JWT的安全认证

  • mctt的broker

  • mqtt的遗嘱机制

  • 发布订阅的过滤器.

  • mosqujitto的docker部暑

  • matt的日志实时监控

6、云原生专栏

(一)Docker

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

  • 进程namespace

  • UTS namespace

  • IPC namespace

  • 网络namespace

  • 文件系统namesapce

  • cgroup的资源控制

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

  • Docker镜像下载与镜像运行

  • Docker存储管理

  • Docker数据卷

  • Docker与容器安全

  • Docker网络管理(项目)

  • 5种Docker网络驱动

  • pipework跨主机通信

  • 0vS划分vlan与隧道模式

  • GRE实现跨主机Docker间通信

  • Docker云与容器编排 (项目)

  • Dockerfile的语法流程

  • 编排神器Fig/Compose

  • FIynn体系 架构

  • Docker改变了什么?

(二)Kubernetes

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

  • k8s集群安全设置

  • k8s集群网络设置

  • k8s核心服务配置

  • kubectI命令工具.

  • yam|文件语法

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

  • Pod的管理配置

  • Pod升级与回滚

  • DNS服务之于k8s

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

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

  • Node的管理

  • namespace隔离机制

  • k8s集群日志管理

  • k8s集群监控

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

  • RESTful接口

  • API聚合机制

  • API组

  • Go访问k8s API

7、性能分析专栏

(一)性能与测试工具

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

  • goog letest与goog lemock文件

  • 函数检测以及类测试

  • test fixture测试夹具

  • 类型参数化

  • 事件测试

  • 内存泄漏

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

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

  • MySQL性能测试工具mysqlslap

  • Redis性能测试工具redis-benchmark

  • http性能测试工具wrk

  • Tcp性能测试工具TCPBenchmarks

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

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

  • 火焰图工具讲解

  • 火焰图使用场景与原理

  • nginx动态火焰图

  • MySQL火焰图

  • Redis火焰图

(二)观测技术bpf与ebpf

  • 内核bpf的实现原理

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

  • 动态hook: kpr obe/ upr obe

  • 静态hook: tr acepoint和USDT

  • 性能监控计时器PMC模 式

  • cpu的观测taskset的使 用

  • BPF工具bpftrace, BCC

  • bpf对内核功 能的观测

  • 内存观测kmalloc与vm_ area_ struct

  • 文件系统观测vfs的状态:

  • 磁盘io的观测bitesize, mdf lush

  • bpf对网络流量的统计

  • bpf对redis-server观测

  • 网络观测tcp_ connect, tcp_ accept, tcp_ close

(三)内核源码机制

  • 进程调度机制哪些事儿

  • qemu调试内存

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

  • task_ struct结构体

  • RCU机制与内存优化屏障

  • 内核内存管理运行机制

  • 虚拟内存地址布局

  • SMP/NUMA模型

  • 页表与页表缓存原理

  • 伙伴系统实现

  • 块分配(SIab/SIub/Slob) 原理实现

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

  • 文件系统组件

  • 虚拟文件系统vfs

  • Proc文件系统

  • super_ _block与 inode结构体

  • 文件描述符与挂载流程

8、分布式架构

(一)分布式数据库

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

  • 前缀搜索

  • 低优先级写入

  • 生存时间的支持

  • Transact i ons

  • 快照存储

  • 日志结构的数据库引擎

  • TiDB存储引擎的原理

  • TiKV的Key-Value存储引擎

  • 基于RBAC的权限管理

  • 数据加密

  • TiDB集群方案与Replication原理

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

  • Raft协议讲解

  • OLTP与0LAP

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

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

  • ceph的集群部署

  • monitor与OSD

  • ceph 5个核心组件

  • ceph集群监控

  • ceph性能调调优与benchmark

  • 分布式ceph存储集群部署

  • 同步机制

  • 线性扩容

  • 如何实现高可用

  • 负载均衡

(三)分布式协同

  • 注册服务中心Etcd

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

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

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

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

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

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

  • fuse的使用场景

  • 文件系统读写事件

  • fuse的实现原 理

  • /dev/fuse的 作用

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

  • 网关NAT表分析

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

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

  • 网络穿透的原理

  • 网络穿透的3种情况

9、上线项目实战

(一)dkvstore实现(上线项目)

  • kv存储的架构设计

  • 存储节点定义

  • tcp server/cI ient

  • hash数据存储

  • list数据存储

  • skiptable数据存储

  • rbtree数据存储

  • 网络同步与事务序列化

  • 序列化与反序列化格式

  • 建立事务与释放事务

  • 线程安全的处理

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

  • 大块与小块分配策略

  • 内存回收机制

  • 数据持久化

  • KV存储的性能测试

  • 网络测试tps

  • 吞吐量测试

  • go, lua, java多语言支持

  • hash/list/sk iptable/rbtree测试

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

  • ceph架构分析和配置

  • ceph架构分析

  • 快速配置ceph

  • 上传文件逻辑 分析

  • 下载文件逻辑分析

  • 文件传输和接口设计

  • http接口设计

  • 图床数据库设计

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

  • 业务流程实现

  • 容器化docker部署

  • crontab定时清理数据

  • docker server服 务

  • grpc连接池管理

(三)容器化docker部署

  • crontab定时清理数据

  • docker server服 务

  • grpc连接池管理

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

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

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

  • wrk测试接口吞吐量

  • jmeter压力测试

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

  • IM即时通讯项目框架分析和部暑

  • 即时通讯应用场景分析

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

  • 即时通讯数据库设计

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

  • 即时通讯项目部署

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

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

  • protobuf通信协议设计

  • reactor模型C++实现

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

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

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

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

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

  • 请求登录逻辑

  • 最近联系会话逻辑.

  • 查询用户在线主题

  • 未读消息机制

  • 单聊消息推拉机制

  • 群聊消息推拉机制

  • 路由转发机制

  • 数据库代理服务器设计

  • main函数主流程

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

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

  • redis实现未读消息机制

  • 如何实现群消息的推送

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

  • 文件服务器和ooker部署

  • 在线文件传输机制分析

  • 离线文件传输机制分析

  • etcd微服务注册与发现

  • docker制作与部暑

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

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

  • chatgpt的构想 与需求分析

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

  • gin框架实现代理服务

  • 接口功能设计

  • grpc与protobuf的使用流程

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

  • 敏感词识别服务

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

  • redis实现上下文管理

  • 问题记录保存

  • web端协议解析

  • OneBot协议

  • 服务部署上线

  • docker stack服务部署

  • wrk接口吞吐量测试

  • 线上节点监控

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

  • 网络模块实现

  • boost.asio跨平台网络库

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

  • boost. asio在TrinityCore 中的封装

  • 网络模块应用实践

  • 地图模块实现

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

  • 地图模块驱动方式

  • A0I 核心算法实现

  • AABB碰撞检测实现

  • A*寻路算法实现

  • 战斗模块实现

  • 技能设计以及实 现

  • Al设计

  • 怪物管理

  • 副本设计

  • TrinityCore 玩法实现

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

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

  • 触发机制实现

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

10、适宜的工程师人群(共分为8大群体)

  • 1.从事业务开发多年,对底层原理理解不够深入的在职工程师

  • 2.从事嵌入式方向开发,想转入互联网开发的在职工程师

  • 3. 从事Qt/MFC等桌面开发的,薪资多年涨幅不大的在职工程师

  • 4.从事非开发岗位(算法岗,运维岗,测试岗),想转后台开发岗位的在职工程师

  • 5.工作中技术没有挑战,工作中接触不到新技术的在职工程师

  • 6.自己研究学习速度较慢,不能系统构建知识体系的开发人员

  • 7.了解很多技术名词,但是深入细问又不理解的工程师

  • 8.计算机相关专业想进入大厂的在校生(本科及以上学历,有c/c++基础)

11、配套书籍资料

  • 1. MySQL: 《高性能MySQL 第3版》

  • 2. Nginx: 《深入理解Nginx: 模块开发与架构分析(第2版)》(陶辉)

  • 3. Redis: Redis设计与实现 (黄健宏)

  • 4. Linux内核: 《深入理解Linux内核架构》 (郭旭 译)

  • 5. 数据结构与算法:《算法导论》(第3版)

  • 6.性能分析:《性能之巅洞悉系统、企业与云计算》

  • 7. MongoDB: 《MongoDB权威指南》

  • 8. Ceph: 《Ceph分布式存储学习指南》 (Ceph中国社区)

  • 9. Docker: 《Docker容器 与容器云(第2版)》

  • 10. TCP/IP: 《Tcp/Ip详解卷一卷二卷三》

  • 11. Linux系统编程: 《Unix环境高级编程》

  • 12. 计算机: 《深入理解计算机系统》

  • 13. DPDK: 《深入浅出DPDK》

  • 14. k8s: 《Kubernates权威指南》 龚正等编著

  • 15. bpf: 《BPF之巅洞悉Linux系统和应用性能》

以上是系统学习课程大纲,需要系统学习请扫码添加小雯老师(备注911领取专属大额优惠券。

学习成果检验

  • 腾讯offer比例15%

  • 知名企业offer比例73%

  • 最高offer腾讯T3.1(现T9)年薪65w 

  • 最高年薪涨幅30W

  • 最快跳槽学习时间1个半月

如果是想在c/c++开发方向得到有效的快速提升(不是所谓的速成),这份学习体系是大家绕不过的具有参考意义的提升路线。从学习路线中可以对c/c++开发方向的技术栈有一个清晰的认识。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多