- 博客(274)
- 资源 (8)
- 收藏
- 关注
原创 MyBatis 源码分析 - 缓存原理
在 MyBatis 中,Cache 是缓存接口,定义了一些基本的缓存操作,所有缓存类都应该实现该接口。MyBatis 内部提供了丰富的缓存实现类,比如具有基本缓存功能的 PerpetualCache,具有 LRU 策略的缓存 LruCache,以及可保证线程安全的缓存 SynchronizedCache 和具备阻塞功能的缓存 BlockingCache 等。除此之外,还有很多缓存实现类,这里就不一一列举了。需要特别说明的是,MyBatis 在实现缓存模块的过程中,使用了装饰模式。
2024-04-18 10:20:18 582
原创 MyBatis 源码分析 - 内置数据源
PooledDataSource 需要借助两个辅助类帮其完成功能,这两个辅助类分别是 PoolState 和 PooledConnection。PoolState 用于记录连接池运行时的状态,比如连接获取次数,无效连接数量等。同时 PoolState 内部定义了两个 PooledConnection 集合,用于存储空闲连接和活跃连接。PooledConnection 内部定义了一个 Connection 类型的变量,用于指向真实的数据库连接。
2024-04-18 10:19:29 211
原创 MyBatis 源码分析 - SQL 的执行过程
在前面的文章中,我分析了配置文件和映射文件的解析过程。经过前面复杂的解析过程后,现在,MyBatis 已经进入了就绪状态,等待使用者发号施令。本篇文章我将分析MyBatis 执行 SQL 的过程,该过程比较复杂,涉及的技术点很多。为 mapper 接口生成实现类根据配置信息生成 SQL,并将运行时参数设置到 SQL 中一二级缓存的实现插件机制数据库连接的获取与管理查询结果的处理,以及延迟加载等如果大家能掌握上面的技术点,那么对 MyBatis 的原理将会有很深入的理解。
2024-04-17 17:33:03 587
原创 MyBatis 源码分析 - 映射文件解析过程
在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程。由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因。所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来,独立成文,于是就有了本篇文章。在本篇文章中,我将分析映射文件中出现的一些及节点,比如 ,,, 等。除了分析常规的 XML 解析过程外,我还会向大家介绍 Mapper 接口的绑定过程等。
2024-04-17 17:29:21 578
原创 MyBatis 源码分析 - 配置文件解析过程
在上一篇文章中,我介绍了 MyBatis 的一些基础知识,用于为本文及后续的源码分析文章进行铺垫。经过前面的铺垫,我觉得是时候后分析一下 MyBatis 源码了。在本篇文章中,我将从 MyBatis 解析配置文件的过程着手进行分析。并会在分析的过程中,向大家介绍一些配置的使用方式和用途。MyBatis 的配置比较丰富,很难在一篇文章中把所有配置的解析过程分析完。所以关于配置文件的解析,这里会分两篇文章进行讲解。本篇文章将会分析诸如settings以及等标签的解析过程。
2024-04-15 10:09:32 1148 1
原创 MyBatis 源码分析系列文章导读
MyBatis 的前身是 iBatis,其是 Apache 软件基金会下的一个开源项目。2010年该项目从 Apache 基金会迁出,并改名为 MyBatis。同期,iBatis 停止维护。MyBatis 是一种半自动化的 Java 持久层框架(persistence framework),其通过注解或 XML 的方式将对象和 SQL 关联起来。
2024-04-15 10:06:39 1030
原创 简述Kafka的高可靠性
Kafka通过ACK应答机制保证了不同组件之间的通信效率,通过副本同步机制、数据截断和数据清理机制实现了对于数据的管理策略,保证整个系统运行效率。作为一款高性能又同时兼顾高可靠性的消息中间件来说,Kafka能吹的点实在太多。如果本篇文章对你有所帮助,点击一下右下角的大拇指,下一次我们来详细讲解Kafka是如何实现副本间数据传递的。作者:鼓楼丶链接:https://juejin.cn/post/7103335924079001636来源:稀土掘金著作权归作者所有。
2024-04-12 18:00:53 391
原创 Redis 与 MySQL 数据一致性问题
缓存中存有数据,缓存的数据值 = 数据库中的值;缓存中没有该数据,数据库中的值 = 最新值。缓存的数据值 ≠ 数据库中的值;缓存或者数据库存在旧的数据,导致线程读取到旧数据。❝为何会出现数据一致性问题呢?把 Redis 作为缓存的时候,当数据发生改变我们需要双写来保证缓存与数据库的数据一致。数据库跟缓存,毕竟是两套系统,如果要保证强一致性,势必要引入2PC或Paxos等分布式一致性协议,或者分布式锁等等,这个在实现上是有难度的,而且一定会对性能有影响。
2024-04-12 17:59:54 769
原创 Java 8 内存管理原理解析及内存故障排查实践
G1也是采用三色标记分段式进行回收的算法, 不过它是写屏障 + STAB快照实现,G1设定的目标是在延迟可控(低暂停)的情况下获得尽可能高的吞吐量,仍然可以通过并发的方式让Java 程序继续运行,G1垃圾收集器在很多方面弥补了CMS的不足,比如CMS使用的是mark-sweep标记清除算法,自然会产生内存碎片(CMS只能在Full GC时,STW 整理内存碎片),然而G1整体来看是基于标记整理算法实现的收集器,但是从局部来看也是基于复制算法实现的,高效的整理剩余内存,而不需要管理内存碎片它。
2024-04-11 19:21:50 1654
原创 Redis Pipelining 底层原理分析及实践
在数据量比较小的时候没有出现问题,直到有一条收到了Redis的内存和cpu利用率的告警消息,我们发现这么使用是有问题的,核心原因在于list的lrem操作的时间复杂度是O(N+M),其中N是list的长度, M是要移除的元素的个数,而我们这里还是一个一个移除的,当然会导致Redis数据积压和cpu每秒ops升高导致cpu利用率飚高。对于服务端来说,所需要的是能够处理一个客户端通过同一个TCP连接发来的多个命令,可以理解为,这里将多个命令切分,和处理单个命令一样,Redis就是这样处理的。
2024-04-11 19:15:33 911
原创 这些年背过的面试题——JVM篇
我使用 jmap 命令,导出了一份线上堆栈,然后使用 MAT 进行分析,通过对 GC Roots 的分析,发现了一个非常大的 HashMap 对象,这个原本是其他同事做缓存用的,但是做了一个无界缓存,没有设置超时时间或者 LRU 策略,在使用上又没有重写key类对象的hashcode和equals方法,对象无法取出也直接造成了堆内存占用一直上升,后来,将这个缓存改成 guava 的 Cache,并设置了弱引用,故障就消失了。第三,由于缓存的使用,有大量的弱引用,拿一次长达 10 秒的 GC 来说。
2024-04-09 17:07:05 1134
原创 Java对象头压缩---- 永久为Java应用“降本增效”
本文介绍了一下OpenJDK的最新技术,对象头压缩,来大幅优化Java对象的内存占用。前言Java丰富的生态和语言强大的内存管理技术(GC),使得Java应用的开发非常便捷,各类应用场景的适配都非常优秀,大大减少了从Idea到应用落地的难度。不过这一切也不是没有代价的,针对于Java应用内存占用比较高的问题一直拿出来和其他语言比较。虽然JVM已经自带了例如指针压缩(compressed oops)来节约内存开销,不过Java Object对象头本身占用的内存还是非常可观。
2024-04-09 17:06:49 649
原创 Java 8 内存管理原理解析及内存故障排查实践
G1也是采用三色标记分段式进行回收的算法, 不过它是写屏障 + STAB快照实现,G1设定的目标是在延迟可控(低暂停)的情况下获得尽可能高的吞吐量,仍然可以通过并发的方式让Java 程序继续运行,G1垃圾收集器在很多方面弥补了CMS的不足,比如CMS使用的是mark-sweep标记清除算法,自然会产生内存碎片(CMS只能在Full GC时,STW 整理内存碎片),然而G1整体来看是基于标记整理算法实现的收集器,但是从局部来看也是基于复制算法实现的,高效的整理剩余内存,而不需要管理内存碎片它。
2024-04-08 13:46:35 1039
原创 Jackson 工具类使用及配置指南
Json数据格式这两年发展的很快,其声称相对XML格式有很对好处:容易阅读;解析速度快;占用空间更少。不过,JSON 和 XML两者纠结谁优谁劣,这里不做讨论,可以参见知乎上为什么XML这么笨重的数据结构仍在广泛应用?最近在项目中,会有各种解析JSON文本的需求,使用第三方Jackson工具来解析时,又担心当增加会减少字段,会不会出现非预期的情况,因此,研究下jackson解析json数据格式的代码,很有需要。
2024-04-08 13:46:14 1003
原创 网站统计中的数据收集原理及实现
网站数据统计分析工具是网站站长和运营人员经常使用的一种工具,比较常用的有谷歌分析、百度统计和腾讯分析等等。所有这些统计分析工具的第一步都是网站访问数据的收集。目前主流的数据收集方式基本都是基于javascript的。本文将简要分析这种数据收集的原理,并一步一步实际搭建一个实际的数据收集系统。
2024-04-06 21:12:22 766
原创 浅谈偏向锁、轻量级锁、重量级锁
为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。理解偏向锁、轻量级锁、重量级锁的要解决的基本问题,几种锁的分配和膨胀过程,有助于编写并优化基于锁的并发程序。内置锁的分配和膨胀过程较为复杂,限于时间和精力,文中该部分内容是根据网上的多方资料整合而来;仅为方便查阅,后面继续分析JVM源码的时候也有个参考。如果对各级锁已经有了基本了解,读者大可跳过此文。
2024-04-05 21:15:13 868
原创 一个故事告诉你比特币的原理及运作机制
周末花时间看了一些比特币原理相关的资料,虽然不敢说把每个细节都完全搞懂了,不过整体思路和关键部分的主要原理还是比较明白。写一篇文章分享给大家。这篇文章的定位会比较科普,尽量用类比的方法将比特币的基本原理讲出来。这篇文章不会涉及算法和协议中比较细节的部分,打算后面会再写一篇程序员视角下的比特币原理,那里会从技术人员的视角对比特币系统中较为关键的数据结构、算法和协议进行一些讲解。
2024-04-05 21:14:44 1015
原创 浅谈TCP(2):流量控制与拥塞控制
上文浅谈TCP(1):状态机与重传机制介绍了TCP的状态机与重传机制。本文介绍流量控制(Flow Control,简称流控)与拥塞控制TCP依此保障网络的QOS。
2024-04-04 11:27:26 905
原创 “光”速?HakariCP为什么这么快?
这次源码探究,真的感觉看到了无数个小细节,无数个小优化,积少成多。平时开发过程中,一些小的细节也一定要“扣”。“光”速?HakariCP为什么这么快?
2024-04-04 11:26:26 1024
原创 Linux文件系统目录结构
本文以CentOS系统为例,但同样适用于Linux的其他发行版。不需要纠结于具体的版本,即可。本文随时更新。除勘误外,不另做批注。
2024-04-03 18:27:32 590
原创 Java高并发综合
这篇文章是研一刚入学时写的,今天整理草稿时才被我挖出来。当时混混沌沌的面试,记下来了一些并发的面试问题,很多还没有回答。到现在也学习了不少并发的知识,回过头来看这些问题和当时整理的答案,漏洞百出又十分可笑。发表出来权当对自己的一个提醒——如果不能一直进步,你就看不到当初傻逼的自己。曾经,我在面试Java研发实习生时最常听到的一句话就是:搞Java怎么能不学并发呢?没错,真的是经过了面试官的无数鄙视,我才知道Java并发编程在Java语言中的重要性。
2024-04-03 18:27:15 868
原创 源码|并发一枝花之CopyOnWriteArrayList
CopyOnWriteArrayList的设计思想非常简单,但在设计层面有一些小问题需要注意。JDK版本:oracle java 1.8.0_102本来不想写的,但是github上CopyOnWriteArrayList的code results也有165k,为了流量还是写一写吧。
2024-04-02 09:38:26 545
原创 源码|并发一枝花之ConcurrentLinkedQueue
现在基于假设1和假设2,尝试定义入队模型的状态机。存在2个生产者P1、P2,同时触发入队操作。
2024-04-02 09:38:05 971
原创 源码|从串行线程封闭到对象池、线程池
相对于线程封闭,串行线程封闭离用户的距离更近一些,简单灵活,实用性强,很容易掌握。而线程封闭更多沦为单纯的设计策略,单纯使用线程封闭的场景不多。线程池与串行线程封闭、对象池的关系不大,但经常被混为一谈;没看过源码的很难想到其实现方案,面试时也能立分高下。线程池的实现很有意思。在追源码之前,猴子一直以为线程池就是把线程存起来,用的时候取出来执行任务;看了源码才知道实现如此之妙,简洁优雅效率高。源码才是最好的老师。原文地址:源码|从串行线程封闭到对象池、线程池。
2024-04-01 10:32:11 796
原创 MySQL索引背后的数据结构及算法原理
本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论。文章主要内容分为三个部分。第一部分主要从数据结构及算法理论层面讨论MySQL数据库索引的数理基础。
2024-04-01 10:31:52 1650
原创 线程池ThreadPoolExecutor总结
keepAliveTime,unit:如果线程池中的线程数大于corePoolSize小于等于maximumPoolSize,则选择闲置时间超过keepAliveTime(单位为unit)的线程销毁,直到无线程可销毁或线程数等于corePoolSize。相对的,CachedThreadPool被设计为一种maximumPoolSize无效的缓冲池,同时,因此,必须使用无界的同步队列,让“入队”直接变成“执行”。个线程的线程池,限制线程可缓存60s,超时销毁;
2024-03-31 17:11:45 756
原创 源码|ThreadLocal的实现原理
ThreadLocal也叫“线程本地变量”、“线程局部变量”:其作用域覆盖线程,而不是某个具体任务;其“自然”的生命周期与线程的生命周期“相同”(但在JDK实现中比线程的生命周期更短,减少了内存泄漏的可能)。ThreadLocal代表了一种的思想,从而达到线程封闭的目的,帮助我们设计出更“健康”(简单,美观,易维护)的线程安全类。JDK版本:oracle java 1.8.0_102。
2024-03-31 17:11:17 960
原创 AQS的基本原理
state表示状态,其他状态需要自行维护直接使用不带try前缀的方法,并覆写带try前缀的方法对于带try前缀的方法,约定通过返回值告知调用者(一般是AQS)获取或释放操作的结果本文虽短,且非常重要,是后文分析ReentrantLock等的基础。同时,又是一个高效并发的经典设计案例。AQS的基本原理。
2024-03-30 16:38:14 698
原创 Spring Boot HandlerMethodArgumentResolver 使用和场景
为了将 HTTP 请求参数转换为 Java 对象,我们需要创建一个自定义的实现类。在这个类中,我们需要实现方法和方法。要在 Spring Boot 应用程序中使用自定义的实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个类,并实现接口。在这个类中,我们需要重写方法,并将自定义的实现类添加到参数解析器列表中。@Override要在 Spring Boot 应用程序中使用自定义的实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个类,并实现接口。在这个类中,我们需要重写。
2024-03-30 16:37:34 980
原创 Java中如何恰当的表达“继承”与“扩展”的语义?
到这里,希望你能明白扩展与继承的区别。现在回答题目的问题,Java中如何恰当的表达“继承”与“扩展”的语义?仅表达继承用B类继承或C类继承仅表达扩展用A类继承或简化的D类继承(不继承接口)同时表达继承和扩展用D类继承PS:要真正理解extends、implements与继承的关系。extends从一个类扩展出另一个类,implements从一个接口实现一个类或抽象类,它们作为Java中的关键字,语义本身是正确的;只是与面向对象中的继承无法一一对应。
2024-03-29 09:57:02 605
原创 volatile关键字的作用、原理
综上,其实volatile保持内存可见性和防止指令重排序的原理,本质上是同一个问题,也都依靠内存屏障得到解决。更多内容请参见JVM相关书籍。volatile关键字的作用、原理。
2024-03-29 09:56:40 949
原创 算法分析中递推式的一般代数解法
算法分析中经常遇到需要求解递推式的情况,即将递推式改写为等价的封闭形式。例如汉诺塔问题的时间复杂度递推形式为,可以解出封闭形式为(设初始状态)。因为递推式求解的重要性,许多算法书籍对其有专门介绍。Donald Knuth在Concrete Mathematics一书中多个章节都涉及递推式求解方法。算法导论也在第四章中专门论述的这个主题。在这些相关论述中,主要介绍了一些启发式方法,这些方法往往需要一些特殊的技巧和灵感才能完成。
2024-03-28 09:34:21 518
原创 SAML2.0详解,助力企业级SSO
在国内,提到认证授权、单点登录(SSO),第一时间想到的大多是OAuth 2.0。OAuth 2.0 是一个开放标准,在国内的技术社区中得到了广泛的支持和推广,许多互联网公司以及开发者积极采用。还有一点就是国内的许多场景更关注于授权而非认证,OAuth 2.0 专注于授权机制,允许用户授权第三方应用程序访问其存储在另一个服务提供者上的资源,而无需共享用户名和密码,这种机制非常适合于社交媒体、移动应用、开放平台等场景。今天我想说的是一种不一样的声音,今日的主角并不是 OAuth 2.0,而是。
2024-03-28 09:34:09 263
原创 浅谈双亲委派模型
双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。每一个层次的类加载器都是如此。因此,所有的加载请求最终都应该传送到顶层的启动类加载器中。只有当父加载器反馈自己无法完成这个加载请求时(搜索范围中没有找到所需的类),子加载器才会尝试自己去加载。很多人对“双亲”一词很困惑。
2024-03-27 09:39:21 534
原创 String常量池和String#intern()
String是Java基础的重要考点。可问的点多,而且很多点可以横向切到其他考点,或纵向深入JVM。本文略过了String的基本内容,重点在于String#intern()。
2024-03-27 09:39:02 679
原创 数组还可以这样用!常用但不为人知的应用场景
数组在Java中是一种基本的数据结构,可以表示连续的内存空间。它可以用来存储一组相同数据类型的元素。Java中的数组可以是一维或多维的,而且数组的大小一旦确定就无法更改。本文将介绍数组的几种常用但不为人知的应用场景,包括二维数组的应用,数组的旋转、查找、去重等操作,以及在算法中使用数组等场景。并且将分析这些应用场景的优缺点,并提供相应的示例代码和测试用例。这表示创建一个3行4列的二维数组。这种方式可以直接初始化二维数组的每个元素。
2024-03-26 17:33:39 754
原创 聊聊 Java GC
在遍历GC Roots 对象树的时候,同时将标记到得对象复制到新生代小的S0/S1内存区域中,这样,当我们遍历完对象空间的时候,可以将整个新生代Eden区域内存分配的当前有效内存开始指针置为开始位置,这样,我们就操作完了对新生代对象的GC回收。从上文的对象定位可以看到,一般情况下,java对象都是在堆上分配,然后其引用指针保存在调用栈对应位置,然后在访问的时候,需要两次查找才能获取完所有的需要的对象信息,而在栈上分配对象内存的话,就避免了这个耗时。因此,在S1上,就存在不同分代年龄的对象了。
2024-03-26 17:33:21 2178
2018美团点评技术文章-后台篇
2019-01-25
java sigar获得服务器信息
2018-05-08
大型网站分布式技术架构书(集合)
2018-04-18
TCP-IP详解 卷一、二、三 非扫描
2018-04-17
Java TCPIP Socket编程 源码
2018-04-08
大话JAVA:从零基础到数据库、WEB开发.
2018-04-04
《Java加密与解密的艺术》源码
2018-04-04
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人