如涉及公司条例,可联系我删除,答案是自己整理的,答案不一定正确,欢迎指正
- 自我介绍(包括项目介绍)
- 怎么判断栈溢出
答:栈溢出发生的时候,栈顶指针(SP - Stack Pointer)一定会超出栈的范围,所以也可以在发生线程切换的时候,检测SP指向的地址是否超过了栈的内存限定。
3.什么是函数指针?
答:是一个函数指针变量,指向函数的地址
4.什么是指针函数?
答:是一个函数,指针函数返回类型是某一类型的指针
5.你知道各个线程间任务是如何通信的吗?你从系统层面分析一下?
答:线程通信主要可以分为三种方式,分别为共享内存、消息传递和管道流。
共享内存:通过volatile关键字实现线程间的变量共享
消息传递:wait/notify等待通知方式、join方式
管道流:管道输入/输出流的形式
6.说一下spi和 i2c和 UART的 各自的工作方式优缺点
答:
7.MCU能不能运行Linux
答:正常是不可以的,除非自己重写了Linux内核且搭配足够大的内存芯片,从理论上来说是可以省掉MMU的。但是MMU诞生的意义就是为了解决操作系统越来越复杂的内存管理。
8.stm32启动过程
答:①上电后硬件设置堆栈指针SP、程序计数器PC
②设置系统时钟
③软件设置堆栈指针SP
④加载.data、.bss,并初始化栈区
⑤跳转到C文件的main函数
9.进程和线程的基本区别
答:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位,一个进程可以有多个线程,且线程间共享地址空间,进程间一般不共享
10.C 为什么有指针还要引用
答:C 从 C 继承了指针,所以不能删除它们,否则会导致严重的兼容性问题。引用在很多方面都很有用,但在 c 中引入它们的直接原因是为了支持运算符重载。
11.介绍一下你对ROS操作系统的理解(项目)
机器人操作系统(ROS)是一套用于构建机器人应用程序的软件库和工具。实际上是运行在Ubuntu上的亚系统,提供类似操作系统所提供的功能
包含:
1–硬件抽象描述
2–底层驱动程序管理
3–公用功能的执行
4–程序间的消息传递
5–程序发行包管理
6–它也提供一些工具程序和库用于获取,建立,编写和运行多机整合的程序
12.ROS和其他操作系统的区别
答:以Linux为例,ros系统和linux的区别:1、Linux不仅系统性能稳定,而且是开源软件,Linux具有开放源码、没有版权、技术社区用户多等特点;2、ROS是用于编写机器人软件程序的一种具有高度灵活性的软件架构。
13.中断是如何产生的,具体的工作原理知不知道
答:
外中断:异步中断是由cpu的外设产生的电信号引起的中断,其发生的时间点不可预期。发生后会保存现场然后先执行中断程序,执行完毕后恢复现场继续执行。
14.MMU是什么东西?MMU是如何实现虚拟内存和实际物理内存的切换的
答:内存管理单元。MMU的主要作用:虚拟地址到物理地址的转换。具体的过于复杂。
15.ARM处理器的核心数,工作频率,位数等
答:
16.I2C的读写数据的步骤。
答:
17.static的作用,修饰局部变量时为什么函数调用不会改变值,问了static实现原理
答:用static修饰局部变量:使其变为静态存储方式(静态数据区),那么这个局部变量在函数执行完成之后不会被释放,而是继续保留在内存中。
函数中的静态变量:当变量声明为static时,空间将在程序的生命周期内分配,其被存放在在全局数据区。即使多次调用该函数,静态变量的空间也只分配一次,前一次调用中的变量值通过下一次函数调用传递。
18.C 多态
答:C 多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。重写的话可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数的才能算作是体现了C 多态性。
虚函数和纯虚函数:定义一个函数为虚函数,不代表函数为不被实现的函数。
定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
定义一个函数为纯虚函数,才代表函数没有被实现。
定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。
虚函数表存放在全局数据区
19.怎么访问类中私有变量,友元是单向的还是双向的?友元可以继承吗
答:使用友元函数,友元关系不满足对称性,不能
20.时间片轮转机制和时间设置, 还问了SysTick
答:(1)在某个进程的运行时间达到系统所分配的最大时间时,操作系统会将剥夺其cpu的执行权,分配给其他进程去执行;
(2)进程在规定的最大运行时间段中运行过程中,发生阻塞或异常结束,cpu马上就会切换到其他进程去执行;
(1)时间片设置过短:由于设置过短,分配到每个进程的时间也会很短,因此会在多个进程中进行频繁的切换;降低cpu的执行效率。这种切换称为进程切,又叫上下文切换,一次切换需耗时5ms;
(2)时间片设置过长:由于设置过长,会导致短的交互请求响应很慢。
总结:一般来说时间片的长度不宜过长或过短,一般我们建议设置在100ms比较合适。
21.说一下Linux设备驱动框架的编写吧
答:设备初始化/释放、通过文件系统从应用程序读取数据,把数据通过文件系统回送给应用程序(文件系统层<->设备驱动层)、
把数据从内核传送到硬件,从硬件读取数据到内核(设备驱动层<->硬件层)
22.上操作系统相较于裸机的区别
答:裸机运行的程序代码,一般由一个main函数中的while死循环和各种中断服务程序组成,平时CPU执行while循环中的代码,出现其他事件时,跳转到中断服务程序进行处理,没有多任务、线程的概念。
而引入操作系统后,程序执行时可以把一个应用程序分割为多个任务,每个任务完成一部分工作,并且每个任务都可以写成死循环。操作系统根据任务的优先级,通过调度器使CPU分时执行各个任务,保证每个任务都能够得到运行。若调度方法优良,则可使个任务看起来是并行执行的,减少了CPU的空闲时间,提高了CPU的利用率。由操作系统的任务管理衍生出相应的CPU管理、内存管理,它们分别负责分配任务对CPU的占有权和管理任务所占有的内存空间。在linux操作系统中,还具有文件管理、I/O设备管理的功能。
23.操作系统中,怎么去评估你的任务的好坏
答:CPU空闲时间短、且不会超出预设时间
24.说一下死锁是怎么产生的
答:因竞争资源发生死锁 现象:系统中供多个进程共享的资源的数目不足以满足全部进程的需要时,就会引起对诸资源的竞争而发生死锁现象。或者是进程的顺序设置不合理。
发生死锁必需以下四个条件同时满足
互斥,共享资源 X 和 Y 只能被一个线程占用;
占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X;
不可抢占,其他线程不能强行抢占线程 T1 占有的资源;
循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待。
25.追问怎么解决死锁的问题
答:破坏第二个条件,占有且等待,那么我们可以一次性去申请所有资源,就不会存在等待的问题了。
破坏不可抢占,可以让占用部分资源的线程进一步申请资源,如果申请不到,可以主动释放其他线程占用的资源,这样就可以把不可抢占的条件破坏掉。
破坏循环等待,可以按照顺序来进行资源的处理。
26.优先级反转
答:一个高优先级任务间接被一个低优先级任务所抢先(preemtped),使得两个任务的相对优先级被倒置。
这往往出现在一个高优先级任务A等待访问一个被低优先级任务C正在使用的临界资源,从而阻塞了高优先级任务A;同时,该低优先级任务C被一个次高优先级的任务B所抢先,从而无法及时地释放该临界资源。这种情况下,该次高优先级任务B获得执行权。
27.怎么解决优先级反转
答:当线程申请某共享资源时,把该线程的优先级提升到可访问这个资源的所有线程中的最高优先级
28.实时操作系统的任务调度
答:实时操作系统的调度算法是抢占式的,因为要保证对事件的实时响应,需要事件响应进程及时获得CPU时间,采用抢占式调度算法可以保证优先级高的进程可以暂停优先级低的进行而自身获取CPU时间
29.用过什么类型的单片机,说一下它们的架构,说一下你用的stm32的一些参数
答:STM32F103ZET6,ARM32位ContexTM-M3 CPU,最高72Mhz工作频率,2个12位A/D转换器(16个输入通道),速度为1us:转换范围0~3.6V
、STM32F427IIH6
、rt1064
30.单片机的堆栈
答:一个专门的区域来存放某些特别的数据,它遵循顺序存取和后进先出(LIFO/FILO)的原则,这个RAM区叫堆栈,堆栈区由堆栈指针SP管理
31.栈里面存放什么数据
答:栈由系统自动分配,存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new出来的对象)或者常量池中(字符串常量对象存放的常量池中),局部变量【注意:(方法中的局部变量使用final修饰后,放在堆中,而不是栈中)】
32.进程的调度和现场恢复
答:每个任务,在其创建的时候都会在栈内开辟一段固定大小的空间用来保存任务的上下文(包括CPU状态,运行栈,内部寄存器),保存现场就是要把CPU寄存器的值放到对应任务内存(OSTCBStkCur)上
恢复:把任务堆栈指针中保存的值加载CPU堆栈寄存器SP,和保存现场顺序一致,把堆栈SP值依次出栈并放入R0~R12/R14;完成恢复现场
33.说一下你用过的单片机外设
答:ADC采样、定时器、
34.程序怎么定位错误
答:使用调试器debug,如正点原子的无线调试器或者jlink_ob
35.玩32是时候遇到的困难
答:工程的时钟配置不对,对于工程的时钟树的理解,时钟源可以分为外部晶振和内部晶振,一般选择外部晶振然后需要对时钟源进行倍频和分频,验证时钟的方法可以是观察对应时钟寄存器的值,然后主时钟对了之后在对外设时钟进行检查,其中有一个外部时钟源的宏定义只会影响到串口和iis,需要特别注意。
36.说一下usb协议
答:USB,通用串行总线,是一种计算机与外围设备进行数据交互的通信协议。3.0,传输距离短,一般不超过5m,编码方式数据为0的时候电平翻转,数据为1的时候电平不反转。
37.说一下IIC协议
答:内部集成电路总线,一种常见的串行半双工通信协议,主要有四根线组成,其中SCL时钟线,SDA数据线
38.说一下你怎么用的uart协议
答:DMA循环双缓冲 空闲中断
将DMA设为循环模式,缓冲区长度设为两倍帧长,通过串口空闲中断(也可以通过DMA传输过半中断判断,只不过依然会出现上面的问题)触发一帧数据处理。在接收到完整一帧后触发串口空闲中断,此时再通过确认接收到的数据长度是否为一帧长度即可及时发现错误,同时两倍缓冲区长度使得在内核处理一帧时,即使第二帧马上发送仍然能够无丢失地接收,因此可以处理突发数据接收。
39.说一下你用过的编辑器
答:gcc、g
40.gcc写过编译脚本么
答:无
41.说一下gcc的命令吧
答:一步到位 gcc test.c -o test
- 预处理:gcc -E Test.c -o Test.i
- 编译: gcc -S Test.i -o Test.s
- 汇编: gcc -c Test.s -o Test.o
- 链接生成可执行文件: gcc Test.o -o Test
42.gcc编译 的时候用过构建系统么
答:无
43.遇到内存泄漏的错误么,用过free和malloc,如果你malloc一个东西,忘记free,怎么解决这个内存泄漏的问题
答:通过malloc、free的第二次封装来预防内存泄漏,主要表现是分别记录不同地方调用malloc、free的次数,来判断malloc、free是否配对使用,如果不配对使用,可以帮助定位到哪个地方是不配对使用的,以此达到内存泄漏定位的效果。
44.位运算为什么比除法运算快?
45.高速cache的相关知识简述