前端面经-操作系统与网络原理

前端面经-操作系统与网络原理

HTTP1.0

参考链接

早先1.0HTTP版本,是一种无状态、无连接的应用层协议。

HTTP1.0规定浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。

这种无状态性可以借助cookie/session机制来做身份认证和状态记录。而下面两个问题就比较麻烦了。

首先,无连接的特性导致最大的性能缺陷就是无法复用连接。每次发送请求的时候,都需要进行一次TCP的连接,而TCP的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率非常低。

其次就是队头阻塞(head of line blocking)。由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了。

为了解决这些问题,HTTP1.1出现了。

HTTP1.1

对于HTTP1.1,不仅继承了HTTP1.0简单的特点,还克服了诸多HTTP1.0性能上的问题。

  1. 首先是长连接HTTP1.1增加了一个Connection字段,通过设置Keep-Alive可以保持HTTP连接不断开,避免了每次客户端与服务器请求都要重复建立释放建立TCP连接,提高了网络的利用率。如果客户端想关闭HTTP连接,可以在请求头中携带Connection: false来告知服务器关闭请求。

  2. 其次,是HTTP1.1支持请求管道化pipelining)。基于HTTP1.1的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。举个例子来说,假如响应的主体是一个html页面,页面中包含了很多img,这个时候keep-alive就起了很大的作用,能够进行“并行”发送多个请求。(注意这里的“并行”并不是真正意义上的并行传输,具体解释如下。)

需要注意的是,服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。

也就是说,HTTP管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。
在这里插入图片描述

如图所示,客户端同时发了两个请求分别来获取htmlcss,假如说服务器的css资源先准备就绪,服务器也会先发送html再发送css

换句话来说,只有等到html响应的资源完全传输完毕后,css响应的资源才能开始传输。也就是说,不允许同时存在两个并行的响应

可见,HTTP1.1还是无法解决队头阻塞(head of line blocking)的问题。同时“管道化”技术存在各种各样的问题,所以很多浏览器要么根本不支持它,要么就直接默认关闭,并且开启的条件很苛刻…而且实际上好像并没有什么用处。

  1. 缓存处理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag

    If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

  2. 带宽优化及网络连接的使用,HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且

    支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者

    由的选择以便于充分利用带宽和连接。

  3. 错误通知的管理,在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务

    上的某个资源被永久性的删除。

  4. Host头处理,在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技

    的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应

    持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。

HTTP2.0

  • 二进制分帧:在http层和tcp层之间增加二进制分帧层,将数据转换成二进制的格式,并在二进制分帧层进行分割。(流和帧的概念:一个请求一个流,一个流对应多个帧),不同的请求的帧复用一个tcp连接,到对端之后根据帧中的流标识进行组装

  • 多路复用:每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。

    举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。

    另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。

    可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

  • 首部压缩,减少体积,并且在服务端访问过的header进行map存储,第二次访问的时候可以发送key,查找对应的value

  • 服务器推送:服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。

  • 请求优先级:多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY允许给每个request设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的html内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。

http和https的区别

1、HTTPS 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。

2、HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。

3、HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4、HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)

HTTPS的建立过程(SSL建立安全会话的过程)

img

状态码301,302,304,404,5xx

  • 301:网页永久移动到新位置,get或者head请求会自动将请求转移到新位置,post请求需要用户自己请求新的url,如果收藏为标签,会自动更新标签

  • 302:临时移动,不会自动转移到新位置

  • 304:自从上次请求后,网页没有修改过,不会返回网页内容,客户的缓存资源是最新的,要客户端使用缓存,节省带宽

  • 401:未授权的操作

  • 402: 不明

  • 403:服务器拒绝客户端的请求

  • 404:找不到请求的网页

  • 5xx:服务器内部错误,500是服务器内部错误,无法完成请求,503,服务不可用,可能停机或者超载

总结:

  • 2xx:请求成功

  • 3xx:请求成功,重定向了,服务器内容移动

  • 4xx:请求失败,客户端原因,可能是格式不正确

  • 5xx:请求失败,服务器原因

TCP三次握手

TCP 的可靠连接是靠 seq( sequence numbers 序列号)来达成的。所以说,建立可靠连接,需要对客户端和服务器的起始序列号达成共识。

  1. 主机A通过向主机B 发送一个含有同步序列号SYN的标志位的数据段给主机B ,向主机B 请求建立连接,通过这个数据段, 主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我.

  2. 主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事: 我已经收到你的请求了,你可以传输数据了;你要用哪佧序列号作为起始数据段来回应我

  3. 主机A收到这个数据段后,再发送一个**确认应答ACK,**确认已收到主机B 的数据段:"我已收到回复,我现在要开始传输实际数据了 这样3次握手就完成了,主机A和主机B 就可以传输数据了

为什么是三次握手而不是两次?

TCP四次挥手

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。

(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。

(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。

(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。

TCP和UDP的区别

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付,无顺序控制,重传控制,没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等);

3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的;

4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP首部开销20字节;UDP的首部开销小,只有8个字节

6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

TCP拥塞控制

参考链接

TCP流量控制

TCP协议-如何保证传输可靠性

参考链接

  • 校验和
  • 序列号
  • 确认应答
  • 超时重传
  • 连接管理
  • 流量控制
  • 拥塞控制

post和get区别

知乎的解答:https://www.zhihu.com/question/28586791

没有副作用叫做幂等

这里指的是非ajax的浏览器请求

  • 携带数据的格式不一样:浏览器发送get请求限定只能通过url的方式,所以浏览器发送get请求的方式是地址栏和a标签href,所以get的参数只能以key/value的形式放在url中进行传递,get不如post安全/要想安全还需要https,而post请求来自表单提交,表单数据被浏览器编码到body里,支持传递不同形式的数据

  • **数据大小的限制:**由于浏览器的url有长度限制,所以限制了get请求的数据大小有限制

  • **幂等与否:**get请求是幂等的,可以重复请求,没有副作用,post方法有副作用,form标签submit提交请求的时候是不幂等的,不能重复请求,所以不能做缓存,而get可以做缓存,不能把post保存为标签,尝试重新提交表单浏览器会提醒

试想一下,如果POST请求被浏览器缓存了,那么下单请求就可以不向服务器发请求,而直接返回本地缓存的“下单成功界面”,却又没有真的在服务器下单。

接口中的请求比较自由,没有浏览器那么多限制,所以有一些接口规范。但是没看出来浏览器实现表单提交的post和rest中创建资源的post有什么不同

浏览器缓存机制

参考链接

浏览器同源策略及跨域的解决方法

参考链接

XSS及CSRF攻击防御

参考链接

DNS域名解析全过程

参考链接

当一个用户在地址栏输入www.taobao.com时,DNS解析有大致十个过程,如下:

  1. 浏览器先检查自身缓存中有没有被解析过的这个域名对应的ip地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。

  2. 如果浏览器缓存中没有(专业点叫还没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果。而操作系统也有一个域名解析的过程。在windows中可通过c盘里一个叫hosts的文件来设置,如果你在这里指定了一个域名对应的ip地址,那浏览器会首先使用这个ip地址。但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的ip地址上,造成所谓的域名劫持。所以在windows7中将hosts文件设置成了readonly,防止被恶意篡改。

  3. 如果至此还没有命中域名,才会真正的请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。

  4. 如果LDNS仍然没有命中,就直接跳到Root Server 域名服务器请求解析

  5. 根域名服务器返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如.com .cn .org等)地址

  6. 此时LDNS再发送请求给上一步返回的gTLD

  7. 接受请求的gTLD查找并返回这个域名对应的Name Server的地址,这个Name Server就是网站注册的域名服务器

  8. Name Server根据映射关系表找到目标ip,返回给LDNS

  9. LDNS缓存这个域名和对应的ip

  10. LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,域名解析过程至此结束

CDN(内容分发网络)

浏览器缓存只是为了提升页面二次访问的速度,而对于提升首次访问的响应能力,通常是采用CDN进行加速,CDN通过在原服务器和用户之间增加一层新的网络架构,将静态资源缓存到离用户很近的或相同网络运营商的CDN节点上,不仅可以提高用户的访问速度,还能节省服务器的带宽消耗,降低负载。

进程和线程的区别

进程是资源分配的最小单位,线程是CPU调度的最小单位

做个简单的比喻:进程=火车,线程=车厢

线程在进程下行进(单纯的车厢无法运行)

一个进程可以包含多个线程(一辆火车可以有多个车厢)

不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)

同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)

进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)

进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)

进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)

进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-“互斥锁”

进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”

从浏览器多进程到JS单线程

参考链接(解析得非常全!!!)

浏览器都包含哪些进程?

浏览器是多进程的,包含哪些进程:

  1. Browser进程:浏览器的主进程(负责协调、主控),只有一个。作用有
    • 负责浏览器界面显示,与用户交互。如前进,后退等
    • 负责各个页面的管理,创建和销毁其他进程
    • 将Renderer进程得到的内存中的Bitmap,绘制到用户界面上
    • 网络资源的管理,下载等
  2. 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建
  3. GPU进程:最多一个,用于3D绘制等
  4. 浏览器渲染进程(浏览器内核)(Renderer进程,内部是多线程的):默认每个Tab页面一个进程,互不影响。主要作用为
    • 页面渲染,脚本执行,事件处理等

强化记忆:在浏览器中打开一个网页相当于新起了一个进程(进程内有自己的多线程)

当然,浏览器有时会将多个进程合并(譬如打开多个空白标签页后,会发现多个空白标签页被合并成了一个进程)

重点是浏览器内核(渲染进程)

对于普通的前端操作来说,最重要的是渲染进程。页面的渲染,JS的执行,事件的循环,都在这个进程内进行。

请牢记,浏览器的渲染进程是多线程的,它都包含了哪些线程:

  1. GUI渲染线程
    • 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
    • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行
    • 注意,GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  2. JS引擎线程
    • 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
    • JS引擎线程负责解析Javascript脚本,运行代码。
    • JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序
    • 同样注意,GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
  3. 事件触发线程
  4. 定时触发器线程
  5. 异步http请求线程

WebWorker,JS的多线程?

  • 创建Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,完全受主线程控制,而且不能操作DOM)
  • JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)

所以,如果有非常耗时的工作,请单独开一个Worker线程,这样里面不管如何翻天覆地都不会影响JS引擎主线程,只待计算出结果后,将结果通信给主线程即可,而且注意下,JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。

其它,关于Worker的详解就不是本文的范畴了,因此不再赘述。

浏览器输入网址到页面渲染全过程

http://www.dailichun.com/2018/03/12/whenyouenteraurl.html一个面试官写的答案

输入域名->浏览器缓存(cache-control过期时间)->dns解析(递归解析)->tcp连接(三次握手)->http请求->服务器处理请求并返回http报文->浏览器渲染页面(边接收边渲染,遇到js,css文件接着发送http请求,可能涉及跨域a标签,script和css标签,加载css样式文件后,可能会引起回流或者重绘,直到全部渲染完成)->四次挥手关闭http连接

https://www.jianshu.com/p/fc95603b8cf0

浏览器解析页面流程

浏览器器内核拿到内容后,渲染大概可以划分成以下几个步骤:

  1. 解析html建立dom树
  2. 解析css构建render树(将CSS代码解析成树形的数据结构,然后结合DOM合并成render树)
  3. 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  4. 绘制render树(paint),绘制页面像素信息
  5. 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。
    在这里插入图片描述

进程间通信方式

参考链接

(1)管道(pipe)及有名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

(2)信号(signal):信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。

(3)消息队列(message queue):消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。

(4)共享内存(shared memory):可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。

(5)信号量(semaphore):主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。

进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。

(3)消息队列(message queue):消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。

(4)共享内存(shared memory):可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。

(5)信号量(semaphore):主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。

(6)套接字(socket):这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值