← 返回目录

简述slice的底层原理,和数组的区别是什么

第 21 / 29 卷日期:

简述slice的底层原理,和数组的区别是什么

slice内部的是通过指针引用一个底层数组,是对数组一个连续片段的引用,另外还有长度和容量两个变量

其数据结构如下:

图 22-1
图 22-1

Slice是可变长度的数组,其长度是基于底层数组的长度的,如果底层数组的长度不足以满足需求,可以进行扩容,扩容其实就是另外开一个数组把当前切片的内容copy过去,扩容策略简单来说是以下规则:

如果新申请的容量大于两倍的旧容量,那么最终容量就是新申请的容量大小

如果不大于两倍旧容量,则判断旧容量是否小于1024,如果是则最终容量是旧容量的两倍

如果旧容量大于等于1024,就从旧容量大小开始每次增加现有旧容量的四分之一,直到满足需求为止

slice和数组的区别

声明时数组要指定长度或者是写 ...,而slice方括号中为空数组声明后可以不进行初始化,其内元素已经为默认零值,而slice需要初始化才能使用,不初始化时为空

函数传参时参数为数组是传的一个数组的copy,改变形参不会对原数组产生影响;而参数为slice时因为slice 本身结构中包含了数组指针,因此改变slice形参可以改变底层的数组,同时在传slice时要注意slice的扩容问

题

channel的发送和接收操作有哪些基本特性?

  1. 对同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的。

即同一时刻,go的runtime只会执行对同一个通道的任意个发送操作中的某一个,直到这个发送的元素值被完全复制进该通道之后,其他发送操作才可能被执行。接收操作类似。

  1. 发送操作和接收操作中对元素值的处理都是不可分割的

即发送操作和接收操作都是原子的。例如接收操作时元素值从通道移动到外界,这个移动操作包含了两步,第一步是生成正在通道中的这个元素值的副本,并准备给到接收方,第二步是删除在通道中的这个元素值,这两个操作会

一起完成。类似于innodb的事务机制。

这样既是为了保证通道中元素值的完整性,也是为了保证通道操作的唯一性

  1. 发送操作在完全完成之前会被阻塞,接收操作也是。
全站分卷索引 · 29 卷
  1. 1代码随想录知识星球精华(最强八股文)第五版(Go篇))
  2. 2Go string 和 []byte 的区别
  3. 3数组和切片的区别
  4. 4扩容前后的Slice是一样的吗
  5. 5Go语言map是有序的还是无序的, 为什么
  6. 6go里面的map是并发安全的吗?如何并发安全
  7. 7Go 的错误处理和 Java 的异常处理对比
  8. 8介绍一下panic和recover
  9. 9什么是defer?有什么作用
  10. 10Go并发
  11. 11进程、线程的区别
  12. 12什么是go runtine
  13. 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
  14. 14什么是互斥锁(mutex)?在什么情况下会用到它们?
  15. 15Mutex有几种模式
  16. 16goroutine什么情况会发生内存泄漏?如何避免。
  17. 17Go语言中GC的流程是什么
  18. 18Go 中的内存逃逸现象是什么?
  19. 19CAP 理论,为什么不能同时满足
  20. 20说一下 Gin 的路由怎么实现的
  21. 21简述slice的底层原理,和数组的区别是什么
  22. 22defer底层原理
  23. 23侵入式和非侵入式的区别
  24. 24goroutine与线程的区别
  25. 25goroutine在什么情况下会被挂起呢?
  26. 26GC(垃圾回收)原理 1.5版本
  27. 27简述Go的垃圾回收机制
  28. 28协程优势及其通信方式
  29. 29Go的内存对齐