小笔记(http/网络 篇)

95 阅读8分钟

笔记打算记录,自己整理好的面试题,
争取保持准确性和专业性,然后用直白的语言描述出来,
希望能做成一个API文档,让我日后翻到能直接对着复习就好,
如果也能帮助到你就最好了(我会不定时的更新的)

描述一下 http(1.0 / 1.1 / 2.0)之间的差异

  • http1.0

浏览器和服务器之间保持短连接,每次请求都新建立一个 tcp链接,完成后就断开。(如需保持长连接,需手动在请求头增加 connent: keep-alive)。 1.0有强缓存的概念(expirescache-control),当同时出现时,cache-control 的优先级会较高

表示当前资源文件具体可以缓存多久,常规的单位是:具体的日期或者 多少天(10d)。如果资源文件在缓存时间内,返回 200 的http状态码。(如出现客户端的时间与服务端的时间不同步时,会导致缓存失效)

经常配合 max-age=second 使用,表示缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒),该时间是指资源文件,在客户端请求前后的时间差(与服务器无关)。在设定的时间内,资源文件返回 200 的http状态码。

  • 当设置了 no-cache 时,就会触发http新版本协商缓存的逻辑
  • 当设置了 no-store 则表示该文件不进行缓存。
  • http1.1
  1. 默认支持 keep-alive 的长连接,不需要用户手动添加 connect 字段
  2. 加入了协商缓存的字段:last-modifyetag
  3. 加入新的请求方法: optionsputdelete
  4. 请求头中增加了 host 字段

keep-alive 的基础上延伸出,允许在一个 tcp连接上,并发多个 http请求(多路复用),但是后端服务仍有排队的概念(请求堵塞),请求结果会按并发的顺序逐一返回。在 chrome 中,一个 host 最多可以打开 6个 tcp连接

协商缓存,结合请求头If-Modified-Since一起使用,记录文件的修改时间(精度比 etag 低),返回 304 的 http状态码

结合请求头 If-match 使用,记录的是文件的 hash值,返回 304 的 http状态码

  • http2.0
  1. 多路复用(在 1.1 的基础上,返回结果无需按顺序返回,减少排队阻塞问题)
  2. 请求报文支持 二进制 的模式(支持格式:文本 / 二进制)
  3. 允许服务器主动推送的模式(只支持静态资源文件的推送)
  4. 加入了头部报文压缩的概念(HPACK)

因老版本 http 每个请求都将完整的头部报文进行传输,导致带宽浪费。新版本为了优化请求的体积,提出了报文压缩概念(HPACK)。实现的原理是在客户端和服务端之间,建立一个静态字典(保存:常规头字段)和动态字典(保存:新发现的内容),使用 Huffman编码 的模式(一段请求头信息使用一个字符来表示),在后续请求中.当匹配到相同的内容,则用 1个字符 进行传输,实现体积压缩。

http 和 https的区别

httphttps
端口80443
协议httphttps
数据使用TLS/SSL证书加密明文(不加密)
证书CA证书无证书
连接无状态 + 加密证书无状态

TCP/SSL证书,是在传统的 TCP请求 建立后(三次握手),进行http请求前的一层加密操作

https加密属于非对称加密

  1. 客户端发起请求(传输包括:客户端随机数、支持的加密方法)
  2. 服务端server响应请求(传输包括:服务端随机数、确认的加密方法、安全证书)证书包括:公钥
  3. 客户端验证证书,再生成一个随机数,使用公钥加密(加密成只能用私钥进行解密)
  4. 服务端server收到加密随机数,使用私钥进行解密(获得新的随机数
  5. 2端将3个随机数(客户端随机数、服务端随机数、经过加密解密验证的新随机数)进行哈希加密(SHA-256)最终得出新的密钥
  6. 后续的数据传输就使用 新的密钥 进行加密

(完成了公钥加密、私钥解密的步骤,此时安全连接算是已经建立)

如果 https 访问 http 的资源,需要怎么做?

正常直接访问,浏览器是会提示安全错误的,如果要跳过此拦截,可以有以下的操作:

  1. 资源不写协议信息,直接访问资源由浏览器自己补充
  2. http资源加上请求头 Content-Security-Policy: upgrade-insecure-requests

常见 http 状态码

  • 200:表示OK
  • 204:表示 no content(常见于请求成功,但是后端response为空)
  • 302:重定向,重定向的URL为response中的location信息(临时重定向,永久的为 301)
  • 304:有协商缓存
  • 401:unauthorized(常见未鉴权,指无系统权限)
  • 403:forbidden(通过了系统鉴权,但是无具体页面或功能操作权限)
  • 404:资源未找到
  • 405:常见于请求方法不正确(method not allow)
  • 502:后端服务异常(bad gateway)
  • 504:后端网关超时

nginx 的理解

server部分,定义主机相关的配置,一个nginx实例允许有多个 server块。(简单的多个场景就是维护http和https)

  • 端口号
  • 主机名

location部分,常用语定义 URL路径的匹配规则

  • 路径匹配规则:/path、支持简单字符串匹配或者正则匹配
  • 代理设置:proxy
  • 缓存设置

upstream部分,通常用于定义负载均衡配置

# 像定义变量一样,将一组服务器地址维护在一起,访问相关域名时,nginx自动进行转发
upstream backend { 
  server backend1.example.com; 
  server backend2.example.com; 
  server backend3.example.com; 
}

server { 
  listen 80; 
  location / { 
    # 使用上面定义的 upstream 
    proxy_pass http://backend; 
  } 
}

TCP 和 UDP 的理解

TCP协议(运用于需要可靠传输的场景:http协议)

优点缺点
有链接、可靠性高建立联系需要通过三次握手,开销较大
数据传输有先后顺序(保证完整性)延迟高
有流量控制、排队阻塞控制不适合实时要求高的场景
超时、丢失会自动重传
1对1全双工(支持客户端和服务端数据互传)

UDP协议(运用于实时性强、能容忍丢包的场景:在线视频、游戏、DNS查询)

关键:UDP 不是用在“不能丢包”的场景,而是用在“可以容忍偶尔丢包,但不能容忍延迟”的场景。

优点缺点
无连接、速度快不保证数据能送达,存在丢包风险(通信不用建立连接)
支持广播、实时性强的业务场景无流量控制、容易造成堵塞、超时不会重传
支持1对多、多对多

DNS(域名解析),为什么使用UDP协议做查询?

  1. 查询数量小、请求速度非常快
  2. 丢了马上重发请求

websocket 和 传统长轮询的区别

websocket

优点:

  • 客户端和服务端的双向通信
  • 持久性的连接,能够保持实时性

缺点:

  • 老旧浏览器不支持 ws
  • 服务端需要改造,需要支持ws协议

长轮询

优点:

  • 兼容性好
  • 实现难度小,不需要后端配合改造,复杂度低

缺点:

  • 存在延迟性
  • 频繁发送请求,存在加大服务器负载的风险

service worker的理解

serviceWorker是可以运行在浏览器后台的js脚本,与页面的DOM元素分离,独立的一个线程。主要作用是当网络环境不稳定时,仍然可以提供服务

serviceWorker可以将所有的HTTP请求的response存入缓存中,HTTP请求的响应可以是:静态资源文件、图片、视频、js代码等。通过使用 cache storage进行存储。

serviceWorker 可以带来什么:

  1. 可以对所有请求进行拦截,并进行对应的处理。(请求访问的顺序:①serviceWorker、②缓存、③正常请求)
  2. 离线支持,因serviceWorker的缓存机制,使得离线时仍可返回缓存的内容
  3. 后台同步,缓存数据(离线保存),当恢复网络时将自动进行同步
  4. 提高性能,因缓存机制,减少带宽消耗

如何实例化一个 serviceWorker:

image.png

// 先创建一个独立的 js文件,里面写入 service-worker的钩子函数
self.addEventListener('install', (event) => {
  console.log('Service Worker installing.');
});

self.addEventListener('activate', (event) => {
  console.log('Service Worker activating.');
});

self.addEventListener('fetch', (event) => {
  console.log('Fetching:', event.request.url);
  // 可拦截请求,做缓存、离线处理等
});

// 在 main.js中 根据路径注册 service-worker
navigator.serviceWorker.register('/service-worker.js')

浏览器输入URL的过程

  1. URL字符串解析(解析后进行DNS解析
  2. DNS解析的过程是为了获取URL对应的 service ip地址(如果URL是CDN服务,返回CNAME
  3. 与ip地址建立 tcp链接
  4. tcp建立后发起 http请求
  5. 服务端对请求进行处理,返回所需的资源文件
  6. 获取资源文件(htmljscss ... )
  7. 解析文件呈现页面

浏览器解析静态文件转换为可展示页面的过程理解

  1. 生成 DOM树