嵌入式面经
C语言的函数调用原理是什么?
-
栈帧(Stack Frame):
- 在函数调用时,会创建一个新的栈帧,用于存储函数的局部变量、参数、返回地址以及其他相关信息。
- 栈帧通常包括以下几个部分:
- 参数: 被调用函数的参数被压入栈中,按照一定的顺序排列。
- 返回地址: 调用函数的返回地址被压入栈中,用于指示函数执行完毕后返回的位置。
- 局部变量: 被调用函数的局部变量在栈帧中分配空间。
- 其他辅助信息: 如保存的寄存器状态等。
-
调用过程:
- 在函数调用前,调用者需要将参数压入栈中。
- 调用者将函数的返回地址压入栈中,然后跳转到被调用函数的入口地址。
- 被调用函数开始执行,创建新的栈帧,并将参数和局部变量存储在其中。
- 被调用函数执行完毕后,将返回值存储在适当的位置,然后将返回地址弹出栈,并跳转到该地址,返回到调用函数处。
-
栈的管理:
- 栈用于存储函数调用过程中的参数、局部变量和返回地址等信息。
- 栈的大小通常是固定的,当函数调用嵌套层级很深或者函数中声明了大量的局部变量时,可能会导致栈溢出。
- 在函数调用结束后,栈上的空间会被释放,以便其他函数调用使用。
总的来说,C语言中的函数调用原理涉及到栈的使用和管理,通过栈帧来保存函数调用过程中的相关信息,并通过栈来传递参数和返回值。
什么是封装、继承、多态?
-
封装(Encapsulation):
- 封装是将数据和操作数据的方法(即函数)封装在一起,形成一个完整的、相互依赖的单元。通过封装,对象的内部细节被隐藏起来,外部只能通过对象所提供的接口来访问和操作对象的状态。
- 封装提供了良好的抽象屏障,使得对象的内部实现细节对外部是透明的,从而降低了系统的耦合度,提高了代码的可维护性和可重用性。
-
继承(Inheritance):
- 继承是一种机制,通过它一个类(称为子类或派生类)可以从另一个类(称为父类或基类)继承属性和方法。子类可以直接访问父类中的非私有成员(即公有成员和受保护成员),并且可以扩展或修改父类的行为。
- 继承实现了代码的重用,通过定义通用的类并从中派生出具体的类,可以减少代码的重复编写,并且使得代码的结构更加清晰和易于理解。
-
多态(Polymorphism):
- 多态是指同一个操作作用于不同的对象上时会产生不同的行为。在面向对象编程中,多态通常通过函数重载(Overloading)和虚函数(Virtual Function)来实现。
- 函数重载允许同一个函数名可以有多个不同的参数列表或不同的返回类型,从而实现了同名函数的多态性。
- 虚函数允许子类重写父类中的同名函数,并且在运行时根据对象的实际类型来确定调用的是哪个版本的函数,从而实现了运行时多态性。
深拷贝和浅拷贝有何区别?
-
浅拷贝(Shallow Copy):
- 浅拷贝是将一个对象的引用复制给另一个对象,而不是复制对象本身。这意味着两个对象共享同一块内存空间,它们指向相同的内存地址。
- 当对其中一个对象进行修改时,另一个对象也会受到影响,因为它们指向相同的数据。换句话说,浅拷贝只复制了对象的表面结构,没有复制对象内部的数据。
-
深拷贝(Deep Copy):
- 深拷贝是将一个对象的所有内容复制给另一个对象,包括对象内部的所有数据。这意味着在内存中会创建一个新的对象,并且将原对象中的所有数据复制到新对象中。
- 由于深拷贝会复制对象的所有数据,因此修改其中一个对象不会影响到另一个对象,它们在内存中彼此独立,互不影响。
总的来说,浅拷贝只复制对象的表面结构,而深拷贝则复制对象的所有内容,包括内部的数据。 在实际编程中,需要根据具体的需求来选择合适的拷贝方式。
友元在C++中的含义是什么?
- 被声明为某个类的友元函数后,就可以访问该类的私有成员和受保护成员。
- 声明友元函数的语法是在类的内部使用
friend
关键字声明
struct和class在C++中的区别是什么?
-
成员访问权限默认值:
- 对于
struct
,默认的成员访问权限是公有(public),这意味着在结构体中声明的成员默认是公有的,可以被外部访问。 - 而对于
class
,默认的成员访问权限是私有(private),这意味着在类中声明的成员默认是私有的,只能在类的内部访问。
- 对于
-
其他细微差异:
- 在继承方面,
struct
默认继承是公有继承(public inheritance),而class
默认继承是私有继承(private inheritance)。 - 在内存布局上,
struct
和class
的成员排列顺序一致,但是class
可能会有额外的对齐规则。 - 从语义上来说,
struct
更偏向于数据结构,而class
更偏向于面向对象编程,但这并不是绝对的,因为两者都可以定义成员函数和数据成员。
- 在继承方面,
CPU、MPU、MCU、SOC、SPOC有何区别?
-
CPU(Central Processing Unit):
- CPU是中央处理单元的缩写,是计算机中的主要处理器,负责执行程序指令、处理数据以及控制计算机的操作。
-
MPU(Microprocessor Unit):
- MPU是微处理器单元的缩写,通常用于指代嵌入式系统中的微处理器,如用于控制、数据处理和通信等任务的芯片。
-
MCU(Microcontroller Unit):
- MCU是微控制器单元的缩写,是一种集成了处理器核心、存储器、输入输出接口和定时器等功能模块的芯片。它通常被用于嵌入式系统中,用于控制各种设备和系统。
-
SoC(System on Chip):
- SoC是片上系统的缩写,指的是将所有计算机或电子系统的核心功能集成到一个芯片上的解决方案。这包括处理器核心、内存、输入输出接口、通信接口等。
-
SPOC(Secure Processor On Chip):
- SPOC是片上安全处理器的缩写,是一种专门用于安全计算、数据保护和安全通信的芯片或处理器。
嵌入式系统基于ROM和基于RAM的运行方式有何区别?
-
基于ROM的运行方式:
- 在基于ROM的嵌入式系统中,程序和数据通常存储在只读存储器(ROM)中,这些数据是预先固化在芯片中的,用户无法修改。
- 程序的执行速度相对较慢,因为数据只能从ROM中读取,不能进行实时修改。
- 这种方式通常用于那些程序和数据稳定不变、对性能要求不高、对存储容量有限的应用场景,如嵌入式控制器、嵌入式系统固件等。
-
基于RAM的运行方式:
- 在基于RAM的嵌入式系统中,程序和数据存储在随机存储器(RAM)中,用户可以动态地读取、写入和修改数据。
- 程序的执行速度相对较快,因为数据可以直接在RAM中读取和修改,不需要额外的访问时间。
- 这种方式通常用于那些对性能要求较高、需要动态修改程序和数据、对存储容量要求较大的应用场景,如智能手机、平板电脑、嵌入式系统的操作系统等。
linux中断和异常有何区别?
-
中断(Interrupt):
- 中断是由外部设备或其他处理器发出的信号,用于通知 CPU 某个事件已经发生,需要 CPU 进行相应的处理。
- 中断可以是硬件中断(Hardware Interrupt)或软件中断(Software Interrupt)。
- 硬件中断是由硬件设备(如时钟、键盘、鼠标等)发送给 CPU 的信号,用于通知 CPU 进行相应的处理。处理硬件中断的程序称为中断处理程序(Interrupt Service Routine,ISR)。
- 软件中断是由程序中的特殊指令(如系统调用)或软件发出的信号,用于请求操作系统进行某种服务或操作。
-
异常(Exception):
- 异常是由 CPU 在执行指令时检测到的一种错误或不寻常情况,它们可能是由程序错误、非法指令、内存访问错误等引起的。
- 异常可以是故障(Fault)、陷阱(Trap)或终止(Abort)的形式。
- 故障是一种可以被修复的异常,例如缺页异常,操作系统可以尝试加载所需的页面。
- 陷阱是一种由程序有意触发的异常,通常用于实现系统调用或软件调试。
- 终止是一种无法修复的异常,通常会导致程序的终止或操作系统的崩溃。
中断和DMA的区别是什么?
-
中断(Interrupt):
- 中断是一种异步事件处理机制,用于处理来自外部设备或其他处理器的通知或信号。
- 当外部设备需要 CPU 的处理或者发生了特定的事件时,会发送中断信号给 CPU,CPU 将暂时中止当前的执行流,跳转到中断处理程序(ISR)执行相应的处理。
- 中断是一种响应式的机制,通常由外部设备或其他部件触发,CPU 需要响应并执行相应的处理逻辑,然后恢复到原来的执行流程。
-
直接内存访问(DMA,Direct Memory Access):
- DMA 是一种数据传输机制,允许外部设备直接访问内存而无需 CPU 的介入。
- 当需要大量数据的传输时,传统的方式是由 CPU 通过 I/O 指令来处理数据传输,这会占用 CPU 的大量时间和资源。
- 使用 DMA,外部设备可以直接与内存进行数据交换,而无需通过 CPU,从而提高数据传输的效率和性能。
- DMA 控制器负责管理数据传输的过程,包括内存地址、数据量、传输方向等,减轻了 CPU 的负担,让 CPU 可以同时处理其他任务。
总的来说,中断是一种事件驱动的处理机制,用于响应外部设备的信号或事件;而DMA是一种数据传输机制,用于实现高效的数据传输而无需 CPU 的持续介入,从而提高了系统的性能和效率。两者在功能和应用场景上有所不同,但都是计算机系统中重要的数据传输和处理机制。