自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(36)

原创 fastjson源码分析(番外篇):一个偶然发现的反序列化“bug”

背景 项目中,有一个需求是需要传递一些数据到别的项目方,如果是基本类型或者java自带的类,那么可以直接传递对应的对象,如果是目标项目的类,那么传递json字符串,所以就有了下面这段测试代码:package test;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.TypeReference;imp...

2019-07-15 00:43:48 958

原创 Spring源码-xml解析bean(2)

delegate.parseCustomElement(ele)和delegate.parseCustomElement(root)具体执行

2020-08-16 23:47:38 14

原创 Groovy脚本的OOM源码分析

Groovy脚本是应用比较广泛的一种基于JVM的动态语言,Groovy可以补充Java静态方面能力的不足。一般语java结合的时候会有三种方式:GroovyClassLoader、GroovyShell和GroovyScriptEngine。 这三种方式用起来差不多,GroovyShell底层也是通过GroovyClassLoader实现的,GroovyScriptEngine是...

2020-08-16 18:37:22 296

原创 Spring注解-原理和实战

1.Autowired前提:所有bean,如果加了名称,按照用户自定义的名称来作为beanName;如果不加,按照类名首字母转小写的结果作为beanName@Autowired 根据类型注入, @Resource 默认根据名字注入,其次按照类型搜索 @Autowired @Qualifier("userService") 两个结合起来可以根据名字和类型注入解释: 假设现在有个类 : @Service public class UserServiceImpl impleme...

2020-08-09 10:44:18 25

原创 父类和子类的代码块加载顺序

package com.cainiao.arrow.arrowservice.jvm;public class TestSon extends Testfather{ static { System.out.println("TestSon,静态代码块"); } { System.out.println("TestSon,非静态代码块"); } TestSon(){ System.out.println("Te.

2020-08-02 11:54:38 29

原创 switch-前端资源代理工具

https://chrome.google.com/webstore/detail/xswitch/idkjhjggpffolpidfkikidcokdkdaogg​​​

2020-05-25 14:04:57 79

原创 递归解析json

/** * 递归解析json * 本身是json格式,或经过parse之后是json格式。要对子元素递归解析 */public static Object stringToJson(Object json){ try{ if(json==null){ return json; } //数值类型的,直接返回 ...

2020-05-07 12:32:06 72

原创 jvm调优

一、OOM1.top 的时候发现负载很高2.jstat可以观察到classloader,compiler,gc相关信息 jstat-gcutil pid 查看各个区的占比,和gc的次数。244023$./jstat -gcutil 2403 S0 S1 E O M CCS YGC YGCT FGC F...

2019-11-25 18:12:36 45

原创 AntV-G6包在项目中的应用

背景&需求 现有的项目工程,在改造之后需要一种更好的展示链路的方式。当前的项目框架提供的图形有限,没有足够的API支持。所以,在调研了一些开源的图形工具之后,选择了蚂蚁的G6包,作为链路图形展示的基础。 G6的文档相对来说不够详细,对一些细节没有解释,同时一些提供的包都已过期,需要用户重新设计。本文以链路图的设计代码为例,讲解了G6的一些使用方法和原理,希望能够帮助...

2019-11-10 15:05:44 3089 2

原创 git 配置简写命令

1.首先找到.gitconfig文件.gitconfig是隐藏文件,放在了用户目录下面:执行命令:cd ~vim .gitconfig[user] name = my email = my@xx.com[alias] st = status ci = commit co = checkout br = branch...

2019-11-08 17:28:48 90

原创 ASM原理分析

ASM是一款十分优秀的字节码处理框架,在很多地方都有用到,像fastJson序列化、反序列化时,针对用户定义的class类型去生成新的类。像在Spring的aop的动态代理中,用到了ASM做类的代理。有了asm,可以帮助我们解决很多问题,确实是值得深入了解的一个优秀武器。ASM的设计模式 在了解ASM之前,先来说一下ASM的整体设计模式-访问者模式(visitor)。 这种...

2019-08-18 23:10:50 193 1

原创 springAOP-CGLIB代理源码分析

在AOP3里我提到了proxy-target-class属性,这个属性的值决定是继承接口的还是基于类的代理被创建。(1)如果为true,那么使用cglib的动态代理。(2)如果为true为false或这不设置,那么aop根据类是否继承接口决定用哪一种代理方式。那么cglib的代理方式是怎么实现的呢,一起来探究一下:jdk的动态代理是用反射实现的,这里就不展开叙述了,先来写一段cgl...

2019-08-18 18:14:49 51

原创 日志logback-spring.xml配置

<?xml version="1.0" encoding="UTF-8"?><configuration> <!-- https://github.com/spring-projects/spring-boot/blob/v1.5.13.RELEASE/spring-boot/src/main/resources/org/springframework/b...

2019-08-04 20:13:00 39

原创 SpringAOP-2.日志管理和代码追踪

项目现状:1.logback配置了9种appender,在LogUtil中对日志做开关控制。(1)优点:这样分散了日志压力,毕竟全打在一个文件,会给排查带来很多麻烦。(2)缺点:但是带来问题也很明显,在打日志的时候,要给每一条日志加开关,这个重复工作量较大,也会影响代码整洁性。解决思路:2.所以在调研了AOP的功能之后,决定从两方面下手来做日志管理:(1)日志收敛,统一加开...

2019-08-04 19:05:32 53

原创 fastjson源码分析 (一):序列化

fastJson是很常用的序列化工具,用了这么久一直想底层看一下它的设计,探究一下它序列化和反序列化效率高的秘密。现在从最基础的用法开始,一点点揭开fastJson神秘的面纱。(版本:1.2.50)实际工程里,最常用的就是序列化和反序列化:ResultDO resultDO = new ResultDO();String jsonStr = JSON.toJSONString(re...

2019-07-07 18:40:56 628

转载 本地读日志目录报错:log4j java.io.FileNotFoundException (permission denied)

MacOS(1)本地代码启动的时候,需要在home下新建admin文件夹,但是一只提示没权限,最后发现需要修改下auto_master。执行 sudo vim /etc/auto_master# Automounter master map+auto_master # Use directory service/net ...

2019-06-18 20:46:37 2716

原创 SpringAOP-1.初探SpringAOP

想对spring的AOP原理做一些深入了解,就先做了一些aop配置,从应用层面对切面有所感知。基本概念:1.Joinpoint(连接点):连接点就是你要拦截的点,spring只支持方法类型的连接点。所以连接点实际中就是某一个业务类的方法。2.Pointcut(切入点):切入点是一种“位置”定义,是对连接点的描述,把一或多个连接点定义为一个切入点。3.Advice(通知):切面中定...

2019-06-16 23:52:59 35

原创 Spring源码-xml解析bean(1)

紧接上文, 在SpringAOP初探中,我们大概理解了aop的用法,现在从源码的角度来解析aop的运作原理。很巧的是,在spring源码(一)获取bean中我们分析了怎么获取bean的源码,现在通过xml解析的方式来了解在获取bean之前,这些在xml中定义的bean是怎么被解析、加载的。 因为我们现在用xml方式来注册bean,所以直接进入到AbstractBea...

2019-06-16 23:52:46 49

原创 Http和RPC的选择

在解决应用间通信的问题上,常见的两种方式就是http请求和HSF、dubbo这种RPC框架(以HSF为例)。 直观的感受来讲,规模较大的应用群会选用RPC框架,而很多小规模应用会采用简单的http来维护多应用之间的通信。最开始接触的是http服务,现在项目主体采用的都是HSF服务,部分会用http。 对两者的认识如下: 1.首先,RPC是一种框架,它可以有很多实现方式,可以...

2019-05-19 23:57:18 556

原创 高并发插入重复数据问题

背景:项目中有一块分析数据的功能,在多线程执行用例的时候,每次一个用例执行完,如果执行失败,都会调用分析模块。而分析的方式就是对执行返回的结果和相关的日志进行错误聚类分析。当一批用例执行结束之后,会发邮件报告。设计思路:采用数据字典的思路,把每次出现的错误都当作一个错误标签存储起来,如果字典中有,就直接关联此次执行结果;如果字典中没有,就插入标签再进行关联。错误标签包括错误内容和对应的应用,关...

2019-04-28 15:19:39 2796

原创 tair切db的灰度策略

背景:(1)项目中有一部份数据是用户的收藏数据,这部分数据一开始比较少,就一直以持久化的方式放tair里面,没有落db。但是随着用户增加,收藏的数据也越来越多,所以打算切到db,并且搜索速度没有太大影响,所以暂时没有做tair缓存,只走db。那么这就是一个纯切换的问题。(2)预发和线上的收藏老逻辑,都是纯tair增删改查操作。步骤:(1)写完一套db操作后,在每一个涉及到收藏tai...

2019-04-19 17:34:40 57

原创 设计模式-工厂模式优化

在项目的应用里,有很多功能都是通过前端传过来的key,去判断走哪一个处理类。一开始的时候是一个简单工厂模式的变型,用if..else的判断来做处理的分发,根据参数得到对应的类之后,直接执行了对应的方法。所以严格的说,这是简单工厂模式加策略模式。个人理解:(1)简单工厂模式是把创建对象的权利交给了工厂,由工厂根据传入的参数来返回用户需要的对象。然后用户拿到对象再去自己执行方法。(...

2019-04-14 22:30:38 411

原创 线程的基本方法-重入锁ReentrantLock(一)

说到ReentrantLock,肯定要提一下synchronized,两者都是解决并发的重要工具。在jdk5的版本,重入锁的性能是好于synchronized,但是从6开始,jdk对synchronized做了很多的优化,目前两者性能相差不大,官方建议synchronized的方式。说一下两者的相同点和不同点:相同点:(1)都是可重入锁,同一个线程每进入一次,锁的计数器都自增1,等...

2019-04-08 20:33:27 23

原创 线程的基本方法-重入锁ReentrantLock(二)

这一部分重点解析一下公平锁和非公平锁:背景:默认情况下,ReentrantLock采用的是非公平锁,即不排队的方式。当一个线程释放锁之后,其他线程是随机获取这把锁。synchronized不支持公平的设定,而ReentrantLock提供方法设置线程的公平性。1.创建 public ReentrantLock() { sync = new Nonfai...

2019-04-08 20:32:39 27

原创 前缀长度

问题:在MySQL中,前缀长度最大值为255字节。对于存储引擎为MyISAM或InnoDB的数据表,前缀最长为1000字节。在MySQL中,对于TEXT和BLOB这种大数据类型的字段,必须给出前缀长度(length)才能成功创建索引。办法:可以通过计算选择性来确定前缀索引的选择性,计算方法如下全列选择性:SELECT COUNT(DISTINCT column_name) /...

2019-02-20 16:53:30 492

原创 leetcode146 LRUCache

class LRUCache {    int capacity;    int len=0;    private Map<Integer,DoubleNode> map=new HashMap<Integer,DoubleNode>();    DoubleNode head;    DoubleNode tail;    public LRUCache(...

2018-12-23 09:34:41 140

原创 HashMap的线程不安全分析

大家都知道hashMap是线程不安全的,concurrentHashMap是线程安全的,而具体的原因可能还不是很清楚。现在先来分析一下hashMap的代码:(jdk 1.8)jdk在到1.8的时候多了很多新特性,hashmap也做了很多改动,由之前的数组+链表的模式,变成了数组+链表或数组+红黑树的模式。原因可想而知,当hash冲突增多的时候,长长的链表挂在一个数组节点上,这时候的get操...

2018-12-02 18:53:22 198

原创 JSON转义的问题

1.序列化循环引用的问题(1)一般情况下,是被序列化对象中,有多处引用了同一个数据,类似于下面这种:"receiver": { "$ref": "$[0].buyer"},或者在传到前端的时候,会有类似的情况:"$ref":"$.map.monthFinishRed[5]"就是receiver引用buyer字段的内容,此时的JSON对象保存的receiver是指向...

2018-12-02 15:51:36 509

原创 db与缓存不一致的问题

db和缓存的先后问题在日常代码中是很常见的,现在来分析一下每种情景的细节首先排除定时删除缓存的这种操作,因为这样不会有双写问题。因为不管有多少线程,(1)缓存没失效的时候都是走的缓存;(2)然后缓存在某一时刻失效时,线程A先到,发现缓存失效,从DB里面去读,此时读的都是最新的值。(3)即使在(2)中,正好遇到别的线程B更新db的值,若A在更新之前读,并写入缓存,那这一波仍然用的...

2018-12-02 15:50:40 638

原创 leetcode 71. Simplify Path

1.这题仔细研究一下,可以找到规律,再来编写就不难了。思路很简单,就不所说了

2017-01-20 11:51:19 213

原创 leetcode 93 .Restore IP Addresses

网上面的有些算法步骤太繁琐,不太容易理解。自己写了一下,速度勉强还可以。有兴趣的朋友可以再优化一下。

2016-12-28 14:40:09 119

原创 60. Permutation Sequence

1.个人的第一个想法就是:用最擅长的递归回溯,把这n!个组合度求出来,然后再把第k个数拼出来。显然,O(n!) 的复杂度太夸张了,通过不了2.找规律,对第i个数,共有(n-i)!个组合。所以用k除一下就得到第一个数了,然后通过%,得到下一步的k,循环n次,就可以构造出结果

2016-12-22 11:07:45 142

原创 leetcode 306. Additive Number

public class Solution {   public boolean isAdditiveNumber(String num) {       if(num==null ||num.length()        return false;       int len=num.length();for(int i=0;i{   if(num.charAt

2016-12-21 10:05:37 118

原创 leetcode 50. Pow(x, n) (更新)

public class Solution {  public double myPow(double x, int n) {      if(n==0) return 1.0;      int exp=n>0?n:-n;      if(n==Integer.MIN_VALUE &&x>1)   //本题的更新点在,当n极小的时候,若x>1,则返回的是0,不是-无穷。   

2016-12-21 10:02:57 144

原创 leetcode 122

public class Solution    {        public int MaxProfit(int[] prices)        {            int max = 0;            int n = prices.Length;            int i = 0, j = 1;            while (i

2016-06-28 15:00:38 242

原创 leetcode 283 Move Zeroes --个人的新思路

leetcode 283 move zeroes. 其实想法很简单,这里提供一个新思路。例如 [0,1,0,3,12] 遇到第一个0时,记录当前的count值为1,则,再遇到第二个0之前,数都往前移动count,也就是1位,变成[1,1,0,3,12] .继续循环,count=2,后面的数移动count,即2位,变成[1,3,12,3,12]. 因为count记录了0的个数,所以,从n-count位开始,到最后,都赋值为0. 如果一开始不是0,就说明前面的是默认有序的,i++直到第

2016-06-20 15:11:25 233

空空如也

空空如也

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