面试题答案
一键面试package main
import (
"fmt"
"sync"
)
type SafeSlice struct {
data []int
mu sync.Mutex
}
func (s *SafeSlice) Append(num int) {
s.mu.Lock()
defer s.mu.Unlock()
s.data = append(s.data, num)
}
func (s *SafeSlice) Read() []int {
s.mu.Lock()
defer s.mu.Unlock()
result := make([]int, len(s.data))
copy(result, s.data)
return result
}
func main() {
safeSlice := SafeSlice{}
var wg sync.WaitGroup
// 模拟多个并发写入
for i := 0; i < 5; i++ {
wg.Add(1)
go func(num int) {
defer wg.Done()
safeSlice.Append(num)
}(i)
}
// 等待所有写入完成
go func() {
wg.Wait()
data := safeSlice.Read()
fmt.Println("Final data:", data)
}()
// 防止主线程退出
select {}
}
在上述代码中:
- 定义了一个
SafeSlice
结构体,包含一个存放整数的切片data
和一个互斥锁mu
。 Append
方法用于向切片中追加数据,在操作前加锁,操作完成后解锁,保证写入操作的原子性。Read
方法用于读取切片数据,同样在操作前加锁,操作完成后解锁。这里通过复制切片内容来返回,避免返回内部切片导致外部直接修改。- 在
main
函数中,模拟了多个并发的写入操作,并在所有写入完成后读取数据并打印。select {}
用于防止主线程过早退出。