几个golang面试题及解析

马谦的博客 · · 1754 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、以下代码的输出内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
package main
import (
"fmt"
)
func main() {
defer_call()
}
func defer_call() {
defer func() { fmt.Println("打印前") }()
defer func() { fmt.Println("打印中") }()
defer func() { fmt.Println("打印后") }()
panic("触发异常")
}

答案

1
2
3
4
打印后
打印中
打印前
panic: 触发异常

解析

考查defer和panic组合的情况,在有panic时,会先执行defer然后再把恐慌传递出去。

更多相关内容可查看defer常见的坑以及官方文档描述

二、以下代码有什么问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func pase_student() map[string]*student {
m := make(map[string]*student)
stus := []student{
{Name: "zhou", Age: 24},
{Name: "li", Age: 23},
{Name: "wang", Age: 22},
}
for _, stu := range stus {
m[stu.Name] = &stu
}
return m
}
func main() {
students := pase_student()
for k, v := range students {
fmt.Printf("key=%s,value=%v \n", k, v)
}
}

答案

1
2
3
key=zhou,value=&{wang 22} 
key=li,value=&{wang 22}
key=wang,value=&{wang 22}

解析

for循环使用stu遍历时,stu只是一个临时变量,遍历过程中指针地址不变,所以后面的赋值都是指向了同一个内存区域,导致最后所有的信息都一致。

其实这个现象不仅仅存在于go中,c/c++python中也存在,原理也都一样。

修改方案

1
2
3
4
for i, _ := range stus {
stu:=stus[i]
m[stu.Name] = &stu
}

三、下面的代码会输出什么,并说明原因

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"sync"
"fmt"
)

func main() {
wg := sync.WaitGroup{}
wg.Add(21)
for i := 0; i < 10; i++ {
go func() {
fmt.Println("i: ", i)
wg.Done()
}()
}
for j := 0; j < 10; j++ {
go func(x int) {
fmt.Println("j: ", x)
wg.Done()
}(j)
}
wg.Wait()
}

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
j:  9
i: 10
j: 0
j: 1
j: 2
j: 3
j: 4
j: 5
j: 6
i: 10
i: 10
i: 10
i: 10
i: 10
j: 8
i: 10
i: 10
i: 10
j: 7
i: 10

解析

第一个循环中的打印是在函数中打印的,i是外部的变量,执行go func(){}后代码不会立即执行,一般当该代码片段被调度器执行的时候,for循环已经全部执行完毕,此时的i为10。所以i会打印10个10,而j则会无序打印1-10。

四、下面代码会输出什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowA()
}

答案

1
2
showA
showB

解析

go中没有继承,只有组合。Teacher中的People是一个匿名对象,通过它调用的函数都是自身的。


有疑问加站长微信联系(非本文作者)

本文来自:马谦的博客

感谢作者:马谦的博客

查看原文:几个golang面试题及解析

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1754 次点击  ∙  1 赞  
加入收藏 微博
3 回复  |  直到 2019-06-25 18:27:25
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传