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

【Java校招面试】基础知识(四)——JVM

目录

  • 前言
  • 一、基础概念
  • 二、反射
  • 三、类加载器ClassLoader
  • 四、JVM内存模型
  • 后记


前言

本篇主要介绍Java虚拟机——JVM的相关内容。

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

  1. 点击这里,返回本专栏的索引文章
  2. 点击这里,返回上一篇《【Java校招面试】基础知识(三)——多线程与并发》
  3. 点击这里,前往下一篇《【Java校招面试】基础知识(五)——GC》

一、基础概念

01. Java代码的Compile once, run anywhere是怎么实现的?
所谓Compile once, run anywhere即一次编译,随处运行。
在这里插入图片描述
Java源码首先被编译成字节码,再由不同平台的JVM进行解析,Java语言在不同的平台上运行时不需要进行重新编译,Java虚拟机在执行字节码的时候,把字节码转换成具体平台上的机器指令。

02. 为什么不直接将源码解析成机器码去执行?
1) 准备工作: 每次执行前都需要各种检查,降低执行效率;
2) 兼容性: 可以将别的语言编译成字节码,然后用JVM执行,提高兼容性。

03. JVM如何加载.class文件?
在这里插入图片描述
JVM主要由Class LoaderRuntime Data AreaExecution EngineNative Interface组成。

  • Class Loader: 依据特定格式,加载class文件到内存
  • Execution Engine: 对命令进行解析
  • Native Interface: 融合不同开发语言的原生库为Java所用
  • Runtime Data Area: JVM内存空间结构模型

二、反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。

01. 反射的代码示例
1) 目标类(包含一个私有属性、一个私有方法、一个公有方法,注意包名)

	package reflecttest;public class Target {// 目标类私有属性private String privateField;// 目标类公有方法public void publicMethod(String param) {System.out.println("I'm the public method of Target class.The param is " + param);}// 目标类私有方法private void privateMethod(String param) {System.out.println("I'm the private method of Target class.The param is " + param);}}

2) 反射调用类

	public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {Class targetClass = Class.forName("reflecttest.Target");Target target = (Target) targetClass.newInstance();// 通过反射引用目标类私有属性testPrivateField(targetClass, target);// 通过反射调用目标类公有方法testPublicMethod(targetClass, target);// 通过反射调用目标类私有方法testPrivateMethod(targetClass, target);}private static void testPrivateField(Class clazz, Target target) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {Field privateField = clazz.getDeclaredField("privateField");privateField.setAccessible(true);System.out.println("The Origin Value of Private Field Is: " + privateField.get(target));privateField.set(target, "New Value");System.out.println("The Fixed Value of Private Field Is: " + privateField.get(target));}private static void testPublicMethod(Class clazz, Target target) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {Method publicMethod = clazz.getMethod("publicMethod", String.class);publicMethod.invoke(target, "\"Calling Public Method.\"");}private static void testPrivateMethod(Class clazz, Target target) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {Method privateMethod = clazz.getDeclaredMethod("privateMethod", String.class);privateMethod.setAccessible(true);privateMethod.invoke(target, "\"Calling Private Method.\"");}}

3) 输出结果

The Origin Value of Private Field Is: null
The Fixed Value of Private Field Is: New Value
I'm the public method of Target class. The param is "Calling Public Method."
I'm the private method of Target class. The param is "Calling Private Method."

4) 总结
  ① 流程: 先通过完全限定类名获得类对象,然后newInstance获取实例,该实例用于方法的invoke和属性的set等各种操作;
   getDeclaredMethod可以获得类的所有方法,但不能获取继承的和实现的接口函数,getMethod只可以获取public方法,但也可以获取继承的public方法和实现的接口中的方法。对于Field同理;
   对私有的属性或者方法进行操作时,需要setAccessable(true),改变访问权限。


三、类加载器ClassLoader

ClassLoader的主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流并装载进系统,然后交给JVM进行连接、初始化等操作。

01. 类从编译到执行的过程
1) 编译器将Test.java源文件编译成Test.class字节码文件;
2) ClassLoader将字节码转换为JVM中的Class对象;
3) JVM利用Class对象实例化Test对象。

02. ClassLoader的类型
1) BootstrapClassLoader: 启动类加载器
   使用C++编写;
   负责加载Java核心库,如java.lang;
   无法直接获取;
2) ExtClassLoader: 扩展类加载器
   使用Java编写;
   负责加载jdk_home/lib/ext目录下的jar
3) AppClassLoader: 应用类加载器
   使用Java编写;
   负责加载程序所在目录。
4) 自定义ClassLoader

03. 自定义ClassLoader的例子
1) 要加载的目标类:

	public class Target {static {System.out.println("I'm Static Block of Target Class.");}}

2) 自定义ClassLoader:

	public class MyClassLoader extends ClassLoader {private String classPath;public MyClassLoader(String classPath) {this.classPath = classPath;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] clazz = loadClassFromFile(name);return defineClass(name, clazz, 0, clazz.length);}public byte[] loadClassFromFile(String className) {String path = classPath + File.separator + className + ".class";try (InputStream in = new FileInputStream(new File(path));ByteArrayOutputStream out = new ByteArrayOutputStream();) {int c;while ((c = in.read())!= -1)out.write(c);return out.toByteArray();} catch (Exception ex) {return null;}}}

3) ClassLoader调用类

	public class ClassLoaderTest {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {String classPath = "/path/to/class/loader";MyClassLoader classLoader = new MyClassLoader(classPath);Class c = classLoader.loadClass("Target");c.newInstance();}}

4) 输出结果

	I'm Static Block of Target Class.

04. ClassLoader双亲委派机制
1) AppClassLoader的父类是ExtClassLoader,ExtClassLoader的父类是BootstrapClassLoader;
2) loadClass方法源码:

		protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}

3) 程序逻辑——双亲委派机制

  • 首先找缓存(findLoadedClass),没有的话就判断有没有parent,有的话就用parent来递归的loadClass,然而ExtClassLoader并没有设置parent,则会通过findBootstrapClassOrNull来加载class,而findBootstrapClassOrNull则会通过JNI方法private native Class findBootstrapClass(String name)来使用BootStrapClassLoader来加载class。
  • 然后如果parent未找到class,则会调用findClass来加载class,findClass是一个protected的空方法,可以覆盖它以便自定义class加载过程。

05. 使用双亲委派机制为什么是安全的?
举个例子,ClassLoader加载的class文件来源很多,比如编译器编译生成的class、或者网络下载的字节码。而一些来源的class文件是不可靠的,比如我可以自定义一个java.lang.Integer类来覆盖jdk中默认的Integer类,例如下面这样:

	package java.lang;public class Integer {public Integer(int value) {System.exit(0);}}

初始化这个Integer的构造器是会退出JVM,破坏应用程序的正常进行。 如果使用双亲委派机制的话,该Integer类永远不会被调用。因为委托BootStrapClassLoader加载后会加载JDK中的Integer类而不会加载自定义的这个,因此就保证了安全性。

06. 类的加载方式
1) 隐式加载: new,程序在运行过程中,遇到需要用new生成对象时,隐式调用类加载器将对应的类加载到JVM中。
2) 显式加载: loadClass,forName等

区别:
1) 显式加载需要先获取类对象,然后调用其newInstance方法获取对象,而隐式加载不需要;
2) new支持调用目标类带参数的构造方法,而newInstance方法则不支持传入参数。

07. 类的装载过程
在这里插入图片描述
1) 加载: 通过ClassLoader加载class文件字节码,生成Class对象;
2) 链接:
  ① 校验: 检查加载的类的正确性和安全性;
  ② 准备: 为类变量分配存储空间并设置类变量初始值;
  ③ 解析: JVM将常量池中的符号引用转换为直接引用。
3) 初始化: 执行类变量赋值和静态代码块

08. loadClass和forName的区别
1) Class.forName得到的class是已经初始化完成的;
2) ClassLoader.loadClass得到的class是还没有链接的。

应用场景:
1) 有的类有静态代码块(如mysql-connector),因此需要使用Class.forName;
2) Spring中由于IoC大量使用LazyLoad技术,即延时加载,在bean真正被调用时才完成初始化。这里用到的是ClassLoader.loadClass。


四、JVM内存模型

01. 从线程的角度看JVM内存模型
在这里插入图片描述

  • 线程私有的内存: 程序计数器、虚拟机栈、本地方法栈
  • 所有线程共享的内存: 元空间(MetaSpace)、常量池、堆

1) 程序计数器(Program Counter Register): 一块较小的内存空间,是当前线程所执行的字节码行号指示器 (逻辑计数器)。改变计数器的值来选取下一条需要执行的字节码指令。和线程是一对一关系,即线程私有;对Java方法,记录的是正在执 行的虚拟机字节码指令的地址;对Native方法,其值为Undefined。 由于只记录行号,不会发生内存泄漏。

2) 虚拟机栈(Stack): 是Java方法执行的内存模型。每个方法被执行时,都会 创建一个栈帧(方法运行期间的基础数据结构)。
在这里插入图片描述
  ① 局部变量表和操作数栈
  局部变量表: 包含方法执行过程中的所有变量
  操作数栈: 入栈、出栈、复制、交换、产生/消费变量
  ② 通过一个简单的加法函数例子来深入理解

	public static int add(int a, int b){int c = 0;c = a + b;return c;}

  假设对add方法传入(1, 2),其过程为:
在这里插入图片描述
  ③ 递归为什么会引发java.lang.StackOverflowError异常?
  递归过深,栈帧数超出虚拟栈的深度。解决方法:限制递归深度或者换用迭代方法。
  ④ 总结: 方法执行完成后,栈帧会被自动释放掉,因此不需要GC来回收。
3) 本地方法栈: 与虚拟机栈类似,主要作用于标注了native的方法。
4) 元空间(Meta Space): JDK 8中把类的元数据放在元空间,而JDK 7及以前的版本是放在永久代(PermGen)中。
  MetaSpace与PermGen相比的优势:
   元空间使用本地内存,永久代使用jvm内存;
   字符串常量池存在永久代中,容易出现性能问题和内存溢出,Meta Space没有了字符串常量池,它被移动到了堆中;
   类和方法的信息大小难以确定,给永久代的大小指定带来困难;
   永久代会为GC带来不必要的复杂性,回收效率偏低;
   方便HotSpot与其他JVM(如Jrockit)的集成。
5) 堆(Heap): 对象实例的分配区域,GC管理的主要区域;

02. 从存储的角度看JVM内存模型
1) JVM三大性能调优参数-Xms、-Xmx、-Xss的含义?

  • -Xms堆大小的初始值
  • -Xmx堆大小能扩容的最大值
  • -Xss规定了每个线程虚拟机栈(堆栈)的大小;

通常-Xms和-Xmx设置成一样的,因为在堆扩容时会发生内存抖动,影响程序运行时的稳定性。
2) 内存分配策略

  • 静态存储: 编译时确定每个数据目标在运行时的存储空间需求;
  • 栈式存储: 数据区需求在编译时未知,运行时模块入口已确定;
  • 堆式存储: 编译时或运行时模块入口都无法确定,动态分配。

3) Java内存模型中堆和栈的区别
联系: 引用对象、数组时,栈里定义变量保存堆中目标的首地址;
在这里插入图片描述
区别:
  ① 管理方式: 栈自动释放,堆需要GC;
  ② 空间大小: 一般情况下栈比堆小;
  ③ 碎片相关: 栈产生的碎片远小于堆;
  ④ 分配方式: 栈支持静态和动态分配,堆仅支持动态分配;
  ⑤ 效率: 栈的效率比堆高。

4) Meta Space、堆、线程独占部分的联系
一个HelloWorld的例子:

	public class HelloWorld{private String String name;public void setName(String name){this.name = name;}public void sayHello(){System.out.println("Hello " + name);}public static void main(String[] args){int a = 1;HelloWorld hw = new HelloWorld();hw.setName("test");hw.sayHello();}}

内存分配:
在这里插入图片描述
5) JDK 6和JDK 6+中intern方法的区别

	String s = new String("Test");s.intern();
  • JDK 6: 当调用intern方法时,如果字符串常量池已创建该字符串对象,则返回池中的该字符串的引用。否则,将此字符串对象添加到字符串常量池中,并返回该字符串对象的引用。
  • JDK 6+: 当调用intern方法时,如果字符串常量池已创建该字符串对象,则返回池中的该字符串的引用。否则,如果该字符串对象已经存在于Java堆中,则将堆中对此对象的引用添加到字符串常量池,并且返回该引用;如果堆中不存在,则在池中创建该字符串并返回其引用。

6) 不同JDK中intern方法的功能区别
  ① 代码

		public static void main(String[] args){String s = new String("a");s.intern();String s2 = "a";System.out.println(s == s2);String s3 = new String("a") + new String("a");s3.intern();String s4 = "aa";System.out.println(s3 == s4);}

  ② JDK 6中(输出结果false、false)
  PermGen只存放堆中的副本,不能存放引用,所以s3==s4false
在这里插入图片描述
  ③ JDK 6+中(输出结果false、true)
  堆中的字符串常量池可以存放字符串的引用,所以s3==s4true
在这里插入图片描述
03. 对象在内存中的布局
1) 对象头(Header): 对象头分为Mark WordClass Metadata Address两部分,如果对象类型是数组,还要有第三个部分Array Length,即数组长度。

长度内容说明
32/64 bitsMark Word存储对象的hashCode或锁信息等
32/64 bitsClass Metadata Address存储对象类型数据的指针
32 bitsArray Length数组长度(如果对象类型是数组)

Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的 数据,它会根据对象的状态复用自己的存储空间。

   在32位的HotSpot虚拟机中,如果对象处于未被锁定的状态下,那么Mark Word的32bit空间中的25bit用于存储对象哈希码,4bit用于存储对象分代年龄,2bit 用于存储锁标志位,1bit固定为0。

锁状态25 bits4 bits1 bit是否是偏向锁2 bits锁标志位
无锁对象的hashCode对象的分代年龄001

   在 32 位系统下,存放 Class 指针的空间大小是 4 字节,Mark Word 空间大小也是4字节,因此头部就是 8 字节,如果是数组就需要再加 4 字节表示数组的长度。

锁状态25 bits4 bits1 bit2 bits
23 bits2 bits是否是偏向锁锁标志位
轻量级锁指向栈中锁记录的指针00
重量级锁指向互斥量(重量级锁)的指针10
GC标记11
偏向锁线程IDEpoch对象分代年龄101

   在64位系统及64位JVM下,开启指针压缩,那么头部存放Class指针的空间大小还是4字节,而Mark Word区域会变大,变成8字节,也就是头部最少为12字节。

锁状态25 bits31 bits1 bit4 bits1 bit2 bits
cms free分代年龄偏向锁锁标志位
无锁unusedhashCode001
偏向锁ThreadID(54 bits), Epoch(2 bits)101

2) 实例数据(Instance Data): 实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在 Java源码中定义顺序的影响。

3) 对齐填充(Padding): 不是必然存在的,没有特别的含义,它仅起到占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,也就是说对象的大小必须是8字节的整数倍。对象头部分是8字节的倍数,所以当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。


后记

JVM的知识点也不少,为便于阅读,我将其分为了基础概念反射类加载器ClassLoaderJVM内存模型4个部分。

相关文章:

【Java校招面试】基础知识(四)——JVM

目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第四篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回…...

项目管理-计算专题(三点估算、PERT估算)

基本概念 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划评审技术(PERT)。PERT使用三种估算值来界定活动持续时间的近似区间: 最可能时间(tM)&#xff1a;基于最可能获得的资源、最可能取得的资源生产率、对资源可用时间的现…...

【华为OD机试 2023最新 】模拟商场优惠打折(C语言题解 100%)

文章目录 题目描述输入描述输出描述用例题目解析代码思路C语言题目描述 模拟商场优惠打折,有三种优惠券可以用,满减券、打折券和无门槛券。 满减券:满100减10,满200减20,满300减30,满400减40,以此类推不限制使用; 打折券:固定折扣92折,且打折之后向下取整,每次购…...

使用TrieTree(字典树)来实现敏感词过滤

使用TrieTree&#xff08;字典树&#xff09;来实现敏感词过滤 1. 字典树定义 字典树&#xff08;TrieTree&#xff09;&#xff0c;是一种树形结构&#xff0c;典型应用是用于统计&#xff0c;排序和保存大量的字符串&#xff08;但不仅限于字符串,如01字典树&#xff09;。…...

USB转串口芯片CH9101U

CH9101是一个USB总线的转接芯片&#xff0c;实现USB转异步串口。提供了常用的MODEM联络信号&#xff0c;用于为计算机扩展异步串口&#xff0c;或者将普通的串口设备或者MCU直接升级到USB总线。 特点 全速USB设备接口&#xff0c;兼容USB V2.0。内置固件&#xff0c;仿真标准串…...

Java语言介绍

Java是一种广泛使用的计算机编程语言&#xff0c;由Sun Microsystems公司于1995年推出。它是一个健壮的、面向对象的、跨平台的语言&#xff0c;被用于开发各种应用程序和系统&#xff0c;包括Web应用程序、移动应用程序、桌面应用程序、游戏以及企业级系统等。 Java具有许多优…...

终于把 vue-router 运行原理讲明白了(二)!!!

一、vue-router路由变化侦测 1.1 上一遍文章中&#xff0c;介绍了vue-router 的install 函数的内部实现&#xff0c;知道了能在this中访问$router 和视图更新的机制&#xff0c;文章链接终于把 vue-router 运行原理讲明白了&#xff08;一&#xff09;&#xff01;&#xff01…...

ChatGPT实现服务器体验沙箱

服务器体验沙箱 IT 人员在学习一门新技术时&#xff0c;第一个入门门槛通常都是"如何在本地安装并成功运行"。因此&#xff0c;很多技术的官网都会通过沙箱技术&#xff0c;提供在线试用的 playground 或者按步模拟的 tour。让爱好者先在线尝试效果是否满足预期&…...

【算法】刷题中的位运算

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;人类做题的过程&#xff0c;其实是暴搜的过程&#x1f43e; 文章目录 1.位运算概述2.位运算符3.位运算应用3.1整数的奇偶性判断3.2有关 2 的幂的应用3.3lowbit(x)返回x的最后一位13.4二进制数中1的个数3.5求…...

9.Java中异常处理机制是什么

Java的异常处理通过五个关键字来实现&#xff0c;分别是捕获异常&#xff1a;try&#xff0c;catchsfinally&#xff1b;声明异常&#xff1a;throws&#xff1b;抛出异常&#xff1a;throw 一&#xff1a;try&#xff0c;catch捕获异常二&#xff1a;finally回收资源三&#x…...

GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图

GeoTools实战指南: 叠加GeoTIFF与Shapefile图层生成截图 介绍 本教程将介绍如何使用GeoTools库在Java中将栅格数据(GeoTIFF)与矢量数据(Shapefile)叠加显示,并将结果保存为PNG格式的图片文件。我们将解析和分析 RasterDataRenderer 类,并了解其中的每个方法和对象。 准…...

nginx配置sh脚本远程执行一键安装

背景 本地多机重复操作某些shell指令&#xff0c;分步执行&#xff0c;很耗费时间&#xff0c; 需要远程一键部署&#xff0c;傻瓜化运维&#xff0c;更为通用安装。 即参考docker通用安装 sudo curl https://get.docker.com | sh - # sudo python3 -m pip install docker-co…...

Excel表格成绩排名全攻略,让你事半功倍!

在学校或公司中&#xff0c;我们经常需要对成绩进行排名。如果手动计算排名&#xff0c;不仅费时费力&#xff0c;而且容易出错。幸运的是&#xff0c;Microsoft Excel提供了一个简单而快速的方法来计算和显示排名。 在学校或公司中&#xff0c;成绩排名是一项重要的任务。使用…...

Docker 持久化存储 Bind mounts

Docker 持久化存储 Bind mounts Bind mounts 的 -v 与 --mount 区别启动容器基于bind mount挂载到容器中的非空目录只读 bind mountcompose 中使用 bind mount 官方文档&#xff1a;https://docs.docker.com/storage/bind-mounts/ Bind mounts 的 -v 与 --mount 区别 如果使用…...

LVS +Keepalived 高可用群集部署

一、LVSKeepalived 高可用群集 在这个高度信息化的 IT 时代&#xff0c;企业的生产系统、业务运营、销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机信息和服务&#xff0c;对高可用&#xff08;HA&#xff09;技术的应用需求不断提高&#xff0c;以便提供持续的…...

Kafka调优

生产者 参数名称描述bootstrap.serverskafka集群的地址key.deserializerkey的反序列化类&#xff0c;写全类名value.deserializervalue的反序列化类&#xff0c;写全类名buffer.memoryRecordAccumulator缓冲区总大小&#xff0c;默认32mbatch.size缓冲区一批数据最大值&#x…...

Debezium系列之:详细介绍Debezium2.X版本导出Sqlserver数据库Debezium JMX指标的方法

Debezium系列之:详细介绍Debezium2.X版本导出Sqlserver数据库Debezium JMX指标的方法 一、需求背景二、相关技术文章三、安装jmx_prometheus_javaagent四、Debezium2.X版本Sqlserver数据库jmx指标格式五、导出Debezium2.X版本Sqlserver数据库jmx指标方法六、Debezium2.X版本各…...

基于PWM技术的三相光伏逆变器研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

〖Python网络爬虫实战㉑〗- 数据存储之JSON操作

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…...

不得不说的行为型模式-责任链模式

目录 责任链模式&#xff1a; 底层原理&#xff1a; 代码案例&#xff1a; 下面是面试中可能遇到的问题&#xff1a; 责任链模式&#xff1a; 责任链模式是一种行为型设计模式&#xff0c;它允许多个对象在一个请求序列中依次处理该请求&#xff0c;直到其中一个对象能够…...

基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)

整个调试验证与仿真分析分三个步骤&#xff1a;第一步是进行 PCB 检查及电气特性测试&#xff0c;主 要用来验证硬件设计是否正常工作&#xff1b;第二步进行各子模块功能测试&#xff0c;包括高速光纤串行 通信的稳定性与可靠性测试&#xff0c; A/D 及 D/A 转换特性测…...

快速搭建Electron+Vite3+Vue3+TypeScript5脚手架 (无需梯子,快速安装Electron)

一、介绍 &#x1f606; &#x1f601; &#x1f609; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需…...

语义分割学习笔记(二)转置卷积

目录 1.转置卷积Transposed Convolution概念 2.转置卷积操作步骤 3.转置卷积参数 4.实战案例 推荐课程&#xff1a;转置卷积&#xff08;transposed convolution&#xff09;_哔哩哔哩_bilibili 感谢霹雳吧啦Wz&#xff0c;真乃神人也。 1.转置卷积Transposed Convolutio…...

docker运行PostgreSQL数据库维护,执行脚本备份数据库与更新表结构

文章目录 PostgreSQL简介业务场景数据库维护docker-compose配置备份脚本更新表结构脚本 PostgreSQL简介 PostgreSQL是一种开源的关系型数据库管理系统&#xff0c;它是一个功能强大、高度可定制化和支持复杂应用的数据库。它支持广泛的数据类型&#xff0c;包括数值、文字、二…...

【计算机网络】127.0.0.1、0.0.0.0、localhost地址是什么?

目录 0.0.0.0是什么&#xff1f;127.0.0.1是什么&#xff1f;用途 localhost是什么&#xff1f;总结 0.0.0.0是什么&#xff1f; IPV4中&#xff0c;0.0.0.0地址被用于表示一个无效的&#xff0c;未知的或者不可用的目标。 在服务器中&#xff0c;0.0.0.0指的是本机上的所有I…...

分享2款CSS3母亲节主题寄语文字动画特效

目录 ❤️ 前言 第一款&#xff1a;妈妈您辛苦了&#xff01; 一、效果图 二、代码实现 第二款&#xff1a;Mothers Day&#xff01; 一、效果图 二、代码实现 ❤️ 祝福 ❤️ 前言 母亲节&#xff0c;在每年五月的第二个星期日&#xff0c;是用来感谢母亲的节日。…...

【AutoGPT】AutoGPT出现,是否意味着ChatGPT已被淘汰

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 前言 什么是ChatGPT&#xff1f; 什么是AutoGPT&#xff1f; AutoGPT与ChatGPT的区别 AutoGPT的优势和劣势 优势 劣势 ChatGPT是否会被淘汰&#xff1f; 前言 近年来&#x…...

( 字符串) 9. 回文数 ——【Leetcode每日一题】

❓9. 回文数 难度&#xff1a;简单 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如…...

SpringAOP

SpringAOP 一、AOP1. AOP简介1.1 AOP简介和作用1.2 AOP中的核心概念 2. AOP入门案例【重点】2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三步】定义通知类&#xff0c;制作通知方法【第四步】定义切入点表达式、配…...

学系统集成项目管理工程师(中项)系列15_质量管理

1. 质量&#xff08;Quality&#xff09;的定义 1.1. 反应实体满足主体明确和隐含需求的能力的特性总和 1.2. 明确需求是指在标准、规范、图样、技术要求、合同和其他文件中用户明确提出的要求与需要 1.3. 隐含需求是指用户和社会通过市场调研对实体的期望以及公认的、不必明…...

大连网站/灰色seo关键词排名

求职信是应聘者向招聘单位介绍自己的资历与能力、表达自己就业愿望的一种书信。求职信主要由6部分组成&#xff1a;称谓、正文、结尾、附件、署名、成文时间。 其中&#xff0c;称谓写在第一行&#xff0c;要顶格写公司名称&#xff0c;也可以在公司名称后加“负责人”二字。 正…...

wordpress站点名没有更改/长沙网站优化seo

雅思官方规定&#xff1a;雅思写作考试有最低字数要求&#xff0c;Task 1应不少于150字&#xff0c;Task 2应不少于250字。但是&#xff0c;如果写的越多就越容易得到高分吗&#xff1f;官方回答&#xff1a;“不一定&#xff01;”首先&#xff0c;雅思写作有两篇文章。建议Ta…...

贵南县wap网站建设公司/综合搜索引擎

单例模式用于当一个类只能有一个实例的时候&#xff0c; 通常情况下这个“单例”代表的是某一个物理设备比如打印机&#xff0c;或是某种不可以有多个实例同时存在的虚拟资源或是系统属性比如一个程序的某个引擎或是数据。用单例模式加以控制是非常有必要的。 单例模式需要达到…...

织梦dedecms网站更换域名后文章图片路径批量修改/软件制作

利用springmvc接收前台ajax传过来的数据完成注册功能。为了方便把&#xff0c;前台js的model和后台的user写成一致的功能。代码如下前端&#xff1a;var User function() {var id null;var name null;var password null;var sex null;var telephone null;var role null;…...

wordpress自定义登录页/关键词排名怎么上首页

tar格式&#xff0c;会打包成一个文件&#xff0c;可以对多个目录&#xff0c;或者多个文件进行打包 tar命令只是打包&#xff0c;不会压缩&#xff0c;打包前后大小是一样的 tar命令 -c //打包 -x //解压 -f //指定文件 -t //查看 tar cf 压缩后的文件名 要…...

关闭未备案网站/石家庄seo网络优化的公司

阿里 最重视项目经验 阿里一般情况下有五轮面试&#xff0c;其中大概有四轮都是基于项目的技术在问实现机制、改进技术方案、做的认为不足的地方&#xff0c;技术栈的实现原理&#xff0c;有没有其他替代方案&#xff0c;涉及中间件的原理等等。 重视技术原理 对自己做的项目实…...