Golang常见知识点 | 青训营笔记

79 阅读3分钟

1、golang 中 make 和 new 的区别?(基本必问)

共同点: 给变量分配内存

不同点:

1)作用变量类型不同,new给string,int和数组分配内存,make给切片,map,channel分配内存;

2)返回类型不一样,new返回指向变量的指针,make返回变量本身;

3)new 分配的空间被清零。make 分配空间后,会进行初始化;

  1. 字节的面试官还说了另外一个区别,就是分配的位置,在堆上还是在栈上?这块我比较模糊,大家可以自己探究下,我搜索出来的答案是golang会弱化分配的位置的概念,因为编译的时候会自动内存逃逸处理,懂的大佬帮忙补充下:make、new内存分配是在堆上还是在栈上?

2、数组和切片的区别 (基本必问)

相同点:

1)只能存储一组相同类型的数据结构

2)都是通过下标来访问,并且有容量长度,长度通过 len 获取,容量通过 cap 获取

区别:

1)数组是定长,访问和复制不能超过数组定义的长度,否则就会下标越界,切片长度和容量可以自动扩容

2)数组是值类型,切片是引用类型,每个切片都引用了一个底层数组,切片本身不能存储任何数据,都是这底层数组存储数据,所以修改切片的时候修改的是底层数组中的数据。切片一旦扩容,指向一个新的底层数组,内存地址也就随之改变

简洁的回答:

1)定义方式不一样 2)初始化方式不一样,数组需要指定大小,大小不改变 3)在函数传递中,数组切片都是值传递。

数组的定义

var a1 [3]int

var a2 [...]int{1,2,3}

切片的定义

var a1 []int

var a2 :=make([]int,3,5)

数组的初始化

a1 := [...]int{1,2,3}

a2 := [5]int{1,2,3}

切片的初始化

b:= make([]int,3,5)

3、for range 的时候它的地址会发生变化么?

答:在 for a,b := range c 遍历中, a 和 b 在内存中只会存在一份,即之后每次循环时遍历到的数据都是以值覆盖的方式赋给 a 和 b,a,b 的内存地址始终不变。由于有这个特性,for 循环里面如果开协程,不要直接把 a 或者 b 的地址传给协程。解决办法:在每次循环时,创建一个临时变量。

4、go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?

作用:defer延迟函数,释放资源,收尾工作;如释放锁,关闭文件,关闭链接;捕获panic;

避坑指南:defer函数紧跟在资源打开后面,否则defer可能得不到执行,导致内存泄露。

多个 defer 调用顺序是 LIFO(后入先出),defer后的操作可以理解为压入栈中