Docker学习——⑥

文章目录

  • 1、什么是存储卷?
  • 2、为什么需要存储卷?
  • 3、存储卷分类
  • 4、管理卷 Volume
  • 5、绑定卷 bind mount
  • 6、临时卷 tmpfs
  • 7、综合实战-MySQL 灾难恢复
  • 8、常见问题

1、什么是存储卷?

存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着,当我们在容器中的这个目录下写入数据时,容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。

在宿主机上的这个与容器形成绑定关系的目录被称作存储卷。卷的本质是文件或者目录,它可以绕过默认的联合文件系统,直接以文件或目录的形式存在于宿主机上。

宿主机的/data/web 目录与容器中的/container/data/web 目录绑定关系,然后容器中的进程向这个目录中写数据时,是直接写在宿主机的目录上的,绕过容器文件系统与宿主机的文件系统建立关联关系,使得可以在宿主机和容器内共享数据库内容,让容器直接访问宿主机中的内容,也可以宿主机向容器写入内容,容器和宿主机的数据读写是同步的

容器的销毁并不会影响存储卷的数据

2、为什么需要存储卷?

1. 数据丢失问题

容器按照业务类型,总体可以分为两类

  • 无状态的(数据不需要被持久化)
  • 有状态的(数据需要被持久化)

显然,容器更擅长无状态应用。因为未持久化数据的容器根目录的生命周期与容器的生命周期一样,容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对任何文件的修改都存在于该读写层,当容器被删除时,容器中的读写层也会随之消失。

虽然容器希望所有的业务都尽量保持无状态,这样容器就可以开箱即用,并且可以任意调度,但实际业务总是有各种需要数据持久化的场景,比如 MySQL、Kafka 等有状态的业务。因此为了解决有状态业务的需求,Docker 提出了卷(Volume)的概念。

2. 性能问题
UnionFS 对于修改删除等,一般效率非常低,如果对一于 I/O 要求比较高的应用,如redis 在实现持化存储时,是在底层存储时的性能要求比较高。

3. 宿主机和容器互访不方便

宿主机访问容器,或者容器访问要通过 docker cp 来完成,应用很难操作

4. 容器和容器共享不方便

3、存储卷分类

目前 Docker 提供了三种方式将数据从宿主机挂载到容器中:

volume docker 管理卷,默认映射到宿主机的/var/lib/docker/volumes 目录下,只需要在容器内指定容器的挂载点是什么,而被绑定宿主机下的那个目录,是由容器引擎 daemon 自行创建一个空的目录,或者使用一个已经存在的目录,与存储卷建立存储关系,这种方式极大解脱用户在使用卷时的耦合关系,缺陷是用户无法指定那些使用目录,临时存储比较适合。

bind mount 绑定数据卷,映射到宿主机指定路径下,在宿主机上的路径要人工的指定一个特定的路径,在容器中也需要指定一个特定的路径,两个已知的路径建立关联关系

tmpfs mount 临时数据卷,映射到于宿主机内存中,一旦容器停止运行,tmpfs mounts 会被移除,数据就会丢失,用于高性能的临时数据存储。

在这里插入图片描述

4、管理卷 Volume

创建卷
存储卷可以通过命令方式创建,也可以在创建容器的时候通过 -v and --mount 指定。

方式一:Volume 命令操作

命令清单如下

命令别名功能
docker volume create创建存储卷
docker volume inspect显示存储卷详细信息
docker volume lsdocker volume list列出存储卷
docker volume prune清理所有无用数据卷
docker volume rm删除卷,使用中的无法删除

docker volume create
创建存储卷

docker volume create [OPTIONS]

关键参数
-d, --driver:指定驱动,默认是 local
- -label:指定元数据

创建匿名卷

docker volume create

在这里插入图片描述

创建命名卷

docker volume create myvolume1

在这里插入图片描述

docker volume inspect
查看卷详细信息

docker volume inspect [OPTIONS] VOLUME [VOLUME...]

关键参数
-f:指定相应个格式,如 json

查看myvolume1的详细信息

docker volume inspect myvolume

在这里插入图片描述

创建一个卷,这个卷的默认位置是 /var/lib/docker/volumes 下,如果改过根目录,对应的目录也会发生变化

docker volume ls
列出卷

docker volume ls [OPTIONS]

关键参数
- -format:指定相应个格式,如 json,table
- -filter,-f: 过滤
-q: 仅显示名称

docker volume rm
删除卷,需要容器不使用,卷中的数据也会被删除

docker volume rm [OPTIONS] VOLUME [VOLUME...]

关键参数
-f, --force:强制删除

删除名为myvolume1的存储卷

docker volume rm myvolume1

在这里插入图片描述

docker volume prune
删除不使用的本地卷,如果是命名卷,即使没使用,也不会被删除

docker volume prune [OPTIONS]

关键参数
- -filter:过滤
-f, --force :不提示是否删除

在这里插入图片描述

方式二:-v 或者--mount 指定
-v 和-mount 都可以完成管理卷的创建

-v 参数:完成目录映射

docker run -v name:directory[:options] ......
#这种创建的匿名卷
docker run -v directory[:options] ......

参数
第一个参数:卷名称
第二个参数:卷映射到容器的目录
第三个参数:选项,如 ro 表示 readonly

运行一个容器,并使用-v参数指定目录映射

docker run -d --name mynginx -v volnginx1:/usr/share/nginx/html/ nginx:1.21.3

在这里插入图片描述

查看存储卷映射的目录下是否有数据

在这里插入图片描述

当我们使用-v参数指定容器目录映射到宿主机时,容器目录下的数据也会在宿主机中

进入容器内部的指定目录下,删除文件,再退出容器,再查看宿主机中对应的文件是否还存在

在这里插入图片描述

在运行容器时,指定为readonly,再次测试是否能被删除

在这里插入图片描述

发现即使是rm -f 也无法删除

如果在宿主机中删除对应的文件,是能被删除的,也就是参数 -ro 只能限定容器,而不能限定宿主机

在这里插入图片描述

–mount 参数:完成目录映射

--mount '<key>=<value>,<key>=<value>'
#这种创建的匿名卷

关键参数
type : 类型表示 bind, volume, or tmpfs
source ,src :对于命名卷,这是卷的名称。对于匿名卷,省略此字段
destination,dst,target:文件或目录挂载在容器中的路径
ro,readonly: 只读方式挂载

采用 mount 创建命名 volume

docker run -d --name mynginx2 --mount 'src=volnginx3,dst=/usr/share/nginx/html' nginx:1.21.3

在这里插入图片描述

采用 mount 创建匿名volume

docker run -d --name mynginx3 --mount ',dst=/usr/share/nginx/html' nginx:1.21.3

在这里插入图片描述

既然是匿名,如何知道名为mynginx3的容器,它的存储卷是哪个呢?

通过docker inspect mynginx3查看,其中有个名为Mounts的json,里面有个name字段就是

在这里插入图片描述

方式三:Dockerfile 匿名卷
通过 Dockerfile 的 VOLUME 可以创建 docker 管理卷,后续博客再讲

我们也可以通过 dockerfile 的 VOLUME 指令在镜像中创建 Data Volume,这样只要通过该镜像创建的容器都会存在挂载点,但值得注意的是通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是由 docker 随机生成的

操作案例

命令创建管理卷

docker volume inspect test1

在这里插入图片描述

启动一个nginx并进行管理卷的映射

docker run -d --name nginx -p 80:80 -v test1:/usr/share/nginx/html nginx:1.21.3

在这里插入图片描述

查看存储卷映射的宿主机中对应的目录下是否有数据

在这里插入图片描述

修改nginx的首页index.html

在这里插入图片描述

进入容器,查看对应的index.html是否有变化

在这里插入图片描述
已经发生了变化,再通过浏览器访问,也能成功访问到nginx的页面

如果在宿主机上对文件做了修改,那么在容器内部也是会实时响应的

Docker卷的生命周期:如果将容器删除,卷中的数据是不会被删除的,除非手动删除这个卷

在这里插入图片描述

在这里插入图片描述

Docker 卷共享

docker volume create test
docker run -d --name nginx1 -p 6379:80 -v test:/usr/share/nginx/html nginx:1.21.3
docker run -d --name nginx2 -p 6380:80 -v test:/usr/share/nginx/html nginx:1.21.3
docker ps

在这里插入图片描述

查看卷在宿主机的映射位置,并修改里面的index.html

在这里插入图片描述

分别进入两个容器内查看index.html是否被修改

在这里插入图片描述

分别通过浏览器访问,查看nginx的页面是否一致

在这里插入图片描述

在这里插入图片描述

共享卷本质就多个卷映射到宿主机的同一个目录下,因此数据如果一旦修改,影响是相互的

5、绑定卷 bind mount

-v 和-mount 都可以完成绑定卷的创建

通过-v创建

docker run -v name:directory[:options] .........

参数

第一个参数:宿主机目录,这个和管理卷是不一样的
第二个参数:卷映射到容器的目录
第三个参数:选项,如 ro 表示 readonly

创建绑定卷

docker run -d --name nginx -v /data/fl/testbind/:/usr/share/nginx/html/ nginx:1.21.3

在这里插入图片描述

查看对应的绑定信息

docker inspect nginx

在这里插入图片描述

查看宿主机绑定的目录

在这里插入图片描述

里面什么都没有,这跟管理卷是不一样的,管理卷中有数据,会将数据拷贝到宿主机上,而绑定卷是不会的,绑定卷的数据是来自宿主机的,宿主机有,绑定卷就有,否则就没有

创建一个文件,然后进入容器内查看

在这里插入图片描述

容器里也只有宿主机创建的这个文件

通过 --mount创建

--mount '<key>=<value>,<key>=<value>'

关键参数

type : 类型表示 bind, volume, or tmpfs
source ,src :宿主机目录,这个和管理卷是不一样的
destination,dst,target:文件或目录挂载在容器中的路径
ro,readonly: 只读方式挂载

docker run -d --name nginx --mount type=bind,src=/data/fl/testbind/,dst=/usr/share/nginx/html/ nginx:1.21.3

在这里插入图片描述

检测一下容器的Mounts

在这里插入图片描述

进入容器,创建一个文件,再在宿主机中查看是否存在

在这里插入图片描述

用mount创建绑定卷,在绑定时,如果宿主机的目录不存在,则失败,但是用-v参数时,宿主机的目录不存在会自动创建

在这里插入图片描述
在这里插入图片描述

如果宿主机中存在内容和容器里的内容一样,则会以宿主机的为准,-v和 --mount是一样的

在这里插入图片描述

绑定卷的共享和管理卷的共享是一样的,宿主机中进行数据的修改,同步影响其他容器

6、临时卷 tmpfs

临时卷数据位于内存中,在容器和宿主机之外

tmpfs 局限性

  • 不同于卷和绑定挂载,不能在容器之间共享 tmpfs 挂载
  • 这个功能只有在 Linux 上运行 Docker 时才可用

创建卷
方式一:指定 --tmpfs 创建

--tmpfs /app
docker run -d --name nginx --tmpfs /test nginx:1.21.3

在这里插入图片描述

进入容器,在映射的目录下创建文件,然后再重启,查看文件是否存在

在这里插入图片描述

结果发现文件消失了,这就是临时卷的一个缺点:容器退出或者重启后,数据都会消失

方式二: --mount 指定参数创建

--mount '<key>=<value>,<key>=<value>'

关键参数
type : 类型表示 bind, volume, or tmpfs
destination,dst,target:挂载在容器中的路径
tmpfs-size:tmpfs 挂载的大小(以字节为单位)。默认无限制
tmpfs-mode:tmpfs 的八进制文件模式。例如,700 或 0770。默认为 1777或全局可写

docker run -d --name nginx --mount type=tmpfs,dst=/test1 nginx:1.21.3

在这里插入图片描述

进入容器,在映射的目录下创建文件,然后再重启,查看文件是否存在

在这里插入图片描述

结果跟前面的一样,数据已经丢失了

内存会覆盖容器内的数据

docker run -d --name nginx --tmpfs /usr/share/nginx/html/ -p 80:80 nginx:1.21.3

进入容器内,查看/usr/share/nginx/html/下是否有数据

在这里插入图片描述

里面并没有数据,说明数据已经被覆盖了,创建一个html文件,通过浏览器访问

echo "hello tmpfs!">index.html

在这里插入图片描述

退出容器,重启,再通过浏览器访问,就会发现出现403,原因就是重启后创建的html文件就会丢失

在这里插入图片描述

在这里插入图片描述

- -mount同目录处理、内存读取、大小限制验证

创建临时卷,并指定内存大小为1M

docker run -d --name nginx --mount type=tmpfs,dst=/usr/share/nginx/html/,tmpfs-size=1m -p 80:80 nginx:1.21.3

在这里插入图片描述

进入容器内,创建html文件,通过浏览器验证是否能正常访问nginx

在这里插入图片描述

在这里插入图片描述

将一个超过1M的文件拷贝到容器的根目录下

在这里插入图片描述

在容器内,将这个文件拷贝到容器映射的目录下,结果就会发现拷贝失败,因为前面设置了内存限制为1M

在这里插入图片描述

tmpfs失踪了

创建一个nginx容器,进入容器,创建一个文件

在这里插入图片描述

在另一个终端上查找这个文件,是能找到的

在这里插入图片描述

再创建一个容器,进入容器,创建一个文件

在这里插入图片描述

在另一个终端上查找这个文件,结果是找不到

在这里插入图片描述

这就验证了:tmpfs是把文件放在宿主机的内存里面,在宿主机中通过find或者cat等命令就不能随意找到这些文件,也就验证了临时卷是具备一定的安全性的,一些保密性的数据就可以考虑用tmpfs,不过也需要考虑容器重启或停止,数据就会消失这个局限性

7、综合实战-MySQL 灾难恢复

使用 MySQL 5.7 的镜像创建容器并创建一个普通数据卷 mysql-data 用来保存容器中产生的数据。需要在容器中连接 MySQL 服务, 并创建数据库 test, 并在在该数据库中创建一个简单的表并插入一些数据进来

创建容器并绑定卷

docker run --name mysql -v /data/fl/mysqltest:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=fl@test -d mysql:5.7

连接 MySQL 的 shell, 创建一个 user 数据库,并在该数据库中创建一个 student 表,在表中插入了两条数据

在这里插入图片描述

在这里插入图片描述

在宿主机中查看 volume

在这里插入图片描述

可以看到容器中 MySQL 创建的数据库和表数据以及持久化到宿主机挂载的目录下了

有一天莫名其妙停电了, 然后服务器重启了,这个时候 Mysql 没有起来,然后有个哥们看磁盘空间不多了,把所有停止的容器都删除了。结果我们的 Mysql 也没有了

在这里插入图片描述

幸好我们的数据还在,这个时候怎么恢复呢,我们再次启动我们的运行命令,确保目录映射一致就能找回我们的数据了

在这里插入图片描述

在这里插入图片描述

8、常见问题

什么时候用 Volume,什么时候用 bind、tmpfs?

  • volume:volume 是 docker 的宿主机文件系统一部分,用于不需要规划具体目录的场景

  • bind:bind mount 完全是依赖于主机的目录结构和操作系统,用于目录需要提前规划,比如 mysql 的目录需要个空间大的,其他服务有不占用的时候,用 volume 就不太合适了

  • tmpfs:用于敏感文件存储,文件不想存储的宿主机和容器的可写层之中

存储卷在实际研发中带来了哪些问题

  • 跨主机使用
    docker 存储卷是使用其所在的宿主机上的本地文件系统目录,也就是宿主机有一块磁盘,这块磁盘并没有共享给其他的 docker 主机,容器在这宿主机上停止或删除,是可以重新再创建的,但是不能调度到其他的主机上,这也是 docker 本身没有解决的问题,所以 docker 存储卷默认就是 docker 所在主机的本地,但是自己搭建一个共享的 NFS来存储 docker 存储的数据,也可以实现,但是这个过程强依赖于运维人员的能力。所以未来应用的存储和数据往往分离,越来越多的分布式存储方案出现,如 s3 系列,nfs 等

  • 启动参数未知
    容器有一个问题,一般与进程的启动不太一样,就是容器启动时选项比较多,如果下次再启动时,很容器会忘记它启动时的选项,所以最好有一个文件来保存容器的启动,这就是容器编排工具的作用
    一般情况下,是使用命令来启动操作 docker,但是可以通过文件来读,也就读文件来启动,读所需要的存储卷等,但是它也只是操作一个容器,如果要几十上百个容器操作,就需要专业的容器编排工具
    这种一般像开源的 k8s,各个云厂商也有自己的企业版编排软件

  • 复杂场景仍然需要运维
    对于有状态要持久的集群化组件,如 mysql 的主从。部署维护一个 Mysql 主从需要运维知识、经验整合进去才能实现所谓的部署,扩展或缩容,出现问题后修复,必须要了解集群的规模有多大,有多少个主节点,有多少个从节点,主节点上有多少个库,这些都要一清二楚,才能修复故障,这些就强依赖于运维经验
    这种复杂的场景往往还是需要人力,很难有完美的工具出现

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

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

相关文章

AI 引擎系列 5 - 以 AI 引擎模型为目标运行 AI 引擎编译器(2022.1 更新)

AI 引擎系列 5 - 以 AI 引擎模型为目标运行 AI 引擎编译器&#xff08;2022.1 更新&#xff09; 简介 在先前的 AI 引擎系列博文中&#xff0c;我们以 x86 模型为目标运行了 AI 引擎编译器&#xff0c;并运行了 X86 仿真器来验证 AI 引擎应用的功能模型。在本文中&#xff0c;…

2011年09月21日 Go生态洞察:Go图像处理包

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Javaweb之javascript的BOM对象的详细解析

1.5.2 BOM对象 接下来我们学习BOM对象&#xff0c;BOM的全称是Browser Object Model,翻译过来是浏览器对象模型。也就是JavaScript将浏览器的各个组成部分封装成了对象。我们要操作浏览器的部分功能&#xff0c;可以通过操作BOM对象的相关属性或者函数来完成。例如&#xff1a…

【docker:容器提交成镜像】

容器创建部分请看&#xff1a;点击此处查看我的另一篇文章 容器提交为镜像 docker commit -a "sinwa lee" -m "首页变化" mynginx lxhnginx:1.0docker run -d -p 88:80 --name lxhnginx lxhnginx:1.0为啥没有变啊&#xff0c;首页&#xff1f; 镜像打包 …

【CCF-C解刊】4区逆袭到1区TOP,这本期刊实力强劲,34天录用,7天见刊!

计算机类 • 好刊解读 今天小编带来Elsevier旗下计算机领域好刊的解读&#xff0c;这本期刊从4区逆袭成为中科院1区&#xff08;TOP&#xff09;&#xff0c;如此实力强劲的期刊&#xff0c;究竟如何&#xff1f; 如有相关领域作者有意向投稿&#xff0c;可作为重点关注&…

离散Hopfield神经网络分类——高校科研能力评价

大家好&#xff0c;我是带我去滑雪&#xff01; 高校科研能力评价的重要性在于它对高等教育和科研体系的有效运作、发展和提高质量具有深远的影响。良好的科研能力评价可以帮助高校识别其在不同领域的强项和薄弱点&#xff0c;从而制定战略&#xff0c;改进教学和科研&#xff…

Linux 多线程控制详解

目录 多线程编临界资源访问 互斥锁 API 简述 初始化互斥量 互斥量加锁/解锁 互斥量加锁(非阻塞方式) 互斥量销毁 程序示例 多线程编执行顺序控制 信号量 API 简述 初始化信号量 信号量 P/V 操作 信号量申请(非阻塞方式) 信号量销毁 程序示例 条件变量 创建和销毁…

node插件MongoDB(四)—— 库mongoose 的条件控制(三)

文章目录 前言一、运算符二、逻辑运算1. $or 逻辑或2. $and 逻辑与 三、正则匹配 前言 在mongodb 不能使用 > < > < ! 等运算符&#xff0c;需要使用替代符号。 一、运算符 > 使用 $gt< 使用 $lt> 使用 $gte< 使用 $lte! 使用 $ne 例子&#xff1a;获…

单片机启动流程

存储器 ​ 一个单片机中存在rom和ram&#xff0c;Soc也有rom和ram&#xff08;ddrx&#xff09;&#xff0c;部分Soc还包含MMU&#xff08;Memory Manage Unit 内存管理单元&#xff09;— &#xff08;用于系统内存管理&#xff0c;比如说虚拟内存空间&#xff0c;内存区间的…

Flink SQL自定义标量函数(Scalar Function)

使用场景&#xff1a; 标量函数即 UDF&#xff0c;⽤于进⼀条数据出⼀条数据的场景。 开发流程&#xff1a; 实现 org.apache.flink.table.functions.ScalarFunction 接⼝实现⼀个或者多个⾃定义的 eval 函数&#xff0c;名称必须叫做 eval&#xff0c;eval ⽅法签名必须是 p…

jenkins通知

构建失败邮件通知 配置自己的邮箱 配置邮件服务&#xff0c;密码是授权码 添加构建后操作 扩展 配置流水线 添加扩展 钉钉通知 Jenkins安装钉钉插件 钉钉添加机器人 加签 https://oapi.dingtalk.com/robot/send?access_token98437f84ffb6cd64fa2d7698ef44191d49a11…

为什么审计平台不适合进行数据库变更管理?

关于视源电子 广州视源电子科技股份有限公司 (CVTE) 成立于 2005 年 12 月&#xff0c;旗下拥有多家业务子公司。 截至 2022 年底&#xff0c;公司总人数超 6000 人&#xff0c;约 60% 为技术人员。公司的主营业务为液晶显示主控板卡和交互智能平板等显控产品的设计、研发与销…

C语言之文件操作(剩余部分)

上篇博客字数到极限了&#xff0c;给大家把内容补充在这一篇&#xff0c;我们还剩下文件读取结束的判定和文件缓冲区的内容没有介绍&#xff0c;让我们开始下面的学习吧&#xff01; 目录 1.文件读取结束的判定 1.1feof函数 1.2ferror函数 代码示例 2.文件缓冲区 2.1fflu…

Redis之主从复制

文章目录 一、什么是Redis主从复制&#xff1f;1.作用2.配置主从复制的原因3.环境配置 二、一主二从三、复制原理四、链路总结 一、什么是Redis主从复制&#xff1f; 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(ma…

用Go实现网络流量解析和行为检测引擎

1.前言 最近有个在学校读书的迷弟问我:大德德, 有没有这么一款软件, 能够批量读取多个抓包文件,并把我想要的数据呈现出来, 比如:源IP、目的IP、源mac地址、目的mac地址等等。我说&#xff1a;“这样的软件你要认真找真能找出不少开源软件, 但毕竟没有你自己的灵魂在里面,要不…

类与对象(2)

✨前言✨ &#x1f4d8; 博客主页&#xff1a;to Keep博客主页 &#x1f646;欢迎关注&#xff0c;&#x1f44d;点赞&#xff0c;&#x1f4dd;留言评论 ⏳首发时间&#xff1a;2023年11月11日 &#x1f4e8; 博主码云地址&#xff1a;博主码云地址 &#x1f4d5;参考书籍&…

C++动态库

C动态库 动态库文件&#xff08;Dynamic Link Library&#xff0c;DLL&#xff09;是程序在运行时所需要调用的库。静态库文件是程序在编译时所需要调用的库。 1 环境介绍 VS版本&#xff1a;VS2017 编程语言&#xff1a;C 2 功能介绍 使用VS2017项目模板创建C动态库生成…

Java 之 IO/NIO/OKIO

BIO blocking io AIO Asynchronous IO 从内存读取到写入--输出 从外部到内存 -- 输入 OutputStream //文件不存在则自动创建 try {OutputStream outputStream new FileOutputStream("text.txt");outputStream.write(a);outputStream.write(b);} catch (IOExcep…

Java-多态

1. 多态 1.1 多态的概念 多态的概念&#xff1a;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 1.2 多态实现条件 在java中要实现多态&#xff0c;必须要满足如下几个条件&#xff0c;缺一不…

vivado时序分析-3时序分析关键概念

1、时钟相移 时钟相移对应于延迟时钟波形 &#xff0c; 此波形与因时钟路径内的特殊硬件所导致的参考时钟相关。在 AMD FPGA 中 &#xff0c; 时钟相移通常是由 MMCM 或 PLL 原语引入的 &#xff0c; 前提是这些原语的输出时钟属性 CLKOUT*_PHASE 为非零值。 时序分析期间…