Golang面試題解析(四)

來源:互聯網
上載者:User

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.