【NIO番外篇】之组件 Selector
目录
- 一、Selector:网络世界的“机场管制塔” / “总机接线员” 📡
- 什么是 Selector?
- 它的作用是什么?
- 二、Selector 的工作流程:塔台是怎么指挥飞机的?
- 1. 飞机就位 (准备 Channel):
- 2. 向塔台报到 (注册 Channel):
- 3. 登记凭证 (SelectionKey):
- 4. 塔台开始监控 (调用 select() ):
- 5. 处理就绪航班 (处理 selectedKeys):
- 6. 日复一日,年复一年 (循环):
- 上代码!模拟一个简单的回声服务器 📢
- 三、Selector 的常用“指令”小结:
🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解 Java NIO 请看 : NIO,看完你就懂了!
其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等
如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning
好的,各位旅客请注意,请各位旅客请注意!我们即将从 Buffer
缓冲垫站出发,前往下一站——Java NIO 的交通枢纽核心:Selector
选择器站!请系好安全带,准备体验用一个线程调度万千连接的神奇之旅!🚀
了解其他两个组件可以看:
Channel 组件:【NIO番外篇】之组件 Channel
Buffer 组件:【NIO番外篇】之组件 Buffer
一、Selector:网络世界的“机场管制塔” / “总机接线员” 📡
想象一下,你开了一家超火爆的在线服务(比如猫咪图片直播 🐱),成千上万的用户(Channels
)同时连接进来。如果按照老式做法(阻塞 IO),你得为每个连接都雇一个专属客服(线程)傻等着,用户不说话客服就摸鱼,但工资照发。很快,你的公司(服务器)就会因为人手过多(线程爆炸)而“人”满为患,效率低下,最终破产倒闭。😭
什么是 Selector?
Selector
就是 NIO 请来的 超级调度员!它允许你 用一个线程(一个敬业的管制塔操作员 🧑✈️ 或总机接线员 ☎️)来同时 监控多个通道(Channels) 的状态。哪个通道有“情况”(比如可以读数据了、可以写数据了、有新连接来了),Selector 就会告诉你。
它的作用是什么?
- I/O 多路复用 (Multiplexing):这是它的核心价值!它能让你用 一个单独的线程 管理成百上千的网络连接(Channels)。就像一个管制塔能同时监控空域里的所有飞机 ✈️,而不是每架飞机配一个专属塔台。
- 无敌的可伸缩性 (Scalability):因为它大大减少了所需的线程数量,服务器的资源消耗(内存、CPU 上下文切换开销)急剧下降。你的猫咪图片直播服务可以轻松应对海量用户,走向喵星球巅峰!📈
- 事件驱动 (Event-Driven):你的线程不再需要傻乎乎地挨个问“你好了没?你好了没?”(轮询),也不用死等一个连接(阻塞)。它只需要向 Selector 喊一声:“有情况了叫我!” (
select()
),然后就可以去泡杯咖啡 ☕️ 或者打个盹 😴 (线程等待)。当某个通道真的准备好了,Selector 就会像闹钟一样 🔔 把它叫醒。
二、Selector 的工作流程:塔台是怎么指挥飞机的?
想让 Selector 为你工作,得遵循一套“航空管制条例”:
1. 飞机就位 (准备 Channel):
- 只有
SelectableChannel
的子类(比如SocketChannel
,ServerSocketChannel
等)才能接受 Selector 的调度。 - 最最重要的一步:必须将 Channel 设置为非阻塞模式!
channel.configureBlocking(false);
。否则,管制塔的指令还没发出去,飞机自己就一头扎进云里(阻塞)了,还怎么调度?🤷♂️
2. 向塔台报到 (注册 Channel):
- 你需要告诉 Selector:“嗨,塔台,请帮我留意这架飞机(Channel)!”。使用
channel.register(selector, ops, [attachment]);
selector
: 你要注册到的那个 Selector 实例。ops
: 一个整数,表示你 关心 这架飞机(Channel)的哪些 事件(Interest Operations)。比如:SelectionKey.OP_READ
: 关心它是否可以读数据了 (飞机请求降落许可?)。SelectionKey.OP_WRITE
: 关心它是否可以写数据了 (飞机请求起飞许可?)。SelectionKey.OP_CONNECT
: 关心一个客户端SocketChannel
是否连接成功了 (飞机确认进入管制区?)。SelectionKey.OP_ACCEPT
: 关心一个服务器ServerSocketChannel
是否有新的连接进来了 (有新飞机请求进入空域?)。
你可以用位运算|
组合多个事件,比如OP_READ | OP_WRITE
。
[attachment]
(可选): 你可以给这次注册附加一个“行李牌”🏷️,比如一个包含会话信息或专属 Buffer 的对象,方便后续处理。- 返回值: 这次注册会返回一个
SelectionKey
对象,这是你的登记凭证。
3. 登记凭证 (SelectionKey):
- 每个
SelectionKey
代表了一个 Channel 在一个 Selector 上的注册记录。它像一张详细的“航班信息卡”,包含了:channel()
: 这是哪架飞机 (Channel)?selector()
: 它在哪个塔台 (Selector) 登记的?interestOps()
: 飞行员(你)关心 这架飞机哪些状态?(起飞?降落?)readyOps()
: 塔台(Selector)检测到 这架飞机 当前 已经 准备好 进行哪些操作了?(跑道已清空,可以降落!)这个状态由select()
调用更新。attachment()
: 之前附加的那个“行李牌”🏷️。
4. 塔台开始监控 (调用 select() ):
- 这是 Selector 的核心工作!你的管理线程会调用以下方法之一:
selector.select()
: 阻塞,直到至少有一个你关心的 Channel 准备好了相应的事件,或者其他线程调用了selector.wakeup()
,或者线程被中断。这是最常用的模式。(塔台操作员全神贯注盯着雷达,不等到有情况绝不离开岗位!💪)selector.select(long timeout)
: 最多阻塞timeout
毫秒。超时后即使没事件也会返回。(操作员盯一会儿,到点没情况就去喝口水 ☕️,然后再回来继续盯。)selector.selectNow()
: 非阻塞。立刻返回,不管有没有 Channel 准备好。(操作员快速扫一眼雷达,有情况就报,没情况就拉倒,继续干别的活。)
- 返回值: 这些方法返回一个整数,表示有多少个 Channel 的就绪状态发生了变化(有多少张
SelectionKey
的readyOps
被更新了)。如果是 0,表示没啥新情况。
5. 处理就绪航班 (处理 selectedKeys):
- 当
select()
返回值大于 0 时,说明有“情况”了!你需要:- 调用
selector.selectedKeys()
: 获取一个Set<SelectionKey>
,里面包含了所有当前已就绪的 Channel 的SelectionKey
。(拿到一份“需要立即处理的航班列表”🗒️。) - 遍历这个 Set 中的每一个
SelectionKey
。 - 对于每个
key
,检查它具体是哪个事件就绪了:key.isAcceptable()
: 是不是有新连接可以接受了? (新飞机来了?快引导!)key.isConnectable()
: 是不是连接成功了? (飞机已进入航线?)key.isReadable()
: 是不是可以读数据了? (乘客消息到了?快接收!)key.isWritable()
: 是不是可以写数据了? (有指令要发给飞机?快发送!)
- 根据就绪的事件,执行相应的 非阻塞 I/O 操作(比如
serverChannel.accept()
,socketChannel.read()
,socketChannel.write()
)。 - 最最最最关键的一步 (敲黑板 N 遍 칠판!!!):处理完一个
SelectionKey
后,必须手动将它从selectedKeys
集合中移除!iterator.remove();
或者selector.selectedKeys().remove(key);
。如果你不移除,下次select()
时它还会被包含在内,即使你已经处理过了,会导致你的程序像复读机一样重复处理同一个事件,造成死循环或逻辑混乱! (塔台处理完一架飞机的指令,必须把它从“待办”列表里划掉 ✅,否则会一直骚扰它!)
- 调用
6. 日复一日,年复一年 (循环):
- 上述的
select()
-> 获取selectedKeys
-> 遍历处理 -> 移除key
的过程,通常放在一个while(true)
循环里,让你的单线程调度员持续不断地为人民服务。
上代码!模拟一个简单的回声服务器 📢
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;public class SelectorEchoServer {private static final int PORT = 9999;private static final int BUFFER_SIZE = 1024;public static void main(String[] args) {System.out.println("启动 Selector 回声服务器在端口 " + PORT + " 📡");try (Selector selector = Selector.open(); // 打开“塔台”ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) // 打开服务器“机场”{serverSocketChannel.bind(new InetSocketAddress(PORT)); // 机场绑定地址和端口serverSocketChannel.configureBlocking(false); // 关键:机场设置为非阻塞模式!// 向塔台注册机场,只关心“新飞机抵达”事件 (OP_ACCEPT)serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("服务器机场已向塔台报到,等待新连接...");while (true) { // 开始塔台的 7x24 小时值班// 1. 等待事件发生(阻塞直到有情况)int readyChannels = selector.select(); // 等待雷达信号...if (readyChannels == 0) {// System.out.println("暂时无事发生..."); // select() 可能因 wakeup() 或超时返回0continue; // 继续下一轮监控}// 2. 获取就绪事件的列表 (拿到需要处理的航班列表)Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> keyIterator = selectedKeys.iterator();// 3. 遍历处理每个就绪事件while (keyIterator.hasNext()) {SelectionKey key = keyIterator.next();try {// --- 情况 A:有新飞机抵达 (isAcceptable) ---if (key.isAcceptable()) {System.out.println("🔔 检测到新连接请求!");ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();SocketChannel clientChannel = serverChannel.accept(); // 接受连接,得到代表客户端的通道clientChannel.configureBlocking(false); // 关键:新飞机也设置为非阻塞!// 将新客户端通道注册到同一个塔台,关心“可以读数据”事件// 并附加一个 ByteBuffer 作为它的专属“货舱”clientChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(BUFFER_SIZE));System.out.println("✅ 新客户端已连接并注册: " + clientChannel.getRemoteAddress());}// --- 情况 B:已连接的飞机发来消息 (isReadable) ---if (key.isReadable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = (ByteBuffer) key.attachment(); // 获取附加的“货舱”try {int bytesRead = clientChannel.read(buffer); // 从通道读数据到 Bufferif (bytesRead == -1) {// 客户端关闭了连接System.out.println("❌ 客户端断开连接: " + clientChannel.getRemoteAddress());key.cancel(); // 取消在塔台的注册clientChannel.close(); // 关闭通道} else if (bytesRead > 0) {System.out.println("📨 收到来自 " + clientChannel.getRemoteAddress() + " 的消息 (" + bytesRead + " bytes)");// 准备回写数据:将 Buffer 从写模式切换到读模式buffer.flip();// 将兴趣切换为 OP_WRITE,告诉塔台“我想发消息了”// 注意:这里直接修改 key 的 interestOpskey.interestOps(SelectionKey.OP_WRITE);}} catch (IOException e) {// 客户端强制关闭等异常System.err.println("⚠️ 读数据时连接异常: " + clientChannel.getRemoteAddress() + " - " + e.getMessage());key.cancel();clientChannel.close();}}// --- 情况 C:可以向飞机发送消息了 (isWritable) ---// 注意:通常 OP_WRITE 会在缓冲区有空间时一直触发,需要小心处理if (key.isWritable()) {SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = (ByteBuffer) key.attachment(); // 获取“货舱”try {System.out.println("📤 准备向 " + clientChannel.getRemoteAddress() + " 回写数据...");clientChannel.write(buffer); // 将 Buffer 中的数据写回给客户端if (!buffer.hasRemaining()) {// 数据全部写完了!System.out.println("✅ 数据已全部回写给 " + clientChannel.getRemoteAddress());// 清空 Buffer,准备下次读取buffer.clear();// 将兴趣切换回 OP_READ,告诉塔台“我又可以收消息了”key.interestOps(SelectionKey.OP_READ);}} catch (IOException e) {System.err.println("⚠️ 写数据时连接异常: " + clientChannel.getRemoteAddress() + " - " + e.getMessage());key.cancel();clientChannel.close();}}} catch (IOException e) {System.err.println("处理 Key 时发生 IO 异常: " + e.getMessage());// 尝试关闭出问题的 channelif (key.channel() instanceof SocketChannel) {try { ((SocketChannel)key.channel()).close();} catch (IOException ioex) {/* ignore */}}key.cancel(); // 从 selector 中移除} finally {// 4. 关键!关键!关键!处理完后从 selectedKeys 集合中移除当前 KeykeyIterator.remove(); // 划掉!搞定一个!✅}} // end of while(keyIterator.hasNext())} // end of while(true)} catch (IOException e) {System.err.println("服务器启动或运行出错: " + e.getMessage());e.printStackTrace();}}
}
运行这个代码,你可以用 telnet localhost 9999
连接上去,输入任何信息,服务器都会原样返回给你!这就是 Selector 的魔力,一个线程处理所有连接!
三、Selector 的常用“指令”小结:
Selector.open()
: 开门营业!建个新塔台。channel.configureBlocking(false)
: 飞机听指挥!必须非阻塞。channel.register(selector, ops, [attachment])
: 登记!告诉塔台你的需求。selector.select() / select(timeout) / selectNow()
: 监听!等待事件发生。selector.selectedKeys()
: 报告!获取就绪事件列表。key.isReadable/Writable/Acceptable/Connectable()
: 识别!判断具体是什么事件。key.channel() / key.attachment()
: 关联!获取对应的飞机和行李牌。key.interestOps(ops)
: 更新!改变你关心的事件。keyIterator.remove()
: 销账!处理完必须移除!(再说亿遍)key.cancel()
: 退役!从塔台注销。selector.wakeup()
: 叫醒!强制select()
返回。selector.close()
: 关门!关闭塔台。
Selector 的智慧:
用最少的人(线程),办最多的事(管理海量连接),这就是 Selector 的核心哲学——I/O 多路复用。掌握了它,你就掌握了构建高性能、高并发网络应用的钥匙🔑!
希望这个机场塔台的故事,能让你对 Selector 这个 NIO 的大总管有更生动、更深刻的理解!现在,你可以自豪地说:“Selector,你的调度逻辑我 get 到了!” 😎
相关文章:
【NIO番外篇】之组件 Selector
目录 一、Selector:网络世界的“机场管制塔” / “总机接线员” 📡什么是 Selector?它的作用是什么? 二、Selector 的工作流程:塔台是怎么指挥飞机的?1. 飞机就位 (准备 Channel):2. 向塔台报到…...
对接印度尼西亚股票数据源API
随着对东南亚市场的关注增加,获取印度尼西亚(IDX)股票市场的实时和历史数据变得尤为重要。本文将指导您如何使用Spring Boot框架对接一个假定的印尼股票数据源API(例如,StockTV),以便开发者能够…...
SQL(9):创建数据库,表,简单
1、创建数据库,一句SQL语句搞定 CREATE DATDBASE 数据库名 CREATE DATABASE my_db;2、创建表 CREATE TABLE 表名(字段名 类型) CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255)…...
医学成像中的对比语言-图像预训练模型(CLIP):一项综述|文献速递-深度学习医疗AI最新文献
Title 题目 CLIP in medical imaging: A survey 医学成像中的对比语言-图像预训练模型(CLIP):一项综述 01 文献速递介绍 尽管在过去十年中视觉智能领域取得了重大进展(何恺明等人,2016;塔尔瓦宁和瓦尔…...
KEGG注释脚本kofam2kegg.py--脚本010
采用kofam结合kegg官网htxt进行注释 用法: python kofam2kegg.py kofam.out ath00001.keg my_kegg_output code: import sys from collections import defaultdictdef parse_kofam_file(kofam_file):ko_to_genes defaultdict(list)with open(kofam_file) as f:…...
hevc编码芯片学习-VLSI实现
在Fan等工作中,根据特定算法设计了整像素运动估计引擎,最终的BD-Rate损失非常小,但是硬件开销比较大,搜索算法缺少灵活性,本次设计优化了硬件设计架构, 微代码 取像素 压缩 水平参考像素存储器 寻址控制 转…...
选导师原理
总述 一句话总结:是雷一定要避,好的一定要抢。方向契合最好,不契合适当取舍。 首先明确自身需求: 我要学东西!青年导师,好沟通,有冲劲,高压力。 我要摆烂!中老年男性教…...
2.5亿像素卷帘快门CMOS大幅面扫描相机
规格说明书 主要特征 ◎ 卷帘快门CMOS 传感器 ◎ 2.46 亿像素分辨率 ◎ 全分辨率最高帧率达5fps ◎ 高灵敏度及低噪声 ◎ ROI 区域设置 ◎ 曝光时间灵活控制(外触发,自由运行) ◎ 输出像素格式8/10/12bit 可选 ◎ 自动坏像素校正、平场校正…...
CD27.【C++ Dev】类和对象(18)友元和内部类
目录 1.友元 友元函数 几个特点 友元类 格式 代码示例 2.内部类(了解即可) 计算有内部类的类的大小 分析 注意:内部类不能直接定义 内部类是外部类的友元类 3.练习 承接CD21.【C Dev】类和对象(12) 流插入运算符的重载文章 1.友元 友元函数 在CD21.【C Dev】类和…...
企业级硬盘的测试流程
测试硬盘流程 找一个有Linux操作系统的服务器,配置好管理ip的接口,连接上linux服务器,执行lsblk命令来查看设备的情况 使用mkfs命令格式化要测试的硬盘,格式化之前务必把数据进行备份,可以使用blkid命令查看硬盘的文件…...
std::enable_shared_from_this 模板类的作用是什么?
我们以Connection类的shared智能指针为例说明,std::enable_shared_from_this<Connection> 是一个标准库模板类,它的作用是让一个类的对象能够安全地生成指向自身的 std::shared_ptr,即使该对象最初是通过普通指针或其他方式创建的。 作…...
鸿蒙开发-ArkUi控件使用
2.0控件-按钮 2.1.控件-文本框 Text(this.message).fontSize(40) // 设置文本的文字大小.fontWeight(FontWeight.Bolder) // 设置文本的粗细.fontColor(Color.Red) // 设置文本的颜色------------------------------------------------------------------------- //设置边框Tex…...
大数据学习栈记——MongoDB编程
本文介绍NoSQL技术:MongoDB用Java来连接数据库,执行常见的数据库操作,使用环境:IntelliJ IDEA、Ubuntu24.04。 配置Maven 我们需要使用“MongoDB Driver”,所以先打开“MongoDB Java Driver”项目,但是提…...
体系结构论文(六十七):A Machine-Learning-Guided Framework for Fault-Tolerant DNNs
A Machine-Learning-Guided Framework for Fault-Tolerant DNNs DATE 2024 研究动机 深度神经网络(DNN)虽然对某些扰动具有天然的容错性,但在面对硬件故障(如软错误、老化、环境干扰等)时,仍会出现输出错…...
qt designer 创建窗体选择哪种屏幕大小
1. 新建窗体时选择QVGA还是VGA 下面这个图展示了区别 这里我还是选择默认,因为没有特殊需求,只是在PC端使用...
游戏引擎学习第225天
只能说太难了 回顾当前的进度 我们正在进行一个完整游戏的开发,并在直播中同步推进。上周我们刚刚完成了过场动画系统的初步实现,把开场动画基本拼接完成,整体效果非常流畅。看到动画顺利呈现,令人十分满意,整个系统…...
sql工具怎么选最适合自己的?
sql工具怎么选? 为什么大多数主流工具又贵又难用?有没有一款免费好用的sql工具?像大多数朋友经常用的sql工具应该都遇到过这种情况,用着用着收到了来自品牌方的律师函,或者处理数据时经常卡死,再或者不支持…...
css实现一键换肤
实现一键换肤的时候,我们除了动态替换引用的css文件,还可以通过使用css变量的方式,达到所需效果。 首先我们来了解css变量,css变量以--开头,引用时va(--变量名),例 :root{--default-color: #fff; } .box{b…...
波束形成(BF)从算法仿真到工程源码实现-第八节-波束图
一、概述 本节对MVDR、LCMV、LMS等算法的波束图进行仿真。 二、MVDR代码仿真 2.1 mvdr代码 clc; clear; M 18; % 天线数 lambda 10; d lambda / 2; L 100; %快拍数 thetas [10]; % 期望信号入射角度 thetai [-30 30]; % 干扰入射角度 n [0:M-1]; vs exp(-1j * 2…...
静态代码深度扫描详解
静态代码深度扫描是一种通过分析源代码结构、语法、语义及潜在逻辑,在不运行程序的情况下全面检测代码缺陷、安全漏洞和质量问题的技术。它通过结合数据流分析、控制流分析、符号执行等高级技术,实现对代码的深度理解,帮助开发团队在早期发现…...
LC25. K 个一组翻转链表(自己用)
25. K 个一组翻转链表 Java代码: 思路:利用虚拟头节点结合反转链表实现 Code: class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode dummy new ListNode(0);if (head null || k 1)return head;ListNode…...
Spring事务同步器在金融系统中的应用:从风控计算到交易投递
一句话总结 通过 TransactionSynchronization 机制,成功将投行交易系统的可靠性提升至金融级要求,并在对公贷款风控中实现高效资源管理。未来,事务管理将不仅仅是“提交”与“回滚”的二元选择,而是向智能化、实时化演进的核心基础设施。 1. 架构设计 1.1 整体架构图 2.…...
sealos跳转到cusor安装出错
第一次打开cursor安装出错怎么办 我出现这个问题的解决方式是重新下载并且切换目录解决...
【CUDA 】第3章 CUDA执行模型——3.5循环展开(1)
CUDA C编程笔记 第三章 CUDA执行模型3.5 循环展开3.5.1 展开的规约 待解决的问题: 第三章 CUDA执行模型 3.5 循环展开 循环展开是一种循环优化的技术,通过减少分支出现频率循环维护指令。 循环主体代码被多次编写,任何封闭的循环可以把迭代…...
AndroidStudio编译报错 Duplicate class kotlin
具体的编译报错信息如下: Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21) D…...
LeetCode hot 100—搜索二维矩阵
题目 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 fa…...
栈与队列习题分享(精写)
最小栈 题解 一、题目描述 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素 val 推入堆栈。 void pop() 删除堆栈顶部的元素。 int…...
Kotlin 集合过滤全指南:all、any、filter 及高级用法
在 Kotlin 中,集合过滤是数据处理的核心操作之一。无论是简单的条件筛选,还是复杂的多条件组合,Kotlin 都提供了丰富的 API。本文将详细介绍 filter、all、any、none 等操作符的用法,并展示如何在实际开发中灵活运用它们。 1. 基础…...
【lerobot】3-开源SO-100 主从臂的舵机位置校正、遥控操作(ubuntu系统)
官方从零教程:https://github.com/huggingface/lerobot/blob/main/examples/10_use_so100.md 8-lerobot aloha装配完毕如何进行遥操作 需要先完成的 组装好了so-100 2个机械臂下载安装了lerobot的代码环境:固定好主从臂,通过usb链接到同一个…...
影刀RPA证书题库包含初级、中级、高级和AP初级
影刀rpa初级证书选择题答案,影刀证书答案,影刀rpa考试,影刀初级考试,影刀初级考试选择题 原因 以前的在线题库https://exam.ezrpa.store/是为了方便更新题目和使用的,但经过实际使用发现大部分人“不会用”࿱…...
LR(0)
LR0就是当我处在自动机为红色这些结束状态的时候,这些红色状态就代表我们识别到了一个句柄,那现在的问题就是识别到了句柄,那要不要对他进行归约?LR0就是我不管当前指针指向的终结符是什么,我都拿它做规约 这里的二号状…...
基于 Python 和 OpenCV 技术的疲劳驾驶检测系统(2.0 全新升级,附源码)
大家好,我是徐师兄,一个有着7年大厂经验的程序员,也是一名热衷于分享干货的技术爱好者。平时我在 CSDN、掘金、华为云、阿里云和 InfoQ 等平台分享我的心得体会。 🍅文末获取源码联系🍅 2025年最全的计算机软件毕业设计…...
Matplotlib库详解
Matplotlib 是 Python 里一个特别常用的绘图库,它能帮你创建各种各样的可视化图形,像折线图、柱状图、散点图等。对于数据可视化、数据分析和科学研究而言,它是非常重要的工具。接下来我会以初学者的视角,为你详细介绍 Matplotlib…...
daz dForce to UE 的原理分析
dForce是物理模拟,不是关键帧动画: dForce是一个物理引擎。当你运行模拟时,Daz Studio会根据你设置的物理属性(如裙子的重量、布料的硬度、摩擦力)、环境因素(如重力、风力)以及与角色的碰撞&am…...
速卖通商品详情API接口:功能、应用与开发指南
前言 在全球跨境电商蓬勃发展的背景下,速卖通(AliExpress)作为阿里巴巴旗下的国际电商平台,凭借丰富的商品种类和庞大的用户群体,成为众多商家和开发者拓展海外市场的首选平台。为了满足商家和开发者对商品数据的深度…...
4月14日星期一今日早报简报微语报早读
4月14日星期一,农历三月十七,早报#微语早读。 1、全国田径大奖赛接力摘金,苏炳添的传奇将延续至全运会; 2、中国红基会:2024年全年总收支12.85亿元; 3、我国2025年电影总票房已突破250亿 位居全球第一&a…...
快速排序(非递归版本)
引言 在排序算法的世界里,快速排序以其高效的性能脱颖而出。它采用分治法的思想,通过选择基准元素将数组分为两部分,递归地对左右两部分进行排序。然而,递归实现的快速排序在处理大规模数据时可能会导致栈溢出的问题。为了解决这…...
Ubuntu20.04 设置开机自启
参考: Ubuntu20.04 设置开机自启_ubuntu进bos系统-CSDN博客...
添加登录和注册功能
先写前端再写后端 前提:ideavue3mybatisspringBoot3前后端分离实现对一张表的增删改查(完整代码版)-CSDN博客 项目地址 1.添加一个Login.vue视图 <template><div class"login_container"><div class"login…...
弱口令爆破
1.简单介绍 弱口令是指一些简单易猜的密码,可通过社工方式和一些爆破工具进行破解,以下介绍一款爆破工具的用法。burpsuite简称BP,一款可以利用字典破解账户密码的工具。 2.部署网站 可以使用PHPstudy的Apache服务,也可以使用I…...
springboot调用python文件,在ubuntu上部署,踩坑之旅(已部署成功)
项目介绍 springboot 调用python文件,python调用另一个数据文件,然后计算出结果,看似简单,实际上有很多坑,因为涉及到python的三方库,有时候下载不下来,有时候版本不匹配,折腾了好久…...
Android studio消息同步机制:消息本地存储,服务器交互减压
文章目录 后端(Flask)代码前端(Android Studio Java)代码 消息同步机制: 手机端可以将消息存储在本地数据库中,减少与服务器的交互压力。同时,通过序列号机制,手机端可以与服务器同步消息&#…...
前端常用组件库全览与推荐
📌 一、组件库生态全景图 🚀 二、React 生态组件库推荐 名称简介官网Ant Design阿里出品,企业级 UI 系统,设计规范完整,适合后台系统https://ant.designMaterial UIGoogle Material Design 实现,样式响应式…...
视觉算法+雾炮联动:开创智能降尘新时代
在许多工业环境中,尤其是那些涉及大量物料搬运和处理的地方,如工厂或仓库,扬尘问题是一个普遍存在的挑战。这不仅影响了工作人员的工作条件,还可能构成健康和安全隐患。为了改善这一状况,不少业主采用了物理方法来减少…...
【Pandas】pandas DataFrame items
Pandas2.2 DataFrame Indexing, iteration 方法描述DataFrame.head([n])用于返回 DataFrame 的前几行DataFrame.at快速访问和修改 DataFrame 中单个值的方法DataFrame.iat快速访问和修改 DataFrame 中单个值的方法DataFrame.loc用于基于标签(行标签和列标签&#…...
易境通WMS系统代理仓解决方案:让代理仓管理无后顾之忧!
易境通WMS系统代理仓解决方案:让代理仓管理无后顾之忧! 对于海外仓企业而言,除了自有仓库外,为了业务发展还会同时代理其他仓库,于是经常会面临主仓代理仓数据同步问题及费用问题。此外,由于个仓库分布较广…...
【智驾中的大模型 -2】VLM 在自动驾驶中的应用
1. 前言 随着端到端 AI 和多模态学习的迅猛发展,VLM(视觉-语言模型)在自动驾驶领域中的应用正逐渐成为一个备受瞩目的重要研究方向。VLM 凭借其强大的融合能力,将视觉(如高清晰度的摄像头图像、精准的雷达数据&#x…...
L1-104 九宫格
L1-104 九宫格 - 团体程序设计天梯赛-练习集 九宫格是一款数字游戏,传说起源于河图洛书,现代数学中称之为三阶幻方。游戏规则是:将一个 99 的正方形区域划分为 9 个 33 的正方形宫位,要求 1 到 9 这九个数字中的每个数字在每一行…...
图像预处理(OpenCV)-part2
4 边缘填充 为什么要填充边缘呢?我们以下图为例。 原图旋转后的图 可以看到,左图在逆时针旋转45度之后原图的四个顶点在右图中已经看不到了,同时,右图的四个顶点区域其实是什么都没有的,因此我们需要对空出来的区域进…...
SpringAI-ollama
SpringAi主要依赖 System Prompt :设置提示词 用来预设角色 ConversationMemory: 对话集 RAG: 检索增强生成 将业务数据存储在向量数据库中(做相似性检索)通过RAG进行链接 Function Calling 用来调用自己的api <dependencyManagement>&…...