【面经】三面拿下字节跳动后台开发实习岗Offer

一、写在前面

秉持分享的原则,先把我在面试准备过程中用到的非常有价值的资料贴在下面吧!

  • CS-Notes
  • 剑指Offer第二版及C++题解,百度云提取码:lpht
  • Java后台开发岗面试笔记
  • 简历模板

说明:资源链接中的『Java后台开发岗面试笔记』是我在牛客网面经评论栏找的,在我使用的过程中,做了一些微不足道的整理。如有侵权,请联系我删除。


疫情当前,最近几天北京更是首当其冲。博主在北京读研,不允许返校,也不许返京,在家待得满身铁锈,体重也渐长。心想,要不找个实习吧,push一下自己,还是忙碌的状态最踏实。由于博主家在四川,于是6月11号(周四)在字节跳动、腾讯、华为官网投了成都的后台研发岗位。不得不说,字节跳动效率是真的高,上午投的简历,下午就收到了HR的面试邀约。

HR:北京的岗位你考虑吗,可以远程实习。
我:原来可以远程实习呀,那可以啊。
HR:你最近什么时候有空面试呢?咱们约个时间吧!
我:最近都有空。
HR:要不约在下周一二吧,这样你可以多准备几天。
我:也行,那就下周一吧!

最后,面试时间约在了下周一(6.15)的下午四点。

面试时间一定,感觉自己立马来劲了。由于博主前些时间并没有专门准备面试,于是想着到牛客网刷一些面经,可能会事半功倍。

当天晚上十点多开始刷面经,刷完了几篇热门贴之后,心态变化过程是:问题不大——稳住!别慌——Excuse me???——这还面啥啊,洗洗睡吧!

那些面试题,在没准备的情况下,真的让人难以应对。平均每十道题,我大概能对其中一两道题回答上个大概,比如TCP三次/四次握手协议,因为以前学过计算机网络,知道些大概,但是协议具体工作过程、标志位之类的早就忘记了;还有堆排序,上次代码实现得追溯到三年前了…另外的一些知识点,比如数据库系统原理(事务隔离级别、联合索引最左匹配原则、数据库范式等)、Java虚拟机、设计模式,我甚至学都还没学过…

不过还好我没打退堂鼓,继续刷了一些面经,找到了别人整理得比较全面的面试知识点总结。12万字、146页的文档,全面得让人觉得可怕。

接下来的三天,真的是寝食难安,像极了曾经考期极限预习的场景。庆幸自己没跟HR商量第二天就面试,不然我得原地爆炸。

二、个人情况

博主本科就读于北京某985大学机械工程专业,大三时觉得本专业索然无味,遂自学计算机相关专业课程,然后通过考研转入了本校计算机学院。

目前研一,导师对我进行放养式管理,从来没有定期开组会的习惯,有任务安排的时候才会叫过去开个小会。

在实验室里干的活也很杂,研一上学期主要就是帮导师整理一些文献,搜一些资料,写一些充量的设计文档。个人的规划是毕业找一份后台开发相关的工作,所以在课程之余自学了一些Java后端方向的知识,比如JSP、Servlet、Maven、JDBC、MySQL、MyBatis、SpringBoot等。

寒假期间正式做了一个实验室的Online Judge项目,负责后台开发。两个月的时间,写出了一版,能使用,但也仅限于能用,用户体验较差。

由于一直无法返校,远程学习之余继续学习Java后台开发相关的技术和知识。强烈推荐GitHub上的一个叫 『CS-Notes』 的项目,对Java后台知识框架体系整理得特别完善。博主疫情期间主要学了些 CS-Notes 里面的数据库系统原理、MySQL、Java容器、Java并发等。

后面就是面试的故事了。

三、面试准备

面试准备方向主要有两个:基础知识和算法

1、基础知识

在突击准备过程中,博主基础知识复习和预习主要以 『Java后台开发岗面试笔记』为准,里面知识点覆盖得非常全面,如果能全部掌握,面试游刃有余。但是楼主只有三天半的准备时间,所以挑了些重点看了看,包括计算机网络、操作系统、集合框架、多线程并发、JVM、MySQL、数据库系统原理、Java基础知识、SpringBoot的一些配置注解等。其中计算机网络、操作系统、数据库系统原理 是重中之重。对于文档中说明不明确或自己不理解的地方,辅以 『CS-Notes』和搜索引擎进行学习。对于自己完全没学过的知识点,比如Redis、设计模式、Spring原理等,考虑到已经来不及速成,遂直接放弃。

文档过了一遍花了整整三天,但是看完后,也忘了不少,但总归有个印象。尽人事,知天命。

2、算法

博主去年暑假在 LeetCode 按序刷了50道左右的算法题,后面接近一年时间没碰算法。直到投简历前十多天,又在 LeetCode 上刷了《剑指Offer》前16道题目。博主写了Java题解:『CodingInterviewJava』。感兴趣的朋友给个star呗,嘿嘿!

面试前一天晚上和第二天抓紧看了剩下的《剑指Offer》,只看了思路,没有动手写代码。尽管如此,还是没有看完。

事实证明,《剑指Offer》是相当的靠谱,面试过程中遇到了好几道原题,比如单向链表的倒数第K个节点、快速排序、用两个堆栈构造一个队列。个人认为,认真刷完《剑指Offer》,面试过程中算法部分基本就没问题了。

四、字节跳动面试

博主是在牛客网平台进行视频面试的,下面是面试截图和一些面试官提问消息。

【面经】三面拿下字节跳动后台开发实习岗Offer_第1张图片
面试共三轮,前两轮技术面,第三轮HR面,三轮是连在一起的。由于前两轮面完后,HR当时比较忙,HR面就没有接着视频面试,而是稍后进行的电话面试。

技术面每轮大概会控制在50分钟,HR面20分钟左右。

面试过程中的聊天消息,主要是面试官的提问。当然里面不包括所有提问,有些面试官直接口头出题,不会给出文字信息:

在连接服务器…
15:43:44 系统: 您已连接到服务器
15:43:45 系统: 您已经进入792426号房间
15:54:57 系统: 面试官已经进入792426号房间
15:55:31 系统: 面试官已经离开792426号房间
15:55:32 系统: 面试官已经进入792426号房间
15:56:13 系统: 当前通话配置:低清模式 + 标准通道
16:00:44 对方: 一个长度为n的链表,找出倒数第K个节点
16:01:31 对方: 正整数
16:01:51 对方: 如果k超过n了就返回第一个节点
16:11:12 对方: 轮盘赌-概率输出奖品算法
16:11:34 对方: 输入:数组a, 如:a[4] = {5,2,2,1}
16:11:42 对方: 输出: 随机输出数组a的某一个下标
16:11:51 对方: 要求:输出下标的概率,为其值/总和
16:12:15 对方: 0:5/10 50%
16:12:40 对方: 1: 2/10 20%
16:12:47 对方: 2: 2/10 20%
16:13:36 对方: 3: 1/10 10%
16:22:30 对方: 两个栈实现一个队列
16:31:03 对方: TCP/IP的拥塞控制的含义是什么,有什么拥塞控制的方法
16:33:31 对方: TCP三次握手过程
16:35:58 对方: mysql索引,联合索引 a, b, c字段, 查询where c=1 and a=1, where b=1 and c= 1
16:41:24 对方: 查出一个网络监听端口为8888的服务进程,并kill掉
16:41:49 我: ps -ef | grep=8888
16:42:08 我: kill pid
16:51:59 系统: 面试官已经离开792426号房间
16:52:01 系统: 面试官已经进入792426号房间
16:52:01 系统: 面试官已经离开792426号房间
17:00:12 系统: 面试官已经进入792426号房间
17:00:27 系统: 当前通话配置:低清模式 + 标准通道
18:01:33 系统: 面试官已经离开792426号房间
18:09:10 系统: 面试官已经进入792426号房间
18:09:23 系统: 当前通话配置:低清模式 + 标准通道
18:09:50 系统: 面试官已经离开792426号房间

1、一面:普通技术面

第一面运气不错,面试官是校友,看着比我也年长不了几岁。学长人超级Nice,面试氛围相当轻松。

首先面试官自我介绍了一下,由于是校友,寒暄了几句,接着就是我自我介绍了。

1.1 算法题环节

算法题共有三道,依次是:

  1. 求链表的倒数第K个结点。
    注意,面试官并没有说K的取值范围,也没有说链表类型。所以大家在面试的过程中,动手前一定要问清楚题目的含义以及取值范围。比如这个题目中,并没有说链表是单向链表,虽然双方都知道肯定是单向链表,但是你得明面上说出来(面试官笑着说,不要在意这些细节哈哈哈);还有就是题中也没有说 K 的取值范围,是否能取负数和零,K 是否会超过链表的长度,这些都得提前和面试官约定好的。这样做的好处有二,其一是写代码过程中各种条件和边界都是确定的,其二是面试官会觉得求职者善于主动询问问题并且思维严谨。
  2. 轮盘赌-概率输出奖品算法
    这个算法在日常生活中非常常见,但我却从未思考过用代码怎么实现。面试过程中我思索了好半天,最后想出了一个时间复杂度和空间复杂度都很高的算法,就是用内存空间模拟轮盘,用随机次数循环遍历数组来模拟转转盘,而且这个算法思路还有bug,我就不详细说了。最后我还是没想出更好的思路,于是面试官提示了一下,立刻醍醐灌顶,直呼:“妙啊!”。具体算法思路我就不赘述了,大家搜索一下,就会有一大堆答案。总的来说,这道题是很简单的,要是见过,可直接秒杀。
  3. 用两个栈实现一个队列(要求实现队列的push和pop方法)
    这道题直接就是《剑指Offer》原题了,博主刷到过,所以很快就有了思路。

1.2 基础知识环节

关于基础知识,主要问了以下几个问题:

  1. TCP/IP的拥塞控制的含义是什么,有什么拥塞控制的方法?
  2. TCP三次握手过程,为什么不能使用两次握手?
  3. MySQL联合索引 a, b, c 字段,查询 where c=1 and a=1where b=1 and c= 1,命中情况是怎样的?
    备注:这个涉及到MySQL联合索引的最左匹配原则,大家着重复习一下。
  4. Linux命令:查出一个网络监听端口为 8888 的服务进程,并 kill 掉。
  5. 说一下数据库 ACID 的概念。
  6. 数据库有哪几种隔离级别?

除此之外,面试官问我学过Redis没,我说最近正在学,了解不多。于是就没接着问了。

1.3 项目提问环节

面试官看我简历上有一个Online Judge后台开发项目,于是让我介绍了一下项目,并没有深入问更多的东西。

1.4 提问环节

  1. 通过面试,你觉得我在哪些方面有明显缺陷需要提升或弥补吗?
    面试官对我一顿夸,说我面试表现挺好的,善于主动提问,给人的感觉就是很靠谱,很严谨。听得我很开心呀哈哈哈哈。

2、二面:Leader技术面

二面是一个看上去30来岁的Leader,没有很严厉的感觉。让我做自我介绍之后就直接进入正题了,虽然面试官言辞和善,但还是能明显感觉到压力升了一个Level。

2.1 算法题环节

首先进入的是算法题环节,面试官只出了一道题,原因是我在这道题上面思考了很长时间:

  • 给定有序数组,构建一颗平衡二叉搜索树。

说实话,当我看到平衡二叉树这几个字眼,我心就凉了半截。因为我在大三上学期(得追溯到2017年10月份)在MOOC上学过浙大翁凯和陈越教授主讲的数据结构,里面有讲过如何构建平衡二叉树。我还记得,在平衡二叉树插入节点的时候,需要检测二叉树是否满足平衡条件(任何节点的左右子树高度差不超过1),如果不平衡,需要进行旋转,好像有LL旋转、RR旋转、LR旋转、RL旋转之类的,当年用C语言实现的时候也是备受折磨。

想到此,我就已经做好放弃这道题的思想准备了,因为我知道我不可能当场写出旋转的代码的,早就忘得一干二净了。但我还是充满了求生欲地把自己并不完整而且无法实现的思路说了出来。

面试官:可以不用旋转实现吗?利用一下数组的有序性。

然后,陷入垂死挣扎中。几分钟过后,依然毫无思路。

面试官:根节点是哪一个?

继续挣扎…

我:可以以数组最中间的数作为根节点,但是这样会构建出一颗‘八’字的二叉树,但依然不平衡。(在线卑微求放过o(╥﹏╥)o)

面试官:可以划分为子问题吗?

内心OS,咦~子问题,有点耳熟。片刻之后恍然大悟,这不可以递归解决左右子树嘛!于是向面试官说了我的思路。

面试官:如何证明这样构建的二叉树是平衡的?

OS:啥玩意儿,需要这么严谨吗…

我:我有一个不太严谨的证明,使用二分递归解决,左右子树的节点数量差不会超过1,这样的话左右子树的高度差应该也不会超过1。

面试官:数的高度的是多少?

我:明白了,树的高度是 log ⁡ 2 N + 1 \log _{2} \mathrm{N} + 1 log2N+1,而左右子树节点数量差值最大为1,那么节点的左右子树高度差就不会超过1,而且由于是递归构建,那么每一个节点都满足平衡性。

最后就是代码实现了。实现的过程中,还是忘记了检查形参数组是否为空以及长度是否为0,经面试官提醒,又赶紧添上了。

说了这么多,想要表达的意思就是,如果遇到自己平日里没见过的算法题,并且一时半会没有明确的思路,面试的时候也要尽力分析,千万不要说不会,把自己所有的思路或想法都说出来,哪怕是不成熟甚至是错误的思路,面试官是会慢慢提醒和引导的。

2.2 基础知识环节

由于面试官都是口头提问,所以以下是仅凭记忆汇总的问题:

  1. 说一下虚拟内存,页面置换算法。
  2. 说一下快速排序和堆排序的算法思路,两者的时空复杂度,以及主要应用场景。
  3. 说一下进程内存空间。
  4. 进程间通信的方式有哪些?
  5. 在Linux中,kill 一个进程的背后发生了什么?

2.3 项目提问环节

面试官针对我最近做的一个Online Judge项目展开了提问:

  1. 怎么保持用户登录态的?

我:通过服务器端的 session 来保持的。
面试官:只用 session 就行了吗?
我:应该还需要用到客户端的 cookie
面试官:那 cookie 里面会保存什么呢?工作过程是怎样的?
我:不太清楚。
面试官:那你在项目里面是怎么实现的呢?
我:我代码写好之后,就能实现这个功能了。所以我也没仔细思考这里面的具体原理。
面试官:你是用的框架吗?
我:是的。
完~

  1. 我看你项目技术栈里面用到了 ActiveMQ ,那是什么,介绍一下?

2.4 提问环节

  1. 我本科并非计算机专业,半路出家,比别人少学几年,希望能快速弥补和提升,可以给我一些建议吗?
  2. 可以介绍一下公司使用的技术栈吗?
  3. 如果我有幸能通过面试,那么需要提前学习哪些知识和技术呢?

3、三面:HR面

三面电话面试,就轻松很多了。首先做了自我介绍(三轮面试自我介绍都说的差不多),然后聊了聊可实习时长,是否考虑转正,做项目过程中遇到的最大问题等等。

然后又是提问环节:

  1. 如果通过实习,在实习期间,我能接触到较为核心的业务吗?也就是说我能有多大程度的提升?
    导师制,能提升多少取决于你想要学多少。
  2. 薪资待遇如何?
    400¥/天,如果租房,会有房补(1500左右)。
  3. 工作时长如何?
    弹性工作制。
  4. 特殊时期实习形式?
    疫情期间在线远程实习,回到学校后需要到公司实习。

五、总结

认真刷完《剑指Offer》,面试算法题问题就不大。准备算法的过程中,最好分类学习:

  1. 数组
  2. 链表:单向链表和双向链表
  3. 栈和队列
  4. 二叉树:前、中、后、层序遍历的递归与非递归实现,二叉树的构建(比如根据前序遍历和中序遍历构建二叉树)
  5. 堆:大顶堆和小顶堆
  6. DFS:核心是递归
  7. BFS:核心是堆栈加循环
  8. 动态规划:核心是数列递推
  9. 排序算法:尤其是快速排序、堆排序和归并排序,要做到随手便可写出的程度,还有就是各自的时空复杂度分析

至于其他数据结构,例如图论,较为复杂,考到的概率较小。


看完并理解『Java后台开发岗面试笔记』和『CS-Notes』,面试过程中回答基础问题游刃有余。其中重点掌握计算机网络、操作系统、数据库系统原理、Java基础、Java容器(源码、底层数据结构)、Java并发、Java虚拟机、Linux、Redis


上面的都掌握了,Offer也就不远了。

祝大家面试顺利,拿到心仪的Offer!

你可能感兴趣的:(Interview,字节跳动,java,面试)