版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
324道Java高频面试题及详细答案(完整版)第一部分:Java基础(1-80题)1.JDK、JRE、JVM的区别?JVM是Java虚拟机,是运行Java字节码的虚拟机器,是Java实现跨平台的核心,只负责运行class文件。JRE是Java运行环境,包含JVM和Java核心类库,普通用户只需要安装JRE就能运行Java程序。JDK是Java开发工具包,包含JRE、编译工具、调试工具、打包工具等,开发人员必须安装JDK才能编写、编译、调试Java代码。三者层级关系:JDK>JRE>JVM。2.Java基本数据类型有哪些?占用字节数?一共8种基本数据类型。整数型:byte(1字节)、short(2字节)、int(4字节)、long(8字节);浮点型:float(4字节)、double(8字节);字符型:char(2字节);布尔型:boolean(虚拟机规范未明确,实际开发中单个变量占1字节,数组占1字节/元素)。注意:long类型赋值必须加L后缀,float必须加F后缀。3.包装类和基本数据类型的区别?基本类型是原生数据类型,占用内存小、运算速度快,没有对象的特性,不能调用方法,默认有固定初始值。包装类是基本类型的对象封装,属于引用类型,默认值为null,提供了大量数据转换、数值判断的工具方法,支持泛型使用、存入集合。Java5之后引入自动装箱和拆箱,实现了基本类型和包装类的自动转换。4.自动装箱拆箱原理?装箱是基本类型转包装类,底层执行包装类的valueOf()方法;拆箱是包装类转基本类型,底层执行xxxValue()方法。例如Integeri=10;底层是Integeri=Integer.valueOf(10);inta=i;底层是inta=Value();另外Integer、Short等包装类有缓存机制,Integer缓存-128~127之间的数值,这个区间内的对象复用,超出区间会新建对象。5.==和equals的区别?==是比较运算符,对于基本类型,比较的是数值是否相等;对于引用类型,比较的是对象的内存地址是否相同。equals是Object类的方法,默认实现和==一致,比较地址。String、Integer等类重写了equals方法,重写后比较的是对象的内容值是否相等。日常开发中,字符串、对象内容对比优先用equals,地址对比才用==。6.String、StringBuilder、StringBuffer的区别?String是不可变字符串,底层是final修饰的字符数组,每次拼接都会生成新对象,效率最低。StringBuilder和StringBuffer是可变字符串,底层数组可扩容,拼接不会生成新对象。StringBuffer是线程安全的,所有方法加了synchronized锁,多线程场景使用,效率稍低。StringBuilder线程不安全,无锁,单线程场景首选,效率最高。日常开发字符串拼接优先用StringBuilder。7.String为什么不可变?JDK1.9之前String底层是finalchar[]数组,JDK1.9之后改为finalbyte[]数组。核心原因是数组被final修饰,意味着数组的引用地址不可修改,同时String内部没有提供任何修改数组元素的公开方法,所有增删改操作都是生成新的String对象。不可变的特性保证了字符串常量池复用、哈希值固定、线程安全。8.字符串常量池的作用?字符串常量池是JVM为了减少字符串对象重复创建、节省内存开辟的缓存空间。直接双引号定义的字符串会存入常量池,后续创建相同内容的字符串会直接复用池中的对象,不会新建。newString()方式会强制在堆中创建新对象,不会复用常量池对象。9.int和Integer的区别?int是基本类型,默认值0,占用4字节,直接存储数值,运算效率高。Integer是int的包装类,引用类型,默认值null,存储对象地址,具备对象特性。两者对比关键点:两个newInteger对象对比永远不等;非new的Integer变量,数值在-128~127之间相等,超出不等;int和Integer对比,会自动拆箱,只比数值。10.final、finally、finalize的区别?final是修饰符,修饰变量表示常量不可修改,修饰方法表示不可重写,修饰类表示不可继承。finally是异常处理关键字,搭配try-catch使用,代码块一定会执行,常用于释放资源。finalize是Object类的废弃方法,JDK9之后废弃,原本用于垃圾回收前对象的资源清理,执行时机不确定、无法保证调用。11.接口和抽象类的区别?抽象类用abstract修饰,有构造方法,可以有普通成员变量、普通方法、抽象方法,单继承,偏向于模板设计。接口用interface修饰,无构造方法,JDK1.8之前只有抽象方法和常量,1.8支持默认方法、静态方法,1.9支持私有方法,可多实现,偏向于行为规范。开发中优先用接口,降低耦合。12.抽象方法能不能是static、private、final?都不可以。抽象方法的核心目的是被子类重写实现。static方法属于类,不能被子类重写;private方法仅本类可见,子类无法访问;final方法禁止重写,三者都和抽象方法的设计初衷冲突。13.重载和重写的区别?重载是方法同名、参数列表不同(个数、类型、顺序),和返回值、权限修饰符无关,发生在同一个类中,编译期多态。重写是子类对父类非私有、非final、非static方法的覆盖,方法名、参数列表、返回值必须一致,权限修饰符范围大于等于父类,异常范围小于等于父类,发生在父子类中,运行期多态。14.面向对象的四大特性?封装、继承、多态、抽象。封装是将属性私有化,通过公开方法访问,隐藏内部细节、保证数据安全。继承是子类复用父类代码,减少冗余、实现代码复用。多态是同一行为不同实现,分为编译期多态(重载)和运行期多态(重写),提升代码扩展性。抽象是抽取事物共性特征,定义规范,约束子类行为。15.构造方法能不能重写?能不能重载?构造方法不能重写,因为构造方法名必须和类名一致,子类和父类类名不同,无法重写。构造方法可以重载,一个类中可以定义多个参数列表不同的构造方法,实现对象不同方式的初始化。16.静态变量、实例变量、局部变量的区别?静态变量用static修饰,属于类,加载类时初始化,全局唯一,所有对象共享,存储在方法区。实例变量属于对象,创建对象时初始化,每个对象独立拥有,存储在堆内存。局部变量定义在方法、代码块中,调用方法时创建,方法结束销毁,存储在栈内存,无默认值,必须手动初始化。17.static关键字的作用?static可以修饰变量、方法、代码块、内部类。修饰变量为静态变量,类共享、全局唯一;修饰方法为静态方法,属于类,可直接通过类名调用,不能访问实例成员;修饰代码块为静态代码块,类加载时执行一次,用于初始化静态资源;修饰内部类为静态内部类,不依赖外部类对象。18.静态方法能不能调用非静态方法?不能直接调用。静态方法属于类,类加载时就存在;非静态方法属于对象,必须创建对象后才能调用。静态方法执行时,可能还没有创建类的实例,因此无法直接调用非静态方法,只能通过new对象的方式间接调用。19.成员变量和局部变量的初始化区别?成员变量(静态、实例变量)系统会自动赋予默认值,数值型0、布尔false、引用类型null。局部变量没有默认值,必须手动赋值后才能使用,否则编译报错。20.数组有没有length()方法?字符串有没有length属性?数组没有length()方法,只有length属性,用于获取数组长度。字符串有length()方法,没有length属性。集合有size()方法获取元素个数。21.break、continue、return的区别?break用于跳出当前循环或switch语句,终止循环执行。continue用于跳过本次循环剩余代码,直接进入下一次循环。return用于结束当前方法,返回方法结果,直接退出方法,终止所有后续代码执行。22.Java异常体系结构?所有异常父类是Throwable,分为Error和Exception。Error是系统级严重错误,如OOM、栈溢出,程序无法处理,直接崩溃。Exception是可处理异常,分为运行时异常(RuntimeException)和编译时异常。运行时异常无需主动捕获,如空指针、数组越界;编译时异常必须捕获或抛出,否则编译报错,如IO异常、文件异常。23.运行时异常和编译时异常的区别?编译时异常(受检异常):继承Exception,不处理编译报错,必须try-catch捕获或throws抛出,用于处理可预期的外部异常,如文件不存在、网络异常。运行时异常(非受检异常):继承RuntimeException,编译不报错,运行才抛出,多为代码逻辑问题导致,如空指针、类型转换异常,可处理可不处理。24.try-catch-finally中return的执行顺序?如果try中有return,会先执行try中return前的代码,再执行finally代码块,最后执行return返回结果。如果finally中也有return,会覆盖try中的返回值,直接返回finally的结果,开发中禁止在finally中写return,会掩盖异常、造成逻辑混乱。25.常见的运行时异常有哪些?NullPointerException空指针异常、ArrayIndexOutOfBoundsException数组下标越界异常、ClassCastException类型转换异常、IllegalArgumentException参数非法异常、ArithmeticException算术异常、IndexOutOfBoundsException索引越界异常。26.throw和throws的区别?throws用在方法声明上,表示方法声明抛出异常,告知调用者该方法可能出现异常,支持声明多个异常。throw用在方法内部,表示手动抛出具体异常对象,主动触发异常,一次只能抛一个异常。27.异常处理的最佳实践?尽量精准捕获异常,不要直接捕获Exception;禁止空catch块,必须记录日志;不要在循环中频繁try-catch;优先捕获具体异常,最后捕获全局异常;finally中统一释放资源;业务异常自定义异常,区分系统异常和业务异常。28.自定义异常的使用场景?系统自带异常无法满足业务需求时使用,比如账号不存在、密码错误、权限不足、参数校验失败等业务场景。自定义异常可以统一异常格式、精准区分异常类型、方便全局异常统一处理,提升项目规范性。29.Java的四种访问修饰符权限范围?private(私有的):仅本类可见;default(默认,不写修饰符):本类、同包可见;protected(受保护的):本类、同包、不同包子类可见;public(公共的):所有类可见。权限范围从小到大:private<default<protected<public。30.接口的默认方法和静态方法区别?JDK1.8新增。默认方法用default修饰,需要接口实现类对象调用,实现类可以重写,解决接口升级兼容问题。静态方法用static修饰,通过接口名直接调用,属于接口本身,实现类不能重写、不能继承。31.内部类的分类和特点?分为成员内部类、静态内部类、局部内部类、匿名内部类。成员内部类依赖外部类对象,可访问外部类所有成员;静态内部类不依赖外部类,只能访问外部类静态成员;局部内部类定义在方法内,仅当前方法有效;匿名内部类无类名,用于快速创建接口/抽象类实例,简化代码。32.匿名内部类和Lambda表达式的关系?Lambda表达式是JDK1.8推出的语法糖,用于简化函数式接口的匿名内部类写法。函数式接口指仅有一个抽象方法的接口,Lambda可以替代匿名内部类的冗余代码,让代码更简洁,本质还是创建接口实例。33.函数式接口是什么?常用函数式接口?仅有一个抽象方法的接口,可使用Lambda表达式简化实现。常用核心接口:Consumer消费型(无返回值)、Supplier供给型(无参数有返回值)、Function函数型(有参数有返回值)、Predicate断言型(返回布尔值)。34.Java泛型的作用和原理?泛型是参数化类型,编译期类型校验,避免类型转换异常,提升代码复用性、安全性。原理是泛型擦除,编译时校验类型,编译后擦除泛型信息,运行期没有泛型,所有泛型类型都会转为原始类型,因此泛型不支持基本类型。35.泛型通配符?和extends、super区别??代表任意通配符,匹配任意类型。?extendsT上限通配符,代表T及T的子类,只能读不能写。?superT下限通配符,代表T及T的父类,只能写不能读。开发中遵循PECS原则:生产者用extends,消费者用super。36.序列化和反序列化是什么?序列化是将Java对象转为字节序列的过程,用于网络传输、文件持久化。反序列化是将字节序列还原为Java对象的过程。Java对象需要实现Serializable接口才能序列化,该接口是标记接口,无任何抽象方法。37.transient关键字的作用?被transient修饰的成员变量,不会参与序列化过程,序列化后该字段值为默认值。常用于临时字段、敏感数据(密码、密钥),避免敏感信息被序列化传输或存储。38.serialVersionUID的作用?序列化版本号,用于验证序列化对象和当前类的版本是否一致。手动定义固定版本号,可以避免类轻微修改(新增普通字段、方法)后,旧序列化数据无法反序列化的问题。如果不手动定义,JDK会自动生成,类修改后版本号改变,反序列化会报错。39.深浅拷贝的区别?浅拷贝:仅拷贝基本类型数值,引用类型只拷贝内存地址,新旧对象共享同一个引用对象,修改引用数据会互相影响。深拷贝:完全拷贝所有数据,基本类型复制数值,引用类型新建对象复制内容,新旧对象完全独立,修改互不影响。实现方式:重写clone方法、序列化、手动赋值。40.Java值传递和引用传递?Java只有值传递,没有引用传递。基本类型传递的是数值副本,方法内修改不影响原数据。引用类型传递的是对象地址副本,方法内修改对象内容会影响原对象,修改地址引用不会影响原对象。41.枚举的特点和使用场景?枚举是固定常量集合,线程安全、单例、防篡改。底层是继承Enum的类,常量都是静态常量对象。适用于状态固定的场景:订单状态、支付状态、性别、季节、权限类型等,替代静态常量,可读性和安全性更高。42.枚举能不能被继承?不能,枚举类默认被final修饰,无法被继承。枚举的构造方法默认私有,无法外部实例化,所有枚举常量都是类内部预先创建的单例对象。43.Java8新特性有哪些?Lambda表达式、函数式接口、Stream流式编程、LocalDateTime全新时间类、接口默认/静态方法、Optional空值处理、重复注解、并行流、HashMap底层优化、元空间替代永久代。44.Optional的作用?常用方法?用于解决空指针异常问题,优雅处理空值。常用方法:ofNullable(包装可为空对象)、isPresent(判断非空)、ifPresent(非空执行逻辑)、orElse(为空返回默认值)、orElseGet(为空执行函数)、map(值转换)。45.Stream流的优缺点?优点:代码简洁、链式编程、支持并行计算、简化集合遍历和数据处理。缺点:调试困难、过度使用会降低代码可读性、简单循环场景性能略低于普通for循环、并行流需注意线程安全。46.Stream流的常用操作?创建流:集合.stream()、数组转流。中间操作(延迟执行):filter过滤、map映射、sorted排序、distinct去重、limit截断、skip跳过。终止操作(触发执行):forEach遍历、collect收集、count统计、max/min最值、anyMatch匹配。47.新旧时间类的区别?旧的Date、Calendar可变、线程不安全、API繁琐、月份从0开始计算。新的LocalDate、LocalTime、LocalDateTime、Instant不可变、线程安全、API简洁易懂、时区分离、支持精准时间计算,推荐项目统一使用新时间类。48.注解的作用和分类?注解是代码标记,用于替代xml配置、简化代码、实现声明式编程。分为内置注解(Override、Deprecated、SuppressWarnings)、元注解(修饰注解的注解)、自定义注解。元注解包含:Target(作用位置)、Retention(保留周期)、Documented(生成文档)、Inherited(可继承)。49.注解的保留周期?SOURCE:源码阶段保留,编译后丢弃,仅做编译校验;CLASS:编译阶段保留,运行期丢弃,默认级别;RUNTIME:运行期保留,可通过反射获取注解信息,框架开发常用。50.反射的原理和作用?反射是运行期获取类的完整信息(构造方法、成员变量、方法),并动态调用的机制。原理:类加载后会生成Class对象,存储类的所有元数据。作用:框架底层核心(SpringIOC、AOP)、动态创建对象、动态调用方法、注解解析、通用工具类封装。51.反射的优缺点?优点:灵活性极高,运行期动态操作类和对象,适配各种通用场景。缺点:破坏封装性、性能低于直接调用、跳过编译期校验,容易引发运行时异常,日常业务代码尽量少用。52.如何获取Class对象的三种方式?1.类名.class,静态获取,无需创建对象;2.对象.getClass(),通过实例对象获取;3.Class.forName("全类名"),动态加载类,最常用,可用于加载外部类。53.反射能不能修改final修饰的变量?可以。通过反射获取字段对象,关闭访问权限校验,再修改值。但如果是编译期常量(finalstatic基本类型/字符串常量),编译器会常量折叠,反射修改后外部取值还是原值,无法真正修改。54.什么是常量折叠?编译期优化机制,对于final修饰的基本类型和字符串常量,编译器会直接将变量替换为对应数值,运行期不再读取变量值,提升程序运行效率。这也是反射无法修改编译期常量的核心原因。55.Java语法糖有哪些?语法糖是简化代码的语法,编译后会还原为基础语法,不改变运行逻辑。常见:自动装箱拆箱、泛型、for增强循环、Lambda表达式、try-with-resources资源自动关闭、字符串拼接、可变参数、注解。56.try-with-resources的作用?JDK7新特性,用于自动关闭实现AutoCloseable接口的资源(流、连接、会话),无需手动在finally中关闭,代码更简洁,同时避免资源泄漏,资源会在try代码块执行完毕后自动关闭。57.可变参数的特点?格式:参数类型...参数名,本质是数组。可以接收0个或多个对应类型参数,方法参数列表中可变参数必须放在最后,一个方法只能有一个可变参数,支持数组传入。58.内部类可以用哪些修饰符?成员内部类:可以用public、private、protected、static、final修饰。局部内部类:只能用final修饰。顶级类只能用public、default、final修饰,不能用private、protected、static。59.super和this的区别?this代表当前对象,调用本类属性、方法、构造方法。super代表父类对象,调用父类属性、方法、构造方法。this()、super()必须放在构造方法第一行,且不能同时使用。60.子类构造方法默认调用父类无参构造?是的。子类所有构造方法默认第一行都会隐式调用super(),执行父类无参构造。如果父类没有无参构造,且子类没有手动调用父类有参构造,会编译报错。因此实体类一般建议手动定义无参构造。61.多态的实现条件?三个条件:1.存在继承关系;2.子类重写父类方法;3.父类引用指向子类对象。运行时根据实际对象类型执行对应重写方法,实现动态多态。62.向上转型和向下转型?向上转型:子类对象赋值给父类引用,自动转换,安全,只能调用父类方法和子类重写方法,丢失子类独有方法。向下转型:父类引用强制转为子类类型,不安全,可能报类型转换异常,转型前建议用instanceof判断类型。63.instanceof关键字作用?用于判断对象是否是某个类或接口的实例,返回布尔值。向下转型前必须使用instanceof校验,避免ClassCastException类型转换异常。64.静态代码块、构造代码块、构造方法执行顺序?父类静态代码块→子类静态代码块(仅类加载执行一次)→父类构造代码块→父类构造方法→子类构造代码块→子类构造方法(每次创建对象执行)。65.接口能不能有构造方法?不能。接口是行为规范,不能实例化,不需要构造方法。抽象类可以有构造方法,用于子类初始化父类成员。66.抽象类可以有静态方法吗?可以。抽象类可以包含静态方法、普通方法、抽象方法、成员变量、静态变量、构造方法。静态方法属于类,不需要实例化,和类是否抽象无关。67.重写方法的返回值要求?JDK5之后支持协变返回,子类重写方法的返回值可以是父类返回值的子类类型。基础要求:返回值范围必须小于等于父类,不能扩大。68.重写方法的异常要求?子类重写方法抛出的受检异常,必须是父类方法异常的子类、或者不抛异常、或者抛出更少的异常,不能抛出更广的受检异常。运行时异常无限制。69.字符型char能不能存中文?可以。char占2字节,Java使用Unicode编码,单个char可以存储一个中文字符。70.float和double的精度问题?浮点型基于二进制存储,无法精准表示所有十进制小数,会存在精度丢失。比如0.1+0.2≠0.3。金融场景禁止使用float、double,必须使用BigDecimal进行精确运算。71.BigDecimal的使用注意事项?创建对象优先用字符串构造,避免浮点精度丢失;运算必须调用add、subtract、multiply、divide方法,不能用运算符;除法必须指定保留小数位数和舍入模式,防止除不尽报错;比较数值用compareTo,不要用equals。72.位运算符的使用场景?位运算直接操作二进制,效率极高。常用场景:奇偶判断(a&1)、数值交换、权限位标记、取模运算、扩容计算、状态标识。73.&&和&、||和|的区别?&&和||是短路逻辑运算符,前面条件成立/不成立时,后面代码不执行,效率高,日常开发常用。&和|是非短路运算符,无论前面条件结果如何,后面代码都会执行,可用于位运算和逻辑运算。74.数组的特点?数组是固定长度、连续内存空间、存储同类型数据的容器。长度一旦定义不可修改,支持下标快速访问,查询效率高,增删效率低,可存储基本类型和引用类型。75.可变参数和数组的区别?可变参数底层是数组,语法更灵活,调用时可直接传多个参数,无需创建数组。数组调用必须传入数组对象。可变参数必须位于参数列表末尾,数组无位置限制。76.断言的作用?生产环境使用吗?断言用于代码调试阶段校验条件,条件不成立抛出异常。生产环境默认关闭断言,且禁止使用断言做业务校验,仅用于开发自测。77.native关键字的作用?native修饰本地方法,方法无实现体,由C/C++语言实现,Java调用底层系统资源。常见:Object的hashCode、clone、wait方法,IO、线程底层方法大量使用native。78.strictfp关键字作用?用于严格浮点精度计算,保证不同平台浮点运算结果一致,避免系统差异导致精度偏差,金融、科学计算场景偶尔使用。79.synchronized能不能修饰静态方法?可以。修饰静态方法锁的是类对象,所有对象共用一把锁,属于全局锁。修饰普通方法锁的是当前实例对象,不同对象互不影响。80.代码块的分类?普通代码块(方法内)、构造代码块(类中{})、静态代码块(static{})、同步代码块(synchronized{})。构造代码块创建对象执行,静态代码块类加载执行一次。第二部分:Java集合(81-140题)81.Java集合体系架构?核心分为Collection单列集合、Map双列集合。Collection下三大子接口:List(有序可重复)、Set(无序不可重复)、Queue(队列)。List实现类:ArrayList、LinkedList、Vector。Set实现类:HashSet、LinkedHashSet、TreeSet。Map实现类:HashMap、LinkedHashMap、TreeMap、HashTable。82.List、Set、Map的区别?List:有序、可重复、支持下标访问。Set:无序、不可重复、无下标。Map:键值对存储,键唯一、值可重复,无序,无下标。83.ArrayList和LinkedList的区别?ArrayList底层是动态数组,查询快、增删慢,支持随机访问,线程不安全,默认初始容量10,扩容1.5倍。LinkedList底层是双向链表,查询慢、首尾增删快,不支持随机访问,线程不安全,适合频繁增删场景。84.ArrayList的扩容机制?JDK1.8ArrayList默认空参创建是空数组,首次添加元素初始化容量10。当元素个数达到容量上限时,触发扩容,新容量=原容量+原容量/2(1.5倍扩容),扩容后复制原数组元素到新数组,底层调用Arrays.copyOf实现。85.ArrayList和Vector的区别?Vector是古老集合,线程安全(方法加synchronized),效率低,扩容2倍。ArrayList线程不安全,效率高,扩容1.5倍。日常开发全部使用ArrayList,不使用Vector。86.为什么ArrayList线程不安全?多线程同时add元素时,会出现覆盖写入、元素丢失、数组越界问题。1.多个线程同时判断容量充足,同时写入覆盖;2.同时扩容导致数组下标异常。线程安全场景推荐CopyOnWriteArrayList。87.CopyOnWriteArrayList原理?写时复制机制。增删改操作时,先复制原数组生成新数组,在新数组上修改,修改完成后替换原数组。读操作直接读原数组,读写分离,读无锁、写加锁,适合读多写少场景,缺点是占用内存高、写操作慢。88.HashSet的去重原理?HashSet底层基于HashMap实现,存储元素时,先调用对象hashCode()计算哈希值,确定存储位置;如果位置无元素直接存入;如果有元素,调用equals()比较内容,内容相同则去重,内容不同则链表挂载。去重必须同时重写hashCode和equals方法。89.hashCode和equals的关联?规范:两个对象equals相等,hashCode必须相等;hashCode相等,对象不一定equals相等。集合去重依赖该规则,只重写equals不重写hashCode,会导致相同内容对象hash值不同,无法去重,出现重复元素。90.TreeSet的排序原理?TreeSet底层是TreeMap,基于红黑树实现,可自然排序。元素实体类实现Comparable接口重写compareTo方法,或者创建集合时传入Comparator比较器,根据返回值正负判断排序顺序,元素不可重复、有序。91.HashSet、LinkedHashSet、TreeSet区别?HashSet:无序、去重、查询快。LinkedHashSet:有序(插入顺序)、去重、性能略低于HashSet。TreeSet:自然排序、去重、基于红黑树,查询速度稍慢。92.HashMap底层原理(JDK1.8)?底层是数组+链表+红黑树。默认容量16,负载因子0.75,阈值12。元素通过哈希算法定位数组下标,下标位置元素少则链表存储,链表长度≥8且数组容量≥64时转为红黑树;红黑树节点≤6时退化为链表。核心作用:解决哈希冲突,平衡查询和写入效率。93.为什么负载因子是0.75?负载因子是扩容阈值系数。0.75是时间和空间的平衡值。过小:频繁扩容、浪费空间;过大:哈希冲突增多、链表过长、查询效率降低。0.75能最大程度减少哈希冲突,保证性能最优。94.HashMap为什么线程不安全?多线程put数据会导致数据覆盖;JDK1.7扩容存在链表闭环死循环、数据丢失问题;JDK1.8解决了死循环,但仍存在数据覆盖、元素丢失问题。并发场景推荐ConcurrentHashMap。95.JDK1.7和1.8HashMap的区别?1.7底层数组+链表,无红黑树,链表头插法,扩容易死循环,扩容阈值固定。1.8底层数组+链表+红黑树,链表尾插法,解决死循环问题,链表长度8转树,6退链表,优化哈希算法,性能更高。96.HashMap的key能不能为null?value能不能为null?key可以为null,且只能有一个null键,null键固定存储在数组下标0位置。value可以为null,允许多个value为null。HashTable的key和value都不能为null。97.HashMap和HashTable的区别?HashTable线程安全、效率低、不允许null键值、默认容量11、扩容2倍+1。HashMap线程不安全、效率高、允许null键值、默认容量16、扩容2倍。HashTable基本废弃,并发场景用ConcurrentHashMap。98.LinkedHashMap的特点和使用场景?继承HashMap,底层额外维护双向链表,保证插入顺序或访问顺序有序。支持LRU缓存策略,适合实现本地缓存、有序键值对存储场景。99.TreeMap的原理和特点?底层红黑树,按键自然排序或自定义排序,key不可为null,线程不安全,查询、插入、删除效率稳定,适合需要排序的键值对场景。100.ConcurrentHashMap底层原理(JDK1.8)?底层数组+链表+红黑树,采用CAS+synchronized实现并发安全,摒弃1.7分段锁。锁粒度细化到数组节点,只锁定当前操作下标位置,不影响其他位置读写,并发效率极高。默认容量16,负载因子0.75,支持高并发读写。101.ConcurrentHashMap为什么key、value不能为null?并发场景下无法区分key/value为null是不存在还是主动存入null,会产生歧义,导致并发逻辑异常,因此直接禁止null键值。102.集合遍历方式有哪些?普通for循环、增强for循环、迭代器Iterator、Stream遍历、forEach方法。增强for底层基于迭代器,适合快速遍历,不支持增删;迭代器支持遍历中安全删除元素。103.迭代器遍历为什么不能用集合remove?会触发并发修改异常ConcurrentModificationException。集合增删会修改modCount变量,迭代器遍历会校验modCount和expectedModCount,不一致直接报错。遍历删除必须用迭代器自身的remove方法。104.并发修改异常产生原因?迭代器遍历集合时,集合结构被修改(增删元素),导致迭代器预期修改次数和实际次数不匹配。单线程遍历增删、多线程同时操作集合都会触发该异常。105.Queue队列常用实现类?ArrayDeque:数组实现的双端队列,效率高,非阻塞。LinkedList:链表队列。PriorityQueue:优先级队列,自动排序。阻塞队列:ArrayBlockingQueue、LinkedBlockingQueue,用于线程池、消息队列场景。106.ArrayDeque和LinkedList区别?ArrayDeque基于数组,头尾操作效率更高,无扩容开销,不支持null元素。LinkedList基于链表,支持任意位置增删,内存占用更高。队列、栈场景优先用ArrayDeque。107.Stack栈的特点?为什么不推荐使用?后进先出,线程安全、效率低,继承Vector,设计老旧。官方推荐用ArrayDeque模拟栈,性能更高、设计更合理。108.优先级队列PriorityQueue原理?底层最小堆结构,默认自然升序排序,可自定义比较器,每次取出优先级最高(最小/最大)的元素,适合任务优先级调度场景。109.集合工具类Collections常用方法?sort排序、reverse反转、shuffle打乱、max/min最值、empty空集合、synchronizedxxx线程安全集合、unmodifiablexxx不可修改集合。110.不可变集合的作用?创建后无法增删改,只能查询,线程安全、防止数据被篡改,适合常量数据、全局配置数据存储,JDK9支持of()快速创建不可变集合。111.HashMap初始化容量设置最佳实践?预估元素个数,初始化容量设置为【预估个数/0.75+1】,且尽量为2的幂次,避免频繁扩容、减少哈希冲突,提升性能。比如存100个元素,初始化容量设为128。112.为什么HashMap容量必须是2的幂次?哈希取模优化,用位运算替代取模运算(hash&(cap-1)),效率极高。同时保证哈希分布均匀,减少冲突。非2的幂次会导致哈希分布不均,大量元素扎堆。113.红黑树的特性?1.节点非黑即红;2.根节点黑色;3.叶子节点黑色;4.红色节点的子节点都是黑色;5.任意节点到叶子节点的所有路径黑色节点个数相同。保证最长路径不超过最短路径2倍,平衡二叉树,查询效率稳定。114.HashMap树化和退化条件?树化:链表长度≥8且数组容量≥64,转为红黑树。退化:红黑树节点数量≤6,退化为链表。中间7、8节点为缓冲区间,避免频繁树
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 关于付款方式的明确告知8篇
- 需求2026年产品更新计划的讨论函8篇范文
- T/SXJP 039-2023钢化类汽车用安全玻璃
- T/SWSTA 0006-2022住宅二次供水智慧化建设与运行维护技术规程
- 关于维护渠道关系的通知函3篇
- T/GFQX 30103-2023舰船燃气轮机涡轮冷却叶片冷效试验工况模拟法
- 煤层气勘探工作方案
- 智能经济+金融科技应用分析报告
- 机电行业的案例分析报告
- 具身智能+空间站维护外勤机器人方案
- 2026年血气分析采样护理方案
- 小学二年级道德与法治统编版上册《欢欢喜喜庆国庆》教学设计
- 2026年地产运营AI 解决方案合同
- 邀请招标文件
- 2026年金属非金属矿山(地下矿山)安全管理人员考试试题及答案(完整版)
- 2027年高考历史一轮复习:必修《中外历史纲要(上)》全册知识点考点提纲
- 学史方法(一)如何建立历史的纵向联系 课件(内嵌视频 )2025-2026学年统编版八年级历史下册
- GB/T 47111-2026公园城市建设评价指南
- 船厂看火监护制度规范
- 手术消毒铺单知识
- 2025年文山州遴选公务员笔试真题汇编带答案解析
评论
0/150
提交评论