Langchain-Chatchat 部署本地知识库 使用 LangChain-Chatchat,基于在线 LLM 模型(智谱AI API)和离线 Embedding 模型(text2vec-base-chinese 或 bge-base-zh-v1.5)搭建本地知识库。
Lombok 原理与实现 本文主要包含以下内容:Lombok 的实现机制分析。插入式注解处理器的说明及使用。动手实现 lombok 的 @Getter 和 @Setter 注解。配置 IDEA 以调试 Java 编译过程。
阅读 MyBatis 源码:数据库连接池 PooledDataSource 在 MyBatis 中,使用 PooledDataSource 数据源作为连接池对象,在连接池中存储的是 PooledConnection 对象。通过动态代理,实现对原始连接对象的复用,以及多线程间使用数据库连接的隔离。
阅读 MyBatis 源码:插件开发 MyBatis 插件,简单理解为拦截器,它采用动态代理的方式,实现对目标方法的拦截,在前后做一些操作。本文通过分页查询插件的例子,了解 MyBatis 插件的实现原理。
阅读 MyBatis 源码:SQL 执行过程 通过 MyBatis 简单查询的例子,探究 MyBatis 执行 SQL 查询的代码流程,了解源码中 SqlSession、Executor、StatementHandler、ResultSetHandler、MappedStatement 等类的作用。
阅读 JDK 源码:线程池 ThreadPoolExecutor 上一篇文章介绍了 Thread 类,可知线程随着任务的执行结束而被销毁。但是,由于线程的创建与销毁操作涉及到系统调用,开销较大,因此需要将线程的生命周期与任务进行解耦。使用线程池来管理线程,可以有效地重复利用线程来执行任务。本文将介绍线程池最基础的实现类 ThreadPoolExecutor。本文基于 jdk1.8.0_91文章目录1. 线程池体系2. 构造方法2.1 源码分析2.2 使用说明2.2.1 Core and maximum pool sizes2.2.2 On-demand const
阅读 JDK 源码:线程类 Thread 在 Java 中,使用 Thread 类可以在操作系统层面创建线程,并绑定到对应的 Thread 类实例中。利用线程异步地执行任务,是并发编程的基础。本文通过阅读 Thread 源码,了解线程状态的定义,线程调度的相关方法,以及对线程中断的处理等。本文基于 jdk1.8.0_91
阅读 JDK 源码:异步任务 FutureTask 在 Java 中,Runnable 接口表示一个没有返回结果的任务,而 Callable 接口表示具有返回结果的任务。在并发编程中,异步执行任务,再获取任务结果,可以提高系统的吞吐量。Future 接口应运而生,它表示异步任务的执行结果,并提供了检查任务是否执行完、取消任务、获取任务执行结果等功能。FutureTask 是 Future 接口的基本实现,常与线程池实现类 ThreadPoolExecutor 配合使用。本文基于 jdk1.8.0_91文章目录1. 继承体系2. 属性2.
阅读 JDK 源码:读写锁 ReentrantReadWriteLock 在 JUC 包中,共享锁包括 CountDownLatch、CyclicBarrier、Semaphore 等。ReentrantReadWriteLock 是基于 AQS(AbstractQueuedSynchronizer)框架实现的锁工具,其中定义了两个锁:共享锁 readLock 和独占锁 writeLock。readLock 用于读操作,能同时被多个线程获取;writeLock 用于写入操作,只能被一个线程持有。读锁、写锁均具有公平模式、非公平模式两种获取锁的方式。
阅读 JDK 源码:可重入锁 ReentrantLock 前几篇文章介绍了 AQS(AbstractQueuedSynchronizer)中的独占模式和对 Condition 的实现,这一篇文章来聊聊基于 AQS 框架实现的锁工具:ReentrantLock。ReentrantLock 是一个可重入的互斥锁,也被称为独占锁。具有两种实现:公平锁(fair lock)、非公平锁(non-fair lock)。本文基于 jdk1.8.0_91
阅读 JDK 源码:AQS 对 Condition 的实现 前两篇文章分别介绍了 AQS 框架中的独占模式和共享模式,本篇将介绍 AQS 对 Condition 接口的实现。在阅读本篇之前,建议先了解 AQS 中的数据结构和独占模式的实现原理。JUC 通过 Lock 和 Condition 两个接口实现管程(Monitor),其中 Lock 用于解决互斥问题,而 Condition 用于解决同步问题,而 AQS 对 Lock 和 Condition 接口的实现提供了一个基础的框架。文章目录1. Condition 接口2. Condition 使用3. Con
阅读 JDK 源码:AQS 中的共享模式 AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。上一篇文章介绍了 AQS 的数据结构和独占模式的实现原理,本篇介绍 AQS 共享模式的源码实现。文章目录1. 共享模式1.1 获取锁-acquireShared1.1.1 tryAcquireShared1.1.2 doAcquireSharedsetHeadAndPropagatedoReleaseShared1.2 释放锁-releaseShared
阅读 JDK 源码:AQS 中的独占模式 AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。JUC 包下常见的锁工具如 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch 都是基于 AQS 实现的。文章目录1. AQS 框架1.1 继承体系1.2 模板方法2. 数据结构2.1 资源定义2.2 节点定义2.3 同步队列2.4 条件队列3. 独占模式3.1 获取锁-acquire3.1.1 tryAcquire3.1.2 add
阅读 JDK 源码:传递队列 LinkedTransferQueue LinkedTransferQueue 是一个由链表结构组成的无界阻塞 TransferQueue 队列。接口 TransferQueue 和实现类 LinkedTransferQueue 从 Java 7 开始加入 J.U.C 之中。文章目录1. 继承体系2. 数据结构2.1 节点定义2.2 head 和 tail 节点3. 构造函数4. 数据存取及传递4.1 xfer4.2 匹配过程图示4.3 tryAppend4.4 awaitMatch4.5 自旋次数4.6 unsplice5. 容量6. 总结
阅读 JDK 源码:松弛队列 ConcurrentLinkedQueue ConcurrentLinkedQueue 是一个由链表结构组成的无界非阻塞队列,是 JDK 中唯一一个并发安全的非阻塞队列。使用无锁算法来保证线程安全,为了减少 CAS 操作造成的资源争夺损耗,其链表结构被设计为“松弛”的,本文对 ConcurrentLinkedQueue 的入队和出队过程进行图解,直观展示其内部结构。文章目录1. 继承体系2. 数据结构2.1 链表节点2.2 head 和 tail 节点基本不变式head 的不变式和可变式tail 的不变式和可变式3. 构造函数4. 入队4.1 源码
阅读 JDK 源码:传递队列 SynchronousQueue SynchronousQueue 是一个由链表或栈结构组成的阻塞队列,适用于传递性场景,即生产者线程处理的数据直接传递给消费者线程。队列中不直接存储数据元素(队列容量固定为 0)。采用无锁算法,每个线程的存入或取出操作没有被匹配时,将会阻塞在队列中等待匹配,内部的链表或栈结构用于暂存阻塞的线程。当消费者消费速度赶不上生产速度,队列会阻塞严重。文章目录1. 继承体系2. 数据结构3. 构造函数4. 属性5. 容量6. 存入取出操作7. 栈实现栈定义节点定义transferawaitFulfill8. 队列
阅读 JDK 源码:WeakHashMap 和 Reference、ReferenceQueue WeakHashMap 是一种特殊的 HashMap,它的 key 为 WeakReference 弱引用,并且内置了一个 ReferenceQueue 用于存储被回收的弱引用。阅读 WeakHashMap 源码之前,需要先理解 Reference 和 ReferenceQueue 的机制。理解其基本原理之后,可以使用 HashMap 达到跟 WeakHashMap 一样的效果,文末提供了示例。1. Referencepublic abstract class Reference<T>ex