网络请求实战-缓存、缓存清理和HTTP缓存

news2024/12/29 10:05:06

目录

缓存介绍

清空策略(FIFO)

实战:fifo的memory函数

实战:LRU算法

HTTP缓存

Cache-Control

强制缓存

协商缓存

协商缓存-2(用的最多的)

小结


缓存介绍

早期cpu,内存设计上都有缓存

存储将被用到的数据,让数据访问更快

布隆过滤器(效率更高,牺牲缓存命中率)

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

清空策略(FIFO)

1.先进先出

思考:如果是Javascript缓存,用Map还是Array(Map易读取,Array易清空)

2.LFU-Least Frequently used

优先清除命中次数少的,根据使用频率

内部实现用数组还是优先级队列?(量大的话用数组遍历效率低,可以考虑用优先级队列)

3.LRU-Least recently used

优先清除太久没有使用的,保留最近被使用的缓存,更新最近调用时间

思考:内部实现用数组还是优先级队列?

实战:fifo的memory函数

缓存成立的环境,会做哪些事情

通常是在浏览器上,在端上,整体缓存设置大小限制的

// 先进先出实现方法
function memory(f, maxSize = 10) {
  // [{hash, value}]
  const cache = []
  return (...args) => {
    const hash = args.join(',')
    const item = cache.find(x => x.hash === hash)// 循环遍历,找到x.hash === hash 的x   
    if(item) {
      return item.value
    }
    const result = f(...args)
    cache.push({
      hash,
      value: result
    })
    if(cache.length > maxSize) {
      cache.shift() // 移除第一个值
    }
    return result
  }
}
// 1 1 2 3 5 8 13
// 斐波那契数列(Fibonacci sequence),
// 又称黄金分割数列
function fib(n) {
  if(n === 1 || n === 2) {
    return 1
  }
  //  递归,前面2个数的和
  // 因为是递归函数所以,下面mfib用外面那个使用缓存的mfib
  return mfib(n-1) + mfib(n-2) 
}
const mfib = memory(fib, 10)
2^n // 2的n次方
console.log(fib(40))

实战:LRU算法

缓存越来越多的话,会采取的策略

更新最近调用时间

// 优先清除太久没有使用的,保留最近被使用的缓存,更新最近调用时间
function memory(f, maxSize = 10) {
  // [{hash, value}]
  let cache = [] // 重新附过值用let
  //let cache = {}
  return (...args) => {
    const hash = args.join(',')
    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() // 新增时间
    })
    if(cache.length > maxSize) {// 删掉时间戳最小的值
      let min = Infinity // 正无穷
      let minItem = null
      for(let item of cache) {
        if(item.time <min) { // 循环比对,把时间戳最小值赋值给min,minItem
          min = item.time
          minItem = item
        }
      }
      cache = cache.filter(x => x !== minItem) // 保留除了时间戳最小值的数据
    }
    return result
  }
}
// 1 1 2 3 5 8 13
function fib(n) {
  if(n === 1 || n === 2) {
    return 1
  }
  return mfib(n-1) + mfib(n-2)
}
const mfib = memory(fib, 10)
console.log(fib(40))

 建议用优先级队列,更新一下,上面方法里的on循环

HTTP缓存

Cache-Control

定义所有缓存都要遵守的行为

可缓存性

  • public:允许所有方缓存
  • private:只允许浏览器缓存
  • no-cache:每次必须先询问服务器资源是否已经更新
  • no-store:不使用缓存

缓存期限

  • max-age:秒(存储周期)
  • s-maxage:秒(共享缓存如代理等,存储周期)

强制缓存

强制使用缓存,不去服务器对比;(缓存生效不再发送请求)

Cache-Control: max-age=600(多用这个)

Expires:(用的少)

const express = require('express')
const app = express()
app.get('/x', (req, res) => {
    // max-age=0 === no-cache
  res.set("Cache-Control", 'max-age=600') // 强制缓存,一般用于一定时间内不会变的静态文件
  res.send("x6")
})
app.listen(3000)
// fetch("/x") // Code: 200 OK (from disk cache)

请求页面,请求接口会用304协商缓存no-cache

协商缓存

协商使用缓存,每次需要向服务器请求对比,缓存生效不传回body

返回: Last-Modified:

请求:If-Modified-Since:

const express = require('express')
const app = express()
app.set('etag', false)// etag也是一种协商缓存,关掉干扰因素
app.get('/x', (req, res) => {
  res.set("Last-Modified", 'Tue Sep 28 2021 23:41:43 GMT+0800') // 协商缓存,数据更新的最后时间,比较好用
  res.send("x6")
})
app.listen(3000)

协商缓存-2(用的最多的)

返回:E-Tag:1234567

请求:If-None-Match:1234567

小结

  • 发布新的静态资源的时候,如何更新缓存?

1.每次发布的静态资源文件名都不同(大厂最多策略)

  • HTTP缓存有大小限制吗?FIFO还是LRU

HTTP有大小限制,用端的时候要和端上的同学协商用多大的缓存,

浏览器有自己的限制;CDN也会有限制,只是通常触发不到

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/442741.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

开发常用的 Linux 命令4(系统、进程和其它)

开发常用的 Linux 命令4&#xff08;系统、进程和其它&#xff09; 作为开发者&#xff0c;Linux是我们必须掌握的操作系统之一。因此&#xff0c;在编写代码和部署应用程序时&#xff0c;熟练使用Linux命令非常重要。这些常用命令不得不会&#xff0c;掌握这些命令&#xff0…

【JUC】volatile和JMM

【JUC】volatile和JMM 文章目录 【JUC】volatile和JMM1. volatile1.1 特点1.2 内存语义 2. 内存屏障2.1 分类2.2 什么叫保证有序性&#xff1f;2.3 内存屏障的4种插入策略 3. volatile特性3.1 保证可见性3.2 volatile读写过程3.3 没有原子性3.4 指令禁重排(有序性) 4. 正确使用…

python标识符概念及规范

在python中 能取名字的东西非常非常多 例如 我们之前学的变量 以及后面要接触的 函数 类&#xff0c;等等&#xff0c;等等 而我们给这些取的名字 被统称为 标识符 而 python中 标识符的命名也是有限制的 主要有三种 1 内容限定 2 大小写铭感 3 不能使用关键字 内容限定来讲…

leetcode6_N字形变换

如有错误&#xff0c;感谢不吝赐教、交流 leetcode6 题目描述 将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时&#xff0c;排列如下&#xff1a; P A H N A P L S I…

HTB-SecNotes

HTB-SecNotes 信息收集8808端口80端口通过CSRF获取通过二次注入 立足tyler -> administrator 信息收集 8808端口 Windows IIS 10.0 可以从官方文档查看10.0版本可能的操作系统。 80端口 通过CSRF获取 目录扫描发现需要登陆后继续进一步操作啊。 对其进行简单的SQL注入测…

数据库基础篇 《7.单行函数》

目录 1. 函数的理解 1.1 什么是函数 1.2 不同DBMS函数的差异 ​编辑1.3 MySQL的内置函数及分类 ​编辑 2. 数值函数 2.1 基本函数 ​编辑 2.2 角度与弧度互换函数 2.3 三角函数 ​编辑 2.4 指数与对数 ​编辑 2.5 进制间的转换 ​编辑3. 字符串函数 ​编辑…

SAM(segment anything model)分割一切 Demo测试及API调用

SAM 分割一切 一&#xff0c;SAM介绍1.1 介绍1.2 项目链接 二&#xff0c;Demo-Test&#xff1a;2.1 Demo功能介绍2.1.1&#xff0c;首页就是这个SAM&#xff0c;点击try demo&#xff0c;可以选择它的自带图片&#xff0c;也可以自己添加。2.1.2 , 自己上传图片测试&#xff1…

[java基础]面向对象(五)

访问控制修饰符&#xff1a;--------------保护数据的安全(隐藏数据、暴露行为)&#xff0c;实现封装 public&#xff1a;公开的&#xff0c;任何类 private&#xff1a;私有的&#xff0c;本类 protected&#xff1a;受保护的&#xff0c;本类、派生类、同包类 默认的&…

learn_C_deep_3 (最名不符实的关键字 - static、static关键字总结、基本数据类型、最冤枉的关键字 - sizeof)

目录 最名不符实的关键字 - static stati修饰全局变量和函数 static修饰局部变量 static关键字总结 几个问题 1.c语言要设置全局变量和函数可以跨文件使用的原因 2.C程序地址空间是什么样的&#xff1f; 3.局部变量为什么具有临时性 4.全局变量为什么具有全局性 5.为…

vue-cli版本号始终是2.9.6,且无法删除,安装更新无效的问题。

参考博客 目录 1.问题出现原因2.我的解决办法&#xff1a;删除原脚手架&删除原vuevue.cmd 1.问题出现原因 从各种博客我得知&#xff0c;这种问题出现在2处&#xff1a; 没有卸载原来的脚手架原来的vue和vue.cmd没删除干净 2.我的解决办法&#xff1a;删除原脚手架&…

[oeasy]python0135_命名惯用法_name_convention

命名惯用法 回忆上次内容 上次 了解了isidentifier的细节 关于 关键字关于 下划线 如何查询 变量所指向的地址&#xff1f; id 如何查询 已有的各种变量&#xff1f; locals 如果 用一个变量a的值 给另一个变量b 赋值是什么样的过程 呢&#xff1f;&#xff1f;&#x1f914;…

当,Kotlin Flow与Channel相逢

前言 之前的文章已经分析了Flow的相关原理与简单使用&#xff0c;Flow之所以用起来香&#xff0c;Flow便捷的操作符功不可没&#xff0c;而想要熟练使用更复杂的操作符&#xff0c;那么需要厘清Flow和Channel的关系。 本篇文章构成&#xff1a; 1. Flow与Channel 对比 1.1 Fl…

AVL树(C++实现)

文章目录 AVL树的概念AVL树结点定义AVL树的插入AVL树的旋转左单旋右单旋左右单旋右左双旋 AVL树的验证AVL树的性能AVL树及测试完整代码 AVL树的概念 二叉搜索树虽然可以缩短查找的效率,但如果数据有序或接近有序,那么二叉搜索树将退化为单支树,查找元素则相当于在顺序表中搜索…

从零手写Resnet50实战——利用 torch 识别出了虎猫和萨摩耶

大家好啊&#xff0c;我是董董灿。 自从前几天手写了一个慢速卷积之后&#xff08;从零手写Resnet50实战—手写龟速卷积&#xff09;&#xff0c;我便一口气将 Resnet50 中剩下的算法都写完了。 然后&#xff0c;暴力的&#xff0c;按照 Resnet50 的结构&#xff0c;将手写的…

【Flowable】Flowable基础表结构

1.表结构讲解 表结构创建文件&#xff1a;flowable-engine-6.3.0.jar!\org\flowable\db\create\flowable.mysql.create.engine.sql 工作流程的相关操作都是操作存储在对应的表结构中&#xff0c;为了能更好的弄清楚Flowable的实现原理和细节&#xff0c;我们有必要先弄清楚Fl…

Python边缘检测之prewitt, sobel, laplace算子

文章目录 滤波算子简介具体实现测试 滤波算子简介 ndimage中提供了卷积算法&#xff0c;并且建立在卷积之上&#xff0c;提供了三种边缘检测的滤波方案&#xff1a;prewitt, sobel以及laplace。 在convolve中列举了一个用于边缘检测的滤波算子&#xff0c;统一维度后&#xf…

es6 const的使用

1.const用来定义常量&#xff0c;赋值知乎不能再赋值&#xff0c;再次赋值会报错。 <script>//1.定义常量&#xff0c;赋值后不能再赋值&#xff0c;在赋值报错const count 1// count 2</script> ​ 2.const不能只声明不赋值&#xff0c;会报错。 <script>…

智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络)

智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络) 目录 智能学习 | MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法优化BP神经网络)预测效果基本介绍程序设计参考资料预测效果 基本介绍 MATLAB实现CS-BP多变量时间序列预测(布谷鸟搜索算法…

chatGPT衣食住行10种场景系列教程(01)chatGPT热点事件+开发利器

导读 时隔5个多月&#xff0c;chatGPT可谓是一日千里&#xff0c;越演越火&#xff0c;携带着AIGC行业一起飞了起来&#xff0c;那么在短短5个月当中有那些值得我们关注的事件&#xff1f;有那些好玩的场景&#xff1f;以及有那些chatGPT好用的工具&#xff1f;本文都将一一告…