题目答案分离,方便自查自测
快速跳转:
- 面试笔试问题
- ==1. 关键字static有什么用途?(请至少说明两种)==
- ==2. 嵌入式系统中经常要用到无限循环,如何用C编写死循环?==
- ==3. 程序的局部变量存在于哪里,全局变量存在于哪里,动态申请数据存在于哪里?==
- ==4. 什么是平衡二叉树?==
- ==5. 解释一下进程、线程、协程的概念。==
- ==6. 解释一下进程和线程的区别。==
- ==7. 解释一下协程和线程的区别。==
- ==8. 何时使用多进程,何时使用多线程?==
- ==9. 堆栈溢出一般是由什么原因导致的?==
- ==10. 什么函数不能声明为虚函数?==
- ==11. Internet采用哪种网络协议?该协议的主要层次结构?==
- ==12. 局部变量能否和全局变量重名?==
- ==13. 如何引用一个已经定义过的全局变量?==
- ==14. 关键字volatile有什么含意?并给出三个不同的例子。==
- ==15. STM32的主要组成部分是什么?==
- ==16. 描述STM32中的中断向量表和中断处理过程。==
- ==17. C语言中头文件中的 ifndef/define/endif 干什么用?==
- ==18. 解释一下TCP、UDP的区别。==
- ==19. STM32的时钟系是如何工作的?==
- ==20. 什么是死锁?产生死锁的原因是什么?==
- ==21. ADC的工作模式共有几种?分别是什么?==
- ==22. DMA的工作方式共有几种,它的作用是什么?==
- ==23. DMA和中断的区别是什么?==
- 🚀 获取工程代码及更多详细资料可点击链接进群领取,谢谢支持!👇
面试笔试问题
- 关键字static有什么用途?(请至少说明两种)
- 嵌入式系统中经常要用到无限循环,如何用C编写死循环?
- 程序的局部变量存在于哪里,全局变量存在于哪里,动态申请数据存在于哪里?
- 什么是平衡二叉树?
- 解释一下进程、线程、协程的概念。
- 解释一下进程和线程的区别。
- 解释一下协程和线程的区别。
- 何时使用多进程,何时使用多线程?
- 堆栈溢出一般是由什么原因导致的?
- 什么函数不能声明为虚函数?
- Internet采用哪种网络协议?该协议的主要层次结构?
- 局部变量能否和全局变量重名?
- 如何引用一个已经定义过的全局变量?
- 关键字volatile有什么含意?并给出三个不同的例子。
- STM32的主要组成部分是什么?
- 描述STM32中的中断向量表和中断处理过程。
- C语言中头文件中的 ifndef/define/endif 干什么用?
- 解释一下TCP、UDP的区别。
- STM32的时钟系是如何工作的?
- 什么是死锁?产生死锁的原因是什么?
- ADC的工作模式共有几种?分别是什么?
- DMA的工作方式共有几种,它的作用是什么?
- DMA和中断的区别是什么?
1. 关键字static有什么用途?(请至少说明两种)
答:
在 C 语言中,static 是一种类型声明符,主要有三个用途:声明静态局部变量、声明静态外部全局变量和声明静态外部函数。下面是对这三个用途的详细解释。
(1)声明静态局部变量
静态局部变量是使用 static 声明的局部变量,其存储空间分配在静态存储区,作用域仅仅限于声明该变量的函数内部。在程序整个运行期间都不释放,生存期贯穿于程序运行的整个过程。与 auto 类型变量相比,static 变量的存储空间分配在静态存储区,而 auto 变量的存储空间分配在栈上。
在赋初值时,static 变量是在编译时赋初值,即只赋初值一次;而 auto 变量赋初值是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。如果在定义局部变量时不赋初值的话,static 变量将自动赋初值 0(对数值型变量)或空字符(对字符变量),而 auto 变量的值是一个不确定的值。
(2)声明静态外部全局变量
在 C 语言中,static 还用来声明静态外部全局变量,那么这个全局变量的作用域就被限制在本文件内部。外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字 extern 对该变量作“外部变量声明”。表示该变量是一个已经定义的外部变量。如果我们声明的全局变量不想被其他文件访问和使用,那就是在声明的时候前面加上关键字 static。
(3)声明静态外部函数
在 C 语言中,我们的函数默认都是全局的,也就是说你可以调用其他文件中的函数。在使用的时候,我们象前面一样在头文件中加上 extern 就可以了。但是有时候我们写的函数并不想让别的文件访问和调用,那么我们在声明函数的时候前面加上 static 就可以了。使用内部函数的好处有二:一是可以让某些内部函数不为人所能使用,而仅仅让调用者使用他能使用的东西,有利于保护代码;二是不用担心自己定义的函数是否会与其它文件中的函数同名。
2. 嵌入式系统中经常要用到无限循环,如何用C编写死循环?
答:while(1){}或者for( ; ; )。
3. 程序的局部变量存在于哪里,全局变量存在于哪里,动态申请数据存在于哪里?
答:程序的局部变量存在于栈区;全局变量存在于静态区;动态申请数据存在于堆区。
4. 什么是平衡二叉树?
答:左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1
5. 解释一下进程、线程、协程的概念。
答:
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
协程:是一种比线程更加轻量级的存在。一个线程也可以拥有多个协程。其执行过程更类似于子例程,或者说不带返回值的函数调用。
6. 解释一下进程和线程的区别。
答:
(1)地址空间:线程共享本进程的地址空间,而进程之间是独立的地址空间。
(2)资源:线程共享本进程的资源如内存、I/O、cpu等,不利于资源的管理和保护,而进程之间的资源是独立的,能很好的进行资源管理和保护。
(3)健壮性:多进程要比多线程健壮,一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。
(4)执行过程:每个独立的进程有一个程序运行的入口、顺序执行序列和程序入口,执行开销大。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,执行开销小。
(5)可并发性:两者均可并发执行。
(6)切换时:进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
(7)其他:线程是处理器调度的基本单位,但是进程不是。
7. 解释一下协程和线程的区别。
答:
协程避免了无意义的调度,由此可以提高性能,但程序员必须自己承担调度的责任。同时,协程也失去了标准线程使用多CPU的能力。
线程相对独立有自己的上下文切换受系统控制;协程相对独立有自己的上下文切换由自己控制,由当前协程切换到其他协程由当前协程来控制。
8. 何时使用多进程,何时使用多线程?
对资源的管理和保护要求高,不限制开销和效率时,使用多进程。要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。
9. 堆栈溢出一般是由什么原因导致的?
答:
没有回收垃圾资源
10. 什么函数不能声明为虚函数?
答:
构造函数,因为它是在对象产生之头被调用的,而虚函数是对象产生之后才起作用的机制,所以声明虚构造函数无意义。
11. Internet采用哪种网络协议?该协议的主要层次结构?
答:
tcp/ip 应用层/传输层/网络层/链路层。
12. 局部变量能否和全局变量重名?
答:
能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
13. 如何引用一个已经定义过的全局变量?
答:
extern关键字
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
14. 关键字volatile有什么含意?并给出三个不同的例子。
答:
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
- 并行设备的硬件寄存器(如:状态寄存器)。
- 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)。
- 多线程应用中被几个任务共享的变量。
15. STM32的主要组成部分是什么?
答:
STM32微控制器的主要组成部分围绕着其核心——ARM Cortex-M系列处理器,并包括一系列的片上外设、存储器、总线架构以及其他辅助电路。以下是STM32的一些关键组成部分:
-
ARM Cortex-M内核:
- STM32使用ARM Cortex-M系列内核,如Cortex-M0、M0+、M3、M4、M7等,这些内核提供了高性能和低功耗的平衡。
-
存储器:
- Flash Memory:用于存放程序代码和常量数据。
- SRAM:作为工作内存,用于存放变量和运行时数据。
- STM32还可能包含EEPROM或内置的非易失性存储器。
-
总线架构:
- AHB(Advanced High-performance Bus):高速总线,连接到CPU、DMA、总线矩阵和一些高速外设。
- APB(Advanced Peripheral Bus):较低速的总线,用于连接低速外设和一些时钟频率较低的外设。
- System Bus:用于连接CPU和各种内部组件。
- ICode/DCode Buses:用于指令和数据的分离传输。
-
外设:
- GPIO(General-Purpose Input/Output):通用输入输出端口。
- 定时器:用于产生精确的延时和计数。
- ADC(Analog-to-Digital Converter):用于将模拟信号转换为数字信号。
- DAC(Digital-to-Analog Converter):用于将数字信号转换为模拟信号。
- USART/SPI/I²C:用于串行通信。
- DMA(Direct Memory Access):用于在没有CPU干预的情况下在内存和外设之间传输数据。
- CAN(Controller Area Network):用于汽车和工业自动化网络通信。
- USB(Universal Serial Bus):用于高速数据传输和设备连接。
- Ethernet:用于网络通信。
- CRC(Cyclic Redundancy Check):用于数据完整性校验。
-
电源管理与时钟控制:
- 电源管理单元:用于控制不同电压域的电源供给。
- 时钟管理器:用于生成和控制各种时钟信号,如HSI(内部高速)、HSE(外部高速)、LSI(内部低速)、LSE(外部低速)等。
-
安全和加密:
- 加密引擎:用于数据加密和解密。
- 真随机数生成器(TRNG):用于生成随机数。
-
调试和跟踪:
- JTAG/SWD(Serial Wire Debug):用于调试和编程。
- ETM(Embedded Trace Macrocell):用于跟踪CPU的执行路径。
-
高级特性:
- 在某些STM32系列中,可能还会包括FPU(浮点运算单元)、DSP(数字信号处理器)指令集、MPU(Memory Protection Unit)等高级特性。
这些组成部分共同构成了STM32微控制器的强大功能和灵活性,使其适合广泛的应用领域,从简单的数据采集和控制,到复杂的通信和多媒体处理。
16. 描述STM32中的中断向量表和中断处理过程。
答:
STM32的中断向量表位于内存的最开始处,即0x08000000地址开始的位置。这个位置通常是闪存的起始地址,但由于STM32的启动配置,中断向量表通常被映射到SRAM区域,以加快中断响应速度。
中断向量表包含了所有的中断向量,每个向量占用4个字节,指向中断服务子程序的起始地址。除了中断向量之外,STM32的IVT还包括复位向量、未定义指令异常、软件中断、预取异常等异常处理向量。
中断处理过程通常遵循以下步骤:
(1)中断请求:当一个外部事件触发中断请求时,相应的中断线被激活。
中断挂起和优先级检查:中断挂起机制确保高优先级的中断可以打断低优先级的中断。中断优先级由NVIC(Nested Vectored Interrupt Controller)管理,它可以配置中断的抢占优先级和响应优先级。
(2)中断向量查找:一旦确定中断要被处理,STM32会查找中断向量表中对应的中断向量地址。
(3)保存上下文:在跳转到中断服务程序之前,STM32会自动保存当前处理器的状态,包括PC(程序计数器)、LR(链接寄存器)和其他寄存器的内容。
(4)执行中断服务程序:处理器跳转到中断向量指向的地址,开始执行中断服务程序。中断服务程序负责处理中断事件,比如读取传感器数据、更新状态机、驱动硬件等。
(5)恢复上下文:在中断服务程序执行完毕后,处理器恢复被保存的上下文,返回到中断前的指令继续执行。
(6)清除中断标志:通常,中断服务程序会清除相应的中断标志位,表示该中断已经被处理。
17. C语言中头文件中的 ifndef/define/endif 干什么用?
答:
在C语言中,#ifndef, #define, 和 #endif 是预处理指令,它们通常一起使用来防止头文件的内容被多次包含。这种技术被称为“包含保护”或“头文件保护”。
当一个头文件被多次包含时,如果没有适当的保护,可能会导致以下问题:
符号重复定义:如果头文件中有定义,比如全局变量或函数体的定义,多次包含会导致链接错误。
符号重复声明:虽然多次声明相同类型的变量或函数不会直接导致编译错误(如果遵循C99标准),但它会使得代码冗余且不易维护。
18. 解释一下TCP、UDP的区别。
答:
TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的网络传输协议,它们有以下区别:
(1)连接:TCP是面向连接的协议,而UDP是无连接的协议。在发送数据前,TCP通过三次握手建立连接,而UDP不需要建立连接。
(2)可靠性:TCP提供可靠的数据传输,保证了数据的可靠性和完整性。TCP通过序号、确认应答和超时重传等机制来实现可靠性。而UDP不提供可靠性保证,数据可能丢失、损坏或重复。
(3)传输速度:UDP比TCP快,因为它不需要建立连接和提供可靠性保障。在一些场景中,如视频、音频等实时应用,UDP更适合。
(4)数据量限制:UDP的数据包大小通常受限于底层网络协议(如以太网),一般不超过1472字节。而TCP的数据包大小则取决于操作系统和底层网络协议。
(5)应用场景:TCP适用于可靠性要求高的应用场景,如网页浏览、电子邮件等。UDP适用于对速度和实时性要求高的应用场景,如在线游戏、视频流等。
(5)头部开销:TCP的首部较大,为20个字节,而UDP的首部较小,为4个字节。
总的来说,TCP提供了可靠的连接和数据传输,但相对较慢;而UDP快,但数据传输不可靠。在选择传输协议时,需要根据具体的应用场景来权衡。
19. STM32的时钟系是如何工作的?
答:
STM32的时钟系统相当复杂,它由多个时钟源和时钟树组成,旨在提供高度灵活和可配置的时钟管理。下面是一个概括性的描述,解释STM32时钟系统的基本工作原理:
-
时钟源:
- HSI (High Speed Internal Oscillator): 内部高速RC振荡器,典型频率为16 MHz。
- HSE (High Speed External Oscillator): 外部高速晶体振荡器,频率范围通常在4 MHz到26 MHz。
- LSI (Low Speed Internal Oscillator): 内部低速RC振荡器,频率大约为32 kHz。
- LSE (Low Speed External Oscillator): 外部低速晶体振荡器,通常为32.768 kHz。
-
PLL (Phase Locked Loop):
- PLL可以使用HSI、HSE或外部时钟信号作为输入,通过倍频或分频产生更高的时钟频率,用于系统时钟(SYSCLK)。
-
系统时钟 (SYSCLK):
- 系统时钟可以是HSI、HSE、PLL的输出,或者是LSI经过预分频器(PLL)之后的输出。
- SYSCLK频率决定了STM32的核心运行速度,以及所有依赖于系统时钟的外设的频率。
-
APB (Advanced Peripheral Bus):
- APB1和APB2总线分别连接低速和高速外设,它们的频率由SYSCLK通过预分频器决定。
- APB1的频率通常低于APB2的频率。
-
AHB (Advanced High-performance Bus):
- AHB总线连接高速外设和内存,其频率等于SYSCLK。
-
RTC (Real-Time Clock):
- RTC有自己的独立时钟源,通常使用LSE或LSI,即使在其他时钟关闭时也能保持运行。
-
控制和配置:
- 时钟的配置和控制主要通过RCC(Reset and Clock Control)寄存器完成,包括时钟的启用和禁用、分频和倍频、选择时钟源等。
-
时钟树:
- 时钟树是一种图形化表示,展示了时钟信号如何从各个时钟源开始,通过分频、倍频和选择,最终分配给不同的总线和外设的过程。
在使用STM32时,开发者通常需要根据应用需求选择合适的时钟源和配置,以达到最佳的性能和功耗平衡。例如,在需要高速运行的应用中,可能会选择HSE作为PLL的输入,然后将PLL的输出作为系统时钟;而在低功耗应用中,则可能选择HSI或LSI作为系统时钟源。
20. 什么是死锁?产生死锁的原因是什么?
死锁(Deadlock)是指两个或更多的进程或线程永久地阻塞,每个进程或线程都在等待另一个进程或线程释放资源,从而形成一个循环依赖,没有任何进程能够继续执行的情况。死锁是一种僵局状态,除非有外部干预,否则参与死锁的进程将无法继续执行或终止。
产生死锁的本质原因为:
(1)系统资源有限。
(2)进程推进顺序不合理。
21. ADC的工作模式共有几种?分别是什么?
答:
共有四种:单次 ;连续;扫描;不连续采样
22. DMA的工作方式共有几种,它的作用是什么?
答:
DMA的工作方式共有两种:正常和循环模式
DMA的作用是用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输可以在无需任何CPU操作的情况下通过DMA快速移动数据这样节省的CPU资源可供其它操作使用。
23. DMA和中断的区别是什么?
答:
①DMA是硬件方式,中断是软件方式
②DMA不需要CPU参与,中断是需要CPU参与
③DMA只能搬运数据,中断可以处理一些其他事情
④DMA的优先级是要高于中断的,中断的优先级是要高于main的