🐁下面代碼中的指針p為野指針,因為返回的棧內存在函數結束時會被釋放,這一說法是否正確。

答案:說法錯誤
golang不存在野指針,它有自己的垃圾回收和逃逸分析。go語言的自動內存管理機制使得只要還有一個指針引用一個變量,那這個變量就會在內存中得以保留,因此在Go語言函數內部返回指向本地變量的指針是安全的。
這題考查的是Go語言的變量逃逸...Go語言會通過判斷引用關系,將在棧中初始化的變量,轉變為到堆初始化。
🐳當函數deferDemo返回失敗時,並不能destroy已create成功的資源()

答案:錯誤
題目問的是函數返回false的情況下,能不能釋放資源
函數返回失敗有3種情況:
一是第一次分配資源失敗,直接返回,這時並沒有分配成功的資源;
二是第一次分配資源成功,第二次分配資源失敗,函數返回,第二次和第三次的資源都未成功分配,此時err不為nil,第一次分配成功的資源通過defer釋放;
三是第一二次資源分配成功,第三次資源分配失敗,函數返回,第一二次分配成功的資源通過defer釋放;
如果第三次資源分配也成功了,則函數不會返回失敗。
🐓從切片中刪除一個元素,下面的算法實現正確的是


答案:D
因為追加的是一個slice而不是元素,故應該加上...。
函數 append 向 slice s 追加零值或其他 x 值,並且返回追加后的新的、與 s有相同類型的 slice。如果 s 沒有足夠的容量存儲追加的值, append 分配一個足夠大的、新的 slice 來存放原有 slice 的元素和追加的值。因此,返回的 slice 可能指向不同的底層 array。
s0 := []int{0, 0}
s1 := append(s0, 2) //追加一個元素, s1 == []int{0, 0, 2};
s2 := append(s1, 3, 5, 7) //追加多個元素, s2 == []int{0, 0, 2, 3, 5, 7};
s3 := append(s2, s0...) //追加一個 slice, s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}。注意這三個點!
🐈關於init函數
init函數可以在任何包中有0個或1個或多個;
首先初始化導入包的變量和常量,然后執行init函數,最后初始化本包的變量和常量,然后是init函數,最最后是main函數;
main函數只能在main包中有且只有一個,main包中也可以有0或1或多個init函數;
init函數和main函數都不能被顯示調用;
🐝當程序運行時,如果遇到引用空指針、下標越界或顯式調用panic函數等情況,則先觸發panic函數的執行,然后調用延遲函數。調用者繼續傳遞panic,因此該過程一直在調用棧中重復發生:函數停止執行,調用延遲執行函數。如果一路在延遲函數中沒有recover函數的調用,則會到達該協程的起點,該協程結束,然后終止其他所有協程,其他協程的終止過程也是重復發生:函數停止執行,調用延遲執行函數。這一說法是否正確。
解答:
當內置的panic()函數調用時,外圍函數或方法的執行會立即終止。然后,任何延遲執行(defer)的函數或方法都會被調用,就像其外圍函數正常返回一樣。最后,調用返回到該外圍函數的調用者,就像該外圍調用函數或方法調用了panic()一樣,因此該過程一直在調用棧中重復發生:函數停止執行,調用延遲執行函數等。當到達main()函數時不再有可以返回的調用者,因此這個過程會終止,並將包含傳入原始panic()函數中的值的調用棧信息輸出到os.Stderr。
panic需要等defer結束后才會向上傳遞。出現panic的時候,會先按照defer的后入先出的順序執行,最后才會執行panic。
🐲對於局部變量整型切片x的賦值,下面定義正確的是

答案:ACD
go語言編譯器會自動在以標識符、數字字面量、字母字面量、字符串字面量、特定的關鍵字(break、continue、fallthrough和return)、增減操作符(++和--)、或者一個右括號、右方括號和右大括號(即)、]、})結束的非空行的末尾自動加上分號。
對於B選項,6是數字字面量,所以在6的后面會自動加上一個分號,導致編譯出錯。
對於D選項,gofmt會自動把6后面的“,”去掉,關掉gofmt后測試,也能通過編譯,正常運行。
定義切片時,新起一行時,上一行必須是逗號或者右括號
🐙關於GoStub測試框架 ,下面說法正確的是
A、GoStub可以對全局變量打樁
B、GoStub可以對函數打樁
C、GoStub可以對類的成員方法打樁
D、GoStub可以打動態樁,比如對一個函數打樁后,多次調用該函數會有不同的行為
正確答案:ABD
GoStub框架的使用場景很多,依次為:
基本場景:為一個全局變量打樁
基本場景:為一個函數打樁
基本場景:為一個過程打樁
復合場景:由任意相同或不同的基本場景組合而成
🐰import后面的最后一個元素是包名
正確答案:錯誤
import后面跟的是包的路徑,而不是包名;
同一個目錄下可以有多個.go文件,但是只能有一個包;
使用第三方庫時,先將源碼編譯成.a文件放到臨時目錄下,然后去鏈接這個.a文件,而不是go install安裝的那個.a文件;
使用標准庫時,直接鏈接.a文件,即使修改了源碼,也不會從新編譯源碼;
不管使用的是標准庫還是第三方庫,源碼都是必須存在的,即使使用的是.a文件。
🐣golang中沒有隱藏的this指針,這句話的含義是()
A、方法施加的對象顯式傳遞,沒有被隱藏起來
B、golang沿襲了傳統面向對象編程中的諸多概念,比如繼承、虛函數和構造函數
C、golang的面向對象表達更直觀,對於面向過程只是換了一種語法形式來表達
D、方法施加的對象不需要非得是指針,也不用非得叫this
正確答案:ACD
A,方法施加的對象顯式傳遞,指的是接收器。需要給結構體增加方法時,需要使用 func (a 結構體名) 方法名(參數列表) (返回值列表) {函數體} 這種形式,在函數體里面,調用結構體成員的時候使用的就是 a.xxx,用 c 語言的方式來解釋,就是將對象作為參數傳入了函數,函數調用這個參數從而訪問對象的成員,當然這個函數是友聯函數,可以訪問任意訪問權限的成員
B,golang 不存在虛函數
C,這玩意看不懂,函數實現接口那塊怎么解釋?這也是面向對象?至於簡化,這不是很主觀的詞嘛?怎么可以用在客觀題上。。我就覺得不簡化,那怎么答案是簡化呢?不懂...
D,參考 A,可以傳對象,不一定要傳對象指針,至於名字,喜歡可以用 this,不喜歡可以看 A,用 a/b/c,隨你喜歡,go 推薦用結構體名首字母小寫
🌵關於接口和類的說法,下面說法正確的是
A、一個類只需要實現了接口要求的所有函數,我們就說這個類實現了該接口
B、實現類的時候,只需要關心自己應該提供哪些方法,不用再糾結接口需要拆得多細才合理
C、類實現接口時,需要導入接口所在的包
D、接口由使用方按自身需求來定義,使用方無需關心是否有其他模塊定義過類似的接口
正確答案:ABD
⛄關於同步鎖,下面說法正確的是
A、當一個goroutine獲得了Mutex后,其他goroutine就只能乖乖的等待,除非該goroutine釋放這個Mutex
B、RWMutex在讀鎖占用的情況下,會阻止寫,但不阻止讀
C、RWMutex在寫鎖占用情況下,會阻止任何其他goroutine(無論讀和寫)進來,整個鎖相當於由該goroutine獨占
D、Lock()操作需要保證有Unlock()或RUnlock()調用與之對應
正確答案:ABC
1、RWMutex.RLock()時,可以隨便讀。多個goroutin同時讀。不能寫。
2、RWMutex.Lock()時(寫的時候),啥都不能干。不能讀,也不能寫。
A選項正確,這就是互斥鎖的作用
B和C看以上兩條規則
D無論是RWMutex還是Mutex,與Lock()對應的都是Unlock()
🐦對於常量定義zero(const zero = 0.0),zero是浮點型常量,這一說法是否正確。
正確答案:錯誤
Go語言的常量有個不同尋常之處。雖然一個常量可以有任意有一個確定的基礎類型,例如int或float64,或者是類似time.Duration這樣命名的基礎類型,但是許多常量並沒有一個明確的基礎類型。編譯器為這些沒有明確的基礎類型的數字常量提供比基礎類型更高精度的算術運算;你可以認為至少有256bit的運算精度。這里有六種未明確類型的常量類型,分別是無類型的布爾型、無類型的整數、無類型的字符、無類型的浮點數、無類型的復數、無類型的字符串。
❄️關於main函數(可執行程序的執行起點),下面說法正確的是
A、main函數不能帶參數
B、main函數不能定義返回值
C、main函數所在的包必須為main包
D、main函數中可以使用flag包來獲取和解析命令行參數
Main函數和init函數都沒有參數和返回值的定義
🍔interface{}是可以指向任意對象的Any類型,這一說法是否正確。
正確答案:正確
空接口可以接受任何類型
☕Golang支持反射,反射最常見的使用場景是做對象的序列化,這一說法是否正確。
正確答案:正確
反射最常見的使用場景是做對象的序列化(serialization,有時候也叫Marshal & Unmarshal)。例如,Go語言標准庫的encoding/json、encoding/xml、encoding/gob、encoding/binary等包就大量依賴於反射功能來實現。
🎯下面關於文件操作的代碼可能觸發異常(如下圖),這一說法是否正確。

正確答案:正確
defer應該在if后面,如果文件為空,close會崩潰
file, err := os.Open("/null")
defer func() {
err := file.Close()
if err != nil {
fmt.Println("close error: ", err)
} else {
fmt.Println("close no error")
}
}()
if err != nil {
fmt.Println("open error! ", err)
return
}
-------Ouput:-----------
open error! open /null: The system cannot find the file specified.
close error: invalid argument
🍗關於slice或map操作,下面正確的是

正確答案: A C D
Make只用來創建slice,map,channel。 其中map使用前必須初始化。 append可直接動態擴容slice,而map不行。
🪲golang中分為值類型和引用類型
值類型分別有:int系列、float系列、bool、string、數組和結構體
引用類型有:指針、slice切片、管道channel、接口interface、map、函數等
值類型的特點是:變量直接存儲值,內存通常在棧中分配
引用類型的特點是:變量存儲的是一個地址,這個地址對應的空間里才是真正存儲的值,內存通常在堆中分配
☀️考查對 pprof 包的理解
內存泄漏(Memory Leak)是指程序中己動態分配的堆內存由於某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。
在影響軟件系統穩定性的因素里,我們最擔心的一個問題是內存泄漏,隨着系統的運行,系統消耗的內存越來越多,直到最后整個操作系統越來越慢,甚至還會導致系統崩潰。在Go語言里,我們檢測內存泄漏主要依靠的是go里面的pprof包,除此之外,我們還可以使用瀏覽器來查看系統的實時內存信息(包括CPU、goroutine等的信息)。
🐥下面賦值正確的是
A、var x = nil
B、var x interface{} = nil
C 、var x string = nil
D、var x error = nil
正確答案: B D
Go語言中的引用類型只有五個:
切片 映射 函數 方法 通道
nil只能賦值給上面五種通道類型的變量以及指針變量。

🍁關於GetPodAction定義,下面賦值正確的是

A、var fragment Fragment = new(GetPodAction)
B、var fragment Fragment = GetPodAction
C、var fragment Fragment = &GetPodAction{}
D、var fragment Fragment = GetPodAction{}
正確答案: A C D
go中var類型既可以表示指針類型的變量,也可以表示普通變量
🐍golang中大多數數據類型都可以轉化為有效的JSON文本,下面幾種類型除外
A、指針
B、channel
C、complex
D、函數
正確答案: B C D
雖然指針本身不能進行序列化,但是go提供了隱式轉換,表面進行的是指針序列化,內部會針對指針進行取值操作,實際還是針對的起所指的對象進行序列化
😆CGO是調用C代碼模塊,靜態庫和動態庫。CGO是C語言和Go語言之間的橋梁,原則上無法直接支持C++的類。CGO不支持C++語法的根本原因是C++至今為止還沒有一個二進制接口規范(ABI)。CGO只支持C語言中值類型的數據類型,所以我們是無法直接使用C++的引用參數等特性的。
😅go語言的指針不支持指針運算,指針運算包括:可以通過“&”取指針的地址、可以通過“*”取指針指向的數據
🌀下面對add函數調用正確的是

A、add(1, 2)
B、add(1, 3, 7)
C、add([]int{1, 2})
D、add([]int{1, 3, 7}...)
正確答案: A B D

🍃關於channel的特性,下面說法正確的是
A、給一個 nil channel 發送數據,造成永遠阻塞
B、從一個 nil channel 接收數據,造成永遠阻塞
C、給一個已經關閉的 channel 發送數據,引起 panic
D、從一個已經關閉的 channel 接收數據,如果緩沖區中為空,則返回一個零值
正確答案: A B C D
🐢關於函數聲明,下面語法錯誤的是
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
要求返回參數要么都有變量名要么都沒有,必須統一。
golang中分為值類型和引用類型
值類型分別有:int系列、float系列、bool、string、數組和結構體
引用類型有:指針、slice切片、管道channel、接口interface、map、函數等
值類型的特點是:變量直接存儲值,內存通常在棧中分配
引用類型的特點是:變量存儲的是一個地址,這個地址對應的空間里才是真正存儲的值,內存通常在堆中分配
:squirrel:
關於異常的觸發,下面說法正確的是
A、空指針解析
B、下標越界
C、除數為0
D、調用panic函數
正確答案: A B C D
空指針解析、下標越界、除數為0、調用panic函數都是會報異常的。
🌱關於go vendor,下面說法正確的是
A、基本思路是將引用的外部包的源代碼放在當前工程的vendor目錄下面
B、編譯go代碼會優先從vendor目錄先尋找依賴包
C、可以指定引用某個特定版本的外部包
D、有了vendor目錄后,打包當前的工程代碼到其他機器的$GOPATH/src下都可以通過編譯
正確答案: A B D
go vendor無法精確的引用外部包進行版本控制,不能指定引用某個特定版本的外部包;
🎏關於布爾變量b的賦值,下面錯誤的用法是
A、b = true
B、b = 1
C、b = bool(1)
D、b = (1 == 2)
正確答案: B C
bool類型和int類型沒法強制轉換
🎍關於cap函數的適用類型,下面說法正確的是
A、array
B、slice
C、map
D、channel
cap的作用
arry:返回數組的元素個數
slice:返回slice的最大容量
channel:返回channel的buffer容量
