面试真题 | 地平线
地平线嵌入式实习面经
1.自我介绍
等着,在给大哥们准备了。
2.spi与iic协议可以连接多个设备吗?最多多少个?通讯时序。
这是几个问题,在回答的时候。不要一问就开口,花几秒钟沉吟思考整理一下自己的思路。
这个问题问了几个点?每个点的回答步骤。
是我的话,我会采用以下的步骤来回答:
- 一两句概括SPI和IIC的概念
- 然后对比说明SPI、IIC分别能不能连接多个设备,能连接的最多数是多少。
- 再说一下为什么是这个数量
- 最后会追追问你时序问题。先说IIC时序,再说SPI时序。不要混在一起了。
不要自己主动去讲,因为一般面试官都会固定问面试者几个问题。你主动回答了多余的,这不是替他省了一个技能。哈哈哈,对不起我鸡贼了。
当然上面的基础,都是建立在你对IIC和SPI都有一定了解与经验哦。没有的话,快学起来。不然就算是背下面的答案,再稍微扩展一下就露馅了,其次是这些东西都是工作中真的会使用的,所以学起来不吃亏。
不吃学习的苦,就要吃生活的苦了。
SPI(Serial Peripheral Interface)与IIC(Inter-Integrated Circuit,也称为I2C)协议在连接多个设备的能力上存在差异。
SPI协议
- 连接多个设备的能力:SPI协议通常是一对一的主从机连接,即一个主设备(Master)与一个从设备(Slave)之间的通信。每个从设备都需要一个单独的片选线(Select line,通常标记为SS或CS)来被主设备选中进行通信。因此,SPI协议本身并不直接支持在单个总线上连接多个从设备而不进行物理上的切换(除非使用特殊的多路复用器或类似设备)。
- 最多连接设备数:由于SPI协议的这种特性,它并不限制连接从设备的总数,但每个从设备需要独立的片选线。在实际应用中,受限于物理引脚数量和硬件复杂度,连接的设备数量会受到限制。每个从设备都需要一个独立的片选线来使之与主设备进行通信,因此SPI总线能够连接的最大设备数量等于片选线的数量。在实际应用中,SPI总线通常可以连接4个或更少的设备。
IIC协议
- 连接多个设备的能力:IIC协议支持多主机和多从机的通信,可以连接多个设备到同一总线上。每个从设备都有一个唯一的地址,主设备通过发送从设备的地址来选择与哪个从设备进行通信。
- 最多连接设备数:IIC协议的总线上最多可以连接的设备数受到从设备地址的限制。由于从设备地址通常是7位的(有的设备可能支持10位地址),因此理论上最多可以连接2^7 = 128个设备(对于7位地址)或2^10 = 1024个设备(对于10位地址)。然而,在实际应用中,由于总线电容、信号完整性和其他因素的影响,可能无法连接这么多设备。
综上所述,SPI协议通常仅仅支持在单个总线上直接连接4个或者更少的从设备,而IIC协议则支持通过地址选择来连接多个从设备,最多可以连接128个(对于7位地址)或更多(对于10位地址)设备,但实际连接数会受到硬件和电气特性的限制。
关于通信时序,认真去看看之前的文章:
这玩意就是让你去说说怎么通信传输数据的,讲清楚下面两个时序图。
4.c语言的栈区堆区,各存储什么?有什么区别?
heap:是由malloc之类函数分配的空间所在地。地址是由低向高增长的。
stack:是自动分配变量,以及函数调用的时候所使用的一些空间。地址是由高向低减少的。
回答不同,就是默认你都知道他们分别的内容,那么从下面几个方面来回答一下:
回答一定要分点作答!体现你的思维清晰,也可以帮你自己梳理知识点。
1. 管理方式不同
- 栈区:由编译器自动管理,无需程序员手工控制。当函数被调用时,函数的局部变量、参数等会被自动分配到栈上,并在函数返回时自动释放。
- 堆区:由程序员手动管理,通过调用如
malloc
(C语言)或new
(C++语言)等函数来申请内存,并通过free
(C语言)或delete
(C++语言)等函数来释放内存。如果程序员忘记释放内存,可能会导致内存泄漏。
2. 空间大小不同
- 栈区:栈是向低地址扩展的数据结构,其大小是系统预先规定好的,通常是有限的(例如,在Windows下可能是1MB或2MB)。如果申请的空间超过栈的剩余空间,将会导致栈溢出错误。
- 堆区:堆是向高地址扩展的数据结构,其大小受限于计算机系统中有效的虚拟内存。因此,堆区可以获得比栈区更灵活且更大的内存空间。
3. 是否产生碎片
- 栈区:由于栈是先进后出的数据结构,且栈中的元素都是一一对应的,因此栈区不会产生内存碎片。
- 堆区:频繁的
malloc
/free
(或new
/delete
)操作可能会导致内存空间的不连续,从而产生大量的内存碎片,降低程序的效率。
4. 增长方向不同
- 栈区:栈的增长方向是向下的,即向着内存地址减小的方向。
- 堆区:堆的增长方向是向上的,即向着内存地址增加的方向。
5. 分配方式不同
- 栈区:栈的分配和释放是由编译器自动完成的,无需程序员干预。栈的动态分配可以通过
alloca
函数(但请注意,alloca
函数并不是标准C语言的一部分,且在不同编译器上的行为可能有所不同)实现,但其分配和释放仍然是由编译器控制的。 - 堆区:堆的分配和释放是由程序员通过调用
malloc
/free
(或new
/delete
)等函数来完成的。
6. 分配效率不同
- 栈区:由于栈是由编译器自动管理的,且栈的分配和释放通常都有专门的指令支持,因此栈的分配效率通常较高。
- 堆区:堆的分配效率相对较低,因为堆的分配涉及到在链表中查找合适的空闲内存块、更新链表等复杂操作。此外,如果堆内存不足,还可能需要操作系统介入进行内存管理。
变量在内存中的存储情况
-
栈区 — 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。
-
堆区 — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事。
-
全局/静态存储区 — 全局变量和静态变量被分配到同一块内存中,在以前的 C 语言中,全局变量又分为初始化的和未初始化的(初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区可以通过 void* 来访问和操纵,程序结束后由系统自行释放),在 C++ 里面没有这个区分了,他们共同占用同一块内存区。
-
常量存储区 — 这是一块比较特殊的存
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
让实战与真题助你offer满天飞!!! 每周更新!!! 励志做最全ARM/Linux嵌入式面试必考必会的题库。 励志讲清每一个知识点,找到每个问题最好的答案。 让你学懂,掌握,融会贯通。 因为技术知识工作中也会用到,所以踏实学习哦!!!