自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(291)
  • 资源 (6)
  • 收藏
  • 关注

原创 《Go程序设计语言》一书视频讲解(更新中...)

《Go程序设计语言》一书视频讲解,跟我一起学习Go程序设计语言。Go语言在2009年发布,Go是一种开源的程序设计语言,它意在使人们能够方便的构建简单、可靠、高效的软件。

2022-05-08 23:35:15 268

原创 Netty 入门实战之实现简易聊天系统

Netty 是什么?用官方文档来说,Netty 是一个高性能、异步事件驱动的网络应用框架。基于 Netty,可以快速地开发和部署高性能、高可用的网络服务端和客户端应用。简单来说,Netty 是一个封装了 Java NIO 的 Jar 包,是对 Socket 网络编程的封装。Netty 应用广泛,一些知名框架 Alibaba Dubbo、Apache Flink、Apache Spark、gRP...

2019-01-15 22:14:26 438

原创 Apache SkyWalking 监控 Linux 实战

SkyWalking 从 8.4 版本开始支持监控主机,用户可以轻松从 dashboard 上检测可能的问题,例如当 CPU 使用过载、内存或磁盘空间不足或者当网络状态不健康时等。与监控 MySQL Server 类似,SkyWalking 也是利用 Prometheus 和 OpenTelemetry 收集主机的 metrics 数据。

2024-03-12 22:46:20 1012

原创 Apache SkyWalking 监控 MySQL Server 实战

Apache SkyWalking 监控 MySQL Server 实战

2022-10-17 18:29:13 1592 1

原创 Apache SkyWalking Java Agent 08-增强实例方法

通过上一篇文章Apache SkyWalking Java Agent 06-插件定义体系我们了解到插件定义顶层类 AbstractClassEnhancePluginDefine 是一个抽象类,它提供了如何对目标类增强的模版方法,define 方法是增强目标类的主要入口,define 方法内部调用了两个抽象方法 enhanceInstance 和 enhanceClass 方法,分别用于增强实例方法(包括构造方法)、静态方法,由具体子类实现。

2022-09-22 17:17:53 633

原创 Apache SkyWalking Java Agent 07-Byte Buddy 操作字节码

通过之前文章的学习我们了解到SkyWalkingJavaAgent插件加载机制和插件体系。本篇文章我们继续分析SkyWalkingJavaAgent源码,先回到插件加载部分的代码。通过我们完成了插件定义类的加载和实例化,然后将插件对象列表传入的构造方法,根据增强类的匹配规则对插件匹配做分类。如果是对JDK内置类的增强,则放入bootstrapClassMatchDefine中。...

2022-07-15 08:00:00 418

原创 Apache SkyWalking Java Agent 06-插件定义体系

SkyWalkingJavaAgent使用了ByteBuddy库来操作类的字节码,实现对类的增强功能,所谓对目标类增强就是修改Java类的字节码,包括给类新增一个属性、让类实现一个接口,并实现接口中的方法,对类中的方法拦截(在方法执行前、执行后、抛异常等执行相应的方法,是不是和AOP有点像了),通过JavaAgent技术实现对字节码的修改,不需要应用修改源代码,实现代码无侵入。重写了getInstanceMethodsInterceptPoints方法,说明对目标类的。...

2022-07-14 23:23:36 320

原创 Apache SkyWalking Java Agent 05-插件加载机制(下)

基于 SkyWalking Java Agent 8.8.0 版本上一篇文章中我们重点分析了自定义类加载器 AgentClassLoader.initDefaultLoader() 部分,AgentClassLoader 初始化主要是定位 skywalking-agent.jar 所在目录以及成员变量 DEFAULT_LOADER 和 classpath 的初始化。AgentClassLoader 主要负责查找插件和拦截器,其中插件位于 skywalking-agent.jar 目录下的 Config.Pl

2022-06-25 00:03:30 674

原创 Apache SkyWalking Java Agent 01-源码编译

编译环境注意:Maven 版本需要3.6+。Fork skywalking-java 到自己的GitHub仓库skywalking-java GitHub地址 https://github.com/apache/skywalking-java 点击fork到自己的GitHub仓库。Clone 源码到本地编译源码导入IntelliJ IDEA设置 Generated Source Codes and folders in apm-protocol/apm-network/target/gene

2022-06-13 22:48:45 579

原创 Apache SkyWalking Java Agent 04-插件加载机制(上)

基于 SkyWalking Java Agent 8.8.0 版本之前的两篇文章分别介绍了 SkyWalking Java Agent 日志组件 和 配置初始化流程SkyWalking Java Agent 日志组件分析SkyWalking Java Agent 配置初始化流程分析今天我们要分析的是 SkyWalking Java Agent 插件加载机制/** * The main entrance of sky-walking agent, based on javaagent

2022-01-24 09:35:30 933

原创 Apache SkyWalking Java Agent 03-配置初始化流程分析

SkyWalking Java Agent 配置初始化流程分析

2022-01-08 00:17:19 1067

原创 Apache SkyWalking Java Agent 02-日志组件分析

基于 SkyWalking Java Agent 8.8.0 版本SkyWalkingAgent 类是 SkyWalking Java Agent 的入口 premain 方法所在类,今天我们要分析的不是 premain 方法,而是任何一个应用程序都需要的日志框架,SkyWalking Java Agent 并没有依赖现有的日志框架如 log4j 之类的,而是自己实现了一套。/** * The main entrance of sky-walking agent, based on javaagent

2022-01-05 08:43:41 669

原创 Go语言进阶

Go语言进阶Go语言进阶PointersStructsMethodsInterfacesEmbeddingErrorsGoroutinesChannelsChannel BufferingChannel SynchronizationChannel DirectionsSelectTimeoutsNon-Blocking Channel OperationsClosing ChannelsRange over ChannelsGo语言进阶文中大部分示例代码来自Go by ExamplePointers

2021-12-21 09:38:25 796

原创 Go基础语法

Go基础语法Go基础语法Hello WorldValuesVariablesConstantsForIf/ElseSwitchArraysSlicesMapsRangeFunctionsMultiple Return ValuesVariadic FunctionsClosuresRecursionGo基础语法文中大部分示例代码来自Go by ExampleHello Worldpackage mainimport "fmt"func main() { fmt.Println("hello

2021-12-17 14:44:44 422

原创 HashMap面试常见问题

1、底层数据结构,1.7与1.8有何不同?1.7 数组 + 链表1.8 数组 +(链表 | 红黑树)2、为何要用红黑树,为何不直接树化,树化阈值为何是8,何时会树化,何时会退化为链表?当发生哈希冲突时,新元素会添加到链表尾部,可能导致链表长度比较长,查找元素时就需要一次次比较,比较耗时。如何解决链表长度过长问题呢?①通过扩容可以减少链表长度链表长度过长是可能发生了较多的哈希冲突,而减少哈希冲突的办法可以通过扩容数组长度来解决,数组长度足够长可以容纳更多的元素。数组默认长度为16,当元素个数超过

2021-10-16 17:20:53 151

原创 tcpdump排查线上接口请求问题

新上线的服务出问题了,调用第三方的接口出现服务端响应状态码401,赶紧查询 HTTP Code 401代表啥意思,于是找到了这篇文章 http常见的状态码,400,401,403状态码分别代表什么?401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息401是服务端响应的状态码,根据接口文档在请求header中添加 X_API_KEY用于接口验证,代码中也确实这么实现的。而且同样的接口本地发送请求没有问题,这里是使用Hutool(3.3.2版本)工具包发送HTTP请

2021-10-16 17:18:16 467

原创 Spring加载BeanDefinition过程详解(二)

上一篇文章我们分析到 DefaultBeanDefinitionDocumentReader 注册 BeanDefinition 信息。/** * This implementation parses bean definitions according to the "spring-beans" XSD * (or DTD, historically). * <p>Opens a DOM Document; then initializes the default settings.

2021-05-31 08:49:33 148

原创 Spring加载BeanDefinition过程详解(一)

今天我们继续Spring源码的学习,上一篇文章分析了 BeanDefinitionReader 的创建过程,本篇文章分析 BeanDefinitionReader 加载BeanDefinition过程。/** * Load bean definitions from the specified XML file. * @param resource the resource descriptor for the XML file * @return the number of bean defini

2021-05-27 14:40:01 351

原创 【JVM】谈谈JVM内存区域的划分

对 Java 程序员来说我们不用自己手动管理对象内存的申请与释放,全部交由 Java 虚拟机(JVM)来管理内存的分配与回收。因此,日常开发中我们不用关心内存分配与回收,减少了很多繁琐的工作,大大提高了开发效率。也正是因为如此,一旦出内存泄漏和溢出方面的问题,如果不了解 JVM 内部的内存结构、工作机制,那么排查问题将变得异常艰难。接下来,我们一起学习 JVM 内存区域的划分、作用以及可能产生的问题。根据 Java 虚拟机规范,Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为几

2021-05-27 14:29:00 504

原创 【Spring源码】BeanDefinitionReader 的创建过程分析

通过前面两篇文章的分析我们知道 Spring 将配置文件封装为 Resource。Resource 只负责资源文件的封装,而配置文件的读取工作则交给 BeanDefinitionReader 来完成。Spring 中的大部分功能都是通过配置的方式实现的,其中以 XML 文件的形式最为常用。XML 配置文件的读取正是通过 XmlBeanDefinitionReader 类完成的,它的内部将 XML 文档的读取工作委托给 BeanDefinitionDocumentReader 接口的实现类DefaultBe

2021-03-05 13:02:47 248

原创 【Spring源码】DefaultListableBeanFactory 创建过程分析

上篇文章我们分析了 ClassPathResource 对资源文件的封装。Resource resource = new ClassPathResource("applicationContext.xml");接下来,我们继续往下分析,Spring中Bean工厂是如何创建的呢我们这里是通过调用 DefaultListableBeanFactory 类的无参构造方法创建一个 BeanFactory 对象DefaultListableBeanFactory beanFactory = new Defa

2021-02-26 16:54:27 269

原创 【Spring源码】ClassPathResource 资源文件源码分析

上一篇文章我们主要介绍了开发 Spring 应用涉及到的一些核心组件,在文章的最后搭建了开发环境。那么接下来我们开始分析 Spring 源码部分,本篇文章首先分析 Spring 是如何封装资源文件的。Spring 框架内部使用 Resource 接口作为所有资源的抽象和访问接口,在上一篇文章的示例代码中的配置文件是通过ClassPathResource 进行封装的,ClassPathResource 是 Resource 的一个特定类型的实现,代表的是位于 classpath 中的资源。对不同来源的资源

2021-02-26 16:51:55 814 2

原创 【Spring源码】Spring概述与环境搭建

Spring 概述Spring 是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。Spring 是为了简化 Java EE 的企业级应用开发的复杂性而创建的。目前,Spring 已经成为事实上的 Java EE 开发标准,学习研究 Spring 框架已经成为每一位 Java开发人员的必修课。Spring 框架提倡基于POJO(Plain Old

2021-01-25 23:34:10 143

原创 合并两个有序数组

需求有两个有序数组a[] 和 b[],将它们合并成数组c[],要求数组c[]也是有序数组。例如 数组a[] = {4, 6}; 数组b[] = {1, 2, 3, 5}; 那么合并后的数组c[] = {1, 2, 3, 4, 5, 6}。实现过程1、定义数组c[] 长度为数组a[] 的长度与数组b[] 长度之和;2、定义三个变量i, j, k 分别指向数组a[]、数组b[] 和 数组c[] 的起始下标;3、遍历数组a[] 和 数组b[] ,比较a[i] 和 b[j] 大小,将较小的一个值放入c[

2021-01-19 23:03:51 550

原创 从源码层面理解 ArrayList 扩容策略

ArrayList 在我们日常开发中用到的非常多,我们知道 ArrayList 内部是通过 Object 数组实现的,而数组的长度一经定义,就无法更改了。那么问题就来了,ArrayList 是如何实现扩容的呢?我们先来看看 ArrayList 类中有哪些成员变量。ArrayList 的成员变量/** * Default initial capacity. * 默认的初始容量10。 */private static final int DEFAULT_CAPACITY = 10;/**

2021-01-01 19:54:46 251 3

原创 详解选择排序

选择排序(Selection Sort)与插入排序有点类似都有已排序区间和未排序区间,选择排序是在未排序区间找到最小元素,然后将其添加到已排序区间末尾(与未排序区间的第一个元素交换位置)。开始时已排序区间为空,未排序区间就是整个待排序的数组,首先找到数组中最小的那个元素,然后将它和数组的第一个元素交换位置(如果第一个元素就是最小元素,那么它就和自己交换)。这个时候第一个元素就在已排序区间,剩余的元素在未排序区间。接下来,在剩下的元素(未排序区间)中找到最小元素,将它与数组的第二个元素交换位置。如此往复,直

2021-01-01 19:51:01 147 2

原创 详解插入排序

插入排序(Insertion Sort)的过程就像我们排序扑克牌一样(从左到右,从小到大)。开始时我们左手为空,然后我们从桌子上拿起一张牌并将它插入到左手中正确的位置,为了找到这个位置,我们将这张牌与左手中从右向左的每张牌进行比较,直到找到比它小或相等的牌的后面。与排序扑克牌类似插入排序的原理是:将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素,接着取未排序区间中的元素(数组的第二个元素),在已排序区间中找到合适的插入位置将其插入,并保证已排序区间数据一

2020-12-17 22:11:59 170

原创 详解冒泡排序,不能再详细了!

在我们日常开发中,排序是非常常见的一种需求,提供一组数据元素,把这些数据元素按照一定的规则进行排序。比如微信公众号的文章是按照文章的发布时间进行排序,再比如在电商类APP中查询一些商品,按照商品的价格进行排序,更复杂的会根据用户的喜好进行排序。在平常的项目中,简单的排序需求我们可以使用数据库提供的order by 语句进行排序,我们也可以使用JDK提供的工具方法(比如Arrays.sort())进行排序,这些排序方式都是别人封装好的,内部肯定使用了某种排序算法。我们有必要去了解一些经典的排序算法,接下来的

2020-12-11 21:23:40 239

原创 从一个故事开始讲递归

讲个故事从前有座山,山上有座庙,庙里有个老和尚和一个小和尚,一天,老和尚给小和尚讲了一个故事,故事的内容是“从前有座山,山上有座庙,庙里有个老和尚和一个小和尚,一天,老和尚给小和尚讲了一个故事,故事的内容…”。这个故事自己套着自己,没完没了,像是某种特征在不断重复,这就是我们今天要将的主题「递归」了。递归递归(Recursion)是一种非常广泛的算法,更是一种编程技巧。英文 Recursion 的中文翻译“递归”表达了两个意思“递”+“归”,去的过程叫做递,回来的过程叫做归,在编程语言中递归可以简单

2020-12-07 23:33:36 1015

原创 表达式求值

在上篇文章的最后留下了一个问题,求表达式4 + 2 * 3 - 10/5 的值。对于计算机来说,它看到的就是用户输入的字符串,这个字符串是由运算符和数字组成的。为了使问题简单化,我们这里仅讨论最常见的加减乘除四则运算。那么如何解析出运算符和数字以及如何处理运算符的优先级问题呢?我们可以通过上篇文章学习到的栈来解决,这里需要两个栈,一个栈用来保存数字,另一个栈保存运算符。下面我将一步一步展示表达式4 + 2 * 3 - 10 / 5 的计算过程:为了解析出操作数和运算符我们需要从左向右遍历表达式。当遇.

2020-11-15 22:51:39 284

原创

在之前的文章中详细介绍过队列这种数据结构,队列是一种先入先出(FIFO)的线性表。和队列相反,今天要讲的栈(stack)是一种先入后出(first in last out,FILO)的线性表。举一个生活中的例子,我们平时放盘子的时候是从上往下一个一个的放,取的时候我们也是从上往下一个一个的取,不能从中间任意取出。栈是一种操作受限的线性表,只能在一端进行插入和删除数据。允许插入和删除的一端为变化的一端,称为栈顶(top),另一端为固定的一端,称为栈底(bottom)。最先放入栈中的元素在栈底,最后放入的元素

2020-11-15 22:43:01 353

原创 面试官让我手写一个双向链表

笔者之前参加过一场视频面试,其中一个问题是说说ArrayList、LinkedList的区别,参加过面试的同学可能经常会被问到这个问题,当我说到ArrayList是基于数组实现的LinkedList是基于双向链表实现的时候,面试官说那你能写一个双向链表吗?因为面试邀请邮件中告知面试时需要写代码,笔者在面试之前虽然看了一些数据结构方面的知识点,但当真正手写的时候还是费了一番功夫。趁着这次周末有空,写一篇文章总结下双向链表。在前面的文章单链表的CRUD中详细介绍过单链表的插入、查找、修改和删除操作。我们可以

2020-11-10 11:48:22 613

原创 约瑟夫问题

问题来源约瑟夫问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家,他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定杀掉谁,约瑟夫和另外一个人是最后留下的两个人。约瑟夫说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫把他的存活归因于运气或天意,他不知道是究竟是哪一个。约瑟夫问题是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并

2020-10-31 16:39:47 4711

原创 单向循环链表(Java版)

前面的文章中介绍到单链表,它的尾结点(最后一个结点)的指针域next都是指向null,如下图:单链表的指针域只存储了向后的指针,到了尾结点就无法继续向后的操作。本篇文章将介绍单向循环链表,它和单链表的区别在于结尾点的指针域不是指向null,而是指向头结点,形成首尾相连的环。这种首尾相连的单链表称为单向循环链表。循环链表可以从任意一个结点出发,访问到链表中的全部结点。和单链表一样,为了使空链表与非空链表处理一致,我们通常会设置一个头结点。当然,之前提到的单链表和本文的单向循环链表都不是必须要有头结点

2020-10-14 23:44:56 629

原创 单链表的反转(Java版)

上一篇文章单链表的CRUD 介绍了单链表的查找、插入、删除、修改等操作,本篇文章是在上一篇的基础上实现单链表的反转功能。所谓反转就是将链表整体反过来,比如原链表是 a —> b —> c —> null,则反转后的链表是 c —> b —> a —> null。如下图所示:实现思路:1.首先新创建一个链表2.遍历原链表把原链表中每个结点的数据域依次插入到新链表头结点后面,比如依次将a、b、c 这3个数据域依次添加到新链表头结点后面:/** * 单链表的反转

2020-10-11 23:22:51 187

原创 单链表的CRUD(Java版)

我们知道数组需要一块连续的内存空间来存储数据,数组中逻辑上相邻的两个元素在物理位置上也相邻。而链表就不一样了,它不需要一块连续的存储空间,它通过指针将一组零散的内存块串起来。我们把内存块称为结点(Node)。链表为了将所有的结点串起来,链表的每个结点除了存储数据外,还需要存储一个指向其下一个结点位置的指针。所以链表有两块存储区域,其中存储数据的域称为数据域,存储下一个结点存储位置的域称为指针域。单链表我们在第一个结点之前增设一个结点,叫做头结点,头结点的数据域可以不存储任何信息,也可以存储如链表的

2020-09-27 00:58:26 230

原创 循环队列(Java版)

在上一篇文章的最后,我们提到了可以用循环队列来解决顺序队列只能使用一次的问题。在循环队列中,我们依然需要使用两个变量head(指向队列中的第一个元素,初始值为0)和tail(指向队列中最后一个元素的下一个位置,初始值为0)。在顺序队列中,我们需要判断队空和队满的情况,同样在循环队列也需要判断队满和队空的情况。上图中这个队列大小size为8,开始队列空时head和tail都指向下标0。依次添加元素a、b,此时如上图所示head位置不变,tail向后移指向下标为2的位置。继续添加元素c、d、e、f、g,

2020-09-22 22:18:47 303

原创 顺序队列(Java版)

上一篇文章介绍了队列的基本概念,并且通过画图的形式分析了入队出队的过程。本篇文章我将通过Java代码实现顺序队列。话不多说,先上代码。public class ArrayQueue { private Integer[] items; private int size; private int head = 0; private int tail = 0; public ArrayQueue(int size) { this.size =

2020-09-09 23:43:10 300

原创 队列

队列队列是一个有序列表,可以用数组或是链表实现。你可以想象下10年前去火车站排队买票的场景,在同一个窗口排成长长的队,先来的先买,后来的只能站在最后面排队,不允许插队。先来的人先买票(先进先出),后来的后买票(后进后出)。遵循先入先出的原则,即:先存入队列的数据,要先取出,后存入的要后取出。示意图:队列最基本的两个操作:入队(enqueue),放一个数据到队列的尾部;出队(dequeue)从队列头部取一个元素。顺序队列和链式队列用数组实现的队列叫顺序队列,用链表实现的队列叫链式队列。本篇文章

2020-09-08 23:34:00 209

原创 Docker入门

docker安装yum install -y yum-utils device-mapper-persistent-data lvm2yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum makecache fastyum -y install docker-cesystemctl start dockersystemctl enable docker

2020-07-27 16:07:36 146

基于SpringMVC的用户三次登录失败案例

基于SpringMVC的用户三次登录失败案例,用户连续三次登录失败后,只有等24小时之后才可以登录。本案例为了演示,设置时间为2分钟,可以自行修改...

2014-12-05

httpclient4.3开发文档

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。本文首先介绍 HTTPClient,然后根据作者实际工作经验给出了一些常见问题的解决方法.

2014-04-30

HTML语言教程

HTML语言教程软件,从入门到精通教你网页制作的基本技能

2013-06-03

汇编金手指

汇编金手指,查看常用指令的用法,便于学习汇编语言

2013-06-03

go语言编程

Go语言编程,带你进入go的世界.

2013-05-18

汇编语言王爽

汇编语言是个各种CPU所提供的机器指令的助记符的集合,人们可以用汇编语言直接控制硬件系统执行工作。

2013-05-17

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除