30 个java编程技巧(最佳实践的初学者)

使用Optioanl优雅的处理空值 业务中的空值 场景 存在一个UserSearchService用来提供用户查询的功能: public interface UserSearchService{List listUser(); User get(Integer id);} 问题现场 对于面向对象语言来讲,抽象层级特别的重要。尤其是对接口的抽象,它在设计和开发中占很大的比重,我们在开发时希望尽量面向接口编程。 对于以上描述的接口方法来... 阅读详情

30 个java编程技巧(最佳实践的初学者)

https://blog.youkuaiyun.com/zyf__java/article/details/52437199

 

1.return 一个空的集合,而不是 null

如果一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else” 判断null元素。

30 个java编程技巧(最佳实践的初学者)一

Java 的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY_LIST,除此之外,还有 EMPTY_MAP, EMPTY_SET,真是贴心。

2. 小心使用 String

因为字符串相加或者拼接的方式都会在对象池中查找字符串是否存在,如果不存在则创建,这样在拼接的过程中会产生大量中间过程的字符串,占用内存资源。StringBuilder效率优于StringBuffer,但是StringBuffer线程安全。

30 个java编程技巧(最佳实践的初学者)一

30 个java编程技巧(最佳实践的初学者)一

另外,在实例化一个字符串对象,构造函数应该避免发生直接实例化,例如:

30 个java编程技巧(最佳实践的初学者)一

3. 避免不必要的对象

一个最昂贵的操作(在内存利用率)是java对象的创建。因此,建议只在必要时创建或初始化对象。下面的代码给出了一个例子:

30 个java编程技巧(最佳实践的初学者)一

4.Array 和ArrayList 选择

ArrayList和Array是我们在实际编程中经常使用的容器,而且因为ArrayList相当于动态化的数组,所以它们之间有太多的相似,以至于我们在选择哪种来存储元素的时候,会有小小的迷惑,他们都有注解的优缺点,选择真的取决于你的真实场景。

30 个java编程技巧(最佳实践的初学者)一

4.1.Array 有固定大小但 ArrayList 的大小不同。由于Array 的大小是固定的,在Array 类型变量声明的时候,内存被分配。因此,Array 是非常快的。另一方面, 使用ArrayList的最大缺点就是当我们添加新的元素的时候,它是先检查内部数组的容量是否足够,如果不够,它会创建一个容量为原来数组两倍的新数组,���后将所有元素复制到新数组里,接着抛掉旧数组。这点真的很麻烦,因为每次都要这么搞,尤其是元素足够多的时候,这就真的是既影响内存又影响效率的问题,但通过单独测试它们的运行时间,发现其实差不多,最大的影响就是如果是有其他代码也需要使用到内存,那么Array依然不变,但是ArrayList就会变得慢多,相同情况下所花的时间是Array的四倍多(实际情况是远远不止)。

4.2.这是添加或删除元素从ArrayList 比Array更容易。

4.3.数组可以多维但ArrayList只有一个维度。

4.4.ArrayList因为内部是一个数组,所以它是可以转化为数组的。

4.5 两者的适用场合:

List list = new ArrayList();

虽然我们想要的确实是ArrayList而不是list,但是我们知道,父类是可以获得子类的引用并且使用子类的方法,所以这样我们就能同时使用List和ArrayList的方法而不用害怕出错了。

首先,一个重要的约束就是,List的声明区域一般是在main方法里(当然静态list也可以,但是我们一般使用的时候都只是当做存储元素的临时容器),而Array是可以在外部进行声明的,这时它就是全局数组。所以,单看这点,它们的使用已经有区别,如果想要保存一些在整个程序运行期间都会存在而且不变的数据,我们可以将它们放进一个全局数组里,但是如果我们单纯只是想要以数组的形式保存数据,方便我们进行查找,那么,我们就选择ArrayList。而且还有一个地方是必须知道的,就是如果我们需要对元素进行频繁的移动或删除,或者是处理的是超大量的数据,那么,使用ArrayList就真的不是一个好的选择,因为它的效率很低,使用数组进行这样的动作就很麻烦,那么,我们可以考虑选择LinkedList。

30 个java编程技巧(最佳实践的初学者)一

5.用try catch的时候,要加finally吗?

考虑下面的代码片断

30 个java编程���巧(最佳实践的初学者)一

运行结果:

在Finally代码块中

在Finally代码块中

在Finally代码块中

在Finally代码块中

在Try内部代码块,退出不执行Finally代码块

在运行代码前,它看起来像要打印 ”在Finally代码块中“ 5次。但是执行的结果只有4次。第五次打印的结果是 ”在Try内部代码块,退出不执行Finally代码块“。

关于 Java 虚拟机是如何编译 finally 语句块的问题,有兴趣的读者可以参考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 节 Compiling finally。那里详细介绍了 Java 虚拟机是如何编译 finally 语句块。实际上,Java 虚拟机会把 finally 语句块作为 subroutine(对于这个 subroutine 不知该如何翻译为好,干脆就不翻译了,免得产生歧义和误解。)直接插入到 try 语句块或者 catch 语句块的控制转移语句之前。但是,还有另外一个不可忽视的因素,那就是在执行 subroutine(也就是 finally 语句块)之前,try 或者 catch 语句块会保留其返回值到本地变量表(Local Variable Table)中。待 subroutine 执行完毕之后,再恢复保留的返回值到操作数栈中,然后通过 return 或者 throw 语句将其返回给该方法的调用者(invoker)。

将上面代码修改如下:

30 个java编程技巧(最佳实践的初学者)一

运行结果:

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

在Try内部代码块,退出不执行Finally代码块

总结:

这里就不过多的去具体分析整个过程有兴趣的朋友可找资料了解整个过程,一个小小的、看似简单的 finally 语句块背后居然隐藏了这么多玄机。看来,我们平时还是应该认真的阅读 Java 相关的基础文档,比如:Java 语言规范、Java 虚拟机规范等,很多棘手的问题都可以从中得到答案。只有真正的吃透了基础知识,才能达到运用自如的境界!

1> try、catch、finally语句中,在如果try语句有return语句,则返回的之后当前try中变量此时对应的值,此后对变量做任何的修改,都不影响try中return的返回值

2> 如果finally块中有return 语句,则返回try或catch中的返回语句忽略。

3 >如果finally块中抛出异常,则整个try、catch、finally块中抛出异常

所以使用try、catch、finally语句块中需要注意的是

1> 尽量在try或者catch中使用return语句。通过finally块中达到对try或者catch返回值修改是不可行的。

2 >finally块中避免使用return语句,因为finally块中如果使用return语句,会显示的消化掉try、catch块中的异常信息,屏蔽了错误的发生

3 >finally块中避免再次抛出异常,否则整个包含try语句块的方法回抛出异常,并且会消化掉try、catch块中的异常

6.奇数判断

看看下面的代码行,并确定如果他们可以用来精确地识别一个给定的数字是否是奇数?

30 个java编程技巧(最佳实践的初学者)一

奇数可以被定义为被2整除余数为1的整数。表达式 num% 2 计算的是 num整除 2 时所产生的余数,因此看起来这个程序应该能够正确运转。遗憾的是,它不能;它在四分之一的时间里返回的都是错误的答案。

为什么是四分之一?因为在所有的 int 数值中,有一半都是负数,而 isOdd 方法对于对所有负奇数的判断都会失败。在任何负整数上调用该方法都回返回 false ,不管该整数是偶数还是奇数。

这是 Java 对取余操作符(%)的定义所产生的后果。该操作符被定义为对于所有的 int 数值 a 和所有的非零 int 数值b,都满足下面的恒等式:

(a / b) * b + (a % b) == a

现在进行修改如下:

30 个java编程技巧(最佳实践的初学者)一

使用此代码,不仅是解决了奇数的负的问题,而且这个代码也高度优化。因为,算术和逻辑运算的速度更快,比除法和乘法,结果取得了更快。

7. 单引号和双引号之间的区别

30 个java编程技巧(最佳实践的初学者)一

尝试运行上面的程序。这个程序演示了一个死锁。这种死锁的产生是因为两个线程都在等待其他线程所抓取的资源。他们都不在任何一个版本。从代码,似乎还“HaHa”是回来了,但它实际上返回ha169。原因是,如果使用双引号,字符串对待,但在单引号的情况下,字符自动转换为int型,进行计算。

8. 通过简单的技巧避免内存泄漏

内存泄漏经常会导致软件的性能退化。因为,java自动管理内存,开发商没有太多的控制。但仍有一些标准的做法,可以用来防止内存泄漏。

当查询完成时,总是释放数据库连接。

尽量使用 Finally 块。

释放存储在静态表中的实例。

9. 避免死锁

死锁出现的原因有很多。避免死锁不是一句话就能解决的。通常来说,当某个同步对象在等待另一个同步对象所拥有的资源上的锁时,便会产生死锁。

试着运行下下面的程序。它会告诉你什么是死锁。这个死锁是由于两个线程都在等待对方所拥有的资源,因此会产生死锁。它们会一直等待,没有谁会先放手。

30 个java编程技巧(最佳实践的初学者)一

30 个java编程技巧(最佳实践的初学者)一

30 个java编程技巧(最佳实践的初学者)一

运行结果:

Addition Thread: 13

Subtraction Thread: 7

Holding First Lock…

Holding Second Lock…

Addition Thread: Waiting for AddLock…

Subtraction Thread: Waiting for SubLock…

但如果调用的顺序变一下的话,死锁的问题就解决了。

将 MySubtractionThread中的线程加锁顺序调换再看看

30 个java编程技巧(最佳实践的初学者)一

运行结果:

Addition Thread: 13

Holding First Lock…

Addition Thread: Waiting for AddLock…

Threads: Holding Add and Sub Locks…

Subtraction Thread: 7

Holding Second Lock…

Subtraction Thread: Waiting for SubLock…

Threads: Holding Add and Sub Locks…

三种用于避免死锁的技术:

1>加锁顺序

2>加锁时限

3>死锁检测

一个更好的方案是给这些线程设置优先级,让一个(或几个)线程回退,剩下的线程就像没发生死锁一样继续保持着它们需要的锁。如果赋予这些线程的优先级是固定不变的,同一批线程总是会拥有更高的优先级。为避免这个问题,可以在死锁发生的时候设置随机的优先级。

10.JAVA运行内存的设置

一些java应用程序可以被高度的CPU密集型以及他们需要很多内存。这样的应用程序通常运行速度慢,因为内存高的要求。所以,我们可以在相关的配置文件中进行修改调整内存大小。

Xms = 设置内存初始化的大小

Xmx = 设置最大能够使用内存的大小

XX:PermSize =初始大小,将分配给JVM的启动过程

XX:MaxPermSize = 最大尺寸可以分配JVM的启动过程

11. 如何在java时间操作

有java时间两种标准方法:

System.currentTimeMillis()、System.nanoTime()

平时产生随机数时我们经常拿时间做种子,比如用System.currentTimeMillis的结果,但是在执行一些循环中使用了System.currentTimeMillis,那么每次的结果将会差别很小,甚至一样,因为现代的计算机运行速度很快。后来看到java中产生随机数函数以及线程池中的一些函数使用的都是System.nanoTime。

>System.currentTimeMillis返回的是从1970.1.1 UTC 零点开始到现在的时间,精确到毫秒,平时我们可以根据System.currentTimeMillis来计算当前日期,星期几等,可以方便的与Date进行转换,

> System.nanoTime提供相对精确的计时,但是不能用他来计算当前日期,

所以在使用中,我们可以根据我们具体的目的去正确的选择他们。

12. Float 和Double的选择

Data typeBytes usedSignificant figures (decimal)
Float47
Double815

double应该比float更好用,原因:

大多数处理器需要几乎相同数量的处理时间来执行浮点和双运算的操作。在相同数量的计算时间双提供了更高的精度。

13. Java的乘方运算

java提供了两个方法:

Multiplication:乘法

30 个java编程技巧(最佳实践的初学者)一

pow(double base, double exponent):(base的exponent次方)

30 个java编程技巧(最佳实践的初学者)一

math.pow只应在必要时使用,像指数是一个分数。Math.pow()方法通常慢300-600倍的速度比乘法。

14. 如何处理空指针异常

空指针异常在java中是很常见的。当我们尝试调用一个空对象引用的方法时,这个异常会发生。例如:

30 个java编程技巧(最佳实践的初学者)一

如果在上面的例子中,如果得到一个NullPointerException异常,然后学校 是null 或liststudents()null。有个好注意你可以提早将异常抛出,通过提早抛出异常(又���"迅速失败"),异常得以清晰又准确堆栈信息立即反映出什么出了错(提供了非法参数值),为什么出错(文件名不能为空值),以及哪里出的错,菜鸟和高手都可能犯的一个错是,在程序有能力处理异常之前就捕获它。Java编译器通过要求检查出的异常必须被捕获或抛出而间接助长了这种行为。自然而然的做法就是立即将代码用try块包装起来,并使用catch捕获异常,以免编译器报错。

30 个java编程技巧(最佳实践的初学者)一

【Seurat绘图进阶】从参数调优到美学定制:解锁DimPlot与FeaturePlot的隐藏技巧 本文深入探讨了Seurat包中DimPlot与FeaturePlot的进阶使用技巧,旨在解决单细胞数据可视化中的常见痛点。通过参数调优(如order、shuffle、raster)、颜色美学定制(使用RColorBrewer、viridis配色)以及性能优化(栅格化处理),并结合scCustomize包与patchwork排版,帮助用户将基础图表提升为信息清晰、可直接用于论文发表的出版级可视化结果。 阅读详情

相关推荐

Basilisk vs. STK:开源航天仿真工具在Windows上的实战体验与生态对比

本文对比了开源航天仿真工具Basilisk与商业软件STK在Windows平台上的实战体验与生态差异。从技术架构、安装配置、使用成本、功能覆盖、社区生态到适用场景,全面分析了二者的优劣势,为航天工程师和研究人员提供选型参考。Basilisk在性能和扩展性上表现突出,而STK在可视化与专业模块上更具优势。

weixin_30632089的博客 588

JAVA--中--List返回为空和返回为null的区别

JAVA–中--List返回为空和返回为null的区别 简述: 判断一个集合返回为空还是null,是不一样的. 举个例子: 你手上一个杯子(list),我手上什么都没有. 你的list.size()为0 ,我的结果null, 你需要 new Arraylist()去 list.add() 添加水,没有杯子水直接溢出(空指针). 实际运用 一、判断: 1.什么时候用null? 2.什么时候用 isEmpty() 和 list.size()呢? 二、空集合: isEmpty() 和

weixin_44774713的博客 5402

车载以太网入坑指南,从小白到懂哥的进阶之路【技术分享】

各位技术大佬们好!最近公司项目涉及到车载以太网,刚开始完全懵逼,花了大半个月时间各种查资料、测试设备,总算是摸清了门道。想着互联网上卧虎藏龙,肯定有不少大佬对这个技术感兴趣,所以写个帖子分享一下,顺便求各位大佬指点。

starelink的博客 1261

20个Java编程技巧

事实上,你甚至可以把case语句和 惊人的FORTRAN77项声明 类比,对于FORTRAN,它的神秘已经超越了它的功能。是的,这是会发生的。接着就出现了一群用户,他们只是把一切类型生搬硬套进 Object 中 直到那该死的编译器停止工作,然后他们突然链接到了错误的方法,认为这一切都是你的错(事情总是这样)。我希望Java能像Scala语言一样,人们在所有地方都直接用 val 来表示变量,甚至都不考虑易变性,除非明确需要的时候他们才用 var 来声明变量,但是这样的机会特别少。是的,写成final。

2301_78021017的博客 1237

用Verilog在FPGA上做个电子琴:从矩阵键盘到蜂鸣器的完整实现(附代码)

本文详细介绍了如何使用Verilog在FPGA上实现一个完整的电子琴系统,涵盖矩阵键盘扫描、音调生成和蜂鸣器驱动等核心模块。通过模块化设计和PWM调制技术,开发者可以构建一个可交互的音乐播放器,项目代码完整且易于扩展,适合FPGA初学者和数字逻辑设计爱好者实践。

weixin_29191669的博客 403

十一、学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现)

学生信息管理系统(PyQt5+MySQL+PyMySQL模块实现)

ungoing的博客 8991

springboot中返回前端空对象或空集合处理实现

处理前了解一些的基本知识点:     返回前端数据格式就会想到HttpMessageConverter,简单来讲就是将http请求的请求内容和响应内容转化为对应格式.常见的http消息转化器有很多,现在大部分前后端数据共用格式为json,所以涉及到以下几个类:     MappingJacksonHttpMessageConverter: 负责读取和写入json格式的数据;     具体

weixin_43401380的博客 5736

提供一个微信投票刷票的js代码

最近几天,有个朋友找我去写一个脚本帮他 在微信上刷票、微信投票刷票,我大概看了一下,本次微信投票刷票其实就是根据微信的openid来限制,每个openid只能投三次票的限制。上图可以看出,其实只要openid,和toopenid即可,openid是自己的微信id,toopenid是投票对象的微信id,那我们定时修改openid即可给某一个人刷投票。把这段代码复制到浏览器F12之后的console里,直接回车即可开始微信投票刷票(刷新或关闭浏览器即可停止刷票)//生成随机的ip地址。

qq_858865388专业提供快速微信投票教程攻略和方法的博客 2万+

30 个java编程技巧(最佳实践的初学者)

http://www.envicloud.cn/pages/news/235.html#4

胖胖龙的博客 578

Yolo8行人车辆目标检测实战分享 完整项目代码可直接运行

Yolo8行人车辆目标检测实战分享 完整项目代码可直接运行

1294

【问题解决】解决 Python `PermissionError` 权限不足:文件/进程/端口全场景修复

本文总结了Python程序中常见的权限问题及解决方案,包括文件、进程和端口权限错误。文件权限问题通常由文件占用、权限不足或路径错误引起;进程问题多因权限不足或系统限制;端口问题则与端口占用、防火墙或特权端口相关。解决方案提供了详细的代码实现:文件权限管理器类(FilePermissionManager)包含检查权限(check_permission)、修复权限(fix_permission)、安全写入(safe_write)和安全删除(safe_delete)等方法,通过异常处理和临时文件等技术确保操作安全

博客 358

java 用方法计算30_30 个java编程技巧(最佳实践的初学者)

1.return 一个空的集合,而不是 null如果一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else” 判断null元素。Java 的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY_LIST,除此之外,还有 EMPTY_MAP, EMPTY_SET,真是贴心。2. 小心使用 String因为字符...

weixin_42324002的博客 359

C#从入门到精通(35)—如何防止winform程序因为误操作被关闭

我们在开发的上位机软件运行起来以后,一般在右上角都有一个关闭按钮,正常情况下点击关闭按钮就能关闭软件,但是不排除我们不想关闭软件,但是因为不小心把鼠标点到了关闭按钮,如果这是一个正在生产的机器,突然关闭软件可能会导致产品损坏,那么我们如何去解决这个误操作的问题呢,本文就来讲解解决方案!

qq_34059233的博客 678

Java编程迅速入门_30 个java编程技巧(最佳实践的初学者)

1.return 一个空的集合,而不是 null如果一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else” 判断null元素。Java的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY_LIST,除此之外,还有 EMPTY_MAP, EMPTY_SET,真是贴心。2. 小心使用 String因为字符...

weixin_39966740的博客 130

Camera2Demo

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

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java30前奇数和_30 个java编程技巧(最佳实践的初学者)一

1.return 一个空的集合,而不是 null如果一个程序返回一个没有任何值的集合,请确保一个空集合返回,而不是空元素。这样你就不用去写一大堆 ”if else" 判断null元素。Java 的标准库设计者已经在 Collections 类中放了一个空的 List 常量 EMPTY_LIST,除此之外,还有 EMPTY_MAP, EMPTY_SET,真是贴心。2. 小心使用 String因为字符...

weixin_39901213的博客 178

jre9下载 jdk9

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

30 Java Programming Tips and Best Practices for Beginners

Java is one of the most popular programming languages – be it Win applications, Web Applications, Mobile, Network, consumer electronic goods, set top box devices, Java is everywhere. More than 3 Bill

nobody 1403

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

30个Java入门技巧和最佳实践

Java是最流行的编程语言之一-无论是Win应用程序,Web应用程序,移动,网络,消费电子产品,机顶盒设备,Java随处可见。 在Java上运行的设备超过30亿。 据甲骨文称 ,正在使用50亿张Java卡。 超过900万的开发人员选择用Java编写代码 ,它在开发人员中非常流行,同时也是最流行的开发平台。 对于即将到来的Java开发人员,此博客提供了一段时间内已学习的最佳实践的集...

最佳 Java 编程 385

java 8入门与实践_30个Java入门技巧和最佳实践

java 8入门与实践 Java是最流行的编程语言之一-无论是Win应用程序,Web应用程序,移动,网络,消费电子产品,机顶盒设备,Java随处可见。 在Java上运行的设备超过30亿。 据Oracle称 ,正在使用50亿张Java卡。 超过900万开发人员选择用Java编写代码,该代码在开发人员中非常流行,同时也是最流行的开发平台。 对于即将到来的Java开发人员,此博客提供了一...

最佳 Java 编程 602

编写高性能Java代码的最佳实践

原文:How to Improve the Performance of a Java Application 作者:Eugen Paraschiv 翻译:雁惊寒 摘要:本文首先介绍了负载测试、基于APM工具的应用程序和服务器监控,随后介绍了编写高性能Java代码的一些最佳实践。最后研究了JVM特定的调优技巧、数据库端的优化和架构方面的调整。以下是译文。 介绍 在这篇文章中,我

优快云研发技术 9349

Java编程的几个最佳实践

看smack的时候,发现作者提出了几个开发的实践(http://community.igniterealtime.org/docs/DOC-1984),转载过来,并初步翻译了一下[抱歉,翻译的有点烂],虽然很容易理解,但很有意思,对我们的编程有借鉴意义。 To convert a primitive to a String use String.valueOf(...). Don't u

闲来无事 634

JAVA高效开发小技巧总结(这是一位同事的分享,感谢)

1.以下两种for循环 这一种循环,会额外创建一个迭代器,然后遍历值。当遇到链表、Hashmap表时,用它速度很快,因为这样不需要查询,而下一种则不行,下一种还必须查找,时间复杂度立马上升。 for(String str : list){ } 这一种循环,不用创建迭代器,当遇到数组、ArrayList时,用它速度最快,节省创建迭代器时间。 int len=list.size();

浪漫鼠 5896

java编程中的一些技巧

  技巧1:  public void btnFind_actionPerformed(ActionEvent e) {        if (txtWhat.getText().equals("")) {            javax.swing.JOptionPane.showMessageDialog(this, "请输入查询信息!");            r

wangzff的专栏 580
上一篇: Simple_Wallet 在服务器端通过RPC操纵钱包
下一篇: Java常用对象API——泛型
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值