Maven Dependency 机制
依赖关系管理是Maven的核心功能。管理单个项目的依赖关系很容易。管理由数百个模块组成的多模块项目和应用程序的依赖关系是可能的。Maven在定义、创建和维护具有良好定义的类路径和库版本的可复制构建方面有很大帮助。
一、传递依赖
Maven通过自动包含可传递的依赖关系,避免了发现和指定您自己的依赖关系所需的库的需要。
通过从指定的远程存储库中读取依赖项的项目文件,可以实现此功能。通常,这些项目的所有依赖项都会在项目中使用,项目从其父项或依赖项继承的任何依赖项也是如此,依此类推。
可以从中收集依赖关系的级别数量没有限制。只有当发现循环依赖关系时,才会出现问题。
有了可传递的依赖关系,包含库的图可以很快变大。因此,还有一些附加功能限制了所包含的依赖项:
- 依赖项中介 - 这决定了在遇到多个版本作为依赖项时将选择哪个版本的项目。Maven选择了“最接近的定义”。也就是说,它使用依赖项树中与项目最近的依赖项的版本。您始终可以通过在项目的 POM 中显式声明版本来保证版本。请注意,如果两个依赖项版本在依赖项树中的深度相同,则第一个声明优先。
- “最接近的定义”意味着使用的版本将是依赖项树中与您的项目最接近的版本。考虑以下依赖树:
A├── B│ └── C│ └── D 2.0└── E└── D 1.0
在文本中,A、B和C的依赖项定义为A->B->C->D2.0和A->E->D1.0,然后在构建A时将使用D1.0,因为从A到D通过E的路径更短。您可以在a中显式地向D2.0添加依赖项,以强制使用D2.0,如下所示:
A├── B│ └── C│ └── D 2.0├── E│ └── D 1.0│└── D 2.0
- 依赖项管理-这允许项目作者在传递依赖项或未指定版本的依赖项中遇到工件时,直接指定要使用的工件版本。在上一节的例子中,一个依赖项被直接添加到a中,尽管a没有直接使用它。相反,a可以将D作为依赖项包含在其dependencyManagement部分中,并直接控制在何时或是否引用它时使用D的哪个版本。
- 依赖关系范围-这允许您只包括适用于构建的当前阶段的依赖关系。下面将对此进行更详细的描述。
- 排除的依赖项-如果项目X依赖于项目Y,而项目Y依赖于项目Z,则项目X的所有者可以使用“排除”元素将项目Z明确排除为依赖项。
- 可选依赖项-如果项目Y依赖于项目Z,则项目Y的所有者可以使用“可选”元素将项目Z标记为可选依赖项。当项目X依赖于项目Y时,X将仅依赖于Y,而不依赖于Y的可选依赖项Z。然后,项目X的所有者可以根据自己的选择显式添加对Z的依赖项。(将可选依赖项视为“默认排除”可能会有所帮助)
尽管可传递依赖项可以隐式地包括所需的依赖项,但显式指定源代码直接使用的依赖项是一种很好的做法。这种最佳实践证明了它的价值,尤其是当项目的依赖关系改变了它们的依赖关系时。
例如,假设您的项目A指定了对另一个项目B的依赖项,而项目B指定了对项目C的依赖项。如果您直接在项目C中使用组件,而您没有在项目A中指定项目C,则当项目B突然更新/删除其对项目C的依赖时,可能会导致生成失败。
直接指定依赖项的另一个原因是它为您的项目提供了更好的文档:只需读取项目中的POM文件,或者执行mvn-dependency:tree,就可以了解更多信息。
Maven还提供了dependency:analyze插件分析依赖关系的目标:这有助于使这种最佳实践更容易实现。
二、依赖范围
依赖关系范围用于限制依赖关系的传递性,并确定依赖关系何时包含在类路径中。
共有6个作用域:
- compile
这是默认范围,如果未指定,则使用。编译依赖项在项目的所有类路径中都可用。此外,这些依赖项将传播到依赖项目。
- provided
这很像编译,但表示您希望JDK或容器在运行时提供依赖关系。例如,当为Java Enterprise Edition构建web应用程序时,您需要将对Servlet API和相关Java EE API的依赖设置为所提供的范围,因为web容器提供了这些类。具有此作用域的依赖项被添加到用于编译和测试的类路径中,但不添加到运行时类路径中。它不可传递。
- runtime
此范围表示编译不需要依赖项,而是执行依赖项。Maven在运行时和测试类路径中包含一个具有此作用域的依赖项,但不包括编译类路径。
- test
此范围表示应用程序的正常使用不需要依赖项,仅适用于测试编译和执行阶段。此范围不可传递。通常,这个范围用于JUnit和Mockito等测试库。它也用于非测试库,如Apache Commons IO,如果这些库用于单元测试(src/test/java),但不用于模型代码(src/main/java)。
- system
这个作用域与提供的作用域类似,只是您必须提供显式包含它的JAR。工件总是可用的,并且不会在存储库中查找。
- import
只有<dependencyManagement>部分中pom类型的依赖项才支持此作用域。它指示依赖项将被指定POM的<dependencyManagement>部分中的有效依赖项列表所取代。由于它们被替换,具有导入范围的依赖项实际上并没有参与限制依赖项的传递性。
每个作用域(导入除外)都以不同的方式影响可传递的依赖项,如下表所示。如果将依赖项设置为左列中的作用域,则该依赖项与顶行中作用域的可传递依赖项将导致主项目中的依赖项与交叉点处列出的作用域。如果没有列出作用域,则表示省略了依赖项。
| compile | provided | runtime | test | |
| compile | compile(*) | - | runtime | - |
| provided | provided | - | provided | - |
| runtime | runtime | - | runtime | - |
| test | test | - | test | - |
(*)注意:这应该是运行时范围,因此必须显式列出所有编译依赖项。但是,如果您所依赖的库从另一个库扩展了一个类,则两者在编译时都必须可用。由于这个原因,编译时依赖关系仍然是编译范围,即使它们是可传递的。
三、依赖关系管理
依赖关系管理部分是一种用于集中依赖关系信息的机制。当您有一组从公共父级继承的项目时,可以将有关依赖项的所有信息放在公共 POM 中,并对子 POM 中的项目进行更简单的引用。通过一些例子可以最好地说明这种机制。给定扩展同一父级的这两个 POM:
项目A:
<project>...<dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId><version>1.0</version><exclusions><exclusion><groupId>group-c</groupId><artifactId>excluded-artifact</artifactId></exclusion></exclusions></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies>
</project>
项目B:
<project>...<dependencies><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>war</type><scope>runtime</scope></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies>
</project>
这两个示例 POM 共享一个共同的依赖项,并且每个都有一个非平凡的依赖项。此信息可以像这样放入父 POM 中:
<project>...<dependencyManagement><dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId><version>1.0</version><exclusions><exclusion><groupId>group-c</groupId><artifactId>excluded-artifact</artifactId></exclusion></exclusions></dependency><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>war</type><scope>runtime</scope></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies></dependencyManagement>
</project>
然后,两个子 POM 变得更加简单:
<project>...<dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>bar</type></dependency></dependencies>
</project>
<project>...<dependencies><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>war</type></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><!-- This is not a jar dependency, so we must specify type. --><type>bar</type></dependency></dependencies>
</project>
注意:在其中两个依赖引用中,我们必须指定<type/>元素。这是因为用于将依赖引用与dependencyManagement节匹配的最小信息集实际上是{groupId,artifactId,type,classifier}。在许多情况下,这些依赖关系将引用没有分类器的jar工件。这允许我们将标识集简写为{groupId,artifactId},因为类型字段的默认值是jar,而默认分类器是null。
依赖关系管理部分的第二个也是非常重要的用途是控制可传递依赖关系中使用的工件的版本。以这些项目为例:
项目A:
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>A</artifactId><packaging>pom</packaging><name>A</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>a</artifactId><version>1.2</version></dependency><dependency><groupId>test</groupId><artifactId>b</artifactId><version>1.0</version><scope>compile</scope></dependency><dependency><groupId>test</groupId><artifactId>c</artifactId><version>1.0</version><scope>compile</scope></dependency><dependency><groupId>test</groupId><artifactId>d</artifactId><version>1.2</version></dependency></dependencies></dependencyManagement>
</project>
项目B:
<project><parent><artifactId>A</artifactId><groupId>maven</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>B</artifactId><packaging>pom</packaging><name>B</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>d</artifactId><version>1.0</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>a</artifactId><version>1.0</version><scope>runtime</scope></dependency><dependency><groupId>test</groupId><artifactId>c</artifactId><scope>runtime</scope></dependency></dependencies>
</project>
当maven在项目B上运行时,无论POM中指定的版本是什么,都将使用工件a、B、c和d的1.0版本。
- a和c都被声明为项目的依赖项,因此由于依赖项中介,使用1.0版本。两者都有运行时作用域,因为它是直接指定的。
- b是在b的父级依赖关系管理部分中定义的,由于对于可传递依赖关系,依赖关系管理优先于依赖关系中介,因此如果在a或c的POM中引用它,将选择1.0版本。b也将具有编译范围。
- 最后,由于d是在B的依赖关系管理部分中指定的,如果d是a或c的依赖关系(或传递依赖关系),则将选择1.0版本,这也是因为依赖关系管理优先于依赖关系中介,也因为当前POM的声明优先于其父声明。
有关依赖项管理标记的引用信息可从项目描述符引用中获得。
四、正在导入依赖项
上一节中的示例描述了如何通过继承指定托管依赖项。然而,在较大的项目中,这可能是不可能实现的,因为一个项目只能从单亲继承。为了适应这种情况,项目可以从其他项目导入托管依赖项。这是通过将POM工件声明为范围为“import”的依赖项来实现的。
Project B:
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>B</artifactId><packaging>pom</packaging><name>B</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>maven</groupId><artifactId>A</artifactId><version>1.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>test</groupId><artifactId>d</artifactId><version>1.0</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>a</artifactId><version>1.0</version><scope>runtime</scope></dependency><dependency><groupId>test</groupId><artifactId>c</artifactId><scope>runtime</scope></dependency></dependencies>
</project>
假设A是前面例子中定义的POM,那么最终结果将是相同的。A的所有托管依赖项都将被合并到B中,除了d,因为它是在这个POM中定义的。
Project X:
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>X</artifactId><packaging>pom</packaging><name>X</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>a</artifactId><version>1.1</version></dependency><dependency><groupId>test</groupId><artifactId>b</artifactId><version>1.0</version><scope>compile</scope></dependency></dependencies></dependencyManagement>
</project>
Project Y:
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>Y</artifactId><packaging>pom</packaging><name>Y</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>test</groupId><artifactId>a</artifactId><version>1.2</version></dependency><dependency><groupId>test</groupId><artifactId>c</artifactId><version>1.0</version><scope>compile</scope></dependency></dependencies></dependencyManagement>
</project>
Project Z:
<project><modelVersion>4.0.0</modelVersion><groupId>maven</groupId><artifactId>Z</artifactId><packaging>pom</packaging><name>Z</name><version>1.0</version><dependencyManagement><dependencies><dependency><groupId>maven</groupId><artifactId>X</artifactId><version>1.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>maven</groupId><artifactId>Y</artifactId><version>1.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>
在上面的示例中,Z从X和Y导入托管依赖项。然而,X和Y都包含依赖项a。这里,将使用a的1.1版本,因为X是首先声明的,而a不是在Z的dependencyManagement中声明的。
这个过程是递归的。例如,如果X导入另一个POM Q,那么当Z被处理时,它将简单地显示出Q的所有托管依赖项都是在X中定义的。
五、BOM表POM
当用于定义通常是多项目构建的一部分的相关工件的“库”时,导入最有效。一个项目使用这些库中的一个或多个工件是相当常见的。然而,有时很难使用工件来保持项目中的版本与库中分发的版本同步。下面的模式说明了如何创建“BOM表”(BOM)以供其他项目使用。
项目的根是BOM POM。它定义了将在库中创建的所有工件的版本。其他希望使用库的项目应该将此POM导入其POM的dependencyManagement部分。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>bom</artifactId><version>1.0.0</version><packaging>pom</packaging><properties><project1Version>1.0.0</project1Version><project2Version>1.0.0</project2Version></properties><dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>project1</artifactId><version>${project1Version}</version></dependency><dependency><groupId>com.test</groupId><artifactId>project2</artifactId><version>${project2Version}</version></dependency></dependencies></dependencyManagement><modules><module>parent</module></modules>
</project>
父子项目将BOM POM作为其父项目。这是一个正常的多项目pom。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><version>1.0.0</version><artifactId>bom</artifactId></parent><groupId>com.test</groupId><artifactId>parent</artifactId><version>1.0.0</version><packaging>pom</packaging><dependencyManagement><dependencies><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency></dependencies></dependencyManagement><modules><module>project1</module><module>project2</module></modules>
</project>
接下来是实际的项目POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><version>1.0.0</version><artifactId>parent</artifactId></parent><groupId>com.test</groupId><artifactId>project1</artifactId><version>${project1Version}</version><packaging>jar</packaging><dependencies><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId></dependency></dependencies>
</project><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.test</groupId><version>1.0.0</version><artifactId>parent</artifactId></parent><groupId>com.test</groupId><artifactId>project2</artifactId><version>${project2Version}</version><packaging>jar</packaging><dependencies><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></dependency></dependencies>
</project>
下面的项目显示了现在如何在另一个项目中使用库,而不必指定依赖项目的版本:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>use</artifactId><version>1.0.0</version><packaging>jar</packaging><dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>bom</artifactId><version>1.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>project1</artifactId></dependency><dependency><groupId>com.test</groupId><artifactId>project2</artifactId></dependency></dependencies>
</project>
最后,在创建导入依赖项的项目时,请注意以下事项:
- 请勿尝试导入在当前POM的子模块中定义的POM。尝试这样做将导致构建失败,因为它将无法定位POM。
- 切勿将导入POM的POM声明为目标POM的父级(或祖级等)。无法解析循环,将引发异常。
- 当引用其POM具有可传递依赖性的工件时,项目需要将这些工件的版本指定为托管依赖性。不这样做会导致生成失败,因为工件可能没有指定版本。(在任何情况下,这都应该被视为最佳实践,因为它防止工件的版本从一个构建更改到下一个构建)。
从Maven4.0开始,引入了一种新的特定BOM打包。它允许定义一个BOM表,该BOM表在利用较新的4.1.0模型的项目中不用作父级,同时仍然提供与Maven 3.X客户端和项目的完全兼容性。在安装/部署时,利用Maven 4的构建/消费者POM功能,将此BOM打包转换为更常见的POM打包。因此,这提供了与Maven 3.x的完全兼容性。
<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd"><parent><groupId>com.test</groupId><version>1.0.0</version><artifactId>parent</artifactId></parent><groupId>com.test</groupId><artifactId>bom</artifactId><version>1.0.0</version><packaging>bom</packaging><properties><project1Version>1.0.0</project1Version><project2Version>1.0.0</project2Version></properties><dependencyManagement><dependencies><dependency><groupId>com.test</groupId><artifactId>project1</artifactId><version>${project1Version}</version></dependency><dependency><groupId>com.test</groupId><artifactId>project2</artifactId><version>${project2Version}</version></dependency></dependencies></dependencyManagement></project>相关文章:
Maven Dependency 机制
依赖关系管理是Maven的核心功能。管理单个项目的依赖关系很容易。管理由数百个模块组成的多模块项目和应用程序的依赖关系是可能的。Maven在定义、创建和维护具有良好定义的类路径和库版本的可复制构建方面有很大帮助。 一、传递依赖 Maven通过自动包含可传递的依赖关系&…...
CustomShapes/自定义形状, CustomCurves/自定义曲线, AnimateableData/数据变化动画 的使用
1. CustomShapes 自定义形状视图 1.1 资源图文件 therock.png 1.2 创建自定义形状视图 CustomShapesBootcamp.swift import SwiftUI/// 三角形 struct Triangle: Shape{func path(in rect: CGRect) -> Path {Path { path inpath.move(to: CGPoint(x: rect.midX, y: rect.mi…...
软件测试用例设计方法-因果图法
边界值法是等价类划分法的补充,所以,它们是一对搭档。 那么,判定表法有没有它的搭档呢? 答案是,有的。那就是本篇文章分享的用例设计方法—— 因果图法 。 定义 因果图法: 用来处理等价类划分和边界值考…...
水库大坝安全监测是什么和主要作用?
水库大坝安全监测是指通过仪器观测和巡视检查对水利水电工程主体结构、地基基础、两岸边坡、相关设施以及周围环境所作的测量及观察。大坝安全监测是作为水库大坝安全管理的重要组成部分,是掌握水库大坝安全性态的重要手段,是科学调度、安全运行的前提。…...
极品三国新手攻略之进阶篇
尊敬的主公大人您好,首先恭喜您在游戏中取得的不俗成绩,相信您已经熟练掌握了不少玩法。今天,我们给大家奉上一份极品三国新手攻略之进阶篇,希望能为您提供有力的帮助。本篇攻略将为您深入分析游戏中武将、装备、试炼塔以及神兵等…...
windows应用程序告警:帐户名与安全标识间无任何映射完成
目录 一、问题现象 二、问题解决 (一)官方方法 (二)问题定位 (三)问题处理 一、问题现象 今天巡检域控服务器时,发现告警如下: 安全策略已传播,但有警告信息。 0x534…...
自定义jenkins镜像提示FontConfiguration.head错误
系统使用:Debian12,jdk17 提示问题:缺少字体 找一台jdk8的环境,在lib文件夹中找到fontconfig.bfc find / -name *fontconfig* 复制到jenkins目标服务器中,jdk目录的lib中 再次启动jenkins服务正常...
《软件方法》2023版第1章(10)应用UML的建模工作流-大图
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 1.4 应用UML的建模工作流 1.4.1 概念 我用类图表示建模工作流相关概念如图1-16。 图1-16 建模工作流相关概念 图1-16左侧灰色部分定义了“游戏规则”,右侧则是在“游戏规…...
The given SOAPAction http__xxxxx_xx does not match an operation
这是在客户端调用服务端接口时报出的错误,主要是客户端在调用时设置了SOAPAction,参考如下: 解决方案 在注解WebMethod() 中加上action注解,设置上一模一样的SOAPAction即可,如下: WebMethod(action &qu…...
【java零基础入门到就业】第二天:jdk的下载安装和第一个HelloWorld程序
1、java内容概述 java前半部分学习内容主要如下: 1、Java基础语法2、面向对象3、API4、字符串5、集合6、拼图游戏 1.1、 java基础语法 java基础语法主要包括以下内容: Java入门小概念Idea和运算符判断和循环方法数组课后练习题 Java是什么…...
C++数据结构X篇_15_求二叉树叶子数与高度(递归方法)
本篇参考求二叉树叶子数与高度(C)进行整理。 文章目录 1. 二叉树中叶子数与高度2. 求二叉树叶子数与高度的实现代码 1. 二叉树中叶子数与高度 我们首先来看一看二叉树中叶子数与高度的定义: 叶子数:对于一个二叉树的节点&#x…...
MySQL锁学习笔记
锁 事务的隔离性由锁来实现。 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在程序开发中会存在多线程同步的问题,当多个线程并发访问某个数据的时候,尤其是针对一些敏感的数据(比如订单、金额等),我…...
如何将前后端分离项目部署到本地的Docker Desktop容器运行并且访问
文章目录 前言 完成了客户的一个前后端分离项目,要求部署到客户电脑上去展示,那肯定不能直接把代码弄上去跑呀~~~,于是我就想把他们都打包部署到本地的docker容器里面,方便运行和访问,so,以下内容就详细介…...
前端开发中的try...catch
首先try...catch 结构可以用来处理 Promise 中的异常。在 JavaScript 中,Promise 提供了一种处理异步操作的机制,并且可以通过 .catch() 方法捕获并处理异步操作中抛出的异常。 async function someAsyncFunction() {try {const result await someProm…...
数据加密中,采用密钥管理系统相比加密机的好处
密钥管理系统与加密机都能提供数据加解密,那么针对具体的应用加密,采用密钥管理系统比单纯使用加密机有哪些优点,列表如下: 集中化管理:密钥管理系统可以对加密算法和密钥进行集中化管理,使得企业可以对加…...
Elasticsearch:什么是大语言模型 (LLMs)?
假设你想参加流行的游戏节目 Jeopardy(这是一个美国电视游戏节目,参赛者将获得答案并必须猜测问题)。 要参加演出,你需要了解任何事情的一切。 所以你决定在接下来的三年里每天都花时间阅读互联网上的所有内容。 你很快就会意识到…...
神奇的python的生成器
函数生成器代码 def num():print("message 1")yield 1print("message 2")yield 2print("message 3")yield 3f num() x next(f) # message 1 print(x) # 输出1x next(f) # message 2 print(x) # 输出2x next(f) # message 3 print(x) …...
【来点小剧场--项目测试报告】个人博客项目自动化测试
前述 针对个人博客项目进行测试,个人博客主要由七个页面构成:注册页、登录页、个人博客列表页、博客发布页、博客修改页、博客列表页、博客详情页,主要功能包括:注册、登录、编辑并发布博客、修改已发布的博客、查看详情、删除博…...
【安卓环境搭建报错的解决】
安卓环境搭建报错的解决 问题描述解决方法 问题描述 电脑中新安装的 Android Studio Giraffe | 2022.3.1 Patch ,运行 studio 系统工程,提示如下错误 Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.…...
Pruning Pre-trained Language Models Without Fine-Tuning
本文是LLM系列文章,针对《Pruning Pre-trained Language Models Without Fine-Tuning》的翻译。 修剪未微调的预训练语言模型 摘要1 引言2 相关工作3 背景4 静态模型剪枝5 实验6 分析7 结论8 局限性 摘要 为了克服预训练语言模型(PLMs)中的过度参数化问题…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
