2021年并发编程面试题解析

线程与进程

  1. 进程和线程的区别是什么?

    进程是操作系统资源分配的基本单位,而线程是CPU调度的基本单位。一个进程可以包含多个线程,它们共享进程的资源,但拥有独立的程序计数器、堆栈和局部变量等。

  2. 多线程编程的优势和挑战是什么?

    优势:

    • 提高资源利用率
    • 提升程序响应速度
    • 便于程序设计和开发

    挑战:

    • 线程同步和互斥问题
    • 上下文切换开销
    • 程序调试难度增加

并发控制

  1. 什么是死锁?如何避免死锁?

    死锁是指两个或多个进程(或线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。

    避免死锁的方法:

    • 破坏互斥条件:允许资源共享
    • 破坏请求与保持条件:进程必须一次性申请所有需要的资源
    • 破坏不剥夺条件:允许进程抢占资源
    • 破坏循环等待条件:对资源进行排序,按照顺序申请资源
  2. Semaphore 和 Mutex 的区别是什么?

    Semaphore 是用于控制访问有限资源的计数器,可以允许多个线程同时访问资源。Mutex 则是用于保护临界区,保证同一时间只有一个线程访问共享资源。

线程池

  1. 为什么要使用线程池?

    • 降低资源消耗:重复利用已创建的线程,降低线程创建和销毁的开销。
    • 提高响应速度:任务到达时,线程池中已有可用线程,无需等待线程创建。
    • 便于管理:线程池可以统一管理线程的生命周期、数量等。
  2. 线程池的工作原理是什么?

    线程池维护一定数量的线程,等待任务的到来。当有任务到达时,线程池会分配一个空闲线程来执行任务。任务执行完成后,线程不会被销毁,而是返回线程池等待下一个任务。

并发编程模型

  1. 介绍几种常见的并发编程模型。

    • Future 模式: 将耗时操作异步执行,并通过 Future 对象获取操作结果。
    • Actor 模型: 将并发实体建模为 Actor,Actor 之间通过消息传递进行通信。
    • CSP 模型: 通过通道进行通信,实现并发实体之间的同步和数据交换。

Java 并发工具类

  1. 介绍 Java 中常用的并发工具类。

    • ReentrantLock:可重入锁,提供比 synchronized 更灵活的锁机制。
    • Condition:条件变量,用于线程之间的协作。
    • Semaphore:信号量,用于控制并发线程的数量。
    • CountDownLatch:倒计时器,用于等待多个线程完成任务。
    • CyclicBarrier:循环栅栏,用于同步多个线程,让它们在同一时刻执行某个操作。
    • ConcurrentHashMap:线程安全的 HashMap,支持高并发访问。
    • BlockingQueue:阻塞队列,用于生产者-消费者模式。
    • AtomicInteger:原子类,提供原子操作,保证线程安全。

其他

  1. 如何保证线程安全?

    • 使用同步机制(锁、信号量等)保护共享资源。
    • 使用线程安全的类库。
    • 避免使用全局变量和静态变量。
  2. volatile 关键字的作用是什么?

    • 保证变量的可见性:修改后的变量值能够立即被其他线程看到。
    • 禁止指令重排序:保证代码执行顺序符合预期。

总结

并发编程是软件开发中不可或缺的技能,掌握并发编程的相关知识点,对于提升程序性能、解决并发问题至关重要。