面试题答案
一键面试实现思路
- 使用map作为缓存:Go语言中的map可以方便地存储键值对,这里键可以是由两个整数参数组成的唯一标识,值是对应的计算结果。
- 缓存读写逻辑:在调用计算密集型函数前,先检查缓存中是否存在对应结果。如果存在,直接返回缓存中的值;如果不存在,则调用函数计算结果,并将结果存入缓存。
- 避免缓存穿透:缓存穿透是指查询一个不存在的数据,每次都绕过缓存直接查询数据库等数据源。为了避免在计算密集型函数场景下的类似问题,可以在缓存中设置一个特殊标识,标识某个键对应的数据不存在,当查询到这个标识时,不再调用计算函数。
示例代码
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)
}
在上述代码中:
cache
是一个全局的map用于缓存计算结果。computeIntensiveFunction
模拟一个计算密集型函数,这里简单地返回两个整数的和。getComputedResult
函数先检查缓存中是否有对应结果,如果有则直接返回;如果没有则调用computeIntensiveFunction
计算并缓存结果。同时,对于不存在的数据,通过设置值为-1
作为标识,避免重复计算不存在的数据。main
函数演示了如何使用这些函数,首次调用计算并缓存结果,再次调用直接从缓存获取结果。