自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(55)
  • 收藏
  • 关注

原创 GC垃圾回收(3)- 三色标记算法

1. CMSCMS过程在上篇文章 GC垃圾回收(2) 中已经写过。它分为四个阶段:1 initial mark (初始标记)2 concurrent mark (并发标记)3 remark (重新标记)4 concurrent sweep (并发清理)其中 并发标记 阶段会有漏标的问题,为解决这个问题,采用了 “三色标记算法”2. G1G1 GC(Garbage First Garbage Collector)是一种服务端应用使用的垃圾收集器,目标是用在 多核、大内存的机器上,它

2020-06-30 19:37:17 1864

原创 CAS无锁优化&ABA问题

本文内容:Atomic原子类CAS(无锁优化,乐观锁)ABA问题Unsafe对某些常见操作,加锁的情况有很多,所以Java提供了一些类来实现这种操作,这些类内部自动带了锁,但这锁不是synchronized实现,而是CAS的操作来实现的。Atomic原子类以AtomicXXX开头的都是用CAS操作来保证线程安全的类。在开发工作中经常有多个线程共同访问一个值,改变一个值的场景,这...

2020-05-19 21:58:38 279

原创 ThreadLocal的使用及源码阅读

ThreadLocal的含义及使用ThreadLocal看字面意思,Thread 线程,Local 本地,它是什么意思?通过一个小程序来解释:public class ThreadLocalTest_01 { volatile static Person person = new Person(); public static void main(String[] args) { new Thread(() -> { try {

2020-05-16 15:35:05 100

原创 AQS原理及源码浅析

什么是AQS?AQS 即 AbstractQueuedSynchronizer 抽象队列同步器,它是Java并发用来构建锁和其他同步工具的基础框架,是一个抽象类。AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock、Semaphore、CountDownLatch。ReentrantLock是如何加锁的?AQS是如何被使用的?ReentrantLock 通过调用对象的lock()和unlock()方法来加锁解锁,下面分析一下源码中加锁的过程,在

2020-05-14 17:54:21 382

原创 Http流式响应接口封装

需要对接某个大模型的流式http对话接口,因为该项目中还需要对接另外的大模型服务但是另一个请求方式为websocket,为了实现模型服务切换以及对客户端做统一的流式响应,需要对大模型服务的调用做统一的流式响应封装。

2024-08-08 14:36:05 530

原创 WebSocket流式响应接口封装

*** 大模型websocket客户端/*** 消息回调接口/*** 是否收到消息/*** 等待连接打开的最长时间 ms/*** 等待服务器响应的最长时间 ms/*** 等待数据被读取的最长时间 ms} /*** 发送消息并同步获取响应* @param payload 发送的数据* @param callback 响应回调,由调用者实现获取响应数据。

2024-08-08 14:33:52 340

原创 Win10 TiKV单机单节点Docker部署测试

环境:Windows10、WSL2、Ubuntu20.04、Docker Desktop目标:单机单节点部署TiKV,测试用。

2024-06-04 09:45:26 489 1

原创 Java自制微信聊天图片自动保存软件

Java自制微信聊天图片自动保存软件

2022-08-05 17:33:44 1675

原创 幻读与间隙锁

一、前言在上一篇《事务隔离与可重复读的实现原理》中说过,MySQL是用MVCC技术实现了读提交和可重复读隔离级别。​我们都知道,在标准的隔离级别理论中,读提交(RC)能解决脏读问题,可重复读(RR)能解决脏读、不可重复读问题。而在MySQL(InnoDB)中,可重复读(RR)还解决了幻读的问题,具体看以下内容。初始化用到的表和数据:CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11

2022-03-04 11:54:54 1312

原创 事务隔离与可重复读的实现原理

一、前言简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在MySQL中,事务支持是在引擎层实现的。MySQL是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如MySQL原生的MyISAM引擎就不支持事务,这也是MyISAM被InnoDB取代的重要原因之一。下面会以InnoDB为例。二、隔离性与隔离级别提到事务,肯定会想到ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)下面来看其中的 I,

2022-03-04 11:48:25 1779

原创 DDD 核心概念与 Domain primitive

一、什么是DDD?领域驱动设计(Domain-Driven Design 简称DDD),是一套成熟的理论方法来指导中台领域建模以及微服务拆分和设计,聚焦于“如何在复杂业务场景下设计软件”。2003年埃里克·埃文斯(ErjcEvans)出版了《领域驱动设计》这本书后, DDD诞生。DDD的核心思想是从业务视角出发,根据限界上下文边界划分业务的领域边界,定义领域模型,确定业务边界。在微服务落地时,建立业务领域模型与微服务代码模型的映射关系,从而保证业务架构与微服务系统架构的—致性。但DDD提出后在软件开发领

2021-12-30 11:53:12 2604

原创 策略模式在Spring下的实践(生产已用)

一、前言如果只使用 策略模式,还需要在代码中手动 new 出不同的策略实体再进行操作。​如果使用 策略模式 + 工厂,new 策略的操作交给了工厂去做,但是在需求扩展需要添加新的策略时,不仅需要编写新增的策略代码,还要修改工厂类的代码使工厂具有加载新策略的功能。​这样就违背了“开闭原则”,对扩展开放,对修改关闭。​这时再加上广泛使用的Spring容器,就可以实现新策略的自动注册,只专注于编写新的策略代码即可。二、实践1. 类图2. 代码以订单操作为例(可根据需求改造成不同的策略)​

2021-12-28 14:41:17 319

原创 TCP/IP简述

互联网是由许多独立发展的网络通信技术融合而成。能够使它们之间不断融合并实现统一的正是TCP/IP技术。​如上图的 OSI参考模型所示,IP协议是网络层协议,TCP、UDP协议是传输层协议TCP/IP是通信协议的统称。一、协议简单来说,协议就是计算机与计算机之间通过网络实现通信时事先达成的一种“约定”。这种“约定”使那些由不同厂商的设备、不同的CPU以及不同的操作系统组成的计算机之间,只要遵循相同的协议就能够实现通信。反之,如果所使用的协议不同,就无法实现通信。​TCP(Transmissi.

2021-12-17 14:37:41 4774

原创 Kafka 生产者 Producer 原理及重要参数

《深入理解kafka:核心设计与实践原理》笔记​一、整体架构  消息在真正发往 Kafka 之前,有可能需要经过 拦截器(Interceptor)、序列化器(Serializer)和分区器(Partitioner)等一系列作用,下面先来看一下生产者客户端的整体架构。  拦截器(Interceptor):Kafka 一共有两种拦截器:生产者拦截器和消费者拦截器。生产者拦截器既可以用来在消息发送前做一些准备工作,比如按照某个规则过滤不符合要求的消息、修改消息的内容等,也可以用来在发送回调逻辑前做一些定

2021-11-20 17:17:30 2149

原创 Kafka 初探

《深入理解kafka:核心设计与实践原理》笔记一、什么是 KafkaKafka是由Apache软件基金会开发的一个开源流处理平台,由 Scala 和 Java 编写。Kafka是一种高吞吐量的,多分区、多副本且基于 Zookeeper协调的分布式发布订阅消息系统。目前 Kafka 已经定位为一个分布式流式处理平台,它以高吞吐、可持久化、可水平扩展、支持流数据处理等多种特性而被广泛使用。目前越来越多的开源分布式处理系统如 Cloudera、Storm、Spark、Flink 等都支持与 Kafka 集成

2021-11-17 18:02:51 148

原创 开发常见密码技术概念&RSA使用示例

一、单向散列函数1.1 概念及术语单向散列函数(one-way hash function)有一个输入和一个输出,其中输入称为消息(message),输出称为散列值(hash value)。单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。这里的消息可以是文档图像视频音频等,散列函数会将它们都当成单纯的bit序列来处理。这样,要确认完整性就不需要对比消息本身,对比小的散列值即可。注意:单向散列函数并不是一种加密,因此无法通过解密将散列值还原为原来的消息。术语:单向散列

2021-09-01 15:44:22 1681

原创 开发中的异常处理问题

应用程序避免不了出异常,捕获和处理异常是一个精细活。在开发业务逻辑时不考虑任何异常处理,项目接近完成时再采用“流水线”的方式进行异常处理,也就是统一为所有方法打上 try…catch…捕获所有异常记录日 志,或者使用 AOP 来进行类似的“统一异常处理”。 其实,这种处理异常的方式非常不可取。下面来说下不可取的原因、与异常处理相关的坑和异常处理的最佳实践。一、捕获和处理异常容易犯的错1. 常见错误1.1 不在业务代码层面考虑异常处理,仅在框架层面粗犷捕获和处理异常这个也就是常说的“统一异常处理”,

2021-06-21 22:24:54 988

原创 Spring事务传播机制

开发中有多个事务方法嵌套调用时,就涉及到了 Spring 的事务传播机制。下面梳理一下 7 种传播机制的含义,做一些测试以加深理解,也方便开发中灵活使用。1. Spring事务传播类型枚举PropagationREQUIRED: 没有事务就开启,有事务就加入,不指定的话默认为该类型SUPPORTS: 有事务就加入,没有就无事务运行MANDATORY: 加入当前事务,如果不存在则抛出异常REQUIRES_NEW: 没有就开启,有了挂起原来的,开启新的NOT_SUPPORTED: 有了挂起,没有

2021-06-16 18:13:19 448

原创 IDEA中类文件存在却无法被引入

1. 现象项目空间中有这个类,但是无法引入,提示创建这个类。2. 解决可能由于某些操作导致IDEA的缓存出现问题,需要将缓存无效并重启IDEA

2021-05-21 11:22:50 2948 1

原创 向对象中的List添加元素后,返回前端数据丢失

1. 现象在开发中遇到了一个bug,我在一个对象的 list 属性中add了一个新值,但是接口返回时 list 并没有被改变。下面我用demo模拟了一下:定义返回的对象clazz班级,studentsJson 对应数据库中存储的 Json Array 字符串,students是将字符串处理后返回的列表:public class Clazz { private String name; private String studentsJson; private List&l

2021-05-21 11:21:39 1128

原创 IDEA中类文件存在却无法被引入

1. 现象1.png项目空间中有这个类,但是无法引入,提示创建这个类。2. 解决可能由于某些操作导致IDEA的缓存出现问题,需要将缓存无效并重启IDEA2.png...

2021-05-21 11:09:51 1950

原创 代码加锁的常见问题

一、业务逻辑中的并发问题1. 示例当存在 一个类中 的 两个方法 同时被 多个线程 执行操作 共享资源 时,需要考虑加锁。示例如下:public class LockTest_1 { private static final Logger log = LoggerFactory.getLogger(LockTest_1.class); volatile int a = 1; volatile int b = 1; public void add() {

2021-05-16 15:18:13 1013

原创 Class类加载过程(一)

一、Class的生命周期一个Class文件经过三个步骤才能加载到内存中:Loading:class文件内是一个个二进制字节,将这些内容装到内存中Linking:该过程又分为3小步verification:校验class文件是否符合标准,比如文件开头不是CAFEBABE,这一步就会失败preparation:把class文件静态变量赋默认值(不是初始值)。如static int i = 8,在这个步骤会先把 i 赋成0而不是8resolution是把class文件常量池里面用到的符号引用,转

2021-02-21 16:29:51 455

原创 用构建器构造多参数实例

如果一个类构造器的参数大于四个就要考虑使用构造器来构建类了。它可以使参数更加灵活,扩展性更好并且可以减少一些参数位置写错的情况。可采用Builder模式的一种形式,不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或静态工厂)得到一个builder对象。然后客户端在builder对象上调用类似setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员类。示例:public class Nutrition

2020-09-01 15:38:28 276

原创 Java后端返回树型数据

前端有时需要展示部门树,城市树,人员树等树形结构,这时后端返回的数据需要经过一定的加工。1. 树结构的节点,设置children属性,可嵌套package com.jiangxb.test.util.tree;import java.util.ArrayList;import java.util.List;/** * @author jiangxiangbo * @date 2020/8/19 * @Description: 树结构实体 */public class TreeItem

2020-08-20 09:39:40 4309 6

原创 数据库数据存在空字符问题

说明有次给前端返回code值时,code后多了许多空字符,造成了编码不匹配的问题,之后发现是数据库字段设置的有问题。当时设置的CHAR类型,当存储的数据字节长度小于定义的长度时,不足的部分会补成空字符。解决方案code值定长时,CHAR类型长度设置为跟code长度一致,否则会有空字符。code若会变化,改用VARCHAR或者VARCHAR类型存储数据,它们是长度可变的,不会有空字符问题,但效率比CHAR略低。char varchar varchar2 的区别参考:https://wenku

2020-08-19 10:47:22 871

原创 Java中的四种引用 - 强软弱虚

Java中有四种引用,分别是:强引用、软引用、弱引用、虚引用。什么是引用?比如Object o = new Object(),声明了一个变量o,它指向new出来的Object对象,这就是一个引用。在Java的四种引用中,最常用的形式,如Object o = new Object(),就是强引用。强引用普通的引用NormalReference,是默认的引用,也就是强引用。只要有一个引用指向这个对象,那么这个对象就不是垃圾,一定不会被垃圾回收器回收,只有没有引用指向它时才会被回收。通过一个小程序理解

2020-08-10 20:32:02 234

原创 FastJson序列化类的问题

1. getter setter 的问题有次开发中使用FastJson时出现了个bug,说是类里面没有某个属性,debug后发现它默认通过get方法取出属性值,也就是说FastJson默认通过JavaBean规范进行对象序列化。所以命名方法时若不是类的get/set方法时,不要以get或set为前缀命名。测试:public class FastJsonTest { public static void main(String[] args) { // json转对象

2020-08-02 17:41:23 665

原创 JVM内存区域小结

1. 运行时数据区(Runtime Data Area)当类被加载入方法区时,就已经开始使用运行时数据区了。根据《Java虚拟机规范》的规定,运行时数据区通常包括这五个部分:方法区、堆、程序计数器、本地方法栈、Java虚拟机栈。如图所示:在JVM规范中虽然规定了程序在执行期间运行时数据区应该包括这几部分,但是至于具体如何实现并没有做出规定,不同的虚拟机厂商可以有不同的实现方式。2. 生命周期程序启动产生进程,一个虚拟机对应一个进程, 其中(橙色):方法区 和 堆 跟进程的生命周期是一致的。随着虚

2020-07-19 10:37:19 105

转载 JVM内存区域解析(转载链接)

https://www.cnblogs.com/mrhgw/p/10819234.htmlhttps://www.cnblogs.com/junzi2099/p/8418009.html

2020-07-16 17:14:59 111

原创 基本排序算法 - 快速排序

快速排序基本思想快速排序是冒泡排序的改进。它通过一轮排序将要排序的数据分为独立的两部分,其中一部分都比另外一部分小,然后分别对两部分再进行快排(可递归),直到各区间只有一个数快速排序结束。图示与代码public class QuickSort { public static void main(String[] args) { int[] arr = {6, 21, 5, 9, 10, 2, 16}; int len = arr.length;

2020-07-16 16:26:36 106

原创 基本排序算法 - 希尔排序

简单插入排序存在一定的问题:当待插入的数比较小时,会进行多次比较并进行多次的后移赋值操作,影响效率。希尔排序也是一种插入排序,是希尔(Donald Shell)在1959年提出的一种排序算法。它是简单插入排序经过改进后的一个更高效的版本,也称为缩小增量排序。希尔排序基本思想希尔排序是把元素按照下标的增量进行分组,对每组元素直接使用插入排序。这样随着增量的逐步减少,数组会越来越有序,当增量减至1时,执行完该轮排序后,希尔排序结束。图示与代码根据对有序序列在插入时采用的方法不同,希尔排序又可分为交换

2020-07-15 17:02:48 160

原创 基本排序算法 - 插入排序

排序算法相关理论网上资料已经很多了,这里记录一下代码方便复习。插入排序核心思想:把数组分为有序表和无序表,从后面无序表中依次取出第一个数,插入到有序表的适当位置。/** * @Description: 插入排序 * * 1.从第一个元素开始,该元素可以认为已经被排序 * 2.取出下一个元素,在已经排序的元素序列中从后向前扫描 * 3.如果该元素(已排序)大于新元素,将该元素移到下一位置 * 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 * 5.将新元素插入到该位置后

2020-07-13 17:24:03 91

原创 GC垃圾回收(2)- 常见的垃圾回收器

JDK诞生 Serial追随 提高效率,诞生了Parallel Scavenge,为了配合CMS,诞生了ParNew,CMS是1.4版本后期引入,CMS是里程碑式的GC,它开启了并发回收的过程,但是CMS毛病较多,因此目前没有任何一个JDK版本默认是CMS。并发垃圾回收是因为无法忍受STW1. Serial & Serial OldSerial & Serial Old分别是新生代和老年代的垃圾回收器,串行回收,现在一般不用了。Seriala stop-the-world(ST.

2020-06-29 09:43:36 190

原创 GC垃圾回收(1)- 回收算法与分代模型

1. 什么是garbage垃圾?没有任何引用指向的一个对象或者多个对象(循环引用),就是垃圾1.1 Java与C++对于垃圾处理的区别JavaGC处理垃圾开发效率高,执行效率低C++手动处理垃圾忘记回收 -> 会导致内存泄漏回收多次 -> 会造成非法访问开发效率低,执行效率高2. 怎么定位垃圾Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,哪些成为了”垃圾“。定位“垃圾”有如下算法:(1)引用计数法(Referenc

2020-06-28 11:39:19 533

原创 win10系统热点频率设置

我的电脑开热点默认是5GHz,其它电脑如果款式比较老可能就搜不到热点,为解决这个问题需要把我电脑的热点频率设置为2.4GHz。过程如下:控制面板 -> 网络和 Internet -> 网络和共享中心点击自己的网络连接,点击属性:点击配置,高级:如图选中2.4Ghz选项。注:不一定是Preferred Band选项,找到值中有2.4GHz字样的选项就行。网上其他人的配置项我系统也没有。...

2020-06-11 09:59:02 11609 1

原创 老旧的Vector与HashTable

在最开始的JDK1.0容器里只有两个,一个是Vector,实现List接口,底层是数组;一个是HashTable实现Map接口。这两个容器设计成了方法都是加synchronized的,是线程安全的,这是它最早设计不太合理的地方。因为多数情况下程序只有一个线程在工作,完全没有必要加synchronized,所以最开始的时候设计的性能比较差,所以后来在Hashtable之后又添加HashMap,HashMap就是完全的没有加锁。虽然HashMap效率高,但是HashMap没有加锁,不是线程安全的,那么怎么才能

2020-05-19 14:48:23 162

原创 Java容器分类

本文相当于一个目录,用来指导我之后的学习内容。容器分类容器的第一个接口是Collection叫集合。集合不管这个容器是什么结构都能把元素放在里面,是一个一个地放;Map是以键值对的方式往里放。其实Map可以看作是Collection一个特殊的变种,可以把一对对象看成一个entry对象,所以这也是一整个对象。容器就是用来装一个个对象的。严格来讲数组也属于容器。从数据结构角度来讲在物理上的这种存储的数据结构其实只有两种,一种是连续存储的数组Array,另一种就是非连续存储的一个指向另外一个的链表。Que

2020-05-19 10:56:43 614

原创 LockSupport的使用

因为wait()方法需要释放锁,所以必须在synchronized中使用,否则会抛出异常IllegalMonitorStateExceptionnotify()方法也必须在synchronized中使用,并且应该指定对象synchronized()、wait()、notify()对象必须一致,一个synchronized()代码块中只能有一个线程调用wait()或notify()以上诸...

2020-05-11 10:52:10 223

原创 基于CAS的一些锁(7)- Exchanger

Exchanger 交换器,用于两个线程之间交换数据。可以把exchanger想象成一个容器,这个容器有两个值,两个线程,有两个格的位置,第一个线程执行到exchanger.exchange的时候,阻塞,但是要注意exchange方法执行时是往里面传了一个值的,你可以认为把T1扔到第一个格子了,然后第二个线程开始执行,也执行到exchange,他把自己的值T2扔到第二个格子里。接下来这两个值交换...

2020-05-09 18:40:15 243

空空如也

空空如也

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

TA关注的人

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