---
url: /notes/面试/真实面经/卓迅信息技术/index.md
---
## 对称加密和非对称加密的区别

对称加密：加解密使用相同密钥。常见：AES,DES,RC4

非对称加密：公钥加密，私钥解密。常见：RSA,ECC,DSA

特性             	 对称加密                     	 非对称加密
**密钥数量**     	 1个密钥（加密和解密相同）   	 2个密钥（公钥和私钥）
**密钥管理**     	 密钥必须保密，管理复杂       	 公钥公开，私钥保密，管理简单
**速度**         	 快（适合大量数据）           	 慢（适合小量数据）
**安全性**       	 密钥泄露风险高               	 密钥泄露风险低
**应用场景**     	 数据加密、文件加密           	 数字签名、密钥交换、身份验证
**常见算法**     	 AES、DES、3DES               	 RSA、ECC、DSA

## spring默认怎么使用定时器

##

@Scheduled

定时任务的参数  @Scheduled  注解支持以下参数：

fixedRate  ：指定任务执行的时间间隔（单位：毫秒）。任务会按照指定的时间间隔执行，无论上一次任务是否完成。

fixedDelay  ：指定任务执行的延迟时间（单位：毫秒）。任务会在上一次任务完成后延迟指定的时间再次执行。

cron  ：使用Cron表达式定义任务的执行时间。Cron表达式非常灵活，可以指定任务在特定的时间点执行。

initialDelay  ：指定任务首次执行的延迟时间（单位：毫秒）。

zone  ：指定任务执行的时区。

**quartz使用**

Quartz的核心组件包括：

Job：任务类，实现  org.quartz.Job  接口，定义任务的具体逻辑。

Trigger：触发器，定义任务的执行时间规则（如Cron表达式）。

Scheduler：调度器，管理任务和触发器的执行。

在Spring配置类或主类上添加  @EnableScheduling  注解

任务类需要实现  org.quartz.Job  接口，并重写  execute  方法

在Spring配置类中配置任务和触发器

```java
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail myJobDetail() {
        return JobBuilder.newJob(MyJob.class)
                .withIdentity("myJob", "group1")
                .usingJobData("count", 1)
                .build();
    }

    @Bean
    public Trigger myJobTrigger() {
        return TriggerBuilder.newTrigger()
                .withIdentity("myJobTrigger", "group1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(5)
                        .repeatForever())
                .build();
    }
}

```

**Quartz通过集群模式和数据库锁机制来保证任务的唯一性，确保同一个任务不会在多个节点上重复执行。**

1. **数据库锁机制**

Quartz集群模式下，所有节点共享同一个数据库，任务调度信息（如任务状态、触发器信息等）存储在数据库中。Quartz通过数据库锁来确保任务的唯一性：

• 任务锁（  QRTZ\_LOCKS  表）：Quartz使用数据库中的  QRTZ\_LOCKS  表来管理锁。每个任务调度操作（如获取任务、执行任务等）都会尝试获取相应的锁。

• 悲观锁机制：当一个节点获取到任务锁后，其他节点会被阻塞，直到锁被释放。这样确保了同一时间只有一个节点可以执行任务。

2. 集群心跳机制

Quartz集群中的每个节点都会定期向数据库中的  QRTZ\_SCHEDULER\_STATE  表发送心跳（  LAST\_CHECKIN\_TIME  字段）。心跳机制的作用包括：

• 检测节点状态：通过心跳时间戳，其他节点可以检测到某个节点是否仍然活跃。

• 故障转移：如果某个节点的心跳超时（默认2分钟），其他节点会接管该节点的任务，确保任务不会因为节点故障而丢失。

3. 配置集群属性为了启用Quartz集群模式，需要在  quartz.properties  文件或Spring配置中设置以下关键属性：properties# 启用集群模式

```properties
# 启用集群模式
org.quartz.jobStore.isClustered = true

# 设置集群检查间隔（单位：毫秒）
org.quartz.jobStore.clusterCheckinInterval = 20000

# 设置数据库锁的超时时间（单位：秒）
org.quartz.jobStore.txLockWaitCount = 3
```

4. 配置数据库存储

Quartz需要一个数据库来存储任务和触发器信息。在  application.properties  中配置数据库连接：

```properties
# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/quartz_db?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Quartz配置
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.scheduler.instanceName=ClusteredScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
```

5. 防止任务并发执行

为了避免同一个任务在多个节点上并发执行，可以在任务类上使用  @DisallowConcurrentExecution  注解：

```java
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

@DisallowConcurrentExecution
public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Task executed at: " + new Date());
    }
}
```

6. 动态任务配置

   在集群模式下，动态任务配置也需要通过数据库来同步。例如，添加、修改或删除任务时，需要确保所有节点都能感知到这些变化。

Quartz集群模式下，任务调度和执行的同步是通过数据库的行锁来实现的。

## 行锁和表锁是什么情况下会出现？

行锁

更新单行数据

读取单行数据

事务处理：对单行数据继续增，删，改操作

表锁：

批量操作

表结构修改

全表扫描

特性             	 行锁（Row Lock）               	 表锁（Table Lock）
**锁定范围**     	 单个行                        	 整个表
**并发性能**     	 高（允许多个事务并发操作）     	 低（阻塞其他事务对表的访问）
**管理开销**     	 大（需要管理每个行的锁）       	 小（只需要管理整个表的锁）
**适用场景**     	 更新单行数据、事务处理         	 批量操作、表结构修改、全表扫描
**示例**     `UPDATE table_name SET column = value WHERE id = specific_id;` 	 `UPDATE table_name SET column = value;`

## java里面的队列分为哪几种

Java提供了多种队列实现，每种实现都有其特定的用途和特性：

标准队列（  LinkedList  ）：适合单线程环境。

阻塞队列（  ArrayBlockingQueue（基于数组实现的阻塞队列，具有固定的容量。）,   LinkedBlockingQueue（基于链表实现的阻塞队列，支持动态扩容。））：适合多线程环境。

阻塞队列是一种线程安全的队列，支持在多线程环境中安全地进行插入和移除操作。当队列为空时，尝试移除元素的操作可能会阻塞，直到有元素可用；当队列满时，尝试添加元素的操作可能会阻塞，直到有空间可用。

优先队列（  PriorityQueue  ）：适合需要按优先级处理元素的场景。

优先队列是一种特殊的队列，元素按照优先级顺序存储，优先级最高的元素总是位于队列头部。

双端队列（  LinkedList  ）：适合需要在两端进行操作的场景。

双端队列（Deque）是一种支持在两端进行插入和移除操作的队列。

并发队列（  ConcurrentLinkedQueue  ）：适合高并发场景。

延迟队列（  DelayQueue  ）：适合需要延迟处理元素的场景。
