嵌入式软件开发就业面试题。2022最新,最全总结。

在网上搜集了很多的面试题,发现总体的试题都是倾向于c语言,不能说是完全不相关,只能说毫不相关,本合集关于嵌入式软件开发从底层驱动到应用层,也是从网上搜集的,也有本人学习嵌入式开发的经验和侧重点突出;值得一看,记得收藏!

1. select和epoll的区别

解题思路 (这个我在找面试题之前没了解过 ,还是学的太少了,多学!!!)

select的时间复杂度O(n)。它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。 epoll的时间复杂度O(1)。epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))

2.异步IO和同步IO区别?

解题思路 (同步和异步的概念还是在通信的时候学到,这里意思有点差异,注意!)

所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。而异步就是过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。所以异步IO和同步IO区别就是数据拷贝的时候进程是否阻塞

3.什么叫死锁?产生死锁的原因是什么?

解题思路(学过多线程,就知道死锁的概念 ,和锁有同样功能的有信号,信号灯集。。)

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
死锁产生的原因可归结为两点:
1.竞争资源;
2.进程间推进顺序非法

4.死锁的必要条件是什么?

解题思路(学过多线程应该都知道锁的概念,还有信号条件变量等对资源的控制手段)

产生死锁的必要条件: 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。 环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链

5.linux的进程状态有哪些?

解题思路
学过进程都知道

Linux系统下进程通常存在6种不同的状态,分为:就绪态、运行态、僵尸态、可中断睡眠状态(浅度睡眠)、不可中断睡眠状态(深度睡眠)以及暂停态。

6.什么是优先级翻转,如何避免优先级翻转?

解题思路 (优先级的概念还是在学单片机中认识,顾名思义,先后顺序的意思)
转指的是一个具有中等优先级的任务比一个更高优先级的任务先执行。优先级翻转的主要原因是对共享资源的访问产生了互斥,因此我们可以采用带有优先级继承机制的互斥量来避免优先级翻转。**

7.Linux驱动程序的功能是什么?

解题思路 *(明白了驱动程序的意思!)

设备驱动连接操作系统和硬件。设备驱动程序是一种可以使计算机与设备进行通信的特殊程序,可以说相当于硬件的接口。操作系统只有通过这个接口,才能控制硬件设备的工作。安装在操作系统中的驱动程序可以完成设备的初始化和释放,进行外部数据和操作系统的通信和数据交互,控制硬件的行为,并检查设备可能出现的故障并报错。

8.Linux驱动程序的分类有哪些?

解题思路

Linux将硬件设备分为3大类,分别是字符设备、块设备和网络设备。字符设备是指那些能一个字节一个字节读取数据的设备,如键盘鼠标等,常见的SPI/I2C/UART默认也是字符设备。块设备与字符设备类似,一般是像磁盘一样的设备。网络设备主要负责主机之间的数据交换。与字符设备和块设备完全不同,网络设备主要是面向数据包的接收和发送而设计的。

9.内核程序中申请内存使用什么函数?

解题思路 (之前都是cc++里面申请内存,现在是内核中,可以对比一下)

内核中使用kmalloc(),kzalloc(), vmalloc(), alloc_page()等函数。 kamlloc申请的内存区域位于物理内存的映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,存在比较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。 kzalloc() 函数与 kmalloc() 额外附加了 __GFP_ZERO 标志,所以它除了申请内核内存外,还会对申请到的内存内容清零。 vmalloc() 函数则会在虚拟内存空间给出一块连续的内存区,但这片连续的虚拟内存在物理内存中并不一定连续。由于 vmalloc() 没有保证申请到的是连续的物理内存,因此对申请的内存大小没有限制,如果需要申请较大的内存空间就需要用此函数了。需要注意的是vmalloc() 和 vfree() 可以睡眠,因此不能从中断上下文调用。 alloc_page()用于申请连续的物理页,可以通过page_address()把指定的页转化成逻辑地址。 如何区分这几个概念: kmalloc是最常用的内存分配函数,可以原子操作,速度快,缺点就是大小有上限,kzalloc是强制清零版本的kmalloc,而vmalloc只有在需要申请大内存的时候使用,会陷入阻塞

10.内核程序中申请内存和应用程序时申请内存有什么区别?

解题思路

应用程序的内存申请,例如C/C++可以使用malloc函数,与内核的kmalloc(),kzalloc(), vmalloc(), alloc_page()等函数相比,比较像vmalloc机制,即虚拟地址申请,物理地址不一定连续,区别在于,应用程序malloc不会做分配物理页的动作,交由内核去申请,而vmalloc本身在内核中会执行这个动作。

11.自旋锁和信号量在互斥使用时需要注意什么?在中断服务程序里面的互斥是使用自旋锁还是信号量?

解题思路 (自旋锁的概念)

自旋锁会一直自旋等待,不会休眠;而信号量是等待信号来唤醒进程,进程会睡眠。使用时注意希望长等待不吃系统资源时使用信号量,反过来短期的等待使用自旋锁,但会增加系统开销。 中断中不可以使用信号量,因为中断不能睡眠。

谈一谈什么是系统声明周期,说说你对敏捷开发的理解以及和SDLC的关系

解题思路 (难理解啊。。。。)

SDLC:sdlc(系统生命周期,系统生存周期)是软件的产生直到报废的生命周期,是软件工程中的一种思想原则,包括: 问题定义及规划、需求分析、软件设计、程序编码、软件测试、运行维护 敏捷开发的核心是迭代开发(iterative development)。敏捷一定是采用迭代开发的方式。迭代开发将一个大任务,分解成多次连续的开发,本质就是逐步改进。一般采用“增量开发”(incremental development)划分迭代。所谓"增量开发",指的是软件的每个版本,都会新增一个用户可以感知的完整功能。虽然敏捷开发将软件开发分成多个迭代,但是也要求,每次迭代都是一个完整的软件开发周期,必须按照软件工程的方法论,进行正规的流程管理。也就是说,敏捷开发的每一次迭代都需要一个完整的SDLC。

13.请你讲一讲Linux中断的原理和开发方法?

解题思路

Linux中断处理过程分为两部分: 上半部:上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可以放在上半部完成。 下半部:如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部去执行,这样中断处理函数就会快进快出。 那些对时间敏感、执行速度快的操作可以放到中断处理函数中,也就是上半部。剩下的所有工作都可以放到下半部去执行,比如在上半部将数据拷贝到内存中,关于数据的具体处理就可以放到下半部去执行。一般来说,不希望被其他中断打断、对时间敏感、和硬件有关的任务建议放在中断上半部。

14.static修饰局部变量和全局变量会有什么效果

解题思路 (这个也是c里面的知识)

静态全局变量:具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被 static 关键字修饰过的变量具有文件作用域。 静态局部变量:具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在。

15.堆和栈的区别

解题思路 最基本的

栈由系统分配,堆由程序员控制,例如C/C++的malloc函数 栈的大小较小,有默认上限,堆理论上可以申请整个虚拟内存的大小 栈向下增长,地址由高到低,堆向上增长,地址从低到高 栈的分配效率较高,保证函数执行跳转的效率,堆的分配更为复杂,容易产生碎片,需要回收 栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等;堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。

16.简述gcc编译过程

解题思路 学过Linux都知道

预处理、编译、汇编和链接,一个hello.c的c语言程序如下。 预处理阶段:hello.c–>hello.i 编译阶段:hello.i–>hello.s 汇编阶段:hello.s–>hello.o 链接阶段:hello.o–>hello

17.线程与进程的区别

解题思路 进程与线程的区别 ,简单

进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发;线程是操作系统可识别的最小执行和调度单位。 一个线程只能属于一个进程,而一个进程可以有多个线程 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存 进程是资源分配的最小单位,线程是CPU调度的最小单位 进程切换的开销也远大于线程切换的开销。进程编程调试简单可靠性高,但是创建销毁开销大;线程正相反,开销小,切换速度快,但是编程调试相对复杂

18.野指针出现情况、怎么解决

解题思路 c知识

1.指针变量声明时没有被初始化,可以在指针声明时初始化,可以是具体的地址值,也可让它指向NULL。 2.指针 p 被 free 或者 delete 之后,没有置为 NULL。指针指向的内存空间被释放后指针应该指向NULL。 3.指针操作超越了变量的作用范围,在变量的作用域结束前释放掉变量的地址空间并且让指针指向NULL。

19.dma有什么用

解题思路 单片机

直接存储器存取(Direct Memory Access,DMA)可以让某些电脑内部的硬体子系统(电脑外设),可以独立地直接读写系统存储器,而不需绕道 CPU。在同等程度的CPU负担下,DMA是一种快速的数据传送方式。它允许不同速度的硬件装置来沟通,而不需要依于 CPU的大量中断请求。大大提高了访问效率,减少访问时间,降低CPU资源的消耗。

20.说一说RISC和CISC的区别

解题思路 两个指令集

精简指令集RISC和复杂指令集CISC CISC处理的是不等长指令集,它必须对不等长指令进行分割,因此在执行单一指令的时候需要进行较多的处理工作。而RISC执行的是等长精简指令集,CPU在执行指令的时候速度较快且性能稳定。因此在并行处理方面RISC明显优于CISC,RISC可同时执行多条指令,它可将一条指令分割成若干个进程或线程,交由多个处理器同时执行。由于RISC执行的是精简指令集,所以它的制造工艺简单且成本低廉。

持续更新 收藏!!!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>