CVTE C++ 软件开发 二面 面经

1. 自我介绍

面试官您好,我是XXX,本科/硕士毕业于XX大学XX专业。一面之后对贵公司的业务方向更感兴趣了。我的技术背景主要是C++后台开发,熟悉网络编程和并发编程,做过XXX项目,实习期间在XX公司负责XXX模块。今天希望能进一步交流。

2. 进程和线程的区别是什么?

进程是操作系统资源分配的基本单位,拥有独立的虚拟地址空间、文件描述符、信号处理等资源。线程是CPU调度的基本单位,同一进程内的线程共享地址空间和文件描述符,但每个线程有自己独立的栈和寄存器上下文。

区别体现在几个方面:

隔离性:进程间内存隔离,一个进程崩溃不影响其他进程;线程共享内存,一个线程崩溃可能导致整个进程崩溃。

通信成本:线程间通信直接读写共享内存,成本低;进程间通信需要管道、消息队列、共享内存、socket等IPC机制,成本高。

切换开销:线程切换只需保存恢复寄存器和栈指针,开销小;进程切换还需要切换页表、刷新TLB,开销大。

创建销毁:线程比进程轻量,创建销毁更快。

3. 说说 epoll 的工作原理,LT 和 ET 模式的区别?

epoll 是 Linux 下高效的 I/O 多路复用机制,通过 epoll_create 创建实例,epoll_ctl 注册/修改/删除监听的文件描述符,epoll_wait 阻塞等待事件就绪。

内核实现上,epoll 用红黑树管理所有监听的 fd,用双向链表维护就绪事件列表。当 fd 状态变化时,通过回调将其加入就绪链表,epoll_wait 只需检查就绪链表,不需要遍历所有 fd,所以在大量连接场景下性能远优于 select/poll。

LT(水平触发):只要 fd 处于就绪状态,每次调用 epoll_wait 都会返回该事件,直到数据被读完。是默认模式,编程简单,不容易漏事件。

ET(边缘触发):只在状态发生变化时通知一次,比如从不可读变为可读时触发一次。要求每次触发后必须把数据全部读完(循环读直到返回 EAGAIN),否则后续不会再通知。ET 减少了系统调用次数,性能更高,但编程复杂,必须配合非阻塞 fd 使用。

4. 什么是内存对齐,为什么需要它?

内存对齐是指数据存储的起始地址必须是其自身大小的整数倍。比如 int(4字节)的地址必须是4的倍数,double(8字节)的地址必须是8的倍数。

原因有两点:

硬件限制:大多数 CPU 访问未对齐的内存需要多次总线操作,甚至在某些架构(如 ARM)上直接触发硬件异常。

性能:对齐的数据一次总线操作即可读取,未对齐可能需要两次,影响性能。

结构体对齐规则:每个成员按自身大小对齐,结构体整体大小是最大成员大小的整数倍。成员顺序会影响结构体大小,把小成员放在一起可以减少填充字节。

5. 虚函数的实现原理是什么?

每个含有虚函数的类都有一张虚函数表(vtable),表中按声明顺序存放各虚函数的指针。每个该类的对象在内存布局的起始位置有一个虚指针(vptr),指向对应类的 vtable。

调用虚函数时,编译器生成的代码通过 vptr 找到 vtable,再根据函数在表中的偏移找到实际函数地址,完成调用。这就是运行时多态的底层机制。

几个延伸点:

构造函数不能是虚函数,因为构造时 vptr 还没初始化完成。

析构函数

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论

相关推荐

zzzilik:但凡有一段 ai 相关经历实习,基本都进了,除了阿里云感觉卡硕
校招笔试
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务