面试题合集目录

整型切片如何初始化?
s1 := make([]int, 0)
s2 := make([]int, 5, 10)
s3 := []int{1, 2, 3}
nil切片和空切片指向的地址一样?
func main() {var s1 []ints2 := make([]int, 0)s3 := make([]int, 0)data1 := (*reflect.SliceHeader)(unsafe.Pointer(&s1)).Datadata2 := (*reflect.SliceHeader)(unsafe.Pointer(&s2)).Datadata3 := (*reflect.SliceHeader)(unsafe.Pointer(&s3)).Datafmt.Printf("s1 data:%+v\n", data1)fmt.Printf("s2 data:%+v\n", data2)fmt.Printf("s3 data:%+v\n", data3)fmt.Printf("s1:s2=>%t\n", data1 == data2)fmt.Printf("s2:s3=>%t\n", data2 == data3)
}//输出
s1 data:0
s2 data:824634859200
s3 data:824634859200
s1:s2=>false
s2:s3=>true

nil切片和空切片指向的地址不一样。
nil切片引用数组指针地址为0(无指向任何实际地址)
空切片的引用数组指针地址是有的,且固定为一个值。

//切片的数据结构
type SliceHeader struct {Data uintptr //引用数组指针地址Len  intCap  int
}

nil切片和空切片最大的区别在于指向的数组引用地址是不一样的。

拷贝大切片一定比小切片代价大吗?

并不是,所有切片的大小相同;三个字段(一个uintptr,两个int)。切片中的第一个字段是指向切片底层数组的指针,这是切片的存储空间,第二个字段是切片的长度,第三个字段是容量。将一个slice变量分配给另一个变量只会复制三个机器字。所以拷贝大切片跟小切片的代价应该是一样的。

SliceHeader 是切片在go的底层结构。

type SliceHeader struct {Data uintptrLen  intCap  int
}

大切片跟小切片的区别无非就是 Len 和 Cap的值比小切片的这两个值大一些,如果发生拷贝,本质上就是拷贝上面的三个字段。

数组和切片的区别是什么?

切片是指针类型,数组是值类型;
数组的长度是固定的,而切片长度可以任意调整(切片是动态的数组);
数组只有长度一个属性,而切片比数组多了一个容量(cap)属性;
切片的底层也是数组实现的。

数组和切片在传递的时候的区别?

数组在默认情况下是“非引用类型传递”;
切片进行的是“引用类型传递”。

Go语言是如何实现切片扩容的?
func main() {arr := make([]int, 0)oldCap := cap(arr)fmt.Println("len 为", len(arr), "cap 为", cap(arr))for i := 0; i < 2000; i++ {arr = append(arr, i)if oldCap != cap(arr) {fmt.Println("len 为", len(arr), "cap 为", cap(arr))oldCap = cap(arr)}}
}//输出
len 为 0 cap 为 0
len 为 1 cap 为 1
len 为 2 cap 为 2
len 为 3 cap 为 4
len 为 5 cap 为 8
len 为 9 cap 为 16
len 为 17 cap 为 32
len 为 33 cap 为 64
len 为 65 cap 为 128
len 为 129 cap 为 256
len 为 257 cap 为 512
len 为 513 cap 为 848
len 为 849 cap 为 1280
len 为 1281 cap 为 1792
len 为 1793 cap 为 2560

以go 1.18+来说,
原来的slice 容量oldcap小于256的时候,新 slice 的容量newcap是oldcap 的2倍;
当oldcap容量大于等于 256 的时候,newcap会有个计算公式
newcap += (newcap + 3*threshold) / 4
再对 newcap 作了一个内存对齐,这个和内存分配策略相关。进行内存对齐之后,新 slice 的容量是要 大于等于 按照前半部分生成的newcap。部分源码

func growslice(et *_type, old slice, cap int) slice {// ...newcap := old.capdoublecap := newcap + newcapif cap > doublecap {newcap = cap} else {const threshold = 256if old.cap < threshold {newcap = doublecap} else {for 0 < newcap && newcap < cap {newcap += (newcap + 3*threshold) / 4}if newcap <= 0 {newcap = cap}}}// ...capmem = roundupsize(uintptr(newcap) * goarch.PtrSize)newcap = int(capmem / goarch.PtrSize)// ...
}
json库对nil slice和空slice的处理是一致的吗?

json库对nil slice和空slice的处理是不一致的,
因为nil slice只是声明了slice,却没有给实例化的对象。

    var f1 []stringf2 := make([]string, 0)json1, _ := json.Marshal(Person{f1})json2, _ := json.Marshal(Person{f2})fmt.Printf("%s\n", string(json1))fmt.Printf("%s\n", string(json2))//输出
{"Friends":null}
{"Friends":[]}

json库对nil slice编码为null,
json库对空slice编码为[]。

golang slice的底层实现?

切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为基于数组实现,所以它的底层的内存是连续分配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化。

切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。

切片对象非常小,是因为它是只有3个字段的数据结构:

type SliceHeader struct {Data uintptr //指向底层数组的指针Len  int    //切片的长度Cap  int     //切片的容量
}
扩容前后的slice是否相同?

情况一:原数组还有容量可以扩容(实际容量没有填充完),这种情况下,扩容以后的数组还是指向原来的数组,对一个切片的操作可能影响多个指针指向相同地址的slice。
情况二:原来数组的容量已经达到了最大值,再想扩容,go默认会先开一片内存区域,把原来的值拷贝过来,然后再执行append()操作。这种情况丝毫不影响原数组。
要复制一个slice,最好使用copy函数。

2023版golang面试题100道(slice)相关推荐

  1. 2023版golang面试题100道(map)

    面试题合集目录 map查找? 假设当前 B=4 即桶数量为2^B=16个,要从map中获取k4对应的value [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 k4的查找步骤: ...

  2. 【JAVA Core】精品面试题100道

    [JAVA Core]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题> 后续我会把自己有价值的题和面试真题添加进入,也对 ...

  3. c语言while中100 95,C语言笔试题100道

    C语言笔试题100道 a) 30 b) 50 c) 40 d) 20 e) 10 18) #include void main() { int a=3,b=2,c=1; int x=10,y=20; ...

  4. 【Redis】精品面试题100道

    [Redis]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题>和敖丙面试题 后续我会把自己有价值的题和面试真题添加进入, ...

  5. Python经典面试题100道(附PDF下载地址)

    最近肝了一个月,整理了下经典的 Python 经典习题 100 道,有基础的,也有进阶的,用习题来巩固知识点,不枯燥,为了方便大家查阅,我把这 100 道题整理成了 PDF 文档,大家可以下载到电脑或 ...

  6. 【JAVA面试题】java面试题100道详解

    Java面试简答题100道详解 什么是Java? Java是一种高级编程语言,具有面向对象.跨平台.容易学习等特点. Java有哪些特点? Java有面向对象.跨平台.垃圾回收.安全性等特点. 说说J ...

  7. Linux面试题100道

    导读:本文整理了最新的Linux面试题,近3万字,约100道题,分享至此,希望对大家有帮助. 目录 一.Linux 概述 二.磁盘.目录.文件 三.安全 Shell 四.编程题 七.文档编辑命令 八. ...

  8. JAVA面试题100道

    1.final关键字 final修饰类,表示类不可变,不可继承,比如String,不可变性 final修饰方法,表示该方法不可重写,比如模板方法,可以固定我们的算法 final修饰变量,这个变量就是常 ...

  9. 最新阿里Java后端开发面试题100道(P6-P7)

    面试题 1.什么是字节码?采用字节码的好处是什么? 2. Oracle JDK 和 OpenJDK 的对比? 3.Arrays.sort 和 Collections.sort 实现原理和区别 4.wa ...

最新文章

  1. vmmem 内存占用高
  2. 毕业设计——学术交流管理系统的设计与实现-1
  3. 人工智能学习体系大纲(src:http://blog.sina.com.cn/s/blog_7dbb766f0102xdwu.html)
  4. 06 事件处理函数绑定与事件对象
  5. 在ASP.NET Core中实现一个Token base的身份认证
  6. win10 linux装软件有哪些,win10若何装linux,win10安装linux双系统的详细教程,微商必备软件有哪些...
  7. python清空集合_python集合删除多种方法详解
  8. vue rule鼠标移走校验_Vue-cli+Element-ui实现后台管理系统(二)实现后台登录功能...
  9. 为什么说时代在召唤华为!
  10. WP7备注(11)(页面跳转)
  11. 为 DEV-C++ 生成 libmysql.a 的过程 及 windows下 devc++ c语言访问mysql数据库 环境配置...
  12. 常用的几款抓包工具_ 常见的4种抓包工具比较
  13. Python学习日记之从Tushare上获取500成分股
  14. java用户行为日志记录方法_简单易用的开源用户操作日志记录系统
  15. 用python编写加减乘除计算器_python实现加减乘除计算器
  16. ##DBUtils工具类的正确使用(一)
  17. python读取txt文件中的数字_python从txt文件读取数据
  18. java毕业生设计医院设备管理系统计算机源码+系统+mysql+调试部署+lw
  19. 计算机视觉 牛人主页
  20. 蜂鸟无线LR43B无线射频接收模块调试记录

热门文章

  1. left join 用法
  2. c 语言中双向链表逆转编程题,C/C++ 双链表之逆序的实例详解
  3. OSChina 周三乱弹 ——一首诗解释程序人生
  4. 解决Win10无法安装没有数字签名驱动的问题
  5. DDT数据驱动基本应用
  6. 2345浏览器的2.4版本,在2013年1月19日,像小丑一样笑着!
  7. 520到了,是时候展示真正的技术了,程序猿的浪漫代码集合
  8. c语言头文件包含嵌套问题和包含原则
  9. 数仓数据处理与数据流向
  10. 免费无限次的API 接口