Java 基础高频面试题及详细答案(实战版)-1_第1页
Java 基础高频面试题及详细答案(实战版)-1_第2页
Java 基础高频面试题及详细答案(实战版)-1_第3页
Java 基础高频面试题及详细答案(实战版)-1_第4页
Java 基础高频面试题及详细答案(实战版)-1_第5页
已阅读5页,还剩2页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java基础高频面试题及详细答案(实战版)一、基础语法与核心概念1.JDK、JRE、JVM的区别与联系?答案:三者是层层包含的关系,范围从大到小:JDK>JRE>JVM。JVM是Java虚拟机,是Java程序运行的核心环境,负责加载字节码、解释/编译代码、内存管理、垃圾回收,是实现Java跨平台的核心,只负责运行程序。JRE是Java运行环境,包含JVM+Java核心类库(比如常用的String、集合、IO类等)。普通用户只安装JRE就可以运行Java程序,没有编译、调试等开发工具。JDK是Java开发工具包,包含JRE+开发工具(javac编译器、java运行命令、jar、调试工具jdb等)。开发人员必须安装JDK,才能编写、编译、调试Java代码。简单总结:JVM负责跑代码,JRE提供跑代码的环境,JDK提供开发+运行的全套环境。2.Java是编译型还是解释型语言?答案:Java属于半编译半解释型语言,不是纯编译也不是纯解释。首先通过javac编译器,把.java源文件编译成跨平台的.class字节码文件,这是编译过程;运行时,JVM会读取字节码,要么逐行解释执行,要么通过JIT即时编译器把字节码编译成机器码执行,这是解释执行过程。正是这种机制,让Java实现了“一次编译,到处运行”的跨平台特性。3.==和equals()的区别?答案:==是运算符,equals()是Object类的方法,核心区别是比较的内容不同。1、对于基本数据类型:==比较的是数值本身,基本类型没有equals方法。2、对于引用数据类型:==比较的是对象的内存地址,判断是不是同一个对象;默认的equals()方法和==效果一致,也是比较地址。但String、Integer等包装类重写了equals()方法,重写后比较的是对象的内容/值,不再比较地址。日常开发中,比较字符串、包装类数值是否一致,一律用equals;判断两个对象是否是同一个,用==。4.String、StringBuilder、StringBuffer的区别?答案:核心区别:可变性、线程安全、性能1、String:字符串不可变,底层是final修饰的字符数组。每次拼接、修改字符串都会生成新的String对象,频繁操作会产生大量无用对象,占用内存、效率低。适合少量字符串定义、不频繁修改的场景。2、StringBuilder:字符串可变,底层数组可扩容。线程不安全,多线程并发操作会出现数据错乱,但执行效率最高。适合单线程下频繁字符串拼接、修改场景。3、StringBuffer:字符串可变,和StringBuilder底层逻辑基本一致。方法都加了synchronized锁,线程安全,但加锁会损耗性能,效率偏低。适合多线程下频繁字符串操作场景。开发最优选择:单线程用StringBuilder,多线程用StringBuffer,常量字符串用String。5.final、finally、finalize的区别?答案:三者完全无关,只是命名相似,是高频易混点。1、final:是修饰符,可以修饰类、方法、变量。final修饰的类不能被继承;修饰的方法不能被重写;修饰的变量是常量,只能赋值一次,不能修改。2、finally:是异常处理的关键字,搭配try-catch使用。作用是无论代码正常执行还是出现异常,finally中的代码一定会执行(除了系统退出、断电等极端情况),通常用来释放资源,比如关闭流、关闭连接。3、finalize():是Object类的废弃方法,JDK9之后已废弃。原本设计是垃圾回收器回收对象前触发该方法,用来做资源释放,但执行时机不确定、无法保证调用,实际开发中基本不用。二、面向对象OOP核心1.面向对象的四大特性?分别是什么?答案:四大特性:封装、继承、多态、抽象1、封装:把类的属性私有化,通过public方法对外提供访问、修改入口。隐藏内部实现细节,统一访问方式,提高代码安全性、可维护性。比如实体类的private属性+get/set方法。2、继承:子类继承父类的属性和方法,实现代码复用。子类可以在父类基础上扩展新功能,减少重复代码。Java是单继承,一个类只能有一个直接父类,可实现多个接口。3、多态:同一个行为,不同子类有不同的实现。核心体现:父类引用指向子类对象,方法重写。编译看父类,运行看子类,提高代码扩展性、通用性。4、抽象:抽取事物的共性特征和行为,忽略细节。通过抽象类、接口实现,定义规范,让子类去实现具体逻辑,统一代码标准。2.重载和重写的区别?答案:重载(Overload):发生在同一个类中,多个方法名相同,参数列表不同(参数个数、类型、顺序不同),和返回值、访问修饰符无关。属于编译期多态,代码编译时就确定调用哪个方法。重写(Override):发生在父子类之间,子类重写父类的非私有、非final、非静态方法。方法名、参数列表、返回值必须和父类一致;访问权限不能比父类严格;抛出的异常范围不能比父类大。属于运行期多态,程序运行时才确定调用子类方法。简单记:重载是一个类里的方法翻新,重写是子类对父类方法的改造。3.抽象类和接口的区别?答案:1、定义与修饰:抽象类用abstract修饰,接口用interface修饰。2、继承实现:类只能单继承一个抽象类;类可以多实现多个接口,解决了单继承的局限性。3、成员变量:抽象类可以有普通成员变量、常量;接口中默认都是publicstaticfinal常量,不能定义普通变量。4、方法:抽象类可以有普通方法、静态方法、抽象方法;JDK8之前接口只有抽象方法,JDK8新增默认方法、静态方法,JDK9新增私有方法。5、构造方法:抽象类有构造方法,供子类初始化父类成员;接口没有构造方法,不能实例化。6、设计思想:抽象类是模板复用,描述一类事物的共性;接口是行为规范,描述类具备的能力。4.什么是向上转型、向下转型?有什么应用场景?答案:向上转型:子类对象赋值给父类引用,格式:父类引用名=new子类();是自动转换,无需强转。此时只能调用父类的方法,子类独有方法无法调用,重写的方法会执行子类逻辑。常用于统一方法参数、简化代码。向下转型:父类引用强制转换为子类类型,格式:子类引用名=(子类)父类引用;是手动强转,存在类型转换异常风险,通常需要配合instanceof判断类型。主要用于调用子类独有方法。三、集合框架(面试重点)1.ArrayList和LinkedList的区别?答案:1、底层结构:ArrayList底层是动态数组;LinkedList底层是双向链表。2、查询效率:ArrayList支持随机索引访问,查询速度极快;LinkedList只能从头节点/尾节点遍历查询,效率低。3、增删效率:ArrayList中间、头部增删元素需要移动数组元素,效率低;尾部增删较快。LinkedList任意位置增删只需修改节点指针,无需移动元素,增删效率更高。4、内存占用:ArrayList会预留扩容空间,存在内存冗余;LinkedList每个节点包含数据和指针,单个元素占用内存更大。开发选择:查询多、增删少用ArrayList;频繁增删、少量查询用LinkedList。2.HashMap的底层原理?JDK1.7和JDK1.8的区别?答案:底层核心原理:HashMap基于哈希表实现,通过hash算法计算key的哈希值,确定数组下标位置,存放键值对。存在哈希冲突时,通过链表解决,链表过长会转为红黑树,提高查询效率。JDK1.7与JDK1.8核心区别:1、数据结构:1.7是「数组+单向链表」;1.8是「数组+单向链表+红黑树」。2、哈希冲突优化:1.7链表长度无限增长,查询效率随链表变长持续降低;1.8链表长度超过8且数组容量大于64时,链表转为红黑树,查询时间复杂度从O(n)优化为O(logn)。3、插入方式:1.7链表采用头插法,并发场景容易出现环形链表,导致死循环;1.8改为尾插法,规避了环形链表问题。4、扩容机制:1.8优化了扩容重哈希逻辑,无需重新计算所有key的哈希值,提升扩容效率。3.HashMap和HashTable的区别?答案:1、线程安全:HashMap线程不安全;HashTable线程安全,所有方法都加了synchronized锁。2、效率:HashMap无锁,并发效率高;HashTable锁粒度大,全局锁,效率极低,开发中基本不用。3、null支持:HashMap允许key、value为null(最多一个nullkey);HashTable不允许key和value为null,会直接报错。4、继承与规范:HashTable是古老类,方法繁琐、性能差,已被淘汰;日常多线程场景推荐使用ConcurrentHashMap替代HashTable。4.ConcurrentHashMap的线程安全原理?答案:JDK1.8的ConcurrentHashMap摒弃了分段锁机制,采用CAS+synchronized锁实现线程安全。1、无冲突时,通过CAS自旋操作实现无锁更新,效率极高;2、出现哈希冲突时,只对当前数组下标位置的链表/红黑树根节点加synchronized锁,锁粒度极小,不会锁住整个集合;3、兼顾了线程安全和并发性能,是生产环境多线程存取键值对的最优选择。四、异常处理1.受检异常和非受检异常的区别?答案:Java中所有异常的父类是Throwable,分为Error和Exception,Exception又分为受检异常和运行时异常(非受检异常)。1、受检异常(编译时异常):直接继承Exception,编译阶段必须处理,否则代码报错。处理方式要么try-catch捕获,要么throws抛出。常见:IO异常、SQL异常、文件不存在异常。2、非受检异常(运行时异常):继承RuntimeException,编译阶段不报错,运行程序时才会抛出。无需强制捕获或抛出,通常是代码逻辑问题导致。常见:空指针、数组越界、类型转换异常、算术异常。3、Error:系统级严重错误,比如内存溢出、栈溢出,程序无法处理,只能终止运行。2.try-catch-finally执行顺序?return对finally有影响吗?答案:正常执行顺序:先执行try代码块,出现异常执行对应catch代码块,最后一定会执行finally代码块。即使try、catch中存在return语句,也不会阻止finally执行。执行逻辑是:先执行return前的代码、缓存返回值,再执行finally代码,最后再return返回结果。唯一不执行finally的场景:代码中执行System.exit(0)退出JVM、程序断电、系统崩溃。五、泛型、枚举与包装类1.泛型的作用是什么?泛型擦除是什么?答案:泛型核心作用:编译期类型检查,避免类型转换异常,省去强制类型转换代码,让代码更通用、更安全。泛型擦除:Java泛型是伪泛型,只在编译阶段生效。编译成功生成class文件后,会将泛型类型全部擦除,统一替换为Object类型(有上限的替换为上限类型),运行阶段不存在泛型信息。这也是为什么不能用泛型创建实例、泛型数组的核心原因。2.基本类型和包装类的区别?自动装箱与拆箱?答案:1、基本类型:8种,直接存储数值,占用内存小,存放在栈中,无默认null,效率高。2、包装类:是基本类型的对象封装,属于引用类型,存放在堆中,默认值可以为null,具备对象特性,可以调用方法、存储在集合中(集合只能存对象,不能存基本类型)。自动装箱:基本类型自动转为包装类,比如Integera=10;自动拆箱:包装类自动转为基本类型,比如intb=a;补充:Integer有缓存机制,-128~127范围内的数值,装箱会复用缓存对象,超出范围会新建对象。六、IO与新特性基础1.BIO、NIO的核心区别?答案:1、BIO:同步阻塞IO,传统IO模式。一个线程只能处理一个连接,客户端未请求、数据未就绪时,线程会一直阻塞等待。并发量低,适合小流量、简单场景。2、NIO:同步非阻塞IO,Java新IO。支持缓冲区、通道、选择器,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论