大疆智能驾驶软件工程二面

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编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

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