数据结构:
1、List、ArrayList、LinkedList
List:元素是有序的(怎么存的就怎么取出来,顺序不会乱),元素可以重复(角标1上有个3,角标2上也可以有个3)因为该集合体系有索引。LinkedList:底层的数据结构是链表结构(特点是查询较慢,增删较快)。
2、HashMapHashMap插入对象时,根据给定的键key计算hashcode,然后再与数组长度进行求余运算得到数组下标。然后与该位置上的链表中已存储的键进行比较,对于已存在的键,则覆盖;对于不存在的键,则添加到链表尾。
工作原理:
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用LinkedList来解决碰撞问题,当发生碰撞了,对象将会储存在LinkedList的下一个节点中。 HashMap在每个LinkedList节点中储存键值对对象。
当两个不同的键对象的hashcode相同时会发生什么? 它们会储存在同一个bucket位置的LinkedList中。键对象的equals()方法用来找到键值对。
key对象相同则覆盖,hashcode相同则添加到链表尾。
3、HashMap与HashTable的区别
Hashtable 继承自 Dictionary 而 HashMap继承自AbstractMap。
HashTable:方法是同步的
方法不允许value==null
方法调用了key的hashCode方法,如果key==null,会抛出空指针异常
HashMap:方法是非同步的
方法允许key==null
方法并没有对value进行任何调用,所以允许为null
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口。主要的区别有:线程安全性,同步(synchronization),以及速度。
4、HsahMap与HashSet的区别
*HashMap* | *HashSet* |
HashMap实现了Map接口 | HashSet实现了Set接口 |
HashMap储存键值对 | HashSet仅仅存储对象 |
使用put()方法将元素放入map中 | 使用add()方法将元素放入set中 |
HashMap中使用键对象来计算hashcode值 | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap比较快,因为是使用唯一的键来获取对象 | HashSet较HashMap来说比较慢 |
5、HashMap和TreeMap的区别
相同点:
HashMap非线程安全,TreeMap非线程安全。都继承了AbstractMap。
不同点:
HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()(可以重写hashCode()和equals()),为了优化HashMap空间的使用,您可以调优初始容量和负载因子。TreeMap:基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。
HashMap:适用于在Map中插入、删除和定位元素。TreeMap:适用于按自然顺序或自定义顺序遍历键(key)。
HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。
HashMap的结果是没有排序的。TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map中插入、删除和定位元素,HashMap是最好的选择。TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
6、树遍历
前序遍历、中序遍历、后序遍历、层序遍历,前、中、后为根节点遍历到的顺序,层序遍历每次遍历一层。
平衡:所有叶子都位于同一层,或至少是彼此相差不超过一个层。
完全:是平衡的,且底层的叶子都都位于树的左边。
堆:完全树,最小或最大。
二叉查找树:左孩子小于父节点,父节点小于或等于右孩子。
优先级队列:优先级队列,因为一般用二叉堆来实现,因此又称为堆。它的每一个父节点的值都比孩子节点大(或者小)。它的工作是查找或者删除优先队列中的最大值(或最小值)
基础:
1、说出final,finalize,finally的区别?
final是修饰符,被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,不能重载。
finalize是方法名。ava技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。
2、对于static关键字的理解。3、重载和重写的区别? 子类可以重载父类的方法吗?
重载:指的是同名的方法拥有不同的参数列表,而系统调用函数是能够根据参数列表选择正确的方法。
重写:指的是是对父类方法的一种覆盖。
子类不可以重载父类的方法,只能重写。
4、Object类常用方法
equals(),toString(),线程通信:wait(),notify(),notifyAll()。
5、常用的类,包,接口,常见的runtime exception常见的异常:ClassCastException (强制转换异常)NullPointerException(空指针异常,使用Null时)ArrayIndexOutofBoundsException(数组越界)StringIndexOutBoundsException(指示索引或者为负或者超出字符串大小)IndexOutOfBoundsException(下标越界)NumberFormatException(数据格式异常,字符串->数字)FileNotFoundException(文件未找到异常)SQLException(操作数据库异常)IOException(I/O输入输出异常)
6、String、StringBuffer、StringBuilder
正常情况下执行效率:StringBuilder > StringBuffer > String(例外情况是String str = "abc"+"de",这种情况相当于String str = "abcde",所以快了不少)7、泛型
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型只在编译阶段有效。
定义一个泛型类:
public class Generic{
//key这个成员变量的类型为T,T的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
this.key = key;
}
public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return key;
}
}
8、Java字节流、字符流
详情见 https://blog.csdn.net/cynhafa/article/details/6882061
9、Java反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。