爆肝 30 天!从 JVM 调优到百万级 QPS,我的 Java 性能飞升全记录(1)

高并发大流量的Java系统策略揭秘,千万级QPS服务如何平滑启动 在应对高并发大流量情况下的Java系统平滑启动时,我们需要采取综合的策略。通过探活、懒加载、延迟注册和小流量预热,来实现Java系统在高负载情况下的稳定性启动。 阅读详情

在 Java 开发的世界里,性能优化是永恒的话题。当系统面临高并发、大数据量时,如何让 Java 应用程序保持高效运行,成为了每个开发者必须攻克的难题。接下来,我将分享自己通过 30 天时间,从 JVM 调优到实现百万级 QPS 的 Java 性能优化全历程,希望能给大家带来启发。

一、JVM 调优:性能优化的基石

JVM 作为 Java 程序运行的核心环境,其调优至关重要。首先要了解 JVM 的内存结构,包括堆内存、方法区、程序计数器、虚拟机栈和本地方法栈。其中,堆内存是对象分配的主要区域,也是调优的重点。

通过设置合理的堆内存大小参数,可以有效提升程序性能。例如,使用-Xms和-Xmx参数设置堆的初始大小和最大大小,避免频繁的内存扩展和收缩。如:

 java -Xms1024m -Xmx4096m MyApp

同时,垃圾回收机制的选择也会影响性能。常见的垃圾回收器有 Serial、Parallel、CMS 和 G1 等。对于不同的应用场景,应选择合适的垃圾回收器。比如,对于响应时间敏感的应用,CMS 垃圾回收器可能是更好的选择,它能在垃圾回收过程中尽量减少应用程序的停顿时间。

二、多线程优化:提升并发处理能力

在高并发场景下,多线程技术是提升系统吞吐量的关键。但多线程也会带来线程安全、死锁等问题。为了优化多线程性能,可以从以下几个方面入手。

1. 线程池的合理使用

线程池可以避免频繁创建和销毁线程带来的开销。Java 提供了ExecutorService接口及其实现类ThreadPoolExecutor来创建线程池。通过设置合理的核心线程数、最大线程数、队列容量等参数,可以充分利用系统资源。例如:

ExecutorService executorService = new ThreadPoolExecutor(
    5, // 核心线程数
    10, // 最大线程数
    60L, // 空闲线程存活时间
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100) // 任务队列
);

2. 锁优化

在多线程环境中,锁的使用会影响性能。尽量减小锁的粒度,使用ConcurrentHashMap等线程安全的集合类代替加锁的普通集合类。对于读写操作频繁的场景,可以使用ReadWriteLock,允许多个线程同时读,但只允许一个线程写,从而提高并发性能。

三、数据库优化:提升数据访问效率

数据库是 Java 应用程序的重要组成部分,数据库性能的好坏直接影响整个系统的性能。

1. SQL 语句优化

编写高效的 SQL 语句是数据库优化的基础。避免使用SELECT *,明确指定需要查询的字段;合理使用索引,对经常用于查询条件、排序和连接的字段创建索引。例如,对于一个查询用户信息的 SQL 语句:

SELECT id, name, age FROM users WHERE age > 18 AND city = 'Beijing';

可以在age和city字段上创建复合索引,以加快查询速度。

2. 数据库连接池

使用数据库连接池可以减少数据库连接的创建和销毁开销。常见的数据库连接池有 C3P0、DBCP 和 HikariCP 等。HikariCP 以其高性能和低资源消耗受到广泛青睐,配置示例如下:

spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/mydb
spring.datasource.hikari.username=root
spring.datasource.hikari.password=123456

四、缓存技术:减少数据库压力

引入缓存可以将经常访问的数据存储在内存中,减少对数据库的访问次数,从而提高系统性能。常用的缓存框架有 Ehcache、Guava Cache 和 Redis 等。

以 Redis 为例,它是一个高性能的键值对数据库,可以作为缓存使用。在 Java 中,通过 Jedis 或 Lettuce 等客户端库可以方便地操作 Redis。例如,使用 Jedis 获取缓存数据:

Jedis jedis = new Jedis("localhost", 6379);
String value = jedis.get("key");
if (value == null) {
    // 从数据库查询数据
    value = queryFromDatabase();
    jedis.set("key", value);
}
return value;

通过以上一系列的性能优化措施,经过 30 天的不断尝试和调整,最终实现了系统百万级 QPS 的目标。性能优化是一个持续的过程,需要不断学习和实践,希望大家在 Java 开发中也能打造出高性能的应用程序。

颠覆认知!Java 21 虚拟线程的 5 大实战场景,你用过几个?

Java 21 引入的虚拟线程,为 Java 开发者带来了全新的编程体验,它极大地简化了并发编程,提高了应用程序的性能和可扩展性。虚拟线程与传统的平台线程相比,具有轻量级、创建成本低等优势,能够轻松处理海量并发任务。下面将为大家介绍虚拟线程的 5 大实战场景,看看你是否已经应用到实际开发中。

一、高并发 Web 服务

在 Web 应用开发中,经常会面临高并发的请求。传统的线程模型在处理大量并发请求时,会因为线程数量过多而导致系统资源耗尽。而虚拟线程的出现,完美解决了这个问题。

以 Spring Boot 应用为例,通过在ThreadPoolTaskExecutor中配置虚拟线程工厂,可以轻松实现基于虚拟线程的高并发处理。首先,创建一个虚拟线程工厂:

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.VirtualThread;
public class VirtualThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        return VirtualThread.newThread(r);
    }
}

然后,在 Spring Boot 的配置类中配置线程池:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public class ThreadPoolConfig {
    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadFactory(new VirtualThreadFactory());
        executor.setCorePoolSize(100);
        executor.setMaxPoolSize(1000);
        executor.setQueueCapacity(10000);
        return executor;
    }
}

这样,当 Web 服务接收到大量请求时,虚拟线程能够快速响应,提高服务的吞吐量和响应速度。

二、异步批处理任务

在数据处理场景中,经常需要对大量数据进行异步批处理。例如,从数据库中读取大量数据,然后进行计算、转换等操作。使用虚拟线程可以轻松创建大量的异步任务,同时避免线程资源的浪费。

以下是一个简单的示例,使用虚拟线程对数据列表进行异步处理:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class BatchProcessing {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List<Integer> dataList = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            dataList.add(i);
        }
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        for (Integer data : dataList) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                // 模拟数据处理操作
                processData(data);
            }, new VirtualThreadFactory());
            futures.add(future);
        }
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
    }
    private static void processData(int data) {
        // 具体的数据处理逻辑
        System.out.println("Processing data: " + data);
    }
}

通过这种方式,可以高效地处理大量数据,提高批处理任务的执行效率。

三、微服务调用优化

在微服务架构中,服务之间的调用通常是异步的。虚拟线程可以降低微服务调用过程中的线程切换开销,提高系统的整体性能。

当一个微服务需要调用多个其他微服务获取数据时,可以使用虚拟线程并行发起调用。例如,使用HttpClient发起 HTTP 请求:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class MicroserviceCall {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        String url1 = "http://service1/api/data";
        String url2 = "http://service2/api/data";
        CompletableFuture<HttpResponse<String>> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                HttpRequest request = HttpRequest.newBuilder()
                   .uri(URI.create(url1))
                   .build();
                return client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, new VirtualThreadFactory());
        CompletableFuture<HttpResponse<String>> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                HttpRequest request = HttpRequest.newBuilder()
                   .uri(URI.create(url2))
                   .build();
                return client.send(request, HttpResponse.BodyHandlers.ofString());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, new VirtualThreadFactory());
        CompletableFuture.allOf(future1, future2).join();
        try {
            HttpResponse<String> response1 = future1.get();
            HttpResponse<String> response2 = future2.get();
            // 处理响应数据
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

通过虚拟线程并行调用微服务,可以减少整体的响应时间,提升用户体验。

四、实时日志处理

在大型应用系统中,日志量通常非常庞大。实时处理日志数据,如日志分析、统计等,需要高效的并发处理能力。虚拟线程可以快速处理大量的日志数据,满足实时性要求。

例如,使用虚拟线程对日志文件进行实时读取和分析:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
public class LogProcessing {
    public static void main(String[] args) {
        String logFilePath = "path/to/logfile.log";
        CompletableFuture.runAsync(() -> {
            try (BufferedReader reader = new BufferedReader(new FileReader(logFilePath))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    // 分析日志数据
                    analyzeLog(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, new VirtualThreadFactory());
    }
    private static void analyzeLog(String log) {
        // 具体的日志分析逻辑
        System.out.println("Analyzing log: " + log);
    }
}

通过这种方式,可以及时处理日志数据,为系统监控和故障排查提供有力支持。

五、大规模数据爬取

在数据采集领域,需要从大量的网页中爬取数据。由于网页数量众多,传统的线程模型难以高效处理。虚拟线程可以轻松创建大量的爬虫任务,快速获取数据。

以下是一个简单的网页爬虫示例:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.CompletableFuture;
public class WebCrawler {
    public static void main(String[] args) {
        String[] urls = {"http://example1.com", "http://example2.com", "http://example3.com"};
        List<CompletableFuture<String>> futures = new ArrayList<>();
        for (String url : urls) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                try {
                    URL obj = new URL(url);
                    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                    con.setRequestMethod("GET");
                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuilder response = new StringBuilder();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();
                    return response.toString();
                } catch (IOException e) {
                    e.printStackTrace();
                    return "";
                }
            }, new VirtualThreadFactory());
            futures.add(future);
        }
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        try {
            for (CompletableFuture<String> future : futures) {
                String content = future.get();
                // 处理爬取到的网页内容
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

通过虚拟线程并行发起网页请求,可以大大提高数据爬取的效率。

Java 21 的虚拟线程为开发者提供了强大的并发编程工具,在上述 5 大场景以及更多的应用场景中都能发挥巨大的作用。希望大家能够深入学习和应用虚拟线程,提升自己的 Java 开发水平。

以上两篇文章分别聚焦 Java 性能优化和虚拟线程实战。若你对文章内容深度、案例类型还有别的想法,欢迎随时告诉我。

【信息科学与工程学】【数据中心】第三十二篇 云数据中心的计算/存储/网络的核心挑战01 状态方程: SOCk+1​=SOCk​−Qn​ik​Δt​;: 三相电流变换到αβ坐标系: iα​=32​​(ia​−21​ib​−21​ic​), iβ​=32​​(23​​ib​−23​​ic​). 计算瞬时有功功率p和无功功率q,经低通滤波器分离直流分量,反变换得基波电流,差值即为谐波指令。: 节点i的信念 bi​(xi​)=ϕi​(xi​)∏j∈N(i)​mji​(xi​), 消息 mij​(xj​)=∑xi​​ϕi​(xi​)ψij​(xi​,xj​)∏k∈N(i)\j​mki​(xi​). 阅读详情

相关推荐

[Java实战]性能优化qps从1万到3万(一)

[Java实战]性能优化qps从1万到3万

曼岛_的博客 997

了解JAVA术语QPS、TPS、并发用户数、吞吐量

QPS是每秒查询率 ,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准, 即每秒的响应请求数,也即是最大吞吐能力。

Piniata的博客 2347

【模型解读】【代码复现】Segment Anything Model(SAM)

Meta AI的一个新的人工智能模型,只需一次点击就能 "分割出 "任何图像中的任何物体! SAM是一个可提示的分割系统,对不熟悉的物体和图像具有zero-shot的概括性,并且不需要额外的训练。

lalula的博客 2万+

Java中QPS、TPS、RPS等相关术语

Java基础学习

weixin_68093593的博客 1668

Tessent --- PDL

当关联的ICL模块是当前ICL顶部模块时,即当它与当前设计匹配时,只能iCall一个iTopProc。但是,可以在iTopProc内调用iCall iProc或iTopProc。为指定后续iProc命令引用的ICL模块,发出这个命令之后,随后定义的iProc都会对应的ICL模块进行定义。为后续iCall调用,当使用iCall命令调用该过程时,参数列表中的变量将被替换为iCall命令中指定的值。在调用iProc时,运行iProc内的命令。PDL是面向工程师的,工程师利用PDL语言,对ICL中的单元进行控制。

qiantianyiqian的博客 2786

scratch航天梦主题课程作品分享,包含ppt、素材包

而今年多国都将发射探测器尝试登陆月球,2023年或将称为“登月年”,请大家发挥创新思维,以“星辰大海”为创作主题,搜集相关信息 、展开联想,为实现升空 、探测 、取样贡献创意!即使去淘宝买的素材,也要从百度网盘,但素材太多大了或者太多文件,也要充值百度网盘超级会员才能保存,提高下载速度。同学们大家好,今天我们就要开始航天主题-嫦娥五号探月工程系列的编程课程了,不仅可以学习到很多航天知识,了解本次嫦娥五号的发射历程,还能让我们用编程遨游太空呢。即使下载了,也要上传,不是特别方便,尤其是不好查找。

少儿编程吕口口 2482

一次简单的Java服务性能优化,实现压测 QPS 翻倍

近两周的排查和梳理中,发现并解决了多个性能瓶颈,修改了系统熔断方案,最终实现了服务能处理的 QPS 翻倍,能实现在极高 QPS(3-4倍)压力下服务正常熔断,且能在压力降低后迅速恢复正常,以下是部分问题的排查和解决过程。答案就是会使用上面的那段”奇怪”代码,先创建一个空的 ApiContext 类,并将所有的传入参数依次尝试 set 进这个类,如果 set 失败了,就 catch 住异常继续执行,而 set 成功后,就完成了 ApiContext 类内一个属性的参数绑定。

bjmsb79的博客 625

AI提示词实战:用EARS语法5步搞定产品需求拆解(附完整案例)

本文详细介绍了如何运用EARS语法将模糊的产品需求进行原子化拆解,转化为清晰、可执行的结构化指令。通过一个完整的自由职业者项目管理工具案例,演示了从原始需求分析到构建增强AI提示词的五步实战流程,帮助产品经理和技术人员实现高效、精准的需求传达与协作。

nokia的博客 1033

什么是TPS、QPS、并发数,java面试基础问题

即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!

2301_76190858的博客 1493

密码学:一文看懂Base64算法

Base64常常在我们开发中出现,我们可能只知道它是一串乱码(看不懂的符号),知道有时候知道我们需要把一些数据进行base64编码,有时候需要进行Base64解码。但是却不知道它的作用是什么?它存在的意义是什么?还有它是如何生成的?如何编码和解码?上述的疑问相信在你读完本篇文章之后烟消云散。下面开始正文。Base64是什么?它和加密解密操作有什么关系吗?没错,这就是经过Base64编码后的字符串。对它解码后,我们获得以下内容点个关注,是对我持续创作的最大的鼓励!

Shujie 1万+

从无人机到机械臂:深入聊聊LQR和LQG在实际项目里的那些‘坑’与最佳实践

本文深入探讨了LQR和LQG在无人机和机械臂等实际项目中的应用挑战与最佳实践。从系统建模的妥协艺术到调参的系统化方法,再到离散化的细节处理,文章分享了工程实践中的宝贵经验。特别强调了如何应对传感器噪声、未建模动态等现实问题,并提供了实用的调试工具和诊断流程,帮助工程师避免常见陷阱,提升控制系统的稳定性和性能。

weixin_28683391的博客 386

tps和qps的区别和理解

Qps基本类似于Tps,但是不同的是,对于一个页面的一次访问,形成一个Tps;高负载阶段,系统利用率较高,系统响应时长随着并发数增加出现大幅增长,在此阶段并发数对系统响应时长的影响很大,其主要原因是因为系统资源满载了,请求数量大于 CPU 的核心数,导致进程或者线程不断切换,响应耗时增大。系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间、QPS(TPS):每秒钟request/事务 数量、并发数: 系统同时处理的request/事务数、 响应时间: 一般取平均响应时间。

liuqinhou的博客 888

华为OD机考双机位A卷 - 流浪地球(Java & Python& JS & C/C++ & GO )

华为OD机考双机位A卷 - 流浪地球(OD上机考试双机位A卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 4041

爆肝 30 天!从 JVM 调优到百万级 QPS,我的 Java 性能飞升全记录(3)

JVM参数:-XX:+AlwaysPreTouch 启动时预热内存页(避免运行时缺页中断)线程池:核心线程数 ≠ 最大线程数,动态扩容间隔应 ≥ 30秒SQL优化:联合索引字段顺序遵守AER原则(等值查询在前,范围在后,排序最后)缓存策略:热点Key检测算法需满足T时间内访问次数 > 3σ(标准差)混沌工程:每月至少执行一次随机杀节点演练附录:工具链全家福诊断工具Arthas:线上线程/内存实时分析async-profiler:无侵入式性能剖析压测工具Venom:全链路染色压测系统。

java_beautiful的博客 888

实战交易策略 篇二十二:情绪流龙头交易策略

在股票市场中,机构主导趋势,游资驱动热点,散户易被情绪裹挟,形成“金字塔”式生态链,并存在情绪传递、强者恒强、物极必反的规律特点。股市是资金驱动的情绪博弈场,价格波动由群体心理、资金博弈和预期差共同驱动,核心是资本逐利性与人性贪婪恐惧的交织,兼具资源配置、财富再分配与风险定价功能。涨停加速与逃逸缺口(主升强化)凹字板/平台突破(趋势延续)天量弱转强(分歧买点)不参与首波(二波策略)情绪周期(道术合一)主线思维(聚焦核心)开盘抢筹(竞价博弈)一字助攻(情绪强化)分批进出(滚动操作)

生活在别处 1499

NTscan扫描工具

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

爆肝 30 天!从 JVM 调优到百万级 QPS,我的 Java 性能飞升全记录(2)

‌参数调优‌:掌握 JVM/中间件的基础配置‌模式识别‌:从日志/metrics 中读取系统语言‌架构防控‌:设计自适应的弹性系统当系统在凌晨 4 点的大促中平稳运行的那一刻,我忽然明白:真正的性能优化,不是追求参数极值,而是让系统在混沌中保持优雅。

2501_92589102的博客 453

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java之QPS控制

什么是QPS QPS:queries per second :每秒的请求数 QPS控制的目的 防止恶意请求,增加服务端负载 以下代码可以保证在任意时间段(1s)内,请求数不超过100。 import java.util.Arrays; import java.util.concurrent.TimeUnit; /** *使用数组存储每个请求到来的时间,前10次请求顺利通过,并填满数组。 * 后续请求到来时,判断当前时间是否比数组中最早的时间晚1s,未晚,则打回, * 晚则替换数组...

wangli61289的专栏 2520

VB摄像头监控

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

如何提高Java系统的QPS(Queries Per Second)

提高Java系统的QPS是一个系统工程,需要从代码优化、数据库优化、网络与系统优化、分布式与微服务架构、监控与调优等多个方面入手。通过综合运用这些方法,可以显著提升系统的处理能力,满足高并发场景下的性能需求。同时,也要注意平衡性能与稳定性之间的关系,确保系统在追求高性能的同时,也能保持良好的稳定性和可扩展性。

weixin_65837469的博客 621

java 统计qps_统计接口QPS

现在记录话单的时候想加一个参数:每秒接口调用的并发量,也就是所谓的QPS(Queries per second)。QPS即每秒请求数,是对一个特定的接口在规定时间内请求流量的衡量标准。那么如何实现QPS的计算呢?我想到的是两种方案:1、一定时间内(比如一分钟)的请求总量/统计时间段(比如一分钟),最终得出就是每秒的并发量,它是基于某一段时间来统计的2、直接统计一秒钟内的请求总量,就是按每秒的时间段...

weixin_39689700的博客 1710

服务调用的QPS控制(Java)

代码: /** * @desc: QPS控制器 * @author: visy.wang * @date: 2020/9/25 15:09 */ public class QPSCtrl { private static int count; private static long startTime; //重置 private static void reset(long now){ count = 1; startTime = now; } /** * qps控.

咘噜biu的博客 1608

java 常见软件的性能指标

Akka:Akka 是一个基于 Actor 模型的并发框架,可以支持数百万的并发连接。从报告中,我们可以得出 Redis 的单机 QPS 可以达到 8w+(CPU 性能有关系,也和执行的命令也有关系比如执行 SET 命令甚至可以达到 10w+QPS)。需要注意的是,并发连接数只是衡量并发能力的一个指标,还需要考虑每个连接的处理时间、资源消耗等因素。Spring 框架:Spring 本身不直接处理并发,但是它可以与支持高并发的技术如 Netty、Vert.x 等集成,因此具体并发量取决于所使用的技术。

bareape的博客 5452

【java】项目中常用指标UV PV QPS TPS 等的含义和统计方法

java项目中常用指标UV PV QPS TPS 等的含义和统计方法

qq_42320804的博客 1615
上一篇: 一站式掌握高效数据处理之道
下一篇: 爆肝 30 天!从 JVM 调优到百万级 QPS,我的 Java 性能飞升全记录(2)
程序员职业指南
博客等级 码龄4年 2136粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值