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

Dubbo加载配置文件方式,加载流程,加载配置文件源码解析

配置方法

API配置

以Java编码的方式组织配置,Dubbo3配置API详解 :https://dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/config/api/#bootstrap-api

public static void main(String[] args) throws IOException {ServiceConfig<GreetingsService> service = new ServiceConfig<>();service.setApplication(new ApplicationConfig("first-dubbo-provider"));service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));service.setInterface(GreetingsService.class);service.setRef(new GreetingsServiceImpl());service.export();System.out.println("first-dubbo-provider is running.");System.in.read();
}

xml配置

以XML方式配置各种组件,支持与Spring无缝集成

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder/><dubbo:application name="demo-provider"/><dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181"/><dubbo:provider token="true"/><bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/><dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/></beans>

Annotation 结合SpringBoot配置

以注解方式暴露服务和引用服务接口,支持与Spring无缝集成

  • 注解有 @DubboService、@DubboReference 与 @EnableDubbo。

其中 @DubboService 与 @DubboReference 用于标记 Dubbo 服务

@EnableDubbo 启动 Dubbo 相关配置并指定 Spring Boot 扫描包路径。

  • 配置文件 application.properties 或 application.yml

@Service@Reference注解从 3.0 版本开始就已经废弃,改用 @DubboService,@DubboReference,以区别于 Spring 的 @Service,@Reference 注解

@DubboService(version = "1.0.0", group = "dev", timeout = 5000,registry="zk-registry")
@DubboReference(version = "1.0.0", group = "dev", timeout = 5000)

注解中的参数有限,如果需要可以使用dubbo.properties 或者javaconfig代替,或者通过SpringBoot的配置文件结合

SpringBoot配置文件

spring.application.name=dubbo--provider-sample
dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service# Dubbo Application
## The default value of dubbo.application.name is ${spring.application.name}
## dubbo.application.name=${spring.application.name}# Dubbo Protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=12345## Dubbo Registry
dubbo.registry.address=N/A## DemoService version
demo.service.version=1.0.0

JavaConfig

JavaConfig即使用 @Bean的方式添加到Spring容器中

@Configuration
public class Configuration {@Beanpublic ServiceConfig demoService() {ServiceConfig service = new ServiceConfig();service.setInterface(DemoService.class);service.setRef(new DemoServiceImpl());service.setGroup("dev");service.setVersion("1.0.0");Map<String, String> parameters = new HashMap<>();service.setParameters(parameters);return service;}
}

dubbo.properties

参考

dubbo.service.org.apache.dubbo.springboot.demo.DemoService.timeout=5000
dubbo.service.org.apache.dubbo.springboot.demo.DemoService.parameters=[{myKey:myValue},{anotherKey:anotherValue}]
dubbo.reference.org.apache.dubbo.springboot.demo.DemoService.timeout=6000

配置加载流程

  • JVM System Properties,JVM -D 参数
  • System environment,JVM进程的环境变量
  • Externalized Configuration,外部化配置,从配置中心读取
  • Application Configuration,应用的属性配置,从Spring应用的Environment中提取"dubbo"打头的属性集
  • API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式
  • 从classpath读取配置文件 dubbo.properties

关于dubbo.properties属性:

  1. 如果在 classpath 下有超过一个 dubbo.properties 文件,比如,两个 jar 包都各自包含了 dubbo.properties,dubbo 将随机选择一个加载,并且打印错误日志。
  2. Dubbo 可以自动加载 classpath 根目录下的 dubbo.properties,但是你同样可以使用 JVM 参数来指定路径:-Ddubbo.properties.file=xxx.properties

常用配置组件如下

  • application: Dubbo应用配置
  • registry: 注册中心
  • protocol: 服务提供者RPC协议
  • config-center: 配置中心
  • metadata-report: 元数据中心
  • service: 服务提供者配置
  • reference: 远程服务引用配置
  • provider: service的默认配置或分组配置
  • consumer: reference的默认配置或分组配置
  • module: 模块配置
  • monitor: 监控配置
  • metrics: 指标配置
  • ssl: SSL/TLS配置

属性覆盖

发生属性覆盖可能有两种情况,并且二者可能是会同时发生的:

  1. 不同配置源配置了相同的配置项
  2. 相同配置源,但在不同层次指定了相同的配置项

不同配置源

按配置加载流程 从上到下覆盖, JVM -D 优先级最高,dubbo.properties 优先级最低

相同配置源

属性覆盖是指用配置的属性值覆盖config bean实例的属性,类似Spring PropertyOverrideConfigurer 的作用。

但与PropertyOverrideConfigurer的不同之处是,Dubbo的属性覆盖有多个匹配格式,优先级从高到低依次是:

#1. 指定id的实例级配置 dubbo.{config-type}s.{config-id}.{config-item}={config-item-value} 
#2. 指定name的实例级配置 dubbo.{config-type}s.{config-name}.{config-item}={config-item-value} 
#3. 应用级配置(单数配置) dubbo.{config-type}.{config-item}={config-item-value} 

属性覆盖处理流程:

按照优先级从高到低依次查找,如果找到此前缀开头的属性,则选定使用这个前缀提取属性,忽略后面的配置。

配置加载源码解析

DefaultApplicationDeployer#initialize()

@Override
public void initialize() {if (initialized) {return;}// Ensure that the initialization is completed when concurrent callssynchronized (startLock) {if (initialized) {return;}// register shutdown hookregisterShutdownHook();startConfigCenter();loadApplicationConfigs();initModuleDeployers();// @since 2.7.8startMetadataCenter();initialized = true;if (logger.isInfoEnabled()) {logger.info(getIdentifier() + " has been initialized!");}}
}

始化过程中会先启动配置中心配置信息处理,然后 调用加载初始化应用程序配置方法loadApplicationConfigs()进行配置加载

Dubbo框架的配置项比较繁多,为了更好地管理各种配置,将其按照用途划分为不同的组件,最终所有配置项都会汇聚到URL中,传递给后续处理模块。

配置信息的初始化回顾

在创建dubbo环境时,ModuleEnvironment环境信息 getApplicationModel().getModelEnvironment()获取对象时,使用spi扩展加载ModuleEnvironment,会触发 ExtensionLoader#initExtension ()

对象如下代码所示:

public ModuleEnvironment(ModuleModel moduleModel) {super(moduleModel);this.moduleModel = moduleModel;this.applicationDelegate = moduleModel.getApplicationModel().getModelEnvironment();
}@Override
public ModuleEnvironment getModelEnvironment() {if (moduleEnvironment == null) {moduleEnvironment = (ModuleEnvironment) this.getExtensionLoader(ModuleExt.class).getExtension(ModuleEnvironment.NAME);}return moduleEnvironment;
}private void initExtension(T instance) {if (instance instanceof Lifecycle) {Lifecycle lifecycle = (Lifecycle) instance;lifecycle.initialize();}}

属性加载

Environment中属性的初始化方法 initialize()

这个初始化方法对应ModuleEnvironment的父类型Environment中的初始化方法如下

@Override
public void initialize() throws IllegalStateException {if (initialized.compareAndSet(false, true)) {//加载在JVM或者环境变量指定的dubbo.properties配置文件 配置的key为dubbo.properties.file ,如果未指定则查找类路径下的dubbo.propertiesthis.propertiesConfiguration = new PropertiesConfiguration(scopeModel);//系统JVM参数的配置无需我们来加载到内存,系统已经加载好了放到了System中,我们只需System.getProperty(key)来调用this.systemConfiguration = new SystemConfiguration();//系统环境变量的配置,无需我们来加载到内存,系统已经加载好了放到了System中,我们只需System.getenv(key)来获取就可以this.environmentConfiguration = new EnvironmentConfiguration();//从远程配置中心的全局配置获取对应配置this.externalConfiguration = new InmemoryConfiguration("ExternalConfig");//从远程配置中心的应用配置获取对应配置this.appExternalConfiguration = new InmemoryConfiguration("AppExternalConfig");//应用内的配置比如:  Spring Environment/PropertySources/application.propertiesthis.appConfiguration = new InmemoryConfiguration("AppConfig");//加载迁移配置,用户在JVM参数或者环境变量中指定的dubbo.migration.file,如果用户未指定测尝试加载类路径下的dubbo-migration.yamlloadMigrationRule();}
}

dubbo.properties配置文件加载解析原理

如前面所示:

//加载在JVM或者环境变量指定的dubbo.properties配置文件 配置的key为dubbo.properties.file ,如果未指定则查找类路径下的dubbo.properties
this.propertiesConfiguration = new PropertiesConfiguration(scopeModel);

下面就直接提构造器的PropertiesConfiguration代码了:

public PropertiesConfiguration(ScopeModel scopeModel) {this.scopeModel = scopeModel;refresh();}public void refresh() {//配置获取的过程是借助工具类ConfigUtils来获取的properties = ConfigUtils.getProperties(scopeModel.getClassLoaders());}

继续看ConfigUtils的getProperties方法:

public static Properties getProperties(Set<ClassLoader> classLoaders) {//这个配置的KEY是dubbo.properties.file System.getProperty是从JVM参数中获取配置的 一般情况下我们在启动Java进程的时候会指定Dubbo配置文件 如配置://-Ddubbo.properties.file=/dubbo.propertiesString path = System.getProperty(CommonConstants.DUBBO_PROPERTIES_KEY);if (StringUtils.isEmpty(path)) {//优先级最高的JVM参数拿不到数据则从 环境变量中获取,这个配置key也是dubbo.properties.file  System.getenv是从环境变量中获取数据//例如我们在环境变量中配置 dubbo.properties.file=/dubbo.propertiespath = System.getenv(CommonConstants.DUBBO_PROPERTIES_KEY);if (StringUtils.isEmpty(path)) {//如果在JVM参数和环境变量都拿不到这个配置文件的路径我们就用默认的吧//默认的路径是类路径下的资源文件 这个路径是: dubbo.properties path = CommonConstants.DEFAULT_DUBBO_PROPERTIES;}}return ConfigUtils.loadProperties(classLoaders, path, false, true);}

路径获取之后加载详细的配置内容:

ConfigUtils的loadProperties代码如下:

ConfigUtils.loadProperties(classLoaders, path, false, true);

代码如下:

public static Properties loadProperties(Set<ClassLoader> classLoaders, String fileName, boolean allowMultiFile, boolean optional) {Properties properties = new Properties();// add scene judgement in windows environment Fix 2557//检查文件是否存在 直接加载配置文件如果加载到了配置文件则直接返回if (checkFileNameExist(fileName)) {try {FileInputStream input = new FileInputStream(fileName);try {properties.load(input);} finally {input.close();}} catch (Throwable e) {logger.warn("Failed to load " + fileName + " file from " + fileName + "(ignore this file): " + e.getMessage(), e);}return properties;}//为什么会有下面的逻辑呢,如果仅仅使用上面的加载方式只能加载到本系统下的配置文件,无法加载封装在jar中的根路径的配置Set<java.net.URL> set = null;try {List<ClassLoader> classLoadersToLoad = new LinkedList<>();classLoadersToLoad.add(ClassUtils.getClassLoader());classLoadersToLoad.addAll(classLoaders);//这个方法loadResources在扩展加载的时候说过set = ClassLoaderResourceLoader.loadResources(fileName, classLoadersToLoad).values().stream().reduce(new LinkedHashSet<>(), (a, i) -> {a.addAll(i);return a;});} catch (Throwable t) {logger.warn("Fail to load " + fileName + " file: " + t.getMessage(), t);}if (CollectionUtils.isEmpty(set)) {if (!optional) {logger.warn("No " + fileName + " found on the class path.");}return properties;}if (!allowMultiFile) {if (set.size() > 1) {String errMsg = String.format("only 1 %s file is expected, but %d dubbo.properties files found on class path: %s",fileName, set.size(), set);logger.warn(errMsg);}// fall back to use method getResourceAsStreamtry {properties.load(ClassUtils.getClassLoader().getResourceAsStream(fileName));} catch (Throwable e) {logger.warn("Failed to load " + fileName + " file from " + fileName + "(ignore this file): " + e.getMessage(), e);}return properties;}logger.info("load " + fileName + " properties file from " + set);for (java.net.URL url : set) {try {Properties p = new Properties();InputStream input = url.openStream();if (input != null) {try {p.load(input);properties.putAll(p);} finally {try {input.close();} catch (Throwable t) {}}}} catch (Throwable e) {logger.warn("Fail to load " + fileName + " file from " + url + "(ignore this file): " + e.getMessage(), e);}}return properties;}

完整的配置加载流程这里用简单的话描述下:

  • 项目内配置查询

    • 路径查询
      • 从JVM参数中获取配置的 dubbo.properties.file配置文件路径
      • 如果前面未获取到路径则从环境变量参数中获取配置的dubbo.properties.file配置文件路径
      • 如果前面未获取到路径则使用默认路径dubbo.propertie
    • 配置加载
      • 将路径转为FileInputStream 然后使用Properties加载
  • 依赖中的配置扫描查询

    • 使用类加载器扫描所有资源URL
    • url转InputStream 如 url.openStream() 然后使用Properties加载

加载JVM参数的配置

这里我们继续看SystemConfiguration配置的加载 这个直接看下代码就可以了:

这个类型仅仅是使用System.getProperty来获取JVM配置即可

 public class SystemConfiguration implements Configuration {@Overridepublic Object getInternalProperty(String key) {return System.getProperty(key);}public Map<String, String> getProperties() {return (Map) System.getProperties();}
}

加载环境变量参数的配置

这里我们来看EnvironmentConfiguration

public class EnvironmentConfiguration implements Configuration {@Overridepublic Object getInternalProperty(String key) {String value = System.getenv(key);if (StringUtils.isEmpty(value)) {value = System.getenv(StringUtils.toOSStyleKey(key));}return value;}public Map<String, String> getProperties() {return System.getenv();}
}

内存配置的封装:InmemoryConfiguration

这里我们看下InmemoryConfiguration的设计,这个直接看代码吧内部使用了一个LinkedHashMap来存储配置

public class InmemoryConfiguration implements Configuration {private String name;// stores the configuration key-value pairsprivate Map<String, String> store = new LinkedHashMap<>();public InmemoryConfiguration() {}public InmemoryConfiguration(String name) {this.name = name;}public InmemoryConfiguration(Map<String, String> properties) {this.setProperties(properties);}@Overridepublic Object getInternalProperty(String key) {return store.get(key);}/*** Add one property into the store, the previous value will be replaced if the key exists*/public void addProperty(String key, String value) {store.put(key, value);}/*** Add a set of properties into the store*/public void addProperties(Map<String, String> properties) {if (properties != null) {this.store.putAll(properties);}}/*** set store*/public void setProperties(Map<String, String> properties) {if (properties != null) {this.store = properties;}}public Map<String, String> getProperties() {return store;}}

Dubbo迁移新版本的配置文件加载dubbo-migration.yaml

这个配置文件的文件名字为:dubbo-migration.yaml

  private void loadMigrationRule() {//JVM参数的dubbo.migration.file配置String path = System.getProperty(CommonConstants.DUBBO_MIGRATION_KEY);if (StringUtils.isEmpty(path)) {//环境变量的dubbo.migration.file配置path = System.getenv(CommonConstants.DUBBO_MIGRATION_KEY);if (StringUtils.isEmpty(path)) {//默认的迁移配置文件 dubbo-migration.yamlpath = CommonConstants.DEFAULT_DUBBO_MIGRATION_FILE;}}this.localMigrationRule = ConfigUtils.loadMigrationRule(scopeModel.getClassLoaders(), path);}

初始化加载应用配置

加载配置涉及到了配置优先级的处理,

下面来看加载配置代码 loadApplicationConfigs()方法

private void loadApplicationConfigs() {//发布器还是不处理配置加载的逻辑还是交给配置管理器configManager.loadConfigs();
}

配置管理器加载配置:

 @Overridepublic void loadConfigs() {// application config has load before starting config center// load dubbo.applications.xxx//加载应用配置loadConfigsOfTypeFromProps(ApplicationConfig.class);// load dubbo.monitors.xxx//加载监控配置loadConfigsOfTypeFromProps(MonitorConfig.class);// load dubbo.metrics.xxx//加载指标监控配置loadConfigsOfTypeFromProps(MetricsConfig.class);// load multiple config types:// load dubbo.protocols.xxx//加载协议配置loadConfigsOfTypeFromProps(ProtocolConfig.class);// load dubbo.registries.xxxloadConfigsOfTypeFromProps(RegistryConfig.class);// load dubbo.metadata-report.xxx//加载元数据配置loadConfigsOfTypeFromProps(MetadataReportConfig.class);// config centers has bean loaded before starting config center//loadConfigsOfTypeFromProps(ConfigCenterConfig.class);//刷新配置refreshAll();//检查配置checkConfigs();// set model nameif (StringUtils.isBlank(applicationModel.getModelName())) {applicationModel.setModelName(applicationModel.getApplicationName());}}

相关文章:

Dubbo加载配置文件方式,加载流程,加载配置文件源码解析

配置方法 API配置 以Java编码的方式组织配置&#xff0c;Dubbo3配置API详解 &#xff1a;https://dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/config/api/#bootstrap-api public static void main(String[] args) throws IOException {ServiceConfig<Greet…...

十大开源测试工具和框架,一定有你需要的

目录 前言 Katalon Studio Selenium Appium JMeter SOAP UI Robot Framework Watir JUnit Robotium Citrus 总结 前言 免费的开源框架和工具由于其开源特性&#xff0c;现在逐渐成为自动化测试的首选解决方案。区别在于&#xff0c;你是喜欢使用类库编写一个全新的…...

加密技术在android中的应用

1、算法基础 算法基础参照linux的全盘加密与文件系统加密在android中的应用 消息摘要算法 对称加密算法 非对称加密算法...

备战蓝桥杯【一维前缀和】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

研报精选230214

目录 【行业230214艾瑞股份】中国增强现实&#xff08;AR&#xff09;行业研究报告【行业230214国信证券】信息安全深度剖析5&#xff1a;密评和信创双催化&#xff0c;密码产业开启从1到N【行业230214民生证券】磁性元器件深度报告&#xff1a;乘新能源之风&#xff0c;磁性元…...

【SSL/TLS】准备工作:证书格式

证书格式1. 格式说明1.1 文件编码格式1.2 文件后缀格式2. xca导出格式1. 格式说明 1.1 文件编码格式 1. PEM格式: 使用Base 64 ASCII进行编码的纯文本格式。后缀为“.pem”, ".cer", ".crt", ".key" 2. DER格式 二进制编码格式&#xff0c;文件…...

Linux常用命令---系统常用命令

Linux系统常用命令场景一&#xff1a; 查看当前系统内核版本相关信息场景二&#xff1a; sosreport 命令场景三&#xff1a; 如何定位并确定命令&#xff1f;场景四&#xff1a;查看当前系统运行负载怎场景五&#xff1a; 查看当前系统的内存可用情况场景六&#xff1a;查看网卡…...

C 结构体

C 数组允许定义可存储相同类型数据项的变量&#xff0c;结构是 C 编程中另一种用户自定义的可用的数据类型&#xff0c;它允许您存储不同类型的数据项。结构用于表示一条记录&#xff0c;假设您想要跟踪图书馆中书本的动态&#xff0c;您可能需要跟踪每本书的下列属性&#xff…...

手语检测识别

论文&#xff1a;Real-Time Sign Language Detection using Human Pose Estimation Github&#xff1a;https://github.com/google-research/google-research/tree/master/sign_language_detection SLRTP 2020 手语识别任务包括手语检测&#xff08;Sign language detection&a…...

android fwk模块之Sensor架构

本文基于Android 12源码整理&#xff0c;包含如下内容&#xff1a; 通信架构应用层实现使用方式SensorManager抽象接口具体实现fwk层的实现native中的SensorManager的初始化流程native中的消息队列初始化与数据读取sensorservice实现HAL层的实现通信架构 应用层实现 涉及代码&…...

安装less-loader5出现webpack版本不兼容

今天遇到一个问题&#xff1a; 安装less-loader5之后其它包提示peerDependencies WARNING&#xff0c;意思是包版本不兼容。 【难题】 虽然NPM已经很自动化了&#xff0c;但依赖问题真的是一个难题&#xff0c;无法自动解决&#xff0c;需要人工干预调整。 【解决办法】 去查…...

Java 网络编程

1.UDP和TCPUDP和TCP是传输层协议中最核心的两种协议他们的特点分别是UDP: 无连接,不可靠传输,面向数据报,全双工TCP: 有连接,是可靠传输,面向字节流,全双工有无连接有连接:就好比两个人打电话,打电话的一方发出连接请求,被打电话的一方选择确认连接,此时双方才能进行通话无连接…...

BEV学习记录

近期可能要经常性的开展BEV工作&#xff0c;打算把自己觉着不错的网站拿出来记录一下。 首先贴上来我还没有细读的一篇觉着不错的文章。 自动驾驶感知新范式——BEV感知经典论文总结和对比&#xff08;上&#xff09;_苹果姐的博客-CSDN博客_bev视角 开山之作--LSS ECCV 202…...

Webrtc Native C++切换音频输入源

modules/audio_device/audio_device_impl.cc #include “api/audio_options.h” #include “modules/audio_device/include/factory.h” // 创建一个 AudioDeviceModule 对象 auto audio_device_module = webrtc::AudioDeviceModule::Create( webrtc::AudioDeviceModule::kPl…...

裸辞5个月,面试了37家公司,终于找到理想工作了

上半年裁员&#xff0c;下半年裸辞&#xff0c;有不少人高呼裸辞后躺平真的好快乐&#xff01;但也有很多人&#xff0c;裸辞后的生活五味杂陈。 面试37次终于找到心仪工作 因为工作压力大、领导PUA等各种原因&#xff0c;今年2月下旬我从一家互联网小厂裸辞&#xff0c;没想…...

Mybatis-plus@DS实现动态切换数据源应用

目录1 DS实现动态切换数据源原理2 不可在事务中切换数据库分析解决3 原因解析1 DS实现动态切换数据源原理 首先mybatis-plus使用com.baomidou.dynamic.datasource.AbstractRoutingDataSource继承 AbstractDataSource接管数据源&#xff1b;具体实现类为com.baomidou.dynamic.d…...

SpringBoot的创建和使用

SpringBoot是什么&#xff1f;SpringBoot诞生的目的就是为了简化Spring开发&#xff0c;而相对于Spring&#xff0c;SpringBoot算是一个很大的升级&#xff0c;就如同汽车手动挡变成了自动挡。Spring&#xff1a;SpringBoot&#xff1a;SpringBoot的优点SpringBoot让Spring开发…...

居家电话客服宝典

客服分类从销售的流程来分&#xff0c;客服分为售前和售后。售前一般都带有销售性质&#xff0c;工资主要靠提成&#xff0c;售后一般是解答问题&#xff0c;工资主要看服务质量和差评量。从工作模式来分&#xff0c;客服分为在线客服和热线客服。在线客服以打字聊天为主&#…...

开发方案设计

1、开发流程产品需求设计-->需求粗评-->做设计方案-->粗估时-->需求细评-->排期-->开发-->提测、修bug-->code review-->上线设计方案主要是写实现思路、模块划分code review&#xff1a;完善代码&#xff0c;发现未考虑到的边界问题2、具体实现方案…...

文件路径模块pathlib

文件路径模块pathlib 文章目录文件路径模块pathlib1.概述2.创建路径2.1.创建非windos平台路径2.2.动态拼接路径joinpath2.3.替换文件名称 with_name2.4.创建固定目录2.5.创建文件夹和文件1.创建多级目录mkdir2.创建空文件3.路径解析3.1.根据路径分隔符解析路径parts3.2.获取父级…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...