嵌⼊式软件⼯程师经典⾯试题(附答案)(⼆)
⼀、基本介绍
嵌⼊式系统是以应⽤为中⼼,以计算机技术为基础,并且软硬件可裁剪,适⽤于应⽤系统对功能、可靠性、成本、体积、功耗有严格要求的专⽤计算机系统。它⼀般由、外围硬件设备、以及⽤户的应⽤程序等四个部分组成,⽤于实现对其他设备的控制、监视或管理等功能。
嵌⼊式软件⼯程师就是编写嵌⼊式系统的⼯程师。
⼆、职业要求
应具备哪些能⼒
1.最重要的是C语⾔编程,以及C++,这个与你读程,应⽤,开发项⽬,做系统移植息息相关;
2.操作系统: LINUX,WINCE等,⾄少学习过⼀种,并且还需要对些基础知识有蛮多的了解;
3.对ARM,FPGA,DSP等这些硬件⽐较了解。
这是最常规的条件
当然,⼀些基本素质,像英语能⼒,团队协作能管理,也很重要。
三、经典⾯试题
1.嵌⼊式系统中经常要⽤到⽆限循环,如何⽤C编写死循环?
while(1){}或者for(;;)
2.程序的局部变量存在于哪⾥,全局变量存在于哪⾥,动态申请数据存在于哪⾥?
程序的局部变量存在于栈区;全局变量存在于静态区;动态申请数据存在于堆区
3.关键字const有什么含义?
1)只读。
2)使⽤关键字const也许能产⽣更紧凑的代码。
3)使编译器很⾃然地保护那些不希望被改变的参数,防⽌其被⽆意的代码修改
4.请问以下代码有什么问题?
int main() {
char a;
char *str=&a;
strcpy(str,"hello");
嵌入式系统开发是什么printf(str);
return 0;
}
没有为str分配内存空间,将会发⽣异常,问题出在将⼀个字符串复制进⼀个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进⾏内在读写⽽导致程序崩溃
5.已知⼀个数组table,⽤⼀个宏定义,求出数据的元素个数?
#define NTBL (sizeof(table)/sizeof(table[0]))
6.写⼀个"标准"宏MIN ,这个宏输⼊两个参数并返回较⼩的⼀个?
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
考点:
1) 标识#define在宏中应⽤的基本知识。这是很重要的。因为在 嵌⼊(inline)操作符 变为标准C的⼀部分之前,宏是⽅便产⽣嵌⼊代
码的唯⼀⽅法,对于嵌⼊式系统来说,为了能达到要求的性能,嵌⼊代码经常是必须的⽅法。
2) 三重条件操作符的知识。这个操作符存在C语⾔中的原因是它使得编译器能产⽣⽐if-then-else更优的代码,了解这个⽤法是很重要
的。
3) 懂得在宏中⼩⼼地把参数⽤括号括起来
7.do……while和while有什么区别?
前⼀个循环⼀遍再判断,后⼀个判断以后再循环
8.什么是预编译,何时需要预编译?
1、总是使⽤不经常改动的⼤型代码体。
2、程序由多个模块组成,所有模块都使⽤⼀组标准的包含⽂件和相同的编译选项。在这种情况下,可以将所有包含⽂件预编译为⼀个预编译头。
预编译指令指⽰了在程序正式编译前就由编译器进⾏的操作,可以放在程序中的任何位置
9.⼀个32位的机器,该机器的指针是多少位?
指针是多少位只要看地址总线的位数就⾏了。80386以后的机⼦都是32的数据总线。所以指针的位数就是4个字节了
10.局部变量能否和全局变量重名?
能,局部会屏蔽全局。
局部变量可以与全局变量同名,在函数内引⽤这个变量时,会⽤到同名的局部变量,⽽不会⽤到全局变量。
对于有些编译器⽽⾔,在同⼀个函数内可以定义多个同名的局部变量,⽐如在两个循环体内都定义⼀个同名的局部变量,⽽那个局部变量的作⽤域就在那个循环体内
11.引⽤与指针有什么区别?
1) 引⽤必须被初始化,指针不必。
2) 引⽤初始化以后不能被改变,指针可以改变所指的对象。
3) 不存在指向空值的引⽤,但是存在指向空值的指针
12.关键字static的作⽤是什么?
在C语⾔中,关键字static有三个明显的作⽤:
1) 在函数体,⼀个被声明为静态的变量在这⼀函数被调⽤过程中维持其值不变。
2) 在模块内(但在函数体外),⼀个被声明为静态的变量可以被模块内所⽤函数访问,但不能被模块外其它函数访问。它是⼀个本地
的全局变量。
3) 在模块内,⼀个被声明为静态的函数只可被这⼀模块内的其它函数调⽤。那就是,这个函数被限制在声明它的模块的本地范围内使
⽤。
13.static全局变量与普通的全局变量有什么区别?static函数与普通函数有什么区别?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本⾝就是静态存储⽅式,静态全局变量当然也是静态存储⽅式。这两者在存储⽅式上并⽆不同。
这两者的区别虽在于⾮静态全局变量的作⽤域是整个源程序, 当⼀个源程序由多个源⽂件组成时,⾮静态的全局变量在各个源⽂件中都是有效的。⽽静态全局变量则限制了其作⽤域,即只在定义该变量的源⽂件内有效, 在同⼀源程序的其它源⽂件中不能使⽤它。
由于静态全局变量的作⽤域局限于⼀个源⽂件内,只能为该源⽂件内的函数公⽤,因此可以避免在其它源⽂件中引起错误。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储⽅式即改变了它的⽣存期。把全局变量改变为静态变量后是改变了它的作⽤域,限制了它的使⽤范围。
static函数与普通函数作⽤域不同。仅在本⽂件。只在当前源⽂件中使⽤的函数应该说明为内部函数(static),内部函数应该在当前源⽂件中说明和定义。
对于可在当前源⽂件以外使⽤的函数,应该在⼀个头⽂件中说明,要使⽤这些函数的源⽂件要包含这个头⽂件。
14.进程之间通信的途径有哪些?
进程间通信主要通过管道、消息、信号等途径进⾏。
1、⽆名管道( pipe ):管道是⼀种半双⼯的通信⽅式,数据只能单向流动,⽽且只能在具有亲缘关系的进程间使⽤。进程的亲缘关系
通常是指⽗⼦进程关系。
2、⾼级管道(popen):将另⼀个程序当做⼀个新的进程在当前程序进程中启动,则它算是当前程序的⼦进程,这种⽅式我们成为⾼级
管道⽅式。
3、有名管道 (named pipe) :有名管道也是半双⼯的通信⽅式,但是它允许⽆亲缘关系进程间的通信。
4、消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信
息少、管道只能承载⽆格式字节流以及缓冲区⼤⼩受限等缺点。
5、信号量( semophore ) :信号量是⼀个计数器,可以⽤来控制多个进程对共享资源的访问。它常作为⼀种锁机制,防⽌某进程正
在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同⼀进程内不同线程之间的同步⼿段。
6、信号 ( sinal ) :信号是⼀种⽐较复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣。
7、共享内存( shared memory ) :共享内存就是映射⼀段能被其他进程所访问的内存,这段共享内存由⼀个进程创建,但多个进程
都可以访问。共享内存是最快的 IPC ⽅式,它是针对其他进程间通信⽅式运⾏效率低⽽专门设计的。它往往与其他通信机制,如信号两,配合使⽤,来实现进程间的同步和通信。
8、套接字( socket ) :套解⼝也是⼀种进程间通信机制,与其他通信机制不同的是,它可⽤于不同机器间的进程通信。
15.产⽣死锁的原因是什么?
多个并发进程因争夺系统资源⽽产⽣相互等待的现象。即:⼀组进程中的每个进程都在等待某个事件发⽣,⽽只有这组进程中的其他进程才能触发该事件,这就称这组进程发⽣了死锁。
产⽣死锁的本质原因为:
1)、系统资源有限。
2)、进程推进顺序不合理。
16.死锁的4个必要条件?
1、互斥:某种资源⼀次只允许⼀个进程访问,即该资源⼀旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待:⼀个进程本⾝占有资源(⼀种或多种),同时还有资源未得到满⾜,正在等待其他进程释放该资源。
3、不可抢占:别⼈已经占有了某项资源,你不能因为⾃⼰也需要该资源,就去把别⼈的资源抢过来。
4、循环等待:存在⼀个进程链,使得每个进程都占有下⼀个进程所需的⾄少⼀种资源。
当以上四个条件均满⾜,必然会造成死锁,发⽣死锁的进程⽆法进⾏下去,它们所持有的资源也⽆法释放。这样会导致CPU的吞吐量下降。所以死锁情况是会浪费系统资源和影响计算机的使⽤性能的。那么,解决死锁问题就是相当有必要的了。
17.死锁的处理⽅式有哪些?
死锁的处理⽅式主要从预防死锁、避免死锁、检测与解除死锁这四个⽅⾯来进⾏处理。
预防死锁:
1、资源⼀次性分配:(破坏请求和保持条件)
2、可剥夺资源:即当某进程新的资源未满⾜时,释放已占有的资源(破坏不可剥夺条件)
3、资源有序分配法:系统给每类资源赋予⼀个编号,每⼀个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
避免死锁:
预防死锁的⼏种策略,会严重地损害系统性能。因此在避免死锁时,要施加较弱的限制,从⽽获得 较满意的系统性能。由于在避免死锁的策略中,允许进程动态地申请资源。因⽽,系统在进⾏资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进⼊不安全状态,则将资源分配给进程;否则,进程等待。其中最具有代表性的避免死锁算法是银⾏家算法。
检测死锁:
⾸先为每个进程和每个资源指定⼀个唯⼀的号码;
然后建⽴资源分配表和进程等待表
解除死锁:
当发现有进程死锁后,便应⽴即把它从死锁状态中解脱出来,常采⽤的⽅法有:
1、剥夺资源:从其它进程剥夺⾜够数量的资源给死锁进程,以解除死锁状态;
2、撤消进程:可以直接撤消死锁进程或撤消代价最⼩的进程,直⾄有⾜够的资源可⽤,死锁状态.消除为⽌;所谓代价是指优先级、
运⾏代价、进程的重要性和价值等。
18.进程和线程有什么区别?
进程是并发执⾏的程序在执⾏过程中分配和管理资源的基本单位。线程是进程的⼀个执⾏单元,是⽐进程还要⼩的独⽴运⾏的基本单位。⼀个程序⾄少有⼀个进程,⼀个进程⾄少有⼀个线程。两者的区别主要有以下⼏个⽅⾯:
1. 进程是资源分配的最⼩单位。
2. 线程是程序执⾏的最⼩单位,也是处理器调度的基本单位,但进程不是,两者均可并发执⾏。
3. 进程有⾃⼰的独⽴地址空间,每启动⼀个进程,系统就会为它分配地址空间,建⽴数据表来维护代码段、堆栈段和数据段,这种操
作⾮常昂贵。⽽线程是共享进程中的数据,使⽤相同的地址空间,因此,CPU切换⼀个线程的花费远⽐进程⼩很多,同时创建⼀个线程的开销也⽐进程⼩很多。
4. 线程之间的通信更⽅便,同⼀进程下的线程共享全局变量、静态变量等数据,⽽进程之间的通信需要以通信的⽅式(IPC)进⾏。不
过如何处理好同步与互斥是编写多线程程序的难点。但是多进程程序更健壮,多线程程序只要有⼀个
线程死掉,整个进程也跟着死掉了,⽽⼀个进程死掉并不会对另外⼀个进程造成影响,因为进程有⾃⼰独⽴的地址空间。
5. 进程切换时,消耗的资源⼤,效率低。所以涉及到频繁的切换时,使⽤线程要好于进程。同样如果要求同时进⾏并且⼜要共享某些
变量的并发操作,只能⽤线程不能⽤进程。
6. 执⾏过程:每个独⽴的进程有⼀个程序运⾏的⼊⼝、顺序执⾏序列和程序⼊⼝。但是线程不能独⽴执⾏,必须依存在应⽤程序中,
由应⽤程序提供多个线程执⾏控制。
优缺点:
线程执⾏开销⼩,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运⾏。
进程执⾏开销⼤,但是能够很好的进⾏资源管理和保护,可以跨机器迁移。
何时使⽤多进程,何时使⽤多线程?
对资源的管理和保护要求⾼,不限制开销和效率时,使⽤多进程。
要求效率⾼,频繁切换时,资源的保护管理要求不是很⾼时,使⽤多线程。
19. 线程是否具有相同的堆栈?
真正的程序执⾏都是线程来完成的,程序启动的时候操作系统就帮你创建了⼀个主线程。
每个线程有⾃⼰的堆栈。
20.TCP与UDP有啥区别?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论