多线程---2021面试题汇总传送门:
目录
3.操作系统系统中有哪两种程序,cpu有几种状态,分别描述一下?
第一部分:操作系统基础
1.可以给我讲一下什么是操作系统吗?
1.首先操作系统是一个软件。 2.操作系统控制和管理整个计算机系统的软硬件资源,并且对其进行组织与分配。从而提供给用户和其他软件方便的接口和环境。
2.操作系统的特征是什么?
1.并发(最基本):两个或者多个事件在同一时间间隔内发生。 2.共享(最基本):资源共享。 3.虚拟:把一个物理上的实体变成若干逻辑上的对应物。 4.异步:多道程序环境下允许多个进程并发执行,但是由于资源有限,这些进程并不是一下执行到底的,而是断断续续进行执行,这就是异步。
3.操作系统系统中有哪两种程序,cpu有几种状态,分别描述一下?
1.应用程序和内核程序,用户态和内核态。 2.应用程序由用户态进行执行,内核程序由内核态进行执行。
4.内核态的内容?
1.时钟管理:计时、通过时钟中断实现进程切换 2.中断机制:用户态转换内核态通过中断机制 3.原语:原子性的、运行时间短的、操作系统底层的一些操作 4.操作系统控制的数据结构以及处理:进程管理、设备管理等
5.可以介绍一下什么是系统调用嘛?
介绍系统调用之前,我们先来了解一下用户态和系统态。
1.用户态(user mode) : 用户态运行的进程可以直接读取用户程序的数据。 2.系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。说了用户态和系统态之后,那么什么是系统调用呢?
我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能咋办呢?那就需要系统调用了! 也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。这些系统调用按功能大致可分为如下几类:
1.设备管理。完成设备的请求或释放,以及设备启动等功能。 2.文件管理。完成文件的读、写、创建及删除等功能。 3.进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。 4.进程通信。完成进程之间的消息传递或信号传递等功能。 5.内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
第二部分:进程管理
1.进程和线程的区别是什么?
1.首先进程是操作系统资源分配和调度的基本单位,而线程是操作系统执行程序的最小单位。 2.一个进程内可以包含多个进程,而一个线程只能属于一个进程, 3.进程之间的资源都是相互独立的,他们都有独立的内存空间,而在一个进程中的线程之间可以共享进程的内存资源(JVM)。
2.进程的状态有哪些,他们之间如何进行切换?
1.创建态:进程正在被创建,尚未到就绪状态。 2.就绪态:进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。 3.运行态:进程正在处理器上上运行(单核 CPU 下任意时刻只有一个进程处于运行状态)。 4.阻塞态:又称为等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO 操作完成。即使处理器空闲,该进程也不能运行。 5.结束态:基础讷航从系统中消失。
3.进程间的通信方式有哪些?可以详细讲述一下吗?
1.信号量;信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。 2.信号:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生; 3.管道(pipes):(管道是一个共享文件,是指用于连接一个读进程和一个写进程以实现他们之间通信的共享文件。管道采用半双工通信,也就是说某一时刻只能单向传输,所以要进行双向传输,需要创建两个管道)用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。 4.有名管道(Names pipes): 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。 5.内存共享:在相互通信的进程之间有一个可以直接访问的共享空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。 6.消息队列:消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比 FIFO 更有优势。**消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺。 7.套接字 (socket):用于网络传输。
4.线程间的同步方式有哪些?
1.互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的 synchronized 关键词和各种 Lock 都是这种机制。 2.信号量(Semphares) :它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量 3.事件(Event) :Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操
5.进程的调度算法了解嘛?可不可以讲一下?
1.先来先服务(FCFS)调度算法:按照进入就绪队列的先后顺序,为进程分配处理机 2.优先级调度算法:每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。 3.多级反馈队列调度算法:多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。 4.最短进程优先调度算法:从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。 5.时间片轮转调度算法:时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
6.你知道什么死锁吗?
1.简单来说,死锁是指多个进程因为互相争夺资源,导致进程之间处于一种循环等待的僵持状态。 2.具体来说,是指多个进程之间具备了形成死锁的必要条件。比如有三个进程,三个资源,这三个进程分别占有一个资源,但是有都请求占有他旁边的资源,这是这三个进程就陷入了死锁状态。
7.形成死锁的四个必要条件是什么?
1.互斥:资源是非共享的,同一时间只能有一个进程占有一个资源。 2.占有且等待:某进程占有了一个资源,同时又在请求别的资源。 3.非抢占:资源是不可以被抢占的,只有一个进程执行完,释放了资源,这个资源才可以被其他进程占有。 4.循环等待:一个进程拥有了一个资源,同时又去请求另一个资源。多个进程都处于这种状态时就是循环等待。
8.如何预防死锁?
破坏形成死锁的四个必要条件
9.如何避免死锁 ?
死锁避免是指在资源的动态分配过程中,采用一些算法(如银行家算法)防止系统进入不安全的状态,以避免发生死锁。
10.如何查找死锁以及解除死锁?
1、使用jps定位进程号,jdk的bin目录下: 有一个jps
命令:
jps -l
2、使用
jstack
进程进程号 找到死锁信息
一般情况信息在最后:
死锁解除:1.资源剥夺法:挂起某些死锁进程,并且抢夺他的资源,分配给其他的死锁进程 2.撤销进程法:强制撤销某些死锁进程,并且剥夺他们的资源 3.进程回退法:将死锁进程回退到未形成死锁的地步,进程回退时资源放弃资源
第三部分:内存管理
1.什么是内存管理以及内存管理的功能有哪些?
1.内存管理是指操作系统对内存进行动态分配与划分。 2.功能如下:1.内存空间分配与回收 2.逻辑地址与物理地址的转换 3.内存空间的扩充 4.存储保护
2.覆盖和交换技术了解吗?
了解的。覆盖和交换技术是用来逻辑上扩充内存的一种技术。 1.覆盖:将用户空间划分为覆盖区和固定区两个部分。将经常活跃的部分放在固定区,其余部分按照调用关系分段。首先将那些即将要访问的段放在覆盖区,其他的段放在外存中,在需要时操作系统在将其调入到覆盖区,替换覆盖区中原有的段。 2.交换:指将处于等待状态的程序从内存移动到辅存中,将内存空间腾出来,这部分称为换出,把准备好竞争cpu运行的程序从赋存移动到内存中,这部分称为换入。
3.常见的内存管理机制有哪些?
常见的内存管理机制可以分为两大类:连续分配管理机制和非连续分配管理机制 连续分配管理机制有以下分类: 1.单一连续分配:内存分为系统区和用户区,系统区仅供操作系统使用,用户区是出了系统区外的内存,为用户提供.特点:简单、产生内部碎片、仅支持单户系统 2.固定分区分配:将用户内存划分为若干大小相同的区域,每个区域只装入一道作业。(这里可以再分为分区大小相等和分区大小不相等)特点及问题:1.程序太大时,没有一个内存区域可以放下。 2.主存利用率低,产生内部碎片。 3.动态分区分配:在进程装入内存时,根据进程大小动态的建立分区,并且分区大小和进程大小相等。特点及问题:产生外部碎片(通过紧凑技术去解决)。 动态分区策略: 1.首次适应(空闲分区以地址递增排序,找到首个满足进程大小需求的就为之分配) 2.临领近适应(空闲分区以地址递增排序,从上次查找结束位置开始再次查找,由首次适应演变) 3.最佳适应(空闲分区以容量递增,首个满足的....) 4. 最坏适应 (空闲分区以容量递减,首个满足的) 非连续内存管理机制有以下分类: 1.基本分页存储管理:把主存分为大小相等且固定的一页一页的形式,页较小,相对相比于块式管理的划分力度更大,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址 2.基本分段存储管理:页式管理虽然提高了内存利用率,但是页式管理其中的页实际并无任何实际意义。 段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。 3.段页式管理:段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。
4.快表和多级页表可以分别讲一下吗?
在分页内存管理中,很重要的两点是: 虚拟地址到物理地址的转换要快。 解决虚拟地址空间大,页表也会很大的问题。 快表 为了解决虚拟地址到物理地址的转换速度,操作系统在 页表方案 基础之上引入了 快表 来加速虚拟地址到物理地址的转换。我们可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的 Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。 使用快表之后的地址转换流程是这样的: 根据虚拟地址中的页号查快表; 如果该页在快表中,直接从快表中读取相应的物理地址; 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中; 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。 看完了之后你会发现快表和我们平时经常在我们开发的系统使用的缓存(比如 Redis)很像,的确是这样的,操作系统中的很多思想、很多经典的算法,你都可以在我们日常开发使用的各种工具或者框架中找到它们的影子。 多级页表 引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。多级页表属于时间换空间的典型场景
5.分页机制和分段机制的异同点?
1.共同点 : 分页机制和分段机制都是为了提高内存利用率,较少内存碎片。 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的。 2.区别 : 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序。 分页仅仅是为了满足操作系统内存管理的需求,而段中则包含了程序的逻辑信息。
6.什么是逻辑地址什么又是物理地址呢?
1.逻辑地址:C++语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定 概念:编译后,每个目标模块都从0号单元开始编址,这称为目标模块的逻辑地址。 2.物理地址:理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址 概念:物理地址是指内存中物理单元的集合,他是地址转换的最终地址,进程在运行时执行指令和访问数据,最后都要通过物理地址从主存中存取。
第四部分:虚拟内存
1.什么是虚拟内存?
首先,在我们使用计算机的过程中,经常会看到一个软件所占用的内存空间是大于计算机真实内存大小的,那这是怎么做到的呢?其实就是使用了虚拟内存技术。言归正传,虚拟内存是一种操作系统中内存管理的技术。通过这种技术可以让应用程序认为它拥有一整块完整连续的内存空间,然而实际上,它通常是被分隔在不同的物理内存碎片中的,有的部分甚至存放在外存中,在工作需要时再进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存的使用也更有效率。
2.局部性原理你可以讲一下吗?
可以的。要想了解虚拟内存技术,那么必须先了解局部性原理。局部性原理不仅适用于程序结构,也适用于数据结构。 局部性原理表现在以下两个方面: 1.时间局部性 :程序中的某条指令一旦被执行,不久后该指令可能再次被执行,某数据被访问后的不久很有可能再次被访问。产生时间局部性的原理是因为程序中存在着大量的循环操作。 2.空间局部性:一个程序一旦访问了某个存储单元,那么他附近的存储单元也将被访问,因为指令通常是按照顺序存放、顺序执行的、数据一般以数组、向量等形式簇聚存储。
3.虚拟存储器了解嘛?
基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器。 虚拟存储器的三个特性: 1.多次性:无需再作业时一次性全部装入内存,可以分多次进行调入。 2.虚拟性:指从逻辑上进行内存的扩充。 3.对换性:指允许作业过程中进行换进换出,而不要求作业一直常驻内存。
4.虚拟内存技术的实现有哪些方式?
1.请求分页存储管理 :建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。 2.请求分段存储管理 :建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。 3.请求段页式存储管理 不管是上面那种实现方式,我们一般都需要: 1.一定容量的内存和外存 2.页表机制(段表机制):作为主要的数据结构 3.缺页中断机构:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序; 4.地址变换机构 :逻辑地址到物理地址的变换。
5.请求分段(分页)存储管理和分段(分页)存储管理的区别?
请求分页存储管理建立在分页管理之上。 它们之间的根本区别在于是否要将一作业的全部地址空间同时装入主存。 请求分页存储管理不要求将作业全部地址空间同时装入主存。基于这一点,请求分页存储管理可以提供虚存,而分页存储管理却不能提供虚存。
6.页面置换算法?
地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断(缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问),当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法,我们可以把页面置换算法看成是淘汰页面的规则。 1.OPT 页面置换算法(最佳页面置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。但由于人们目前无法预知进程在内存下的若千页面中哪个是未来最长时间内不再被访问的,因而该算法无法实现。一般作为衡量其他置换算法的方法。 2.FIFO(First In First Out) 页面置换算法(先进先出页面置换算法) : 总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。 3.LRU (Least Recently Used)页面置换算法(最近最久未使用页面置换算法) :LRU算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当须淘汰一个页面时,选择现有页面中其 T 值最大的,即最近最久未使用的页面予以淘汰。 4.LFU (Least Frequently Used)页面置换算法(最少使用页面置换算法) : 该置换算法选择在之前时期使用最少的页面作为淘汰页。