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

【Java校招面试】基础知识(五)——GC

目录

  • 前言
  • 一、基础概念
  • 二、垃圾回收算法
  • 三、垃圾收集器
  • 四、引用
  • 后记


前言

本篇主要介绍Java垃圾回收机制——GC的相关内容。

“基础知识”是本专栏的第一个部分,本篇博文是第五篇博文,如有需要,可:

  1. 点击这里,返回本专栏的索引文章
  2. 点击这里,返回上一篇《【Java校招面试】基础知识(四)——JVM》
  3. 点击这里,前往下一篇《【Java校招面试】基础知识(六)——计算机网络》

一、基础概念

01. 垃圾回收(GC)发生的位置
垃圾回收发生在JVM内存模型的堆内存

02. 对象被判定为垃圾的标准
没有被其他对象引用。

03. 判定对象是否为垃圾的算法
1) 引用计数算法: 通过判断对象的引用数量来决定对象是否可以被回收。每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1。任何引用计数为0的对象实例可以被当作垃圾收集。

  • 优点: 执行效率高,程序执行受影响小。
  • 缺点: 无法检测出循环引用的情况,会导致内存泄漏。

2) 可达性分析算法: 通过判断对象的引用链是否可达来决定对象是否可以被回收;
在这里插入图片描述
04. 可作为GC Root的对象
1) 虚拟机栈中引用的对象(栈帧中的本地变量表);
2) 方法区中的常量引用对象;
3) 方法区中的类静态属性引用的对象;
4) 本地方法栈中JNI(Native方法)的引用对象;
5) 活跃线程的引用对象。


二、垃圾回收算法

01. 标记清除算法(Mark and Sweep)

  • 标记: 从根集合进行扫描,对存活的对象进行标记
  • 清除: 对堆内存从头到尾进行线性遍历,回收不可达对象内存
    在这里插入图片描述
  • 存在的问题: 产生大量不连续的碎片,造成堆内存碎片化

02. 复制算法(Copying)
将堆内存按照一定的比例分成两块或多块,分为对象面和空闲面。选择其中的一块或两块作为对象面,其他的作为空闲面。对象主要在对象面上创建。当对象面的内存用完时,将存活的对象从对象面复制到空闲面。然后将对象面多有对象内存清除。适用于对象存活率低的场景。
在这里插入图片描述

  • 优点:
    1) 解决了碎片化的问题;
    2) 顺序分配内存,简单高效;
    3) 适用于对象存活率较低的场景;
  • 缺点: 在对象存活率较高的场景中,需要进行较多的复制

03. 标记整理算法(Compacting)

  • 标记: 从根集合进行扫描,对存活的对象进行标记
  • 清除: 移动所有存活的对象,且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收。
    在这里插入图片描述
    优点:
    1) 避免内存的不连续性;
    2) 不用设置两块内存互换;
    3) 适用于对象存活率较高的场景;

04. 分代收集算法(Generational Collector)——目前的主流垃圾回收算法

  • 特点:
    1) 垃圾回收算法的组合;
    2) 按照对象生命周期的不同划分区域以采取不同的垃圾回收算法;
  • 目的: 提高JVM的回收效率

05. JDK 8中对堆内存所作的调整
1) JDK 8以前及JDK 8的JVM内存模型区别
在这里插入图片描述
从图中可见,JDK 8中,从堆内存中去除了Permanent Generation(永久代),取而代之的是在本地内存中新设的Meta Space(元空间)

2) 永久代中存放的数据
   类的元数据(如类的名称、访问修饰符、父类、实现的接口等)
   常量池
   静态变量
   即时编译器编译后的代码
   一些需要在类加载时完成的初始化操作

3) 永久代存在的问题(被元空间替代的原因)
  ① 内存限制问题: 永久代的大小是通过-XX:MaxPermSize参数来指定的,而该参数的默认值较小,容易导致OutOfMemoryError异常。
  ② 类加载器泄漏问题: 在永久代中,存在着一些类加载器无法被回收的情况,导致永久代的内存无法释放,最终也会导致OutOfMemoryError异常。
  ③ 字符串常量池溢出问题: 由于字符串常量池被存储在永久代中,如果不合理地使用字符串常量,就会导致永久代的内存快速耗尽,最终也会导致OutOfMemoryError异常。
  ④ 性能问题: 永久代的垃圾回收效率很低,会导致应用程序的性能下降。
  ⑤ 维护成本问题: 永久代需要手动调整大小,而且需要进行垃圾回收,增加了应用程序的维护成本。

4) 永久代和元空间的区别
  ① 存储位置: 永久代位于JVM堆内存中,而元空间则是位于本地内存中。
  ② 大小限制: 永久代的大小是固定的,而且它很容易被填满,导致OutOfMemoryError。而元空间的大小是动态的,它可以根据需要来自动调整大小,因此更加灵活。
  ③ 垃圾回收: 永久代是由JVM的垃圾回收机制来进行管理和清除的。而元空间不再使用垃圾回收机制进行管理,而是使用本地内存的机制,例如使用操作系统的虚拟内存来管理。
  ④ 移植性: 由于永久代是Java虚拟机的一部分,因此它只能在Java虚拟机中使用。而元空间是本地内存的一部分,因此它可以在不同的虚拟机和操作系统中使用。

06. 垃圾回收器的分类

  • Minor GC: 针对年轻代的垃圾回收,通常情况下只会回收年轻代中的Eden区和一个Survivor区。
  • Major GC: 针对老年代的垃圾回收,通常情况下会回收整个老年代。
  • Full GC: 针对整个堆空间的垃圾回收,包括年轻代和老年代。

他们的区别主要有以下几点:
1) 发生频率不同: Minor GC频率很高,可能会发生多次,Major GC和Full GC发生频率较低。
2) 对应用程序的影响不同: Minor GC对应用程序的影响较小,Major GC和Full GC会导致较长的停顿时间,对应用程序的影响较大。
3) 回收效率不同: Minor GC的回收效率较高,Major GC和Full GC的回收效率较低。

07. 触发Full GC的条件(答出3点即可)
1) 老年代空间不足
2) 永久代空间不足(针对JDK 7及以下版本)
3) CMS GC时出现promotion failedconcurrent mode failure
4) Minor GC晋升到老年代的平均大小大于老年代的剩余空间
5) 程序中手动调用System.gc()
6) 使用RMI(远程方式)来进行RPC或管理的JDK应用,每小时执行1次Full GC

08. 年轻代
在这里插入图片描述
用于存放并尽可能快速地收集掉那些生命周期短的对象
1) 包含一个Eden(伊甸园)区和两个Suivivor(一个From区,一个To区),比例为8:1:1
2) 每次将Eden和From中的存活对象复制到To区中,最后清理掉Eden和From区;
3) 每次复制,存活对象的年龄+1,当对象的年龄达到一定值(默认是15,可以通过-XX:MaxTenuringThreshold修改)时,对象将会被移动到老年代。

09. 老年代
存放生命周期较长的对象,占整个堆内存的2/3
在这里插入图片描述
10. 常见的GC调优参数

  • -XX:SurvivorRatio, Eden和Suivivor的比值,默认8:1;
  • -XX:NewRatio, 老年代和年轻代内存大小的比例;
  • -XX:MaxTenuringThreshold, 对象聪年轻代晋升到老年代经过GC次数的最大阈值;

11. Stop-The-World
1) JVM由于要执行GC而停止了应用程序的执行;
2) 任何一种GC算法中都会发生;
3) 多数GC优化通过减少Stop-The-World发生的时间来提高程序性能。

12. SafePoint
1) 分析过程中对象引用关系不会发生变化的点;
2) 产生SafePoint的地方: 方法调用、循环跳转、异常跳转等。GC发生时,让所有的线程都跑到最新的安全点,如果发现线程不在安全点,则恢复线程,等其跑到安全点。
3) 安全点数量需要适中,太少会让GC等待太长的时间;太多会增加程序运行的负荷。


三、垃圾收集器

01. 新生代常见的垃圾收集器
1) Serial收集器(-XX:+UseSerialGC,复制算法)
在这里插入图片描述

  • 单线程收集,进行垃圾收集时,必须暂停所有工作线程;
  • 简单高效,Client模式下默认的年轻代收集器。

2) ParNew收集器(-XX:+UseParNewGC,复制算法)
在这里插入图片描述

  • 多线程收集,其余的行为、特点和Serial收集器一样;
  • 单核执行效率不如Serial,在多核下执行才有优势,默认开启的线程数与CPU核数相同;
  • 在Server模式下重要的收集器,除Serial外,只有ParNew可以和CMS收集器配合工作。

3) Parallel Scavenge收集器(-XX:+UseParallelGC,复制算法)
在这里插入图片描述
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)

  • 比起关注用户线程停顿时间,更关注系统吞吐量;
  • 在多核下执行才有优势,Server模式下默认的年轻代收集器;
  • 如果对于垃圾收集器运作原理不是很了解,在优化过程中遇到困难时,可以使用-XX:+UseAdaptiveSizePolicy把调优任务交给虚拟机。

02. 老年代常见的垃圾收集器
1) Serial Old收集器(-XX:+UseSerialOldGC,标记整理算法)
在这里插入图片描述

  • 单线程收集,进行垃圾收集时,必须暂停所有工作线程;
  • 简单高效,Client模式下默认的老年代收集器。

2) Parallel Old收集器(-XX:+UseParallelOldGC,标记整理算法)
多线程,吞吐量优先
在这里插入图片描述
3) CMS收集器(-XX:+UseConcMarkSweepGC,标记清除算法)
在这里插入图片描述

  • 初始标记:Stop-The-World
  • 并发标记:并发追溯标记,程序不会停顿
  • 并发预清理:查找执行并发标记阶段从年轻代晋升到老年代的对象
  • 重新标记:暂停虚拟机,扫描CMS堆中的剩余对象
  • 并发清理:清理垃圾对象,程序不会停顿
  • 并发重置:重置CMS收集器的数据结构

存在的问题: 采用标记清除算法,不对内存进行压缩,会造成空间碎片化的问题

03. 既可用于老年代也可用于年轻代的GC
G1(Garbage First)收集器(-XX:+UseG1GC,复制+标记整理算法)
在这里插入图片描述
1) 特点:

  • 并行和并发
  • 分代收集
  • 空间整合
  • 可预测的停顿

2) 设计:

  • 将整个Java堆内存划分成多个大小相等的Region
  • 年轻代和老年代不再物理隔离

04. 所有垃圾收集器的关系
在这里插入图片描述
05. 两个在新的垃圾收集器
这两个垃圾收集器在JDK 11中作为实验特性引入,在JDK 15中已成为正式的垃圾收集器。

  • Epsilon GC
  • ZGC

06. Object类的finalize()方法的作用和C++的析构函数有什么不同?
1) C++中的析构函数是在对象生命周期结束时自动调用的,而不是在垃圾回收时调用的。
2) C++中的析构函数可以手动调用,而Java中的finalize()方法只能由垃圾回收器调用。
3) C++中的析构函数可以被重载,而Java中的finalize()方法是Object类的一个标准方法,不能被重载。


四、引用

01. Java中的强引用,软引用,弱引用,虚引用都是什么?
强引用(Strong Reference):
1) 最普遍的引用: Object obj = new Object();
2) 抛出OutOfMemoryError终止程序也不会回收具有强引用的对象;
3) 通过将对象的引用设置为null来弱化引用,使其被回收。

软引用(Soft Reference):
1) 对象处在有用但非必须的状态;
2) 只有当内存空间不足时,GC才会回收该引用的对象的内存;
3) 可以用来实现高速缓存;
4) 用法

	String str = new String("abc");SoftReference<String> softReference = new SoftReference<>(str);

弱引用(Weak Reference):
1) 非必需的对象,比软引用更弱一些;
2) GC时会被回收;
3) 由于GC线程优先级很低,被回收的概率也不大;
4) 适用于引用偶尔被使用且不影响垃圾收集的对象;
5) 用法:

	String str = new String("abc");WeakReference<String> weakReference = new weakReference<>(str);

虚引用(Phantom Reference):
1) 不会决定对象的生命周期;
2) 任何时候都可能被垃圾收集器回收;
3) 跟踪对象被垃圾收集器回收的活动,起哨兵的作用;
4) 必须和引用队列ReferenceQueue联合使用,因为它的get函数返回值永远为null,因此无法用get函数判断它是否已被回收;
5) 用法:

	String str = new String("abc");ReferenceQueue refQueue = new ReferenceQueue();PhantomReference ref = new PhantomReference(str, refQueue);

02. 四种引用的比较
强引用 > 软引用 > 弱引用 > 虚引用

引用类型被回收的时间用途生存时间
强引用从来不会对象的一般状态JVM停止运行时终止
软引用内存不足时对象缓存内存不足时终止
弱引用垃圾回收时对象缓存GC运行后终止
虚引用未知/瞬间标记、哨兵未知/瞬间

03. 引用队列(ReferenceQueue)

  • 无实际存储结构,存储逻辑依赖于内部节点之间的关系来表达;
  • 存储关联的且被GC的软引用、弱引用和虚引用。

04. 引用队列的代码示例
1) 目标对象MyObject

	public class MyObject {public String name;public MyObject(String name){this.name = name;}@Overrideprotected void finalize() throws Throwable {System.out.printf("Finalizing Object %s", name);super.finalize();}}

2) 目标对象弱引用MyObjectWeakReference

	public class MyObjectWeakReference extends WeakReference<MyObject>{public String name;public MyObjectWeakReference(MyObject referent, ReferenceQueue<MyObject> q) {super(referent, q);this.name = referent.name;}}

3) 调用类

	public class ReferenceQueueTest {private static ReferenceQueue<MyObject> q = new ReferenceQueue<>();private static void checkQueue() {Reference ref;while ((ref = (Reference<MyObject>) q.poll()) != null) {System.out.println("In Queue: Weak Reference of " + ((MyObjectWeakReference) ref).name);System.out.println("Reference Object " + ref.get());}}public static void main(String[] args) {List<WeakReference<MyObject>> refList = new ArrayList<>();for (int i = 0; i < 3; i++) {refList.add(new MyObjectWeakReference(new MyObject("MyObject" + i), q));System.out.println("Created Weak Reference " + refList.get(i));}System.out.println("First Time Check.");checkQueue();System.gc();try {Thread.sleep(1000);} catch (InterruptedException ie) {}System.out.println("Second Time Check.");checkQueue();}}

4) 代码流程分析
i) 创建3个弱引用对象;
ii) 输出引用队列中的所有引用对象;
iii) 手动gc并等待其结束(这里是让线程睡眠1秒);
iv) 再次输出引用队列中的所有引用对象。

5) 代码输出

Created Weak Reference referencequeuetest.MyObjectWeakReference@15db9742
Created Weak Reference referencequeuetest.MyObjectWeakReference@6d06d69c
Created Weak Reference referencequeuetest.MyObjectWeakReference@7852e922
First Time Check.
Finalizing Object MyObject2
Finalizing Object MyObject1
Finalizing Object MyObject0
Second Time Check.
In Queue: Weak Reference of MyObject2
Reference Object null
In Queue: Weak Reference of MyObject1
Reference Object null
In Queue: Weak Reference of MyObject0
Reference Object null

6) 代码输出解析
i) 创建3个弱引用对象;
ii) 首次检查时,因为还没有发生GC,所以引用队列里什么都没有,没有任何输出;
iii) GC发生,MyObject的finalize方法被调用;
iv) 第二次检查时,因为已经发生GC,所以3个MyObjectWeakReference都在RefernceQueue里;
v) 因为已经发生GC,所以通过ref.get()得到的对象为null;


后记

GC(垃圾收集)部分内容也不少,我将这些知识点分为基础概念垃圾回收算法垃圾收集器引用4个部分,便于阅读和查找。

相关文章:

【Java校招面试】基础知识(五)——GC

目录 前言一、基础概念二、垃圾回收算法三、垃圾收集器四、引用后记 前言 本篇主要介绍Java垃圾回收机制——GC的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第五篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回本专…...

使用CMake调用Makefile 项目

目录标题 基本示例Cmake传递lib给MakefileCmake传递参数给Makefile&#xff0c;比如make cleanWindows下使用Cmake调用Makefile 基本示例 如果项目是使用传统的Makefile构建的&#xff0c;并且您希望使用CMake调用这些Makefile&#xff0c;您可以使用CMake的add_custom_target…...

快速傅里叶变换FFT学习笔记

点值表示法 我们正常表示一个多项式的方式&#xff0c;形如 A ( x ) a 0 a 1 x a 2 x 2 . . . a n x n A(x)a_0a_1xa_2x^2...a_nx^n A(x)a0​a1​xa2​x2...an​xn&#xff0c;这是正常人容易看懂的&#xff0c;但是&#xff0c;我们还有一种表示法。 我们知道&#xf…...

如何下载安装驱动

1 打开浏览器 这里以Edge浏览器举例 第一步打开桌面上的Edge浏览器 如果您的桌面上没有 那么找到搜索栏 搜索Edge 然后打开 打开之后一般是这样 然后把我发送您的地址 驱动下载地址 https://t.lenovo.com.cn/yfeyfYyD &#xff08;这个网址只是一个例子&#xff09; 删除掉前…...

鸿蒙Hi3861学习四-Huawei LiteOS介绍

一、什么是LitesOS Huawei LiteOS是华为针对物联网领域推出的轻量级物联网操作系统&#xff0c;是华为物联网战略的重要组成部分&#xff0c;具备轻量级、低功耗、互联互通、组件丰富、快速开发等关键能力。基于物联网领域业务特征打造领域性技术栈&#xff0c;为开发者提供“一…...

Vue核心 收集表单数据 过滤器

1.14. 收集表单数据 收集表单数据: 若: &#xff0c;则v-model收集的是value值&#xff0c;用户输入的就是value值。若: &#xff0c;则v-model收集的是value值&#xff0c;且要给标签配置value值。若: 没有配置input的value属性&#xff0c;那么收集的就是checked(勾选 or 未…...

华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包

华为EC6108V9E&#xff0f;EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的…...

数字化转型导师坚鹏:面向数字化转型的大数据顶层设计实践

面向数字化转型的大数据顶层设计实践 课程背景&#xff1a; 数字化背景下&#xff0c;很多企业存在以下问题&#xff1a; 不清楚大数据思维如何建立&#xff1f; 不清楚企业大数据分析方法&#xff1f; 不了解大数据应用成功案例&#xff1f; 课程特色&#xff1a; …...

day27_mysql

今日内容 零、 复习昨日 一、单表查询 二、多表联查 零、 复习昨日 1 DDL,DML,DQL是啥 DDL 数据定义语言&#xff08;库&#xff0c;表&#xff0c;列&#xff09;DML 数据操作语言&#xff08;表内数据的操作增删改&#xff09;DQL 数据查询语言&#xff08;表内数据的查询&am…...

QwtPlotCurve使用说明

QwtPlotCurve是Qwt库中用于绘制曲线的类&#xff0c;可以在QwtPlot上绘制各种类型的曲线&#xff0c;如折线、样条线、散点等。以下是QwtPlotCurve的一些常用函数和使用说明&#xff1a; setSamples(const QPolygonF &samples)&#xff1a;设置曲线的数据点&#xff0c;参数…...

JS逆向 -- 某平台登录加密分析

一、打开网站&#xff0c;使用账号密码登录 账号&#xff1a;aiyou123.com 密码&#xff1a;123456 二、通过F12抓包&#xff0c;抓到如下数据&#xff0c;发现密码加密了 三、加密结果是32位&#xff0c;首先考虑是md5加密。 四、全局搜索pwd&#xff0c;点击右上角&#xf…...

一分钟快速实现Flask框架的蓝图和视图

一分钟快速实现Flask框架的蓝图和视图 Flask是一个轻量级的Web应用框架&#xff0c;非常适合快速开发小型的Web应用。Flask框架使用蓝图&#xff08;Blueprint&#xff09;和视图&#xff08;View&#xff09;的概念来组织应用程序的代码。在本文中&#xff0c;我们将介绍如何…...

Mysql 约束练习【第13章_约束】

#第13章_约束 /* 基础知识 1.1 为什么需要约束&#xff1f; 为了保证数据的完整性&#xff01; 1.2 什么叫约束&#xff1f;对表中字段的限制。 1.3 约束的分类&#xff1a; 角度1&#xff1a;约束的字段的个数 单列约束 vs 多列约束 角度2&#xff1a;约束的作用范围 列…...

java调用cmd命令

1.首先&#xff0c;我们需要了解一下 java是如何调用 cmd的&#xff1a; 6.在实际的开发中&#xff0c;我们有可能会遇到 java调用 cmd命令的情况&#xff1a; 7.对于一些特定的环境下&#xff0c;例如在嵌入式系统中&#xff0c;那么我们可以使用下面这种方式来调用 cmd命令&a…...

Qt音视频开发36-超时检测和自动重连的设计

一、前言 如果网络环境正常设备正常,视频监控系统一般都是按照正常运行下去,不会出现什么问题,但是实际情况会很不同,奇奇怪怪七七八八的问题都会出现,就比如网络出了问题都有很多情况(交换机故障、网线故障、带宽故障等),所以监控系统在运行过程中,还得做超时检测,…...

Reactor 第九篇 WebFlux重构个人中心,效果显著

1 重构背景 原有的开发人员早已离职&#xff0c;代码细节没人知道&#xff0c;经过了一段时间的维护&#xff0c;发现有以下问题&#xff1a; 个人中心系统的特征就是组装各个业务的接口&#xff0c;输出个人中心业务需要的数据&#xff0c;整个系统调用了几十个第三方业务线的…...

Vben Admin 自学记录 —— Drawer组件的基本使用及练习(持续更新中...)

Drawer 抽屉组件 对 antv 的 drawer 组件进行封装&#xff0c;扩展拖拽&#xff0c;全屏&#xff0c;自适应高度等功能。 Drawer相关使用及概念 练习 —— 在之前table基础上&#xff0c;添加查看功能&#xff0c;点击查看按钮&#xff0c;弹出抽屉显示单条表格数据&#xf…...

Android 9.0 根据包名默认授予app悬浮窗权限

1.概述 在9.0的设备开发中,对于在app中授予悬浮窗权限,也是通常用的功能,但在设备产品中预制app,需求要求默认授予悬浮窗权限, 就不需要在app中动态申请悬浮窗权限了,所以就来分析下这个实现这个功能 2.根据包名默认授予app悬浮窗权限的核心类 packages\apps\Settings\s…...

Swift中Data,String,[UInt8]的相互转换(6种互相转换)

var dataData() var array[UInt8]() var str"" //Data[UInt8] data.append(10) array[UInt8](data) print(array)//[10] //[UInt8]转Data array[1,2,3,4,5] dataData(array) print(data.count)//5 //Data转String data.removeAll() data.append(contentsOf:[0x31,…...

【微软Bing王炸更新】无需等待,人人可用,答案图文并茂,太牛了

&#x1f680; AI破局先行者 &#x1f680; &#x1f332; AI工具、AI绘图、AI专栏 &#x1f340; &#x1f332; 如果你想学到最前沿、最火爆的技术&#xff0c;赶快加入吧✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域优质创作者&#x1f3c6;&am…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...