Java经典面试题整理及答案详解(五)

Java经典面试题第五弹来啦!本节面试题主要是针对Java初级基础提问,看看你还记得多少?

1.String str=“hello”,这个字符串对象在栈内存中明明有一个引用(str[ox00010]),为什么还说这个字符串是匿名对象呢?

所谓的字符串是匿名对象,实际上是因为只要使用了“’’”声明,那么就表示将在堆内存空间里面开辟一个新的字符串对象(String对象),这个对象是可以直接使用的,例如:““hello”.length()”。这个时候的字符串由于没有引用,所以称为匿名对象,对于此时的代码“String str=“hello””,已经明确的为str对象进行实例化,所以“hello”对应的堆内存的地址已经有了明确的栈内存指向,就不是匿名对象了。

2.当使用直接赋值额的方式实例化一个字符串对象的时候,他的引用是保存在哪里的?

只要是引用对象就保存在堆内存里面,而我们所有能够进行的内存控制,也只有堆内存。

3,对象池(常量池)和栈是什么关系?

不论是对象池还是常量池,都是保存在堆内存里面的,而堆内存需要进行一些合理的划分。
image.png

4.不同的操作系统会由软件和硬件模拟出不同的虚拟机,但是不同的JVM对Java程序度支持,能实现这个功能的原理是不是:虚拟机中定义了类似于接口这样的操作,接口中定义了类似native抽象方法,然后具体方法的实现交给操作系统去完成?

对于JVM有三种实现标准,这三种实现标准我们使用的是HotSpot虚拟机标准,这个标准的实现不是简单的调用一些底层函数。它里面是需要与一些设备进行交互的,而整个系统设计之中,为了可以让Java调用函数功能,专门提供有一个native交由JVM负责实现一些具体功能。

5.JVM内存优化
(1)JVM优化的第一个问题,取消掉伸缩区,让total=max;
—— CMS问题,频繁的CMS会导致性能下降;
——伊甸园区、存活区、老年代的关系要说明白,JDK1.8之后取消了永久代,而使用元空间代替。
(2)如果你的内存过大,要使用GI收集器来进行收集;
(3)在Tomcat里面由于其使用基于JVM,所以需要设置一个“JAVA OPTS”指令,可以将全部的内存供Tomcat使用(默认的最大可用内存为全部内存的四分之一,默认的total内存为全部内存的64分之1)。

6.JVM内存组成

扫描二维码关注公众号,回复: 9616447 查看本文章

JVM内存组成里面最为关键的几个内存:
(1)栈内存:只是保存有堆内存的引用地址,而且从一个简单的角度来讲,栈内存可以保存基本类型;
(2)堆内存:Java没有采用句柄的模式进行引用,所以它的引用性能是最高的,但是从另外一个角度来讲,堆内存里面实际上又分为若干个子内存空间:伊甸园区、存活区、老年代(FullGC、MajorGC);
①原则:少产生无用的大量内存空间,因为会引发频繁的GC,而频繁的GC会带来CMS问题,那么会导致程序中断执行,所以这个处理的原则之中对于程序员的要求;
②让你初始化的空间大小等于整个堆内存的分配大小,避免伸缩区,这样可以进行性能的提升;
(3)方法区(JDK1.8以前可以称为永久代,在JDK1.8之后称为元空间);
(4)全局数据区也可以认为其规划在堆内存里面,因为会发现全局数据区中保存的内容有可能是对象,有可能是基本类型,只不过它采用了一种特殊的处理形式而已。
在面试中还有可能问到的是堆内存的组成以及GC的处理流程。

7.HashMap需要resize时扩容因子是如何得到的?

如果要想解决这个问题还是需要进行源代码的深入研究,也就是说对于基本的数据结构(类集)。
在进行数据添加的时候这个里面存在有一个put()方法:

image.png

在put()方法里面可以发现有一个putVal方法(),而且可以发现这个方法首先进行了hash计算(查找),而后在这个方法的实现定义:

image.png

它的容量扩充指的是一开始放30个,如果发现不够了,则进行位移处理,302,那么再一次扩充302*2。

8.说出RuntimeException和非RuntimeException的区别
这里最容易让你混淆的只是一些名词:
java.lang.Runtime类:是一个具备有单例设计模式的开发类,在每一个JVM的进程中只会存在一个Runtime类的对象,这个类给我们最大的帮助在于可以取得一些系统信息或者进行一些进程的处理操作。基本上使用这个类取得一些内存信息或者进行垃圾收集处理。(GC)

image.png

整个JVM内存划分存在伸缩区,面对这样的问题,为了提升性能,往往会将初始化内存与最大内存设为相同。(如果不相同,那么就需要一直进行空间的判断,而后不断进行空间的分配,这样操作是比较可怕的。)

image.png

RuntimeException的异常子类不需要强制性处理,可以由用户选择性处理,而Exception子类必须进行处理,RuntimeException是Exception子类。
这些问题放在一起,就是为了混淆你的认识,这样才有的和你谈,也是为了考察你的基本功是不是扎实。

9.Java内存模型
(1)看你是否是知道Java的内存划分;
(2)看你是否有过具体的工作经验,因为在实际的开发之中,如果不调整内存,那么性能将会造成极大的浪费;
(3)关于GC的解释操作。
说到内存,可能最直观的理解就在于Runtime类中,这个类采用了单例设计模式,这个类之中提供了内存信息的取得,以及系统垃圾的收集处理操作。

范例:取得默认的内存大小:

image.png
image.png

这三个方法的返回值类型都是long,所以返回的数据单位都是字节。

实际在Java里面如果想要进行内存的变更,就需要掌握一下内存的结构(内存模型)。

在Java里面对于内存的空间可以划分为如下几点
1.伊甸园区:新生的对象都保存在此处,但这些新生的对象不一定会一直存活;
此处也属于内存空间,既然是内存空间一定会被占满,如果占满了,就会执行GC操作;
2.旧生代区:如果某些对象其要一直使用,那么就将进入到旧生代区,这属于二级回收保险;
如果要先执行GC,那么肯定先清理伊甸园区,随后如果发现空间不足,继续清理旧生代区;
3.永久区:永久区中的数据不会清除,即使程序出现了“OutOfMemoryError”也不会清除。

范例:直观的观察内存

image.png
image.png
image.png

调整内存大小:-Xms2048M-Xmx2048M-Xmn1024M
(1)“-Xms”:初始分配的内存大小,默认在物理内存的64分之1,但是小于1G;
(2)“-Xmx”:最大分配内存,默认大小为物理内存的4分之1,但是小于1G;
(3)“-Xmn”:设置年轻代(伊甸园区)的堆内存大小;

只有调整之后才可以保证系统内存会得到提升,这样很明显,你就可以发挥出你电脑的性能,因为默认的大小。

更多专业知识,面试技巧就在面试一点通,持续更新中……
感谢浏览~
本内容来源于阿里云大学-Java面试技巧

发布了287 篇原创文章 · 获赞 1010 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/alitech2017/article/details/104530943