Docker 使用与部署(超详细)
目录
引入
入门使用
部署对比
镜像仓库
命令解释
基础
常见命令
示例
数据卷的使用
数据卷的概念
数据卷的使用
挂载本地目录文件
镜像
结构
Dockerfile
容器网络
部署
DockerCompose
语法
编辑
基础命令
引入
当我们在 Linux 上部署一个集成了很多中间件的单体项目的时候,会发现命令太多不易记住,软件安装包的名字复杂,安装和部署步骤复杂,容易出错。在部署微服务项目的时候,由于需要部署的服务器数量众多,并且每一台服务器的运行环境也不一样,写好的安装流程,部署脚本并不一定在每个服务器都能正常运行,经常出错。这就给系统的部署运维带来了诸多困难,那有没有一种技术能够避免部署对服务器环境的依赖,减少复杂的部署流程呢?有的兄弟,有的,这就是即将要介绍的 Docker 技术。
Docker 是一种 容器化技术,它可以把应用程序及其所有依赖(库、环境、配置)打包到一个 轻量级、可移植的容器 中,这个容器可以在任何支持 Docker 的环境中快速运行。那 Docker 除了简化部署流程还有那些有点呢?
- 解决“在我的电脑上可以跑”的问题:Docker 容器打包了完整的运行环境,确保无论是在开发、测试还是生产环境,运行效果一致
- 轻量级:容器比虚拟机(VM)更轻,因为它们共用宿主机的操作系统内核,不需要额外的系统资源
- 快速部署与启动:容器启动速度快,适合微服务、自动化部署、持续集成/持续交付(CI/CD)场景。
-
易于拓展和管理:配合 Kubernetes 等编排工具,Docker 容器可以方便地进行扩缩容和负载均衡。
-
方便版本控制和回滚:Docker 镜像支持版本化,能快速切换或回退到指定版本。
入门使用
部署对比
我们先对比 Docker 部署 MySQL 和传统部署 MySQL 的方式:
传统部署 MySQL 的话需要:
- 搜索并下载 MySQL 的安装包
- 上传至 Linux 环境
- 编译和配置环境
- 安装,之后还要进行一些权限设置
Docker 部署 MySQL 只需要在命令行中输入一下命令:
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \mysql:8.0(版本号)
输入完之后 Docker 就会去自动搜索并下载了 MySQL ,然后自动运行 MySQL ,这个时候你可以通过任意客户端工具去连接它了。
并且,这种方式完全不用考虑运行的操作系统的环境,这条命令在所有的操作系统中,比如 CentOS,Ubuntu,MacOS,Kali 等等,都是可以用这一条命令运行的。
不同的操作系统下,一个软件的安装包,运行环境都是不相同的。如果是手动安装,必须手动解决安装包不同,运行环境不同,配置环境不同的问题。比如你安装软件的时候是不是下面都会有 Windows ,MacOS,Linux 这三个版本的安装包供你下载,并且每一个系统的安装包版本还可以细分更多别的版本,这个时候你要手动选择适合你电脑系统的版本安装包,而 Docker 就不需要这些,直接“一键式”安装,有点像 Mac 里面的 Homebrew。
在使用 Docker 的时候,以上说的这些完全不用考虑,因为 Docker 会自动搜索并下载 MySQL。但是这里的下载的并不是安装包,而是它的“镜像”。镜像中不仅仅包含了 MySQL 本身,还包含了它运行所需要的环境,配置,系统级函数库,因此在它运行的时候就会有自己独立的环境,就可以跨系统运行,也不需要手动配置环境了。这套独立的隔离环境被称为“容器”。所以,Docker 安装软件的过程,就是自动搜索下载镜像,然后创建并运行容器的过程。
镜像仓库
Docker 官方提供了一个专门管理,存储镜像的网站,并对外开放了镜像上传,下载的权利。Docker 官方提供了一些基础的镜像,然后各大软件公司又在基础镜像的基础上,制作了自家软件的镜像,全部存放在这个网站,并成了 Docker 镜像的交流社区(这套机制有点像 Maven 仓库):Docker 镜像交流社区。因此 Docker 会根据命令中的镜像名称自动去这里面搜索并下载镜像。
像这种提供存储,管理 Docker 镜像的服务器,被称为 “DockerRegistry”。DockerHub 网站是官方仓库,但是官方仓库在国外,下载速度较慢,一般都会使用阿里云,华为云等等的第三方仓库提供镜像加速功能,提高下载速度。我们也可自己搭建私有的镜像仓库,而企业内部的机密项目,往往就会采用私有镜像仓库,所以镜像来源有:
- 基于官方基础镜像自己制作
- 直接去 DockerRegistry 下载
总结:Docker 本身包含一个后台服务,我们可以利用 Docker 命令告诉服务,帮我们快速部署指定应用。Docker 服务部署应用的时候,首先去搜索并下载应用对应的镜像,然后根据镜像创建并运行容器,应用就部署完成了:
命令解释
我们就先针对上面的那一条部署 MySQL 命令去解释一下:
- docker run -d:创建并运行一个容器,-d 则是让容器以后台进程运行
- --name mysql:给容器起个名字叫 mysql,这个名字也是可以起别的
- -p 3306:3306:设置端口映射。容器是隔离环境,外界不可访问,但是可以将宿主机端口映射到容器内的端口,当访问宿主机指定端口的时候,就是在访问容器内端口了。容器内端口往往是由容器内进程决定的,例如 MySQL 进程默认端口是3306,因此容器内端口一定是3306,而宿主机端口可以任意绑定;格式: -p 宿主机端口:容器内端口,示例端口就是将宿主机的3306映射到容器内的3306端口
- -e TZ=Asia/Shanghai:配置容器内进程运行的一些参数,格式:-e KEY = VALUE ,KEY 和 VALUE 都是由容器内进程决定,上面的 TZ = Asia/Shanghai 是设置时区;MYSQL_ROOT_PASSWORD=123 是设置 MYSQL 的默认密码
- mysql:设置镜像名称,Docker 会根据这个名字搜索并下载镜像;格式:REPOSITORY:TAG,例如 mysql:8.0 ,其中 REPOSITORY 可以理解镜像名称,TAG 是版本号。在未指定TAG的情况下,默认是最新版本,也就是 mysql:latest
镜像名称不是随意的,而是要到 DockerRegistry 中寻找,镜像运行时的配置也不是随意的,要参考镜像的帮助文档,这些 DockerHub 网站或者软件的官方网站中都能找到;如果我们要安装其他软件,也可以到 DockerRegistry 中寻找对应的镜像名称和版本,阅读相关配置。
基础
常见命令
图片表示:
默认情况下,每次重启虚拟机都需要手动重启 Docker 和 Docker 中的容器,通过一下命令可以实现开机自启动:
# Docker 开机自启动 systemctl enable docker@ Docker 容器开机自启 docker update --restart=always [容器名/容器id]
示例
接下来就是通过 Docker 部署一个 Nginx 来演示:
# 去 DockerHub 查看 Nginx 镜像仓库以及信息
# 拉取 Nginx 镜像
docker pull nginx#查看镜像,如果成功拉取的话就会显示在下面中
docker images# 创建并允许 Nginx 容器
docker run -d --name nginx -p 90:80 nginx# 查看运行中的容器(格式化访问)
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Name}}"# 访问对应的网页
# 停止容器
docker stop nginx# 查看所有容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Name}}"# 再次启动 Nginx 容器
docker start nginx# 再次查看容器
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Name}}"# 查看容器的详细信息
docker inspect nginx# 进入容器,查看容器内的目录
docker exec -it nginx bash
# 这是进入 mysql 容器并进入 mysql
docker exec -it mysql mysql -uroot -p# 删除容器
docker rm nginx# 强制删除容器
docker rm -f nginx
由于格式化查看容器的命令较长,但是不格式话查看的话无用信息又很多,所以我们可以给命令取别名,方便以后进行访问:
# 修改/root/.bashrc文件 vi /root/.bashrc 内容如下: # .bashrc# User specific aliases and functionsalias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"' alias dis='docker images'# Source global definitions if [ -f /etc/bashrc ]; then. /etc/bashrc fi# 退出去之后 source ./.bashrc 使得命令生效
数据卷的使用
数据存储一直是不管软件还是硬件都需要考虑的重要问题,而容器也需要考虑自己的数据存储,但是由于容器是隔离环境,容器内的程序的文件,配置,运行时产生的数据都在容器内部,所以读写容器内的文件不是很方便,因此,容器提供程序的运行环境,但是程序运行时产生的数据,依赖的配置都应该与容器进行解耦合。
数据卷的概念
数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。以刚刚拉取的 Nginx 为例,Nginx 中有两个关键的目录:
- html:放置静态资源
- conf:放置配置文件
如果要让 Nginx 代理静态资源,最好是放在 html 目录;如果要修改 Nginx 的配置,最好在 conf 目录下面的 nginx.conf 文件,但是容器运行的 Nginx 所有文件都在容器内部,所以需要利用数据卷将两个目录与宿主机目录进行关联,方便修改操作,而且他们还是双向绑定的,就是你宿主机的目录中文件修改的话,对应的容器内的数据也会被修改。
假设我们创建了两个数据卷:conf,html;Nginx 容器内部的 conf 目录和 html 目录分别与两个数据卷关联,而数据卷 conf 和 html 分别指向了宿主机对应的 /var/lib/docker/volumes/conf/_data 目录和 /var/lib/docker/volumes/html /_data 目录;
这样的话,容器内的 conf 和 html 目录就和宿主机的 conf 和 html 目录关联起来了,称为挂载。此时,在宿主机操作 /var/lib/docker/volumes/html/_data 就是在操作容器内的 /usr/share/nginx/html/_data 目录。只要将静态资源放入宿主机对应目录,就可以被 Nginx 代理。
/var/lib/docker/volumes 就是 Linux 下默认存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为 /数据卷名/_data
之所以不让容器目录直接指向宿主机目录,而是通过数据卷当中间桥梁间接访问,是因为如果直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能会发生改变,但由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作;但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机之前的映射关系就行。
数据卷的使用
注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。
1,下面可以看一下 Nginx 的目录挂载:
# 首先创建容器并指定数据卷,注意通过 -v 参数在最后来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx# 然后查看数据卷
docker volume ls# 查看数据卷详情
docker volume inspect html
# 结果
[{"CreatedAt": "2024-05-17T19:57:08+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/html/_data","Name": "html","Options": null,"Scope": "local"}
]# 查看 /var/lib/docker/volumes/html/_data 目录
ls /var/lib/docker/volumes/html/_data# 进入目录并修改 index.html 内容
cd /var/lib/docker/volumes/html/_data
vim index.html# 进入容器内部。查看 /var/share/nginx/html 目录内的文件是否变化
docker exec -it nginx bash
2,当我们拉取 MySQL 的镜像没有 -v 指定参数时候,但是通过 docker inspect mysql 命令查看容器信息的时候,会发现在 .Config.Volumes 这个信息的下面会发现 MySQL 这个容器声明了一个本地目录,需要挂载数据卷,但是数据卷未定义,这就是匿名卷:
{"Config": {// ... 略"Volumes": {"/var/lib/mysql": {}}// ... 略}
}
然后再观察 .Mounts 部分:
{"Mounts": [{"Type": "volume","Name": "29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f","Source": "/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data","Destination": "/var/lib/mysql","Driver": "local",}]
}
可以发现:
- Name:数据卷名称。由于定义容器未设置容器名称,这里就是匿名卷自动生成的名字,一串 hash 值。
- Source:宿主机目录
- Destination:容器内的目录
解释:上面的配置是将容器内的 /var/lib/mysql 这个目录,与数据卷 29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f 挂载,于是在宿主机中就有了 /var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data 这个目录。这就是匿名数据卷对应的目录。然后就可以切换到改目录下面查看 MySQL 的 data 文件.
挂载本地目录文件
我们除了使用数据卷进行间接访问,还可以直接将容器文件挂载到本地文件,只不过正如上诉所说有一定的弊端,但是数据卷的目录结构较深,直接去操作数据卷目录不是很方便,在很多情况下,会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:
- 挂载本地目录:-v 本地目录:容器内目录
- 挂载本地文件:-v 本地文件:容器内文件
注意:本地目录或者文件必须以 / 或 ./ 开头,如果直接以名字开头,会被识别为数据卷名字。
- -v mysql:/var/lib/mysql 会被识别为一个数据卷名字叫 mysql ,并在运行时创建这个数据卷
- -v ./mysql:/var/lib/mysql 会被识别为当前目录下面的 mysql 目录,运行时不存在会自动创建
演示:挂载 MySQL 的数据和配置目录
# 创建并运行新mysql容器,挂载本地目录
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \mysql
镜像
之前所说我们拉取的镜像,有部分是官方提供的,有部分是一些厂商提供的,而我们也可以自定义一些镜像供别人进行部署,这就叫打包镜像。
结构
镜像之所以能够跨操作系统部署应用而忽略其运行环境,配置,就是因为镜像中包含了程序运行需要的系统函数库,环境,配置,依赖。因此自定义镜像本质就是一次准备好程序运行的基础环境,依赖,应用本身,运行配置等文件,并且打包而成,一下以部署 Java 项目为例:
传统部署:
- 准备 Linux 服务器
- 安装配置 JDK
- 上传 jar 包
- 运行 jar 包
打包镜像:
- 准备 Linux 运行环境
- 暗转配置 JDK
- 拷贝 jar 包
- 配置启动脚本
上诉操作中每一步都是在生产一些文件(系统运行环境,函数库,配置,最后都是磁盘文件),所以镜像就是一堆文件的集合。但是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加的,每一层形成的文件都会单独打包并标记一个唯一 id ,称为 Layer (层) 。这样,如果我们构建时用到某些层其他人已经或者已经拉取过了,就可以直接拷贝使用这些层,而不用重复拉取。
在第一步中需要的 Linux 运行环境就有很强的通用性,所以 Docker 官方就制作了这样的只包含 Linux 运行环境的镜像,在制作 Java 镜像的时候,就不需要重复制作,直接使用 Docker 官方提供的 Linux (CentOS/Ubuntu) 镜像作为基础镜像,然后再搭建其他层:
Dockerfile
在制作镜像的过程中,需要逐层打包较为复杂,所以 Docker 就提供了自动打包镜像的功能。只需将打包的过程,每一层要做的事情用固定的语法写下来,交给 Docker 执行,而这种记录镜像结构的文件就是 Dockerfile(注意区分下面要要讲解的Docker-compose) 。下面是基础语法:
一下是基于 Ubuntu 构建 Java 应用的 Dockerfile:
# 指定基础镜像
FROM ubuntu:16.04# 配置环境变量,JDK 安装目录,容器时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai# 拷贝 JDK 和 Java 项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone# 安装 JDK
RUN cd $JAVA_DIR && tar -xf ./jdk8.tar.gz && mv ./jdk1.8.0_144 ./java8# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin# 指定项目监听的端口
EXPOSE 8080# 入口,Java 项目的启动命令
ENTRYPOINT ["java","-jar","/app.jar"]
我们每次构建 Java 镜像的时候,都需要拉取 Linux 和 JDK 环境,所以有人提供了基础的系统加 JDK 环境,在此基础上制作 Java 镜像,就可以省去 JDK 的配置了:
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
构建镜像:
# 进入镜像目录
cd /root/demo# 开始构建
docker build -t docker-demo:1.0 .
- docker build:就是构建一个 docker 镜像
- -t docker-demo:1.0: -t 参数是指定镜像的名字
- .:最后的点是构建镜像的时候 Dockerfile 所在的目录
运行完之后再次查看镜像列表就可以查看到对应的镜像了,运行之后就可以正常访问对应的 Java 项目了。
容器网络
在 Java 项目中需要访问其它各种中间件,例如 MySQL ,Redis 等,容器之间也能通过 IP:Port 进行相互访问,每个容器都有自己的独立的 IP 地址(每次重启的时候随机分配):
# 用基本命令,寻找 Networks.bridge.IPAddress 属性并使用 format 过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql# 得到 IP 地址:
172.17.0.2# 通过命令进入其它任意容器
docker exec -it anyone bash# 通过 ping 命令进行测试网络
ping 172.17.0.2# 正常返回结果
虽然可以访问,但是容器内的网络 IP 其实是一个虚拟 IP ,这个 IP 并不固定的与某一个容器进行绑定,如果在开发的时候写死某一个容器 IP,在部署的时候可以那个容器的 IP 就会发生变化导致连接失败。Docker 就有一个方法解决这个问题:在容器中创建一个虚拟的局域网络,然后让需要被部署的容器都加入到这个网络中,虽然每一个容器的 IP 仍然会发送变化,但是在同一个网络中,容器之间相互通讯就不是通过 IP 了,而是通过容器名字进行查找连接,这样就不会因为 IP 的变化而找不到对应的容器了,毕竟每一个容器的名字是唯一的;常见命令:
自定义网络:
# 创建网络
docker network create chase# 查看网络
docker network ls# 让 nginx 和 mysql 都加入到该网络中,并取别名(可选)
docker network connect chase mysql --alias db
docker network connect chase nginx# 进入 nginx 容器,并尝试访问 db 容器
docker exec -it nginx bash
ping db
# 也可以通过容器名字访问
ping mysql
部署
DockerCompose
当我们部署的 Java 项目较为复杂的时候,可能包含很多容器(中间件),如果手动部署的话就显得很麻烦了。这时,DockerCompose 就可以帮助我们实现多个相互关联的 Docker 容器快速部署。它允许用户通过一个单独的 docker-compose.yml 模版文件(yaml 格式)(与上面说的Dockerfile区分)来定义一组相关联的应用。
语法
docker-compose 文件中可以定义多个相互关联的应用容器,每一个应用容器被称为服务(service)。由于 service 就是定义某个应用的运行时参数,因此与 docker run 参数类似;
我们将用 docker run 部署 MySQL 和用 docker-compose.yml 来定义 MySQL 对比一下:
# 用 docker run
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \--network chasemysql:3.8# 用 docker-compose.yml
version: "3.8"services:mysql:image: mysqlcontainer_name: mysqlports:- "3306:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- "./mysql/conf:/etc/mysql/conf.d"- "./mysql/data:/var/lib/mysql"networks:- new
networks:new:name: chase
基础命令
在编写好 docker-compose.yml 文件之后就可以通过一些常见命令来部署项目了:
# 基本语法
docker compose options command
# 进入 root 目录
cd /root# 删除旧容器
docker rm -f contrainer_name# 删除 chase 镜像
docker rmi chase# 清空 MySQL 数据
rm -rf mysql/data# 启动所有
docker compose up -d# 查看镜像
docker compose images# 查看容器
docker compose ps
以上就是本文的全部内容,涵盖了几乎日常中使用 Docker 所需要的全部命令,也不用全部背下来,可以点个收藏加关注,需要的时候在来这边找对应的命令就行了,我也是用的时候才去找对应的命令 (^ - ^ )。
相关文章:
Docker 使用与部署(超详细)
目录 引入 入门使用 部署对比 镜像仓库 命令解释 基础 常见命令 示例 数据卷的使用 数据卷的概念 数据卷的使用 挂载本地目录文件 镜像 结构 Dockerfile 容器网络 部署 DockerCompose 语法 编辑 基础命令 引入 当我们在 Linux 上部署一个集成了很多中间件…...
Android第三次面试总结之Java篇补充
一、Array 与 ArrayList 在 Android 中的深度对比与优化 1. 内存模型与性能差异的本质原因 数组(Array)的内存布局 基本类型数组(如 int[])在 Java 中是连续的原始数据块,直接存储值,无额外对象开销&#…...
CVPR2023 | 通过降低对图像块损坏的敏感性来提高视觉Transformer的鲁棒性
Improving Robustness of Vision Transformers by Reducing Sensitivity to Patch Corruptions 摘要-Abstract引言-Introduction相关工作-Related Work降低对Patch损坏的敏感性-Reducing Sensitivity to Patch Corruptions实验-Experiments分析与讨论-Analysis and Discussions…...
NV228NV254固态美光颗粒NV255NV263
NV228NV254固态美光颗粒NV255NV263 美光颗粒固态硬盘技术解析与选购指南 一、美光颗粒技术体系解析 1. 颗粒分类与性能差异 美光颗粒采用独特编号体系,NV254(如MT29F8T08GLLBHL4-36QMES)代表8Tb TLC颗粒,采用BOS(浮…...
LeetCode 1007. 行相等的最少多米诺旋转 题解
示例 输入:tops [2,1,2,4,2,2], bottoms [5,2,6,2,3,2] 输出:2 解释: 图一表示:在我们旋转之前, tops 和 bottoms 给出的多米诺牌。 如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个…...
c盘怎么安全清理---微软电脑管家
1、c盘红了怎么办 问了ai,也是要安装第三方的软件,win自带的不行吗?找找看 2、主角登场 仔细一看确实是官方自带的 3、使用自带工具扫描 4、转移文件到其他的盘 系统应用管理中的工具里面有个可以转移安装的软件到d盘,有一些软…...
C语言----指针入门篇
1. 指针是什么? 指针理解的两个要点: 1. 指针是内存中一个最小单元的编号 也就是地址 2. 平时口语中说的指针 通常指的是指针变量 是用来存放内存地址的变量 下面我将会具体解释上面两个要点 这时我们就不得不提一提内存了 1.1 什么是内存呢? C语言中的内存布局 程序…...
GitHub 趋势日报 (2025年05月03日)
本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1hacksider/Deep-Live-Camreal time face swap and one-click video deepfake with only a single image⭐ 1582⭐ 59337Python2aip…...
Go-Spring 全新版本 v1.1.0
Go-Spring 全新版本 v1.1.0 已于 2025 年发布。该版本具有诸多新特性,具体如下: 命名与结构优化:命名更加符合 Go 规范,模块划分更加合理,核心设计更加简洁。功能增强:突破性地支持统一日志框架,…...
JVM——JVM是怎么实现invokedynamic的?
JVM是怎么实现invokedynamic的? 在Java 7引入invokedynamic之前,Java虚拟机(JVM)在方法调用方面相对较为“僵化”。传统的Java方法调用主要依赖于invokestatic、invokespecial、invokevirtual和invokeinterface这四条指令&#x…...
使用 IDEA + Maven 搭建传统 Spring MVC 项目的详细步骤(非Spring Boot)
搭建Spring MVC项目 第一步:创建Maven项目第二步:配置pom.xml第三步:配置web.xml第四步:创建Spring配置文件第五步:创建控制器第六步:创建JSP视图第七步:配置Tomcat并运行目录结构常见问题解决与…...
洛谷 P1495:【模板】中国剩余定理(CRT)/ 曹冲养猪
【题目来源】 https://www.luogu.com.cn/problem/P1495 https://www.acwing.com/problem/content/225/ 【题目描述】 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪。可是曹冲满不高兴,于是在工作中马马虎…...
【iOS】 分类 拓展 关联对象
【iOS】 分类 拓展 关联对象 文章目录 【iOS】 分类 拓展 关联对象前言拓展分类分类与拓展的区别分类拓展关联对象哈希表(AssociationsHashMap) 大致工作流程setgetremove 关联对象的释放时机总结 前言 之前讲过有关于类对象的内容,这里学习一下有关于类的分类拓展和关联对象的…...
iview 老版本合并单元格
新版的iview中已经支持了合并单元格了,我的版本比较老,为:"iview": "^3.5.2"。暂不支持。记录一下别的大佬的方法。感觉思路比较活,正在这种思路需要在解决问题的过程中学习。 核心思路:通过rende…...
go语言实现用户管理系统
goweb实现用户管理系统 用户后台管理系统功能描述 登录功能 支持用户通过邮箱密码和密码进行登录。对输入的邮箱和密码进行验证,确保用户信息的正确性。登录成功后,更新用户的今日登录统计信息,并将用户信息存入会话(cookie&am…...
普通IT的股票交易成长史--20250504实盘记录
声明:本文章的内容只是自己学习的总结,不构成投资建议。价格行为理论学习可参考简介中的几位,感谢他们的无私奉献。 送给自己的话: 仓位就是生命,绝对不能满仓!!!!&…...
SQL手工注入(DVWA)
手工SQL注入攻击的标准思路 Low等级 (1)判断是否存在注入 (2)猜解字段个数 (3)确定字段顺序 (4)获取当前数据库 (5)获取当前数据库中的表 (…...
【LLM】deepseek R1之GRPO训练笔记(持续更新)
note 相关框架对比: 需微调模型且资源有限 → Unsloth;本地隐私优先的小规模推理 → Ollama;复杂逻辑或多模态任务 → SGLang;高并发生产环境 → vLLM 微调SFT和GRPO是确实能学到新知识的四种格式(messages、sharegpt…...
序列到序列学习
seq2seq 就是把一个句子翻译到另外一个句子。 机器翻译 给定一个源语言的句子,自动翻译成目标语言这两个句子可以有不同的长度 seq2seq 是一个 Encoder - Decoder 的架构 编码器是一个 RNN , 读取输入句子(可以是双向) 解码…...
去打印店怎么打印手机文件,网上打印平台怎么打印
在数字化时代,手机已成为我们存储和传输文件的重要工具。然而,当需要将手机中的文件转化为纸质文档时,许多人会面临选择:是前往线下打印店,还是利用线上打印平台?本文将为您解析这两种方式的优劣࿰…...
LeetCode每日一题5.4
1128. 等价多米诺骨牌对的数量 问题 问题分析 等价的定义为:两个骨牌 [a, b] 和 [c, d] 等价,当且仅当 (a c 且 b d) 或者 (a d 且 b c)。 思路 标准化骨牌表示: 为了方便比较,我们可以将每个骨牌 [a, b] 标准化为 [min(a…...
前端小练习————表白墙+猜数字小游戏
1,猜数字游戏 实现一个这个样式的 要猜的目标数字 点击重新开始游戏之后: 代码实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widt…...
五年级数学知识边界总结思考-上册
目录 一、背景二、过程1.小数乘法和除法小学五年级小数乘除法的知识点、由来、作用与意义解析**一、核心知识点梳理****二、知识点的由来****三、作用与意义****四、教学意义** **总结** 2.位置小学五年级“位置”知识点、由来、作用与意义解析**一、核心知识点梳理****二、知识…...
C与指针——内存操作与动态内存
1、内存常用操作 void* memcpy(void* dst,const void* src,size_t length); \\内存不允许重叠 void* memmove(void* dst,const void* src,size_t length); \\内存允许重叠 int memcmp(const void* dst,const void* src,size_t length); \\相等返回0 void* memset(void* dst,in…...
P3469 [POI 2008] BLO-Blockade
P3469 [POI 2008] BLO-Blockade 题目描述 B 城有 n n n 个城镇(从 1 1 1 到 n n n 标号)和 m m m 条双向道路。 每条道路连结两个不同的城镇,没有重复的道路,所有城镇连通。 把城镇看作节点,把道路看作边&…...
Linux网络编程 day3 五一结假
基本概念 三次握手 主动发起连接请求端,发送SYN标志位,请求建立连接。携带数据包包号、数据字节数(0)、滑动窗口大小。 被动接收连接请求端,发送ACK标志位,同时携带SYN请求标志位。携带序号、确认序号、数据包包号、数据字节数…...
解释一下NGINX的反向代理和正向代理的区别?
大家好,我是锋哥。今天分享关于【解释一下NGINX的反向代理和正向代理的区别?】面试题。希望对大家有帮助; 解释一下NGINX的反向代理和正向代理的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 NGINX 作为一个高效的反向代理服务器&a…...
Coco AI 入驻 GitCode:打破数据孤岛,解锁智能协作新可能
在信息爆炸时代,企业正面临前所未有的挑战: 企业数据和信息分散,数据孤岛现象严重,员工往往浪费大量时间跨平台检索;跨部门协作困难,团队因信息隔阂导致项目延期;数据安全问题严峻,…...
【QT】QT中的网络编程(TCP 和 UDP通信)
QT中的网络编程(TCP 和 UDP通信) 1.tcp1.1 tcp通信1.1.1 相比linux中tcp通信:1.1.2 QT中的tcp通信: 1.2 tcp通信流程1.2.1 服务器流程:1.2.1.1 示例代码1.2.1.2 现象 1.2.2 客户端流程:1.2.2.1 示例代码1.2.2.2 现象: …...
个性化推荐:大数据引领电子商务精准营销新时代
个性化推荐:大数据引领电子商务精准营销新时代 引言 在电子商务的时代,个性化推荐系统已经成为提升用户体验、增强平台竞争力的重要技术。随着大数据技术的迅猛发展,传统的推荐方法已经无法满足用户日益增长的需求。为了精准地把握用户兴趣和消费倾向,商家们依赖大数据分析…...
【前端】【总复习】HTML
一、HTML(结构) HTML 是网页的骨架,主要负责网页的结构与语义表达,为 CSS 和 JavaScript 提供承载基础。 1.1 HTML 基本结构与语义化标签 1.1.1 HTML 基本结构 <!DOCTYPE html> <html lang"en"> <hea…...
Android 输入控件事件使用示例
一 前端 <EditTextandroid:id="@+id/editTextText2"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10"android:inputType="text"android:text="Name" />二 后台代…...
JVM happens-before 原则有哪些?
理解Java Memory Model (JMM) 中的 happens-before 原则对于编写并发程序有很大帮助。 Happens-before 关系是 JMM 用来描述两个操作之间的内存可见性以及执行顺序的抽象概念。如果一个操作 A happens-before 另一个操作 B (记作 A hb B),那么 JMM 向你保证&#x…...
Python实例题:Python获取NBA数据
目录 Python实例题 题目 方式一:使用网页爬虫获取数据 代码解释 get_nba_schedule 函数: 主程序: 方式二:使用专业 API 获取数据 代码解释 运行思路 方式一 方式二 注意事项 以下是完整的 doubaocanvas 代码块&#…...
【中间件】brpc_基础_remote_task_queue
文章目录 remote task queue1 简介2 核心功能2.1 任务提交与分发2.2 无锁或低锁设计2.3 与 bthread 深度集成2.4 流量控制与背压 3 关键实现机制3.1 数据结构3.2 任务提交接口3.3 任务窃取(Work Stealing)3.4 同步与唤醒 4 性能优化5 典型应用场景6 代码…...
React-router v7 第七章(导航)
导航 在React-router V7中,大致有四种导航方式: 使用Link组件 link使用NavLink组件 navlink使用编程式导航useNavigate usenavigate使用redirect重定向 redirect Link Link组件是一个用于导航到其他页面的组件,他会被渲染成一个<a>…...
Terraform 中的 external 数据块是什么?如何使用?
在 Terraform 中,external 数据块(Data Block) 是一种特殊的数据源,允许你通过调用外部程序或脚本获取动态数据,并将结果集成到 Terraform 配置中。它适用于需要从 Terraform 外部的系统或工具获取信息的场景。 一、e…...
打印Excel表格时单元格文字内容被下一行遮盖的解决方法
本文介绍在打印Excel表格文件时,单元格最后一行的文字内容被下一行单元格遮挡的解决方法。 最近,需要打印一个Excel表格文件。其中,已知对于表格中的单元格,都设置了自动换行,如下图所示。 并且,也都设置了…...
【Linux】命令行参数与环境变量
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、命令行参数 1. 什么是命令行参数 2. 命令行参数的作用 二、环境变量 1. 基本概念 2. 常见的环境变量 3. 环境变量相关操作 定义…...
Dify 完全指南(一):从零搭建开源大模型应用平台(Ollama/VLLM本地模型接入实战)》
文章目录 1. 相关资源2. 核心特性3. 安装与使用(Docker Compose 部署)3.1 部署Dify3.2 更新Dify3.3 重启Dify3.4 访问Dify 4. 接入本地模型4.1 接入 Ollama 本地模型4.1.1 步骤4.1.2 常见问题 4.2 接入 Vllm 本地模型 5. 进阶应用场景6. 总结 1. 相关资源…...
民法学学习笔记(个人向) Part.3
民法学学习笔记(个人向) Part.3 8. 诉讼时效🌸 概念: 是指权利主体在法定期间内不行使权利,则债务人享有抗辩权,可以导致权利人无法胜诉的法律制度(有权你不用,别人就有话说了&#…...
C# 方法(返回值、返回语句和void方法)
本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 返回值 方法可以向调用代码返…...
打电话玩手机检测数据集VOC+YOLO格式8061张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):8061 标注数量(xml文件个数):8061 标注数量(txt文件个数):8061 …...
详解如何压测RocketMQ
目录 1.如何设计压测 2.压测工具 3.硬件配置 4.写代码压测 5.自带压测脚本 1.如何设计压测 二八定律法则:按业务峰值的 120% 设计压测目标(若线上峰值1000TPS,压测目标至少1200TPS) 关注三个指标 吞吐量(TPS&…...
实验三 触发器及基本时序电路
1.触发器的分类?各自的特点是什么? 1 、 D 触发器 特点:只有一个数据输入端 D ,在时钟脉冲的触发沿,输出 Q 的状态跟随输入端 D 的 状态变化,即 ,功能直观,利于理解和感受…...
双列集合——map集合和三种遍历方式
双列集合的特点 键和值一一对应,每个键只能对应自己的值 一个键和值整体称为键值对或键值对对象,java中叫做entry对象。 map常见的api map接口中定义了双列集合所有的共性方法,下面三个实现类就没有什么额外新的方法要学习了。 map接口…...
WebRTC 服务器之Janus视频会议插件信令交互
1.基础知识回顾 WebRTC 服务器之Janus概述和环境搭建-CSDN博客 WebRTC 服务器之Janus架构分析-CSDN博客 2.插件使用流程 我们要使⽤janus的功能时,通常要执⾏以下操作: 1. 在你的⽹⻚引入 Janus.js 库,即是包含janus.js; <…...
LabVIEW温控系统热敏电阻滞后问题
在 LabVIEW 构建的温控系统中,热敏电阻因热时间常数大(2 秒左右)产生的滞后效应,致使控温出现超调与波动。在不更换传感器的前提下,可从算法优化、硬件调整和系统设计等维度着手解决。 一、算法优化 1. 改进 PI…...
【Unity】使用XLua进行热修复
准备工作: (1)将XLua的Tool拖入Asset (2)配置热修复 (3)运行Genrate Code (4)运行Hotfix Inject In Editor 编写脚本(注意类上带有[Hotfix]) [Hot…...
GateWay使用
首先创建一个网关服务,添加对应的依赖 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId&…...