Go面试题(一)

1.请写出代码最后输出的内容

package main

import "fmt"

func defer_call() {
	defer func() {fmt.Println("1")}()
	defer func() {fmt.Println("2")}()
	defer func() {fmt.Println("3")}()
	panic("异常")
}

func main() {
	defer_call()

}

执行结果
在这里插入图片描述
defer的顺序我们都了解 类似于堆栈 后进先出 那么321没有什么值得疑问的,那么panic这里的顺序,执行defer的过程中如果遇到recover的时候继续执行,如果没有遇到recover那么执行完所有的defer之后会向stderr抛出panic信息。

2.以下代码有什么问题 请说明原因

package main

type student struct {
	name string
	age int
}

func main() {
	m := make(map[string]*student)
	stus := []student{
		{name: "a",age: 1},
		{name: "b",age: 2},
		{name: "c",age: 3},
	}
	for _,stu := range stus {
		m[stu.name] = & stu
	}
}

这里有朋友经过汇编之后找到了执行结果

{
    var stu student
    for _, stu = range stud {
        t := stu
        m[stu.Name] = &t
  }
}

其实就是多加了一层语句块,将for条件表达式中的变量声明定义放在外层块中了,所以在执行for时,条件表达式中的变量声明只会进行一次,而for每一次循环使用的变量都是外层的变量,而for语句块结束,外层语句块也就结束,所以外部作用域是无法访问stu变量的。但因为m中有引用stu所以stu的内存也不会回收(原理可以参考go语言的gc机制,三色标记的设计模型)

3.下面代码会触发异常吗

package main

import (
	"fmt"
	"runtime"
)

func main() {
	runtime.GOMAXPROCS(1)
	int_chan := make(chan int,1)
	string_chan := make(chan string,1)
	int_chan <- 1
	string_chan <- "hello"
	select {
	case value := <- int_chan:
		fmt.Println(value)

	case value := <- string_chan:

		panic(value)
	}
}

每个 case 都必须是一个通信
所有 channel 表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通信可以进行,它就执行,其他被忽略。
如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。
否则:
如果有 default 子句,则执行该语句。
如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。
所以当两个管道中都有值的时候他会随机抽一个
有概率出发panic
4.下面的代码有什么问题

package main

import (
	"sync"
)

type UserAges struct {
	ages map[string]int
	sync.Mutex
}

func (ua *UserAges) Add(name string,age int) {
	ua.Lock()
	defer ua.Unlock()
	ua.ages[name] = age
}

func (ua *UserAges) Get(name string) int {
	if age,ok := ua.ages[name];ok {
		return  age 
	}
	return -1 
}

func main() {

}

5.map,selice类型数据函数传参是传值还是传递至?下列函数会变成ua的值吗,为什么

func (ua *UserAges) change(name string,age int) {
	ua.ages[name] = age
}

会修改,指针接收者等同于修改了他所在的内存地址中存放的值
6.请说出你能想到的golang多协程平滑关闭方案,后台启动方案
平滑关闭的话我们可以设置信号管理当收到某个信号的时候可以用sync.WaitGroup{} 来等待以及down,也可以根据信号来做热载
7.请问golang客户端http请求长连接怎么建立
8.请求golang的cgo代码中怎么调用c的动态库,golang中底层用的三种编译器是(go build内部调用的)?
9.如果一个变量a interface类型,需要判断不同类型怎么做
可以用switch a.(type) 然后用case来判断
10.请问goland的rpc调用方式用过哪些,顺便说一种golang+rpc的分布式架构
11.请问用过那种redis解决方案,redis官方集群方案采用的数据同步算法是?
redis 主从哨兵
12.请问用过kafka队列中间件吗对比rabbitmq的优点是?
13.es的解决场景是?
14.请问b-tree跟二叉查找树相比的优点有哪些?为什么mysql innodb索引会采用b-tre结构,请问聚簇索引跟辅助索引的区别是?

说实话笔者运维出身对数据结构算法以及开发这块还是学习尚浅,只是朋友遇到了先总结

猜你喜欢

转载自blog.csdn.net/weixin_45413603/article/details/107436826
今日推荐