MST

星途 面试题库

面试题:Go接口与泛型编程 - 复杂场景运用

设计一个Go语言程序,使用接口和泛型实现一个通用的缓存系统。缓存系统需要支持多种数据类型的缓存(通过泛型实现),并且能够动态添加和删除缓存项。接口部分需要定义缓存操作的基本方法,如`Set(key, value)`,`Get(key)`,`Delete(key)`。在实现过程中,要考虑并发安全问题,并且要合理使用Go的特性来优化性能。请详细描述设计思路,并给出核心代码实现。
25.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 接口定义:定义一个通用的缓存接口,包含SetGetDelete方法,这些方法将作为缓存操作的标准接口。
  2. 泛型实现:使用Go 1.18引入的泛型来支持多种数据类型的缓存。这样可以在编译时确保类型安全,同时减少重复代码。
  3. 并发安全:使用sync.RWMutex来保证缓存操作的并发安全性。读操作使用读锁,写操作使用写锁,以避免数据竞争。
  4. 性能优化:使用Go的map数据结构来存储缓存数据,因为map在查找、插入和删除操作上具有较好的性能。同时,合理使用锁机制,尽量减少锁的粒度,提高并发性能。

核心代码实现

package main

import (
    "fmt"
    "sync"
)

// 定义缓存接口
type CacheInterface[K comparable, V any] interface {
    Set(key K, value V)
    Get(key K) (V, bool)
    Delete(key K)
}

// 缓存结构体
type Cache[K comparable, V any] struct {
    data map[K]V
    mu   sync.RWMutex
}

// 创建新的缓存实例
func NewCache[K comparable, V any]() *Cache[K, V] {
    return &Cache[K, V]{
        data: make(map[K]V),
    }
}

// 设置缓存项
func (c *Cache[K, V]) Set(key K, value V) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.data[key] = value
}

// 获取缓存项
func (c *Cache[K, V]) Get(key K) (V, bool) {
    c.mu.RLock()
    defer c.mu.RUnlock()
    value, exists := c.data[key]
    return value, exists
}

// 删除缓存项
func (c *Cache[K, V]) Delete(key K) {
    c.mu.Lock()
    defer c.mu.Unlock()
    delete(c.data, key)
}

使用示例

func main() {
    // 创建一个字符串到整数的缓存
    cache := NewCache[string, int]()

    // 设置缓存项
    cache.Set("key1", 100)

    // 获取缓存项
    value, exists := cache.Get("key1")
    if exists {
        fmt.Printf("Value for key1: %d\n", value)
    } else {
        fmt.Println("Key not found")
    }

    // 删除缓存项
    cache.Delete("key1")

    // 再次获取缓存项
    value, exists = cache.Get("key1")
    if exists {
        fmt.Printf("Value for key1: %d\n", value)
    } else {
        fmt.Println("Key not found")
    }
}