0、操作系统基础

厨子大约 17 分钟操作系统操作系统基础原创面试题技术解析程序员

操作系统面试题

什么是操作系统?

操作系统是管理硬件和软件的一种应用程序。操作系统是运行在计算机上最重要的一种 软件,它管理计算机的资源和进程以及所有的硬件和软件。它为计算机硬件和软件提供了一种中间层,使应用软件和硬件进行分离,让我们无需关注硬件的实现,把关注点更多放在软件应用上。

通常情况下,计算机上会运行着许多应用程序,它们都需要对内存和 CPU 进行交互,操作系统的目的就是为了保证这些访问和交互能够准确无误的进行。

操作系统的主要功能

一般来说,现代操作系统主要提供下面几种功能:

  • 进程管理: 进程管理的主要作用就是任务调度,在单核处理器下,操作系统会为每个进程分配一个任务,进程管理的工作十分简单;而在多核处理器下,操作系统除了要为进程分配任务外,还要解决处理器的调度、分配和回收等问题
  • 内存管理:内存管理主要是操作系统负责管理内存的分配、回收,在进程需要时分配内存以及在进程完成时回收内存,协调内存资源,通过合理的页面置换算法进行页面的换入换出
  • 设备管理:根据确定的设备分配原则对设备进行分配,使设备与主机能够并行工作,为用户提供良好的设备使用界面。
  • 文件管理:有效地管理文件的存储空间,合理地组织和管理文件系统,为文件访问和文件保护提供更有效的方法及手段。
  • 提供用户接口:操作系统提供了访问应用程序和硬件的接口,使用户能够通过应用程序发起系统调用从而控制硬件,实现想要的功能。
功能模块
核心职责
关键机制
典型场景
进程管理
1. 任务调度(CPU时间片分配)
2. 多核处理器负载均衡
3. 进程创建/销毁/同步
- 时间片轮转(Round-Robin)
- 优先级调度
- 多级反馈队列(MLFQ)
单核CPU分时运行多个程序;服务器多核任务分配
内存管理
1. 内存分配与回收
2. 虚拟内存管理
3. 页面置换优化
- 分页/分段机制
- LRU/FIFO页面置换算法
- 内存映射(MMAP)
程序运行时动态申请内存;解决内存不足问题
设备管理
1. 设备驱动控制
2. 并行/串行I/O调度
3. 即插即用(PnP)支持
- 中断机制
- DMA传输
- 设备文件抽象(如Linux `/dev`)
打印机队列管理;USB设备热插拔识别
文件管理
1. 存储空间分配
2. 文件系统组织
3. 权限与保护机制
- FAT/NTFS/EXT4文件系统
- 索引节点(inode)
- 日志式写入(Journaling)
磁盘文件读写;多用户共享文件权限控制
用户接口
1. 提供系统调用(Syscall)
2. 图形界面(GUI)或命令行(CLI)
- Shell解释器(Bash/Zsh)
- WinAPI/POSIX标准
- 桌面环境(如GNOME/KDE)
用户通过终端命令或点击图标启动应用程序

🌟 软件访问硬件的几种方式

软件访问硬件其实就是一种 I/O 操作,软件访问硬件的方式,也就是 I/O 操作的方式有哪些。

硬件在 I/O 上大致分为并行和串行,同时也对应串行接口和并行接口。

随着计算机技术的发展,I/O 控制方式也在不断发展。选择和衡量 I/O 控制方式有如下三条原则:

  1. 数据传送速度足够快,能满足用户的需求但又不丢失数据;
  2. 系统开销小,所需的处理控制程序少;
  3. 能充分发挥硬件资源的能力,使 I/O 设备尽可能忙,而 CPU 等待时间尽可能少。

根据以上控制原则,I/O 操作可以分为四类:

  • 直接访问:直接访问由用户进程直接控制主存或 CPU 和外围设备之间的信息传送。直接程序控制方式又称为忙/等待方式。
  • 中断驱动:为了减少程序直接控制方式下 CPU 的等待时间以及提高系统的并行程度,系统引入了中断机制。中断机制引入后,外围设备仅当操作正常结束或异常结束时才向 CPU 发出中断请求。在 I/O 设备输入每个数据的过程中,由于无需 CPU 的干预,一定程度上实现了 CPU 与 I/O 设备的并行工作。

上述两种方法的特点都是以 CPU 为中心,数据传送通过一段程序来实现,软件的传送手段限制了数据传送的速度。接下来介绍的这两种 I/O 控制方式采用硬件的方法来显示 I/O 的控制

  • DMA 直接内存访问:为了进一步减少 CPU 对 I/O 操作的干预,防止因并行操作设备过多使 CPU 来不及处理或因速度不匹配而造成的数据丢失现象,引入了 DMA 控制方式。
  • 通道控制方式:通道是独立于 CPU 的专门负责输入输出控制的处理机,它控制设备与内存直接进行数据交换。有自己的通道指令,这些指令由 CPU 启动,并在操作结束时向 CPU 发出中断信号。
I/O控制方式
工作原理
CPU参与度
数据传输速度
直接访问
用户进程直接控制I/O操作,CPU轮询设备状态(忙等待)
100%
最慢
中断驱动
设备就绪后向CPU发送中断信号,CPU处理中断
中等
较慢
DMA
由DMA控制器直接管理设备与内存的数据传输,完成后通知CPU
极低

通道控制
专用I/O处理器(通道)独立执行I/O程序,完全解放CPU
几乎不参与
最快

🌟 操作系统的主要目的是什么?

操作系统是一种软件,它的主要目的有三种

  • 管理计算机资源,这些资源包括 CPU、内存、磁盘驱动器、打印机等。
  • 提供一种图形界面,就像我们前面描述的那样,它提供了用户和计算机之间的桥梁。
  • 为其他软件提供服务,操作系统与软件进行交互,以便为其分配运行所需的任何必要资源。

操作系统的种类有哪些?

常见的操作系统只有三种:Windows、macOS 和 Linux

🌟 为什么 Linux 系统下的应用程序不能直接在 Windows 下运行?

这是一个老生常谈的问题了,在这里给出具体的回答。

其中一点是因为 Linux 系统和 Windows 系统的格式不同,格式就是协议,就是在固定位置有意义的数据。Linux 下的可执行程序文件格式是 elf,可以使用 readelf 命令查看 elf 文件头。

而 Windows 下的可执行程序是 PE 格式,它是一种可移植的可执行文件。

还有一点是因为 Linux 系统和 Windows 系统的 API 不同,这个 API 指的就是操作系统的 API,Linux 中的 API 被称为 系统调用,是通过 int 0x80 这个软中断实现的。而 Windows 中的 API 是放在动态链接库文件中的,也就是 Windows 开发人员所说的 DLL ,这是一个库,里面包含代码和数据。Linux 中的可执行程序获得系统资源的方法和 Windows 不一样,所以显然是不能在 Windows 中运行的。

对比项
Linux 系统
Windows 系统
可执行文件格式
ELF (Executable and Linkable Format)
PE (Portable Executable)
查看工具
`readelf`、`objdump`
`dumpbin`(Visual Studio 工具)、PE 查看器
文件结构特点
分段结构(如 `.text`、`.data`、`.rodata`),支持动态链接(`.so` 文件)
分节结构(如 `.text`、`.rdata`),依赖动态链接库(DLL 文件)
系统 API 实现
通过 `int 0x80` 或 `syscall` 指令触发系统调用(如 `read`, `write`)
通过 DLL 导出 API(如 `kernel32.dll`、`user32.dll` 中的函数)
资源访问方式
直接调用内核提供的系统调用接口
调用 Windows API 封装层,再由内核处理
兼容层原理
WINE 通过将 Linux 系统调用转换为 Windows API 调用实现部分兼容
WSL 通过虚拟化层模拟 Linux 内核行为
典型限制
依赖 Linux 特有的库(如 `glibc`)和路径结构(如 `/proc`)
依赖 Windows 注册表、DLL 版本和运行时环境(如 Visual C++ Redistributable)

🌟什么是用户态?什么是内核态?

内核态:又指管态、系统态,是操作系统管理程序执行时机器所处的状态。具有较高特权,能执行一切指令。

用户态:是用户程序执行时机器所处的状态,特权较低,只能执行规定内的指令,访问指定的部分。

总结:内核态特权高,可以横行霸道,拥有一切特权,执行指令,访问内存。用户态特权小,只能执行部分指令,访问部分内存。

另外用户不能直接调用内核态程序,只能通过中断,由中断系统将其转入操作系统内的相应程序。

特权指令:只能有操作系统内核部分使用,不允许用户直接使用的指令,I/0 指令。设置中断屏蔽指令、清内存指令,存储保护指令,设置时钟指令。

中断和异常

中断:又称为外中断,是系统正常功能的一部分,使系统停止当前运行的进程而执行其他进程。然后操作系统处理完该任务之后,再来处理中断前的命令。

异常:是由错误引起的,如文件损坏、进程越界等。

为什么称为陷入内核?

如果把软件结构进行分层说明的话,应该是这个样子的,最外层是应用程序,里面是操作系统内核。

应用程序处于特权级 3,操作系统内核处于特权级 0 。如果用户程序想要访问操作系统资源时,会发起系统调用,陷入内核,这样 CPU 就进入了内核态,执行内核代码。至于为什么是陷入,我们看图,内核是一个凹陷的构造,有陷下去的感觉,所以称为陷入。

🌟 用户态和内核态是如何切换的?

所有的用户进程都是运行在用户态的,但是我们上面也说了,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有 系统调用,而能够执行系统调用的就只有 操作系统

一般用户态到内核态的转换我们都称之为 trap 进内核,也被称之为 陷阱指令(trap instruction)

它们的工作流程如下:

  • 首先用户程序会调用 glibc 库,glibc 是一个标准库,同时也是一套核心库,库中定义了很多关键 API。
  • glibc 库知道针对不同体系结构调用 系统调用 的正确方法,它会根据体系结构应用程序的二进制接口设置用户进程传递的参数,来准备系统调用。
  • 然后,glibc 库调用 软件中断指令(SWI) ,这个指令通过更新 CPSR 寄存器将模式改为超级用户模式,然后跳转到地址 0x08 处。
  • 到目前为止,整个过程仍处于用户态下,在执行 SWI 指令后,允许进程执行内核代码,MMU 现在允许内核虚拟内存访问
  • 从地址 0x08 开始,进程执行加载并跳转到中断处理程序,这个程序就是 ARM 中的 vector_swi()
  • 在 vector_swi() 处,从 SWI 指令中提取系统调用号 SCNO,然后使用 SCNO 作为系统调用表 sys_call_table 的索引,调转到系统调用函数。
  • 执行系统调用完成后,将还原用户模式寄存器,然后再以用户模式执行。
步骤
用户态操作
内核态操作
关键点说明
1
用户程序调用 `glibc` 库的 API(如 `read()`)
-
`glibc` 封装系统调用,提供标准化接口
2
`glibc` 根据体系结构设置参数(如 x86-64 用 `rax` 存系统调用号)
-
参数传递规则由 ABI(应用二进制接口)定义
3
执行陷阱指令(x86: `syscall`/`int 0x80`,ARM: `SWI`,RISC-V: `ecall`)
CPU 切换到内核模式(修改 CPSR/EFLAGS 寄存器)
硬件自动完成模式切换,跳转到固定中断向量地址(如 x86: `0x80`,ARM: `0x08`)
4
-
MMU 启用内核内存映射,允许访问内核空间
内核页表包含用户空间映射,但用户页表无内核映射
5
-
执行中断处理程序(x86: `system_call()`,ARM: `vector_swi()`)
通过系统调用号索引 `sys_call_table` 找到具体实现
6
-
内核执行系统调用(如 `sys_read()`),访问硬件或核心资源
期间可能阻塞(如等待磁盘 I/O)
7
-
内核将结果存入寄存器/栈,恢复用户态寄存器
错误码通常通过 `errno` 机制返回
8
CPU 切换回用户模式,继续执行 `glibc` 返回后的代码
-
用户程序通过返回值判断成功/失败

关键概念对比

对比维度
用户态 (User Mode)
内核态 (Kernel Mode)
权限级别

受限权限(无法直接访问硬件)
特权模式(可执行任意CPU指令)
内存访问
仅能访问用户空间内存
可访问全部物理内存和IO设备
触发方式
通过调用库函数(如`glibc`)
通过陷阱指令(`syscall`/`int 0x80`)主动进入
典型场景
应用程序逻辑运算
硬件交互、进程调度、中断处理

什么是内核?

在计算机中,内核是一个计算机程序,它是操作系统的核心,可以控制操作系统中所有的内容。内核通常是在 boot loader 装载程序之前加载的第一个程序。

这里还需要了解一下什么是 boot loader

boot loader 又被称为引导加载程序,能够将计算机的操作系统放入内存中。在电源通电或者计算机重启时,BIOS 会执行一些初始测试,然后将控制权转移到引导加载程序所在的主引导记录(MBR)

Linux 操作系统启动流程

什么是系统调用?

介绍系统调用之前,我们先来了解一下用户态和系统态。

根据进程访问资源的特点,我们可以把进程在系统上的运行分为两个级别:

  1. 用户态(user mode) : 用户态运行的进程或可以直接读取用户程序的数据。
  2. 系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。

说了用户态和系统态之后,那么什么是系统调用呢?

我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能咋办呢?那就需要系统调用了!

也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。

这些系统调用按功能大致可分为如下几类:

  • 设备管理。完成设备的请求或释放,以及设备启动等功能。
  • 文件管理。完成文件的读、写、创建及删除等功能。
  • 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信。完成进程之间的消息传递或信号传递等功能。
  • 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
对比维度
用户态 (User Mode)
内核态 (Kernel Mode)
权限级别

受限权限(无法直接访问硬件)
特权模式(可执行任意CPU指令)
内存访问
仅能访问用户空间内存
可访问全部物理内存和IO设备
触发方式
通过调用库函数(如`glibc`)
通过陷阱指令(`syscall`/`int 0x80`)主动进入
典型场景
应用程序逻辑运算
硬件交互、进程调度、中断处理