11 2023 档案

摘要:在spring体系中,配置的概念非常重要,无论是spring xml配置,还是springboot中yml/properties配置,以及spring cloud体系中的配置中心,都脱离不了spring 的配置框架,区别是配置的存储格式不同,存储位置不一样。不熟悉spring配置体系的可以参考:ht 阅读全文
posted @ 2023-11-23 11:27 mingshan 阅读(886) 评论(0) 推荐(0) 编辑
摘要:编译spring源码是学习spring的第一步,spring源码是用gradle编译的,在编译时会遇到一些问题,在此记录一下。 下载spring源码 第一步需要下载spring的源码,由于官方托管在github,国内访问github不通畅,这里就直接使用gitee的镜像仓库,在国内比较快,地址:ht 阅读全文
posted @ 2023-11-10 14:15 mingshan 阅读(140) 评论(0) 推荐(0) 编辑
摘要:用Markdown写博客的时候,有时需要用到Latex来写数学公式,通过使用MathJax,我们可以让Markdown解析Latex数学表达式,同时Next主题也支持MathJax,所以了解一下Latex语法是十分有必要的。 基础语法 公式标记 MathJax支持行内公式(inline)和陈列公式( 阅读全文
posted @ 2023-11-09 12:29 mingshan 阅读(628) 评论(0) 推荐(0) 编辑
摘要:输出GC日志 通过阅读GC日志,我们可以了解Java虚拟机内存分配与回收策略。 先来看一个简单的示例。 下面是GC日志: 0.115: [GC (System.gc()) [PSYoungGen: 3020K->600K(38400K)] 3020K->608K(125952K), 0.001229 阅读全文
posted @ 2023-11-08 11:54 mingshan 阅读(33) 评论(0) 推荐(0) 编辑
摘要:死锁在系统中可能出现的频率比较高,特别是在生产环境中,对于死锁发生原因的定位比较困难,读懂死锁日志是非常有必要的。下面我们来模拟死锁的产生,然后分析死锁日志。 死锁概念 对于死锁,MySQL官方文档是这样描述的: A deadlock is a situation where different t 阅读全文
posted @ 2023-11-07 15:28 mingshan 阅读(1010) 评论(1) 推荐(0) 编辑
摘要:在InnoDB中,锁的类型有如下几种: Shared and Exclusive Locks(共享S或独占X锁) Intention Locks(意向锁) Record Locks(记录锁) Gap Locks(间隙锁) Next-Key Locks Insert Intention Locks(插 阅读全文
posted @ 2023-11-07 15:27 mingshan 阅读(88) 评论(0) 推荐(0) 编辑
摘要:在生产者消费者模型这篇文章中我们使用了ReentrantLock结合Condition实现生产者消费者模型,但我们对于ReentrantLock和Condition的工作原理并不了解,其内部的结构和源码级别实现就更加不了解了。比如在使用await方法的时候,为什么一定要用while判断条件,用if为 阅读全文
posted @ 2023-11-07 15:09 mingshan 阅读(19) 评论(0) 推荐(0) 编辑
摘要:记得去年学习Spring MVC的时候自己学着写了一个小小的框架,用了一个AppContext来表示应用上下文,每个请求都应该有各自独立的AppContext,里面可以存储一些数据,比如数据库连接Connection等,此时考虑数据库的事务问题,即在一个线程内,一个事务的多个操作拿到的是一个Conn 阅读全文
posted @ 2023-11-07 15:07 mingshan 阅读(17) 评论(0) 推荐(0) 编辑
摘要:栈介绍 栈是一种仅在表头进行插入和删除操作的线性表,并且属于后进先出(last-in,first-out,LIFO)原则,下面是栈的入栈和出栈的图示: 主要操作 栈主要有入栈和出栈操作,但要实现完整的栈操作,我们需要定义一些方法 push 入栈,将元素压入栈顶 pop 出栈,获取栈顶元素并将其从栈中 阅读全文
posted @ 2023-11-07 15:06 mingshan 阅读(17) 评论(0) 推荐(0) 编辑
摘要:在JDK9中,包含了一个叫Variable Handles的新功能,下面是该功能的描述: Define a standard means to invoke the equivalents of various java.util.concurrent.atomic and sun.misc.Uns 阅读全文
posted @ 2023-11-07 14:46 mingshan 阅读(63) 评论(0) 推荐(0) 编辑
摘要:在Java中,我们想在程序运行时调用其方法,可以用JDK提供的反射相关API来实现,代码如下: Class clazz = Demo.class; Method method = clazz.getMethod("studyHard", new Class[]{String.class}); Dem 阅读全文
posted @ 2023-11-07 14:45 mingshan 阅读(80) 评论(0) 推荐(0) 编辑
摘要:最近看JDK11的CompletableFuture源码实现时,发现内部使用了Treiber stack,维基百科上作以下描述: The Treiber stack algorithm is a scalable lock-free stack utilizing the fine-grained 阅读全文
posted @ 2023-11-07 14:44 mingshan 阅读(93) 评论(0) 推荐(0) 编辑
摘要:在前面的文章中总结了二叉树的一些操作,提供了二叉树前中后的递归和非递归的实现。在非递归的实现中,基本思想是利用栈来模拟递归调用遍历的过程,本质上和递归实现没有区别,空间复杂度为O(n)。是否存在一种算法,它不使用栈也不破坏二叉树结构,但是可以完成对二叉树的遍历?即: 空间复杂度为\(O(1) 阅读全文
posted @ 2023-11-07 14:42 mingshan 阅读(54) 评论(0) 推荐(0) 编辑
摘要:反射是Java语言中一个比较重要的特性,它允许对正在运行的Java进行观测,甚至动态修改程序,即在运行态,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。 反射API介绍 获取Class对象 通常来说,使用反射API的第一步是获取Class对象,在J 阅读全文
posted @ 2023-11-07 14:38 mingshan 阅读(46) 评论(0) 推荐(0) 编辑
摘要:链表作为一种数据结构我们是比较熟知的,相对数组来说插入和删除操作性能比较高,因为数组涉及到移位操作,但数组可以利用二分法进行快速查找,而在链表中想要获取当前元素,就必须知道该元素的上一个节点(头节点除外),这就限制了链表在查找操作的性能,试想有没有一种数据结构,在链表基础上也能实现类似二分查找这样较 阅读全文
posted @ 2023-11-07 14:34 mingshan 阅读(42) 评论(0) 推荐(0) 编辑
摘要:ReentrantLock源码学习 - 释放锁(unlock) 上次谈到了利用ReentrantLock的非公平和公平加锁方式,那么接下来看看释放锁的流程 首先调用ReentrantLock的unlock方法 public void unlock() { sync.release(1); } 然后会 阅读全文
posted @ 2023-11-07 14:31 mingshan 阅读(17) 评论(0) 推荐(0) 编辑
摘要:ReentrantLock 学习 - 获取锁(JDK 1.8) ReentrantLock 提供非公平锁与公平锁两种加锁方式, 默认加锁方式为非公平锁。 ReentrantLock类的结构为: 从图中可以看出,ReentrantLock类包含三个静态内部类: Sync NonfairSync Fai 阅读全文
posted @ 2023-11-07 14:31 mingshan 阅读(26) 评论(0) 推荐(0) 编辑
摘要:生产者消费者问题是一个常见而且经典的问题,相信了解过多线程或者消息队列的同学对这个名词并不陌生。正如Java常用的设计模式一样,生产者消费者问题是为了解决某一类问题而存在,参阅维基百科对Producer–consumer problem的描述: In computing, the producer– 阅读全文
posted @ 2023-11-07 14:29 mingshan 阅读(53) 评论(0) 推荐(2) 编辑
摘要:前面我们总结了Java虚拟机的监控及诊断工具(命令行)相关命令的使用,用命令行虽然说比较方便,但不够直观,要是有图形显示JVM运行的一些情况就好了。eclipse MAT 和 Java Mission Control 是两个使用比较广泛的GUI虚拟机的监控及诊断工具,下面让我们来用用吧。 Eclip 阅读全文
posted @ 2023-11-07 08:53 mingshan 阅读(69) 评论(0) 推荐(0) 编辑
摘要:对于普通的开发人员来说,可以阅读帮助文档或者源码来对JDK的设计以及JVM的内存管理获取一定的了解,但对于线上运行的程序,如何对程序进行监控和诊断呢?比如一个程序挂了,怎么通过分析堆栈信息、GC日志、线程快照等信息来快速定位问题?JDK的大佬早就为我们考虑到这一点,所以在JDK中包含了许多用于监控及 阅读全文
posted @ 2023-11-07 08:52 mingshan 阅读(133) 评论(0) 推荐(0) 编辑
摘要:Channel介绍 Channel? 我们在使用Buffer的时候,需要往Buffer中放数据,再从Buffer中取数据,那么在NIO体系中,与Buffer交互是什么呢,没错,就是Channel。所有的NIO的I/O操作都是从Channel 开始的,读操作的时候将Channel中的数据填充到Buff 阅读全文
posted @ 2023-11-06 08:48 mingshan 阅读(18) 评论(0) 推荐(0) 编辑
摘要:Selector是Java NIO中实现多路复用的关键,用于检查一个或多个NIO Channel 的状态是否处于可连接、可接收、可读、可写状态。单个单线程通过Selector来管理多个Channel,减少线程上下文切花能带来的开销。 Selector是一个抽象类,具体是通过SelectorProvi 阅读全文
posted @ 2023-11-06 08:47 mingshan 阅读(14) 评论(0) 推荐(0) 编辑
摘要:Buffer?我们很容易想到缓冲区的概念,在NIO中,它是直接和Channel打交道的缓冲区,通常场景或是从Buffer写入Channel,或是从Channel读入Buffer。Buffer是一个抽象类,Java提供如下图的实现类,我是直接在Eclipse截出来的_ 其实核心是ByteBuffer, 阅读全文
posted @ 2023-11-06 08:46 mingshan 阅读(19) 评论(0) 推荐(0) 编辑
摘要:链式队列介绍 链式队列拥有队列的特性,只不过和顺序队列的区别是,顺序队列底层用的是数组存储元素,而链式队列用的是链表结构存储数据,也就是把一个元素和指向下个结点的指针封装成一个结点,这里称为Node,当队列为空,头指针与尾指针均指向头结点,只不过头结点为空结点,下面是链式队列的结构图 一个结点抽象成 阅读全文
posted @ 2023-11-06 08:45 mingshan 阅读(35) 评论(0) 推荐(0) 编辑
摘要:LeetCode有两道合并数据相关的题,分别是: 21.合并两个有序链表 88.合并两个有序数组 617.合并二叉树 这些题数据结构不同,但是算法的目标大致一致,即将给定的两个相同的数据结构,合并为一个数据结构。其中会用到递归等思想,下面先从最简单的合并两个有序数组开始分析吧。 88.合并两个有序数 阅读全文
posted @ 2023-11-06 08:43 mingshan 阅读(12) 评论(0) 推荐(0) 编辑
摘要:LeetCode一道对链表排序的题:148.排序链表,原题如下: 你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 进阶: 你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗? 我们直接整进阶的。 题目分析 如果做这个题之前知道归并排序和合并两个 阅读全文
posted @ 2023-11-06 08:42 mingshan 阅读(9) 评论(0) 推荐(0) 编辑
摘要:最近碰到几道关于i++与++i相关的题,我们从字节码角度来分析执行情况,该文章需要读者有字节码相关基础及了解方法调用机制。 分析 下面是一个题,请问下面代码输出什么? public static void f() { int i = 1; System.out.println(i++ + i++); 阅读全文
posted @ 2023-11-03 09:09 mingshan 阅读(8) 评论(0) 推荐(0) 编辑
摘要:图(Graph)这个数据结构在平时开发中遇到的比较少,但我认为它是十分重要的,因为从真实的世界中来看,很多东西都可以抽象为图的表示,比如人际关系,地理位置,天马行空的东西都可以抽象为图,所以它比链表等基础数据结构高级一点点,也比较复杂,属于非线性结构。数学中有一个图论的分支也是与其有关。了解图在程序 阅读全文
posted @ 2023-11-03 09:07 mingshan 阅读(64) 评论(0) 推荐(0) 编辑
摘要:平时接触动态代理比较多,例如Spring等框架如何使用了动态代理经常听到,本文主要介绍JDK动态代理的基本实现原理(JDK8版本),当了解了这些实现细节后,再次使用动态代理就会十分容易和清楚,知其然也知其所以然。 动态代理Demo 先来看一下利用JDK动态代理写的Demo,下面会根据这个Demo进行 阅读全文
posted @ 2023-11-02 10:22 mingshan 阅读(371) 评论(0) 推荐(0) 编辑
摘要:javap命令可以用来查阅字节码文件,可以将指定的字节码文件反编译,反解析出当前类对应基本信息、常量池(Constant pool)、字段区域、 方法区(Code[JVM指令集])、异常表(Exception table)、本地变量表(LocalVariableTable)、行数表(LineNumb 阅读全文
posted @ 2023-11-02 10:21 mingshan 阅读(117) 评论(0) 推荐(0) 编辑
摘要:哈希表(Hash Table,也叫散列表),是存储键值对(key-value)的数据结构,主要利用hash算法将key映射到表中,以便加快查找速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。对于数组而言,查找数据容易,但添加删除数据比较慢;对于链表来说,添加删除数据容易,但查找数据比较慢, 阅读全文
posted @ 2023-11-02 10:20 mingshan 阅读(3) 评论(0) 推荐(0) 编辑
摘要:Java虚拟机定义了程序执行期间使用的各种运行时数据区域。如下图所示: 在Java虚拟机规范的描述中,虚拟机栈、本地方法栈和程序计数器是线程私有的,而像堆、方法区(Jdk8之前)、元空间(JDK8之后)属于所有线程共享区域。除了程序计数器外,虚拟机内存的其他几个运行时区域都有可能发生OutOfMem 阅读全文
posted @ 2023-11-02 10:19 mingshan 阅读(38) 评论(0) 推荐(0) 编辑
摘要:堆这个数据结构在我大学的教材上没有讲解,但平时听说过堆排序什么的,无疑是要用到这个数据结构,所以本篇文章主要是总结下堆的概念和实现。 堆概念 在维基百科中,是这样定义堆的: 堆(英语:Heap)是计算机科学中的一种特别的树状数据结构。若是满足以下特性,即可称为堆:“给定堆中任意节点 P 和 C,若 阅读全文
posted @ 2023-11-02 10:14 mingshan 阅读(858) 评论(0) 推荐(0) 编辑
摘要:在看Class文件的结构时,我们会遇到这样几个概念,全限定名(Fully Qualified Name)、简单名称(Simple Name)和描述符(Descriptor),那么这些是什么东东呢? 首先来说全限定名,一个类的全限定名是将类全名的.全部替换为/,示例如下: me/mingshan/cg 阅读全文
posted @ 2023-11-02 10:13 mingshan 阅读(143) 评论(0) 推荐(0) 编辑
摘要:双向链表描述 双向链表也叫双链表,它的每个数据结点都有两个指针,分别指向前驱结点和后继节点,同时有一个数据域来保存数据,双向链表的图示如下: 从图片可以看出,双链表的头结点的前驱结点和尾结点的后继结点为空,这一点要注意,对双链表的操作要检查这两种情况。 双向链表结构 每个数据结点都有两个指针,分别指 阅读全文
posted @ 2023-11-02 10:11 mingshan 阅读(28) 评论(0) 推荐(0) 编辑
摘要:在维基百科中,关于分治算法(divide-and-conquer)的介绍如下:在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个概念 阅读全文
posted @ 2023-11-02 10:09 mingshan 阅读(55) 评论(0) 推荐(0) 编辑
摘要:这里有n个房子在一列直线上,现在我们需要给房屋染色,共有k种颜色。每个房屋染不同的颜色费用也不同,你希望每两个相邻的房屋颜色不同 费用通过一个nxk 的矩阵给出,比如cost[0][0]表示房屋0染颜色0的费用,cost[1][2]表示房屋1染颜色2的费用。 样例: 输入: costs = [[14 阅读全文
posted @ 2023-11-02 10:08 mingshan 阅读(52) 评论(0) 推荐(0) 编辑
摘要:一条包含字母A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -> 26 要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"111" 可以将 "1" 中的每个 "1" 映射为 "A" ,从而得到 "AAA" 阅读全文
posted @ 2023-11-02 10:07 mingshan 阅读(27) 评论(0) 推荐(0) 编辑
摘要:先来看一下这道题简化的描述: 现有2元,5元,7元三种硬币,假设硬币都足够多,现求解:最少用多少枚上述硬币拼出27块钱? 递归解法 看到这个问题,我们一下子就可以想到一个树形结构,27块钱可以分别减去上面三种硬币的面额,剩下的值可以继续减去上面三种硬币的面额,直至无法再减,计算出刚好能减完的路线(从 阅读全文
posted @ 2023-11-02 10:07 mingshan 阅读(71) 评论(0) 推荐(0) 编辑
摘要:前几天生产环境出现了一个问题,gc日志里面某一个时间段出现了大量的Full GC,而且都是回收元空间内存失败了,最终导致了JVM停止运行,微服务中的某个服务发生了宕机。下面记录下排查该问题的过程。 首先我们根据服务器的CPU核心数和内存大小,设置了元空间的最大值为512M,这是前提。在服务GC日志中 阅读全文
posted @ 2023-11-01 15:10 mingshan 阅读(133) 评论(0) 推荐(0) 编辑
摘要:相信很多小伙伴自己都会有一些包,我们可以将包发布中央仓库,然后直接通过maven来使用这些包,下面就整理下如何将包发到中央仓库。 新建项目 第一步,我们需要在sonatype上注册一个账号,这一步就不再演示了。 注册好账户之后,然后我们来创建项目。点击新建按钮,问题类型 选择 New Project 阅读全文
posted @ 2023-11-01 15:07 mingshan 阅读(49) 评论(0) 推荐(0) 编辑
摘要:经过对JDK动态代理实现原理的解析,我们会对动态代理的实现流程有个根本的认识,具体分析过程参考JDK动态代理实现原理这篇文章,这里就不多谈了。这篇文章主要思考如何去实现一个简易的动态代理,以便加深对其的理解。 模仿着JDK动态代理,我们需要一个代理Proxy类,一个InvocationHandler 阅读全文
posted @ 2023-11-01 15:05 mingshan 阅读(32) 评论(0) 推荐(0) 编辑
摘要:了解到CompletableFuture的基础用法之后,我们不禁好奇,以前的Future模式不支持如此好用的异步编程,CompletableFuture是如何做到的呢?这就需要我们去阅读源码了,通过源码我们才能了解到其设计思想和实现方式,我们分析下supplyAsync 和 thenApplyAsy 阅读全文
posted @ 2023-11-01 15:03 mingshan 阅读(27) 评论(0) 推荐(0) 编辑
摘要:ArrayQueue假溢出 我们在利用数组实现队列的时候,发现数组队列会出现假溢出问题,即队列还没有满,但不能再往队列中放入元素了,如下图所示: 在数据进行出队的时候,每一个元素出队,指向队列头元素的head就会向后移动,导致head之前的元素被“遗忘”了,无法再次利用,出队的代码如下: @Over 阅读全文
posted @ 2023-11-01 15:03 mingshan 阅读(20) 评论(0) 推荐(0) 编辑
摘要:在JDK 1.5之后Java提供了并发包(java.util.concurrent),加强对并发的支持。该包下的类大量使用 CAS(Compare and Swap)来实现原子操作、锁优化等。在java.util.concurrent.atomic包中,提供了对基本类型的原子封装,比如AtomicI 阅读全文
posted @ 2023-11-01 15:02 mingshan 阅读(10) 评论(0) 推荐(0) 编辑
摘要:Callable 在Java中我们知道创建一个线程可以继承Thread类或者实现Runnable接口,JDK1.5之后在java.util.concurrent提供了Callable接口,该接口设计类似Runnable接口,不过Callable接口可以返回任务执行的结果,并且在执行任务过程中可能会抛 阅读全文
posted @ 2023-11-01 15:00 mingshan 阅读(55) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示