一、Java基础知识
1. 为什么说Java相对性能较差?
答:因为Java是半编译语言,不能被直接编译成机器可以执行的机器码,所以相对于直接编译语言性能略差。
2.Hotspot原理?
答:由解释器和编译器(C1:Client Complier和C2:Server Complier)组成。
解释器:直接将字节码转化成机器码执行。
编译器:基于计数器探测热点代码,然后使用JIT编译将热点代码转化成本地机器码,下次可以不用经过解释或编译就能直接运行。
3.在一个静态方法内调用一个非静态成员为什么是非法的?
答:因为静态方法可以不用对象所调用,所以静态方法里不可以有非静态成员。
4.String为什么是不可变的?
答: 因为String类中由final修饰字符数组 :因为String类没有提供修改数组的方法,且String类是final修饰的,不可被继承重写String类的方法去修改
private final char[] value
注:Java 9以后,改由byte数组储存
private final byte[] value
5.String与常量池的关系
答:当创建String对象时,JVM会从常量池中查找,是否有与创建的String对象值相同的对象,如果有,就把值赋给当前创建的引用,如果没有,就在常量池创建一个新的String对象。
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
6.线程的基本状态
答:
① new:初始状态,表示线程刚被创建,还没有调用start方法。
② runnable:运行状态,Java线程将操作系统中的就绪和运行统称为“运行中”。
③ blocked:阻塞状态,指线程阻塞于锁。
④ waiting:等待状态,线程进入等待状态,需要其他线程通知或中断
⑤ time_waiting:超时等待,相当于在等待的状态上加了超时限制,如sleep(long millis)方法和wait(long millis)方法,在到达指定时间后,恢复为runnable状态。
⑥ terminated:终止状态,表示线程已执行完毕。
7.基本数据类型和包装数据类型的使用规则
答:成员变量用包装,局部变量用基本。
8.Arrays.asList() 避坑说明
答:Arrays.asList()是泛型方法,必须传入对象数组,不能传入基本数据类型数组!
举例:
// 错误用法:基本类型数组
int[] intArray = {1, 2, 3};
List intList = Arrays.asList(intArray);
// 正确用法:包装类型数组
Integer[] integerArray = {1, 2, 3};
List integerList = Arrays.asList(integerArray);
特别注意:Arrays.asList()生成的List是固定数组,不能使用add()、remove()、clear()等方法。
9.数组怎么转ArrayList最合适?
答:使用 Guava
String[] strArray = {"a", "b", "c"};
List<String> strList = ImmutableList.copyOf(strArray);
10. 线程池的核心参数
答:
- 核心线程数:即最小可用的线程数。
- 最大线程数:当队列任务到达其容量上限时,启用最大线程数。
- 队列容量:当任务量超出核心线程数时,其余的任务进入队列等待。
- 保持连接时间:当前线程数大于核心线程数时,不会立即销毁,而是等超过保持连接时间后,进行销毁回收。
- 拒绝策略:当线程数大于最大线程数启用的策略。
11. JDK1.8后的内存区域
答:
12. JVM调优参数
答:
- -Xms:最小堆内存
- -Xmx:最大堆内存
- 指定新生代内存
- 指定永久代(JDK1.8后移除)/Metaspace 内存
- GC策略:标记-清除、复制、标记-整理