[TOC]
1.1. 计算机网络
1.1.1. 计算机网络历史
ARPAnet
封包(pack-switching)

- 1969年
第一个RFC(request-for-comment)
第一个接口信息处理单元(Interface-Message-Processor)(路由器的前身)
互联网Internet
- 1971年
第一个email(ARPAnet)也是世界上第一个网络
ALOHAnet 第一个wi-fi(Wireless Fidelity)
- 1973年
Ethernet (局域网的前身)
SATNET (卫星网络)
IP电话/互联网电话(VOIP)(第一个给用户使用的电话在1995年)
- 1974年
路由器(施乐Xerox)
- 1976年
第一个IP路由器,但是被称作网关(Gateway)
- 1978年
Bob Kahn发明了TCP/IP协议
- 1981年
Internet protocol Version 4,RCF 791
BITnet
CSnet
- 1983年
ARPAnet迁移到TCP/IP协议
DNS(Domain Name System)
1986年
- 1988年
WaveLan(WI-FI)
Packet filter wall(第一个防火墙Paper)
APAPnet
1990年 第一个交换机(Kalpana)
1996年 IPv6
1997年 802.11 wifi标准(2mbps)
- 1999年
802.11a(5GHz 25mbps)、802.11b标准(11mbps)
WEP加密协议(RC4对称加密+CRC-32)
- 2000s
802.11g标准(54mbps)
WPA加密协议
WPA2加密协议
4G标准(100Mbps)
802.11n标准(600mbps)
- 现在
移动互联网、5G、边缘计算、云、物联网、VR
1.1.2. OSI七层模型
OSI模型简介
(ISO/IEC 7498-1)
开放式系统互联模型
世界范围内的网络标准概念模型
OSI的努力让互联网协议走向标准化
国际标准化组织(ISO)
始于欧洲,发扬于美国,中国获利
应用层(Application Layeer)
提供高级API
定义了网络主机提供的方法和接口(业务协议),往往直接对应用户行为,例如:HTTP、FTP、SMTP等
展示层(Presentation Layer)
也被称作语法层,将应用层中的数据转化为传输格式,保留语义(序列化、加密解密、字符串编码解码);确保数据发送出去后可以被接收者理解。
会话层(Session Layer)
提供管理会话的方法(Open/Close/ReOpen/检查状态等),提供对底层连续断断续续的隐藏,甚至对多种底层流的隐藏,保证上层看不到细节
传输层(Transport Layer)
提供主机到主机(host-to-host)的数据通信能力
建立简介保证数据封包发送、接收到的顺序一致;提供可靠性(发送者知道数据有没有被完整送达);提供流控制(同步发送者和接受者的速率);提供多路复用(「多工」,Multiplexing,多种信号复用一个信道)

网络层(Network Layer)
提供数据在逻辑单元(IP地址)之间的传递能力
「路由」:决定数据的下一站在哪里;「寻址」:为数据封包增加头信息(地址等)
数据链路层(Data Link Layer)
提供数据在设别和设备间的传输能力
「流控制」:发送者接受者之间同步数据首发速度和数据量,「错误控制」:检测数据有没有出错,并重发出错的信息
物理层(Physical Layer)
定义底层一个个位(bit)的数据如何变成物理信号
数据链路层发生的数据传递行为转化为物理设备识别的信号(电流);封装了大量底层物理设备的能力
实际应用
- Alice想Bob发微信
Alice提交的输入被微信存储成某种内部协议格式——「应用层」
数据被转化为传输用的格式(如加密、压缩等)——「表示层」
微信客户端建立起与服务器的连接(也可能已经建立好了)「会话层」
微信客户端向服务器传输数据——「传输层」
一个个数据封包从主机传输到服务器——「网络层」
数据帧在一个个设备之间传输——「数据链路层」
数据最终以光电信号的形式在物理设备间传输——「物理层」
深入思考OSI

分层架构
替换其中一层不用重构整个应用(比如换了一家快递,我依然可以把快递送到目标地址)
- 必要性/独立性/可替换
- 层的颗粒度
- 数据可追踪性
1.1.3. 网络协议
TCP/IP协议和互联网
TCP/IP协议群(Internet Protocol Suite)
类似OSI模型,一种网络协议的概念模型

传输层(Transport Layer)
提供主机到主机的通信能力,通过TCP/UDP协议
还有主机端口(浏览器默认80端口)
网络层(Internet Layer)
提供地址到地址的通信能力,通过IP协议
链路层(Link Layer)
提供设备到设备的通信能力,Mac地址到Mac地址
什么是设备、地址、应用?
分别对应链路层、网络层、传输层
设备:MAC;地址:IP;应用:端口
TCP/IP封包
各层之间的数据转换

TCP/IP的封包
(网络层)通过IP协议在进行一次数据的封装加上IP的header,称为IP协议的封包

完整的TCP协议头

tcp的header相当于一个说明书,后边跟着一段段的数据,header来指明数据的类型,编码的格式,原地址,目标地址等信息
这样就形成了一个TCP协议的封包(传输层)

每个封包称作一个TCP信息段(TCP Segment)
Header用户描述传输行为
- Header后边跟着若干个byte数据,每个byte拥有自己的序列号
三次握手
syn 请求同步
syn-ack 请求并确认
ack 确认

数据顺序问题
TCP/IP的处理方法:
消息的绝对顺序用(SEQ,ACK)这一对元组描述,这个元组就保存在TCP的header中
SEQ(Sequence):这个消息发送前一共发送了多少字节
ACK(Acknowledge):这个消息发送前一共收到了多少个字节

四次挥手
在断开连接的时候,每一端都要发送Finish和Ackonwledge,在接收完断开之前的信息之后再发送Ackownledge

总结
「最简化原则」:没有足够的事情要做,就不必分层
为什么需要三次握手?四次挥手?
网络中的顺序问题,是通过(SEQ,ACK)这组绝对数据来解决的
DNS(重点)
DNS基础知识
URL:也被称作「网址」,用于定位互联网上的资源。由方案(协议)、域名(主机/IP地址)、端口(应用)、路径、查询、片段(给客户端使用)组成

DNS(Domain Name System):域名系统,将域名解析为IP地址。

「AA」 :Authoritative Answer 权威回答
- A记录
描述IPv4地址。其中IN(Internet)代表大部分网络
www.example.com. IN A 139.22.33.2
- AAAA记录
IPv6的记录
- CNAME记录(Canonical Name Record)
前者作为后者的别名记录下来
www.foo.com. IN CNAME example.com
- MX记录(Mail exchaner record)
定为邮件服务器
123@qq.com. IN MX qq.com
- NS记录(Name Server Record)
定义提供dns信息的服务器(A的子服务)
- SOA记录(Start of Authority Record)
定义在多个NS服务器中那个是主服务器
- TXT记录
微信提供文本信息,将其加入到我的域名之下,在请求微信的域名的时候带上文本可以证明我的域名身份。
DNS工具实战
本地host修改:Switchhost工具
CDN工具
CDN:内容分发网络(Content Delivery Network)

基于地理位置的分布式代理服务器/数据中心
- 提供高可用
- 提升性能
- 提升体验
中国的主干网络
- 中国联通
- 中国电信
- 中国移动
- 中国教育和科研计算机网
- 中国科技网
- 广电带宽(2018)
- ……
CDN实现原理

适用于静态资源,不经常变动。
修改CDN上的资源非常麻烦。
CDN云测平台
Http入门和基础工具
HTTP协议
超文本传输协议(Hyper Text Transfer Protocol)
处理客户端和服务端之间的通信,可以使用文本传输信息,而不是二进制。
http请求 - http返回
主要用于请求网页/json/提交表单/xml……
纯文本+无状态(stateless)
无状态,相对简单,每一个请求都是独立的,互相不影响
但是我们需要通过cookie,session等浏览器提供的手段维护状态
历史及设计优化
在网络协议设计中,带宽和延迟是非常重要的因素,和用户体验紧密联系;而延迟可以通过缓存、DNS查询等优化来降低
1991 HTTP 0.9
1996 HTTP 1.0
缓存
提供缓存机制如IF-Modified-Since等基础缓存控制策略
1999 HTTP 1.1
缓存优化
提供E-tag等高级缓存策略
带宽优化
利用长链接让多个请求在一个TCP连接上排队
利用range(范围)头获取文件的某个部分
2015 HTTP 2.0
带宽优化
利用多路复用技术同时传输多个请求
压缩/安全性
压缩
主流web服务器nginx/express都提供gzip压缩
http2.0采用二进制传输,头部使用HPACK算法压缩
HTTPS
在HHTTP和TCP/IP之间增加TSL/SSL层
数据传输加密(非对称和对称)
实战-实现简单http协议
http传输内容分为两部分Header和Body。
const net = require('net')
// 基础能力 发送数据 传输层=》网络层 =〉 连接层 =》 物理层,也就是可以操纵TCP协议
const response =
`HTTP/1.1 200 OK
Data: Tue, 30 Jun 2000 01:00:00 GMT
Content-Type: text/plain
Connection: Closed
Hello World
`
const server = net.createServer(socket => {
socket.end(response)
})
server.listen(80,()=>{
})
工具
cURL 命令行工具 ,可以请求url
它支持很多协议
fetch 在网络还是那个获取数据的标准接口
提供 请求/返回 标准Promise标准方法
提供自定义Header能力
提供跨域能力
postman 协作的API开发工具
Whistle 跨平台网络调试工具,抓包
需要SwitchOmega插件
nodejs开发
支持抓包、重放、替换、修改
charles同上
Http协议详情
前端重点、面试重点、日常常用
Http协议内容和方法
GET
从服务器获取资源
POST
在服务器创建资源
PUT
在服务器修改资源(幂等性)
DELETE
在服务器删除资源
OPTION
跨域
TRACE
显示调试信息,多数网站不支持
CONENECT
代理
PATCH
对资源进行部分更新(很少使用)
常见Http状态吗
1xx:提供信息
- 100 continue
- 101 切换协议(switch protocol)
2xx:
- 200 OK
- 201 Created 已创建
- 202 Accepted 已接受
- 203 Non Authoritative Information 非权威内容(中间的代理服务器修改过内容)
- 204 No Content 没有内容
- 205 Reset Content 重置内容
- 206 Partial Content 服务器下发了部分内容(range header)
3xx:重定向
- 300 Multiple Choices 用户请求了多个选项的资源(返回链接选项列表)
- 301 Moved Permanently 永久转移
- 302 Found 资源被找到(临时转移)
- 303 See Other 可以使用GET方法在另一个URL找到资源
- 304 Not Modified 没有修改(在缓存部分)
- 305 Use Proxy 需要代理
- 307 Temporary Redirect 临时重定向
- 308 Permanent Redirect 永久重定向
301 vs 308
资源被永久移动到新的地址
客户端收到308请求后,之前是什么method,那么之后也会沿用这个method到新地址
客户端收到301请求后,通常用户会想新地址发起GET请求
302 vs 303 vs 307
临时重定向,资源临时放到新地址
302时http1.0提出的,最早叫做Moved Temporarily;很多浏览器没有遵循标准,把所有请求都重定向为GET
1999年标准委员会增加了303/307,并将302重新定义为Found
303告诉客户端使用GET方法重定向资源
307告诉客户端使用原请求的method重定向资源
4xx:客户端错误
- 400 Bad Request 请求格式错误
- 401 Unauthorized 没有授权(跳登陆)
- 402 Payment Required 请先付费
- 403 Forbidden 禁止访问(没有权限)
- 404 Not Found 没有找到
- 405 Method Not Allowed 方法不被允许(只接受post 但是发送了get)
- 406 Not Acceptable 服务端可以提供的内容和客户端期待的不一样
5xx:服务器错误
- 500 Internal Server Error 内部服务器错误(崩掉了)
- 501 Not Implemented 没有实现(接口还未实现)
- 502 Bad Gateway 网关错误(网关给的)
- 503 Sevice Unavailable 服务不可用(线程池满了,内存用光了等)
- 504 Gateway Timeout 网关超时(网关给的)
- 505 HTTP Version Not Supported版本不支持(http2.0请求http1.0时)
常见Http头
Content-Length
发送给接收者的Body内容长度(字节)
一个字节byte是 8 bit
utf-8编码的字符是1-4个字节
User-Agent
帮助区分客户端特性的字符串
操作系统、浏览器类型、制造商、内核类型、版本号……
Content-Type
帮助区分资源的媒体类型(Media Type/MIME Type)
text/html、text/css、application/json、image/jpeg……
Origin
描述请求来源地址
scheme://host:port
不含路径,可以是null
Accept
建议服务端返回何种媒体类型(MIME Type)
/*代表所有类型
多个类型用逗号隔开text/html,text/css
Accept-Encoding
建议服务器发送那种编码(压缩算法)
gzip、deflate;q=1.0, *;q=0.5
;后的q是权重,来分开组别
Accept-Language
建议服务端传递哪种语言
fr-CH,fr;q=0.9,en;q=0.8,*;q=0.5
Referer
告诉服务端打开当前页面的上一张页面的URL;如果是ajax请求那么就告诉服务端发送请求的URL是什么
由于它会形成一条链,所以常用来分析用户行为
非浏览器环境有时候不发送Referer(或者爬虫来做虚拟Referer)
Connection
决定连接是否在当前事务完成后关闭
Http1.0默认是close
Http1.1后默认是keep-alive
全栈角度看Http协议
实践巩固、全栈应用、架构思想
Method和解析Body
跳转Header和3xx状态吗
认真对待3xx状态码
错误处理4xx和5xx
错误处理遵循协议约定
加密和Https证书
面试重点、前端重点、架构思想
对称加密和非对称加密
明文传输非常不安全,导致各大厂商需要自己加密。
加密解密的方法称为「密钥」
对称加密:

非对称加密:

创建者创建一个密钥对(公钥和私钥)
公钥加密必须私钥解密
私钥加密必须公钥解密
创建者保留私钥,公钥向外界公开
解决信任问题
通过第三方机构的证书来验证 某网站的证书是否可信
在根证书上的验证方式

实际上的证书体系,比较复杂

常见算法介绍
DES(Data Encryption Standard)
8bit = 1byte
著名的对称加密算法,将64bits原文和56bits密钥进行DES加工成64bits密文;可暴力破解
AES(Advanced Encryption Standard)
2001年美国国家标准于技术研究院发布的对称加密算法
可旁道攻击(通过硬件表现,猜出来算法过程)
RSA(Rivest-Shamir- Adleman)
非对称加密算法,三个人的名字命名
对称与非对称的区别
非对称加密安全性更好
对称加密计算速度更快
通常混合使用(利用非对称加密协商密钥,然后进行对称加密通信)
https建立连接到工作的过程

UDP和TCP、Https2.0/3.0
面试重点、前端重点、架构思想
TCP vs UDP
TCP面向流(API接收流)、UDP面向消息(API接收数据包)
场景上:TCP远程控制、UDP查询DNS
UDP:User Data Diagram
需要用户在应用层定义相应机制
不需要建立连接(延迟更低
封包提及更小(传输速度快
- 不关心数据顺序(不需要ACK
- 不保证数据不丢失
http2.0
http2.0最显著的特征是帧(Frame)和流(Steam)
h2中数据的传输单位以二进制数据帧的形式存在,传输形式依赖于流(也就是多个帧组成),每一个数据帧都会标识出属于哪一个流(通过流的ID),而在每一个TCP连接中可以存在并行的多个流,也就是可以发出多个请求,这便是多路复用;h1中的序列与阻塞机制被摒弃后,也就避免了队头阻塞的发生,接收端只管接收数据帧便可,不用担心丢失阻塞问题,每一个帧都有ID标识,在接受完毕后就可以组成完整的请求文件。

多个请求多路复用
多路复用:把相近的请求混合在一起请求过去,相当于并行
防止队头阻塞
队头阻塞:http1.1中的TCP长连接承载多个请求,在上一个请求A还未被响应时,后边的请求B自然就被阻塞了。

压缩HTTP头部(HPACK)
类似于摩尔斯电码,用数字代替字符串
服务端推送
在发现客户端请求的
html文件里有关联的css、js文件时,会自动将css、js一并推送返回给客户端
http2.0已经摒弃了雪碧图,
还需要GZIP,
不需要js/css文件合并,但需要js压缩
需要首屏优化
http3.0

详解帧(Frame)和流(Stream)
帧(frame)
HTTP/2 中数据传输的最小单位,因此帧不仅要细分表达 HTTP/1.x 中的各个部份,也优化了 HTTP/1.x 表达得不好的地方,同时还增加了 HTTP/1.x 表达不了的方式。 每一帧都包含几个字段,有length、type、flags、stream identifier、frame playload等

帧的字段含义
| 名称 | 长度 | 描述 |
|---|---|---|
| Length | 3 字节 | 表示帧负载的长度,默认最大帧大小2^14 |
| Type | 1 字节 | 当前帧的类型,下面会做介绍 |
| Flags | 1 字节 | 具体帧的标识 |
| R | 1 字节 | 保留位,不需要设置,否则可能带来严重后果 |
| Stream Identifier | 31 位 | 每个流的唯一ID |
| Frame Payload | 不固定 | 真实帧的长度,真实长度在Length中设置 |
其中type 代表帧的类型,在 HTTP/2 的标准中定义了 10 种不同的类型,包括上面所说的 HEADERS frame 和 DATA frame。此外还有: PRIORITY(设置流的优先级) RST_STREAM(终止流) SETTINGS(设置此连接的参数) PUSH_PROMISE(服务器推送) PING(测量 RTT) GOAWAY(终止连接) WINDOW_UPDATE(流量控制) CONTINUATION(继续传输头部数据)
| 名称 | ID | 描述 |
|---|---|---|
| DATA | 0x0 | 传输流的核心内容 |
| HEADERS | 0x1 | 包含HTTP首部,和可选的优先级参数 |
| PRIORITY | 0x2 | 指示或者更改流的优先级和依赖 |
| RST_STREAM | 0x3 | 允许一端停止流(通常是由于错误导致的) |
| SETTINGS | 0x4 | 协商连接级参数 |
| PUSH_PROMISE | 0x5 | 提示客户端,服务端要推送些东西 |
| PING | 0x6 | 测试连接可用性和往返时延(RTT) |
| GOAWAY | 0x7 | 告诉另外一端,当前端已结束 |
| WINDOW_UPDATE | 0x8 | 协商一端要接收多少字节(用于流量控制) |
| CONTINUATION | 0x9 | 用以拓展HEADER数据块 |
在 HTTP 2.0 中,它把数据报的两大部分分成了 header frame 和 data frame。也就是头部帧和数据体帧。
流(stream)
流: 存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。 HTTP/2 长连接中的数据包是不按请求-响应顺序发送的,一个完整的请求或响应(称一个数据流 stream,每个数据流都有一个独一无二的编号)可能会分成非连续多次发送。它具有如下几个特点:
- 双向性:同一个流内,可同时发送和接受数据。
- 有序性:流中被传输的数据就是二进制帧 。帧在流上的被发送与被接收都是按照顺序进行的。
- 并行性:流中的 二进制帧 都是被并行传输的,无需按顺序等待。
- 流的创建:流可以被客户端或服务器单方面建立, 使用或共享。
- 流的关闭:流也可以被任意一方关闭。
- HEADERS 帧在 DATA 帧前面。
- 流的 ID 都是奇数,说明是由客户端发起的,这是标准规定的,那么服务端发起的就是偶数了。
1.1.4. 网络请求实战
RESTFUL约定和Postman工具
工作日常、面试重点、大厂生态
RESTFUL(Representationnal state transfer)
表现层状态转化

资源(Resource)
- 服务端的一个资源
- 拥有URL
表示(Representation)
- 服务端的资源在客户端的表示
- 客户端拥有操作服务端资源的方法
转换(Transfer)
- 客户端收到新的表示(状态),从而向用户展现新的内容
RESTFUL的内容:
资源命名
使用名词性词组
用户登录
/user/login=>/token状态
客户端是无状态的(statless),从服务端请求来资源表示,客户端直接将表示转化为展示
产品列表
GET/products=> 产品列表组件展示统一
资源ID前后端统一
描述性强
按照规范的HTTP状态码
CURD(约定)

RESTFUL的优点:
- 客户端无业务状态(简化开发)
- 资源独立,接口间独立(缓存好设计)
- 对协议依赖不严重(可迁移)
Postman的使用
mocha/jest
mock.js
Fetch和Promise
工作日常、面试重点、程序架构
Promise神器
Fetch的基本用法
返回Promise
Resolve发生在网络通信正常(404,500也是resolve)
Reject发生在网络通信异常
默认不接受cookie
一个处理http pipeline更容易的工具

实战
应对不稳定的网络环境-指数补偿
按照指数的时间倍数重复发送请求
0ms - 200ms - 400ms - 800ms - 1600ms
function request (url) {
let resolved = false
let t = 1
return new Promise((resolve)=>{
function doFetch(){
if(resolved || t > 16){
return
}
fetch(url).then(resp => {
return resp.text()
})
.then(data => {
// 如果发现已经已经被解决掉了就不再resolve
if(!resolved){
resolve(data)
resolved = true
}
})
// 直接同步调用doFetch就会形成递归调用
// 所以套一个setTimeout变成异步调用
setTimeout(()=>{
doFetch()
t *= 2
},t*100)
}
})
}
并发处理和时间窗口(类似于节流)
多个资源并发请求,基于时间窗口过滤重复请求
function window_it(f,time = 50){
}
实战文件上传
工作日常、面试重点
表单提交方式
- FormData是用来表示表单数据的一个对象
- 里边是key/value
- 用boundary分隔
- 观察用表单提交数据是POST到服务端的数据body是怎样的?
- 观察用表单提交文件时body是怎样的?
- Express如何接受表单提交的数据?
HTML5方式
H5通过将文件(这里的文件是blob数据)转为base64放入body里,然后JSON化提交,服务端拿到之后,直接把base64转成文件。
base64:
用64个可打印字符来编码二进制(A-Za-z0-9+,)
- 0-255的ASCII码有许多不能打印的字符
- 不能打印的字符就不需要在中间过程中转义,如空格变成%2f,其实是不需要的

Man = base64 => TWFu
但是base64会将文件变大,还是通过FormData的形式保存并放入body传递比较快CPU压力会更小
上传文件和提交输入框中的字段没有本质的区别
Base64方法速度慢,没有特殊原因通常用blob转FormData上传
实战websocket聊天室
工作日常、面试重点、程序训练
WebSocket协议初探
一个基于TCP的通信协议,会(带着特定头部)复用HTTP的握手,在连接中会有websocket的自己的封包以二进制传输。
因为服务端无法主动的向客户端发送信息,所以建立一个稳定的通道WebSocket,可以频繁的互相的主动发消息。

websocket的握手-web
const client = new WebSocket('ws://chat.svc')
// wss -> WebSocket Secure
// https -> tls.ssl - tcp/ip
// wss - tls - tcp/ip
client.onopen = () => {
console.log('connnet OK!')
}
websocket的握手-node
const server = net.createSercer()
server.on('connection'.socket => {
socket.on('data',(buffer)=>{
// 返回
const sha1 = cryptp.createHash('sha1')
sha1.update(headers['sec-websocket-key']+'258...')
const acceptKey = sha1.digest('base64')
let response = 'HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Accept: ${acceptKey}
// 这里要空一行,因为http中的body和头部就差一行
// 如果没有这一行,浏览器就会一直等待body
// 且每一项前边不可以有空格
'
socket.write(response)
})
})
聊天室-node端
如果需要下载聊天记录,那就新建一个连接,这个链接是socket还是http都可以
socket.io
const users = new Map()
// 发送信息
function broadcast(type,message,sender){
socket.send(type,message,sender)
}
io.on('connect',socket =>{
// data {type,message}
socket.on('message',data => {
swich(data.type){
case 'LOGIN':
users.set(socket,{name:data.name})
broadcast('LOGIN',${data.name} + 'join in!')
break
case 'CHAT':
const user = users.get(scoket)
broadcast('CHAT', data.message, user.name)
break
}
})
})
聊天室-web端
socket.io
const socket = io('ws://chat.svc:8080')
const name = 'user '+ new Date().getTime()
socket.send({
type: 'LOGIN',
name
})
// 发送消息
cosnt ipt = document.getElementById('ipt')
ipt.addEventLisetener('keyup',e=>{
if(e.key === 'Enter') send()
})
function send(){
const val = ipt.value
if(val === ''){
return
}
socket.send({
type: "CHAT",
message: val
})
ipt.value = ''
ipt.focues()
}
websocket中tcp握手和协议转换的过程很自然
socket(网络插座)为客户端。服务端提供通信机制
缓存、缓存清理和HTTP缓存
工作日常、面试重点、架构思想
缓存介绍
存储将被用到的数据,让数据访问更快。

- 命中:在缓存中找到了请求的数据
- 不命中/穿透:缓存中没有找到需要的数据
- 命中率:命中次数/总次数
- 缓存大小:缓存中一共可以存多少数据
- 清空策略:如果缓存空间不够时,数据如何被替换
FIFO的清空策略
先进先出队列

LFU-Least Frequently used

LRU-Least Recently used

实战:FIFO的memory函数
function _fib(n){
if(n==1 || n==2){
return n
}
return fib(n-1) + fib(n-2)
}
function memory(f,maxSize = 10){
const cache = []
return (...args) => {
const hash = args.join(',')
// sheji mingzhong
const item = cache.find(x => x.hash ===hash)
// 如果 命中
if(item) {
return item.value
}
// 如果没有命中
const result = f(...args)
cache.push({hash,value:result})
// 如果缓存长度超过maxSize,就要推出末尾的缓存
if(cache.length > maxSize){
cache.shift()
}
return result
}
}
const fib = memory(_fib, 10)
实战:LRU算法的缓存
function memory(f,maxSize = 10){
let cache = []
return (...args) => {
const hash = args.join(',')
// sheji mingzhong
const item = cache.find(x => x.hash ===hash)
// 如果 命中
if(item) {
item.time = new Date().getTime()
return item.value
}
// 如果没有命中
const result = f(...args)
cache.push({hash,
value:result,
time: new Date().getTime()})
// 如果缓存长度超过maxSize,就要推出时间最堵啊的呢的缓存
if(cache.length > maxSize){
let min = Infinity
let minItem = null
for(let item of cache){
if(item.time < min){
min = item.time
minItem = item
}
}
//去掉
cache = cache.filter(x=> x!==minItem)
}
return result
}
}
缓存策略
Cache-Control:定义所有缓存都要遵守的行为

常见用法:

强制缓存:强制使用浏览器缓存,不请求服务器
直接设置max-age= 360来实现强制缓存。
协商缓存:协商使用缓存,每次需要向服务器请求对比,缓存生效不传回body,也就不更新内容和缓存。
一个是:last-Modified 和 if-Modified-Since
另一个是:Etag 和 if-None-Match
