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

Apache Commons Pool :介绍与使用

Apache Commons Pool :介绍与使用

什么是 commons-pool2

commons-pool2 是 Apache Commons 提供的一个开源对象池实现框架。它旨在为应用程序提供通用的对象池支持,方便开发者管理资源(如数据库连接、网络连接等)复用,从而减少资源创建与销毁的开销,提高应用程序的性能和可扩展性。


功能特性

  1. 对象池管理:
    • 提供对象的创建、复用、回收、销毁机制。
  2. 多种池实现:
    • 支持通用对象池(GenericObjectPool)和键值对象池(GenericKeyedObjectPool)。
  3. 强大的配置支持:
    • 可以自定义池大小、最大闲置数、最小闲置数等。
  4. 线程安全:
    • 内部实现了高效的并发控制。
  5. 动态调节:
    • 支持在运行时动态调整池的大小和行为。

如何使用

Maven 依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version>
</dependency>

使用步骤

  1. 创建对象工厂:
    • 实现 org.apache.commons.pool2.PooledObjectFactory 接口,用于定义对象的创建和销毁逻辑。
  2. 初始化对象池:
    • 使用 GenericObjectPoolGenericKeyedObjectPool 来管理对象池。
  3. 获取与归还对象:
    • 使用 borrowObject() 从池中获取对象,用完后通过 returnObject() 将对象归还到池中。

示例:使用 GenericObjectPool

以下是一个简单的数据库连接池实现。

import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;// 模拟的数据库连接类
class DatabaseConnection {private String id;public DatabaseConnection(String id) {this.id = id;}public void connect() {System.out.println("Connecting to database with ID: " + id);}public void close() {System.out.println("Closing database connection with ID: " + id);}public String getId() {return id;}
}// 数据库连接工厂类
class DatabaseConnectionFactory implements PooledObjectFactory<DatabaseConnection> {private int counter = 0;@Overridepublic PooledObject<DatabaseConnection> makeObject() {DatabaseConnection connection = new DatabaseConnection("DB-" + (++counter));System.out.println("Creating new connection: " + connection.getId());return new DefaultPooledObject<>(connection);}@Overridepublic void destroyObject(PooledObject<DatabaseConnection> p) {p.getObject().close();}@Overridepublic boolean validateObject(PooledObject<DatabaseConnection> p) {return true; // 假设所有对象都有效}@Overridepublic void activateObject(PooledObject<DatabaseConnection> p) {p.getObject().connect();}@Overridepublic void passivateObject(PooledObject<DatabaseConnection> p) {// 暂时不需要实现}
}public class ConnectionPoolExample {public static void main(String[] args) throws Exception {// 配置对象池GenericObjectPoolConfig<DatabaseConnection> config = new GenericObjectPoolConfig<>();config.setMaxTotal(5);          // 最大对象数config.setMaxIdle(3);           // 最大闲置数config.setMinIdle(1);           // 最小闲置数config.setTestOnBorrow(true);   // 借出时测试对象是否有效// 创建对象池GenericObjectPool<DatabaseConnection> pool = new GenericObjectPool<>(new DatabaseConnectionFactory(), config);// 使用对象池DatabaseConnection conn1 = pool.borrowObject(); // 从池中获取对象conn1.connect();DatabaseConnection conn2 = pool.borrowObject();conn2.connect();pool.returnObject(conn1); // 将对象归还到池中pool.returnObject(conn2);// 销毁池pool.close();}
}

输出示例

Creating new connection: DB-1
Connecting to database with ID: DB-1
Connecting to database with ID: DB-2
Closing database connection with ID: DB-1
Closing database connection with ID: DB-2

优化方式

  1. 合理配置池参数:

    • maxTotal:限制最大对象数,防止过多对象占用内存。
    • minIdle:设置最小闲置数,避免频繁创建与销毁对象。
    • maxWaitMillis:设置获取对象的超时时间。
  2. 定期测试池对象:

    • setTestOnBorrow(true):借出时验证对象。
    • setTestOnReturn(true):归还时验证对象。
    • setTestWhileIdle(true):闲置时验证对象。
  3. 监控池性能:

    • 利用池的 getNumActive()getNumIdle() 方法动态监控池中活动与闲置的对象数。
  4. 资源回收:

    • 确保池在不需要时调用 close() 释放资源。

常见场景

  1. 数据库连接池
  2. 网络连接池
  3. 线程池管理
  4. 文件句柄池

commons-pool2 闲置对象过期及设置详解

默认行为

commons-pool2 的连接池实现中,闲置对象的过期时间以及移除行为由多个参数共同决定。

默认配置

  • 默认情况下,如果没有显式设置移除闲置对象的策略,连接池中的对象可能因为资源限制而被移除。
  • 具体的移除时机依赖于如下参数设置。

相关参数详解

1. minIdle

  • 描述: 最小闲置连接数。
  • 作用: 保证连接池中始终有一定数量的对象处于闲置状态。
  • 默认值: 0(即没有保留最小闲置对象)。
  • 影响: 如果设置为较大的值,连接池会在对象被移除前尝试补充更多的空闲对象。

2. timeBetweenEvictionRunsMillis

  • 描述: 间隔多久运行一次空闲对象的逐出检查线程(以毫秒为单位)。
  • 默认值: -1(表示不运行逐出线程)。
  • 建议优化: 设置为合理的时间间隔,例如 30000 毫秒(30 秒)。

3. minEvictableIdleTimeMillis

  • 描述: 对象在池中保持空闲状态的最小时间(以毫秒为单位),超过该时间的对象可能会被移除。
  • 默认值: 1800000 毫秒(30 分钟)。
  • 建议优化: 设置为较小的值以快速移除闲置对象,例如 600000 毫秒(10 分钟)。

4. softMinEvictableIdleTimeMillis

  • 描述: 对象在池中保持空闲状态的最小时间(以毫秒为单位),但只有当空闲对象超过 minIdle 时才会被移除。
  • 默认值: 未设置。
  • 建议优化: 配合 minIdle 使用,用于延长部分闲置对象的存活时间。

5. numTestsPerEvictionRun

  • 描述: 每次空闲对象检查时检测的对象数量。
  • 默认值: -1(检查所有对象)。
  • 建议优化: 根据池的大小设置为一个合理的值,例如 10

配置示例

以下是一个完整的连接池配置示例:

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;public class PoolConfigExample {public static void main(String[] args) {GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();// 设置最小空闲对象数config.setMinIdle(5);// 设置最大空闲对象数config.setMaxIdle(20);// 设置最大池容量config.setMaxTotal(50);// 设置空闲对象逐出线程运行间隔(30 秒)config.setTimeBetweenEvictionRunsMillis(30000);// 设置空闲对象的最小逐出时间(10 分钟)config.setMinEvictableIdleTimeMillis(600000);// 检查空闲对象的线程一次处理的数量config.setNumTestsPerEvictionRun(5);// 创建连接池GenericObjectPool<Object> pool = new GenericObjectPool<>(new MyObjectFactory(), config);System.out.println("连接池初始化完成!");}
}// 示例对象工厂
class MyObjectFactory extends BasePooledObjectFactory<Object> {@Overridepublic Object create() throws Exception {return new Object(); // 返回一个新对象}@Overridepublic PooledObject<Object> wrap(Object obj) {return new DefaultPooledObject<>(obj);}
}

总结

空闲对象的移除策略

  • 默认情况下,闲置对象不会自动过期,除非设置了逐出线程参数(如 timeBetweenEvictionRunsMillis)。
  • 设置 minEvictableIdleTimeMillis 可以明确指定闲置对象的过期时间。
  • 通过调优 minIdlemaxIdle 可以更好地控制池中对象的生命周期。

推荐配置

  • 动态调整参数: 根据实际负载和资源需求动态调整 minIdletimeBetweenEvictionRunsMillis
  • 观察性能: 通过性能测试和监控,逐步优化连接池的行为,减少过期对象对系统性能的影响。

Apache Commons Pool: 最小闲置数与逐出线程的交互行为

背景介绍

Apache Commons Pool 是一个高效的对象池管理库,广泛用于连接池、线程池等需要管理资源的场景。其配置包括 最小闲置数 (minIdle)逐出线程 (Evictor) 参数。

  • 最小闲置数 (minIdle)

    • 定义对象池中需要保持的最小空闲对象数。
    • 如果空闲对象少于该值,池会创建新的对象,直到满足 minIdle
  • 逐出线程 (Evictor)

    • 周期性检查并清理空闲对象。
    • timeBetweenEvictionRunsMillisminEvictableIdleTimeMillis 参数控制。

参数交互行为

minIdle 和逐出线程参数同时设置时,逐出线程会考虑 minIdle,确保空闲对象数不低于该值。

逐出线程行为规则

  1. 逐出线程运行规则

    • 定期检查空闲对象是否超过 minEvictableIdleTimeMillis
    • 清理超过空闲时间的对象。
  2. 空闲对象保留规则

    • 如果当前空闲对象数少于或等于 minIdle,逐出线程不会清理这些对象。
    • 若空闲对象数大于 minIdle,逐出线程会清理部分对象,直到空闲对象数等于 minIdle 或更少。

参数对行为的影响

参数描述
minIdle池中最小保留空闲对象数。
timeBetweenEvictionRunsMillis逐出线程运行的时间间隔(毫秒)。
minEvictableIdleTimeMillis对象可被清理的最小空闲时间(毫秒)。

示例代码

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;public class PoolConfigExample {public static void main(String[] args) {GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();// 设置最小空闲数config.setMinIdle(5);// 逐出线程每30秒运行一次config.setTimeBetweenEvictionRunsMillis(30000);// 空闲时间超过60秒的对象可能被清理config.setMinEvictableIdleTimeMillis(60000);// 示例:确保至少保留5个空闲对象System.out.println("Pool configured with minIdle=5");}
}

特殊场景

  1. 最小闲置数未设置或为0

    • 空闲对象数可能会被清理为 0。
    • 下次获取对象时需要重新创建,可能导致性能下降。
  2. 逐出线程未设置

    • 空闲对象永远不会被清理,可能造成内存占用。

重要结论

  • 逐出线程不会清理到低于 minIdle 的空闲对象数
  • 如果设置合理的 minEvictableIdleTimeMillistimeBetweenEvictionRunsMillis,可以在资源回收与性能间取得平衡。
  • 配置建议:
    • 保证 minIdle 的值与系统负载需求匹配。
    • 根据对象的生命周期合理配置 minEvictableIdleTimeMillis
    • 避免过于频繁或过于稀疏的逐出线程运行时间。

总结

Apache Commons Pool 提供了灵活的参数配置,支持多种资源池管理场景。当 minIdle 和逐出线程参数同时设置时,系统会优先保证 minIdle 的空闲对象数,不会因逐出线程清理而导致空闲对象不足。合理的参数配置可以在资源利用率与性能间找到最佳平衡点。


Apache Commons Pool - 逐出线程设置指南

背景

在使用 Apache Commons Pool 进行对象池管理时,如果未设置逐出线程,空闲对象将永远不会被清理,可能导致内存占用问题。因此,合理配置逐出线程的相关参数可以避免资源泄露,提高系统性能。


关键参数

timeBetweenEvictionRunsMillis

  • 作用:控制逐出线程的运行周期(以毫秒为单位)。
  • 默认值-1,表示逐出线程不运行。
  • 建议设置:例如 60000 表示每分钟运行一次。

minEvictableIdleTimeMillis

  • 作用:设置空闲对象被逐出的最小生存时间(以毫秒为单位)。
  • 默认值1800000(30 分钟)。
  • 建议设置:根据业务需求调整,例如 10 分钟:600000

minIdle

  • 作用:确保池中始终保持的最小空闲对象数。即使逐出线程运行,也不会清理低于该数量的空闲对象。
  • 建议设置:根据系统负载调整,例如 5

maxIdle

  • 作用:限制池中空闲对象的最大数量。如果空闲对象超过此值,多余的对象会被逐出。
  • 建议设置:例如 10

配置代码示例

以下代码展示如何通过 GenericObjectPool 设置逐出线程:

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;public class PoolExample {public static void main(String[] args) {// 配置池参数GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();// 设置最小空闲连接数config.setMinIdle(5);// 设置最大空闲连接数config.setMaxIdle(10);// 设置最大连接数config.setMaxTotal(20);// 逐出线程运行周期(每 60 秒运行一次)config.setTimeBetweenEvictionRunsMillis(60000);// 最小可逐出时间(30 分钟未使用的空闲对象会被清理)config.setMinEvictableIdleTimeMillis(1800000);// 创建对象池GenericObjectPool<Object> pool = new GenericObjectPool<>(new ObjectFactory(), config);// 使用对象池try {Object obj = pool.borrowObject(); // 获取对象pool.returnObject(obj);           // 归还对象} catch (Exception e) {e.printStackTrace();} finally {pool.close(); // 关闭池}}// 自定义对象工厂static class ObjectFactory extends BasePooledObjectFactory<Object> {@Overridepublic Object create() {return new Object(); // 创建对象}@Overridepublic PooledObject<Object> wrap(Object obj) {return new DefaultPooledObject<>(obj); // 包装对象}}
}

参数详细说明

参数名称作用示例值
setTimeBetweenEvictionRunsMillis控制逐出线程的运行周期。正值表示启用逐出线程,例如 60000 表示每分钟运行一次。60000
setMinEvictableIdleTimeMillis空闲对象的最小生存时间,超过此时间的对象会被逐出。1800000
setMinIdle保证的最小空闲对象数,即使逐出线程运行,也不会清理低于该数量的对象。5
setMaxIdle最大空闲对象数,超过此值的对象会被逐出。10

配置文件示例

可以通过 properties 文件加载配置:

pool.minIdle=5
pool.maxIdle=10
pool.maxTotal=20
pool.timeBetweenEvictionRunsMillis=60000
pool.minEvictableIdleTimeMillis=1800000

在代码中加载配置:

Properties props = new Properties();
try (InputStream input = new FileInputStream("config.properties")) {props.load(input);GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();config.setMinIdle(Integer.parseInt(props.getProperty("pool.minIdle")));config.setMaxIdle(Integer.parseInt(props.getProperty("pool.maxIdle")));config.setMaxTotal(Integer.parseInt(props.getProperty("pool.maxTotal")));config.setTimeBetweenEvictionRunsMillis(Long.parseLong(props.getProperty("pool.timeBetweenEvictionRunsMillis")));config.setMinEvictableIdleTimeMillis(Long.parseLong(props.getProperty("pool.minEvictableIdleTimeMillis")));
}

优化建议

  1. 合理设置最小和最大空闲对象数:避免频繁创建和销毁对象。
  2. 监控池性能:通过池提供的指标(例如活动对象数、空闲对象数)动态调整配置。
  3. 避免逐出线程频繁运行:将逐出线程运行周期设置为合理的值,例如 1 分钟或更长时间。
  4. 测试与调优:根据实际使用场景不断调整参数,平衡性能与资源消耗。

通过合理设置逐出线程和相关参数,可以显著提高对象池的性能和资源利用效率。


线程数量逐渐增加的原因分析与参数设置建议

当线程数量逐渐增加时,可能是由于以下原因或参数设置的问题导致的。以下是详细分析及解决方法。


1. 未限制线程池最大线程数量

  • 原因

    • 未设置线程池的最大线程数 (maxTotal),默认值可能非常大甚至是无界的。随着任务增加,线程池不断创建新线程来满足请求,导致线程数量逐渐增加。
  • 解决方法

    • 设置合理的 maxTotal 值,以限制线程池中的最大线程数。

2. 核心线程数设置过高

  • 原因

    • corePoolSize 是线程池中核心线程的数量。如果设置过高,即使任务较少,线程池也会保持较多的核心线程。
  • 解决方法

    • 根据实际需求,设置一个合理的 corePoolSize 值,以减少空闲线程的数量。

3. 空闲线程未被回收

  • 原因

    • 空闲线程的生存时间参数 (minEvictableIdleTimeMillis) 过长,导致空闲线程无法及时被逐出。
  • 解决方法

    • 设置 minEvictableIdleTimeMillis 为合理的时间(如 30 秒或 60 秒),使得空闲线程能在闲置一段时间后被回收。

4. 逐出线程未启动

  • 原因

    • 未启用逐出线程(Evictor),导致空闲线程不会被定期清理,线程池中的线程数量可能持续累积。
  • 解决方法

    • 设置 timeBetweenEvictionRunsMillis 为一个正值(如 30000 毫秒),开启逐出线程。
    • 配合使用 minEvictableIdleTimeMillisnumTestsPerEvictionRun 参数进行逐出策略优化。

5. 任务积压导致线程池扩容

  • 原因

    • 线程池的队列(workQueue)容量不足时,新任务可能会触发线程池动态扩容。如果任务积压过多,线程池可能创建更多线程来处理任务。
  • 解决方法

    • 使用有限大小的阻塞队列(如 LinkedBlockingQueue),并合理设置其容量。
    • 设置 maximumPoolSize 限制线程数量的扩展。

6. 线程工厂问题

  • 原因

    • 如果线程池使用的 ThreadFactory 未正确管理线程,可能会导致线程池创建更多的线程。
  • 解决方法

    • 确保 ThreadFactory 正确实现,并为线程池创建的线程设置合理的优先级、命名和守护线程属性。

7. 线程泄漏

  • 原因

    • 某些任务未正常退出线程,或线程被错误地持久化,导致线程池中的线程无法被回收。
  • 解决方法

    • 定期监控线程池中的活动线程数。
    • 确保任务逻辑正确,避免线程长期处于阻塞状态。

参数设置示例

以下是一个合理的线程池参数设置,避免线程数量逐渐增加:

GenericObjectPoolConfig<Object> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(100); // 设置线程池最大线程数
config.setMinIdle(10);  // 设置最小闲置线程数
config.setMaxIdle(50);  // 设置最大闲置线程数
config.setTimeBetweenEvictionRunsMillis(30000); // 逐出线程运行间隔
config.setMinEvictableIdleTimeMillis(60000);   // 最小闲置时间
config.setNumTestsPerEvictionRun(3);           // 每次逐出线程检测的对象数

通过合理的参数设置,可以有效控制线程数量,避免不必要的资源消耗。


对象清理行为分析及配置

问题描述

最小闲置数未设置或为0逐出线程未设置 的情况下,如何清理空闲对象?是优先清理最小闲置数为0的对象,还是优先考虑逐出线程未设置的情况,即使最小闲置数为0也不清理?


行为规则分析

1. 最小闲置数未设置或为0

  • 效果
    • 如果 minIdle 设置为 0 或未设置,则空闲池对象可以降到 0 个,即没有任何最小保留的连接或线程。
    • 但仅此设置并不会直接导致清理,因为清理动作需要逐出线程的参与。

2. 逐出线程未设置

  • 效果
    • 如果没有设置逐出线程(即未配置 evictor),则系统不会主动清理空闲对象。
    • 即使 minIdle0,由于缺少逐出线程触发,空闲对象仍然会长期存在。

3. 优先顺序

  • 逐出线程优先控制清理逻辑:如果没有逐出线程,即使 minIdle0,也不会清理空闲对象。
  • 清理动作需要逐出线程定期检查并触发。

总结行为

1. 逐出线程未设置的情况

  • 空闲对象永远不会被清理。
  • 即使 minIdle0,对象也会一直存在,导致资源可能被长期占用。

2. 逐出线程设置了,但 minIdle 为0的情况

  • 逐出线程会按照配置定期运行,清理空闲对象,直到池中对象数量为 0

优化建议

1. 如果希望空闲对象及时释放:

  • 配置逐出线程参数:
    • timeBetweenEvictionRunsMillis:逐出线程运行的时间间隔(单位:毫秒)。
    • minEvictableIdleTimeMillis:空闲对象被逐出的最短存活时间(单位:毫秒)。
  • 设置 minIdle 为合适的非零值(如 minIdle = 2),确保资源池中保留一定数量的空闲对象。

2. 如果不希望清理空闲对象:

  • 设置 minIdle 为大于 0 的值(如 minIdle = 5)。
  • 不设置逐出线程参数,或将 timeBetweenEvictionRunsMillis 设置为一个较大的值,避免频繁触发清理。

示例代码

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();// 设置最小闲置数为 0
config.setMinIdle(0);// 配置逐出线程,每 30 秒运行一次
config.setTimeBetweenEvictionRunsMillis(30000);// 空闲对象超过 60 秒被逐出
config.setMinEvictableIdleTimeMillis(60000);

参数含义

参数名说明示例值
minIdle最小闲置对象数0
timeBetweenEvictionRunsMillis逐出线程运行间隔30000
minEvictableIdleTimeMillis空闲对象存活时间60000

通过合理的配置,可以有效管理资源池对象的生命周期,防止资源浪费或内存泄漏,同时提升系统性能。


相关文章:

Apache Commons Pool :介绍与使用

Apache Commons Pool &#xff1a;介绍与使用 什么是 commons-pool2&#xff1f; commons-pool2 是 Apache Commons 提供的一个开源对象池实现框架。它旨在为应用程序提供通用的对象池支持&#xff0c;方便开发者管理资源&#xff08;如数据库连接、网络连接等&#xff09;复…...

sentinel-请求限流、线程隔离、本地回调、熔断

请求限流&#xff1a;控制QPS来达到限流的目的 线程隔离&#xff1a;控制线程数量来达到限流的目录 本地回调&#xff1a;当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断&#xff1a;熔断也叫断路器&#xff0c;当失败、或者…...

微信小程序 app.json 配置文件解析与应用

目录 一、什么是 app.json&#xff1f; 二、app.json 文件的基本结构 三、详细解析 app.json 配置项 1. pages&#xff1a;小程序页面路径配置 2. window&#xff1a;窗口样式配置 3. tabBar&#xff1a;底部标签栏配置 4. networkTimeout&#xff1a;网络请求超时配置 …...

C语言-共用体(联合体)

1.共用体(联合体) 1.共用体union是一个能在同一个存储空间存储不同类型数据的类型 2.共用体所占的内存长度等于其最长成员的长度。 3.同一内存段可以用来存放几种不同类型的成员&#xff0c;但每一瞬时只有一种起作用 4.共用体变量中起作用的成员是最后一次存放的成员&#xff…...

C++算法知识点

创建队列&#xff1a; 关于队列的一些常用方法&#xff1a; 创建栈&#xff1a; 将字符串换成整数&#xff1a;...

芝法酱学习笔记(2.3)——shardingsphere分库分表

一、前言 之前的例子中&#xff0c;我们以一个简化了的销售单报表查询&#xff0c;展示了大数据量查询时&#xff0c;在索引和变量类型层面可以做的一些优化。可我们发现&#xff0c;无论怎么优化&#xff0c;一次查询都要好几秒。 这是一个现实问题&#xff0c;只要一个系统用…...

vue3+vite+nginx打包

在开发环境下&#xff0c;已经可以正常地运行一个有增删改查功能的页面了&#xff0c;但如何把它发布到运行服务器呢&#xff1f;仍有许多的问题需要探索。 网上很多文章给了很大的帮助&#xff0c;但总是没有说明原理&#xff0c;对于像我这样的初学者来说&#xff0c;不知其…...

爬虫与反爬虫实现全流程

我选取的网页爬取的是ppt nba版 需要的工具:pycharm,浏览器 爬虫需要观察它的网页信息,然后开始首先爬取它的html,可以看到有人气,标题,日期,咨询 可以看到用get方法 import requests url"https://img-home.csdnimg.cn/images/20230724024159.png?origin_urlhttps%3A%2…...

Kimi进行学术方向选择精讲!

目录 1.文献搜索 2.辅助选题 3.选题判断 在我们之前的文章中&#xff0c;小编都强调了选题在文章价值中的核心作用。一篇优秀的文章背后&#xff0c;肯定有一个精心挑选的选题。选题的好坏直接影响着文章能够发表的期刊等级。许多宝子们却采取了相反的做法&#xff0c;将大量…...

湖北产教融合教育研究院重庆分院揭牌成立

百年大计&#xff0c;教育为本。为积极响应重庆市人才培养的迫切需求&#xff0c;充分发挥中国同等学力申硕综合服务领航者的专业优势&#xff0c;12月26日&#xff0c;湖北产教融合教育研究院重庆分院启动仪式在渝北区龙山一路278号祈年悦城4栋24层隆重举行。 湖北产教融合教育…...

探索CSS Houdini:下一代样式与动画技术

随着前端开发对用户体验的要求不断提高&#xff0c;传统的CSS在某些场景下难以满足开发者的高阶需求。在这种背景下&#xff0c;CSS Houdini 技术应运而生&#xff0c;为开发者提供了更高自由度和更强大的功能&#xff0c;开创了现代Web动画与样式的新可能。 什么是CSS Houdin…...

winserver搭建域环境

域环境的搭建 7.1理论知识 Windows Server 2008网络类型 工作组&#xff08;Work Group&#xff09; 在安装Windows系统的时候 &#xff0c;工作组名一般为“workgroup”,也可以任意起个名字&#xff0c;在同一工作组或不同工作组在访问时也没有什么分别&#xff0c;在使用时&a…...

鸿蒙开发工程师成长的五个阶段

在科技日新月异的今天&#xff0c;鸿蒙&#xff08;HarmonyOS&#xff09;作为华为自主研发的操作系统&#xff0c;正以其独特的魅力和广阔的应用前景吸引着越来越多的开发者加入。鸿蒙不仅承载着华为对未来智能设备互联互通的愿景&#xff0c;也为开发者提供了一个充满挑战与机…...

Redis集成到SpingBoot 的数据结构常见操作

一.环境配置 1.依赖注入 2.yaml文件配置 3.启动本地Redis服务 (或在虚拟机上启动,这里为了方便演示在本地启动) 4.启动成功案例 5.创建一个Controller我们开始演示 RestController public class MyController {Autowiredprivate StringRedisTemplate redisTemplate;} 二 …...

输入输出(I/O):熟悉 Java 的 I/O 类库,尤其是 NIO 和文件操作

输入输出&#xff08;I/O&#xff09;&#xff1a;熟悉 Java 的 I/O 类库&#xff0c;尤其是 NIO 和文件操作 在 Java 中&#xff0c;I/O&#xff08;输入输出&#xff09;操作是开发中非常重要的一部分&#xff0c;用于与文件、网络和其他数据流交互。Java 提供了传统的 I/O&…...

mysql建立主从集群

mysql建立主从集群需要多个mysql服务器&#xff0c;主从数据库是通过log日志来进行同步的&#xff0c;所以需开启log-bin。本地安装多个mysql参考底部 主数据库配置 打开主数据库my.ini配置文件&#xff0c;给其配置server_id1 [mysqld] port3306 basedirD:/phpstudy_pro/1/…...

Python AI 教程之四:无监督学习

什么是无监督学习? 无监督学习是机器学习的一个分支,用于处理未标记的数据。与监督学习(其中数据被标记为特定类别或结果)不同,无监督学习算法的任务是在不了解数据含义的情况下寻找数据中的模式和关系。这使得无监督学习成为探索性数据分析的强大工具,其目标是了解数据…...

ReactiveStreams、Reactor、SpringWebFlux

注意&#xff1a; 本文内容于 2024-12-28 21:22:12 创建&#xff0c;可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容&#xff0c;请访问原文地址&#xff1a;ReactiveStreams、Reactor、SpringWebFlux。感谢您的关注与支持&#xff01; ReactiveStreams是…...

Qt 的信号槽机制详解:之信号槽引发的 Segmentation Fault 问题拆析(下)

Qt 的信号槽机制详解&#xff1a;之信号槽引发的 Segmentation Fault 问题拆析&#xff08;下&#xff09; 前言一. 信号槽的误用导致崩溃的常见原因1.信号和槽连接的对象被提前释放案例解决方法 2.参数类型不匹配案例解决方法 3. 多线程信号槽使用不当案例解决方法 4. 信号重复…...

opencv(cpp) Mat使用总结

opencv访问矩阵的通道数 #include <opencv2/opencv.hpp> #include <iostream>int main() {// 创建一个3通道的彩色图像&#xff08;例如&#xff0c;BGR格式&#xff09;cv::Mat colorImage cv::Mat::zeros(100, 100, CV_8UC3);// 创建一个单通道的灰度图像cv::M…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...