最全【JDK源码】ArrayDeque源码分析,Java工程师最容易遇到4个瓶颈是什么

最后

码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

以下是部分内容截图
架构面试专题及架构学习笔记导图.png

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

allocateElements(c.size());

addAll©;

}

//传入指定大小,初始化数组

private void allocateElements(int numElements) {

elements = new Object[calculateSize(numElements)];

}

// 计算容量,这段代码的逻辑是算出大于numElements的最接近的2的n次方且不小于8

// 比如,3算出来是8,9算出来是16,33算出来是64

private static int calculateSize(int numElements) {

int initialCapacity = MIN_INITIAL_CAPACITY;

// Find the best power of two to hold elements.

// Tests “<=” because arrays aren’t kept full.

if (numElements >= initialCapacity) {

initialCapacity = numElements;

initialCapacity |= (initialCapacity >>> 1);

initialCapacity |= (initialCapacity >>> 2);

initialCapacity |= (initialCapacity >>> 4);

initialCapacity |= (initialCapacity >>> 8);

initialCapacity |= (initialCapacity >>> 16);

initialCapacity++;

if (initialCapacity < 0) // Too many elements, must back off

initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements

}

return initialCapacity;

}

通过构造方法,我们知道默认初始容量是16,最小容量是8

4.入队


入队有很多方法,我们这里主要分析两个,addFirst(e)addLast(e)

队头入队

//从队列头入队

public void addFirst(E e) {

//如果为null,直接抛异常

if (e == null)

throw new NullPointerException();

//将head指针减1并与数组长度减1取模

//目的是防止数组到头了边界溢出

//如果到头了就从尾部再向前

//相当于循环利用数组

//栗子:head为0,数组长度为8.(-1&7)=(-1%8)=7

elements[head = (head - 1) & (elements.length - 1)] = e;

if (head == tail)

//如果头尾在一起了,就触发扩容

doubleCapacity();

}

队尾入队

//从队列尾入队

public void addLast(E e) {

//不允许null元素,否则抛出异常

if (e == null)

throw new NullPointerException();

//在尾指针的位置放入元素

//可以看到tail指针指向的是队列的最后一个元素的下一个位置

elements[tail] = e;

//tail指针+1,如果到数组尾了就从头开始

if ((tail = (tail + 1) & (elements.length - 1)) == head)

doubleCapacity();

}

整个流程:

  1. 入队有两种方式,从队列头或者从队列尾

  2. 如果容量不够了,直接扩大为两倍

  3. 通过取模的方式让头尾指针在数组范围内循环

  4. x & (len - 1) = x % len,使用&的方式更快

5.扩容


//两倍扩容

private void doubleCapacity() {

assert head == tail;

//头指针的位置

int p = head;

//旧数组的长度

int n = elements.length;

// head右边元素的个数

int r = n - p; // number of elements to the right of p

//扩容两倍

int newCapacity = n << 1;

//判断是否溢出

if (newCapacity < 0)

throw new IllegalStateException(“Sorry, deque too big”);

//新建新数组

Object[] a = new Object[newCapacity];

//将旧数组head之后的元素拷贝到新数组中

System.arraycopy(elements, p, a, 0, r);

//将就数组小标0到head之间的元素拷贝到新数组中

System.arraycopy(elements, 0, a, r, p);

//赋值给新数组

elements = a;

//head指向0,tail指向旧数组长度表示的位置

head = 0;

tail = n;

}

下图为一个栗子,可做参考:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wJjh42V-1641083950341)(ArrayDeque源码分析.assets/640)]

6.出队


出队同样有很多方法,我们主要看两个,pollFirst()pollLast()

队头出队

//从队列头出队

public E pollFirst() {

int h = head;

@SuppressWarnings(“unchecked”)

//取队列头元素

E result = (E) elements[h];

// 如果队列为空,就返回null

if (result == null)

return null;

//将队列头置为空

elements[h] = null; // Must null out slot

//队列头指针想右移动一位

head = (h + 1) & (elements.length - 1);

//返回取到的元素

return result;

}

队尾出队

//从队列尾出队

public E pollLast() {

//tail的上一个位置是最后一个元素

//尾指针左移一位

int t = (tail - 1) & (elements.length - 1);

@SuppressWarnings(“unchecked”)

//取当前尾指针处元素

E result = (E) elements[t];

//如果队列为空返回null

if (result == null)

return null;

//将当前尾指针处置为空

总结

面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。

此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!

给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”

image

且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

a、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。

[外链图片转存中…(img-QGl6qqvB-1715588189155)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值