https://blog.****.net/sheng_q/category_10901984.html?spm=1001.2014.3001.5482
字节流:面向字节的io流,音频 图片 歌曲
byteArray/stringbuffer/file/piped/sequence /filter/data/buffer缓冲/lineNumber/pushedbackInputStream
byte/file/piped/filter/data/print/bufferedOutputStream
reader/writer:字符流 2个字节的Unicode字符 需要缓冲区, 转成字节放入硬盘
io
nio:同步非阻塞 多路复用基础
异步:用户进程read操作 去做其他事情 ,内核角度asynchronousread后 立刻返回,内核等待数据准备好 拷贝到用户内存 ,内核给用户发送signal
同步/异步:消息通信机制,发起调用等待结果
阻塞/非阻塞:等待调用结果时的状态,阻塞 结果返回之前会被挂起 得到结果才会返回
reactor:同步io 事件分离器 等待文件描述符 /socket读写操作准备就绪,处理器具体操作
proactor:异步io 是处理器也是分离器,io交给操作系统:数据缓冲区地址 数据大小
异步情况下(Proactor),当回调handler表示I/O操作已经完成;
同步情况下(Reactor),回调handler表示I/O设备可进行某个操作(can read or can write)
BIO:
同步阻塞,while循环服务端accept等待接收,接收到套接字上读写请求,不再接受其他的请求
NIO:
基于Reactor,有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的
事件驱动/避免多线程/单线程多任务/非阻塞IO /基于block传输/零拷贝/io多路复用
零拷贝:
fileChannel:transferTo transferFrom
通道交叉连接到另一个通道,DMA文件内容复制到内核读缓冲区,数据从这个缓冲区复制另一与socket输出相关的内核缓冲区中,第三次复制DMA把socket关联的缓冲区中的数据复制到协议引擎上发送到网络上
优化:
transferTo数据复制到内核缓冲区,描述符追加到socket关联的缓冲区中,DMA将缓冲区中数据传输给协议引擎
ServerSocketChannel:监听tcp连接SocketChannel
SocketChannel:连接tcp套接字的通道
AIO:
有流可读,可读流传入read方法的缓冲区,通知应用程序
select和epoll:select posix标准,epoll上linux
select句柄数目受限,最多1024个 ;epoll没有 限制最大的打开文件句柄数目
epoll不会随fd数量增长而降低效率,select轮询 数组,epoll队列 只操作活跃socket(callback)
解决:io多路复用,描述符列表 调用函数 直到其中一个准备好才返回, 告诉进程哪些IO就绪
NIO技术概览 | Idea Buffer
epoll
事件驱动的I/O模型,同时处理大量的文件描述符
内核与用户空间mmap共享一个事件表:监控的文件描述符以它们的状态,当状态变化,内核将事件通知给用户空间,用户空间根事件类型进行相应的处理
epoll_create(内核空间)创建文件描述符epfd
ep_alloc建初始化eventpoll
eventpoll:被监听socket列表rbr(epitem)/等待队列wq/就绪socket列表rdllist(wait方法从其取)
epitem:红黑树rbn/rdllink就绪列表/ffd引用描述符/pwqlist等待队列/eq含当前的eventpoll对象指针/event感兴趣的事件和源fd
anon_inode_getfd把wventpoll映射到文件描述符
epoll_ctl:添加或删除要监听的socket(到epfd)
epoll_wait等待数据
bean实例化与依赖注入
属性注入:javaBean中存在默认构造函数 设置方法
Spring系列-3 Bean实例化与依赖注入_实例化包括属性注入嘛-****博客
循环依赖:提前暴露引用
/**创建好的对象 实例化 属性设置 初始化Cache of singleton objects: bean name to bean instance*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**半成品对象Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/**构造bean对象的lambda表达式,bean对象创建工厂Cache of singleton factories: bean name to ObjectFactory.(被代理的)对象 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
三级缓存作用:
如果需要代理 初始化阶段的aop提前至属性设置阶段,引入this.earlyProxyReferences标志(map)
lambda表达式并执行获取代理对象
二级缓存作用:
第一次通过lambda表达式得到代理对象,将代理对象存入二级缓存并删除三级缓存
第二次直接从二级缓存中查询,而不需要再次执行lambda表达式
inject:
根据beanName等信息获取待注入的值; 通过反射完成属性注入
国际化
Locale类国际化类型,包含国家和地区
准备国际化文件:资源名_语言_国家/地区.properties(只能含ASCII字符)
refresh()的步骤中存在initMessageSource()
springboot 通过spi spring.factories中MessageSourceAutoConfiguration @ConditionalOnMissingBean
JsonDeserializer 自定义
高并发优化:
高并发扣减库存:
提交订单-库存,支付时效,超过自动取消订单 还原库存
token校验/防多次刷单 拉黑/ redis先操作 扣减库存 支付的时候再实际扣减库存
扣减明细 流水 / 缓存扣减 / 扣减库 +MQ
定期检查redis/数据库 一致性; 异步更新缓存canal
https://blog.****.net/sheng_q/category_10901984.html?spm=1001.2014.3001.5482
线程池:
corePoolSize:核心
maximumPoolSize 核心+非核心
threadFactory工厂:释放守护/优先级
blockingQueue:
- LinkedBlockingQueue链式阻塞队列Integer.MAX_VALUE,无限创建队列
- ArrayBlockingQueue数组阻塞队列,需要指定队列的⼤⼩
- SynchronousQueue同步队列,内部容量为0,每个put操作必须等待⼀个take操作
- DelayQueue延迟队列,当其指定的延迟时间到了,才能够从队列中获取到该元素
rejectedExecutionHandler拒绝策略:
- AbortPolicy丢弃任务并抛RejectedExecutionException异常
- DiscardPolicy丢弃新来的任务
- DiscardOldestPolicy丢弃队列头部(最旧)任务 重新尝试执⾏程序(如果失败,重复此过程)
- CallerRunsPolicy调⽤线程来处理该任务
newCachedThreadPool 很多短时间的任务时,线程复⽤率⽐较⾼,非核心线程 先入队
0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>()
newFixedThreadPool只创建核⼼线程
nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()
newSingleThreadExecutor
1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()
newScheduledThreadPool定⻓线程池,⽀持定时及周期性任务执⾏
corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()
【多线程】线程池里边都有些什么东西呢_当队列满了,核 线程空闲、扩展线程也空闲,谁从队列 获取?-****博客百度安全验证
object.finalize在垃圾收集器删除对象之前对这个对象调用的
SynchronousQueue: 公平内部TransferQueue队列:头尾两个指针队尾匹配队头出队,先进先出
非公平TransferStack栈,head指针 CAS
跳表:结点可含很多个指向后续结点的指针,可跳过不必要结点,加快查找、删除等。链表内每一个结点包含多少个指向后续元素的指针,通过一个随机函数生成器得到
concurrentHashMap:
java1.7与1.8
1.7 switch支持字符串,catch可分配更多空间 自动释放资源
1.8 lambda表达式 stream流 函数式编程
collection
list/set/map:
hashset:可null 基于hashmap 非线程安全
linkedHashset:继承hashset 可null linkedHashSet有linkedhashmap 双向链表和hashmap 非安全
treeset:不null treemap 红黑树 次序,非安全
自然排序:comparable ;比较排序java.util的comparator
list:有序 ????️重 ,顺序索引
arraylist:可null 数组实现 动态增长/再分配object数组 非线程安全
linkedlist:可null 双端链表 队列和栈 ,deque继承queue 非线程安全
stack 继承vector 模拟栈 先进后出 线程安全
queue:FIFO 新元素插入到队尾 访问元素返回队头
priorityQueue:不null 二叉堆底层,队列大小重新排序
arrayDeque:基于数组双端队列,arraylist类似 底层动态/可重分配object数组存储集合元素
map:映射关系
hashmap:1.7 散列表+链表,1.8散列表+链表+红黑树 非线程安全
linkedhashmap:继承hashmap,双向链表+hashmap 非线程安全
treemap:sortedMap,红黑树 非安全
hashtable 线程安全
ArrayList和LinkedList:
arraylist动态数组,随机访问get/set,指定位置插入 arraycopy耗时
linkedList双向链表,for循环获取元素,index<size/2,左边查 否右边查
数据量大 插入数据 arraylist优势大 特别是后面位置查入
java集合框架05——ArrayList和LinkedList的区别-****博客
Kunbernetes(k8s)的基本概念详解+部署_kuburnetes-****博客
安全验证 - 知乎
linkedHashMap
双向链表,有序;key value容许为空 ;key被覆盖 value可重复 ; 非线程安全
HashMap 操作数据结构 +LinkedList 维护插入元素顺序
K key;
V value;
Entry<K, V> next;//HashMap指定table位置上(链表)连接的Entry
int hash;
Entry<K, V> before;
NEtry<K, V> after;
//链表的头结点 入口节点不存数据
private transient Entry<K,V> header;
//该属性指取得键值对的方式,是个布尔值,false表示插入顺序 默认,true表示访问顺序,也就是访问次数.
private final boolean accessOrder;
accessOrder=false,put 新元素加入哈希桶 加入双向链表末尾
accessOrder=true,put新元素 哈希冲突 key同替换 双向链表尾部 超过上限removeEldestEntry返true 删除最早元素 方便新元素插入,无冲突放入 加入双向链表尾部,get到的元素添加双向链表尾部
LRU:最久未访问header指向的元素,继承linkedhashmap重写removeEldestEntry设置缓存大小
Java基础汇总(十六)——LinkedHashMap-****博客
LinkedHashMap的底层原理_linkedhashmap底层-****博客
树
红黑树
平衡二叉查找树,节点非红即黑,根节点/叶子节点黑色
红色节点必须有两个黑色子节点,任一节点到叶子节点含相同数目的黑色节点
安全验证 - 知乎
事务原理 aop 动态代理
mybatis 读取mybatis.xml配置文件 configuration
映射关系:mapper.class 代理工厂
enviroment 数据库环境 datasource /事务工厂JdbcTransaction ManagedTransaction/连接池
其他信息:xml配置文件的其他信息
当用户以目标对象类型从IOC获取Bean对象时, 得到的是代理对象; 当调用目标对象的方法时, 被增强器TransactionInterceptor所拦截, 并进入invoke方法
虚拟内存:
内存页struct page 4k,调度以页为单位进行,mem_map管理,虚拟内存 struct mm_struct 物理内存映射,pgd属性中(物理)页的起始地址(fork进程时创建自己独立页表mm_struct)
每个进程的虚拟内存空间相互隔离,有属于自己的页表,管理虚拟内存空间映射关系 访问物理内存的权限
PTE 保存了进程虚拟内存空间中的虚拟页与物理内存页的映射关系,以及控制物理内存访问的相关权限位,内核先从虚拟内存地址中提取出 页表内偏移
,根 页表起始地址 + 页表内偏移 * sizeof(PTE)
获取到该虚拟内存地址所在虚拟页在页表中对应的 PTE 了
一步一图带你构建 Linux 页表体系 —— 详解虚拟内存如何与物理内存进行映射_虚拟内存 页表 物理内存-****博客