针对C++后端/鸡架面试题汇总,感谢贡献面经的大家;数据库我不太熟可能搜集的是偏内核的题目;
博客与github仓库同步更新。欢迎在仓库贡献答案发起pull request。
系统
体系结构
- 增加CPU的数量,会对CPU密集型或IO密集型的任务性能处理有提升吗?
- CPU多级缓存,为什么这么设计?
- 用户态和内核态区别是什么?
- 用户态和内核态切换的主要开销在哪里
- 同步IO和异步IO的区别,阻塞IO和非阻塞IO的区别,是否存在同步非阻塞IO?
- 物理地址在cache中的映射关系
- 讲一讲NUMA架构
- cpu缓存机制的坏处
- 大型系统debug中应该怎么定位问题?如果硬件缺中断怎么办?
操作系统
- 操作系统有哪些主要功能?
- 常见的系统调用?
- 什么是零拷贝?
- 什么是RTOS?
进程管理
- 进程和线程区别和联系
- Python/Java/C++里面的线程有什么不一样?
- 时间片是什么
- 进程、线程、协程切换的开销分别是什么
- 进程通信方式;管道和socket各自使用在什么场景里面呢?
- 讲讲 fork() 函数
- Linux 杀死进程的过程
- 知道哪些信号,什么时候产生?
- 什么是协程?
- 讲一讲调度算法。调度算法调度的是什么?目前Linux使用的是哪一个呢?
- int i;while(true){i++;} 在自己的电脑上一秒钟大概的值;怎么估算;
内存管理
- 操作系统页面置换算法
- 分段机制、分页机制,缺页中断、为什么有页表
- Linux为啥要做分页?缺点是什么?为什么随机读写比顺序读写慢?
- 操作系统里面分配内存和管理内存,怎么做的?如果是多核的情况应该怎么优化呢?
- 为什么需要虚拟内存?
- malloc()底层涉及了什么系统调用?mmap和brk的区别?
- 内存池怎么实现?有什么优化点?
文件系统
- write操作发生了什么
- write的用户态内核态操作,数据要拷贝到内核态吗,如果突然宕机了会有没写的吗?怎么刷新缓冲区呢?这块系统调用是什么呢?异步情况下缓冲区啥时候落盘会不会阻塞
- 讲一讲怎么看文件权限?文件权限是怎么实现的?
- Linux 文件描述符 vs. 文件句柄
- 基本的IO模型有哪些
- 文件描述符有哪些种类?
- ext2 的 inode里面大概有哪些内容?
- read操作大概会发生什么? 包括磁盘io 磁盘驱动那块怎么做
- ext2中的目录树是怎样实现的
并发
- 什么是线程安全?
- 服务器多线程如何防止数据冲突
- 死锁产生的条件;设计一种通用性算法,怎么检测一个死锁;
- 说说(Java)ThreadLocal或(C++)thread_local
- (Java) 多线程wait notify join
- 自旋锁互斥锁 读写锁,公平锁/非公平锁, 乐观锁和排他锁是什么?
- 生产者消费者模式下队列读写会有死锁吗?
Linux 使用
- 用 cat 和 grep 根据关键字查找日志
- grep 查找前边的十行,用什么参数
- 用什么工具调试内存泄漏,怎么定位?
- Git 底层
- 是否用过 Linux,常用命令
- 你觉得linux操作系统可以怎么改进
- linux里netfilter的原理是什么?
- linux启动gui还是文本框是怎么区分的?
- linux中sudo提权的原理是什么?
- linux实现软路由的原理是什么?
- linux login之后的程序是什么?
- linux中”hello world”发生了什么?
- 什么是linux RCU机制?什么是watch dog机制
- 什么是中断?linux硬中断的流程是什么?linux中断的时候pcb存在什么位置?什么是中断底部中断顶部?
- mmap在linux底层是怎么实现的?它是怎么把虚拟地址映射到物理地址的?
- socket的文件拷贝流程是怎样的?可以怎么优化呢?sendfile的原理是什么?
- memset有多少次缺页?
- 共享内存怎么实现
网络
架构
- 计网分层模型
- 介绍一下IP/TCP的每一层,以及每一层常见的协议
- 当我在浏览器上输入美团的招聘网站,直到页面出现,中间的流程是怎么样的
- raft可以怎么优化
低两层
- 介绍数据链路层 CSMA/CD 协议
- 描述一下ARP协议 / 在同一个子网里头,如何获取主机的 MAC 地址 / 不知道 MAC 地址,是怎么转发的:
网络层
- ping 的原理
- traceroute 的原理
2.1 如果有多条平行路由路径,怎么把这些路径都探测出来? - 常见路由算法 BGP OSPF RIP LS/DV
- 一台机器上有两个网卡,如果把它们的 ip 地址配到同一个网段,会发生什么问题?
传输层 TCP/UDP/QUIC
- UDP 和 TCP 的区别,谁有队头阻塞
- 包格式
- TCP、UDP中的报文头有哪些字段
- UDP的包有大小限制,是UDP协议自己的限制的吗?(是下层的IP协议的IP包大小限制)TCP没有限制吗?
- 讲一讲TCP的flag字段有哪些?rst字段作用是什么?
- TCP 连接管理
- 三次握手;
- 四次挥手,各个状态,time_wait和close_wait在挥手的哪个阶段;四次挥手大量的time_wait/close_wait状态是有哪些可能的原因
- 为什么需要第三次的ACK应答;第三次握手没有了会发生什么问题;TCP 为什么要三次握手,而不是两次握手
- 四次挥手为什么多一次?如果服务端发现没有数据需要发送,FIN 和 ACK 可以合并吗,协议支持吗
- 心跳探测
- CLOSE_WAIT是什么?你说服务器上出现closewait,那么客户端上会出现closewait吗
- SYN Flood 会怎么样,如何解决?
- 可靠数据传输
- TCP为啥是可靠的?咋保证的呢?
- UDP怎么在应用层做一些可靠性保证
- 拥塞控制
- 流量控制
- 快速重传/超时重传:
应用层
- DNS 协议的详细流程
- HTTP2 跟 HTTP1 的区别,谁有队头阻塞
- 了解哪些开源的 RPC 框架,gRPC 的特点
- https和http,https加密的过程;https为什么不是只用非对称加密,非对称加密如何实现
- HTTP长连接、短连接
- 对于文件上传问了挺多问题的
- 讲讲HTTP 3
- cookie 和 session 的对比
- MPI用过吗?
- HTTP怎么解析?
Linux内核网络
- 使用socket()开发时,客户端服务端分别会调哪些系统调用?追问如果服务端一直不accept()会发生什么情况?
- 常用的IO多路复用技术
- epoll 的数据结构;
- tcpdump 的原理
- netfilter 的原理
- 如何在 Linux 上实现软路由
- eBPF 的原理?编译完的eBPF跨内核版本/跨机器能不能通用?
- Linux内核网络中,从socket()发送数据到出网卡的流程(包括四层处理、三层路由、二层ARP、驱动)
- 追问三层路由:ping本地网络中的另一台主机,查询到一条/16的linklocal路由以后要干什么?回答:用ARP解析对端MAC,但是面试官不满意
- 继续追问:发出ping的ICMP包后,内核是否会把/32路由插入本地路由表?回答:不会,只会插入二层neighbor表,面试官表示你确定?
- Linux NAPI 机制
- linux网卡收包过程:
- 多块网卡bond的技术是什么? 负载均衡会不会 RSS RFS啥的会不会
- 三次握手和socket的状态变化关系 以及如果超时了会怎么样?linux这块超时是怎么设计的
RDMA
- 讲一讲RDMA技术的优势
- 讲一讲RDMA WRITE操作的细节
- RDMA为什么要注册一块内存
- RDMA相对于TCP/UDP的集中类型(四种)
- RDMA相对于TCP/UDP的性能有没有测过(这个需要测?)
- 这块内存会swap到磁盘上吗(这个我不会 我回答的是我们一般开大页)
- RDMA和TCP协议栈有哪些不同
- RDMA 真实场景下延迟大概多少
- PFC 机制、PFC 风暴、 PFC 死锁
DPDK
- 介绍一下DPDK的原理;介绍一下DPDK转发数据包(从网卡进到网卡出)的完整流程
- 追问:DPDK驱动使用了用户态轮询的机制,和中断相比好处是什么
C++/STL/算法
- 哈希如何实现的;哈希的时间空间复杂度,解决冲突的方式
- hash表原理,扩容,什么时候扩容,扩多大;开链法如果链表很长,你有什么解决方法
- 说下hashmap插入一个节点的过程 ;
- concurrent hashmap C++怎么实现;
- 加锁导致性能下降,有什么解决办法? 加了读写锁性能还是不够,有什么方法?读写公平锁怎么做的?
- 哈希算法有几种、一次性哈希、如何判断这个哈希算法优秀
- map unordered_map底层实现
- 怎么删除map里面index是偶数的kv
- unordered_map 哈希表 具体实现;
- unordered_map怎么扩容?以及vector 怎么扩容 vector初始化的时候预备空间(就是reserve指定的玩意)大小
- thread-safe的concurrent hashmap C++怎么实现;
- 多态、重载(编译时还是运行时)、重写、泛型
- C++三个特性是哪三个?继承封装多态是什么?继承封装多态是什么?
- 你觉得OOP有什么好处
- 虚函数表是怎么实现的?对于对象A,A继承了对象B,C它的虚函数表怎么实现?爷爷父亲孙子这种呢?
- 虚函数表是为了实现运行时多态还是编译时多态?虚函数能不能 static
- 快速排序的特点 什么情况下复杂度高;什么是稳定排序 什么是不稳定排序
- 数组和链表的区别
- JVM 内存划分—>C++ 程序的内存划分和生命周期(类的成员变量和方法是放在哪里的)
- LSM vs. B+Tree;为什么B+树要把数据都放在叶子节点;这种存储相对于B树有啥优点
- 跳表怎么实现?它的时间复杂度呢?
- 反射机制以及应用;泛型机制以及应用
- 类的双亲委派模型
- 怎么看区别一个类和别的类(类加载器+全类名)
- ACID解释一下
- 线程池参数;线程池的关闭;线程的关闭;wait/sleep的区别;核心线程数一般是多少?线程池任务调度是怎么样的
- 如果用红黑树,红黑树适合什么场景,他的复杂度是多少
- C++20的协程了解过吗
- 如果让你在C++写一个线程池,你会怎么写; 线程池里的线程执行任务之后直接就退出了,怎么保证还能持续从任务队列里面拿任务
- 什么是 CAS,什么是自旋;
- mutex的实现?
- 自旋锁怎么实现?自旋锁和互斥锁各自适合什么场景?优缺点是什么?
- C++内存屏障
- 什么场景下用 shared_ptr 什么场景下用 unique_ptr
- 讲一讲shared_ptr unique_ptr;哪一个快,shared_ptr是线程安全的吗;
- dfs和bfs的区别;一棵瘦高的树用dfs还是bfs
- LRU怎么实现
- 内存2g 磁盘500g 文件大小20g 每行一个数字 怎么对文件排序
- 悲观锁和乐观锁
- 类加载过程
- static关键字的用处是什么?
- include<>和include“”的区别是什么
- const关键字的使用;
const int *p,int * const p
等组合的区别 - new和malloc的区别是什么?
- 动态链接静态链接区别是什么?
- cpp为什么开源库的结构体要对齐成128kb
- 什么是好的并发算法
- 讲一讲完美转发
- segment fault 错误的原因、有用gdb 调试coredump吗
- char s = (char )malloc(100); s[100] = ‘a’ 内存实际分配在什么时候,如果物理内存不够,第一行出错还是第二行
- CPP为什么开源库的结构体要对齐成128Kb
- C++异步IO怎么实现;future promise 原理
- B+树并发算法怎么做
- Extern “c”的含义是什么
- 用什么数据结构可以用于快速找到满足范围要求的多维数据,比如RGB三维数据表示颜色,怎么快速找到符合RGB要求的颜色;
- CPP atomic 内存模型
- C++中纯虚函数怎么实现?父类实现了纯虚函数,子类还需要实现吗?
数据库
- 说一说mysql的索引,为什么使用B+树(跟B树和hash比)B树和B+树查询有啥区别?IO上有啥区别?还有哪些索引?
- redis的数据结构
- redis的string怎么实现的,二进制的结构是什么样子的(没回答上来)
- 介绍下ES,ES是做什么的,ES为什么能从doc中快速查找
- mysql主键和非主键区别
- 2pc提交
- MapReduce原理;怎么手写
- mysql的火山模型
- mysql左连接 右连接 内连接 全外连接
- 两个表,A左连接B,建立索引怎么高效
- ACID解释一下;各个隔离性级别和实现;事务的隔离级别,哪一个隔离级别解决了脏读、幻读
- 二级索引解释一下;主索引/辅助索引;
- Mysql有哪些存储引擎;InnoDB和MyIsam的区别
- 聚簇索引
- 表有字段姓名 性别 年龄 班级 该怎么建立索引提高查找效率
- mvcc机制
- 写个sql,今日消费最多的前10个人
- 说说 MySQL 索引(B-Tree索引、哈希索引、R-Tree索引、全文索引等等)
- 数据一致性检验
- mysql日志:redo log、binlog、undo log 区别与作用
- 讲一讲bufferpool机制,是为了优化什么场景?
中间件、微服务
- 消息队列作用、为什么要引入;MQ消息丢失问题
- 缓存穿透\击穿\雪崩场景解释,缓存穿透解决方法
- zookeeper的作用,怎么做负载均衡基于什么理论,部署zookeeper集群对网络和机房的要求
- kafka:如果leader挂了,怎么恢复任务,怎么保证数据最终一致性
- 负载均衡机制,负载均衡算法
设计模式
- 了解的设计模式,有哪些讲下策略模式
- 单例
- 懒汉饿汉模式讲一下
算法题
- 二叉树的右视图
- 岛屿数量
- k个一组反转链表,自己处理输入输出
- 输出有效括号对
- 两个大整数相加;字符串给出的两个大整数相加 返回字符串
- 0或1组成的数组,最多允许你把k个0变成1,求变换后数组最长连续1的个数
- 一堆工作1-5-3-2-1 k工人 最短完成时间
- m * n的二维矩阵,行列有序,找到第k个大的数。
- 小顶堆插入数字的调整,用数组实现一下
- 归并排序
- 走格子,上下左右走,14,23=1+4+2+3=10超过阈值k=8的走不到,问能走到多少格子
- topk
- 一个字符串找出里面出现最多的一个字符
- 约瑟夫环,报数123
- 合并区间
- 实现对一个数开平方
- 反转链表
- 给二叉树的中序序列和后序序列,求前序序列
- 有向图找环
- 去除数组中的重复数字
- 下一个更大元素 II
- 将点分十进制表示的IPv4地址(本质上是一个32位二进制数)转化为一个十进制数(难崩 实操中我是用chatgpt+python做的)
- 二叉树的层序遍历
- 最大子数组和
- 跳台阶,可以跳 1-n 级
- 有序链表合并
- 一亿个浮点数,找到最大的10000个
- 算法: 实现一个能够完成定时任务的类
- 链表的区间反转
- 白板写整型转8进制,需要运行,只能使用char数组,不能使用任何库函数,得到char数组后最后返回值可以转string
- 快乐数
- |x!*y-y-n|最小
- 循环数组找最小值(二分即可,关键是条件判断)
- 到来一个序列找中位数(维护两个堆,一个小的部分一个大的部分,保证他们的数量相差不超过1即可)
- 二叉树最大宽度 https://leetcode.cn/problems/maximum-width-of-binary-tree/
- 两个有序数组找中位数
- 累加数 leetcode306
- 实现 memmove 库函数
- 实现atoi
- 实现inet_ntop
- 有一副手牌,只能打同花和顺子,输出如果能打完手牌,打出的牌的系列
- 给一亿个ipv4地址怎么排序;TOP100呢
- kmp算法口嗨
- 二叉搜索树和双向链表 剑指36;
- 带括号的计算器实现
智力题/数学题
- 找硬币 9个,有一个不知道轻重,最多几次
- 四个球中有一个是假货,只有一个天平,没有砝码,有供比较的标准球;问怎么找到假货以及知道假货是偏轻还是偏重
- 连续扔一枚硬币,直到连续两次正面超上,问你期望投掷次数
- m 枚正品硬币,n枚次品硬币,次品硬币两面都是国徽。随手掏出一枚硬币,连续投掷r次都是国徽,问你是正品硬币的概率是多少
- 九辆赛车,有一条跑道可以同时比较三辆赛车;目标是找到速度前两名;请问需要几次;
- 64匹马比赛,每次比8匹,找出1234,最小次数
- 100瓶水 有一瓶是慢性毒药 请问最少需要几只老鼠