欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

golang面試題解析

最近在很多地方看到了golang的面試題,看到了很多人對Golang的面試題心存恐懼,也是為了復(fù)習(xí)基礎(chǔ),我把解題的過程總結(jié)下來。

成都創(chuàng)新互聯(lián)公司總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護(hù)、公眾號搭建、微信小程序定制開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!

面試題

1. 寫出下面代碼輸出內(nèi)容。

package main

import (
    "fmt"
)

func main() {
    defer_call()
}

func defer_call() {
    defer func() { fmt.Println("打印前") }()
    defer func() { fmt.Println("打印中") }()
    defer func() { fmt.Println("打印后") }()

    panic("觸發(fā)異常")
}

考點:defer執(zhí)行順序
解答: defer 是后進(jìn)先出
panic 需要等defer 結(jié)束后才會向上傳遞。出現(xiàn)panic恐慌時候,會先按照defer的后入先出的順序執(zhí)行,最后才會執(zhí)行panic。

打印后
打印中
打印前
panic: 觸發(fā)異常

2. 以下代碼有什么問題,說明原因。

type student struct {
    Name string
    Age  int
}

func pase_student() {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        m[stu.Name] = &stu
    }

}

考點:foreach
解答:這樣的寫法初學(xué)者經(jīng)常會遇到的,很危險!與Java的foreach一樣,都是使用副本的方式。所以m[stu.Name]=&stu實際上一致指向同一個指針,最終該指針的值為遍歷的最后一個struct的值拷貝。就像想修改切片元素的屬性:

for _, stu := range stus {
    stu.Age = stu.Age+10
}

也是不可行的。大家可以試試打印出來:

func pase_student() {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    // 錯誤寫法
    for _, stu := range stus {
        m[stu.Name] = &stu
    }

    for k,v:=range m{
        println(k,"=>",v.Name)
    }

    // 正確
    for i:=0;i<len(stus);i++  {
        m[stus[i].Name] = &stus[i]
    }
    for k,v:=range m{
        println(k,"=>",v.Name)
    }
}

3. 下面的代碼會輸出什么,并說明原因

func main() {
    runtime.GOMAXPROCS(1)
    wg := sync.WaitGroup{}
    wg.Add(20)
    for i := 0; i < 10; i++ {
        go func() {
            fmt.Println("A: ", i)
            wg.Done()
        }()
    }
    for i := 0; i < 10; i++ {
        go func(i int) {
            fmt.Println("B: ", i)
            wg.Done()
        }(i)
    }
    wg.Wait()
}

考點:go執(zhí)行的隨機(jī)性和閉包
解答:誰也不知道執(zhí)行后打印的順序是什么樣的,所以只能說是隨機(jī)數(shù)字。但是A:均為輸出10,B:從0~9輸出(順序不定)。第一個go func中i是外部for的一個變量,地址不變化。遍歷完成后,最終i=10。故go func執(zhí)行時,i的值始終是10。

第二個go func中i是函數(shù)參數(shù),與外部for中的i完全是兩個變量。尾部(i)將發(fā)生值拷貝,go func內(nèi)部指向值拷貝地址。

4. 下面代碼會輸出什么?

type People struct{}

func (p *People) ShowA() {
    fmt.Println("showA")
    p.ShowB()
}
func (p *People) ShowB() {
    fmt.Println("showB")
}

type Teacher struct {
    People
}

func (t *Teacher) ShowB() {
    fmt.Println("teacher showB")
}

func main() {
    t := Teacher{}
    t.ShowA()
}

考點:go的組合繼承
解答:這是Golang的組合模式,可以實現(xiàn)OOP的繼承。被組合的類型People所包含的方法雖然升級成了外部類型Teacher這個組合類型的方法(一定要是匿名字段),但它們的方法(ShowA())調(diào)用時接受者并沒有發(fā)生變化。此時People類型并不知道自己會被什么類型組合,當(dāng)然也就無法調(diào)用方法時去使用未知的組合者Teacher類型的功能。

showA
showB

5. 下面代碼會觸發(fā)異常嗎?請詳細(xì)說明

func main() {
    runtime.GOMAXPROCS(1)
    int_chan := make(chan int, 1)
    string_chan := make(chan string, 1)
    int_chan <- 1
    string_chan <- "hello"
    select {
    case value := <-int_chan:
        fmt.Println(value)
    case value := <-string_chan:
        panic(value)
    }
}

考點:select隨機(jī)性
解答: select會隨機(jī)選擇一個可用通用做收發(fā)操作。所以代碼是有肯觸發(fā)異常,也有可能不會。單個chan如果無緩沖時,將會阻塞。但結(jié)合 select可以在多個chan間等待執(zhí)行。有三點原則: 

  •  select 中只要有一個case能return,則立刻執(zhí)行。 *

  • 當(dāng)如果同一時間有多個case均能return則偽隨機(jī)方式抽取任意一個執(zhí)行。

  •  如果沒有一個case能return則可以執(zhí)行”default”塊。

6. 下面代碼輸出什么?

func calc(index string, a, b int) int {
    ret := a + b
    fmt.Println(index, a, b, ret)
    return ret
}

func main() {
    a := 1
    b := 2
    defer calc("1", a, calc("10", a, b))
    a = 0
    defer calc("2", a, calc("20", a, b))
    b = 1
}

考點:defer執(zhí)行順序
解答:這道題類似第1題需要注意到defer執(zhí)行順序和值傳遞 index:1肯定是最后執(zhí)行的,但是index:1的第三個參數(shù)是一個函數(shù),所以最先被調(diào)用calc("10",1,2)==>10,1,2,3 執(zhí)行index:2時,與之前一樣,需要先調(diào)用calc("20",0,2)==>20,0,2,2 執(zhí)行到b=1時候開始調(diào)用,index:2==>calc("2",0,2)==>2,0,2,2 最后執(zhí)行index:1==>calc("1",1,3)==>1,1,3,4

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4

7. 請寫出以下輸入內(nèi)容

func main() {
    s := make([]int, 0)
    s = append(s, 1, 2, 3)
    fmt.Println(s)
}

考點:make默認(rèn)值和append
解答: make初始化是由默認(rèn)值的哦,此處默認(rèn)值為0

[0 0 0 0 0 1 2 3]

大家試試改為:

s := make([]int, 0)
s = append(s, 1, 2, 3)
fmt.Println(s)//[1 2 3]

8. 下面的代碼有什么問題?

type UserAges struct {
	ages map[string]int
	sync.Mutex
}

func (ua *UserAges) Add(name string, age int) {
	ua.Lock()
	defer ua.Unlock()
	ua.ages[name] = age
}

func (ua *UserAges) Get(name string) int {
	if age, ok := ua.ages[name]; ok {
		return age
	}
	return -1
}

考點:map線程安全
解答:可能會出現(xiàn)fatal error: concurrent map read and map write. 修改一下看看效果

func (ua *UserAges) Get(name string) int {
    ua.Lock()
    defer ua.Unlock()
    if age, ok := ua.ages[name]; ok {
        return age
    }
    return -1
}

9. 下面的迭代會有什么問題?

func (set *threadSafeSet) Iter() <-chan interface{} {
	ch := make(chan interface{})
	go func() {
		set.RLock()

		for elem := range set.s {
			ch <- elem
		}

		close(ch)
		set.RUnlock()

	}()
	return ch
}

考點:chan緩存池
解答:看到這道題,我也在猜想出題者的意圖在哪里。 chan?sync.RWMutex?go?chan緩存池?迭代? 所以只能再讀一次題目,就從迭代入手看看。既然是迭代就會要求set.s全部可以遍歷一次。但是chan是為緩存的,那就代表這寫入一次就會阻塞。我們把代碼恢復(fù)為可以運(yùn)行的方式,看看效果

package main

import (
    "sync"
    "fmt"
)

//下面的迭代會有什么問題?

type threadSafeSet struct {
    sync.RWMutex
    s []interface{}
}

func (set *threadSafeSet) Iter() <-chan interface{} {
    // ch := make(chan interface{}) // 解除注釋看看!
    ch := make(chan interface{},len(set.s))
    go func() {
        set.RLock()

        for elem,value := range set.s {
            ch <- elem
            println("Iter:",elem,value)
        }

        close(ch)
        set.RUnlock()

    }()
    return ch
}

func main()  {

    th:=threadSafeSet{
        s:[]interface{}{"1","2"},
    }
    v:=<-th.Iter()
    fmt.Sprintf("%s%v","ch",v)
}

10. 以下代碼能編譯過去嗎?為什么?

package main

import (
	"fmt"
)

type People interface {
	Speak(string) string
}

type Stduent struct{}

func (stu *Stduent) Speak(think string) (talk string) {
	if think == "bitch" {
		talk = "You are a good boy"
	} else {
		talk = "hi"
	}
	return
}

func main() {
	var peo People = Stduent{}
	think := "bitch"
	fmt.Println(peo.Speak(think))
}

考點:golang的方法集
解答:編譯不通過!做錯了!?說明你對golang的方法集還有一些疑問。一句話:golang的方法集僅僅影響接口實現(xiàn)和方法表達(dá)式轉(zhuǎn)化,與通過實例或者指針調(diào)用方法無關(guān)。

11. 以下代碼打印出來什么內(nèi)容,說出為什么。

package main

import (
	"fmt"
)

type People interface {
	Show()
}

type Student struct{}

func (stu *Student) Show() {

}

func live() People {
	var stu *Student
	return stu
}

func main() {
	if live() == nil {
		fmt.Println("AAAAAAA")
	} else {
		fmt.Println("BBBBBBB")
	}
}

考點:interface內(nèi)部結(jié)構(gòu)
解答:很經(jīng)典的題!這個考點是很多人忽略的interface內(nèi)部結(jié)構(gòu)。 go中的接口分為兩種一種是空的接口類似這樣:

var in interface{}

另一種如題目:

type People interface {
    Show()
}

他們的底層結(jié)構(gòu)如下:

type eface struct {      //空接口
    _type *_type         //類型信息
    data  unsafe.Pointer //指向數(shù)據(jù)的指針(go語言中特殊的指針類型unsafe.Pointer類似于c語言中的void*)
}
type iface struct {      //帶有方法的接口
    tab  *itab           //存儲type信息還有結(jié)構(gòu)實現(xiàn)方法的集合
    data unsafe.Pointer  //指向數(shù)據(jù)的指針(go語言中特殊的指針類型unsafe.Pointer類似于c語言中的void*)
}
type _type struct {
    size       uintptr  //類型大小
    ptrdata    uintptr  //前綴持有所有指針的內(nèi)存大小
    hash       uint32   //數(shù)據(jù)hash值
    tflag      tflag
    align      uint8    //對齊
    fieldalign uint8    //嵌入結(jié)構(gòu)體時的對齊
    kind       uint8    //kind 有些枚舉值kind等于0是無效的
    alg        *typeAlg //函數(shù)指針數(shù)組,類型實現(xiàn)的所有方法
    gcdata    *byte
    str       nameOff
    ptrToThis typeOff
}
type itab struct {
    inter  *interfacetype  //接口類型
    _type  *_type          //結(jié)構(gòu)類型
    link   *itab
    bad    int32
    inhash int32
    fun    [1]uintptr      //可變大小 方法集合
}

可以看出iface比eface 中間多了一層itab結(jié)構(gòu)。 itab 存儲_type信息和[]fun方法集,從上面的結(jié)構(gòu)我們就可得出,因為data指向了nil 并不代表interface 是nil,所以返回值并不為空,這里的fun(方法集)定義了接口的接收規(guī)則,在編譯的過程中需要驗證是否實現(xiàn)接口結(jié)果:

BBBBBBB

文章名稱:golang面試題解析
標(biāo)題網(wǎng)址:http://www.chinadenli.net/article0/iphdio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航面包屑導(dǎo)航搜索引擎優(yōu)化網(wǎng)站內(nèi)鏈標(biāo)簽優(yōu)化靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司