嵌入式软件开发面试题总结四

编译有几个阶段 每个阶段做什么事情

解题思路
词法分析阶段:读入源程序,对构成源程序的字符流进行扫描和分解,识别出单词, 语法分析阶段:机器通过词法分析,将单词序列分解成不同的语法短语,确定整个输入串能够构成语法上正确的程序。语义分析阶段:检查源程序上有没有语义错误,在代码生成阶段收集类型信息 中间代码生成阶段:在进行了上述的语法分析和语义分析阶段的工作之后,有的编译程序将源程序变成一种内部表示形式 代码优化:这一阶段的任务是对前一阶段产生的中间代码进行变换或进行改造,目的是使生成的目标代码更为高效,即省时间和省空间 目标代码生成:这一阶段的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码

内核申请内存vmalloc和kmalloc的区别是什么

解题思路
1,vmalloc分配的一般为高端内存,只有当内存不够的时候才分配低端内存;kmallco从低端内存分配。
2,vmalloc分配的物理地址一般不连续,而kmalloc分配的地址连续,两者分配的虚拟地址都是连续的;
3,vmalloc分配的一般为大块内存,而kmaooc一般分配的为小块内存,(一般不超过128k);

简单描述一下数组指针和指针数组

解题思路
数组指针是一个指针,指向一个数组。指针数组由n个指针类型的数组元素组成。数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。、

简单描述linux设备驱动中的总线,设备和驱动的关系。

解题思路
总线将设备和驱动绑定。在系统每注册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每 注册一个驱动的时候,会寻找与之匹配的设备,而匹配由总线完成。一个现实的Linux设备和驱动通常都需要挂接在一种总线上。设备与驱动的关联通过总线的match()方法进行匹配,驱动挂载总线时与所有设备进行匹配,设备挂载总线时与所有的驱动进行匹配,所以驱动和设备的挂载无先后之分。匹配成功后会通过调用驱动的probo()方法来初始化设备。

简述一下什么是红黑树

解题思路
红黑树是一种近似平衡的二叉查找树,它能够确保任何一个节点的左右子树的高度差不会超过二者中较低那个的一倍。具体来说,红黑树是满足如下条件的二叉查找树 1.每个节点要么是红色,要么是黑色。
2.根节点必须是黑色
3.红色节点不能连续(也即是,红色节点的孩子和父亲都不能是红色)。
4.对于每个节点,从该点至null(树尾端)的任何路径,都含有相同个数的黑色节点。
5.最长的路径长度不会超过任意路径的两倍。

指针和引用的区别

解题思路
(1)指针是实体,占用内存空间;引用是别名,与变量共享内存空间。
(2)指针不用初始化或初始化为NULL;引用定义时必须初始化。
(3)指针中途可以修改指向;引用不可以。
(4)指针可以为NULL;引用不能为空。
(5)sizeof(指针)计算的是指针本身的大小;而sizeof(引用)计算的是它引用的对象的大小。
(6)如果返回的是动态分配的内存或对象,必须使用指针,使用引用会产生内存泄漏。
(7)指针使用时需要解引用;引用使用时不需要解引用’*'。(8)有二级指针;没有二级引用。

说说内联函数和宏函数的区别

解题思路
相同点: (1)二者都是通过将函数调用替换成完整的函数体,相比函数调用的时间、空间开销而言,二者提高了效率。不同点: (1)宏定义不是函数,而内联函数时函数,因此内联函数可以调试,宏定义不能。(2)宏定义的代码展开阶段是预处理阶段,而内联函数在编译阶段,因此内联 函数有类型安全检查,宏定义没有 (3)内联函数作为类的成员函数时,可以访问类的所有成员(公有、保护、私有),宏定义不能。

在FreeRTOS中,二值信号量和互斥量的区别?

解题思路
互斥型信号量必须是同一个任务申请,同一个任务释放,其他任务释放无效。同一个任务可以递归申请。二进制信号量,一个任务申请成功后,可以由另一个任务释放。

在FreeRTOS中,任务通知的运行机制是怎么样的?

解题思路
任务通知的数据结构包含在任务控制块中,只要任务存在,任务通知数据结构就已经创建完毕,可以直接使用。任务通知可以在任务中向指定任务发送通知,也可以在中断中向指定任务发送通知,FreeRTOS 的每个任务都有一个 32 位的通知值,任务控制块中的成员变量 ulNotifiedValue就是这个通知值。只有在任务中可以等待通知,而不允许在中断中等待通知。如果任务在等待的通知暂时无效,任务会根据用户指定的阻塞超时时间进入阻塞状态,我们可以将等待通知的任务看作是消费者;其它任务和中断可以向等待通知的任务发送通知,发送通知的任务和中断服务函数可以看作是生产者,当其他任务或者中断向这个任务发送任务通知,任务获得通知以后,该任务就会从阻塞态中解除。

什么情况下会栈溢出?如何避免?

解题思路
1.局部数组过大。当函数内部的数组过大时,有可能导致堆栈溢出。2.递归调用层次太多。递归函数在运行时会执行压栈操作,当压栈次数太多时,也会导致堆栈溢出。3.指针或数组越界。这种情况最常见,例如进行字符串拷贝,或处理用户输入等等。解决这类问题的办法有两个, 一是增大栈空间,二是改用动态分配,使用堆(heap)而不是栈(stack)。

深复制和浅复制的区别?

解题思路
浅复制:被复制对象的所有变量都含有与原来对象相同的值,而所有其他对象的引用仍然指向原来的对象。深复制:被复制对象的所有变量都含有与原来对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象。

简述一下快速排序的步骤

解题思路
1.从数列中挑出一个元素,称为 “基准”;
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置;
3.递归地把小于基准值元素的子数列和大于基准值元素的子数列排序

头文件的两种包含方式的区别

解题思路
< >引用的是编译器的类库路径里面的头文件,#include <> 的查找位置是标准库头文件所在目录;“ ”引用的是你程序目录的相对路径中的头文件, #include “” 的查找位置是当前源文件所在目录。

.CAN通信介绍;CAN通信报文的标识符有几位?

解题思路
CAN 是ISO国际标准化的串行通信协议。CAN 控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。通信报文标识符有标准格式和扩展格式两种格式。标准格式有11 个位的标识符(ID),扩展格式有29 个位的ID。

C语言结构体怎么定义节省内存

解题思路
1.在保证值域足够的情况下,用小字节变量代替大字节变量,如用short替代int
2.将各成员按其所占字节数从小到大声明,以尽量减少中间的填补空间(字节对齐)。
3.可以取消字节对齐,#pragma pack(1),当然这会牺牲效率,谨慎采用。
STM32 中断是怎么进入到中断服务程序的

解题思路
在STM32中,为了区分不同的中断,每个设备有自己的中断号。系统有0-255一共256个中断。系统有一张中断向量表,用于存放256个中断的中断服务程序入口地址。每个入口地址对应一段代码,即中断服务程序。

malloc和新的区别

解题思路
1、申请的内存所在位置不同。new操作符从自由存储区上为对象动态分配内存空间,malloc函数从堆上动态分配内存。
2. 返回类型安全性不同。new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
3. 内存分配失败时的返回值不同。new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL。malloc分配内存失败时返回NULL。
4. 是否需要指定内存大小不同。使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。malloc则需要显式地指出所需内存的尺寸。

为什么局部变量未赋值时,每次初始化的结果是不确定的?

解题思路
定义局部变量,其实就是在栈中通过移动栈指针来给程序提供一个内存空间和这个局部变量名绑定。因为这段内存空间在栈上,而栈内存是反复使用的,上次用完没清零的,所以说使用栈来实现的局部变量定义时如果不显式初始化,值就是脏的,是不确定的。

linux的锁机制?

解题思路
(1)互斥锁:mutex,保证在任何时刻,都只有一个线程访问该资源,当获取锁操作失败时,线程进入阻塞,等待锁释放。(2)读写锁:rwlock,分为读锁和写锁,处于读操作时,可以运行多个线程同时读。但写时同一时刻只能有一个线程获得写锁。(3)自旋锁:spinlock,在任何时刻只能有一个线程访问资源。但获取锁操作失败时,不会进入睡眠,而是原地自旋,直到锁被释放。这样节省了线程从睡眠到被唤醒的时间消耗,提高效率。(4)条件锁:就是所谓的条件变量,某一个线程因为某个条件未满足时可以使用条件变量使该程序处于阻塞状态。一旦条件满足了,即可唤醒该线程(常和互斥锁配合使用) (5)信号量。

介绍下常用的gdb命令

解题思路
quit:退出gdb,结束调试 list:查看程序源代码 reverse-search:字符串用来从当前行向前查找第一个匹配的字符串 run:程序开始执行 help list/all:查看帮助信息 break:设置断点 break get_sum:以函数名设置断点 break 行号或者函数名 if 条件:以条件表达式设置断点 观看 条件表达式:条件表达式发生改变时程序就会停下来 next:继续执行下一条语句 ,会把函数当作一条语句执行 step:继续执行下一条语句,会跟踪进入函数,一次一条的执行函数内的代码

C++ 什么情况下必须用初始化列表

解题思路
1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。2.const 成员或引用类型的成员。因为 const 对象或引用类型只能初始化,不能对他们赋值。

linux用户态怎么进入内核态

解题思路
linux从用户态到内核态的切换通过系统调用接口来实现,而系统调用切换时通过软件中断来完成,该中断是程序人员自己开发出的一种正常的异常,那么在Linux下,这个异常具体就是调用int $0x80的汇编指令,这条汇编指令将产生向量为0x80的编程异常。

操作系统条件变量的惊群效应是什么

解题思路
惊群效应原本是:当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到食物的鸽子只好回去继续睡觉, 等待下一块食物到来。这样,每扔一块食物,都会惊动所有的鸽子,即为惊群。在操作系统中,多进程/多线程等待同一资源时,当某一资源可用时,多个进程/线程会惊醒,竞争资源。这就是操作系统中的惊群。

什么是预编译:

预编译就是预处理 一些文本和代码的替换工作,在我们整个项目工程代码中是随处可见的,基本上每个头文件中都会用到,尤其是在嵌入式开发中用到更多; 对于我们经常用带的代码体和不经常改变的代码,我么就可以将他们做成预编译的头文件供我们使用

#include #ifdef #ifndef #else #enfid

#define seconds_year (3652460*60)UL
#define arraylen(A) (sizeof(A)/sizeof(A[0]))

IIC

IIc一共有两条总线,一条SCL一条SDA,都是双向路线,都通过上拉电阻连接到正的电源电压,当总线空闲时,总线都是高电平。IIc总线上数据传输速率标准模式下100kbit/s 快速模式400kbit/s 高速模式3.4mbit/s
地址SLAVE_ADDRESS
每个外设都有自己的地址,标准地址可以是7位或者10位,整个总线要协调好
一个字节八个数据位:七个数据为+一位读写位 =8位地址( 0写 1读)
连接到总线的接口是根据总线电容限定决定
————|——————|————|————|——————|————
起始信号 设备地址 读写位 R/W DATA A|~A响应位 终止信号
起始信号:当SCL线为高电平时,SDA从高电平转换到低电平
终止信号:当SCL线为高电平时,SDA从低电平转换到高电平
(起始条件:SCL线是高电平时,SDA线从高电平向低电平切换
终止条件:SCL是高电平时,SDA线由高电平向低电平切换)
有效位:
SDA线上的数据必须在时钟的高电平周期保持稳定。数据线的高低状态只有在SCL线的时钟信号是低电平时才能改变
响应
每发一个字节都有一个响应
数据接收端发送响应
SPI
四条总线
nss片选线 每个外设都有一根
sck 时钟线
mosi 主机输出从机输入
miso 主机输入从机输出

开始信号:nss信号线由高变低是SPI通讯的起始信号, nss是每个从机独占的信号线,当从机从自己的nss线检测到起始信号后,知道自己被主机选中了,开始准备与主机通讯
时钟极性:CPOL
cpol是指spi通讯设备处于空闲时,sck信号线的电平信号(spi开始通讯前,nss为高电平时sck的状态)CPOL=0时sck在空闲状态为低电平,cpol=1sck在空闲时为高电平
时钟相位:CPHA
cpha指采样的时刻;当cpha为低电平时,mosi或miso数据线上的信号将会在sck时钟线奇数边沿被采样;当cpha为高电平时,数据线上的信号会在sck时钟线的偶数边沿采样

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值