爬取了牛客网,提炼出「性能测试」高频面试题50问

最近很多B乎粉丝都在面试性能测试工程师的岗位,

🍅知乎号主:程序员面试秘籍

💬 大厂面试真题、简历模板、近40篇面试经验文章、接口、自动化测试、性能测试、安全测试学习资源、学习路线指引。关注我,都给你

🌈 感激相遇,愿你我皆有所获

同时再问我:有没有性能测试专项面试题(包含答案这种),这不爆肝一晚上给大家整出来了。

从性能测试概念、方案、工具、性能调优并结合调优案例一并给大家整全面了。

概念篇

  1. 吞吐量、吞吐率、点击率是什么?

  2. 事务、TPS、QPS是什么?

  3. PV、UV 是什么?

  4. 负载测试、压力测试是什么?

  5. 性能测试包含了哪些测试(至少举出3种)。

  6. 简述性能测试的步骤。

  7. 性能测试什么时候开始?

方案篇

  1. 如何得到性能测试需求

  2. 「客户」在性能测试中关注什么?

  3. 「开发」在性能测试中关注什么?

  4. 「测试」在性能测试中关注什么?

  5. 需求分析应关注哪些「性能」点?

  6. 敏捷开发模型,如何设计「性能测试策略」?

  7. 对于一个缺乏性能明确需求的项目,你是如何提取性能需求  的?

工具篇

  1. 请描述LoadRunner性能测试过程?

  2. LoadRunner由哪些部件组成?

  3. LoadRunner的一些基础概念。

  4. 什么是集合点?设置集合点有什么意义?Loadrunner中设置集合点的函数是哪个?

  5. Vuser_init 中包括什么内容?

  6. Vuser_end 中包括什么内容?

  7. think time是什么?think_time有什么用?

  8. 如何在LR中进行手动关联?

  9. 如何在LR中编写自定义函数?

  10. 解释以下函数及他们的不同之处。

调优篇

  1. 请描述什么是系统性能拐点?

  2. 如何识别性能瓶颈?

  3. 打开浏览器输入网址到页面渲染,响应时间通常可以细分为哪些?

  4. 什么是内存泄露?

  5. 硬件关注「性能指标」有哪些?

  6. 中间件关注「性能指标」有哪些?

  7. 数据库关注「性能指标」有哪些?

  8. 前端关注「性能指标」有哪些?

案例篇

  1. SQL执行时间长排查

  2. 数据库出现死锁排查

  3. 线程阻塞在日志记录上排查

  4. 多线程并发问题排查

  5. 打开了太多文件排查

  6. 内存泄漏排查

  7. JVM垃圾回收频繁排查

  8. CPU高排查

  9. 批处理时间长、数据库逐笔插入缓慢排查

  10. 数据库CPU高排查

  11. 压测TPS曲线剧烈下降或抖动排查

概念篇

1. 吞吐量、吞吐率、点击率是什么?

  • 吞吐量:1次性能测试过程中网络上传输的数据量的总和。

  • 吞吐率:单位时间内网络上传输的数据量。

  • 点击率:每秒钟用户向web服务器提交的HTTP请求数。

例子:

小黑向系统A发动攻击了1次攻击,
模拟多个用户在10秒钟内请求了200次HTTP请求、并且发送了100MB流量

吞吐量:100MB
吞吐率:10MB(100MB/10秒)
点击率:20次(200次/10秒)

2. 事务、TPS、QPS是什么?

  • 事务:用户某一步或几步操作的集合,例:如用户对某一个页面的一次请求,用户对某系统的一次登录,淘宝用户对商品的一次确认支付过程。

  • TPS:每秒传输事物率,Transaction Per second,人为定义事物

  • QPS:每秒查询率,Queries Per Second,查询后端服务器次数

例子:

用户访问 index 页面会请求服务器 3 次,
包括:1次 html、1次 css、1次 js

结论:访问 index 页面产生1个“T”,产生3个“Q”。

3. PV、UV 是什么?

  • PV:page view 即页面浏览量

  • UV:Unique Visitor 指独立访客访问数,通常使用终端mac地址作为唯一标识

举例:

某网站首页1天内的用户累计「页面访问量」达到1000万,
其中「不重复的电脑mac」的数量有80万。

该网站首页1天内
PV:1000万
UV:80万

4. 负载测试、压力测试是什么?

负载测试:通过「不断的加大负载」来确定在满足性能指标情况下,目的:获取系统所能够承受的「最大并发数」。

压力测试:通过「高负载」的手段来使服务器资源处于极限的状态,目的:获取系统在极限状态「长时间运行是否稳定」。

举例:

背景:某系统A存在用户注册、登录、访问首页的业务,
目前需要对登录业务进行性能测试任务。

负载测试:设置并发数10、20、50、100来验证系统「最大并发数」是多少。
压力测试:假设「最大并发数」是50,那么设置10倍即500并发数,
看系统在极限情况下「长时间运行是否稳定」。

5. 性能测试包含了哪些测试(至少举出3种)?

6. 简述性能测试的步骤。 

  • 1)熟悉应用:了解应用的架构、功能逻辑;

  • 2)需求分析:根据测试目的,细化需求;

  • 3)测试准备:客户端准备、测试数据准备、测试脚本准备;

  • 4)执行测试:监控测试客户端和服务器性能,监控服务器端应用情况;

    • 客户端的系统资源(CPU、IO、Memory)情况;

    • 服务端的系统资源(CPU、IO、Memory)情况;

    • 服务器的JVM运行情况;

    • 服务端的应用情况是否有异常;

    • 响应时间、吞吐量等指标;

  • 5)性能分析与调优:找出性能瓶颈,提高系统整体性能,满足用户需求;

  • 6)编写测试报告:测试结束后,归档整理测试报告;

7. 性能测试什么时候开始?

  • 一般在系统功能稳定没有大的缺陷之后开始执行。

  • 但前期准备工作可以从系统需求分析时就开始:性能目标制定、场景获取、环境申请等。

方案篇

1. 如何得到性能测试需求

  • 查看需求文档提取性能测试需求,了解客户实际使用情况;

  • 结合业务信息,设计操作场景从而总结出需要测试的性能关键指标;

  • 执行用例后,提取关键性能指标来分析是否满足性能需求;

2. 「客户」在性能测试中关注什么?

  • 客户:重点关注打开速度及响应时间;

    • 在进行操作时,每个请求之间的间隔时间;

    • 大量用户在同一时刻在软件系统上操作是否有较好的体验;

3. 「开发」在性能测试中关注什么?

  • 开发人员:重点关注响应时间和数据库交互,进行性能调优;

    • 系统架构:架构设计是否合理;

    • 数据库设计:数据库设计是否存在问题;

    • 代码:代码是否存在性能方面的问题,系统中是否有不合理的内存使用方式;

    • 业务逻辑:系统中是否存在不合理的线程同步方式,系统中是否存在不合理的资源竞争;

4. 「测试」在性能测试中关注什么?

  • 测试人员:重点关注用户感受到的软件性能;

    • 系统的响应时间;

    • 系统状态的相关信息,如:CPU、内存、应用服务器状态、JVM可用内存、数据库的状态等;

    • 系统的可扩展性,处理并发的能力;

    • 系统可能的最大容量,可能的性能瓶颈,通过更换哪些设备或是进行哪些扩展能够提高系统性能;

    • 长时间运行是否足够稳定,是否能够不间断的提供业务服务等;

5. 需求分析应关注哪些「性能」点?

  • 明确到底要不要做性能测试,性能测试的目的是什么;

  • 明确被测系统的架构、软硬件配置、网络等;

  • 明确被测系统的基本业务、关键业务、用户行为;

  • 明确被测系统未来的业务拓展规划以及性能需求;

  • 明确工具选型,比如Jmeter、LoadRunner等;

  • 明确性能测试的指标,比如并发、吞吐量、响应时间等;

6. 敏捷开发模型,如何设计「性能测试策略」?

  • 每个迭代目标中包含明确的性能目标;

  • 建立不同层次的性能测试;

  • 完全或接近完全自动化的性能测试;

  • 使用测试驱动方法保证性能与优化性能;

7. 对于一个缺乏性能明确需求的项目,你是如何提取性能需求的?

  • 与客户交流,查看历史日志,跟同类产品对比,根据以往的经验。

工具篇

1. 请描述LoadRunner性能测试过程?

2. LoadRunner由哪些部件组成?

  • VuGen(Virtual User Generator):录制脚本,录制一个场景(在一个事务中),通过录制或编写脚本来模拟用户的行文;对用户名、密码参数化(使多个用户运行同一脚本,在本地修改用户名密码),到Controller;

  • Controller:设置场景、监控运行场景,收集数据到Controller;

  • Analysis:在测试完成后,对测试过程中收集到的各种性能数据进行计算、汇总和处理,生成各种图表和报告,为系统性能测试结果分析提供支持。

3. LoadRunner的一些基础概念。

  • Scenario:场景。所谓场景,是指在每一个测试过程中发生的事件。

  • Vusers:虚拟用户。LoadRunner使用多线程或多进程来模拟用户对应用程序操作时产生的压力。一个场景可能包括多个虚拟用户,甚至成千上万个虚拟用户。

  • Vuser Script:脚本。用脚本来描述Vuser在场景中执行的动作。

  • Transactions:事务。事务代表了用户的某个业务过程,需要衡量这些业务过程的性能。

  • rendezvous :集合。当我们测试多个用户并发时,每个用户执行到该事务脚本的先后顺序是不确定的,所以得到的测试结果也并不是一个完全 并发的极限测试结果。在开始事务之前 ,插入一个“集合点”,那么在多用户执行时,就可以将用户请求停下来,直到用户数量达到满足的条件(默认是100%的用户都到达集合点)。那么,所有的用户都将同时发出接下来的请求。

4. 集合点是什么?集合点意义是什么?Loadrunner中设置集合点的函数是哪个?

  • 集合点是什么:在测试计划中,可能会要求系统能够承受1000 人同时提交数据,在LoadRunner 中可以通过在提交数据操作前面加入集合点,这样当虚拟用户运行到提交数据的集合点时,LoadRunner 就会检查同时有多少用户运行到集合点,如果不到1000 人,LoadRunner 就会命令已经到集合点的用户在此等待,当在集合点等待的用户达到1000 人时,LoadRunner 命令1000 人同时去提交数据,从而达到测试计划中的需求。

  • 集合点意义是什么:插入集合点是为了衡量在加重负载的情况下服务器的性能情况。

  • 集合点函数:rendezvous 

5. Vuser_init中包括什么内容?

 vuser_init:虚拟用户的初始化函数,一般将用户初始化的操作放在这里,如登录操作、分配内存等。

6. Vuser_end中包括什么内容? 

  • vuser_end () :与vuser_init相对,结束函数,只运行一次,例如登出操作,内存释放等。

  • 请描述什么是系统性能拐点?

  • 如何识别性能瓶颈?

  • 打开浏览器输入网址到页面渲染,响应时间通常可以细分为哪些?

  • 什么是内存泄露?

  • 硬件关注「性能指标」有哪些?

  • 中间件关注「性能指标」有哪些?

  • 数据库关注「性能指标」有哪些?

  • 前端关注「性能指标」有哪些? 

7.think time是什么?think_time有什么用?

  • think time是什么:用户在执行连续操作之间等待的时间称为“思考时间”,它是决定对服务器施压大小的因素之一。

  • think_time有什么用:设置思考时间,是为了更真实的模拟用户 

8. 如何在LR中进行手动关联?

  • 录制测试脚本,录制二遍

  • 使用WinDiff工具找出两次脚本的不同,判断是否需要进行关联

  • 确定插入关联的位置

  • 在VIEW TREE中使用web_reg_save_param函数手动建立关联

  • 将脚本中有用到关联的数据,用参数代替

  • 验证关联的正确性 

9. 如何在LR中编写自定义函数?

  • 在创建用户自定义函数前我们需要和创建DLL(external libary)。把库放在VuGen bin 目录下。

  • 一旦加了库,把 自定义函数分配做一个参数。该函数应该具有一下格式:__declspec (dllexport) char* (char*, char*)。

10. 解释以下函数及他们的不同之处。

  • lr_debug_message 函数在指定的消息级别
    •  // 处于活动状态时发送一条调试消息。如果指定的

    •  // 消息级别未处于活动状态,则不发出消息。

  • Lr_output_message 要发送不是特定错误消息的特殊通知

  • Lr_error_message  函数将错误消息发送到// 输出窗口和 Vuser日志文件

  • Lrd_stmt lrd_exec 函数执行 lrd_stmt设置的 SQL 语句。

  • Lrd_fetch  函数从结果集中提取后续若干行 

调优篇

1.请描述什么是系统性能拐点?

 性能开始急剧下降的点。

2.如何识别性能瓶颈?

  • 硬件上的性能瓶颈:如CPU、内存、磁盘读写等的瓶颈,为服务器硬件瓶颈;

  • 应用软件上的性能瓶颈:如服务器操作系统瓶颈(参数配置)、数据库瓶颈(参数配置)、web服务器瓶颈(参数配置)、中间件瓶颈(参数配置)等;

  • 应用程序上的性能瓶颈:应用程序上的性能瓶颈,如SQL语句、数据库设计、业务逻辑、算法等等;

  • 操作系统上的性能瓶颈:一般指的是Windows、linux等操作系统,如出现物理内存不足时,或虚拟内存设置不合理(虚拟内存设置不合理,会导致虚拟内存的交换率大大降低,从而导致行为的响应时间大大增加,可以认为在操作系统上出现了性能瓶颈);

  • 网络设备上的性能瓶颈:一般是防火墙、动态负载均衡器、交换机等设备导致;

3.打开浏览器输入网址到页面渲染,响应时间通常可以细分为哪些?

  • 从客户端到服务端的请求时间(请求网络传输时间Request);

  • 从服务端返回数据到客户端的时间(响应网络传输时间Response);

  • 页面渲染时间(客户端浏览器加载页面的时间);

  • 处理器的处理时间(应用服务器+数据库服务器处理时间);

4. 什么是内存泄露?

  • 内存泄漏是指对象不再被应用程序使用,但是垃圾回收器却不能回收它们,因为它们正在被引用。

  • 对于长时间运行的程序来说,内存泄漏会使程序占用的内存一直增加,最后就会出现内存耗尽而导致宕机。

  • 即使不宕机也会是系统的运行越来越慢,还有就是内存有其他资源,比如数据库连接,网络连接等等

5. 硬件关注「性能指标」有哪些?

  • 硬件性能指标:CPU,内存Memory,磁盘I/O(Disk I/O),网络I/O(Network I/O) ;

6. 中间件关注「性能指标」有哪些?

  • 中间件:常用的中间件如web服务器Tomcat, Weblogic web服务器,JVM(java虚拟机),ThreadPool线程池,JDBC数据驱动 ;

7. 数据库关注「性能指标」有哪些?

  • 数据库指标:SQL,吞吐量,缓存命中率,连接数等;

8. 前端关注「性能指标」有哪些?

  • 前端指标 :首次显示时间,页面数量,页面大小,网络startRender,firstRender等。

  • 前端的性能与后端的性能的不同点在于,前端是每个用户的直观的感受,如前端页面加载元素耗费的时间,

  • 后端的性能关注点在于多用户使用系统时,服务器是否能够承受或者服务器的处理能力如何,能否以较好的响应时间响应; 

案例篇

1. SQL执行时间长排查

  • 问题现象:系统响应时间长、数据库cpu高。

  • 问题原因:全表扫描、索引低效、排序溢出。

  • 解决方法:

    • 通过数据库快照查看执行时间长的SQL,查看该SQL执行计划,在cost比较高的SQL上增加合适索引。要求所有大表SQL执行计划的cost低于100,超过100的SQL要评审。对于排序溢出、可参考数据中心规范设置排序堆大小,规范中排序堆设置为AUTOMATIC。

    • 制定数据库表清理策略。根据数据的生命周期要求,对流水类的数据定期进行清理备份,不再长期保留。定期对全库的表结构进行reorg、runstats操作,以提高索引效率。

  • 排查方法:

    • 获得数据库快照(DB2数据库为例):db2 get snapshot for all on corpdb >gswyzfzzshpl1207.log

    • 从快照中提取慢SQL,Toad查看SQL执行计划

    • Db2命令方式查看SQL执行计划:db2expln -d corpdb -t -g -q “SQL语句”

    • 执行计划查看方法:自上而下查看cost最大的分支,找到未走索引或索引使用不当的表 

2. 数据库出现死锁排查

  • 问题现象:数据库快照检测到存在数据库死锁,或通过db2evmon -db corpdb -evm DB2DETAILDEADLOCK>dlock.txt生成死锁监控文件,快照或监控文件中存在deadlock的情况。

  • 问题原因:全表扫描、大事务、更新相同表记录的SQL执行顺序交叉等。

  • 解决方法:缩短事务路径长度,避免全表扫描。如果必须存在大事务,则更新相同表的SQL执行顺序一致,并且坚决避免全表扫描。网银系统指令发送功能全表扫描+全局大事务,导致数据库死锁。

  • 排查方法:根据死锁监控文件dlock.txt找到导致死锁的SQL,以及该SQL持有的锁,分析该SQL可能存在的问题。 

3. 线程阻塞在日志记录上排查

  • 问题现象:系统响应时间长、通过javacore查看很多线程阻塞在打印日志上。

  • 问题原因:log4j1.x版本较低,性能较差;大报文日志多次输出。

  • 解决方法:

    • 减少无效日志、删除无用日志,减少大日志输出。

    • 升级log4j组件到log4j2,参考log4j2官方文档,配置合理的日志缓冲区,采用高效的Appenders,比如RollingRandomAccessFile。但log4j2仍然采用同步日志,不采用异步日志。如果日志量少(压测产生日志的速度,低于日志写入文件的速度),则可以使用异步日志,大幅提高性能。如果日志量较大,则不建议使用异步日志。

  • 排查方法:

    • JVM启动参数中增加-XX:+HeapDumpOnCtrlBreak,压测进行时,kill -3 pid 杀几个javacore,使用jca457.jar工具打开并分析。推荐使用该工具,因为该工具可以对所有线程状态进行统计,并生成饼状图,方便查看。

    • 压测进行时,使用jvisualvm获取jvm快照,分析线程堆栈。 

4. 多线程并发问题排查

  • 问题现象:采用合理的并发数压测,系统出现逻辑错误、交易失败或异常报错。经查是由于对象中变量被异常修改导致。

  • 问题原因:系统中全局对象中的类变量或全局对象,被多个线程修改。

  • 解决方法:排查系统中所有持有全局对象或类变量的代码,检查其全局变量是否可能被多个线程并行修改。

  • 修改方法:

    • 将全局变量转成方法内的局部变量;

    • 对全局变量进行同步控制比如syncronized代码块,或者java.util.concurrent锁。 

  • 排查方法:并发问题很可能是由全局变量或者对象导致,准确识别全局变量,通过阅读代码找问题。建议应用梳理所有可能存放全局对象的代码,统一管控,或者把所有全局对象放到一个类中,方便管理。 

5. 打开了太多文件排查

  • 问题现象:采用合理的并发数压测,交易失败,或后台日志报错:To many open files。

  • 问题原因:

    • 读取配置文件或者业务数据文件后,未关闭文件流;

    • /etc/security/limits.conf中最大打开文件数配置过小

  • 解决方法:

    • 使用lsof –p pid 命令查看进程打开的文件,如果大部分文件都是同一类型的文件,说明可能未关闭文件流。找到打开文件的代码,关闭文件流即可。

    • 如果不存在未关闭文件流的问题,且业务本身就需要处理大量文件,则修改/etc/security/limits.conf 

vim /etc/security/limits.conf  
#在最后加入  
* soft nofile 4096  
* hard nofile 4096  

6. 内存泄漏排查

  • 问题现象:JVM内存耗尽,后台日志抛出OutOfMemeryError异常;

  • 问题原因:内存溢出问题可能的原因比较多,可能是全局的List、Map等对象不断被扩大,也可能是程序不慎将大量数据读到内存里;可能是循环操作导致,也可能后台线程定时触发加载数据导致。

  • 解决方法:对于jdk纯java应用,在jvm启动时设置-XX:+HeapDumpOnOutOfMemory Error参数,会在内存溢出时生成heapdump文件。使用MAT(memory analyzer tool)工具打开heapdump文件,分析大对象是如何产生的。

    • 当然,在heapdump中对象类型可能只是List这种结构,看不出具体哪个业务代码创建的对象。此时要分析所有的全局对象,列出可疑的List或Map对象,排查其溢出原因。

    • 全局对象、引用的初始化、修改要慎重。建议应用梳理所有可能存放全局对象的代码,统一管控。 

7. JVM垃圾回收频繁排查

  • 问题现象:top –H –p pid命令查看,GC Slave线程CPU占用排名始终为前三名,同时Jconsole查看jvm内存占用较高,垃圾回收频繁。使用JConsole分析gc日志,查看gc频率、时长。

  • 问题原因:高并发下,内存对象较多,jvm堆内存不够用 。

  • 解决方法:扩大堆内存大小–Xmx2048m –Xms2048m。 

8. CPU高排查

  • 问题现象:50并发压测,监控工具显示bp、前置CPU占用90%以上。

  • 问题原因:业务处理中存在大量CPU计算操作。

  • 解决方法:采用更高效的算法、数据结构替换原来消耗CPU的代码,或者采用新的设计绕过瓶颈代码,比如查找数据的逻辑,可以把List改为Map,以空间换时间;比如用Json报文替换XML报文,提高传输、解析和打印日志的效率。

    • 导致Cpu计算资源高消耗的代码:报文格式转换、加解密、正则表达式、低效的循环、低效的正则表达式。

  •  排查方法:
    • 压测进行时,使用jvisualvm工具远程连接应用,点抽样器àCPU,点快照生成线程快照。采样一段时间后,抽样器会显示各个方法占用cpu时间,可以针对CPU时间占用高的方法进行优化。

    • 使用tprofiler,jprofiler,OracleDeveloperStudio12.6-linux-x86工具分别分析消耗CPU时间长的方法,以上工具分析结果可能有些差别。针对CPU计算耗时最长的方法进行优化。 

9. 批处理时间长、数据库逐笔插入缓慢排查

  • 问题现象:大批量数据(10万条以上)更新或插入数据库,耗时较长。

  • 问题原因:批量数据处理时,如果逐条更新数据库,则会存在大量网络io、磁盘io,耗时较长,而且对数据库资源消耗较大。

  • 解决方法:

    • 采用java提供的batchUpdate方法批量更新数据库,每1000条commit一次,可大幅提高数据更新效率。

    • 单线程改成线程池,并行处理,充分利用多核CPU,通过数据库或者其他同步锁控制并行性;增加缓冲池,降低数据库或磁盘IO访问频次。 

10. 数据库CPU高排查

  • 问题现象:后台指令发送满负荷工作时,数据库CPU高。

  • 问题原因:后台指令发送线程每次对全量查询结果排序,结果集很大,然后取一条记录;索引区分度不高,满负荷执行时;查询频率很高;压测显示,并行发送指令的后台线程越多,数据库CPU越高,效率越低。

  • 解决方法:

    • 去掉ORDER BY,增加索引后,效果不明显。因为结果集大和查询频繁两个问题没有解决,因此考虑使用设计新的方案。

    • 新方案:设计指令发送线程池,生产者线程每台任务服务器只有一个线程,负责查询待发送指令,每次查询50条指令。每条指令包装成一个Runnable对象,放进ThreadPoolExecutor线程池,线程池大小参数设置为100或200。每当线程池满时,生产者停止生产指令,休息15秒后继续。消费者线程即线程池里的线程,参数设置为4,8或12(和不同指令类型的指令数据量成正比)。

    • 改进后的方案,数据库CPU降到10%一下,发送效率单机提升6倍,且可线性扩展任务服务器。 

11. 压测TPS曲线剧烈下降或抖动排查

  • 问题现象:50并发压测,TPS曲线正常应该是平缓的,波动不大,如果突然出现剧烈下降,并且短时间内无法恢复,则可能存在问题。

  • 问题原因:一般是由于前置或bp的jvm进行垃圾回收,或者日志记录磁盘满导致的。

  • 解决方法:如果不是特别剧烈的波动或者TPS曲线下降后长时间不反弹,则可以忽略该问题。否则,需要分析曲线下降的时刻,系统当时正在发生的事情。可以通过top命令监控当时CPU占用比价高的线程,也可以kill -3 pid杀javacore来查看线程堆栈。 

资料白嫖关注公号:程序员一凡,可自行🔍WeChat查看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值