Golang面试题解析(五)

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

内容简介:map需要初始化后才能使用。编译错误:invalid operation: s.Param["RMB"] (type *Param does not support indexing)msg不属于student类型,所以没有Name字段。

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


以上所述就是小编给大家介绍的《Golang面试题解析(五)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Elements of Programming

Elements of Programming

Alexander A. Stepanov、Paul McJones / Addison-Wesley Professional / 2009-6-19 / USD 39.99

Elements of Programming provides a different understanding of programming than is presented elsewhere. Its major premise is that practical programming, like other areas of science and engineering, mus......一起来看看 《Elements of Programming》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码