Go 基础面试题, Go 语言 slice,map 和 channel 创建时的参数有什么含义?
Go 基础面试题, Go 语言 slice,map 和 channel 创建时的参数有什么含义?
QA
Step 1
Q:: Go 语言中 slice、map 和 channel 的创建时分别有哪些参数,它们的含义是什么?
A:: 在 Go 语言中,slice、map 和 channel 都是常用的数据结构,它们的创建有各自特定的参数。1) Slice:
使用 make([]T, len, cap)
创建,T
是元素类型,len
是 slice 的初始长度,cap
是容量。如果不指定容量,容量等于长度。2) Map:
使用 make(map[K]V, hint)
创建,K
是键的类型,V
是值的类型,hint
是预估的 map 大小。3) Channel:
使用 make(chan T, buffer)
创建,T
是 channel 中传输的数据类型,buffer
是 channel 的缓冲区大小。如果 buffer
为 0
或未指定,创建的是无缓冲 channel。
Step 2
Q:: 为什么 Go 语言中 slice 没有类似 map 的 hint 参数?
A:: Slice 是基于数组的一种数据结构,它的容量是动态调整的,可以通过 append
方法自动扩展。当 slice 的长度超过容量时,Go 语言会自动分配更大的底层数组,并将旧数组的内容复制过去。因此不需要提前指定容量的 hint 值。
Step 3
Q:: 无缓冲 channel 和有缓冲 channel 有什么区别?
A:: 无缓冲 channel 是同步的,也就是说发送操作会阻塞直到有接收操作,而接收操作也会阻塞直到有发送操作。有缓冲 channel 则允许一定数量的数据被发送而无需立即被接收,只有当缓冲区满时,发送操作才会阻塞。这种特性使有缓冲 channel 在某些并发模式下更加灵活。
Step 4
Q:: Go 语言中的 map 是否线程安全?如果不是,如何实现线程安全?
A:: Go 语言中的 map 不是线程安全的。在多协程环境下同时读写 map 会导致数据竞争和不确定行为。要实现线程安全,可以使用 sync.RWMutex
保护 map 的读写操作,或者使用 sync.Map
,它是 Go 标准库提供的线程安全的 map。
Step 5
Q:: 如何在不影响性能的情况下初始化一个容量较大的 slice?
A:: 可以使用 make([]T, len, cap)
创建一个容量较大的 slice。通过直接指定较大的容量,可以避免后续 append
操作导致的多次内存分配和数组复制,从而提升性能。如果容量可以预估,应尽量提前分配足够的容量。