key generator

http://hi.baidu.com/jonsonda/blog/item/e5a0a712551fb5cdc2fd78f3.html

序列键生成器与单例及多例模式
2007-10-25 02:07
在一个关系数据库中,所有的数据都是存储在表里,而每一个表都有一个主键(Primary Key)。对大多数的用户输入数据来讲,主键需要由系统以序列号方式产生。比如一个餐馆的贩卖系统需要一个序列号给每天开出去的卖单编号,这个序列号码就应当存放到数据库里面。每当发出序列号码的时候,都应当从数据库读取这个号码,并更新这个号码。

为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在请求一个键值时,首先将数据库中的键值更新为下一个可用值,然后将旧值提供给客户端。这样万一出现运行中断的话,最多就是这个键值被浪费掉。

与此相对的是记录式键值存储办法。也就是说,键值首先被返还给客户端,然后记录到数据库中去。这样做缺点明显,因此不要使用这种登记式的存储办法。

预定式的存储办法可以每一次预定多个键值(也即一个键值区间),而不是每一次仅仅预定一个值。由于这些值都是一些序列数值,因此,所谓一次预定多个值,不过就是每次更新键值时将键值增加一个大于1的数目。

这个序列键管理器可以设计成一个单例类。

下面从一个最简单的情况出发,逐渐将问题的复杂性提高,直到给出具有实用价值的解决方案为止。

方案一:没有数据库的情况
package com.javapatterns.keygen.ver1;

public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private int key = 1000;

private KeyGenerator() {}

public static KeyGenerator getInstance() {
return keygen;
}

public synchronized int getNextKey() {
return key++;
}
}

package com.javapatterns.keygen.ver1;

public class Client {
private static KeyGenerator keygen;

public static void main(String[] args) {
keygen = KeyGenerator.getInstance();
System.out.println("key = " + keygen.getNextKey());
System.out.println("key = " + keygen.getNextKey());
System.out.println("key = " + keygen.getNextKey());
}
}
这一设计基本上实现了向客户端提供键值的功能,但是也有明显的缺点。由于没有数据库的存储,一旦系统重新启动,KeyGenerator都会重新初始化,这就会造成键值的重复。为了避免这一点,就必须将每次的键值存储起来,以便一旦系统和重启时,可以将这个键值取出,并在这个值的基础上重新开始。

方案二:有数据库的情况

package com.javapatterns.keygen.ver2;

public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();

private KeyGenerator() {}

public static KeyGenerator getInstance() {
return keygen;
}

public synchronized int getNextKey() {
return getNextKeyFromDB();
}

private int getNextKeyFromDB() {
String sql1 = "UPDATE KeyTable SET keyValue = keyValue + 1 ";
String sql2 = "SELECT keyValue FROM KeyTable";
//execute the update SQL
//run the SELECT query
//这里只是示意性地返回一个数值
return 1000;
}
}
Client类的代码与方案一类似,不再重复。

在接到客户端的请求时,这个KeyGenerator每次都向数据库查询键值,将新的键值登记到表里,然后将查询的结果返还给客户端。上面的代码中,只给出了SQL语句,为了将注意力集中在系统设计上而并没有给出执行这两行语句的JDBC代码。

方案三:键值的缓存方案

每一次都进行键值的查询,有必要吗?毕竟一个键的值只是一些序列号码,与其每接到一次请求就查询一次,然后向客户端提供这一个值,不如在一次查询中一次性地预先登记多个键值,然后连续多次地向客户端提供这些预订的键值。这样一来,不是节省了大部分不必要的数据库查询操作吗?

这就是键值的缓存机制。当KeyGenerator每次更新数据库中的键值时,它都将键值增加。与方案二不同之处是,键值的增加值不是1而是更多。下面的例子中,键值的增加值是20.为了存储所有的与键有关的信息,特地引进一个KeyInfo类,这个类除了存储与键有关的信息外,还提供了一个retrieveFromDB()方法,向数据库查询键值。

package com.javapatterns.keygen.ver3;

public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private static final int POOL_SIZE = 20;
private KeyInfo key ;

private KeyGenerator() {
key = new KeyInfo(POOL_SIZE);
}

public static KeyGenerator getInstance() {
return keygen;
}

public int getNextKey() {
return key.getNextKey();
}
}


package com.javapatterns.keygen.ver3;

class KeyInfo {
private int keyMax;
private int keyMin;
private int nextKey;
private int poolSize;

public KeyInfo(int poolSize) {
this.poolSize = poolSize;
retrieveFromDB();
}

public int getKeyMax() {
return keyMax;
}

public int getKeyMin() {
return keyMin;
}

public synchronized int getNextKey() {
if (nextKey > keyMax) {
retrieveFromDB();
}
return nextKey++;
}

private void retrieveFromDB() {
String sql1 = "UPDATE KeyTable SET keyValue = keyValue + "
+ poolSize + " WHERE keyName = 'PO_NUMBER'";
String sql2 = "SELECT keyValue FROM KeyTable WHERE KeyName = 'PO_NUMBER'";
// execute the above queries in a transaction and commit it
// assume the value returned is 1000
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
} package com.javapatterns.keygen.ver3;


public class Client {
private static KeyGenerator keygen;

public static void main(String[] args) {
keygen = KeyGenerator.getInstance();
for (int i = 0 ; i < 25 ; i++) {
System.out.println("key(" + (i+1)
+ ")= " + keygen.getNextKey());
}
}
}
现在,这个键值生成器已经具有如下的功能:在整个系统是唯一的,能将生成的键值存储到数据库中,以便在系统重新启动时也能够继续键值的生成,而不会造成键值上的重复。

这本来已经足够好了,但是还有一点值得设计师考虑改进的是,一般的系统都不会只有一个键值,而是有多个键值需要生成。怎么让上面的设计适用于任意多个键值的情况呢?

首先,由于KeyGenerator是单例类,因此,给出多个KeyGenerator的实例并无可能,除非将之推广为多例类。

其次,虽然KeyGenerator是单例类,但KeyGenerator仍然可以在内部使用一个聚集管理多个键值。换言之,可以使用一个本身是单例对象的聚集对象,配合上合适的接口达到目的。

方案四:有缓存的多序列键生成器

此方案是对方案三的改进,引进了一个聚集来存储不同序列键信息的KeyInfo对象。

package com.javapatterns.keygen.ver4;

import java.util.HashMap;

public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private static final int POOL_SIZE = 20;
private HashMap keyList = new HashMap(10);

private KeyGenerator() {}

public static KeyGenerator getInstance() {
return keygen;
}

public int getNextKey(String keyName) {
KeyInfo keyinfo;
if ( keyList.containsKey(keyName) ) {
keyinfo = (KeyInfo) keyList.get(keyName);
System.out.println("key found");
} else {
keyinfo = new KeyInfo(POOL_SIZE, keyName);
keyList.put(keyName, keyinfo);
System.out.println("new key created");
}
return keyinfo.getNextKey();
}
}

package com.javapatterns.keygen.ver4;

class KeyInfo {
private int keyMax;
private int keyMin;
private int nextKey;
private int poolSize;
private String keyName;

public KeyInfo(int poolSize, String keyName) {
this.poolSize = poolSize;
this.keyName = keyName;
retrieveFromDB();
}

public int getKeyMax() {
return keyMax;
}

public int getKeyMin() {
return keyMin;
}

public synchronized int getNextKey() {
if (nextKey > keyMax) {
retrieveFromDB();
}
return nextKey++;
}

private void retrieveFromDB() {
String sql1 = "UPDATE KeyTable SET keyValue = keyValue + "
+ poolSize + " WHERE keyName = '"
+ keyName + "'";
String sql2 = "SELECT keyValue FROM KeyTable WHERE KeyName = '"
+ keyName + "'";
// execute the above queries in a transaction and commit it
// assume the value returned is 1000
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
}

从上面的代码可以看出,每当getNextKey()被调用时,这个方法都会根据缓冲区的大小和已经用过的键值来判断是否需要更新缓冲区。当缓冲区被更新后,KeyInfo会持有已经向数据库预定过的20个序列号码,并不断向调用者顺序提供这20个号码。等这20个序列号用完之后,KeyInfo对象就会向数据库预定后20个新号码。
当然,如果系统被重新启动,而缓冲区中的号码并没有用完的话,这些没有完的号码就不会再次被使用了。系统重新启动之后,KeyInfo对象会重新向数据库预定下面的20个号码,并向外界提供这20个号码。

package com.javapatterns.keygen.ver4;

public class Client {
private static KeyGenerator keygen;

public static void main(String[] args) {
keygen = KeyGenerator.getInstance();
for (int i = 0 ; i < 25 ; i++) {
System.out.println("key(" + (i+1)
+ ")= " + keygen.getNextKey("PO_NUMBER"));
}
}
}

方案五:应用多例模式的设计方案

为了能够处理多系列键值的情况,除了可以将单例模式所封装的单一状态改为聚集状态之外,还可以采用多例模式。

package com.javapatterns.keygen.ver5;

import java.util.HashMap;

public class KeyGenerator {
private static HashMap kengens = new HashMap(10);
private static final int POOL_SIZE = 20;
private KeyInfo keyinfo;

private KeyGenerator() {}

private KeyGenerator(String keyName) {
keyinfo = new KeyInfo(POOL_SIZE, keyName);
}

public static synchronized KeyGenerator
getInstance(String keyName) {
KeyGenerator keygen;
if (kengens.containsKey(keyName)) {
keygen = (KeyGenerator) kengens.get(keyName);
} else {
keygen = new KeyGenerator(keyName);
//以下语句为初晨之阳所加,原书中没有,疑似作者笔误
keygens.put(keyName, keygen);
}
return keygen;
}

public int getNextKey() {
return keyinfo.getNextKey();
}
}

KeyInfo类的代码与方案四类似,不再重复。

package com.javapatterns.keygen.ver5;

public class Client {
private static KeyGenerator keygen;

public static void main(String[] args) {
keygen = KeyGenerator.getInstance("PO_NUMBER");
for (int i = 0 ; i < 25 ; i++) {
System.out.println("key(" + (i+1)
+ ")= " + keygen.getNextKey());
}
}
}

在上面给出的方案中,第四个和第五个方案都是具有实用价值的设计方案。

如果一个单例模式是一个聚集对象的话,那么这个聚集中所保存的是对其他对象的引用。一个多例模式则不同,多例对象使用一个聚集对象登记和保存自身的实例。由于这两种设计模式的相似之处,在很多情况下它们可以互换使用。
OpenCV-Python实战(10)——详解 OpenCV 轮廓检测 在计算机视觉领域,轮廓通常指图像中对象边界的一系列点。因此,轮廓通常描述了对象边界的关键信息,包含了有关对象形状的主要信息,该信息可用于形状分析与对象检测和识别。在本文中,将首次通过简单示例了解轮廓的基本概念,然后通过实际示例来了解如何检测和压缩轮廓,最后利用介绍如何利用图像矩描述检测到的轮廓属性。 阅读详情

相关推荐

大红球预警版-精选+自定义板块监控

这是一款简单易用的股票大单资金监控插件,兼容通达信软件,可嵌入分时图或定制版面。它以红绿圆球直观显示主力买卖情况(红球为买,绿球为卖),支持300万以上大单语音播报。插件提供实时资金流向分析、多股同时监控、自定义预警条件等功能,无需L2账号。用户可自由切换图形/列表模式,监控特定板块,并配合幻影软件实现自动交易。虽然上涨股通常红球占优,但需结合其他指标综合判断。该插件完全免费,包含详细视频教程,适合新手使用。

guleba的博客 1793

《Java与模式》学习笔记(8)——序列键生成器与单例及多例模式

在一个关系数据库中,所有的数据都是存储在表里,而每一个表都有一个主键(Primary Key)。对大多数的用户输入数据来讲,主键需要由系统以序列号方式产生。比如一个餐馆的贩卖系统需要一个序列号给每天开出去的卖单编号,这个序列号码就应当存放到数据库里面。每当发出序列号码的时候,都应当从数据库读取这个号码,并更新这个号码。 为了保证在任何情况下键值都不会出现重复,应当使用预定式键值存储办法。在

初晨的天空 1282

基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案分享

各位FPGAer周末愉快,今天熊猫君分享一个基于AMD AU15P FPGA的SLVS-EC桥PCIe设计方案。

haoxingheng的专栏 1445

密钥生成器KeyGenerator

密钥生成器KeyGenerator

kimi 7219

别再花屏了!手把手教你用STM32CubeIDE搞定LVGL 8.3移植(附完整源码)

本文详细介绍了如何在STM32CubeIDE环境下成功移植LVGL 8.3,解决常见的花屏问题。从环境配置、显示驱动优化到编译警告处理,提供完整的实战方案和源码示例,帮助开发者快速实现流畅的嵌入式GUI界面。特别针对STM32平台的DMA2D加速和内存管理进行了深度优化。

weixin_33739646的博客 242

【71页PPT】工业40及智能制造解决方案(附下载方式)

2013年,工业4.0平台发布白皮书,正式确立其发展战略。工业4.0不仅是技术的升级,更是制造业思维的重构。工业4.0的核心是通过信息物理系统(CPS)实现工厂内外的互联,构建高度灵活的个性化生产模式。它不仅是技术革新,更是一种生产方式的变革,使传统行业界限模糊化,催生新的商业模式和合作形式。德国作为制造业强国,其GDP的25%和出口总额的60%依赖制造业,因此工业4.0成为其维持全球领先地位的重要战略。CPS是工业4.0的基石,通过计算、通信与控制技术(3C)实现物理世界与信息世界的深度融合。

2501_92808811的博客 950

mybatis中KeyGenerator的设计与实现

key Generator主要是用于insert操作,其接口定义为 public interface KeyGenerator { void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter); void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter

多看多听多总结 1272

将MathType、zotero嵌入Word、WPS

最近也是慢慢学起了写文稿之类的内容,在写论文的时候,肯定会遇到一些数学公式的插入,如果使用wps、word等自带的插入公式,一般不符合投稿期刊的格式要求,而且不方便、不美观,故开始研究MathType 这款插入公式的工具。

2401_83617940的博客 2275

Hibernate主键生成 Key Generator 详解

Hibernate 主键生成器是负责生成数据表记录的主键,通常有如下几种常见的主键生成方式。 Hibernate主键生成方式 Key Generator 主键产生器: 首先介绍几种常见的主键生生器: 1) increment increment: 对 long , short 或 int 的数据列生成自动增长主键。 主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持...

读过几年书 384

YOLO26升级:CVPR2026 WDAM小波方向注意力+C2PSA,频域高频引导低频暗区复原,小目标检测精度跃升!

将 WDAM 引入 YOLO 的 C2PSA 模块,核心优势在于用极低的计算开销,为模型装上了一个“结构感知”的增强器,尤其适合处理密集小目标与边缘部署场景。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 370

SOI LDMOS器件的Sentaurus TCAD建模与关键电学特性仿真研究

本文研究了SOI LDMOS器件的TCAD建模与电学特性仿真。通过Sentaurus TCAD平台建立了单RESURF结构的SOI LDMOS模型,详细阐述了器件结构原理和RESURF耐压机制。研究采用SDE进行几何定义和掺杂配置,在Sentaurus Device中构建了完整的物理模型体系,包括迁移率、复合和碰撞电离模型。通过系统仿真提取了器件的转移特性、输出特性和击穿特性等关键参数,分析了各参数对性能的影响规律。研究结果为功率半导体器件的仿真建模提供了规范化参考,有助于优化SOI LDMOS的性能设计。

huanghm88的专栏 134

MyBatis主键生成器KeyGenerator(一)

Mybatis提供了主键生成器接口KeyGenerator,insert语句默认是不返回记录的主键值,而是返回插入的记录条数;如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 。 由于不同的数据库对主键的生成不一样: (1)针对Sequence主键而言,在执行insert sql前必须指定一个主键值给要插入的记录,如Oracle、DB2,KeyGenerator提供了proce

井底之蛙 2万+

使用Simulink对氢燃料电池与锂电池的混合储能系统进行建模

本文介绍了基于Simulink的氢燃料电池与锂电池混合储能系统建模与协同控制方法。系统通过氢燃料电池提供稳定能源,锂电池实现快速响应,结合DC-DC变换器和负载管理器实现动态调控。详细阐述了从模型创建、关键模块配置到控制器设计的完整流程,重点说明了功率分配算法和充放电控制策略的实现。通过仿真分析验证了系统在不同负载条件下的性能表现,包括响应速度、工作效率和稳定性等指标。该方案为新能源混合储能系统的设计与优化提供了实用指导,有助于提升系统可靠性和延长电池寿命。

amy_mhd的博客 314

License Key Generator

http://licensekeygenerator.codeplex.com/

爱.NET 898

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

json-web-key-generator:生成JSON Web密钥的利器

json-web-key-generator:生成JSON Web密钥的利器 项目介绍 json-web-key-generator 是一个基于Java的命令行工具,用于生成JSON Web密钥(JWK)和JSON私有/共享密钥(JPSKs)。这个项目为开发者提供了一个方便的工具,用于快速创建和管理JSON格式的密钥,以满足各种加密和身份验证的需求。 项目技术分析 json-web-key-gen...

gitblog_00950的博客 556

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【亲测免费】 Random Key Generator 项目推荐

Random Key Generator 项目推荐 项目基础介绍和主要编程语言 Random Key Generator 是一个开源项目,旨在生成各种类型的随机密钥和密码。该项目主要使用 HTML、CSS 和 JavaScript 进行开发。HTML 用于构建用户界面,CSS 用于样式设计,而 JavaScript 则负责实现核心的随机密钥生成逻辑。 项目核心功能 Random Key Gener...

gitblog_01063的博客 432

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IINA:macOS 视频播放器如何上手,从安装到插件开发完整指南

MKV 里的繁体外挂字幕找不到、VLC 的快捷键用不惯、原生 QuickTime 又只认识 MP4——在 Mac 上看视频,你多半遇到过其中一两件事。IINA 是一个为 macOS 设计的开源视频播放器,基于 mpv 引擎做解码,把播放、字幕、音轨、播放列表这些功能整合进一个原生界面里。这篇文章带你从零开始把 IINA 跑起来,顺便讲清楚它值得留作主力播放器的几个理由。 ## 它是什么:一句话说

gitblog_00027的博客 119

如何用tavily-key-generator批量注册Exa:邮件验证与Dashboard API Key提取详解

[tavily-key-generator](https://link.gitcode.com/i/8fb0542a3f4f45bc77051082de279ade) 是一个多服务自动注册工具包,支持批量注册 Tavily、Firecrawl 和 Exa 账号,自动完成**邮件验证码接收**、浏览器自动化登录,并从 Exa Dashboard 提取可用的 **API Key**。本文以 Exa 为

gitblog_00023的博客 155

用 yo generator-code 脚手架新建 VSCode 插件:TaoToken 统一 Key 接入配置骨架

用 yo generator-code 脚手架生成 VSCode 插件骨架,再通过 package.json 声明配置项,把 TaoToken 统一 Key 与 base URL 收口到设置中读取,避免硬编码泄露。跟着改 extension.ts 即可发出首个请求,官网见 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 。

Ceshi01的博客 12

配置VSCode插件 Python Docstring Generator:TaoToken 统一 Key 接入与本地验证

在 VSCode 里配置 Python Docstring Generator 插件时,把 customTemplatePath 指向本地 mustache 模板,并将 TaoToken 统一 Key 写入 settings.json,即可让模板骨架与模型补全描述串成一条链路。本文给出可复制配置、curl 与 Python 验证脚本,并排查 401、local proxy failed、choices 读取失败等常见报错。官网 https://taotoken.net/?utm_source=taotoke

weixin_35753431的博客 9

tavily-key-generator自动注册Firecrawl完整流程:从填表到API Key验证的12个步骤(新手快速上手指南)

tavily-key-generator 是一款多服务注册器与聚合 API 上游工具,本文带你从零开始走通 **Firecrawl 自动注册** 的完整流程:自动填表、邮箱验证链接处理、提取 API Key,并立即调用官方接口验证 Key 是否真实可用。全程只需 `python3 run.py` 一条命令,依赖和浏览器环境全部自动准备,12 个步骤即可完成批量注册。 ## 一、它能为新手做什么?

gitblog_00839的博客 66

VSCode插件开发环境部署:用TaoToken统一Key打通yo与generator-code初始化链路

VSCode插件开发用yo code初始化后,通过TaoToken统一Key打通settings.json与config.toml配置,实现AI辅助编码。本文提供可复制配置骨架与curl连通性自检,解决401、404等常见报错。官网:https://taotoken.net/?utm_source=taotoken_aicg_blog_end

weixin_32480007的博客 12

Flutter for OpenHarmony 中 API Key 编译期加密:envied_generator 实战指南

在客户端开发中,敏感信息的安全存储始终是重要课题,尤其是在 Flutter 与 OpenHarmony 生态融合的背景下,API Key 作为访问服务的凭证,一旦以明文形式存在于安装包中,极易被逆向提取。传统硬编码或资源文件方式难以抵御静态分析,而编译期代码生成与混淆技术为提升破解成本提供了新思路。envied_generator 通过注解驱动,将密钥在编译阶段转换为混淆字节码,运行时动态还原,既能规避明文暴露,又保持了纯 Dart 的跨平台特性,对鸿蒙适配尤为友好。在 Flutter for OpenHa

weixin_42548893的博客 246

tavily-key-generator完整指南:如何自动注册Tavily/Firecrawl/Exa账号并拿到免费API Key

tavily-key-generator 是一款开源的多服务自动注册工具,它用真实浏览器自动注册 Tavily、Firecrawl、Exa 账号,通过邮箱 API 自动收取验证码与验证链接,拿到免费 API Key 后还会立即做真实调用验证,并可选自动上传到统一 API Key 池。只需三步,就能批量获得可直接使用的搜索 API Key。 ## 1. tavily-key-generator 是

gitblog_00813的博客 161

3DGenStudio 桌面应用安装教程:Electron 打包的 Win/macOS/Linux 全平台指南

3DGenStudio 是一款开源的 AI 驱动 3D 网格生产工作站,覆盖文生图、图像编辑、网格生成、UV 展开到贴图的完整流程。它的桌面应用基于 Electron + electron-builder 打包,一套代码即可产出 Windows、macOS、Linux 三个平台的安装包。本文从零讲起,带你完成 3DGenStudio 桌面应用的安装、首次启动配置与源码打包全流程。 安装完成后,你

gitblog_00540的博客 169

npm 下载常用包太慢?用 TaoToken 统一 Key 打通 express-generator、vue、mongoose 配置

npm 装 express-generator、mongoose 总卡住?先配好 .npmrc 稳定源,再用 TaoToken 统一 Key 管理模型调用。本文给出可复制的 .npmrc 与 config.toml 骨架,完整走通 express-generator、express、vue、mongoose 安装与验证,并附 ETIMEDOUT、command not found 等常见报错排查。官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_e

weixin_35592186的博客 194
上一篇: html5 server push
下一篇: 开发工具备忘
wavee
博客等级 码龄22年 0粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值