1.下面两处打印的值是否相同?请简要说明。

1func main() {
2 var val int
3 println(&val)
4 f(10000)
5 println(&val)
6}
7
8func f(i int) {
9 if i--; i == 0 {
10 return
11 }
12 f(i)
13}

参考答案及解析:不同。知识点:栈增长、逃逸分析。每个 groutine 都会分配相应的栈内存,比如 Go 1.11 版本是 2Kb,随着程序运行,栈内存会发生增长或缩小,协程会重新申请栈内存块。就像这个题目,循环调用 f(),发生深度递归,栈内存不断增大,当超过范围时,会重新申请栈内存,所以 val 的地址会变化。

这道题还有个特别注意的地方,如果将 println() 函数换成 fmt.Println() 会发现,打印结果相同。为什么?因为函数 fmt.Println() 使变量 val 发生了逃逸,逃逸到堆内存,即使协程栈内存重新申请,val 变量在堆内存的地址也不会改变。

2.下面代码 A 处输出什么?请简要说明。

1func main() {
2 var val int
3
4 a := &val
5 println(a)
6
7 f(10000)
8
9 b := &val
10 println(b)
11
12 println(a == b) // A
13}
14
15func f(i int) {
16 if i--; i == 0 {
17 return
18 }
19 f(i)
20}
  • A. ture
  • B. false

参考答案及解析:A。这道题和上一道有一定联系,a 是指向变量 val 的指针,我们知道 val 变量的地址发生了改变,a 指向 val 新的地址是由内存管理自动实现的。

1func main() {
2 var val int
3
4 a := &val
5 println(a)
6
7 f(10000)
8
9 b := &val
10 println(a) // a b 的值相同
11 println(b)
12
13 println(a == b) // A
14}
15
16func f(i int) {
17 if i--; i == 0 {
18 return
19 }
20 f(i)
21}

解析若有不妥之处,欢迎在留言区交流、指正!

一起来看下今天的题目:

1.下面代码输出什么?请简要说明。

1func main() {
2 x := []int{100, 200, 300, 400, 500, 600, 700}
3 twohundred := &x[1]
4 x = append(x, 800)
5 for i := range x {
6 x[i]++
7 }
8 fmt.Println(*twohundred)
9}

2.下面代码输出什么?请简要说明。

1func main() {
2 a := []int{0, 1}
3 fmt.Printf("%v", a[len(a):])
4}

答案以及解析会在下一篇文章中给出,鼓励大家在留言区留下答案,抱团学习,日拱一卒,每天进步一点!


Go 面试每天一篇(第 112 天)_引用变量

Go 面试每天一篇(第 112 天)_堆内存_02