C/C++面试面试真题加积累八股 第二期
这里我总结一下我的嵌入式的八股文积累,体量比较大,基本都是我秋招面试来遇到的面试真题,什么题都有
主要是偏C/C++嵌入式这一块,希望能帮到各位小伙伴和后来的人,希望大家送送花点点赞
这个系列大概分为好几期吧,尽快肝出来,大家只要面试前抽个一个小时每次背背,基本上八股部分不会有太大问题
我都放在我主页置顶希望小伙伴们捧捧场
千万别只点收藏哦
Linux的四种锁机制
互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,**线程会进入睡眠**,等待锁释放时被唤醒。
读写锁:rwlock,分为读锁和写锁。处于读操作时,可以允许多个线程同时获得读操作。但是同一时刻只能有一个线程可以获得写锁。其它获取写锁失败的线程都会进入睡眠状态,直到写锁释放时被唤醒。 注意:写锁会阻塞其它读写锁。当有一个线程获得写锁在写时,读锁也不能被其它线程获取;写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)。
适用于读取数据的频率远远大于写数据的频率的场合。
自旋锁:spinlock,在任何时刻同样只能有一个线程访问对象。但是当获取锁操作失败时,不会进入睡眠,而是会在原地自旋,直到锁被释放。这样节省了线程从睡眠状态到被唤醒期间的消耗,在加锁时间短暂的环境下会极大的提高效率。但如果加锁时间过长,则会非常浪费CPU资源。
RCU:即read-copy-update,在修改数据时,首先需要读取数据,然后生成一个副本,对副本进行修改。修改完成后,再将老数据update成新的数据。使用RCU时,读者几乎不需要同步开销,既不需要获得锁,也不使用原子指令,不会导致锁竞争,因此就不用考虑死锁问题了。而对于写者的同步开销较大,它需要复制被修改的数据,还必须使用锁机制同步并行其它写者的修改操作。在有大量读操作,少量写操作**的情况下效率非常高。
eg:
1.两个进程访问临界区资源,会不会出现都获得自旋锁的情况?
参考回答:
单核cpu,并且开了抢占可以造成这种情况。
2.请问就绪状态的进程在等待什么?
参考回答:
被调度使用cpu的运行权
3.怎么唤醒被阻塞的socket线程?
参考回答:
给阻塞时候缺少的资源。
4.如何设计server,使得能够接收多个客户端的请求
参考回答:
多线程,线程池,io复用。
5.死循环+来连接时新建线程的方法效率有点低,怎么改进?
参考回答:
提前创建好一个线程池,用生产者消费者模型,创建一个任务队列,队列作为临界资源,有了新连接,就挂在到任务队列上,队列为空所有线程睡眠。改进死循环:使用select epoll这样的技术。
6.请你说一说死锁产生的必要条件?
参考回答:
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
两个进程分别占据a、b资源,一个需要b资源释放,一个需要a资源释放,两个进程相互占据资源不放且不能被强行剥夺造成死锁。
用过哪些STM32芯片,他们的区别是什么?
1. STM32F103系列:这个系列是STM32F系列中最受欢迎的型号之一。它基于[ARM](https://so.csdn.net/so/search?q=ARM&spm=1001.2101.3001.7020) **Cortex-M3**内核,提供了不同的封装和内存选项,适用于各种应用。
2. STM32F407系列:这个系列基于**ARM Cortex-M4**内核,具有较高的性能和丰富的外设。它广泛应用于嵌入式系统、工业自动化、通信和消费电子等领域。
GD32F1 ARM Cortex-M3
GD32F4 ARM Cortex-M4
STM32F1和F4的区别?
内核不同:F1是Cortex-M3内核,不带FPU和DSP指令集,F4是Cortex-M4内核,不带FPU和DSP指令集
主频不同:F1主频72MHz,F4主频168MHz;
浮点运算:F1无浮点运算单位,F4有;
功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等;
F4的flash和RAM的范围更大(128k-2048k,64k-256k)
F1的flash和RAM的范围更大(16k-1024k,4k-80k)
STM32F4拥有多达192KB的片内SRAM
STM32F4更低的功耗
STM32的启动过程:
单片机上电后一直到准备好C语言运行环境并跳转到main函数执行总共经历了5个步骤:
1.内核初始化,上电取址;
cotexm3会去0地址取出栈指针,然后偏移四个字节取出跳转地址
内核复位和NVIC寄存器部分清零;
内核设置堆栈:内核从向量表0地址读出堆栈地址,并设置主堆栈指针;
2.PC指针指向中断向量表的复位中断向量执行复位中断函数;
3.在复位中断函数中调用 SystemInit 函数,进行初始化(初始化时钟,配置中断向量表等)
4.调用 __main (在**IAR**中是 __iar_program_start )函数完成全局/静态变量的初始化和重定位工作,初始化堆栈和库函数
5.跳转到main函数中执行
STM32外设:
ADC模数转换器
DMA转运寄存器
UART串口
I2C
SPI
中断和异常的区别:
中断和异常
相同点:都是CPU对系统发生的某个事情做出的一种反应。
区别:中断由外因引起,异常由CPU本身原因引起。
大小端判断和转换:
大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。
(这里结合项目,可以说在学校项目中,数据传输就是这样,数据接收的小端模式,数据解码先要将每位数据单独转换位十进制,在按位拼接转成有效数字
底层驱动了解吗?还是用STM32提供的库?
做实际项目开发基本上是走库开发,开发比较快,然后配置简单点
底层驱动我理解就是直接通过软件代码去开启时钟,配置外设寄存器,设置中断优先级。具体的配置需要看系统结构图,比如一个外设通过哪一个时钟线获取时钟,该时钟线是通过晶振几分频得到的,这个外设的时钟寄存器开关位,再看外设的寄存器配置,然后再设置中断优先级;这里可以类似理解位EB配置Mcal,也是先做mcu时钟配置,做时钟分频,然后配置Port然后配置Can、spi、以太网。
STM32底层接口的实现关注过吗?
外设寄存器的配置通常通过结构体来实现,结构体内部的各个元素会将设置值解码映射到对应的寄存器上来实现寄存器的配置要求,完成外设的驱动。
传感器的传输是否可靠?
一个是取决于通信协议本身,二是硬件设备通信的时间能否同步,传输数据是否丢帧
添加校验CRC校验,应答机制,这里在汽车MCU中有bootloader刷写固件程序实现升级,这里刷写文件会有一个checksum校验和,在实际进入刷写服务中通过校验checksum来实现扩展功能。
主要是偏C/C++嵌入式这一块,希望能帮到各位小伙伴和后来的人,希望大家送送花点点赞
这个系列大概分为好几期吧,尽快肝出来,大家只要面试前抽个一个小时每次背背,基本上八股部分不会有太大问题
我都放在我主页置顶希望小伙伴们捧捧场
千万别只点收藏哦
Linux的四种锁机制
互斥锁:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,**线程会进入睡眠**,等待锁释放时被唤醒。
读写锁:rwlock,分为读锁和写锁。处于读操作时,可以允许多个线程同时获得读操作。但是同一时刻只能有一个线程可以获得写锁。其它获取写锁失败的线程都会进入睡眠状态,直到写锁释放时被唤醒。 注意:写锁会阻塞其它读写锁。当有一个线程获得写锁在写时,读锁也不能被其它线程获取;写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)。
适用于读取数据的频率远远大于写数据的频率的场合。
自旋锁:spinlock,在任何时刻同样只能有一个线程访问对象。但是当获取锁操作失败时,不会进入睡眠,而是会在原地自旋,直到锁被释放。这样节省了线程从睡眠状态到被唤醒期间的消耗,在加锁时间短暂的环境下会极大的提高效率。但如果加锁时间过长,则会非常浪费CPU资源。
RCU:即read-copy-update,在修改数据时,首先需要读取数据,然后生成一个副本,对副本进行修改。修改完成后,再将老数据update成新的数据。使用RCU时,读者几乎不需要同步开销,既不需要获得锁,也不使用原子指令,不会导致锁竞争,因此就不用考虑死锁问题了。而对于写者的同步开销较大,它需要复制被修改的数据,还必须使用锁机制同步并行其它写者的修改操作。在有大量读操作,少量写操作**的情况下效率非常高。
eg:
1.两个进程访问临界区资源,会不会出现都获得自旋锁的情况?
参考回答:
单核cpu,并且开了抢占可以造成这种情况。
2.请问就绪状态的进程在等待什么?
参考回答:
被调度使用cpu的运行权
3.怎么唤醒被阻塞的socket线程?
参考回答:
给阻塞时候缺少的资源。
4.如何设计server,使得能够接收多个客户端的请求
参考回答:
多线程,线程池,io复用。
5.死循环+来连接时新建线程的方法效率有点低,怎么改进?
参考回答:
提前创建好一个线程池,用生产者消费者模型,创建一个任务队列,队列作为临界资源,有了新连接,就挂在到任务队列上,队列为空所有线程睡眠。改进死循环:使用select epoll这样的技术。
6.请你说一说死锁产生的必要条件?
参考回答:
互斥条件:一个资源每次只能被一个进程使用。
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
两个进程分别占据a、b资源,一个需要b资源释放,一个需要a资源释放,两个进程相互占据资源不放且不能被强行剥夺造成死锁。
用过哪些STM32芯片,他们的区别是什么?
1. STM32F103系列:这个系列是STM32F系列中最受欢迎的型号之一。它基于[ARM](https://so.csdn.net/so/search?q=ARM&spm=1001.2101.3001.7020) **Cortex-M3**内核,提供了不同的封装和内存选项,适用于各种应用。
2. STM32F407系列:这个系列基于**ARM Cortex-M4**内核,具有较高的性能和丰富的外设。它广泛应用于嵌入式系统、工业自动化、通信和消费电子等领域。
GD32F1 ARM Cortex-M3
GD32F4 ARM Cortex-M4
STM32F1和F4的区别?
内核不同:F1是Cortex-M3内核,不带FPU和DSP指令集,F4是Cortex-M4内核,不带FPU和DSP指令集
主频不同:F1主频72MHz,F4主频168MHz;
浮点运算:F1无浮点运算单位,F4有;
功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等;
F4的flash和RAM的范围更大(128k-2048k,64k-256k)
F1的flash和RAM的范围更大(16k-1024k,4k-80k)
STM32F4拥有多达192KB的片内SRAM
STM32F4更低的功耗
STM32的启动过程:
单片机上电后一直到准备好C语言运行环境并跳转到main函数执行总共经历了5个步骤:
1.内核初始化,上电取址;
cotexm3会去0地址取出栈指针,然后偏移四个字节取出跳转地址
内核复位和NVIC寄存器部分清零;
内核设置堆栈:内核从向量表0地址读出堆栈地址,并设置主堆栈指针;
2.PC指针指向中断向量表的复位中断向量执行复位中断函数;
3.在复位中断函数中调用 SystemInit 函数,进行初始化(初始化时钟,配置中断向量表等)
4.调用 __main (在**IAR**中是 __iar_program_start )函数完成全局/静态变量的初始化和重定位工作,初始化堆栈和库函数
5.跳转到main函数中执行
STM32外设:
ADC模数转换器
DMA转运寄存器
UART串口
I2C
SPI
中断和异常的区别:
中断和异常
相同点:都是CPU对系统发生的某个事情做出的一种反应。
区别:中断由外因引起,异常由CPU本身原因引起。
大小端判断和转换:
大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
小端模式 :强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
大端模式 :符号位的判定固定为第一个字节,容易判断正负。
(这里结合项目,可以说在学校项目中,数据传输就是这样,数据接收的小端模式,数据解码先要将每位数据单独转换位十进制,在按位拼接转成有效数字
底层驱动了解吗?还是用STM32提供的库?
做实际项目开发基本上是走库开发,开发比较快,然后配置简单点
底层驱动我理解就是直接通过软件代码去开启时钟,配置外设寄存器,设置中断优先级。具体的配置需要看系统结构图,比如一个外设通过哪一个时钟线获取时钟,该时钟线是通过晶振几分频得到的,这个外设的时钟寄存器开关位,再看外设的寄存器配置,然后再设置中断优先级;这里可以类似理解位EB配置Mcal,也是先做mcu时钟配置,做时钟分频,然后配置Port然后配置Can、spi、以太网。
STM32底层接口的实现关注过吗?
外设寄存器的配置通常通过结构体来实现,结构体内部的各个元素会将设置值解码映射到对应的寄存器上来实现寄存器的配置要求,完成外设的驱动。
传感器的传输是否可靠?
一个是取决于通信协议本身,二是硬件设备通信的时间能否同步,传输数据是否丢帧
添加校验CRC校验,应答机制,这里在汽车MCU中有bootloader刷写固件程序实现升级,这里刷写文件会有一个checksum校验和,在实际进入刷写服务中通过校验checksum来实现扩展功能。
全部评论
相关推荐