1、== 与 equals 的区别
==: 基本数据类型 比较值
引用类型 比较引用
equals:都是比较值是否相同
示例: String a = "Java";
String b = "Java";
String c = new String("Java");
a == b;//true
a == c;//false
a.equals(c);//true
2、 两个对象hashCode()相同,equals()也一定为true吗?
不对,在散列表中,hashCode()相同表示两个键值对的哈希值相同,但不能表明两个键值对一定相同。
3、 final的作用
final修饰的类不可继承,方法不可重写,修饰的变量为常量
4、String、StringBuffer、StringBuilder的区别
String:声明的是不可变的对象,每次操作都会生成新的String对象,底层为char数组
StringBuffer:定义的是一个可变的字符序列,本质还是char数组存放的,有16个字符的容量,容量不够的时候,会自动扩容,即复制数组。线程安全
StringBuilder:与StringBuffer类似,但线程不安全,单线程情况下推荐使用,效率比StringBuffer高
5、抽象类与接口的区别
抽象类使用extends继承,接口使用implement实现
抽象类中可以有构造函数,而接口中不能
抽象类中方法的修饰符可以为任意,而接口默认为public
抽象类单一继承,接口可多重实现
抽象类和接口都不能被实例化
6、 描述一下你所知道的集合类
常用的分为Collection和Map两大容器
Collection:
List(可存放重复元素,有序):ArrayList、LinkedList、Vector
Set(不可重复,无序):HashSet、TreeSet
Map(以键值对形式存储数据):HashMap、HashTable、TreeMap
ArrayList:底层为动态数组,默认容量大小为10,加载因子为1,自动扩容,新的容量=(原来的容量*3)/2+1,查询多增删少的操作,因为插入数据时会改变其元素的下标,线程不安全;
LinkedList:底层为双向链表,适合增删多查询少的操作,因为LinkedList中每下一个元素的位置都存储在上一个元素中,所以查询起来效率不高,但插入数据时,直接插入到链表尾端即可;
Vector:底层为数组结构,初始容量大小为10,加载因子为1,自动扩容,每次扩大一倍,线程安全类;
HashSet:底层为一个HashMap,存取速度快,线程不安全,初始容量为16,加载因子为0.75,即大小超过容量的0.75倍时,进行扩容,扩大为原来的一倍。去重原理:当我们向HashSet添加元素时,这个值会存储在底层hashMap的key中,而hashMap的key值不能重复,就达到了去重的目的;
TreeSet:基于TreeMap实现,有序,元素不能为null,不可重复;
HashMap:基于散列表实现,map中的key、value以entry的形式存放在数组中,entry的位置有key的hashCode计算得到,这个位置也叫做hash桶。当两个key值算出的hashCode相同时,会发生hash碰撞,通过链表解决,即把新插入的元素放在原来的元素的地方,原来的元素则为新元素的next,在java1.8之后,如果发生hash碰撞的元素大于等于8个时,这个链表就会转变成红黑树。初始容量为16,加载因子为0.75,扩容时增大一倍。线程不安全;
HashTable:与HashMap一样也是一个散列表,它存储的内容是键值对映射,key、value的值不能为null,线程安全,初始容量为11,达到阙值扩容,new=old*2+1;
TreeMap:基于红黑树数据结果的实现,查看键和键值时,它们会被排序,也就是说,我们得到的结果是经过排序的。
7、Java方法中的参数是值传递还是引用传递,如果该参数传的是一个对象呢?
都是值传递,当传递的参数为一个对象时,传递的是引用对象的内存地址。
8、&和&&的区别
逻辑与和短路与,使用&&时,如果前面的一个判断条件不成立,后面的判断条件就不会去执行
9、switch中可以用哪些数据类型
byte、short、int、char、enum(1.5之后)、String(1.7之后)
10、静态变量和实例变量的区别
用static修饰的变量为静态变量,也称类变量,它是属于类的,不管创建多少个对象,在内存中只有一个类变量的拷贝。实例变量需要依赖于某一实例,需要创建对象之后才能访问,可以实现多个对象共享内存。
11、解释一下序列化
将实现序列化的对象转换成字节序列,可以保存在磁盘上,或通过网络传输,以备恢复成原来的对象,使对象脱离程序的运行而独立存在。通过ObjectOutputStream的writeObject(Object obj)方法实现。
12、Error 和 Exception的区别
Error:一般指与虚拟机相关的问题,与程序本身无关,如系统崩溃,虚拟机错误,程序无法处理的问题
Exception:表示需要捕获或处理的异常,是一种设计和实现的问题
分为RunTime异常和Checked异常,RunTime异常需要捕获,通常有IndexOutOfException、NullpointException、ClassCastException,Checked异常通常有IOException、SQLException
13、sleep()与wait()的区别
sleep是线程类的方法,会暂停该线程的执行并指定时间,将执行机会给其他线程,但不会释放对象锁,保持监控状态,到时间后自动恢复。
wait()是Object的方法,执行此方法会释放对象锁,进入此对象的等待锁定池,只有调用notify()或notifyAll()方法才会进入对象锁定池准备获取对象锁
14、sleep()和yield()的区别
sleep()方法给其他线程执行机会时,不考虑优先级情况,所以会先给优先级低的线程执行机会,yield()只会给相同优先级或优先级更高的线程执行机会
线程执行sleep()方法后进入阻塞状态,而执行yield()方法后进入就绪状态
sleep()方法需要声明抛出interruptedException异常,而yield()不需要
sleep()方法比yield()方法具有更好的移植性
15、ThreadLocal是什么
为每个使用该变量的线程提供独立的变量副本,使每个线程都可以独立改变自己的副本,而不会影响其他线程的副本,通常在数据库连接和session管理中使用
16、Sychronized和Lock的区别
Sychronized可以给类,方法,代码块加锁,而Lock只能给代码块加锁
Sychronized不需要手动获取锁释放锁,发生异常时会自动释放锁,不会造成死锁,Lock则需要手动释放锁,如果没有使用unLock()去释放锁,会造成死锁
Sychronized不知道有没有成功获取锁,而Lock可以知道是否成功获取锁
Lock可以提高多个线程进行读操作的效率
Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现
17、Sychronized和volatile的区别
Sychronized修饰的是类,方法,代码块,volatile修饰的是变量
volatile仅可以实现变量的修改可见性,无法保证原子性,而Sychronized可以保证