2023版golang面试题100道(slice)
面试题合集目录
整型切片如何初始化?
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)相关推荐
- 2023版golang面试题100道(map)
面试题合集目录 map查找? 假设当前 B=4 即桶数量为2^B=16个,要从map中获取k4对应的value [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 k4的查找步骤: ...
- 【JAVA Core】精品面试题100道
[JAVA Core]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题> 后续我会把自己有价值的题和面试真题添加进入,也对 ...
- 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; ...
- 【Redis】精品面试题100道
[Redis]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题>和敖丙面试题 后续我会把自己有价值的题和面试真题添加进入, ...
- Python经典面试题100道(附PDF下载地址)
最近肝了一个月,整理了下经典的 Python 经典习题 100 道,有基础的,也有进阶的,用习题来巩固知识点,不枯燥,为了方便大家查阅,我把这 100 道题整理成了 PDF 文档,大家可以下载到电脑或 ...
- 【JAVA面试题】java面试题100道详解
Java面试简答题100道详解 什么是Java? Java是一种高级编程语言,具有面向对象.跨平台.容易学习等特点. Java有哪些特点? Java有面向对象.跨平台.垃圾回收.安全性等特点. 说说J ...
- Linux面试题100道
导读:本文整理了最新的Linux面试题,近3万字,约100道题,分享至此,希望对大家有帮助. 目录 一.Linux 概述 二.磁盘.目录.文件 三.安全 Shell 四.编程题 七.文档编辑命令 八. ...
- JAVA面试题100道
1.final关键字 final修饰类,表示类不可变,不可继承,比如String,不可变性 final修饰方法,表示该方法不可重写,比如模板方法,可以固定我们的算法 final修饰变量,这个变量就是常 ...
- 最新阿里Java后端开发面试题100道(P6-P7)
面试题 1.什么是字节码?采用字节码的好处是什么? 2. Oracle JDK 和 OpenJDK 的对比? 3.Arrays.sort 和 Collections.sort 实现原理和区别 4.wa ...
最新文章
- vmmem 内存占用高
- 毕业设计——学术交流管理系统的设计与实现-1
- 人工智能学习体系大纲(src:http://blog.sina.com.cn/s/blog_7dbb766f0102xdwu.html)
- 06 事件处理函数绑定与事件对象
- 在ASP.NET Core中实现一个Token base的身份认证
- win10 linux装软件有哪些,win10若何装linux,win10安装linux双系统的详细教程,微商必备软件有哪些...
- python清空集合_python集合删除多种方法详解
- vue rule鼠标移走校验_Vue-cli+Element-ui实现后台管理系统(二)实现后台登录功能...
- 为什么说时代在召唤华为!
- WP7备注(11)(页面跳转)
- 为 DEV-C++ 生成 libmysql.a 的过程 及 windows下 devc++ c语言访问mysql数据库 环境配置...
- 常用的几款抓包工具_ 常见的4种抓包工具比较
- Python学习日记之从Tushare上获取500成分股
- java用户行为日志记录方法_简单易用的开源用户操作日志记录系统
- 用python编写加减乘除计算器_python实现加减乘除计算器
- ##DBUtils工具类的正确使用(一)
- python读取txt文件中的数字_python从txt文件读取数据
- java毕业生设计医院设备管理系统计算机源码+系统+mysql+调试部署+lw
- 计算机视觉 牛人主页
- 蜂鸟无线LR43B无线射频接收模块调试记录