当前位置: 首页 > news >正文

深入理解 Java 虚拟机第三版(周志明)

这次社招选的这本作为 JVM 资料查阅,记录一些重点

1. 虚拟机历史

Sun Classic VM :已退休

HotSpot VM:主流虚拟机,热点代码探测技术

Mobile / Embedded VM :移动端、嵌入式使用的虚拟机

2.2 运行时数据区域

程序计数器(线程级):当前线程所执行的字节码的行号指示器。

虚拟机栈(线程级):存放局部变量、操作数栈、动态链接、方法出口等信息。其中局部变量包含编译时可知的基本数据类型和对象引用。

本地方法栈(线程级):与虚拟机栈类似,为虚拟机使用到的本地方法服务。

堆:对象分配。

方法区:存储已经被虚拟机加载的类型信息、常量、静态变量等。

2.2 补充 - 直接内存

直接内存不是虚拟机运行时数据区的一部分。使用 Native 函数直接分配堆外内存,然后通过一个存储在堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。

2.3 对象的创建

1. 读到 new 指令。

2. 检查这个指令的参数能否在常量池定位到一个类的符号引用。检查这个类是否已经加载、解析、初始化,若没有则执行。

3. 分配内存(对象所需的内存大小在类加载完成后就可以完全确定)。

4. 初始化为零值。

5. 记录对象头。

6. 初始化。

对对象的访问有句柄式和直接指针两种类型

2.3 补充 - 分配内存时保持线程安全

方案一:对分配内存空间的动作进行同步处理;

方案二:每个线程在堆中预先分配一小块内存,优先使用本地缓冲区,耗尽后才需要进行同步锁定。

2.3 补充 - 对象的内存布局

对象头:存储对象自身的运行时数据(Hashcode,锁等),类型指针(对象指向其类型元数据的指针),当对象是一个 java 数组时,还需要记录数组长度。

实例数据:包含父类 & 子类的数据。

对齐补充:补充为 8 字节的整数倍。

3.2 判断对象是否可以回收

1. 引用计数法:利用引用计数器来记录引用数量。无法解决循环引用问题。

2. 可达性分析:通过 GC Roots 向下搜索,如果某个对象不可达,则说明不再使用。可以作为 GC Roots 的对象包含:虚拟机栈中引用的对象、方法区中静态属性引用的对象、方法区常量引用的对象、虚拟机内部的引用、被同步锁持有的对象、反映虚拟机内部情况的变量。

强引用:通过引用赋值 Object obj = new Object()

软引用:用于描述一些还有用但非必须得对象。 SoftReferrence,系统要发生移除异常前,才进行回收。

弱引用:对象只活到下次 GC 之前。WeakReferrence。

虚引用:不影响回收,作用仅是在回收时可以收到一个系统通知。 PhantomReference 。

对象在可达性分析后发现不可达,进行第一次标记 -> 放入 F - Queue 中 ->  Finalizer 线程执行 finalize() 方法 -> 对 F - Queue 中的对象进行二次标记。

在枚举根节点时,必然会停顿用户进程。

3.2 补充 方法区中的回收

主要回收废弃的常量和不再使用的类型。不再使用的类型(该类的所有实例都已经回收 & 类加载器已经回收 & 该类的 Class 对象没有任何引用)

3.3 分代收集基础上的垃圾回收算法

1. 标记 - 清除算法

2. 标记 - 复制算法:内存分为大小相等的两块,每次只使用其中的一块。Appel 式回收将内存划分为一块 Eden 区两块 Survivor 区域,每次使用 Eden + 一块 Survivor,当出现极限情况会占用老年代内存。

3. 标记 - 整理算法:存活的对象需要移动到整理

3.4 安全点 & 安全区域

安全点:用户程序执行可以停下来的时间点

安全区域:安全点无法保证挂起的线程可以执行到,可以视作延长了的安全点。

  • 如果线程在执行关键操作(如执行系统调用)时收到挂起请求,JVM可能会延迟挂起,直到线程完成当前操作并进入下一个安全点。

虽然用户可以通过Thread.suspend()方法请求挂起一个线程,但JVM可能会根据当前的执行环境和线程状态,延迟挂起操作,直到线程到达一个安全点。这种做法有助于确保程序的稳定性和数据的一致性。然而,需要注意的是,Thread.suspend()方法已经被标记为过时(deprecated),并且不推荐在现代Java应用程序中使用,因为它可能会导致死锁和其他问题。现代Java应用程序更倾向于使用Thread.interrupt()方法来请求线程中断,并通过轮询中断状态来实现线程的协作挂起。

3.5 卡表

为了解决跨代引用问题,新生代会维护一个「记忆集」,避免把整个老年代都加入 GC Roots 的扫描范围。通常使用卡表来作为解决方案。

只要对应的内存中存在一个跨代指针就标记,扫描时将其加入范围内。通过「写屏障」技术在每次赋值之后维护。

3.6 垃圾回收器

Serial :单线程工作。Stop the world。

ParNew:Serial 的多线程版本。

Parallel:基于标记复制算法,尽可能达到一个可控制的吞吐量。适用于后台运算不需要太多交互的任务。

Serial Old:Serial 的老年代版本。

Parallel Old: Parallel 的老年代版本。

CMS:最短响应时间。标记清除算法。

G1:虽然保留了新生代和老年代的概念,但不再固定区域转为划分为 Region,每个 Region 可以独立作为某个代。

Shenandoah:提供并发标记、并发回收、并发引用更新的处理,旨在提供最小停顿时间。

ZGC:基于 Region 内存布局的,不设分代的,使用了读屏障、染色指针和内存多重映射技术实现的可以并发的标记整理算法的垃圾处理器。

3.6 补充 G1 的卡表

CMS垃圾收集器的记忆集设计

  1. 记忆集的作用

    • 记忆集用于记录从非收集区域指向收集区域的指针集合。在CMS中,主要是记录老年代中哪些对象引用了新生代的对象71。

  2. 卡表的实现

    • 卡表是记忆集的具体实现方式之一。在CMS中,卡表是一个字节数组,每个字节对应一个卡页(通常是512字节)。如果卡页中的某个对象引用了新生代的对象,对应的卡表字节会被标记为171。

  3. 卡表的更新

    • 在CMS的并发标记阶段,如果老年代对象引用了新生代对象,卡表会被更新,标记相应的卡页为“脏卡”。这样在Minor GC时,只需要扫描这些脏卡对应的老年代对象71。

  4. 并发标记和重新标记

    • CMS的并发标记阶段会并发地进行GC Roots Tracing,而重新标记阶段则会修正并发标记阶段由于用户程序变动导致的问题71。

G1垃圾收集器的记忆集设计

  1. 记忆集的复杂性

    • G1的堆内存被划分为多个大小相等的区域(Region),每个区域可以是Eden、Survivor或老年代区域。G1的记忆集需要记录跨Region的引用关系72。

  2. 卡表的局限性

    • 在G1中,由于堆内存的划分方式,传统的卡表结构不再适用。G1采用了“空间换时间”的策略,通过增加记忆集的结构复杂度来减少GC的时间78。

  3. 记忆集的实现

    • G1的记忆集在概念上采用了"point-in"的思想,即记录了哪个区域指向我。这种记忆集在Card Table的基础上增加了HashTable的数据结构,Key是某个老年代Region的起始位置,Value是这个老年代Region的所有存在跨代指针的卡页的起始位置的集合78。

  4. 跨Region引用的处理

    • G1的每个Region都维护有自己的记忆集,记录了其他Region中的对象到该Region的引用。这样在进行垃圾回收时,只需要扫描这些记录的引用关系,而不需要扫描整个堆77。

  5. 记忆集的空间开销

    • G1的每个Region都维护有自己的记忆集,这导致G1比其他垃圾收集器有着更高的内存占用负担。根据经验,G1至少要耗费大约相当于Java堆容量10%至20%的额外内存来维持收集器工作

7.2 类加载的时机

加载

- 通过类的类名来获取定义此类的二进制字节流

- 字节流转化为方法区的运行时数据结构

- 生成 .Class 对象

准备

- 为类中定义的变量分配内存并设置初始值。

解析

- 常量池里的符号引用替换为直接引用的过程。包含接口、字段、方法、接口方法等

8.2 运行时栈

8.3 重载和重写是如何实现的 - 分派

静态分派

Human man = new Man(),其中 Human 为变量的静态类型或外观类型,编译时可知。Man 为实际类型或运行时类型,编译时不可知(eg:通过计算才确定 new 啥的写法)。

Java 中的静态分配由于同时参考静态类型 & 参数,所以属于多分派类型。

重载是通过静态类型进行判断的。

动态分派

在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。

重写即为动态分派的体现,根源在于 invokevirtual 指令的运行逻辑会优先使用实际类型。事实上,Java 中只有虚方法存在,字段永远不可能是虚的(子类会屏蔽父类的同名字段)。

Java 中的动态分派属于单分派类型,只受实际类型影响。

8.3 补充 - 虚方法表

动态分派的实现方式之一:类型在方法区会建立一个虚方法表,用虚方法表代替元数据查找。虚方法表中存放着各个方法的实际入口地址。若没有重写,子类的虚方法表和父类相同方法的入口一致,都指向父类的实现入口。

此外,还会他用过类型集成关系分析、守护内联、内联缓存等来争取更大的优化。

8.4 动态类型语言

动态类型语言的类型检查主体过程在运行期而不是编译期。Java 是静态语言。

8.5 解释执行 & 编译执行

  1. 编译执行 (Compile and Execute):

    • 编译阶段:源代码(如C、C++、Java等语言编写的程序)首先需要通过编译器转换成机器代码或字节码。编译器检查源代码的语法错误,进行类型检查,优化代码,最终生成可执行文件或字节码文件。
    • 执行阶段:编译后的机器代码由计算机的操作系统加载并执行,或者字节码由虚拟机(如Java虚拟机)加载并解释执行。
  2. 解释执行 (Interpret and Execute):

    • 解释执行通常指的是源代码直接由解释器逐行解释并立即执行,无需编译成机器代码。这种执行方式常见于脚本语言(如Python、JavaScript、Ruby等)。
    • 解释器读取源代码,转换为中间表示(如果需要),然后立即执行这些操作,而不需要等待整个程序编译完成。
  3. 即时编译 (Just-In-Time Compilation, JIT):

    • 某些语言(如Java)使用即时编译技术,将字节码在运行时编译成机器代码。这种方式结合了编译执行和解释执行的优点,允许程序在开始时快速启动(像解释执行),并在运行过程中优化性能(像编译执行)。

10.3 泛型

Java 中的泛型为类型擦除式泛型,只在源码中存在,在编译后的字节码文件中,全部泛型都被替换为原来的裸类型

10.3 补充 自动装箱 &  拆箱

Java 的自动装箱(Autoboxing)和拆箱(Unboxing)是 Java 5 引入的两个特性,它们允许基本数据类型(如 `int`、`double` 等)和对应的包装类(如 `Integer`、`Double` 等)之间的自动转换。

### 自动装箱(Autoboxing)
自动装箱是指自动将基本数据类型转换为对应的包装类类型。这个过程是编译器在代码编译时自动完成的。例如:

```java
Integer refInt = 5; // 自动装箱,将 int 类型 5 转换为 Integer 类型
```

在这个例子中,整数值 `5` 被自动转换为 `Integer` 对象。

### 自动拆箱(Unboxing)
自动拆箱是指自动将包装类类型转换为对应的基本数据类型。这同样是由编译器在编译时自动完成的。例如:

```java
int num = refInt; // 自动拆箱,将 Integer 类型转换为 int 类型
```

在这个例子中,`refInt` 是 `Integer` 类型的对象,它被自动转换为 `int` 类型的变量 `num`。

### 转换规则
- `int` 与 `Integer`
- `double` 与 `Double`
- `float` 与 `Float`
- `long` 与 `Long`
- `short` 与 `Short`
- `byte` 与 `Byte`
- `char` 与 `Character`
- `boolean` 与 `Boolean`

### 注意事项
- 自动装箱和拆箱在编译时由编译器处理,因此在运行时不会有明显的性能损失。
- 包装类 `Long`、`Integer` 和 `Short` 提供了缓存机制,对于一定范围内的值(通常在 `-128` 到 `127` 之间),会使用相同的实例来避免创建过多的对象。这个范围可以通过 `java.lang.Integer.IntegerCache` 高度自定义。
- 过度使用自动装箱可能导致性能问题,尤其是在涉及到大量数据的情况下,因为它会增加对象的创建和垃圾回收的负担。
- 在进行算术运算时,如果涉及到基本数据类型和包装类型,Java 会自动拆箱基本数据类型,然后再进行运算。

自动装箱和拆箱使得在需要使用对象的情况下,可以更加方便地使用基本数据类型,同时保持代码的简洁性和可读性。然而,开发者应该注意它们可能带来的性能影响,并在适当的时候手动进行装箱或拆箱操作。
 

11.3 解释器和编译器

程序需要快速启动和执行的时候,解释器可以首先发挥作用,省去编译时间立刻运行。程序启动后,编译器逐渐发生作用,把越来越多的代码译为本地代码获得更高的执行效率。

11.4 方法内联

原理上是将目标方法的代码复制到发起调用的方法之中,减少方法调用。但实际需要进行很多优化准备(因为大部分调用都是虚方法)。例如采用类型继承关系分析、内联缓存等。

11.5 逃逸分析

分析对象动态作用域,当一个对象在方法里面被定义后,可能被外部方法引用,称为方法逃逸。被外部线程访问,称为线程逃逸。

若一个对象逃逸程度较低,可以采取不同程度的优化:

1. 栈上分配:如果确定对象不会逃逸到线程外,直接分配在栈上。

2. 标量替换:如果对象不会被方法外访问,可以将其拆分到最小基本类型。分配到栈上。

3. 同步消除:如果对象不会被线程外访问,可以消除其同步措施。

11.6 公共子表达式消除

如果一个表达式之前已经被计算过了,并且从之前的计算到现在E中所有变量都没有变化,那么无需重复计算。

12.3 Java 内存模型

12.4 Volatile

1. 保证此变量对所有线程的可见性

适用于:运算结果并不依赖变量的当前值,或者能确保只有单一线程修改此值;变量不需要与其他状态变量共同参与不变约束。

2. 禁止指令重排序

12.5 原子性、可见性、有序性

1. 原子性:基本数据类型的访问读写都是原子性的,当需要更大范围的保证时,提供了 synchronized 关键字。

2. 可见性:通过变量修改后把新值同步回主内存,在读取变量前从主内存刷新变量值来实现。此外 synchronized 和 final 关键字也可以保证可见性。

3. 有序性:在本线程内观察,所有操作都是有序的,在另外一个线程中观察则是无序的。 volatile 和 synchronized 都可以保证。

12.6 先行发生原则

先行发生:内存模型中定义的两项操作之间的偏序关系,即发生操作B之前,操作A的影响能被B观察到。

1. 程序次序规则:一个线程内,按控制流顺序执行。

2. 管程锁定原则: unlock 晚于 lock

3. volatile :对 volatile 的写先行发生于读

4. 线程启动:线程的 start() 动作先行发生于此线程的每一个动作

5. 线程终止:线程的所有操作都先行发生于对此线程的终止检测

6. 线程中断:对 interrupt的调用先行发生于被中断线程的代码检测到中断事件的发生

7. 对象终止:初始化先行于 finalize()

8. 传递性。

12.7 线程状态

13.1 线程安全

线程安全的不同级别

1. 不可变:例如 final 修饰的变量。

2. 绝对线程安全:很难达到

Vector 是 Java 中的一个同步的 List 实现,它的方法默认都是同步的,这意味着在多线程环境下,多个线程可以安全地访问 Vector 对象,而不需要额外的同步控制。

然而,即使 Vector 的方法是同步的,这并不意味着在多线程环境下对 Vector 进行的所有操作都是安全的。以下是一些可能导致问题的情况:

  1. 迭代器失效

    • 如果在一个线程中正在遍历 Vector,而另一个线程删除了元素,那么遍历的迭代器可能会失效。这是因为删除操作可能会改变底层数组的结构,导致迭代器的状态与实际数据不一致。
  2. 并发修改异常

    • 尽管 Vector 的方法是同步的,但如果在一个线程中删除元素后,另一个线程立即尝试访问该元素,可能会抛出 ConcurrentModificationException。这是因为 Vector 无法保证在删除操作和访问操作之间的原子性。
  3. 索引变化

    • 当一个线程删除了一个元素后,Vector 的大小会减小,但其他线程可能还不知道这个变化。如果这些线程仍然使用旧的索引来访问元素,可能会访问到错误的位置,甚至抛出 IndexOutOfBoundsException
  4. 可见性问题

    • 在多线程环境中,一个线程对 Vector 的修改可能对其他线程不可见,直到修改后的值被写回到主内存。如果其他线程没有看到最新的值,可能会使用错误的数据。
  5. 方法级别的同步

    • Vector 的同步是方法级别的,这意味着每次调用方法时都会进行同步。但是,如果一个线程在执行一个方法的过程中被中断,而另一个线程在此时调用了另一个方法,可能会发生不一致的状态。

3. 相对线程安全:对象的单次操作是线程安全的,但对于一些特定顺序的连续调用需要额外的手段来保证正确性。Java 中大部分声称线程安全的对象都属于此类。

4. 线程兼容

5. 线程对立:无论是否采取了同步措施,都无法在多环境使用。

13.2 线程安全的实现方法

1. 互斥同步:保证共享数据值被一条线程使用。例如 synchronized 和 lock

2. 非阻塞同步:CAS 方案

3. 无同步方案:

相关文章:

深入理解 Java 虚拟机第三版(周志明)

这次社招选的这本作为 JVM 资料查阅,记录一些重点 1. 虚拟机历史 Sun Classic VM :已退休 HotSpot VM:主流虚拟机,热点代码探测技术 Mobile / Embedded VM :移动端、嵌入式使用的虚拟机 2.2 运行时数据区域 程序计…...

算法 定长按组翻转链表

一、题目 已知一个链表的头部head,每k个结点为一组,按组翻转。要求返回翻转后的头部 k是一个正整数,它的值小于等于链表长度。如果节点总数不是k的整数倍,则剩余的结点保留原来的顺序。示例如下: (要求不…...

安装nfs和rpcbind设置linux服务器共享磁盘

1、安装nfs和rpcbind 1.1 检查服务器是否安装nfs和rpcbind,执行下命令,检查服务器是否安装过。 rpm -qa|grep nfs rpm -qa|grep rpcbind 说明服务器以安装了,如果没有就需要自己安装 2、安装nfs和rpcbind 将rpm安装包: libtirpc-…...

物联网在电力行业的应用

作者主页: 知孤云出岫 这里写目录标题 作者主页:物联网在电力行业的应用简介主要应用领域代码案例分析1. 智能电表数据采集和分析2. 设备监控和预测性维护3. 能耗管理和优化4. 电力负载预测5. 分布式能源管理6. 电动汽车充电管理7. 电网安全与故障检测 物联网在电力行业的应用…...

Java 代码规范if嵌套

在Java编程中,过度的if嵌套会使代码难以阅读和维护。为了遵循良好的代码规范,我们应尽量减少嵌套的深度。这通常可以通过重新组织代码或使用其他结构(如switch语句,或者将逻辑封装到单独的方法中)来实现。 以下是一个…...

ASPICE如何确保汽车软件产品质量的稳固基石

ASPICE通过一系列的方法和原则来保障汽车软件产品的质量,以下是其保障产品质量的几个关键方面: 制定明确的质量方针和目标: ASPICE要求组织制定明确的质量方针和目标,这些方针和目标与客户需求和预期相一致。 开发团队需要定义软…...

【深度学习】yolov8-seg分割训练,拼接图的分割复原

文章目录 项目背景造数据训练 项目背景 在日常开发中,经常会遇到一些图片是由多个图片拼接来的,如下图就是三个图片横向拼接来的。是否可以利用yolov8-seg模型来识别出这张图片的三张子图区域呢,这是文本要做的事情。 造数据 假设拼接方式有…...

Python升级打怪—Django入门

目录 一、Django简介 二、安装Django 三、创建Dajngo项目 (一) 创建项目 (二) 项目结构介绍 (三) 运行项目 (四) 结果 一、Django简介 Django是一个高级Python web框架,鼓励快速开发和干净、实用的设计。由经验丰富的开发人员构建,它解决了web开…...

leetcode面试题17.最大子矩阵

sooooooo long没刷题了,汗颜 题目链接:leetcode面试题17 1.题目 给定一个正整数、负整数和 0 组成的 N M 矩阵,编写代码找出元素总和最大的子矩阵。 返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和…...

计算机网络:构建联结的基础

目录 1. 网络拓扑结构 1.1 星型拓扑 1.2 环型拓扑 1.3 总线型拓扑 1.4 网状拓扑 2. 传输介质 2.1 双绞线 2.2 同轴电缆 2.3 光纤 2.4 无线电波 3. 协议栈模型 3.1 OSI模型 3.2 TCP/IP模型 4. 网络设备 4.1 交换机 4.2 路由器 4.3 网关 4.4 防火墙 5. IP地址…...

node和npm安装;electron、 electron-builder安装

1、node和npm安装 参考: https://blog.csdn.net/sw150811426/article/details/137147783 下载: https://nodejs.org/dist/v20.15.1/ 安装: 点击下载msi直接运行安装 安装完直接cmd打开可以,默认安装就已经添加了环境变量&…...

操作系统概念(黑皮书)阅读笔记

操作系统概念(黑皮书)阅读笔记 进程和内存管理部分章节 导论: 操作系统类似于政府,其本身不能实现任何有用功能,而是提供一个方便其他程序执行有用工作的环境 ​ 个人理解:os是government的作用&#xff0…...

matlab gui下的tcp client客户端编程框架

GUI界面 函数外定义全局变量 %全局变量 global TcpClient; %matlab作为tcpip客户端 建立连接 在“连接”按钮的回调函数下添加以下代码: global TcpClient;%全局变量 TcpClient tcpip(‘192.168.1.10’, 7, ‘NetworkRole’,‘client’); %连接到服务器地址和端…...

Matplotlib : Python 的绘图库

Matplotlib 是一个 Python 的绘图库,广泛用于生成各种静态、动态、交互式的图表。它基于 NumPy,一个用于科学计算的 Python 库。Matplotlib 可以用于生成出版质量级别的图表,并且提供了丰富的定制选项,以适应不同用户的需求。以下…...

数据编织 VS 数据仓库 VS 数据湖

目录 1. 什么是数据编织?2. 数据编织的工作原理3. 代码示例4. 数据编织的优势5. 应用场景6. 数据编织 vs 数据仓库6.1 数据存储方式6.2 数据更新和实时性6.3 灵活性和可扩展性6.4 查询性能6.5 数据治理和一致性6.6 适用场景6.7 代码示例比较 7. 数据编织 vs 数据湖7.1 数据存储…...

CSS(十一)——CSS分组和嵌套,尺寸(Dimension)

CSS 分组 和 嵌套 选择器 分组选择器 举个例子,多个标签有同一个样式,就可以不一个一个分开写,使用分组选择器 比如: h1 {color:green; } h2 {color:green; } p {color:green; } 就可以写为: h1,h2,p {color…...

必备神器!三款优秀远程控制电脑软件推荐

嘿,各位职场小伙伴们,今儿个咱们来聊聊个挺实用又带点“科技范儿”的话题——电脑远程控制那点事儿。作为刚踏入职场不久的新人,我深刻体会到,在这信息爆炸的时代,掌握几招远程操作的技能,简直就是给自个儿…...

关于正运动学解机器人手臂算法

机器人正运动学是机器人学的一个分支,研究机器人的运动和位置之间的关系。它通过解析机器人的结构和关节参数,以及给定的关节角度,来计算机器人的末端执行器的位置和姿态。 机器人正运动学算法通常使用DH(Denavit-Hartenberg&…...

MySQL 约束 (constraint)

文章目录 约束(constraint)列级约束和表级约束给约束起名字(constraint)非空约束(no null)检查约束(check)唯一性约束 (unique)主键约束 (primary key)主键分类单一主键复合主键主键自增 (auto_increment) 外键约束外什…...

用python程序发送文件(python实例二十六)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.文件上传 3.1 代码构思 3.2 服务端代码 3.3 客户端代码 3.4 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具…...

最新源支付系统源码 V7版全开源 免授权 附搭建教程

本文来自:最新源支付系统源码 V7版全开源 免授权 附搭建教程 - 源码1688 简介: 最新源支付系统源码_V7版全开源_免授权_附详细搭建教程_站长亲测 YPay是专为个人站长打造的聚合免签系统,拥有卓越的性能和丰富的功能。它采用全新轻量化的界面…...

HTML:lang属性作用

lang作用 用法常见语言代码优点示例结构效果说明分析HTML 基础结构导航栏内容部分总结 扩展 用法 HTML 文档级别: 在 <html> 标签上使用 lang 属性&#xff0c;指定整个文档的语言。 <!DOCTYPE html> <html lang"en"> <head><meta charse…...

Android SurfaceFlinger——纹理的绘制流程(二十八)

在系统开机动画的播放流程中,会从给定的资源文件中加载纹理数据并初始化一个 OpenGL 纹理对象,这里我们就来解析软件模拟纹理的绘制流程。 一、纹理概述 在 Android 的 SurfaceFlinger 系统组件中,纹理(Texture)是一个核心概念,特别是在涉及到图形渲染和显示的过程中。 …...

深入解析Memcached:C#中的应用与实战案例

目录 Memcached简介Memcached的特点Memcached的工作原理Memcached的应用场景Memcached的安装和配置Memcached与C#的集成 引入依赖配置Memcached客户端C#代码示例 存储数据读取数据删除数据深入解析Memcached 数据存储和过期策略分布式架构性能优化实战案例 缓存数据库查询结果实…...

keyring 库

目录 安装 keyring 基本用法 1. 设置密码 2. 获取密码 3. 删除密码 4. 返回当前使用的默认密钥环 5. 列出所有密码 支持的后端 keyring 是一个 Python 库&#xff0c;用于将敏感信息&#xff08;如密码&#xff09;安全地存储在操作系统的密码管理器中。它支持多种平台…...

[css3] 如何设置边框颜色渐变

div {border: 4px solid;border-image: linear-gradient(to right, #8f41e9, #578aef) 1; }参考&#xff1a; 5种CSS实现渐变色边框&#xff08;Gradient borders方法的汇总...

Redux +Toolkit 工具包快速入门

您将学到什么 如何设置并使用 Redux Toolkit 和 React-Redux 先决条件 熟悉ES6 语法和功能了解 React 术语&#xff1a;JSX、State、Function Components 、 Props和Hooks理解Redux 术语和概念 1、基本使用 1.1、安装 Redux Toolkit 和 React- Redux 将 Redux Toolkit 和 Rea…...

【Python数据增强】图像数据集扩充

前言&#xff1a;该脚本用于图像数据增强&#xff0c;特别是目标检测任务中的图像和标签数据增强。通过应用一系列数据增强技术&#xff08;如旋转、平移、裁剪、加噪声、改变亮度、cutout、翻转等&#xff09;&#xff0c;生成多样化的图像数据集&#xff0c;以提高目标检测模…...

实时同步:使用 Canal 和 Kafka 解决 MySQL 与缓存的数据一致性问题

目录 1. 准备工作 2. 将需要缓存的数据存储 Redis 3. 监听 canal 存储在 Kafka Topic 中数据 1. 准备工作 1. 开启并配置MySQL的 BinLog&#xff08;MySQL 8.0 默认开启&#xff09; 修改配置&#xff1a;C:\ProgramData\MySQL\MySQL Server 8.0\my.ini log-bin"HELO…...

WINUI——Microsoft.UI.Xaml.Markup.XamlParseException:“无法找到与此错误代码关联的文本。

开发环境 VS2022 .net core6 问题现象 在Canvas内的子控件要绑定Canvas的兄弟控件的一个属性&#xff0c;在运行时出现了下述报错。 可能原因 在 WinUI&#xff08;特别是用于 UWP 或 Windows App SDK 的版本&#xff09;中&#xff0c;如果你尝试在 XAML 中将 Canvas 内的…...

C语言 | Leetcode C语言题解之第283题移动零

题目&#xff1a; 题解&#xff1a; void swap(int *a, int *b) {int t *a;*a *b, *b t; }void moveZeroes(int *nums, int numsSize) {int left 0, right 0;while (right < numsSize) {if (nums[right]) {swap(nums left, nums right);left;}right;} }...

WPF项目实战视频《二》(主要为prism框架)

14.prism框架知识&#xff08;1&#xff09; 使用在多个平台的MVVM框架 新建WPF项目prismDemo 项目中&#xff1a;工具-NuGet包管理&#xff1a;安装Prism.DryIoc框架 在git中能看Prism的结构和源代码&#xff1a;git链接地址 例如&#xff1a;Prism/src/Wpf/Prism.DryIoc.Wpf…...

【微信小程序实战教程】之微信小程序 WXS 语法详解

WXS语法 WXS是微信小程序的一套脚本语言&#xff0c;其特性包括&#xff1a;模块、变量、注释、运算符、语句、数据类型、基础类库等。在本章我们主要介绍WXS语言的特性与基本用法&#xff0c;以及 WXS 与 JavaScript 之间的不同之处。 1 WXS介绍 在微信小程序中&#xff0c…...

Android中Service学习记录

目录 一 概述二 生命周期2.1 启动服务startService()2.2 绑定服务bindService()2.3 先启动后绑定2.4 先绑定后启动 三 使用3.1 本地服务&#xff08;启动式&#xff09;3.2 可通信的服务&#xff08;绑定式&#xff09;3.3 前台服务3.4 IntentService 总结参考 一 概述 Servic…...

Elasticsearch:Java ECS 日志记录 - log4j2

ECS 记录器是你最喜欢的日志库的格式化程序/编码器插件。它们可让你轻松将日志格式化为与 ECS 兼容的 JSON。ECS 兼容的 JSON 日志记录可以帮我们简化很多分析&#xff0c;可视化及解析的工作。在今天的文章里&#xff0c;我来详述如何在 Java 应用里生成 ECS 相兼容的日志。 …...

MongoDB自学笔记(四)

一、前文回顾 上一篇文章中我们学习了MongoDB中的更新方法&#xff0c;也学了一部分操作符。今天我们将学习最后一个操作“删除”。 二、删除 原始数据如下&#xff1a; 1、deleteOne 语法&#xff1a;db.collection.deleteOne(< query >,< options >) 具体参…...

时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法(CPO)优化VMD二次分解

时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法&#xff08;CPO&#xff09;优化VMD二次分解 目录 时序分解 | Matlab基于CEEMDAN-CPO-VMD的CEEMDAN结合冠豪猪优化算法&#xff08;CPO&#xff09;优化VMD二次分解效果一览基本介绍程序设计参考资料 效果一览…...

新版海螺影视主题模板M3.1全解密版本多功能苹果CMSv10后台自适应主题

苹果CMS2022新版海螺影视主题M3.1版本&#xff0c;这个主题我挺喜欢的&#xff0c;之前也有朋友给我提供过原版主题&#xff0c;一直想要破解但是后来找了几个SG11解密的大哥都表示解密需要大几百大洋&#xff0c;所以一直被搁置了。这个版本是完全解密的&#xff0c;无需SG11加…...

汽车免拆诊断案例 | 2014 款上汽名爵 GT 车发动机无法起动

故障现象 一辆2014款上汽名爵GT车&#xff0c;搭载15S4G发动机&#xff0c;累计行驶里程约为18.4万km。该车因左前部发生碰撞事故进厂维修&#xff0c;更换损坏的部件后起动发动机&#xff0c;起动机运转有力&#xff0c;但无着机迹象。用故障检测仪检测&#xff0c;发现无法与…...

vue3前端开发-小兔鲜项目-登录功能的业务接口调用

vue3前端开发-小兔鲜项目-登录功能的业务接口调用!这次&#xff0c;正式调用远程服务器的登录接口了。大家要必须使用测试账号密码&#xff0c;才能验证我们的代码。 测试账号密码是&#xff1a;账号&#xff08;xiaotuxian001&#xff09;&#xff1b;密码是&#xff08;1234…...

【Linux】vim编辑器使用详解

目录 一、vim编辑器简介二、 vim编辑器使用指南1.基本操作1.进入与退出2.模式切换 2.命令模式1.移动光标2.选择文本&#xff08;可视模式&#xff09;3.删除文字4.复制粘贴5.替换6.撤销7.注释8.多文件窗口切换 3.底行模式1.列出每行的行号2.跳转到某行3.查找字符4.保存文件5.在…...

手机怎么设置不同的ip地址

在数字化日益深入的今天&#xff0c;智能手机已成为我们生活、工作和学习中不可或缺的设备。然而&#xff0c;随着网络应用的广泛和深入&#xff0c;我们有时需要为手机设置不同的IP地址来满足特定需求。比如&#xff0c;避免网络限制、提高网络安全、或者进行网络测试等。本文…...

SpringBoot读取配置的6种方式

在SpringBoot应用开发中&#xff0c;配置文件是不可或缺的一部分。它们帮助我们管理应用的运行时参数&#xff0c;使得应用的部署和维护变得更加灵活。SpringBoot提供了多种方式来读取配置文件&#xff0c;每种方式都有其适用场景和优缺点。本文将介绍六种常用的SpringBoot读取…...

1.1 openCv -- 介绍

OpenCV(开放源代码计算机视觉库:http://opencv.org)是一个开源库,包含了数百种计算机视觉算法。本文件描述了所谓的OpenCV 2.x API,这是一个本质上基于C++的API,与基于C的OpenCV 1.x API(C API已被弃用,并且自从OpenCV 2.4版本起不再使用“C”编译器进行测试)相对。 …...

探索PostgreSQL的GUI工具:提升数据库管理效率

在当今快速发展的技术世界中&#xff0c;数据库管理是任何软件开发项目的核心部分。PostgreSQL&#xff0c;作为一款功能强大的开源关系型数据库管理系统&#xff0c;因其稳定性、可靠性和高度的可扩展性而广受开发者和数据库管理员的青睐。然而&#xff0c;尽管PostgreSQL自带…...

【从零开始实现stm32无刷电机FOC】【实践】【5/7 stm32 adc外设的高级用法】

目录 采样时刻触发采样同步采样 点击查看本文开源的完整FOC工程 本节介绍的adc外设高级用法用于电机电流控制。 从前面几节可知&#xff0c;电机力矩来自于转子的q轴受磁力&#xff0c;而磁场强度与电流成正比&#xff0c;也就是说电机力矩与q轴电流成正相关&#xff0c;控制了…...

springcloud接入seata管理分布式事务

下载安装包 链接: seata 配置seata-server 文件上传Linux解压 压缩包我放在/usr/local/seata中 tar -zxvf seata-server-2.0.0.tar.gz修改配置文件 设置nacos为注册和配置中心 进入文件夹 cd /usr/local/seata/seata/conf修改application.yml文件 ...... ...... cons…...

Android APP 音视频(02)MediaProjection录屏与MediaCodec编码

说明&#xff1a; 此MediaProjection 录屏和编码实操主要针对Android12.0系统。通过MediaProjection获取屏幕数据&#xff0c;将数据通过mediacodec编码输出H264码流&#xff08;使用ffmpeg播放&#xff09;&#xff0c;存储到sd卡上。 1 MediaProjection录屏与编码简介 这里…...

java中log4j.properties配置文件浅析

Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的&#xff0c;它可按keyvalue格式的设置或xml格式的设置信息。通过配置&#xff0c;可以创建出Log4J的运行环境。 1、配置文件 Log4J配置文件的基本格式如下&#xff1a; #配置根Logger log4j.roo…...

RV1126 Linux 系统,接外设,时好时坏(二)排查问题的常用命令

在 RV1126 Linux 系统中,排查外设连接问题时,可以使用多种命令来诊断和调试。以下是一些常用的命令和工具: 1. 查看系统日志 dmesg: 显示内核环形缓冲区的消息,通常包含设备初始化、驱动加载和错误等信息。 dmesg | grep <设备名或相关关键字>journalctl: 查看系统…...