面试 Java 基础八股文十问十答第二十四期

2024-04-13 12:52

本文主要是介绍面试 Java 基础八股文十问十答第二十四期,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

面试 Java 基础八股文十问十答第二十四期

作者:程序员小白条,个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)类加载与卸载

在Java中,类加载是指将类的字节码加载到内存中,并生成对应的Class对象的过程。类加载器负责加载类文件的任务,Java虚拟机(JVM)在运行时动态加载类,使得程序可以在运行时引用这些类。

类加载的过程包括加载、链接和初始化三个阶段:

  • 加载(Loading): 将类的字节码从磁盘或网络加载到内存中。
  • 链接(Linking): 将类与其他类连接起来,包括验证、准备(为静态变量分配内存并初始化为默认值)和解析(将符号引用转换为直接引用)。
  • 初始化(Initialization): 执行类的初始化代码,包括静态变量赋值和静态代码块的执行。

类卸载是指当类在运行时不再需要时,由垃圾回收器将其从内存中删除的过程。类被卸载的条件是类加载器加载的类实例被回收,且该类所有的实例都已经被回收。类卸载是Java虚拟机的一个重要功能,可以避免内存泄漏和资源浪费。

2)JVM的内存模型

JVM的内存模型主要包括以下几个部分:

  • 方法区(Method Area): 存放类的元信息、常量、静态变量等数据。方法区是线程共享的内存区域,用于存储被虚拟机加载的类信息。
  • 堆(Heap): 存放对象实例。堆是线程共享的内存区域,用于存储所有被new出来的对象和数组。在堆中分为新生代和老年代,新生代又分为Eden区、Survivor From区和Survivor To区。
  • 虚拟机栈(Java Virtual Machine Stacks): 每个线程在创建时会创建一个栈,用于存放局部变量、方法参数、返回值和部分结果。栈帧包含了方法的运行过程,包括局部变量表、操作数栈、动态链接、方法出口等信息。
  • 本地方法栈(Native Method Stack): 与虚拟机栈类似,但是用于执行本地方法的部分。
  • 程序计数器(Program Counter): 每个线程都有一个程序计数器,用于存储当前线程正在执行的字节码指令地址。

3)堆和栈的区别

堆和栈是Java中两种不同的内存分配方式,主要区别如下:

  • 存放内容: 堆用于存放对象实例,包括由new创建的对象和数组。栈用于存放基本数据类型的变量和对象的引用(即对象的地址)。
  • 生命周期: 堆中的对象的生命周期由虚拟机的垃圾回收器管理,当对象不再被引用时,会被垃圾回收器回收。栈中的变量生命周期与方法的调用周期相同,当方法执行结束时,栈中的局部变量会被销毁。
  • 空间大小和管理: 堆的空间通常较大,可以动态地分配和回收内存。栈的空间相对较小,大小在编译时就已确定,并且由系统自动管理。
  • 访问速度: 栈的访问速度比堆要快,因为栈是按照“先进后出”的原则管理数据,访问和存储速度更快。堆的访问速度相对较慢,因为要通过引用来访问对象。

总的来说,堆和栈在Java中扮演着不同的角色,理解它们的区别有助于更好地理解Java程序的运行机制和内存管理。

4)什么时候会触发 Full GC

Full GC(Full Garbage Collection)是Java虚拟机执行的一种垃圾回收操作,它会清理整个堆内存,包括新生代和老年代。Full GC通常在以下情况下触发:

  • 老年代空间不足: 当老年代的空间不足以存放新分配的对象时,会触发Full GC来清理老年代,并尽量回收内存。
  • 永久代(在Java 8之前)或元空间(在Java 8及以后)空间不足: 如果永久代或元空间的空间不足以存放类的元数据、常量池等信息时,会触发Full GC来进行清理。
  • 手动触发: 开发人员可以通过调用System.gc()方法来建议虚拟机执行垃圾回收操作,有时候会触发Full GC。

Full GC是一种开销较大的操作,因为它会暂停所有的应用线程,直到垃圾回收完成。因此,应尽量避免Full GC的频繁发生,可以通过优化程序代码和合理设置堆内存大小来减少Full GC的次数。

5)什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?

Java虚拟机(Java Virtual Machine,JVM)是Java程序运行的环境,它负责将Java字节码解释或编译成特定平台上的机器指令,并管理程序的内存、线程等资源。JVM实现了Java语言规范,是Java跨平台特性的关键。

Java被称作“平台无关的编程语言”,主要是因为Java程序在编译时生成的是字节码(Bytecode),而不是特定平台上的机器码。这些字节码可以在任何支持Java虚拟机的平台上运行,而无需重新编译。Java虚拟机负责将字节码解释或编译成特定平台上的机器指令,从而实现了跨平台的能力。

6)Java内存结构

Java内存结构包括以下几个部分:

  • 程序计数器(Program Counter Register): 每个线程都有一个程序计数器,用于存储当前线程正在执行的字节码指令地址。
  • Java虚拟机栈(Java Virtual Machine Stacks): 每个线程在创建时都会创建一个栈,用于存放方法的局部变量、方法参数、返回值和部分结果。每个方法在执行时会创建一个栈帧,栈帧包含了方法的运行过程中所需的信息。
  • 本地方法栈(Native Method Stack): 与虚拟机栈类似,但用于执行本地方法(Native Method)的部分。
  • 堆(Heap): 存放对象实例,包括由new创建的对象和数组。堆是所有线程共享的内存区域,用于存储动态分配的对象。
  • 方法区(Method Area): 存放类的元信息、常量、静态变量等数据。方法区是所有线程共享的内存区域,用于存储被虚拟机加载的类信息。
  • 运行时常量池(Runtime Constant Pool): 方法区的一部分,用于存放编译期生成的字面量和符号引用。在运行时,还可以将新的常量池符号引用存放到运行时常量池中。

这些内存区域在Java程序的运行过程中起着不同的作用,相互配合来支持程序的执行。

7)对象分配规则

Java中的对象分配规则主要包括以下几个方面:

  • 堆分配: Java中的对象实例都在堆(Heap)中分配内存。当我们使用new关键字创建一个对象时,内存会在堆上动态分配。
  • 栈上分配: 对于一些不逃逸的局部变量,编译器可以选择将它们分配在栈上,这样可以提高对象的访问速度。
  • 寄存器分配: 一些简单的对象可以直接存储在CPU的寄存器中,而不必分配在堆或栈上。
  • 常量池中的分配: 字符串常量和基本类型的常量(如intfloat等)可以在常量池中分配内存。
  • 线程本地分配缓冲区(TLAB): 为了提高多线程环境下的对象分配效率,JVM会为每个线程预先分配一块小的内存空间,称为线程本地分配缓冲区。

8)Java对象创建过程

Java对象的创建过程主要包括以下几个步骤:

  1. 类加载: 当我们第一次使用某个类时,Java虚拟机会加载并初始化该类。
  2. 内存分配: 一旦类被加载,JVM会在堆中分配内存给该对象。如果对象需要的内存大小在TLAB(线程本地分配缓冲区)中无法分配,则会在堆中进行分配。
  3. 初始化: 在分配内存后,JVM会对对象进行初始化,包括设置对象的默认值和调用构造方法。
  4. 构造方法执行: 构造方法会执行对象的初始化过程,初始化对象的各个字段。
  5. 对象引用: 最后,将对象的引用返回给调用方,调用方可以使用该引用来操作对象。

9)类的生命周期

类的生命周期包括以下几个阶段:

  1. 加载(Loading): 加载是指将类的字节码加载到内存中,并生成对应的Class对象的过程。加载阶段由类加载器完成,包括查找类的字节码文件、创建Class对象等。
  2. 链接(Linking): 链接阶段包括验证、准备和解析三个阶段:
    • 验证(Verification): 确保加载的字节码符合Java虚拟机规范,并且不会危害虚拟机的安全。
    • 准备(Preparation): 为类的静态变量分配内存,并设置默认初始值。
    • 解析(Resolution): 将类中的符号引用转换为直接引用。
  3. 初始化(Initialization): 初始化阶段是类加载的最后一步,它会执行类的初始化代码,包括静态变量赋值和静态代码块的执行。类的初始化是在必要时才进行的,例如当访问类的静态成员或调用静态方法时。
  4. 使用(Usage): 类初始化完成后,可以通过创建对象、访问静态成员等方式来使用类。
  5. 卸载(Unloading): 类卸载是指当类不再被引用且满足垃圾回收条件时,由垃圾回收器将其从内存中删除的过程。类的卸载是Java虚拟机的一个重要功能,可以避免内存泄漏和资源浪费。

10)简述Java的对象结构

Java的对象结构主要包括对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)三部分:

  • 对象头(Object Header): 对象头存储了对象的元数据信息,包括对象的哈希码、GC分代年龄、锁状态标志、线程持有的锁信息等。对象头的大小在不同的JVM实现中可能有所不同。
  • 实例数据(Instance Data): 实例数据存储了对象的各个字段的值,包括实例变量和从父类继承的变量。
  • 对齐填充(Padding): 对齐填充是为了保证对象在内存中的地址是8字节对齐的,以提高访问速度。对齐填充会在对象的实例数据和对象头之间插入一些无意义的填充数据,使得对象的大小为8字节的整数倍。

Java对象的结构在不同的JVM实现中可能有所不同,但通常都包括上述三部分。对象的大小取决于对象头的大小、实例数据的大小和对齐填充的大小。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 900+ Star,1.5W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

这篇关于面试 Java 基础八股文十问十答第二十四期的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Spring Security方法级安全控制@PreAuthorize注解的灵活运用小结

《SpringSecurity方法级安全控制@PreAuthorize注解的灵活运用小结》本文将带着大家讲解@PreAuthorize注解的核心原理、SpEL表达式机制,并通过的示例代码演示如... 目录1. 前言2. @PreAuthorize 注解简介3. @PreAuthorize 核心原理解析拦截与

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.