设为首页 加入收藏

TOP

Go-常见的面试题(一)(一)
2019-09-03 02:38:43 】 浏览:33
Tags:Go- 常见 试题

文章转载自:http://www.pythonheidong.com/blog/article/2261/

文章转载地址:https://juejin.im/entry/5971bed66fb9a06bb21adf15

1、写出下面代码的输出

package main

import "fmt"

func main() {
	defer_all()
	panic("触发异常")
}

func defer_all()  {
	defer func() {
		fmt.Println("打印前")
	}()
	defer func() {
		fmt.Println("打印中")
	}()
	defer func() {
		fmt.Println("打印后")
	}()
}

  解析:这道题主要考察的是对 defer 的理解,defer 主要是延迟函数,延迟到调用者函数执行 return 命令之前,

多个 defer 之前按照先进后出的顺序执行,所以,这道题中,在 panic 触发时结束函数运行,在 return 之前依次打

印:打印后、打印中、打印前。最后 runtime 运行时抛出打印 panic 异常信息,panic 需要 defer 结束后才会向上传

        需要注意的是,函数的 return value 不是原子操作,而是在编译器中被分解成两部分:返回值和return,而我们

知道 defer 是在 return 之前执行的,所以可以在 defer 函数中修改返回值,如下示例:

package main

import (
	"fmt"
)

func main() {
	fmt.Println(doubleScore(0))    //0
	fmt.Println(doubleScore(20.0)) //40
	fmt.Println(doubleScore(50.0)) //50
}
func doubleScore(source float32) (score float32) {
	defer func() {
		if score < 1 || score >= 100 {
			//将影响返回值
			score = source
		}
	}()
	score = source * 2
	return

	//或者
	//return source * 2
}

2. 下面的代码输出什么?

package main

import "fmt"

func calc(index string, a, b int) int {
	ret := a + b
	fmt.Println(index, a, b, ret)
	return ret
}

func main()  {
	a := 1
	b := 2
	defer calc("1", a, calc("10", a, b))
	a = 0
	defer calc("2", a, calc("20", a, b))
	b = 1
}

 解析:

   程序在执行到第三行的时候,会先执行 calc 函数的 b 参数,即:calc("10",a,b),输出:10,1,2,3 得到值 3,然后因为

defer 定义的函数是延迟函数故 calc("1",1,3) 会被延迟执行

   程序执行到第五行的时候,同样先执行 calc("20",a,b) 输出:20,0,2,2 得到值 2,同样将 calc("2",0,2) 延迟执行

   程序执行到末尾的时候,按照栈先进后出的方式依次执行:calc("2",0,2),calc("1",1,3),则就依次输出:2,0,2,2、

1,1,3,4

3.请写出以下输出内容

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

  解析:

     使用 make 初始化 slice,第二个参数代表的是 slice 的长度,slice 还有第三个参数表示容量,这里没有指定容量表示创建一个

满容的切片,使用 len()、cap() 函数获取切片的 长度,初始化后切片的长度和容量都是 5,使用 append 追加三个元素使得切片的

长度大于原有的容量,此时切片的容量扩大一倍,变成 10,因此输出的结果为:

[0 0 0 0 0 1 2 3]

3. 下面的代码能正常编译吗?

package main

import (
	"fmt"
)

type People interface {
	Speak(string) string
}

type Stduent struct{}

func (stu *Stduent) Speak(think string) (talk string) {
	if think == "bitch" {
		talk = "You are a good boy"
	} else {
		talk = "hi"
	}
	return
}

func main() {
	var peo People = Stduent{}
	think := "bitch"
	fmt.Println(peo.Speak(think))
}

  运行打印结果:

# command-line-arguments
.\main.go:23:6: cannot use Stduent literal (type Stduent) as type People in assignment:
        Stduent does not implement People (Speak method has pointer receiver)

  从上面的输出信息可以看出 Student 没有实现 People 这个接口

       解析:

       我们来看一下语言规范里面定义的规则,这些规则用来说明一个类型的值或指针是否实现了该接口:

       1.类型 *T 的可调用方法集包含接收者为 *T 或 T 的所有方法集

          这条规则说的是如果我们用来调用接口方法的变量是一个指针类型,那么方法的接收者可以是值类型也可以是指针类型,

现在看一下我们的例子显然是不符合规则的,var peo People = Student{} 是一个值类型

       2. 类型 T 的可调用方法集包含接收者为 T 的所有方法集

         这条规则说的是如果我们用来调用
Go-常见的面试题(一)(一) https://www.cppentry.com/bencandy.php?fid=78&id=246324

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇go 面试题总结 下一篇Mac下搭建go和beego开发环境