golang常见的坑和面试题

坑:

  1. uint 不能直接相减,结果是负数会变成一个很大的uint
  2. channel一定记得close(可以不用关闭 chan。但这前提是这个 chan 永远不再使用了!)
  3. goroutine记得return或者中断,不然容易造成goroutine占用大量CPU
  4. 从slice创建slice,注意原slice的操作可能导致底层数组变化
  5. channel是通过注册相关goroutine id实现消息通知的
  6. slice底层是数组,保存了len,capacity和对数组的引用
  7. JSON 标准库对 nil slice 和 空 slice 的处理是不一致

面试题:

1.除了 mutex 以外还有那些方式安全读写共享变量?

  • Golang中Goroutine 可以通过 Channel 进行安全读写共享变量。

2.无缓冲 Chan 的发送和接收是否同步?

  • ch := make(chan int)
  • 无缓冲的channel由于没有缓冲发送和接收需要同步.
  • channel无缓冲时,发送阻塞直到数据被接收,接收阻塞直到读到数据。
  •  
  • ch := make(chan int, 2)
  • 有缓冲channel不要求发送和接收操作同步.
  • channel有缓冲时,当缓冲满时发送阻塞,当缓冲空时接收阻塞。

3.Golang 中常用的并发模型?

  • 通过channel通知实现并发控制
  • 通过sync包中的WaitGroup实现并发控制
  • 在Go 1.7 以后引进的强大的Context上下文,实现并发控制

4. 什么是goroutine,他与process, thread有什么区别?

process进程

  • 程序运行时的产物,也就是正在运行的代码;
  • 拥有独享的虚拟地址空间(堆和栈),由操作系统调度。

thread线程

  • 系统级线程总是在进程之内;
  • 拥有独立的栈空间,所有运行在同一个进程里的线程,共享该进程的虚拟地址空间;
  • 一个进程至少有一个线程,每个进程的第一个线程(主线程)随着进程启动而创建;
  • 主线程外的系统级线程由代码显示创建和销毁,调度由操作系统完成;

协程

  • 用户级线程;
  • 协程架设于系统级线程之上,所以和系统级线程一样不共享栈空间,共享所在进程的虚拟地址空间;
  • 创建、销毁、调度、状态变更以及其中的代码和数据都需要在程序中手动地实现和处理,程序编写者既是指令下达者又是指令执行者。

goroutine:

5. 什么是channel,为什么它可以做到线程安全?

Channel是Go中的一个核心类型,可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication),Channel也可以理解是一个先进先出的队列,通过管道进行通信。

Golang的Channel,发送一个数据到Channel 和 从Channel接收一个数据 都是 原子性的。而且Go的设计思想就是:不要通过共享内存来通信,而是通过通信来共享内存,前者就是传统的加锁,后者就是Channel。也就是说,设计Channel的主要目的就是在多任务间传递数据的,这当然是安全的。

6. 了解读写锁吗,原理是什么样的,为什么可以做到?

7. 如何用channel实现一个令牌桶?

8. 如何调试一个go程序?

9. 如何写单元测试和基准测试?

10. goroutine 的调度是怎样的?

11. golang 的内存回收是如何做到的?

12. 什么是interface?

13.Go 空结构体 struct{} 的使用

  • 不占据任何的内存空间。
  •  map 作为集合(Set)使用时,可以将值类型定义为空结构体,仅作为占位符使用即可
  • 不发送数据的信道(channel)
  • 仅包含方法的结构体
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值