美团财务一面 挂
2024.09.13
面了一个多小时
秒挂😥
都是结合项目问的(以下答案为后期收集,并不完全是面试过程中我的回答,因为是自己收集的,也不一定完全正确)
1.threadlocal,项目中具体应用
实在没用到的话,可以讲讲securityContextHolder,拿来存储解析jwt后的用户信息,基本上每个项目都会涉及登陆校验吧
2.mysql主从原理,有哪些模式,主从数据因为网络或者主库写入过快不同步怎么处理
1.模式:小林coding里面有(同步异步半同步)
2.避免主从延迟:强制将读请求路由到主库处理
3.mysql锁,一条语句怎么判断加了什么锁,不同索引加的锁是什么。多线程下锁是什么情况,两个语句对同一个行进行操作加了什么锁 mysql怎么解决竞争,秒杀项目用乐观锁版本号会有什么问题,怎么解决(秒杀我说把库存放redis,他说不讨论那种情况,就讨论mysql中怎么处理,实际上我压根没写秒杀项目)
以下来自小林coding与javaGuide
1.锁:全局锁、表锁、行锁。
行锁又分为:
- 记录锁(Record Lock):单个行记录上的锁、有S锁和X锁,满足读写互斥,写写互斥
- 间隙锁(Gap Lock):锁定一个范围,不包括记录本身、
- 临键锁(Next-Key Lock):Record Lock+Gap Lock,锁定一个范围,包含记录本身,主要目的是为了解决幻读问题。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。
2.不同索引加什么锁:在 InnoDB 默认的隔离级别 REPEATABLE-READ 下,行锁默认使用的是 Next-Key Lock。但是,如果操作的索引是唯一索引或主键,则加Record Lock(引擎进行了优化),即仅锁住索引本身,而不是范围。
3.多线程下锁:
两个线程的update语句同时处理一行数据:事务A添加行级锁中的X记录锁,事务B产生阻塞
其他补充:
- 两条update语句处理一张表的不同的主键范围的记录,一个<10,一个>15:不阻塞,锁住范围不相交
- 如果范围更新条件不是主键或索引:事务A没有用到索引则全表扫描,全部索引都加行锁,事务B阻塞
4.秒杀问题:版本号冲突无限重试,频繁事务回滚
解决:
- 限制重试次数:可以设定一个合理的重试次数上限,超过这个次数就不再重试,而是直接返回给用户“商品已售罄”的信息。
- 使用悲观锁:在一些极端高并发的场景下,可以考虑使用悲观锁(Pessimistic Locking)。悲观锁会在事务开始时就锁定需要的数据,直到事务结束。这种方法可以确保数据的一致性,但是会降低系统的并发能力。
4.乐观锁与悲观锁,各自优缺点,java中锁哪些乐观哪些悲观,sync为什么要用轻量级锁和偏向锁,分别又是怎么回事,锁膨胀怎么回事,mysql怎么加乐观锁和悲观锁。使用轻量级锁和偏向锁是如何得出效率优化的结论的
如何得出效率优化的结论:使用轻量级锁和偏向锁可以减少在无竞争情况下的锁开销,因为它们避免了重量级锁带来的系统调用和上下文切换。通过减少锁的获取和释放成本,可以显著提升并发性能。这些优化结论是通过基准测试(benchmarking)和性能分析工具得出的,通过对不同锁机制的性能进行对比,可以观察到在无竞争或低竞争情况下,轻量级锁和偏向锁带来的性能优势。
5.sql优化,explain输出解释,mysql怎么指定走某个索引,为什么要小表驱动大表
1.指定索引:force index
SELECT * FROM table_name FORCE INDEX (index_name) WHERE condition;
2.为什么小驱动大:**小表驱动大表速度快的前提是:**两个表上根据主/外键建立了索引,这样在根据某一条数据查找B+树时,速度就会大大提高,若没有建立索引,则两个表无论谁当作主表,查找数据的次数都是一样的
select * from a join b on a.bid =b.id a表10000数据,b表20数据
小驱大:查找次数 20+ log10000
for 20条数据 匹配10000数据(根据on a.bid=b.id的连接条件,进行B+树查找)
大驱小:查找次数 10000+ log20
for 10000条数据 匹配20条数据(根据on a.bid=b.id的连接条件,进行B+树查找)
6.联合索引与普通索引区别,这俩个索引选择的优缺点对比。为什么大字段要建立前缀索引。频繁更新字段和低区分度字段为什么不适合建立索引。不同索引选择会影响什么
为什么前缀:
- 节省空间:相对于完整字段的索引,前缀索引占用的存储空间更小。
- 提高插入和更新速度:由于索引的大小较小,插入和更新数据时需要更少的磁盘I/O操作。
- 降低维护成本:较小的索引更容易保持高效,有助于降低数据库的维护成本。
频繁更新字段不适合建立索引:
- 增加维护成本:每当字段被更新时,索引也需要更新。如果字段频繁更新,这会增加维护索引的成本。
- 降低性能:频繁的索引维护操作会降低插入、更新和删除操作的性能。
低区分度字段不适合建立索引:
- 选择性差:如果一个字段的值分布非常集中,那么该字段的选择性很差,索引的效果不明显。
- 索引利用率低:低区分度字段的索引可能不会被优化器选择使用,因为使用索引可能不会显著减少需要扫描的数据量。
7.b+树 16k会影响哪些东西
还是多看看小林coding吧
16k是恒定的,不同类型主键可能导致分支数量不同(bigint与varchar)
聚合索引使用主键排序 每页16k 主键越小 每页数据更多 减少io 理论加快查询速度
8.4种引用的区别。软引用和弱引用在新生代会被回收吗
跟新生代还是老年代无关,跟他们自己的特性有关
9.mvcc解决了什么,幻读场景举例,怎么解决的,但是哪一部分又解决不了,为什么要使用mvcc,mvcc这种多线程竞争条件下不是会产生一些阻塞问题吗,为什么还要选择。
还是多看看javaGuide里面的MVCC这部分吧
是否解决幻读这个问题还是多看看小林coding的这部分吧
N.其他忘了,想起来再补充
手撕:前k的高频词汇但是改了点东西,最后求出来的还需要按照字母序排序。