第一次面头部大厂,担心的事情都发生了(记录字节一面)

在面字节之前,实话说我内心是比较紧张的。

之前听说过诸多传闻,比如字节喜欢拷打项目,一直不停深挖;还喜欢考算法。

我的担忧点主要有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、在算法上面,还有很多要练习的空间。

全部评论
能有自己的思维和想法都不叫实习生了。那不就相当于全掌握全理解吗😰
36 回复 分享
发布于 2024-07-10 02:56 湖北
你就是吾浴西风,jvm弹幕一直刷屏那个
21 回复 分享
发布于 2024-07-10 07:47 江苏
我感觉你的反应才是正常反应啊,压力已经透过屏幕传过来了。 就不该打开评论区,怎么那么多牛人觉得难度一般啊,真就全是大佬呗。光是面经就看红温了,现在看了评论区更红了...
18 回复 分享
发布于 2024-07-16 15:44 海南
id递增是为了防止页分裂吧。 如果是随机id的话,要是一页刚好满了然后你的id正好落在了页中间的部分,就得分裂成两页。递增的话能保证每次都插在末尾,页满了的话直接插新页就行,避免了页分裂。 后面那个lua脚本的没太看懂,lua脚本不是保证原子性么,即便引发重试别的线程应该也要等当前线程重试完再跑吧
10 回复 分享
发布于 2024-07-09 21:34 江西
哈哈哈哈佬肯定没考408,否则操作系统的那个i,j遍历的区别的题一定会记忆犹新的
10 回复 分享
发布于 2024-07-10 11:19 安徽
我觉得这些知识很基础了,特别是缓存那里,缓存主要作用就是保证高并发,Redis的内存速度一定大于MySQL的磁盘速度。 可以从“为什么要这样设计”的角度去重新看一下项目。 至于算法,hot100先刷一遍吧。
5 回复 分享
发布于 2024-07-10 08:11 广东
那字节练手是真铁啊
4 回复 分享
发布于 2024-07-09 21:26 北京
说实话不难,感觉可能是你面少了,才面5场,经验不足,很多问题都是很基础的。还有项目,这项目一眼就知道是那个星球拿个offer的,我记得他那个星球有很多文档吧,基本解答的应该都很详细,只能说自己半桶水,感觉面试官已经很给面子了
4 回复 分享
发布于 2024-07-11 18:05 广东
有没有省流版本?
3 回复 分享
发布于 2024-07-10 09:53 浙江
“我把从出生到现在发生的所有事都想了一遍,唯独没想到问题的答案。” 名言!
3 回复 分享
发布于 2024-08-06 15:03 北京
铁铁,问一下,现在找实习,到时候秋招打算咋准备
2 回复 分享
发布于 2024-07-10 11:19 上海
i++执行100次最终的结果不是100吗?
2 回复 分享
发布于 2024-07-11 10:58 江苏
可以万能导包,import java.util.*
2 回复 分享
发布于 2024-07-24 20:51 北京
真的太恐怖了,我要去考公
1 回复 分享
发布于 2024-07-09 22:55 广东
绷,我项目一个字没问
1 回复 分享
发布于 2024-07-10 11:20 湖北
好文!
1 回复 分享
发布于 2024-07-10 14:46 浙江
布隆过滤器的二维向量可以说一下是什么吗,没有搜索到
1 回复 分享
发布于 2024-07-10 16:09 北京
大佬还是很强的
1 回复 分享
发布于 2024-07-10 21:09 广东
我今天也一面了,只问了项目,感觉问的比较简单,可能是我的项目比较水
1 回复 分享
发布于 2024-07-15 17:12 广东
哈人,佬面的啥部门啊😰
点赞 回复 分享
发布于 2024-07-09 21:23 江西

相关推荐

裸面,完全没准备,一些非常基础的八股也没答上来,自然被拒。emmm还是慢慢背吧。这里记录几个还有印象的问题1.Java的数据类型有哪些?应答:基本数据类型和引用数据类型。基本数据类型包括byte&nbsp;short&nbsp;int&nbsp;long&nbsp;float&nbsp;double&nbsp;char&nbsp;Boolean八种。引用数据类型包括类(class)、接口(interface)、数组(array)。2.讲一讲数据库的删除操作吧应答:delete、truncate、drop三种。delete属于dml操作语言,只删除数据不删除表的结构,会走事务,执行时会触发trigger。truncate属于ddl语言,删除表中所有数据,隐性提交,不能rollback。drop属于ddl语言,删除表和数据库都可以。3.讲讲你在项目里用的jwt令牌技术是如何生效的?应答:用户登录-认证通过-生成jwt&nbsp;token返回前端-前端发起请求时携带token-拦截器请求验证token-放行/不放行4.讲讲Java里的集合这个问的太宽泛了,我也答非所问,索性全部贴出来背了。应答:Java集合主要由Collection和Map派生出来的。前者派生List、Set、Queue。List代表有序可重复集合,可直接根据元素的索引来访问;Set代表无序不可重复集合,只能根据元素本身来访问;Queue是队列集合。Map代表的是存储key-value对的集合,可根据元素的key来访问value。List接口常用的实现类有:ArrayList、LinkedList、Vector。集合中的元素允许重复。集合中的元素是有顺序的,各元素插入的顺序就是各元素的顺序。集合中的元素可以通过索引来访问或者设置。ArrayList是一个动态数组,也是我们最常用的集合,是List类的典型实现。ArrayList擅长于随机访问,同时ArrayList是非同步的。与ArrayList相似,但是Vector是同步的,它的操作与ArrayList几乎一样。LinkedList是采用双向循环链表实现,LinkedList是List接口的另一个实现,除了可以根据索引访问集合元素外,LinkedList还实现了Deque接口,可以当作双端队列来使用,也就是说,既可以当作“栈”使用,又可以当作队列使用。1)ArrayList优点:&nbsp;底层数据结构是数组,查询快,增删慢。缺点:&nbsp;线程不安全,效率高2)Vector优点:&nbsp;底层数据结构是数组,查询快,增删慢。缺点:&nbsp;线程安全,效率低3)LinkedList优点:&nbsp;底层数据结构是链表,查询慢,增删快。缺点:&nbsp;线程不安全,效率高Set扩展Collection接口,无序集合,不允许存放重复的元素。Set接口常用的实现类有:HashSet、LinkedHashSet、TreeSet1)HashSet底层其实是包装了一个HashMap实现的底层数据结构是数组+链表&nbsp;+&nbsp;红黑树具有比较好的读取和查找性能,&nbsp;可以有null&nbsp;值通过equals和HashCode来判断两个元素是否相等非线程安全2)LinkedHashSet继承HashSet,本质是LinkedHashMap实现底层数据结构由哈希表(是一个元素为链表的数组)和双向链表组成。有序的,根据HashCode的值来决定元素的存储位置,同时使用一个链表来维护元素的插入顺序非线程安全,可以有null&nbsp;值3)TreeSet是一种排序的Set集合,实现了SortedSet接口,底层是用TreeMap实现的,本质上是一个红黑树原理排序分两种:自然排序(存储元素实现Comparable接口)和定制排序(创建TreeSet时,传递一个自己实现的Comparator对象)正常情况下不能有null值,可以重写Comparable接口&nbsp;局可以有null值了。队列是数据结构中比较重要的一种类型,它支持&nbsp;FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。PriorityQueue保存队列元素的顺序并不是按照加入的顺序,而是按照队列元素的大小进行排序的。PriorityQueue不允许插入null元素。Deque接口是Queue接口的子接口,它代表一个双端队列,当程序中需要使用“栈”这种数据结构时,推荐使用ArrayDeque。Map(这块内容真多byd)1.HashMapMap接口基于哈希表的实现,是使用频率最高的用于键值对处理的数据类型。它根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,特点是访问速度快,遍历顺序不确定,线程不安全,最多允许一个key为null,允许多个value为null。可以用&nbsp;Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap类。2.HashtableHashtable和HashMap从存储结构和实现来讲有很多相似之处,不同的是它承自Dictionary类,而且是线程安全的,另外Hashtable不允许key和value为null,并发性不如ConcurrentHashMap。3.LinkedHashMapLinkedHashMap继承了HashMap,是Map接口的哈希表和链接列表实现,它维护着一个双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序。4.TreeMapTreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。5.你项目中说是使用了Redis技术,讲讲Redis技术是怎么做到加速效果的此时已抠出三室一厅。应答:Redis&nbsp;是高性能的,基于键值对的,写入缓存的&nbsp;内存存储系统。它支持多种数据结构如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令。项目中引入&nbsp;Redis&nbsp;的地方是:查询店铺营业状态&nbsp;,像这种店铺营业状态,本项目无非就两个状态:营业中/打样。而且它属于高频查询。只要用户浏览到这个店铺,前端就要自动发送请求到后端查询店铺状态。Redis&nbsp;是基于键值对这种形式存储的,而且&nbsp;Redis&nbsp;也把将数据放到缓存中,而不是磁盘,有效缓解了这种高频查询给磁盘带来的压力。 6.讲讲spring中ioc容器应答:Spring&nbsp;IoC负责创建对象、管理对象(通过依赖注入(DI)、装配对象、配置对象,并且管理这些对象的整个生命周期。Ioc—Inversion&nbsp;of&nbsp;Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制,对于spring框架来说,就是由Spring来负责控制对象的生命周期和对象间的关系。到这里已经神志不清,面试官也问不下去了,遂结束。
查看6道真题和解析
点赞 评论 收藏
分享
评论
175
587
分享

创作者周榜

更多
牛客网
牛客企业服务