博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang面试题解析(五)
阅读量:6943 次
发布时间:2019-06-27

本文共 4749 字,大约阅读时间需要 15 分钟。

41.执行下面的代码发生什么?

package maintype 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 mainimport "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 mainimport (    "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 mainfunc 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 mainimport "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 := MutilParamvalue := 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

转载于:https://blog.51cto.com/qiangmzsx/2176019

你可能感兴趣的文章
typeof操作符的返回值
查看>>
@Spring事务管理
查看>>
Ubuntu系统如何卸载并安装新版本的jdk(permission denied问题)
查看>>
解决 2003 Can’t connect to MySQL server on ‘localhost’ (10048)
查看>>
thinkphp整合系列之phpqrcode生成二维码
查看>>
转: eclipse 快捷键列表(功能清晰版本)
查看>>
Java 并发工具包 java.util.concurrent 用户指南
查看>>
plsql 的循环之 goto
查看>>
漂亮回答面试官struts2的原理
查看>>
python基础——调试
查看>>
同步/异步/阻塞/非阻塞
查看>>
【转】Maven实战(四)---多模块项目---JBOSS部署问题
查看>>
每天一个linux命令(46):vmstat命令
查看>>
使用Apache的DigestUtils类实现哈希摘要(SHA/MD5)
查看>>
minimum-moves-to-equal-array-elements-ii(好)
查看>>
js-JavaScript高级程序设计学习笔记1
查看>>
5.把报表集成到Web应用程序中-生成网页和导出两种方式
查看>>
linux下svn命令大全
查看>>
_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h':问题的解决 mysql安装python...
查看>>
devenv.exe assert failure
查看>>