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

五种 IO 模型

文章目录

      • 操作系统和内存
        • 内核空间和用户空间
        • 应用程序的内核态和用户态
        • 网络 IO 和磁盘 IO
        • 简易的网络通信流程
        • 阻塞和非阻塞
      • 阻塞 IO 模型
      • 非阻塞 IO 模型
      • IO 复用模型
        • Select
        • Poll
        • Epoll
        • 小结
      • 信号驱动 IO 模型
      • 异步 IO 模型
      • 五种 IO 模型的对比
      • IO 模型里的同步和异步

5种 IO 模型分别是: 阻塞 IO 模型非阻塞 IO 模型IO 复用模型信号驱动 IO 模型异步 IO 模型

操作系统和内存

计算机由操作系统和硬件组成。

操作系统主要包含内核(kernel)应用程序

内核提供进程管理、内存管理、网络服务等底层功能,也提供了与硬件交互的接口,通过系统调用提供给上层的应用程序使用。

应用程序(如浏览器、QQ、MySQL 等,下面简称为程序)要操作硬件(如进行磁盘读写),需要先与内核交互再由内核与硬件交互

硬件包括 CPU、内存、硬盘、网卡、声卡、显卡等。

内核空间和用户空间

操作系统都是采用虚拟地址空间,内核是操作系统的核心,独立于普通的应用程序,内核可以访问受保护的内存空间(内核空间),也有访问底层硬件设备的所有权限。

为了保证内核的安全,操作系统将虚拟内存空间划分为内核空间用户空间两个部分。它们是隔离的,即使用户程序崩溃了,内核也不受影响。

  • 内核空间是操作系统的内核代码运行的地址空间,是受保护的内存空间。也称内核内存。
  • 用户空间是普通的用户程序代码运行的内存地址空间。也称用户内存。

应用程序的内核态和用户态

早期的操作系统是不区分内核空间和用户空间的。应用程序能随意访问任意内存空间,导致用户程序经常把系统搞崩溃。

后来,就按照 CPU 指令的重要程度对指令进行了分级。

CPU 指令分为四个级别:Ring0 ~ Ring3,Linux 只使用了 Ring0 和 Ring3 两个运行级别。

程序进程运行 Ring3 级别的指令时运行在用户态,只能访问用户空间。

程序进程运行 Ring0 级别的指令时被称为内核态,可访问任意内存空间。

当程序进程(线程)运行在内核空间时,它就处于内核态;当程序进程(线程)运行在用户空间时,它就处于用户态。

那么,程序什么时候运行在内核空间,什么时候运行在用户空间呢?

当需要进行 IO 操作时,比如读写磁盘文件、读写网卡数据时,程序进程需切换到内核态,否则无法操作。无论是从用户态切换到内核态,还是从内核态切换到用户态,都需要进行一次上下文的切换。一般情况下,程序不能直接操作内核空间的数据,需要把内核内存的数据拷贝到用户空间才能操作。

当程序进程执行系统调用而进入内核代码中执行时,称进程处于内核运行态(内核态)。

除了系统调用可以实现用户态到内核态的切换,软中断和硬中断也会切换用户态和内核态。

  • 在内核态下:程序进程(线程)运行在内核空间中,此时 CPU 可以执行任何指令。运行的代码也不受任何的限制,可以自由地访问任何有效地址,也可以直接进行端口的访问。
  • 在用户态下:程序进程(线程)运行在用户空间中,被执行的代码要受到 CPU 的很多检查,比如:进程只能访问映射其地址空间的页表项中规定的在用户态下可访问的虚拟地址。

网络 IO 和磁盘 IO

IO 是 Input/Output 的缩写,也就是计算机中的输入和输出。

由于应用程序和运行时数据是在内存中驻留的,由 CPU 来执行各种操作,涉及到数据交换的地方(通常是内存、磁盘和网络等)就需要 IO 接口。

通常,程序完成 IO 操作会有 Input 和 Output 两个数据流。比如,从 MySQL 读取数据到内存,就有 Input 操作,再把数据展现出来给我们看,就有 Output 操作。

IO 操作是相对于内存而言的,数据从外部设备进入内存就是 Input;从内存取出数据输出到外部设备就是 Output。

用户进程无法直接操作 IO 设备,必须通过系统调用,请求内核来协助完成。内核会为每一个 IO 设备维护一个缓冲区。

通常,用户进程完成一次完整的 IO 操作,需要两个阶段:用户进程空间与内核空间的交互内核空间与设备空间(硬盘、网卡)的交互

IO 从读取数据的来源分为内存 IO、 网络 IO 和磁盘 IO 三种,通常说的 IO 是指网络 IO 和 磁盘 IO。(因为内存 IO 的读写速度远大于网络 IO 和磁盘 IO)

IO 按照设备来分,可分为网络 IO 和磁盘 IO。网络 IO 就是通过网络进行数据的拉取和输出。
磁盘 IO 就是对磁盘进行的读写操作。

  • 网络 IO:等待网络数据到达网卡,把网卡中的数据读取到内核缓冲区,然后从内核缓冲区拷贝数据到用户进程空间。
  • 磁盘 IO:把数据从磁盘读取到内核缓冲区,然后从内核缓冲区拷贝数据到用户进程空间。

由于 CPU 和内存的运行速度远远高于外部设备(网卡、磁盘等),所以在 IO 编程中,存在速度严重不匹配的问题。

简易的网络通信流程

以两个应用程序的通信为例,程序 A 给程序 B 发送消息,基本流程如下:

  • A 把数据发送到 TCP 发送缓冲区。
  • TCP 发送缓冲区再把数据发送出去,经过网络传递后,数据会发送到 B 所在服务器的 TCP 接收缓冲区。
  • B 再从 TCP 接收缓冲区去读取属于自己的数据。

也就是说,消息发送要经过应用层的程序 A、A 所在服务器的 TCP 发送缓冲区,经过网络传输后消息发送到了另一个应用层的程序 B 所在服务器的 TCP 接收缓冲区,最终 B 读取到消息。

阻塞和非阻塞

由于应用程序之间发送消息是间断性的,那么,当程序 B 所在服务器的 TCP 接收缓冲区,还未接收到消息数据时,此时 B 向 TCP 接收缓冲区发起读取申请,TCP 接收缓冲区是应该马上告诉 B 现在没有你的数据,还是让 B 继续等待,直到有数据再交给 B。

对于应用程序 A 也是一样。A 在向 TCP 发送缓冲区发送数据时,如果 TCP 发送缓冲区已经满了,那么是立即告诉 A 现在没空间了,还是让 A 等着,等 TCP 发送缓冲区有空间了再把 A 的数据拷贝到发送缓冲区。

阻塞:以读取数据为例,当程序 B 发起读取申请时,在内核把数据准备就绪之前,B 一直处于等待状态(其它什么也不做),直到内核把数据准备好交给 B,才结束。

基本流程:

  1. 程序进程(或线程)向内核发起 recfrom 读取数据。
  2. 内核准备数据。
  3. 程序进程将数据从内核空间拷贝到用户空间。
  4. 拷贝完成后,返回成功提示。

非阻塞:以读取数据为例,当程序 B 发起读取申请时,如果内核没有把数据准备好,会立即告诉 B(返回提示或错误),不会让 B 一直等待。

基本流程:

  1. 程序进程(或线程)向内核发起 recfrom 读取数据。
  2. 内核没有把数据好时,立即返回 EWOULDBLOCK 错误码。
  3. 程序进程不断调用 recvfrom,即向内核发起轮询请求。
  4. 当数据准备就绪,就进行下一步;否则还是返回错误码。
  5. 将数据从内核空间拷贝到用户空间。
  6. 拷贝完成后,返回成功提示。

IO 操作分为两个阶段(步骤)

  • 内核进行数据准备的阶段
  • 数据从内核空间拷贝到用户空间的阶段

根据这两个阶段,处理方式的不同,IO 操作可细分为下面五种。

阻塞 IO 模型

阻塞 IO 模型是指当程序 B 发起 IO 请求时,如果内核没有把数据准备就绪,B 会一直处于等待状态,直到内核把数据准备好了,并交给 B 才结束。

优点:开发相对简单,在阻塞期间,用户线程被挂起,期间不会占用 CPU 资源。

缺点

  • 连接利用率不高,内核如果没有响应数据,则该连接一直处于阻塞状态,占用连接资源。
  • 一个线程维护一个 IO 资源,当有大量并发请求时,需要创建等价的线程来处理请求,不适合高并发场景。

非阻塞 IO 模型

非阻塞 IO 模型是指当程序 B 发起 IO 请求时,如果内核没有把数据准备就绪,会立即告诉 B(返回提示或错误码),这样,B 就不会一直等待,而是每过一段时间发起轮询请求

优点:每次发起 IO 请求时,在内核准备数据的过程中可以立即返回,用户线程不会阻塞,实时性较好。

缺点

  • 当用户线程 B 没有获取到数据时,需不断轮询,占用大量 CPU 时间,效率不高。
  • 和阻塞 IO 一样,一个线程维护一个 IO 资源,当有大量并发请求时,需要创建等价的线程来处理请求,不适合高并发场景。

IO 复用模型

思考一个问题:

高并发的情况下,有很多人向应用程序 B 发送消息,此时程序 B 可能就要创建很多个线程,每个线程都会调用 recvfrom 读取数据。B 是不知道什么时候 TCP 接收缓冲区里会有数据,为了保证能及时读取到消息,每个线程必须不断内核发起 recvfrom 请求。

问题在于,大量线程不断调用 recvfrom,实在太浪费系统资源。

于是,有人便提出了一个解决思路:

在程序 B 中,采用 IO 复用器(select),监控多个网络请求(fd 文件描述符,句柄),这样,只需一个线程就可以完成数据状态的询问操作,当内核空间中有数据准备就绪,再分配其他的线程(或自己)去读取数据。而不用为每一个请求创建一个线程,从而节省出大量的线程资源。这就是 IO 复用模型

Linux 中 IO 复用的实现方式主要有 Select、Poll 和 Epoll。

IO 复用模型的思路是系统提供了一种函数可以同时监控多个 fd,这个函数就是我们常说的 select、poll 或 epoll,程序线程通过调用 select 函数就可以同时监控多个 fd,监控的 fd 集合中只要有任何一个数据状态准备就绪了,select 函数就会返回可读状态,这时再去分配其他线程(或自己),发起 recvfrom 请求读取数据。

Select

水平触发(Level Triggered),它会无差别地遍历(轮询)整个被监听的 fd 文件描述符集合(fd_set) 。如果有哪一个 fd 准备就绪,就返回这个活跃的连接。fd_set 的大小是受限制的(由 Linux 内核的 FD_SETSIZE 定义)。

  • 事件集合:通过3个参数分别可读、可写及异常等事件。内核通过对这些参数的在线修改来反馈其中的就绪事件,使得每次调用 select 函数都要重置这 3 个参数。
  • 工作模式:LT
  • 程序获得就绪 fd 的复杂度:时间复杂度 O(n)
  • 支持最大的 fd 数量:一般为 1024
  • 内核实现和复杂度:轮询方式检测就绪事件,时间复杂度:O(n)

Poll

原理和 select 类似,poll 底层需要分配一个 pollfd 结构数组,维护在内核中,不受 fd_set 大小的限制。

  • 事件集合:统一处理所有事件类型,因此只需要一个事件集参数。用户通过 pollfd.events 传入要监听的事件,内核通过修改 pollfd.revents 反馈其中就绪的事件。
  • 工作模式:LT
  • 程序获得就绪 fd 的复杂度:时间复杂度 O(n)
  • 支持最大的 fd 数量:65535
  • 内核实现和复杂度:轮询方式检测就绪事件,时间复杂度:O(n)

Epoll

边缘触发(Edge Triggered),采用事件驱动和回调函数。三大要素:mmap、红黑树、链表。

  • 事件集合:内核通过一个事件表直接管理用户程序监听的所有事件。因此每次调用 epoll_wait 时,无需反复传入事件。epoll_wait 系统调用的参数 events 仅用来反馈就绪的事件。
  • 工作模式:ET
  • 程序获得就绪 fd 的复杂度:时间复杂度 O(1)
  • 支持最大的 fd 数量:65535
  • 内核实现和复杂度:回调方式检测就绪事件,时间复杂度:O(1)

说明:epoll 并不是在所有的场景都比 select 和 poll 高效很多,尤其是当活动连接比较多的时候。epoll 特别适用于连接数量多,但活动连接较少的场景

小结

select、poll、epoll 都是 IO 多路复用的机制。

IO 多路复用就是通过一种机制,监听多个 fd 文件描述符,一旦某个 fd 准备就绪,能够通知程序进行相应的读写操作。

但 select、poll、epoll 本质上都是同步 IO,因为它们都需要在读写事件就绪后自己负责读写(一个个的处理),也就是说这个读写过程是阻塞的。而异步 IO 则无需自己负责读写,异步 IO 的实现会负责把数据从内核空间拷贝到用户空间。

IO 复用的基本思想是通过 select、poll、epoll 来监控多个 fd ,达到不必为每个 fd 创建一个对应的监控线程,从而减少线程资源的创建。

IO 复用的优势并不是对于单个连接处理得多快,而是在于能处理更多的连接。

IO 复用模型的优点:系统不必创建和维护大量的线程,只需要一个或几个线程便可同时处理成千上万个连接,大大减少了系统的开销。

IO 复用模型的缺点:本质上还是同步阻塞模式。

信号驱动 IO 模型

IO 复用模型实现了一个线程可以监控多个 fd,但 select 是采用轮询的方式来监控多个 fd 的,通过不断轮询 fd 的状态来判断是否有数据准备就绪,这种无脑的轮询显得有些暴力,因为大部分情况下的轮询都是无效的。

所以有人就想,能不能不要让我总是去询问你是否有数据准备就绪,能不能我发出请求后等你数据准备好了就通知我。于是,就诞生了信号驱动 IO 模型。

信号驱动 IO 模型是指程序 B 通过系统调用 sigaction,向内核空间注册一个信号处理回调函数,就立即返回(非阻塞);当内核把数据准备就绪时,会发送一个信号(SIGIO)通知 B,B 再向内核调用 recvfrom 读取数据。

信号驱动 IO 模型解决了轮询询问数据状态的问题,线程在发出信号监控后立即返回(非阻塞),因此,一个线程也可以同时监控多个 fd。

信号驱动 IO 也可以看成是一种异步非阻塞 IO。

在内核进行数据准备期间,程序进程(线程)不阻塞。但是,当程序进程(线程)将数据从内核空间拷贝到用户空间期间,是阻塞的。这是它和异步 IO 的本质区别。

异步 IO 模型

可以发现,不管是 IO 复用还是信号驱动 IO,要读取数据需发起两次请求,第一次发起判断数据就绪状态的请求第二次发起 recvfrom 读取数据的请求

为什么我们明明是想读取数据,却非要先发起一个判断数据状态的请求,然后再发起真正的读取请求。有没有一种方法,只需发送一个请求告诉内核我要读取数据,就什么都不管,由内核去帮我完成所有的事情。

于是,异步 IO 模型便诞生了。

异步 IO 模型是指程序 B 向内核发送一个 IO 请求(比如 read),告知内核我要读取数据,便立即返回;内核收到请求后会与之建立一个信号联系,当数据准备就绪,内核会主动把数据从内核空间复制到用户空间。所有操作完成之后,内核会发送一个完成通知告知 B。

异步 IO 模型做到了真正的非阻塞。

异步 IO 模型与信号驱动 IO 模型的主要区别在于,信号驱动 IO 只是让内核通知我们何时可以开始下一个 IO 操作,而异步 IO 模型是让内核通知我们操作什么时候完成。

此模型和前 4 个模型最大的区别是:前 4 个模型从内核空间拷贝数据到用户空间这一过程,必须由程序自身来进行,必然是阻塞的。
而异步 IO 模型在内核准备数据数据从内核空间拷贝到用户空间这两个过程都不用等待,完全非阻塞。

用户进程(线程)完全不需要关心实际的整个 IO 操作是如何进行的,只需先发起一个请求,当收到内核返回的成功信号时,所有的 IO 操作都已完成。它是最理想的模型。

五种 IO 模型的对比

  • 阻塞 IO:在数据准备阶段和数据拷贝阶段,都会阻塞。
  • 非阻塞 IO:在数据准备阶段,非阻塞;但在数据拷贝阶段阻塞。
  • IO 复用:在数据准备阶段,采用复用器轮询遍历多个 fd,会阻塞;在数据拷贝阶段阻塞。但是,它用单一线程监听了多个连接,减少了线程资源的创建。
  • 信号驱动 IO:在数据准备阶段,注册一个信号处理函数,来接收内核准备数据的结果信号,实现非阻塞;在数据拷贝阶段阻塞。
  • 异步 IO:在数据准备阶段和数据拷贝阶段,都非阻塞。

IO 模型里的同步和异步

我们常常可以听到同步阻塞 IO、同步非阻塞 IO、异步 IO。

应用程序发起读取数据请求,若数据还没准备就绪,需要等待就是阻塞;反之,若立即返回就是非阻塞。

那么,这里的同步和异步怎么理解呢?

同步:是指应用程序发起 IO 请求,从发起请求到请求最终完成,整个过程都需要参与其中(与内核进行交互)。

异步:是指应用程序发起 IO 请求之后,就不再参与后续的具体过程,接收最终完成结果的通知由回调实现。

为什么只有异步非阻塞而没有异步阻塞?因为异步 IO 模型下,程序发送完请求指令后就立即返回了,没有任何后续流程。因此,它注定不会阻塞,也就只会有异步非阻塞。

阻塞必然同步,同步不一定阻塞。

相关文章:

五种 IO 模型

文章目录操作系统和内存内核空间和用户空间应用程序的内核态和用户态网络 IO 和磁盘 IO简易的网络通信流程阻塞和非阻塞阻塞 IO 模型非阻塞 IO 模型IO 复用模型SelectPollEpoll小结信号驱动 IO 模型异步 IO 模型五种 IO 模型的对比IO 模型里的同步和异步5种 IO 模型分别是&…...

34-Golang中的结构体!!!

Golang中的结构体结构体和结构体变量(实例)的区别和联系结构体变量(实例)在内存中的布局如何声明结构体字段/属性注意事项和细节说明创建结构体实例的四种方式结构体使用细节结构体和结构体变量(实例)的区别和联系 1.结构体是自定义的数据类型,代表一类事物2.结构体…...

这6个视频剪辑素材库,你一定要知道~

推荐5个免费商用视频素材网站,建议收藏哦! 1、菜鸟图库 视频素材下载_mp4视频大全 - 菜鸟图库 网站素材量很大,有设计、图片、音频、视频等超多素材,大部分都能免费下载。视频素材都很高清,有自然、人物、科技、农业…...

RocketMQ WIN11 搭建

去官方下载 https://rocketmq.apache.org/zh/download/ 下载,博主下载的是 4.6.0 的版本,选择Binary版本 拓展 Source 下载:需要编译 Binary 下载:不需要编译 解压缩,运行 先解压缩环境变量中添加rocketMQ文件夹路…...

iPhone更换电池和屏幕后提醒非原厂配件的操作办法

---开局一张图,内容全靠编系列! 【图】 自从在iPhone系统iOS13开始支持原厂配件检测后,可以说苹果也动起了维修站商家利益的这块蛋糕。道理自然简单,卷嘛!全球汽车行业也不是靠卖新车才赚钱的,各种交通事故…...

chatGPT发布记录

发行说明(2 月 13 日)我们对 ChatGPT 进行了多项更新!这是新功能:我们更新了免费计划中 ChatGPT 模型的性能,以便为更多用户提供服务。根据用户反馈,我们现在默认让 Plus 用户使用更快的 ChatGPT 版本&…...

DataX及DataX-Web

大数据Hadoop之——数据同步工具DataX数据采集工具-DataX datax详细介绍及使用 一、概述 DataX 是阿里云DataWorks数据集成的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre、HDFS、…...

数据结构与算法系列之kmp算法

什么是kmp算法 1.kmp算法是一种改进的字符串算法,其核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数已达到快速匹配的目的。 它主要实现作用的是 在 (主串)中找到 (匹配)字符串。 例 BF算法与k…...

算法分析详解

自古老的公元前1世纪开始,《周髀算经》就作为中国最古老的天文学和数学著作。 《周髀算经》采用最简便可行的方法确定天文历法,揭示日月星辰的运行规律,包括四季更替,气候变化,南北有极,昼夜相推的道理。为…...

东南大学自然辩证法概论期末总结

写在前面 作者:夏日 博客地址:https://blog.csdn.net/zss192 本文为2022年东南大学自然辩证法概论期末总结,内容为根据老师所发题纲综合多个资料总结得来 考试形式:从老师所发题纲,10个题目中选出4个,题…...

《爆肝整理》保姆级系列教程python接口自动化(二十)--token登录(详解)

简介 为了验证用户登录情况以及减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。有些登录不是用 cookie 来验证的,是用 token 参数来判断是否登录。token 传参有两种一种是放在请求头里,本质上是跟 cookie 是一样的&…...

k8s种的kubectl命令

一.kubectl基本命令1.1 称述式资源管理的方法kubernetes集群管理集群资源的唯一入口是通过相应的方法调用apiserver的接口kubectl是官方的CLI命令行工具,用于与apiserver进行通信,将用户在命令行输入的命令,组织并转化为apiserver能识别的信息…...

数组(一)-- LeetCode[26][80] 删除有序数组中的重复元素

1 删除有序数组中的重复项 1.1 题目描述 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 由于在某些语言中不能改变数组的长度&#xff0c…...

GEE学习笔记 六十三:新的地图图层ui.Map.CloudStorageLayer

在GEE中导出数据有一种方式是直接导出地图到Google Cloud Storage中,也就是Export.map.toCloudStorage(xxx),这种方式是将我们计算生成影像导出成为静态瓦片的格式存放在Google Cloud Storage中。我们可以在其他的前端程序比如OpenLayer、Mapbox GL JS等…...

ClickHouse 语法详解

ClickHouse有2类解析器:完整SQL解析器(递归式解析器),以及数据格式解析器(快速流式解析器) 除了 INSERT 查询,其它情况下仅使用完整SQL解析器。 INSERT查询会同时使用2种解析器:INSE…...

手把手教你将微信小程序放到git上

背景 首先,要创建一个自己的git仓库,这里默认大家都能够自己创建了git仓库了。如果不会创建仓库的话,百度一下,很容易就能够创建了!(后续,如有不知道在哪里,怎么创建仓库的话&#…...

功能测试3年,回顾一路走来的艰辛

不论你是什么时候开始接触测试这个行业的,你首先听说的应该是功能测试。通过一些测试手段来验证开发做出的代码是否符合产品的需求?当然你也有自己对功能测试的理解,但是最近两年感觉功能测试好像不太受欢迎,同时不少同学真的是功…...

作为Linux C/C++程序员必备的工具

Linux系统 可以选择centOS或者ubautu server(不建议选择桌面版本的)。不建议裸机安装,玩坏了就特别麻烦。不建议使用有桌面版本的ubautu,在一定程度有桌面的版本的会消耗性能。 如果经济实力允许,可以购买云服务器。 参考文章: Ubuntu server…...

docker Alpine一个只有5M小而美的Docker镜像

docker Alpine一个只有5M小而美的Docker镜像 参考链接: Alpine 一个只有5M的Docker镜像 http://www.infoq.com/cn/news/2016/01/Alpine-Linux-5M-Docker?utm_sourcetuicool&utm_mediumreferral 使用alpinelinux 构建 golang http 启动了才15mb http://blog.csdn.net/fre…...

Springboot扩展点之InstantiationAwareBeanPostProcessor

Springboot扩展点系列实现方式、工作原理集合:Springboot扩展点之ApplicationContextInitializerSpringboot扩展点之BeanFactoryPostProcessorSpringboot扩展点之BeanDefinitionRegistryPostProcessorSpringboot扩展点之BeanPostProcessorSpringboot扩展点之Instant…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务&#xff0c;但是又不想花钱&#xff0c;所以就想着自己搭建一个&#xff0c;刚好我们用的一个开源框架已经集成了MinIO&#xff0c;所以就选了这个 我这边对文件服务性能要求不是太高&#xff0c;单机版就可以 安装非常简单&#xff0c;几个命令就…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...