岗位索引

后端开发工程师面试题库第 3 页

后端开发面试题解析,覆盖缓存、数据库、分布式和系统设计基础。

378 道题 15 个公司 134 个知识点

后端开发相关面试题第 3 页

为什么Redis的速度这么快?

Redis 快不是单一原因,而是数据结构、内存访问、事件模型、网络处理和工程取舍共同作用的结果。面试回答时不能只说“因为它是内存数据库”或“因为单线程”,更关键的是说明:绝大多数请求走内存,核心命令复杂度低;单线程事件循环减少锁竞争和上下文切换;I/O 多路复用提升并发连接处理能力;协议和数据结构实现轻量;同时 Redis 也通过持久化、复制、集群等机制在速度与可靠性之间做取舍。

集群环境怎么更新本地缓存?

集群环境更新本地缓存的核心是把进程内缓存视为性能优化层,而不是共享事实源。常见方案是数据库作为最终事实源,Redis 作为跨节点共享缓存,本地缓存作为单机热点加速层;数据变更后通过可靠事件广播删除各实例本地缓存,并用 TTL、版本号和补偿机制兜底。

缓存的 key 是什么?

缓存的 key 不是随手拼接的字符串,而是后端系统把业务对象、查询条件、租户环境、版本语义和一致性边界映射到缓存空间的唯一标识。一个好的缓存 key 需要同时解决可定位、可隔离、可失效、可观测、可扩展和可治理的问题,否则很容易出现串数据、删不准、热点集中、基数爆炸和线上排查困难。

热点数据怎么保证redis和db中的一致?

热点数据的 Redis 与数据库一致性,核心不是追求所有场景下绝对强一致,而是先明确业务可接受的一致性等级,再选择缓存模式、写入顺序、失效策略和补偿机制。高频面试答案应围绕 Cache Aside、先更新数据库再删除缓存、删除失败补偿、TTL 兜底、版本号防乱序、binlog/CDC 异步修复、热点保护与强一致场景降级到串行化读写展开。

redis的gossip机制?

Redis Cluster 的 Gossip 机制是集群节点之间交换状态信息的一套去中心化通信机制。每个节点不依赖中心协调者,而是通过定期向其他节点发送 PING、PONG、MEET 等消息,携带自己已知的节点元数据、槽位信息、配置纪元和故障判断结果,使整个集群逐步达成状态收敛,并用于节点发现、拓扑维护、故障疑似与故障确认。

Redis解决了什么问题?

Redis 本质上解决的是把需要极低延迟、高并发访问、临时状态管理和轻量计算的数据,从慢路径中抽出来的问题。它不是关系型数据库的替代品,而是用内存读写、丰富数据结构、过期机制、原子操作、持久化和集群能力,帮助系统降低数据库压力、提升响应速度、承载热点流量,并处理计数、排行榜、会话、限流、分布式锁等高频场景。

Redis的过期策略?

Redis 的过期策略本质上是在性能、内存回收及时性和主线程延迟之间做平衡:它不会为每个带 TTL 的键单独启动定时器,而是通过 TTL 元数据记录过期时间,再结合访问时惰性删除和后台周期性主动抽样删除来清理过期键。回答时要区分过期删除与内存淘汰,并补充持久化、复制、过期风暴和热 Key 场景下的工程治理。

说一下数据库底层数据结构B+数据,为什么用,与二叉平衡树区别 Redis怎么用的?

数据库索引常用 B+ 树,核心原因不是“查找复杂度看起来是 O(log n)”,而是它非常适合磁盘和页式存储:节点扇出高,树高低,单次查询需要的页访问次数少;叶子节点按键有序并通过链表连接,范围查询、排序扫描、分页扫描都很高效。二叉平衡树如 AVL、红黑树更适合内存中的动态查找结构,节点扇出低、树高大、局部性差,如果直接用于磁盘索引会产生大量随机 I/O。

还知道哪些缓存中间件?

缓存中间件不只有 Redis。可以按部署位置和能力分为远程内存缓存、进程内本地缓存、分布式缓存、CDN/HTTP 缓存、数据库内部缓存,以及用于削峰和结果复用的消息缓存、结果缓存。回答这题的关键不是罗列产品名,而是说明 Redis、Memcached、Caffeine、Ehcache、Hazelcast、Ignite、CDN、数据库 Buffer Pool 等分别解决什么问题,以及选型时如何比较数据结构、持久化、一致性、延迟和运维复杂度。

过去经历中怎么应对高并发或高性能场景的?

高并发或高性能场景不是考单点技术名词,而是考候选人能否把真实工程问题讲成闭环:先明确业务目标和容量指标,再通过压测和可观测性找到瓶颈,随后从流量、应用、缓存、队列、数据库、线程池、连接池、锁竞争、水平扩展和稳定性预案等层面治理,最后用结果指标证明方案有效。

锁的实现原理是什么?

锁的实现原理可以概括为:用一个可被原子修改的状态表示锁是否被占用,用所有者信息判断谁持有锁,用等待队列管理竞争失败的线程,用阻塞与唤醒降低空转成本,并通过内存屏障建立临界区内外的可见性与有序性保证。理解锁不能只停留在“加锁和解锁”两个动作,而要能讲清互斥、状态变更、线程挂起、唤醒、公平性、重入、超时、中断和竞争优化之间的关系。

可重入锁的原理?

可重入锁的核心原理是:锁不仅记录有没有被占用,还记录被哪个线程占用以及同一线程重复进入了多少次。当持有锁的线程再次请求同一把锁时,不会被自己阻塞,而是把重入计数加一;退出时计数减一,只有计数归零才真正释放锁并唤醒后续等待线程。Java 中 synchronized 和 ReentrantLock 都支持可重入,但实现层次不同:synchronized 由 JVM 管理监视器和锁记录,ReentrantLock 主要基于 AQS 的 state、独占线程 owner、等待队列、CAS 和 park/unpark 实现。

分布式锁的使用场景?

分布式锁用于解决多个进程、多个实例、多个节点同时争抢同一份业务资源时的互斥问题,典型场景包括库存扣减、定时任务去重、幂等控制和资源抢占。面试回答不能只说“防止并发”,还要讲清锁的粒度、过期时间、唯一 token、续期、释放校验、可重入、公平性,以及 Redis、ZooKeeper、数据库方案在性能、一致性和故障边界上的取舍。

线程锁锁的到底是什么?

线程锁并不是把某个线程本身锁住,也不是直接把一段代码或一个变量物理锁住。更准确地说,锁是一种同步协议:它通过某个可竞争的同步状态,约束多个线程进入临界区的顺序,从而保护共享资源及其不变量。Java 中 synchronized 竞争的是对象监视器或类对象监视器,ReentrantLock 竞争的是基于 AQS 维护的同步状态;操作系统层面的 mutex、semaphore 等竞争的是内核或用户态维护的同步状态。

MySQL 底层数据结构?

MySQL 底层数据结构在 InnoDB 中主要围绕“页、B+树索引、聚簇索引、二级索引、Buffer Pool、事务日志”展开。真正决定查询性能的不是某一个抽象结构,而是这些结构如何协同:数据按页组织,索引以 B+树维护有序访问路径,主键索引叶子节点保存完整行记录,二级索引叶子节点保存主键值,内存中的 Buffer Pool 缓存热点页,变更再通过 redo log、undo log 等机制保证事务与崩溃恢复。理解这些内容,才能解释为什么 MySQL 不直接使用普通二叉树、红黑树或单纯哈希表作为主要索引结构。

mysql慢查询优化方案?

这道题考察的不是背几个索引原则,而是候选人能否把“发现慢查询、判断瓶颈、制定优化方案、验证效果、防止回退”串成闭环。优秀回答应覆盖慢查询日志与监控定位、EXPLAIN 执行计划分析、索引设计、SQL 改写、表结构与数据规模治理、分页与排序优化、锁等待排查、缓存与业务链路优化,以及上线后的持续观测。

内存资源很宝贵,为什么不能直接访问数据库表?

不能直接访问数据库表的原因是,表不是应用进程里可随意读取的一块内存数组,而是数据库引擎管理的持久化数据结构。应用需要通过 SQL、连接、权限、索引、事务和数据库协议访问数据;数据库内部再决定从磁盘、Buffer Pool、索引页或缓存中读取哪些页。绕过数据库引擎或把全表搬到内存,会破坏一致性、并发控制、恢复能力、安全边界和资源隔离。

后端通过什么连接到数据库?

后端连接数据库的核心链路通常是:业务代码通过 ORM 或数据访问框架发起数据库操作,框架从连接池拿到连接,连接池底层使用数据库驱动,驱动按照数据库协议与数据库实例、代理或中间件建立 TCP 连接,并完成认证、参数协商、SQL 发送、结果解析、事务控制和连接复用。以 Java 后端连接 MySQL 为例,常见链路是 Service/DAO -> MyBatis/JPA/JdbcTemplate -> DataSource/HikariCP/Druid -> JDBC Driver/MySQL Connector/J -> MySQL 协议 -> MySQL Server 或数据库代理。

MySQL事务的四种特性,分别解释?

MySQL 事务的四种特性是 ACID:原子性、一致性、隔离性、持久性。在 InnoDB 中,原子性主要依赖 undo log 回滚;隔离性依赖 MVCC、ReadView 和锁;持久性主要依赖 redo log 及刷盘机制;一致性不是某一个日志单独保证的,而是由数据库约束、事务语义、隔离控制、崩溃恢复和应用正确性共同保证。

索引下推是什么?

索引下推(Index Condition Pushdown,ICP)是 MySQL 优化器把部分原本由 server 层判断的 WHERE 条件,下推到存储引擎层,在扫描二级索引时先利用索引记录中的列做过滤,再决定是否回表读取完整行。它的核心价值不是减少索引扫描本身,而是减少无效回表次数,尤其适合联合索引中部分条件不能继续用于定位范围、但仍包含在索引列里的场景。

Spring 事务失效有哪些常见场景?

Spring 事务失效不要只背 @Transactional 场景清单,核心要答出声明式事务的运行条件:方法调用必须进入 Spring AOP 代理,由 TransactionInterceptor 配合 TransactionManager 在调用前后开启、提交或回滚事务;常见失效本质上分为三类:没有经过代理、异常没有触发回滚、真实数据库资源没有加入同一个事务。

分库分表如何设计?

分库分表不是先选中间件,而是先判断单库单表在容量、吞吐、可用性、隔离性上的瓶颈,再设计一套可路由、可扩容、可治理、可回滚的数据架构。好的回答要把垂直拆分、水平拆分、分片键、路由、全局 ID、事务、查询、扩容、热点、读写分离和灰度治理串成一个完整工程方案。

B 树和 B+ 树有什么区别?

B 树和 B+ 树都是面向磁盘页设计的多路平衡搜索树,核心差异不只是数据放在哪里,而是由此带来的扇出、树高、查询路径稳定性、范围扫描能力和索引工程实现差异。数据库索引更偏好 B+ 树,因为它能用更高扇出降低磁盘访问次数,并用叶子节点顺序结构支撑范围查询、排序、覆盖索引和顺序预读。

ArrayList 和 LinkedList 有什么区别?

ArrayList 和 LinkedList 都实现了 List 接口,但核心差异来自底层结构:ArrayList 基于可扩容数组,擅长随机访问、顺序遍历和末尾追加;LinkedList 基于双向链表,单个节点插入删除本身很快,但定位节点通常需要线性遍历。面试中不能只背数组查询快、链表增删快,还要结合容量扩容、内存占用、CPU 缓存、迭代器删除、fail-fast 和真实业务场景来回答。

Spring 和 Spring Boot 有什么区别?

Spring 是基础框架和生态体系,核心价值在于 IoC 容器、AOP、事务管理、MVC、数据访问等通用能力;Spring Boot 不是替代 Spring,而是在 Spring 之上提供约定优于配置的应用启动脚手架,通过自动配置、starter 依赖、内嵌服务器、外部化配置和运行监控,降低搭建与运维成本。

ConcurrentHashMap为什么性能比较好?

ConcurrentHashMap 性能好,本质上不是因为完全没有锁,而是把锁的范围、锁的频率和锁竞争都压到了更低水平。它通过读操作无锁、写操作尽量 CAS、冲突时只锁单个桶、扩容时多线程协作迁移、计数时分散热点等方式,避免了 Hashtable 或直接给 HashMap 加 synchronized 那种全表串行化的瓶颈。回答时要区分 JDK7 的 Segment 分段锁模型和 JDK8 的 Node 数组加 CAS、synchronized 桶级锁模型。

Java 动态代理的实现原理是什么?

Java 动态代理本质上是在运行期生成一个实现目标接口的代理类,把接口方法调用统一转发给 InvocationHandler。面试回答不能只说“反射”或“运行期生成对象”,还要讲清 JDK 动态代理的接口约束、Proxy 生成代理类、方法调用链、Spring AOP 的代理选择,以及 final、private、自调用等失效边界。

Java三大特性 多态是怎么实现的?

Java 三大特性是封装、继承和多态。高质量回答不能只背三个词,而要说明它们分别解决对象状态保护、类型复用扩展、抽象行为分派的问题。多态的实现重点在方法重写、向上转型和动态绑定:编译期确认引用类型上是否存在可调用方法,运行期根据对象真实类型分派到具体实现。

HashMap 的底层实现原理是什么?

HashMap 的核心是用哈希表存储键值对,通过 key 的 hash 值定位数组桶,再在桶内处理哈希冲突。JDK 1.7 主要是数组加链表,链表采用头插法,扩容迁移时在并发场景下可能形成链表环;JDK 1.8 改为数组、链表、红黑树组合,链表采用尾插法,并在冲突严重时树化,把极端情况下的查找从线性复杂度优化到对数复杂度。

了解哪些不同 JDK 版本的新特性?

这道题考察的不是背版本号,而是能否把 JDK 演进和工程实践联系起来。回答时应先按主线概括:JDK 8 是现代 Java 的分水岭,引入 Lambda、Stream、Optional、默认方法和新的日期时间 API;JDK 9 到 10 开始模块化、集合工厂方法、JShell、接口私有方法和局部变量类型推断;JDK 11 作为常用长期支持版本,补齐 HTTP Client、字符串和文件 API、ZGC 初步可用等能力;JDK 17 是当前大量生产系统升级的关键长期支持版本,带来 sealed class、record、switch 表达式、文本块、模式匹配等语言能力,并强化 JVM、GC 和封装边界;JDK 21 进一步把虚拟线程、结构化并发、模式匹配 switch、record pattern、分代 ZGC 等特性推向成熟,重点提升高并发服务的线程模型和表达能力。

JDK25 有些什么新特性?

JDK 25 的面试回答应先定位版本:它在 2025-09-16 GA,并且是多数发行版选择的 LTS 基线。然后要区分 final、preview、incubator、experimental 四类能力。生产升级重点看正式特性、运行时变化、诊断能力、安全 API 和兼容性变化,预览、孵化、实验能力更适合评估与提前适配。

Java 的多态是怎么实现的?

Java 多态的核心是:编译期看引用的静态类型决定能调用哪些成员、选择哪个方法签名;运行期看对象的实际类型决定执行哪个被重写的方法实现。它主要依赖方法重写、动态分派以及虚方法调用指令完成,字段、静态方法、私有方法和构造方法不按同样规则参与多态。

Java 类加载流程和双亲委派机制是什么?

这道题要回答清楚两层:第一是类从字节码进入 JVM 到可执行状态的生命周期,通常按加载、验证、准备、解析、初始化来讲,其中验证、准备、解析属于链接阶段;第二是类加载器如何查找类,也就是双亲委派模型。面试中不能只背阶段名称,还要说明每阶段做什么、初始化触发时机、类身份由类名和加载器共同决定,以及为什么工程框架有时会打破或绕开双亲委派。

Java里抽象类和接口的区别是什么?

Java 中抽象类和接口的核心区别不只是语法,而是建模意图:抽象类用于表达“是什么”的继承关系和共享骨架,接口用于表达“能做什么”的能力契约。抽象类可以保存状态、定义构造器、复用模板流程;接口更适合定义跨层级、可多实现的规范,并通过 default、static、private 方法支持演进和少量公共逻辑。

熟悉Java的哪些框架?

这类问题不是让候选人背框架名称,而是考察你是否真正理解 Java 后端技术栈如何支撑业务系统。高质量回答应该从“核心开发框架、Web 请求链路、数据访问、微服务治理、RPC 通信、异步消息、缓存与性能、项目落地经验”几个层次展开,体现你不仅会用 Spring Boot 写接口,也理解框架背后的设计思想、运行机制、适用边界和工程实践。