面试题答案
一键面试设计思路
- 使用互斥锁:为了保证数据一致性,在对共享变量进行类型强制转换操作时,使用
sync.Mutex
来保护临界区。这样可以避免多个协程同时修改共享变量,导致数据竞争。 - 边界情况处理:对于
time.Duration
到int
的转换,要考虑time.Duration
值可能非常大的情况。time.Duration
是一个int64
类型,而int
类型的大小在不同平台可能不同(32位或64位)。因此,需要检查转换后的值是否会超出int
类型的范围。 - 性能优化:虽然互斥锁能保证数据一致性,但会降低并发性能。为了在一定程度上优化性能,可以尽量缩短临界区的代码,减少锁的持有时间。
关键部分代码示例
package main
import (
"fmt"
"sync"
"time"
)
var (
mu sync.Mutex
sharedVar time.Duration
)
func convertToInt() (int, error) {
mu.Lock()
defer mu.Unlock()
// 检查是否会超出int类型范围
if sharedVar > time.Duration(int(^uint(0)>>1)) || sharedVar < time.Duration(-(int(^uint(0)>>1)+1)) {
return 0, fmt.Errorf("time.Duration value is out of int range")
}
return int(sharedVar), nil
}
func main() {
sharedVar = 10 * time.Second
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
result, err := convertToInt()
if err != nil {
fmt.Println("Conversion error:", err)
} else {
fmt.Println("Converted value:", result)
}
}()
}
wg.Wait()
}
在这段代码中:
mu
是一个sync.Mutex
实例,用于保护共享变量sharedVar
。convertToInt
函数在对sharedVar
进行类型转换前,先获取锁,转换完成后释放锁。- 在转换前,通过比较
sharedVar
与int
类型的最大最小值,来检查是否会发生溢出。 - 在
main
函数中,模拟了10个协程同时调用convertToInt
函数的高并发场景。