面试经验总结记录
操作系统
1、高并发的本质是什么
充分利用多核CPU,解决IO速度和CPU速度的冲突 ,当碰到IO或者其他情况的阻塞的时候,如果是单线程会导致整个程序阻塞,但多线程可以有其他线程继续利用CPU资源继续工作
2、进程池,线程池,连接池(更偏向于JAVA的问题)
线程池创建的时候需要定义
- 核心线程数大小(正常工作使用的线程数)
- 最大线程数(当核心不能满足需求时,扩容能够扩展的最大线程)
- 线程存活时间(超出核心线程数的线程维持时间)
- 任务队列(用于存放等待的任务)
- 拒绝策略(当队列已满,线程数达到最大还有新的任务进来)
3、线程池的扩充和删除
当任务队列已满,线程达到最大时,可以采用扩容策略进行扩容,动态增加核心线程数和最大线程数以满足任务数量的需求
线程池预热,线程池创建完成后,池里是没有线程的,所以需要预热
怎么让线程池的线程阻塞(suspend阻塞,resume唤醒)
4、线程同步的方式
- 互斥量(只有一个线程能够访问)
- 信号量(n个线程能够访问)
- 条件变量
- 锁
5、进程通信方式
- 管道(匿名管道,父子进程单向流通,命名管道利用文件系统)
- 系统IPC(消息队列,信号量,共享内存)
- socket
- 信号
6、进程的同步互斥方式
信号量,消息队列,管程(通过只能在管程内部使用的条件变量来提供同步)
7、线程安全
通过加锁对临界区进行保护
8、锁的类型
互斥锁(只允许一个线程访问)
条件锁(条件变量,满足条件则唤醒)
自旋锁(忙等,不释放资源直到条件满足)
原子锁(原子操作,锁内不会被中断)
读写锁(读可重入,写会阻塞)
悲观锁(每次写入数据都假设其他线程会更改数据,因此需要加锁)
悲观锁又包括共享锁(也叫读锁,可以读,不能写)
也包括排它锁(也叫写锁,其他事务无法进入)
乐观锁(直到数据提交才加锁)
公平锁(多个线程通过申请的顺序进入队列排队,排第一位的能够获得锁)缺点:吞吐量低,其余线程都阻塞。
非公平锁(直接获取锁,获取不到才进行排队)缺点:可能会饥饿
9、LRU算法(最近最少使用)
利用固定大小的双向链表,将已存在被访问的数据或新加入数据放在链表头,如果长度超标,删除链表尾的数据
LFU(最近不经常使用)
10、逻辑地址和物理地址的映射
浅析逻辑地址与物理地址映射关系_朱里安-优快云博客_逻辑地址到物理地址的映射
11、汇编角度的函数调用逻辑,push ebp,mov ebp,esp
12、怎么从硬盘中拿到想要的数据,通过段表或页表
13、内存泄露怎么检测,怎么解决
泄露类型:(1)堆泄露,malloc分配的空间没有释放
(2)系统资源泄露,socket资源没有释放
检查方案:(1)BoundsChecker
(2)windows平台,利用crt库
(3)Linux平台,利用valgrind
14、用户态调用fopen后发生了什么
15、TLB的作用
作为页表的cache
通过TLB可以直接将虚拟内存映射到物理内存,不需要访问页表
16、浮点数的存储方式,符号位,指数位,小数位
17、用户态进入核心态
(1)系统调用
(2)异常
(3)外设中断
计算机网络
1、用udp实现可靠传输功能
2、IP的分片机制
(1)DF=0,允许分片
(2)MF=1,后续还有分片,MF=0,最后一个分片
(3)片偏移,单位是8字节
3、IP报文格式,TCP报文格式
4、TCP的可靠传输,流量控制,拥塞控制
拥塞控制:慢开始,拥塞避免,快重传,快恢复
5、TCP的timewait有什么用
(1)最后发送的ACK对方可能没有收到,如果对方没有收到会继续重发FIN,这时TimeWait状态会回复ACK并重置等待时间2MSL,
(2)对方发送的数据包可能由于网络原因还没有到达,这时还会继续接受数据包
6、证书的内容
7、为什么要三次握手
(1)通信双方都需要有能力发送信息并且接受回应的过程
(2)如果第二次后认为连接成功,服务器主动发送数据,而第二次握手可能会丢失,客户端就无法正常接受数据,三次握手的话,这种情况会进行第二次的重发
8、read,write的底层实现
9、IO复用,select和epoll的具体功能和实现
select将所有已连接的Socket都放到一个文件描述符的集合中,然后调用select函数将文件描述符拷贝到内核中,通过内核来检查是否有网络事件的发生,检查到后,将Socket标记为可读或可写,然后将整个文件描述符拷贝回用户态,再通过用户态遍历找到可读或可写的socket再处理
select利用固定长度的BitsMap来表示文件描述符集合,默认长度FD_SETSIZE 1024
poll用链表组织文件描述符集合,长度可以更大,但具体思路是一样的
epoll在内核中利用红黑树来跟踪进程的文件描述符,利用事件驱动的机制,在内核维护了一个链表来记录就绪事件,当有事件发生,可以通过回调函数将其加入列表中
epoll中提供ET边缘触发,当被监控的socket中有可读事件触发,服务器会从epoll_wait中苏醒一次,没有read结束也只会苏醒一次,因此必须要一次读完
LT水平触发,服务器会不断从缓冲区中读数据,读完才结束
10、ssl握手流程
clienthello(支持加密套件)
server_key_exchange(协商密钥),server_certificate(签名证书),server_hello_done(加密套件)
client_key_exchange(协商密钥)
change_cipher_spec(接下来用会话密钥加密),finished(hash,握手完成)
数据结构
1、LSM树
提高写性能,牺牲一部分读性能,让写操作顺序化
2、字典树
3、位图
排序算法
都是从小到大
选择排序
排序方案:每次选择最小的数与无序的第一位进行交换,交换的位置变为有序
优化方案:可以一次得到最大和最小两个数,节省一半时间
时间复杂度:O(n^2)
空间复杂度:O(1)
冒泡排序
排序方案:每次比较相邻两个数,如果第二个比第一个小,就交换
时间复杂度:O(n^2)
空间复杂度:O(1)
插入排序
排序方案 :把第一个元素当做有序数列,从第二个元素开始扫描未排序数列,将其插入有序数列中
时间复杂度:O(n^2)
空间复杂度:O(1)
希尔排序
排序方案:对待排序数组根据一定的增量分成多个子序列,对每个子序列进行插入排序,对增量进行递减到增量为1,则直接插入排序,相当于是插入排序的优化方案
时间复杂度:小于O(n^2)
空间复杂度:O(1)
快速排序
排序方案:找到一个数字基准,将比这个基准小的移动到左边,比他大的移动到右边,每轮该基准都能找到自己的最终位置
时间复杂度:O(nlogn)
空间复杂度:O(1)
归并排序
堆排序
C++
1、C++不能重载的符号
- . 成员访问运算符
- .* 成员指针访问运算符
- :: 域运算符
- sizeof 长度运算符
- ?: 条件运算符
2、map,unordered_map,set有什么相同点和区别
map基于红黑树,有序,log(n)的查找效率
unordered_map基于hash表,无序,O(1)的查找效率,但不稳定,依赖于hash碰撞
3、回调机制
通过给函数传函数指针,触发事件时调用
4、函数指针 void(*pfun)(int);
5、虚函数实现机制
6、delete this
(1)this对象必须用new分配(而不是用new[],也不是用placement new,也不是局部对象,也不是global对象)
(2)delete this之后,不能访问该对象任何的成员变量和虚函数
(3)delete this之后,不能访问this指针
7、右值引用
延长右值对象的生命周期
8、对齐
9、static和const的作用
10、智能指针
shared_ptr
unique_ptr
weak_ptr
11、四种强制类型转换
const_cast 只能改变const
static_cast 任何具有明确定义的类型转换,不包含const
reinterpret_cast 位模式提供的较低层次的转换
dynamic_cast 类类型的转换,必须有虚函数
Base* base = new Derived;
Derived *der = dynamic_cast<Derived*>(base);
12、new和malloc的区别
- *最重要的。new进行类类型分配,会调用类的构造函数,利用delete进行释放会调用析构函数,而malloc没有
- *次重要。new[],delete[]可以进行数组的分配处理,malloc无
- 申请内存位置。new为自由存储区,具体位置需要看编译器,malloc为堆
- 返回类型安全性。new返回对象类型指针,类型匹配,malloc返回void*,需要强转
- 失败返回。new抛出异常,malloc返回NULL
- 内存大小分配。new不需要指定大小,直接按类型分配,malloc需要自定义分配大小
HTTP
1、具体格式
请求报文:
请求行,请求头,请求体
请求行(主要包括GET,POST,HEAD,PUT,DELETE等请求类型,结构为请求类型,url,http类型)
请求头(结构为,key: value,包括cookie,编码类型,主机名称,支持的语言类型,连接保持情况,客户端版本号,接受压缩类型,接收的资源类型)
请求体(包括请求的具体数据,对于GET请求,内容一般直接放在url中,请求体为空,而POST的请求内容都放在请求体中)
响应报文:
状态行,响应头,响应体
状态行(结构为http类型,状态码,状态信息,状态码:1xx(信息性)2xx(成功)3xx(重定向)4xx(客户端错误)5xx(服务器错误))(4,5到底有什么区别)
响应头(结构也为 key:value 包括cookie设置)
响应体(包括客户端请求的数据,类型为MIME type,包括text/plain,text/html等等)
2、GET和POST的区别
GET,请求参数全放到url中,这样请求长度就受到了限制
GET一般用于获取信息,可缓存,而POST用于修改数据,不可缓存
POST一般会有更多的请求头,需要说明其请求体部分,某些客户端的实现会让POST先发送头部再发送请求体,这样会导致POST的速度比get慢,但这种发两次包不是必须的
3、cookie的作用
由服务器发送给客户端,用于记录用户身份,下次再建立连接时一起发送cookie,服务器就知道客户端的身份了
弊端:
cookie的数量和长度有限制,存在安全问题,cookie可能会被第三方截获转发
MYSQL
1、索引底层实现是利用BTtree或者Hash或者B+Tree实现
BTree是一棵多叉平衡树,B+Tree只有叶子节点存放数据
本文是作者的面试经验总结,涵盖了操作系统、计算机网络、数据结构和C++等关键知识点。在操作系统方面,讨论了高并发的本质、线程池的工作原理、线程同步与进程通信方式、内存管理和LRU算法。计算机网络部分涉及UDP可靠传输、IP分片、TCP的可靠传输机制、SSL握手流程等。数据结构部分讲解了排序算法,如选择排序、冒泡排序等。C++部分涉及了函数指针、虚函数实现机制、智能指针等概念。此外,还介绍了HTTP的基本格式、GET和POST的区别以及cookie的作用。
2275

被折叠的 条评论
为什么被折叠?



