面试复盘
总结:
面试了将近一个月,大厂基本上都面过了,大厂技术栈基本上都是springcloud+mysql+redis+kafka,一面基本上都是自我介绍,问问kafka问问redis问问mysql问问并发。问题基本上都很简单,虽然说都是八股文背一背就行了,不过最好还是有自己的理解,不然稍微厉害的面试官会考察你的思路根据你的理解出场景题,如果只是背诵问两个问题就能发现你根本不理解。简历上写的技术一定要重点准备。
面试碰到不会的场景题目没关系,跟面试官表达出自己的思考过程,面试官一般也会提点下。如果碰到不会的知识点,直接坦言自己接触过较少,不会即可。但是自我介绍,尤其是项目介绍一定要条理清楚,逻辑清晰。建议先面试一两个然后录音复盘。
中间件:
Kafka(RocketMQ只有腾讯阿里问了几句)
Redis(数据类型基本都会问,持久化也基本都会问,厉害一点的面试官会根据数据类型的原理出场景题问你怎么实现)
数据库:
Mysql(架构+索引、调优)
Java:
LinkedList与ArrayList、hashmap
并发编程:volatile、synchronized、同步器、线程数据交换
算法:
我是没碰到特别难得算法,面试过的大厂只有lazada给45min做了算法题,其他都是面试结束给20min左右,所以题目基本是leetcode初中级足够了,考点基本上就是链表、bfs、dfs、堆(topK)。
典型考题:
topK
链表题目(考的次数非常多)
N个线程按顺序输出(考了两次,之前专门写了个博客)
消息队列篇
介绍下消息队列?
消息队列我个人的理解,其实就是做一件事:系统A将消息发送给消息队列,然后系统B从消息队列去获取A发送的消息。
那么,消息队列需要有几点能力:
- 消息的堆积能力:如果系统A发送上去了,系统B因为网络原因或者是出现故障宕机,导致消费延迟,消息都在消息队列中堆积了,不能因为消息堆积影响消息队列的性能
- 高可靠性:消息不能发送成功,但是丢失了啊
- 高可用性:就是说因为一些原因消息队列不能提供了,需要短时间内有解决方案——一般是副本机制,原来的消息队列不能提供了,那就换一个备用的来
- 低延迟:系统A发送了消息如果系统B需要过很久很久才能获取,那肯定体验是不好的
为什么需要消息队列?
从上面消息队列的介绍和能力可以看出,它其实可以做三件事:异步、解耦、削峰。
异步
异步的价值,个人理解是可以把非核心的业务逻辑从核心的业务中抽取出来,比如我们购买商品,通常下完订单后不仅仅是商品库存-1,还会包含将商品从购物车中删除、生成订单等操作。但是其实只有减去库存跟支付才是核心的业务逻辑,如果刚才说的操作都是同步调用,那么假设后面再来一个发送优惠券,或者给用户发个短信等需求,那商品支付的代码就越来越多,掺杂了一大堆跟他自己没关系的业务,而且请求响应也会变慢。所以这个时候我们就需要消息队列,好处有两点:
- 可以更快地返回结果;
- 减少等待,自然实现了步骤之间的并发,提升系统总体的性能。
解耦
还是刚才的例子,商品支付成功,减库存成功了,就可以给用户返回响应了。它只需要把用户下订单这个消息发送给消息队列,让购物车服务、订单服务、优惠券服务自己去订阅然后处理就行了。如果后面再来一个别的需求,也仅仅是去订阅这个事件,然后做自己的业务逻辑就好了,把商品服务与这一堆其他的服务解耦。这样不管需求怎么变,商品服务不需要做任何修改。
削峰
如果是在秒杀的情况下,秒杀的特性:在短时间内会有非常多的请求,那就有可能因为过多的请求压垮我们的系统。这种情况下也可以使用消息队列,隔离网关与后端服务,达到一个流量控制与保护后端服务的目的。
那流程就是:网关收到请求->放入消息队列->后端服务从消息队列取出请求,处理秒杀逻辑->返回结果,这样秒杀开始后,大量的请求会堆积在消息队列中,后端按照自己的能力来处理,而超时的请求则可以直接拒绝。
优点:
可以根据下游的处理能力自动调节流量,也就是所谓的“削峰填谷”
缺点:
因为加上了消息队列,多了系统调用的环节,总体响应时间可能会延长
上游下游变为异步调用,系统变复杂了。
当然流量控制还有其他的方法,比如可以加上限流策略,使用令牌桶算法或者漏桶算法。
你的项目在哪里用到了消息队列?
RocketMQ:
事务反查机制怎么实现的?
RocketMQ是怎么持久化的?
RocketMQ 在持久化的设计上,采取的是**「消息顺序写、随机读的策略」**,利用磁盘顺序写的速度,让磁盘的写速度不会成为系统的瓶颈。并且采用 MMPP 这种“零拷贝”技术,提高消息存盘和网络发送的速度。极力满足 RocketMQ 的高性能、高可靠要求。
消息数据刷盘
因为操作系统 PAGECACHE 的存在,PageCache是OS对文件的缓存,用于加速对文件的读写,所以一般都是先写入到 PAGECACHE 中,然后再持久化到磁盘上。我们熟悉的其他组件,MySQL、Redis 等都是如此。RocketMQ 也不列外。在 RocketMQ 中提供了**「同步刷盘」和「异步刷盘」两种刷盘方式,可以通过 Broker 配置文中中的 flushDiskType 参数来设置(SYNC_FLUSH、ASYNC_FLUSH)。「异步刷盘方式(默认)」:消息写入到内存的 PAGECACHE中,就立刻给客户端返回写操作成功,当 PAGECACHE 中的消息积累到一定的量时,触发一次写操作,将 PAGECACHE 中的消息写入到磁盘中。这种方式「吞吐量大,性能高,但是 PAGECACHE 中的数据可能丢失,不能保证数据绝对的安全」。「同步刷盘方式」:消息写入内存的 PAGECACHE 后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。这种方式「可以保证数据绝对安全,但是吞吐量不大」**
Kafka
Kafka概念介绍
Kafka 属于分布式的消息引擎系统。(摘自官网)
Kafka的核心概念?Kafka有哪些组件?
- 消息:Record。Kafka 是消息引擎嘛,这里的消息就是指 Kafka 处理的主要对象。
- Broker:Kafka 的服务器端由被称为 Broker 的服务进程构成,即一 个 Kafka 集群由多个 Broker 组成,Broker 负责接收和处理客户端发送过来的请求,以及 对消息进行持久化。
- 主题:Topic。主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
- 分区:Partition。一个有序不变的消息序列。每个主题下可以有多个分区。
- 消息位移:Offset。表示分区中每条消息的位置信息,是一个单调递增且不变的值。
- 副本:Replica。Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方 就是所谓的副本。副本还分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。
- 生产者:Producer。向主题发布新消息的应用程序。
- 消费者:Consumer。从主题订阅新消息的应用程序。
- 消费者位移:Consumer Offset。表征消费者消费进度,每个消费者都有自己的消费者 位移。
- 消费者组:Consumer Group。多个消费者实例共同组成的一个组,同时消费多个分区 以实现高吞吐。
- 重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配 订阅主题分区的过程。Rebalance 是 Kafka