MST

星途 面试题库

面试题:Go语言切片在并发环境下的动态管理

假设你正在开发一个多 goroutine 并发操作切片的程序,在动态添加和删除切片元素的过程中,如何保证数据的一致性和程序的正确性?请给出具体的实现思路和关键代码片段。
19.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 使用sync.Mutex来保护对切片的操作。在添加或删除切片元素前,先获取锁,操作完成后释放锁,这样可以避免多个 goroutine 同时修改切片导致的数据竞争。
    • 也可以使用sync.RWMutex,如果读操作较多,写操作较少,读操作时使用读锁,写操作时使用写锁,能提高并发性能。因为读操作之间不互斥,只有读操作和写操作、写操作和写操作之间互斥。
  2. 关键代码片段(使用sync.Mutex
package main

import (
    "fmt"
    "sync"
)

var (
    dataSlice []int
    mu        sync.Mutex
)

func addElement(num int) {
    mu.Lock()
    dataSlice = append(dataSlice, num)
    mu.Unlock()
}

func removeElement(index int) {
    mu.Lock()
    if index < len(dataSlice) {
        dataSlice = append(dataSlice[:index], dataSlice[index+1:]...)
    }
    mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    // 模拟多个 goroutine 并发操作
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            addElement(n)
        }(i)
    }
    wg.Wait()
    fmt.Println("Final slice:", dataSlice)
}
  1. 关键代码片段(使用sync.RWMutex,示例只展示添加操作,删除操作类似,加写锁)
package main

import (
    "fmt"
    "sync"
)

var (
    dataSlice []int
    rwMu      sync.RWMutex
)

func addElement(num int) {
    rwMu.Lock()
    dataSlice = append(dataSlice, num)
    rwMu.Unlock()
}

func readElement() {
    rwMu.RLock()
    fmt.Println("Reading slice:", dataSlice)
    rwMu.RUnlock()
}

func main() {
    var wg sync.WaitGroup
    // 模拟多个 goroutine 并发操作
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            addElement(n)
        }(i)
    }
    wg.Wait()
    readElement()
}