1. 进程和线程的区别?创建线程的代价比创建进程小吗?
- 进程是资源分配和调度的基本单位;线程是 CPU 调度的基本单位。
- 进程有独立的地址空间,线程共享进程地址空间。
- 创建/销毁进程开销大,线程开销小。
- 是的,因为不需要分配独立地址空间。
2. 线程共享哪些资源?
- 地址空间(代码段、数据段、堆等)
- 打开的文件
- 全局变量
- 信号处理器
- 不共享:栈、寄存器、程序计数器。
3. 用户线程与内核线程区别?
- 用户线程(User-level):用户态管理,切换快,但内核不可见,一个阻塞会导致整个进程阻塞。
- 内核线程(Kernel-level):内核直接调度,支持多核并行,但切换开销大。
4. 进程的五种状态?哪些事件会引起新的进程创建?
新建(new)、就绪(ready)、运行(running)、阻塞(waiting)、终止(terminated)。
- 系统初始化
- 用户请求(如执行程序)
- 创建系统调用(fork)
- 批处理作业调度
5. 进程上下文切换是什么?线程上下文切换呢?
保存和恢复进程的 CPU 环境(寄存器、PC、内存映射等),开销大。
保存/恢复线程的寄存器、栈指针等,不涉及地址空间切换,开销小。
6. CPU 如何调度进程? 常见调度算法?
- 调度目标:公平性、高吞吐量、低响应时间。
- 常见调度算法:
- 先来先服务 (FCFS)
- 思想:谁先到就先执行,按进入就绪队列的顺序来。
- 优点:简单、公平,易于实现。
- 缺点:长作业会让后面的短作业等待很久(“护航效应”)。
- 短作业优先 (SJF)
- 思想:优先调度执行时间短的作业。
- 优点:平均等待时间最短,效率高。
- 缺点:需要预知运行时间;对长作业不公平,可能一直得不到执行。
- 高响应比优先 (HRRN)
- 思想:综合考虑等待时间和运行时间,公式:
- 响应比=(等待时间+运行时间)/运行时间
- 优点:兼顾长短作业,避免短作业独占 CPU。
- 缺点:实现稍复杂,需要动态计算。
- 时间片轮转 (RR)
- 思想:每个进程分配一个时间片,时间片到没执行完就放回队列,轮流调度。
- 优点:公平,适合分时系统,响应快。
- 缺点:时间片过小 → 频繁切换开销大;过大 → 退化成 FCFS。
- 优先级调度
- 思想:给每个进程设优先级,优先级高的先执行。
- 优点:灵活,可以满足任务的不同紧急性。
- 缺点:可能导致低优先级进程长期得不到执行(饥饿现象)。
- 多级反馈队列 (MFQ,最常用)
- 思想:综合前面几种算法的优点。
- 按优先级分多个队列,高优先级先执行。
- 新进程先进入高优先级队列,时间片短;如果没执行完,就降到低一级队列,时间片更长。
- 长作业慢慢“下沉”,短作业一般能在上层快速完成。
- 优点:公平、灵活,适合通用操作系统。
- 缺点:实现复杂,参数(队列数、时间片长短)不好调。
7. 分页与分段的区别?
- 分页(Paging)
按固定大小划分:整个逻辑空间切成页,物理内存切成页框。
页可以 不连续 地存放在物理内存中。
优点:
消除外部碎片,内存利用率高
方便虚拟内存和置换
缺点:
逻辑连续性在物理上不保证
代码、数据可能被分散到不同页上
分页把逻辑空间划分为页,物理内存划分为页框,通过页表实现逻辑页到物理页框的映射。页表存在内存里,为了加速地址转换引入了快表(TLB);为减少大页表的内存消耗,引入了多级页表;进一步可以用反向页表+哈希查找来优化空间和效率。程序看到的都是虚拟地址,运行时通过页表机制映射为物理地址。
- 分段(Segmentation)
按逻辑模块划分:代码段、数据段、栈段、堆等。
每段在物理内存中 连续存放。
优点:
逻辑清晰,符合程序结构
易于保护(不同段可设置不同权限)
可以共享整个段(如只读代码段)
缺点:
可能产生 外部碎片
需要连续内存空间
分段是按程序逻辑划分内存,每段可变大小,地址由段号+段内偏移组成。段表记录段基址和段长,实现逻辑地址 → 物理地址映射。
8. 虚拟内存原理?页面置换算法?
虚拟内存(Virtual Memory)是操作系统将物理内存(RAM)与硬盘空间结合形成的二级存储体系,通过创建分页文件(如Windows的pagefile.sys)扩展可用内存容量。当物理内存不足时,系统自动将不活跃的数据转移到硬盘,腾出空间供当前进程使用。
把部分数据放在磁盘,需要时换入内存,不需要时换出。通过页表+缺页中断实现。
TLB替换和虚拟内存换页都用类似的策略(FIFO、LRU等),本质都是缓存替换思想。但TLB替换只在CPU内部缓存页表映射,开销小;虚拟内存换页涉及把物理页换出到磁盘,开销大,需要处理缺页中断。
- FIFO(先进先出)
- LRU(最近最少使用)
- LFU(最不经常使用,频率)
9. 什么是缺页中断?什么是 页面抖动 ?
访问页面不在内存时触发,由操作系统调入缺失页。
缺页率过高,频繁调页,CPU 时间大多浪费在换页上。
10. 段页式管理是什么?
- 基础是分页
- 内存按固定大小页框管理,逻辑页连续,物理页不连续
- 优点:内存利用率高,换入换出快,消除了外部碎片
- 加上段的概念
- 虚拟地址空间按逻辑模块分段(代码段、数据段、栈段)
- 每段有独立段表 → 可单独管理、保护和共享
- 段内再分页 → 段内页可以分散存放,仍然享受分页优势
- 逻辑和物理关系
- 逻辑上:段内连续,保持程序结构
- 物理上:段内页不连续,提高内存利用率
- 支持虚拟内存换入换出,不影响段的保护和共享
11. 临界区是什么?互斥 vs 同步 vs 异步 vs 并发?
进程/线程访问共享资源的代码片段。
- 互斥(Mutual Exclusion)
目的:防止多个线程/进程同时访问共享资源导致冲突。
关键点:同一时间 只允许一个线程访问资源
实现方式:锁(synchronized、ReentrantLock)、信号量(Semaphore)等
例子:两个线程同时往银行账户存钱,需要加锁保证金额正确
- 同步(Synchronous)
目的:保证操作按顺序执行,协调多个任务
特点:
调用者 必须等待操作完成 才能继续
可以是线程之间的同步,也可以是调用者与被调用者的同步
例子:
方法调用:int res = foo(); → 调用线程必须等 foo() 执行完再继续
多线程同步:用 CountDownLatch、Barrier 等让线程按顺序执行
- 异步(Asynchronous)
特点:
调用者 不等待操作完成,可以继续执行其他任务
操作结果通过回调、Future、Promise、事件通知等方式获取
例子:
异步 HTTP 请求、异步消息队列消费、CompletableFuture
- 并发(Concurrency)
定义:多个任务在同一时间段交替进行执行
特点:
不要求同时执行(同时执行是并行 Parallelism)
利用 CPU 时间片轮转等机制交替执行
例子:
多线程访问 CPU → 在时间上交错执行
操作系统调度多个进程 → 并发处理
12. 如何实现线程间同步?常见同步问题?
线程间同步主要是为了保护共享资源,防止数据竞争。常用方法有:基于锁的同步(synchronized、ReentrantLock)、信号量(Semaphore)、条件变量或阻塞队列(wait/notify, BlockingQueue)、原子操作(Atomic 类或 CAS)、屏障/闭锁(CountDownLatch, CyclicBarrier)等。根据场景选择最合适的方式。
13. 死锁是什么?死锁条件?死锁检测和解除?预防死锁的方式?
- 死锁条件(必要条件):
- 互斥
- 占有并等待
- 不可剥夺
- 循环等待
- 避免死锁:破坏上述条件之一。
- 预防死锁:如一次性申请所有资源、资源有序分配。
- 死锁检测与解除:
- 检测:通过资源分配图、银行家算法。
- 解除:撤销进程或抢占资源。
- 死锁定义:多个进程因竞争资源互相等待,无法继续执行。
14. 资源分配图
- 节点:
- 圆形:表示进程(P1, P2…)
- 方形 / 长方形:表示资源(R1, R2…)
- 边:
- 请求边(→):进程指向资源,表示进程请求该资源
- 分配边(←):资源指向进程,表示资源已分配给该进程
- 无环 → 系统安全,无死锁
- 有环(单实例资源) → 系统发生死锁
- 有环(多实例资源) → 可能死锁,需要进一步分析
- 单实例资源:每类资源在系统中只有一个可用单位。
- 例子:打印机、CPU、磁带机
- 多实例资源:每类资源有多个单位可用。
- 例子:内存页框、多个相同型号打印机、数据库连接池
15. 什么是缓冲区?
缓冲区就是在生产者和消费者之间开的一块临时存储区。生产者(快的)生成数据后不必等待消费者(慢的)处理完,直接放入缓冲区去做其他事情;消费者则可以按自己的速度从缓冲区取数据处理。这样解决了速度不匹配的问题,同时避免了直接阻塞。
16. 中断与轮询的区别?中断与系统调用区别?
轮询是CPU主动周期性检查设备状态,低效且可能延迟;中断是设备或事件主动通知CPU,CPU只在需要时处理,效率高、响应快。中断机制是现代操作系统的主要I/O处理方式。
中断是异步的,因为它的触发时间不可预测,由外部设备或异常事件主动产生,不依赖CPU或程序主动调用。CPU在执行程序时,随时可能被中断打断去执行中断服务程序,因此中断是异步的。
系统调用是用户程序主动请求操作系统服务的过程,CPU 在系统调用指令处顺序切换到内核态执行,不会突然中断其他任务;调用完成后返回用户态继续执行原程序。与中断不同,中断是异步事件,会打断 CPU 当前执行的程序
17. 文件的索引结构?
文件索引结构用于管理文件在磁盘上的块分配,常见的有连续分配(简单快速,但容易产生外部碎片)、链式分配(消除外部碎片,但随机访问慢)、索引分配(建立索引块支持随机访问,可多级管理大文件。
a. (1) 连续分配(Contiguous Allocation)
- 文件占用磁盘上 连续的块
- 优点:随机访问快,索引简单
- 缺点:容易产生外部碎片,文件扩展困难
- 索引表示:
文件名 → 起始块号 + 文件长度
b. (2) 链式分配(Linked Allocation)
- 文件的每个块包含 下一个块的指针
- 优点:消除外部碎片,文件可动态增长
- 缺点:随机访问慢,需要顺序遍历
- 索引表示:
块1 → 块2 → 块3 → … → 块n
c. (3) 索引分配(Indexed Allocation)
- 每个文件有一个 索引块,记录文件所有块号
- 优点:支持随机访问,不要求连续空间
- 缺点:索引块占用额外空间
- 多级索引:
- 单级:索引块直接记录文件块号
- 多级:索引块指向其他索引块 → 支持大文件
- 示例:UNIX i-node
i-node:
直接块 0~11 → 文件块
一级间接块 → 指向文件块
二级间接块 → 指向一级索引块
三级间接块 → 支持超大文件
18. 僵尸进程与孤儿进程?
僵尸进程是子进程已退出,但父进程未回收其 PCB,导致占用少量系统资源;孤儿进程是父进程先退出,子进程仍在运行,系统会由 init 进程收养并回收。僵尸进程需要父进程主动回收,孤儿进程系统自动处理。
19. 热备份与冷备份?
热备份是在系统运行过程中进行备份,用户可以继续访问系统,但需要考虑数据一致性问题;冷备份是在系统停机时备份,操作简单、天然一致,但会中断业务。热备份适合高可用场景,冷备份适合低频全量备份。
- 热备份:
- 数据库正在处理用户请求,同时用快照或日志复制数据
- MySQL InnoDB 在线备份、Oracle RMAN 在线备份
- 冷备份:
- 停掉数据库服务 → 复制整个数据库文件
- 简单、可靠,但会造成服务停机
20. 常用的编译优化技术
a. (1) 代码生成优化
- 常量折叠(Constant Folding)
- 编译期计算常量表达式
- 示例:
int a = 3 + 4;
→ 编译器直接生成int a = 7;
- 常量传播(Constant Propagation)
- 将已知常量替换到表达式中,提高编译效率
- 冗余代码消除(Dead Code Elimination)
- 删除永远不会执行或结果不影响程序的代码
b. (2) 循环优化
- 循环展开(Loop Unrolling)
- 减少循环控制开销,提高执行效率
- 循环交换(Loop Interchange)
- 调整多重循环顺序,提高缓存命中率
- 循环合并/拆分(Loop Fusion/Splitting)
- 合并相似循环减少开销,或拆分循环提高并行性
c. (3) 数据流优化
- 公共子表达式消除(Common Subexpression Elimination, CSE)
- 避免重复计算同一表达式
- 强度降低(Strength Reduction)
- 用位运算或加法替换乘法/除法等昂贵操作
- 寄存器分配优化(Register Allocation)
- 尽量将频繁访问的变量放入寄存器
d. (4) 内存与访问优化
- 内存对齐与缓存优化
- 调整数据布局,提高 CPU cache 命中率
- 延迟加载(Lazy Evaluation)
- 只有真正需要时才计算或访问数据
e. (5) 函数与调用优化
- 内联展开(Function Inlining)
- 减少函数调用开销
- 尾递归优化(Tail Recursion Optimization)
- 将尾递归转换为循环,减少栈空间
f. (6) 并行与向量化优化
- 自动向量化(SIMD)
- 编译器将循环或操作转为并行向量指令
- 多线程/并行优化
- 利用 CPU 多核加速循环或独立计算