大疆智能驾驶软件工程一面
1. select和poll的区别
select的特点:
- 使用固定大小的位图(fd_set)来表示文件描述符集合,通常限制为1024个
- 每次调用需要将fd_set从用户态拷贝到内核态
- 返回后需要遍历整个fd_set来找出就绪的文件描述符
- 跨平台性好,几乎所有Unix系统都支持
poll的特点:
- 使用pollfd结构体数组,没有最大文件描述符数量限制
- 同样需要将整个pollfd数组在用户态和内核态之间拷贝
- 返回后也需要遍历整个数组找出就绪的描述符
- 相比select,接口更清晰,不会修改传入的数据结构
共同缺点:
- 都需要轮询检查,时间复杂度O(n)
- 大量文件描述符时性能较差
- 每次调用都需要重复传递文件描述符集合
2. 虚拟内存和物理内存的映射机制
操作系统通过**页表(Page Table)**实现虚拟地址到物理地址的映射:
- 虚拟地址被分为页号和页内偏移
- 页号作为索引查找页表,获得物理页框号
- 物理页框号+页内偏移 = 物理地址
- 现代系统多采用多级页表(如四级页表)来节省空间
- TLB(Translation Lookaside Buffer)缓存常用的页表项,加速地址转换
3. 缺页中断的处理流程
当进程访问的页面不在物理内存中时,触发缺页中断:
- CPU检测到页表项的有效位为0,产生缺页异常
- 陷入内核态,保存现场
- 内核检查访问是否合法(地址是否在进程地址空间内)
- 如果合法,分配物理页框
- 从磁盘(swap区或文件)读取页面内容到物理内存
- 更新页表项,设置有效位
- 恢复现场,重新执行引发缺页的指令
缺页类型:
- 硬缺页:需要从磁盘加载
- 软缺页:页面在内存中但页表未更新
4. 互斥锁和自旋锁的区别
互斥锁(Mutex):
- 获取不到锁时,线程会进入睡眠状态,放弃CPU
- 适合锁持有时间较长的场景
- 涉及上下文切换,开销较大
- 不会浪费CPU资源
自旋锁(Spinlock):
- 获取不到锁时,线程会循环检查锁状态(忙等待)
- 适合锁持有时间很短的场景
- 不涉及上下文切换,开销小
- 会持续占用CPU资源
- 单核CPU上使用自旋锁可能导致死锁
5. 一个进程一个页表还是一个线程一个页表
一个进程一个页表。
- 同一进程内的所有线程共享相同的地址空间
- 因此它们使用同一个页表
- 进程切换时需要切换页表(更新CR3寄存器)
- 线程切换时不需要切换页表,只需切换栈和寄存器
6. 死锁的四个必要条件
- 互斥条件 :资源不能被多个进程同时使用
- 请求与保持 :进程已持有资源,同时请求新资源
- 不可剥夺 :资源只能由持有者主动释放
- 循环等待 :存在进程资源的循环等待链
**预防死锁:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。
查看10道真题和解析