在 Java 面试中,线程和集合相关的知识是非常常见的考察点。以下是几个典型的问题及答案:
线程相关面试题
-
什么是线程?
- 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以有多个线程,这些线程共享进程的资源,如内存地址空间。
-
如何创建线程?
- 有两种主要方式:
- 继承
Thread
类并重写run
方法。 - 实现
Runnable
接口并实现run
方法,然后将其实例传递给Thread
对象。
- 继承
- 有两种主要方式:
-
Thread
和Runnable
的区别是什么?Thread
是一个类,可以直接实例化并启动线程。Runnable
是一个接口,需要实现run
方法。使用Runnable
可以避免单继承的限制,同时可以更好地实现资源共享。
-
什么是线程同步?为什么需要线程同步?
- 线程同步是为了防止多个线程同时访问同一资源而导致数据不一致的问题。Java 提供了多种同步机制,如
synchronized
关键字、ReentrantLock
等。
- 线程同步是为了防止多个线程同时访问同一资源而导致数据不一致的问题。Java 提供了多种同步机制,如
-
synchronized
和ReentrantLock
的区别是什么?synchronized
是内置的锁机制,使用简单但功能有限。ReentrantLock
是java.util.concurrent.locks
包中的锁实现,提供了更多的功能,如公平锁、锁的中断等。synchronized
自动释放锁,而ReentrantLock
需要手动释放锁。
-
什么是死锁?如何避免死锁?
- 死锁是指两个或多个线程互相等待对方释放资源而无法继续执行的情况。避免死锁的方法包括:
- 避免嵌套锁。
- 使用锁顺序。
- 使用超时机制。
- 使用
Lock
接口的tryLock
方法。
- 死锁是指两个或多个线程互相等待对方释放资源而无法继续执行的情况。避免死锁的方法包括:
-
什么是线程池?为什么使用线程池?
- 线程池是一组预先创建的、可重用的线程。使用线程池可以减少创建和销毁线程的开销,提高响应速度,控制并发线程的数量。
- 常见的线程池实现包括
ExecutorService
、ThreadPoolExecutor
等。
集合相关面试题
-
Java 集合框架的主要接口有哪些?
List
、Set
、Map
、Queue
等。
-
List
、Set
和Map
的主要实现类有哪些?List
:ArrayList
、LinkedList
、Vector
。Set
:HashSet
、TreeSet
、LinkedHashSet
。Map
:HashMap
、TreeMap
、Hashtable
、LinkedHashMap
。
-
ArrayList
和LinkedList
的区别是什么?ArrayList
基于动态数组实现,适合随机访问,插入和删除操作较慢。LinkedList
基于双向链表实现,适合频繁的插入和删除操作,随机访问较慢。
-
HashMap
和Hashtable
的区别是什么?HashMap
是非线程安全的,允许一个null
键和多个null
值。Hashtable
是线程安全的,不允许可null
键和null
值。HashMap
的性能通常优于Hashtable
。
-
HashSet
和TreeSet
的区别是什么?HashSet
基于HashMap
实现,不保证元素的顺序,查找效率高。TreeSet
基于TreeMap
实现,保证元素的自然顺序或自定义顺序,查找效率稍低。
-
什么是
ConcurrentHashMap
?ConcurrentHashMap
是HashMap
的线程安全版本,使用分段锁机制来提高并发性能。它允许多个读操作同时进行,但在写操作时会锁定整个段。
-
如何遍历集合?
- 使用
for-each
循环。 - 使用
Iterator
。 - 使用
Stream
API(Java 8 以后)。
- 使用
示例代码
线程示例
// 继承 Thread 类
class MyThread extends Thread {@Overridepublic void run() {System.out.println("Thread running");}
}// 实现 Runnable 接口
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("Runnable running");}
}public class ThreadExample {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();Thread runnableThread = new Thread(new MyRunnable());runnableThread.start();}
}
集合示例
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class CollectionExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("Apple");list.add("Banana");list.add("Cherry");Set<String> set = new HashSet<>();set.add("Apple");set.add("Banana");set.add("Cherry");System.out.println("List: " + list);System.out.println("Set: " + set);}
}