MST

星途 面试题库

面试题:Go语言并发安全的复杂数据结构设计

设计一个并发安全的哈希表,要求支持在多个协程同时进行插入、删除和查询操作。请使用Go语言实现,并阐述在实现过程中如何利用原子操作和其他并发控制机制来确保数据的一致性和安全性。
40.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
    "sync"
    "sync/atomic"
)

type SafeMap struct {
    data map[string]int
    mu   sync.RWMutex
    count uint64
}

func NewSafeMap() *SafeMap {
    return &SafeMap{
        data: make(map[string]int),
    }
}

func (sm *SafeMap) Insert(key string, value int) {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    sm.data[key] = value
    atomic.AddUint64(&sm.count, 1)
}

func (sm *SafeMap) Delete(key string) {
    sm.mu.Lock()
    defer sm.mu.Unlock()
    delete(sm.data, key)
    atomic.AddUint64(&sm.count, ^uint64(0))
}

func (sm *SafeMap) Query(key string) (int, bool) {
    sm.mu.RLock()
    defer sm.mu.RUnlock()
    value, exists := sm.data[key]
    return value, exists
}

func (sm *SafeMap) Count() uint64 {
    return atomic.LoadUint64(&sm.count)
}

在实现过程中:

  1. 互斥锁(Mutex):使用sync.RWMutex来保护哈希表的数据。在插入和删除操作时,使用写锁(Lock),以确保同一时间只有一个协程可以修改哈希表,避免数据竞争。在查询操作时,使用读锁(RLock),允许多个协程同时进行查询,提高并发性能。
  2. 原子操作:使用atomic包中的函数来对元素个数进行原子操作。例如,在插入时使用atomic.AddUint64增加元素计数,删除时使用atomic.AddUint64减少元素计数,这样可以保证在并发环境下元素计数的准确性,不受其他协程干扰,确保数据的一致性和安全性。