Golang面試題解析(五)
阿新 • • 發佈:2018-09-17
import == all 允許 沒有 ron lang 不兼容 i++ 41.執行下面的代碼發生什麽?
package main
type Param map[string]interface{}
type Show struct {
*Param
}
func main() {
s := new(Show)
s.Param["RMB"] = 10000
}
考點:map初始化
map需要初始化後才能使用。
編譯錯誤:invalid operation: s.Param["RMB"] (type *Param does not support indexing)
42.執行下面的代碼發生什麽?
package main import "fmt" type student struct { Name string } func zhoujielun(v interface{}) { switch msg := v.(type) { case *student, student: msg.Name = "qq" fmt.Print(msg) } }
考點:類型轉換
msg不屬於student類型,所以沒有Name字段。
改為:
s := v.(student)
s.Name = "qq"
43.執行下面的代碼發生什麽?
package main import ( "encoding/json" "fmt" ) type People struct { name string `json:"name"` } func main() { js := `{ "name":"11" }` var p People err := json.Unmarshal([]byte(js), &p) if err != nil { fmt.Println("err: ", err) return } fmt.Println("people: ", p) }
考點:結構體訪問控制
這道題坑很大,很多同學一看就以為是p
的初始化問題,實際上是因為name
首字母是小寫,導致其他包不能訪問,所以輸出為空結構體。
改為:
type People struct {
Name string `json:"name"`
}
44.以下代碼有什麽問題?
package main
func Stop(stop <-chan bool) {
close(stop)
}
考點:close channel
有方向的channel不可被關閉
45.實現一個函數可以根據指定的size切割切片為多個小切片
解析
func main() { lenth := 11 size := 5 list := make([]int, 0, lenth) for i := 0; i < lenth; i++ { list = append(list, i) } SpiltList(list, size) } func SpiltList(list []int, size int) { lens := len(list) mod := math.Ceil(float64(lens) / float64(size)) spliltList := make([][]int, 0) for i := 0; i < int(mod); i++ { tmpList := make([]int, 0, size) fmt.Println("i=", i) if i == int(mod)-1 { tmpList = list[i*size:] } else { tmpList = list[i*size : i*size+size] } spliltList = append(spliltList, tmpList) } for i, sp := range spliltList { fmt.Println(i, " ==> ", sp) } }
46.實現兩個go輪流輸出:A1B2C3.....Z26
解析
方法一:有緩沖chan
func ChannelFunc() {
zimu := make(chan int, 1)
suzi := make(chan int, 1)
zimu <- 0
// zimu
go func() {
for i := 65; i <= 90; i++ {
<-zimu
fmt.Printf("%v", string(rune(i)))
suzi <- i
}
return
}()
go func() {
for i := 1; i <= 26; i++ {
<-suzi
fmt.Printf("%v", i)
zimu <- i
}
return
}()
time.Sleep(1 * time.Second)
fmt.Println()
}
方法二:無緩沖chan
func Channel1Func() {
zimu := make(chan int)
suzi := make(chan int)
// zimu
go func() {
for i := 65; i <= 90; i++ {
fmt.Printf("%v", string(rune(i)))
zimu <- i
<-suzi
}
return
}()
go func() {
for i := 1; i <= 26; i++ {
<-zimu
fmt.Printf("%v", i)
suzi <- i
}
return
}()
time.Sleep(10 * time.Second)
fmt.Println()
}
方法三:使用鎖
大家可以自己實現,把結果留言給我,答案後續公布。
47.執行下面代碼輸出什麽?
package main
// 47.執行下面代碼輸出什麽?
import "fmt"
func main() {
five := []string{"Annie", "Betty", "Charley", "Doug", "Edward"}
for _, v := range five {
five = five[:2]
fmt.Printf("v[%s]\n", v)
}
}
考點:range副本機制
循環內的切片值會縮減為2,但循環將在切片值的自身副本上進行操作。 這允許循環使用原始長度進行叠代而沒有任何問題,因為後備數組仍然是完整的。
結果:
v[Annie]
v[Betty]
v[Charley]
v[Doug]
v[Edward]
48.for 和 for range有什麽區別?
考點:for range
- 使用場景不同
for可以- 遍歷array和slice
- 遍歷key為整型遞增的map
- 遍歷string
for range可以完成所有for可以做的事情,卻能做到for不能做的,包括 - 遍歷key為string類型的map並同時獲取key和value
- 遍歷channel
- 實現不同
for可以獲取到的是被循環對象的元素本身,可以對其進行修改;
for range使用值拷貝的方式代替被遍歷的元素本身,是一個值拷貝,而不是元素本身。
49.解決下面問題:輸出MutilParam= [ssss [1 2 3 4]]如何做到輸出為[ssss 1 2 3 4]?
package main
import "fmt"
func MutilParam(p ...interface{}) {
fmt.Println("MutilParam=", p)
}
func main() {
MutilParam("ssss", 1, 2, 3, 4) //[ssss 1 2 3 4]
iis := []int{1, 2, 3, 4}
MutilParam("ssss", iis) //輸出MutilParam= [ssss [1 2 3 4]]如何做到輸出為[ssss 1 2 3 4]
}
考點:函數變參
這樣的情況會在開源類庫如xorm升級版本後出現Exce函數不兼容的問題。
解決方式有兩個:
方法一:interface[]
tmpParams := make([]interface{}, 0, len(iis)+1)
tmpParams = append(tmpParams, "ssss")
for _, ii := range iis {
tmpParams = append(tmpParams, ii)
}
MutilParam(tmpParams...)
方法二:反射
f := MutilParam
value := reflect.ValueOf(f)
pps := make([]reflect.Value, 0, len(iis)+1)
pps = append(pps, reflect.ValueOf("ssss"))
for _, ii := range iis {
pps = append(pps, reflect.ValueOf(ii))
}
value.Call(pps)
50.編譯並運行如下代碼會發生什麽?
package main
// 50.編譯並運行如下代碼會發生什麽?
import "fmt"
func main() {
mmap := make(map[map[string]string]int, 0)
mmap[map[string]string{"a": "a"}] = 1
mmap[map[string]string{"b": "b"}] = 1
mmap[map[string]string{"c": "c"}] = 1
fmt.Println(mmap)
}
考點:map key類型
golang中的map,的 key 可以是很多種類型,比如 bool, 數字,string, 指針, channel , 還有 只包含前面幾個類型的 interface types, structs, arrays。
顯然,slice, map 還有 function 是不可以了,因為這幾個沒法用 ==
來判斷,即不可比較類型。
可以將map[map[string]string]int
改為map[struct]int
。
Golang面試題解析(五)