02docker简单使用和配置(网络、存储和Hub)
四:网络
1:命名容器
在各种docker命令中,可以通过名字中找到对应的容器。之前创建的容器都是由docker自动命名的,可以在docker run中,通过--name参数指定容器的名字。比如:
$ docker run -d -P --name web training/webapp python app.py
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
容器的名字必须是唯一的。因此只能有一个容器叫做web,如果想再次使用这个名字,必须删除之前的容器。
2:在默认网络上运行容器
docker默认提供两种网络驱动,分别是bridge和overlay。docker允许自己写网路驱动插件,不过这属于高级话题了,暂不讨论。
安装docker引擎后自动包含了三种默认的网络:
[hh_93_197 ~]# docker network ls
NETWORK ID NAME DRIVER
57f0a920665a none null
e8fad866218e host host
4948e842e58f bridge bridge
除非在docker run中特意指定,否则docker总是将容器运行在bridge网络上,比如:
[hh_93_197 ~]# docker run -itd --name=networktest ubuntu
df38005e240bcd0a2502f1c47b8b2d1b31059f1b7c75f0522006cd0b986e3916
使用docker network inspect命令看一下默认的bridge网络:
[hh_93_197 ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "4948e842e58f3fedd25afe97bf292d53d7023ddeb90fefb7825103b56c5251b8",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16"
}
]
},
"Containers": {
"df38005e240bcd0a2502f1c47b8b2d1b31059f1b7c75f0522006cd0b986e3916": {
"Name": "networktest",
"EndpointID": "ee6b49e5c03ca2bd61f2d2b46c45c9067ae5ccf098bb4c14beaeeb64fde8bb5f",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
}
}
]
可见该网络使用的网段是172.17.0.0/16,容器networktest是attach到该网络上的唯一容器,其IP地址为172.17.0.2。主机上的docker0就是该网络上的网桥。
下面,进入容器networktest,用ifconfig看一下它的IP地址,确实是172.17.0.2。
[hh_93_197 ~]# docker attach networktest
root@df38005e240b:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02
inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
可以将容器从一个网络中移除(断开),比如在另一个终端上执行下面的命令:
[hh_93_197 ~]# docker network disconnect bridge networktest
此时,在容器中查看网络配置:
root@df38005e240b:/# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
网络是隔离容器最合适的方法。可以创建自己的网络:
3:创建自己的网络
bridge网络将容器限制在运行dokcer引擎的主机上,而overlay网络则可以跨越多个主机(高级话题)。
可以创建自己的bridge网络:
[hh_93_197 ~]# docker network create -d bridge my-bridge-network
c6198f9bb78a4275088d7f06116ef839871ca7aa1dbbd7b120f1187df4224cb4
[hh_93_197 ~]# docker network ls
NETWORK ID NAME DRIVER
57f0a920665a none null
e8fad866218e host host
4948e842e58f bridge bridge
c6198f9bb78a my-bridge-network bridge
使用-d选项,表明新创建的网络使用bridge驱动。分别使用docker network inspect 和ifconfig看一下:
[hh_93_197 ~]# docker network inspect my-bridge-network
[
{
"Name": "my-bridge-network",
"Id": "c6198f9bb78a4275088d7f06116ef839871ca7aa1dbbd7b120f1187df4224cb4",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1/16"
}
]
},
...
[hh_93_197 ~]# ifconfig
... br-c6198f9bb78a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:81:54:91:a3 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:c6:77:db:9e txqueuelen 0 (Ethernet)
RX packets 107 bytes 7532 (7.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 135 bytes 11825 (11.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ...
可见br-c6198f9bb78a就是新创建的my-bridge-network中的网桥。
4:网络隔离
下面分别将两个容器加入到两个独立的网络中查看一下,首先将一个基于ubuntu镜像的容器加入到新创建的网络中:
[hh_93_197 ~]# docker run -itd --net=my-bridge-network --name testnetwork ubuntu
559048438ae5972c8c4e578f63195d14d4c7a155e9306630f3eff6d9d18fcb2c
[hh_93_197 ~]# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' testnetwork
172.18.0.2
可见该容器的IP地址为172.18.0.2。接下来再创建一个web容器,不指定任何网络参数,因此该容器会attach到默认的bridge网络上:
[hh_93_197 ~]# docker run -d --name web training/webapp python app.py
226dc5d3a98a9d2b009e870462c7f072180c98ba5a1f6144b5cff4e15b0a1638
[hh_93_197 ~]# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2
可见该容器的IP地址为172.17.0.2。两个容器附加到不同的网络上,相当于已经隔离了。进入testnetwork容器,在该容器中ping一下172.17.0.2,ping不通:
[hh_93_197 ~]# docker exec -it testnetwork bash
root@559048438ae5:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
21 packets transmitted, 0 received, 100% packet loss, time 19999ms
docker允许将一个容器attach到任意多的网络上。下面,在另一个终端上,将web容器attach到my-bridge-network上:
[hh_93_197 ~]# docker network connect my-bridge-network web
此时,在testnetwork容器中ping一下web容器:
root@559048438ae5:/# ping web
PING web (172.18.0.3) 56(84) bytes of data.
64 bytes from web.my-bridge-network (172.18.0.3): icmp_seq=1 ttl=64 time=0.105 ms
64 bytes from web.my-bridge-network (172.18.0.3): icmp_seq=2 ttl=64 time=0.046 ms
...
说明web已经和testnetwork处于同一个网络上了。其实,web容器目前是分别attach到my-bridge-network和bridge两个网络上,具有两个IP地址,分别是172.17.0.2和172.18.0.3。
五:存储
1:数据卷(Data Volumes)
数据卷用于持久化数据以及共享数据,它具有以下功能:
a:当容器创建时会初始化卷。如果容器的基础镜像在特定挂载点上包含数据,则这些数据会在卷初始化时复制到新卷中(当挂载宿主机目录时不会这么做)。
b:数据卷可以在多个容器间共享和重用;
c:数据卷上的改变,是立即可见的;
d:当升级镜像时,不会包含数据卷中修改的内容;
e:容器被删除时,数据卷依然存在。
数据卷用于持久化数据,并且独立于容器的生命周期。因此即使删除容器时,Docker也不会自动的删除卷,也不会在没有容器引用一个卷时,将其清理。
2:增加一个数据卷
在docker create和docker run中使用-v选项可以在创建容器时增加数据卷,也可以使用多个"-v"选项挂载多个数据卷。
例子如下:
[hh_93_197 ~]# docker run -it --name testvolume2 -v /dev ubuntu /bin/bash
root@aa644c48392b:/# ls /dev
agpgart core kmem loop6 midi03 mixer3 ram ram14 ram6 rmidi2 smpte3 tty1 tty8
audio dsp loop0 loop7 midi1 mpu401data ram0 ram15 ram7 rmidi3 sndstat tty2 tty9
audio1 dsp1 loop1 mem midi2 mpu401stat ram1 ram16 ram8 sequencer stderr tty3 urandom
audio2 dsp2 loop2 midi0 midi3 null ram10 ram2 ram9 shm stdin tty4 zero
audio3 dsp3 loop3 midi00 mixer port ram11 ram3 random smpte0 stdout tty5
audioctl fd loop4 midi01 mixer1 ptmx ram12 ram4 rmidi0 smpte1 tty tty6
console full loop5 midi02 mixer2 pts ram13 ram5 rmidi1 smpte2 tty0 tty7
可见,直接在容器中创建了/dev这个数据卷,而且/dev是ubuntu镜像原有的挂载点,其中的内容也已经复制到这个数据卷了。
在容器中,进入/dev目录下,新建readme.txt文件,内容是:”thisis data volume in container”。
在宿主机上,使用docker inspect命令查看该容器,得到信息如下:
…
"Mounts": [
{
"Name": "35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429",
"Source": "/var/lib/docker/volumes/35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429/_data",
"Destination": "/dev",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
…
因此,容器中的数据卷,对应着宿主机上的目录是/var/lib/docker/volumes/35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429/_data,查看该目录的内容:
[hh_93_197 /var/lib/docker/volumes/35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429/_data]# ls
agpgart core kmem loop6 midi03 mixer3 ram ram14 ram6 rmidi1 smpte2 tty0 tty7
audio dsp loop0 loop7 midi1 mpu401data ram0 ram15 ram7 rmidi2 smpte3 tty1 tty8
audio1 dsp1 loop1 mem midi2 mpu401stat ram1 ram16 ram8 rmidi3 sndstat tty2 tty9
audio2 dsp2 loop2 midi0 midi3 null ram10 ram2 ram9 sequencer stderr tty3 urandom
audio3 dsp3 loop3 midi00 mixer port ram11 ram3 random shm stdin tty4 zero
audioctl fd loop4 midi01 mixer1 ptmx ram12 ram4 readme.txt smpte0 stdout tty5
console full loop5 midi02 mixer2 pts ram13 ram5 rmidi0 smpte1 tty tty6
[hh_93_197 /var/lib/docker/volumes/35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429/_data]# cat readme.txt
this is data volume in container
可见,readme.txt文件已经在宿主机上可见了。反之也成立。在宿主机上的该目录下创建文件readme2.txt,在容器中也是立即可见的。
使用该容器制作新镜像,不会包含数据卷中的新增内容:
[hh_93_197 ~]# docker commit -m "test data volume" -a "hh" testvolume2 hh/ubuntu:volume2
sha256:1c4275b3ac33ee0c4e64ea533d836ee407369de7a1c604e9933b997e22027ff1
[hh_93_197 ~]# docker run -ti hh/ubuntu:volume2 /bin/bash
root@f6987d519b9a:/# ls /dev
agpgart core kmem loop6 midi03 mixer3 ram ram14 ram6 rmidi2 smpte3 tty1 tty8
audio dsp loop0 loop7 midi1 mpu401data ram0 ram15 ram7 rmidi3 sndstat tty2 tty9
audio1 dsp1 loop1 mem midi2 mpu401stat ram1 ram16 ram8 sequencer stderr tty3 urandom
audio2 dsp2 loop2 midi0 midi3 null ram10 ram2 ram9 shm stdin tty4 zero
audio3 dsp3 loop3 midi00 mixer port ram11 ram3 random smpte0 stdout tty5
audioctl fd loop4 midi01 mixer1 ptmx ram12 ram4 rmidi0 smpte1 tty tty6
console full loop5 midi02 mixer2 pts ram13 ram5 rmidi1 smpte2 tty0 tty7
当删除上面的容器后,宿主机上的数据卷目录依然存在:
[hh_93_197 /var/lib/docker/volumes/35aa73994cc70828d861620dca03fd1e91699ff46d1b560b6e3ded6128b1e429/_data]# ls
agpgart core kmem loop6 midi03 mixer3 ram ram14 ram6 rmidi0 smpte1 tty tty6
audio dsp loop0 loop7 midi1 mpu401data ram0 ram15 ram7 rmidi1 smpte2 tty0 tty7
audio1 dsp1 loop1 mem midi2 mpu401stat ram1 ram16 ram8 rmidi2 smpte3 tty1 tty8
audio2 dsp2 loop2 midi0 midi3 null ram10 ram2 ram9 rmidi3 sndstat tty2 tty9
audio3 dsp3 loop3 midi00 mixer port ram11 ram3 random sequencer stderr tty3 urandom
audioctl fd loop4 midi01 mixer1 ptmx ram12 ram4 readme2.txt shm stdin tty4 zero
console full loop5 midi02 mixer2 pts ram13 ram5 readme.txt smpte0 stdout tty5
3:挂载宿主机目录到容器中
使用-v选项,还可以将宿主机上的目录,挂载到容器中:
[hh_93_197 ~]# docker run -it -v /host/foo:/opt/foo ubuntu /bin/bash
root@0235be2f412d:/# ls /opt
foo
以上的命令,就将宿主机上的/host/foo目录,挂载到容器中的/opt/foo中了。
在宿主机中/host/foo创建文件,容器中/opt/foo会立即可见;容器中/opt/foo创建的文件,宿主机中/host/foo也是立即可见的。
如果宿主机目录/host/foo不存在,则docker会自动创建。如果容器中的目录/opt/foo中原先已存在且包含文件,则挂载宿主机目录后,/opt/foo中的内容不会被删除,只是不可见了,一旦解除mount,则/opt/foo中的内容会恢复(这事mount的特点)。
在-v选项中,容器目录必须是绝对路径的形式,宿主机目录可以是一个绝对路径,也可以是一个名字,使用名字时,docker会使用改名字创建一个命名卷。
默认情况下,docker使用的是读写挂载,可以指定只读挂载,这种情况下,容器中就不能修改相应目录的内容了:
[hh_93_197 ~]# docker run -it -v /host/foo:/opt/foo:ro ubuntu /bin/bash
root@b1ba14479947:/# cd /opt/foo/
root@b1ba14479947:/opt/foo# touch readme2.txt
touch: cannot touch 'readme2.txt': Read-only file system
注意,因为挂载主机目录是依赖于特定主机的,因此,不允许在Dockerfile中挂载主机目录,因为创建的镜像必须是可移植的,包含主机目录挂载的镜像不能应用到其他主机上。
除了可以挂载目录之外,也可以将主机的文件挂载到容器中:
[hh_93_197 ~]# docker run --rm -it -v ~/proxy_on:/root/proxy_on ubuntu /bin/bash
root@2305c0b5e1b4:/# cat /root/proxy_on
export https_proxy=http://19.28.20.22:1888
export http_proxy=http://12.28.20.22:8000
4:创建并挂载一个数据卷容器(数据卷共享)
可以将数据卷在多个容器中共享。比如下面先创建第一个容器sd1,其中挂载了数据卷/sharedata:
[hh_93_197 ~]# docker run -it -v /sharedata --name sd1 ubuntu
然后在docker run中,使用--volumes-from参数,创建新容器,并把sd1中的/sharedata挂载到新容器中:
[hh_93_197 ~]# docker run -it --volumes-from sd1 --name sd2 ubuntu
[hh_93_197 ~]# docker run -it --volumes-from sd2 --name sd3 ubuntu
此时,sd1、sd2和sd3这三个容器都具有数据卷/sharedata,而且是共享的。在其中任意一个容器中的/sharedata中修改内容,都可以在其他容器中立即可见。
删除容器sd1、sd2或者sd3时,该数据卷并不会被删除。可以在docker rm命令中使用-v参数,当最后一个关联数据卷的容器删除时,相应的数据卷也会被删除。
[hh_93_197 ~]# docker rm -v sd1
sd1
[hh_93_197 ~]# docker rm -v sd2
sd2
[hh_93_197 ~]# docker rm -v sd3
sd3
这样删除sd3之后,数据卷也就相应的被删除了。
如果不指定-v选项,则当一个数据卷的所有关联容器都被删除之后,该数据卷就成了” dangling”卷。可以使用命令docker volume ls -f dangling=true列出所有” dangling”卷,并使用命令dockervolume rm <volume name>删除即可。
5:数据备份、迁移和恢复
使用--volumes-from参数,可以实现数据备份、迁移和恢复的功能。例子如下:
首先创建一个挂载数据卷/sharedata的容器,然后在/sharedata中创建新文件,当做需要备份的数据,然后退出:
[hh_93_197 ~]# docker run -it -v /sharedata --name sd1 ubuntu
root@c62d94cb3c91:/# cd /sharedata/
root@c62d94cb3c91:/sharedata# echo "hello world" >> readme.txt
root@c62d94cb3c91:/sharedata# cat readme.txt
hello world
root@c62d94cb3c91:/sharedata# exit
exit
然后使用--rm选项,创建一个临时容器。--rm选项可以在容器停止运行后立即将其删除。
该临时容器通过--volumes-from参数,与sd1共享/sharedata目录,并且挂载宿主机目录,运行tar命令压缩备份/sharedata内容,将备份数据存放到宿主机目录中:
[hh_93_197 ~]# docker run --rm --volumes-from sd1 -v /root/testbackup:/backup ubuntu tar cvf /backup/backup.tar /sharedata
tar: Removing leading `/' from member names
/sharedata/
/sharedata/readme.txt
接下来,创建需要恢复数据的容器sd2:
[hh_93_197 ~]# docker run -ti -v /sharedata --name sd2 ubuntu /bin/bash
root@0d44aee764fa:/# ls /sharedata/
目前其/sharedata目录是空的,然后再创建一个临时容器,将数据恢复到sd2中:
[hh_93_197 /host/foo]# docker run --rm --volumes-from sd2 -v /root/testbackup:/backup ubuntu bash -c "cd /sharedata && tar xvf /backup/backup.tar --strip 1"
sharedata/readme.txt
此时,在sd2中查看/sharedata,数据已经恢复了:
root@0d44aee764fa:/# cat /sharedata/readme.txt
hello world
注意,使用共享数据卷时,当多个容器同时修改共享卷中的同一个文件时,有可能会造成数据损坏。
而且,数据卷在宿主机上也是可见的,如果宿主机和容器同时修改同一个文件,也可能会造成数据损坏。
六:Docker镜像库
DockerHub(hub.docker.com)是由Docker公司维护的镜像库。可以通过docker search,pull,login和push命令与Docker Hub交互。
dockerlogin用于向Docker Hub注册用户;
dockersearch用于在Docker Hub搜索镜像;
dockerpull用于下载镜像;
dockerpush用于上传镜像;
除了Docker Hub之外,还可以从其他仓库下载镜像,从其它仓库下载时需要指定完整的仓库注册服务器地址。比如:
[hh_93_197 ~]# docker pull registry.aliyuncs.com/ddbmh/redis
Using default tag: latest
latest: Pulling from ddbmh/redis
80ab95908a2b: Pull complete
a3ed95caeb02: Pull complete
47a0d79f89b9: Pull complete
7190081b1686: Pull complete
fe09c22d81ac: Pull complete
a5eae2bcc645: Pull complete
662723161f77: Pull complete
b568670a8ccd: Pull complete
a1a961e320bc: Pull complete
Digest: sha256:68a1aa9675f25e77d97fe9436dececd29be5ba6eae4ce04169288da5bfe9096b
Status: Downloaded newer image for registry.aliyuncs.com/ddbmh/redis:latest
[hh_93_197 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
...
registry.aliyuncs.com/ddbmh/redis latest a70b69767606 7 months ago 109.3 MB
https://docs.docker.com/engine/userguide/containers/networkingcontainers/
https://docs.docker.com/engine/userguide/containers/dockervolumes/
https://docs.docker.com/engine/userguide/containers/dockerrepos/
02docker简单使用和配置(网络、存储和Hub)的更多相关文章
- 利用Openfiler配置基于文件系统的网络存储
一.Openfiler简介 Openfiler是一个操作系统,其提供基于文件的网络附加存储和基于块的存储区域网络功能. Openfiler支持的网络协议包括:NFS,SMB/CIFS,HTTP/Web ...
- 配置iSCSI部署网络存储
iSCSI( Internet Small Computer System Interface 互联网小型计算机系统接口)是由IBM 下属的两大研发机构一一加利福尼亚AImaden和以色列Haifa研 ...
- 网络存储(二)之ISCSI原理
组成 一个简单ISCSI系统大致由以下部分构成 ISCSI Initiator 或者 ISCSI HBA ISCSI Target 以太网交换机 一台或者多台服务器 结构图如下: iscsi服务器用来 ...
- 网络存储技术介绍(2) ( based on zt)
http://www.educity.cn/tx/429084.html 互联网技术DAS.NAS和SAN存储方案的比较 按照设备位置和接入方式,磁盘存储可以分为内置存储和外挂存储,外挂存储又分为直连 ...
- 网络存储技术介绍(1) ( based on zt)
最近由于某同学微信发了一些网络存储的文章,开始感兴趣,稍微收集了一些 一. 网络存储技术 http://ask.zol.com.cn/q/187044.html (yxr:很老的技术介绍吧) 网络 ...
- Android开发手记(20) 数据存储五 网络存储
Android为数据存储提供了五种方式: 1.SharedPreferences 2.文件存储 3.SQLite数据库 4.ContentProvider 5.网络存储 安卓的网络存储比较简单,因为A ...
- 网络存储结构简明分析—DAS、NAS和SAN 三者区别
存储的总体分类 主流存储结构 网络存储结构大致分为三种:直连式存储(DAS:Direct Attached Storage).存储区域网络(SAN:Storage Area Network ...
- 基于RxJava2+Retrofit2简单易用的网络请求实现
代码地址如下:http://www.demodashi.com/demo/13473.html 简介 基于RxJava2+Retrofit2实现简单易用的网络请求,结合android平台特性的网络封装 ...
- windows网络服务之配置网络负载均衡(NLB)群集
O首页51CTO博客我的博客 搜索 每日博报 社区:学院论坛博客下载更多 登录注册 家园 学院 博客 论坛 下载 自测 门诊 周刊 读书 技术圈 曾垂鑫的技术专栏 http:// ...
随机推荐
- 一句话介绍python线程、进程和协程
一.进程: Python的os模块封装了常见的系统调用,其中就包括fork.而fork是linux常用的产生子进程的方法,简言之是一个调用,两个返回. 在python中,以下的两个模块用于进程的使用. ...
- JS为什么是单线程的?
JavaScript语言最大的特点就是单线程.它是浏览器的脚本语言.在同一时间只能做一件事.用于操作DOM.如果JS是多线程的,当我在给一个DOM添加内容时,又删除了这个DOM,那么JS该怎么做. 关 ...
- mybatis深入理解(三)-----MyBatis事务管理机制
MyBatis作为Java语言的数据库框架,对数据库的事务管理是其非常重要的一个方面.本文将讲述MyBatis的事务管理的实现机制.首先介绍MyBatis的事务Transaction的接口设计以及其不 ...
- day37 02-Hibernate二级缓存:二级缓存的散装数据
一级缓存存放的是对象的地址.把对象的地址缓存下来了.二级缓存里面存放的是对象的散装数据.你再去获取的时候,因为一级缓存的生命周期结束了,它会从二级缓存中获取.从二级缓存中获取,因为它又会得到一个对象. ...
- 忘记用了delete释放内存,如何防止内存溢出
C++的内存管理还是要自己来做的,自己要进行内存的申请和释放 程序直接kill掉,OS会回收的 但是面试要问到这个问题,其实是想问你别的 RAII,也称为“资源获取就是初始化”,是c++等编程语言常用 ...
- UIImageView添加圆角
最直接的方法就是使用如下属性设置: 1 2 3 imgView.layer.cornerRadius = 10; // 这一行代码是很消耗性能的 imgView.clipsToBounds = YES ...
- 在Liferay 7中如何自定义一个Portlet的toolbar
哈哈,懒得自己写了,直接贴教程了,你想为那个portlet添加自定义的toolbar,就在javax.portlet.name=属性中写上它的值.教程博客:Adding Portlet URL in ...
- LeetCode136 Single Number, LeetCode137 Single Number II, LeetCode260 Single Number III
136. Single Number Given an array of integers, every element appears twice except for one. Find that ...
- 【JZOJ2758】【SDOI2012】走迷宫(labyrinth)
╰( ̄▽ ̄)╭ Morenan 被困在了一个迷宫里. 迷宫可以视为 N 个点 M 条边的有向图,其中 Morena n处于起点 S , 迷宫的终点设为 T . 可惜的是 , Morenan 非常的脑小 ...
- 【JZOJ4923】【NOIP2017提高组模拟12.17】巧克力狂欢
题目描述 Alice和Bob有一棵树(无根.无向),在第i个点上有ai个巧克力.首先,两人个选择一个起点(不同的),获得点上的巧克力:接着两人轮流操作(Alice先),操作的定义是:在树上找一个两人都 ...