【Linux高级IO(二)】初识epoll
目录
1、epoll的接口
2、epoll原理
3、epoll工作方式
1、epoll的接口
#include <sys/epoll.h>
1、int epoll_create(int size) :创建epoll模型
返回值是一个文件描述符,创建一个struct file结构体,指向epoll模型,返回的是在进程文件描述符表中的一个fd,通过这个fd就能找到epoll模型。
2、int epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
:监听文件描述符上的事件并返回就绪的事件列表
是在关联就绪队列
作用:事件等待:
epoll_wait
可以让程序在不使用忙等待的情况下,高效地等待多个文件描述符上的 I/O 事件。通过设置合适的timeout
参数,程序可以根据需求进行阻塞等待或非阻塞等待。事件收集:一旦有文件描述符就绪,epoll_wait
会将这些就绪事件的详细信息填充到events
数组中。events
数组的每个元素是一个struct epoll_event
结构体,包含了事件的类型(如EPOLLIN
表示可读,EPOLLOUT
表示可写)以及与之关联的数据(通常是文件描述符)。函数返回值表示就绪事件的数量,通过遍历events
数组,程序可以获取每个就绪文件描述符的具体信息,并进行相应的处理 。高效处理大量并发连接:在处理大量并发连接的场景中,如网络服务器,epoll_wait
的优势尤为明显。相比于传统的select
和poll
函数,epoll
使用了事件驱动的机制,采用红黑树和链表的数据结构,使得在处理大量文件描述符时,其时间复杂度为 O (1),而select
和poll
的时间复杂度为 O (n)。这意味着epoll_wait
可以更高效地处理大量并发连接,减少 CPU 资源的消耗。第一个参数:epoll_create 的返回值
第二个:它是一个指向
struct epoll_event
结构体数组的指针。当epoll_wait
检测到有事件发生时,会将这些事件的相关信息填充到这个数组中。 每个struct epoll_event
结构体包含了事件的类型和与之关联的数据(通常是文件描述符)第三个:
events
数组的最大长度,也就是epoll_wait
最多能返回的事件数量第四个:
- 当
timeout
为-1
时,epoll_wait
会一直阻塞,直到有事件发生才会返回。- 当
timeout
为0
时,epoll_wait
会立即返回,即使没有事件发生。- 当
timeout
为一个正整数时,epoll_wait
会在该时间内阻塞等待事件发生,如果在超时时间内没有事件发生,函数将返回0
。返回值:已经就绪的fd的个数
3、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
:新增一个文件描述符,及修改其要关心的事件
是在对红黑树增删改
第一个:epoll_create 的返回值
第二个:选项
第三、四个:哪个文件描述符,上的哪些事件
struct epoll_event结构:
struct epoll_event ev;
ev.events = event;
ev.data.fd = sock;
n = epoll_ctl(_epfd,oper,sock,&ev);
event可以使用几个宏的集合:
2、epoll原理
OS在硬件层面,怎么知道网卡上有数据呢? 硬件中断
1、在内部维护一颗红黑树
struct rb_node
{
int fd;//内核要关心的fduint32_t event;// 要关心的事件
//链接字段
}
2、就绪队列(双链表)某个节点的事件就绪了,就将他链入就绪对列中。
struct list_node
{
int fd;//已经就绪的fduint32_t event; //已经就绪的事件
}
3、OS内部提供回调函数 底层网卡有数据就绪了,自动调用回调
1、向上交付 2、将数据交付给tcp的接收缓冲区 3、查找rb_tree, 看fd,并且看有没有关心EPOLLIN或者EPOLLOUT 4、如果有,构建就绪节点,插入到就绪队列中
用户只需要从就绪队列中获取就绪节点即可!!
上面三套就是epoll模型。
Epoller.hpp
#pragma once#include "nocopy.hpp"
#include <cerrno>
#include <sys/epoll.h>
#include <unistd.h>
#include <string.h>
#include "Log.hpp"class Epoller : public nocopy //类Epoller继承自nocopy类,类Epoller对象不能被拷贝和复值
{static const int size = 128;
public:Epoller(){_epfd = epoll_create(size); //创建epoll模型 返回一个文件描述符if(_epfd == -1){lg(Error,"epoll_create error: %s", strerror(errno));}else{lg(Info,"epoll_create success: %d", _epfd);}}int EpollerWait(struct epoll_event revents[], int num) //传一个数组和数组大小就ok{int n = epoll_wait(_epfd,revents, num, _timeout);//等待epoll实例_epfd上的事件发生,将发生的事件存储在revents数组中,//最多存储num个事件 ,超时事件为_timeout毫秒 返回事件发生的数量//---解释---第二个参数是指向结构体数组的指针 当检测到有事件发生时,就会将事件的信息:fd、事件类型填充到结构体中return n;}int EpollerUpdate(int oper,int sock,uint32_t event) //修改epoll实例上的文件描述符的监听事件{int n = 0;if(oper == EPOLL_CTL_DEL){n = epoll_ctl(_epfd, oper, sock, nullptr);//从epoll实例中删除指定文件描述符sockif(n != 0){lg(Error, "epoll_ctl delete error!");}}else{struct epoll_event ev;ev.events = event;ev.data.fd = sock;n = epoll_ctl(_epfd,oper,sock,&ev);//通过新增调用 向红黑树中新增节点 让节点和底层队列产生关联if(n != 0){lg(Error, "epoll_ctl error!");}}return 0;}~Epoller(){if(_epfd >= 0)close(_epfd);}
private:int _epfd;int _timeout{3000};
};
EpollerServer.hpp
#pragma once#include <iostream>
#include <sys/epoll.h>
#include <unistd.h>
#include <memory>
#include "Socket.hpp"
#include "Epoller.hpp"
#include "Log.hpp"
#include "nocopy.hpp"uint32_t EVENT_IN = (EPOLLIN);
uint32_t EVENT_OUT = (EPOLLOUT);class EpollServer : public nocopy
{static const int num = 64;
public:EpollServer(uint16_t port):_port(port),_listsocket_ptr(new Sock()), _epller_ptr(new Epoller()){}void Init(){_listsocket_ptr->Socket();//创建套接字_listsocket_ptr->Bind(_port);//将套接字绑定到指定的端口_listsocket_ptr->Listen();//将套接字设置为监听状态lg(Info, "create listen socket success: %d\n", _listsocket_ptr->Fd());}void Accepter() //处理新的客户端连接{//获取新连接std::string clientip;uint16_t clientport;int sock = _listsocket_ptr->Accept(&clientip,&clientport);if(sock > 0){//不需要阻塞 因为这些是已经就绪的//但是不能立马读 建立连接了并不代表有数据//这个文件描述符上到底有没有新数据到来,只有epoll最清楚_epller_ptr->EpollerUpdate(EPOLL_CTL_ADD, sock, EVENT_IN);}}void Recver(int fd){char buffer[1024];ssize_t n = read(fd, buffer, sizeof(buffer) -1);if(n > 0)//读取成功{buffer[n] = 0; //在缓冲区末尾加字符串结束符std::cout << "get a message:" << buffer << std::endl;//writestd::string echo_str = "server echo $";echo_str += buffer;write(fd,echo_str.c_str(), echo_str.size());}else if(n == 0) //读取长度为0,客户端已经将连接关闭了{_epller_ptr->EpollerUpdate(EPOLL_CTL_DEL,fd,0);//从epoll中移除时必须保证这是一个合法的文件描述符 所以先移除再关close(fd); }else{_epller_ptr->EpollerUpdate(EPOLL_CTL_DEL,fd,0);//从epoll中移除时必须保证这是一个合法的文件描述符 所以先移除再关close(fd); }}void Dispatcher(struct epoll_event revs[], int num) //传入的是所有已经就绪的文件描述符和对应的事件{for(int i = 0; i < num; i++){uint32_t events = revs[i].events;int fd = revs[i].data.fd; //拿到是哪个文件描述符就绪了if(events & EVENT_IN) //当前事件是可读事件{//将监听套接字的文件描述符添加到 epoll 实例中,并关注其可读事件(EPOLLIN)。//当有新的客户端连接请求到达时,监听套接字就会变得可读,//epoll 会检测到这个事件并将其作为就绪事件返回给服务器if(fd == _listsocket_ptr->Fd())//当前文件描述符是监听套接字的描述符,表示有新的客户端连接请求{//服务器根据文件描述符判断是监听套接字可读是,就知道有新连接到来//当有新连接到来,监听套接字就会变的可读,epoll就会检测到监听套接字上的可读事件,并将其作为一个就绪事件返回给服务器Accepter(); //处理新的客户端连接}else //普通客户端套接字有数据可读{//其他fd上面的普通读取事件就绪Recver(fd); //处理客户端发送的数据}}}}void Start(){//将listensock添加到epoll中, 就是listensock和他关心的事件,添加到内核epoll模型中的rb_tree(红黑树)中_epller_ptr->EpollerUpdate(EPOLL_CTL_ADD, _listsocket_ptr->Fd(), EVENT_IN);//要让epoll去等listen套接字 要让套接字增多//epoll只负责在IO模型中进行等待//---解释---调用Epoller类的EpollerUpdate方法,将监听套接字添加到epoll实例中,并关注可读事件struct epoll_event revs[num];//---解释---存储epoll_wait函数返回的就绪事件for(;;){int n = _epller_ptr->EpollerWait(revs, num); //不断调用epoll_wait函数等待事件发生if(n > 0){//有事件就绪Dispatcher(revs,n); //事件派发}else if(n == 0){lg(Info, "time out ...");}else{lg(Error, "epll wait error");}}}~EpollServer(){_listsocket_ptr->Close(); }
private:std::shared_ptr<Sock> _listsocket_ptr;std::shared_ptr<Epoller> _epller_ptr;uint16_t _port;
};
3、epoll工作方式
LT:水平触发Level Triggered
ET:边缘触发Edge Triggered : 数据/连接,从无到有,从有到多,变化的时候,才会通知我们一次。
epoll默认模式:LT模式(有事件到来,上层不取走,就一直通知你)
ET的通知效率高。不仅如此,ET的IO效率也更高。
边缘触发会倒逼程序员,在每次通知的时候把数据全取走,循环读取,直到读取出错。所有的fd必须是非阻塞的。当读取不成功就会出错,而不是一直阻塞等待。(面试题) 这意味着tcp会向对方通告一个更大的窗口,从而从概率上让对方一次给我发送更多的数据!!
其实LT也可以将所有的fd设置成为non_block,然后循环读取。在通知第一次的时候,就全部读取,不就和ET一样了。
向就绪队列里添加一次,还是一直添加(这就是ET和LT的区别)
上面的代码存在问题:read如何保证一次读完完整的报文。 没读完的数据在缓冲区中,如果想着下一次再去读,缓冲区已经被清空或者覆盖了。
下一节代码Reactor解决这个问题
相关文章:
【Linux高级IO(二)】初识epoll
目录 1、epoll的接口 2、epoll原理 3、epoll工作方式 1、epoll的接口 #include <sys/epoll.h> 1、int epoll_create(int size) :创建epoll模型 返回值是一个文件描述符,创建一个struct file结构体,指向epoll模型,返回的…...
2018年真题
数学基础 一、 (共4分)用逻辑符号表达下列语句(论域为包含一切事物的集合) 1、(2分)集合A的任一元素的元素都是A的元素 经过对图片文字的识别与逻辑分析,结果如下: 符号定义&…...
Linux xxd命令
目录 一. xxd命令简介二. 简单使用三. -p选项纯16进制输出四. -r选项将十六进制还原成原始内容五. 小应用 一. xxd命令简介 xxd 是一个将文件或输入内容转换为十六进制(Hex Dump)格式的工具,也可以将十六进制恢复成原始数据。 它在调试二进制…...
高校实验室安全数智化分级分类管理-危化品管理LIMS
一、背景与依据 传统实验室安全管理如同老式挂钟,齿轮咬合处总会随时间产生间隙。为进一步规范学校实验室建设与适用,从源头管控实验室和实验项目安全风险,确保教学科研活动安全有序开展,分级分类体系构建如同绘制实验室的"…...
春芽儿智能跳绳:以创新技术引领运动健康新潮流
在全球运动健康产业蓬勃发展的浪潮中,智能健身器材正成为连接科技与生活的重要纽带。据《中国体育用品产业发展报告》显示,2023年中国智能运动装备市场规模突破千亿元,其中跳绳类目因兼具大众普及性与技术升级空间,年均增速超30%。…...
Fast网络速度测试工具
目录 网站简介 功能特点 测试过程 为什么使用Fast 如果网络速度不达标 网站简介 Fast是一个由Netflix提供的网络速度测试工具,主要用来测试用户的互联网下载速度。它以其简洁的界面和快速的测试过程而受到用户的欢迎。 功能特点 下载速度测试:这是…...
java的文件输入输出流(FileInputStream、FileOutputStream、FileReader、FileWriter)
文章目录 文件输入输出流1 java I/O 流的原理流的分类 2 FileInputStream 文件字节输入流3 FileOutputStream 文件字节输出流4 使用文件字节输入输出流完成对文件的拷贝5 FileReader 文件字符输入流6 FileWriter 文件字符输出流 文件输入输出流 1 java I/O 流的原理 I/O 是 In…...
stm32week10
stm32学习 七.CAN 7.STM32 CAN外设 标识符过滤器: 每个过滤器的核心由两个32位寄存器组成:R1[31:0]和R2[31:0] FSCx:位宽设置,置0为16位,置1为32位 FBMx:模式设置,置0为屏蔽模式,…...
【UnityEditor扩展】如何在 Unity 中创建棱柱体(用作VR安全区检测),同时在编辑器插件中实现与撤销/恢复功能
Unity 编辑器扩展:3D 空间中绘制安全区棱柱体(含撤销/恢复/保存/读取) 在虚拟现实(VR)和增强现实(AR)开发中,安全区是保障用户安全的重要组成部分。通过精确控制用户活动范围&#…...
C++小游戏 合集
生化危机 #include<conio.h> #include<string.h> #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<direct.h> int n,round,gold0; bool f1,f2,f3,deadfalse,PC_64Bit; char str[4]; struct n…...
常州 d??
回来了! 今天(?发出来的时候可能已经是第二天了吧 真的爆零了qaq 挺难的 最高分只有100 而且t2t3t4一个人都没拿分qaq 这段时间在写网络流 唉博客还是不要写太水了 抄一点网络流代码上来 EK不写了 dinic会就行了 板子题洛谷p3376 dini…...
juc并发包的常用类、线程安全实现方式、锁机制及 JVM 优化策略
juc并发包的常用类、线程安全实现方式、锁机制及 JVM 优化策略 1. juc包下的常用类:线程池:并发集合类:同步工具类:原子类: 2. 怎么保证多线程安全:3. Java中常用锁及使用场景:4. 线程同步的方法…...
学习日记-0407(Inductive Matrix Completion Using Graph Autoencoder)
论文阅读:Inductive Matrix Completion Using Graph Autoencoder 代码:swtheing/IMC-GAE 总而言之就是设计了一个不同评分下的邻接图,然后对每一个评分图T进行独立GNN编码。这个 GNN 编码器主要由三个组件构成:嵌入层、消息传递层…...
FPGA入门:状态机思想编程
一、状态机思想编写流水灯 1、状态机思想的概念 状态机思想是一种用于描述和处理具有多个状态以及状态之间转换关系的系统的思维方式。以下是对其主要概念、应用场景和优势的介绍: 主要概念 状态:指系统在某一时刻的状况或条件。例如,在一…...
【电路笔记】-切换触发器
切换触发器 文章目录 切换触发器1、概述2、切换触发器3、JK触发器转换为D型触发器4、D型触发器转换为切换触发器切换触发器是常用的时序逻辑电路,作为单个比特双稳态存储元件,在计数器、存储器设备中经常使用,或作为响应时钟脉冲的分频器。 1、概述 切换触发器是另一种基于…...
示例项目文档模板集:TaskBoard 任务管理系统
一套完整、高可读性、结构清晰的项目文档模板,适用于中小型软件项目的设计、开发、交接与展示全流程。 📌 项目概述文档(overview.md) 📂 项目名称:TaskBoard 🧭 项目简介 TaskBoard 是一款专为敏捷团队打造的任务管理系统,支持任务分配、状态追踪与协作沟通,帮…...
TF-IDF忽略词序问题思考
自从开始做自然语言处理的业务,TF-IDF就是使用很频繁的文本特征技术,他的优点很多,比如:容易理解,不需要训练,提取效果好,可以给予大规模数据使用,总之用的很顺手,但是人…...
代理模式的优缺点是什么?
什么是代理模式? 代理模式(Proxy Pattern)是一种结构型设计模式,它通过创建代理对象来控制对原始对象的访问。 这种模式在前端开发中广泛应用,特别是在需要控制对象访问、添加额外逻辑或优化性能的场景中。 核心…...
十分钟上手:Distilling the Knowledge in a Neural Network
概述:知识蒸馏是一种模型压缩技术,通过让轻量化的学生模型模仿复杂教师模型的输出概率分布,结合软目标和硬目标进行训练,从而将教师模型的泛化能力迁移至学生模型,实现小模型的高效部署而不显著降低性能。 硬目标&…...
百度的deepseek与硅基模型的差距。
问题: 已经下载速度8兆每秒,请问下载30G的文件需要多长时间? 关于这个问题。百度的回答如下: 30GB文件下载时间计算 理论计算(基于十进制单位): 单位换算 文件大小:3…...
OpenCV 图形API(18)用于执行两个矩阵(或数组)的逐元素减法操作函数sub()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 描述 计算两个矩阵之间的逐元素差值。 sub 函数计算两个矩阵之间的差值,要求这两个矩阵具有相同的尺寸和通道数: dst ( I ) src…...
布谷一对一直播源码android版环境配置流程及功能明细
一:举例布谷交友(一对一直播源码)搭建部署的基本环境说明 1. 首先安装Center OS 7.9系统,硬盘最低 40G 2. 安装宝塔环境 https://bt.cn(强烈推荐使用) 3. 安装环境 ● PHP 7.3(安装redis扩展…...
#MongoDB 快速上手
docker pull mongo docker run -d --name my-mongo -p 27017:27017 mongo docker exec -it my-mongo mongo 🚪进入 Mongo Shell 后的第一步 你进入后会看到类似提示符: >说明已经进入 Mongo Shell,现在就可以操作数据库了。 …...
docker相关命令
常用命令 #创建并启动 docker-compose up -d # 启动之后就可以通过浏览器访问了 #停止并删除 docker-compose down #重启 docker-compose restart #停止 docker-compose stop #启动 docker-compose startdocker search #搜索镜像(只搜索官方仓库的,官方仓库地址&am…...
浅谈进程与程序的区别
如大家所了解的,进程与程序是有区别的。 下面做了一个总结,供大家参考、学习: 1. 程序是指令的有序集合,是一个静态的概念,其本身没有任何运行的含义。进程是程序在 CPU 上的一次执行过程,是一个动态的概…...
redis 和 MongoDB都可以存储键值对,并且值可以是复杂json,用完整例子分别展示说明两者在存储json键值对上的使用对比
Redis 存储 JSON 键值对示例 存储操作: // 存储用户信息(键:user:1001,值:JSON对象) SET user:1001 {"name":"Alice", "age":30, "address":"New York&quo…...
基于chatgpt得到的生活成本计算
意大利的生活成本因城市而异,比如米兰和罗马相对较贵,而南部城市如那不勒斯或巴勒莫则便宜一些。下面是意大利大致的基本生活成本和费用明细(以欧元€为单位,2025年初数据为基础,具体数值可能随时间和汇率略有变化&…...
C和C++有什么区别?
C和C是两种不同的编程语言,虽然它们有许多相似之处,但也存在一些关键的区别。 C是一种过程化编程语言,专注于函数和流程控制,非常适合系统级编程。而 C是一种面向对象编程语言,支持类、对象和封装、继承、多态等特性。…...
力扣1338 === 贪心算法解决数组减半问题
目录 问题分析 方法思路:贪心算法 步骤分解 代码解释 复杂度分析 正确性证明 示例验证 边界情况 总结 要解决这个问题,我们需要找到最少需要删除的不同整数集合,使得剩余的元素个数不超过原数组的一半。以下是对该问题的详细分析和解…...
企业知识库如何搭建?应对高频咨询的AI自助问答系统
在客户服务和内部沟通中,“同样的问题被反复问”、“信息找不到”、“新员工上手慢”等现象屡见不鲜。为了提升企业运营效率,越来越多企业开始重视知识库建设,而“企业知识库如何搭建”也成为热门话题。 尤其在AI技术快速发展的今天…...
UE5学习笔记 FPS游戏制作44 统一UI大小 sizeBox
如果我们希望多个类似的UI大小一样,例如不同菜单的标题,可以使用sizeBox组件 我们在标题控件上,用sizeBox包裹所有子物体 然后指定他的最小宽高,或最大宽高 如果指定的是最小宽高,当子元素(如图片…...
SpringAOP新链浅析
前言 在复现CCSSSC软件攻防赛的时候发现需要打SpringAOP链子,于是跟着前人的文章自己动手调试了一下 参考了大佬的文章 https://gsbp0.github.io/post/springaop/#%E6%B5%81%E7%A8%8B https://mp.weixin.qq.com/s/oQ1mFohc332v8U1yA7RaMQ 正文 依赖于Spring-AO…...
高效网页截图利器:支持长截图、异步加载内容截图、API调用、Docker一键部署!
一、简介 利用playwright自动化工具,模拟浏览器打开网页,实现完整网页截图功能支持长截图,支持异步加载动态渲染内容截图支持docker一键部署支持API调用项目地址:https://github.com/luler/hello_screenshot 二、安装 提前安装好d…...
处理语言模型返回的响应
completion.choices[0].message.content 是在处理语言模型(如 OpenAI 的 GPT 系列)返回的响应时,用于 访问模型生成的文本内容的代码路径。为了更好地理解它,我们需要先了解语言模型响应的结构。 1. 响应的结构 当使用语言模型&…...
Go语言类型捕获及内存大小判断
代码如下: 类型捕获可使用:reflect.TypeOf(),fmt.Printf在的%T。 内存大小判断:len(),unsafe.Sizeof。 package mainimport ("fmt""unsafe""reflect" )func main(){var i , j 1, 2f…...
Java 大视界 -- Java 大数据机器学习模型在智能客服多轮对话系统中的优化策略(179)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
CAS号:288574-78-7,Zinpyr-1可用作PET传感器
试剂描述: Zinpyr-1(ZP-1)是一种具细胞膜渗透性的荧光探针,选择性检测锌离子(Zn2)(Kd 0.7 0.1 nM)。一旦与金属离子复合,诱发荧光信号产生。活细胞内,Zinpyr…...
【JVM调优实战指南:从案例分析到性能优化】
一、JVM 调优核心原则 JVM 调优旨在平衡系统的吞吐量、延迟和内存使用。在进行 JVM 调优时,我们可以遵循以下原则: 先优化代码:优先排查业务逻辑中的内存泄漏、对象滥用等问题。优化代码不仅能从根本上解决性能问题,还能减少对 J…...
交换机转发原理 和 DNS服务
1. 收到报文后,将其转换为二进制,并记录在缓存当中 2. 根据二进制中的源 MAC 地址,与接收报文的接口,记录对应关系,在 MAC 地址表中,每个动态表项 300S 老化时间。 3. 判断 如果目的 MAC 是组播或广…...
强化学习Q-Learning:DQN
强化学习Q-Learning/DQN 本文是一篇学习笔记,主要参考李宏毅老师的强化学习课程。 目前主流的强化学习方法大致可以分为 policy-based 和 value-based 两大类。之前我们介绍的 policy gradient 策略梯度,就是 policy-based 的方法。本文要介绍的 Q-learn…...
OpenCv(七)——模板匹配、打包、图像的旋转
目录 一、模板匹配 模板匹配原理 1、单模板之间的匹配 (1)读取并显示待匹配的图片和模板图片 (2)模板匹配并绘制匹配位置的外接矩形 (3)显示最终的效果 2、模板与多个对象匹配,仅匹配当前…...
汽车售后诊断 ODX 和 OTX 对比分析报告
一、引言 在汽车行业不断发展的当下,汽车售后诊断技术对于保障车辆性能、维护车主权益以及提升汽车品牌服务质量起着至关重要的作用。随着汽车电子化程度的不断提高,售后诊断所涉及的数据和流程愈发复杂,这就促使行业需要更加标准化、高效化…...
关于图卷积
深入理解神经网络中的图卷积 一、为什么需要图卷积(动机) 在图结构中,比如: 社交网络(节点是人,边是朋友关系)分子结构(节点是原子,边是化学键)知识图谱&a…...
Meta LLaMA 4:对抗 GPT-4o 与 Claude 的开源王牌
2025 年 4 月,Meta 正式发布了 LLaMA 4 系列的首批两款模型。 这两款模型模型分别是:LLaMA 4 Scout 与 LLaMA 4 Maverick,均采用了 专家混合架构(Mixture-of-Experts, MoE)。 据 Meta 表示,这是首次有 …...
如何进行SQL调优
如何进行SQL调优 SQL 调优是优化数据库查询性能的过程,目的是减少查询的执行时间,提高数据库系统的整体效率。SQL 调优的技巧和方法可以针对不同的数据库管理系统(DBMS)有所不同,但基本的原则和步骤是相似的。以下是一…...
WAF防护规则配置技巧与企业级安全实践指南
面对日益复杂的Web应用攻击,WAF规则配置直接决定防护体系的有效性。本文深度解析规则优先级编排、误报消减策略、智能学习机制等17项关键技术,结合金融行业API攻击案例与Gartner最新防御框架,为企业提供可落地的WAF优化路径。 WAF规则引擎的…...
第16届蓝桥杯单片机模拟试题Ⅱ
试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //ds1302.c extern unsigned char time[3]; void w_ds1302(); void r_ds1302(); //iic.c float v_adc(unsigned char addr); //sys.c extern float light_v; extern float rb2_v; exte…...
机器学习——ROC曲线、PR曲线
一、ROC曲线简介 1.1 ROC曲线的构成 1.横轴(假正率,FPR): 表示负样本被错误分类为正的比例(越小越好) 2.纵轴(真正率,TPR,即召回率): 表示正样…...
Flutter之交互事件
目录: 1、点击事件标准案例1.1、效果图2.1、代码实现 1、点击事件标准案例 1.1、效果图 2.1、代码实现 class FavoriteWidget extends StatefulWidget {const FavoriteWidget({super.key});overrideState<FavoriteWidget> createState() > _FavoriteWidge…...
深入解析Spring Boot自动装配:原理、设计与最佳实践
引言 Spring Boot作为现代Java开发中的一股清流,凭借其简洁、快速和高效的特性,迅速赢得了广大开发者的青睐。而在Spring Boot的众多特性中,自动装载(Auto-configuration)无疑是最为耀眼的明珠之一。本文将深入剖析Sp…...