阿里面试官常问:阻塞队列ArrayBlockingQueue与LinkedBlockingQueue的问题

157 篇文章 1 订阅

什么是阻塞队列

阻塞队列最大的特性在于支持阻塞添加和阻塞删除方法:

  • 阻塞添加:当阻塞队列已满时,队列会阻塞加入元素的线程,直到队列元素不满时才重新唤醒线程执行加入元素操作。
  • 阻塞删除:但阻塞队列元素为空时,删除队列元素的线程将被阻塞,直到队列不为空再执行删除操作

Java 中的阻塞队列接口 BlockingQueue 继承自 Queue 接口,因此先来看看阻塞队列接口为我们提供的主要方法:

public interface BlockingQueue<E> extends Queue<E> {

    // 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量)
    // 在成功时返回 true,如果此队列已满,则抛IllegalStateException。 
    boolean add(E e); 

    // 将指定的元素插入到此队列的尾部(如果立即可行且不会超过该队列的容量) 
    // 如果该队列已满,则在到达指定的等待时间之前等待可用的空间,该方法可中断 
    boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; 

    //将指定的元素插入此队列的尾部,如果该队列已满,则一直等到(阻塞)。 
    void put(E e) throws InterruptedException; 

    //获取并移除此队列的头部,如果没有元素则等待(阻塞),直到有元素将唤醒等待线程执行该操作 
    E take() throws InterruptedException; 

    //获取并移除此队列的头部,在指定的等待时间前一直等到获取元素, //超过时间方法将结束
    E poll(long timeout, TimeUnit unit) throws InterruptedException; 

    //从此队列中移除指定元素的单个实例(如果存在)。 
    boolean remove(Object o); 
}

//除了上述方法还有继承自Queue接口的方法 
//获取但不移除此队列的头元素,没有则跑异常NoSuchElementException 
E element(); 

//获取但不移除此队列的头;如果此队列为空,则返回 null。 
E peek(); 

//获取并移除此队列的头,如果此队列为空,则返回 null。 
E poll();

这里我们把上述操作进行分类:

(1)插入方法

  • add(E e):添加成功返回 true,失败抛 IllegalStateException 异常
  • offer(E e):成功返回 true,如果此队列已满,则返回 false
  • put(E e):将元素插入此队列的尾部,如果该队列已满,则一直阻塞

(2)删除方法

  • remove(Object o):移除指定元素,成功返回 true,失败返回 false
  • poll():获取并移除此队列的头元素,若队列为空,则返回 null
  • take():获取并移除此队列头元素,若没有元素则一直阻塞

(3)检查方法

  • element() :获取但不移除此队列的头元素,没有元素则抛异常
  • peek() :获取但不移除此队列的头;若队列为空,则返回 null

ArrayBlockingQueue 和 LinkedBlockingQueue的区别

(1)队列大小有所不同,ArrayBlockingQueue 是有界的初始化必须指定大小,而LinkedBlockingQueue 可以是有界的也可以是无界的(默认是 Integer.MAX_VALUE),对于后者而言,当添加速度大于移除速度时,在无界的情况下,可能会造成内存溢出等问题
(2)数据存储容器不同,ArrayBlockingQueue 采用的是数组作为数据存储容器,而LinkedBlockingQueue 采用的则是以 Node 节点作为连接对象的链表
(3)创建与销毁对象的开销不同,ArrayBlockingQueue 采用数组作为存储容器,在插入或删除元素时不会产生或销毁任何额外的对象实例,而 LinkedBlockingQueue 则会生成一个额外的 Node 对象。在长时间内需要高效并发地处理大批量数据的时,对于GC可能存在较大影响。
(4)队列添加或移除的锁不一样,ArrayBlockingQueue 的锁是没有分离的,添加操作和移除操作采用同一个 ReenterLock 锁,而 LinkedBlockingQueue 的锁是分离的,添加采用的是 putLock,移除采用的是 takeLock,这样能大大提高队列的吞吐量,也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

面试需要掌握那些技能?

1. Java基础知识:包括面向对象编程、集合框架、多线程编程、JVM、测试和调试技术等。

2. 熟悉Spring框架:包括Spring MVC、Spring Boot、Spring Cloud等。

3. 掌握常见的数据库操作技术:如SQL语句、关系型数据库和非关系型数据库等。

4. 熟练使用版本控制工具:如Git等。

5. 对Web开发有一定的了解,熟悉前端相关技术:如HTML、CSS、JavaScript等。

6. 能够写高效的算法,并对数据结构有一定的了解。

7. 有良好的代码习惯,能够编写易于维护和扩展的代码,并理解单元测试和集成测试等概念。

8. 在面试过程中,还需要表达清晰、思路清晰明了、能够准确地回答面试官提出的问题,此外,自信、积极和礼貌也是很重要的。


2023年大厂面试官常问的技术核心知识点

1. Java基础知识:Java语言的基本知识,包括数据类型、继承、多态、接口等。


2. 面向对象编程:对面向对象编程原则和设计模式的理解,如单例、工厂、观察者、策略等。


3. 数据库知识:对关系型数据库和非关系型数据库操作的熟悉程度,掌握SQL语言,了解事务管理机制,并清楚地描述ORM框架的使用场景及实际操作。


4. Web开发:Web开发相关技术,例如Servlet、JSP、Spring MVC、JSON、RESTful API等。熟悉HTTP/HTTPS协议以及网络通信机制。


5. 常用框架:Spring、Hibernate、MyBatis等框架,尤其是Spring框架,深入理解Spring IOC,AOP等核心原理,知道如何配置基础设施组件,如事务管理、缓存等基础组件。


6. 分布式系统架构:分布式系统相关技术,如Dubbo、Zookeeper等,对微服务架构模式有一定的了解,熟悉分布式锁、分布式缓存、分布式数据存储等高可用性方案。


7. 性能排查:了解性能优化的方法,包括代码和SQL调优等,并且熟悉性能监测和分析工具,例如掌握JVM内存结构及堆栈排查技术。


8. 算法和数据结构:有基本的算法和数据结构知识,例如排序、查找、哈希表等。


我最近整理了一些小伙伴们发给我的面试题以及我的一些最新的面试等学习资料,有需要的小伙伴可以找我领取下。或者点击《2023最新Java后端全套VIP面试学习资源》直接获取以下Java后端架构VIP进阶学习面试资料。

资料里面包含了:Java基础、MySQL、jvm、分布式、性能优化、spring 、spring boot、spring cloud、 MyBatis、Netty源码分析、算法、乙级高并发、Redis、dubbo、Tomcat、集合框架、锁、MQ、百万简历模板等等学习视频资料。

资料如图展示:(知识其中一部分)

同时也欢迎大家关注公众号【Java烂猪皮】,回复【666】,获取最新Java后端架构VIP学习资料以及视频学习教程,然后一起学习,一文在手,面试我有。

公众号【Java烂猪皮】里面每天都会分享很多独家的干货内容,比如:Java后端学习路线,分享实战项目,源码分析,百万级系统设计,系统上线的一些坑,MQ专题,真实面试题,每天都会回答大家提出的问题。

每一个专栏都是大家非常关心,和非常有价值的话题,我相信在专栏中你会学到很多东西,一起共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值