程序员面试再不了解JVM? 你就OUT了!一篇教你秒懂Java垃圾回收机!

阿里Java面试被out后,奋战3个月,最终拿下美团Offer! 前言 一位小伙伴准备了许久的阿里Java面试,原以为能够顺利拿下offer,但在第三面还是被摁在地上反复摩擦,丧气一段时间后,小伙伴调整了心态重新尝试了一下,最终拿下了美团offer,今天小编把这位小伙伴遇到的面试题分享出来,希望能对即将面试的小伙伴有所帮助。 阿里 mq 消息可靠性,幂等如何保证 分布式锁的实现方案比较,为什么选择 zookeeper, zookeeper 一致性协议原理 线程池参数,阻塞队列实现 一致性 Hash解决什么问题, 如何实现? 虚拟节点的作用? Java 锁的实现方式, 阅读详情

在这里插入图片描述

本文是基于jdk8进行分析的

概述

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java虚拟机本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。Java语言的可移植性正是建立在Java虚拟机的基础上。任何平台只要装有针对于该平台的Java虚拟机(JVM从软件层面帮我们屏蔽不同操作系统在底层硬件与指令上的区别),字节码文件(.class)就可以在该平台上运行。这就是“一次编译,多次运行”。

JVM体系结构

image

Java虚拟机包含类装载器子系统、执行引擎、运行时数据区、本地方法接口和垃圾收集模块。其中垃圾收集模块在Java虚拟机规范中并没有要求Java虚拟机垃圾收集,但是在没有发明无限的内存之前,大多数JVM实现都是有垃圾收集的。

  • 类装载器子系统:根据给定的全限定类名(如:java.lang.Object)来装载class文件到运行时数据区域的方法区中。
  • 执行引擎:执行字节码或执行本地方法。
  • 运行时数据区:我们常说的JVM的内存,堆,方法区,虚拟机栈,本地方法栈,程序计数器。
  • 本地方法接口:与本地方法库交互,作用就是为了融合不同编程语言为Java所用,它的初衷是融合C/C++程序。

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

类加载机制

Java类加载机制就是虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的java类型。

类加载器

类加载器分为启动类加载器,扩展类加载器,应用程序类加载器,自定义类加载器。各种类加载器之间存在着逻辑上的父子关系,但不是真正意义上的父子关系,因为它们直接没有从属关系。除了启动类加载器(Bootstrap ClassLoader)是由C++编写的,其他都是由Java编写的。由Java编写的类加载器都继承自类java.lang.ClassLoader。

  1. 启动类加载器(BootstrapClassLoader):负责加载$JAVA_HOME/jre/lib目录下的核心类库,比如rt.jar,charsets.jar。
  2. 扩展类加载器(ExtClassLoader):负责加载支撑J$JAVA_HOME/jre/lib/ext目录下的JAR类包。父加载器是启动类加载器。
  3. 应用类加载器(AppClassLoader):负责加载ClassPath路径下的类包,主要就是加载我们自己写的那些类。父加载器是扩展类加载器。
  4. 自定义类加载器(CustomClassLoader):负责加载用户自定义目录下的类包。父加载器是应用类加载器。
类加载过程

java类加载分为5个过程,加载–>验证–>准备–>解析–>初始化。这5个阶段一般是顺序发生的,但在动态绑定的情况下,解析阶段发生在初始化阶段之后。

  • 加载:将字节码从不同的数据源(可能是 class 文件,也可能是 jar 包,甚至网络)转化为二进制字节流加载到内存中;将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;并在堆中生成一个代表该类的 java.lang.Class 对象,作为对方法区这个类的各种数据的访问入口。
  • 验证:验证的目的是为了确保加载进来的class文件符合JVM的规范,一般是进行文件格式的验证、元数据的验证、字节码验证和符号引用验证。
  1. 文件格式的验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理,该验证的主要目的是保证输入的字节流能正确地解析并存储于方法区之内。经过该阶段的验证后,字节流才会进入内存的方法区中进行存储,后面的三个验证都是基于方法区的存储结构进行的。
  2. 元数据的验证:对类的元数据信息进行语义校验(其实就是对类中的各数据类型进行语法校验),保证不存在不符合Java语法规范的元数据信息。
  3. 字节码验证:该阶段验证的主要工作是进行数据流和控制流分析,对类的方法体进行校验分析,以保证被校验的类的方法在运行时不会做出危害虚拟机安全的行为。
  4. 符号引用验证:这是最后一个阶段的验证,它发生在虚拟机将符号引用转化为直接引用的时候(解析阶段中发生该转化),主要是对类自身以外的信息(常量池中的各种符号引用)进行匹配性的校验。
  • 准备:给类的静态变量分配空间,并赋予默认值。
  • 解析:将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。
  • 初始化:对类的静态变量初始化为指定的值,执行静态代码块。
双亲委派机制

双亲委派机制就是当某个类加载器收到加载类的请求,如果这个类没有被加载过,该类加载器不会直接加载,会先为委派给父加载器,如果父加载器没有加载过,依次往上传递,直到顶层启动类加载器。如果父加载器可以完成加载任务,则父加载器加载返回;如果父加载器不能完成加载任务,才会自己去进行加载。一句话概述双亲委派机制加载流程就是,从下往上检查类是否已经被加载,从上往下尝试去加载。

双亲委派机制的优点:

  1. 沙箱安全机制:避免核心API被篡改。自己写的java.lang.String.class类不会被加载。
  2. 避免重复加载:如果父加载器已经加载过该类,子类加载器就没有必要再去加载。

双亲委派机制加载类的核心代码 ClassLoader类的loadClass()方法:

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 首先会检查该类是否已经被本类加载器加载,如果已经被加载则直接返回
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                // 如果没有被加载,则委托父加载器去加载
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        // 让父加载器对象去调用loadClass方法
                        c = parent.loadClass(name, false);
                    } else {
                        // parent==null,说明父加载器是启动类加载器。启动类加载器是C++编写的,这里去调用本地方法区尝试加载该类。
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                }
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    // 如果父加载器没有加载到该类,则自己去加载。这里会调用URLClassLoader类的findClass()方法
                    c = findClass(name);
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
全盘负责委托机制

全盘负责委托机制就是当一个Classloader加载一个Class的时候,这个Class所依赖的和引用的其它Class通常也由这个Classloader负责加载。

打破双亲委派机制

打破双亲委派机制就是我们希望自定义类加载器去直接加载指定类,而不是先委托父加载器去加载或者是自定义类加载器加载不到才让父加载器去进行加载。

自定义类加载器实现

了解双亲委派机制以及打破双亲委派机制之后,我们可以自己写一个自定义类加载器。自定义类加载器实现思路:

如果使用双亲委派机制就是重写findClass()方法(类加载器具体去加载类的方法),代码传送门。

如果要打破双亲委派机制,在重写findClass()方法基础上,还需要重新loadClass()方法,这里我们可以改写逻辑,先让该类加载器去加载类,加载不到再让父加载器去进行加载,代码传送门。

JVM运行时数据区

  • 程序计数器

程序计数器线程私有的,它的生命周期与线程相同,它是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果线程当前正在执行的方法是本地方法,这个计数器值则应为空。字节码解释器的工作就是通过这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成。这个区域是唯一不会抛出OutOfMemoryError异常的区域。

  • 虚拟机栈

虚拟机栈是线程私有的,它的生命周期与线程相同。每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double),对象引用和returnAddress类型。

以下异常条件与Java虚拟机栈相关:

如果线程中请求的栈深度大于虚拟机所允许的深度,Java虚拟机将会抛出StackOverflowError异常。【白嫖资料】
    如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存,Java虚拟机将会抛出OutOfMemoryError异常。

  • 本地方法栈

本地方法栈是线程私有的,生命周期与当前线程一致。与虚拟机栈的作用是一样的,区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈是为虚拟机使用到的本地方法服务。

以下异常条件与本地方法栈相关联(与虚拟机栈一样):

如果线程中请求的栈深度大于虚拟机所允许的深度,Java虚拟机将会抛出tackOverflowError异常。

如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存,Java虚拟机将会抛出OutOfMemoryError异常。

  • 堆

堆是线程共享的,在虚拟机启动的时候创建,从中分配类实例(几乎所有的对象都存放在堆中,但是不是所有的)和数组的内存。对于大多数应用来说,堆是内存最大的一块区域;同时堆是内存模型中最重要的一个区域,也是JVM调优重点关注的区域。对象的堆存储由自动存储管理系统(称为垃圾收集器)回收;对象永远不会显式释放。

以下异常情况与堆相关联:

如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虚拟机将会抛出OutOfMemoryError异常。

堆内存分为年轻代(Young Generation)和老年代(Old Generation)。

  1. 年轻代(YoungGen):年轻代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1。
  2. 老年代(OldGen)。
  • 方法区(元空间)

方法区是线程共享的,在虚拟机启动的时候创建,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

以下异常条件与方法区域相关联:

如果方法区无法满足新的内存分配需求时,Java虚拟机将会抛出OutOfMemoryError异常。

  • 运行时常量池

运行时常量池是方法区的一部分。它包含多种常量,范围从编译时已知的数字文字到必须在运行时解析的方法和字段引用。运行时常量池的功能类似于常规编程语言的符号表,尽管它包含的数据范围比典型的符号表还大。每个运行时常量池都是从Java虚拟机的方法区分配的。当Java虚拟机创建类或接口时,将为该类或接口构造运行时常量池。

以下异常条件与类或接口的运行时常量池的构造相关联:

如果运行时常量池无法再申请到内存时,则Java虚拟机将抛出OutOfMemoryError异常。

  • 直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。但是这部分内存有时候会使用,而且也可能导致OutOfMemoryError异常出现,所以这里简单提一下。直接内存的分配不会受到Java 堆大小的限制,既然是内存,肯定还是会受到本机总内存的大小及处理器寻址空间的限制。服务器管理员配置虚拟机参数时,一般会根据实际内存设置-Xmx等参数信息,但经常会忽略掉直接内存,使得各个内存区域的总和大于物理内存限制从而导致动态扩展时出现OutOfMemoryError异常。【获取资料】

垃圾回收机制

在java中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。

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

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

垃圾收集算法
  • 分代收集理论

  • 标记—清除算法

标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。

image

  • 标记—复制算法

按照容量划分为2个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用区域的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。

image

  • 标记—整理算法

标记无用对象,让所有存活对象都向一端移动,然后直接清除掉端边界以外的内存。

image

垃圾收集器
  • Serial 收集器(标记—复制算法):新生代单线程收集器,标记和清理都是单线程,优点是简单高效。

  • ParNew 收集器(标记—复制算法):新生代并行收集器,实际上是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。

  • Parallel Scavenge 收集器(标记—复制算法):新生代并行收集器,追求高吞吐量,高效利用CPU。吞吐量=用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效的利用CPU时间,尽快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景。

  • Serial Old 收集器(标记—整理算法):老年代单线程收集器,Serial收集器的老年代版本。

  • Parallel Old 收集器(标记—整理算法):老年代并行收集器,吞吐量优先,Parallel Scavenge收集器的老年代版本。

  • Concurrent Mark Sweep(CMS)收集器(标记—清除算法):老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。

  • Garbage First(G1)收集器(标记—整理算法):Java堆并行收集器,G1收集器是JDK1.7提供的一个新收集器,G1收集器基于“标记—整理”算法实现,也就是说不会产生内存碎片。此外,G1收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或者老年代。

JVM调优参数
  • -Xms4g:初始化堆大小为4g
  • -Xmx4g:堆最大内存为4g
  • -XX:NewRatio=4:设置年轻代和老年代的内存比例为1:4
  • -XX:SurvivorRatio=8:设置新生代Eden和Survivor比例为8:2(8:1:1)
  • -XX:+UseParNewGC:指定使用ParNew + Serial Old垃圾回收器组合
  • -XX:+UseParallelOldGC:指定使用ParNew + ParNew Old垃圾回收器组合
  • -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合
  • -XX:+PrintGC:开启打印gc信息
  • -XX:+PrintGCDetails:打印gc详细信息

分类: [Java]在这里插入图片描述

最新2021整理收集的很多干货,包含mysql,netty,spring,线程,spring cloud、jvm、源码、算法等详细讲解,需要获取这些内容的朋友加Q君样:484138291

JVM高频面试基本问题与知识点整理 阅读详情

相关推荐

fastbin attack快速入门

0x01 fastbin简介 Fastbin包含0x20~0x80大小bin的数组指针,用于快速分配小堆块。fastbin按照单链表结构进行组织,相同大小的bin在同一个链表中,fd指向下一个bin,采用LIFO(Last In First Out)机制。在fastbin中,堆块的inuse标志都为1,处于占用状态,防止chunk释放时进行合并,加快小堆块的分配。 正常fastbin的使用 通过这个简单的案例来了解fastbin的单链表结构,malloc和free的过程。 #include<stdio

abelxu 1571

面试阿里被问到JVM,不逼逼赖赖,直接盘给面试官看!!!

面试阿里被问到JVM,不逼逼赖赖,直接盘给面试官看!!!概述JVM体系结构类加载机制类加载器类加载过程双亲委派机制全盘负责委托机制打破双亲委派机制自定义类加载器实现JVM运行时数据区程序计数器虚拟机栈本地方法栈堆方法区(元空间)运行时常量池直接内存垃圾回收机制GC对象判定方法垃圾收集算法垃圾收集器JVM调优参数 概述 JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 J.

wj1314250的博客 3587

SAP 中配置权限职责菜单并分配给用户的核心流程是:用PFCG 创建 / 维护角色(含菜单、事务码、权限)→ 生成权限参数文件 → 通过 SU01/SU10 将角色分配给用户

SAP权限配置核心流程:1)通过PFCG创建角色,配置菜单事务码及权限对象;2)生成权限参数文件;3)用SU01/SU10分配角色给用户。关键步骤包括:在PFCG中维护菜单结构、设置权限字段值、生成Profile,通过用户比较验证权限。批量分配可用SU10,特殊需求可创建复合角色或自定义权限对象。常见问题需检查权限缺失(SU53)、菜单分配及组织级别设置。流程简化为:创建角色→配置权限→分配用户→验证生效。

金牌架构师 1276

类的加载过程(生命周期)

一、概述 生命周期的7个阶段: 从使用过程看: 最后会在方法区,存在类的模版,之后就可以使用这个类了。 二、过程1:Loading阶段(加载) 所谓加载,就是将字节码文件加载到机器内存中,并在内存中构建出Java类的原型-类模版对象,其是一个java类在JVM内存中的一个快照,JVM将字节码文件中解析出来的常量池、类字段、类方法都存储到模版中,这样JVM在运行期间可以通过类模版获取到类中的任意信息、遍历成员变量、方法调用。反射机制也基于这个。 1、加载完成的操作 查找并加载二进制数据,

liming0025的专栏 4468

轨迹优化 | 基于ESDF的共轭梯度优化算法(附ROS C++/Python仿真)

共轭梯度法的核心原理是求解优化问题的共轭向量组作为优化方向,由于优化方向间彼此正交,故每次迭代只需沿着一个方向寻优而互不影响。本文设计基于ESDF的障碍约束、曲率约束和平滑约束,基于ROS C++和Python提供了共轭梯度法的轨迹优化实践案例

FRIGIDWINTER的博客 1万+

【UG\NX二次开发】使用内部函数展开和折叠工序导航器

NX二次开发-群精选」专栏收录了那些曾散落在聊天对话框里的精彩的知识分享,这都是被遗落的宝贵财富。让我们一起向大佬学习,充满激情地进步,不断超越自己。底部联系方式,欢迎您加入一起交流。​下次一定。

王牌飞行员_里海的博客 822

类的加载

1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。 类加载器并不需要等到某个类被“首次...

立志变成java巨头 1381

YOLOv11的对比学习预训练改进-(通过SimCLR预训练增强特征提取)

本文介绍了将SimCLR对比学习预训练与YOLOv11目标检测模型相结合的创新方法。文章首先概述了目标检测领域的发展现状和YOLOv11的架构优化,包括主干网络、特征金字塔和检测头的改进设计。其次详细解析了SimCLR对比学习的核心原理,涵盖数据增强、投影头设计和NT-Xent损失函数。最后探讨了如何将对比学习与目标检测有效结合,通过特征空间对齐和渐进式微调策略提升模型性能。该方法显著增强了特征提取能力,提高了检测精度和训练效率,特别是在小目标和遮挡目标的检测上表现突出。

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 687

类的加载过程详解

在java中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载。 按照java虚拟机规范,从class文件到加载进入内存中的类,再到类卸载出内存为止,整个生命周期如下 一、加载 将java类的字节码文件加载到机器内存中,并在内存中构建出java类的原型(类模板对象) 1、加载类时,java虚拟机加载步骤 (1)通过类的全名,获取类的二进制数据流 (2)解析类的二进制数据流为方法区内的数据结构(Java类模型) (3)创建java.lang.

勇心在馨 9721

微信小程序、H5微信公众号网页JSAPI:解决报错requestMerchantTransfer:fail:internal error(使用wx.requestMerchantTransfer错误)

如何解决requestMerchantTransfer:fail:internal error,微信小程序wx.requestMerchantTransfer报错,微信公众号H5网页使用jssdk调用wx.requestMerchantTransfer报错,JSAPI调起用户确认收款报错errMsg:“requestMerchantTransfer:fail:internal error“,微信小程序/H5 调起确认收款界面,JSAPI调起用户确认收款,微信公众号(H5),用户发起提现,商家转账给用户,用户

✅ 精选推荐文章 4976

uniapp(安卓苹果APP端):解决video组件播放视频卡顿,视频一直加载非常缓慢或加载不出来解决方案,解决多个video组件视频播放很卡一直加载非常慢怎么办(无论真机调试还是本地测试都完美搞定)

uni-app APP端video组件播放视频卡顿,uniapp video app 加载不出来解决方案,uniapp app使用video视频播放卡顿,uni-app APP端video组件播放视频卡顿_uniapp video老是加载,uniapp开发app视频在真机上卡顿,安卓app播放视频很卡,苹果ios真机运行播放视频加载很慢怎么办,解决UniApp中MP4视频播放卡顿问题,解决m3u8视频播放很卡的问题,uniapp 使用video组件,部分视频加载非常慢,uniapp视频播放卡顿,安卓视频播放

✅ 精选推荐文章 7919

一文解读类的加载过程(类的生命周期)

在Java中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载。按照Java虚拟机规范,从class文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包括如下7个阶段:其中,验证、准备、解析3个部分统称为链接(Linking)

一个菜鸡的博客 8888

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

android经典项目案例开发实战宝典,再不了解你就out啦

自我介绍一下,小编13年北京科技大学毕业,曾经在字节跳动待过,也去过vivo、小米等大厂,18年进入华为一直到现在。小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担,能在岗位上再创辉煌,步步高升!!。

2401_84904939的博客 1821

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java数组排列组合,再不了解你就out啦

4 年经验应该具备哪些技能 首先,简单的聊一下我认为的 4 年经验左右、优秀的 Java 程序员应该具备的技能有哪些,按“专业技能”和“项目”两块,包括但不限于以下内容。 专业技能方面 基础:JDK 常用类的原理、源码、使用场景。 设计模式:常用几种的原理、使用场景,单例、动态代理、模板、责任链等。 数据结构:数组、链表、栈、队列、树。 网络:TCP、HTTP、HTTPS、负载均衡算法。 框架:Spring IoC 原理、Spring AOP 原理和使用、Spring 常用的扩展点、MyBatis 的核心

m0_57205294的博客 730

java线程安全面试题,再不了解你就out啦

汇总技术架构路线,梳理技术盲区(条理清晰,一清二楚) 在技术汇总中,可以看到有一些是自己常用的,也有一些是当前工作经历下没用接触过的。那么这些以上的技术栈,你有想过他们是怎么互相配合,组装出一张技术架构图吗?每一个地方用什么技术承载,也可以考虑自己的日常开发中,都有哪些技术来支撑你们整个技术框架。 这是一张把服务端开发涉及的技术栈汇总出来的一张技术架构图。 当然技术栈内容绝对不止局限于此,还有很多的其他的框架,可以被替代,只不过这些是比较常用的。 这些构成你日常开发的整张技术图,可能有些是没用接触的,但

m0_57767685的博客 212

java给数组分配空间,再不了解你就out啦

三、堆空间 基本描述 JVM启动时创建堆区,是内存管理的核心区,通常情况下也是最大的内存空间,是被所有线程共享的,几乎所有的对象实例都要在堆中分配内存,所以这里也是垃圾回收的重点空间。 堆栈关系 栈是JVM运行时的单位,堆是存储单位,当栈中方法结束,相关对象失去所有引用后,不会马上被移除堆空间,要等到垃圾收集器运行的时候。 四、虚拟机栈 虚拟机栈(Java栈)在每个线程创建时都会生成一个虚拟机栈,栈的内部是一个个栈帧单元,对应Java方法的调用,其生命周期和线程周期保持一致。用来存储方法的局部遍历,部分执

m0_57768035的博客 241

面试必问系列 | 工作很多年了,还不会JVM性能调优?那你就Out了,快点收藏冰河写的这篇JVM性能调优文章吧

对于工作3年左右的Java程序员来说,在面试大厂的过程中,面试官可能不会太关注你做了多少个项目、你的CRUD水平如何。更多的是关注你对某项技术点的理解深度,所以说,工作3年左右的小伙伴一定要把自己的重心放到技术的深度上来。

冰河的专栏 2593

面试官问:垃圾回收机制是怎样的?(附图解+比喻+避坑指南)

摘要:垃圾回收(GC)是JVM自动管理内存的核心机制,自动回收不再使用的对象,避免内存泄漏。GC机制分为垃圾判定(可达性分析)、回收算法(标记-清除/复制/标记-整理/分代收集)、垃圾收集器(Serial/Parallel/CMS/G1/ZGC)三层。本文用“城市环卫系统”比喻 + 四大算法详解 + 七大收集器对比 + 6道面试官追问,彻底讲透这道JVM面试必考题。一句话:GC = 自动识别“垃圾” + 高效清理“垃圾”,让程序员从手动内存管理中解放出来。

折哥|智能物流与Java实战,副高数据库工程师。深耕出版社物流WMS/OMS(线体/立库/VGA),也分享Java进阶与OMS电商对接。Oracle→PG实战派。相信沉淀可迁移能力,分享通用技术,不藏不虚。 731

2021最新京东Java面试题目,再不了解你就out啦

01 Mysql 1. 数据库三范式及判断、E-R图 2. innodb和myisam存储引擎的区别 3. 索引分类(主键、唯一索引、全文索引、覆盖索引等等),最左前缀原则,哪些条件无法使用索引 4. B树、B+树区别,索引为何使用B+树 5. 聚集索引与非聚集索引(使用非聚集索引的查询过程) 6. 事务的ACID(原子性、一致性、隔离性、持久性) 7. 事务隔离级别和各自存在的问题(脏读、不可重复读、幻读)和解决方式(间隙锁及MVCC) 8. 乐观锁和悲观锁、行锁与表锁、共享锁与排他锁(inndob如何手

m0_56662269的博客 149

JVM面试精讲:内存模型、垃圾回收算法、类加载机制与GC调优场景

JVM(Java虚拟机)是Java程序的运行环境,主要组成部分包括类加载器、运行时数据区、执行引擎和本地库接口。运行时数据区包含堆、方法区、栈、本地方法栈和程序计数器。JVM采用分代垃圾回收机制,包括新生代和老年代,使用标记清除、复制、标记整理等算法进行内存管理。垃圾回收器有串行、并行、CMS和G1等类型。JVM调优涉及堆大小、垃圾回收器选择等参数设置,可通过jmap、jstack等工具监控和排查内存泄漏、CPU飙高等问题。双亲委派机制确保类加载的安全性和唯一性。

xwhxy的博客 530

JUC、JVM

什么是juc?JUC就是java.util.concurrent工具包的简称。这是一个处理线程的工具包。提供了许多在并发编程工程中常用的工具类,用于定义类似于线程的自定义子系统,包括线程池、异步IO、轻量级框架、还提供了多线程上下文的Collectiion的实现。什么是进程和线程?一个软件一个进程,一个进程有许多的线程。进程——资源分配最小单位  线程——程序执行最小单位New 新建状态(线程刚被创建,start方法之前的状态)

qq_42012853的博客 2030

2026Java面试 | Java 8、Java 21、Java 25 新特性与 Spring Boot 版本对应指南:JVM 垃圾回收、版本差异与迁移实践

Java面试 | Java 8、Java 21、Java 25 新特性与 Spring Boot 版本对应指南:JVM 垃圾回收、版本差异与迁移实践

weixin_48053866的博客 642

docker域名解析,再不了解你就out啦

个人基本情况: 首先介绍一下自己的个人基本情况,某专科学校毕业,计算机技术与应用专业,有过2年的工作经验,毕业以后一直想要进入一线互联网大厂工作,但无奈学历受限,屡屡被挡在门外。后来接触到一个朋友,了解到“霸面”,所以鼓起勇气去尝试了,挑战了一下蚂蚁金服,没想到经过4轮面试之后,居然拿到了offer,现特分享一下自己的面试真题,希望能够给你有所帮助。 一面真题 项目介绍 项目中如何保证数据一致性的 项目中存在的问题 JVM内存 程序计算器的作用 gc 算法,垃圾收集器 Spring事务,事务的实现机制,

碧海朝天素 625

一文解决面试中的JVM问题

Java Virtual Machine,JAVA程序的运行环境(JAVA二进制字节码的运行环境)

qq_37429343的博客 423
上一篇: 妈妈再也不用担心我的学习了!看完教你一招教你吃透数据结构链表!
下一篇: 关于Java泛型你还有什么疑虑?看完这篇一键消除你的小烦恼!
Danny_java
博客等级 码龄5年 9粉丝 64原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值