使用canal和openfire实现Mysql的实时数据订阅

文章目录

    • 1、Openfire插件接收binlog数据
      • 1.1、创建用户组
      • 1.2、接口实现
    • 2、Canal客户端开发
    • 3、Smack消息客户端实现。

mysql的binlog的实时数据订阅
(1) canal安装与客户端使用
(2) openfire 4.7.5 Web插件开发
(3) 使用canal和openfire实现Mysql的实时数据订阅

业务系统每天产生的数据在5000-1万之间,数据量不大,但是订阅这些数据的用户量比较多,当前要支持100多用户,并且要求数据实时同步。产生的数据是包含类别的,用户按实际购买情况订阅自己需要的数据,但是类别总数不多,可以用户分成不同的组,同一组用户订阅相同的类别数据。
简单的构思了一下实现:
1、要实现数据实时同步,最好的方式是基于binlog日志同步,可选的读取binlog工具:canal、floinkcdc等。
2、要把数据同步到用户的数据库,可选方案:
(1)binlog数据保存到kafka,在用户的服务器上安装读取kafka的客户端,实现数据入库。但是这方案在用户管理不方便。
(2)基于netty实现数据同步的服务器端和客户端,binlog数据发送到netty服务器端,netty服务器端再通过传输协议把数据同步到netty客户端入库。但是这方案比较可行,但是开发工作量比较大。
(3)使用开源openfire即时消息服务器和客户端Smack库实现数据同步的服务器端和客户端,这方案开发工作量不大,而且Openfire自带用户和组管理,单机也支持1万用户的并发量,后期用户增长也没压力。但是需要开发人员先学习openfire相关技术,需要一定的学习时间。
本文使用方案(3)测试数据同步方案。
数据同步链路如下:
在这里插入图片描述

1、Openfire插件接收binlog数据

1.1、创建用户组

在openfire后台创建用户组data-group,组内添加用户test1、test2,这个组内的数据只同步给test1、test2两个用户。
在这里插入图片描述

1.2、接口实现

实现代码是在前文openfire 4.7.5 Web插件开发 的Jersey接口例子基础上,增加MessageService类,实现接收数据的http接口,接收来自canal客户端的sql数据,并将数据发送到Smack客户端。

package org.igniterealtime.openfire.service;import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.igniterealtime.openfire.exampleplugin.DbCdcPlugin;
import org.jivesoftware.admin.AuthCheckFilter;
import org.jivesoftware.openfire.MessageRouter;
import org.jivesoftware.openfire.XMPPServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import javax.annotation.PostConstruct;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.*;@Path("dbcdc/v1/message")
public class MessageService {private static final Logger log = LoggerFactory.getLogger(MessageService.class);private DbCdcPlugin plugin;@PostConstructpublic void init() {plugin = (DbCdcPlugin) XMPPServer.getInstance().getPluginManager().getPlugin( "dbcdc" );AuthCheckFilter.addExclude("dbcdc/v1/message/sendMsgToOne");}// http://localhost:9090/plugins/dbcdc/v1/message/sendMsgToOne?msg=aaaaabbbbbb@POST@Path("/sendMsgToOne")@Produces(MediaType.APPLICATION_JSON)@Consumes(MediaType.APPLICATION_FORM_URLENCODED)public Map<String, Object> sendMsgToOne(@FormParam("msg") String msg) throws Exception{List<String> jids = getMembers();// 给组内用户同步binlogMap<String, Object> data = new HashMap<>();data.put("msg", msg);String from = "admin@21doc.net";jids.forEach(jid->{String to = jid;Message message = new Message();message.setFrom(new JID(from));message.setTo(new JID(to));message.setID(nextID());message.setType(Message.Type.chat);message.setBody(msg);MessageRouter messageRouter = plugin.server.getMessageRouter();messageRouter.route(message);data.put(jid, "success");});return data;}private List<String> getMembers(){List<String> list = new ArrayList();try{// 测试只发给data-group用户组Collection<JID> jids = plugin.groupManager.getGroup("data-group").getMembers();for(JID jid:jids){list.add(jid.toBareJID());}}catch(Exception e){log.error("getMembers error=====",e);}return list;}public static synchronized String nextID() {Random random = new Random();int number1 = random.nextInt(899) + 100;int number2 = random.nextInt(899) + 100;return new StringBuffer().append(number1).append("-").append(number2).toString();}
}

2、Canal客户端开发

Canal客户端接收Canal服务器端传输的binlog数据,并转成对应的sql语句,再发送到Openfire服务器端分发给用户。
是在前文canal安装与客户端使用的基础上,重新实现了CanalClient类,例子只处理了删除、更新、插入三种SQL操作。

package com.penngo.canal.component;import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.protocol.CanalEntry.*;
import com.alibaba.otter.canal.protocol.Message;
import com.google.protobuf.InvalidProtocolBufferException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.springframework.stereotype.Component;
import java.util.List;@Component
@Slf4j
public class CanalClient {private final static String imUrl = "http://localhost:9090/plugins/dbcdc/v1/message/sendMsgToOne";@Resourceprivate CanalConnector canalConnector;/*** canal入库方法*/public void run() {int batchSize = 1000;try {canalConnector.connect();canalConnector.subscribe("flinktest\\..*");canalConnector.rollback();try {while (true) {Message message = canalConnector.getWithoutAck(batchSize);long batchId = message.getId();int size = message.getEntries().size();System.out.println("batchId=======" + batchId + ",size:" + size);if (batchId == -1 || size == 0) {Thread.sleep(1000);} else {dataHandle(message.getEntries());}canalConnector.ack(batchId);}} catch (InterruptedException e) {e.printStackTrace();} catch (InvalidProtocolBufferException e) {e.printStackTrace();}} finally {canalConnector.disconnect();}}/*** 数据处理* @param entrys*/private void dataHandle(List<Entry> entrys) throws InvalidProtocolBufferException {for (Entry entry : entrys) {if (EntryType.ROWDATA == entry.getEntryType()) {RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());EventType eventType = rowChange.getEventType();if (eventType == EventType.DELETE) {genDeleteSql(entry);} else if (eventType == EventType.UPDATE) {genUpdateSql(entry);} else if (eventType == EventType.INSERT) {genInsertSql(entry);}}}}private void genUpdateSql(Entry entry) {try {RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());List<RowData> rowDatasList = rowChange.getRowDatasList();for (RowData rowData : rowDatasList) {List<Column> newColumnList = rowData.getAfterColumnsList();StringBuffer sql = new StringBuffer("update " + entry.getHeader().getTableName() + " set ");for (int i = 0; i < newColumnList.size(); i++) {sql.append(" " + newColumnList.get(i).getName()+ " = '" + newColumnList.get(i).getValue() + "'");if (i != newColumnList.size() - 1) {sql.append(",");}}sql.append(" where ");List<Column> oldColumnList = rowData.getBeforeColumnsList();for (Column column : oldColumnList) {if (column.getIsKey()) {sql.append(column.getName() + "=" + column.getValue());break;}}this.sqlToIm(sql.toString());}} catch (Exception e) {e.printStackTrace();}}private void genDeleteSql(Entry entry) {try {RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());List<RowData> rowDatasList = rowChange.getRowDatasList();for (RowData rowData : rowDatasList) {List<Column> columnList = rowData.getBeforeColumnsList();StringBuffer sql = new StringBuffer("delete from " + entry.getHeader().getTableName() + " where ");for (Column column : columnList) {if (column.getIsKey()) {sql.append(column.getName() + "=" + column.getValue());break;}}this.sqlToIm(sql.toString());}} catch (Exception e) {e.printStackTrace();}}private void genInsertSql(Entry entry) {try {RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());List<RowData> rowDatasList = rowChange.getRowDatasList();for (RowData rowData : rowDatasList) {List<Column> columnList = rowData.getAfterColumnsList();StringBuffer sql = new StringBuffer("insert into " + entry.getHeader().getTableName() + " (");for (int i = 0; i < columnList.size(); i++) {sql.append(columnList.get(i).getName());if (i != columnList.size() - 1) {sql.append(",");}}sql.append(") VALUES (");for (int i = 0; i < columnList.size(); i++) {sql.append("'" + columnList.get(i).getValue() + "'");if (i != columnList.size() - 1) {sql.append(",");}}sql.append(")");this.sqlToIm(sql.toString());}} catch (Exception e) {e.printStackTrace();}}/*** 同步到openfire服务器端* @param sql*/public void sqlToIm(String sql) throws Exception {String body = Jsoup.connect(imUrl).ignoreContentType(true).header("Content-Type", "application/x-www-form-urlencoded").data("msg", sql).method(Connection.Method.POST).execute().body();log.info("sqlToIm result=======" + body);}
}

3、Smack消息客户端实现。

Smack消息客户端接收来自Openfire服务器的消息,并把数据同步到数据库。实现代码
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.penngo.example</groupId><artifactId>Smack-Test</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><java.version>8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-core --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-core</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-extensions --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-extensions</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-im --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-im</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-tcp --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-tcp</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-debug --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-debug</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-experimental --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-experimental</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-legacy --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-legacy</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-bosh --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-bosh</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-resolver-minidns --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-resolver-minidns</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-resolver-javax --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-resolver-javax</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-resolver-dnsjava --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-resolver-dnsjava</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-xmlparser-xpp3 --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-xmlparser-xpp3</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-sasl-javax --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-sasl-javax</artifactId><version>4.4.6</version></dependency><!-- https://mvnrepository.com/artifact/org.igniterealtime.smack/smack-java8 --><dependency><groupId>org.igniterealtime.smack</groupId><artifactId>smack-java8</artifactId><version>4.4.6</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.6</version></dependency></dependencies><repositories><repository><id>alimaven</id><name>Maven Aliyun Mirror</name><url>https://maven.aliyun.com/repository/central</url></repository></repositories><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>${java.version}</source><target>${java.version}</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.22.2</version><configuration><skip>true</skip></configuration></plugin></plugins></build>
</project>

业务逻辑实现SqlAgentIM.java

package com.penngo.example;import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException;import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.jid.EntityBareJid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.Connection;
import java.sql.DriverManager;public class SqlAgentIM {private static final Logger log = LoggerFactory.getLogger(SqlAgentIM.class);private String dburl = "jdbc:mysql://localhost:3306/flinktest2?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false";private AbstractXMPPConnection conn = null;private DbDao dbDao = null;public SqlAgentIM(){}public void run(){dbDao = new DbDao(dburl, "root", "test123");login();}public void login(){try{// 打开调试窗口SmackConfiguration.DEBUG = true;XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder().setUsernameAndPassword("test2", "123456").setXmppDomain("21doc.net").setHost("127.0.0.1").setPort(5222).setSecurityMode(ConnectionConfiguration.SecurityMode.disabled).build();conn = new XMPPTCPConnection(config);conn.connect().login();setOnlineStatus();ChatManager chatManager = ChatManager.getInstanceFor(conn);chatManager.addChatListener((chat, b) -> chat.addMessageListener((chat1, message) ->{String sql = message.getBody();//System.out.println("New message from " + chat1 + ": " + message.getBody());System.out.println("New message from " + chat1.getParticipant().asEntityBareJidString() + ": " + sql);try{int successCount = dbDao.execute(sql);log.info("execute result====successCount:" + successCount);}catch(Exception e){e.printStackTrace();log.error("execute error", e);}}));}catch(Exception e){e.printStackTrace();}}public void setOnlineStatus() throws SmackException.NotConnectedException, InterruptedException {Presence presence = new Presence(Presence.Type.available, "online", 1, Presence.Mode.available);conn.sendStanza(presence);Presence presence2 = new Presence(Presence.Type.subscribe, "online", 1, Presence.Mode.available);conn.sendStanza(presence2);Presence presence3 = new Presence(Presence.Type.subscribed, "online", 1, Presence.Mode.available);conn.sendStanza(presence3);}class DbDao {private String jdbc_driver;private String jdbc_url;private String jdbc_username;private String jdbc_password;private Connection conn = null;public DbDao(String url, String username, String password){if(conn == null){try{if(jdbc_driver == null){jdbc_driver = "";jdbc_url = url;jdbc_username = username;jdbc_password = password;}DbUtils.loadDriver(jdbc_driver);conn = DriverManager.getConnection(jdbc_url, jdbc_username, jdbc_password);}catch(Exception e){e.printStackTrace();}}}public int execute(String sql, Object... params) throws Exception{QueryRunner qr = new QueryRunner();int i = qr.update(conn, sql, params);return i;}public void close(){DbUtils.closeQuietly(conn);}}public static void main(String[] args) {SqlAgentIM sqlAgentIM = new SqlAgentIM();sqlAgentIM.run();}
}

本文仅实现了用户在线时的mysql实现更新,未实现内容:

  • 1、客户端离线时,离线数据的同步;
  • 2、用户第一次订阅数据时的数据全量更新。
    后续可以根据方案采用情况再优化完善。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/147148.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElementUI实现增删改功能以及表单验证

目录 前言 BookList.vue action.js 展示效果 前言 本篇还是在之前的基础上&#xff0c;继续完善功能。上一篇完成了数据表格的查询&#xff0c;这一篇完善增删改&#xff0c;以及表单验证。 BookList.vue <template><div class"books" style"pa…

分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测

分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测 目录 分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-CNN多特征分类预测&#xff0c;多特征输入模型&#xf…

OpenCV 实现 SIFT→SURF 算法关键点检测实现

目录 1&#xff0c;SIFT算法原理 1.1&#xff0c;基本流程 1.1.1 尺度空间极值检测 1.1.2 关键点定位 1.1.3 关键点方向确定 1.1.4 关键点描述 1.1.5 总结 1.2 SURF原理 2 代码实现 3 结果展示 4&#xff0c;你肯定会遇到报错 cv2.error: OpenCV(3.4.8) C…

想用ChatGPT写申请文书?那你肯定会被拒!

美国总统乔拜登&#xff08;Joe Biden&#xff09;、诗人TS艾略特&#xff08;T. S. Eliot&#xff09;和历史学家斯蒂芬安布罗斯&#xff08;Stephen Ambrose&#xff09;&#xff0c;他们的名字都曾与抄袭事件联系在一起。 其中&#xff0c;艾略特的抄袭行为是在他去世后才被…

AutoCAD 产品设计:图形单位

本文讲解 AutoCAD 产品的图形单位功能产品设计&#xff0c;没有任何代码实现。 使用的 AutoCAD 为 2020 版本 图形单位是什么&#xff1f; 图形单位是用于设置 一些属性数据应该用什么格式显示 的命令&#xff0c;命令标识为 un&#xff08;units&#xff09;。 举个例子。 …

uboot启动流程-涉及s_init汇编函数

一. uboot启动涉及函数 本文简单分析uboot启动流程中&#xff0c;涉及的汇编函数&#xff1a; lowlevel_init函数调用的函数&#xff1a;s_init 函数 save_boot_params_ret函数调用的函数&#xff1a; _main 函数 本文继上一篇文章的学习&#xff0c;地址如下&#xff1a;…

“把握拐点,洞悉投资者情绪与比特币价格的未来之路!“

“本来这篇文章是昨天晚上发的&#xff0c;国庆节庆祝喝多了&#xff0c;心有余而力不足&#xff01;直接头躺马桶GG了” 标准普尔 500 指数 200 天移动平均线云是我几个月来一直分享的下行目标&#xff0c;上周正式重新测试了该目标。200 日移动平均线云表示为: 200 天指数移…

JDBC学习笔记(1)

连接数据库 下载mysql-connector-java&#xff0c;这里我是看的这个连接mysql-connector-java下载。 下载后并且导入了Idea中的lib文件下。 导入成功后&#xff0c;为了验证可以通过CTRLn来搜索Driver看看有没有添加进来。 随后在MySQL中创建一个数据库&#xff0c;我这里直…

uboot启动流程-涉及_main汇编函数

一. uboot启动流程涉及函数 本文简单分析一下 save_boot_params_ret调用的函数&#xff1a;_main汇编函数。 本文继之前文章的学习&#xff0c;地址如下&#xff1a; uboot启动流程-涉及s_init汇编函数_凌肖战的博客-CSDN博客 二. uboot启动流程涉及的 _main汇编函数 经过之…

Beats Studio Buds 连接 Windows 11 声音输出不显示设备

Beats Studio Buds 连接 Windows 11 声音输出不显示设备 Beats Studio Buds 蓝牙耳机连接Windows 11电脑后&#xff0c;无法通过耳机播放声音&#xff0c;在声音输出选项中也没有耳机选项。 问题 蓝牙耳机连接电脑。 在声音输出中查看输出设备选项。 解决方法 以管理员身…

Python中匹配模糊的字符串

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 如何使用thefuzz 库&#xff0c;它允许我们在python中进行模糊字符串匹配。 此外&#xff0c;我们将学习如何使用process 模块&#xff0c;该模块允许我们在模糊…

淘宝天猫渠道会员购是什么意思?如何开通天猫淘宝渠道会员购有什么用?

淘宝天猫渠道会员购是什么意思&#xff1f; 淘宝天猫渠道会员购与淘宝天猫粉丝福利购意思基本相同&#xff0c;都可以领取淘宝天猫大额内部隐藏优惠券、通过草柴APP开通绑定渠道会员还可以获得购物返利。 草柴APP如何绑定开通淘宝天猫渠道会员&#xff1f; 1、手机下载安装「…

【改进哈里鹰算法(NCHHO)】使用混沌和非线性控制参数来提高哈里鹰算法的优化性能,解决车联网相关的路由问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

数学建模三大类模型适用场景及建模方法(纯干货)(3)

目录 一&#xff0c;评价类算法 1&#xff0c;层次分析法 ●基本思想: ●基本步骤: ●优点: ●缺点 ●适用范围: ●改进方法: 2&#xff0c;灰色综合评价法&#xff08;灰色关联度分析&#xff09; ●基本思想: ●基本步骤: ●优点: ●缺点: ●适用范围: ●改进方…

游戏制作资源推荐

教程 创建僵尸第一人称射击游戏 | 虚幻引擎 5 初学者教程https://www.youtube.com/watch?vqOam3QjGE8g ​​​​​​​ 虚幻商城免费资产 人物资产 各种角色应有尽有 关键词&#xff1a;paragon &#xff1b;推荐程度&#xff1a;三颗星

CBA球员注册管理系统(计科课设)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;数据结构初阶 ⭐代码仓库&#xff1a;Data Structure 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff…

SpringBoot注册web组件

目录 前言 一、注册Servlet组件 1.1 使用SpringBoot注解加继承HttpServet类注册 1.2 通过继承HttpServet类加配置类来进行注册 二、注册Listener组件 2.1 使用SpringBoot注解和实现ServletContextListener接口注册 2.2 ServletContextListener接口和配置类来进行注册 …

算法框架-LLM-1-Prompt设计(一)

原文&#xff1a;算法框架-LLM-1-Prompt设计&#xff08;一&#xff09; - 知乎 目录 收起 1 prompt-engineering-for-developers 1.1 Prompt Engineering 1.1.1 提示原则 1. openai的环境 2. 两个基本原则 3. 示例 eg.1 eg.2 结构化输出 eg.3 模型检验 eg.4 提供示…

uwb人员定位系统:人员轨迹实时定位

UWB定位系统是一种基于超宽带技术的定位系统。它与传统的通信技术不同&#xff0c;不需要使用载波&#xff0c;而是通过发送和接收具有纳秒或微妙级以下的极窄脉冲来实现无线传输。这种系统的优势包括低功耗、对信道衰落不敏感、抗环境能力强、不会对同一环境下的其他设备造成影…

深度学习(1)---卷积神经网络(CNN)

文章目录 一、发展历史1.1 CNN简要说明1.2 猫的视觉实验1.3 新认知机1.4 LeNet-51.5 AlexNet 二、卷积层2.1 图像识别特点2.2 卷积运算2.3 卷积核2.4 填充和步长2.5 卷积计算公式2.6 多通道卷积 三、池化层 一、发展历史 1.1 CNN简要说明 1. 卷积神经网络&#xff08;Convolut…