极客兔兔Gee-Cache Day2

  • 接口型函数

    • // 定义接口
      type Getter interface {Get(key string) ([]byte, error)
      }// 定义函数
      type GetterFunc func(key string) ([]byte, error)// 实现接口
      func (f GetterFunc) Get(key string) ([]byte, error) {return f(key)
      }
      
    • 价值:能将普通的函数类型作为参数,也能将结构体作为参数,使用更为灵活

    • 例如:

      • // 若GetFromSource定义如下,需要传一个Getter作为参数
        func GetFromSource(getter Getter, key string) []byte
        // 1.传函数(匿名函数和非匿名函数,下面是匿名)
        // 将函数类型转换为GetterFunc,这是实现了Getter接口的,可以传
        GetFromSource(GetterFunc(func(key string) ([]byte, error) {return []byte(key), nil
        }), "hello")
        // 2.传结构体
        type DB struct{ url string}
        func (db *DB) Get(key string) ([]byte, error) {// ...return []byte(v), nil
        }
        func main() {GetFromSource(new(DB), "hello")
        }
        
    • net/http包下的Handler就是使用这种特性

      • type Handler interface {ServeHTTP(ResponseWriter, *Request)
        }
        type HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r)
        }
        
  • sync.Mutex:Go 语言标准库提供的一个互斥锁,当一个协程(goroutine)获得了这个锁的拥有权后,其它请求锁的协程(goroutine) 就会阻塞在 Lock() 方法的调用上,直到调用 Unlock() 锁被释放。

  • reflect.DeepEqual()

    • 对于基本数据类型(整数、布尔、字符串),与==相同
    • 可以比较数组、切片、结构体、map、接口等是否相同
    • 对于切片,必须切片长度相等且顺序相同,元素相同
  • day2由四个文件组成,分别是lru.gobyteview.gocache.gogeecache.go

    • lru.golru缓存淘汰策略

    • byteview.go:缓存值,实现了Value接口

    • cache.go:并发控制

    • geecache.go:与外部交互,在缓存未命中时去查找数据源

    • cache.goday1中的lru加入了锁机制,实现并发下的互斥访问,geecache.go中实现了Group结构体,其中包含cache和回调函数,在cache未命中时会调用回调函数查找数据库中的内容,同时,使用map结构分配多个缓存,用name进行区分,每个Group有一个唯一的name(例如学生成绩和学生课程的缓存使用不同的name区分)

    • 代码

      // ---------------------------------------------------------------------------------------
      // ByteView.go 缓存元素的抽象
      package gee// 只读数据结构 表示缓存值,实现了Value接口
      type ByteView struct {b []byte
      }func (v ByteView) Len() int {return len(v.b)
      }func (v ByteView) ByteSlice() []byte {return cloneBytes(v.b)
      }func cloneBytes(b []byte) []byte {c := make([]byte, len(b))copy(c, b)return c
      }func (v ByteView) String() string {return string(v.b)
      }
      // cache.go 对day1中的lru加上并发控制
      package gee
      // ---------------------------------------------------------------------------------------
      // 实现并发控制
      import ("sync"
      )type cache struct {mu         sync.Mutexlru        *CachecacheBytes int64
      }func (c *cache) add(key string, value ByteView) {c.mu.Lock()defer c.mu.Unlock()if c.lru == nil { // 延迟初始化c.lru = New(c.cacheBytes, nil)}c.lru.Add(key, value)
      }func (c *cache) get(key string) (value ByteView, ok bool) {c.mu.Lock()defer c.mu.Unlock()if c.lru == nil {return}if v, ok := c.lru.Get(key); ok {return v.(ByteView), ok}return
      }
      // ---------------------------------------------------------------------------------------
      // geecache.go 与源数据库进行交互
      package gee// 实现与外部交互
      import ("fmt""sync"
      )type Getter interface {Get(key string) ([]byte, error)
      }type GetterFunc func(key string) ([]byte, error)// 接口型函数
      func (f GetterFunc) Get(key string) ([]byte, error) {return f(key)
      }type Group struct {name      string // 缓存名称getter    Getter // 回调函数mainCache cache  // 缓存
      }var (mu     sync.Mutexgroups = make(map[string]*Group)
      )func NewGroup(name string, cacheBytes int64, getter Getter) *Group {if getter == nil {panic("Getter nil")}mu.Lock()defer mu.Unlock()g := &Group{name:      name,getter:    getter,mainCache: cache{cacheBytes: cacheBytes},}groups[name] = greturn g
      }func GetGroup(name string) *Group {mu.Lock()defer mu.Unlock()g := groups[name]return g
      }func (g *Group) Get(key string) (ByteView, error) {if key == "" {return ByteView{}, fmt.Errorf("key is nil")}if v, ok := g.mainCache.get(key); ok {fmt.Println("Gee Cache hit")return v, nil}return g.load(key)
      }func (g *Group) load(key string) (Value ByteView, err error) {return g.getLocally(key)
      }// 调用回调函数,去源数据库查找内容
      func (g *Group) getLocally(key string) (ByteView, error) { bytes, err := g.getter.Get(key)if err != nil {return ByteView{}, err}value := ByteView{b: cloneBytes(bytes)}g.add(key, value)return value, nil}func (g *Group) add(key string, value ByteView) {g.mainCache.add(key, value)
      }

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gm/ID设计方法学习笔记(一)

前言&#xff1a;为什么需要gm/id &#xff08;一&#xff09;主流设计方法往往侧重于强反型区&#xff08;过驱>0.2V&#xff09;&#xff0c;低功耗设计则侧重于弱反型区&#xff08;<0&#xff09;&#xff0c;但现在缺乏对中反型区的简单和准确的手算模型。 1.对于…

10月2日笔记(内网资源探测篇)

内网资源探测 在内网渗透中&#xff0c;测试人员往往需要通过各种内网扫描技术来探测内网资源的情况&#xff0c;为后续的横向渗透做准备&#xff0c;通常需要发现内网存活的主机&#xff0c;并探测主机的操作系统、主机开放了哪些端口、端口上运行了哪些服务、服务的当前版本…

SQL SERVER 从嫌弃存储到爱上存储过程我给存储过程开发了版本控制工具和远程调试功能...

优缺点 SQL SERVER 爱上存储过程我给存储过程开发了版本控制工具和远程调试功能 先说说 存储过程的优缺点吧存储过程的优点 提高执行效率&#xff1a;存储过程是预编译的&#xff0c;执行速度较快&#xff0c;减少了网络传输量。 减少开发工作量&#xff1a;存储过程可以将复杂…

数据结构——对顺序线性表的操作

大家好啊&#xff0c;今天给大家分享一下对于顺序线性表的相关操作&#xff0c;跟随我的步伐来开始这一篇的学习吧&#xff01; 如果有知识性错误&#xff0c;欢迎各位指正&#xff01;&#xff01;一起加油&#xff01;&#xff01; 创作不易&#xff0c;希望大家多多支持哦…

中级软件设计师:一文搞懂下午第一题——数据流图技术

中级软件设计师&#xff1a;一文搞懂下午第一题——数据流图技术 0. 答题技巧-【11-12分】分必拿方法0. 本章的考点1. 数据流图的基本元素1.1 数据流1.2 加工1.3 数据存储(文件)1.4 外部实体1.5 分层数据流图&#xff08;DFD&#xff09;1.6 自顶至下&#xff0c;逐步精化1.6.1…

8645 归并排序(非递归算法)

### 思路 非递归归并排序通过逐步合并相邻的子数组来实现排序。每次合并后输出当前排序结果。 ### 伪代码 1. 读取输入的待排序关键字个数n。 2. 读取n个待排序关键字并存储在数组中。 3. 对数组进行非递归归并排序&#xff1a; - 初始化子数组的大小curr_size为1。 - 逐…

GO网络编程(二):客户端与服务端通信【重要】

本节是新知识&#xff0c;偏应用&#xff0c;需要反复练习才能掌握。 目录 1.C/S通信示意图2.服务端通信3.客户端通信4.通信测试5.进阶练习&#xff1a;客户端之间通信 1.C/S通信示意图 客户端与服务端通信的模式也称作C/S模式&#xff0c;流程图如下 其中P是协程调度器。可…

使用VBA快速生成Excel工作表非连续列图片快照

Excel中示例数据如下图所示。 现在需要拷贝A2:A15,D2:D15,J2:J15,L2:L15,R2:R15为图片&#xff0c;然后粘贴到A18单元格&#xff0c;如下图所示。 大家都知道VBA中Range对象有CopyPicture方法可以拷贝为图片&#xff0c;但是如果Range对象为非连续区域&#xff0c;那么将产生10…

Web安全 - 安全防御工具和体系构建

文章目录 安全标准和框架1. 国内安全标准&#xff1a;等级保护制度&#xff08;等保&#xff09;2. 国际安全标准&#xff1a;ISO27000系列3. NIST安全框架&#xff1a;IDPRR方法4. COBIT与ITIL框架 防火墙防火墙的基本作用防火墙的三种主要类型防火墙的防护能力防火墙的盲区 W…

【MATLAB2024b】安装离线帮助文档(windows)

文章目录 一、在 MATLAB 设置中安装二、从math works 网站下载ISO&#xff1a;给无法联网的电脑安装三、重要说明 版本&#xff1a;matlab 2024b&#xff08;或者大于等于2023a&#xff09; 所需空间&#xff1a;10~15 GB 平台&#xff1a;Windows 需要注册math works账号。 一…

【计算机网络】详解UDP协议格式特点缓冲区

一、UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度&#xff1b;如果16位UDP检验和出错&#xff0c;报文会被直接丢弃。 1.1、检验和出错的几种常见情况 数据传输过程中的比特翻转&#xff1a;在数据传输过程中&#xff0c;由于物理介质或网络设…

UE5.4.3 录屏回放系统ReplaySystem蓝图版

这是ReplaySystem的蓝图使用方法版&#xff0c;以第三人称模版为例&#xff0c;需要几个必须步骤 项目config内DefaultEngine.ini的最后添加&#xff1a; [/Script/Engine.GameEngine] NetDriverDefinitions(DefName"DemoNetDriver",DriverClassName"/Script/…

二、Spring Boot集成Spring Security之实现原理

Spring Boot集成Spring Security之实现原理 一、Spring Security实现原理概要介绍二、使用WebSecurityConfiguration向Spring容器中注册FilterChainProxy类型的对象springSecurityFilterChain1、未配置securityFilterChain过滤器链时使用默认配置用于生成默认securityFilterCha…

JDBC 快速入门

JDBC 快速入门 搭建步骤代码实现数据库java 代码 搭建步骤 准备数据库官网下载数据库连接驱动jar 包。https://downloads.mysql.com/archives/c-j/创建 java 项目&#xff0c;在项目下创建 lib 文件夹&#xff0c;将下载的驱动 jar 包复制到文件夹里选中 lib 文件夹右键 ->…

第二十一章 (动态内存管理)

1. 为什么要有动态内存分配 2. malloc和free 3. calloc和realloc 4. 常⻅的动态内存的错误 5. 动态内存经典笔试题分析 6. 总结C/C中程序内存区域划分 1.为什么要有动态内存管理 我们目前已经掌握的内存开辟方式有 int main() {int num 0; //开辟4个字节int arr[10] …

【EXCEL数据处理】000009 案列 EXCEL单元格数字格式。文本型数字格式和常规型数字格式的区别

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000009 案列 EXCEL单元格数字格式。文本型数字格式和…

CTK框架(十一):使用的常见问题

目录 1.MF文件路径 2.服务必须要接口类 3.插件名命名要求 4.生命周期问题 5.一个接口对多个实现注意 6.中文输出注意 7.同一插件安装注意 8.添加元数据 9.关于升级插件时遇到的问题 10.不同插件定义资源文件注意路径问题 11.安装插件 12.插件依赖 1.MF文件路径 在…

K8S:开源容器编排平台,助力高效稳定的容器化应用管理

云计算de小白 Kubernetes&#xff08;简称K8s&#xff09;是一个开源容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序。 K8S诞生于Google&#xff0c;基于其多年在生产环境运行容器的经验&#xff0c;目前已成为现代微服务架构和云原生应用的核心技术。 图…

【C++算法】10.滑动窗口_长度最小的子数组

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 209. 长度最小的子数组 题目描述&#xff1a; 解法 解法一&#xff1a;暴力求解&#xff08;会超时&#xff09; 暴力枚举出所有子数组的和。 查找子数组n2&#xff0…

云计算 Cloud Computing

文章目录 1、云计算2、背景3、云计算的特点4、云计算的类型&#xff1a;按提供的服务划分5、云计算的类型&#xff1a;按部署的形式划分 1、云计算 定义&#xff1a; 云计算是一种按使用量付费的模式&#xff0c;这种模式提供可用的、便捷的、按需的网络访问&#xff0c;进入可…