意难平的滴滴支付一二三轮5年社招面经
前言
免责宣言,以下为博主朋友云雨雪于2023年底面试滴滴支付岗社招后端开发工程师岗位的真实经历,如有雷同,你是真的。本次延续上篇不一样面经系列的宗旨,不仅会介绍题目和题解,还会分析面试官为什么这么提问,最后结合云雨雪的个人体验来做一个面试总结。对了,以下我的好友云雨雪视角书写时可能会由于笔误不小心写成第一人称视角,请不要误会。
一面
问答
- 你说过有封装过一些组件,具体讲解下封装了什么,有什么用
- 组件里面应用最多的是哪些部分
- 你在组件中对于多线程是如何封装的
- JVM线上问题有没有遇到特别棘手的问题
- 聊一下订单交付这个项目,具体是干什么的
- 说一下重构前后的一个变化,重构的意义在哪,定时如何转实时
- Java类生命周期,类加载器有哪些,类加载机制有哪些,如何破除双亲委派
- JVM内存区域划分
- CMS和G1的相同点和不同点
- 什么时候进行FullGC,FullGC的回收范围
- MySQL的隔离级别,各自有什么特点和问题,MySQL默认是什么
- innodb如何解决可重复读的问题,innodb会出现幻读吗,幻读如何解决
- innodb有哪些索引结构,B+树和B树红黑树有什么优势
- 如何解决一个慢查询的SQL
- 数据库分片有了解过吗--没答出来
- 缓存有用过哪些
- 如何解决热点Key问题,缓存穿透、击穿、雪崩
- 布隆过滤器原理
- 算法题:字符串相加
- 算法题:动态口令
首先介绍下JD,据我模糊的印象是招聘的滴滴支付团队的Java后端,据三面面试官介绍,支付属于核心岗位(插播一下,云雨雪投另一个核心,也就是网约车部门,简历被拒了),内部细分为业务和技术中台两块,这个JD是面向业务的。上一篇面经有关于云雨雪的个人及工作经历介绍,这里不再赘述。
前三个问题是基于我的自我介绍提出的问题,SDK封装的经历算是我的一个加分项,面试官感兴趣就提问了,这里,注意,感兴趣的时候就奠定了一个良好的沟通氛围,印象分上来了。这里没有答案,属于个人独特经历不细说了。这里特别强调一下,一定要好好自我介绍,把简历上的亮点再强调一下,有时候你自我介绍太快,人面试官简历还没看完呢,咋问你,那不就尬住了嘛。
第四个也是常规必问了,我一般会简要提到我遇到的三种线上问题,OOM、CPU占用高和数据库线上违规操作。我一般会快速过一遍每种问题大致怎么解决,比如OOM我处理过堆内存溢出、元空间溢出和直接内存溢出,CPU占用率高用传统和工具两种解决方法,如何监控告警介绍下整个流程。这其实有点啰嗦,但是面试本质就是推销自己,尽可能地展示自己,多说点没坏处。我一般会在最后,视情况询问面试官想了解哪方面的,或者我会主动找一个元空间溢出或者直接内存溢出这样少见的案例进行讲解。
五和六就是必问的项目经历,推荐大家一定要找一个最有意义的项目挖掘一下,全程主导或者参与的最好。这里讲的是一个集合了大数据、重构和性能优化三个特性的项目,非常优质,偶尔我会聊聊别的项目,比如看板、门户和日志收集系统。在五年工作中我其实做了茫茫多的项目,很多很多的业务CRUD,但是说实话,铺到简历上真没啥说的,太简单了,所以写的时候我都进行了整合和忽略。也建议大家简历上少一些这种毫无意义和亮点的项目,除非是简历铺不满两页,需要凑版面。
- Java类生命周期,类加载器有哪些,类加载机制有哪些,如何破除双亲委派 类的生命周期分为加载-连接-初始化-使用-卸载,连接可细化为验证、加载、解析。 JVM提供了三种类加载机制,分别是全盘负责、缓存机制和双亲委派机制。
- 全盘负责的意思是,当前类加载器加载了某个类,那这个类依赖和引用的类默认都将由该加载器加载。
- 缓存机制则是缓存所有加载过的类,当程序需要某个类时先从缓存中找,找不到就加载类再放到缓存中。
- 双亲委派机制的意思是在加载某个类时,会向上寻找最顶端的父类先加载,如果加载不了再向下传递由子类加载。这样加载有一个好处,比如我乱写一个String类想要搞破坏顶掉JDK里的String,因为有双亲委派机制的原因,加载String类会优先从JDK里面找到加载。因此代码中只要不是我显式指定要用我自己的String类,那就是默认用JDK中的String类,不会造成混乱。 一是使用自定义类加载器,重写loadClass方法,二是使用Java的Instrumentation API,修改字节码逻辑。这类问题既然是基于框架的,那么最好的办法就是重写框架提供的接口或者使用SPI机制,类似的都可以这么回答。
- JVM内存区域划分 JVM内存结构用于描述运行时数据结构,主要区域划分为堆和栈,堆用来管理数据的存储、栈用来管理方法的运行。具体根据线程共享分为两类,线程私有的程序计数器、虚拟机栈、本地方法栈,线程共享的有堆、方法区。
- CMS和G1的相同点和不同点 相同点就是都是并发垃圾回收器,目的是尽量减小停顿时间。区别是CMS只用了标记清除算法,G1使用分代算法,混合使用。
- 什么时候进行FullGC,FullGC的回收范围 时机是三个节点,老年代、方法区空间不足和显式调用GC,回收范围是整个堆内存空间。
七八九十就是经典的JVM模块,在JAVA知识点中,JVM属于必问,其他例如基础、集合、多线程、JUC有几率问到。这里我知识体系构建系列有完整解答,这里重点提一下两个不常见问题的解答。如何破除双亲委派?什么时候进行FullGC,FullGC的回收范围?时机是三个节点,老年代、方法区空间不足和显式调用GC,回收范围是整个堆内存空间。
- MySQL的隔离级别,各自有什么特点和问题,MySQL默认是什么 默认可重复读。未提交读能读到未提交事务的数据,主要问题是脏读。已提交读,多次重复读可能读出不同的数据。可重复读会有幻读问题。串行话就是性能差,全加锁。
- innodb如何解决可重复读的问题,innodb会出现幻读吗,幻读如何解决 通过MVCC解决,默认隔离级别会出现幻读,解决的话通过快照读和加锁的当前读解决。
- innodb有哪些索引结构,B+树和B树红黑树有什么优势 B+树和HASH结构两种。相对B树,单内存页节点数更多,查询效率更稳定,相比红黑树层级不高,查询效率高。
- 如何解决一个慢查询的SQL 体系问题,详见之前写的如何挖掘项目亮点那篇文章
十一到十五是MySQL模块,这一块也是常问,这里问题都比较简单,常规八股。面试题的话,我真实回答不是这样的,限于篇幅,这里只是给一个答案的方向,具体答案可以从我的知识体系系列博客看。这里面试官问了我知不知道数据库分片,我反问了下是不是分库分表,他说不是,emmm,是不是滴滴有什么特别的东西,不太清楚这个。
- 缓存有用过哪些
- 如何解决热点Key问题,缓存穿透、击穿、雪崩 缓存穿透是指用户请求缓存和数据库不存在的数据,可以使用业务拦截、缓存空值和布隆过滤器三种方法,缓存击穿是缓存失效高并发读取,可以让缓存永不过期或者定时主动更新两种方法。缓存雪崩是大批量key到期或者redis挂了,可以设置不同的过期时间同时均分key到不同的redis节点,避免过热,redis挂了就是熔断降级,本地缓存。
- 布隆过滤器原理 布隆过滤器是由一个位数组和多个哈希函数构成。原理是判断数据通过多个哈希函数计算后,在位数组对应下标都为1时说明存在,否则不存在。因为多个不同的元素存储时会产生相同的索引,所以存在误判的情况。
字符串相加这个是leetcode原题,不要抖机灵强转数字相加字符串相加-leetcode官方题解。因为做得比较快,面试官需要熬到1小时,所以就又让我做了一道题,leetcode原题,动态口令。做题形式都是在leetcode官网做的,我登录了账号,然后通过滴滴会议软件投屏的。
感受
滴滴严格来说是面试的第三家大厂,此刻到了11月,有了一个月左右的面试经验,每周大概两三个面试,其实比较少,这还包括二面三面的。为啥不海投呢?在职确实没时间,特别是我10-11月天天加班到11点还通宵加班,周末也加班,属实没心力找面试。平心而论,错失了很多机会,从现在来看,当时的面试状态绝对是一个小巅峰,如果有机会应该多投几个一起面试。
话说回来,滴滴一面过程中我就感觉我能过了,因为回答的很好,我的知识面广度和深度相对来说还可以,所以聊起来就是谈天说地,喜笑颜开。整个面试给我感觉比较好,滴滴给我的感觉就像百度一样,很有技术范儿,一面协作同事面嘛,如果有这样的同事我感觉还挺安心的。这里针对面试感觉特别聊一下,虽然不是特别准,但是一般出现两种情况说明面试不通过的几率很高。首先是面试官全程盘问式的态度,或者很快进入了代码题阶段亦或者直接反问,有什么问题想问的,这种就说明面试官对你的感觉不好,你身上没有他感兴趣或者想了解的地方。
二面
问答
- 跑路理由
- 你在供应链业务是做什么的,项目内容啥样的,开发模式和流程咋样的
- 看你大数据方面做得多,简单介绍下为什么做大数据
- 为什么要用到TIDB,数据量如何
- TIDB如何部署的,节点如何分配
- 为什么用TIDB,与传统数据库优势在哪
- NoSQL很好扩容,那么TIDB是如何做到无缝扩容的
- 为什么不用MySQL+Redis,而是用TIDB?
- 缓存需要考虑数据一致性问题,TIDB如何保证数据一致性问题的---没回答出来
- 因为没答上上一个问题,我主动扯到了缓存数据库一致性问题---开始深挖,噩梦开始
- 缓存穿透问题,预热带来的问题
- 本地缓存和分布式缓存的实现思路有哪些,结构区别在哪--没有细聊
- 本地缓存应用场景,对比分布式有什么优点和缺点
- 本地缓存有哪些,怎么实现的,如果让你来设计一个本地缓存需要考虑哪些问题
- 本地缓存多节点更新时,如何考虑其他节点本地缓存的更新,guava里是如何做的--我这里答的自相矛盾
- 有没有哪些写得好的组件分享一下
- 面试官说他之前也写过日志收集这么一套东西,他觉得相对简单,就是配置一下,问了我的一个设计思路
- NIO、IO多路复用怎么玩的,epoll解决了什么问题
- Kafka的批处理是什么
- 代码题:多线程循环打印
- 如何保证一个系统的稳定性-事前事中事后,他在教我,说我缺少这方面的经验
一二三是对我过往的业务经历感兴趣,因为我快五年都在同一家公司,几乎每次二面或者三面都会问到我这个问题。因为大数据兼职的人比较少,很多人也会对大数据这块感兴趣,特别是TiDB,我发现真挺多公司在用。特别是用过的人,总会问我TiDB的东西,这里简要总结下,一个新技术或者中间件会怎么提问。选型理由,如何部署,和之前区别在哪,有什么好处和坏处,原理和架构设计。四五六简单回答一下TiDB的优点和缺点,优点自然是分布式架构天然支持大数据量、简单的命令提高了运维效率、同时自带的看板提高了可观测性。缺点自然是需要更强更多的硬件资源、小数据量下分布式网络开销的影响表现不如MySQL以及兼容性问题。
七是个好问题,涉及到了TiDB的原理。架构上TiDB分为四大组件,PD、TiDB、TiKV和TiFlash,TiDB是整个架构的中枢,负责执行、优化等SQL处理,PD负责元信息管理和集群的调度,TiKV和TiFlash都是存储组件。在存储中将数据分割成许多小的区块(Region),每个 Region 由多个副本(replica)组成,这些副本通过 Raft 协议保证数据的一致性和高可用性。扩容时,新节点可以接管一些现有 Region 的副本,从而分散负载。
八同样是个好问题,众所周知,越多的技术层级会带来越多稳定性上的问题,同时增加了代码的复杂度。
问题九难到我了,答了个乱七八糟,没说出来重点。事后总结一下,大致分为四点。一是内置分布式事务,多节点二阶段提交保证一致性。二是TiKV设计了分片和副本的概念,使用 Raft 协议来管理数据的复制和一致性。三是和MySQL类似的MVCC机制保证读写。四是TiDB有定时做一致性检查,有问题会触发数据修复机制。
如何保证数据库和缓存的数据一致性
如果数据量级很小,可以全量数据装载进缓存,定时刷入数据库,有一个缺陷是如果缓存宕机,数据库可能不是最新的数据。 通常对缓存的操作分为修改和删除两种,修改有两个问题,一是异常,修改数据库和缓存只要有一个出现异常,双方的值都会不一样,二是并发带来的修改丢失问题。删除可以避免修改异常带来的问题,但是也不能解决并发的问题,解决可以通过延时双删。通常会采用旁路缓存模式,也就是先更新数据库,再删除缓存,先删除缓存的话容易在并发时缓存写入旧值。后删除缓存同样会存在问题,在缓存刚好失效的情况下,读请求先于写请求读取数据库,此时写请求更新数据库,然后删除缓存,最后读请求写入旧缓存。但这种极端条件不容易满足,还不如考虑删除缓存失败的情况,删除失败可以考虑重试,重试最好异步可以走消息队列。 如果要保证强一致性,就要考虑分布式事务,比如2PC,3PC之类的一致性协议,但是性能降低了,为了保证性能,还是考虑最终一致性。
十到十五是针对缓存的提问,看来这块应该是面试官擅长或者感兴趣的地方,问的很多。缓存数据库一致性问题回答如上,缓存穿透场景,我提到了两个,业务拦截和预热。紧接着追问我预热会有什么问题,我说还需要定时更新保证不失效,后面还问了啥忘了。从这里的一些表现,面试官直接跟我说是不是缺少高并发的经验,我说是的,老哥戳着我肺管子了,哈哈。又问了本地缓存和分布式缓存,我介绍了我常用的Caffeine和Redis,简要介绍了下数据结构及原理,没有细问。接着问了本地缓存相比分布式的优劣势,优势自然是无网络开销和稳定性强,缺点显而易见,占堆内存。然后又问我本地缓存有哪些,我说了还用过GuavaCache,数据结构都是ConCurrentHashMap的变种配合不同的驱逐策略。让我自己设计的话,我回答了会从数据结构选择、线程安全、驱逐策略三方面考虑。
十五这里我没答出来,因为我懵了,本地缓存在我印象中就是没法多节点更新,事后查了也确实没有,我怀疑是不是我问题理解错了,应该是问我分布式缓存应该如何设计。这一块我相信读者也能感觉出来,这就是面试里会有的连环炮环节,面试官会根据知识点围攻型的提问,很多情况下已经脱离了常规的八股和场景题了,更多的是考验技术积累。所以我一直做的是去构建自己的知识体系,而不是背题,题是背不完的,Java这个生态太广了,连环炮一开总会挖到你够不着的地方,更不用说有些面试官自己也说不上,就是想看看你有没有金点子。这里简单提一个属于我的面试经验,如何去规避连环炮。在面对连环炮的开场基础问题时,我会随机应变根据问题的基础,自动去扩展问题的广度和深度,按照答案->原理->实战->扩展四步走完成一段较长的论述,通常这么一段下来就会有一种面试官说一句,我说几十句的效果。为什么这么做?一是完美地展示了自己知识范围内的广度和深度,避免连环炮问到不会的地方。二是压缩了面试官的提问时间,这也是很重要的,不一样面经第一篇就提到了,面试有时间限制,各个模块的考察也有时间限制,我占用了这部分时间,面试官如果没有意外就会认为这个模块及格,进入下一模块。
十六十七就是想要知道我觉得我自己写的组件里最满意的技术组件是啥,我说了日志收集,感兴趣可以翻一下我博客的第二篇,自己去搭一个。这一块就是闲聊,没怎么扩展,因为日志收集的思路我描述的很清楚,市面上流行的日志收集逻辑也差不多都一个套路,没啥说的。
十八十九就是我前面提到的,每个模块都得沾一下,要打分的。这里重点提一下,为什么问的这么简单?原因是这个时间,面试官对我印象非常好了,主动跟我说在翻我的博客看,觉得我基础很扎实,就随便问了俩博客看到的问题,确认下是不是我写的。
代码题就是多线程打印,这里粘一下之前的,题目不一样,但是逻辑和思路一样,不重新写了。
public static void main(String[] args) {
AtomicInteger ai = new AtomicInteger(1);
Semaphore a = new Semaphore(1);
Semaphore b = new Semaphore(0);
Semaphore c = new Semaphore(0);
try (ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100,
1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(100));) {
executor.submit(new Thread(() -> {
printNum(ai, a, b);
}));
executor.submit(new Thread(() -> {
printNum(ai, b, c);
}));
executor.submit(new Thread(() -> {
printNum(ai, c, a);
}));
}
}
private static void printNum(AtomicInteger ai, Semaphore cur, Semaphore next) {
while (ai.get() <= 100) {
try {
cur.acquire();
//必要--在多线程环境中,有可能一个线程已经通过了循环条件(ai.get() <= MAX_NUMBER)并且获取了信号量,而另一个线程(它已经在等待中)也通过了循环条件。如果没有额外的检查,两个线程可能在释放信号量之前都会打印超过上限的数字,导致输出不正确。
if (ai.get() <= 100) {
System.out.println(ai.getAndIncrement());
}
next.release();
} catch (InterruptedException e) {
throw new RuntimeException();
}
}
}
二十一其实是喂饭局,这个问题是他自问自答的,因为他说三面经理百分百会问,让我好好准备一下,教我大概怎么回答比较合适。
感受
其实面试到一多半的时��,我就感觉会过了,因为他提到在看我的博客,目前我的博客对于面试官的初见印象有着极强的拉升作用,只要看了,这场面试就会过。整个面试下来,回答了百分百的问题,正确率复盘大概是百分之九十,少有不会的也会靠知识体系的扩展去关联到我会的地方,实在不会的那就抱歉了,不会就是不会,学会了再来。代码题也是老搭档了,多线程我太熟练了,沟通上整体舒适,都很开心。最后给我透题真是活久见,感谢善良的面试官,虽然最后没过。这里提一下,滴滴都是第二天早上10-11点通知面试通过,哪怕是这个二面面试官明确告诉我等下一面通知,流程依旧是这样的。
三面
- 跳槽原因
- 有没有拿到别的Offer
- 介绍一下你公司的业务,规模如何,团队规模如何,开发的业务
- 介绍下你工作中的一个项目,从业务和架构两方面来讲
- 为什么之前定时计算花了一小时,拆解一下,订单量级如何
- 这个项目中最大的技术挑战是什么
- 如何保证Flink的高可用
- 数仓的数据量如何
- Flink有没有什么监控措施
- 聊一聊系统的高可用如何保证
- 有遇到什么特别棘手的线上问题吗
- 遇到事故之后怎么去做,分步骤
- 评价一下你四年的开发历程
- 讲一下你在工作中的优势和劣势
- 你的项目如何保证可用性
- 职业规划是什么
三面其实挺少问技术的,因为前两面该考察的都考察完毕了,但也不排除有的,看领导,大中公司我都遇到过三面考察技术的,一旦考察技术多少会做道题。常规来说,三面不会问技术,因为前两面的面试官的评分和面试表都会给到三面面试官,能到三面技术就没啥问题。我说这么多的意思就是,三面也别放松,还是有技术面的考察可能。 还是来通过问题分析一下面试官想要考察的点,首先是一二,常规问题,但是问你有没有别的offer,大概率是因为你的一二面评分较高,超过了其他候选人。
三到八都是对项目的业务和设计侧考察,核心目的是判断你对整个项目的熟悉情况,也就是这个项目是否真实,其二是通过这个项目去考察你对业务的熟练程度。为什么会考察业务?因为现在的岗位,大多还是业务岗,后面我也有面过技术中台的岗位,确实不太关注业务,考察业务的理解也就侧面能判断出你在接触新业务时的一个上手的速度。
九到十二其实都是围绕高可用保障这一点去聊,前面二面面试官提点过我的,所以这块准备充分,答得还行吧。
十三到十六就是比较宽泛的聊天局,差不多就会有这些问题,大家也可以提前准备一下。为啥会有这些看起来很广的题呢?其实换位思考,三面也就是经理级别,我们这种面试的小喽啰进去也不是人家的直接下属,人也就是面试的时候看一下你的简历,短时间也不能通过简历看出你的能力,所以会抛一个很宽的问题让我们回答。哪怕是你没有准备,你自己来说一个案例,也是你认为职业生涯中最好的东西,面试官就会基于这个点去深挖,找他想要从你身上了解的东西。三面我认为和一二面的面试策略不同,一二面你是被考察的人,三面是更需要你去展示自我的,所以口才一定要在及格以上。
三面隔天通知是过了,HR也很热情,告诉我准备下HRBP面试,我也很高兴,毕竟滴滴核心岗。我有朋友在滴滴,他跟我说滴滴开发氛围挺不错的,所以期待值拉满。三面其实也没啥好总结的,一般分为线下和线上,强制要求线下的话,一般要注意下可能会有技术考察、纸笔画流程图和设计图等情况发生。滴滴是我第一个三面通过的大厂,这时候其实已经开香槟了,毕竟谁也没想到现在面试什么骚操作都有。
HRBP
HRBP面试大多数情况下,可以理解为三面的缩略版,会偏生活侧一些,当然基于技术和业务的考察也有。问题很简单,这里就不赘述了,结果就是等了两天,HR告诉我结果待定,因为滴滴崩了,他们在着急解决问题,所以我也能理解。隔了一周告诉我,我的技术基础很好,但是没有高并发项目经历这点让老板很纠结,让我再等等。然后的然后,我也知道没戏了,没腆着脸再问了,毕竟再问就不礼貌了。
说实话,在HRBP面被卡我真是没想到的,都开好香槟了,给我收回去了,2023年魔幻的就业市场让我惊叹!当然后面的经历告诉我,2024年更是逆天,这里后面再说。
写在最后
说实话,从2023年底面试到2024年中,在面试过的岗位中,无论是有没有offer的,最喜欢的就是滴滴这个岗位,无论是平台还是工作方向都是上上之选,意难平是真的意难平,特别是倒在胜利前夜的感觉。颓靡了不到半周,又接着开始找了,没办法,现实是现实,无论是什么原因都改变不了结果。不过这次半成功的经历非常激励我,毕竟滴滴核心岗都能过三面,说明我的能力是被认可的,面试信心倍增。
不一样面经系列来到了第二篇,除了第一篇更多的描述感觉,后续的面积都会按照这个模板去写。为什么叫不一样面经呢?因为就像Java生态一样,太广了,面试题你是背不完的,所以比起授人以鱼,我习惯于授人以渔,用云雨雪面试的经验和感受告诉你,如何去面试,如何展示自己的才华。希望大家在这个寒冬中找到满意的工作,身体健康赚钱钱,我要让这痛苦压抑的世界绽放幸福快乐之花,向美好的世界献上祝福!!!
转载自:https://juejin.cn/post/7388635438741389321