您好,登錄后才能下訂單哦!
這篇文章主要介紹“GO必知的常見面試題有哪些”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“GO必知的常見面試題有哪些”文章能幫助大家解決問題。
基本數(shù)據(jù)類型都是值類型,包括:int系列、float系列、bool、字符串、數(shù)組、結(jié)構(gòu)體struct。
指針、切片slice、接口interface、管道channel
值類型在內(nèi)存中存儲(chǔ)的是值本身,而引用類型在內(nèi)存中存儲(chǔ)的是值的內(nèi)存地址。
值類型內(nèi)存通常在棧中分配,引用類型內(nèi)存通常在堆中分配。
引用類型的內(nèi)存在堆中分配,當(dāng)沒有任何變量引用堆中的內(nèi)存地址時(shí),該內(nèi)存地址對(duì)應(yīng)的數(shù)據(jù)存儲(chǔ)空間就變成了垃圾,就會(huì)被GO語言的GC回收。
在Go中,棧的內(nèi)存是由編譯器自動(dòng)進(jìn)行分配和釋放,棧區(qū)往往存儲(chǔ)著函數(shù)參數(shù)、局部變量和調(diào)用函數(shù)幀,它們隨著函數(shù)的創(chuàng)建而分配,函數(shù)的退出而銷毀。
一個(gè)goroutine對(duì)應(yīng)一個(gè)棧,棧是調(diào)用棧(call stack)的簡(jiǎn)稱。一個(gè)棧通常又包含了許多棧幀(stack frame),它描述的是函數(shù)之間的調(diào)用關(guān)系,每一幀對(duì)應(yīng)一次尚未返回的函數(shù)調(diào)用,它本身也是以棧形式存放數(shù)據(jù)。
與棧不同的是,應(yīng)用程序在運(yùn)行時(shí)只會(huì)存在一個(gè)堆。狹隘地說,內(nèi)存管理只是針對(duì)堆內(nèi)存而言的。程序在運(yùn)行期間可以主動(dòng)從堆上申請(qǐng)內(nèi)存,這些內(nèi)存通過Go的內(nèi)存分配器分配,并由垃圾收集器回收。
切片之間是不能比較的,我們不能使用==操作符來判斷兩個(gè)切片是否含有全部相等元素。
切片唯一合法的比較操作是和nil比較。
要檢查切片是否為空,應(yīng)該使用
len(s) == 0
來判斷,而不應(yīng)該使用
s == nil
來判斷。
原因是:一個(gè)nil值的切片并沒有底層數(shù)組,一個(gè)nil值的切片的長(zhǎng)度和容量都是0。但是我們不能說一個(gè)長(zhǎng)度和容量都是0的切片一定是nil。
我們通過下面的示例就很好理解了:
var s1 []int //len(s1)=0;cap(s1)=0;s1==nil s2 := []int{} //len(s2)=0;cap(s2)=0;s2!=nil s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil
所以要判斷一個(gè)切片是否是空的,要是用len(s) == 0來判斷,不應(yīng)該使用s == nil來判斷。
其根本原因在于后面兩種初始化方式已經(jīng)給切片分配了空間,所以就算切片為空,也不等于nil。但是len(s) == 0成立,則切片一定為空。
注意:在go中 var是聲明關(guān)鍵字,不會(huì)開辟內(nèi)存空間;使用 := 或者 make 關(guān)鍵字進(jìn)行初始化時(shí)才會(huì)開辟內(nèi)存空間。
深拷貝和淺拷貝操作的對(duì)象都是Go語言中的引用類型
引用類型的特點(diǎn)是在內(nèi)存中存儲(chǔ)的是其他值的內(nèi)存地址;而值類型在內(nèi)存中存儲(chǔ)的是真實(shí)的值。
我們?cè)趃o語言中通過 := 賦值引用類型就是 淺拷貝,即拷貝的是內(nèi)存地址,兩個(gè)變量對(duì)應(yīng)的是同一個(gè)內(nèi)存地址對(duì)應(yīng)的同一個(gè)值。
a := []string{1,2,3} b := a
如果我們通過copy()函數(shù)進(jìn)行賦值,就是深拷貝,賦值的是真實(shí)的值,而非內(nèi)存地址,會(huì)在內(nèi)存中開啟新的內(nèi)存空間。
舉例如下:
a := []string{1,2,3} b := make([]string,len(a),cap(a)) copy(b,a)
new是GO語言一個(gè)內(nèi)置的函數(shù),它的函數(shù)簽名如下:
func new(Type) *Type
Type表示類型,new函數(shù)只接受一個(gè)參數(shù),這個(gè)參數(shù)是一個(gè)類型
*Type表示類型指針,new函數(shù)返回一個(gè)指向該類型內(nèi)存地址的指針。
new函數(shù)不太常用,使用new函數(shù)得到的是一個(gè)類型的指針,并且該指針對(duì)應(yīng)的值為該類型的零值。
func main() { a := new(int) b := new(bool) fmt.Printf("%T\n", a) // *int fmt.Printf("%T\n", b) // *bool fmt.Println(*a) // 0 fmt.Println(*b) // false }
var a *int只是聲明了一個(gè)指針變量a但是沒有初始化,指針作為引用類型需要初始化后才會(huì)擁有內(nèi)存空間,才可以給它賦值。
應(yīng)該按照如下方式使用內(nèi)置的new函數(shù)對(duì)a進(jìn)行初始化之后就可以正常對(duì)其賦值了:
func main() { var a *int a = new(int) *a = 10 fmt.Println(*a) }
make也是用于內(nèi)存分配的,區(qū)別于new,它只用于slice、map以及channel的內(nèi)存創(chuàng)建,而且它返回的類型就是這三個(gè)類型本身,而不是他們的指針類型,因?yàn)檫@三種類型就是引用類型(指針類型),所以就沒有必要返回他們的指針了。
func make(t Type, size ...IntegerType) Type
make函數(shù)是無可替代的,我們?cè)谑褂胹lice、map以及channel的時(shí)候,都需要使用make進(jìn)行初始化,然后才可以對(duì)它們進(jìn)行操作。
var b map[string]int這段代碼,只是聲明變量b是一個(gè)map類型的變量,需要像下面的示例代碼一樣使用make函數(shù)進(jìn)行初始化操作之后,才能對(duì)其進(jìn)行鍵值對(duì)賦值:
func main() { var b map[string]int b = make(map[string]int, 10) b["分?jǐn)?shù)"] = 100 fmt.Println(b) }
二者都是用來做內(nèi)存分配的。
make只用于slice、map以及channel的初始化,返回的是類型本身(類型本身就是引用類型(指針類型));
而new用于內(nèi)存分配時(shí),在內(nèi)存中存儲(chǔ)的是對(duì)應(yīng)類型的型零值(比如0,false),返回的是該類型的指針類型。
我們知道go語言的map類型底層是有hash實(shí)現(xiàn)的,是無序的,不支持排序。
如果我們的數(shù)據(jù)使用map類型存儲(chǔ),如何實(shí)現(xiàn)排序呢?
排序map的key,再根據(jù)排序后的key遍歷輸出map即可。
package main import ( "fmt" "math/rand" "sort" "time" ) func main() { rand.Seed(time.Now().UnixNano()) //初始化隨機(jī)數(shù)種子 var scoreMap = make(map[string]int, 30) for i := 0; i < 30; i++ { key := fmt.Sprintf("stu%02d", i) //生成stu開頭的字符串 value := rand.Intn(30) //生成0~50的隨機(jī)整數(shù) scoreMap[key] = value } //取出map中的所有key存入切片keys var keys = make([]string, 0, 30) for key := range scoreMap { keys = append(keys, key) } //對(duì)切片進(jìn)行排序 sort.Strings(keys) //按照排序后的key遍歷map for _, key := range keys { fmt.Println(key, scoreMap[key]) } }
關(guān)于“GO必知的常見面試題有哪些”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。