guava笔记12-EventBus

JDK从1.0开始就存在Observer和Observable,可以用来完成生产者/消费者这样的需求。其实也是观察者模式的实现。

 

Guava使用EventBus来实现类似的功能,但是用起来比Observer更方便。

直接拿代码来讲解吧。

//定义消息实体

class EventObj{

private String info;

public EventObj(String info){

this.info = info;

}

public String getInfo(){

return info;

}

}

 

//消息订阅者

class MySubcribler{

@Subscribe

public void recordInfo(EventObj eventObj){

System.out.println("first subscribe:"+eventObj.getInfo());

}

@Subscribe

public void recordInfo2(EventObj eventObj){

System.out.println("second subscribe:"+eventObj.getInfo());

}

@Subscribe

public void recordDeadEvent(DeadEvent deadEventObj){// 没有订阅者的消息一律为DeadEvent

System.out.println("dead event:"+deadEventObj.getEvent());

}

}

 

@Test

public void testEventBus(){

EventBus eventBus = new EventBus();

 

eventBus.register(new MySubcribler());//注册订阅者,可以注册多个

 

EventObj eo = new EventObj("event info");

eventBus.post(eo);  //投递消息

 

eventBus.post("no subscriber"); //投递消息,该类型的消息没有订阅者

eventBus.post(9999); //投递消息,该类型的消息没有订阅者

 

}

 

运行上面的Test,结果如下:

second subscribe:event info

first subscribe:event info

dead event:no subscriber

dead event:9999

 

可以看到,EventBus用起来非常简单。

对于subscriber而言,只需要定义接到消息后如何处理即可,采用@Subscribe注解来表示。

 

对于publisher方而言,分为“注册订阅者”和“消息投递”两个步骤。

注册订阅者就是注册所有的subscriber。

消息投递就是发送一条消息,所有的subscriber会收到这条消息,但是只有参数类型跟消息类型一致的subscriber方法才会处理这条消息。

另外,有一种特殊的消息类型DeadEvent,任何没有subscriber接收的消息类型,都会被转换为DeadEvent。所有我们可以定义一个处理方法,接收DeadEvent类型的消息,一般可用于打印日志,或者排除问题。

 

消息监听具有继承的特性,如果订阅者A监听了TypeA类型的消息,那么他也会自动监听所有TypeA的子类型的消息。

 

Spring Boot集成Guava EventBus并注入Bean 目录前言目标事件总线介绍概览图代码实践基础类IEventBusAbstractSpringEventBusIEventConsumer业务类实现事件总线投递消息消费者 前言 基于事件总线的方式开发,可以使我们代码更加简洁,而且解耦 Guava的EventBus是个轻量级的事件总线,而且事件间可以相互隔离,所以更加灵活多变 本文不讲EventBus的具体功能,只考虑应用场景 目标 在Spring中集成Guava的EventBus,并友好的注入Bean 消费者只需要实现接口,即可接收事件消息 生产者只需要 阅读详情

相关推荐

选择 Guava EventBus 还是 Spring Framework ApplicationEvent

如果正在开发Spring应用程序,或者需要与Spring框架的其他功能集成,那么可以使用Spring的ApplicationEvent来实现事件驱动的架构。Spring Framework 的 ApplicationEvent 是 Spring 框架提供的一种事件机制,用于实现发布和订阅事件的功能。它提供了一种简单而有效的机制,用于解耦组件之间的通信。通过使用 Spring 的 ApplicationEvent,开发人员可以实现更灵活、可扩展的应用程序架构,并在应用程序中使用事件驱动的编程范式。

程序员野蛮成长 1535

Guava入门~EventBus~DeadEvents

当调用EventBus.post(event),事件没有订阅者,则会封装成DeadEvent。

小强快跑~~ 343

Guava EventBus(事件总线)

EventBus是Guava的事件处理机制,是设计模式中观察者模式(生产/消费者编程模型)的优雅实现。

Jinlong_Xu的博客 1806

Guava系列之EventBus

EventBus是Guava中实现的用于发布/订阅模式的事件处理组件,它是设计模式中观察者模式的优雅实现,关于观察者模式可以看一下我的另一篇博客:设计模式学习-观察者模式 EventBus简化了观察者模式,无须创建复杂的类和接口层次结构 EventBus的基本用法 1、定义事件对象 public class Event { private String message; public Event(String message){ this.message = message;

果子爸聊技术 1万+

guava之EventBus

观察者模式 这个讲的地方特别多,随便百度就好,这里随意贴了一个别人的链接 http://c.biancheng.net/view/1390.html 解决的问题 观察者模式解决的场景就是:解耦。将一些和主业务逻辑不强相关的逻辑可以解耦出来,统一处理。 Eventbus EventBus提供了两种观察方式:同步和异步 同步方式:post()和对应的事件处理器EventHandler逻辑在同一个线程执行。 异步方式:事件处理器EventHandler逻辑在指定线程池中执行,和post()事件的线

sinat_14913533的博客 2021

深入解析SerDes系统中的时钟数据恢复电路(CDR)——基于Cadence的PLL/Bang-Bang/PS-PI架构实现与仿真

本文深入解析SerDes系统中的时钟数据恢复电路(CDR),重点探讨基于Cadence平台的PLL、Bang-Bang和PS-PI三种架构的实现与仿真。通过详细的技术对比和工程实践案例,揭示CDR在高速串行通信中的关键作用,并提供TSMC 28nm工艺下的优化策略与故障排查经验,助力工程师应对10Gbps以上SerDes设计挑战。

weixin_29202687的博客 249

Guava学习笔记【12】:EventBus

EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。   Observer模式是比较常用的设计模式之一,虽然有时候在具体代码里,它不一定叫这个名字,比如改头换面叫个Listener,但模式就是这个模式。手工实现一个Observer也不是...

azhegps的博客 996

Ollama本地大模型部署指南:从核心原理到实战避坑

大语言模型(LLM)作为人工智能领域的核心技术,通过海量数据训练获得强大的语言理解和生成能力。其工作原理基于Transformer架构,通过自注意力机制处理序列数据,在文本生成、代码编写和对话系统等场景展现出巨大价值。随着开源模型的普及,本地部署成为关注焦点,它解决了数据隐私和定制化需求,但面临环境配置和资源管理的挑战。Ollama作为开源工具,通过封装模型格式和统一API,简化了本地部署流程,支持GPU加速和性能调优,让开发者能够快速集成到IDE和自动化脚本中,实现高效的本地AI应用部署。

weixin_30915951的博客 451

google Guava之EventBus

EventBus基本用法 1. 创建Listener 2. 创建EventBus并发送消息 Listener之间的继承关系 Subscriber 不同类型参数的Subscribe event 继承关系的event DeadEvent EventBus之异常处理 EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现,在应...

栋先生 1万+

vcs中systemverilog和c/c++联合仿真

前言 systemverilog中,可以通过DPI、PLI来与外部其它语言的程序进行交互。PLI又分为三类,TF、ACC和VPI,可以认为是PLI技术的三代演进: 其中VPI(PLI3.0)是TF/ACC的一个超集,目前使用的PLI基本上都是VPI。 与PLI技术相独立的另一个技术就是DPI,DPI技术简化了systemverilog与foreign language的交互步骤,对于开发者相对友好,所以使用相对广泛一些。 本文不对DPI中程序调用/数据交互展开讨论(这部分可以参考绿皮书..

kevindas的博客 1万+

初识colmap

COLMAP是一款开源的计算机视觉软件,主要用于从一系列二维图像中进行三维重建。它全称为“COLLISION-MAPping”,是一个高度集成的Structure-from-Motion (SfM) 和 Multi-View Stereo (MVS) 管道工具,由斯坦福大学开发和维护。COLMAP的主要功能包括特征检测与匹配、增量式SfM、多视图立体匹配以及优化。它能够从无序或有序的二维照片集合中恢复出三维场景的几何结构(点云)以及每张图像对应的相机姿态。

Hhsjehejj的博客 5551

Guava 12:Guava EventBus源码剖析

一、架构速读 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的。设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦。EventBus不是通用型的发布-订阅实现,不适用于进程间通信。 架构图如下: 。 二、简单使用 步骤如下: 1.构造一个事件总线 2.构造一个事件监听器 3.把事件监听器注册到事件总线上 4.事件总线发布事件,触发监...

博客园搬家测试账号 901

jetson agx orin开箱及接口介绍

jetson agx orin开箱及接口介绍

qq_58728069的博客 1万+

Google Guava EventBus(事件总线)

       EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus非常优雅使用起来也非常的简单,这个可不是吹的是真的非常的简单。        EventBus内部实现原理不复杂(源码不复杂,强烈推荐大家去看下)。我们简单的...

旧路 2万+

焊缝缺陷智能检测:基于 YOLO 的工业质检系统实战

从焊缝缺陷数据集的构建到模型训练,从桌面检测界面到缺陷统计输出,本文覆盖了一套工业焊缝质检系统的完整路线。这个场景的核心难点在数据层面——气孔和裂纹这类小目标的标注质量直接决定了模型的最终表现。建议先在开源数据集上跑通全链路,确认 mAP 达到可接受的水平后,再通过补充特定类型的小目标数据和提升输入分辨率来做精度优化。工业场景中,漏检一个气孔的成本和误报一个假阳性的成本不一样——根据对两类成本的承受力,调整置信度阈值来找到业务上的最佳平衡点。

m0_71589036的博客 202

AD快速上手笔记

本文详细介绍了使用Altium Designer从零创建PCB项目全流程:新建工程、绘制原理图(元件放置、连线、电源端口)、编译检查、生成PCB、布局布线(含铺铜)、DRC检查及输出Gerber与钻孔文件。重点强调了库选择、参数修改、层切换、铺铜设置和生产文件导出规范,确保设计无误,便于顺利下单生产。

qq_53529450的博客 42

Guava之eventbus

Guava简介 如同boost之于c++,guava也几乎成为了java编程中不可或缺的一部分。guava中涵盖了很多有意思的东西,比如在java中使用函数式编程;新的数据结构,如bimap等等。总之,guava让写java程序成为一件更美好的事情。guava中还有很多很多有意思的东西,可以去guava的官方网站上探个究竟。guava 本文试图通过分析guava的eventbus的源代

奔跑的乌龟的专栏 2810

Windows 11 安装 JDK 21:下载、安装、配置环境变量、验证

本文详细介绍了在 Windows 11 系统中安装 JDK 21 的完整流程,包括从 Oracle 官网下载压缩包、解压至自定义目录、配置 JAVA_HOME 与 Path 环境变量,并验证安装是否成功。文章推荐使用 ZIP 压缩包而非安装程序,以实现绿色便携、多版本共存等优势,并通过一个包含 Java 21 新特性的示例程序进行功能验证,适合开发者快速上手。

寒水馨 · 轻量级技术文档 · hanshuixin.org 2518

Guava EventBus 使用

Guava EventBus 使用 EventBus 是 Google Guava 提供的消息发布-订阅类库,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现,消息通知负责人通过 EventBus 去注册/注销观察者,最后由消息通知负责人给观察者发布消息。 对于事件监听和发布订阅模式,EventBus 是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。 基本用法 创建事件...

Star's Tech Blog 3398

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Guava EventBus 使用详解

EventBus是Google Guava库中的发布-订阅模式组件,支持同步和异步事件处理。核心优势包括解耦通信、类型安全和简洁的注解驱动配置。主要使用步骤:定义事件类、创建@Subscribe标注的订阅者方法、通过EventBus.post()发布事件。高级功能涵盖异步处理(AsyncEventBus)、死信事件捕获、自定义异常处理和订阅优先级控制。最佳实践建议:生产环境需配置线程池和异常监控、合理设计事件粒度、确保处理幂等性。典型应用场景包括电商系统中的订单状态变更、库存管理等跨模块协作。EventBu

油墨香^-^的博客 1273

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Guava 之 EventBus

在 Curator 官网(http://curator.apache.org/)有这么一张图片: 这句话足以说明 Guava 的地位。这次就来看一个 Guava 中有点意思的EvenBus。 EvenBus是 Guava 中 Pub/Sub 模式的轻量级实现。平时开发如果我们要实现自己的 Pub/Sub 模型,要写不少类,设计也挺复杂,对业务代码也有一定的侵入,但是在使用了Event...

【欢迎关注公众号:冬瓜白】 1434

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Guava EventBus详解

EventBus是google的Guava库中的一个处理组件间通信的事件总线,它基于发布/订阅模式,实现了多组件之间通信的解耦合,事件生产方和事件消费方实现解耦分离,提升了通行的简介性。当一个事件的发送(事件生产方),需要触发很多事件消费方的时候,我们通常会在事件产生方中,分别的去调用那些事件消费方,这样比较繁琐、复杂,业务也不清晰。事件的产生方与事件的消费方,产生的极大的耦合,如果我们要改动某一个事件消费方,很可能要改动事件的产生方。/*** @desc 事件总线配置*/@Bean。

抽象的螺旋 2264

java guava eventbus_Guava-EventBus使用笔记

Guava EventBus 的作用个人对EventBus的理解是: 它是一个事件(消息)发布订阅框架,在我们的应用中可以处理一些异步任务。先通过代码来看下它的简单用法:packagenet.leokong.test;importcom.google.common.eventbus.EventBus;importcom.google.common.eventbus.Subscribe;/**...

weixin_42185419的博客 387

Guava教程-EventBus

Guava为我们提供了事件总线EventBus库,它是事件发布-订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计。事件Guava 发布-订阅模式 中传递的事件,是一个普通的POJO类。 class OrderEvent { private String message; public OrderEvent(String mess

Ricky 6943

、【Guava】EventBus 源码解析

EventBus 采用发布订阅者模式的实现方式,它实现了泛化的注册方法以及泛化的方法调用,另外还考虑到了多线程的问题,对多线程使用时做了一些优化,观察者模式都比较熟悉,这里会简单介绍一下,重点介绍的是如何泛化的进行方法的注册以及调用,还有在单个线程和多线程不同的实现方式。#发布订阅者模式Guva中EventBus的机制就是观察者模式,因此符合观察者模式的一般结构:监听者:监听来自被监听者的变更事件,完成动作变更被监听者:发送变更事件给监听者,使监听者监听到变更事件后,完成动作变更。

成年老猿的专栏 1493
上一篇: guava笔记11-Hashing
下一篇: guava笔记13-Math
leadtoit
博客等级 码龄17年 2粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值