跳到主要内容

网络✅

TCP 与 UDP 的区别,Node.js 分别如何使用?

答案

核心概念:

  • TCP 面向连接、可靠有序、字节流,拥塞/重传/流控完善,适合大多数 Web/长连接
  • UDP 无连接、报文为边界、不保证到达与顺序,时延小,适合实时音视频、DNS、广播/组播
  • TCP 需自行处理“粘包/拆包”(应用层定长/分隔符/长度头);UDP 天然保留消息边界但可能丢包

延伸阅读:

为什么以及如何正确使用 HTTP Keep-Alive 与 Agent 连接复用?

答案

核心概念:

  • HTTP/1.1 默认 Keep-Alive,复用 TCP 连接显著降低握手与 TLS 成本
  • Node 的 Agent 是连接池:复用、并发上限(maxSockets)、空闲回收(keepAliveMsecs/maxFreeSockets)
  • 客户端/服务端都应允许 Keep-Alive;错误地禁用或滥开连接会导致 TIME_WAIT/资源耗尽

示例说明:

提示

代理/负载均衡场景注意传递并尊重 Connection/Keep-Alive 与 X-Forwarded-*;HTTP/2 多路复用可进一步减少连接数。

面试官视角:

  • 要点清单:Agent 的作用与关键参数;Keep-Alive 的收益与风险;与 HTTP/2 的关系
  • 加分项:TLS 会话复用/ALPN;TIME_WAIT 风险与服务端端口耗尽排查
  • 常见失误:关闭 Agent(agent:false)导致连接风暴;无节制提升 maxSockets

延伸阅读:

Node.js 中 DNS 解析:dns.lookup 与 dns.resolve 有何区别?

答案
  • dns.lookup 走系统解析器(getaddrinfo),遵循 hosts/本机缓存,默认返回单个地址;在 libuv 线程池执行
  • dns.resolve 直接发 DNS 查询到权威/递归服务器,返回指定记录类型的完整结果,不走系统缓存
  • 生产实践:优先 http/https 客户端使用默认解析;若需精确控制记录/权威结果,用 resolve/resolve4/6/TXT/SRV

示例说明:

面试官视角:

  • 要点清单:数据来源差异;线程池行为;记录类型控制;IPv4/IPv6 选择
  • 加分项:线程池耗尽风险(大量 DNS 查询);TTL/自建缓存;dns.setServers 的副作用
  • 常见失误:误以为 lookup 使用 DNS 服务器;忽略 hosts;未设置 family 导致 IPv6 连接失败

延伸阅读:

什么是 Nagle 算法与延迟确认,何时需要 setNoDelay(true)?

答案
  • Nagle 算法合并小包降低报文数;Delayed ACK 延迟确认以减少 ACK 数量,两者在交互式小包下可能引入额外延迟
  • 对低延迟的小消息交互(RPC、IM 协议头/心跳)可考虑 socket.setNoDelay(true);大吞吐场景默认即可
  • Node 还提供 socket.cork/uncork 以应用层合并多次 write,再一次性发送

示例说明:

延伸阅读:

Socket/HTTP 流的背压如何处理?有哪些限流策略?

答案
  • Writable.write 返回 false 表示下游缓冲已满,应等待 'drain' 继续写;Readable 可用 pause/resume 或 pipeline
  • highWaterMark 控制内部缓冲阈值;合理设置有助于内存稳定与吞吐/延迟平衡
  • 限流常见手段:基于字节/请求数的漏桶/令牌桶、应用层节流、排队与超时

示例说明:

延伸阅读:

如何实现最小可用的 HTTPS 与 HTTP/2 服务?

答案
  • HTTPS 是 HTTP over TLS,需要证书(key/cert);SNI 支持多域名,ALPN 协商 H2/H1
  • HTTP/2 基于二进制帧与多路复用、首部压缩(HPACK),可在同一连接并发请求
  • 生产常在边缘层(Nginx/Envoy/ALB)终止 TLS,再回源 H2/H1;Node 原生也可直挂

示例说明:

// HTTPS
const https = require('node:https')
const fs = require('node:fs')
const creds = { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') }
https.createServer(creds, (req, res) => res.end('hello tls')).listen(3443)

// HTTP/2(ALPN,可回退 H1)
const http2 = require('node:http2')
http2.createSecureServer({ ...creds, allowHTTP1: true }, (req, res) => {
res.stream.respond({ ':status': 200, 'content-type': 'text/plain' })
res.stream.end('hello h2')
}).listen(3444)

延伸阅读: