操作系统基础校招面试题
操作系统基础校招面试题
本文面向刚开始学习操作系统、同时需要准备面试的读者。每道题先解释它是什么、用来解决什么问题,大家可以根据文档理解该知识点,理解后,尝试口述出来问题答案
本章先回答三个基础问题:操作系统为什么存在,应用程序如何请求操作系统服务,以及 CPU 为什么需要区分用户态和内核态。
理解这些内容后,后面的进程、内存、文件系统和 I/O 才能串联起来。
1. 什么是操作系统?它有哪些主要功能?
打开音乐播放器,选择一首歌,再一边听歌一边编辑文档,看起来只是几个简单操作。
但计算机内部至少要解决这些事情:从存储设备找到歌曲,把内容放进内存,让播放器获得 CPU 时间处理音频,再把处理后的声音送给音频设备;与此同时,还不能让编辑器的工作被播放器完全挡住。
应用负责“要做什么”,但 CPU、内存和设备由谁分配、不同程序怎样互不干扰,不能全靠应用各自决定。
操作系统就是负责这些公共管理工作,并为应用提供运行环境的系统软件。
假如没有操作系统,会多出哪些工作
先认识几种硬件:CPU:执行指令,内存临时保存正在使用的代码和数据,磁盘或其他存储设备长期保存文件,声卡、网卡等负责特定输入输出。
只有这些硬件,还不会自动出现“打开歌曲文件”的能力。
程序需要知道内容放在哪里,怎样向控制器发命令,什么时候数据准备好了。如果同时运行两个程序,还得协调谁用哪些内存、谁先使用 CPU,以及一个程序出错后怎样避免破坏另一个。
没有操作系统的裸机程序确实可以存在,例如某些简单嵌入式设备,但上述工作仍要由程序自己或其他基础软件承担。操作系统的价值,是把许多程序都需要的能力集中起来管理,避免应用反复处理同样的底层问题。
顺着播放音乐,看它怎样工作
- 建立运行环境,系统启动播放器,为这次运行管理内存、打开文件等资源。这种运行实例叫进程;其中实际推进工作的执行流程叫线程,后面会分别展开。
- 安排 CPU, 播放器需要解码音频,编辑器需要处理输入,系统安排可运行线程使用 CPU。多个任务可以交替执行,在多核条件下也可能同时执行。
- 提供文件访问。 播放器指定歌曲路径,系统负责查找文件、检查权限、取得内容。如果数据已在缓存中,不必每次都访问存储设备。
- 协调音频输出。 播放器或所用媒体库把压缩歌曲处理成音频数据,再通过音频接口、可能的系统服务和驱动送往设备。操作系统并不因此包办所有音乐解码算法。
- 管理等待与保护。 某个任务等待数据时,CPU 可以处理其他工作;内存和权限机制限制程序不应进行的访问。程序退出后,相应资源被回收。
这条过程串起了操作系统的主要功能:处理器管理、内存管理、文件管理、设备管理,以及通信、同步和安全保护。
操作系统不等于一定拥有桌面。没有图形界面的服务器仍有操作系统;内核是承担核心管理与保护的部分,完整系统通常还有库、工具和服务,其中不少运行在用户态。
严格说 Linux 是内核,日常“Linux 系统”通常指包含用户空间软件的完整环境。
面试回答
操作系统是管理硬件资源、为应用提供运行环境的系统软件。它负责安排 CPU、分配和保护内存、管理文件与设备,并提供通信和安全机制,让多个程序能够协调运行。它还把底层能力组织成文件、虚拟地址空间、Socket 等接口,减少应用对硬件细节的依赖。内核是其核心,但操作系统不等于一定拥有图形界面,也不意味着所有组成部分都运行在内核态。
2. 操作系统有哪些类型?
操作系统的分类,首先是在区分它优先满足什么需求,而不是列举几个产品名称。
处理整夜账单的系统、让多人交互操作的系统、控制设备按时动作的系统,即使都在管理 CPU 和内存,设计重点也不一样。
同一台计算机,面对不同目标
批处理操作系统关注把一批工作自动做完。例如夜间提交大量账单任务,系统按规则处理并保存结果,不要求用户在每一步参与。减少人工等待、提高吞吐量是重点,但用户不一定能立即得到交互反馈。
分时操作系统关注多个用户或任务都能及时得到服务。例如多人通过终端使用同一台服务器,系统让不同任务轮流获得执行机会,一个人等待输入时,其他人仍可以工作。用户感到服务连续,并不意味着单个 CPU 同一瞬间真的执行了所有任务。
实时操作系统关注结果是否赶在截止时间前产生。例如控制任务要求在规定时间内完成采样、计算和输出,平均很快却偶尔严重超时,仍可能不合格。硬实时强调在规定条件下满足严格时间约束,软实时允许一定超时但会损害服务质量。“实时”不只是速度快。
前三种分类主要体现任务组织和时间要求。下面几种则更多从使用环境或系统组织出发。
运行在哪里、怎样组织,也可以成为分类标准
网络操作系统强调连接、远程访问和资源共享。多台计算机能够交换文件、访问远程服务,但通常仍保留各自独立的管理身份。
分布式操作系统进一步尝试协调多台机器,向用户提供更统一的系统和资源视图,隐藏部分机器分布细节。应用部署了多个服务、组成分布式业务,并不自动说明底层使用的是分布式操作系统。
嵌入式操作系统面向特定设备或用途,例如路由器、家电控制器。它可能重点控制体积、功耗和成本,也可能强调可靠性或实时性。嵌入式不一定都是硬实时,一台设备也可能不运行完整操作系统。
为什么不能把每个产品只放进一类?
这些分类标准不同,所以可以重叠。一个嵌入式系统可以同时具备网络能力和实时要求;通用服务器系统既能提供交互式服务,也能运行批处理任务。
Windows、Linux、macOS 是具体系统或系统家族的称呼,不是理论分类的全部。判断一个具体系统是否满足硬实时等要求,还需要看配置、调度、负载和时间保证,不能因为能运行某类任务,就认为已经具备对应保证。
面试回答
操作系统可以按不同维度分类。按任务处理和时间要求,有批处理、分时与实时系统,分别重视自动处理、交互响应和截止时间;按环境与组织,还可讨论网络、分布式和嵌入式系统。这些类别不互斥,同一系统可以具备多类特征。
Windows、Linux、macOS 是产品或家族,不是完整分类;实时也不能简单理解为运行速度快。
3. 什么是用户态和内核态?二者如何切换?
内核态:又指管态、系统态,是操作系统管理程序执行时机器所处的状态。具有较高特权,能执行一切指令。
用户态:是用户程序执行时机器所处的状态,特权较低,只能执行规定内的指令,访问指定的部分。
总结:内核态特权高,可以横行霸道,拥有一切特权,执行指令,访问内存。用户态特权小,只能执行部分指令,访问部分内存。
程序计算 1 + 2 和 读取一个文件,都需要 CPU 执行指令,但涉及的权限不同。
计算自己的数据通常不会影响别人;
读取文件却需要检查权限,还可能操作多个程序共同使用的设备。如果应用能任意修改这些管理规则,一个程序的错误就可能破坏整个系统。
因此,CPU 提供不同的执行权限,操作系统利用它们隔开普通应用与核心管理代码。
用户态、内核态描述 CPU 当前执行代码时的权限状态,不是两个固定进程。
同一个线程怎样进入和离开内核
以应用读取已经打开的普通文件为例:
- 线程在用户态准备文件描述符、接收缓冲区和读取长度。
- 通过系统调用入口请求读取。CPU 与内核入口代码配合,保存必要状态,转入受保护的内核执行环境。
- 内核检查参数、访问权限等条件,寻找数据。
- 如果数据已在页缓存中,内核通常可完成读取,直接返回应用。
- 如果需要等待设备,线程可能阻塞,调度器让其他任务使用 CPU。数据准备好后,原线程重新获得运行机会,继续完成系统调用。
- 返回用户态,应用从调用之后继续,并检查实际读取长度或错误。
第 4 步可能只有权限状态变化,没有换任务;第 5 步才可能同时涉及调度。因此,进入内核不等于切换进程。也不是应用代码自己获得了任意高权限,而是内核代码接手规定的请求。
操作系统内核并不只有“系统调用”这一种执行入口。应用程序可以通过系统调用主动请求内核服务;CPU 执行指令发生缺页、除零等异常时,也会自动进入对应的内核异常处理程序;网卡、磁盘、时钟等硬件产生中断时,CPU 同样会转去执行内核的中断处理程序。
因此进入内核,本质上是 CPU 将控制权转交给内核中的某个处理程序,并不一定意味着发生了用户态到内核态的切换。
CPU 执行指令遇到异常,例如缺页,会进入内核处理程序;设备或时钟产生中断,也可以让内核接手。中断可能发生在 CPU 已经执行内核代码时,此时没有用户态到内核态的转换。
面试回答
用户态和内核态是 CPU 执行代码时的不同权限状态。应用通常在用户态运行,需要受保护服务时,通过系统调用进入内核,由内核检查并处理,再返回应用。异常和中断也会进入内核处理程序。模式切换不等于进程切换:同一线程可以进入内核后直接返回,只有发生等待或调度等情况时,才可能换到其他任务。
4. 应用程序如何通过操作系统访问硬件?什么是系统调用?
我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能咋办呢?那就需要系统调用了!
也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。
应用要读取一首歌,通常只需表达“打开哪个文件、从哪里读取、需要多少内容”,不应直接决定存储控制器执行哪些命令。否则每种设备都需要应用自行适配,还可能让一个错误请求破坏其他程序的数据。
操作系统因此提供受控的服务入口:应用说明需求,内核检查并执行适当操作。系统调用就是用户程序请求内核服务的接口,除了读写文件,也包括创建进程、建立通信和管理内存等。
可以把常见的系统调用场景总结成下面几类:
文件操作
程序需要打开、读取、写入或关闭文件时,会通过系统调用请求内核完成。
例如:open()、read()、write()、close()。
进程管理
程序需要创建新进程、执行另一个程序、等待子进程结束时,需要系统调用。
例如:fork()、execve()、wait()、exit()。
内存管理
程序申请或映射内存时,需要内核修改进程的虚拟地址空间。
例如:mmap()、munmap()、brk()。
网络通信
程序创建 Socket、连接服务器、收发网络数据,本质上都需要内核网络协议栈参与。
例如:socket()、connect()、accept()、send()、recv()。
进程间通信
不同进程之间通过管道、共享内存等方式交换数据,也需要内核协调。
例如:pipe()、shmget() 等。
获取或修改系统信息
比如获取当前进程 ID、查询时间、修改文件权限等。
例如:getpid()、clock_gettime()、chmod()。
可以简单总结为一句话:
凡是应用程序需要访问文件、网络、进程、内存或其他受操作系统管理的资源时,通常都需要通过系统调用进入内核,请求操作系统代为完成。
先把函数调用和系统调用分开
普通函数调用可以一直在应用的执行环境中完成,例如计算一个字符串长度。系统调用则要进入内核提供的受保护入口,请内核处理当前应用不能自行决定的事情。
开发者往往仍写成函数形式,例如 read。运行库在背后按照平台约定准备请求编号、参数等,再进入内核;处理结束后,把结果或错误以应用接口约定的方式交回来。函数写法相似,不表示执行边界相同。参见 Linux 系统调用与库封装说明。
应用并非每做一步都要进入内核
普通计算、已经建立映射后的正常内存访问,通常不需要逐次系统调用。printf 等库函数也可能先在用户态格式化和缓冲,之后才通过写入接口输出;一次库调用可能触发零次、一次或多次系统调用。
高性能场景还可能使用受控的共享内存、设备映射或用户态驱动,把一部分工作留在用户态,但通常需要系统先配置访问权限与资源,不代表可以任意绕过保护。
至于 CPU 怎样进入内核,第 5 题会展开。这里只需知道入口由架构和 ABI 规定,不能把所有 Linux 系统调用都写成同一种旧式中断指令。
面试回答
应用通常通过运行库或 API 表达需求,再经系统调用请求内核服务。内核检查参数和权限,使用文件系统、网络栈等组件处理,必要时由驱动控制设备。系统调用是受保护的服务边界,不等于普通库函数;缓存命中可能不访问设备,普通计算和已映射内存访问也不必每一步进入内核。
5. 为什么 Linux 程序通常不能直接在 Windows 上运行?
把 Linux 上编译好的程序复制到 Windows,哪怕两台机器都是 x86-64,它通常也不能直接运行。原因是 CPU 只负责执行指令,而启动并运行一个程序,还需要操作系统和运行库遵守一整套约定。
可以把问题拆成两个阶段:系统怎样把程序启动起来,以及启动后程序向谁请求服务。
第一关:系统怎样看懂这个程序文件
可执行文件不只是一串指令,还包含哪些内容应装入内存、从哪里开始执行、需要哪些库等信息。负责读取这些信息并建立运行环境的组件叫加载器。
Linux 常用 ELF,Windows 常用 PE。两种格式对这些信息的组织方式不同。把文件名改成 .exe,只改了名字,不会把内部格式转换成 PE。Windows 的加载约定见 Microsoft PE 格式说明。
即使额外工具解决了文件解析,也只是过了第一关。
第二关:运行过程中使用哪套接口
假设程序要读取 a.txt,它通常会调用某个库接口,最终请求操作系统服务。Linux 程序依赖的调用方式、库符号和系统语义,不会仅因 Windows CPU 能执行相同加法指令就自动出现。
这里需要认识两个词:
- API是程序员使用的接口,例如某个函数需要哪些参数、完成什么工作。
- ABI是编译后二进制之间的约定,例如参数放在哪些寄存器、数据如何布局、怎样调用并链接其他组件。
源代码里两个函数看起来相近,不代表编译后遵循同一 ABI。Linux 程序可能需要特定版本的 glibc 等运行库,Windows 程序则可能依赖相应 DLL 和平台服务;路径、权限及进程行为也可能不同。
即使静态链接带上了部分库代码,程序仍可能依赖 Linux 系统调用,并不能因此天然跨操作系统运行。
有哪些办法补齐运行环境
如果有源代码,可以适配平台接口后重新编译;若源代码和依赖本就可移植,这一步可能较直接,但不能保证任何项目只换编译器就成功。
兼容层可以实现或转换目标程序需要的接口;虚拟机可以运行相应客户机操作系统。WSL 是在 Windows 环境中运行 Linux 程序的一种方案,但其架构也有区别:WSL 1 使用兼容转换思路,WSL 2 使用实际 Linux 内核及受管理的虚拟化环境,不能统称为“Windows 内核直接执行所有 Linux 系统调用”。参见 Microsoft WSL 版本对比。
容器通常共享其运行环境的内核,因此容器本身并不自动解决不同内核 ABI 的差异。Windows 上运行 Linux 容器时,往往另有 Linux 内核环境提供支持。
面试回答
Linux 二进制通常不能直接在 Windows 运行,不仅因为 ELF 与 PE 格式不同,还因为 ABI、系统调用、动态库和运行环境不同。CPU 指令集相同,只解决部分指令执行条件,不保证程序能被正确加载并获得服务。一般需要适配后重新编译,或通过兼容层、WSL、虚拟机等补齐环境,改扩展名或只使用容器都不能自动解决问题。
6. 中断、异常有什么区别?
中断:又称为外中断,是系统正常功能的一部分,使系统停止当前运行的进程而执行其他进程。然后操作系统处理完该任务之后,再来处理中断前的命令。
异常:是由错误引起的,如文件损坏、进程越界等。
CPU 在正常情况下会按照程序的指令顺序执行,但在执行过程中,有时需要暂时停止当前流程,转而让操作系统内核进行处理。
例如,网卡收到数据时会产生中断;程序访问尚未加载到内存中的页面时会触发缺页异常;程序需要读取文件、创建进程时,则会主动发起系统调用。
这些情况最终都可能让 CPU 转去执行内核代码,但触发原因并不相同,分别属于中断、异常和系统调用。
下面来看具体的例子
例如,CPU 正在计算订单总价,这时网卡恰好收到了一个数据包。网卡收到数据这件事与 CPU 当前正在执行哪条指令没有直接关系,因此这种由网卡、磁盘、时钟等外部设备触发的事件,通常称为外部中断。它相对于当前指令来说是异步发生的。
另一种情况是,CPU 正在执行一条内存访问指令,但在访问过程中发现对应的虚拟内存页面当前不可用,于是产生缺页异常。这个异常正是由当前这条指令触发的,因此属于同步异常。
所以可以简单理解为:中断通常来自当前指令之外,而异常通常是执行当前指令时直接产生的。

这里的“同步”和“异步”描述的是事件与当前指令之间的关系,并不是在讨论 I/O 操作是否阻塞。
| 场景 | 发生原因 | 常见分类 |
|---|---|---|
| 时钟到期、网卡通知数据到达 | 外部事件 | 中断 |
| 整数除法遇到零除数 | 当前指令不能正常完成 | 异常 |
| 访问页面需要内核补齐映射 | 当前访存触发检查 | 异常 |
| 程序执行系统调用入口 | 主动请求内核服务 | 程序主动发起系统调用 |
异常不一定是程序错误
合法页面可能只是尚未分配或尚未读入。内核处理后,程序可以重试原指令,继续运行;如果是非法地址,内核通常向程序报告错误。因此,同样进入异常处理,结果可能是“补齐条件后继续”,也可能是“无法继续执行”。
“陷入内核”常泛指通过受控入口转移控制权。但 trap 在不同教材、CPU 架构中的定义并不统一,不能把中断、异常、陷阱看成全球统一、互不重叠的三类。
例如 x86 会把某些异常细分为 fault、trap、abort,区别涉及报告位置和恢复方式;系统调用也可以使用专门的指令路径。初学时先掌握来源、与当前指令的关系及恢复方式,再学习具体架构术语。
面试回答
中断通常来自设备或时钟,与当前指令没有直接因果关系;异常由当前指令触发,例如除零和缺页。异常不一定是错误,合法缺页可以处理后继续执行。“陷入”常描述程序通过受控入口进入内核,但 trap 的严格含义依体系结构而异,不能把所有系统调用机械归为同一种 CPU 异常。
7. 什么是操作系统内核?
桌面、终端和设置程序属于操作系统环境,但不是内核。关闭图形桌面后,服务器仍能处理网络请求、运行任务和读写文件,因为负责资源分配与保护的核心代码还在运行。
在计算机中,内核是一个计算机程序,它是操作系统的核心,可以控制操作系统中所有的内容。内核通常是在 boot loader 装载程序之前加载的第一个程序。
这里还需要了解一下什么是 boot loader。
boot loader 又被称为引导加载程序,能够将计算机的操作系统放入内存中。在电源通电或者计算机重启时,BIOS 会执行一些初始测试,然后将控制权转移到引导加载程序所在的
主引导记录(MBR)。
内核负责管理执行、内存和设备,并落实保护规则。 它需要较高权限,同时必须避免应用随意修改这些规则。
为什么需要这样一个核心
编辑器读取文件时,需要判断权限、找到数据、协调设备;等待期间还要把 CPU 分配给其他任务。桌面或 Shell 可以表达“打开文件”的意图,但不能绕过这些管理机制。
内核因此负责进程与线程调度、内存管理、文件和设备服务、中断处理与安全检查。更换用户界面,并不要求把这些规则全部重写。
面试回答
内核是负责调度、内存、文件、设备和保护机制的操作系统核心,不等于桌面或完整操作系统。
阅读导航




