java面试题总结

1.谈谈你对Java平台的理解?

1)java本身是面向对象的语言,最显著的两个特征,一是:书写一次,到处行,jvm具有跨平台的能力。另外一个特征是垃圾收集(GC( Garbage Collection)),java通过垃圾收集器回收分配,大部分时间情况下,程序员不需要自己操心内存的分配和收回

 

gc机制: 避免内存泄漏                 

 原理:

            jvm会给每个对象分配一个整形的变量,称为引用计数器该变量 表示该对象被引用的次数。

            引用次数越多,数值越大,对象越安全,一旦引用计数器变为0的时候,jvm有可能会回收该对象

回收时机:

                   jvm有固定的运行周期和运行时机,一般周期取决于内存使用状况,

                   如果内存占用一直很低,gc永不执行。如果内存超过阀值,gc才有可能执行

                   gc的执行时机和力度由jvm控制,程序员无法干涉,但是可以使用gc方法建议执行             

 一定回收:

                   1)引用计数器为0并且该对象很久没有使

                   2)jvm达到最大可用内存,gc会自动清理

 

 JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是 JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。 我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码

 

 

2. 我理解的java程序执行步骤

首先javac编译器将源代码编译成字节码。

然后jvm类加载器加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度相对会比较慢。有些方法和代码块是高频率调用的,也就是所谓的热点代码,所以引进jit技术,提前将这类字节码直接编译成本地机器码。这样类似于缓存技术,运行时再遇到这类代码直接可以执行,而不是先解释后执行。

 

 

3. 解释执行和编译执行的区别??

            计算机并不能直接地识别高级语言编写的源程序,要翻译成机器语言,计算机才能识别和执行。这种"翻译"通常有两种方式,即编译方式和解释方式。

    编译方式:当用户将高级语言编写的源程序输入计算机后,编译程序便把源程序整个地翻译成用机器语言的目标程序,然后计算机再执行该目标程序。

    解释方式:是指源程序进入计算机后,解释程序边扫描边解释,逐句输入逐句翻译,计算机一句句执行,并不产生目标程序。

4.Exception和Error有什么区别?

1)Exception 和 Error 都是继承了 Throwable 类,,异常处理机制是被抛出(throw)或者捕获(catch)

2)Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。

3)Exception: 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。

    Error:系统错误,虚拟机出错,我们处理不了,也不需要我们来处理。

4)Exception :(编译异常和运行异常):

    编译异常:必须进行捕获处理不要抛出,这是编译期检查的一部分

    运行异常:通常是可以编码避免的逻辑错误,不要抛出或延迟处理异常,就地解决最好,并且需要实实在在的进行处理

总结: 1.当一个try后跟了很多个catch时,必须先捕获小的异常再捕获大的异常。

          2.上传下载不能抛异常。上传下载一定要关流。

           3. 不要在finally代码块中处理返回值。

           4.  请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保finally的存在不会改变函数的返回值

从性能的角度来审视一下java的异常处理机制

1)try-catch 代码段会产生额外的性能开销, 它往往会影响 JVM 对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的 try 包住整段的代码;

2) 与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。

3) Java 每实例化一个 Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了

      5.事务

1.事务是一个执行的单元要么都成功要么都失败。事务始于连接到数据库执行DML语句,结束commit或者rollback

2.事务有四大特点:一致性,原子性,持久性,隔离性;

一致性

      表示事务执行的是一个整体要么全部成功,要么全部失败!

原子性:

      表示一个事务内有一个操作失败所有的更改都回滚的初始的状态;

持久性:

      事务执行完成后操作后是永久性的

隔离性

      事务查看数据时候所处的状态,要么是另一个并发事务修改之前的状态,要么是修改之后的状态,事务不会查看中间的状态

3.事务并发问题:

1)脏读(Dirty Read):一个事务读取到了另一个事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。

2)不可重复读(虚读)(NonRepeatable Read)

一个事务对同一行集(同一个SELECT语句):数据重复读取两次,发现值不一样了。例如事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。

3)幻读(Phantom Read):事务在插入已经检查过不存在的记录时,惊奇的发现这些数据已经存在了,之前的检测获取到的数据如同鬼影一般。

也就是说事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据这是因为在两次查询过程中有另外一个事务插入或删除数据造成的

4.事务的安全隔离级别

1 - 读未提交

Read uncommitted:最低级别,以上事务并发情况均无法解决。

 

2 - 读已提交

Read committed:可避免脏读情况发生。(Oracle默认)

 

4 - 可重复读

Repeatable read:可避免脏读、不可重复读情况的发生。不可以避免幻读。(MySQl默认)

 

8 - 串行化读

Serializable:事务只能一个一个执行,避免了脏读、不可重复读、幻读。执行效率慢,使用时慎重。

 

6.Session 和CurrentSession 的区别

1.Session每次获取的对象都是全新的对象,而CurrentSession每次获取的对象都是相同的对象

2.CurrentSession的使用必须要配合事务, Transaction,增删改查操作必须开启事务.

Session对象操作增删改查就不一定非要开启事务.增删改的时候可以开启事务 进行回滚操作

3.内部实现的机制不同:

Session是由SessionImpl类来创建的 ,SessionImpl类每次加载SessionFactory中的config信息的时候,获得的Session对象都是不一样的

CurrentSession是由ThreadLocalContextClass类来构建的,CurrentSession是从ThreadLoacl中获取的,只有第一次获取的时候,会创建一个Session对象,但是之后的每次获取都是从ThreadLocal中获取 所以获取的对象都一样的

4.CurrentSession需要在cfg.xml配置文件中开启功能

 

 

7.一级缓存:

概念:位于应用程序hibernate和持久化存储区域(DB)之间的一块存放数据的内存区

作用:提高了应用程序和数据库之间的数据访问速度

     协调了应用程序和数据库之间的时间差

     提高了应用程序的效率和性能

执行流程:

    应用程序查询数据时,先从Session缓存中获取数据,如果没有数据,就会去数据库中加载数据,如果有的话 就直接从session缓存中把数据拿出来交给应用程序直接使用和显示

生命周期:当session被close()的时候,缓存就消失了

    

 

                                                                                    java基础面试题:

 

2. 多态存在的三个必要条件

一、要有继承;

二、要有重写;

三、父类引用指向子类对象。

 

 

setDaemon(boolean on);   JVM的垃圾回收线程就是典型的后台线程。该方法必须在start方法调用前,否则出现IllegalThreadStateException异常。

 

5线程的生命周期:

    

 

 

 

 

6.创建线程对象的两种方式

            1) 继承Thread线程类 

          2) 实现Runnable接口 创建线程对象和实现类的对象,把实现类的对象放入线程对象引用的括号中(常用)

                 优势:避免了java单继承带来的局限性

 

 

 

 

 

                                                                        线程的面试题:

 

1) 什么是线程?

    线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位; 多线程对运算密集型任务提速比如,如果一个线程完成一个任务要 100 毫秒,那么用十个线程完成改任务只需 10 毫秒

 

 

2). 线程和进程有什么区别?

    线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据   bbbbbbbbbb

 

3.  如何在 Java 中实现线程

    1.继承Thread类

    2.实现Runnable接口创建线程

    3.使用线程池

 

4.如何选择继承Thread类和实现Runnable接口创建线程

    实现Runnable接口在开发中更常用,因为java不支持多继承,而可以实现多实现。

 

5.  Thread 类中的 start () 和 run () 方法有什么区别?

     start ()方法被用来启动新创建的线程,而且 start ()内部调用了 run ()方法,这和直接调用 run ()方法的效果不一样。当你调用 run ()方法的时候只会是在原来的线程中调用,没有新的线程启动,start ()方法才会启动新线程

 

6.  Java 内存模型是什么?

     它在多线程的情况下尤其重要。Java 内存模型对一个线程所做的变动能被其它线程可见提供了保证

 

 

7. Java 中的 volatile 变量是什么?

     特殊的修饰符,只有成员变量才能使用它,在多线程并发编程中synchronizedvolatile都扮演着重要的角色,volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的"可见性" volatile 变量可以保证下一个读取操作会在前一个写操作之后发生,就是上一题的 volatile 变量规则

 

8. 什么是线程安全?Vector 是一个线程安全类吗?

   线程安全: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的

    Vector 是用同步方法来实现线程安全的,而和它相似的 ArrayList 不是线程安全的

 

9. Java 中什么是竞态条件?

    竞态条件会导致程序在并发情况下出现一些 bugs多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了,那么整个程序就会出现一些不确定的 bugs。这种 bugs 很难发现而且会重复出现,因为线程间的随机竞争

     例子就是:无序处理

 

10.  Java 中如何停止一个线程

    1: Java 提供了很丰富的 API 但没有为停止线程提供API

    2: stop ()等方法 由于潜在的死锁威胁因此在后续的 JDK 版本中他们被弃用了

    3: 手动结束一个线程,  volatile 布尔变量来退出 run ()方法的循环或者是取消任务来中断线程

 

11. 一个线程运行时发生异常会怎样?

    1.如果异常没有被捕获该线程将会停止执行

    2.里面有一个 用于处理未捕获异常造成线程突然中断情况的一个内嵌接口

    

 12.如何在两个线程间共享数据?

      1. 通过使用唤醒机制  wait 和 notify 方法实现了生产者消费者模型。

 

13. wait 和 notify的理解?

    1.它们都是Object下面的方法,因为他们需要获得同步锁的对象,而同步锁的对象是任意的对象

            wait:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法

            notify:唤醒在此对象监视器上等待的单个线程

    2: 当想要调用wait( )进行线程等待时,必须要取得这个锁对象的控制权(对象监视器),一般是放到synchronized(obj)代码中

    3: 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。

    4: 当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁

 

 

14.什么是ThreadLocal?

    1: 线程的局部变量, 是每一个线程所单独持有的, 通常是类中的 private static 字段

    2: 一个对象的变量会被多个线程所访问,可能有线程安全问题, 可以使用synchorinized 关键字来为此变量加锁,进行同步处理,那样会大大降低效率, 可以使用ThreadLocal来解决对某一个变量的访问冲突问题

    3.如何解决变量访问冲突的问题: 当使用ThreadLocal维护变量的时候 为每一个使用该变量的线程提供一个独立的变量副本, 因此他们使用的都是自己从内存中拷贝过来的变量的副本

    4.弊端: 每个线程中都创建了副本,资源的消耗过大

 

 

15 为什么你应该在循环中检查等待条件?

     处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出

 

16. Java 中堆和栈有什么不同?

    1. 每个线程都有自己的栈内存,用于存储本地变量

    2 所有的线程都共享一个推内存 对象都在堆里创建, 线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时 volatile 变量就可以发挥作用了

 

17. 什么是线程池? 为什么要使用它

    1. 创建线程要花费, 昂贵的资源和时间

    2. JDK1.5 开始。 能够有效的降低频繁创建和销毁线程对性能所带来的开销

 

18. Java 多线程中的死锁?

    1. 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象, 让程序无法完成任务

    2. 死锁的发生必须满足四个条件:

        1)   互斥条件:一个资源每次只能被一个进程使用。

        2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

        3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺

        4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    3.避免死锁: 阻止循环等待条件      系统中所有的资源设置 排序 规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁

           

19.  怎么检测一个线程是否拥有锁?

     在 java.lang.Thread 中有一个方法叫 holdsLock (),它返回 true 当前线程拥有锁

 

20  Thread 类中的 yield 方法有什么作用?

    1. Yield 方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行

    2. 当前线程放弃 CPU 占用而不能保证使其它线程一定能占用 CPU

 

21. 如果你提交任务时,线程池队列已满。会时发会生什么?

     如果一个任务不能被调度执行那么会抛出一个异常

 

22. Java 线程池中 submit () 和 execute ()方法有什么区别?

    1. 两个方法都可以向线程池提交任务

    2. execute ()方法的返回类型是 void,它定义在 Executor 接口中

    3.  submit ()方法可以返回持有计算结果的 Future 对象,它定义在 ExecutorService 接口中,它扩展了 Executor 接口

 

23. 什么是阻塞式方法

     程序会一直等待该方法完成期间不做其他事情, 直到得到结果之后才会返回

 

 

24. Swing 是线程安全的吗? 为什么?

        Swing 不是线程安全的

 

25. 如何强制启动一个线程?

     这个问题就像是如何强制进行 Java 垃圾回收,目前还没有觉得方法,虽然你可以使用 System.gc ()来进行垃圾回收,但是不保证能成功, 它是被线程调度器控制着

 

26. Java 多线程中调用 wait() 和 sleep ()方法有什么不同?

    sleep:1.不释放同步锁,当睡眠的时间到了 会进入就绪状态 2.sleep通常被用于暂停执行,3.sleep方法后,线程进入计时阻塞状态,.sleep时间到了就会到就绪状态,等待cpu的分配时间片4.是Thread类中的方法

    wait:释放同步锁,可以使用notify()来释放锁,然后进入同步代码块阻塞状态,是Object。和notify()来模拟生产者和消费者模型

 

 

 

 


1、面向对象的特征有哪些方面? 

 1)抽象:     抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什

2) 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。 解决代码重复的问题. 表示出一个体系.,同时继承也是封装程序中可变因素的重要手段

3)  封装:将类的的某些信息隐藏在类的内部,不允许外界直接访问,只向外界提供访问的接口

4) 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,

    多态存在的三个必要条件

        一、要有继承;

        二、要有重写;

                子类继承父类并重写父类中已有的或抽象的方法

        三、父类引用指向子类对象:这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为

 

 

2. 访问修饰符public,private,protected,以及不写(默认)时的区别?

修饰符

当前类

同 包

子 类

其他包

public

protected

×

default

×

×

private

×

×

×

public:在其他包下都可以使用

protected:除了其他的包下都可以使用

default:只能在当前类和同包下可以使用

private:只能在当前类中使用

 

3: String 是最基本的数据类型吗?

    不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型,剩下的都是引用类型,Java 5以后引入的枚举类型也算是一种比较特殊的引用类型

 

4: float f=3.4;是否正确? 

    答:不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F     默认是double类型的双精度

 

5. short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗? 

答:对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换

 

6: 如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象

     Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

        System.out.println(f1 == f2); //true 比较的是int的值

        System.out.println(f3 == f4); //false 比较的Integer对象的地址值

}

 

 

7、解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。

     定义一个基本数据类型的变量,一个对象的引用保存在JVM中的栈空间;而通过创建的对象则放在堆空间堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、"hello"和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError

 

8.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

            12                                                -11            四舍五入的原理是在参数上加0.5然后进行下取整

 

9. 在Java中,如何跳出当前的多重嵌套循环? 

     在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环

XXX:

   for

        for

        break XXX;

 

continue:跳过当前的循环,执行下一下循环

break:结束当前一层循环

return:结束方法,所以所有的循环都结束了

 

 

10 .构造器(constructor)是否可被重写(override)? 

答:构造器不能被继承,因此不能被重写,但可以被重载

 

11.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? 

答:不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;(2)如果两个对象的hashCode相同,它们并不一定相同

 

12. 是否可以继承String类? 

答:String 类是final类,不可以被继承

 

13. String和StringBuilder、StringBuffer的区别? 

        1 String是内容不可变的,而StringBuffer和StringBuilder都是内容可变的

         2 StringBuffer是 被synchronized修饰,同步的,数据安全,效率低,String和StringBuilder是不同步的,数据不安全,效率高

         3 String 类型进行改变的时候其实都等同于生成了一个新的 String对象(然后将指针指向新的 String 对象,每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的),而StringBuffer和StringBuilder 对象本身进行操作,而不是生成新的对象

 

      String:适用于少量的字符串操作的情况

  StringBuilder:适用单线程下在字符缓冲区进行大量操作的情况

  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

 

 

14. 重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

    方法的重载和重写都是实现多态的方式,区别在于重载实现的是编译时的多态性,而重写实现的是运行时的多态性。重载发生在同一个类中同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者参数的个数不同)则视为重载;重写发生在子类与父类之间,重写有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)

 

 

15. 描述一下JVM加载class文件的原理机制?

  Java具有跨平台性, 经过编译的Java源程序并不是一个可执行程序, JVM会确保这个类已经被加载连接(验证、准备和解析)和初始化

    类的加载:是指把类的.class文件中的数据读入到内存中,然后产生与所加载类对应的Class对象

    连接阶段: 验证准备(为静态变量分配内存并设置默认的初始值)解析(将符号引用替换为直接引用)三个步骤

    初始化:包括:1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;2)如果类中存在初始化语句,就依次执行这些初始化语句

 

16.char 型变量中能不能存贮一个中文汉字,为什么?

     char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode,一个char类型占2个字节

 

 

17. 静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同? 

答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化

 

 

18. Java 中会存在内存泄漏吗,请简单描述?

     理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题;然而在实际开发中,可能会存在无用但不能被GC回收的对象,因此也会导致内存泄露的发生。例如Hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象中可能存在无用的垃圾对象,如果不及时关闭(close)或清空(flush)一级缓存就可能导致内存泄露

 

 

20. 抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰? 

答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

 

 

21 如何实现对象克隆? 

答:有两种方式: 

  1). 实现Cloneable接口并重写Object类中的clone()方法; 

  2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆

 

22. 一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制? 

答:可以,但一个源文件中最多只能有一个公开类(public class)而且文件名必须和公开类的类名完全保持一致。

 

 

23. Java 中的final关键字有哪些用法? 

答:(1)修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。

 

 

24: Error和Exception有什么区别?

     Error表示系统级的错误程序不必处理的异常,是恢复很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;

    Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况

 

 

25:try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后? 

    答:会执行,在方法返回调用者前执行。

 

26: Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用? 

     try用来指定一块预防所有异常的程序;catch子句紧跟在try块后面,用来指定你想要捕获的异常的类型;throw语句用来明确地抛出一个异常;throws用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally为确保一段代码不管发生什么异常状况都要被执行

 

 

27: 阐述final、finally、finalize的区别

      final:修饰符(关键字)有三种用法:类: 即不能被继承;  变量: 变量必须在声明时给定初值,只能读取不可修改;  方法: 不能在子类中被重写

      finally:通常放在try…catch…的后面构造总是执行代码块

      finalize:Object类中定义的方法 这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作

 

 

                        集合

28: 阐述ArrayList、Vector、LinkedList的存储性能和特性。 

答:ArrayList 和Vector都是使用数组方式存储数据,,它们都允许直接按序号查找元素,但是插入元素要涉及数组元素移动等内存操作,所以查询数据快而插入数据慢Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,逐渐被ArrayList取代了。LinkedList使用双向链表实现存储 (这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号查询数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强实现)。

 

29:Collection和Collections的区别? 

答:Collection是一个接口,它是Set、List等容器的父接口;Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。

 

30: List、Map、Set三个接口存取元素时,各有什么特点? 

答:List以索引来存取元素,可以有重复元素Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value )映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序根据元素key达到排序和去重的效果。

 

31: TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素? 

答:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序

 

 

32. 请说出与线程同步以及线程调度相关的方法。 

答: 

- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁; 

- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常; 

- notify():唤醒一个处于等待状态的线程并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关; 

- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

 

 

33. 举例说明同步和异步。 

答:如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取数据库操作中的排他锁就是最好的例子)。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。事实上,所谓的同步就是指阻塞式操作,而异步就是非阻塞式操作

 

 

34: 什么是线程池(thread pool)?

     线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候取出,使用完毕放回池中,从而减少创建和销毁线程对象的开销 

 

35. 简述synchronized 和java.util.concurrent.locks.Lock的异同? 

    答:Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的控制线程和更好的性能,而且不强制性的要求一定要获得锁。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且最好在finally 块中释放(这是释放外部资源的最好的地方)。

 

 

36 你在项目中哪些地方用到了XML? 

答:XML的主要作用有两个方面:数据交换信息配置; XML曾经用来系统间交换数据,但此项功能几乎已经被JSON取而代之 目前很多软件仍然使用XML来存储配置信息

 

37: 阐述JDBC操作数据库的步骤。

   1 加载驱动。

Class.forName("oracle.jdbc.driver.OracleDriver");

    2创建连接。

Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "tiger");

    3创建sql语句。

PreparedStatement ps = con.prepareStatement("select * from emp where sal between ? and ?"); ps.setInt(1, 1000); ps.setInt(2, 3000);

    4执行语句。

ResultSet rs = ps.executeQuery();

    5处理结果

while(rs.next()) { System.out.println(rs.getInt("empno") + " - " + rs.getString("ename")); }

    6关闭资源。

finally { if(con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }

 

38: Statement和PreparedStatement有什么区别?哪个性能更好?

     ①PreparedStatement接口代表预编译的语句,它主要的优势在于可以减少SQL的编译错误增加SQL的安全性(减少SQL注射攻击的可能性)

     ②PreparedStatemen避免了用字符串连接拼接SQL语句的麻烦和不安全;③PreparedStatement有明显的性能上的优势,由于数据库可以将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快

 

39: 在进行数据库编程时,连接池有什么作用?

     由于创建连接和释放连接都有很大的开销(数据库服务器不在本地时,每次建立连接都需要进行TCP的三次握手,释放连接需要进行TCP四次握手,造成的开销是不可忽视), 为了提升系统访问数据库的性能,可以事先创建若干连接置于连接池中,需要时直接从连接池获取,使用结束时归还连接池而不必关闭连接,从而避免频繁创建和释放连接所造成的开销,这是典型的用空间换取时间的策略   C3P0  Druid

 

31: 什么是DAO模式?

    DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作

 

32:  获得一个类的类对象有哪些方式? 

- 方法1:类型.class,例如:String.class 

- 方法2:对象.getClass(),例如:"hello".getClass() 

- 方法3:Class.forName(),例如:Class.forName("java.lang.String")

 

33.模式:

     - 工厂模式:工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。

    - 模板方法模式:提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。 

 

34: 阐述Servlet和CGI的区别? 

答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行其service()方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于Servlet

 

35: Servlet接口中有哪些方法? 

    一共定义五个方法

Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法。

 

36: 转发(forward)和重定向(redirect)的区别?

    1.数据共享方面

                转发到的页面可以共享request里面的数据

                重定向不能共享数据

    2.地址栏显示:

                转发:服务器直接访问目标地址url,把url响应的数据读取过来,然后发给浏览器,浏览器不知道内容从哪里来的。所有还是显示原来的地址

                重定向:发送一个状态码,告诉浏览器重启访问这个url,所以地址栏上现实的新的url

 

    3.本质区别:

                转发:是浏览器行为,浏览器做了一次请求

                重定向:是客户端行为,浏览器做了两次请求

        

 

面试题:浏览器关闭,session就销毁了? 

    不对,ssesion要基于cookie实现的,cookid中储存这session中的id,当客服端访问服务器的时候,回去通过cookie中存储的id去寻找数据,因为如果不设置cookie的时间,那么默认关闭浏览器或者使用其他的服务器 会话结束 就消除内存中的cookie的数据,那么储存在cookie中的session的id也就没了 ,不过储存在服务器中的那片空间还是存在的,只不过没有id去指向它,默认30分钟自动销毁

 

 

37: JSP有哪些内置对象?作用分别是什么?

答:JSP有9个内置对象: 

- request:封装客户端的请求,其中包含来自GET或POST请求的参数; 

- response:封装服务器对客户端的响应; 

- pageContext:通过该对象可以获取其他对象; 

- session:封装用户会话的对象; 

- application:封装服务器运行环境的对象; 

- out:输出服务器响应的输出流对象; 

- config:Web应用的配置对象; 

- page:JSP页面本身(相当于Java程序中的this); 

- exception:封装页面抛出异常的对象。

 

 

38: HTTP协议中的两种发送请求的方法 :get和post请求的区别? 

①get请求用来从服务器上获得资源,而post是用来向服务器提交数据 

②get提交的数据显示在地址栏上,get传输不安全,post传输比较安全

③get传输的数据要受到URL长度限制(1024字节)get可以传输少量的数据;而post可以传输大量的数据,上传文件通常要使用post方式; 

4.get传输速度快,post传输速度慢

GET产生一个TCP数据包;POST产生两个TCP数据包。 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次, 在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点

 

 

39:JSP和Servlet是什么关系? 

     Servlet是一个特殊的Java程序 ,它担当客户端请求与服务器的响应的中间层,

     JSP本质上是Servlet的一种简易形式

    区别: servlet和JSP最主要的不同点在于,

                1.Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开; JSP是Java和HTML组合成一个扩展名为.jsp的文件。

                 2 JSP侧重于视图,Servlet主要用于控制逻辑

 

40: 讲解JSP中的四种作用域。 

答:JSP中的四种作用域包括page、request、session和application,具体来说: 

- page代表与页面的对象和属性 

- request代表与一个请求相关的对象和属性。需要在页面显示的临时数据可以置于此作用域。 

- session代表与某个用户与服务器建立的一次会话相关的对象和属性跟某个用户相关的数据应该放在用户自己的session中。 

- application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域

 

41: 实现会话跟踪的技术有哪些?

     由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器据此判断到底是哪一个用户。

    1: URL 重写:在URL中添加用户会话的信息作为请求的参数,或者将唯一的会话ID添加到URL结尾以标识一个会话

    2: 表单隐藏域: 这些信息不会在浏览器中显示但是提交表单时会提交给服务器。 

    3:cookie: 一种是基于窗口的,浏览器窗口关闭后,cookie就没有了;另一种是将信息存储在一个临时文件中,并设置存在的时间

                注意: 首先不要在cookie中存放敏感信息; 其次cookie存储的数据量有限(4k); 浏览器通常只允许一个站点最多存放20个cookie

    4: session 在所有会话跟踪技术中,session对象是最强大也是功能最多的 设置域对象的值

 

42: 你的项目中使用过哪些JSTL标签? 

答:项目中主要使用了JSTL的核心标签库,包括<c:if>、<c:choose>、<c: when>、<c:forEach>等,主要用于构造循环和分支结构以控制显示逻辑

    

43: JSP中的静态包含和动态包含有什么区别?

     静态包含是编译时包含,如果包含的页面不存在则会产生编译错误, 只产生一个class文件

     动态包含是运行时包含包含页面和被包含页面是独立的,会编译出两个class文件,如果被包含的页面不存在,不会产生编译错误,也不影响页面其他部分的执行

    

44: 如何设置请求的编码以及响应内容的类型? 

    请求:setCharacterEncoding("UTF-8)方法可以设置请求的编码

    响应: setContentType()

传输层协议:

TCPUDP的区别:

       TCP :面向连接(经历三次握手)、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需 要开销较多(时间,系统资源)。 服务端和客户端

       UDP:面向非连接、传输不可靠(丢包[数据丢失])、用于传输少量数据(数据包模式)、速度快发送端和接收端

 

 

 

 

                                                    框架:

1: 什么是ORM? 

答:对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM是通过使用描述对象和数据库之间映射的元数据(在Java中可以用XML或者是注解),将程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成Java对象,其本质上就是将数据从一种形式转换到另外一种形式

 

2. 持久层设计的目标包括: 

- 数据存储逻辑的分离,提供抽象化的数据访问接口。dao和mapper 

- 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。 

- 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。 

- 数据抽象,提供更面向对象的数据操作。

 

 

3.Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)? 

答:SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,可以被多个线程并发访问。SessionFactory一般只会在启动的时候构建。,最好将SessionFactory通过单例模式进行封装以便于访问。Session是一个轻量级非线程安全的对象线程间不能共享session),它表示与数据库进行交互的一个工作单元。Session是由SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用ThreadLocal将session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。

 

4.Hibernate中Session的load和get方法的区别是什么? 

答:主要有以下三项区别: 

① 找不到数据,get方法返回null,load方法抛出异常。 

② get方法直接返回实体类对象,load方法返回实体类对象的代理 

3;load延迟加载

5: Hibernate的对象有三种状态:瞬时态(transient)、持久态(persistent)和游离态(detached)

 

6: Session加载实体对象的过程?

    1): 首先会在一级缓存中通过实体类型和主键进行查找,如果有,则直接返回

    2): 如果一级缓存查询失败则查询二级缓存,如果二级缓存命中则直接返回

    3): 如果之前的查询都未命中,则发出SQL语句

    4):  根据映射配置和SQL语句得到ResultSet,并创建对应的实体对象;

    5): 将对象纳入Session(一级缓存)的管理

    6): 如果有对应的拦截器,则执行拦截器的onLoad方法

    7): 如果开启并设置了要使用二级缓存,则将数据对象纳入二级缓存; 

    8): 返回数据对象。

    

6、#{}和${}的区别是什么?

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

 

15、Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。

 

    

7: Query接口的list方法和iterate方法有什么区别? 

答: 

list()方法无法利用一级缓存和二级缓存(对缓存只写不读)iterate()方法可以充分利用缓存,如果目标数据只读或者读取频繁,使用iterate()方法可以减少性能开销 

② list()方法不会引起N+1查询问题,而iterate()方法可能引起N+1查询问题

 

8: 如何理解Hibernate的延迟加载机制?

     延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载

 

9: 简述Hibernate常见优化策略。 

制定合理的缓存策略(二级缓存、查询缓存)。 

② 采用合理的Session管理机制。 

尽量使用延迟加载特性。 

④ 设定合理的批处理参数。 

⑤ 如果可以,选用UUID作为主键生成器。 

⑥ 如果可以,选用基于版本号的乐观锁替代悲观锁。 

⑦ 在开发过程中, 开启hibernate.show_sql选项查看生成的SQL,从而了解底层的状况;开发完成后关闭此选项。 

⑧ 考虑数据库本身的优化,合理的索引、恰当的数据分区策略等都会对持久层的性能带来可观的提升

 

 

10: 谈一谈Hibernate的一级缓存、二级缓存和查询缓存。 

一级缓存:默认开启,当应用程序保存持久化实体、修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或通过close()方法关闭Session。通过一级缓存,可以减少程序与数据库的交互,从而提高数据库性能 

二级缓存: 默认是关闭的,手动开启

 

个ID是唯一的

 

12 MyBatis中的动态SQL是什么意思

需要根据用户指定的条件动态生成SQL语句

- if 

- choose / when / otherwise 

- trim 

- where 

- set 

- foreach

    

 

 

                                                                                                           spring

 

谈谈你对spring框架的理解

1.   spring框架是一个开源而轻量级的框架,是一个IOC和AOP容器

2.  spring的核心就是控制反转(IOC)和面向切面编程(AOP)

3. 控制反转(IOC):是面向对象编程中的一种设计原则,用来降低程序代码之间的耦合度,通过容器来实现对象管理

4.  面向切面编程(AOP)将安全,事务等于程序逻辑相对独立的功能抽取出来,利用Spring的配置文件将这些功能插进去,提高了复用性;最主要的作用:可以在不修改源代码的情况下,给目标方法动态添加功能

5.  spring优点:a:非侵入式,独立于各种应用服务器

                          b:依赖注入特点性将组件关系透明化,降低耦合度

                         c:与第三方框架具有良好的整合效果

 

 

13:什么是IoC和DI?DI是如何实现的? 

答:IoC叫控制反转,是Inversion of Control的缩写,DI 叫依赖注入,是对IoC更简单的诠释。控制反转是把对象的调用权交给容器,通过容器来实现对象管理。依赖注入的基本原则是应用组件不应该负责查找资源或者其他依赖的协作对象配置对象由容器负责,查找资源的逻辑交给容器来完成DI是对IoC更准确的描述。

 

14:解释一下什么叫AOP(面向切面编程)

    AOP称为面向切面编程AOP是OOP的延续, 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性,同时提高了开发的效率。在方法中要加入某种系统功能代码,例如:事务、日志、安全性实现AOP功能采用的是代理技术

    

 

                                                                    SpringMVC

1.MVC(Model-View-Controller)是种设计模式,它将程序分为三个核心模块:模型,视图,控制器,各自有各自的任务

 

2.MVC处理的过程

    (1)首先控制器接受用户请求,决定调用哪个模型进行处理

    (2)然后模型根据用户请求进行相应业务逻辑处理,并返回数据

    (3)最后控制器调用相应的视图格式化模型,返回数据,并通过视图呈现给用户

 

      

3.MVC的优点

    (1)多个视图能共享一个模型,同一个模型可以被不同的视图重用,大大提高代码的可重用性

    (2)三个模块都是相互独立,改变其中一个不会影响其他两个,这样的设计思想能构造良好的松耦合的构件

    (3)控制器提高了程序的灵活性

 

 

 

                                                                            Mybatis

 

  • MyBatis是对JDBC的封装,

  • 将SQL语句放在了映射文件中

 

都是orm框架

HibernateMyBatis都可以是通过SessionFactoryBuiderXML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。

   优点:

        1.并且能够自动的将输入参数映射到SQL语句的动态参数上,能够将SQL语句执行的结果集自动的映射成Java对象

         2.可以进行更为细致的SQL优化,可以减少查询字段

 缺点:

      1.框架还是比较简陋,功能不是很齐全,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改

        2.二级缓存对细粒度的数据,缓存实现不好 如果不能完全确定数据更新操作的范围脏数据的出现会给系统的正常运行带来很大的隐患

 

 

 

hibernate:

优点:1  功能强大,数据库无关性好, 需要写的代码很少,开发速度很快

            2. 有更好的二级缓存机制

 

缺点: 学习的难度大

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值