大疆智能驾驶软件工程二面
1. TCP三次握手和四次挥手的过程
三次握手建立连接:
- 客户端发送SYN报文,进入SYN_SENT状态
- 服务器收到后发送SYN+ACK报文,进入SYN_RCVD状态
- 客户端收到后发送ACK报文,双方进入ESTABLISHED状态
四次挥手断开连接:
- 主动方发送FIN报文,进入FIN_WAIT_1状态
- 被动方收到后发送ACK报文,进入CLOSE_WAIT状态,主动方进入FIN_WAIT_2状态
- 被动方发送FIN报文,进入LAST_ACK状态
- 主动方收到后发送ACK报文,进入TIME_WAIT状态,等待2MSL后关闭
2. 虚表指针存储在对象内存的什么位置
虚表指针通常位于对象内存布局的最开始位置。
- 这样设计便于快速访问虚表,提高多态调用效率
- 保证了派生类对象中基类部分的内存布局一致性
- 在多重继承情况下,每个基类部分都有自己的虚表指针
3. 什么是内存对齐,为什么需要内存对齐
内存对齐是指数据在内存中的存储地址必须是某个值的整数倍。
- CPU访问对齐的数据效率更高,某些架构访问未对齐数据会导致性能下降甚至崩溃
- 编译器会在结构体成员之间插入填充字节来满足对齐要求
- 可以通过调整成员顺序或使用pragma pack指令来优化结构体大小
4. 构造函数和析构函数能否为虚函数
构造函数不能是虚函数。
- 对象创建时虚表尚未完全建立,虚函数机制无法工作
- 构造函数的职责就是初始化对象包括虚表指针,此时对象类型已经确定
析构函数应该是虚函数(当类作为基类时)。
- 当基类指针指向派生类对象时,如果基类析构函数不是虚函数,删除对象只会调用基类析构函数,导致派生类资源泄漏
- 声明为虚函数后,会根据对象实际类型先调用派生类析构函数,再调用基类析构函数,确保资源正确释放
5. 进程和线程的区别
资源分配和调度:
- 进程是资源分配的基本单位,拥有独立的地址空间
- 线程是CPU调度的基本单位,共享进程的地址空间和资源
开销和切换:
- 进程创建和切换开销大,需要切换页表和上下文
- 线程创建和切换开销小,只需切换寄存器和栈
通信方式:
- 进程间通信需要特殊机制如管道、共享内存、消息队列
- 线程间可以直接访问共享变量,但需要同步机制
6. 智能指针的类型及各自特点
unique_ptr独占所有权。
- 同一时刻只能有一个unique_ptr指向对象,不能拷贝只能移动
- 开销最小,性能接近原始指针
- 适合明确所有权归属的场景
shared_ptr共享所有权。
- 使用引用计数管理对象生命周期,多个shared_ptr可以指向同一对象
- 最后一个shared_ptr销毁时释放对象
- 有引用计数的原子操作开销,可能出现循环引用问题
weak_ptr弱引用。
- 不增加引用计数,用于打破share
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。
查看6道真题和解析