面试基础

Notion地址

java常用集合

Collection (接口)
├── List (有序,可重复)
│ ├── ArrayList (动态数组,查询快,增删慢)
│ ├── LinkedList (双向链表,增删快,查询慢)
│ └── Vector (线程安全的动态数组,效率低)
├── Set (无序,不可重复)
│ ├── HashSet (基于 HashMap,存取快)
│ ├── TreeSet (基于 TreeMap,排序存储)
│ └── LinkedHashSet (有序 HashSet,保留插入顺序)
└── Queue (队列)
├── PriorityQueue (优先级队列)
├── LinkedList (双端队列)
└── ArrayDeque (高效双端队列)

Map (接口,键值对)
├── HashMap (数组+链表+红黑树,无序,线程不安全)
├── TreeMap (基于红黑树,key 自动排序)
├── LinkedHashMap (保留插入顺序)
├── Hashtable (线程安全,低效,已过时)
└── ConcurrentHashMap (线程安全,高效,生产环境推荐)

1.springbean的作用域有哪些

6 种作用域(常用就 2 个)

Spring Bean 作用域,说白了就是:

这个对象能活多久、能被多少人共用、每次拿是不是同一个。

1. singleton(单例,默认)

整个容器里就一个实例,所有人共用这一个对象。

  • 不管你 @Autowired 多少次,拿的都是同一个 Bean
  • 从容器启动到关闭,就这一个
  • 适用:Service、Dao、Controller 这些无状态组件

2. prototype(原型)

每次获取 / 注入,都新建一个对象。

  • 每次 @Autowired、每次 getBean (),都new 一个新的
  • Spring 不负责销毁它,用完就不管了
  • 适用:有状态、多线程不安全的 Bean

3. request(请求级,Web 环境)

一次 HTTP 请求一个 Bean 实例。

  • 同一次请求内多次注入/获取都是同一个
  • 请求结束就销毁
  • 适用:只在一次请求链路内有效的对象(例如:请求上下文包装、临时聚合对象)

4. session(会话级,Web 环境)

同一个 HTTP Session 共享一个 Bean 实例。

  • 同一用户会话期间,多次请求拿到同一个
  • Session 失效后销毁
  • 适用:跟“用户会话状态”强相关的对象(不推荐放太重的状态)

5. application(应用级,Web 环境)

整个 Web 应用(ServletContext)范围内一个实例。

  • 类似 singleton,但范围是 Web 应用上下文
  • 应用关闭才销毁
  • 适用:全局共享、且与 Web 容器生命周期绑定的对象

6. websocket(WebSocket 会话级,Web 环境)

一次 WebSocket 会话一个实例。

  • WebSocket 连接建立到断开期间有效
  • 适用:与单个 WebSocket 连接绑定的状态对象

作用域怎么写

  • 注解:@Scope("singleton")@Scope("prototype")
  • XML:scope="singleton"

2. “Spring 事务怎么实现?Spring 事务有哪些隔离级别?事务的传播机制?可能有哪些原因导致事务无法回滚?事务失效”


回答要点:

事务实现:

  • Spring 通过声明式事务(基于 AOP)和编程式事务来实现事务管理。通常使用 @Transactional 注解来声明事务。

事务隔离级别:

  • READ_UNCOMMITTED:最低的隔离级别,允许脏读。
  • READ_COMMITTED:防止脏读,但允许不可重复读。
  • REPEATABLE_READ:防止脏读和不可重复读,但允许幻读。
  • SERIALIZABLE:最高的隔离级别,防止脏读、不可重复读和幻读。

事务传播机制:

  • REQUIRED:如果当前没有事务,则新建一个事务;如果已经有事务,则加入当前事务。
  • REQUIRES_NEW:新建一个事务,并挂起当前事务。
  • NESTED:在当前事务内嵌套一个事务,支持事务的回滚。

事务无法回滚的原因:

  • 默认情况下,Spring 事务只会在运行时抛出 RuntimeException 及其子类时回滚。如果抛出 checked exceptions,默认不会回滚。
  • 可以通过 @Transactional(rollbackFor = Exception.class) 来指定回滚策略。

3.@Transcational的注解常用参数

4. spring 中用到了哪些设计模式(90% 问)


回答要点:

常见设计模式:

  • 单例模式:Spring Bean 默认使用单例模式。
  • 工厂模式:通过 BeanFactoryApplicationContext 等类实例化 Bean。
  • 代理模式:AOP 使用动态代理来增强 Bean 功能。
  • 模板方法模式:Spring 提供的 JdbcTemplateHibernateTemplate 等类使用模板方法模式。
  • 观察者模式:Spring 事件机制使用了观察者模式。

5.IOC 容器初始化过程

  1. 加载配置:加载 XML 配置文件或进行注解扫描,解析 Bean 的定义信息。
  2. 实例化 Bean:根据解析后的 Bean 定义,通过反射等方式创建 Bean 实例。
  3. 依赖注入:将 Bean 所依赖的其他 Bean 实例,注入到当前 Bean 的对应属性中。
  4. 调用初始化方法:如果 Bean 中定义了初始化方法(如@PostConstruct注解标记的方法),Spring 容器会在依赖注入完成后执行该方法。
  5. 容器准备完毕:所有单例 Bean 初始化完成后,IOC 容器正式就绪,开始对外提供服务、接收请求。

6.Redis 常用数据结构及使用场景

String:最基本的数据类型,可以存储字符串、数字等。适用于存储缓存、用户 Session、计数器等场景。

List:双端队列,支持从两端进行推入或弹出操作。常用于消息队列、任务队列等场景。

Set:集合类型,存储唯一的元素,支持交集、并集等集合操作。用于标签、去重、关系计算等场景。

Hash:存储字段和值的映射关系。常用于存储对象的属性、用户信息、订单详情等场景。

ZSet(有序集合):基于跳表实现,元素带有分数(score)。用于排行榜、按权重排序的任务调度等场景。

Bitmaps:操作位(0/1),用于统计访问量、在线人数等场景。

HyperLogLog:用于基数统计,适合大规模数据的去重统计场景。

Geospatial:支持经纬度的地理位置数据操作,用于位置相关应用场景。

7. 为什么使用 redis 作缓存?为什么不用本地缓存?

回答要点:

使用 Redis 作缓存的原因:

  • 分布式:Redis 是分布式的,支持多个实例、集群,适用于大规模并发应用。
  • 高可用和高性能:Redis 是内存数据库,速度快,适用于高并发的应用场景。
  • 持久化:Redis 支持 AOF 和 RDB 持久化方式,保证数据不丢失。

为什么不用本地缓存:

  • 扩展性差:本地缓存只在当前进程内有效,难以扩展到多台机器。
  • 内存限制:本地缓存的内存受限,不能满足大规模数据存储需求。
  • 一致性问题:不同进程或机器间的缓存数据不一致,难以保证缓存同步。

8. 缓存穿透、缓存雪崩、缓存击穿了解吗,分别怎么解决?

回答要点:

缓存穿透

  • 问题:查询的请求在缓存和数据库中都没有结果,导致每次请求都直接访问数据库,影响性能。
  • 解决:使用布隆过滤器,提前判断某个查询是否存在,避免无效的查询进入数据库。

缓存雪崩

  • 问题:缓存中大量数据在同一时间过期,导致大量请求直接访问数据库。
  • 解决:设置合理的过期时间,并通过加随机值、分布式锁等手段来避免大规模缓存失效。

缓存击穿

  • 问题:某个热点数据突然失效,导致并发请求访问数据库,造成数据库压力过大。
  • 解决:使用互斥锁、标志位等方式,确保只有一个线程访问数据库并加载数据到缓存。

9.Redis 10 大经典业务场景(面试必背版)

每个场景都配:用途 + 用什么数据结构 + 一句话原理,直接背就行。


1. 分布式缓存(最常用)

  • 用途:减轻数据库压力,加速查询
  • 结构:String / Hash
  • 原理:热点数据放 Redis,设置过期时间,查询先读缓存,没有再查 DB

2. 分布式锁

  • 用途:解决集群下并发安全问题(比如超卖、重复提交)
  • 结构:String(SETNX + EX)
  • 原理:加锁成功执行业务,失败等待或重试,防止多个节点同时操作

3. 全局唯一 ID 生成

  • 用途:订单号、流水号、分布式自增 ID
  • 结构:String + INCR
  • 原理:利用 INCR 原子自增,保证全局唯一、趋势递增

4. 排行榜 / 热度排序

  • 用途:游戏积分、销量榜、粉丝榜、视频热度
  • 结构:ZSet(有序集合)
  • 原理:score 存分数 / 时间戳,自动排序,支持查前 N、查排名、加分

5. 消息队列 / 任务队列

  • 用途:异步处理、解耦(订单通知、日志、短信)
  • 结构:List / Stream
  • 原理:LPUSH + RPOP 或 发布订阅,简单业务直接用,复杂上 MQ

6. 接口限流 / 防刷

  • 用途:防止恶意请求、接口限流(1 分钟最多 10 次)
  • 结构:String + INCR + EXPIRE
  • 原理:以 IP / 用户为 key,请求一次计数,超时重置,超次数拒绝

7. 签到、用户在线状态(BitMap)

  • 用途:用户连续签到、日活统计、在线状态
  • 结构:BitMap(位图)
  • 原理:用 bit 位表示状态,极省内存,1 亿用户仅占约 12MB

8. 附近的人 / 地理位置

  • 用途:附近店铺、附近的人、打车距离
  • 结构:GEO(底层 ZSet)
  • 原理:存储经纬度,支持按距离范围查找、计算距离

9. 布隆过滤器(防缓存穿透)

  • 用途:过滤不存在的 key,避免大量无效请求打穿 DB
  • 结构:BitMap
  • 原理:判断数据一定不存在,减少空查询

10. 会话共享(Session 统一存储)

  • 用途:集群 / 分布式系统登录状态统一
  • 结构:String / Hash
  • 原理:把 session 存 Redis,多服务共享,不用粘会话

10. Mysql 有哪些索引类型?聚簇索引和非聚簇索引的区别?

(中国工商银行 - 2024 届春招 && 美团 && 蚂蚁 && 中国农业银行 - 2024 届 && 交通银行 - 2023 届)

回答要点:

索引类型:

  • 普通索引(Index):最基本的索引类型,允许索引列有重复值。
  • 唯一索引(Unique Index):索引列的值必须唯一,但允许 NULL 值。
  • 主键索引(Primary Key):特殊的唯一索引,不能为 NULL,每个表只能有一个主键。
  • 全文索引(Fulltext Index):主要用于文本搜索,可以加速对文本内容的查询。
  • 空间索引(Spatial Index):用于地理信息数据,支持空间查询。

聚簇索引和非聚簇索引的区别:

  • 聚簇索引:表中的数据按照索引的顺序存储,数据和索引是存储在同一结构中的。每个表只能有一个聚簇索引(InnoDB 表的主键索引就是聚簇索引)。
  • 非聚簇索引:数据和索引存储在不同的结构中,非聚簇索引包含指向数据的指针,可以有多个非聚簇索引

11、现在国内主流:Spring Cloud Alibaba

这套才是你工作、面试 99% 会遇到的:

  • 注册中心 + 配置中心:Nacos(核心中的核心)
  • 服务调用:OpenFeign(还是用)
  • 网关:Spring Cloud Gateway
  • 熔断限流:Sentinel
  • 分布式事务:Seata
  • 消息队列:RocketMQ