(备战春招,每天进步亿点点)常见面试题总结——Java基础(2)

大家好,我是杜晓帅~,一名Java实习生,抓紧学习,每天进步亿点点😁

在这里插入图片描述

Java基础

值传递和引用传递的区别的什么?为什么说Java中只有值传递?

值传递: 指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。

引用传递: 指的是在方法调用时,传递的参数是按引用进行传递,其实传递的是引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

基本类型作为参数被传递时肯定是值传递;引用类型作为参数被传递时也是值传递,只不过“值”为对应的引用。

深入了解请参考文章:http://www.itwanger.com/java/2019/11/26/java-yinyong-value.html

== 和 equals 区别是什么?

== 常用于相同的基本数据类型之间的比较,也可用于相同类型的对象之间的比较;

  • 如果 == 比较的是基本数据类型,那么比较的是两个基本数据类型的值是否相等
  • 如果 == 比较的是两个对象,那么比较的是两个对象的引用,也就是判断两个对象是否指向了同一块内存区域

equals 方法主要用于两个对象之间,检测一个对象是否等于另一个对象
下面看看Object类中equals的源码:

public boolean equals(Object obj) {
        return (this == obj);
    }

它的作用也是判断两个对象是否相等,一般有两种使用情况:

  • 情况1,类没有覆盖equals()方法。则通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象。
  • 情况2,类覆盖了equals()方法。一般,我们都覆盖equals()方法来两个对象的内容相等;若它们的内容相等,则返回true(即,认为这两个对象相等)。

java语言规范要求equals方法具有以下特性:

  • 自反性。对于任意不为null的引用值x,x.equals(x)一定是true。
    对称性)。对于任意不为null的引用值x和y,当且仅当x.equals(y)是true时,y.equals(x)也是true。
  • 传递性。对于任意不为null的引用值x、y和z,如果x.equals(y)是true,同时y.equals(z)是true,那么x.equals(z)一定是true。
  • 一致性。对于任意不为null的引用值x和y,如果用于equals比较的对象信息没有被修改的话,多次调用时x.equals(y)要么一致地返回true要么一致地返回false。
  • 对于任意不为null的引用值x,x.equals(null)返回false。

String,StringBuffer, StringBuilder 三者有什么区别?

1.可变与不可变?
String类中使用字符数组保存字符串,因为有“final”修饰符,所以string对象是不可变的。对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,这两种对象都是可变的。
2.是否多线程安全?

String中的对象是不可变的,也就可以理解为常量,显然线程安全。

StringBuilder是非线程安全的。

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。

StringBuffer源码如下:

 @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

3.执行效率
每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
综上所述:
如果单论同一线程的代码执行效率来说,StringBuilder的效率是最高的,String是最低的,StringBuffer居中

什么是反射以及如何获取反射中的Class对象?

什么是反射?

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在这里插入图片描述

如何获取反射中的Class对象?

1.Class.forName(“类的路径”);当你知道该类的全路径名时,你可以使用该方法获取 Class 类对象。

Class clz = Class.forName("java.lang.String");

2.类名.class。这种方法只适合在编译前就知道操作的 Class。

Class clz = String.class

3.对象名.getClass()。

String str = new String("Hello");
Class clz = str.getClass();

4.如果是基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。

Java序列化与反序列化是什么?为什么需要序列化与反序列化?

Java序列化与反序列化是什么?

Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程:

  • 序列化: 序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。核心作用是对象状态的保存与重建。我们都知道,Java对象是保存在JVM的堆内存中的,也就是说,如果JVM堆不存在了,那么对象也就跟着消失了。
    而序列化提供了一种方案,可以让你在即使JVM停机的情况下也能把对象保存下来的方案。就像我们平时用的U盘一样。把Java对象序列化成可存储或传输的形式(如二进制流),比如保存在文件中。这样,当再次需要这个对象的时候,从文件中读取出二进制流,再从二进制流中反序列化出对象。
  • 反序列化: 客户端从文件中或网络上获得序列化后的对象字节流,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。

为什么需要序列化与反序列化?

对内存中的对象进行持久化或网络传输, 这个时候都需要序列化和反序列化
如下:
1.对象序列化可以实现分布式对象。
主要应用例如:RMI(即远程调用Remote Method Invocation)要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。

2.java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。
可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。

3.序列化可以将内存中的类写入文件或数据库中。
比如:将某个类序列化后存为文件,下次读取时只需将文件中的数据反序列化就可以将原先的类还原到内存中。也可以将类序列化为流数据进行传输。
总的来说就是将一个已经实例化的类转成文件存储,下次需要实例化的时候只要反序列化即可将类实例化到内存中并保留序列化时类中的所有变量和状态。

4.对象、文件、数据,有许多不同的格式,很难统一传输和保存。
序列化以后就都是字节流了,无论原来是什么东西,都能变成一样的东西,就可以进行通用的格式传输或保存,传输结束以后,要再次使用,就进行反序列化还原,这样对象还是对象,文件还是文件。

Java常见异常有哪些?

  • java.lang.IllegalAccessError:违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常。
  • java.lang.InstantiationError:实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.
  • java.lang.OutOfMemoryError:内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。
  • java.lang.StackOverflowError:堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出或者陷入死循环时抛出该错误。
  • java.lang.ClassCastException:类造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。
  • java.lang.ClassNotFoundException:找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
  • java.lang.ArithmeticException:算术条件异常。譬如:整数除零等。
  • java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
  • java.lang.IndexOutOfBoundsException:索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。
  • java.lang.InstantiationException:实例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。
  • java.lang.NoSuchFieldException:属性不存在异常。当访问某个类的不存在的属性时抛出该异常。
  • java.lang.NoSuchMethodException:方法不存在异常。当访问某个类的不存在的方法时抛出该异常。
  • java.lang.NullPointerException:空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
  • java.lang.NumberFormatException:数字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。
  • java.lang.StringIndexOutOfBoundsException:字符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常。

访问修饰符public、private、protected、以及不写(默认)时的区别?

Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  • public : 对所有类可见。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
    在这里插入图片描述

抽象类和接口的区别是什么?

语法层面上的区别:

  • 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
  • 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

设计层面上的区别:

  • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。
  • 设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。

如需深入了解,可参考文章:https://www.cnblogs.com/dolphin0520/p/3811437.html

java 创建对象有哪几种方式?

Java中提供了以下四种创建对象的方式:

  • new创建新对象
  • 通过反射机制
  • 采用clone机制
  • 通过序列化机制

前两者都需要显式地调用构造方法。对于clone机制,需要注意浅拷贝和深拷贝的区别,对于序列化机制需要明确其实现原理,在java中序列化可以通过实现Externalizable或者Serializable来实现。

String为什么要设计成不可变的?

1.便于实现字符串池(String pool)

在Java中,由于会大量的使用String常量,如果每一次声明一个String都创建一个String对象,那将会造成极大的空间资源的浪费。Java提出了String pool的概念,在堆中开辟一块存储空间String pool,当初始化一个String变量时,如果该字符串已经存在了,就不会去创建一个新的字符串变量,而是会返回已经存在了的字符串的引用。

String a = "Hello World!";
String b = "Hello World!";

如果字符串是可变的,某一个字符串变量改变了其值,那么其指向的变量的值也会改变,String pool将不能够实现!

2.使多线程安全
在并发场景下,多个线程同时读一个资源,是安全的,不会引发竞争,但对资源进行写操作时是不安全的,不可变对象不能被写,所以保证了多线程的安全。

3.避免安全问题

在网络连接和数据库连接中字符串常常作为参数,例如,网络连接地址URL,文件路径path,反射机制所需要的String参数。其不可变性可以保证连接的安全性。如果字符串是可变的,黑客就有可能改变字符串指向对象的值,那么会引起很严重的安全问题。

4.加快字符串处理速度

由于String是不可变的,保证了hashcode的唯一性,于是在创建对象时其hashcode就可以放心的缓存了,不需要重新计算。这也就是Map喜欢将String作为Key的原因,处理速度要快过其它的键对象。所以HashMap中的键往往都使用String。

总体来说,String不可变的原因要包括 设计考虑,效率优化,以及安全性这三大方面。


今天的常见面试题总结(Java基础篇)就这些了,如果能帮助到你,还望三连支持一下,后续会亿点点更新😁

在这里插入图片描述

### ARM 和 STM32 常见面试题及答案 #### 面试问题一:ARM 架构的特点及其优势 ARM架构采用精简指令集计算(RISC),具有低功耗、高性能和低成本等特点。其特点在于简单而高效的指令集设计,使得处理器可以在较低的频率下实现较高的性能效率[^1]。 ```c // 示例代码展示如何初始化一个简单的ARM寄存器操作 void arm_register_init(uint32_t *reg, uint32_t value){ *reg = value; // 初始化指定寄存器为给定值 } ``` #### 面试问题二:STM32 的主要特性有哪些? STM32系列微控制器基于ARM Cortex-M内核构建,具备丰富的外设接口和支持多种通信协议的能力。此外,还提供灵活的工作模式选项来优化电源管理,并支持实时操作系统RTOS运行环境。 #### 面试问题三:解释中断向量表的作用 中断向量表存储着各个异常处理程序的位置地址,在发生特定事件时CPU会跳转到对应位置执行相应代码片段完成对该事件响应的任务调度工作流程。 #### 面试问题四:GPIO配置方式说明 通用输入/输出端口(GPIO)可以通过设置相应的控制位来进行方向设定(输入或输出),还可以通过上拉/下拉电阻的选择提高信号稳定性;对于高速应用场合,则需考虑驱动能力等因素的影响从而合理调整相关参数以满足实际需求。 #### 面试问题五:DMA传输机制原理概述 直接内存访问(DMA)允许数据在外部设备之间快速交换而不必经过中央处理器(CPU)干预,这样可以有效减轻CPU负担并提升整体系统的吞吐率表现水平。 #### 面试问题六:定时器功能介绍 定时器模块能够产生精确的时间延迟或者周期性的触发脉冲序列用于测量时间间隔长度等功能用途广泛存在于各种嵌入式应用场景当中。 #### 面试问题七:串行通信协议UART/SPI/IIC区别对比 不同类型的串行总线各有侧重适用范围也有所差异: UART适用于异步半双工通讯场景,SPI则更适合同步全双工多主机拓扑结构,IIC常被用来连接少量从属器件形成简洁紧凑型网络体系。 #### 面试问题八:ADC/DAC转换过程解析 模数转换器(Analog-to-Digital Converter, ADC)负责将连续变化电压转变为离散数值表示形式供后续数字电路进一步分析处理;相反地数模转换器(Digital-to-Analog Converter,DAC)则是把计算机内部产生的量化电平还原成模拟电信号输出供给其他外围组件使用。 #### 面试问题九:RTC实时时钟的应用价值阐述 实时时钟(Real-Time Clock, RTC)能够在系统断电情况下依然保持准确计时状态,这对于长时间无人值守工作的自动化控制系统来说至关重要,因为它能确保即使是在极端条件下也能维持稳定可靠的操作日志记录与报警提示服务。 #### 面试问题十:PWM波形生成方法探讨 脉宽调制(Pulse Width Modulation,PWM)是一种利用改变方波占空比大小的方式来调节平均功率的技术手段,在电机驱动等领域有着不可替代的重要作用地位。 ### 准备技巧建议: - **深入理解理论基础**:掌握ARM架构基础知识以及STM32芯片手册中的核心概念和技术细节。 - **动手实践项目经验积累**:积极参与开源社区贡献代码或是自己动手制作一些小型作品来锻炼解决问题的实际能力。 - **关注行业动态资讯更新**:定期浏览技术论坛网站获取最新发展趋势信息以便及时调整个人职业规划路径走向。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值