当前位置: 首页 > news >正文

Docker 使用与部署(超详细)

目录

引入

入门使用

部署对比

镜像仓库

命令解释

基础

常见命令

示例

 数据卷的使用

数据卷的概念

数据卷的使用

挂载本地目录文件

镜像

结构

Dockerfile

容器网络

部署

DockerCompose

语法

​编辑

基础命令


引入

当我们在 Linux 上部署一个集成了很多中间件的单体项目的时候,会发现命令太多不易记住,软件安装包的名字复杂,安装和部署步骤复杂,容易出错。在部署微服务项目的时候,由于需要部署的服务器数量众多,并且每一台服务器的运行环境也不一样,写好的安装流程,部署脚本并不一定在每个服务器都能正常运行,经常出错。这就给系统的部署运维带来了诸多困难,那有没有一种技术能够避免部署对服务器环境的依赖,减少复杂的部署流程呢?有的兄弟,有的,这就是即将要介绍的 Docker 技术

Docker 是一种 容器化技术,它可以把应用程序及其所有依赖(库、环境、配置)打包到一个 轻量级、可移植的容器 中,这个容器可以在任何支持 Docker 的环境中快速运行。那 Docker 除了简化部署流程还有那些有点呢?

  1. 解决“在我的电脑上可以跑”的问题:Docker 容器打包了完整的运行环境,确保无论是在开发、测试还是生产环境,运行效果一致
  2. 轻量级:容器比虚拟机(VM)更轻,因为它们共用宿主机的操作系统内核,不需要额外的系统资源
  3. 快速部署与启动:容器启动速度快,适合微服务、自动化部署、持续集成/持续交付(CI/CD)场景。
  4. 易于拓展和管理:配合 Kubernetes 等编排工具,Docker 容器可以方便地进行扩缩容和负载均衡。

  5. 方便版本控制和回滚:Docker 镜像支持版本化,能快速切换或回退到指定版本。

入门使用

部署对比

我们先对比 Docker 部署 MySQL 和传统部署 MySQL 的方式:

传统部署 MySQL 的话需要:

  1. 搜索并下载 MySQL 的安装包
  2. 上传至 Linux 环境
  3. 编译和配置环境
  4. 安装,之后还要进行一些权限设置

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 网站是官方仓库,但是官方仓库在国外,下载速度较慢,一般都会使用阿里云,华为云等等的第三方仓库提供镜像加速功能,提高下载速度。我们也可自己搭建私有的镜像仓库,而企业内部的机密项目,往往就会采用私有镜像仓库,所以镜像来源有:

  1. 基于官方基础镜像自己制作
  2. 直接去 DockerRegistry 下载

总结:Docker 本身包含一个后台服务,我们可以利用 Docker 命令告诉服务,帮我们快速部署指定应用。Docker 服务部署应用的时候,首先去搜索并下载应用对应的镜像,然后根据镜像创建并运行容器,应用就部署完成了

命令解释

我们就先针对上面的那一条部署 MySQL 命令去解释一下:

  1. docker run -d:创建并运行一个容器,-d 则是让容器以后台进程运行
  2. --name mysql:给容器起个名字叫 mysql,这个名字也是可以起别的
  3. -p 3306:3306:设置端口映射。容器是隔离环境,外界不可访问,但是可以将宿主机端口映射到容器内的端口,当访问宿主机指定端口的时候,就是在访问容器内端口了。容器内端口往往是由容器内进程决定的,例如 MySQL 进程默认端口是3306,因此容器内端口一定是3306,而宿主机端口可以任意绑定;格式: -p 宿主机端口:容器内端口,示例端口就是将宿主机的3306映射到容器内的3306端口
  4. -e TZ=Asia/Shanghai:配置容器内进程运行的一些参数,格式:-e KEY = VALUE ,KEY 和 VALUE 都是由容器内进程决定,上面的 TZ = Asia/Shanghai 是设置时区;MYSQL_ROOT_PASSWORD=123 是设置 MYSQL 的默认密码
  5. 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 中有两个关键的目录:

  1. html:放置静态资源
  2. 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",}]
}

可以发现:

  1. Name:数据卷名称。由于定义容器未设置容器名称,这里就是匿名卷自动生成的名字,一串 hash 值。
  2. Source:宿主机目录
  3. 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 项目为例:

传统部署:

  1. 准备 Linux 服务器
  2. 安装配置 JDK 
  3. 上传 jar 包
  4. 运行 jar 包

打包镜像:

  1. 准备 Linux 运行环境
  2. 暗转配置 JDK
  3. 拷贝 jar 包
  4. 配置启动脚本

上诉操作中每一步都是在生产一些文件(系统运行环境,函数库,配置,最后都是磁盘文件),所以镜像就是一堆文件的集合。但是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加的,每一层形成的文件都会单独打包并标记一个唯一 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 规范,模块划分更加合理,核心设计更加简洁。功能增强:突破性地支持统一日志框架&#xff0c…...

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)获取当前数据库中的表 &#xff08…...

【LLM】deepseek R1之GRPO训练笔记(持续更新)

note 相关框架对比: 需微调模型且资源有限 → Unsloth;本地隐私优先的小规模推理 → Ollama;复杂逻辑或多模态任务 → SGLang;高并发生产环境 → vLLM 微调SFT和GRPO是确实能学到新知识的四种格式(messages、sharegpt…...

序列到序列学习

seq2seq 就是把一个句子翻译到另外一个句子。 机器翻译 给定一个源语言的句子,自动翻译成目标语言这两个句子可以有不同的长度 seq2seq 是一个 Encoder - Decoder 的架构 编码器是一个 RNN , 读取输入句子(可以是双向) 解码…...

去打印店怎么打印手机文件,网上打印平台怎么打印

在数字化时代,手机已成为我们存储和传输文件的重要工具。然而,当需要将手机中的文件转化为纸质文档时,许多人会面临选择:是前往线下打印店,还是利用线上打印平台?本文将为您解析这两种方式的优劣&#xff0…...

LeetCode每日一题5.4

1128. 等价多米诺骨牌对的数量 问题 问题分析 等价的定义为:两个骨牌 [a, b] 和 [c, d] 等价,当且仅当 (a c 且 b d) 或者 (a d 且 b c)。 思路 标准化骨牌表示: 为了方便比较,我们可以将每个骨牌 [a, b] 标准化为 [min(a…...

前端小练习————表白墙+猜数字小游戏

1&#xff0c;猜数字游戏 实现一个这个样式的 要猜的目标数字 点击重新开始游戏之后&#xff1a; 代码实现 <!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 个城镇&#xff08;从 1 1 1 到 n n n 标号&#xff09;和 m m m 条双向道路。 每条道路连结两个不同的城镇&#xff0c;没有重复的道路&#xff0c;所有城镇连通。 把城镇看作节点&#xff0c;把道路看作边&…...

Linux网络编程 day3 五一结假

基本概念 三次握手 主动发起连接请求端&#xff0c;发送SYN标志位&#xff0c;请求建立连接。携带数据包包号、数据字节数(0)、滑动窗口大小。 被动接收连接请求端&#xff0c;发送ACK标志位&#xff0c;同时携带SYN请求标志位。携带序号、确认序号、数据包包号、数据字节数…...

解释一下NGINX的反向代理和正向代理的区别?

大家好&#xff0c;我是锋哥。今天分享关于【解释一下NGINX的反向代理和正向代理的区别?】面试题。希望对大家有帮助&#xff1b; 解释一下NGINX的反向代理和正向代理的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 NGINX 作为一个高效的反向代理服务器&a…...

Coco AI 入驻 GitCode:打破数据孤岛,解锁智能协作新可能

在信息爆炸时代&#xff0c;企业正面临前所未有的挑战&#xff1a; 企业数据和信息分散&#xff0c;数据孤岛现象严重&#xff0c;员工往往浪费大量时间跨平台检索&#xff1b;跨部门协作困难&#xff0c;团队因信息隔阂导致项目延期&#xff1b;数据安全问题严峻&#xff0c;…...

【QT】QT中的网络编程(TCP 和 UDP通信)

QT中的网络编程&#xff08;TCP 和 UDP通信&#xff09; 1.tcp1.1 tcp通信1.1.1 相比linux中tcp通信:1.1.2 QT中的tcp通信: 1.2 tcp通信流程1.2.1 服务器流程&#xff1a;1.2.1.1 示例代码1.2.1.2 现象 1.2.2 客户端流程&#xff1a;1.2.2.1 示例代码1.2.2.2 现象&#xff1a; …...

个性化推荐:大数据引领电子商务精准营销新时代

个性化推荐:大数据引领电子商务精准营销新时代 引言 在电子商务的时代,个性化推荐系统已经成为提升用户体验、增强平台竞争力的重要技术。随着大数据技术的迅猛发展,传统的推荐方法已经无法满足用户日益增长的需求。为了精准地把握用户兴趣和消费倾向,商家们依赖大数据分析…...

【前端】【总复习】HTML

一、HTML&#xff08;结构&#xff09; HTML 是网页的骨架&#xff0c;主要负责网页的结构与语义表达&#xff0c;为 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)&#xff0c;那么 JMM 向你保证&#x…...

Python实例题:Python获取NBA数据

目录 Python实例题 题目 方式一&#xff1a;使用网页爬虫获取数据 代码解释 get_nba_schedule 函数&#xff1a; 主程序&#xff1a; 方式二&#xff1a;使用专业 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 任务窃取&#xff08;Work Stealing&#xff09;3.4 同步与唤醒 4 性能优化5 典型应用场景6 代码…...

React-router v7 第七章(导航)

导航 在React-router V7中&#xff0c;大致有四种导航方式&#xff1a; 使用Link组件 link使用NavLink组件 navlink使用编程式导航useNavigate usenavigate使用redirect重定向 redirect Link Link组件是一个用于导航到其他页面的组件&#xff0c;他会被渲染成一个<a>…...

Terraform 中的 external 数据块是什么?如何使用?

在 Terraform 中&#xff0c;external 数据块&#xff08;Data Block&#xff09; 是一种特殊的数据源&#xff0c;允许你通过调用外部程序或脚本获取动态数据&#xff0c;并将结果集成到 Terraform 配置中。它适用于需要从 Terraform 外部的系统或工具获取信息的场景。 一、e…...

打印Excel表格时单元格文字内容被下一行遮盖的解决方法

本文介绍在打印Excel表格文件时&#xff0c;单元格最后一行的文字内容被下一行单元格遮挡的解决方法。 最近&#xff0c;需要打印一个Excel表格文件。其中&#xff0c;已知对于表格中的单元格&#xff0c;都设置了自动换行&#xff0c;如下图所示。 并且&#xff0c;也都设置了…...

【Linux】命令行参数与环境变量

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、命令行参数 1. 什么是命令行参数 2. 命令行参数的作用 二、环境变量 1. 基本概念 2. 常见的环境变量 3. 环境变量相关操作 定义…...

Dify 完全指南(一):从零搭建开源大模型应用平台(Ollama/VLLM本地模型接入实战)》

文章目录 1. 相关资源2. 核心特性3. 安装与使用&#xff08;Docker Compose 部署&#xff09;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

民法学学习笔记&#xff08;个人向&#xff09; Part.3 8. 诉讼时效&#x1f338; 概念&#xff1a; 是指权利主体在法定期间内不行使权利&#xff0c;则债务人享有抗辩权&#xff0c;可以导致权利人无法胜诉的法律制度&#xff08;有权你不用&#xff0c;别人就有话说了&#…...

C# 方法(返回值、返回语句和void方法)

本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 返回值 方法可以向调用代码返…...

打电话玩手机检测数据集VOC+YOLO格式8061张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;8061 标注数量(xml文件个数)&#xff1a;8061 标注数量(txt文件个数)&#xff1a;8061 …...

详解如何压测RocketMQ

目录 1.如何设计压测 2.压测工具 3.硬件配置 4.写代码压测 5.自带压测脚本 1.如何设计压测 二八定律法则&#xff1a;按业务峰值的 120% 设计压测目标&#xff08;若线上峰值1000TPS&#xff0c;压测目标至少1200TPS&#xff09; 关注三个指标 吞吐量&#xff08;TPS&…...

实验三 触发器及基本时序电路

1.触发器的分类&#xff1f;各自的特点是什么&#xff1f; 1 、 D 触发器 特点&#xff1a;只有一个数据输入端 D &#xff0c;在时钟脉冲的触发沿&#xff0c;输出 Q 的状态跟随输入端 D 的 状态变化&#xff0c;即 &#xff0c;功能直观&#xff0c;利于理解和感受…...

双列集合——map集合和三种遍历方式

双列集合的特点 键和值一一对应&#xff0c;每个键只能对应自己的值 一个键和值整体称为键值对或键值对对象&#xff0c;java中叫做entry对象。 map常见的api map接口中定义了双列集合所有的共性方法&#xff0c;下面三个实现类就没有什么额外新的方法要学习了。 map接口…...

WebRTC 服务器之Janus视频会议插件信令交互

1.基础知识回顾 WebRTC 服务器之Janus概述和环境搭建-CSDN博客 WebRTC 服务器之Janus架构分析-CSDN博客 2.插件使用流程 我们要使⽤janus的功能时&#xff0c;通常要执⾏以下操作&#xff1a; 1. 在你的⽹⻚引入 Janus.js 库&#xff0c;即是包含janus.js&#xff1b; <…...

LabVIEW温控系统热敏电阻滞后问题

在 LabVIEW 构建的温控系统中&#xff0c;热敏电阻因热时间常数大&#xff08;2 秒左右&#xff09;产生的滞后效应&#xff0c;致使控温出现超调与波动。在不更换传感器的前提下&#xff0c;可从算法优化、硬件调整和系统设计等维度着手解决。 ​ 一、算法优化​ 1. 改进 PI…...

【Unity】使用XLua进行热修复

准备工作&#xff1a; &#xff08;1&#xff09;将XLua的Tool拖入Asset &#xff08;2&#xff09;配置热修复 &#xff08;3&#xff09;运行Genrate Code &#xff08;4&#xff09;运行Hotfix Inject In Editor 编写脚本&#xff08;注意类上带有[Hotfix]&#xff09; [Hot…...

GateWay使用

首先创建一个网关服务&#xff0c;添加对应的依赖 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId&…...