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 异常和错误的区别
区别对比:
| 特性 | Exception | Error |
|---|---|---|
| 类型 | 可检查异常、运行时异常 | 系统级错误 |
| 可恢复性 | 可恢复 | 不可恢复 |
| 处理方式 | 应该捕获处理 | 不应捕获 |
| 示例 | IOException, NullPointerException | OutOfMemoryError, 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全栈开发中的核心技术要点,涵盖了从基础语法到分布式架构的各个层面。掌握这些知识点不仅能够应对技术面试,更重要的是能够在实际项目中灵活运用,构建高质量、可维护的软件系统。
技术成长建议:
- 深度理解原理:不仅要会用,更要理解背后的设计思想和实现原理
- 实践驱动学习:通过实际项目巩固理论知识
- 关注技术演进:持续学习新技术,但要有选择地应用到项目中
- 培养架构思维:从全局视角思考系统设计,而不仅仅是代码实现
希望这篇技术笔记能够帮助你在Java全栈开发的道路上不断进步!