Skip to Content
面试题库Computer Network计算机网络

计算机网络

微观上来看计算机网络的传输(这部分内容是计算机网络的核心,但是过于底层,要是没有兴趣可以跳过)

TCP/IP 模型与数据封装

从数据的角度上来看TCP/IP

我们通常说的OSI 7层模型只是个理论,在实际应用中,绝大多数人都在使用TCP/IP 4层模型、5层模型。无论4层还是5层,核心在于理解数据从上到下的“穿衣服(封装)”过程:

  1. 应用层:你写代码的地方。比如你构建了一个HTTP请求。这个时候的数据叫做报文(Message)
  2. 传输层:你的代码调用了TCP/UDP的API。TCP会给你的报文穿上“传输层的衣服(TCP头)”,记录上源端口和目的端口。这个时候的数据变成了段(Segment)
  3. 网络层:传输层把数据段交给了IP协议。IP协议给它穿上“网络层的衣服(IP头)”,写上源IP地址和目的IP地址,负责路由寻址。这个时候的数据变成了包(Packet)
  4. 数据链路层:光有IP不行,局域网内的设备只能认MAC地址。所以这一层给IP包穿上“MAC头(源MAC和目的MAC)”和“尾部校验和”。这个时候的数据变成了帧(Frame)
  5. 物理层:最后,网卡把封装好的帧,转换成0和1的电信号或光信号,顺着网线发出去。

相关阅读:

从功能的角度上来看TCP/IP

  • 应用层:直接为应用进程提供服务,收集应用程序中的数据。

  • 传输层:接收上层应用程序的数据,根据应用程序的需要,为进程通信提供数据传输服务。

    • TCP:提供了可靠性传输服务。超时重传、确认应答、序号机制、流量控制、拥塞控制、三次握手和四次挥手。
    • UDP:提供了实时性传输服务。后续可以根据上层需要,由应用层进行扩展,提供可靠性和是实时性兼有的服务。
  • 网络层:在主机上,接收传输层的数据,提供尽可能可靠的数据传输服务;在路由器上,提供路由寻址功能,实现不同局域网络的互通,形成互联网。

  • 数据链路层:为相邻节点的提供透明数据传输服务,两个相邻结点之间传送数据是直接传送的(点对点)。**数据链路层将网络层交下来的IP数据报组装成帧,**在两个相邻结点之间的链路上“透明”地传送帧中的数据。

    • 如何理解相邻节点

      • 非同一网络:源主机的数据链路层->路由器的数据链路层->目的主机的数据链路层。
      • 同一网络:源主机的数据链路层->目的主机的数据链路层。
    • 数据链路层的机制

      • 封装成帧:为数据链路层提供透明传输数据的能力。无论什么样的比特组合的数据都能够通过这个数据链路层,对所传送的数据来说,这些数据就“看不见”数据链路层。如通过字节填充法和字符填充法。
      • 差错检测:避免数据传输过程中是否产生比特差错,在检查到出现比特差错时就直接丢帧。如奇偶校验、循环冗余校验CRC。
      • 可靠传输:通过滑动窗口协议,保证数据传输的可靠性和效率,避免出现乱序问题。如停止-等待协议、回退N帧协议和选择重传协议。
      • 介质访问控制子层:解决多台主机同时发送数据时的碰撞问题。
  • 物理层:将帧作为数据部分,转换成比特流,进入信道进行传输。

差错控制——传输层与数据链路层之间的区别

传输层和数据链路层的差错控制的核心区别其实是各自服务的对象不同

  • 数据链路层为物理层提供可靠服务,保证向上层(网络层)提供的数据是无差错的,因为物理层可能导致比特传输差错,在数据链路层便提供可靠传输的服务可以保证物理层在传输过程中无差错;
  • 传输层是为网络层提供可靠传输服务的,保证向上层(应用层)提供的数据是无误且按序交付的。

交换机没有网络层,只通过数据链路层,需要保证数据是正确的,所以数据链路层必须提供可靠传输的服务;

网络层提供的是尽可能的可靠传输服务,为了能够让应用层的数据得到可靠传输,我们就需要利用传输层提供可靠的传输服务。

当然我个人认为还有一种可能性是客观存在的原因,有一些协议不能够到传输层,那么我们也需要为其提供可靠的传输服务。

从协议的角度上去看TCP的连接

从本质上来说,任何一个场景,协议的使用基本上都是一个套路

  1. 寻找IP、MAC地址:端对端通信的本质是依靠MAC地址进行的,知道MAC地址之前我们需要知道IP地址,IP地址的获取是通过DNS协议获得的,那么,接下来就需要使用ARP协议获取对应IP地址下物理主机的MAC地址,然后双方依靠MAC地址进行通信。

  2. 建立连接:寻找到IP、MAC地址后,如果端与端之间需要建立连接(TCP),那么就需要使用TCP三次握手和四次挥手。

  3. 数据传输

    1. 应用层:首先一定是从应用程序出发,需要经过应用层,应用层协议有可能是Http、私有协议;
    2. 传输层:应用层结束之后就来到了传输层,而传输层的协议其实就是TCP和UDP,封装应用层的数据包,这个取决于你对可靠性和实时性的取舍。
    3. 网络层:继续向下走,被IP协议进行封装,同时被封装的还有ICMP协议,进行网络状态的校验;
    4. 数据链路层:进行封帧;
    5. 物理层:最后通过物理层转换成对应的比特流。
    6. 路由器(三层模式,处理逻辑在网络层):找到路由器后,依据路由表进行寻址,确定下一跳。

相关阅读:

打开一个网页涉及到的协议

涉及到的过程

  • 浏览器查找域名的IP地址:DNS查找过程,分别是浏览器缓存、路由器缓存、DNS 缓存。

    • DNS:获取域名对应IP,域名解析的过程涉及到数据传输,肯定需要使用传输层协议进行传输。

      • 由于是端到端之间的数据传输,DNS模块将生成的DNS报文传递给传输层的UDP协议单元。
      • UDP协议单元将该数据封装成UDP数据报,传递给网络层的IP协议单元;
      • IP协议单元将该数据封装成IP数据包,其目的IP地址为DNS服务器的IP地址;
      • 封装好的IP数据包将传递给数据链路层的协议单元进行发送;
      • 发送时在ARP缓存中查询相关数据,如果没有,就发送ARP广播,得到ARP回应后,将IP地址与路由的下一跳MAC地址对应的信息写入ARP缓存表;
      • 写入缓存后,以路由下一跳的地址填充目的MAC地址,以数据帧形式转发,转发有可能进入多次;
  • 浏览器向web服务器发送一个HTTP请求:cookies会随着请求发送给服务器。

    • TCP:与服务器建立TCP连接。
    • IP:建立TCP连接时,需要发送数据,发送数据在网络层使用IP协议。
    • OPSF:IP数据包在路由器之间,路由选择使用OPSF协议。
    • ARP:路由器在与服务器通信时,需要将ip地址转换为MAC地址,需要使用ARP协议。
  • 服务器处理请求、客户端接收响应:生成一个HTML响应,并根据建立的连接,服务器发回一个HTML响应,浏览器开始显示HTML。

    • HTTP:在TCP建立完成后,使用HTTP协议访问网页。

传输层基础协议:TCP 与 UDP

传输层协议:TCP 与 UDP 的核心区别与取舍

要理解计算机网络,首先必须回答一个最经典的问题:TCP和UDP的区别是什么?

这个问题的核心不在于你能背出多少条区别,而在于你是否理解了**“可靠性”与“实时性”的取舍**。

  • TCP(传输控制协议):是面向连接的、可靠的、基于字节流的传输层协议。它就像是打电话,必须先拨通(建立连接),然后才能说话,对方没听清你还要重复(重传),最后还要挂断(释放连接)。它的应用场景是对数据准确性要求极高的场景,比如网页浏览(HTTP底层就是TCP)、文件传输(FTP)、邮件发送。
  • UDP(用户数据报协议):是无连接的、不可靠的、基于数据报的传输层协议。它就像是写信或者发广播,把信丢进邮筒就不管了,至于信丢没丢、顺序乱没乱,它一概不负责。正因为它没有那么多繁琐的确认机制,所以它的速度极快,实时性极高。它的应用场景是视频直播、语音通话、网络游戏。

所以,一句话总结,TCP与UDP的核心区别是:可靠与不可靠、面向连接和面向无连接。

  • 可靠与不可靠:UDP只关注信息的发送,TCP还需要关注是否能够正常接收和传输数据。
  • 面向连接和面向无连接:UDP的通信不需要建立连接,TCP需要建立连接。

相关阅读:

如何选择传输协议?

很多面试官都喜欢出一类场景题: “假设让你来设计类似腾讯会议、抖音直播,你会选择什么传输协议,你会怎么设计?要保证什么?”

候选人:“视频通话要求实时性,所以我选 UDP!”

面试官追问:“那 UDP 是不可靠的,丢包了怎么办?难道就让用户的屏幕一直卡着、花屏吗?”

候选人慌了:“呃……那为了保证画面完整,我选 TCP 吧!”

面试官冷笑:“TCP 丢包了会一直重传,阻塞后续数据,导致视频延迟越来越大,这怎么视频通话?”

这个问题本质上是在问,你应该怎么取舍协议的**“可靠性”与“实时性”**?

在回答具体设计之前,我们需要先明确 TCP 和 UDP 的核心边界

  • TCP(传输控制协议):它是面向连接的、绝对可靠的。适用于对数据准确性要求极高的场景。
  • UDP(用户数据报协议): 它无连接、不可靠,但速度极快、实时性极高。

它们的核心区别其实只有两点:可靠与不可靠、面向连接与无连接。TCP 关注的是‘必须安全送达’,而 UDP 关注的是‘只管发’。”

所以,面对视频通话的场景,这个问题问的其实是:“如何在保证传输速率的前提下,基于一定的可靠性!”。你完全可以在应用层基于UDP自己实现一套丢包重传、前向纠错的机制(比如QUIC协议),从而兼顾TCP的可靠性和UDP的实时性。这就是所谓的“在不可靠的网络上构建可靠的服务”。

可以参考这两篇文章: 音视频传输协议https://blog.csdn.net/L6466446/article/details/146337434?ops_request_misc=&request_id=&biz_id=102&utm_term=WebRTC&utm_medium=distribute.pc_search_result.none-task-blog-2\~all\~sobaiduweb\~default-1-146337434.142^v102^pc_search_result_base3&spm=1018.2226.3001.4187  RUDP可以看这篇文章https://blog.csdn.net/daxialeesuper/article/details/140711569?ops_request_misc=&request_id=&biz_id=102&utm_term=RUDP&utm_medium=distribute.pc_search_result.none-task-blog-2\~all\~sobaiduweb\~default-7-140711569.142^v102^pc_search_result_base3&spm=1018.2226.3001.4187 

TCP 连接管理与可靠传输

TCP 的可靠性是由一整套机制组成的,基本上从三个方向入手,建立连接的可靠性->点对点交互的可靠性->全局网络的可靠性:通过三次握手和四次挥手机制保证连接的可靠性;通过序号机制、流量控制、确认应答、超时重传机制保证信息不丢失;通过拥塞控制避免整体资源被浪费。(面试的时候回答到这些内容就行)

UDP正是因为没有上述的机制,所以它才被叫做是“不可靠传输”

一些概念的介绍

  1. 基础防错(校验和):每个包都有校验和,收到包算一下,不对就直接扔掉。
  2. 核心机制(序列号与确认应答):给每个字节编号,收到包就回复一个ACK,没收到就触发超时重传。为了加速重传,TCP还有快速重传机制(连续收到三个重复的ACK就不等超时,直接重发)。
  3. 点对点控制(流量控制):接收方通过“滑动窗口”告诉发送方自己还能吃下多少数据,防止发送方发得太快把接收方撑死。
  4. 全局控制(拥塞控制):发送方不仅要考虑接收方,还要考虑整个网络环境。通过慢启动、拥塞避免算法,试探网络的带宽边界,防止网络大塞车。

拥塞控制和流量控制之间的区别

  • 拥塞控制通常表示的是一个全局性的过程,它会涉及到网络中所有的主机、 所有的路由器和降低网络传输性能的所有因素。
  • 流量控制发生在发送端和接收端之间,只是点到点之间的控制。

相关阅读:

三次握手与四次挥手

既然说到了TCP是可靠的连接,那么它是怎么建立和断开连接的呢?

三次握手的目的,是为了同步双方的序列号,并确认双方都有发送和接收的能力。(这个我是在抖音hollis面试题里面看到的,我觉得很好,所以写出来,面试的时候也可以说,当然,另一种说法也要记住)

  1. A发消息:告知B,A有发送消息的能力(但是这个时候没有办法确认A有收消息的能力
  2. B接收消息:告知A,B有接收消息的能力,同时有发送消息的能力
  3. A接收消息并再发送:告知B,A有接收消息的能力

当然,还可以从另一个角度来解释为什么不能是两次?从等待的角度来回答

  • 假设客户端发了第一个消息,但是由于网络延迟,客户端以为丢了,所以又发了一个消息,并顺利建立了连接。
  • 很久之后,第一个消息突然到了服务端,如果是两次握手,服务端回复之后,连接就建立了。但如果此时客户端关机了,服务端就会一直等待,浪费资源。所以必须要有第三次,让客户端来做最终的确认。

再来看四次挥手

为什么挥手要比握手多一次?

  1. 因为在握手时,服务端可以把“确认收到(ACK)”和“请求连接(SYN)”合并在一个包里发过去。
  2. 但在挥手时,当服务端收到客户端的FIN时,它自己可能还有数据没发完,所以只能先回一个ACK稳住客户端,等自己的数据发完了,再发自己的FIN。这就是为什么是四次。

这里还有一个非常容易被问到的细节:客户端在发完最后一次ACK后,为什么要等待2MSL(两倍的最大报文段生存时间)才真正关闭连接?

保证所有在网络中流转的报文段全部失效,以达到确认确保服务端没有重传数据的目的。如果客户端发完消息之后就直接关机,万一这个消息丢失,服务端没收到,服务端就重发,如果客户端已经关机,服务端就永远等不到回复了。

相关阅读:

流量控制

流量控制是点对点的。 当接收方来不及处理发送方的数据,能通过滑动窗口,提示发送方降低发送的速率,防止包丢失。

TCP的流量控制通常使用滑动窗口协议,所以针对于每一个接收方和发送方,都会有一个接收窗口和一个发送窗口。窗口与窗口之间通过序列号判断自己接受的数据是否是满足条件的数据,避免包丢失和乱序。

可以看看这篇文章:https://cloud.tencent.com/developer/article/1556051 

拥塞控制

拥塞控制是全局性的。 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞

拥塞控制算法(慢开始+拥塞避免)就是解决这个问题的。

可以参考这个内容:https://blog.csdn.net/weixin_74798742/article/details/139705707?ops_request_misc=elastic_search_misc&request_id=a301146f16ea0450434fed37a4180afa&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2\~all\~top_click\~default-2-139705707-null-null.142^v102^pc_search_result_base3&utm_term=%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6&spm=1018.2226.3001.4187 

HTTP 协议演进与安全

HTTP 与 HTTPS 的本质区别

  • HTTP(超文本传输协议):最大的特点是“明文传输”和“无状态”。你在网上填的密码,在网络中就是一段谁都能看懂的明文字符串,非常容易被黑客在半路截获或者篡改。
  • HTTPS(HTTP over SSL/TLS):为了解决安全问题,在HTTP和TCP之间加了一层SSL/TLS加密层。

HTTPS 核心通信流程(TLS 密钥交换核心逻辑)

HTTPS到底是怎么实现安全的? 它结合了非对称加密和对称加密的优点:

  1. 服务端在 TLS 握手阶段,向客户端下发携带服务端公钥的数字证书;
  2. 客户端本地随机生成会话对称密钥,使用服务端公钥对该对称密钥进行非对称加密,加密后报文发送至服务端;
  3. 服务端通过本地留存的私钥,采用非对称解密算法,还原出客户端生成的会话对称密钥;
  4. 密钥协商完成后,通信双方统一使用该对称密钥进行业务数据加解密传输。

补充:非对称加密计算开销大、性能低,仅用于短期密钥协商;对称加密运算效率高,承担后续海量业务数据的加密传输,兼顾安全与性能。

中间人攻击风险(公钥篡改问题)

若无证书校验机制,中间人可拦截服务端原始公钥,替换为自身伪造公钥转发给客户端。

客户端会使用伪造公钥加密会话密钥,中间人截获密文后,通过自身私钥解密窃取会话密钥,全程劫持、窃听甚至篡改双向明文数据,实现中间人劫持攻击

CA 证书防篡改原理

  1. 服务端需向权威 CA 机构申请合规数字证书,证书内绑定域名、有效时长、服务端公钥,并由 CA 机构通过私钥签名
  2. 操作系统、浏览器内置全球可信根 CA 根证书,预装根公钥;
  3. 客户端收到服务端证书后,通过根证书链式逐级验签,校验证书合法性、签名完整性、域名匹配性及有效期;
  4. 校验通过,证明证书内公钥为服务端真实可信公钥;校验失败则直接拦截访问、抛出安全风险警告,杜绝公钥伪造与中间人攻击。

相关阅读:

状态管理与认证机制:Cookie、Session、Token

刚才提到了HTTP是“无状态”的,那服务器是怎么认出登录过的用户的呢?这就涉及到三种核心技术:

  • Cookie:存储在客户端浏览器的一段文本,随请求自动发送。它是最基础的载体。
  • Session:服务器端记录的会话数据(“有状态”)。服务器通过Cookie里的SessionID来认人。优点是服务端可控,缺点是多台服务器部署时同步困难,且易受CSRF攻击。
  • Token:服务器签发的一段加密字符串(比如JWT),由客户端保存并每次带上(“无状态”)。服务器不存会话,只负责解密验证。它天然适配微服务,扩展性极强。实际生产中,为了解决“无法主动注销Token”的问题,往往会结合Redis黑名单或较短有效期(加Refresh Token)来实现混合方案。

相关阅读:

长连接与 HTTP 演进史

早期的HTTP 1.0短连接。你请求一个HTML,它三次握手连一次,传完数据四次挥手断开;当你发现HTML里还有一张图片要请求时,它又得重新三次握手建立连接。在网络慢的时代,这种频繁的握手挥手极其浪费性能。

为了解决这个问题,HTTP 1.1默认开启了长连接(Keep-Alive)。也就是建立一次TCP连接后,大家先不断开,连续发好几个请求。而且它还支持了管道化传输(Pipeline)

但是!HTTP 1.1 的长连接有一个致命弱点:队头阻塞(Head-of-Line Blocking)。如果客户端一口气发了请求A和请求B,服务端必须先严格回复A,再回复B。如果服务器处理A卡住了,那么B的响应也只能在后面排队傻等。

为了干掉这个队头阻塞,HTTP 2.0做了一个革命性的改变:** 二进制分帧和多路复用**。

它把文本报文打碎成了二进制的“帧”,并且给每个帧打上了“流ID”。客户端可以把请求的帧混在一起乱序发过去,服务端也能乱序处理并乱序返回。浏览器收到后根据帧上的流ID自己拼凑出完整的响应。这就实现了真正意义上的并行传输,彻底消灭了HTTP层面的队头阻塞。

除了多路复用,HTTP 2.0 还有两个杀手锏:头部压缩(HPACK)服务端主动推送

但是,因为HTTP 2.0底层用的还是TCP,所以它没有解决TCP层面的队头阻塞!如果底层的TCP在传输过程中丢了一个包,TCP为了保证可靠性和顺序,会把后面收到的所有包全部扣留在内核缓冲区里,直到那个丢的包重传过来为止。

这就是为什么现在大厂在搞HTTP 3.0(也就是QUIC协议)。HTTP 3.0直接基于底层的UDP重新实现了一套可靠传输,彻底解决了所有层面的队头阻塞问题。

队头阻塞问题看这个:https://blog.csdn.net/bingyuea/article/details/130267950?ops_request_misc=&request_id=&biz_id=102&utm_term=Http%E7%9A%84%E9%98%9F%E5%A4%B4%E9%98%BB%E5%A1%9E%E9%97%AE%E9%A2%98&utm_medium=distribute.pc_search_result.none-task-blog-2\~all\~sobaiduweb\~default-0-130267950.142^v102^pc_search_result_base3&spm=1018.2226.3001.4187 

我之前自己总结的

  • Http1.x:本质上是由于管道化才导致队头阻塞。请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后,如果一个响应产生了延迟,后续的响应都会被延迟,这就是Http队头阻塞。原因是,没有序号标明顺序,只能串行接收。

    • 它只在有效荷载(payload)的前面附加头(headers),在资源块(resource chunks)之间不使用分隔符。它不会进一步区分单个资源与其他资源。
    • 比如:当浏览器发送给服务器的资源包括:js(大资源块)、css(小资源块)等内容,但是服务器不能对他们进行分块解析,就会导致需要等到js块解析完毕后,才去解析css块。
  • Http2:通过”流“的概念,解决了Http队头阻塞,但是没有解决tcp队头阻塞。之所以Http1.x会阻塞,其本质原因是Http1.x无法实现乱序发送,实现重组,为了避免数据乱序,需要通过阻塞的方式保证数据正序。“流”这个概念主要体现在”分帧“和”队头阻塞“上。通过分帧的方式,将数据分为互不依赖的帧,然后乱序发送,再在另一端重新组合;利用多路复用,实现tcp管道的复用,保证帧在传送的过程中不会发生阻塞。这两种方式结合解决了tcp队头阻塞问题。

    • tcp队头阻塞:假设有两个请求同时发送,这两个请求在两条不同的流中进行传输。假设在传输过程中,请求1的某个数据包丢了,如果是TCP,即使请求2的所有数据包都收到了,但是也只能阻塞在内核缓冲区中,无法交给应用层。
    • 这是因为HTTP2的传输层用的TCP,TCP的实现是在内核态的,而流是实现在用户态的,TCP是看不到“流”的,所以在TCP中,它不知道这个数据包是请求1还是请求2的,只会根据seq number来判断包的先后顺序。
  • Http3:解决了tcp队头阻塞问题。这是因为http2虽然是面向数据流的,但是这种数据流不是体现在tcp,而是在用户态,tcp层面是感知不到队头阻塞问题的。而QUIC抛弃了tcp,请求1的数据包丢了只会阻塞请求1,请求2不会受到阻塞。

相关阅读:

打破单向通信:WebSocket

大家都知道,HTTP有一个天生的缺陷:它只能由客户端主动发起请求。即使是长连接,服务端也不能无缘无故地主动给客户端推数据。

以前如果你想做一个网页聊天室,只能用“轮询”的笨办法——让浏览器每隔一秒钟就去问服务器:“有新消息吗?”这极其浪费服务器性能。

所以,WebSocket 应运而生。WebSocket 也是一个应用层协议,它最牛的地方在于它是全双工通信的。

当浏览器和服务器通过HTTP请求完成一次特殊的“握手升级”之后,双方的连接就变成了一条平等的双向通道。服务端只要一有新消息,就能立刻主动推给客户端,不需要客户端来问。

这就完美契合了股票行情推送、在线聊天室、协同办公等对实时性要求极高的场景。

相关阅读:

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册