当前位置: 首页 > news >正文

面试小总结

Q1:Java 内存模型(JMM)是什么?作用是什么?
A:JMM 是抽象模型,定义了线程和主内存之间的交互规则:所有变量存在主内存,线程操作时将变量加载到工作内存,操作后写回。作用是解决多线程内存可见性、原子性、有序性问题,是 synchronized、volatile 等并发关键字的底层依据。

Q2:垃圾回收(GC)的流程?常见的垃圾收集器有哪些?
A:流程分三步:①通过可达性分析(GC Roots)判断对象是否存活;②回收存活对象内存(清除 / 标记 - 复制 / 标记 - 整理);③内存分配(指针碰撞 / 空闲列表)。
常见收集器:SerialGC(单线程,简单高效)、ParallelGC(多线程,注重吞吐量)、G1(区域化分代,兼顾吞吐量与延迟)、ZGC/Shenandoah(低延迟,大堆场景)。

Q3:类加载机制的流程?什么是双亲委派模型?
A:类加载流程:加载(读字节码)→验证(校验字节码合法性)→准备(静态变量赋默认值)→解析(符号引用转直接引用)→初始化(执行 clinit 方法)。
双亲委派:加载类时,先委托父加载器(Bootstrap→Extension→Application),父加载器无法加载时才自己加载。作用是防止类重复加载、保证核心类安全(如 java.lang.String 不会被自定义类篡改)。

Q1:HashMap 的实现原理?JDK 1.7 和 1.8 有什么区别?
A:底层是数组 + 链表(JDK1.7)/ 数组 + 链表 + 红黑树(JDK1.8),通过 key 的 hashCode 计算索引,解决哈希冲突。
区别:①1.7 用头插法(多线程可能死循环),1.8 用尾插法;②1.8 当链表长度≥8 时转红黑树(≤6 时退化为链表);③1.8 的 hash 计算更简单(减少扰动)。

Q2:ArrayList 和 LinkedList 的区别?分别适合什么场景?
A:①底层:ArrayList 是动态数组(连续内存),LinkedList 是双向链表(离散内存);②性能:ArrayList 随机访问快(O (1))、增删慢(需移动元素,O (n));LinkedList 随机访问慢(O (n))、增删快(O (1),只需改指针)。
场景:ArrayList 适合读多写少、需要随机访问;LinkedList 适合写多(首尾操作)、无需随机访问。

Q3:ConcurrentHashMap 如何保证线程安全?JDK 1.7 和 1.8 有什么区别?
A:JDK1.7:分段锁(Segment 数组,每个 Segment 是 ReentrantLock,锁粒度大,并发度 = Segment 数量);
JDK1.8:取消 Segment,用synchronized+CAS(锁链表头 / 红黑树根节点,锁粒度小,并发度更高)。

Q1:synchronized 和 volatile 的区别?
A:①synchronized:保证原子性、可见性、有序性(重量级锁,可重入);②volatile:仅保证可见性(禁止指令重排序),不保证原子性。
场景:synchronized 适合复合操作(如 i++),volatile 适合单一线程写、多线程读的场景(如状态标记)。

Q2:线程池的核心参数?如何设置合理的核心线程数?
A:核心参数:corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、keepAliveTime(非核心线程空闲时间)、workQueue(任务队列)、handler(拒绝策略)。
线程数设置:①CPU 密集型(如计算):线程数≈CPU 核心数 + 1;②IO 密集型(如网络 / 数据库操作):线程数≈CPU 核心数 ×2(或根据 IO 阻塞时间调整)。

Q3:ThreadLocal 的原理?为什么会导致内存泄漏?
A:原理:每个 Thread 有 ThreadLocalMap,key 是 ThreadLocal(弱引用),value 是存储的值。作用是线程隔离(每个线程存自己的副本)。
内存泄漏:ThreadLocalMap 的 key 是弱引用,GC 时 key 会被回收,但 value 仍被 Thread 引用(强引用),若 Thread 长期存活(如线程池),value 无法回收,导致泄漏。解决:使用后调用remove()手动清理。

Q1:BIO、NIO、AIO 的区别?
A:①BIO(同步阻塞):一个连接一个线程,效率低,适合连接少的场景;②NIO(同步非阻塞):基于 Selector、Channel、Buffer,一个线程管理多个连接,非阻塞,适合高并发(如 Netty);③AIO(异步非阻塞):操作完成后由 OS 通知线程,无需轮询,适合 IO 密集型但连接数不多的场景(如文件读写)。

Q2:NIO 的三大核心组件是什么?
A:①Channel(通道):双向读写(与 BIO 的 Stream 单向不同),如 FileChannel、SocketChannel;②Buffer(缓冲区):数据容器,Channel 读写必须通过 Buffer;③Selector(选择器):单线程监听多个 Channel 的事件(如连接、可读、可写),实现多路复用。

Q1:Lambda 表达式的作用? functional interface 是什么?
A:Lambda 简化匿名内部类代码(如(a,b)->a+b),本质是 “可传递的代码块”。
functional interface 是只有一个抽象方法的接口(可含默认方法),是 Lambda 的载体(如 Runnable、Consumer)。

Q2:Stream API 的优势?常用操作有哪些?
A:优势:简化集合操作(链式调用),支持并行处理(parallelStream())。
常用操作:①中间操作(filter、map、sorted);②终止操作(collect、forEach、count)。

Q1:单例模式的实现方式?如何保证线程安全?
A:常见方式:①饿汉式(类加载时初始化,线程安全但可能浪费内存);②懒汉式(双重校验锁 + volatile,volatile防止指令重排序);③静态内部类(延迟加载,线程安全)。
示例(双重校验锁):

java

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {

        if (instance == null) {

            synchronized (Singleton.class) {

                if (instance == null) {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }}

Q2:代理模式的两种实现?Spring AOP 用的哪种?
A:①静态代理:手动编写代理类,编译期生成;②动态代理:运行时生成代理类(JDK 动态代理基于接口,CGLIB 基于继承)。
Spring AOP:默认用 JDK 动态代理(目标类有接口时),无接口时用 CGLIB。

Q1:IoC 和 DI 的区别?
A:IoC(控制反转)是思想:对象创建权由自己转交给 Spring 容器;DI(依赖注入)是 IoC 的实现:容器在创建对象时,自动将依赖注入到对象中(如 @Autowired)。

Q2:AOP 的原理?常用场景有哪些?
A:AOP(面向切面)通过动态代理在目标方法前后插入增强逻辑(如日志、事务),核心概念:切面(Aspect)、通知(Advice)、切点(Pointcut)。
场景:日志记录、事务管理、权限校验。

Q3:Spring 事务的传播机制和隔离级别?
A:传播机制:定义多事务方法调用时的行为(如 REQUIRED:当前有事务则加入,无则新建;REQUIRES_NEW:无论是否有事务,都新建)。
隔离级别:①READ_UNCOMMITTED(读未提交);②READ_COMMITTED(读已提交,解决脏读);③REPEATABLE_READ(可重复读,解决不可重复读,MySQL 默认);④SERIALIZABLE(串行化,解决幻读)。

2. MyBatis

Q1:MyBatis 的一级缓存和二级缓存?
A:一级缓存:SqlSession 级别的缓存,默认开启,同一个 SqlSession 内多次查询相同 SQL 会缓存结果,关闭 SqlSession 后失效;
二级缓存:Mapper 级别的缓存,需手动开启(<cache/>),不同 SqlSession 可共享,查询前先查二级缓存→一级缓存→数据库。

Q2:MyBatis 接口绑定的方式?
A:①XML 映射文件(namespace 对应接口全类名,id 对应方法名);②注解(如 @Select、@Insert 直接写在接口方法上)。

1. MySQL

Q1:索引的类型?B + 树索引和哈希索引的区别?
A:索引类型:主键索引、二级索引(普通索引)、联合索引、唯一索引。
区别:B + 树索引支持范围查询、排序,适合频繁范围查询;哈希索引等值查询快(O (1)),但不支持范围查询、排序,适合高频等值查询(如字典表)。

Q2:事务的 ACID 特性?MySQL 如何保证?
A:ACID:原子性(Atomicity,事务要么全成要么全败,靠 undo log)、一致性(Consistency,最终状态合法,靠其他三特性保证)、隔离性(Isolation,靠锁和 MVCC)、持久性(Durability,靠 redo log)。

Q3:如何优化慢 SQL?
A:①加索引(避免全表扫描);②避免索引失效(如函数操作索引列、用!=、not in);③分页优化(limit 大偏移量时用子查询定位起点);④分表分库(大表拆分)。

2. Redis

Q1:Redis 的数据结构及应用场景?
A:①String(缓存、计数器);②Hash(存储对象,如用户信息);③List(消息队列、最新列表);④Set(去重、交集并集,如共同好友);⑤SortedSet(排序,如排行榜)。

Q2:缓存三大问题(穿透、击穿、雪崩)及解决方案?
A:①穿透(查不存在的数据,直击 DB):布隆过滤器拦截无效 key,或缓存空值;②击穿(热点 key 失效,瞬间大量请求击 DB):互斥锁(同一时间只让一个线程更新缓存),或热点 key 永不过期;③雪崩(大量 key 同时失效,DB 压力骤增):过期时间加随机值(错开失效时间),或集群部署(主从 + 哨兵)。

项目经验与场景题

1. 项目描述技巧

  • 用 “STAR 法则”:S(场景)→T(任务)→A(行动,重点说自己负责的模块和技术难点)→R(结果,如性能提升多少、用户量增长)。
  • 例:“在仿微信聊天项目中(S),我负责消息实时推送模块(T),用 Netty 实现长连接,通过 Redis 缓存离线消息,解决了高并发下消息延迟问题(A),最终支持 10 万用户同时在线,消息投递成功率 99.9%(R)”。

2. 场景题

  • Q:如何设计一个高并发的订单系统?
    A:①限流(用 Redis+Lua 脚本做接口限流,防止过载);②异步处理(订单创建后用 MQ 发送消息,异步处理支付、物流,提高响应速度);③分库分表(按用户 ID 哈希分库,订单表按时间分表);④缓存(热点订单缓存,减少 DB 查询);⑤分布式锁(防止超卖,用 Redis 的 setnx 或 ZooKeeper)

http://www.dtcms.com/a/311756.html

相关文章:

  • 解决技术问题思路
  • STM32学习记录--Day6
  • Spring 中 Bean 的生命周期
  • 知识蒸馏 - 基于KL散度的知识蒸馏 HelloWorld 示例
  • Linux网络编程【UDP网络通信demon】
  • 网页操作自动化解决方案:如何用Browser-Use+CPolar提升企业运营效率
  • React ahooks——副作用类hooks之useThrottleFn
  • 【智能体cooragent】新智能体创建相关代码解析
  • 双网卡UDP广播通信机制详解
  • 海洋大地测量基准与水下导航系列之九我国海洋PNT最新技术进展(下)
  • P13014 [GESP202506 五级] 最大公因数
  • 使用WSL2开发zephyr
  • 重型机械作业误伤预警响应时间缩短80%!陌讯多模态识别算法在工程现场的应用优化
  • 音频3A处理简介之AGC(自动增益控制)
  • RHCE认证题解
  • 自动驾驶中的传感器技术13——Camera(4)
  • 知识蒸馏 - 最小化KL散度与最小化交叉熵是完全等价的
  • stm32103如果不用32k晶振,那引脚是悬空还是接地
  • C++入门基础(三):const引用、指针和引用的关系、inline(修饰内联函数)替代宏、nullptr代替null
  • 使用docker运行vite项目
  • C++ vector底层实现与迭代器失效问题
  • 深入 Go 底层原理(十五):cgo 的工作机制与性能开销
  • 【深度学习】【三维重建】windows11环境配置PyTorch3d详细教程
  • Flutter开发 初识目录结构
  • 自动布局视图来实现聊天室的界面
  • 【iOS】KVO
  • 20250802让飞凌OK3576-C开发板在飞凌的Android14下【rk3576_u选项】适配NXP的WIFIBT模块88W8987A的蓝牙
  • OTC焊接机器人节能技巧
  • Java内存模型(Java Memory Model,JMM)
  • 关于鸦片战争的历史