面试题答案
一键面试- 删除元素场景
- 底层内存角度:
- Go语言中切片删除元素通常使用
append
函数来模拟删除操作。例如,若要删除切片s1
中的第i
个元素,可以使用s1 = append(s1[:i], s1[i + 1:]...)
。 - 由于
s1
和s2
共享底层数组,当对s1
进行删除操作时,实际上是改变了s1
在底层数组中的起始位置和长度。假设底层数组为arr
,原本s1
从arr[j]
开始,长度为n
,删除元素后,s1
可能从arr[k]
开始(k
可能等于j
或者不等于j
,取决于删除的位置),长度变为m
(m < n
)。
- Go语言中切片删除元素通常使用
- 对s2的影响:
- 内存布局:如果删除操作没有导致底层数组扩容或重新分配内存(即删除后
len(s1) + cap(s1) - 1
仍小于等于底层数组容量),那么s2
的内存布局不会改变,因为底层数组没有改变。但是如果删除操作导致了底层数组重新分配内存(例如删除大量元素后,剩余元素很少,触发了内存优化机制重新分配一个更小的底层数组),那么s2
指向的底层数组就会改变,其内存布局也会相应改变。 - 实际可用元素:如果没有重新分配底层数组,
s2
的实际可用元素数量不变,只是s1
删除元素对应的位置对于s2
来说可能处于“无效”状态(因为s1
删除元素改变了其逻辑上的长度)。如果底层数组重新分配,s2
的实际可用元素可能会因为新的底层数组大小和内容改变而改变。
- 内存布局:如果删除操作没有导致底层数组扩容或重新分配内存(即删除后
- 底层内存角度:
- 添加元素场景
- 底层内存角度:
- 使用
append
函数向s1
添加元素时,如果当前s1
的容量(cap(s1)
)足够,那么直接在底层数组的空闲位置添加元素,s1
的长度(len(s1)
)增加,起始位置不变。如果当前容量不足,Go会重新分配一个新的底层数组,新数组的大小通常是原数组容量的两倍(如果原容量小于1024),然后将原数组内容复制到新数组,再在新数组的空闲位置添加元素。
- 使用
- 对s2的影响:
- 内存布局:如果添加元素没有导致底层数组扩容,
s2
的内存布局不变,因为底层数组未变。但如果导致了底层数组扩容并重新分配内存,s2
指向的底层数组会改变,内存布局也会改变。 - 实际可用元素:若未扩容,
s2
实际可用元素不变。若扩容,s2
的实际可用元素可能会因为新的底层数组大小和内容改变而改变,例如新的底层数组可能在原数组基础上增加了新元素,这些新元素对于s2
来说也可能是可用的(取决于s2
的起始位置和长度)。
- 内存布局:如果添加元素没有导致底层数组扩容,
- 底层内存角度: