(嵌入式面经)第11章 20+公司面经杂谈(五):Momenta、瑞晟、OPPO、VIVO

本篇涉及的所有问题概要:大家可以试试在看参考答案前,提前尝试解答,以便明确自身知识点的不足部分!

1.中断里面通常可以睡眠吗,为什么?

2.什么是栈溢出,有什么方法检测?

3.MCU 与 MPU 的区别是什么?

4.讲一下Linux中断分为上半部和下半部的原因?

5.如果给线程访问加锁,是在驱动层实现还是应用层实现?

6.现在需要一个常量5来做一些运算,你会使用const还是define?为什么?

7.项目里的ADC多通道采集是具体采用什么方式?

8.说一下互斥锁,自旋锁的区别,在中断中可以用哪个锁?

9.怎么保证原子性操作?

10.专栏订阅奖励(支持模仿)——个人创新点问答:在你设计的FreeRTOS PLUS中提及修改任务控制块,增加优先级阶段继承属性,来进一步降低“优先级反转”的影响,展开说说?

---------------------------------------------------------------------------------------------------

1.中断里面通常可以睡眠吗,为什么?

在 Linux 内核或嵌入式 RTOS(如 FreeRTOS)中,中断处理程序(ISR) 不能进入 睡眠(sleep/wait) 状态。

主要有 两大原因

  1. 中断上下文的限制(缺乏调度支持)
  2. 中断设计的初衷——高实时性、不可阻塞

1. 中断上下文限制,缺乏调度支持

📌 什么是中断上下文?

  • 内核中的中断处理程序不属于某个特定进程,而是独立的执行实体,没有进程调度信息。
  • 没有进程的内核栈、调度信息、文件描述符 等数据结构,无法像普通进程一样被调度。
  • 缺少进程控制块(PCB),无法进行任务切换。

✅ 具体分析

  • 进程上下文(Process Context) → 进程有自己的 调度信息、内核栈、寄存器保存,可以被挂起并恢复。
  • 中断上下文(Interrupt Context)没有这些信息,如果 ISR 进入睡眠,就无法被调度器重新唤醒。

🚨 问题:

  • 进入睡眠后 找不到中断的上下文信息,唤醒后无法恢复,系统可能会崩溃。

2. 中断设计的初衷:高实时性,不可阻塞

📌 中断的核心任务

  • 中断的目的是 快速响应硬件事件,执行最小化的任务,然后尽快恢复系统运行
  • 如果中断中调用 sleep(),会导致 CPU 挂起整个系统,影响其他任务的执行。

✅ 为什么要避免阻塞?

  • 中断优先级比普通进程高,如果中断中进入睡眠,会导致 CPU 被占用,进程调度器无法调度其他任务。
  • 高优先级中断可能会阻塞低优先级进程,影响系统性能

3. 实例:为什么 ISR 不能调用 sleep()

📌 错误示例

🚨 在中断处理中调用 sleep()

  • msleep()会导致任务挂起,但中断上下文没有进程调度信息,无法恢复。
  • 可能导致系统崩溃Kernel Panic
  • 📌 正确做法:使用 workqueuetasklet

    中断处理程序中,只做必要的工作,然后将复杂任务交给其他线程(如 workqueue)。

    解决方案:使用 workqueue

  • ISR 只负责触发任务,不会阻塞中断
  • workqueue 运行在进程上下文,可以 sleep()
  • 结论

    使用 workqueuetasklet 处理复杂任务

    避免在 ISR 中使用 sleep(),改为调度后台线程处理

    2.什么是栈溢出,有什么方法检测?

    1. 什么是栈溢出?

    栈溢出(Stack Overflow)是指程序在运行过程中,函数调用栈空间超出系统分配的范围,导致程序崩溃或行为异常。

    由于栈空间是有限的,如果程序需要的栈空间超过了系统分配的最大限制,就会发生栈溢出

    2. 栈溢出的常见原因

    📌(1)函数调用层数过深

    无限递归/深度递归 会不断地向栈中压入新的栈帧,最终超过栈的最大空间,导致栈溢出。

    示例:递归导致的栈溢出

    由于 stack_overflow_function()没有终止条件,递归会无限增长,最终导致栈空间被耗尽,程序崩溃。

    📌(2)占用栈空间过大的局部变量

    如果一个函数中的局部变量过大,尤其是大数组结构体,也可能导致栈溢出。

    示例:局部变量过大导致栈溢出

    🚨 问题:

    • 局部数组 buffer 占用了 10MB 的栈空间,大于默认栈空间,导致栈溢出。

    3. 栈溢出的后果

    4. 栈溢出的检测方法

    📌(1)哨兵检测(Stack Sentinel)

    • 在栈的起始地址结束地址放置特定的标志值(哨兵值),然后在任务切换或关键点检查这些值是否被修改。
    • 如果哨兵值被改写,说明发生了栈溢出!

    示例:哨兵检测

    • 只适用于单任务环境,如果多个任务共用栈空间,可能检测不到问题。

    📌(2)栈指针范围检测

    • 在任务切换时检查 SP(栈指针) 是否越界
    • 如果 SP 低于分配的栈空间,说明栈溢出

    示例:FreeRTOS 栈溢出检测

    📌 FreeRTOS 需要在 FreeRTOSConfig.h 启用检测

    📌(3)使用 ulTaskCheckFreeStackSpace() 监测任务栈

    FreeRTOS 提供的栈检查 API

    📌 如果 freeStack 过小(如 <20),可能需要增加栈空间!

    📌(4)GCC 编译器保护(-fstack-protector

    • 启用 -fstack-protector 选项,可以在函数返回时检测栈溢出
    • 原理:编译器在栈上存放"Canary" 保护值函数返回时检查 Canary 是否被修改如果被篡改,则触发 stack smashing detected

    启用 -fstack-protector

    gcc -fstack-protector -o test test.c

  • 只能检测函数返回时的溢出
  • 不能检测无限递归
  • 5. 如何预防栈溢出

    (1)避免深度递归

    • 用循环代替递归
    • 尾递归优化

    (2)减少局部变量的栈空间

    • 大数组使用 malloc() 在堆上分配
    • 减少函数嵌套调用

    (3)合理分配栈大小

    • 在 FreeRTOS/Linux 任务创建时,合理设置 STACK_SIZE
    • 监测 uxTaskGetStackHighWaterMark() 确保栈足够

    (4)使用 -fstack-protector 进行编译器保护

    gcc -fstack-protector -o my_program my_program.c

    (5)启用 configCHECK_FOR_STACK_OVERFLOW

    结论

    🚀 防止栈溢出,需要合理分配栈大小、优化代码结构、并启用硬件和软件监测机制! 🎯

    3.MCU 与 MPU 的区别是什么?

    • MPU(Microprocessor Unit) 适用于复杂运算的大型程序,通常需要外挂 RAM 和 ROM
    • MCU(Microcontroller Unit) 适用于中小型控制程序内部集成 RAM 和 ROM,无需外挂存储器。

    1. MCU(微控制器)

    特点:

    • 集成度高:MCU 典型地将 CPU、RAM、ROM、GPIO、定时器、ADC、PWM、串口(UART/I2C/SPI) 等外设集成在一颗芯片内
    • 成本低:由于 MCU 的所有组件都集成在同一芯片中,硬件设计成本较低。
    • 低功耗:适用于低功耗设备(如 IoT 设备、工业控制、汽车电子)。
    • 高实时性:一上电即可运行,无需操作系统,也可以跑 RTOS(如 FreeRTOS)。
    • 典型应用
  • 传感器数据采集(如 STM32 采集温湿度传感器)
  • 电机控制(如 STM32 驱动步进电机)
  • 显示控制(如 LCD、OLED、数码管控制)
  • 无线通信模块(如 ESP8266 进行 Wi-Fi 通信)
  • 例子

    • STM32F4(Cortex-M4)
    • AVR ATmega328(Arduino 用的芯片)
    • GD32F3(国产 MCU)

    2. MPU(微处理器)

    特点:

    • 高性能:MPU 适用于复杂计算,如 AI、图像处理、多任务操作
    • 需要外挂 RAM 和 ROM
  • RAM 作为运行时存储(DDR3/DDR4)
  • ROM(Flash/eMMC)存储操作系统和程序
  • 运行完整的操作系统

  • Linux、Android、Windows CE、FreeBSD 等
  • 适用于需要 UI、多任务、复杂运算的设备

  • 智能手机、嵌入式 Linux 设备、工控机、网络路由器
  • 典型应用

  • 图像处理(如 AI 摄像头)
  • 多媒体播放(如智能电视)
  • 网络通信设备(如 OpenWRT 路由器)
  • 例子

    • 树莓派(Raspberry Pi)
    • NXP i.MX 6/8(Cortex-A 系列)
    • Allwinner H3/H5(电视盒子芯片)
    • Rockchip RK3399(安卓平板/开发板)

    3. STM32(MCU) vs 树莓派(MPU)

    4. 为什么导弹、工业控制用 MCU?

    1. 高实时性:MCU 上电即运行,而 MPU 需要加载操作系统,延迟高
    2. 功耗低:MCU 可以低功耗运行,而 MPU 需要较大功耗运行。
    3. 稳定可靠:MCU 运行裸机或 RTOS,没有 OS 崩溃的风险

    总结:

    • MPU 适合需要操作系统、复杂运算(如 AI、Linux 设备)
    • MCU 适合实时控制、低功耗应用(如 STM32 控制电机、传感器)

    4.讲一下Linux中断分为上半部和下半部的原因?

    在 Linux 内核中,中断处理被分为 上半部(Top Half)下半部(Bottom Half)

    主要目的是提高系统响应速度,减少中断禁用时间,避免影响系统的实时性。

    1. 为什么要分为上半部和下半部?

    中断处理的挑战:

    1.中断发生时,CPU 需要立即响应

  • 硬件设备(如键盘、网卡、定时器等)触发中断时,CPU 需要尽快执行中断处理程序(ISR),否则可能会错失重要事件。
  • 2.中断处理会影响其他任务

  • 如果中断处理时间过长,会导致CPU 不能执行其他任务,影响系统性能。
  • 3.中断是优先级最高的任务

  • 中断处理程序不能被进程调度,一旦中断处理时间过长,会影响整个系统的调度。
  • 4.解决方案:

    • 上半部(Top Half)快速执行关键任务,完成最小化的硬件操作,然后尽快返回,释放 CPU。
    • 下半部(Bottom Half):在稍后的合适时间,延迟执行较慢的任务,降低系统负担。

    2. 上半部(Top Half)

    主要作用:

    • 处理紧急的硬件相关任务,确保系统快速响应中断
    • 代码通常执行极少的操作,然后立即退出。

    典型任务:

    • 读取中断状态(ISR 读取寄存器)
    • 清除中断标志,防止重复触发
    • 将数据存入缓冲区
    • 触发下半部处理

    上半部的限制:

    ✅ 不能使用 sleep()(不能阻塞)

    ✅ 不能访问 用户空间(只能访问内核空间)

    ✅ 不能执行 耗时操作(如磁盘 I/O、复杂计算)

    3. 下半部(Bottom Half)

    主要作用:

    • 执行耗时的任务,但不影响中断响应速度。
    • 避免在中断上下文中执行过长的操作,以提高系统性能。

    典型任务:

    • 数据处理(如网络包解析)
    • 唤醒等待的进程
    • 调用文件系统、磁盘 I/O
    • 复杂计算

    Linux 实现下半部的方法:

    1. 软中断(SoftIRQ)适合高吞吐量任务(如网络协议栈、定时器)
    2. 任务队列(Tasklet)适合较短的任务,可以在多个 CPU 上并行执行
    3. 工作队列(Workqueue)适合能睡眠的任务,在进程上下文中执行

    4. 例子:网络数据包处理

    假设网卡收到数据包,触发中断:

    上半部(ISR)

  • 读取网络芯片寄存器,获取数据包地址
  • 触发 SoftIRQ,让下半部执行
  • 尽快返回,不影响其他中断
  • 下半部(SoftIRQ / Workqueue)

  • 解析数据包
  • 将数据交给 TCP/IP 协议栈
  • 唤醒用户态进程(如 socket 读取数据)
  • 总结

    🚀 结论:分离上半部和下半部可以减少 CPU 负担,提高系统的实时性和响应速度。

    5.如果给线程访问加锁,是在驱动层实现还是应用层实现?

    回答:可以在驱动层实现,也可以在应用层实现,具体取决于需求和并发控制的粒度。

    • 驱动层加锁:适用于多个进程/线程访问同一个驱动资源(如设备寄存器、共享内存)。
    • 应用层加锁:适用于多个线程访问同一资源,但不涉及内核驱动(如数据库、全局变量)。

    1. 在驱动层实现加锁(

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

    作者简介:仅用几个月时间0基础天坑急转嵌入式开发,逆袭成功拿下华为、vivo、小米等15个offer,面试经验100+,收藏20+面经,分享求职历程与学习心得。 专栏内容:这是一份覆盖嵌入式求职过程中99%问题指南,详细讲解了嵌入式开发的学习路径、项目经验分享、简历优化技巧、面试心得及实习经验,从技术面,HR面,AI面,主管面,谈薪一站式服务,助你突破技术瓶颈、打破信息差,争取更多大厂offer。

    全部评论

    相关推荐

    联想数据开发工程师面经(2025届校招/实习)📌&nbsp;背景:985本硕,计算机相关专业,有大数据项目经历,面试岗位为数据开发工程师(Base北京/上海)。📝&nbsp;面试流程&nbsp;&amp;amp;amp;&nbsp;问题回顾1.&nbsp;笔试(线上编程+SQL)-&nbsp;题型:-&nbsp;算法题(********中等难度,考察数组、字符串、动态规划)-&nbsp;SQL题(多表关联、窗口函数、复杂查询优化)-&nbsp;大数据基础(Hadoop/Spark原理简答)2.&nbsp;技术一面(1小时)-&nbsp;数据结构与算法-&nbsp;手撕代码:合并K个有序链表(优先队列实现)-&nbsp;时间复杂度分析,如何优化?-&nbsp;大数据生态-&nbsp;Spark和Hadoop的区别?Spark为什么更快?-&nbsp;数据倾斜的解决方案?-&nbsp;SQL实战-&nbsp;写一个**连续登录用户统计**的SQL(使用窗口函数)-&nbsp;项目深挖-&nbsp;介绍一个大数据项目,你在其中负责什么?-&nbsp;如果数据量增加10倍,如何优化你的方案?3.&nbsp;技术二面(45分钟)-&nbsp;系统设计-&nbsp;设计一个实时数据仓库,如何保证低延迟和高可用?-&nbsp;Kafka和Flink在实时计算中的作用?-&nbsp;数据库-&nbsp;MySQL索引原理,B+树&nbsp;vs&nbsp;Hash索引-&nbsp;Hive内部表和外部表的区别?-&nbsp;场景题-&nbsp;如果某天发现报表数据异常,如何排查?4.&nbsp;HR面(30分钟)-&nbsp;职业规划、为什么选择联想?-&nbsp;对加班/出差的看法?-&nbsp;期望薪资?💡&nbsp;面试建议1.&nbsp;**重点复习**:SQL(窗口函数、优化)、Spark/Hadoop原理、常见大数据场景题。2.&nbsp;**项目复盘**:确保能清晰讲解技术选型、难点和优化思路。3.&nbsp;**算法刷题**:********热题100+剑指Offer,尤其是**链表、树、DP**。4.&nbsp;**反问环节**:可以问团队业务、技术栈、新人培养计划等。🌟&nbsp;联想数据团队体验-&nbsp;技术氛围浓厚,大牛导师带教,内部有完善的大数据平台。-&nbsp;业务覆盖智能供应链、用户行为分析、风控建模等,实战性强!📢&nbsp;投递Tips:联想对代码能力+大数据基础要求较高,建议尽早投递!📅&nbsp;【投递链接】春招:https://talent.lenovo.com.cn/position?projectType=1暑期实习:https://talent.lenovo.com.cn/position?projectType=2【内推码】2025XZLMCX【内推入口】在“联想校招官网”投递校招职位,创建简历时“从哪儿获知招聘信息”选择“联想员工推荐”并且输入推荐人ITcode:2025XZLMCX投递的同学评论区留下【姓名缩写+岗位】,方便及时跟进加入联想,与创新者同行,用科技改变世界!(欢迎留言交流,祝大家offer多多!🎯) #内推#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内推码&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#联想#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;26届&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#26届实习交流#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据人的面试交流地&nbsp;&nbsp;&nbsp;
    点赞 评论 收藏
    分享
    评论
    12
    40
    分享

    创作者周榜

    更多
    牛客网
    牛客企业服务