Golang面试题解析(五) 原

栏目: ASP.NET · 发布时间: 6年前

内容简介:map需要初始化后才能使用。编译错误:invalid operation: s.Param["RMB"] (type *Param does not support indexing)

开发十年,就只剩下这套 Java 开发体系了 >>> Golang面试题解析(五) 原

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

  1. 使用场景不同 for可以
    • 遍历array和slice
    • 遍历key为整型递增的map
    • 遍历string for range可以完成所有for可以做的事情,却能做到for不能做的,包括
    • 遍历key为string类型的map并同时获取key和value
    • 遍历channel
  2. 实现不同 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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ES6 标准入门(第2版)

ES6 标准入门(第2版)

阮一峰 / 电子工业出版社 / 2016-1 / 69.00元

ES6(又名 ES2105)是 JavaScript 语言的新标准,2015 年 6 月正式发布后,得到了迅速推广,是目前业界超级活跃的计算机语言。《ES6标准入门(第2版)》是国内仅有的一本 ES6 教程,在前版基础上增补了大量内容——对标准进行了彻底的解读,所有新增的语法知识(包括即将发布的 ES7)都给予了详细介绍,并且紧扣业界开发实践,给出了大量简洁易懂、可以即学即用的示例代码。 《......一起来看看 《ES6 标准入门(第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具