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 的意思是,你定义时写的啥样,它就啥样,你有换行,它就换行。你写转义字符,它也就展示转义字符。







参考: