嵌入式面经第三弹:腾讯、科大讯飞、阳光电源、蔚来
本篇涉及的所有问题概要:大家可以试试在看参考答案前,提前尝试解答,以便明确自身知识点的不足部分!
想进大厂做嵌入式?想一次性拿下华为、博世、理想、韶音等20+公司的面试?这份超全嵌入式面经就是你的制胜法宝!
提前模拟来练习这些问题,面试不再慌!
剩下内容都在👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
嵌入式面经第三弹:(嵌入式面经)第11章 20+公司面经杂谈(三):腾讯、科大讯飞、阳光电源、蔚来
1.用过交叉编译器吗,简单介绍一下?
2.说一下memcpy()和strcpy()的区别?
3.你写代码时用过多条件if else if else吗,如何进行优化呢?
4.在STM32里,串口接收哪几种模式,你比较常用什么模式,为什么呢?它是接受断如何判断数据接受结束的?
5.IIC接口地址位有几位,只有7位地址模式吗,理论上能接多少外设,实际上能接多少,是什么因素影响的?
6.说一说FreeRTOS如何去实现任务调度的?
7.如果实际中,你碰到数据传入速度大于数据处理速度,你会怎么解决?
8.在你的项目中,是如何考虑控制的实时性?
9.看你有涉及Linux跟FreeRTOS,说一说这两个操作系统的区别吧?
10. 专栏订阅奖励(支持模仿)——个人创新点问答:说一说你是如何在应对小数据量存储下,增加Flash单扇区存储的使用寿命的?
---------------------------------------------------------------------------------------------------
1.用过交叉编译器吗,简单介绍一下?
1. 交叉编译器(Cross Compiler)介绍
交叉编译器 是指在 一种 CPU 架构(如 x86)上编译可在 另一种 CPU 架构(如 ARM、RISC-V)上运行的代码的编译器。它主要用于 嵌入式系统、操作系统移植 和 跨平台开发。
2. 交叉编译的应用场景
✅ 嵌入式开发(如 STM32、ESP32、ARM Linux)
✅ Linux 内核编译(使用 arm-linux-gcc
交叉编译 ARM 设备的 Linux 内核)
✅ Android 开发(Android NDK 使用交叉编译器生成 ARM 兼容的应用)
✅ 操作系统移植(移植 FreeRTOS、U-Boot 等)
3. 交叉编译器的常见工具链
4. 如何使用交叉编译器
(1)使用交叉编译器编译 C 代码
使用 arm-none-eabi-gcc
编译:
arm-none-eabi-gcc -o hello.elf hello.c
编译 ARM Linux 可执行文件:
arm-linux-gnueabihf-gcc -o hello_arm hello.c
然后可以拷贝到 ARM 设备(如树莓派)运行:
scp hello_arm user@raspberrypi:/home/user/
ssh user@raspberrypi ./hello_arm
(2)编译 FreeRTOS 代码
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -o main.elf main.c
-mcpu=cortex-m4
指定 Cortex-M4 处理器-mthumb
使能 Thumb 指令集5. 交叉编译 vs 本地编译
6. 交叉编译的挑战
❌ 库兼容性问题(如 glibc
版本不同)
❌ 调试难度高(需借助 GDB 远程调试)
❌ 架构指令集差异(如 ARM
vs RISC-V
)
解决方案:
qemu
模拟目标环境总结
🚀 交叉编译器 在 嵌入式开发 和 多平台支持 方面至关重要。
常见工具链如 arm-none-eabi-gcc
、arm-linux-gnueabihf-gcc
可用于不同场景。
通过合理的工具配置,我们可以在 PC 端开发代码,并将其部署到 ARM、RISC-V 设备,极大提高开发效率!
2.说一下memcpy()和strcpy()的区别?
memcpy
和 strcpy
都是用于内存操作的 C 语言库函数,但它们的功能、用法和适用场景有明显的不同。
1. memcpy 与 strcpy 的主要区别
2. memcpy 详解
函数原型
void *memcpy(void *dest, const void *src, size_t n);
dest
:目标地址src
:源地址n
:拷贝的字节数\0
结束符适用场景
✅ 适用于 二进制数据、结构体、数组、内存块 拷贝,例如:
int
、double
、char
数组)示例
⚠️ memcpy
可能会导致溢出,如果 n
超过目标缓冲区大小,就会引发 缓冲区溢出,影响程序稳定性。
3. strcpy 详解
函数原型
char *strcpy(char *dest, const char *src);
dest
:目标字符串src
:源字符串(必须以\0
结尾)- 注意:会自动拷贝
\0
结束符
适用场景
✅ 适用于 字符串(char
数组)拷贝,例如:
char
数组示例
⚠️ strcpy
可能导致缓冲区溢出,如果 dest
的大小 小于 src
,则会发生 越界写入,可能导致程序崩溃。
4. 关键区别示例
memcpy
可拷贝二进制数据,而 strcpy
仅适用于字符串
memcpy(dest1, src, 5);
- 仅仅复制
"Hello"
的 5 个字节,但不会自动添加\0
结尾。 dest1
之前的内容是"XXXXXXXXXX"
,所以输出可能会出现乱码,或者包含之前的内容。- 如果目标数组中原本有数据,则
\0
终止符不会自动加上,可能导致不受控的输出!
strcpy(dest2, src);
strcpy
会自动拷贝\0
结束符,因此dest2
仅包含"Hello"
并正确终止。- 不会残留
XXXXXX
,保证输出是正确的字符串!
memcpy(dest3, src, 6);
- 这里
memcpy
手动指定 6 个字节拷贝,包含了\0
终止符,因此dest3
也是正确的字符串。 - 但如果
src
不是字符串,而是结构体或二进制数据,memcpy
仍然不会做\0
处理。
5. 区别总结
6. 何时使用?
✅ 使用 memcpy
- 复制 非字符串(二进制数据、结构体、数组)
- 需要拷贝 精确的字节数
- 数据大小已知,且不会重叠
✅ 使用 strcpy
- 仅 复制字符串
- 保证目标有足够空间
- 需要 自动拷贝
\0
结尾
🚨 避免常见错误
memcpy
不会 添加\0
,要手动处理strcpy
不检查 目标空间,可能 越界- 推荐
strncpy
限制strcpy
的拷贝大小
结论
memcpy
更通用,适用于结构体、二进制数据strcpy
适用于字符串,但要注意越界- 优先使用
strncpy
或memmove
以提高安全性
3.你写代码时用过多条件if else if else吗,如何进行优化呢?
当 if
语句包含多个条件时,优化代码不仅能提升可读性,还能提高执行效率。
1. 提前 return,让主干代码更清晰
适用于: 代码逻辑有多个分支,但主要执行路径明确的情况。
示例:未优化代码
优化后(提前 return
):
2. 使用 && 和 || 组合条件
适用于: 条件逻辑较多但可以合并的情况。
示例:未优化代码
优化后(合并条件):
- 逻辑更直观,减少
if
嵌套。
3. 使用 switch 代替多个 if-else
适用于: 多个 if-else
语句用于匹配固定值的情况。
示例:未优化代码
优化后(switch
替换 if-else
):
switch
比多个 if-else
更高效(编译器可能优化为跳转表)。4. 使用 三目运算符 使代码更简洁
适用于: 简单 if-else
赋值逻辑。
示例:未优化代码
优化后(? :
三目运算符):
- 代码简洁,可读性更强。
5. 逻辑表驱动法
适用于: 复杂的 if-else
判断逻辑,可用数据结构存储匹配规则。
示例:
- 便于扩展,可减少
if-else
的复杂性。