JAVA八股面试必备(1)

张开发
2026/4/4 18:38:43 15 分钟阅读
JAVA八股面试必备(1)
文章目录一、说一说Spring Boot 和Spring的区别一 总结二 详细区别二 、 说一说Spring Boot常用注解一接口开发二分层开发三配置读取四事务控制五项目启动三 、 说一说Spring Boot自动配置四、 mybatis用过吗说说#和$的区别一 核心区别二 详细区别1、编译方式不同2、是否带引号3、SQL注入4、使用场景不同五 、数据库索引你是怎么设计的六 、数据库索引失效怎么办一EXPLAIN 看是否全表扫描二检查是否在索引列上用了函数 / 运算 / 隐式转换三检查是否 %开头、NOT IN、OR四联合索引是否遵守最左匹配五看数据分布是否过于集中六重建 / 优化索引避免冗余索引七尽量使用覆盖索引避免回表七 、数据库你是怎么调优的八 、你说你用过 mq 是吧那么 mq 消息太多怎么办九 、redis 的缓存的穿透击穿雪崩是什么怎么解决一穿透二击穿三雪崩十 、你说你用过 linux 是吧你是怎么部署项目的十一 、当用户登录时你是怎么确保是该用户登录的 (考察 jwt 令牌)十二 、说说拦截器你是怎么设计的十三 、HikariCP与Druid的核心区别一 一句话总结二 核心区别三标准回答四记忆口诀一、说一说Spring Boot 和Spring的区别一 总结Spring是一套企业级Java开发框架全家桶提供Ioc、Aop等核心功能但配置繁琐Spring Boot是基于Spring的快速开发工具目的是简化Spring开发自动配置开箱即用二 详细区别配置方式不同最大的区别-Spring需要手动写大量的XML配置文件/JavaConfig比如配置Bean、数据源、DispatcherServlet等配置繁琐容易出错-Spring Boot自动配置AutoConfiguration几乎零XML通过注解和application.yml极简配置框架自动加载默认配置。依赖管理不同-Spring需要手动引入每个依赖还需要处理版本冲突非常麻烦-Spring Boot提供starter场景启动器比如spring-boot-starter-web一键引入web开发的所有依赖自动管理版本。服务器-Spring必须手动配置Tomcat/Jetty等外部服务器打包成war部署-Spring Boot内置Tomcat/Jetty直接打包成jar包一行命令就能运行。使用的目的不同-Spring解决企业级开发的耦合性问题Ioc、Aop、事务和MVC等-Spring Boot解决Spring开发复杂配置繁琐的问题实现快速开发快速部署。代码侵入性-Spring无侵入但配置复杂-Spring Boot更低侵入更轻量化。精简版回答Spring 是一个轻量级的企业级开发框架提供 IOC、AOP 等核心功能但需要大量手动配置依赖管理复杂。Spring Boot 是基于 Spring 的快速开发框架它通过自动配置、starter 依赖管理、内置服务器消除了繁琐的 XML 配置让 Spring 项目可以快速搭建、开箱即用本质是 Spring 的简化开发工具。二 、 说一说Spring Boot常用注解一接口开发RestController GetMapping/PostMapping RequestBody二分层开发Service业务 Repository数据 Autowired注入三配置读取Value / ConfigurationProperties四事务控制Transactional五项目启动SpringBootApplication三 、 说一说Spring Boot自动配置Spring Boot 自动配置是通过 EnableAutoConfiguration 开启基于 SPI 机制 读取 META-INF/spring/…AutoConfiguration.imports 里的自动配置类再通过 条件注解如 ConditionalOnClass、ConditionalOnMissingBean判断是否满足装配条件满足条件就自动创建 Bean 并注册到容器。它的思想是约定大于配置让开发者无需手动配置直接使用 Starter 即可快速集成功能。四、 mybatis用过吗说说#和$的区别一 核心区别#{}预编译、安全、防SQL注入推荐使用${}字符串拼接、不安全、有注入风险慎用二 详细区别1、编译方式不同#{}SQL先编译再代入参数相当于JDBC的占位符${}先拼接SQL语句再编译2、是否带引号#{}会自动给字符串加引号${}不回加引号直接拼接进去whereusername#{name}→ 最终变成whereusername张三whereusername${name} → 最终变成whereusername张三报错3、SQL注入#{}可以防止SQL注入${}有注入风险经典注入例子传入参数1 or 11用${}拼接后变成select*fromuserwhereid1 or 11全表数据泄露4、使用场景不同#{}用于99%的场景传入参数值用户名、密码、标题、内容、ID等${}只能用于动态传入表名、列名、order by字段而且会做白名单校验例如orderby${columnName}desc五 、数据库索引你是怎么设计的先看业务 SQL → 选高区分度字段 → 组合成联合索引 → 等值在前范围在后 → 把查询与排序字段放进索引做成覆盖索引 → 最后 EXPLAIN 验证去掉冗余。六 、数据库索引失效怎么办一EXPLAIN 看是否全表扫描二检查是否在索引列上用了函数 / 运算 / 隐式转换三检查是否 %开头、NOT IN、OR四联合索引是否遵守最左匹配五看数据分布是否过于集中六重建 / 优化索引避免冗余索引七尽量使用覆盖索引避免回表七 、数据库你是怎么调优的-举例百万级查询会导致磁盘IO爆炸select*fromlimit1000000,10调优后使用主键索引避免大量查询无效IOselect*fromwhereid1000000limit10八 、你说你用过 mq 是吧那么 mq 消息太多怎么办首先紧急扩容消费者增加实例和消费线程先把堆积消下去然后排查消费慢原因通常是业务逻辑慢、数据库慢、死循环重试导致代码上做批量消费、异步消费、减少 IO提升吞吐量建立死信队列避免失败消息无限重试生产者做限流削峰防止流量突增最后加上监控告警提前发现堆积。九 、redis 的缓存的穿透击穿雪崩是什么怎么解决一穿透查不存在的数据缓存数据库都没有请求直接打库。解决缓存空值、布隆过滤器、接口校验。二击穿热点 key 过期大量并发打库。解决分布式锁、热点 key 永不过期、后台异步更新。三雪崩大量 key 同时过期 / Redis 宕机全部请求打库。解决过期时间随机、多级缓存、Redis 集群、数据库限流降级。十 、你说你用过 linux 是吧你是怎么部署项目的把java项目打包成jar包然后在Linux中部署jdk和mysql环境在Linux中登录数据库执行数据库脚本source 目录/文件jar包上传至Linux,执行nohup java -jar jar包 使得java项目可以一直挂在服务器上然后ps -ef | grep java,判断该项目有没有在执行如果执行了使用kill -9 进程Id杀死进程然后运行项目在部署之前也要通过ps -ef | grep 端口号如果该端口号被占用则考虑应该更换项目的端口号还是杀死被占用这个端口号的这个项目**十一 、当用户登录时你是怎么确保是该用户登录的 (考察 jwt 令牌)用户登录时后端验证账号密码通过后会生成 JWT 令牌将用户 ID 等身份信息存在载荷里并用服务端密钥进行签名。前端拿到 Token 后每次请求都在请求头携带。后端通过校验 JWT 签名是否合法、是否过期来确认 Token 没有被篡改然后解析出用户 ID从而确定当前登录的是哪个用户实现无状态的身份认证。十二 、说说拦截器你是怎么设计的项目中通过实现 HandlerInterceptor 接口 自定义登录拦截器在 preHandle 方法中校验 Session 判断用户是否登录未登录则重定向到登录页。然后通过 Configuration 配置类实现 WebMvcConfigurer调用 addInterceptors 注册拦截器设置 拦截所有请求并放行登录页、注册接口、静态资源等白名单从而实现全局登录权限控制。十三 、HikariCP与Druid的核心区别一 一句话总结HikariCPSpring Boot默认最快、最轻量、最简单主打高性能。Druid阿里开源功能最全自带监控、防SQL注入主打生产可控。二 核心区别性能速度-HikariCP最快目前Java最快连接池-Druid性能略低一点但完全够用功能特点-HikariCP极简只做连接池没有多余的功能-Druid功能强大自带Web监控页面慢SQL记录、防SQL注入、防火墙使用复杂度-HikariCP开箱即用几乎不用任何配置-Druid需要加依赖、可配置更多参数国内企业使用-中小项目/新项目普遍用HikariCP-传统企业/老项目/需要监控普遍用Druid三标准回答HikariCP是Spring Boot默认的连接池性能最快、轻量简洁适合大多数项目Druid是阿里开源的功能更全自带SQL监控和防注入适合需要运维监控的生产环境四记忆口诀HikariCP快简单默认Druid全监控安全

更多文章