当前位置: 首页 > news >正文

1222面经

1,Kafka 如何保障顺序消费?

Kafka 保障顺序消费主要通过以下几个关键机制和配置来实现:

分区策略

  • Kafka 将主题划分为多个分区,每个分区内的消息是天然有序的,其按照消息发送到分区的先后顺序进行存储和追加。
  • 生产者在发送消息时,可以指定消息要发送到的分区。如果不指定,Kafka 会根据默认的分区策略进行分配。例如,按照轮询的方式将消息均匀分配到各个分区,以确保每个分区的负载相对均衡。

消费者配置

  • 单消费者实例按分区顺序消费:在消费者端,一个消费者实例可以同时订阅多个分区。当消费者拉取消息时,会按照分区内的顺序依次获取消息进行消费,从而保证了在单个分区内的消息顺序性。
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Arrays;
import java.util.Properties;public class KafkaConsumerExample {public static void main(String[] args) {Properties props = new Properties();props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);consumer.subscribe(Arrays.asList("test-topic"));while (true) {ConsumerRecords<String, String> records = consumer.poll(100);for (var record : records) {System.out.printf("Received message: key = %s, value = %s, partition = %d, offset = %d\n",record.key(), record.value(), record.partition(), record.offset());}}}
}
  • 多消费者实例的顺序协调:当一个消费者组中有多个消费者实例时,Kafka 会通过协调机制确保每个分区只会被组内的一个消费者实例消费,避免多个消费者同时消费同一个分区导致的顺序混乱问题。

消息确认机制

  • Kafka 采用的是基于偏移量(offset)的消息确认机制。消费者在成功消费一条消息后,会向 Kafka 提交该消息的偏移量,表示这条消息已经被正确处理。
  • 只有当消费者提交了偏移量,Kafka 才会认为该消息已经被成功消费,并且后续不会再次将该消息发送给消费者。这种机制确保了消息不会被重复消费,同时也保证了消息消费的顺序性。

幂等性和事务支持

  • 幂等性:Kafka 生产者支持幂等性写入,即无论消息发送多少次,其在分区中的最终状态都是相同的。这对于保障消息顺序消费非常重要,因为它避免了因消息重复发送而导致的顺序混乱问题。
  • 事务支持:Kafka 还提供了事务机制,允许生产者在一个事务中将多条消息发送到多个分区,并且保证这些消息要么全部成功提交,要么全部回滚。

2,秒杀场景,如何设计一个秒杀功能?

秒杀场景通常具有高并发、瞬时流量大等特点,设计一个秒杀功能需要从多个方面综合考虑,以下是一个较为全面的设计方案:

前端设计

  • 静态资源优化:将秒杀页面的 HTML、CSS、JavaScript 等静态资源进行优化,如压缩、合并、缓存等,减少页面加载时间,提高用户体验。
  • 防刷机制:在前端通过验证码、滑块验证等方式,增加机器人刷请求的难度,一定程度上过滤掉非法请求。

后端设计

  • 库存管理
    • 预扣库存:当用户发起秒杀请求时,先在缓存中预扣库存,而不是直接操作数据库。这样可以快速响应请求,减少数据库的压力。
    • 库存扣减:采用乐观锁或悲观锁来保证库存扣减的原子性和一致性。例如,使用乐观锁时,在更新库存时判断当前库存是否大于等于预扣的数量,如果是则扣减库存,否则回滚事务并返回库存不足的提示。
public class SeckillServiceImpl implements SeckillService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate SeckillMapper seckillMapper;@Override@Transactionalpublic boolean seckill(Long seckillId, Long userId) {// 从缓存中获取库存String stockKey = "seckill:stock:" + seckillId;Integer stock = (Integer) redisTemplate.opsForValue().get(stockKey);if (stock == null || stock <= 0) {return false;}// 预扣库存,在缓存中减1redisTemplate.opsForValue().decrement(stockKey);try {// 扣减数据库库存int result = seckillMapper.reduceStockByOptimisticLock(seckillId);if (result > 0) {// 生成订单等后续操作createOrder(seckillId, userId);return true;} else {// 库存扣减失败,回滚缓存中的预扣库存redisTemplate.opsForValue().increment(stockKey);return false;}} catch (Exception e) {// 发生异常,回滚缓存中的预扣库存redisTemplate.opsForValue().increment(stockKey);throw new RuntimeException("秒杀失败", e);}}
}
  • 请求限流
    • 令牌桶算法:使用令牌桶算法来限制进入秒杀系统的请求流量。系统按照一定的速率生成令牌放入令牌桶中,每个请求需要获取一个令牌才能继续处理,当令牌桶中没有令牌时,请求将被拒绝。
    • 漏桶算法:漏桶算法也可用于请求限流,请求以任意速率进入漏桶,漏桶以固定的速率将请求流出进行处理,当漏桶满时,新的请求将被丢弃。
  • 异步处理
    • 消息队列:将秒杀成功的订单生成等后续操作放入消息队列中异步处理,这样可以快速响应前端请求,提高系统的并发处理能力。
    • 定时任务:对于一些需要定时执行的任务,如库存补充、订单状态更新等,可以使用定时任务来完成,避免对秒杀主流程的影响。
  • 分布式事务:在秒杀过程中,如果涉及到多个数据库操作或跨系统调用,需要使用分布式事务来保证数据的一致性。可以采用 Seata 等分布式事务框架来实现。

数据存储设计

  • 数据库设计:设计合理的数据库表结构,如秒杀商品表、订单表、用户表等,确保数据的完整性和一致性。
  • 缓存设计:使用 Redis 等缓存数据库来存储热门商品信息、库存信息等,提高数据的读写速度。

高可用设计

  • 集群部署:采用集群部署的方式,将秒杀系统部署在多个服务器上,通过负载均衡器将请求分发到不同的服务器上,提高系统的可用性和并发处理能力。
  • 容灾备份:定期对数据库和缓存进行备份,当出现故障时能够快速恢复数据,减少损失。

3,Redis 持久化机制是什么?

Redis 提供了两种持久化机制,即 RDB(Redis Database)持久化和 AOF(Append Only File)持久化,它们可以将内存中的数据保存到磁盘上,以防止数据丢失,以下是具体介绍:

RDB 持久化

  • 原理:RDB 持久化是通过对 Redis 中的数据进行定期的快照来实现的。在指定的时间间隔内,Redis 会将内存中的数据集快照写入到磁盘上的一个 RDB 文件中。这个过程是通过 fork 一个子进程来完成的,子进程负责将内存中的数据以二进制的形式写入到临时文件,然后替换原有的 RDB 文件,从而实现数据的持久化。
  • 优点
    • 高效:RDB 文件是一个经过压缩的二进制文件,存储效率高,恢复数据时速度也非常快。
    • 适合备份:由于是对整个数据集的快照,因此非常适合用于数据备份和灾难恢复场景。
  • 缺点
    • 数据丢失风险:如果在两次快照之间 Redis 发生故障,那么这期间的数据将会丢失。
    • 占用内存:在进行快照时,需要 fork 子进程,会占用一定的内存空间,可能会对性能产生一定的影响。

AOF 持久化

  • 原理:AOF 持久化以日志的形式记录 Redis 服务器所执行的所有写命令,将这些命令追加到一个 AOF 文件的末尾。当 Redis 需要恢复数据时,会重新执行 AOF 文件中的所有写命令,从而将数据恢复到内存中。
  • 优点
    • 数据安全性高:由于是记录每一条写命令,因此数据的完整性和一致性更好,丢失数据的风险相对较小。
    • 实时性好:可以通过配置将 AOF 文件的同步策略设置为每执行一条写命令就同步到磁盘,从而实现数据的实时持久化。
  • 缺点
    • 文件体积大:随着时间的推移,AOF 文件会变得越来越大,需要定期进行重写来压缩文件体积。
    • 恢复速度慢:在恢复数据时,需要重新执行 AOF 文件中的所有写命令,因此恢复速度相对较慢。

混合持久化

  • 原理:混合持久化结合了 RDB 和 AOF 两种持久化方式的优点。在开启混合持久化后,Redis 会以 RDB 的方式进行数据快照,同时将从上次 RDB 快照之后到当前时刻的所有写命令以 AOF 的方式追加到文件中。
  • 优点
    • 兼顾效率与安全:在数据恢复时,首先加载 RDB 文件,然后再重放 AOF 文件中的增量写命令,这样既可以快速恢复大部分数据,又可以保证数据的完整性。
    • 减小 AOF 文件体积:相比单纯的 AOF 持久化,混合持久化可以有效减小 AOF 文件的体积,提高了文件的读写效率。

4,解决 Redis 热点 Key 问题的方法有哪些?

Redis 热点 Key 是指在 Redis 中,某些特定的 Key 在一段时间内被大量的请求频繁访问,导致该 Key 所在的 Redis 节点负载过高,可能会影响整个系统的性能和稳定性。以下是一些解决 Redis 热点 Key 问题的方法:

优化 Key 的设计

  • 分散热点:将热点数据分散到多个不同的 Key 中,避免所有请求都集中在一个 Key 上。例如,对于一个热门商品的库存 Key,可以按照一定的规则将其拆分为多个子 Key,如 “product:stock:1”“product:stock:2” 等,不同的请求可以访问不同的子 Key。
  • 添加前缀或后缀:在 Key 的命名上添加一些随机的前缀或后缀,使得请求能够均匀地分布在不同的 Key 上。比如,对于用户的订单 Key,可以在订单号的基础上添加一个随机的字符串作为前缀,如 “order_abc123_123456”。

本地缓存

  • 客户端缓存:在应用程序的客户端本地缓存热点 Key 的数据,当客户端再次需要访问该热点 Key 时,首先从本地缓存中获取数据,如果本地缓存中有,则直接返回,无需再向 Redis 发送请求。
  • 应用层缓存:在应用层中增加一层缓存,如使用 Guava Cache 等本地缓存框架,将热点 Key 的数据缓存到应用层。当有请求访问热点 Key 时,先从应用层缓存中获取数据,命中则直接返回,未命中再去 Redis 中获取,并将获取到的数据放入应用层缓存中。

分布式缓存

  • 一致性哈希算法:采用一致性哈希算法来分配热点 Key 到不同的 Redis 节点上,使得热点 Key 能够均匀地分布在多个节点上,避免单个节点负载过高。
  • Redis 集群:使用 Redis 集群来分散热点 Key 的访问压力。Redis 集群将数据分散存储在多个节点上,当有热点 Key 的访问请求时,集群会根据 Key 的哈希值将请求路由到对应的节点上,从而实现负载均衡。

限流与降级

  • 请求限流:在应用程序的入口处对访问热点 Key 的请求进行限流,限制单位时间内的请求数量,避免过多的请求涌向 Redis。可以使用令牌桶算法或漏桶算法等限流算法来实现。
  • 服务降级:当 Redis 的热点 Key 出现性能问题时,对一些非核心的业务功能进行降级处理,减少对热点 Key 的访问。例如,对于一些推荐系统中的热点商品推荐,可以暂时降低推荐的精度或减少推荐的数量,以减轻 Redis 的压力。

数据预热

  • 提前加载热点数据:在系统启动或业务低峰期,提前将热点数据加载到 Redis 中,并进行预热,使得热点数据在被大量请求访问之前就已经在 Redis 中处于热状态,提高访问速度。
  • 动态更新热点数据:根据业务的实际情况,动态地更新热点数据的缓存时间和内容。例如,对于一些实时性要求较高的热点新闻,可以每隔一段时间就更新一次缓存中的新闻内容,确保用户获取到的是最新的热点数据。

5,MySQL 主从复制是如何实现的?

MySQL 主从复制是指将一台 MySQL 服务器(主服务器)的数据复制到一台或多台其他 MySQL 服务器(从服务器)的过程,其实现主要涉及以下三个步骤:

主服务器配置

  • 开启二进制日志:在主服务器的my.cnf配置文件中,需要确保log-bin参数已开启,该参数用于指定二进制日志文件的路径和名称前缀。例如:log-bin=mysql-bin,这将使得主服务器在执行写操作时,会将这些操作以二进制的形式记录到二进制日志文件中。
  • 设置服务器唯一 ID:为了在复制架构中唯一标识每台服务器,需要为每台服务器设置不同的server-id。在主服务器的my.cnf配置文件中,设置server-id=1,这里的1只是一个示例,通常可以根据实际情况进行设置,但必须保证整个复制集群中server-id的唯一性。

从服务器配置

  • 配置连接主服务器信息:在从服务器的my.cnf配置文件中,需要指定要连接的主服务器的相关信息,包括主服务器的 IP 地址、端口号、用于复制的用户账号和密码等。例如:
server-id=2
relay-log=mysql-relay-bin
read-only=1
log-slave-updates=1

其中,server-id设置为与主服务器不同的值,relay-log指定了中继日志文件的名称,read-only=1表示从服务器默认只提供读操作,log-slave-updates=1表示从服务器在执行中继日志中的 SQL 语句时也会将其记录到自己的二进制日志中。

  • 启动复制线程:在从服务器上执行CHANGE MASTER TO语句来配置与主服务器的连接信息,如CHANGE MASTER TO MASTER_HOST='master_ip', MASTER_PORT=3306, MASTER_USER='repl_user', MASTER_PASSWORD='repl_password';,其中master_ip是主服务器的 IP 地址,repl_userrepl_password是在主服务器上创建的用于复制的用户账号和密码。配置完成后,在从服务器上执行START SLAVE语句启动复制线程,从服务器会连接到主服务器并开始等待接收主服务器发送的二进制日志事件。

复制过程

  • 二进制日志转储线程(Binlog Dump Thread):在主服务器上,当有数据修改操作发生时,会将这些操作记录到二进制日志中。同时,主服务器会启动一个二进制日志转储线程,该线程负责将二进制日志中的事件发送给从服务器。它会根据从服务器的请求,将二进制日志中的事件按照顺序依次发送给从服务器。
  • I/O 线程(I/O Thread):在从服务器上,I/O 线程负责连接主服务器,并接收主服务器发送的二进制日志事件。它会将接收到的二进制日志事件写入到从服务器的中继日志(Relay Log)中。中继日志是从服务器上用于临时存储主服务器二进制日志事件的文件,其格式与二进制日志类似。
  • SQL 线程(SQL Thread):从服务器上的 SQL 线程会从中继日志中读取事件,并将这些事件在从服务器上执行,从而实现数据的复制。SQL 线程会按照中继日志中事件的顺序依次执行,确保数据的一致性。

6,MySQL InnoDB 和 MyISAM 的区别是什么?

MySQL 中的 InnoDB 和 MyISAM 是两种常用的存储引擎,它们在事务支持、锁机制、并发性能等多个方面存在区别,以下是详细介绍:

事务支持

  • InnoDB:支持事务处理,具有事务的四大特性 ACID(原子性、一致性、隔离性、持久性)。通过事务日志和回滚段等机制来保证事务的正确执行和数据的一致性,适用于对数据完整性和一致性要求较高的应用场景,如银行转账、电商订单处理等。
  • MyISAM:不支持事务,在执行写操作时,如果发生错误或异常,可能会导致数据不一致。对于一些简单的、对事务要求不高的应用场景,如数据仓库、日志记录等,可以使用 MyISAM 存储引擎。

锁机制

  • InnoDB:支持行级锁和表级锁,默认使用行级锁。行级锁可以在并发操作时,只锁定需要修改的行,提高并发性能。在事务处理过程中,会根据事务的隔离级别和操作的类型自动选择合适的锁类型。
  • MyISAM:只支持表级锁,在对表进行写操作时,会锁定整个表,导致其他并发的读写操作都需要等待锁的释放。因此,在高并发环境下,MyISAM 的并发性能相对较差。

并发性能

  • InnoDB:由于支持行级锁,在高并发环境下,多个事务可以同时对不同的行进行操作,并发性能较好。同时,InnoDB 还支持多版本并发控制(MVCC),可以在不加锁的情况下,实现对数据的并发读取,进一步提高并发性能。
  • MyISAM:在并发写入时,由于表级锁的限制,只能串行执行,并发性能较差。但在并发读取时,MyISAM 的性能相对较好,因为它不需要像 InnoDB 那样处理复杂的事务和锁机制。

存储结构

  • InnoDB:数据和索引存储在同一个文件中,即表空间文件(.ibd 文件)。表空间可以由多个文件组成,支持自动扩展。InnoDB 还会将数据存储在内存中的缓冲池(Buffer Pool)中,以提高数据的读写速度。
  • MyISAM:数据和索引分别存储在不同的文件中,数据文件的扩展名为.MYD,索引文件的扩展名为.MYI。在读取数据时,需要分别从数据文件和索引文件中获取信息,相对来说效率较低。

外键支持

  • InnoDB:支持外键约束,通过外键可以建立表与表之间的关联关系,保证数据的完整性和一致性。在进行数据插入、更新和删除操作时,会自动检查外键约束,避免出现数据不一致的情况。
  • MyISAM:不支持外键约束,需要在应用程序中通过代码来实现表与表之间的关联关系和数据一致性检查。

缓存机制

  • InnoDB:使用缓冲池(Buffer Pool)来缓存数据和索引,提高数据的读写效率。缓冲池中的数据会根据一定的算法进行淘汰和更新,以保证缓存的命中率。
  • MyISAM:只缓存索引文件,不缓存数据文件。在读取数据时,如果数据不在缓存中,需要从磁盘中读取,相对来说效率较低。

数据恢复

  • InnoDB:在发生故障时,可以通过事务日志和备份文件进行数据恢复。事务日志记录了所有的事务操作,通过重放事务日志,可以将数据库恢复到故障前的状态。
  • MyISAM:在发生故障时,只能通过备份文件进行恢复。如果没有及时备份,可能会导致数据丢失。

7,MySQL 中的 MVCC 是什么?

MVCC 即多版本并发控制(Multi-Version Concurrency Control),是 MySQL 中 InnoDB 存储引擎实现并发控制的一种重要机制,以下是其详细介绍:

基本原理

  • MVCC 通过为每行数据维护多个版本来实现并发控制,在事务执行过程中,每个事务看到的都是数据的某个特定版本,而不是最新的版本。这样可以在不加锁的情况下,实现多个事务对同一行数据的并发读取,提高并发性能。
  • 当一个事务对某行数据进行修改时,InnoDB 会为该行数据创建一个新的版本,并将旧版本保留在系统中。其他事务在读取该行数据时,可以根据自己的事务时间戳或其他条件,选择读取合适的版本,而不会受到当前正在进行的修改操作的影响。

实现机制

  • 事务版本号:每个事务在开始时都会被分配一个唯一的事务版本号,这个版本号随着事务的执行而递增。事务版本号用于标识事务的先后顺序和确定事务能够看到的数据版本。
  • 隐藏列:InnoDB 在每行数据中都添加了一些隐藏列,用于存储数据的版本信息。这些隐藏列包括创建版本号(DB_TRX_ID)和删除版本号(DB_ROLLBACK_SEGMENT_ID)。创建版本号记录了该行数据被创建时的事务版本号,删除版本号记录了该行数据被删除时的事务版本号。
  • 版本链:对于每一行数据,InnoDB 会根据其修改历史形成一个版本链。版本链中的每个节点都对应着该行数据的一个版本,节点之间通过指针相连。当一个事务对该行数据进行修改时,会在版本链的头部插入一个新的版本节点。
  • ReadView:ReadView 是 MVCC 的核心概念之一,它是一个事务在某个时刻对数据库的一个视图。ReadView 中包含了一些重要的信息,如创建该 ReadView 的事务版本号、当前系统中活跃的事务列表等。当一个事务进行读取操作时,会根据自己的 ReadView 来判断应该读取哪个版本的数据。

工作过程

  • 数据读取:当一个事务进行读取操作时,InnoDB 会首先根据该事务的 ReadView 来确定能够看到的数据版本。如果数据的创建版本号小于或等于该事务的版本号,并且删除版本号大于该事务的版本号或为空,则该事务可以读取该数据版本。
  • 数据修改:当一个事务对某行数据进行修改时,InnoDB 会为该行数据创建一个新的版本,并将旧版本保留在系统中。新的版本会记录当前事务的版本号作为创建版本号,同时将旧版本的删除版本号设置为当前事务的版本号。
  • 事务提交与回滚:当事务提交时,其对数据的修改会正式生效,其他事务在后续的读取操作中可能会看到新的版本。如果事务回滚,InnoDB 会根据版本链将数据恢复到事务开始前的状态。

优势

  • 提高并发性能:MVCC 允许多个事务同时对同一行数据进行并发读取,而不需要加锁,大大提高了数据库的并发性能。
  • 保证数据一致性:通过为每个事务提供一个一致的数据库视图,MVCC 可以保证事务在执行过程中看到的数据是一致的,即使在并发操作的情况下也不会出现数据不一致的情况。
  • 减少锁冲突:由于不需要对数据进行加锁,MVCC 可以减少锁冲突的发生,提高系统的稳定性和可扩展性。

8,什么是 Java 中的双亲委派模型?

双亲委派模型是 Java 中类加载器的一种工作机制,以下是关于它的详细介绍:

工作原理

  • 当一个类加载器收到类加载请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。
  • 只有当父类加载器在其搜索范围内无法找到所需的类时,子类加载器才会尝试自己去加载。

类加载器层次结构

  • Bootstrap ClassLoader:它是 Java 类加载层次结构中的顶层类加载器,主要负责加载 Java 核心库,如java.langjava.util等包中的类。它是用 C++ 实现的,是 JVM 的一部分,在 Java 中无法直接获取到它的实例。
  • Extension ClassLoader:它的父类加载器是 Bootstrap ClassLoader,主要负责加载 Java 的扩展库,即位于JRE/lib/ext目录下的类库,或者通过java.ext.dirs系统属性指定的目录下的类库。
  • Application ClassLoader:它的父类加载器是 Extension ClassLoader,也称为系统类加载器,是 Java 应用程序中默认的类加载器,负责加载应用程序的类路径(classpath)下的所有类。

实现代码示例

以下是在 Java 中模拟双亲委派模型的部分代码示例:

public class ClassLoaderTest {public static void main(String[] args) {// 获取系统类加载器ClassLoader applicationClassLoader = ClassLoader.getSystemClassLoader();// 获取扩展类加载器ClassLoader extensionClassLoader = applicationClassLoader.getParent();// 获取引导类加载器ClassLoader bootstrapClassLoader = extensionClassLoader.getParent();try {// 使用系统类加载器加载类Class<?> clazz1 = applicationClassLoader.loadClass("java.lang.String");System.out.println(clazz1.getClassLoader());// 使用扩展类加载器加载类Class<?> clazz2 = extensionClassLoader.loadClass("javax.swing.JButton");System.out.println(clazz2.getClassLoader());// 使用自定义类加载器加载类ClassLoader customClassLoader = new CustomClassLoader();Class<?> clazz3 = customClassLoader.loadClass("com.example.MyClass");System.out.println(clazz3.getClassLoader());} catch (ClassNotFoundException e) {e.printStackTrace();}}
}class CustomClassLoader extends ClassLoader {@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {if (!name.startsWith("com.example")) {return super.loadClass(name);}try {// 自定义类加载逻辑String fileName = name.substring(name.lastIndexOf('.') + 1) + ".class";InputStream is = getClass().getResourceAsStream(fileName);if (is == null) {return super.loadClass(name);}byte[] b = new byte[is.available()];is.read(b);return defineClass(name, b, 0, b.length);} catch (IOException e) {throw new ClassNotFoundException(name);}}
}

优势

  • 避免类的重复加载:确保了 Java 核心库中的类在整个系统中只有一份,避免了不同类加载器重复加载相同类可能导致的冲突和混乱。
  • 保证类的安全性:防止恶意代码自定义一个与 Java 核心库中同名的类来破坏系统的稳定性,因为核心库的类总是由 Bootstrap ClassLoader 加载,而自定义类加载器无法覆盖它。
  • 实现类的隔离性:不同的类加载器可以加载相同名称的类,这些类在不同的类加载器命名空间中是相互隔离的,这在一些复杂的应用场景中,如插件化开发、容器化部署等非常有用。

9,synchronized 和 lock 有什么区别?

在 Java 中,synchronizedLock都可用于实现多线程同步,但在使用方式、功能特性等方面存在一些区别,以下是详细介绍:

用法与语法

  • synchronized:它是 Java 中的关键字,可用于修饰方法或代码块。修饰方法时,在方法声明中加上synchronized关键字,如public synchronized void method(),表示该方法是同步方法,同一时刻只有一个线程可以访问该方法。修饰代码块时,使用synchronized(this)synchronized(obj)的形式,其中this表示当前对象,obj表示指定的对象,在该代码块执行期间,其他线程无法访问被同步的资源。
  • Lock:它是一个接口,位于java.util.concurrent.locks包中,常用的实现类是ReentrantLock。使用Lock时,需要先通过Lock接口的实现类创建一个锁对象,如Lock lock = new ReentrantLock();,然后在需要同步的代码块前调用lock.lock()方法获取锁,在代码块执行完毕后调用lock.unlock()方法释放锁。

功能特性

  • 锁的获取与释放
    • synchronized:由 Java 虚拟机自动获取和释放锁,当线程执行完同步方法或代码块时,锁会自动释放,无需手动干预。
    • Lock:需要手动调用lock()方法获取锁,unlock()方法释放锁,如果忘记释放锁,可能会导致死锁等问题,所以通常在finally块中释放锁,以确保锁一定会被释放。
  • 锁的可重入性
    • synchronized:具有隐式的可重入性,即同一个线程在已经获取了某个对象的锁的情况下,可以再次进入该对象的同步方法或代码块,不会发生死锁。
    • Lock:通过ReentrantLock等实现类实现可重入性,在构造ReentrantLock对象时,可以传入一个布尔值参数来指定是否为公平锁,默认是非公平锁。
  • 锁的公平性
    • synchronized:是非公平锁,即线程获取锁的顺序是不确定的,可能会导致某些线程长时间等待。
    • Lock:可以通过构造函数指定是否为公平锁,公平锁按照线程请求锁的顺序来分配锁,避免了线程饥饿问题,但公平锁的性能通常会比非公平锁略低。
  • 锁的等待与唤醒机制
    • synchronized:使用Object类的wait()notify()notifyAll()方法来实现线程的等待与唤醒,这些方法必须在同步代码块或同步方法中使用,且必须通过获取到锁的对象来调用。
    • Lock:通过Condition接口的await()signal()signalAll()方法来实现线程的等待与唤醒,Condition对象可以通过Lock对象的newCondition()方法获取。

性能差异

  • 在低竞争场景下,synchronized的性能与Lock相当,甚至可能更好,因为synchronized是 Java 内置的同步机制,由虚拟机进行了优化。
  • 在高竞争场景下,Lock的性能通常优于synchronized,尤其是使用非公平锁时,Lock可以提供更好的并发性能,因为它可以更灵活地控制锁的获取和释放,减少线程的等待时间。

使用场景

  • synchronized:适用于简单的同步场景,如对共享资源的单次访问进行同步,或者对整个方法进行同步。如果不需要复杂的锁控制和等待唤醒机制,使用synchronized更加简洁方便。
  • Lock:适用于复杂的同步场景,如需要手动控制锁的获取和释放、实现公平锁、多个条件变量的等待与唤醒等。在高并发场景下,如果对性能有较高要求,也可以考虑使用Lock

10,什么是指令重排序,如何解决?

指令重排序是指在程序执行过程中,编译器和处理器为了优化程序性能,对指令执行的顺序进行重新排列的一种现象。以下是关于指令重排序的详细介绍以及解决方法:

产生原因

  • 编译器优化:在不改变程序语义的前提下,编译器会对代码进行优化,调整指令的执行顺序,以提高程序的运行速度和效率。
  • 处理器乱序执行:现代处理器为了充分利用硬件资源,采用了乱序执行技术,允许指令在不影响程序最终结果的情况下,按照一定的规则进行乱序执行。

可能导致的问题

  • 多线程并发问题:在多线程环境下,指令重排序可能会导致程序的执行结果与预期不符,出现数据竞争、线程安全等问题。例如,在一个线程中对共享变量进行写操作,另一个线程中对该共享变量进行读操作,如果写操作的指令被重排序到读操作之后,就可能导致读操作读取到错误的值。

解决方法

  • 使用 volatile 关键字:当一个变量被声明为volatile时,编译器和处理器会对该变量的访问进行特殊处理,确保对该变量的读写操作不会被重排序。在多线程环境下,如果一个共享变量被多个线程访问,并且其中至少有一个线程对该变量进行写操作,那么可以将该变量声明为volatile,以保证变量的可见性和有序性。
  • 使用锁机制:通过使用synchronized关键字或Lock接口来实现锁机制,可以保证在同一时刻只有一个线程能够访问被锁定的代码块或方法,从而避免指令重排序导致的问题。在使用锁机制时,需要确保在对共享变量进行读写操作时,始终持有锁,以保证操作的原子性和有序性。
  • 使用原子类:Java 提供了一系列的原子类,如AtomicIntegerAtomicLong等,这些原子类在内部使用了CAS(比较并交换)算法来实现原子操作,并且保证了操作的可见性和有序性。在多线程环境下,如果需要对共享变量进行原子操作,可以使用原子类来代替普通的变量,以避免指令重排序导致的问题。
  • 使用内存屏障:内存屏障是一种特殊的指令,它可以阻止编译器和处理器对指令进行重排序。在 Java 中,可以通过Unsafe类来使用内存屏障,但是Unsafe类是一个底层的、不安全的类,不建议直接使用。不过,一些框架和库会在内部使用内存屏障来解决指令重排序的问题,例如Disruptor框架。

11,Spring loC 和 AOP 是什么?

Spring 是一个开源的 Java 应用程序框架,在企业级 Java 开发中广泛使用。其核心特性包括控制反转(IoC)和面向切面编程(AOP),以下是对它们的详细介绍:

Spring IoC(Inversion of Control,控制反转)

  • 概念:是一种设计模式,通过将对象的创建和依赖关系的管理交给容器来实现,而不是由对象自身去负责。在传统的程序设计中,对象之间的依赖关系通常是在代码中通过new关键字等硬编码的方式创建和管理的。而在 Spring IoC 中,对象的创建和依赖注入由 Spring 容器来完成,对象只需要关心自身的业务逻辑,降低了对象之间的耦合度。
  • 实现原理:Spring 容器在启动时,会读取配置文件(如 XML 配置文件或 Java 配置类),根据配置信息创建对象,并将对象之间的依赖关系进行注入。当一个对象需要依赖其他对象时,它不需要自己去创建,而是由 Spring 容器将所依赖的对象注入进来。
  • 依赖注入方式
    • 构造函数注入:通过类的构造函数将依赖对象注入进来。例如:
public class UserService {private UserDao userDao;public UserService(UserDao userDao) {this.userDao = userDao;}
}
  • Setter 方法注入:通过类的 Setter 方法将依赖对象注入进来。例如:
public class UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userdao;}
}
  • 字段注入:直接在类的字段上使用@Autowired等注解进行注入。例如:
public class UserService {@Autowiredprivate UserDao userDao;
}

Spring AOP(Aspect Oriented Programming,面向切面编程)

  • 概念:是一种编程范式,它允许将与业务逻辑无关的横切关注点(如日志记录、事务管理、安全检查等)从业务逻辑中分离出来,形成独立的切面(Aspect),然后在程序运行时将这些切面动态地织入到目标对象的业务逻辑中,从而实现对业务逻辑的增强,而无需修改业务逻辑代码本身。
  • 相关术语
    • 切面(Aspect):是一个包含了横切关注点的模块,通常由切点和通知组成。
    • 切点(Pointcut):用于定义在哪些连接点上应用切面,通常使用表达式来指定。
    • 通知(Advice):是在切点所定义的连接点上执行的代码,包括前置通知(在目标方法执行前执行)、后置通知(在目标方法执行后执行)、环绕通知(在目标方法执行前后都执行)、异常通知(在目标方法抛出异常时执行)和返回通知(在目标方法正常返回时执行)等。
    • 连接点(Join Point):是程序执行过程中的一个点,如方法调用、方法执行、异常抛出等,在这些点上可以插入切面的通知。
  • 实现原理:Spring AOP 基于代理模式实现,当一个目标对象需要被增强时,Spring 会为其创建一个代理对象,代理对象在调用目标对象的方法时,会根据切点的定义判断是否需要执行切面的通知,如果需要,则在目标方法执行前后或抛出异常时等执行相应的通知。
  • 使用示例
// 定义切面
@Aspect
public class LoggingAspect {// 定义切点@Pointcut("execution(* com.example.service.UserService.*(..))")public void userServicePointcut() {}// 定义前置通知@Before("userServicePointcut()")public void beforeMethod(JoinPoint joinPoint) {System.out.println("Before method: " + joinPoint.getSignature().getName());}
}

12,解决 Hash 碰撞的方法有哪些?

哈希碰撞(Hash Collision)是指不同的输入经过哈希函数计算后得到了相同的哈希值。解决哈希碰撞的方法有多种,以下是一些常见的方法:

开放定址法

  • 线性探测法:当发生哈希碰撞时,从当前哈希地址开始,依次向后探测空闲的存储单元,直到找到一个空闲位置为止。例如,哈希表大小为 10,哈希函数为hash(key)=key % 10,插入键值对(15, "value1")(25, "value2")时,hash(15)=5hash(25)=5,发生碰撞,此时使用线性探测法,会将(25, "value2")存储在hash(25)+1=6的位置。
  • 二次探测法:当发生哈希碰撞时,按照二次函数的规律来探测下一个空闲位置,即探测位置为hash(key)+i^2i为探测次数)。例如,哈希表大小为 10,哈希函数为hash(key)=key % 10,插入键值对(15, "value1")(25, "value2")时,发生碰撞后,第一次探测位置为hash(25)+1^2=6,如果6位置也被占用,则第二次探测位置为hash(25)+2^2=9,以此类推。
  • 随机探测法:在发生哈希碰撞时,通过一个随机数生成器生成一个随机的步长,然后按照这个步长来探测下一个空闲位置。

链地址法

  • 基本原理:将所有哈希地址相同的元素构成一个单链表,即把发生碰撞的元素用链表连接起来,存储在同一个哈希桶中。例如,对于哈希函数hash(key)=key % 10,键值对(15, "value1")(25, "value2")(35, "value3")都哈希到5这个位置,那么在哈希表的5号桶中,会形成一个链表,依次存储这三个键值对。
  • 优化:可以将链表替换为其他更高效的数据结构,如红黑树、跳表等,以提高在哈希桶中查找元素的效率。

再哈希法

  • 基本原理:当发生哈希碰撞时,使用另一个哈希函数对该键再次进行哈希计算,直到找到一个空闲的位置为止。例如,有哈希函数hash1(key)=key % 10hash2(key)=(key / 10) % 10,插入键值对(15, "value1")(25, "value2")时,hash1(15)=5hash1(25)=5发生碰撞,此时使用hash2(25)=2,将(25, "value2")存储在2号位置。
  • 多哈希函数选择:可以准备多个不同的哈希函数,在发生碰撞时依次尝试,或者根据一定的规则动态选择哈希函数。

建立公共溢出区

  • 基本原理:将哈希表分为基本表和溢出表两部分,当发生哈希碰撞时,将冲突的元素都存储到溢出表中。在查找元素时,先在基本表中查找,如果找不到,则再到溢出表中查找。

13,什么是 ABA 问题?

ABA 问题是在多线程并发编程中,由于对共享资源的访问和修改顺序不一致而导致的一种特殊问题,以下是具体介绍:

问题描述

  • 在多线程环境下,一个线程对共享变量进行了多次操作,使得该变量的值从 A 变成 B,又变回 A,而在这个过程中,其他线程可能在该变量值为 A 时进行了一些操作,这些操作可能会因为变量值看似未变而产生错误的结果,即线程看到的变量状态是 A,但是实际上这个 A 已经不是之前的那个 A 了,中间发生了变化又变回了 A,这就是 ABA 问题。

产生原因

  • 并发操作:多个线程同时对同一个共享变量进行读写操作,且没有进行适当的同步控制。
  • 指令重排:在没有正确同步的情况下,编译器和处理器可能会对指令进行重排序,导致操作的执行顺序与代码的书写顺序不一致,从而增加了 ABA 问题出现的可能性。

示例

import java.util.concurrent.atomic.AtomicReference;public class ABAProblemExample {private static AtomicReference<String> atomicReference = new AtomicReference<>("A");public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {String prev = atomicReference.get();System.out.println("Thread 1 read value: " + prev);// 模拟一些耗时操作try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}boolean result = atomicReference.compareAndSet("A", "B");System.out.println("Thread 1 CAS result: " + result);result = atomicReference.compareAndSet("B", "A");System.out.println("Thread 1 CAS result: " + result);});Thread thread2 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}boolean result = atomicReference.compareAndSet("A", "C");System.out.println("Thread 2 CAS result: " + result);});thread1.start();thread2.start();thread1.join();thread2.join();}
}

在上述示例中,thread1首先读取atomicReference的值为"A",然后经过一些操作将其值从"A"修改为"B",再修改回"A"。而thread2thread1操作完成后,也尝试将atomicReference的值从"A"修改为"C",此时thread2compareAndSet操作会成功,因为它看到的值也是"A",但实际上这个"A"已经不是最初的那个"A"了,这就可能导致程序出现意外的结果。

解决方法

  • 使用版本号或时间戳:在共享变量中增加一个版本号或时间戳字段,每次对变量进行修改时,同时更新版本号或时间戳。在进行比较和交换操作时,不仅要比较变量的值,还要比较版本号或时间戳,只有两者都相等时,才进行交换操作。
  • 使用AtomicStampedReferenceAtomicMarkableReferenceJava中的AtomicStampedReferenceAtomicMarkableReference类可以在原子操作中同时携带一个版本号或标记位,通过这种方式来解决 ABA 问题。

14,算法:反转链表

以下是使用 Java 语言实现反转链表的几种常见算法,这里以单链表为例进行介绍:

迭代法

  • 思路:通过遍历链表,依次改变当前节点的指针方向,使其指向前一个节点,从而实现链表的反转。需要使用两个指针,一个指针prev指向当前节点的前一个节点,初始时为null;另一个指针curr指向当前正在处理的节点,初始时指向链表的头节点。在遍历过程中,先保存当前节点的下一个节点,然后将当前节点的指针指向前一个节点,接着更新prevcurr指针,继续下一个节点的处理,直到遍历完整个链表。
  • 代码示例
class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}
}public class ReverseLinkedList {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr!= null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}return prev;}
}

递归法

  • 思路:递归地反转链表,将问题逐步分解为更小的子问题。对于一个链表,先反转除了头节点之外的其余部分链表,然后将头节点的指针指向已反转的子链表的末尾,最后返回反转后的头节点。递归的终止条件是当链表为空或者只有一个节点时,直接返回该链表。
  • 代码示例
class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;}
}public class ReverseLinkedList {public ListNode reverseList(ListNode head) {if (head == null || head.next == null) {return head;}ListNode reversedSubList = reverseList(head.next);head.next.next = head;head.next = null;return reversedSubList;}
}

在实际应用中,可以根据具体的场景选择合适的方法来反转链表,迭代法相对来说更容易理解和实现,递归法则代码更加简洁,但在处理较长链表时可能会有栈溢出的风险(取决于递归深度)。

相关文章:

1222面经

1&#xff0c;Kafka 如何保障顺序消费? Kafka 保障顺序消费主要通过以下几个关键机制和配置来实现&#xff1a; 分区策略 Kafka 将主题划分为多个分区&#xff0c;每个分区内的消息是天然有序的&#xff0c;其按照消息发送到分区的先后顺序进行存储和追加。生产者在发送消息…...

271-基于XC7V690T的12路光纤PCIe接口卡

一、板卡概述 基于XC7V690T的12路光纤PCI-E接口卡&#xff0c;用于实现多通道高速光纤数据接收和发送&#xff0c;板卡兼容PCIe 2.0和PCIe 3.0规范&#xff0c;利用PCI-E Switch PEX 8748实现FPGA芯片与计算机的通信&#xff0c;计算机与板卡接口处提供PCI-e 16速接口&#xff…...

完成第一个 Vue3.2 项目后,这是我的技术总结

第一次Composition API 在vue3.2中&#xff0c;正式支持了script setup的写法,这样可以大大简化组件的代码量&#xff0c;减少一些重复操作&#xff0c;我认为当你写vue3时&#xff0c;应该把这当作默认写法。在vue3.2之前&#xff0c;一般会这样写。 <script>export de…...

类的动态演绎:程序运行中的生命绽放

任务1.按照要求设计类(根据输出设计类) 设计类就是根据数据封装的要求&#xff0c;抽象出适合的类。 有如下情况的测试程序和测试程序的输出结果&#xff0c;要求设计类Smile。 &#xff08;一&#xff09;第1种情况&#xff1a; &#xff08;1&#xff09;测试程序如下&#x…...

从代币角度介绍solana账户体系

1、solana 的账户概念介绍 Solana的账户体系是其区块链的核心组成部分&#xff0c;它允许数据和价值在链上存储和转移。以下是Solana账户体系的一些关键特点&#xff1a; • 账户模型&#xff1a; • 在Solana上&#xff0c;所有数据都存储在所谓的“账户”中&#xff0c;类似…...

Python pygame 主副屏编程时 在副屏上全屏窗口的方法

Python在windows环境中编程时&#xff0c;用pygame工具包能够很轻易的完成2D游戏的简单设计&#xff0c;非常好用&#xff0c;相关帖子很多。 而当电脑连接了多块显示器时&#xff08;注意不是windows的多桌面&#xff09;&#xff0c;系统选择扩展这些显示器后&#xff0c;可…...

服务器数据恢复—V7000存储中多块磁盘出现故障导致业务中断的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台V7000存储上共12块SAS机械硬盘&#xff08;其中1块是热备盘&#xff09;&#xff0c;组建了2组Mdisk&#xff0c;创建了一个pool。挂载在小型机上作为逻辑盘使用&#xff0c;小型机上安装的AIXSybase。 服务器存储故障&#xff1a; V7…...

Qt开发经验 --- 避坑指南(2)

文章目录 1、 Heob窗口变得非常长&#xff0c;配置名称是一长串乱码2、 Qt安装报错 From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.3、Cmake编译错误找不到libwinpthread-1.dll4、CMake编译找不到mingw5、linux下qtcreator启动报错…...

2.4 网络概念(分层、TCP)

网络层与传输层概述 网络层&#xff1a; 抽象概念&#xff1a;网络层是基于 IP 的抽象概念&#xff0c;与数据链路层用 MAC 地址标记设备不同。MAC 地址是一种具体化的概念&#xff0c;绑定于所在的物理网络&#xff0c;而 IP 地址可以是固定的&#xff0c;也可以通过路由动态…...

Elasticsearch问题总结

Fielddata access on the_id field is disallowed, you can re-enable it by updating the dynamic cluster setting: indices.id_field_data.enabledElasticsearch默认禁用_id字段进行排序&#xff0c;这是因为_id字段通常不需要进行聚合或排序操作&#xff0c;启用字段数据可…...

C++点云大文件读取

C点云大文件读取 1. 常规读取1.1 逐行读取1.2 逐字节读取 2. 并行读取 (Multithreading)3. 使用缓冲读取 (Buffered I/O)4. 内存映射文件 (Memory Mapping) 在C中读取大文件时&#xff0c;如果需要提高读取速度&#xff0c;可以考虑以下几种方法&#xff1a; 1. 常规读取 常规…...

Hololens 2 Unity VS2019编译报错解决方案

报错问题描述不够详细&#xff0c;但是针对Hololens 2和Unity开发环境中的VS2019编译错误&#xff0c;以下 是一些常见的问题及其解决方案: 1.缺少或错误的Unity版本 确保安装了支持Hololens 2的Unity版本(例如2019.3或更高)。 2.缺少C工作负载 打开Visual Studio Installe…...

【Cadence射频仿真学习笔记】IC设计中电感的分析、建模与绘制(EMX电磁仿真,RFIC-GPT生成无源器件及与cadence的交互)

一、理论讲解 1. 电感设计的两个角度 电感的设计可以从两个角度考虑&#xff0c;一个是外部特性&#xff0c;一个是内部特性。外部特性就是把电感视为一个黑盒子&#xff0c;带有两个端子&#xff0c;如果带有抽头的电感就有三个端子&#xff0c;需要去考虑其电感值、Q值和自…...

记录:virt-manager配置Ubuntu arm虚拟机

virt-manager&#xff08;Virtual Machine Manager&#xff09;是一个图形用户界面应用程序&#xff0c;通过libvirt管理虚拟机&#xff08;即作为libvirt的图形前端&#xff09; 因为要在Linux arm环境做测试&#xff0c;记录下virt-manager配置arm虚拟机的过程 先在VMWare中…...

Qt Quick:CheckBox 复选框

复选框不止选中和未选中2种状态哦&#xff0c;它还有1种部分选中的状态。这3种状态都是Qt自带的&#xff0c;如果想让复选框有部分选中这个状态&#xff0c;需要将三态属性&#xff08;tristate&#xff09;设为true。 未选中的状态值为0&#xff0c;部分选中是1&#xff0c;选…...

腾讯云云开发 Copilot 深度探索与实战分享

个人主页&#xff1a;♡喜欢做梦 欢迎 &#x1f44d;点赞 ➕关注 ❤️收藏 &#x1f4ac;评论 目录 一、引言 二、产品介绍 三、产品体验过程 四、整体总结 五、给开发者的复用建议 六、对 AI 辅助开发的前景展望 一、引言 在当今数字化转型加速的时代&#xff0c;…...

Linux应用开发————mysql数据库表

mysql数据库表操作 查看表的结构 mysql> desc / describe 表名; 或者&#xff1a; mysql> show create table 表名; 常见数据库引擎&#xff1a; innodb, myISAM... 删除表 mysql> drop tabl…...

《军工记忆》第二季播出,科技创新铸国之重器

2019年8月1日晚20点&#xff0c;《军工记忆》第二季在央视纪录频道&#xff08;CCTV-9&#xff09;播出&#xff0c;第一集《第一颗氢弹》首当其冲&#xff0c;为我们生动描绘了氢弹研制过程的艰难岁月&#xff0c;重现中国军工事业的漫漫长路&#xff0c;科技创新铸国之重器。…...

linux 无网络安装mysql

下载地址 通过网盘分享的文件&#xff1a;mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz 链接: https://pan.baidu.com/s/1qm48pNfGYMqBGfoqT3hxPw?pwd0012 提取码: 0012 安装 解压 tar -zxvf mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz mv /usr/mysql-5.7.33-linux-glibc2.1…...

如何使用Python进行音频片断合成

以下是几种使用 Python 进行音频合成的方法&#xff1a; 使用 synthesizer 库 通过 pip install synthesizer 安装后&#xff0c;利用其提供的合成器类&#xff0c;可自定义振荡器类型&#xff0c;如锯齿波、方波或正弦波&#xff0c;并调制振幅来创造不同音色&#xff0c;还…...

【SH】在Ubuntu Server 24中基于Python Web应用的Flask Web开发(实现POST请求)学习笔记

文章目录 Flask开发环境搭建保持Flask运行Debug调试 路由和视图可变路由 请求和响应获取请求信息Request属性响应状态码常见状态码CookieSession 表单GET请求POST请求 Flask 在用户使用浏览器访问网页的过程中&#xff0c;浏览器首先会发送一个请求到服务器&#xff0c;服务器…...

方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]

文章目录 方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利…...

SpringBoot Redis 消息队列

文章目录 参考消息队列list源码 pub/sub源码 参考 https://www.cnblogs.com/uniqueDong/p/15904837.html https://www.cnblogs.com/wzh2010/p/17205390.html https://blog.csdn.net/qq_16557637/article/details/121015736 https://developer.aliyun.com/article/1095035 http…...

Oracle 中间件 Webcenter Portal服务器环境搭建

环境信息 服务器基本信息 如下表&#xff0c;本次安装总共使用2台服务器&#xff0c;具体信息如下&#xff1a; Webcenter1服务器 归类 SOA服务器 Ip Address 172.xx.xx.xx.xx HostName wcc01.xxxxxx.com Alias wccprd01 Webcenter2服务器 归类 OSB服务器 Ip Addr…...

域名和服务器是什么?域名和服务器是什么关系?

在互联网的生态系统中&#xff0c;域名和服务器是两个至关重要的组成部分。它们共同构成了我们访问网站和使用在线服务的基础。那么域名和服务器是什么?域名和服务器是什么关系? 1、域名的概念 域名是互联网中用于标识特定地址的一种文字形式。它是用户访问网站时输入的易记…...

设计模式-观察者模式

背景 气象站需要将每天测量到的温度、湿度、气压等数据公布出去&#xff0c; 需要设计开放的API&#xff0c;以便第三方获取气象站的数据&#xff0c; 如果数据有更新&#xff0c;能及时地通知第三方 传统思路&#xff1a; 创建WeatherData类&#xff0c;有温度、湿度、气…...

获取显示器(主/副屏)友好名称(FriendlyName)

在开发涉及多显示器的应用程序时&#xff0c;获取显示器的友好名称&#xff08;Friendly Name&#xff09;是一个常见需求。本文将深入探讨GetMonitorFriendlyName 方法&#xff0c;了解其实现细节和工作原理。 方法签名 public static string GetMonitorFriendlyName(bool i…...

打造智慧医院挂号枢纽:SSM 与 Vue 融合的系统设计与实施

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…...

图漾相机-ROS1_SDK_ubuntu版本编译(新版本)

文章目录 官网编译文档链接官网SDK下载链接1、下载 Camport ROS1 SDK1.下载git2、下载链接 2、准备编译工作1、安装 catkin2、配置环境变量3. 将Camport3中的linux库文件拷贝到 user/lib目录下4、修改lunch文件制定相机&#xff08;可以放在最后可以参考在线文档&#xff09;**…...

ENSP实验

一.实验拓扑 二.实验需求 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分&#xff0c;PC1可以正常访问3.3.3.0/24网段&#xff0c;但是PC2不允许 3.学校内部路由使用静态路由&#xff0c;R1和…...

10. 虚拟机VMware Workstation Pro下共享Ubuntu和Win11文件夹

本文记录当前最新版虚拟机VMware Workstation Pro&#xff08;2024.12&#xff09;如何在win11下共享文件&#xff0c;以实现Windows与Ubuntu互传文件的目的。 1. 创建共享文件夹 1.1 先关闭虚拟机的客户机&#xff0c;打开虚拟机设置 1.2 在虚拟机设置界面找到“选项”->“…...

Qwen文章阅读笔记

一、引言 大型语言模型&#xff08;LLMs&#xff09;的影响&#xff1a; LLMs通过将大量知识压缩进神经网络&#xff0c;使得它们在复杂推理和问题解决任务上展现出了惊人的能力。这些模型能够执行之前被认为只有人类才能完成的任务&#xff0c;尤其是在涉及创造力和专业知识…...

Docker容器命令

docker 命令说明docker pull拉取镜像docker push推送镜像到DockerRegistrydocker images查看本地镜像docker rmi删除本地镜像docker run创建并运行容器&#xff08;不能重复创建&#xff09;docker stop停止指定容器docker start启动指定容器docker restart重新启动容器docker…...

算法 计算大的长方形容器中,存放一排小长形容器,计算出小长形容器中最后一个元素的x坐标的位置的实现方法

1、先上个图&#xff1a; 2、说明 1&#xff09;中间的蓝色长方形是里面的橙色长方形的容器&#xff0c;比如第一个图中width2width3&#xff0c;因为只有一个&#xff0c;第二个图中有二个小的长方形&#xff0c;也就是说width22width3&#xff0c;第三个图中有3个小长方形&a…...

【libuv】Fargo信令1:client发connect消息给到server

tcp 单机测试,进行模拟 (借助copilot实现) 【Fargo】28:字节序列client发connect消息给到serverserver 收到后回复ack给到客户端程序借助copilot实现。项目构建 Console依赖于Halo.dll提供的api,Halo 依赖于 Immanuel, 运行效果 遗留问题 客户端似乎么有逻辑收到ack做处理各…...

MyBatis主键自增回填功能源码分析

文章目录 难点分析KeyGenerator接口概述SelectKeyGenerator分析 解析selectKey标签执行插入后执行获取主键查询 难点分析 【1】 事务的一致性。 在插入数据并获取自增主键时&#xff0c;可能会涉及事务的一致性问题&#xff0c;尤其是在并发插入的情况下。MyBatis需要确保即使…...

Git使用教程-分支使用/合并分支提交

Git使用教程-分支使用 文章目录 Git使用教程-分支使用一、分支&#xff08;branch&#xff09;的基本操作&#xff1a;二、查看分支&#xff1a;参考 一、分支&#xff08;branch&#xff09;的基本操作&#xff1a; git clone https://.git git status …...

TypeScript概述与安装指南

TypeScript概述与安装指南 HarmonyOS Next主要开发语言是ArkTS&#xff0c;ArkTS又是TS的超集&#xff0c;为了更好的学习HarmonyOS 和 ArkTS&#xff0c;从基础的TS入口介绍TS语法。 第一章&#xff1a;TypeScript概述与安装指南 1.1 什么是TypeScript&#xff1f; TypeSc…...

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …...

Git配置公钥步骤

GIt公钥的配置去除了git push输入账号密码的过程&#xff0c;简化了push流程。 1.生成SSH公钥和私钥 ssh-keygen -t rsa -b 4096 -C “your_emailexample.com” 遇到的所有选项都按回车按默认处理。获得的公钥私钥路径如下&#xff1a; 公钥路径 : ~/.ssh/id_rsa.pub 私钥路径…...

NSDT 3DConvert:高效实现大模型文件在线预览与转换

NSDT 3DConvert 作为一个 WebGL 展示平台&#xff0c;能够实现多种模型格式免费在线预览&#xff0c;并支持大于1GB的OBJ、STL、GLTF、点云等模型进行在线查看与交互&#xff0c;这在3D模型展示领域是一个相当强大的功能。 平台特点 多格式支持 NSDT 3DConvert兼容多种3D模型…...

优先队列【东北大学oj数据结构9-3】C++

优先队列 优先级队列是一种数据结构&#xff0c;其中保存了一组数据 S&#xff0c;其中每个元素都有一个键&#xff0c;并执行以下操作&#xff1a; insert(S, k)&#xff1a;将元素k插入集合S extractMax(S)&#xff1a;从S中取出S中key最大的元素并返回其值 创建一个程序&am…...

全志H618 Android12修改doucmentsui功能菜单项

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 在进入File文件管理器后,查看...功能菜单时,有不需要的功能菜单,需要隐藏,如:新建窗口、不显示的文件夹、故代码分析以及客制…...

SAP PP ECN CSAP_MAT_BOM_MAINTAIN

刚开始的时候ECN总是加不上&#xff0c; 参考kimi给出的案例 点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cth1ipmqvl7f04qkggdg 效果 加上了 FUNCTION ZPBOM_PLM2SAP. *"------------------------------------------------------------------…...

STM32HAL I2C函数

8.5 使用IIC协议读写EEPROM 硬件方式实现 &#xff08;HAL库&#xff09; **HAL_I2C_Mem_Write() :这种方法可以写1个或者多个字节 ** /*** brief 以阻塞模式向指定的内存地址写入数据* param hi2c 指向 I2C_HandleTypeDef 结构体的指针&#xff0c;包含指定 I2C 的配置信息…...

技术转管理需要有哪些思维上的转变?

不少项目管理行业的负责人都是从技术岗产生&#xff0c;那么技术岗做的是代码、调试之类的内容&#xff0c;除了负责范围增加外&#xff0c;还有什么思维方面的转变呢&#xff1f; 1、从个体到团队 个体的技能决定着工作的完成度&#xff0c;而在管理工作岗位上&#xff0c;项…...

数据结构漫游记:初识vector

​ 嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的…...

RestTemplate远程调用、服务注册、

一.RestTemplate Spring给我们提供了一个RestTemplate的API&#xff0c;可以方便的实现Http请求的发送。 同步客户端执行HTTP请求&#xff0c;在底层HTTP客户端库(如JDK HttpURLConnection、Apache HttpComponents等)上公开一个简单的模板方法API。RestTemplate通过HTTP方法为常…...

ARP..

ARP 0 前言 真正接触到现网才发现ARP十分重要&#xff0c;无论是排错还是S-MLAG都需要用到ARP这个协议&#xff0c;以前对于ARP的理解比较混乱&#xff1b;所以这次对其中的主要内容做个梳理&#xff1b;一定要学好ARP&#xff01;&#xff01;&#xff01; 1 ARP的概念 Ar…...

电子电器架构 ---整车区域控制器

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...