今天想聊聊我面试经历中最难忘的一次,那是我工作第三年的时候,去面试一家大厂的高级开发岗位,被面试官问到崩溃,从会议室出来的时候整个人都是懵的,甚至一度怀疑自己是不是不适合做程序员。
那次面试虽然失败了,但是给我的触动很大,让我意识到了自己的很多不足,也改变了我后来的学习和工作方式。今天写这篇文章,记录一下那次被问到崩溃的面试经历,以及后来的反思和成长,希望能给正在找工作或者准备面试的朋友一些启发。
一、面试前的准备
先说说那次面试的背景。
那时候我工作三年,在一家中小公司做后端开发,技术栈是PHP+MySQL,平时主要做业务开发,增删改查为主,也做过一些性能优化和架构调整。自我感觉还不错,觉得自己技术还可以,就想去大厂试试,看看能不能上个台阶。
投了简历之后,很快就收到了面试邀请,是一家大家都知道的大厂,岗位是高级后端开发。收到邀请的时候我还挺开心的,觉得自己的简历被认可了。
然后开始准备面试。那时候我准备面试的方式,就是刷面试题,在网上找了很多PHP面试题、MySQL面试题、Redis面试题,背了很多答案,比如PHP的垃圾回收机制、MySQL的索引原理、Redis的数据结构和持久化等。我觉得把这些题背熟了,面试应该就没问题了。
现在回想起来,那时候的准备方式太浅了,只是背了一些表面的知识点,没有深入理解原理,也没有结合实际项目经验,这也是后来面试被问崩的主要原因。
准备了大概一周,自我感觉良好,就去面试了。
二、一面:还比较顺利
一面是电话面试,面试官是一个工作五六年的开发,问的问题比较基础,我答得还可以。
问了PHP的一些基础,比如PHP的生命周期、垃圾回收机制、命名空间、自动加载等,这些我都背过,答得比较顺。然后问了MySQL的索引原理、事务隔离级别、锁机制,也答得差不多。还问了Redis的数据结构、持久化方式、缓存穿透和击穿的解决方案,我也都答上来了。
最后问了一个项目相关的问题,让我介绍一下我做过的最有挑战的项目。我介绍了之前做的一个秒杀系统,说了一下架构和遇到的问题,以及怎么解决的。面试官听了之后点了点头,没再追问。
一面大概40分钟,结束的时候面试官说我基础还可以,让我等二面通知。挂了电话我还挺开心的,觉得大厂面试也不过如此嘛,没想象中那么难。
现在想想,一面只是基础筛查,真正的考验在二面。
三、二面:开始有点吃力
二面是现场面试,到了公司之后,前台把我带到一个会议室,等了一会儿,面试官进来了,是一个看起来很资深的技术专家,后来才知道是某个团队的技术负责人。
面试官很客气,先让我做了个自我介绍,然后就开始问问题。
最开始问的还是技术基础,但是比一面深了很多。比如问MySQL索引,一面的时候只问了索引的原理,二面的时候就问得很细了:
"你说索引是B+树,那为什么用B+树而不是B树?B+树的叶子节点是链表,这个链表是双向还是单向?为什么?"
"聚簇索引和非聚簇索引的区别是什么?非聚簇索引为什么要回表?什么情况下不需要回表?覆盖索引的原理是什么?"
"联合索引的最左前缀原则是什么?为什么会有最左前缀?如果我建了一个(a,b,c)的联合索引,查询条件是where b=? and c=?,会不会用到索引?为什么?"
这些问题,我背过的面试题里有一些,但是有些没有,而且面试官会一直追问为什么,问到原理层面,我就有点答不上来了。比如最左前缀的原理,我只知道有这么个规则,但是不知道为什么会有,被问住了。
然后问了Redis,也是一样,问得很深:
"Redis的单线程为什么这么快?除了内存操作和IO多路复用,还有什么原因?"
"Redis的持久化,RDB和AOF的区别是什么?AOF的重写原理是什么?重写的时候会不会阻塞主线程?具体是怎么实现的?"
"Redis的集群方案,哨兵和Cluster的区别是什么?Cluster的分片原理是什么?数据是怎么分布的?如果新增一个节点,数据怎么迁移?"
这些问题,有些我能答上来,有些答得很模糊,尤其是深入到原理和实现细节的时候,我就卡壳了。面试官看我答不上来,也没为难我,就换了下一个问题,但是我已经开始有点慌了。
然后问了项目,这次问得很细,不是让我简单介绍一下就行了,而是一直追问细节:
"你说你做过秒杀系统,那这个秒杀系统的QPS能到多少?你是怎么测的?压测的时候瓶颈在哪里?你是怎么优化的?"
"你说你用了Redis做缓存,那缓存和数据库的数据一致性是怎么保证的?有没有出现过缓存和数据库不一致的情况?如果出现了,你是怎么解决的?"
"你说你做了分库分表,那是怎么分的?用的什么方案?跨库join是怎么解决的?分布式事务是怎么处理的?"
这些问题,我做项目的时候确实遇到过,但是很多都是用了现成的方案,没有深入思考过原理和细节,被面试官一追问,就答不上来了,只能说一些大概的思路,说不清楚具体的实现和细节。
二面大概一个小时,结束的时候我已经满头大汗了,感觉答得很不好,很多问题都没答上来。面试官说让我等通知,我知道大概率是没戏了。
但是没想到,我还是收到了三面的通知,后来才知道,二面的面试官觉得我虽然基础不够扎实,但是学习能力还可以,项目经验也有,就给了我三面的机会。
四、三面:彻底被问崩
三面是总监面,我以为总监面会问一些架构、管理、职业规划之类的问题,不会问太细的技术,结果完全不是我想的那样。
三面的面试官是一个技术总监,看起来很严肃,进来之后没怎么寒暄,直接就开始问问题,而且问的问题比二面更难,更深入。
最开始问了一个系统设计的问题:
"如果让你设计一个类似微博的系统,支持千万级用户,日活百万,你会怎么设计?从前端到后端,从数据库到缓存,从架构到部署,详细说说你的思路。"
这个问题太大了,我之前没有系统地思考过,只能想到什么说什么,说得很零散,没有条理。面试官听了之后,开始追问细节:
"你说用了微服务,那服务是怎么拆分的?拆分的依据是什么?服务之间是怎么通信的?用的RPC还是消息队列?为什么?"
"你说用了Redis做缓存,那缓存的架构是怎样的?是单机还是集群?用的什么分片方案?缓存的命中率是多少?如果缓存挂了怎么办?"
"你说数据库做了分库分表,那是按什么维度分的?用户ID还是时间?如果要查一个用户的所有微博,怎么查?如果要按时间排序查最新的微博,怎么查?"
"你说用了消息队列解耦,那消息队列是怎么选型的?用的Kafka还是RocketMQ?为什么?消息的可靠性是怎么保证的?有没有出现过消息丢失或者重复消费的情况?怎么处理的?"
这些问题,我很多都答不上来,因为我之前做的项目都是中小规模的,没有遇到过这么大的流量和这么复杂的场景,很多东西都是听说过,但是没有实际用过,更别说深入理解原理了。
面试官看我答得不好,又换了一个问题,问了一个算法题:
"给你一个很大的文件,里面有很多URL,每个URL一行,文件太大内存装不下,让你找出出现次数最多的前100个URL,你会怎么做?"
这个问题我有点印象,好像是用分治+哈希,但是具体怎么实现,细节我记不清了,只能说一个大概的思路,说不清楚具体的步骤和时间复杂度。面试官又追问了几个细节,我就完全答不上来了。
然后又问了一个计算机基础的问题:
"你平时用的是Linux,那你说说Linux的IO模型有哪几种?select、poll、epoll的区别是什么?epoll的水平触发和边缘触发的区别是什么?什么情况下用水平触发,什么情况下用边缘触发?"
这个问题,我只知道select、poll、epoll的大概区别,但是深入到原理和使用场景,我就答不上来了,尤其是水平触发和边缘触发,我一直没搞太清楚,被问住了。
接下来的问题,我基本都答不上来了,面试官问一个,我摇头说不会,再问一个,还是不会。到后来我已经完全懵了,脑子一片空白,甚至连之前会的问题都答不上来了。
面试官看我实在答不上来,就没再问技术问题了,问了我几个职业规划的问题,然后就结束了。
从会议室出来的时候,我整个人都是崩溃的,手心全是汗,腿都有点软。在公司楼下坐了半个小时才缓过来,那时候真的很挫败,觉得自己工作三年,什么都不会,甚至怀疑自己是不是不适合做程序员。
五、面试后的反思
那次面试之后,我消沉了好几天,觉得自己太菜了,什么都不会。但是消沉过后,我开始反思,为什么会被问崩?问题出在哪里?
我总结了几个原因:
1. 基础不扎实,知其然不知其所以然
我之前学技术,都是浅尝辄止,知道怎么用,但是不知道为什么这么用,背后的原理是什么。比如MySQL索引,我知道用B+树,但是不知道为什么用B+树,B+树的具体实现细节是什么。被面试官一追问为什么,就答不上来了。
2. 项目经验不够深入,没有思考过细节
我做项目,都是完成需求就行了,没有深入思考过为什么这么做,有没有更好的方案,遇到的问题有没有更深入的解决方案。比如做秒杀系统,我只知道用Redis缓存,但是没有深入思考过缓存和数据库的一致性怎么保证,缓存挂了怎么办,这些细节都没有想过。
3. 技术视野不够,没有接触过大规模的场景
我一直在中小公司,做的项目都是中小规模的,没有接触过千万级用户、百万日活的大规模场景,很多技术和方案都没有实际用过,只是听说过,所以被问到系统设计的时候,就答不上来了。
4. 学习方式不对,只是背面试题,没有真正理解
我准备面试的方式,就是背面试题,把答案背下来,但是没有真正理解,也没有结合实际经验。背的东西,面试官换个问法,或者追问一下,就答不上来了。
5. 计算机基础薄弱
计算机基础,比如操作系统、计算机网络、数据结构与算法,这些我都学得不扎实,很多东西都还给老师了。被问到IO模型、算法题的时候,就答不上来了。
反思清楚之后,我就开始制定学习计划,一点点补短板。
六、后来的改变和成长
那次面试虽然失败了,但是给我的触动很大,改变了我后来的学习和工作方式。
1. 深入学习技术原理,不再浅尝辄止
从那以后,我学技术不再满足于会用,而是要搞懂原理。比如学MySQL,我会去看B+树的具体实现,看索引的底层结构,看事务和锁的实现原理,看源码或者相关的书籍,真正搞懂为什么。
我买了很多技术书籍,比如《高性能MySQL》《Redis设计与实现》《深入理解计算机系统》《TCP/IP详解》等,一本一本地啃,把基础打扎实。
2. 做项目的时候多思考,多总结
做项目的时候,不再满足于完成需求,而是多思考,为什么这么做?有没有更好的方案?遇到的问题,深入研究,找到根本原因,而不是解决了就完事了。
我还开始写技术博客,把项目中遇到的问题和解决方案记录下来,整理成文章,这样既加深了理解,也方便以后回顾。
3. 拓宽技术视野,学习大规模系统的设计
我开始关注大规模系统的设计,看很多大厂的技术博客,学习他们的架构方案和最佳实践。比如淘宝、美团、字节跳动的技术博客,我都经常看,学习他们是怎么处理高并发、大数据量的场景的。
我还系统地学习了分布式系统的知识,比如分布式缓存、分布式消息队列、分库分表、微服务、容器化等,把这些技术的原理和使用场景都搞清楚。
4. 补计算机基础
我重新学习了计算机基础,操作系统、计算机网络、数据结构与算法,这些都重新捡起来了。每天抽时间刷算法题,从简单到困难,一点点提升算法能力。
虽然工作之后再学这些很辛苦,但是我知道这些基础很重要,是技术成长的根基,基础不牢,地动山摇。
5. 调整心态,接受自己的不足
最重要的是心态的改变。那次面试之后,我一度很自卑,觉得自己什么都不会。但是后来我想通了,被问崩不是坏事,至少让我知道了自己的不足在哪里,有了努力的方向。如果一直待在舒适区,觉得自己什么都会,反而不会进步。
我开始接受自己的不足,承认自己还有很多东西要学,然后一点点地补,一点点地进步。不再和别人比,只和昨天的自己比,只要今天比昨天进步了一点,就是好的。
七、现在的我
两年过去了,现在的我,已经不是当年那个被问崩的小伙子了。
我通过自己的努力,进了一家还不错的公司,做着自己喜欢的技术工作。技术上也有了很大的进步,基础扎实了,项目经验也丰富了,再去面试,不会像当年那样被问崩了。
但是我依然记得那次被问崩的经历,它时刻提醒我,技术这条路没有尽头,永远有学不完的东西,永远要保持谦虚,保持学习的心态。
我也很感谢那次面试,感谢那个把我问崩的面试官,如果不是那次面试,我可能还在舒适区里待着,觉得自己技术还可以,不会有后来的成长和进步。
八、给正在准备面试的朋友的建议
最后,给正在准备面试或者找工作的朋友一些建议,也是我从那次经历中总结出来的:
第一,不要只背面试题,要真正理解原理。面试题可以背,但是不能只背,要搞懂背后的原理,这样不管面试官怎么问,你都能答上来。
第二,基础很重要,一定要打扎实。操作系统、计算机网络、数据结构与算法,这些基础是技术的根基,不管做什么方向的开发,都要把基础打扎实。
第三,项目经验要深入,不要只停留在表面。做项目的时候,多思考,多总结,搞清楚每个细节,遇到的问题要深入研究,找到根本原因。面试的时候,项目细节是最能体现一个人能力的。
第四,拓宽技术视野,多学习大规模系统的设计。即使你现在的公司规模不大,也要多学习大厂的技术方案和架构设计,拓宽自己的技术视野,这样遇到系统设计的问题才不会慌。
第五,被问崩了不要怕,那是成长的机会。面试被问崩是很正常的,说明你遇到了比你厉害的人,发现了自己的不足。不要因此自卑或者放弃,把它当成成长的机会,回去补短板,下次会更好。
第六,保持学习的心态,技术这条路没有尽头。技术更新很快,永远有学不完的东西,要保持学习的心态,持续学习,持续进步。
九、写在最后
那次被面试官问到崩溃的经历,是我职业生涯中最难忘的经历之一。它让我看到了自己的不足,也让我找到了努力的方向,改变了我后来的职业发展。
现在回想起来,我很感谢那次经历,也很感谢那个把我问崩的面试官。如果不是那次面试,我可能还在原地踏步,不会有后来的成长。
如果你也在面试中被问崩过,不要灰心,不要气馁,那不是终点,而是新的起点。把它当成成长的机会,回去好好补短板,下次一定会更好。
技术这条路,没有谁是天生的大神,都是一步步踩坑、一步步成长起来的。被问崩不可怕,可怕的是被问崩之后还不反思,还不进步。
希望这篇文章能给正在找工作或者准备面试的朋友一些启发,也祝大家都能拿到自己心仪的offer。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录