面试题(1)

🔹 Java 基础

1. HashMap 的底层结构?JDK 1.8 有什么变化?

答案:

  • JDK 1.7:数组 + 链表,链表头插法

  • JDK 1.8

    • 数组 + 链表/红黑树(链表长度 > 8 且数组长度 ≥ 64 时转为红黑树)

    • 链表尾插法(解决多线程下可能的循环链表问题)

    • 扩容时重新计算hash的方式优化(高位参与运算)

    • 新增方法:getOrDefaultcomputeIfAbsent

2. synchronized 和 ReentrantLock 的区别?

答案:

特性 synchronized ReentrantLock
实现层面 JVM层面 JDK层面
锁的获取 自动获取释放 手动lock/unlock
响应中断 不支持 支持lockInterruptibly()
公平锁 非公平 可选择公平/非公平
条件变量 一个Condition 多个Condition
性能 优化后差距不大 高竞争下有优势

3. 什么是 volatile 关键字?它能保证原子性吗?

答案:

  • 作用

    • 保证可见性:一个线程修改后,其他线程立即可见

    • 禁止指令重排序

  • 不能保证原子性 :如count++这种复合操作不是原子的

  • 使用场景:状态标志位、DCL单例模式

4. 谈谈你对 JVM 内存模型的理解?

答案:

  • 线程私有

    • 程序计数器:当前线程执行的字节码行号

    • 虚拟机栈:方法执行的内存模型

    • 本地方法栈:Native方法服务

  • 线程共享

    • 堆:对象实例分配区域

    • 方法区:类信息、常量、静态变量

  • JDK 1.8:元空间替代永久代

5. 什么是双亲委派模型?为什么要使用它?

答案:

  • 工作机制:类加载请求先委派给父加载器,只有父加载器无法完成时才自己加载

  • 层次结构

    • Bootstrap ClassLoader

    • Extension ClassLoader

    • Application ClassLoader

    • 自定义ClassLoader

  • 优点

    • 避免类的重复加载

    • 保证核心类库安全(如java.lang.Object)


🔹 Spring & Spring Boot

1. Spring Boot 自动装配的原理是什么?

答案:

  • 核心注解@SpringBootApplication@EnableAutoConfiguration

  • 关键文件META-INF/spring.factories

  • 流程

    1. 扫描spring.factories中的EnableAutoConfiguration配置

    2. 通过@Conditional条件判断决定是否装配

    3. 创建并注册Bean到IOC容器

2. Spring 中 Bean 的生命周期?

答案:

  1. 实例化Bean

  2. 属性赋值(依赖注入)

  3. 调用Aware接口方法(BeanNameAware、BeanFactoryAware)

  4. BeanPostProcessor前置处理

  5. 初始化方法(@PostConstruct、InitializingBean)

  6. BeanPostProcessor后置处理

  7. Bean就绪使用

  8. 容器关闭时调用销毁方法(@PreDestroy、DisposableBean)

3. Spring 事务传播机制有哪些?如何使用?

答案:

  • REQUIRED(默认):有事务加入,无事务新建

  • REQUIRES_NEW:新建事务,挂起当前事务

  • NESTED:嵌套事务,外部事务回滚会影响内部

  • SUPPORTS:有事务就用,没有就算了

  • NOT_SUPPORTED:非事务执行,挂起当前事务

  • MANDATORY:必须有事务,否则抛异常

  • NEVER:必须无事务,否则抛异常

4. Spring MVC 的工作流程是怎样的?

答案:

  1. 用户请求 → DispatcherServlet

  2. DispatcherServlet 查询 HandlerMapping

  3. 调用 HandlerAdapter 执行 Controller

  4. Controller 返回 ModelAndView

  5. 视图解析器解析视图

  6. 渲染视图并返回响应

5. 如何自定义一个 Starter?

答案:

复制代码
// 1. 创建配置类
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyService();
    }
}

// 2. 在META-INF/spring.factories中配置
// org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.MyAutoConfiguration

🔹 数据库 & Redis

1. MySQL 索引底层结构?什么是聚簇索引?

答案:

  • 底层结构:B+Tree

  • 聚簇索引

    • 索引与数据存储在一起

    • InnoDB主键就是聚簇索引

    • 一个表只有一个聚簇索引

  • 非聚簇索引

    • 索引与数据分离

    • 叶子节点存储主键值,需要回表查询

2. 什么是事务的隔离级别?MySQL 默认是哪个?

答案:

  • 读未提交:可能脏读、不可重复读、幻读

  • 读已提交:解决脏读(Oracle默认)

  • 可重复读:解决脏读、不可重复读(MySQL默认)

  • 串行化:解决所有问题,性能最低

3. Redis 持久化方式有哪些?区别是什么?

答案:

  • RDB

    • 定时快照,文件小,恢复快

    • 可能丢失最后一次快照后的数据

  • AOF

    • 记录所有写操作,数据安全

    • 文件大,恢复慢

  • 混合持久化(Redis 4.0+):RDB + AOF,兼顾速度和数据安全

4. 如何用 Redis 实现分布式锁?要注意什么?

答案:

复制代码
-- 加锁
SET lock_key unique_value NX EX 30

-- 解锁(Lua脚本保证原子性)
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

注意事项

  • 设置唯一value,防止误删其他线程的锁

  • 设置过期时间,避免死锁

  • 考虑锁续期问题

5. 缓存穿透、缓存雪崩、缓存击穿有什么区别?如何解决?

答案:

  • 缓存穿透:查询不存在的数据

    • 解决:布隆过滤器、缓存空对象
  • 缓存雪崩:大量缓存同时失效

    • 解决:设置不同的过期时间、集群部署
  • 缓存击穿:热点key突然失效

    • 解决:永不过期、互斥锁重建

🔹 微服务 & 分布式

1. 什么是服务注册与发现?Nacos 和 Eureka 有什么区别?

答案:

  • 服务注册:服务提供者向注册中心注册自身信息

  • 服务发现:服务消费者从注册中心获取服务列表

  • 区别

    • Nacos支持CP+AP模式切换,Eureka只支持AP

    • Nacos支持配置管理,Eureka不支持

    • Nacos健康检查更丰富

2. 如何保证微服务之间的调用安全?

答案:

  • 使用HTTPS加密传输

  • JWT Token身份认证

  • API网关统一鉴权

  • 服务间认证(如Spring Security OAuth2)

3. 什么是熔断和降级?Sentinel 是如何实现的?

答案:

  • 熔断:服务故障时快速失败,避免雪崩

  • 降级:服务压力大时关闭非核心功能

  • Sentinel实现

    • 基于滑动窗口统计QPS、响应时间等指标

    • 根据规则进行流量控制、熔断降级

4. 你了解 Spring Cloud Gateway 的过滤器吗?如何使用?

答案:

复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: my_route
        uri: http://example.org
        filters:
        - AddRequestHeader=X-Request-color, blue
        - PrefixPath=/api
  • 全局过滤器:对所有路由生效

  • 局部过滤器:对特定路由生效


🔹 项目 & 场景题

1. 你在项目中遇到的最大技术难点是什么?如何解决的?

参考答案

"在博客系统的评论模块中,需要实现多级评论回复。最初使用递归查询,但性能很差。后来改用parent_id字段维护层级关系,结合tree_path字段存储评论路径,通过一次SQL查询获取所有评论,在内存中构建树形结构,性能提升了10倍以上。"

2. 如果系统出现 CPU 飙高,如何排查?

答案

  1. top命令找到占用CPU高的进程

  2. top -Hp <pid>找到具体线程

  3. jstack <pid> > stack.log导出线程栈

  4. 将线程ID转换为16进制,在stack.log中查找对应线程

  5. 分析代码定位问题(如死循环、频繁GC等)

3. 如何设计一个秒杀系统?

答案

  • 前端:静态化页面、按钮防重复点击

  • 网关:限流、恶意请求过滤

  • 服务层

    • Redis预减库存(原子操作)

    • 消息队列异步处理订单

    • 令牌桶限流

  • 数据层:数据库乐观锁、分库分表

4. 你如何保证接口的幂等性?

答案

  • Token机制:先获取token,请求时携带token

  • 唯一索引:防重复提交

  • 状态机:只有特定状态才能执行操作

  • 分布式锁:防并发重复提交

  • 悲观锁/乐观锁:数据库层面控制

相关推荐
二饭2 小时前
POI操作Docx的踩坑指南(一)
java·apache
李贺梖梖2 小时前
DAY25 综合案例
java
-雷阵雨-3 小时前
数据结构——优先级队列(堆)
java·开发语言·数据结构·intellij-idea
好家伙VCC3 小时前
**全息显示技术的发散创新与深度探索**一、引言随着科技的飞速发展,全息显示技术已成为显示领域的一大研究热点。本文将带你
java·图像处理·python·科技·计算机视觉
步行cgn3 小时前
Java项目包结构设计与功能划分详解
java·开发语言·架构·mvc
ss2733 小时前
手写MyBatis第92弹:SqlSource体系、SqlNode树与Trim标签实现原理全揭秘
java·开发语言
235164 小时前
【LeetCode】46. 全排列
java·数据结构·后端·算法·leetcode·职场和发展·深度优先
_extraordinary_4 小时前
Java Linux --- 基本命令,部署Java web程序到线上访问
java·linux·前端
heyCHEEMS4 小时前
最长连续序列 Java
java·开发语言·算法