面试题答案
一键面试设计思路
- 使用互斥锁(Mutex):互斥锁可以确保在同一时间只有一个协程能够对切片进行操作,从而保证数据的一致性。但是,如果频繁使用互斥锁,会导致性能瓶颈,因为其他协程需要等待锁的释放。
- 结合通道(Channel):通道可以用于协程之间的通信和同步。通过将切片的操作任务发送到一个专门的协程中,由这个协程来处理所有的切片合并与拆分操作,这样可以减少锁的竞争。同时,利用通道的缓冲机制,可以在一定程度上提高性能。
关键代码片段
package main
import (
"fmt"
"sync"
)
// 定义一个结构体来表示切片操作任务
type SliceTask struct {
operation string
data []int
}
func sliceProcessor(taskChan chan SliceTask, wg *sync.WaitGroup) {
var result []int
var mu sync.Mutex
defer wg.Done()
for task := range taskChan {
mu.Lock()
switch task.operation {
case "merge":
result = append(result, task.data...)
case "split":
// 这里假设简单地按照一半拆分
mid := len(task.data) / 2
left := task.data[:mid]
right := task.data[mid:]
// 这里可以进一步处理拆分后的逻辑,比如发送到其他通道
fmt.Println("Split result: left:", left, "right:", right)
}
mu.Unlock()
}
}
在主程序中使用如下:
func main() {
var wg sync.WaitGroup
taskChan := make(chan SliceTask)
wg.Add(1)
go sliceProcessor(taskChan, &wg)
// 模拟发送任务
task1 := SliceTask{operation: "merge", data: []int{1, 2, 3}}
taskChan <- task1
task2 := SliceTask{operation: "split", data: []int{4, 5, 6, 7}}
taskChan <- task2
close(taskChan)
wg.Wait()
}
在上述代码中:
SliceTask
结构体用于封装切片操作任务,包括操作类型(合并或拆分)和相关的数据。sliceProcessor
协程负责处理从taskChan
通道接收到的任务。它使用互斥锁mu
来保护对result
切片的操作,确保数据一致性。- 在
main
函数中,创建了taskChan
通道和sliceProcessor
协程,并向通道发送切片操作任务。最后关闭通道并等待sliceProcessor
协程完成任务。