Java大学问——优雅地处理异常

java.lang.NullPointerException出现的几种原因及解决方案 java.lang.NullPointerException(空指针异常)是Java开发中常见错误,多因对null对象执行操作所致。常见原因包括:调用null对象的方法或属性、将null作为数组访问、null参与自动拆箱、集合未初始化就操作等。 解决方案涵盖:调用前判空(如if语句、Objects.requireNonNull)、初始化对象与集合、使用Optional类规避风险、借助IDE调试定位null源头等。掌握其成因与解决办法,能有效提升代码健壮性,减少程序崩溃隐患,是Java开发者必备技能。 阅读详情

一.前言

你有没有这样的印象,当你想要更新一款 APP 的时候,它的更新日志里总有这么一两句描述:

  • 修复若干 bug
  • 杀了某程序员祭天,并成功解决掉他遗留的 bug

作为一名负责任的程序员,我们当然希望程序不会出现 bug,因为 bug 出现的越多,间接地证明了我们的编程能力越差,至少领导是这么看的。

事实上,领导是不会拿自己的脑袋宣言的:“我们的程序绝不存在任何一个 bug。”但当程序出现 bug 的时候,领导会毫不犹豫地选择让程序员背锅。

为了让自己少背锅,我们可以这样做:

  • 在编码阶段合理使用异常处理机制,并记录日志以备后续分析
  • 在测试阶段进行大量有效的测试,在用户发现错误之前发现错误

还有一点需要做的是,在敲代码之前,学习必要的编程常识,做到兵马未动,粮草先行。

二.层次结构

在 Java 中,异常(Throwable)的层次结构大致如下。

Java大学问——优雅地处理异常

Error 类异常描述了 Java 运行时系统的内部错误,比如最常见的 OutOfMemoryError和NoClassDefFoundError。

导致OutOfMemoryError的常见原因有以下几种:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
  • 集合中的对象引用在使用完后未清空,使得 JVM 不能回收;
  • 代码中存在死循环或循环产生过多重复的对象;
  • 启动参数中内存的设定值过小;

OutOfMemoryError的解决办法需要视情况而定,但问题的根源在于程序的设计不够合理,需要通过一些性能检测才能找得出引发问题的根源。

导致NoClassDefFoundError的原因只有一个,Java 虚拟机在编译时能找到类,而在运行时却找不到。

Java大学问——优雅地处理异常

NoClassDefFoundError 的解决办法,我截了一张图,如上所示。当一个项目引用了另外一个项目时,切记这一步!

Exception(例外)通常可分为两类,一类是写代码的人造成的,比如访问空指针(NullPointerException)。应当在敲代码的时候进行检查,以杜绝这类异常的发生。

if (str == null || "".eqauls(str)) {
}

另外一类异常不是写代码的人造成的,要么需要抛出,要么需要捕获,比如说常见的 IOException。

抛出的示例。

public static void main(String[] args) throws IOException {
    InputStream is = new FileInputStream("Java高级架构狮.txt");
    int b;
    while ((b = is.read()) != -1) {

    }
}

捕获的示例。

public static void main(String[] args) {
    try {
        InputStream is = new FileInputStream("Java高级架构狮.txt");
        int b;
        while((b = is.read()) != -1) {

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

三.finally

当抛出异常的时候,剩余的代码就会终止执行,这时候一些资源就需要主动回收。Java 的解决方案就是finally子句——不管异常有没有被捕获,finally 子句里的代码都会执行。

在下面的示例当中,输入流将会被关闭,以释放资源。

public static void main(String[] args) {
    InputStream is = null;
    try {
        is = new FileInputStream("Java高级架构狮.txt");
        int b;
        while ((b = is.read()) != -1) {}
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        is.close();
    }
}

但我总觉得这样的设计有点问题,因为close()方法同样会抛出 IOException:

public void close() throws IOException {}

也就是说,调用close()的main方法要么需要抛出IOException,要么需要在finally子句里重新捕获IOException。

选择前一种就会让 try catch 略显尴尬,就像下面这样。

public static void main(String[] args) throws IOException {
    InputStream is = null;
    try {
        is = new FileInputStream("Java高级架构狮.txt");
        int b;
        while ((b = is.read()) != -1) {}
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        is.close();
    }
}

选择后一种会让代码看起来很臃肿,就像下面这样。

public static void main(String[] args) {
    InputStream is = null;
    try {
        is = new FileInputStream("Java高级架构狮.txt");
        int b;
        while ((b = is.read()) != -1) {}
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总之,我们需要另外一种更优雅的解决方案。JDK7 新增了Try-With-Resource语法:如果一个类(比如InputStream)实现了 AutoCloseable接口,那么就可以将该类的对象创建在 try 关键字后面的括号中,当try-catch代码块执行完毕后,Java 会确保该对象的 close方法被调用。示例如下。

public static void main(String[] args) {
    try (InputStream is = new FileInputStream("Java高级架构狮.txt")) {
        int b;
        while ((b = is.read()) != -1) {
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

四.建议

关于异常处理机制的使用,我这里总结了一些非常实用的建议,希望你能够采纳。

1.尽量捕获原始的异常。

实际应该捕获 FileNotFoundException,却捕获了泛化的 Exception。示例如下。

InputStream is = null;
try {
    is = new FileInputStream("Java高级架构狮.txt");
}
catch (Exception e) {
    e.printStackTrace();
}

这样做的坏处显而易见:假如你喊“王二”,那么我就敢答应;假如你喊“老王”,那么我还真不敢答应,万一你喊的我妹妹“王三”呢?

很多初学者误以为捕获泛化的Exception更省事,但也更容易让人“丈二和尚摸不着头脑”。相反,捕获原始的异常能够让协作者更轻松地辨识异常类型,更容易找出问题的根源。

2.尽量不要打印堆栈后再抛出异常

当异常发生时打印它,然后重新抛出它,以便调用者能够适当地处理它。就像下面这段代码一样。

public static void main(String[] args) throws IOException {
    try (InputStream is = new FileInputStream("Java高级架构狮.txt")) {
    }catch (IOException e) {
        e.printStackTrace();
        throw e;
    } 
}

这似乎考虑得很周全,但是这样做的坏处是调用者可能也打印了异常,重复的打印信息会增添排查问题的难度。

java.io.FileNotFoundException: Java高级架构狮.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at learning.Test.main(Test.java:10)
Exception in thread "main" java.io.FileNotFoundException: Java高级架构狮.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at learning.Test.main(Test.java:10)

3.千万不要用异常处理机制代替判断

我曾见过类似下面这样奇葩的代码,本来应该判 null 的,结果使用了异常处理机制来代替。

public static void main(String[] args) {
    try {
        String str = null;
        String[] strs = str.split(",");
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

捕获异常相对判断花费的时间要多得多!我们可以模拟两个代码片段来对比一下。

代码片段 A:

long a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
    try {
        String str = null;
        String[] strs = str.split(",");
    } catch (NullPointerException e) {
    }
}
long b = System.currentTimeMillis();
System.out.println(b - a);

代码片段 B:

long a = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
    String str = null;
    if (str != null) {
        String[] strs = str.split(",");
    }
}
long b = System.currentTimeMillis();
System.out.println(b - a);

100000 万次的循环,代码片段 A(异常处理机制)执行的时间大概需要 1983 毫秒;代码片段 B(正常判断)执行的时间大概只需要 1 毫秒。这样的比较虽然不够精确,但足以说明问题。

4.不要盲目地过早捕获异常

如果盲目地过早捕获异常的话,通常会导致更严重的错误和其他异常。请看下面的例子。

InputStream is = null;
try {
    is = new FileInputStream("Java高级架构狮.txt");

} catch (FileNotFoundException e) {
    e.printStackTrace();
}

int b;
try {
    while ((b = is.read()) != -1) {
    }
} catch (IOException e) {
    e.printStackTrace();
}

finally {
    try {
        is.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

假如文件没有找到的话,InputStream的对象引用is就为null,新的NullPointerException就会出现。

java.io.FileNotFoundException: Java高级架构狮.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at learning.Test.main(Test.java:12)
Exception in thread "main" java.lang.NullPointerException
    at learning.Test.main(Test.java:28)

NullPointerException 并不是程序出现问题的本因,但实际上它出现了,无形当中干扰了我们的视线。正确的做法是延迟捕获异常,让程序在第一个异常捕获后就终止执行。

五.总结

好了,关于异常我们就说到这。异常处理是程序开发中必不可少的操作之一,但如何正确优雅地对异常进行处理却是一门学问,好的异常处理机制可以确保程序的健壮性,提高系统的可用率。

从Session到JWT:Web认证技术演进与Spring Boot实战迁移指南 身份认证是Web应用安全架构的核心基础,其本质是在客户端与服务器之间建立可信的身份声明机制。传统基于Session的认证采用中心化状态管理,服务器存储会话数据并通过Cookie传递Session ID,虽保障了安全,但在微服务与分布式架构下面临扩展性瓶颈和状态同步难题。Token-Based Authentication应运而生,通过密码学签名将认证信息编码成自包含令牌,实现了去中心化的无状态验证,使服务器集群获得天然的水平扩展能力。JWT作为该领域的开放标准,以其标准化的三段式结构和自包含声明,广泛应用于 阅读详情

相关推荐

Android TextView深度解析:从基础设置到高级适配与性能优化

在Android应用开发中,UI组件的正确使用是构建良好用户体验的基础。TextView作为最核心的文本显示控件,其内容、字体大小、颜色和背景的设置看似简单,实则涉及移动端开发的多个关键技术领域。理解其工作原理,需要掌握Android资源系统、屏幕适配机制和渲染性能优化等核心概念。通过资源化管理和主题化设计,开发者可以实现文本的国际化支持、深色主题适配以及动态样式切换,这对提升应用的可维护性和用户体验至关重要。在实际工程实践中,合理运用**sp与dp单位**进行字体适配,以及通过**ColorStateLi

436

极光java sdk_极光使用服务端使用java sdk 出现异常 日志如下

服务器已经开启了443端口 ,并且开通了ip 白名单, 但是 使用java jpush sdk 报错```cn.jiguang.common.resp.APIConnectionException: Connection IO error.Can not connect to JPush Server. Please ensure your internet connection is o...

weixin_42138545的博客 820

Android保险理赔App实战:从离线暂存到图片上传全解析

在移动端业务型应用开发中,保险理赔类App因涉及复杂表单、多文件上传、弱网容错等场景,成为检验Android工程师综合能力的试金石。本文从基础概念出发,讲解如何利用Kotlin协程处理异步任务,以MVVM架构结合Room数据库实现草稿离线暂存,通过CameraX与Compressor解决拍照旋转与图片压缩难题,并梳理提交理赔时的状态机流转与失败重试机制。同时探讨Android 14权限变更、分区存储适配等工程实践要点,帮助开发者构建稳定可靠的理赔流程。这类技术方案不仅适用于保险行业,同样可复用到银行、政务、

weixin_30768881的博客 322

Java程序员如何优雅编程

导读本文结合作者经验提出了一些编程的建议,这些建议旨在告诉读者如何更好的构造代码以便于它们能更好的工作,也便于将来对代码进行修改和改善的时候有一个参考。甚至,程序也会因此变得更加令人愉悦,更加优雅。01前言在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!编程不仅是一项单纯的技能,更是一个充...

架构师小秘圈 416

AIOps智能运维:从数据治理到故障自愈的实践指南

AIOps(智能运维)通过融合人工智能与运维管理,构建了感知-决策-执行的闭环体系。其核心技术包括多维度数据采集、机器学习算法和自动化执行,显著提升了告警治理、故障定位和容量预测的效率。在数据层,全量性、实时性的数据采集是基础,而算法层的异常检测和根因分析则依赖统计方法、孤立森林和LSTM等模型。AIOps尤其适用于处理告警风暴和复杂系统故障,如在电商大促中通过K-Means聚类减少92%的告警量。随着云原生和边缘计算的普及,AIOps正逐步实现与Service Mesh、Serverless等技术的深度集

weixin_30175731的博客 288

ARS408毫米波雷达数据解析避坑指南:从硬件连接到Python处理

本文提供了ARS408毫米波雷达从硬件连接到Python数据处理的完整实战指南。针对串口通信不稳定、数据解析错误等常见问题,详细解析了硬件连接方案选择、串口数据高效读取策略、二进制协议解析的位操作技巧,并给出了坐标转换、目标跟踪及实时可视化的代码实现,帮助开发者快速搭建稳定的雷达数据处理流水线。

weixin_29091105的博客 149

Java异常处理:优雅应对错误,保障程序稳健运行

异常处理是编写健壮和可靠代码的重要方面。通过适当的异常处理,我们可以保护代码免受意外情况的影响,并提供有用的错误信息和调试信息。同时,合理的异常处理策略和最佳实践可以提高代码的可读性、可维护性和可测试性。在编写Java代码时,不要忽视异常处理,让你的代码更加健壮和可靠。

weixin_43885959的博客 443

中科蓝讯(第一次使用指南)

中科蓝讯 新手指南

qq_48579018的博客 1万+

java.lang.NullPointerException出现的几种原因以及解决

java.lang.NullPointerException出现的几种原因: 1、字符串变量未初始化 2、接口类型的对象没有用具体的类初始化,比如: Map map // 会报错 Map map = new Map(); //则不会报错了 3、当一个对象的值为空时,你没有判断为空的情况。 4、字符串与文字的比较,文字可以是一个字符串或Enum的元素,如下会出现异常 String str...

宜春 96万+

Python3.11安装fairseq避坑指南:解决dataclasses兼容性问题(附详细代码修改)

本文详细解析了在Python 3.11环境下安装Fairseq时因dataclasses模块规则变更导致的安装失败问题。通过定位核心配置文件,将`default=SomeConfig()`修改为`default_factory=SomeConfig`,并调整依赖版本,提供了从源码修改到环境验证的完整解决方案,确保Fairseq顺利运行。

weixin_29098367的博客 495

纳米尺度仿真软件:GROMACS_(3).分子动力学模拟原理

分子动力学(MD)模拟是一种强大的计算方法,通过数值积分牛顿运动方程,追踪粒子在时间上的位置和速度变化,提供关于体系动力学行为的详细信息。选择合适的力场、设置初始条件、应用边界条件、控制温度和压力、选择合适的时间步长、计算能量和力,是 MD 模拟的关键步骤。通过这些步骤,可以对各种化学、生物和材料体系进行模拟和分析,揭示其结构、动力学和热力学性质。高级应用如反应路径模拟和蛋白质折叠研究,进一步扩展了 MD 模拟的应用范围。

kkchenjj的博客 1100

Java大学问——优雅地处理异常,字节跳动Java研发岗这些知识点内部泄露出来了

总之,我们需要另外一种更优雅的解决方案。JDK7 新增了语法:如果一个类(比如)实现了接口,那么就可以将该类的对象创建在 try 关键字后面的括号中,当try-catch代码块执行完毕后,Java 会确保该对象的 close方法被调用。示例如下。try (InputStream is = new FileInputStream(“Java高级架构狮.txt”)) {int b;= -1) {四.建议====

2301_78398209的博客 899

【51单片机实物】基于51单片机设计的简易直流电机调测速系统(可用在普中开发板)

功能任务描述:将设置的转速与当前测量的转速比较,得出差值用于控制DAC0832的输出电压,从而控制直流电机的转速,使转速逐渐达到设置转速。在LED上显示设置转速(左2位LED)和当前转速(右2位LED),转速显示采用十进制。控制过程中,当前转速显示不断变化。*直流电机转速范围0-96r/s,误差±1r/s

嵌入式阿齐Archie 1万+

未捕获异常string was not recognized_Java大学问——优雅地处理异常

一.前言你有没有这样的印象,当你想要更新一款 APP 的时候,它的更新日志里总有这么一两句描述:修复若干 bug杀了某程序员祭天,并成功解决掉他遗留的 bug作为一名负责任的程序员,我们当然希望程序不会出现 bug,因为 bug 出现的越多,间接地证明了我们的编程能力越差,至少领导是这么看的。事实上,领导是不会拿自己的脑袋宣言的:“我们的程序绝不存在任何一个 bug。”但当程序出现 bug 的时候...

weixin_39816448的博客 274

【软件系统架构】系列六:系统工程

系统工程是一种跨学科方法论,用于分析、设计、集成和管理复杂系统的全生命周期。其核心特点包括系统性思维、全周期管理、跨学科协作和需求导向。主流采用V模型生命周期,涵盖需求分析、系统设计、实现、测试验证及运维退役等阶段。核心工作方法包括需求工程、系统建模、接口设计、风险管理等。系统工程与项目管理协同,分别侧重技术实现和进度资源管理。应用领域覆盖航天军工、智能制造、智慧城市等。未来将向AI融合、数字孪生、模型驱动工程等方向发展,为复杂系统开发提供系统化协作范式。

moton2017的博客 2257

Lammps实现甲烷与水的竞争吸附-循环不同气体分子

Lammps实现甲烷与水的竞争吸附

Rockyoung 5375

别让异常毁掉你的代码!Java异常处理的“避坑指南”

更优雅的做法是精准捕获特定异常,针对性处理,同时搭配finally块释放资源,或者用Java 7的try-with-resources语法自动关闭流、连接等资源,省心又安全。非受检异常则是“突如其来的意外”,比如NullPointerException、ArrayIndexOutOfBoundsException,编译器不会提醒,但一旦触发,程序就会直接崩溃。异常处理的本质,不是“消灭异常”,而是“优雅地应对异常”。下次写代码时,别再对异常“视而不见”,用好这门“纠错艺术”,你的代码才能更健壮、更可靠。

2401_88815339的博客 412

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Scala集成OpenAI API:类型安全客户端的设计、实战与生产优化

在现代应用开发中,API客户端是连接服务与业务逻辑的关键组件,其核心价值在于提供类型安全、异步友好的交互方式,以提升开发效率与系统可靠性。通过将API的请求与响应建模为强类型数据结构,编译器能在编译期捕获大量潜在错误,而基于Future或IO等异步原语的封装,则能优雅地处理网络IO,避免阻塞。这种设计模式对于集成如OpenAI这类提供复杂AI能力(如聊天补全、图像生成、文本嵌入)的外部服务尤为重要,它能显著降低集成复杂度,让开发者更专注于业务创新。具体到Scala生态,一个优秀的客户端库会深度融入函数式编程

weixin_30376083的博客 432

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Spring Boot项目从零搭建实战:企业级开发规范与核心模块详解

Spring Boot作为Java领域主流的应用开发框架,其核心设计思想是“约定大于配置”,旨在简化基于Spring的应用初始搭建和开发过程。通过自动配置和起步依赖机制,开发者可以快速构建独立运行、生产就绪的应用程序,极大地提升了开发效率。这一特性在微服务架构和云原生环境中展现出极高的技术价值,使得快速构建可独立部署的服务单元成为可能。在实际应用场景中,一个结构清晰、配置规范的项目骨架是保障代码可维护性和团队协作效率的基础,涉及配置分层、数据库集成、API规范等核心要素。本文以构建一个包含用户管理模块的实战

weixin_34377919的博客 413

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Java List合并全解析:从addAll到并发场景的实战指南

在Java集合框架中,List作为最常用的数据结构之一,其合并操作是数据处理的基础。从原理上讲,合并操作涉及集合的扩容机制、元素复制策略以及内存管理。在技术价值层面,高效的合并方法能显著提升程序性能,尤其在处理大数据量时避免OOM(内存溢出)问题。应用场景广泛,包括数据聚合、缓存更新、配置合并等。本文聚焦于Java List合并,深入探讨了线程安全、数据一致性等核心问题,并对比了addAll、Stream API以及CopyOnWriteArrayList等不同方案的性能差异与适用场景,为高并发环境下的集合

weixin_30876945的博客 336

Dynamic-Datasource 实战指南:从配置到多数据源事务管理

本文详细介绍了Dynamic-Datasource在Spring Boot项目中的实战应用,涵盖从基础配置、多数据源分组到高级事务管理的完整流程。通过@DS注解实现无侵入式数据源切换,并深入探讨了本地多数据源事务与集成Seata分布式事务的解决方案,帮助开发者高效应对读写分离、多租户等复杂数据库场景。

441

Python自动化测试框架实战:从PO模式到CI/CD集成

自动化测试是现代软件工程中提升交付效率与质量的关键实践,其核心原理在于通过脚本模拟用户操作,实现重复性测试任务的自动执行。在技术选型上,Python凭借其简洁语法、丰富的库生态和强大的社区支持,成为自动化测试领域的首选语言,尤其适合快速构建和维护测试脚本。从技术价值看,一个设计良好的自动化框架能显著提升测试覆盖率、加快回归验证速度,并降低人为错误。在实际应用场景中,无论是Web UI、接口还是移动端测试,都需要结合具体工具链和设计模式。例如,Page Object (PO) 模式通过将页面元素与操作逻辑分离

weixin_33850015的博客 398

高可用的本质:故障时用户无感的工程实践体系

高可用(High Availability)是分布式系统保障业务连续性的核心能力,其本质并非追求零故障,而是通过可衡量的SLI/SLO指标、可设计的冗余与容错机制、可验证的混沌工程实践,实现故障发生时关键业务仍能稳定响应。它涵盖单点故障识别、主从/多活架构选型、熔断限流降级等关键技术路径,广泛应用于电商秒杀、金融支付、IoT边缘控制等对稳定性要求严苛的场景。本文结合真实系统演进案例,深入解析如何用布隆过滤器防缓存穿透、用Resilience4j实现智能熔断、用SLI驱动可观测闭环——让高可用从PPT指标落地

chuanjiaoye5017的博客 437

如何写出优雅、高效、逼格高的Java代码(代码优化、Java新特性、代码规范)

尽量多的收录了一些优雅、高效、逼格高的java代码 欢迎大家补充,共同学习进步~

Meteors.的博客 6766
上一篇: 微服务探索与实践—服务注册与发现
下一篇: JVM 与 Linux 的内存关系详解
大G哥
博客等级 码龄9年 5303粉丝 1408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值