计算机网络核心面试知识深入解析

0 阅读10分钟

一、HTTPS建立连接的过程

image.png

证书申请阶段(前置准备)

在正式建立连接前,服务器需要向证书机构(CA)申请SSL证书:

  • 服务器将自己的公钥发给CA机构
  • CA机构用自己的私钥对服务器的公钥进行加密,生成SSL证书
  • 服务器存储SSL证书,供后续安全连接使用

image.png

连接建立详细流程

第1步:TCP三次握手 客户端与服务器先建立TCP连接(这是HTTPS的基础)

第2步:服务器发送SSL证书 服务器将SSL证书发送给客户端,证书包含:

  • 证书的发布机构(CA)
  • 证书的有效期
  • 服务器的公钥
  • 证书所有者
  • 数字签名

第3步:客户端验证证书(以浏览器为例)

  1. 浏览器检查证书所有者、有效期等基本信息
  2. 查找操作系统中内置的受信任CA证书,比对颁发者
  3. 如果找不到,浏览器报错(证书不可信)
  4. 如果找到,用CA的公钥解密证书中的签名
  5. 用相同hash算法计算证书hash值,与解密后的签名对比
  6. 一致则证明证书合法,读取公钥用于后续加密

为什么需要CA?

假设没有CA,可能发生中间人攻击:

正常流程:服务器公钥 → 客户端
被攻击:服务器公钥被hack截获 → hack将自己的公钥发给客户端 → 客户端用hack公钥加密数据 → hack解密获取数据 → hack用服务器公钥加密转发

有了CA后,客户端内置的CA根证书能识别出hack的证书不合法,有效防止中间人攻击。


二、HTTP的缓存策略是怎么样的?

image.png HTTP缓存主要分为强缓存对比缓存两种,优先级:强缓存 > 对比缓存

强缓存

浏览器直接从本地缓存读取数据,不再向服务器发送请求

image.png 实现字段:

  • Expires:缓存到期时间(绝对时间,服务器时间+缓存有效期)
    • 缺点:客户端修改本地时间会导致缓存失效;本地时间与服务器时间不一致也会失效
  • Cache-Control:缓存最大有效时间(相对时间)
    • 优点:即使本地时间与服务器不一致,也不会导致缓存失效
    • 常用取值:
      • max-age:最大有效时间(秒)
      • no-cache:没有缓存
      • s-maxage:同max-age,仅用于共享缓存(如CDN)
      • public:多用户共享缓存(默认)
      • private:不能多用户共享

对比缓存

先向服务器发送请求,带上缓存标识,由服务器判断是否使用缓存

Last-Modified/If-Modified-Since

  • 响应头返回Last-Modified(资源最后修改时间)
  • 请求头带上If-Modified-Since(上次获取的修改时间)
  • 服务器判断资源是否更新:
    • 有更新:返回新资源(状态码200)
    • 无更新:返回304,浏览器使用缓存

缺点:

  1. 只能精确到秒级,1秒内多次修改无法准确标识
  2. 内容未变但修改时间改变,导致缓存失效

Etag/If-None-Match

  • 响应头返回Etag(资源版本号)
  • 请求头带上If-None-Match(上次的版本号)
  • 服务器对比版本号决定返回200还是304

缓存优先级

强缓存(Cache-Control) > 强缓存(Expires) > 对比缓存(Etag) > 对比缓存(Last-Modified)


三、TCP三次握手和四次挥手是怎么样的?

三次握手(建立连接)

客户端         服务端
  |----SYN---->|
  |<--SYN+ACK--|
  |----ACK---->|

详细流程:

  1. 客户端发SYN:生成随机数J作为序号,发送SYN包(seq=J),进入SYN_SENT状态
  2. 服务端回应SYN+ACK:进入SYN_RECV状态,发送SYN包(ACK=1,ack=J+1,seq=K)
  3. 客户端发ACK:检查ACK=1且ack=J+1,发送ACK包(ACK=1,ack=K+1)
  4. 双方进入ESTABLISHED状态,连接建立成功

四次挥手(断开连接)

客户端         服务端
  |----FIN---->|  客户端→服务端断开
  |<---ACK-----|  服务端确认
  |<---FIN-----|  服务端→客户端断开
  |----ACK---->|  客户端确认

详细流程:

  1. 客户端发FIN:发送FIN包(seq=J),进入FIN_WAIT_1,表示客户端无数据发送
  2. 服务端回ACK:发送ACK包(ack=J+1),进入CLOSE_WAIT,客户端收到后进入FIN_WAIT_2
  3. 服务端发FIN:服务端无数据后,发送FIN包,进入LAST_ACK
  4. 客户端回ACK:发送ACK包,进入TIME_WAIT,超时后自动关闭;服务端收到ACK后进入CLOSE

TIME_WAIT的意义:如果ACK包丢失,服务端会重发FIN,客户端可以在TIME_WAIT状态下重发ACK。


四、TCP怎么保证可靠性的?

TCP通过多种机制共同保障可靠性:

1. 校验和

将数据切分成16位二进制串,求和得到校验和。接收方用相同算法计算,对比校验和是否一致,防止数据损坏。

2. 序列号/确认应答 + 超时重传

  • 每个数据包都有序号
  • 接收方收到数据返回ACK确认
  • 超过超时时间未收到ACK,触发超时重传
  • 超时时间动态变化:初始值>正常往返时间,重传失败则指数增加
  • Linux中以500ms为单位,重传超时依次为500ms、2500ms、4500ms...
  • 重传次数累计到阈值后,关闭连接

3. 最大消息长度(MSS)

建立连接时双方约定MSS作为发送单位,理想情况下刚好不被网络层分块。

4. 滑动窗口控制

发送方不需要等待每个包的确认,只要包在滑动窗口内就可以发送。每收到一个确认应答,窗口向后移动一位。

5. 流量控制

接收方根据缓冲区情况,动态调整滑动窗口大小,通知发送方调整发送速率,防止接收方缓冲区溢出。


五、TCP拥塞控制怎么实现?

拥塞控制由四个算法组成:慢启动、拥塞避免、拥塞发生时算法、快速恢复

1. 慢启动

  • 连接刚建立时,拥塞窗口cwnd初始为1
  • 每收到一个ACK确认,cwnd+1
  • 每个往返时延RTT,窗口大小翻倍(指数增长)
  • 目的:试探网络承受能力

2. 拥塞避免

  • 当cwnd达到慢启动阈值ssthresh时,停止指数增长
  • 进入线性增长:每个RTT,cwnd+1
  • 目的:避免超过网络承载能力导致拥塞

3. 拥塞发生时算法

判定拥塞的依据(丢包):

  • 超时重传:超过RTO未收到ACK
  • 三个重复ACK:收到3个以上相同的ACK(如连续收到3个ACK=2,说明包3丢失)

处理方式:

  • 将ssthresh设置为当前窗口大小的一半
  • 判定拥塞后触发快速恢复

补充:快重传 收到失序报文时,接收方立即返回已收到的最新序号ACK(如收到包4但没收到包3,仍返回ACK=2)。连续3个重复ACK触发发送方快速重传丢失的包。

4. 快速恢复算法

  • TCP Tahoe(早期算法):cwnd重置为1,重新慢启动
  • TCP Reno(现在常用):cwnd设置为新的ssthresh,进入拥塞避免(线性增长)

六、close_wait太多怎么处理?

close_wait产生原因

四次挥手中,服务端返回ACK应答后,如果还有数据要发给客户端,会进入close_wait状态。如果被动关闭方没有及时发出FIN包,就会一直停留在close_wait状态。

解决方案

可以调整TCP空闲连接存活时间:

tcp_keepalive_time = 7200  # 默认2小时,可调小

time_wait太多的问题及处理

产生原因:高并发短连接场景下,主动关闭方进入TIME_WAIT状态,端口资源(0-65535)有限,持续高并发会导致端口耗尽。

解决方案(修改系统配置):

net.ipv4.tcp_syncookies = 1      # 开启SYN Cookies,防范SYN攻击
net.ipv4.tcp_tw_reuse = 1         # 允许TIME-WAIT sockets重新用于新连接
net.ipv4.tcp_tw_recycle = 1       # 开启TIME-WAIT sockets快速回收
net.ipv4.tcp_fin_timeout = 30     # 修改默认TIMEOUT时间

HTTP/2 有哪些新特性?

1. 二进制传输

  • 采用二进制格式传输数据,而非HTTP/1.x的纯文本
  • 协议解析更高效
  • 将请求和响应数据分割为更小的帧,二进制编码
  • 同域名下所有通信在单个连接上完成,承载任意数量双向数据流

2. Header压缩(HPACK算法)

  • 客户端和服务器建立"字典",用索引号表示重复字符串
  • 采用哈夫曼编码压缩整数和字符串,压缩率达50%-90%
  • 首部表在连接存续期内始终存在,渐进更新
  • 新请求只需发送差异数据,减少冗余

3. 多路复用

  • 解决浏览器对同域名请求数量的限制
  • 更容易实现全速传输
  • 避免了TCP连接的慢启动过程

4. Server Push(服务器推送)

  • 服务器可主动向客户端发送消息
  • 例如:浏览器请求HTML时,服务器提前推送可能用到的JS、CSS文件
  • 减少等待延迟

5. 提高安全性

  • 虽然不强制加密,但主流浏览器只支持加密的HTTP/2
  • 实际应用的HTTP/2都是加密的
  • 协议标识:"h2"表示加密,"h2c"表示明文

HTTP报文结构是怎么样的?

请求报文结构

请求行 + 请求头 + 空行 + 请求内容

请求行:请求方法 + URL + 协议版本(空格分隔)

  • 请求方法:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT

请求头:key/value对,每行一对,冒号分隔

  • User-Agent:浏览器类型
  • Accept:可识别的响应内容类型
  • Accept-Language:可接受的自然语言
  • Host:请求的主机名
  • Connection:连接方式(close或keepalive)
  • Cookie:客户端扩展字段

空行:标识请求头结束

请求内容:POST请求的body,配合Content-Type和Content-Length使用

响应报文结构

状态行 + 响应头 + 空行 + 响应内容

状态行:HTTP协议版本 + 状态码 + 状态描述(空格分隔)

  • 1xx:接收请求,继续处理
  • 2xx:成功处理
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

常见状态码

  • 200 OK:请求成功
  • 304 Not Modified:资源未修改,可使用缓存
  • 400 Bad Request:请求语法错误
  • 401 Unauthorized:未经授权
  • 404 Not Found:资源不存在
  • 500 Internal Server Error:服务器内部错误
  • 503 Service Unavailable:服务不可用

响应头

  • Location:重定向位置
  • Server:服务器软件信息
  • Vary:不可缓存请求头列表
  • Connection:连接方式
  • Keep-Alive:保持连接时间

空行:标识响应头结束

响应内容:服务器返回的文本信息


HTTP状态码502,503,504各自代表着什么?

502 Bad Gateway

  • 含义:网关(一般是Nginx)从后端服务器接收到无效响应
  • 常见原因:后端服务器挂了、服务崩溃、无法响应
  • 示例:后端Java应用进程突然退出

503 Service Unavailable

  • 含义:服务不可用,请求过载
  • 常见原因:请求超过Nginx限流设置的阈值
  • 示例:服务器配置了每秒最多处理100个请求,超过则返回503

504 Gateway Timeout

  • 含义:网关(一般是Nginx)从后端服务器接收响应超时
  • 常见原因:后端处理时间过长,超过Nginx等待时间
  • 示例:Nginx配置了60秒超时,但后端接口处理需要90秒