zoukankan      html  css  js  c++  java
  • go面试题[2]

    1.关于 cap() 函数的适用类型,下面说法正确的是()

    • A. array

    • B. slice

    • C. map

    • D. channel

    参考答案及解析:ABD。知识点:cap(),cap() 函数不适用 map。

    2.下面这段代码输出什么?

    2.下面这段代码输出什么?

    func main() {  
        var i interface{}
        if i == nil {
            fmt.Println("nil")
            return
        }
        fmt.Println("not nil")
    }
    • A. nil

    • B. not nil

    • C. compilation error

    参考答案及解析:A。当且仅当接口的动态值和动态类型都为 nil 时,接口类型值才为 nil。

    func main() {  
        s := make(map[string]int)
        delete(s, "h")
        fmt.Println(s["h"])
    }
    • A. runtime panic

    • B. 0

    • C. compilation error

    参考答案及解析:B。删除 map 不存在的键值对时,不会报错,相当于没有任何作用;获取不存在的减值对时,返回值类型对应的零值,所以返回 0。

    第二题

    1.下面属于关键字的是()

    • A.func

    • B.struct

    • C.class

    • D.defer

    参考答案及解析:ABD。知识点:Go 语言的关键字。Go 语言有 25 个关键字,看下图:

    2.下面这段代码输出什么?

    func main() {  
        i := -5
        j := +5
        fmt.Printf("%+d %+d", i, j)
    }
    • A. -5 +5

    • B. +5 +5

    • C. 0 0

    参考答案及解析:A。%d表示输出十进制数字,+表示输出数值的符号。这里不表示取反。

    3.下面这段代码输出什么?

    type People struct{}
    
    func (p *People) ShowA() {
        fmt.Println("showA")
        p.ShowB()
    }
    func (p *People) ShowB() {
        fmt.Println("showB")
    }
    
    type Teacher struct {
        People
    }
    
    func (t *Teacher) ShowB() {
        fmt.Println("teacher showB")
    }
    
    func main() {
        t := Teacher{}
        t.ShowB()
    }

    参考答案及解析:teacher showB。知识点:结构体嵌套。在嵌套结构体中,People 称为内部类型,Teacher 称为外部类型;通过嵌套,内部类型的属性、方法,可以为外部类型所有,就好像是外部类型自己的一样。此外,外部类型还可以定义自己的属性和方法,甚至可以定义与内部相同的方法,这样内部类型的方法就会被“屏蔽”。这个例子中的 ShowB() 就是同名方法。

     第三题

    1.定义一个包内全局字符串变量,下面语法正确的是()

    • A. var str string

    • B. str := “”

    • C. str = “”

    • D. var str = “”

    参考答案及解析:AD。B 只支持局部变量声明;C 是赋值,str 必须在这之前已经声明;

    2.下面这段代码输出什么?

    func hello(i int) {  
        fmt.Println(i)
    }
    func main() {  
        i := 5
        defer hello(i)
        i = i + 10
    }

    参考答案及解析:5。这个例子中,hello() 函数的参数在执行 defer 语句的时候会保存一份副本,在实际调用 hello() 函数时用,所以是 5.

    type People struct{}
    
    func (p *People) ShowA() {
        fmt.Println("showA")
        p.ShowB()
    }
    func (p *People) ShowB() {
        fmt.Println("showB")
    }
    
    type Teacher struct {
        People
    }
    
    func (t *Teacher) ShowB() {
        fmt.Println("teacher showB")
    }
    
    func main() {
        t := Teacher{}
        t.ShowA()
    }

    参考答案及解析:

    showA
    showB

    知识点:结构体嵌套。这道题可以结合第 12 天的第三题一起看,Teacher 没有自己 ShowA(),所以调用内部类型 People 的同名方法,需要注意的是第 5 行代码调用的是 People 自己的 ShowB 方法。

    第四题

    1.下面代码输出什么?

    func main() {
        str := "hello"
        str[0] = 'x'
        fmt.Println(str)
    }
    • A. hello

    • B. xello

    • C. compilation error

    参考代码及解析:C。知识点:常量,Go 语言中的字符串是只读的。

    2.下面代码输出什么?

    func incr(p *int) int {
        *p++
        return *p
    }
    
    func main() {
        p :=1
        incr(&p)
        fmt.Println(p)
    }
    • A. 1

    • B. 2

    • C. 3

    参考答案及解析:B。知识点:指针,incr() 函数里的 p 是 *int 类型的指针,指向的是 main() 函数的变量 p 的地址。第 2 行代码是将该地址的值执行一个自增操作,incr() 返回自增后的结果。

    3.对 add() 函数调用正确的是()

    func add(args ...int) int {
    
        sum := 0
        for _, arg := range args {
            sum += arg
        }
        return sum
    }
    • A. add(1, 2)

    • B. add(1, 3, 7)

    • C. add([]int{1, 2})

    • D. add([]int{1, 3, 7}…)

    参考答案及解析:ABD。知识点:可变函数

    第五天

     

    1.下面代码下划线处可以填入哪个选项?

    func main() {
        var s1 []int
        var s2 = []int{}
        if __ == nil {
            fmt.Println("yes nil")
        }else{
            fmt.Println("no nil")
        }
    }
    • A. s1

    • B. s2

    • C. s1、s2 都可以

    参考答案及解析:A。知识点:nil 切片和空切片。nil 切片和 nil 相等,一般用来表示一个不存在的切片;空切片和 nil 不相等,表示一个空的集合。

    2.下面这段代码输出什么?

    func main() {  
        i := 65
        fmt.Println(string(i))
    }
    • A. A

    • B. 65

    • C. compilation error

    参考答案及解析:A。UTF-8 编码中,十进制数字 65 对应的符号是 A。

    3.下面这段代码输出什么?

    type A interface {
        ShowA() int
    }
    
    type B interface {
        ShowB() int
    }
    
    type Work struct {
        i int
    }
    
    func (w Work) ShowA() int {
        return w.i + 10
    }
    
    func (w Work) ShowB() int {
        return w.i + 20
    }
    
    func main() {
        c := Work{3}
        var a A = c
        var b B = c
        fmt.Println(a.ShowA())
        fmt.Println(b.ShowB())
    }

    参考答案及解析:13 23。知识点:接口。一种类型实现多个接口,结构体 Work 分别实现了接口 A、B,所以接口变量 a、b 调用各自的方法 ShowA() 和 ShowB(),输出 13、23。

     第六题

    1.切片 a、b、c 的长度和容量分别是多少?

    func main() {
    
        s := [3]int{1, 2, 3}
        a := s[:0]
        b := s[:2]
        c := s[1:2:cap(s)]
    }

    参考答案及解析:a、b、c 的长度和容量分别是 0 3、2 3、1 2。知识点:数组或切片的截取操作。截取操作有带 2 个或者 3 个参数,形如:[i:j] 和 [i:j:k],假设截取对象的底层数组长度为 l。在操作符 [i:j] 中,如果 i 省略,默认 0,如果 j 省略,默认底层数组的长度,截取得到的切片长度和容量计算方法是 j-i、l-i。操作符 [i:j:k],k 主要是用来限制切片的容量,但是不能大于数组的长度 l,截取得到的切片长度和容量计算方法是 j-i、k-i。

    2.下面代码中 A B 两处应该怎么修改才能顺利编译?

    func main() {
        var m map[string]int        //A
        m["a"] = 1
        if v := m["b"]; v != nil {  //B
            fmt.Println(v)
        }
    }
    func main() {
        m := make(map[string]int)
        m["a"] = 1
        if v,ok := m["b"]; ok {
            fmt.Println(v)
        }
    }

    在 A 处只声明了map m ,并没有分配内存空间,不能直接赋值,需要使用 make(),都提倡使用 make() 或者字面量的方式直接初始化 map。

    B 处,v,k := m[“b”] 当 key 为 b 的元素不存在的时候,v 会返回值类型对应的零值,k 返回 false。

    type A interface {
        ShowA() int
    }
    
    type B interface {
        ShowB() int
    }
    
    type Work struct {
        i int
    }
    
    func (w Work) ShowA() int {
        return w.i + 10
    }
    
    func (w Work) ShowB() int {
        return w.i + 20
    }
    
    func main() {
        c := Work{3}
        var a A = c
        var b B = c
        fmt.Println(a.ShowB())
        fmt.Println(b.ShowA())
    }
    • A. 23 13

    • B. compilation error

    参考答案及解析:B。知识点:接口的静态类型。a、b 具有相同的动态类型和动态值,分别是结构体 work 和 {3};a 的静态类型是 A,b 的静态类型是 B,接口 A 不包括方法 ShowB(),接口 B 也不包括方法 ShowA(),编译报错。看下编译错误:

    a.ShowB undefined (type A has no field or method ShowB)
    b.ShowA undefined (type B has no field or method ShowA)

    第七题

    1.下面代码中,x 已声明,y 没有声明,判断每条语句的对错。

      1. x, _ := f()
        2. x, _ = f()
        3. x, y := f()
        4. x, y = f()

    参考答案及解析:错、对、对、错。知识点:变量的声明。1.错,x 已经声明,不能使用 :=;2.对;3.对,当多值赋值时,:= 左边的变量无论声明与否都可以;4.错,y 没有声明。

    2.下面代码输出什么?

    func increaseA() int {
        var i int
        defer func() {
            i++
        }()
        return i
    }
    
    func increaseB() (r int) {
        defer func() {
            r++
        }()
        return r
    }
    
    func main() {
        fmt.Println(increaseA())
        fmt.Println(increaseB())
    }
    • A. 1 1

    • B. 0 1

    • C. 1 0

    • D. 0 0

    参考答案及解析:B。知识点:defer、返回值。注意一下,increaseA() 的返回参数是匿名,increaseB() 是具名。关于 defer 与返回值的知识点,后面我会写篇文章详细分析,到时候可以看下文章的讲解。

    下面代码输出什么?

    type A interface {
        ShowA() int
    }
    
    type B interface {
        ShowB() int
    }
    
    type Work struct {
        i int
    }
    
    func (w Work) ShowA() int {
        return w.i + 10
    }
    
    func (w Work) ShowB() int {
        return w.i + 20
    }
    
    func main() {
        var a A = Work{3}
        s := a.(Work)
        fmt.Println(s.ShowA())
        fmt.Println(s.ShowB())
    }
    • A. 13 23

    • B. compilation error

    参考答案及解析:A。知识点:类型断言。这道题可以和第 15 天的第三题 和第 16 天的第三题结合起来看

     第八题

    1.下面代码段输出什么?

    type Person struct {
        age int
    }
    
    func main() {
        person := &Person{28}
    
        // 1. 
        defer fmt.Println(person.age)
    
        // 2.
        defer func(p *Person) {
            fmt.Println(p.age)
        }(person)  
    
        // 3.
        defer func() {
            fmt.Println(person.age)
        }()
    
        person.age = 29
    }

    参考答案及解析:29 29 28。变量 person 是一个指针变量 。

    1.person.age 此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;

    2.defer 缓存的是结构体 Person{28} 的地址,最终 Person{28} 的 age 被重新赋值为 29,所以 defer 语句最后执行的时候,依靠缓存的地址取出的 age 便是 29,即输出 29;

    3.闭包引用,输出 29;

    又由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 29 28。

    第九题

    1.下面这段代码正确的输出是什么?

    func f() {
        defer fmt.Println("D")
        fmt.Println("F")
    }
    
    func main() {
        f()
        fmt.Println("M")
    }
    A. F M D
    
    B. D F M
    
    C. F D M
    
    参考答案及解析:C。被调用函数里的 defer 语句在返回之前就会被执行,所以输出顺序是 F D M。

    2.下面代码输出什么?

    type Person struct {
        age int
    }
    
    func main() {
        person := &Person{28}
    
        // 1.
        defer fmt.Println(person.age)
    
        // 2.
        defer func(p *Person) {
            fmt.Println(p.age)
        }(person)
    
        // 3.
        defer func() {
            fmt.Println(person.age)
        }()
    
        person = &Person{29}
    }

    参考答案及解析:29 28 28。这道题在第 19 天题目的基础上做了一点点小改动,前一题最后一行代码 person.age = 29 是修改引用对象的成员 age,这题最后一行代码 person = &Person{29} 是修改引用对象本身,来看看有什么区别。

    1处.person.age 这一行代码跟之前含义是一样的,此时是将 28 当做 defer 函数的参数,会把 28 缓存在栈中,等到最后执行该 defer 语句的时候取出,即输出 28;

    2处.defer 缓存的是结构体 Person{28} 的地址,这个地址指向的结构体没有被改变,最后 defer 语句后面的函数执行的时候取出仍是 28;

    3处.闭包引用,person 的值已经被改变,指向结构体 Person{29},所以输出 29.

    由于 defer 的执行顺序为先进后出,即 3 2 1,所以输出 29 28 28。

    总结:
    1、切片cap()容量和长度如何区分?
    2、map类型数据结构首先要make然后存储数据
    3、切片数据结构和通道数据结构
    4、接口数据类型和结构体类型调用 & 通过断言转化
    5、defer的作用

  • 相关阅读:
    hive分区学习
    pyspark的学习
    往hive表中插入数据以及导出数据
    【Pytest学习3】setup和teardown简单用法,fixture里面的scope等于setup,用yield等于teardown
    【Pytest学习2】 pytest用例设计规则,terminal中使用常见命令行参数,pycharm中使用常见的命令行参数
    Jmeter响应内容显示乱码问题的解决办法
    Jmeter(三)测试计划和线程组
    Jmeter(二)Jmeter目录介绍 & 元件介绍
    JMeter之Ramp-up Period(in seconds)说明
    badboy云盘下载链接
  • 原文地址:https://www.cnblogs.com/zh718594493/p/14469282.html
Copyright © 2011-2022 走看看