每天一道面试题@第五天

1.包装类型的缓存机制了解么?

指部分包装类在创建对象时,会将一定范围内的对象缓存起来,当再次使用相同值创建对象时,优先从缓存中获取,而不是重新创建新对象。【提高性能】【节省内存】

列举几个常见的包装类缓存机制:

(1)Integer 类在 -128 到 127 这个范围内有缓存机制。当使用 Integer.valueOf(int) 方法创建 Integer 对象时,如果值在这个范围内,会直接从缓存中获取对象,否则会创建新对象。

Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b); // 输出 true,因为从缓存中获取的同一个对象Integer c = Integer.valueOf(200);
Integer d = Integer.valueOf(200);
System.out.println(c == d); // 输出 false,因为值不在缓存范围内,创建了新对象

(2)ByteShort 和 Long 类也有类似的缓存机制,缓存范围都是 -128 到 127

Byte byte1 = Byte.valueOf((byte) 10);
Byte byte2 = Byte.valueOf((byte) 10);
System.out.println(byte1 == byte2); // 输出 trueShort short1 = Short.valueOf((short) 100);
Short short2 = Short.valueOf((short) 100);
System.out.println(short1 == short2); // 输出 trueLong long1 = Long.valueOf(120L);
Long long2 = Long.valueOf(120L);
System.out.println(long1 == long2); // 输出 true

(3)Character 类会缓存从 \u0000 到 \u007F(即 0 到 127)的字符对象。

Character char1 = Character.valueOf('A');
Character char2 = Character.valueOf('A');
System.out.println(char1 == char2); // 输出 true

(4)Boolean 类会缓存 true 和 false 两个对象。

Boolean bool1 = Boolean.valueOf(true);
Boolean bool2 = Boolean.valueOf(true);
System.out.println(bool1 == bool2); // 输出 true

【注意】只有使用 valueOf 方法创建对象时才会触发缓存机制,如果使用 new 关键字创建对象,无论值是否在缓存范围内,都会创建新对象。

2. 自动装箱与拆箱了解吗?原理是什么?

Java的自动装箱和拆箱是Java 5 引入的,主要用于简化基本数据类型和对应的包装类之间的转换操作。

自动装箱:指基本类型自动转换成对应的包装类对象。如 int 自动转 Integer。

自动拆箱:指包装类对象自动转换成对应的基本类型。如 Integer自动转int。

// 自动装箱
int num1 = 10;
Integer num2 = num1;// 自动拆箱
Integer num3 = 20;
int num4 = num3;

自动装箱和拆箱的原理:

自动装箱原理:在编译阶段,编译器会调用包装类的valueOf()方法来实现自动装箱。

例如,上述代码中的Integer num2 = num1;

在编译后实际上会变成Integer num2 = Integer.valueOf(num1);。

自动拆箱:在编译阶段,编译器会调用包装类的xxxValue()方法来实现自动拆箱。

像int num4 = num3;

在编译后会变为int num4 = num3.intValue();。

包装类的缓存机制,又在这里得到了验证。

3. 浅拷贝和深拷贝区别了解吗?什么是引用拷贝?

浅拷贝、深拷贝和引用拷贝是三种不同的对象复制方式。

(1)引用拷贝仅仅是复制对象的引用,而不会创建新的对象。也就是说,原对象和复制后的对象都指向内存中的同一个实例。因此,对其中一个对象的修改会反映到另一个对象上。

(2)浅拷贝会创建一个新的对象,然后将原对象的非静态字段复制到新对象中。如果字段是基本数据类型,就直接复制其值;如果字段是引用类型,只复制引用,而不复制对象本身。这意味着原对象和浅拷贝对象中的引用类型字段会指向同一个对象(也就是说原对象的内部类会直接引用)。

要实现浅拷贝,可以让类实现 Cloneable 接口并重写 clone() 方法。

(3)深拷贝同样会创建一个新的对象,并且会递归地复制原对象的所有字段,包括引用类型的字段。这意味着原对象和深拷贝对象中的引用类型字段指向不同的对象,对一个对象的修改不会影响到另一个对象

要实现深拷贝,可以通过序列化和反序列化来完成,也可以手动递归地复制所有引用类型的字段。

4. 谈谈对 Java 注解的理解,解决了什么问题?

注解可以看作是一种特殊的标记,它可以应用于包、类、方法、字段等元素上,以提供额外的信息。注解通过 @ 符号来标识,例如 @Override@Deprecated 等。Java 提供了一些内置的注解,同时开发者也可以自定义注解。

注解解决的问题:

(1)编译时检查:编译器会检查被 @Override 注解标记的方法是否真的重写了父类的方法,如果没有则会报错。这样可以避免因方法名拼写错误或方法签名不匹配而导致的潜在问题。

(2)代码生成:在一些框架中,注解可以用于生成代码。如 Lombok 

(3)配置信息管理:注解可以用于替代传统的配置文件,将配置信息直接嵌入到代码中。例如,Spring 框架使用 @Component@Service@Repository 等注解来标识组件,将组件的配置信息与代码紧密结合,提高了代码的可维护性。

(4)运行时信息的获取:通过反射机制,在运行时获取注解的信息,并根据这些信息执行相应的操作。例如,JUnit 框架使用 @Test 注解来标记测试方法,在运行测试时,JUnit 会通过反射查找所有被 @Test 注解标记的方法并执行。

5. Exception 和 Error 有什么区别?

Exception 和 Error 都继承自 Throwable 类

Exception 表示程序运行时可能出现的可处理的异常情况。开发人员能够通过捕获和处理这些异常。

Error 表示系统级别的错误通常是由 JVM或者底层系统出现问题引发的。

应用场景

  • Exception
    • 受检查异常:在编译时就需要被处理的异常,若不处理,程序将无法通过编译,例如 IOExceptionSQLException 等。
    • 运行时异常:编译时不需要强制处理,例如 NullPointerExceptionArrayIndexOutOfBoundsException 等。
  • Error:一般是系统级的错误,常见的有 OutOfMemoryErrorStackOverflowError 

6. Java 反射?反射的缺点?反射的应用场景?

 反射是什么?

反射(Reflection)是 Java 提供的一种动态机制,允许程序在运行时获取类的元数据(如类名、方法、字段、构造器等),并动态操作类或对象(如实例化对象、调用方法、访问私有成员等)。其核心是通过 Class 对象实现,关键 API 包括:

  • Class 类:表示类的元数据。

  • MethodFieldConstructor:分别表示方法、字段和构造器。

示例:通过类名动态创建对象:
Class<?> clazz = Class.forName("com.example.User");
Object user = clazz.newInstance();

反射的缺点

  • 性能开销:反射调用涉及动态解析和 JVM 优化限制(如无法内联方法),性能比直接调用低。但通过缓存 Method 对象或使用 setAccessible(true) 关闭安全检查可缓解。

  • 破坏封装性:可访问私有成员(如 private 方法或字段),可能导致代码安全隐患。

  • 代码复杂度:反射代码冗长,需处理大量异常(如 ClassNotFoundException),降低可读性和维护性。

  • 兼容性风险:反射依赖类的内部细节(如方法名、参数列表),若类结构变更(如版本升级),反射代码可能失效。

  • 泛型擦除:反射无法直接获取泛型类型信息(如 List<String> 在运行时变为 List)。

 反射的应用场景

  • 框架开发

    • Spring 依赖注入:通过反射实例化 Bean 并注入属性。

    • ORM 框架(如 Hibernate):将数据库结果映射到 Java 对象。

    • 动态代理(如 AOP):生成代理类拦截方法调用。

  • 序列化/反序列化:如 Jackson 通过反射读取对象字段生成 JSON。

  • 测试工具:JUnit 使用反射调用测试方法。

  • 插件化架构:动态加载类(如通过配置文件的类名实例化对象)。

  • IDE 和调试工具:实时获取对象信息(如变量值、方法列表)。

7. Java 泛型了解么?什么是类型擦除?介绍⼀下常⽤的通配符?

Java泛型&通配符

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql--索引

索引作为一种数据结构&#xff0c;其用途是用于提升检索数据的效率。 分类 普通索引&#xff08;INDEX&#xff09;&#xff1a;索引列值可重复 唯一索引&#xff08;UNIQUE&#xff09;&#xff1a;索引列值必须唯一&#xff0c;可以为NULL 主键索引&#xff08;PRIMARY KEY&a…

王道考研数据结构课后题代码题(2026版)——排序部分

一、前言 本合集以王道考研《数据结构》辅导书&#xff08;2026版&#xff09;课后习题代码题部分为参考依据&#xff0c;给出课后习题代码题的可执行代码的实现&#xff0c;本合集使用编程语言以C/C语言为主&#xff0c;也不限于使用Python和Java语言&#xff0c;本套合计代码…

AVFormatContext 再分析零

随着对于AVFormatContext 各个参数的学习&#xff0c;逐渐可以从 整体架构上 再认识一下 AVFormatContext 了。 还是从解封装的第一步开始。 int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options); 实际上…

uniapp打包apk详细教程

目录 1.打apk包前提条件 2.获取uni-app标识 3.进入dcloud开发者后台 4.开始打包 1.打apk包前提条件 1.在HBuilderX.exe软化中&#xff0c;登录自己的账号 2.在dcloud官网&#xff0c;同样登录自己的账号。没有可以免费注册。 2.获取uni-app标识 获取方法&#xff1a;点…

Vue2 和 Vue3 的核心区别

1. 响应式原理&#xff1a;从「手动挡」到「自动挡」 Vue2&#xff1a; 使用 Object.defineProperty 监听数据变化&#xff0c;但无法检测新增属性和数组索引修改&#xff0c;需要借助 Vue.set。 // Vue2 中修改数组元素不会触发视图更新 this.list[0] 新值; // ❌ 不…

EMMC存储性能测试方法

记于 2022 年 9 月 15 日 EMMC存储性能测试方法 - Wesley’s Blog 参考Android-emmc性能测试 | 一叶知秋进行实践操作 dd 命令 页面缓存 为了测试 emmc 的真实读写性能&#xff0c;我们需要先把页面缓存给清理&#xff1a; echo 1 > /proc/sys/vm/drop_caches console:…

软件管理(安装方式)

1.rpm安装 1.1.rpm介绍 rpm软件包名称: 软件名称 版本号(主版本、次版本、修订号) 操作系统 -----90%的规律 举例:openssh-6.6.1p1-31.el7.x86_64.rpm 数字是版本号:第一位主版本号,第二位次版本号,带横杠的是修订号, el几---操作系统的版本。 #用rpm安装需要考虑如下信…

OnlyOffice Document Server 源码调试指南-ARM和x86双模式安装支持

在ARM64架构下创建的ONLYOFFICE源码调试容器具有显著优势。该容器基于官方Document Server镜像构建&#xff0c;通过集成Git、Python和Node.js等工具链&#xff0c;实现跨平台环境一致性&#xff0c;确保ARM设备的兼容性。容器化隔离消除了依赖冲突&#xff0c;支持快速部署到边…

oracle 数据库查询指定用户下每个表占用空间的大小,倒序显示

oracle 查询指定用户下每个表占用空间的大小&#xff0c;倒序显示 使用场景&#xff1a;数据分析&#xff1b;导出医院正式库到开发环境时&#xff0c;查询出占用表空间高的业务表、导出时排除该表 在Oracle数据库中&#xff0c;要查询指定用户下每个表占用空间的大小并以倒序…

归并排序【逆序对】

目录 归并排序原理 逆序对 归并排序 主要利用分治思想&#xff0c;时间复杂度O(nlogn) 原理 1.对数列不断等长拆分&#xff0c;直到一个数的长度。2.回溯时&#xff0c;按升序合并左右两段。3.重复以上两个过程&#xff0c;直到递归结束。 合并 1.i&#xff0c;j分别指向a的…

AI 与生物技术的融合:开启精准医疗的新纪元

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;与生物技术的融合正在成为推动医疗领域变革的重要力量。精准医疗作为现代医学的重要发展方向&#xff0c;旨在通过深入了解个体的基因信息、生理特征和生活方式&#xff0c;为患者提供个性化的治疗方案。AI…

对比表格:数字签名方案、密钥交换协议、密码学协议、后量子密码学——密码学基础

文章目录 一、数字签名方案1.1 ECDSA&#xff1a;基于椭圆曲线的数字签名算法1.2 EdDSA&#xff1a;Edwards曲线数字签名算法1.3 RSA-PSS&#xff1a;带有概率签名方案的RSA1.4 数字签名方案对比 二、密钥交换协议2.1 Diffie-Hellman密钥交换2.2 ECDH&#xff1a;椭圆曲线Diffi…

Linux 进程间通信(IPC)详解

进程间通信&#xff08;IPC&#xff09;深入解析 一、进程间通信概述 在操作系统里&#xff0c;不同进程间常常需要进行数据交换、同步协调等操作&#xff0c;进程间通信&#xff08;Inter - Process Communication&#xff0c;IPC&#xff09;机制应运而生。在Linux系统中&a…

深度解析ComfyUI的使用

一、ComfyUI 概述 ComfyUI 本质上是一个专为 AI 绘画爱好者和专业人士打造的用户界面工具&#xff0c;它的核心作用是将复杂的 AI 绘画生成过程以直观的方式呈现给用户。与传统的图像生成工具不同&#xff0c;ComfyUI 借助其独特的节点化工作流系统&#xff0c;把深度学习模型…

模型测试报错:有2张显卡但cuda.device_count()显示GPU卡数量只有一张

此贴仅为记录debug过程&#xff0c;为防后续再次遇见 问题 问题情境 复现文章模型&#xff0c;使用GPU跑代码&#xff0c;有两张GPU&#xff0c;设置在 cuda: 1 上跑 问题描述 在模型测试加载最优模型时报错&#xff1a;torch.cuda.device_count()显示GPU卡数量只有一张&…

【计网】认识跨域,及其在go中通过注册CORS中间件解决跨域方案,go-zero、gin

一、跨域&#xff08;CORS&#xff09;是什么&#xff1f; 跨域&#xff0c;指的是浏览器出于安全限制&#xff0c;前端页面在访问不同源&#xff08;协议、域名、端口任一不同&#xff09;的后端接口时&#xff0c;会被浏览器拦截。 比如&#xff1a; 前端地址后端接口地址是…

内存性能测试方法

写于 2022 年 6 月 24 日 内存性能测试方法 - Wesley’s Blog dd方法测试 cat proc/meminfo console:/ # cat proc/meminfo MemTotal: 3858576 kB MemFree: 675328 kB MemAvailable: 1142452 kB Buffers: 65280 kB Cached: 992252 …

AVFormatContext 再分析二

说明 &#xff1a;将 avfromatContext 的变量依次打印分析&#xff0c;根据ffmpeg 给的说明&#xff0c;猜测&#xff0c;结合网上的文章字节写测试代码分析二。 37 AVInputFormat *iformat; /** * The input container format. * * Demuxing only, set by avfo…

深入了解Linux系统—— 进程优先级

前言 我们现在了解了进程是什么&#xff0c;进程状态表示什么 &#xff0c;我们现在继续来了解进程的属性 —— 进程优先级 进程执行者 在了解进程优先级之前&#xff0c;先来思考一个问题&#xff1a;在我们进行文件访问操作时&#xff0c;操作系统是如何直到我们是谁&#x…

Expected SARSA算法详解:python 从零实现

&#x1f9e0; 向所有学习者致敬&#xff01; “学习不是装满一桶水&#xff0c;而是点燃一把火。” —— 叶芝 我的博客主页&#xff1a; https://lizheng.blog.csdn.net &#x1f310; 欢迎点击加入AI人工智能社区&#xff01; &#x1f680; 让我们一起努力&#xff0c;共创…