题目
1 写出以下逻辑,要求每秒钟调用一次proc并保证程序不退出
package main
func main() {
go func() {
// 1 在这里需要你写算法
// 2 要求每秒钟调用一次proc函数
// 3 要求程序不能退出
}()
select {}
}
func proc() {
panic("ok")
}
2 下面代码写法有什么问题?
package main
import (
"fmt"
)
type Stduent struct {
Age int
}
func main() {
kv := map[string]Stduent{"menglu": {Age: 21}}
kv["menglu"].Age = 22
s := []Stduent{{Age: 21}}
s[0].Age = 22
fmt.Println(kv, s)
}
3.写出以下打印结果,并解释下为什么这么打印的。
package main
import (
"fmt"
)
func main() {
str1 := []string{"a", "b", "c"}
str2 := str1[1:]
str2[1] = "new"
fmt.Println(str1)
str2 = append(str2, "z", "x", "y")
fmt.Println(str1)
}
4.为sync.WaitGroup中Wait函数支持WaitTimeout功能( )
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
c := make(chan struct{})
for i := 0; i < 10; i++ {
wg.Add(1)
go func(num int, close <-chan struct{}) {
defer wg.Done()
<-close
fmt.Println(num)
}(i, c)
}
if WaitTimeout(&wg, time.Second*5) {
close(c)
fmt.Println("timeout exit")
}
time.Sleep(time.Second * 10)
}
func WaitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
// 要求手写代码
// 要求sync.WaitGroup支持timeout功能
// 如果timeout到了超时时间返回true
// 如果WaitGroup自然结束返回false
}
答案
1.写出以下逻辑,要求每秒钟调用一次proc并保证程序不退出
func main() {
go func() {
for {
time.Sleep(time.Second)
func() {
defer func() {
if err := recover(); err != nil {
fmt.Println("捕获异常:", err)
}
}()
proc()
}()
}
}()
select {}
}
func proc() {
panic("ok")
}
2 kv["menglu"].Age = 22
会报错,不能修改Age,cannot assign to struct field kv["menglu"].Age in map
map中struct不能修改值的原因是struct类型是值类型。考虑以下情况:
stu1 := Student{Name:"Mike", Age: 21}
kv := map[string]Student{"Mike": stu1}
我们定义了一个map,这个map的主要作用就是可以通过人的名字来直接取得该名字对应的个人信息。现在我们要修改stu1
的年龄,但是由于struct是值类型,也就是在赋值给kv
的时候进行了值拷贝,存在kv
中的只是stu1
的一份拷贝,所以通过修改kv
中的对象,并不能达到修改stu1
的目的。
题外话:关于struct值传递有另外一个坑就是,对于声明了指针接收者方法的结构体,是不能直接赋值给接口的。
3.基础题目:搞明白切片是不是值类型而是引用类型就好。所以str2
和str1
底层数据指向的是同一个地方。但是当str2
使用append
进行插入操作的时候,如果底层数组的长度不够会进行扩容,也就是重新申请一块新的长度为原底层数组长度两倍的新数组,将原底层数组的数据复制到新的数组,在新的数组插入新的数据,然后将str2
的指针指向新的数组。而str1
还是指向原先的底层数组,所以str1
保持不变。
func WaitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
wgChan := make(chan struct{})
go func() {
wg.Wait()
wgChan <- struct{}{}
}()
select {
case <-wgChan:
return false
case <- time.After(2 * time.Second):
return true
}
}