当前位置: 首页 > news >正文

Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现

LRU(Least Recently Used,最近最少使用)是通过记录缓存项的访问顺序来决定淘汰的策略:当缓存满时,移除最久未被使用的项。

核心概念:

  • 缓存存储:使用 Map 存储键值对,用于快速访问缓存内容。
  • 访问顺序跟踪:通过 双向链表(LinkedList) 跟踪缓存的访问顺序,访问过的元素会被移动到链表的前端,最久未访问的元素位于链表的尾部。
  • 淘汰机制:缓存容量满时,删除链表尾部的元素,即最少使用的元素。

代码实现:

  1. LRUCache:负责管理缓存,使用 Map 存储键值对,使用 LinkedList 跟踪访问顺序。
  2. LinkedList:双向链表,用于按访问顺序排列缓存项,支持移动元素到链表前端、删除尾部元素等操作。
  3. Node:链表节点,用于存储缓存项。

工作方式:

  • get(key):如果缓存存在,移至链表前端,表示最近使用。
  • put(key, value):插入新缓存或更新现有缓存,满时淘汰尾部项。

代码示例:

// 双向链表节点定义
class Node {constructor(value) {this.value = value; // 节点值this.prev = null;   // 指向前一个节点this.next = null;   // 指向后一个节点}
}// LRUCache 类实现 LRU 缓存
class LRUCache {constructor(maxSize) {this.maxSize = maxSize;this.cache = new Map(); // Map 存储缓存,保证插入顺序this.list = new LinkedList();// 链表记录访问顺序}// 获取缓存值	get(key) {if (this.cache.has(key)) { // 如果缓存中存在该 keythis.list.moveToFront(key); // 将该 key 移动到链表头return this.cache.get(key); // 返回缓存值}return null; // 如果没有找到,返回 null}// 插入或更新缓存put(key, value) {// 如果缓存中已经有该 key,将该项移到链表前端if (this.cache.has(key)) {this.list.moveToFront(key);} else {if (this.cache.size >= this.maxSize) { // 如果缓存已满// 移除尾部的最久未使用项,从缓存中删除该项const lastKey = this.list.removeLast();this.cache.delete(lastKey);}this.list.addAtFront(key); // 将新项添加到链表头}this.cache.set(key, value); // 更新缓存的值}
}// 双向链表实现
class LinkedList {constructor() {// 初始化链表为空this.head = this.tail = null;  // 初始化链表为空}// 将节点插入到链表前端addAtFront(value) {const newNode = new Node(value); // 创建新节点if (this.head) { // 1.如果链表非空:新节点的 next 指向当前头节点。当前头节点的 prev 指向新节点newNode.next = this.head;this.head.prev = newNode;} else {this.tail = newNode; // 2.如果链表为空,新的节点是尾节点}this.head = newNode; // 3.新节点为头节点}// 将某个节点移动到链表头moveToFront(value) {const node = this.find(value); // 查找节点if (node === this.head) return; // 如果该节点已在头部,直接返回   // 更新 node 的前后节点,使其从链表中移除。// 当前节点的前一个节点 node.prev 的 next 指针,指向当前节点的下一个节点 node.nextif (node.prev) node.prev.next = node.next;// 当前节点的下一个节点 node.next 的 prev 指针,指向 当前节点的前一个节点 node.previf (node.next) node.next.prev = node.prev;// 如果是尾节点,更新尾节点if (this.tail === node) this.tail = node.prev; // 将节点插入到链表前端this.addAtFront(value);}// 移除链表尾部节点并返回其 keyremoveLast() {const value = this.tail.value; // 获取尾部节点的值ifthis.head === this.tail) {  // 如果链表只有一个节点this.head = this.tail = null // 清空链表} else {this.tail = this.tail.prev // 更新尾节点this.tail.next = null // 断开尾节点与原节点的链接}return value; // 返回移除值}// 查找链表中某个节点find(value) {let current = this.head;// 遍历链表,找到目标节点while (current && current.value !== value) {current = current.next;}return current;}
}

注释解释

  • LRUCache 类:实现了缓存的主要功能,包括存储数据、获取数据、添加新数据、以及缓存淘汰。其中 get 和 put 方法:实现了缓存读取和更新逻辑,并保证缓存的顺序和容量。
  • LinkedList 类:双向链表,用来维护缓存访问顺序。链表的头节点表示最近使用的缓存项,尾节点表示最久未使用的缓存项。
  • Node 类:链表中的节点,每个节点包含值以及指向前后节点的指针。

操作示例:

const cache = new LRUCache(3);
cache.put('key1', 'value1');
cache.put('key2', 'value2');
cache.put('key3', 'value3');
cache.get('key1'); // 最近使用过,移到前端
cache.put('key4', 'value4'); // 超过最大容量,移除最后使用的key3

LRU 缓存淘汰策略总结:

  1. 缓存项访问顺序:每次访问都会将该缓存项移到前端,表示最近使用。
  2. 满缓存时淘汰:如果缓存超出最大容量,淘汰链表尾部的最久未访问项(LRU)。
  3. 效率Map 提供 O(1) 时间复杂度的缓存存取,LinkedList 保证了 O(1) 的插入、移动和删除操作。

记忆要点:

  • LRU:最近最少使用的缓存项会被淘汰。
  • 双向链表:用来维护缓存项的访问顺序,确保 O(1) 时间复杂度。
  • 缓存淘汰:超出容量时,淘汰最久未访问的缓存项。

相关文章:

Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现

LRU(Least Recently Used,最近最少使用)是通过记录缓存项的访问顺序来决定淘汰的策略:当缓存满时,移除最久未被使用的项。 核心概念: 缓存存储:使用 Map 存储键值对,用于快速访问缓…...

李宏毅机器学习课程知识点摘要(14-18集)

线性回归,逻辑回归(线性回归sigmoid),神经网络 linear regression , logistic regression , neutral network 里面的偏导的相量有几百万维,这就是neutral network的不同,他是…...

《AI大模型开发笔记》Faster-Whisper 免费开源的高性能语音识别模型

1 Whisper模型,免费开源的语音识别模型 Whisper模型是OpenAI公开的语音识别模型。这是一个免费可商用的模型。 Whisper模型根据参数量来区分,有多个不同的版本,分别是tiny,base,small medium,large&#x…...

蓝队基础,网络七杀伤链详解

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…...

golang开发一个海盗王的登录更新器

前段时间,用golang配合界面库govcl开发一个海盗王的登陆更新器,实现多区注册和文件更新分离不同服务器等新功能。 由于govcl没有更换皮肤的功能,界面都是默认,不好看。 找了很多go语言的gui库,都没有符合要求的。 后来…...

李宏毅机器学习课程知识点摘要(6-13集)

pytorch简单的语法和结构 dataset就是数据集,dataloader就是分装好一堆一堆的 他们都是torch.utils.data里面常用的函数,已经封装好了 下面的步骤是把数据集读进来 这里是读进来之后,进行处理 声音信号,黑白照片,红…...

003 STM32基础、架构以及资料介绍——常识

注: 本笔记参考学习B站官方视频教程,免费公开交流,切莫商用。内容可能有误,具体以官方为准,也欢迎大家指出问题所在。 01什么是STM32(宏观) STM32属于一个微控制器,自带了各种常用通…...

【大语言模型】ACL2024论文-20 SCIMON:面向新颖性的科学启示机器优化

【大语言模型】ACL2024论文-20 SCIMON:面向新颖性的科学启示机器优化 目录 文章目录 【大语言模型】ACL2024论文-20 SCIMON:面向新颖性的科学启示机器优化目录摘要研究背景问题与挑战如何解决创新点算法模型实验效果推荐阅读指数:★★★★☆ …...

开源可视化工具对比:JimuReport VS DataEase

在当今数据驱动的时代,高效的数据可视化工具成为企业洞察业务、做出决策的关键利器。那对于企业来讲如何选择BI产品呢? 在开源可视化工具的领域中,JimuReport和DataEase 以其独特的优势脱颖而出,究竟谁更胜一筹呢?让我…...

2024年亚太地区数学建模大赛A题-复杂场景下水下图像增强技术的研究

复杂场景下水下图像增强技术的研究 对于海洋勘探来说,清晰、高质量的水下图像是深海地形测量和海底资源调查的关键。然而,在复杂的水下环境中,由于光在水中传播过程中的吸收、散射等现象,导致图像质量下降,导致模糊、…...

shell与QQ邮箱的连接

1.下载软件:yum install s-nail 2.配置文件:vim /etc/s-nail.rc 末尾添加此三行,加入QQ邮箱和验证码 3.验证码位于QQ邮箱安全管理内,进行复制粘贴 4.测试发消息给本地邮箱:echo "要发送的内容" | mail …...

11.21 深度学习-tensor常见操作

import torch from PIL import Image from torchvision import transforms # 获取元素值 tensor.item() 返回一个数值 只能是tensor里面有一个数字的 # 我们可以把单个元素tensor转换为Python数值,这是非常常用的操作 # tensor 里面超过了1个数字就不行 def g…...

【MySQL课程学习】:MySQL安装,MySQL如何登录和退出?MySQL的简单配置

🎁个人主页:我们的五年 🔍系列专栏:MySQL课程学习 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 MySQL在Centos 7环境下的安装: 卸载…...

基于官网的Vue-router安装(2024/11)

!!!首先声明,官网很重要。其次,不知道为啥,我不会安装时看不懂官网,会了之后就能看懂了。 官网地址:https://router.vuejs.org/zh/guide/ 1.npm安装 npm install vue-router4 官方貌…...

未来已来:少儿编程竞赛聚焦物联网,激发创新潜力

随着人工智能与物联网技术(IoT)的快速发展,少儿编程教育正在迎来新的变革浪潮。近年来,各类少儿编程竞赛纷纷增加了物联网相关主题,要求学生结合编程知识和硬件设备设计智能家居、智慧城市等创新项目。这一趋势不仅丰富…...

archlinux安装waydroid

目录 参考资料 注意 第一步切换wayland 第二步安装binder核心模组 注意 开始安装 AUR安裝Waydroid 启动waydroid 设置网络(正常的可以不看) 注册谷歌设备 安装Arm转译器 重启即可 其他 参考资料 https://ivonblog.com/posts/archlinux-way…...

Oralce数据库巡检SQL脚本

文章目录 Oralce数据库巡检SQL脚本1 检查表空间使用情况2 检查是否有 offline 状态的表空间3 在线日志是否存在小于 50M 的及状态不正常4 检查锁阻塞5 查看是否有僵死进程6 检查是否有失效索引7 检查不起作用的约束8 缓冲区命中率9 数据字典命中率10 库缓存命中率11 内存中的排…...

CentOS使用中遇到的问题及解决方法

一、CentOS 7网络配置(安装后无法联网问题) 现象说明 在安装CentOS系统后,有可能出现无法联网的问题,虚拟机中的网络配置并没有问题,而系统却无法联网,也ping不通。 原因描述 CentOS默认开机不启动网络,因…...

ThinkPad t61p 作SMB服务器,打印服务器,pc ,android ,ipad利用此服务器互传文件

1.在t61p上安装win7 2,配置好smb 服务 3.再安装好打印驱动程序 4.pc与win7利用系统的网络互相发现,映射为硬盘使用。 5.android,ipad安装ES文件浏览器访问win7 共享文件夹,互传文件。 6.android手机安装FE文件浏览器,可以利用花生壳外网…...

php:使用Ratchet类实现分布式websocket服务

一、前言 最近需要做一个有关聊天的小程序,逻辑很简单,所以不打算用Swoole和workerman之类的,最后选择了Ratchet,因为简单易用,适合小型websocket服务。 二、问题 但是目前我的项目是分布式环境,统一通过Ng…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

python/java环境配置

环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Kafka入门-生产者

生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...