Golang面试题 练习题

p_gerer · · 755 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

整理自golang中文网https://studygolang.com/

不管面试里用不用得到,万丈高楼平地起,先得从基础做起

package main
 
import (
     "fmt"
)
 
 func main() {
    defer_call()
 }

func defer_call() {
   defer func() { fmt.Println("打印前") }()
   defer func() { fmt.Println("打印中") }()    
   defer func() { fmt.Println("打印后") }()
   panic("触发异常")
}

答案:

打印后
打印中
打印前
触发异常

参考解析:defer 的执行顺序是后进先出。当出现 panic 语句的时候,会先按照 defer 的后进先出的顺序执行,最后才会执行panic。

func main() {
     slice := []int{0,1,2,3}
     m := make(map[int]*int)
     for key,val := range slice {
         m[key] = &val
     }

    for k,v := range m {
        fmt.Println(k,"->",*v)
    }
}

答案:

0 -> 3
0 -> 3
0 -> 3
0 -> 3

参考解析:这是新手常会犯的错误写法,for range 循环的时候会创建每个元素的副本,而不是元素的引用,所以 m[key] = &val 取的都是变量 val 的地址,所以最后 map 中的所有元素的值都是变量 val 的地址,因为最后 val 被赋值为3,所有输出都是3.

3.下面两段代码输出什么

// 1.
func main() {
   s := make([]int, 5)
   s = append(s, 1, 2, 3)
   fmt.Println(s)
}

// 2.
func main() {
    s := make([]int,0)
    s = append(s,1,2,3,4)
    fmt.Println(s)
}

答案:

[0 0 0 0 0 1 2 3  ]
[1 2 3 4]

参考解析:这道题考的是使用 append 向 slice 添加元素,第一段代码常见的错误是 [1 2 3],需要注意
make 分配slice内存元素默认分配0值, slice内存不足底层数组会重新分配

4.下面这段代码有什么缺陷

func funcMui(x,y int)(sum int,error){
    return x+y,nil
}

答案: 返回第二个参数未命名
参考解析:
在函数有多个返回值时,只要有一个返回值有命名,其他的也必须命名。如果有多个返回值必须加上括号();如果只有一个返回值且命名也必须加上括号()。这里的第一个返回值有命名 sum,第二个没有命名,所以错误。

5.new() 与 make() 的区别
参考答案:
new(T) 和 make(T,args) 是 Go 语言内建函数,用来分配内存,但适用的类型不同。

new(T) 会为 T 类型的新值分配已置零的内存空间,并返回地址(指针),即类型为 *T 的值。换句话说就是,返回一个指针,该指针指向新分配的、类型为 T 的零值。适用于值类型,如数组、结构体等。

make(T,args) 返回初始化之后的 T 类型的值,这个值并不是 T 类型的零值,也不是指针 *T,是经过初始化之后的 T 的引用。make() 只适用于 slice、map 和 channel.

6.下面这段代码能否通过编译,不能的话原因是什么;如果能,输出什么

func main() {
    list := new([]int)
    list = append(list, 1)
    fmt.Println(list)
}

参考答案及解析:不能通过编译,new([]int) 之后的 list 是一个 *[]int 类型的指针,不能对指针执行 append 操作。可以使用 make() 初始化之后再用。同样的,map 和 channel 建议使用 make() 或字面量的方式初始化,不要用 new() 。

7.下面这段代码能否通过编译,如果可以,输出什么?

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{4, 5}
    s1 = append(s1, s2)
    fmt.Println(s1)
}
参考答案及解析:不能通过编译。append() 的第二个参数不能直接使用 slice,需使用 … 操作符,将一个切片追加到另一个切片上:append(s1,s2…)。或者直接跟上元素,形如:append(s1,1,2,3)。

8.下面这段代码能否通过编译,如果可以,输出什么?

var(
    size := 1024
    max_size = size*2
)

func main() {
    fmt.Println(size,max_size)
}
参考答案及解析:不能通过编译。这道题的主要知识点是变量声明的简短模式,形如:x := 100。但这种声明方式有限制:
必须使用显示初始化;
不能提供数据类型,编译器会自动推导;
只能在函数内部使用简短模式;

9.下面这段代码能否通过编译?不能的话,原因是什么?如果通过,输出什么?

  func main() {
     sn1 := struct {
         age  int
         name string
     }{age: 11, name: "qq"}
    sn2 := struct {
         age  int
         name string
     }{age: 11, name: "qq"}

    if sn1 == sn2 {
        fmt.Println("sn1 == sn2")
    }

    sm1 := struct {
        age int
        m   map[string]string
    }{age: 11, m: map[string]string{"a": "1"}}
    sm2 := struct {
        age int
        m   map[string]string
    }{age: 11, m: map[string]string{"a": "1"}}

    if sm1 == sm2 {
        fmt.Println("sm1 == sm2")
    }
 }

参考答案及解析:编译不通过 invalid operation: sm1 == sm2

这道题目考的是结构体的比较,有几个需要注意的地方:

1>. 结构体只能比较是否相等,但是不能比较大小。

2>. 相同类型的结构体才能够进行比较,结构体是否相同不但与属性类型有关,还与属性顺序相关,sn3 与 sn1 就是不同的结构体;

    sn3:= struct {
        name string
        age  int4    }{age:11,name:"qq"}

3>. 如果 struct 的所有成员都可以比较,则该 struct 就可以通过 == 或 != 进行比较是否相等,比较时逐个项进行比较,如果每一项都相等,则两个结构体才相等,否则不相等;

那什么是可比较的呢,常见的有 bool、数值型、字符、指针、数组等,像切片、map、函数等是不能比较的。 具体可以参考 Go 说明文档。http://docs.studygolang.com/ref/spec#Comparison_operators

10.通过指针变量 p 访问其成员变量 name,有哪几种方式?
A.p.name
B.(&p).name
C.(*p).name
D.p->name
参考答案及解析:A C

2.下面这段代码能否通过编译?如果通过,输出什么?

 package main
 
 import "fmt"
 
 type MyInt1 int
 type MyInt2 = int
 
func main() {
    var i int =0
    var i1 MyInt1 = i 
    var i2 MyInt2 = i
    fmt.Println(i1,i2)
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:p_gerer

查看原文:Golang面试题 练习题

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

755 次点击  ∙  1 赞  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传