java 八股

101 阅读3分钟

集合相关

ArrayList

图片.png

ArrayList 扩容机制 (JDK8)

无参初始化 初始是一个空数组

图片.png

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

有参可以设置长度

图片.png

有参可以设置集合 根据集合设置大小

图片.png

add方法的扩容机制

图片.png

图片.png 图片.png

addAll方法的扩容机制

图片.png

图片.png

图片.png

小结

图片.png

迭代器 Iterator_FailFast_FailSafe 遍历策略

两张遍历规则
ArrayList迭代器是FailFast CopyOnWriteArrayList()迭代器是FailSafe 图片.png

FailFast源码分析

图片.png 图片.png

图片.png

图片.png

FailSafe源码解析

图片.png

图片.png 图片.png

Arraylist 和linkedList

图片.png

图片.png

HashMap

数据结构

图片.png

hash表的应用场景

图片.png

链表过长的解决——扩容

扩容之后 桶下标会重新计算,进而导致之前一样的桶下标变化,但如果原始hash值一样,扩容就会失效
**一开始满13个元素扩容 **
元素的个数到达hash表总长度的3/4就会扩容 图片.png

链表过长的解决——树化

扩容为64还是有链表长度大于8,之后会树化

图片.png

红黑树的意义,树化的阈值

图片.png

图片.png

红黑树退化为链表

图片.png

图片.png

索引如何计算

图片.png 注意:按位与 与数-1之前要为2的n次幂 图片.png

图片.png

为何要二次哈希

为了使值更均匀 图片.png

HashMap 容量为何是2的n次幂

图片.png

图片.png

HashMap 容量不为2的n次幂行不行

追求效率选2的n次幂,追求分布性选择质数 hashmap 最终选择了2的n次幂 hashtable 容量不是2的n次幂

hashMap put的流程

图片.png

图片.png

负载因子为啥是0.75

图片.png

图片.png

HashMap 并发丢数据

图片.png 并发扩容死锁

图片.png

图片.png

图片.png

图片.png 图片.png

图片.png

hashMap_key的要求

图片.png 图片.png

String对象的hashcode的设计

图片.png

单例模式

图片.png

1 饿汉方式

图片.png 反射破坏单例 图片.png 反制 图片.png 反序列化破坏单例 图片.png 反制

图片.png unsafe破坏单例

图片.png

枚举饿汉

图片.png

图片.png

图片.png

并发篇

线程状态 java中的线程状态

1667715203(1).png

5种状态 VS 6种状态

1667718562(1).png

线程池核心参数

0d68dcc3dcbe0e4bce2879aafdb3273.png 1667720355(1).png

d2e82e6a9411d528dfffc1d72f00556.png

6460eace25b31b66ec41016bc9045b9.png

60fc54d6294ad5304d18bf754b5069d.png

sleep与wait

1667723261(1).png 打断 1667726177(1).png

lock vs synchronized

1667727014(1).png

lock 阻塞

18d39f2b68ac0380afb48a64e506edc.png

公平锁非公平锁

1667804292(1).png 1667804140(1).png

1667804628(1).png

1667804662(1).png

条件变量演示

1667806035.png

volatile是否可以保证线程安全

1667807014(1).png

原子性

1667807590(1).png 运行次序的不同导致错误 1667807798(1).png

可见性

错误回答 1667808688(1).png 正确答案 1667810018.png

964776dbeb5788dfd298c68f2e9e707.png 解决方法 image.png

volatile有序性

volatile保证有序性 使用内存屏障解决指令重排序,但效果也受到加入位置的影响
可以保证r1,r2不出现 1,0的情况 406a9b941813cf4e98398802e229918.png 加载x上无法避免1,0 5672b6137bd3af5ead4ed89d8266aef.png

volatile位置不同影响原因分析

5672b6137bd3af5ead4ed89d8266aef.png

1667812663(1).png

25f460da41b19f26fad15fb56aa6c72.png

悲观锁和乐观锁

悲观锁 91ac58483ea9ea40d6895b17126ab48.png 乐观锁

1667820507(1).png

乐观锁 Unsafe

image.png

悲观锁和乐观锁的代码对比

悲观 不会发生指令交错 1667822024(1).png 乐观 会指令交错 1667822316(1).png

Hashtable vs ConcurrentHashMap (都是线程安全集合)

1667869387(1).png

HashTable

整个hashTable一把锁
扩容大小是×2+1
不需要二次hash fb734047e89bd0f3311d5cb1a67d3f7.png 1667869520(1).png

ConcurrentHashMap java7版本

segment+数组+链表

82aa7bcaca106442a9a6970232301c7.png 91037219d8b433fd3761a2d78e6dc6d.png

ConcurrentHashMap java7版本 索引计算

segment的计算 79ac9057dce6f049dbf02cf9d9ad77c.png segment中小数组的计算

1667873897(1).png

8e2b86ff2e07c839749132c6efde656.png

ConcurrentHashMap java7版本 扩容机制

segment不能扩容
小数组扩容超过3/4 扩容一倍

concurrentHashMap segment[0]原型

1667875451(1).png

ConcurrentHashMap java7版本 vs java8版本

8版本没有segment,懒汉式初始化,扩容方法到3/4就扩容(不用超过)

ConcurrentHashMap java8版本 构造参数含义

注意 数组长度是2的次方 853f1c7f07129a8ee9c536e6bdb78c1.png

1667894510(1).png

并发put

ConcurrentHashMap java8版本 扩容

从后往前迁移节点 6a235d441776ea3e6ede749f7df5579.png

ConcurrentHashMap java8版本 扩容时的细节

扩容时发生get 可以并发执行, 已经F的就到扩容后的数组中找,没F的就到原数组中找。 扩容时发生put, 如果发生在迁移之前的节点,则放入,如果put正在迁移的节点就会阻塞,如果是已经迁移完成的节点,阻塞或帮忙迁移

ThreadLocal的作用

8f3adcdd5b1fe19a02bc5f597de4a10.png

ThreadLocal原理