zoukankan      html  css  js  c++  java
  • 【40讲系列15】LRU缓存

    一、理论

    LRU是一种缓存淘汰策略,最近使用的认为是「有用的」,很久没使用过的数据认为是无用的,缓存满时就优先删除它们。

    • LRU- Least recently used(最近最少使用页面置换算法、按访问的时序来淘汰)
    • LFU- Least frequently used(最近最不常用页面置换算法、按访问频率来淘汰)

    LRU缓存算法的核心数据结构:哈希表 + 双向链表

    设计的cache需要满足的条件:O(1)查询、O(1)修改、有顺序之分。

    哈希表查找快,无序;链表有序,但查找慢。所以结合一下,哈希+链表,借助哈希表赋予链表快速查找的特性。

    二、典型例题

    ☆☆①:设计和实现一个LRU缓存机制(LC146)

    方法1:使用LinkedHashMap。属于取巧,面试不大行。。

    方法2:HashMap + 手写DoubleList。

    方法1:(需要理解LinkedHashMap的源码)

    LinkedHashMap的有序可以按两种顺序排列,一种是按照插入的顺序,一种是按照读取的顺序。其内部是靠 建立一个双向链表 来维护这个顺序的。

    构造函数:主要是两个构造方法,一个继承HashMap,一个是可选择accessOrder的值(默认false,代表按照插入顺序排序)来确定是按插入顺序还是读取顺序排序。

    class LRUCache extends LinkedHashMap<Integer,Integer> {
        /**
         * LinkedHashMap的构造函数之一。
         * 这里的 accessOrder 默认是为false,如果要按读取顺序排序需要将其设为 true
         * initialCapacity 代表 map 的 容量,loadFactor 代表加载因子 (默认即可)
         *     public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
         *         super(initialCapacity, loadFactor);
         *         this.accessOrder = accessOrder;
         *     }
         */
        private int capacity;
        public LRUCache(int capacity) {
            super(capacity,0.75f,true);
            this.capacity = capacity;
        }
        public int get(int key) {
            return super.getOrDefault(key, -1);
        }
        public void put(int key, int value) {
            super.put(key,value);
        }
        @Override
        protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
            return size() > capacity;
        }
    }

    方法2:HashMap + 手写DoubleList。

    参考1、 LRU策略详解和实现

    参考2、哈希表 + 双向链表

    M.  涉及链表操作细节较多,很具有综合性,以后一定手写完成!!

  • 相关阅读:
    ubuntu下内核源码树的建立
    删除ubuntu旧版本内核
    设置ubuntu12.04桌面版开机进入命令行模式
    MFC学习笔记(一)向模态对话框传递数据
    redis 映射数据结构粗略
    redis入门
    mybatis总结
    mybatis--mapper配置总结
    mybatis-初步使用
    maven-plugins说明
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14061336.html
Copyright © 2011-2022 走看看