[TOC]
### 结构体的比较:
* 结构体只能比较是否相等,但是不能比较大小。
* 相同类型的结构体才能够进行比较,结构体是否相同不但与属性类型有关,还与属性顺序相关
* 如果 struct 的所有成员都可以比较,则该 struct 就可以通过 == 或 != 进行比较是否相等,比较时逐个项进行比较,如果每一项都相等,则两个结构体才相等,否则不相等;
~~~
可比较类型:常见的有 bool、数值型、字符、指针、数组
不可比较类型:切片、map、函数
~~~
### 类型设置
![](https://img.kancloud.cn/ff/65/ff65772ed1a0d4bd04df12a43329a210_1445x487.png)
### nil赋值
nil 只能赋值给指针、chan、func、interface、map 或 slice 类型的变量
### 类型断言
![](https://img.kancloud.cn/93/ac/93ac6ba3e28159ccbee0a216b6610deb_1202x422.png)
只有接口类型才有类型断言
### cap
![](https://img.kancloud.cn/0a/e6/0ae699615ba0b17bc11da204299a8036_535x250.png)
channle 的cap就是缓冲,make(chan int,1),cap=1
array 的cap和len 一致
slice 在没有设置cap时候,和长度一致
### go中字符串是只读的
![](https://img.kancloud.cn/5a/44/5a44ff963acd128a6abc28d98cf27fa4_500x337.png)
### 多重赋值
![](https://img.kancloud.cn/13/36/13362e12b6ce745a3795637c7f1108fc_687x450.png)
### const 常量不能取地址
![](https://img.kancloud.cn/d1/c7/d1c726e1803f77f85416d9c49ac09b69_1245x246.png)
### slice的for range遍历
![](https://img.kancloud.cn/a8/a6/a8a6fc0cb27ede281d22d914cd6abdda_442x359.png)
如果是map,也是仅输出索引部分
### 不能使用短变量声明结构体
![](https://img.kancloud.cn/57/73/5773f9fa0bca02cfea4a43805c3787c8_476x616.png)
### 简短声明的变量需要注意啥
* 简短声明的变量只能在函数内部使用
* struct 的变量字段不能使用 := 来赋值
* 不能用简短声明方式来单独为一个变量重复声明, := 左侧至少有一个新变量,才允许多变量的重复声明
### 切片和数组的区别
数组:
1、数组是具有固定长度,且拥有零个或者多个,相同数据类型元素的序列。
2、数组的长度是数组类型的一部分,所以\[3\]int 和 \[4\]int 是两种不同的数组类型。
3、数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变;数组是值传递。数组是内置类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值。在初始化后长度是固定的,无法修改其长度。
4、当作为方法的参数传入时将复制一份数组而不是引用同一指针。数组的长度也是其类型的一部分,通过内置函数len(array)获取其长度
切片:
1、切片表示一个拥有相同类型元素的可变长度的序列。
2、切片是一种轻量级的数据结构,它有三个属性:指针、长度和容量。
3、切片不需要指定大小;
4、切片是地址传递;
5、切片可以通过数组来初始化,也可以通过内置函数make()初始化 。初始化时len=cap,在追加元素时如果容量cap不足时将按len的2倍扩容
### for循环
for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的break,可以选择中断哪一个循环 for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量。
### go语言中的switch语句
单个 case 中,可以出现多个结果选项。只有在 case 中明确添加 fallthrough关键字,才会继续执行紧跟的下一个 case。
### go语言中的引用类型包含哪些
数组切片、字典(map)、通道(channel)、接口(interface)
### go语言的main函数
* main 函数不能带参数;main 函数不能定义返回值。
* main 函数所在的包必须为 main 包;main 函数中可以使用 flag 包来获取和解析命令行参数。
### go语言的select机制
* select 机制用来处理异步 IO 问题
* select 机制最大的一条限制就是每个 case 语句里必须是一个 IO 操作
* golang 在语言级别支持 select 关键字
### go的接口是什么
* 在 go 语言中,interface 也就是接口,被用来指定一个对象。接口具有下面的要素:
* 一系列的方法
* 具体应用中并用来表示某个数据类型
* 在 go 中使用 interface 来实现多态
### Go语言里面的类型断言是怎么回事
类型断言是用来从一个接口里面读取数值给一个具体的类型变量。类型转换是指转换两个不相同的数据类型。
### Golang Slice的底层实现
切片是基于数组实现的,它的底层是数组,它自己本身非常小,可以理解为对底层数组的抽象。因为基于数组实现,所以它的底层的内存是连续分配的,效率非常高,还可以通过索引获得数据,可以迭代以及垃圾回收优化。
切片本身并不是动态数组或者数组指针。它内部实现的数据结构通过指针引用底层数组,设定相关属性将数据读写操作限定在指定的区域内。切片本身是一个只读对象,其工作机制类似数组指针的一种封装。
切片对象非常小,是因为它是只有3个字段的数据结构:
* 指向底层数组的指针
* 切片的长度
* 切片的容量
这3个字段,就是Go语言操作底层数组的元数据。
![](https://img.kancloud.cn/01/6c/016c6e325510b0a8cfc6a7d3b6ddb8fb_881x280.png)
### Golang Slice的扩容机制,有什么注意点
首先判断,如果新申请容量大于 2 倍的旧容量,最终容量就是新申请的容量。否则判断,如果旧切片的长度小于 1024,则最终容量就是旧容量的两倍。
否则判断,如果旧切片长度大于等于 1024,则最终容量从旧容量开始循环增加原来的 1/4 , 直到最终容量大于等于新申请的容量。如果最终容量计算值溢出,则最终容量就是新申请容量。
情况一:原数组还有容量可以扩容(实际容量没有填充完),这种情况下,扩容以后的数组还是指向原来的数组,对一个切片的操作可能影响多个指针指向相同地址的Slice。
情况二:原来数组的容量已经达到了最大值,再想扩容, Go 默认会先开一片内存区域,把原来的值拷贝过来,然后再执行 append() 操作。这种情况丝毫不影响原数组。
要复制一个Slice,最好使用Copy函数。
### Golang Map底层实现???
Golang 中 map 的底层实现是一个散列表,因此实现 map 的过程实际上就是实现散表的过程。
在这个散列表中,主要出现的结构体有两个,一个叫hmap(a header for a go map),一个叫bmap(a bucket for a Go map,通常叫其bucket)。
- Go准备工作
- 依赖管理
- Go基础
- 1、变量和常量
- 2、基本数据类型
- 3、运算符
- 4、流程控制
- 5、数组
- 数组声明和初始化
- 遍历
- 数组是值类型
- 6、切片
- 定义
- slice其他内容
- 7、map
- 8、函数
- 函数基础
- 函数进阶
- 9、指针
- 10、结构体
- 类型别名和自定义类型
- 结构体
- 11、接口
- 12、反射
- 13、并发
- 14、网络编程
- 15、单元测试
- Go常用库/包
- Context
- time
- strings/strconv
- file
- http
- Go常用第三方包
- Go优化
- Go问题排查
- Go框架
- 基础知识点的思考
- 面试题
- 八股文
- 操作系统
- 整理一份资料
- interface
- array
- slice
- map
- MUTEX
- RWMUTEX
- Channel
- waitGroup
- context
- reflect
- gc
- GMP和CSP
- Select
- Docker
- 基本命令
- dockerfile
- docker-compose
- rpc和grpc
- consul和etcd
- ETCD
- consul
- gin
- 一些小点
- 树
- K8s
- ES
- pprof
- mycat
- nginx
- 整理后的面试题
- 基础
- Map
- Chan
- GC
- GMP
- 并发
- 内存
- 算法
- docker