网络传输场景面试题(重点)#
网络分层模型(重要)#
1. 介绍一下 OSI 七层协议,各层协议都有哪些?#

2. TCP/IP 网络模型有哪几层?#
应用层:负责为应用软件提供网络服务,例如HTTP、HTTPS、DNS等协议。
传输层:负责为应用程序层提供数据传输服务,传输层协议主要有 TCP和UDP,TCP是可靠传输协议,UDP是不可靠的传输协议。
网络层:负责主机寻址,打包和路由功能。 网络层的核心协议是IP、ARP、ICMP等协议。IP 协议负责寻址和路由,ARP协议负责获取MAC地址,ICMP负责提供诊断功能并报告错误。
网络接口层:负责为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。
3. IP 协议和 TCP 协议属于哪一层?#
IP 协议属于网络层,TCP 协议属于传输层。
4. 网络为什么要分层?#
分层的目的是为了降低耦合,各层相互独立之后,上层可以不关心下层的实现,只关心下层提供的接口服务,有利于排查网络问题,能更精细定位问题所在哪一层。
而且分层之后层一层之间不会产生关联性,不会因为某个层的改动,影响了其他层,比如我们应用层的 HTTP 协议,从 HTTP1.1 升级到 HTTP2.0 的时候,并不会对传输层、网络层等有影响,或者网络层的IPv4协议升级为 IPv6协议的时候,也不会影响应用层、传输层。
键入网址场景问题(重要)#
1. 输入网址后,期间发生了什么?#

- 浏览器会先解析 URL,然后构造 HTTP 请求报文。
- 接着进行域名解析,将域名解析为 IP地址,系统缓存、本地系统 host 文件、本地 DNS 服务器、本地DNS服务器分别去根域名服务器->顶级域名服务器->权威域名服务器询问
- 由于HTTP是基于TCP传输的,所以在发送HTTP请求前,需要进行三次握手,在客户端发送第一次握手的时候,TCP头部会填上SYN标记位,同时填上目标端口和源端口的信息。源端口是浏览器随机生成的,目标端口要看是HTTP还是HTTPS,如果是 HTTP 默认目标端口是 80,如果是 HTTPS 默认是 443。
- 然后到网络层,会加上IP头,同时填上目标IP地址和源IP地址。
- 然后到数据链路层,会通过ARP协议,获取路由器的MAC地址,然后会加上MAC头,填上目标MAC地址和源MAC地址。
- 然后到物理层之后,直接把数据包,转发给路由器,路由器再通过下一跳,最终找到目标服务器,然后目标服务器收到客户的 SYN 报文后,会响应第二次握手。
- 当双方都完成三次握手后,如果是 HTTP 协议,客户端就会将 HTTP 请求就会发送给目标服务器;如果是 HTTPS 协议,客户端还要和服务端进行 TLS 四次握手之后,客户端才会将HTTP报文发送给目标服务器。
- 目标服务器收到 HTTP 请求消息后,就返回 HTTP 响应消息,浏览器会对响应消息进行解析渲染,呈现给用户。
2. DNS是如何解析的?属于哪一层的协议?#

3. DNS域名解析使用的什么协议?#
在DNS中,域名解析请求和响应都是基于UDP进行传输的。
UDP是一种无连接的传输层协议,它提供了一种简单的传输机制,适用于对实时性要求较高的应用场景。DNS使用UDP协议进行域名解析是因为域名解析通常是短小而频繁的请求,UDP的无连接特性可以减少建立和断开连接的开销,并提高解析的效率。
UDP对于TCP的缺点是没办法保证数据的可靠传输,针对这个缺陷,可以在应用层实现一个超时重传机制,如果域名解析请求在一定时间内没收到响应,那么就重发域名解析请求。
4. 输入域名如何知道端口的?#
HTTP 默认端口是 80,HTTPS 默认端口是 443,如果用户指定了端口,比如域名:8080,这时候就会使用 8080 作为目标端口。
5. 客户端向服务端的IP地址发送数据,服务端如何确定应该把数据传递给谁?#
服务端的应用会监听端口,协议栈会通过端口来区分不同应用的数据。
6. 现在很多网站都要求使用https,假设我们输入一个http网址,网站是如何实现由http跳转到https的?#
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
- 服务器网关收到http请求后,给客户端一个http响应,状态码为301(永久重定向)
- 浏览器收到重定向响应后,自动向服务器发起一个新的 HTTPS 请求(默认端口 443)。
网络传输场景问题#
1. 如果浏览器没有显示页面有哪些原因?#
先确定是服务端的问题,还是客户端的问题
如果客户端网络没问题,就抓包确认 DNS 是否解析出了 IP 地址,如果没有解析出来,说明域名写错了,如果解析出了 IP 地址,抓包确认有没有和服务端建立三次握手
如果客户端网络是正常的,但是访问速度很慢,导致很久才显示出来。可以通过 ping 去确认网络延迟是否正常,如果耗时很严重,可以排查服务器的流量是不是很大,导致超过了带宽上限,产生了丢包的问题。如果网络是正常的,可能要排查接口为什么处理这么久,这里有可能是慢 sql 导致的。
2. 服务器ping不通但是http能请求成功,会出现这种情况吗?#
会的,因为ping 和 http 使用的协议是不一样的,ping 是基于网络层的 icmp 协议,而 http是基于传输层的 tcp 协议的,有可能服务器的防火墙禁止 icmp 协议,但是 tcp 协议没有禁止,就会出现服务器 ping 不通,但是 http 能请求现象。
3. 客户端 TCP 连接一个不存在的IP地址的服务端会发生什么?(冷门)#
如果访问的 IP 地址是局域网内的,客户端的内核在发 arp 请求的时候,广播询问这个目标 IP 地址是谁的,由于网络中不存在该目标 IP 地址,所以没有设备应答客户端的 arp 请求,这时候就会卡在 arp 协议,客户端的 SYN 报文是发送不出去的。
如果访问的 IP 地址不是局域网的,客户端会先将 SYN 报文发给路由器,然后路由器会继续转发,由于目标 IP 地址是不存在的,该 SYN 报文会在网络中消亡,因此客户端是不会收到对 SYN 报文的确认报文的,接着客户端会触发超时重传,重传 SYN 报文,直到重传的次数达到最大次数后,客户端的连接就会被释放。
4. 客户端 TCP 连接一个IP地址存在但是端口不存在的服务端会发生什么?(冷门)#
端口不存在的话,代表服务端没有监听这个端口,服务端在收到客户端的 SYN 报文后,服务端会回 RST 报文,客户端收到 RST 报文后,会断开连接。
5. 客户端 UDP 发送一个 IP地址存在但是端口不存在报文会发生什么?(冷门)#
服务端会回 ICMP 报文,报告端口不可达。
应用层面试题(重点)#
HTTP(重要)#
1. HTTP协议的特点是什么?#
HTTP具有简单、灵活可扩展、无状态等特点,是一种广泛应用于Web通信的协议。
- 基于文本: HTTP的消息是以文本形式传输,易于阅读和调试。
- 可扩展性:HTTP协议本身不限制数据的内容和格式,可以通过扩展头部、方法等来支持新的功能。
- 灵活性: HTTP支持不同的数据格式(如HTML、JSON、XML等),适用于多种应用场景。
- 请求应答模式:HTTP 协议使用的是请求 - 应答通信模式,请求方先发起连接和请求,是主动的,而应答方只有在收到请求后才能答复,是被动的,如果没有请求时不会有任何动作。
- 无状态: HTTP每个请求之间相互独立,服务器不会保留之前请求的状态信息,需要通过其他手段(如Cookies、Session)来维护状态。
2. HTTP 报文格式?怎么分割的?#
HTTP 报文格式分为请求行、请求头、请求体三个部分。
- 请求行是请求或响应的基本信息,比如请求方法、URL、HTTP 版本信息;
- 请求头使用 key-value 形式更详细地说明报文,比如Host字段、Connection 字段、Content-Length 字段
- 请求体是实际传输的数据,比如文本数据、图片数据
3. HTTP默认的端口是什么?#
80 端口
4. HTTP 有什么方法?#
我了解到 HTTP 方法的有 GET、POST、PUT、HEAD、DELETE 这些方法,其中:
- GET 方法是用来请求从服务器获取资源的;
- HEAD 方法和 GET 方法类似,也是请求从服务器获取资源,但与GET请求不同的是,服务器不会返回请求的实体数据,只会传回响应头,也就是获取的是资源的“元信息”。
- POST 方法是用来向服务端提交数据,数据就放在报文的 body 里
- PUT 方法和 POST 类似,也可以向服务器提交数据,区别在于POST 是“新增数据”,PUT 是“更新数据”。
- DELETE 方法是用来删除资源
5. 分析一下哪些 HTTP 方法是安全或者幂等的?#
安全的方法:GET / HEAD 不安全的方法:POST / DELETE / PUT
幂等的方法:GET / HEAD / DELETE / PUT 不幂等的方法:POST
6. GET 和 POST 请求的区别?追问:GET 请求一定是安全且幂等的吗?#
如果开发者处理 GET 请求的方式是新增数据,这时候 GET 请求就不是安全且幂等的。
7. HTTP 有什么状态码?#
HTTP 状态共有 5 类:
数字 1 开头的状态码表示目前是协议处理的中间状态,还需要后续操作,比如客户端请求服务端从 HTTP 切换为 WebSocket 通信的时候,服务端如果同意切换,就会回 101 状态码。
数字 2 开头的状态码表示服务器收到并成功处理了客户端的请求,比如 200 状态码是代表服务端成功响应了客户端的请求。
数字 3 开头的状态码表示服务端的资源发生了变动,需要进行重定向了,比如 301 是代表永久重定向,302 代表临时重定向。
数字 4 开头的状态码是客户端错误,表示客户端发送的请求报文有误,服务器无法处理,比如 404 状态码表示资源在本服务器上未找到。
数字 5 开头的状态码是服务端错误,服务器在处理时内部发生了错误,比如 502 状态码是nginx服务器作为代理时返回的错误码,表示nginx服务器自身工作正常,但是访问后端服务器时发生了错误,具体的错误需要去排查后端服务器。
8. 什么情况下会出现502错误码呢?#
如果客户端访问服务器是通过 nginx 来反向代理到应用服务器,那么如果应用服务器如果出现了故障,导致 nginx 无法从应用服务器获取到响应,这时候 nginx 就会返回 502 错误码给客户端。
9. 有个服务出现了504,你觉得这个服务是出了什么问题?#
504是网关超时错误,通常是nginx将请求代理到后端应用时,后端应用没有在规定的时间返回数据,需要开发检查下应用那块有什么耗时的操作
比如是否出现了 sql 慢查询,接口是否发生死循环、死锁等问题,然后后端服务器系统负载高不高。
10. 重定向是哪一类状态码?临时重定向和永久重定向有什么区别?#
301 状态码是代表永久重定向,客户端收到 301 状态码后,会记忆重定向后的 URL 地址,这样下一次访问的时候,不需要访问旧 URL,直接跳转到新 URL 访问。
302 状态码代表临时重定向,客户端收到 302 状态码后,不会记忆重定向后的 URL 地址,下一次访问的时候,还需要访问旧 URL ,再跳转访问新的 URL 。
11. HTTP是长连接还是短连接?#
HTTP 1.0 虽然支持长连接,但是默认的连接行为是短链接,从HTTP1.1版本之后,都是默认长连接了。
12. HTTP长连接和短连接的区别?#
短连接:每次通信请求都需要建立新的连接,请求完成后立即关闭连接。这样每次请求都需要建立连接和释放连接,会增加通信开销和延迟。
长连接:在通信过程中保持连接的持续性,多次请求可以共享同一个连接。在长连接中,客户端和服务器建立连接后可以进行多次请求和响应,减少了连接建立和释放的开销,提高了通信效率。
13. HTTP长连接有什么好处?#
长连接可以在一次TCP连接中可以发送和响应多个HTTP请求,可以减少了 TCP 连接资源创建和断开的开销。
14. HTTP/1.0 和 HTTP/1.1 的区别?#
长连接:
pipline:并发发送HTTP请求
host字段:HTTP/1.0 没有 host 字段,HTTP/1.1 新增了 host 字段, 通过Host头部字段,一个物理服务器可以承载多个域名或站点
15. HTTP/1.1 和 HTTP/2.0 的区别?#
我认为 HTTP/1.1 和 HTTP/2.0 最大的区别在于,HTTP/1.1无法实现请求和响应的并发传输,而 HTTP/2.0 能够实现请求和响应的并发传输,HTTP/1.1 虽然支持了管道化请求模式,能够并发传输HTTP请求,但是HTTP响应还是需要按顺序返回,无法做到HTTP响应并发传输,HTTP/2 引入了 stream 的概念,不同的HTTP请求和响用不同的 stream 来区分,多个 stream 复用一条 TCP 连接,只需要一条连接就可以达到了并发传输的效果。
HTTP2.0 在 HTTP 报文格式上也做了改进,HTTP2.0 用了 HPACK 算法压缩了 HTTP 头部,同时将 HTTP/1.1 纯文本的格式改进成了二进制格式,提高了数据传输的效率。
HTTP2.0 还支持服务器主动推送资源,比如客户端在从服务器获取 HTML 文件时,可能这个页面渲染还需要其他 CSS,这时候服务器可以接主动推送 CSS 文件,可以减少了消息传递的次数。
16. HTTP/2.0 和 HTTP/3.0 的区别?#
HTTP/3.0 连接建立方面比 HTTP/2.0 更高效,HTTP/2.0建立连接的时候需要 3 次 TCP 握手+TLS 四次握手,而 HTTP3.0 的 QUIC 协议只需要 3 次握手就能完成连接建立+TLS握手建立 HTTP/3.0 在网络环境切换的过程,可以不需要重新建立连接
17. HTTP是无状态的吗?#
是的,HTTP 是无状态的,一般我们会通过 Cookie、Session、Token这些机制来维护用户的状态。
18. HTTP 用户后续的操作,服务端如何知道属于同一个用户?追问:如果服务端是一个集群机器?#
可以使用 Session Cookie 的机制 ,达到身份识别的效果。 第一种方案,将 session id 集中保存在 redis 或者 mysql,服务器集群通过判断 session id 的状态信息在不在 redis 或者 mysql,来确定用户是否已经登陆,这种方案的缺陷是单点故障的问题(虽然也可以对redis搭建集群,但是架构的成本太高了)
第二种方案,服务器索性不保存 session 数据了,把状态信息保存在客户端,每次请求都发回服务器,这个就是 token 机制,为了保证 token 不被中间人篡改,可以使用 JWT 的方式来进行身份识别,通常分布式系统都是采用 JWT 来进行身份状态识别。
19. 如果禁用 Cookie,怎么实现 Session?#
可以通过重写 URL 来实现 Session 机制,就是在 URL 中增加 session id 请求参数。
20. cookie 和 seesion 的区别?#
Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
Session代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。
21. Cookie、Session 和 Token 有什么区别?#
简单来说 Cookie 适用于简单的状态管理,Session 适用于需要保护用户敏感信息的场景,而 Token 适用于状态无关的身份验证和授权。
22. 简述 JWT 的原理和校验机制#
JWT 令牌是由 3 个部分组成,分别是头部、负载、签名。头部是描述令牌使用的签名算法,负载描述的是用户信息,比如用户名称、过期时间等等,头部和负载都是不会被加密的,只是会用 base64 编码。最后一部分是签名是对头部和负载两部分数据的签名,签名的过程是,使用头部的签名算法,通过服务器的密钥对前面两部分内容进行加密计算。
23. JWT 令牌为什么能解决集群部署?#
JWT 包含身份验证和会话信息,可以让服务器无需存储会话信息,就让服务器成为无状态的了,从而比较容易实现扩展。
24. JWT 有什么缺点?#
令牌难以主动失效、JWT 要防止盗用的问题
25. 什么是跨域?什么情况下会发生跨域请求?#
当一个网页去尝试访问不同源的资源的时候,就意味着发生了跨域请求,只要域名、协议、端口这三个信息任意一个不同,都认为是不同源的URL。
跨域请求在浏览器上是不被允许的,只要在浏览器上发生跨域请求操作时,浏览器就会自动抛出的错误。
如果想绕过这个限制,可以用跨域资源共享(CORS)技术,实现的方式是服务器需要在响应头上添加 Access-Control-Allow-Origin 的字段,这个字段是设置为需要放行的域名,浏览器识别到了,才能放行该请求。
26. RestFul 是什么?RestFul 请求的 URL 有什么特点?#
RestFul 是一种 API 接口设计规范,用 URL 定位资源,用HTTP 方法表示接口的动作,用 HTTP 状态码表示接口处理的情况。
RestFul风格的 HTTP 接口可以通过 URL 就能判定这个接口是做什么的。比如:
- /articles POST ,代表新增一个文章
- /articles GET ,代表获取全部文章,有可能后边带参数进行一些过滤查询或分页
- /articles/1 GET ,代表获取 id 为 1 这篇文章
- /articles/1 PUT ,代表更新id为 1 的文章,请求体可能会带一些更新内容
- /articles/1 DELETE ,代表删除id为 1 的文章
HTTPS(重要)#
1. HTTP 和 HTTPS 有什么区别?#
安全性、 建立连接、端口号、证书
2. 了解过哪些加密算法?#
对称加密算法、非对称加密算法、哈希算法
在 HTTPS 协议里,对称加密算法和非对称加密算法这两种算法都会用到,对称加密算法适用于大量数据的加密和解密,而非对称加密算法适用于密钥交换和数字签名等场景。
对称加密算法就是用一个密钥进行加解密,比如 AES 算法,
非对称加密则是有 2 个密钥,分别是公钥和私钥,比如RSA算法。
哈希算法主要用过 MD5 算法,哈希算法是一种单向算法,用户可以通过哈希算法对目标信息生成一段特定长度的唯一的哈希值,却不能通过这个哈希值重新获得目标信息,所以用于数据完整性校验方面。
3. 对称加密和非对称加密是什么?各自有哪些算法?#
对称加密算法:AES(高级加密标准)、DES(数据加密标准)、3DES(三重数据加密算法) 非对称加密算法:RSA、ECC(椭圆曲线密码学)等。
对称加密和解密都是用同一个密钥进行操作,加密和解密过程速度较快,适合对大量数据进行加密,对称密钥必须保密,不能明文传输,常见的对称加密算法有AES、DES等。
非对称加密使用两个密钥,分别是公钥和私钥,加密和解密过程相对较慢,适合对少量数据进行加密。公钥可以任意分发,而私钥必须保密,可以通过公钥加密对称密钥,私钥解密的方式,保证对称密钥的安全传输,常见的非对称加密算法有RSA、ECC等。
4. 对称和非对称的加密算法的区别?#
对称加密和解密都是用同一个密钥进行操作,加密和解密过程速度较快,适合对大量数据进行加密,对称密钥必须保密,不能明文传输。
非对称加密使用两个密钥,分别是公钥和私钥,加密和解密过程相对较慢,适合对少量数据进行加密。公钥可以任意分发,而私钥必须保密,可以通过公钥加密对称密钥,私钥解密的方式,保证对称密钥的安全传输。
5. 假设有一个文件,大小未知,现在要把它上传到云端,该使用对称加密还是非对称加密算法?#
使用对称加密算法比较好,因为对称加密算法运算速度是比非对称加密更快的,比较适合数据量大常见的加密。
6. HTTPS 建立过程是怎么样的?#
首先客户端要和服务端先进行 TCP 三次握手建立 TCP 连接。接下来,会进行 TLS 四次握手:
第一次 TLS 握手:客户端首先会发一个 Client Hello 消息,消息里面有客户端使用的 TLS 版本号、支持的密码套件列表、客户端生成的随机数,这个随机数是用来后面生成对称密钥元素之一。
第二次 TLS 握手:当服务端收到客户端的消息后,会返回 Server Hello 消息给的客户端,消息里面有服务器确认的 TLS 版本号、密码套件、服务端生成的随机数。接着服务端为了证明自己的身份,会发送 Server Certificate 给客户端,这个消息里含有数字证书。随后,服务端发了 Server Hello Done 消息,目的是告诉客户端,我已经把该给你的东西都给你了,本次握手完毕。
校验证书:客户端收到服务端的数字证书的时候,会对校验服务端的证书,如果证书是合法的,客户端会用 CA 机构的公钥解密数字证书拿到服务端的公钥。
第三次 TLS 握手:客户端再次生成一个随机数,用服务端的公钥加密后,通过 Client Key Exchange 消息传给服务端。服务端收到后,用服务端的私钥解密得到客户端的第二个随机数。到这里,服务端和客户端双方都有 3 个随机数,双方根据已经得到的三个随机数,会根据算法生成对称密钥。生成完对称密钥后,客户端会发一个消息告诉服务端开始使用对称加密方式发送消息,并且还会对之前所有发送的数据做个摘要,再用对称加密加密一下,让服务器做个验证,验证对称密钥是否可用,以及之前握手信息是否有被中途篡改。
第四次 TLS 握手:服务器也是同样的操作,发送消息告诉客户端开始用对称加密方式发送消息,并且也会对数据做个摘要,并用对称密钥加密一下,让客户端做个校验,如果双方都验证加密和解密没问题,那么 TLS 四次握手正式完成了。
最后,就用对称密钥加解密 HTTP 请求和响应了。
7. 为什么需要三个随机数?#
因为计算机生成的随机数其实是一个伪随机,那么只用一个随机数来生成的对称密钥很容易就被破解了,用三个伪随机数就十分接近随机了,这样称密钥破解的难度都变高了。
8. 一次HTTPS需要几次RTT(就是几个来回)?#
HTTPS是四次握手,那么就是 2 次RTT
9. 你了解业界现在有一个RTT建立HTTPS连接的方案吗?#
TLS 1.2 版本如果使用的是 RSA 密钥交换算法,那么需要 4 次握手,也就是要花费 2 RTT,才可以进行应用数据的传输。
基于 ECDHE 密钥交换的 HTTPS 连接方案,可以实现 1 个 RTT建立 HTTPS 连接
10. HTTPS 过程进行了多少次非对称加密?多少次对称加密?#
客户端会用服务端的公钥加密随机数,服务端再用私钥解密,这里涉及了 1 次非对称加密。
客户端和服务端生成对称密钥之后,都需要对之前握手的数据做个摘要,并用对称密钥加密一下,这个过程客户端和操作都会涉及到,所以 HTTPS 握手期间用了 2 次对称加密,客户端和服务端各做了一次。
11. SSL握手流程为什么要使用非对称加密?#
我的理解主要是为了保护对称加密钥不被中间人窃取,如果对称加密钥被窃取了,使用这个对称加密钥加密的 HTTP 报文就很容易被破解了。
在 HTTPS 协议进行 TLS 握手的时候,客户端生成随机数,这个是生成对称加密钥元素之一,它会被公钥加密后传输给服务端,由服务端用私钥解密,这里就保证了对称加密钥的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容。
12. 为什么 HTTPS 不用非对称加密算法加密 HTTP 报文?#
非对称加密算法的加密和解密操作相对比对称加密算法更消耗 CPU 计算力,也更耗时,而HTTP报文通常包含大量的数据,如果直接使用非对称加密算法对整个报文进行加密和解密,会导致性能下降和延迟增加。
13. HTTPS 会对 URL 加密吗?#
URL 是属于 HTTP 报文头部的信息,HTTPS 会对整个 HTTP 报文都会加密,所以 HTTPS 是会对 URL 加密的。
14. CA 机构如何验证server身份?#
服务端在向CA机构申请证书的时候,CA机构会通过自己的私钥对服务器的一些信息进行数字签名,然后在HTTPS握手阶段的时候,服务端会发送证书给客户端来验证,客户端实际上已经内置了CA机构的公钥,那么就用这个公钥来验证服务端的数字证书是否是可信的。
15. 证书是绿色的是什么意思?#
代表网站是可信的,浏览器在 HTTPS 握手阶段会对网站服务器下发的证书进行校验,如果校验成功,代表网站的身份的可信的,是被 CA 机构认证过的。
16. 自己随便编一个证书可以吗?需要去什么地方注册?#
浏览器在校验这个证书的时候,会认为是非法的证书,这时候浏览器会显示访问的网站是不可信。
得去 CA 机构申请证书,浏览器才会认为是合法的证书,这样才能正常的访问网站的内容。
RPC#
1. RPC的作用是什么?#
Remote Procedure Call RPC 是远程过程调用,主要运用于微服务之间的通信,它的作用是帮助我们屏蔽网络编程细节,实现调用远程方法就跟调用本地(同一个项目中的方法)一样的体验,让我们更专注于业务逻辑,而无需关注底层网络通信的细节。
2. 为什么有HTTP协议了?还要用RPC?#
HTTP 和 RPC 其实是两个维度的东西, HTTP 指的是通信协议。而 RPC 则是远程调用,其对应的是本地调用。RPC 的通信可以用 HTTP 协议,也可以自定义协议,是不做约束的。
RPC 因为它定制化程度更高,可以采用体积更小的protobuf或其他序列化协议去保存结构体数据
Nginx#
1. Nginx位于七层网络结构中的哪一层?#
应用层,nginx nginx 是七层负载均衡。
2. Nginx有哪些负载均衡算法?#
普通轮询、加权轮询、IP哈希、URL哈希、最短响应时间、最短连接 任务平分类:普通轮询、加权轮询 负载均衡类:最短响应时间、最短连接 Hash类:IP哈希、URL哈希
3. 什么是反向代理?什么是正向代理#
正向代理代理的客户端这一方,而反向代理是代理服务器这一方,可以通过负载均衡策略,将请求分发到不同服务器上。
传输层面试题(重点)#
TCP 三次握手(重要)#
1. TCP 头部有哪些字段?#
窗口大小、标记位、头部长度
序列号和确认号都是 32 位大小,序列号可以保证数据的有序性
源端口号和目的端口号是 16 位大小,源端口是发送方使用的端口号,目的端口是接收方使用的端口号,端口的作用是标识TCP连接是哪个进程的。
2. 说一下 TCP 三次握手的过程#
close syn_sent established
close listen sync_rcvd established
最开始双方的 TCP 连接都处于 close 状态,服务端首先会监听一个端口,处于 Listen 状态。
在第一次握手的时候,客户端会随机生成初始化序号,放到 TCP 报文头部的序号字段中,同时把 SYN 标志设置为 1,这样就表示 SYN 报文。接着把这个 SYN 报文发送给服务端,之后客户端处于 SYN_SENT 状态。
服务端收到 SYN 报文后,首先服务端也会随机生成初始化序号,放到 TCP 报文头部的序号字段中,然后对客户端的初始化序号+1作为确认号,放到 TCP 报文头部的确认应答字段中,并将 SYN 和 ACK 标志设置为 1,这样就表示 SYN-ACK报文,后把该报文发给客户端,之后服务端处于 SYN_RCVD 状态。
客户端收到服务端SYN-ACK报文后,客户端会回一个 ACK 确认报文,该报文的确认号是服务端的初始化序号+1,并且 ACK 标志会设置为 1。之后客户端处于 ESTABLISHED 状态。
服务端收到 ACK 确认报文后,服务端也进入处于 ESTABLISHED 状态。
3. 为什么需要三次握手?两次不行吗?#
两次握手服务端无法确定客户端是否收到了自己的回复,三次握手可以有效防止历史连接的建立,避免资源浪费 三次握手可以确认客户端和服务端是否同时具备发送和接收的能力
4. 如果第一次握手丢包,会发生什么?#
如果第一次握手丢包了,达到超时重传的时机的话,会进行重传SYN报文,如果重传次数达到最大次数,还是没有收到第二次握手的话,客户端就会断开链接了。
5. 如果第二次握手丢包,会发生什么?#
第一个是报文中的 ACK, 是对第一次握手的确认报文,那么当第二次握手的丢失的时候,就会导致客户端长时间没有收到 ACK 而触发超时重传 SYN 报文
第二个是报文中的 SYN,是服务端发起建立 TCP 连接的报文,那么当第二次握手的丢失的时候,服务端就收不到第三次握手,于是服务端这边会触发超时重传机制,重传 SYN-ACK 报文
6. 如果第三次握手丢包,会发生什么?#
我的理解是第三次握手的 ACK 是对第二次握手的 SYN 报文的确认,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。
7. TCP的半连接队列和全连接队列了解过吗?#
半连接队列:服务端收到客户端发起的 SYN 请求后,内核会把未完成握手的连接存储到半连接队列,等待完成三次握手后转移到全连接队列。
全连接队列:服务端收到第三次握手的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到全连接队列,等待进程调用 accept 函数时把连接取出来。
TCP 四次挥手(重要)#
1. TCP 四次挥手的过程#

2. 为什么 TCP 需要四次挥手?三次挥手不行吗?#
TCP 是全双工协议,双方都具备发送和接收的能力:
服务端收到后,服务器收到客户端的 FIN 报文时,内核会马上回一个 ACK 应答报文,但是服务端应用程序可能还有数据要发送,所以并不能马上发送 FIN 报文,而是将发送 FIN 报文的控制权交给服务端应用程序,如果服务端应用程序有数据要发送的话,就发完数据后,才调用关闭连接的函数。所以第二次挥手和第三次挥手通常不会合并一起发送,而是分开发送,所以就需要四次挥手。
3. TIME_WAIT 是如何产生的?#
当 TCP 连接的主动关闭方关闭连接,与被动关闭方进行了四次挥手的时候,在主动关闭方发送完第四次挥手后,也就是最后一个 ACK 报文后,主动关闭方的 TCP 连接就会进入到 TIME_WAIT 状态,这个状态会持续 2MSL的时长,以确保对方已经收到了最后一个ACK报文。
4. 为什么 TIME_WAIT 状态要等待 2MSL?#
- 等待2MSL就可以让两个方向的报文可以在网络中自然消失
- 为了确保第四次挥手 ACK 报文能被接收,从而帮助被动关闭方正常关闭连接
5. TIME_WAIT 过多有什么危害?#
会占用系统资源,比如文件描述符、内存资源、CPU 资源、线程资源等。
6. 怎么解决 TIME_WAIT 状态过多的问题?#
如果是客户端有大量 time_wait状态,可以考虑开启 tcp_tw_reuse参数,当发起新连接的时候,会复用处于 time_wait 状态的连接。
如果是服务端的话,尽量让主动断开连接的方式,由客户端来进行,可以在应用层设计一个逻辑,当服务端要断开连接的时候,发送一个消息给客户端,客户端收到之后,由客户端来断开 tcp 连接,这样服务端就不会有 time_wait状态了。
7. 服务端产生大量 TIME_WAIT 状态的原因是什么?#
HTTP 没有使用长连接 HTTP 长连接的请求数量设置过小
8. 服务端产生大量 CLOSE_WAIT 状态的原因是什么?#
是服务端没有及时调用 close 关闭连接的函数,导致出现大量 CLOSE_WAIT 状态的连接,因为只有正确调用了 close 关闭连接函数的时候,TCP 连接状态才会有从 CLOSE_WAIT 状态变为 LAST_ACK 状态。
9. 如果server发送FIN之后,因为client挂掉了,收不到回应,会发生什么?#
重传FIN报文,如果FIN报文达到最大的重传次数之后,还是没有收到响应,那么 server 就会断开链接了 。
10. 如果客户端宕机重启,收到了server的FIN,会发生什么?#
既然客户端宕机重启了,之前的TCP连接信息就不存在了,那么如果收到server的FIN,会回RST报文给server,server收到 RST报文就会断开连接。
TCP 与 UDP(重要)#
1. TCP 和 UDP 有什么区别?#
TCP 是面向连接的协议,在发送数据的时候,需要先建立 TCP 三次握手,而 UDP 无连接的协议,直接就可以发送数据。
TCP 会通过超时重传、流量控制、拥塞控制保证数据的可靠传输,而 UDP 并没有这些特性,UDP 不考虑数据的可靠性。
TCP 发送的数据是以字节流的形式,没有边界。而 UDP 是一个包一个包的发送,是有边界的。
2. 什么时候用 TCP? 什么时候用 UDP?#
如果主要关注数据接收的可靠性和顺序,可以选使用 TCP,比如FTP协议、HTTP协议都是基于 TCP 协议进行传输数据。 如果主要关注的是速度和实时性,而且并不在意某些数据包的丢失,可以选使用 UDP 协议
3. 此时此刻的视频面试用的 UDP 还是 TCP?UDP丢包会有什么现象?#
我觉得是UDP协议,因为视频会议这个场景下,重要的是实时性,UDP协议实时性比TCP好,采用UDP协议传输音视频数据的话,如果发生了丢包,只是就丢失某一瞬间的画面和语音,然后还可以继续进行会议沟通,不会太影响视频会议的体验,如果是采用 TCP 协议的,由于 TCP 是可靠传输,如果发生了丢包,可能画面就卡住不动,等丢包重传才会推进画面,这样实时性就比较差了。
4. UDP 怎么改造变为可靠传输?#
序列号字段,确认号,超时重传机 流量控制,拥塞控制
5. TCP 和 UDP 可以共用一个端口吗?#
可以的。
socket 是根据五元组信息唯一确认的:协议类型、源 ip 地址、源端口、目标 ip地址、目标端口,只要有一个信息不同,就会认为是不同的 socket,不会引起冲突,所以TCP和UDP是可以共用一个端口号的。
TCP 可靠性(重要)#
1. TCP 是如何保证可靠性的?#
- 连接建立
- 序列号与确认应答
- 超时重传
- 滑动窗口机制
- 拥塞控制方面
2. TCP流量控制和拥塞控制的区别?#
流量控制:这是一个端到端的控制机制,目的是防止发送方发送的数据过快,导致接收方处理不过来。这通过滑动窗口机制实现,接收方在ACK报文中告诉发送方自己的接收窗口大小,这样就告诉了发送方可接收的最大数据量。
拥塞控制:这是一个网络层面的控制机制,目的是防止过多的数据包同时在网络中传输,导致网络拥塞。主要是通过慢启动、拥塞避免、拥塞发生,快速重传和快速恢复,这几种算法实现的。
3. 滑动窗口怎么设计的?解决什么问题?#
发送方和接收方在内核各自都有一个缓冲区,发送缓冲区和接收缓冲区上都各有一个窗口,发送方的窗口表示可发送的最大数据量,接收方的窗口表示可接收的最大数据量。
发送方有了发送窗口后,那么发送方可以不用等待已发送数据的确认报文,就可以继续发送下一批数据,提高了发送的速率。
接收方有了接收窗口后,可以实现流量控制,把接收方的接收窗口告诉给发送方,让发送方按自己的接收情况来发送数据,避免发送方发送的数据过快,导致接收方处理不过来。
4. TCP 协议拥塞控制是怎么实现的?#

慢启动:指数方式增长 拥塞避免:线性方式增长
拥塞发生:随着发送速率慢慢增长,可能网络会出现拥塞,发生了数据包丢失,这时候就需要重传数据,重传机制主要有两种,一个是超时重传和快速重传。
- 超时重传:当发生了超时重传,慢启动门限会设置为拥塞窗口的一半,并且将拥塞窗口恢复为初始值,接着,就重新开始慢启动,发送速率就会瞬间下降了很多。
- 快速重传和快速恢复:收到 3 个重复 ACK 后立即重传丢失报文,然后慢启动门限设置为减少后的拥塞窗口大小,丢包后窗口减半而非降到 1,随后直接进入拥塞避免
5. TCP的延迟应答和累计应答是什么?#
TCP的延迟应答是指接收方不立即发送ACK确认接收到的数据,而是延迟一段时间后再发送ACK。这样可以等待是否有更多的数据要发送,从而减少ACK报文的数量,提高网络利用率。
TCP的累计应答是指接收方可以一次性确认接收到多个连续的数据包,而不是每收到一个数据包就发送一个ACK。这样可以减少ACK报文的数量,提高网络效率。
TCP 场景#
1. TCP 拆包沾包原因是什么?怎么解决?#
如果发送的数据包超过 MSS 大小或者接收窗口大小后,会被拆分多个 TCP 段发送,这时候站在应用层的角度,就是一个完整的数据包被拆开了。 如果发送的数据包太小,TCP 还有一个 Nagle算法,会把多个小数据包堆积成一个 TCP 段发送,这时候就会感觉数据包是粘合一起发送的。 固定消息长度的方式、特定分隔符的方式、消息长度 + 消息内容的方式
2. TCP 的 keepalive 了解吗?说一说它和 HTTP 的 keepalive 的区别?#
HTTP 的 Keep-Alive 是叫 HTTP 长连接,该功能是由应用程序实现的,可以使得用同一个 TCP 连接来发送和接收多个 HTTP 请求和应答,减少了 HTTP 短连接带来的多次 TCP 连接建立和释放的开销。
TCP 的 Keepalive 是叫 TCP 保活机制,该功能是由内核实现的,当客户端和服务端双方长达一定时间没有进行数据交互时,内核为了确保该连接是否还有效,就会发送探测报文,来检测对方是否还在线,然后来决定是否要关闭该连接。
3. MTU是啥? MSS是啥?#
MTU是一个网络包的最大长度,一般是 1500 字节,MSS是除去IP包和TCP包的数据的最大长度,IP层如果超过MTU大小就会分片,TCP如果有超过MSS的应用数据就要分段
4. IP层会分片,为什么TCP层还需要MSS呢#
如果交给IP来进行分片,如果某一个 IP 分片丢失了,整个 IP 报文的所有分片都得重传。因为 IP 层本身没有超时重传机制,它由传输层的 TCP 来负责超时和重传。
当某一个 IP 分片丢失后,接收方的 IP 层就无法组装成一个完整的 TCP 报文(头部 + 数据),也就无法将数据报文送到 TCP 层,所以接收方不会响应 ACK 给发送方,因为发送方迟迟收不到 ACK 确认报文,所以会触发超时重传,就会重发整个 TCP 报文(头部 + 数据)。
应用层的数据在 TCP 层经过 MSS 分片之后,每一个分片都具备 TCP 头部信息,这样经过 MSS 分片后的报文,如果某一个丢失了,只需要重传这一个丢失的 TCP 报文就可以了,而不用重传所有的分片,大大增加了重传的效率。
5. 一个服务端进程最多可以建立多少条 TCP 连接?#
对于有1个IP的客户端来说,受限于ip_local_port_range参数,也受限于65535。但单机Linux可以配置多个ip,有几个ip,最大理论值就翻几倍。
6. 一个机器最多可以建立多少条 TCP 连接?#
理论上最大可以建立的 TCP 连接数等于客户端IP数 x 客户端端口数 x 服务端端口数
7. 如果已经建立了连接,但是服务端突然出现断电了会发生什么?#
如果客户端接下来会发送数据,那么由于服务端断电了,客户端已发送的数据就没办法得到确认,于是就会发生超时重传,重传次数达到上限之后,客户端就会断开 TCP 连接了。
8. 如果已经建立了连接,但是服务端的进程崩溃会发生什么?#
服务端进程崩溃的话,内核会负责回收服务端进程的资源,会发送 FIN 报文,和客户端进行四次挥手断开连接。
9. TCP 中 SYN 洪水是什么?如何防止?#
SYN 洪水攻击就是攻击者伪造大量不同 IP 地址的 SYN 报文发送给服务端,服务端每收到 SYN 报文后,会把还没完成连接建立的 socket,存放在 tcp 半连接队列,然后响应 syn-ack 报文,但是这些 IP 地址都是不存在的,这样服务端就无法收到第三次握手,这样就会导致 tcp 半连接队列被占满了,占满后,服务端就无法再建立 tcp 连接了,不能给正常的用户提供服务了。
解决的方式话,我觉得最好的是开启 tcp 的 syn cookie 机制,它可以在服务端第二次握手的时候,生成一个伪随机的序列号,用于验证客户端的SYN包。只有在客户端回应服务器的ACK包时,服务器才会分配资源,所以可以在不使用 SYN 半连接队列的情况下成功建立连接,相当于绕过了 SYN 半连接来建立连接。
其次的话,可以通过调整内核参数来增大半连接队列的大小,以及减少 syn+ack 重传的次数来避免 SYN 洪水攻击。
