Go 面試題

能力模式

FDBFE207-17F1-4E6C-854E-F291AE0AE7AE.png

選擇題

  1. 【初級(jí)】下面屬于關(guān)鍵字的是()
    A. func
    B. def
    C. struct
    D. class

參考答案:AC

  1. 【初級(jí)】定義一個(gè)包內(nèi)全局字符串變量,下面語(yǔ)法正確的是()
    A. var str string
    B. str := ""
    C. str = ""
    D. var str = ""

參考答案:AD

  1. 【初級(jí)】通過(guò)指針變量 p 訪問(wèn)其成員變量 name,下面語(yǔ)法正確的是()
    A. p.name
    B. (*p).name
    C. (&p).name
    D. p->name

參考答案:AB

  1. 【初級(jí)】關(guān)于接口和類的說(shuō)法,下面說(shuō)法正確的是()
    A. 一個(gè)類只需要實(shí)現(xiàn)了接口要求的所有函數(shù),我們就說(shuō)這個(gè)類實(shí)現(xiàn)了該接口
    B. 實(shí)現(xiàn)類的時(shí)候,只需要關(guān)心自己應(yīng)該提供哪些方法,不用再糾結(jié)接口需要拆得多細(xì)才合理
    C. 類實(shí)現(xiàn)接口時(shí),需要導(dǎo)入接口所在的包
    D. 接口由使用方按自身需求來(lái)定義,使用方無(wú)需關(guān)心是否有其他模塊定義過(guò)類似的接口

參考答案:ABD

  1. 【初級(jí)】關(guān)于字符串連接,下面語(yǔ)法正確的是()
    A. str := ‘a(chǎn)bc’ + ‘123’
    B. str := "abc" + "123"
    C. str := '123' + "abc"
    D. fmt.Sprintf("abc%d", 123)

參考答案:BD

  1. 【初級(jí)】關(guān)于協(xié)程,下面說(shuō)法正確是()
    A. 協(xié)程和線程都可以實(shí)現(xiàn)程序的并發(fā)執(zhí)行
    B. 線程比協(xié)程更輕量級(jí)
    C. 協(xié)程不存在死鎖問(wèn)題
    D. 通過(guò)channel來(lái)進(jìn)行協(xié)程間的通信

參考答案:AD

  1. 【中級(jí)】關(guān)于init函數(shù),下面說(shuō)法正確的是()
    A. 一個(gè)包中,可以包含多個(gè)init函數(shù)
    B. 程序編譯時(shí),先執(zhí)行導(dǎo)入包的init函數(shù),再執(zhí)行本包內(nèi)的init函數(shù)
    C. main包中,不能有init函數(shù)
    D. init函數(shù)可以被其他函數(shù)調(diào)用

參考答案:AB

  1. 【初級(jí)】關(guān)于循環(huán)語(yǔ)句,下面說(shuō)法正確的有()
    A. 循環(huán)語(yǔ)句既支持for關(guān)鍵字,也支持while和do-while
    B. 關(guān)鍵字for的基本使用方法與C/C++中沒(méi)有任何差異
    C. for循環(huán)支持continue和break來(lái)控制循環(huán),但是它提供了一個(gè)更高級(jí)的break,可以選擇中斷哪一個(gè)循環(huán)
    D. for循環(huán)不支持以逗號(hào)為間隔的多個(gè)賦值語(yǔ)句,必須使用平行賦值的方式來(lái)初始化多個(gè)變量

參考答案:CD

  1. 【中級(jí)】對(duì)于函數(shù)定義:
    func add(args ...int) int {
    sum :=0
    for _,arg := range args {
    sum += arg
    }
    returnsum
    }

下面對(duì)add函數(shù)調(diào)用正確的是()
A. add(1, 2)
B. add(1, 3, 7)
C. add([]int{1, 2})
D. add([]int{1, 3, 7}...)

參考答案:ABD

  1. 【初級(jí)】關(guān)于類型轉(zhuǎn)化,下面語(yǔ)法正確的是()
    A.

type MyInt int

var i int = 1

var jMyInt = i

B.

type MyIntint

var i int= 1

var jMyInt = (MyInt)i

C.

type MyIntint

var i int= 1

var jMyInt = MyInt(i)

D.

type MyIntint

var i int= 1

var jMyInt = i.(MyInt)

參考答案:C

  1. 【初級(jí)】關(guān)于局部變量的初始化,下面正確的使用方式是()
    A. var i int = 10
    B. var i = 10
    C. i := 10
    D. i = 10

參考答案:ABC

  1. 【初級(jí)】關(guān)于const常量定義,下面正確的使用方式是()
    A.
    const Pi float64 = 3.14159265358979323846
    const zero= 0.0

B.
const (
size int64= 1024
eof = -1
)

C.
const (
ERR_ELEM_EXISTerror = errors.New("element already exists")
ERR_ELEM_NT_EXISTerror = errors.New("element not exists")
)

D.
const u, vfloat32 = 0, 3
const a,b, c = 3, 4, "foo"

參考答案:ABD

  1. 【初級(jí)】關(guān)于布爾變量b的賦值,下面錯(cuò)誤的用法是()
    A. b = true
    B. b = 1
    C. b = bool(1)
    D. b = (1 == 2)

參考答案:BC

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是()
    func main() {
    if (true) {
    defer fmt.Printf("1")
    } else {
    defer fmt.Printf("2")
    }
    fmt.Printf("3")
    }

A. 321
B. 32
C. 31
D. 13

參考答案:C

  1. 【初級(jí)】關(guān)于switch語(yǔ)句,下面說(shuō)法正確的有()
    A. 條件表達(dá)式必須為常量或者整數(shù)
    B. 單個(gè)case中,可以出現(xiàn)多個(gè)結(jié)果選項(xiàng)
    C. 需要用break來(lái)明確退出一個(gè)case
    D. 只有在case中明確添加fallthrough關(guān)鍵字,才會(huì)繼續(xù)執(zhí)行緊跟的下一個(gè)case

參考答案:BD

  1. 【中級(jí)】 golang中沒(méi)有隱藏的this指針,這句話的含義是()
    A. 方法施加的對(duì)象顯式傳遞,沒(méi)有被隱藏起來(lái)
    B. golang沿襲了傳統(tǒng)面向?qū)ο缶幊讨械闹T多概念,比如繼承、虛函數(shù)和構(gòu)造函數(shù)
    C. golang的面向?qū)ο蟊磉_(dá)更直觀,對(duì)于面向過(guò)程只是換了一種語(yǔ)法形式來(lái)表達(dá)
    D. 方法施加的對(duì)象不需要非得是指針,也不用非得叫this

參考答案:ACD

  1. 【中級(jí)】 golang中的引用類型包括()
    A. 數(shù)組切片
    B. map
    C. channel
    D. interface

參考答案:ABCD

  1. 【中級(jí)】 golang中的指針運(yùn)算包括()
    A. 可以對(duì)指針進(jìn)行自增或自減運(yùn)算
    B. 可以通過(guò)“&”取指針的地址
    C. 可以通過(guò)“*”取指針指向的數(shù)據(jù)
    D. 可以對(duì)指針進(jìn)行下標(biāo)運(yùn)算

參考答案:BC

  1. 【初級(jí)】關(guān)于main函數(shù)(可執(zhí)行程序的執(zhí)行起點(diǎn)),下面說(shuō)法正確的是()
    A. main函數(shù)不能帶參數(shù)
    B. main函數(shù)不能定義返回值
    C. main函數(shù)所在的包必須為main包
    D. main函數(shù)中可以使用flag包來(lái)獲取和解析命令行參數(shù)

參考答案:ABCD

  1. 【中級(jí)】下面賦值正確的是()
    A. var x = nil
    B. var x interface{} = nil
    C. var x string = nil
    D. var x error = nil

參考答案:BD

  1. 【中級(jí)】關(guān)于整型切片的初始化,下面正確的是()
    A. s := make([]int)
    B. s := make([]int, 0)
    C. s := make([]int, 5, 10)
    D. s := []int{1, 2, 3, 4, 5}

參考答案:BCD

  1. 【中級(jí)】從切片中刪除一個(gè)元素,下面的算法實(shí)現(xiàn)正確的是()
    A.
    func (s Slice)Remove(value interface{})error {
    for i, v := range s {
    if isEqual(value, v) {
    if i== len(
    s) - 1 {
    s = (s)[:i]
    }else {
    s = append((s)[:i],(
    s)[i + 2:]...)
    }
    return nil
    }
    }
    return ERR_ELEM_NT_EXIST
    }

B.

func (s*Slice)Remove(value interface{}) error {

for i, v:= range *s {

if isEqual(value, v) {

    *s =append((*s)[:i],(*s)[i + 1:])

    return nil

}

}

returnERR_ELEM_NT_EXIST

}

C.

func (s*Slice)Remove(value interface{}) error {

for i, v:= range *s {

if isEqual(value, v) {

    delete(*s, v)

    return nil

}

}

returnERR_ELEM_NT_EXIST

}

D.

func (s*Slice)Remove(value interface{}) error {

for i, v:= range *s {

if isEqual(value, v) {

    *s =append((*s)[:i],(*s)[i + 1:]...)

    return nil

}

}

returnERR_ELEM_NT_EXIST

}

參考答案:D

  1. 【初級(jí)】對(duì)于局部變量整型切片x的賦值,下面定義正確的是()
    A.

  2. x := []int{

  3. 1, 2, 3,

  4. 4, 5, 6,

}

B.

x :=[]int{

1, 2, 3,

4, 5, 6

}

C.

x :=[]int{

1, 2, 3,

4, 5, 6}

D.

x :=[]int{1, 2, 3, 4, 5, 6,}

參考答案:ACD

  1. 【初級(jí)】關(guān)于變量的自增和自減操作,下面語(yǔ)句正確的是()
    A.

  2. i := 1

i++

B.

i := 1

j = i++

C.

i := 1

++i

D.

i := 1

i--

參考答案:AD

  1. 【中級(jí)】關(guān)于函數(shù)聲明,下面語(yǔ)法錯(cuò)誤的是()
    A. func f(a, b int) (value int, err error)
    B. func f(a int, b int) (value int, err error)
    C. func f(a, b int) (value int, error)
    D. func f(a int, b int) (int, int, error)

參考答案:C

  1. 【中級(jí)】如果Add函數(shù)的調(diào)用代碼為:

  2. func main() {

  3. var a Integer = 1

  4. var b Integer = 2

  5. var i interface{} = &a

  6. sum := i.(*Integer).Add(b)

  7. fmt.Println(sum)

}

則Add函數(shù)定義正確的是()
A.

typeInteger int

func (aInteger) Add(b Integer) Integer {

return a + b

}

B.

typeInteger int

func (aInteger) Add(b *Integer) Integer {

return a + *b

}

C.

typeInteger int

func (a*Integer) Add(b Integer) Integer {

return *a + b

}

D.

typeInteger int

func (a*Integer) Add(b *Integer) Integer {

return *a + *b

}

參考答案:AC

  1. 【中級(jí)】如果Add函數(shù)的調(diào)用代碼為:

  2. func main() {

  3. var a Integer = 1

  4. var b Integer = 2

  5. var i interface{} = a

  6. sum := i.(Integer).Add(b)

  7. fmt.Println(sum)

}

則Add函數(shù)定義正確的是()
A.

typeInteger int

func (a Integer)Add(b Integer) Integer {

return a + b

}

B.

typeInteger int

func (aInteger) Add(b *Integer) Integer {

return a + *b

}

C.

typeInteger int

func (a*Integer) Add(b Integer) Integer {

return *a + b

}

D.

typeInteger int

func (a*Integer) Add(b *Integer) Integer {

return *a + *b

}

參考答案:A

  1. 【中級(jí)】關(guān)于GetPodAction定義,下面賦值正確的是()

  2. type Fragment interface {

  3. Exec(transInfo *TransInfo) error

  4. }

  5. type GetPodAction struct {

  6. }

  7. func (g GetPodAction) Exec(transInfo*TransInfo) error {

  8. ...

  9. return nil

}

A. var fragment Fragment =new(GetPodAction)
B. var fragment Fragment = GetPodAction
C. var fragment Fragment = &GetPodAction{}
D. var fragment Fragment = GetPodAction{}

參考答案:ACD

  1. 【中級(jí)】關(guān)于GoMock,下面說(shuō)法正確的是()
    A. GoMock可以對(duì)interface打樁
    B. GoMock可以對(duì)類的成員函數(shù)打樁
    C. GoMock可以對(duì)函數(shù)打樁
    D. GoMock打樁后的依賴注入可以通過(guò)GoStub完成

參考答案:AD

  1. 【中級(jí)】關(guān)于接口,下面說(shuō)法正確的是()
    A. 只要兩個(gè)接口擁有相同的方法列表(次序不同不要緊),那么它們就是等價(jià)的,可以相互賦值
    B. 如果接口A的方法列表是接口B的方法列表的子集,那么接口B可以賦值給接口A
    C. 接口查詢是否成功,要在運(yùn)行期才能夠確定
    D. 接口賦值是否可行,要在運(yùn)行期才能夠確定

參考答案:ABC

  1. 【初級(jí)】關(guān)于channel,下面語(yǔ)法正確的是()
    A. var ch chan int
    B. ch := make(chan int)
    C. <- ch
    D. ch <-

參考答案:ABC

  1. 【初級(jí)】關(guān)于同步鎖,下面說(shuō)法正確的是()
    A. 當(dāng)一個(gè)goroutine獲得了Mutex后,其他goroutine就只能乖乖的等待,除非該goroutine釋放這個(gè)Mutex
    B. RWMutex在讀鎖占用的情況下,會(huì)阻止寫,但不阻止讀
    C. RWMutex在寫鎖占用情況下,會(huì)阻止任何其他goroutine(無(wú)論讀和寫)進(jìn)來(lái),整個(gè)鎖相當(dāng)于由該goroutine獨(dú)占
    D. Lock()操作需要保證有Unlock()或RUnlock()調(diào)用與之對(duì)應(yīng)

參考答案:ABC

  1. 【中級(jí)】 golang中大多數(shù)數(shù)據(jù)類型都可以轉(zhuǎn)化為有效的JSON文本,下面幾種類型除外()
    A. 指針
    B. channel
    C. complex
    D. 函數(shù)

參考答案:BCD

  1. 【中級(jí)】關(guān)于go vendor,下面說(shuō)法正確的是()
    A. 基本思路是將引用的外部包的源代碼放在當(dāng)前工程的vendor目錄下面
    B. 編譯go代碼會(huì)優(yōu)先從vendor目錄先尋找依賴包
    C. 可以指定引用某個(gè)特定版本的外部包
    D. 有了vendor目錄后,打包當(dāng)前的工程代碼到其他機(jī)器的$GOPATH/src下都可以通過(guò)編譯

參考答案:ABD

  1. 【初級(jí)】 flag是bool型變量,下面if表達(dá)式符合編碼規(guī)范的是()
    A. if flag == 1
    B. if flag
    C. if flag == false
    D. if !flag

參考答案:BD

  1. 【初級(jí)】 value是整型變量,下面if表達(dá)式符合編碼規(guī)范的是()
    A. if value == 0
    B. if value
    C. if value != 0
    D. if !value

參考答案:AC

  1. 【中級(jí)】關(guān)于函數(shù)返回值的錯(cuò)誤設(shè)計(jì),下面說(shuō)法正確的是()
    A. 如果失敗原因只有一個(gè),則返回bool
    B. 如果失敗原因超過(guò)一個(gè),則返回error
    C. 如果沒(méi)有失敗原因,則不返回bool或error
    D. 如果重試幾次可以避免失敗,則不要立即返回bool或error

參考答案:ABCD

  1. 【中級(jí)】關(guān)于異常設(shè)計(jì),下面說(shuō)法正確的是()
    A. 在程序開發(fā)階段,堅(jiān)持速錯(cuò),讓程序異常崩潰
    B. 在程序部署后,應(yīng)恢復(fù)異常避免程序終止
    C. 一切皆錯(cuò)誤,不用進(jìn)行異常設(shè)計(jì)
    D. 對(duì)于不應(yīng)該出現(xiàn)的分支,使用異常處理

參考答案:ABD

  1. 【中級(jí)】關(guān)于slice或map操作,下面正確的是()
    A.

  2. var s []int

s =append(s,1)

B.

var mmap[string]int

m["one"]= 1

C.

var s[]int

s =make([]int, 0)

s =append(s,1)

D.

var mmap[string]int

m =make(map[string]int)

m["one"]= 1

參考答案:ACD

  1. 【中級(jí)】關(guān)于channel的特性,下面說(shuō)法正確的是()
    A. 給一個(gè) nil channel 發(fā)送數(shù)據(jù),造成永遠(yuǎn)阻塞
    B. 從一個(gè) nil channel 接收數(shù)據(jù),造成永遠(yuǎn)阻塞
    C. 給一個(gè)已經(jīng)關(guān)閉的 channel 發(fā)送數(shù)據(jù),引起 panic
    D. 從一個(gè)已經(jīng)關(guān)閉的 channel 接收數(shù)據(jù),如果緩沖區(qū)中為空,則返回一個(gè)零值

參考答案:ABCD

  1. 【中級(jí)】關(guān)于無(wú)緩沖和有沖突的channel,下面說(shuō)法正確的是()
    A. 無(wú)緩沖的channel是默認(rèn)的緩沖為1的channel
    B. 無(wú)緩沖的channel和有緩沖的channel都是同步的
    C. 無(wú)緩沖的channel和有緩沖的channel都是非同步的
    D. 無(wú)緩沖的channel是同步的,而有緩沖的channel是非同步的

參考答案:D

  1. 【中級(jí)】關(guān)于異常的觸發(fā),下面說(shuō)法正確的是()
    A. 空指針解析
    B. 下標(biāo)越界
    C. 除數(shù)為0
    D. 調(diào)用panic函數(shù)

參考答案:ABCD

  1. 【中級(jí)】關(guān)于cap函數(shù)的適用類型,下面說(shuō)法正確的是()
    A. array
    B. slice
    C. map
    D. channel

參考答案:ABD

  1. 【中級(jí)】關(guān)于beego框架,下面說(shuō)法正確的是()
    A. beego是一個(gè)golang實(shí)現(xiàn)的輕量級(jí)HTTP框架
    B. beego可以通過(guò)注釋路由、正則路由等多種方式完成url路由注入
    C. 可以使用bee new工具生成空工程,然后使用bee run命令自動(dòng)熱編譯
    D. beego框架只提供了對(duì)url路由的處理,而對(duì)于MVC架構(gòu)中的數(shù)據(jù)庫(kù)部分未提供框架支持

參考答案:ABC

  1. 【中級(jí)】關(guān)于goconvey,下面說(shuō)法正確的是()
    A. goconvey是一個(gè)支持golang的單元測(cè)試框架
    B. goconvey能夠自動(dòng)監(jiān)控文件修改并啟動(dòng)測(cè)試,并可以將測(cè)試結(jié)果實(shí)時(shí)輸出到web界面
    C. goconvey提供了豐富的斷言簡(jiǎn)化測(cè)試用例的編寫
    D. goconvey無(wú)法與go test集成

參考答案:ABC

  1. 【中級(jí)】關(guān)于go vet,下面說(shuō)法正確的是()
    A. go vet是golang自帶工具go tool vet的封裝
    B. 當(dāng)執(zhí)行g(shù)o vet database時(shí),可以對(duì)database所在目錄下的所有子文件夾進(jìn)行遞歸檢測(cè)
    C. go vet可以使用絕對(duì)路徑、相對(duì)路徑或相對(duì)GOPATH的路徑指定待檢測(cè)的包
    D. go vet可以檢測(cè)出死代碼

參考答案:ACD

  1.         【中級(jí)】關(guān)于map,下面說(shuō)法正確的是()
    

A. map反序列化時(shí)json.unmarshal的入?yún)⒈仨殲閙ap的地址
B. 在函數(shù)調(diào)用中傳遞map,則子函數(shù)中對(duì)map元素的增加不會(huì)導(dǎo)致父函數(shù)中map的修改
C. 在函數(shù)調(diào)用中傳遞map,則子函數(shù)中對(duì)map元素的修改不會(huì)導(dǎo)致父函數(shù)中map的修改
D. 不能使用內(nèi)置函數(shù)delete刪除map的元素

參考答案:A

  1.         【中級(jí)】關(guān)于GoStub,下面說(shuō)法正確的是()
    

A. GoStub可以對(duì)全局變量打樁
B. GoStub可以對(duì)函數(shù)打樁
C. GoStub可以對(duì)類的成員方法打樁
D. GoStub可以打動(dòng)態(tài)樁,比如對(duì)一個(gè)函數(shù)打樁后,多次調(diào)用該函數(shù)會(huì)有不同的行為

參考答案:ABD

  1.         【初級(jí)】關(guān)于select機(jī)制,下面說(shuō)法正確的是()
    

A. select機(jī)制用來(lái)處理異步IO問(wèn)題
B. select機(jī)制最大的一條限制就是每個(gè)case語(yǔ)句里必須是一個(gè)IO操作
C. golang在語(yǔ)言級(jí)別支持select關(guān)鍵字
D. select關(guān)鍵字的用法與switch語(yǔ)句非常類似,后面要帶判斷條件

參考答案:ABC

  1.         【初級(jí)】關(guān)于內(nèi)存泄露,下面說(shuō)法正確的是()
    

A. golang有自動(dòng)垃圾回收,不存在內(nèi)存泄露
B. golang中檢測(cè)內(nèi)存泄露主要依靠的是pprof包
C. 內(nèi)存泄露可以在編譯階段發(fā)現(xiàn)
D. 應(yīng)定期使用瀏覽器來(lái)查看系統(tǒng)的實(shí)時(shí)內(nèi)存信息,及時(shí)發(fā)現(xiàn)內(nèi)存泄露問(wèn)題

參考答案:BD

填空題

  1. 【初級(jí)】聲明一個(gè)整型變量i__________

參考答案:var i int

  1. 【初級(jí)】聲明一個(gè)含有10個(gè)元素的整型數(shù)組a__________

參考答案:var a [10]int

  1. 【初級(jí)】聲明一個(gè)整型數(shù)組切片s__________

參考答案:var s []int

  1. 【初級(jí)】聲明一個(gè)整型指針變量p__________

參考答案:var p *int

  1. 【初級(jí)】聲明一個(gè)key為字符串型value為整型的map變量m__________

參考答案:var m map[string]int

  1. 【初級(jí)】聲明一個(gè)入?yún)⒑头祷刂稻鶠檎偷暮瘮?shù)變量f__________

參考答案:var f func(a int) int

  1. 【初級(jí)】聲明一個(gè)只用于讀取int數(shù)據(jù)的單向channel變量ch__________

參考答案:var ch <-chan int

  1. 【初級(jí)】假設(shè)源文件的命名為slice.go,則測(cè)試文件的命名為__________

參考答案:slice_test.go

  1. 【初級(jí)】 go test要求測(cè)試函數(shù)的前綴必須命名為__________

參考答案:Test

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. for i := 0; i < 5; i++ {

  3. defer fmt.Printf("%d ", i)

}

參考答案:4 3 2 1 0

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func main() {

  3. x := 1

  4. {

  5. x := 2

  6. fmt.Print(x)

  7. }

  8. fmt.Println(x)

}

參考答案:21

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func main() {

  3. strs := []string{"one","two", "three"}

  4. for _, s := range strs {

  5. go func() {

  6.    time.Sleep(1 * time.Second)
    
  7.    fmt.Printf("%s ", s)
    
  8. }()

  9. }

  10. time.Sleep(3 * time.Second)

}

參考答案:three threethree

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func main() {

  3. x := []string{"a", "b","c"}

  4. for v := range x {

  5. fmt.Print(v)

  6. }

}

參考答案:012

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func main() {

  3. x := []string{"a", "b","c"}

  4. for _, v := range x {

  5. fmt.Print(v)

  6. }

}

參考答案:abc

  1. 【初級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func main() {

  3. i := 1

  4. j := 2

  5. i, j = j, i

  6. fmt.Printf("%d%d\n", i, j)

}

參考答案:21

  1. 【初級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. func incr(p *int) int {

  3. *p++

  4. return *p

  5. }

  6. func main() {

  7. v := 1

  8. incr(&v)

  9. fmt.Println(v)

}

參考答案:2

  1. 【初級(jí)】啟動(dòng)一個(gè)goroutine的關(guān)鍵字是__________

參考答案:go

  1. 【中級(jí)】下面的程序的運(yùn)行結(jié)果是__________

  2. type Slice []int

  3. func NewSlice() Slice {

  4. return make(Slice, 0)

  5. }

  6. func (s* Slice) Add(elem int) *Slice {

  7. s = append(s, elem)

  8. fmt.Print(elem)

  9. return s

  10. }

  11. func main() {

  12. s := NewSlice()

  13. defer s.Add(1).Add(2)

  14. s.Add(3)

}

參考答案:132

判斷題

  1. 【初級(jí)】數(shù)組是一個(gè)值類型()

參考答案:T

  1. 【初級(jí)】使用map不需要引入任何庫(kù)()

參考答案:T

  1. 【中級(jí)】?jī)?nèi)置函數(shù)delete可以刪除數(shù)組切片內(nèi)的元素()

參考答案:F

  1. 【初級(jí)】指針是基礎(chǔ)類型()

參考答案:F

  1. 【初級(jí)】 interface{}是可以指向任意對(duì)象的Any類型()

參考答案:T

  1. 【中級(jí)】下面關(guān)于文件操作的代碼可能觸發(fā)異常()

  2. file, err := os.Open("test.go")

  3. defer file.Close()

  4. if err != nil {

  5. fmt.Println("open file failed:",err)

  6. return

  7. }

...

參考答案:T

  1. 【初級(jí)】 Golang不支持自動(dòng)垃圾回收()

參考答案:F

  1. 【初級(jí)】 Golang支持反射,反射最常見(jiàn)的使用場(chǎng)景是做對(duì)象的序列化()

參考答案:T

  1. 【初級(jí)】 Golang可以復(fù)用C/C++的模塊,這個(gè)功能叫Cgo()

參考答案:F

  1. 【初級(jí)】下面代碼中兩個(gè)斜點(diǎn)之間的代碼,比如json:"x",作用是X字段在從結(jié)構(gòu)體實(shí)例編碼到JSON數(shù)據(jù)格式的時(shí)候,使用x作為名字,這可以看作是一種重命名的方式()

  2. type Position struct {

  3. X int json:"x"

  4. Y int json:"y"

  5. Z int json:"z"

}

參考答案:T

  1. 【初級(jí)】通過(guò)成員變量或函數(shù)首字母的大小寫來(lái)決定其作用域()

參考答案:T

  1. 【初級(jí)】對(duì)于常量定義zero(const zero = 0.0),zero是浮點(diǎn)型常量()

參考答案:F

  1. 【初級(jí)】對(duì)變量x的取反操作是~x()

參考答案:F

  1. 【初級(jí)】下面的程序的運(yùn)行結(jié)果是xello()

  2. func main() {

  3. str := "hello"

  4. str[0] = 'x'

  5. fmt.Println(str)

}

參考答案:F

  1. 【初級(jí)】 golang支持goto語(yǔ)句()

參考答案:T

  1. 【初級(jí)】下面代碼中的指針p為野指針,因?yàn)榉祷氐臈?nèi)存在函數(shù)結(jié)束時(shí)會(huì)被釋放()

  2. type TimesMatcher struct {

  3. base int

  4. }

  5. func NewTimesMatcher(base int) *TimesMatcher{

  6. return &TimesMatcher{base:base}

  7. }

  8. func main() {

  9. p := NewTimesMatcher(3)

  10. ...

}

參考答案:F

  1. 【初級(jí)】匿名函數(shù)可以直接賦值給一個(gè)變量或者直接執(zhí)行()

參考答案:T

  1. 【初級(jí)】如果調(diào)用方調(diào)用了一個(gè)具有多返回值的方法,但是卻不想關(guān)心其中的某個(gè)返回值,可以簡(jiǎn)單地用一個(gè)下劃線“_”來(lái)跳過(guò)這個(gè)返回值,該下劃線對(duì)應(yīng)的變量叫匿名變量()

參考答案:T

  1. 【初級(jí)】在函數(shù)的多返回值中,如果有error或bool類型,則一般放在最后一個(gè)()

參考答案:T

  1. 【初級(jí)】錯(cuò)誤是業(yè)務(wù)過(guò)程的一部分,而異常不是()

參考答案:T

  1. 【初級(jí)】函數(shù)執(zhí)行時(shí),如果由于panic導(dǎo)致了異常,則延遲函數(shù)不會(huì)執(zhí)行()

參考答案:F

  1. 【中級(jí)】當(dāng)程序運(yùn)行時(shí),如果遇到引用空指針、下標(biāo)越界或顯式調(diào)用panic函數(shù)等情況,則先觸發(fā)panic函數(shù)的執(zhí)行,然后調(diào)用延遲函數(shù)。調(diào)用者繼續(xù)傳遞panic,因此該過(guò)程一直在調(diào)用棧中重復(fù)發(fā)生:函數(shù)停止執(zhí)行,調(diào)用延遲執(zhí)行函數(shù)。如果一路在延遲函數(shù)中沒(méi)有recover函數(shù)的調(diào)用,則會(huì)到達(dá)該攜程的起點(diǎn),該攜程結(jié)束,然后終止其他所有攜程,其他攜程的終止過(guò)程也是重復(fù)發(fā)生:函數(shù)停止執(zhí)行,調(diào)用延遲執(zhí)行函數(shù)()

參考答案:F

  1. 【初級(jí)】同級(jí)文件的包名不允許有多個(gè)()

參考答案:T

  1. 【中級(jí)】可以給任意類型添加相應(yīng)的方法()

參考答案:F

  1. 【初級(jí)】 golang雖然沒(méi)有顯式的提供繼承語(yǔ)法,但是通過(guò)匿名組合實(shí)現(xiàn)了繼承()

參考答案:T

  1. 【初級(jí)】使用for range迭代map時(shí)每次迭代的順序可能不一樣,因?yàn)閙ap的迭代是隨機(jī)的()

參考答案:T

  1. 【初級(jí)】 switch后面可以不跟表達(dá)式()

參考答案:T

  1. 【中級(jí)】結(jié)構(gòu)體在序列化時(shí)非導(dǎo)出變量(以小寫字母開頭的變量名)不會(huì)被encode,因此在decode時(shí)這些非導(dǎo)出變量的值為其類型的零值()

參考答案:T

  1. 【初級(jí)】 golang中沒(méi)有構(gòu)造函數(shù)的概念,對(duì)象的創(chuàng)建通常交由一個(gè)全局的創(chuàng)建函數(shù)來(lái)完成,以NewXXX來(lái)命名()

參考答案:T

  1. 【中級(jí)】當(dāng)函數(shù)deferDemo返回失敗時(shí),并不能destroy已create成功的資源()

  2. func deferDemo() error {

  3. err := createResource1()

  4. if err != nil {

  5. return ERR_CREATE_RESOURCE1_FAILED

  6. }

  7. defer func() {

  8. if err != nil {

  9.    destroyResource1()
    
  10. }

  11. }()

  12. err = createResource2()

  13. if err != nil {

  14. return ERR_CREATE_RESOURCE2_FAILED

  15. }

  16. defer func() {

  17. if err != nil {

  18.    destroyResource2()
    
  19. }

  20. }()

  21. err = createResource3()

  22. if err != nil {

  23. return ERR_CREATE_RESOURCE3_FAILED

  24. }

  25. return nil

}

參考答案:F

  1. 【中級(jí)】 channel本身必然是同時(shí)支持讀寫的,所以不存在單向channel()

參考答案:F

  1. 【初級(jí)】 import后面的最后一個(gè)元素是包名()

參考答案:F

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

面試題

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

package main
import (
"fmt"
)
funcmain() {
defer_call()
}
funcdefer_call() {
deferfunc() {fmt.Println("打印前")}()
deferfunc() {fmt.Println("打印中")}()
deferfunc() {fmt.Println("打印后")}()
panic("觸發(fā)異常")
}

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

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

2 以下代碼有什么問(wèn)題,說(shuō)明原因。

type student struct {
Name string
Age int
}
funcpase_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
}
}

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

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

也是不可行的。 大家可以試試打印出來(lái):

func pase_student() {
m := make(map[string]*student)
stus := []student{
{Name: "zhou",Age: 24},
{Name: "li",Age: 23},
{Name: "wang",Age: 22},
}
// 錯(cuò)誤寫法
for _,stu := range stus {
m[stu.Name] =&stu
}
fork,v:=range m{
println(k,"=>",v.Name)
}
// 正確
for i:=0;i<len(stus);i++ {
m[stus[i].Name] = &stus[i]
}
fork,v:=range m{
println(k,"=>",v.Name)
}
}

3 下面的代碼會(huì)輸出什么,并說(shuō)明原因

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

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

第二個(gè)go func中i是函數(shù)參數(shù),與外部for中的i完全是兩個(gè)變量。 尾部(i)將發(fā)生值拷貝,go func內(nèi)部指向值拷貝地址。
4 下面代碼會(huì)輸出什么?

type People struct{}func (p People)ShowA() {
fmt.Println("showA")
p.ShowB()
}
func(p
People)ShowB() {
fmt.Println("showB")
}
typeTeacher struct {
People
}
func(t*Teacher)ShowB() {
fmt.Println("teachershowB")
}
funcmain() {
t := Teacher{}
t.ShowA()
}

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

5 下面代碼會(huì)觸發(fā)異常嗎?請(qǐng)?jiān)敿?xì)說(shuō)明

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

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

select 中只要有一個(gè)case能return,則立刻執(zhí)行。
當(dāng)如果同一時(shí)間有多個(gè)case均能return則偽隨機(jī)方式抽取任意一個(gè)執(zhí)行。
如果沒(méi)有一個(gè)case能return則可以執(zhí)行”default”塊。

6 下面代碼輸出什么?

funccalc(indexstring, a, bint) int {
ret := a+ b
fmt.Println(index,a, b, ret)
return ret
}
funcmain() {
a := 1
b := 2
defer calc("1", a,calc("10", a, b)) a = 0
defer calc("2", a,calc("20", a, b)) b = 1
}

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

7 請(qǐng)寫出以下輸入內(nèi)容

funcmain() {
s := make([]int,5)
s = append(s,1, 2, 3)
fmt.Println(s)
}

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

[00000123]

大家試試改為:

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

8 下面的代碼有什么問(wèn)題?

type UserAges struct {
ages map[string]int
sync.Mutex
}
func(uaUserAges)Add(name string, age int) {
ua.Lock()
deferua.Unlock()
ua.ages[name] = age
}
func(ua
UserAges)Get(name string)int {
ifage, ok := ua.ages[name]; ok {
return age
}
return-1
}

考點(diǎn):map線程安全
解答:
可能會(huì)出現(xiàn)

fatal error: concurrent mapreadandmapwrite.

修改一下看看效果

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

  1. 下面的迭代會(huì)有什么問(wèn)題?

func (set *threadSafeSet)Iter()<-chaninterface{} {
ch := make(chaninterface{})
gofunc() {
set.RLock()
for elem := range set.s {
ch <- elem
}
close(ch)
set.RUnlock()
}()
return ch
}

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

package main
import (
"sync"
"fmt")//下面的迭代會(huì)有什么問(wèn)題?type threadSafeSet struct {
sync.RWMutex
s []interface{}
}
func(set*threadSafeSet)Iter() <-chaninterface{} {
//ch := make(chan interface{}) // 解除注釋看看!
ch := make(chaninterface{},len(set.s))
gofunc() {
set.RLock()
forelem,value := range set.s {
ch <- elem
println("Iter:",elem,value)
} close(ch)
set.RUnlock()
}()
return ch
}
funcmain() {
th:=threadSafeSet{
s:[]interface{}{"1","2"},
}
v:=<-th.Iter()
fmt.Sprintf("%s%v","ch",v)
}

10 以下代碼能編譯過(guò)去嗎?為什么?

package main
import ( "fmt")
typePeople interface {
Speak(string) string
}
typeStduent struct{}
func(stu*Stduent)Speak(think string)(talk string) {
ifthink == "bitch" {
talk = "Youare a good boy"
} else {
talk = "hi"
}
return
}
funcmain() {
var peoPeople = Stduent{}
think := "bitch"
fmt.Println(peo.Speak(think))
}

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

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

package main
import ( "fmt")
typePeople interface {
Show()
}
typeStudent struct{}
func(stuStudent)Show() {
}
funclive()People {
var stu
Student
return stu
}
funcmain() { if live() == nil
{
fmt.Println("AAAAAAA")
} else {
fmt.Println("BBBBBBB")
}
}

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

varininterface{}

另一種如題目:

type People interface {
Show()
}

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

type eface struct { //空接口
_type _type //類型信息
data unsafe.Pointer //指向數(shù)據(jù)的指針(go語(yǔ)言中特殊的指針類型unsafe.Pointer類似于c語(yǔ)言中的void
)}
typeiface struct { //帶有方法的接口
tab itab //存儲(chǔ)type信息還有結(jié)構(gòu)實(shí)現(xiàn)方法的集合
data unsafe.Pointer //指向數(shù)據(jù)的指針(go語(yǔ)言中特殊的指針類型unsafe.Pointer類似于c語(yǔ)言中的void
)}
type_type struct {
size uintptr //類型大小
ptrdata uintptr //前綴持有所有指針的內(nèi)存大小
hash uint32 //數(shù)據(jù)hash值
tflag tflag
align uint8 //對(duì)齊
fieldalign uint8 //嵌入結(jié)構(gòu)體時(shí)的對(duì)齊
kind uint8 //kind 有些枚舉值kind等于0是無(wú)效的
alg *typeAlg //函數(shù)指針數(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 存儲(chǔ)_type信息和[]fun方法集,從上面的結(jié)構(gòu)我們就可得出,因?yàn)閐ata指向了nil 并不代表interface 是nil, 所以返回值并不為空,這里的fun(方法集)定義了接口的接收規(guī)則,在編譯的過(guò)程中需要驗(yàn)證是否實(shí)現(xiàn)接口 結(jié)果:

BBBBBBB
12.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

func main() {
i := GetValue() switch i.(type) {
caseint:
println("int")
casestring:
println("string")
caseinterface{}:
println("interface")
default:
println("unknown")
}
}
funcGetValue()int {
return1
}

解析
考點(diǎn):type

編譯失敗,因?yàn)閠ype只能使用在interface

13.下面函數(shù)有什么問(wèn)題?

func funcMui(x,y int)(sum int,error){
returnx+y,nil
}

解析
考點(diǎn):函數(shù)返回值命名
在函數(shù)有多個(gè)返回值時(shí),只要有一個(gè)返回值有指定命名,其他的也必須有命名。 如果返回值有有多個(gè)返回值必須加上括號(hào); 如果只有一個(gè)返回值并且有命名也需要加上括號(hào); 此處函數(shù)第一個(gè)返回值有sum名稱,第二個(gè)未命名,所以錯(cuò)誤。

14.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

package mainfunc main() { println(DeferFunc1(1)) println(DeferFunc2(1)) println(DeferFunc3(1))
}func DeferFunc1(i int)(t int) {
t = i deferfunc() {
t += 3
}() return t
}
funcDeferFunc2(i int)int {
t := i deferfunc() {
t += 3
}() return t
}
funcDeferFunc3(i int)(t int) { deferfunc() {
t += i
}() return2}

解析
考點(diǎn):defer和函數(shù)返回值
需要明確一點(diǎn)是defer需要在函數(shù)結(jié)束前執(zhí)行。 函數(shù)返回值名字會(huì)在函數(shù)起始處被初始化為對(duì)應(yīng)類型的零值并且作用域?yàn)檎麄€(gè)函數(shù) DeferFunc1有函數(shù)返回值t作用域?yàn)檎麄€(gè)函數(shù),在return之前defer會(huì)被執(zhí)行,所以t會(huì)被修改,返回4; DeferFunc2函數(shù)中t的作用域?yàn)楹瘮?shù),返回1;DeferFunc3返回3

15.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

funcmain() { list := new([]int)
list = append(list,1)
fmt.Println(list)
}

解析
考點(diǎn):new

list:=make([]int,0)

16.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

package mainimport "fmt"funcmain() {
s1 := []int{1, 2, 3}
s2 := []int{4, 5}
s1 = append(s1,s2)
fmt.Println(s1)
}

解析
考點(diǎn):append
append切片時(shí)候別漏了'…'

17.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

func main() {
sn1 := struct {
age int
name string
}{age: 11,name: "qq"}
sn2 := struct {
age int
name string
}{age: 11,name: "qq"} if sn1== sn2 {
fmt.Println("sn1== sn2")
}
sm1 := struct {
age int
m map[string]string
}{age: 11, m:map[string]string{"a": "1"}}
sm2 := struct {
age int
m map[string]string
}{age: 11, m:map[string]string{"a": "1"}}
if sm1 == sm2 {
fmt.Println("sm1== sm2")
}
}

解析
考點(diǎn):結(jié)構(gòu)體比較
進(jìn)行結(jié)構(gòu)體比較時(shí)候,只有相同類型的結(jié)構(gòu)體才可以比較,結(jié)構(gòu)體是否相同不但與屬性類型個(gè)數(shù)有關(guān),還與屬性順序相關(guān)。

sn3:= struct {
name string
age int
}
{age:11,name:"qq"}

sn3與sn1就不是相同的結(jié)構(gòu)體了,不能比較。 還有一點(diǎn)需要注意的是結(jié)構(gòu)體是相同的,但是結(jié)構(gòu)體屬性中有不可以比較的類型,如map,slice。 如果該結(jié)構(gòu)屬性都是可以比較的,那么就可以使用“==”進(jìn)行比較操作。

可以使用reflect.DeepEqual進(jìn)行比較

if reflect.DeepEqual(sn1, sm) {
fmt.Println("sn1==sm")
}else {
fmt.Println("sn1!=sm")
}

所以編譯不通過(guò): invalid operation: sm1 == sm2

18.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

func Foo(x interface{}) { if x== nil {
fmt.Println("emptyinterface")
return
}
fmt.Println("non-emptyinterface")
}
funcmain() {
var x *int = nil
Foo(x)
}

解析
考點(diǎn):interface內(nèi)部結(jié)構(gòu)

non-emptyinterface

19.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

func GetValue(m map[int]string, id int)(string, bool) {
if _,exist := m[id]; exist {
return"存在數(shù)據(jù)", true
}
returnnil, false}funcmain() {
intmap:=map[int]string{
1:"a",
2:"bb",
3:"ccc",
}
v,err:=GetValue(intmap,3)
fmt.Println(v,err)
}

解析
考點(diǎn):函數(shù)返回值類型
nil 可以用作 interface、function、pointer、map、slice 和 channel 的“空值”。但是如果不特別指定的話,Go 語(yǔ)言不能識(shí)別類型,所以會(huì)報(bào)錯(cuò)。報(bào):cannot use nil as type string in return argument.

20.是否可以編譯通過(guò)?如果通過(guò),輸出什么?

const (
x = iota
y
z = "zz"
k
p = iota)
funcmain()
{
fmt.Println(x,y,z,k,p)
}

解析
考點(diǎn):iota
結(jié)果:

0 1 zz zz 4

21.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package mainvar(
size :=1024
max_size = size*2)
funcmain() {
println(size,max_size)
}

解析
考點(diǎn):變量簡(jiǎn)短模式
變量簡(jiǎn)短模式限制:

定義變量同時(shí)顯式初始化
不能提供數(shù)據(jù)類型
只能在函數(shù)內(nèi)部使用
結(jié)果:

syntaxerror: unexpected :=

22.下面函數(shù)有什么問(wèn)題?

package main
const cl = 100
var bl = 123
funcmain() {
println(&bl,bl)
println(&cl,cl)
}

解析
考點(diǎn):常量
常量不同于變量的在運(yùn)行期分配內(nèi)存,常量通常會(huì)被編譯器在預(yù)處理階段直接展開,作為指令數(shù)據(jù)使用,

cannot take the address of cl

23.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
funcmain() {
for i:=0;i<10;i++ {
loop:
println(i)
} gotoloop
}

解析
考點(diǎn):goto
goto不能跳轉(zhuǎn)到其他函數(shù)或者內(nèi)層代碼

goto loop jumps intoblock starting at

24.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
import"fmt"
funcmain() {
typeMyInt1 int
typeMyInt2 = int
var i int =9
var i1MyInt1 = i
var i2MyInt2 = i
fmt.Println(i1,i2)
}

解析
考點(diǎn):**Go 1.9 新特性 Type Alias **
基于一個(gè)類型創(chuàng)建一個(gè)新類型,稱之為defintion;基于一個(gè)類型創(chuàng)建一個(gè)別名,稱之為alias。 MyInt1為稱之為defintion,雖然底層類型為int類型,但是不能直接賦值,需要強(qiáng)轉(zhuǎn); MyInt2稱之為alias,可以直接賦值。

結(jié)果:

cannot use i (typeint) astype MyInt1 in assignment

25.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
import"fmt"
typeUser struct {
}
typeMyUser1 User
typeMyUser2 = User
func(iMyUser1)m1(){
fmt.Println("MyUser1.m1")
}
func(iUser)m2(){
fmt.Println("User.m2")
}
funcmain() {
var i1MyUser1
var i2MyUser2
i1.m1()
i2.m2()
}

解析
考點(diǎn):**Go 1.9 新特性 Type Alias **
因?yàn)镸yUser2完全等價(jià)于User,所以具有其所有的方法,并且其中一個(gè)新增了方法,另外一個(gè)也會(huì)有。 但是

i1.m2()

是不能執(zhí)行的,因?yàn)镸yUser1沒(méi)有定義該方法。 結(jié)果:

MyUser1.m1User.m2

26.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
import"fmt"
type T1 struct {
}
func(tT1)m1(){
fmt.Println("T1.m1")
}
type T2= T1
typeMyStruct struct {
T1
T2
}
funcmain() {
my:=MyStruct{}
my.m1()
}

解析
考點(diǎn):**Go 1.9 新特性 Type Alias **
是不能正常編譯的,異常:

ambiguousselectormy.m1

結(jié)果不限于方法,字段也也一樣;也不限于type alias,type defintion也是一樣的,只要有重復(fù)的方法、字段,就會(huì)有這種提示,因?yàn)椴恢涝撨x擇哪個(gè)。 改為:

my.T1.m1()
my.T2.m1()

type alias的定義,本質(zhì)上是一樣的類型,只是起了一個(gè)別名,源類型怎么用,別名類型也怎么用,保留源類型的所有方法、字段等。

27.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
import (
"errors"
"fmt")
varErrDidNotWork = errors.New("did not work")
funcDoTheThing(reallyDoItbool)(errerror) {
ifreallyDoIt {
result, err:= tryTheThing()
if err!= nil || result != "it worked" {
err = ErrDidNotWork
}
} return err
}
functryTheThing()(string,error) {
return"",ErrDidNotWork
}
funcmain() {
fmt.Println(DoTheThing(true))
fmt.Println(DoTheThing(false))
}

解析
考點(diǎn):變量作用域
因?yàn)?if 語(yǔ)句塊內(nèi)的 err 變量會(huì)遮罩函數(shù)作用域內(nèi)的 err 變量,結(jié)果:

改為:

func DoTheThing(reallyDoIt bool)(errerror) {
varresult string
ifreallyDoIt {
result, err =tryTheThing()
if err!= nil || result != "it worked" {
err = ErrDidNotWork
}
} return err
}

28.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
functest() []func() {
varfuns []func()
fori:=0;i<2;i++ {
funs = append(funs,func() {
println(&i,i)
})
} returnfuns
}
funcmain(){
funs:=test()
for_,f:=range funs{
f()
}
}

解析
考點(diǎn):閉包延遲求值
for循環(huán)復(fù)用局部變量i,每一次放入匿名函數(shù)的應(yīng)用都是想一個(gè)變量。 結(jié)果:

0xc042046000 2
0xc042046000 2

如果想不一樣可以改為:

func test() []func() {
varfuns []func()
fori:=0;i<2;i++ {
x:=i
funs = append(funs,func() {
println(&x,x)
})
} returnfuns
}

29.編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
functest(x int)(func(),func()) {
returnfunc() {
println(x)
x+=10
}, func() {
println(x)
}
}
funcmain() {
a,b:=test(100)
a()
b()
}

解析
考點(diǎn):閉包引用相同變量*
結(jié)果:

100
110

  1. 編譯執(zhí)行下面代碼會(huì)出現(xiàn)什么?

package main
import ( "fmt"
"reflect")
funcmain1() {
deferfunc() {
iferr:=recover();err!=nil{
fmt.Println(err)
}else {
fmt.Println("fatal")
}
}()
deferfunc() {
panic("deferpanic")
}()
panic("panic")
}
funcmain() {
deferfunc() {
iferr:=recover();err!=nil{
fmt.Println("++++")
f:=err.(func()string)
fmt.Println(err,f(),reflect.TypeOf(err).Kind().String())
}else {
fmt.Println("fatal")
}
}()
deferfunc() {
panic(func()string {
return "defer panic"
})
}()
panic("panic")
}

解析
考點(diǎn):panic僅有最后一個(gè)可以被revover捕獲
觸發(fā)panic("panic")后順序執(zhí)行defer,但是defer中還有一個(gè)panic,所以覆蓋了之前的panic("panic")


轉(zhuǎn)載自:
作者:尹成
來(lái)源:CSDN
原文:https://blog.csdn.net/itcastcpp/article/details/80462619
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 選擇題 [primary] 下面屬于關(guān)鍵字的是() A. func B. def C. struct D. cla...
    盤木閱讀 1,875評(píng)論 0 29
  • 一、數(shù)據(jù)類型轉(zhuǎn)換 https://studygolang.com/articles/10838 package m...
    蓓蓓的萬(wàn)能男友閱讀 1,161評(píng)論 0 1
  • Golang是我最喜歡的一門語(yǔ)言,它簡(jiǎn)潔、高效、易學(xué)習(xí)、開發(fā)效率高、還可以編譯成機(jī)器碼… 雖然它一出世,就飽受關(guān)注...
    盤木閱讀 3,703評(píng)論 0 7
  • 一、日歷 本周我是否完成重要的日歷事項(xiàng),有沒(méi)有爽約或變更固定事項(xiàng)? 沒(méi)有,均按時(shí)參加 二、清單 本周我有沒(méi)有做到要...
    lucky_duoduo閱讀 162評(píng)論 0 0
  • 像是眩暈癥發(fā)作,一下子摔倒在地,再醒來(lái)2017已經(jīng)過(guò)去。元旦那場(chǎng)濃的化不開的大霧,似乎預(yù)示著18年困難重重。然,又...
    井底看月亮閱讀 203評(píng)論 0 0

友情鏈接更多精彩內(nèi)容