(此系列试题来源于Java面试宝典书籍)
一、选择题
1. 下面代码运行结果
public static void main(String[] args) {
List<String> a = null;
test(a);
System.out.println(a.size());
}
private static void test(List<String> a) {
a = new ArrayList<String>();
a.add("abc");
}
result:;java.lang.NullPointerException 空指针异常
解析:对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常
2. Linux下查看进程占用的CPU的百分比,使用工具
- A. Ps
- B. Cat
- C. More
- D. Sep
解析:https://www.runoob.com/linux/linux-comm-more.html 菜鸟教程
- linux ps命令,查看进程cpu和内存占用率排序
- Cat是linux文本输出命令 可以一次显示整个文件
- More也是文本输出命令 以一页一页的形式显示文件
- Sep貌似是杀毒...
3. JVM内存里哪个区域不可能发生Out Of MemoryError
- A. 程序计数器
- B. 堆
- C. 方法区
- D. 本地方法栈
解析:https://blog.youkuaiyun.com/qq_33524158/article/details/83348677 作者:小彬彬~
- java程序计数器
- Java虚拟机栈
- 堆
- 方法区
- 运行时常量池
- 本地方法栈
4. 下面关于阻塞队列(java.util.concurrent.BlockingQueue)的说法不正确的是
- A . 阻塞队列是线程安全的
- B. 阻塞队列的主要应用场景是"生产者-消费者"模式
- C. 阻塞队列里的元素不能为空
- D. 阻塞队列的实现必须显示地设置容量
解析:
- 当队列中为空时,从队列中获取元素的操作将被阻塞;当队列满时,向队列中添加元素的操作将被阻塞
- 阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程
D也有问题 :
- ArrayBlockingQueue: 一个基于数组实现的有界阻塞队列,必须设置容量
- LinkedBlockingQueue: 基于链表实现的阻塞队列,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队
- PriorityBlockingQueue: 一个无界的阻塞队列,使用的排序规则和PriorityQueue类似并提供了阻塞操作
- LinkedBlockingDeque: 一个基于双端链表的双端阻塞队列,容量可以选择进行设置
5. 如果现在需要创建一组任务,他们并行的执行工作,然后进行下一个步骤之前等待, 直至所有的任务都完成,而去这种控制可以重用多次, 这种情形使用 java.util.concurrent 包中引入哪种同步工具最适合
- A. CountDownLatch
- B. CyclicBarrier
- C. Semaphore
- D. FurureTask
解析:
- CountDownLatch:倒计时器,是一个非常实用的多线程控制工具
- CyclicBarrier:栅栏类,栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。
- Semaphore:信号量,用于控制访问特定资源的线程数目
- FurureTask:一个可取消的异步计算
二、问答题
1. java 中, 为什么基本类型不能做为 HashMap 的键值, 而只能是引用类型,把引用类型作 为 HashMap 的键值, 需要注意哪些地方?
- 在Java中是使用泛型来约束HashMap中的key和value的类型的,即HashMap< K, V>;而泛型在Java的规定中必须是对象Object类型的,也就是说HashMap< K, V>可以理解为HashMap< Object, Object>,很显然基本数据类型不是Object类型的,因此不能作为键值,只能是引用类型。虽然我们在HashMap中可以这样添加数据:“map.put(1, “Java”);”,但实际上是将其中的key值1进行了自动装箱操作,变为了Integer类型
2. 编写一个工具类StringUtil,提供方法int compare(char[] v1,char[] v2)方法,比较字符串v1,v2,如果按照字符顺序v1>v2则return 1,v1=v2则return 0,v1<v2则return -1
public class StringUtil {
public static int compare(char[] v1,char[] v2){
String str1 = new String(v1);
String str2 = new String(v2);
// compareTo()方法需要的参数为String
int result = str1.compareTo(str2);
return result == 0 ? 0 : (result > 0 ? 1 : -1);
}
public static void main(String[] args) {
char[] v1 = {'a','b'};
char[] v2 = {'c','d'};
// System.out.println(Integer.valueOf('a'));
System.out.println(compare(v1,v2));
}
}
3. Java出现OutOFMemorryError的原因有哪些?出现OOM错误后,怎么解决
出现原因:
- 触发 java.lang.OutOfMemoryError:最常见的原因就是应用程序需要的堆空间是大的,但是 JVM 提供的却小。 这个的解决方法就是提供大的堆空间即可
- 内存泄露:特定的编程错误会导致你的应用程序不停的消耗更多的内存,每次使用有内存泄漏风险的功能就会留下一些不能 被回收的对象到堆空间中 , 随着时间的推移 , 泄漏的对象会消耗所有的堆空间 , 最终触发 java.lang.OutOfMemoryError: Java heap space 错误。第一个解决方案是显而易见的,你应该确保有足够的堆空间来正常运行你的应用程序,在 JVM 的启动配置中增加 -Xmx1024m
- 流量/数据量峰值:应用程序在设计之初均有用户量和数据量的限制,某一时刻,当用户数量或数据量突然达到一个 峰 值 , 并 且 这 个 峰 值 已 经 超 过 了 设 计 之 初 预 期 的 阈 值 , 那 么 以 前 正 常 的 功 能 将 会 停 止 , 并 触 发java.lang.OutOfMemoryError: Java heap space 异常。 解决方案,如果你的应用程序确实内存不足,增加堆内存会解决 GC overhead limit 问题,就如下面这样,给你的应用程序 1G 的堆内存:java -Xmx1024m com.yourcompany.YourClass