自学内容网 自学内容网

面试(六)

一. 根据 int foo[8]的定义,int foo[8]={0,1,2,3,4,5,6,7};*((int*)((char*)&foo+sizeof(int)))的值是?

&foo:这是数组foo的地址,其类型是int(*)[8] (指向包含8个int的数组的指针)

[char*]&foo:里我们将&foo的类型转换为char*.这是因为char类型通常被用作字节操作的基础类型,其大小为1字节(在大多数系统上)。

(char*)&foo + sizeof(int):这里我们将char*指针向前移动了sizeof(int)个字节。这相当于跳过了数组foo的第一个元素(因为sizeof(int)通常等于一个整数的大小)。

(int*)((char*)&foo + sizeof(int)):现在我们将上述得到的char*指针再次转换为int*类型。

*((int*)((char*)&foo + sizeof(int))):最后,我们解引用这个int*指针,即访问数组中第二个元素的值。

二. RT-Thread 支持邮箱和消息队列

在RT-Thread中,邮箱的长度为4字节。。而消息队列(Message Queue)则能够接收不固定长度的消息,消息的长度可以根据实际应用需求设定。

RT-Thread的邮箱和消息队列设计时就考虑到了线程安全和中断上下文的使用

RT-Thread的邮箱和消息队列都支持多种等待策略,包括按线程优先级等待和按先进先出(FIFO)方式获取消息。

三. bin文件或hex文件包含哪些部分

包含RO段和RW段,RO段中保存了Code和RO-data,RW段中保存了RW-data

四. 在RT-Thread中,主线程和空闲线程属于系统线程,用户编写的打印线程和处理中断服务的线程属于用户线程

五. 在Linux中,request请求和bio的关系?

通常一个 bio 对应一个 I/O 请求。I/O 调度算法可将连续的 bio 合并成一个请求,每个 request 里面会有多个 bio。所以,一个请求可以包含多个 bio。所以请求和bio的关系是一对多.

六. 在Linux中,块设备的结构?

包括三部分,段:由若干个块组成,是Linux内存管理机制中一个内存页或者内存页的一部分。

块:由Linux制定对内核或文件系统等数据处理的基本单位。通常由1个或多个扇区组成

扇区:块设备的基本单位,通常在512字节到32768字节之间,默认512字节

七. RISC和CISC的区别

RISC:精简指令集,执行的是等长精简指令集,可以同时执行多条指令。

CISC:复杂指令集,处理的是不等长指令集,执行单一指令集需要比较多的处理工作

八. 说说对MMU和TLB的理解

MMU是计算机系统的一种硬件设备,主要用于处理内存管理的任务,负责将程序中的虚拟地址映射到物理内存中的实际地址,以及管理内存访问权限。

TLB是MMU中的一种高速缓存,用于加速虚拟地址到物理地址的转换过程

九. volatile关键字作用?

1. 防止编译器过度优化

#include <stdio.h>

int global_var = 0;

void increment() {
    // 没有使用volatile,编译器可能优化掉这个操作
    global_var++;
}

int main() {
    for (int i = 0; i < 1000000; i++) {
        increment();
    }
    
    printf("Final value of global_var: %d\n", global_var);
    
    return 0;
}

比如这一段代码,当没加volatile修饰变量的时候,编译器可能不会真正执行global_var++的操作,因为从编译器的角度来看,global_var的值在整个循环中都没有变化的必要,如果我们要运行验证的话,需要使用编译器的优化级别(如GCC的-O2-O3

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

宏函数由预处理器在编译时进行文本替换,而内联函数是由编译器在编译时将函数体代码插入到调用处。

内联函数提供类型检查,而宏函数不提供。

内联函数具有正常的作用域规则,而宏函数则没有作用域限制

十一. 虚拟地址怎么转换成物理地址

虚拟地址转换成线性地址,通过MMU的页表将线性地址转换为物理地址

十二. 简述TCP三次握手的过程

第一次握手:客户端创建传输控制块,然后向服务器发出连接请求报文(将标志位syn置1,随机产生一个序列号seq=x),客户端接着进入SYN_SENT状态

第二次握手服务器收到请求报文,回复确认报文(SYN和ACK置1,ack=x+1,随机产生序列号seq=y)

第三次握手:检查ack是否等于x+1,ACK是否等于1,是则发送确认报文,将ACK置1,ack=y+1,序列号seq=x+1

十三. 简述TCP四次挥手的过程

第一次挥手:客户端发送FIN报文

第二次挥手:服务器确认FIN报文

第三次挥手:服务器发送FIN报文

第四次挥手:客户端确认FIN报文

十四. 为什么三次握手的时候ack=seq+1

告诉发送方收到了发出的同步信息

十五. 引用和指针区别

引用时变量的别名,指针是指向一段地址的变量

十六. 动态库和静态库的区别

1.扩展名不一样,静态库的扩展名一般为“.a”或“.lib”;动态库的扩展名一般为“.so”或“.dll”

2.链接时间不一样,静态库是在编译时链接,而动态库是在运行时链接

3.速度不一样,静态库的速度更快

十七. 异步IO和同步IO区别?

异步IO在调用一个功能时,得不到结果就去做下一件事,有结果后回调通知给调用者

同步IO在调用一个功能时,这个功能没有结束就一直等待它结束,必须做完一件事后再做下一件事,没有结果该调用就不会返回

十八. linux的进程状态?

七大详细状态

1. 运行态(正在运行或在运行队列中等待)

2. 就绪态

3. 中断睡眠状态(休眠中, 受阻, 在等待某个条件的形成或接受到信号)

4. 不可中断睡眠状态(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)

5. 僵尸态(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)

6. 暂停态

7. 终止态

五大最基本状态:创建、就绪、运行、阻塞、终止。
 

十九. 常见的操作系统进程调度策略有哪些?

时间片轮转,高优先级优先,先来先服务,短作业优先

二十. 逻辑地址、线性地址、物理地址、总线地址、虚拟地址的区别

逻辑地址:与内存段相关偏移的部分

线性地址=逻辑地址+基地址

物理地址=总线地址

虚拟地址=由内存管理单元(MMU)虚拟映射出来的地址

二十一. 死锁的必要条件是什么?

互斥、请求和保持条件、不可剥夺、环形链

二十二. 什么是优先级翻转,如何避免优先级翻转?

由于共享资源规则,导致高优先级线程被低优先级线程阻塞。解决办法:1、优先级天花板:将申请某资源的线程的优先级提升到最高;2、优先级继承:将占用资源的进程的优先级提升,与其他申请进程的优先级相同,等释放后再恢复。
 


原文地址:https://blog.csdn.net/m0_66746512/article/details/140072517

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!