面试题答案
一键面试设计思路
- 资源竞争与数据同步:
- 使用互斥锁(
sync.Mutex
)来保护共享资源,防止多个协程同时访问和修改导致数据不一致。 - 利用通道(
chan
)进行协程间的通信和同步,以确保数据的有序传递和处理。
- 使用互斥锁(
- 结合Go语言并发模型:
- 对于多值返回,可以将返回值封装成一个结构体,然后通过通道传递这个结构体,避免多次传递不同的值带来的复杂性。
- 当需要等待多个协程完成时,可以使用
sync.WaitGroup
来同步。
代码示例
package main
import (
"fmt"
"sync"
)
// 定义多值返回的函数
func multiValueFunction() (int, string) {
return 42, "Hello, World!"
}
func main() {
var wg sync.WaitGroup
resultChan := make(chan struct {
num int
str string
}, 1)
// 启动协程
wg.Add(1)
go func() {
defer wg.Done()
num, str := multiValueFunction()
resultChan <- struct {
num int
str string
}{num, str}
}()
go func() {
wg.Wait()
close(resultChan)
}()
// 从通道接收结果
for result := range resultChan {
fmt.Printf("Number: %d, String: %s\n", result.num, result.str)
}
}
在上述代码中:
multiValueFunction
是一个简单的多值返回函数。- 在
main
函数中,我们创建了一个通道resultChan
,用于接收多值返回封装后的结果。 - 启动一个协程来调用
multiValueFunction
,并将返回值封装后发送到通道中。 - 使用
sync.WaitGroup
来等待协程完成,完成后关闭通道。 - 通过
for... range
循环从通道接收数据并处理,这样可以确保在协程完成工作后,主函数能够正确获取到多值返回的结果,同时避免资源竞争和实现数据同步。
如果涉及到共享资源的修改,例如以下情况:
package main
import (
"fmt"
"sync"
)
var sharedData int
var mu sync.Mutex
// 定义多值返回的函数
func multiValueFunction() (int, string) {
mu.Lock()
sharedData++
mu.Unlock()
return sharedData, "Hello, World!"
}
func main() {
var wg sync.WaitGroup
resultChan := make(chan struct {
num int
str string
}, 1)
// 启动协程
for i := 0; i < 3; i++ {
wg.Add(1)
go func() {
defer wg.Done()
num, str := multiValueFunction()
resultChan <- struct {
num int
str string
}{num, str}
}()
}
go func() {
wg.Wait()
close(resultChan)
}()
// 从通道接收结果
for result := range resultChan {
fmt.Printf("Number: %d, String: %s\n", result.num, result.str)
}
}
这里使用sync.Mutex
来保护sharedData
的修改,避免多个协程同时修改导致数据不一致。通过这种方式,在Go语言的并发编程场景中,对多值返回进行优化,确保资源的高效利用以及数据的一致性和同步。