題目
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
}
}