Golang面試題(一)

題目

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.基礎題目:搞明白切片是不是值類型而是引用類型就好。所以str2str1底層數據指向的是同一個地方。但是當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
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章