MST

星途 面试题库

面试题:Go语言并发场景下切片slice边界处理

在一个多协程并发访问和修改切片的场景中,有一个全局切片`globalSlice := make([]int, 10)`。多个协程会对这个切片进行读和写操作,例如有的协程会向切片中追加元素,有的协程会根据索引修改切片中的值。请设计一个方案来确保在并发环境下,切片的边界处理始终正确,避免出现越界、数据竞争等问题。请详细阐述你所采用的同步机制以及如何在这种机制下处理切片的边界情况。
36.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 采用的同步机制
    • 使用sync.Mutex来保证对globalSlice的读写操作的原子性,避免数据竞争。sync.Mutex是Go语言标准库中提供的互斥锁,它可以保证同一时间只有一个协程能够访问被保护的资源。
  2. 处理切片边界情况
    • 追加元素

      var mu sync.Mutex
      globalSlice := make([]int, 10)
      func appendToSlice(newValue int) {
          mu.Lock()
          defer mu.Unlock()
          globalSlice = append(globalSlice, newValue)
      }
      

      在追加元素前,先获取锁,这样其他协程不能同时进行追加或修改操作。追加操作本身是安全的,因为Go语言的append函数会自动处理切片的扩容等边界情况。

    • 根据索引修改值

      func setValueAtIndex(index, value int) {
          mu.Lock()
          defer mu.Unlock()
          if index < 0 || index >= len(globalSlice) {
              // 处理越界情况,这里简单返回,实际应用中可以根据需求处理,比如记录日志等
              return
          }
          globalSlice[index] = value
      }
      

      在根据索引修改值前,同样先获取锁。然后检查索引是否越界,如果越界则不进行操作并处理越界情况,在获取锁的情况下,其他协程不能修改切片长度,所以可以保证索引判断的正确性。

    • 读取切片元素

      func getValueAtIndex(index int) int {
          mu.Lock()
          defer mu.Unlock()
          if index < 0 || index >= len(globalSlice) {
              // 处理越界情况,这里简单返回0,实际应用中可以根据需求处理
              return 0
          }
          return globalSlice[index]
      }
      

      读取操作也需要获取锁,以防止在读取过程中切片被其他协程修改。同样要检查索引是否越界,确保不会读取到无效数据。

通过这种方式,利用sync.Mutex保证了切片操作的原子性,同时在操作前检查边界条件,避免了越界问题,从而确保在并发环境下切片操作的正确性。