Java八股第四天

82 阅读6分钟

31. 迭代器 Iterator 是什么?

Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获 取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程中移除元素。

32.Iterator 怎么使用?有什么特点?

List list = new ArrayList<>();
Iterator it = list. iterator();
while(it. hasNext()) {
String obj = it. next();
System. out. println(obj); }
Iterator 的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出 ConcurrentModificationException 异常。

33.Iterator 和 ListIterator 有什么区别?

Iterator 可以遍历 Set 和 List 集合,而 ListIterator 只能遍历 List。 Iterator 只能单向遍历,而 ListIterator 可以双向遍历(向前/后遍历)。 ListIterator 从 Iterator 接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元 素、获取前面或后面元素的索引位置。

34.怎么确保一个集合不能被修改?

可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合,这 样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。

35.并行和并发有什么区别?

并行是同一时刻可以多个进程在运行(处于running),并发是经过上下文快速切换,使得看上去多个进程同时都在运行的现象,是一种OS欺骗用户的现象。

  • 并行是指两个或者多个事件在同一时刻发生,而并发是指两个或多个事件在同一时间间隔发生。
  • 并行是在不同实体上的多个事件,并发是在同一实体上的多个事件

36. 线程和进程的区别?

1.进程和线程的区别是,基本单位不同:进程是操作系统资源分配的基本单位,线程是操作系统调度的基本单位。 2.总的来说,进程和线程都是计算机并发执行任务的基本单位,它们之间的主要区别在于资源管理和通信机制上进程是操作系统资源分配和管理的基本单位,而线程是进程内部并发执行的基本单位,它们之间需要根据具体的应用场景进行选择和使用。 3.进程和线程的根本区别是进程是操作系统(OS)资源分配的基本单位,而线程是处理器(CPU)任务调度和执行的基本单位。

37.守护线程是什么?

守护线程(Daemon Thread)是在程序运行时在后台提供服务的线程。与普通线程相比,守护线程的生命周期与程序的生命周期相互关联。当所有的非守护线程结束时,守护线程也会随之结束。
守护线程通常用于执行一些辅助性的任务,如垃圾回收、内存管理等。它们在后台默默地运行,不会阻塞程序的退出。当所有的非守护线程结束时,守护线程会自动退出,不管它是否执行完任务。
守护线程的创建和普通线程类似,可以通过继承Thread类或实现Runnable接口来创建。创建守护线程的方法是调用线程对象的setDaemon(true)方法将其设置为守护线程。
守护线程的特点如下:

  1. 守护线程的优先级比较低,通常低于普通线程。

  2. 守护线程不能持有任何资源,因为它们会在程序退出时被强制终止,无法进行清理操作。

  3. 守护线程不能访问非守护线程创建的对象,因为它们可能在非守护线程结束时被销毁。

守护线程的应用场景包括:

  1. 后台任务处理:守护线程可以用于执行一些后台任务,如日志记录、数据备份等。

  2. 定时任务:守护线程可以用于执行定时任务,如定时清理临时文件、定时发送心跳包等。

  3. 资源管理:守护线程可以用于管理一些资源,如数据库连接池的连接回收、线程池的线程回收等。

需要注意的是,守护线程的运行状态是不可控的,因此在编写代码时要确保守护线程不会影响到程序的正常运行。守护线程也不能依赖于其他线程的执行顺序,因为它们可能会在任意时刻被终止。

38.创建线程有哪几种方式?

创建线程有三种方式: 继承 Thread 重写 run 方法; 实现 Runnable 接口; 实现 Callable 接口。

39.说一下 runnable 和 callable 有什么区别?

  1. 方法不同 Runnable接口只有一个run()方法,该方法不返回任何值,因此无法抛出任何checked Exception。 Callable接口则有一个call()方法,它可以返回一个值,并且可以抛出一个checked Exception。
  2. 返回值不同 Runnable的run()方法没有返回值,只是一个void类型的方法。 Callable的call()方法却必须有一个返回值,并且返回值的类型可以通过泛型进行指定。
  3. 异常处理不同 在Runnable中,我们无法对run()方法抛出的异常进行任何处理。 但在Callable中,自定义的call()方法可以抛出一个checked Exception,并由其执行者Handler进行捕获并处理。
  4. 使用场景不同 Runnable适用于那些不需要返回值,且不会抛出checked Exception的情况,比如简单的打印输出或者修改一些共享的变量。 Callable适用于那些需要返回值或者需要抛出checked Exception的情况,比如对某个任务的计算结果进行处理,或者需要进行网络或IO操作等。在Java中,常常使用Callable来实现异步任务的处理,以提高系统的吞吐量和响应速度。

40.线程有哪些状态?

1. 初始(NEW) :新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE) :Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED) :表示线程阻塞于锁。
4. 等待(WAITING) :进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING) :该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED) :表示该线程已经执行完毕。 这6种状态定义在Thread类的State枚举中,可查看源码进行一一对应。