基本数据结构-map

什么是map 为什么要用map map的底层如何实现 map内存模型 创建map 哈希函数 key定位过程 map的两种get操作 【面试重点】如何进行扩容 【重点】map的遍历 map的赋值 map的删除 map进阶 可以边遍历边删除么 key可以是float类型么 总结 参考资料 面试经常被问到golang map的扩容,特此记录下来 map的结构 golang中map是...

基本数据结构-slice

查看slice结构

查看slice内部的构造:在runtime/slice.go中查看源码

1
2
3
4
5
6
// runtime/slice.go
type slice struct {
array unsafe.Pointer // 元素指针
len int // 长度
cap int // 容量
}

结构剖析,slice 共有三个属性:

  1. 指针,指向底层数组,同一个底层数组可以被多个slice同时指向,因此只要有一个slice修改,其他指向该底层数组的slice也会被修改;
  2. 长度,表示切片可用元素的个数,也就是说使用下标对 slice 的元素进行访问时,下标不能超过 slice 的长度
  3. 容量,底层数组的元素个数,容量 >= 长度。在底层数组不进行扩容的情况下,容量也是 slice 可以扩张的最大限度

对切片进行赋值的时候,实际是对表层结构体的拷贝,但是拷贝出来的结构体与原来的结构体的array指向同一个底层数组。

切片的三种状态

平常我们创建切片的方式有很多种,其实里面就包含了我们切片中的三种状态(零切片,nil切片,空切片),只是很少有人关注罢了

创建方式一 创建方式二 特点
zero slice 【任意数据类型都可以】s1 := make([]int, 10) 【指针类型】s2 := make([]*int, 10) 数组中的元素值都是对应类型的零值
nil slice var s1 []int s1 := *new([]int) 底层数组是nil
empty slice s1 := make([]int, 0) s1 := []int{} 底层数组都指向某一个特殊的内存地址(zerobase)