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

Epoll 的本质与原理:高性能网络编程的基石

Epoll 的本质与原理:高性能网络编程的基石

在当今高并发的网络应用中,如何高效地处理大量的并发连接是每个开发者都需要面对的关键问题。Linux 系统提供的 epoll 技术正是解决这一问题的利器,被广泛应用于 Nginx、Redis、Skynet 等高性能网络服务器中。本文将基于提供的资料,深入探讨 epoll 的本质、设计思路、原理与工作流程,帮助读者理解其高性能背后的奥秘。

一、从网卡接收数据说起

要理解 epoll 的作用,我们首先需要了解计算机是如何接收网络数据的。当网卡接收到来自网络的数据时,它并不会直接通知 CPU,而是通过 直接内存访问 (DMA) 技术将数据写入到内存中的特定区域。一旦数据写入完成,网卡会向 CPU 发送一个 中断信号,告知操作系统有新的数据到达。操作系统接收到中断信号后,会执行相应的 中断处理程序 来处理这些数据。中断处理程序会将网络数据从内核空间的环形缓冲区复制到对应 socket 的接收缓冲区中,并最终唤醒等待在该 socket 上的线程。

二、如何知道接收了数据?

正如前文所述,CPU 通过 中断 机制来感知硬件事件的发生。中断是一种允许硬件设备(如网卡、键盘等)通知 CPU 有事件需要处理的机制。当网卡接收到数据并写入内存后,会向 CPU 的特定引脚发送一个高电平信号,CPU 捕获到这个信号后,会暂停当前正在执行的任务,跳转到预先定义好的中断处理程序的入口地址执行相应的代码。对于网络数据接收而言,这个中断处理程序负责将数据放入 socket 的接收缓冲区。

三、线程阻塞为什么不占用 CPU 资源?

在网络编程中,我们常常使用 recvselectepoll 等系统调用来接收数据。这些方法在没有数据到达时通常会使线程进入 阻塞 状态。那么,阻塞的线程为什么不会占用宝贵的 CPU 资源呢?

这涉及到操作系统线程调度的机制。操作系统会将线程分为“运行”和“等待”等状态。当一个线程因为等待某个事件(例如,等待 socket 接收到数据)而进入阻塞状态时,操作系统会将其从 工作队列 移动到与该事件相关的 等待队列 中。CPU 只会轮流执行工作队列中的线程,因此,处于等待队列中的线程不会被 CPU 调度执行,从而不会占用 CPU 资源。当等待的事件发生时(例如,socket 接收到数据),操作系统会将相应的线程从等待队列重新放回工作队列,使其有机会被 CPU 调度执行。

四、内核接收网络数据全过程

现在,我们可以将上述知识点串联起来,描述在阻塞的 recv 调用下,内核接收网络数据的完整过程:

  1. 接收网络数据: 远端主机发送的数据包到达本机网卡。
  2. 写入内存: 网卡通过 DMA 技术将接收到的数据写入到内核空间的环形缓冲区中。
  3. 中断通知: 网卡向 CPU 发送中断信号,通知操作系统有新的数据到达。
  4. 执行中断程序: CPU 响应中断,执行网卡中断处理程序。
  5. 复制数据到 Socket 缓冲区: 中断处理程序将数据从内核空间的环形缓冲区复制到对应 socket 的接收缓冲区中。
  6. 唤醒线程: 中断处理程序检查该 socket 的等待队列,如果有等待的线程(例如,调用了 recv 的线程),则将其唤醒,重新放入工作队列。
  7. 用户程序读取数据: 被唤醒的线程继续执行,recv 系统调用返回,并将 socket 接收缓冲区中的数据复制到用户空间的缓冲区中。

在这个过程中,数据经历了三次拷贝:网卡到内核环形缓冲区(DMA,硬件完成)、内核环形缓冲区到 socket 接收缓冲区(内核完成)、socket 接收缓冲区到用户缓冲区(内核和用户程序共同完成)。

五、同时监视多个 Socket 的简单方法:Select

服务器端通常需要同时管理多个客户端连接,而 recv 只能监视单个 socket。为了解决这个问题,早期的解决方案是使用 select 系统调用。

select 的基本思路是:创建一个包含所有需要监视的 socket 的文件描述符集合 fds,然后调用 selectselect 会阻塞直到 fds 中的至少一个 socket 发生事件(例如,有数据可读)。当 select 返回后,程序需要遍历 fds,通过 FD_ISSET 宏判断哪些 socket 发生了事件,并进行相应的处理。

然而,select 存在一些明显的缺点:

  1. 效率低下: 每次调用 select 都需要将线程添加到所有被监视 socket 的等待队列中,并且在唤醒时需要从每个队列中移除。这涉及到两次遍历,并且每次都需要将整个 fds 列表传递给内核,开销较大。出于效率的考虑,select 能够监视的最大 socket 数量通常有限制(默认为 1024)。
  2. 需要再次遍历:select 返回时,程序并不知道具体哪些 socket 收到了数据,还需要遍历整个 fds 集合来找出就绪的 socket。

select 的低效之处在于将“维护等待队列”和“阻塞线程”两个步骤耦合在一起,直接在 socket 集合上进行等待。

六、Epoll 的设计思路

epoll 的出现正是为了解决 select 的这些缺点,提供一种更高效的方式来监视多个 socket。epoll 的核心思想在于引入了一个中间层 eventpoll 对象,作为 socket 和线程之间的中介。

epoll 主要通过以下两个关键措施来提高效率:

  1. 功能分离: epoll 将“维护等待队列”和“阻塞线程”的操作分离开来。它首先通过 epoll_create 创建一个 eventpoll 对象,然后使用 epoll_ctl 将需要监视的 socket 添加到这个 eventpoll 对象中。内核会将 eventpoll 添加到这些 socket 的等待队列中。最后,调用 epoll_wait 阻塞线程,等待 eventpoll 对象上有事件发生。这种分离避免了每次调用都进行添加和移除等待队列的操作。
  2. 就绪列表: epoll 在内核中维护一个“就绪列表”(rdlist),用于引用已经接收到数据的 socket。当某个被 epoll 监视的 socket 接收到数据时,中断处理程序会将该 socket 的引用添加到 eventpoll 对象的就绪列表中,而不会直接唤醒线程。当程序调用 epoll_wait 时,如果就绪列表不为空,epoll_wait 会直接返回就绪列表中的 socket,避免了像 select 那样需要遍历整个被监视的 socket 集合。

七、Epoll 的原理与工作流程

下面我们通过一个例子来详细讲解 epoll 的原理和工作流程:

  1. 创建 Epoll 对象: 当某个线程调用 epoll_create 方法时,内核会创建一个 eventpoll 对象。这个对象在内核中以文件描述符的形式存在,就像 socket 一样,它也有自己的等待队列。
  2. 维护监视列表: 创建 epoll 对象后,可以使用 epoll_ctl 系统调用来添加、修改或删除需要监视的 socket。例如,当添加 socket1、socket2 和 socket3 到 epoll 对象时,内核会将当前的 eventpoll 对象添加到这三个 socket 的等待队列中。
  3. 接收数据: 当被监视的 socket(例如,socket2 或 socket3)接收到数据时,网卡中断处理程序会将这些 socket 的引用添加到 eventpoll 对象的“就绪列表”(rdlist)中。注意,此时并不会直接操作等待在 epoll 对象上的线程。
  4. 阻塞和唤醒线程: 当程序执行到 epoll_wait 时,如果 eventpoll 对象的就绪列表(rdlist)已经引用了 socket,那么 epoll_wait 会立即返回,并将就绪列表中的 socket 信息返回给用户程序。如果就绪列表为空,那么内核会将调用 epoll_wait 的线程放入 eventpoll 对象的等待队列中,使其进入阻塞状态。只有当就绪列表不为空时,等待在 eventpoll 上的线程才会被唤醒。

八、Epoll 的实现细节

epoll 为了实现高效的监视和就绪通知,在内核中使用了复杂的数据结构和机制:

  1. eventpoll 结构体: 当调用 epoll_create 时,内核会创建一个 eventpoll 结构体的实例。这个结构体是 epoll 机制的核心,它通常包含以下关键成员:
    • 红黑树 (Red-Black Tree): 用于存储所有被 epoll 监视的文件描述符(sockets)。红黑树是一种自平衡的二叉搜索树,能够保证插入、删除和查找操作的时间复杂度为 O(log N),其中 N 是被监视的文件描述符数量。这使得 epoll_ctl 在添加、修改或删除监视的 socket 时能够高效地完成。每个节点通常会关联一个 epoll_event 结构体,用于存储该文件描述符关心的事件类型等信息。
    • 就绪链表 (Ready List): 用于存储已经就绪(例如,有数据可读或可写)的文件描述符。当被监视的 socket 接收到数据或者发生其他关注的事件时,内核会将该 socket 对应的 epoll_event 结构体添加到这个就绪链表中。这是一个双向链表,方便快速地添加和移除元素。
    • 等待队列 (Wait Queue): 每个 eventpoll 对象也有一个等待队列,用于存放调用 epoll_wait 而被阻塞的线程。当就绪链表不为空时,内核会唤醒这个等待队列上的线程。
  2. 事件通知机制: 当内核检测到被监视的文件描述符发生事件时(例如,通过中断处理程序),它不会立即唤醒等待的线程。而是将该文件描述符对应的事件信息添加到 eventpoll 结构体的就绪链表中。
  3. epoll_wait 的处理: 当用户程序调用 epoll_wait 时,内核首先会检查 eventpoll 结构体的就绪链表是否为空。
    • 如果就绪链表不为空,内核会将链表中的事件信息复制到用户空间的数组中,并返回就绪事件的数量。
    • 如果就绪链表为空,那么内核会将当前调用 epoll_wait 的线程放入 eventpoll 对象的等待队列中,使其进入睡眠状态。只有当有新的事件发生并添加到就绪链表时,或者等待超时,该线程才会被唤醒。
  4. 避免不必要的遍历:select 不同,epoll 在添加监视的文件描述符时,就已经将它们组织在了红黑树中。当事件发生时,内核只需要将发生事件的文件描述符添加到就绪链表中,而不需要遍历所有被监视的文件描述符来查找就绪的 socket。epoll_wait 也只需要检查就绪链表即可,避免了额外的遍历操作。

总而言之,epoll 的高效性得益于其内部使用的数据结构(红黑树和就绪链表)以及事件通知机制。红黑树用于高效地管理被监视的文件描述符,而就绪链表则用于快速地获取就绪的文件描述符,从而避免了像 select 那样在每次调用时都进行遍历的开销。这使得 epoll 在处理大量并发连接时能够保持很高的性能。

九、小结

相比于 selectepoll 通过功能分离和就绪列表等机制,显著提高了在高并发场景下的网络 I/O 性能。它避免了每次都遍历所有被监视 socket,并且只返回真正就绪的 socket,极大地提升了效率。这使得 epoll 成为构建高性能网络服务器的关键技术之一。

参考:这里

相关文章:

Epoll 的本质与原理:高性能网络编程的基石

Epoll 的本质与原理:高性能网络编程的基石 在当今高并发的网络应用中,如何高效地处理大量的并发连接是每个开发者都需要面对的关键问题。Linux 系统提供的 epoll 技术正是解决这一问题的利器,被广泛应用于 Nginx、Redis、Skynet 等高性能网络…...

Tesseract OCR技术初探(Python调用)

一、Tesseract OCR技术解析 1.1 核心架构与发展历程 Tesseract是由HP实验室于1985年研发的光学字符识别引擎,2005年由Google开源并持续维护至今。其核心技术经历了三个阶段演进: 传统模式(v3.x):基于特征匹配算法&a…...

黑盒测试的测试用例构成的八点要素

测试用例: 是为测试项目而设计的执行文档 作用: 防止漏测实施测试的标准 编写格式: 用例编号:项目 模块 编号用例标题:预期结果(测试点)模块/项目:所属项目或模块优先级:表示用例的重要程度或者影响力P0~p4(P0最高)前置条件:要执行此条用例&#xf…...

手撕string

目录 引言 1&#xff0c;成员变量 2&#xff0c;先建一个可以跑的 2_1&#xff0c;构造函数 2_2&#xff0c; 扩容函数reserve 2_3&#xff0c;push_back 2_4&#xff0c;append[ ] 2_5&#xff0c;operator << 2_6&#xff0c;测试一下&#xff0c;看猪跑 3&…...

12款星光闪光污迹艺术绘画效果Clip Studio Paint笔刷画笔+闪光纹理图片 Clip Studio Glitter Texture Brushes

这 12 种 Clip Studio 画笔 额外的闪光纹理包含闪光、污迹、星光和闪亮的斑点&#xff0c;为您的艺术增添额外的流行感。想想闪光胶&#xff0c;但已经长大了&#xff08;而且更好&#xff09;。想象一下&#xff1a;无论您是用微小的闪光还是厚实的微光涂鸦&#xff0c;都有适…...

5G_WiFi_CE_杂散测试

目录 一、规范要求 1、法规目录&#xff1a; 2、限值&#xff1a; &#xff08;1&#xff09;带外发射杂散 &#xff08;2&#xff09;带内发射杂散 &#xff08;3&#xff09;接收杂散 二、测试方法 1、带外发射杂散 &#xff08;1&#xff09;测试条件 &#xff08…...

蓝卓为中小制造企业注入数字化转型活力

随着劳动力成本上升,原材料价格上涨,企业生产成本逐年增加&#xff0c;市场竞争越来越激烈&#xff0c;传统的中小制造企业面临着巨大的压力。 通过数字化转型应对环境的变化已成为行业共识&#xff0c;在数字化的进程中&#xff0c;中小企业首要考虑生存问题&#xff0c;不能…...

集成 shardingsphere-jdbc 常见问题

一、报错内容 Caused by: org.apache.ibatis.executor.ExecutorException: Error preparing statement. Cause: org.apache.shardingsphere.infra.exception.kernel.metadata.TableNotFoundException: Table or view t_xxx does not exist. 解决 1、配置 !SHARDING rules:-…...

DeepSeek接入飞书多维表格,效率起飞!

今天教大家把DeepSeek接入飞书表格使用。 准备工作&#xff1a;安装并登录飞书&#xff1b;可以准备一些要处理的数据&#xff0c;确保数据格式正确&#xff0c;如 Excel、CSV 等&#xff0c;也可直接存储到飞书多维表格。 创建飞书多维表格&#xff1a;打开飞书&#xff0c;点…...

AI来了,新手如何着手学习软件开发?

AI时代新手学习软件开发的7步进化指南 &#xff08;附具体工具与避坑策略&#xff09; 一、建立“人机协作”学习观 AI是教练&#xff0c;不是替身 正确姿势&#xff1a;用AI辅助理解概念&#xff08;如让DeepSeek 、ChatGPT用生活案例解释递归&#xff09;&#xff0c;但坚持手…...

sqli-labs靶场 less5

文章目录 sqli-labs靶场less 5 报错注入 sqli-labs靶场 每道题都从以下模板讲解&#xff0c;并且每个步骤都有图片&#xff0c;清晰明了&#xff0c;便于复盘。 sql注入的基本步骤 注入点注入类型 字符型&#xff1a;判断闭合方式 &#xff08;‘、"、’、“”&#xf…...

AI基础02-图片数据采集

上篇文章我们学习了文本的数据采集&#xff0c;今天主要了解一下图片数据采集的方法。图片采集方法通常有网页采集和实时采集&#xff08;传感器采集&#xff09;两种。我们学习一下如何利用python 工具和笔记本计算机摄像头进行图片数据的实时采集。 1&#xff09;cv2库简介 …...

QT音乐播放器(1):数据库保存歌曲

实现功能&#xff1a;用数据库保存本地导入和在线搜索的歌曲记录 目录 一. 保存本地添加的歌曲 1. 使用QSettings &#xff08;1&#xff09;在构造函数中&#xff0c;创建对象。 &#xff08;2&#xff09;在导入音乐槽函数中&#xff0c;保存新添加的文件路径&#xff0c…...

Java面试黄金宝典22

1. 树的中序遍历&#xff0c;除了递归和栈还有什么实现方式 定义 Morris 遍历是一种用于二叉树遍历的算法&#xff0c;它利用树中大量空闲的空指针&#xff0c;在不使用额外栈空间和递归的情况下&#xff0c;完成树的遍历。通过建立临时的线索连接&#xff0c;使得可以按照中…...

英伟达GB300新宠:新型LPDDR5X SOCAMM内存

随着人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;和高性能计算&#xff08;HPC&#xff09;应用的快速发展&#xff0c;对于高效能、大容量且低延迟内存的需求日益增长。NVIDIA在其GB系列GPU中引入了不同的内存模块设计&#xff0c;以满足这些严格…...

验证Linux多进程时间片切换的程序

​​ 一、软件需求 在同时运行多个CPU密集型进程时&#xff0c;需采集以下统计信息&#xff1a; 当前运行在逻辑CPU上的进程ID每个进程的运行进度百分比 实验程序设计要求&#xff1a; 1. 命令行参数 参数说明示例值n并发进程数量3total总运行时长&#xff08;毫秒&…...

Linux学习笔记(应用篇四)

基于I.MX6ULL-MINI开发板 输入设备tslib库 输入设备 触摸屏 触摸屏设备是绝对位移设备可以上报绝对位移事件 触摸可分为单触摸和双触摸 BTN_TOUCH &#xff1a;按压触摸屏和松开会触发上报&#xff0c;滑动时不会 单触摸上报事件 ABS_X&#xff1a; X 轴绝对位移坐标值 ABS_Y…...

linux基本命令(1)--linux下的打包命令 -- tar 和gzip

tar 解压 &#xff0c;打包 语法&#xff1a;tar [主选项辅选项] 文件或者目录 使用该命令时&#xff0c;主选项是必须要有的&#xff0c;它告诉tar要做什么事情&#xff0c;辅选项是辅助使用的&#xff0c;可以选用。 主选项&#xff1a; c 创建新的档案文件。如果用户想备…...

【Linux内核系列】:文件ELF格式详解

&#x1f525; 本文专栏&#xff1a;Linux &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; “人生没有白走的路&#xff0c;你踩过的荆棘、蹚过的泥泞&#xff0c;都会在某一刻&#xff0c;变成你脚下的风。” ★★★ 本文前置…...

CubeMx ——新建工程

新建工程 选择芯片 设置主频 选择调试口 选择晶振口 设置 GPIO 输出 工程设置 LED 闪烁 /* USER CODE BEGIN WHILE */while (1){HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_10);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */...

使用postcss-px-to-viewport-8-plugin将页面转响应式

使用postcss-px-to-viewport-8-plugin将页面转响应式 背景 公司最近接了个项目&#xff0c;其中要求部分页面在移动端正常显示&#xff0c;第一方案是使用响应式&#xff0c;但是设计稿最后出的和Web端差别较大同时两端的功能不是完全对齐的&#xff0c;所以决定使用两个模块…...

Java---类与对象

类与对象 前言&#xff1a;一、面向对象二、类的定义1.类的定义格式2.访问修饰限定符 三、类的实例化四、this引用1.this引用2.this引用的原因 五、对象的构造和初始化1.初始化对象2.构造方法(1).构造方法的概念&#xff1a;(2).特性&#xff1a;(3).this调用:3.就地初始化4.默…...

告别桌面杂乱与充电焦虑,移速165W百变桌面充电站首发体验

告别桌面杂乱与充电焦虑&#xff0c;移速165W百变桌面充电站首发体验 哈喽小伙伴们好&#xff0c;我是Stark-C~ 先如今&#xff0c;家里的电子产品越来越多&#xff0c;手机、平板、电脑三件套已经是基础配置&#xff0c;还有相机、Switch、智能手表等&#xff0c;这些产品用…...

基于springboot+vue的农产品电商平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

dom0运行android_kernel: do_serror of panic----failed to stop secondary CPUs 0

问题描述&#xff1a; 从日志看出,dom0运行android_kernel&#xff0c;刚开始运行就会crash,引发panic 解决及其原因分析&#xff1a; 最终问题得到解决&#xff0c;发现是前期在调试汇编阶段代码时&#xff0c;增加了汇编打印的指令&#xff0c;注释掉这些指令,问题得到解决。…...

MySQL 语句

MySQL 语句教程博客 MySQL 是目前广泛应用的关系型数据库管理系统&#xff0c;本文将详细介绍 MySQL 中常用的 SQL 语句及其应用&#xff0c;内容主要涵盖以下部分&#xff1a; DDL&#xff08;数据定义语言&#xff09; DML&#xff08;数据操作语言&#xff09; DQL&#…...

MySQL General Log

MySQL General Log MySQL General Log General Log 的开启General Log 的用法log_output 参数 MySQL主从复制&#xff1a;https://blog.csdn.net/a18792721831/article/details/146117935 MySQL Binlog&#xff1a;https://blog.csdn.net/a18792721831/article/details/146606…...

自动关机监控器软件 - 您的电脑节能助手

## 自动关机监控器 - 您的电脑节能助手 自动关机监控器是一款基于Python开发的实用工具&#xff0c;旨在帮助用户节省电力资源并延长电脑使用寿命。该程序通过监控用户的鼠标和键盘活动&#xff0c;在设定的无活动时间后自动关闭计算机&#xff0c;特别适合需要长时间离开电脑但…...

基于改进粒子群算法的多目标分布式电源选址定容规划(附带Matlab代码)

通过分析分布式电源对配电网的影响&#xff0c;以有功功率损耗、电压质量及分布式电源总容量为优化目标&#xff0c;基于模糊理论建立了分布式电源在配电网中选址定容的多目标优化模型&#xff0c;并提出了一种改进粒子群算法进行求解。在算例仿真中&#xff0c;基于IEEE-14标准…...

解锁健康密码:拥抱多元养生新方式

在追求高质量生活的当下&#xff0c;健康养生不再是一句空洞的口号&#xff0c;而是融入到日常生活的方方面面。它不仅关乎我们的身体健康&#xff0c;更与心理状态和生活品质息息相关。下面&#xff0c;就为大家介绍一些实用的养生知识&#xff0c;帮助大家开启健康生活之旅。…...

@Slf4j注解

Slf4j注解是Lombok库提供的一个注解&#xff0c;用于简化日志记录器的创建。使用该注解后&#xff0c;无需手动创建Logger实例&#xff0c;编译器会自动帮你完成这一步。以下是使用Slf4j注解打印日志的步骤和示例&#xff1a; 使用步骤 1. 引入依赖&#xff1a;在项目中引入SL…...

firewall-cmd添加访问规则

若要使用 **firewall-cmd** 允许 192.168.3.0/24 网段访问本地的 8088 端口&#xff0c;你可以按照以下步骤操作。 临时允许访问 如果你仅需临时允许该网段访问 8088 端口&#xff0c;可使用如下命令&#xff1a; firewall-cmd --add-rich-rulerule family"ipv4" …...

【Linux网络与网络编程】02.初识Socket编程

1. 数据传输的目的 前一篇文章中我们讲解了网络传输的流程&#xff0c;那么网络传输的目的是什么呢&#xff1f;难道我们只是将数据从一台主机传输到另一台主机吗&#xff1f; 当然不是的&#xff01;因为数据是给人用的。比如&#xff1a;聊天是人在聊天&#xff0c;下载是人…...

Python库()

1.概念 Matplotlib 库&#xff1a;是一款用于数据可视化的 Python 软件包&#xff0c;支持跨平台运行&#xff0c;它能够根据 NumPy ndarray 数组来绘制 2D 图像&#xff0c;它使用简单、代码清晰易懂 Matplotlib 图形组成&#xff1a; Figure&#xff1a;指整个图形&#xf…...

CVPR-2025 | 南洋理工基于图表示的具身导航统一框架!UniGoal:通用零样本目标导航方法

作者&#xff1a;Hang Yin 1 ^{1} 1, Xiuwei Xu 1 ^{1} 1, Linqing Zhao 1 ^{1} 1, Ziwei Wang 2 ^{2} 2, Jie Zhou 1 ^{1} 1, Jiwen Lu 1 ^{1} 1单位&#xff1a; 1 ^{1} 1南洋理工大学&#xff0c; 2 ^{2} 2清华大学论文标题&#xff1a;UniGoal: Towards Universal Zero-sho…...

Banner区域

div下 justify-content:space-between 左侧测导航left 在这里插入图片描述 在这里插入图片描述...

【C++】C++11介绍列表初始化右值引用和移动语义

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. C11简介2. 统一的列表初始化2.1&#xff5b;&#xff5d;初始化2.2 std::initializer_list 3. 声明3.1 auto3.2 decltype3.3 nullptr 4. 范围for循环4.1 范围for的语法4.2 范围for的使用条件 5. STL中一些变化6. 右…...

基于Spring Boot的高校普法系统的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

算法为舟 思想为楫:AI时代,创作何为?

在科技浪潮汹涌澎湃的当下,AI技术以前所未有的态势席卷各个领域,创作领域亦未能幸免。当生成式AI展现出在剧本撰写、诗歌创作、图像设计等方面的惊人能力时,人类创作者仿佛置身于文明演化的十字路口,迷茫与困惑交织,兴奋与担忧并存。在AI时代,创作究竟该何去何从?这不仅…...

GPT-4o 原生图像生成技术解析:从模型架构到吉卜力梦境的实现

最近不少 AI 爱好者、设计师、Vlogger 在社交平台晒出了 GPT-4o 生成的梦幻图像&#xff0c;尤其是吉卜力风格的作品——柔和光影、日系构图、治愈色彩、富有情感的角色表达&#xff0c;一下子击中了无数人的“童年回忆 审美舒适区”。 &#x1f3a8; 下面是一些 GPT-4o 实际生…...

无线通信技术(二):ITU、3GPP及传统波段对无线频谱的划分

本文介绍国际标准组织ITU、3GPP和传统波段对无线频谱的划分 。 一.ITU波段划分 国际电信联盟&#xff08;ITU&#xff09;将无线电频谱划分为多个频段&#xff0c;并根据频率范围和业务需求分配用途。 ITU对无线频谱的划分 带号频带名称频率范围波长范围波段名称典型应用…...

[Python学习日记-88] 并发编程之多进程 —— 队列与生产者消费者模型

[Python学习日记-88] 并发编程之多进程 —— 队列与生产者消费者模型 简介 队列 一、队列的介绍 二、队列的使用 生产者消费者模型 一、为什么要使用生产者消费者模型 二、什么是生产者消费者模型 三、生产者消费者模型的优势 四、生产者消费者模型的实现 JoinableQ…...

Vue学习笔记集--computed

computed 在 Vue 3 的 Composition API 中&#xff0c;computed 用于定义响应式计算属性 它的核心特性是自动追踪依赖、缓存计算结果&#xff08;依赖未变化时不会重新计算&#xff09; 基本用法 1. 定义只读计算属性 import { ref, computed } from vue;const count ref(…...

python之多线程,多进程理解

目录 一,什么是多线程多进程 1,1 多线程 1.2 多进程 二,多线程 2.1 使用threading模块 三,多进程 3.1 使用multiprocessing模块 3.2 多进程的优势 3.3 进程间的通信 四,如何选择多进程还是多线程 五,异步编程的替代方案(协程) 在开发过程中&#xff0c;提升程序的并…...

3月29日星期六今日早报简报微语报早读

3月29日星期六&#xff0c;农历三月初一&#xff0c;早报#微语早读。 1、全国公立医疗机构自3月31日起全面停止收取门诊预交金&#xff1b; 2、永辉超市“胖东来调改店”已达47家店 一线员工薪酬涨幅50%以上&#xff1b; 3、两孩家庭补10万&#xff0c;三孩家庭补20万&#…...

栈:隐匿于计算机科学长卷的璀璨明珠

目录 &#x1f680;前言&#x1f31f;栈的概念&#x1f914;栈的两种实现形式&#x1f4af;数组栈实现&#x1f4af;链表栈实现 ⚙️数组栈与链表栈对比&#x1f427;递归与栈&#x1f4bb;总结 &#x1f680;前言 大家好&#xff01;我是 EnigmaCoder。 在计算机科学的宏大版图…...

【万字总结】前端全方位性能优化指南(七)——按需加载、虚拟列表、状态管理

现代框架高阶优化——突破复杂场景的性能临界点 当Web应用进入「十万级组件、百万级数据」的复杂场景时,传统优化手段开始触及框架底层瓶颈:Redux的单一Store引发级联渲染风暴、全量加载的首屏资源阻塞关键交互、长列表滚动导致内存飙升直至页面崩溃……这些痛点正在倒逼框架…...

合并石子 | 第十四届蓝桥杯省赛JavaB组

在桌面从左至右横向摆放着 N 堆石子。 每一堆石子都有着相同的颜色&#xff0c;颜色可能是颜色 0&#xff0c;颜色 1 或者颜色 2 中的其中一种。 现在要对石子进行合并&#xff0c;规定每次只能选择位置相邻并且颜色相同的两堆石子进行合并。 合并后新堆的相对位置保持不变&…...

【商城实战(94)】构建高并发的负载均衡与集群架构

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…...

鸿蒙开发:了解Canvas绘制

前言 本文基于Api13 系统的组件无法满足我们的需求&#xff0c;这种情况下就不得不自己自定义组件&#xff0c;除了自定义组合组件&#xff0c;拓展组件&#xff0c;还有一种方式&#xff0c;那就是完全的自绘制组件&#xff0c;这种情况&#xff0c;常见的场景有&#xff0c;比…...