---
title: 《BAT高频面点》操作系统高频面试题八股文（必看🔥）
category: 
  - Java
  - BAT高频面点
  - 操作系统
tag:
  - 进程
  - 线程
  - 内存
  - 堆
  - 栈
head:
  - - meta
    - name: keywords
      content: 进程,线程,虚拟内存,操作系统,死锁 堆栈,内核
    - name: description
      content: 图解《操作系统-BAT高频面题》全网质量最高操作系统常见知识点和面试题总结，希望对你有帮助
---
### 1、什么是操作系统

- 操作系统简称OS，负责管理**协调****计算机硬件****与****软件资源****工作的****系统软件**
- 屏蔽了硬件层的复杂性，为上层应用软件与用户提供易用的服务

### 2、系统调用

操作系统**提供给应用程序**（程序员/编程人员）**使用的****接口****，**可以以此**获得操作系统内核的服务****。**

#### 用户态切换到内核态的几种方式

系统调用、硬件设备中断信号

异常：发生异常，切换到处理该异常的内核程序中

### 3、进程和线程的区别

一个正在运行中的程序就是一个进程，进程包括程序段、数据段、PCB三部分。程序段就是程序的代码，数据段就是程序运行时产生的数据（比如全局变量、局部变量等），PCB 中包含操作系统对其进行管理的各种信息（如进程标识符 PID，进程当前状态，进程优先级）。

调度：进程是**资源分配的基本单位**，线程是**任务调度和执行的基本单位**。

内存：进程拥有**独立的地址空间与资源**，同个进程下的线程**共享进程的地址空间与资源。**

开销：线程间切换开销小，进程间**切换开销大**（线程共享进程资源，拥有独立的**栈与程序计数器**，进程切换要切换上下文环境）。

切换：同一进程间线程切换不会引起进程切换，不同进程间线程切换会引起进程切换

线程也被称为轻量级线程。

通信：线程间可以通过直接**读写同一进程**中的数据进行通信，但是进程通信需要借助**系统内核**的帮助。

健壮性：进程中一个线程死了，整个进程也就死了；而进程死了，不会对其他进程有影响，独立地址空间

### 4、线程切换开销为啥比进程小

1、线程切换不需要更换**页表**，而进程切换需要。页表切换缓存失效，性能低（虚拟内存、页表）

2、进程切换需要切换上下环境比线程上下文环境大，保存现场，切换，到恢复现场更耗时。

进程上下文环境：

程序计数器，通用寄存器、数据、用户栈、页表、pcb等

### 4、协程

协程是一种**用户态的**，不被操作系统内核所管理，完全**由用户控制**的，**比线程更加轻量级**的存在；一个进程可以由有多个线程，一个线程也可以有多个协程；**用户态执行，性能大大提升**

### 5、进程5种状态

- 新建态（创建一个进程）
- 就绪态（已经获取到资源，准备好了，进入就绪队列，一旦获得时间片可以立即执行）
- 运行态（获取到了时间片，执行程序）
- 阻塞态（运行过程中**等待获取其他资源**，I/O请求等）
- 终止态（进程被杀死了)

java中线程6种状态：

new、runnable(就绪+运行)、blocked(阻塞于锁)、waiting、timed_waiting、terminated

### 6、虚拟内存

虚拟内存**使得应用程序认为它拥有连续的可用的内存（一个连续完整的地址空间）,**使得进程**逻辑上有很大的连续内存地址空间**，实际上一部分**对应物理内存上的块**，还有一部分没加载进内存的对应在**外部磁盘**，在需要时进行数据交换。

虚拟内存可以让程序可以**拥有超过系统物理内存大小**的**可用内存空间**

### 7、孤儿进程与僵尸进程

僵尸进程（危害）：子进程退出，父进程没有调用wait()/waitpid()获取子进程终止状态，子进程保留的信息得不到释放，占用进程号，浪费资源，等进程号耗尽便无法产生新进程。

孤儿进程（无害）：父进程退出，子进程还在运行，这些进程便称为孤儿进程。孤儿进程将被**init进程**（进程号为1）收养，并由init进程完成进程收集工作。

### 8、进程间通信与线程间通信

**进程间通信：**

**（无名）管道**(半双工通信、**需亲缘**父子或兄弟进程中使用)、**FIFO**(命名管道，不是父子也可使用)、**信号量**(计数器—实现进程间互斥同步)、**socket**、**消息队列**、**共享内存、信号（**由软件【kill】、硬件【ctrl c】产生信号通知进程某个事件已经发生**）**

**线程间（同步）通信：**

- 互斥量(Mutex)：互斥对象机制，拥有互斥对象才能访问。（synchonized、lock）
- 信号量：允许同⼀时刻多个线程访问同⼀资源，但是需要控制同⼀时刻访问此资源的最⼤线程数量
- 事件**(Event)** ：通过通知操作方式实现同步（wait/notify）

### 9、堆栈区别

申请方式：栈系统自动申请，堆需手动申请c语言malloc()，java new Object()；

stack系统分配速度快，堆慢，容易内部碎片；

栈地址空间连续，堆是不连续的（链表存储空闲内存地址）；

内容不一样，大下限制（栈预先设定好的，堆取决有效虚拟内存）

### 10、什么情况下Java程序会产生死锁？如何定位、恢复？

一、死锁原因：

两个或多个任务以不合理的顺序相互竞争资源造成相互等待，无限期阻塞

例如：线程A持锁a，获取锁b;线程B持锁b，获取锁a，就会死锁

**二、死锁检测：**

- jps、ps、任务管理器获取进程ID
- jstack pid获取进程中线程堆栈信息（区分线程状态 -> 查看等待目标 -> 对比 Monitor 等持有状态）
- **jconsole、Jvisualvm排查死锁问题**（java监视管理平台）

三、死锁解决：

打破造成死锁条件（互斥、占有并等待、非抢占、循环等待）、按顺序获取锁，使用超时锁、不要同时获取多把锁

```java
//死锁例子
public class DeadLockSample extends Thread {
  private String first;
  private String second;
  public DeadLockSample(String name, String first, String second) {
      super(name);
      this.first = first;
      this.second = second;
  }

  public  void run() {
      synchronized (first) {
          System.out.println(this.getName() + " obtained: " + first);
          try {
              Thread.sleep(1000L);
              synchronized (second) {
                  System.out.println(this.getName() + " obtained: " + second);
              }
          } catch (InterruptedException e) {
              // Do nothing
          }
      }
  }
  public static void main(String[] args) throws InterruptedException {
      String lockA = "lockA";
      String lockB = "lockB";
      DeadLockSample t1 = new DeadLockSample("Thread1", lockA, lockB);
      DeadLockSample t2 = new DeadLockSample("Thread2", lockB, lockA);
      t1.start();
      t2.start();
      t1.join();
      t2.join();
  }
}
```

### 11、内存管理机制

块式管理：将内存分为一个个块，一个块包含一个进程

**页式管理**：将**内存空间**分为一个个大小相等的**分区**，每个分区就是一个**页框**，然后将进程的逻辑地址分页存储在页框中，通过⻚表对应逻辑地址和物理地址

**段式管理**：：内存被划分为若干个段，按段存储

**段页式管理**：把主存先分成若干段，每个段又分成若干页。



**页表**：存储页面与页框对于关系，通过页表对应逻辑地址与物理地址。

### 12、分页机制与分段机制异同

1. 共同点 ：

- 分⻚机制和分段机制都是为了提⾼内存利⽤率，减少内存碎⽚。
- ⻚和段都是离散存储的，所以两者都是离散分配内存的⽅式。但是，每个⻚和段中的内存是连续的。

1. 区别 （段：地址空间二维、产生外部碎片、大小不固定、对用户可见、更容易信息共享与保护）

- - 分页对用户不可见，分段对用户可见
  - 分页**地址空间**一维，分段地址空间二维
  - 分段更容易实现**信息的共享与保护**
  - 分段会产生外部**碎片**；分页内存利用率更高，不会产生外部碎片
  - 页的**大小**是固定的，由操作系统决定；而段的大小不固定，取决于我们当前运⾏的程序

### 13、select、poll、epoll

基本原理概叙：

- select：将文件描述符（fds）收集给内核，内核发现有数据到来，select返回，并将有数据的fd值为1。用户空间中，由于SELECT 没有返回哪些 fd 有数据到来，用户态需要遍历得到置位的fd读取数据并处理，O（n）时间复杂度。

- - 缺点：fd有大小限制，bitmap数据结构，1024；需要一次用户态内核态切换、处理需要线性遍历fd
  - 优点：由内核态判断fds有无数据到来，只需要一次用户内核切换，不然每次都要切

- poll：原理和select近似，只是poll采用结构体表示fd（int fd-指定给fd、int event-监听的某个事件、int revent）-结构体+链表
- epoll：结构体+链表、**没有置位操作**、用户内核态共享内存、**返回有数据到来的fd，不用遍历**

### 14、进程调度算法

先来先服务、短作业优先、时间片轮转、多级反馈队列、优先级调度

### 15、页面置换算法

**FIFO（First In First Out） 页面置换算法（先进先出页面置换算法）** 

**LRU （Least Recently Used）页面置换算法（最近最久未使用页面置换算法）**

**OPT 页面置换算法（最佳页面置换算法）未来长时间不使用的或永久不使用的，****理想的，无法实现的****，无法确定页面访问时间**

**时钟(CLOCK)置换算法：**

- 当内存中无对应数据，访问位为 0 即可置换，再变换访问位为 1，然后指针下移。
- 当内存中无对应数据，访问位为 1 不置换，再变换访问位为 0，然后指针下移。
- 当内存中有对应数据时，访问位变换，指针下移。

### 16、IO模型

### 17、select、poll、epoll

### 18、Linux常用命令

pwd：显示当前所在位置

kill -9  pid ：杀死进程（-9 表示强制终止）

kill -2 pid：保存相关数据再退出

tar -xvf ：解压

wget : 是从远程下载的工具。

top

df -h：查看磁盘空间



网络相关：

netstat -ntl

netstat -naptul | grep 端口

进程：

ps -ef | grep xxx

telnet IP地址 端口：判断主机是否开启了某个端口

ping : 查看与某台机器的连接情况。TTL：生存时间。数据报被路由器丢弃之前允许通过的网段数量

linux如何查看端口被哪个进程占用的方法：

1、lsof -i:端口号

2、netstat -tunlp|grep 端口号

1、网络排查

```bash
netstat -ntl  [t:tcp u:udp l:处于监听状态连接 n:以IP地址显示]
查找某个端口
netstat -ntl | grep 端口
```

![img](https://cdn.nlark.com/yuque/0/2021/png/21967782/1625731936479-caaa6e3f-c377-4c83-b2d4-05230feda940.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_15%2Ctext_5b6u5L-h5YWs5LyX5Y-377ya5bCP6b6ZY29kaW5n%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10)

2、查找指定进程

```bash
ps -ef | grep 进程关键字
```

3、查看一个进程所占内存

```bash
ps -ef | grep 进程关键字 【得到进程ID】
top -p 进程ID
```

4、查看文件前几行后几行

```bash
tail -fn 1000 nohut.out 【f循环打印 n行数 tail后几行】
head -n 1000 nohut.out 【 n行数 head前几行】
```

5、运行Jar包

```bash
nohup java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -jar /home/hik/data/ygw/ygw-1.0.0-SNAPSHOT.jar &
```

6、其他基本命令

```bash
cat vim mkdir cd ll ls 
#监控TCP/IP网络并过滤指定端口
netstat -lanp|grep 8080
netstat -aon|grep ".27:80 "|wc
#查看磁盘空间
df -hl
#查看内存使用情况
free
#查找目录下的文件
find path -name 文件名
#查找当前目录下的以out结尾的文件
find . -name "*.out" 
```