您的位置:首页 > Web前端

蚂蚁金服2019实习生面经总结(已拿口头offer)

2019-04-17 23:28 876 查看

一面 (37 分钟左右)

一面是上海的小哥打来的,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,又说到线程池,分别说了底层实现和项目中的应用。

面试官: 我觉得差不多了,那我再问个与技术无关的问题哈,虽然这个问题可能不应该我问,就是你是如何考虑你的项目架构的呢?

我: 先用最简单的方式实现它,再去发掘系统的问题和瓶颈,于是查资料改进架构。。。

面试官: 好,那我给你介绍下我这边的情况吧

总结: 一面可能是简历面吧,问的比较简单,我在讲项目中说出了我做项目时的学习历程和思考,赢得了面试官的好感,感觉他应该给我的评价很好。

二面 (33 分钟左右)

然而开心了没一会,内推人问我面的怎么样啊?看我流程已经到大大 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 并发编程的艺术里讲的都说出来了,说了得有十分钟,自夸一波,毕竟这本书我看了五遍

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: