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

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

前言

本篇文章继续讲解嵌入式面试笔试刷题,希望大家能够继续坚持哦。

一、进程和线程的区别

1.定义:进程是程序的执行实例,是资源分配和调度的单位;线程是进程中的执行单元,是CPU调度和执行的基本单位。

2.资源占用:每个进程都有独立的内存空间、文件描述符和其他系统资源,进程之间的通信需要使用进程间通信(IPC)机制。而线程是在进程内部共享进程的资源,包括内存空间和文件描述符等,线程之间可以直接共享数据,因此线程间通信更加方便。

3.调度和切换:在操作系统中,进程是一个独立的单位,由调度器进行调度和切换。切换进程时需要保存和恢复进程的上下文,开销较大。而线程是进程内部的执行单元,线程的切换开销比进程的切换小很多。因此,多线程的程序在切换和调度上更加高效。

4.执行并发性:由于进程之间具有独立的内存空间和资源,不同进程间的执行是相互独立的,可以同时执行不同的任务。而线程共享进程的资源,线程之间执行可以并发或并行,可以更充分利用系统的多核处理器提高执行效率。

5.容错性:由于进程的独立性,一个进程的崩溃不会影响其他进程的执行。而线程是在进程内部执行,一个线程的错误可能会导致整个进程崩溃。

二、共享内存的原理

通过将一块内存区域映射到多个进程的地址空间,使得这些进程可以直接访问和共享相同的内存内容,从而实现数据的交互和共享。

三、中断有传参和返回值吗

中断通常不直接支持传参和返回值。这是因为中断是一种异步事件处理机制,它的执行是由硬件或者特定的事件触发,并且不像函数调用那样由程序主动发起。

四、串口数据帧格式

1.起始位

2.数据位

3.奇偶校验位

4.停止位

五、进程通信有几种,哪几种需要借助内核

1.方式

1.管道

2.命名管道

3.共享内存

4.信号量

5.消息队列

6.套接字

7.信号

2.需要借助内核的

需要借助内核的通信方式包括管道、共享内存、信号量、消息队列和套接字。

六、flash有哪几种类型

1.NOR Flash:NOR Flash 主要用于存储程序代码和执行读操作。它提供了快速的随机访问速度和较长的擦除寿命。NOR Flash 的特点是可以按字节进行读写操作,且具有较低的擦除和写入时间。因此,它适用于需要频繁执行读操作的应用,如嵌入式系统中的引导程序和固件存储。

2.NAND Flash:NAND Flash 主要用于大容量存储和数据存储,例如移动设备和固态硬盘(SSD)。相对于 NOR Flash,NAND Flash 具有较高的存储密度和较低的成本,但访问速度较慢,通常以页为单位进行读写操作。NAND Flash 的特点是具有较高的数据传输速率和较高的擦写寿命,适用于需要大容量存储和频繁写操作的应用。

3.eMMC:eMMC(Embedded Multi-Media Card)是一种内嵌式多媒体卡,集成了 NAND Flash 存储芯片和控制器。它通常用于嵌入式设备和移动设备中,提供了可靠的存储解决方案。eMMC 的特点是小巧便携、低功耗,且支持随机读写操作。

4.UFS:UFS(Universal Flash Storage)是一种新型的高速闪存存储标准,可提供更快的数据传输速率和更高的性能。它被广泛用于高端移动设备和存储解决方案中。UFS 具有较低的延迟、更高的带宽和更好的可靠性,支持高速读写操作。

七、指针的本质是什么

指针的本质是一个变量,但它存储的是一个内存地址,而不是实际的数据。

指针的存储方式取决于计算机架构和编程语言。在大多数计算机体系结构中,内存地址通常使用二进制表示,并根据特定的内存寻址方案进行存储。指针变量本身也是存储在内存中的,它占用一定的内存空间,用于存储目标地址。

八、指针和数组的区别

1.数据结构:数组是一种数据结构,用于存储一系列相同类型的数据元素。它是连续的内存块,每个元素在内存中的位置相邻。指针是一个变量,存储了一个内存地址,它可以指向任何数据类型的数据,包括数组。

2.内存分配:数组在定义时需要指定长度或者使用动态内存分配(如C++中的new运算符),编译器在编译时为数组分配指定长度的内存空间。指针可以通过赋值操作指向任何有效的内存地址,包括数组的首地址或者其他内存区域。

3.大小和访问:数组的大小是固定的,一旦定义后不能改变。通过索引可以直接访问数组中的元素,索引从0开始。指针本身的大小取决于系统的位数(通常为4字节或8字节),通过解引用操作符(*)可以访问指针指向的内存位置,可以通过指针的算术运算来访问数组中的不同元素。

4.数组名 vs. 指针变量:在C语言中,数组名实际上是指向数组首元素的指针常量。它可以被隐式转换为指针类型,所以可以使用指针的方式对数组进行操作。然而,数组名本身不能被赋值或修改。指针变量可以重新赋值来指向不同的内存位置。

5.参数传递:作为函数参数传递时,数组通常以指针的形式传递。在函数内部,无法得知数组的长度,因此需要额外的参数来传递数组的长度信息。指针作为函数参数可以提供灵活的传递和访问内存的能力。

九、使用宏定义交换变量不能使用中间变量

#include <stdio.h>
#define SWAP(a, b)  do { \
                        (a) = (a) ^ (b); \
                        (b) = (a) ^ (b); \
                        (a) = (a) ^ (b); \
                    } while(0)
int main() {
    int x = 10;
    int y = 20;
    printf("Before swap: x = %d, y = %d\n", x, y);
    SWAP(x, y);
    printf("After swap: x = %d, y = %d\n", x, y);
    return 0;
}

在上面的示例中,我们定义了一个名为 SWAP 的宏函数,它使用了位异或运算符(^)来交换数据。通过连续进行三次异或操作,可以实现两个变量的值互换,而无需使用临时变量。

需要注意的是,宏函数使用 do { … } while(0) 结构来确保宏定义中的多个语句都能够正常运行,并且可以在条件语句中使用宏函数。

这样,在调用 SWAP(x, y) 时,宏展开后的代码会执行三次位异或运算,实现 x 和 y 的交换。最终,x 的值变成了原来 y 的值,y 的值变成了原来 x 的值。

十、do { … } while(0) 结构的作用

在宏定义的使用中使用 do { … } while(0) 结构的主要目的是为了确保宏定义在展开时可以正常工作。

宏定义本质上是文本替换,编译器在代码中找到宏的调用,并将其展开为宏定义中的代码。如果宏定义只是简单地展开为一行代码,那么在某些情况下可能会导致意想不到的行为。

使用 do { … } while(0) 结构可以解决以下两个问题:

1.语法上的问题:如果宏定义只是一个单独的语句,并且在某些情况下需要在条件语句中使用宏,例如:if (condition) MACRO(x); else …。这样的话,如果宏定义展开后只是一个语句,那么编译器在展开后的输出代码中会导致语法错误。通过使用 do { … } while(0) 结构,可以确保宏定义受到分号(;)的约束,从而避免语法错误。

2.嵌套问题:如果宏定义展开后包含多个语句,并且在代码中使用了条件语句、循环等结构,例如:

#define MACRO(x) do { \
                   statement1; \
                   if (condition) { \
                       statement2; \
                   } \
               } while(0)

如果宏定义展开后的代码中缺少大括号,那么在使用该宏时嵌套结构可能会导致逻辑错误。通过使用 do { … } while(0) 结构,宏定义中的多个语句都被包含在一个块作用域中,确保了这些语句的正常执行。

总结来说,使用 do { … } while(0) 结构是为了保证宏定义在展开时在语法和逻辑上都是正确的。这种结构在宏定义中是一种常用的技巧,以确保宏在使用时能够像正常的代码一样正常工作。

总结

本篇文章就讲解到这里,下篇文章继续讲解。


相关文章
|
5月前
|
SQL Java
java面试题笔试常见选择题大全含答案
java面试题笔试常见选择题大全含答案
|
1月前
|
C语言
经典面试题:嵌入式系统中经常要用到无限循环,怎么样用C编写死循环呢
在嵌入式系统开发中,无限循环常用于持续运行特定任务或监听事件。使用C语言实现死循环很简单,可以通过`while(1)`或`for(;;)`的结构来编写。例如:`while (1) { /* 循环体代码 */ }`,这种写法明确简洁,适用于需要持续执行的任务或等待中断的场景。
|
6月前
|
存储 算法 安全
【刷题】 leetcode 面试题 01.06 字符串压缩
来看效果: 非常好!!!过啦!!!
63 5
【刷题】 leetcode 面试题 01.06 字符串压缩
|
6月前
|
算法
【刷题】 leetcode 面试题 08.05.递归乘法
递归算法是一种在计算机科学和数学中广泛应用的解决问题的方法,其基本思想是利用问题的自我相似性,即将一个大问题分解为一个或多个相同或相似的小问题来解决。递归算法的核心在于函数(或过程)能够直接或间接地调用自身来求解问题的不同部分,直到达到基本情况(也称为基础案例或终止条件),这时可以直接得出答案而不必再进行递归调用。
69 4
【刷题】 leetcode 面试题 08.05.递归乘法
|
4月前
|
传感器 芯片
嵌入式通信协议全解析:SPI、I²C、UART详解(附带面试题)
通信是指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递。从广义上来说,通信是指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法、任意媒质,将信息从某方准确安全地传送到另方。在出现电波传递通信后,通信被单一解释为信息的传递,是指由一地向另一地进行信息的传输与交换,其目的是传输消息。通信方式包括利用“电”来传递消息的电信,这种通信具有迅速、准确、可靠等特点,且几乎不受时间、地点、空间、距离的限制,因而得到了飞速发展和广泛应用。
972 0
|
6月前
|
存储 算法 C语言
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
从C语言到C++_39(C++笔试面试题)next_permutation刷力扣
61 5
|
6月前
|
网络安全 Windows
PentestGPT-V0(1),网络安全面试题2024笔试
PentestGPT-V0(1),网络安全面试题2024笔试
|
6月前
|
算法 Java C++
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
刷题两个月,从入门到字节跳动offer丨GitHub标星16k+,美团Java面试题
|
6月前
|
消息中间件 前端开发 Java
java面试刷题软件kafka和mq的区别面试
java面试刷题软件kafka和mq的区别面试
|
6月前
|
监控
嵌入式面试题:数据传输单工,半双工,全双工之间的区别
嵌入式面试题:数据传输单工,半双工,全双工之间的区别
73 0