自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 浏览器缓存策略详解

1、为什么要引入浏览器缓存1、服务器会存在大量重复请求比如我们每次刷新页面的时候都会发送一次请求到服务器,而多次请求的参数和响应的内容都完全一致,其实这种请求完全就是多余的,我们完全可以就用上一次的响应内容。2、提高响应的速度对于重复的请求,我们将响应内容保存到本地,下一次请求时可以直接返回而无需请求服务器,那么会提高响应的速度,增强用户体验3、提高服务器的吞吐量如果我们能够减少对服务器发送重复的请求,那么服务器就有更多的时间和资源去处理那些真正有效的请求了,无疑是会增大我们服务器的吞吐量的。

2021-01-11 18:38:00 754 1

原创 关于求子数组最大长度问题的三种经典题型

这里写目录标题1、和为k的子数组的最大长度,数组中的元素可正、可负、可02、和为k的子数组的最大长度,数组中的元素都是正数3、和小于k的子数组的最大长度,数组中的元素可正、可负、可01、和为k的子数组的最大长度,数组中的元素可正、可负、可0思路:假设存在和为k的最长子数组,索引范围i~j,那么下面的式子必然存在:k = 子数组[0~j]的和 - 子数组[0~i]的和因此我们可以遍历数组求子数组[0~i]{0 < i < n}的累加和,每次获取了累加和后就可以判断有没有以i结尾的和为k的子

2021-01-06 11:58:01 591

原创 手撸LFU缓存结构,哈希表+二维链表

什么是LFU?当内存不足时,优先删除被操作次数最少的元素。数据结构设计哈希表 + 二维双向链表二维链表维护不同访问次数和相同访问次数结点集合之间的关系。每一列的双向链表是所有出现操作次数相同的节点的集合,次数链表的头节点之间也相互连接的,同样构成双向链表。二维链表的结构:链表中Node结点的设计:public static class Node { Integer key; Integer value; Integer

2020-11-16 15:07:34 358

原创 手撸LRU缓存结构,哈希表+双链表

要求:添加、获取、删除元素的时间复杂度为O(1),采用LRU内存淘汰策略。数据结构设计哈希表+双向链表双向链表的Node类型设计:public static class Node<K, V>{ K key; V value; Node pre; Node next; public Node(K key, V value) { this.key = key; this.value = value; }}

2020-11-12 21:41:35 281

原创 ThreadLocal的使用场景以及原理源码分析

ThreadLocal一般有两种使用场景:1)保证访问对象的线程安全2)每个线程内保存全局变量保证访问对象的线程安全通常很多工具类并不是线程安全的(典型有SimpleDateFormat和Random),如果我们需要在多线程环境中使用他们,我们可以将它放到ThreadLocal中,保证线程安全。public class TestSimpleDateFormat { @Test public void test1() throws InterruptedException, Exec

2020-10-27 21:44:58 159

原创 堆排序以及堆数据结构的优势

我们要了解堆排序,必须要知道堆这个伟大的数据结构。堆是一个非常重要的数据结构,可以被看做一棵完全二叉树的数组对象。我们的数据实际上在逻辑上可以根据数组的索引构建出为一颗完全二叉树,结点的位置与索引之间的关系是:i位置结点的左孩子在数组中的位置是:(2 * i) + 1,右孩子在数组中的位置是:(2*i)+2i位置结点的父节点在数组中的位置是:(i-1) / 2。堆的类型有两种:1)大根堆:每个二叉树的中的根结点是最大的。2)小根堆:每个二叉树的中的根结点是最小的。堆有两个非常重要的方法:

2020-10-24 21:46:01 2198

原创 synchronized作用、性质、用法、缺陷详解

synchronized的作用?官网文档翻译:同步方法支持一种简单的策略来防止线程干扰和内存一致性错误︰如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。通俗点说就是:能够保证同一时刻只有一个线程执行被synchronized保护的代码块,以达到保证并发安全的效果synchronized的两个用法对象锁包括方法锁(默认锁的对象为this当前实例对象)和同步代码块锁(需要自己指定锁的对象)类锁指synchronized修饰静态方法,或指定锁为class对象(syn

2020-10-24 21:12:08 698

原创 java15都出来了,不会有人还不知道函数式接口吧?

什么是函数式接口?函数式接口时java8引入的,只包含一个抽象方法的接口称为函数式接口我们可以在任意函数式接口上使用@FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。注意:@FunctionalInterface只是起到一个检查和声明的作用,并不是所有的函数式接口都需要加上@FunctionalInterface。只要接口只包含一个抽象方法(可以包含n个非抽象方法),那么这个接口就可以被称为函数式

2020-10-23 21:10:48 82

原创 找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。

题目:设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。示例 1:输入: nums = [5,6,5], target = 11输出: [[5,6]]示例 2:输入: nums = [5,6,5,6], target = 11输出: [[5,6],[5,6]]思路一:hash表hahs用来存储数组中数据,key为值,value为这个数在数组中出现的次数。从左到右遍历数组:如果hash表中存在target - num这个key,就添加这对数到结果集中,并且判断

2020-10-23 20:04:12 1066

原创 redis的单机、哨兵、集群模式对比

redis作为集中式的数据库中间件,它具有持久化的能力,但是需要容许少量数据的丢失。单机版生成环境不建议使用,有单点故障风险。一旦单台结点出现故障,可能会导致整个服务不可用sentinal哨兵模式另外引入一台结点redis sentinal(哨兵),会与其他的redis结点保持长连接(心跳机制),它实时地感应到其他redis结点的状态,客户端进行访问时,会向redis sentinal询问可用的redis服务结点,redis sentinal会返回可用的redis结点的信息。客户端获取到信息后再去访

2020-10-22 16:53:48 4260

原创 实际工程中避免死锁的技巧

1、设置超时超时时间使用Lock锁中tryLock方法的超时放弃机制,在指定时间内获取不到锁就放弃原来占用的锁。破坏死锁的请求与保持条件。/** * 描述: * 用tryLock来避免死锁 */public class TryLockDeadLock implements Runnable{ int flag; static Lock lock1 = new ReentrantLock(); static Lock lock2 = new ReentrantL

2020-10-20 20:42:22 335

原创 java代码演示经典哲学家就餐问题,以及解决方案

哲学家就餐问题哲学家每天除了思考就是吃饭,假设一张桌子上坐了5名哲学家,他们吃饭时都必须获取两根筷子,并且他们都有着相同的习惯,先拿起左边的筷子再拿起有右边的筷子,如果获取不到两根筷子就等待。代码演示死锁情况:public class DiningPhilosophers{ public static class Philosopher implements Runnable { private Object leftChopstick; private Ob

2020-10-20 20:33:55 947

原创 死锁的定义、危害、发生死锁的四个必要条件以及代码演示

1、什么是死锁前提:首先死锁一定是发生在并发中,在并发中我们为了保证线程安全,会使用一些加锁、信号量的方法,但是使用不当的情况下就造成了死锁。当两个(或者更多)线程(或进程)互相持有对方需要的资源,但又不主动释放,导致所有人都无法继续前进,导致程序陷入无尽的阻塞,这就是死锁。两个线程发生死锁:多个线程发生死锁:如果多个线程之间的依赖关系是环形,存在环路的锁依赖关系,那么也可能会发生死锁。2、死锁的影响死锁的影响在不同的系统中是不一样的,这取决于系统对死锁的处理能力。比如:在数据库中:

2020-10-20 20:09:53 796

原创 原子类AtomicLong在高并发环境下性能不好,怎么解决?LongAdder解决及原理分析

我们都知道原子类LongAdder可以在高并发环境下保证线程安全,因此我们在生产环境也会经常用到它,但是在高并发环境下它的性能却不是那么好。我们该怎么解决呢?要想解决这个问题,我们必须清楚为什么在高并发环境下,AtomicLong的效率会变低。AtomicLong底层运用的是CAS算法,是一种无锁保证线程安全的算法,在一般情况下可以提高我们程序的运行效率,但是在高并发环境下,也会称为我们系统性能的瓶颈。比如在高并发环境下进行累加操作,我们每做一次加法都会将变量的值同步回主存,由于竞争十分激烈,发生冲突

2020-10-15 21:40:32 635

原创 线程池中的钩子函数

所谓钩子函数,通俗地将也就是父类定义的一些空实现的方法,子类通过实现这些方法,在程序运行的声明周期中的某个阶段来回调这些方法,实现我们自定义的功能。java的线程池ThreadPoolExecutor为我们提供了三个钩子函数:beforeExecute:在执行任务之前回调afterExecute:在任务执行完后回调terminated:在线程池中的所有任务执行完毕后回调作用我们可以使用钩子方法在线程池执行任务的前后做一些事情,比如:日志记录,数据统计等等。使用beforeExecute实现

2020-10-13 20:43:13 897

原创 线程池构造参数详解,添加线程的规则,拒绝策略

ThreadPoolExecutor提供了四种构造函数,但本质都是调用最后一种这里一共有五种参数(long和TimeUnit表示的是KeepAliveTime,后面我直接将这两个参数表示成KeepAliveTime)分别是corePoolSize、maxPoolSize、keepAliveTime、workQueue、threadFactory、handler。我们先来了解一下这些参数的大概含义:参数名类型含义corePoolSizeint核心线程数maxPoolSiz

2020-10-13 20:29:35 297

原创 ajax跨域请求,无法携带cookie的问题,google浏览器问题

今天被一个跨域请求折腾了一天,任何方法都试过了,结果是google浏览器的问题!Chrome升级到80版本之后cookie的SameSite属性默认值由None变为Lax,这也就造成了一些访问跨域cookie无法携带的问题。解决:打开谷歌浏览器在Chrome中访问chrome://flags/,搜索SameSite并设置为disabled即可。然后就可以进行跨域访问了,当然前提是基本的客户端和服务端的配置得配好。这个很简单:客户端://表示支持跨域携带cookiexhrFields:{wit

2020-09-27 17:35:49 1697

原创 TCP释放连接(四次挥手),为什么要四次,最后一次挥手后为什么要等待2MSL

TCP释放连接的四次挥手第一次:发送方向接收方发送FIN释放连接请求报文,进入第一个等待时间FIN-WAIT-1第二次:接收方收到发送方的释放连接的请求,向发送方发送ack表示收到发送方的释放连接请求,但是还无法立即关闭,因为还要未完成处理的发送请求,因此进行关闭等待阶段,在这个期间接收方可以处理还未完成的发送请求;发送方收到接收方的第一次确认后进行第二次等待,等待它处理完发送请求(在这期间还可以进行数据的传输。)接收方处理完成之后,向发送方发送释放连接请求表示自己已经可以执行释放连接操作,并且携带

2020-09-24 21:09:57 5896

原创 TCP建立连接过程(三次握手)

三次握手的过程第一次:发送方发送SYN的连接请求报文到接收方,请求建立连接;接收方收到之后开始为本次请求分配资源第二次:接收方收到发送方连接的请求后,发送ACK确认收到发送方的连接请求,并向发送方发起SYN连接请求;发送方收到接收方的ack请求,开始分配资源第三次:发送方收到接收方的连接请求后,也会发送ACK确认收到接收方的请求连接这样TCP的连接就建立起来了!为什么是三次呢?我的理解是双方都需要收到对方的ack,才能确保自己到对方的网络路径是连通可用的。在第二次握手的时候,接收方收到ack

2020-09-24 20:43:33 6078

原创 使用AOP动态切换数据源实现mysql的读写分离

使用AOP动态切换数据源实现mysql的读写分离基于docker搭建Mysql主从复制AOP动态切换数据源基于docker搭建Mysql主从复制AOP动态切换数据源基于docker搭建Mysql主从复制1、创建两个mysql容器,一主一从,并将数据持久化到本地master节点:docker run -p 3301:3306 --name mysql_master \-v /mydata/mysql_copy/mysql_master/log:/var/log/mysql \-v /mydat

2020-09-14 20:40:32 249

原创 ConcurrentModificationException究极源码分析,为什么不能在迭代器遍历中,一边遍历,一边删除?以及解决方案

问题我们都知道在使用迭代器遍历集合时,删除集合中的元素会报java.util.ConcurrentModificationException异常,那么这是为什么呢?先来看看问题代码:List<String> list = new ArrayList<>();list.add("古力娜扎");list.add("李沁");list.add("琪琪");System.out.println(list);for (String s : list) { if(s.eq

2020-09-07 11:18:51 187

原创 下载开源项目,运行时node-sass 安装失败的原因及解决办法

今天在gitee上下载了一个开源项目,在npm install安装环境直接报错了:进行一系列拍错后发现是node-sass的问题,是一种预处理器脚本语言,可以解释或编译成层叠样式表,这个依赖用npm install安装h会出问题解决:单独安装mode-sass#先卸载先前安装的npm uninstall node-sass#单独安装一下npm install node-sass这样就可以了,最后npm install一下就好了~...

2020-09-06 14:50:27 152

原创 备忘录模式讲解及代码实现

1.核心就是保存某个对象某个时刻内部状态的拷贝,这样就可以将该对象(通过拷贝的对象)恢复到原先的状态2.结构2.1 源发器类Originator–需要被拷贝的对象2.2 备忘录类Memento–拷贝信息存放到此对象中2.3 负责人类CareTaker–管理备忘录对象3.实现方法3.1 备忘录中的信息与源发器中的信息保持一致,备忘录中提供构造方法以源发器对象作为参数3.2 源发器中...

2020-03-30 10:06:16 515

原创 观察者模式详解以及代码实现

1、简介:当对象之间存在一对多关系时,则使用观察者模式。当目标对象发送变化时,则通知他所依赖的所有对象(观察者对象)更新状态。2、优点:2.1 观察者与被观察者之间是抽象耦合的2.2 建立了一套触发机制3、缺点:3.1 当一个被观察者有很多直接或间接的观察者时,将所有的观察者通知到会花费大量时间3.2 如果观察者与目标对象之间存在循环依赖的话,目标对象会触发它们之间的循环调用,可能...

2020-03-29 17:24:09 1332

空空如也

空空如也

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

TA关注的人

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