MST

星途 面试题库

面试题:Go语言中Goroutine、Sync包原语与复杂业务逻辑的结合

设计一个分布式文件系统的简单模型。有多个节点(用Goroutine模拟),每个节点可以处理文件读写请求。使用Go的同步原语(如Mutex、WaitGroup、Channel等)来实现:1. 节点间的负载均衡,确保每个节点处理的请求数量大致相同。2. 对文件的并发读写控制,保证读操作在写操作完成后进行,且同一时间只有一个写操作。3. 当所有节点都完成当前批次的请求后,通知主程序。请描述设计思路并给出关键代码片段。
48.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 负载均衡:使用一个请求队列(channel)来存储所有的文件读写请求。每个节点(Goroutine)从这个队列中取出请求并处理,这样可以确保请求均匀分配到各个节点。
  2. 并发读写控制:使用读写锁(sync.RWMutex)来保证同一时间只有一个写操作,并且读操作在写操作完成后进行。
  3. 通知主程序:使用WaitGroup来等待所有节点完成当前批次的请求。每个节点完成请求后,调用WaitGroup的Done方法,主程序调用Wait方法等待所有节点完成。

关键代码片段

package main

import (
    "fmt"
    "sync"
)

type File struct {
    data   string
    mu     sync.RWMutex
}

func (f *File) Read() string {
    f.mu.RLock()
    defer f.mu.RUnlock()
    return f.data
}

func (f *File) Write(data string) {
    f.mu.Lock()
    defer f.mu.Unlock()
    f.data = data
}

func Node(requests <-chan func(), wg *sync.WaitGroup) {
    defer wg.Done()
    for req := range requests {
        req()
    }
}

func main() {
    var wg sync.WaitGroup
    file := File{}
    numNodes := 3
    requests := make(chan func(), 100)

    // 启动节点
    for i := 0; i < numNodes; i++ {
        wg.Add(1)
        go Node(requests, &wg)
    }

    // 模拟请求
    requests <- func() { file.Write("new data") }
    requests <- func() { fmt.Println(file.Read()) }

    close(requests)
    wg.Wait()
}

在上述代码中:

  1. File结构体使用sync.RWMutex来控制文件的读写操作。
  2. Node函数是每个节点的处理逻辑,从requests通道中取出请求并执行。
  3. main函数中,启动多个节点,并向requests通道中发送模拟的读写请求,最后等待所有节点完成任务。