✍个人博客:Pandaconda-CSDN博客
📣专栏地址:https://blog.csdn.net/newin2020/category_12903849.html
📚专栏简介:在这个专栏中,我将会分享后端开发面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
1. 在 Spring Boot 中,如何实现定时任务?
在 Spring Boot 中实现定时任务有多种方式,这里主要介绍常用的两种:
使用 @Scheduled 注解
@Scheduled 是 Spring 框架提供的一个注解,可用于方法上,将该方法标记为定时任务。使用步骤如下:
- 在主应用类上添加 @EnableScheduling 注解,开启定时任务功能。
java">import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@EnableScheduling
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
- 创建一个组件类,在其中定义带有 @Scheduled 注解的方法。
java">import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class ScheduledTasks {// 固定延迟,上一次任务执行结束后,延迟 5000 毫秒执行下一次任务@Scheduled(fixedDelay = 5000) public void fixedDelayTask() {System.out.println("Fixed delay task executed.");}// 固定速率,每隔 3000 毫秒执行一次任务@Scheduled(fixedRate = 3000) public void fixedRateTask() {System.out.println("Fixed rate task executed.");}// 使用 cron 表达式,每天凌晨 2 点执行任务@Scheduled(cron = "0 0 2 * * ?") public void cronTask() {System.out.println("Cron task executed.");}
}
使用 SchedulingConfigurer 接口
如果需要更灵活地配置定时任务,可以实现 SchedulingConfigurer 接口。
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler(taskExecutor());taskRegistrar.addFixedRateTask(() -> {System.out.println("Custom scheduled task executed.");}, 5000);}public Executor taskExecutor() {return Executors.newScheduledThreadPool(10);}
}
redis__88">2. redis 中,如何实现分布式锁?
基本思路
- 使用 SET 命令设置一个特定的键值对,同时设置过期时间,确保即使持有锁的客户端崩溃,锁也能在一定时间后自动释放。
- 通过判断 SET 命令的返回结果来确定是否成功获取锁。
- 释放锁时,需要确保只有持有锁的客户端才能释放锁,通常使用 Lua 脚本来保证操作的原子性。
示例代码(Python + Redis)
python">import redis
import time# 连接 Redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)def acquire_lock(lock_name, acquire_timeout=10, lock_timeout=10):end_time = time.time() + acquire_timeoutwhile time.time() < end_time:# 使用 SET 命令尝试获取锁result = redis_client.set(lock_name, "locked", nx=True, ex=lock_timeout)if result:return Truetime.sleep(0.1)return Falsedef release_lock(lock_name):# 使用 Lua 脚本释放锁,保证操作的原子性lua_script = """if redis.call("get", KEYS[1]) == ARGV[1] thenreturn redis.call("del", KEYS[1])elsereturn 0end"""result = redis_client.eval(lua_script, 1, lock_name, "locked")return result# 使用示例
lock_name = "my_distributed_lock"
if acquire_lock(lock_name):try:print("获取到锁,开始执行任务...")time.sleep(5) # 模拟任务执行finally:release_lock(lock_name)print("任务执行完毕,释放锁。")
else:print("未能获取到锁。")
3. 简述如何在 MySQL 中实现数据库备份与恢复
备份
-
使用 mysqldump 工具(逻辑备份)
-
备份多个数据库:
mysqldump -u username -p --databases database1 database2 > backup.sql
-
只备份数据库结构(不包含数据):
mysqldump -u username -p --no-data database_name > structure_backup.sql
-
物理备份
可以直接复制 MySQL 数据目录下的文件来进行物理备份,但这种方法需要停止 MySQL 服务,且对文件的管理和恢复要求较高。一般适用于 InnoDB 存储引擎,可使用 xtrabackup 工具进行热备份。
恢复
-
使用 mysql 命令恢复(逻辑备份恢复)
如果之前使用 mysqldump 进行了备份,可以使用 mysql 命令将备份文件恢复到数据库中。
mysql -u username -p database_name < backup.sql
该命令会将 backup.sql 文件中的 SQL 语句执行,从而恢复数据库的结构和数据。
-
物理备份恢复
对于物理备份,需要将备份的文件复制到 MySQL 数据目录下,并根据具体情况进行配置和启动 MySQL 服务。如果使用 xtrabackup 进行备份,可使用其提供的恢复命令进行恢复。例如:
xtrabackup --prepare --target-dir=/path/to/backup xtrabackup --copy-back --target-dir=/path/to/backup