第一次面头部大厂,担心的事情都发生了(记录字节一面)
在面字节之前,实话说我内心是比较紧张的。
之前听说过诸多传闻,比如字节喜欢拷打项目,一直不停深挖;还喜欢考算法。
我的担忧点主要有3个:1、会不会像之前一样被八股拷打?2、会不会一直深挖项目?(这俩项目实话说平时我也没有去深挖,按以往经验被问的深一点就答不上来了)3、字节算法会不会被拷打?(这点我特别担心,因为目前只面过5家公司,只有快手有考过算法,练习机会很有限,很久没刷算法了,很多解法都忘光了,也不知道题型是怎么样的,会出现什么可笑的问题,真的很未知,有点恐惧)。
省流:我的项目被面试官层层深挖,扒到连皮都不剩了。算法也没撕出来。
(写面经积攒一下人品,好心牛友们送朵花支持一下啦~)
————下面是原文,好奇的朋友们接着看————
就这么说吧,普通小厂的面试难度只有1颗星,基本上就是项目浅浅问一下。
然后中厂像得物和快手的难度勉强2颗星,八股文拷打+项目浅浅问一下+来道小算法。
头部大厂像字节的难度感觉直线飙升,3星难度,没有开胃八股文,一上来就是项目拷打,挑到一个点,深挖一个点,我多次给自己挖坑,直接被狠狠的栽进坑里,迎接我的只有不停的深挖和追问。
我说我不会,言外之意就是:面试官求放过。
结果面试官让我花点时间想一想,气氛沉默的那1分钟里我的脑海中一片空白,我把从出生到现在发生的所有事都想了一遍,唯独没想到问题的答案。
然后面试官继续深挖追问,直到我彻底被打趴下。
如何形容字节面试的呢?
借用麦克阿瑟的一句话就是:“我是真的在被拷打,每一分每一秒都是在煎熬。”
写算法用飞书的平台,我连引个包都不知道要引哪个包。
面试官给了道二叉树的题目,我还傻傻的问:“要不要自己定义数据结构?”
面试官当场亚麻呆住了(这个问题还需要问吗?)
我一看算法的题面很像二叉树的锯齿形层序遍历,我承认我的内心在那一瞬间闪过了欣喜,但后续的20分钟,带给我的只有深深的汗流浃背。。
面完什么感受?——透心凉。
(感兴趣的牛友们可以关注一下,6月份开始找实习,看看今年能否面穿各小中大厂,帮大家踩踩坑~)
————下面是我和面试官的比拼过程,好奇的朋友们接着看————
下面记录了我和面试官的“精彩”对话节选。
回合1:(轻松应对,完胜)
先让我自我介绍一下,突出讲之前学的内容和项目经历。
第一轮:完胜
回合2:(开始汗流浃背,惨败)
(挑了雪花算法,一个很小众的角度开始发问,之前从没被问过。。)
雪花算法是在什么场景下使用?
你觉得ID生成的算法需要满足哪些特点?(我提到有序递增)
那你说的雪花算法生成的结果满足有序递增,这个规律有什么坏处或好处?(坏处答道不安全)
那你觉得不安全的因素指的是什么呢?你可以举个例子吗?(答不出来,让我想想)
(提示)是不是会对用户的隐私构成问题(我答:单凭递增谈不上对隐私构成问题吧)
那你觉得除了隐私问题还会有什么问题?
(提示)你想想字段递增落到数据库上会有一些什么好处?
(提示)从索引的角度来看数据递增的好处是什么?(我答可以范围查询)
如果不是递增就不能范围查询吗?(我无言以对)
(提示)可以想一下数据库索引的特性,如果一张表有某个索引字段是递增的,跟没有递增的写入性能上会有什么区别?(我答如果非递增可能会导致索引位置的变动,插入效率低)
具体变动指的是什么呢?(此时已大脑空白,汗流浃背)
第二轮:惨败
回合3:(彻底汗流浃背,惨败)
(挑了12306开始追问,mmp)
你的核心表结构模型有哪些?有哪几张表是核心的?(我答了几张表)
我不是让你直接回答这个问题哦,我是想问你是如何思考的,去建这几张表?(我回答了一下业务的思路,对应要哪几张表)
为什么要把订单表和支付表分开?能不能合成一张表?你觉得哪个设计好?(我回答合在一起可能不满足第三范式,给自己挖了个坑)
你说的第三范式是什么意思?(我:。。)
订单模块和支付模块为什么要分开?理论上合在一起一致性是不是会更好一些?
(最后面试官提示:一个订单可以对应多个支付记录,一对多的关系,所以分开更好)
第三轮:惨败
回合4:(扳回一局,险胜)
我看你进行了分库分表,分库分表主要解决了什么问题?(我答:单表体积过大,查询插入删除效率降低)
这里的分片具体是怎么实现的?
订单表拆分的依据是什么?(我没听清楚是问订单,回答用户表依据用户名进行拆分,又给自己挖了个坑)
用户表需要分片吗?
用户名需要唯一性是吧,用户注册的时候用户名可能很容易重复,如何完成这个注册?(我答:可以预先分配给每个用户一个没有重名的用户名)
那你怎么保证你给用户分配的用户名没有重名?(大致回答了随机生成算法,感觉还不错,面试官同意了我的观点)
第四轮:险胜
回合5:(不相上下,惜败)
我看你项目封装了缓存的设计,这个是解决什么问题?(我答:解决缓存穿透。太久没复习了,忘了封装缓存的目的。。)
我看你已经分库分表了,为什么还要通过缓存来减轻数据库的访问压力?(我答:注册并发量会很大)
注册会有很大的并发吗?为什么?(我答可能会遭到黑客攻击)
那遭遇黑客攻击,难道缓存就不会崩溃吗?(我。。。)
难道中间件不会崩溃吗?假如每秒一百万请求下来,任何服务器都得崩溃吧?(我思路一转,答了我们系统在注册的时候会有限流和验证码机制,所以流量不会大到那么离谱,缓存或多或少可以减轻数据库压力,面试官赞同)
那有了验证码和限流机制还需要缓存吗?(我答:缓存或多或少能减少数据库的压力。我真想骂,你是来砸场子的吗?)
那你这个项目里的缓存是怎么设计的呢?(把提前准备好的答案说了一下)
为什么在布隆过滤器后面还需要一层缓存呢?(我答布隆过滤器数据无法删除,如果用户取消注册或者注册失败,用户名就无法再注册)
那布隆过滤器除了不能删除还有其它的缺点吗?(我答可能误判)
那布隆过滤器是怎么误判的呢?是会把有误判成无还是会把无误判成有(不得不说这个提问水平很高。我答了布隆过滤器底层的二维向量和随机索引结构,哈希冲突,面试官表示赞同)
第五轮:惜败
回合6:(汗流浃背,完败)
我看你项目里用到了一个Redis脚本,这个作用是什么?(保证优惠券不被超领)
你能说一下超领和这个Lua脚本之间的关系是什么?(保证检查库存和扣减库存的原子性)
如果使用Lua脚本时系统网络出现抖动,系统会引入一些超时和重试的机制,如果库存扣减这个操作发生了重试,如何保证幂等?简单来说如果一个人领了一次,接下来又发生了重试,怎么保证不会再被领一次?(我:。。。)
Lua脚本里面总体是由哪几个步骤组成的?(太久没复习了,只答了大概)
如果两个请求同时过来,去查询领取记录,两个线程可能都没查到领取记录,没有有可能扣减的时候变成扣减2份?这个问题如何解决呢?(我:。。。)
Lua脚本有什么限制吗?还是说想怎么用就可以怎么用?(我。。。)
(提示)Redis涉及到高并发的设计,需要一个集群去支撑,像Redis有很多集群模式你了解吗?(知识盲区。。)
第六轮:完败
回合7:(汗流浃背,完败)
操作系统里面进程间的通信的方式有哪些?(脱口而出:管道和消息队列)
管道有哪些特点跟限制?优缺点是什么?是不是所有的进程通讯都可以用管道去进行?(我:。。。)
你说可以用消息队列进行进程间通信,操作系统里面的消息队列大概是个什么概念?操作系统里的消息队列是啥?(我:。。。)
第七轮:完败
回合8:手撕代码(汗流浃背,惨败)
1、执行的效率有差别吗?
for(int i =0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]和a[j][i]
破题点:a[i][j]会把磁盘中连续的空间读取到内存中,加快访问的速度(侧面考察了操作系统:真够冷门)。
2、i++执行100次最终的结果会是100吗?
让我写一段代码,来模拟这个过程。。不会。。
3、之字形输出二叉树。
这其实是力扣二叉树的锯齿形层序遍历的变式题,z字形的方向和力扣那道是反向的。
撕了十多分钟脑袋抽抽了没撕出来。。
————下面是字节算法流程,好奇的朋友们接着看————
这里简单说一下算法题是怎么个流程:
字节使用的是飞书,然后面试官那边会选择题目,在我们这边会弹出一个方框。
方框的左边是题目,包含简单的题目描述(基本没有描述),然后会示例输出。
题目的描述基本没有(估计是怕通过题面来搜题),都是面试官口头描述,会问你读懂题意了吗。
测试的用例一般只有一个很简单的,只需要让代码的结果等于这个测试用例一般就可以了。
但是最好不要用一些很低级的暴力方法。
比如有些数组的题目其实暴力也可以解决,但如果只是用暴力没有优化基本这场面试就凉凉了。。
初始的代码很简单就下面这两句话(记得是):
import java.util.Scanner; public static void main(String[] args) { System..println("Hello World"); }
需要注意一下几点:
1、数据结构要自己定义:如果要做树或者链表的题目需要自己定义数据结构。
2、输入数据要自己模拟:题目的输入需要你自己模拟,比如构建一颗树,构造一个链表,构建一个数组。
3、写题目的过程中不要随意切换页面:如果你在写题目的过程中切换到其它界面,面试官那里是可以看到提示的,比如:对方已离开当前屏幕5秒之类的。
4、包要自己引入:一定要记得引入包,包括new以及Deque LinkedList ArrayDeque这些包都是要自己引入的,不然会报错。
5、可以选择在飞书的那个答题界面上作答代码,也可以选择分享本地的屏幕,然后在IDEA上进行作答。
6、你的任务就是:根据面试官描述题目的意思,写一个代码,能够成功输出示例中的输出结果。
————下面是个人总结————
总结一下:
1、平时做项目的时候没有对项目的一些点进行深挖,没有自己的思考,导致面试的时候很多都回答不上来。
2、平时记忆八股文的时候对于一些表述其实有点想当然了,没有去深挖更深一层的细节。
3、在算法上面,还有很多要练习的空间。