面试题答案
一键面试- 数组作为参数传递时的情况:
在Go语言中,当数组作为参数传递给函数时,是值传递。这意味着函数接收的是原数组的一个副本,对副本的任何修改都不会影响原数组。例如:
上述代码中,package main import "fmt" func modifyArray(arr [3]int) { arr[0] = 100 } func main() { original := [3]int{1, 2, 3} modifyArray(original) fmt.Println(original) }
modifyArray
函数修改的是original
数组的副本,original
数组本身不会改变,输出仍然是[1 2 3]
。 - 性能问题:
当数组较大时,值传递会导致大量的数据复制,这会消耗额外的内存和时间。比如有一个非常大的数组
[1000000]int
,传递给函数时,函数内部会复制一份1000000个int
大小的数据,这对内存和性能都是很大的开销。 - 优化方案:
- 使用数组指针:
- 优点:避免了数组的整体复制,只传递一个指针,大大减少了内存开销和传递时间。例如:
上述代码中,package main import "fmt" func modifyArrayPtr(arr *[3]int) { (*arr)[0] = 100 } func main() { original := [3]int{1, 2, 3} modifyArrayPtr(&original) fmt.Println(original) }
modifyArrayPtr
函数接收的是数组指针,对指针指向的数组进行修改,original
数组也会改变,输出为[100 2 3]
。 - 缺点:函数调用者需要注意传递指针,代码可读性可能会略有下降,并且指针操作相对复杂一些,如果使用不当可能会导致空指针异常等问题。
- 优点:避免了数组的整体复制,只传递一个指针,大大减少了内存开销和传递时间。例如:
- 使用切片:
- 优点:切片本质上是一个轻量级的数据结构,包含一个指向底层数组的指针、长度和容量。传递切片时只是复制了切片头(通常是3个机器字长,在64位系统上为24字节),而不是整个底层数组。例如:
上述代码中,package main import "fmt" func modifySlice(slice []int) { slice[0] = 100 } func main() { original := []int{1, 2, 3} modifySlice(original) fmt.Println(original) }
modifySlice
函数接收切片并修改,original
切片也会改变,输出为[100 2 3]
。切片在Go语言中使用非常灵活,易于理解和操作。 - 缺点:由于切片共享底层数组,如果不小心在多个地方通过切片修改底层数组,可能会出现意想不到的结果,增加调试难度。同时,切片的扩容机制也需要开发者注意,不合理的扩容可能会导致额外的性能开销。
- 优点:切片本质上是一个轻量级的数据结构,包含一个指向底层数组的指针、长度和容量。传递切片时只是复制了切片头(通常是3个机器字长,在64位系统上为24字节),而不是整个底层数组。例如:
- 使用数组指针: