go语言常见问题总结

  • go语言中的goroutine和其它语言中的coroutine有什么相同和不同?
    1. coroutine 意味着支持将控制转移到另一个协程的明确手段。也就是说,程序员在确定coroutine何时应该暂停执行并将其控制权传递给另一个coroutine时(通过调用return/exit(通常称为yield))来编写coroutine。
    2. goroutine 它隐含的放弃了某些不确定点的控制权,当goroutine即将在I / O完成,信道发送等某些(外部)资源上休眠时发生这种情况。这种方法与通过channel共享状态相结合程序员将程序逻辑编写为一组连续的轻量级进程,它消除了基于协程和基于事件的方法常见的意大利面条代码问题。
  • goroutine和操作系统线
    1. 相同点,都是简化了并发的操作。
    2. 不同点,简单点来说:就是线程开销太大了,所以搞一个协程,可以在线程之间调度,具体的表现就是将一个函数的执行做成异步的,如果我们用线程来做的话,开销会很大,而且线程上下文的切换也很耗时间。下面翻译原文给的解释“Goroutines是将独立执行的函数 - 协程 - 复用到一组线程上。当协程阻塞时,例如通过调用阻塞系统调用,运行时自动将同一操作系统线程上的其他协同程序移动到另一个可运行的线程,这样它们就不会被阻塞。程序员看不到这一点,这就是重点。结果,我们称之为goroutines,可以非常便宜:它们在堆栈的内存之外几乎没有开销,这只是几千字节。为了使堆栈变小,Go的运行时使用可调整大小的有限堆栈。一个新铸造的goroutine给了几千字节,这几乎总是足够的。如果不是,则运行时间会自动增长(并缩小)用于存储堆栈的内存,从而允许许多goroutine生存在适量的内存中。 CPU开销平均每个函数调用大约三个廉价指令。在同一地址空间中创建数十万个goroutine是切实可行的。如果goroutines只是线程,系统资源将以更小的数量运行。”
  • goroutine的默认调度器是怎么调度的?如何实现自己的一个调度器?
    • 这个是在go语言的runtime里面实现的,需要了解一下go的runtime。参考文章:https://tonybai.com/2017/06/23/an-intro-about-goroutine-scheduler/
    goroutine的生命周期是怎样的过程?
    • 如果在一个goroutine的函数中写一个死循环,那么go的main goroutine是可以保证正常退出,如果main goroutine没有循环,那么子goroutine也不会有循环。这个方案应该是和goroutine的调度机制有关。
    golang中垃圾回收机制是怎么样的? goroutine中常用的数据结构?如何封装自己的数据结构?
    • 就像c语言中自定义结构体一样,golang中同样使用。
  • 在服务器端编程,如何使用socket,什么时候使用应用层消息,如:http,什么时候使用传输层协议,如tcp。
  • go语言编程中的select和c语言中使用select有什么区别?
    • 很类似,golang中select 可以处理多个channel, 就像c语言中使用select处理多个socket通信一样。
  • go语言中有没有线程,有没有进程?如何使用?
    • 没有像python中processing 和multiprocessing 之间的区别,go语言中只有一个goroutine,并且在这之上封装了一个context来实现goroutine之间的通信。
  • go语言中channel,buffer怎么理解,如何控制大小?
    • 有channel,就有buffer,目的是为了缓存大小,但是又不能太大,所以有这么一个参数可以让我们去控制。
  • go语言内存模型
    • 主要的是happern bofore,1:w happens before r, 2:Any other write to the shared variable v either happens before w or after r。并且提供了多个goroutine并发操作同步的手段。参考链接:https://golang.org/ref/mem

参考链接:go语言官网常见问题列表:https://golang.org/doc/faq