你们好,我是 Guide 哥!不少读者抱怨计算操做系统的知识点比较繁杂,本身也没有多少耐心去看,可是面试的时候又常常会遇到。因此,我带着我整理好的操做系统的常见问题来啦!这篇文章总结了一些我以为比较重要的操做系统相关的问题好比进程管理、内存管理、虚拟内存等等。html
文章形式经过大部分比较喜欢的面试官和求职者之间的对话形式展开。另外,Guide 哥也只是在大学的时候学习过操做系统,不过基本都忘了,为了写这篇文章这段时间看了不少相关的书籍和博客。若是文中有任何须要补充和完善的地方,你均可以在评论区指出。若是以为内容不错的话,不要忘记点个在看哦!java
我我的以为学好操做系统仍是很是有用的,具体能够看我昨天在星球分享的一段话:git
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-11/image-20200329145912767.png" height="666"/>github
这篇文章只是对一些操做系统比较重要概念的一个概览,深刻学习的话,建议你们仍是老老实实地去看书。另外, 这篇文章的不少内容参考了《现代操做系统》第三版这本书,很是感谢。面试
面试官顶着蓬松的假发向我走来,只见他一手拿着厚重的 Thinkpad ,一手提着他那淡黄的长裙。算法
<img src="http://wx4.sinaimg.cn/large/ceeb653ely1gd8wj5evc4j20i00n0dh0.jpg" height="300"></img>编程
👨💻面试官 : 先来个简单问题吧!什么是操做系统?windows
🙋 我 :我经过如下四点向您介绍一下什么是操做系统吧!数组
关于内核多插一嘴:内核负责管理系统的进程、内存、设备驱动程序、文件和网络系统等等,决定着系统的性能和稳定性。是链接应用程序和硬件的桥梁。
内核就是操做系统背后黑盒的核心。
👨💻面试官 :什么是系统调用呢? 能不能详细介绍一下。缓存
🙋 我 :介绍系统调用以前,咱们先来了解一下用户态和系统态。
<img src="http://ww4.sinaimg.cn/large/006r3PQBjw1fbimb5c3srj30b40b40t9.jpg" height="200" width="2"/>
根据进程访问资源的特色,咱们能够把进程在系统上的运行分为两个级别:
说了用户态和系统态以后,那么什么是系统调用呢?
咱们运行的程序基本都是运行在用户态,若是咱们调用操做系统提供的系统态级别的子功能咋办呢?那就须要系统调用了!
也就是说在咱们运行的用户程序中,凡是与系统态级别的资源有关的操做(如文件管理、进程控制、内存管理等),都必须经过系统调用方式向操做系统提出服务请求,并由操做系统代为完成。
这些系统调用按功能大体可分为以下几类:
👨💻面试官: 好的!我明白了!那你再说一下: 进程和线程的区别。
🙋 我: 好的! 下图是 Java 内存区域,咱们从 JVM 的角度来讲一下线程和进程之间的关系吧!
若是你对 Java 内存区域 (运行时数据区) 这部分知识不太了解的话能够阅读一下这篇文章: 《多是把 Java 内存区域讲的最清楚的一篇文章》>)
从上图能够看出:一个进程中能够有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 以后的元空间)资源,可是每一个线程有本身的程序计数器、虚拟机栈 和 本地方法栈。
总结: 线程是进程划分红的更小的运行单位,一个进程在其执行的过程当中能够产生多个线程。线程和进程最大的不一样在于基本上各进程是独立的,而各线程则不必定,由于同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。
👨💻面试官 : 那你再说说进程有哪几种状态?
🙋 我 :咱们通常把进程大体分为 5 种状态,这一点和线程很像!
👨💻面试官 :进程间的通讯常见的的有哪几种方式呢?
🙋 我 :大概有 7 种常见的进程间的通讯方式。
下面这部分总结参考了: 《进程间通讯 IPC (InterProcess Communication)》 这篇文章,推荐阅读,总结的很是不错。
👨💻面试官 :那线程间的同步的方式有哪些呢?
🙋 我 :线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以免关键的资源使用冲突。操做系统通常有下面三种线程同步的方式:
👨💻面试官 :你知道操做系统中进程的调度算法有哪些吗?
🙋 我 :嗯嗯!这个咱们大学的时候学过,是一个很重要的知识点!
为了肯定首先执行哪一个进程以及最后执行哪一个进程以实现最大 CPU 利用率,计算机科学家已经定义了一些算法,它们是:
👨💻 面试官: 操做系统的内存管理主要是作什么?
🙋 我: 操做系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操做系统内存管理作的事情。
👨💻 面试官: 操做系统的内存管理机制了解吗?内存管理有哪几种方式?
🙋 我: 这个在学习操做系统的时候有了解过。
简单分为连续分配管理方式和非连续分配管理方式这两种。连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如 块式管理 。一样地,非连续分配管理方式容许一个程序使用的内存分布在离散或者说不相邻的内存中,常见的如页式管理 和 段式管理。
👨💻面试官 : 回答的还不错!不过漏掉了一个很重要的 段页式管理机制 。段页式管理机制结合了段式管理和页式管理的优势。简单来讲段页式管理机制就是把主存先分红若干段,每一个段又分红若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。
🙋 我 :谢谢面试官!刚刚把这个给忘记了~
<img src="http://ww4.sinaimg.cn/large/6af89bc8gw1f8txoxc2asj20k00k0mxv.jpg" alt="这就很尴尬了_尴尬表情" height="200" width="200"/>
👨💻面试官 : 页表管理机制中有两个很重要的概念:快表和多级页表,这两个东西分别解决了页表管理中很重要的两个问题。你给我简单介绍一下吧!
🙋 我 :在分页内存管理中,很重要的两点是:
为了解决虚拟地址到物理地址的转换速度,操做系统在 页表方案 基础之上引入了 快表 来加速虚拟地址到物理地址的转换。咱们能够把块表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者所有内容。做为页表的 Cache,它的做用与页表类似,可是提升了访问速率。因为采用页表作地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提升指令执行速度。
使用快表以后的地址转换流程是这样的:
看完了以后你会发现快表和咱们平时常常在咱们开发的系统使用的缓存(好比 Redis)很像,的确是这样的,操做系统中的不少思想、不少经典的算法,你均可以在咱们平常开发使用的各类工具或者框架中找到它们的影子。
引入多级页表的主要目的是为了不把所有页表一直放在内存中占用过多空间,特别是那些根本就不须要的页表就不须要保留在内存中。多级页表属于时间换空间的典型场景,具体能够查看下面这篇文章
为了提升内存的空间性能,提出了多级页表的概念;可是提到空间性能是以浪费时间性能为基础的,所以为了补充损失的时间性能,提出了快表(即 TLB)的概念。 不管是快表仍是多级页表实际上都利用到了程序的局部性原理,局部性原理在后面的虚拟内存这部分会介绍到。
👨💻面试官 : 分页机制和分段机制有哪些共同点和区别呢?
🙋 我 :
<img src="http://wx3.sinaimg.cn/large/de80a5ably1gcuslckpygg208c08cwfu.gif" height="200" width="200"></img>
共同点 :
区别 :
👨💻面试官 :你刚刚还提到了逻辑地址和物理地址这两个概念,我不太清楚,你能为我解释一下不?
🙋 我: em...好的嘛!咱们编程通常只有可能和逻辑地址打交道,好比在 C 语言中,指针里面存储的数值就能够理解成为内存里的一个地址,这个地址也就是咱们说的逻辑地址,逻辑地址由操做系统决定。物理地址指的是真实物理内存中地址,更具体一点来讲就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。
👨💻面试官 :CPU 寻址了解吗?为何须要虚拟地址空间?
🙋 我 :这部分我真不清楚!
<img src="http://wx2.sinaimg.cn/bmiddle/a9cf8ef6ly1fhqpdipcyfj20ce0b4wex.jpg " height="300px" />
因而面试完以后我默默去查阅了相关文档!留下了没有技术的泪水。。。
这部份内容参考了 Microsoft 官网的介绍,地址: https://msdn.microsoft.com/zh...
现代处理器使用的是一种称为 虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU 须要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件。以下图所示:
为何要有虚拟地址空间呢?
先从没有虚拟地址空间的时候提及吧!没有虚拟地址空间的时候,程序都是直接访问和操做的都是物理内存 。可是这样有什么问题呢?
总结来讲:若是直接把物理地址暴露出来的话会带来严重问题,好比可能对操做系统形成伤害以及给同时运行多个程序形成困难。
经过虚拟地址访问内存有如下优点:
👨💻面试官 :再问你一个常识性的问题!什么是虚拟内存(Virtual Memory)?
🙋 我 :这个在咱们平时使用电脑特别是 Windows 系统的时候太常见了。不少时候咱们使用点开了不少占内存的软件,这些软件占用的内存可能已经远远超出了咱们电脑自己具备的物理内存。为何能够这样呢? 正是由于 虚拟内存 的存在,经过 虚拟内存 可让程序能够拥有超过系统物理内存大小的可用内存空间。另外,虚拟内存为每一个进程提供了一个一致的、私有的地址空间,它让每一个进程产生了一种本身在独享主存的错觉(每一个进程拥有一片连续完整的内存空间)。这样会更加有效地管理内存并减小出错。
虚拟内存是计算机系统内存管理的一种技术,咱们能够手动设置本身电脑的虚拟内存。不要单纯认为虚拟内存只是“使用硬盘空间来扩展内存“的技术。虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,而且 把内存扩展到硬盘空间。推荐阅读:《虚拟内存的那点事儿》
维基百科中有几句话是这样介绍虚拟内存的。
虚拟内存 使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它一般是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在须要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如 RAM)的使用也更有效率。目前,大多数操做系统都使用了虚拟内存,如 Windows 家族的“虚拟内存”;Linux 的“交换空间”等。From: https://zh.wikipedia.org/wiki...
👨💻面试官 :要想更好地理解虚拟内存技术,必需要知道计算机中著名的局部性原理。另外,局部性原理既适用于程序结构,也适用于数据结构,是很是重要的一个概念。
🙋 我 :局部性原理是虚拟内存技术的基础,正是由于程序运行具备局部性原理,才能够只装入部分程序到内存就开始运行。
如下内容摘自《计算机操做系统教程》 第 4 章存储器管理。
早在 1968 年的时候,就有人指出咱们的程序在执行的时候每每呈现局部性规律,也就是说在某个较短的时间段内,程序执行局限于某一小部分,程序访问的存储空间也局限于某个区域。
局部性原理表如今如下两个方面:
时间局部性是经过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性一般是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是创建了 “内存一外存”的两级存储器的结构,利用局部性原理实现髙速缓存。
👨💻面试官 :都说了虚拟内存了。你再讲讲虚拟存储器把!
🙋 我 :
这部份内容来自: 王道考研操做系统知识点整理。
基于局部性原理,在程序装入时,能够将程序的一部分装入内存,而将其余部分留在外存,就能够启动程序执行。因为外存每每比内存大不少,因此咱们运行的软件的内存大小其实是能够比计算机系统实际的内存大小大的。在程序执行过程当中,当所访问的信息不在内存时,由操做系统将所须要的部分调入内存,而后继续执行程序。另外一方面,操做系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器。
实际上,我以为虚拟内存一样是一种时间换空间的策略,你用 CPU 的计算时间,页的调入调出花费的时间,换来了一个虚拟的更大的空间来支持程序的运行。不得不感叹,程序世界几乎不是时间换空间就是空间换时间。
👨💻面试官 :虚拟内存技术的实现呢?
🙋 我 :虚拟内存的实现须要创建在离散分配的内存管理方式的基础上。 虚拟内存的实现有如下三种方式:
这里多说一下?不少人容易搞混请求分页与分页存储管理,二者有何不一样呢?
请求分页存储管理创建在分页管理之上。他们的根本区别是是否将程序所有所需的所有地址空间都装入主存,这也是请求分页存储管理能够提供虚拟内存的缘由,咱们在上面已经分析过了。
它们之间的根本区别在因而否将一做业的所有地址空间同时装入主存。请求分页存储管理不要求将做业所有地址空间同时装入主存。基于这一点,请求分页存储管理能够提供虚存,而分页存储管理却不能提供虚存。
无论是上面那种实现方式,咱们通常都须要:
👨💻面试官 :虚拟内存管理很重要的一个概念就是页面置换算法。那你说一下 页面置换算法的做用?常见的页面置换算法有哪些?
🙋 我 :
这个题目常常做为笔试题出现,网上已经给出了很不错的回答,我这里只是总结整理了一下。
地址映射过程当中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断 。
缺页中断 就是要访问的 页不在主存,须要操做系统将其调入主存后再进行访问。 在这个时候,被内存映射的文件实际上成了一个分页交换文件。
当发生缺页中断时,若是当前内存中并无空闲的页面,操做系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫作页面置换算法,咱们能够把页面置换算法当作是淘汰页面的规则。
做者介绍: Github 70k Star 项目 JavaGuide(公众号同名) 做者。每周都会在公众号更新一些本身原创干货。公众hao后台回复“1”领取Java工程师必备学习资料+面试突击pdf。