操作系统常见面试题

(根据自己的面试经验总结的知识点,内容比较浅显,有问题的地方欢迎指正呀)

1、进程和线程以及它们的区别

  1. 进程是对运行时程序封装,是系统进行资源分配和调度的基本单位,实现了操作系统的并发
  2. 线程是进程的子任务,是CPU调度和分配的基本单位,用于保证程序的实时性,实现进程内部的并发;
  3. 一个程序至少有一个进程,一个进程至少有一个线程,线程依赖进程而存在
  4. 进程在执行过程中拥有独立的内存单元,多个线程共享进程的内存

2、进程间通信的几种方式

  1. 管道及命名管道: 管道可用于具有亲缘关系的父子进程间的通信,有些管道除了具有管道所具有的的功能外,它还允许无亲缘关系进程间的通信;
  2. 信号: 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
  3. 消息队列:消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息;
  4. 共享内存:可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等;
  5. 信号量:主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段;
  6. 套接字:这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

2.1、进程有几种状态

  1. 三态模型:就绪、允许、阻塞
  2. 五态模型:新建态、就绪态、运行态、阻塞态、终止态

2.2、说一说进程同步有几种机制

原子操作、信号量机制、自旋锁管程、会合、分布式系统

3、线程实现方式

  1. 通过继承Thread类实现一个线程
  2. 通过实现Runnable接口实现一个线程
    继承扩展性不强,java总只支持单继承,如果一个类继承Thread就不能继承其他的类了。
  3. Collable实现

3.1、线程间同步方式

  1. 互斥量Synchronized/Lock: 采用互斥对象机制,只有拥有多个互斥对象的线程才有访问公共资源的权限.因为互斥对象只有一个,所以可以保证公共资源不会同时被多个线程同时访问
  2. 信号量Semphare: 它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
  3. 事件Wait/Notify: 通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作

3.2、有没有使用过线程并发库

简单了解过?JDK5中增加了Doug Lea的并发库,这一引进给Java线程的管理和使用提供了强大的便利性。java.util.current包中提供了对线程优化、管理的各项操作,使得线程的使用变得的心应手。该包提供了线程的运行、线程池的创建、线程生命周期的控制。

4、进程有几种状态

创建(new)、就绪(runnable/start)、运行(running)、阻塞(blocked)、等待(waiting)、时间等待(time waiting) 和 消亡(dead/terminated)

4.1、线程安全实现方式

1、 互斥同步:多个线程并发访问一个数据的时候,保证共享数据在同一个时刻只能被一个或者一些线程使用,synchronized来实现,Java.util.concurrent中的重入锁来实现,互斥是因,同步是果,互斥是方法,同步是目的。
2、 非阻塞同步:基于冲突检测的乐观并发策略,通俗地说就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生了冲突,那就再进行其他的补偿措施(最常见的补偿措施就是不断地重试,直到试成功了为止)
3、 无同步方案:要保证线程安全,并不是一定就要进行同步,两者没有因果关 系。同步只是保障共享数据争用时的正确性的手段,如果一个方法本来就不涉及共享数据,那它自然就无须任何同步措施去保证正确性。可重入代码,线程本地存储

4.2、什么是多线程

多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。在一个程序中,这些独立运行的程序”

4.3、什么是线程并发

线程并发是指一个类的实例对象创建了多个线程对象同时启动,调用同样的资源,造成线程的安全问题。
解决办法:根本–保证容易出现问题的代码的原子性(破坏产生多线程并发安全问题的条件)。
1、使用synchronized关键字,创建同步代码块,当执行到了synchronized(object)语句的时候,先检查object对象的标志位,如果为0状态,则表示有其他线程正在执行,那么此线程将暂时阻塞,让出CPU资源,直到另外的线程执行完毕,将标志位恢复为1后,可以继续运行。
2、禁止共享资源 --ThreadLocal
3、禁止修改 —ReadWriteLock

4.4、线程池有哪几种

Java通过Executors提供四个静态方法创建四种线程池,分别为:

  1. newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO后进先出, 优先级)执行

4.5、线程池的作用

限定线程的个数,不会导致由于线程过多导致系统运行缓慢或崩溃
线程池不需要每次都去创建或销毁,节约了资源
线程池不需要每次都去创建,响应时间更快。

4.6、线程池几个关键参数

a.核心线程数;b 最大线程数;c 线程空闲时间;d 阻塞队列大小:queueCapacity;e 任务拒绝处理器 :rejectedExceptionHandler
1.corePoolSize 指定了线程池里的线程数量
2.maximumPoolSize 指定了线程池里的最大线程数量
3.keepAliveTime 当线程池线程数量大于corePoolSize时候,多出来的空闲线程,多长时间会被销毁。
4.unit 时间单位
5.workQueue 任务队列,用于存放提交但是尚未被执行的任务。
6.threadFactory 线程工厂,用于创建线程,一般可以用默认的
7.handler 拒绝策略,当任务过多时候,如何拒绝任务。
更详细的解释请参照ditto77 线程池核心参数

4.7、连接池是什么

连接池的作用:连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建连接和销毁连接的过程。这样性能上得到了提高。
基本原理是这样的:
1、 建立数据库连接池对象(服务器启动)。
2、按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
对于一个数据库访问请求,直接从连接池中得到一个连接。
3、如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
4、存取数据库。
5、关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接 数则释放连接)。
6、释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。
三种连接池的配置:dbcp、c3p0、druid

5、死锁

5.1、概念

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

5.2、死锁的四个必要条件

  1. 互斥: 某种资源只允许一个进程访问,该资源一旦分配一个进程,其他进程就不会访问,直到该进程访问结束.eg:打印机
  2. 循环等待:存在一个进程链,使得每个进程都占有下一个进程所需要的至少一种资源
  3. 保持和请求: 一个进程占用A资源,还需要B资源才能运行结束,另一个进程占用B资源,需要A资源才能运行结束
  4. 不可剥夺: 进程占用了某种资源,其他进程不能剥夺

5.3、死锁预防

破坏四个必要条件之一就行了

  1. 破坏互斥条件:运行资源可以被多个进程同时占有,但是有些资源无法公用的,比如打印机
  2. 破坏循环等待条件: 实行资源有序分配策略.对所有资源排序编号,所有进程对资源的请求必须严格按照资源序号递增的顺序提出,即只有占有了小号资源才能申请大号资源,这样就不会产生环路,预防死锁的产生.
  3. 破坏保持和请求条件: 实行资源预先分配策略(进程在运行前一次性向系统申请它所需要的全部资源,若所需全部资源得不到满足,则不分配任何资源,此进程暂不运行;只有当系统能满足当前进程所需的全部资源时,才一次性将所申请资源全部分配给该线程)或者只允许进程在没有占用资源时才可以申请资源(一个进程可申请一些资源并使用它们,但是在当前进程申请更多资源之前,它必须全部释放当前所占有的资源). 但是这种策略也存在一些缺点:在很多情况下,无法预知一个进程执行前所需的全部资源,因为进程是动态执行的,不可预知的;同时,会降低资源利用率,导致降低了进程的并发性。
  4. 破坏不可剥夺条件: 允许进程强行从占有者哪里夺取某些资源。也就是说,但一个进程占有了一部分资源,在其申请新的资源且得不到满足时,它必须释放所有占有的资源以便让其它线程使用。这种预防死锁的方式实现起来困难,会降低系统性能。

5.4、死锁避免

死锁避免的基本思想是动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。
所谓安全状态是指:如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的,换句话说就是,如果存在一个安全序列,那么系统处于安全状态。
资源分配图算法银行家算法是两种经典的死锁避免的算法,其可以确保系统始终处于安全状态。其中,资源分配图算法应用场景为每种资源类型只有一个实例(申请边,分配边,需求边,不形成环才允许分配),而银行家算法应用于每种资源类型可以有多个实例的场景。

5.4.1、银行家算法

1.设进程i提出请求Request[n],则银行家算法按如下规则进行判断。
(1)如果Request[n]>Need[i,n],则报错返回。
(2)如果Request[n]>Available,则进程i进入等待资源状态,返回。
(3)假设进程i的申请已获批准,于是修改系统状态:
Available=Available-Request
Allocation=Allocation+Request
Need=Need-Request
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
2.安全性检查
(1)设置两个工作向量Work=Available;Finish =False
(2)从进程集合中找到一个满足下述条件的进程,
Finish =False
Need<=Work
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+Allocation
Finish=True
GO TO 2
(4)如所有的进程Finish =true,则表示安全;否则系统不安全。

5.5、死锁解除

两种方法进程终结和资源抢占.指简单地终止一个或多个进程以打破循环等待,包括三种方式:

  1. 资源剥夺法。挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于 资源匮乏的状态。
  2. 撤销进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。
  3. 进程回退法。让一(或多)个进程回退足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。

6、操作系统中的进程调度策略

  1. FCFS(先来先服务,队列实现,非抢占的):先请求CPU的进程先分配到CPU
  2. SJF(最短作业优先调度算法):平均等待时间最短,但难以知道下一个CPU区间长度
  3. 优先级调度算法(可以是抢占的,也可以是非抢占的):优先级越高越先分配到CPU,相同优先级先到先服务,存在的主要问题是:低优先级进程无穷等待CPU,会导致无穷阻塞或饥饿;解决方案:老化
  4. 时间片轮转调度算法(可抢占的):队列中没有进程被分配超过一个时间片的CPU时间,除非它是唯一可运行的进程。如果进程的CPU区间超过了一个时间片,那么该进程就被抢占并放回就绪队列。
  5. 多级队列调度算法:将就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。其中,一个进程根据自身属性被永久地分配到一个队列中。
  6. 多级反馈队列调度算法:与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多CPU时间,那么它会被转移到更低的优先级队列;在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。

7、分页存储和分段存储

  1. 段式存储管理:是一种符合用户视角的内存分配管理方案。在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)
  2. 分页式存储管理方案:是一种用户视角内存与物理内存相分离的内存分配管理方案。在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。

7.1、分页和分段区别

两者的不同点:

  1. 目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;
  2. 大小不同:页的大小固定且由系统决定,而段的长度却不固定,由其所完成的功能决定;
  3. 地址空间不同: 段向用户提供二维地址空间;页向用户提供的是一维地址空间;
  4. 信息共享:段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制;
  5. 内存碎片:页式存储管理的优点是没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满);而段式管理的优点是没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。

8、内存的发展历史(这一部分简单了解即可)

没有内存抽象(单进程,除去操作系统所用的内存之外,全部给用户程序使用) —> 有内存抽象(多进程,进程独立的地址空间,交换技术(内存大小不可能容纳下所有并发执行的进程)—> 连续内存分配(固定大小分区(多道程序的程度受限),可变分区(首次适应,最佳适应,最差适应),碎片) —> 不连续内存分配(分段,分页,段页式,虚拟内存)

8.1、虚拟内存

虚拟内存允许执行进程不必完全在内存中。虚拟内存的基本思想是:每个进程拥有独立的地址空间,这个空间被分为大小相等的多个块,称为页(Page),每个页都是一段连续的地址。这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立刻进行必要的映射;当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的命令。这样,对于进程而言,逻辑上似乎有很大的内存空间,实际上其中一部分对应物理内存上的一块(称为帧,通常页和帧大小相等),还有一些没加载在内存中的对应在硬盘上,如图5所示。
注意,请求分页系统、请求分段系统和请求段页式系统都是针对虚拟内存的,通过请求实现内存与外存的信息置换。
虚拟内存示意图
虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问MMU(内存管理单元)去匹配对应的物理地址(比如上图的0,1,2)。如果虚拟内存的页并不存在于物理内存中(如上图的3,4),会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。

8.2、页面置换算法

  1. FIFO先进先出算法:在操作系统中经常被用到,比如作业调度(主要实现简单,很容易想到);
  2. LRU(Least recently use)最近最少使用算法:根据使用时间到现在的长短来判断;
  3. LFU(Least frequently use)最少使用次数算法:根据使用次数来判断;
  4. OPT(Optimal replacement)最优置换算法:理论的最优,理论;就是要保证置换出去的是不再被使用的页,或者是在实际内存中最晚使用的算法。

8.3、虚拟内存的应用与优点

虚拟内存很适合在多道程序设计系统中使用,许多程序的片段同时保存在内存中。当一个程序等待它的一部分读入内存时,可以把CPU交给另一个进程使用。虚拟内存的使用可以带来以下好处:
在内存中可以保留多个进程,系统并发度提高
解除了用户与内存之间的紧密约束,进程可以比内存的全部空间还大

8.4、颠簸

颠簸本质上是指频繁的页调度行为,具体来讲,进程发生缺页中断,这时,必须置换某一页。然而,其他所有的页都在使用,它置换一个页,但又立刻再次需要这个页。因此,会不断产生缺页中断,导致整个系统的效率急剧下降,这种现象称为颠簸(抖动)。

8.4.1、颠簸的解决策略

  1. 如果是因为页面替换策略失误,可以修改替换算法来解决这个问题;
  2. 如果是因为运行的程序太多,造成程序无法同时将所有频繁访问的页面调入内存,则要降低多道程序的数量;
  3. 否则,还剩下两个办法:终止该进程或增加物理内存容量

8.5、局部性原理

  1. 时间上的局部性:最近被访问的页在不久的将来还会被访问;
  2. 空间上的局部性:内存中被访问的页周围的页也很可能被访问
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值