面试题答案
一键面试方案
在Go语言中,可以使用sync.Mutex
或sync.RWMutex
来实现线程安全的切片动态数组操作。以sync.RWMutex
为例,读操作使用读锁,写操作使用写锁,示例代码如下:
package main
import (
"fmt"
"sync"
)
type SafeSlice struct {
data []int
mutex sync.RWMutex
}
func (s *SafeSlice) Append(num int) {
s.mutex.Lock()
s.data = append(s.data, num)
s.mutex.Unlock()
}
func (s *SafeSlice) Get(index int) (int, bool) {
s.mutex.RLock()
defer s.mutex.RUnlock()
if index < 0 || index >= len(s.data) {
return 0, false
}
return s.data[index], true
}
优势
- 性能:
- 读性能高:读操作使用读锁,多个协程可以同时进行读操作,提升了读的并发性能。例如在大量读少量写的场景下,使用
sync.RWMutex
相比于sync.Mutex
能显著提高效率,因为sync.Mutex
同一时间只允许一个协程操作,而sync.RWMutex
允许多个读协程同时进行。 - 写性能尚可:虽然写操作需要获取写锁,同一时间只能有一个写操作,但对于一般的写操作频率不是极高的场景,性能也能满足需求。
- 读性能高:读操作使用读锁,多个协程可以同时进行读操作,提升了读的并发性能。例如在大量读少量写的场景下,使用
- 资源消耗:
- 资源消耗低:使用
sync.RWMutex
这种简单的同步机制,在资源消耗方面相对较少,不需要引入复杂的分布式锁等机制,减少了系统资源的开销。
- 资源消耗低:使用
不足
- 性能:
- 写操作阻塞读操作:当有写操作时,读操作会被阻塞,直到写操作完成。如果写操作频繁,读操作的响应时间会变长。例如在某些实时性要求高的读场景下,可能会影响系统的实时性。
- 写操作性能瓶颈:对于写操作非常频繁的场景,同一时间只能有一个写操作,可能会成为性能瓶颈。
- 资源消耗:
- 锁竞争开销:在高并发情况下,锁的竞争会导致额外的CPU开销。当大量协程同时竞争锁时,会增加系统的调度成本,降低整体性能。