首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
哈哈哈哈哈哈开心
门头沟学院 Java
发布于北京
关注
已关注
取消关注
@BAT后端川哥:
字节飞书后端一面不知道凉不凉经|讲解
挑选了一篇牛客上的面经给大家做讲解分析和学习指引,期望对大家有所帮助~本文也是《热门面经讲解》系列文章之一,大家可以持续关注原帖链接本文主要涉及大量数据库mysql的考察,也比较有参考意义。所以结合这些题目,给大家指引了系统且高效的学习资料下面开始~1. 实现一个cache,包括LRU算法和在x秒后过期解析:LRU 属于常考题, 大家需要重点掌握;Java 可以用 LinkedHashMap + ScheduledExecutorService实现参考回答:import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class LRUCacheWithExpiration<K, V> { // 缓存的最大容量 private final int capacity; // 缓存项的过期时间(秒) private final long expirationTimeInSeconds; // 使用LinkedHashMap实现LRU缓存,accessOrder设置为true以启用LRU顺序 private final LinkedHashMap<K, CacheEntry<V>> cacheMap; // 定时任务执行器,用于清理过期的缓存项 private final ScheduledExecutorService expirationExecutor; // 内部类CacheEntry,用于存储缓存值和过期时间 private static class CacheEntry<V> { V value; long expirationTime; CacheEntry(V value, long expirationTime) { this.value = value; this.expirationTime = expirationTime; } } // 构造函数 public LRUCacheWithExpiration(int capacity, long expirationTimeInSeconds) { this.capacity = capacity; this.expirationTimeInSeconds = expirationTimeInSeconds; // 初始化LRU缓存,设置accessOrder为true,以便按访问顺序进行LRU操作 this.cacheMap = new LinkedHashMap<>(capacity, 0.75f, true) { // 重写removeEldestEntry方法,当Map大小超过指定容量时,删除最老的元素 @Override protected boolean removeEldestEntry(Map.Entry<K, CacheEntry<V>> eldest) { return size() > LRUCacheWithExpiration.this.capacity; } }; // 初始化定时任务执行器 this.expirationExecutor = Executors.newSingleThreadScheduledExecutor(); // 安排定时任务,每隔expirationTimeInSeconds秒执行一次清理过期缓存项的操作 this.expirationExecutor.scheduleAtFixedRate(this::evictExpiredEntries, expirationTimeInSeconds, expirationTimeInSeconds, TimeUnit.SECONDS); } // 获取缓存项 public synchronized V get(K key) { CacheEntry<V> entry = cacheMap.get(key); if (entry == null || isExpired(entry.expirationTime)) { // 缓存项不存在或已过期,返回null return null; } // 更新缓存项的访问顺序(移到尾部,表示最近访问) cacheMap.remove(key); cacheMap.put(key, entry); // 返回缓存值 return entry.value; } // 添加或更新缓存项 public synchronized void put(K key, V value) { // 创建新的缓存项,设置过期时间 CacheEntry<V> newEntry = new CacheEntry<>(value, System.currentTimeMillis() + (expirationTimeInSeconds * 1000)); // 将新的缓存项添加到LRU缓存中,如果缓存已满,则会自动删除最老的元素 cacheMap.put(key, newEntry); } // 清理过期缓存项的方法 private void evictExpiredEntries() { long currentTime = System.currentTimeMillis(); // 遍历缓存,移除已过期的缓存项 cacheMap.entrySet().removeIf(entry -> isExpired(entry.getValue().expirationTime)); } // 判断缓存项是否过期 private boolean isExpired(long expirationTime) { return expirationTime <= System.currentTimeMillis(); } // 关闭缓存,停止定时任务执行器 public void close() { expirationExecutor.shutdown(); try { if (!expirationExecutor.awaitTermination(60, TimeUnit.SECONDS)) { expirationExecutor.shutdownNow(); } } catch (InterruptedException e) { expirationExecutor.shutdownNow(); Thread.currentThread().interrupt(); } } }学习指引:牛客题目:BM100 设计LRU缓存结构2. MySQL事务:ACID四个特性?原子性是如何保证的?隔离性是怎么保证的?四个隔离级别?解析:mysql事务,简单且重要,校招考察频率高,必须掌握。参考回答:MySQL事务的ACID四个特性:1.原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。2.一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。3.隔离性(Isolation):通常,一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。4.持久性(Durability):一旦事务提交,则其结果永久保存在数据库中。原子性是如何保证的?原子性是通过日志(如MySQL的redo log和undo log)和锁机制来保证的。当事务开始时,MySQL会先记录redo log,表示事务执行过程中的修改。如果事务成功,这些修改会被永久写入数据文件。如果事务失败,MySQL会使用undo log来回滚事务,恢复到事务开始前的状态,从而保证原子性。隔离性是怎么保证的?隔离性是通过数据库的多版本并发控制(MVCC) 和 锁机制 来实现的。MVCC允许读取者在不阻塞写入者的情况下读取数据,并通过保存数据的多个版本来确保事务之间的隔离。锁机制则用于在必要时阻止其他事务访问特定数据,直到当前事务完成。四个隔离级别:1.读未提交(Read Uncommitted):事务可以读取尚未提交的其他事务的数据。这是隔离级别最低的一种,可能会导致很多问题,如脏读、不可重复读和幻读。2.读已提交(Read Committed):一个事务只能读取已经提交的事务的数据。这可以避免脏读,但可能会导致不可重复读和幻读。3.可重复读(Repeatable Read):这是MySQL的默认隔离级别。在这个级别,事务在开始时取得的快照数据在事务内是保持一致的,即使其他事务修改了数据。这可以避免脏读和不可重复读,但在某些情况下仍可能导致幻读。但在InnoDB存储引擎中,由于使用了MVCC,可重复读级别实际上可以防止幻读。4.串行化(Serializable):这是隔离级别最高的一种。事务串行化执行,事务之间不可能产生干扰。这可以避免脏读、不可重复读和幻读,但会大大降低并发性能。学习指引小林 coding|图解Mysql|事务篇3. 为什么读已提交会的时候其他事务读取不到修改了的数据?解析:考察“读已提交”这种隔离级别下是如何工作的,常考面试题,大家需要理解原理之后用自己的话来描述。同时还有“可重复读”隔离级别下是如何工作的也要重点掌握。参考回答:读已提交(Read Committed)隔离级别下,其他事务读取不到当前事务修改的数据,是因为在当前事务提交之前,其对数据的修改对其他事务是不可见的。InnoDB通过多版本并发控制(MVCC)机制来实现这种隔离性。在每个事务开始时,InnoDB会为其创建一个唯一的事务ID,并使用这个ID来标记事务中所有读取和修改的数据行。当其他事务尝试读取这些数据行时,InnoDB会根据其事务ID和行上的标记来判断这些行是否对当前事务可见。如果数据行的修改是在当前事务开始之后提交的,那么这些修改对其他事务是不可见的,因为它们属于不同的版本。这样,即使在读已提交隔离级别下,InnoDB也能保证事务之间的隔离性,避免脏读问题。学习指引Mysql事务:可重复读是如何工作的?Mysql事务:读提交是如何工作的?4. 索引的数据结构,为什么查询快?解析:考察mysql InnoDB引擎的数据结构B+树,需要回答出来为什么要选用B+树,而不是B树,也不是二叉树。 为什么B+树比他们合适,比他们块。参考回答:MySQL 默认的存储引擎 InnoDB 采用的是 B+ 作为索引的数据结构,原因有:1.B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。(为什么不选二叉树也有类似原因)2.B+ 树有大量的冗余节点(所有非叶子节点都是冗余索引),这些冗余索引让 B+ 树在插入、删除的效率都更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化;3.B+ 树叶子节点之间用链表连接了起来,有利于范围查询,而 B 树要实现范围查询,因此只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率不如 B+ 树。学习指引:系统学习小林 coding|为什么 MySQL 采用 B+ 树作为索引?5.聚族索引和非聚族索引有什么区别,是不是聚族索引更好?解析:属于mysql中的两个重要概念,必须掌握。另外在innodb中,非聚族索引也指二级索引。参考回答:聚簇索引(Clustered Index)和非聚簇索引(Non-Clustered Index)是数据库中两种常见的索引类型,它们在数据结构、数据存储方式和性能上有显著的区别。聚簇索引1.数据存储:聚簇索引决定了表中数据的物理存储顺序。换句话说,聚簇索引中的键值与数据行在磁盘上是存放在一起的。因此,一个表只能有一个聚簇索引。2.性能:由于聚簇索引的键值和数据行存储在一起,所以范围查询非常快。当查询连续的数据时,磁盘I/O操作可以最小化。3.主键:在InnoDB存储引擎中,如果表定义了主键,InnoDB会自动为主键创建聚簇索引,除非明确指定其他列。非聚簇索引:1.数据存储:非聚簇索引与数据的物理存储顺序无关。它只包含键值和指向数据行的指针。这意味着非聚簇索引和表数据是分开存储的。2.性能:非聚簇索引需要额外的磁盘空间来存储索引结构,并且在执行查询时可能需要更多的磁盘I/O操作,因为索引和数据可能分布在不同的磁盘位置。3.多个索引:一个表可以有多个非聚簇索引,因为非聚簇索引不决定数据的物理存储顺序。聚簇索引和非聚簇索引的比较查询性能:聚簇索引通常对范围查询更为高效,因为它将数据按照索引键值的顺序存储。然而,非聚簇索引可能在某些情况下提供更好的性能,特别是当索引覆盖查询所需的所有列时(即覆盖索引)。更新开销:当数据行的键值(即聚簇索引的键值)发生变化时,聚簇索引可能需要重新组织数据的存储顺序,这可能会导致更大的更新开销。而非聚簇索引只需要更新索引条目。学习指引系统学习Mysql:索引的分类6.出现慢查询要怎么优化?解析:面试重点:索引优化。可以先讲一些策略明,不深入细节,面试官细问了再详细说。参考回答:常见优化索引的方法:1.前缀索引优化;2.覆盖索引优化;3.主键索引最好是自增的;4.索引最好设置为 NOT NULL5.防止索引失效;学习指引:如果不清楚每一种优化方法原理,看这篇就清楚了有什么优化索引的方法?7. a b c三个字段怎么设计他们的索引顺序?解析:这种题目面试官一般会给出一条sql查询的条件语句,然后让你据此来分析联合索引应该怎么建立,你在回答的时候除了要答出具体的顺序,还要讲出每个字段的作用。 例如"where a>50 and b=20 and c=20 order by d 怎么建立联合索引?"例如:参考回答:索引顺序(bcda)。因为这时候 b 和 c 字段都能走索引,而且 d 能利用索引有序性,避免 filesort,最后的 a 字段虽然无法走索引,但是可以利用索引下推,减少回表的次数。学习指引一文搞懂MySQL索引应用篇:建立索引的正确姿势与使用索引的最佳指南!8. 数据库中的锁解析:数据库中的锁也是面试重点。看一篇资料就够了参考回答:基于锁的属性分类:1.共享锁(Share Lock,S锁):当一个事务为数据加上读锁之后,其他事务只能对该数据加读锁,而不能对数据加写锁,直到所有的读锁释放之后其他事务才能对其进行加持写锁。共享锁主要用于支持并发的读取数据,读取数据的时候不支持修改,避免出现重复读的问题。2.排他锁(Exclusive Lock,X锁):当一个事务为数据加上写锁时,其他请求将不能再为数据加任何锁,直到该锁释放之后,其他事务才能对数据进行加锁。排他锁避免了出现脏数据和脏读的问题。基于锁的粒度分类:1.行级锁(InnoDB):对数据库表中的某一行或多行记录进行加锁,使得其他事务在当前事务释放锁之前无法修改这些记录。2.表级锁(InnoDB、MyISAM):对整个数据库表进行加锁,使得其他事务在当前事务释放锁之前无法对该表进行访问或修改。表级锁包括表共享读锁和表独占写锁。3.页级锁(InnoDB、BDB引擎):是一种介于行级锁和表级锁之间的锁,它锁定的是数据页而不是整个表或单个行。页级锁在某些情况下可以减少锁的竞争,提高并发性能。4.记录锁:行级锁的一种,单条记录上加的锁。5.间隙锁(InnoDB):在索引记录之间的间隙上加的锁,主要用于防止两个事务同时向一个范围内插入新的记录,产生幻读的情况。6.临键锁(Next-Key Locks):是InnoDB的行级锁和间隙锁的结合,即除了锁住记录本身,还要再锁住索引记录前面的间隙。基于锁的状态分类:1.意向共享锁(Intention Shared Lock):事务有意向对表中的某些行加共享锁。2.意向排他锁(Intention Exclusive Lock):事务有意向对表中的某些行加排他锁。全局锁:对整个数据库进行加锁,阻止其他用户对该数据库的访问和修改。例如,当需要让整个数据库进行备份时,可以使用全局锁。但全局锁会严重影响并发性能,应谨慎使用。学习指引小林coding 一文搞懂。MySQL 有哪些锁?9. 缓存穿透、缓存雪崩说一下,缓存击穿要怎么处理解析:缓存本省是一个优化利器,也是面试当中的重点。引入缓存之后,缓存本身也会带来一些问题,缓存穿透、缓存雪崩就是需要解决的问题。参考回答:缓存穿透:指查询一个一定不存在的数据,由于缓存不命中时需要从数据库查询,而数据库中也无此数据,因此无法写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,给数据库带来压力。对于恶意利用此漏洞的攻击,甚至可能压垮数据库。其解决方案包括但不限于:对查询的key进行合法性校验,比如长度、格式等,对不合法的key直接拒绝服务。对不存在的key也进行缓存,设置一个较短的过期时间即可。使用布隆过滤器,将所有可能存在的key预先加载到过滤器中,在查询前先进行过滤,如果不存在则直接返回,避免对数据库的查询。缓存雪崩:当缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。解决方案包括:给缓存的失效时间加上一个随机值,避免集体失效。使用互斥锁,当缓存失效的时候,不是立即去load db,而是先使用缓存工具的某个机制,比如Redis的SETNX去设置一个锁,当操作返回成功时,再去load db并放入缓存;否则,就重试获取缓存值。采用双缓存策略,即设置两级缓存,原始缓存和拷贝缓存,原始缓存失效时,可以访问拷贝缓存,原始缓存与拷贝缓存,定期同步数据,保证一致。缓存击穿:是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。其解决方案包括:设置热点数据永远不过期。使用互斥锁,当缓存失效的时候,不是立即去load db,而是通过缓存工具的某个机制(如Redis的SETNX)去设置一个锁,当操作返回成功时,再去load db并放入缓存;否则,就重试获取缓存值。学习指引系统学习“缓存篇”:什么是缓存雪崩、缓存击穿?10. 为什么Redis速度比较快解析:redis高频面试题之一参考回答:Redis速度快的原因主要有以下几点:首先,Redis是一个内存数据库,所有的数据都存储在内存中,这大大减少了磁盘I/O的延迟,使得数据读写速度非常快;其次,Redis使用单线程模型,避免了线程切换和锁竞争等开销,能够更高效地利用CPU资源;此外,Redis提供了多种高效的数据结构,如字符串、哈希表、列表、集合等,这些数据结构都经过了高度优化,能够实现快速的读写操作;最后,Redis还使用了异步I/O模型,能够同时处理多个并发请求,提高了系统的吞吐量。这些因素共同作用,使得Redis在处理大量读写请求时表现出色,成为了一个高性能的键值数据库。学习指引系统学习RedisRedis为什么快?往期相关文章推荐阅读面经讲解系列:某跨境电商独角兽Java实习面经|讲解阿里云 实习面经(已OC) 一面面经|讲解师兄经验分享:一篇真正的面经:你真的准备好实习“面试”了吗?文中学习指引提到的很多经典书籍(Java,JVM,数据库,Redis等等),我都有电子版,需要的同学可以私信我。其他 学习指引/简历修改相关问题也可以咨询我,抽空安排!
点赞 19
评论 0
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
07-18 10:49
南京航空航天大学 机械工程师
体验到了小鹏的ai面
第一部分是60道心理测评,每道题显示一分钟第二部分是行测,10个题目,三四个计算题,两三个图形题,两三个找规律,两三个言语,一点都没做过的建议牛客刷一下吧还是第三部分是自我介绍+职业规划以及对公司以及岗位的了解第四部分是问人生低谷怎么度过,最近一次因为好奇心驱动学习新技能是啥时候怎么学的类似的问题,但是每一个大问题都会追问。
查看4道真题和解析
点赞
评论
收藏
分享
07-22 17:56
郑州大学 机械工程师
速腾提前批-挂
感谢信一步步更新,提前批base深圳,投递秒挂!双9也不行,只要项目对口
投递速腾聚创等公司10个岗位
点赞
评论
收藏
分享
06-16 19:09
河南开封科技传媒学院 Java
26届暑假想找java实习
面试官要完简历之后大部分都是已读不回,大佬能帮我看看我的简历有什么问题吗
牛客83700679...:
简历抄别人的,然后再投,有反馈就是简历不行,没反馈就是学历不行,多投多改只要技术不差机会总会有的
点赞
评论
收藏
分享
07-22 22:17
已编辑
猎豹移动_AI 生产力部门_大模型应用开发工程师(实习员工)
根本找不到工作,投简历秒拒😂
秋招咋办啊。°(°¯᷄◠¯᷅°)°。
野猪不是猪🐗:
包装的有点过了
你的简历改到第几版了
点赞
评论
收藏
分享
07-22 11:07
门头沟学院 Java
京东26校招
投递2h后收到测评有没有佬知道这个测评是海测吗
投递京东等公司10个岗位
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
实习包装不是吹牛皮,要怎么包装看这里
5.1W
2
...
百度一二面凉经
4914
3
...
河南萌新联赛2025第(二)场:河南农业大学_题解
3437
4
...
再再再再强调一遍!秋招不要装逼
2998
5
...
字节实习第三天10点下班,哭了
2998
6
...
百度一面面经7.14
2595
7
...
入我滴滴!早十晚六 !
2569
8
...
26届米哈游秋招提前批面经(游戏客户端)已挂
1969
9
...
滴滴提前批
1881
10
...
刷力扣被旁边的实习生举报
1847
创作者周榜
更多
正在热议
更多
#
哪些公司开提前批了?
#
20116次浏览
225人参与
#
实习如何「偷」产出?
#
43248次浏览
1069人参与
#
除了主业以外,你还有哪些其他收入?
#
9750次浏览
172人参与
#
校招阶段,学历VS技术哪个更重要?
#
15194次浏览
170人参与
#
不卡学历的大厂有哪些?
#
23734次浏览
186人参与
#
职场新人体验
#
20258次浏览
191人参与
#
风评不好的公司,你会去吗?
#
49986次浏览
375人参与
#
实习打杂,要跑路吗
#
16442次浏览
193人参与
#
硬件人求职现状
#
434037次浏览
4539人参与
#
校园里的破防时刻
#
9465次浏览
108人参与
#
你今年的平均薪资是多少?
#
133366次浏览
680人参与
#
社恐入职新公司如何融入团队
#
11554次浏览
63人参与
#
腾讯音乐求职进展汇总
#
97753次浏览
570人参与
#
你投递的公司有几家约面了?
#
108343次浏览
775人参与
#
歌尔求职进展汇总
#
58185次浏览
339人参与
#
Offer比较,你最看重什么?
#
191205次浏览
1300人参与
#
你的秋招第一面感觉怎么样
#
74660次浏览
575人参与
#
正在实习的碎碎念
#
1453627次浏览
13467人参与
#
实习时,大家都怎么称呼自己的mentor?
#
43613次浏览
273人参与
#
摸鱼被leader发现了怎么办
#
61135次浏览
371人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务