JVM 面试精选 20 题

在这里插入图片描述

目录

      • 1. 什么是 JVM、JDK 和 JRE?它们之间的关系是什么?
      • 2. Java 内存区域(运行时数据区)有哪些?
      • 3. 说说你对 JVM 垃圾回收机制的理解。
      • 4. 常用的垃圾回收算法有哪些?
      • 5. 什么是 Minor GC、Major GC 和 Full GC?
      • 6. JVM 调优的常用参数有哪些?
      • 7. 说说 Java 对象的创建过程。
      • 8. 什么是 JVM 类加载机制?
      • 9. 什么是双亲委派模型?
      • 10. 常见的 JVM 垃圾回收器有哪些?
      • 11. 为什么说 CMS 会产生内存碎片?
      • 12. 什么是 JIT 编译器?它的作用是什么?
      • 13. 什么是逃逸分析?
      • 14. 谈谈你对强引用、软引用、弱引用、虚引用的理解。
      • 15. 什么是 OOM(Out of Memory)?如何排查?
      • 16. JVM 发生 GC 时,STW(Stop-The-World)是什么?
      • 17. 为什么说 JVM 堆是分代的?
      • 18. 对象在 JVM 中的内存布局是怎样的?
      • 19. JVM 中的线程死锁如何排查?
      • 20. 简述 JVM 的执行引擎。


JVM(Java Virtual Machine)作为 Java 语言的核心,是每个 Java 开发者都绕不开的话题。在面试中,JVM 相关问题几乎是必考项。本文整理了 20 道常见的 JVM 面试题,并附带详细解答,帮助你更好地准备面试。

1. 什么是 JVM、JDK 和 JRE?它们之间的关系是什么?

解答:

  • JVM(Java Virtual Machine):Java 虚拟机,是运行 Java 字节码的虚拟机。它负责将编译好的 .class 文件翻译成机器码并执行。JVM 只是一个规范,不同的厂商可以有不同的实现,比如 HotSpot。
  • JRE(Java Runtime Environment):Java 运行时环境,它包含了 JVM 和运行 Java 程序所需的核心类库(如 java.langjava.util 等)。如果你只需要运行一个 Java 程序,安装 JRE 就足够了。
  • JDK(Java Development Kit):Java 开发工具包,是提供给 Java 开发人员使用的,它包含了 JRE、编译器(javac)、调试工具(jdb)等开发工具。如果你需要编写和编译 Java 程序,必须安装 JDK。

关系:
JDK > JRE > JVM。JDK 包含 JRE,而 JRE 包含 JVM 和核心类库。

2. Java 内存区域(运行时数据区)有哪些?

解答:

根据《Java 虚拟机规范》,Java 虚拟机运行时数据区分为以下几个部分:

  • 程序计数器(Program Counter Register):一块较小的内存空间,是当前线程所执行的字节码的行号指示器。每个线程都有独立的程序计数器,它是线程私有的。
  • Java 虚拟机栈(Java Virtual Machine Stacks):每个方法在执行时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。线程私有
  • 本地方法栈(Native Method Stacks):与虚拟机栈类似,但是为虚拟机使用到的 Native 方法服务。线程私有
  • Java 堆(Java Heap):虚拟机所管理的内存中最大的一块。所有线程共享,用于存放对象实例和数组。它是垃圾回收的主要区域。
  • 方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。所有线程共享。在 JDK 1.8 之后,方法区被 元空间(Metaspace) 取代,元空间在本地内存中,不受 JVM 内存限制。

3. 说说你对 JVM 垃圾回收机制的理解。

解答:

垃圾回收(Garbage Collection, GC)是 JVM 自动管理内存的一种机制。它的主要任务是回收堆内存中不再使用的对象,释放内存空间。

GC 的基本思想是:找到那些不再被任何引用所指向的对象,然后将其占用的内存回收。为了判断对象是否“存活”,JVM 采用了两种主要算法:

  • 引用计数算法:给每个对象添加一个引用计数器。当有地方引用它时,计数器加 1;引用失效时,计数器减 1。当计数器为 0 时,说明该对象可以被回收。但是,它无法解决对象之间循环引用的问题,所以现代 JVM 不使用此算法。
  • 可达性分析算法:通过一系列称为 “GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。GC Roots 包括虚拟机栈中的引用对象、方法区中的静态变量和常量等。

4. 常用的垃圾回收算法有哪些?

解答:

  • 标记-清除(Mark-Sweep)

    • 标记:从 GC Roots 开始标记所有可达对象。
    • 清除:遍历整个堆,回收所有未被标记的对象。
    • 缺点:会产生大量不连续的内存碎片,导致后续需要大块连续内存的对象无法分配,提前触发 GC。
  • 复制(Copying)

    • 将内存分为大小相等的两块,每次只使用其中一块。当这块内存用完时,将存活的对象复制到另一块上,然后清空已使用的这块内存。
    • 优点:不会产生内存碎片,实现简单高效。
    • 缺点:内存利用率只有 50%。常用于新生代
  • 标记-整理(Mark-Compact)

    • 标记:同标记-清除,标记所有存活对象。
    • 整理:让所有存活对象都向一端移动,然后直接清理掉边界以外的内存。
    • 优点:不会产生内存碎片。
    • 缺点:效率比标记-清除低,因为需要移动对象。常用于老年代
  • 分代收集

    • 结合了上述算法,根据对象的生命周期将堆分为新生代老年代
    • 新生代:大部分对象“朝生夕灭”,采用复制算法,效率高。
    • 老年代:对象存活率高,采用标记-整理或标记-清除算法,减少移动开销。

5. 什么是 Minor GC、Major GC 和 Full GC?

解答:

  • Minor GC(新生代 GC)

    • 指发生在新生代的垃圾回收。
    • 新生代采用复制算法,因为对象存活率低,效率高。
    • 触发条件:Eden 区满时。
  • Major GC(老年代 GC)

    • 指发生在老年代的垃圾回收。
    • Major GC 通常会伴随一次 Minor GC。
  • Full GC(全堆 GC)

    • 指对整个堆(新生代、老年代和方法区/元空间)进行垃圾回收。
    • 触发条件:老年代空间不足;方法区空间不足;调用 System.gc() 等。
    • Full GC 的代价很高,会造成较长的 STW(Stop-The-World),应尽量避免。

6. JVM 调优的常用参数有哪些?

解答:

  • -Xms<size>:设置 JVM 的初始堆内存,等价于 -XX:InitialHeapSize
  • -Xmx<size>:设置 JVM 的最大堆内存,等价于 -XX:MaxHeapSize
  • -Xmn<size>:设置新生代的大小。
  • -XX:NewRatio=<ratio>:设置新生代和老年代的比例,例如 -XX:NewRatio=2 表示新生代与老年代的比例为 1:2。
  • -XX:MaxMetaspaceSize=<size>:设置元空间的最大大小。
  • -XX:+PrintGCDetails:打印详细的 GC 日志。
  • -XX:+UseG1GC:使用 G1 垃圾回收器。
  • -Xss<size>:设置每个线程的栈大小。

7. 说说 Java 对象的创建过程。

解答:

  1. 类加载检查:当 JVM 遇到 new 指令时,首先检查指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化。
  2. 分配内存:在类加载检查通过后,为新对象分配内存。
  3. 初始化零值:内存分配完成后,JVM 会将分配到的内存空间都初始化为零值(不包括对象头),这保证了对象的实例字段在不赋初值时可以直接使用。
  4. 设置对象头:JVM 会设置对象头中的元数据,比如哈希码、GC 年龄、锁信息、对象所属的类等。
  5. 执行 <init> 方法:执行对象的构造方法,按照代码中的逻辑进行初始化。

8. 什么是 JVM 类加载机制?

解答:

类加载机制是 JVM 将 class 文件加载到内存,并对其进行校验、准备、解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型。

加载过程

  1. 加载(Loading):通过类的全限定名获取二进制字节流,将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,并在内存中生成一个代表该类的 java.lang.Class 对象。
  2. 验证(Verification):确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,不会危害虚拟机自身的安全。
  3. 准备(Preparation):为类的静态变量分配内存,并设置默认初始值(例如 int 类型为 0,boolean 类型为 false)。
  4. 解析(Resolution):将常量池中的符号引用替换为直接引用。
  5. 初始化(Initialization):执行 <clinit>() 方法,对类的静态变量和静态代码块进行赋值。

9. 什么是双亲委派模型?

解答:

双亲委派模型(Parent Delegation Model)是 Java 类加载器的一种工作机制。当一个类加载器收到类加载请求时,它并不会自己先去加载,而是先把这个请求委派给它的父类加载器去执行。如果父类加载器还存在父类加载器,则继续向上委派,直到最顶层的启动类加载器。只有当父类加载器在它的搜索范围内找不到所需的类时,子类加载器才会尝试自己去加载。

优点:

  • 避免重复加载:确保每个类在 JVM 中只加载一次。
  • 保证安全性:防止恶意代码替换核心类库,例如,用户不能自己写一个 java.lang.String 类来欺骗 JVM。

10. 常见的 JVM 垃圾回收器有哪些?

解答:

  • Serial(串行):单线程 GC,简单高效,但会造成较长的 STW。适用于单核 CPU 或内存较小的客户端应用。
  • ParNew:Serial 的多线程版本,用于新生代。
  • Parallel Scavenge:关注吞吐量(Throughput),即 CPU 用于执行用户代码的时间与 GC 时间的比值。可以有效利用多核 CPU。
  • CMS(Concurrent Mark Sweep):以获取最短停顿时间为目标的 GC,采用“标记-清除”算法。在并发阶段,GC 线程和用户线程可以同时运行。
  • G1(Garbage First)分代收集器,将堆划分为一个个的区域(Region),通过维护一个优先列表,优先回收垃圾最多的区域,从而实现可预测的停顿时间。适用于大内存服务器。
  • ZGC / Shenandoah:新一代的低延迟垃圾回收器,旨在实现几乎不中断的 GC 停顿时间(小于 10ms),适用于超大内存的应用。

11. 为什么说 CMS 会产生内存碎片?

解答:

CMS 垃圾回收器采用了标记-清除算法,这个算法的特点是:

  1. 标记:遍历堆,标记所有存活对象。
  2. 清除:直接清除所有未标记对象占用的内存。

这个过程中,存活对象的位置不会改变,因此被清除的对象所占用的空间就成了不连续的“空洞”,也就是内存碎片。当一个需要大块连续内存的新对象需要分配时,如果现有空闲内存虽然总量足够,但是没有足够大的连续空间,就会导致分配失败,从而不得不触发一次 Full GC。

12. 什么是 JIT 编译器?它的作用是什么?

解答:

JIT(Just-In-Time)编译器,又称即时编译器,是 HotSpot JVM 中的一个重要组成部分。它的作用是在程序运行时,将频繁执行的热点代码(Hot Spot Code)编译为本地机器码,从而提高代码的执行效率。

Java 程序最初是解释执行的,即由解释器逐行翻译字节码。JIT 编译器的出现弥补了这一缺点。当 JVM 发现某段代码被多次调用或者是一个循环时,就会将其识别为热点代码,并交由 JIT 编译器编译。编译后的本地代码可以直接运行在操作系统上,效率更高。


13. 什么是逃逸分析?

解答:

**逃逸分析(Escape Analysis)**是 JVM 编译器的一项优化技术,它分析对象是否会被方法外部访问。

  • 不逃逸:一个对象只在方法内部使用,不会被外部引用。
  • 方法逃逸:对象作为方法的返回值,或者作为参数传递给其他方法。
  • 线程逃逸:对象被多个线程共享,例如作为静态变量或者被添加到公共集合中。

逃逸分析的优化:

  • 栈上分配:如果一个对象不逃逸,可以直接在栈上分配内存。栈上的内存随着方法结束自动回收,减轻了 GC 压力。
  • 同步消除:如果一个对象只在一个线程中使用,即使它被 synchronized 包裹,JVM 也可以消除这个锁,因为不会发生竞争。
  • 标量替换:如果一个对象不逃逸,并且可以拆分为基本类型,那么可以不创建这个对象,直接创建它的字段,节省内存。

14. 谈谈你对强引用、软引用、弱引用、虚引用的理解。

解答:

  • 强引用(Strong Reference):最常见的引用类型,如 Object obj = new Object()。只要强引用存在,垃圾回收器永远不会回收被引用的对象。
  • 软引用(Soft Reference):用于描述一些还有用但非必需的对象。当内存空间不足时,JVM 会回收这些对象。常用于缓存。
  • 弱引用(Weak Reference):用于描述那些非必需的对象。只要发生垃圾回收,无论内存是否充足,都会回收被弱引用关联的对象。常用于 WeakHashMap
  • 虚引用(Phantom Reference):最弱的引用,无法通过虚引用获取对象实例。它唯一的用途是,在对象被回收时收到一个系统通知。常用于管理直接内存。

15. 什么是 OOM(Out of Memory)?如何排查?

解答:

OOM 指程序在申请内存时,JVM 没有足够的内存空间来分配。

常见的 OOM 类型:

  • java.lang.OutOfMemoryError: Java heap space:Java 堆内存不足,可能是创建了太多大对象,或者内存泄漏。
  • java.lang.OutOfMemoryError: Metaspace:元空间不足,可能是加载了太多类。
  • java.lang.OutOfMemoryError: unable to create new native thread:无法创建新的本地线程,可能是线程创建过多,或者操作系统对线程数有限制。

排查方法:

  1. 分析错误日志:查看 OOM 错误的具体类型和信息。
  2. 分析堆转储文件:使用 jmapHeapDumpOnOutOfMemoryError 生成 .hprof 文件,然后使用 MAT(Memory Analyzer Tool)VisualVM 等工具分析堆中对象的分布,找出导致 OOM 的“大对象”或对象数量异常增长。
  3. 查看 GC 日志:通过 PrintGCDetails 等参数打印 GC 日志,分析 GC 频率和耗时,判断是否频繁 GC 导致内存不足。

16. JVM 发生 GC 时,STW(Stop-The-World)是什么?

解答:

**STW(Stop-The-World)**是指在进行垃圾回收时,JVM 停止所有的应用线程,直到 GC 过程结束。所有用户线程都被暂停,无法响应请求,就像整个世界都停止了一样。

STW 的目的是为了保证 GC 过程中的数据一致性。如果在 GC 时,用户线程还在不断创建新对象、修改引用关系,那么 GC 线程将无法准确地判断哪些对象是存活的,导致回收错误。

现代的垃圾回收器(如 CMS、G1、ZGC)都在努力减少 STW 的时间,甚至实现并发 GC,让 GC 线程和用户线程同时运行,从而减少对应用程序的影响。

17. 为什么说 JVM 堆是分代的?

解答:

**分代(Generational)**是 JVM 堆内存的一种管理策略,基于一个重要的假设:绝大多数对象都是“朝生夕灭”的

  • 新生代(Young Generation):用于存放新创建的对象。这里的大多数对象在 Minor GC 后都会被回收。采用复制算法,效率很高。
  • 老年代(Old Generation):用于存放经过多次 Minor GC 仍然存活的对象。这些对象生命周期较长。采用标记-整理标记-清除算法,减少移动开销。

这种分代管理可以根据不同区域对象的特点,采用最适合的 GC 算法,从而提高 GC 效率。

18. 对象在 JVM 中的内存布局是怎样的?

解答:

一个 Java 对象在堆内存中主要包含三部分:

  1. 对象头(Object Header)

    • Mark Word:存储对象的哈希码、GC 年龄、锁信息等。
    • Klass Pointer:指向对象所属类的元数据指针。
  2. 实例数据(Instance Data)

    • 存储对象的所有成员变量(包括父类的成员变量)。
  3. 对齐填充(Padding)

    • 保证对象的大小是 8 字节的倍数。这不是必需的,只是为了方便 CPU 访问。

19. JVM 中的线程死锁如何排查?

解答:

  1. 使用 jps 命令:找到 Java 进程 ID。
  2. 使用 jstack 命令jstack <pid>jstack 会打印出 JVM 中所有线程的堆栈信息,如果存在死锁,它会明确地在日志中报告死锁信息,并列出涉及死锁的线程和锁。
  3. 分析 jstack 结果:仔细阅读 jstack 的输出,找到 Found one Java-level deadlock 的信息,然后根据堆栈信息分析是哪些线程、哪些锁导致了死锁。
  4. 使用图形化工具:如 VisualVM,它可以直观地显示线程状态、CPU 使用情况,并能自动分析死锁。

20. 简述 JVM 的执行引擎。

解答:

**执行引擎(Execution Engine)**是 JVM 的核心组成部分,它负责执行被加载到内存中的字节码。执行引擎的工作方式有两种:

  1. 解释执行:由**解释器(Interpreter)**逐条读取和翻译字节码指令,然后执行。这种方式启动快,但执行效率低。
  2. 编译执行:由 JIT 编译器将热点代码编译成机器码。这种方式启动慢,但一旦编译完成,执行效率高。

现代的 JVM 普遍采用解释器和 JIT 编译器并存的混合模式。程序刚启动时,解释器快速执行;当代码被多次调用后,JIT 编译器介入,将热点代码编译成高效的本地代码,以达到最佳性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93605.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93605.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CMIP6 气候模式核心特性解析

在全球气候变化研究中&#xff0c;CMIP6&#xff08;第六次耦合模式比较计划&#xff09;的气候模式是关键工具。以下从研发背景与核心能力角度&#xff0c;解析五类主流模式的技术特点与适用场景。 一、主流模式技术特性 1. CanESM5/CanESM5-1&#xff08;加拿大环境与气候变…

【牛客刷题】BM63 跳台阶:三种解法深度解析(递归/DP动态规划/记忆化搜索)

文章目录 一、题目介绍 1.1 题目描述 1.2 示例 二、算法设计思路 2.1 核心问题分析 2.2 斐波那契数列关系 三、流程图 解法1:递归法(自顶向下) 解法2:动态规划(自底向上) 解法3:记忆化搜索(递归优化) 解法4: 优化DP流程(推荐) 四、解法实现 五、复杂度分析对比 六、…

《解构WebSocket断网重连:指数退避算法的前端工业级实践指南》

WebSocket作为客户端与服务器双向通信的核心载体,支撑着从在线协作、金融行情到即时通讯等各类高实时性场景。然而,网络环境的动态变化—从用户设备的Wi-Fi与蜂窝网络切换,到公共网络的临时拥塞,再到服务器的短暂重启—都可能导致WebSocket连接中断,进而引发数据传输停滞、…

医疗洁净间的“隐形助手”:富唯智能复合机器人如何重塑手术器械供应链

当手术刀片在无影灯下传递时&#xff0c;0.01mm的抓取偏差可能意味着感染风险——而富唯智能复合机器人以0.02mm的重复定位精度与99.999%无菌操作的硬实力&#xff0c;正成为高端医疗产线中替代人力的关键技术支点。一、医疗上下料的三大痛点&#xff1a;精度、洁净与连续性1.毫…

《设计模式》工厂方法模式

1.工厂方法模式&#xff08;Factory Method&#xff09;定义 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 1.1 UML图&#xff1a; 主要有4个对象&#xff1a; 抽象工厂&#xff08;Abstract Creator&#xf…

冒泡排序——简单理解和使用

阅前声明&#xff1a;如果想直接了解冒泡排序的简化思想&#xff0c;请跳至文章尾部在介绍之前&#xff0c;我们先看一个用到该功能的实战训练&#xff08;本人也是从中开始认识到冒泡排序这个函数定义&#xff09;对于小白来说&#xff0c;我的思路如下&#xff1a;1.题目中涉…

AI应用商业化加速落地 2025智能体爆发与端侧创新成增长引擎

今年以来&#xff0c;人工智能 (AI) 正在进入从算力投入到云服务消耗再到商业化收入&#xff0c;最终回到算力再投入的良性循环&#xff0c;而 AI 应用的起量正是推动这一飞轮效应的关键。7 月 31 日&#xff0c;国务院常务会议审议通过了《关于深入实施 “人工智能 ” 行动的意…

Pytest测试框架基础及进阶

Pytest测试框架基础# Pytest测试框架介绍# Pytest是Python一款三方测试框架&#xff0c;用于编写和运行单元测试、集成测试和功能测试。Pytest测试框架具有简单、灵活、易于扩展等特点&#xff0c;被广泛应用于Python项目的测试工作中。 Pytest主要特点&#xff1a; 简单易用…

航空装备先进加工工艺与制造技术论坛——2025成都航空装备展

300参展企业 11500㎡展区面积 7大专业展区 12000观众规模15同期会议 160发言嘉宾 5000参会嘉宾 100媒体报道航空工业飞速发展&#xff0c;先进加工工艺与制造技术成为了支撑航空装备性能提升、质量保障和产能优化的核心基石。为探索前沿技术路径、凝聚行业创新力量&#xff0c;…

为什么品牌更愿意为新品打广告?

品牌资源向新品广告倾斜&#xff0c;可以说是市场上的普遍现象。尤其对于没有明星产品的品牌而言&#xff0c;新品推广时企业的重要曝光节点。下面就让我们一同来了解下&#xff0c;为什么品牌更愿意为新品打广告。一、市场需求更充分新品广告往往承担着市场教育的功能&#xf…

电子电气架构 --- 关于整车信息安全的一些思考

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

报错:Eplan无法打开数据库的解决方法

详细报错信息&#xff1a;无法打开数据库 E:\eplan\部件\Microsoft\ESS_part001.mdb。针对64位版本的EPLAN 平台需要使用64位版本的Microsoft Office. 一、报错及解决方法 报错信息&#xff1a;无法打开数据库 E:\eplan\部件\Microsoft\ESS_part001.mdb。针对64位版本的EPLAN 平…

深度学习篇---卷积核的权重

卷积核权重&#xff1a;在深度学习的卷积操作中&#xff0c;“卷积核的权重” 是最核心的概念之一&#xff0c;它决定了卷积核能从图像中 “看到” 什么特征&#xff08;比如边缘、纹理&#xff0c;甚至是眼睛、车轮这样的复杂结构&#xff09;。我们可以把它理解成卷积核的 “…

SMTPman,smtp ssl助力安全高效邮件传输!

SMTPman&#xff0c;smtp ssl助力安全高效邮件传输&#xff01;SMTPman&#xff0c;smtp ssl不仅仅是一种邮件协议方式&#xff0c;更是企业日常运营的重要支撑。通过SMTPman&#xff0c;smtp ssl&#xff0c;用户可以获得更快的投递速度&#xff0c;更稳定的连接&#xff0c;以…

学习日志37 python

1 Python 和 Java 在类属性&#xff08;静态属性&#xff09;和实例属性的处理题目执行以下程序&#xff0c;输出结果为&#xff08;&#xff09; class Base(object):count 0def __init__(self):pass b1 Base() b2 Base() b1.count b1.count 1 print(b1.count,end" …

对于QPS的理解和简单

QPS&#xff08;Queries Per Second&#xff09; 是衡量系统吞吐量的核心指标&#xff0c;表示每秒能处理的请求数量。以下是关于QPS的完整解析和实践指南&#xff1a;一、QPS的核心公式 QPS 总请求量 / 请求总时间&#xff08;秒&#xff09;典型场景计算&#xff1a; 日请求…

【笔记ing】考试脑科学 脑科学中的高效记忆法

前言本书是拙作《高中生学习法》的修订版。《高中生学习法》出版已有十余年。这期间&#xff0c;脑科学研究不断进步&#xff0c;十几年前无法解释的事情现在已经开始逐渐明晰。同时&#xff0c;书中有些内容甚至已经被明确证实是错误的。也就是说&#xff0c;《高中生学习法》…

Web安全 - 构建安全可靠的API:基于国密SM2/SM3的文件上传方案深度解析

文章目录概述1. 缘起&#xff1a;挑战与目标2 . 核心架构&#xff1a;非对称签名与摘要算法的珠联璧合威胁模型&#xff08;我们要防的攻击&#xff09;密钥管理体系3 . 签名与验证&#xff1a;一步一解&#xff0c;安全闭环3.1 A系统&#xff1a;签名的生成&#xff08;请求前…

【MyBatis-Plus】一、快速入门

这里写自定义目录标题MyBatis-Plus 概述快速入门入门案例常用注解常见配置MyBatis-Plus 概述 MyBatis-Plus 简介&#xff1a; MyBatis-Plus 是在 MyBatis 基础上开发的一个 增强工具包&#xff0c;它简化了 MyBatis 的开发&#xff0c;减少了大量重复代码。它保持了 MyBatis …

PostgreSQL导入mimic4

一、PostgreSQL连接验证 正确连接命令 使用psql工具连接目标数据库&#xff0c;格式为&#xff1a;psql -h 127.0.0.1 -U 用户名 -d 数据库名 --password 示例&#xff08;用户名Shinelon&#xff0c;数据库mimic&#xff09;&#xff1a;psql -h 127.0.0.1 -U Shinelon -d mi…