2026-05-26 20:37:47
字节跳动后端开发面试核心考察点涵盖网络编程、C++语言特性、系统编程、数据库、并发编程及问题定位能力,以下为具体高频问题及解析:
一、网络编程相关epoll ET模式如何保证缓冲区数据读完ET(边缘触发)模式下,内核仅在文件描述符状态变化时通知,需一次性读取所有数据。实现方式包括:
使用循环读取直到EAGAIN错误(如while((n = read(fd, buf, sizeof(buf))) > 0))。
确保缓冲区足够大,避免多次触发事件。
结合非阻塞IO,避免线程阻塞。
TCP与UDP区别
连接性:TCP面向连接(三次握手),UDP无连接。
可靠性:TCP通过序列号、确认应答、重传机制保证可靠性;UDP仅尽力交付。
性能:TCP头部开销大(20字节),UDP仅8字节;TCP支持流量控制(滑动窗口),UDP无。
应用场景:TCP适用于文件传输、邮件;UDP适用于视频流、DNS查询。
TCP三次握手过程
客户端发送SYN=1, seq=x到服务端。
服务端回复SYN=1, ACK=1, seq=y, ack=x+1。
客户端发送ACK=1, ack=y+1,连接建立。
TCP粘包问题及解决原因:TCP是流式协议,数据无边界,可能因发送方缓冲区合并或接收方读取不足导致粘包。解决方案:
固定长度消息(如每条消息100字节)。
分隔符法(如n分隔)。
头部包含长度字段(如HTTP协议)。
TCP可靠性实现
序列号与确认应答:确保数据按序到达。
超时重传:发送方未收到ACK时重传。
流量控制:通过滑动窗口避免接收方溢出。
拥塞控制:慢启动、拥塞避免、快速恢复等算法。
Nagle算法作用:减少小数据包数量,合并多个小数据包为一个发送。原理:仅当上一个ACK到达或数据包达到MSS(最大段大小)时才发送。适用场景:对延迟不敏感的场景(如文件传输);禁用场景:实时交互(如游戏)。
三大特性
封装:通过类隐藏实现细节,提供接口。
继承:子类复用父类属性和方法,支持多态。
多态:同一接口不同实现,分为编译时(重载)和运行时(虚函数)。
多态实现与虚函数
虚函数表:每个类维护一个虚函数表,存储虚函数地址;对象中包含指向虚函数表的指针(vptr)。
调用过程:通过对象vptr找到虚函数表,再调用具体函数。
浅拷贝与深拷贝
浅拷贝:仅复制指针,不复制指向的内容(如memcpy),可能导致重复释放。
深拷贝:复制指针指向的内容(如动态分配内存并拷贝数据),需自定义拷贝构造函数。
默认构造:编译器生成的默认拷贝构造函数执行浅拷贝。
类型转换
C风格转换:(type)value,不安全。
C++静态转换:static_cast,编译时检查,用于基础类型或无继承关系的类。
动态转换:dynamic_cast,运行时检查,用于多态类型(需虚函数)。
常量转换:const_cast,移除或添加const属性。
重解释转换:reinterpret_cast,低级转换(如指针转整数)。
new与malloc区别
初始化:new调用构造函数,malloc仅分配内存。
类型安全:new返回具体类型指针,malloc返回void*。
失败处理:new抛异常,malloc返回NULL。
内存大小:new自动计算,malloc需显式指定。
placement new作用:在已分配的内存上构造对象。用法:new (ptr) Type(),其中ptr为预分配内存地址。场景:自定义内存池、避免动态内存分配开销。
内存泄漏检测
工具:Valgrind(Linux)、AddressSanitizer(ASan)。
方法:监控内存分配/释放,检测未释放的块。
智能指针shared_ptr线程安全性
引用计数:原子操作,线程安全。
管理对象:非线程安全(需外部同步访问对象)。
sizeof(shared_ptr):32位机器下为12字节(包含指针和引用计数)。
进程崩溃定位
核心转储:启用ulimit -c unlimited生成core dump文件。
工具:gdb加载核心文件分析调用栈。
日志:记录崩溃前关键操作。
CPU 100%定位
工具:top查看高CPU进程,perf或strace分析系统调用。
方法:生成火焰图定位热点函数。
B+树索引一定快吗
优势:适合范围查询,磁盘IO次数少(层数低)。
劣势:插入/删除可能导致树重组,小数据量可能不如哈希索引。
查询慢优化:
检查索引是否失效(如函数操作字段)。
分析执行计划(EXPLAIN)。
考虑覆盖索引或联合索引。
事务ACID实现
原子性:通过undo log回滚。
持久性:通过redo log刷盘。
隔离性:通过锁(如MVCC)或多版本控制。
一致性:通过约束、触发器等保证。
数组与链表区别
内存分配:数组连续,链表分散。
访问效率:数组随机访问O(1),链表O(n)。
插入/删除:数组需移动元素,链表仅修改指针。
缓存友好性:数组更优(局部性原理)。
进程与线程
进程:资源分配单位,独立地址空间,通信需IPC。
线程:调度单位,共享进程资源,通信更高效。
fork()与Copy-On-Write:fork()后父子进程共享内存,写时复制。
线程同步方式
互斥锁:保护共享资源,避免竞争。
条件变量:配合互斥锁实现线程间通知。
读写锁:读共享、写独占。
原子操作:无锁编程,依赖CPU指令。
死锁条件与避免
条件:互斥、持有并等待、非抢占、循环等待。
避免方法:按固定顺序获取锁、设置超时、使用try_lock。
用户态与内核态
用户态:应用程序运行权限,受限访问硬件。
内核态:操作系统运行权限,可直接操作硬件。
切换开销:上下文切换耗时(如系统调用)。
并行与并发
并行:多核CPU同时执行多任务。
并发:单核通过时间片轮转模拟多任务。
单核能否并行:不能,但可通过并发提高吞吐量。