开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情
今天来学习下Go常见的习题问题(二十五),也是面试中可能会遇到的,让我们来一起学习吧~
逃逸分析
观察下列代码,判断变量p是否会因为函数结束而释放?
type TimesMatcher struct {
base int
}
func NewTimesMatcher(base int) *TimesMatcher {
return &TimesMatcher{base:base}
}
func main() {
p := NewTimesMatcher(10)
fmt.Println(p)
}
参考答案:不会被释放,因为根据Go语言中的内存回收机制gc,只要有一个指针引用赋值给一个变量,那么这个变量就不会被释放,这里发生了逃逸分析,因为当函数执行完毕,分配的栈内存就会被销毁,这块是有编译器负责分配和销毁,但是指针引用已经返回给变量p,那么外部函数通过变量p通过*p来取值,虽然地址存在但是内存已经被回收释放,就存在野指针的情况,所以会发生逃逸(顾名思义:把栈上内存分配到堆上),因此在 Go 语言中返回函数参数或临时变量是安全的
iota
观察下列代码,判断输出结果是什么?为什么?
const (
azero = iota
aone = iota
)
const (
info = "msg"
bzero = iota
bone = iota
)
func main() {
fmt.Println(azero, aone)
fmt.Println(bzero, bone)
}
参考答案:输出0 1 1 2,这里考察iota 的使用,在一个常量声明代码块中,iota出现在第一行初始值才为0,其他情况是根据所在行数判断
同级文件的包名不允许有多个
一个文件夹下只能有一个包,可以多个.go文件,但这些文件必须属于同一个包
接口
观察下列代码,判断是否通过编译?
type data struct {
name string
}
func (p *data) print() {
fmt.Println("name:", p.name)
}
type printer interface {
print()
}
func main() {
d1 := data{"one"}
d1.print()
var d2 printer = data{"two"}
d2.print()
}
参考答案:不能通过编译,因为结构类型data{"two"}没有实现print()方法,需要使用var d2 printer = &data{"two"}才可以
总结
今天浅谈了Go的习题(二十五),主要介绍了GO面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!