全部写的是技术面试,hr面就没写了
1.字节跳动
字节面试提前和内推人沟通好了,给安排6.23下午2点到5点面完技术面
1.1一面(60分钟)
面试时间:6.:00-15:00
1.自我介绍这一部分提前要准备好,主要是讲自己擅长什么技术,负责过哪些项目,抓住重点,什么平时的兴趣爱好就不要说了,面试官不会care的
2.用过哪些Java容器
3.ArrayList和LinkedList特点及各自应用场景
4.说下TreeMap和LinkedHashMap
5.TreeMap怎么按照自己想要的顺序排序
6.说下HashMap
7.ConcurrentHashMap怎么实现的,1.7和1.8分别说下
8.ConcurrentHashMap怎么取的size值
9.一个非常多元素的HashMap,rehash非常耗时,所以需要在它rehash过程中还能get、put,你有什么解决方案或者思路,谈谈你的理解这题我一开始没了解面试官说的什么意思,然后扯了很多相关的东西,比如:针对大容量,带参初始化,避免频繁扩容ConcurrentHashMap是fail-safe容器,遍历时会在副本上遍历,后续的写操作对当前遍历不可见
然后面试官又说那这个数据量特别大,rehash很耗时怎么办,还在rehash后面的get、put怎么办呢?我说可以借鉴Redis的渐进式hash,hash操作分摊开
然后面试官说正在rehash,这时get元素怎么取值、put元素怎么插入?我说在ConcurrentHashMap中当另一个线程put元素时,发现当前状态为扩容时会协助其扩容,这样提高性能
面试官说你不一定要去想已有的实现,可以自己想想有什么方案我说由于正在rehash,比如正在从16扩容到32,那么对输入key进行两次hash,分别定位扩容前和扩容后的table索引位置,然后再在链表上遍历
10.怎么防止恶意请求刷接口
11.说下ES的倒排索引
12.那ES怎么切词的呢,有写过切词插件吗
13.你在项目中用Redis的场景
14.说下Redis有哪些数据类型
15.说说你在项目中怎么用的这些数据类型
16.一次请求拿出来所有的数据有什么问题,那怎么改进Redis单线程阻塞后面请求,类似线上服务不要执行keys*,可以分批取数据
17.Redis怎么分片的
18.Redis的删除策略
19.写代码,很简单的斐波那契数列面试官后面跟我说一般前面回答的好,算法题就不会为难你的,如果你前面答的一般,就需要难的算法题来找你的亮点了遇到这些简单的算法题一定不能大意,这种写出瑕疵了会非常的减分,各种边界比如传的参数小于0可以抛异常,还有注意命名规范面试写算法题要多和面试官交流,有的面试官故意不把题目说清楚,等着你去问,考察你的沟通交流能力,不要上来不交流就蒙头写代码
20.手撕代码,leetcode98验证二叉搜索树
SELECTuser_id,count(distinct(video_id))ascFROMvideoWHEREstart_time=-6-23GROUPBYuser_idHAVINGcORDERBYcDESCLIMIT0,3
写完和面试官聊了聊优化点,其实可以不用全部中序遍历完再判断,不然树比较大的话性能不够好
21.写SQL一个video表,里面有三个字段user_id、video_id、start_time表里面的一行记录表示的是某个user在在某个time看了某个video要求:今天看不同视频数量超过个的用户id的前三名
SELECTuser_id,count(distinct(video_id))ascFROMvideoWHEREstart_time=-6-23GROUPBYuser_idHAVINGcORDERBYcDESCLIMIT0,3
SQL渣渣,自己很虚也不知道写的对不对,面试官说没什么问题
22.你有什么想问我的吗
面试官夸我基础扎实,挺开心,这些天的复习刷lc总算没有白费
1.2二面(60分钟)
面试时间:6.:00-16:00
1.自我介绍
2.为什么还不到一年就出来看机会了得不到成长,有一些重复性的工作,注意不要说前东家的坏话
3.你希望你处于一个什么样的工作环境做的事有挑战性,周围都是优秀的人push自己更快的成长
4.你的职业规划计划赶不上变化,短期三年内主要是稳扎稳打学技术,提高实战能力,提升快速把业务抽象成代码的能力,拓宽技术广度,部分技术深度达到top
5.怎么根据0-5随机函数得到0-8随机函数
6.缓存和DB之间怎么保证数据一致性缓存预留模式读操作:先读缓存,缓存没有的话读DB,然后取出数据放入缓存,最后响应数据写操作:先更新DB,再删除缓存为什么是删除而不是更新呢?原因很简单,复杂场景下缓存不单单是DB中直接取出来的值,此外更新缓存的代价是很高的,频繁更新的缓存到底会不会被频繁访问到?可能更新到缓存里面的数据都是冷数据,频繁失效,所以一般用到再去加载缓存,lazy加载的思想
先更新DB,再删除缓存的问题,如果更新DB成功,删除缓存失败会导致数据不一致所以一般是先删除缓存,再更新DB
还是有问题,A先删除了缓存,但还没更新DB,这时B过来请求数据,发现缓存没有,去请求DB拿到旧数据,然后再写到缓存,等A更新完了DB之后就会出现缓存和DB数据不一致的情况了
解决方案:更新数据时,根据数据的唯一标识路由到队列中,读取数据时,如果发现数据不再缓存中,那么把读取数据+更新缓存的操作,根据唯一标识路由之后,也发送到相应队列中。一个队列对应一个工作线程,线程串行拿到队列里的操作一一执行
带来的新问题:可能数据更新频繁,导致队列中积压了大量的更新操作,读请求长时间阻塞,所以要压测
7.延时消息队列怎么设计Redis的zset
8.zset做延时队列会有什么问题死循环轮询耗时
9.zset区间查询怎么做的,时间复杂度多少底层跳表,lgN的查询,定位到起始位置顺序遍历即可
10.你最擅长的技术有哪些Java的集合、并发、虚拟机MySQL和Redis的底层原理
11.说下索引二八原理、提升读性能牺牲写性能的数据结构一个索引对应一颗B+树哈希、有序数组、二叉树查询的优缺点那为什么不用跳表呢?
回表、索引覆盖
最左前缀哪些字段适合建索引、索引缺点
12.为什么疫情期间要展示健康码,别人又不看,又不扫描这个健康码,那展示出来有什么用呢还有就是为什么你最近去了疫情多发区,再扫健康码就是红色的了
其实就是拿出健康码时你的位置信息会push上去
13.火车票区间查询怎么设计数据结构比如上海去武汉,途经南京、合肥现在要快速查询出两点之间票的库存
我说借鉴跳表的思路可以实现
14.手撕代码,leetcode54螺旋矩阵
privatestaticfinalfloatMIN_COUNT=0.01f;publicListFloatfunc(floattotal,intk){ListFloatres=newArrayList(k);if(total=0
k=0
k*MIN_COUNTtotal)returnres;Randomrandom=newRandom();while(k!=0){if(k==1){res.add(total);}else{floatcur=MIN_COUNT+random.nextFloat(total-k*MIN_COUNT);res.add(cur);total-=cur;}k--;}returnres;}
15.你有什么想问我的吗
1.3三面(60分钟)
面试时间:6.:00-17:00
1.手撕代码,模拟