自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 java中的类路径classpath是什么?

classpath是java应用程序在运行时查找类文件、资源文件和库文件的路径集合类路径告诉jdk工具和应用程序在哪里可以找到第三方和用户自定义的类

2024-08-01 10:36:23 455

原创 is not null 、StringUtils.isNotEmpty和StringUtils.isNotBlank之间的区别?

is not null 只是说明该对象不为空,没有考虑是否为空串和空白字符串。这三者主要是针对对象是否为空、是否为空串和是否为空白字符串有不同的功能。StringUtils.isNotBlank除了检查字符串是否不为。选择使用哪个方法取决于具体的需求:如果只关心字符串是否有内容,使用。StringUtils.isNotEmpty检查字符串是否不为。且长度大于零,还要求字符串中不能只包含空白字符。如果还要确保字符串中有实际的非空白字符,使用。且长度大于零,不考虑字符串中的空白字符。

2024-06-15 08:07:39 392

原创 Mybatis简介

Mybatis是一个优秀的基于ORM的半自动轻量级持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身, 而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。2.针对于频繁创建释放数据库连接,使用数据库连接池。1.针对于数据库配置信息硬编码问题,使用配置文件。3.针对存在sql语句硬编码问题,使用配置文件。4.针对需要手动封装返回结果集,使用反射+内省。1.3 Mybatis实战入门。

2024-05-17 11:09:20 238

原创 在垃圾回收时哪些可以作为垃圾回收的根对象?

java虚拟机在执行方法调用时必须执行操作系统方法,操作系统方法执行时所引用的一些java对象。由启动类加载器加载的类,一些核心的类,不如说。活动线程所引用的一些对象。被同步监视器加锁的对象。

2024-03-10 14:48:55 261

原创 聊一聊ThreadLocal的原理?

因为ThreadLocalMap中的每一个key都是ThreadLocal弱引用,当发生垃圾回收时,不管JVM的内存空间是否充足,都会回收该对象占用的内存。每一个线程在往ThreadLocal里设置值的时候,都是往自己的ThreadLocalMap中设置值,读也是以某个ThreadLocal作为引用,在自己的map里找对应的key,从而实现线程隔离的作用。堆内存线程共享,存储了对象的实例。如果不弱引用,是强引用,当ThreadLocal释放掉内存后,ThreadLocal一直被key强引用着。

2024-03-07 20:33:49 309

原创 SpringMVC发送请求原理

浏览器发送请求,若请求地址符合前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet处理。前端控制器读取SpringMVC的核心配置文件,通过扫描组件找到控制器,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称。

2024-02-28 10:08:19 154 1

原创 MVC是什么

用户通过视图层发送请求到服务器,Controller接收请求,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器。C: Controller, 控制层,指工程中的servlet,作用是接收请求和响应浏览器。V: View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据。M: Model,模型层,指工程中是的javaBean,作用是处理数据。

2024-02-25 19:20:21 159

原创 AOP的前世今生

那就产生了大量重复的代码,日志功能还是分散的,没有统一的管理。它的作用是提供一个代理类,让我们在调用目标方法的时候,不是直接调用目标方法,而是通过代理方式间接调用。让不属于目标方法的核心逻辑代码从目标方法中剥离出来,以达到解耦的操作。1.静态代理类是会建立多个的,因为代码都写死了。不管你是什么类,什么接口,如下图所有,这个逻辑就是在目标方法前、目标方法后都会执行日志操作。要抽取的代码在方法内部,靠以前抽取重复的代码部分到父类的方式没法解决。1)核心业务代码和日志混合在一起,在开发时会分散精力。

2024-02-25 13:18:12 187

原创 1.手写IOC实现Bean创建过程

5.实现bean 容器接口,根据包规则扫描加载Bean,这是在实现@Bean。对于@Di来说,遍历所有的Bean对象,判断其上是否有@Di注解,如果有,则赋值。4.创建Bean容器接口ApplicationCOntext,定义方法。2.创建测试类 (service dao)@Bean 创建对象。

2024-02-24 22:18:01 205

原创 @Resource注入和@Autowired注入有什么区别

3.@Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name.通过name找不到的话会自动启动通过类型byType装配。1.@Resource注解是jdk扩展包中的,也就是说属于JDK的一部分。4.@Autowired注解默认根据类型装配,如果想根据名称装配,需要配合@Quanlifier注解一起用。6.@Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。@Resource注解也可以完成属性注入,那它和@Autowired注解有什么区别?

2024-02-24 20:34:24 182

原创 Bean的声明周期

首先要定义一个类MyBeanPost,实现BeanPostProcessor接口,然后重写后置处理器的初始化前方法以及初始化后方法。最后在IOC容器中配置后置处理器。3.bean后置处理器(初始化前执行,类似于过滤器和拦截器)4.bean对象初始化(调用指定的初始化方法)2.给bean对象设置相关属性(依赖注入)7.bean对象销毁(配置指定的销毁方法)1.创建Bean对象(调用无参数构造)5.bean后置处理器(初始化之后)6.bean对象创建完成,可以使用了。8.IOC容器关闭了。

2024-02-24 17:24:12 151

原创 Spring的优点

Spring就是一个容器,可以将所有对象创建和关系维护交给Spring管理。面向切面编程,方便实现程序进行权限拦截,运行监控等功能。通过配置完成事务的管理,无需手动编程。5.方便集成各种优秀的框架。1.方便解耦,简化开发。3.声明式事务的支持。

2024-02-24 14:24:51 255

原创 类的加载过程

编写好java程序后,首先由java.exe程序编译为.class字节码文件,然后类加载器将字节码文件加载至内存并生成java.lang.Class实例。执行类构造器的过程。这个过程是对所有的类变量进行赋值动作以及静态代码块的执行。正式为类变量(static)分配内存并设置默认值。虚拟机的常量池中的符合引用替换为直接引用。确保加载的类信息符合JVM规范。

2024-02-22 22:29:43 120

原创 面向对象的三大特征

编译时多态是指在编译时就能确定方法的调用对象和参数类型,这种动态称为静态多态。比如方法的重载,是一种编译时多态,编译器根据方法的参数类型和参数个数来确定调用哪一个对象。是指根据已创建的类的定义作为基础创建新的类,新创建的类可以增加新的属性和方法。运行时多态是指在运行时根据对象的实际类型来确定方法的调用对象和参数类型。这种多态也称为运行时多态。所谓多态是指同一个方法在不同的对象上有不同的行为。多态包括两种形式:编译时多态和运行时多态。封装就是把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法。

2024-02-18 20:21:25 157

原创 面向过程和面向对象的方式?

面向对象:把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个步骤,而是为了描述某个事件在整个问题所发生的行为。这样做可以提高代码的复用性。面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤逐个实现,然后一个一个地进行调用就好了。如果是面向对象,则会根据构建对象分解成两个对象:一个是人,一个是洗衣机。人负责打开洗衣机,把衣服放进洗衣机,放入洗衣液。这个例子应该可以解释清楚这个问题。洗衣机负责清洗和甩干。2.把衣服放进洗衣机。

2024-02-18 18:00:02 402

原创 创建线程实现火车站多窗口买票问题

(2)通过实现Runnable的方式实现,使用同步代码块,这个同步监视器可以直接使用this.因为实现runnable接口的实现类的对象只有一个,可以实现同步机制。这里要非常注意如果使用同步代码块,这个同步监视器的对象,如果是继承方式实现的,那么就要使用CreateThread.class.2.多个线程(多个窗口)卖票这里要考虑线程安全问题,不然会出现错票和重票的问题。(2)通过实现runnable的方式。(1)通过继承Thread类的方式。(1)通过继承thread类实现。1.首先要知道创建线程的方式。

2024-02-15 21:13:31 514

原创 Redis哨兵模式

背景:slave节点宕机了恢复后可以找master节点同步数据,那master节点宕机了怎么办?master宕机了,数据如何同步。而且master宕机了,无法执行写操作。这个时候就引入了Redis哨兵模式。哨兵(Sentinel)模式机制来实现主从集群的自动故障恢复。从上图可以看出:Sentinel集群模式,为什么Sentinel会有集群模式,这是因为可能Sentinel单节点会出现宕机的状态。

2024-01-11 15:28:29 394

原创 Redis主从复制底层原理

执行replicaof命令或者执行slaveof(slaveof ip port )建立连接,连接一旦建立,slave就可以向master发请求数据同步,此时,我发送replid offset,master判断replid是否和我的id一直,如果不一致,那说明是第一次连接,我返回我的id和offset.slave保存版本信息。在生成RDB文件,发送RDB文件期间,可能仍然会有数据写入,这一部分操作的命令全部写入repl_backlog.第三阶段就是发送repl_baklog中的命令。

2024-01-10 16:13:56 414

原创 Redis的持久化方式

AOF记录的是所有的写操作,如果说一个操作写很多次也会记录下来,因此aof文件的大小一定比rdb大。在执行bgsave时,主进程fork子进程,将页表复制过去,由于子进程共享父进程的页表,因此,子进程也能通过页表访问物理内存,从而写入新的RDB文件。主进程不能直接操作物理内存,而是操作虚拟内存,而虚拟内存通过页表间接操作物理内存,从而实现对物理内存的读写。1.如果每60save一次,如果在60s内执行写操作,一旦宕机,这数据就丢失了。当主进程执行写操作时,则会拷贝一份数据,执行写操作。

2024-01-10 15:22:02 557

原创 单节点的redis会有什么问题?

业务对redis的依赖越来越多,不仅仅是缓存,有时候是分布式session,一旦发生故障,对整个微服务的影响的范围就很大。Redis主要作用是分布式锁和分布式缓存,今天主要讲单节点的Redis会有什么问题?虽然单节点的并发能力虽然不错,但是也无法满足像68这样的高并发场景。Redis是基于内存,单节点能存储的数据量难以满足海量数据的需求。3.故障恢复的问题(哨兵机制,实现健康检测和自动恢复)4.存储能力问题(搭建分片集群,利用插槽机制实现do)2.并发能力的问题(搭建主从集群,实现读写分离)

2024-01-09 23:02:13 440

原创 怎么理解进程和线程?

进程可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如网易云音乐、360安全卫士等)就是因为如果一个子类需要继承其他的类,上面的方式就无法实现,所以引入Runnable接口的形式。通过Thread类的子类对象调用start()方法,会做两件事,1是启动一个新线程,2是调用run方法。3.将此对象传递到Thread类的构造器中,创建Thread类的实例t1。当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。

2024-01-06 22:50:45 368

原创 缓存更新策略

如果你访问的数据redis和数据库都没有,我就赋一个空值,下次来访问的时候就不至于缓存失效,但是这有一个问题,就是要给空值赋予一个过期时间,因为访问的数据在数据库中出现的时候,就要更新到redis当中。这个逻辑过期并不是真的过期,是通过给对象添加一个expire字段,这个字段值比如在当前时间+30,判断如果当前时间大于expire,这个时候就过期了,这个时候先获取锁,然后开启一个新线程进行缓存重建,当完成的时候,这个新线程释放锁。首先从redis当中,查询商铺信息,判断是否命中,如果未命中,返回空。

2024-01-05 21:00:48 892

原创 聊一聊为什么需要缓存?

如果没有缓存,我们查询的所有数据都要在数据库上面,我们都知道查询数据库需要磁盘IO,这样性能非常低。为了提高读写效率,降低响应时间,而且可以降低后端的负载。但是缓存又会带来一些问题:比如一致性问题,我们为了解决一致性问题,需要代码维护成本。缓存就是数据交换的缓冲区,是存储数据的临时地方,一般读写性能较高。

2024-01-04 22:03:15 436

原创 [Redis] 五种数据结构

如果需要写redis命令,可以从这里取。下次具体讲解这五种数据结构的底层实现。

2024-01-04 21:02:50 366

原创 Arrays.sort()方法到底用的是什么排序?

当数组长度1<=n<=47时,使用插入排序。当数组长度47<=n<=286,使用快速排序。当n>286时,使用归并或者快排(有一定的顺序使用归并,若无顺序使用快排)。

2023-12-29 23:46:39 416

原创 【JVM】类的加载过程

为static变量分配空间,赋值在初始化阶段,但如果是基本数据类型,在这个阶段。如果是引用数据类型,则在初始化阶段。javac将.class编译成字节码文件,然后由类加载器加载到方法区中,加载过程就完成了。访问类的static final (基本数据类型和字符串)不会触发。将常量池中的符号引用改为直接引用。1.main方法所在的类总是会被先初始化。2.首次访问这个类的静态变量或静态方法。3.子类初始化,但是父类还没有初始化。类对象.class不会触发初始化。类加载器加载字节码文件。

2023-12-29 23:30:44 367

原创 集合框架的起源

2.数组中存储数据特点的单一性,不适合无序的,不可重复的场景就不适用了.这里讲一讲为什么会有这个集合框架,这个集合框架的作用是什么?2.数组中的多个元素是依次紧密排列的,有序的,可重复的。我们存储数据一般是使用数组,数组有如下的特点;3.数组一旦初始化完成,其元素的类型就是确定的。1.数组一旦初始化完成,其长度就不可变了。1.数组一旦初始化,其长度就是确定的。因此,引入集合框架解决上述数组的问题。4.插入和删除元素性能较差。3.数组没有过多的api。

2023-12-27 20:22:35 429 1

原创 G1 Garbage First(为什么叫Garbage First)

刚开始都是小区域的白色的未使用的内存,随着对象的创建,这些对象会被放入伊甸园区,当这个内存逐渐被占满,那这个时候会进行一次垃圾回收,这个时候会将Eden区复制进幸存区(两个区域之间使用复制算法)并对这个对象赋值年龄。从jdk9开始,CMS就被弃用,使用G1代替CMS,同时注重高吞吐和低延时的特点,默认的暂停目标是200ms。2.智能优先级调整:G1会根据垃圾回收情况动态调整垃圾回收的优先级,每次回收时都选取垃圾最多的区域,这样就有利于在规定的时间内提高吞吐量。为什么叫G1,优先回收垃圾最多的区域。

2023-12-25 10:13:21 493

原创 java中的Comparable 和Comparator

我将从背景和使用两个方面去讲述。

2023-12-20 20:32:06 388 1

原创 【JVM】三种垃圾回收器

第一个参数是控制新生代大小,第二个参数是控制垃圾回收时间和总时间的一个占比1/1+radio,比如说radio为99,垃圾回收时间不能超过总时间的1%,第三个参数是最大暂停时间,这里默认是200ms,第四个参数是线程数。首先讲一讲如何保证的每一次stw时间很短的,因为除了初始标记和重新标记之外会stop the world,其他时候都是和用户并发进行的,因此stw的时间就缩短了,但是其吞吐量减少了,因为有一个线程用来作为垃圾回收线程,因此相比于吞吐量优先垃圾回收器,少了一个线程执行任务。

2023-12-10 10:51:48 82 1

原创 垃圾回收算法&分代垃圾回收

当对象被创建的时候,会首先放在伊甸园区,随着对象一直被创建,伊甸园区会被逐渐放满,当出现新生代内存不足时,此时会发生MinorGC(这个时候会stop the world),首先标记没有被GCRoot引用的对象,将引用的对象放入幸存区中的to区,并且对其年龄计数+1.然后交换from。与标记清除同样的做法,扫描堆区的对象,先标记,然后在清除的过程中将可用的对象向前移动,使内存更紧凑,这样连续的空间就比较多了。首先标记,然后将存活的对象移动到to区,然后清理掉from区,最后实习交换。

2023-12-09 18:57:19 411

原创 【jvm】五种引用

当该对象没有被强引用引用时,虚拟机会创建终结器引用,当这个对象被垃圾回收时,终结器引用对象被加入到引用队列当中,这个时候对象并没有被回收,等到引用队列有个优先级比较低的finalizeHandler线程在某个时间找到新加入的终结器引用对象,这个时候进行垃圾回收该对象。当没有强引用ButeBuffer对象时,会被垃圾回收掉,但是直接内存是堆外内存,并不会被垃圾回收掉,此时,Cleaner虚引用对象会被放入到引用队列当中。弱引用的特点就是当发生垃圾回收时,不管内存是否足够,这个对象都会被垃圾回收掉。

2023-12-09 15:32:58 54

原创 【垃圾回收】如何判断垃圾可回收?

记录每一个对象的引用次数,如果一个对象被其他变量所引用,那么这个变量的计数+1,如果这个对象被引用两次则计数为2。如果某一个变量不再引用它,那么计数就减一。但是这种情况有个问题,如果A引用B,B也引用A,存在循环引用,但是这两个对象没有人引用他们,但他们计数为1,这种情况下无法进行垃圾回收。可达性分析算法是判断哪些对象是根对象的算法,在垃圾回收之前对堆内所有对象进行扫描,首先要确定根对象,哪些可以作为根对象?3.Thread 活动线程中引用的一些对象(活动线程执行过程中,局部变量所引用的对象作为根对象)

2023-12-08 17:08:43 66

原创 JVM【直接内存】

一个应用程序如何读取数据,用户态不能直接操作操作系统,由用户态切换为内核态,然后执行io操作,这个时候将磁盘文件数据读取到系统内存的系统缓存区,但是java并不能直接读取系统缓存区的数据,这个时候要将系统缓存区复制一份数据到java缓冲区,这样效率就不高,因此,引入了直接内存,这个直接内存就是相当于在系统缓存区和java缓存区搭了一个桥梁,是互通的,在这种情况下,磁盘文件直接上传到直接内存当中,然后内核态读取。但是直接内存不受JVM内存回收管理,需要unsafe进行内存的回收和释放。

2023-12-08 09:42:30 32

原创 Kafka如何消费数据

单独的消费者可以消费多个分区数据,也可以通过消费者组中的一个消费者消费。消费者消费了数据会将offset,提交到_consumer_offsets当中。由图可以看出,首先生产者发送数据到broker的leader分区,然后副本进行同步,消费者有两种形式,一种是一个是单独的消费者,一种是消费者组。

2023-12-07 22:04:27 167

原创 【JVM】虚拟机栈

如果局部变量没有逃离方法之外,它是线程安全的,它逃离了,就是非线程安全,比如传参的时候传递了一个对象,这里引用,在方法外仍然可以对该对象的修改.或者返回一个对象的引用。这个也同样的不知道如何去分析,首先看到栈内存是线程运行时所占用的内存,如果栈内存分配越多,每个线程运行时所占用的内存就大,而物理内存是固定的,线程就会减少。栈是方法调用产生的内存,方法一旦调用完成,就弹栈,这个时候就不需要垃圾回收。2.每个虚拟机栈都有很多栈帧,栈帧是每个方法执行所需要的内存。要么就是栈帧过大,超过了栈的大小。

2023-12-05 16:12:10 37

原创 JVM程序计数器

我将从背景和策略两部分去说明:1.java源代码首先通过javac编译器编译成字节码文件(如下图所示)解释器将字节码文件解释成机器码,才可以通过cpu执行成功。那程序计数器的作用是什么呢?程序计数器是记住下一条jvm指令的执行地址。当cpu执行jvm指令时,此时程序计数器记录了下一条执行指令的地址。

2023-12-04 22:38:23 180

原创 kafka如何高效读写数据

当生产者发送消息的时候,往里面进行写数据的时候,直接写如缓存中,当读数据的时候,先看页缓存中有没有,如果有直接返回,如果没有,从磁盘中读入数据,然后通过网卡直接返回给消费者。0拷贝:kafka应用层不关心存储的数据,由生产者对数据操作,由消费者对数据进行消费处理。1.kafka本身是个分布式集群,可以采用分区技术,并行度高。2.读数据采用稀疏索引,可以快速定位要消费的数据。4.使用页缓存+0拷贝(这个是重点)3.使用顺序磁盘IO。

2023-12-04 21:49:06 138

原创 Kafka中节点故障挂了怎么办?

在讲这个之前,首先介绍两个概念每个副本的最后一个offset,LEO就是最新的offset+1所有副本中最小的LEO.如果follower挂了,首先会从isr中退出,在这期间Leader和Follower继续接收数据,等到follower恢复之后,首先找到hw,并将log文件高于HW的部分截取掉,从HW开始向Leader进行同步。其实这里有个问题,就是为什么要将log文件高于HW部分截取掉,不直接向Leader进行同步,因为Leader始终是数据比较多的?

2023-12-04 21:23:11 876

原创 Kafka中Follower挂了怎么办

2023-12-04 20:43:07 36

空空如也

空空如也

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

TA关注的人

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