golang工程师面试第二天

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

**1**.写出代码运行结果,如有错误则指出 (1) ```go package main import "fmt" func main() { /* 先defer的后执行 recover后输出panic中的信息 */ defer func() { if err := recover(); err != nil { fmt.Print(err) } else { fmt.Print("no") } }() defer func() { panic("1111111111111") }() panic("22222222222") }``` **解题思路**:先defer的语句后执行,即假如你defer了多个语句,执行时会按逆序执行,所以这段代码执行顺序为 先 `panic("22222222222")`, 再 ```go defer func() { panic("1111111111111") }()``` 最后 ``` go defer func() { if err := recover(); err != nil { fmt.Print(err) } else { fmt.Print("no") } }()``` 所以得出结果 输出 1111111111111 (2) ```go package main import "fmt" var c1 =make(chan int) var c2 =make(chan int) func main() { go func() { fmt.Println("111111111111") c1<-<-c2 }() go func() { c1<-<-c2 fmt.Println("22222222222") }() <-c1 }``` **解题思路**:无缓存的Channel发送接收都为阻塞, **2**.简述go中的channel和mutex锁机制的原理异同与使用场景 golang中的同步是通过sync.WaitGroup来实现的.WaitGroup的功能:它实现了一个类似队列的结构,可以一直向队列中添加任务,当任务完成后便从队列中删除,如果队列中的任务没有完全完成,可以通过Wait()函数来出发阻塞,防止程序继续进行,直到所有的队列任务都完成为止.WaitGroup总共有三个方法:Add(delta int), Done(), Wait()。Add:添加或者减少等待goroutine的数量Done:相当于Add(-1)Wait:执行阻塞,直到所有的WaitGroup数量变成0 **使用场景**:   程序中需要并发,需要创建多个goroutine,并且一定要等这些并发全部完成后才继续接下来的程序执行.WaitGroup的特点是Wait()可以用来阻塞直到队列中的所有任务都完成时才解除阻塞,而不需要sleep一个固定的时间来等待.但是其缺点是无法指定固定的goroutine数目. Channel机制: 相对sync.WaitGroup而言,golang中利用channel实习同步则简单的多.channel自身可以实现阻塞,其通过<-进行数据传递,channel是golang中一种内置基本类型,对于channel操作只有4种方式: 创建channel(通过make()函数实现,包括无缓存channel和有缓存channel); 向channel中添加数据(channel<-data); 从channel中读取数据(data<-channel); 关闭channel(通过close()函数实现,关闭之后无法再向channel中存数据,但是可以继续从channel中读取数据) channel分为有缓冲channel和无缓冲channel,两种channel的创建方法如下: var ch = make(chan int) //无缓冲channel,等同于make(chan int ,0) var ch = make(chan int,10) //有缓冲channel,缓冲大小是5 其中无缓冲channel在读和写是都会阻塞,而有缓冲channel在向channel中存入数据没有达到channel缓存总数时,可以一直向里面存,直到缓存已满才阻塞.由于阻塞的存在,所以使用channel时特别注意使用方法,防止死锁的产生. **golang 并发总结**: 并发两种方式:sync.WaitGroup,该方法最大优点是Wait()可以阻塞到队列中的所有任务都执行完才解除阻塞,但是它的缺点是不能够指定并发协程数量. channel优点:能够利用带缓存的channel指定并发协程goroutine,比较灵活.但是它的缺点是如果使用不当容易造成死锁;并且他还需要自己判定并发goroutine是否执行完. 但是相对而言,channel更加灵活,使用更加方便,同时通过超时处理机制可以很好的避免channel造成的程序死锁,因此利用channel实现程序并发,更加方便,更加易用. **3**.简述go中实现非阻塞IO的原理,以及对goroutine的理解 **4**.如何理解go中的闭包和逃逸分析 ```go func f(i int) func() int { return func() int { i++ return i } }``` 返回的函数就是闭包。 **逃逸分析**:在编译程序优化理论中,逃逸分析是一种确定指针动态范围的方法,可以分析在程序的哪些地方可以访问到指针。它涉及到指针分析和形状分析。 当一个变量(或对象)在子程序中被分配时,一个指向变量的指针可能逃逸到其它执行线程中,或者去调用子程序。如果使用尾递归优化(通常在函数编程语言中是需要的),对象也可能逃逸到被调用的子程序中。 如果一个子程序分配一个对象并返回一个该对象的指针,该对象可能在程序中的任何一个地方被访问到——这样指针就成功“逃逸”了。如果指针存储在全局变量或者其它数据结构中,它们也可能发生逃逸,这种情况是当前程序中的指针逃逸。 逃逸分析需要确定指针所有可以存储的地方,保证指针的生命周期只在当前进程或线程中。 **逃逸分析的用处**:最大的好处应该是减少gc的压力,不逃逸的对象分配在栈上,当函数返回时就回收了资源,不需要gc标记清除。 因为逃逸分析完后可以确定哪些变量可以分配在栈上,栈的分配比堆快,性能好 同步消除,如果你定义的对象的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。 **5**.列出目前OS涉及到的几种进程调度算法,并简述对他们的理解 **6**.假如一个web服务器存在大量的CLOSE_WAIT和LAST_ACK状态的连接,你认为一般是那些原因造成的 **7**.任意演示一段代码,说明golang是如何实现接口的,并能体现他相对oop中继承方式的一些优势

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

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

1955 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
2 回复  |  直到 2018-01-16 18:36:08
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传