VS Code 这么牛,再次印证了一句名言

当代码成为流水线:程序员的不可替代性究竟在哪里? 路德维希·维特根斯坦认为,语言的意义不在于其指称,而在于其使用。每一个语言游戏都有其特定的规则和语境,脱离语境谈论"正确"是没有意义的。软件开发本质上也是一种语言游戏——只不过这里的语言是编程语言、架构模式、设计原则和团队协作规范。维度过去(实现者)现在(定义者)核心职责将明确的需求转化为代码参与定义什么才是"正确的需求"关注焦点“如何实现”“实现什么"以及"为什么”工作模式个体编码系统设计 + 团队协调 + 技术决策价值判断代码是否正确方案是否可持续、可演化沟通对象。 阅读详情

2011年,50岁的Eric Gamma 从IBM跳槽到微软。

那一年我正好在IBM,还是IBM的百年大庆,看到这个消息,非常失望,这么一位大牛,《设计模式》的作者,JUnit的作者,Eclipse JDT架构师,程序员界的标杆性人物,IBM没有留住他,实在是太可惜了。

6476b18288dfeaa8a9f1772b646daf19.png

当时Eclipse风头正盛,IDEA还没有现在这么火,Eric Gamma突然跳槽,这挺让人费解。

后来得知,他加入了Visual Studio团队,从事的是online developer tooling,就是让程序员可以在浏览器中写代码。

这一次,50岁的Eric Gamma,相当于抛弃之前所有的成就和荣誉,重新创业了。

1

创业起步

可能很多人并不知道Eric Gamma一直以来都是远离IT的中心美国,在瑞士的苏黎世,领导着一个小而强悍的团队工作。

fcd8e31c90be1bc2b3de224e505e8b2f.png

(风景如画的苏黎世)

他的小团队马上要面对一个最大的问题:我们的产品是什么? 

如果没有产出,去哪里获取进一步的投资?

资本就是这么现实,Eric Gamma你再牛,没有产品说话,也是混不下去的。

他们的第一个产品就是 Monaco Editor,一个Web版本的编辑器。

这个编辑器利用了HTML5的技术,支持语法高亮,智能提示。

Eric Gamma还做了一个重要的决定:不使用任何UI Framework,尽可能地接近最底层的DOM。

decdf280c5f5ff992ef20939db79d7a1.png

因为他认为性能非常重要,完全控制自己的命运更加重要。 

于是,Monaco Editor 就这么完全从零开始,一行一行地发展起来。

一切从头来过,嗯,牛人就是牛人。 

对项目名称,老外好像特别喜欢用地名,例如摩纳哥(Monaco),雅加达(Jakarta),爪哇(Java),我在IBM的时候也遇到过,明明是个电子商务系统,非要叫个意大利的地名:塔司科尼。

谁要是知道原因的话,不妨在下面留个言。 

产品出来了,自然要找客户。

Monaco的第一个客户是 微软云Azure ,随后也被嵌入到了各种各样的产品中。

可以这么说,这个创业公司生存没问题,接下来就是怎么发展了。

2

遭遇滑铁卢

初战告捷,胜利冲昏了团队的头脑:为什么不把它变成一个Web IDE呢?把日常开发的所有内容都搬到浏览器中。 

于是,他们把Monaco Editor改造成了Monaco Workbench ,一个单词的变化,一下子就高大上起来。

他们搭建了本地的服务器,开始吃自己的狗粮,使用Monaco Workbench来开发Monaco Workbench。 

fc255a4048c080003630cf2048826a17.png

Monaco是用JavaScript编写,而JavaScript是一门匆忙设计出来的语言,其中一些特性在代码库变大的时候很容易让人抓狂。

即使Erich Gamma的团队编程水平很高,他们也会遇到一个动态语言的终极问题:动态一时爽,重构火葬场。

幸运的是,微软的另外一个大神Anders创造了一门叫做TypeScript的语言,完美地解决了这个问题。

(Anders的故事参见 《一个养活了四代程序员的男人》)

04a74b40678523a992685519ea460c20.png

从这幅图中可以看出,Monaco并不是推倒重来,而是渐进式地采用TypeScript。

2013年,他们发布了Visual Studio Online Monaco(这个名字实在是太长了), 具备代码浏览,和Git集成,搜索代码等功能,界面和后来的VS Code已经非常像了。 

ba309e3c2c387b9209ee7518bc88f6a4.png

界面看起来很酷,但是残酷的现实是:这个产品每个月只有3000活跃用户。

对于微软这么一个巨无霸来说,产品用户以亿级计数,这实在是太尴尬了。

在线的IDE,这样的产品理念在2013年可能是太超前了。

这中间还发展了一个趣事,摩纳哥(Monaco)王国写了一封信,说他们不喜欢这个产品的名字(有他们的国家名在其中),后来Erich Gamma他们只好加了一个引号 Visual Studio Online “Monaco”

939243bbc9d17318a6eea83dc00f4b72.png

是不是很奇怪,为什么一定要把Monaco这个地名放到一个程序员用的产品中呢?叫Visual Studio Online 不行吗?

3

转折

Erich Gamma的团队面临着一个经典的创业公司挑战:如何获得十倍,百倍的用户增长?

从哪里获得用户呢? 

是继续砸钱在程序员社区做推广,还是转向别的方向?

这时候大环境发生了变化,新CEO纳德拉上台,微软开始拥抱开源,为了吸引更多程序员,微软的产品要从运行在Windows上,变成跨平台运行。

9002a17a0acf2d779cc8213a292e48d6.png

Erich Gamma看到机会,也发现了一个新的用户群体:为Web开发而生的程序员。

这个群体在开发中会使用很多语言,很多开发工具,有很多不同的运行时环境,天生有跨平台的需求。

但是Web程序员是喜欢Editor 还是IDE呢? 

Erich Gamma决定选择中间部分。

77b3b85b280217bb894fb1b871d4836c.png

Web版没人用,那就开发一个桌面版吧,但是从头儿开发代价太高。 

幸运的是,当时存在着一个叫做Electron的技术,通过使用使用Node.js(作为后端)和Chromium的渲染引擎(作为前端),让JavaScript可以运行在桌面端。 

fd8e2e828e7873ab7f590d14f9bf4b5d.jpeg

通过Electron的包装,Visual Studio Online "Monaco" 这个Web Workbench摇身一变,成了桌面"IDE",并且是跨平台的。

2015年5月,发布 VS Code (终于不再有地名了), 团队做了一个很酷的Demo:在Linux上调试.NET程序,一下子引起了轰动。

VS Code 从此进入了发展的快车道。 

4

创新致胜

如果到此打住的话,VS Code充其量也只是个好一点的编辑器。

想捕获程序员的芳心,不拿出来些干货是不行的。

1.开源

群众的呼声很高,微软和Erich Gamma 团队也顺势而为,开源VS Code。

放到GitHub之前,团队仔细地Review了代码,把它弄得干干净净。

无论是谁,都担心自己的代码被喷啊。 

2. 扩展

大家试用了VS Code以后,提出的最大建议就是:要支持扩展,支持插件。

这不正是Erich Gamma 擅长的吗!他在Eclipse搞了10多年的扩展了!

但Erich非常清楚,扩展是好东西,但是也可能会伤害你,它会严重地拖慢你的IDE。

有了之前的惨痛教训, 团队决定,扩展要在一个独立的进程中运行(是不是让你想到了Chrome?)

VS Code核心通过RPC和扩展进行交互,这样即使扩展崩溃了, VS Code核心也不会受到影响。

7ae5603f81c30de89d6ae5eda030e7af.png

3. LSP

Web开发通常使用多种语言,用JavaScript写前端,用Java写后端,还可能用Python搞点儿脚本啥的。

这么多语言,如何在一个编辑器中对它们支持智能的感知呢?

例如:

用户点击了某个函数名,点击“Go to Definition”,就应该跳到函数定义。

用户把鼠标放到某个类名上,应该显示相关定义和文档。

......

Erich Gamma再次发挥了他大师级的抽象能力,把用户在编辑时最常用的操作,如打开文件、编辑文档,Goto Definition等抽象出来,定义出一套协议:LSP(Language Server Protocol)。

VS Code不用理解语言的特性,不用考虑抽象语法树,非常轻量级.

编程语言,Java也好,Python也罢,不用考虑IDE,只要有个对应的Language Server实现了这套协议,就可以和VS Code进行交互。

1733e4fa85f222a2bb361e52a2116bff.png

3be49944dcd393a32aee22bbacaeae5d.png

LSP协议在短短几年内取得了空前的成功,现在已经有了来自微软以及社区的一百个实现,基本覆盖了所有主流编程语言。

4. VS Code Remote

VS Code Remote 让程序员可以在远程环境(比如虚机、容器)里开一个VS Code工作区,然后用本地的VS Code连上去工作。

bb841f5f523375d3ee7f4b0fefa3e141.png

在这些创新特性的加持下,VS Code 迅速攻城掠地,开始爆炸式发展,成为广大开发者的必备神器。

5

回归初心

不要忘了Erich Gamma的最初目标:online developer tooling,让程序员在浏览器中写代码。

经过艰苦的奋斗,现在终于可以回归初心:浏览器中的VS Code

fc80d8538bb58916d3b01853a4c9673d.png

由于VS Code良好的架构,使得它向Web的迁移比较容易,主要的改变是UI层。

原来是依赖Electron 做UI, 现在转向Web,需要再次重构代码,做出抽象。

例如原来有Electron的对话框,现在需要抽象出Dialog,给出HTML Dialog的实现。

但是,程序员真的会适应纯Web的编辑器,在浏览器中编程吗?大家可以在留言区讨论下。 

这里有一些统计数字,大家可以看下,每月的活跃用户达到了1400万,28k个插件,LSP Server都有138个。

cde94f1f4893440a069188d03df1db5f.png

尤其是那10万的issue,格外耀眼,让人非常震撼,一个好的产品真的是靠不断打磨出来的。

十年过去了,一个完整的社区成形, 60岁的Erich Gamma创业成功!

6

总结

看完这段历史,你可能会觉得,Erich Gamma实在太牛了,干啥都能成。

其实并不是这样,在他离开IBM之前, 曾经做过一个叫做Jazz的项目,Jazz试图把团队协作,特别是敏捷软件开发的流程搬到IDE这样的开发工具中,和代码无缝集成,但是除了IBM内部的人,恐怕了解Jazz的并不多,这个项目并没有在业界掀起多大的波澜。

如果要总结的话,还是那句老话:运气,从来都是给有实力的,准备好的人。 

TypeScript、Electron、微软转型看起来都是VS Code的重要助力和运气,但是如果没有最早的摩纳哥Editor,没有Erich Gamma迅速转型的勇气,没有后续的一系列创新,VS Code走不到今天。

参考资料:

本文大部分内容和图片的来源于Erich Gamma的演讲:《VS Code an Overnight Success… 10 years in the making》

https://www.youtube.com/watch?v=hilznKQij7A

(完)

更多精彩,尽在码农翻身

6e1f0934b53dccf50d32a087960c9718.png

47a85c349e7d59d677a84bfd437a5137.png

设计模式:可复用面向对象软件的基础.[美]Erich Gamma(带详细书签) 这本书的目的就是将面向对象软件的设计经验作为设计模式记录下来。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。我们的目标是将设计经验以人们能够有效利用的形式记录下来。鉴于此目的,我们编写了一些重要的设计模式,并以编目分类的形式将它们展现出来。 内容简介 《设计模式:可复用面向对象软件的基础》是引导读者走出软件设计迷宫的指路明灯,凝聚了软件开发界几十年设计经验的结晶。四位面向对象领域专家精心选取了具价值的设计实践,加以分类整理和命名,并用简洁而易于重用的形式表达出来。本书已经成为面向对象技术人员的圣经和词典,书中定义的23个模式逐渐成为开发界技术交流所必备的基础知识和语汇。 立即下载

相关推荐

Nvivo12新手避坑指南:从安装到编码的完整流程(附实战案例)

本文为Nvivo12新手提供了从软件安装、初始设置到数据导入和编码分析的完整避坑指南。通过一个“校园欺凌现象的学生访谈研究”实战案例,详细拆解了处理中文文本、创建项目结构、执行手动编码及高级查询等关键步骤,帮助研究者避开常见错误,快速上手并高效完成质性数据分析。

resnet7explorer的博客 317

对话 Eclipse 之父、《设计模式》作者 Erich Gamma

2016 年 6 月 1 日,北京香格里拉饭店,微软中国开发者峰会上,我见到了 VS Code 的负责人,当时的微软杰出工程师 Erich Gamma,那个时候,他更负盛名其实还是因为 Eclipse 和《设计模式》,他非常地 Nice,随身带了很多 VS Code 的贴纸,给我分享了很多,并眉飞色舞地演示着说可以贴在脑门上。如今 4 年过去了,每每回忆起这段采访时,总会不由陷入思考,有些话当时没有充分理解,而后却意味悠长。在此分享对话全文。

唐小引(Echo)的 优快云 博客。 3711

五子棋AI实战:极大极小搜索、Alpha-Beta剪枝与禁手实现

博弈树搜索是双人零和博弈AI的经典决策框架,其核心思想是假设对手最优应对,通过递归遍历走法空间寻找最优解。极大极小搜索配合Alpha-Beta剪枝,能在不影响决策结果的前提下将搜索量降至平方根级别,大幅提升搜索效率。在五子棋场景中,还需处理黑棋禁手规则,包括双三、双四和长连判定,并将其融入搜索框架。评估函数基于棋型识别对局面打分,走法排序和迭代加深进一步优化剪枝效果。这些技术共同构成了一个可运行的五子棋AI,适用于棋类AI入门与博弈搜索实践。

weixin_29054399的博客 131

埃里希·伽玛(Erich Gamma)加入微软

Erich Gamma将以Microsoft杰出工程师的身份加入Visual Studio团队。 根据公告 ,Gamma将领导位于瑞士苏黎世的新Visual Studio开发实验室,并将于8月初加入该实验室。 Gamma在Java生态系统中取得了长足的成就:他与人合着了《设计模式:可重用的面向对象软件的元素》这本书,据报道印刷了超过一百万册,是Eclipse平台的Java开发工具的负责人该...

760

点云欧式聚类快速了解

一种基于欧氏距离度量的聚类算法基于KD-Tree的近邻查询算法是加速欧式聚类算法的重要预处理方法KD-Tree是由二分搜索树演变而来的用于大规模高维度数据查找场景当中的索引结构,主要用于最近邻查找和近似最近邻查找。将整个空间划分为二叉树的形式,方便有效找到最近邻点云处理算法库PCL,是比较重要的,在后续会继续学习,然后发出更优质的文章。

xiaobaiwsc的博客 1722

王珊数据库系统概论第5版视频教材

目录 隐藏 说明:本课程共包括1种电子书、84个高清视频(共68课时)、1种纸质书(赠品)。 网授课程 王珊《数据库系统概论》(第5版)网授精讲班【共68课时】 序号 名称 课时 1 第1章 绪 论(1) 00:32:25 2 第1章 绪 论(2) 00:17:03 3 第1章 绪 论(3) 00:50:19 4 第1章 绪 论(4) 00:20:37 5 第1章 绪 论(5) 00:24:47 6 第2章 关系数据库(1) 00:47:23 7 第2章 关系数据库(2) 00:14:48 8 第2章 关系

mrtaoy96的博客 1147

畅销25年,销售百万册,这本神书和背后的软件大神

1997年,在从瑞士苏黎世飞往美国亚特兰大的飞机上,长途的旅行让大家都疲惫不堪。可是却有一对儿"好基友"兴奋异常,两个人都是程序员,他们...

码农翻身 1527

数字图像处理:直方图匹配或规定化Histogram Matching (Specification)原理及感悟

本文介绍了连续图像和数字图像直方图匹配(直方图规定化)的原理、处理过程,并提供了案例进行了讲解。可以看到,直方图均衡处理是直方图匹配的一个重要桥梁。 最后,对于直方图规定化这个翻译个人觉得很low,个人感觉叫指定直方图更好理解,但Histogram Specification怎么翻译确实不太好把握,因此还是叫Histogram Matching直方图匹配最好。

老猿Python 2880

[答疑]EA导入java源文件,出现中文字节乱码的问题

北京.放牛娃(80***166) 11:35:31各位,遇到个问题通过EA导入java源文件,出现中文字节乱码的问题,不知道如何设置。北京.放牛娃(80***166) 11:36:03北京.放牛娃(80***166) 13:03:20北京.放牛娃(80***166) 13:03:35没有找到设置代码编辑时的页面编码北京.放牛娃(80***166) 13:09:16解决了王明云(23***97) 13:10:49[幻灯]7.29-8.1日晚-剔除“伪创新”和“无领域”的领域驱动设计-网课[2020.01加一套

rolt的专栏 676

国产FPGA高云GW1NSR-4C,集成ARM Cortex-M3硬核

从板子整体角度来看,这是一款国产化程度很高的板子,从主控FPGA,到JTAG芯片,存储芯片、电源芯片等,都是使用的国产半导体公司的产品。板子整体尺寸也比较迷你,属于小而美类型的,可以认为是一款FPGA核心板,当然也预留了排针接口,给用户足够的扩展空间。对于想了解高云小蜜蜂SoC软硬件开发,以及对云源软件、MCU开发环境做个深度评测来说足够了。JTAG调试器固件可以增加虚拟串口功能,对于板子本来来说面积不会有改动,只需要添加两根信号线即可。

whik1194的博客 6397

Logstash安装部署

1. 部署及安装所用的用户不能是root。

lmj3732018的博客 4294

埃里希伽玛_埃里希·伽玛(Erich Gamma)加入微软

埃里希伽玛 Erich Gamma将以Microsoft杰出工程师的身份加入Visual Studio团队。 根据公告 ,Gamma将领导位于瑞士苏黎世的新的Visual Studio开发实验室,并将于8月初加入该实验室。 Gamma在Java生态系统中有很长的成就:他与人合着了《设计模式:可重用的面向对象软件的元素》这本书,据报道印刷了超过一百万册,是Eclipse平台的Java开发工具的...

516

PyTorch强化学习实战(1)——强化学习(Reinforcement Learning,RL)详解

在本节中,开始进入探索强化学习 (Reinforcement Learning, RL) 之旅,首先剖析了强化学习的独特之处及其与监督学习、无监督学习范式的关系。随后系统学习了强化学习的基础形式化框架及其内部关联机制,并深入讲解了马尔可夫过程 (Markov Process, MP)、马尔可夫奖励过程 (Markov Reward Process, MRP) 和马尔可夫决策过程 (Markov Decision Process, MDP),为后续学习奠定基础。

盼小辉丶的博客 2050

Claude Code 的 Clean Code 生成规范:用清晰代码规则约束 AI,产出可维护的工程级代码

代码被阅读的次数大约是它被书写的 10 倍。Claude Code 之所以能持续产出"可维护、专业级"的代码,靠的是一套显式的 Clean Code 规则约束——本仓库根目录下的 [clean-code-rules.md](https://link.gitcode.com/i/5512a07142ec2b404ccd40fe6d931bae) 正是这套规则集本身。本文以它为骨架,结合仓库内 `03

gitblog_00030的博客 1029

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Web-Dev-For-Beginners:基于事件驱动编程从零构建打字速度游戏

在 Web-Dev-For-Beginners 课程的第 4 课中,你将通过构建一个能追踪打字速度与准确率的打字游戏,系统掌握浏览器事件驱动编程的核心机制:事件监听器(event listener)、`addEventListener()`、`click` 与 `input` 事件的处理流程,以及如何用 DOM 操作实现实时视觉反馈。读完本篇并动手完成后,你将能够独立完成"用户输入 → 事件分发

gitblog_00713的博客 203

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...

TRELLIS.2-4B-GGUF的8大权重文件全解析:图像生成3D流水线速查指南

**TRELLIS.2-4B-GGUF** 是微软 TRELLIS.2-4B「图像生成 3D」模型(image-to-3d)的 GGUF(f16)格式权重仓库,专为 [trellis2cpp](https://github.com/localai-org/trellis2cpp) / ggml 运行时设计——无需 CUDA、无需 PyTorch、无需 Python 推理环境,下载后直接加载即可把一

gitblog_00375的博客 439

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Comprehensive Rust 课程精讲:使用 `Display` Trait 打造面向最终用户的可读字符串输出

`std::fmt::Display` 是 Rust 标准库中负责"把值写成字符串"的核心 trait,它与 `Debug` 的最大区别在于:`Display` 的输出面向最终用户(end user),追求人类可读的友好信息,而 `Debug` 的输出面向程序员,用于开发期调试。本文基于 Google Android 团队的 Rust 课程(Comprehensive Rust)中 [common

gitblog_00990的博客 202

Learn Harness Engineering 第 09 讲:为什么 Agent 会过早宣布胜利——用三层终止验证与独立审查构建可信的完成判定

> 本讲围绕 Harness Engineering 的核心故障模式"过早胜利宣言(premature victory declaration)"展开:当 AI 编程 Agent 告诉你"任务完成了"时,它很可能只是"感觉"完成了。本文从置信度校准偏差的根源出发,给出可落地的三层终止验证、完成判定外部化、运行时信号采集与"红笔批注"式错误反馈等一整套反制机制,并结合本仓库 Lecture 09 的

gitblog_00809的博客 1058

事件驱动编程实战:用 Web-Dev-For-Beginners 从零构建一个打字游戏(Typing Game)

本指南以仓库内 [4-typing-game 单元总览](https://link.gitcode.com/i/7bb3de3314c6ea856593b32242c32c07)(及其保加利亚语译本 [translations/bg/4-typing-game/README.md](https://link.gitcode.com/i/4a3d4d4dbbe52e5786f7b3754341b3a

gitblog_00064的博客 200

You-Dont-Know-JS 精读:JavaScript 基准测试与性能调优——从 `Date.now()` 计时陷阱到 ES6 尾调用优化

> 本文基于仓库中《You Don't Know JS: Async & Performance》系列的[第 6 章:Benchmarking & Tuning](https://link.gitcode.com/i/2cc5e0513540979113266db931e2b2dc)(葡萄牙语译本)撰写,并以同一仓库中的[第 1 章(指令重排序)](https://link.gitcode.com

gitblog_00819的博客 198

Chrome ERR_UNSAFE_PORT 端口拦截原理与解决方案

浏览器端口限制是 Web 安全体系中的基础防护机制,其核心在于通过预设的不安全端口黑名单(如139、445、25等)阻断潜在攻击面。该机制源于 Chromium 内核对历史高危协议(NetBIOS、SMTP、SMB等)的主动防御设计,本质是将端口号作为轻量级风险信号,在网络请求发起前完成拦截。它不同于 CORS 或 HTTPS 强制策略,不依赖上下文判断,而是硬编码式守门,因此具备零误报、高性能特点。开发者常遇的 localhost 调试失败、fetch 报 ERR_UNSAFE_PORT 等问题,多因后端

weixin_34239169的博客 354

Python深度学习:从入门到实战

亲爱的读者,欢迎您翻开这本书。我们即将探索的,是深度学习的宇宙——一个由数据、算法与算力构筑的奇妙世界。它既是严谨的科学,也是创造的艺术,更是一条通往未来智慧的修行之路。本书将带您从最基础的数学原理出发,亲手搭建神经网络,驾驭Transformer等前沿模型,最终将智慧转化为现实世界的价值。请放下畏惧,保持好奇。这不仅是一次知识的学习,更是一场思维的远行。来,随我一起,开启这趟非凡的旅程吧。

weixin_45747731的博客 296
上一篇: 你们程序员为什么不靠自己的项目谋生?而必须为其他人打工?
下一篇: 漫画 | 老板裁掉我两周后,又把我请回去,工资翻番!
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值