当前位置: 首页 > news >正文

面试八股文之——JAVA基础

众所周知,程序员的技术能力考核大部分来源于面试和笔试,少数人可以靠着开源项目或者是证书、个人作品(书籍)等提升求职竞争力而直接获取offer。绝大多数程序员依旧是靠面试来获取offer。因此对待面试题,很多时候,应聘者需要做很多的准备,本文将对JAVA基础知识高频面试题目进行分享。

一、数据类型

1.Integer与int的区别?有int,为啥还要设计封装类Integer?

回答角度数据类型,存储位置,初始值,包装类的作用
1.int是Java语言的基础类型,存储于中,初始值为0
2.Integer是int的包装类,是对象类型,初始值为null,存储于堆内存中,通过对基础类型int的封装,使得对整形数据的操作更加灵活与方便。

2.为什么两个整数a和b都等于1000,比对为false,a和b值均为100,比对结果为true?

回答角度缓存设计、享元模式
八大基础类型中,byte、short、int、long、char这五种类型都采用了缓存设计,其中byte、short、int、long这四种数值类型为了减少频繁创建对象带来的内存消耗,缓存了-128~127范围的值(为啥选这个范围,考虑到这个范围的数据使用是最频繁的),因此在此范围的值,读取来自于常量池构建的对象,并不会重新创建对象。这里借助于享元模式,提升空间和时间的性能。

3.new String(“abc”) 到底创建了几个对象?

分情况讨论:
1.如果字符串"abc"常量不存在,则会创建两个对象,一个是存堆中,一个是存于常量池中。
2.如果字符串"abc"常量存在,则会创建一个对象,只会在堆中构建。

4.String、StringBuffer、StringBuilder的区别?

回答角度: 值可变性、线程安全、性能、存储位置
1.String内部使用final修饰,是不可变类,每次修改,都会重新构建一个新对象,其他两个类是可变类,因此在字符串变更时候,不会重新构建对象。
2.String作为不可变类,先天线程安全,StringBuffer内部方法使用synchronized关键字修饰,保证线程安全,
StringBuilder线程不安全
3.StringBuilder性能大于StringBuffer,因为StringBuffer使用了同步锁,String性能最低,因为对象不可变性,在对String类型数据进行修改时,只能通过重新创建对象来实现。
4.String存储于字符串常量池中,其他两个存储于堆中

二、Object对象

1.Java对象的创建过程?

回答角度: JVM检查、类加载、类初始化、内存分配、普通成员初始化、对象头设置、init方法和构造方法
1.JVM会检查对象是否被加载并且初始化
2.没有的话,则JVM会立刻加载目标类,然后调用目标类的构造器完成初始化,目标类的加载是通过类加载器来实现的。主要作用就是把一个类加载到内存中
3.初始化包括静态变量、类成员变量、静态代码块进行初始化
4.初始化后,为新对象分配内存空间,分配内存一般分为:指针碰撞,空闲列表;JVM会根据Java堆是否规整来决定分配方式
5.JVM对普通成员变量进行初始化赋值,比如int初始化为0,Integer对象类型初始化为null
6.JVM对目标对象的对象头进行设置,GC分代年龄、锁标记、对像所属类元信息等。
7.执行目标对象内部生成的init方法【代码编译之后在字节码文件中生成】,初始化成员变量、执行构造块、执行构造方法。

2.谈谈对深克隆与浅克隆的理解?

设计模式中原型模式,就是专门处理对象复制问题。这个对象的复制,分为浅克隆和深克隆,
所谓浅克隆,即在复制一个对象时候,仅仅复制对象本身以及其引用类型成员的引用,而不复制引用指向的对象本身,因此新对象和原对象共享相同的属性。新旧对象引用类型属性的变更会相互影响。
深克隆,即在进行对象复制时,会对所有引用执行的对象进行递归复制。新旧对象相互对立,互不影响。

3.强引用、软引用、弱引用、虚引用的区别?

强引用:只要引用关系存在,JVM就永远不会对其进行回收,除非强制将对象赋值为null或者没有引用关系。
软引用:JVM会在内存不足,溢出前会对其进行垃圾回收,通常用来实现内存敏感的缓存。空间足,保留缓存,空间不足,则清理缓存。
弱引用:下次GC一定回收,不管内存是否足够。
虚引用:这个必须和引用队列一起使用,用来观测对象的GC过程。提供了一种确保对象被finalize之后执行某些事件的机制。

4.一个空Object到底占用多大内存?

1.对象分为三部分:
(1) 对象头,对象头继续分为Markword、类元指针、数组长度(4个字节)。
(2) 实例数据,实际存储对象的字段信息
(3) 对齐填充,Java对象需要按照8字节的整数倍来对齐,来避免虚伪共享问题。
其中Markword用以存储GC分代年龄、hashCode等,类元指针用来存储当前实例对象所属于哪个类。
这两个存储的空间大小受操作系统和JVM指针压缩配置的影响,
以64位系统为例,Markword占用8个字节,32位操作系统为4个字节,
未开启指针压缩情况下,类元指针占用8个字节。此时空对象占用16个字节。
如果开启指针压缩,类元指针占用4个字节,整个对象占用12字节,此时对齐填充会补齐4个字节,因此在64位操作系统下一个空Object仍然是16个字节。

5.为什么重写equals方法就一定要重写hashCode()方法?

Java集合中hash结构在判断某个key是否存在时,为了提高效率,先比对对象的hashCode,如hashCode结果一致,再使用equals方法进行比对,减少equals方法的调用。因此为了让对象和集合类能正常工作,必须保证equals方法判定结果一致,则hashCode结果必须一致。因此在重写equals方法时候,如不重写hashCode方法,可能会发生equals判定一致,hashCode判定不一致的错误。因此开发中约定俗成一条规则,equals方法重写,必须重写hashCode方法

三、其他特性

1.受检异常和非受检异常?

1.受检异常表示在代码编译时候需要强制检查的异常,通常需要显示地使用try/catch进行捕获,或者是使用throws进行抛出,否则程序无法通过编译。除了Error类和RuntimeException类及派生类,其他都是受检异常,
比如IOException,SQLException等

2.非受检异常则不需要强制检查的异常,比如Error类和RuntimeException类及派生类。

2.fail-fast机制和fail-safe机制分别有什么作用?

这个是多线程并发操作集合时的失败处理机制。
fail-fast是快速失败,在对集合进行遍历过程中,一旦发现容器中数据被修改,立即抛出ConcurrentModificationException,触发遍历失败。java.util下的集合类都是这个机制,比如HashMap/ArrayList
fail-fast是安全失败,在对集合进行遍历过程中,一旦发现容器中数据被修改,不抛出异常,原因是,遍历过程中不是直接操作原集合,而是先复制集合,在操作复制后的集合。java.util.concurrent包下的集合都是采用这个机制,比如ConcurrentHashMap/CopyOnWriteArrayList等。

3.序列化和反序列化的理解?

序列化的目的是解决网络通信中对象传输问题。为了便于对象的存储和传输,通常需要将对象转化为字节流,这个过程称为序列化,同样,将字节流转化为对象的过程称为反序列化。其次为了提升通信双方对对象的可识别性,会将对象格式化指定结构比如JSON/XML/Protobuf,然后在进行序列化传输。实际应用过程中采用哪种序列化技术需要综合考虑以下几点:
1.序列化后数据大小
2.序列化的性能
3.是否支持跨平台、跨语言
4.技术的成熟度

4.什么是SPI,SPI的作用?

SPI,全程Service Provider Interface,是一种基于接口的动态扩展机制,Java SPI 相当于Java提供了一套接口,然后第三方可以基于这个接口完成功能的扩展。
典型的例子就是数据库驱动Java.jdbc.Driver。JDK定义了驱动类,并没有提供具体实现,开发过程中,根据驱动类型,动态加载对应的扩展实现,完成对数据库的连接。
很多开源框架借鉴了Java SPI的思想,提供了自己的SPI框架,比如Dubbo的ExtensionLoader,Spring 提供了SpringFactoriesLoader,SPI机制将装配的控制权移至程序之外,做到标准和实现的解耦,提供了动态可插拔的能力。
Java SPI 存在不足,不能根据需求加载需要的扩展实现会实例化所有实现类,存在一定的资源浪费

5.finally语句块一定会执行吗?

不一定,两种情况不会执行
1.程序没有进入try代码块因为异常导致程序终止,问题原因代码捕获异常范围不够。
2.try或者catch语句块中执行了System.exit(0)语句,JVM直接退出。

6.内存溢出和内存泄漏的理解?

1.内存泄漏,是本该凋亡的对象,JVM没有对其进行垃圾回收,长期大量的对象造成的内存泄露,会导致内存溢出。
2.内存溢出,内存空间不足以分配现有的对象,比如要分配一个10MB的数组,此时JVM内存空间只剩下5MB,就会触发内存溢出,这是个重大错误。

http://www.dtcms.com/a/350877.html

相关文章:

  • 深度学习梯度下降与交叉熵损失
  • 重塑企业沟通与增长:云蝠智能大模型如何成为您的智能语音中枢
  • 大模型(一)什么是 MCP?如何使用 Charry Studio 集成 MCP?
  • SQL查询-设置局部变量(PostgreSQL、MySQL)
  • 嵌入式学习 day58 驱动字符设备驱动
  • 玳瑁的嵌入式日记D25-0825(进程)
  • Java全栈开发实战:从Spring Boot到Vue3的项目实践
  • Android Glide 缓存机制深度解析与优化:从原理到极致实践
  • 集成电路学习:什么是ONNX开放神经网络交换
  • 深度学习③【卷积神经网络(CNN)详解:从卷积核到特征提取的视觉革命(概念篇)】
  • 详解 Transformer 激活值的内存占用公式
  • SOME/IP-SD报文中 Entry Format(条目格式)-理解笔记5
  • 算法题记录01:
  • 0826xd
  • Trip Footprints 旅行App开发全流程解析
  • UALink是什么?
  • 数字化转型:概念性名词浅谈(第四十二讲)
  • 牛客周赛 Round 106(小苯的方格覆盖/小苯的数字折叠/ 小苯的波浪加密器/小苯的数字变换/小苯的洞数组构造/ 小苯的数组计数)
  • 撤回git 提交
  • 算法训练营day62 图论⑪ Floyd 算法精讲、A star算法、最短路算法总结篇
  • C# 中常见的 五大泛型约束
  • [系统架构设计师]应用数学(二十一)
  • 云计算学习笔记——Linux用户和组的归属权限管理、附加权限、ACL策略管理篇
  • 联邦雪框架FedML自学---第四篇---案例一
  • 浅谈:运用幂的性质
  • 程序的“烽火台”:信号的产生与传递
  • 【基础-单选】使用http发起网络请求,需要以下哪种权限?
  • C6.2:小信号、交流电流增益分析
  • 立轴式小型混凝土搅拌机的设计含14张CAD
  • 客户生命周期价值帮助HelloFresh优化其营销支出