Java设计模式:四、行为型模式-06:观察者模式
文章目录
- 一、定义:观察者模式
- 二、模拟场景:观察者模式
- 2.1 观察者模式
- 2.2 引入依赖
- 2.3 工程结构
- 2.4 模拟摇号
- 2.4.1 摇号服务接口
- 2.4.2 摇号返回结果类
- 三、违背方案:观察者模式
- 3.0 引入依赖
- 3.1 工程结构
- 3.2 添加摇号接口和实现
- 3.2.1 摇号服务接口
- 3.2.2 摇号服务接口实现类
- 3.3 单元测试
- 四、改善代码:观察者模式
- 4.0 引入依赖
- 4.1 工程结构
- 4.2 观察者模式结构图
- 4.3 添加事件监听和管理器
- 4.3.1 定义事件监听接口
- 4.3.2 短信息事件监听接口实现
- 4.3.3 MQ发送事件监听接口实现
- 4.3.4 事件处理器
- 4.4 摇号抽象类及其实现
- 4.4.1 业务抽象类
- 4.4.2 业务接口实现类
- 4.5 单元测试
- 五、总结:观察者模式
一、定义:观察者模式
- **观察者模式:**当一个行为发生时传递信息给另外一个用户接收做出相应的处理,两者之间没有直接的耦合关联。
- 除了生活中的场景外,在我们编程开发中也会常用到一些观察者的模式或者组件。例如:
- 经常使用的 MQ 服务:虽然 MQ 服务是有一个通知中心并不是每一个类服务进行通知,但整体上也可以算作是观察者模式的思路设计。
- 类似事件监听总线:让主线服务与其他辅线业务分离,为了使系统降低耦合和增强扩展性,也会使用观察者模式进行处理。
二、模拟场景:观察者模式
2.1 观察者模式
- 模拟每次小客车指标摇号事件通知场景
- 可能大部分人看到这个案例一定会想到自己每次摇号都不中的场景,收到一个遗憾的短信通知。当然目前的摇号系统不会给你发短信,而是由百度或者一些其他插件发的短信。
- 那么假如这个类似的摇号功能由你来开发,并且需要对外部的用户做一些事件通知以及需要在主流外再添加一些额外的辅助流程时该如何处理呢?
- 基本很多人对于这样的通知事件类的实现往往比较粗犷,直接在类里面添加就可以了。
- ①考虑这可能不会怎么扩展,②是压根就没考虑过扩展。
- 但如果你有仔细思考过你的核心类功能会发现,这里面有一些核心主链路,还有一部分是辅助功能。
- 比如完成了某个行为后需要触发 MQ 给外部,以及做一些消息 PUSH 给用户等。
- 这些都不算做是核心流程链路,是可以通过事件通知的方式进行处理。
- 基本很多人对于这样的通知事件类的实现往往比较粗犷,直接在类里面添加就可以了。
2.2 引入依赖
pom.xml
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.62</version></dependency><!-- LOGGING begin --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.5</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>1.7.5</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.0.9</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency>
</dependencies>
2.3 工程结构
design-19.0-0
|——src|——main|--java|--com.lino.design|-LotteryResult.java|-MinibusTargetService.java
2.4 模拟摇号
2.4.1 摇号服务接口
MinibusTargetService.java
package com.lino.design;/*** @description: 小客车指标调控服务*/
public class MinibusTargetService {/*** 模拟摇号** @param uId 用户编号* @return 结果*/public String lottery(String uId) {return Math.abs(uId.hashCode()) % 2 == 0 ?"恭喜你,编码".concat(uId).concat("在本次摇号中签"): "很遗憾,编码".concat(uId).concat("在本次摇号未中签或摇号资格已过期");}
}
2.4.2 摇号返回结果类
LotteryResult.java
package com.lino.design;import java.util.Date;/*** @description: 摇号结果类*/
public class LotteryResult {/*** 用户ID*/private String uId;/*** 摇号信息*/private String msg;/*** 业务时间*/private Date dateTime;public LotteryResult(String uId, String msg, Date dateTime) {this.uId = uId;this.msg = msg;this.dateTime = dateTime;}public String getuId() {return uId;}public void setuId(String uId) {this.uId = uId;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Date getDateTime() {return dateTime;}public void setDateTime(Date dateTime) {this.dateTime = dateTime;}
}
三、违背方案:观察者模式
按照需求需要在原有的摇号接口中添加 MQ 消息发送以及短信息通知功能。
如果是最直接的方式那么可以直接在方法中补充功能即可。
3.0 引入依赖
<dependencies><dependency><groupId>com.lino</groupId><artifactId>design-19.0-0</artifactId><version>1.0-SNAPSHOT</version></dependency>
</dependencies>
3.1 工程结构
design-19.0-1
|——src|——main|--java|--com.lino.design|-LotteryService.java|-LotteryServiceImpl.java|--test|--com.lino.design.test|-ApiTest.java
3.2 添加摇号接口和实现
3.2.1 摇号服务接口
LotteryService.java
package com.lino.design;/*** @description: 摇号接口*/
public interface LotteryService {/*** 摇号** @param uId 用户编号* @return 摇号结果*/LotteryResult doDraw(String uId);
}
3.2.2 摇号服务接口实现类
LotteryServiceImpl.java
package com.lino.design;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;/*** @description: 摇号接口实现类*/
public class LotteryServiceImpl implements LotteryService {private Logger logger = LoggerFactory.getLogger(LotteryServiceImpl.class);private MinibusTargetService minibusTargetService = new MinibusTargetService();@Overridepublic LotteryResult doDraw(String uId) {// 摇号String lottery = minibusTargetService.lottery(uId);// 发短信logger.info("给用户 {} 发送短信通知(短信):{}", uId, lottery);// 发MQ信息logger.info("记录用户 {} 摇号结果(MQ):{}", uId, lottery);return new LotteryResult(uId, lottery, new Date());}
}
- 从上面的方法实现中可以看到,整体过程包括三部分:摇号、发短信、发 MQ 消息,而这部分都是顺序调用的。
- 除了 摇号 接口调用外,后面的两部分都是非核心主链路功能,而且会随着后续的业务需求发展而不断的调整和扩充,在这样的开发方式下就非常不利于维护。
3.3 单元测试
ApiTest.java
package com.lino.design.test;import com.alibaba.fastjson.JSON;
import com.lino.design.LotteryResult;
import com.lino.design.LotteryService;
import com.lino.design.LotteryServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @description: 单元测试*/
public class ApiTest {private Logger logger = LoggerFactory.getLogger(ApiTest.class);@Testpublic void test() {LotteryService lotteryService = new LotteryServiceImpl();LotteryResult result = lotteryService.doDraw("2765789109876");logger.info("测试结果:{}", JSON.toJSONString(result));}
}
- 测试过程中提供对摇号服务接口的调用
测试结果
17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 给用户 2765789109876 发送短信通知(短信):很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期
17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 记录用户 2765789109876 摇号结果(MQ):很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期
17:06:15.122 [main] INFO com.lino.design.test.ApiTest - 测试结果:{"dateTime":1675760774946,"msg":"很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期","uId":"2765789109876"}
四、改善代码:观察者模式
4.0 引入依赖
<dependencies><dependency><groupId>com.lino</groupId><artifactId>design-19.0-0</artifactId><version>1.0-SNAPSHOT</version></dependency>
</dependencies>
4.1 工程结构
design-19.0-2
|——src|——main|--java|--com.lino.design|--event| |--listener| | |--EventListener.java| | |--MessageEventListener.java| | |--MQEventListener.java| |--EventManager.java|-LotteryService.java|-LotteryServiceImpl.java|--test|--com.lino.design.test|-ApiTest.java
4.2 观察者模式结构图
- 从上图可以分为三大块:事件监听、事件处理、具体的业务流程。
- 另外在业务流程中
LotteryService
定义的是抽象类,因为这样可以通过抽象类将事件功能屏蔽,外部业务流程开发者不需要知道具体的通知操作。
- 另外在业务流程中
- 右下角圆圈图表示的是核心流程与非核心流程的结构。
- 一般在开发中会把主线流程开发完成后,再使用通知的方式处理辅助流程。他们可以是异步的,在 MQ 以及定时任务的处理下,保证最终一致性。
4.3 添加事件监听和管理器
4.3.1 定义事件监听接口
EventListener.java
package com.lino.design.event.listener;import com.lino.design.LotteryResult;/*** @description: 事件监听接口*/
public interface EventListener {/*** 监听事件** @param result 摇号结果*/void doEvent(LotteryResult result);
}
- 接口定义了基本的事件类,这里如果方法的入参信息类型是变化的,可以使用泛型
T
。
4.3.2 短信息事件监听接口实现
MessageEventListener.java
package com.lino.design.event.listener;import com.lino.design.LotteryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @description: 短消息事件监听实现*/
public class MessageEventListener implements EventListener {private Logger logger = LoggerFactory.getLogger(MessageEventListener.class);@Overridepublic void doEvent(LotteryResult result) {logger.info("给用户 {} 发送短信通知(短信):{}", result.getuId(), result.getMsg());}
}
4.3.3 MQ发送事件监听接口实现
MQEventListener.java
package com.lino.design.event.listener;import com.lino.design.LotteryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @description: MQ事件监听实现*/
public class MQEventListener implements EventListener {private Logger logger = LoggerFactory.getLogger(MQEventListener.class);@Overridepublic void doEvent(LotteryResult result) {logger.info("记录用户 {} 摇号结果(MQ):{}", result.getuId(), result.getMsg());}
}
4.3.4 事件处理器
EventManager.java
package com.lino.design.event;import com.lino.design.LotteryResult;
import com.lino.design.event.listener.EventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @description: 事件处理器*/
public class EventManager {Map<Enum<EventType>, List<EventListener>> listeners = new HashMap<>();public EventManager(Enum<EventType>... operations) {for (Enum<EventType> operation : operations) {this.listeners.put(operation, new ArrayList<>());}}public enum EventType {/*** 事件类型*/MQ, Message}/*** 订阅** @param eventType 事件类型* @param listener 监听*/public void subscribe(Enum<EventType> eventType, EventListener listener) {List<EventListener> users = listeners.get(eventType);users.add(listener);}/*** 取消订阅** @param eventType 事件类型* @param listener 监听*/public void unsubscribe(Enum<EventType> eventType, EventListener listener) {List<EventListener> users = listeners.get(eventType);users.remove(listener);}/*** 通知** @param eventType 事件类型* @param result 结果*/public void notify(Enum<EventType> eventType, LotteryResult result) {List<EventListener> users = listeners.get(eventType);for (EventListener listener : users) {listener.doEvent(result);}}
}
- 整个处理的实现上提供了三个主要方法:订阅
subscribe
、取消订阅unsubscribe
、通知notify
。这三个方法分别用于对监听事件的添加和使用。 - 另外因为事件有不同的类型,这里使用率枚举的方式进行处理,也方便让外部在规定下使用事件,而不至于乱传信息。
- 枚举:
EventType.MQ
、EventType.Message
- 枚举:
4.4 摇号抽象类及其实现
4.4.1 业务抽象类
LotteryService.java
package com.lino.design;import com.lino.design.event.EventManager;
import com.lino.design.event.listener.MQEventListener;
import com.lino.design.event.listener.MessageEventListener;/*** @description: 摇号抽象类*/
public abstract class LotteryService {private EventManager eventManager;public LotteryService() {eventManager = new EventManager(EventManager.EventType.MQ, EventManager.EventType.Message);eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener());eventManager.subscribe(EventManager.EventType.Message, new MessageEventListener());}public LotteryResult draw(String uId) {LotteryResult lotteryResult = doDraw(uId);eventManager.notify(EventManager.EventType.MQ, lotteryResult);eventManager.notify(EventManager.EventType.Message, lotteryResult);return lotteryResult;}/*** 执行摇号** @param uId 用户编号* @return 结果*/protected abstract LotteryResult doDraw(String uId);
}
- 使用抽象类的方式定义实现方法,可以在方法中扩展需要的额外调用。
- 并提供抽象类
abstract LotteryResult doDraw(String uId)
,让类的继承者实现。 - 同时,方法的定义使用的是
protected
,也就是保证将来外部的调用方不会调用到此方法,只有调用到draw(String uId)
才能完成事件通知。
- 并提供抽象类
- 此种方式到实现是在抽象类中写好一个基本的方法,在方法中完成新增逻辑到同时,再增加抽象类的使用,而这个抽象的定义会由继承者实现。
- 另外,在构造函数中提供了对事件的定义:
eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener())
。- 在使用时也采用枚举的方式通知使用者,传了哪些类型
eventManager.EventType.Message
,就执行哪些事件通知,按需添加。
4.4.2 业务接口实现类
LotteryServiceImpl.java
package com.lino.design;import java.util.Date;/*** @description: 摇号服务实现* @author: lingjian* @createDate: 2023/2/6 17:02*/
public class LotteryServiceImpl extends LotteryService {private MinibusTargetService minibusTargetService = new MinibusTargetService();@Overrideprotected LotteryResult doDraw(String uId) {// 摇号String lottery = minibusTargetService.lottery(uId);// 结果return new LotteryResult(uId, lottery, new Date());}
}
- 业务流程的实现,没有额外的辅助流程,只有核心流程的处理。
4.5 单元测试
ApiTest.java
package com.lino.design.test;import com.alibaba.fastjson.JSON;
import com.lino.design.LotteryResult;
import com.lino.design.LotteryService;
import com.lino.design.LotteryServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @description: 单元测试*/
public class ApiTest {private Logger logger = LoggerFactory.getLogger(ApiTest.class);@Testpublic void test_draw() {LotteryService lotteryService = new LotteryServiceImpl();LotteryResult result = lotteryService.draw("1000000101010019");logger.info("测试结果:{}", JSON.toJSONString(result));}
}
测试结果
19:45:45.314 [main] INFO c.l.d.event.listener.MQEventListener - 记录用户 1000000101010019 摇号结果(MQ):恭喜你,编码1000000101010019在本次摇号中签
19:45:45.319 [main] INFO c.l.d.e.l.MessageEventListener - 给用户 1000000101010019 发送短信通知(短信):恭喜你,编码1000000101010019在本次摇号中签
19:45:45.398 [main] INFO com.lino.design.test.ApiTest - 测试结果:{"dateTime":1675770345311,"msg":"恭喜你,编码1000000101010019在本次摇号中签","uId":"1000000101010019"}
五、总结:观察者模式
- 从基本的过程式开发,到使用观察者模式面向对象开发,可以看到使用设计模式改造后,拆分出来核心流程与辅助流程的代码。
- 代码中的核心流程一般不会发生经常变化,辅助流程会随着业务的变化而变化,包括营销、裂变和促活等。
- 因此使用设计模式编码就显得非常有必要。
- 观察者模式从结构上满足开闭原则,当需要新增其他的监听事件或修改监听逻辑时,不需要改动事件处理类。
- 观察者模式可能不能控制调用顺序以及需要做一些事件结果的返回操作,所以在使用的过程时需要考虑场景的适用性。
相关文章:
![](https://img-blog.csdnimg.cn/f36cb565c2a34ebcadbd777e4d1526ed.png)
Java设计模式:四、行为型模式-06:观察者模式
文章目录 一、定义:观察者模式二、模拟场景:观察者模式2.1 观察者模式2.2 引入依赖2.3 工程结构2.4 模拟摇号2.4.1 摇号服务接口2.4.2 摇号返回结果类 三、违背方案:观察者模式3.0 引入依赖3.1 工程结构3.2 添加摇号接口和实现3.2.1 摇号服务…...
![](https://csdnimg.cn/release/blog_editor_html/release2.3.6/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=N7T8)
vscode中讨厌的蓝色波浪线的去除小trick和原理
问题描述 不小心“设置同步”时和远程电脑的合并(merge)了,然后就出现了这个问题!烦死了!!! 大概是这个样子: 解决办法 站在了巨人的肩膀上,在下图位置输入这样一行参数&…...
![](https://img-blog.csdnimg.cn/ef2fbed1962e4b4e98ef54d4d6e25861.png)
开发工具——IDE安装 / IDEA子module依赖导入失败编译提示xx找不到符号 / IDEA在Git提交时卡顿
近期换了工作电脑,公司的IT团队不够给力,不能复制电脑系统,所以又到了需要重装IDE配置开发环境的时候了;在安装和导入Java编译器IDEA的时候遇到一些"棘手"问题,这里整理下解决方法以备不时之需; …...
![](https://img-blog.csdnimg.cn/5a7ae9cebe04480785b7b18d45b31bfa.png)
AcWing 787:归并排序
【题目来源】https://www.acwing.com/problem/content/789/【题目描述】 给定你一个长度为 n 的整数数列。 请你使用归并排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。【输入格式】 输入共两行,第一行包含整数 n。 第二行包含 n 个整数&#…...
![](https://www.ngui.cc/images/no-images.jpg)
SeamlessM4T—Massively Multilingual Multimodal Machine Translation
本文是LLM系列的文章,针对《SeamlessM4T—Massively Multilingual & Multimodal Machine Translation》的翻译。 SeamlessM4T:大规模语言多模态机器翻译 摘要1 引言2 多模态翻译的社会技术维度2.12.22.3 3 SeamlessAlign:自动创建语音对…...
![](https://www.ngui.cc/images/no-images.jpg)
Python数据分析-Numpy
Numpy 个人笔记,仅供参考,谢谢 导入 import numpy import numpy as np from numpy import *Numpy数组对象 引入 # 让列表1 a [1,2,3,4],b [4,5,6,7] [x1 for x in a] # 实现ab a b > [1,2,3,4,5,6,7,8] [x y for (x,y) in zip(a,b)] -------…...
![](https://img-blog.csdnimg.cn/5bf6926d23f2401ba6f95ffd040179a3.png#pic_center)
【真题解析】系统集成项目管理工程师 2023 年上半年真题卷(案例分析)
本文为系统集成项目管理工程师考试(软考) 2023 年上半年真题(全国卷),包含答案与详细解析。考试共分为两科,成绩均 ≥45 即可通过考试: 综合知识(选择题 75 道,75分)案例分析(问答题 4 道,75分)案例分析(问答题*4)试题一试题二试题三试题四案例分析(问答题*4) …...
![](https://img-blog.csdnimg.cn/06cb26df0c694336a59b08170782be09.png)
【GAMES202】Real-Time Global Illumination(in 3D)—实时全局光照(3D空间)
一、SH for Glossy transport 1.Diffuse PRT回顾 上篇我们介绍了PRT,并以Diffuse的BRDF作为例子分析了预计算的部分,包括Lighting和Light transport,如上图所示。 包括我们还提到了SH,可以用SH的有限阶近似拟合球面函数ÿ…...
![](https://img-blog.csdnimg.cn/a508c51abb7a4c97ad38894b11d57a95.png)
金蝶云星空二开,公有云执行SQL
功能背景; 金蝶公有云执行sql工具,因官方为云部署 用户无法连接数据库增删改查 天梯维护网页仅支持增删改操作 二开单据已支持根据sql动态生成单据体 与sql可视化界面操作一致 功能实现及场景: 1.可用于公有云执行sql类操作 2.私有云部署&am…...
![](https://www.ngui.cc/images/no-images.jpg)
JAVA String 二维的字符串数组 String[][]
String[][] 表示一个二维的字符串数组,也可以称为字符串矩阵。它是由多个一维的字符串数组组成的,每个一维数组都表示矩阵中的一行。 在 Java 中,可以使用如下方式声明和初始化一个二维字符串数组: String[][] matrix new Strin…...
![](https://img-blog.csdnimg.cn/430fd5b6362d48c281827ddc6a56789d.gif)
【Unity3D赛车游戏优化篇】【九】Unity中如何让汽车丝滑漂移?
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:Uni…...
![](https://img-blog.csdnimg.cn/6b646dc57361425b877b9fc674c41afc.png)
el-dialog设置高度、使用resetFields清除表单项无效问题
初学者容易踩坑的的el-dialog、el-form问题 1. el-dialog设置高度2. el-form中表单项对不齐3. 使用resetFields清除表单项无效 1. el-dialog设置高度 在el-dialog中里面添加一个div设置固定高度,或者限制最小的高度。 <el-dialogtitle"选择图标"v-mod…...
![](https://www.ngui.cc/images/no-images.jpg)
MySql切换到达梦数据库,各种问题解决记录
参考官方文档: https://eco.dameng.com/document/dm/zh-cn/sql-dev/practice-func.html 1. 关键字导致的报错:如ref,comment,top,domain等 Error -2007: 第 1 行, 第 117 列[ref]附近出现错误: 语法分析出错解决方案:修改关键字即可 2. 查…...
![](https://img-blog.csdnimg.cn/c4d65a5b0ef4479685b1d9691fae6fc6.jpeg#pic_center)
2023开学礼山东财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉新财经图书馆
2023开学礼山东财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉新财经图书馆...
![](https://www.ngui.cc/images/no-images.jpg)
vscode中使用eslint+prettier的配置
eslintprettiervscode自动保存用起来感觉非常爽快。 一般来说,安装eslintprettier插件,然后使用相关脚手架配套的eslintprettier,无法自动格式代码,每次都需要执行格式化命令。这里贴出保存自动格式化代码的setting.json。 // .…...
![](https://img-blog.csdnimg.cn/6a643e6be3fc4552bcace756924718e1.png)
HTML 标签讲解
HTML 标签讲解 HTML 语言结构根元素元数据元素主体根元素大纲元素文本内容语义化内联文本图像与多媒体编辑标识table表格内容表单内容table表单 HTML 语言结构 Markup (标记、标签)用来容纳和描述内容 严格意义上,标签是指开始标签…...
![](https://www.ngui.cc/images/no-images.jpg)
ue5 小知识点 ue的world type,pie editor game
说明以该命令行模式启动游戏的前提下的两个问题: 1.WITH_EDITOR中的代码会被编译 2.由于没有在编辑器中(即没有打开虚幻编辑器),所以GIsEditor为false WITH_EDITOR和WITH_EDITORONLY_DATA的区别 在论坛中找到的答案: WITH_EDITORONLY_DAT…...
![](https://www.ngui.cc/images/no-images.jpg)
两表union 如何保证group by 字段唯一
当要计算的指标可能来源多个表时,可能会使用到union all把不同的表中计算的指标合起来。关于union all使用条件:两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致) 另外,回顾union和uni…...
![](https://img-blog.csdnimg.cn/7fd1da237f87401b8d4a9194d820e030.png#pic_center)
【⑰MySQL】 变量 | 循环 | 游标 | 处理程序
前言 ✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL变量 | 循环 | 游标 | 处理程序的分享✨ 目录 前言1. 变量1.1系统变量1.2 用户变量 2. 定义条件与处理程序2.1 案例分析2.2 定义条件2.3 定义处理程序2.4 案例解决 3. 流程控制3.1 分支结构3.2 循环结构3.3 跳转…...
![](https://img-blog.csdnimg.cn/41b6bbc55a804632994fae64dbaca52a.png)
如何在arXiv上发表一篇文章
目录 1. 初始信息确认2. 提交论文文件3. 论文编译结果4. 补充论文信息5. 总览 1. 初始信息确认 版权问题需要根据个人情况选择。 IEEE, Elsevier, BioMed Central, 这几个出版商都允许在投稿之前挂文章到arXiv下。通常是选择: arXiv.org perpetual, non-exclusive l…...
![](https://www.ngui.cc/images/no-images.jpg)
重要性采样
重要性采样 前言 离散型随机变量 X X X,我们可以通过以下方法求取其期望: 直接计算法,需要知道概率分布: E ( X ) ∑ x ∈ X [ p ( x ) ⋅ x ] \mathbb{E}(X)\sum_{x\in X}\left[p(x)\cdot x\right] E(X)x∈X∑[p(x)⋅x] 采…...
![](https://img-blog.csdnimg.cn/img_convert/51334f5d0a731f29373821b6180f5d20.webp?x-oss-process=image/format,png)
说说Omega架构
分析&回答 Omega架构我们暂且称之为混合数仓。 什么是ECS设计模式 在谈我们的解法的时候,必须要先提ECS的设计模式。 简单的说,Entity、Component、System分别代表了三类模型。 实体(Entity):实体是一个普通的对象。通常,…...
![](https://img-blog.csdnimg.cn/f5b4099795e7494ba7977c1f7101b6e3.png)
高忆管理:光刻胶概念强势拉升,同益股份、格林达涨停
光刻胶概念5日盘中强势拉升,截至发稿,同益股份、格林达涨停,波长光电、晶瑞电材涨超7%,容大感光涨逾5%,华懋科技、茂莱光学、苏大维格、南大光电等均走强。 音讯面上,据新加坡《联合早报》网站9月2日报导&…...
![](https://img-blog.csdnimg.cn/73208c83354a49e993d6b1571b1196f0.png#pic_center)
计算机图形学线性代数相关概念
Transformation(2D-Model) Scale(缩放) [ x ′ y ′ ] [ s 0 0 s ] [ x y ] (等比例缩放) \left[ \begin{matrix} x \\ y \end{matrix} \right] \left[ \begin{matrix} s & 0 \\ 0 & s \end{matrix} \right] \left[ \begin{matrix} x \\ y \en…...
![](https://img-blog.csdnimg.cn/7ab6d2849187466fb56cbabc1b36ea3a.jpeg#pic_center)
开源PHP 代挂机源码,可对接QQ、网易云、哔哩哔哩、QQ空间、等级加速等等
本程序运行环境PHP5.6 95dg/config.php修改系统数据库 进入数据库绑定 你搭建的域名即可 部署完成 进入数据库 找到data 输入绑定授权域名即可进行授权打开此网站 网站是无对接接口 需要您自行找对接接口即可 本源码有点乱 有实力的铁铁 可以修改一下哦!...
![](https://img-blog.csdnimg.cn/ea996b7096b441e6aa6a8003217b7f03.png)
【仿牛客论坛java项目】第五章 Kafka,构建TB级异步消息系统:阻塞队列、Kafka入门、Spring整合Kafka、发送系统通知、显示系统通知
这里写自定义目录标题 一、阻塞队列简单的阻塞队列测试案例总结阻塞队列 二、Kafka入门1、基础知识Kafka术语消息队列实现方式两种 2、配置3、启动全部命令启动 zookeeper 服务器再启动 kafka 服务器创建Topic关闭 4、总结Kafka的特点Kafka的术语 三、 Spring整合Kafka导入依赖…...
![](https://img-blog.csdnimg.cn/8af40acdfef640048ce7e3941879caa3.png)
【AIGC专题】Stable Diffusion 从入门到企业级实战0401
一、概述 本章是《Stable Diffusion 从入门到企业级实战》系列的第四部分能力进阶篇《Stable Diffusion ControlNet v1.1 图像精准控制》第01节, 利用Stable Diffusion ControlNet Inpaint模型精准控制图像生成。本部分内容,位于整个Stable Diffusion生…...
![](https://img-blog.csdnimg.cn/8873f302023b433bb4daa25655d6b7aa.png)
Matlab信号处理1:模拟去除信号噪声
由于工作内容涉及信号系统、信号处理相关知识,本人本硕均为计算机相关专业,专业、研究方向均未涉及信号相关知识,因此需进行系统地学习。之前已将《信号与系统》快速过了一遍,但感觉较抽象且理解较浅显。在此系统地学习如何使用Ma…...
![](https://img-blog.csdnimg.cn/e0879e8cbbd24e0691bff3fa639d0428.png)
Bootstrap的行、列布局设计(网络系统设计)
目录 00-基础知识01-等宽列布局02-指定某一列的宽度03-根据内容自动改变列的宽度04-五种预定义列宽度 .col、.col-sm-*、.col-md-*、.col-lg-*、.col-xl-*05-不同视口宽度按不同的分列方案划分06-删除列内容的盒模型的外边距07-超过12列怎么办?08-重新排列各列的顺序…...
![](https://img-blog.csdnimg.cn/9e9a2e381994401b99ee66d8c13f7a1e.png)
1.1 计算机网络在信息时代中的作用
思维导图: 正文: 我的理解: 这段话是一本书或课程的第一章简介,它的目的是为读者或学生提供一个关于计算机网络基础知识的框架或大纲。 首先,它强调了这章是整本书的一个概览,会先介绍计算机网络在信息时…...
![](/images/no-images.jpg)
网站建设找哪些平台/郑州网络营销哪家正规
最近客户不知道从哪里拿来了很多MP4,上传到系统后无法在网页上直接用H5播放。 用格式工厂将编码改为H264也播放不了,无奈之下,查询了一下网上的资料,用ffmpeg自己写了上传文件的转码功能。 首先,去 https://ffmpeg.zer…...
![](/images/no-images.jpg)
张店网站建设方案/seo搜索推广
IPHostname 172.16.100.251nginx01代理 apiverser172.16.100.252nginx02代理 apiverser172.16.100.254apiserver01.xxx.comVIP地址,主要用于nginx高可用确保nginx中途不会中途172.16.100.51k8s-etcd-01etcd集群节点,默认关于ETCD所有操作均在此节点上操作172.16.100.52k8s-etcd…...
![](https://img-blog.csdnimg.cn/img_convert/ca055397a3e3db9a8a77ad1db4516ab6.gif)
网站建设胡菘/如何制作网页最简单的方法
欢迎关注我的公众号是【CodeAllen】,关注回复【1024】获取资源 程序员技术交流①群:736386324 ,程序员技术交流②群:371394777 物理地址是一种标识符,用来标记网络中的每个设备。同现实生活中收发快递一样…...
![](/images/no-images.jpg)
公司做网站走什么费/淘大象排名查询
最近在搞Redis所以装了个virtualbox的ubuntu的虚拟机, redis不是在ubuntu上. 因为需要使用本机客户端访问redis服务,所以需要配置虚拟机和本地机器的双向访问,所以就用到了桥接的上网方式。 废话不多说具体的配置如下: 配置虚拟机IP地址 g…...
![](https://img-blog.csdnimg.cn/img_convert/47c604e71559bf4a5f17404083e1b234.png)
郑州网站建设seo优化/百度app营销软件
首先在你项目app下的build.gradle中配置: dependencies { debugImplementation ‘com.squareup.leakcanary:leakcanary-android:1.6.2’ releaseImplementation ‘com.squareup.leakcanary:leakcanary-android-no-op:1.6.2’ // 可选,如果你使用支持库的fragmen…...
![](https://img-blog.csdnimg.cn/img_convert/dd81ea51508fa597f9c1da881a1ff649.png)
做系统下载网站建设/网站优化助手
【阿里天猫、蚂蚁、钉钉面试专题题目加答案】 不会做别着急:文末有答案以及视频讲解,架构师资料 1. junit用法,before,beforeClass,after, afterClass的执行顺序 2. 分布式锁 3. nginx的请求转发算法,如何配置根据权重转发 4…...