耗时二周,万字总结Maven简明教程,与君共勉!

news/2024/4/20 10:30:54/文章来源:https://blog.csdn.net/BASK2311/article/details/128426039

什么是Mavne

Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM:Project Object Model),一组标准集合。由于 Maven 使用标准目录布局和默认构建生命周期,开发团队几乎可以立即自动化项目的构建基础设施。在多个开发团队环境的情况下,Maven 可以在很短的时间内按照标准设置工作方式。

Maven 之前,更多的是使用 Ant 的项目构建工具,Ant 有一个特点,每次都得写,每次都写的差不多,配置也臃肿。所以,后来搞出来 Maven。Maven 就是最先进的版本构建工具吗?不是的,只不过,目前在 Java 领域 Maven 使用比较多。除了 Maven,还有 Gradle。

它的主要功能有:

  • 提供了一套标准化的项目结构;
  • 提供了一套标准化的构建流程(编译,测试,打包,发布……);
  • 提供了一套依赖管理机制。

为了实现上面的主要功能,Maven提供了两大核心:

  • 依赖管理:对 jar 的统一管理(Maven 提供了一个 Maven 的中央仓库,当我们在项目中添加完会自动去中央仓库下载相关的依赖,并且解决依赖的依赖问题)
  • **项目构建:**对项目进行编译、测试、打包、部署、上传到私服等

Maven模型

下面来谈一谈Maven模型的整体结构,包括三个部分:

  • 项目对象模型 (Project Object Model)
  • 依赖管理模型(Dependency)
  • 插件(Plugin)

如上图所示,包括蓝、黄两个部分分别对应着依赖关系和项目构建两大核心功能。

首当其冲的一个核心就是项目对象模型,也就是经常使用的pom.xml

另外一个就是项目构建,Maven的项目构建可以按照生命周期具备以下三个标准生命周期:

  • clean:项目清理的处理
  • default(或 build):项目部署的处理
  • site:项目站点文档创建的处理

项目对象模型(POM)

POM 代表项目对象模型。它是 Maven 中的基本工作单元。它是一个 XML 文件,作为 pom.xml 驻留在项目的跟目录中。POM 不仅包含有关项目的信息以及 Maven 用于构建项目的各种配置详细信息, 还包含目标和插件。

在执行任务或目标时,Maven 在当前目录中查找 POM。它读取 POM,获取所需的配置信息,然后执行目标。在POM文件中常见的配置包括一下几点:

  • 项目依赖
  • 插件
  • 目标
  • 建立档案
  • 项目版本
  • 开发商
  • 邮件列表

在创建 POM 之前,我们应该首先确定项目(groupId)、项目名称(artifactId) 和版本,因为这些属性有助于在存储库中唯一标识项目。

<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.coderV</groupId><artifactId>coderV</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>com.coderV</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.8.2</version><scope>test</scope></dependency></dependencies><build><plugins><plugin>//...</plugin></plugins></build>
</project>
复制代码

接下来仔细拆解POM文件结构

1、项目标识符

Maven 使用一组标识符(也称为坐标)来唯一标识项目并指定应如何打包项目工件:

  • groupId: 创建项目的公司或组的唯一基本名称
  • artifactId: 项目的唯一名称
  • **version:**项目的一个版本
  • packaging: 一种打包方法(例如WAR / JAR / ZIP

其中所有 POM 文件都需要项目元素和三个必填字段:groupId、artifactId、version

其中的前三个 ( groupId:artifactId:version ) 结合形成唯一标识符,并且是您指定项目将使用的外部库(例如 JAR)版本的机制。

详细说明一些基本的项目标识符6

参数名称描述
Project root这是项目root的标签。您需要指定基本架构设置,例如 apache 架构和 w3.org 规范。
Model version模型版本应为 4.0.0。
**groupId **这是项目组/公司的 ID。这在组织或项目中通常是唯一的。
artifactId这是项目的 ID。这通常是项目的名称
version这是项目的版本

2、依赖管理

Maven 使用存储库的概念进行依赖管理,项目中使用的这些外部库称为依赖项。Maven 中的依赖项管理功能可确保从中央存储库自动下载这些库,因此您不必将它们存储在本地。

这是 Maven 的一个关键特性,并提供以下好处:

  • 结合本地仓库大幅减少从远程存储库下载的数量,减少存储使用量
  • 管理项目依赖性变得更容易
  • 提供了一个有效的平台,用于在组织内外交换二进制组件,而无需每次都从源代码手动安装组件

为了声明对外部库的依赖,您需要提供库的groupId、artifactId、verison。让我们看一个例子:

<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.16</version>
</dependency>
复制代码

当 Maven 处理依赖项时,它会将 Spring Core 库下载到本地 Maven 存储库中,并在项目中使用

传递依赖

如下图所示,项目 A 依赖于项目 B,B 又依赖于项目 C,此时 B 是 A 的直接依赖,C 是 A 的间接依赖

Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖,Maven 会动读取当前项目各个直接依赖的 POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。Maven 的依赖传递机制能够帮助用户一定程度上简化 POM 的配置。

基于 A、B、C 三者的依赖关系,根据 Maven 的依赖传递机制,我们只需要在项目 A 的 POM 中定义其直接依赖 B,在项目 B 的 POM 中定义其直接依赖 C,Maven 会解析 A 的直接依赖 B的 POM ,将间接依赖 C 以传递性依赖的形式引入到项目 A 中。

通过这种依赖传递关系,可以使依赖关系树迅速增长到一个很大的量级,很有可能会出现依赖重复,依赖冲突等情况,Maven 针对这些情况提供了如下功能进行处理。

  • 依赖范围(Dependency scope)
  • 依赖调解(Dependency mediation)
  • 可选依赖(Optional dependencies)
  • 排除依赖(Excluded dependencies)
  • 依赖管理(Dependency management)

Maven 具有以下 6 中常见的依赖范围,如下表所示。

依赖范围描述
compile编译依赖范围,scope 元素的缺省值。使用此依赖范围的 Maven 依赖,对于三种 classpath 均有效,即该 Maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。
test测试依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath 有效。例如,Junit 依赖只有在测试阶段才需要。
provided已提供依赖范围。使用此依赖范围的 Maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 Maven 重复引入该依赖。
runtime运行时依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath、运行 classpath 有效。例如,JDBC 驱动实现依赖,其在编译时只需 JDK 提供的 JDBC 接口即可,只有测试、运行阶段才需要实现了 JDBC 接口的驱动。
system系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 Maven 仓库的本地依赖,通过依赖元素 dependency 中的 systemPath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。
import导入依赖范围,该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。

依赖范围与三种 classpath 的关系一览表,如下所示。

依赖范围编译 classpath测试 classpath运行 classpath例子
compilelog4j
test--junit
provided-servlet-api
runtime--JDBC-driver
system-非 Maven 仓库的本地依赖

依赖范围对传递依赖的影响

项目 A 依赖于项目 B,B 又依赖于项目 C,此时我们可以将 A 对于 B 的依赖称之为第一直接依赖,B 对于 C 的依赖称之为第二直接依赖。

B 是 A 的直接依赖,C 是 A 的间接依赖,根据 Maven 的依赖传递机制,间接依赖 C 会以传递性依赖的形式引入到 A 中,但这种引入并不是无条件的,它会受到依赖范围的影响。

传递性依赖的依赖范围受第一直接依赖和第二直接依赖的范围影响,如下表所示。

compiletestprovidedruntime
compilecompile--runtime
testtest--test
providedprovided-providedprovided
runtimeruntime--runtime

注:上表中,左边第一列表示第一直接依赖的依赖范围,上边第一行表示第二直接依赖的依赖范围。交叉部分的单元格的取值为传递性依赖的依赖范围,若交叉单元格取值为“-”,则表示该传递性依赖不能被传递。

通过上表,可以总结出以下规律(*):

  • 当第二直接依赖的范围是 compile 时,传递性依赖的范围与第一直接依赖的范围一致;
  • 当第二直接依赖的范围是 test 时,传递性依赖不会被传递;
  • 当第二直接依赖的范围是 provided 时,只传递第一直接依赖的范围也为 provided 的依赖,且传递性依赖的范围也为 provided;
  • 当第二直接依赖的范围是 runtime 时,传递性依赖的范围与第一直接依赖的范围一致,但 compile 例外,此时传递性依赖的范围为 runtime。

依赖调节

Maven 的依赖传递机制可以简化依赖的声明,用户只需要关心项目的直接依赖,而不必关心这些直接依赖会引入哪些间接依赖了。为了避免出现依赖重复的问题,Maven 通过依赖调节来确定间接依赖的引入路径。

依赖调节遵循以下两条原则:

  1. 引入路径短者优先
  2. 先声明者优先

引入路径短者优先

引入路径短者优先,顾名思义,当一个间接依赖存在多条引入路径时,引入路径短的会被解析使用。

例如,A 存在这样的依赖关系: A->B->C->D(1.0) A->X->D(2.0)

D 是 A 的间接依赖,但两条引入路径上有两个不同的版本,很显然不能同时引入,否则造成重复依赖的问题。根据 Maven 依赖调节的第一个原则:引入路径短者优先,D(1.0)的路径长度为 3,D(2.0)的路径长度为 2,因此间接依赖 D(2.0)将从 A->X->D(2.0) 路径引入到 A 中。

先声明者优先

先声明者优先,顾名思义,在引入路径长度相同的前提下,POM 文件中依赖声明的顺序决定了间接依赖会不会被解析使用,顺序靠前的优先使用。

例如,A 存在以下依赖关系: A->B->D(1.0) A->X->D(2.0)

D 是 A 的间接依赖,其两条引入路径的长度都是 2,此时 Maven 依赖调节的第一原则已经无法解决,需要使用第二原则:先声明者优先。

Maven排除依赖和可选依赖

我们知道 Maven 依赖具有传递性,例如 A 依赖于 B,B 依赖于 C,在不考虑依赖范围等因素的情况下,Maven 会根据依赖传递机制,将间接依赖 C 引入到 A 中。但如果 A 出于某种原因,希望将间接依赖 C 排除,那该怎么办呢?Maven 为用户提供了两种解决方式:排除依赖(Dependency Exclusions)和可选依赖(Optional Dependencies)。

排除依赖

假设存在这样的依赖关系,A 依赖于 B,B 依赖于 X,B 又依赖于 Y。B 实现了两个特性,其中一个特性依赖于 X,另一个特性依赖于 Y,且两个特性是互斥的关系,用户无法同时使用两个特性,所以 A 需要排除 X,此时就可以在 A 中将间接依赖 X 排除。

排除依赖是通过在 A 中使用 exclusions 元素实现的,该元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖,示例代码如下:

    <dependencies><dependency><groupId>net.biancheng.www</groupId><artifactId>B</artifactId><version>1.0-SNAPSHOT</version><exclusions><!-- 设置排除 --><!-- 排除依赖必须基于直接依赖中的间接依赖设置为可以依赖为 false --><!-- 设置当前依赖中是否使用间接依赖 --><exclusion><!--设置具体排除--><groupId>net.biancheng.www</groupId><artifactId>X</artifactId></exclusion></exclusions></dependency></dependencies>
复制代码

关于 exclusions 元素及排除依赖说明如下:

  • 排除依赖是控制当前项目是否使用其直接依赖传递下来的间接依赖;
  • exclusions 元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖;
  • exclusion 元素用来设置具体排除的间接依赖,该元素包含两个子元素:groupId 和 artifactId,用来确定需要排除的间接依赖的坐标信息;
  • exclusion 元素中只需要设置 groupId 和 artifactId 就可以确定需要排除的依赖,无需指定版本 version。

可选依赖

与上文的应用场景相同,也是 A 希望排除间接依赖 X,除了在 B 中设置可选依赖外,我们还可以在 B 中将 X 设置为可选依赖。

设置可选依赖

在 B 的 POM 关于 X 的依赖声明中使用 optional 元素,将其设置成可选依赖,示例配置如下:

    <dependencies><dependency><groupId>net.biancheng.www</groupId><artifactId>X</artifactId><version>1.0-SNAPSHOT</version><!--设置可选依赖  --><optional>true</optional></dependency></dependencies>
复制代码

关于 optional 元素及可选依赖说明如下:

  • 可选依赖用来控制当前依赖是否向下传递成为间接依赖;
  • optional 默认值为 false,表示可以向下传递称为间接依赖;
  • 若 optional 元素取值为 true,则表示当前依赖不能向下传递成为间接依赖。

排除依赖 VS 可选依赖

排除依赖和可选依赖都能在项目中将间接依赖排除在外,但两者实现机制却完全不一样。

    • 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
    • 可选依赖是控制当前项目的依赖是否向下传递;
    • 可选依赖的优先级高于排除依赖;
    • 若对于同一个间接依赖同时使用排除依赖和可选依赖进行设置,那么可选依赖的取值必须为 false,否则排除依赖无法生效。

3、Maven 仓库

在 Maven 术语中,仓库是存储所有项目的 jar包的地方,Maven 可以轻松使用它们。根据类别可以将Maven仓库分为三类:

1)本地仓库 默认情况下,每个本地计算机的用户目录下都有一个路径名为.m2/repository/的仓库目录,这个就是本地的仓库

也可以在 settings.xml 文件配置本地仓库的路径

2)远程仓库 远程仓库也称为私服,由公司或者项目组维护,是开发人员自己定义的远程仓库,其中包含项目所需要的库或其他的jar包,可以通过标签来制定远程仓库地址

   <repositories><repository><id>companyname.lib1</id><url>http://download.companyname.org/maven2/lib1</url></repository></repositories>
复制代码

3)中央仓库

Maven中央仓库是Maven社区提供的仓库。它包含大量常用的库。当 Maven 在本地存储库中找不到任何依赖项时,就会从中央仓库中搜索

其中中央仓库有以下几点需要注意:

  • 此存储库由 Maven 社区管理。
  • 不需要配置,但可以替换中央仓库的源为制定的镜像源
  • 它需要互联网访问才能搜索。

Maven 依赖加载顺序

当我们执行 Maven 构建命令时,Maven 开始按以下顺序查找依赖库:

  • 第 1 步- 在本地存储库中搜索依赖项,如果未找到,则转到第 2 步,否则执行进一步处理。
  • 第 2 步- 如果没有提到远程存储库,则跳转到第 3 步。在一个或多个远程存储库中搜索依赖项,如果找到则将其下载到本地存储库以供将来参考
  • 第 3 步- 在中央存储库中搜索依赖项,将其下载到本地存储库以供将来参考。如果未找到 Maven 只是停止处理并抛出错误(无法找到依赖项)

4、属性(properties)

自定义属性有助于pom.xml文件更易于阅读和维护。一个十分经典的使用场景就是,通过自定义属性来定义项目依赖项的版本。

Mavenproperties是一个占位符,通过properties定义不同属性名的值

例如下面的例子中,通过<properties>定义了一个spring.version的属性,其具体的值为 5.3.16;如果想要将 Spring 升级到更新的版本,就只需更改<spring.version>属性标签内的值,所有在其<version>标签中使用该属性的依赖项都将更新。

<properties><spring.version>5.3.16</spring.version>
</properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
</dependencies>
复制代码

另一个常用的场景就是使用<properties>定义构建路径的变量,例如

<properties><project.build.folder>${project.build.directory}/tmp/</project.build.folder>
</properties><plugin>//...<outputDirectory>${project.resources.build.folder}</outputDirectory>//...
</plugin>
复制代码

5、Build

build部分也是 Maven POM 中非常重要的部分。它提供有关默认 Maven目标、已编译项目的目录和应用程序的最终名称的信息。默认build如下所示:

<build><!--当项目没有规定目标(Maven2叫做阶段(phase))时的默认值, --><!--必须跟命令行上的参数相同例如jar:jar,或者与某个阶段(phase)相同例如install、compile等 --><defaultGoal>install</defaultGoal><!-- 构建产生的所有文件存放的目录,默认为${basedir}/target,即项目根目录下的target --><directory>${basedir}/target</directory><!-- 产生的构件的文件名,默认值是${artifactId}-${version}--><finalName>${artifactId}-${version}</finalName><!--当filtering开关打开时,使用到的过滤器属性文件列表。 --><!--项目配置信息中诸如${spring.version}之类的占位符会被属性文件中的实际值替换掉 --><filters><filter>filters/filter1.properties</filter></filters>//...
</build>
复制代码

编译工件的默认输出文件夹名为*target*,打包工件的最终名称由*artifactId*和*version*组成,但您可以随时更改。

6、配置文件

构建配置文件是一组配置值,可用于设置或覆盖 Maven 构建的默认值。使用构建配置文件,您可以为不同的环境(例如生产环境和开发环境)自定义构建。

配置文件主要分为两种类型,一种是在定义在项目上pom.xml文件中,另一种是定义在setting.xml上

<profiles><profile><id>production</id><build><plugins><plugin>//...</plugin></plugins></build></profile><profile><id>development</id><activation><activeByDefault>true</activeByDefault></activation><build><plugins><plugin>//...</plugin></plugins></build></profile></profiles>
复制代码

定义在pom.xml文件上的profile可以看做pom.xml的副本,拥有与pom.xml相同的子元素与配置方法。

正如您在上面的示例中看到的,默认配置文件设置为development。如果要运行生产配置文件,可以使用以下 Maven 的 -P 命令显示的激活一个profile:

mvn clean install -P production
复制代码

Maven 构建生命周期

每个 Maven 构建都遵循指定的生命周期。您可以执行多个构建生命周期目标,包括编译项目代码、创建包以及在本地 Maven 依赖项存储库中安装存档文件的目标。

以下列表显示了最重要的 Maven生命周期阶段:

  • validate: 检查项目的正确性
  • compile: 将提供的源代码编译成二进制工件
  • test: 执行单元测试
  • package: 将编译后的代码打包*到归档文件中
  • integration-test: 执行额外的测试,这需要打包
  • verify——检查包是否有效
  • install – 将包文件安装到本地 Maven 存储库
  • deploy – 将包文件部署到远程服务器或存储库

1、Clean 生命周期

当我们执行 mvn post-clean 命令时,Maven 调用 clean 生命周期,它包含以下阶段:

  • pre-clean:执行一些需要在clean之前完成的工作
  • clean:移除所有上一次构建生成的文件
  • post-clean:执行一些需要在clean之后立刻完成的工作

在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,如果执行 mvn clean 将运行pre-clean, clean两个生命周期阶段;运行 mvn post-clean ,则运行pre-clean, clean, post-clean三个生命周期阶段

2、Default (Build) 生命周期

这是 Maven 的主要生命周期,被用于构建应用,包括下面的 23 个阶段:

生命周期阶段描述
validate(校验)校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
initialize(初始化)初始化构建状态,比如设置属性值。
generate-sources(生成源代码)生成包含在编译阶段中的任何源代码。
process-sources(处理源代码)处理源代码,比如说,过滤任意值。
generate-resources(生成资源文件)生成将会包含在项目包中的资源文件。
process-resources (处理资源文件)复制和处理资源到目标目录,为打包阶段最好准备。
compile(编译)编译项目的源代码。
process-classes(处理类文件)处理编译生成的文件,比如说对Java class文件做字节码改善优化。
generate-test-sources(生成测试源代码)生成包含在编译阶段中的任何测试源代码。
process-test-sources(处理测试源代码)处理测试源代码,比如说,过滤任意值。
generate-test-resources(生成测试资源文件)为测试创建资源文件。
process-test-resources(处理测试资源文件)复制和处理测试资源到目标目录。
test-compile(编译测试源码)编译测试源代码到测试目标目录.
process-test-classes(处理测试类文件)处理测试源码编译生成的文件。
test(测试)使用合适的单元测试框架运行测试(Juint是其中之一)。
prepare-package(准备打包)在实际打包之前,执行任何的必要的操作为打包做准备。
package(打包)将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
pre-integration-test(集成测试前)在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
integration-test(集成测试)处理和部署项目到可以运行集成测试环境中。
post-integration-test(集成测试后)在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
verify (验证)运行任意的检查来验证项目包有效且达到质量标准。
install(安装)安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
deploy(部署)将最终的项目包复制到远程仓库中与其他开发者和项目共享。

Site 生命周期

Maven Site 插件一般用来创建新的报告文档、部署站点等。

  • pre-site:执行一些需要在生成站点文档之前完成的工作
  • site:生成项目的站点文档
  • post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
  • site-deploy:将生成的站点文档部署到特定的服务器上

插件(Plugin)

插件管理与依赖管理原理一样、不同的是定义的元素标签不一样、插件管理标签是build标签的子标签pluginManagement

pluginManagement 用来做插件管理的。它是表示插件声明,即你在项目中的pluginManagement下声明了插件,Maven不会加载该插件,pluginManagement声明可以被继承。如下面的例子

<pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>2.1</version><configuration><attach>true</attach></configuration><executions><execution><phase>compile</phase><goals><goal>jar</goal></goals></execution></executions></plugin></plugins>
</pluginManagement><!-- 子POM-->
<plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId></plugin>
</plugins>

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

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

相关文章

消息队列RabbitMQ学习笔记(四)死信队列和延迟队列

1. 死信的概念 先从概念解释上搞清楚这个定义&#xff0c;死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理 解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到queue 里了&#xff0c;consumer 从 queue 取出消息 进行…

Linux 下 使用点阵在LCD上显示汉字,字符

文章目录前言一、显示字符1.获取点阵&#xff1a;2.描点&#xff08;显示字符函数&#xff09;&#xff1a;3. 要打开LCD设备&#xff1a;4. 通过ioctl 获取Framebuffer参数:5. 通过mmap映射出Framebuffer的地址&#xff1a;6.清屏并显示字符&#xff1a;二、显示汉字1.区位码&…

多线程基础入门

文章目录前言一、认识线程&#xff08;一&#xff09;概念1.线程是什么2.为啥要有线程&#xff08;轻量级进程&#xff09;为什么线程比进程更轻量经典面试题&#xff1a;谈谈进程和线程的区别和联系3.线程的结构&#xff08;二&#xff09;第一个多线程程序&#xff08;三&…

我国用电信息采集系统行业应用需求及市场容量分析 现6省上线运行

用户用电信息采集系统是通过对配电变压器和终端用户的用电数据的采集和分析&#xff0c;实现用电监控、推行阶梯定价、负荷管理、线损分析&#xff0c;最终达到自动抄表、错峰用电、用电检查&#xff08;防窃电&#xff09;、负荷预测和节约用电成本等目的。建立全面的用户用电…

RabbitMQ 第一天 基础 4 RabbitMQ 的工作模式 4.4 Topic 通配符模式 4.5 工作模式总结

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第一天 基础4 RabbitMQ 的工作模式4.4 Topic 通配符模式4.4.1 模式说明4.4.2 代码编写4.4.3 小结4.5 工作模式总结第一天 基础 4 RabbitMQ 的工作模式 4.4 Topic 通配符模式 …

32天高效突击:开源框架+性能优化+微服务架构+分布式,面阿里获P7(脑图、笔记、面试考点全都有)

今年的大环境不佳&#xff0c;所以大部分的人在今年的招聘旺季都没有收获到好的结果。 但不要着急&#xff0c;今天分享的内容则是由 一位阿里P7的面试心得&#xff0c;通过32天的高效突击训练&#xff0c;成功拿下offer的学习方法。 篇章分为三大章节&#xff0c;可以根据自…

day 10 模拟和高精度

P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布 #include<bits/stdc.h> using namespace std; int n, na, nb, fa, fb;//f:得分 int a[205], b[205];void fun(int ta, int tb){if(ta 0 && tb 1) fb;if(ta 1 && tb 0) fa;if(ta 0 && tb …

【nowcoder】笔试强训Day2

目录 一、选择题 二、编程题 2.1排序子序列 2.2倒置字符串 一、选择题 1.A 派生出子类 B &#xff0c; B 派生出子类 C &#xff0c;并且在 java 源代码有如下声明&#xff1a; 1. A a0new A(); 2. A a1new B(); 3. A a2new C(); 问以下哪个说法是正确的&#xff08;&…

机器学习 | 线性回归

一.基本原理 利用回归方程&#xff08;函数&#xff09;对一个或多个自变量&#xff08;特征值&#xff09;和因变量&#xff08;目标值&#xff09;之间关系进行建模的一种分析方式 根据线性代数&#xff0c;我们可以定义方程 xwy&#xff0c;在线性回归问题中&#xff0c;x…

前端小知识:赋予变量默认值(逻辑与运算符、空值合并运算符、逻辑空运算符)

8. 逻辑与运算符、空值合并运算符、逻辑空运算符&#xff08;可用赋予默认值&#xff09; &#xff08;空值合并运算符&#xff09;官方文档&#xff1a; https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing   &#xff08;逻辑…

【推荐收藏】这份图解算法数据结构的材料太良心

5年前发生的一件事&#xff0c;成为了我职业生涯的重要转折点。当时的我在交大读研&#xff0c;对互联网求职一无所知&#xff0c;但仍然硬着头皮申请了 Microsoft 实习生。面试官让我在白板上写出“快速排序”代码&#xff0c;我畏畏缩缩地写了一个“冒泡排序”&#xff0c;并…

1754. 构造字典序最大的合并字符串

摘要 1754. 构造字典序最大的合并字符串 一 贪心算法分析 题目要求合并两个字符串 word1 与 word2&#xff0c;且要求合并后的字符串字典序最大。首先需要观察一下合并的选择规律&#xff0c;假设当前需要从 word1​ 的第 i 个字符和 word2​ 的第 j个字符选择一个字符加入到…

自制macOS安装镜像iso虚拟机用

在网上下载的用于在虚拟机中安装的镜像版本相对比较旧。安装完成后还要进行升级比较麻烦。于是我就想自己制作安装镜像了。 精华 #创建空白磁盘镜像 hdiutil create -o /tmp/ventura -size 13800m -volname ventura -layout SPUD -fs HFSJ #挂载上面创建的镜像 hdiutil attac…

内容资产管理11问

&#x1f447;点击一键关注主笔&#xff1a;邹小困、邝晴岚主持人&#xff1a;增长黑盒分析师Emma出品&#xff1a;增长黑盒研究组前言在这个信息爆炸的数据时代&#xff0c;各个行业正积极推进数字化转型&#xff0c;产业升级与技术赋能成为主题之一。在推进企业线上线下融合的…

最近面试遇到一个算法题,简单写一点。

第⼀题&#xff08;必答&#xff09; 请针对有重复数字的数组设计⼀个快排算法&#xff0c;⽐如&#xff1a;[34, 34, 89, 1, 1, 20, 12]&#xff0c;排序后结果为 [89,34,34,20,12,1,1] 第⼆题&#xff08;必答&#xff09; 请利⽤Redis 实现⼀个通⽤分布式锁&#xff0c;并…

B+树 [数据结构与算法][Java]

B树 B树是B树的一种变形 我们通过一颗四阶B树来理解认识一下B树:(如下:) 我们其实从图上就可以看出B树和B树是有很多不同之处的 比如我们的B树中将叶子结点层的所有结点使用一个链表串联了起来B树中对于非叶子结点都是只是存储的索引(指针), 并没有存储关键字, 所以我们最终查…

Linux系统基础——BIOS和Bootloader

BIOS和Bootloader 特此说明: 刘超的趣谈linux操作系统是比较重要的参考资料&#xff0c;本文大部分内容和所有图片来源于这个专栏。 1 了解背景 1.1 目的 操作系统不是在板子上电就直接运行的&#xff0c;上电到系统启动的中间过程要搞明白&#xff0c;比如了解linux系统启动…

火山引擎 DataTester 上线“流程画布”功能,支持组合型 A/B 实验分析

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 在精细化运营的时代&#xff0c;运营活动同样需要有精细化的策略&#xff0c;例如在年末大促活动中&#xff0c;设计 APP 弹窗提醒、满减、会员领券时&#xff0c;我…

TikTok 加速团结独立站,跨境电商的又一次红利期?

TikTok近年来在国际上非常流行。2021年8月&#xff0c;TikTok的全球下载量首次超过Facebook&#xff0c;成为全球最大的下载量。TikTok的诞生打破了海外社交媒体的垄断&#xff0c;TikTok营销成为许多跨境卖家的重点之一。 封号事件发生后&#xff0c;许多跨境卖家开始向独立站…

Python函数总结

在Python中&#xff0c;函数是一个带有名字的代码块&#xff0c;可以被反复调用。函数可以帮助你组织和重用代码&#xff0c;使你的程序更整洁&#xff0c;更易于维护。本文将会深入探索Python的秘密 目录 定义函数 自定义函数 内置函数 函数式方程 高阶函数 函数标注 …