Java面向对象:对象内存图+成员与局部变量

🏠个人主页:黎雁

🎬作者简介:C/C++/JAVA后端开发学习者

❄️个人专栏:C语言数据结构(C语言)EasyXJAVA游戏规划程序人生

✨ 从来绝巘须孤往,万里同尘即玉京

文章目录

  • ✨Java面向对象精讲(三):对象内存图+成员与局部变量|吃透底层运行机制
    • [📌 文章摘要(247字)](#📌 文章摘要(247字))
      • [🕒 阅读时长:约16分钟](#🕒 阅读时长:约16分钟)
      • [✅ 适用人群 & 阅读重点](#✅ 适用人群 & 阅读重点)
    • [📖 知识回顾(课前必看,快速衔接)](#📖 知识回顾(课前必看,快速衔接))
    • [一、对象内存图 🗺️ 看透JVM底层运行逻辑(核心重点)](#一、对象内存图 🗺️ 看透JVM底层运行逻辑(核心重点))
    • [二、成员变量与局部变量 🆚 全方位区分(高频考点)](#二、成员变量与局部变量 🆚 全方位区分(高频考点))
      • [2.1 定义与核心概念(先明确,再区分)](#2.1 定义与核心概念(先明确,再区分))
        • [✔ 成员变量](#✔ 成员变量)
        • [✔ 局部变量](#✔ 局部变量)
      • [2.2 五大核心区别(对比表格,必背高频考点)](#2.2 五大核心区别(对比表格,必背高频考点))
      • [2.3 逐点拆解区别(结合实例,加深理解)](#2.3 逐点拆解区别(结合实例,加深理解))
        • [✔ 1. 初始化值差异(最易踩坑)](#✔ 1. 初始化值差异(最易踩坑))
        • 示例代码(初始化值差异)
        • [✔ 2. 内存位置与生命周期差异(底层核心)](#✔ 2. 内存位置与生命周期差异(底层核心))
        • [✔ 3. 作用域差异(代码使用范围)](#✔ 3. 作用域差异(代码使用范围))
        • 示例代码(作用域差异)
      • [2.4 高频易错点避坑指南(零失分必备)](#2.4 高频易错点避坑指南(零失分必备))
      • [2.5 实战案例(综合运用,巩固区别)](#2.5 实战案例(综合运用,巩固区别))
      • [2.6 成员与局部变量核心总结(必背)](#2.6 成员与局部变量核心总结(必背))
    • [✨ 核心知识点总结(精华提炼,查漏补缺)](#✨ 核心知识点总结(精华提炼,查漏补缺))
      • [✅ 对象内存图核心](#✅ 对象内存图核心)
      • [✅ 成员与局部变量核心](#✅ 成员与局部变量核心)
    • [✍️ 写在最后](#✍️ 写在最后)

✨Java面向对象精讲(三):对象内存图+成员与局部变量|吃透底层运行机制

📌 文章摘要(247字)

本文是Java面向对象系列第三篇底层核心,承接上篇this关键字、构造方法与标准JavaBean知识,聚焦对象内存图、成员变量与局部变量区别两大核心考点,也是理解Java面向对象运行机制的关键。从JVM内存模型(栈、堆、方法区)入手,逐图拆解单对象、多对象、多引用指向同一对象的内存分布与运行逻辑,彻底讲清对象创建与使用的底层原理;通过对比表格+实例,全方位区分成员变量与局部变量的5大核心差异,搭配易错点避坑、底层逻辑解读与实战代码。内容由浅入深、图文结合,零基础能看懂底层,进阶者能夯实核心,学完可从"会写代码"升级为"懂底层运行",是突破面向对象瓶颈的必备内容。

🕒 阅读时长:约16分钟

✅ 适用人群 & 阅读重点

▫️ Java零基础入门者 :重点看对象内存图的基础逻辑、成员与局部变量的定义和使用区别,能通过内存图理解对象运行本质。

▫️ 在校学生/备考笔试者 :重点吃透内存图的运行步骤、成员与局部变量的区别表格,这些是笔试选择/简答高频考点,务必牢记。

▫️ 开发入门夯实基础者 :重点看多引用指向同一对象的内存逻辑、变量生命周期与作用域,避免开发中因变量使用不当导致的bug。

▫️ 初学面向对象迷茫者 :重点看内存图的逐步解析、代码与内存的对应关系,打通"代码语法-底层运行"的逻辑闭环。

▫️ 复习巩固者:直接看「知识回顾+核心总结」,快速梳理底层原理与变量差异,强化记忆易混点。


📖 知识回顾(课前必看,快速衔接)

在上一篇内容中,我们掌握了Java面向对象的进阶语法:理解了this关键字的本质与用法,能区分同名的成员变量和局部变量;学会了构造方法的定义、重载与使用,实现对象创建时的高效初始化;掌握了标准JavaBean类的企业级规范,能编写符合团队开发要求的实体类。

但很多同学只停留在"会写代码"的层面,却不懂"代码为什么这么运行":创建对象时JVM在内存中做了什么?多个对象之间为何互不影响?成员变量和局部变量的默认值、内存位置为何不同?本文将从底层内存视角拆解这些问题,帮你吃透面向对象的运行机制。


一、对象内存图 🗺️ 看透JVM底层运行逻辑(核心重点)

要理解Java面向对象的运行机制,必须先掌握JVM的三大核心内存区域,这是对象创建、方法调用、变量存储的基础,所有Java代码的运行都围绕这三大区域展开。

1.1 JVM三大核心内存区域(必懂,底层基石)

✔ 栈内存(Stack)
  • 作用:存储局部变量 (方法内的变量、方法形参、main方法中的对象引用变量)、方法栈帧(方法调用时创建,方法执行完毕后销毁)。
  • 特点:先进后出(FILO),空间小、访问速度快,随方法进栈而存在,出栈而释放,无需手动管理内存。
✔ 堆内存(Heap)
  • 作用:存储对象本身(包括对象的成员变量)、数组对象。
  • 特点:空间大、访问速度较慢,对象由new关键字创建,在堆中开辟独立空间,每个对象有唯一地址;对象的销毁由Java垃圾回收机制(GC)自动管理,无需手动释放。
✔ 方法区(Method Area)
  • 作用:存储类的字节码文件(.class) 、常量(如字符串常量)、静态变量(后续讲解)、成员方法的字节码。
  • 特点:类加载时,字节码文件被加载到方法区,全局共享,一个类的字节码仅加载一次,供所有对象复用。

1.2 单对象内存图(基础案例,逐步拆解)

Student类为例,拆解Student s = new Student();创建对象、赋值、调用方法的完整内存运行步骤,这是理解所有内存图的基础。

示例代码
java 复制代码
// JavaBean类
public class Student {
    String name; // 成员变量
    int age;

    public void study() {
        System.out.println("好好学习");
    }
}

// 测试类
public class StudentTest {
    public static void main(String[] args) {
        Student s = new Student(); // 创建对象
        System.out.println(s); // 输出对象地址
        System.out.println(s.name + "..." + s.age); // 输出默认值

        s.name = "阿强"; // 给成员变量赋值
        s.age = 23;
        System.out.println(s.name + "..." + s.age); // 输出赋值后的值
        s.study(); // 调用成员方法
    }
}
内存运行逐步解析(核心重点,必懂)
  1. 加载类字节码 :程序启动后,JVM先将Student.classStudentTest.class的字节码文件加载到方法区 ,存储Student类的成员变量(name、age)和成员方法(study())字节码,以及main方法字节码。
  2. 执行main方法 :JVM在栈内存 创建main方法的栈帧,开始执行main方法内的代码。
  3. 创建对象引用变量 :执行Student s,在main方法栈帧中声明局部变量s,此时s未赋值,暂存默认值null
  4. 堆中开辟对象空间 :执行new Student(),JVM在堆内存 开辟一块独立空间,分配唯一地址(如0x00000012),并对对象的成员变量进行默认初始化 (name为null,age为0)。
  5. 绑定对象地址 :将堆中对象的地址0x00000012赋值给栈中的引用变量s,此时s指向堆中的Student对象。
  6. 取值与赋值
    • 取值时,通过s存储的地址找到堆中对象,获取成员变量的默认值(null...0);
    • 赋值时,通过地址找到对象,将name="阿强"age=23写入堆中成员变量,覆盖默认值。
  7. 调用成员方法 :执行s.study(),通过s的地址找到堆中对象,再根据对象存储的方法引用,去方法区调用study()方法,在栈中创建study方法栈帧,执行方法体(输出"好好学习"),方法执行完毕后栈帧销毁。
单对象内存图简化示意
复制代码
栈内存(Stack)
┌─────────────────────────────────────────────┐
│ study方法栈帧(执行完毕后销毁)              │
│ System.out.println("好好学习");              │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ main方法栈帧                                │
│ s.study(); // 调用方法,创建study栈帧        │
│ System.out.println("阿强...23");             │
│ s.age = 23; // 通过地址赋值                  │
│ s.name = "阿强"; // 通过地址赋值             │
│ System.out.println("null...0");             │
│ System.out.println(s); // 输出0x00000012    │
│ Student s = 0x00000012; // 引用变量指向对象 │
└─────────────────────────────────────────────┘

堆内存(Heap)
┌─────────────────────────────────────────────┐
│ new Student() 地址:0x00000012              │
│ 成员变量:name = "阿强"(赋值后)            │
│          age = 23(赋值后)                 │
│ 方法引用:study() → 指向方法区对应字节码     │
└─────────────────────────────────────────────┘

方法区(Method Area)
┌─────────────────────────────────────────────┐
│ 存储 Student.class、StudentTest.class字节码 │
│ Student类:成员变量(name、age)             │
│          成员方法(study()字节码)           │
│ StudentTest类:main()方法字节码              │
│ 常量池:"阿强"、"好好学习"等字符串常量       │
└─────────────────────────────────────────────┘

1.3 多对象内存图(核心特性,互不影响)

当创建多个对象时,每个对象在堆中拥有独立空间,成员变量独立存储,互不干扰,这是对象的核心特性。以下通过两个Student对象案例拆解内存逻辑。

示例代码
java 复制代码
public class StudentTest2 {
    public static void main(String[] args) {
        // 创建第一个对象
        Student s1 = new Student();
        s1.name = "阿强";
        s1.age = 23;
        s1.study();

        // 创建第二个对象
        Student s2 = new Student();
        s2.name = "阿珍";
        s2.age = 24;
        s2.study();
    }
}
多对象内存核心逻辑
  1. 类字节码仅加载一次:创建s2时,Student.class已在方法区加载,无需重复加载,直接复用。
  2. 堆中独立空间:new Student()创建s2时,JVM在堆中开辟另一块独立空间(地址如0x00000024),成员变量默认初始化后,赋值为name="阿珍"age=24,与s1的空间互不干扰。
  3. 栈中独立引用:s1s2是栈中两个独立的局部变量,分别存储各自对象的地址,修改s1的成员变量不会影响s2
  4. 方法共享复用:两个对象调用study()方法时,均指向方法区的同一study()字节码,在栈中分别创建独立的方法栈帧,执行完毕后销毁,方法本身不会被复制。
多对象内存图简化示意
复制代码
栈内存(Stack)
┌─────────────────────────────────────────────┐
│ study方法栈帧(s2调用,执行后销毁)          │
│ System.out.println("好好学习");              │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ main方法栈帧                                │
│ s2.study();                                 │
│ s2.age = 24;                                │
│ s2.name = "阿珍";                           │
│ Student s2 = 0x00000024;                    │
│ s1.study();                                 │
│ s1.age = 23;                                │
│ s1.name = "阿强";                           │
│ Student s1 = 0x00000012;                    │
└─────────────────────────────────────────────┘

堆内存(Heap)
┌─────────────────────────────────────────────┐
│ new Student() 地址:0x00000024(s2指向)    │
│ name = "阿珍",age = 24                      │
│ study() → 指向方法区                         │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ new Student() 地址:0x00000012(s1指向)    │
│ name = "阿强",age = 23                      │
│ study() → 指向方法区                         │
└─────────────────────────────────────────────┘

方法区(Method Area)
┌─────────────────────────────────────────────┐
│ Student.class、StudentTest2.class字节码      │
│ Student类:name、age成员变量,study()方法    │
│ 常量池:"阿强"、"阿珍"、"好好学习"           │
└─────────────────────────────────────────────┘

1.4 多引用指向同一对象(特殊场景,核心易错点)

当多个引用变量指向同一个堆对象时,所有引用操作的是同一个对象的成员变量,修改其中一个引用的属性,会影响所有引用的取值,这是笔试高频易错点。

示例代码
java 复制代码
public class StudentTest3 {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.name = "阿强"; // 给stu1指向的对象赋值
        Student stu2 = stu1; // stu2指向stu1对应的对象
        stu2.name = "阿珍"; // 通过stu2修改对象属性

        // 输出结果:两个引用的name均为"阿珍"
        System.out.println(stu1.name + "..." + stu2.name);

        stu1 = null; // stu1不再指向任何对象
        stu2 = null; // stu2不再指向任何对象,对象成为垃圾,等待GC回收
    }
}
核心内存逻辑
  1. 赋值引用:stu2 = stu1表示将stu1存储的对象地址(如0x00000012)赋值给stu2,此时stu1stu2同时指向堆中同一个Student对象,栈中两个引用,堆中一个对象。
  2. 属性共享:通过stu2.name = "阿珍"修改的是堆中对象的namestu1指向同一个对象,因此取值时stu1.name也为"阿珍"。
  3. 引用置空:stu1 = null表示stu1不再指向任何堆对象,stu2 = null后,堆中对象无任何引用指向,成为垃圾对象,后续由Java垃圾回收机制自动清理,释放堆内存。
多引用内存图简化示意
复制代码
栈内存(Stack)
┌─────────────────────────────────────────────┐
│ main方法栈帧                                │
│ stu2 = null; // 置空,不再指向对象           │
│ stu1 = null; // 置空,不再指向对象           │
│ System.out.println("阿珍...阿珍");           │
│ stu2.name = "阿珍"; // 修改同一对象属性      │
│ Student stu2 = 0x00000012; // 指向stu1的对象│
│ stu1.name = "阿强"; // 给对象赋值            │
│ Student stu1 = 0x00000012;                  │
└─────────────────────────────────────────────┘

堆内存(Heap)
┌─────────────────────────────────────────────┐
│ new Student() 地址:0x00000012              │
│ name = "阿珍"(被stu2修改后)                │
│ age = 0(默认值)                            │
│ 无引用指向后,成为垃圾对象,等待GC回收       │
└─────────────────────────────────────────────┘

方法区(Method Area)
┌─────────────────────────────────────────────┐
│ StudentTest3.class、Student.class字节码      │
│ 常量池:"阿强"、"阿珍"                       │
└─────────────────────────────────────────────┘

1.5 对象内存图核心总结(必背,底层基石)

  1. 类加载:.class字节码仅加载一次到方法区,供所有对象复用,无需重复加载。
  2. 对象存储:对象本身及成员变量在堆中,每个对象有独立空间,引用变量在栈中存储对象地址。
  3. 方法调用:成员方法字节码在方法区,调用时在栈中创建方法栈帧,执行完毕后栈帧销毁,方法共享复用。
  4. 多引用特性:多个引用指向同一对象时,操作的是同一个堆对象,属性修改相互影响;引用置空后,对象无引用则成为垃圾,等待GC回收。
  5. 核心原则:栈存引用/局部变量,堆存对象/成员变量,方法区存类信息/常量,三者协同完成代码运行。

二、成员变量与局部变量 🆚 全方位区分(高频考点)

成员变量与局部变量是Java中最基础的两种变量类型,两者在定义位置、内存存储、初始化值等方面差异显著,也是笔试面试的高频考点,必须全方位区分,避免使用错误。

2.1 定义与核心概念(先明确,再区分)

✔ 成员变量
  • 定义位置:类中、方法外,属于对象的属性,是类的成员之一。
  • 分类:普通成员变量(无static修饰,属于对象)、静态成员变量(有static修饰,属于类,后续讲解),本文重点讲普通成员变量。
  • 示例:Student类中的nameage变量。
✔ 局部变量
  • 定义位置:方法内、方法形参上、代码块内,属于方法的临时变量。
  • 分类:方法内变量、方法形参、代码块变量(如for循环中的变量)。
  • 示例:main方法中的sstudy方法内的临时变量、setXxx方法的形参。

2.2 五大核心区别(对比表格,必背高频考点)

区别维度 成员变量(类中方法外) 局部变量(方法内/形参)
类中位置不同 类中,方法外 方法内、方法形参、代码块内
初始化值不同 有默认初始化值(与数组默认值一致) 无默认值,使用前必须手动赋值,否则编译报错
内存位置不同 堆内存的对象中(随对象存储) 栈内存的方法栈帧中(随方法存储)
生命周期不同 随对象创建而存在,随对象销毁而消失 随方法进栈而存在,随方法出栈而消失
作用域范围 整个类中有效(所有成员方法均可访问) 仅在当前方法/代码块中有效,超出范围不可访问

2.3 逐点拆解区别(结合实例,加深理解)

✔ 1. 初始化值差异(最易踩坑)
  • 成员变量:有默认初始化值,JVM自动赋值,无需手动初始化即可使用:
    • 整数型(byte/short/int/long):0;
    • 小数型(float/double):0.0;
    • 布尔型(boolean):false;
    • 字符型(char):\u0000(空字符);
    • 引用类型(String/对象):null。
  • 局部变量:无默认值,必须手动赋值后才能使用,否则编译器直接报错,这是最常见的易错点。
示例代码(初始化值差异)
java 复制代码
public class VariableTest {
    // 成员变量,有默认值
    int num1;
    String str1;

    public void method() {
        // 局部变量,无默认值,必须赋值才能使用
        int num2;
        // System.out.println(num2); // 编译报错:变量未初始化
        num2 = 10; // 手动赋值后可使用
        System.out.println(num2);

        // 成员变量可直接使用(默认值)
        System.out.println(num1); // 输出:0
        System.out.println(str1); // 输出:null
    }
}
✔ 2. 内存位置与生命周期差异(底层核心)
  • 成员变量:存储在堆内存的对象中,生命周期与对象一致:
    • 对象创建(new)→ 成员变量在堆中分配空间,赋值;
    • 对象被GC回收→ 成员变量随对象一起销毁,堆内存释放。
  • 局部变量:存储在栈内存的方法栈帧中,生命周期与方法一致:
    • 方法调用→ 栈帧创建,局部变量分配空间,赋值;
    • 方法执行完毕→ 栈帧销毁,局部变量随之消失,栈内存释放。
✔ 3. 作用域差异(代码使用范围)
  • 成员变量:作用域覆盖整个类,类中的所有成员方法均可直接访问(无需传递)。
  • 局部变量:作用域仅限定义它的方法/代码块,超出范围后,变量不可见,无法访问。
示例代码(作用域差异)
java 复制代码
public class VariableTest2 {
    // 成员变量,整个类有效
    String name = "阿强";

    public void method1() {
        // 访问成员变量
        System.out.println(name);
        // 局部变量,仅method1有效
        int num = 10;
        System.out.println(num);
    }

    public void method2() {
        // 访问成员变量
        System.out.println(name);
        // System.out.println(num); // 编译报错:num未定义(超出作用域)
    }
}

2.4 高频易错点避坑指南(零失分必备)

  1. ❌ 错误:使用局部变量前未赋值,直接打印或运算;
    ✅ 正确:局部变量必须手动赋值后才能使用,无默认值。
  2. ❌ 错误:成员变量与局部变量同名时,未用this关键字区分,导致访问错误;
    ✅ 正确:同名时,局部变量优先,需用this.成员变量访问成员变量。
  3. ❌ 错误:认为局部变量也有默认值,或成员变量必须手动初始化;
    ✅ 正确:成员变量有默认值,局部变量无,这是两者的核心差异之一。
  4. ❌ 错误:在一个方法中访问另一个方法的局部变量;
    ✅ 正确:局部变量作用域仅限自身方法,无法跨方法访问。
  5. ❌ 错误:对象被置空后,仍试图访问其成员变量;
    ✅ 正确:对象置空(s = null)后,引用不再指向堆对象,访问成员变量会报空指针异常(NullPointerException)。

2.5 实战案例(综合运用,巩固区别)

java 复制代码
public class VariablePractice {
    // 成员变量
    private String username;
    private int age;

    // 带参构造(形参是局部变量)
    public VariablePractice(String username, int age) {
        // 同名时,this区分成员变量与局部变量
        this.username = username;
        this.age = age;
    }

    public void showInfo() {
        // 局部变量,必须赋值
        String info = "用户信息:";
        // 访问成员变量
        System.out.println(info + username + ",年龄:" + age);
    }

    public static void main(String[] args) {
        // 创建对象,调用带参构造
        VariablePractice vp = new VariablePractice("张三", 20);
        vp.showInfo();

        // 局部变量,未赋值不能使用
        // int num;
        // System.out.println(num); // 编译报错
    }
}

✅ 运行结果:用户信息:张三,年龄:20,代码正确区分成员变量与局部变量,无报错,符合规范。

2.6 成员与局部变量核心总结(必背)

  1. 核心区分:类中位置决定变量类型,进而影响内存位置、初始化值、生命周期与作用域;
  2. 初始化值:成员变量有默认值,局部变量无,必须手动赋值;
  3. 内存与生命周期:成员变量在堆(随对象),局部变量在栈(随方法);
  4. 同名处理:局部变量优先,用this关键字区分成员变量;
  5. 核心原则:按需定义变量,成员变量存储对象属性,局部变量存储方法临时数据。

✨ 核心知识点总结(精华提炼,查漏补缺)

✅ 对象内存图核心

  1. 三大内存区域:栈(引用/局部变量/方法栈帧)、堆(对象/成员变量)、方法区(类字节码/常量);
  2. 单对象:new创建堆空间,栈引用存地址,方法区存类信息,协同运行;
  3. 多对象:堆中独立空间,成员变量互不干扰,方法共享复用;
  4. 多引用:指向同一对象时,属性修改相互影响,无引用则对象成为垃圾。

✅ 成员与局部变量核心

  1. 定义位置:成员变量(类中方法外),局部变量(方法内/形参);
  2. 五大区别:位置、初始化值、内存、生命周期、作用域(必背表格);
  3. 易错点:局部变量需手动赋值,同名用this区分,跨方法不可访问局部变量。

✍️ 写在最后

本文是Java面向对象的底层核心内容,也是从"会用"到"懂原理"的关键一步。对象内存图揭示了Java代码运行的底层逻辑,帮你理解"为什么创建对象要new""为什么多引用指向同一对象会相互影响";成员变量与局部变量的区别则是编码的基础,避免因变量使用不当导致的编译报错或逻辑bug。

很多同学觉得底层内容抽象、难理解,这是正常的。内存图的学习,不在于死记硬背图示,而在于理解"栈-堆-方法区"的协同逻辑,多结合代码一步步拆解内存变化,慢慢就能建立起底层思维。而变量的区别,只需牢记对比表格,再通过多写代码强化记忆,就能轻松掌握。

至此,Java面向对象的核心基础内容(类与对象、封装、this、构造方法、标准JavaBean、内存图、变量区别)已全部讲解完毕。这些内容是Java后续学习(继承、多态、接口、框架)的根基,必须扎实掌握,才能在进阶学习中得心应手。

下一篇我们会带来面向对象的综合实战练习,通过经典案例串联所有知识点,帮你巩固所学、查漏补缺,将理论转化为实战能力,敬请关注~

希望本文能帮你吃透面向对象的底层机制,区分核心变量类型。如果觉得内容对你有帮助,欢迎点赞+收藏+关注 ✨,你的支持是我持续更新的最大动力!

Java学习,底层为王。愿你在理解底层的路上,夯实基础,突破瓶颈,稳步走向进阶!💪


预告:Java面向对象精讲(四)

面向对象综合实战练习(经典案例+代码实现+思路拆解) + 全系列知识点汇总梳理 + 笔试高频考点总结,帮你串联所有内容,强化实战能力~

相关推荐
窗边鸟2 小时前
小白日记之java方法(java复习)
java·学习
sunfove2 小时前
实战篇:用 Python 徒手实现模拟退火算法解决 TSP 问题
开发语言·python·模拟退火算法
jiunian_cn2 小时前
【C++】IO流
开发语言·c++
砚边数影2 小时前
AI数学基础(一):线性代数核心,向量/矩阵运算的Java实现
java·数据库·人工智能·线性代数·矩阵·ai编程·金仓数据库
froginwe112 小时前
C 语言输入与输出详解
开发语言
_童年的回忆_3 小时前
【PHP】关于守护进程报错:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
开发语言·oracle·php
少林码僧3 小时前
2.30 传统行业预测神器:为什么GBDT系列算法在企业中最受欢迎
开发语言·人工智能·算法·机器学习·ai·数据分析
豆沙沙包?3 小时前
2026年--Lc343-1926. 迷宫中离入口最近的出口(图 - 广度优先搜索)--java版
java·算法·宽度优先