面试题答案
一键面试使用读写锁优化Go语言Map在高并发场景下的性能
- 原理:读写锁(
sync.RWMutex
)可以区分读操作和写操作。多个读操作可以同时进行,而写操作则需要独占锁,这样可以在保证数据一致性的前提下,提高读操作的并发性能。 - 代码示例:
package main
import (
"fmt"
"sync"
)
var (
dataMap = make(map[string]int)
rwMutex sync.RWMutex
)
func read(key string) int {
rwMutex.RLock()
defer rwMutex.RUnlock()
return dataMap[key]
}
func write(key string, value int) {
rwMutex.Lock()
defer rwMutex.Unlock()
dataMap[key] = value
}
func main() {
var wg sync.WaitGroup
// 模拟多个写操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
key := fmt.Sprintf("key%d", index)
write(key, index)
}(i)
}
// 模拟多个读操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
key := fmt.Sprintf("key%d", index)
value := read(key)
fmt.Printf("Read key: %s, value: %d\n", key, value)
}(i)
}
wg.Wait()
}
使用sync.Map优化性能
- 原理:
sync.Map
是Go语言标准库提供的一个线程安全的map。它内部采用了分段锁等机制,在高并发场景下可以提供更好的性能,并且无需用户手动管理锁。 - 代码示例:
package main
import (
"fmt"
"sync"
)
var syncData sync.Map
func syncRead(key string) (int, bool) {
value, ok := syncData.Load(key)
if ok {
return value.(int), true
}
return 0, false
}
func syncWrite(key string, value int) {
syncData.Store(key, value)
}
func main() {
var wg sync.WaitGroup
// 模拟多个写操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
key := fmt.Sprintf("key%d", index)
syncWrite(key, index)
}(i)
}
// 模拟多个读操作
for i := 0; i < 5; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
key := fmt.Sprintf("key%d", index)
value, ok := syncRead(key)
if ok {
fmt.Printf("Sync Read key: %s, value: %d\n", key, value)
}
}(i)
}
wg.Wait()
}
避免内存泄漏及优化内存使用效率
- 及时删除不再使用的键值对:在使用普通map加读写锁时,要及时删除不再使用的键值对,防止map不断膨胀。例如:
func deleteKey(key string) {
rwMutex.Lock()
defer rwMutex.Unlock()
delete(dataMap, key)
}
- sync.Map的清理:
sync.Map
没有直接的删除所有元素的方法,但可以通过遍历并删除的方式来清理。例如:
func clearSyncMap() {
syncData.Range(func(key, value interface{}) bool {
syncData.Delete(key)
return true
})
}
- 合理预分配内存:在初始化map时,如果能预估数据量,可以预先分配一定的内存空间,减少动态扩容带来的性能开销和内存碎片。例如:
dataMap = make(map[string]int, 1000)
通过以上方法,可以在高并发频繁读写操作下,优化Go语言Map的性能,避免内存泄漏并提高内存使用效率。