嵌入式软件面试问题汇总

Posted by R on 2024-03-18

C++方面

继承和多态

vector 和 list 的区别

常用的 STL 容器

面向对象的三大特性

重载和重写(覆盖)的区别

多继承的优先级

知道程序分成那几个段吗?

  • 代码段(Code Segment):也称为文本段(Text Segment),用于存放可执行指令的二进制代码。这部分代码通常是只读的,并且多个进程可以共享同一个代码段。
  • 数据段(Data Segment):也称为静态数据段或初始化数据段,用于存放全局变量和静态变量等在程序运行时被初始化的数据。该数据是可读写的。
  • BSS 段(Block Started by Symbol):用于存放未经初始化的全局变量和静态变量等,在程序加载时会自动清零。BSS 段节省了可执行文件大小,因为它不需要保存每个未初始化变量的初始值。
  • 堆(Heap):堆是动态分配内存的区域,用于存储通过函数如 malloc() 或 new 分配的内存块。堆中的内存需要手动释放,否则可能导致内存泄漏。
  • 栈(Stack):栈用于管理函数调用和局部变量等临时性数据。当函数被调用时,栈会分配一定空间给该函数使用,包括函数参数、返回地址、局部变量等。每个线程都有自己独立的栈空间。
  • 其他特殊段:还有其他一些特殊段,如动态链接库段、共享内存段等,用于特定的需求或操作系统机制。

堆和栈有什么区别?

  • 分配方式:堆是由程序员手动分配和释放的,而栈是自动分配和释放的。在堆中,我们可以使用像 malloc() 或 new 这样的函数来申请内存,并使用 free() 或 delete 来释放内存。而在栈中,变量的分配和释放是随着函数的调用和返回自动进行的。
  • 管理方式:堆由程序员显式地管理,需要手动进行内存的申请与释放;而栈由编译器自动管理,会自动跟踪函数调用、局部变量等信息,并在不需要时进行自动回收。
  • 空间大小:堆的空间通常比较大,可以容纳更多数据;而栈的空间相对较小,在一般情况下有限制。
  • 空间分配方式:堆采用动态分配内存,因此可灵活地为对象或数据分配任意大小的内存空间;而栈采用静态分配内存,在编译期确定每个变量所需空间大小。
  • 访问速度:从性能上来看,访问栈上的变量通常比访问堆上的变量更快速。这是因为栈上的数据是连续存储的,可以直接通过指针进行访问;而堆上的数据可能是离散的,需要通过间接寻址来获取。

嵌入式通信协议

你了解整个SPI的通信过程吗?SPI有几根线,分别是什么?你使用SPI的时候速率配置的是多少?

SPI通信需要四根线,分别是:

  • SCLK(Serial Clock):时钟线,由主设备生成,用于同步数据传输。
  • MOSI(Master Out Slave In):主设备输出从设备输入的数据线。
  • MISO(Master In Slave Out):主设备输入从设备输出的数据线。
  • SS(Slave Select):从设备选择线,由主设备控制,用于选中特定的从设备进行通信。

SPI速率配置取决于所使用的硬件和系统。典型的SPI速率可以在几百 kHz 到数十 MHz 之间。具体速率应根据硬件规格和应用需求进行配置。

网络通信框架原理与实现

7层网络模型以及对应举个协议的例子

TCP 和 UDP 的区别及其应用

三次握手的过程

socket 编程、通信过程、全部函数

linux操作系统知识

进程和线程的区别

互斥锁和自旋锁的应用及区别

常用的锁和同步机制

  • 互斥锁(Mutex):用于保护临界区资源,只允许一个进程或线程访问。
  • 信号量(Semaphore):用于控制同时访问共享资源的进程或线程数量。
  • 条件变量(Condition Variable):用于在满足特定条件时进行等待或唤醒其他进程或线程。
  • 屏障(Barrier):用于在所有参与者都达到某个点之前进行等待,然后同时继续执行。
  • 读写锁(Read-Write Lock):允许多个读操作并发进行,但只有一个写操作可以进行。

linux 是在用户态开发还是内核态开发?

Linux是一个开源的操作系统,它的核心部分是内核。内核是操作系统的核心组件,负责管理计算机硬件资源,并提供给用户态程序运行所需的服务和接口。因此,Linux操作系统包括用户态和内核态两个部分。用户态开发主要指的是在应用程序层面进行开发,而内核态开发则涉及到对Linux内核的修改、扩展或驱动程序的编写。

有使用过DMA吗?解释一下什么是DMA?

DMA是一种数据传输技术,用于在外设和内存之间直接进行数据传输,而无需CPU的干预。传统情况下,CPU负责控制数据传输过程,但这会占用CPU的时间和资源。而通过使用DMA,可以减轻CPU的负担,提高系统性能。

DMA通常由一个专门的控制器或硬件模块管理。它具有自己的地址寄存器、计数器和状态寄存器,并能够与主存储器和外设进行直接交互。DMA的操作流程如下:

  • 配置DMA控制器:设置源地址、目标地址、数据长度等参数。
  • 请求DMA传输:外设向DMA控制器发送请求信号,启动数据传输。
  • DMA传输:DMA控制器根据配置信息自动从源地址读取数据,并将其写入目标地址。
  • 完成中断:当DMA传输完成后,DMA控制器会触发一个中断信号给CPU,通知传输完成。

通过使用DMA,在某些场景下可以实现高速、高效的数据传输,并且减少了对CPU资源的依赖。

数据结构与算法

算法的时间复杂度和空间复杂度

时间复杂度推导方法:

  • 用常数1取代运行时间中的所有加法常数
  • 在修改后的函数中只保留最高阶项
  • 如果最高阶项存在且其系数不是1,则去除与这个项相乘的系数,得到的结果就是复杂度阶数。

    常见时间复杂度耗费时间顺序:

    常数阶 < 对数阶 < 线性阶 < nlogn阶 < 平方阶 < 立方阶 < 指数阶

    空间复杂度通过计算算法所需的存储空间实现,计算算法执行时所需的辅助空间。

线性表

线性表就是零个或者多个具有相同数据类型的数据元素的有限序列。

线性表顺序存储结构、链式存储结构

线性表顺序存储结构在插入和删除操作时需要移动大量元素,而单链表只需要赋值移动指针,对于插入和删除数据越频繁的操作,单链表的效率优势就越明显。如果需要频繁查找,很少进行插入和删除操作时,适宜采用顺序存储结构。另外,不知道元素个数有多少或变化较大时适宜采用单链表。

链式存储结构

单链表、静态链表、循环链表、双向链表。
静态链表通过数组代替指针来描述单链表,但没有解决连续存储分配带来的表长难以确定的问题,失去了链式存储结构随机存取的特性。
循环链表使得单链表首尾相连形成一个环,双向链表在单链表的每个节点中再设置了一个指向前驱节点的指针域。

栈与队列

栈是限定仅在表尾进行插入和删除操作的线性表。
队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

机考题库知识点

判断字符大小写的 isupper()islower(),以及大小写转换的 touppertolower。字符串处理的相关函数,cincin.getcin.getlinegetline 等的不同情况下用法,判断是否为某个字符的函数为 isalpha()

sstream是string类型转换的头文件,在由string转换为其他类型时很好用(进制转换)。

substr(位置、长度)能够截取 string 类型数据。

itoa(数、进制)十进制转任意进制函数。