🚀JVM系列 之 深入探索Java 类加载器Hey 大家好,我是 Shio👋。今天我们将深入探讨 Java 的类加载器,这是 Java 虚拟机(JVM)中一个重要的概念。在上一篇中,我们了解到 Java 类加载分为多个步骤,其中只有加载步骤中的读取二进制流与初始化部分是由上层开发者控制的, 剩下的步骤都由 JVM 掌控 。 这是为了符合面向对象中的开闭原则和封装思想。
📦 类加载器的分类首先要声明的是,类加载器的分类属于 JVM 规范,是一种抽象的概念。各个 JVM 的实现方式可能不同。在JVM 规范中,类加载器分为启动类加载器和非启动类加载器。本节我们只讲最常见和主流 HotSpot:
启动类加载器
Bootstrap Class Loader:
采用 C 和 C++ 实现,嵌套在 JVM 内部,无法被程序引用。
主要加载 Java 的核心类库,如 JAVA_HOME /lib 路径下的包(rt.jar tool.jar等)或由启动参数指定的核心类库。(-Xbootclasspath/a: jar包目录/jar包名 的类也会被其加载)
只加载包名在白名单 ...
🌱JVM系列 之 自底向上理解Java内存模型Hey 大家好,我是 Shio👋。今天我们将深入探讨Java 内存模型
⚠️ 注意!!!!
🚧🚧🚧 本文并不完整, 还未彻底 完成🚧🚧🚧
💾内存模型发展:rocket: 单处理器时代的纵向优化
在单处理器计算机时代,程序员只需编写单线程程序,除了算法降低复杂度外, 只能依赖硬件和编译器进行纵向优化。
随着硬件发展速度趋于平缓,工程师们开始追求横向拓展,即在单台计算机中使用更多的处理器。
👾 缓存的引入与多处理器时代的问题
为弥补CPU处理速度与内存读写速度的差距,引入了缓存以提高效率。然而,在多处理器环境下,缓存带来了数据不一致的问题。
🚧 缓存一致性协议的设计
为此科学家们设计了缓存一致性协议,解决多个CPU缓存之间的同步问题这些协议, 保证了数据的一致性。
大致分为窥探型和基于目录型。
可想而知, 为了保证多个CPU缓存一致性和同步, 协议中一定涉及到等待和唤醒等同步步骤
对于CPU这种运算速率极快的组件来说, 任何等待都是对其性能极大的浪费 (CPU A 在读取 D时还需要等待 CPU B 将D写回到 ...
🌟 JVM系列 之 深入理解类加载机制👥 背景故事在一次友人间的聚餐讨论中,我们提及了不同编程语言的优势与学习深度。对于一位以PHP为背景的朋友,有人建议其转向Java生态,因为Java具有成熟的生态系统和广泛的应用场景。朋友表示自己也会Java, 掌握Java的语法 …..
💡 学习层次剖析学习编程语言可分为三个递进层次:
📚 基础语法核心类库的熟悉使用
🌐 优势劣势分析与生态系统了解
🔧 底层运行机制探究与应用优化
💻 Java核心 -JVMJava的核心魅力在于Java虚拟机(JVM),它是跨平台执行Java字节码的关键。诸如Kotlin, Groovy、Scala等其他基于JVM的语言,通过深入理解JVM可以更高效地掌握。
📖 类加载机制详解
编译与执行:Java源代码经过javap编译转换成.class字节码文件,由JVM加载并解析执行,同时即时编译器(JIT)会将热点代码转化为高效的二进制代码, 通过解释器和即时编译器想结合预热后的代码可以达到很快的执行效率
类加载流程
加载阶段:加载阶段的任务是读取字节码资源以静态结构的形式存储在方法区,同时 ...
Spring
未读渐进式实现Spring日志1 开始实现一个简单的Spring Bean容器1.1 设计思路使用Map数据结构来存储所有的Bean对象。
2. 基于模板模式实现对象定义、注册和获取2.1 设计思路使用模板模式,统一使用核心方法的调用逻辑和标准定义,进而可以很好地实现后续步骤而不用关心某一方法的调用逻辑。按照统一方式执行,类的继承者只需要关心具体方法如何实现即可。
基于模板方法模式实现对象定义, 注册, 获取
SingletonBeanRegistry- 获取单例的注入和获取能力DefaultSingletonBeanRegistry- 内部维护singletonObjectsMap, 提供单例对象的管理能力BeanFactory- 获取Bean的能力AbstractBeanFactory- 提供getBean的模板方法实现 - 获取单例, 获取成功直接返回(利用父类DefaultSingletonBeanRegistry) - 获取BeanDefinition 抽象方法交给子类实现 - 创建Bean实例 抽象方法交给子类实现 DefaultAutowireCapableBeanFa ...
【Java版本】常用代码模板——-基础算法——-排序快速排序代码模板
private void quickSort(int[] arr, int left, int right) { // 递归终止条件,如果左边界大于等于右边界则认为递归结束 if (left >= right) { return arr; } // 设定一个分界值,这里是(left + right)/ 2 int p = arr[left + right >> 1]; // 左右提前预留一个位置 int i = left - 1; int j = right + 1; while (i < j) { // 等效于do while // 当数值小于分界值时持续遍历,直到找到第一个大于等于分界值的索引 // 如果是逆序则调整两个while循环 while (arr[++i] < p) ; whi ...
设计模式之美—-职责链模式本文将对责任链模式(职责链模式)分为四个部分进行讲解
原理
实现
应用
练习
让大家系统全面的学会使用责任链模式, 并应用到开发中去
原理篇
大部分设计模式的核心是应对工程中的复杂性, 使得代码满足开闭原则, 提高代码扩展性
职责链的英文名为Chain Of Responsibility Design Pattern, 在GoF的设计模式中的定义如下
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
“将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。”
实际上就是将请求通过类 ...
太原理工大学软工方向选择指南大家好! 我是Shio, 国内白嫖的服务器过期了, 所以博客又回到了GitHub Page上, 访问速度会很慢, 大家见谅
又到了一年一度软件专业同学选择方向的时候了, 这时候的大家大概心里也对自己将来是考公, 考研, 还是就业 心里大概有了一个基本的方向, 下面是我对选方向上的一些经验, 分享给大家
首先我们先给大家扫扫盲
每年学校给软工学生分配的方向和所处基地并不是强绑定的关系, 也就是说, 可能今年这个方向在某某基地, 但是明年是有概率换的
所有基地都会分考研班和就业班, 所以考研的同学不需要太过担心到基地后的学业压力, 基本每个基地的考研班在课程上都是很轻松的, 基本不会影响到你的备战
往年基本选定哪个方向就能去哪个方向, 但是去年我们这届情况特殊, 移动互联方向只有八十人左右, 而网安方向投递志愿的人太多, 所以会根据成绩进行排序, 排序靠后的同学最后会调剂到第二志愿的方向去
在选定方向后, 大三下就会根据不同方向有不同的课程以及课设安排, 之后大概在6, 7月份会对各方向的培训工作公开招标(但根据往年的情况看, 其实就是那几家), 一般7月份就 ...
【从零构建Spring|第十三节】 加载,解析资源并注册Bean对象目标在上一章节我们通过基于 Proxy.newProxyInstance 代理操作中处理方法匹配和方法拦截,对匹配的对象进行自定义的处理操作。并把这样的技术核心内容拆解到 Spring 中,用于实现 AOP 部分,通过拆分后基本可以明确各个类的职责,包括你的代理目标对象属性、拦截器属性、方法匹配属性,以及两种不同的代理操作 JDK 和 CGlib 的方式。
再有了一个 AOP 核心功能的实现后,我们可以通过单元测试的方式进行验证切面功能对方法进行拦截,但如果这是一个面向用户使用的功能,就不太可能让用户这么复杂且没有与 Spring 结合的方式单独使用 AOP,虽然可以满足需求,但使用上还是过去分散。
因此我们需要在本章节完成 AOP 核心功能与 Spring 框架的整合,最终能通过在 Spring 配置的方式完成切面的操作
设计将 AOP 融入 Spring 需要解决几个问题
怎么通过 BeanPostProcessor 将动态代理融入 Bean 的生命周期中?
如何组装各项切点、拦截、前置以及适配对应的代理器?
...
🌟七天重启人生计划🌟:从摆烂到高效,我的亲身实践🚀在人生的某个阶段或者某段时间,我们或许都会陷入一种“摆烂”状态——无目标、无动力,甚至开始怀疑自我。但你知道吗?只需七天,你就能重启人生,找回失去的激情与方向!🌈
📆Day 1:记录与觉醒📝选择一个你觉得舒适的日子作为你的Day 1。这天,仔细记录你所做的一切,无论是刷手机的闲暇时光还是完成工作任务的高效瞬间。标记出那些消耗你时间和精力的“吸血鬼”,它们可能是无休止的社交媒体滚动、冗长无意义的会议或是拖延症。🎯
🧠Day 2-4:目标设定与思维激荡💡接下来的三天,每晚睡前,让大脑沉浸在对未来一年目标的思考中。不要限制自己,任何可能性都是开放的。但到了第四天晚上,你需要对目标无比坚定,明确知道自己想要什么,无论是事业上的提升、健康状况的改善还是个人兴趣的培养。🌱
🗓️Day 5:规划未来📅今天,是时候制定详细的计划了。规划接下来一周、一个月乃至一年的具体行动。将大目标分解成小步骤,这样更容易执行。记得,每个项目都要有优先级,先做什么后做什么,一目了然。📈
🔧Day 6:微调与优化🔧回顾昨天的计划,看看是否有需 ...
【从零构建Spring|第十六节】 三级缓存解决循环依赖问题前言目前我们的 Spring 可以完成一个基本功能。但是如果遇到 A、B 两个 Bean 对象相互依赖,就会报出 java.lang.StackOverflowError 错误。因为创建 A 时需要 B,而 B 的创建又依赖于 A 创建,死循环
循环依赖是 Spring 经典的场景。需要解决的主要是以下三种情况:
自身依赖
循环依赖
多组依赖
按照 Spring 框架的设计,用于解决循环依赖需要用到三个缓存 Map,这三个缓存分别存放了成品对象、半成品对象(未填充属性值)、代理对象,分阶段存放对象内容,来解决循环依赖问题。
singletonObjects:成品对象
earlySingletonObjects:半成品对象
singletonFactories:工厂对象(代理对象)
这里我们需要知道一个核心的原理,就是用于解决循环依赖就必须是三级缓存呢,二级行吗?一级可以不?其实都能解决,只不过 Spring 框架的实现要保证几个事情,如只有一级缓存处理流程没法拆分,复杂度也会增加,同时半成品对象可能会有空指针异常。 ...