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

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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/499008.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自建私有云相册:Docker一键部署Immich,照片视频备份利器

自建私有云相册&#xff1a;Docker一键部署Immich&#xff0c;照片视频备份利器 前言 随着人们手机、PC、平板等电子产品多样&#xff0c;我们拍摄和保存的照片和视频数量也在不断增加。如何高效地管理和备份这些珍贵的记忆成为了一个重要的问题。 传统的云备份虽然方便&…

ArcGIS教程(009):ArcGIS制作校园3D展示图

文章目录 数据下载校园3D展示图制作创建要素类矢量化【楼】要素矢量化【绿地】矢量化【范围】矢量化处理打开ArcScene添加动画数据下载 https://download.csdn.net/download/WwLK123/90189025校园3D展示图制作 创建要素类 添加底图: 新建【文件地理数据库】,并修改名称为【…

Windows安装了pnpm后无法在Vscode中使用

Windows安装了pnpm后无法在Vscode中使用 解决方法&#xff1a; 以管理员身份打开 PowerShell 并执行以下命令后输入Y回车即可。 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser之后就可以正常使用了

OpenHarmony源码编译后烧录镜像教程,RK3566鸿蒙开发板演示

本文介绍瑞芯微主板/开发板编译OpenHarmony源码后烧录镜像的教程&#xff0c;触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器&#xff0c;树莓派卡片电脑设计&#xff0c;支持开源鸿蒙OpenHarmony3.2-5.0系统&#xff0c;适合鸿蒙开发入门学习。 编译源码…

【MATLAB APP Designer】小波阈值去噪(第一期)

代码原理及流程 小波阈值去噪是一种信号处理方法&#xff0c;用于从信号中去除噪声。这种方法基于小波变换&#xff0c;它通过将信号分解到不同的尺度和频率上来实现。其基本原理可以分为以下几个步骤&#xff1a; &#xff08;1&#xff09;小波变换&#xff1a;首先对含噪信…

关于埃斯顿机器人指令含义

等待一组数字量输入指令&#xff0c;用于多个输入数字量的指示&#xff01; DO8421(9.17.0)该指令含义为将9-17端口的虚信号输出为0 (图1) (CALL指令) 子程序调用指令&#xff0c;用于程序中调用子程序 (SetSimDO指令) 设置虚拟数字量输出指令&#xff0c;用于程序中设置虚…

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…

html+css+js网页设计 美食 家美食1个页面

htmlcssjs网页设计 美食 家美食1个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xf…

【发票提取明细+发票号改名】批量提取PDF电子发票明细导出Excel表格并改名技术难点,批量PDF多区域内容识别提取明细并用内容改名的小结

1、图片版的发票提取表格改名 【批量图片发票识别表格】批量图片发票的提取Excel表格和提取字段改名&#xff0c;扫描发票识别表格&#xff0c;拍照发票识别表格&#xff0c;图片发票识别改名我们在工作中很多扫描发票&#xff0c;拍照发票&#xff0c;需要整理成excel表格&am…

如何规范的提交Git?

多人协作开发提交代码通常是遵循约定式提交规范&#xff0c;如果严格安照约定式提交规范&#xff0c; 手动进行代码提交的话&#xff0c;那么是一件非常痛苦的事情&#xff0c;但是 Git 提交规范的处理又势在必行&#xff0c;那么怎么办呢&#xff1f; 经过了很多人的冥思苦想…

MiFlash 线刷工具下载合集

MiFlash 线刷工具下载合集 MiFlash 线刷工具下载合集 – MIUI历史版本相较于小米助手的刷机功能&#xff0c;线刷还是偏好使用 MiFlash。特点是界面简单纯粹&#xff0c;有自定义高级选项&#xff0c;可以选择刷机不上 BL 锁&#xff0c;自定义刷机脚本&#xff0c;EDL 刷机模…

STM32 SPI读取SD卡

七个响应类型&#xff1a; R1 Response (Normal Response): R1响应是最基本的响应&#xff0c;包含一个字节的状态位&#xff0c;用于指示命令是否成功执行。常用。最高位为0。最低位为1表示是空闲状态。其他位是各种错误提示。 R1b Response (Normal with Busy): 类似于R1&a…

深入浅出 Spring (二)| 依赖注入(DI)、自动装配

3. 依赖注入&#xff08;DI&#xff09; 3.1 概念 依赖注入&#xff08;Dependency Injection,DI&#xff09;。 依赖&#xff1a;bean对象的创建依赖于容器&#xff01;注入&#xff1a;bean对象中的所有属性&#xff0c;由容器来注入&#xff01; 创建子项目 spring04-DI…

线性代数期末复习 [基础篇]

关于第六点: AXB 在期末考试中一般A都是可逆的 我们可以先把A的逆求出来,X A − 1 B A^-1B A−1B,或者 (A,B) -> r (E, A − 1 B A^-1B A−1B) 如果A矩阵不可逆,转变为方程组求解问题,假设都是二维矩阵 A(x1,x2) (b1,b2) Ax1 b1,Ax2 b2 XAB 如果A可逆,直接XB A − 1 A^-…

V90伺服PN版组态配置<一>

1、添加PLC之后&#xff0c;继续博图中网络视图中添加新设备&#xff0c;添加伺服驱动器组态设备 2、SINAMICS V90 PN V1.0 3、修改驱动器的IP地址。 【注意】 在项目中提前做好项目规划&#xff0c;如PLC设备从192.168.0.1开始&#xff0c;顺序递增------个位数都是CPU设备…

深度学习笔记(12)——深度学习概论

深度学习概论 深度学习关系&#xff1a; 为什么机器人有一部分不在人工智能里面&#xff1a;机器人技术是一个跨学科的领域&#xff0c;它结合了机械工程、电子工程、计算机科学以及人工智能&#xff08;AI&#xff09;等多个领域的知识。 并不是所有的机器人都依赖于人工智能…

TCP-UDP调试工具推荐:Socket通信测试教程(附详细图解)

前言 在网络编程与应用开发中&#xff0c;调试始终是一项不可忽视的重要环节。尤其是在涉及TCP/IP、UDP等底层网络通信协议时&#xff0c;如何确保数据能够准确无误地在不同节点间传输&#xff0c;是许多开发者关注的核心问题。 调试的难点不仅在于定位连接建立、数据流控制及…

使用three.js 实现vr全景图展示,复制即可用

1.实现效果 2.代码 1.npm安装three.js npm install three 2.引入three.js import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls 3.初始化模型 init(val) {this.container document.querySelector(.container)// 初始…

1月第二讲:WxPython跨平台开发框架之图标选择界面

1、图标分类介绍 这里图标我们分为两类&#xff0c;一类是wxPython内置的图标资源&#xff0c;以wx.Art_开始。wx.ART_ 是 wxPython 提供的艺术资源&#xff08;Art Resource&#xff09;常量&#xff0c;用于在界面中快速访问通用的图标或位图资源。这些资源可以通过 wx.ArtP…

C语言优化技巧--达夫设备(Duff‘s Device)解析

1983年&#xff0c;一位程序员TomDuff&#xff08;曾在贝尔实验室和星球大战母公司卢卡斯影业就职过&#xff09;&#xff0c;在参与图形渲染的软件中尝试优化图像数据传输到帧缓冲区的过程中遇到了性能瓶颈&#xff0c;写下了一段奇怪的代码&#xff1a; void send( int * to…