嵌入式笔试面试刷题(day12)

简介: 嵌入式笔试面试刷题(day12)

前言

本篇文章继续带大家来刷题,秋招也快到了大家坚持刷题,相信大家都可以找到好工作。

一、SDK是什么

SDK是软件开发工具包(Software Development Kit)的缩写,它是一组用于开发软件应用程序的工具、库和文档的集合。SDK通常由软件开发平台或框架提供,旨在帮助开发人员更轻松、高效地创建应用程序。

SDK通常包含以下主要组件:

1.API(Application Programming Interface):SDK会提供一组API,即一组定义了如何与某个特定平台、操作系统或服务进行交互的编程接口。

2.工具和实用程序:SDK通常提供用于开发、构建、调试和测试应用程序的工具和实用程序,例如编译器、调试器、模拟器、测试框架等。

3.示例代码和示例应用程序:SDK通常提供一些示例代码和示例应用程序,以帮助开发人员理解和使用API和工具。

4.文档和教程:SDK通常提供详细的文档和教程,包括API文档、编程指南、开发者手册等,以帮助开发人员了解如何使用SDK中的组件和工具。

二、内存分配最小单位

当涉及内存分配时,有两个相关的概念需要区分:内存分配单位和内存分配函数。

1.内存分配单位:内存分配单位是指内存管理的最小单位。在操作系统中,内存通常以页面(Page)为最小分配单位。页面的大小通常是4KB或者更大,具体取决于操作系统和硬件。

2.内存分配函数:内存分配函数是编程语言提供的用于动态分配内存的函数。其中,malloc函数是C语言和C++语言中的一个常用内存分配函数。malloc函数通过请求操作系统为程序分配指定大小的连续字节的内存块。

区别:内存分配单位与内存分配函数之间的区别在于:

1.内存分配单位:指操作系统和硬件层面上内存管理的最小单位,通常是页面大小,如4KB。操作系统会根据页面的大小进行内存管理和分配,以支持虚拟内存等机制。

2.内存分配函数:是编程语言提供的接口,用于在程序运行时请求操作系统分配一定大小的内存。其中,malloc函数是一种常见的内存分配函数,它按字节为单位动态分配内存块。

3.内存分配函数(如malloc)使用字节作为分配单位,但在操作系统层面,内存管理以页面为最小分配单位。这是由于操作系统需要管理和映射页面,而应用程序通常只需要通过内存分配函数来分配适当大小的内存块,以满足其数据结构或算法的需求。

三、内联函数和宏函数的区别

内联函数和宏函数是两种在编程中实现函数展开的方式,它们有一些区别,包括以下几个方面:

1.语法和类型安全性:

内联函数是C++语言提供的一种函数声明方式,使用关键字inline进行声明。内联函数具有函数的语法结构,支持参数的类型检查和类型安全。内联函数可以像普通函数一样进行重载,可以包含复杂的语句和控制流程。

宏函数则是预处理器进行文本替换的方式,使用宏定义声明。宏函数是简单的文本替换,没有函数的语法结构,不进行类型检查。宏函数展开时只是进行简单的文本替换,可能会导致意外的副作用。

2.展开方式和底层实现:

内联函数在编译期间进行函数展开,将函数的实际代码嵌入到调用处,避免了函数调用的开销。内联函数的展开是由编译器控制的,并且可以对其进行内联优化。

宏函数在预处理阶段进行文本替换,将宏的实际文本替换到调用处。宏函数没有函数调用的开销,但可能会产生较大的代码体积。

3.命名空间和作用域:

内联函数位于命名空间中,具有自己的作用域。可以通过静态链接在多个源文件之间共享。内联函数也可以在类中定义,对于类的成员函数,可以在类声明中直接定义内联函数。

宏函数没有自己的作用域和命名空间,它是简单的文本替换。宏定义的作用范围是全局的,可能会导致命名冲突或不可预期的副作用。

4.调试和错误信息:

内联函数在调试过程中可以单步执行和观察,可以提供更好的调试信息和错误提示,因为内联函数是编译器处理的一部分。

宏函数无法单步执行和观察,可能会导致调试和错误定位困难,因为宏函数只是简单的文本替换。

总的来说,内联函数比宏函数更安全、更灵活,可以进行类型检查,有自己的作用域和命名空间,提供更好的调试和错误信息。而宏函数则更接近于简单的文本替换,没有类型检查和作用域的概念,可能会产生不可预期的副作用。因此,推荐在C++中使用内联函数,除非特殊情况下需要使用宏函数的特性和灵活性。

四、空指针和野指针的区别

1.空指针(Null Pointer):

空指针表示指针不指向任何有效的对象或函数。在C和C++中,空指针通常使用特殊的值0来表示,也可以使用宏定义NULL或C++11引入的nullptr关键字。

空指针指向的是一个已知的特殊地址,该地址被保留给表示空指针的目的。对空指针进行解引用操作(如访问指针指向的内存)将产生未定义的行为。

2.野指针(Dangling Pointer):

野指针是指指针变量持有一个无效的、未定义的内存地址。野指针可能是一个已被释放的内存地址,或者指向还未分配给有效对象的内存区域。

野指针是一种危险的编程错误,使用野指针可能导致程序崩溃、内存错误和不可预测的行为。

五、访问野指针和空指针会发生什么

访问野指针:

可能导致程序崩溃或异常终止。

可能读取到不可预测或无效的数据,导致意外结果。

可能引发安全漏洞,如信息泄露或缓冲区溢出。

访问空指针:

可能导致段错误(Segmentation Fault)或空指针异常,终止程序。

可能出现未定义的行为,造成程序行为无法预测。

六、C++面向对象的三要素

1.封装(Encapsulation):

封装是一种将数据和操作捆绑在一起的机制,以创建一个类(Class)。类将数据(成员变量)和操作(成员函数)组合在一起,可以隐藏实现的细节,只暴露必要的接口给外部使用。

封装通过访问控制(public、private、protected)提供了对数据的保护,使得数据只能通过类的接口进行访问和修改。

封装可以实现信息隐藏和数据隔离,提高代码的可维护性、灵活性和安全性。

2.继承(Inheritance):

继承是一种机制,允许一个类(称为子类或派生类)基于另一个类(称为父类或基类)建立,并且可以继承父类的属性和行为。

通过继承,子类可以重用父类的代码,避免代码的重复编写,并且可以扩展或修改父类的行为。

继承实现了类之间的关系,如“is-a”关系,其中子类可以视为父类的一种类型。

3.多态(Polymorphism):

多态是指能够使用基类(父类)的指针或引用来引用派生类(子类)对象,并根据上下文自动选择正确的方法执行。

多态允许使用相同的接口处理不同的对象,通过重写(覆盖)基类的虚函数实现特定类的行为。

多态提高了代码的可扩展性和灵活性,使得程序可以根据不同的对象类型采取适当的动作。

七、if(0 == x) 和 if(x == 0)

一般来说很多人习惯使用if(x == 0),但是也有一些人是使用if(0 == x)的,使用if(0 == x)这种写法能够保证 == 不被误写为 = 导致出现错误。

八、二维数组地址是否连续

一个二维数组的地址在内存中是连续的。二维数组在内存中以行主序(row-major order)连续存储其元素。

int arr[3][4];

在内存中,它会以如下的方式连续存储:

arr[0][0]   arr[0][1]   arr[0][2]   arr[0][3]   arr[1][0]   arr[1][1]   arr[1][2]   arr[1][3]   arr[2][0]   arr[2][1]   arr[2][2]   arr[2][3]

因此,二维数组的地址是连续的,可以通过指针算术运算来访问数组中的元素。

例如,可以使用指针来访问二维数组中的元素:

int arr[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int *ptr = &arr[0][0];
for (int i = 0; i < 12; i++) {
    printf("%d ", *(ptr + i));
}

以上代码将打印出连续存储的二维数组的元素值:

1 2 3 4 5 6 7 8 9 10 11 12

所以,对于连续分配的二维数组,其地址是连续的,可以通过指针算术运算来访问和操作二维数组的元素。

总结

本篇文章就讲解到这里。


相关文章
|
6月前
|
SQL Java
java面试题笔试常见选择题大全含答案
java面试题笔试常见选择题大全含答案
|
2月前
|
C语言
经典面试题:嵌入式系统中经常要用到无限循环,怎么样用C编写死循环呢
在嵌入式系统开发中,无限循环常用于持续运行特定任务或监听事件。使用C语言实现死循环很简单,可以通过`while(1)`或`for(;;)`的结构来编写。例如:`while (1) { /* 循环体代码 */ }`,这种写法明确简洁,适用于需要持续执行的任务或等待中断的场景。
|
5月前
|
传感器 芯片
嵌入式通信协议全解析:SPI、I²C、UART详解(附带面试题)
通信是指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递。从广义上来说,通信是指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法、任意媒质,将信息从某方准确安全地传送到另方。在出现电波传递通信后,通信被单一解释为信息的传递,是指由一地向另一地进行信息的传输与交换,其目的是传输消息。通信方式包括利用“电”来传递消息的电信,这种通信具有迅速、准确、可靠等特点,且几乎不受时间、地点、空间、距离的限制,因而得到了飞速发展和广泛应用。
1211 0
|
7月前
|
存储 算法 C语言
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
71 5
|
7月前
|
网络安全 Windows
PentestGPT-V0(1),网络安全面试题2024笔试
PentestGPT-V0(1),网络安全面试题2024笔试
|
7月前
|
算法 Java C++
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
|
7月前
|
消息中间件 前端开发 Java
java面试刷题软件kafka和mq的区别面试
java面试刷题软件kafka和mq的区别面试
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?