面试题答案
一键面试设计思路
- 负载均衡:使用一个请求队列(channel)来存储所有的文件读写请求。每个节点(Goroutine)从这个队列中取出请求并处理,这样可以确保请求均匀分配到各个节点。
- 并发读写控制:使用读写锁(sync.RWMutex)来保证同一时间只有一个写操作,并且读操作在写操作完成后进行。
- 通知主程序:使用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()
}
在上述代码中:
File
结构体使用sync.RWMutex
来控制文件的读写操作。Node
函数是每个节点的处理逻辑,从requests
通道中取出请求并执行。- 在
main
函数中,启动多个节点,并向requests
通道中发送模拟的读写请求,最后等待所有节点完成任务。