# 面试题

118 篇文章

与「面试题」相关的全部文章。

RocketMQ 的集群消费和广播消费?

一、集群消费(CLUSTERING) 同一条消息只被消费组内的一个消费者消费。 负载均衡:队列在消费者之间分配。 实际生产中最常用。 二、广播消费(BROADCASTING) 同一条消息被消费组内所有消费者都消费一次。 每个消费者都消费全量消息。 适用于需要所有节点都处理的场景,如配置刷新、缓存失效

RocketMQ 和 Kafka 的区别?

一、对比 维度 RocketMQ Kafka 开发语言 Java Java/Scala 消息模型 Topic/Queue Topic/Partition 顺序消息 支持 支持(分区内) 延迟消息 支持 不原生支持 事务消息 支持 不支持 吞吐量 十万级 百万级 适用场景 业务消息、事务 日志、大数据

RocketMQ 如何保证消息不丢?

一、生产端不丢 同步发送:等待 Broker ACK,失败重试。 开启重试机制:retryTimesWhenSendFailed。 事务消息保证本地事务与消息发送一致。 二、Broker 不丢 同步刷盘:消息写入磁盘才返回成功(flushDiskType=SYNC_FLUSH)。 同步复制:主从都写

RocketMQ 支持哪些消息类型?

一、普通消息 最基本的消息,发完即走。 二、顺序消息 同一队列内消息严格有序。发送时用 MessageQueueSelector 把同一业务 key 的消息发到同一队列,消费时同一队列只一个线程消费。 三、延迟消息 消息发送后延迟一段时间才投递。RocketMQ 支持固定延迟级别(1s/5s/10s

RocketMQ 的整体架构?

一、四大角色 Producer:消息生产者。 Consumer:消息消费者,支持 Push/Pull 两种模式。 NameServer:路由注册中心,无状态,可集群部署,节点间不通信。 Broker:消息存储与转发,可主从部署。 二、工作流程 NameServer 启动,Broker 启动后向所有

CountDownLatch 和 CyclicBarrier 的区别?

一、CountDownLatch 一个或多个线程等待其他线程完成后再继续。 用计数器实现,countDown() 减 1,await() 等待归零。 一次性,归零后不能重置。 场景:主线程等待多个子任务完成。 二、CyclicBarrier 一组线程互相等待,全部到达屏障点后一起继续。 可循环使用,

volatile 关键字的作用?

一、两大作用 可见性:被 volatile 修饰的变量,一个线程修改后其他线程立即可见。实现:写入时立即刷新主内存,读取时从主内存重新加载。 禁止指令重排:在读写操作前后插入内存屏障。 二、不保证原子性 volatile int count = 0; count++; // 不是原子操作,多线程

AQS 的原理是什么?

一、定义 AQS(AbstractQueuedSynchronizer)是 JUC 锁的基础框架,用一个 int 状态变量(state)和一个 FIFO 等待队列实现同步。 二、核心 state:同步状态,0 表示空闲,>0 表示被占用。 CLH 队列:未获取锁的线程封装成 Node 入队,自旋 +

线程池的核心参数与工作流程?

一、七大核心参数 corePoolSize:核心线程数,即使空闲也保留。 maximumPoolSize:最大线程数。 keepAliveTime:非核心线程空闲存活时间。 unit:时间单位。 workQueue:阻塞队列。 threadFactory:线程工厂。 handler:拒绝策略。 二、

synchronized 和 ReentrantLock 的区别?

一、底层实现 synchronized:JVM 级,字节码指令 monitorenter/monitorexit,依赖对象头的 Mark Word。 ReentrantLock:JDK 级,基于 AQS(AbstractQueuedSynchronizer)实现。 二、对比 维度 synchroni

常见的 OOM 有哪些?

一、Java heap space 堆内存不足,对象太多或内存泄漏。排查:dump 堆快照,用 MAT 分析大对象/泄漏点。 二、GC overhead limit exceeded GC 耗时过长(98% 时间用于 GC 且回收不到 2% 内存)。通常是堆太小或内存泄漏。 三、Java.lang.

类加载过程是怎样的?

一、五个阶段 加载:通过类的全限定名获取二进制字节流,在内存中生成 Class 对象。 验证:校验字节码的合法性(魔数、版本、语义)。 准备:为类的静态变量分配内存并赋默认值(零值),final static 在编译期已赋值。 解析:把符号引用替换为直接引用。 初始化:执行 <clinit> 方法,

CMS 和 G1 的区别?

一、CMS 基于标记-清除算法。 以最短停顿时间为目标。 流程:初始标记(STW)→ 并发标记 → 重新标记(STW)→ 并发清除。 缺点:内存碎片、并发阶段消耗 CPU、浮动垃圾、可能 Concurrent Mode Failure 退化为 Serial Old。 二、G1 把堆分成多个 Regi

常见的垃圾回收算法?

一、判断对象是否可回收 引用计数法:对象被引用计数 +1,为 0 则回收。无法解决循环引用。 可达性分析:从 GC Roots 出发,不可达的对象可回收。GC Roots 包括栈中引用、静态变量、常量、JNI 引用。 二、回收算法 标记-清除:标记存活对象,清除垃圾。缺点:内存碎片。 标记-复制:内

JVM 运行时内存结构?

一、线程私有 程序计数器:记录当前线程执行的字节码行号,唯一不会 OOM 的区域。 虚拟机栈:每个方法调用创建一个栈帧,存局部变量、操作数栈、动态链接。栈深度过深抛 StackOverflowError。 本地方法栈:为 native 方法服务。 二、线程共享 堆:对象实例和数组,GC 主要区域,可

Redis 为什么单线程还这么快?

一、核心原因 纯内存操作:数据在内存中,访问速度极快。 I/O 多路复用:用 epoll 处理大量并发连接,单线程也能处理高并发。 避免上下文切换:单线程没有线程切换开销,也没有锁竞争。 二、Redis 6.0 多线程 Redis 6.0 引入多线程,但只用于网络 I/O 的读写,命令执行仍是单线程

Redis 如何实现分布式锁?

一、基本实现 SET lock_key unique_value NX EX 30 NX:key 不存在才设置。 EX:过期时间,防止死锁。 unique_value:释放锁时校验,防止误删别人的锁。 二、释放锁(Lua 脚本保证原子) if redis.call("get", KEYS[1])

缓存穿透、击穿、雪崩及解决方案?

一、缓存穿透 查询不存在的数据,缓存和数据库都没有,请求全打到数据库。 解决方案: - 缓存空值(设置较短过期时间)。 - 布隆过滤器,不存在的 key 直接拦截。 二、缓存击穿 热点 key 过期瞬间,大量并发请求打到数据库。 解决方案: - 互斥锁(setnx),只有一个请求查库并回填缓存。 -

Redis 的持久化方式有哪些?

一、RDB(快照) 原理:在某个时间点把内存数据序列化写入 dump.rdb。 触发:save(阻塞)、bgsave(fork 子进程)、自动配置(save 900 1)。 优点:文件紧凑、恢复快。 缺点:可能丢失最后一次快照后的数据。 二、AOF(追加日志) 原理:把写命令追加到 appendon

Redis 常见数据结构及使用场景?

一、String 最基础,存字符串/整数/二进制。场景:缓存、计数器(incr)、分布式锁(setnx)、限流。 二、List 双向链表。场景:消息队列(lpush/brpop)、最新列表。 三、Hash 键值对集合。场景:对象存储(用户信息)、购物车。 四、Set 无序去重集合。场景:标签、共同好