自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Redis原理解析(三) 字典(dict)

目录1.3 字典(dict)1.3.1 概述1.3.2 字典的实现1.3.3 哈希算法1.3.4 哈希冲突1.3.5 rehash1.Rehash操作2.渐进式rehash3.渐进式rehash执行期间的哈希表操作1.3.6 总结本系列所有的内容直接参考于redis3.0版本源码和《Redis设计与实现》圣经,请大家放心食用~1.3 字典(dict)1.3.1 概述字典是一种用于保存键值对的抽象数据结构,Cpp、Java等语言中的Map就是字典的实现之一。在Redis中字典运用的相当广泛,比如Re

2022-02-12 12:46:39 302

原创 Redis原理解析(二) 链表(adlist)

目录1.2 链表(adlist)1.2.1 概述1.2.2 链表的底层实现1.2.3 链表的特性本系列所有的内容直接参考于redis3.0版本源码和《Redis设计与实现》圣经,请大家放心食用~1.2 链表(adlist)1.2.1 概述链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用的C语言并没有内置这种数据结构,所以Redis构建了自己的链表实现。链表在Redis中的

2022-02-11 11:20:53 969

原创 Redis原理解析(一) String底层实现之SDS

目录1.1 SDS(Simple Dynamic String)1.1.1 概述1.1.2 底层实现1.1.3 源码实现1.不使用结构体指针传递,而使用变长数组传递参数2.底层数组扩容规则1.1.4 使用SDS的好处本系列所有的内容直接参考于redis3.0版本源码和《Redis设计与实现》圣经,请大家放心食用~1.1 SDS(Simple Dynamic String)1.1.1 概述Redis的数据类型都是Key-Value键值对,Key永远都是String类型,而我们常说的Redis五大数据类

2022-02-10 11:39:04 1435

原创 Linux编程 C语言自定义线程池

简单模拟实现了下线程池的功能,代码不多就是基本功能,没有做错误处理,大家可以参考一下。头文件#ifndef __THREADPOOL_H_#define __THREADPOOL_H_#include<pthread.h>//最大的线程池线程数#define MAX_THREAD_SIZE 8//最大的任务队列数量#define MAX_TASK_SIZE 16//void* run(void* arg);typedef void*(*Task)(void* arg);ty

2022-01-20 18:34:42 1224

原创 MVCC的流程和作用详解

MVCC解决了什么问题,它的底层原理是什么?答:解决了不可重复读和快照读情况下的幻读问题。要彻底说清楚MVCC,必须先得了解四样东西。1、mysql有一个全局的事务ID,每次新建一个事务它的事务ID就是当前的全局事务ID,然后全局事务ID自增2、innodb存储引擎的表记录中有三个隐藏字段,第一个是row_id,该字段是用于没有主键并且没有唯一索引情况下的mysql的隐藏主键。第二个是事务id,它记录了最后一次插入或修改当前记录的事务ID,第三个是undo_log(回滚日志指针)它指向着当前记录的

2021-07-16 22:10:13 494

原创 Java偏向锁、轻量级锁、重量级锁过程详解

偏向锁、轻量级锁、重量级锁因为早期Java版本的synchronized底层实现采取的是操作系统的互斥量,线程阻塞和唤醒的代价很大,性能较低,因此Java尝试在多线程竞争不那么激烈的情况下,降低锁的开销。1、偏向锁偏向锁适用于只有一个线程进入同步代码的情况偏向锁会偏向于获得偏向锁的线程,它会在对象头的markword存储当前获取偏向锁的线程ID,当该线程下次获取锁的时候无需额外的操作只需要判断一下当前线程是否指向自己,如果指向自己则成功获得锁,否则进行偏向锁的撤销(偏向锁的撤销会产生两种结果:1、另

2021-07-07 18:37:08 1010 1

原创 CAS之ABA问题最形象例子!!

假设现在你使用链表维护了一个栈,栈中的元素如下:然后你有一个通过CAS算法实现的pop操作1.获取当前的栈顶:oldTop = head;2.获取栈顶元素的下一个元素:nextTop = oldTop.next;3.使用CAS算法,当栈顶元素为oldTop时,进行更新操作。4.返回原来的栈顶元素拿上面ABC三个元素组成的栈来说,head指针首先指向A元素,我们调用pop方法。oldTop = A;nextTop =B;CAS(&head,期望值[A],原有值[A],更新值[B])。最

2021-05-10 21:59:53 544

原创 分布式缓存的穿透、雪崩、击穿以及分布式锁

1.缓存穿透什么是缓存穿透,咱们来咬文嚼字理解一下,穿透穿透,穿过了还透过去了。缓存穿透主要指的是服务器在某一时间内接收到了大量数据库根本不存在的记录的查询请求(可能是恶意攻击),这些请求没有命中缓存,直接大量压向数据库最终导致服务不可用。我们传统的查询缓存,大都是先看缓存中有没有,有的话直接从缓存取。如果没有则去数据库查询,如果查询到了则保存在缓存里,返回结果。如果没有的话则直接返回null。这就导致了对于根本不存在的请求,我们每次都会查数据库,这其实就是上述问题出现的原因。对此有两种解决办法。解

2021-04-07 19:23:50 438

原创 合并两个无序链表

楼主昨天看到阿里的一道算法题是只使用O(1)的额外空间,合并两个无序链表。乍一看有点奇怪,一般都是双指针算法合并两个有序链表,后面思考过后除了不能像数组能够随机访问链表的每个元素外合并两个有序链表实际上就是先对每个链表进行排序,然后将两个有序链表合并起来。也就是分为两步。对两个链表分别排序将两个有序链表合并起来然后楼主看了一下网上的其他帖子,大部分都是使用选择啊、冒泡啊这种O(n^2)的算法。这效率实在太低了。尽管链表确实不像数组那样访问元素方便,但是通过快慢指针我们页能很快的就找到我们链表中指定的

2021-04-07 10:41:19 3295 2

原创 Nacos在linux虚拟机运行失败的原因

今天在Linux虚拟机上准备搭建nacos集群,但是运行之后jps发现没有对应的进程,nacos没有启动成功。运行出错,先去看日志这是一个开发人员必备的技能。到nacos安装目录的logs/start.log之后,发现因为运行时内存不足导致的,所以我去把Linux虚拟机内存提到了2g,但是提升之后又发现不能运行了,nacos的内存配置又自动变为了2g,最终解决办法,我们修改startup.sh文件的内容,修改如下即可,改为适合自己内存的配置...

2021-03-16 22:57:50 663

原创 [性能监控与分析] Java的浅堆和深堆

最近博主在使用MAT分析堆转储文件的时候,发现了对象的直方图中有如下两项。Shallow Heap 和 Retained Heap分别表示浅堆和深堆。那么究竟什么是对象的浅堆大小和深堆大小呢?我觉着首先我们应该有一个前提知识,一个对象本身的大小该如何计算?对象占用堆内存的计算假设下面有这样一个类。如果我们创建这个类的实例,那么对象占用了多大的堆内存呢?在Hotspot 64位虚拟机而言,答案是:32字节。大家可以先自己尝试着算一下,看看能否得出正确的答案。一个对象占用的内存大小可以分为下面三

2021-03-15 13:50:04 456 4

原创 使用Netty实现Dubbo RPC

emmmm不想一点一点介绍这个代码了,注释写的挺清楚的,主要思路就是Consumer通过反射获取对应的服务接口实例时,使用的代理模式。调用代理对象时的方法时,实际上是通过Netty的channel将对应的方法调用信息传给Provider直接wait()阻塞,然后通过synchronized+wait()+notify()实现线程通信,当Provider接收到客户端得请求时,根据请求数据去服务容器中寻找对应的服务进行调用处理(这里简单得通过一个Map模拟了服务容器,然后通过反射调用Method得invoke方

2021-02-23 21:51:38 115

原创 Netty源码篇(二) 接收客户端请求源码分析

上一篇源码分析中,我们完成了对服务器启动的源码分析。不知道小伙伴们还记不记得最终我们的服务器启动之后进入到了哪里?直接揭晓答案了:进入到了NioEventLoop类中的run方法,里面有一个死循环,一直做着三件事情:select()、processSelectedKeys()、runAllTasks()。现在我们启动客户端给服务器发送消息,看看服务器会做哪些处理。因为我们的Netty是基于主从Reactor多线程的模型改进而来,我们就将本文分为bossGroup部分和workerGroup部分来叙述,我

2021-02-23 15:44:31 135

原创 Netty源码篇(一) 服务器启动源码分析

目录1.创建EventLoopGroup1.1 关于线程数的设置1.2 构造方法主体内容2.创建ServerBootstrap3.服务器启动3.1 initAndRegister()Netty是什么就不过多介绍了,源码分析的代码来自于netty源码包下的案例。今天分析的代码就是上面这一段,现在我们就开始分析服务端启动的源码流程。(在看源码之前希望大家能够了解Nio、三种Reactor模型等前置知识,这些可以帮助你进行源码理解。源码这个东西自己看的越多就越容易理解,大家坚持下去就一定能掌握)1.创建

2021-02-22 23:54:15 241

原创 Netty之自定义协议+编解码解决Tcp粘包拆包问题

什么是Tcp粘包和拆包问题?因为Tcp是面向连接的,面向流的,提供高可靠的连接服务,因此发送端为了将多个发送给接收端的包更加有效的发送给对方,就会使用一种优化算法(Nagle),将多次间隔较小的小数据包合并成一个大的数据块,然后进行封装。这样做虽然提高了效率,但是接收端就无法分辨出到底有多少个数据包。(面向流的)通信是无消息保护边界的。所以发送端发送的多个包可能被接收端当作一个包接收,这就是粘包问题。同时也可能一个包被拆开到多个包中,这就是拆包问题。如何解决?自定义协议+编解码如果通信的双方都知

2021-02-21 22:24:00 644

原创 JVM之记忆集和卡表

当我们进行young gc时,我们的gc roots除了常见的栈引用、静态变量、常量、锁对象、class对象这些常见的之外,如果老年代有对象引用了我们的新生代对象,那么老年代的对象也应该加入gc roots的范围中,但是如果每次进行young gc我们都需要扫描一次老年代的话,那我们进行垃圾回收的代价实在是太大了,因此我们引入了一种叫做记忆集的抽象数据结构来记录这种引用关系。什么是记忆集?记忆集是一种用于记录从非收集区域指向收集区域的指针集合的数据结构。如果我们不考虑效率和成本问题,我们可以用一个数组

2021-02-21 15:43:17 2722

原创 Google Protocol Buffer

目录1.protobuf是什么?2.使用protobuf传输指定类型2.1编写*.proto文件2.2使用protoc.exe解析出对应的Java源文件3.使用protobuf传输多种类型3.1 编写*.proto文件3.2解析出对应的Java源程序4.上述两种的测试代码1.protobuf是什么?protobuf(Google Protocol Buffers)是Google提供一个具有高效的协议数据交换格式工具库(类似Json),但相比于Json,Protobuf有更高的转化效率,时间效率和空间效率

2021-02-20 21:24:48 181

原创 BIO、NIO与netty的架构关系

目录1.BIO2.NIO3.Netty3.1 传统阻塞式IO模型3.2 Reator模型3.2.1单reactor单线程模型3.2.2单reactor多线程模型3.2.3主从reactor多线程模型3.3 netty架构模型3.4 Netty的执行流程1.BIOBIO的基本特点:BIO基本特点就是服务器在接收到客户端请求之前(accept方法)会进行阻塞,并且每接收到一个连接,都会新建一个线程去处理客户端的请求,并且读取客户端数据的过程是阻塞式的,如果没有读到对应的数据会一直等待。并且客户端数据发送完毕

2021-02-19 20:41:26 349

原创 JVM之CMS垃圾回收器

第一款真正意义上的并发垃圾回收器Concurrent Mark Sweep并发标记清除垃圾回收器垃圾回收的主要流程为以下1.初始标记:发生STW,初始标记阶段仅仅是标记一下GC roots能够直接引用的对象,就恢复用户线程的执行,因此暂停时间很短。2.并发标记:并发标记就是从初始标记过的那些对象出发,遍历整个对象图的过程。由于用户线程和标记线程一块执行,所以并发标记中存在一些问题:多标:原本是在对象整个引用链中的,在标记过后引用断开了,变成了垃圾对象,这种属于浮动垃圾,本次垃圾回收无法清理。漏

2021-02-18 13:03:00 214 2

原创 JVM之对象的四种引用

目录1.Java的四种引用2.强引用3.软引用4.弱引用5.虚引用6.终结器引用7.finalize方法调用后对象就被回收了吗?1.Java的四种引用我们平时创建对象直接返回的引用就是所谓的强引用。我们传统的强引用只能给对象两种状态:被引用|不被引用,但是对于下面的几个案例,我们的强引用却很难达到目的对于缓存这类存储空间,我们希望在空间允许的时候将其保留,空间不允许的时间将其进行回收如果我们程序中维护了一个Map<key,value>的引用,但是map中的某个键已经不能在程序的任何地方

2021-02-17 00:37:34 138

原创 JVM之安全点和安全区域

安全点JVM只有当程序运行到特定位置时才能暂停用户线程转入GC对应的流程,这个位置就是安全点。1.为什么要有安全点?我们针对于栈和方法区这种基本上固定为GC Roots的区域,因为我们区域空间很大,如果每次我们都线性遍历一遍区域找到所有的gc roots,这样太浪费我们的时间了,所以hotspot虚拟机就提供了一种OopMap的数据结构,在特定位置上记录下我们栈上哪些位置是引用,这样我们枚举GC roots的时候就不需要进行扫描,直接就能够得到对应的引用。这些位置就是安全点。2.安全点一般设立在什么

2021-02-16 21:03:45 630

原创 2020再见,你好2021

2020以最后一道算法题的提交画上了句号。2020时间线1 - 5 月:在家里浑浑噩噩,毫无长进5月21-8月15日:突然醒悟开始努力,慢慢接触到java的框架,第一次真正接触到算法,第一次写出自己的项目…8月15日-12月31日学校开学了,开始忙于学校的各种事情,渐渐又落下了学习Java,中间间歇性踌躇满志学了一丢丢算法和其他框架。元旦突然觉着自己好像没多少时间了,开始心慌,渐渐开始迁移自己的时间1月8日-至今:每天八点多起床,晚上十二点睡觉,除了吃饭睡觉,玩手机的时间加起来不超过30分钟.

2021-02-12 00:08:45 128 3

原创 Zookeeper分布式锁代码实现

分布式锁和普通锁有什么区别?普通我们单机程序解决线程安全问题可能会使用Synchronized关键字同步方法等对共享资源进行加锁,但是在分布式的场景下普通的内存锁明显不太适用了,因为我们需要进行同步的是多台机器的进程,所以其中单台机器的内存锁是无法达到这个目的的,所以我们需要分布式锁。zookeeper的分布式锁原理zookeeper存在一种节点类型为临时有序型节点,我们每个节点获取锁时我们都在指定路径("/locks")下创建一个临时有序节点("/lock_"),zookeeper会自动给我们的临时

2021-02-10 20:21:52 81

原创 JVM之对象创建内部流程一揽子知识点

我们平时都在创建对象,但是创建对象后面jvm和对应的内存结构发生了什么变化,本文主要记录这个过程,本文由个人笔记零零散散拼凑起来,稍显凌乱请见谅。1.对象创建流程Object obj = new Object();1.根据对象的全限定名去运行时常量池中寻找对应的符号引用,如果符号引用已经被解析为直接引用了,那么直接获取到类元信息,否则通过当前类加载器,在双亲委派机制下去寻找当前类全限定名的.class字节码文件,如果找不到class文件,则抛出classnotfoundexception异常,否则进

2021-02-06 12:04:15 71

原创 Springboot之内容协商

什么是内容协商?针对于标注了@responsebody的处理方法,我们服务器会根据浏览器的需要返回不同格式的响应数据,如json、xml这些。原理1.浏览器发送请求时,请求头会携带accept信息,表示浏览器所能接受的响应信息格式(带权重的)2.springboot会对控制器处理方法返回的类型进行处理,springboot底层通过messageConverter进行转换,我们springboot底层会统计出我们能转换的所有类型格式。上述两步的源码有兴趣的可以参照下面这张图片进行自行查找3.第

2021-02-02 22:49:50 516

原创 spring常见面试题

1、什么是Spring框架?Spring框架有哪些主要模块?Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的Java平台。Spring帮助开发者解决了开发中基础性的问题,使得开发人员可以专注于应用程序的开发。Spring框架本身亦是按照设计模式精心打造,这使得我们可以在开发环境中安心的集成Spring框架,不必担心Spring是如何在后台进行工作的。Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编

2021-01-23 21:55:55 114

原创 Spring源码分析

spring源码1.写在前面2.构造方法主要内容2.1 this()2.2 register3.refresh()3.1 prepareRefresh();3.2 obtainFreshBeanFactory()3.3 prepareBeanFactory3.4 postProcessBeanFactory3.5 invokeBeanFactoryPostProcessors()3.6 registerBeanPostProcessors3.7 initMessageSource();3.8 initApp

2021-01-23 21:31:53 100

原创 SpringAOP源码分析

目录写在前面写在前面今天我们主要分析springAOP的源码流程,因为博主本人习惯于使用AspectJ和注解的方式使用AOP,因此本次的分析是基于@EnableAspectJAutoProxy注解和cglib动态代理的AOP,

2021-01-20 19:50:25 185 2

原创 类初始化和对象创建过程

类初始化过程在我们的class字节码文件中,可以看到类初始化执行的是< clinit >方法及class init方法,该方法的主要内容如下:1.类的静态成员2.类的静态代码块执行顺序和声明顺序相同,并且< clinit >方法只会在类加载时执行一次。对象初始化过程对象初始化过程执行的是< init >方法,该方法的主要组成如下1.父类的初始化方法即父类的<init>方法2.普通成员或普通代码块 按顺序执行3.构造方法 注意点:1.类

2021-01-19 18:52:47 283

原创 Mybatis面试题总结

1.jdbc、mybatis、hibernate三者优缺点?JDBC:编写SQL – 预编译SQL – 设置参数 – 执行SQL – 封装结果JDBC的优缺点:执行效率高但是工作量大并且繁杂.Hibernate:[编写SQL – 预编译SQL – 设置参数 – 执行SQL – 封装结果]Hibernate优缺点:是一个ORM(Object relation Mapping)层的全自动框架,不需要我们写任何SQL语句,完全自动进行映射,但是对于复杂的查询情况,我们一般需要定制SQL和对SQL进行

2021-01-17 18:58:59 108

原创 Cannot find a valid baseurl for repo: base/7/x86_6 centOS6 yum失效

出现的错误YumRepo Error: All mirror URLs are not using ftp, http[s] or file. Eg. Invalid release/repo/arch combination/removing mirrorlist with no valid mirrors: /var/cache/yum/x86_64/6/base/mirrorlist.txtError: Cannot find a valid baseurl for repo: base原

2021-01-17 10:35:32 86

原创 基于REST风格URL的SSM_CURD

源码链接:https://pan.baidu.com/s/137AKqCO3yXoBHPldYgQPTg提取码:abcd编写版本:tomcat8+jdk1.8+spring4主要技术:SSM框架效果展示

2021-01-16 20:49:03 66

原创 mybatis之自定义插件

要写一个mybatis的插件,我们大概分为以下三步1.书写插件类,实现interceptor接口2.书写插件的方法标签(为四大对象的哪个方法执行拦截操作)3.在mybatis全局配置中配置我们书写的插件案例假设现在我们需要通过ID属性从数据库查询员工信息,我们通过自定义插件,使得每次查询的ID参数都被我们改为查询1号员工,实现偷梁换柱。插件类 @Intercepts({ @Signature(type = StatementHandler.class,

2021-01-14 19:15:30 427

原创 Mybatis从创建SQLSessionFactory到获取Mapper源码分析

目录1.写在前面2.获取SqlSessionFactory对象3.获取SqlSession对象4.获取Mapper1.写在前面(1).InputStream in = Resources.getResourceAsStream("mybatis-config.xml");(2).SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);(3).SqlSession sqlSession = sqlS

2021-01-13 22:43:21 1019

原创 Maven下mybatis和Spring整合

所需依赖<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <gro

2021-01-13 18:27:25 77

原创 Hibernate 的检索策略

类的检索策略设置于class元素的lazy属性,有true和false两种取值。默认为true。lazy为true:在load方法加载时会使用延迟检索,返回代理对象。lazy为false:在load方法加载会立即检索。一对多、多对多关系检索策略主要是针对于hbm映射文件的set元素的配置1.lazy属性lazy有三种取值1.true 默认的取值 只有在需要访问集合元素的属性或者集合大小时才对集合进行初始化2.false 不使用延迟加载 在初始化持久化对象时就将集合元素一起加载,不建议设置

2020-11-23 22:10:19 117

原创 Hibernate表与表之间的关系映射

一对多关系一个student有多个作业,所以student表中的记录和homework表中的记录形成1对多关系表中字段体现在homework表中具有S_ID字段,表示该记录对应的作业属于哪个学生1.单向一对多数据表Student表对应java中的Student类,homework表对应Homework类单向一对多是只从多的一段维护关联关系,即Homework类中存储了其对应的student的引用hbm映射文件的配置除了基础字段的映射,关联字段同样需要映射,多个homework对应一个st

2020-11-19 16:51:45 278

原创 hibernate篇:持久化对象的状态

站在持久化的角度,hibernate将对象分为四种状态。1.持久化状态 OID不为空,缓存中存在记录,数据库中也有响应的记录2.临时状态 在使用代理主键的情况下,OID通常为null 不在session的缓存中 数据库中没有相应的记录3.游离状态 OID不为null ,不在session的缓存中,数据库中可能还保留有响应的记录4.删除状态 数据库中没有和其OID相同的记录,不在session的缓存中1.save()方法save方法可以将临时对象转换为持久化对象可以看到在save

2020-10-21 21:13:21 234

原创 Hibernate篇:一级缓存

一级缓存为了减少对数据库的访问次数,提高查询效率,hibernate提供了一级缓存和二级缓存,这里先介绍一级缓存,一级缓存是session级别的。什么是一级缓存?执行上述语句,我们会发现hibernate只向数据库发送了一次select语句,这是因为存在一级缓存的缘故,所以第二次进行查询时,session会先在缓存中查询看是否存在该对象,如果存在则不会去数据库中进行查询。session缓存有关操作flush操作flush操作是指按照缓存中对象的属性变化来同步更新数据库。什么时候会执行fl

2020-10-21 15:06:12 100

原创 第九届蓝桥杯Java B组决赛赛题解析

目录1.三角形面积2.最大乘积3.全排列4.整理玩具5.版本分支6.防御力1.三角形面积标题:三角形面积已知三角形三个顶点在直角坐标系下的坐标分别为:(2.3, 2.5)(6.4, 3.1)(5.1, 7.2)求该三角形的面积。注意,要提交的是一个小数形式表示的浮点数。要求精确到小数后3位,如不足3位,需要补零。答案 : 8.795解法1:解法一也是我一开始下意识想到的解法 a* b*sinC /2,分别求出三条边的长度,sinC需要用余弦公式求出cosC 然后求出sinC

2020-09-21 19:59:43 388

空空如也

空空如也

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

TA关注的人

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