31. 演算法
在utf8字串判斷是否包含指定字串,並返回下標。
"北京天安門最美麗" , "天安門"
結果:2
解答:
import ( "fmt" "strings")func main(){ fmt.Println(Utf8Index("北京天安門最美麗", "天安門")) fmt.Println(strings.Index("北京天安門最美麗", "男")) fmt.Println(strings.Index("", "男")) fmt.Println(Utf8Index("12ws北京天安門最美麗", "天安門"))}func Utf8Index(str, substr string) int { asciiPos := strings.Index(str, substr) if asciiPos == -1 || asciiPos == 0 { return asciiPos } pos := 0 totalSize := 0 reader := strings.NewReader(str) for _, size, err := reader.ReadRune(); err == nil; _, size, err = reader.ReadRune() { totalSize += size pos++ // 匹配到 if totalSize == asciiPos { return pos } } return pos}
32,編程
實現一個單例
解答:
package mainimport "sync"// 實現一個單例type singleton struct{}var ins *singletonvar mu sync.Mutex//懶漢加鎖:雖然解決並發的問題,但每次加鎖是要付出代價的func GetIns() *singleton { mu.Lock() defer mu.Unlock() if ins == nil { ins = &singleton{} } return ins}//雙重鎖:避免了每次加鎖,提高代碼效率func GetIns1() *singleton { if ins == nil { mu.Lock() defer mu.Unlock() if ins == nil { ins = &singleton{} } } return ins}//sync.Once實現var once sync.Oncefunc GetIns2() *singleton { once.Do(func() { ins = &singleton{} }) return ins}
33,執行下面的代碼發生什嗎?
package mainimport ( "fmt" "time")func main() { ch := make(chan int, 1000) go func() { for i := 0; i < 10; i++ { ch <- i } }() go func() { for { a, ok := <-ch if !ok { fmt.Println("close") return } fmt.Println("a: ", a) } }() close(ch) fmt.Println("ok") time.Sleep(time.Second * 100)}
考點:channel
往已經關閉的channel寫入資料會panic的。
結果:
panic: send on closed channel
34,執行下面的代碼發生什嗎?
import "fmt"type ConfigOne struct { Daemon string}func (c *ConfigOne) String() string { return fmt.Sprintf("print: %v", p)}func main() { c := &ConfigOne{} c.String()}
考點:fmt.Sprintf
如果類型實現String(),%v和%v格式將使用String()的值。因此,對該類型的String()函數內的類型使用%v會導致無限遞迴。
編譯報錯:
runtime: goroutine stack exceeds 1000000000-byte limitfatal error: stack overflow
35,編程題
反轉整數
反轉一個整數,例如:
例子1: x = 123, return 321
例子2: x = -123, return -321
輸入的整數要求是一個 32bit 有符號數,如果反轉後溢出,則輸出 0
func reverse(x int) (num int) { for x != 0 { num = num*10 + x%10 x = x / 10 } // 使用 math 包中定義好的最大最小值 if num > math.MaxInt32 || num < math.MinInt32 { return 0 } return}
36,編程題
合并重疊區間
給定一組 區間,合并所有重疊的 區間。
例如:
給定:[1,3],[2,6],[8,10],[15,18]
返回:[1,6],[8,10],[15,18]
type Interval struct { Start int End int}func merge(intervals []Interval) []Interval { if len(intervals) <= 1 { return intervals } sort.Slice(intervals, func(i, j int) bool { return intervals[i].Start < intervals[j].Start }) res := make([]Interval, 0) swap := Interval{} for k, v := range intervals { if k == 0 { swap = v continue } if v.Start <= swap.End { swap.End = v.End } else { res = append(res, swap) swap = v } } res = append(res, swap) return res}
37.輸出什嗎?
package mainimport ( "fmt")func main() { fmt.Println(len("你好bj!"))}
考點:編碼長度
輸出9
38.編譯並運行如下代碼會發生什嗎?
package mainimport "fmt"type Test struct { Name string}var list map[string]Testfunc main() { list = make(map[string]Test) name := Test{"xiaoming"} list["name"] = name list["name"].Name = "Hello" fmt.Println(list["name"])}
考點:map
編程報錯cannot assign to struct field list["name"].Name in map
。
因為list["name"]不是一個普通的指標值,map的value本身是不可定址的,因為map中的值會在記憶體中移動,並且舊的指標地址在map改變時會變得無效。
定義的是var list map[string]Test,注意哦Test不是指標,而且map我們都知道是可以自動擴容的,那麼原來的儲存name的Test可能在地址A,但是如果map擴容了地址A就不是原來的Test了,所以go就不允許我們寫資料。你改為var list map[string]*Test試試看。
39.ABCD中哪一行存在錯誤?
type S struct {}func f(x interface{}) {}func g(x *interface{}) {}func main() { s := S{} p := &s f(s) //A g(s) //B f(p) //C g(p) //D}
考點:interface
看到這道題需要第一時間想到的是Golang是強型別語言,interface是所有golang類型的父類,類似Java的Object。
函數中func f(x interface{})
的interface{}
可以支援傳入golang的任何類型,包括指標,但是函數func g(x *interface{})
只能接受*interface{}
.
40.編譯並運行如下代碼會發生什嗎?
package mainimport ( "sync" //"time")const N = 10var wg = &sync.WaitGroup{}func main() { for i := 0; i < N; i++ { go func(i int) { wg.Add(1) println(i) defer wg.Done() }(i) } wg.Wait()}
考點:WaitGroup
這是使用WaitGroup經常犯下的錯誤!請各位同學多次運行就會發現輸出都會不同甚至又出現報錯的問題。
這是因為go
執行太快了,導致wg.Add(1)
還沒有執行main函數就執行完畢了。
改為如下試試
for i := 0; i < N; i++ { wg.Add(1) go func(i int) { println(i) defer wg.Done() }(i) } wg.Wait()
附錄
https://zhuanlan.zhihu.com/p/35058068?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
https://stackoverflow.com/questions/42600920/runtime-goroutine-stack-exceeds-1000000000-byte-limit-fatal-error-stack-overf
https://studygolang.com/topics/3853