Java基础面试题
Java基础面试题
唐喜乐Java中的基本数据类型
基本类型 | 位数 | 字节 | 默认值 | 取值范围 |
---|---|---|---|---|
boolean | 1 | false | true、false | |
byte | 8 | 1 | 0 | -128 ~ 127 |
char | 16 | 2 | ‘u0000’ | 0 ~ 65535 |
short | 16 | 2 | 0 | -32768 ~ 32767 |
int | 32 | 4 | 0 | -2147483648 ~ 2147483647 |
long | 64 | 8 | 0L | -9223372036854775808 ~ 9223372036854775807 |
float | 32 | 4 | 0f | 1.4E-45 ~ 3.4028235E38 |
double | 64 | 8 | 0d | 4.9E-324 ~ 1.7976931348623157E308 |
static、final、this、super关键字总结
final
final主要修饰变量、方法、类
- 修饰变量:被final修饰的变量不可变,一旦赋值后不可再改变
- 修饰方法:被final修饰的方法不可被子类重写
- 修饰类:被final修饰的类不可被继承
static
static主要修饰变量、方法、代码块、内部类
- 修饰变量:被static修饰的变量属于类变量,在类加载时就会分配内存,可以通过类名直接访问,也可以通过对象名访问
- 修饰方法:被static修饰的方法属于类方法,可以通过类名直接访问,也可以通过对象名访问
- 修饰代码块:被static修饰的代码块属于静态代码块,在类加载时就会执行,而且只会执行一次
- 修饰内部类:被static修饰的内部类属于静态内部类,可以通过类名直接访问,也可以通过对象名访问
this
this是一个引用变量,用于引用类的当前实例
- 在方法中,this可以用来访问当前对象的成员变量和成员方法
- 在构造方法中,this可以用来调用当前类的其他构造方法
super
super是一个引用变量,用于从子类访问父类的变量和方法
- 在方法中,super可以用来访问父类的成员变量和成员方法
- 在构造方法中,super可以用来调用父类的构造方法
== 和 equals() 的区别
==
对于基本数据类型来说,== 比较的是值。
对于引用数据类型来说,== 比较的是对象的内存地址
equals()
equals() 不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等
类没有重写 equals()方法:通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是 Object类equals()方法。
类重写了 equals()方法:一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。
String 中的 equals 方法是被重写过的,比较的是String的内容
String、StringBuffer、StringBuilder 的区别
- String被final修饰是不可变的,StringBuilder 与 StringBuffer继承自 AbstractStringBuilder是可变的
- String与StringBuffer线程安全,StringBuilder线程不安全
- 性能:StringBuilder > StringBuffer > String
集合相关
底层实现
List
- ArrayList 对象数组
- Vector 对象数组,线程安全
- LinkedList 双向链表
Set
- HashSet 哈希表,无序集合
- Treeset 红黑树,是有序集合
Map
- HashMap 数组+链表结合使用的链表散列,无序集合
- TreeMap 红黑树,是有序集合
- Hashtable 数组+链表,无序集合,线程安全
Hash具体实现
HashMap 底层是数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的 hashcode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。ArrayList 与 LinkedList 区别
- 底层数据结构: ArrayList 底层使用的是 对象数组;LinkedList 底层使用的是 双向链表 数据结构
- ArrayList 采用数组存储,所以插入和删除元素受元素位置影响,效率不高,但是查找元素效率高;LinkedList 采用链表存储,所以插入和删除元素效率高,但是查找元素效率低
- 内存空间占用:ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要存放直接后继和直接前驱以及数据,比 ArrayList 消耗更多的空间
ConcurrentHashMap 和 Hashtable 的区别
主要是实现线程安全的方式不一样
ConcurrentHashMap 使用Node 数组+链表+红⿊树的数据结构来实现,并发控制使⽤ synchronized 和 CAS 来操作。
Hashtable 使用synchronized来保证线程安全,效率较低。
线程的基本状态
- NEW: 初始状态,线程被创建出来但没有被调⽤ start() 。
- RUNNABLE: 运⾏状态,线程被调⽤了 start() 等待运⾏的状态。
- BLOCKED :阻塞状态,需要等待锁释放。
- WAITING:等待状态,表示该线程需要等待其他线程做出⼀些特定动作(通知或中断)。
- TIME_WAITING:超时等待状态,可以在指定的时间后⾃⾏返回⽽不是像 WAITING 那样⼀直等待。
- TERMINATED:终⽌状态,表示该线程已经运⾏完毕。
sleep() ⽅法和 wait() ⽅法的区别
- sleep() 是 Thread 类的静态本地⽅法, wait() 则是 Object 类的本地⽅法
- sleep() ⽅法没有释放锁,⽽ wait() ⽅法释放了锁
- wait() ⽅法被调⽤后,线程不会⾃动苏醒,需要别的线程调⽤同⼀个对象上的 notify() 或者notifyAll() ⽅法,sleep() ⽅法执⾏完成后,线程会⾃动苏醒,或者也可以使⽤ wait(long timeout) 超时后线程会⾃动苏醒