《BAT高频面点》操作系统高频面试题八股文(必看🔥)

小龙coding2023/4/9大约 10 分钟

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监视管理平台)

三、死锁解决:

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

//死锁例子
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、网络排查

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

img

2、查找指定进程

ps -ef | grep 进程关键字

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

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

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

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

5、运行Jar包

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

6、其他基本命令

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"