blog
blog copied to clipboard
Go 语言笔试面试题(基础语法) | 极客面试 | 极客兔兔
https://geektutu.com/post/qa-golang-1.html
Go 语言/golang 笔试题,面试题,基础语法与内部实现原理,包括不限于垃圾回收机制(GC)、面向对象、并发编程等。
新手有两个问题想请教下:
1. Q7 什么是 rune 类型
代码中 []rune("Go语言")
意思是使用 rune
强制转换类型是吧?
2. Q13 如何判断 2 个字符串切片(slice) 是相等的?
其中代码块中的第10行
b = b[:len(a)]
这么操作的目的是什么?保证数组切片一样长吗?
@lisgroup
第一个问题,你的理解是对的,字符串类型转换为 rune 切片类型。
第二个问题,这种写法是为了优化边界检查从而提升运行时效率的。在go语言中称之为 Bounds Check Elimination
,简称为 BCE。简言解释下,如果没有这一句,在运行时,Go 语言每次都会对 b[i] 做边界检查,看看是否越界了,如果越界了,就 panic。但是如果加上这一句,Go语言在编译时,能够做一些简单的静态分析,发现 b[i] 是不可能越界的,编译时就能将没必要的边界检查给优化了,那么运行时,就不会对 b[i] 做边界检查,从而提升运行时效率。
这篇文章提供了更多的示例,帮助理解。Bounds Check Elimination - go101.org
_ = b[:len(a)]
@GiveTimeToLife 我觉得这种写法应该也是OK的,Go 的切片底层对应的数组是一样的,切片只是改变指针的位置,这一步检查几乎是没有损耗的。
2. Q13 如何判断 2 个字符串切片(slice) 是相等的?
针对这个中的b = b[:len(a)]
,使用go 1.15.6
编译,已经没有效果了,在len判断
的时候就已经做了优化
@zzhaolei 感谢指出问题,新版本将 b = b[:len(a)]
去掉后,也不会产生边界检查(Bounds Check)了。
是否产生边界检查,可以用下面的命令验证。
go build -gcflags="-d=ssa/check_bce/debug=1" main.go
例如针对下面的例子,如果 s[2] 没有越界,那么 s[1] 和 s[0] 肯定是合法,因此只需要对 s[2] 做一次边界检查即可:
package main
func f(s []int) {
_ = s[2]
_ = s[1]
_ = s[0]
}
func main() {}
go build -gcflags="-d=ssa/check_bce/debug=1" main.go
# command-line-arguments
./main.go:4:7: Found IsInBounds
q14 如果结构是指针作为接收者者不会调用 String() 方法