2.1 Spring

来源于牛客网:https://www.nowcoder.com/discuss/161991

1、说一下IOC和AOP?

IOC

Spring 通过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化

Bean 并建立 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工作的基础上,还提供

了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务。

AOP

"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,

并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共

同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未

来的可操作性和可维护性。

使用"横切"技术,AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流

程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生

在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP 的作用在于分离系统

中的各种关注点,将核心关注点和横切关注点分离开来。

2、介绍一下bean的生命周期

1.实例化bean对象(通过构造方法或者工厂方法)
2.设置对象属性(setter等)(依赖注入)
3.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
4.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
5.将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
6.调用Bean的初始化方法
7.将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
8.使用Bean
9.容器关闭之前,调用Bean的销毁方法
 

3、Spring里面注解用过没有?autowired 和resource区别?

1、@Autowired

由Spring提供,只按照byType注入

2、@Resource

由J2EE提供,默认按照byName自动注入

@Resource有两个重要的属性:name和type

Spring将@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

@Resource装配顺序:

(1)如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

(2)如果指定了name,则从Spring上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

(3)如果指定了type,则从Spring上下文中找到类型匹配的唯一bean进行装配,找不到或找到多个,都抛出异常

(4)如果既没指定name,也没指定type,则自动按照byName方式进行装配。如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入。

3、使用区别

(1)@Autowired与@Resource都可以用来装配bean,都可以卸载字段或setter方法上

(2)@Autowired默认按类型装配,默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。如果想使用名称装配可以结合@Qualifier注解进行使用。

(3)@Resource,默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行名称查找。如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

         推荐使用@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与Spring的耦合。

         另外,通过实践,还总结出一条规律:

         如果@Requied或者@Autowired写了set方法之上,则程序会走到set方法内部。但如果写在了field之上,则不会进入set方法当中。

转载:http://blog.sina.com.cn/s/blog_9075354e0101huup.html

4、@Controller和@RestController的区别?

@RestController注解相当于@ResponseBody和@Controller的结合

但是在使用@RestController注解的时候需要注意几个问题:

1.如果使用@RestController注解Controller,那么该Controller中的方法就无法返回jsp页面,就是说如果在方法中return "xx",那么它只会返回"xx"的内容,因为@RestController中相当于已经有了@RessponseBody的注解效果,所以它无法返回jsp,html界面,配置的InternalResourceViewResolver不工作,只返回return的内容。

2.根据第一条的规定,如果该Controller中需要返回jsp,html界面,那么就需要使用@Controller注解Controller,不能用@RestController。

3.第一条中说到@RestController注解的Controller只返回return中的内容,所以如果我们在Controller方法中需要返回JSON、XML或者我们自己定义的类型到页面中,那么就需要使用@ResponseBody注解该方法。
参考:https://blog.csdn.net/xiaoxinxin123456789/article/details/85621172

5、依赖注入的方式有几种,哪几种?

  • Set注入

这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口)。

  • 构造器注入

这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来。

  • 静态工厂的方法注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取

  • 实例工厂的方法注入

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法。

  • 总结

Spring IOC注入方式用得最多的是(1)(2)种,多谢多练就会非常熟练。

        另外注意:通过Spring创建的对象默认是单例的,如果需要创建多实例对象可以在<bean>标签后面添加一个属性:

Java代码 

 收藏代码

  1. <bean name="..." class="..." scope="prototype"> 

参考:https://blessht.iteye.com/blog/1162131

6、springIOC原理?自己实现IOC要怎么做,哪些步骤?

IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩。Java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用他的合作对象时,自己均要使用像new object() 这样的语法来完成合作对象的申请工作。你会发现:对象间的耦合度高了。而IOC的思想是:Spring容器来实现这些相互依赖对象的创建、协调工作。对象只需要关系业务逻辑本身就可以了。从这方面来说,对象如何得到他的协作对象的责任被反转了(IOC、DI)。
这是我对Spring的IOC的体会。DI其实就是IOC的另外一种说法。DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
如果对这一核心概念还不理解:这里引用一个叫Bromon的blog上找到的浅显易懂的答案:

IoC与DI

  首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。

  那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。如果你还不明白的话,我决定放弃。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。关于反射的相关资料请查阅java doc。
 理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工作只是在spring的框架中堆积木而已

参考:http://blog.csdn.net/it_man/article/details/4402245

自己实现???

7、Spring中BeanFactory和ApplicationContext的区别?

BeanFactory是Spring中最基本、通用的工厂,这里的工厂,其不仅仅是构造实例,它可以创建并管理各种类的对象,即是Spring IOC容器体系结构的基本接口,其与其子接口便构成了Spring IOC容器的体系结构(如下图:IOC容器主要接口关系图)。所以不要把它理解成常规意义的简单工厂,也可以把它称为Sring容器。

而ApplicationContext也是一个Spring容器,它是由BeanFactory接口派生而来,因而提供BeanFactory所有的功能,此外它还扩展了BeanFactory的功能,提供了更多的高级功能:

1. MessageSource, 提供国际化的消息访问  
2.资源访问,如URL和文件  
3.事件传播  
4.载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

所以联系上它们本身都是Spring提供的接口,它们都和其子接口构成了Spring IOC的容器,我们一般都称他们为Spring容器。其中BeanFactory是Spring框架的基础设施,面向Spring本身,其提供基本的功能,如:getBean(),;ApplicationContext是建立在它之上,面向使用者,扩展了更多面向应用的功能,更易于创建实际应用,实际也基本使用它。
区别上:由上述可知他们提供的功能是有不同的,体系结构、用途等有所不同。另外他们在初始化时有一个重大的区别:BeanFactroy初始化容器时,并未初始化Bean,直到第一次在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化(延迟加载),这样的话,我们就不能在初始化容器时发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,就一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 

 

8、什么是IoC和DI?DI是如何实现的?

重复

9、请问Spring中Bean的作用域有哪些?

当通过spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:

  • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

  • prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

  • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

  • session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

  • globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。

参考:https://www.cnblogs.com/goody9807/p/7472127.html

10、谈谈Spring中自动装配的方式有哪些?

1.       no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。

2.       byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

3.       byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

4.       constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。

5.       autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。
参考:https://blog.csdn.net/pangqiandou/article/details/53388518

11、aop的应用场景?

AOP 主要应用场景有:

1. Authentication 权限

2. Caching 缓存

3. Context passing 内容传递

4. Error handling 错误处理

5. Lazy loading 懒加载

6. Debugging 调试

7. logging, tracing, profiling and monitoring 记录跟踪 优化 校准

8. Performance optimization 性能优化

9. Persistence 持久化

10. Resource pooling 资源池

11. Synchronization 同步

12. Transactions 事务

12、AOP的原理是什么?

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

参考https://blog.csdn.net/wuruijiang/article/details/78970720

13、你如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?

  • 连接点:程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。
  • 切点:如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
  • 增强:增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。很多资料上将增强译为“通知”,这明显是个词不达意的翻译,让很多程序员困惑了许久。
  • 引介:引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过引介功能,可以动态的未该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
  • 织入:织入是将增强添加到目标类具体连接点上的过程,AOP有三种织入方式:
    1. 编译期织入:需要特殊的Java编译期(例如AspectJ的ajc)
    2. 类装载期织入:要求使用特殊的类加载器
    3. 动态代理织入:在运行时为目标类生成代理实现增强
Spring采用了动态代理织入,而AspectJ采用了编译期织入和类装载期织入的方式。
  • 切面:切面是由切点和增强(引介)组成的,它包括了对横切关注功能的定义,也包括了对连接点的定义。

参考:http://www.voidcn.com/article/p-uxbjxtmw-dh.html

14、Spring支持的事务管理类型有哪些?你在项目中使用哪种方式?

Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。

事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。
参考:https://blog.csdn.net/troubleshooter/article/details/78468767

15、介绍一下spring?

链接:https://www.nowcoder.com/questionTerminal/bcfd9351afbd4499873bc2fef66738ba?orderByHotValue=1&page=1&onlyReference=false

1、Spring的核心是一个轻量级(Lightweight)的容器(Container)

2、Spring是实现Ioc(Inversion of Control)容器和非入侵性(No intrusive)的框架

3、Spring提供AOP(Aspect-oriented programming)概念的实现方式

4、Spring提供对持久层(Persistence)、事务(Transaction)的支持

5、Spring提供MVC Web框架的是实现,并对一些常用的企业服务api提供一致的模型封装

6、Spring提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案

总之,Spring是一个全方位的应用程序框架

16、Struts拦截器和Spring AOP区别?

我们知道struts2使用拦截器主要是用来处理用户的请求,OGNL的使用,表单验证 等。

而spring的拦截器,主要体现在AOP的事务管理方面,还有比如一些错误或者异常的日志的显示 也是通过配置spring的log拦截器来实现的。

Struts的拦截器是针对Struts的,比如SSH项目都会去使用AOP ,如果是单纯的STRUTS项目 自然使用Struts本身的拦截器,两者最终效果是一样的;对于应用来说没什么区别,但对于底层实现方式来说有细微的区别!拦截器是AOP的一种实现,struts2 拦截器采用xwork2的interceptor!而spring的AOP基于IoC基础,其底层采用动态代理与CGLIB代理两种方式结合的实现方式。

参考:https://www.cnblogs.com/IcreamPrince/p/3995616.html

17、spring框架的优点?

链接:https://www.nowcoder.com/questionTerminal/e2c9c293f26f46fba3fad98165598467?orderByHotValue=1&page=1&onlyReference=false
1.轻量:基础版本只有2MB

2.控制反转:通过控制反转,实现松散耦合,对象们给出他们的依赖,而不是通过创建或查找对象的依赖

3.面向切面编程:通过面向切面编程,实现业务逻辑和系统服务分开,支持面向切面编程

4.事务管理:spring提供事务管理接口,实现本地事务和全局事务的管理

5.异常处理:提供异常处理接口,把hibernate或者jdbc的异常转为一致的unchecked异常

6.容器:spring包含并管理应用中对象的生命周期和配置

7.MVC框架:spring的web框架是一个优秀的框架,是web框架的替代品

18、选择使用Spring框架的原因(Spring框架为企业级开发带来的好处有哪些)?

重复

19、持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些?

所谓”持久”就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。

持久层设计的目标包括:

  • 数据存储逻辑的分离,提供抽象化的数据访问接口。
  • 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。
  • 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。
  • 数据抽象,提供更面向对象的数据操作。

持久层框架有:

参考:https://www.jianshu.com/p/13d610bf1580

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值