Getting Started with Continuous Integration

国央企创新负责人如何通过平台实现科研成果的快速识别与转化?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

原文地址:http://www.developer.com/tech/article.php/3557396/Getting-Started-with-Continuous-Integration.htm


Imagine that you've just fixed a bug in your application's code and checked the fix into the project's source code repository. How much do you know now? If all you know is that the fix worked on your machine, you're playing with fire. If you've run the fix through a suite of integration tests and are confident that it didn't break anything else in the project's code, you're doing much better: your process is under control. But would you believe that you can do better than that? There are some teams that know that the new checkin passes the integration tests, that the tests cover the entire codebase, that the project's coding standards are being followed, and that there's no excessive duplication in code. And they know this after every checkin. Best of all, they know this without human intervention: a little icon in their system tray turns red if anything goes wrong, and stays happily green otherwise. At any time, they can visit a Web page on their local intranet to check up on the current state of the code.

The technique behind this seeming magic is called continuous integration, and it's not as difficult to set up as you might think. In this article I'll show you how the pieces fit together for a simple .NET continuous integration server that will help you monitor the quality of your own coding efforts in real time.

Setting Up the Server

The first step in continuous integration is to set up a build server. Ideally, this will be a dedicated computer that isn't used for anything else. This is the computer that will be the master source for final builds of your software: if all goes well, at any time you should be able to burn a working CD from this machine's hard drive and be ready to install it on customer boxes. You'll want a computer that is powerful enough to run all of the tools that you need to build your software. If you're doing .NET development, that means that it at least needs to be able to manage command-line builds using the csc or vbc compilers, though you shouldn't skimp here. The faster the build machine can turn out a fresh build of your software, the faster you get feedback on the code quality of new checkins.

The key piece of software you'll need is a continuous integration server. This is a master controller for the build process: it monitors your source code control repository for checkins, and every time that it spots one, it gets the latest version of the code. Then it kicks off a build by calling other tools, such as compilers and unit test tools. Finally, the continuous integration server notifies team members of the build status by publishing information in a variety of ways, from updated Web pages to e-mailed status messages, and goes back to watching for new checkins. There are several continuous integration servers for .NET available; I happen to use CruiseControl.NET, which is currently at the 1.0RC2 release level. Installing CruiseControl.NET is straightforward; you'll want to have the .NET Framework and IIS with ASP.NET installed first. Then just download and run the installers for CruiseControl.NET and the separate Web Dashboard (the applications are free) and you're off and running. CruiseControl.NET is open source, so if you prefer you can start with the source code and build it yourself.

Installing Your Tools

The next thing the server needs is everything required to actually build your software, starting from the source code. It's impossible to give a complete list here, because every project is different. What you need to do is observe your own manual practices, starting from source code checkin and ending with the deliverable. Certainly you'll need to install a source code control client, so the continuous integration server can get at the source code, and either the .NET SDK or Visual Studio .NET to build the software. From there, you may need a unit-testing tool, an obfuscator, a code-quality checker, a setup builder, and other tools.

Depending on your own particular set of tools, you'll also want to install a general-purpose build-scripting utility such as NAnt or MSBuild. While CruiseControl.NET can call many tools directly, it can't know about every development tool in the universe. Sometimes you may find that you need to have CruiseControl.NET call a NAnt task that in turn calls your development tool of choice.

It's important that you get the same versions of all your tools on the build server that you're using on your development computers. Otherwise, some day you'll spend far too much time trying to track down a subtle error caused by, say, the testing tool being at a different revision level on different machines. One way to handle this is to actually check the tools into your source code control repository and install them from there. Another is to use a central software distribution system such as Microsoft Systems Management Server to install the build tools.

A Simple Example

To make this all a bit more concrete, let's look at one of the projects on my own continuous integration server. My build tools stack for this project currently includes these tools:

  • Subversion for source code control.
  • Visual Studio .NET to handle the actual builds.
  • NUnit for unit testing.
  • NAnt for build automation.
  • FxCop for conformance checking.
  • NCover for code coverage analysis.
  • Simian for similarity analysis.
  • Vil for collecting code metrics.

One key to making the process work smoothly is the proper use of NAnt. I want the build process on the continuous integration server to be as close as possible to the build process on my local development computer. That way, if anything goes wrong, it's easy for me to replicate what happened. So rather than have CruiseControl.NET call out to the individual tools directly, I've set it up to call a NAnt build file that in turn calls the individual build tools. With this indirection in place, I can replicate what CruiseControl.NET is doing simply by invoking NAnt by had any time I need to check what's going on. The NAnt configuration file looks like this:


<?xml version="1.0" ?>
<project name="nant" default="compile"
  xmlns="http://nant.sf.net/schemas/nant.xsd">
<target name="compile">
  <solution solutionfile="RssDrop.sln" 
    configuration="AutomatedDebug" />
</target>
<target name="test" depends="compile, run-unit-tests" 
  description="Compile and Run Tests" />
<target name="ccnet" 
  depends="compile, fxcop, ncover, simian, vil" 
  description="Cruise Control.NET target" />
<target name="run-unit-tests">
  <nunit2>
    <formatter type="Xml" usefile="false" />
    <test assemblyname="RssDropLibUnitTests.dll" />
  </nunit2>
</target>
<!-- Run FxCop compliance checker -->
<target name="fxcop">
  <exec program="toolsFxCopfxcopcmd.exe" ... />
</target>
<!-- NOTE: ncover runs nunit tests -->
<target name="ncover">
  <exec program="toolsncoverNCover.Console.exe" ... />
</target>
<!-- Find duplicate code -->
<target name="simian" >
  <exec program="toolssimiansimian-2.2.7.exe"  ... /> 
</target>
<!-- Code metrics -->
<target name="vil">
  <exec program="toolsvilvil.exe" ... />
</target>
</project>

I've omitted the details of the command lines and arguments for the various tools so as to make the structure of this file more clear. Even if you're not familiar with NAnt, you should be able to tell what's going on here. A NAnt configuration file is a collection of targets, each of which tells NAnt what to do in a particular circumstance; when you invoke NAnt, you tell it which target to carry out. The ccnet target is the composite target that CruiseControl.NET will execute; it in turn calls the targets that make up the various steps involved in building and testing my project.

Configuring the Continuous Integration Server

To hook all this up to the continuous integration server requires another XML configuration file, this one for CruiseControl.NET:


<cruisecontrol>
  <project name="RssDrop">
    <workingDirectory>c:ProjectsRssDrop</workingDirectory>
    <webURL>http://TITANIC/ccnet/</webURL>
    <triggers>
      <!-- Build every sixty seconds if any changes in SVN -->
      <intervalTrigger seconds="60" />
      <!-- Force a daily build at 1AM -->
      <scheduleTrigger time="01:00" buildCondition="ForceBuild" />
    </triggers>
    <modificationDelaySeconds>10</modificationDelaySeconds>
    <sourcecontrol type="svn">
      <executable>c:program filessubversionbinsvn.exe</executable>
      <trunkUrl>svn://BAKUNIN/Repos/Larkware/trunk/RssDrop</trunkUrl>
      <autoGetSource>true</autoGetSource>
      <username>CCNet</username>
      <password>XXXXXX</password>
      <workingDirectory>c:ProjectsRssDrop</workingDirectory>
    </sourcecontrol>
    <tasks>
      <nant>
        <executable>C:ProjectsRssDropToolsNAntnant.exe</executable>
        <nologo>false</nologo>
        <buildFile>RssDrop.build</buildFile>
        <targetList>
          <target>ccnet</target>
        </targetList>
        <buildTimeoutSeconds>600</buildTimeoutSeconds>
      </nant>
    </tasks>
    <publishers>
      <merge>
        <files>
          <file>AutomatedBuildsFxCop.xml</file>
          <file>AutomatedBuildsRssDropLibUnitTests.dll-results.xml</file>
          <file>AutomatedBuildsCoverage.xml</file>
          <file>AutomatedBuildssimian.xml</file>
          <file>AutomatedBuildsresults-vil.xml</file>
        </files>
      </merge>
      <xmllogger />
    </publishers>
  </project>
</cruisecontrol>

Let's pick this apart one piece at a time. First comes some basic setup: the working directory on the build server where CruiseControl.NET will do its work and the URL on my intranet where it will publish results. Next comes the triggers section. This specifies the events that will trigger a build. I've set up two of these. The first checks the source code repository once every minute for checkins, and starts a build if anything has changed. The second builds the code every morning at 1AM when I am (hopefully) in bed, so I get a daily record of progress.

The next section of the file sets up the source code control hookup - in this case, to my Subversion repository, which lives on the BAKUNIN server. I've supplied all the necessary information for CruiseControl.NET to log in to the server using its own account. Note that it automatically gets any changes to the code when it checks the repository, so it's always building from the most recent sources. The modificationDelaySeconds element puts a ten-second delay into things so that multiple checkins in a short span of time don't trigger multiple builds; it waits until things are quiet for a little bit before getting underway.

Next comes the tasks section, which tells CruiseControl.NET just what to do when it does decide it's time to rebuild. In this case, I've added a single task, which calls the NAnt build file that I set up earlier. More complex situations will call for multiple tasks here. CruiseControl.NET can do many things with tasks, including call NAnt, call MSBuild, call any command-line executable, invoke Visual Studio .NET directly, and so on.

The publishers section of the configuration file tells the server what to do after the build. In this case, it collects all the various XML output files from the different build tools and merges them together into a single XML log file. If you're working with a team, you'll probably also want to take advantage of the server's ability to send success or failure e-mail here.

That's about all there is to setting things up. What about keeping an eye on them?

Monitoring the Results

CruiseControl.NET maintains its own IIS-based Web Dashboard for easy Web-based reporting on its activities. Figure 1 shows a sample Web report for the project that I've been examining in this article.

CruiseControl.NET Web Dashboard

The Web Dashboard lets you easily move between projects on your server, see the builds for any project, and drill into the results from each tool on any build you wish. XSL transforms are used to format the tools' XML output files for pretty display. You can also force a build from the Web Dashboard, telling the server to build immediately without waiting for the triggers to activate.

The Web Dashboard is useful when you need to see the details of a particular build, but for convenient monitoring of the current build status you can't beat the CCTray application. As you might guess from the name, this little tool normally lives in the tray notification area, where it presents build status through simple color codes: green to show the last build was good, red to show it failed, and yellow to show that a build is underway. As long as the icon stays green, you know that your most recent checkin didn't break anything - and neither did a checkin from any of your co-workers.

It's All About Good Build Hygiene

Continuous integration by itself doesn't do any good, of course. You still need to write good unit tests, check in code on a regular basis, think about the architecture of your code, and so on. But coupled with other good build and development processes, it can be a powerful way to know that your code quality is staying high - or to help you immediately pinpoint problem areas when things slip. You'll need to devote a bit of time and a dedicated computer to setting things up, but you'll probably find that the rewards are worth it. With the tools being free, you've got very little to lose by trying it out!

About the Author

Mike Gunderloy is the author of over 20 books and numerous articles on development topics, and the lead developer for Larkware. Check out his latest books, Coder to Developer and Developer to Designer, both from Sybex. When he's not writing code, Mike putters in the garden on his farm in eastern Washington state.


PotPlayer自用皮肤 自用 PotPlayer 皮肤,仅微调了字体大小与颜色,是按个人习惯调整,未做适配性调整。 立即下载

相关推荐

2-shell及常用命令-续.pdf

2-shell及常用命令-续.pdf

Jenkinsapi从入门到精通:构建企业级CI/CD自动化平台

Jenkinsapi是一个强大的Python API,用于访问和配置Hudson及Jenkins持续集成服务器。通过Jenkinsapi,开发者可以轻松实现CI/CD流程的自动化,包括创建作业、管理构建、监控节点等核心功能,为企业级自动化平台搭建提供了便捷工具。 [![Jenkins CI/CD自动化平台](https://raw.gitcode.com/gh_mirrors/je/jenkin

gitblog_00861的博客 391

硬件作品3----STM32F103RCT6最小系统板MCU配置

电路未调试成功,目前刚打板,后续需要补充或者改版另行注明。

weixin_58364194的博客 5561

Jenkinsapi开发者手册:构建自定义Jenkins集成工具的关键技术

Jenkinsapi是一个强大的Python API,用于访问和配置Hudson与Jenkins持续集成服务器。通过Jenkinsapi,开发者可以轻松查询Jenkins服务器状态、修改配置并自动化节点和作业的管理任务,是构建自定义Jenkins集成工具的核心技术。 ## 为什么选择Jenkinsapi? Jenkins作为领先的持续集成/持续部署(CI/CD)平台,其强大的扩展性和灵活性使其

gitblog_00156的博客 843

高德地图爬虫

高德地图爬虫 工具:Pycharm,win10,Python3.6.4 1.需求分析 这篇爬虫和上一篇百度地图爬虫要求一样,百度地图爬虫我发现有一个auth参数会一直变化,一旦变化则获取的数据是不准确的,所以我上高德地图看了一下,高德地图没有这个反爬机制。但是高德地图大概爬取120个页面就会跳一次验证码,我这里是通过换IP解决这个问题的。 2.数据准备 同样我们需要全国地级市信息,用之前...

123的博客 1万+

Qt Tab Widget 实战:如何打造一个可动态增删的标签页管理器(附完整代码)

本文深入探讨了使用Qt框架中的Tab Widget控件构建动态标签页管理器的实战方法。通过分析动态增删的核心挑战,提供了完整的C++代码示例,涵盖信号槽机制、页面生命周期管理、上下文菜单实现以及状态持久化等关键功能,帮助开发者打造高效、用户友好的桌面应用界面。

bb456的博客 1043

微软技术日报 11-09:.NET 8 与 9 明日同时停止支持,注册表编辑器出了 WinUI 3 版

今天这四条消息的共同点是收口。.NET 8 和 9 的支持期到点,注册表编辑器的新界面只放在仓库里给人看,GitHub 把一类危险触发器按住默认,微软在安全报告里把防线从地址黑名单挪到行为。收口并不等于关门。.NET 10 还在支持期里,被按住的触发器可以用策略按文件放回来,实验室里的样例随时可能变成产品。区别在于这些动作要有人签字,不再是默认开着。如果今天只做一件事,去看一眼构建机上的 .NET 版本。明天之后,8 和 9 的漏洞补丁不会再来了。

海盗Sharp的博客 307

HFSS实战:手把手教你设计3.3-10.6GHz超宽带微带天线(附S11优化技巧)

本文提供了一份基于Ansys HFSS的超宽带微带天线实战设计指南,详细讲解了从3.3GHz到10.6GHz天线的建模、仿真与优化全流程。文章重点剖析了阻抗匹配的核心挑战,并分享了通过接地板开槽、参数化扫描及目标驱动优化等系统性技巧来优化S11曲线的实用方法,帮助射频工程师快速掌握超宽带天线设计的关键技能。

2y3u4i5o6p的博客 1081

微软技术周报 11-02~11-09:VS Code 混装 Claude 与 Codex、EF Core 11 静默改行为、.NET 11 倒计时

11 月 6 日,Power Platform 通过消息中心通知管理员,Copilot Studio、Power Automate 和 Power Apps 里所有跑在 Anthropic Claude、xAI Grok 以及旧版 GPT 上的 prompt,12 月 2 日自动迁移到 GPT-6 系列,档位价格不变,模型选择收窄到一条产品线。效果是这样的:让 Claude 评审一个 Copilot chat 写出的方案,或者把同样的任务交给 Codex,两边并排跑在同一个会话里。更要紧的是下周的时间线。

海盗Sharp的博客 426

杰理接入第三方升级协议OTA教程

本教程介绍了使用dual_bank_updata_api.h接口接入第三方协议进行固件升级的方法。主要内容包括:INI配置要求(需启用双备份并强制4K对齐)、7个核心API接口功能说明及参数详解(初始化、空间检查、数据写入、校验等)、标准升级流程步骤(初始化→检查→写入→校验→引导→清理)。特别强调了4K对齐配置的重要性以避免数据丢失,并提供了被动升级流程图。该方案支持用户自定义协议接入,需严格按照流程调用接口完成升级。

qq_42014563的博客 1429

B站自动答题协议分析

使用Python写了一个自动答题机器人!基于接口协议实现且包含点选验证码识别

吴秋霖的博客 2652

11-01-演进-.NET GC发展史

.NET GC发展史映射硬件演进:从单核STW到多核并发,再到区域化细粒度回收。历经分代管理、ServerGC、BackgroundGC、LOH自动压缩、POH隔离、DATC自适应线程数及Region-based管理等关键革新,代码量从5000行增至4万+,复杂度指数上升。每一步优化均在暂停时间、吞吐量与资源开销间权衡,体现“实用主义”哲学。核心启示:GC演进由硬件驱动,方向明确——更短暂停、更高效率,但代价是工程复杂性持续攀升。

设计 AI 玩游戏🎮 364

FLAC3D数值三轴测试

本文介绍了使用FLAC3D进行数值三轴测试的命令流程。通过建立圆柱体模型,设置Mohr-Coulomb本构模型及材料参数,施加边界条件和荷载,并定义Fish函数监测应变和应力。命令包括模型创建、网格划分、材料属性定义、边界约束、荷载施加以及结果监测等步骤。该流程可用于模拟岩土材料在三轴条件下的力学响应,为数值分析提供参考。完整代码可从指定链接下载获取。

qq_36980284的博客 99

.NET 10 的性能提升

你不需要重写代码去用Span<T>,不需要手工池化对象,甚至不需要调整 GC 配置。JIT 编译器变得更“聪明”了,它会在编译时替你完成一些过去需要手动干预的优化。但与此同时,.NET 10 也引入了一个默认开启的 GC 行为变化,它在某些场景下会。这篇文章想讲清楚:哪些性能是你“自动”拿到的,哪些是需要你主动审视和取舍的。

qq_41019429的博客 339

34、高效探索柔性蛋白质环构象空间的算法

本文介绍了一种高效探索柔性蛋白质环构象空间的算法,通过种子采样和变形采样两种技术,同时满足运动学闭合和避免空间位阻冲突的约束条件。种子采样能够在闭合无冲突构象空间中广泛生成构象,而变形采样则可以对“有趣”区域进行更密集的探索。实验结果表明,这两种方法在不同大小和受限程度的蛋白质环上均表现出色,运行时间在可接受范围内。相关算法已集成到工具包LoopTK中,可在https://simtk.org/home/looptk获取。

moon9的博客 127

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

.NET 性能优化:先找瓶颈,再谈技巧

NET 性能优化没有“一招鲜”。Span<T>ValueTaskstackalloc这些工具在特定场景下确实很强,但它们解决的是微观层面的分配问题。如果你的应用瓶颈在数据库查询或者线程池阻塞,用再多Span<T>也救不回来。先测量,找到热路径,再针对性修改,改完再测量验证。跳过第一步的优化,大概率是在给编译器添乱。

qq_41019429的博客 373

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

.NET 11 - 尝试一下Blazor中的新特性SupplyParameterFromTempData

时光匆匆,.NET Conf 2026大会将会在2026年11月份举办(11/10-11/13),到时微软将会发布.NET11,这是一个STS版本(Standard Term Support), 微软提供两年支持。当前.NET 11已经处于RC3版本(Release Candidate 3),很多新特性已经被发布出来了。

limingdinghao的博客 223

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

jre9下载 jdk9

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

在 .NET 10 中使用 Keycloak.Admin.Sdk 管理 Keycloak:从基础接入到功能开关

面向 .NET 10 / Native AOT 的 Keycloak Admin REST API 客户端,当前仅支持 Keycloak 26.8.1。主包引用 Microsoft.Extensions.Http 10.0.14 和 Microsoft.Extensions.Http.Resilience 10.11.0,使用源生成 JSON 元数据,默认关闭反射序列化。仓库固定 .NET SDK 10.0.403。

ChaITSimpleLove的博客 365

.NET 可观测性选型:Metrics、ActivitySource、EventSource 到底该用哪个

很多人把Meter当成"新版 EventSource",把当成"新版 DiagnosticSource",然后在生产环境里发现:指标查不到、链路断了、开销还不小。这三个 API 解决的是三个不同维度的问题,混用一定会踩坑。

dotnethello的博客 165

FFmpeg × C# 实战:从命令行原理到 .NET 工程化落地

本文系统讲解 FFmpeg 的核心概念(容器/编码/流/滤镜/时间基),并给出 C# 对接的五条技术路线对比。重点实现一个可落地的 FFmpegRunner 封装,解决管道死锁、结构化进度解析、取消超时、二进制分发与参数注入五大工程问题;随后覆盖转码、裁剪、合并、抽帧、限体积压缩、水印、硬件加速六大高频场景,并附安全清单与排错速查表。

李赛赛的专栏 576

在.NET WinForms中创建SQLite数据库

本文介绍在WinForms项目中使用SQLite的完整流程:通过NuGet安装System.Data.SQLite.Core包,将数据库文件置于程序目录下,利用CREATE TABLE IF NOT EXISTS实现自动建库建表;通过封装GetConnection()方法管理连接,初始化时调用Init()创建表结构;后续通过参数化SQL实现增删改查操作,支持数据绑定、登录验证等场景,确保安全高效。

2301_80809484的博客 287

【WPF】兼容.net 4.8 相机控制

老项目兼容性问题:.NET 4.8 WinForms 可调用相机程序但界面卡住,.NET 8 可正常挂载句柄。最终通过创建空壳用户控件+自定义无边框窗口(FloatingPanelHost)实现界面悬浮绑定,利用 SetWindowPos 精确对齐屏幕坐标,确保跨进程窗口在 WPF 中正确显示,且随主窗口移动、缩放、隐藏同步,解决句柄挂载难题。

qq_37516758的博客 249

一款基于 .NET 开源、免费的数据库自治诊断平台

DBPilot。它解决的是 DBA 日常工作中最耗时的痛点:性能趋势分析、Top SQL 定位、阻塞与死锁排查,原本散落在多个工具和脚本里的活,现在一个 Web 控制台全搞定。DBPilot 是一个自托管的数据库自治诊断平台。它持续采集实例的性能数据,在同一个 Web 控制台里完成日常 DBA 工作流:性能趋势与 AAS 负载拆解、Top SQL、执行计划变更跟踪、缺失索引建议、索引使用与碎片、阻塞分析、死锁分析、慢日志。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 173

版本即契约:.NET 6 WebAPI 多版本治理与 Swagger 文档分治实践

本文基于Asp.Versioning.Mvc6.4.1,采用Swashbuckle原生路线实现.NET 6多版本API管理:通过DocInclusionPredicate反射控制器的[ApiVersion]属性分组,绕过IApiExplorer,无需引入Asp.Versioning.Mvc.ApiExplorer。结合apiVersions数组统一管理版本,确保配置一致。配合VersionDefaultValueFilter自动填充路径参数默认值,AddApiVersioningConfig实现未指定版本时

m0_74000869的博客 350

Keycloak.Admin.Sdk 26.8.1-preview.3 发布:从管理 API 到应用协议的 .NET 10 SDK

如果你的项目正在使用 Keycloak 26.8.1,欢迎通过 NuGet 体验 **26.8.1-preview.3**,也欢迎提交具体接口、协议或运行环境下的使用反馈。

ChaITSimpleLove的博客 306

C# + .NET 8 + WPF + HALCON25.11

在解决方案资源管理器,右键→【设为启动项目】顶部菜单:【生成】→【生成解决方案】,看输出窗口,无报错按F5启动调试点击按钮【加载测试图】:图片显示,缺陷自动画红框,表格输出坐标。

qq_36657291的博客 266
上一篇: CruiseControl.Net 与 FxCop 集成
下一篇: 创建更新物化视图的Job
danqueen
博客等级 码龄21年 5粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值