面试题(查漏补缺)

List和Set的区别

List:有序集合,可重复,按对象的插入顺序保存。允许多个Null元素对象,可以使用iterator取出所有元素,在逐一遍历,还可以使用get(index)获取指定下标的元素。

Set:无序,不可重复。最多只允许有一个Null元素对象,取元素时只能用iterator接口取得所有元素,在逐一遍历。

ArrayList和LinkedList区别

ArrayList:基于动态数组实现,连续内存存储,适合下标访问(随机访问)。有扩容机制,因为数组长度固定,超出长度存数据时需要新建数组,然后将老数组拷贝到新的数组,如果不是尾部插入,还会涉及元素的移动。使用尾插法并指定初始容量可以极大提升性能。

LinkedList:基于链表实现,可以存储在分散的内存中,适合做数据的插入及删除操作,不适合查询。需要逐一遍历,遍历LinkedList必须使用iterator不能使用for循环,因为每次for循环体内通过get(i)取得某一元素时都需要对List重新遍历,性能消耗大。
另外不要用indexOf等返回元素索引,并利用其进行遍历,使用indexOf对list进行遍历,当结果未空时会遍历整个列表。

==和equals比较

==比较的是栈中的值,基本数据类型是变量值,引用类型是堆中内存对象的地址。
equals:object中默认也是采用==比较,但通常会重写。

接口和抽象类的区别

一个类只能继承一个抽象类,但可以实现多个接口。继承抽象类用关键字extends,实现接口用implements。

抽象类中的成员变量可以是各种类型的,而接口中的成员变量默认是public static final类型,必须赋初始值,不能被修改。

抽象类可以存在普通成员函数,接口只有定义,在JDK8之前方法被指定为public abstract,JDK8之后允许添加非抽象的方法,但是必须用default关键字修饰;定义了default的方法可以不被实现子类所实现,但可以被实现子类的对象调用。

接口的设计目的是对类的行为进行约束,也就是提供一种机制,可以强制要求不同类具有相同的行为,它只约束了行为的有无,但不对如何实现行为进行限制。

而抽象类的设计目的,是为了代码复用,当不同的类具有某些相同的行为,且其中一部分行为的实现方式一致(A的非真子集,记为B),可以让这些类都派生与一个抽象类。这个抽象类中实现了B,避免让所有的子类来实现B,这样就达到了代码复用的目的。而A-B的部分,留给各个子类自己实现。正是因为A-B在这里没有实现,所有抽象类不允许实例化。

抽象类是对类本质的抽象,表达的是is a的关系。抽象类包含并实现子类的通用特性,将子类存在差异化的特性进行抽象,交由子类去实现。

接口的核心是定义行为,,即实现类可以做什么,至于实现类主体是谁,如何实现,接口并不关心。

重载和重写的区别

重载:发生在同一个类中,方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同。

重写:发生在父子类中,方法名,参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符的范围大于等于父类,如果父类方法访问修饰符为private则子类就不能重写该方法。