geektutu / blog

极客兔兔的博客,Coding Coding 创建有趣的开源项目。
https://geektutu.com
Apache License 2.0
166 stars 21 forks source link

Go 语言笔试面试题(基础语法) | 极客面试 | 极客兔兔 #87

Open geektutu opened 3 years ago

geektutu commented 3 years ago

https://geektutu.com/post/qa-golang-1.html

Go 语言/golang 笔试题,面试题,基础语法与内部实现原理,包括不限于垃圾回收机制(GC)、面向对象、并发编程等。

lisgroup commented 3 years ago

新手有两个问题想请教下:

1. Q7 什么是 rune 类型

代码中 []rune("Go语言") 意思是使用 rune 强制转换类型是吧?

2. Q13 如何判断 2 个字符串切片(slice) 是相等的?

其中代码块中的第10行

b = b[:len(a)]

这么操作的目的是什么?保证数组切片一样长吗?

geektutu commented 3 years ago

@lisgroup

第一个问题,你的理解是对的,字符串类型转换为 rune 切片类型。

第二个问题,这种写法是为了优化边界检查从而提升运行时效率的。在go语言中称之为 Bounds Check Elimination,简称为 BCE。简言解释下,如果没有这一句,在运行时,Go 语言每次都会对 b[i] 做边界检查,看看是否越界了,如果越界了,就 panic。但是如果加上这一句,Go语言在编译时,能够做一些简单的静态分析,发现 b[i] 是不可能越界的,编译时就能将没必要的边界检查给优化了,那么运行时,就不会对 b[i] 做边界检查,从而提升运行时效率。

这篇文章提供了更多的示例,帮助理解。Bounds Check Elimination - go101.org

givetimetolife commented 3 years ago

_ = b[:len(a)]

geektutu commented 3 years ago

@GiveTimeToLife 我觉得这种写法应该也是OK的,Go 的切片底层对应的数组是一样的,切片只是改变指针的位置,这一步检查几乎是没有损耗的。

zzhaolei commented 3 years ago

2. Q13 如何判断 2 个字符串切片(slice) 是相等的?

针对这个中的b = b[:len(a)],使用go 1.15.6编译,已经没有效果了,在len判断的时候就已经做了优化

geektutu commented 3 years ago

@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
PaiGack commented 6 months ago

q14 如果结构是指针作为接收者者不会调用 String() 方法