Docker容器理解
目录
目录
一:简单理解操作系统
操作系统:
内核:
内核空间和用户空间:
二:简单理解文件系统
1:什么是文件系统
2:什么是root文件系统
三:docker
1:docker镜像
2:docker镜像的分层存储
3:容器
a:容器 = 镜像 + 可读可写层
b: 运行态容器 + 一些docker的基本操作
4:通过docker commit命令来理解镜像的构成
5:利用dockfile定制镜像
一:简单理解操作系统
操作系统:
分为内核和用户空间;内核,即操作系统用于和计算机硬件通信的部分;用户空间,即用户程序运行的部分。我们知道人是无法直接和计算机进行交互的,操作系统的作用就是上通下达,它一方面接收人类给到计算机的指令,另一方面,他将这些指令转化为计算机零件可以看懂的东西(可以理解为,操作系统就是把指令转化为特定的电流,给到特定的硬件),以此实现人类和计算机得交互。我们把操作系统和计算机硬件之间得通信部分看作是内核,把操作系统和用户之间的交互看作是用户空间(用词可能不太准确,但大概意思是这样)。
内核:
参考自:(19条消息) 操作系统的内核到底是什么?_操作系统内核是什么_deepin_mq的博客-CSDN博客
内核涉及到的操作:进程调度、内存管理、文件系统、网络接口、进程通信等等这些;本质上内核是对计算机硬件的抽象。
这样说是因为这里涉及到一个更根本的问题:人机交互。如何让计算机理解人的想法,需求,并将之实现。
比如:让计算机计算一下硬盘中的一个文档的字数。我们是没有办法去打开“硬盘”翻箱倒柜找到这个文件,然后丢给“CPU”去统计,并从“CPU”那里得到这个结果。对于计算机内部真正的核心组成部分:CPU、硬盘、内存等等这些硬件,人是无法直接去面对和交互的。而计算机处理的所有工作,都是通过调用这些硬件设备来完成的。
对操作系统来说,最重要的正是管理和调度计算机内部的资源。而具体到操作系统的内部分工,则是由内核来真正完成和执行的。除了内核以外,操作系统其他所有的部件,都不需要也不关注如何计算、如何存储、如何和具体的某个硬件设备打交道。所有的部件都只需要将具体的诉求传递给内核,调用内核的接口,即可完成硬件资源的调度和使用。
内核抽象了计算机内部硬件资源,并统一管理对外提供支持,所以内核 = 计算机硬件。
内核空间和用户空间:
参考自:用户空间和内核空间到底是什么? - 知乎 (zhihu.com)
我们知道计算机所有运行的程序以及数据其实都是放在内存中的,也只有把程序和数据放进内存 ,计算机才能进行相应的操作或者计算。那么我们以4g的内存举例,其中有1g的内存容量是专门给内核相关代码数据用的,比如就是地址从0~1g的内存空间,这部分内存块,我们称之为内核空间;而对于1~3g的内存部分,则是提供给用户的代码和数据的,我们把这部分内存块看作用户空间;
图片来自参考。
二:简单理解文件系统
1:什么是文件系统
文件系统是一种数据结构,用于管理计算机中的文件和目录。在计算机中,文件系统通常是操作系统的一部分,它负责解释和执行文件系统中的文件和目录,并提供对文件和目录的访问。文件系统也可以是一个独立的软件模块,它运行在操作系统之上,提供对文件和目录的访问和管理。
常见的文件系统类型包括 FAT、FAT32、NTFS、ext2、ext3、ext4 等。
再简单一点,文件系统不是文件,是用来管理文件的的一种数据结构,它本身也是可以保存数据之类的,比如下面说到的root文件系统,它就存储了系统的根目录和根文件系统中的数据和文件。
典型的Linux文件系统由bootfs
文件系统和rootfs
文件系统组成,bootfs
会在Kernel
加载到内存后umount
掉,所以我们进入系统看到的都是rootfs。
BootFS 和 rootFS 是 Linux 内核中用于存储和管理根文件系统中的数据和文件的模块。
BootFS 是一个特殊的文件系统,它在 Linux 内核启动时自动挂载到内存中,并用于存储内核启动时需要使用的数据,例如内核镜像、内核配置信息和内核日志等。BootFS 通常使用 LUKS 加密,并且可以在内核启动时进行调整。
rootFS 是 Linux 内核中用于存储根文件系统中的数据和文件的模块。它是一个只读的文件系统,通常使用 EXT4 文件系统格式。rootFS 通常位于硬盘的最后一个扇区,并且是系统启动时第一个被加载的文件系统。在这个文件中,可以找到系统引导程序 (如 Grub) 以及用于管理系统文件的 Shell 和命令。
bootfs 和 rootfs 是 Linux 内核中用于存储和管理重要数据的文件系统,它们的作用非常重要,对于系统的稳定性和安全性都有着至关重要的作用。
2:什么是root文件系统
root文件系统,不等同于上述的rootfs文件系统,它是linux系统下,用来管理“/”文件夹的文件系统;"/"文件夹,也就是根目录,这个目录下包括/home,/bin,/usr,/etc等文件。因为root文件系统是用来管路根目录的,也就是说root文件系统可以管理/下面所有文件,对所有文件有操作,访问的权限,所以:root 文件系统是操作系统中唯一的超级用户权限所有者所在的文件系统,因此只有 root 用户可以访问和修改它。为了保护系统的安全性,root 文件系统通常需要进行加密和分区,以便只有 root 用户可以访问和修改它。
root 文件系统通常用于存储系统启动文件,如 boot 目录、/etc 目录、/var 目录等,以及所有系统启动时需要访问的文件。
对于 Linux 而言,内核启动(就是BootFS 文件系统)后,会挂载 root
文件系统为其提供用户空间支持,这里就是上面说的,会用到bootfs。
root 文件系统是指 Linux 系统中的一个特殊文件系统,通常用于存储系统的根目录和根文件系统中的数据和文件。在 Linux 系统中,root 文件系统通常是只读的,并且只有系统管理员才能进行修改。
root 文件系统通常使用 EXT4 文件系统格式,并且在 Linux 内核中,有一个特殊的模块叫做"rootfs"或"root partition",用于加载和初始化 root 文件系统。在系统启动时,内核会首先加载 rootfs 模块,然后通过模块中的代码来加载 root 文件系统,并将其挂载到根目录下。
root 文件系统是 Linux 系统的核心,它包含了系统的启动代码、系统配置文件、系统运行所需的命令和文件等。因此,一旦 root 文件系统被损坏或破坏,可能会导致整个系统无法运行。因此,在维护 Linux 系统时,通常需要小心谨慎地操作 root 文件系统。
root 文件系统和 rootfs 文件系统是不同的,尽管它们在某些方面有相似之处。
root 文件系统是 Linux 系统中的一个重要文件系统,通常用于存储系统的根目录和根文件系统中的数据和文件。root 文件系统通常是只读的,并且只有系统管理员才能进行修改。在 Linux 系统中,root 文件系统通常使用 EXT4 文件系统格式。
而 rootfs 文件系统是在 Linux 内核中用于加载和初始化根文件系统的模块,通常也称为根文件系统模块。rootfs 文件系统模块使用特殊的命令和代码来加载和初始化 root 文件系统,并将其挂载到根目录下。与 root 文件系统不同,rootfs 文件系统通常是可写的,并且系统管理员可以使用该文件系统来更新和修改根文件系统。
因此,尽管 root 文件系统和 rootfs 文件系统都是用于存储根目录和根文件系统中的数据和文件,但它们的具体实现和功能是不同的。
三:docker
参考自:镜像 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
1:docker镜像
docker镜像就相当于一个root文件系统。比如官方镜像 ubuntu:18.04
就包含了完整的一套 Ubuntu 18.04 最小系统的 root
文件系统。
题外话:这也是为什么说docker容器比虚拟机轻量的原因,因为docker只是一个root文件系统,也就是相当于只虚拟了用户空间;而虚拟机时要虚拟整个操作系统,它不仅要虚拟用户空间,还要虚拟内核。每一个虚拟机都是这样,所以很笨重。
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
注意:docker镜像相当于root文件系统,但它不是root文件系统,也不是rootfs文件系统,它就是一组只读的文件系统。
在 Docker 镜像中,数据和配置通常存储在 Docker 镜像的卷中,而不是在 rootfs 文件系统中。Docker 镜像的卷是一个或多个只读的文件系统,它们可以被映射到容器的目录中,从而为容器提供所需的数据和配置。因此,Docker 镜像并不直接等同于 rootfs 文件系统,但它们可以一起用于构建和部署容器化应用程序。
2:docker镜像的分层存储
因为镜像包含操作系统完整的
root
文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
docker镜像时一组文件系统,这组文件系统有层次划分。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
因此,我们可以把镜像简单理解为一组只读的文件系统:
参考:(19条消息) docker容器和镜像的区别_docker镜像和容器的区别_清风不灭的博客-CSDN博客
3:容器
参考:容器 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
(19条消息) docker容器和镜像的区别_docker镜像和容器的区别_清风不灭的博客-CSDN博客
镜像(Image
)和容器(Container
)的关系,就像是面向对象程序设计中的 类
和 实例
一样,镜像是静态的定义,容器是镜像运行时的实体。再做个类比,镜像就是代码,容器就是代码运行起来的进程。(仅作类比)
a:容器 = 镜像 + 可读可写层
图片来源于:Docker系列学习(14) -- 容器内镜像分层详解 - 掘金 (juejin.cn)
这个读写层可以读取下面镜像层的内容,但是,是只能读不能写的!!!!!
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root
文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
b: 运行态容器 + 一些docker的基本操作
运行态容器 = 容器 + 隔离的进程空间;图中灰色框表示进程
其他命令可以详细参考:(19条消息) docker容器和镜像的区别_docker镜像和容器的区别_清风不灭的博客-CSDN博客
4:通过docker commit命令来理解镜像的构成
docker commit
命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。存储记录了文件的变化以及新加入的东西等
举例如下:参考自:利用 commit 理解镜像构成 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
这里我们可以看到,容器的这个读写层,实际上最开始的时候,是直接读取的镜像保存的东西;但其实不是简单的读取!后面会细说!
这样看上去我们修改了镜像的内容,实际上是没有的,我们永远要记住,镜像是只读的!!!
那么修改的到底是什么呢?
其实是:参考自:Docker系列学习(14) -- 容器内镜像分层详解 - 掘金 (juejin.cn)
容器层有一种特效叫 copy-on-wirte, 这是指在容器层进行文件修改时,容器层会自上向下逐层扫描镜像层寻找文件,找到后会copy一份副本到容器层中,再进行修改,这样不会影响镜像
这里还要提一下对容器层删除文件的操作,上面也说了,容器层的文件是从镜像层copy来的,删除的时候删除copy的文件,但如果没有拷贝的文件,就会生成了一条删除记录,记录在without文件中,并屏蔽对该镜像层中这个文件的读取
容器层被删除时,容器层内的所有文件都会失效,数据也会被删除
同时,当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。这样,上层的镜像内容就会覆盖底层的镜像内容,看上去就像是修改了底层镜像内容一样,实际上底层镜像内容并没有动!
这里我们通过commit理解了镜像的生成,但实际上我们很少直接用commit来生成镜像,因为commit'是一个黑箱操作,他会带来很多无关的内容。而且很多操作是不可知的;另外,因为我们说了,这样的方式是不会修改之前层的,我们只会在当前的容器可读可写层记录之前层文件的添加,修改之类的,所以会让镜像不断的臃肿。
5:利用dockfile定制镜像
待续:使用 Dockerfile 定制镜像 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
从刚才的
docker commit
的学习中,我们可以了解到,镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
拿上面的例子来举例:
6:基础镜像
参考:使用 Dockerfile 定制镜像 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
在dockfile中,from用于指定基础镜像,我们说用dockfile来定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 nginx
镜像的容器,再进行修改一样,基础镜像是必须指定的。因此一个 Dockerfile
中 FROM
是必备的指令,并且必须是第一条指令。
在 Docker Hub 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 nginx、redis、mongo、mysql、httpd、php、tomcat 等;也有一些方便开发、构建、运行各种语言应用的镜像,如 node、openjdk、python、ruby、golang 等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如 ubuntu、debian、centos、fedora、alpine 等,这些操作系统的软件库为我们提供了更广阔的扩展空间。
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。
如果你以
scratch
为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,比如 swarm、etcd。对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接
FROM scratch
会让镜像体积更加小巧。使用 Go 语言 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。
7:dockfile的RUN命令
参考自:使用 Dockerfile 定制镜像 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
RUN命令的作用就是新开一个容器,然后再这个容器上执行命令,执行完以后把这层可读可写层commit成一个镜像。
这里可以很好的说明为什么commit会造成镜像臃肿,像这里的命令一样,每一个RUN就是一层镜像,但我们的最终目标其实就是最后的一个RUN,而中间的RUN其实就是写编译软件呀,或者编译过程的中间文件,这些文件其实是不需要的,但是这里的RUN和commit一样都保存下来了,所以会让镜像越来越臃肿。
8:docker build建立镜像
参考:使用 Dockerfile 定制镜像 · Docker —— 从入门到实践 · 看云 (kancloud.cn)
未完待续........
相关文章:

Docker容器理解
目录 目录 一:简单理解操作系统 操作系统: 内核: 内核空间和用户空间: 二:简单理解文件系统 1:什么是文件系统 2:什么是root文件系统 三:docker 1:docker镜像 2&…...

SpringBoot 整合knife4j
文章目录SpringBoot 整合knife4j引入knife4j注解案例knife4j增强功能接口添加作者资源屏蔽访问页面加权控制接口排序分组排序请求参数缓存过滤请求参数禁用调试禁用搜索框SpringBoot 整合knife4j Knife4j是一款基于Swagger 2的在线API文档框架 在Spring Boot中,使…...

73-归并排序练习-LeetCode148排序链表
题目 给你链表的头结点 head ,请将其按升序排列并返回排序后的链表 。 示例 1: 输入:head [4,2,1,3] 输出:[1,2,3,4] 示例 2: 输入:head [-1,5,3,4,0] 输出:[-1,0,3,4,5] 示例 3ÿ…...

Hystrix学习笔记
Hystrix 官方文档: https://github.com/Netflix/Hystrix/wiki 是什么 In a distributed environment, inevitably some of the many service dependencies will fail. Hystrix is a library that helps you control the interactions between these distributed …...

面向对象编程(基础)8:关键字:package、import
目录 8.1 package(包) 8.1.1 语法格式 说明: 8.1.2 包的作用 8.1.3 应用举例 举例2:MVC设计模式 8.1.4 JDK中主要的包介绍 8.2 import(导入) 8.2.1 语法格式 8.2.2 应用举例 8.2.3 注意事项 8.1 package(包) package,称为包&#x…...

【机器学习】P10 从头到尾实现一个线性回归案例
这里写自定义目录标题(1)导入数据(2)画出城市人口与利润图(3)计算损失值(4)计算梯度下降(5)开始训练(6)画出训练好的模型(…...

【Java EE】-多线程编程(四) 死锁
作者:学Java的冬瓜 博客主页:☀冬瓜的主页🌙 专栏:【JavaEE】 分享:2023.3.31号骑行的照片再发一次(狗头)。 主要内容:什么是死锁?不可重入可重入、死锁的三个典型情况:1、一个线程一…...

学习数据结构第1天(数据结构的基本概念)
数据结构的基本概念基本概念和术语数据结构的三要素经典试题基本概念和术语 1.数据 数据是信息的载体,是描述客观事物属性的数、字符以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。数据是计算机程序加工的原料。 2.数据元素 数据元素是数据的基本…...

南大通用数据库-Gbase-8a-学习-33-空洞率查询与解决方法
目录 一、个人理解 二、存储过程 三、虚机测试 四、解决方法 1、重建表 2、shrink space 一、个人理解 空洞率的产生是由于delete语句并不会真实的删除数据,只是在数据上打了一个不可见标签,但实际还是占用着相应的存储空间。 二、存储过程 自定义…...

为什么我们认为GPT是一个技术爆炸
从23年初,ChatGPT火遍全球,通过其高拟人化的回答模式,大幅提升了人机对话的体验和效率,让用户拥有了一个拥有海量知识的虚拟助手,根据UBS发布的研究报告显示,ChatGPT在1月份的月活跃用户数已达1亿ÿ…...

程序员如何能提高自己的编程水平?
这些实用的小建议,能帮你迅速地提高编程水平: 不要做无意义的奋斗 拒绝喊口号和无意义的奋斗,包括但不限于: ①做了计划表却从未有执行的一天; ②每天都是最早来、最晚走,但是工作进度趋近于0;…...

从零使用vuepress搭建个人博客部署.github.io
前言 记录小白如何搭建个人博客 github部署的博客👉: DreamLuffe的博客 netilify部署的博客:👉:DreamLuffe的博客 个人博客搭建实战 网上有很多优秀的开源博客页面,我们就直接安装好,再继续…...

Python 进阶指南(编程轻松进阶):十一、注释、文档字符串和类型提示
原文:http://inventwithpython.com/beyond/chapter11.html 源代码中的注释和文档可能和代码一样重要。原因是软件是永远不会完成的;无论是添加新功能还是修复错误,您总是需要做出改变。但是你不能改变代码,除非你理解它࿰…...

python item()方法
Python中有很多方法来解决一些简单的问题,其中最常见的就是用 item ()方法来完成。item ()方法的全称是item-process (),该方法用来对对象进行创建、删除、改变、添加、更新等操作。…...

【day2】Android Jetpack Compose环境搭建
【day2】Android Jetpack Compose环境搭建 以下是适用于 Jetpack Compose 的环境要求: Android Studio 版本:4.2 Canary 15 或更高版本Gradle 版本:7.0.0-beta02 或更高版本Android 插件版本:4.2.0-beta15 或更高版本Kotlin 版本…...

stable-diffusion安装和简单测试
参考: https://github.com/CompVis/stable-diffusion 理解DALLE 2, Stable Diffusion和 Midjourney的工作原理 Latent Diffusion Models论文解读 【生成式AI】淺談圖像生成模型 Diffusion Model 原理 【生成式AI】Stable Diffusion、DALL-E、Imagen 背後…...

MATLAB算法实战应用案例精讲-【智能优化算法】 基于帕累托包络的选择算法II(PESA-II)(附MATLAB代码实现)
目录 前言 知识储备 数据包络分析(DEA) 特点 名词解释 类型介绍 案例简介 软件操作(SPSSPRO)...

【华为机试真题详解JAVA实现】—坐标移动
目录 一、题目描述 二、解题代码 一、题目描述 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。 输入: 合法坐标为A(或者D或者W或者S) +…...

【软考五】数据库(做题)
该文章不适合学习数据库,适合考证,遇到实际问题的,不要在这儿浪费时间。切记切记 软考之数据库一、概念数据模型(下午题常考)二、结构数据模型关系模型1、关系模型中基本术语2、关系模型中的关系完整性约束3、关系代数…...

【Java Web】012 -- SpringBootWeb综合案例(登录功能、登录校验、异常处理)
目录 一、登录功能 1、基础登录功能 ①、SQL语句 ②、接口参数 ③、实现思路 ④、实现步骤 2、联调Bug(没有Cookie或Session) 二、登录校验 1、登录校验的实现思路 2、会话技术 ①、会话与会话跟踪 ②、会话跟踪方案对比 Cookie Session …...

跨界智能手表:比亚迪向左,小鹏向右
如今,电动化、智能化是汽车行业转型的大方向,而由于目前国内汽车产业在电动化方面已经算是“小有成效”,因此,抢占智能化高地,打造一个多设备互融的生态系统,就成为了车企的共同愿景。在此背景下࿰…...

【c++初阶】第九篇:vector(常用接口的使用 + 模拟实现)
文章目录vector介绍vector的使用vector的定义vector iterator(迭代器) 的使用begin和endrbegin和rendvector 空间增长问题size和capacityreserve和resize(重点)测试vector的默认扩容机制emptyvector的增删查改push_back和pop_backinsert和erasefindswapo…...

Taro React组件使用(6) —— RuiSendCode 短信验证码【倒计时】
1. 需求分析 获取验证码按钮,点击后进入倒计时环节;默认采用 120s 后才允许再次发送短信验证码;发送后不能再次点击发送按钮,点击也不执行发送逻辑;最好将发送短信的业务逻辑请求接口写在组件中,封装为公用组件,可以多处使用。2. 实现效果 2.1 验证码发送前 2.2 验证码…...

把ChatGPT接入我的个人网站
效果图 详细内容和使用说明可以查看我的个人网站文章 把ChatGPT接入我的个人网站 献给有外网服务器的小伙伴 如果你本人已经有一台外网的服务器,并且页拥有一个OpenAI API Key,那么下面就可以参照我的教程来搭建一个自己的ChatGPT。 需要的环境 Cento…...

关于数字游民是未来年轻人工作趋势的一种思考
Q:我觉得未来,数字游民会是中国工作的一种主流方式,因为实体行业受到严重冲击,科技的发展是推导支持这样的远程工作形式,而且未来人的时间是越来越离散化、碎片化、原子化的,以订单交付的形式,P2P的形式会是…...

2022年 合肥市经开区信息学竞赛区赛 初中组
2022年 合肥市经开区信息学竞赛区赛 初中组T1.普通排序 题目描述 牛牛是一位编程爱好者,今天第一次参加初中组比赛,看到第一题,不要紧张,来一个简单的排序题做一做,牛牛学过了很多排序,一直想练个手,这回机会来了,给牛牛N个数(n<=100),每个数都在(0 ~ 1000)之间…...

【工作小札】自定义classloader实现热加载jar
文章目录楔子第一步:添加maven依赖第二步:创建jar包路径构造类第三步:定义需要被加载的jar的目录结构第四步:创建自定义类加载器1 继承ClassLoader并实现Closeable接口2 标记该加载器支持并行类加载机制3 私有化构造方法ÿ…...

spring—AOP
系列文章目录 Spring中AOP技术的学习 文章目录系列文章目录前言一、AOP核心概念二、AOP入门案例1.AOP入门案例思路分析2.AOP入门案例实现三、AOP工作流程四、AOP切入点表达式五、AOP通知类型六、案例:测量业务层接口万次执行效率1.项目结构2.实现类七、AOP获取通知…...

自己曾经的C++笔记【在c盘爆满的时候找到的回忆】
文章目录**C与C的区别** (二)类和对象构造函数和析构函数C特殊成员C友元C类的继承C虚函数和多态C模板C可变参模板CSTL容器篇C迭代器C仿函数C函数适配器CSTL算法C智能指针C类型推断CIO流C正则表达式具有特殊意义的元字符量词元字符校验数字的表达式校验字符的表达式特…...

Nginx 实战-负载均衡
一、负载均衡今天学习一下Nginx的负载均衡。由于传统软件建构的局限性,加上一台服务器处理能里的有限性,在如今高并发、业务复杂的场景下很难达到咱们的要求。但是若将很多台这样的服务器通过某种方式组成一个整体,并且将所有的请求平均的分配…...