本文来自 Anonymous 的投稿 ,JavaGuide 对原文进行了重新排版和一点完善。
一面是上海的小哥打来的,3.12 号中午确认的内推,下午就打来约时间了,也是唯一一个约时间的面试官。约的晚上八点。紧张的一比,人生第一次面试就献给了阿里。
幸运的是一面的小哥特温柔。好像是个海归?口语中夹杂着英文。废话不多说,上干货:
面试官: 先自我介绍下吧!
我: 巴拉巴拉...。
关于自我介绍:从 HR 面、技术面到高管面/部门主管面,面试官一般会让你先自我介绍一下,所以好好准备自己的自我介绍真的非常重要。网上一般建议的是准备好两份自我介绍:一份对 HR 说的,主要讲能突出自己的经历,会的编程技术一语带过;另一份对技术面试官说的,主要讲自己会的技术细节,项目经验,经历那些就一语带过。
面试官: 我看你简历上写你做了个秒杀系统?我们就从这个项目开始吧,先介绍下你的项目。
关于项目介绍:如果有项目的话,技术面试第一步,面试官一般都是让你自己介绍一下你的项目。你可以从下面几个方向来考虑:
- 对项目整体设计的一个感受(面试官可能会让你画系统的架构图)
- 在这个项目中你负责了什么、做了什么、担任了什么角色
- 从这个项目中你学会了那些东西,使用到了那些技术,学会了那些新技术的使用
- 另外项目描述中,最好可以体现自己的综合素质,比如你是如何协调项目组成员协同开发的或者在遇到某一个棘手的问题的时候你是如何解决的又或者说你在这个项目用了什么技术实现了什么功能比如:用 redis 做缓存提高访问速度和并发量、使用消息队列削峰和降流等等。
我: 我说了我是如何考虑它的需求(秒杀地址隐藏,记录订单,减库存),一开始简单的用 synchronized 锁住方法,出现了问题,后来乐观锁改进,又有瓶颈,再上缓存,出现了缓存雪崩,于是缓存预热,错开缓存失效时间。最后,发现先记录订单再减库存会减少行级锁等待时间。
一面面试官很耐心地听,并给了我一些指导,问了我乐观锁是怎么实现的,我说是基于 sql 语句,在减库存操作的 where 条件里加剩余库存数>0,他说这应该不算是一种乐观锁,应该先查库存,在减库存的时候判断当前库存是否与读到的库存一样(可这样不是多一次查询操作吗?不是很理解,不过我没有反驳,只是说理解您的意思。事实证明千万别怼面试官,即使你觉得他说的不对)
面试官: 我缓存雪崩什么情况下会发生?如何避免?
我: 当多个商品缓存同时失效时会雪崩,导致大量查询数据库。还有就是秒杀刚开始的时候缓存里没有数据。解决方案:缓存预热,错开缓存失效时间
面试官: 问我更新数据库的同时为什么不马上更新缓存,而是删除缓存?
我: 因为考虑到更新数据库后更新缓存可能会因为多线程下导致写入脏数据(比如线程 A 先更新数据库成功,接下来要取更新缓存,接着线程 B 更新数据库,但 B 又更新了缓存,接着 B 的时间片用完了,线程 A 更新了缓存)
逼逼了将近 30 分钟,面试官居然用周杰伦的语气对我说:
我突然受宠若惊,连忙说谢谢,也正是因为第一次面试得到了面试官的肯定,才让我信心大增,二三面稳定发挥。
面试官又曰: 我看你还懂数据库是吧,答:略懂略懂。。。那我问个简单的吧!
我: 因为这个问题太简单了,所以我忘记它是什么了。
面试官: 你还会啥数据库知识?
我: 我一听,问的这么随意的吗。。。都让我选题了,我就说我了解索引,慢查询优化,巴拉巴拉
面试官: 等等,你说索引是吧,那你能说下索引的存储数据结构吗?
我: 我心想这简单啊,我就说 B+树,还说了为什么用 B+树
面试官: 你简历上写的这个 J.U.C 包是什么啊?(他居然不知道 JUC)
我: 就是 java 多线程的那个包啊。。。
面试官: 那你都了解里面的哪些东西呢?
我: 哈哈哈!这可是我的强项,从 ConcurrentHashMap,ConcurrentLinkedQueue 说到 CountDownLatch,CyclicBarrier,又说到线程池,分别说了底层实现和项目中的应用。
面试官: 我觉得差不多了,那我再问个与技术无关的问题哈,虽然这个问题可能不应该我问,就是你是如何考虑你的项目架构的呢?
我: 先用最简单的方式实现它,再去发掘系统的问题和瓶颈,于是查资料改进架构。。。
面试官: 好,那我给你介绍下我这边的情况吧
总结: 一面可能是简历面吧,问的比较简单,我在讲项目中说出了我做项目时的学习历程和思考,赢得了面试官的好感,感觉他应该给我的评价很好。
然而开心了没一会,内推人问我面的怎么样啊?看我流程已经到大大 boss 那了。我一听二面不是主管吗???怎么直接跳了一面。于是瞬间慌了,赶紧(下床)学习准备二面。
隔了一天,3.14 的早上 10:56 分,杭州的大大 boss 给我打来了电话,卧槽我当时在上毛概课,万恶的毛概课每节课都点名,我还在最后一排不敢跑出去。于是接起电话来怂怂地说不好意思我在上课,晚上可以面试吗?大大 boss 看来很忙啊,跟我说晚上没时间啊,再说吧!
于是又隔了一天,3.16 中午我收到了北京的电话,当时心里小失望,我的大大 boss 呢???接起电话来,就是一番狂轰乱炸。。。
第一步还是先自我介绍,这个就不多说了,提前准备好要说的重点就没问题!
面试官: 我们还是从你的项目开始吧,说说你的秒杀系统。
我: 一面时的套路。。。我考虑到秒杀地址在开始前不应暴露给用户。。。
面试官: 等下啊,为什么要这样呢?暴露给用户会怎么样?
我: 用户提前知道秒杀地址就可以写脚本来抢购了,这样不公平
面试官: 那比如说啊,我现在是个黑客,我在秒杀开始时写好了脚本,运行一万个线程获取秒杀地址,这样是不是也不公平呢?
我: 我考虑到了这方面,于是我自己写了个 LRU 缓存(划重点,这么多好用的缓存我为啥不用偏要自己写?就是为了让面试官上钩问我是怎么写的,这样我就可以逼逼准备好的内容了!),用这个缓存存储请求的 ip 和用户名,一个 ip 和用户名只能同时透过 3 个请求。
面试官: 那我可不可以创建一个 ip 代理池和很多用户来抢购呢?假设我有很多手机号的账户。
我: 这就是在为难我胖虎啊,我说这种情况跟真实用户操作太像了。。。我没法区别,不过我觉得可以通过地理位置信息或者机器学习算法来做吧。。。
面试官: 好的这个问题就到这吧,你接着说
我: 我把生成订单和减库存两条 sql 语句放在一个事务里,都操作成功了则认为秒杀成功。
面试官: 等等,你这个订单表和商品库存表是在一个数据库的吧,那如果在不同的数据库中呢?
我: 这面试官好变态啊,我只是个本科生?!?!我觉得应该要用分布式锁来实现吧。。。
面试官: 有没有更轻量级的做法?
我: 不知道了。后来查资料发现可以用消息队列来实现。使用消息队列主要能带来两个好处:(1) 通过异步处理提高系统性能(削峰、减少响应所需时间);(2) 降低系统耦合性。关于消息队列的更多内容可以查看这篇文章:https://snailclimb.gitee.io/javaguide/#/./system-design/data-communication/message-queue
后来发现消息队列作用好大,于是现在在学手写一个消息队列。
面试官: 好的你接着说项目吧。
我: 我考虑到了缓存雪崩问题,于是。。。
面试官: 等等,你有没有考虑到一种情况,假如说你的缓存刚刚失效,大量流量就来查缓存,你的数据库会不会炸?
我: 我不知道数据库会不会炸,反正我快炸了。当时说没考虑这么高的并发量,后来发现也是可以用消息队列来解决,对流量削峰填谷。
面试官: 好项目聊(怼)完了,我们来说说别的,操作系统了解吧,你能说说 NIO 吗?
我: NIO 是。。。
面试官: 那你知道 NIO 的系统调用有哪些吗,具体是怎么实现的?
我: 当时复习 NIO 的时候就知道是咋回事,不知道咋实现。最近在补这方面的知识,可见 NIO 还是很重要的!
面试官: 说说进程切换时操作系统都会发生什么?
我: 不如杀了我,我最讨厌操作系统了。简单说了下,可能不对,需要答案自行百度。
面试官: 说说线程池?
答: 卧槽这我熟啊,把 Java 并发编程的艺术里讲的都说出来了,说了得有十分钟,自夸一波,毕竟这本书我看了五遍😂
面试官: 好问问计网吧如果设计一个聊天系统,应该用 TCP 还是 UDP?为什么
我: 当然是 TCP!原因如下:
面试官: 好的,你有什么要问我的吗?
我: 我还有下一次面试吗?
面试官: 应该。应该有的,一周内吧。还告诉我居然转正前要实习三个月?wtf,一个大三满课的本科生让我如何在八月底前实习三个月?
我: 面试官再见
3.18 号,三面来了,这次又是那个大大 boss!
第一步还是先自我介绍,这个就不多说了,提前准备好要说的重点就没问题!
面试官: 聊聊你的项目?
我: 经过二面的教训,我迅速学习了一下分布式的理论知识,并应用到了我的项目(吹牛逼)中。
面试官: 看你用到了 Spring 的事务机制,你能说下 Spring 的事务传播吗?
我: 完了这个问题好像没准备,虽然之前刷知乎看到过。。。我就只说出来一条,面试官说其实这个有很多机制的,比如事务嵌套,内事务回滚外事务回滚都会有不同情况,你可以回去看看。
面试官: 说说你的分布式事务解决方案?
我: 我叭叭的照着资料查到的解决方案说了一通,面试官怎么好像没大听懂???
阿里巴巴之前开源了一个分布式 Fescar(一种易于使用,高性能,基于 Java 的开源分布式事务解决方案),后来,Ant Financial 加入 Fescar,使其成为一个更加中立和开放的分布式交易社区,Fescar 重命名为 Seata。Github 地址:https://github.com/seata/seata
面试官: 好,我们聊聊其他项目,说说你这个 MapReduce 项目?MapReduce 原理了解过吗?
我: 我叭叭地说了一通,面试官好像觉得这个项目太简单了。要不是没项目,我会把我的实验写上吗???
面试官: 你这个手写 BP 神经网络是干了啥?
我: 这是我选修机器学习课程时的一个作业,我又对它进行了扩展。
面试官: 你能说说为什么调整权值时要沿着梯度下降的方向?
我: 老大,你太厉害了,怎么什么都懂。我压根没准备这个项目。。。没想到会问,做过去好几个月了,加上当时一紧张就忘了,后来想起来大概是....。
面试官: 好我们问问基础知识吧,说说什么叫 xisuo?
我:???xisuo,您说什么,不好意思我没听清。(这面试官有点口音。。。)就是 xisuo 啊!xisuo 你不知道吗?。。。尴尬了十几秒后我终于意识到,他在说死锁!!!
面试官: 假如 A 账户给 B 账户转钱,会发生 xisuo 吗?能具体说说吗?
我: 当时答的不好,后来发现面试官又是想问分布式,具体答案参考这个:https://blog.csdn.net/taylorchan2016/article/details/51039362
面试官: 为什么不考研?
我: 不喜欢学术氛围,巴拉巴拉。
面试官: 你有什么问题吗?
我: 我还有下一面吗。。。面试官说让我等,一周内答复。
等了十天,一度以为我凉了,内推人说我流程到 HR 了,让我等着吧可能 HR 太忙了,3.28 号 HR 打来了电话,当时在教室,我直接飞了出去。
面试官: 你好啊,先自我介绍下吧
我: 巴拉巴拉....HR 面的技术面试和技术面的还是有所区别的!
面试官人特别好,一听就是很会说话的小姐姐!说我这里给你悄悄透露下,你的评级是 A 哦!
接下来就是几个经典 HR 面挂人的问题,什么难给我来什么,我看别人的 HR 面怎么都是聊聊天。。。
面试官: 你为什么选择支付宝呢,你怎么看待支付宝?
我: 我从个人情怀,公司理念,环境氛围,市场价值,趋势导向分析了一波(说白了就是疯狂夸支付宝,不过说实话我说的那些一点都没撒谎,阿里确实做到了。比如我举了个雷军和格力打赌 5 年 2000 亿销售额,大部分企业家关注的是利益,而马云更关注的是真的为人类为世界做一些事情,利益不是第一位的。)
面试官: 明白了解,那你的优点我们都很明了了,你能说说你的缺点吗?
缺点肯定不能是目标岗位需要的关键能力!!!
总之,记住一点,面试官问你这个问题的话,你可以说一些不影响你这个职位工作需要的一些缺点。比如你面试后端工程师,面试官问你的缺点是什么的话,你可以这样说:自己比较内向,平时不太爱与人交流,但是考虑到以后可能要和客户沟通,自己正在努力改。
我: 据说这是 HR 面最难的一个问题。。。我当时翻了好几天的知乎才找到一个合适的,也符合我的答案:我有时候会表现的不太自信,比如阿里的内推二月份就开始了,其实我当时已经复习了很久了,但是老是觉得自己还不行,不敢投简历,于是又把书看了一遍才投的,当时也是舍友怂恿一波才投的,面了之后发现其实自己也没有很差。(划重点,一定要把自己的缺点圆回来)。
面试官: HR 好像不太满意我的答案,继续问我还有缺点吗?
我: 我说比较容易紧张吧,举了自己大一面实验室因为紧张没进去的例子,后来不断调整心态,现在已经好很多了。
接下来又是个好难的问题。
面试官: BAT 都给你 offer 了,你怎么选?
其实我当时好想说,BT 是什么?不好意思我只知道阿里。
我 : 哈哈哈哈开玩笑,就说了阿里的文化,支付宝给我们带来很多便利,想加入支付宝为人类做贡献!
最后 HR 问了我实习时间,现在大几之类的问题,说肯定会给我发 offer 的,让我等着就好了,希望过两天能收到好的结果。