Docker进阶教程 - 1 Dockerfile

更好的阅读体验:点这里 ( www.doubibiji.com

1 Dockerfile

Dockerfile 是做什么的?

我们前面说到,制作镜像的方法主要有两种方式:

  • 使用 docker commit 命令;
  • 使用 Dockerfile 文件。

但是使用 docker commit 命令很麻烦,每次都要进入容器修改容器然后提交。我们可以通过 Dockerfile 通过一条一条的指令和参数来构成脚本文件,通过脚本文件来生成镜像,这样就很方便。


下面就来讲解通过 Dockerfile 来编排镜像。

使用 Dockerfile 是构建镜像的步骤如下:

1、编写一个 Dockerfile 文件;

2、使用 docker build 命令运行脚本文件,构建成为一个镜像;

3、使用 docker run 命令运行镜像;

4、如果需要,可以使用 docker push 命令发布镜像到镜像仓库(DockerHub 、阿里云仓库等)。


1.1 使用Dockerfile构建镜像

在前面我们通过运行 Ubuntu 镜像生成一个容器,在容器中安装 vim 编辑器,然后使用 docker commit 命令生成一个新的镜像。

下面使用 Dockerfile ,基于 Ubuntu22.04,安装 vimifconfig 命令,生成一个新的 Ubuntu 镜像。

1 编写 Dockerfile 文件

随便在一个目录下创建一个文件,例如我在 /home/doubi 目录下,名称为 Dockerfile,名称是固定的,内容如下:

FROM ubuntu:22.04# 更新 apt
RUN apt update# 安装 vim
RUN apt install -y vim# 安装 ifconfig
RUN apt install -y net-tools

FROM 是 Dockerfile 第一行非注释代码,表示我们的镜像是基于哪个镜像来创建的。

RUN 用于在构建镜像的时候运行 Shell 命令,这里运行了三条命令,用来安装 vimifconfig 命令。指令是很简单的。

Dockerfile 中的命令的关键字必须是大写字母,#表示注释。


但是上面的 Dockerfile 可以进行优化,因为构建镜像时,Dockerfile 的每⼀条 RUN 指令都会在镜像上构建⼀层,为了减⼩镜像⽂件⼤⼩,可以将多个 RUN 命令合并为一条命令,从而减少镜像的层数。

所以上面的 Dockerfile 可以改写为如下:

FROM ubuntu:22.04# 安装 vim 和 ifconfig
RUN apt update && apt install -y vim && apt install -y net-tools

2 构建镜像

下面执行 docker build 命令,运行脚本文件,构建成为一个镜像:

docker build -t myubuntu:1.0.0 .			# 后面有一个"点"
  • docker build:这是 Docker 的构建命令,用于根据 Dockerfile 中的指令创建 Docker 镜像;

  • -t myubuntu:1.0.0 :指定构建的镜像的名称为myubuntu,同时设置版本标签为 1.0.0;

  • . :这个参数指定了 Dockerfile 所在的路径,. 表示当前目录。Docker 会在当前目录下寻找名为 Dockerfile 的文件,并根据其中的指令构建镜像。


构建需要一点时间,构建完成,可以看到在本地生成了镜像:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3 运行镜像

镜像已经生成了,下面运行一下使用 Dockerfile 生成的镜像,查看一下是否有 vimifconfig

运行镜像:

docker run -it myubuntu:1.0.0 /bin/bash

运行后,查看容器中是否有 vimifconfig 命令,可以看到我们自己的镜像已经包含了 vimifconfig

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


上面使用 Dockerfile 构建镜像比使用 docker commit 构建镜像方便多了。

1.2 查看官方容器

我们之前使用的 Tomcat、Redis 等容器,在 dockerhub 上查看,其实这些容器也是使用 Dockerfile 来构建的。

例如在 dockerhub 上搜索 redis 容器,进入到容器详情页面,提供了 Dockefile 的链接:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


点击链接可以跳转到容器的 Dockerfile 页面,查看容器 Dockerfile 的详细内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当然对于我们来说一般也不用编写这么复杂的镜像,只需要了解原理,看得懂简单的镜像编写即可。

1.3 Dockerfile 常用命令

上面我们实现了自定义的 Ubuntu 镜像构建,里面用到了 FROMRUN 命令,在 Dockerfile 中还有一些常用的命令。

下面简单的介绍一下常用的命令。

1 FROM

FROM 指令指明构建的新镜像是基于哪个基础镜像,如果没有选择 tag,那么默认值为 latest。

语法:

FROM <image>:<tag>

举个栗子:

构建的镜像是基于 ubuntu22.04 来构建:

# 基于ubuntu22.04来构建镜像
FROM ubuntu:22.04

2 LABEL

LABEL 指令用于向镜像添加元数据,提供关于镜像的描述信息。这些标签可以包含有关项目、维护者、版本、许可证等信息。

语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

举个栗子:

# 使用LABEL向镜像描述信息
LABEL version="1.0" maintainer="doubibiji@qq.com" description="My custom Docker image"

LABEL 指令可以省略,添加也没有实际的影响。

3 RUN

RUN 命令可以在构建镜像时执行命令。这个命令接收两种格式:ShellExec

Shell 形式

语法:

RUN <command>

举个栗子:

构建的新镜像中我们想在 /home/doubi 目录下创建一个 hello 目录。

RUN mkdir -p /home/doubi/hello

也可以执行指令来安装软件、配置环境等。例如安装 vim 命令:

RUN apt update && apt install -y vim

Exec 形式

在 Exec 形式中,命令是一个数组,指定了可执行文件及其参数。这种形式适用于避免 Shell 字符串处理的一些潜在问题,同时也提供了更直观的命令执行方式。

示例:

RUN ["apt", "update", "&&", "apt", "install", "-y", "vim"]

这是与上述 Shell 形式等效的命令,使用哪种格式,看你自己,我还是喜欢 Shell 格式的。

注意:RUN 命令会在执行 docker build 命令的时候执行。每⼀条 RUN 指令都会在镜像上构建⼀层,为了减⼩镜像⽂件⼤⼩,可以将多个 RUN 命令合并为一条命令,从而减少镜像的层数。合并会降低可读性,需要根据实际情况权衡可读性和减小层数之间做个平衡。

4 COPY

COPY 指令可以拷贝文件或目录到镜像中。

语法:

COPY <src> <dest>

举个栗子:复制 jar 包到 镜像文件中:

# 将hello-springboot-0.0.1-SNAPSHOT.jar复制到镜像文件中,目标名称为app.jar
COPY hello-springboot-0.0.1-SNAPSHOT.jar app.jar

5 ADD

ADD 指令可以拷贝文件或目录到镜像中,类似于 COPY,但支持更多功能。

语法:

ADD <src> <dest>

src 可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压。还可以是一个 url,如果把 src 写成一个 url,那么 ADD 就类似于 wget 命令,然后自动下载和解压。

举个栗子:

通过 url 下载文件到镜像的 /tmp/ 目录下,并解压:

ADD https://example.com/file.tar.gz /tmp/

6 WORKDIR

WORKDIR 命令用于设置工作目录,此后的 RUN、CMD、ENTRYPOINT、COPY 、AND 等命令将在这个工作目录下执行。

语法:

WORKDIR 路径

WORKDIR 命令可以多次使用,每次使用都会改变当前工作目录。

举个栗子:

WORKDIR /path/to/directory

如果设置的目录不存在会自动创建。

7 ENV

ENV 命令用于在构建镜像过程中设置环境变量,这些环境变量是一直存在于镜像中的。

语法:

# 格式1
ENV key value
# 格式2:可以使用=
ENV key1=value1 key2=value2

举个栗子:

# 设置一个名为 "WORK_HOME" 的环境变量
ENV WORK_HOME /home/doubi# 引用WORK_HOME环境变量
WORKDIR $WORK_HOME

环境变量可以在后续的RUN、WORKDIR命令中使用。

如果在 Dockerfile 中使用 ENV 指令设置了环境变量,那么在使用 docker run 命令的时候,可以使用 -e 参数覆盖 Dockerfile 中设置的值。这在需要动态配置容器时非常有用,比如根据运行时的条件来设置不同的环境变量值。

举个栗子:

# 设置Spring Boot配置文件环境变量,默认为dev  
ENV SPRING_PROFILES_ACTIVE=prod  

在运行容器的时候,可以使用 -e 参数覆盖 Dockerfile 中的环境变量:

docker run -d -e SPRING_PROFILES_ACTIVE=dev -p 8080:8080 my_image

8 ARG

ARG 命令与 ENV 命令作用一样,和 ENV 命令不同的是:这些变量只在构建过程中有效,构建完成后不会被保留在最终的镜像中。

语法:

ARG key[=value]
  • name :参数的名称。
  • default_value :参数的默认值,可以缺省。

构建过程中,ARG 定义的参数可以用于在 Dockerfile 中的各个指令中,并在 docker build 命令中被覆盖。它对于在构建时动态地传递参数非常有用。

举个栗子:

# 定义构建参数  
ARG VERSION=latest  
ARG BUILD_DATE  # 使用构建参数设置环境变量  
ENV APP_VERSION=$VERSION  
ENV BUILD_DATE=$BUILD_DATE 

在构建的时候,可以通过 --build-arg 传递参数:

# 可以传递多个参数
docker build --build-arg VERSION=1.0.0 --build-arg BUILD_DATE=$(date) -t my-image .

9 EXPOSE

EXPOSE 命令的作用就是对外暴漏端口。但是并不是打开端口,而是声明,实际还是在运行 docker run 命令的时候,通过 -p 参数指定。

语法:

EXPOSE <port> [<port>/<protocol>...]
  • <port>:要暴露的端口号。
  • <protocol>:可选参数,指定要使用的协议(如 tcpudp)。

举个栗子:

# 暴露80端口
EXPOSE 80# 暴露多个端口
EXPOSE 80 443# 指定端口和协议
EXPOSE 8080/tcp

可以一次指定多个端口,或者指定多个端口和协议的组合。

10 CMD

CMD 命令用于为容器指定默认的执行命令或应用程序。当容器启动时,这个命令将被执行,可以用来启动容器中的应用程序。

什么意思,是不是有点蒙?

前面的 RUN 命令是在构建镜像的时候执行,也就是执行 docker build 命令的时候执行;而 CMD 命令是启动容器的时候执行,也就是执行 docker run 命令的时候执行。

查看官方的 Tomcat 镜像的 Dockerfile,可以看到最后一行脚本是:

CMD ["catalina.sh", "run"]

catalina.sh run 命令也就是启动 Tomcat 的命令。如果没有这行命令,在使用 docker run 命令启动 Tomcat 容器的时候,容器是启动起来了,但是容器中的 Tomcat 没有被启动。所以 CMD 命令可以用来启动容器中的应用程序的。

如果在 Dockerfile 中存在多个 CMD 命令,只有最后一个会生效。


CMD 命令的语法和 RUN 命令相似,也支持 ShellExec 两种格式:

# Shell格式
CMD <command># Exec格式
CMD ["参数1", "参数2", ...]

需要注意:CMD中定义的命令会被 docker run 之后的参数替换

什么意思呢?看下面的指令:

docker run -it -p 8080 tomcat /bin/bash

上面的 /bin/bash 就是 docker run 之后的参数,会替换掉 Tomcat Dockerfile文件中的 CMD ["catalina.sh", "run"] 命令中的参数,导致容器启动了,但是 Tomcat 没有被启动,所以一定要注意。

11 ENTRYPOINT

ENTRYPOINT 命令用于指定容器启动时执行的命令,它与 CMD 命令有些相似。同样在一个 Dockerfile 中只能有一个 ENTRYPOINT 命令。如果在 Dockerfile 中定义了多个 ENTRYPOINT,则只有最后一个 ENTRYPOINT 命令会生效,而之前的将被忽略。

ENTRYPOINT 命令也支持 ShellExec 两种格式:

# Shell格式
ENTRYPOINT <command># Exec格式
ENTRYPOINT ["参数1", "参数2", ...]

但是 ENTRYPOINTCMD 有一些关键的区别。

前面说到 CMD中定义的命令会被 docker run 之后的参数替换,但是ENTRYPOINT 命令不会。如果用户在运行容器时提供了命令,那么这些用户提供的命令将作为参数传递给 ENTRYPOINT 指定的命令。

举个栗子,比如我们的 Dockerfile 中有如下命令:

ENTRYPOINT ["echo", "Hello, Docker!"]

那么在使用 docker run 命令运行镜像的时候,后面添加了 “Custom command” 参数:

# 启动容器
docker run -it my-image "Custom command"

那么启动容器执行的指令将会是 echo "Hello, Docker!" "Custom command"


ENTRYPOINT 可以和 CMD 一起使用,当需要使用变参的时候,可以使用 CMDENTRYPOINT 传递参数,此时的 CMD 作用发生了变化,不再是运行命令,而是将 CMD 的内容作为参数传递给 ENTRYPOINT 命令。

举个栗子:

FROM nginxENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]

上面的 Dockerfile,在运行容器的时候,相当于执行了指令 nginx -c /etc/nginx/nginx.confCMD 的内容作为参数传递给 ENTRYPOINT 命令。

如果想要在运行容器的时候,传递参数,覆盖 /etc/nginx/nginx.conf,使用另外一个配置文件,那么可以在启动容器的时候指定参数:

docker run -it mynginx -c /etc/nginx/new.conf

那么相当于执行了指令 nginx -c /etc/nginx/new.conf

12 VOLUME

VOLUME 命令用来做匿名挂载,在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

语法:

# 方式1
VOLUME <路径># 方式2
VOLUME <路径1> <路径2># 方式3
VOLUME ["<路径1>", "<路径2>"...]

一个 Dockerfile 可以包含多个 VOLUME 命令,指定多个需要持久化存储的目录。

举个栗子:

FROM ubuntu:latest
VOLUME /data
VOLUME /config

在运行容器时,你可以使用 -v 选项来将宿主机上的目录挂载到 VOLUME 声明的目录上。例如:

docker run -v /host/data:/data -v /host/config:/config my-image

1.4 构建Tomcat镜像

dockerhub 上已经有了 Tomcat 镜像了,这里我们只是为了学习 Dockerfile 的常用命令,使用上面的命令构建我们自己的 Tomcat 镜像。

1 准备文件

查看 Tomcat 官方镜像的 Dockerfile,100多行很复杂,因为官方镜像是在 Dockerfile 中下载和安装 Tomcat,这里我们简单一点,先下载好 Tomcat 安装包,然后将安装包使用 ADD 命令将安装包拷贝到镜像中。

所以首先在 Tomcat 官网下载安装包,官网: https://tomcat.apache.org/

这里我下载 Tomcat10 的 apache-tomcat-10.1.19.tar.gz 包。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2 编写Dockerfile

下面开始编写 Dockerfile:

# 设置基础镜像为 Ubuntu 22.04  
FROM ubuntu:22.04  # 设置环境变量,防止在安装时有提示  
ARG DEBIAN_FRONTEND=noninteractive  # 更新软件包列表  
RUN apt-get update \  # 安装jdk  && apt install -y openjdk-17-jdk-headless \# 安装软件包之后清理APT缓存&& rm -rf /var/lib/apt/lists/*# 设置工作目录  
WORKDIR /opt  # 使用 ADD 命令拷贝并解压 Tomcat 压缩包  
ADD apache-tomcat-10.1.19.tar.gz /opt/  # 重命名解压后的目录
RUN mv apache-tomcat-10.1.19 tomcat# 暴露 Tomcat 默认的端口  
EXPOSE 8080  # 启动 Tomcat  
CMD ["/opt/tomcat/bin/catalina.sh", "run"]

上面的 RUN 命令如果太长,可以使用 \ 进行换行。

Tomcat 需要 JDK,所以先安装 JDK,然后将 apache-tomcat-10.1.19 添加到镜像中,然后启动 Tomcat,学了 Dockerfile 常用的命令,上面的脚本还是容器看得懂的。

3 构建镜像

Dockerfile 编写完成了,下面执行 docker build 命令,来构建镜像。

这里需要将 apache-tomcat-10.1.19.tar.gz 包和 Dockerfile 放在宿主机的同一个目录下,然后执行 docker build 命令:

docker build -t my-tomcat:10.1.19 .			# 后面有个点

构建如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4 运行容器

镜像已经构建完成,下面运行容器:

docker run -d -p 8080:8080 my-tomcat:10.1.19

运行后,可查看正在运行的容器:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5 访问Tomcat

运行容器后,可以访问宿主机的8080端口,来访问 Tomcat 了:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

完成!

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

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

相关文章

leetcode每日一题310.最小高度树

目录 一.题目原型 二.题目思路 三.代码实现 一.题目原型 二.题目思路 首先&#xff0c;我们看了样例&#xff0c;发现这个树并不是二叉树&#xff0c;是多叉树。 然后&#xff0c;我们可能想到的解法是&#xff1a;根据题目的意思&#xff0c;就挨个节点遍历bfs&#xff0c;…

瑞_Redis_短信登录_Redis代替session的业务流程

文章目录 项目介绍1 短信登录1.1 项目准备1.2 基于Session实现登录流程1.3 Redis代替session的业务流程1.3.1 设计key的结构1.3.2 设计key的具体细节1.3.3 整体访问流程1.3.4 代码实现 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《Redis》的实战篇的短信登录章节的R…

springboot项目读取excel表格内容到数据库,excel表格字段为整数的读取方法

在我昨天的项目中&#xff0c;我需要把excel表格中字段为整数的字段读取到数据库中进行保存&#xff0c;但是在内置方法中并没有读取整数的方法&#xff08;也有可能是我没发现&#xff0c;太菜了~~&#xff09;&#xff0c;那接下来我就提供给大家一个简单地方法来读取excel表…

Apache-Doris基础概念

OLAP数据库Doris 一、Doris架构二、基本概念1. Row & Column2. Partition & Tablet3. 建表示例&#xff08;1&#xff09;列的定义&#xff08;2&#xff09;分区分桶&#xff08;3&#xff09;多列分区&#xff08;4&#xff09;PROPERTIES&#xff08;5&#xff09;E…

【LabVIEW FPGA入门】单周期定时循环

单周期定时循环详解 单周期定时环路是FPGA编程中最强大的结构之一。单周期定时循环中的代码更加优化&#xff0c;在FPGA上占用更少的空间&#xff0c;并且比标准While循环中的相同代码执行得更快。单周期定时环路将使能链从环路中移除&#xff0c;以节省FPGA上的空间。…

windows下使用tree指定层数生成项目结构

windows自带的tree太辣鸡了&#xff0c;我们需要找东西代替 工具链接 Tree for Windows (sourceforge.net) 点击这里下载 置入Git 解压下载的压缩包&#xff0c;将bin目录下的exe复制下来 进入你的Git目录&#xff0c;将其放入Git目录下的usr/bin目录下 打开Git Bash 输入…

如何在Mac中删除照片?这里有详细步骤

前言 本文介绍如何从Mac中删除照片,以释放硬盘空间或更好地组织文件和文件夹。 如何使用废纸篓删除Mac上的图片 在Mac上删除图片的最简单方法之一是使用废纸篓功能。学习只需几秒钟。下面是如何删除单个图片以及如何在Mac上删除多个图片,以及一些关键和有用的提示,以使该…

Selenium-webdriver_manager判断是否已经下载过驱动(复用缓存驱动)

1,谷歌浏览器默认位置 2&#xff0c;ChromeDriverManager 下载的驱动位置 其中admin为机器的用户名 def installDriver(self):"""判断是否需要下载driver""""""找到本机谷歌浏览器版本""""""C:\P…

【学习心得】Python数据分析的基本思路

一、什么是数据分析&#xff1f; 数据分析是指通过一些方法&#xff0c;对一些数据进行分析&#xff0c;从中提取出有价值的信息并形成结论进行展示。 &#xff08;1&#xff09;一些方法 数学和统计学方法&#xff1a;例如回归分析、聚类分析、主成分分析、时间序列分析等&a…

机器人路径规划:基于改进型A*算法的机器人路径规划(提供Python代码)

一、A*算法介绍 A*算法最早可追溯到1968年&#xff0c;在IEEE Transactions on Systems Science and Cybernetics中的论文A Formal Basis for the Heuristic Determination of Minimum Cost Paths中首次提出。 https://blog.csdn.net/weixin_46204734/article/details/1367905…

Windows 网络质量测试

Windows 网络质量测试 References 保证网络稳定性&#xff0c;建议最大数据包延迟 200ms 以内&#xff0c;数据包最大和最小延迟差 100ms 以内&#xff0c;丢包率最好不丢包或 5% 以内。 ping www.baidu.com -t 调出 运行 (快捷键 Win R)&#xff0c;输入 cmd&#xff0c;pi…

黑马程序员——javase进阶——day08——异常,多线程,Lambda,Stream,File,递归

目录&#xff1a; 异常的概述 什么是异常异常的存在的形式程序中异常产生后&#xff0c;是如何处理的异常的分类异常的处理方式 JVM处理异常的方式手动处理异常方式 声明异常抛出异常捕获异常Throwable的成员方法异常练习自定义异常 概述实现步骤自定义异常注意多线程入门 多线…

文献阅读笔记:SAM大模型(Segment Anything)

文献阅读笔记&#xff1a;SAM大模型&#xff08;Segment Anything&#xff09; 摘要Abstract1. SAM大模型1.1 文献摘要1.2 引言1.3 SAM大模型网络结构1.4 实验1.4.1 零样本单点有效掩码评估1.4.2 零样本边缘检测1.4.3 零样本对象提议1.4.4 零样本通过文本提示预测mask 1.5 SAM模…

27-2 文件上传漏洞 - 前端绕过

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 前端绕过思路 - 禁用 JavaScript: 背景: 当前开发行业大多采用前后端分离模式,后端使用多种开发语言如 PHP、Java 等,而前端主要使用 JavaScript(JS)。因此,禁用 JavaScrip…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的火焰与烟雾检测系统详解(深度学习模型+UI界面升级版+训练数据集)

摘要&#xff1a;本研究详细介绍了一种集成了最新YOLOv8算法的火焰与烟雾检测系统&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行性能评估对比。该系统能够在包括图像、视频文件、实时视频流及批量文件中准确识别火焰与烟雾。文章深入探讨了YOLOv8算法的原理&#xff0…

误删电脑C盘要重装系统吗 误删电脑C盘文件怎么恢复 误删c盘系统文件怎么修复 不小心删除C盘的东西恢复

C盘通常是操作系统(如Windows)的默认安装目录。它包含了操作系统的核心文件、驱动程序及系统所需的各种支持文件。这些文件对于计算机的正常运行至关重要。如果我们不小心将C盘的重要文件删除&#xff0c;会导致应用无法打开。本篇文章&#xff0c;我们将学习误删电脑C盘要重装…

面试算法-39-删除链表的倒数第 N 个结点

题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 解 class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {L…

基于支持向量机SVM的沉降预测,SVM详细原理,Libsvm详解

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 完整代码和数据下载链接:基于支持向量机SVM的沉降预测资源-CSDN文库 https://download.csdn.net/download/abc991835105/88947544 SVM应用实例,基于支持向量机SVM的沉降预测…

指挥航空公司架次与延误率占比

打开前端Vue项目kongguan_web&#xff0c;创建前端 src/components/Delay.vue 页面&#xff0c;并添加柱状图与折线图叠加&#xff0c;设置双Y轴。 页面div设计&#xff0c;代码如下&#xff1a; <template><div><div class"home"><div id&qu…

关于volatile与指令重排序的探讨

写在开头 在之前的学习我们了解到&#xff0c;为了充分利用缓存&#xff0c;提高程序的执行速度&#xff0c;编译器在底层执行的时候&#xff0c;会进行指令重排序的优化操作&#xff0c;但这种优化&#xff0c;在有些时候会带来 有序性 的问题。 那何为有序性呢&#xff1f;…