Docker的一个简单例子(二)

文章目录

  • 环境
  • 示例
    • 持久化数据
    • bind mount
    • 多容器应用
    • Docker Compose
  • 参考

环境

  • RHEL 9.3
  • Docker Community 24.0.7

示例

持久化数据

默认情况下,各个容器之间的文件系统是相互独立的。即使两个容器来自同一个image,对其中一个容器的修改,对另一个容器也是不可见的。

我们来实际操作一下。

首先启动一个容器,创建 /data.txt 文件,其内容是一个随机数:

docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"

该命令启动了一个 ubuntu image的容器,并运行了两条命令:

  • shuf -i 1-10000 -n 1 -o /data.txt :产生一个随机数,并写到 /data.txt 文件里
  • tail -f /dev/null :仅仅是为了运行一条“可持续运行”的命令,否则 docker run 命令就会立即结束

注: docker run 只能运行一条命令,本例为了运行两条命令,用 && 来连接,这是bash的语法。

查看容器:

➜  ~ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                      NAMES
1216910a048e   ubuntu            "bash -c 'shuf -i 1-…"   13 seconds ago   Up 12 seconds                              gracious_pike
......

我们来看一下该容器里的 /data.txt 文件:

➜  ~ docker exec 1216910a048e cat /data.txt 
9458

可见,文件已经创建好了。

接下来,我们再启动一个 ubuntu image的容器,并查看 /data.txt 文件:

➜  ~ docker run -it ubuntu ls /data.txt
ls: cannot access '/data.txt': No such file or directory

可见,在第二个容器里,没有 /data.txt 文件。

最后,把两个容器都删除。

接下来,我们来实现数据的持久化。

回到我们之前的 getting-started 应用。该应用会把数据存储在SQLite数据库里,其位置为 /etc/todos/todo.db

通过创建一个volume,并将其mount到容器里的 /etc/todos 目录,我们就可以实现数据持久化。

首先通过 docker volume create 命令创建一个volume:

docker volume create todo-db

删除之前运行的容器,然后运行一个新的容器:

docker run -dp 0.0.0.0:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started

打开浏览器,访问 http://localhost:3000 ,添加一些item:

在这里插入图片描述

删除容器:

docker rm -f <container ID>

重新启动一个容器:

docker run -dp 0.0.0.0:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started

打开浏览器,访问 http://localhost:3000 ,可以看到之前添加的item仍然还在。

那么问题来了,持久化的数据保存到哪里了呢?

看一下volume:

➜  ~ docker volume ls
DRIVER    VOLUME NAME
local     todo-db
......
➜  ~ docker volume inspect todo-db
[{"CreatedAt": "2024-01-01T10:00:38+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/todo-db/_data","Name": "todo-db","Options": null,"Scope": "local"}
]

可见,mount point是 "/var/lib/docker/volumes/todo-db/_data" ,这就是宿主机上的路径。

在宿主机上查看该目录:

➜  ~ sudo ls -l "/var/lib/docker/volumes/todo-db/_data"
total 8
-rw-r--r--. 1 root root 8192 Jan  1 11:23 todo.db

同样,如果我们在宿主机上创建一个文件,比如 /var/lib/docker/volumes/todo-db/_data/test.txt ,然后在容器里也可以访问:

➜  ~ docker exec 885e3594b2e0 cat /etc/todos/test.txt
haha

bind mount

上一节使用了volume mount,这一节介绍bind mount。

使用bind mount,把宿主机上的指定目录mount到容器里。当宿主机上的文件有变化时,容器里的文件同样也立即变化。

volume mount和bind mount的对比:

Volume mountBind mount
宿主机路径Docker决定个人决定
示例type=volume,src=my-volume,target=/usr/local/datatype=bind,src=/path/to/data,target=/usr/local/data
向volume注入容器内容YesNo
是否支持volume驱动YesNo

在宿主机的 getting-started-app 根目录下,运行:

docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash

--mount 的参数如下:

  • type=bind :指定mount类型
  • src="$(pwd)" :指定宿主机路径
  • target=/src :指定容器路径

现在,我们已经进入了容器,查看 /src 目录:

root@9c90854addd6:/# ls -l /src
total 156
-rw-r--r--. 1 1000 1000    209 Dec 31 11:17 Dockerfile
-rw-r--r--. 1 1000 1000    269 Dec 31 09:19 README.md
-rw-r--r--. 1 1000 1000    648 Dec 31 09:19 package.json
drwxr-xr-x. 4 1000 1000     39 Dec 31 09:19 spec
drwxr-xr-x. 5 1000 1000     69 Dec 31 09:19 src
-rw-r--r--. 1 1000 1000 147266 Dec 31 09:19 yarn.lock

在容器里创建文件:

echo hello > /src/test.txt

在宿主机上也能访问:

➜  getting-started-app git:(main)cat test.txt
hello

反之,在宿主机上的文件修改,也会立即反映在容器里。

通过bind mount,我们可以把源代码mount到容器里,在容器里build和运行应用。

在宿主机的 getting-started-app 根目录下,运行:

docker run -dp 127.0.0.1:3000:3000 \-w /app --mount type=bind,src="$(pwd)",target=/app \node:18-alpine \sh -c "yarn install && yarn run dev"

可通过 docker logs <container ID> 查看容器log。或者 docker logs -f <container ID> ,持续更新log。

注意:在国内会非常慢,还经常失败,要多试几次。

➜  getting-started-app git:(main) ✗ docker logs -f 8fb9ce6b6953b4b9013db782eb483591a0df137f2f34c67174cb1cd04ac92250
yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 163.98s.
yarn run v1.22.19
$ nodemon -L src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

按“Ctrl + C” 退出。

打开浏览器,访问 http://localhost:3000 ,确保应用工作正常。

接下来,在宿主机上修改源代码,比如修改 src/static/js/app.js 文件,把按钮上的文字由 Add Item 改为 Add ,保存,然后刷新浏览器:

在这里插入图片描述

可见,在宿主机上修改源代码后,通过浏览器访问应用,会立即反映出来。

注:分两步走:

  1. 在宿主机修改源代码 -> 修改同步到容器
  2. nodemon 发现源代码有变化后,立即重启应用(这一步是自动的, nodemon 是在 package.json 里启动的)

调试完毕后,最后构建image:

docker build -t getting-started .

多容器应用

现在我们来将应用改为使用MySQL数据库。显然,基于“高内聚,低耦合”的原则,需要在另外一个容器里单独运行MySQL。也就是说,应用由两个容器组成。那么问题来了,容器之间如何通信?容器的运行都是相互隔离的,显然它们需要通过网络来互相通信。

有两种方式将容器与网络关联:

  • 在启动容器时,分配网络
  • 把已运行的容器连接到网络

首先创建网络:

docker network create todo-app

查看网络:

➜  ~ docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
be48b324c533   todo-app   bridge    local
......

启动MySQL容器:

docker run -d \--network todo-app --network-alias mysql \-v todo-mysql-data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=secret \-e MYSQL_DATABASE=todos \mysql:8.0

其中:

  • --network todo-app --network-alias mysql :设置要加入的网络,以及该容器在网络里的别名
  • -v todo-mysql-data:/var/lib/mysql :指定volume(注:之前没有创建过 todo-mysql-data volume,此时会自动被创建)
  • -e MYSQL_ROOT_PASSWORD=secret :设置环境变量
  • -e MYSQL_DATABASE=todos :设置环境变量

注: -v 选项比较复杂,既可以volume mount,也可以bind mount。本例中是mount一个volume。

下面是一些 -v 的源(即 : 左边)例子:

  • $(pwd) :正确,绝对路径
  • . :正确,宿主机相对路径
  • ./src :正确,宿主机相对路径
  • ./src/static :正确,宿主机相对路径
  • src :正确,表示一个volume名字
  • src/static :错误!Docker会把它当作volume的名字,但是包含了非法字符 /

接下来,我们先来测试一下MySQL数据库:

docker exec -it <container ID> mysql -u root -p

提示输入密码,输入 secret

登录成功后,查看数据库:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)

可见,已经创建好 todos 数据库了。

最后,输入 exit 退出。

至此,MySQL数据库已经准备好了。

在把应用连接到MySQL之前,我们先来看一下 nicolaka/netshoot ,它包含了很多有用的网络调试工具。

启动 nicolaka/netshoot 容器,并连接到 todo-app 网络:

➜  ~ docker run -it --network todo-app nicolaka/netshoot
Unable to find image 'nicolaka/netshoot:latest' locally
latest: Pulling from nicolaka/netshoot
8a49fdb3b6a5: Pull complete 
f08cc7654b42: Pull complete 
bacdb080ad6d: Pull complete 
df75a2676b1d: Pull complete 
d30ac41fb6a9: Pull complete 
3f3eebe79603: Pull complete 
086410b5650d: Pull complete 
4f4fb700ef54: Pull complete 
5a7fe97d184f: Pull complete 
a6d1b2d7a50e: Pull complete 
599ae1c27c63: Pull complete 
dd5e50b27eb9: Pull complete 
2681a5bf3176: Pull complete 
2517e0a2f862: Pull complete 
7b5061a1528d: Pull complete 
Digest: sha256:a7c92e1a2fb9287576a16e107166fee7f9925e15d2c1a683dbb1f4370ba9bfe8
Status: Downloaded newer image for nicolaka/netshoot:latestdP            dP                           dP   88            88                           88   
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P 
88'  `88 88ooood8   88   Y8ooooo. 88'  `88 88'  `88 88'  `88   88   
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88   
dP    dP `88888P'   dP   `88888P' dP    dP `88888P' `88888P'   dP   Welcome to Netshoot! (github.com/nicolaka/netshoot)
Version: 0.11

输入 dig mysql ,查看 mysql 的网络信息:

1ae405a48c1c  ~  dig mysql; <<>> DiG 9.18.13 <<>> mysql
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61648
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0;; QUESTION SECTION:
;mysql.				IN	A;; ANSWER SECTION:
mysql.			600	IN	A	172.18.0.2;; Query time: 8 msec
;; SERVER: 127.0.0.11#53(127.0.0.11) (UDP)
;; WHEN: Mon Jan 01 10:17:08 UTC 2024
;; MSG SIZE  rcvd: 44

可见, mysql 的IP地址是 172.18.0.2 。尽管 mysql 不是一个有效的hostname,Docker可以将其解析为IP地址,因为我们之前给MySQL容器设置过 --network-alias 。也就是说,我们只需把应用连接到 mysql ,就能连接MySQL数据库了。

在应用端需要设置一些MySQL连接的环境变量:

  • MYSQL_HOST
  • MYSQL_USER
  • MYSQL_PASSWORD
  • MYSQL_DB

注:在源代码里判断这些环境变量并做相应处理,Docker只是传入环境变量。

注意:在开发环境里,通过设置环境变量来设置MySQL连接信息的做法是OK的,但在生产环境里不推荐这么做,更安全的做法是,把这些私密信息放在文件里,然后mount到容器。很多应用也支持带 _FILE 后缀的环境变量,指定包含这些变量的文件。

接下来,启动应用,在 getting-started-app 根目录下,运行:

docker run -dp 127.0.0.1:3000:3000 \-w /app -v "$(pwd):/app" \--network todo-app \-e MYSQL_HOST=mysql \-e MYSQL_USER=root \-e MYSQL_PASSWORD=secret \-e MYSQL_DB=todos \node:18-alpine \sh -c "yarn install && yarn run dev"

其中:

  • -v "$(pwd):/app" :bind mount宿主机当前目录
  • --network todo-app :指定了要加入的网络,本例没有指定别名,因为不需要别人连接它
  • -e MYSQL_HOST=mysql :和下面几个环境变量一起,指定了数据库的连接信息

注: -v 选项比较复杂,既可以volume mount,也可以bind mount。本例中是bind mount一个宿主机目录(最好用绝对路径,如果用相对路径,貌似必须从 . 开始)。

然后,通过 docker ps 查看容器ID,并查看其log:

docker logs -f <container ID>

如下:

➜  getting-started-app git:(main) ✗ docker logs -f edf21888a43a
yarn install v1.22.19
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.35s.
yarn run v1.22.19
$ nodemon -L src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Waiting for mysql:3306.
Connected!
Connected to mysql db at host mysql
Listening on port 3000

可见,已经连接上mysql数据库。

打开浏览器,访问 http://localhost:3000 ,添加一些item。

接下来,在MySQL容器里,查看数据:

mysql> use todos;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> select * from todo_items;
+--------------------------------------+-------+-----------+
| id                                   | name  | completed |
+--------------------------------------+-------+-----------+
| 75900696-2daa-4e0e-91ef-07b8c4f532f0 | item1 |         0 |
| c4c9c814-22c4-4604-b145-c2380184e1b1 | item2 |         0 |
+--------------------------------------+-------+-----------+
2 rows in set (0.00 sec)

可见,刚刚添加的 itemitem2 已经保存在数据库里了。

Docker Compose

Compose用来定义多容器应用。只需在一个YAML文件里定义各个service,然后只用一条命令就能启动所有东西(容器,网络,volume等)。

getting-started-app 根目录下,创建 compose.yaml 文件如下:

services:app:image: node:18-alpinecommand: sh -c "yarn install && yarn run dev"ports:- 127.0.0.1:3000:3000working_dir: /appvolumes:- ./:/appenvironment:MYSQL_HOST: mysqlMYSQL_USER: rootMYSQL_PASSWORD: secretMYSQL_DB: todosmysql:image: mysql:8.0volumes:- todo-mysql-data:/var/lib/mysqlenvironment:MYSQL_ROOT_PASSWORD: secretMYSQL_DATABASE: todosvolumes:todo-mysql-data:

在该YAML文件中,定义了两个service,表示将会启动两个容器。

这两个容器会自动加到同一个网络里。service名字就是其网络别名:

  • app
  • mysql

我们可以把这两个service和前面对应的 docker run 命令对比一下,内容基本是一致的,只是语法不同而已。

注意:前面提到, docker run 命令里,若指定的volume不存在,则Docker会自动创建该volume。但对于Compose,必须显式创建volume。本例中,显式创建了volume todo-mysql-data

删除之前运行的容器,然后运行:

➜  getting-started-app git:(main) ✗ docker compose up -d
[+] Running 4/4✔ Network getting-started-app_default           Created                                                                                                                                                                                0.2s ✔ Volume "getting-started-app_todo-mysql-data"  Created                                                                                                                                                                                0.0s ✔ Container getting-started-app-mysql-1         Started                                                                                                                                                                                0.0s ✔ Container getting-started-app-app-1           Started 

可见,创建了一个网络,创建了一个volume,并且启动了两个容器。

查看compose的log:

➜  getting-started-app git:(main) ✗ docker compose logs -f 
......
app-1    | Connected to mysql db at host mysql
app-1    | Listening on port 3000
......
mysql-1  | 2024-01-01T14:11:24.084722Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.35'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

可见,应用已经启动成功。按下“Ctrl + C”退出log。

打开浏览器,访问 http://localhost:3000 ,测试应用工作正常。

注:之前填过的item都不见了,这是因为和之前使用的不是同一个volume。之前用的是 todo-mysql-data ,现在用的是 getting-started-app_todo-mysql-data

查看网络:

➜  getting-started-app git:(main) ✗ docker network ls        
NETWORK ID     NAME                          DRIVER    SCOPE
1903ef27abaa   getting-started-app_default   bridge    local
......
➜  getting-started-app git:(main) ✗ docker network inspect 1903ef27abaa
......"Containers": {"2faf22f53ea7ee2bafbf5b817b27b8220f86af9a06ab7dad500bc7721bfac76a": {"Name": "getting-started-app-app-1","EndpointID": "46bf8de5bb06982ae6ad121631d35b3fc9e20ed423978fdf0ecd7e29ede3ccaa","MacAddress": "02:42:ac:16:00:02","IPv4Address": "172.22.0.2/16","IPv6Address": ""},"4d549752261d29c672484b9e6cb68d6746a32d8fe77fdd6459c5dde2e2da28e5": {"Name": "getting-started-app-mysql-1","EndpointID": "d887f42ab3ed22f759e3f4bff45d83c6d2a162065a4237dd064f6c79585b7aa0","MacAddress": "02:42:ac:16:00:03","IPv4Address": "172.22.0.3/16","IPv6Address": ""}
......

最后,删除所有东西:

➜  getting-started-app git:(main) ✗ docker compose down
[+] Running 3/3✔ Container getting-started-app-app-1    Removed                                                                                                                                                                                       0.2s ✔ Container getting-started-app-mysql-1  Removed                                                                                                                                                                                       3.2s ✔ Network getting-started-app_default    Removed

注意:网络 getting-started-app_default 会和容器一起删除,但是volume getting-started-app_todo-mysql-data 不会删除。若想要删除volume,则需加上 --volumes 选项:

➜  getting-started-app git:(main) ✗ docker compose down --volumes                
[+] Running 4/4✔ Container getting-started-app-mysql-1       Removed                                                                                                                                                                                  3.0s ✔ Container getting-started-app-app-1         Removed                                                                                                                                                                                  0.2s ✔ Volume getting-started-app_todo-mysql-data  Removed                                                                                                                                                                                  0.0s ✔ Network getting-started-app_default         Removed

但是要慎用,一旦删除volume,持久化的数据就没了。下次再启动容器,之前的填过的item就不见了。

参考

  • https://docs.docker.com/get-started/
  • https://www.linuxidc.com/Linux/2015-09/123519.htm

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

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

相关文章

leetcode算法题之递归--综合练习(二)

本章目录 1.N皇后2.有效的数独3.解数独4.单词搜索5.黄金矿工6.不同路径III 1.N皇后 N皇后 class Solution {vector<vector<string>> ret;vector<string> path;int n;bool checkCol[10],checkDig1[20],checkDig2[20]; public:vector<vector<string&g…

Android 13.0 SystemUI状态栏居中显示时间和修改时间显示样式

1.概述 在13.0的系统rom定制化开发中,在systemui状态栏系统时间默认显示在左边和通知显示在一起,但是客户想修改显示位置,想显示在中间,所以就要修改SystemUI 的Clock.java 文件这个就是管理显示时间的,居中显示的话就得修改布局文件了 效果图如下: 2.SystemUI状态栏居中显…

conda安装transformers、wordcloud库

conda安装transformers库 使用 conda 自 Transformers 4.0.0 版始&#xff0c;我们有了一个 conda 频道&#xff1a; huggingface。 &#x1f917; Transformers 可以通过 conda 依此安装&#xff1a; conda install -c huggingface transformers安装起来就很通畅 conda查看…

NGINX 配置本地HTTPS(免费证书)

生成秘钥key,运行: $ openssl genrsa -des3 -out server.key 2048 会有两次要求输入密码,输入同一个即可。输入密码然后你就获得了一个server.key文件。 以后使用此文件(通过openssl提供的命令或API)可能经常回要求输入密码,如果想去除输入密码的步骤可以使用以下命令: $ op…

【JVM】一篇通关JMM内存模型

JMM内存模型 1. 原子性1-1. 问题分析1-2. 问题解决 2. 可见性2-1. 问题分析2-2. 问题解决 3. 有序性3-1. 问题分析3-2. 问题解决 4. CAS与原子性5. synchronized 优化 1. 原子性 很多人将【java 内存结构】与【java 内存模型】傻傻分不清&#xff0c;【java 内存模型】是 Java…

C++ queue

目录 一、介绍 二、queue使用 三、模拟实现 四、优先级队列 五、priority_queue使用 OJ题&#xff1a;215. 数组中的第K个最大元素 快速排序 优先级队列 TOPK 六、模拟实现priority_queue 1、仿函数 2、优先级队列类 3、测试函数 一、介绍 1、队列是一种容器适配器…

【React系列】高阶组件

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 高阶组件 1.1. 认识高阶组件 什么是高阶组件呢&#xff1f;相信很多同学都听说过&#xff0c;也用过 高阶函数&…

macOS 老版本系统恢复中出现“MacBook Pro无法与恢复服务器取得联系”

macOS 老版本系统恢复中出现“MacBook Pro无法与恢复服务器取得联系” 网络问题系统时间问题镜像索引问题 网络问题 系统时间问题 镜像索引问题 恢复模式的 “实用工具 > 系统终端” 里执行如下 nvram IASUCatalogURLhttps://swscan.apple.com/content/catalogs/others/i…

Vue页面传值:Props属性与$emit事件的应用介绍

一、vue页面传值 在Vue页面中传值有多种方式&#xff0c;简单介绍以下两种 通过props属性传递值&#xff1a;父组件在子组件上定义props属性&#xff0c;子组件通过props接收父组件传递的值。通过$emit触发事件传递值&#xff1a;子组件通过$emit方法触发一个自定义事件&#…

20.扫雷

题目 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int m sc.nextInt();int[][] f new int[n][m];for(int i0;i<n;i) {for(int j0;j<m;j) {f[i][j] sc.nextInt()…

TS学习笔记一:认识TS及环境准备

本次学习笔记是具有一定js基础的情况下从头开始学习ts相关内容。 视频信息 TS学习笔记一&#xff1a;认识TS及环境准备 B站视频 TS学习笔记一&#xff1a;认识TS及环境准备 西瓜视频 https://www.ixigua.com/7320049274006274560 1.1.目的 通过本次学习&#xff0c;学习并…

养乐多公司确认 95 G 用户私密数据被泄露

一名自称为DragonForce的组织声称已经公开泄露了澳大利亚养乐多公司&#xff08;Yakult Australia&#xff09;的95.19 GB数据。Yakult Australia证实了这次网络攻击的真实性&#xff0c;并表示公司在澳大利亚和新西兰的IT系统都受到了影响。 该公司在一份声明中表示&#xff…

21.串的处理

题目 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);String str sc.nextLine();char[] c str.toCharArray();int n c.length;StringBuilder st new StringBuilder();int i 0;while(i<n)…

C++学习笔记 ——this指针+对象数组

目录 一、Cthis指针 二、this指针的一个案列 三、对象数组 四、对象数组代码案列详解 一、Cthis指针 C中的this指针是一个特殊的指针&#xff0c;它指向当前对象的地址。在类中的成员函数中&#xff0c;this指针可以用来访问当前对象的成员变量和成员函数。 当我们调用一…

轻松玩转书生·浦语大模型趣味Demo

轻松玩转书生浦语大模型趣味Demo 大模型及InternLM模型介绍InternLM模型全链路开源 InternLM-Chat-7B智能对话Demo模型介绍模型部署webDemo运行 Lagent智能体工具调用DemoLagent介绍 浦语灵笔图文创作理解Demo通用环境配置模型下载 大模型及InternLM模型介绍 人工智能领域中 参…

shell 计算两个数据百分比,bc高级运算,bc计算系统磁盘剩余内存

目录 安装运算工具 bc使用方法高级数学库 (直接把公式 给他即可)计算百分比计算内存已经使用的百分比计算圆周率 安装运算工具 bc yum -y install bc使用方法 echo $((10/3)) | bc高级数学库 (直接把公式 给他即可) echo $((24)) | bc -l计算百分比 这里是 bc 的用法 也是计…

深度学习 Day24——J3-1DenseNet算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 文章目录 前言1 我的环境2 pytorch实现DenseNet算法2.1 前期准备2.1.1 引入库2.1.2 设…

「Verilog学习笔记」编写乘法器求解算法表达式

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule calculation(input clk,input rst_n,input [3:0] a,input [3:0] b,output [8:0] c);reg [8:0] data1, data2 ; assign c data2 ; always (posed…

猫咪主食罐头巅峰、希喂、K9哪款好?猫咪主食罐头真实对比测评

在当前科学喂养观念广泛传播的背景下&#xff0c;铲屎官们对猫咪主食的营养价值和健康性有了更高的要求。作为猫咪日常成长和活动的主要能量来源&#xff0c;主食的营养价值对猫咪的健康状况有着直接的影响。特别是对于处于成长期的猫咪来说&#xff0c;选择一款优质的主食对其…

关键词优化完整 “操作 “指南

关键词优化的定义 在内容中突出相关关键词的行为&#xff0c;有助于将谷歌流量引向您的网站。关键词优化要求内容创建者做到以下几点&#xff1a; 研究并发现最佳关键词找到自然的方式在内容中突出相关词语 看看&#xff0c;你已经创建了一些很棒的内容。你做了研究&#xf…