Java 后端开发完整学习指南:从基础语法到 Spring Boot 项目实战

Java 后端开发完整学习指南:从零基础到 Spring Boot 企业项目与面试

适合对象:零基础学习 Java、前端转后端、想做 Vue/React + Java 前后端分离项目、准备 Java 后端面试的人。

更新时间:2026-05-28

推荐学习版本:JDK 25 LTS 或企业常用的 JDK 21 LTS。如果只是学习新特性,也可以了解 JDK 26。


目录

  1. Java 是什么
  2. Java 应用领域
  3. JDK、JRE、JVM 区别
  4. Java 环境安装与开发工具
  5. Java 程序执行流程
  6. Java 基础语法
  7. 方法、数组与字符串
  8. 面向对象编程 OOP
  9. 常用 API 与工具类
  10. 集合框架
  11. 泛型
  12. 异常处理
  13. IO、NIO 与文件操作
  14. Lambda、Stream API 与 Optional
  15. 多线程与并发编程
  16. JVM 核心原理
  17. 数据库与 MySQL
  18. JDBC、MyBatis、MyBatis-Plus、JPA
  19. Java Web 与 HTTP 基础
  20. Spring、Spring MVC、Spring Boot
  21. 登录注册、JWT、权限拦截
  22. Redis、消息队列、搜索、缓存
  23. Maven、Gradle 与项目构建
  24. Docker、Linux、Nginx 部署
  25. Java 企业级项目结构
  26. Java 学习路线
  27. Java 官方文档与相关资源表
  28. Java 面试题与答案
  29. 项目练习建议
  30. 总结

一、Java 是什么?

Java 是一门 面向对象、强类型、跨平台、生态成熟 的编程语言。Java 最常见的应用方向是后端开发,尤其是在企业级系统、电商系统、金融系统、支付系统、后台管理系统、微服务系统中非常常见。

Java 的核心特点:

特点 说明
跨平台 Java 程序编译成字节码,由 JVM 在不同系统上运行
面向对象 使用类、对象、封装、继承、多态组织代码
强类型 变量类型明确,编译阶段能发现较多错误
生态成熟 Spring、MyBatis、Maven、Redis、MQ、微服务生态完善
适合大型项目 代码规范、稳定性强、企业级框架多
高并发能力强 支持多线程、线程池、并发容器、JVM 调优

一句话理解 Java:

Java 是企业后端开发中非常主流的一门语言,尤其适合构建稳定、可维护、可扩展的服务端系统。


二、Java 应用领域

1. 企业后端开发

这是 Java 最大的应用场景。

常见系统包括:

  • OA 办公系统
  • ERP 企业资源系统
  • CRM 客户管理系统
  • CMS 内容管理系统
  • 电商平台
  • 支付系统
  • 金融交易系统
  • 物流系统
  • 后台管理系统

技术组合通常是:

text 复制代码
Spring Boot + MyBatis/MyBatis-Plus + MySQL + Redis + Spring Security + JWT

2. 前后端分离项目

前端使用 Vue、React、Angular 等框架,后端使用 Java 提供接口。

典型流程:

text 复制代码
Vue / React 页面
    ↓ axios/fetch
Spring Boot REST API
    ↓
Service 业务层
    ↓
Mapper / Repository
    ↓
MySQL / Redis

3. 微服务与分布式系统

Java 在微服务领域非常成熟。

常见技术:

  • Spring Cloud
  • Spring Cloud Alibaba
  • Nacos
  • Gateway
  • OpenFeign
  • Sentinel
  • Seata
  • Redis
  • RabbitMQ
  • Kafka
  • Docker
  • Kubernetes

4. 安卓开发

安卓早期主要使用 Java,现在 Kotlin 更主流,但 Java 仍然是安卓生态的重要基础。

5. 大数据生态

很多大数据组件与 Java/JVM 生态相关:

  • Hadoop
  • HBase
  • Flink
  • Spark
  • Kafka
  • Elasticsearch

6. 桌面应用与工具开发

虽然现在不是主流方向,但 Java 仍可以开发桌面程序,例如:

  • JavaFX
  • Swing
  • IntelliJ IDEA 插件
  • 企业内部工具

三、JDK、JRE、JVM 区别

名称 全称 作用
JDK Java Development Kit Java 开发工具包,包含编译器、运行环境、工具
JRE Java Runtime Environment Java 运行环境,只负责运行 Java 程序
JVM Java Virtual Machine Java 虚拟机,负责执行字节码

关系:

text 复制代码
JDK 包含 JRE
JRE 包含 JVM
JVM 负责运行 .class 字节码

学习和开发时,直接安装 JDK 即可。


四、Java 环境安装与开发工具

1. 推荐 JDK 版本

当前建议:

场景 推荐版本
新手学习 JDK 21 LTS 或 JDK 25 LTS
企业项目 JDK 17、21、25,视公司技术栈而定
学习新特性 JDK 25、JDK 26
老项目维护 JDK 8、11、17

说明:

  • LTS 表示长期支持版本。
  • 企业项目更倾向选择 LTS 版本,因为稳定周期更长。
  • 学习阶段不建议一开始纠结版本,先用 JDK 21 或 JDK 25 即可。

2. 安装步骤

Windows 安装流程

  1. 下载 JDK 安装包
  2. 安装到指定目录,例如:
text 复制代码
C:\Program Files\Java\jdk-25
  1. 配置环境变量:
text 复制代码
JAVA_HOME=C:\Program Files\Java\jdk-25
Path=%JAVA_HOME%\bin
  1. 检查安装:
bash 复制代码
java -version
javac -version

看到版本号说明安装成功。

3. 推荐开发工具

工具 说明
IntelliJ IDEA Java 开发首选 IDE,适合 Spring Boot 项目
Eclipse 老牌 Java IDE
VS Code 可用于简单 Java 学习,但大型项目不如 IDEA
DataGrip 数据库管理工具
Navicat 数据库可视化工具
Postman 接口测试工具
Apifox 接口文档、调试、Mock 一体化工具
Git 版本控制
Maven / Gradle 项目构建和依赖管理

五、Java 程序执行流程

Java 代码不是直接运行的,而是先编译成字节码,再由 JVM 执行。

text 复制代码
HelloWorld.java 源代码
        ↓ javac 编译
HelloWorld.class 字节码
        ↓ JVM 执行
程序运行

示例:

java 复制代码
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello Java");
    }
}

编译:

bash 复制代码
javac HelloWorld.java

运行:

bash 复制代码
java HelloWorld

main 方法说明

java 复制代码
public static void main(String[] args)

含义:

关键字 说明
public 公共访问权限
static 静态方法,不需要创建对象即可调用
void 没有返回值
main 程序入口方法名
String\[\] args 命令行参数

六、Java 基础语法

1. 注释

java 复制代码
// 单行注释

/*
 多行注释
*/

/**
 * 文档注释
 */

2. 变量

变量是用来存储数据的容器。

java 复制代码
int age = 18;
String name = "张三";
double price = 99.9;
boolean isLogin = true;

3. 常量

Java 使用 final 定义常量。

java 复制代码
final double PI = 3.1415926;

常量一般使用大写命名:

java 复制代码
final int MAX_COUNT = 100;

4. 基本数据类型

Java 有 8 种基本数据类型。

类型 占用空间 默认值 示例 说明
byte 1 字节 0 byte b = 10; 小整数
short 2 字节 0 short s = 100; 短整数
int 4 字节 0 int age = 18; 常用整数
long 8 字节 0L long id = 100L; 长整数
float 4 字节 0.0F float f = 3.14F; 单精度小数
double 8 字节 0.0D double d = 3.14; 双精度小数
char 2 字节 '\u0000' char c = 'A'; 字符
boolean 依 JVM 而定 false boolean ok = true; 布尔值

5. 引用数据类型

引用类型包括:

  • 接口
  • 数组
  • 枚举
  • 注解
  • String
  • 集合对象

示例:

java 复制代码
String username = "admin";
User user = new User();
int[] nums = {1, 2, 3};

6. 运算符

算术运算符

java 复制代码
int a = 10;
int b = 3;

System.out.println(a + b); // 13
System.out.println(a - b); // 7
System.out.println(a * b); // 30
System.out.println(a / b); // 3
System.out.println(a % b); // 1

比较运算符

java 复制代码
System.out.println(a > b);
System.out.println(a >= b);
System.out.println(a < b);
System.out.println(a == b);
System.out.println(a != b);

逻辑运算符

java 复制代码
boolean x = true;
boolean y = false;

System.out.println(x && y); // false
System.out.println(x || y); // true
System.out.println(!x);     // false

7. 条件判断

java 复制代码
int score = 85;

if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

8. switch

java 复制代码
int type = 2;

switch (type) {
    case 1:
        System.out.println("普通用户");
        break;
    case 2:
        System.out.println("管理员");
        break;
    default:
        System.out.println("未知角色");
}

较新版本 Java 支持更简洁的 switch 表达式:

java 复制代码
String role = switch (type) {
    case 1 -> "普通用户";
    case 2 -> "管理员";
    default -> "未知角色";
};

9. 循环

for 循环

java 复制代码
for (int i = 0; i < 5; i++) {
    System.out.println(i);
}

while 循环

java 复制代码
int i = 0;
while (i < 5) {
    System.out.println(i);
    i++;
}

do-while 循环

java 复制代码
int num = 0;
do {
    System.out.println(num);
    num++;
} while (num < 5);

增强 for 循环

java 复制代码
int[] arr = {1, 2, 3};

for (int item : arr) {
    System.out.println(item);
}

10. break 和 continue

java 复制代码
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
    System.out.println(i);
}

break:结束整个循环。

java 复制代码
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        continue;
    }
    System.out.println(i);
}

continue:跳过本次循环,继续下一次循环。


七、方法、数组与字符串

1. 方法定义

java 复制代码
public static int add(int a, int b) {
    return a + b;
}

调用:

java 复制代码
int result = add(10, 20);
System.out.println(result);

2. 方法重载

同一个类中,方法名相同,参数列表不同,叫方法重载。

java 复制代码
public int add(int a, int b) {
    return a + b;
}

public double add(double a, double b) {
    return a + b;
}

public int add(int a, int b, int c) {
    return a + b + c;
}

3. 数组

java 复制代码
int[] nums = {10, 20, 30};
System.out.println(nums[0]);
System.out.println(nums.length);

遍历数组:

java 复制代码
for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
}

二维数组:

java 复制代码
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6}
};

System.out.println(matrix[0][1]); // 2

4. String 字符串

java 复制代码
String str = "hello java";

System.out.println(str.length());
System.out.println(str.toUpperCase());
System.out.println(str.contains("java"));
System.out.println(str.replace("java", "spring"));

字符串比较:

java 复制代码
String a = "abc";
String b = new String("abc");

System.out.println(a == b);      // false,比较地址
System.out.println(a.equals(b)); // true,比较内容

实际项目中,字符串内容比较用:

java 复制代码
"admin".equals(username)

这样可以避免 username 为 null 导致空指针异常。

5. StringBuilder

适合大量字符串拼接。

java 复制代码
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("Java");

System.out.println(sb.toString());

八、面向对象编程 OOP

Java 的核心是面向对象。面向对象的四大基础思想:

  • 类和对象
  • 封装
  • 继承
  • 多态

1. 类和对象

类是模板,对象是具体实例。

java 复制代码
public class User {
    String username;
    int age;

    public void sayHello() {
        System.out.println("你好,我是" + username);
    }
}

创建对象:

java 复制代码
User user = new User();
user.username = "admin";
user.age = 20;
user.sayHello();

2. 构造方法

构造方法用于创建对象时初始化属性。

java 复制代码
public class User {
    private String username;
    private int age;

    public User(String username, int age) {
        this.username = username;
        this.age = age;
    }
}

3. this 关键字

this 表示当前对象。

java 复制代码
public void setUsername(String username) {
    this.username = username;
}

4. 封装

封装是把属性私有化,通过 getter/setter 控制访问。

java 复制代码
public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能小于0");
        }
        this.age = age;
    }
}

封装的好处:

  • 数据更安全
  • 控制访问规则
  • 降低外部依赖
  • 方便后期维护

5. 继承

继承用于复用父类代码。

java 复制代码
public class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}

public class Dog extends Animal {
    public void bark() {
        System.out.println("狗叫");
    }
}

使用:

java 复制代码
Dog dog = new Dog();
dog.eat();
dog.bark();

6. 方法重写

子类重写父类方法。

java 复制代码
public class Animal {
    public void eat() {
        System.out.println("动物吃东西");
    }
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

7. 多态

父类引用指向子类对象。

java 复制代码
Animal animal = new Cat();
animal.eat();

多态的好处:

  • 提高扩展性
  • 降低耦合
  • 支持面向接口编程
  • 适合框架和业务抽象

8. 抽象类

抽象类不能直接创建对象,适合定义通用模板。

java 复制代码
public abstract class Shape {
    public abstract double area();

    public void print() {
        System.out.println("图形面积:" + area());
    }
}

子类实现:

java 复制代码
public class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

9. 接口

接口定义能力和规范。

java 复制代码
public interface PayService {
    void pay(BigDecimal amount);
}

实现类:

java 复制代码
public class AliPayService implements PayService {
    @Override
    public void pay(BigDecimal amount) {
        System.out.println("支付宝支付:" + amount);
    }
}

实际项目中常见写法:

java 复制代码
public interface UserService {
    User getById(Long id);
}

@Service
public class UserServiceImpl implements UserService {
    @Override
    public User getById(Long id) {
        return new User();
    }
}

10. 接口和抽象类区别

对比 接口 抽象类
设计目的 定义能力规范 抽取共性模板
继承数量 一个类可实现多个接口 一个类只能继承一个抽象类
成员变量 默认 public static final 可以有普通成员变量
方法 抽象方法、默认方法、静态方法 抽象方法、普通方法
使用场景 支付接口、通知接口、业务服务接口 模板方法、公共父类

九、常用 API 与工具类

1. Object 类

所有类默认继承 Object。

常用方法:

方法 说明
toString() 对象字符串表示
equals() 判断对象是否相等
hashCode() 返回对象哈希值
getClass() 获取对象 Class 信息

2. Math

java 复制代码
System.out.println(Math.max(10, 20));
System.out.println(Math.min(10, 20));
System.out.println(Math.sqrt(16));
System.out.println(Math.random());

3. BigDecimal

金额计算不要使用 double,推荐 BigDecimal。

java 复制代码
BigDecimal price = new BigDecimal("99.90");
BigDecimal count = new BigDecimal("3");
BigDecimal total = price.multiply(count);

System.out.println(total);

4. LocalDate、LocalDateTime

java 复制代码
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(now.format(formatter));

5. UUID

java 复制代码
String id = UUID.randomUUID().toString();
System.out.println(id);

常用于生成唯一标识。


十、集合框架

Java 集合用于存储多个对象,比数组更灵活。

主要接口:

text 复制代码
Collection
 ├── List
 ├── Set
 └── Queue

Map
 ├── HashMap
 ├── TreeMap
 └── ConcurrentHashMap

1. List

特点:有序、可重复。

java 复制代码
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Spring");
list.add("MySQL");

System.out.println(list.get(0));

常见实现:

实现类 特点
ArrayList 基于数组,查询快,尾部新增快
LinkedList 基于链表,插入删除较灵活
Vector 线程安全,较老,不常用

2. Set

特点:不可重复。

java 复制代码
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Java");
set.add("Spring");

System.out.println(set);

常见实现:

实现类 特点
HashSet 无序,去重
LinkedHashSet 保持插入顺序
TreeSet 可排序

3. Map

键值对结构。

java 复制代码
Map<String, Object> map = new HashMap<>();
map.put("username", "admin");
map.put("age", 20);

System.out.println(map.get("username"));

遍历:

java 复制代码
for (Map.Entry<String, Object> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

常见实现:

实现类 特点
HashMap 常用,线程不安全
LinkedHashMap 保持插入顺序
TreeMap 按 key 排序
Hashtable 线程安全,较老
ConcurrentHashMap 并发场景常用

4. ArrayList 和 LinkedList 区别

对比 ArrayList LinkedList
底层结构 动态数组 双向链表
查询
头部插入删除
随机访问 支持 不适合
使用场景 查询多 插入删除多

5. HashMap 底层原理

HashMap 底层主要由:

text 复制代码
数组 + 链表 + 红黑树

组成。

基本流程:

  1. 根据 key 的 hashCode 计算 hash 值
  2. 根据 hash 值定位数组下标
  3. 如果该位置没有元素,直接放入
  4. 如果有元素,比较 key 是否相同
  5. 如果 key 相同,覆盖 value
  6. 如果 key 不同,形成链表或红黑树
  7. 当链表长度较长且数组容量达到条件时,链表可能转为红黑树

十一、泛型

泛型可以让代码更安全、更通用。

1. 泛型集合

java 复制代码
List<String> names = new ArrayList<>();
names.add("张三");
// names.add(123); // 编译报错

2. 泛型类

java 复制代码
public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

使用:

java 复制代码
Result<String> result = new Result<>(200, "成功", "登录成功");
Result<User> userResult = new Result<>(200, "成功", new User());

3. 泛型方法

java 复制代码
public static <T> T getFirst(List<T> list) {
    if (list == null || list.isEmpty()) {
        return null;
    }
    return list.get(0);
}

4. 通配符

java 复制代码
public void printList(List<?> list) {
    for (Object item : list) {
        System.out.println(item);
    }
}

上界:

java 复制代码
public void printNumbers(List<? extends Number> list) {
    for (Number number : list) {
        System.out.println(number);
    }
}

下界:

java 复制代码
public void addInteger(List<? super Integer> list) {
    list.add(1);
}

十二、异常处理

异常用于处理程序运行中的错误。

1. 异常体系

text 复制代码
Throwable
 ├── Error
 └── Exception
      ├── RuntimeException
      └── Checked Exception
类型 说明
Error 严重错误,例如 OOM、StackOverflowError
Checked Exception 编译期异常,必须处理
RuntimeException 运行时异常,可选择处理

2. try-catch

java 复制代码
try {
    int result = 10 / 0;
    System.out.println(result);
} catch (ArithmeticException e) {
    System.out.println("计算异常:" + e.getMessage());
} catch (Exception e) {
    System.out.println("系统异常:" + e.getMessage());
}

3. finally

java 复制代码
try {
    System.out.println("执行代码");
} catch (Exception e) {
    System.out.println("捕获异常");
} finally {
    System.out.println("释放资源");
}

4. throw 和 throws

throw:主动抛出异常。

java 复制代码
throw new RuntimeException("用户名不能为空");

throws:声明方法可能抛出异常。

java 复制代码
public void readFile() throws IOException {
    FileReader reader = new FileReader("test.txt");
}

5. 自定义业务异常

java 复制代码
public class BusinessException extends RuntimeException {
    public BusinessException(String message) {
        super(message);
    }
}

使用:

java 复制代码
if (user == null) {
    throw new BusinessException("用户不存在");
}

6. Spring Boot 全局异常处理

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusinessException(BusinessException e) {
        return Result.fail(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        return Result.fail("系统异常,请稍后再试");
    }
}

十三、IO、NIO 与文件操作

1. 字节流

适合处理图片、视频、压缩包等二进制文件。

java 复制代码
try (FileInputStream fis = new FileInputStream("input.txt")) {
    int data;
    while ((data = fis.read()) != -1) {
        System.out.print((char) data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

2. 字符流

适合处理文本文件。

java 复制代码
try (FileReader reader = new FileReader("input.txt")) {
    int data;
    while ((data = reader.read()) != -1) {
        System.out.print((char) data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

3. BufferedReader

java 复制代码
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

4. Files 工具类

java 复制代码
Path path = Paths.get("test.txt");
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);

for (String line : lines) {
    System.out.println(line);
}

写入文件:

java 复制代码
Files.writeString(
    Paths.get("output.txt"),
    "Hello Java",
    StandardCharsets.UTF_8
);

十四、Lambda、Stream API 与 Optional

1. Lambda 表达式

Lambda 可以简化函数式接口写法。

传统写法:

java 复制代码
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("线程执行");
    }
});

Lambda 写法:

java 复制代码
Thread thread = new Thread(() -> System.out.println("线程执行"));

2. Stream API

适合集合过滤、转换、排序、分组。

java 复制代码
List<User> users = List.of(
    new User("张三", 18),
    new User("李四", 25),
    new User("王五", 30)
);

List<User> result = users.stream()
    .filter(user -> user.getAge() >= 20)
    .toList();

3. map 转换

java 复制代码
List<String> names = users.stream()
    .map(User::getUsername)
    .toList();

4. 排序

java 复制代码
List<User> sortedUsers = users.stream()
    .sorted(Comparator.comparing(User::getAge))
    .toList();

5. 分组

java 复制代码
Map<Integer, List<User>> groupMap = users.stream()
    .collect(Collectors.groupingBy(User::getAge));

6. Optional

用于减少空指针异常。

java 复制代码
Optional<User> optionalUser = Optional.ofNullable(user);

String username = optionalUser
    .map(User::getUsername)
    .orElse("默认用户");

十五、多线程与并发编程

1. 创建线程

继承 Thread

java 复制代码
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程执行");
    }
}
java 复制代码
new MyThread().start();

实现 Runnable

java 复制代码
Runnable runnable = () -> System.out.println("Runnable 执行");
new Thread(runnable).start();

实现 Callable

java 复制代码
Callable<String> callable = () -> "任务结果";
FutureTask<String> task = new FutureTask<>(callable);
new Thread(task).start();

String result = task.get();

2. 线程生命周期

text 复制代码
NEW 新建
RUNNABLE 就绪/运行
BLOCKED 阻塞
WAITING 等待
TIMED_WAITING 限时等待
TERMINATED 结束

3. synchronized

java 复制代码
public synchronized void add() {
    count++;
}

也可以锁代码块:

java 复制代码
synchronized (this) {
    count++;
}

4. volatile

volatile 可以保证变量的可见性,不能保证复合操作的原子性。

java 复制代码
private volatile boolean running = true;

5. ReentrantLock

java 复制代码
private final ReentrantLock lock = new ReentrantLock();

public void add() {
    lock.lock();
    try {
        count++;
    } finally {
        lock.unlock();
    }
}

6. 线程池

项目中不建议频繁 new Thread,推荐使用线程池。

java 复制代码
ExecutorService executor = Executors.newFixedThreadPool(5);

executor.submit(() -> {
    System.out.println("执行任务");
});

executor.shutdown();

更推荐手动创建 ThreadPoolExecutor:

java 复制代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,
    10,
    60,
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100),
    Executors.defaultThreadFactory(),
    new ThreadPoolExecutor.CallerRunsPolicy()
);

7. 线程池核心参数

参数 说明
corePoolSize 核心线程数
maximumPoolSize 最大线程数
keepAliveTime 空闲线程存活时间
unit 时间单位
workQueue 任务队列
threadFactory 线程工厂
handler 拒绝策略

8. CompletableFuture

适合异步编排。

java 复制代码
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    return "查询用户信息";
});

String result = future.get();

组合任务:

java 复制代码
CompletableFuture<String> userFuture = CompletableFuture.supplyAsync(() -> "用户信息");
CompletableFuture<String> orderFuture = CompletableFuture.supplyAsync(() -> "订单信息");

CompletableFuture<Void> all = CompletableFuture.allOf(userFuture, orderFuture);
all.join();

十六、JVM 核心原理

1. JVM 是什么?

JVM 是 Java 虚拟机,负责运行 Java 字节码。

Java 跨平台的核心原因:

text 复制代码
同一份 Java 字节码,可以运行在不同操作系统对应的 JVM 上。

2. JVM 内存结构

区域 线程是否共享 作用
程序计数器 线程私有 记录当前线程执行位置
Java 虚拟机栈 线程私有 存储方法调用栈、局部变量
本地方法栈 线程私有 Native 方法调用
线程共享 存储对象实例
方法区 / 元空间 线程共享 存储类信息、常量、静态变量等

3. 对象创建过程

java 复制代码
User user = new User();

大致过程:

  1. 类加载检查
  2. 分配内存
  3. 初始化零值
  4. 设置对象头
  5. 执行构造方法
  6. 引用指向对象

4. 类加载机制

类加载过程:

text 复制代码
加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载

5. 双亲委派模型

类加载器收到加载请求后,先交给父加载器尝试加载,父加载器无法加载时,子加载器再加载。

好处:

  • 避免核心类被篡改
  • 避免类重复加载
  • 保证 Java 核心 API 安全

6. 垃圾回收 GC

Java 会自动回收不再使用的对象。

判断对象是否可回收:

  • 引用计数法
  • 可达性分析算法

Java 主流使用可达性分析。

7. GC Roots 常见对象

  • 虚拟机栈中的引用对象
  • 方法区中的静态属性引用对象
  • 方法区中的常量引用对象
  • 本地方法栈 JNI 引用对象
  • 活跃线程引用对象

8. 常见 GC 算法

算法 说明
标记-清除 标记垃圾对象后清除,会产生内存碎片
标记-整理 清除后整理内存,减少碎片
复制算法 将存活对象复制到另一块区域
分代收集 新生代、老年代使用不同回收策略

9. 常见 JVM 参数

参数 说明
-Xms 初始堆大小
-Xmx 最大堆大小
-Xss 每个线程栈大小
-XX:+UseG1GC 使用 G1 垃圾回收器
-XX:+HeapDumpOnOutOfMemoryError OOM 时导出堆快照
-XX:HeapDumpPath 堆快照输出路径

示例:

bash 复制代码
java -Xms512m -Xmx1024m -XX:+UseG1GC -jar app.jar

十七、数据库与 MySQL

Java 后端开发必须掌握数据库。

1. SQL 基础

查询

sql 复制代码
SELECT id, username, age FROM user WHERE id = 1;

新增

sql 复制代码
INSERT INTO user(username, password, age) VALUES('admin', '123456', 20);

修改

sql 复制代码
UPDATE user SET username = 'newAdmin' WHERE id = 1;

删除

sql 复制代码
DELETE FROM user WHERE id = 1;

2. 表设计示例

sql 复制代码
CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(100) NOT NULL,
    nickname VARCHAR(50),
    email VARCHAR(100),
    status TINYINT DEFAULT 1,
    create_time DATETIME,
    update_time DATETIME
);

3. 索引

sql 复制代码
CREATE INDEX idx_username ON user(username);

索引优点:

  • 提升查询速度
  • 支持排序优化
  • 支持唯一约束

索引缺点:

  • 占用空间
  • 降低新增、修改、删除速度
  • 不合理索引会影响性能

4. 事务

事务保证一组操作要么全部成功,要么全部失败。

ACID:

特性 说明
Atomicity 原子性 要么全部成功,要么全部失败
Consistency 一致性 数据从一个一致状态到另一个一致状态
Isolation 隔离性 并发事务之间互不干扰
Durability 持久性 提交后数据永久保存

十八、JDBC、MyBatis、MyBatis-Plus、JPA

1. JDBC

JDBC 是 Java 操作数据库的基础 API。

java 复制代码
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/demo",
    "root",
    "123456"
);

PreparedStatement ps = conn.prepareStatement("SELECT * FROM user WHERE id = ?");
ps.setLong(1, 1L);
ResultSet rs = ps.executeQuery();

实际项目中不会大量手写 JDBC,通常使用 MyBatis、MyBatis-Plus 或 JPA。

2. MyBatis

Mapper 接口:

java 复制代码
@Mapper
public interface UserMapper {
    User selectById(Long id);
}

XML:

xml 复制代码
<select id="selectById" resultType="com.example.entity.User">
    SELECT * FROM user WHERE id = #{id}
</select>

3. MyBatis-Plus

Mapper:

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

查询:

java 复制代码
User user = userMapper.selectById(1L);

条件查询:

java 复制代码
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUsername, "admin");

User user = userMapper.selectOne(wrapper);

4. JPA / Hibernate

实体类:

java 复制代码
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
}

Repository:

java 复制代码
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

5. MyBatis 和 JPA 区别

对比 MyBatis JPA/Hibernate
SQL 控制 强,手写 SQL 灵活 自动生成 SQL 较多
学习成本 中等 较高
复杂查询 适合 需要理解 ORM 机制
国内项目 非常常见 部分项目使用
适合场景 复杂业务、SQL 优化 领域模型清晰、CRUD 较多

十九、Java Web 与 HTTP 基础

1. HTTP 请求方法

方法 作用
GET 查询数据
POST 新增数据、提交表单
PUT 修改完整数据
PATCH 修改部分数据
DELETE 删除数据

2. HTTP 状态码

状态码 说明
200 成功
201 创建成功
400 请求参数错误
401 未登录
403 无权限
404 资源不存在
500 服务器异常

3. RESTful API 示例

操作 请求
查询用户列表 GET /users
查询单个用户 GET /users/{id}
新增用户 POST /users
修改用户 PUT /users/{id}
删除用户 DELETE /users/{id}

4. Servlet

Servlet 是 Java Web 的底层基础。

java 复制代码
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().write("Hello Servlet");
    }
}

现在企业开发一般不直接写 Servlet,而是使用 Spring MVC / Spring Boot。


二十、Spring、Spring MVC、Spring Boot

1. Spring 核心思想

Spring 的核心:

  • IOC:控制反转
  • DI:依赖注入
  • AOP:面向切面编程

2. IOC 和 DI

传统写法:

java 复制代码
UserService userService = new UserServiceImpl();

Spring 写法:

java 复制代码
@Service
public class UserServiceImpl implements UserService {
}

@RestController
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }
}

对象由 Spring 容器创建和管理。

3. AOP

AOP 适合处理横切逻辑:

  • 日志记录
  • 权限校验
  • 事务控制
  • 接口耗时统计
  • 统一异常处理

示例:

java 复制代码
@Aspect
@Component
public class LogAspect {

    @Around("execution(* com.example.controller..*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        System.out.println("接口耗时:" + (end - start) + "ms");
        return result;
    }
}

4. Spring Boot 项目结构

text 复制代码
src
 └── main
     ├── java
     │   └── com.example.demo
     │       ├── DemoApplication.java
     │       ├── controller
     │       ├── service
     │       ├── service.impl
     │       ├── mapper
     │       ├── entity
     │       ├── dto
     │       ├── vo
     │       ├── config
     │       ├── common
     │       └── exception
     └── resources
         ├── application.yml
         └── mapper

5. Spring Boot 启动类

java 复制代码
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

6. Controller

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public Result<UserVO> getUser(@PathVariable Long id) {
        return Result.success(userService.getUser(id));
    }
}

7. Service

java 复制代码
public interface UserService {
    UserVO getUser(Long id);
}
java 复制代码
@Service
public class UserServiceImpl implements UserService {
    @Override
    public UserVO getUser(Long id) {
        return new UserVO();
    }
}

8. 配置文件 application.yml

yaml 复制代码
server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

9. 统一返回结果

java 复制代码
@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("成功");
        result.setData(data);
        return result;
    }

    public static <T> Result<T> fail(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMessage(message);
        return result;
    }
}

10. 参数校验

DTO:

java 复制代码
@Data
public class LoginDTO {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
}

Controller:

java 复制代码
@PostMapping("/login")
public Result<String> login(@Valid @RequestBody LoginDTO loginDTO) {
    return Result.success("登录成功");
}

二十一、登录注册、JWT、权限拦截

1. 登录流程

text 复制代码
1. 前端输入用户名和密码
2. 调用后端 /login 接口
3. 后端查询用户是否存在
4. 校验密码是否正确
5. 登录成功生成 JWT Token
6. 前端保存 token
7. 后续请求在 Authorization 请求头携带 token
8. 后端拦截器或过滤器校验 token
9. 校验通过访问接口,否则返回 401

2. 登录接口示例

java 复制代码
@PostMapping("/login")
public Result<String> login(@Valid @RequestBody LoginDTO loginDTO) {
    String token = userService.login(loginDTO);
    return Result.success(token);
}

3. 前端携带 Token

javascript 复制代码
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
  }
  return config
})

4. 后端拦截器

java 复制代码
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authorization = request.getHeader("Authorization");

        if (authorization == null || !authorization.startsWith("Bearer ")) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }

        String token = authorization.substring(7);
        // 校验 token
        return true;
    }
}

5. 注册拦截器

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/login", "/register");
    }
}

6. 权限模型

常见权限模型:

text 复制代码
用户 User
角色 Role
权限 Permission

关系:

text 复制代码
一个用户可以有多个角色
一个角色可以有多个权限

常见表:

  • user
  • role
  • permission
  • user_role
  • role_permission

二十二、Redis、消息队列、搜索、缓存

1. Redis

Redis 常用场景:

  • 登录 token 存储
  • 验证码缓存
  • 热点数据缓存
  • 分布式锁
  • 排行榜
  • 限流
  • 会话共享

Spring Boot 使用 Redis:

java 复制代码
@Resource
private StringRedisTemplate stringRedisTemplate;

public void saveCode(String phone, String code) {
    stringRedisTemplate.opsForValue().set("code:" + phone, code, 5, TimeUnit.MINUTES);
}

2. 缓存穿透、击穿、雪崩

问题 说明 解决方案
缓存穿透 查询不存在的数据,绕过缓存打到数据库 缓存空值、布隆过滤器
缓存击穿 热点 key 失效,大量请求打到数据库 互斥锁、逻辑过期
缓存雪崩 大量 key 同时失效 过期时间随机化、限流、降级

3. 消息队列 MQ

常见 MQ:

  • RabbitMQ
  • Kafka
  • RocketMQ

应用场景:

  • 异步处理
  • 削峰填谷
  • 订单超时取消
  • 日志收集
  • 系统解耦

4. Elasticsearch

适合搜索场景:

  • 商品搜索
  • 文章搜索
  • 日志搜索
  • 后台模糊查询

二十三、Maven、Gradle 与项目构建

1. Maven 是什么?

Maven 用于:

  • 管理依赖
  • 编译项目
  • 运行测试
  • 打包项目
  • 管理项目结构

2. pom.xml 示例

xml 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>

3. Maven 常用命令

命令 作用
mvn clean 清理构建文件
mvn compile 编译源码
mvn test 运行测试
mvn package 打包
mvn install 安装到本地仓库
mvn spring-boot:run 启动 Spring Boot 项目

4. Gradle 简介

Gradle 也是构建工具,常用于 Java、Kotlin、Android 项目。

build.gradle 示例:

groovy 复制代码
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.14'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

二十四、Docker、Linux、Nginx 部署

1. Spring Boot 打包

bash 复制代码
mvn clean package

生成:

text 复制代码
target/demo-0.0.1-SNAPSHOT.jar

启动:

bash 复制代码
java -jar demo-0.0.1-SNAPSHOT.jar

后台启动:

bash 复制代码
nohup java -jar demo.jar > app.log 2>&1 &

2. Dockerfile

dockerfile 复制代码
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/demo.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

构建镜像:

bash 复制代码
docker build -t demo-app .

运行容器:

bash 复制代码
docker run -d -p 8080:8080 --name demo demo-app

3. Nginx 反向代理

nginx 复制代码
server {
    listen 80;
    server_name example.com;

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        root /www/wwwroot/frontend;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}

4. 前后端分离部署结构

text 复制代码
用户浏览器
    ↓
Nginx
 ├── /        → Vue/React 静态文件
 └── /api     → Spring Boot 8080
                     ↓
                   MySQL / Redis

二十五、Java 企业级项目结构

推荐结构:

text 复制代码
mall-admin
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com.example.mall
│   │   │       ├── MallApplication.java
│   │   │       ├── common
│   │   │       │   ├── Result.java
│   │   │       │   └── PageResult.java
│   │   │       ├── config
│   │   │       ├── controller
│   │   │       ├── service
│   │   │       ├── service.impl
│   │   │       ├── mapper
│   │   │       ├── entity
│   │   │       ├── dto
│   │   │       ├── vo
│   │   │       ├── exception
│   │   │       ├── interceptor
│   │   │       └── utils
│   │   └── resources
│   │       ├── application.yml
│   │       └── mapper
│   └── test
└── README.md

目录说明:

目录 作用
common 公共返回对象、常量、分页对象
config 配置类,如跨域、拦截器、Redis
controller 接口控制层
service 业务接口
service.impl 业务实现
mapper 数据库访问层
entity 数据库实体类
dto 接收前端参数
vo 返回前端视图对象
exception 异常处理
interceptor 登录拦截器
utils 工具类

二十六、Java 学习路线

阶段 1:Java 基础

学习重点:

  • 环境安装
  • 基础语法
  • 数据类型
  • 运算符
  • 流程控制
  • 数组
  • 方法
  • 类和对象
  • 封装、继承、多态
  • 接口、抽象类

目标:能独立写控制台小程序。

阶段 2:Java 进阶

学习重点:

  • String
  • 集合框架
  • 泛型
  • 异常
  • IO
  • Lambda
  • Stream
  • Optional
  • 反射
  • 注解
  • 枚举
  • 多线程

目标:理解 Java 常用 API 和基础底层思想。

阶段 3:数据库

学习重点:

  • MySQL 基础
  • SQL 查询
  • 表设计
  • 索引
  • 事务
  • JDBC
  • MyBatis
  • MyBatis-Plus

目标:能完成用户、商品、订单等表的增删改查。

阶段 4:Spring Boot

学习重点:

  • Spring IOC
  • Spring AOP
  • Spring MVC
  • Spring Boot
  • RESTful API
  • 参数校验
  • 全局异常
  • 统一返回
  • 文件上传
  • 登录注册
  • JWT 权限

目标:能写完整后端接口。

阶段 5:前后端分离项目

推荐做:

  • 登录注册系统
  • 用户管理系统
  • 权限管理系统
  • 博客系统
  • 商品管理系统
  • 后台管理系统

目标:完成 Vue/React + Spring Boot + MySQL 项目。

阶段 6:企业进阶

学习重点:

  • Redis
  • MQ
  • Elasticsearch
  • Docker
  • Linux
  • Nginx
  • Jenkins
  • Spring Cloud
  • 微服务
  • 分布式锁
  • 分布式事务
  • 高并发优化

目标:具备企业项目开发和面试竞争力。


二十七、Java 官方文档与相关资源表

1. Java 官方资源

资源 地址 用途
Oracle Java 下载 https://www.oracle.com/java/technologies/downloads/ 下载 JDK
Oracle Java 中文下载页 https://www.oracle.com/tw/java/technologies/downloads/ 下载 JDK,可查看当前版本
Java SE API 文档 https://www.oracle.com/java/technologies/java-se-api-doc.html 查询 Java 标准库 API
Oracle Java 文档入口 https://docs.oracle.com/en/java/ Java 官方文档
OpenJDK https://openjdk.org/ 开源 JDK 项目
OpenJDK JDK 项目 https://openjdk.org/projects/jdk/ JDK 版本项目
dev.java https://dev.java/ Oracle 提供的 Java 学习入口
Java Language Specification https://docs.oracle.com/javase/specs/ Java 语言规范
Java Virtual Machine Specification https://docs.oracle.com/javase/specs/jvms/se25/html/ JVM 规范

2. Spring 生态官方资源

资源 地址 用途
Spring 官网 https://spring.io/ Spring 生态入口
Spring Framework https://spring.io/projects/spring-framework Spring 核心框架
Spring Framework Docs https://docs.spring.io/spring-framework/reference/ Spring 参考文档
Spring Boot https://spring.io/projects/spring-boot Spring Boot 项目页
Spring Boot Docs https://docs.spring.io/spring-boot/index.html Spring Boot 文档
Spring Security https://spring.io/projects/spring-security 权限安全框架
Spring Security Docs https://docs.spring.io/spring-security/reference/ 安全认证文档
Spring Initializr https://start.spring.io/ 在线创建 Spring Boot 项目
Spring Guides https://spring.io/guides Spring 官方教程

3. 数据库与 ORM 资源

资源 地址 用途
MySQL 文档 https://dev.mysql.com/doc/ MySQL 官方文档
MyBatis https://mybatis.org/mybatis-3/ MyBatis 官方文档
MyBatis-Spring-Boot https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/ MyBatis Spring Boot 集成
MyBatis-Plus https://baomidou.com/ MyBatis-Plus 官方文档
Hibernate ORM https://hibernate.org/orm/documentation/ Hibernate ORM 文档

4. 构建、部署与运维资源

资源 地址 用途
Maven https://maven.apache.org/guides/index.html Maven 官方指南
Maven Getting Started https://maven.apache.org/guides/getting-started/ Maven 入门
Gradle Docs https://docs.gradle.org/ Gradle 官方文档
Docker Docs https://docs.docker.com/ Docker 官方文档
Redis Docs https://redis.io/docs/latest/ Redis 官方文档
Nginx Docs https://nginx.org/en/docs/ Nginx 官方文档
Kubernetes Docs https://kubernetes.io/docs/home/ K8s 官方文档

5. 接口、测试与工具资源

工具 地址 用途
Postman https://www.postman.com/ API 调试
Apifox https://apifox.com/ API 文档、调试、Mock
IntelliJ IDEA https://www.jetbrains.com/idea/ Java IDE
Git https://git-scm.com/ 版本控制
GitHub https://github.com/ 代码托管
Gitee https://gitee.com/ 国内代码托管
Navicat https://www.navicat.com/ 数据库管理
DBeaver https://dbeaver.io/ 免费数据库管理工具

二十八、Java 面试题与答案

下面整理 80 道 Java 常见面试题,覆盖 Java 基础、集合、JVM、并发、数据库、Spring Boot、Redis、微服务与项目。


一、Java 基础面试题

1. Java 有哪些基本数据类型?

Java 有 8 种基本数据类型:

  • byte
  • short
  • int
  • long
  • float
  • double
  • char
  • boolean

其中整数默认是 int,小数默认是 double。


2. Java 是值传递还是引用传递?

Java 只有值传递。

如果传递的是基本类型,传递的是值的副本。

如果传递的是对象引用,传递的是引用地址的副本。

所以方法中可以修改对象内部属性,但不能让外部引用指向一个新对象。


3. ==equals() 的区别?

==

  • 基本类型比较值
  • 引用类型比较内存地址

equals()

  • 默认比较地址
  • 很多类重写后比较内容,例如 String、Integer

示例:

java 复制代码
String a = new String("abc");
String b = new String("abc");

System.out.println(a == b);      // false
System.out.println(a.equals(b)); // true

4. String 为什么不可变?

String 内部用于存储字符的数据结构被设计为不可随意修改,同时 String 类本身是 final 类。

不可变的好处:

  • 线程安全
  • 可以被字符串常量池复用
  • 适合作为 HashMap 的 key
  • 避免被恶意修改,例如数据库连接地址、文件路径

5. String、StringBuilder、StringBuffer 区别?

类型 是否可变 是否线程安全 场景
String 不可变 安全 少量字符串
StringBuilder 可变 不安全 单线程大量拼接
StringBuffer 可变 安全 多线程拼接

实际项目中,单线程拼接优先使用 StringBuilder。


6. final、finally、finalize 区别?

  • final:修饰类、方法、变量。类不能被继承,方法不能被重写,变量不能重新赋值。
  • finally:异常处理中一定会执行的代码块,常用于释放资源。
  • finalize:Object 的方法,垃圾回收前可能被调用,已经不推荐使用。

7. 抽象类和接口区别?

抽象类适合描述共性模板,接口适合定义能力规范。

一个类只能继承一个抽象类,但可以实现多个接口。


8. 重载和重写区别?

重载 Overload:同一个类中,方法名相同,参数列表不同。

重写 Override:子类重新实现父类方法,方法签名通常相同。


9. static 关键字有什么作用?

static 可以修饰:

  • 变量:类变量,所有对象共享
  • 方法:类方法,不需要创建对象即可调用
  • 代码块:类加载时执行
  • 内部类:静态内部类

10. this 和 super 的区别?

this 表示当前对象。

super 表示父类对象。

常见用途:

  • this 调用当前类属性、方法、构造器
  • super 调用父类属性、方法、构造器

二、集合面试题

11. ArrayList 和 LinkedList 区别?

ArrayList 底层是动态数组,查询快,随机访问快。

LinkedList 底层是双向链表,头尾插入删除较方便,但随机访问慢。


12. ArrayList 扩容机制是什么?

ArrayList 底层数组容量不够时会扩容。常见实现中,新容量通常约为原容量的 1.5 倍,然后把旧数组元素复制到新数组中。

因此,如果能提前知道数据量,建议初始化容量:

java 复制代码
List<String> list = new ArrayList<>(1000);

13. HashMap 底层结构是什么?

HashMap 底层是:

text 复制代码
数组 + 链表 + 红黑树

当发生 hash 冲突时,会形成链表;链表过长且数组容量达到一定条件时,会转换为红黑树,提高查询效率。


14. HashMap 为什么线程不安全?

因为多个线程同时 put、resize、修改链表或红黑树时,可能导致数据覆盖、数据丢失、结构异常等问题。

并发场景推荐使用:

java 复制代码
ConcurrentHashMap

15. HashMap 和 Hashtable 区别?

对比 HashMap Hashtable
线程安全 不安全 安全
性能 较高 较低
null key/value 允许 不允许
是否推荐 推荐单线程使用 不推荐新项目使用

16. HashMap 和 ConcurrentHashMap 区别?

HashMap 线程不安全,适合单线程。

ConcurrentHashMap 线程安全,适合并发场景。

ConcurrentHashMap 通过更细粒度的并发控制提升性能,不是简单地给整个 Map 加 synchronized。


17. List、Set、Map 区别?

  • List:有序、可重复
  • Set:不可重复
  • Map:键值对结构,key 不可重复

18. 如何实现集合去重?

可以使用 Set:

java 复制代码
List<String> list = List.of("a", "b", "a");
Set<String> set = new HashSet<>(list);

如果是对象去重,需要重写 equals()hashCode()


19. Iterator 遍历时能不能删除元素?

可以,但要使用 Iterator 的 remove() 方法,不能直接调用集合的 remove()

java 复制代码
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    if ("a".equals(item)) {
        iterator.remove();
    }
}

20. fail-fast 是什么?

fail-fast 是集合遍历时的一种快速失败机制。遍历过程中如果集合结构被非迭代器方式修改,可能抛出 ConcurrentModificationException


三、异常与泛型面试题

21. Checked Exception 和 RuntimeException 区别?

Checked Exception 是编译期异常,必须处理或声明抛出。

RuntimeException 是运行时异常,可以不强制处理。


22. throw 和 throws 区别?

throw 用于实际抛出异常对象。

throws 用于方法声明,表示该方法可能抛出异常。


23. 泛型有什么作用?

泛型的作用:

  • 提高类型安全
  • 避免强制类型转换
  • 提高代码复用性
  • 编译期发现类型错误

24. Java 泛型擦除是什么?

Java 泛型主要在编译期生效,编译后泛型类型信息会被擦除。运行时通常无法直接获取 List<String> 中的 String 泛型类型。


25. List<?>List<? extends T>List<? super T> 区别?

  • List<?>:未知类型,只适合读取 Object
  • List<? extends T>:上界通配符,适合读取 T 或其子类
  • List<? super T>:下界通配符,适合写入 T 或其子类

口诀:

PECS:Producer Extends,Consumer Super。


四、JVM 面试题

26. JVM 内存结构有哪些?

主要包括:

  • 程序计数器
  • Java 虚拟机栈
  • 本地方法栈
  • 方法区 / 元空间

其中堆和方法区是线程共享的,程序计数器、虚拟机栈、本地方法栈是线程私有的。


27. 堆和栈有什么区别?

栈:存储方法调用、局部变量、操作数栈,线程私有,生命周期随方法调用结束。

堆:存储对象实例,线程共享,由 GC 管理。


28. 什么是类加载机制?

类加载机制是 JVM 把 class 文件加载到内存,并完成验证、准备、解析、初始化的过程。

流程:

text 复制代码
加载 → 验证 → 准备 → 解析 → 初始化

29. 什么是双亲委派模型?

类加载器加载类时,会先委托父加载器加载,父加载器无法加载时,子加载器才尝试加载。

优点:

  • 避免类重复加载
  • 保护 Java 核心类库
  • 提高安全性

30. 如何判断对象是否可以被回收?

Java 主要使用可达性分析算法。

如果对象无法从 GC Roots 通过引用链到达,则认为对象可以被回收。


31. GC Roots 有哪些?

常见 GC Roots:

  • 虚拟机栈中的引用对象
  • 方法区中的静态变量引用对象
  • 方法区中的常量引用对象
  • 本地方法栈 JNI 引用对象
  • 活跃线程引用对象

32. Minor GC 和 Full GC 区别?

Minor GC:主要回收新生代。

Full GC:通常回收整个堆和方法区,开销更大,停顿时间更长。


33. 什么情况下会发生 OOM?

常见原因:

  • 堆内存不足
  • 大对象过多
  • 内存泄漏
  • 线程过多导致栈内存不足
  • 元空间加载类过多

34. StackOverflowError 是什么?

栈溢出错误,常见原因是递归过深或方法调用层级过多。

java 复制代码
public void test() {
    test();
}

35. 常见 JVM 调优参数有哪些?

常见参数:

bash 复制代码
-Xms512m
-Xmx1024m
-Xss1m
-XX:+UseG1GC
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/logs/heapdump.hprof

五、多线程与并发面试题

36. 创建线程有几种方式?

常见方式:

  • 继承 Thread
  • 实现 Runnable
  • 实现 Callable + FutureTask
  • 使用线程池
  • 使用 CompletableFuture

项目中推荐使用线程池。


37. start() 和 run() 区别?

start() 会启动新线程,由 JVM 调用 run 方法。

run() 只是普通方法调用,不会创建新线程。


38. synchronized 的作用是什么?

synchronized 用于保证线程安全,可以保证同一时刻只有一个线程进入同步代码块,同时具有可见性和互斥性。


39. synchronized 和 ReentrantLock 区别?

对比 synchronized ReentrantLock
类型 JVM 关键字 JDK 类
释放锁 自动释放 需要手动 unlock
可中断 不灵活 支持
公平锁 不支持直接设置 支持
条件队列 单一等待队列 多个 Condition

40. volatile 有什么作用?

volatile 保证变量的可见性和禁止指令重排序,但不能保证复合操作的原子性。

例如:

java 复制代码
volatile int count = 0;
count++; // 不是原子操作

41. 什么是死锁?

死锁是多个线程互相持有对方需要的锁,导致所有线程都无法继续执行。

产生条件:

  • 互斥条件
  • 请求并保持
  • 不可剥夺
  • 循环等待

42. 如何避免死锁?

  • 按固定顺序获取锁
  • 设置锁超时时间
  • 减少锁粒度
  • 避免嵌套锁
  • 使用 tryLock

43. 线程池核心参数有哪些?

  • corePoolSize
  • maximumPoolSize
  • keepAliveTime
  • unit
  • workQueue
  • threadFactory
  • rejectedExecutionHandler

44. 线程池拒绝策略有哪些?

常见拒绝策略:

  • AbortPolicy:抛异常
  • CallerRunsPolicy:调用者线程执行
  • DiscardPolicy:直接丢弃
  • DiscardOldestPolicy:丢弃队列最老任务

45. ThreadLocal 是什么?

ThreadLocal 为每个线程提供独立变量副本,常用于保存用户上下文、请求上下文、数据库连接等。

使用后要注意 remove,避免线程池场景下内存泄漏。


六、数据库与 MyBatis 面试题

46. 什么是事务?

事务是一组数据库操作,要么全部成功,要么全部失败。


47. ACID 是什么?

  • 原子性:全部成功或全部失败
  • 一致性:数据状态合法
  • 隔离性:并发事务互不干扰
  • 持久性:提交后永久保存

48. MySQL 隔离级别有哪些?

  • 读未提交 Read Uncommitted
  • 读已提交 Read Committed
  • 可重复读 Repeatable Read
  • 串行化 Serializable

49. 脏读、不可重复读、幻读是什么?

脏读:读到其他事务未提交的数据。

不可重复读:同一事务中两次读取同一行数据结果不同。

幻读:同一事务中两次范围查询,结果行数不同。


50. 索引为什么能提高查询速度?

索引可以减少数据库扫描的数据量。MySQL InnoDB 常用 B+ 树索引,可以通过树结构快速定位数据,而不是全表扫描。


51. B+ 树为什么适合做数据库索引?

原因:

  • 树高度低,磁盘 IO 少
  • 叶子节点有序,适合范围查询
  • 非叶子节点只存 key,可以容纳更多索引项
  • 查询性能稳定

52. 什么情况下索引会失效?

常见情况:

  • 对索引列使用函数
  • 使用左模糊 LIKE,例如 %abc
  • 隐式类型转换
  • 联合索引不满足最左前缀
  • OR 条件使用不当
  • 查询条件选择性太低

53. MyBatis 中 #{}${} 区别?

#{} 使用预编译,占位符方式,能防 SQL 注入。

${} 是字符串拼接,存在 SQL 注入风险。

一般参数传递使用 #{}


54. MyBatis 一级缓存和二级缓存区别?

一级缓存:SqlSession 级别,默认开启。

二级缓存:Mapper namespace 级别,需要配置开启。

实际项目中二级缓存使用要谨慎,复杂业务中容易出现数据一致性问题。


55. MyBatis-Plus 的优点是什么?

优点:

  • 简化 CRUD
  • 减少重复 SQL
  • 提供条件构造器
  • 支持分页插件
  • 支持代码生成
  • 与 MyBatis 兼容

七、Spring 与 Spring Boot 面试题

56. 什么是 IOC?

IOC 是控制反转,对象的创建和依赖关系不再由程序员手动控制,而是交给 Spring 容器管理。


57. 什么是 DI?

DI 是依赖注入,Spring 容器把对象依赖自动注入到需要的地方。

常见方式:

  • 构造器注入
  • Setter 注入
  • 字段注入

推荐构造器注入。


58. 什么是 AOP?

AOP 是面向切面编程,用于把日志、权限、事务、耗时统计等横切逻辑从业务代码中抽离出来。


59. Spring Bean 生命周期是什么?

大致流程:

  1. 实例化 Bean
  2. 属性赋值
  3. Aware 回调
  4. BeanPostProcessor 前置处理
  5. 初始化方法
  6. BeanPostProcessor 后置处理
  7. Bean 可使用
  8. 容器关闭时销毁 Bean

60. Spring 如何解决循环依赖?

Spring 通过三级缓存解决单例 Bean 的部分循环依赖。

但构造器循环依赖无法解决,因为对象还没创建完成就互相依赖。


61. Spring MVC 请求流程是什么?

流程:

text 复制代码
请求 → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → Service → 返回结果 → 视图/JSON响应

62. Spring Boot 自动配置原理是什么?

Spring Boot 根据 classpath 中的依赖、配置属性和条件注解自动装配 Bean,减少手动配置。

核心思想:

  • Starter 依赖
  • 自动配置类
  • 条件注解
  • 配置属性绑定

63. Spring Boot 常用注解有哪些?

常见注解:

  • @SpringBootApplication
  • @RestController
  • @RequestMapping
  • @GetMapping
  • @PostMapping
  • @Service
  • @Repository
  • @Component
  • @Autowired
  • @Configuration
  • @Bean
  • @Transactional
  • @Valid

64. @Autowired 和 @Resource 区别?

@Autowired 默认按类型注入,属于 Spring。

@Resource 默认按名称注入,属于 Jakarta/Java 标准注解。


65. @Transactional 什么时候会失效?

常见失效场景:

  • 方法不是 public
  • 同类内部方法调用
  • 异常被 catch 但未抛出
  • 抛出的异常类型不触发回滚
  • 数据库引擎不支持事务
  • 没有被 Spring 管理

66. Spring Boot 如何统一异常处理?

使用:

java 复制代码
@RestControllerAdvice
@ExceptionHandler

示例:

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Result<Void> handle(Exception e) {
        return Result.fail(e.getMessage());
    }
}

67. Spring Boot 如何解决跨域?

可以使用 WebMvcConfigurer:

java 复制代码
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOriginPatterns("*")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("*")
            .allowCredentials(true);
    }
}

生产环境不建议直接放开所有来源,应指定具体域名。


68. 拦截器和过滤器区别?

过滤器 Filter 属于 Servlet 规范,执行时机更靠前。

拦截器 Interceptor 属于 Spring MVC,主要拦截 Controller 请求。

常见顺序:

text 复制代码
Filter → Interceptor → Controller

八、登录认证与安全面试题

69. JWT 是什么?

JWT 是一种令牌格式,常用于前后端分离登录认证。

它通常由 Header、Payload、Signature 三部分组成。


70. JWT 登录流程是什么?

  1. 用户登录提交账号密码
  2. 后端校验成功后生成 JWT
  3. 前端保存 JWT
  4. 请求接口时在请求头携带 JWT
  5. 后端解析和校验 JWT
  6. 校验成功放行,请求失败返回 401

71. Token 存在哪里?

常见方案:

  • localStorage:简单,但容易受 XSS 影响
  • sessionStorage:关闭页面失效
  • HttpOnly Cookie:前端 JS 不能直接读取,安全性更好
  • Redis:服务端保存 token 状态,便于踢下线和过期控制

72. 什么是 RBAC 权限模型?

RBAC 是基于角色的访问控制。

模型:

text 复制代码
用户 → 角色 → 权限

例如:

  • 用户 A 拥有管理员角色
  • 管理员角色拥有用户管理、菜单管理权限

九、Redis 与缓存面试题

73. Redis 常用数据类型有哪些?

  • String
  • Hash
  • List
  • Set
  • ZSet
  • Stream
  • Bitmap
  • HyperLogLog
  • Geo

74. Redis 常见应用场景有哪些?

  • 缓存
  • 分布式锁
  • 验证码
  • 排行榜
  • 限流
  • 购物车
  • 会话共享
  • 消息队列

75. 缓存穿透、击穿、雪崩区别?

缓存穿透:查询不存在数据,缓存没有,数据库也没有。

缓存击穿:热点 key 过期,大量请求打到数据库。

缓存雪崩:大量 key 同时失效,数据库压力暴增。


76. Redis 分布式锁如何实现?

常见命令:

bash 复制代码
SET lock_key unique_value NX EX 30

含义:

  • NX:不存在才设置
  • EX:设置过期时间
  • unique_value:防止误删其他线程锁

释放锁时要校验 value,推荐使用 Lua 脚本保证原子性。


十、微服务与部署面试题

77. 什么是微服务?

微服务是把一个大型系统拆分为多个独立服务,每个服务负责独立业务能力,可以独立开发、部署、扩展。

例如电商系统可拆为:

  • 用户服务
  • 商品服务
  • 订单服务
  • 支付服务
  • 库存服务

78. Nacos 有什么作用?

Nacos 常用于:

  • 服务注册与发现
  • 配置中心

服务启动后注册到 Nacos,其他服务可以通过服务名调用它。


79. Gateway 网关有什么作用?

网关是微服务统一入口,常用于:

  • 路由转发
  • 登录认证
  • 权限校验
  • 限流
  • 日志
  • 跨域处理

80. Java 项目如何部署到服务器?

常见流程:

  1. 本地或 CI/CD 打包 jar
  2. 上传服务器
  3. 安装 JDK、MySQL、Redis、Nginx
  4. 启动 Spring Boot jar
  5. Nginx 配置反向代理
  6. 配置域名解析
  7. 配置 HTTPS
  8. 使用 systemd、Docker 或 Jenkins 管理服务

示例:

bash 复制代码
nohup java -jar app.jar > app.log 2>&1 &

Docker 部署:

bash 复制代码
docker build -t app .
docker run -d -p 8080:8080 --name app app

二十九、项目练习建议

1. 用户登录注册系统

功能:

  • 用户注册
  • 用户登录
  • JWT 认证
  • 修改密码
  • 用户信息查询
  • 登录拦截

技术:

text 复制代码
Spring Boot + MyBatis-Plus + MySQL + JWT + Redis

2. 后台管理系统

功能:

  • 登录
  • 用户管理
  • 角色管理
  • 菜单管理
  • 权限管理
  • 日志管理
  • 文件上传

技术:

text 复制代码
Vue3 + Element Plus + Spring Boot + MyBatis-Plus + MySQL + Redis

3. 博客系统

功能:

  • 文章发布
  • 文章分类
  • 标签管理
  • 评论
  • 点赞
  • 后台审核
  • 搜索

4. 电商系统

功能:

  • 商品管理
  • 购物车
  • 下单
  • 支付模拟
  • 库存扣减
  • 订单超时取消
  • 秒杀

技术:

text 复制代码
Spring Boot + Redis + RabbitMQ/Kafka + MySQL + Elasticsearch

5. 推荐练习顺序

text 复制代码
Java 基础控制台项目
  ↓
MySQL 增删改查
  ↓
Spring Boot 用户管理接口
  ↓
Vue/React 调接口
  ↓
登录注册 + JWT
  ↓
后台管理系统
  ↓
Redis 缓存
  ↓
Docker 部署
  ↓
微服务项目

三十、总结

Java 学习不要只背语法,最好围绕项目逐步推进。

推荐主线:

text 复制代码
Java 基础
  ↓
面向对象
  ↓
集合、异常、IO、泛型
  ↓
多线程、JVM
  ↓
MySQL、MyBatis
  ↓
Spring Boot
  ↓
登录认证、权限、JWT
  ↓
Redis、MQ、搜索
  ↓
Linux、Docker、Nginx 部署
  ↓
微服务与分布式

对于前端开发者,最实用的目标是先完成:

text 复制代码
Vue3 / React + Spring Boot + MySQL + Redis 的前后端分离后台管理系统

只要你能独立完成登录、注册、权限控制、用户管理、分页查询、文件上传、接口联调、部署上线,就已经具备 Java 后端入门到初中级开发的核心能力。


附:建议学习计划

第 1 周:Java 基础

  • 环境安装
  • 数据类型
  • 流程控制
  • 数组
  • 方法
  • 面向对象基础

第 2 周:Java 进阶

  • 集合
  • 泛型
  • 异常
  • IO
  • Lambda
  • Stream

第 3 周:数据库

  • MySQL
  • SQL
  • 表设计
  • 索引
  • JDBC
  • MyBatis

第 4 周:Spring Boot

  • Spring IOC
  • Spring MVC
  • REST API
  • MyBatis-Plus
  • 统一返回
  • 全局异常

第 5 周:登录权限

  • 登录注册
  • JWT
  • 拦截器
  • 权限表设计
  • Redis 缓存

第 6 周:完整项目

  • 后台管理系统
  • 前后端联调
  • 文件上传
  • 分页搜索
  • 部署上线

第 7 周以后:进阶

  • JVM
  • 并发
  • Redis 高级
  • MQ
  • Docker
  • 微服务
  • 高并发系统设计
相关推荐
牵着毛驴唱着歌14 小时前
JaVers 版本历史功能完整实现指南
java·javers·变更记录
JavaGuide14 小时前
终于有好用的 Claude Code 状态栏增强插件了!
前端·后端·ai编程
止语Lab14 小时前
从文件到配置中心:Go 配置管理的三个升级拐点
开发语言·后端·golang
better_liang14 小时前
每日Java面试场景题知识点之-JUC并发编程核心原理与实战
java·线程池·并发编程·juc·aqs·reentrantlock·concurrenthashmap
小张小张爱学习14 小时前
Java-io流
java·开发语言
林森i14 小时前
vscode设置java
java·ide·vscode
人道领域14 小时前
新项目该怎么入手?我用Claude code 接入小米mimo复盘黑马点评,看他的思路是什么。
java·人工智能·后端·mimo·claude code
AC赳赳老秦14 小时前
OpenClaw多Agent分工协作:按工作模块拆分Agent,实现全流程自动化闭环
java·大数据·数据库·python·自动化·php·openclaw