Java高频面试题集(含代码+详细答案)_第1页
Java高频面试题集(含代码+详细答案)_第2页
Java高频面试题集(含代码+详细答案)_第3页
Java高频面试题集(含代码+详细答案)_第4页
Java高频面试题集(含代码+详细答案)_第5页
已阅读5页,还剩9页未读, 继续免费阅读

下载本文档

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

文档简介

Java高频面试题集(含代码+详细答案)本面试题集精选一线企业高频Java面试题,涵盖基础语法、核心特性、集合框架、多线程、异常处理、JVM基础、编程实战等核心模块,所有题目均配备可运行代码案例+通俗详细解析,贴合真实面试答题逻辑,无书面化空洞内容,适合面试刷题、复盘巩固。一、Java基础语法面试题1、==和equals的区别是什么?(高频必问)核心答案1、==是运算符,可以比较基本数据类型和引用数据类型:基本数据类型:比较数值是否相等引用数据类型:比较对象内存地址是否相同2、equals()是Object类的方法,仅用于比较引用数据类型:默认源码中equals()底层就是==,比较内存地址String、Integer等包装类重写了equals(),改为比较对象内容是否相等代码示例java

publicclassEqualsTest{

publicstaticvoidmain(String[]args){

//基本类型==比较数值

inta=10;

intb=10;

System.out.println(a==b);//true

//字符串对比

Strings1=newString("java");

Strings2=newString("java");

System.out.println(s1==s2);//false(不同对象,地址不同)

System.out.println(s1.equals(s2));//true(内容相同)

Strings3="spring";

Strings4="spring";

System.out.println(s3==s4);//true(字符串常量池,复用地址)

}

}2、String、StringBuilder、StringBuffer的区别?核心答案1、String:字符串常量,不可变,每次修改都会生成新字符串对象,效率低;适用于少量字符串操作场景。2、StringBuffer:字符串变量,可变,线程安全(方法加synchronized锁),效率低;适用于多线程大量字符串拼接场景。3、StringBuilder:字符串变量,可变,线程不安全,效率最高;适用于单线程大量字符串拼接场景(日常开发首选)。代码示例(效率对比)java

publicclassStringTest{

publicstaticvoidmain(String[]args){

//String拼接(效率极低)

Stringstr="";

longstart1=System.currentTimeMillis();

for(inti=0;i<10000;i++){

str+=i;

}

longend1=System.currentTimeMillis();

System.out.println("String耗时:"+(end1-start1)+"ms");

//StringBuilder拼接(单线程高效)

StringBuildersb=newStringBuilder();

longstart2=System.currentTimeMillis();

for(inti=0;i<10000;i++){

sb.append(i);

}

longend2=System.currentTimeMillis();

System.out.println("StringBuilder耗时:"+(end2-start2)+"ms");

}

}3、final、finally、finalize的区别?核心答案1、final:修饰符,用于定义常量、禁止重写和继承修饰变量:变量不可修改(常量)修饰方法:方法不可重写修饰类:类不可继承2、finally:异常处理关键字,搭配try-catch使用,无论程序是否异常,最终都会执行(唯一不执行场景:JVM退出),常用于释放资源。3、finalize():Object类的废弃方法,JVM垃圾回收前调用,存在性能问题,JDK9之后已废弃,基本不使用。代码示例(final+finally)java

publicclassFinalTest{

//final修饰常量

privatestaticfinalintNUM=100;

publicstaticvoidmain(String[]args){

try{

intres=10/0;

}catch(Exceptione){

System.out.println("程序出现异常");

}finally{

//必定执行

System.out.println("finally执行,释放资源");

}

}

}二、集合框架面试题1、ArrayList和LinkedList的区别?核心答案1、底层结构:ArrayList基于动态数组;LinkedList基于双向链表。2、查询效率:ArrayList支持随机访问,查询速度快;LinkedList只能遍历查询,速度慢。3、增删效率:ArrayList增删需要移动元素,效率低;LinkedList仅修改节点指针,增删效率高。4、内存占用:ArrayList存在数组扩容冗余空间;LinkedList每个节点存储指针,内存占用更高。5、线程安全:两者均为线程不安全。代码示例(基础使用)java

importjava.util.ArrayList;

importjava.util.LinkedList;

publicclassListTest{

publicstaticvoidmain(String[]args){

ArrayList<String>arrayList=newArrayList<>();

arrayList.add("Java");

arrayList.add("Python");

System.out.println("ArrayList查询元素:"+arrayList.get(0));

LinkedList<String>linkedList=newLinkedList<>();

linkedList.addFirst("前端");//头部插入,效率极高

linkedList.addLast("后端");

System.out.println("LinkedList头部元素:"+linkedList.getFirst());

}

}2、HashMap的底层原理?JDK1.7和JDK1.8区别?核心答案底层原理:HashMap基于数组+链表+红黑树实现,通过hash算法计算元素存储位置,解决hash冲突。JDK1.7与1.8核心区别:数据结构:1.7数组+单向链表;1.8数组+单向链表+红黑树冲突优化:链表长度>8且数组长度>64时,链表转为红黑树,提升查询效率插入方式:1.7头插法(多线程易出现环形链表死循环);1.8尾插法扩容机制:1.8优化了hash重计算逻辑,效率更高代码示例(HashMap基础使用)java

importjava.util.HashMap;

publicclassHashMapTest{

publicstaticvoidmain(String[]args){

HashMap<String,Integer>map=newHashMap<>();

//存入元素

map.put("张三",22);

map.put("李四",25);

map.put("张三",23);//覆盖重复key

//获取元素

System.out.println("张三年龄:"+map.get("张三"));

System.out.println("集合大小:"+map.size());

}

}3、HashMap和HashTable的区别?核心答案1、线程安全:HashMap线程不安全;HashTable线程安全(所有方法加锁)。2、null值支持:HashMap允许key、value为null;HashTable不允许null键值。3、效率:HashMap无锁,效率高;HashTable全局锁,效率极低。4、继承关系:HashMap继承AbstractMap;HashTable继承Dictionary。5、扩容:HashMap默认容量16,扩容2倍;HashTable默认容量11,扩容2倍+1。三、多线程面试题1、创建线程的四种方式?核心答案1、继承Thread类;2、实现Runnable接口;3、实现Callable接口(带返回值);4、线程池创建线程(企业开发首选)。完整代码示例(四种方式)java

importjava.util.concurrent.Callable;

importjava.util.concurrent.ExecutorService;

importjava.util.concurrent.Executors;

importjava.util.concurrent.FutureTask;

publicclassThreadTest{

publicstaticvoidmain(String[]args)throwsException{

//方式1:继承Thread类

newMyThread().start();

//方式2:实现Runnable接口

newThread(newMyRunnable()).start();

//方式3:实现Callable接口(有返回值)

FutureTask<Integer>futureTask=newFutureTask<>(newMyCallable());

newThread(futureTask).start();

System.out.println("线程返回值:"+futureTask.get());

//方式4:线程池(开发常用)

ExecutorServicepool=Executors.newSingleThreadExecutor();

pool.execute(newMyRunnable());

pool.shutdown();

}

}

//1、继承Thread

classMyThreadextendsThread{

@Override

publicvoidrun(){

System.out.println("Thread线程执行");

}

}

//2、实现Runnable

classMyRunnableimplementsRunnable{

@Override

publicvoidrun(){

System.out.println("Runnable线程执行");

}

}

//3、实现Callable

classMyCallableimplementsCallable<Integer>{

@Override

publicIntegercall(){

System.out.println("Callable线程执行");

return666;

}

}2、synchronized和Lock的区别?核心答案1、底层层面:synchronized是JVM原生锁,底层依赖虚拟机指令实现;Lock是代码层面锁(接口),基于AQS实现。2、锁释放:synchronized自动加锁、自动释放锁;Lock需要手动lock()加锁、unlock()解锁。3、锁特性:synchronized不可中断、非公平锁;Lock可中断、可设置公平/非公平锁、可超时锁。4、粒度:synchronized锁粒度粗;Lock锁粒度更精细,性能更好。代码示例(两种锁使用)java

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassLockTest{

//手动锁

privatestaticfinalLockLOCK=newReentrantLock();

privatestaticintnum=0;

//synchronized同步方法

publicstaticsynchronizedvoidsyncAdd(){

num++;

System.out.println("synchronized计数:"+num);

}

//Lock锁方式

publicstaticvoidlockAdd(){

LOCK.lock();//加锁

try{

num++;

System.out.println("Lock计数:"+num);

}finally{

LOCK.unlock();//手动释放锁

}

}

publicstaticvoidmain(String[]args){

newThread(LockTest::syncAdd).start();

newThread(LockTest::lockAdd).start();

}

}3、volatile关键字的作用?核心答案volatile是轻量级同步关键字,核心两大作用:保证可见性:一个线程修改变量,其他线程立即感知最新值,避免变量缓存导致数据不一致。禁止指令重排:保证代码执行顺序和书写顺序一致,解决多线程指令重排安全问题。注意:volatile不保证原子性,无法替代锁,复合操作(i++)依旧线程不安全。代码示例(可见性演示)java

publicclassVolatileTest{

//加volatile保证可见性

privatestaticvolatilebooleanflag=true;

publicstaticvoidmain(String[]args)throwsInterruptedException{

newThread(()->{

while(flag){

//循环监听flag状态

}

System.out.println("线程感知到flag变更,退出循环");

}).start();

Thread.sleep(1000);

flag=false;

}

}四、异常处理面试题1、CheckedException和RuntimeException的区别?核心答案Java异常分为编译时异常(受检异常)和运行时异常(非受检异常):1、RuntimeException(运行时异常):程序运行时抛出,编译不报错,可选择性捕获,例如空指针、数组越界、类型转换异常。2、CheckedException(编译时异常):除运行时异常外所有异常,编译强制处理(try-catch捕获或throws抛出),例如IO异常、文件不存在异常。代码示例java

importjava.io.FileReader;

publicclassExceptionTest{

publicstaticvoidmain(String[]args){

//运行时异常:编译不报错,运行报错

Stringstr=null;

//str.length();//空指针异常

//编译时异常:必须手动处理

try{

FileReaderreader=newFileReader("test.txt");

}catch(Exceptione){

e.printStackTrace();

}

}

}五、JVM基础面试题1、JVM内存区域划分?核心答案JVM运行时数据区分为5大区域,其中线程私有3个、线程共享2个:线程私有(随线程创建销毁):程序计数器:记录当前线程执行字节码行号,无内存溢出虚拟机栈:存储局部变量、方法栈帧,栈溢出、内存溢出本地方法栈:执行native本地方法线程共享(全局唯一):堆:存储所有对象实例、数组,JVM垃圾回收核心区域方法区:存储类信息、常量、静态变量、编译后的代码2、GC垃圾回收机制,哪些对象会被回收?核心答案GC核心作用:回收堆中无有效引用的对象,释放内存。可被回收的对象场景:对象引用赋值为null对象引用超出作用域集合清空、移除元素弱引用、软引用对象满足回收条件GC不会回收:静态变量引用对象、活跃线程引用对象、常量池对象。六、Java编程实战面试题(手写代码)1、手写冒泡排序解题思路相邻元素两两对比,大的元素后移,每轮排序确定一个最大值,循环完成整体排序。完整代码java

publicclassBubbleSort{

publicstaticvoidmain(String[]args){

int[]arr={5,2,9,1,5,6};

bubbleSort(arr);

//遍历输出

for(intnum:arr){

System.out.print(num+"");

}

}

//冒泡排序方法

publicstaticvoidbubbleSort(int[]arr){

if(arr==null||arr.length<=1){

return;

}

//外层循环:排序轮数

for(inti=0;i<arr.length-1;i++){

//内层循环:两两对比

for(intj=0;j<arr.length-1-i;j++){

if(arr[j]>arr[j+1]){

//交换位置

inttemp=arr[j];

arr[j]=arr[j+1];

arr[j+1]=temp;

}

}

}

}

}2、手写单例模式(双重检查锁,面试最优写法)解题思路私有化构造方法、静态私有实例、公共静态获取实例方法,双重检查锁保证线程安全、兼顾效率。完整代码java

publicclassSingleton{

//volatile禁止指令重排,保证线程安全

privatestaticvolatileSingletoninstance;

//私有构造方法,禁止外部实例化

privateSingleton(){}

//双重检查锁获取单例对象

publicstaticSingletongetInstance(){

//第一次校验:避免每次加锁,提升效率

if(instance==null){

synchronized(Singleton.class){

//第二次校验:防止多线程重复创建对象

if(instance==null){

instance=newSingleton();

}

}

}

returninstance;

}

publicstaticvoidmain(String[]args){

Singletons1=Singleton.getInstance();

Singletons2=Singleton.getInstance();

System.out.println(s1==s2);//true,同一个对象

}

}3、反转字符串(手写实现

温馨提示

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

评论

0/150

提交评论