八股文——网络篇
网络篇
浏览器输入URL并按下回车之后会发生什么?(超高频)
- 解析URL:输入URL并进行解析。输入URL后,浏览器会解析出来使用的协议、主机、端口号、所请求的资源的文件路径等信息;并构造一个HTTP请求(并且浏览器会根据请求头判断是否有HTTP缓存,并根据是否有缓存决定从服务器获取资源还是使用缓存资源);
- 域名解析:DNS域名解析,将域名解析为对应的IP地址;
- TCP连接建立:建立TCP连接(包括三次握手);
- 发送请求报文:浏览器发送HTTP请求报文到服务器;
- 服务器响应:服务器处理HTTP请求并返回HTTP响应报文;
- 加载页面:浏览器根据接受到的报文渲染页面;
- TCP连接断开:断开TCP连接(四次挥手)
DNS是什么?为什么要有DNS?
DNS是一种用于将域名转换为IP地址的分布式系统。(分别解释域名、IP地址、分布式系统、转换过程)域名符合人们的使用和记忆,但是不符合计算机的存储;IP地址符合计算机的存储但是不符合人们的使用和记忆(引出问题);所以我们在使用和记忆时使用域名,在计算机通信时使用IP地址;
DNS为什么是分布式系统?
(首先解释集中式系统有什么不好)如果DNS是集中式系统,会有以下几个问题:单点故障、远距离集中式数据库、维护成本巨大;
- 单点故障:单个DNS服务器要处理所有的DNS服务,一旦故障,整个网络都会瘫痪;
- 远距离集中式数据库:只有单个DNS服务器,不同计算机到达服务器的距离不同,只有邻近DNS服务器的用户可以快速查询,远距离的用户势必势必有很大的时延;(甚至为了避免远距离,有些网站开启了CDN服务)
- 维护成本巨大:单个DNS服务器会导致低俗和拥堵的链路,造成严重时延。单个DNS服务器维护成本巨大,要频繁更新。(其次说明是如何实现分布式的)
DNS分布式系统的实现:
- 分层结构:从根域名服务器开始,逐级向下划分为顶级域名服务器,授权域名服务器、本地域名服务器,每一个级别的服务器都只负责维护和管理一部分域名数据;
- 递归查询和迭代查询:当客户端向某个DNS服务器查询域名解析时,如果该DNS服务器不负责该域名,则会向其他DNS服务器查询,最终找到负责该域名的DNS服务器来完成域名解析;
- DNS缓存:域名解析未必要在DNS服务器上进行,如果DNS服务器崩溃,本地有DNS缓存,也可以用缓存来回答客户端的查询;(域名解析数据不只存储在一处,可以缓存在很多处,比如本地主机、本地路由器等)
- 域名区域分布:不同的域名服务器只负责自己的域名区域的管理工作;
什么是分布式系统?就是数据分成很多部分,分别存储在不同的主机或服务器;分析域名www.baidu.com,域名解析数据可能保存在本地缓存,可能保存在本地服务器缓存中,也可能同一子网中某个主机也有该域名解析,也可能保存在某些权威域名服务器,同一数据可能保存在不同地方;同样如果是blog.outlierli.ink,则保存在ink域名服务器记录的权威域名服务器中,不同数据可以保存在不同服务器;
不存在baidu域名服务器,当我们在com域名服务器中找时,会返回权威域名服务器而不是所谓的baidu域名服务器(没有二级域名服务器这一说法)!根域名服务器和顶级域名服务器并不负责具体的域名解析,根域名服务器返回域名对应的顶级域名服务器的IP地址,顶级域名服务器返回保存域名解析的权威域名服务器,在权威域名服务器上才会进行最终的域名解析;
(ps:blog.outlierli.ink中,没有独立的outlierli域名服务器,但是可以通过注册商所提供的解析服务以及分布式的域名系统架构来实现域名解析,具体而言就是注册商将域名解析信息分发到根域名服务器、ink顶级域名服务器、某些权威服务器等)
域名的层级关系你知道吗?
DNS中的域名按照"."来分割。比如www.baidu.com中有2个不同的域名:baidu,com;域名越靠近右边层级越高,比如com是顶级域名,baidu是二级域名。注意www并不是域名,而是baidu域名的子域名(子目录),子域名是域名系统中更具体地子分类,不同的子域名可以有自己的主机和资源。(比如www.outlierli.ink和blog.outlierli.ink中www和blog就是两个不同的子域名,我们可以在两个不同子域名的网站上部署不同的资源)
DNS做域名解析的过程是什么,请描述?
- 查浏览器缓存中有没有
域名-IP地址转换关系; - 查本地的
HOST文件中是否有对应缓存; - 查与本机相连的路由器缓存;
- 如果子网内没有
DNS服务器,则采用ARP地址解析协议对默认网关进行查询,获取到默认网关的MAC地址,将DNS查询请求发到默认网关; - 如果子网内有
DNS服务器,采用ARP地址解析协议对DNS服务器查询,获取DNS服务器MAC地址,向本地的DNS服务器(互联网服务商ISP例如中国移动提供)发送查询请求; - 本地
DNS服务器中如果没有,则向根DNS服务器发出查询请求;根DNS服务器并不解析域名,而是告诉本地DNS解析器应该向哪个顶级域的DNS服务器查询;(比如www.baidu.com要向com顶级域名DNS服务器查询) - 本地
DNS解析器向指定的顶级域名服务器查询,顶级域名服务器告诉本地DNS解析器向哪个权威DNS服务器查询;(迭代查询) - 本地
DNS解析器向权威DNS服务器查询;权威DNS服务器会查找baidu.com对应的IP地址,然后返回给本地的DNS解析器; - 本地
DNS解析器将IP地址返回浏览器;并且进行缓存; - 浏览器根据
IP地址,与目标服务器进行连接;
DNS解析过程中的递归查询和迭代查询你清楚吗?
递归查询就是本地DNS解析器只用向上层DNS服务器发送一次查询请求,之后上层DNS服务器会自动查询下一级的服务器,并将最终结果返回本地DNS解析器(本地DNS解析器发起一次查询,收到一次返回,即可实现解析;就像递归一样,一层层自己深入,然后最后只返回结果,深入了多少层我们不关心)
迭代查询就是本地DNS解析器只是询问上层服务器一个更高级域名服务器的地址,然后自己向更高层域名服务器发起查询;(本地DNS解析器发起多次查询)
二者的适用场景不同,递归查询适用于普通用户和客户端(对普通用户来说,看上去就像只查找了一次就成功);迭代查询适用于DNS服务器之间的通信;
HTTP的特性是什么?简述一下。
简单、灵活和易于扩展、无状态、明文传输、不安全;
- 简单:
HTTP基本报文格式为header+body,头部信息(即请求头)也是最简单的key-value的简单文本的形式,易于理解; - 灵活:
HTTP协议里各种信息没有被固定死(比如各种请求方法、头字段等),允许开发人员自定义和扩展; - 易于扩展:
HTTP工作在应用层,下层可以所以变化,在HTTP和TCP之间添加SSL/TSL安全传输层,就是HTTPS;将TCP换成基于UDP的QUIC就是HTTPS; - 无状态:服务器不会记忆
HTTP的状态(解决方案Cookie技术) - 明文传输:传输中的信息可以直接阅读;
- 不安全:适用明文传输,内容可能被窃听;没有验证通信方身份,可能遭遇伪装;无法保证报文的完整性(没有完整性校验),可能被篡改;
窃听、伪装、篡改分别是什么意思?
窃听:未经允许监视网络信息;
伪装:攻击者伪装为合法用户(包括合法客户端和合法服务器)来欺骗用户或服务方;
篡改:指修改传输过程中的数据包;
HTML、CSS、HTML、URL这些分别是什么?
- HTML是页面文本标记语言,定义了网页中文本、图像等元素的展示方式;
- CSS是用于定义网页样式和布局样式的语言;
- HTTP是超文本传输协议;
- URL是统一资源定位符,用于标识互联网上的资源,包括协议类型、域名、路径等信息,用于定位资源位置;
你对于HTTP的版本变化有了解吗?分别阐述HTTP各个版本,包括HTTPS、HTTP3等,重点在于每个版本有什么问题,下一个版本改进了什么。
HTTP/0.9:最早的版本,只支持GET方法,没有请求头,服务器只能返回HTML格式的内容(就是只能获取静态页面)
HTTP/1.0:是HTTP协议的第一个正式版本;
- 相对于上一个版本的改进:引入了请求头和响应头,支持多种请求方法和状态码;
- 存在的问题:不支持持久连接(短连接),每一次请求都要建立新的连接;(同时如果要发送下一个请求,要上一个请求的响应回来才能发送,只有上一个响应回来了,上一次连接才完成)
HTTP/1.1:
- 相对于上个版本解决的问题:长连接和管道网络传输,更多请求头、请求方法、状态码,更好的协商缓存判断;
- 长连接:TCP三次握手之后建立长连接,只有任何一方没有明确提出断开连接,则一直维持连接(并不只是TCP的长连接,而且还是HTTP自己的长连接,HTTP的头部字段中
Keep-Alive有效); - 管道网络传输:客户端可以同时发送多个请求,无需等待之前的请求回来就可以继续发送请求;
- 增加了HOST请求头,使得一个服务器可以创建多个Web站点;
- 增加了新请求方法、错误响应状态码;
- 增加了新的协商缓存的缓存头(比如根据标志位判断资源有没有被修改的缓存头)
- 长连接:TCP三次握手之后建立长连接,只有任何一方没有明确提出断开连接,则一直维持连接(并不只是TCP的长连接,而且还是HTTP自己的长连接,HTTP的头部字段中
- 存在的问题:头部冗余、队头堵塞、没有请求优先级控制只能按照请求顺序处理和返回响应、服务器只能被动响应不能主动推送资源;
- 头部冗余:每一次请求和响应都要带有一定的“重复的”头部信息(明明已经建立好了连接,可是还是每次发送重复的信息,按理来说,一个连接内这些冗余的头部信息只用发一次即可)
- 队头堵塞:客户端改进之后可以一次性发送多条请求,可是服务端还是要一条条顺序处理,如果第一个请求要处理的时间很长,则后面的请求都会被堵塞,表现出来就是客户端发送了很多请求,可是一个响应都没有回来。
- 没有请求优先级控制只能按照请求顺序处理和返回响应:比如页面中有一个视频资源没有加载出来,而此时我们还选择登录页面,登录请求就会被视频资源请求阻塞,明明登录请求更为重要,可是我们却不能及时处理。
- 服务器只能被动响应不能主动推送资源:服务器可能已经知道了客户端想要什么资源,可是由于客户端没有请求,服务器不能主动返回,即使服务器知道了下一次推送的资源,还是要等待客户端的请求;(一般请求HTML的资源后还要请求CSS资源,如果可以主动推送CSS的资源,就可以减少请求资源的次数)
HTTP/2:基于HTTPS的,所以增加了安全性;
- 相对于上个版本解决的问题:编码效率提高、并发传输、服务器主动推送;
- 编码效率提高:首先使用了
HPACK压缩算法对请求和响应头进行压缩,减少了头部数据量;其次将数据分割为二进制帧进行传输,增加了数据传输效率; - 并发传输:引出了
Stream的概念,多个Stream复用在一条TCP连接,并用独一无二的StreamID来区分,不同的Stream帧可以乱序发送(到达服务器后根据StreamID重组即可);最终实现并行交错地收发请求和响应; - 服务器主动推送:对于客户端的一个请求,服务器可以发送多个响应,即服务器可以额外推送资源;
- 编码效率提高:首先使用了
- 存在的问题:队头堵塞、握手延迟、网络迁移要重新连接;
- 队头堵塞:和之前的队头堵塞不同,之前是宏观上的队头堵塞(消息和消息之间的队头堵塞,因为早到的消息堵塞晚到的消息),现在是微观上的队头堵塞(由于TCP是字节流协议,必须保证字节数据的完整和连续,所以后面字节由于前面的字节没有到只能放在内核缓冲区,不能被应用层拿到,只有等待前面的字节也到了组成完整且连续的字节流,才能被应用层拿到);
- 握手延迟:TCP和TLS存在握手延迟;(TCP三次握手,TLS1.2四次握手(TLS1.3改进为3次握手),而且必须先TCP握手然后TLS握手,不能一起进行,最少3RTT的时延)
- 网络迁移要重新连接:如果网络发生变化(比如从
wifi切换到移动数据,IP地址会变化),要重新建立TCP和TLS连接,然后才能继续通信;(这也是因为TCP协议导致的,TCP连接由【源IP地址,源端口,目标IP地址,目标端口】确定,其中的任何一个发生变化,就会导致连接断开,需要重新连接)
HTTP/3:下层的TCP协议改为了UDP协议,同时添加了QUIC协议;
- 由于HTTP/2存在的问题是队头阻塞,而此时的队头阻塞是由于TCP是基于字节流的协议,所以要解决字节队头堵塞,就要抛弃TCP协议,使用UDP协议;可是直接使用UDP协议也不可以,因为UDP协议是无连接的、不可靠的,所以必须在UDP和HTTP之间添加QUIC协议保证可靠性;
- 此外虽然UDP协议是无序的,但是QUIC协议包含TLS层的功能,TLS会保证数据包可以被有序的重组记录,确保数据的有序性;
- UDP协议虽然是无连接的,但是QUIC协议可以在零延时情况下建立连接,并且QUIC的连接也支持多路复用,单个连接上可以同时传输多个数据流;此外QUIC协议还可以实现类似TCP的流量控制、拥塞控制以及重传机制;(QUIC协议补足了UDP的缺陷,同时又让UDP快速、简单、实时传输的特性得以保留)
- 相对于上个版本解决的问题:传输效率更高、无队头堵塞、更快的连接建立、网络迁移不需要重新连接、向前纠错机制;
- 传输效率更高:QUIC协议改进了头部压缩算法(从HPACK到QPACK),静态表的大小变大(从61项到91项);
- 无队头堵塞:UDP协议传输数据,不用维护字节流的完整和连续,一个连接上的多个
Stream之间没有依赖,一个Stream包丢了不会影响其他Stream包,所以不会发生队头阻塞; - 更快的连接建立:UDP不需要建立连接;QUIC允许在首次连接时进行零往返时间连接建立,减少了连接延迟;
- 网络迁移不需要重新连接:QUIC协议允许网络切换时将连接迁移到新的IP地址,从而减少连接的中断时间,也不用重新建立连接;
- 向前纠错机制:每一个数据包都带有其他数据包的部分数据(数据包都带冗余),所以少量丢包可以不用重新发送,而使用其他数据包进行重组恢复;避免了数据重传;
HPACK压缩算法是什么?有什么作用?
HPACK算法时HTTP/2对于HTTP/1的改进中使用的算法;用于压缩头部;由于每次发送请求和接受响应的请求头和响应头中有很多重复的内容,影响传输效率,所以HTTP/2中用HPACK压缩算法来将高频出现在头部的字符串和字段进行压缩;
压缩过程:
- 对头部中高频出现的常见的字符串和字段的压缩:使用静态表编码(静态表早已经写入了HTTP/2框架中,通信双方都提前知道静态表内容,例如
:path : /index.html是一组key-value) - 对于在同一个连接上,传输完全相同的HTTP头部:使用动态表编码(动态表编码时通信双方在一个连接上都维护的表,可以动态更新),动态表的大小对于服务器的性能有影响,所以不能无限增大,到达某一个大小之后服务端就会关闭连接;
- 动态编码表:客户端和服务器各自维护各自的动态编码表,双方并不知对方的动态编码表的
key-value内容;收到编码后的消息,用HPACK解码;发送消息时,用静态编码表和动态编码表编码; - 虽然双方没有发消息同步动态编码表内容,但是动态编码表再双方是一致的,只有一致才能编码解码;
- 初始时动态编码表为空;动态编码表在收发数据包中逐渐扩大;
- 双方都坚持一套动态编码表算法,虽然不对彼此的动态编码表进行同步,但是在收发彼此都知道的数据包过程中,不断扩大动态编码表;(比如动态编码表想象为一共函数
key(),发送方发送报文mes1就用key(mes1)生成动态编码表内容,接收方收到mes1后也用key(mes1)生成动态编码表内容,虽然双方没有发送彼此的动态编码表进行同步,但是只要没有丢包,双方的动态编码表就一直保持同步) - 动态编码表不一致的问题:比如某个包丢失了,而这个包中可能存在可以更新动态编码表内容的头部信息,那之后的包很可能无法解码,因为发送方的动态编码表已经更新了,接收方没有接收到,所以动态编码表没有更新,最终导致动态编码表不同步,接收方就无法解码后面的信息;(在HTTP3中改进为QPACK压缩算法)
- 动态编码表:客户端和服务器各自维护各自的动态编码表,双方并不知对方的动态编码表的
- 对字符串进行哈夫曼编码来压缩;
静态编码表 + 动态编码表 + 哈夫曼编码,最终让传输效率大大提升;
讲一下HTTP/2的并发传输是如何实现的?
- 多路复用:允许在一个TCP连接上同时发送和接收多个请求/响应的数据流;
- 流Stream传输:每个HTTP请求和响应都被划分为一个或多个逻辑上的流Stream,每个流都有唯一的标识符和优先级,可以独立管理和传输,可以同时传输多个流;
- 头部压缩:使用头部压缩算法提高传输效率;
- 服务器推送:服务器可以主动推送消息,实现了服务器端的并发传输;
- 为Stream设置优先级:优先级高的流Stream会被优先处理;
QUIC协议是什么?怎么用QUIC协议加UDP协议实现类似TCP的可靠连接的功能?
UDP协议是简单、无序、无连接、不可靠的传输协议,数据包没有依赖关系;QUIC协议为UDP协议实现类似TCP的连接管理、拥塞窗口、流量控制、超时重传的网络特性,使得UDP协议可以在保留自己的简单、快速、实时传输等特性的同时,又实现了TCP的可靠性;
QUIC内部包含了TLS,而TCP和TLS是分层的,所以TCP握手完才能TLS握手,而QUIC和UDP结合时,UDP不需要握手,所以只用TLS握手,并且优化了TLS握手的过程,实现了近乎0时延的连接建立;
怎么实现近乎0时延?QUIC优先在第一次握手时就发送加密的应用数据,而不需要经历完整的握手过程之后才能发送数据;这样在第一次握手时发送方就可以附上请求,在第二次握手时接收方就可以做出响应,看上去数据就是0RTT建立连接;
QUIC+UDP实现近似TCP+TLS并且扩展了TCP+TLS的功能:
- QUIC内部包含TLS,所以可以实现TLS的功能(包括对数据包标上顺序,在接收端根据顺序重组数据包)
- 连接管理:支持0RTT握手,用连接ID标识每一个连接;
- 会话恢复:QUIC支持连接的会话恢复,即使连接断开,也可以通过之前保存的会话密钥来快速恢复连接状态,无需重新完整的握手;
- 重传机制:QUIC提供了类似TCP重传的重传机制,也包括超时重传(RTO时间内未收到ACK报文)和快速重传(连续收到3次相同的ACK报文);
- 流量控制:QUIC提供了类似TCP滑动窗口的流量控制机制,也是使用窗口,每个数据流都有自己的接收窗口大小,接收方根据报文的接收窗口大小来控制发送速率;
- 拥塞控制:也是通过拥塞窗口控制,也包括慢启动、拥塞避免、快重传等拥塞控制算法;
- 确认应答:虽然和TCP一样加入了确认应答机制,通过发送特定的ACK帧来实现,但有所不同;QUIC无需确认就可以发送消息;QUIC中的确认应答可以是无序的,不必等待连续的应答数据包;QUIC还支持延时确认机制,接收方可以攒够足够多的应答然后一次性发送;QUIC还可以用累积确认,即在确认应答包中包含已经成功接收的数据包序列号范围(就不要每一个不同的序列号数据包都发送一个应答);
- 多路复用:允许单个连接上同时传输多个数据流;
- 连接迁移:即使IP地址改变连接断开,也可以通过会话密钥实现恢复连接,即连接迁移;
- 安全性:提供了TLS的加密机制,确保数据传输的安全;
- 数据恢复:每一个数据包都有其他数据包的部分内容,即使个别数据包丢失,也可以由其余数据包中的冗余数据进行恢复,无需重传;
HTTP缓存是什么?缓存的实现方式有几种?
HTTP缓存就是在浏览器访问过目标资源之后,在本地(主机或浏览器)保存一份资源副本;之后如果继续申请访问同一资源,就可以不去服务器获取,而是在本地的资源副本中获取;(甚至可以无需和服务器做任何通讯)
HTTP缓存的实现方式:强制缓存、协商缓存;
- 强制缓存:不问服务器,直接在本地内存中找之前的副本;如果当前时间在副本的强制缓存期以内,则直接返回到浏览器;(缓存过期后,修改本地时间,也可以实现不去服务器找而在内存中找)
- 协商缓存:问服务器要请求的资源有没有修改过,最近一次修改时间是什么时候,然后和本地缓存的时间比较,如果发现本地缓存没有被修改,则使用本地缓存,并更新缓存时间为当前时间;(只需要通信一次,服务器返回状态码304说明可以使用本地资源)
- 怎么知道有没有修改过,有两种方法:
- 看服务器资源最后修改时间:本地缓存中有资源获取时间,将这个时间附到请求报文中,服务器收到后检查报文中的时间,看是否和最后修改时间一致;(有问题,即使资源内容没有改变最后修改时间也可能改变)
- 计算哈希:本地资源计算出一个哈希值附到请求报文中发送,服务器资源也计算出一个哈希值,比较两个哈希值;(哈希值计算消耗资源,可以用摘要算法计算部分的哈希值来减少资源消耗)
- 怎么知道有没有修改过,有两种方法:
副本资源和服务器资源一致性判断方式:
- 强制缓存:根据文件是否过期判断;(当副本创建时,会设置一个过期时间大小,通过请求资源时间和过期时间大小,计算出文件是否过期;如果本地时间修改,则可能即使过期也会使用缓存)
- 协商缓存:
- 本地缓存中有一个字段记录了文件被修改时间;在询问服务器资源时附上这个时间,服务器拿到这个时间然后来决定返回304还是返回新的资源和状态码200 OK;(缺点:有时候服务器端文件即使没有被修改,也可能更新文件修改时间,比如文件名先被修改,然后再改回来,此时文件修改时间变了,可文件内容没有改变,而我们却要重新返回文件资源)
- 基于ETag的协商缓存(比较文件指纹):根据文件计算出一个哈希值,作为文件指纹,只要本地缓存中的文件指纹和服务器的文件指纹没有变化,则我们认为文件也没有变化;(计算文件指纹意味着多出了计算开销,如果文件大、数量多则不适合;也可以选取文件的关键部分做文件指纹,准确率下降了,可开销也下降了)
什么是对称加密,什么是非对称加密?
对称加密(私钥加密):用相同的算法和密钥加密、解密;(密钥一旦泄露,后果很严重)
非对称加密(公钥加密):使用一对不同但相关的密钥:公钥和私钥;公钥用于加密数据,私钥用于解密数据;如果使用公钥加密,则需要对应私钥解密;如果用私钥加密,则需要对应公钥解密;
对称加密速度快,但密钥泄露后很不安全;非对称密钥速度慢,但是安全;
HTTPS的混合加密是什么,过程是什么样的?
混合加密是指对称加密和非对称加密联合使用;(对称加密的弊端在于会话密钥泄露之后很危险,所以用非对称加密发送会话密钥,用会话密钥实现对称加密,即保证了安全性,又保证了数据通信速度)
基本过程:
- 客户端向服务器发送一个HTTP请求;请求建立安全连接;
- 服务器向客户端返回一个包含服务器公钥的数字证书;
- 客户端向权威机构验证数字证书的有效性,确认服务器是合法的;
- 客户端使用服务器发来的公钥,随机生成一个对称加密密钥作为会话密钥;
- 客户端用会话密钥对数据加密,然后用公钥将将加密后的数据和会话密钥一起加密后发送给服务器;
- 服务器用私钥解密,获取到了会话密钥,然后双方就都有了安全的会话密钥,即可在后序的过程中使用会话密钥和对称加密来实现通信;
具体实现过程中,会话密钥不会这么简单,可能用3个双方都知道的随机数来生成会话密钥而不是传输会话密钥;
- 服务器生成第1个随机数,然后用私钥加密后和数字证书一起发送;
- 客户端收到数字证书,验证后提前出公钥解密出第1个随机数;
- 客户端生成第2个随机数,用公钥进行加密传输给服务器;
- 服
网络八股文:从URL到HTTPS全解析

最低0.47元/天 解锁文章
3104

被折叠的 条评论
为什么被折叠?



