开始改变第二天 基础知识整理

46 阅读12分钟

Java全栈开发核心知识点详解 - 面试必备技术指南

一、Java基础核心

1.1 面向对象 vs 面向过程

区别对比:

特性面向过程面向对象
编程思想以过程为中心,分析解决问题的步骤以对象为中心,分析问题中涉及的实体
数据与操作数据与操作分离数据与操作封装在一起
核心概念函数、过程类、对象、继承、封装、多态
适用场景性能要求高、流程简单的场景大型复杂系统、需要扩展维护的场景

代码示例:

// 面向过程 - 计算矩形面积
public class ProceduralExample {
    public static double calculateArea(double length, double width) {
        return length * width;
    }
    
    public static void main(String[] args) {
        double area = calculateArea(5.0, 3.0);
        System.out.println("Area: " + area);
    }
}

// 面向对象 - 计算矩形面积
class Rectangle {
    private double length;
    private double width;
    
    public Rectangle(double length, double width) {
        this.length = length;
        this.width = width;
    }
    
    public double calculateArea() {
        return length * width;
    }
}

public class OOPExample {
    public static void main(String[] args) {
        Rectangle rect = new Rectangle(5.0, 3.0);
        double area = rect.calculateArea();
        System.out.println("Area: " + area);
    }
}

1.2 多态详解

多态的实现方式:

  • 编译时多态:方法重载
  • 运行时多态:方法重写

代码示例:

// 父类
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

// 子类
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
    
    // 方法重载
    public void makeSound(int times) {
        for (int i = 0; i < times; i++) {
            System.out.println("Woof!");
        }
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        // 运行时多态
        Animal myAnimal = new Dog();  // 父类引用指向子类对象
        myAnimal.makeSound();  // 输出: Dog barks
        
        myAnimal = new Cat();
        myAnimal.makeSound();  // 输出: Cat meows
        
        // 编译时多态
        Dog dog = new Dog();
        dog.makeSound(3);  // 输出: Woof! Woof! Woof!
    }
}

1.3 正则表达式常用类型

常用正则表达式:

public class RegexExamples {
    public static void main(String[] args) {
        // 1. 匹配数字
        String numberRegex = "\\d+";
        System.out.println("123".matches(numberRegex));  // true
        
        // 2. 匹配邮箱
        String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        String email = "test@example.com";
        System.out.println(email.matches(emailRegex));  // true
        
        // 3. 匹配手机号
        String phoneRegex = "^1[3-9]\\d{9}$";
        String phone = "13812345678";
        System.out.println(phone.matches(phoneRegex));  // true
        
        // 4. 提取数字
        String text = "价格是123元,重量是45公斤";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println("找到数字: " + matcher.group());
        }
        
        // 5. 替换操作
        String replaced = text.replaceAll("\\d+", "***");
        System.out.println(replaced);  // 价格是***元,重量是***公斤
    }
}

1.4 异常和错误的区别

区别对比:

特性ExceptionError
类型可检查异常、运行时异常系统级错误
可恢复性可恢复不可恢复
处理方式应该捕获处理不应捕获
示例IOException, NullPointerExceptionOutOfMemoryError, StackOverflowError

异常处理最佳实践:

public class ExceptionHandling {
    
    // 可检查异常
    public void readFile(String filename) {
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            System.err.println("文件未找到: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("IO错误: " + e.getMessage());
        }
    }
    
    // 运行时异常
    public void processData(String data) {
        if (data == null) {
            throw new IllegalArgumentException("数据不能为空");
        }
        // 处理数据
    }
    
    // 自定义异常
    class BusinessException extends RuntimeException {
        public BusinessException(String message) {
            super(message);
        }
    }
}

1.5 集合框架深度解析

List集合比较:

public class ListComparison {
    public static void main(String[] args) {
        // ArrayList vs LinkedList
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
        
        // 添加性能测试
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            arrayList.add("element" + i);
        }
        long arrayListTime = System.currentTimeMillis() - start;
        
        start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            linkedList.add("element" + i);
        }
        long linkedListTime = System.currentTimeMillis() - start;
        
        System.out.println("ArrayList添加时间: " + arrayListTime + "ms");
        System.out.println("LinkedList添加时间: " + linkedListTime + "ms");
    }
}

HashMap原理分析:

public class HashMapAnalysis {
    /**
     * HashMap核心原理:
     * 1. 数组 + 链表/红黑树结构
     * 2. 默认容量16,负载因子0.75
     * 3. 扩容机制:当size > capacity * loadFactor时扩容为2倍
     * 4. hash冲突解决:链表法,当链表长度>8且数组长度>=64时转为红黑树
     */
    
    public static void analyzeHashMap() {
        Map<String, Integer> map = new HashMap<>();
        
        // put过程
        map.put("key1", 1);
        map.put("key2", 2);
        
        // 获取值
        Integer value = map.get("key1");
        System.out.println("key1的值: " + value);
        
        // 遍历方式
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

线程安全集合:

public class ConcurrentCollections {
    public static void main(String[] args) {
        // ConcurrentHashMap
        ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
        
        // CopyOnWriteArrayList
        CopyOnWriteArrayList<String> copyOnWriteList = new CopyOnWriteArrayList<>();
        
        // 使用Collections创建同步集合
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
        
        // 在多线程环境中安全操作
        ExecutorService executor = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            final int index = i;
            executor.submit(() -> {
                concurrentMap.put("key" + index, index);
            });
        }
        executor.shutdown();
    }
}

1.6 IO流体系

字节流 vs 字符流:

public class IOStreamExample {
    
    // 字节流操作 - 适合处理图片、视频等二进制文件
    public static void copyFileWithByteStream(String source, String target) throws IOException {
        try (FileInputStream fis = new FileInputStream(source);
             FileOutputStream fos = new FileOutputStream(target)) {
            
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, length);
            }
        }
    }
    
    // 字符流操作 - 适合处理文本文件
    public static void copyFileWithCharStream(String source, String target) throws IOException {
        try (FileReader reader = new FileReader(source);
             FileWriter writer = new FileWriter(target)) {
            
            char[] buffer = new char[1024];
            int length;
            while ((length = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, length);
            }
        }
    }
    
    // 使用缓冲流提高性能
    public static void copyFileWithBufferedStream(String source, String target) throws IOException {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target))) {
            
            byte[] buffer = new byte[8192];  // 8KB缓冲区
            int length;
            while ((length = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, length);
            }
        }
    }
    
    // 对象序列化
    public static void serializeObject(Object obj, String filename) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
            oos.writeObject(obj);
        }
    }
    
    public static Object deserializeObject(String filename) throws IOException, ClassNotFoundException {
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
            return ois.readObject();
        }
    }
}

1.7 线程与线程池

线程生命周期:

public class ThreadLifecycle {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("线程执行中...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程执行完成");
        });
        
        System.out.println("线程状态: " + thread.getState());  // NEW
        
        thread.start();
        System.out.println("线程状态: " + thread.getState());  // RUNNABLE
        
        Thread.sleep(100);
        System.out.println("线程状态: " + thread.getState());  // TIMED_WAITING
        
        thread.join();
        System.out.println("线程状态: " + thread.getState());  // TERMINATED
    }
}

线程池使用:

public class ThreadPoolExample {
    
    public static void main(String[] args) {
        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            5,      // 核心线程数
            10,     // 最大线程数
            60L,    // 空闲线程存活时间
            TimeUnit.SECONDS, // 时间单位
            new LinkedBlockingQueue<>(100), // 工作队列
            Executors.defaultThreadFactory(), // 线程工厂
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );
        
        // 提交任务
        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            executor.execute(() -> {
                System.out.println("执行任务: " + taskId + ", 线程: " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        
        // 关闭线程池
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
        }
    }
}

CompletableFuture异步编程:

public class CompletableFutureExample {
    
    public static void main(String[] args) throws Exception {
        // 异步执行任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "任务结果";
        });
        
        // 任务完成后的回调
        future.thenAccept(result -> {
            System.out.println("接收到结果: " + result);
        });
        
        // 组合多个异步任务
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
        
        CompletableFuture<String> combined = future1.thenCombine(future2, (s1, s2) -> s1 + " " + s2);
        System.out.println(combined.get());  // Hello World
        
        // 异常处理
        CompletableFuture.supplyAsync(() -> {
            if (true) {
                throw new RuntimeException("发生错误");
            }
            return "成功";
        }).exceptionally(ex -> {
            System.err.println("处理异常: " + ex.getMessage());
            return "默认值";
        });
    }
}

1.8 注解与自定义注解

内置注解:

// 使用内置注解
@Deprecated
class OldClass {
    @SuppressWarnings("unchecked")
    public void oldMethod() {
        List list = new ArrayList();  // 忽略警告
    }
    
    @Override
    public String toString() {
        return "OldClass";
    }
}

自定义注解:

// 定义自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface MyAnnotation {
    String value() default "";
    String description() default "";
    int version() default 1;
}

// 使用自定义注解
@MyAnnotation(value = "TestClass", description = "测试类", version = 2)
public class AnnotationTest {
    
    @MyAnnotation("testMethod")
    public void testMethod() {
        System.out.println("测试方法");
    }
    
    // 注解处理器
    public static void processAnnotations(Class<?> clazz) {
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("类注解值: " + annotation.value());
            System.out.println("描述: " + annotation.description());
            System.out.println("版本: " + annotation.version());
        }
        
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("方法 " + method.getName() + " 的注解值: " + annotation.value());
            }
        }
    }
    
    public static void main(String[] args) {
        processAnnotations(AnnotationTest.class);
    }
}

二、数据库与SQL

2.1 复杂SQL编写

高级查询示例:

-- 窗口函数
SELECT 
    employee_id,
    department_id,
    salary,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) as rank_in_dept,
    AVG(salary) OVER (PARTITION BY department_id) as avg_salary_in_dept
FROM employees;

-- 公用表表达式(CTE)
WITH DepartmentStats AS (
    SELECT 
        department_id,
        AVG(salary) as avg_salary,
        COUNT(*) as employee_count
    FROM employees
    GROUP BY department_id
    HAVING COUNT(*) > 5
)
SELECT 
    e.employee_id,
    e.salary,
    ds.avg_salary
FROM employees e
JOIN DepartmentStats ds ON e.department_id = ds.department_id
WHERE e.salary > ds.avg_salary;

-- 递归查询
WITH RECURSIVE EmployeeHierarchy AS (
    -- 基础情况:顶级管理者
    SELECT 
        employee_id,
        manager_id,
        name,
        1 as level
    FROM employees
    WHERE manager_id IS NULL
    
    UNION ALL
    
    -- 递归情况:下属员工
    SELECT 
        e.employee_id,
        e.manager_id,
        e.name,
        eh.level + 1
    FROM employees e
    JOIN EmployeeHierarchy eh ON e.manager_id = eh.employee_id
)
SELECT * FROM EmployeeHierarchy ORDER BY level, employee_id;

三、Spring框架全家桶

3.1 Spring IOC核心原理

IOC容器工作流程:

@Component
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    public User findUserById(Long id) {
        return userRepository.findById(id);
    }
}

@Repository
public class UserRepository {
    public User findById(Long id) {
        // 数据库查询逻辑
        return new User(id, "testUser");
    }
}

// 配置类
@Configuration
@ComponentScan("com.example")
public class AppConfig {
    
    @Bean
    public DataSource dataSource() {
        // 数据源配置
        return new DriverManagerDataSource();
    }
}

// IOC容器使用
public class IOCExample {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);
        User user = userService.findUserById(1L);
        System.out.println(user);
    }
}

常用注解:

  • @Component - 通用组件注解
  • @Service - 服务层组件
  • @Repository - 数据访问层组件
  • @Controller - 控制器组件
  • @Autowired - 自动注入
  • @Qualifier - 指定注入的Bean名称
  • @Value - 注入配置值
  • @Configuration - 配置类
  • @Bean - 声明Bean

3.2 Spring AOP详解

AOP配置与使用:

@Aspect
@Component
public class LoggingAspect {
    
    // 定义切点
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}
    
    // 前置通知
    @Before("serviceLayer()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("方法执行前: " + joinPoint.getSignature().getName());
    }
    
    // 后置通知
    @AfterReturning(pointcut = "serviceLayer()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("方法执行后: " + joinPoint.getSignature().getName() + ", 结果: " + result);
    }
    
    // 异常通知
    @AfterThrowing(pointcut = "serviceLayer()", throwing = "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
        System.out.println("方法异常: " + joinPoint.getSignature().getName() + ", 异常: " + error.getMessage());
    }
    
    // 环绕通知
    @Around("serviceLayer()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            long executionTime = System.currentTimeMillis() - start;
            System.out.println(joinPoint.getSignature() + " 执行时间: " + executionTime + "ms");
            return result;
        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - start;
            System.out.println(joinPoint.getSignature() + " 异常执行时间: " + executionTime + "ms");
            throw e;
        }
    }
}

// 启用AOP
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example")
public class AopConfig {
}

3.3 Spring事务管理

声明式事务:

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Transactional(propagation = Propagation.REQUIRED, 
                   isolation = Isolation.READ_COMMITTED,
                   rollbackFor = Exception.class,
                   timeout = 30)
    public void createUserWithOrder(User user, Order order) {
        // 保存用户
        userRepository.save(user);
        
        // 设置订单用户关系
        order.setUserId(user.getId());
        orderRepository.save(order);
        
        // 如果这里抛出异常,整个事务会回滚
        if (order.getAmount() < 0) {
            throw new IllegalArgumentException("订单金额不能为负数");
        }
    }
    
    @Transactional(readOnly = true)
    public User getUserWithOrders(Long userId) {
        return userRepository.findByIdWithOrders(userId);
    }
}

// 事务传播机制示例
@Service
public class OrderService {
    
    @Autowired
    private UserService userService;
    
    @Transactional
    public void processOrder(Order order) {
        // REQUIRED: 如果当前没有事务,就新建一个事务
        userService.createUserWithOrder(order.getUser(), order);
        
        // 其他业务逻辑
        updateInventory(order);
    }
}

3.4 Spring MVC流程解析

请求处理流程:

1. 用户发送请求 → DispatcherServlet
2. DispatcherServlet 查询 HandlerMapping → 找到对应Controller
3. 调用 Controller 方法处理请求
4. Controller 返回 ModelAndView
5. DispatcherServlet 查询 ViewResolver → 解析视图
6. 渲染视图返回响应

常用注解:

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        List<User> users = userService.findAllUsers(page, size);
        return ResponseEntity.ok(users);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findUserById(id);
        return ResponseEntity.ok(user);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
        User savedUser = userService.saveUser(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        user.setId(id);
        User updatedUser = userService.updateUser(user);
        return ResponseEntity.ok(updatedUser);
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
    
    // 异常处理
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }
}

3.5 Mybatis深度使用

#{} vs ${} 区别:

<!-- #{} 使用预编译,防止SQL注入 -->
<select id="findUserById" parameterType="long" resultType="User">
    SELECT * FROM users WHERE id = #{id}
</select>

<!-- ${} 直接拼接SQL,有SQL注入风险 -->
<select id="findUsersOrderBy" parameterType="string" resultType="User">
    SELECT * FROM users ORDER BY ${orderBy}
</select>

动态SQL:

<select id="findUsersByCondition" parameterType="map" resultType="User">
    SELECT * FROM users
    <where>
        <if test="name != null and name != ''">
            AND name LIKE CONCAT('%', #{name}, '%')
        </if>
        <if test="email != null and email != ''">
            AND email = #{email}
        </if>
        <if test="status != null">
            AND status = #{status}
        </if>
        <if test="minAge != null">
            AND age >= #{minAge}
        </if>
        <if test="maxAge != null">
            AND age <= #{maxAge}
        </if>
    </where>
    ORDER BY create_time DESC
</select>

<!-- 批量操作 -->
<insert id="batchInsertUsers" parameterType="list">
    INSERT INTO users (name, email, age) VALUES
    <foreach collection="list" item="user" separator=",">
        (#{user.name}, #{user.email}, #{user.age})
    </foreach>
</insert>

Mybatis插件开发:

@Intercepts({
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class SqlCostInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            long cost = System.currentTimeMillis() - start;
            String methodName = invocation.getMethod().getName();
            System.out.println("SQL执行[" + methodName + "]耗时: " + cost + "ms");
        }
    }
    
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    
    @Override
    public void setProperties(Properties properties) {
        // 设置属性
    }
}

四、分布式与微服务

4.1 Spring Cloud核心组件

微服务架构组件:

# application.yml
spring:
  application:
    name: user-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
      config:
        server-addr: localhost:8848
        file-extension: yaml
    sentinel:
      transport:
        dashboard: localhost:8080

# 服务注册发现
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

# 配置中心使用
@RestController
@RefreshScope
public class ConfigController {
    
    @Value("${app.config.value:default}")
    private String configValue;
    
    @GetMapping("/config")
    public String getConfig() {
        return configValue;
    }
}

服务调用与熔断:

// Feign客户端
@FeignClient(name = "order-service", fallback = OrderServiceFallback.class)
public interface OrderServiceClient {
    
    @GetMapping("/orders/user/{userId}")
    List<Order> getOrdersByUserId(@PathVariable("userId") Long userId);
}

// 熔断降级
@Component
public class OrderServiceFallback implements OrderServiceClient {
    
    @Override
    public List<Order> getOrdersByUserId(Long userId) {
        // 返回降级数据
        return Collections.emptyList();
    }
}

// 使用Feign客户端
@Service
public class UserService {
    
    @Autowired
    private OrderServiceClient orderServiceClient;
    
    public UserDTO getUserWithOrders(Long userId) {
        User user = userRepository.findById(userId);
        List<Order> orders = orderServiceClient.getOrdersByUserId(userId);
        
        UserDTO userDTO = new UserDTO();
        userDTO.setUser(user);
        userDTO.setOrders(orders);
        return userDTO;
    }
}

4.2 Spring Boot自动装配原理

自动配置机制:

// 自定义starter
@Configuration
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@EnableConfigurationProperties(DatabaseProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class DatabaseAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
    @Bean
    @ConditionalOnProperty(name = "app.database.audit.enabled", havingValue = "true")
    public DatabaseAuditAspect databaseAuditAspect() {
        return new DatabaseAuditAspect();
    }
}

// 配置属性类
@ConfigurationProperties(prefix = "app.database")
public class DatabaseProperties {
    private String schema;
    private boolean auditEnabled = false;
    
    // getter/setter
}

// META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfigure.DatabaseAutoConfiguration

与Spring的区别:

  • Spring Boot提供自动配置,减少样板配置
  • 内嵌Web服务器,简化部署
  • 提供starter依赖,简化依赖管理
  • 生产就绪功能(监控、健康检查)

五、中间件技术

5.1 Redis深度使用

数据结构与应用场景:

@Component
public class RedisExamples {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // String类型 - 缓存
    public void cacheUser(User user) {
        String key = "user:" + user.getId();
        redisTemplate.opsForValue().set(key, user, Duration.ofMinutes(30));
    }
    
    public User getCachedUser(Long userId) {
        String key = "user:" + userId;
        return (User) redisTemplate.opsForValue().get(key);
    }
    
    // Hash类型 - 存储对象
    public void cacheUserDetails(User user) {
        String key = "user:details:" + user.getId();
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("name", user.getName());
        userMap.put("email", user.getEmail());
        userMap.put("age", user.getAge());
        redisTemplate.opsForHash().putAll(key, userMap);
        redisTemplate.expire(key, Duration.ofMinutes(30));
    }
    
    // List类型 - 消息队列
    public void pushMessage(String queue, String message) {
        redisTemplate.opsForList().leftPush(queue, message);
    }
    
    public String popMessage(String queue) {
        return (String) redisTemplate.opsForList().rightPop(queue);
    }
    
    // Set类型 - 标签系统
    public void addUserTags(Long userId, String... tags) {
        String key = "user:tags:" + userId;
        redisTemplate.opsForSet().add(key, tags);
    }
    
    public Set<Object> getUserTags(Long userId) {
        String key = "user:tags:" + userId;
        return redisTemplate.opsForSet().members(key);
    }
    
    // ZSet类型 - 排行榜
    public void addScore(String leaderboard, String player, double score) {
        redisTemplate.opsForZSet().add(leaderboard, player, score);
    }
    
    public Set<ZSetOperations.TypedTuple<Object>> getTopPlayers(String leaderboard, int topN) {
        return redisTemplate.opsForZSet().reverseRangeWithScores(leaderboard, 0, topN - 1);
    }
}

缓存问题解决方案:

@Service
public class CacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private UserRepository userRepository;
    
    // 缓存穿透解决方案 - 布隆过滤器或空值缓存
    public User getUserWithCache(Long userId) {
        String key = "user:" + userId;
        
        // 先从缓存获取
        User user = (User) redisTemplate.opsForValue().get(key);
        if (user != null) {
            // 如果是空对象(解决缓存穿透)
            if (user.getId() == null) {
                return null;
            }
            return user;
        }
        
        // 缓存不存在,查询数据库
        user = userRepository.findById(userId);
        
        if (user != null) {
            // 缓存用户数据
            redisTemplate.opsForValue().set(key, user, Duration.ofMinutes(30));
        } else {
            // 缓存空对象,防止缓存穿透
            User emptyUser = new User();
            redisTemplate.opsForValue().set(key, emptyUser, Duration.ofMinutes(5));
        }
        
        return user;
    }
    
    // 缓存击穿解决方案 - 互斥锁
    public User getUserWithMutexLock(Long userId) {
        String cacheKey = "user:" + userId;
        String lockKey = "lock:user:" + userId;
        
        // 尝试获取缓存
        User user = (User) redisTemplate.opsForValue().get(cacheKey);
        if (user != null) {
            return user;
        }
        
        // 尝试获取锁
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "locked", Duration.ofSeconds(10));
        if (Boolean.TRUE.equals(locked)) {
            try {
                // 双重检查
                user = (User) redisTemplate.opsForValue().get(cacheKey);
                if (user != null) {
                    return user;
                }
                
                // 查询数据库
                user = userRepository.findById(userId);
                if (user != null) {
                    redisTemplate.opsForValue().set(cacheKey, user, Duration.ofMinutes(30));
                } else {
                    // 缓存空值
                    User emptyUser = new User();
                    redisTemplate.opsForValue().set(cacheKey, emptyUser, Duration.ofMinutes(5));
                }
                
                return user;
            } finally {
                // 释放锁
                redisTemplate.delete(lockKey);
            }
        } else {
            // 未获取到锁,短暂等待后重试
            try {
                Thread.sleep(50);
                return getUserWithMutexLock(userId);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return null;
            }
        }
    }
}

Redis高可用方案:

  • 主从复制:数据备份和读写分离
  • 哨兵模式:自动故障转移
  • 集群模式:数据分片和高可用

六、开发流程与部署

6.1 项目开发完整流程

开发流程阶段:

1. 需求分析 → 2. 技术方案设计 → 3. 数据库设计
4. 项目搭建 → 5. 编码开发 → 6. 单元测试
7. 集成测试 → 8. 部署上线 → 9. 监控运维

前后端联调要点:

// 统一API响应格式
@Data
public class ApiResponse<T> {
    private boolean success;
    private String code;
    private String message;
    private T data;
    private long timestamp;
    
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setSuccess(true);
        response.setCode("SUCCESS");
        response.setMessage("操作成功");
        response.setData(data);
        response.setTimestamp(System.currentTimeMillis());
        return response;
    }
    
    public static ApiResponse<Object> error(String code, String message) {
        ApiResponse<Object> response = new ApiResponse<>();
        response.setSuccess(false);
        response.setCode(code);
        response.setMessage(message);
        response.setTimestamp(System.currentTimeMillis());
        return response;
    }
}

// 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<Object>> handleException(Exception e) {
        ApiResponse<Object> response = ApiResponse.error("SYSTEM_ERROR", "系统异常");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
    
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ApiResponse<Object>> handleBusinessException(BusinessException e) {
        ApiResponse<Object> response = ApiResponse.error(e.getCode(), e.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }
}

6.2 常用工具命令

Linux常用命令:

# 进程管理
ps aux | grep java          # 查看Java进程
kill -9 <pid>               # 强制杀死进程
jstack <pid>                # 查看Java线程堆栈

# 文件操作
tail -f application.log     # 实时查看日志
grep "ERROR" application.log # 搜索错误日志
find /app -name "*.jar"     # 查找文件

# 网络相关
netstat -tlnp               # 查看端口占用
curl http://localhost:8080/health # 健康检查

# 系统监控
top                         # 系统资源监控
free -h                     # 内存使用情况
df -h                       # 磁盘使用情况

Git工作流:

# 功能开发流程
git checkout -b feature/user-management  # 创建功能分支
git add .                                # 添加修改
git commit -m "feat: 添加用户管理功能"     # 提交更改
git push origin feature/user-management  # 推送到远程

# 代码合并
git checkout develop                     # 切换到开发分支
git pull origin develop                  # 拉取最新代码
git merge feature/user-management        # 合并功能分支
git push origin develop                  # 推送到远程

# 版本发布
git checkout main                        # 切换到主分支
git merge develop                        # 合并开发分支
git tag v1.0.0                          # 打标签
git push origin v1.0.0                  # 推送标签

总结

本文全面梳理了Java全栈开发中的核心技术要点,涵盖了从基础语法到分布式架构的各个层面。掌握这些知识点不仅能够应对技术面试,更重要的是能够在实际项目中灵活运用,构建高质量、可维护的软件系统。

技术成长建议:

  1. 深度理解原理:不仅要会用,更要理解背后的设计思想和实现原理
  2. 实践驱动学习:通过实际项目巩固理论知识
  3. 关注技术演进:持续学习新技术,但要有选择地应用到项目中
  4. 培养架构思维:从全局视角思考系统设计,而不仅仅是代码实现

希望这篇技术笔记能够帮助你在Java全栈开发的道路上不断进步!