Java问题解疑

一. Java基础

JVM

1、JVM初始化步骤 ? 2、类初始化时机 ?3、哪几种情况下,Java虚拟机将结束生命周期?

初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:
①声明类变量是指定初始值
②使用静态代码块为类变量指定初始值

  • JVM初始化步骤
    1、假如这个类还没有被加载和连接,则程序先加载并连接该类
    2、假如该类的直接父类还没有被初始化,则先初始化其直接父类
    3、假如类中有初始化语句,则系统依次执行这些初始化语句
  • 类初始化时机:只有当对类的主动使用的时候才会导致类的初始化,类的主动使用包括以下六种:
    • 创建类的实例,也就是new的方式
    • 访问某个类或接口的静态变量,或者对该静态变量赋值
    • 调用类的静态方法
    • 反射(如Class.forName(“com.shengsiyuan.Test”))
    • 初始化某个类的子类,则其父类也会被初始化
    • Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类
  • 结束生命周期
    在如下几种情况下,Java虚拟机将结束生命周期
    • 执行了System.exit()方法
    • 程序正常执行结束
    • 程序在执行过程中遇到了异常或错误而异常终止
    • 由于操作系统出现错误而导致Java虚拟机进程终止

Java 并发

如何合理的配置java线程池?如CPU密集型的任务,基本线程池应该配置多大?IO密集型的任务,基本线程池应该配置多大?用有界队列好还是无界队列好?任务非常多的时候,使用什么阻塞队列能获取最好的吞吐量?
答:1)配置线程池时CPU密集型任务可以少配置线程数,大概和机器的cpu核数相当,可以使得每个线程都在执行任务
2)IO密集型时,大部分线程都阻塞,故需要多配置线程数,2*cpu核数
3)有界队列和无界队列的配置需区分业务场景,一般情况下配置有界队列,在一些可能会有爆发性增长的情况下使用无界队列。
4)任务非常多时,使用非阻塞队列使用CAS操作替代锁可以获得好的吞吐量。

动态代理

在程序运行时,运用反射机制动态创建而成。动态代理的优势就是实现无侵入式的代码扩展。

应用场景
  • 方法增强,Spring AOP
  • 远程调用,RPC
JDK动态代理与CGLIB区别
  • JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
  • CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。
    CGLIB是一个强大的高性能的代码生成库。作为JDK动态代理的互补,它对于那些没有实现接口的类提供了代理方案。在底层,它使用ASM字节码操纵框架。本质上来说,CGLIB通过产生子类覆盖非final方法来进行代理。它比使用Java反射的JDK动态代理方法更快。CGLIB不能代理一个final类或者final方法。通常来说,你可以使用JDK动态代理方法来创建代理,对于没有接口的情况或者性能因素,CGLIB是一个很好的选择。

推荐阅读更多精彩内容

  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 3,640评论 1 14
  • 对于上班党来说我们每年最向往的时刻之一――年休假。 年休假最惬意的当属外出旅行了。可估计80%的伙...
    清水05阅读 92评论 8 9
  • 2017年6月8号 星期四 晴 今天跟儿子视频,听儿子讲发生在学校里的趣闻趣事。 我们聊到了侄女的高考情况,...
    袁千贺妈妈阅读 53评论 0 2
  • 当我在写诗的时候 我在写些什么 文字在我笔下流淌 诉说着言不由衷的故事 是爱恋是相思 是惆怅是别离 是我的情感是我...
    夏有小雨阅读 106评论 0 1