2024-01-23
2024-01-23
程序员朱永胜Dubbo 负载均衡策略
- 轮询
- 随机:会有问题,单节点卡慢
- 最少活跃:使请求响应慢的节点任务更少
- 一致性 Hash:相同参数请求总是请求到指定的节点
loadbalance 配置
Dubbo 线程模型
Dispatcher
- all:所有请求都发到线程池
- direct:所有消息都不派发到线程池
- message:只有请求响应消息派发到线程池,其他连接断开,心跳等消息,直接再 IO 线程上执行
- execution:只有请求派发到线程池,不含响应,响应和断开,心跳等消息直接在 IO 线程上执行
- connection:再 IO 线程上,将连接断开事件放入队列,其它消息派发到线程池
threadPool
- fixed:固定大小
- cached:缓冲线程池
- limited:可伸缩线程池,线程只会增长不会收缩,防止大流量引起性能问题
- eager:优先创建 worker 线程池,超过 maximum 丢到阻塞队列中
Put 元素,如何计算 Hash 值
首先通过 hashcode 计算,然后通过 CRC16 计算
Put 和 Get 方法的实现
Put
- 判断是否超过(负载因子 * 最大容量)阈值,超过阈值会出发扩容
- 扩容默认是 2 倍
- 计算 hash 值,然后判断值大小
- 如果值大于 8 且数组大小大于 64,会转为红黑树;如果数组小于 64 或者值小于 6 会转为链表
- 在对应的数据结构上添加数据
Get
- 计算 hash 值,查看对应的值是什么数据结构
- 根据对应的数据结构查找值
Hashmap 什么时候会转为红黑树
- 数组大于 64
- 链表长度大于 8
线程安全的 Map
- concurrentHashMap
- collections 工具类
- hashtable
Hashmap 是线程安全的吗
不是
Put 元素,如何计算 Hash 值
首先通过 hashcode 计算,然后高 16 位异或运算
JDK7 和 8 中 HashMap 区别
- jdk7 采用头插法,8 采用尾插法
- 7 使用链表,8 使用链表 + 红黑树
JDK7 和 8 中 Concurrenthashmap 区别
- 7 使用分段锁 8 使用 CAS+Node
JVM 安全点和安全区域是什么
安全点
JVM 清理垃圾的时候会暂停所有线程运行,即 STW。安全点就是 JVM 设置的一些点位,当 STW 的时候,代码执行到点位的时候就会暂停执行,等待 STW 结束。
- 方法执行前
- 方法执行后
- 循环的末位
安全区域
某些运算比较复杂的方法或者执行时间较长的代码段不能立马结束,JVM 就将这块特殊的区域标记为安全区域。安全区域中的代码执行完之后会查看是否 STW 结束了,如果结束了,就继续执行。如果没有结束,就等待。
常见的序列化协议有哪些
- json
- JDK 原生
- protobuff
JDK 自带序列化方式
实现 Serilialable 接口即可,实际就是 WriteObject 和 ReadObject 方法
无序性
值得是内部元素没有先后顺序区分
不可重复性
指的是内部元素不能重复
ArrayList 扩容机制
- 默认扩容 1.5 倍
- 直接创建一个新的数组,然后将原来的数组拷贝过去,然后修改引用指针
如何自定义类加载器
继承 ClassLoader,重写 loadClass,findClass 方法
类加载器
- 启动类加载器 加载 lib 下类
- 扩展类加载器 加载 lib/ext 下类
- 应用类加载器 加载用户
New 一个 HashMap 的时候会发生什么
这里主要看两个参数,负载因子和容量,他们的乘积就是扩容阈值,默认扩容 2 的 n 次,实际就是 2 倍
默认大小 16,默认负载因子 0.75
Copyonwritelist 缺点
- 只能保证最终一致性,不能保证全程一致性
- 占用内存
什么是字节码
一种二进制文件,是通过 Javac 命令生成的一种文件,JVM 能识别这种文件并实现跨平台特性。
受检异常和非受检异常有什么区别
受检异常:启动前必须显示处理,不然编译报错
非受检异常:可以不处理
Java 中的 Unsafe
Unsafe 是 Java 提供的一个类,可以直接控制直接内存。
Vector 和 Stack 区别
Vector 是数组,支持动态扩容
stack 是栈,先进后出
Linkedlist 为什么不能实现 Randomaccess 接口
randomaccess 指的是随机读写,linkedlist 底层是链表,无法实现
Linkedlist 插入和删除元素时间复杂度
插入:O(n) 删除:O(n)
ArrayList 与 LinkedList 区别
- 底层实现不同 数组 链表
- 使用场景不同 查询 增删
Java 随机访问流
randomaccessfile
Java 字节流
input/outputstream
BIO
阻塞 IO 模型,值得是客户端发送请求后等待服务端响应,同一个线程同时只能处理一个请求。
对应 Java 中的实现就是,socket 编程。
Javap 命令
查看二进制文件
Jclasslib
一个 idea 插件,查看字节码
三色标记的大致流程可以讲一下吗
三色标记算法是一种查找垃圾的算法
假设三种颜色
- 白色:初始状态
- 灰色:当前类存在关联类未标记
- 黑色:当前类及其关联类全标记
流程
- 初始状态:所有对象标记位白色
- 并发标记:所有从 GC ROOTS 开始查找的对象标记为灰色
- 最终标记:将灰色节点标记位黑色,开始查找关联节点标记位灰色
- 重复上述流程
- 最终白色的就是垃圾
ArrayList 和 Array(数组)的区别?
可变
javaIO 设计模式之装饰器模式
装饰器实际就是对某个类增强,
类的生命周期
- 加载:将字节码转为 jVM 中的符号引用
- 链接
- 校验:校验语法
- 初始值:分配空间
- 引用:将符号引用转为直接引用
- 初始化:初始化值
- 使用
- 销毁
帧数据
帧数据实际就是栈数据,每个线程会分配一个栈帧,包含程序计数器,局部变量表,操作数栈,引用链接等
CMS 收集器
是基于标记 - 整理算法实现的垃圾收集器,常用于老年代。存在的问题主要是容易产生浮动垃圾
回收过程
- 初始标记:从 GCROOTS 开始查找所有对象(STW)
- 并发标记:从这些对象开始查找关联的对象
- 最终标记:标记上个阶段产生的垃圾
- 清除阶段:清除垃圾