【精选】项目管理工具——Maven详解

news2024/11/15 17:49:22

Maven简介

在这里插入图片描述

Maven是一个项目管理工具。它可以帮助程序员构建工程,管理jar包,编译代码,完成测试,项目打包等等。

  • Maven工具是基于POM(Project Object Model,项目对象模型)实现的。在Maven的管理下每个项目都相当于是一个对象。
  • Maven标准化了项目的构建。即对项目结构,构建命令等进行了标准化定义。
  • Maven提供了一个免费的中央仓库,在其中几乎可以找到任何的流行开源类库。
  • Maven是跨平台的,在Windows、Linux、Mac上,都可以使用同样的命令。

Maven的作用

在这里插入图片描述

一键构建

我们的项目往往都要经历编译、测试、运行、打包、安装 ,部署等一系列过程,这些过程称之为构建。通过Maven工具,可以使用简单的命令轻松完成构建工作。

依赖管理

传统的Web项目中,我们必须将工程所依赖的jar包复制到工程中,导致了工程的变得很大。如果一个公司具有相同架构的项目有十个,那么就需要将这一份jar包复制到十个不同的工程中,非常浪费资源。

同样的项目内容,传统Web项目大小如下:

而使用Maven构建的项目大小如下:

这说明了传统Web项目中大部分磁盘空间是被jar包占据,而Maven项目中一定没有jar包,那没有jar包的项目是怎么运行的呢?

maven工程中不直接将jar包导入到工程中,而是有一个专门存放jar包的仓库,仓库中的每个jar包都有自己的坐标。maven工程中只要配置jar包坐标即可,运行项目需要使用jar包时,根据坐标即可从maven仓库中拿到jar包即可运行。

Maven工程的类型和结构

Maven工程类型

  • POM工程

    POM工程是逻辑工程,Maven并不会对该类型工程做打包处理,这些工程往往不包含具体的业务,而是用来整合其他工程的。

  • JAR工程

    普通Java工程,在打包时会将项目打成jar包。

  • WAR工程

    JAVA Web工程,在打包时会将项目打成war包。

Maven工程结构

接下来我们通过一个WAR工程学习Maven工程的结构

文件目录结构:

  • src:源代码
  • target:编译生成的文件
  • pom.xml:Maven工程配置文件,如坐标信息等。

项目结构:

  • src/main/java:存放项目的java 文件
  • src/main/resources:存放项目资源文件,如配置文件
  • src/test/java:存放项目的测试文件
  • src/test/resources:存放测试时的资源文件

一键构建

项目的生命周期

使用maven完成项目的构建的过程中,包括:验证、编译、测试、打包、部署等过程,maven将这些过程规范为项目构建的生命周期。

在这里插入图片描述

生命周期所做工作
验证 validate验证项目是否正确
编译 compile源代码编译
测试 Test使用适当的单元测试框架(例如junit)运行测试。
打包 package创建JAR/WAR包
检查 verify对集成测试的结果进行检查,以保证质量达标。
安装 install安装打包的项目到本地仓库,以供其他项目使用。
部署 deploy拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。

maven有三套相互独立的生命周期。分为是构建生命周期,clean生命周期(清理构建后的文件)、site生命周期(生成项目报告)。作为开发人员我们一般重点学习构建生命周期即可。

Maven常用命令

在Maven构建项目的每一步都可以使用一句简单的命令完成,接下来我们学习这些命令:

命令作用
mvn clean清除编译的class文件,即删除target目录。
mvn validate验证项目是否正确
mvn compile编译maven项目
mvn test编译maven项目及运行测试文件
mvn package编译maven项目及运行测试文件,并打包
mvn install编译maven项目及运行测试文件并打包,并发布到本地仓库
mvn deploy部署项目到远程仓库
mvn tomcat7:run使用tomcat运行项目

Maven依赖插件来执行命令,比如clean、validate等命令是maven自带的,tomcat7命令是引入的第三方插件。

依赖管理

Maven仓库类型

本地仓库

本地仓库指用户计算机中的文件夹。用来存储从远程仓库或中央仓库下载的jar包,只有下载到本地仓库的jar包才能使用,项目使用jar包时优先从本地仓库查找。

远程仓库

远程仓库一般指私服,它是架设在局域网的仓库服务,可以从中央仓库下载资源,供局域网使用,从而减少每个程序员都从中央仓库下载浪费的带宽。

如果项目需要的jar包本地仓库没有,则会去远程仓库下载,下载到本地仓库即可使用。

远程仓库不是必须配置的,如果本地仓库没有jar包,也没有配置远程仓库,则会直接从中央仓库下载。

中央仓库

中央仓库是互联网上的服务器,是Maven提供的最大的仓库,里面拥有最全的jar包资源。

如果项目需要的jar包,本地仓库和远程仓库都没有,则会去中央仓库下载,下载到本地仓库使用。

Maven中央仓库访问页面:https://mvnrepository.com/

中央仓库访问速度较慢,我们一般都会配置镜像代理中央仓库的下载请求,如阿里镜像、华为镜像等。

Maven配置文件

本地仓库的默认位置是${user.dir}/.m2/repository${user.dir}表示 windows用户目录,我们可以通过修改${MAVEN_HOME}\conf\settings.xml,修改本地仓库的位置。

配置本地仓库

<settings>中添加如下标签:

<!-- 本地仓库路径 -->
<localRepository>F://repository</localRepository>

配置镜像

由于中央仓库访问速度较慢,可以配置镜像代理中央仓库的下载请求。在<settings>下的<mirrors>中添加如下标签即可配置镜像:

<mirror> 
  <!-- 指定镜像ID -->
  <id>nexus-aliyun</id> 
  <!-- 匹配中央仓库。-->
  <mirrorOf>central</mirrorOf>
  <!-- 指定镜像名称 -->  
  <name>Nexus aliyun</name> 
  <!-- 指定镜像路径 -->
<url>http://maven.aliyun.com/nexus/content/groups/public</url> 
</mirror>

配置JDK版本

创建maven项目的时候,默认使用的JDK是1.5版本,验证语法、编译、运行时都会按照JDK1.5操作,这样就有很多语法无法使用。我们本机安装的JDK是JDK11,可以配置maven按照JDK11创建项目。

<settings>下的<profiles>中添加如下标签即可配置JDK版本:

<profile>  
  <id>jdk11</id>  
  <activation>  
    <activeByDefault>true</activeByDefault>  
    <jdk>11</jdk>  
  </activation>  
  <properties>  
    <maven.compiler.source>11</maven.compiler.source>  
    <maven.compiler.target>11</maven.compiler.target>  
    <maven.compiler.compilerVersion>11</maven.compiler.compilerVersion>  
  </properties>  
</profile>

pom文件配置

pom文件最上方是项目基本信息:

  • groupId

    groupId一般定义项目组名,命名规则使用反向域名。例如com.java

  • artifactId

    artifactId一般定义项目名,命名使用小写字母。项目发布后,它的坐标是groupId+artifactId。

  • version

    version定义版本号。版本号一般有三段,第一段:革命性的产品升级。第二段:新功能版本。第三段:修正一些bug。

  • packaging

    packaging定义打包方式。

<properties>中定义一些配置信息:

<dependencies>中定义依赖的jar包坐标:

由于项目是web项目,需要写Servlet和JSP,所以需要引入Servlet和JSP的依赖。查找依赖坐标的网站:https://mvnrepository.com/

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <!-- jsp -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
  </dependency>
  <!-- servlet -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
  </dependency>
</dependencies>

为什么之前的web项目中没有引入jsp和servlet的jar包?

因为之前项目中使用的是tomcat中的jsp和servlet中的jar包,在项目中没有引入。

<plugins>中定义第三方插件:

web项目依赖tomcat运行,所以添加tomcat7插件

<plugins>
  <!-- tomcat插件 -->
  <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
      <port>8080</port>
      <path>/</path>
      <uriEncoding>UTF-8</uriEncoding>
      <server>tomcat7</server>
    </configuration>
  </plugin>
</plugins>

编写代码

接下来编写Servlet和Jsp代码:

@WebServlet("/demo1")
public class MyServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.getRequestDispatcher("hello.jsp").forward(req,resp);
   }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>测试</title>
  </head>
  <body>
    <h1>你好,程序员!</h1>
  </body>
</html>

运行项目,按照如图步骤,配置使用maven中的tomcat7插件运行项目:

点击OK后配置完成,点击Idea的运行符号即可使用maven中的tomcat7插件运行项目。

依赖范围

访问servlet后,发现报500异常,这是为什么呢?

这是由于项目中引入了Servlet和Jsp的jar包,而在项目运行时,Tomcat要使用它自带的Servlet和Jsp的jar包,这样就造成了jar包冲突。但如果项目不引入Servlet和Jsp的jar包,则根本无法通过编译。

此时可以设置依赖的作用范围解决该问题,设置Servlet和Jsp的jar包只在编译期起作用,运行时不起作用,这样不仅可以通过编译,还能在运行时避免jar包冲突。

通过在<dependency>中添加<scope>,可以设置依赖的作用范围,有以下取值:

  • compile

    默认范围。表示该依赖在编译和运行时生效,项目打包时也会将该依赖打包进去。

  • provided

    使用此依赖范围的Maven依赖,编译和测试时有效,但在运行时无效。典型的例子是servlet-api,在运行时Web容器已经提供依赖,就不需要Maven重复地引入一遍。

  • runtime

    runtime范围表明编译时不需要生效,而只在运行时生效。典型的例子是JDBC驱动包,编译时只需要JDK的JDBC接口即可,只有运行项目时才需要具体的JDBC驱动。

  • test

    test范围表明使用此依赖范围的依赖,只在编译和运行测试代码的时生效,程序的正常运行不需要此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。

  • system

    如果有些你依赖的jar包没有Maven坐标的,它完全不在Maven体系中,这时候你可以把它下载到本地硬盘,然后通过system来引用。(不推荐使用)

所以对于Servlet和Jsp依赖,我们添加依赖范围为provided即可。

<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.0.1</version>
  <scope>provided</scope>
</dependency>

重启项目,即可正常访问Servlet和Jsp

Maven工程测试

测试概述

测试即在交付前对写好的代码进行评测,分为黑盒测试和白盒测试:

  • **黑盒测试:**不需要写代码,给输入值,看程序是否能够输出期望的值。
  • **白盒测试:**需要写代码的。关注程序具体的执行流程。

单元测试是指对软件中的最小可测试单元进行检查和验证,Java里单元测试指一个类的功能。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

Junit是Java编程语言的单元测试框架,用于编写和运行可重复的自动化测试。从分类中属于白盒测试。

Junit使用步骤

在Maven项目中引入依赖
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
	
定义被测试的类

我们定义一个计算器工具类。

public class Calculator {
  // 加法
  public int add(int a,int b){
    return a+b;
   }
  // 除法
  public int div(int a,int b){
    return a/b;
   }
}

对定义的类进行测试
  1. 创建src/test/java包,并将改包设置为测试包。

  2. 在src/test/java中创建测试类的包,包名一般与被测试包名一致。

  3. 定义测试类,类名一般为被测试类+Test

  4. 测试类中编写测试方法。

public class CalculatorTest {
  /**
   * 测试方法是可以独立运行的,写法如下:
   * 1.方法名一般为test+被测试方法名
   * 2.方法上方添加@Test
   * 3.测试方法没有参数和返回值
   */
  @Test
  public void testAdd(){
    Calculator calculator = new Calculator();
    int add = calculator.add(1, 2);
    System.out.println(add);
   }


  @Test
  public void testDiv(){
    Calculator calculator = new Calculator();
    int div = calculator.div(2,0);
    System.out.println(div);
   }
}

Junit结果判定

点击测试方法边的三角运行测试方法,如果出现绿色对钩,证明方法能正常运行;如果出现红色感叹号,证明方法抛出异常,需要修改方法。

当然,不是能正常运行就代表方法一定没有问题,也有可能方法的结果和预期结果不一致,这时就需要使用断言操作。

断言操作:Assert.assertEquals(参数1,参数2);

参数1:预期结果,参数2:实际结果

@Test
public void testAdd(){
  Calculator calculator = new Calculator();
  int add = calculator.add(1, 2);
  /**
   * 断言
   * 参数1:预期结果,参数2:实际结果
   */
  Assert.assertEquals(2,add);
}

如果真实结果和预期结果不一致,则会抛出以下异常:

@Before、@After注解

在测试类中,@Before修饰的方法会在测试方法之前自动执行,@After修饰的方法会在测试方法执行之后自动执行。之后的学习中,我们可以设置前置方法为获取资源,后置方法为释放资源。

@Before
public void before(){
  System.out.println("开始测试");
}


@After
public void after(){
  System.out.println("结束测试");
}

依赖冲突

依赖冲突产生的原因:依赖传递

假设你的项目依赖jar包A,jar包A又依赖jar包B。当添加jar包A时,Maven会把jar包B也自动加入到项目中。比如刚刚我们添加了junit依赖,junit又依赖hamcrest,所以Maven会将junit和hamcrest都加入项目中。

这时就可能会产生依赖冲突问题,比如依赖A会引入依赖C,依赖B也会引入依赖C。如果不进行调解则会引入两个依赖C,那么Maven是如何解决依赖冲突问题的呢?

依赖冲突调解

我们以Spring依赖为例,spring-webmvc依赖spring-aop,spring-context也依赖spring-aop,如果两个同时引入,会引入哪个版本的spring-aop呢?

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.12.RELEASE</version>
</dependency>


<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>

最先声明原则

最短路径优先原则不能解决所有问题,比如这样的依赖关系:A–>B–>C(1.0)D–>E–>C(2.0),同时引入A和D之后,C(1.0)和C(2.0)的依赖路径长度都为2。此时第一原则将不能解决问题

Maven调解依赖冲突的第二原则是最先声明原则:

在依赖路径长度相等的前提下,在POM中依赖声明的顺序靠前的会被解析使用。比如:以上案例中,spring-webmvc和spring-context到spring-core的路径都为1。谁声明在上方,spring-core会按照谁的版本引入。

排除依赖、锁定版本

如果不想使用Maven默认的冲突调解方式,有两种方式可以手动进行冲突调解。

排除依赖

比如以上案例中,想使用spring-webmvc的spring-aop包,那么可以让spring-context引入时排除引入spring-aop包,这样就可以使用spring-webmvc的spring-aop包了,写法如下:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.12.RELEASE</version>
  <exclusions>
    <exclusion>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
    </exclusion>
  </exclusions>
</dependency>

锁定版本

在Maven中为某个jar包配置锁定版本后,不考虑依赖的声明顺序和依赖路径,以锁定的版本的为准添加到工程中,此方法在企业开发中常用。以下可以直接配置spring-aop锁定的版本。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
  </dependencies>
</dependencyManagement

Maven聚合开发

聚合关系

之前我们在Idea中开发时会将项目的所有包放在同一个工程当中。

  • domain:定义实体类
  • dao:操作数据库
  • service:具体的业务逻辑,需要调用dao的方法。
  • controller:前后端交互,需要调用service的方法。
  • webapp:存放前端资源

假如我们现在写了两个项目分别是电商卖家端和电商买家端,两个项目都需要调用serive层查询订单的方法。原来的写法如下:

重复编码造成开发效率降低。

而使用maven后,我们可以把之前的项目按需拆分成一个个小项目,之后将小项目发布到仓库中,小项目之间也可以互相引用,并且在我们的项目中引入需要的小项目即可。

Maven将一个大项目分成一个个小项目开发,最后打包时会将这些小的项目打成一个完整的war包独立运行。

继承关系

Maven中的继承是针对于父工程和子工程。父工程定义的依赖和插件子工程可以直接使用。注意父工程类型一定为POM类型工程。

多继承

在Maven中对于继承采用的也是单继承,也就是说一个子项目只能有一个父项目。但我们可以在<dependencyManagement>配置多继承。写法如下:

<dependencyManagement>
  <dependencies>
    <!--父项目a-->
    <dependency>
      <groupId>com.java</groupId>
      <artifactId>parent_a</artifactId>
      <version>1.0-SNAPSHOT</version*>
      <type>pom</type>
      <!-- 引入父项目,scope的值为import -->
      <scope>import</scope>
    </dependency>


    <!--父项目b-->
    <dependency>
      <groupId>com.java</groupId>
      <artifactId>parent_b</artifactId>
      <version>1.0-SNAPSHOT</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】前言

数据结构是在计算机中维护数据的方式。 数据结构是OI重要的一部分。 同的数据结构各有优劣&#xff0c;能够处理的问题各不相同&#xff0c;而根据具体问题选取合适的数据结构&#xff0c;可以大大提升程序的效率。 所以&#xff0c;学习各种各样的数据结构是很有必要的。 数据…

车载通信架构 —— 新车载总线类型下(以太网)的通信架构

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

Azure Machine Learning - Azure AI 搜索中的集成数据分块和嵌入

在基于索引器的索引编制中&#xff0c;Azure AI _集成矢量化_将数据分块和文本到矢量嵌入添加到技能中&#xff0c;它还为查询添加文本到矢量的转换。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本…

栈与队列:设计循环队列

目录 题目&#x1f525;&#xff1a; 数据模型&#xff1a; 本题大意&#xff1a; 思路分析&#xff1a; 代码分析&#xff1a; 一、定义队列 二、初始化、判断队列的空和满⭐ 初始化&#xff1a; 空满的判断&#xff1a; 三、入队和出队&#x1f387; 入队&…

LeetCode【32】最长的有效括号

题目&#xff1a; 思路&#xff1a; 括号字符串依次入栈&#xff0c;删除匹配的成对括号。最后栈中留下的都是无法匹配的断点。这些断点的差值减一就是断点间有效括号串的长度&#xff0c;取这些长度的最大值即可。 例如括号字符串 “)()((())(”&#xff0c;最后留在栈中的…

比Postman强在哪里

Postman的受众对象主要是广大开发人员&#xff0c;调测使用&#xff0c;它并不能完全满足专业测试人员需求&#xff0c;而自动化测试平台可以 1&#xff0c;Postman&#xff0c;Jmter是单机版软件&#xff0c;类似打游戏你和电脑PK&#xff0c;而很多时候是要联网和其他人团队作…

LeetCode【36】有效的数独

题目&#xff1a; 思路&#xff1a; https://blog.51cto.com/u_15072778/3788083 代码&#xff1a; public boolean isValidSudoku(char[][] board) {// 二维数组第一个标识 0-9行&#xff0c;第二个表示 0-9数字&#xff0c;存的内容boolean 表示第0-9行&#xff0c;0-9这些…

系列十二、强引用、软引用、弱引用、虚引用分别是什么?

一、整体架构 二、强引用&#xff08;默认支持模式&#xff09; 2.1、概述 当内存不足时&#xff0c;JVM开始垃圾回收&#xff0c;对于强引用的对象&#xff0c;就算是出现了OOM也不会对该对象进行回收&#xff0c;死都不收。 强引用是我们最常见的普通对象引用&#xff0c;只…

INFINI Labs 产品更新 | 发布 Easysearch Java 客户端,Console 支持 SQL 查询等功能

近年来&#xff0c;日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志&#xff0c;挖掘日志数据价值&#xff0c;驱动运维、运营&#xff0c;提升服务管理效率。 方案架构 Beats 是轻量级采集器&#xff0c;包括 Filebeat、Metricbeat 等。E…

我叫:选择排序【JAVA】

1.我是个啥子&#xff1f;&#xff1f; 选择式排序&#xff1a;属于内部排序法,从欲排序的数据中,按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 2.我的思想 基本思想:第一次从arr[0]~arr[n-1]中选取最小值&#xff0c;与arr[0]交换&#xff0c;第…

【Promise12数据集】Promise12数据集介绍和预处理

【Segment Anything Model】做分割的专栏链接&#xff0c;欢迎来学习。 【博主微信】cvxiayixiao 本专栏为公开数据集的介绍和预处理&#xff0c;持续更新中。 要是只想把Promise12数据集的raw形式分割为png形式&#xff0c;快速导航&#xff0c;直接看2&#xff0c;4标题即可 …

个人博客添加访问人数以及访问时间-githubpage

layout: post # 使用的布局&#xff08;不需要改&#xff09; title: 个人博客添加访问人数以及访问时间 # 标题 subtitle: 个人博客优化 #副标题 date: 2023-11-18 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 catalog: tr…

centos7 探测某个tcp端口是否在监听

脚本 nc -vz 192.168.3.128 60001 if [ $? -eq 0 ]; thenecho "tcp succeed" elseecho "tcp failed" fi nc -vz 192.168.3.128 60001 探测192.168.3.128服务器上60001 tcp端口, -vz说明是探测TCP的 端口开启的情况 执行脚本 端口禁用情况 执行脚本

054-第三代软件开发-信号槽

第三代软件开发-信号槽 文章目录 第三代软件开发-信号槽项目介绍信号槽实现原理与MFC消息映射机制区别Qt信号槽机制的优缺点 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#x…

Vue中实现div的任意移动

前言 在系统应用中&#xff0c;像图片&#xff0c;流程预览及打印预览等情况&#xff0c;当前视窗无法全部显示要预览的全部内容&#xff0c;设置左右和上下滚动条后&#xff0c;如果用鼠标拖动滚动条&#xff0c;又不太便利&#xff0c;如何用鼠标随意的移动呢&#xff1f; …

Apache ECharts简介

二十九、Apache ECharts 29.1 介绍 Apache ECharts 是一款基于 JavaScript 的数据可视化图表库&#xff0c;提供直观、生动、可交互、可个性化定制的数据可视化图表。 官网地址&#xff1a;https://echarts.apache.org/zh/index.html 常见效果展示&#xff1a; 1). 柱形图 …

定点整数、小数

文章目录 一、定点整数二、定点小数三、定点小数的加/减运算 一、定点整数 二、定点小数 三、定点小数的加/减运算 对两个定点小数A、B进行加法/减法时&#xff0c;需要先转换为补码 计算机硬件如何做定点小数补码的加法&#xff1a;从最低位开始&#xff0c;按位相加&#x…

【评估分级方法】自然断点法(Python实现全代码)

自然断点法 自然断点法有两个称呼&#xff0c;一个就是直接英文名称&#xff0c;叫做“Natural Breaks”&#xff0c;这就不解释了&#xff0c;还有一个称呼就是ArcGIS里面用的&#xff0c;叫做“Jenks”&#xff0c;主要是来源于它的创造者&#xff1a;乔治弗雷德里克詹克斯&…

Vulhub靶场-KIOPTRIX: LEVEL 1.1

目录 环境配置 端口扫描 漏送发现 漏送利用 提权&#xff08;内核漏洞提权&#xff09; 环境配置 环境配置的过程同主页该专栏第一个靶场&#xff0c;不在赘述。 端口扫描 首先通过arp-scan并根据靶机的mac地址确定靶机的IP地址 然后对靶机进行一个扫描 首先扫描到OpenS…

自动驾驶学习笔记(九)——车辆控制

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 控制器设计 比例积分微分控制 线性…