大厂学苑之JUC并发编程与源码分析(中)
8. CAS8.1 没有CAS之前
多线程环境不使用原子类保证线程安全(基本数据类型)
1234567891011121314151617181920212223 package com.atguigu.juc.prepare;import java.util.concurrent.atomic.AtomicInteger;/** * @auther zzyy * @create 2020-04-15 10:41 */public class T3{ volatile int number = 0; //读取 public int getNumber() { return number; } //写入加锁保证原子性 public synchronized void setNumber() { number++; }}
多线程环境 使用原子类保证线程安全(基本数据类型)
12345678910111213141516171819202 ...
大厂学苑之JUC并发编程与源码分析(上)
JUC并发编程与源码分析1. 本课程前置要求说明JUC四大口诀
高内聚低耦合前提下,封装思想,线程操作资源类
判断、干活、通知
防止虚假唤醒,wait方法要注意
注意标志位flag,可能是volatile的
JUC要求的知识内容
ReentrantLock
ReentrantReadWriteLock
Condition
工具类
CountDownLatch
CyclicBarrier
Semaphore
线程池与阻塞队列
ForkJoinPool与ForkJoinTask
Java8新特性函数式编程、方法引用、lambda Express
原子操作类Atomic
volatile
Callable和FutureTask
本课程的难度对标
阿里P6—P7
阿里P6、P7对高级Java开发工程师的要求明细
技术栈
阿里手册规范
大厂面试题
1、闲聊,自我介绍,负责业务,技术栈
【JUC】
2、synchronized作用、底层实现
3、说下什么是偏向锁,什么时候触发锁升级
4、jmm内存模型,说一下理解、这种内存模型会导致什么问题
5、把你 ...
MESI原理
由于 CPU 的运算速度远远的超过了内存的 IO 速度,因此在它和内存间又加了一层高速缓存,引入了缓存就必然带来一致性的问题。来看看这样的语句执行起来会是什么样的效果。 CPU b 先加载了 n=1,然后cpuA也加载了n,还进行了n+1的操作,这时候 CPU b 再去获取 n 的值。由于高速缓存中已经有值了,所以他拿到的还是n=1,产生了不一致的情况。 CPU 厂商为了解决这样的情况,引入了缓存一致性的协议。常见的比如说MESI,它有四个状态对应着修改、独占、共享、失效,而这四种状态又能量转换形成 16 种情况,这其实就是一个状态机。这个状态机看得我都头大,其实我们没有必要去了解得很透彻,继续用刚刚的例子走一遍流程,看看它是如何保证一致性的。
CPU b 先获取 n 的值,这时候它是独占状态,然后 CPU a 在获取 n 的时候,通过总线地址冲突检测到 b 有这个值,于是向 b 请求这个值,这时候 n 变成了共享状态。当 CPU a 要修改 n 的时候,会通过总线发出失效命令,让 b 的高速缓存对应的 n 的状态变为失效。收到 ACK 后让本地的 n 变为独占状态 ...
一些面试笔记
解释下Java线程池的各个参数的含义?在JDK当中,创建线程值的API为ThreadPoolExector类,这个类的构成方法当中就包含了创建线程值的几个核心参数。第一个corePoolSize用于设置线程池里面的核心线程数量maxPoolSize用于设置线程池里面允许的最大线程数量keepAliveTime用于设置当线程数量大于corePoolSize多出来空闲的线程将会在keepAliveTime之后就会被释放掉。unit用于设置keepAliveTime时间单位,比如秒钟、分钟等。workQueen用于设置等待队列,ThreadFactory用于设置每当创建新的线程放入线程值的时候,就会是就是通过这个线程工厂来创建的。handler用于设置就是说当线程等待队列都满了之后采取的策略,比如抛出异常等策略。那我们假设一组参数值来说明一下这些参数的含义。假设我们设置corePoolSize为1,maxPoolSize为3,keepAliveTime为60秒,workQueen为ArrayBrokingQueen有界阻塞队列大小为4,handler了默认的策略抛出一个所的threadRej ...
使用kubeadm快速部署一个K8s集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。
这个工具能通过两条指令完成一个kubernetes集群的部署:
12345# 创建一个 Master 节点$ kubeadm init# 将一个 Node 节点加入到当前集群中$ kubeadm join <Master节点的IP和端口 >
1. 安装要求在开始之前,部署Kubernetes集群机器需要满足以下几个条件:
一台或多台机器,操作系统 CentOS7.x-86_x64
硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
禁止swap分区
2. 准备环境
角色
IP
master
192.168.1.11
node1
192.168.1.12
node2
192.168.1.13
使用kubeadm方式搭建K8s集群主要分为以下几步
准备三台虚拟机,同时安装操作系统CentOS 7.x
对三个安装之后的操作系统进行初始化操作
在三个节点安装 docker ku ...
单机Kubernetes安装
安装 kubectl
下载对应版本的kubectl
下载一个可执行文件,加入到PATH环境变量即可
需要指定版本直接换版本即可(我安装是1.17,直接脚本中替换为v1.17.0即可)
12345678# Linuxcurl -LO https://dl.k8s.io/release/v1.22.0/bin/linux/amd64/kubectl# Maccurl -LO "https://dl.k8s.io/release/v1.22.0/bin/darwin/arm64/kubectl"# Windowscurl -LO "https://dl.k8s.io/release/v1.22.0/bin/windows/amd64/kubectl.exe"
配置PATH环境变量
12345678910# 给下载的kubectl 赋予权限chmod +x kubectl# kubectl 放到当前用户家目录下.local/bin/下(可以直接放到PATH环境变量下即可譬如/usr/local/bin下)mkdir -p ~/.local/b ...
Spring是如何使用三级缓存来解决循环依赖问题?
1.什么是循环依赖?假设我们有两个类 A 和 B,类A和类B的实例互为成员变量即为循环依赖。
当然也有可能是一个类,或三个类间进行循环依赖。
2.什么是Spring的循环依赖?我们这里还是拿上面类 A 和 B 来举例:
补充知识:Bean的声明周期如下:
当 Spring 框架启动后,开始根据注解将类 A 实例化并注入到容器当中,在实例化 A 之后就会尝试获取类 B 的实例来进行依赖注入。
由于类 B 并没有进行实例化,那么 Spring 框架就会去实例化类 B,同样的也会需要将类 A 的依赖注入到类 B 的实例中:
最终,无论先实例化哪个类,都会形成死循环。
简化后如下所示:
3.三级缓存解决循环依赖Spring 框架解决循环依赖是通过三级缓存,对应的三级缓存如下所示:
12345678910// 单实例对象注册器public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { private static fina ...
Elasticsearch数据写入
es的架构简介首先,从架构的角度来看,Elasticsearch是一个分布式的搜索和分析引擎,它能够存储、搜索和分析大量数据。为了实现这些功能,Elasticsearch采用了分片和副本的机制,使得数据可以分布在多个节点上,并且具有容错性和可扩展性。简要介绍Elasticsearch的架构:
1. 分布式架构节点与集群:Elasticsearch由多个节点(Node)组成,这些节点可以组成一个集群(Cluster)。每个节点都可以处理读写请求,并且数据在集群中的节点之间进行分布和复制,以实现高可用性和扩展性。
分片与副本:为了支持大规模数据,Elasticsearch将索引划分为多个分片(Shard),每个分片可以独立存储和处理数据。此外,每个分片可以有多个副本(Replica),用于提供数据冗余、故障恢复和读取负载均衡。
2. 索引与搜索倒排索引:Elasticsearch使用Lucene作为其底层的搜索库。Lucene构建倒排索引(Inverted Index)来加速搜索过程。倒排索引将文档中的单词映射到包含这些单词的文档列表,从而实现快速查找和检索。
查询执行:当客户端发送搜索 ...
三色标记法
JVM(Java虚拟机)中的三色标记法是一种用于垃圾收集(Garbage Collection, GC)的算法,尤其在CMS(Concurrent Mark Sweep)和G1(Garbage First)等并发收集器中广泛使用。该算法通过将对象标记为三种不同的颜色来追踪和识别垃圾对象,从而在不发生或尽可能短地发生STW(Stop The World,即全线程停顿)的情况下进行垃圾收集。以下是三色标记法的详细介绍:
三色标记法的颜色定义
白色:表示对象尚未被垃圾收集器访问过。在可达性分析刚开始的阶段,所有的对象都是白色的。如果在分析结束的阶段,对象仍然是白色的,则表示该对象不可达,即被认为是垃圾。
灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过。在扫描过程中,垃圾收集器会从灰色对象出发,继续扫描其引用的其他对象。
黑色:表示对象已经被垃圾收集器访问过,并且这个对象的所有引用都已经被扫描过。黑色对象是安全存活的,不会被作为垃圾回收。
三色标记法的流程
初始状态:所有对象都是白色的。
根节点标记:将GC Roots(如线程栈、静态变量等)直接可达的对象标 ...
令牌桶算法Java实现
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051/** * 令牌桶,使用令牌桶算法进行限流 * */public class TokenBucket { private double capacity;// 令牌容量,桶内能容纳的令牌数 private double rate;// 令牌增加速率,每毫秒增加的可用令牌数 private double lastSize;// 上次获得令牌之后,桶内的剩余可用令牌数 private long lastAcquireTime;// 上次获得令牌的时间 /** * @param capacity 令牌容量,桶内能容纳的令牌数 * @param rate 令牌增加速率,每毫秒增加的可用令牌数 */ public TokenBucket(double capacity, double rate) { this.capacity = capacity; this.rate = ...








