你说过有封装过一些组件,具体讲解下封装了什么,有什么用
组件里面应用最多的是哪些部分
你在组件中对于多线程是如何封装的
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这个生态太广了,连环炮一开总会挖到你够不着的地方,更不用说有些面试官自己也说不上,就是想看看你有没有金点子。这里简单提一个属于我的面试经验,如何去规避连环炮。在面对连环炮的开场基础问题时,我会随机应变根据问题的基础,自动去扩展问题的广度和深度,按照答案->原理->实战->扩展四步走完成一段较长的论述,通常这么一段下来就会有一种面试官说一句,我说几十句的效果。为什么这么做?一是完美地展示了自己知识范围内的广度和深度,避免连环炮问到不会的地方。二是压缩了面试官的提问时间,这也是很重要的,不一样面经第一篇就提到了,面试有时间限制,各个模块的考察也有时间限制,我占用了这部分时间,面试官如果没有意外就会认为这个模块及格,进入下一模块。
十六十七就是想要知道我觉得我自己写的组件里最满意的技术组件是啥,我说了日志收集,感兴趣可以翻一下我博客的第二篇,自己去搭一个。这一块就是闲聊,没怎么扩展,因为日志收集的思路我描述的很清楚,市面上流行的日志收集逻辑也差不多都一个套路,没啥说的。
十八十九就是我前面提到的,每个模块都得沾一下,要打分的。这里重点提一下,为什么问的这么简单?原因是这个时间,面试官对我印象非常好了,主动跟我说在翻我的博客看,觉得我基础很扎实,就随便问了俩博客看到的问题,确认下是不是我写的。
代码题就是多线程打印,这里粘一下之前的,题目不一样,但是逻辑和思路一样,不重新写了。