共计 3015 个字符,预计需要花费 8 分钟才能阅读完成。
每个时代,都不会亏待会学习的人。
大家好,我是 yes。
这种设计类问题想必大家都不生疏,面试时或多或少都能碰到。
比方如何写一个线程池?如何写一个 HashMap?如何写一个 RPC 框架等等,当然这里的写不是真的叫你用代码写进去,只是说说设计理念,整体架构。
这个面试题来自于一个读者的字节面试经验,我会从面试技巧和消息中间件的设计两个方面论述。
我感觉重点在于面试技巧,因为它通用。
两种极其的状况
大多数同学遇到这种问题会呈现两种极其的状况:
- 第一种:一脸懵逼,两眼无神,不知从何说起,万般思路,都化作一声叹气。
- 第二种:沉默寡言,像是口中架起了一把加特林,哒哒哒哒哒哒哒哒,还冒着蓝火。
第一种不用说了,好一点的面试官可能会疏导你,会问一些提示性的问题,一步一步地带你渐入佳境,当然你要是胸中无点滴,那还是没救的,局面就异样地难堪。
第二种会把面试官整蒙了,或者你真的懂很多,很多细节也都清晰,然而你不能一股脑儿的都抛出来,这会显得你抓不住重点。
面试官也是人
这点其实很要害,很多把面试官当成一个莫得感情的发问机器人,感觉他无所不能能够齐全 get 到你的点,殊不知你引以为傲的细节答复,他可能感觉你在说蛇皮。
是人就会有感情,就须要交换,好的面试官会把控整体进度,从拉家常开始,让场子热起来再一步一步的深挖。
当然也有一些面试官比拟弱,这时候就须要你来 特意地流出一点空白,来让面试官涂鸦,让面试官感觉你这人就很难受,你这波就稳了。
当然即便面对着把控全场的面试官你也得主动出击,每个人都有本人的善于点,你须要疏导面试官来询问你的短处。
正确的答复姿态
正确的答复姿态是 BFS(广度优先搜寻)而不是 DFS(深度优先搜寻),什么意思呢?
就是咱们须要 先从大局上讲出须要设计的货色的重点,而后再期待面试官的持续发问,深挖。
咱们须要 琢磨面试官的心理,从他的发问能够看出他想要晓得的重点是哪个方向的。
比方就拿 HashMap 来说,你 简略的 把获取、写入、抵触解决、扩容啥的都说了,而后期待面试官接下来的发问,有可能会往线程平安方面深刻,也有可能会往扩容方向再挖,比方引出 Redis 的 hash 扩容等等。
所以说给面试官留发问的机会,抓住他的爱好或者说熟知的方向答复,这样如果你答得好,相互之间谈的来,面试官会对你高度认可。
而且在 说各设计要点的时候也要留神进展,要留机会给面试官插话,让面试官充沛参加你的设计。
还是拿 HashMap 作为例子,比方你说了获取、写入、抵触之后稍作进展,这时候大概率面试官还会问还有吗?让面试官有参与感,让他感觉通过他的疏导这个设计才逐渐地欠缺。
当然如果不问也没事,你进展下持续说就行。
让面试成为一场技术交换,这是面试的最高境界,置信面试完了之后单方都会有意犹未尽的感觉,惺惺相惜就是这么来的。
然而这种场景也不是这么容易碰到的,首先你和面试官得有雷同方向的爱好,比方你对 JVM 有很深刻的钻研,而面试官对存储方面有很深刻的钻研,JVM 懂的不深,这样就碰不出火花了。
所以说会有很多人碰到这么个状况:我面这个公司一面挂,另一家公司面面超神,这都是很失常的。
当然你要是说你全能,那当我没说。
小结一下面试技巧
首先要正确的对待面试官,你和面试官是等同的,不要一来就低声下气的。
其次答复问题须要抓住重点,不要一股脑儿的把你晓得的都说了,要留白待面试官发问。
要把控面试的节奏,往本人熟知的方向上引。
如何写个消息中间件
接下来咱们再看看如何写个消息中间件。
首先咱们须要明确地提出消息中间件的几个重要角色,别离是生产者、消费者、Broker、注册核心。
简述下消息中间件数据流转过程,无非就是生产者生成音讯,发送至 Broker,Broker 能够暂缓音讯,而后消费者再从 Broker 获取音讯,用于生产。
而注册核心用于服务的发现包含:Broker 的发现、生产者的发现、消费者的发现,当然还包含下线,能够说服务的高可用离不开注册核心。
而后开始简述实现要点,能够同通信讲起:各模块的通信能够基于 Netty 而后自定义协定来实现,注册核心能够利用 zookeeper、consul、eureka、nacos 等等,也能够像 RocketMQ 本人实现简略的 namesrv(这一句话就都是关键词)。
为了思考扩容和整体的性能,采纳分布式的思维,像 Kafka 一样采取分区理念,一个 Topic 分为多个 partition,并且为保证数据可靠性,采取多正本存储,即 Leader 和 follower,依据性能和数据牢靠的衡量提供异步和同步的刷盘存储。
并且利用选举算法保障 Leader 挂了之后 follower 能够顶上,保障音讯队列的高可用。
也同样为了进步音讯队列的可靠性利用本地文件系统来存储音讯,并且采纳程序写的形式来进步性能。
可依据音讯队列的个性利用内存映射、零拷贝进一步的晋升性能,还可利用像 Kafka 这种批处理思维进步整体的吞吐。
至此就差不多了,该说的要点说的都差不多了,面试官心里曾经想,这人如同有点货色。
之后能够深挖的点就很多了,比方提到的 Netty,各种注册核心就能问很多,比方各注册核心之间的选型比照等。
你还提到了选举算法,所以可能会问 Bully 算法、Raft 算法、ZAB 算法等等。
你还提到了分区,可能会问这个分区和 RocketMQ 的队列有什么不同啊?具体分区要怎么实现?
而后你提到程序写,可能会问为什么要程序写啊?你说的内存映射和零拷贝又是什么啊?那你晓得 RocketMQ 和 Kafka 用了哪个吗?(这些我都剖析过,能够看 RocketMQ 和 Kafka 底层存储之那些你不晓得的事)
当然还有可能问各种细节,比方音讯的写入如何存储、音讯的索引如何生成等等,来深挖看你有没有看过消息中间件的源码。
能够问的还很多,这篇文章我也不可能每个点都延长开说,这些知识点还是得靠大家与日俱增和素日的多加思考。
当然日后的文章能够写一写明天提到的一些点,比方 Netty、选举算法啊,多种注册核心比照啊啥的。
面试官想问的是什么
再回到这个面试题,其实面试官想问的就是大方向上的设计,包含整体的架构、数据的流转和一些个性的把握,所以对于这个问题他想听到的就是那些重点,而不是那些细节。
而持续的深挖取决于你答复这个问题时提出的各个关键词,对于面试官本身而言相熟的词一抓到,他就曾经晓得下一步要问你什么了。
所以 在答复面试官的时候不仅要 get 到他的点,还得为之后的答复铺路,不会说的点不要提,善于的点多提提。
最初
之前我曾经提到了,这篇文章的重点其实不在于如何答复写一个消息中间件,而在于面试的技巧。
因为面试题千千万,而技巧把握了那么千千万的面试题都实用。
我还想提一下对于面试的一些集体认识,我集体是面试驱动学习型选手,我学习的能源就是面试,我享受面试官问我啥我都嘴角一翘微微一笑的那种不羁。
然而我不提倡那种纯正反面试题的做法,学习是一个与日俱增的过程,就像我每篇文末说的,从一点点到亿点点,又像我每篇结尾都会提的,每个时代,都不会亏待会学习的人。
我的面试驱动不仅仅是说为了面试而学习,还要以面试场景来学习,什么意思呢?
学任何一种货色,都模仿一个面试官在你后面,让他从各种角度向你发问,驱动你全方位的了解一个知识点,这才是我说的面试驱动学习型选手。
所以如果你看过我之前的文章会发现我常常会提出为什么呢,而后再作答。
还有一点要留神,入手能力,这很要害。
Talk is cheap, show me the code。
我是 yes,从一点点到亿点点,咱们下篇见。