GO面试
2021-02-25 16:07:19 133 举报
AI智能生成
在GO面试中,您将有机会展示您的编程技能和解决问题的能力。面试官可能会问您关于数据结构、算法、设计模式等方面的问题,以了解您的专业知识。此外,他们可能还会要求您编写代码片段或完成编程任务,以评估您的实际编程能力。为了在面试中取得成功,建议您提前准备并熟悉相关主题,以便能够清晰、自信地回答问题。祝您好运!
作者其他创作
大纲/内容
数据库
mysql
隔离级别
读未提交
脏读
读已提交
不可重复读
可重复读
写数据情况幻读
快照读
select
当前读
update、insert、delete
串行化
对所有读取的行都加锁
并发控制
读写锁
共享锁,排它锁
锁粒度
InnoDB存储引擎实现了行级锁
表锁
MVCC
添加两个版本号,创建事务ID,删除事务ID
乐观锁
给数据行加上版本号
索引
最左前缀原则
查询必须从索引最左边开始,且不能跳过
不能使用范围条件右边的列
索引设计
数据结构尽量简单
主要是数据之间的比较
尽量不为空
索引不会包含有空值的列
前缀索引,指定长度
在列上进行运算,不会使用索引
like以通配符开头,不会使用索引
避免or条件
如果or前面条件使用索引后面没使用,则会放弃所有索引
索引排序
filesort
内存中排序,快排
内存装载不下,外部排序(使用临时表)
索引排序
索引顺序与order by顺序相同,且为同方向(同为正序或同为倒序)
与查询型子句一样,需要满足最左前缀原则,where条件也可以加入评估
连表查询时,仅当order by所有列都是第一个表的字段时才使用索引
索引数据结构
平衡二叉树
基于二分法策略,提高数据查询速度的数据结构
任何节点两个子树高度差不超过1
B树(B-Tree)
B-Tree为多叉树,又名平衡多路查找树
排序方式:递增,左小右大
所有叶子节点均在同一层
非叶子节点保存关键字记录指针
B+Tree
B+Tree的非叶子节点,不保存关键字记录的指针,能保存更多的关键字
叶子节点保存了父节点所有关键字记录的指针
关键字在叶子节点从小到大依次排序,左边结尾数据保存一个右边开始数据的指针
每一个叶子节点包含指向下一个叶子节点的指针,方便范围遍历
优点
层级更少
能保存更多的关键字所以层级更少
查询速度稳定
所有关键字数据地址都存储在叶子节点
系统从磁盘读取数据到内存是以磁盘块为基本单位,位于同一磁盘块的数据会被一次性读出来
InnoDB
聚簇索引(主键索引)
Innodb对主键建立聚簇索引,如果没有主键则选择一个唯一非空字段,在没有就定义一个隐藏主键(一个表只有一个聚簇索引)
节点页只包含索引,叶子页包含了全部行数据(聚簇索引就是”表“)
非聚簇索引(二级索引)
叶子节点存储的是索引key和主键值
MyISAM
非聚簇索引
叶子节点存储指向数据的指针
redis
redis持久化
RDB(存储快照)
将redis存储的数据生成快照并存储到磁盘等介质上
适合于对数据完整性不敏感
AOF(记录指令)
将redis执行过的所有指令记录下来,在下次redis重新启动时,只要把这些指令执行一遍就可以实现数据恢复了
每秒将指令刷入硬盘
缓存
缓存穿透
查询缓存中不存在的数据时会造成缓存穿透
解决方案一:缓存空对象
当redis和mysql都没有对象时,缓存一个空对象到redis
缺点
缓存过多空值,可能导致有效数据被淘汰策略淘汰掉
设置了过期时间,可能导致数据库和redis在某一时间数据不一致
解决方案二:布隆过滤器
存在哈希碰撞,布隆过滤器说这条数据存在,其实不一定存在,但布隆过滤器说这条数据不存在,则一定不存在
将数据哈希到bit数组,增加bit数组长度或使用多个哈希函数避免哈希冲突
缓存击穿
热点数据失效,大量请求到达mysql
解决方案一:分布式锁
缓存雪崩
多个热点数据同时失效,或redis挂了
解决方案一:使用随机的过期时间
解决方案二:使用集群
高可用(HA)
主从
主从复制
从数据库向主数据库发送sync请求
主数据库生产RDB文件并记录此后执行的命令到缓冲区
向所有从数据库发送快照文件,并继续记录被执行的命令
从数据库载入快照,执行主数据库缓冲区记录的命令
主数据库每执行一个命令就向从数据库发送相同的命令
优点
主从复制、读写分离
哨兵
基于主从模式,添加哨兵监控,实现master宕机,自动选举新master并将其他从节点指向master
集群
实现redis的分布式存储,对数据进行分片,每台redis节点存储不同的内容
数据结构
zset
ziplist
元素数量小于128,所有元素长度小于64字节
使用压缩列表来保存,member与score紧挨着
skiplist
dict保存元素与score的字典
skiplist保存元素有序列表
红黑树
黑色完美平衡
淘汰策略
redis用作缓存时,如果内存空间满了,就会自动驱逐老数据
LRU:最近最少使用
记录每个数据最近一次访问的时间戳
随机选出n个数据进行LRU
LFU:最少频率使用
记录每个数据的最近访问时间和访问次数
根据频率、时间顺序进行淘汰
GO
基础
iota
iota在const关键字出现时被重置为0
const声明快中每新增一行iota值自增1
或者:iota代表了const声明快的行索引
return
若为命名返回值,return将后面的表达式的值赋给返回值,然后执行defer,最后返回结果
若为匿名返回值,return将后面表达式的值赋值给一个临时变量,执行完defer后再将临时变量返回
defer
执行顺序:压栈:后进先出
return->defer->返回
panic后依然会执行defer,主动os.Exit不会执行defer
defer后的函数参数会被先执行
局部变量分配在堆还是栈
编译器会自动决定,编译器会做逃逸分析,当变量逃逸则分配在堆上
make与new的区别
make会进行初始化,new返回一个零值的指针
栈的特点
并发与并行
数据结构
channel
主要用于goroutine间通信
map
用哈希表实现,每个bucket存储一组键值对
GO用链地址法解决哈希冲突
interface
互斥锁
包含一个state状态和sema信号量
state为32位整型,1位表示是否被锁定,1位表示是否有协程已被唤醒,1位表示是否处于饥饿状态,29位表示阻塞的协程数
解锁时若有被阻塞协程,则释放信号量
normal模式
获取锁失败不会立即阻塞,会有短时间的自旋,尝试抢锁
starvation模式
饥饿模式不会自旋
被唤醒的协程再次阻塞超过1ms,锁将会被标记为饥饿
一旦有协程释放锁,那么一定会唤醒协程,被唤醒的协程也会成功获取到锁
读写锁
进行写锁定时先将读计数器减去2^30,此时读锁定来检测到读计数器为负数则阻塞等待
互斥锁、读/写信号量,读计数器、写阻塞计数器
垃圾回收
标记清扫
三色标记
混合写屏障
内存分配
go调度
GMP
调度器设计策略
复用线程
避免频繁创建、销毁线程,而是进入睡眠复用线程
M休眠队列
利用并行
最多有GOMAXPROCS个线程分布在CPU上同时运行
抢占
一个goroutine最多占用CPU10ms,防止其他goroutine被饿死
context
writgroup
广播
继承
多态
消息中间件
kafka
消费者组
相同的数据会被不同的消费者组消费多次
同一组内一个消费者只能消费一个分区,消费者大于分区数将会空闲
ack机制
0:kafka不会等待broker的ack,延迟低,但当server挂掉可能会丢数据
1:等待leader确认收到发送ack消息,如果leader挂掉,不保证新leader上存在次数据
-1:等待所有follower收到数据才发送ack
消费者
消费者会记录消费的物理偏移量
一个分片对应一个消费者成员,如果消费者组中成员太多会有空闲成员
顺序
kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是顺序的
整个topic不保证有序,如果保证topic整个有序,那么将partition调整为1
网络
http
http1
给定的TCP连接,一次允许一个请求未完成
文本传输效率低
http2
多路复用,同一域名只需要一个TCP连接
二进制数据传输效率更高
通过流实现多路复用,每个帧会标识出属于哪个流
0 条评论
下一页