通俗图解HTTP面试题
👨🏫面试官:要不来聊聊 HTTP 吧?
👨💻候选者:可以,我的理解是HTTP它是种客户端和服务器通信的格式,那你可能要问呢 那格式是啥?说白了就是双方约定好的一种协议,就好像你租房一样是吧,让我们双方能看的懂而已;这个交互实际上就是请求和饷应。其中包括最重要的是传包括文本在内的各式各样“消息”,另外呢,它也是种无状态的协议。
详细过程看下图
👨🏫面试官:那你说的无状态你是咋理解的?
👨💻候选者:它的意思是服务器它不维护任何有关客户端发过来的请求消息。哈哈这其实是一种懒,对浏览器来说省事多了,并且状态协议会复杂一点,需要你维护状态(历史信息),并且如果客户或服务器失效,会产生状态的不一致,如果要解决这种不一致的代价会更高。
👨🏫 面试官:差不多,问你 HTTP 协议有哪些优点?
👨💻 候选者:扩展性强啊、速度快、跨平台支持性好。
👨🏫 面试官:HTTP 属于哪一层的协议啊?
👨💻候选者:它是应用层协议,用 TCP(传输层)作为底层协议,默认端口为 80
👨🏫 面试官:这些太简单,HTTP 通信过程能简单介绍一下不?
👨💻 候选者:明显八股文哈哈:
1 服务器在 80 端口等待客户的请求
2 浏览器发起到服务器的 TCP 连接,同时在本地创建套接字 Socket
3 服务器接收来自浏览器的 TCP 连接
4 浏览器(HTTP 客户端)与 Web 服务器(HTTP 服务器)交换 HTTP 消息
5 关闭 TCP 连接
👨🏫面试官:还行,那你知道HTTP版本的区别吗?
👨💻候选者:各个之间的区别还是蛮大的,HTTP1.0 默认是短连接,每次和服务器交互,都需要断开又连;那么 HTTP1.1 版本最主要的是[默认持久连接]。只要你客户端服务器没有断开TCP连接,它就一直保持连接,你也可以发多次HTTP请求,非常的nice啊 1.1还有个就是[断点续传],啥意思呢?它是用HTTP消息头用分块的形式传编码,把实体分成块进行传。
👨💻候选者:1.1说完了,咱们摆下HTTP2.0,坑定高级许多,它不再用文本的方式传了,而是采用二进制来传,对头部进行了压缩,能进行流量控制,最主要就是HTTP/2它是支持多路复用,意思是通过单一的TCP连接并行发起多个的请求和响应消息。
👨🏫面试官:嗯,稍微打断你下。我知道HTTP1.1版本来有个管线化理论,但默认是关闭的。管线化这个跟HTTP2的多路复用是很类似的,它们有什么区别呀?
👨💻候选者:HTTP1.1提出的 管线化 只能串行(一个响应必须完全返回后,下个请求才会开始传输);而我说的HTTP2的多路复用是它利用分帧数据流,把HTTP协议分解为互不依赖的帧(给每个帧排好序然后发出去,接回来的时候按序重组),进而可以搞成乱序,注意发送的时候要避免一定的队列阻塞问题哈,也就是不要把先进先出这个顺序搞混了。
👨💻候选者:无论是HTTP1.1还是HTTP2,response饷应的处理顺序总是要跟request请求顺序保持一致的。假如某个请求的reponse饷应慢了,还是同样会有阻塞的问题,这什么原因呢,根本原因是HTTP底层的传输协议是TCP,没办法完全解决线头阻塞的问题哦
总的来说,做了如下总结
HTTP/1.1
-
引入了持久连接,即 TCP 连接默认不关闭,可以被多个请求复用。
-
分块传输编码,即服务端每产生一块数据,就发送一块,用” 流模式” 取代” 缓存模式”。
-
管道机制,即在同一个 TCP 连接里面,客户端可以同时发送多个请求。
HTTP/2.0
- 二进制协议,1.1 版本的头信息是文本(ASCII 编码),数据体可以是文本或者二进制;2.0 中,头信息和数据体都是二进制。
- 完全多路复用,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应。
- 报头压缩,HTTP 协议不带有状态,每次请求都必须附上所有信息。Http/2.0 引入了头信息压缩机制,使用 gzip 或 compress 压缩后再发送。
- 这个我没有说,是服务端推送,允许服务器未经请求,主动向客户端发送资源。
👨🏫面试官:嗯,好的。那你讲下 HTTP3 跟前面版本什么区别
👨💻候选者:最本质的是 HTTP1和2 的底层都是 TCP,而 HTTP3 它的底层是 UDP。使用HTTP3能够减少RTT(往返时延),还有他使用 QUIC 来保证 UDP可靠性。之前的HTTP/2是存在的一些问题,比如重传,请求饷应慢了,上面也说了都是由于 TCP 本身的特性导致的,所以HTTP/3在QUIC的基础上进行发展而来,QUIC(Quick UDP Connections)译为快速UDP网络连接,底层使用UDP进行数据传输,你说强不强?
HTTP/3主要有这些特点:
- 使用UDP作为传输层进行通信
- 在UDP的基础上QUIC协议保证了HTTP/3的安全性,在传输的过程中就完成了TLS加密握手
- HTTPS 要建⽴⼀个连接,要花费 6 次交互,先是建⽴三次握⼿,然后是 TLS/1.3 的三次握⼿。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数。
- QUIC 有⾃⼰的⼀套机制可以保证传输的可靠性的。当某个流发⽣丢包时,只会阻塞这个流,其他流不会受到影响。
我们拿一张图看一下HTTP协议的变迁:
👨🏫面试官:那好 HTTP 如何实现长连接?它在什么时候会超时?
HTTP 分为长连接和短连接,本质上说是 TCP 的长短连接。TCP 连接是一个双向的通道,要握手的嘛,它是可以保持一段时间不关闭的,因此 TCP 连接才具有真正的长连接和短连接这一说法。
TCP 长连接可以复用一个 TCP 连接,来发起多次的 HTTP 请求,这样就可以减少资源消耗,比如一次请求 HTML,如果是短连接的话,可能还需要请求后续的 JS/CSS。
怎么设置长连接,通过在头部(请求和响应头)设置 Connection 字段指定为 keep-alive,HTTP/1.0 协议支持,但是是默认关闭的,从 HTTP/1.1 以后,连接默认都是长连接。
那什么时候会超时呢?
-
HTTP 一般会有 httpd 守护进程,里面可以设置 keep-alive timeout,当 tcp 连接闲置超过这个时间就会关闭,也可以在 HTTP 的 header 里面设置超时时间
-
TCP 的 keep-alive 包含三个参数,支持在系统内核的 net.ipv4 里面设置;当 TCP 连接之后,闲置了 tcp_keepalive_time,则会发生侦测包,如果没有收到对方的 ACK,那么会每隔 tcp_keepalive_intvl 再发一次,直到发送了 tcp_keepalive_probes,就会丢弃该连接。
1. tcp_keepalive_intvl = 15
2. tcp_keepalive_probes = 5
3. tcp_keepalive_time = 1800
👨🏫面试官:那你了解HTTPS的过程吗?
👨💻候选者:这个我知道,HTTPS在我的理解下,就是安全的HTTP协议,意思是能够做到端到端中链路进行加密;如果要加密,首先要解决的是认证的问题,说下客户端是需要准确的知道服务端是不是真实的,所以在HTTPS中有一个角色叫CA(工信机构),它具有极高的信任度,所以由它来给各公钥签名,信任的一方签的证书,那必然证书是能够被信任的。
为啥子要搞这么复杂,目的要避免中间人在获取证书对其中的内容篡改。
下面就是证书完整的签发和验证过程:
👨💻候选者:我这给你描述下上面详细步骤
- 1 服务端在使用HTTPS前,需要去认证的CA机构申请一份数字证书。数字证书里面包含了证书持有者,证书有效期,服务器公钥等信息,对这些信息进行 Hash 计算,得到一个 Hash 值;
- 然后 CA 会把自己的私钥把该 Hash 值加密,生成 Certificate Signature, 也就是 CA 对证书做了签名;
- 最后把 Certificate Signature 添加到文件证书上,这样就形成了数字证书了;
客户端校验服务端的数字证书的过程,如上图右半部分:
- 首先客户端会用上面同样的 Hash 算法获取该证书的 Hash 值 H1;
- 通常浏览器和操作系统中集成了 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2;
- 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则认为证书不可信。
所以你现在明白了为啥 CA 的证书能解?因为前面已经说过了,CA它个是工信机构,会在浏览器或操作系统中去判断,所以客户端会判这个证书是不是可信啊,是不是已经篡改过?说到这里,私钥加密,公钥解密这两个高大上的名字叫数字签名,这个很形象啊,你想下马化腾签800亿美元的合同,他不得看的清清楚楚啊,这种方式可以看有没有被改了,我说的就是这个意思。
👨💻候选者:等我喘口气先,到现在其实已经解决认证的问题啦,下面我们解决如何保密的问题唠,我们目的肯定不会在传过程中漏给第三方,客户端从 CA 拿到数字证书后,就能拿到服务端的公钥,拿到之后客户端生成一个 key 作为对称加密的秘钥,客户端用服务端的公钥加密传给服务端;服务端收到了用户自己的私钥解密客户端的数据,得到对称加密的秘钥,后面客户端和服务器就可以使用对称加密的秘钥愉快地发送和接收信息了
这道题有几个要点:公私钥、数字证书、加密、对称加密、非对称加密。
再回到问题上来答
- 客户端发起 HTTPS 请求,连接到服务端的 443 端口。
- 服务端有一套数字证书(证书内容有公钥、证书颁发机构、失效日期等)。
- 服务端将自己的数字证书发送给客户端(公钥在证书里面,私钥由服务器持有)。
- 客户端收到数字证书之后,会验证证书的合法性。如果证书验证通过,就会生成一个随机的对称密钥,用证书的公钥加密。
- 客户端将公钥加密后的密钥发送到服务器。
- 服务器接收到客户端发来的密文密钥之后,用自己之前保留的私钥对其进行非对称解密,解密之后就得到客户端的密钥,然后用客户端密钥对返回数据进行对称加密,酱紫传输的数据都是密文啦。
- 服务器将加密后的密文返回到客户端。
- 客户端收到后,用自己的密钥对其进行对称解密,得到服务器返回的数据。
这里我画了一张更详尽的图:
👨🏫面试官:现在 HTTP 还有哪些缺点?
因为HTTP 是明⽂传输,存在安全上的风险:
窃听⻛险,⽐如通信链路上可以获取通信内容,用户账号被盗。
篡改⻛险,⽐如强制植⼊垃圾⼴告,视觉污染。
冒充⻛险,⽐如冒充淘宝⽹站,用户金钱损失。
所以我们引入了HTTPS,HTTPS 在 HTTP 与 TCP 层之间加⼊了 SSL/TLS 协议,可以很好的解决了这些风险:
-
信息加密:交互信息⽆法被窃取。
-
校验机制:⽆法篡改通信内容,篡改了就不能正常显示。
-
身份证书:能证明淘宝是真淘宝。
所以SSL/TLS 协议是能保证通信是安全的。
👨🏫面试官:嗯,既然你撩到了SSL,那你给我说下 TLS 握手的过程是咋样的?
👨💻候选者:啊这,我尽量;我们知道在进行 HTTP 通信前,要先进行 TLS 握手,TLS 的握手过程,如下:
你可看到其中每个框都是一个记录,记录的是啥?记的是收发数据的基本单位,类似于 TCP 里的 segment。多个记录可以组合成一个 TCP 包发送,所以通常经过「四个消息」就可以完成 TLS 握手,也就是需要 2个 RTT 的时延,然后就可以在安全的通信环境里发送 HTTP 报文,实现 HTTPS 协议。
所以可以发现,HTTPS 是应用层协议,需要先完成 TCP 连接建立,然后走 TLS 握手过程后,才能建立通信安全的连接。
事实上,不同的密钥交换算法,TLS 的握手过程可能会有一些区别,如果想去研究交换算法,自己去看黑皮书。
👨🏫面试官:嗯了解,那你讲下RPC和HTTP调用有啥区别呢?
👨💻候选者:首先搞明白HTTP在哪,他在应用层,而TCP它是传输层协议,知道分层目的是让你理解为什么RPC服务跟HTTP服务跟Nice一些的,为啥?我们说啊以前的这种HTTP服务成RESTful风格的接口,这种有啥好处呢,肯定直接,简单,方便肯定是方便,那你的写很多的接口文档啊,叫你严格地表名输入输出是什么?叫你说清楚接口的请求方法,以及请求参数需要注意的事项,哎,烦死了这些, 技术前期就是这样的。回到这个接口上来,它返回的是一个JSON字符串或者XML文档,然后这个客户端再去处理这个返回的消息,这样可以快速进行开发。
👨💻候选者:这种对付小公司还行,公司稍微大点,子系统忒多,接口也肯定很多,这种情况下RPC这种远程调用跟合适了,首先它是长链接,每次没必要通信都要像http一样去3次握手什么,这样减少了网络开销;其次不管大大小小的RPC一般都有注册中心,有全面的监控地址管理;然后发布,下线接口,动态扩展等,对调用方来说好像什么事没发生过一样,具体RPC的好处,我可以给大家举个例子,现在有一个处理订单的系统服务,你先去声明它所有的接口(治理具体指Java的interface),然后把这个项目打成一个Jar包,服务端这边要引用这个二次库(两次打包的意思),然后实现相应的功能,客户端它直接引用这个二方库即可调用了。你想下为什么要这么做?为了减少客户端这边的Jar包大小,因为每一次打包发布的时候,Jar太多肯定加载慢。这里也是为了提高可移植性,端到端可以解耦了。最后呢具体选啥,要和你整个项目完整评估后,仔细比对开发框架对整个项目的影响你才来决定。
👨🏫面试官:看来你有点经验,想问你去认证CA机构的证书是不是假的哦?
👨💻候选者:I know 你的意思意思说是不是合法的吗?第一点很简单,既然你证书是公开的对吧,如果现要发起中间人攻击,我去官网下载一份证书,作为我服务器的证书,客户端肯定会认同这个证书是合法的,是吧,但是这对吗。如何避免冒用的情况?其实就是非对称加密公私钥的好处了,虽然你中间人可以得到证书,但私钥你是拿不到的, 一份公钥是不可能把自己的私钥算出来的哈,两个遇到一起才行。
上面反向来思考,现在我们正向来想服务端的证书具体咋来的啊,详细全部步骤看下面
👨💻候选者:第二点,既然机构是要有认证的,不是随随便便一个机构都有资格颁发证书,不然也不叫权威机构。另外,证书的可信性基于信任制进行背书,不是一棍子打死。不同等级的权威机构对审核的要求也不一样,于是证书就有免费的,便宜和贵的。
👨🏫面试官:你刚才说机构我倒是不担心,浏览器该如何验证证书的合法性?
👨💻候选者:当浏览器发起HTTPS请求时,服务器会返回网站的SSL证书,浏览器需要对证书做一下验证:
1 验证域名、有效期等信息是否正确。证书上都有包含这些信息,比较容易完成验证;
2 判断证书来源是否合法。每份签发证书都可以根据验证链查找到对应的根证书,操作系统、浏览器会在本地存储权威机构的根证书,利用本地根证书可以对对应机构签发证书完成来源验证;
4 判断证书是否被篡改。需要与 CA 服务器进行校验;
5判断证书是否已吊销。通过CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现,其中 OCSP 可用于第3步中以减少与 CA 服务器的交互,提高验证效率
以上任意一步都满足的情况下浏览器才认为证书是合法的。
👨🏫面试官:嗯嗯不错,对称加密算法中重要的随机数被窃取这个该怎么办?
👨💻候选者:其实 HTTPS 并不会包含对随机数的安全保证,它只保证传的过程中是安全就行,生成的随机数是放在本地的,要想不被窃取,可以安杀毒软件,反木马,浏览器升级修复漏洞这些。
👨🏫面试官:我想问下用了 HTTPS 我可以抓包吗?
👨💻候选者:HTTPS 的数据是加密的,常规下抓包工具代理请求后抓到的包内容是加密状态,你是看不到的哈。
👨💻候选者:但是呢浏览器会提示安全风险,如果用户授权是可以继续访问网站,完成请求。因此,只要客户端是我们自己的终端,我们授权的情况下,自己可以组建中间人网络,而抓包工具是作为中间人的代理。通常 HTTPS 抓包工具的使用方法是会生成一个证书,用户需要手动把证书安装到客户端中,然后终端发起的所有请求通过该证书完成与抓包工具的交互,然后抓包工具再转发请求到服务器,最后把服务器返回的结果在控制台输出后再返回给终端,从而完成整个请求的闭环,简直
👨💻候选者:现在既然你 HTTPS 不能防抓包了,那你 HTTPS 有什么意义?HTTPS 可以防止用户在不知情的情况下通信链路被监听,而对于主动授信的抓包操作是不提供防护的,因为这时用户是是知道有风险的。如果要防止被抓包,需采用应用级的安全防护,例如采用私有的对称加密,同时做好移动端的防反编译加固,防止本地算法被破解啊。
👨🏫面试官:答的还行,你上面提到对称加密,我记得还有一种用在SSL、TLS进行通信端到端的非对称加密方案,但是这种设计比较复杂的数学算法,在实际过程中,计算的代价较高,效率太低,干脆抛弃。所以,SSL/TLS实际对消息的加密使用却是对称加密。
👨🏫面试官:好了,再跟你聊聊 HTTP 常见的状态码吧?
👨💻候选者:先让HTTP状态码分个类:
- 1XX:信息性状态码
- 2XX:成功状态码
- 3XX:重定向状态码
- 4XX:客户端错误状态码
- 5XX:服务端错误状态码
几个常用的,面试之外,也应该记住:
常见HTTP状态码
这里我要说一下 301 和 302 之间区别?
301:永久性移动,请求的资源已被永久移动到新位置。服务器返回此响应时,会返回新的资源地址。
302:临时性性移动,服务器从另外的地址响应资源,但是客户端还应该使用这个地址。
用一个比喻,301就是嫁人的新垣结衣,302就是有男朋友的长泽雅美,老司机们懂的都懂。
👨🏫面试官:嗯?怀疑你在开车 好了问你 HTTP 有哪些请求方式?
其中,POST、DELETE、PUT、GET的含义分别对应我们最熟悉的增、删、改、查,拒绝CRUD哈哈
👨🏫面试官:正经点,说⼀下 GET 和 POST 的区别?
👨💻候选者:从 HTTP 报文层面来看,GET 请求将信息放在 URL,POST 将请求信息放在请求体中。这一点使得 GET 请求携带的数据量有限,因为 URL 本身是有长度限制的,而 POST 请求的数据存放在报文体中,大小是没有限制。而且从形式上看,GET 请求把数据放 URL 上不太安全,而 POST 请求把数据放在请求体里比较安全一点。
从数据库层面来看,GET 符合幂等性和安全性,而 POST 请求不符合。这个其实和 GET/POST 请求的作用有关。按照 HTTP 的约定,GET 请求用于查看信息,不会改变服务器上的信息;而 POST 请求用来改变服务器上的信息。正因为 GET 请求只查看信息,不改变信息,对数据库的一次或多次操作获得的结果是一致的,认为它符合幂等性。安全性是指对数据库操作没有改变数据库中的数据。
👨💻候选者:从其他层面来看,GET 请求能够被缓存,GET 请求能够保存在浏览器的浏览记录里,GET 请求的 URL 能够保存为浏览器书签。这些都是 POST 请求所不具备的。缓存是 GET 请求被广泛应用的根本,他能够被缓存也是因为它的幂等性和安全性,除了返回结果没有其他多余的动作,因此绝大部分的 GET 请求都被 CDN 缓存起来了,大大减少了 Web 服务器的负担。
👨🏫面试官:别念了头晕,再问一个 GET 的长度限制是多少?
👨💻候选者:HTTP中的GET方法是通过URL传递数据的,但是URL本身其实并没有对数据的长度进行限制,真正限制GET长度的是浏览器。
例如IE浏览器对URL的最大限制是2000多个字符,大概2kb左右,像Chrome、Firefox等浏览器支持的URL字符数更多,其中FireFox中URL的最大长度限制是65536个字符,Chrome则是8182个字符。这个长度限制也不是针对数据部分,而是针对整个URL。
👨🏫面试官:刚才你不是说URL吗,这个和URI什么区别
-
URI,统一资源标识符(Uniform Resource Identifier, URI),标识的是Web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都是由一个URI进行标识的。
-
URL,统一资源定位符(Uniform Resource Location),它是URI的一种子集,主要作用是提供资源的路径。
👨💻候选者:它们的主要区别在于,URL除了提供了资源的标识,还提供了资源访问的方式。这么比喻,URI 像是身份证,可以唯一标识一个人,而 URL 更像一个住址,可以通过 URL 找到这个人——人类住址协议://地球/中国/北京市/朝阳区/五道口职业技术学院/14号宿舍楼/525号寝/张三.男。
👨🏫面试官:嗯很形象,那Session 和 Cookie 有什么联系和区别?
👨💻候选者:先来看看什么是 Session 和 Cookie
Cookie 是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个 Cookie,客户端就把 Cookie 保存起来。在客户端下次向同一服务器再发起请求时,Cookie 被携带发送到服务器。服务端可以根据这个Cookie判断用户的身份和状态。
Session 指的就是服务器和客户端一次会话的过程。它是另一种记录客户状态的机制。不同的是cookie保存在客户端浏览器中,而session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找用户的状态。
👨🏫面试官:那它们区别呢?
👨💻候选者:前面我说了存储位置不一样嘛,Cookie 保存在客户端,Session 保存在服务器端。
存储数据类型不一样,Cookie 只能保存ASCII,Session可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般有效时间较短,客户端关闭或者 Session 超时都会失效。
隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
存储大小不同, 单个Cookie保存的数据不能超过4K,Session可存储数据远高于 Cookie。
之间有啥联系,只知道可以使用Cookie记录Session的标识。
步骤
用户第一次请求服务器时
- 服务器根据用户提交的信息,创建对应的 Session,
- 请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,
- 会将此信息存入 Cookie 中,同时 Cookie 记录此 SessionID 是属于哪个域名。
当用户第二次访问服务器时
- 请求会自动判断此域名下是否存在 Cookie 信息,如果存在,则自动将 Cookie 信息也发送给服务端,
- 服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,
- 如果没有找到,说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。
👨🏫面试官:分布式环境下Session怎么处理呢?
👨💻候选者:那个,分布式环境下,客户端请求经过负载均衡,可能会分配到不同的服务器上,比如说一个用户的请求两次没有落到同一台服务器上,那么在新的服务器上就没有记录用户状态的Session。
这时候怎么办
可以使用Redis等分布式缓存来存储Session,在多台服务器之间共享。
客户端无法使用Cookie怎么办?
有可能客户端无法使用Cookie,比如浏览器禁用Cookie,或者客户端是安卓、IOS等等。
这时候怎么办?SessionID怎么存?怎么传给服务端呢?
首先是SessionID的存储,可以使用客户端的本地存储,比如浏览器的sessionStorage。
接下来怎么传呢?
拼接到URL里:直接把SessionID作为URL的请求参数
放到请求头里:把SessionID放到请求的Header里,比较常用。
下期再见
- 点赞
- 收藏
- 关注作者
评论(0)