基础类型内存宽度以及表示范围
bool
1Byte true/false
uint8
1Byte 0-255
uint16
2Byte 0-65535
uint32
4Byte 0-4294967295
uint64
8Byte 0-18446744073709551615
int8
1Byte -128-127
int16
2Byte -32768-32767
int32
4Byte -2147483648-2147483647
int64
6Byte -9223372036854775808-9223372036854775807
byte
1Byte 类似 uint8
rune
4Byte 类似 int32
uint
4Byte / 8Byte 32 或 64 位
int
4Byte / 8Byte 与 uint 一样大小
float32
4Byte
float64
8Byte
string
1Byte (英文) / 2Byte-4Byte(中文,取决于字符编码类型)
切片拼接
slice1 := []int{0, 1, 2, 3}
slice2 := []int{3, 4, 5}
slice1 = append(slice1, slice2...)
fmt.Println(slice1)
//[0 1 2 3 3 4 5]
bit Byte
bit
:计算机记忆的最小单位,一个bit
可以代表0或1
Byte
:一个Byte
由8bits
所组成
1Byte
=8Bits
1KB
=1024Bytes
时间转换
字符串转时间
time.Parse()
时间转字符串
time.Format()
时间转时间戳
Time.Unix()
时间戳转时间
time.Unix()
计时
朴素方法
startTime := time.Now()
//do something
time.Sleep(time.Second)
duration := time.Since(startTime)
fmt.Printf("经过时间:%v\n", duration)
//经过时间:1.005046959s
简洁方法
// TimeCost 耗时统计函数
func TimeCost(start time.Time) {
duration := time.Since(start)
fmt.Printf("经过时间:%v\n", duration)
}
defer TimeCost(time.Now())
//do something
time.Sleep(time.Second)
//经过时间:1.005054375s
优雅方法
// TimeCost 耗时统计函数
func TimeCost() func() {
start := time.Now()
return func() {
duration := time.Since(start)
fmt.Printf("经过时间:%v\n", duration)
}
}
defer TimeCost()()
//do something
time.Sleep(time.Second)
//经过时间:1.005033916s
时间的加减法
// Add 时间相加
now := time.Now()
// ParseDuration parses a duration string.
// A duration string is a possibly signed sequence of decimal numbers,
// each with optional fraction and a unit suffix,
// such as "300ms", "-1.5h" or "2h45m".
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
// 10分钟前
m, _ := time.ParseDuration("-1m")
m1 := now.Add(m)
fmt.Println(m1)
// 8个小时前
h, _ := time.ParseDuration("-1h")
h1 := now.Add(8 * h)
fmt.Println(h1)
// 一天前
d, _ := time.ParseDuration("-24h")
d1 := now.Add(d)
fmt.Println(d1)
// 10分钟后
mm, _ := time.ParseDuration("1m")
mm1 := now.Add(mm)
fmt.Println(mm1)
// 8小时后
hh, _ := time.ParseDuration("1h")
hh1 := now.Add(hh)
fmt.Println(hh1)
// 一天后
dd, _ := time.ParseDuration("24h")
dd1 := now.Add(dd)
fmt.Println(dd1)
// Sub 计算两个时间差
subM := now.Sub(m1)
fmt.Println(subM.Minutes(), "分钟")
sumH := now.Sub(h1)
fmt.Println(sumH.Hours(), "小时")
sumD := now.Sub(d1)
fmt.Printf("%v 天\n", sumD.Hours()/24)
go get 下载指定版本
go get github.com/ormissia/go-opv@v0.0.2
go chan close
在go
的chan
中,chan
被关闭后,消费者会继续读取channel
中的消息。直到消息被全部读取之后使用i, ok := <-ch
得到的ok
才会变为false
下面是测试代码以及运行时控制台打印结果:
func main() {
ch := make(chan int, 3)
go producer(ch)
for {
i, ok := <-ch
fmt.Printf("consume msg: %d\tok: %v\n", i, ok)
time.Sleep(time.Second * 3)
}
}
func producer(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
fmt.Printf("produce msg: %d\n", i)
time.Sleep(time.Second)
}
close(ch)
fmt.Println("chan closed")
}
输出结果
produce msg: 0
consume msg: 0 ok: true
produce msg: 1
produce msg: 2
consume msg: 1 ok: true
produce msg: 3
produce msg: 4
consume msg: 2 ok: true
produce msg: 5
consume msg: 3 ok: true
produce msg: 6
consume msg: 4 ok: true
produce msg: 7
consume msg: 5 ok: true
produce msg: 8
consume msg: 6 ok: true
produce msg: 9
chan closed
consume msg: 7 ok: true
consume msg: 8 ok: true
consume msg: 9 ok: true
consume msg: 0 ok: false
consume msg: 0 ok: false
异或
- 异或运算法则:无进位相加
- 异或运算性质:
- 0 ^ N = N
- N ^ N = 0
- 满足交换律和结合律
a := 0b1100
b := 0b1001
fmt.Printf("%b",a^b)
//101
简单应用:不申请额外内存交换两个变量的值
a := 0b1100
b := 0b1001
a = a ^ b
b = a ^ b //b = (a ^ b) ^ b = a
a = a ^ b //a = (a ^ b) ^ a = b
fmt.Printf("a:%b,b:%b", a, b)
//a:1001,b:1100
堆
堆的实质是一棵完全二叉树
堆可分为两种类型:
- 大根堆:所有子树的根节点均为最大值
- 小根堆:所有子树的根节点均为最小值
一般情况下堆可以用一个有序数组来存储
[0…i…n]
i
节点的左孩子index
为2*i+1
,右孩子为2i+2
,父节点为(i-1)/2
也有一种特例是从1开始(位运算比加减法快)
[01…i…n]
i
节点的左孩子index
为2*i
即i<<1
,右孩子为2i+1
即i<<1|1
,父节点为i/2
- 堆的基本操作:
- 上浮
- 下沉
- 堆的插入弹出
- 插入
- 在最后插入节点
- 依次上浮
- 弹出
- 弹出根节点
- 将最后一个节点放入根节点
- 将根节点下沉
- 插入
- 堆排序
- 依次弹出根节点