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

再析jvm

前言

希望自己每一次学习都有不同的理解

文章目录

    • 前言
    • 1. jvm的组成
        • 取消永久代使用元空间原因
    • 2. 运行时数据区
    • 3. 堆栈区别
    • 队列和栈,队列先进先出,栈先进后出从栈顶弹出
    • 4. GC、内存溢出、垃圾回收
      • 4.1 如何确定引用是否会被回收
        • 4.1.1 Java中的引用类型
        • 4.1.2 如何定位对象
      • 4.2 垃圾回收算法以及收集器
      • 4.3 分代垃圾回收器是怎么工作的
      • 4.4 jvm的类加载器
        • 什么是双亲委派机制
        • 类的加载过程
      • 4.5 jvm调优
        • 流程
        • 参数
        • 如何调整参数

1. jvm的组成

  • Jdk1.6及之前:方法区(永久代), 常量池在方法区
    在这里插入图片描述

  • Jdk1.7:有永久代,但已经逐步“去永久代”,常量池在堆

  • Jdk1.8及之后: 无永久代,元空间, HotSpot JVM
    在这里插入图片描述

  1. 类加载子系统 Class loader 装载class文件到Runtime data area中的method area

  2. 执行引擎 Execution engine执行classes中的指令

  3. 本地方法接口库,与native libraries交互,是其它编程语 言交互的接口

  4. 运行时数据区

首先通过编译器把 Java 代码转换成字节码,类加载器(ClassLoader) 再把字节码加载到内存中,将其放在运行时数据区(Runtime data area)的方 法区内,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作 系统去执行,因此需要特定的命令解析器执行引擎(ExecutionEngine),将 字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他 语言的本地库接口(Native Interface)来实现整个程序的功能。

取消永久代使用元空间原因

1、字符串存在永久代中,容易出现性能问题和内存溢出。

2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。

3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。

元空间的本质和永久代类似,元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入 java 堆中,这样可以加载多少类的元数据就不再由MaxPermSize 控制, 而由系统的实际可用空间来控制。

2. 运行时数据区

在这里插入图片描述

  • 程序计数器:线程所执行的字节码的行号 指示器

  • :存储栈帧,栈帧包含局部变量表、操作 数栈、动态链接、方法出口等信息

  • 本地方法栈:与线程栈一样,但是是为调用native方法服务

  • :内存大的一块,是被所有线程共享 的,几乎所有的对象实例都在这里分配内存,1.7之后常量、静态变量也在此区

  • 方法区:存储已被虚拟机加载的类信息,、即时编译后的代码等数据,1.8后改为元空间

Java中的常量池,实际上分为两种形态:静态常量池运行时常量池

  • 静态常量池,即*.class文件中的常量池,class文件中的常量池不仅仅包含字符串(数字)字面量,还包含类、方法的信息,占用class文件绝大部分空间
  • 运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池

3. 堆栈区别

  • 物理地址分配

    堆的是不连续的,性能相对慢一些,GC的时候也要考虑到 不连续的分配,所以有各种算法,比如标记-消除,复制,标记-压缩,分代 (即新生代使用复制算法,老年代使用标记—压缩

    栈使用的是数据结构中的栈,先进后出的原则,物理地址分配是连续的

  • 内存

    堆内存远大于栈

  • 内容以及范围

    堆内主要存放数组、对象,关注的是数据的存储,对整个应用是可见的,静态变量是存在于方法区的,但是静态的对象是存在堆

    栈主要存放局部变量、操作数栈、返回结果,关注的是方法的执行,仅对线程可见

队列和栈,队列先进先出,栈先进后出从栈顶弹出

4. GC、内存溢出、垃圾回收

内存溢出也就是jvm发生了Full GC,

永久代(java8之前)内存超出临界值后也会Full Gc,Java8之后取消永久代,增加元空间

原因:长生命周期的对象拥有短生命周期对象的引用,导致短生命周期对象未能被释放导致

4.1 如何确定引用是否会被回收

  1. 可达性分析法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。 当一个对象到 GCRoots 没有任何引用链相连时,则证明此对象是可以被回收的。

​ GC Root 对象可以是一些静态的对象,Java方法的local变量或参数, native 方法引用的对象,活着的线程,虚拟机栈中引用的对象

  1. 引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用 被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用 的问题

4.1.1 Java中的引用类型

  • 强引用:长期不会被释放
  • 软引用:有用但不必须,在发生内存溢出之前会被回收
  • 弱引用:有用但不必须,在下一次GC时会被回收
  • 虚引用:无法通过虚引用获得对象,虚引用的用途是在 gc 时返回一个通知,用PhantomReference 实现虚引用

4.1.2 如何定位对象

主要通过jvm线程栈上的引用访问jvm堆,现在主流的方式有句柄式和直接指针;

  • 直接指针: 直接指向对象,优势是速度更快,节省了一次指针定位的开销。

  • 句柄: 可以理解为指向指针的指针,维护着对象的指针。句柄不直接指向对象,而是 指向对象的指针(句柄不发生变化,指向固定内存地址),再由对象的指针指向对象的 真实内存地址。

    Java堆中有一块内存来作为句柄池,引用中存储对象的句柄地址,而句柄中 包含了对象实例数据对象类型数据各自的具体地址信息,具体构造如下图所 示

    优势:引用中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是 非常普遍的行为)时只会改变句柄中的实例数据指针,而引用本身不需要修改

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aOOc9qVj-1677148411673)(/Users/zhipengsong/Library/Application Support/typora-user-images/image-20230223162718403.png)]

4.2 垃圾回收算法以及收集器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E9fwn7l6-1677148411673)(/Users/zhipengsong/Library/Application Support/typora-user-images/image-20230223151320058.png)]

  • 标记-清除算法:标记无用对象,然后进行清除回收。

    • 优点:实现简单,不需要对象进行移动,后面算法以此为基础
    • 缺点:效率不高,产生大量不连续的内存碎片,无法清除。
  • 复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的 对象复制到另一块上,然后再把已使用的内存空间一次清理掉。

    • 优点:解决了内存碎片的问题,
    • 缺点:内存使用率不 高,只有原来的一半。
    • 收集器
      • Serial收集器: 新生代单线程收集器,标记和清理都是单线程,优点 是简单高效
      • ParNew收集器:多线程版本
      • Parallel Scavenge收集器:新生代并行收集器,追求高吞吐量,高效 利用 CPU。吞吐量= 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高 效率的利用CPU时间,尽快完成程序的运算任务,适合后台应用等对交互相应要求不 高的场景
  • 标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清 除掉端边界以外的内存。

    • 优点:解决了内存碎片的问题

    • 缺点:局部对象移动降低效率

    • 收集器

      • Serial Old收集器: 老年代单线程收集器,Serial收集器的老年代版本;
      • Parallel Old收集器 : 老年代并行收集器,吞吐量优先, Parallel Scavenge收集器的老年代版本;

      在这里插入图片描述

  • 分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代和永久代(元数据区)

    • 新生代基本采用复制算法

    • 老年代采用标记整理算法

      • CMS收集器(标记-清除算法): 老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最 短GC回收停顿时间,但是会出现大量的内存碎片,当内存不够使用的时候会采用 Serial Old 回收器进行垃圾清除
      • G1收集器 (标记-整理算法): Java堆并行收集器,基于标记-整理算法,但是G1回收的范围是整个Java堆(包括新生代,老年代)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8FzMteEI-1677148411673)(/Users/zhipengsong/Library/Application Support/typora-user-images/image-20230222141923519.png)]

**在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。 **

4.3 分代垃圾回收器是怎么工作的

分代回收器有两个分区:老生代和新生代,新生代默认的空间占比总空间的 1/3,老生代的默认占比是2/3。

新生代使用的是复制算法,新生代里有 3 个分区:Eden、To Survivor、From Survivor,它们的默认占比是 8:1:1,它的执行流程如下:

  1. 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
  2. 清空 Eden 和 From Survivor 分区;
  3. From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

每次在 From Survivor 到 To Survivor 移动时都存活的对象,年龄就 +1,当年 龄到达 15(默认配置是15)时,升级为老生代。大对象也会直接进入老生代

老生代当空间占用到达某个值之后就会触发全局垃圾收回,一般使用标记整理的 执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程

对象分配:

java对象优先分配在eden区,大对象(需要连续的内存空间的对象,不经过eden和survivor)和长期存活的对象分配至老年代

4.4 jvm的类加载器

启动类加载器:负责加载JRE的核心类库,如jre目标下的rt.jar,charsets.jar等

扩展类加载器:负责加载JRE扩展目录ext中JAR类包

系统类加载器:负责加载ClassPath路径下的类包

用户自定义加载器:负责加载用户自定义路径下的类包 (继承ClassLoader,然后覆盖findClass()方法)

什么是双亲委派机制

在这里插入图片描述

要加载一个类MyClass.class,从低层级到高层级一级一级委派,先由应用层加载器委派给扩展类加载器,再由扩展类委派给启动类加载器;启动类加载器载入失败,再由扩展类加载器载入,扩展类加载器载入失败,最后由应用类加载器载入,如果应用类加载器也找不到那就报ClassNotFound异常了

双亲委派机制的优点:

1.保证安全性,层级关系代表优先级,也就是所有类的加载,优先给启动类加载器,这样就保证了核心类库类。

2.避免重复,如果父类加载器加载过了,子类加载器就没有必要再去加载了

类的加载过程

  1. 加载
    1. 通过过一个类的全限定名获取该类的二进制流
    2. 将该二进制流中的静态存储结构转化为方法去运行时数据结构
    3. 在内存中生成该类的 Class 对象,作为该类的数据访问入口
  2. 验证
    1. 文件格式验证:验证字节流是否符合 Class 文件的规范,常量池中的常量是否有不被支持的类型
    2. 元数据验证: 对字节码描述的信息进行语义分析,如这个类是否有父类,是否集成了不被继承的类等。
    3. 字节码验证:是整个验证过程中最复杂的一个阶段,通过验证数据流和控制流的分析,确定程序语义是否正确,主要针对方法体的验证。如:方法中的类型转换是否正确,跳转指令是否正确等。
    4. 符号引用验证:这个动作在后面的解析过程中发生,主要是为了确保解析动作能正确执行。
  3. 准备 : 为类的变量以及静态变量分配内存并将其初始化为默认值
  4. 解析:要完成符号引用到直接引用的转换动作
  5. 初始化:到了初始化阶段,才真正开始执行类中定义的 Java 程序代码

4.5 jvm调优

在这里插入图片描述

性能调优指标:

  • 吞吐量:重要指标之一,是指不考虑垃圾收集引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标。
  • 延迟:其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收集所引起的停顿,避免应用运行时发生抖动。
  • 内存占用:垃圾收集器流畅运行所需要 的内存数量。

这三个属性中,其中一个任何一个属性性能的提高,几乎都是以另外一个或者两个属性性能的损失作代价,不可兼得,具体某一个属性或者两个属性的性能对应用来说比较重要,要基于应用的业务需求来确定。

流程

  1. 工具:
    1. 于 JDK 的 bin 目录下的工具:jconsole、jvisualvm、jmap
    2. mat工具,可以分析到具体某个线程,某个对象占用了空间
  2. 检查范围
    1. Dump线程详细信息:查看线程内部运行情况,内存热点分析
    2. 死锁检查
    3. 线程监控

调优的目的是什么:

  • GC的时间足够的小
  • GC的次数足够的少
  • 减少老年代的对象数量
  • 发生Full GC的周期足够的长

但是很明显,第一条和第二条相悖,因为GC时间小必然需要一个较小的堆,而次数少则必然需要一个较大的堆

参数

为了防止垃圾收集器在最小、最大之间收缩堆而产生额外的时间,我们通常把最大、最小设置为相同的值

  • -Xms2g:初始化推大小为 2g;
  • -Xmx2g:堆最大内存为 2g;
  • -XX:NewSize :新生代空间大小初始值
  • -XX:MaxNewSize :新生代空间大小最大值
  • -Xmn :新生代空间大小,此处的大小是(eden+2 survivor space)

如果应用存在大量的临时对象,应该选择更大的年轻代;如果存在相对较多的持久对象,年老代应该适当增大。可以通过监控堆状态老年代内存占有情况来决定比例

  • -XX:NewRatio=2:设置年轻的和老年代的内存比例为 1:2;默认为1:2
  • -XX:SurvivorRatio=8:设置新生代Eden 和 Survivor 比例为 8:2;
  • –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
  • -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
  • -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组 合;
  • -XX:+PrintGC:开启打印 gc 信息;
  • -XX:+PrintGCDetails:打印 gc 详细信息。
  • XX:MetaspaceSize=2M : 元空间初始大小,如果没有指定这个参数,元空间会在运行时根据需要动态调整,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
-XX:+UseParallelGC :选择垃圾收集器为并行收集器。 此配置仅对年轻代有效。即上述配置下,年轻代 使用并发收集,而年老代仍旧使用串行收集。 -XX:ParallelGCThreads=20 :配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值 最好配置与处理器数目相等。 -XX:+UseParallelOldGC :配置年老代垃圾收集方式为并行收集。JDK6.0支持对年老代并行收集。 -XX:MaxGCPauseMillis=100 : 设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动 调整年轻代大小,以满足此值。 -XX:+UseAdaptiveSizePolicy :设置此选项后,并行收集器会自动选择年轻代区大小和相应的 Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时,一直 打开。

如何调整参数

系统完成之后不对jvm进行参数调整,进行压测,查看GC日志,GC日志指令: -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:

fullGC后查看GC数据
在这里插入图片描述

之后可以根据一下修改配置,修改之后再进行压测

在这里插入图片描述

User user = new User()做了什么操作,申请了哪些内存

  1. new User(); 创建一个User对象,内存分配在堆上

  2. User user; 创建一个引用,内存分配在栈上

  3. = 将User对象地址赋值给引用

相关文章:

再析jvm

前言 希望自己每一次学习都有不同的理解 文章目录前言1. jvm的组成取消永久代使用元空间原因2. 运行时数据区3. 堆栈区别队列和栈,队列先进先出,栈先进后出从栈顶弹出4. GC、内存溢出、垃圾回收4.1 如何确定引用是否会被回收4.1.1 Java中的引用类型4.1.…...

社招前端二面面试题总结

代码输出结果 var A {n: 4399}; var B function(){this.n 9999}; var C function(){var n 8888}; B.prototype A; C.prototype A; var b new B(); var c new C(); A.n console.log(b.n); console.log(c.n);输出结果:9999 4400 解析: conso…...

人人能读懂redux原理剖析

一、Redux是什么? 众所周知,Redux最早运用于React框架中,是一个全局状态管理器。Redux解决了在开发过程中数据无限层层传递而引发的一系列问题,因此我们有必要来了解一下Redux到底是如何实现的? 二、Redux的核心思想…...

uniCloud云开发----7、uniapp通过uni-swiper-dot实现轮播图

uniapp通过uni-swiper-dot实现轮播图前言效果图1、官网实现的效果2、需求中使用到的效果图官网提供的效果图源码1、html部分2、js部分3、css部分根据需求调整轮播图前言 uni-swiper-dot.文档 uni-swiper-dot 轮播图指示点 - DCloud 插件市场 本次展示根据需求制作的和官网用到…...

IM即时通讯构建企业协同生态链

在当今互联网信息飞速发展的时代,随着企业对协同办公要求的提高,协同办公的定义提升到了智能化办公的范畴。大多企业都非常重视构建连接用户、员工和合作伙伴的生态平台,利用即时通讯软件解决企业内部的工作沟通、信息传递和知识共享等问题。…...

Python实现构建gan模型, 输入一个矩阵和两个参数值,输出一个矩阵

构建一个GAN模型,使用Python实现,该模型将接受一个矩阵和两个参数值作为输入,并输出另一个矩阵。GAN(生成对抗网络)是一种深度学习模型,由生成器和判别器两部分组成,可以用于生成具有一定规律性的数据,如图像或音频。 # 定义生成器 def make_generator(noise_dim, dat…...

开学准备哪些电容笔?ipad触控笔推荐平价

在现代,数码产品的发展受到高技术的驱动。不管是在工作上,还是在学习上,大的显示屏可以使图像更加清晰。Ipad将成为我们日常生活中不可或缺的一部分,无论现在或将来。如果ipad配上一款方便操作的电容笔,将极大地提高我…...

放下和拿起 解放自己

放下太难,从过去中解放自己 工作这么久了,第一次不拿包上班,真爽 人的成长都是在碰撞和摸索中产生的,通过摸索,知道自己能力的边界和欲望的边界以及身体的边界,这三个决定了 你能做什么 你能享受什么&…...

100%BIM学员的疑惑:不会CAD可以学Revit吗?

在新一轮科技创新和产业变革中,信息化与建筑业的融合发展已成为建筑业发展的方向,将对建筑业发展带来战略性和全局性的影响。 建筑业是传统产业,推动建筑业科技创新,加快推进信息化发展,激发创新活力,培育…...

经常会采坑的javascript原型应试题

一. 前言 原型和原型链在面试中历来备受重视,经常被提及。说难可能也不太难,但要真正完全理解,吃透它,还是要多下功夫的。 下面为大家简单阐述我对原型和原型链的理解,若是觉得有说的不对的地方&#xff…...

完全背包—动态规划

一、背包问题概述 如图,完全背包与01背包的区别只有一点:01背包中每个物品只能取一个而完全背包中每个物品可以取无数个。解决完全背包问题必须首先弄明白01背包,不清楚的可以看我的这篇文章01背包—动态规划。 二、例题 重量价值物品0115物…...

消息队列MQ介绍

消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。 消息中间件概述 消息队列技术是…...

C语言进阶(八)—— 链表

1. 链表基本概念1.1 什么是链表链表是一种常用的数据结构,它通过指针将一些列数据结点,连接成一个数据链。相对于数组,链表具有更好的动态性(非顺序存储)。数据域用来存储数据,指针域用于建立与下一个结点的…...

手工测试用例就是自动化测试脚本——使用ruby 1.9新特性进行自动化脚本的编写

昨天因为要装watir-webdriver的原因将用了快一年的ruby1.8.6升级到了1.9。由于1.9是原生支持unicode编码,所以我们可以使用中文进行自动化脚本的编写工作。 做了简单的封装后,我们可以实现如下的自动化测试代码。请注意,这些代码是可以正确运…...

RockerMQ简介和单节点部署

目录一、RockerMQ简介二、Linux中单节点部署1、准备工作2、下载和解压3、修改初始内存4、启动5、查看进程6、发送接收消息测试7、关闭三、控制台的安装与启动(可视化页面)1、修改配置(1)修改端口号(2)指定RocketMQ的name server地…...

SFP光纤笼子 别称 作用 性能要点 工程要素

Hqst盈盛电子导读:2023年,Hqst盈盛电子于下属五金部开发生产SFP光纤连接器笼子等系列产品,所有产品生产及性标准都将参照连接器产品常用测试标准EIA-364-C等标准,以下为我司常规SFP光纤连接器基本性能要求SFP光纤笼子别称&#xf…...

[HarekazeCTF2019]Easy Notes

知识点:session 反序列化,代码审计代码分析 flag.php 中有个 is_admin 函数的判断。 在 lib.php 中有 is_admin 函数,需要 session[admin] 为 true,或者通过文件读取的方式。 在 index.php 中的 include 并不能使用伪协议读取 …...

Java学习-IO流-字符流-FileReader

Java学习-IO流-字符流-FileReader 字符流 字节流 字符集 输入流:默认一次读一个字节,遇到中文时一次读多个字节 输出流:底层把数据按照指定编码方式编码,变成字节写入文件 使用场景:纯文本文件读写 // …...

python攻陷米哈游《元神》数据?详情请看文章。。

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 《原神》是由米哈游自研的一款全新开放世界冒险RPG。 里面拥有许多丰富得角色,让玩家为之着迷~ 今天,我们就来用python探索一下原神游戏角色信息! 标题大家看看就好了哈~&#xff08…...

【unity细节】基于unity子对象(如相机)为什么无法进行z轴的拖拽移动和z轴自动归位的问题

👨‍💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity细节和bug ⭐基于unity子对象为什么无法进行z轴的拖拽移动和z轴自动归位⭐ 文章目录⭐基于u…...

如何维护固态继电器?

固态继电器是SSR的简称,是由微电子电路、分立电子器件和电力电子功率器件组成的非接触式开关。隔离装置用于实现控制端子与负载终端之间的隔离。固态继电器的输入端使用微小的控制信号直接驱动大电流负载。那么,如何保养固态继电器呢? 在为小…...

Sprng依赖注入(三):构造方法注入是如何工作的?

前言这是Spring依赖注入系列的第三篇,前两篇主要分析了Spring bean依赖属性注入的两种方式,是字段注入和setter方法注入,单独比较这两种方式,会发现其过程和工作原理非常类似,那么构造方法注入会不会也和前两种比较类似…...

「1」指针进阶——详解

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 🐰指针的回顾 🐰字符指针 🐰指针数组 🌸模…...

JS语法让人困惑的点 “==与===”

在JS中有很多神奇的语法,非常让人困惑,我们就先一一道来,相信你在开发中或多或少都踩过这些坑,或者让人无法理解。 今天我们就来说下【】和【】 这题对于很多没有系统学过前端开发的技术人员来说,算个重点&#xff0c…...

《狂飙》壁纸大嫂如此惊艳,做成日历壁纸天天看

兄弟们,今年的反腐大剧狂飙都有看吗 ? 话说,名字虽然叫狂飙,但是全剧只有有田一个人在狂飙! 当然,有田虽然亮眼,但是毕竟是个糟老头子,正经人谁看有田啊,当然是看大嫂了…...

手机照片删除了怎么恢复

手机照片删除了怎么恢复?喜欢拍照的小伙伴,都会不定期删除手机上的照片,因为这些爱拍照的人,手机中会存储着很多照片,删除照片是必然的,但在手机删除照片时,如果是一张一张删除太麻烦了,就直接…...

maven pom.xml 依赖的scope属性

maven pom.xml 依赖的scope属性 compile 适用范围 编译期、测试期、运行期 作用 从中央仓库拉取依赖到本地,并编译 打包到结果包中 runtime 适用范围 测试期、运行期 作用 runtime 用在 Class.forName(“com.mysql.jdbc.Driver”) 时,compile 编…...

git 的使用方法 (下 - 远程仓库和图形化)

目录前言:一、什么是协同开发二、Gitee 使用协同开发1. 首先注册一个码云账号2. 新建一个仓库3. 根据下图把新建仓库设置为开源4. 在远端合并分支的方法5. 链接 git 远程6. 提交(同步)远程7. 远程拉取至本地8. 远程分支三、git 图形化的使用1…...

Java基础:拼图小游戏

涉及到的知识: 1.图形用户接口GUI(Graphical User Interface)用图形化的方式显示操作界面 两个体系: AWT包和Swing包 2.界面会用到JFrame类 3.界面中的菜单会用到JMenuBar, JMenu, JMenuItem 4.添加图片 在设置完JLabel的location之后还需要获得展示内容的窗体, 通过setLay…...

一个跟蘑菇结缘的企业老板

记得那是一个很久以前的一家公司了董事长办公室里中的大型盆栽里面长了一个蘑菇董事长认为是祥瑞每天都会浇水后来一个新来的保洁阿姨以为杂草啥的给他掰掉扔垃圾桶了董事长第二天来浇水的时候发现没了就问谁动了他的蘑菇问道之后就跑到楼道大垃圾桶那里把蘑菇找回来种在花盆里…...