计算机网络--面试知识总结一

HTTP

HTTP中的缓存技术

什么·是强制强制缓存

是只依赖于客服端的,

当我们第一次访问服务器资源的时候,HTTP响应里面除了访问的相关数据还会返回对应的相应头字段Cach-Control:相对过期时间或者Expires:绝对过期时间

然后第二次访问该资源的时候会先去本地缓存中看看是否有该资源的缓存如果有,且没过期那么直接从本地获取数据这就是强制缓存

什么是协商缓存
 

协商缓存是在没命中强制缓存的时候使用的,有两种方式,一种是对某一资源进行打标签Etag操作,每一个资源最新状况有一个唯一标签,第二种是访问时通过携带该资源的最后一次修改时间然后服务端进行对比来判断该资源是否过期,Etag标签的优先级高于lastmodifed的优先级这是因为打标签的方式解决了几个问题

  • 在没有修改文件的最后修改时间也可能改变
  • 有些服务器不能准确的获取文件的最后修改时间

注意强制缓存的优先级是高于协商缓存的

注意,协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求

对于Etag标签方式大概如下:

  • 浏览器第一次访问资源的时候,服务端在返回资源的同时还会在Reponse响应头部加上Etag标签,这个唯一标签就是根据当前请求资源生成的
  • 当下一次再次访问该资源的时候,首先会先检查是否命中本地强制缓存(本地缓存没过期),
    • 如果命中强制缓存直接返回
    • 如果没命中(过期了),那么会在Http的Request头部加上一个If-None-Match请求头,对应的值就是Etag标签值
  • 服务端在收到请求的时候,会取出if-none-match请求头中的值然后和请求请求的资源生成的唯一标签etag进行对比
    • 如果对比前后etag值相等,那么说明该资源没修改,直接返回304 Not Modified 客服端直接从本地缓存中拿数据
    • 如果对比etag不想等,那么说明访问资源被修改过了,返回200,并且携带访问资源数据以及在Response请求头中加上一个对应新的etag标签
  • 客服端浏览器在收到请求后,如果是304 那么直接在本地拿资源,如果是200,那么除了接收数据外,会将其缓存起来

使用lastModified的方式也是一样的,只是将etag的比较换成最后一次修改的时间

如果同时使用两种协商换成,流程如下

Get和Post的区别

  • get请求因为只是对资源的访问因此不会对服务端数据做出修改操作所以是安全、幂等可做缓存的
  • post请求则相反服务端接收到post请求之后会对其进行处理,也报错对数据的修改操作,所以说他是不安全,不幂等的,所以也不做缓存
  • get由于RFC的规范,会对请求的url长度进行限制,而post的数据一般是放在body里面的,RFC对其没有大小限制,我实习的公司里面的所有请求都是使用post请求

HTTP的特性

通用的优点:

  • 1、简单易用:HTTP包括请求头header+请求内容body组成,其请求头中的使用也是key-value形式,使用简单
  • 2、易于扩展:因为Http属于IOS模型中的最上层,所以基于最上层很方便进行扩展,比如HTTPS等
  • 3、具有跨平台性质,手机端,浏览器等等都可以直接使用HTTP来发送请求

HTTP1.1的特点及其性能

由于HTTP1.1是无状态的明文传输,因此带来了几个问题

  • 1、因为无状态,那么服务器就不会去话费额外的资源去记录状态,但是带来的问题,由于是无状态的所以在进行请求之间的关联关系的时候不好进行依赖链接,通常解决方法就是使用Cookie来请求头中保存状态,比如我们的登陆就可以是这样做
  • 2、因为是明文传输,所以会带来数据安全问题

性能:

  • 1、http1.1支持长连接,即每次发送HTTP请求就不再需要三次握手四次挥手了,而是三次握手建立好连接之后,就可以连续处理请求,当不再需要使用的时候在进行四次挥手关闭连接
  • 2、支持管道操作,即由于长连接是,要上一个请求处理完之后才能发下一个请求,发送端可能造成队头阻塞,管道操作就是,客服端可以发起多个请求,而不是需要等待第一个请求收到回复,但是需要注意,虽然可以发起多个请求但是,服务端返回必须按照请求的顺序进行返回,所以在服务端会造成队头阻塞
  • 3、通过上面的描述:会有对头阻塞问题

Http的演化历史

Http1.0->http1.1

1.0的问题:每一个请求都需要三次握手四次挥手,响应较慢

httP1.0->1.1:增加了长连接以及管道传输的功能,减少了传输时间和建立连接时间从而减少了响应时间

1.1的问题:

  • 1、请求和响应只压缩body而对对应的请求头和响应头没有对其压缩以及相同的请求头/响应头会重复发送造成资源的浪费
  • 2、有对头阻塞问题
  • 3、不能设置优先级
  • 4、只能从客服端开始,服务端被动接受

HTTP/1.1-->HTTP/1.2

整体回答

对于Http2.0我认为是对于1.1的一个改进,分贝如下

  • 1、支持头部压缩,以及避免了重复头部的传输
  • 2、改为二进制传输
  • 3、引入Stream支持并发传输,解决了应用层的对头阻塞
  • 4、支持服务端的主动推送

通过上面这些改进来提好Http的性能以及减少资源的浪费

重复编码以及压缩算法是怎么做的

对于上面的解析大致如下

首先对于头部压缩以及避免重复的头部传输是通过HPAK算法来解决的,HPACK算法主要有三个方面第

  • 第一是:静态字典
  • 第二是:动态字典
  • 第三十Huffman编码(压缩算法)

首先我理解的就是通过静态、动态字典(相当于map缓存)来避免重复请求/响应头的传输,通过哈夫曼编码来进行数据压缩下面是静态字典的大致,静态编码总共最多有61组,如果超过了61组那么就需要使用动态字典了,由于是要进行减少重复字段的传输,所以需要客服端、服务端同时缓存下这两张表,然后进行每次有重复的头部信息的话就直接传输对应的索引就好了

而对于哈夫曼的话其实就是使用哈夫曼对于key的value进行编码,其实就是对应的压缩算法,和数据结构里面学的差不多就是按照对应字符出现频率来建立哈夫曼树,然后每个字符就对应一个唯一的哈夫曼编码这就是对应的压缩算法

所以HPACK算法就是静态表+动态表+哈夫曼编码

客户端和服务器两端都会建立和维护「字典」,用长度较小的索引号表示重复的字符串,再用 Huffman 编码压缩数据,可达到 50%~90% 的高压缩率

二进制帧

对于HTTP2.0来说的话对于数据的传输就全部改为了二进制传输,这样的好处就是通过二进制一定程度上可以减少数据的传输,主要对于计算机来说识别二进制是更加容易的,因此可以提高HTTP的性能

下面就是二进制帧的格式,需要重点注意的就是对于一个请求/响应消息,都被分为了两个帧一个是header帧一个是body帧,第二个需要注意的就是每一个完整的请求的帧的流表示一般是同一个,重点解析看下面的并发传输就知道其作用了

并发传输

我自己认为其实2.0最厉害的地方就是能让多个请求响应进行并发传输,他是通过Stream流的概念来完成的,既然能并发完成,那么我们就主要看看他是怎么去正确将同一个消息分割后,怎么正确的组合成一个正确的完整的消息的:主要如下:

首先明确一个概念:多个Stream流可以跑在同一个tcp连接上,然后一个Stream中可能包含多个Massage,一个massge中含有多个二进制帧,一个massage可以理解为一个请求,

明确这个概念后来看看他是怎么正确组装消息的,通常来说一个消息会被分割成多个帧,每个帧中都记录中对应的流标识,注意!!!!!,一般同一个消息分割成帧之后,都是按照顺序进行发送的,这样我们接收方就可以先根据流id进行分组,分组后按照帧发送的顺序进行组装,最后就能拼接成一个正确完整的消息了。

上面就是大多数情况的一个并发传输过程,当然,因为一个Stream中含有多个massge含有多个帧,因此也有可能一个stream流上有多个请求,那么按照上面的方式就不行了,因为上面的方式是一个Stream中传输一个请求响应,所以只需要流id以及发送顺序就能保证得到一个完整小溪,而对于多个请求这种,在传输分割的时候可以在帧的头部再记录对应该帧是属于哪个请求的,最后就能正确地道消息

服务端推送消息

对于HTTp2.0来说可以服务端主动推送消息,需要注意的是,一般客服端请求使用的流id是奇数,然后服务端推送消息是使用偶数的流id,使用这个来区分,

小结:

面试中我应该会采用这样的回答:

HTTP2.0其实是对于1.1的一个改进分别从如下方面进行了一个该井

  • 1、支持头部压缩以及减少重复头部字段的传输,这是通过HPAK算法来完成的,其中HPACK算法主要就是(静态表、动态表、哈夫曼编码),相当于减少重复发送时通过静态、动态表,可以理解为客服端服务端共同设置一个缓存,通过哈夫曼编码进行压缩
  • 2、通过二进制帧和多个Stream流复用同一个tcp连接来节约了 TCP 和 TLS 握手时间,以及减少了 TCP 慢启动阶段对流量的影响。同时也支持设置Steam的优先级
  • 3、服务器支持主动推送资源,大大提升了消息的传输性能
  • 需要注意的是虽然2.0通过并发Stream来进行传送,解决了应用层的队头阻塞问题,但是HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题。

HTTP/1.2-->HTTP/1.3

对于Http/3来说主要优点如下:
  • 1、真正意义上的解决了对头阻塞问题
  • 2、能更快的建立连接
  • 3、无感的迁移网络

真正意义上的解决了对头阻塞问题

首先对于真正意义上的对头阻塞,我们先来看看1.1,1.2是怎么造成队头阻塞的,

对于1.1来说队头阻塞其实就是因为,服务端需要按照客服端发送的请求顺序进行回答,所以只要当前面的请求阻塞住了,那么后面的所有请求也会阻塞回答,对于1.2来说虽然通过多个Stream并发传输解决了HTTP层面的队头阻塞,但是由于1.2是多个Steam跑在同一个TCP连接上的,而一个tcp连接是基于字节流的只用一个滑动窗口,当包没有按序到达的时候窗口就会阻塞住,这就是1.2的tcp层面的队头阻塞

看看1.3是怎么进行解决的,1.3通过QUIC+UDP来进行可靠传输,QUIC中也是有使用多个Stream复用一个UDP连接但是他给每个Stream单独分配了对应的滑动窗口,每个窗口互不影响,当某个Stream中发生了阻塞那么也只是影响这个Stream,这样通过QUIC处理过后,就直接使用UDP来进行传输(UDP快)

对于更快的建立连接
  • 首先如果是采用普通的Https来进行连接的话,会经过tcp的3次握手,tls的四次握手才能建立一个连接,
  • 而对于Http/3来说在传输数据前虽然需要 QUIC 协议握手,但是这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商,如下图:
无感的切换连接

对于1.1/1.2来说都是采用tcp进行传输的,而tcp中的一个连接有四元祖(源ip,源端口,目的ip,目的端口)来确认,当进行网络的切换,比如从wifi切换为手机网络,这个过程的ip地址是发生改变的对于tcp来说就是新的连接,所以需要重新进行连接(3次握手+tls四次握手)会发生卡顿现象,而对于http/3.0来说由于连接是有一个唯一的连接id来标识的,因此在切换网络的时候连接id其实没有变那么就可以继续使用,就不会发生卡顿现象

既然http/1.3这么好那么为什么现在使用的还比较少

由于QUIC是新协议,很多网络涉别根本不知道QUIC是什么,这样就会出问题,由于他们不认识QUIC,而3.0又是通过UDP来发送数据的,因此他们就会将3.0的请求按照UDP来进行处理,然后UDP不会考虑传输数据的可靠性,如果丢包了也不会进行重传等操作,所以目前使用较少,简而言之就是目前的网络设备对QUIC得兼容性比较差

参看博客

这里主要是对小林coding上的知识进行总结和结合自己理解进行总结的,大家如果需要详细了解相关知识可以到对应链接进行学习:3.1 HTTP 常见面试题 | 小林coding

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值