✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
28. Go 语言当中数组和切片在传递的时候的区别是什么?
在 Go 语言中,数组和切片在传递的时候有一些区别。
首先,数组在传递时是以值传递的方式进行的。也就是说,当我们把一个数组作为参数传递给函数时,实际上是将该数组的一个副本传递给函数。因此,在函数内部对该数组进行修改并不会影响原始数组的值。这也是数组的缺点之一,因为它会带来额外的内存开销。
而切片则是以引用传递的方式进行的。也就是说,当我们把一个切片作为参数传递给函数时,实际上是将该切片的一个指针传递给函数。因此,在函数内部对该切片进行修改会影响原始切片的值。这使得切片比数组更加灵活和高效,因为它可以动态地调整大小,并且不会占用额外的内存空间。
需要注意的是,虽然切片是引用传递的,但是切片底层的数组却仍然是以值传递的方式进行的。也就是说,在将一个切片作为参数传递给函数时,函数内部修改底层数组的值会影响到原始切片以及其他引用该数组的切片。
另外,数组和切片的定义方式也不同。数组的长度是固定的,而切片的长度可以动态地改变。这也是切片比数组更加灵活的原因之一。
29. Go 语言是如何实现切片扩容的?
在 Go 语言中,切片的扩容是通过 append() 函数实现的。当切片的容量不足时,append() 函数会自动对切片进行扩容,并返回一个新的切片。
具体来说,当一个切片的容量不足时,Go 语言会为该切片重新分配一块更大的内存空间。通常情况下,新分配的内存空间大小为原来的两倍。然后,将原来的数据复制到新的内存空间中,并在新内存空间的末尾添加新的元素。最后,返回一个新的切片,指向新的内存空间。
需要注意的是,切片的扩容可能会导致底层数组重新分配内存空间,并将原来的数据复制到新的内存空间中,因此扩容操作的时间复杂度为 O(n),其中 n 表示切片的长度。因此,如果需要对一个大型的切片进行频繁的扩容操作,可能会对程序的性能产生影响。为了避免这种情况,可以在创建切片时尽可能地指定切片的容量,或者使用数组来代替切片。
30. Go 语言切片的扩容条件是什么?
切片的扩容条件是:在使用 append() 函数追加元素时,如果当前的元素个数已经达到了底层数组的容量,那么就会触发切片的扩容操作。
切片底层的数组容量是在创建切片时确定的。当切片长度小于等于底层数组容量时,切片底层数组就可以满足需求,不需要扩容。当切片长度大于底层数组容量时,就需要对底层数组进行扩容,才能满足追加元素的需求。
一般情况下,切片的扩容规则是将底层数组的容量翻倍。但在实际扩容过程中,可能会存在一些优化策略,例如:在容量小于 1024 时,每次扩容增加一倍容量;在容量大于 1024 时,每次扩容增加 25% 容量等等。这些细节会由 Go 语言运行时根据实际情况进行调整,用户不需要过多关注。
需要注意的是,切片的扩容可能会导致底层数组重新分配内存空间,并将原来的数据复制到新的内存空间中,因此扩容操作的时间复杂度为 O(n),其中 n 表示切片的长度。因此,如果需要对一个大型的切片进行频繁的扩容操作,可能会对程序的性能产生影响。为了避免这种情况,可以在创建切片时尽可能地指定切片的容量,或者使用数组来代替切片。