docker容器通俗理解

前言

如果大家没使用过Docker,就在电脑上下载一个VMware Workstation Pro,创建一个虚拟机安装一个windows操作一下感受一下,为什么我的电脑上还以再安装一台windows主机?其实你可以理解为Docker就是Linux系统的一个虚拟机软件。

我的Windows也可以安装Docker啊?打开Docker官网https://www.docker.com/get-started/点击"Download for Window"下载一个安装查看一下。Docker在Windows上可以运行是因为Windows统提供了一种叫做 Docker Desktop for Windows的工具,它通过在Windows上创建一个Linux虚拟机来实现。Docker Desktop for Windows使用了一种叫做Hyper-V的虚拟化技术,Windows上创建了一个轻量级的Linux虚拟机,该虚拟机运行一个精简的Linux内核称为Docker宿主机。

VMware和docker

VMware和docker同样是虚拟机,但他们却有一些不同:普通虚拟化(完全型解耦)和Docker(半解耦)

耦合:耦合指的是软件组件之间的依赖关系和关联程度。
解耦:指的是减少软件组件之间的依赖关系,降低耦合度,提高代码的灵活性、可维护性和可重用性。
简单理解,就是软件之间的依赖关系紧密不紧密。
  • 普通虚拟化(完全型解耦):每个虚拟机都拥有自己的完整操作系统和内核。这意味着虚拟机之间是完全解耦的,它们可以运行不同版本的操作系统,甚至不同类型的操作系统(例如 Linux、Windows),并且彼此之间没有任何冲突。每个虚拟机都相当于一个独立的物理服务器,可以独立地进行管理和维护。
  • 和Docker(半解耦):在Docker中使用了一种更轻量级的容器化技术所有的容器共享宿主主机的操作系统和内核,它们之间是半解耦的。尽管容器之间共享了操作系统的核心部分,但它们仍然是相互隔离的,每个容器拥有自己的文件系统、进程空间、网络空间等。因此,容器可以运行在不同的操作系统发行版中,但它们仍然受到宿主主机操作系统的限制,并且可能会受到容器之间的冲突影响。

所以你在VMware的linux虚拟机中可以升级linux的系统内核,但是不能在Docker的容器中升级容器的系统内核。如果你的软件服务对内核版本有严格要求,这个服务就不太适合用docker来实现。

还有服务不能用Docker实现?

还有服务不能用Docker实现?一个完整的服务有可能是由多个服务在一起运行实现。开发人员开发了服务A对内核有要求需要服务器内核版本A,而开发的另一个服务B对内核也有要求需要服务器内核版本B,那么Docker就不能再同一台服务来运行A和B两个服务。这就和Docker的这种半解耦的状态有关系了。

Docker的虚拟化

Docker有个核心的组件是Containerd。在讲容器的时候大部分人会认为是容器就是Docker,我更愿意把Docker和容器分开理解,我感觉Docker和Kubernetes只是容器的管理工具而真正的容器是底层的Containerd。Docker没有Containerd组件就创建不了容器,Containerd没了Docker依然可以独立的创建容器提供服务。

docker要管理容器的生命周期

找台docker主机执行命令:docker version

[root@localhost ~]# docker version 
Client: Docker Engine - Community
 Version:           26.0.0
 API version:       1.45
 Go version:        go1.21.8
 Git commit:        2ae903e
 Built:             Wed Mar 20 15:21:09 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          26.0.0
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.8
  Git commit:       8b79278
  Built:            Wed Mar 20 15:20:06 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

我们看到docker有两个重要的组件docker引擎Client、Server:

  • Client:是与用户交互的主要方式,它提供了一个命令行界面(CLI)和API,使得用户可以使用Docker来构建、运行和管理容器化的应用程序。用户可以通过Docker CLI命令(例如 docker run、docker build)通过 Docker API来向Server发送请求。
  • Server:是一个后台运行的进程,负责管理Docker上的容器、镜像、网络和存储等资源。它是Docker引擎的核心组件之一,负责接收来自 Docker客户端的请求,并根据这些请求来创建、启动、停止、删除容器,以及构建、拉取、推送镜像等操作。它还通过与containerd进行通信来管理容器的生命周期。
    在这里插入图片描述

docker:的基本架构

  1、 doker分为用户端和服务器端:我们刚刚已经查看过了。 Server为客户端提供UESTfulAPI,响应来自客户端的请求采用模块化的架构,通过专门的Engine模块来分发管理各个来自客户端的任务。
  2、docker-proxy:是dockerd的子进程,当需要进行容器映射的时候docker-proxy完成网络映射配置。
  3、containerd:是dockerd的子进程提供GRPC接口来响应来自dockerd的请求,对下管理runC镜像和容器环境。
  4、containerd-shim:是dockerd的子进进程为Runc容器提供支持同事作为容器的根进程。

docker的隔离策略

docker是半耦合的虚拟化,那么它是如何实现隔离的呢?Docker的隔离主要是通过Linux内核提供的一系列的特性来实现的.
进入linux系统在进入任意进程查看一下:cd /proc/2538/ns | ll

[root@localhost ns]# pwd 
/proc/2538/ns
[root@localhost ns]# ll
总用量 0
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 ipc -> ipc:[4026532679]
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 mnt -> mnt:[4026532677]
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 net -> net:[4026532682]
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 pid -> pid:[4026532680]
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 user -> user:[4026531837]
lrwxrwxrwx. 1 bwk root 0 4月  27 15:26 uts -> uts:[4026532678]

基于此Docker有六项隔离实现了容器与宿主机、容器与容器之间的隔离:

IPC: 信号量、消息队列和共享内存
MNT: 挂载点、文件系统
NET: 网络设备、网络栈、端口等等
PID: 进程编号
USER: 用户、组
UTS: 主机名、域名

主要包括以下几个方面:

  • 命名空间(Namespace): Docker使用Linux内核的命名空间机制来隔离容器的进程视图、网络、文件系统、用户、主机名等资源。每个容器都有自己独立的命名空间,使得容器内的进程无法感知到其他容器或宿主机上的进程,从而实现了进程级别的隔离。
  • 控制组(Cgroup): Docker使用Linux内核的控制组机制来限制容器对 CPU、内存、磁盘、网络等资源的使用。通过将容器的资源限制和监控与控制组关联起来,Docker 可以有效地管理和调度容器的资源使用,防止容器占用过多的系统资源,从而确保系统的稳定性和可靠性。
  • 容器文件系统(Union File System): Docker使用联合文件系统(Union File System)来实现容器的文件系统隔离。联合文件系统允许容器在一个只读的基础文件系统上叠加多个可写的文件系统层,使得容器内的文件系统与宿主机和其他容器的文件系统相互隔离,同时可以实现文件系统的共享和复用。
  • 网络隔离: Docker使用Linux内核的网络命名空间来实现容器之间的网络隔离。每个容器都有自己独立的网络命名空间,使得容器可以拥有自己独立的网络接口、IP 地址和路由表,从而实现了网络层面的隔离。

1、命名空间(Namespace)
我的docker运行了一个Elasticsearch集群:
命名空间有六项隔离,我们查看一下:es01有映射端口是9200

[root@localhost docker]# ps -ef | grep 9200
root       3744   1501  0 16:32 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9200 -container-ip 172.18.0.4 -container-port 9200
root       3750   1501  0 16:32 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 9200 -container-ip 172.18.0.4 -container-port 9200
root       4098   1418  0 16:43 pts/0    00:00:00 grep --color=auto 9200
[root@localhost docker]# ps -ef | grep 1501
root       1501      1  0 11:36 ?        00:00:29 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root       3744   1501  0 16:32 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9200 -container-ip 172.18.0.4 -container-port 9200
root       3750   1501  0 16:32 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 9200 -container-ip 172.18.0.4 -container-port 9200
root       4100   1418  0 16:44 pts/0    00:00:00 grep --color=auto 1501

一个映射ipv4一个映射ipv6进程是3744和3750,我们看到两个9200的进程有同一个父进程1501并且这个正是docker的主进程。
那么在容器内部是怎么样的呢?

[root@localhost ns]# docker exec -it es01 /bin/bash
root@e67d6d5de8b2:/usr/share/elasticsearch# ps aux 
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0   2484   312 ?        Ss   16:32   0:00 /bin/tini -- /usr/local/bin/docker-entrypoint.sh eswrapper
elastic+      7  4.8 26.9 4272660 1040204 ?     SLl  16:32   1:23 /usr/share/elasticsearch/jdk/bin/java -Xshare:auto -Des.networkaddress.cache.ttl=60 -Des.networkaddres
elastic+    209  0.0  0.1 108392  4600 ?        Sl   16:32   0:00 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
root        253  3.7  0.0   4100  2164 pts/0    Ss   17:01   0:00 /bin/bash
root        263  0.0  0.0   5884  1476 pts/0    R+   17:01   0:00 ps aux

在容器内部完全是独立的系统进程,宿主机看到的是3744和3750,3744和3750在/proc/3744/ns中六项均都指向的是同一样的命名空间标识符其实是一个服务。

2、控制组(Cgroup)
Cgroup(Control Group)是属于linux的内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用。

它的作用:

1)资源限制,可以将组设置一定的内存限制。
2)优先级,通过优先级让一些组优先获得更多资源。
3)资源审计,用来统计系统实际上把多少资源用到适合的目的上。
4)隔离,为组隔离命名空间,这样使得一个组不会看到另一个组的进程、网络链接和文件系统。
4)控制,执行挂起、恢复、和重启等操作。
devices:设备权限控制。
cpuset:分配指定的cpu和内存
cpu:控制cpu占用率。
cpuacct:统计cpu使用情况 
memory:限制内存使用情况。
freezer:冻结(暂停)Cgroup中的进程  
net_prio: 设置进程的网络流量优先级。
huge_tlb:限制HugeTLB的使用。
perf_event:允许perfect工具基于Cgroup分组做性能监测。

Cgroup是一个虚拟的文件系统,在Linux发行版中系统启动时已经完成挂载。

[root@python ~]# mount | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)

在/sys/fs/cgroup/下相应的属性文件下都有一个docker的目录里面存放生成的容器隔离文件。太多自己可以查看一下。

[root@localhost cgroup]# pwd
/sys/fs/cgroup
[root@localhost cgroup]# ls
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd

Cgroup子系统介绍简单理解:

 1、cpuset子系统
      cpuset.cpus 允许进程使用的CPU列表(例如0~4,9)
      cpuset.mems 允许进程使用的内存列表 (例如:0~1)
 2、cpu子系统
      用于限制进程cpu占用率,有三个功能分别通过不同的接口来实现。
       1)cpu比重分配:接口cpu.shares。假设在cgroupfs的根目录下创建(C1、C2)并且cpu.shares分别配置512和1024.那么在C1和C2使用cpu时候c2将比c1使用多一倍的cpu使用率,只有当他们争用cpu的时候才起效。
       2)cpu带宽限制:接口cpu.cfs_quota_us。接口单位是微秒。可以将period设置为1秒将quota设置为0.5秒。那么Cgroup中的进程在1秒内最多只能运行0.5秒然后被强制睡眠直到进入到下一个1秒。实时进程的带宽限制:接口cpu.rt_peri-od_us和cpu.rt_runtime_us。
  3、cpuacct子系统
       用来统计cpu的使用情况。
  4、memory子系统
       memory子系统用来限制Cgroup所能使用的内存上限 接口memory.limit_in_bytes。单位k/K、m/M或者g/G表示
         echo 1G > memory.limit_in_bytes
       memory.memsw.lim-it_in_bytes 设定内存加交换分区的使用总量。防止进程用尽交换分区。
       memory.oom_control: 如果设置为0,那么在内存使用量超过上限时不会杀死进程,而是阻塞进程直到内存释放可供使用。另一方面系统会向用户发送通知用户的监控程序可以根据该事件来做相应处理。
       memory.stat: 汇报内存使用信息。
  5、blkio 子系统
       用来限制Cgroup的block I/O带宽。(就是磁盘IO)
       .blkio.weight: 设置权重值,范围100~1000。和cpu.shares类似,是比重分配,不是绝对资源限制,只有在Cgroup在争用同一块设备时候才起作用。
       .blkio.weight_device对具体的设备设置权重值,这个值会覆盖blkio.weight。
   6、devices子系统
       用来控制Cgroup的进程对那些设备具有访问权限。
       .devices.list 只读文件显示目前允许访问的设备列表。每个条目分3个域。 
          1)类型:可以是a、c或b,分别表示所有设备、字符设备、块设备。
          2)设备号 
          3)权限r、w或m的组合分别表示可读、可写、可创建设备节点。
       .devices.allow 只写文件,以上描述的格式写入文件,就可以允许相应的设备访问权限。
       .devices.deny 只写文件,以上描述的格式写入该文件,就可以禁止相应的设备访问权限。

我们用memroy看一下:

[root@localhost /]# docker ps -a 
CONTAINER ID   IMAGE                                                   COMMAND                   CREATED       STATUS       PORTS                                                 NAMES
e67d6d5de8b2   docker.elastic.co/elasticsearch/elasticsearch:7.17.14   "/bin/tini -- /usr/l…"   3 weeks ago   Up 5 hours   0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 9300/tcp   es01
55d5e73f9a94   docker.elastic.co/elasticsearch/elasticsearch:7.17.14   "/bin/tini -- /usr/l…"   3 weeks ago   Up 5 hours   9200/tcp, 9300/tcp                                    es02
53f7c8128cc1   docker.elastic.co/elasticsearch/elasticsearch:7.17.14   "/bin/tini -- /usr/l…"   3 weeks ago   Up 5 hours   9200/tcp, 9300/tcp                                    es03

看一下es01的内存配置这个内存我是没做任何限制,表示容器可以使用宿主机上的全部可用内存:

[root@localhost /]# docker inspect es01 --format='{{.HostConfig.Memory}}'
0

查看一下容器ID:

[root@localhost ~]# docker inspect es01
[
    {
        "Id": "e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba",
        "Created": "2024-04-04T13:56:18.043205656Z",

在/sys/fs/cgroup/memory/docker目录下:

[root@localhost docker]# ll
总用量 0
drwxr-xr-x. 2 root root 0 4月  27 11:36 53f7c8128cc1a1117e4ec0b521d8fcc4c6ca4df490f5ac44c8463b5cf19920ac
drwxr-xr-x. 2 root root 0 4月  27 11:36 55d5e73f9a94677e00fa5a4a77e492a312fe1ab7101f27000b7c2b6f59c2956c
-rw-r--r--. 1 root root 0 4月  27 11:36 cgroup.clone_children
--w--w--w-. 1 root root 0 4月  27 11:36 cgroup.event_control
-rw-r--r--. 1 root root 0 4月  27 11:36 cgroup.procs
drwxr-xr-x. 2 root root 0 4月  27 11:36 e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba

进入到虚拟目录:

[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# cat memory.limit_in_bytes 
9223372036854771712
[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# echo 1G > memory.limit_in_bytes
[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# cat memory.limit_in_bytes 
1073741824

实际上我们对内存做了1G的限制。重启容器:

[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# docker restart es01
es01
[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# ls
[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# cd ..
[root@localhost docker]# cd e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba/
[root@localhost e67d6d5de8b273e69fbc806d303f1bea169941779ade044be2081f488f5db5ba]# cat memory.limit_in_bytes 
9223372036854771712

因为他是虚拟文件,重启后目录下文件消失,恢复docker默认设置。

哪些是耦合的

  • 共享内核:Docker 容器与宿主机共享同一个内核,因此容器内部的进程直接运行在宿主机的内核之上。这种共享内核的特性导致容器与宿主机之间有一定的耦合性,容器的行为受限于宿主机的内核版本和配置。
  • 资源:虽然 Docker 容器提供了一定程度的资源隔离,如 CPU、内存和网络等,但是由于容器与宿主机共享同一个内核,因此容器之间的资源隔离并不是完全隔离的。例如,在容器内部可以通过一些技巧访问到宿主机的资源,将宿主机上的某些目录挂载到容器内部,以便与宿主机共享文件或配置。
  • 网络:Docker 容器提供了一定程度的网络隔离,每个容器都有自己独立的网络栈和网络命名空间。但是由于容器共享宿主机的网络设备,因此容器之间仍然可以相互通信,容器的网络行为也受限于宿主机的网络配置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WMS仓库库存管理软件如何优化工厂的仓库管理-亿发

如果一家工厂没有专业的WMS仓储软件支撑,管理原材料、辅料、半成品和产成品等环节可能会面临诸多问题。 在仓库管理方面,缺乏安全库存的管理会导致库存不足或过剩,而没有及时的缺货分析可能会导致生产中断。全凭人工核算剩余库存和订单质检的…

金价大跳水,美梦变噩梦!2024真正适合普通人的靠谱创业项目!2024适合30-40岁轻资产小生意

4月22日晚间,向上“狂飙”了一个多月的金价突然就“大跳水”。当日,每克金价均下调14块。在这次跳水中,有人欢喜有人愁:有投资者自报做空金价一夜狂赚14万,也有投资者哭诉,头晚进货到早上就净亏损2万&#…

Android 11 bindService 流程分析

我们可以使用bindService来跨进程通信,其使用方法如下 Intent intent new Intent("xxx"); intent.setPackage("xxx"); boolean result bindService(intent,new ServiceConn(),BIND_AUTO_CREATE);private class ServiceConn implements Servi…

STM32入门_江协科技_1~2_OB记录的自学笔记_STM32简介

1.综述 1.1. 课程简介 手打代码是加入了实操,增加学习效果; STM最小系统板面包板的硬件平台; 配套0.96寸的显示屏,便于调试; 因为使用面板板,所以如果程序现象不出来也有可能是硬件连接的问题; …

Allegro画PCB时如何只删除走线的一部分

如何只删除走线的一部分 1、第一步: 2、第二步: 3、第三步,点击相应的走线段就能删除了。 说明:上面的Cline和Line只的是电线和线,您按下删除后,就可以删除这两种东西,但删除的是一整条折线.把这两个取消掉,换成Cline Segs和Ot…

【代码随想录刷题记录】LeetCode283移动零

题目地址 1. 思路 1.1 基本思路及假设 拿到这个题,首先想到,这是类似删除元素的方法,因为删除元素也是移动元素,但是移动的方向和删除元素的方法刚好相反,我们都知道,如果在数组中删除某个元素&#xff…

【Docker】docker部署lnmp和wordpress网站

环境准备 docker:192.168.67.30 虚拟机:4核4G systemctl stop firewalld systemctl disable firewalld setenforce 0 安装docker #安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像 yum-config-manager --add…

vue2主体页面进行拆分

目录 一.组件化 二.新建Header.vue页面 三.Aside.vue代码 四.Main.vue代码如下 五.Home.vue代码如下 六.index.js代码如下: 七.项目效果图 在Vue.js 2中,将主体页面进行拆分是一种常见的做法,它有助于提高代码的可维护性和可读性。页面…

js实现简单的级联下拉列表

代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script src"js/jquery.min.js" type"text/javascript" charset"utf-8"></script><st…

Linux的磁盘分区,格式化,挂载

1.需要提前添加几个磁盘&#xff0c;以做实验 2.把nvme0n2磁盘用来分区实验 3.分了一个主分区&#xff0c;和一个扩展分区&#xff08;扩展分区是不能使用的&#xff0c;所以又在扩展分区里分了一个逻辑分区&#xff09;分区的大小自己定义 4.格式化分出来的区&#xff0c;这…

618不可错过的数码好物精选!等等党必看清单汇总

无论是追求高效工作的职场人士&#xff0c;还是热爱科技、追求品质生活的消费者&#xff0c;都希望能找到那些既实用又富有创新精神的数码好物&#xff0c;现在正值618购物狂欢节来临之际&#xff0c;我精心为大家挑选了一份不可错过的数码好物清单&#xff0c;这份清单不仅汇聚…

App一键直达,Xinstall助力提升用户体验

在这个移动互联网时代&#xff0c;App已经成为了我们日常生活中不可或缺的一部分。然而&#xff0c;每当我们在浏览器或社交平台上看到一个有趣的App推荐&#xff0c;点击下载后却往往要经历一系列繁琐的跳转和确认过程&#xff0c;这无疑大大降低了用户体验。那么&#xff0c;…

数据结构 - C/C++

快速跳转 数组链表栈队列串树 目录 数据结构 逻辑结构 物理结构 数据结构 数据 数据不仅仅包括整型、实型等数值类型&#xff0c;还包括字符及声音、图像、视频等非数值类型。 计算机可以理解并按照指定格式处理。 结构 元素相互之间存在一种或多种特定关系的数据集合。 …

Git 常用命令大全

&#x1f680; Git安装与基础知识学习 &#x1f310; &#x1f3af; Git作为一款全球开发者广泛使用的分布式版本控制系统&#xff0c;能够有效帮助团队协作并追踪项目历史版本。接下来&#xff0c;我们将详细展开Git的安装流程、基础命令操作、高级用法以及应对常见问题的方法…

西湖大学赵世钰老师【强化学习的数学原理】学习笔记1节

强化学习的数学原理是由西湖大学赵世钰老师带来的关于RL理论方面的详细课程&#xff0c;本课程深入浅出地介绍了RL的基础原理&#xff0c;前置技能只需要基础的编程能力、概率论以及一部分的高等数学&#xff0c;你听完之后会在大脑里面清晰的勾勒出RL公式推导链条中的每一个部…

信息系统集成对企业的影响到底有多大?

什么是信息系统集成 系统集成&#xff08;System Integration&#xff09;是指将若干个独立运作的系统或服务联通并整合的过程&#xff0c;旨在将那些存在交集或重复功能的分散模块融合为一个协同工作的整体&#xff0c;以实现效能的最大化和资源的最优配置&#xff0c;避免不…

找不到mfc140u.dll文件如何处理?这三种方法帮你快速修复mfc140u.dll

当你的电脑出现提示&#xff0c;显示找不到mfc140u.dll文件&#xff0c;从而无法继续执行代码&#xff0c;你需要知道如何应对这种情况。今天我们就来详细说明如何解决mfc140u.dll文件丢失的问题&#xff0c;并对该文件进行详细分析。这个文件是Microsoft Visual Studio的一个重…

AI文章写作网站

最强AI文章写作网站——心语流光&#xff08; Super Ai Writer &#xff09; 特点 多轮问答写作&#xff0c;自动携带历史记录进行问答可以自定义携带历史记录的轮数&#xff0c;为0则携带全部历史记录&#xff0c;有效避免token浪费&#xff08;类似coze平台&#xff09;AI生…

【Java网络编程】TCP通信(Socket 与 ServerSocket)和UDP通信的三种数据传输方式

目录 1、TCP通信 1.1、Socket 和 ServerSocket 1.3、TCP通信示例 2、UDP的三种通信&#xff08;数据传输&#xff09;方式 1、TCP通信 TCP通信协议是一种可靠的网络协议&#xff0c;它在通信的两端各建立一个Socket对象 通信之前要保证连接已经建立&#xff08;注意TCP是一…

【06】JAVASE-数组讲解【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture&#xff1a;波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。…
最新文章