亿级别大数的排序查找

大数据算法面试:1亿数据在有限内存上如何排序 比如我们要找出现次数最多的前100个,我们将1000万的数据分布到10台机器上,找到每台出现次数最多的前100个,归并之后这样不能保证找到真正的第100个,因为比如出现次数最多的第100个可能有1万个,但是它被分到了10台机子,这样在每台上只有1千个,假设这些机子排名在1000个之前的那些都是单独分布在一台机子上的,比如有1001个,这样本来具有1万个的这个就会被淘汰,即使我们让每台机子选出出现次数最多的1000个再归并,仍然会出错,因为可能存在大量个数为1001个的发生聚集。如果数据无法放入内存。 阅读详情

技术思路

1.容量换算

1 byte = 8 bits

1k = 1024 byte = 8*1024 bit

1M = 1024 k = 810241024 bit = 8388608 bit 800万

100M = 8亿比特

1亿 = 1 0 8 10^8 108

1亿整数 = 32亿比特 = 400M

int 能存的最大数字为[ − 2 31 -2^{31} −231, 2 31 − 1 ] 2^{31}-1] 231−1],即 [-2147483648, 2 147 483 647] 。

正整数是 21亿个,int 总共表达的数字超过40亿

2.拆分

拆分目标:

  • 将数据拆分到多台机器上进行处理

  • 如果程序运行无法直接加载一个大文件到内存中,就将大文件拆分为小文件

拆分策略:

  1. 按出现的顺序进行拆分
  2. 按散列值进行拆分,选取数据的主键key,然后通过哈希取模 hash(key)%N 得到数据应该拆分到的机器编号,N是机器数量。
  3. 按数据的实际含义进行拆分,例如来自同一个地区的用户更有可能成为朋友,如果让同一个地区的用户尽可能存储在同一个机器上,那么在查找一个用户的好友信息时,就可以避免到多台机器上查找,从而降低延迟。缺点同样是需要使用查找表。

海量数据去重

HashSet

HashSet存储,能以 O ( 1 ) \Omicron(1) O(1) 的时间复杂度判断数据是否存在。考虑到海量数据,需要使用拆分的方式将数据拆分到多台机器。拆分过程可以用哈希取模实现。

BitSet

  • 存储10亿个整数,需要120M的内存。

  • BitSet存储。如果海量数据是整数且范围不大时,可以使用BitSet存储,通过构建一定大小的比特数组就可以判断某个整数是否出现。

  • 使用BitSet还可以解决一个整数出现次数的问题,例如使用两个比特数组就可以存储0-3的信息,共有四种状态。判重问题可以简单看成一个数据出现的次数是否为 1,因此一个比特数组就够了。

#include <iostream>
using namespace std;

void memoryPrint(int byteSize)
{
	if (byteSize<1024)
	{
		cout<<"Consumed mempry of Hash is "<<byteSize<<" Byte"<<endl;
	}
	else if(byteSize<1024*1024)
	{
		cout<<"Consumed mempry of Hash is "<<byteSize/1024.0<<" KB"<<endl;
	}
	else if(byteSize<1024*1024*1024)
	{
		cout<<"Consumed mempry of Hash is "<<byteSize/1024.0/1024.0<<" MB"<<endl;
	}
	else if (byteSize<1024*1024*1024*1024)
	{
		cout<<"Consumed mempry of Hash is "<<byteSize/1024.0/1024.0/1024.0<<" GB"<<endl;
	}
	else
	{
		cout<<"too big to show"<<endl;
	}
}

class BitHashSet
{
public:
	BitHashSet(int s){
		size = s;
		// size/32+1, 50个数,用2个int就可以存储了 
		hash = new int[(size>>5)+1];
		memoryPrint(4*((size>>5)+1));
	}
	~BitHashSet(){
		delete[] hash;
	}
	void set(int pos){
		if(pos>=size || pos<0){
			cout<<"exceed the border."<<endl;
			return;
		}
		int highNum = pos>>5;      //pos/32
		int lowerNum = pos & 0x1F; //pos%32,在32bit的哪一位
		hash[highNum] |= 1<<lowerNum; //将1移到 lowernum指定的位数
	}
	bool get(int pos){
		if(pos>=size || pos<0){
			cout<<"exceed the border."<<endl;
			return false;
		}
		int highNum = pos>>5;      //pos/32
		int lowerNum = pos & 0x1F; //pos%32,在32bit的哪一位
		bool isexist = (hash[highNum] & (1<<lowerNum)) != 0;
		if (isexist)
			cout<<pos<<" is marked."<<endl;
		else
			cout<<pos<<" is not contained."<<endl;
		return isexist;
	}

private:
	int size;
	int* hash;
};


int main()
{
	BitHashSet hash(1000000000);  //10亿,109.209MB
	hash.set(100);
	hash.set(20);
	hash.set(1234);
	hash.get(100);
	hash.get(21);

	system("pause");
}

布隆过滤器

能以极小的空间开销解决海量数据判重问题,但是会有一定的误判率。主要应用于网页黑名单、垃圾邮件过滤、爬虫的网址判重系统,redis防止缓存穿透(布隆过滤器用来过滤大量数据库中未存储的key)。

布隆过滤器使用BitSet来存储数据,但是经过了改进,解除了BitSet要求数据范围的限制。

存储时,要求数据先经过k个哈希函数得到k个位置,并将BitSet中对应位置设为1,在查找时,也需要先经过k个哈希函数得到k个位置,如果所有位置上都为1,那么表示这个数据存在。

由于哈希函数的特点,两个不同的数通过哈希函数得到的值可能相同。如果两个数通过 k 个哈希函数得到的值都相同,那么使用布隆过滤器会将这两个数判为相同。

可以知道,令 k (哈希函数数量)和 m(BitSet空间) 都大一些会使得误判率降低,但是这会带来更高的时间和空间开销。

布隆过滤器会误判,也就是将一个不存在的数判断为已经存在,这会造成一定的问题。例如在垃圾邮件过滤系统中,会将一个邮件误判为垃圾邮件,那么就收不到这个邮件。可以使用白名单的方式进行补救。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6O1efoBc-1586340076593)(亿级别大数的排序查找.assets/20190428151811.png)]

Trie 字典树

Trie 树又叫字典树、前缀树和单词查找树,它是一颗多叉查找树,键不是直接保存在节点中,而是由节点在树中的位置决定。

如果海量数据是字符串数据,那么可以用很小的空间开销构建一颗Trie树,空间开销和树高有关。

详情

海量数据排序

外部排序

将海量数据拆分到多台机器或者多个文件,这些机器或文件称为拆分节点;然后在每个拆分节点上将数据全部读入内存并使用快速排序等方法进行排序;最后在合并节点使用多路归并方法将所有拆分节点的部分排序结果整合成最终的排序结果。外部排序也可以被称为外部归并排序。

如果不进行额外处理,合并节点仍然无法将所有数据读入内存,可以使用最小顶堆来解决这个问题。

1.假设有 k 个拆分节点,从这 k 个拆分节点分别读取一个最小的数据到小顶堆中。
2.将堆顶数据移出堆并写入合并节点的最终结果文件中。
3.确定刚才从堆中移除的数据属于哪个拆分节点,并从该拆分节点再读入一个数据。

但是上面的做法需要频繁地读写磁盘,可以设置输入缓存和输出缓存来解决这个问题。为每个拆分节点都设置一个输入缓存,每次将一部分数据读入输入缓存中,只有当输入缓存数据为空时才再从磁盘读入数据。并设置一个输出缓存,只有输出缓存满时才将数据写出磁盘中。

BitMap /BitSet

如果待排序的数据是整数,或者是其它范围比较小的数据,可以使用 BitMap 对其进行排序。BitMap 相当于一个比特数组,如果某个数据存在时就将对应的比特数组位置设置为 1,最后从头遍历比特数组就能得到一个排序的整数序列。

这种方法只能处理数据不重复的情况,如果数据重复,就要将比特数组转换成整数数组用于计数,这种排序方法叫做计数排序??。

Trie 字符串

如果海量数据是字符串,可以使用 Trie 树来完成排序操作。先读入海量字符串数据构建一个 Trie 树,最后按字典序先序遍历 Trie 树就能得到已排序的数据。为了处理数据重复问题,可以使用 Trie 树的节点存储计数信息。

问题1:查找十亿个正整数中重复出现的一个数

位图法:位图法也就是对于出现的数,其中每1bit代表这个数,如果该位为1,则说明该数出现;如果该位为0,则说明该数没有出现。

1 byte = 8 bits

1k = 1024 byte = 8 * 1024 bit

1M = 1024 k = 8* 1024 * 1024 bit = 8388608 bit 800万

100M = 8亿比特

思路一: 可以建立120M的一个位图,将其所有位设置为0,然后开始遍历这10亿个整数,每遍历一个,则对应到位图中相应的位置1,如果对应到位图中相应的位已经置1了,则说明这个数是要找的那个重复的数。用这种方法,最多就是遍历一遍,将这个10亿个正整数遍历完。而使用的内存为120M左右。
思路二: 只用100M内存的话,那么用每个bit来表示1个数,0表示没有出现,1表示出现,我们用取模的方式num%8亿来将数映射到8亿个bit中去,最前的2亿个bit会被重复映射,而剩下的6亿个bit只被映射一次(step1,遍历一次);由于10亿个正整数,只有其中1个数重复出现过,因此如果在映射到这后6亿个bit中,若发现某bit位已经是1,那么我们就提前找到这个数了;否则我们可以认为重复的数是那些被映射到前2亿位的数。因此只要在第一遍映射中没有发现重复的数,则接下来我们只需要用4亿个bit来判断重复的数,即,前2亿个bit用来记录num/2亿=0的数,而后2亿个位用来记录num/2亿=4的数,这样同样若发现某bit位已经是1,那么我们就提前找到这个数了(step2,遍历一次)。一共遍历了2遍,时间复杂度O(2n)=O(n)。

问题2:分割10亿个不重复的整数,查找中位数

问题3:从亿个数中找出前K个最大的数

(1)读取前100个数字,建立最大值堆。
(2)依次读取余下的数,与最大值堆作比较,维持最大值堆。可以每次读取的数量为一个磁盘页面,将每个页面的数据依次进堆比较,这样节省IO时间。
(3)将堆进行排序,即可得到100个有序最大值。

问题4:对含有亿个正整数的文件,怎么将数字进行排序

(1)磁盘合并排序
先将所有数据分成多个小文件,多个小文件采用内部排序后,再用多路合并排序完成排序输出。

总数据为n, 内存中采用内部排序最多m。先分成n/m个小文件,再内部排序,第三部读取所有小文件,每次将最小的数输出即可。
(2)多通道
0~ 1 0 k 10^k 10k-1

10k~2*10k-1

…

分成m个通道,读m次,每次读取在通道范围内的数,按顺序写到对应的输出文件,完成排序。
(3)bitmap排序
在内存中开10^7比特,均初始化为0,若出现则设置为1,输出为1的数即可。(此方法去重)

问题5:20G的文件,找出出现次数最多的数字

如果有一个20g的日志文件,日志文件记录着用户访问过的url,每一行为一个url,给你一台512M的主机,找出出现次数最多的10个url

参考答案及思路:

1.Top K算法:使用堆排序算法+大顶堆+10个元素的数组。
2.

  • IP地址最多有2^32=4G种取值情况,所以不能完全加载到内存中处理;
  • 可以考虑采用“分而治之”的思想,按照IP地址的Hash(IP)%1024值,把海量IP日志分别存储到1024个小文件中。这样,每个小文件最多包含4MB个IP地址;
  • 对于每一个小文件,可以构建一个IP为key,出现次数为value的Hash map,同时记录当前出现次数最多的那个IP地址;
  • 可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;
    最多的10个url
面对亿级数据,MySQL硬的起来么? 很多粉丝问我:MySQL到底能支撑多少数据,是不是500万以上就不行了,查询就非常慢了?这个问题问得好。到底行不行呢?我觉得还是得通过实验来见证一下,mysql面对百万、千万、亿级别的数据时,查询到底行不行???test1表,结构比较简单,2个字段,都有索引。 插入1亿数据 无条件查询(耗时24秒) 耗时20多秒,如果给用户用,这个肯定是无法接受的。 走索引查询(耗时1毫秒) order_num 字段上面有索引,我们插入的时候,order_num 这个字段的值没有重复的。用这个字段查询一下看看效果,耗时1 阅读详情

相关推荐

数据结构与算法——有1亿个整数,找出最大的1000个,要求时间越短越好,空间占用越少越好

数据结构与算法——有1亿个整数,找出最大的1000个,要求时间越短越好,空间占用越少越好(最小堆实现)

Be The Best! 4974

动画:二分查找(上) | 面试官问我如何在 1 亿数据中快速查找某一整数?(上)

关注公众号,小鹿动画学编程,一天一篇动画喂饱你! 写在前边 今天就来学习一下在一组有序数据中如何快速查找一个数。也就是我们所说的二分查找,虽然很多小伙伴对二分查找很熟悉,但是到了真正的应用问题上,还是不能更好的来把握二分的思想。要想把这部分把握好,还需要真正的体验一下二分查找的强大的效率。 如题目中所述,如果你今天去面试,面试官要问你如何在十个数中查找一个整数,那么你很快就会想到从头到尾遍历就...

小鹿动画学编程 4045

python 排序算法(选择、冒泡和归并)和查找算法(顺序和折半)

归并排序 是高效的基于比较的稳定排序算法。

butterfly_onfly的专栏 1202

Java面试指南:突破面试难关,成为优秀程序员的必备利器!

超高质量的文章,Java面试,Java理论知识大全,人生感悟都给到你。

我是Java程序员廖志伟,感谢朋友们的支持! 12万+

C++算法:搜索旋转排序数组-----二分查找

题目: 假设按照升序排序的数组在预先未知的某个点上进行了旋转。( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。你可以假设数组中不存在重复的元素。你的算法时间复杂度必须是 O(log n) 级别。 示例 1: 输入: nums = [4,5,6,7,0,1,2], targ...

ZHAO 465

告别爆显存!手把手教你为ComfyUI+华为Atlas 300I Duo配置wan2.1视频生成工作流(含CPU-VAE参数)

本文详细介绍了华为Atlas 300I Duo与ComfyUI的深度适配实战,重点优化wan2.1视频生成工作流。从硬件散热改造到软件栈配置,再到ComfyUI专项优化,提供完整的解决方案,显著提升视频生成效率与稳定性,特别适合需要高效文生视频的应用场景。

weixin_26812607的博客 467

(2016)[SAS数据处理] 利用二分法思想加速DATA步数据截取操作 [v1.02]

(2016)[SAS数据处理] 利用二分法思想加速DATA步数据截取操作

DQQ-077 CS博客 1262

SAP成本控制范围配置全流程:从货币参数到标准层次(附2024最新SPRO路径)

本文详细拆解了SAP成本控制范围(Controlling Area)的完整配置流程,涵盖从货币与估价参数文件定义、参数文件分配到控制范围,再到成本中心标准层次创建等核心步骤。文章提供了2024年最新的SPRO导航路径和实战配置要点,帮助顾问构建稳健、可扩展的管理会计基础架构,并附有常见问题排查指南。

java5的博客 940

百亿级别数据排序之其他方案

大数据量排序解决方案

KingOdin的博客 1183

现场总线课程设计-基于modbus协议使用QT实现主从站控制通信

【平台:QT】 【协议:modbus(注:由于要求,需要自己来实现modbus库,而非直接调用已有的库)】 【由于复制粘贴,时间原因可能格式有误,如需要具体工程文件以及报告文件请私信博主】 1、 大作业任务: (1)使用附件中工具软件体验MODBUS主从站数据传输过程(可在主从站模拟工具里面观察各功能码对应数据帧内容并对其进行分析) (2)使用串口调试助手,手工发出MODBUS主、从站该发出的数据,并观察对方发出的数据 (3)实现MODBUS主、从站功能,描述实现过程(语言不限于使用VC

weixin_44469597的博客 4066

Win10蓝屏代码critical process died的解决方法

critical process died”蓝屏错误是Win10操作系统中较为常见的问题之一。当遇到这一问题时,可以尝试通过修复当前系统、检查硬盘槽位或重新安装系统等方法来解决。本文详细介绍了这三种方法的操作步骤和注意事项,希望能帮助大家摆脱这一困扰。同时,也建议大家在日常使用中注意系统的维护和更新,以减少类似问题的发生。

mmoo_python的博客 9537

Java中查找与排序算法探究

java常见的查询与排序算法详解

小金的博客 796

探索Vortex开源GPGPU:RISC-V SIMT架构(2),指令Decode

本文分析了Vortex RISC-V内核的Decode模块设计。文章详细介绍了指令译码过程,包括操作码、功能码和寄存器字段的提取,以及不同类型指令(R/I/S/B/U/UJ)的立即数处理。重点阐述了基于操作码和功能码的分层译码逻辑,包括ALU运算、分支跳转、系统调用等指令的译码规则。此外,还描述了定制指令的处理机制以及与调度器的握手协议。Decode模块通过组合逻辑实现快速译码,并将结果传递给下级Issue模块,同时协调指令流控制。

weixin_55313207的博客 1793

大数据问题

top k问题 即在很多数据的情况下选出前k大的数据,数据量可上亿 要分情况讨论, 如果是堆排序,时间复杂度是O(lgn)级别,,比较次数和交换次数相同,平均为logn/2, 可以采用插入排序的办法,只维护一个k的数组,按降序排列,只用在中间插入并删掉超过k的部分,这个时间复杂度为O(n),平均比较次数为O(n/2),移动次数是O(n/2),如果可以做成链表结构,则还能省去移动的开销,而只用在比较完成后修改指针 大数据排序 如果是上亿的数据,常规的办法:加载到内存并用经典算法是行不通的,内存没办

ptgood的博客 356

HINT: High-quality INpainting Transformer with Mask-Aware Encoding and Enhanced Attention 训练自己的数据集

HINT(高质量图像修复变换器)通过创新的掩码感知像素洗牌下采样模块(MPD)和空间激活通道注意力层(SCAL),显著提高了图像修复的质量,尤其在大面积缺失区域的情况下。实验表明,HINT在CelebA、CelebA-HQ、Places2和敦煌数据集上超越了现有的最先进模型,提升了图像的细节和结构一致性。

LJ1147517021的博客 314

【深度学习新浪潮】Qwen3.5-397B-A17B 深度解析与工程部署实战:超大MoE模型的推理加速与落地

Qwen3.5-397B-A17B是当前开源社区综合能力最强、部署效率最高的超大模型,其MoE架构彻底解决了“大模型难部署、慢、贵”的痛点。

专注:太空算力、AI infra、异构调度、大模型成本工程 1710

10、Python词语排序与查找效率优化终极指南:指定顺序+O(1)查找

Python词语排序与查找优化指南:提供3种指定顺序排序方法(外部参照、权重频次、复合规则)和4种高效查找方案(二分查找、哈希表、Trie树、布隆过滤器),实现从O(n)到O(1)的性能飞跃。包含完整代码示例和决策流程图,适用于敏感词过滤、标签管理等场景,支持千万级数据处理。通过自定义排序规则和空间换时间策略,显著提升文本处理效率。

专注将Python与AI工程化落地。擅用测试思维拆解复杂模型,聚焦数据质量、自动化评估与管道优化。 748

如何通过插值法计算cell delay?

插值法的公式:Z = A + B * X + C * Y + D * X * Y,其中X为input transition,Y为output load,A、B、C、D为四个参数,Z为delay值。从而得到Z=-0.086176 + 11.5493 * x + 0.65917 * y - 24.859 * x * y,当X=0.014930、Y=0.296311时,得到Z=0.1716ns。从而得到A = 0.08075,B = 3.47539,C = 0.04008,D = 0.01648。

芯冰乐 1077

二分查找和折半插入排序一块说说-很合适~~~

前言 上一篇在聊时间复杂度和空间复杂度时,没有按指定格式显示(明明预览的时候没问题的),强迫症的我稍微优化了一下重新发布,目的就是让小伙伴看着舒服。 上次聊到的直接插入排序在比较有序数据和待插入数据时,是通过依次遍历的方式进行比较,当数据量比较大时,得考虑进一步优化;折半插入排序就是通过减少有序数据与待插入数据的比较次数,从而提升效率。 正文 1. 先来熟悉一下折半查找 1.1 折半查找算法思想 折半查找又称二分查找,仅适用于有序的顺序表; 思想(假设顺序表是升序的): 首先将指定值与顺序表

zyq025的专栏 323

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

(算法课大报告)大数据的查找与排序

    前段时间写的,把老师留的作业写得详细了些,现在把它贴上来,有错误欢迎指正,有需要改进的地方也欢迎提出! 1. 题目要求 1. 数据: sentencesFile.txt是英文语句集合文件。句子之间有字符‘\n’分割,sentencesFile.txt文件大小&lt;=1GB, 其中最短句子长度为6个字符,最长句子长度超过1000Kbyte。 计算环境:机...

weixin_33681778的博客 170

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

排序二维数组查找是否包含数字,时间复杂度优化

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 请完成一个函数,输入这样的一个二维数组和一个整数.返回在二维数组是否包含此数字. 例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true; 如果査找数字5,由于数组不含有该数字,则返回false。 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 ...

gcs的博客 1012

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

顺序查找(Sequential Search),也称线性查找,是最简单的一种查找算法

类别时间复杂度使用场合线性查找( O(n) )- 数组无序- 寻找首次出现二分查找- 已经经过预处理后的静态表- 关注速度插值查找平均: ( O(log log n) )最差 : ( O(n) )- 统计性质良好且连续性强的大规模数据库斐波那契查找平均 & 最差均为 ( O(log n) )- 减少磁盘读写的频繁程度- 处理大规模稀疏矩阵顺序查找和二分查找是两种常见的查找算法,它们各自适用于不同的场景。数据量较小:当数据量较小时,顺序查找的开销并不比二分查找大很多,且实现更简单。

[Blog][Domain] programb.blog.youkuaiyun.com 1951

在排序数组中查找第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], targ...

韩绘锦的博客 410

快速查找无序数组中的第K大数?

1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN)。在此,我们想探索是否存在时间复杂度<O(NlgN),而且近似等于O(N)的高效算法。 还记得我们快速排序的思想麽?通过“partition”递归划分前后部分。在本问题求解策略中,基于快排的划分函数可以利用“夹击法”,不断从原来的区间[0,n-1]向中间搜索第k大的数,大概...

weixin_30564901的博客 100

面试题53 - I. 在排序数组中查找数字 I

题目描述 统计一个数字在排序数组中出现的次数。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: 0 限制: 0 <= 数组长度 <= 50000 解法一 因为参数是整形,可以用二分查找K-0.5、K+0.5 两数应该插入的位置,相减即次数。...

qq_41373857的博客 171
上一篇: Redis实战——实现类附近商铺功能
下一篇: Redis实战——商户查询缓存
486过于烦躁
博客等级 码龄6年 17粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值