MST

星途 面试题库

面试题:Go语言指针在并发场景下的内存管理及安全问题

假设你正在开发一个高并发的Go程序,其中涉及多个goroutine同时访问和修改共享内存中的指针指向的数据。请描述可能会出现哪些内存管理相关的问题,如竞态条件等。并说明如何使用Go语言提供的工具(如sync包)来解决这些问题,给出具体的代码示例。
38.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

可能出现的内存管理问题

  1. 竞态条件:多个goroutine同时读写共享内存中的指针指向的数据,会导致数据竞争,最终结果不可预测。例如一个goroutine读取数据时,另一个goroutine同时在修改该数据,可能导致读取到不一致的数据。

使用sync包解决问题

  1. 使用sync.Mutexsync.Mutex用于保护共享资源,确保同一时间只有一个goroutine能够访问共享内存。
package main

import (
    "fmt"
    "sync"
)

type Data struct {
    value int
}

var mu sync.Mutex
var dataPtr *Data

func modifyData(wg *sync.WaitGroup) {
    defer wg.Done()
    mu.Lock()
    if dataPtr == nil {
        dataPtr = &Data{value: 0}
    }
    dataPtr.value++
    mu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    numGoroutines := 10
    for i := 0; i < numGoroutines; i++ {
        wg.Add(1)
        go modifyData(&wg)
    }
    wg.Wait()
    mu.Lock()
    fmt.Printf("Final value: %d\n", dataPtr.value)
    mu.Unlock()
}
  1. 使用sync.RWMutex: 如果读操作远多于写操作,可以使用sync.RWMutex。它允许多个goroutine同时进行读操作,但写操作时会独占资源。
package main

import (
    "fmt"
    "sync"
)

type Data struct {
    value int
}

var rwmu sync.RWMutex
var dataPtr *Data

func readData(wg *sync.WaitGroup) {
    defer wg.Done()
    rwmu.RLock()
    if dataPtr != nil {
        fmt.Printf("Read value: %d\n", dataPtr.value)
    }
    rwmu.RUnlock()
}

func writeData(wg *sync.WaitGroup) {
    defer wg.Done()
    rwmu.Lock()
    if dataPtr == nil {
        dataPtr = &Data{value: 0}
    }
    dataPtr.value++
    rwmu.Unlock()
}

func main() {
    var wg sync.WaitGroup
    numReaders := 5
    numWriters := 3
    for i := 0; i < numReaders; i++ {
        wg.Add(1)
        go readData(&wg)
    }
    for i := 0; i < numWriters; i++ {
        wg.Add(1)
        go writeData(&wg)
    }
    wg.Wait()
}