版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java基础知识面试题(2025年)附答案1.自动装箱与拆箱的底层实现原理是什么?Integer缓存的范围是多少?修改缓存范围的方法及注意事项有哪些?自动装箱指基本数据类型转换为对应包装类的过程,底层通过调用包装类的`valueOf()`方法实现。例如`Integeri=10`会编译为`Integeri=Integer.valueOf(10)`。拆箱则是包装类转换为基本类型,通过调用`intValue()`、`doubleValue()`等方法实现,如`intj=i`编译为`intj=Value()`。Integer缓存默认范围是-128到127,由`IntegerCache`静态内部类实现,该范围在类加载时通过`VM参数-XX:AutoBoxCacheMax=<size>`可调整上限,但下限-128不可修改。修改缓存范围需注意:若设置过大(如1000),会增加类加载时的内存占用,可能导致JVM启动变慢;且仅对自动装箱有效,显式调用`newInteger()`不会使用缓存。2.String、StringBuilder、StringBuffer的核心区别是什么?在高并发场景下拼接字符串应如何选择?String类内部使用`finalchar[]value`存储字符,具有不可变性。每次字符串拼接都会提供新的String对象,效率较低。StringBuilder继承自AbstractStringBuilder,内部使用可变的char数组(无final修饰),默认容量16,扩容时新容量为原容量2+2,拼接操作通过`append()`方法直接修改数组,无需新建对象,效率最高但非线程安全。StringBuffer与StringBuilder结构类似,但所有方法添加了`synchronized`关键字,保证线程安全,效率略低于StringBuilder。高并发场景下,若多线程频繁拼接字符串,应使用StringBuffer;若单线程或多线程但拼接操作在方法内部(无共享),优先用StringBuilder;若拼接量小且不频繁(如简单日志拼接),可直接使用String的`+`运算符(编译器会优化为StringBuilder)。3.面向对象三大特性中,继承可能带来哪些问题?组合与继承的选择原则是什么?继承的问题:①破坏封装性:子类依赖父类实现细节,父类修改可能导致子类功能异常(里氏替换原则被破坏);②紧耦合:子类与父类强关联,难以独立修改;③方法覆盖风险:子类覆盖父类方法时若未正确实现(如未调用`super.method()`),可能导致逻辑混乱。组合与继承的选择原则:优先使用组合(Has-A关系),当满足“is-a”关系且父类设计为被继承(如模板方法模式)时使用继承。例如,实现一个带日志功能的集合类,应通过组合(持有集合对象引用并添加日志方法)而非继承ArrayList,避免因ArrayList内部方法修改导致日志逻辑失效。4.简述Java异常处理中CheckedException与UncheckedException的区别,实际开发中如何设计自定义异常?CheckedException(受检异常)是Exception子类(除RuntimeException),必须显式处理(捕获或声明抛出),否则编译失败,如IOException。UncheckedException(非受检异常)是RuntimeException及其子类(如NullPointerException、IllegalArgumentException),不强制处理,通常表示程序逻辑错误。自定义异常设计原则:①受检异常用于可恢复的错误(如数据库连接失败),非受检异常用于程序逻辑错误(如参数校验失败);②继承Exception或RuntimeException,根据是否强制处理选择父类;③保留异常链(通过构造方法调用`super(message,cause)`),避免丢失原始异常信息;④异常信息应包含上下文(如出错的参数值、操作类型),便于排查。5.线程的六种状态是什么?如何让一个线程安全地终止?线程状态定义在Thread.State枚举中,包括:NEW:线程创建但未调用start();RUNNABLE:处于JVM运行中状态(可能在等待CPU时间片);BLOCKED:等待监视器锁(如synchronized同步块);WAITING:调用wait()、join()、LockSupport.park()无超时参数方法;TIMED_WAITING:调用sleep(time)、wait(time)、join(time)等带超时参数的方法;TERMINATED:线程执行完毕或异常终止。安全终止线程的方法:①使用中断机制:调用线程的interrupt()方法设置中断标志,线程内部通过isInterrupted()或捕获InterruptedException响应中断(如循环中检查标志并退出);②自定义终止标志:通过volatile变量控制循环结束(避免线程可见性问题);③避免使用stop()方法(已过时,会强制终止线程并释放锁,可能导致数据不一致)。6.线程池的核心参数有哪些?拒绝策略的类型及适用场景是什么?线程池(ThreadPoolExecutor)的核心参数:corePoolSize:核心线程数,即使空闲也不会被销毁(除非设置allowCoreThreadTimeOut为true);maximumPoolSize:最大线程数,线程池允许的最大线程数量;keepAliveTime:非核心线程空闲时的存活时间(allowCoreThreadTimeOut为true时核心线程也适用);unit:keepAliveTime的时间单位;workQueue:任务队列,存储待执行的Runnable任务(如ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue);threadFactory:线程工厂,用于创建新线程(建议自定义以设置线程名、优先级等);handler:拒绝策略,任务无法提交时的处理逻辑。拒绝策略类型及场景:AbortPolicy(默认):抛出RejectedExecutionException,适用于关键任务且希望快速感知错误的场景;CallerRunsPolicy:由调用者线程执行任务,适用于流量控制(降低提交速度);DiscardPolicy:静默丢弃最新任务,适用于允许丢失非关键任务的场景;DiscardOldestPolicy:丢弃队列中最老任务并重新提交当前任务,适用于对时效性要求高的任务(如实时统计)。7.HashMap在Java7与Java8中的实现有哪些差异?如何避免哈希冲突导致的性能下降?Java7中HashMap底层是“数组+链表”结构,Entry数组存储键值对,链表解决哈希冲突(头插法)。Java8优化为“数组+链表+红黑树”结构,当链表长度≥8且数组长度≥64时,链表转换为红黑树(时间复杂度从O(n)降至O(logn)),链表长度≤6时红黑树转回链表(避免频繁转换)。此外,Java8的哈希计算简化为`(h=key.hashCode())^(h>>>16)`(高位参与运算减少冲突),插入方式改为尾插法(避免多线程扩容时的循环链表问题)。避免哈希冲突的方法:①重写hashCode()时结合对象关键属性(如String的hashCode()基于字符序列计算),使哈希值分布均匀;②合理设置初始容量(如预计存储100个元素,初始容量设为128,避免频繁扩容);③使用不可变对象作为键(如String、Integer),防止键的hashCode()改变导致无法定位元素。8.ConcurrentHashMap在Java7与Java8中的线程安全实现有何不同?高并发下如何优化其性能?Java7的ConcurrentHashMap使用分段锁(Segment),继承ReentrantLock,默认16个Segment,每个Segment独立加锁,支持16个线程并发写。Java8弃用分段锁,采用“CAS+synchronized”机制:数组节点(Node)使用volatile修饰保证可见性;插入元素时,若节点为空则通过CAS原子操作插入;若节点非空(链表或红黑树),使用synchronized锁住该节点头元素,锁粒度更细(仅锁链表头而非整个段),并发性能更高。高并发优化:①根据业务场景调整初始容量(如预估并发量为100,初始容量设为128,减少扩容次数);②避免使用size()方法(Java8中需遍历所有节点,高并发下可能影响性能),改用mappingCount()(返回long类型,更准确);③对于读多写少场景,可使用ConcurrentSkipListMap(基于跳表,读操作时间复杂度O(logn)且无锁)。9.JVM类加载的全过程分为哪些阶段?双亲委派模型的作用及打破该模型的典型场景是什么?类加载过程分为:加载:通过类加载器将class文件字节流加载到方法区,提供对应的Class对象;链接:包含验证(检查字节码格式是否合法)、准备(为类静态变量分配内存并初始化为默认值)、解析(将符号引用替换为直接引用);初始化:执行类构造器<clinit>()方法(静态变量赋值和静态代码块执行)。双亲委派模型作用:①避免类重复加载(父类加载器已加载的类,子类加载器不再加载);②保证核心类安全(如java.lang.Object由启动类加载器加载,防止用户自定义同名类覆盖)。打破双亲委派的场景:①热部署(如OSGi动态加载类,每个Bundle有独立类加载器,可自定义加载顺序);②自定义类加载器(如Tomcat的WebappClassLoader,优先加载Web应用的类,再委托父类加载器);③服务提供者接口(SPI,如JDBC,通过ThreadContextClassLoader打破委派,由子类加载器加载实现类)。10.JVM堆内存的分代模型是怎样的?G1收集器与ZGC收集器的核心区别是什么?分代模型将堆分为新生代和老年代:新生代含Eden区、Survivor0(S0)、Survivor1(S1),默认比例8:1:1;老年代存储长期存活对象(经历多次MinorGC后仍存活)。新生代使用复制算法(Eden+S0存活对象复制到S1,交换S0/S1),老年代使用标记-整理算法(标记存活对象,整理并移动到内存一端)。G1(Garbage-First)与ZGC的区别:目标:G1目标是将停顿时间控制在100ms内,ZGC目标是10ms内(支持TB级堆);堆划分:G1将堆划分为多个大小相等的Region(约2MB-32MB),ZGC使用动态的Page(小Page2MB、中Page32MB、大PageN2MB);标记算法:G1使用SATB(快照存活),ZGC使用ColoredPointers(指针染色)和LoadBarrier(加载屏障),标记与应用线程并发执行;适用场景:G1适合大堆(几GB到几十GB)且对延迟有一定要求的场景,ZGC适合超大型堆(几十GB到几TB)且需要极低延迟的场景(如实时交易系统)。11.反射的实现原理是什么?实际开发中反射的典型应用场景及潜在问题有哪些?反射通过Class对象获取类的构造方法、字段、方法等信息,底层调用本地方法(如sun.reflect.NativeMethodAccessorImpl)实现。JVM在第一次调用反射方法时会提供字节码(通过MethodAccessor),后续调用可能切换为更快的实现(如委派模式,减少本地方法调用开销)。典型应用场景:①框架开发(如Spring通过反射注入依赖,MyBatis通过反射设置SQL参数);②动态代理(如JDKProxy通过反射调用目标方法);③通用工具类(如JSON反序列化,通过反射设置对象字段值)。潜在问题:①性能开销:反射调用比直接调用慢(约10-100倍),频繁调用影响性能(可通过缓存Method对象或使用Lombok的@Accessors优化);②破坏封装性:可访问私有字段/方法,可能导致对象状态不一致;③兼容性问题:反射依赖类的具体结构,版本升级字段名变更会导致反射代码失效。12.泛型的类型擦除是什么?为何不能创建泛型数组?如何实现泛型数组?类型擦除指编译器在编译阶段移除泛型类型信息,用原始类型(RawType)代替。例如`List<String>`擦除后变为List,所有类型参数替换为Object(若有上界则替换为上界类型,如`TextendsNumber`替换为Number)。不能创建泛型数组的原因:数组在运行时会检查元素类型(动态类型检查),而泛型类型信息已被擦除,无法在运行时验证元素类型是否匹配(如`newList<String>[10]`会编译报错)。实现泛型数组的方法:①使用`List<T>`代替数组(推荐);②通过反射创建数组(`(T[])Array.newInstance(clazz,size)`),需传入具体类型的Class对象(如`createArray(String.class,10)`),并处理类型转换警告(@SuppressWarnings("unchecked"))。13.Serializable与Externalizable的区别是什么?自定义序列化时如何控制字段的序列化行为?Serializable是标记接口(无方法),JVM默认实现序列化(将对象所有非transient、非静态字段写入流)。Externalizable继承Serializable,需实现`writeExternal(ObjectOutput)`和`readExternal(ObjectInput)`方法,完全自定义序列化逻辑(可选择序列化哪些字段)。控制序列化行为的方法:①使用transient关键字标记不序列化的字段(如密码、临时变量);②实现`writeObject(ObjectOutputStream)`和`readObject(ObjectInputStream)`方法(JVM会优先调用这两个方法,覆盖默认序列化逻辑);③对于Externalizable,通过writeExternal/readExternal精确控制序列化内容(需显式写入/读取字段)。14.Java8的Lambda表达式如何实现?StreamAPI的中间操作与终止操作的区别是什么?Lambda表达式的底层实现通过invokedynamic指令(JVM7引入的动态调用指令),运行时由LambdaMeta
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026徐州国源资源开发集团招聘1人笔试历年参考题库附带答案详解
- 《文旅电商与物流》思政-项目九:跨境文旅电商与物流中的全球视野与开放合作
- 幼儿园游戏教学反思与总结
- 预防校园欺凌主题班会课件
- xx小区物业服务合同
- 大型场馆物业管理合同
- 2026贵州安顺职业技术学院社会引进人才4人笔试参考题库及答案解析
- 内江市快递行业安全督导员招聘笔试模拟试题及答案解析
- 2026四川巴中市考核招聘省属公费师范毕业生345人考试备考题库及答案解析
- 2026上半年云南昭通市彝良县市场监督管理局招聘编外人员2人考试参考题库及答案解析
- 动力管道设计手册-第2版
- 阿那亚分析研究报告
- 杨根思连长课件完整版
- 韦氏成人智力测验(完全版)
- 城市轨道交通光缆接续作业指导书
- 直肠癌柱状切除术的临床实践与体会
- GB/T 6075.1-2012机械振动在非旋转部件上测量评价机器的振动第1部分:总则
- GB/T 15788-2017土工合成材料宽条拉伸试验方法
- GA/T 1442-2017法庭科学摹仿笔迹检验技术规程
- 基本习题及答案-量子力学
- 水利工程中鱼道设计的工程伦理思考课件
评论
0/150
提交评论