Linux项目相关
1.平均负载?平均负载: 单位时间内活跃的进程数
eg:
平均负载为 2 时,意味着什么呢?
系统有2个CPU:所有的CPU都刚好被完全占用。
系统有4个CPU: CPU有50%的空闲。
系统有1个CPU:一半的进程竞争不到CPU,会有进程切换
2.记录了1分钟、5分钟、15分钟的平均负载,到底怎么参考?负载平衡:1 分钟、5 分钟、15 分钟的三个值基本相同
1 分钟的值远小于 15 分钟的值: 在14分钟的时间里系统的负载情况是有一点问题的
1 分钟的值远大于 15 分钟的值: 这种增加有可能只是临时性的,需要持续观察
1 分钟的平均负载接近或超过了 CPU 的个数: 系统正在发生过载的问题,就需要分析具体的问题,并进行优化了
当平均负载高于 CPU 数量 70% 的时候,你就应该分析排查负载高的问题了。
3.平均负载与 CPU 使用率的区别平均负载: 代表的是活跃进程数,指单位时间内,处于可运行状态和不可中断状态的进程数。
CPU 使用率: 单位时间内 CPU 繁忙情况的统计。
平均负载和CPU使用率未必是一致的:
CPU 密集型进程,使用大量 CPU 会导致平均负载升高, ...
TCP协议
1.什么是TCP网络分层?
客户端:发送HTTP数据包
应用层:根据HTTP协议组装数据包
传输层:增加TCP头部(包含端口号、序列号等)
网络层:增加IP头部(包含源IP地址等)
网络接口层:增加以太网头部(包含MAC地址等)
服务端:接收HTTP数据包
应用层:HTTP报文解析
传输层:TCP报文解析
网络层:IP报文解析,传送数据包、确定路由
网络接口层:根据MAC地址判断包是不是发给自己的
2.TCP协议的三次握手为什么不能是两次?为什么不能是四次?三次握手:
客户端向服务端发送连接请求:客户端发送请求报文将 SYN = 1 同步序列号和初始化序列号 seq = x 发送给服务端,发送完之后客户端处于 SYN_Send 状态 (确认客户端的发送能力、服务端的接收能力)
服务端向客户端确认:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,此时服务器处于SYN_RCVD 的状态(确认服务端的发送能力、客户端的接收能力)
客户端收到 SYN 报文之后, ...
IO多路复用
IO多路复用IO多路复用:由内核检测多个文件描述符的状态,来解决传统的阻塞式的IO,可以提高CPU的利用率。另外,相比于多线程模型,每个连接都要一个独立的线程,所需的系统开销过大,而IO多路复用只有在连接准备好进行读写操作时,才进行处理。
select函数原型1234567#include <sys/select.h>struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */};int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval * timeout);
nfds:委托内核检测的这三个集合中最大的文件描述符 + 1
readfds:需要检测读缓冲区的文件描述符的集合
writefds:需要检测写缓冲区的文件描述符的集合
exceptfds: 需要检 ...
C++八股7
1. 什么是STL?STL,即标准模板库
STL从广义上讲主要包括三大部分:算法、容器和迭代器。
2. 什么是RAII?RAII 的全称是 Resource Acquisition Is Initialization(资源获取即初始化),这是一种 C++ 中的编程范式,用于管理资源(如内存、文件句柄、网络连接等)的生命周期。
资源的分配与对象的构造绑定:在对象创建时(调用构造函数)申请或分配资源。
资源的释放与对象的析构绑定:在对象销毁时(调用析构函数)自动释放资源。
智能指针(std::shared_ptr和std::unique_ptr)即RAII最具代表的实现,使用智能指针,可以实现自动的内存管理,再也不需要担心忘记delete造成的内存泄漏。
3.++it 和 it++ 的区别以及哪个更好?前置递增 (++it):不需要额外创建临时对象,因此效率更高。
1234int& operator++() { *this += 1; // 将当前对象加 1 return *this; // 返回当前对象的引用}
后置递增 (it++):后置递增首 ...
套接字通信
套接字通信1.基本概念1.1 局域网和广域网局域网:局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。、
局域网的主要特点是传输速度快、延迟低、成本较低且安全性高。
广域网:又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。
广域网相对于局域网来说,传输速度较慢,延迟较高。
1.2 IP和端口IP: 是分配给网络上每个设备的唯一标识符,用于在网络中进行通信。
IPv4
IPv4使用32位整数来表示一个IP地址,这相当于4个字节。通常,这个32位的地址被分为四部分,每部分8位(1字节),并以点分十进制格式表示。
最小的IPv4地址是 0.0.0.0,而最大的是 255.255.255.255
鉴于IPv4采用32位地址,理论上总共可以提供 2^{32}个不同的地址
IPv6
IPv6使用128位整数来表示一个IP地址,等同于16个字节。
Pv6地址写作8组,每组4个十六进制数字,各组之间用冒号分隔,例如 2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b。
由于IPv6采用128位 ...
C++八股6
1.为什么虚函数能实现动态绑定?虚函数能实现动态绑定主要通过虚函数表和虚函数指针实现的
动态绑定的具体过程:
调用虚函数:
当通过基类指针或引用调用虚函数时,编译器生成的代码不会直接调用函数,而是通过虚函数指针查找虚函数表中的函数地址。
查找虚函数表:
编译器会根据对象的虚函数指针找到该对象所属类的虚函数表。
在虚函数表中查找对应虚函数的地址。
调用实际函数:
根据虚函数表中的地址,调用实际的函数版本。
如果派生类重写了虚函数,则调用派生类的版本;否则调用基类的版本。
注:虚函数表 vs 虚函数指针
2.如何禁止程序自动生成拷贝构造函数?
方法一:将拷贝构造函数和拷贝赋值函数设置为 private
方法二:直接使用 = delete 来显式删除函数
3.你知道回调函数吗?它的作用?回调函数就相当于一个中断处理函数,由系统在符合你设定的条件时自动调用。(Qt中的槽函数)
4.介绍一下友元函数和友元类的用法和作用友元(friend)机制允许某些函数或类访问另一个类的私有(private)和保护(protected)成员。
友元关系打破了封装性,但提供了灵活性。
友元函 ...
C++多线程编程
多线程编程头文件:#include<thread>
创建线程:
123456789101112131415#include <iostream>#include <thread>void threadFunction() { std::cout << "Hello from thread!\n";}int main() { // 创建一个线程并执行 threadFunction std::thread t(threadFunction); // 主线程继续执行 std::cout << "Hello from main!\n"; // 等待线程 t 完成(join是一个阻塞等待) t.join(); return 0;}
分离线程: 不希望主线程等待子线程完成,可以调用detach()方法。分离后的线程将在后台运行,主线程不再与之关联。
1234567891011121314#include < ...
C++八股5
1.怎样判断两个浮点数是否相等?由于浮点数在计算机中的表示方式和存储限制,直接使用 == 操作符来判断两个浮点数是否相等可能会导致不准确的结果,即使这两个数看起来应该是相等的。这是因为浮点数的精度有限,在某些计算后可能产生非常小的舍入误差。
正确的做法是比较两个浮点数之间的差值是否在一个很小的范围内,而不是直接检查它们是否完全相等。可以将这两个浮点数相减,然后取结果的绝对值,并与一个预设的小阈值(也称为“精度”)进行比较。
1234if abs(a - b) < epsilon: print("a and b are considered equal")else: print("a and b are not equal")
2.类如何实现只能静态分配和只能动态分配
只能静态分配: 类的对象只能在栈上创建,将 new 和 delete 运算符重载并声明为 private 属性。
12345678910111213141516171819202122232425262728#include <iostream>clas ...
C++泛编程
C++泛编程1.autoauto的主要用途:让编译器自动推断变量的类型
代替冗长复杂的变量声明(函数指针)
在模板中,用于声明依赖模板参数的变量
函数模板依赖模板参数的返回值
用于Lambda表达式中
2.函数模板12345template <typename T>void func(T &a,T &b){}
注1:可以为类的成员函数创建模板,但不能是虚函数和析构函数。
注2:使用函数模板时,如果自动类型推导,不会发生隐式类型转换,而如果显式指定了函数模板的数据类型,则可以发生隐式类型转换。
编译器使用各种函数的规则:
普通函数>具体化>常规模板
如果希望使用函数模板,可以用空模板参数强制使用函数模板
123456789101112131415161718192021222324#include <iostream>// 普通函数void show(int a) { std::cout << "普通函数: " << a << std:: ...
C++八股4
1.malloc、realloc、calloc的区别
malloc函数:
用于分配指定大小的内存块,并返回指向该内存块的指针。如果分配失败,则返回 NULL。
使用 malloc 分配的内存不会被初始化,其中的数据是随机的。
calloc 函数:
原型为 void* calloc(size_t n, size_t size);
第一个参数 n 表示要分配多少个元素;第二个参数 size 表示每个元素的大小(以字节为单位)。
calloc 会将分配的内存初始化为零。
realloc 函数:
原型为 void* realloc(void *p, size_t new_size);
realloc 函数用来改变已经分配的内存块的大小。它可以扩大或缩小已有的内存块。如果新的内存大小大于原来的大小,那么新增的部分内容未定义(即可能包含任何值)。如果缩小内存块,超出部分会被丢弃。
注:C++中可以通过使用STL容器来避免使用realloc的情况,可以减少由于手动管理内存而引发错误的可能。
2.类成员初始化方式?构造函数的执行顺序 ?为什么用成员初始化列表会快一些?类成员 ...