Golang面试字符串、数组、切片知识
本文介绍Go编程中经常用到的字符串、数组、切片的底层内存布局 , 以及基础数据类型字符串和复合数据类型数组、切片使用注意事项 。
符串、数组、切片内存布局
string字符串
文章插图
字符串的内存布局
如上图字符串实际上就是一个指针指向一个byte类型的数组 。
array数组
文章插图
数组的内存布局
如上图数组是相同类型的变量的集合 。
slice切片
文章插图
切片的内存布局
如上图切片就是一个指针指向一个数组;
了解对象内存布局 , 有助于理解值传递、引?用传递等概念 。
String介绍
我们从官方文档中了解基础数据类型字符串的介绍:
文章插图
Go 字符串介绍
字符串是所有8位字节字符串的集合 , 通常是但不一定表示UTF-8编码的文本 。
- 字符串可以为空 , 但不能为nil;
- 允许以索引访问字节数组(非字符串) , 但不能获取元素地址;
- 每个中文字 , 占3个byte;
- 字符串类型的值是不可变的 。
字符串修改需要进行转换 , 转换过程中需要重新分配内存 , 并复制数据 。 转换操作会拖累算法性能 , 可尝试试用“非安全”方法改善 。
用加法操作字符串每次都重新分配内存 。 可以使用string.Join函数代替 。
Array介绍
Go和以往认识的数组有很大不同 , 数组是相同类型的变量的集合 , 需要注意的地方有:
- Go中数组是固定大小;
- 集合中的元素有一个类型 , 并且每个数组只能有一个类型(例如字符串数组 , 整数数组等);
- 由连续的内存位置组成(因此[4] int的内存内表示只是顺序排列的四个整数值)如下图:
文章插图
固定为4的整形数组
- 数组是值类型 , 复制和传参会复制整个数组 , 而不是指针 。 当我们在Go中分配或传递数组时-我们对其进行复制(而不是指针或对其的引用 , 因此这可能会占用大量内存) , 如果想要“引用”传递给数组 , 则可以使用指针;
文章插图
数组值传递
文章插图
数组引用传递
- 数组变量不是指向第一个数组元素的指针 , 数组变量代表整个数组;
- 指针数组[n]*T , 数组指针*[n]T;
- 数组长度也是一种类型必须是常量 , 而且是类型的组成部分 , [2]int和[3]int是不同类型;
- 支持“==”、“!=”操作符 , 因为内存总是被初始化过的 。
- 内置函数len和cap都返回数组长度(元素数量) 。
[N]Type[N]Type{value1, value2, ..., valueN}[...]Type{value1, value2, ..., valueN}
Slice介绍在Go中slice让数组变得很有便捷 。 显然在Go代码中数组实际上很少见 , 切片无处不在 。 slice并不是数组或数组指针 , 它通过内部指针和相关属性引用数组片段 , 以实现变长方案 。
- 引用类型 。 但自身是结构体 , 值拷贝传递 。
- 属性len表示可用元素数量 , 读写操作不能超过该限制 。
- 属性cap表示最大扩张容量 , 不能超出数组限制 。
- 如果slice==nil,那么len、cap结果都等于0 。
data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} slice := data[1:4:5]//[low:hight:max]
文章插图
slice len cap 用法
切片的创建使用语法:
make([]Type, length, capacity)make([]Type, length)[]Type{}[]Type{value1, value2, ..., valueN}
使用切片特别注意:- 切片的读写实际上对应的是底层的数组;
- 新切片依旧指向原底层数组 。
- 向 slice 尾部添加数据 , 返回新的 slice 对象 。
- 切片一旦超出原 slice.cap 限制 , 就会重新分配底层数组 , 即便原数组并未填满 。 通常以 2 倍容量重新分配底层数组 。 在?大批量添加数据时 , 建议?一次性分配?足够?大的空间 , 以减少内存分配和数据复制开销 。 或初始化?足够?长的 len 属性 , 改?用索引号进?行操作 。 及时释放不再使?用的 slice 对象 , 避免持有过期数组 , 造成 GC ?无法回收 。
- ICPC--1199: 在线判题(字符串)
- 三年Java开发,刚从美团、京东、阿里面试归来,分享个人面经
- java面试题整理
- 面试官:问你一个,Spring事务是如何传播的?
- 程序员面试主要看哪些 该怎么准备面试内容
- 震惊!京东T4大佬面试整整三个月,才写了两份java面试笔记
- 2020金九银十安卓面试题来袭(猿辅导+斗鱼+字节+腾讯)
- ICPC--1206: 字符串的修改&1207:字符排列问题
- 「8」进大厂必须掌握的面试题-Java面试-异常和线程
- 安卓面试必备的JVM虚拟机制详解,看完之后简历上多一个技能