2025 2 19 Java 面试题(美团 快手)
在实习期间,我有幸参与到面试协助工作中,这使我得以近距离接触到丰富多样的面试场景,也深切体会到不同候选人在技术知识储备和思维方式上的差异。 面试结束后,我意识到这些面试问题是宝贵的学习资源,它们不仅涵盖了编程语言基础、数据结构与算法、数据库、框架等多个关键领域,还涉及到实际项目开发中的各种场景。为了能更深入地理解这些问题,我前往牛客网,在众多资料中精心挑选了一系列完整且具有代表性的面试问题。在此,我要特别感谢那些在牛客网分享面经的同学,是你们的无私分享,让我有了更全面的素材进行学习,原面经出处我都已标清。 之后,借助豆包强大的分析与解答能力,对这些问题进行了全面且深入的剖析,形成了这份面经答案思路汇总。 这份汇总不仅是对面试问题的解答,更是我个人学习和成长的记录。我希望它能为正在求职的同学提供一些参考,帮助大家更好地应对面试挑战;也希望能与同行们分享交流,共同提升我们在技术领域的认知水平。
美团java后端日常实习一二面一面
- 项目相关的问题
- 什么是缓存雪崩、缓存穿透、缓存击穿
- 分布式限流(Redisson)、限流算法(固定窗口、滑动窗口、漏桶、令牌桶)
- Redis为什么快(内存、io多路复用+事件驱动、数据结构简单,最后这个忘了)
- Maven 解决版本冲突问题(我没了解过这个,面试官说DependencyManagement)
- Mysql索引结构,为什么选择B+树而不是B树
- Mysql默认隔离级别,怎么实现的可重复读(快照读-MVCC,当前读-锁)
- Read View都有什么字段
- sql查询优化
- Bean生命周期
算法:lc19.删除链表的倒数第N个结点
====================================================
二面
- 项目相关的问题
- 了解过什么大模型,学习渠道
- 前端轮询和websocket区别,各自的优势
- 用户量特别大的情况下,轮询压力很大怎么优化
- redis持久化,AOF和RDB对比
- MySQL对比Redis优势
- 线程池机制、核心参数、拒绝策略
- 重载和重写区别
- 接口是什么,使用的场景,和抽象类区别
- jvm内存区域,堆为什么要分成新生代和老年代
- 什么对象会从新生代晋升到老年代
- 用过什么linux指令
- 自己有什么优点和缺点
算法:lc102.二叉树的层序遍历
作者:Czzzzzzzz链接:https://www.nowcoder.com/feed/main/detail/d27704499b5c41e0bd0019a8d158a052来源:牛客网
一面回答思路
- 项目相关问题:
1. 缓存雪崩、缓存穿透、缓存击穿:
2. 分布式限流(Redisson)、限流算法:
3. Redis为什么快:
4. Maven解决版本冲突问题:
5. Mysql索引结构,为什么选择B+树而不是B树:
6. Mysql默认隔离级别,怎么实现的可重复读:
7. Read View都有什么字段:
8. sql查询优化:
9. Bean生命周期:
10. 算法:lc19.删除链表的倒数第N个结点:
- 先向面试官说明使用快慢指针的思路,这样能在一次遍历中找到目标节点,时间复杂度为O(n)。 - 具体实现步骤:定义两个指针,快指针先向前移动N步;然后快慢指针同时移动,直到快指针到达链表末尾;此时慢指针指向的就是倒数第N + 1个节点,删除其下一个节点即可。 - 注意处理边界情况,如链表为空、N为0、N大于链表长度等,确保代码的健壮性。
二面回答思路
1. 项目相关问题:
2. 了解过什么大模型,学习渠道:
3. 前端轮询和websocket区别,各自的优势:
4. 用户量特别大的情况下,轮询压力很大怎么优化:
5. redis持久化,AOF和RDB对比:
6. MySQL对比Redis优势:
7. 线程池机制、核心参数、拒绝策略:
8. 重载和重写区别:
9. 接口是什么,使用的场景,和抽象类区别:
10. jvm内存区域,堆为什么要分成新生代和老年代:
11. 什么对象会从新生代晋升到老年代:
12. 用过什么linux指令:
列举常用指令,如ls
(列出目录内容)、cd
(切换目录)、mkdir
(创建目录)、rm
(删除文件或目录)、cp
(复制文件或目录)、mv
(移动或重命名文件或目录)、grep
(文本搜索)、top
(查看系统资源使用情况)等,并简单说明每个指令的使用场景和基本参数。
13. 自己有什么优点和缺点:
14. 算法:lc102.二叉树的层序遍历:
- 向面试官说明使用队列实现层序遍历的思路,即借助队列先进先出特性,按层依次处理节点。 - 具体实现步骤:先将根节点入队;然后循环取出队列头部节点,将其值加入结果列表,并将其左右子节点(若存在)入队;持续循环直到队列为空,此时结果列表即为二叉树的层序遍历结果。 - 注意处理边界情况,如根节点为空时直接返回空列表,确保代码完整、正确。
快手Java日常实习一面
1、Redis有哪些客户端,有什么区别2、限流算法,漏桶和令牌桶使用场景3、为什么选择RabbitMQ,kafka了解过吗,使用场景4、如何避免消费端重复消费,什么情况下会出现重复收到消息5、粘包半包是什么,怎么在项目中解决的6、自定义的协议有哪些字段7、Springboot怎么做到导入就可以直接使用的8、mysql默认隔离级别,可重复读能够解决幻读问题吗9、举一个可重复读下出现幻读的例子10、mysql有哪些日志,都有什么作用11、插入一行数据,分别什么时候写入这三个日志12、线上项目,没有日志,没后台数据的情况下怎么找出问题算法:lc415字符串相加第一次面试,巨紧张,回答的都不是很好
作者:Czzzzzzzz链接:https://www.nowcoder.com/feed/main/detail/dd1f2a0a303644dab4b53c5be40caf9b?sourceSSR=users来源:牛客网
1. Redis有哪些客户端,有什么区别
- 回答思路
- 示例回答常见的Redis客户端有Jedis、Lettuce和Redisson。
- Jedis:使用方式简单直接,其API与Redis命令一一对应,容易上手。但它是基于阻塞I/O的,在高并发场景下,线程会因为等待I/O操作而阻塞,导致性能下降。例如在一个小型电商系统的商品库存查询功能中,并发量不是特别大,使用Jedis可以快速实现功能。
- Lettuce:基于Netty实现,采用异步非阻塞I/O,能更好地应对高并发场景。它支持响应式编程,性能表现出色。在大型互联网应用的缓存系统中,如微博的热点数据缓存,需要处理大量并发请求,Lettuce就比较合适。
- Redisson:提供了丰富的分布式对象和服务,如分布式锁、分布式集合等。在分布式系统开发中,能极大简化开发过程。比如在一个分布式事务系统中,使用Redisson的分布式锁可以确保数据的一致性。
2. 限流算法,漏桶和令牌桶使用场景
- 回答思路
- 示例回答
- 漏桶算法原理:请求就像水一样流入漏桶,漏桶以固定的速率处理请求。如果请求的流入速度超过了漏桶的处理速度,多余的请求会被丢弃。
- 适用场景:适用于需要严格控制请求处理速度的场景,例如银行的转账接口,为了保证系统的稳定性和安全性,需要将请求以稳定的速率处理,避免系统因突发流量而崩溃。
- 令牌桶算法原理:系统以固定的速率生成令牌放入桶中,请求需要从桶中获取令牌才能被处理。只要桶中有令牌,请求就能立即得到处理。
- 适用场景:适合流量具有突发性,但又需要限制平均速率的场景。比如视频网站的视频播放接口,在用户集中点击播放视频时会有突发流量,令牌桶算法可以在保证平均流量不超限制的情况下,允许这些突发请求通过,保证用户体验。
3. 为什么选择RabbitMQ,kafka了解过吗,使用场景
- 回答思路
- 示例回答选择RabbitMQ主要有以下几个原因:
- 功能丰富:它支持多种交换器类型,如direct、topic、fanout等,可以根据不同的业务需求进行灵活的消息路由。
- 可靠性高:支持消息持久化、事务机制等,能够确保消息不丢失。
- 社区成熟:有丰富的插件和工具,便于与其他系统集成和扩展。
Kafka是一个高吞吐量的分布式消息系统,它的主要特点是高并发、高扩展性和容错性好。
- RabbitMQ使用场景:适用于对消息可靠性和路由规则要求较高的场景,如金融系统中的资金变动通知,需要确保每一条消息都能准确无误地发送和处理。
- Kafka使用场景:适合处理海量数据的实时处理场景,如大型互联网公司的日志收集与分析系统,Kafka可以高效地接收和存储大量的日志数据。
4. 如何避免消费端重复消费,什么情况下会出现重复收到消息
- 回答思路
- 示例回答
- 重复消费的原因
- 避免重复消费的方法
5. 粘包半包是什么,怎么在项目中解决的
- 回答思路
- 示例回答
- 概念解释:粘包是指多个数据包被合并成一个数据包发送,导致接收方无法正确区分每个数据包的边界。半包是指一个数据包被拆分成多个部分发送,接收方收到不完整的数据包。
- 产生原因:主要是由于TCP协议为了提高传输效率,会将小数据包合并成大数据包发送,或者将大数据包拆分成多个小数据包发送。
- 解决方法
6. 自定义的协议有哪些字段
- 回答思路
- 示例回答自定义协议通常包含以下几个部分的字段:
- 消息头字段
- 消息体字段:根据具体的业务需求定义,包含实际要传输的数据。例如在一个用户登录协议中,消息体可能包含用户名和密码。
- 校验字段:用于对消息进行校验,确保消息在传输过程中没有被篡改或损坏。常见的校验方式有CRC校验、MD5校验等。
7. Springboot怎么做到导入就可以直接使用的
- 回答思路
- 示例回答Spring Boot通过自动配置机制实现了导入依赖就可以直接使用的功能。其核心是@EnableAutoConfiguration注解,它会触发Spring Boot的自动配置流程。
Spring Boot会扫描classpath
下的META - INF/spring.factories
文件,该文件中定义了各种自动配置类。当我们在项目中引入某个依赖时,Spring Boot会根据依赖的信息,找到对应的自动配置类,并根据项目的配置属性进行自动配置。
例如,当我们引入spring - boot - starter - web
依赖时,Spring Boot会自动配置Spring MVC相关的组件,如DispatcherServlet
、视图解析器等,我们不需要手动进行大量的配置就可以直接使用Web开发的功能。
8. mysql默认隔离级别,可重复读能够解决幻读问题吗
- 回答思路
- 示例回答MySQL的默认隔离级别是可重复读(Repeatable Read)。
幻读是指在同一事务中,两次相同的查询返回了不同数量的行。
在可重复读隔离级别下,InnoDB存储引擎通过MVCC(多版本并发控制)和间隙锁机制,在很大程度上解决了幻读问题。MVCC保证了在同一事务内多次读取数据的一致性,间隙锁防止了其他事务在查询范围内插入新的数据。但严格来说,可重复读并没有完全解决幻读问题,对于一些特殊情况,如在事务中先插入一条数据,然后再进行相同条件的查询,还是可能出现幻读现象。
9. 举一个可重复读下出现幻读的例子
- 回答思路
- 示例回答假设我们有一个
users
表,包含id
和age
两个字段。
现在有两个并发事务:
- 事务T1:
START TRANSACTION; SELECT * FROM users WHERE age > 18; -- 第一次查询,返回10条记录 -- 这里可能执行一些其他操作 SELECT * FROM users WHERE age > 18; -- 第二次查询 COMMIT;
- 事务T2:
START TRANSACTION; INSERT INTO users (age) VALUES (20); -- 插入一条满足age > 18的记录 COMMIT;
在事务T1中,第一次查询返回了10条记录。在T1事务还未提交时,事务T2插入了一条新记录并提交。当T1进行第二次查询时,发现返回了11条记录,这就出现了幻读现象,因为在T1事务内,两次相同的查询返回了不同数量的行。
10. mysql有哪些日志,都有什么作用
- 回答思路
- 示例回答MySQL常见的日志有以下几种:
- 二进制日志(Binary Log):记录了数据库的所有写操作,如INSERT、UPDATE、DELETE等。主要用于数据备份和恢复,以及主从复制。在主从复制中,主库将二进制日志发送给从库,从库通过重放这些日志来保持与主库的数据一致性。
- 事务日志(InnoDB Redo Log和InnoDB Undo Log)
- 错误日志(Error Log):记录MySQL服务器在启动、运行过程中发生的错误信息,方便管理员排查问题。例如,数据库启动失败的原因、运行时的异常错误等都会记录在错误日志中。
- 查询日志(General Log):记录了所有的SQL语句,包括查询、插入、更新等操作。主要用于调试和分析数据库的使用情况,但会对性能产生一定影响,一般在生产环境中不建议开启。
- 慢查询日志(Slow Query Log):记录了执行时间超过指定阈值的SQL语句,帮助开发人员和管理员找出性能瓶颈,优化数据库查询。
11. 插入一行数据,分别什么时候写入这三个日志(二进制日志、事务日志、错误日志)
- 回答思路
- 示例回答
- 二进制日志:在事务提交时写入。因为二进制日志记录的是数据库的写操作,为了保证数据的一致性和完整性,只有在事务提交后,才将该事务的所有写操作记录到二进制日志中,用于主从复制和数据恢复。
- 事务日志
- 错误日志:只有在插入数据过程中发生错误时才会写入。例如,插入的数据违反了数据库的约束条件(如唯一约束、外键约束等),或者出现了数据库系统内部错误,这些错误信息会被记录到错误日志中,方便开发人员或运维人员排查问题。
12. 线上项目,没有日志,没后台数据的情况下怎么找出问题
- 回答思路
- 示例回答在没有日志和后台数据的情况下,可以从以下几个方面找出问题:
- 系统层面
- 代码层面
- 版本管理层面
算法:lc415字符串相加
- 回答思路
- 示例回答这道题可以使用模拟加法运算的方法来解决。具体步骤如下:
- 初始化两个指针
i
和j
,分别指向两个字符串的末尾。 - 初始化一个进位变量
carry
,用于记录每一位相加的进位。 - 从后往前逐位相加,将对应位的字符转换为数字,并加上进位
carry
。 - 计算当前位的结果和新的进位,将当前位的结果添加到结果字符串中。
- 移动指针
i
和j
,如果其中一个字符串已经遍历完,继续处理另一个字符串。 - 最后,如果还有进位,将进位添加到结果字符串中。
- 由于是从后往前构建结果字符串,最后需要将结果字符串反转。
以下是Python代码示例:
def addStrings(num1, num2): i, j = len(num1) - 1, len(num2) - 1 carry = 0 result = [] while i >= 0 or j >= 0 or carry: n1 = int(num1[i]) if i >= 0 else 0 n2 = int(num2[j]) if j >= 0 else 0 total = n1 + n2 + carry
美团数据系统研发日常实习一面
timeline:2.14晚上莫名其妙给我发了个2.20的面试,没电话通知也,但本着经验+1的想法还是面了。
一、实习介绍:
1.介绍实习有含金量的点,实习的工作。(我介绍了实习的项目)
2.接口幂等性
3.慢SQL问题,怎么发现的,场景,怎么排查
4.Mysql索引相关,索引底层,联合索引
5.联合索引和单列索引的区别(单列索引给我挖坑呢,大家注意区分单列中有主键索引和非主键索引)
6.联合索引的使用,要注意什么(最左匹配,范围查询,sql语句上运算)
二、项目介绍:
1.介绍项目有含金量的点,项目的工作(魔改黑马头条)
2.Redis常见数据类型及其底层(重点说了zset)
3.kafka解决mysql和redis的数据一致性问题,其他还有什么方案
4.布隆过滤器是什么,解决什么问题,能消除误判率吗,误判率怎么设置的
5.bitmap的作用,及常见使用场景
6.kafka怎么保证数据不丢失,我做了什么工作吗
7.假如mysql和redis使用kafka解耦之后,有一部分失败导致数据不一致怎么办(引入对账任务)
三、八股:
1.线程池相关知识,常见线程池,线程池核心参数,常见拒绝策略,线程池怎么用
2.jvm相关知识:常见垃圾回收器,常见垃圾回收算法,对象晋升老年代的方法
lc:**************(难绷,手撕思路对了,没撕出来,有点不重视这个面试,算法好久没刷了)
总结:感觉问的很常规,没有什么场景题,有一些场景是我通过他的问题引申出来的。最后问了业务,感觉也不是很行,还是安心去滴滴吧,毁约实在不好。(再说了,手撕都没出来,人家给你二面吗hhhhh)
作者:给🐭🐭个面试机会吧链接:https://www.nowcoder.com/来源:牛客网
以下是针对校招水平的面试问题,提供一些常见的回答思路和答案。这些问题涵盖了技术基础、项目经验、算法能力以及软技能等多个方面。
一、自我介绍
问题:请做一下自我介绍。
回答思路:
- 简单介绍自己的基本信息(学校、专业、年级)。
- 强调实习经历或项目经验,突出技术能力和解决问题的能力。
- 表达对目标岗位的兴趣和热情。
示例回答:“大家好,我是XX大学计算机专业的应届毕业生。在校期间,我参与了多个项目,比如基于Spring Boot开发的在线商城系统,负责后端接口设计和数据库优化。此外,我还曾在某公司实习过三个月,主要负责高并发场景下的接口性能优化。我对分布式系统和微服务架构有浓厚兴趣,希望能在贵公司进一步提升自己的技术能力。”
二、技术基础知识
1. 接口幂等性
问题:什么是接口幂等性?如何保证接口的幂等性?
回答思路:
- 解释幂等性的定义。
- 提供几种实现方式,例如唯一标识符、数据库唯一约束、分布式锁等。
示例回答:“接口幂等性是指同一个请求多次执行产生的结果是一致的,不会因为重复调用而导致数据异常。常见的实现方式包括:
- 使用唯一标识符(如订单号),确保每次请求都对应唯一的业务操作;
- 在数据库中设置唯一约束,防止重复插入;
- 使用分布式锁,确保同一时间只有一个请求能够处理相同的数据。”
2. 慢SQL问题
问题:如何发现慢SQL?常见场景有哪些?如何排查?
回答思路:
- 说明慢查询日志的作用。
- 提到常用的排查工具和方法,如
EXPLAIN
分析执行计划。 - 结合实际场景举例。
示例回答:“可以通过MySQL的慢查询日志发现慢SQL,通常会设置一个阈值(如1秒)。排查时可以使用EXPLAIN
命令查看执行计划,检查是否存在全表扫描、索引未命中等问题。常见场景包括:
- 复杂的连表查询导致性能下降;
- 缺少合适的索引;
- 数据量过大但查询条件不明确。解决方法是优化SQL语句,添加索引,或者调整查询逻辑。”
3. Mysql索引相关
问题:Mysql索引底层原理是什么?联合索引的作用是什么?
回答思路:
- 解释B+树结构。
- 说明联合索引的优势和使用注意事项。
示例回答:“MySQL的索引底层是基于B+树结构实现的。B+树的特点是所有数据存储在叶子节点上,便于范围查询和排序。联合索引的作用是可以通过组合多个字段来提高查询效率,减少索引占用的空间。使用时需要注意最左匹配原则,即查询条件必须从联合索引的第一个字段开始匹配,否则后续字段的索引将失效。”
4. Kafka相关
问题:Kafka如何保证数据不丢失?如果MySQL和Redis通过Kafka解耦后数据不一致怎么办?
回答思路:
- 阐述Kafka的可靠性机制。
- 提出数据一致性解决方案。
示例回答:“Kafka可以通过以下方式保证数据不丢失:
- 设置
acks=all
,确保消息被所有副本确认; - 调整
min.insync.replicas
参数,确保写入至少N个副本; - 开启WAL(Write-Ahead Log),记录每条消息的偏移量。如果MySQL和Redis通过Kafka解耦后出现数据不一致,可以通过引入对账任务定期校验数据一致性,并修复差异。”
三、项目经验相关
1. 项目介绍
问题:介绍一下你的项目经历。
回答思路:
- 描述项目的背景和目标。
- 重点强调自己负责的核心模块和技术难点。
- 提到解决的问题和取得的成果。
示例回答:“我参与了一个基于Spring Cloud的电商平台项目,主要负责用户登录模块和订单管理模块。在用户登录模块中,我实现了JWT令牌认证机制,确保用户的会话安全;在订单管理模块中,我优化了高并发场景下的库存扣减逻辑,避免了超卖问题。最终,我们的系统在双十一大促期间成功承载了超过10万QPS的流量。”
2. Redis常见数据类型
问题:Redis有哪些常见数据类型?它们的底层实现是什么?
回答思路:
- 列举Redis的主要数据类型。
- 简要说明每种类型的底层实现。
示例回答:“Redis的常见数据类型包括String、Hash、List、Set和ZSet。
- String底层是一个简单的字符串;
- Hash底层是哈希表;
- List底层是双向链表;
- Set底层是哈希表;
- ZSet底层是跳跃表+哈希表,用于支持有序集合的操作。”
3. 布隆过滤器
问题:布隆过滤器是什么?能消除误判率吗?
回答思路:
- 定义布隆过滤器。
- 解释误判率的概念及降低方法。
示例回答:“布隆过滤器是一种空间高效的概率型数据结构,用于判断元素是否存在于集合中。它的特点是速度快、内存占用低,但可能会产生误判(即判断存在但实际上不存在)。误判率无法完全消除,但可以通过增加位数组大小或调整哈希函数数量来降低误判率。”
四、八股知识
1. 线程池相关
问题:线程池的核心参数有哪些?常见的拒绝策略有哪些?
回答思路:
- 列举核心参数及其作用。
- 说明常见的拒绝策略及其适用场景。
示例回答:“线程池的核心参数包括:
corePoolSize
:核心线程数;maximumPoolSize
:最大线程数;keepAliveTime
:空闲线程存活时间;workQueue
:任务队列。常见的拒绝策略包括:AbortPolicy
:直接抛出异常;CallerRunsPolicy
:由调用线程执行任务;DiscardPolicy
:直接丢弃任务;DiscardOldestPolicy
:丢弃队列中最旧的任务。”
2. JVM相关
问题:JVM的垃圾回收器有哪些?对象晋升老年代的条件是什么?
回答思路:
- 列举常见的垃圾回收器。
- 说明对象晋升老年代的条件。
示例回答:“JVM的常见垃圾回收器包括Serial、Parallel、CMS、G1和ZGC等。对象晋升老年代的条件包括:
- 对象年龄达到阈值(默认为15);
- Survivor空间不足;
- 大对象直接进入老年代。”
五、算法题
1. 重排链表
问题:**************
回答思路:
- 找到链表中点。
- 反转后半部分链表。
- 合并前后两部分链表。
代码示例:
public void reorderList(ListNode head) { if (head == null || head.next == null) return; // Step 1: 找到链表中点 ListNode slow = head, fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } // Step 2: 反转后半部分链表 ListNode prev = null, curr = slow; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } // Step 3: 合并前后两部分链表 ListNode first = head, second = prev; while (second.next != null) { ListNode temp1 = first.next; ListNode temp2 = second.next; first.next = second; second.next = temp1; first = temp1; second = temp2; } }
六、软技能相关
1. 你的缺点是什么?
问题:你的缺点是什么?
回答思路:
- 提出一个真实的缺点(与岗位能力相关)。
- 表明你已经意识到并正在改进。
示例回答:“我的缺点是有时候过于埋头苦干,缺少与团队的沟通交流。但在实习期间,我已经意识到这一点,并学会了在复杂需求下先与同事讨论,理清思路后再动手。同时,遇到问题时我会优先尝试通过论坛或AI工具寻找解决方案,实在解决不了才会寻求同事的帮助。”