JAVA
文章平均质量分 63
IAmZRH
虚心学习,共同进步
展开
-
rocketMQ线上异常信息打印分析
前言最近生产环境日志上一直打印一个关于rocketMQ的异常信息:defaultMQProducer send exception然后线上MQ消息是发送成功了,消费端也成功消费。感觉没有影响到其他业务,当时业务挺忙,就没有去检查具体的原因,现在空闲下来了,就根据打印的异常堆栈信息跟踪分析一波。分析过程首先线上MQ消息都是使用同步方式发送,超时时间使用默认值3秒根据异常打印的信息,可以确认是在发送MQ消息时抛出的异常信息,而且其打印的异常信息还不属于MQ客户端自定义异常根据堆原创 2022-05-13 10:48:23 · 2536 阅读 · 0 评论 -
Java中反射实践记录一下
前言Java中的反射可以帮助程序做很多是事,对于运行状态下的类能获取其所有属性和方法。一个类中的公共和私有的变量和方法、构造方法等信息都能通过反射进行获取Class类:getDeclaredField把类的所有属性反射出来(含共有、私有、静态、final修饰的)。getDeclaredClasses把类的所有内部类对象反射出来。getDeclaredMethod把类的所有方法反射出来。setAccessible(true)关闭java语言访问检查,如果想要获取私有成员需要设置为true,不原创 2022-05-12 11:17:46 · 224 阅读 · 0 评论 -
Java过滤XSS脚本攻击记录一下
背景之前公司信息安全部门对公司项目进行网络安全升级时,发现项目里可能会出现XSS脚本攻击漏洞,所以就需要对其参数进行过滤拦截。XSS百度百科:XSS攻击全称:cross site scripting(这里是为了和CSS区分,所以叫XSS),跨站脚本攻击(XSS),是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。攻击者可以使用户在浏览器中执行其预定义的恶意脚本原创 2022-05-11 17:37:14 · 2555 阅读 · 0 评论 -
寻找两个正序数组的中位数
前言LeetCode第四题:寻找两个正序数组的中位数,难道:困难题目描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请找出并返回这两个正序数组的中位数;这道题给我的感觉其实还没有上次做的-无重复最长字符串-难,基本上提交一次就成功了【狗头/滑稽】;方式一:并归数组解题重点两个正序数组,所以提供的数组已经是排好序的,只需要在合并到一起凑成一个大数组即可public double findMedianSortedArrays (int[] nums1原创 2021-10-29 22:07:28 · 183 阅读 · 0 评论 -
无重复字符的最长子串
前言leetcode中算法第三题求无重复字符的最长子串,难度:中等;再做之前有看过一些解决思路,有说用左右指针法计算最长长度,当时只看了一部分解决思路,没看完就自己动手去操作。但是结果如果只用左右指针我根本就做不出来【笑哭】,附一张提交记录图:过程当时实在是搞不出来了【头大】,然后就想到之前有用hash表解决环状链表算法问题,就想着能否用hash表解决这题。哈哈,最后通过不懈努力还是搞出来了。/** * @Author: ZRH * @Date: 2021/10/19 17:06原创 2021-10-29 22:06:56 · 112 阅读 · 0 评论 -
Hikari并发无锁化详解
前言目前SpringBoot默认的数据库连接池是Hikari,相对于Druid连接池来说:Hikari的特点就是快,其内部运用了很多优化机制和操作,主要就是为了更高的性能。而Druid连接池特点不是快,是对数据和sql的监控分析。两者各有各的特点,没有哪个是最好,根据项目和需求选择适合的连接池。FastListHikari连接池内部为了有更好的性能,放弃了使用ArrayList集合,而是自定义了一个FastList集合其内部和ArrayList实现相似,主要在get方法和remove原创 2021-10-29 22:06:31 · 1004 阅读 · 1 评论 -
Java集合中快速失败机制详解
前言以前在看JDK集合源码时,会发现其中有快速失败和失败安全机制的应用实现(以前刚开始看时不知道这个东东是什么意思,后来了解多了才知道这个-_-)快速失败和失败安全机制其实是一种设计思想,其应用场景不只在Java集合类,很多开源框架里也有提现,Dubbo的集群容错机制,其中除了有快速失败和失败安全机制外,还有失败自动切换、失败自动回复、并行调用多个服务机制。本人对dubbo框架了解不多,本次只讨论JDK集合内快速失败和失败安全机制的实现。快速失败机制首先看一到面试题:public sta原创 2021-10-29 22:05:54 · 897 阅读 · 0 评论 -
Future异步回调进阶使用记录一下
前言在某些场景中,对于一些不重要的任务可以使用异步执行的方式进行处理,而有些情况下又有需要获取异步执行任务的回调结果这时就可以使用Future接口,这次结合个人理解,记录一下关于Future接口异步回调的进阶使用,以便后续查阅。FutureTask在使用线程池异步执行任务时,如果需要获取执行结果,那就需要使用submit()方法提交任务,其内部会封装一个FutureTask对象,最后通过get()方法阻塞式获取结果(其实相当于伪异步):public static void main (S原创 2021-10-29 22:05:15 · 493 阅读 · 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 · 422 阅读 · 0 评论 -
线程池调优之动态参数配置
前言线程池的核心参数配置在网上有一大堆的文章介绍,这次结合个人理解写一篇文章记录一下,以便加深印象和后续查阅。线程池配置参数corePoolSize:线程池核心线程数maximumPoolSize:线程池最大线程数keepAliveTime:允许线程空闲时间(对非核心工作线程的回收)TimeUnit:线程空闲时间单位workQueue:线程队列(当核心线程数满了,新的任务就会放入这个队列中)threadFactory:线程工厂(用于创建工作线程,自定义线程工厂可以指定线程名称)han原创 2021-10-08 18:30:39 · 1843 阅读 · 0 评论 -
Log4j日志脱敏记录一下
前言在项目上线环境中,需要记录程序运行时产生的各种错误信息、状态信息、调试信息、执行时间记录等日志信息。可以用于查找问题、定位数据等等操作。日志的具体实现可以有log4j和logback等,这里我们使用SLF4J作为日志系统的实现。使用SLF4J使用idea工具可以安装lombok插件,并引入maven包:<dependency> <groupId>org.projectlombok</groupId> <artifactId>原创 2021-09-27 22:23:01 · 2858 阅读 · 2 评论 -
Java调用机器学习训练包记录一下
前言最近公司有个需求,需要对用户进行数据画像分析。公司大数据组通过对线上用户数据进行分析后,通过机器学习用python做了一个训练模型pkl文件包。要求我部门对用户数据进行分析计算。而我部门的项目都是使用Java进行开发的,所以就需要Java调用pkl训练模型包。经过调研python的pkl训练模型包不能直接被Java调用,跨平台调用需要使用pmml格式文件,所以就让大数据部门依照已经生成的训练模型pkl文件,在次封装成一个pmml文件。pmml格式<?xml version="1原创 2021-09-27 22:21:34 · 1540 阅读 · 0 评论 -
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 · 376 阅读 · 0 评论 -
一致性Hash思想及实现记录一下
前言之前公司有个业务需求,把一批用户信息保存到本地库,数据大概有100万+,而且后期一段时间也会持续性加入本地库,为了保证后期风控查询匹配,所以用了分表模式当时评估了后期的数据量,也是对一致性hash算法了解不多,所以采用了用户唯一信息hash并取模方式插入数据库。采用hash取模方式虽然简单高效,但对数据或节点进行扩容或者缩容,取模的方式就行不通的。这时就可以使用一致性hash算法来解决这种问题一致性Hash设计思想一致性Hash是由固定长度的hash环构成,其大小为2的32次方。将原创 2021-08-19 19:01:33 · 138 阅读 · 0 评论 -
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 · 351 阅读 · 0 评论 -
中高级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 · 194 阅读 · 0 评论 -
CPU缓存一致性协议MESI详解
前言CPU在摩尔定律下以每18月翻一番的速度在发展,然而内存和磁盘的发展速度远不及CPU。这就造成了高性能的内存和磁盘价格昂贵,然而CPU的高速运算又需要高速的数据,为了解决这个问题,CPU中内置少量的高速缓存以解决IO速度和CPU运算速度之间不匹配的问题。在CPU访问存储设备时,无论是存取数据和指令,都聚集在一片连续的区域,这被称为局部性原理- 时间局部性:当一个信息被访问,那么近期它可能还会被再次访问,例如:循环、递归、方法的反复调用;- 空间局部性:当一个存储器位置被引用,那么它附近的原创 2021-08-09 19:47:03 · 535 阅读 · 0 评论 -
Synchronized详解(下)
前言上篇文章介绍了Synchronized和monitor的一些底层基础知识 Synchronized详解(上)| 8月更文挑战;那么有个问题来了,我们知道Synchronized加锁加在对象上的,那么对象是如何记录锁状态的呢?所以这次就介绍一下JVM虚拟机中对象的内存布局对象内存分析HotSpot虚拟机中,对象在内存中分为三块:对象头、实例数据、对其填充;- 对象头:像hash码、分代年龄、对象锁、锁状态标志、偏向锁ID、偏向时间、数组长度等等。对象头一般占两个机器码(在32位虚拟原创 2021-08-04 00:03:01 · 130 阅读 · 1 评论 -
Synchronized详解(上)
前言在多线程编程中,会出现多个线程同时访问一个共享、可变资源(共享:资源被多个线程同时访问;可变:资源可被多个线程修改)的情况,这个资源我们称为临界资源,这种资源可能是对象、变量、文件等等;由于线程执行是不可控的,所以需要采用同步机制来协助对象可变状态访问,即在同一时刻,只能有一个线程访问临界资源,所以被称作同步互斥访问;在Java中提供了两种方式来实现同步互斥访问:synchronized 和 Lock;同步器的本质就是加锁,其目的:序列化访问临界资源,即同一时刻只能有一个线程访问临界资源;原创 2021-08-03 19:25:28 · 329 阅读 · 0 评论 -
DelayQueue延迟处理任务记录一下
DelayQueue延迟处理任务前言过程这里解释下first的内存泄漏情况 :这里解释下leader的作用 :最后前言在工作中经常会遇到需要延迟处理某些消息的业务场景,比如订单超时,延迟通知,任务延迟处理等等。实现方式有多种,包括使用rabbitMQ死信队列处理,jdk的DelayQueue延迟队列,redission的延迟队列。本次介绍DelayQueue队列的使用及其实现原理。过程使用DelayQueue延迟队列,需要加入队列对象实现Delayed接口,重写getDelay()方法和原创 2021-04-24 15:17:03 · 487 阅读 · 0 评论 -
动态规划解决跳台阶问题记录一下
动态规划解决跳台阶问题前言过程最后前言动态规划是一种把原问题分解为相对简单的一系列子问题的方式进行求解的方法。动态规划通常可以用于解决有重叠子问题和最优子结构的问题。在LeetCode上有非常多关于动态规划的问题,很有逻辑性和技巧性,这次以一道很经典的跳台阶问题来学习动态规划。过程leetCode原题:一只青蛙一次可以跳一个台阶,也可以跳两个台阶,求该青蛙跳上10级台阶共有多少种跳法。首先当我们解析一下其过程,就会发现这题不难:当有一级台阶时,只有一种跳台阶的方式。当有两级台阶原创 2021-04-24 13:14:19 · 315 阅读 · 0 评论 -
手写一个rpc远程调用服务demo
手写一个rpc远程调用服务框架demo三级目录三级目录三级目录三级目录原创 2021-04-10 15:46:06 · 407 阅读 · 3 评论 -
用多线程模拟2PC事务提交
用多线程模拟2PC事务提交前言代码实现最后前言之前遇到过一个面试题,要求的是在多线程执行同一批任务里,如果有有一个线程执行失败,那么需要把其他线程通知回滚任务。废话不多说,下面直接上代码。代码实现/** * 2PC事务 -> 分布式事务 * * @Author: ZRH * @Date: 2021/4/1 10:16 */public class Test1 { /** * 子线程最后提交事务还是回滚事务的标识 */ private st原创 2021-04-01 17:00:45 · 325 阅读 · 1 评论 -
LFU算法代码实现记录一下
开头最后参考 LFU算法详解原创 2021-03-29 11:46:28 · 648 阅读 · 3 评论 -
Java高级操作记录一下
说原创 2021-03-15 21:47:08 · 195 阅读 · 0 评论 -
希尔排序记录一下
前言原创 2021-03-15 20:33:21 · 92 阅读 · 1 评论 -
插入排序记录一下
前言插入排序原创 2021-03-10 10:58:03 · 90 阅读 · 0 评论 -
选择排序记录一下
前言选择排序是一种类似冒泡排序的排序算法,每次循环都会选择出最小的一个元素,然后放在数组的最左边。相对于冒泡排序,选择排序的优势没有在最里层进行元素交换,减少了元素的交换次数,但是如果是相同的元素可能会打乱原有的顺序,所以是不稳定排序。选择排序的时间复杂度和冒泡排序一样都是O(n^2)。选择排序下面是代码实现:/** * 选择排序 * * @param args */ public static void main(String[] args原创 2021-03-09 17:47:01 · 103 阅读 · 1 评论 -
冒泡算法记录一下
前言冒泡算法算是以前在学校里最早接触的算法之一了。因为简单易懂,基本上很多人都了解其基本原理。但是因为其排序方式简单粗暴,针对每个元素都依次遍历比较,所以其时间复杂度O(n^2),是一种效率低下的排序算法。这次用于记录一下对冒泡排序的基本实现和一些优化操作。冒泡算法一基础冒泡算法实现: /** * 冒泡算法 - 1 * * @param args */ public static void main(String[] args) {原创 2021-03-09 16:20:57 · 145 阅读 · 0 评论 -
手撸一个线程池
常规开头多线程编程是在开发过程中非常基础且非常重要的一个环节,基本上任何一家软件公司或者项目中都会使用多线程。当然在项目中通常都是通过线程池的方式执行多线程任务。看线程池执行流程和源码设计有助于提升我们多线程编程技术和解决工作中遇到的问题。很久之前就看过ThreadPoolExecutor线程池源码,了解其执行过程。这次准备手撸一个简单版的线程池加强一下对执行流程的理解。简单的过程废话不多说,直接上代码/** * @Author: ZRH * @Date: 2021/3/5 15:13原创 2021-03-05 17:15:18 · 283 阅读 · 2 评论 -
Map中value赋值null记录一下
hashmap和concurrenthashmap关于key-value设置为null的理解:因为使用场景的问题,hashMap是线程不安全集合适用于单线程场景。concurrenthashmap是线程安全集合适用于多线程场景。在单线程场景中,如果hashMap对value设置为null,那么在get(key)时返回null。这时可能存在两种情况,一种是hashMap里面没有对应的key-value,一种是给对应key设置了一个null的值。在单线程环境中可以用hashMap.containsKey(k原创 2021-03-01 16:07:47 · 3344 阅读 · 1 评论 -
多线程异常了会怎样?
多线程中如果一下线程发生异常,会有什么结果。这里都是使用Executor线程池:1,如果是用execute方法执行线程,那么会直接抛异常:如果是用submit方法提交线程,不会直接打印异常,而是需要调用future.get()方法才会打印异常。2,当线程抛异常后不会影响其他线程。3,当线程抛异常后,线程不会回收到线程池而是直接移除线程,并且创建一个新的线程放入线程池中。...原创 2021-03-01 14:29:40 · 205 阅读 · 0 评论 -
模板设计模式
定义模板模式是行为型设计模式。在一个算法流程或者执行流程里,把一系列公共不会变动的算法提取出来。把需要改动的一块代码抽象出来交给子类去重写。通俗的讲就是很多相同步骤的流程里,可能在某个步骤里存在差别。例如在《大话设计模式》中提到的考试场景模式,学生们的试卷都是一样的,只是学生回答的答案不一样,这种场景就适合使用模板模式。代码实现/** * 模板抽象类 * * @Author: ZRH * @Date: 2021/2/9 11:39 */public abstract class Ab原创 2021-02-09 14:14:37 · 206 阅读 · 0 评论 -
简单策略设计模式
定义策略模式是行为型设计模式。其核心思想是多用组合/聚合,少用继承;用行为类组合,而不是行为的继承。实现一组算法策略,可以在各种场景中进行交替使用。所以策略模式注重的是策略类的组织和调用,对应策略是实现并不注重。简单策略模式代码实现首先创建一个策略顶级接口/** * 策略类统一规则接口 * * @Author: ZRH * @Date: 2021/2/3 17:03 */public interface Book<T> { /** * 子策略类需原创 2021-02-09 10:38:26 · 174 阅读 · 0 评论 -
观察者设计模式
定义观察者模式是行为型设计模式。对象订阅者与观察者之间存在一对多的关系,当订阅者对象发送改变时,观察者能感知这种变化做出相应的事件。自定义手写代码实现这里用订阅者是店铺,观察者是两个喜欢苹果和华为的用户。通过店铺不同进货的产品,用户产生不同的响应事件。创建一个订阅者对象。/** * 订阅者对象 * * @author ZRH */public class AppleShop { /** * 订阅者对象内容 */ private String原创 2021-02-08 17:30:21 · 93 阅读 · 0 评论 -
单例设计模式
定义单例模式是创建型设计模式,其思想是私有化对象的构造方法,只提供一个对外获取对象实例的方法代码实践饿汉式/** * 单例模式实例 * * @Author: ZRH * @Date: 2021/2/7 10:05 */public class SingletonTest { private volatile static SingletonTest singletonTest = new SingletonTest(); /** * 构造方法私有化,原创 2021-02-07 11:49:53 · 94 阅读 · 0 评论 -
享元设计模式
享元定义享元模式属于结构型设计模式,其思想主要是使用池化技术对可共享对象的复用代码实践这里使用学科来实践享元设计模式。因为一个学科可以用多个学生,所以相同学科的学生可以共用一个学科对象/** * 享元实体对象 * 一个学科可以包含多个学生(姓名,电话) * 所以学科为内部不可变状态,而学生(姓名,电话)为外部可变状态 * * @Author: ZRH * @Date: 2021/2/3 15:51 */@Datapublic class XianYuanModel {原创 2021-02-07 10:00:41 · 336 阅读 · 0 评论 -
代理设计模式
动态代理传统代理方案JDK动态代理方案CGLIB动态代理方案学习设计模式对我们编写可读性强,扩展性好,耦合度低的代码有很大帮助。比较谁也不想写或接手垃圾代码。在spring中有两个核心模块,其中一个就是AOP切面。它就是使用了动态代理模式对方法进行增强操作。关于代理的定义这里就不在描述了,下面就用官方售票和代理售票的流程模拟三个动态代理实例。传统代理方案首先创建一个官方卖票类/** * 官方卖票 * * @Author: ZRH * @Date: 2021/2/4 11:46 *原创 2021-02-04 15:50:15 · 189 阅读 · 0 评论 -
分布式布隆过滤器实践
分布式布隆过滤器实践定义原理guava布隆过滤器使用redis隆过滤器使用优缺点优点缺点使用场景最后定义布隆过滤器是由Burton Howard Bloom大佬在1970年提出的一种概念。由一个很长的二进制数组和一些哈希函数所构成。原理对于一个元素,在添加是先通过一些哈希函数计算出特定的值,在根据这些值为下标在二进制数组里面找到对应的bit位,把位里的值从0变为1。当验证一个元素是否存在时,也是先通过这些哈希函数计算对应的值,根据这些值为数组的下标查找对应的bit位,如果所有的bit位都为1,那么原创 2021-02-03 11:45:28 · 875 阅读 · 0 评论 -
JAVA双大括号语法
图解JAVA双大括号语法原理匿名内部类 + 初始非静态代码块。第一个大括号是创建一个继承当前对象的匿名内部类。第二个大括号是在这个匿 名内部类中创建一个非静态初始化代码块,最后new 的操作是得到当前对象的子类 (匿名内部类)然后向上转型为当前对象的引用。缺陷:类中每一处双大括号的引用都会产生一个.class文件,导致堆内存会有这些文件的引用,增加类加载器负担。使用双大括号初始化所创建的匿名内部类会持有当前对象的引用,会把当前对象的实例暴露出去,造出内存泄漏...原创 2021-01-24 01:57:28 · 3584 阅读 · 0 评论