RocketMQ第三节(生产者和消费者)
目录
1:生产者(同步、异步、单向)
1.1:同步发送消息(每发送一条等待mq返回值)
1.2:异步发送消息
1.3:单向发送消息(不管成功失败,只管发送消息)
1.4:顺序发送消息
1.5:批量发送消息
1.6:定时发送消息
2:消费者
2.1:push消费
2.2:pull消费
1:生产者(同步、异步、单向)
在了解生产者之前,首先再次查看这个图片。生产者发送消息,围绕生产者的概念和怎么发送消息来解析MQ。生产者有重要的的message元素
Message:包含以下属性
字段名 | 默认值 | 必要性 | 说明 |
---|---|---|---|
Topic | null | 必填 | 消息所属 topic 的名称 |
Body | null | 必填 | 消息体 |
Tags | null | 选填 | 消息标签,方便服务器过滤使用。目前只支持每个消息设置一个 |
Keys | null | 选填 | 代表这条消息的业务关键词,唯一ID |
Flag | 0 | 选填 | 完全由应用来设置,RocketMQ 不做干预 |
DelayTimeLevel | 0 | 选填 | 消息延时级别,0 表示不延时,大于 0 会延时特定的时间才会被消费 |
WaitStoreMsgOK | true | 选填 | 表示消息是否在服务器落盘后才返回应答。mq接受到消息,存入磁盘,然后返回成功或者失败 |
队列:为了支持高并发和水平扩展,需要对 Topic 进行分区,在 RocketMQ 中这被称为队列,一个 Topic 可能有多个队列,并且可能分布在不同的 Broker 上。保证消息的发送和消费的并发速度。在生产者将消息发送到MQ的broker的时候,这个时候broker的内部维护了队列,保证先进先出。默认一个topic里边有4个读4个写的队列
我们怎么发送消息,生产者发送消息包含同步,异步,单向这三个方面。当然按照功能又扩展出来顺序消息、批量消息、定时消息、事务消息等模式。
1.1:同步发送消息(每发送一条等待mq返回值)
同步发送:每次发送一条,等待mq的返回值成功,然后发送下一条,适合可靠的消息传递,适用范围最广泛。如重要的通知消息、短消息通知等
代码如下:
public class 普通消息发送_同步 {/*** 同步消息发送,发送之后等待服务端返回结果* 消息发送到broker 等待响应,成功后接着发送下一条数据* 保证了消息发送的可靠性** 使用场景:大部分可靠性要求高的场景*/public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {//1:初始化一个生产者,并且设置group是商品组System.out.println("同步发送消息模式");String producerGroup="shop_Group";DefaultMQProducer producer=new DefaultMQProducer(producerGroup);//2:设置nameServerproducer.setNamesrvAddr("localhost:9876");//3:启动producerproducer.start();//4:发送100条消息for (int i = 0; i < 10; i++) {//5:定义消息体Message msg=new Message();//设置消息主题 必填String topic="huyijuTopic";msg.setTopic(topic);//设置消息体 必填String body="同步:"+i;msg.setBody(body.getBytes(StandardCharsets.UTF_8));//设置落盘策略 默认落盘成功返回true 选填msg.setWaitStoreMsgOK(true);//设置消息keys 消息唯一标识 选填msg.setKeys("shop"+i);//设置消息标签 选填msg.setTags("同步");//6:发送数据SendResult sendResult = producer.send(msg);System.out.printf("%s%n", sendResult);}//7:发送完消息,关闭生产者producer.shutdown();}}
1.2:异步发送消息
异步发送消息:发送完后不用等待响应,就可以发送第二条消息,通过回调接口,来接受响应成功或者失败。异步发送一般用于链路耗时较长,对响应时间较为敏感的业务场景。例如,视频上传后通知启动转码服务,转码完成后通知推送转码结果等。
代码如下:
public class 普通消息发送_异步 {/*** 异步消息发送模式 发送数据之后不等响应接着发送,需要回调接口,回调接口告知失败 或者成功** 适用场景:适用于发送文件视频等大的文件 节省时间**/public static void main(String[] args) throws Exception {System.out.println("异步发送普通消息");// 初始化一个producer并设置Producer group nameDefaultMQProducer producer = new DefaultMQProducer("shop_Group");// 设置NameServer地址producer.setNamesrvAddr("localhost:9876");// 启动producerproducer.setRetryTimesWhenSendAsyncFailed(0);//重试次数producer.start();for (int i = 0; i < 5; i++) {// 创建一条消息,并指定topic、tag、body等信息,tag可以理解成标签,对消息进行再归类,RocketMQ可以在消费端对tag进行过滤String topic="huyijuTopic";Message msg = new Message(topic,"异步",("异步"+i).getBytes(StandardCharsets.UTF_8));// 异步发送消息, 发送结果通过callback返回给客户端producer.send(msg, new SendCallback() {@Overridepublic void onSuccess(SendResult sendResult) {System.out.println("数据发送成功:"+sendResult);}@Overridepublic void onException(Throwable e) {System.out.println("数据发送失败:"+e);e.printStackTrace();}});}// 一旦producer不再使用,关闭producerproducer.shutdown();}}
1.3:单向发送消息(不管成功失败,只管发送消息)
单向发送:生产者向mq发送消息,不等待mq的返回值,是否消息接收成功或者失败。生产者只管发送,适用于日志等可靠性不高的场景。发送速度很快,微秒级的速度
public class 普通消息发送_单向 {/*** 单向发送消息模式* 服务方只发送消息 不等服务端响应 也不管回调 发送速度很快 就是只管发送消息 不管成功失败** 适用场景:适用于发送日志,对于数据可靠性要求不高*/public static void main(String[] args) throws Exception {System.out.println("单向发送普通消息");// 初始化一个producer并设置Producer group nameDefaultMQProducer producer = new DefaultMQProducer("shop_Group");// 设置NameServer地址producer.setNamesrvAddr("127.0.0.1:9876");// 启动producerproducer.start();for (int i = 0; i < 10; i++) {final int index = i;// 创建一条消息,并指定topic、tag、body等信息,tag可以理解成标签,对消息进行再归类,RocketMQ可以在消费端对tag进行过滤String body="单向"+i;Message msg = new Message("huyijuTopic","单向",body.getBytes(StandardCharsets.UTF_8));// 不管不顾,直接发送,没有返回值producer.sendOneway(msg);}// 一旦producer不再使用,关闭producerproducer.shutdown();}}
1.4:顺序发送消息
我们知道,我们发送的消息,存储到了mq的topic的队列里边,默认的topic是4个队列
根据消息的key将消息轮训的插入队列中,队列的消息能保证FIFO,但是我们并不知道实际具体那条消息在那个队列,无法保证比如订单号是01的所有操作在同一个队列。如下图
消费者再消费的时候,无法保证业务的一致性。所有才有了顺序发送,我们传入指定的订单号,只要订单号一直,就一定会存到相同的队列。
代码如下:
/*** 顺序发送:SendResult send(Message msg, MessageQueueSelector selector, Object arg)* 根据同一个arg的值存入,相同的队列 队列一共四个,很多数据的时候,根据arg%4 存入指定的队列,先进先出** 适用场景:下单,支付,物流等场景,我们使用orderId作为分区id 会发送到同一个队列 保证顺序** 注意事项:只能有一个生产者,因为分布式环境,多个生产者发送相同的同一个orderId,无法判定先后顺序* 必须是单一的生产者** 如果一个Broker掉线,那么此时队列总数是否会发化?** 如果发生变化,那么同一个 ShardingKey 的消息就会发送到不同的队列上,造成乱序。* 如果不发生变化,那消息将会发送到掉线Broker的队列上,必然是失败的。因此 Apache RocketMQ 提供了两种模式,* 如果要保证严格顺序而不是可用性,创建 Topic 是要指定 -o 参数(--order)为true,表示顺序消息:** sh bin/mqadmin updateTopic -c DefaultCluster -t TopicTest -o true -n 127.0.0.1:9876*/
public class 顺序消息发送 {public static void main(String[] args) {System.out.println("顺序消息发送");DefaultMQProducer producer = new DefaultMQProducer("shop_Group");try {// 设置NameServer地址producer.setNamesrvAddr("127.0.0.1:9876");int a=producer.getDefaultTopicQueueNums();System.out.println("默认的队列大小:"+a);producer.start();for (int i = 0; i < 5; i++) {
// String[] tags = new String[] {"TagA", "TagB", "TagC", "TagD", "TagE"};
// Message msg1 =
// new Message("TopicTest", tags[i % tags.length], "KEY" + i,
// ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET));Message msg=new Message();//设置主题String topic="huyijuTopic";msg.setTopic(topic);//设置内容String body="顺序发送"+i;msg.setBody(body.getBytes(RemotingHelper.DEFAULT_CHARSET));//设置keysmsg.setKeys("key"+i);//设置tagsmsg.setTags("顺序发送");//订单id 根据不同的id将消息发送到不同的队列(队列总共4个 取模放入队列) 遵循FIFO
// int orderId = i%a;
// System.out.println("订单id:"+orderId);SendResult sendResult = producer.send(msg, new MessageQueueSelector() {@Overridepublic MessageQueue select(List<MessageQueue> list, Message message, Object arg) {
// System.out.println("参数arg:"+arg);//这里参数的send方法的参数一致
// System.out.println("参数list:"+list.size());//默认队列是4
// System.out.println(message);//根据订单id取模,存入指定的队列 然后返回该队列Integer id = (Integer) arg;int index = id % list.size();MessageQueue messageQueue = list.get(index);return messageQueue;}}, 5);//这里的5就是实际上我们的订单号,根据这个参数将消息存到相同的队列System.out.printf("%s%n", sendResult);}} catch (MQClientException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (MQBrokerException e) {e.printStackTrace();} catch (RemotingException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}finally {producer.shutdown();}}
}
1.5:批量发送消息
批量发送消息:将消息批量发送到mq来节省时间
代码如下:
/*** 批量投送消息,增加吞吐率 减少网络调用次数** 需要注意的是批量消息的大小不能超过 1MB**/
public class 批量消息发送 {public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {System.out.println("批量消息投送");DefaultMQProducer producer = new DefaultMQProducer("shop_Group");producer.setNamesrvAddr("127.0.0.1:9876");producer.start();String body1="批量任务1";String body2="批量任务2";String body3="批量任务3";Message message1=new Message("huyijuTopic","批量任务",body1.getBytes(StandardCharsets.UTF_8));Message message2=new Message("huyijuTopic","批量任务",body2.getBytes(StandardCharsets.UTF_8));Message message3=new Message("huyijuTopic","批量任务",body3.getBytes(StandardCharsets.UTF_8));List<Message> list=new ArrayList<>();list.add(message1);list.add(message2);list.add(message3);SendResult send = producer.send(list);System.out.println("批量消息投送结束"+send);producer.shutdown();}
}
1.6:定时发送消息
定时消息发送:将消息发送到mq,mq根据定时将消息发送给消费者。切记不要搞反了,消息是发送到mq之后,定时发送个消费者。
代码如下:
/*** 延时消息发送,数据发送到mq之后 指定的时间之后才能消费** 适用场景:定时任务、超时精准投送** 缺点:大量的定时任务 容易造成消息积压 时间一到 消费者亚历山大**/
public class 延时消息发送 {public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {DefaultMQProducer producer = new DefaultMQProducer("shop_Group");// 设置NameServer地址
// 1 1s 10 6min
// 2 5s 11 7min
// 3 10s 12 8min
// 4 30s 13 9min
// 5 1min 14 10minproducer.setNamesrvAddr("127.0.0.1:9876");producer.start();for (int i = 0; i < 10; i++) {String body= "定时任务"+i;Message message=new Message("huyijuTopic","定时任务",body.getBytes(StandardCharsets.UTF_8));message.setDelayTimeLevel(3);//设置的定时任务级别SendResult send = producer.send(message);System.out.println("定时消息返回值:"+send);}producer.shutdown();}
}
2:消费者
消息的消费者很简单,只两种模式
第一种(推送模式):订阅mq服务的topic,mq收到消息把消息推送给消费者,适用范围广
第二种(拉取模式):订阅mq服务的topic,mq收到消息,消费者定时去mq拉取消息
2.1:push消费
普通消息的推送消费
//适用于普通的消息推送,不适合用于顺序消息的消费
public class 消息接收_推送1 {public static void main(String[] args) throws MQClientException {String group = "Shop_Group_push";//1:初始化消息接收组DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group);//2:设置NameServer地址consumer.setNamesrvAddr("localhost:9876");//3:订阅一个或多个topic,并指定tag过滤条件,这里指定*表示接收所有tag的消息String topic="huyijuTopic";consumer.subscribe(topic,"*");consumer.setMessageModel(MessageModel.CLUSTERING);//默认是集群模式//consumer.setMessageModel(MessageModel.BROADCASTING);//这里是广播模式//4.1:注册回调接口来处理从Broker中收到的消息 单个对列保证先进先出//但是多个队列 被消费者并发消费 不能保证消费的顺序性consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {System.out.println(list);for (int i = 0; i < list.size(); i++) {byte[] body = list.get(i).getBody();String resault= null;try {resault = new String(body,"utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}System.out.println("接受huyijuTopic的第"+i+"条消息:"+resault);}// 返回消息消费状态,ConsumeConcurrentlyStatus.CONSUME_SUCCESS为消费成功return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();
// consumer.shutdown();System.out.println("推送消息接收启动1");}
}
顺序消息的推送消费
public class 消息接收_顺序消费1 {public static void main(String[] args) throws MQClientException {System.out.println("顺序消费1");String group = "Shop_Group_push";//1:初始化消息接收组DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group);//2:设置NameServer地址consumer.setNamesrvAddr("localhost:9876");//3:订阅一个或多个topic,并指定tag过滤条件,这里指定*表示接收所有tag的消息String topic="huyijuTopic";consumer.subscribe(topic,"*");consumer.setMessageModel(MessageModel.CLUSTERING);//默认是集群模式//consumer.setMessageModel(MessageModel.BROADCASTING);//这里是广播模式//4.2:注册回调接口来处理从Broker中收到的消息 单个对列保证先进先出//但是多个队列 被消费者并发消费,不能保证消费的顺序性 这里使用MessageListenerOrderlyconsumer.registerMessageListener(new MessageListenerOrderly() {@Overridepublic ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext consumeOrderlyContext) {//AtomicLong consumeTimes = new AtomicLong(0);consumeTimes.incrementAndGet();for (int i = 0; i < list.size(); i++) {byte[] body = list.get(i).getBody();String resault= null;try {resault = new String(body,"utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}System.out.println("接受huyijuTopic的第"+i+"条消息:"+resault);}//返回消费状态return ConsumeOrderlyStatus.SUCCESS;}});consumer.start();
// consumer.shutdown();System.out.println("推送消息接收启动1");}
}
2.2:pull消费
消费者一直循环去mq拉取消息
public class 消息接收_拉取消息2 {public static void main(String[] args) throws MQClientException {System.out.println("开始消息拉取");DefaultLitePullConsumer defaultLitePullConsumer = new DefaultLitePullConsumer();defaultLitePullConsumer.setConsumerGroup("Shop_Pull_Group");//订阅主题 拉取消息String topic="huyijuTopic";defaultLitePullConsumer.subscribe(topic, "*");defaultLitePullConsumer.setPullBatchSize(1);defaultLitePullConsumer.setNamesrvAddr("localhost:9876");defaultLitePullConsumer.start();try {while (true) {List<MessageExt> messageExts = defaultLitePullConsumer.poll();System.out.printf("%s%n", messageExts);System.out.println("拉取数据长度:"+messageExts.size());for (int i = 0; i < messageExts.size(); i++) {byte[] body = messageExts.get(i).getBody();String resault= new String(body,"utf-8");System.out.println("拉取消息:"+resault);}}} catch (UnsupportedEncodingException e) {e.printStackTrace();} finally {defaultLitePullConsumer.shutdown();}}
}
以上就是生产者和消费者的消息模型。
相关文章:

RocketMQ第三节(生产者和消费者)
目录 1:生产者(同步、异步、单向) 1.1:同步发送消息(每发送一条等待mq返回值) 1.2:异步发送消息 1.3:单向发送消息(不管成功失败,只管发送消息)…...

人大金仓亮相国际金融展,打造“金融+产业+生态”创新模式
4月27日,以“荟萃金融科技成果,展现数字金融力量,谱写金融服务中国式现代化新篇章”为主题的2023中国国际金融展圆满落幕。作为已经举办30年的行业盛会,人大金仓再一次重磅亮相,全方位展示国产数据库前沿应用和创新服务…...

Syslog-ng RHEL 的安装和配置
syslog-ng 作为 syslog 的替代工具,可以完全替代 syslog 的服务,并且通过定义规则,实现更好的过滤功能。 作为运维来说一个好的日志工具比什么都重要。 通常我们会管理不同的服务器,因此我们需要把日志集中一下以便于快速查找。…...

得物直播低延迟探索 | 得物技术
1.背景 直播的时效性保证了良好的用户体验,根据经验在交易环节,延迟越低转化效果也会越好。传统的直播延迟问题已经成为了一个不容忽视的问题,高延迟不仅破坏了用户的观看体验,也让主播难以实时获取到用户的反馈。为了进一步优化…...

【CVPR红外小目标检测】红外小目标检测中的非对称上下文调制(ACM)
论文题目: Asymmetric Contextual Modulation for Infrared Small Target Detection 红外小目标检测中的非对称上下文调制 红外小目标数据集 目标个数分布:约90%图片中只有一个目标,约10%图片有多个目标(在稀疏/显著的方法中&am…...

Axios概述
一、Json-server 获得零编码的完整伪造 REST API zero coding 在不到 30 秒的时间内 (认真)。 使用 <3 创建,适用于需要快速后端进行原型设计和模拟的前端开发人员,模拟后端发送过来json数据。 1.安装 npm install -g jso…...

用右雅克比对旋转矩阵进行求导
考虑一个向量 a \bold{a} a对其进行旋转, 旋转用旋转矩阵 R \bold{R} R表示, 用朴素的倒数定义进行求导而不是用扰动模型, 我得到了这个过程与结果 和高博的新书结果 − R J r a ∧ -\bold{R}\bold{J}_{r}\bold{a}^{\wedge} −RJra∧结果不一样, 雅克比矩阵位置不同, 是不是…...

高性能HMI 走向扁平化
个人计算机作为图形用户界面(GUI)在自动化中已经使用了30多年。在那段时间里,从技术、术语、功能到用于创建接口的标准和指南,发生了许多变化。 PC 技术的飞速发展,特别是图形显示,用户界面的技术发展导致了…...

虚幻引擎配置物体水面浮力的简便方法
虚幻引擎配置物体水面浮力的简便方法 目录 虚幻引擎配置物体水面浮力的简便方法前言前期工作配置水面浮力针对一个立方体的水面浮力配置针对船3D模型的水面浮力配置 小结 前言 在使用虚幻引擎配置导入的3D模型时,如何快速地将水面浮力配置正确,从而使得…...

WatchGuard 防火墙策略、配置和日志分析器
获取 Internet 活动见解并及时了解安全事件是一项具有挑战性的任务,因为安全设备会生成大量的安全和流量日志。Firewall Analyzer 针对 WatchGuard 防火墙设备的报告功能具有一系列功能,使您能够增强网络安全。WatchGuard 日志分析器软件,可让…...

Web自动化测试——XAPTH高级定位
XAPTH高级定位 一、xpath 基本概念二、xpath 使用场景三、xpath 相对定位的优点四、xpath 定位的调试方法五、xpath 基础语法(包含关系)六、xpath 顺序关系(索引)七、xpath 高级用法1、[last()]: 选取最后一个2、[属性名属性值 an…...
CentOS 7 安装 Nginx
前言 最近,在公司经常会进行项目的部署,但是服务器环境都是导师已经搭建好了的,我就是将项目文件放到特定目录。于是,周末在家就进行了 Nginx 的安装学习。之前,在 Windows 上使用过 Nginx,但是在 Linux 环…...

Databend 开源周报第 91 期
Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。 新数据类型&…...

【Ubuntu18.04使用yolov5教程】
欢迎大家阅读2345VOR的博客【Ubuntu18.04使用yolov5教程】🥳🥳🥳2345VOR鹏鹏主页: 已获得CSDN《嵌入式领域优质创作者》称号👻👻👻,座右铭:脚踏实地,仰望星空…...
CocoaPods如何发布新版本的Pod Library
当我们修改了一个Pod Library中的代码时,如何让依赖该库的项目能更新到最新代码,步骤如下: 假设现在修改了SamplePod(Pod名称)的代码,希望将最新版本更新到1.0.1,目前版本是1.0.0 修改SamplePo…...

v4l2框架
v4l2框架 文章目录 v4l2框架框架1.硬件相关层uvc_probeuvc_register_chainsuvc_register_termsuvc_register_video 2.核心层__video_register_device 3.虚拟视频驱动vivid分析入口vivid_init注册vivid平台驱动vivid_probevivid_create_instance 框架 1.硬件相关层 driver/medi…...
vue项目中生成LICENSE文件
vue项目中生成LICENSE文件 简介 LICENSE 文件是一个文本文件,它包含了你的项目所使用的开源软件的许可证信息。 在开发过程中,我们经常会使用到各种各样的第三方开源软件,这些软件是有版权和许可证的,我们在使用时需要遵循它们的…...

NewBing最新更新使用体验(无需等待人人可用)
NewBing最新更新使用体验 微软Bing爆炸级更新!无需等待人人可用! 今天,微软突然官宣全面开放BingChat: 无需任何等待。只需注册一个账户,首页即可体验。 NewBing最新更新新特性官方文档 https://www.microsoft.com/en-…...

欧拉奔赴品牌2.0时代,女性汽车真实用户需求被定义?
每年的上海国际汽车工业展览会,不仅是各大汽车品牌的技术“秀场”,也是品牌的营销“修罗场”。今年上海车展出圈的营销事件特别多,热度甚至一再蔓延到汽车行业外,其中欧拉也贡献了不少流量。 据了解,在2023上海车展欧…...
机器视觉工程师,听我一句劝,别去外包,干了三年,废了....对女人没了兴趣
外包三年,干了就废,最后只会安装软件。 对于年轻人来说,需要工作,更需要生活。 对于年轻人来说,需要努力,更需要“面包”。 对于年轻人来说,需要规划,更需要发展。 对于外包,虽说废的不是很彻底,但那三年几乎是出差了三年、玩了三年、荒废了三年,那三年,技术…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...