开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 11 天,点击查看活动详情
今天来学习下Go常见的习题问题(二十一),也是面试中可能会遇到的,让我们来一起学习吧~
切片派生
观察下列代码,判断会不会引发panic?
func main() {
x := make([]int, 2, 10)
_ = x[6:10]
_ = x[6:]
_ = x[2:]
}
参考答案:会发生异常,错误信息为:panic: runtime error: slice bounds out of range [6:2],错误出现在_ = x[6:],这里涉及到切片的截取操作,通过使用截取符号[i:j],如果 j 省略,默认是原切片或者数组的长度,原切片len(x)为2,所以最后转换的形式变为[6:2],下标low大于下标high,所以会发生panic异常,如果要在子切片表达式中省略若干下标,需要遵守以下这些规则:
- 如果下标
low为零,则它可被省略 - 如果下标
high等于len(baseSlice),则它可被省略 - 三下标形式中的下标
max在任何情况下都不可被省略
//以下子切片表达式都是等价的
baseSlice[0 : len(baseSlice)]
baseSlice[: len(baseSlice)]
baseSlice[0 :]
baseSlice[:]
baseSlice[0 : len(baseSlice) : cap(baseSlice)]
baseSlice[: len(baseSlice) : cap(baseSlice)]
同步
观察下列代码,判断输出结果是否符合预期?
type data struct {
sync.Mutex
}
func (d data) test(s string) {
d.Lock()
defer d.Unlock()
for i:=0;i<5 ;i++ {
fmt.Println(s,i)
time.Sleep(time.Second)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
var d data
go func() {
defer wg.Done()
d.test("read")
}()
go func() {
defer wg.Done()
d.test("write")
}()
wg.Wait()
}
参考答案:输出预期不符,输出结果为:write 0 read 0 ..,这里发生了锁失效,将 Mutex 作为匿名字段时,相关的方法必须使用pointer-receiver,否则会导致锁机制失效,这里需要receiver类型改为*data后正常,也可以使用嵌入*Mutex来避免复制问题,但是需要专门的初始化,如下所示:
//指针修复法
func (d *data) test(s string) {
d.Lock()
defer d.Unlock()
for i := 0; i < 5; i++ {
fmt.Println(s, i)
time.Sleep(time.Second)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
//添加mutex的初始化
var d data = data{new(sync.Mutex)}
go func() {
defer wg.Done()
d.test("read")
}()
go func() {
defer wg.Done()
d.test("write")
}()
wg.Wait()
}
总结
今天浅谈了Go的习题(二十一),主要介绍了GO面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!