银行技术面操作系统基础:用户态、进程与同步
- 轮次
- 技术面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 什么是用户态和内核态?两者有什么区别?
- 什么是系统调用?按功能可以分成哪几类?
- 如何从用户态切换到内核态?
- 并发与并行、阻塞与非阻塞、同步与异步分别是什么?
- 线程、进程、协程有什么区别?
- PCB 是什么?它包含哪些内容、起什么作用?
- 进程和线程的创建、撤销过程中发生了什么?
- 进程有哪几种状态?它们之间如何转换?
- 常见的进程调度算法有哪些?分别适合什么场景?
- 进程同步有哪些方式?信号量和管程分别怎么用?
- 进程间通信有哪些方式?
《参考解析》
用户态、内核态与系统调用
划分两个特权级的目的是保护:内核态可以执行特权指令、访问全部内存与硬件,用户态只能碰自己地址空间里的数据。用户程序要读写文件、创建进程、申请内存,都必须通过系统调用请内核代办,系统调用按功能大致分成设备管理、文件管理、进程控制、进程通信、内存管理五类。进入内核态有三条路径:系统调用是用户程序主动发起的(read、fork,底层靠一条特殊中断指令,如 Linux 的 int 0x80 或 syscall);异常是被动的,比如缺页;外设中断也是被动的,比如磁盘读写完成。面试常接着追问「系统调用为什么慢」——除了保存寄存器、切换内核栈,真正贵的是上下文切换带来的缓存与 TLB 失效,所以高性能场景会尽量用批量接口或 mmap、io_uring 这类减少陷入次数的机制。
进程、线程与协程
进程是资源分配的基本单位,线程是调度的基本单位,协程则是用户态自己调度的执行单元。三者最该讲清的是开销差异:线程切换要陷入内核、保存寄存器与栈、可能触发 TLB 与缓存失效;同进程内的线程共享地址空间,通信直接读写内存即可,跨进程就得走 IPC。协程把调度搬到用户态,切换只是用户栈与少量寄存器的搬运,所以能撑起十万级并发,代价是阻塞式系统调用会拖住整个线程,必须配合非阻塞 IO 与多路复用。银行的面子题里常见「为什么线程多了反而慢」,答案要落到上下文切换成本与锁竞争上。
PCB 与进程状态机
PCB 是进程存在的唯一标识,操作系统靠它感知进程:里面记录了进程描述信息(PID、名字)、处理机状态(寄存器、程序计数器,中断时保存现场)、调度信息(状态、优先级、阻塞原因)、资源与通信信息、以及队列链接指针。进程的五种状态是创建、就绪、运行、阻塞、结束,其中就绪与运行之间互相转换(时间片用完回就绪、被调度进运行),运行态等待资源时进入阻塞,资源到位后回到就绪而不是直接运行。创建进程的流程是申请空白 PCB、初始化描述信息、分配资源与地址空间、插入就绪队列;撤销时要先终止它的子孙进程、归还资源、再从队列里摘除,实际就是对进程树做一次后序遍历。
同步与互斥
同步解决的是「协作的先后顺序」,互斥解决的是「同一时刻只有一个能进临界区」,这两个概念在面试里经常被混着问。临界区的实现要满足空闲让进、忙则等待、有限等待、让权等待四条。信号量是一个整型变量配 P/V 两个原子操作:P 把信号量减一,减到负数就阻塞等待;V 加一并唤醒等待者。初值为 1 时它退化成互斥量,初值为 N 时就是限流用的资源计数。管程把互斥和条件变量封装在语言/库层面,进入管程自动加锁,用 wait() 释放锁并阻塞、signal() 唤醒对方,比裸写信号量不容易出错,Java 的 synchronized + wait/notify 就是典型形态。还要能指出管程的一个约束:同一时刻只能有一个进程在管程内,条件不满足时必须让出管程,否则其他进程永远进不来。
进程间通信方式的取舍
管道(匿名管道)用于有亲缘关系的进程,单向字节流,写满会阻塞;命名管道(FIFO)去掉了亲缘关系限制;消息队列以消息为单位、有类型,能避免字节流的粘包问题;共享内存把同一块物理内存映射到两个进程的地址空间,是拷贝次数最少、速度最快的方式,但必须自己配信号量做同步;信号量本身也可以当纯粹的同步手段;信号用于事件通知,携带的信息量极小;Socket 是唯一能跨主机的方案。答题时按「是否需要跨主机、要不要双向、拷贝几次、谁来同步」这四条对比,比逐个背定义清楚得多。
进程调度算法
按适用系统分成两类记。批处理系统看吞吐:先来先服务简单但短作业等得久,短作业优先能压低平均周转时间却会让长作业饿死,高响应比优先用「等待时间 + 服务时间」的比值折中;交互式系统看响应:时间片轮转保证公平、响应快,优先级调度要配老化避免低优先级饿死,多级反馈队列把「短作业优先 + 时间片轮转」结合起来,新进程进高优先级队列给短时间片,用不完就下沉,是通用操作系统里最实用的折中。