1.Map遍历的顺序是什么?
go语言中map的内部实现是通过构造一个hash桶,每个桶内再创建一个链表来储存数据的,当遍历一个map对象时,会随机挑选一个桶的一个链表位置开始,按照桶和链表顺序进行遍历。所以在map遍历时,是随机选择一个起始位置,然后按照顺序遍历,既随机又和数据的输入顺序有关系
2.在为切片append一个元素时,为什么要重新给这个切片赋值?
大家都知道对一个切片添加元素时,应该写作strSlice = append(strSlice, "b")的形式,但是切片是一个指针,为什么添加新元素的时候还需要重新赋值呢?原因就在切片的容量上。切片的指针指向的是一个底层数组,如果切片的底层数组没有足够的可用容量,append() 函数会创建一个新的底层数组,将被引用的现有的值复制到新数组里,再追加新的值。这时候就需要为strSlice赋值,以指向新的指针啦
3.如何判断channel关闭?
大家在读取一个channel的值的时候,可以通过c := <- strChan获取,但是channel在关闭时,也会向所有读取的地方返回空值,如何区分channel传过来的值是正常传值还是关闭的标识呢?我们可以改为c, ok := <- strChan,来区分,当ok的值为false时,即表示channel关闭
4.如何在判断channel是否关闭时,防止进程阻塞?
我们经常会使用context包来判断上下文是否结束,但是应该如何能够获取ctx的状态的同时,避免进程阻塞呢?可以采用下面的写法
func do(ctx context.Context) {
select {
case <- ctx.Done():
fmt.Println("ctx done")
return
default:
}
doOther()
}
5.如何为程序在编译时打上版本号?
我们常看开源项目下有一个version文件用来设置版本号,那么,如何在编译的时候把版本号写入代码呢?可以在build的时候添加参数,就能将main包中的Version全局变量重新赋值为VERSION文件的值了
go build -ldflags "-X main.Version=$(cat VERSION)"