【Maven教程】(三)基础使用篇:入门使用指南——POM编写、业务代码、测试代码、打包与运行、使用Archetype生成项目骨架~

Maven基础使用篇

  • 1️⃣ 编写 POM
  • 2️⃣ 编写业务代码
  • 3️⃣ 编写测试代码
  • 4️⃣ 打包和运行
  • 5️⃣ 使用 Archetype生成项目骨架

在这里插入图片描述


1️⃣ 编写 POM

到目前为止,已经大概了解并安装好了Maven环境, 现在,我们开始创建一个最简单的 Hello World 项目。如果你是初次接触 Maven, 建议按照本文的内容 一步步地编写代码并执行, 其中可能你会碰到一些概念暂时难以理解,但不用着急,记下这些疑难点,我在后续文章中会逐一进行解答。

就像 MakeMakefileAntbuild.xml 一样 ,Maven 项目的核心是 pom.xmlPOM (Project Object Model, 项目对象模型) 定义了项目的基本信息,用于描述项目如何构建, 声明项目依赖,等等。现在先为 Hello World 项目编写一个最简单的 pom.xml

首先创建一个名为 hello-world 的文件夹,打开该文件夹,新建一个名为 pom.xml 的文件,输入其内容,如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven,apache.org/POM/4.0.0"
	xmins:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache,org/POM/4.0.0
http://maven.apache,org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.xiaoshan.mvnbook</groupId>
	<artifactId>hello-world</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
</project>

代码的第一行是XML 头,指定了该 xml 文档的版本和编码方式。紧接着是 project 元素 ,project 是所有pom.xml 的根元素,它还声明了一些 POM 相关的命名空间及 xsd 元素 , 虽然这些属性不是必须的,但使用这些属性能够让第三方工具(如 IDE 中的XML 编辑器 ) 帮助我们快速编辑 POM。
根元素下的第一个子元素 modelVersion 指定了当前POM 模型的版本,对于 Maven 2 及 Maven 3 来说,它只能是4.0.0。

这段代码中最重要的是包含 groupldartifactldversion 的三行。这三个元素定义了一个项目基本的坐标,在Maven 的世界,任何的 jarpom 或者 war 都是以基于这些基本的坐标进行区分的。

groupld定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如在 googlecode 上建立了一个名为 myapp 的项目,那么 groupld 就应该是 com. googlecode.myapp, 如果你的公司是 mycom, 有一个项目为 myapp, 那 groupld 就应该是 com.mycom.myappartifactld 定义了当前Maven 项目在组中唯一 的ID, 我们为这个 Hello World 项目定义 artifactldhello-world。 而在前面的 groupIdcom. googlecode.myapp 的例子中,你可能会为不同的子项目(模块)分配 artifactId, 如 myapp-utilmyapp-domainmyapp-web 等。
顾名思义, version 指定了 Hello World 项目当前的版本 — — 1.0-SNAPSHOT。SNAPSHOT 意为快照,说明该项目还处于开发中,是不稳定的版本。随着项目的发展, version 会不断更新,如升级为1.01.1-SNAPSHOT1.12.0 等。后面文章会详细介绍 SNAPSHOT 以及如何使用Maven 管理项目版本的升级发布。

最后一个 name 元素声明了一个对于用户更为友好的项目名称,虽然这不是必须的,但还是推荐为每个 POM 声明 name, 以方便信息交流。

没有任何实际的Java代码,我们就能够定义一个Maven 项目的 POM, 这体现了 Maven 的一大优点,它能让项目对象模型最大程度地与实际代码相独立,我们可以称之为解耦,或者正交性。这在很大程度上避免了Java 代码和 POM 代码的相互影响。比如当项目需要升级版本时,只需要修改 POM, 而不需要更改 Java代码;而在 POM 稳定之后,日常的 Java 代码开发工作基本不涉及 POM 的修改。

2️⃣ 编写业务代码

项目业务代码和测试代码不同,项目的业务代码会被打包到最终的构件中(如 jar), 而 测试代码只在运行测试时用到,不会被打包。默认情况下, Maven 假设项目业务代码位于 src/ main/java 目录,我们遵循 Maven的约定,创建该目录,然后在该目录下创建文件 com/xiaoshan/mvnbook/helloworld/HelloWorld.java, 其内容如下所示:

package com.xiaoshan.mvnbook.helloworld;

public class HelloWorld{
	public String sayHello(){
		return "Hello Maven";
	}
	public static void main(String[] args){
		System.out.print(new HelloWorld().sayHello());
	}
}

这是一个简单的Java 类,它有一个sayHello()方法,返回一个String。 同时这个类还带有一个main 方法 , 创建一个HelloWorld 实例 , 调用sayHello() 方法,并将结果输出到控制台。

关于该Java代码有两点需要注意。首先,在绝大多数情况下,应该把项目主代码放到 src/main/java/ 目录下 ( 遵循 Maven的约定), 而无须额外的配置,Maven 会自动搜寻该目录找到项目主代码。其次,该Java 类的包名是 com.xiaoshan. mvnbook. helloworld, 这与之前在 POM 中定义的 groupIdartifactId 相吻合。 一般来说,项目中Java 类的包都应该基于项目的 groupIdartifactId, 这样更加清晰,更加符合逻辑,也方便搜索构件或者Java 类 。

代码编写完毕后,使用Maven 进行编译,在项目根目录下运行命令 mvn clean compile。会得到如下输出:

[INFO] Scanning for projects..
[INFO]
-----------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, compile]
[INFO]
-----------------------------------------------------------------------
[INFO] [clean:clean {execution:default-clean}]
[INF0] Deleting directory D:\code\hello-world\target
[INF0] [resources:resources {execution:default-resources}]
[INFO] skip non existing resourcepirectory D:\code\hello-world\src\main\resources
[INFO] [compiler:compile {execution:default-compile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\classes
[INFO]
-----------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-----------------------------------------------------------------------
[INFO]    Total time:1 second
[INFO]    Finished at: Fri oct 0902:08:09 CST 2009
[INFO]     Final Memory:9M/16M
-----------------------------------------------------------------------

clean指令告诉 Maven 清理输出目录 target/compile 告诉 Maven 编译项目主代码,从输出中看到 Maven 首先执行了 clean:clean 任务,删除targel/目录。默认情况下, Maven 构建的所有输出都在 target/目录中;接着执行 reources:resources 任务 (未定义项目资源 ,暂且略过 ) ; 最后执行 compiler:compile 任务 , 将项目主代码编译至 target/classes 目录 ( 编译好的类为 com/xiaoshan/mvnbook/helloworld/HelloWorld.class)。

上文提到的 clean:clean, resources: resources 和 compiler:compile 对应了一些 Maven 插件及插件目标,比如 clean:clean 是 clean 插件的 clean 目标 ,compiler:compile 是 compiler 插件的 compile 目标。后文会详细讲述 Maven 插件及其编写方法。

至此 ,Maven 在没有任何额外的配置的情况下就执行了项目的清理和编译任务。接下来,编写一些单元测试代码并让 Maven 执行自动化测试。

3️⃣ 编写测试代码

为了使项目结构保持清晰,业务代码与测试代码应该分别位于独立的目录中。上文讲到过 Maven 项目中默认的主代码目录是 src/main/java, 对应地,Maven 项目中默认的测试代码目录是 src/test/java。因此,在编写测试用例之前,应当先创建该目录。

在Java 中,由 Kent Beck 和 Erich Gamma建立的JUnit 是事实上的单元测试标准。要使用JUnit, 首先需要为 Hello World 项目添加一个JUnit 依赖,修改项目的 POM 如下所示:

<?xml version="1.0" encoding="UTP-8"?>
<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.xiaoshan.mvnbook</groupld>
	<artifactId>helloworld</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>                            

代码中添加了dependencies 元素,该元素下可以包含多个 dependency 元素以声明项目的依赖。这里添加了一个依赖 —— groupIdjunit, artifactIdjunit, version 是 4.7。前面提到 groupIdartifactIdversion 是任何一个 Maven 项目最基本的坐标,JUnit 也不例外,有了这段声明,Maven 就能够自动下载 junit-4.7.jar。也许你会问,Maven 从哪里下载这个 jar 呢? 在 Maven 之前,可以去JUnit 的官方网站下载分发包,有了Maven, 它会自动访问中央仓库 (http://repol.maven.org/maven2/), 下载需要的文件。大家也可以自己访问该仓库,打开路径 junit/junil/4.7/, 就能 看到 junit-4.7.pomjunil-4.7.jar。后面会详细介绍 Maven 仓库及中央仓库。

上述 POM 代码中还有一个值为 test 的元素 scope, scope 为依赖范围,若依赖范围为test 则表示该依赖只对测试有效。换句话说,测试代码中的 import JUnit 代码是没有问题的 ,但是如果在主代码中用 import JUnit 代码,就会造成编译错误。如果不声明依赖范围,那么默认值就是 compile, 表示该依赖对主代码和测试代码都有效。

配置了测试依赖,接着就可以编写测试类。回顾 一 下前面的 HelloWorld 类 , 现在要测试该类的 sayHello() 方法, 检查其返回值是否为 “Hello Maven”。 在 src/test/java 目录下创建文件,其内容如下所示:

package com.xiaoshan.mvnbook.helloworld;

import org.junit.Assert.assertEquals;
import org.junit.Test:

public class HelloWorldTest{
	@Test
	public void testSayHello(){
		He1loWorld helloWorld = new HelloWorld();
		String result = helloWorld.sayHello();
		assertEquals("Hello Maven",result);
	}
}

一个典型的单元测试包含三个步骤:①准备测试类及数据;②执行要测试的行为;③检查结果。上述样例首先初始化了一个要测试的HelloWorld实例,接着执行该实例的sayHello()方法并保存结果到result变量中,最后使用JUnit框架的Assert类检查结果是否为我们期望的“HelloMaven”。在JUnit3中,约定所有需要执行测试的方法都以test开头,这里使用了JUnit4,但仍然遵循这一约定。在JUnit4中,需要执行的测试方法都应该以@Test进行标注。

测试用例编写完毕之后就可以调用 Maven 执行测试。运行 mvn clean test:

[INFO] Scanning for projects.
[INFO]
-------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, test]
[INFO]
-------------------------------------------------------------------
[INFO] [elean:clean	{execution:default-clean}]
[INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target
[INFO] [resources:resources	{execution:default-resources)]
Downloading:http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom
	1K downloaded (junit-4.7.pom)
[INFO] [compiler:compile {execution: default-compile}]
[INFO]       Compiling 1 source file to D:\code\hello-world\target\classes
[INF0] [resources:testResources {execution:default-testResources}]
Downloading: http://repol,maven.org/maven2/junit/junit/4.7/unit-4.7.jar
	226K downloaded (Junit-4.7.jar) 
[INFO] [compiler:testCompile {execution:default-testCompile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO]
-------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO]
-------------------------------------------------------------------
[INFO] Compilation failure
D:\code\hello-world\src\test\java\com\xiaoshan\mvnbook\helloworld\He11oWorldTest.java;[8,5]-source      1.3 中不支持注释(请使用-source 5 或更高版本以启用注释) @Test
[INFO]
[INFO For more information, run Maven with the switch

不幸的是构建失败了 , 先耐心分析一下这段输出。命令行输入的是 mvn clean test, 而 Maven 实际执行的可不止这两个任务 , 还 有 clean:cleanresources:resourcescompiler:compileresources:testResources 以及compiler:testCompile。 暂时需了解的是, 在Maven 执行测试 (test) 之前 , 它会先自动执行项目主资源处理、主代码编译、测试资源处理、测试代码编译等工作,这是 Maven 生命周期的一个特性。后续章节会详细解释 Maven 的生命周期。

从输出中还看到:Maven从中央仓库下载了junit-4.7.pomjunit-4.7.jar 这两个文件到本地仓库(~/. m2/repository)中,供所有Maven项目使用。

构建在执行 compiler:testCompile任务的时候失败了,Maven输出提示我们需要使用 source5或更高版本以启动注释,也就是前面提到的JUnit4的@Test注解。这是Maven初学者常常会遇到的一个问题。由于历史原因,Maven的核心插件之———compiler插件默认只支持编译Java1.3, 因此需要配置该插件使其支持Java5,如下所示:

<project>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5c/target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>           

该 POM 省略了除插件配置以外的其他部分。我们暂且不去关心插件配置的细节,只需知道 compiler 插件支持Java5 的编译。现在再执行mvn clean test, 输出如下:

[INFO] [compiler:testCompile {execution:default-testCompile}]
[INFO]        Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO] [surefire:test {execution:default-test}]
[INFO]        Surefire report directory:D:\code\hello-world\target\surefire-reports
TESTS
Running com.xiaoshan.mvnbook.helloworld.He11oWorldTest
Tests run:1, Failures:0, Errors:0, Skipped:0,Time elapsed:0.055 sec
Results:
Tests run:1, Failures;0.Errors:0,Skipped:0
[INFO]
-------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-------------------------------------------------------------------

我们看到 compiler:testCompile 任务执行成功了,测试代码通过编译之后在 target/test-classes下生成了二进制文件,紧接着 surefire:test 任务运行测试, surefire 是 Maven 中负责执行测试的插件,这里它运行测试用例 HelloWorldTest, 并且输出测试报告,显示一共运行了多少测试,失败了多少,出错了多少,跳过了多少。显然,我们的测试通过了。

4️⃣ 打包和运行

将项目进行编译、测试之后,下一个重要步骤就是打包(package)。HelloWorld 的POM中没有指定打包类型,使用默认打包类型 jar。简单地执行命令mvn clean package 进行打包,可以看到如下输出:

...
Tests run:1,Failures:0, Errors:0, Skipped:0

[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar:D:\code\hello-worid\target\hello-wor1d-1.0-SNAPSHOT.Jar
[INPO]
-------------------------------------------------------------------
[INPO] BUILD SUCCESSFUL
...

类似地, Maven 会在打包之前执行编译、测试等操作。这里看到 jar:jar 任务负责打包,实际上就是 jar 插件的 jar 目 标将项目主代码打包成一个名为 hello-world-1.0-SNAP-SHOT.jar 的文件。该文件也位于 target/ 输出目录中,它是根据 artifact-version.jar 规则进行命名的,如有需要,还可以使用 finalName 来自定义该文件的名称,这里暂且不展开,后面会详细解释。

至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar 文件到其他项目的 Classpath 中从而使用 HelloWonld 类。但是,如何才能让其他的Maven 项目直接引用这个jar呢? 还需要一个安装的步骤,执行 mvn clean install:

...
[INFO] [jar:jar {execution: default-jar}]
[INF0] Building jar:D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO] [install:install {execution:default-instal1}]
[INFO] Installing D:\code\hello-world\target\hello-wor1d-1.0-SNAPSHOT.jar to c:\Users\xiaoshan\.m2\repository\com\xiaoshan\mvnbook\hello-world\1.0-SNAPSHOTN\hello-world-1.0-SNAPSHOT.jar
[INFO]
-------------------------------------------------------------------
[INFO]   BUILD   SUCCESSFUL
...

在打包之后,又执行了安装任务 install:install。从输出可以看到该任务将项目输出的 jar安装到了Maven本地仓库中,可以打开相应的文件夹看到 HelloWorld 项目的 pom和 jar。之前讲述JUnit的POM及jar的下载的时候,我们说只有构件被下载到本地仓库后,才能由所有Maven项目使用,这里是同样的道理,只有将HelloWorld的构件安装到本地仓库之后,其他Maven项目才能使用它。

我们已经体验了Maven最主要的命令:mvn clean compilemvn clean testmvn clean packagemvn clean install。执行test之前是会先执行compile的,执行package之前是会先执行test的,而类似地,install之前会执行package。可以在任何一个Maven项目中执行这些命令,而且我们已经清楚它们是用来做什么的。

到目前为止,还没有运行HelloWorld项目,不要忘了HelloWorld类可是有一个main方法的。默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到 manifest中(打开 jar文件中的META-INF/MANIFEST.MF文件,将无法看到 Main-Class—行)。为了生成可执行的 jar文件,需要借助 maven-shade-plugin,配置该插件如下:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>  
	<artifactId>maven-shade-plugin</artifactId> 
	<version>1.2.1</version>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>shade</goal>
			</goals>
			<configuration>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource. ManifestResourceTransformer">
						<mainClass>com.xiaoshan.mvnbook.helloworld.HelloWorld</mainclass>
					</transformer>	
				</transformers>
			</configuration>
		</execution>
	</executions>
</plugin>

plugin元素在POM中的相对位置应该在<project> <build> <plugins> 下面。我们配置了mainClasscom.xiaoshan.mvnbook.helloworld.HelloWorld, 项目在打包时会将该信息放到 MANIFEST中。现在执行mvn clean install, 待构建完成之后打开 target/ 目录,可以看到 hello-world-1.0-SNAPSHOT.jaroriginal-hello-world-1.0-SNAPSHOT.jar, 前者是带有 Main-Class 信息的可运行jar, 后者是原始的jar, 打开 hello-world-1.0-SNAPSHOT.jarMETA-INF/ MANIFEST.MF, 可以看到它包含这样一行信息:

Main-Class:com.xiaoshan.mvnbook.helloworld.HelloWorld

现在,在项目根目录中执行该jar文件:

D:\code\hello-world>java-jartarget\hello-world-1.0-SNAPSHOT.jar
HelloMaven

控制台输出为HelloMaven,这正是我们所期望的。

5️⃣ 使用 Archetype生成项目骨架

HelloWorld项目中有一些Maven的约定:在项目的根目录中放置pom.xml,在 src/main/java目录中放置项目的主代码,在 src/test/java中放置项目的测试代码。之所以一步一步地展示这些步骤,是为了能让可能是Maven初学者的你得到最实际的感受。我们称这些基本的目录结构和 pom.xml文件内容称为项目的骨架,当第一次创建项目骨架的时候,你还会饶有兴趣地去体会这些默认约定背后的思想,第二次,第三次,你也许还会满意自己的熟练程度,但第四、第五次做同样的事情,你可能就会恼火了。为此Maven提供了 Archetype以帮助我们快速勾勒出项目骨架。

还是以HelloWorld为例,我们使用maven archetype来创建该项目的骨架,离开当前的Maven项目目录。
如果是Maven3,简单地运行:

mvn archetype:generate

如果是Maven2,最好运行如下命令:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate

很多资料会让你直接使用更为简单的mvn archetype:generate命令,但在Maven2中这是不安全的,因为该命令没有指定Archetype插件的版本,于是Maven会自动去下载最新的版本。进而可能得到不稳定的SNAPSHOT版本,导致运行失败。然而在Maven3中,即使用户没有指定版本,Maven也只会解析最新的稳定版本,因此这是安全的。

我们实际上是在运行插件maven-archetype-plugin,注意冒号的分隔,其格式为groupld:arifactld:version:goal, orgapache.maven.plugins是maven官方插件的groupId, maven-archetype-plugin是Archetype插件的artifactId, 2.0-alpha-5是目前该插件最新的稳定版,generate是要使用的插件目标。

紧接着会看到一段长长的输出,有很多可用的Archelype供选择,包括著名的 Appfuse 项目的Archetype、JPA项目的Archetype等。每一个Archetype前面都会对应有一个编号,同时命令行会提示一个默认的编号,其对应的Archetype为 maven-archetype-quickstart, 直接回车以选择该Archelype, 紧接着Maven会提示输入要创建项目的groupIdartifactIdversion 以及包名package。如下输入并确认:

Define value for groupId:: com.xiaoshan.mvnbook
Define value for artifactId::hello-world
Define value for version::1.0-SNAPSHOT
Define value for package:com.xiaoshan.mvnbook::com.xiaoshan.mvnbook.helloworld
Confirm properties configuration:
groupId: com.juvenxu.mvnbook
artifactId: hello-world
version: 1.0-SNAPSHOT
package: com.xiaoshan.mvnbook.helloworld
Y::Y

Archetype插件将根据我们提供的信息创建项目骨架。在当前目录下,Archetype插件会创建一个名为 hello-world(我们定义的artifactId)的子目录,从中可以看到项目的基本结构:基本的pom.xml已经被创建,里面包含了必要的信息以及一个junit依赖;主代码目录src/main/java已经被创建,在该目录下还有一个Java类com.xiaoshan.mvnbook.helloworld.App, 注意这里使用到了刚才定义的包名,而这个类也仅仅只有一个简单的输出Hello World!main方法;测试代码目录 src/test/java 也被创建好了,并且包含了一个测试用例com.xiaoshan.mvnbook.helloworld.AppTest

Archetype可以帮助我们迅速地构建起项目的骨架,在前面的例子中,我们完全可以在Archetype生成的骨架的基础上开发HelloWorld项目以节省大量时间。
此外,这里仅仅是看到了一个最简单的Archetype,如果有很多项目拥有类似的自定义项目结构以及配置文件,则完全可以一劳永逸地开发自己的Archetype,然后在这些项目中使用自定义的Archetype来快速生成项目骨架。后面我会详细阐述如何开发Maven Archetype。


温习回顾上一篇(点击跳转)
《【Maven教程】(二)安装配置篇:手把手教你安装及配置Maven环境~》

继续阅读下一篇(点击跳转)
《》

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

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

相关文章

数据库第十五课-------------非关系型数据库----------Redis

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

基于 BEM 规范实现简单的全局 scss

该文章是在学习 小满vue3 课程的随堂记录示例均采用 <script setup>&#xff0c;且包含 typescript 的基础用法 前言 BEM 是 css 常用的命名规范BEM &#xff1a;block(块)、 element(元素)、 modify(修饰符)以 namespace-block__element、namespace-block---modify 格式…

如何更高效的写出更健全的代码,一篇文章教会你如何拥有一个良好的代码风格

前言&#xff1a;在平常的写代码的过程中&#xff0c;或多或少的遇到很多奇怪的 bug &#xff0c;尤其是一些大的程序&#xff0c;明明上一部分都是好好的&#xff0c;写下一块的时候突然多几百个 bug 的情况&#xff0c;然后这一块写完了后编译的时候直接傻眼了&#xff0c;看…

(学习笔记-调度算法)进程调度算法

进程调度算法也称 CPU 调度算法&#xff0c;毕竟进程是由 CPU 调度的。 当 CPU 空闲时&#xff0c;操作系统就选择内存中标的某个 [就绪状态] 的进程&#xff0c;将其分配给 CPU。 什么时候会发生CPU调度呢&#xff1f;通常有以下情况&#xff1a; 当进程从运行状态转换到等待…

使用 ChatGPT 创建 PowerPoint 演示文稿

让 ChatGPT 成为您的助手来帮助您编写电子邮件很简单,因为众所周知,它非常能够生成文本。很明显,ChatGPT 无法帮助您做饭。但您可能想知道它是否可以生成文本以外的其他内容。在上一篇文章中,您了解到 ChatGPT 只能通过中间语言为您生成图形。在这篇文章中,您将了解使用中…

【Leetcode】103.二叉树的锯齿形层序遍历

一、题目 1、题目描述 给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 示例1: 输入:root = [3,9,20,null,null,15,7] 输出:[[3],[20,9],[15,7]]示例2: 输入:root = [1] 输…

点亮社交新篇章:探索 WeTalk 新增的头像与群聊功能

目录 引言&#xff1a; 引入头像功能&#xff1a; 头像功能的优势&#xff1a; 引入群聊功能&#xff1a; 群聊功能的优势&#xff1a; 引入头像功能&#xff1a; 查看头像&#xff1a; ​编辑 上传头像&#xff1a; 引入群聊功能&#xff1a; 创建群聊&#xff1a…

【数据结构】回溯算法公式化解题 leetcode经典题目带刷:全排列、组合、子集

目录 回溯算法一、什么是回溯算法1、基本思想&#xff1a;2、一般步骤&#xff1a; 二、题目带练1、全排列2、组合3、子集 三、公式总结 回溯算法 一、什么是回溯算法 回溯算法&#xff08;Backtracking Algorithm&#xff09;是一种解决组合问题、排列问题、选择问题等一类问…

字节跳动 Git 的正确使用姿势与最佳实践

版本控制Git 黑马&尚硅谷 Git的前世今生 方向介绍 为什么要学习Git 1.0 Git是什么 1.1 版本控制 1.1.1 本地版本控制 1.1.2 集中版本控制 1.1.3 分布式版本控制 我们已经把三个不同的版本控制系统介绍完了&#xff0c;Git 作为分布式版本控制工具&#xff0c; 虽然目前来讲…

第一讲使用IDEA创建Java工程——HelloWorld

一、前言导读 为了能够让初学者更快上手Java,不会像其他书籍或者视频一样,介绍一大堆历史背景,默认大家已经知道Java这么编程语言了。本专栏只会讲解干货,直接从HelloWord入手,慢慢由浅入深,讲个各个知识点,这些知识点也是目前工作中项目使用的,而不是讲一些老的知识点…

【算法专题突破】双指针 - 移动零(1)

目录 写在前面 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 写在前面 在进行了剑指Offer和LeetCode hot100的毒打之后&#xff0c; 我决心系统地学习一些经典算法&#xff0c;增强我的综合算法能力。 1. 题目解析 题目链接&#xff1a;283. 移动零 - 力…

基于51单片机直流电机转速数码管显示控制系统

一、系统方案 本文主要研究了利用MCS-51系列单片机控制PWM信号从而实现对直流电机转速进行控制的方法。本文中采用了三极管组成了PWM信号的驱动系统&#xff0c;并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节&#xff0c;从而控制其输入信号波形等…

mysql -sql触发器

1、创建触发器。 //创建一个触发器在给section关系插入后触发 create trigger timeslot_check1 after insert on sectionreferencing new row as nrow//对每个插入的行都执行for each row//when指定一个条件&#xff0c;仅对于满足条件的元组才会执行触发器剩余的部分when (nr…

实现简单的element-table的拖拽效果

第一步&#xff0c;先随便创建element表格 <el-table ref"dragTable" :data"tableData" style"width: 100%" border fit highlight-current-row><el-table-column label"日期" width"180"><template slot-sc…

Android SDK 上手指南||第六章 用户交互

第六章 用户交互 在这篇教程中&#xff0c;我们将对之前所添加的Button元素进行设置以实现对用户点击的检测与响应。为了达成这一目标&#xff0c;我们需要在应用程序的主 Activity类中略微涉及Java编程内容。如果大家在Java开发方面的经验不太丰富也没必要担心&#xff0c;只…

Elasticsearch 处理地理信息

1、GeoHash ​ GeoHash是一种地理坐标编码系统&#xff0c;可以将地理位置按照一定的规则转换为字符串&#xff0c;以方便对地理位置信息建立空间索引。首先要明确的是&#xff0c;GeoHash代表的不是一个点而是一个区域。GeoHash具有两个显著的特点&#xff1a;一是通过改变 G…

Map和Set—数据结构

文章目录 1.搜索1.1常见搜索方式1.2模型 2.map2.1介绍2.2 Map.Entry<K, V>2.3map的使用2.4遍历map2.5TreeMap和HashMap的区别 3.set3.1介绍3.2set的使用3.3遍历set3.4 TreeSet和HashSet的不同 4.搜索树4.1概念4.2实现4.3性能分析 5.哈希表5.1查找数据5.2冲突的概念5.3冲突…

如何批量加密PDF文件并设置不同密码 - 批量PDF加密工具使用教程

如果你正在寻找一种方法来批量加密和保护你的PDF文件&#xff0c;批量PDF加密工具是一个不错的选择。 它是一个体积小巧但功能强大的Windows工具软件&#xff0c;能够批量给多个PDF文件加密和限制&#xff0c;包括设置打印限制、禁止文字复制&#xff0c;并增加独立的打开密码。…

LAMP架构介绍配置命令讲解

LAMP架构介绍配置命令讲解 一、LAMP架构介绍1.1概述1.2LAMP各组件的主要作用1.3各组件的安装顺序 二、编译安装Apache httpd服务---命令讲解1、关闭防火墙&#xff0c;将安装Apache所需的软件包传到/opt/目录下2、安装环境依赖包3、配置软件模块4、编译安装5、优化配置文件路径…

数据的深海潜行:数据湖、数据仓库与数据湖库之间的微妙关系

导言&#xff1a;数据的重要性与存储挑战 在这个信息爆炸的时代&#xff0c;数据已经成为企业的核心资产&#xff0c;而如何高效、安全、便捷地存储这些数据&#xff0c;更是每个组织面临的重大挑战。 数据作为组织的核心资产 数据在过去的几十年里从一个辅助工具演变成企业的…