1、golang 中 make 和 new 的区别?
make一般用于map,切片,chan分配内存
new一般用于string,int和数字分配内存
make返回的新分配类型的引用类型,
new返回的新分配类型的指针
2、数组和切片的区别
数组是值类型,切片是引用类型
数组是定长的,访问不能越界,切片可以动态扩容
切片的底层是指向一个数组,如果发生扩容,则指向一个新数组
3、for range 的时候它的地址会发生变化么?
不会,遍历的时候采取覆盖的策略把值赋过去,所以在使用goroutine的时候,不要直接传地址,使用一个新建的临时变量
4、go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?
defer一般用于释放资源,关闭文件,关闭链接,释放锁,收尾工作,捕获panic等
defer是顺序:return->return value->defer 所以defer可以修改最终返回值
有名返回值和指针在defer里修改时,会函数影响返回值
5.rune类型
byte类型等同于int8 用来处理ascii字符
rune类型等同于int32 用来处理Unicode或者utf8
6.golang 中解析 tag 是怎么实现的?反射原理是什么?
tag通过反射来解析
func TypeOf(i interface{}) Type {...}
func ValueOf(i interface{}) Value {...}
7、调用函数传入结构体时,应该传值还是指针? (Golang 都是传值)
首先,go里面没有引用类型,所有的函数传递都是值传递,但是像slice,map,channel由于其内置结构里存在指针,因此传递以上类型会被修改原先数据。
如果想要修改结构体,就传指针
如果不修改,传值
8.讲讲 Go 的 slice 底层数据结构和一些特性
当slice的容量小于1024时,会进行翻倍扩容
当slice的容量大于1024时,在不考虑内存对齐的情况,是1.25倍扩容
如果考虑内存对齐的话,是大于1.25倍
9.讲讲 Go 的 select 底层数据结构和一些特性?
select 为 golang 提供了多路 IO 复用机制,和其他 IO 复用一样,用于检测是否有读写事件是否 ready
1)select 操作至少要有一个 case 语句,出现读写 nil 的 channel 该分支会忽略,在 nil 的 channel 上操作则会报错。
2)select 仅支持管道,而且是单协程操作。
3)每个 case 语句仅能处理一个管道,要么读要么写。
4)多个 case 语句的执行顺序是随机的。
5)存在 default 语句,select 将不会阻塞,但是存在 default 会影响性能。
10.讲讲 Go 的 defer 底层数据结构和一些特性
每个 defer 语句都对应一个_defer 实例,多个实例使用指针连接起来形成一个单连表,保存在 gotoutine 数据结构中,每次插入_defer 实例,均插入到链表的头部,函数结束再一次从头部取出,从而形成后进先出的效果
11、单引号,双引号,反引号的区别?
单引号,表示byte类型或rune类型,对应 uint8和int32类型,默认是 rune 类型。byte用来强调数据是raw data,而不是数字;而rune用来表示Unicode的code point。
双引号,才是字符串,实际上是字符数组。可以用索引号访问某字节,也可以用len()函数来获取字符串所占的字节长度。
反引号,表示字符串字面量,但不支持任何转义序列。字面量 raw literal string 的意思是,你定义时写的啥样,它就啥样,你有换行,它就换行。你写转义字符,它也就展示转义字符。
参考: