SpringBoot 2.3.x 分层构建 Docker 镜像实践

目录[-]

  • . 一、什么是镜像分层
  • . 二、SpringBoot 2.3.x 新增对分层的支持
  • . 三、创建测试的 SpringBoot 应用
  • . 1、Maven 中引入相关依赖和插件
  • . 2、创建测试的 Controller 类
  • . 3、创建 SpringBoot 启动类
  • . 四、创建两种构建镜像的 Dockerfile 脚本
  • . 1、普通镜像构建脚本文件 dockerfile-number
  • . 2、分层镜像构建脚本文件 dockerfile-layer
  • . 五、使用两种 Dockerfile 构建项目镜像
  • . 1、在服务器一构建普通 Docker 镜像
  • . 2、在服务器二构建分层 Docker 镜像
  • . 六、镜像推送到镜像仓库测试
  • . 1、推送镜像到镜像仓库测试
  • . 2、镜像仓库拉取镜像测试
  • . 七、镜像构建、推送、拉取时间汇总
  • . 1、不使用分层构建镜像
  • . 2、使用分层构建镜像
  • . 3、总结

系统环境:

  • Docker 版本: 19.03.13
  • Open JDK 基础镜像版本: openjdk:8u275
  • 私有的 Harbor 镜像仓库: 自建 Harbor 私库
  • 项目 Github: SpringBoot 2.3.x 分层构建 Docker 镜像示例

参考地址:

  • Docker 官方文档-镜像分层机制介绍

一、什么是镜像分层

镜像的构成

现在一谈起镜像大部分都是指 Docker 引擎构建的镜像,一般 Docker 镜像是由很多层组成,底层是操作系统,然后在其之上是基础镜像或者用户自定义 Dockerfile 脚本中定义的中间层。其中镜像在构建完成后,用户只能对镜像进行读操作,而不能进行写操作,只有镜像启动后变为容器,才能进行读写操作。镜像整体结构,可以观看下图:

 

该图中展示了镜像的基本组成,但是图中这一个个中间层是什么呢?要想了解这些层具体是什么,那得知道如何构建 Docker 镜像了。平时我们构建 Docker 镜像时候,都是编写 Dockerfile 脚本,然后使用 Docker 镜像构建命令,按照脚本一行行执行构建。

如下就是一个 Dockerfile 脚本,脚本内容就构建 Java 项目镜像常用的 Dockerfile 命令:

FROM openjdk:8u275
VOLUME /tmp
ADD target/*.jar app.jar
ENV TZ="Asia/Shanghai"
ENV JAVA_OPTS=""
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS -jar /app.jar"]

有了 Dockerfile 脚本,我们需要执行 Docker 的构建镜像命令对执行 Dockerfile 脚本构建镜像,其中构建镜像的过程如下:

## 构建镜像的命令
$ docker build -t java-test:latest . ## 命令执行的过程
Step 1/7 : FROM openjdk:8u275---> 82f24ce79de6
Step 2/7 : VOLUME /tmp---> Running in a6361fdfc193
Removing intermediate container a6361fdfc193---> a43948bf1b98
Step 3/7 : ADD target/*.jar app.jar---> 18f4bc60818f
Step 4/7 : ENV TZ="Asia/Shanghai"---> Running in cc738aa5865b
Removing intermediate container cc738aa5865b---> 538adb85609e
Step 5/7 : ENV JAVA_OPTS=""---> Running in f8b635d32b2b
Removing intermediate container f8b635d32b2b---> 34e7a8cd7b6e
Step 6/7 : ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"---> Running in 9331cb6e443e
Removing intermediate container 9331cb6e443e---> 232b9c6c1d29
Step 7/7 : ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS -jar /app.jar" ]---> Running in c3a24fba3a10
Removing intermediate container c3a24fba3a10---> a41974d5f0e3

可以看到总共存在 7 个构建步骤,每步都与 Dockerfile 里面一行指令对应。样子和下图相似:

 

如果这时候,我们改变原来 Dockerfile 内容,创建一个新的镜像,其 Dockerfile 如下:

FROM openjdk:8u275
VOLUME /tmp
ADD target/*.jar app.jar
ENV TZ="Asia/Macao"                  #与原来 Dockerfile 不同
ENV JVM_OPTS="-Xmx512m -Xss256k"     #与原来 Dockerfile 不同
ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS -jar /app.jar" ]

执行 Docker 命令构建镜像:

$ docker build -t java-test2:latest .Step 1/6 : FROM openjdk:8u275---> 82f24ce79de6
Step 2/6 : VOLUME /tmp---> Using cache---> a43948bf1b98
Step 3/6 : ADD target/*.jar app.jar---> Using cache---> 18f4bc60818f
Step 4/6 : ENV TZ="Asia/Macao"---> Running in fd98b90a5485
Removing intermediate container fd98b90a5485---> afab3fcdab07
Step 5/6 : ENV JVM_OPTS="-Xmx512m -Xss256k"---> Running in 19a99576fba9
Removing intermediate container 19a99576fba9---> 4eeab7d7c720
Step 6/6 : ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS -jar /app.jar" ]---> Running in 2dba72e1eef4
Removing intermediate container 2dba72e1eef4---> 7c706ecf7698

可以观察到执行过程中,从一开始执行的构建步骤中显示,并没有生成新的中间层镜像,而是直接使用了已经存在的缓存镜像。直至 4⁄6 这部中,由于新的 Dockerfile 与原来 Dockerfile 发生变动,所以这部中间层镜像直接是新创建的,并没有使用缓存中间层镜像。

然后往下观察,发现之后的全部构建都是新创建的中间层镜像,即是脚本最后的一行和原来相同,也没有使用缓存中间层镜像。

上面现象说明,Docker 镜像在构建过程中按照 Dockerfile 自上往下的执行顺序中,如果从最上层开始,其脚本内容和已有的缓存中间层镜像内容一致,就会引入缓存中的中间层镜像(并不是直接复制缓存镜像,而是引入镜像文件地址,多个镜像共享这些中间层镜像)。但是,如果执行过程中中间任意一行镜像构建的内容发生变化,那么当前行和之后的全部行在执行时就不会使用缓存中的中间层镜像,而是全部创建新的镜像。

 

这就是 Docker 镜像中缓存中间层镜像的复用,学会使用缓存构建镜像将大大减少存储空间的占用以及镜像的构建的构建速度,镜像的缓存不仅仅体现在镜像的构建上,在执行”镜像推送”、”镜像拉取”操作时都能观察到其的好处。

  • 镜像缓在镜像推送的体现: 如镜像推送时候,也是将镜像整体构成的中间层镜像并行推送到镜像仓库,如果镜像仓库中已经存某个中间层镜像,那么推送过程就不会再次将该层镜像推送到镜像仓库,而是将仓库中并不存在中间层镜像推送到其中。
  • 镜像缓存在镜像拉取的体现: 在拉取镜像时候,如果本地某个大镜像的中间层镜像的组成中,已经包含新拉取镜像的中间层部分镜像,那么将直接复用本地已经镜像的中间层镜像,不必再将其进行拉取,而本地不存在的中间层镜像将会被继续拉取。

说了这么多,相信大家已经对镜像缓存的使用有了初步了解,那么再谈及为什么需要镜像分层就很好解释,其原因就是 Docker 想提高资源的复用率,将一个大镜像拆分成很多层小镜像组成,以达到镜像中间层的复用的目的。

二、SpringBoot 2.3.x 新增对分层的支持

SpringBoot 2.3.x 以后支持分层打包应用,需要 Pom.xml 中引入 SpringBoot 2.3.x 后的父依赖和使用 SpringBoot 打包插件 spring-boot-maven-plugin,并且开启 layers 功能,然后执行 Maven 编译源码构建 Jar 包,使用该 Jar 包就可以构建基于分层模式的 Docker 镜像:

项目 pom.xml 中引入 SpringBoot 2.3.x 依赖:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.6.RELEASE</version><relativePath/>
</parent>

项目 pom.xml 中引入 spring-boot-maven-plugin 打包插件,并且开启分层功能:

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!--开启分层编译支持--><layers><enabled>true</enabled></layers></configuration></plugin></plugins>
</build>

执行 Maven 命令,构建分层的 JAR 包,命令和平时的 Maven 构建命令相同:

$ mvn install

观察 Jar 结构,可以看到里面多了 classpath.idx 与 layers.idx 两个文件:

  • classpath.idx: 文件列出了依赖的 jar 包列表,到时候会按照这个顺序载入。
  • layers.idx: 文件清单,记录了所有要被复制到 Dokcer 镜像中的文件信息。

根据官方介绍,在构建 Docker 镜像前需要从 Jar 中提起出对应的分层文件到 Jar 外面,可用使用下面命令列出可以从分层 Jar 中提取出的文件夹信息:

$ java -Djarmode=layertools -jar target/springboot-layer-0.0.1.jar list

可用该看到以下输出,下面的内容就是接下来使用分层构建后,生成的 Jar 提取出对应资源后的结构:

dependencies
spring-boot-loader
snapshot-dependencies
application

上面即是使用分层工具提取 Jar 的内容后生成的文件夹,其中各个文件夹作用是:

  • dependencies: 存储项目正常依赖 Jar 的文件夹。
  • snapshot-dependencies: 存储项目快照依赖 Jar 的文件夹。
  • resources: 用于存储静态资源的文件夹。
  • application: 用于存储应用程序类相关文件的文件夹。

三、创建测试的 SpringBoot 应用

创建测试的 SpringBoot 项目,并且在 pom.xml 中开启镜像分层。

1、Maven 中引入相关依赖和插件

<?xml version="1.0" encoding="UTF-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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.6.RELEASE</version></parent><artifactId>springboot-dockerfile-layer</artifactId><packaging>jar</packaging><name>springboot-dockerfile-layer</name><description>springboot build layer example</description><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><layers><enabled>true</enabled></layers></configuration></plugin></plugins></build></project>

2、创建测试的 Controller 类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("/hello")public String hello() {return "hello world!";}}

3、创建 SpringBoot 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

四、创建两种构建镜像的 Dockerfile 脚本

为了方便体现出 SpringBoot 2.3.x 支持的分层构建 Dockerfile 的优点,这里在 Java 源码文件夹下,创建普通与分层两种构建镜像的 Dockerfile 脚本,后续会使用这两种脚本构建 Docker 镜像进行构建速度、推送速度、拉取速度的对比。

1、普通镜像构建脚本文件 dockerfile-number

FROM openjdk:8u275
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV TZ="Asia/Shanghai"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • JVM_OPTS: 指定 JVM 启动时候的参数,-XX:MaxRAMPercentage 参数和 -Xmx 类似,都是限制堆内存大小,只不过 -Xmx 需要手动指定限制大小,而 -XX:MaxRAMPercentage 则是根据虚拟机可用内存百分比限制。
  • JAVA_OPTS: 在镜像启动时指定的自定义 Java 参数,例如 -Dspring.application.name=xxx。

2、分层镜像构建脚本文件 dockerfile-layer

FROM openjdk:8u275 as builder
WORKDIR application
COPY target/*.jar application.jar
RUN java -Djarmode=layertools -jar application.jar extractFROM openjdk:8u275
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/application/ ./
ENV TZ="Asia/Shanghai"
ENV JVM_OPTS="-XX:MaxRAMPercentage=80.0"
ENV JAVA_OPTS=""
ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]

说明:

  • TZ: 时区设置,而 Asia/Shanghai 表示使用中国上海时区。
  • -Djarmode=layertools: 指定构建 Jar 的模式。
  • extract: 从 Jar 包中提取构建镜像所需的内容。
  • -from=builder 多级镜像构建中,从上一级镜像复制文件到当前镜像中。

五、使用两种 Dockerfile 构建项目镜像

1、在服务器一构建普通 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.1 .

Docker 镜像构建总共花费 24.98s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.2 .

Docker 镜像构建总共花费 1.27s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-normal:0.0.3 .

Docker 镜像构建总共花费 1.32s 时间。

2、在服务器二构建分层 Docker 镜像

(1)、第一次构建

## 执行 Maven 命令,将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.1 .

Docker 镜像构建总共花费 26.12s 时间。

(2)、第二次构建(修改依赖 pom.xml 文件)

## 修改 pom.xml 里面的依赖,随意添加一个新的依赖包,然后再次将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.2 .

Docker 镜像构建总共花费 3.44s 时间。

(3)、第三次构建(修改代码内容)

## 修改源代码任意内容后,然后再次将源代码构建 Jar 包
$ mvn clean install## 构建 SpringBoot 应用的 Docker 镜像
$ time docker build -t hub.mydlq.club/library/springboot-layer:0.0.3 .

Docker 镜像构建总共花费 2.82s 时间。

六、镜像推送到镜像仓库测试

1、推送镜像到镜像仓库测试

服务器一推送普通镜像到镜像仓库1:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1real    0m35.215s## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2real    0m14.051s## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3real    0m14.183s

服务器二推送分层镜像到镜像仓库2:

## 第一次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.1real    0m34.121s## 第二次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.2real    0m13.605s## 第三次推送镜像
$ time docker push hub.mydlq.club/library/springboot-layer:0.0.3real    0m4.805s

2、镜像仓库拉取镜像测试

服务器一推送从镜像仓库1拉取镜像:

## 清理全部镜像
$ docker rm --force $(docker images -qa)## 拉取镜像 springboot-normal:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1real    0m35.395s## 拉取镜像 springboot-normal:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2real    0m6.501s## 拉取镜像 springboot-normal:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3real    0m6.993s

服务器二推送从镜像仓库2拉取镜像:

## 清理全部镜像
$ docker rm --force $(docker images -qa)## 拉取镜像 springboot-layer:0.0.1
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.1real    0m30.615s## 拉取镜像 springboot-layer:0.0.2
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.2real    0m4.811s## 拉取镜像 springboot-layer:0.0.3
$ time docker push hub.mydlq.club/library/springboot-normal:0.0.3real    0m1.293s

七、镜像构建、推送、拉取时间汇总

1、不使用分层构建镜像

次数\阶段构建(s)推送(s)拉取(s)
第一次构建24.9835.2135.39
第二次构建-修改依赖包1.2714.056.50
第三次构建-修改代码1.3214.186.99

如下图:

 

2、使用分层构建镜像

次数\阶段构建(s)推送(s)拉取(s)
第一次构建26.1234.1230.61
第二次构建-修改依赖包3.4413.604.81
第三次构建-修改代码2.824.801.29

如下图:

 

3、总结

上面进行了使用 SpringBoot2.3.x 分层的方式构建镜像与普通的方式构建镜像,在镜像的构建、推送、拉取方面进行了执行速度对比,总结出如下结论:

  • 镜像构建: 在构建上,使用分层 Jar 构建镜像可能比普通方式构建镜像更繁琐,所以也更耗时,故而在构建上分层 Jar 构建镜像没有太多优势。
  • 镜像推送: 在推送上,如果每次构建镜像都只是修改构建镜像项目的源码,使用分层 Jar 构建镜像,可以大大加快镜像推送速度。如果是修改构建镜像项目中的依赖包,则和普通构建一样速度很慢。
  • 镜像拉取: 拉取和推送类似,如果只修改构建镜像项目的源码,只会拉取源码相关的中间层镜像,该层非常小(一般几百KB),拉取速度自然非常快。而对构建镜像项目的依赖包进行变动(增加依赖、删除依赖、修改依赖版本等),则会和普通方式构建镜像一样,拉取速度很慢,这是因为依赖包层是中间层镜像最大的一层(一般在10MB~200MB之间),如果该层发生变动则整个层会进行重新拉取,这样速度自然会很慢。

—END—

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

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

相关文章

Net任意String格式转换为DateTime类型

方式一&#xff1a;Convert.ToDateTime(string) Convert.ToDateTime(string) 注意&#xff1a;string格式有要求&#xff0c;必须是yyyy-MM-dd hh:mm:ss 方式二&#xff1a;Convert.ToDateTime(string, IFormatProvider) DateTimeFormatInfo dtFormat new System.Globalizatio…

jsonp的简单学习

前言&#xff1a;说到AJAX就会不可避免的面临两个问题&#xff0c;第一个是AJAX以何种格式来交换数据&#xff1f;第二个是跨域的需求如何解决&#xff1f;这两个问题目前都有不同的解决方案&#xff0c;比如数据可以用自定义字符串或者用XML来描述&#xff0c;跨域可以通过服务…

win7台式计算机怎么连热点,怎么用台式电脑开热点,电脑怎么开热点win7

导读&#xff1a;手机是每个人的随身携带之物&#xff0c;手机的功能让越来越多的人痴迷其中&#xff0c;也正是因为这个原因&#xff0c;手机流量的消耗也越来越多&#xff0c;购买流量让我们花费了很多金钱&#xff0c;我们该如何解决这个问题呢?下面我们就一起来看看电脑的…

Jenkins 与 Kubernetes 的 CI 与 CD Git + Maven + Docker+Kubectl

目录[-] . 一、Kubernetes 部署 Jenkins. 1、NFS 存储卷创建 Jenkins 目录. 2、创建 Jenkins 用于存储的 PV、PVC. 3、创建 ServiceAccount & ClusterRoleBinding. 4、创建 Service & Deployment. 5、获取 Jenkins 生成的 Token. 6、启动 Jenkins 进行初始化. 二、Jen…

WebLogic11g-创建域(Domain)及基本配置

2019独角兽企业重金招聘Python工程师标准>>> 最近看到经常有人提问weblogic相关问题&#xff0c;所以闲暇之际写几篇博文&#xff08;基于weblogic11&#xff09;&#xff0c;仅供大家参考。 具体weblogic的介绍以及安装&#xff0c;这里就不赘述了。 以域的创建开篇…

Asp.Net回车键触发Button的OnClick事件解决方案

在aspx页面有textbox文本框&#xff0c;还有三个button按钮。启用textbox的TextChanged事件和button的click事件。 问题&#xff1a; 现在在textbox文本框输入完数据按“回车”后&#xff0c;会触发TextChanged事件&#xff0c;但同时还会触发该页面第一个button按钮的Click事…

计算机教室规则英语作文,班级规则初中英语作文

【导语】无规则不成方圆&#xff0c;班级亦是如此&#xff0c;也拥有属于它的规章制度。下面是无忧考网为你整理的有关班级规则初中英语作文&#xff0c;希望你喜欢!【篇一】班级规则初中英语作文Students should get to school for a half-hour reading before 7:30. Everyone…

Pandas 统计分析基础 笔记4 任务4.4 使用分组聚合进行组内计算

文章目录 pandas_任务4.4 使用分组聚合进行组内计算4.4.1 使用groupby方法拆分数据 代码 4-51 对菜品订单详情表依据订单编号分组代码 4-52 GroupBy 类求均值,标准差,中位数代码 4-53 agg和aggregate函数的参数及其说明代码 4-54 使用agg分别求字段的不同统计量代码 4-55 使用…

陕西理工大学计算机科学与技术系,陕西理工大学计算机科学与技术专业2016年在陕西理科高考录取最低分数线...

类似问题答案南京理工大学计算机类(计算机科学与技术、软件工程、网络工程、智能科学与工程)专业2...学校 地 区 专业 年份 批次 类型 分数 南京理工大学 陕西 计算机类(计算机科学与技术、软件工程、网络工程、智能科学与工程) 2016 一批 理科 563 南京理工大学 陕西 计算机类…

高拍仪拍照SDK开发(良田影像S300L|S500L)

高拍仪拍照SDK开发下载地址&#xff1a;点击下载 本SDK适用于&#xff1a;良田影像S300L|S500L 高拍仪如图&#xff1a; SDN开发包安装之后找到安装目录&#xff0c;如图&#xff1a; 大家找到各自需要的版本即可&#xff0c;需要注意的是如果需要上传图片到服务器的话&#…

Pandas 文件读取和导出

Pandas 文件读取和导出 更新时间&#xff1a;2020-12-28 00:16:20标签&#xff1a;pandas io 说明 Pandas 中文教程修订中&#xff0c;欢迎加微信 sinbam 提供建议、纠错、催更。查看更新日志 我们拿到的数据一般是 CSV、Excel 等格式&#xff0c;将文件加载到 Pandas 的 D…

gitlab的用户使用手册

最近比较忙&#xff0c;没时间写博客&#xff0c;今天来的早所以写一篇关于gitlab的使用手册分享给大家。目录一、账户/项目申请二、登陆与修改密码三、SSH Key导入四、上传/下载代码1、上传&#xff08;用户系统为linux&#xff09;2、下载&#xff08;用户系统为linux&#x…

学计算机多久能拿证,计算机证书多久能领取 什么时候拿

计算机证书多久能领取&#xff0c;什么时候能拿&#xff0c;小编整理了相关信息&#xff0c;希望会对大家有所帮助&#xff01;计算机证书什么时候能领取1、一般情况下是考试结束后50个工作日左右出成绩及出证。全国计算机等级考试证书一年两次考试。每年的3月与9月考试。2、证…

MySQL_0

2019独角兽企业重金招聘Python工程师标准>>> 网址&#xff1a; http://www.mysqlpub.com 转载于:https://my.oschina.net/u/194743/blog/160145

TensorFlow 2.0 mnist手写数字识别(CNN卷积神经网络)

TensorFlow 2.0 (五) - mnist手写数字识别(CNN卷积神经网络) 源代码/数据集已上传到 Github - tensorflow-tutorial-samples 大白话讲解卷积神经网络工作原理&#xff0c;推荐一个bilibili的讲卷积神经网络的视频&#xff0c;up主从youtube搬运过来&#xff0c;用中文讲了一遍。…

计算机组成原理第06章在线测试,计算机组成原理第六章单元测试(二)(含答案)(4页)-原创力文档...

PAGEPAGE 1第六章单元测验 (二)书生1、用以指定待执行指令所在主存地址的寄存器是______。(单选)????A、指令寄存器IR????B、程序计数器PC????C、存储器地址寄存器MAR????D、数据缓冲寄存器2、下列关于微程序和微指令的叙述中______是正确的。(单选)????A、…

前端笔试练习一

前端笔试练习一 请编写一段程序&#xff0c;将一个对象和它直接、间接引用的所有对象的属性字符串放入一个数组。如var o {a:1,{b:2,c:{d:1}}}这里o经过处理后&#xff0c;应该得到["a","b","c","d"] 1 <!DOCTYPE html PUBLIC &qu…

职业梦想是计算机的英语作文,理想职业英语作文2篇

篇一&#xff1a;大学英语作文之我理想的工作my ideal jobMy Ideal JobAs college students, we will step into the society, and now we need to prepare for our future and arrange for our future career life, we need to take into consideration what to do in the fut…

C语言二维数组中的指针问题

#include "stdio.h" void main() {int a[5][5];int i,j;for (i0;i<5;i){for (j0;j<5;j){a[i][j] i;}} for (i0;i<5;i){for (j0;j<5;j){printf("%d ",a[i][j]);}printf("\n");} }转载于:https://blog.51cto.com/shamrock/12…

爬取微信小程序源码

爬取微信小程序源码 想知道爬取微信小程序有多简单吗&#xff1f;一张图、三个步骤&#xff0c;拿到你想要的任何微信小程序源码。