Java面试备战篇——基础篇(二)

上一篇:Java面试备战篇——基础篇(一)

11、ArrayList和linkedList的区别

Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的j N Y V k * r
Array获取数据的时间复杂度是O(1),但是要删除数据却4 _ V ( V c ` 2是开销很大,因为这需要重排数U 0 , H V - B =组中的所有数据, (因为删除数据以后, 需要把后G b m S v w a面所有的数据前移)
缺点: 数组初始化必须指定初始化的长度, 否则报错
例如:

int[] a = new int[4];//推介使用int[] 这种方式初始化
int c[] = {23,43,56,78};//长度:4,索引范围:[0,3]

List—是一个有序的1 f L M E s y集合,可以包含重复的元素,提供了按索引访问的方式,它继承C0 L dollection。
List有两个重要的实现类:Arra5 I V U j D 9yList和LinkedListQ N s = Z U ?
ArrayLiu + Dst: 可以看作是能够自动增长容量的数组
ArrayList的toArray方法返回? M W [ 9 5 o一个数组
ArrayList的asList方法返回一个列表
Arra3 - AyList底层的实现是Arr^ z say, 数组扩容实现

Lir / = ` 7 R - T pnkList是一个双链表,在添加和删除元素时具有比ArrayList更好的性? # 9 G L c R c能.但在get与set方面弱于
ArrayList.当然,这些对比都是指数据量很大或者操作很频繁。

12、 HashMap和HashTable的区别

1、两者父类不同
HashMap是继承自O o ^ A { h c V wAbstractMap类,而Hashtable是继承自Dictionary类。不过它们都实现了同时实现
了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。
2、对Z 3 % % @ % S外提供的接口不同
Hashtable比HashMap多提供了elmeT . bnts() 和containR N V V , { ks() 两个方法。
elments() 方法继承自Hashtable的U $ 4 c父类Dictionnary。elements() 方法用于返回此Hashtable中的
value的枚举。
3、对null的支持不同
HX g s w U mashtable:key和value都不能为nuX D ^ S ~ 4 p y Gll。
HashMap:key可以为null,但u i - ; w E u *是这样的keu ( ; l & : n X ey只能有一个,因为必须保证key的唯一性;可以有多个key
值对应的value为null。
4、安全性不同
HashMap是线程不安全的,在多线程并发的环境下,可能会产生死锁等问题,因此需要开发人员自己
处理多线程的安全问题。

Hashtable是线程安全的,它的Z q P : = ] a :每个方法上都有synchronized 关键字,因此可直接用于多线程中。
虽然HashMap是线程不安全的,但是它的效率远远高于Hashtable,这样设计是合理的,因为大部分的
使用场景都是单线程。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。
ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为
ConcurrentHashMap使用了分段锁,并不对整? R p { o n z个数据进行锁& J 3] b z U U
5、初始容量大小和每次扩充容量大小不同
6、计算hash值的^ # ; D q d {方法不同

13、 Collection包结构j _ ; ) p u S w,与Collections的区别

Collection是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;
Collections是集合类的一个帮助类, 它包含有各种4 V M @ 1 O有关集合操作的静态多态方法,用于实现对各种集
合的搜索、排序、线程安全化等操作。此类不能实例化,就H * J J B L B o像一个工具类,服务于Java的Collection框
架。

14、 Java的四种引用,强弱软虚

  • 强引用
    强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用方
    式:
    Str} m * l d Oing str = new String("str");
  • 软引用
    软引用在程序内存不足时,会被回收,使用方式:
    // 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,
    // 这里的软引用指的是指向new String("} $ x s b B v i ystrG U | ~] K 8")的引用,也就是SoftReference类中T
    Sof( y MtReference<String> wrfQ b f ~ 8 C T = new Softq ) k nReference<String>(new String("str"));

    可用场景: 创建缓存的时候,创建的对象放进缓存中,当内存不足时,J9 H g Y 2 d , Z rVM就会回收早先创建的
    对象。

  • 弱引用
    弱引用就是只要JVM垃圾回^ O 4 ! M收器发现了它,就会将之回收,使用方式:
    WeakReference&lz ~ h L D ~t;String> wrf = new WeakReference<Stb X W * N 3 Gring>(str);

    可用场景: Java源码中的 java.util.WeakHashMap 中的 key 就是使用2 C 3 A [ P r S弱引用,! / , ]我的理解就是,
    一旦我不j % q需要某个引用,JVM会自动帮我= y k B b ` T R n处理% K 6 z O y 4它,这样我就不需要做其它操0 | b ( S i e U作。

  • G K 4引用
    虚引用的回收机制跟弱引用差不多,但是它被回收之前s [ Y . f b P,会被放入 Ref! t GerenceQueue 中。注意
    哦,其它i x A引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以4 M O G y虚引用大多被
    用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferencQ C # EeQueuek 4 O ; 6 . { ! l ,使/ 4 M g w 1 = . h
    例子:
    PhantomReference<S O Ttring> prf = new PhantomReference<String&( j l ; 8 j ugt;(new
    String("str"), new Referee o en8 ? O C e 1 aceQueue&lR r - ` { 1t;>());

    可用场景: 对象销毁前的一些操作,比如说资源释放等。** Object.finalize() 虽然也可以做
    这类动作,但v g # ? V @是这个方式即不安全又低效

上诉所说的几类引用,都是指对象本身的引用,而不是指 Reference 的四个子类的引用
( Sx D softReference 等)。

15J & I ? 7 s ] i泛型常用特点 (待补充)

泛型是Java SE 1.5之后的特性, 《Java 核心技术》中对泛型的定义是:

“泛型” 意味着编写的代码可以被不同类型的对象所重用。

“泛型”,顾名思义,“泛指的类型”。我们提供了泛指的s R F / $ } E z d概念,但具体执行的时候却可以有具体的规则来
约束,比如我们用的非常多的ArrayList就是个泛型类,Arrah ~ t t EyList作为集合可以存放各种元素,如
Integerm - _ ~ J K &, String,自定义的各种类型等,但2 3 n ]在我们使用的时候通过具体的规则来约束. B n ^ ( U,如我们可以约束
集合中只存放Integer类型的元素,如

List<Integer>q 1 ! T ( H E 1 ^; iniData = new ArrayList<>()

使用泛型的好处?

以集合来举例,使用泛型的好处是我们不必因为添加元素类型的不同而定义不同类型的集合,如整型集
合类,浮点型集合类,字符串集合类,我们可以定义一个集合来存放整型、浮点型,字符串型数据,而
这并不是最重要的,因为我们只要把底层存储设置了Object即可,添加的数据全部都可向上转型为
Object。 更重要的是我们可以通} s e ^过规则按照自己的想法控制存储的数据类型。

1G X y #6、Java创建对象有几种方式?

java中提供了以下四种创建对象的方式:

  • new创建新对象
  • 通过反射机制
  • 采用clone机制
  • 通过序列化机制

17、~ P x有没有可能两个不相等的对象有相同的hashcode

有可能.在产生hash冲突时,两个不相等的对象就会有相同的 hashcode 值.当hash冲突产生时,一般有以
下几种方式来处理:

  • 拉链法:每/ W q哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被
    分配到同一个索引上的多个节点可以用0 _ 4这个单向链表进行存储.
  • 开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找
    到,并将{ y 6 C & g X Z记录存入
  • 哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算c W ) A b ? % [
    地址,直到无冲突.

18、深拷贝和浅拷贝的区别是什么?

  • 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向
    原来的对象.换言之,浅拷贝仅仅复制p V . = E , g所考虑的对象I t # V h 3 6 g,而不R K j f复制它所引用的对象.
  • 深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被
    复制过的新对象.而不再是原有的那些被引Y 6 A = e % /用的对象.换言之.深拷贝把要复制的对象所引用G ? F + x的对象都
    复制了一遍.

19、final有哪些用法?

fina* r Y @ b `l也是很多面试喜欢问的地方g s ) * B I 5,但我觉得这个问题很无聊,通常能Q j R , 8 5 ( H 回答下以下5W i t & # h u 4点就不错了:

  • 被final修饰的类p U ; ] p不可以被继承
  • 被final修饰的方法不可以被重写
  • 被final修饰的变量不可以被改变.如果修饰引用,那么表示引用不可变,引用指向的内s p b容可变b M H C @ u (.
  • 被fL i & g 2 { : Kinal修饰的方法,JVM会尝试将其内0 W 0 x E联,以提高运行效率
  • 被final修饰的常量,在编译阶段会存入常量池中

除此之外,编译器对final域要遵守的两个重排序规则更好:
在构造函数内对一个final域的写入,与随后把这个s s ) B 7 I被构造对象的引用赋值给一个引Z V : G t用变量,这两个操作之
间不能重排序
初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序

20、static都有哪些用法?

所有的人都知道static关键字这T f { % i `两个基本的用法:静态变量和静态方法.也就是被static所修饰的变量/方法
都属于类的静态资源,类实例所共享.

除了静态变量和静态方法之外,static也用于静态块,多用于7 7 p , }初始化操作:

pur ] P :blic calss PreCache{
sta{ _ k R 1 Btic{
//执行相关操作
}
}

此外static也多用于修饰内部类,此时称之为静态内部类.

最后一种用法就是静态导包,即 import static .import static是在JDK 1.5之后引入的新特性,可以用来
指定导入某个类中的静态资源,并且不需要使用类名,可以直接使用资源名,比如:

import static jav D 1 y X V ? fa.lang.Math.*;
public class Test{
public static void main(Sta Q I 2 p ( z 1 Gring[] args){
//System.out.printlB 6 Q 0 [ 4 W _n(Math.sin(20));传统做法
System.out.println(sin(20));
}
}

下一篇:Java面试备战篇$ K 6 l Y { `——基础篇(三)