2020-08-20 晚上面试

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

2020-08-20 晚上面试

  • 自我介绍
  • 你最近做过哪些项目。
  • 为什么要离职。

更公平的竞争环境和脱离舒适圈。

  • 你的项目里有对redis的多次操作,怎么提高效率。

利用redis的pipe,将多次redis操作合并一起,降低网络延迟。

  • 刚刚你说到sortedset,sort是怎么实现的。

利用了跳表实现了排序。

  • sortedset的查询一个数据的时间复杂度是怎么样子的?

一开始答的logn,面试官说你确定吗?我就不确定了,查了一下,确实是logn。

  • 跳表是怎么实现的?

仍然是链表的结构,但是多了几个指针指向更加后面的值,实现快速跳跃。

  • redis的集群有几种?

三种,主从,哨兵,集群。

  • 分别说一下这几种。

主从是指有两个redis节点,其中从节点保持跟主节点同步。

  • 同步方式是怎么样子的?

就是当redis有写操作的时候,给从节点也发一个,但是从节点不会过期key,所以主节点有key删除的时候,也会跟从节点说删除某个key。(其实这个只是增量复制,还有全量复制忘记了。。)

哨兵模式是利用一个哨兵,定时地去ping redis的节点,当redis节点不可达之后,会通过修改配置文件,让从redis代替主节点,维持可用。

redis集群是通过redis key hash分区之后落在哪个hash槽中,而每个redis节点都负责一部分hash槽,从而找到该key应该被哪个节点所处理。

  • redis集群是怎么实现高可用的?

答了通过gossip协议来同步配置。。。

事实上错了。。我忘记redis集群也有从节点了,当多个节点发现有节点不通,就判定该节点不可达,然后对他故障转移,然后从他的从节点中选中一个替换他,保证高可用。

  • redis至少有多少个才能成为集群?(因为我上题答错了)

3个。

  • 你确定是三个吗?

不确定。。但是我记得是要3个节点。(事实上还有从节点啊!!!)洗澡的时候才想起来。

  • mysql用的多吗?

挺多挺熟的。

  • mysql有多少种存储引擎。

mysql存储引擎有很多种,因为它支持自己开发,但是常用的只有innodb和 MyISAM 。

  • 说说他们之前的差别。

innodb支持事务,myisam不支持。

innodb用的行表,myisam用的表锁。

  • 四个隔离级别。

我忘记四个隔离级别叫什么名字了,只记得具体表现,跟面试官说了每种隔离级别的具体表现。

应该是未提交读,提交读,可重复读,串行化。

  • innodb是第几个级别。

第三种(可重复读)

  • 那可重读和可串行化的差距在哪里?

记得跟区间有关,具体忘记了。(答案是范围读的时候,如果其他事务在该范围插入数据的时候,会被读到)

  • 主键索引和唯一索引的区别。

主键的话是聚簇索引,数据的内容会存在索引的叶子节点之上,而唯一索引的叶子节点只保存主键数据。

  • 唯一索引查询的时候就要回表咯?

不是的,要看查询的内容,要是select的数据就是索引内容的话,就不用回表。

  • 怎么看一条语句的性能。

explain。

  • 有哪些数据需要注意的?

索引类型和行数。。

  • 哪种索引类型最好。

答了index(事实上不对,最好应该是NULL,就是不用查直接算出来的那种)

  • golang熟不熟啊?

熟啊,就用了很久。

  • map是线程安全的吗?

不是。

  • 怎么解决这个问题呢?

用读写锁和sync.map。

  • 读写锁的表现形式是怎么样的。

当其中一个协程拥有写锁的时候,其他协程不管是要读锁还是写锁,都会被阻塞。

其中一个协程拥有读锁时,其他协程只能申请读锁,而申请写锁会被阻塞住。

  • chan怎么实现的。

用的环形链表。有个头尾指针,还有个结构存储被chann阻塞的goroutine。

  • 有缓存和没缓存的chan表现形式有什么不同?

有缓存当缓存未满时,往里面塞数据不会被阻塞,但是没缓存的会被阻塞。

  • 这样一个场景,如果我要往一个缓存chan里面塞东西,塞不进去就丢掉怎么办?

我一直都是用select拿数据,忘记他还可以用来看缓存是否满了,一开始答的对比len和cap后面才答了select,试了一下,果然可以。

func main() {
    testChan := make(chan int, 1)
    testChan <- 1
    select {
    case testChan <- 2:
        println("aaa")
    default:
        println("bbb")
    }
}

//output:bbb
  • 数组和切片的区别。

数组创建的时候,内存是固定的,只能放那么多元素,没有放的元素都初始化了。切片存储了是数组的指针和len和cap,可拓展

  • 切片的append操作时怎么样子的?

会在切片的后面增加一个元素,如果切片满了要扩容,那么返回的值将和原来的切片不是一个指针。

  • 说说切片的扩容。

就插入的时候发现切片内存不够了,就会触发扩容,会申请一个原容量两倍的数据切片,但是在到了一定程度(猜的1000,应该是1024)就不是两倍了,会是25%。

  • 讲讲go的协程调度?

(内容太多了,自己查一下吧。)

  • 如果协程发生阻塞会怎么样?

p会脱离m,让m绑定g,p去找其他m继续执行任务。

  • 网络阻塞呢?

会有一个net list,有事件的epoll会到这个net list中,调度器会定时把这里面的数据拿到全局g队列里面(其实m在自旋的时候也会拿,忘记答了)

  • 你们的etcd有做服务负载吗?

我们的负载均衡是靠自己实现的,etcd的表现更像是一个数据库的存在。

  • 你有用prometheus吧?那你监控里的句柄数,cpu使用时怎么算的?

go的prometheus包自带的,用查询语句就能查出来。

  • 有用过pprof吗?

有的。

  • 主要用来干嘛?

看协程泄露,因为他记录了每个协程的堆栈,特别容易看。

  • 那如果发现自己的go程序cpu很高怎么办?

利用pprof可以分析go程序,看到所有函数的cpu使用率。

  • linux有用吗?

有的。

  • centos还是Ubuntu。

都有,服务器用的centos,自己是用wsl,是Ubuntu。

  • 你们服务器用的docker吗?k8s呢?

都没有,最原始的虚拟机。

  • 怎么看连接?

netstat指定一个进程。

  • 具体是什么命令。

忘记了。( netstat –ano|findstr

  • timewait是什么状态?

四次挥手之后,为了防止数据误传端口,端口需要保持这个状态一段时间。

  • 怎么看句柄。

lsof。

  • 看cpu占用。

top,可以看到每个进程,如果要详细,可以用vmstat。

  • 最后问一道算法题,实现一个lru。

一开始没有要求,我就随便说了用数组,最简单的那种。

  • 时间复杂度要求1呢?

用map+list+加记录头尾两节点实现时间复杂度为1的lru。


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

本文来自:简书

感谢作者:yellowone

查看原文:2020-08-20 晚上面试

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

576 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传