嵌入式软件开发面试题总结二#面试宝典#

1.为什么需要Cache(高速缓冲存储器)?

我们都知道CPU处理数据的速度非常快,虽然内存的读写速度也不慢,但是相对于CPU它的速度就显得太慢了,所以如果单纯地让CPU对内存进行读写,所消耗的时间绝大部分是在内存对数据的处理上,而这时候CPU就在空等,浪费了资源,因此就需要在CPU与内存之间连接一个Cache来作为缓冲。

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

解题思路

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

3.说说对MMU及TLB的理解

解题思路

MMU是内存管理单元,它是一种负责处理中央处理器(CPU)的内存访问请求的计算机硬件。它的功能包括虚拟地址到物理地址的转换(即虚拟内存管理)、内存保护、中央处理器高速缓存的控制,在较为简单的计算机体系结构中,负责总线的仲裁以及存储体切换(bank switching,尤其是在8位的系统上)。TLB(Translation Lookaside Buffer)传输后备缓冲器是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据。TLB( Translation Look- aside buffer)专门用于缓存内存中的页表项,一般在MMU单元内部。TLB是一个很小的 cache,TLB表项( TLB entry)数量比较少,每个TLB表项包含一个页面的相关信息,例如有效位、虚拟页号、修改位、物理页帧号等。当处理器要访问一个虚拟地址时,首先会在TLB中查询。如果TLB表项中没有相应的表项,称为TLB Miss,那么就需要访问页表来计算出相应的物理地址。如果TLB表项中有相应的表项,那么直接从TLB表项中获取物理地址,称为TLB命中。

4.芯片选型考虑哪些因素?

解题思路

1.根据功能设计需求、成本、供应商等主要因素初步确定几款合适的芯片。2.普通I/O口,考虑数量、负载能力,还需要保证裕量,如果有迭代升级,还需要考虑兼容性 3.片上存储和外围存储,保证bootloader和程序image的容量;内存支持,由程序的RAM需求决定 4.主频及时钟,决定芯片的运行效率,响应和处理速度 5.电源及功耗,由板上电源和承载能力决定 6.如果是CPU芯片,考虑多核和多线程并发能力;如果是FPGA芯片,考虑逻辑单元资源数;如果是DSP芯片,考虑浮点计算能力 7.工作环境,如辐射、单粒子和温度范围 8.芯片成本和交付日期,是否可以购买到,以及购买周期与开发周期的平衡 总结,与软件相关的因素:I/O,内存,外存,处理器核和多线程,系统可移植性等

5.有cache的CPU上使用DMA如何保证数据的一致性

解题思路

Cache是CPU和主存之间的缓冲,DMA是为了主存和I/O数据交互设计的,期间CPU不参与控制。那么如果数据在主存中被CPU修改但是仍在cache中,即尚未更新主存,此时DMA获取的将是旧的数据,导致数据的不一致性。因此DMA在访问主存时,应当先检查cache是否命中,如果命中的话,DMA需要从Cache读取数据而非内存。在设计时可以使用总线监视技术或者nocache机制解决非一致性问题,在软件层次上,当DMA往主存写数据时,在DMA传输之前,可以invalid DMA Buffer地址范围的高速缓存。在DMA传输完成后,程序读取数据不会由于cache hit导致读取过时的数据。相反,DMA将数据输出时,在DMA传输之前,可以clean DMA Buffer地址范围的高速缓存,clean的作用是写回cache中修改的数据。在DMA传输时,不会把主存中的过时数据发送到I/O设备。

6.简述字节对齐?

解题思路

内存空间按照字节划分,理论上可以从任何起始地址访问任意类型的变量。但实际中在访问特定类型变量时经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序一个接一个地存放,这就是对齐。如果不按照平台要求对数据存放进行对齐,会带来存取效率上的损失。比如32位的Intel处理器通过总线访问(包括读和写)内存数据。每个总线周期从偶地址开始访问32位内存数据,内存数据以字节为单位存放。如果一个32位的数据没有存放在4字节整除的内存地址处,那么处理器就需要2个总线周期对其进行访问,显然访问效率下降很多。因此,通过合理的内存对齐可以提高访问效率。为使CPU能够对数据进行快速访问,数据的起始地址应具有“对齐”特性。比如4字节数据的起始地址应位于4字节边界上,即起始地址能够被4整除。此外,合理利用字节对齐还可以有效地节省存储空间。但要注意,在32位机中使用1字节或2字节对齐,反而会降低变量访问速度。因此需要考虑处理器类型。还应考虑编译器的类型。在VC/C++和GNU GCC中都是默认是4字节对齐。字节对齐最主要反映在结构体对齐,对齐的原则如下:
1) 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。2) 结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
3) 指定对齐值:#pragma Pack (value)时的指定对齐值value。
4) 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。

7.宏函数和内联函数的区别

解题思路

内联函数是代码入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。宏定义不检查函数参数和返回值,只是展开,相对来说,内联函数会检查参数类型,所以更安全。内联函数和宏很类似,而区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以像调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。

8.虚拟地址怎么转换到物理地址

解题思路

地址转换(Address Translation)负责将虚拟地址转换成物理地址。现代操作系统有很多实现手段: 最简单的base+bound技术,进程通过寄存器base和bound来转换内存,不能保证安全性,程序的不同内存区需要连续,不能动态管理。段技术:硬件为每个进程分配一组Base和Bound寄存器,每一对Base和Bound控制虚拟地址空间的一部分内存,称为段。每一段的虚拟地址空间是连续的,转换得到物理地址空间也是连续的,各个段之间不需要连续。这个技术可以很好的管理不同内存区,但是对于长度掌控的管理开销较大,寻找一段长度适合的物理地址需要额外开销。页技术:将虚拟内存空间和物理内存空间皆划分成大小相同的页面,例如4KB、8KB和16KB等。并将页作为内存空间的最小分配单位,一个程序的一个页面(虚拟页面)可以存放在任何一个物理页面中。一个程序发出的虚拟地址由虚拟页面号和页内偏移值两部分组成。快表TLB通常和处理器在一起,查找速度非常快,包含多级TLB,第一级TLB容量小、速度快,第二级TLB容量大、速度比第一级慢一些。可以大大提高虚拟地址转换为物理地址的效率

9.进程A执行,发生一个中断,中断发了一个信号,会让更高优先级的进程B执行,这时候中断结束,应该返回进程A还是进入进程B,并解释理由

解题思路

返回进程A。操作系统中中断优先级高于普通的进程,中断发生时,将保护进程A的现场并进入中断上下文,此时进程A仍然是执行态;中断结束后,操作系统将恢复进程A的现场并执行剩下的时间片,进程B的优先级虽然提高了,但需要等待A执行结束后下次调度时才可以执行,如果系统中没有其他中断或者更高优先级的进程的情况。

10.如果两个进程,都要去调用一个设备驱动,设备驱动里面定义的变量是在内核态吗?如果进程A访问并改变了这个变量,那么进程B再访问,是不是读到改变之后的值?

解题思路

驱动程序中的变量是在内核态中,因为操作系统只有内核态可以访问到硬件设备,驱动程序从内核态像用户态输出API以便调用和间接访问硬件设备。进程B访问的是改变后的值,只有在没有考虑并发编程的驱动程序中才可能发生数据的不一致性。内核驱动程序开发必须考虑并发的问题,因为驱动程序将会被一个或者多个进程访问,对于共享的变量,需要加入互斥锁、自旋锁、信号量或者原子操作等同步技术保证数据的一致性。

11.两个进程的内核空间是共享的吗

解题思路

用户空间中,每个进程的用户空间是互相独立的,互不相干。内核空间中,绝大部分是共享的,并不是完全共享,因为内核空间中,不同进程的内核栈之间是不共享的。之所以使用进程的内核栈而非"用户栈",是避免用户态下进程被抢占改变引发内核崩溃,因此每个进程在内核中有一个独立的内核

12.三次握手为什么ACK信号是SYN信号值+1

解题思路

为什么三次握手过程中,比如第一次握手,A向B发了seq=x,B给A回的ack是=x+1呢?如果有数据的话,那理应等于x+LEN。如果没有数据,那就应该保持不动就等于x才对。其实不然,服务器端回复的这个+1,是代表他收到了SYN标示。也就是说由于SYN或者FIN的存在,即使没有数据传输,但服务器端仍然需要通过+1来回应一句“我收到了”。因此握手过程中seq=x的话,ack = x+1。其他几次握手挥手也是同样道理。

13.驱动程序里面,如果有一个buffer,在不同场景下需要定义不同大小,怎么办?

解题思路

可以预先定义一个结构体,包含长度变量和一个指针,长度标志由ioctl函数从应用程序输入,并动态申请和释放内存。也可以在模块加载时预先申请不同大小的缓存。另一种办法是动态检测程序所需要的缓存数量,采用多级缓存的方式,根据所需传递数据的大小动态申请分布式缓存。

14.传引用和传指针区别

解题思路

指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

15.请你说一说cache的作用

解题思路

Cache存储器,电脑中为高速缓冲存储器,是位于CPU和主存储器DRAM(动态随机存取存储器)之间,规模较小,但速度很高的存储器,通常由SRAM(静态随机存取存储器 静态存储器)组成。它是位于CPU与内存间的一种容量较小但速度很高的存储器。CPU的速度远高于内存,当CPU直接从内存中存取数据时要等待一定时间周期,而Cache则可以保存CPU刚用过或循环使用的一部分数据,如果CPU需要再次使用该部分数据时可从Cache中直接调用,这样就避免了重复存取数据,减少了CPU的等待时间,因而提高了系统的效率。Cache又分为L1Cache(一级缓存)和L2Cache(二级缓存),L1Cache主要是集成在CPU内部,而L2Cache集成在主板上或是CPU上。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式软件开发面试中,可能会涉及以下几个方面的问题: 1. 嵌入式系统的特点和应用领域:嵌入式系统是指具有特定功能和任务的计算机系统,常常被用于控制和监控设备,如汽车、家电、工业设备等。面试官可能会问到嵌入式系统的特点,如实时性、功耗要求、资源受限等,以及常见的应用领域。 2. C语言中的位操作:嵌入式系统经常需要对特定的寄存器或内存位置进行位操作。你可以引用中的代码示例来明如何使用位操作宏定义来设置和清除特定的位。 3. 嵌入式系统中的绝对地址访问:有时候,嵌入式系统需要直接访问特定的内存地址来进行数据操作。你可以引用中的代码示例来明如何使用指针来访问绝对地址,并操作其中的数据。 4. 中断处理:中断是嵌入式系统中重要的组成部分,用于响应外部事件并进行相应的处理。你可以讨论中断的基本概念和作用,并提到在一些编译开发商提供的扩展中,可以使用关键字__interrupt来定义中断服务子程序(ISR)。你可以引用中的代码示例来明如何使用__interrupt关键字定义一个中断服务子程序。 5. 预处理指令的使用:在嵌入式软件开发中,预处理指令是常见的工具。你可以引用中的代码示例来明如何使用预处理指令#define来声明一个常数,并使用它来表示1年中的秒数。 总结起来,在嵌入式软件开发面试中,除了基本的软件开发知识外,还需要了解嵌入式系统的特点、C语言中的位操作、绝对地址访问、中断处理以及预处理指令的使用等方面的知识。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值