自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JVM进阶之路(七)垃圾收集器盘点

在前面,我们已经了解了JVM的分代收集,知道JVM垃圾收集在新生代主要采用标记-复制算法,在老年代主要采用标记-清除和标记-整理算法。接下来,我们看一看JDK默认虚拟机HotSpot的一些垃圾收集器的实现。

2025-07-06 08:00:00 785

原创 JVM进阶之路(六)垃圾收集理论和算法

在前面我们了解了虚拟机如何判断对象可回收,接下来我们了解Java虚拟机垃圾收集的一些理论和算法。

2025-07-05 09:15:00 939

原创 JVM进阶之路(五)垃圾回收概述和对象回收判定

垃圾收集(Garbage Collection,简称GC)简单说,就是要干三件事:哪些内存需要回收?什么时候回收?如何回收?在Java的内存区域中:程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作,所以这几个区域的内存回收是确定的,随着方法结束或者线程结束,内存自然回收。

2025-07-05 09:00:00 531

原创 JVM进阶之路(四)直面内存溢出和内存泄漏

在Java中,和内存相关的问题主要有两种,和。

2025-07-05 08:45:00 827

原创 JVM进阶之路(三)探究虚拟机对象

例如在64位的HotSpot虚拟机中,如对象未被同步锁锁定的状态下,Mark Word的64个比特存储空间中的31个比特用于存储对象哈希码,4个比特用于存储对象分代年龄,2个比特用于存储锁标志位,在其他状态(轻量级锁、重量级锁、偏向锁)下对象的存储内容变化如图示。如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是如果数组的长度是不确定的,将无法通过元数据中的信息推断出数组的大小。

2025-07-05 08:30:00 545

原创 JVM进阶之路(二)Java内存区域

考虑到HotSpot未来的发展,在JDK 6的 时候HotSpot开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了 JDK 8,终于完全废弃了永久代的概念,改用与JRockit、J9一样在本地内存中实现的元空间(Meta-space)来代替,把JDK 7中永久代还剩余的内容(主要是类型信息)全部移到元空间中。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。

2025-07-05 08:15:00 525

原创 JVM进阶之路(一)Java虚拟机概览

JVM是整个Java平台的基石。JVM可以看作抽象的计算机。编译器将Java文件编译为Java字节码文件(.class),接下来JVM对字节码文件进行解释,翻译成特定底层平台匹配的机器指令并运行。JVM和Java语言没有必然的联系,它只与class文件格式关联。也就是任何语言,只要能编译成符合规范的字节码文件,都是能被Jvm运行的。也就是说JVM是跨语言的平台。

2025-07-05 08:00:00 645

原创 面试官问:“在项目中用过多线程吗?”你就把这个案例讲给他听!

要说线程,必先说进程。进程是程序的⼀次执⾏过程,是系统运⾏程序的基本单位,因此进程是动态的。系统运⾏⼀个程序即是⼀个进程从创建,运⾏到消亡的过程。线程与进程相似,但线程是⼀个⽐进程更⼩的执⾏单位。⼀个进程在其执⾏的过程中可以产⽣多个线程。与进程不同的是同类的多个线程共享进程的堆和⽅法区资源,但每个线程有⾃⼰的程序计数器、虚拟机栈和本地⽅法栈,所以系统在产⽣⼀个线程,或是在各个线程之间作切换⼯作时,负担要⽐进程⼩得多,也正因为如此,线程也被称为轻量级进程。

2025-07-04 13:19:32 548

原创 MySQL索引由浅入深

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。通俗来讲,索引类似文章的目录,用来提高查询的效率。它是 B Tree 的变种,B Tree 能解决的问题,它都能解决。B Tree 解决的两大问题是什么?(每个节点存储更多关键字;路数更多)

2025-07-04 13:09:56 976

原创 这些不可不知的JVM知识,我都用思维导图整理好了

JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识。

2025-07-04 13:08:31 879

原创 synchronized详解

在Java中,锁可能是我们最早接触的锁了,在 JDK1.5之前synchronized是一个重量级锁,相对于juc包中的Lock,显得比较笨重。庆幸的是在 Java 6 之后 Java 官⽅对从 JVM 层⾯对进行⼤优化,所以现在的 synchronized 锁效率也优化得很不错。 的作用主要有三:Synchronized主要有三种用法:(1)、修饰实例方法: 作用于当前对象实例加锁,进入同步代码前要获得 当前对象实例的锁复制代码 (2)、修饰静态方法: 也就是给当前类加锁,会作用于类的所有对象

2025-07-04 13:04:22 545

原创 盘点分布式文件存储系统

在开始介绍分布式存储之前,先了解一下,非分布式的存储方案。在单机时代,将文件直接存储在服务部署的服务器上——直连存储(DAS):存储和数据直连,拓展性、灵活性差。为了扩展,将文件和服务分离,通过网络连接——中心化存储(NAS、SAN):设备类型丰富,通过网络互连,具有一定的拓展性,但是受到控制器能力限制,拓展能力有限。同时,设备到了生命周期要进行更换,数据迁移需要耗费大量的时间和精力。

2025-07-04 13:02:28 542

原创 思维导图整理Java并发基础

乐观锁和悲观锁是在数据库中引入的名词,但是在并发包锁里面引入了类似的思想。悲观锁指对数据被外界修改持保守态度,认为数据很容易就会被其他线程修改,所以在数据被处理前先对数据进行加锁,并在整个数据处理过程中,使数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制,即在数据 ,在对数据记录操作前给记录排它锁。如果获取锁失败, 则说明数据正在被其它线程修改,当前线程则等待或者抛出异常。如果获取锁成功,则对记录进行操作 ,然后提交事务后释放排它锁。

2025-07-04 13:00:25 607

原创 一张脑图整理Docker常用命令

:Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。其它的指令还有ENTRYPOINT、ARG、VOLUME、WORKDIR、USER、HEALTHCHECK、ONBUILD、LABEL等等。Dockerfile 是一个文本格式的配 文件,用户可以使用 Dockerfile 来快速创建自定义的镜像。一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

2025-07-04 12:58:21 892

原创 什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?

首先看看幂等性的概念:同一个接口,多次发出同一个请求,必须保证操作只执行一次。调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。比如下面这些情况,如果没有实现接口幂等性会有很严重的后果: 支付接口,重复支付会导致多次扣钱;订单接口,同一个订单可能会多次创建。

2025-07-04 12:55:34 539

原创 StringBuilder/StringBuffer源码阅读笔记

这里我们先看一下AbstractStringBuilder这个类,StringBuilder、StringBuffer中的很多方法都是调用它们的父类。

2025-07-03 22:31:03 149

原创 Java Review(三十九、类加载机制与反射)

例如, 如果在 pg 的包中有一个名为 Person 的类, 被类加载器 ClassLoader 的实例 kl负责加载, 则该 Person 类对应的 Class 对象在 JVM 中表示为 Person、pg、kl ) 这意味着两个类加载器加载的同名类: (Person 、pg、 kl ) 和( Person、 pg、 kl2) 是不同的, 它们所加载的类也是完全不同、互不兼容的。在 Java 中, 一。类加载器负责加载所有的类, 系统为所有被载入内存中的类生成java.lang.Class 实例。

2025-07-03 21:52:48 503

原创 Java Review(三十六、IO)

其他程序一旦获得了这种二进制流( 无论是从磁盘中获取的, 还是通过网络获取的), 都可以将这种二进制流恢复成原来的 Java 对象。新 IO 和传统的IO有相同的目的, 都是用于进行输入/输出, 但新 IO 使用了不同的方式来处理输入/输出, 新 IO 采用内存映射文件的方式来处理输入/输出, 新 IO 将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了( 这种方式模拟了操作系统上的虚拟内存的概念), 通过这种方式来进行输入/输出比传统的输入/输出要快得多。

2025-07-03 21:51:48 792

原创 Java Review(三十五、注解)

©Documented 用于指定被该元注解修饰的注解类将被 javadoc 工具提取成文档, 如果定义注解类时使用了©Documented 修饰, 则所有使用该注解修饰的程序元素的 API 文档中将会包含该注解说明。必须编写代码来使用注解。注解不仅可以是这种简单的注解, 还可以带成员变量, 成员变量在注解定义中以无形参的方法形式来声明, 其方法名和返回值定义了该成员变量的名字和类型。使用注解修饰了类、 方法、 成员变量等成员之后, 这些注解不会自己生效, 必须由开发者提供相应的工具来提取并处理注解信息。

2025-07-03 21:50:06 796

原创 Java Review(三十四、JDBC)

一旦在 MySQL 的命令行窗口中输入 set autocommit=0 开启了事务, 该命令行窗口里的所有 DML语句都不会立即生效, 上一个事务结束后第一条 DML 语句将开始一个新的事务, 而后续执行的所有 SQL语句都处于该事务中, 除非显式使用 commit 来提交事务, 或者正常退出, 或者运行 DDL、 DCL 语句导致事务隐式提交。因此不仅安全, 而且编程十分简单。除 JdbcRowSet 需要保持与数据库的连接之外, 其余 4 个子接口都是离线的 RowSet, 无须保持与数据库的连接。

2025-07-03 21:48:50 968

原创 Java Review(三十三、异常处理----补充:断言、日志、调试)

对于包来说,一个包的名字与其父包的名字之间没有语义关系,但是日志记录器的父与子之间将共享某些属性。在一个专业的应用程序中,不要将所有的日志都记录到一个全局日志记录器中,而是可以自定义日志记录器。当断言被禁用时, 类加载器将跳过断言代码, 因此,不会降低程序运行的速度。这条命令将开启 MyClass 类以及在 com.mycompany.mylib 包和它的子包中的所有类的断言。另外, 还可以使用 Level.ALL 开启所有级别的记录, 或者使用 Level.OFF 关闭所有级别的记录。

2025-07-03 21:46:51 559

原创 Java Review(三十一、泛型)

根据前面的 List接口定义的代码可以发现 : add()方法有类型参数 E 作为集合的元素类型,所以传给 add 的参数必须是 E 类的对象或者其子类的对象。假设实现一个工具方法:实现将 src 集合中的元素复制到 dest 集合的功能,因为 dest 集合可以保存 src 集合中的所有元素,所以 dest 集合元素的类型应该是 src 集合元素类型的父类。不管 src 集合元素的类型是什么,只要 dest 集合元素的类型与前者相同或者是前者的父类即可,此时通配符的下限就有了用武之地。

2025-07-03 21:45:54 703

原创 Java Review (三十、集合----- 操作集合的工具类: Collections)

Java 提供了一个操作 Set 、 List 和 Map等集合的类:Collections , 该工具类里提供了大量方法对集合元素进行排序、 查询和修改等操作,还提供了将集合对象设置为不可变、对集合对象实现同步控制等方法。Collections 类中提供了多个 synchronizedXxxO方法,该方法可以将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题。Collections 还提供了如下常用的用于查找、替换集合元素的类万法。

2025-07-03 21:43:33 951

原创 Java Review (二十八、集合----- Queue 集合)

之所以说它是比较标准的队列实现 , 而不是绝对标准的队列实现 , 是因为 PriorityQueue 保存队列元的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。Deque 接口提供了 一个典型的实现类: ArrayDeque ,从该名称就可以看出 , 它是一个基于数组实现的双端队列,创建 Deque 时同样可指定一个 numElements 参数 , 该参数用于指定 Object[]数组的长度 :如果不指定 numElements 参数, Deque 底层数组的长度为 16。

2025-07-03 21:43:01 895

原创 Java Review (二十七、集合----- List 集合)

执行①行代码时 ,程序试图删除一个 A 对象 , List 将会调用该A对象的equals()方法依次与集合元素进行比较,如果该 equalsO方法 以某个集合元素作为参数时返回 true , List将会删除该元素——A 类重写了 equalsO方法 , 该方法总是返回 true。ArrayList 和 Vector 在用法上几乎完全相同 ,Vector十分古老,那时候 Java 还没有提供系统的集合框架,所以 Vector 里提供了 一 些方法名很长的方法。,无须程序保证该集合的同步性。

2025-07-03 21:41:32 563

原创 Java Review (二十六、集合----- Set 集合)

如果有两个元素通过 equals()方法比较返回 true,但它们的 hashCode()方法返回值不相等, HashSet 将会把它们存储在不同的位置,由此应该注意一个问题 : 当需要把一个对象放入 TreeSet中, 重写该对象对应类的 equals()方法时,应保证该方法与 compareTo(Object obj)方法有一致的结果,其规则 是 : 如果两个对象通过 equals()方法比较返回 true 时,这两个对象通过 compareTo(Object obj)方法比较应返回 0。

2025-06-30 21:20:35 961

原创 Java Review (二十五、集合----- Iterator接口)

Iterator接口 也是 Java 集合框架的成员 , 但它与 Collection 系列 、 Map 系列 的集合不 一样 : Collection系列集合、 Map 系列集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问) Collection集合中的元素, Iterator 对象也被称为。Iterator 接口隐藏了各种 Collection实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。

2025-06-30 21:19:55 234

原创 Java Review (二十四、集合-----Collection 接口)

Collection 接口是 List 、 Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合 ,也可用于操作 List 和 Queue 集合。集合类就像容器,现实生活中容器的功能, 无非就是添加对象、删除对象、清空容器、判断容器是否为空等,集合类就为这些功能提供了对应的方法。

2025-06-30 21:19:21 227

原创 Java Review (二十三、集合-----概述)

Java 的集合类主要由两个接口派生而出 : Collection 和 Map , Collection 和 Map 是 Java 集合框架的根接口,这两个接口又包含了一些子接口或实现类。Map 与此类似, Map里的 key 是不可重复的, key 用于标识集合里 的每项数据,如果需要查阅 Map中的数据时,总是根据 Map 的 key 来获取。他们希望将传统的类融人新的框架中。与所有的集合类库设计者一样, 他们必须做出一些艰难的选择,于是,在整个设计过程中,他们做出了一些独具特色的设计决定。

2025-06-30 21:18:41 265

原创 Java Review (二十二、正则表达式)

所以,在其他的语言中(如Perl),一个反斜杠 \ 就足以具有转义的作用,而在 Java 中正则表达式中则需要有两个反斜杠才能被解析为其他语言中的转义作用。也可以简单的理解在 Java 的正则表达式中,两个 \ 代表其他语言中的一个 \,这也就是为什么表示一位数字的正则表达式是 \d,而表示一个普通的反斜杠是 \\。通过 Matcher 类的 findO和 groupO方法可以从目标字符串中依次取出特定子串(匹配正则表达式的子串),例如互联网的网络爬虫,它们可以自动从网页中识别出所有的电话号码。

2025-06-30 21:18:01 911

原创 Java Review (二十一、基础类库----日期、时间类)

但 Date 不仅无法实现国际化 ,而且它对不同属性也使用了前后矛盾的偏移量 ,比如月份与小时都是从 0 开始的,月份中的天数则是从 1 开始的,年又是从 1900 开始的,而java.util.Calendar 则显得过于复杂 ,从下面介绍中会看到传统 Java 对日期、时间处理的不足。它本身不能直接实例化,程序只能创建 Calendar 子类的实例, Java 本身提供了 一个 GregorianCalendar 类,一个代表格里高利日历的子类,它代表了通常所说的公历。

2025-06-30 21:17:15 941

原创 Java Review (二十、基础类库----常用类:Object、String、StringBuffer、StringBuilder、Math)

静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。在某些情况下,也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类(有的地方也叫嵌套类),包含内部类的类也被称为外部类(有的地方也叫宿主类)。外部类想访问成员内部类的成员是受到限制的。

2025-06-30 21:15:52 453

原创 Java Review (十九、基础类库----系统相关类)

System 类代表 当 前 Java 程序的运行平台,程序不能创建 System 类的对象, System 类提供了 一 些类变量和类方法,允许直接通过 System 类来调用这些类变量和类方法。System 类提供了代表标准输入、标准输出和错误输出的类变量,并提供了 一些静态方法用于访问环境变量、系统属性的方法,还提供了加载文件和动态链接库的方法。Runtime 类代表 Java 程序的运行 时环境,可以访问JVM的相关信息,如处理器数量 、 内存信息等。

2025-06-30 21:15:20 605

原创 Java Review (十八、面向对象----对象与垃圾回收)

通知系统进行垃圾回收,如果系统立即进行垃圾回收,那么就会将弱引用 WT 所引用的对象回收。当程序强制垃圾回收后,只有虚引用引用的字符串对象将会被垃圾回收,当被引用的对象被回收后,对应的虚引用将被添加到关联的 引用队列中,因而将在②代码处看到输出 true。而 Java 堆不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,只有在程序处于运行期间时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,Java的垃圾回收机制所关注的是这部分内存。

2025-06-30 21:13:49 969

原创 Java Review (十七、面向对象----枚举类)

枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或者多个接口,也可以定义自己的构造器。如果需要每个枚举值在调用该方法时呈现出不 同 的行为方式 , 则可以让每个枚举值分别来实现该方法 , 每个枚举值提供不同的实现方式,从而让不同的枚举值调用该方法时具有不同的行为方式。定义枚举类时,需要显式列出所有的枚举值,如上面的SPRING,SUMMER,FALL,WINTER所示,所有的枚举值之间以英文逗号 , 隔开,枚举值列举结束后以英文分号作为结束。下面是 Gender 枚举类的代码。

2025-06-30 21:13:18 884

原创 Java Review (十六、面向对象----Lambda 表达式)

如果采用匿名内部类语法来创建函数式接口的实例,则只需要实现一个抽象方法,在这种情况下即可采用 Lambda 表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口。Lambda 表达式的类型,也被称为"目标类型( target type) ", Lambda 表达式的目标类型必须是"函数式接口( functional interface ) "。从前面介绍可以看出, Lambda 表达式是匿名内部类的一种简化 , 因此它可以部分取代匿名内部类的作用。Lambda 表达式与函数式接口。

2025-06-29 20:50:04 653

原创 Java Review (十四、面向对象----接口)

抽象类是从多个类中抽象出来的模板,如果将这种抽象进行得更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(interface),接口里不能包含普通方法,接口里的所有方法都是抽象方法。实现接口方法时 , 必须使用 public 访问 控制修饰符, 因为接口里的方法都是 public的 , 而子类( 相当于 实现类 )重写父类方法时访问权限只能更大或者相等 , 所以实现类实现接口里的方法时只能使用 public 访问权限。接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父接口。

2025-06-29 20:48:46 643

原创 Java Review (十三、面向对象----抽象类)

如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,甚至可能更加抽象。从某种角度看, 祖先类更加通用, 只是将它作为派生其他类的基类,而不作为想使用的特定的实例类。抽象方法和抽象类必须使用 abstract 修饰符来定义,抽象方法和抽象类的规则如下。模板模式范例-抽象父类。

2025-06-29 20:48:06 257

原创 Java Review (十二、面向对象----final 修饰符)

对于 final 修饰的成员变量而言,一旦有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块、构造器中为成员变量指定初始值,那么这些成员变量的值将一直是系统默认分配的0、'\u000'、false或 null ,这些成员变也就完全失去了存在的意义。定义一个不可变的 Address 类,程序把 Address 类的 detail 和 postCode 成员变量都使用 private隐藏起来,并使用 final 修饰这两个成员变量 , 不允许其他方法修改这两个成员变量的值。

2025-06-29 20:47:40 409

原创 Java Review (十一、面向对象----多态)

编写Java程序时,引用变量只能调用它编译时类型的方法,而不能调用它运行时类型的方法,即使它实际所引用的对象确实包含该方法。instanceof运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是接口),它用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。Java 引用变量有两个类型 :一个是编译时类型,一个是运行时类型,编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定,如果编译时类型和运行时类型不一致,就可能出现所谓的。

2025-06-29 20:47:16 424

空空如也

空空如也

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

TA关注的人

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