- 博客(63)
- 收藏
- 关注
原创 蓉漂5年程序员的自述
时光飞逝,一晃眼竟然也在成都工作5年之久,工作经历竟然多达7家公司。 这次也算是对自己前五年的工作生活做个总结,能更清晰的认清自己现状
2022-06-19 16:15:19
363
2
原创 rocketMQ线上异常信息打印分析
前言最近生产环境日志上一直打印一个关于rocketMQ的异常信息:defaultMQProducer send exception然后线上MQ消息是发送成功了,消费端也成功消费。感觉没有影响到其他业务,当时业务挺忙,就没有去检查具体的原因,现在空闲下来了,就根据打印的异常堆栈信息跟踪分析一波。分析过程首先线上MQ消息都是使用同步方式发送,超时时间使用默认值3秒根据异常打印的信息,可以确认是在发送MQ消息时抛出的异常信息,而且其打印的异常信息还不属于MQ客户端自定义异常根据堆
2022-05-13 10:48:23
2422
原创 Java中反射实践记录一下
前言Java中的反射可以帮助程序做很多是事,对于运行状态下的类能获取其所有属性和方法。一个类中的公共和私有的变量和方法、构造方法等信息都能通过反射进行获取Class类:getDeclaredField把类的所有属性反射出来(含共有、私有、静态、final修饰的)。getDeclaredClasses把类的所有内部类对象反射出来。getDeclaredMethod把类的所有方法反射出来。setAccessible(true)关闭java语言访问检查,如果想要获取私有成员需要设置为true,不
2022-05-12 11:17:46
186
原创 Java过滤XSS脚本攻击记录一下
背景之前公司信息安全部门对公司项目进行网络安全升级时,发现项目里可能会出现XSS脚本攻击漏洞,所以就需要对其参数进行过滤拦截。XSS百度百科:XSS攻击全称:cross site scripting(这里是为了和CSS区分,所以叫XSS),跨站脚本攻击(XSS),是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。攻击者可以使用户在浏览器中执行其预定义的恶意脚本
2022-05-11 17:37:14
2506
原创 寻找两个正序数组的中位数
前言LeetCode第四题:寻找两个正序数组的中位数,难道:困难题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请找出并返回这两个正序数组的中位数;这道题给我的感觉其实还没有上次做的-无重复最长字符串-难,基本上提交一次就成功了【狗头/滑稽】;方式一:并归数组解题重点两个正序数组,所以提供的数组已经是排好序的,只需要在合并到一起凑成一个大数组即可public double findMedianSortedArrays (int[] nums1
2021-10-29 22:07:28
168
原创 无重复字符的最长子串
前言leetcode中算法第三题求无重复字符的最长子串,难度:中等;再做之前有看过一些解决思路,有说用左右指针法计算最长长度,当时只看了一部分解决思路,没看完就自己动手去操作。但是结果如果只用左右指针我根本就做不出来【笑哭】,附一张提交记录图:过程当时实在是搞不出来了【头大】,然后就想到之前有用hash表解决环状链表算法问题,就想着能否用hash表解决这题。哈哈,最后通过不懈努力还是搞出来了。/** * @Author: ZRH * @Date: 2021/10/19 17:06
2021-10-29 22:06:56
88
原创 Hikari并发无锁化详解
前言目前SpringBoot默认的数据库连接池是Hikari,相对于Druid连接池来说:Hikari的特点就是快,其内部运用了很多优化机制和操作,主要就是为了更高的性能。而Druid连接池特点不是快,是对数据和sql的监控分析。两者各有各的特点,没有哪个是最好,根据项目和需求选择适合的连接池。FastListHikari连接池内部为了有更好的性能,放弃了使用ArrayList集合,而是自定义了一个FastList集合其内部和ArrayList实现相似,主要在get方法和remove
2021-10-29 22:06:31
949
1
原创 Java集合中快速失败机制详解
前言以前在看JDK集合源码时,会发现其中有快速失败和失败安全机制的应用实现(以前刚开始看时不知道这个东东是什么意思,后来了解多了才知道这个-_-)快速失败和失败安全机制其实是一种设计思想,其应用场景不只在Java集合类,很多开源框架里也有提现,Dubbo的集群容错机制,其中除了有快速失败和失败安全机制外,还有失败自动切换、失败自动回复、并行调用多个服务机制。本人对dubbo框架了解不多,本次只讨论JDK集合内快速失败和失败安全机制的实现。快速失败机制首先看一到面试题:public sta
2021-10-29 22:05:54
850
原创 Future异步回调进阶使用记录一下
前言在某些场景中,对于一些不重要的任务可以使用异步执行的方式进行处理,而有些情况下又有需要获取异步执行任务的回调结果这时就可以使用Future接口,这次结合个人理解,记录一下关于Future接口异步回调的进阶使用,以便后续查阅。FutureTask在使用线程池异步执行任务时,如果需要获取执行结果,那就需要使用submit()方法提交任务,其内部会封装一个FutureTask对象,最后通过get()方法阻塞式获取结果(其实相当于伪异步):public static void main (S
2021-10-29 22:05:15
443
1
原创 Java实现判断环形链表
前言LeetCode算法第141题,是判断环形链表。其实这题算是比较简单,思路也不复杂,这次就把Java的代码简单实现一下。方式一:无限循环/** * 方式一:无限循环 */private static boolean test1 (ListNode head) { int i = 0; boolean fal = false; ListNode next = head; while (next != null) { if (i > 1
2021-10-29 22:04:19
380
原创 MySql中MVCC多版本并发控制器执行机制详解
前言网上有很多文章都有对MySQL的版本并发控制器MVCC的介绍,这次结合个人理解记录一下,加深印象也方便以后查阅。MySQL事务特性(ACID)原子性:一个事务内的所有操作要么全部执行,要么全部不执行。如果事务执行到中间过程时,出现异常,需要把之前已经执行的数据进行回滚操作一致性:一个事务开始前和结束后中,数据库中数据是具有完整性的。这表示更新的数据符合所有的预计规则持久性:一个事务内数据提交结束后,数据是永久性改变,服务器故障也不会丢失最新数据隔离性:多个事务如果并发执行读写操作,那
2021-10-08 18:31:30
214
原创 线程池调优之动态参数配置
前言线程池的核心参数配置在网上有一大堆的文章介绍,这次结合个人理解写一篇文章记录一下,以便加深印象和后续查阅。线程池配置参数corePoolSize:线程池核心线程数maximumPoolSize:线程池最大线程数keepAliveTime:允许线程空闲时间(对非核心工作线程的回收)TimeUnit:线程空闲时间单位workQueue:线程队列(当核心线程数满了,新的任务就会放入这个队列中)threadFactory:线程工厂(用于创建工作线程,自定义线程工厂可以指定线程名称)han
2021-10-08 18:30:39
1346
原创 Log4j日志脱敏记录一下
前言在项目上线环境中,需要记录程序运行时产生的各种错误信息、状态信息、调试信息、执行时间记录等日志信息。可以用于查找问题、定位数据等等操作。日志的具体实现可以有log4j和logback等,这里我们使用SLF4J作为日志系统的实现。使用SLF4J使用idea工具可以安装lombok插件,并引入maven包:<dependency> <groupId>org.projectlombok</groupId> <artifactId>
2021-09-27 22:23:01
2696
2
原创 RocketMQ之顺序消息
前言在项目中使用MQ消息队列时,某些业务场景可能需要保证消息的顺序消费执行。比如在订单流程场景中:创建订单、支付订单、订单完成这三个订单状态需要保证顺序执行,不能先支付订单,再创建订单。也不能订单完成,再去支付订单。在项目中如果使用默认的普通消息,那么就算生产者按照顺序发布消息后,消费端也有可能会不会按照顺序进行消费消息。RocketMQRocketMQ在其官方文档中指出,除了支持无序消息以外,还支持顺序消息。无序消息:普通消息,事务消息,延迟消息和定时消息顺序消息:全局顺序消息,
2021-09-27 22:22:19
1835
原创 Java调用机器学习训练包记录一下
前言最近公司有个需求,需要对用户进行数据画像分析。公司大数据组通过对线上用户数据进行分析后,通过机器学习用python做了一个训练模型pkl文件包。要求我部门对用户数据进行分析计算。而我部门的项目都是使用Java进行开发的,所以就需要Java调用pkl训练模型包。经过调研python的pkl训练模型包不能直接被Java调用,跨平台调用需要使用pmml格式文件,所以就让大数据部门依照已经生成的训练模型pkl文件,在次封装成一个pmml文件。pmml格式<?xml version="1
2021-09-27 22:21:34
1505
原创 MySQL存储IP地址优化记录一下
前言在项目中可能会有一些需求或场景,比如在对接第三方需求时需要指定对方请求IP为白名单,用于白名单放行或黑名单过滤拦截,这时就需要持久化IP地址到本地数据库中,用于存储的数据库有多种,但大多数情况场景下用MySQL存储IP地址另外也可以用MongoDB存储IP地址,系统在单位时间内同一IP地址请求访问频率过多进行限制拦截可以使用Redis实现MySQL存储IP信息:一般情况下在MySQL数据库中是常用VARCHAR(15)列的形式存储IP地址,IP最小长度7字符(0.0.0.1),最大长度1
2021-08-23 19:28:46
347
原创 一致性Hash思想及实现记录一下
前言之前公司有个业务需求,把一批用户信息保存到本地库,数据大概有100万+,而且后期一段时间也会持续性加入本地库,为了保证后期风控查询匹配,所以用了分表模式当时评估了后期的数据量,也是对一致性hash算法了解不多,所以采用了用户唯一信息hash并取模方式插入数据库。采用hash取模方式虽然简单高效,但对数据或节点进行扩容或者缩容,取模的方式就行不通的。这时就可以使用一致性hash算法来解决这种问题一致性Hash设计思想一致性Hash是由固定长度的hash环构成,其大小为2的32次方。将
2021-08-19 19:01:33
114
原创 LRU算法代码实现记录一下
前言之前有写过一篇关于LRU淘汰算法的文章 LRU算法记录一下,LRU算法思想是淘汰最近最少使用的元素,当一个元素在一段时间内没有访问过后,那么在之后的一段时间也极有可能不会被访问,然后当数据池满了后将其淘汰掉。这次把关于LFU算法的三种不同实现方式写一下,那废话不多说,show me codeLRU实现之数组 O(N)/** * LRU实现之数组 O(N) * * @Author: ZRH * @Date: 2021/8/13 10:32 */public class ArrayL
2021-08-13 12:52:56
320
原创 中高级Java一面面试基础知识点记录
前言记录一下公司高级Java工程师一面面试中一些基础知识点。Java基础:1,场景一:new HashMap(1), 只put()一个元素,对性能有什么影响?(扩容机制)2,ConcurrentHashMap锁机制?jdk1.8比jdk1.7优化了哪些?(分段锁、头节点锁+CAS、红黑树、链表尾插等等)3,ArrayList里for循环remove元素会产生什么问题?(fast-fail,modCount操作记录标识)4,场景二:核心线程数,线程队列,最大线程数分别是2,10,5的线程池中。
2021-08-11 22:44:08
171
原创 CPU缓存一致性协议MESI详解
前言CPU在摩尔定律下以每18月翻一番的速度在发展,然而内存和磁盘的发展速度远不及CPU。这就造成了高性能的内存和磁盘价格昂贵,然而CPU的高速运算又需要高速的数据,为了解决这个问题,CPU中内置少量的高速缓存以解决IO速度和CPU运算速度之间不匹配的问题。在CPU访问存储设备时,无论是存取数据和指令,都聚集在一片连续的区域,这被称为局部性原理- 时间局部性:当一个信息被访问,那么近期它可能还会被再次访问,例如:循环、递归、方法的反复调用;- 空间局部性:当一个存储器位置被引用,那么它附近的
2021-08-09 19:47:03
490
原创 Synchronized详解(下)
前言上篇文章介绍了Synchronized和monitor的一些底层基础知识 Synchronized详解(上)| 8月更文挑战;那么有个问题来了,我们知道Synchronized加锁加在对象上的,那么对象是如何记录锁状态的呢?所以这次就介绍一下JVM虚拟机中对象的内存布局对象内存分析HotSpot虚拟机中,对象在内存中分为三块:对象头、实例数据、对其填充;- 对象头:像hash码、分代年龄、对象锁、锁状态标志、偏向锁ID、偏向时间、数组长度等等。对象头一般占两个机器码(在32位虚拟
2021-08-04 00:03:01
109
1
原创 Synchronized详解(上)
前言在多线程编程中,会出现多个线程同时访问一个共享、可变资源(共享:资源被多个线程同时访问;可变:资源可被多个线程修改)的情况,这个资源我们称为临界资源,这种资源可能是对象、变量、文件等等;由于线程执行是不可控的,所以需要采用同步机制来协助对象可变状态访问,即在同一时刻,只能有一个线程访问临界资源,所以被称作同步互斥访问;在Java中提供了两种方式来实现同步互斥访问:synchronized 和 Lock;同步器的本质就是加锁,其目的:序列化访问临界资源,即同一时刻只能有一个线程访问临界资源;
2021-08-03 19:25:28
303
原创 Redis缓存设计与性能优化
前言redis在项目中是经常会使用的一种缓存数据库,了解其一些配置和设计思路有利于我们更有效安全的使用它这次介绍一下关于缓存设计优化和性能优化。缓存设计解析缓存穿透缓存穿透是指查询一个根本不存在的数据,在缓存和数据库层都无法命中。导致每次查询不存在的数据的请求最后都要到数据库层中查询,数据库查不出数据也无法写入缓存,失去了缓存过滤请求保护DB的意义。而造成缓存穿透的原因基本有两个:自身业务代码或者数据出现问题一些恶意攻击,爬虫等造成大量空数据命中缓存穿透的几种解决方案:
2021-07-31 03:22:59
198
原创 Redis主从架构记录一下
前言redis在项目中是经常会使用的一种缓存数据库,了解其一些配置和设计思路有利于我们更有效安全的使用它这次分析一下Redis的主从架构机制,所谓知其然知其所以然。搭建过程想要了解Redis的主从架构机制,最好的办法是自己搭建一套Redis主从架构。下面我们搭建一个redis一主二从的主从架构。首先下载一个单机redis服务器,然后复制两份 redis-6380.conf和redis-6381.conf文件,分别更改以下相关配置从节点:port 6380
2021-07-28 22:54:39
64
原创 Redis持久化记录一下
前言redis在项目中是经常会使用的一种缓存数据库,了解其一些配置和设计思路有利于我们更有效安全的使用它这次分析一下redis的数据持久化机制,知其然知其所以然。解析过程RDB快照处理在默认情况下,Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中可以对Redis进行设置,让它在“N秒内数据至少有M个改动”这一条件被满足,自动保存一次数据快照。在Redis的默认配置如下:save 900 1save 300 10save 60 10000其意思是Red
2021-07-28 22:54:06
86
原创 DelayQueue延迟处理任务记录一下
DelayQueue延迟处理任务前言过程这里解释下first的内存泄漏情况 :这里解释下leader的作用 :最后前言在工作中经常会遇到需要延迟处理某些消息的业务场景,比如订单超时,延迟通知,任务延迟处理等等。实现方式有多种,包括使用rabbitMQ死信队列处理,jdk的DelayQueue延迟队列,redission的延迟队列。本次介绍DelayQueue队列的使用及其实现原理。过程使用DelayQueue延迟队列,需要加入队列对象实现Delayed接口,重写getDelay()方法和
2021-04-24 15:17:03
438
原创 动态规划解决跳台阶问题记录一下
动态规划解决跳台阶问题前言过程最后前言动态规划是一种把原问题分解为相对简单的一系列子问题的方式进行求解的方法。动态规划通常可以用于解决有重叠子问题和最优子结构的问题。在LeetCode上有非常多关于动态规划的问题,很有逻辑性和技巧性,这次以一道很经典的跳台阶问题来学习动态规划。过程leetCode原题:一只青蛙一次可以跳一个台阶,也可以跳两个台阶,求该青蛙跳上10级台阶共有多少种跳法。首先当我们解析一下其过程,就会发现这题不难:当有一级台阶时,只有一种跳台阶的方式。当有两级台阶
2021-04-24 13:14:19
286
原创 用多线程模拟2PC事务提交
用多线程模拟2PC事务提交前言代码实现最后前言之前遇到过一个面试题,要求的是在多线程执行同一批任务里,如果有有一个线程执行失败,那么需要把其他线程通知回滚任务。废话不多说,下面直接上代码。代码实现/** * 2PC事务 -> 分布式事务 * * @Author: ZRH * @Date: 2021/4/1 10:16 */public class Test1 { /** * 子线程最后提交事务还是回滚事务的标识 */ private st
2021-04-01 17:00:45
288
1
原创 mysql主从架构记录一下
mysql主从架构开局准备主从理论同步原理主从搭建主数据库搭建从数据库搭建主从同步测试主从同步扩展GTID同步集群模式集群扩容半同步复制搭建半同步复制模式主从架构数据延迟mysql高可用方案开局准备mysql 8.0.20版本和两台centos7服务器。关于Linux安装mysql,可以自行百度,也可以使用宝塔工具进行搭建mysql,或者也可以使用docker搭建mysql镜像。主从理论MySQL的主从集群搭建,可以解决MySQL的数据存储和访问压力。保证数据安全:MySQL主从配置相当于
2021-03-21 03:26:31
2996
3
原创 mysql高级优化二记录一下
mysql高级优化二记录一下开局准备,先创建示例表和示例数据分页优化mysql的表关联常见的有两种算法嵌套循环链接算法(Nested-Loop join 简称:BLJ)基于块的嵌套循环链接算法(Block Nested-Loop join 简称:BNL)所以mysql关联优化in 和 exsits优化count(*)优化mysql数据类型数值类型时间类型字符串类型INT显示宽度其他优化方式开局准备,先创建示例表和示例数据‐‐ 示例表: CREATE TABLE `t1` ( `id` INT ( 1
2021-03-19 17:56:22
181
原创 mysql覆盖索引优化记录一下
开局准备,先创建一张表和写数据CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄', `position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位', `hire_tim.
2021-03-16 20:52:46
213
原创 选择排序记录一下
前言选择排序是一种类似冒泡排序的排序算法,每次循环都会选择出最小的一个元素,然后放在数组的最左边。相对于冒泡排序,选择排序的优势没有在最里层进行元素交换,减少了元素的交换次数,但是如果是相同的元素可能会打乱原有的顺序,所以是不稳定排序。选择排序的时间复杂度和冒泡排序一样都是O(n^2)。选择排序下面是代码实现:/** * 选择排序 * * @param args */ public static void main(String[] args
2021-03-09 17:47:01
92
1
原创 冒泡算法记录一下
前言冒泡算法算是以前在学校里最早接触的算法之一了。因为简单易懂,基本上很多人都了解其基本原理。但是因为其排序方式简单粗暴,针对每个元素都依次遍历比较,所以其时间复杂度O(n^2),是一种效率低下的排序算法。这次用于记录一下对冒泡排序的基本实现和一些优化操作。冒泡算法一基础冒泡算法实现: /** * 冒泡算法 - 1 * * @param args */ public static void main(String[] args) {
2021-03-09 16:20:57
125
原创 手撸一个线程池
常规开头多线程编程是在开发过程中非常基础且非常重要的一个环节,基本上任何一家软件公司或者项目中都会使用多线程。当然在项目中通常都是通过线程池的方式执行多线程任务。看线程池执行流程和源码设计有助于提升我们多线程编程技术和解决工作中遇到的问题。很久之前就看过ThreadPoolExecutor线程池源码,了解其执行过程。这次准备手撸一个简单版的线程池加强一下对执行流程的理解。简单的过程废话不多说,直接上代码/** * @Author: ZRH * @Date: 2021/3/5 15:13
2021-03-05 17:15:18
266
2
原创 redisson分布式锁的执行源码分析记录一下
很简单的开头之前在项目中有使用redisson作为分布式锁的实现方式,就想着看看它的源码的执行流程,然后记录一下。乱排版的中间废话不多说,先看一下项目中redisson使用方法:<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.12.3</version>
2021-03-04 20:49:48
362
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人