面试准备之计算机网络基础和操作系统基础
1、 TCP连接过程(三次握手):
(1) 服务端通过socket,bind和listen准备好接受外来的连接,此时服务端状态为Listen
(2)客户端通过调用connect来发起主动连接,导致客户端TCP发送一个SYN(同步)字节,告诉服务器客户将在(待建立的)连接中发送的数据的初始***,客户端状态为SYN_SENT。
(3)服务器确认(ACK)客户的SYN,并自己也发送一个SYN,它包含服务器将在同一连接中发送数据的初始***。
(4)客户端确认服务的ACK和SYN,向服务器发送ACK,客户端状态ESTABLISHED
(5)服务器接收ACK,服务器状态ESABLISHED。
2、为什么要进行四次挥手?
由于TCP是全双工的,因此每个方向都需要单独关闭。
因为服务端的listen状态下的socket收到SYN报文的连接请求的时候,可以把ACK和SYN(ACK起应答作用,SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的SYN报文通知时,仅表示对方没有数据发送给你了,但未必你所有的数据都发送给对方了,所以你未必可能会马上关闭socket,即你可能会发送一些东西给对方后,再发送FIN报文给对方代表你同意关闭连接了,所以这里的ACK和SYN大多情况都是分开发送的。
3、为什么不能进行两次握手?
三次握手完成了两个重要的功能,既要双方做好发送数据的准备,也要双方就初始序号进行协商,这个***在握手过程中被发送和确认。
如果把三次握手改成两次握手,死锁是有可能发生的。假如Client发送了一个连接请求分组给Server,Server收到了这个分组,并且发送了确认应答分组。
按照两次握手的协定,Server端认为已经建立连接了,可以进行发送数据。但是,如果Server的应答分组丢失了,Client将不知道Server是否准备好,甚至怀疑Server是否收到了自己的连接请求。在这种情况下,Client认为还未建立成功,将忽略Server发来的任何数据分组,只等待Server端的确认分组。而Server发出的分组超时后,重复发送同样的分组,这样就形成了死锁。
TCP粘包
参考网址:https://www.cnblogs.com/panchanggui/p/9518735.html
4、TIME_WAIT状态的作用:
1)可靠地实现TCP全双工连接的终止
主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),TIME_WAIT状态一般维持在1-4分钟。在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭的客户端必须维持状态信息进入TIME_WAIT状态。
5、Http请求的过程
比如我们在地址栏输入 www.baidu.com,然后回车,后续发生的过程如下:
过程概览:
- 1、对www.baidu.com这个地址进行DNS域名解析,得到对应的IP地址。
- 2、根据这个IP,找到对应的服务器,发起TCP的三次握手。
- 3、建立TCP连接之后发起HTTP请求
- 4、服务器相应HTTP请求,浏览器得到HTML代码
- 5、浏览器解析HTML代码,并请求HTML代码中的资源(如js,css图片等),先得到HTML代码,才能去找这些资源
- 6、浏览器对页面进行渲染呈现给用户。
注:
1、DNS域名解析采用的是递归的方式,过程是,首先先去DNS缓存查找–>缓存找不到就去根域名服务器–>根域名又会去找下一级,这样递归查到了,给web浏览器
2、最后一步浏览器是如何对页面进行渲染的?
- 解析HTML构成DOM树
- 解析css文件构成渲染树
- 边解析,边渲染
- JS单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有的资源下载都是没有必要的,所以JS是单线程的,会阻塞后续资源下载
6、DNS解析过程
过程的具体细节:
- a、首先会搜索浏览器自身的DNS缓存(缓存时间较短,大概只有1分钟,且只能容纳1000条缓存)
- b、如果浏览器自身的DNS缓存没有找到,就会搜索系统的DNS缓存
- c、如果还没有找到,就尝试从hosts文件中去找
- d、如果还没找到,就递归地去域名服务器查找
参考网址:https://www.cnblogs.com/xuzekun/p/7527736.html
7、Http和Https的区别
7.1、基本概念
HTTP协议以明文方式发送内容,不提供任何数据的加密,如果攻击者截取了浏览器和服务器之间的传输报文,就可以直接读懂其中的信息,因此,Http不适合传输一些敏感信息。
Https可以看做http的安全版,即在Http下加入了SSL层,Https的安全基础就是SSL。
Https协议的作用可以分为两个:一种是建立信息安全通道,来保证数据传输的安全。另一种就是确认网站的真实性。
7.2、Http和Https的主要区别(https=http+ssl安全传输协议+ca身份认证)
(1)Https需要申请证书
(2)Https比Http安全
(3)Http和Https采用完全不同的连接方式,端口也不一样,前者是80,后者是443
(4)Http的连接很简单,是无状态的;Https是有SSL+Http协议构建的可进行加密传输,身份认证的网络协议。
7.3、Https的工作原理
客户端在使用Https方式与web服务器进行通信时,会有以下几个步骤:
(1)客户端使用Https的URL访问web服务器,要求与web服务器建立SSL连接。
(2)web服务器收到请求后,会将网站的证书信息(包含公钥)发送给客户端。
(3)客户端的浏览器与web服务器开始协商SSL连接的安全等级,也就是信息加密的等级
(4)客户端的浏览器根据双方同意的加密等级,建立会话**,然后利用网站的公钥将会话**加密,并传送给网站。
(5)web服务器根据自己的私钥解密出会话**。
(6)web服务器根据会话**加密与客户端之间通信。
8、Cookie和Session的区别?
- Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。
- Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
- Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击。
- Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。
session原理:
- session是保存在服务器端,理论上是没有是没有限制,只要你的内存够大。
- 浏览器第一次访问服务器时会创建一个session对象并返回一个JSESSIONID=ID的值,创建一个Cookie对象key为JSSIONID,value为ID的值,将这个Cookie写回浏览器。
- 浏览器在第二次访问服务器的时候携带Cookie信息JSESSIONID=ID的值,如果该JSESSIONID的session已经销毁,那么会重新创建一个新的session再返回一个新的JSESSIONID通过Cookie返回到浏览器
- 针对一个web项目,一个浏览器是共享一个session,就算有两个web项目部署在同一个服务器上,针对两个项目的session是不同的,如:你在tomcat上同时部署了两个web项目,分别是web1、web2。当你在一个浏览器上同时访问web1时创建的session是A1,访问web2时创建的session是A2。后面你再多次访问web1使用的session还是A1,多次访问web2时使用session就是A2。
- session是基于Cookie技术实现,重启浏览器后再次访问原有的连接依然会创建一个新的session,因为Cookie在关闭浏览器后就会消失,但是原来服务器的Session还在,只有等到了销毁的时间会自动销毁。
- 如果浏览器端禁用了Cookie,那么每次访问都会创建一个新的Session,但是我们可以通过服务器端程序重写URL即可,如果页面多连接多,会增加不必要的工作量,那可以强制让你用户开启接收Cookie后再让其访问即可。
通俗解释:当你一次访问服务器的时候,服务器会在内存中开辟一块空间,返回唯一一把打开该空间的钥匙,再把这把钥匙返回到浏览器。
当你第二次访问的时候浏览器会携带这把钥匙到服务器端打开对应的空间,如果该空间已经销毁又重新返回开辟一块新的空间返回新的钥匙到浏览器。
9、并发和并行的区别
1、并发(Concurrent):指应用能够交替执行不同的任务,其实并发有点类似于多线程的原理,多线程并非是同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不断去切换这两个任务,以达到"同时执行效果",其实并不是的,只是计算机的速度太快,我们无法察觉到而已.
2、并行(Parallel):指两个或者多个事件在同一时刻发生,即同时做不同事的能力。例如垃圾回收时,多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
10、虚拟内存的意义及管理
虚拟内存有以下几个作用:
1. 内存访问保护
2. 按需分页(lazy load技术)
3. 页换入换出(page swap in/out)
4. 写时复制(copy on write)
虚拟内存提供了三个重要的能力:缓存,内存管理,内存保护
1. 虚拟内存可以结合磁盘和物理内存的优势为进程提供看起来速度足够快并且容量足够大的存储;
2. 虚拟内存可以为进程提供独立的内存空间并引入多层的页表结构将虚拟内存翻译成物理内存,进程之间可以共享物理内存减少开销,也能简化程序的链接、装载以及内存分配过程;
3. 虚拟内存可以控制进程对物理内存的访问(通过页表),隔离不同进程的访问权限,提高系统的安全性;
什么是虚拟内存?简单地说,是指程序员或CPU “需要”和直接“看到”的内存,这其实暗示了两点:1、虚拟内存单元不一定有实际的物理内存单元对应,即实际的物理内存单元可能不存在;2、如果虚拟内存单元对应有实际的物理内存单元,那二者的地址一般不是相等的。通过操作系统的某种内存管理和映射技术可建立虚拟内存与实际的物理内存的对应关系,使得程序员或CPU访问的虚拟内存地址会转换为另外一个物理内存地址。
那么这个“虚拟”的作用或意义在哪里体现呢?在操作系统中,虚拟内存其实包含多个虚拟层次,在不同的层次体现了不同的作用。首先,在有了分段或分页机制后,程序员或CPU直接“看到”的地址已经不是实际的物理地址了,这已经有一层虚拟化,我们可简称为内存地址虚拟化。有了内存地址虚拟化,我们就可以通过设置段界限或页表项来设定软件运行时的访问空间,确保软件运行不越界,完成内存访问保护的功能。
通过内存地址虚拟化,可以使得软件在没有访问某虚拟内存地址时不分配具体的物理内存,而只有在实际访问某虚拟内存地址时,操作系统再动态地分配物理内存,建立虚拟内存到物理内存的页映射关系,这种技术属于lazy load技术,简称按需分页(demand paging)。把不经常访问的数据所占的内存空间临时写到硬盘上,这样可以腾出更多的空闲内存空间给经常访问的数据;当CPU访问到不经常访问的数据时,再把这些数据从硬盘读入到内存中,这种技术称为页换入换出(page swap in/out)。两个虚拟页的数据内容相同时,可只分配一个物理页框,这样如果对两个虚拟页的访问方式是只读方式,这这两个虚拟页可共享页框,节省内存空间;如果CPU对其中之一的虚拟页进行写操作,则这两个虚拟页的数据内容会不同,需要分配一个新的物理页框,并将物理页框标记为可写,这样两个虚拟页面将映射到不同的物理页帧,确保整个内存空间的正确访问。这种技术称为写时复制(Copy On Write,简称COW)。这三种内存管理技术给了程序员更大的内存“空间”,我们称为内存空间虚拟化。
ucore在实现上述三种技术时,需要解决的一个关键问题是,何时进行请求调页/页换入换出/写时复制处理?其实,在程序的执行过程中由于某种原因(页框不存在/写只读页等)而使 CPU 无法最终访问到相应的物理内存单元,即无法完成从虚拟地址到物理地址映射时,CPU 会产生一次缺页异常,从而需要进行相应的缺页异常服务例程。这个缺页异常处理的时机就是求调页/页换入换出/写时复制处理的执行时机,当相关处理完成后,缺页异常服务例程会返回到产生异常的指令处重新执行,使得软件可以继续正常运行下去。
11、操作系统的四个特性
-
并发:同一段时间内多个程序执行(注意区别并行和并发,并行是同一时刻的多个事件,并发是同一时间段内的多个事件)
-
共享:系统中的资源可以被内存中多个并发执行的进线程共同使用
-
虚拟:通过时分复用(如分时系统)以及空分复用(如虚拟内存)技术实现把一个物理实体虚拟为多个
-
异步:系统中的进程是以走走停停的方式执行的,且以一种不可预知的速度推进
12、操作系统的主要功能
-
处理机管理:处理机分配都是以进程为单位,所以处理机管理也被看做是进程管理。包括进程控制,进程同步,进程通信和进程调度
-
存储器管理(或者内存管理):内存分配,内存保护,地址映射,内存扩充
-
设备管理:管理所有外围设备,包括完成用户的IO请求;为用户进程分配IO设备;提高IO设备利用率;提高IO速度;方便IO的使用
-
文件管理:管理用户文件和系统文件,方便使用同时保证安全性。包括:磁盘存储空间管理,目录管理,文件读写管理以及文件共享和保护
-
提供用户接口:程序接口(如API)和用户接口(如GUI)
13、进程和线程以及它们的区别
进程是对运行时程序的封装,是系统进行资源调度和分配的基本单位,实现了操作系统的并发(如:用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等,然后该进程被放入到进程的就绪队列,进程调度程序选中它,为它分配CPU及其他相关资源,该进程就被运行起来);
线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发;
在没有实现线程的操作系统中,进程既是资源分配的基本单位,又是调度的基本单位,它是系统中并发执行的单元。而在实现了线程的操作系统中,进程是资源分配的基本单位,但是线程是调度的基本单位,是系统中并发执行的单元。
引入线程主要有以下4个方面的优点:
1)易于调度。
2)提高并发性。通过线程可以方便有效地实现并发。
3)开销小。创建线程比创建进程要快,所需要的开销也更小。
4)有利于发挥多处理器的功能。通过创建多线程,每个线程都在一个处理器上运行,从而实现应用程序的并行,使每个处理器都得到充分的运行。
尽管线程和进程很相似,但两者也存在着很大的不同,区别如下:
-
一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程而存在;
-
进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存空间。
-
属于一个进程的所有线程共享该进程的所有资源,包括打开的文件,创建的Socket等。不同的进程互相独立。
-
线程又被称为轻量级进程。进程有进程控制块,线程有线程控制块。但线程控制块比进程控制块小得多。线程间切换代价小,进程间切换代价大。
-
进程是程序的一次执行,线程可以理解为程序中一段程序片段的执行。
14、进程间的通信的几种方式
-
管道(pipe)及命名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
-
信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
-
消息队列:消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息;
-
共享内存:可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等;
-
信号量:主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段;
-
套接字:这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。
15、线程同步的方式
-
临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
-
互斥量 :为协调对一个共享资源的单独访问而设计,采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。
-
信号量:为控制一个具有有限数量的用户资源而设计。它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
-
事件(信号):用来通知线程有一些事件已发生,从而启动后继任务的开始保持多线程同步,也可方便的实现多线程优先级的比较操作
16、线程的实现方式(用户线程与内核线程的区别)
根据操作系统内核是否对线程可感知,可以把线程分为内核线程和用户线程。
内核线程建立和销毁都是由操作系统负责、通过系统调用完成的,操作系统在调度时,参考各进程内的线程运行情况做出调度决定,如果一个进程中没有就绪态的线程,那么这个进程也不会被调度占用CPU。
和内核线程相对应的是用户线程,用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,用户进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。用户线程多见于一些历史悠久的操作系统,例如Unix操作系统,不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少为了在操作系统中加入线程支持,采用了在用户空间增加运行库来实现线程,这些运行库被称为“线程包”,用户线程是不能被操作系统所感知的。
引入用户线程,具体而言,有以下四个方面的优势:
(1)可以在不支持线程的操作系统中实现。
(2)创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。
(3)允许每个进程定制自己的调度算法,线程管理比较灵活。
(4)线程能够利用的表空间和堆栈空间比内核级线程多。
用户线程的缺点主要有以下两点:
(1)同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。
(2)页面失效也会产生类似的问题。
内核线程的优缺点刚好跟用户线程相反。实际上,操作系统可以使用混合的方式来实现线程。
17、进程有哪几种状态?
-
就绪状态:当进程已经分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行;
-
运行状态:当进程已获得处理机,其程序正在处理机上执行;
-
阻塞状态: 正在执行的进程,由于某个事件发生而无法执行时,便放弃处理机而处于阻塞状态;引起进程阻塞状态的事件可以有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)。
注意区别就绪状态和等待状态:就绪状态是指进程仅缺少处理机,只要获得处理机资源就立即执行;而等待状态是指进程需要其他资源(除了处理机)或等待某一事件。
就绪状态 -> 运行状态:处于就绪状态的进程被调度后,获得处理机资源(分派处理机时间片),于是进程由就绪状态转换为运行状态。
运行状态 -> 就绪状态:处于运行状态的进程在时间片用完后,不得不让出处理机,从而进程由运行状态转换为就绪状态。此外,在可剥夺的操作系统中,当有更高优先级的进程就 、 绪时,调度程度将正执行的进程转换为就绪状态,让更高优先级的进程执行。
运行状态 -> 阻塞状态:当进程请求某一资源(如外设)的使用和分配或等待某一事件的发生(如I/O操作的完成)时,它就从运行状态转换为阻塞状态。进程以系统调用的形式请求操作系统提供服务,这是一种特殊的、由运行用户态程序调用操作系统内核过程的形式。
阻塞状态 -> 就绪状态:当进程等待的事件到来时,如I/O操作结束或中断结束时,中断处理程序必须把相应进程的状态由阻塞状态转换为就绪状态。
18、用户态和核心态的区别。
当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。
用户态切换到内核态的3种方式:系统调用、异常、外围设备中断。
19、什么是缓冲区溢出?有什么危害?其原因是什么?
缓冲区溢出是指当计算机向缓冲区内填充数据时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。
危害:在当前网络与分布式系统安全中,被广泛利用的50%以上都是缓冲区溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕虫。而缓冲区溢出中,最为危险的是堆栈溢出,因为入侵者可以利用堆栈溢出,在函数返回时改变返回程序的地址,让其跳转到任意地址,带来的危害一种是程序崩溃导致拒绝服务,另外一种就是跳转并且执行一段恶意代码,比如得到shell,然后为所欲为。通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,使程序转而执行其它指令,以达到攻击的目的。
造成缓冲区溢出的主原因是程序中没有仔细检查用户输入的参数。
20、什么是死锁?死锁产生的条件?
1). 死锁的概念
所谓死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了死锁。通俗的讲,就是两个或多个进程无限期的阻塞、相互等待的一种状态。
2). 死锁产生的四个必要条件
-
互斥条件:一个资源每次只能被一个进程使用;若其他进程申请使用该资源,必须等到该资源被释放为止;
-
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
-
不可剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺;
-
循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系;
3). 死锁的解除与预防
(1). 死锁预防
死锁预防的基本思想是 只要确保死锁发生的四个必要条件中至少有一个不成立,就能预防死锁的发生,具体方法包括:
-
注意:互斥条件无法破坏
-
打破请求与保持条件:可以实行资源预先分配策略(进程在运行前一次性向系统申请它所需要的全部资源,若所需全部资源得不到满足,则不分配任何资源,此进程暂不运行;只有当系统能满足当前进程所需的全部资源时,才一次性将所申请资源全部分配给该线程)或者只允许进程在没有占用资源时才可以申请资源(一个进程可申请一些资源并使用它们,但是在当前进程申请更多资源之前,它必须全部释放当前所占有的资源)。但是这种策略也存在一些缺点:在很多情况下,无法预知一个进程执行前所需的全部资源,因为进程是动态执行的,不可预知的;同时,会降低资源利用率,导致降低了进程的并发性。
-
打破不可剥夺条件:允许进程强剥夺使用其他进程占有的资源,从而破坏不可剥夺条件。也就是说,一个进程占有了一部分资源,在其申请新的资源且得不到满足时,它必须释放所有占有的资源以便让其它线程使用。这种预防死锁的方式实现起来困难,会降低系统性能。
-
打破循环等待条件:实行资源有序分配策略,破坏环路条件。对所有资源排序编号,所有进程对资源的请求必须严格按资源序号递增的顺序提出,即只有占用了小号资源才能申请大号资源,这样就不回产生环路,预防死锁的发生。
(2). 死锁避免的基本思想
死锁避免的基本思想是动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。所谓安全状态是指:如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的,换句话说就是,如果存在一个安全序列,那么系统处于安全状态。资源分配图算法和银行家算法是两种经典的死锁避免的算法,其可以确保系统始终处于安全状态。其中,资源分配图算法应用场景为每种资源类型只有一个实例(申请边,分配边,需求边,不形成环才允许分配),而银行家算法应用于每种资源类型可以有多个实例的场景。
银行家算法:该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。这样申请者就可以很快完成其计算,然后释放它占用的资源,从而保证了系统中所有进程都能完成,所以可避免死锁的发生。
21、 内存管理有哪几种方式(块式、页式、段式、段页式).
内存管理有块式管理,页式管理,段式和段页式管理。现在常用段页式管理。
块式管理:把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程序片断load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但是易于管理。
页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高很多。
段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物理地址上。
段页式管理:结合了段式管理和页式管理的优点。将程序分成若干段,每个段分成若干页。段页式管理每取一数据,要访问3次内存。
22、分页和分段有什么区别(内存管理)?
段式存储管理是一种符合用户视角的内存分配管理方案。在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)
页式存储管理方案是一种用户视角内存与物理内存相分离的内存分配管理方案。在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分配。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。
两者的不同点:
-
目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;
-
大小不同:页的大小固定且由系统决定,而段的长度却不固定,由其所完成的功能决定;
-
地址空间不同: 段向用户提供二维地址空间;页向用户提供的是一维地址空间;
-
信息共享:段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制;
-
内存碎片:页式存储管理的优点是没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满);而段式管理的优点是没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。
23、页面置换算法
最佳置换算法OPT:只具有理论意义的算法,用来评价其他页面置换算法。置换策略是将当前页面中在未来最长时间内不会被访问的页置换出去。
先进先出置换算法FIFO:简单粗暴的一种置换算法,没有考虑页面访问频率信息。每次淘汰最早调入的页面。
最近最久未使用算法LRU:算法赋予每个页面一个访问字段,用来记录上次页面被访问到现在所经历的时间t,每次置换的时候把t值最大的页面置换出去(实现方面可以采用寄存器或者栈的方式实现)。
时钟算法clock(也被称为是最近未使用算法NRU):页面设置一个访问位,并将页面链接为一个环形队列,页面被访问的时候访问位设置为1。页面置换的时候,如果当前指针所指页面访问为为0,那么置换,否则将其置为0,循环直到遇到一个访问为位0的页面。
改进型Clock算法:在Clock算法的基础上添加一个修改位,替换时根究访问位和修改位综合判断。优先替换访问位和修改位都是0的页面,其次是访问位为0修改位为1的页面。
LFU最少使用算法LFU:设置寄存器记录页面被访问次数,每次置换的时候置换当前访问次数最少的。
24、操作系统中进程调度策略有哪几种?
-
先来先服务调度算法FCFS:队列实现,非抢占,先请求CPU的进程先分配到CPU,可以作为作业调度算法也可以作为进程调度算法;按作业或者进程到达的先后顺序依次调度,对于长作业比较有利;
-
最短作业优先调度算法SJF:作业调度算法,算法从就绪队列中选择估计时间最短的作业进行处理,直到得出结果或者无法继续执行,平均等待时间最短,但难以知道下一个CPU区间长度;缺点:不利于长作业;未考虑作业的重要性;运行时间是预估的,并不靠谱 ;
-
优先级调度算法(可以是抢占的,也可以是非抢占的):优先级越高越先分配到CPU,相同优先级先到先服务,存在的主要问题是:低优先级进程无穷等待CPU,会导致无穷阻塞或饥饿;
-
时间片轮转调度算法(可抢占的):按到达的先后对进程放入队列中,然后给队首进程分配CPU时间片,时间片用完之后计时器发出中断,暂停当前进程并将其放到队列尾部,循环 ;队列中没有进程被分配超过一个时间片的CPU时间,除非它是唯一可运行的进程。如果进程的CPU区间超过了一个时间片,那么该进程就被抢占并放回就绪队列。
-
高相应比算法HRN:响应比=(等待时间+要求服务时间)/要求服务时间;
-
多级队列调度算法:将就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。其中,一个进程根据自身属性被永久地分配到一个队列中。
-
多级反馈队列调度算法:目前公认较好的调度算法;设置多个就绪队列并为每个队列设置不同的优先级,第一个队列优先级最高,其余依次递减。优先级越高的队列分配的时间片越短,进程到达之后按FCFS放入第一个队列,如果调度执行后没有完成,那么放到第二个队列尾部等待调度,如果第二次调度仍然没有完成,放入第三队列尾部…。只有当前一个队列为空的时候才会去调度下一个队列的进程。与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多CPU时间,那么它会被转移到更低的优先级队列;在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。
25、说一说进程同步有哪几种机制
原子操作、信号量机制、自旋锁管程、会合、分布式系统
26、什么是虚拟内存?
1).内存的发展历程
没有内存抽象(单进程,除去操作系统所用的内存之外,全部给用户程序使用) —> 有内存抽象(多进程,进程独立的地址空间,交换技术(内存大小不可能容纳下所有并发执行的进程)
)—> 连续内存分配(固定大小分区(多道程序的程度受限),可变分区(首次适应,最佳适应,最差适应),碎片) —> 不连续内存分配(分段,分页,段页式,虚拟内存)
2).虚拟内存
虚拟内存允许执行进程不必完全在内存中。虚拟内存的基本思想是:每个进程拥有独立的地址空间,这个空间被分为大小相等的多个块,称为页(Page),每个页都是一段连续的地址。这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立刻进行必要的映射;当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的命令。这样,对于进程而言,逻辑上似乎有很大的内存空间,实际上其中一部分对应物理内存上的一块(称为帧,通常页和帧大小相等),还有一些没加载在内存中的对应在硬盘上,如图所示。
注意,请求分页系统、请求分段系统和请求段页式系统都是针对虚拟内存的,通过请求实现内存与外存的信息置换。
由图可以看出,虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问MMU(内存管理单元)去匹配对应的物理地址(比如图5的0,1,2)。如果虚拟内存的页并不存在于物理内存中(如图5的3,4),会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。
3). 虚拟内存的应用与优点
虚拟内存很适合在多道程序设计系统中使用,许多程序的片段同时保存在内存中。当一个程序等待它的一部分读入内存时,可以把CPU交给另一个进程使用。虚拟内存的使用可以带来以下好处:
-
在内存中可以保留多个进程,系统并发度提高
-
解除了用户与内存之间的紧密约束,进程可以比内存的全部空间还大
27、颠簸
颠簸本质上是指频繁的页调度行为,具体来讲,进程发生缺页中断,这时,必须置换某一页。然而,其他所有的页都在使用,它置换一个页,但又立刻再次需要这个页。因此,会不断产生缺页中断,导致整个系统的效率急剧下降,这种现象称为颠簸(抖动)。
内存颠簸的解决策略包括:
-
如果是因为页面替换策略失误,可以修改替换算法来解决这个问题;
-
如果是因为运行的程序太多,造成程序无法同时将所有频繁访问的页面调入内存,则要降低多道程序的数量;
-
否则,还剩下两个办法:终止该进程或增加物理内存容量。
28、局部性原理
(1). 时间上的局部性:最近被访问的页在不久的将来还会被访问;
(2). 空间上的局部性:内存中被访问的页周围的页也很可能被访问。