面试复盘|秋招汇总+部分答案总结(蔚来、字节、美团、百度)
个人情况介绍
双非本科,从2,3月份开始准备找实习,然后复习知识。简历挂了很多,主要面试机会来自于腾讯,阿里等提前批,因为当时不怎么卡简历。后续兜兜转转挂了很多,后续6月份才找到好未来实习。
然后7月份开始一边实习一边秋招,可能由于优化了项目和有实习经历以及参加了一个开源活动经历的原因,简历挂的相对少了。
蔚来 7.17 连续三面
一面
项目经历
- 项目是一个IM即时通讯系统,聊了10几分钟
涉及群聊,私聊等的流程,使用的中间件Kafka、Redis、zk等等
设计模式
- 策略模式(简历上写的)
一个类的行为或者算法可以在运行时改变。
创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
算法题
两个队列实现一个栈,口述
lc255
判断链表是否有环,口述
双指针
写题-剑指 Offer 61. 扑克牌中的顺子
当时忘了怎么做了,跟面试官边讨论边写,磨叽了20多分钟.
如果遇到题不会写,一定不要放弃,尽可能地跟面试官讨论,或者让他给点提示什么的class Solution { public boolean isStraight(int[] nums) { Set<Integer> repeat = new HashSet<>(); int max = 0, min = 14; for(int num : nums) { if(num == 0) continue; // 跳过大小王 max = Math.max(max, num); // 最大牌 min = Math.min(min, num); // 最小牌 if(repeat.contains(num)) return false; // 若有重复,提前返回 false repeat.add(num); // 添加此牌至 Set } return max - min < 5; // 最大牌 - 最小牌 < 5 则可构成顺子 } }
二面
项目经历
项目中用到的netty框架的实现
异步,设计模式,架构等等
项目相关的细节
群聊,私聊, Kafka、Redis、zk等等
Kafka如何保证消息有序性
Kafka只能保证单个的partiton之间的顺序消费。所以只需要保证消息发送到同一个partiton就能实现顺序消费。
一般可以指定单个partiton或者指定消息的key,相同key的消息会发送到同一个partiton。
redis的数据结构
- list:双向链表
- set:hashTable
- zset:比set多了一个score参数,可用于排序
- hash:hashTable
- string:字符串键值对、动态字符串
断线重连的设计
客户端掉线:服务端删除map中的映射,并删除redis中的数据。
若服务端挂掉,删除redis失败也无所谓。给redis设置一个过期时间,比如客户端和服务端心跳每隔一段时间就更新这个过期时间。然后用户连接的时候直接覆盖redis的数据
服务端挂掉:服务端和zookeeper通过心跳机制来检测是否存活,若检测到服务器挂掉就删除对应的节点。redis当中客户端会自动重连覆盖
启动失败重连
通过回调函数进行重连运行服务器掉线
通过handler的Inactive方法监听掉线,如果掉线就重新选择服务器进行连接
如何在应用层确保消息的发送成功
借鉴TCP的设计,设计发送确认的机制
SpringCloud了解过吗? 有哪些组件 (这个不会)
心跳机制的设计
Java基础
- 垃圾回收的过程
- 内存泄漏是什么
- 如何避免内存溢出
- 如何排查内存泄漏
- 初步判断:频繁发生Full GC,但是回收的内存又很少
- 分析进程发生内存泄露的地方:导出dump文件(jmap),分析对象的引用链,查看创建对象的代码是否可能存在内存泄露的可能
- 接触过非关系数据库吗? (我寻思redis不算吗?后面随便说了过mogodb的使用)
谈学校和人生
- 学校中遇到的困难,如何解决
- 反问-技术栈,部门等等
三面
项目经历
- netty的异步模型、粘包,拆包问题以及编解码器的api从字节流转换成buffer的操作过程 、直接内存和堆内存
- BIO和NIO的区别
智力题
- 50个蓝球,50个红球,放到两个罐子,如何放才能使得从两个罐子中取出一个红球的概率最大
(一个罐子放一个红球,剩下全放在另一个罐子)
场景设计
- 在线网站画类图,场景就是聊天场景. 有多种消息,比如文本,图片,视频,音频,emoj表情. 如何设计类的抽象和继承组合关系.
(这个没怎么遇到过,搞了很久,最后在引导下画了个差不多的交给他了)
后续
一个月后8.23意向书
字节 一周一面
一面 7.23 40分钟
- 自我介绍、开源经历,实习经历,项目经历介绍
计网
三次握手过程
第一次握手:客户端发送 SYN 报文,并进入 SYN_SENT 状态,等待服务器的确认;
第二次握手:服务器收到 SYN 报文,需要给客户端发送 ACK 确认报文,同时服务器也要向客户端发送一个 SYN 报文,所以也就是向客户端发送 SYN + ACK 报文,此时服务器进入 SYN_RCVD 状态;
第三次握手:客户端收到 SYN + ACK 报文,向服务器发送确认包,客户端进入 ESTABLISHED 状态。待服务器收到客户端发送的 ACK 包也会进入 ESTABLISHED 状态,完成三次握手。
为什么等待2MSL才能断开连接
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
为什么会出现大量time-wating状态,如何解决
调整linux内核,快速回收和重用
请求量太大,连接请求过多如何解决
加机器,分布式服务,通过负载均衡来分散请求
MySQL
ACID特性
一致性举例子
违反举例:A有200元,转账给B。无论如何,A、B加起来都必须满足200元,而不会出现其他状态
数据库隔离级别以及对应的问题
比如脏读、不可重复读、丢失修改等等
如何解决上述问题
MVCC,锁机制、Next-Key lock等等
读已提交级别(RC)是如何实现的
RC和RR一般来说可以通过加锁来解决,但频繁加锁会影响效率,InnoDB使用了MVCC机制的快照读的方式,一定程度解决了RC和RR的问题
Java基础
讲讲ThreadLocal的用处和原理,key和value为什么分别是弱引用和强引用,内存泄露的情况了解吗
每个线程Thread中有一个map,我们创建一个ThreadLocal变量来操作线程中map,比如set/get。key是ThreadLocal变量(this)的弱引用(一gc就会回收),value是保存的变量值
key设计成弱引用的目的
为了更好地对ThreadLocal进行回收,当我们在代码中将ThreadLocal的强引用置为null后,这时候Entry中的ThreadLocal理应被回收了,但是如果Entry的key被设置成强引用则该ThreadLocal就不能被回收
value设计成强引用
因为value是用户需要使用的值,如果在key还没生效时就被回收了显然是不对的;若key被回收变成了null,那么说明这个键值对就是无效的了,应该删除掉(或者在map进行扩容时会自动清除失效的键值对)
内存泄漏相关问题
- key泄漏:
ThreadLocalMap
的key是弱引用,一旦内存不够gc就能回收 - value泄漏:value引用是强引用,随着线程的结束会释放。但是如果线程运行时间很长,但ThreadLocalMap又不使用了的话,就会造成内存泄漏。所以不再使用了的话要手动调用remove方法释放
线程池参数
线程池提交任务的执行流程
AQS的实现
公平锁和非公平锁的区别,以及怎么实现的
GC标记的流程
初始标记-并发标记-再次标记-并发清除
Redis
讲一讲redis的集群
为什么集群的槽数量是16384这个值
crc16可以达到65536个槽,但redis只采用了16384个。因为节点和槽的信息用bitmap表示,16384需要16384/8=2k的空间,而65535需要65536/8=8k,占用空间过大。根据作者的观点,redis理论上最多有1000个节点(更多的话就会网络拥堵),16384个槽是完全够用的,没必要扩展到65536
redis的zset数据结构(跳表的实现)
跳表查询的时间复杂度
算法题
- 写题-判断平衡二叉树
二面 7.28 1小时
- 自我介绍、项目经历
项目经历
- Netty的架构和设计模式
讲了reactor反应器模式,bossgroup和workergroup等 - Java的NIO(selector,channel,buffer组件)
- select和epoll区别
- 读取的字节流放在哪里(内核socket结构中?)
这里我当时不太懂他的意思,我就说从网卡读取后放入内核socket结构中,也不知道对不对 - select之后还需要调用read和write吗?
- netty的直接内存和堆内存
讲了哪些地方使用直接内存,哪些地方堆内存,有什么区别 - netty的零拷贝
这个不太会,netty的零拷贝跟传统意义的零拷贝不太一样,我不记得了
Java基础
- ArrayList和linkedlist区别
- Arraylist为什么不是线程安全的,如何实现线程安全
我说的是用copyOnWrite来实现线程安全 - GC标记的过程,如何选取GC-ROOT
这个标记过程一面没答出来,二面又问了,不知道是不是面评会写这么详细嘛、、 - Java的类型擦除
- ArrayList<string>类型擦除后的实际类型是什么</string>
Redis
- redis的持久化机制
RDB和AOF
计网、操作系统
- http状态码有哪些
- http和https的区别,https的加密过程
- 线程和进程区别
- 进程切换具体需要保存哪些资源
- 线程同步的几种方式
- 操作系统调度算法
算法题
- 算法题-LCS
三面 8.5
这一面忘了录音,大致是聊了一些项目Netty相关的技术,最后写了一道算法题,lc54-螺旋矩阵
推荐这个思路,来自lc评论区老哥,感觉挺好用的
/* 1.定制四个边界,打印一条边就改变一个边界并检查边界是否越界 */ class Solution { public int[] spiralOrder(int[][] matrix) { if(matrix.length==0) return new int[0]; int top=0,bottom=matrix.length-1,left=0,right=matrix[0].length-1; int[] res = new int[matrix.length*matrix[0].length]; int pos=0; while(top<=bottom && left <= right){ for(int i=left;i<=right;i++){ res[pos++]=matrix[top][i]; } top++; for(int i=top;i<=bottom;i++){ res[pos++] = matrix[i][right]; } right--; for(int i=right;i>=left && top<=bottom;i--){ res[pos++] = matrix[bottom][i]; } bottom--; for(int i=bottom;i>=top && left <= right;i--){ res[pos++] = matrix[i][left]; } left++; } return res; } }
然后加了HR微信马上就告知通过了,但没想到还有HR面试...
HR面 8.10 10分钟
飞书上简单聊了一些学校、实习、项目遇到的困难,手上有哪些offer,偏向于哪个这种问题就结束了
后续
等了13个工作日,催了无数次HR和内推人,一度以为凉了。
8.30收到意向书
美团-优选
一面 8.17 1小时
面试官上来先自我介绍,然后介绍了一下部门。我自我介绍后闲聊了几分钟,问了问实习经历,考不考研什么的
- 项目介绍
项目经历
Kafka
消息队列的作用有哪些
异步、解耦
kafka如何保证消息有序性
多线程消费的时候如何保证有序
kafka的高吞吐量的优化(顺序读写、零拷贝、pagecache)
Reids
- redis的数据结构用过哪些
- redis底层hash原理懂吗
- redis的单线程模型
- redis的持久化机制
RPC项目
- 你的RPC项目的流程是怎样的
- 为什么使用ProtocBuf
Java基础
静态类和静态内部类的使用场景
然后我不记得了,提到了单例模式会使用静态内部类
手写单例模式DLC
volatile的用处是什么,为什么要双重检验
JVM内存区域划分
哪些区域会有OOM错误
不停的new 对象一定会爆出OOM错误吗
GC的过程
MySQL
- mysql索引为什么使用B+树
- 如何优化SQL
- 索引哪些情况会失效
- 事务的隔离级别
- 你使用的默认的隔离级别是什么
- 可重复读级别是如何实现的
算法题
- 算法题-最长公共子串
二面 8.28
这一面忘了录音记录了,难度也不大,聊了聊八股就给过了。优选这个部门是真的缺人,也可能是加班太吓人了招不到人了,哈哈。
HR面 电话面 10分钟
先介绍了一下这边是美团优选的HR
确认了一下姓名和学校年份
然后让我自我介绍一下以及说下项目实习
聊关于项目的事情,做了多长时间,做了哪些事儿,遇到哪些困难
再聊实习经历,问做了那些事,有没有遇到团队沟通的不畅的问题
学校经历,学习了哪些课程和技术
如何学习新技术的
你了解美团和优选吗?
了解美团技术氛围吗
最后说这个电话也是微信号,让我加微信,后续一周内发放意向书。
后续更新
9.6意向书
百度
一面
这一面记录也丢失了,哈哈,因为有时候总会忘记录音。这一面主要问的是跟我项目相关的,加上很少一部分八股,所以参考价值也不到。没写算法题
二面 7.21 50分钟
- 项目经历
Java基础
- Java的三大特性 (封装、继承、多态)
- Java的泛型机制、类型擦除
- 讲讲用的比较多的集合类(list,queue,set,map等等)
- ArrayList和LinkedList的区别
- Hashmap的底层数据结构 、什么时候会从链表转换成红黑树,是线程安全的吗?为什么不线程安全
- ConcurrentHashMap是如何实现线程安全的,底层数据结构是什么
- Java保证原子性的几种方法
- 锁升级的过程
- 对象头保存到内容有哪些
- String使用赋值和new的区别,你怎么用的
- Java的异常有哪些类型
- 创建线程的几种方法
- 线程池的使用方式,Java默认自带的有哪些线程池、7大参数 、提交任务的执行流程
- 线程调用start方法后的发生了什么
Spring
SpingBoot、SpringMVC和Spring的区别和优点
IOC和AOP是什么?AOP你有使用过吗?(全局异常处理算不算)
Spring事务了解吗?(我只是到有个@Transaction注解)
然后就开始深入问跟这个@Transaction相关的场景题,就是@Transaction什么情况会回滚,什么时候不能回滚,这里我不怎么会,只能乱扯一通。
其他杂七杂八的
- MyISam和Innodb的区别
- 设计模式了解哪些
- 策略模式和工厂模式有什么区别(我都不知道这两个很像吗)
- JVM内存模型
- 反问部门业务相关,他提到出差的问题,会经常出差,但时间不会长达一两个月。感觉有点坑
- 问了性格怎么样,有什么优点和缺点
三面 7.28 40分钟
- 项目经历
Redis、Kafka
Redis的高可用了解吗?
这里我答得不怎么好,说了redis的持久化机制和集群。但他想问的应该是哨兵机制相关的吧
redis集群和哨兵模式的优缺点
这里越说越不对劲了,自己给自己带坑里去了
Kafka你了解哪些?
这里本来应该可以背一背准备好的八股文,但我脑子抽了就不想背,问他想知道哪些,这里就把主动权交出去了,大忌大忌!!
Kafka的基本架构是什么
我讲了producer、consumer、broker等基本概念,这个问题之前没怎么准备过,有点宽泛
你的消费者和线程之间的对应关系是怎样的
我就只知道一个消费者对应一个线程这种。然后我主动说如果需要使用多线程的话,那么可以一个线程去拉取消息,然后通过一个队列,来启动多个线程进行消费。其实是网上博客看的,我也没怎么懂,教训就是千万不要自己给自己挖坑说一些模棱两可不禁问的东西
你刚才说用一个队列,那如果一条线程消费的手挂掉了,那offset是怎么提交的
然后这个地方说不清楚了,我都说不会了,这面试官不肯放过,还一直问,我也没办法,GG
Java基础
- JVM的内存模型
- 线程同步的几种方式
- 可重入锁底层的实现(AQS)
- AQS是怎么实现的
- AQS的state变量是如何修改的
- 线程切换的过程有哪些(保存现场,移出可运行队列,放入等待队列)
- 进程和线程的区别
设计模式
设计模式了解哪些(单例、工厂、策略)
工厂和抽象工厂模式的区别(这。。都没听说过)
然后他说这不应该不知道啊,netty底层设计都用了抽象工厂模式。我又没研究过netty使用的设计模式...
性格人生云云
对于加班怎么看?
我说最好加班在干一些实际有意义的事情。然后他开始杠了,怎么才算有意义呢?如果项目进度拖慢了,你愿意加班吗?
我说短时间可以,长期不行。他又杠如果就是长期怎么办,我心里想还能怎么办,还不快跑嘛
问到这里我就已经无语了,加班搞得他很光荣一样。。。
团队意见不一致怎么办
你有想过帮助其他人成长吗?(满脸问号)
还用过其他语言和技术栈吗?(python和go)
反问部门业务啥的,走个过场。
后续
第二天简历共享。。。
目前秋招求职情况总结
目前收获了蔚来、字节的意向书,美团HR面完成。后续不怎么想面试了,随缘面一些,躺平吧,哈哈。
#面试复盘##面经##校招##字节跳动##蔚来汽车#