MST

星途 面试题库

面试题:Go语言切片动态数组在并发场景下的高效操作

在高并发环境中,多个协程同时对一个切片进行读写操作,可能会出现数据竞争问题。描述一种利用Go语言特性,实现高效且线程安全的切片动态数组操作方案,并说明该方案在性能和资源消耗方面的优势与不足。
47.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

方案

在Go语言中,可以使用sync.Mutexsync.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
}

优势

  1. 性能
    • 读性能高:读操作使用读锁,多个协程可以同时进行读操作,提升了读的并发性能。例如在大量读少量写的场景下,使用sync.RWMutex相比于sync.Mutex能显著提高效率,因为sync.Mutex同一时间只允许一个协程操作,而sync.RWMutex允许多个读协程同时进行。
    • 写性能尚可:虽然写操作需要获取写锁,同一时间只能有一个写操作,但对于一般的写操作频率不是极高的场景,性能也能满足需求。
  2. 资源消耗
    • 资源消耗低:使用sync.RWMutex这种简单的同步机制,在资源消耗方面相对较少,不需要引入复杂的分布式锁等机制,减少了系统资源的开销。

不足

  1. 性能
    • 写操作阻塞读操作:当有写操作时,读操作会被阻塞,直到写操作完成。如果写操作频繁,读操作的响应时间会变长。例如在某些实时性要求高的读场景下,可能会影响系统的实时性。
    • 写操作性能瓶颈:对于写操作非常频繁的场景,同一时间只能有一个写操作,可能会成为性能瓶颈。
  2. 资源消耗
    • 锁竞争开销:在高并发情况下,锁的竞争会导致额外的CPU开销。当大量协程同时竞争锁时,会增加系统的调度成本,降低整体性能。