面试题总结 ---Linux篇
1.请你谈谈const是什么?它的作用是什么?
const 用来修饰变量、指针、函数参数、函数返回值、类成员函数,表示只读,不能被修改,在编译期做检查。
const 用于限定只读,编译阶段校验,防止误修改。
① 修饰变量:变量只读,定义时初始化;
② 修饰指针:分清常量指针和指针常量;
const int * p ; //指针指向的内容不可以修改,指针本身可以修改
int *const p ; //指针本身不能修改,指针指向的内容可以修改
③ 修饰函数形参:保护传入数据不被修改;
④ 修饰类成员函数:承诺该函数不修改对象成员; void exit() const
2.什么是进程间的共享内存通信?原理是什么?
操作系统在物理内存开辟一块内存,多个进程通过系统调用把这块物理内存映射到自己的虚拟地址空间。进程读写,直接操作物理内存,数据不需要在内核缓冲区和用户缓冲区之间拷贝,所以速度最快。
缺点:本身不带同步互斥机制,需要我们自己加信号量 / 互斥锁保护,防止并发读写冲突。
3.共享内存的使用流程是什么?
shmget:创建 / 获取共享内存段,得到 shmid
shmat:挂载,把共享内存映射到当前进程虚拟地址,返回起始地址
进程直接读写这块内存
shmdt:卸载,断开映射(不删除内存)
shmctl:控制,删除共享内存段(所有进程 detach 之后才真正销毁)
4.shmdt 和 shmctl 的区别是什么
shmdt 会让当前进程断开共享内存和虚拟地址空间的映射,不会打删除标记,其他的进程还是可以对这个共享内存进行创建和搭载的;
shmctl会给这块共享内存打上“待删除”的标记,不会立马释放这块内存,但是等其他的进程shmdt,和这块内存脱离映射的时候,这块内存会被释放;
但是shmctl一旦打上待删除的标记,其他的进程就没有办法再搭载这块共享内存了。
5.共享内存的生命周期
共享内存不属于任何一个进程,就算创建它的进程退出了,它还在,直到调用 shmctl 删除,或者系统关机,共享内存才会被释放。
6.什么是进程间通信?
因为每个进程都有自己的虚拟地址空间,相互隔离,不能直接进行读写,ipc就是一套让不同进程之间可以进行交流,同步信息的机制。
7.信号量的作用是什么?
做同步资源计数,意思就是内核会把共享内存进行划分,为了防止有超过划分数量的进程来访问共享内存,内核创建了信号量只有拿到这个计数器的进程才能访问共享内存,没有拿到信号量的进程要在共享内存外阻塞等待。
8.什么是二元信号量?
二元信号量就是os将共享内存划分成了一块,信号量对应的计数器的个数是一,二元信号量的本质就是琐。
9.同步和异步的区别是什么?
同步的意思就是需要进程主动去调用函数,如read,sem_wait等事件/数据到达发生才能继续往后走,不达到这种情况就卡再这里。
异步的意思是信号的到来,不需要进程主动去等待、查询。进程正常运行,信号随时可能突然抵达,打断当前正在执行的代码,转而执行信号处理函数。
10.什么是信号?
信号也是进程间通信方式的一种,但是信号这种通信能力很弱,只能携带少量数据,如信号数字,不能传递大块数据,进程a可以调用kill通知进程bA 进程可以调用kil了():出事了,你处理一下。这就是进程间的消息传递,所以归类为 IPC。
11.既然共享内存最快,是不是所有场景都优先用共享内存?
不是。共享内存没有自带同步互斥,多进程读写会出现竞态,必须搭配信号量,增加开发复杂度。如果只是简单少量单向数据传输,管道开发更简单稳定。
12.什么是域间socket?
Unix 域 socket 是本机的进程间通信方式,通过内核 socket 文件完成通信,不走网卡,数据只在内核内存流转。API 和网络 socket 一样,性能高于本机 TCP。它的特色是可以在进程之间传递文件描述符。
13.有名管道和域间套接字的区别?
FIFO 仅仅是一个单向的字节流通道,半双工;Unix 域 socket 是一套完整套接字通信,支持全双工、面向连接,还可以传递 fd,能力比 FIFO 强很多。
14.如果两个进程,一个采集数据、一个绘图,你选什么 IPC,为什么?
我选择共享内存+信号量的方式,采集进程进行读,绘图进程进行写,这样大数据传递可以减少拷贝,并且信号量可以控制读写同步,防止读到半帧脏数据。
15.进程处理信号的三种方式
忽略(执行优先级更高的事件)、默认处理(执行系统默认的处理方式)、捕获(执行自定义的函数)
16.什么是volatile关键字?

17.volatile 在多线程里有用吗?
在 C++11 之前,多线程下只能防止编译器缓存,但是无法防止 CPU 乱序执行;C++11 之后多线程一般用std::atomic,不推荐 volatile 做多线程同步。volatile 更多用于嵌入式、硬件寄存器场景。
18.什么是可重入函数?什么是不可重入函数?
可重入函数指函数被中断后,再次调用不会出错,只使用局部栈变量,不使用全局、static 变量。 不可重入函数使用静态 / 全局共享变量,一旦中途被打断再次调用,数据会错乱。
在 Linux 中,信号是异步触发的,信号处理函数内部只能调用可重入(信号安全)的函数,如果调用不可重入函数,容易造成程序崩溃、数据异常。
可重入函数和线程安全没有关系,意思就是函数是线程安全的是要靠加琐的,和它是不是可重入函数没有关系,而线程安全的函数也不一定就是可重入函数
19.什么是线程?
线程是进程更细粒度的划分,进程将自己的代码进行划分,分给多个线程,这些线程共享进程的虚拟地址空间、页表的资源;在 Linux 系统中,线程是用进程模型模拟实现的,内核不单独设计 TCB 线程控制块,线程和进程统一使用task_struct结构体描述。同一个进程里的多个线程各自拥有一份独立的task_struct,这些task_struct共享进程的虚拟地址空间,仅拷贝必要私有信息(线程 ID、线程状态、优先级、独立栈与上下文)。内核复用进程原有的调度、等待队列、切换逻辑,不需要单独为线程开发一套新机制,降低开发和维护成本。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)