1 关于Java
1.Java的8种基本类型的大小及其封装类
基本类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
---|---|---|---|---|
boolean | Boolean | |||
char | 16 bits | Unicode 0 | Unicode 2^16 -1(65535) | Character |
byte | 8 bits | -128 | +127 | Byte |
short | 16 bits | -2^15(-32768) | +2^15 -1(+32767) | Short |
int | 32 bits | -2^31(-2,147,483,648) | +2^31 -1 (+2,147,483,647) | Integer |
long | 64 bits | -2^63 | +2^63 - 1 | Long |
float | 32 bits | Float | ||
double | 64 bits | Double | ||
void | Void |
2.equals和==的区别
equals用于对比两个对象内容是否一样。==用于比较两个变量的值或两个对象那个的地址是否一样。对象的equals方法继承自Object,如果没有覆盖该方法,那么equals默认为对比两个对象的地址是否一样,即与==的功能一样。
3.Object有哪些公共方法?
方法 | 作用 |
---|---|
clone() | 创建并返回对象的一个副本,需要实现Cloneable接口,否则会抛出CloneNotSupportedException |
equals(Object obj) | 判断某个对象是否与此对象“相等” |
finalize() | 用于释放资源,但不能确定什么时候被调用 |
getClass() | 获取此对象的运行时类 |
hashCode() | 返回对象的哈希码值 |
notify() / notifyAll() | 唤醒此对象监视器上等待的单个或所有线程 |
toString() | 返回对象的字符串表示 |
wait() | 在其他线程调用此对象的 notify()方法或 notifyAll()方法前,导致当前线程等待 |
4.i++是否是原子操作,与++i有什么区别?
不是原子操作,i++ 和 ++i 的区别在于前者是先赋值再自增,后者是先自增再赋值。需要注意的是,Java对自增操作采取了中间缓存变量机制。比如:
int i = 0;
for (int j = 0; j < 10; j++)
i = i++;
在执行了上面的代码之后,i 的值仍然为0。因为自增操作的赋值是赋值给临时变量,i = i++
的过程相当于int temp = i; i = i + 1; i = temp
,所以无论加多少次,结果都是0。
5.hashCode的作用
hashCode用于在散列存储结构中确定对象的存储地址的。如果两个对象相同(equals判断),那么hashCode一定相同;但是hashCode相同,对象不一定相同。如果重写了equals方法,那么hashCode方法也应该尽量重写。
6.hashMap的实现。
7.有哪些线程安全的Map?
(1)HashTable。HashTable作用与HashMap类似,但是HashTable是线程安全的,而且不允许有null的键和值。
(2)ConcurrentHashMap。ConcurrentHashMap采用了“分段锁”的技术,通过将整个Map分为N个Segment(类似HashTable),可以提供相同的线程安全,但是效率却能提升N倍。
(3)synchronizedMap。synchronizedMap()是java.util.Collections中的一个静态方法,通过传入一个Map对象,返回该Map的同步实例。该方法是通过使用synchronize关键字实现的同步。
8.StringBuffer和StringBuilder的区别
两者的区别在于StringBuffer是线程安全的,StringBuilder是线程不安全的。但是StringBuilder在单线程中性能比StringBuffer高。
9.HashMap和HashTable的区别
(1)HashMap线程不安全,HashTable线程安全;HashMap的效率较高。
(2)HashMap允许null作为键和值,HashTable不允许;
(3)HashMap实现了Map接口,HashTable继承了Dictionary类。
(4)HashMap中为了避免产生歧义,去掉了contains方法,而HashTable有contains方法。
10.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行。
11.继承中,静态代码块、构造代码块、构造方法、静态变量和实例变量初始化的执行顺序:
(1)如果类还没有被加载,
①执行父类中的静态代码块和静态变量,且静态代码块和静态变量的执行顺序只与代码中的顺序有关。
②执行子类中的静态代码块和静态变量。
③执行父类中的实例变量初始化。
④执行父类的构造代码块。
⑤执行父类的构造方法。
⑥执行子类的实例变量初始化。
⑦执行子类中的构造代码块。
⑧执行子类中的构造方法。
(2)如果类已经被加载,则静态代码块和静态变量初始化的过程不用再执行。
12.concurrent包下面的常用类。
13.volatile的是实现原理。
14.ArrayList扩容原理。
15.多线程的实现方式。
(1)继承Thread类,重写run()方法。
(2)实现Runnable接口,重写run()方法。
(3)实现Callable接口,重写call()方法。
16.使用线程池的好处。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
网友评论