Golang面试题解析(五) 原

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

内容简介: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


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

查看所有标签

猜你喜欢:

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

Mastering Bitcoin

Mastering Bitcoin

Andreas M. Antonopoulos / O'Reilly Media / 2014-12-20 / USD 34.99

Mastering Bitcoin tells you everything you need to know about joining one of the most exciting revolutions since the invention of the web: digital money. Bitcoin is the first successful digital curren......一起来看看 《Mastering Bitcoin》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具