整理的面试题答案
golang
channel 实现原理,底层实现结构,讲讲怎么优雅的关闭一个 channel。channel 有哪些应用,什么情况下 channel 会造成内存泄露?
Channel关闭原则
- 不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作。
- 也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费者已经没有值可以继续读了。只要坚持这个原则,就可以确保向一个已经关闭的channel发送数据的情况不可能发生。
由 channel 引发的血案 —-(关关向)
- 关闭一个 nil 值 channel 会引发 panic。
- 关闭一个已关闭的 channel 会引发 panic。
- 向一个已关闭的 channel 发送数据。
channel 的一些应用 —-信超生 数控互
- 信号通知
- 超时控制
- 生产消费模型
- 数据传递
- 控制并发数
- 互斥锁
- one million……
pprof 可用来查看内存泄露
map 的底层实现,什么情况下会扩容,怎么扩容?是线程安全的吗?那 sync 包中的 map 是怎么实现线程安全的?
扩容情况一:存储的键值对数量过多
扩容情况二:溢出桶数量过多
不是线程安全的。在同一时间段内,让不同 goroutine 中的代码,对同一个字典进行读写操作是不安全
的。字典值本身可能会因这些操作而产生混乱,相关的程序也可能会因此发生不可预知的问题。
配合(锁)实现线程安全的map。 sync.map实现的原理。
加了sync.map,兼容线程安全。在我的理解中,sync.map实现就是依靠两张map对读操作和写操作分离,后续根据需要在把dirty map合入 read map中。相对于乐观锁实现的方式,写进程执行的时候,读进程也可能在read map上进行。
gmp 这都背不下来,转行吧。
垃圾回收机制 面试题:请简单描述 Go 语言 GC(垃圾回收)的工作原理
mysql
1.b+ 树 与 hash的区别
b+树索引主要针对大规模数据存储,相较于哈希索引更具优势。
什么是死锁?当两个事务都需要获得对方持有的排他锁才能完成事务,这样就导致了循环锁等待,也就是常见的死锁类型。
解决死锁的方法:
1、 数据库参数
2、 应用中尽量约定程序读取表的顺序一样
3、 应用中处理一个表时,尽量对处理的顺序排序
4、 调整事务隔离级别(避免两个事务同时操作一行不存在的数据,容易发生死锁)
redis
为什么说redis能够快速执行
- 绝大部分请求是纯粹的内存操作(非常快速)
- 采用单线程,避免了不必要的上下文切换和竞争条件
- 非阻塞IO - IO多路复用
redis 的死锁问题
微服务
本作品采用《CC 协议》,转载必须注明作者和本文链接