Java基础
文章平均质量分 91
koping_wu
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【JVM】类的生命周期
下图中展示的类加载器之间的这种层次关系,称为类加载器的双亲委派模型(Parents Delegation Model)。双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承(Inheritance)的关系来实现,而是都使用组合(Composition)关系来复用父加载器的代码。原创 2025-09-09 09:27:51 · 620 阅读 · 0 评论 -
【JVM】Java对象结构
当我们在Java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc对象,这个对象中包含了对象头、实例数据以及对齐填充。对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。由于虚拟机要求对象的起始地址必须是8字节的倍数(在某些平台上要求更大),因此可能需要在对象的实例数据末尾添加额外的字节来对齐。原创 2025-09-09 09:27:29 · 777 阅读 · 0 评论 -
【JVM】垃圾回收器
总结一下就是,G1会把Java的堆分为多个大小相等的Region(每个Region的大小为1M-32M),他在年轻代回收的时候采用标记-复制算法,而在老年代回收的时候,采用的是标记-整理算法,这两种算法都可以避免内存碎片的产生。G1 和 CMS相比,他们都是基于三色标记法实现的,替代了原有的传统的可达性分析(三色标记也是可达性分析的一种,只不过特殊一点),可以大大的降低STW的时长。总之,G1是一个先进的垃圾收集器,它可以提高系统的吞吐量,降低停顿的频率,并且可以有效管理大型堆。原创 2025-09-09 09:27:10 · 757 阅读 · 0 评论 -
【JVM】垃圾回收算法
JVM的跨代引用问题是指在Java堆内存的不同代之间存在引用关系,导致对象在不同代之间的引用被称为跨代引用。比如:新生代到老年代的引用,老年代到新生代的引用等。跨代引用会有什么问题呢?假如,我们现在JVM的堆是上面这种情况,那么在进行一次MinorGC(YoungGC)的时候,会从GC Root出发,然后进行可达性分析,假如当前正在进行一次Young GC,如果他发现一个对象处于老年代,那么JVM就会中断这条路径。原创 2025-09-09 09:26:48 · 648 阅读 · 0 评论 -
【JVM】堆内存分代和GC触发条件
Safe Point(安全点)是JVM中的一个关键概念。官方的解释是(https://openjdk.org/groups/hotspot/docs/HotSpotGlossary.html):安全点,简单点说就是代码执行过程中的一些特殊位置,当线程执行到这个位置的时候,可以被认为处于“安全状态”,如果有需要,可以在这里暂停,在这里暂停是安全的!这些安全点通常出现在不会改变共享数据状态的位置,例如在方法调用、循环迭代和异常抛出的地方。原创 2025-09-09 09:26:26 · 599 阅读 · 0 评论 -
【JVM】运行时内存区域
堆外内存是指将数据存储在堆以外的内存中,主要是指将一些直接内存分配在堆以外,以提高应用程序的性能或节省堆内存空间。堆外内存可以用于分配容量较大的缓冲区,比如文件缓冲区等等。Java 中的直接内存是通过使用 java.nio 包中的 DirectByteBuffer 类来实现的。DirectByteBuffer 类可以用来分配本地内存,并允许在 Java 和本地内存之间交换数据。使用 DirectByteBuffer 可以减少从 Java 堆和本地堆之间进行复制和读写的开销,从而提升程序的性能。原创 2025-09-09 09:25:58 · 964 阅读 · 0 评论 -
【JVM】JIT优化技术
TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的。在虚拟机的TLAB功能启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。所以说,因为有了TLAB技术,堆内存并不是完完全全的线程共享,其eden区域中还是有一部分空间是分配给线程独享的。这里值得注意的是,原创 2025-09-09 09:25:04 · 1038 阅读 · 0 评论 -
【设计模式】设计模式原则、单例模式、工厂模式、模板模式、策略模式
设计模式是在软件开发过程中经常遇到的问题的通用解决方案。它们是经过无数的验证和经验积累的最佳实践。首先,设计模式是一些前人经验的一些总结,所以,当遇到相似的问题的时候,我们可以直接借鉴好的设计模式来实现,这样可以大大降低我们的试错成本和迭代成本。可以大大提升我们的开发速度。不要认为只有23种,只要是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结都是软件设计模式的。比如说MVC而且,设计模式都是遵守了很多设计原则的,这些原则可以帮助我们大大提升代码的可重用性、可维护性和可扩展性等。原创 2025-12-08 11:11:56 · 981 阅读 · 0 评论 -
【Spring】SpringBoot原理
SpringApplication.run(Application.class, args)方法的实现细节如下:一个是new SpringApplication的初始化过程,一个是SpringApplication.run的启动过程。这个过程确保了在应用上下文被创建和启动之前,所有关键的设置都已就绪,包括环境设置、初始化器和监听器的配置,以及主应用类的识别。这一步,是Spring启动的核心步骤了,这一步骤包括了实例化所有的 Bean、设置它们之间的依赖关系以及执行其他的初始化任务。原创 2025-09-20 15:32:27 · 624 阅读 · 0 评论 -
【Spring】Spring Event事件驱动
在上面的示例中,UserRegistrationEvent 事件在用户注册成功后发布,然后 UserRegistrationEventListener 中的 handleUserRegistrationEvent 方法在事务成功提交后触发,发送欢迎邮件。Spring框架中的事件机制建立在观察者模式的基础上,允许应用程序中的组件注册监听器来监听特定类型的事件,并在事件发生时执行相应的操作。事件监听器将在事务尚未提交时执行,这意味着它可以在事务内部进行回滚操作,如果事件监听器抛出异常,将导致事务回滚。原创 2025-09-20 15:31:32 · 743 阅读 · 0 评论 -
【SpringCloud】SpringCloud组件
Spring Cloud是基于Spring Boot的分布式系统开发工具,它提供了一系列开箱即用的、针对分布式系统开发的特性和组件,用于帮助开发人员快速构建和管理云原生应用程序。Spring Cloud的主要目标是解决分布式系统中的常见问题,例如服务发现、负载均衡、配置管理、断路器、消息总线等。Eureka 的缓存机制设计主要目的是提高服务发现的效率和减少服务注册中心的压力,尤其是在面对大规模的服务注册和发现请求时。这种多层缓存设计帮助 Eureka 提供快速的响应能力。原创 2025-09-15 09:40:11 · 1027 阅读 · 0 评论 -
【Spring】Spring核心功能的理解
相同点:对于下面的代码来说,如果是Spring容器的话,两个注解的功能基本是等价的,他们都可以将bean注入到对应的field中。不同点:1、Autowired是Spring提供的自动注入注解,只有Spring容器会支持,如果做容器迁移,是需要修改代码的。Resource是JDK官方提供的自动注入注解(JSR-250)。它等于说是一个标准或者约定,所有的IOC容器都会支持这个注解。假如系统容器从Spring迁移到其他IOC容器中,是不需要修改代码的。2、Autowired在获取bean的时候,先是原创 2025-09-15 09:19:05 · 868 阅读 · 0 评论 -
【Spring】Spring事务传播机制
有的时候,你排查了很久,发现都没问题,但是还是不生效,然后找别人来帮你看,他上来就看了一下你用的@Transactional,发现并不是Spring中的,而是其他什么地方的,比如 javax.transaction.Transactional ,这样也会导致事务失效。private方法,只会在当前对象中的其他方法中调用,也就是会进行对象的自调用,这种情况是用this调用的,并不会走到代理对象,而@Transactional是基于动态代理实现的,所以代理会失效。2、在事务中有远程调用,就会拉长整个事务。原创 2025-09-15 09:18:50 · 988 阅读 · 0 评论 -
【Spring】Spring MVC
MVC模式(Model-View-Controller)是一种软件设计模式,它将应用程序分为三个部分:模型、视图和控制器。这个模式的目的是将应用程序的表示(视图)与处理(控制器)分开,以及将应用程序的数据和业务逻辑(模型)与表示和处理分开。2)将RequestMappingInfo 和 HandlerMethod(处理url的方法名) 作为kv保存在mappingLookup缓存中。1)将请求路径 和 RequestMappingInfo 作为KV保存在urlLookup缓存中。原创 2025-09-15 09:18:38 · 933 阅读 · 0 评论 -
【Spring】Spring Bean的生命周期
1、在创建对象时,先实例化bean,然后再初始化bean,会调用applyBeanPostProcessorsAfterInitialization方法。2、在applyBeanPostProcessorsAfterInitialization方法中,先遍历每一个后置处理器,然后调用后置处理器的postProcessAfterInitialization方法。原创 2025-09-15 09:18:25 · 836 阅读 · 0 评论 -
【Java并发】ThreadLocal
ThreadLocal是java.lang下面的一个类,是用来解决java多线程程序中并发问题的一种途径;通过为每一个线程创建一份共享变量的副本来保证各个线程之间的变量的访问和修改互相不影响;ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递,这样处理后,能够优雅的解决一些实际问题。原创 2025-08-27 09:57:28 · 679 阅读 · 0 评论 -
【Java并发】synchronized原理
在未释放之前,其他线程是无法再次获得锁的,所以,通过monitorenter和monitorexit指令,可以保证被synchronized修饰的代码在同一时间只能被一个线程访问,在锁未释放之前,无法被其他线程访问到。如果该对象已经被锁住,线程就会进入阻塞状态,直到锁被释放。但是,偏向锁的局限是当只有一个线程反复进入同步代码块时他才能快速获得,但是当有其他线程尝试获取锁的时候,就需要等到 safe point 时,再将偏向锁撤销为无锁的状态或者升级为轻量级锁,而这个过程其实是会消耗一定的性能的。原创 2025-08-27 09:49:07 · 1072 阅读 · 0 评论 -
【Java并发】AQS原理
AQS的各种实现类中,要么是基于独占模式实现的, 要么是基于共享模式实现的。在独占模式中,状态通常表示是否被锁定(0表示未锁定,1表示锁定)。在共享模式中,状态可以表示可用的资源数量。当需要保证某个资源或一段代码在同一时间内只能被一个线程访问时,独占模式是最合适的选择。如我们经常用的ReentrantLock和ReadWriteLock中的写锁。当资源或数据主要被多个线程读取,而写操作相对较少时,共享模式能够提高并发性能。原创 2025-08-27 09:47:22 · 859 阅读 · 0 评论 -
【Java并发】线程状态
在Java中,共有四种方式可以创建线程,分别是(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。(2)创建Thread子类的实例,即创建了线程对象。(3)调用线程对象的start()方法来启动该线程。1.2 实现Runnable接口创建线程(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。(2)创建 Runnable实现类的实例,并依此实例作为Thre原创 2025-08-27 09:44:57 · 419 阅读 · 0 评论 -
【Java并发】CAS
CAS是一项乐观锁技术,是Compare And Swap的简称,顾名思义就是先比较再替换。CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。在进行并发修改的时候,会先比较A和V中取出的值是否相等,如果相等,则会把值替换成B,否则就不做任何操作。当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。原创 2025-08-27 09:35:28 · 572 阅读 · 0 评论 -
【Java集合类】HashMap实现原理
ConcurrentHashMap将哈希表分成多个段,每个段拥有一个独立的锁,这样可以在多个线程同时访问哈希表时,只需要锁住需要操作的那个段,而不是整个哈希表,从而提高了并发性能。简单点说,就是为了把高位的特征和低位的特征组合起来,降低哈希冲突的概率,也就是说,尽量做到任何一位的变化都能对最终得到的结果产生影响。,即将哈希表分成多个段,每个段拥有一个独立的锁。当上面的操作完结后,HashMap会检测两个链表的长度,当元素小于等于6的时候,就会执行取消树化的操作,否则就会将新生成的链表重新树化。原创 2025-08-13 13:32:16 · 710 阅读 · 0 评论 -
【Java集合类】集合排序的方式有哪些?
Java.util包中的List接口继承了Collection接口,用来存放对象集合,所以对这些对象进行排序的时候,要么让对象类自己实现同类对象的比较,要么借助比较器进行比较排序。举例:学生实体类,包含姓名和年龄属性,比较时先按姓名升序排序,如果姓名相同则按年龄升序排序。原创 2025-08-11 08:46:49 · 295 阅读 · 0 评论 -
【Java】面试题
因为BigDecimal的equals方法和compareTo并不一样,equals方法会比较两部分内容,分别是值(value)和标度(scale),而对于0.1和0.10这两个数字,他们的值虽然一样,但是精度是不一样的,所以在使用equals比较的时候会返回false。浮点数不一定能精确地表示小数,double是不精确的。这时候,对于那种可能经常使用的字符串,使用intern进行定义,每次JVM运行到这段代码的时候,就会直接把常量池中该字面值的引用返回,这样就可以减少大量字符串对象的创建了。原创 2025-08-11 08:45:21 · 619 阅读 · 0 评论 -
【Java基础】字符串不可变性、string的intern原理
string不可变的基本原理:2、String为什么设计成不可变的?主要有以下4个原因:字符串常量池的位置:在JDK 1.6及之前的版本,字符串常量池通常被实现为方法区的一部分,即永久代(Permanent Generation),用于存储类信息、常量池、静态变量、即时编译器编译后的代码等数据。从JDK 1.7开始,字符串常量池的实现方式发生了重大改变。字符串常量池不再位于永久代,而是直接存放在堆(Heap)中,与其他对象共享堆内存。之所以要挪到堆内存中,主要原因是因为永久代的 GC 回收效率太低,只有原创 2025-08-09 15:02:16 · 634 阅读 · 0 评论 -
【Java基础】异常处理
Throwable是java中最顶级的异常类,继承Object,实现了序列化接口,有两个重要的子类:Exception和 Error,二者都是 Java 异常处理的重要子类,各自都包含大量子类。原创 2025-08-07 11:51:52 · 663 阅读 · 0 评论 -
【Java基础】常见语法糖
语法糖(Syntactic sugar),指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。虽然Java中有很多语法糖,但是Java虚拟机并不支持这些语法糖,所以这些语法糖在编译阶段就会被还原成简单的基础语法结构,这样才能被虚拟机识别,这个过程就是解语法糖。Java中的switch自身原本就支持基本类型。比如int、char等。对于int类型,直接进行数值的比较。对于char类型则是比较其ascii码。所以,对于编译器来说,switch中其实只能使用整型,任何类型的比较都原创 2025-08-06 09:28:09 · 1139 阅读 · 0 评论 -
【Java基础】不能用浮点数表示金额
比如0.1,是没办法将他转换成一个确定的二进制数的。因为他乘2取整后会进入一个循环。十进制整数转换为二进制整数采用"除2取余,逆序排列"法。十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。比如:十进制的0.625对应的二进制就是0.101。原创 2025-08-04 09:50:43 · 249 阅读 · 0 评论 -
【Java基础】面向对象的三大特征和五大原则
在构建一个电商应用程序时,一个高层的“订单处理”模块不应该直接依赖于一个低层的“数据访问”模块。如果有一个多功能打印机接口包含打印、扫描和复制功能,那么只需要打印功能的客户端应该不必实现扫描和复制的接口。这样底层的数据存储我们就可以任意更换,可以用MySQL,可以用Redis,可以用达梦,也可以用OceanBase,因为我们做到了依赖接口,而不是具体实现。封装就是把现实世界中的客观事物抽象成一个Java类,然后在类中存放属性和方法。像现实世界中儿子可以继承父亲的财产、样貌、行为等一样,编程世界中也有继承,原创 2025-08-03 13:52:12 · 720 阅读 · 0 评论
分享