计算机基础知识整理


前言

这篇博客用来整理需要掌握的计算机基础知识,包括计算机网络与操作系统。


一、计算机网络

1. OSI与TCP/IP各层的结构与功能,都有哪些协议?

开放式系统互联通信参考模型(英语:Open System Interconnection Reference Model,缩写为 OSI),简称为OSI模型(OSI model),一种概念模型,由国际标准化组织提出,一个试图使各种计算机在世界范围内互连为网络的标准框架。

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。

学习计算机网络时我们一般采用折中的办法,也就是中和OSI和TCP/IP的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚。
在这里插入图片描述
结合互联网的情况,自上而下简要介绍一下各层的作用:

  • 应用层
    应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等等。我们把应用层交互的数据单元称为报文

    • 域名系统DNS
      域名系统(Domain Name System,缩写DNS)作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP数串。例如:一个公司的Web 网站可看作是它在网上的门户,而域名就相当于其门牌地址,通常域名都使用该公司的名称或简称。例如 IBM 公司的域名是 www.ibm.com、Oracle 公司的域名是 www.oracle.com、Cisco 公司的域名是 www.cisco.com 等。
    • HTTP协议
      超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,所有的WWW(万维网)文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
  • 运输层
    运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可以同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。

    运输层主要使用以下两种协议:

    • 传输控制协议TCP(Transmission Control Protocol)——提供面向连接的,可靠的数据传输服务。
    • 用户数据协议UDP(User Datagram Protocol)——提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。

    TCP与UDP的对比见问题3。

  • 网络层
    在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在TCP/IP体系结构中,由于网络层使用IP协议,因此分组也叫IP数据报﹐简称数据报

    这里要注意:不要把运输层的“用户数据报UDP”和网络层的“IP数据报”弄混。另外,无论是哪一层的数据单元,都可笼统地用"分组”来表示。这里强调指出,网络层中的“网络”二字已经不是我们通常谈到的具体网络,而是指计算机网络体系结构模型中第三层的名称。

    互联网是由大量的异构(heterogeneous)网络通过路由器(router)相互连接起来的。互联网使用的网络层协议是无连接的网际协议(Intert Protocol)和许多路由选择协议,因此互联网的网络层也叫做网际层IP层

  • 数据链路层
    数据链路层(data link layer)通常简称为链路层。两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。

    在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。控制信息还使接收端能够检测到所收到的帧中有没有差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。如果需要改正数据在链路层传输时出现的差错(数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。

  • 物理层
    在物理层上所传送的数据单位是比特。物理层(physical layer)的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,使其上面的数据链路层不必考虑网络的具体传输介质是什么透明的意思是经实际电路传送后的比特流没有发生变化,对传送的比特流来说,这个电路好像是看不见的。

在这里插入图片描述

2. TCP 三次握⼿和四次挥⼿

三次握手

为了准确无误地把数据送达目标处,TCP 协议采用了三次握手策略。

在这里插入图片描述
简单示意图:
在这里插入图片描述
三次握手分别如下:

  • 客户端——发送带有 SYN 标志的数据包——一次握手——服务端
  • 服务端——发送带有 SYN/ACK 标志的数据包——二次握手——客户端
  • 客户端——发送带有带有 ACK 标志的数据包——三次握手——服务端

具体来说,TCP 的三次握手是这样进行的:发送端发送一个 SYN=1,ACK=0标志的数据包给接收端,请求进行连接,这是第一次握手;接收端收到请求并且允许连接的话,就会发送一个SYN=1,ACK=1标志的数据包给发送端,告诉它可以通讯了,并且让发送端发送一个确认数据包,这是第二次握手;最后,发送端发送一个SYN=0,ACK=1的数据包给接收端,告诉它连接已被确认,这就是第三次握手。之后,一个TCP连接建立,开始通讯。

SYN 是同步序列编号(Synchronize Sequence Numbers),是 TCP 建立连接时使用的握手信号,我们称之为同步标志。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。

ACK (Acknowledge character)是确认字符,我们称之为确认标志,它表示确认发来的数据已经接收无误,提示远端系统已经成功接收所有数据。

为什么要三次握手?

三次握手的目的是建立可靠的通信信道,双方确认自己与对方的发送与接收是正常的。说到通信,简单来说就是数据的发送与接收:

  • 第一次握手:Client 什么都不能确认;Server确认了对方发送正常,自己接收正常
  • 第二次握手:Client 确认了自己发送、接收正常,对方发送、接收正常;Server 确认了对方发送正常,自己接收正常
  • 第三次握手:Client 确认了自己发送、接收正常,对方发送、接收正常;Server 确认了自己发送、接收正常,对方发送、接收正常

所以三次握手就能确认双方收发功能都正常,缺一不可。

为什么要传回 SYN?

接收端传回发送端所发送的SYN是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。

传了SYN,为什么还要传ACK?

双方通信无误必须是两者互相发送信息都无误。传了SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要ACK信号来进行验证。

四次挥手

断开一个TCP连接则需要“四次挥手”:

  • 客户端——发送一个FIN,用来关闭客户端到服务端的数据传送
  • 服务端——收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。
  • 服务端——关闭与客户端的连接,发送一个FIN给客户端
  • 客户端——发回 ACK 报文确认,并将确认序号设置为收到序号加1

在这里插入图片描述
FIN 是一个结束标志,带有该标志置位的数据包用来结束一个 TCP 会话。

具体来说, 第一次挥手:主动关闭方发送一个FIN并进入FIN_WAIT1状态; 第二次挥手:被动关闭方接收到主动关闭方发送的FIN并发送ACK,此时被动关闭方进入CLOSE_WAIT状态;主动关闭方收到被动关闭方的ACK后,进入FIN_WAIT2状态; 第三次挥手:被动关闭方发送一个FIN并进入LAST_ACK状态; 第四次挥手:主动关闭方收到被动关闭方发送的FIN并发送ACK,此时主动关闭方进入TIME_WAIT状态,经过 2ms 时间后关闭连接;被动关闭方收到主动关闭方的ACK后,关闭连接。

为什么要四次挥手?

任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。

举个例子:A和B打电话,通话即将结束后,A说“我没啥要说的了”,B回答“我知道了”,但是B可能还会有要说的话,A不能要求B跟着自己的节奏结束通话,于是B可能又巴拉巴拉说了一通,最后B说“我说完了”,A回答“知道了”,这样通话才算结束。

3. TCP 和 UDP 的区别

在这里插入图片描述
UDP 在传送数据之前不需要先建立连接,另一方在收到 UDP 报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但在某些情况下UDP确是一种最有效的工作方式(一般用于即时通信),比如QQ语音、QQ视频、直播等等。

TCP 在传送数据之前必须先建立连接,数据传送结束后要释放连接。由于TCP 要提供可靠的,面向连接的传输服务,这不可避免地增加了许多开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP一般用于文件传输、发送和接收邮件、远程登录等场景。

4. TCP协议如何保证可靠传输

简单来说,TCP 的可靠性体现在:传递数据之前会有三次握手来建立连接,在数据传递时有确认、重传、窗口、拥塞控制机制,在数据传完后还会通过四次挥手断开连接来节约系统资源。

具体来说:

  • 应用数据被分割成 TCP 认为最适合发送的数据块
  • TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  • 校验和:TCP将保持它首部和数据的检验和,目的是检测数据在传输过程中的任何变化。如果收到端的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
  • TCP 的接收端会丢弃重复的数据
  • 流量控制:TCP 连接的每一端都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。
  • 拥塞控制:当网络拥塞时,减少数据的发送。
  • ARQ 协议:目的也是为了实现可靠传输,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  • 超时重传:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

5. ARQ协议

自动重传请求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中数据链路层和运输层的错误纠正协议之一。它通过使用确认超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。简单来说,如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ 包括停止等待 ARQ 协议连续 ARQ 协议

停止等待 ARQ 协议

  • 停止等待协议的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后)﹐还是没有收到ACK确认帧,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;
  • 在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认;
  • 优点:简单;缺点:信道利用率低,等待时间长
  • 利用停止等待协议进行数据传输时会出现以下三种情况:
    • 无差错情况
      发送方发送分组,接收方在规定时间内收到,并且及时回复确认,发送方再次发送下一组数据。
    • 超时重传
      超时重传是指只要超过一段时间仍然没有收到确认,发送方就会认为刚才发送过的分组丢失了,就会重传前面发送过的分组。因此每发送完一个分组需要设置一个超时计时器,其重传时间应比数据分组传输的平均往返时间更长一些。
    • 确认丢失和确认迟到
      确认丢失:确认消息在传输过程丢失。当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:①丢弃这个重复的M1消息,不向上层交付;②向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。
      确认迟到:确认消息在传输过程中迟到。A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:①A收到重复的确认后,直接丢弃;②B收到重复的M1后,也直接丢弃重复的M1。

连续ARQ协议

  • 连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
  • 优点:信道利用率高,容易实现,即使确认丢失,也不必重传。
  • 缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。比如:发送方发送了5条消息,中间第三条丢失,这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退N),表示需要退回来重传已经发送过的N个消息。

6. 滑动窗口和流量控制

TCP 连接的每一端都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。

TCP 利用可变大小的滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收,防止包丢失。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为0,则发送方不能发送数据。

7. 拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况就叫拥塞拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。

拥塞控制和流量控制的区别是什么?拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

为了进行拥塞控制,TCP 发送方要维持一个拥塞窗口(cwnd)的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

TCP的拥塞控制采用了四种算法,即慢开始拥塞避免快重传快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理AQM) ,以减少网络拥塞的发生。

  • 慢开始:慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络拥塞,因为现在还不知道网络的负荷情况。较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。拥塞窗口初始值为1,每经过一个传播轮次,拥塞窗口的大小加倍。
  • 拥塞避免:拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个传播轮次就把发送方的拥塞窗口加1。
  • 快重传与快恢复:快速重传和恢复(fast retransmit and recovery,FRR)能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了FRR,如果接收方接收到一个不按顺序的数据段,它会立即给发送方发送一个重复确认。如果发送方接收到三个重复确认,它会假定确认中指出的数据段丢失了,并立即重传这些丢失的数据段。有了FRR,数据传输就不会因为重传时要求的暂停被耽误。当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据包在某一段很短的时间内丢失时,它则不能很有效地工作。

8. 阐述在浏览器中输入 url 地址→显示主页的过程

这个问题还可以追问:打开一个网页,整个过程会使用哪些协议?
在这里插入图片描述

9. 状态码

在这里插入图片描述

10. 各种协议与HTTP协议之间的关系

在这里插入图片描述

11. HTTP长连接,短连接

在 HTTP/1.0 中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:Connection: keep-alive。在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

12. HTTP 1.0和HTTP 1.1的主要区别是什么?

HTTP 1.0最早在网页中使用是在1996年,当时只是使用在一些较为简单的网页上和网络请求上,而HTTP1.1则在1999年才开始广泛应用于现在的各大浏览器网络请求中,同时HTTP1.1也是当前使用最为广泛的HTTP协议。主要区别主要体现在:

  • 长短连接:在 HTTP/1.0 中,默认使用的是短连接,每进行一次 HTTP 操作都要重新建立一次连接。HTTP是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手或四次挥手的开销,如果每次请求都要这样的话,开销会比较大。在 HTTP 1.1 中,默认使用长连接,可以用一个长连接来发多个请求。HTTP/1.1的长连接有流水线方式和非流水线方式。流水线方式是指客户端在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是指客户在收到前一个响应后才能发送下一个请求。
  • 错误状态响应码:在HTTP1.1中新增了24个错误状态响应码,如409 (Conflict)表示请求的资源与资源的当前状态发生冲突;410 (Gone)表示服务器上的某个资源被永久性的删除。
  • 缓存处理:在HTTP1.0中主要使用header里的If-Modified-Since, Expires(如果修改过,则过期)来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略,例如Entity tag(实体标记),If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头。
  • 带宽优化及网络连接的使用:HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能;HTTP1.1则在请求头引入了range头域,它允许只请求对象的某个部分,这样就方便了开发者自由的选择以便于充分利用带宽和连接。

13. HTTP是不保存状态的协议,如何保存用户状态?

HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说,HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们如何保存用户状态呢?Session机制的存在就是为了解决这个问题,Session的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为HTTP协议是无状态的。服务器给特定的用户创建特定的 Session 之后就可以标识并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个Session,过了时间限制就会销毁这个Session)。

在服务端保存Session的方法很多,最常用的就是内存和数据库(比如使用内存数据库 redis 保存)。既然Session存放在服务器端,那么我们如何实现Session跟踪呢?大部分情况下,我们都是通过在Cookie 中附加一个 Session ID 的方式来跟踪

Cookie被禁用怎么办?最常用的就是利用URL重写把Session ID直接附加在URL路径的后面。

14. Cookie 的作用是什么?和 Session 有什么区别?

Cookie和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。

Cookie 是指某些网站为了辨别用户身份、进行 session 跟踪而储存在客户端上的数据。比如:①我们在Cookie中保存已经登录过的用户信息,下次访问网站的时候页面可以自动帮我们把登录的一些基本信息给填了;②一般的网站都允许保持登录,也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们存放了一个令牌Token在Cookie 中,下次登录的时候只需要根据Token值来查找用户即可(为了安全考虑,重新登录一般要将Token重写);③登录网站后访问网站的其他页面不需要重新登录。

Session的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为HTTP协议是无状态的。服务器给特定的用户创建特定的Session之后就可以标识并且跟踪这个用户了。

Cookie数据保存在客户端(浏览器端),Session数据保存在服务器端。相对来说Session安全性更高,如果要在Cookie中存储一些敏感信息,不要直接写入Cookie中,最好能将Cookie信息加密然后使用的时候再去服务器端解密。

15. URI和URL的区别是什么?

  • URI(Uniform Resource Identifier)是统一资源标志符,可以唯一标识一个资源。
  • URL(Uniform Resource Location)是统一资源定位符,可以提供该资源的路径。它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何定位这个资源。
  • URI的作用像身份证号一样,URL的作用更像家庭住址一样。

16. HTTP和HTTPS的区别?

  • 端口:HTTP的URL由“ http://” 起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。
  • 安全性和资源消耗:HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS协议是运行在SSL/TLS之上的HTTP协议,SSL/TLS运行在TCP之上。所有传输的内容都经过对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP安全性没有HTTPS高,但是HTTPS比HTTP耗费更多服务器资源。
    • 对称加密:密钥只有一个,加密解密为同一个密钥,且加解密速度快,典型的对称加密算法有DES、AES等;
    • 非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有DSA、RSA等。

二、操作系统

1. 操作系统基础

什么是操作系统?

通过以下四点向您介绍一下什么是操作系统吧:

  • 操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的程序,是计算机系统的内核与基石;
  • 操作系统本质上是运行在计算机上的软件程序;
  • 操作系统为用户提供一个与系统交互的操作界面;
  • 操作系统分内核与外壳(我们可以把外壳理解成围绕着内核的应用程序,而内核就是能操作硬件的程序)。
    关于内核多插一嘴:内核负责管理系统的进程、内存、设备驱动程序、文件和网络系统等等,决定着系统的性能和稳定性。是连接应用程序和硬件的桥梁。内核就是操作系统背后黑盒的核心。

在这里插入图片描述

什么是系统调用?

在介绍系统调用之前,需要先熟悉两个概念:用户态和系统态。

根据进程访问资源的特点,我们可以把进程在系统上的运行分为两个级别:

  • 用户态(user mode):用户态运行的进程或可以直接读取用户程序的数据。
  • 系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。

那什么是系统调用呢?

我们运行的程序基本都是运行在用户态,当我们调用操作系统提供的系统态级别的子功能时,就需要系统调用了!也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。

系统调用按功能大致可分为如下几类:

  • 设备管理:完成设备的请求或释放,以及设备启动等功能。
  • 进程控制:完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信:完成进程之间的消息传递或信号传递等功能。
  • 文件管理:完成文件的读、写、创建及删除等功能。
  • 内存管理:完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。

2. 进程和线程

进程和线程的区别

下图是 Java 内存区域,我们从 JVM 的角度来说一下线程和进程之间的关系吧!
在这里插入图片描述
从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆和方法区(JDK1.8之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈。

总结:线程是进程划分成的更小的运行单位,一个进程在其执行的过程中可以产生多个线程。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。

进程有哪几种状态?

我们一般把进程大致分为5种状态,这一点和线程很像:

  • 创建状态(new):进程正在被创建,尚未到就绪状态。
  • 就绪状态(ready):进程已处于准备运行状态,即进程获得了除了处理器之外的所需的一切资源,一旦得到处理器资源(处理器分配的时间片)即可运行。
  • 运行状态(running):进程正在处理器上运行(单核CPU下任意时刻只有一个进程处于运行状态)。
  • 阻塞状态(waiting):又称为等待状态,进程正在等待某一事件而暂停运行,如等待某资源为可用或等待IO操作完成。即使处理器空闲,该进程也不能运行。
  • 结束状态(terminated):进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运行。

在这里插入图片描述

进程间的通信方式有哪些?

大概有7种常见的进程间的通信方式:

  • 管道/匿名管道(Pipes):用于具有亲缘关系的父子进程间或者兄弟进程间的通信,只存在于内存中的文件。
  • 有名管道(Names Pipes):匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出first in first out)。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
  • 信号(Signal)︰信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
  • 消息队列(Message Queuing):消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是,消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取,比 FIFO 更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  • 信号量(Semaphores):信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
  • 共享内存(Shared memory):使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。
  • 套接字(Sockets):此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持TCP/IP的网络通信的基本操作单元,可以看作是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

线程间的同步的方式有哪些?

线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键的资源使用冲突。操作系统一般有下面三种线程同步的方式:

  • 互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如Java 中的synchronized关键词和各种Lock都是这种机制。
  • 信号量(Semphares):它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
  • 事件(Event):Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便地实现多线程优先级的比较操作。

操作系统中进程的调度算法有哪些?

为了确定首先执行哪个进程以及最后执行哪个进程以实现最大 CPU 利用率,计算机科学家已经定义了一些算法,它们是:

  • 先到先服务(FCFS)调度算法:从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
  • 短作业优先(SJF)的调度算法:从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度。
  • 时间片轮转调度算法:时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法,又称 RR(robin)调度。每个进程被分配一个时间段,称作它的时间片,表示该进程允许运行的时间。
  • 多级反馈队列调度算法:前面介绍的几种进程调度的算法都有一定的局限性。如短优作业先的调度算法,仅照顾了短进程而忽略了长进程。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成,因而它是目前被公认的一种较好的进程调度算法,UNIX操作系统采取的便是这种调度算法。
  • 优先级调度:为每个进程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求、时间要求或任何其他资源要求来确定优先级。

3. 操作系统内存管理基础

操作系统的内存管理主要是做什么?

操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存),地址转换(将逻辑地址转换成相应的物理地址等功能)。

常见的几种内存管理机制(内存管理有哪几种方式)

简单来说,可以分为连续分配管理方式非连续分配管理方式这两种。连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如块式管理。同样地,非连续分配管理方式允许一个程序使用的内存分布在离散或者不相邻的内存中,常见的如页式管理和段式管理。

  • 块式管理:一种古老的计算机操作系统的内存管理方式。将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片
  • 页式管理:把主存划分为大小相等且固定的一页一页的形式,页较小,相比于块式管理它的划分力度更大,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址。
  • 段式管理:页式管理虽然提高了内存利用率,但是页式管理其中的页实际并无任何实际意义。段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。段式管理通过段表对应逻辑地址和物理地址。
  • 段页式管理:段页式管理机制结合了段式管理和页式管理的优点。简单来说,段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说段页式管理机制中段与段之间以及段的内部的都是离散的。

快表和多级页表

页表管理机制中有两个很重要的概念:快表和多级页表,这两个东西分别解决了页表管理中很重要的两个问题。你给我简单介绍一下吧!

在分页内存管理中,需要解决的很重要的两点是:

  • 虚拟地址到物理地址的转换要快。
  • 解决虚拟地址空间大,页表也会很大的问题。

快表

操作系统在页表方案基础之上引入了快表来加速虚拟地址到物理地址的转换。我们可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的高速缓冲存储器 Cache,它的作用与页表相似,但是提高了访问速率。采用页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器、一次主存,这样可加速查找并提高指令执行速度。

使用快表之后的地址转换流程是这样的:

  • 根据虚拟地址中的页号查快表;
  • 如果该页在快表中,直接从快表中读取相应的物理地址;
  • 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;
  • 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。

多级页表

引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。多级页表属于时间换空间的典型场景。

总结

为了提高内存的空间性能,提出了多级页表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表的概念。不论是快表还是多级页表实际上都利用到了程序的局部性原理,局部性原理在后面的虚拟内存这部分会介绍到。

分页机制和分段机制的共同点和区别

共同点

  • 分页机制和分段机制都是为了提高内存利用率,减少内存碎片
  • 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和每个段中的内存是连续的。

区别

  • 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序。
  • 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需求。

逻辑(虚拟)地址和物理地址的概念

我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址就是逻辑地址,逻辑地址由操作系统决定。物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。

CPU 寻址了解吗?为什么需要虚拟地址空间?

现代处理器使用的是一种称为虚拟寻址Virtual Addressing)的寻址方式。使用虚拟寻址,CPU需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。实际上完成虚拟地址转换为物理地址的是CPU中含有一个被称为内存管理单元Memory Management Unit, MMU)的硬件。如下图所示:
在这里插入图片描述
为什么要有虚拟地址空间呢?

没有虚拟地址空间的时候,程序直接访问和操作的都是物理内存,这样有什么问题呢?

  • 用户程序可以访问任意内存,寻址内存的每个字节,这样就很容易(有意或无意)破坏操作系统,造成操作系统崩溃。
  • 想要同时运行多个程序特别困难,比如你想同时运行一个微信和一个 QQ 音乐都不行。为什么呢?举个简单的例子:微信在运行的时候给内存地址 1xxx 赋值后,QQ音乐也同样给内存地址 1xxx 赋值,那么QQ音乐对内存的赋值就会覆盖微信之前所赋的值,这就造成了微信这个程序就会崩溃。

总结来说:如果直接把物理地址暴露出来的话会带来严重问题,比如可能对操作系统造成伤害以及给同时运行多个程序造成困难。

通过虚拟地址访问内存有以下优势:

  • 程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的内存缓冲区。
  • 程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。’当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为4KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。
  • 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。

4. 虚拟内存

什么是虚拟内存(Virtual Memory)?

这个在我们平时使用电脑特别是 Windows 系统的时候太常见了。很多时候我们使用点开了很多占内存的软件,这些软件占用的内存可能已经远远超出了我们电脑本身具有的物理内存。为什么可以这样呢?正是因为虚拟内存的存在,通过虚拟内存可以让程序拥有超过系统物理内存大小的可用内存空间。另外,虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存、拥有一片连续完整的内存空间的错觉。这样会更加有效地管理内存并减少出错。

虚拟内存是计算机系统内存管理的一种技术,我们可以手动设置自己电脑的虚拟内存。虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,并且把内存扩展到硬盘空间

维基百科中有几句话是这样介绍虚拟内存的:

  • 虚拟内存使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如 RAM)的使用也更有效率。目前,大多数操作系统都使用了虚拟内存,如 Windows 家族的“虚拟内存”、Linux 的“交换空间”等。

局部性原理

要想更好地理解虚拟内存技术,必须要知道计算机中著名的局部性原理。局部性原理既适用于程序结构,也适用于数据结构,是非常重要的一个概念。

局部性原理是虚拟内存技术的基础,正是因为程序运行具有局部性原理,才可以只装入部分程序到内存就开始运行。早在1968年的时候,就有人指出我们的程序在执行的时候往往呈现局部性规律,也就是说在某个较短的时间段内,程序执行局限于某一小部分,程序访问的存储空间也局限于某个区域

局部性原理表现在以下两个方面:

  • 时间局部性:如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。
  • 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇存储的。

时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是建立了“内存一外存”的两级存储器的结构,利用局部性原理实现高速缓存。

虚拟存储器

基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大的。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大得多的存储器――虚拟存储器

实际上,我觉得虚拟内存同样是一种时间换空间的策略,用 CPU 的计算时间、页的调入调出花费的时间,换来了一个虚拟的更大的空间来支持程序的运行。

虚拟内存的技术实现

虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。虚拟内存的实现有以下三种方式:

  • 请求分页存储管理︰建立在分页存储管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。
  • 请求分段存储管理:建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段存储管理方式就和请求分页存储管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。
  • 请求段页式存储管理

请求分页存储管理与分页存储管理有何不同呢?

请求分页存储管理建立在分页存储管理之上,它们的根本区别是是否将作业所需的全部地址空间同时都装入主存,这也是请求分页存储管理可以提供虚拟内存的原因。请求分页存储管理不要求将作业全部地址空间同时装入主存。基于这一点,请求分页存储管理可以提供虚拟内存,而分页存储管理却不能提供虚拟内存。

不管是上面哪种实现方式,我们一般都需要:

  • 一定容量的内存和外存:在载入程序的时候,只需要将程序的一部分装入内存,而将其他部分留在外存,然后程序就可以执行了;
  • 缺页中断:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序;
  • 虚拟地址空间:逻辑地址到物理地址的变换。

页面置换算法的作用是什么?常见的页面置换算法有哪些?

虚拟内存管理很重要的一个概念就是页面置换算法。地址映射过程中,如果发现所要访问的页面不在内存中,则发生缺页中断。(缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问。在这个时候,被内存映射的文件实际上成了一个分页交换文件。)

当发生缺页中断时,如果当前内存中并没有空闲的页面,操作系统就必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。用来选择淘汰哪一页的规则叫做页面置换算法

  • OPT页面置换算法(最佳页面置换算法):理想情况,不可能实现,一般作为衡量其他置换算法的方法。
  • FIFO页面置换算法(先进先出页面置换算法):总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。
  • LRU页面置换算法(最近未使用页面置换算法):LRU(Least Currently Used)算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 T,当需要淘汰一个页面时,选择现有页面中其T值最大的,即最近最久未使用的页面予以淘汰。
  • LFU页面置换算法(最少使用页面排序算法):LFU (Least Frequently Used)算法会让系统维护一个按最近一次访问时间排序的页面链表,链表首节点是最近刚刚使用过的页面,链表尾节点是最久未使用的页面。访问内存时,找到相应页面,并把它移到链表之首。缺页时,置换链表尾节点的页面。也就是说内存内使用越频繁的页面,被保留的时间也相对越长。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>