MST

星途 面试题库

面试题:Go类型强制转换在复杂数据结构及并发场景下的应用

假设有一个复杂的`map[string]interface{}`类型的数据结构,其中`interface{}`可能存储了`int`、`float64`、`[]int`等不同类型的数据。在并发环境下,多个`goroutine`需要读取和修改这个`map`中的数据,并且根据不同的数据类型进行特定的计算(比如`int`类型做加法,`float64`类型做乘法等)。请设计一个方案,使用类型强制转换实现这个功能,并考虑如何处理并发安全问题,写出关键的代码逻辑和思路。
24.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 并发安全:使用sync.RWMutex来保证map的并发读写安全。RWMutex允许多个goroutine同时读,但只允许一个goroutine写。
  2. 类型断言:在读取map中的值后,通过类型断言判断其具体类型,然后进行相应的计算。

关键代码逻辑

package main

import (
	"fmt"
	"sync"
)

func main() {
	var mu sync.RWMutex
	data := make(map[string]interface{})

	// 模拟数据写入
	mu.Lock()
	data["intKey"] = 5
	data["floatKey"] = 3.14
	data["intSliceKey"] = []int{1, 2, 3}
	mu.Unlock()

	var wg sync.WaitGroup
	// 模拟并发读取和计算
	wg.Add(3)

	go func() {
		defer wg.Done()
		mu.RLock()
		value, ok := data["intKey"]
		mu.RUnlock()
		if ok {
			if num, ok := value.(int); ok {
				result := num + 10
				mu.Lock()
				data["intKey"] = result
				mu.Unlock()
				fmt.Printf("Int calculation result: %d\n", result)
			}
		}
	}()

	go func() {
		defer wg.Done()
		mu.RLock()
		value, ok := data["floatKey"]
		mu.RUnlock()
		if ok {
			if num, ok := value.(float64); ok {
				result := num * 2
				mu.Lock()
				data["floatKey"] = result
				mu.Unlock()
				fmt.Printf("Float calculation result: %f\n", result)
			}
		}
	}()

	go func() {
		defer wg.Done()
		mu.RLock()
		value, ok := data["intSliceKey"]
		mu.RUnlock()
		if ok {
			if slice, ok := value.([]int); ok {
				sum := 0
				for _, num := range slice {
					sum += num
				}
				mu.Lock()
				data["intSliceKey"] = sum
				mu.Unlock()
				fmt.Printf("Int slice calculation result: %d\n", sum)
			}
		}
	}()

	wg.Wait()
}
  1. 定义一个sync.RWMutex实例mu来保护map数据。
  2. 使用mu.Lock()进行写操作,mu.RLock()进行读操作,确保并发安全。
  3. 通过类型断言(value.(type))判断interface{}实际存储的数据类型,然后进行相应的计算并更新map中的值。