Java面试题 java高级

1:代码优化

(1)代码优化的目标是:

1 、减小代码的体积

2 、提高代码运行的效率

(2)代码结构层次的优化(目的:更加方便代码的维护–可维护性,可读性)

1.代码注释(代码规范)

2.工具类的封装(方便代码的维护,使代码结构更加清晰不臃肿,保证团队里代码质量一致性)

3.公共部分的提取

(3)代码性能的优化(目的:使程序的性能最优化)

(1)尽量指定类、方法的 final 修饰符

(2)尽量重用对象,比如通常使用stringbuffer替代string来进行字符串的拼接。

(3)尽可能使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快,其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。另外,栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收。

(4)及时关闭流

Java 编程过程中,进行数据库连接、 I/O 流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,将会导致严重的后果。

(5)尽量减少对变量的重复计算

明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作:

for (int i = 0; i < list.size(); i++)

{…}

建议替换为:

for (int i = 0, length = list.size(); i < length; i++)

{…}

这样,在 list.size() 很大的时候,就减少了很多的消耗

(6)尽量采用懒加载的策略,即在需要的时候才创建。

(7)慎用异常。——异常对性能不利。只要有异常被抛出, Java 虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制程序流程。

(8)不要在循环中使用 try…catch… ,应该把其放在最外层

(9)如果能估计到待添加的内容长度,为底层以数组方式实现的集合、工具类指定初始长度比如 ArrayList 、 LinkedLlist 、 StringBuilder 、 StringBuffer 、 HashMap 、 HashSet 等等

(10)当复制大量数据时,使用 System.arraycopy() 命令

(11)循环体内不要不断创建对象,可以在循环体外创建空对象——对象引用,在循环体每次new 对象的时候,对象引用指向的是不同的对象,这时候内存中只有一份,大大节省内存空间。

(12)基于效率和类型检查的考虑,应该尽可能使用 array ,无法确定数组大小时才使用 ArrayList

2:Jvm机制

https://blog.csdn.net/u011546655/article/details/52175550

(1)JVM的基础概念

JVM的中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。

JVM也充当着一个翻译官的角色,我们编写出的Java程序,是不能够被操作系统所直接识别的,这时候JVM的作用就体现出来了,它负责把我们的程序翻译给系统“听”,告诉它我们的程序需要做什么操作。

我们都知道Java的程序需要经过编译后,产生.Class文件,JVM才能识别并运行它,JVM针对每个操作系统开发其对应的解释器,所以只要其操作系统有对应版本的JVM,那么这份Java编译后的代码就能够运行起来,这就是Java能一次编译,到处运行的原因。

(2)JVM的生命周期

JVM在Java程序开始执行的时候,它才运行,程序结束的时它就停止。

一个Java程序会开启一个JVM进程,如果一台机器上运行三个程序,那么就会有三个运行中的JVM进程。

JVM中的线程分为两种:守护线程和普通线程

守护线程是JVM自己使用的线程,比如垃圾回收(GC)就是一个守护线程。

普通线程一般是Java程序的线程,只要JVM中有普通线程在执行,那么JVM就不会停止。

权限足够的话,可以调用exit()方法终止程序。

(3)JVM结构体系

Java面试题 java高级

 

(4)JVM内存空间

JVM内存空间包含:方法区、java堆、java栈、本地方法栈。

1.方法区是各个线程共享的区域,存放类信息、常量、静态变量。

2.java堆也是线程共享的区域,我们的类的实例就放在这个区域,可以想象你的一个系统会产生很多实例,因此java堆的空间也是最大的。如果java堆空间不足了,程序会抛出OutOfMemoryError异常。

3.java栈是每个线程私有的区域,它的生命周期与线程相同,一个线程对应一个java栈,每执行一个方法就会往栈中压入一个元素,这个元素叫“栈帧”,而栈帧中包括了方法中的局部变量、用于存放中间状态值的操作栈,这里面有很多细节,我们以后再讲。如果java栈空间不足了,程序会抛出StackOverflowError异常,想一想什么情况下会容易产生这个错误,对,递归,递归如果深度很深,就会执行大量的方法,方法越多java栈的占用空间越大。

4.本地方法栈角色和java栈类似,只不过它是用来表示执行本地方法的,本地方法栈存放的方法调用本地方法接口,最终调用本地方法库,实现与操作系统、硬件交互的目的。

5.PC寄存器,说到这里我们的类已经加载了,实例对象、方法、静态变量都去了自己改去的地方,那么问题来了,程序该怎么执行,哪个方法先执行,哪个方法后执行,这些指令执行的顺序就是PC寄存器在管,它的作用就是控制程序指令的执行顺序。

6.执行引擎当然就是根据PC寄存器调配的指令顺序,依次执行程序指令。

(5)类加载子系统

类加载子系统也可以称之为类加载器,JVM默认提供三个类加载器:

1、BootStrap ClassLoader :称之为启动类加载器,是最顶层的类加载器,负责加载JDK中的核心类库,如 rt.jar、resources.jar、charsets.jar等。

2、Extension ClassLoader:称之为扩展类加载器,负责加载Java的扩展类库,默认加载$JAVA_HOME中jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。

3、App ClassLoader:称之为系统类加载器,负责加载应用程序classpath目录下所有jar和class文件。

类加载器子系统不仅仅负责定位并加载类文件,它还严格按照以下步骤做了很多事情:

1、加载:寻找并导入Class文件的二进制信息

2、连接:进行验证、准备和解析

1)验证:确保导入类型的正确性

2)准备:为类型分配内存并初始化为默认值

3)解析:将字符引用解析为直接引用

3、初始化:调用Java代码,初始化类变量为指定初始值

(6)方法区(Method Area)

在JVM中,类型信息和类静态变量都保存在方法区中,类型信息是由类加载器在类加载的过程中从类文件中提取出来的信息。

需要注意的一点是,常量池也存放于方法区中。

程序中所有的线程共享一个方法区,所以访问方法区的信息必须确保线程是安全的。如果有两个线程同时去加载一个类,那么只能有一个线程被允许去加载这个类,另一个必须等待。

在程序运行时,方法区的大小是可以改变的,程序在运行时可以扩展。

(7)类型信息包括什么?

1、类型的全名(The fully qualified name of the type)

2、类型的父类型全名(除非没有父类型,或者父类型是java.lang.Object)(The fully qualified name of the typeís direct superclass)

3、该类型是一个类还是接口(class or an interface)(Whether or not the type is a class )

4、类型的修饰符(public,private,protected,static,final,volatile,transient等)(The typeís modifiers)

5、所有父接口全名的列表(An ordered list of the fully qualified names of any direct superinterfaces)

6、类型的字段信息(Field information)

7、类型的方法信息(Method information)

8、所有静态类变量(非常量)信息(All class (static) variables declared in the type, except constants)

9、一个指向类加载器的引用(A reference to class ClassLoader)

10、一个指向Class类的引用(A reference to class Class)

11、基本类型的常量池(The constant pool for the type)

(8)方法列表(Method Tables)

为了更高效的访问所有保存在方法区中的数据,在方法区中,除了保存上边的这些类型信息之外,还有一个为了加快存取速度而设计的数据结构:方法列表。每一个被加载的非抽象类,Java虚拟机都会为他们产生一个方法列表,这个列表中保存了这个类可能调用的所有实例方法的引用,保存那些父类中调用的方法。

(9)Java堆(JVM堆、Heap)

当Java创建一个类的实例对象或者数组时,都在堆中为新的对象分配内存。

虚拟机中只有一个堆,程序中所有的线程都共享它。

堆占用的内存空间是最多的。

堆的存取类型为管道类型,先进先出。

在程序运行中,可以动态的分配堆的内存大小。

堆的内存资源回收是交给JVM GC进行管理的。

(10)Java栈(JVM栈、Stack)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值