前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >面试不再怕,20行Python代码帮你搞懂LRU算法

面试不再怕,20行Python代码帮你搞懂LRU算法

作者头像
simpleapples
发布于 2018-10-18 06:54:24
发布于 2018-10-18 06:54:24
54200
代码可运行
举报
文章被收录于专栏:Python私房菜Python私房菜
运行总次数:0
代码可运行

LRU算法在后端工程师面试中,是一个比较常出现的题目,这篇文章带大家一起,理解LRU算法,并最终用Python轻松实现一个基于LRU算法的缓存。

缓存是什么

先看一张图,当我们访问网页,浏览器会给服务器发请求,服务器会经过一系列的运算,把页面返回给浏览器。

当有多个浏览器同时访问的时候,就会在短时间内发起多个请求,而服务器对每一个请求都要进行一系列相同的操作。重复工作不仅浪费资源,还可能导致响应速度变慢。

而缓存则可以把服务器返回的页面保存下来,当有其他的浏览器再访问时候,就不必劳服务器大驾,直接由缓存返回页面。为了保证响应速度,缓存通常是基于比较昂贵的硬件,比如RAM,这就决定了我们很难用大量的缓存把所有的页面都存下来,当恰好没有缓存浏览器请求的页面时,依然需要请求服务器。由于缓存容量有限,而数据量无限(互联网每天新产生的页面数无法估计),就需要把好刚用在刀刃上,缓存那些最有用的信息。

LRU是什么

LRU是一种缓存淘汰算法(在OS中也叫内存换页算法),由于缓存空间是有限的,所以要淘汰缓存中不常用的数据,留下常用的数据,达到缓存效率的最大化。LRU就是这样一种决定“淘汰谁留下谁”的算法,LRU是Least recently used的缩写,从字面意思“最近最少使用”,我们就可以理解LRU的淘汰规则。

LRU的淘汰逻辑

我们用一张图来描述LRU的淘汰逻辑,图中的缓存是一个列表结构,上面是头结点下面是尾节点,缓存容量为8(8个小格子):

- 有新数据(意味着数据之前没有被缓存过)时,加入到列表头

- 缓存到达最大容量时,需要淘汰数据多出来的数据,此时淘汰列表尾部的数据

- 当缓存中有数据被命中,则将数据移动到列表头部(相当于新加入缓存)

按上面的逻辑我们可以看到,一个数据如果经常被访问就会不断地被移动到列表头部,不会被淘汰出缓存,而越不经常访问的数据,越容易被挤出缓存。

20行Python代码实践LRU

接下来我们用Python来实现一个采用LRU算法的缓存。

从前面的文章中我们可以知道,缓存简化下来就两个功能,一个是往里装数据(缓存数据),一个是往外吐数据(命中缓存),所以我们的缓存对外只需要put和get两个接口就可以了。

按照前面的示意图,缓存内部我们只需要有一个列表(list)就可以实现LRU逻辑,不过用列表虽然能实现逻辑,但是在判断是否命中缓存时,速度可能非常慢(列表需要遍历才能知道数据有没有在里面)。在Python中,我们可以用基于hash的结构,比如字典(dict)或集合(set),来快速判断数据是否存在,解决列表实现的性能问题。但是字典和集合又是没有顺序的,如果能有一种既能排序,又是基于hash存储的数据结构,就好了。

在Python的collections包中,已经内置了这种实用的结构OrderedDict,OrderedDict是dict的子类,但是存储在内部的元素是有序的(列表的特点)。

解决了数据结构的问题,我们可以直接上手写逻辑了,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1class LRUCache:
 2
 3    def __init__(self, capacity):
 4        self.capacity = capacity
 5        self.queue = collections.OrderedDict()
 6
 7    def get(self, key):
 8        if key not in self.queue:
 9            return -1 // 要找的数据不在缓存中返回-1
10        value = self.queue.pop(key) // 将命中缓存的数据移除
11        self.queue[key] = value // 将命中缓存的数据重新添加到头部
12        return self.queue[key]
13
14
15    def put(self, key, value):
16        if key in self.queue: // 如果已经在缓存中,则先移除老的数据
17            self.queue.pop(key)
18        elif len(self.queue.items()) == self.capacity:
19            self.queue.popitem(last=False) // 如果不在缓存中并且到达最大容量,则把最后的数据淘汰
20        self.queue[key] = value // 将新数据添加到头部

下次面试在遇到LRU的题目,是不是就胸有成竹了?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python私房菜 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
LRU算法原理解析
LRU是Least Recently Used的缩写,即最近最少使用,常用于页面置换算法,是为虚拟页式存储管理服务的。
py3study
2020/01/15
1.4K0
手写LRU缓存淘汰算法
在我们这个日益追求高效的世界,我们对任何事情的等待都显得十分的浮躁,网页页面刷新不出来,好烦,电脑打开运行程序慢,又是好烦!那怎么办,技术的产生不就是我们所服务么,今天我们就聊一聊缓存这个技术,并使用我们熟知的数据结构--用链表实现LRU缓存淘汰算法。
Simon郎
2021/03/01
7660
Go语言手写本地 LRU 缓存
缓存是计算机编程中的一种技术,用于临时存储数据以加速访问和提高性能。缓存是提高系统性能、减少延迟和优化用户体验的重要工具。合理使用缓存技术,开发人员可以构建更加高效和可靠的应用程序。缓存的重要性体现在以下方面:
FunTester
2025/01/23
620
Go语言手写本地 LRU 缓存
lru_cache分析
在计算机软件领域,缓存(Cache)指的是将部分数据存储在内存中,以便下次能够更快地访问这些数据,这也是一个典型的用空间换时间的例子。一般用于缓存的内存空间是固定的,当有更多的数据需要缓存的时候,需要将已缓存的部分数据清除后再将新的缓存数据放进去。需要清除哪些数据,就涉及到了缓存置换的策略,LRU(Least Recently Used,最近最少使用)是很常见的一个,也是 Python 中提供的缓存置换策略。
Yerik
2021/08/22
6180
【python刷题】LRU
LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。 我们需要记住以下几点就行了:这里以队列为例
西西嘛呦
2021/02/02
5010
LRU算法简介
LRU(Least Recently Used)算法是一种缓存淘汰算法,常用于缓存系统中,通过保留最近使用的数据而淘汰最久未使用的数据,以提高缓存的命中率。LRU算法的核心思想是基于时间局部性原理:最近访问的数据在未来会被再次访问。
孟斯特
2024/01/28
6230
LRU算法简介
实现 LRU 缓存算法
LRU 算法全称是最近最少使用算法(Least Recently Use),是一种简单的缓存策略。顾名思义,LRU 算法会选出最近最少使用的数据进行淘汰。
Se7en258
2022/06/24
9730
实现 LRU 缓存算法
缓存及在 Python 中使用缓存
缓存操作主要有两种类型。缓存如浏览器缓存,服务器缓存,代理缓存,硬件缓存工作原理的读写缓存。当处理缓存时,我们总是有大量的内存需要花费大量的时间来读写数据库、硬盘。 缓存则能帮我们加快这些任务。
Ewdager
2020/07/20
3.8K0
聊聊缓存淘汰算法-LRU 实现原理
我们常用缓存提升数据查询速度,由于缓存容量有限,当缓存容量到达上限,就需要删除部分数据挪出空间,这样新数据才可以添加进来。缓存数据不能随机删除,一般情况下我们需要根据某种算法删除缓存数据。常用淘汰算法有 LRU,LFU,FIFO,这篇文章我们聊聊 LRU 算法。
andyxh
2019/10/30
7820
聊聊缓存淘汰算法-LRU 实现原理
设计实现一个LRU Cache1 什么是LRU Cache2 实现思路
1 什么是LRU Cache 在LeetCode上有一个LRU Cache实现的题目 Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists
JavaEdge
2018/05/16
1.2K0
深入探究LRU缓存机制:优化内存利用与提升性能
LRU(Least Recently Used)缓存是一种常见的缓存淘汰策略,其原理基于“最近最少使用”的原则。当缓存空间不足时,LRU缓存会淘汰最近最久未被使用的数据,以确保缓存中始终存储着最新和最频繁使用的数据。
人不走空
2024/03/16
8080
如何动手撸一个LRU缓存
上篇文章介绍了,如何动手实现一个LFU缓存,今天我们来学习下如何动手实现一个LRU缓存,在这之前,我们还是先回顾下关于缓存置换算法的三种策略:
我是攻城师
2019/07/31
6360
如何动手撸一个LRU缓存
原创 | 你会用缓存吗?详解LRU缓存淘汰算法
大家好,欢迎大家来到周三算法数据结构专题,今天我们和大家聊一个非常常用的算法,叫做LRU。
TechFlow-承志
2020/09/22
7360
原创 | 你会用缓存吗?详解LRU缓存淘汰算法
13. 谈谈 Redis 的过期策略
Redis 会将每个设置了过期时间的 key 放入到一个独立的字典中,默认每 100ms 进行一次过期扫描:
用户11332765
2024/10/28
2530
Python中的collections
在 Python 中,collections是一个非常有用的内置模块,它提供了一些高性能的数据类型,可以帮助你更高效地处理数据。
宅蓝三木
2024/10/09
980
Python 算法基础篇:链表和双向链表的实现与应用
链表和双向链表是常用的线性数据结构,它们在算法和程序设计中有着广泛的应用。本篇博客将重点介绍链表和双向链表的原理、实现以及它们在不同场景下的应用。我们将使用 Python 来演示链表和双向链表的实现,并通过实例展示每一行代码的运行过程。
小蓝枣
2023/07/25
7680
动手实现 LRU 算法,以及 Caffeine 和 Redis 中的缓存淘汰策略
那天我在 LeetCode 上刷到一道 LRU 缓存机制的问题,第 146 题,难度为中等,题目如下。
古时的风筝
2020/07/16
8220
LRU -- Javascript实现版本(核心代码只有10行)
LRU 最近最少使用,是一种常见的淘汰(置换)算法,选择最近最久未使用的予以淘汰。常用于内存管理。
奋飛
2021/10/13
5240
LRU -- Javascript实现版本(核心代码只有10行)
如何实现缓存与LRU算法以及惰性过期
在计算机科学中,缓存是一种临时存储数据的技术,用于加速数据访问速度。通过将常用数据存储在高速缓存中,可以减少对慢速存储器(如磁盘或数据库)的访问次数,从而提高系统的性能和响应速度。缓存通常位于计算机内存或更快速的存储介质上。
GeekLiHua
2025/01/21
860
昨天面试被问到的 缓存淘汰算法FIFO、LRU、LFU及Java实现
第一次请求时把计算好的结果存放在缓存中,下次遇到同样的请求时,把之前保存在缓存中的数据直接拿来使用。
万猫学社
2022/04/22
3290
相关推荐
LRU算法原理解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文