版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
(2025年)细选道Java技术面试题并有答案(包含部分阿里和华为的面试题)1.说说Java中ArrayList和LinkedList的底层结构及适用场景?ArrayList底层基于动态数组实现,初始容量为10(JDK8后),当元素超过容量时触发扩容,扩容因子为1.5倍(新容量=旧容量+旧容量/2),通过Arrays.copyOf复制数组。支持O(1)时间的随机访问(通过索引定位),但插入/删除元素(尤其是中间位置)需要移动后续元素,时间复杂度O(n)。LinkedList底层基于双向链表(JDK1.6前为双向循环链表),每个节点保存前驱和后继指针。插入/删除元素只需修改相邻节点的指针,时间复杂度O(1)(已知节点位置时),但随机访问需要遍历链表,时间复杂度O(n)。适用场景:ArrayList适合频繁读取、少量增删的场景(如数据展示列表);LinkedList适合频繁增删、少量读取的场景(如队列、栈的实现)。阿里面试中曾考察过“高并发下ArrayList扩容导致的线程安全问题”,需注意其非线程安全特性,多线程环境建议使用CopyOnWriteArrayList。2.如何理解Java的泛型擦除?编译期和运行期泛型信息如何保留?泛型是JDK1.5引入的类型安全机制,本质是编译期的语法糖。编译时编译器会擦除所有泛型类型信息(如List<String>变为List),仅保留原始类型(RawType),但会在必要位置插入类型转换代码(如取出元素时转为String)。编译期泛型信息保留在Class文件的属性表中(通过Signature属性),可通过反射获取(如TypeVariable、ParameterizedType等接口)。运行期若泛型类型为具体类(非通配符),可通过反射获取实际类型参数(如通过getGenericSuperclass()获取父类的泛型参数)。华为面试中曾考察“自定义注解如何获取方法参数的泛型类型”,需结合Type接口和反射API实现。3.详细说明synchronized和ReentrantLock的区别及各自适用场景?synchronized是JVM层面的关键字,依赖monitor对象实现锁。JDK6后引入偏向锁、轻量级锁、自旋锁等优化,减少了线程阻塞的开销。特性包括:可重入(同一线程可多次获取同一锁)、非公平性(默认不保证等待线程的顺序)、隐式释放(同步块/方法结束自动释放)。ReentrantLock是java.util.concurrent包下的类,基于AQS(AbstractQueuedSynchronizer)实现。支持可重入、可公平/非公平(构造函数指定)、可中断(lockInterruptibly())、超时获取(tryLock(long,TimeUnit))、条件变量(Condition)等高级功能。适用场景:简单同步需求(如方法同步)用synchronized(代码简洁);需要可中断、超时、公平锁或多个条件变量时用ReentrantLock(如生产者-消费者模型中精准唤醒特定线程)。阿里面试曾问“ReentrantLock的tryLock在高并发下的性能优势”,需说明其非阻塞特性避免线程挂起/唤醒的开销。4.简述JVM类加载的全过程,双亲委派模型的作用及破坏场景?类加载过程分为加载、验证、准备、解析、初始化五个阶段:-加载:通过类加载器将class文件字节码加载到方法区,提供对应的Class对象。-验证:校验字节码格式(如魔数0xCAFEBABE)、语义(如是否继承final类)等,确保安全。-准备:为类静态变量分配内存并设置默认值(如int默认0,引用默认null),常量(staticfinal)直接赋值。-解析:将符号引用(如类名、方法名)替换为直接引用(内存地址)。-初始化:执行类构造器<clinit>()方法(静态变量赋值和静态代码块的合并),触发时机包括new对象、调用静态方法/变量(非final)、反射获取类等。双亲委派模型:类加载器(启动类、扩展类、应用类)收到加载请求时,先委托父类加载器加载,父类无法加载时再自己加载。作用是避免类重复加载(如java.lang.Object只会被启动类加载器加载一次),防止核心类被篡改(如自定义java.lang.String会被父类加载器拦截)。破坏场景:①热部署(如Tomcat):每个Web应用有独立的类加载器,允许同名类不同版本共存。②线程上下文类加载器(如JDBC):父类加载器(启动类)需要加载子类加载器(应用类)的实现类(如MySQL的Driver),通过Thread.currentThread().getContextClassLoader()打破委派。③动态代理(如ASM提供字节码):自定义类加载器直接加载提供的字节码。5.如何分析Java内存泄漏?常用工具及具体步骤?内存泄漏指对象不再被使用但未被GC回收(通常因长生命周期对象持有短生命周期对象的引用)。常见场景:缓存未设置过期时间、静态集合未清理、监听器/回调未注销、ThreadLocal未remove()。分析工具及步骤:-日志监控:通过-XX:+PrintGCDetails打印GC日志,观察FullGC频率和内存占用趋势(如老年代持续增长)。-堆转储(HeapDump):使用jmap-dump:format=b,file=heap.bin<pid>或JVM参数-XX:+HeapDumpOnOutOfMemoryError提供堆文件。-分析工具:①EclipseMAT(MemoryAnalyzerTool):通过OQL查询大对象,查看DominatorTree(对象占用内存占比),检测LeakSuspects(常见泄漏模式)。②JProfiler:可视化分析对象引用链,定位未释放的引用(如静态Map中残留的对象)。③阿里Arthas:通过heapdump命令提供堆文件,或使用ognl表达式实时查看对象数量(如ognl'map=@com.example.Cache@map,map.size()')。华为面试中曾考察“生产环境无法停机时如何快速定位内存泄漏”,需结合Arthas的在线诊断功能,通过watch命令监控关键方法的参数/返回值,或用sc/ss命令查找类的实例数量。6.详细说明Spring循环依赖的解决机制,构造器注入为何无法解决?Spring通过三级缓存解决单例Bean的循环依赖(原型Bean和构造器注入无法解决)。三级缓存定义在DefaultSingletonBeanRegistry中:-singletonObjects(一级缓存):保存已初始化完成的单例Bean。-earlySingletonObjects(二级缓存):保存已实例化但未初始化的早期Bean(用于解决AOP代理问题)。-singletonFactories(三级缓存):保存ObjectFactory(创建早期Bean的工厂,用于提供代理对象)。解决流程(以A依赖B,B依赖A为例):①创建A:调用构造器实例化A,将A的ObjectFactory(()->getEarlyBeanReference(beanName,mbd,bean))放入三级缓存。②A注入B:触发B的创建,B实例化后将其ObjectFactory放入三级缓存。③B注入A:从三级缓存获取A的ObjectFactory,提供早期A(可能是代理对象),放入二级缓存并移除三级缓存的工厂。④B完成初始化,放入一级缓存。⑤A获取B(已在一级缓存),完成初始化,放入一级缓存。构造器注入无法解决的原因:构造器注入发生在实例化阶段(Bean未创建完成),此时三级缓存中没有对应的ObjectFactory(工厂需在实例化后才创建),导致无法提前暴露早期Bean。阿里面试曾问“如果A和B都是@Async注解的Bean(需要代理),循环依赖是否仍能解决”,答案是可以,因为三级缓存的ObjectFactory会调用getEarlyBeanReference提供代理,确保早期Bean是代理对象。7.比较MySQL的InnoDB和MyISAM存储引擎的差异,生产环境如何选择?核心差异:-事务支持:InnoDB支持ACID事务(通过redo/undo日志),MyISAM不支持。-锁粒度:InnoDB支持行锁(基于索引)和表锁,MyISAM仅支持表锁(插入/更新时全表锁定)。-索引类型:InnoDB主键索引(聚簇索引)存储数据,二级索引存储主键值;MyISAM非聚簇索引,索引文件和数据文件分离。-外键支持:InnoDB支持外键约束,MyISAM不支持。-统计行数:InnoDB的COUNT()需扫描索引(或全表),MyISAM维护全局行数计数器(O(1)时间)。生产选择:-需事务、高并发写(如订单系统)选InnoDB;-只读/写少读多(如日志表、字典表)可选MyISAM(但MySQL8.0已废弃);-需外键约束(如关联表)必须选InnoDB。华为面试中曾考察“高并发下InnoDB行锁失效场景”,需注意:无索引条件更新会升级为表锁;索引字段类型不匹配(如varchar用int查询)导致全表扫描,行锁变表锁。8.分布式锁的实现方案(Redis和ZooKeeper),各自优缺点及避坑点?Redis方案:通过setkeyvalueNXEXtimeout原子命令获取锁(NX保证只有一个客户端能设置,EX防止死锁)。释放锁时需校验value(避免误删其他客户端的锁),使用Lua脚本保证原子性(ifredis.call('get',KEYS[1])==ARGV[1]thenredis.call('del',KEYS[1])end)。ZooKeeper方案:创建临时顺序节点(如/lock/seq-),客户端获取最小节点为锁持有者,其他节点监听前一节点的删除事件(避免惊群效应)。锁自动释放(会话超时或客户端断开时临时节点删除)。优缺点对比:-Redis:性能高(单节点QPS约10万),但主从切换可能导致锁丢失(未同步到从节点时主节点宕机);-ZooKeeper:强一致性(基于ZAB协议),锁可靠性高,但性能较低(QPS约1万)。避坑点:-Redis:锁超时时间需大于业务执行时间,可通过“看门狗”机制(后台线程自动续期)避免锁提前释放;-ZooKeeper:避免创建过多临时节点(影响性能),会话超时时间需合理设置(过短易误释放,过长导致死锁)。阿里面试曾问“Redlock(红锁)的争议及改进方案”,需说明Redlock假设多个独立Redis实例,通过多数派获取锁,但MartinKleppmann指出其在时钟漂移场景下不可靠,改进建议是结合租约(Lease)机制或使用ZooKeeper。9.如何设计一个高并发的秒杀系统?需考虑哪些技术点?核心设计点:-流量拦截:①前端限流:按钮防重复点击(倒计时禁用)、验证码(防止脚本刷单);②网关层:Nginx限流(limit_req/limit_conn)、用户鉴权(Token校验);③业务层:预校验(库存是否>0、用户是否已参与),减少数据库压力。-库存优化:①缓存预热:活动前将库存加载到Redis(如stock:1001=100),扣减库存用Lua脚本(保证原子性:ifredis.call('get',KEYS[1])>0thenredis.call('decr',KEYS[1])return1elsereturn0end);②数据库异步更新:缓存扣减成功后,将订单信息写入消息队列(如RocketMQ),异步落库(避免事务阻塞)。-分布式事务:订单创建、库存扣减、支付回调需保证一致性,可使用Seata的AT模式(自动提供回滚日志)或TCC模式(自定义try/confirm/cancel)。-高可用:数据库主从复制+读写分离,Redis哨兵/Cluster模式,应用层多实例部署(K8s负载均衡)。华为面试中曾考察“秒杀场景下超卖问题的解决”,关键是保证库存扣减的原子性(RedisLua脚本或数据库乐观锁:updatestocksetcount=count-1whereid=1001andcount>0)。10.说说JVM垃圾回收器的演进(JDK8到JDK17),G1和ZGC的核心区别?JDK8默认使用ParallelScavenge(新生代)+ParallelOld(老年代);JDK9默认G1;JDK11引入ZGC;JDK17移除CMS。G1(Garbage-First):-分代:逻辑分代(Region划分为Eden/Survivor/Old),物理不连续;-目标:控制停顿时间(-XX:MaxGCPauseMillis),优先回收垃圾多的Region(Garbage-First);-算法:标记-复制(新生代)、标记-整理(老年代);-停顿:STW时间可控(毫秒级),但大内存(>16GB)下效率下降。ZGC:-分代:无分代(统一Region),支持NUMA架构;-算法:标记-复制(使用颜色指针和读屏障);-停顿:STW时间<10ms(与堆大小无关,支持TB级堆);-优化:并发标记/转移/重映射,仅在初始标记和最终标记有短暂STW。核心区别:G1侧重停顿时间控制,适合大内存(4-16GB);ZGC侧重低延迟,适合超大型堆(4TB+)。阿里面试曾问“ZGC的读屏障如何实现”,需说明读屏障在访问对象引用时动态更新指针(颜色指针的Marked0/Marked1/Remapped位),避免STW期间扫描所有对象。11.MyBatis的一级缓存和二级缓存的区别,如何避免缓存击穿?一级缓存(SqlSession级):默认开启,保存在BaseExecutor的localCache中。同一SqlSession内执行相同查询(相同statementId、参数、分页)会直接返回缓存结果。SqlSession关闭/提交或执行增删改操作时缓存失效。二级缓存(Mapper级):需手动开启(<cache/>标签),保存在SqlSessionFactory层面。多个SqlSession共享缓存(需序列化对象),失效策略(LRU、FIFO)可配置。缓存击穿:热点数据缓存失效时大量请求直接查数据库。MyBatis二级缓存可通过设置合理的过期时间(flushInterval),或结合Redis等分布式缓存(MyBatis作为二级缓存的装饰器)。华为面试曾考察“MyBatis二级缓存的脏读问题”,需注意:多数据源场景下(如主从库),主库更新后从库未同步时,二级缓存可能返回旧数据,解决方案是禁用二级缓存或使用Cache-Aside模式(先更新数据库,再删除缓存)。12.详细说明TCP三次握手和四次挥手的过程,TIME_WAIT状态的作用及优化?三次握手:①客户端发送SYN=1,seq=x(连接请求);②服务器回复SYN=1,ACK=1,seq=y,ack=x+1(确认请求,同步自己的seq);③客户端发送ACK=1,seq=x+1,ack=y+1(确认服务器的确认)。四次挥手:①客户端发送FIN=1,seq=u(关闭请求);②服务器回复ACK=1,seq=v,ack=u+1(确认关闭请求,可能仍有数据发送);③服务器发送FIN=1,ACK=1,seq=w,ack=u+1(数据发送完毕,主动关闭);④客户端回复ACK=1,seq=u+1,ack=w+1(确认服务器关闭),进入TIME_WAIT状态(持续2MSL,约2-4分钟)。TIME_WAIT作用:-确保最后一次ACK到达服务器(超时则服务器重发FIN,客户端重新发送ACK);-避免旧连接的报文干扰新连接(相同IP:port的新连接不会接收之前的延迟报文)。优化(高并发服务端):-调整内核参数:net.ipv4.tcp_tw_reuse=1(允许重用TIME_WAIT连接,需时间戳开启),net.ipv4.tcp_tw_recycle=0(关闭快速回收,避免NAT环境问题);-减少TIME_WAIT数量:使用短连接(HTTP/1.1长连接更优),或调整应用层逻辑(避免频繁创建/关闭连接)。阿里面试曾问“三次握手时服务器SYN队列满的后果”,需说明会丢弃后续SYN包(或发送RST),可通过增大net.ipv4.tcp_max_syn_backlog参数或开启syncookies(net.ipv4.tcp_syncookies=1)缓解。13.如何实现一个线程安全的单例模式?双重检查锁定(DCL)为何需要volatile?饿汉式(线程安全):```javapublicclassSingleton{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnINSTANCE;}}```懒汉式(DCL):```javapublicclassSingleton{privatestaticvolatileSingletonINSTANCE;//关键:volatile禁止指令重排privateSingleton(){}publicstaticSingletongetInstance(){if(INSTANCE==null){//第一次检查,避免不必要的同步synchronized(Singleton.class){if(INSTANCE==null){//第二次检查,防止多线程同时通过第一次检查INSTANCE=newSingleton();//非原子操作:1.分配内存2.初始化对象3.引用指向内存}}}returnINSTANCE;}}```volatile的作用:禁止“INSTANCE=newSingleton()”的指令重排。若步骤2和3重排(先将引用指向未初始化的内存,再初始化对象),其他线程可能获取到未初始化的INSTANCE(此时INSTANCE!=null但对象未完成构造)。volatile通过内存屏障保证写操作的可见性和有序性。华为面试曾问“静态内部类单例是否线程安全”,答案是肯定的:JVM保证类加载的线程安全,内部类Holder在第一次调用getInstance()时加载,INSTANCE在类初始化时创建。14.解释Spring的@Transactional事务传播机制,嵌套事务如何实现?事务传播机制定义了多个事务方法调用时的事务行为,通过Propagation枚举类定义:-REQUIRED(默认):当前有事务则加入,无则创建新事务。-REQUIRES_NEW:总是创建新事务,挂起当前事务(若有)。-NESTED:嵌套在当前事务中(通过保存点SAVEPOINT实现),子事务回滚不影响父事务(但父事务回滚会导致子事务回滚)。-SUPPORTS:当前有事务则加入,无则非事务执行。-NOT_SUPPORTED:非事务执行,挂起当
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 养老院入住老人心理健康监测制度
- 企业设备维护与保养制度
- 会议报告与总结撰写制度
- 2026年金融风险管理市场风险识别与控制策略实操题库
- 2026年建筑工程结构设计与施工工艺考试题集
- 2026年新版工业同位协议
- 2026年委托消毒合同
- 山东省泰安市2025-2026学年高三上学期2月一模考试语文试题及参考答案
- 单位总值班室应急值守管理制度内容
- 2025年长江师范学院马克思主义基本原理概论期末考试模拟题附答案解析(夺冠)
- 酒店合伙人管理办法细则
- 车辆挂靠公司免责协议书
- 2025期货从业人员资格考试题库含答案
- TCCEAS001-2022建设项目工程总承包计价规范
- 2024-2025学年八年级数学开学摸底考试卷(北京专用)(解析版)
- 硅锰工艺培训
- 药流护理常规
- HGT 4205-2024《工业氧化钙》规范要求
- 原发性纤毛运动障碍综合征教学演示课件
- 月台施工方案
- 白血病医学知识培训
评论
0/150
提交评论