谈谈你对Java平台的理解
- Java是跨平台的编程语言,可以实现"一次编译,到处运行"的效果。
- Java语言跨平台是Java虚拟机的功劳,并不是说Java语言可以跨平台,而是在不同的平台都有可以让Java语言运行的环境而已。
Java是解释执行的编程语言吗?
即是编译、又是解释:
- 程序从源代码到运行的三个阶段:编码—编译—运行。
- 首先是将Java源代码转化成.class字节码文件,这是第一次编译,.class文件就是可以到处运行的文件。
- 然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的,即Java的第二次编译。
- "到处运行"的关键和前提就是JVM,因为在第二次编译中JVM起着关键作用。
- Java并不是编译机制,而是解释机制。Java字节码的设计充分考虑了JIT这一即时编译方式,可以将字节码直接转化成高性能的本地机器码。
Exception和Error有什么区别?
- 首先两者都继承于 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被 throw 抛出或者 catch 捕获,它是异常处理机制的基本组成类型。
- Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。
- Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。
- Error 既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。
- Exception 举例:IOException、RuntimeException(NullPointerException、ClassCastException)
- Error 举例:VirtualMachineError(OutOfMemoryError、StackOverflowError)
谈谈fnal、fnally、 fnalize有什么不同?
fnal | 说明 |
---|---|
修饰类 | 该类不允许被继承 |
修饰变量 | 该变量不允许被修改 |
修饰方法 | 该方法不允许被重写 |
fnally 是 Java 保证重点代码一定要被执行的一种机制,我们可以使用 try-fnally 或者 try-catch-fnally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。
fnalize 是基础类 java.lang.Object 的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。
fnalize 机制现在已经不推荐使用,并且在 JDK 9 开始被标记为 deprecated。
String、StringBuffer、StringBuilder有什么区别?
相同点:
- 都是 final 修饰的类
不同点:
- String 所有的属性都是 fnal 的,是 Immutable 类的典型实现。
类别 | String | StringBuffer | StringBuilder |
---|---|---|---|
线程是否安全 | 安全 | 安全 | 不安全 |
动态代理是基于什么原理?
动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。
实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了反射机制。还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似 ASM、cglib(基于ASM)、Javassist 等。
int和Integer有什么区别?
不同点:
- int 的初始值为 0,Integer 的默认值为 null 。
解释以下代码运行结果
Integer a = 129;
Integer b = 129;
// false
System.out.println(a == b);
// true
System.out.println(a.equals(b));
包装类型见的相等判断应该用 equals ,而不是 == 。
对于Integer var=? 在-128~127之间的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生(实际上就产生了2个对象),并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。
对比Vector、ArrayList、LinkedList有何区别?
相同点:
- 都是 List 接口的实现类。
不同点:
类别 | Vector | ArrayList | LinkedList |
---|---|---|---|
底层数据结构 | 数组 | 数组 | 双向链表 |
线程是否安全 | 安全 | 不安全 | 不安全 |
查询效率 | 快 | 快 | 随机访问性能要比动态数组慢 |
插入和删除效率 | 除了尾部插入和删除元素较快,其它位置均慢 | 除了尾部插入和删除元素较快,其它位置均慢 | 快 |
扩容大小 | 初始化长度为0 第一次调用 xxx() 后,长度变为10 当达到xxx后,会调用 xxx() 方法来扩容 扩容大小为原来的2倍 | 初始化长度为0 第一次调用 add() 后,长度变为10 当达到xxx后,会调用 grow() 方法来扩容 扩容大小为原来的1.5倍 |
对比Hashtable、HashMap、TreeMap有什么不同?
相同点:
- 都是 Map 接口的实现类。
- 都是以为 key-value 键值对形式存储数据。
不同点:
类别 | Hashtable | HashMap | TreeMap |
---|---|---|---|
线程是否安全 | 安全 | 不安全 | 不安全 |
对null值得的处理 | key或value,都不能为null,会抛出异常NullPointerException | key、value都可以为null | 不安全 |
如何保证集合是线程安全的?
方法一:java.util.Collections
Collections.synchronizedList();
Collections.synchronizedMap();
Collections.synchronizedSet();
方法二:JUC并发包
// 数组
java.util.concurrent.CopyOnWriteArrayList
// Map
java.util.concurrent.ConcurrentHashMap
// Set
java.util.concurrent.CopyOnWriteArraySet
// 链表
java.util.concurrent.LinkedBlockingDeque
java.util.concurrent.LinkedBlockingQueue
java.util.concurrent.LinkedTransferQueue
// 栈、队列
java.util.concurrent.ConcurrentLinkedDeque
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ArrayBlockingQueue
// 其他常用类
java.util.concurrent.CountDownLatch
java.util.concurrent.atomic.AtomicInteger
java.util.concurrent.atomic.AtomicLong
java.util.concurrent.atomic.AtomicBoolean
HashMap为什么线程不安全
ConcurrentHashMap如何实现高效地线程安全?
Java提供了哪些IO方式? NIO如何实现多路复用?
Java有几种文件拷贝方式?哪一种最高效?
谈谈接口和抽象类有什么区别?
谈谈你知道的设计模式?