十一、容器化 vs 虚拟化-Docker

文章目录

  • 前言
  • 一、Docker 介绍
    • 1. 简介
    • 2. 应用场景
    • 3. 特点
    • 4. Docker和虚拟机之间的区别
    • 5. 解决痛点
      • 1. 解决依赖兼容
      • 2. 解决操作系统环境差异
      • 3. 小结
  • 二、Docker 架构
  • 三、工作流程
  • 五、Docker 核心组件及其工作机制
    • 1. Docker 客户端(Docker Client)
    • 2. Docker 守护进程(Docker Daemon)
    • 3. Docker 引擎 API(Docker Engine API)
    • 4. Docker 容器(Docker Containers)
    • 5. Docker 镜像(Docker Images)
    • 6. Docker 仓库(Docker Registries)
    • 7. Docker Compose
    • 8. Docker Swarm
    • 9. Docker 网络(Docker Networks)
    • 10. Docker 卷(Docker Volumes)
  • Docker 命令


前言

容器化

  我们搭建了微服务体系,同时借助Idea编译工具多次完成本地服务启动、部署和验证。就会出现下面场景:

  • 开发人员A写好的代码–>开发人员B的电脑上运行,B必须保证跟A一样的系统环境(JDK/MySQL等)
  • 系统代码部署从DEV–>TEST–>PRE–>PROD,每个环节都必须保证一样的系统环境(同上)
  • 分布式系统中依赖组件非常多,组件与组件之间的部署往往会产生一些冲突(端口/依赖/环境等)

传统基础架构部署
  这样的版本一致保证会耗费我们大量的时间和精力,同时万一有问题产生,我们也很难第一时间考虑到是因为版本不一致导致的问题。

  因此我们需要一套可以平滑切换的部署引擎,这就是容器化技术Docker


一、Docker 介绍

1. 简介

Docker标识
  Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

  Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

  容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低

  Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。

相关链接

Docker 官网

Github Docker 源码

2. 应用场景

  • Web 应用的自动化打包和发布(编译构建和部署)

  • 自动化测试和持续集成、持续交付(CI/CD)

  • 在服务型环境中部署和调整数据库或其他的后台应用。

  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

3. 特点

  Docker 是一个用于开发,交付和运行应用程序的开放平台。

  Docker 使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,您可以采用与管理应用程序相同的方式来管理基础架构。

  通过利用 Docker 的方法实现快速交付,测试和部署代码,您可以大幅提高,开发迭代和部署上限的效率。

  1. 快速,一致地交付应用程序

Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。

容器非常适合持续集成和持续交付(CI / CD)工作流程,请考虑以下示例方案:

  • 您的开发人员在本地编写代码,并使用 Docker 容器与同事共享他们的工作。

  • 他们使用 Docker 将其应用程序推送到测试环境中,并执行自动或手动测试。

  • 当开发人员发现错误时,他们可以在开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。

  • 测试完成后,将修复后的程序推送给生产环境,就像将更新的镜像推送到生产环境一样简单。

  1. 响应式部署和扩展

Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。

Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。

  1. 在同一硬件上运行更多工作负载

Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。

4. Docker和虚拟机之间的区别

‌虚拟机‌:是基于虚拟硬件的操作系统。虚拟机是通过Hypervisor(虚拟机管理系统,常见的有VMWare workstation、VirtualBox),虚拟出网卡、CPU、内存等虚拟硬件,再在其上建立虚拟机,每个虚拟机是个独立的操作系统,拥有自己的系统内核。体积大、启动速度慢、性能一般。

‌Docker‌:是一个系统进程。容器是利用namespace将文件系统、进程、网络、设备等资源进行隔离,利用cgroup对权限、CPU资源进行限制,最终让容器之间互不影响,容器无法影响宿主机。体积小、启动速度快、性能好。

Docker和虚拟机的区别

特性虚拟机容器
启动分钟级秒级
硬盘使用一般为 GB一般为 MB
性能接近原生
系统支持量一般几十个单机支持上千个容器

5. 解决痛点

1. 解决依赖兼容

Docker为了解决依赖的兼容问题的,采用了两个手段:

  • 【依赖打包】将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
  • 【部署隔离】将每个应用放到一个隔离容器去运行,避免互相干扰

Docker解决依赖兼容此时打包好的应用包(不再是原来的jar包)既包含应用本身,也包含应用所需的Libs、Deps,无需在操作系统上安装,自然不存在应用间的兼容问题。
虽然解决了不同应用的兼容问题,但是开发、测试等多个环境,不同的操作系统版本之间也会有差异,这个不解决一样会面临开篇所说的问题,想了解这个必须先了解下操作系统的结构。

2. 解决操作系统环境差异

以一个ubuntu操作系统为例,如下:

Docker解决操作系统环境差异其结构包括:

  • 计算机硬件:如CPU、内存、磁盘等
  • 系统内核:所有Linux发行版内核都是Linux,如CentOS/Ubuntu/Fedora等,内核与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
  • 系统应用:操作系统本身提供的应用、函数库。这些函数是对内核指令的封装,使用更方便。

应用与计算机交互的流程大致如下:

  • 应用(外部应用如redis/web应用等)调用操作系统应用(函数库),实现各种功能
  • 系统函数库是对内核指令集的封装,会调用内核指令
  • 内核指令操作计算机硬件
    如Ubuntu和CenOS虽然都是基于Linux内核,无非是系统应用不同,提供函数库有差异,如下:

在这里插入图片描述
但就是这种差异,当一个Ubuntu版本的MySQL尝试安装到CentOS系统时,MySQL还是调用的Ubuntu函数库,会出现找不到或者不匹配的情况,从而导致报错,即出现我们上面提到的系统环境差异导致的不兼容问题:

在这里插入图片描述
我们来看下Docker是如何处理这种环境间的差异的:

  • Docker将应用程序与所需调用的系统(如Ubuntu)函数库一起打包
  • Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统Linux内核来运行

在这里插入图片描述

3. 小结

  1. Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
  • Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
  • Docker应用运行在容器中,使用沙箱机制,相互隔离
  1. Docker如何解决开发、测试、生产环境有差异的问题?
  • Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
  1. Docker是一个快速交付应用、运行应用的技术,具备下列优势:
  • 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统
  • 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
  • 启动、移除都可以通过一行命令完成,方便快捷

二、Docker 架构

  Docker 架构是基于客户端-服务器的C/S模式,其中包括多个关键组件,确保容器化应用的高效构建、管理和运行。可以使用远程 API 来管理和创建 Docker 容器

  Docker 容器(Container),是独立运行的一个或一组应用,基于 Docker 镜像来创建,是镜像运行时的实体。

  Docker 镜像(Image),用于创建 Docker 容器的模板,就相当于是一个 root 文件系统。

  镜像和容器的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Docker面向对象
容器对象实例
镜像

Docker架构1
Docker架构2
  Docker是一个CS架构的程序,底层由Go 语言进行开发实现,由两部分组成:

  • 服务端(Server):Docker 守护进程,负责处理 Docker 指令,管理镜像、容器等。
  • 客户端(Client):通过命令或 RestAPI 向 Docker 服务端发送指令。可以在本地或远程向服务端发送指令。

Docker架构3

三、工作流程

  • 构建镜像:使用 Dockerfile 创建镜像。

  • 推送镜像到仓库:将镜像上传到 Docker Hub 或私有镜像仓库中。

  • 拉取镜像:通过 docker pull 从镜像仓库中拉取镜像。

  • 运行容器:使用镜像创建并启动容器。

  • 管理容器:使用 Docker 客户端命令管理正在运行的容器(例如查看日志、停止容器、查看资源使用情况等)。

  • 网络与存储:容器之间通过 Docker 网络连接,数据通过 Docker 卷或绑定挂载进行持久化。

五、Docker 核心组件及其工作机制

1. Docker 客户端(Docker Client)

Docker 客户端是用户与 Docker 守护进程交互的命令行界面(CLI)。它是用户与 Docker 系统的主要交互方式,用户通过 Docker CLI 发出命令,这些命令被发送到 Docker 守护进程,由守护进程执行相应的操作。

  • 功能:允许用户使用命令与 Docker 守护进程通信,如创建容器、构建镜像、查看容器状态等。

  • 交互方式:Docker 客户端与 Docker 守护进程之间通过 REST API 或 Unix 套接字通信。常用的命令行工具是 docker,通过它,用户可以发出各种 Docker 操作命令。

常用命令:

  • docker run:运行容器。

  • docker ps:列出正在运行的容器。

  • docker build:构建 Docker 镜像。

  • docker exec:在容器中执行命令。

2. Docker 守护进程(Docker Daemon)

Docker 守护进程(通常是 dockerd)是 Docker 架构的核心,负责管理容器生命周期、构建镜像、分发镜像等任务。

守护进程通常以后台进程的方式运行,等待来自 Docker 客户端的 API 请求。

功能:

  • 启动和停止容器。

  • 构建、拉取和推送镜像。

  • 管理容器的网络和存储。

  • 启动、停止、查看容器日志等。

  • 与 Docker 注册表进行通信,管理镜像的存储与分发。

Docker 守护进程监听来自 Docker 客户端的请求,并且通过 Docker API 执行这些请求。守护进程将负责容器、镜像等 Docker 对象的管理,并根据请求的参数启动容器、删除容器、修改容器配置等。

启动 Docker 守护进程(通常是自动启动的):

sudo systemctl start docker

3. Docker 引擎 API(Docker Engine API)

Docker 引擎 API 是 Docker 提供的 RESTful 接口,允许外部客户端与 Docker 守护进程进行通信。通过这个 API,用户可以执行各种操作,如启动容器、构建镜像、查看容器状态等。API 提供了 HTTP 请求的接口,支持跨平台调用。

功能:

  • 向 Docker 守护进程发送 HTTP 请求,实现容器、镜像的管理。

  • 提供 RESTful 接口,允许通过编程与 Docker 进行交互。

可以通过 curl 或其他 HTTP 客户端访问 Docker 引擎 API。例如,查询当前 Docker 守护进程的版本:

curl --unix-socket /var/run/docker.sock http://localhost/version

4. Docker 容器(Docker Containers)

容器是 Docker 的执行环境,它是轻量级、独立且可执行的软件包。容器是从 Docker 镜像启动的,包含了运行某个应用程序所需的一切——从操作系统库到应用程序代码。容器在运行时与其他容器和宿主机共享操作系统内核,但容器之间的文件系统和进程是隔离的。

功能:

  • 提供独立的运行环境,确保应用程序在不同的环境中具有一致的行为。

  • 容器是临时的,通常在任务完成后被销毁。

容器的生命周期是由 Docker 守护进程管理的。容器可以在任何地方运行,因为它们不依赖于底层操作系统的配置,所有的运行时依赖已经封装在镜像中。

启动一个容器:

docker run -d ubuntu

5. Docker 镜像(Docker Images)

Docker 将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起的特殊文件系统,称为镜像。

Docker 镜像是容器的只读模板,用户可以根据镜像启动容器。每个镜像除了提供容器应用程序运行所需的操作系统、应用程序、库、资源配置等文件外,还包含了为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像是静态的,不包含任何动态数据,其内容在构建之后也不会被改变。

功能:

  • 镜像是构建容器的基础,每个容器实例化时都会使用镜像。

  • 镜像是只读的,不同容器使用同一个镜像时,容器中的文件系统层是独立的。

Docker 镜像可以通过 ‌docker pull‌ 从 Docker Hub 或私有注册表拉取,也可以通过 docker build 从 Dockerfile 构建。

拉取 Ubuntu 镜像:

docker pull ubuntu

6. Docker 仓库(Docker Registries)

Docker 仓库是用来存储 Docker 镜像的地方,最常用的公共仓库是 Docker Hub。用户可以从 Docker Hub 下载镜像,也可以上传自己的镜像分享给其他人。除了公共仓库,用户也可以部署自己的私有 Docker 仓库来管理企业内部的镜像。

功能:

  • 存储 Docker 镜像。

  • 提供镜像的上传和下载功能。

Docker Hub 提供了大量官方和社区维护的镜像,如 Ubuntu、Nginx、MySQL 等。

推送镜像到 Docker Hub:

docker push <username>/<image_name>

7. Docker Compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过 Compose,用户可以使用一个 docker-compose.yml 配置文件定义多个容器(服务),并可以通过一个命令启动这些容器。Docker Compose 主要用于开发、测试和部署多容器的应用。

功能:

  • 定义和运行多个容器组成的应用。

  • 通过 YAML 文件来配置应用的服务、网络和卷等。

创建一个简单的 docker-compose.yml 文件来配置一个包含 Web 服务和数据库服务的应用:

version: '3'
services:web:image: nginxports:- "8080:80"db:image: mysqlenvironment:MYSQL_ROOT_PASSWORD: example

启动 Compose 定义的所有服务:

docker-compose up

8. Docker Swarm

Docker Swarm 是 Docker 提供的集群管理和调度工具。它允许将多个 Docker 主机(节点)组织成一个集群,并通过 Swarm 集群管理工具来调度和管理容器。Swarm 可以实现容器的负载均衡、高可用性和自动扩展等功能。

功能:

  • 管理多节点 Docker 集群。

  • 通过调度器管理容器的部署和扩展。

初始化 Swarm 集群:

docker swarm init

9. Docker 网络(Docker Networks)

Docker 网络允许容器之间相互通信,并与外部世界进行连接。Docker 提供了多种网络模式来满足不同的需求,如 bridge 网络(默认)、host 网络和 overlay 网络等。

功能:

  • 管理容器间的网络通信。

  • 支持不同的网络模式,以适应不同场景下的需求。

创建一个自定义网络并将容器连接到该网络:

docker network create my_network
docker run -d --network my_network ubuntu

10. Docker 卷(Docker Volumes)

Docker 卷是一种数据持久化机制,允许数据在容器之间共享,并且独立于容器的生命周期。与容器文件系统不同,卷的内容不会随着容器的销毁而丢失,适用于数据库等需要持久存储的应用。

功能:

  • 允许容器间共享数据。

  • 保证数据持久化,独立于容器的生命周期。

创建并挂载卷:

docker volume create my_volume
docker run -d -v my_volume:/data ubuntu

Docker 命令

Docker 命令


本文的引用仅限自我学习如有侵权,请联系作者删除。
参考知识
Docker 教程


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

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

相关文章

linux学习笔记01 基础命令

目录 创建 touch 创建文件 &#xff08;创建但是不打开&#xff09; vi / vim 创建文件 (创建一个文件并打开) mkdir 创建文件夹 切换目录 cd 查看 pwd 查看当前目录完整路径 ls 查看目录信息 dir 查看目录信息 ll 表示查看目标目录下的信息 ls -a 查看当前目录下的…

【深度学习】深刻理解多模态模型CLIP

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09; 是由 OpenAI 提出的一个多模态模型&#xff0c;旨在学习视觉和语言的联合表示&#xff0c;能够通过图像和文本之间的对比学习来实现图像和文本之间的紧密联系。CLIP 模型可以通过自然语言描述理解和处理图…

mysql时间戳格式化yyyy-mm-dd

格式化到 年月日 # 将时间换成列名就行&#xff1b;当前是秒级时间戳&#xff0c;如果是毫秒的 / 1000即可 # SELECT FROM_UNIXTIME(1602668106666.777888999 / 1000,%Y-%m-%d) AS a; # SELECT FROM_UNIXTIME(列名 / 1000,%Y-%m-%d) AS a; SELECT FROM_UNIXTIME(1602668106.666…

PDFMathTranslate,PDF多语言翻译,批量处理,学术论文,双语对照(WIN/MAC)

分享一个非常实用的PDF文档翻译项目——PDFMathTranslate。作为一个经常逛GitHub的开发者&#xff0c;我总喜欢翻看各种项目附带的论文&#xff0c;虽然大多时候是瞎研究&#xff0c;但却乐在其中。该项目能够完美保留公式、图表、目录和注释&#xff0c;对于需要阅读外文文献的…

爬虫基础之代理的基本原理

在做爬虫的过程中经常会遇到一种情况&#xff0c;就是爬虫最初是正常运行、正常抓取数据的&#xff0c;一切看起来都是那么美好&#xff0c;然而一杯茶的工夫就出现了错误&#xff0c;例如 403 Forbidden&#xff0c;这时打开网页一看&#xff0c;可能会看到“您的IP访问频率太…

鲲鹏麒麟安装Kafka-v1.1.1

因项目需要在鲲鹏麒麟服务器上安装Kafka v1.1.1&#xff0c;因此这里将安装配置过程记录下来。 环境说明 # 查看系统相关详细信息 [roottest kafka_2.12-1.1.1]# uname -a Linux test.novalocal 4.19.148 #1 SMP Mon Oct 5 22:04:46 EDT 2020 aarch64 aarch64 aarch64 GNU/Li…

群控系统服务端开发模式-应用开发-登录退出发送邮件

一、登录成功发送邮件 在根目录下app文件夹下controller文件夹下common文件夹下&#xff0c;修改Login.php&#xff0c;代码如下 <?php /*** 登录退出操作* User: 龙哥三年风水* Date: 2024/10/29* Time: 15:53*/ namespace app\controller\common; use app\controller\Em…

[游戏开发] Unity中使用FlatBuffer

什么是FlatBuffer 官网&#xff1a; GitHub - google/flatbuffers: FlatBuffers: Memory Efficient Serialization LibraryFlatBuffers: Memory Efficient Serialization Library - google/flatbuffershttps://github.com/google/flatbuffers 为什么用FloatBuffer&#xff0c…

MySQL其一,概念学习,可视化软件安装以及增删改查语句

目录 MySQL 1、数据库的概念 2、数据库分类 3、MySQL的安装 4、安装过程中的问题 DataGrip的使用&#xff1a; SQLynx的使用&#xff1a; 5、编写SQL语句 6、DDL语句 7、DML 新增数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; MySQL SQL其实是一门…

05 在 Linux 使用 AXI DMA

DMA简介 DMA 是一种采用硬件实现存储器与存储器之间或存储器与外设之间直接进行高速数据传输的技术&#xff0c;传输过程无需 CPU 参与&#xff08;但是CPU需要提前配置传输规则&#xff09;&#xff0c;可以大大减轻 CPU 的负担。 DMA 存储传输的过程如下&#xff1a; CPU 向…

linux 安装 vsftpd 服务以及配置全攻略,vsftpd 虚拟多用户多目录配置,为每个用户配置不同的使用权限

linux 安装 vsftpd 服务以及配置全攻略&#xff0c;vsftpd 虚拟多用户多目录配置&#xff0c;为每个用户配置不同的使用权限。 linux 安装 vsftpd 服务以及配置全攻略 FTP 是 File Transfer Protocol 的简称&#xff0c;用于 Internet 上的控制文件的双向传输。同时&#xff0…

SQL语句在MySQL中如何执行

MySQL的基础架构 首先就是客户端&#xff0c;其次Server服务层&#xff0c;大多数MySQL的核心服务都在这一层&#xff0c;包括连接、分析、优化、缓存以及所有的内置函数&#xff08;时间、日期、加密函数&#xff09;&#xff0c;所有跨存储引擎功能都在这一层实现&#xff1…

ragflow连不上ollama的解决方案

由于前期wsl默认装在C盘&#xff0c;后期部署好RagFlow后C盘爆红&#xff0c;在连接ollama的时候一直在转圈圈&#xff0c;问其他人没有遇到这种情况&#xff0c;猜测是因为内存不足无法加载模型导致&#xff0c;今天重新在E盘安装wsl 使用wsl装Ubuntu Win11 wsl-安装教程 如…

C#常见错误—空对象错误

System.NullReferenceException&#xff1a;未将对象引用设置到对象的实例 在C#编程中&#xff0c;System.NullReferenceException是一个常见的运行时异常&#xff0c;其错误信息“未将对象引用设置到对象的实例”意味着代码试图访问一个未被初始化或已被设置为null的对象的成…

沁恒CH32V208蓝牙串口透传例程:修改透传的串口;UART-CH32V208-APP代码分析;APP-CH32V208-UART代码分析

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

Scala的隐式对象

Scala中&#xff0c;隐式对象&#xff08;implicit object&#xff09;是一种特殊的对象&#xff0c;它可以使得其成员&#xff08;如方法和值&#xff09;在特定的上下文中自动可用&#xff0c;而无需显式地传递它们。隐式对象通常与隐式参数和隐式转换一起使用&#xff0c;以…

矩阵的乘(包括乘方)和除

矩阵的乘分为两种&#xff1a; 一种是高等代数中对矩阵的乘的定义&#xff1a;可以去这里看看包含矩阵的乘。总的来说&#xff0c;若矩阵 A s ∗ n A_{s*n} As∗n​列数和矩阵 B n ∗ t B_{n*t} Bn∗t​的行数相等&#xff0c;则 A A A和 B B B可相乘&#xff0c;得到一个矩阵 …

DVWA亲测sql注入漏洞

LOW等级 我们先输入1 我们加上一个单引号&#xff0c;页面报错 我们看一下源代码&#xff1a; <?php if( isset( $_REQUEST[ Submit ] ) ) { // Get input $id $_REQUEST[ id ]; // Check database $query "SELECT first_name, last_name FROM users WHERE user_id …

机器学习01-发展历史

机器学习01-发展历史 文章目录 机器学习01-发展历史1-传统机器学习的发展进展1. 初始阶段&#xff1a;统计学习和模式识别2. 集成方法和核方法的兴起3. 特征工程和模型优化4. 大规模数据和分布式计算5. 自动化机器学习和特征选择总结 2-隐马尔科夫链为什么不能解决较长上下文问…

想了解操作系统,有什么书籍推荐?

推荐一本操作系统经典书&#xff1a; 操作系统导论 《操作系统导论》虚拟化(virtualization)、并发(concurrency)和持久性(persistence)。这是我们要学习的3个关键概念。通过学习这3个概念&#xff0c;我们将理解操作系统是如何工作的&#xff0c;包括它如何决定接下来哪个程序…