MST

星途 面试题库

面试题:Go函数缓存之基础设计

在Go语言中,如果要设计一个简单的函数缓存,用于缓存某个计算密集型函数的结果,该函数接收两个整数参数并返回一个整数结果。请描述实现思路,并编写一个简单示例代码,要求考虑缓存的基本读写逻辑以及避免缓存穿透问题。
26.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 使用map作为缓存:Go语言中的map可以方便地存储键值对,这里键可以是由两个整数参数组成的唯一标识,值是对应的计算结果。
  2. 缓存读写逻辑:在调用计算密集型函数前,先检查缓存中是否存在对应结果。如果存在,直接返回缓存中的值;如果不存在,则调用函数计算结果,并将结果存入缓存。
  3. 避免缓存穿透:缓存穿透是指查询一个不存在的数据,每次都绕过缓存直接查询数据库等数据源。为了避免在计算密集型函数场景下的类似问题,可以在缓存中设置一个特殊标识,标识某个键对应的数据不存在,当查询到这个标识时,不再调用计算函数。

示例代码

package main

import (
    "fmt"
)

// 定义缓存
var cache = make(map[string]int)

// 计算密集型函数
func computeIntensiveFunction(a, b int) int {
    // 模拟复杂计算
    result := a + b
    return result
}

// 获取计算结果,优先从缓存中获取
func getComputedResult(a, b int) int {
    key := fmt.Sprintf("%d-%d", a, b)
    if val, ok := cache[key]; ok {
        if val != -1 {
            return val
        }
    } else {
        result := computeIntensiveFunction(a, b)
        cache[key] = result
        return result
    }
    // 处理缓存中标识不存在的情况
    return -1
}

func main() {
    a, b := 3, 5
    result := getComputedResult(a, b)
    fmt.Printf("计算结果: %d\n", result)

    // 再次获取,从缓存中获取
    result = getComputedResult(a, b)
    fmt.Printf("再次获取的计算结果: %d\n", result)
}

在上述代码中:

  1. cache是一个全局的map用于缓存计算结果。
  2. computeIntensiveFunction模拟一个计算密集型函数,这里简单地返回两个整数的和。
  3. getComputedResult函数先检查缓存中是否有对应结果,如果有则直接返回;如果没有则调用computeIntensiveFunction计算并缓存结果。同时,对于不存在的数据,通过设置值为-1作为标识,避免重复计算不存在的数据。
  4. main函数演示了如何使用这些函数,首次调用计算并缓存结果,再次调用直接从缓存获取结果。