>  本文是鄙人薛某这位老哥的投稿，虽然面试最后挂了，但是老哥本身还是挺优秀的，而且通过这次面试学到了很多东西，我想这就足够了！加油！不要畏惧面试失败，好好修炼自己，多准备一下，后面一定会找到让自己满意的工作。
>

## 背景

前段时间家里出了点事，辞职回家待了一段时间，处理完老家的事情后就回到广州这边继续找工作，大概是国庆前几天我去面试了一家叫做Bigo(YY的子公司)，面试的职位是面向3-5年的Java开发，最终自己倒在了第三轮的技术面上。虽然有些遗憾和泄气，但想着还是写篇博客来记录一下自己的面试过程好了，也算是对广大程序员同胞们的分享，希望对你们以后的学习和面试能有所帮助。

## 个人情况

先说下LZ的个人情况。

17年毕业，二本，目前位于广州，是一个非常普通的Java开发程序员，算起来有两年多的开发经验。

其实这个阶段有点尴尬，高不成低不就，比初级程序员稍微好点，但也达不到高级的程度。加上现如今IT行业接近饱和，很多岗位都是要求至少3-5年以上开发经验，所以对于两年左右开发经验的需求其实是比较小的，这点在LZ找工作的过程中深有体会。最可悲的是，今年的大环境不好，很多公司不断的在裁员，更别说招人了，残酷的形势对于求职者来说更是雪上加霜，相信很多求职的同学也有所体会。所以，不到万不得已的情况下，建议不要裸辞！

## Bigo面试

面试岗位：Java后台开发

经验要求：3-5年

由于是国庆前去面试Bigo的，到现在也有一个多月的时间了，虽然仍有印象，但也有不少面试题忘了，所以我只能尽量按照自己的回忆来描述面试的过程，不明白之处还请见谅！

### 一面(微信电话面)

bigo的第一面是微信电话面试，本来是想直接电话面，但面试官说需要手写算法题，就改成微信电话面。

- 自我介绍
- 先了解一下Java基础吧，什么是内存泄漏和内存溢出？（溢出是指创建太多对象导致内存空间不足，泄漏是无用对象没有回收）
- JVM怎么判断对象是无用对象？（根搜索算法，从GC Root出发，对象没有引用，就判定为无用对象）
- 根搜索算法中的根节点可以是哪些对象？（类对象，虚拟机栈的对象，常量引用的对象）
- 重载和重写的区别？（重载发生在同个类，方法名相同，参数列表不同；重写是父子类之间的行为，方法名好参数列表都相同，方法体内的程序不同）
- 重写有什么限制没有？
- Java有哪些同步工具？（synchronized和Lock）
- 这两者有什么区别？
- ArrayList和LinkedList的区别？（ArrayList基于数组，搜索快，增删元素慢，LinkedList基于链表，增删快，搜索因为要遍历元素所以效率低）
- 这两种集合哪个比较占内存？（看情况的，ArrayList如果有扩容并且元素没占满数组的话，浪费的内存空间也是比较多的，但一般情况下，LinkedList占用的内存会相对多点，因为每个元素都包含了指向前后节点的指针）
- 说一下HashMap的底层结构（数组 + 链表，链表过长变成红黑树）
- HashMap为什么线程不安全，1.7版本之前HashMap有什么问题（扩容时多线程操作可能会导致链表成环的出现，然后调用get方法会死循环）
- 了解ConcurrentHashMap吗？说一下它为什么能线程安全（用了分段锁）
- 哪些方法需要锁住整个集合的？（读取size的时候）
- 看你简历写着你了解RPC啊，那你说下RPC的整个过程？（从客户端发起请求，到socket传输，然后服务端处理消息，以及怎么序列化之类的都大概讲了一下）
- 服务端获取客户端要调用的接口信息后，怎么找到对应的实现类的？(反射 + 注解吧，这里也不是很懂)
- dubbo的负载均衡有几种算法?（随机，轮询，最少活跃请求数，一致性hash）
- 你说的最少活跃数算法是怎么回事？（服务提供者有一个计数器，记录当前同时请求个数，值越小说明该服务器负载越小，路由器会优先选择该服务器）
- 服务端怎么知道客户端要调用的算法的？(socket传递消息过来的时候会把算法策略传递给服务端)
- 你用过redis做分布式锁是吧，你们是自己写的工具类吗？（不是，我们用redission做分布式锁）
- 线程拿到key后是怎么保证不死锁的呢？（给这个key加上一个过期时间）
- 如果这个过期时间到了，但是业务程序还没处理完，该怎么办？（额......可以在业务逻辑上保证幂等性吧）
- 那如果多个业务都用到分布式锁的话，每个业务都要保证幂等性了，有没有更好的方法？（额......思考了下暂时没有头绪，面试官就说那先跳过吧。事后我了解到redission本身是有个看门狗的监控线程的，如果检测到key被持有的话就会再次重置过期时间）
- 你那边有纸和笔吧，写一道算法，用两个栈模拟一个队列的入队和出队。（因为之前复习的时候对这道题有印象，写的时候也比较快，大概是用了五分钟，然后就拍成图片发给了面试官，对方看完后表示没问题就结束了面试。）

第一面问的不算难，问题也都是偏基础之类的，虽然答得不算完美，但过程还是比较顺利的。几天之后，Bigo的hr就邀请我去他们公司参加现场面试。

### 二面

到Bigo公司后，一位hr小姐姐招待我到了一个会议室，等了大概半个小时，一位中年男子走了进来，非常的客气，说不好意思让我等那么久了，并且介绍了自己是技术经理，然后就开始了我们的交谈。

- 依照惯例，让我简单做下自我介绍，这个过程他也在边看我的简历。
- 说下你最熟悉的项目吧。（我就拿我上家公司最近做的一个电商项目开始介绍，从简单的项目描述，到项目的主要功能，以及我主要负责的功能模块，吧啦吧啦..............）
- 你对这个项目这么熟悉，那你根据你的理解画一下你的项目架构图，还有说下你具体参与了哪部分。（这个题目还是比较麻烦的，毕竟我当时离职的时间也挺长了，对这个项目的架构也是有些模糊。当然，最后还是硬着头皮还是画了个大概，从前端开始访问，然后通过nginx网关层，最后到具体的服务等等，并且把自己参与的服务模块也标示了出来）
- 你的项目用到了Spring Cloud GateWay，既然你已经有nginx做网关了，为什么还要用gateWay呢？（nginx是做负载均衡，还有针对客户端的访问做网关用的，gateWay是接入业务层做的网关，而且还整合了熔断器Hystrix）
- 熔断器Hystrix最主要的作用是什么？（防止服务调用失败导致的服务雪崩，能降级）
- 你的项目用到了redis，你们的redis是怎么部署的？（额。。。。好像是哨兵模式部署的吧。）
- 说一下你对哨兵模式的理解？（我对哨兵模式了解的不多，就大概说了下Sentinel监控之类的，还有类似ping命令的心跳机制，以及怎么判断一个master是下线之类。。。。。）
- 那你们为什么要用哨兵模式呢？怎么不用集群的方式部署呢？一开始get不到他的点，就说哨兵本身就是多实例部署的，他解释了一下，说的是redis-cluster的部署方案。（额......redis的环境搭建有专门的运维人员部署的，应该是优先考虑高可用吧..........开始有点心慌了，因为我也不知道为什么）
- 哦，那你是觉得集群没有办法实现高可用吗？（不....不是啊，只是觉得哨兵模式可能比较保证主从复制安全性吧........我也不知道自己在说什么）
- 集群也是能保证高可用的，你知道它又是怎么保证主从一致性的吗？（好吧，这里真的不知道了，只能跳过）
- 你肯定有微信吧，如果让你来设计微信朋友圈的话，你会怎么设计它的属性成员呢？（嗯......需要有用户表，朋友圈的表，好友表之类的吧）
- 嗯，好，你也知道微信用户有接近10亿之多，那肯定要涉及到分库分表，如果是你的话，怎么设计分库分表呢？（这个问题考察的点比较大，我答的其实一般，而且这个过程面试官还不断的进行连环炮发问，导致这个话题说了有将近20分钟，限于篇幅，这里就不再详述了）
- 这边差不多了，最后你写一道算法吧，有一组未排序的整形数组，你设计一个算法，对数组的元素两两配对，然后输出最大的绝对值差和最小的绝对值差的"对数"。（听到这道题，我第一想法就是用HashMap来保存，key是两个元素的绝对值差，value是配对的数量，如果有相同的就加1，没有就赋值为1，然后最后对map做排序，输出最大和最小的value值，写完后面试官说结果虽然是正确的，但是不够效率，因为遍历的时间复杂度成了O(n^2)，然后提醒了我往排序这方面想。我灵机一动，可以先对数组做排序，然后首元素与第二个元素做绝对值差，记为num，然后首元素循环和后面的元素做计算，直到绝对值差不等于num位置，这样效率比起O(n^2)快多了。）

面试完后，技术官就问我有什么要问他的，我就针对这个岗位的职责和项目所用的技术栈做了询问，然后就让我先等下，等他去通知三面的技术官。说实话，二面给我的感觉是最舒服的，因为面试官很亲切，面试的过程一直积极的引导我，而且在职业规划方面给了我很多的建议，让我受益匪浅，虽然面试时间有一个半小时，但却丝毫不觉得长，整个面试过程聊得挺舒服的，不过因为时间比较久了，很多问题我也记不清了。

### 三面

二面结束后半个小时，三面的技术面试官就开始进来了，从他的额头发量分布情况就能猜想是个大牛，人狠话不多，坐下后也没让我做自我介绍，直接开问，整个过程我答的也不好，而且面试官的问题表述有些不太清晰，经常需要跟他重复确认清楚。

- 对事务了解吗？说一下事务的隔离级别有哪些（我以比较了解的Spring来说，把Spring的四种事务隔离级别都叙述了一遍）

- 你做过电商，那应该知道下单的时候需要减库存对吧，假设现在有两个服务A和B，分别操作订单和库存表，A保存订单后，调用B减库存的时候失败了，这个时候A也要回滚，这个事务要怎么设计？（B服务的减库存方法不抛异常，由调用方也就是A服务来抛异常）

- 了解过读写分离吗？（额。。。大概了解一点，就是写的时候进主库，读的时候读从库）

- 你说读的时候读从库，现在假设有一张表User做了读写分离，然后有个线程在**一个事务范围内**对User表先做了写的处理，然后又做了读的处理，这时候数据还没同步到从库，怎么保证读的时候能读到最新的数据呢？（听完顿时有点懵圈，一时间答不上来，后来面试官说想办法保证一个事务中读写都是同一个库才行）

- 你的项目里用到了rabbitmq，那你说下mq的消费端是怎么处理的？（就是消费端接收到消息之后，会先把消息存到数据库中，然后再从数据库中定时跑消息）

- 也就是说你的mq是先保存到数据库中，然后业务逻辑就是从mq中读取消息然后再处理的是吧？（是的）

- 那你的消息是唯一的吗？（是的，用了唯一约束）

- 你怎么保证消息一定能被消费？或者说怎么保证一定能存到数据库中？（这里开始慌了，因为mq接入那一块我只是看过部分逻辑，但没有亲自参与，凭着自己对mq的了解就答道，应该是靠rabbitmq的ack确认机制）

- 好，那你整理一下你的消费端的整个处理逻辑流程，然后说说你的ack是在哪里返回的（听到这里我的心凉了一截，mq接入这部分我确实没有参与，硬着头皮按照自己的理解画了一下流程，但其实漏洞百出）

- 按照你这样画的话，如果数据库突然宕机，你的消息该怎么确认已经接收？（额.....那发送消息的时候就存放消息可以吧.........回答的时候心里千万只草泥马路过........行了吧，没玩没了了。）

- 那如果发送端的服务是多台部署呢？你保存消息的时候数据库就一直报唯一性的错误？（好吧，你赢了。。。最后硬是憋出了一句，您说的是，这样设计确实不好。。。。）

- 算了，跳过吧，现在你来设计一个map，然后有两个线程对这个map进行操作，主线程高速增加和删除map的元素，然后有个异步线程定时去删除map中主线程5秒内没有删除的数据，你会怎么设计？

  （这道题我答得并不好，做了下简单的思考就说可以把map的key加上时间戳的标志，遍历的时候发现小于当前时间戳5秒前的元素就进行删除，面试官对这样的回答明显不太满意，说这样遍历会影响效率，ps：对这道题，大佬们如果有什么高见可以在评论区说下！）

......还有其他问题，但我只记住了这么多，就这样吧。

面完最后一道题后，面试官就表示这次面试过程结束了，让我回去等消息。听到这里，我知道基本上算是宣告结果了。回想起来，自己这一轮面试确实表现的很一般，加上时间拖得很长，从当天的2点半一直面试到6点多，精神上也尽显疲态。果然，几天之后，hr微信通知了我，说我第三轮技术面试没有通过，这一次面试以失败告终。

## 总结

以上就是面试的大概过程，不得不说，大厂的面试还是非常有技术水平的，这个过程中我学到了很多，这里分享下个人的一些心得：

1、**基础**！**基础**！**基础**！重要的事情说三遍，无论是什么阶段的程序员，基础都是最重要的。每个公司的面试一定会涉及到基础知识的提问，如果你的基础不扎实，往往第一面就可能被淘汰。

2、**简历需要适当的包装**。老实说，我的简历肯定是经过包装的，这也是我的工作年限不够，但却能获取Bigo面试机会的重要原因，所以适当的包装一下简历很有必要，不过切记一点，就是**不能脱离现实**，比如明明只有两年经验，却硬是写到三年。小厂还可能蒙混过关，但大厂基本很难，因为很多公司会在入职前做背景调查。

3、**要对简历上的技术点很熟悉**。简历包装可以，但一定要对简历上的技术点很熟悉，比如只是简单写过rabbitmq的demo的话，就不要写“熟悉”等字眼，因为很多的面试官会针对一个技能点问的很深入，像连环炮一样的深耕你对这个技能点的理解程度。

4、**简历上的项目要非常熟悉**。一般我们写简历都是需要对自己的项目做一定程序的包装和美化，项目写得好能给简历加很多分。但一定要对项目非常的熟悉，不熟悉的模块最好不要写上去。笔者这次就吃了大亏，我的简历上有个电商项目就写到了用rabbitmq处理下单，虽然稍微了解过那部分下单的处理逻辑，但由于没有亲自参与就没有做深入的了解，面试时在这一块内容上被Bigo三面的面试官逼得最后哑口无言。

5、**提升自己的架构思维**。对于初中级程序员来说，日常的工作就是基本的增删改查，把功能实现就完事了，这种思维不能说不好，只是想更上一层楼的话，业务时间需要提升下自己的架构思维能力，比如说如果让你接手一个项目的话，你会怎么考虑设计这个项目，从整体架构，到引入一些组件，再到设计具体的业务服务，这些都是设计一个项目必须要考虑的环节，对于提升我们的架构思维是一种很好的锻炼，这也是很多大厂面试高级程序员时的重要考察部分。

6、**不要裸辞**。这也是我最朴实的建议了，大环境不好，且行且珍惜吧，唉~~~~

总的来说，这次面试Bigo还是收获颇丰的，虽然有点遗憾，但也没什么后悔的，毕竟自己面试之前也是准备的很充分了，有些题目答得不好说明我还有很多技术盲区，不懂就是不懂，再这么吹也吹不出来。这也算是给我提了个醒，你还嫩着呢，好好修炼内功吧，毕竟菜可是原罪啊。