读懂diff

一文读懂《Vue2 Diff算法》 diff 算法是用于比较两颗虚拟 DOM 树的差异,并生成最小化 DOM 操作指令的算法。它的核心目标是高效更新视图,避免全量渲染的性能浪费。虚拟 DOM:用 Javascript 对象来描述真实 DOM 结构(如 Vue 中的 VNode)diff 算法是一种对比虚拟 DOM 树的差异,计算最小 DOM 更新步骤的算法。diff 算法只在同层级比较,不跨层级比较diff 算法过程中,先使用头尾双指针进行两端对比,再配合查找复用法匹配节点diff 算法中的key。 阅读详情

 diff 是 Unix 系统的一个很重要的工具程序。

  它用来比较两个文本文件的差异,是代码版本管理的基石之一。你在命令行下,输入:

$ diff <变动前的文件> <变动后的文件>

  diff 就会告诉你,这两个文件有何差异。它的显示结果不太好懂,下面我就来说明,如何读懂 diff

一、diff 的三种格式

  由于历史原因,diff 有三种格式:

* 正常格式(normal diff)

* 上下文格式(context diff)

* 合并格式(unified diff)

  我们依次来看。

  二、示例文件

  为了便于讲解,先新建两个示例文件。

  第一个文件叫做 f1,内容是每行一个a,一共 7 行。

a

a

a

a

a

a

a

  第二个文件叫做 f2,修改 f1 而成,第 4 行变成b,其他不变。

a

a

a

b

a

a

a

  三、正常格式的 diff

  现在对 f1 和 f2 进行比较:

$ diff f1 f2

  这时,diff 就会显示正常格式的结果:

4c4

< a

---

> b

  第一行是一个提示,用来说明变动位置。

4c4

  它分成三个部分:前面的"4",表示 f1 的第 4 行有变化;中间的"c"表示变动的模式是内容改变(change),其他模式还有"增加"(a,代表 addition)和"删除"(d,代表 deletion);后面的"4",表示变动后变成 f2 的第 4 行。

  第二行分成两个部分。

< a

  前面的小于号,表示要从 f1 当中去除该行(也就是第 4 行),后面的"a"表示该行的内容。

  第三行用来分割 f1 和 f2。

---

  第四行,类似于第二行。

> b

  前面的大于号表示 f2 增加了该行,后面的"b"表示该行的内容。

  最早的 Unix(即 AT&T版本的 Unix),使用的就是这种格式的 diff。

  四、上下文格式的 diff

  上个世纪 80 年代初,加州大学伯克利分校推出 BSD 版本的 Unix 时,觉得 diff 的显示结果太简单,最好加入上下文,便于了解发生的变动。因此,推出了上下文格式的 diff。

  它的使用方法是加入c参数(代表 context)。

$ diff -c f1 f2

  显示结果如下:

*** f1 2012-08-29 16:45:41.000000000 +0800

--- f2 2012-08-29 16:45:51.000000000 +0800

***************

*** 1,7 ****

a

a

a

! a

a

a

a

--- 1,7 ----

a

a

a

! b

a

a

a

  这个结果分成四个部分。

  第一部分的两行,显示两个文件的基本情况:文件名和时间信息。

*** f1 2012-08-29 16:45:41.000000000 +0800

--- f2 2012-08-29 16:45:51.000000000 +0800

  "***"表示变动前的文件,"---"表示变动后的文件。

  第二部分是 15 个星号,将文件的基本情况与变动内容分割开。

***************

  第三部分显示变动前的文件,即 f1。

*** 1,7 ****

a

a

a

! a

a

a

a

  这时不仅显示发生变化的第 4 行,还显示第 4 行的前面三行和后面三行,因此一共显示 7 行。所以,前面的"*** 1,7 ****"就表示,从第 1 行开始连续 7 行。

  另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。

  第四部分显示变动后的文件,即 f2。

--- 1,7 ----

a

a

a

! b

a

a

a

  除了变动行(第 4 行)以外,也是上下文各显示三行,总共显示 7 行。

  五、合并格式的 diff

  如果两个文件相似度很高,那么上下文格式的 diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff 率先推出了"合并格式"的 diff,将 f1 和 f2 的上下文合并在一起显示。

  它的使用方法是加入u参数(代表 unified)。

$ diff -u f1 f2

  显示结果如下:

--- f1 2012-08-29 16:45:41.000000000 +0800

+++ f2 2012-08-29 16:45:51.000000000 +0800

@@ -1,7 +1,7 @@

a

a

a

-a

+b

a

a

a

  它的第一部分,也是文件的基本信息。

--- f1 2012-08-29 16:45:41.000000000 +0800

+++ f2 2012-08-29 16:45:51.000000000 +0800

  "---"表示变动前的文件,"+++"表示变动后的文件。

  第二部分,变动的位置用两个@作为起首和结束。

@@ -1,7 +1,7 @@

  前面的"-1,7"分成三个部分:减号表示第一个文件(即 f1),"1"表示第 1 行,"7"表示连续 7 行。合在一起,就表示下面是第一个文件从第 1 行开始的连续 7 行。同样的,"+1,7"表示变动后,成为第二个文件从第 1 行开始的连续 7 行。

  第三部分是变动的具体内容。

a

a

a

-a

+b

a

a

a

  除了有变动的那些行以外,也是上下文各显示 3 行。它将两个文件的上下文,合并显示在一起,所以叫做"合并格式"。每一行最前面的标志位,空表示无变动,减号表示第一个文件删除的行,加号表示第二个文件新增的行。

  六、git 格式的 diff

  版本管理系统 git,使用的是合并格式 diff 的变体。

$ git diff

  显示结果如下:

diff --git a/f1 b/f1

index 6f8a38c..449b072 100644

--- a/f1

+++ b/f1

@@ -1,7 +1,7 @@

a

a

a

-a

+b

a

a

a

  第一行表示结果为 git 格式的 diff。

diff --git a/f1 b/f1

  进行比较的是,a版本的 f1(即变动前)和b版本的 f1(即变动后)。

  第二行表示两个版本的 git 哈希值(index 区域的 6f8a38c 对象,与工作目录区域的 449b072 对象进行比较),最后的六位数字是对象的模式(普通文件,644权限)。

index 6f8a38c..449b072 100644

  第三行表示进行比较的两个文件。

--- a/f1

+++ b/f1

  "---"表示变动前的版本,"+++"表示变动后的版本。

  后面的行都与官方的合并格式 diff 相同。

@@ -1,7 +1,7 @@

a

a

a

-a

+b

a

a

a

  七、阅读材料

  * diff - Wikipedia

  * How to read a patch or diff

  * How to work with diff representation in git

LeGo-LOAM源码篇:源码分析(3) mapOptmization.cpp,主要内容包括回环检测、scan-to-map位姿优化、因子图。 阅读详情

相关推荐

【AI蛋白预测实战】零门槛在Colab上运行AlphaFold2全流程解析

本文为零基础用户提供了在谷歌Colab平台上运行AlphaFold2进行蛋白质结构预测的完整实战指南。通过ColabFold项目,用户无需本地高性能硬件,即可免费利用云端GPU完成从序列输入到3D结构生成和结果可视化的全流程,大幅降低了AI蛋白预测的技术门槛。

mqtt6iot的博客 912

Git | git diff 输出结果解读

以下面的结果为例: 第一行表示 a 版本的 new.txt(变动前) 与 b 版本的 new.txt(变动后) 比较: diff --git a/new.txt b/new.txt 第二行 index 后面两个数字表示两个文件的 hash 值(index 区域的 0e9cc9b 对象,与工作目录区域的 af0a351 对象进行比较)。最后的六位数字是对象的模式(100代表普通文件,644代表权限): index 0e9cc9b..af0a351 100644 第三行表示进行比较的两个文件: ---

Cyber 5337

ZYNQ Linux下UIO中断配置避坑实录:从设备树修改到用户层测试(Vivado 2018.2)

本文详细解析了ZYNQ Linux下UIO中断配置的全流程,从设备树修改到用户层测试,特别针对Vivado 2018.2环境中的常见陷阱提供解决方案。内容涵盖中断号配置规则、用户空间中断处理程序编写以及性能优化技巧,帮助开发者高效实现硬件中断的用户空间控制。

weixin_31854867的博客 333

git diff 命令详解

平时我们在本地开发时,一般都是通过 gui 工具(git 图形化工具)查看文件差异,也就是文件变动内容。但是,我们可能会在线上服务器临时改一些小东西去排查 bug,此时就用不了这些 gui 工具了,那么就可以通过这个命令查看我们改动的内容。修改前的文件: 从第 140 行开始显示 3 行,也就是显示 140~142 行。修改后的文件: 从第 140 行开始显示 5 行,也就是显示 140~144 行。100644: 100 代表是普通文件,644 指的是文件权限。查看文件差异(默认查看所有文件的差异)

很酷的站长的博客 5274

AES攻击方法 :差分密码分析 boomerang attack飞去来器攻击

AES具有123比特的分组长度,三种可选的密钥长度(128,192,256) AES是一个迭代型密码,轮数依赖于密钥长度。如果密钥长度为128比特,则轮数为10;如果密钥长度为192比特,则轮数为12;如果密钥长度为256比特,则轮数为14; 混淆(Confusion) 混淆是为了让密钥与密文的统计信息之间的关系变得复杂,从而增加通过统计方法进行攻击的难度。混淆可以通过各种代换算法实现,如S盒、乘法(加)与异或等运算组合,为非线性部件。 扩散(Diffusion) 扩散是为了让明文的单个比特影像到

m0_67105022的博客 3491

化工设计软件:PDMS二次开发_(9).项目案例分析与实战

在化工设计项目中,材料的选择和管理是至关重要的环节。PDMS自带的材料数据库可能无法完全满足特定项目的需求,因此需要进行自定义材料数据库的二次开发。本案例的目标是创建一个自定义材料数据库,并将其集成到PDMS中,以便设计团队能够方便地使用这些材料进行设计。材料名称:材料的唯一标识符。材料类型:如金属、塑料、复合材料等。材料属性:如密度、热导率、耐温范围等。// 定义材料类set;} // 材料名称set;} // 材料类型set;} // 密度set;} // 热导率set;} // 最低耐温。

kkchenjj的博客 573

git diff使用

git diff 查看文件差异。

u014427827的博客 304

影楼精修-AI追色算法解析

本文解析了像素蛋糕软件中AI追色功能的技术原理与实现方案,为理解AI追色技术提供了实用参考。

Trent1985的专栏 2万+

Git 命令 - git diff

Git 命令- git diff

程永强 1997

24、虚拟地理信息系统:技术与应用的全面解析

本文全面解析了虚拟地理信息系统(虚拟GIS)的技术架构与应用前景。文章从地理空间数据的增长出发,探讨了虚拟GIS在地形、建筑、天气等多维度数据的交互式可视化技术,重点介绍了全球层次结构、多分辨率模型、缓存分页机制及交互导航方法。系统已应用于天气分析、城市规划、应急响应等领域,并展望了未来在数据处理、模拟操作、移动可视化及智能城市、文化遗产保护等方向的发展路径与技术挑战。

v4w5x6的博客 88

【unity小技巧】委托(Delegate)的基础使用和介绍

在Unity中,委托(Delegate)是一种用于处理方法回调的特殊类型。它允许您将方法作为参数传递给其他方法,并在需要时调用这些方法。委托在游戏开发中非常有用,特别是在事件处理、消息传递和异步操作方面。它提供了一种灵活的方式来注册和触发方法,而无需显式地知道这些方法的实现细节。个人理解:可以把委托理解为一个容器,容器里面放可以放很多函数方法。一调用委托,里面所有的函数方法都会同步被执行。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 7236

【diff】快速读懂diff

参考资料 读懂diff diff是Unix系统的一个很重要的工具程序。 它用来比较两个文本文件的差异,是代码版本管理的基石之一。你在命令行下,输入: $ diff <变动前的文件> <变动后的文件> diff就会告诉你,这两个文件有何差异。它的显示结果不太好懂,下面我就来说明,如何读懂diff。 一、diff的三种格式 由于历史原因,diff有三种格式:   * 正常格...

weixin_41687289的博客 954

YOLOv5改进 | 多尺度特征提取 | 结合多样分支块及融合的高级设计(CVPR2021)

YOLOv5改进 | 多尺度特征提取 | 结合多样分支块及融合的高级设计(CVPR2021)

qq_44224801的博客 2068

【转】diff详解,读懂diff结果

本文将要讨论的是diff命令,diff用来比较两个文件。当然文件比较的工具很多,windows系统下面就有不错的工具可以使用,例如常用的Beyond Compare,WinMerge都是图形界面的比较工具而且使用非常方便,如果你仅仅是在windows下工作,这些GUI的比较工具绝对是首选。对于在linux环境下工作的人来说,如果每次想看两个文件的区别都要将文件下载到windows环境然后用图形工具进行比较实在是太麻烦了。那么我们必须学会使用linux环境下的比较工具diff。回到顶部。...

测试领域专家,多领域测试技术、管理、工具都略懂,略懂一二 6872

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")

diff详解,读懂diff结果

1.概述 本文将要讨论的是diff命令,diff用来比较两个文件。当然文件比较的工具很多,windows系统下面就有不错的工具可以使用,例如常用的Beyond Compare,WinMerge都是图形界面的比较工具而且使用非常方便,如果你仅仅是在windows下工作,这些GUI的比较工具绝对是首选。对于在linux环境下工作的人来说,如果每次想看两个文件的区别都要将文件下载到windo...

2838

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

读懂 diff 命令

diff是Unix系统的一个很重要的工具程序。 它用来比较两个文本文件的差异,是代码版本管理的基石之一。你在命令行下,输入: 1  $diff< 变动前的文件 > ; diff就会告诉你,这两个文件有何差异。它的显示结果不太好懂,下面我就来说明,如何读懂diff。 一、diff的三种格式

evenness的专栏 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: c中预定义 很有用
下一篇: 如果永远没有人知道你干的事,那你将干什么呢
Iphone4
博客等级 码龄17年 17粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值