Java常见面试题(1)

对java平台的理解,java是否是解释执行?

java是面向对象的语言,最显著的两个特点是“一次书写,到处运行(Write once,run anywhere)”和垃圾收集(GC)。第一个特点使java非常容易的或跨平台能力,第二个特点java通过垃圾收集器回收分配内存,大部分情况下,程序员不需要操心内存的分配与回收。

JRE:java运行环境,包含了JVM和java类库。
JDK:JDK可以看做JRE的一个超集,提供了许多工具,如编译器、诊断工具等。

java解释执行说法不太准确,java源代码首先通过javac便以为字节码文件(.class),然后运行时,通过JVM内嵌的解释器将字节码转换成最终的字节码。但是常见的JVM,如Oracle JDK提供的HotSpot JVM都提供了动态编译器(JIT,Just-In-Time),JIT能够在运行时将热点代码编译成机器码,这种情况下部分热点代码属于编译执行。

通常我们把java分为编译期和运行时。java通过javac编译的字节码和JVM这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是“一次书写,到处执行”的基础。在运行时,JVM会通过类加载器加载字节码,解释或者编译执行。

java字符串String、StringBuffer、StringBuilder的区别?

String提供了构造和管理字符串的各种基本逻辑。是典型的Immutable类,被声明成final class,所有属性也是final的。由于它的不可变性,类似拼接、裁剪字符串都会产生新的String对象。

StringBuffer是为了解决String操作字符串产生太多中间对象的问题而提供的一个类,可以通过append和add方法将字符串添加到已有序列的末尾或指定位置。StringBuffer本身是一个线程安全的可修改字符序列。由于保证了线程安全,所以也产生了额外的性能开销。

StringBuilder是Java 1.5中新增的,在能力上和StringBuffer没有本质的区别,只是去掉了线程安全部分,减少了开销,是大部分情况下字符串拼接的首选。

为了实现修改字符序列的目的,StringBuffer和StringBuilder底层都是利用可修改的数组,二者都继承了AbstractStringBuilder,里面包含了基本操作,区别仅在于最终方法是否加了synchronized。内部数组大小设定,目前实现是,出事长度为16。如果确定拼接会发生非常多次,可以指定合适的大小 ,避免多次扩容的开销。

经过大佬们粗略的统计,把常见应用进行堆转储,然后分析对象组成,发现平均25%的对象是字符串,并且其中一半是重复的。对于这种情况,String在Java 6以后提供intern方法,目的是提示JVM相应字符串缓存起来,以备重复使用。但是并不推荐大量使用intern方法,因为被缓存的字符串是存在PermGen(永久代)中,这个空间是有限的,基本不会被FullGC之外的垃圾收集照顾到。所以使用不当,会出现OOM情况。在后续的版本中,缓存被防止在堆中,永久代也在JDK 8中被MetaSpace(元数据区)替代了。

HashMap、Hashtable、TreeMap有什么不同?

三者都是常见的一些Map实现,是以键值对的形式存储和操作数据的容器类型。

Hashtable是早期java类库提供的一个哈希表实现,本身是同步的,不支持null键和值。

HashMap是应用更加广泛的哈希表实现,行为上大致与Hashtable一致,主要区别在于不是同步的,支持null键和值。

TreeMap则是基于红黑树的一种提供顺序访问的Map,和HashMap不同,它的get、put、remove之类的操作都是O(log(n))的时间复杂度。

Hashtable比较特别,作为类似vector、stack的早期集合相关类型,它是扩展了Dictionary类的,类型结构与HashMap之类明显不同。HashMap等其他Map实现是扩展AbstractMap,里面包含了通用方法抽象。

大部分使用Map的场景就是放入、访问、删除,二对顺序没有什么要求,HashMap在这种情况下是最好的选择。HashMap的性能表现非常依赖哈希码的有效性,所以请务必掌握hashCode和equals的一些基本约定:

  1. equals相等,hashCode一定要相等。
  2. 重写了hashCode一定要重写equals。
  3. hashCode需要保持一致性,状态改变返回的哈希值仍要一致。
  4. equals的反射、传递、对称等特性。

HashMap内部的结构可以看作是(Node < k ,v >[ ] table)和链表结合组成的复合结构,数组被分为一个个桶(bucket),通过哈希值决定了键值对在这个数组的寻址;哈希值相同的键值对,则以链表形式存储。这里需要注意的是,如果链表的大小超过阈值,链表结构就会变成树形结构。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/Andy_96/article/details/82147886