面试题解答系列:单例模式:懒汉、饿汉以及双重检查

2024得物校招面试真题汇总及其解答(二) RDB 是 Redis 的一种快照持久化方式,它会在指定的时间间隔内将数据库的状态保存为一个二进制文件。方法来初始化 Spring 容器,该方法会扫描启动类所在的包及其子包,并将所有符合条件的类注册到 Spring 容器中。单例模式是一种常用的设计模式,它保证一个类只有一个实例,并提供一个全局访问点来获取该实例。数据库锁是使用数据库中的记录来实现锁。在实际应用中,可以根据具体的需求调整 Spring Boot 的启动过程。正则表达式可以用于分割文本中的单词,然后使用计数器记录每个词出现的次数。 阅读详情

一、基本概念单例模式属于创建型设计模式。确保一个类只有一个实例,并提供该实例的全局访问点。实现: 使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。
二、结构类图:私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
三、几类经典单例模式实现1、懒汉式-线程不安全下面的实现中,私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。这个实现在多线程环境下是不安全的,如果多个线程能够同时进入
if (uniqueInstance == null) ,并且此时 uniqueInstance == null,
那么会有多个线程执行 uniqueInstance = new Singleton();
语句,这将导致实例化多次 uniqueInstance。// 懒汉式: 线程不安全
// 有延迟加载: 不是在类加载的时候就创建了,而是在调用newStance()的时候才会创建
public class Singleton {

private static Singleton uniqueInstance;

private Singleton(){

}

public static Singleton newInstance(){
    if(uniqueInstance == null)
        uniqueInstance = new Singleton();
    return uniqueInstance;
}

}
2、懒汉式-线程安全-性能不好为了解决上面的问题,我们可以直接在newInstance()方法上面直接加上一把synchronized同步锁。那么在一个时间点只能有一个线程能够进入该方法,从而避免了实例化多次 uniqueInstance。但是当一个线程进入该方法之后,其它试图进入该方法的线程都必须等待,即使 uniqueInstance 已经被实例化了。这会让线程阻塞时间过长,因此该方法有性能问题,不推荐使用。public static synchronized Singleton newInstance(){//在上面的基础上加了synchronized
if(uniqueInstance == null)
uniqueInstance = new Singleton();
return uniqueInstance;
}
3、饿汉式-线程安全-无延迟加载饿汉式就是 : 采取直接实例化 uniqueInstance 的方式,这样就不会产生线程不安全问题。这种方式比较常用,但容易产生垃圾对象(丢失了延迟实例化(lazy loading)带来的节约资源的好处)。它基于 classloader机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazyloading 的效果。public class Singleton {

// 急切的创建了uniqueInstance, 所以叫饿汉式
private static Singleton uniqueInstance = new Singleton();

private Singleton(){
}

public static Singleton newInstance(){
    return uniqueInstance;
}

// 瞎写一个静态方法。这里想说的是,如果我们只是要调用 Singleton.getStr(...),
// 本来是不想要生成 Singleton 实例的,不过没办法,已经生成了
public static String getStr(String str) {return "hello" + str;}

}
4、双重校验锁-线程安全uniqueInstance 只需要被实例化一次,之后就可以直接使用了。加锁操作只需要对实例化那部分的代码进行,只有当uniqueInstance 没有被实例化时,才需要进行加锁。双重校验锁先判断 uniqueInstance 是否已经被实例化,如果没有被实例化,那么才对实例化语句进行加锁。// 双重加锁
public class Singleton {

// 和饿汉模式相比,这边不需要先实例化出来
// 注意这里的 volatile,使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行
private volatile static Singleton uniqueInstance;

private Singleton() {
}

public static Singleton newInstance() {
    if (uniqueInstance == null) {
        synchronized (Singleton.class) {
            // 这一次判断也是必须的,不然会有并发问题
            if (uniqueInstance == null) {
                uniqueInstance = new Singleton();
            }
        }
    }
    return uniqueInstance;
}

}
注意,内层的第二次if (uniqueInstance == null) {也是必须的,如果不加: 也就是只使用了一个 if 语句。在 uniqueInstance == null 的情况下,如果两个线程都执行了 if 语句,那么两个线程都会进入 if 语句块内。虽然在 if 语句块内有加锁操作,但是两个线程都会执行 uniqueInstance = new Singleton();这条语句,只是先后的问题,那么就会进行两次实例化。因此必须使用双重校验锁,也就是需要使用两个 if 语句。volatile 关键字修饰也是很有必要的, uniqueInstance = new Singleton(); 这段代码其实是分为三步执行:
1)、为 uniqueInstance 分配内存空间;
2)、初始化 uniqueInstance;
3)、将 uniqueInstance 指向分配的内存地址;但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1>3>2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。
例如,线程 T1 执行了 1 和 3,此时 T2 调用 newInstance() 后发现 uniqueInstance 不为空,因此返回 uniqueInstance,但此时 uniqueInstance 还未被初始化。
使用 volatile 可以禁止 JVM 的指令重排,保证在多线程环境下也能正常运行。
5、静态内部类实现当 Singleton 类加载时,静态内部类 Holder 没有被加载进内存。只有当调用 newInstance() 方法从而触发 Holder.uniqueInstance 时 Holder 才会被加载,此时初始化 uniqueInstance 实例,并且 JVM 能确保 uniqueInstance只被实例化一次。这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。这种方式是 Singleton 类被装载了,uniqueInstance 不一定被初始化。
因为 Holders 类没有被主动使用,只有通过显式调用 newInstance() 方法时,才会显式装载 Holder 类,从而实例化uniqueInstance。
public class Singleton {

private Singleton() {
}

// 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性
// 很多人都会把这个嵌套类说成是静态内部类,严格地说,内部类和嵌套类是不一样的,它们能访问的外部类权限也是不一样的。
private static class Holder {
    private static final Singleton uniqueInstance = new Singleton();
}
public static Singleton newInstance() {
    return Holder.uniqueInstance;
}

}6、枚举实现这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。该实现在多次序列化再进行反序列化之后,不会得到多个实例。而其它实现需要使用 transient 修饰所有字段,并且实现序列化和反序列化的方法。枚举实现单例 (+测试):
public class Singleton {

private Singleton() {

}

public static Singleton newInstance() {
    return Sing.INSTANCE.newInstance();
}

private enum Sing {

    INSTANCE;

    private Singleton singleton;

    //jvm guarantee only run once
    Sing() {
        singleton = new Singleton();
    }

    public Singleton newInstance() {
        return singleton;
    }
}

public static int clientTotal = 1000;

public static int threadTotal = 200;

public static void main(String[] args) throws InterruptedException {
    ExecutorService executorService = Executors.newCachedThreadPool();

    Semaphore semaphore = new Semaphore(threadTotal);
    CountDownLatch countDownLatch = new CountDownLatch(clientTotal);

    Set<Singleton>set = Collections.synchronizedSet(new HashSet<>());//注意set也要加锁

    for (int i = 0; i < clientTotal; i++) {
        executorService.execute(() -> {
            try {
                semaphore.acquire();

                set.add(Singleton.newInstance());

                semaphore.release();
            } catch (Exception e) {

            }
            countDownLatch.countDown();
        });
    }
    countDownLatch.await();
    executorService.shutdown();

    System.out.println(set.size());//1
}

}关于序列化和反序列化:public enum Singleton {

INSTANCE;

private String name;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}测试:public class Test {

public static void main(String[] args){
    // 单例测试
    Singleton s1 = Singleton.INSTANCE;
    s1.setName("firstName");
    System.out.println("s1.getName(): " + s1.getName());

    Singleton s2 = Singleton.INSTANCE;
    s2.setName("secondName");

    //注意我这里输出s1 ,但是已经变成了 secondName
    System.out.println("s1.getName(): " + s1.getName());
    System.out.println("s2.getName(): " + s2.getName());

    System.out.println("-----------------");

    // 反射获取实例测试
    Singleton[] enumConstants = Singleton.class.getEnumConstants();
    for (Singleton enumConstant : enumConstants)
        System.out.println(enumConstant.getName());
}

}
输出:s1.getName(): firstName
s1.getName(): secondName
s2.getName(): secondName

secondName该实现可以防止反射攻击。在其它实现中,通过 setAccessible()(反射中的强制访问私有属性方法) 方法可以将私有构造函数的访问级别设置为 public,然后调用构造函数从而实例化对象,如果要防止这种攻击,需要在构造函数中添加防止多次实例化的代码。该实现是由 JVM 保证只会实例化一次,因此不会出现上述的反射攻击。四、总结一般情况下,不建议使用懒汉方式,建议使用饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用枚举方式。如果有其他特殊的需求,可以考虑使用双检锁方式。

喜欢这篇文章的可以点个赞,欢迎大家留言评论,记得关注我,每天持续更新技术干货、职场趣事、海量面试资料等等
如果你对java技术很感兴趣也可以加入我的java学习群(374308445)来交流学习,里面都是同行,群验证【优快云2】有资源共享。

搞定ESD(四):ESD干扰耦合路径深入分析(二) 静电放电过程中静电干扰主要通过三种间接耦合方式干扰敏感源,即电场耦合、磁场耦合、地弹。前文已经深入分析了静电放电过程中的电场耦合,今天就谈谈静电放电过程中的磁场耦合,也可以理解环路耦合。熟话说的好〝人往高处走,水往低处流〞,静电电流也会选择阻抗最低的路径返回到源端。静电电流流会源端的路径实际上就构成了电流环路,当敏感信号形成的电流环路与静电电流环路存在共环路时,就会将静电放电干扰耦合到敏感信号环路内,干扰敏感信号。 阅读详情

相关推荐

STM32 USB2.0 转 Type-C 接口设计与实现

本文详细介绍了STM32 USB2.0转Type-C接口的设计与实现方案,涵盖硬件电路设计、软件配置及调试技巧。重点解析Type-C接口的CC引脚配置和电源管理,提供设备模式、主机模式及双角色模式的实现方法,帮助开发者解决实际应用中的连接稳定性和ESD防护等问题,提升产品可靠性和兼容性。

blockchain9miner的博客 1020

【深入设计模式】单例模式—你确定你会写单例?饿汉式和懒汉式(DCL)演进

在项目开发中,获取一个对象我们通常是通过 new 在内存中进行创建,然后在对其进行引用,当项目逐渐庞大起来后,创建的对象越多对内存资源的占用也将越大,并且很多对象并不需要每次都创建,比如数据库连接池,因此诞生了单例设计模式。单例设计模式是指一个类只有一个实例对象,当我们获取该类对象时始终是同一个。单例模式不仅节省了内存资源,还保证了对象内的数据一致性。在使用单例模式时,我们需要注意单例模式的几个特点:根据上一节中描述的单例模式的四个特点,我们可以画出单例模式的结构图同时,我们也能够根据特点和结构图写出伪代码

SK_Jaco的博客 571

别再乱改基础库了!手把手教你搞定uni-app小程序上传图片报错(chooseAndUploadFile权限篇)

本文详细解析了uni-app开发微信小程序时遇到的`chooseAndUploadFile`权限报错问题,并提供了四步解决方案。从隐私协议与API权限的关联入手,指导开发者正确配置后台声明、双重提交策略和版本管理,避免降级基础库等常见误区,确保小程序合规运行。

weixin_33709364的博客 276

单例模式:懒汉式及饿汉式

设计模式:单例模式

weixin_41221717的博客 262

win2012 r2 + IIS8.5 伪静态设置脚本映射

win2012 r2 + IIS8.5 伪静态设置脚本映射,网站用的.net fromwork 2.0 ,应用程序池设置了32位支持

xueking87的专栏 3239

MMI分束器仿真优化:用Lumerical FDTD实现95%耦合效率的实战技巧

本文详细介绍了使用Lumerical FDTD软件对MMI分束器进行仿真优化的实战技巧。通过构建高保真模型、精确配置光源与边界条件,并重点优化波导结构与taper设计,系统性地将器件的耦合效率提升至95%以上。文章还分享了利用参数扫描、varFDTD加速等高级方法,帮助硅光芯片设计工程师高效实现高性能MMI分束器设计。

rainy的博客 772

美团面试题:单例模式懒汉式和饿汉式有哪些区别?

** 单例模式 单例模式是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 注意: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 明确定义后,看一下代码: 饿汉式 public class SingletonEH { /**

程序员麦冬的博客(公众号同名) 508

行政数据分析大屏实战:用Tableau从Excel到看板的完整搭建流程(含数据连接与字段计算避坑)

本文详细介绍了如何利用Tableau从Excel数据源搭建行政数据分析大屏的完整流程,涵盖数据准备、连接技巧、计算字段优化、看板设计及动态交互部署。通过五阶工作流,帮助用户高效处理多源异构数据,实现业务洞察与可视化呈现,提升行政数据分析效率。

weixin_29696711的博客 337

单例模式实现,懒汉式、饿汉式、同步锁、双重检查锁

单例模式(Singleton) 单例模式定义 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态。

zbh1957282580的博客 1564

autodl云服务器使用中的conda源报错

通过find path -name filename找到.condarc文件,在autodl服务器中,一般在/root/.condarc。为了利用jypyter打开conda虚拟环境运行,需要下载ipykenel。这个报错是源的问题,在通过源获取包元数据时出现了HTTP 429错误。通过conda换源解决。修改.condarc文件,命令: vim .condarc。但这样还不能解决问题,得把报错中有问题的源注释掉。通过以下命令添加清华镜像源。把报错的链接源注释如下。

Ty_kilig的博客 1584

把机器学习“搬进”数据库:SAP HANA PAL 快速上手与 ABAP AMDP 实战

摘要:本文探讨了SAP HANA PAL(Predictive Analysis Library)在企业数据分析中的实践应用。PAL通过将机器学习算法下推到数据库内部执行,有效解决了大数据量场景下的数据搬运瓶颈和治理成本问题。文章详细介绍了PAL的核心功能(包括聚类、分类、回归等10类算法)、使用前提(版本、组件和权限要求)以及通过AMDP实现ABAP与PAL集成的技术方案。重点阐述了参数表设计理念和两个典型应用场景:利用PageRank算法分析企业权限网络关系,以及通过PAL_SCALE进行特征预处理。文

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 5737

单例模式三种模式,饿汉、饱汉、双重锁模式,实例及优劣详解

单例模式是一种很基础的设计模式,在面试时可能会被要求手写不同类型的单例模式代码,主要有三种模式: 1、饿汉模式: //饿汉模式,很饿很着急,所以类加载时即创建实例对象 public class Singleton1 { private static Singleton1 singleton = new Singleton1(); private Singleton1(){

Leeon的博客 2万+

基于ESP32的智能车载环境监测系统开发

随着智能汽车技术的飞速发展,车载系统的功能越来越多样化,除了基本的行驶控制和娱乐功能外,车载环境监测系统也成为了一项重要的功能。通过实时监测车内环境数据,例如温度、湿度、空气质量、气体浓度等,智能车载环境监测系统能够提供更为舒适和安全的驾驶体验,同时增强车辆的智能化程度,提升用户的整体体验。ESP32作为一种集成了Wi-Fi和蓝牙功能的高效能低功耗嵌入式开发平台,成为了设计车载环境监测系统的理想选择。它不仅具备丰富的接口和处理能力,还能够实现与云平台、手机应用等系统的远程数据传输和控制。

2201_76125393的博客 715

详细分析单例模式

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供全局访问点。单例模式常用于管理共享资源(如数据库连接池、线程池、配置对象等)。其中的设计模式指的是,是面向对象编程的经验总结。它们分为和三大类。简要说就是类似于框架,是大佬们提供的可供使用的一种“公式”。

2301_79446157的博客 1123

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

NTscan扫描工具

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

高级java每日一道面试题-2024年7月4日-机考篇(设计模式)-请设计并实现一个线程安全的单例模式,并提供其他线程安全的单例模式的设计思路。

请设计并实现一个线程安全的单例模式,并提供其他线程安全的单例模式的设计思路。在上述代码中,使用了volatile关键字来修饰instance变量,以确保线程之间的可见性。双重检查锁定机制的原理是:首先检查instance是否为null,如果是,则加锁并再次检查,以避免不必要的同步开销。这种实现方式在多线程环境下是线程安全的,并且可以提高性能,因为只有在第一次检查发现instance为null时才需要进行同步操作。需要注意的是,volatile关键字只能保证变量的可见性,但不能保证原子性。

qq_43071699的博客 503

Camera2Demo

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

阿里java面试官问:写一个你认为最好的单例模式?怒写了7个

面试题:写一个你认为最好的单例模式 面试考察点 考察目的: 单例模式可以考察非常多的基础知识,因此对于这种问题,很多面试官都会问。 小伙伴要注意,在面试过程中,但凡能够从多个维度考察求职者能力的题目,一定不会被抛弃,特别是比较泛的问题,比如: ”请你说说对xxx的理解“之类。 考察范围: 工作1到5年经验,随着经验的提升,对于该问题的考察深度越深。 好友添加:huany6880 加入资深Java学习交流圈,并有系统整理了一套java初学/进阶者最佳的学习方法以及路 线图大纲,Java各核心知识点、架构.

Java高级教程、Java架构师、Java进阶教程 577

几率大的杂乱+操作系统面试题(含答案)

本文的面试题如下: Bean的生命周期 手写常用的几个单例模式(懒汉模式和饿汉模式,线程安全等) 各种排序的时间复杂度,堆排序和快排 简单工厂模式、抽象工厂模式、工厂方法模式的区别。 泛型的T,E,?和空的区别 秒杀系统如何设计?高并发下会出现什么问题? 分页和分段有什么区别(内存管理) 操作系统中进程调度策略有哪几种? 虚拟内存是什么 页面置换算法 面向对象的特征 解决 java 集群的 ses...

睶 1万+

Java设计模式面试题分类整理

本文系统整理了Java设计模式面试题,分为创建型和结构型模式两大类。创建型模式包括单例模式(4种线程安全实现)、工厂模式(3种工厂对比)和建造者模式(与工厂模式区别)。结构型模式涵盖适配器模式(类/对象适配器)、装饰器模式(与继承对比)和代理模式(静态/动态代理实现)。每种模式均提供典型面试问题、核心概念解释、代码示例及适用场景分析,帮助开发者深入理解设计模式原理与应用场景,为技术面试提供全面参考。

weixin_39956506的博客 783

【Java面试必备】设计模式全解析:高频面试问题及实战答案详解

尊敬的优快云读者们,在Java工程师招聘过程中,对设计模式的理解与应用能力是衡量开发者架构思维和编程素养的重要指标。本篇博客将聚焦于设计模式部分的常见面试问题,并提供详尽解答,助您轻松掌握这一核心知识点。

qq_58366795的博客 1235

2024中级Android开发面试解答之线程篇,大厂Android高级面试题汇总解答

以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。后面我就自己整理了一套资料,还别说,真香!资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

X7gUWZnYP的博客 683

Java开发程序员面试八股文:知识与经验全解析(含解答)

你也想当就java开发程序员吗?随着技术的不断发展,Java程序员的面试内容也在不断更新。本文将深入探讨Java开发程序员面试中常见的“八股文”知识与经验,并提供详细的解答,帮助你在面试中脱颖而出。

weixin_66924704的博客 657

Java热门基础面试题

Java作为广泛使用的编程语言,在面试中经常会遇到各种热点问题。

m0_37536499的博客 623

【Java高频面试题大全集】Java基础高频面试题TOP 20 原理详解

一、什么是单例模式?单例模式是一种创建型设计模式,确保一个类只有一个实例 ,并提供该实例的全局访问点。唯一性 :整个应用中只有一个实例全局访问 :提供一个静态方法获取该实例私有构造 :防止外部通过new创建实例数据库连接池配置文件管理器日志记录器线程池缓存系统二、两种常见实现方式1.饿汉式(Eager Initialization)特点 :类加载时就创建实例(急切加载)/*** 饿汉式单例* 优点:线程安全,实现简单* 缺点:类加载时就初始化,可能造成资源浪费*/

gaochufukanyongren的博客 1017

Java基础面试题(三)

当然,我们可以继续深入讨论Java及其相关技术的一些面试题和解答。

m0_37536499的博客 441

每日JAVA高级面试题

Java内存模型定义了Java程序中各种变量的访问规则,以及在并发环境下对内存的一致性保证。它对于理解多线程程序的行为至关重要。

代码互助协会的博客 605

Android岗高频面试题三集,看你能答出几题?(含答案)

下面是辛苦给大家整理的学习路线参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF下面是辛苦给大家整理的学习路线[外链图片转存中…(img-kGZMthr5-1724516606354)]参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF。

2401_85968790的博客 853
上一篇: 面试题解答系列:关系型数据库和非关系型数据的比较
下一篇: 面试题解答系列:java invokelater 以及invokeandwait
程序员plus
博客等级 码龄8年 41粉丝 151原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值