浅谈docker学习之docker数据卷(volume)

1.什么是数据卷volume

为了了解什么是Docker Volume,首先我们需要明确Docker内的文件系统是如何工作的。Docker镜像被存储在一系列的只读层。当我们开启一个容器,Docker读取只读镜像并添加一个读写层在顶部。如果正在运行的容器修改了现有的文件,该文件将被拷贝出底层的只读层到最顶层的读写层。在读写层中的旧版本文件隐藏于该文件之下,但并没有被不破坏 - 它仍然存在于镜像以下。当Docker的容器被删除,然后重新启动镜像时,将开启一个没有任何更改的新的容器 - 这些更改会丢失。此只读层及在顶部的读写层的组合被Docker称为Union File System(联合文件系统)。
为了能够保存(持久)数据以及共享容器间的数据,Docker提出了Volumes的概念。很简单,volumes是目录(或者文件),它们是外部默认的联合文件系统或者是存在于宿主文件系统正常的目录和文件。

2.为什么使用数据卷volume

Docker的镜像是由一系列的只读层组合而来,当启动一个容器的时候,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题。

(1)容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便的对容器中的文件进行访问

(2)多个容器之间的数据无法共享

(3)当删除容器时,容器产生的数据将丢失

为了解决这些问题,Docker引入了数据卷(volume)机制。volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利。

(1)volume在容器创建时就初始化,在容器运行时就可以使用其中的文件

(2)volume能在不同的容器之间共享和重用

(3)对volume中的数据的操作会马上生效

(4)对volume中数据操作不会影响到镜像本身

(5)volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除

3.如何使用数据卷 

3.1 从容器挂载volume(-v /path)

在使用docker run创建新容器的时候,可以使用-v 标签为容器添加数据卷volume,以下用法是从容器中的某个文件夹创建volume,如果容器中指定的文件夹不存在,会自动生成

在上面的概念中,有说道,宿主机应该会有一个文件夹绑定挂载到容器中的volume挂载点,那默认的宿主机上的文件夹在哪呢,使用docker inspect命令,查看下容器详情(CRT令起一个SSH终端)

[root@localhost ~]# docker inspect volume-test01
[
 {
  "Id": "81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e",
  "Created": "2016-08-25T07:48:55.942949334Z",
  "Path": "/bin/bash",
  "Args": [],
  "State": {
   "Status": "running",
   "Running": true,
   "Paused": false,
   "Restarting": false,
   "OOMKilled": false,
   "Dead": false,
   "Pid": 10199,
   "ExitCode": 0,
   "Error": "",
   "StartedAt": "2016-08-25T07:48:56.777918888Z",
   "FinishedAt": "0001-01-01T00:00:00Z"
  },
  "Image": "sha256:4fd21defa24c8c07b3689b267a63d563ca0e26ef931b329fc3f3d46efb5bba2d",
  "ResolvConfPath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/resolv.conf",
  "HostnamePath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/hostname",
  "HostsPath": "/var/lib/docker/containers/81a74152e6f45a3f780ac7cdc37c9a089814f9a70aad1d27747093ca3c3dae3e/hosts",
  "LogPath": "",
  "Name": "/volume-test01",
  "RestartCount": 0,
  "Driver": "devicemapper",
  "MountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c47,c332",
  "ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c47,c332",
  "AppArmorProfile": "",
  "ExecIDs": null,
  "HostConfig": {
   "Binds": null,
   "ContainerIDFile": "",
   "LogConfig": {
    "Type": "journald",
    "Config": {}
   },
   "NetworkMode": "default",
   "PortBindings": {},
   "RestartPolicy": {
    "Name": "no",
    "MaximumRetryCount": 0
   },
   "VolumeDriver": "",
   "VolumesFrom": null,
   "CapAdd": null,
   "CapDrop": null,
   "Dns": [],
   "DnsOptions": [],
   "DnsSearch": [],
   "ExtraHosts": null,
   "GroupAdd": null,
   "IpcMode": "",
   "Links": null,
   "OomScoreAdj": 0,
   "PidMode": "",
   "Privileged": false,
   "PublishAllPorts": false,
   "ReadonlyRootfs": false,
   "SecurityOpt": null,
   "UTSMode": "",
   "ShmSize": 67108864,
   "ConsoleSize": [
    0,
    0
   ],
   "Isolation": "",
   "CpuShares": 0,
   "CgroupParent": "",
   "BlkioWeight": 0,
   "BlkioWeightDevice": null,
   "BlkioDeviceReadBps": null,
   "BlkioDeviceWriteBps": null,
   "BlkioDeviceReadIOps": null,
   "BlkioDeviceWriteIOps": null,
   "CpuPeriod": 0,
   "CpuQuota": 0,
   "CpusetCpus": "",
   "CpusetMems": "",
   "Devices": [],
   "KernelMemory": 0,
   "Memory": 0,
   "MemoryReservation": 0,
   "MemorySwap": 0,
   "MemorySwappiness": -1,
   "OomKillDisable": false,
   "PidsLimit": 0,
   "Ulimits": null
  },
  "GraphDriver": {
   "Name": "devicemapper",
   "Data": {
    "DeviceId": "29",
    "DeviceName": "docker-253:0-101330881-9cb32851050b1707022b475489686582a272d883a56a8ff52f3344f56b65639f",
    "DeviceSize": "10737418240"
   }
  },
  "Mounts": [
   {
    "Name": "5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137",
    "Source": "/var/lib/docker/volumes/5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137/_data",
    "Destination": "/opt/vol-data",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
   }
  ],
  "Config": {
   "Hostname": "81a74152e6f4",
   "Domainname": "",
   "User": "",
   "AttachStdin": true,
   "AttachStdout": true,
   "AttachStderr": true,
   "Tty": true,
   "OpenStdin": true,
   "StdinOnce": true,
   "Env": null,
   "Cmd": [
    "/bin/bash"
   ],
   "Image": "test/mycentos:v1.0",
   "Volumes": {
    "/opt/vol-data": {}
   },
   "WorkingDir": "",
   "Entrypoint": null,
   "OnBuild": null,
   "Labels": {}
  },
  "NetworkSettings": {
   "Bridge": "",
   "SandboxID": "c73841812aab480cf8e6a02071e36951dceb002d7b36f7dc0b38ccd9db833ba5",
   "HairpinMode": false,
   "LinkLocalIPv6Address": "",
   "LinkLocalIPv6PrefixLen": 0,
   "Ports": {},
   "SandboxKey": "/var/run/docker/netns/c73841812aab",
   "SecondaryIPAddresses": null,
   "SecondaryIPv6Addresses": null,
   "EndpointID": "3e492b611d9bd2c202c8a6c8fe4b4a755393545348b1aeb4e60995609dabb07c",
   "Gateway": "172.17.0.1",
   "GlobalIPv6Address": "",
   "GlobalIPv6PrefixLen": 0,
   "IPAddress": "172.17.0.2",
   "IPPrefixLen": 16,
   "IPv6Gateway": "",
   "MacAddress": "02:42:ac:11:00:02",
   "Networks": {
    "bridge": {
     "IPAMConfig": null,
     "Links": null,
     "Aliases": null,
     "NetworkID": "54001aaff29a231c9b2fe83459805d99dce0c21d6e2719f9b11bc90d8fe2f9c9",
     "EndpointID": "3e492b611d9bd2c202c8a6c8fe4b4a755393545348b1aeb4e60995609dabb07c",
     "Gateway": "172.17.0.1",
     "IPAddress": "172.17.0.2",
     "IPPrefixLen": 16,
     "IPv6Gateway": "",
     "GlobalIPv6Address": "",
     "GlobalIPv6PrefixLen": 0,
     "MacAddress": "02:42:ac:11:00:02"
    }
   }
  }
 }
] 

注意看Mounts节点(Docker的版本用的是1.10.3),数据卷的使用,类似于 Linux 下对目录或文件进行 mount。

"Mounts": [
   {
    "Name": "5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137",
    "Source": "/var/lib/docker/volumes/5ddd734c53a38a78a9f739157c63074b4aff736d4045925616d7753402304137/_data",
    "Destination": "/opt/vol-data",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
   }
  ] 

当我们在容器的volume上操作时,宿主机上对应的文件是否也会跟着变动呢?测试一下,在容器的volume上创建一个文件test.txt,然后查看宿主机是不是也会同步存在

经测试,当容器上的volume有变动时,宿主机也会跟着变动,那反过来呢?经测试也是一样的。不管是容器挂载点发生变动还是宿主机对挂载目录进行操作,令一方都会跟着变动。

利用docker commit生成新镜像,然后docker run -it 运行新镜像,发现容器挂载目录下没有任何文件了。说明生成新镜像时,是不保存挂载文件的。

3.2从宿主机挂载volume(-v /host-path:/container-path)

将主机的文件或文件夹作为volume挂载时,可以用多个 -v标签为容器添加多个volume,还可以使用:ro指定该volume为只读。注意:如果容器中指定的挂载目录存在相同的文件时,会被宿主机覆盖掉

在宿主机上建立了/opt/vol-01和/opt/vol-02挂载点,分别和容器中的/opt/vol-test-1和/opt/vol-test-2对应,前者权限默认读写,后者只能读,用docker inspect

当在容器的vol-test-2上新建操作时,会提示只读.在宿主机上,2个挂载点新增,修改,删除操作都OK,但是在容器中居然2个都不行,按理说应用是第二个vol-test-2不行才对,不知是哪里出问题了。

利用docker commit生成新镜像,然后docker run -it 运行新镜像,发现容器挂载目录下没有任何文件了。说明生成新镜像时,是不保存挂载文件的。

3.3使用Dockerfile添加volume

使用VOLUME指令向容器添加volume

VOLUME /data

多个时VOLUME ["/data1","/data2"]

这种情况和第一个中情况docker run -v /data是一样的。注意,dockerfile中使用volume是不能和第二种方法那样挂载宿主机中指定的文件夹。这时为了保证Dockerfile的可移植性,因为不能保证所有的宿主机都有对应的文件夹。

需要注意的是,在Dockerfile中使用VOLUME指令后,如果尝试对这个volume进行修改,这些修改指令都不会生效,比如下面例子,尝试添加一个文件,并修改文件并改变文件所有权限

FROM test/mycent:v1.0
RUN useradd foo
VOLUME /data
RUN touch /data/x
RUN chown -R foo:foo /data 

通过该Dockerfile创建镜像并启动容器后,该容器中存在用户foo,并且能看到在/data挂载的volume,但是/data文件夹的所有者并没有被改变为foo,而且/data下也没有/data/x文件。但是如果顺序反过来,先建文件,先授权,再挂载volume,那就得到期待的结果。

4.共享volume/数据卷容器(--volumes-from)

如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

先创建一个名为dbdata的数据卷容器,专门共其他容器挂载。

在/opt/dbdata下创建了一个文件db.properties。

再启动2个容器,a,b都a--volumes-from dbdata,b --volumes-from a.

可以看到vol_a,vol_b容器的/opt/dbdata下都有db.properties文件。在vol_b的/opt/dbdata下创建文件vol_b.txt时,容器dbdata,vol_a也都同时同步了。

对dbdata,vol_a,vol_b使用命令docker inspect时,发现他们的Mounts下的Source都是一样的,说明它们都绑定到宿主机的同一个目录,所以当某个容器的挂载修改时,其他容器也看到了同样的效果

如果挂载源有多个时,可以使用多个--volumes-from,如

docker run -it --name vol_use --volumes-from vol_a --volumes-from vol_b test/mycentos:v1.0 /bin/bash.

如果一个容器挂在了volume,即使容器停止了运行,该volume仍然存在,其他容器仍然可以继续--volumes-from它。

5.删除volume

如果创建容器时挂载了volume,

在/var/lib/docker/volumes/04b003b21b873157433deffbaf08bb0c89d234d3ec3c6576fdd7b61f5d41163e/_data下会生成相应的文件(路径,不同版本,不同操作系统会有所不同,具体可以用docker inspect查看容器具体信息),当删除容器时,宿主机上的挂载目录时不会删除的,并且目录名称是随机字符,不知意义,所以在删除容器时,需要妥善处理容器的volume。删除容器时一并删除volume有2中方法

(1)docker rm -v 删除容器。就是删除容器时,加上-v

(2)docker run --rm .就是启动容器的时候加上--rm,那么当容器运行停止时会自动删除容器以及容器所挂载的volume

上面创建了容器dbdata,vol_a,vol_b,vol_c,现在使用docker rm -v看看有什么效果。

vol_c是--volumes-from dbdata的,删除vol_c时,宿主机的挂载目录仍存在,没删掉,猜测那是因为还有其他容器在连着或者说是dbdata -v的时候创建的。那现在删除dbdata容器试试看(vol_a是--volumes-from dbdata的,vol_a还没删除,验证下能否删除dbdata)。

发现dbdata删除时,宿主机那目录仍然存在,同时也说明哪怕vol_a是--volumes-from dbdata的,vol_a还没删除,那也没影响。同时也说明只要还有一个容器在挂载这宿主机的目录,那宿主机的目录就不会删除。那接下来,把所有容器都删除,再看结果。

可以看到,当最后一个容器删除后,宿主机那volume目录终于删除了.

6.备份、恢复或迁移volume

上面有测试过,当使用docker commit等手段生成新镜像,然后再启动镜像生成新容器时,原先volume目录下的文件不见了,可以生成新镜像时,并没有把volume下的文件一起打包生成镜像。

volume作为数据的载体,在很多情况下需要对其中的数据进行备份、迁移,或是从已有数据恢复。一个很容易想到的方法就是用docker inspect命令查找到volume对应宿主机上对应的那个目录位置,然后复制其中内容或使用tar打包。当这些笨拙的做法并不值得推荐,因为查找主机上文件夹后再操作容易出错,也不适合脚本的自动化执行。

备份volume可以使用以下方法

代码如下:

docker run --rm --volumes-from dbdata -v $(pwd):/backup test/mycentos:v1.0 tar cvf /back/data.tar /data

这行指令启动了一个临时的容器,这个容器挂载了两个volume,第一个volume与要备份的volume共享,第二个volume将宿主机的当前目录(也可以绝对路径)挂载到容器的/backup下。容器运行后将要备份的容器(/data)备份到/backup/data.tar,然后删除容器,备份后的data.tar就留在了当前目录。操作验证一下

居然报错了,说没有权限。进入容器-it时,是docker随机生成一个用户的,至于怎样给该用户授权,以后再研究吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 浅谈Docker 容器数据卷挂载小结
  • 详解Docker 数据卷管理
  • Docker中容器数据卷(Data Volume)和数据管理详解
  • Docker 数据卷权限实例详解
  • Docker 数据卷及数据容器详细介绍及示例
  • Docker 数据卷,数据卷容器详细介绍
  • docker 数据卷之进阶篇
(0)

相关推荐

  • docker 数据卷之进阶篇

    笔者在<Docker 基础 : 数据管理>一文中介绍了 docker 数据卷(volume) 的基本用法.随着使用的深入,笔者对 docker 数据卷的理解与认识也在不断的增强.本文将在前文的基础上介绍 docker 数据卷的原理及一些高级用法.如果您想先了解 docker 数据卷的基本概念与用法,请先移步这里. 为什么需要数据卷? 这得从 docker 容器的文件系统说起.出于效率等一系列原因,docker 容器的文件系统在宿主机上存在的方式很复杂,这会带来下面几个问题: 不能在宿主机上很方

  • Docker 数据卷,数据卷容器详细介绍

    Docker 数据卷,数据卷容器详细介绍 引子 有些时候,我们的服务运行时必不可少的会产生一些日志,或是我们需要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 容器中管理数据主要有两种方式: 数据卷 数据卷容器 数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性: - 数据卷可以在容器之间共享和重用 - 对数据卷的修改会立马生效 - 对数据卷的更新,不会影响镜像 - 卷会一直存在,直到没有容器使用 #(类似linux下的挂载(moun

  • Docker 数据卷及数据容器详细介绍及示例

    Docker 数据卷及数据容器 这两天开始学习docker,发现docker确实很强大,让网站部署和维护的效率大大提高.遂准备将手头维护的几个小站,全部docker化.整理的过程中感觉到,docker可以以功能或者进程为单位进行部署和维护,不用再花时间在繁琐的配置上面,但是docker和宿主之间的数据共享以及docker间的数据共享仍然是让人头疼和操心的地方. 几个基本概念: docker: 一种容器管理技术,这里也指既有的开发工具链. container: 容器 image: 镜像 volum

  • 浅谈Docker 容器数据卷挂载小结

    为了更直观了解数据卷挂载的操作,做个实验一一验证数据卷挂载的各种情况. 情况一.本地不存在文件挂载到容器存在文件 首先是当本地不存在该文件,而容器内存在该文件的情况,尝试把不存在的文件挂载到存在该文件的容器中.以一个 Alpine 镜像为例,这里把一个修改后的 Alpine 镜像打了新标签,叫做 volume_test: # 本地目录不存在 test 文件. $ docker run --name=test -v ~/test.txt:/etc/hosts -d volume_test 0cba

  • Docker 数据卷权限实例详解

    Docker 数据卷权限 在CentOS7中运行NodeJs的容器,发现挂载的本地目录在容器中没有执行权限,经过各种验证和Google搜索,找到了问题的原因,这里做一下记录.原因是CentOS7中的安全模块selinux把权限禁掉了,至少有以下三种方式解决挂载的目录没有权限的问题: 1,在运行容器的时候,给容器加特权: 示例:docker run -i -t --privileged=true -v /home/docs:/src waterchestnut/nodejs:0.12.0 2,临时

  • 详解Docker 数据卷管理

    Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume).数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享. 数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像.使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统. 本节中,我们需要依次完成下面几项任务: 1.创建数据卷 2.管理数据卷权限 3.挂载宿主机文件 4.使用数据卷容器共享数据 5.数据卷备份

  • Docker中容器数据卷(Data Volume)和数据管理详解

    卷(Volume) 众所周知卷(Volume)是容器中的一个数据挂载点,卷可以绕过联合文件系统,从而为Docker 提供持久数据,所提供的数据还可以在宿主机-容器或多个容器之间共享.通过卷,我们可以可以使修改数据直接生效,而不必重新构建镜像. 一.数据卷 数据卷是一个可以绕过联合文件系统的,专门指定的可在一或多个容器间共享目录.卷为提供为持久化或共享数据提供了一些有用的特性. 数据卷设计的初哀是提供持久化数据,而与容器的生命周期无关.因此,在删除容器时,Docker不会自动删除卷,直到没有容器再

  • 浅谈docker学习之docker数据卷(volume)

    1.什么是数据卷volume 为了了解什么是Docker Volume,首先我们需要明确Docker内的文件系统是如何工作的.Docker镜像被存储在一系列的只读层.当我们开启一个容器,Docker读取只读镜像并添加一个读写层在顶部.如果正在运行的容器修改了现有的文件,该文件将被拷贝出底层的只读层到最顶层的读写层.在读写层中的旧版本文件隐藏于该文件之下,但并没有被不破坏 - 它仍然存在于镜像以下.当Docker的容器被删除,然后重新启动镜像时,将开启一个没有任何更改的新的容器 - 这些更改会丢失

  • Docker向数据卷Volume写入数据

    一.前言 我们知道,镜像是只读的,容器是在镜像的基础上加了一层读写层,这样容器就可以写了.既然容器可以进行写入了,那么我们就可以把一些数据放进容器里面.但是这样会有一种问题:如果容器被删除了,那么容器里面的数据也将会被删除.这该怎么解决呢?这时我们就可以使用Volume来解决这种问题. 二.volume 1.什么是volume 我们先来考虑这样一个问题:如何把源代码放进容器里面 可以在制作镜像时直接把源代码嵌入里面.(不考虑这种方式) 把源代码挂载到容器的可读写层. 那么什么是Volume呢?

  • Docker中数据卷(volume)管理的两种方式

    上篇文章给大家介绍过 docker基础知识之挂载本地目录的方法 ,今天给大家介绍Docker中数据卷(volume)管理的两种方式,具体内容如下所示: 什么是数据卷 数据卷( volume ):volume是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久化提供便利. 为什么要用数据卷 Docker分层文件系统存在的问题: Docker的镜像是由一系列的只读层组合而来的,当启动一个容器时, Docker加载镜像的所有只读层,并在最上

  • docker中容器数据卷volume介绍

    目录 docker 容器数据卷volume 使用数据卷 方式一:直接使用命令挂载 -v 方式二:Dockerfile 数据卷容器 总结 docker 容器数据卷volume 如果数据都在容器中,那么我们删除容器的时候数据就会丢失,所以我们希望数据可以持久化. 例如MySQL容器,我们希望数据可以存储在本地,当MySQL容器删除的时候,数据不会丢失. 容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地,这就是卷技术.也就是数据挂载技术,将我们容器内的目录,挂载到Linux上

  • 浅谈MyBatis-Plus学习之Oracle的主键Sequence设置的方法

    一.Oracle的主键Sequence设置简介 在Oracle数据库中不支持主键自增策略,它是通过Sequence序列来进行完成的,因此需要在MP中进行相关配置 二.相关配置如下 2.1.pom.xml 添加相关依赖 注意:由于oracle的授权问题,没办法从maven仓库中下载,因此可以手动从oracle官网中下载,并本地打包到仓库中 <!-- Oracle驱动: 因为Oracle授权的问题,不能从Maven的仓库中下载到Oracle驱动 --> <dependency> <

  • 浅谈Python数学建模之数据导入

    目录 一.数据导入是所有数模编程的第一步 二.在程序中直接向变量赋值 2.1.为什么直接赋值? 2.2.直接赋值的问题与注意事项 三.Pandas 导入数据 3.1.Pandas 读取 Excel 文件 3.2.Pandas 读取 csv 文件 3.3.Pandas 读取文本文件 3.4.Pandas 读取其它文件格式 四.数据导入例程 一.数据导入是所有数模编程的第一步 编程求解一个数模问题,问题总会涉及一些数据. 有些数据是在题目的文字描述中给出的,有些数据是通过题目的附件文件下载或指定网址

  • 浅谈迁移学习

    目录 一.背景 二.定义及分类 2.1.目标 2.2.主要思想 2.3.迁移学习的形式定义及一种分类方式 三.关键点 四.基于实例的迁移 五.基于特征的迁移 5.1.特征选择 5.2.特征映射 六.基于共享参数的迁移 七.深度学习和迁移学习结合 八.Pre-training+Fine-tuning 九.DANN (Domain-Adversarial Neural Network) 一.背景 随着越来越多的机器学习应用场景的出现,而现有表现比较好的监督学习需要大量的标注数据,标注数据是一项枯燥无

  • 浅谈pyhton学习中出现的各种问题(新手必看)

    目前比较杂乱无章,后续还会有一些添加补充 1.标识符 (1)标识符是区分大小写的. (2)标示符以字母或下划线开头,可包括字母,下划线和数字. (3)以下划线开头的标识符是有特殊意义的. 2.参数前加星号(*)的意义 面对实际情况时无法提前得知要传入的参数的个数,因此在参数前加星号从而允许函数接受任意多的参数,情况如下: (1)参数前加一个星号(*),传入的参数存储为元组的形式: (2)参数前加两个星号(*),传入的参数存储为字典的形式,并且调用时采用例如'a=1,b=2,c=3'的形式. 3.

  • 浅谈springMVC接收前端json数据的总结

    对于json对象类型(即JsonObject)的数据,springMVC主要有以下几种方式接收: 1.通过Map接收 @RequestMapping(value = "/getAllStudio" ) public void getAllStudio(@RequestBody Map<String, Integer> map ) { JSONObject json = new JSONObject(); Integer page = map.get("page&q

  • 浅谈JsonObject中的key-value数据解析排序问题

    1.JsonObject中的数据是key-value形式,通过JsonObject的keys方法得到key的迭代器是无序的,要想实现排序,目前只能通过加装一层处理(方法来自Stack Overflow,感谢大神),将key-vlaue放入ThreeMap排序,排序规则默认是字母表顺序,可自定义Comparator修改. iteratorKeys = object.keys();//得到所有title SortedMap map = new TreeMap(); while (iteratorKe

随机推荐