文本描述
Go语言笔试面试题(实现原理) 2020-09-04 23:10:10 golang interview questions Go语言笔试面试题汇总,Github Q1 init() 函数是什么时候执行的? 答案 init()函数是 Go程序初始化的一部分。Go程序初始化先于 main函数,由 runtime初始化每个导入的包,初始化顺序不是按照从上到下的导入顺序,而是按 照解析的依赖关系,没有依赖的包最先初始化。 每个包首先初始化包作用域的常量和变量(常量优先于变量),然后执行包的 init()函数。同一个包,甚至是同一个源文件可以有多个init()函数。init()函 数没有入参和返回值,不能被其他函数调用,同一个包内多个init()函数的执行 顺序不作保证。 一句话总结: import –> const –> var –>init() –>main() 示例: package main import "fmt" func init() { fmt.Println("init1:", a) } func init() { fmt.Println("init2:", a) } var a = 10 const b = 100 func main() { fmt.Println("main:", a) } //执行结果 // init1: 10 // init2: 10 // main: 10 Q2 Go 语言的局部变量分配在栈上还是堆上? 答案 由编译器决定。Go语言编译器会自动决定把一个变量放在栈还是放在堆,编译器 会做逃逸分析(escape analysis),当发现变量的作用域没有超出函数范围,就可以 在栈上,反之则必须分配在堆上。 func foo() *int { v := 11 return &v } func main() { m := foo() println(*m) // 11 } foo()函数中,如果 v分配在栈上,foo函数返回时,&v就不存在了,但是这段函 数是能够正常运行的。Go编译器发现 v的引用脱离了 foo的作用域,会将其分配 在堆上。因此,main函数中仍能够正常访问该值。 Q3 2 个 interface 可以比较吗? 答案 Go语言中,interface的内部实现包含了 2个字段,类型T和值V,interface可以 使用==或!=比较。2个 interface相等有以下 2种情况 1)两个 interface均等于 nil(此时 V和 T都处于 unset状态) 2)类型 T相同,且对应的值 V相等。 看下面的例子: type Stu struct { Name string } type StuInt interface{} func main() { var stu1, stu2 StuInt = &Stu{"Tom"}, &Stu{"Tom"} var stu3, stu4 StuInt = Stu{"Tom"}, Stu{"Tom"} fmt.Println(stu1 == stu2) // false fmt.Println(stu3 == stu4) // true } stu1和stu2对应的类型是*Stu,值是 Stu结构体的地址,两个地址不同,因此结 果为 false。stu3和stu4对应的类型是Stu,值是 Stu结构体,且各字段相等,因 此结果为 true。 Q4 两个 nil 可能不相等吗? 答案 可能。 接口(interface)是对非接口值(例如指针,struct等)的封装,内部实现包含 2个字 段,类型T和值V。一个接口等于 nil,