重生——第七次面试2026.8.6成都分部一面当场OC

📅 2026/8/9 1:47:34
重生——第七次面试2026.8.6成都分部一面当场OC
1、与equals()区别1属于运算符分两种场景基本数据类型byte/short/int/long/float/double/char/boolean直接比较数值是否相等引用数据类型对象、数组、包装类比较栈中保存的对象地址值判断是不是同一个堆内存对象。int a10,b10; ab → true String s1new String(abc),s2new String(abc); s1s2 → false地址不同2equals()Object中原生定义的实例方法默认实现就是return this obj本质依旧比较地址 只有重写之后才会比较对象内容String、Integer、Date等 JDK 内置类都重写了equals比对内部数据自定义实体类如果不重写调用 equals 依旧等价于规范比较常量放前面“abc”.equals(str)避免空指针。核心总结基本类型比值引用类型比地址equals原生比地址重写后比业务内容。2、方法重载OverloadVS 方法重写Override1重载同一个类内方法名相同参数列表不同核心编译期静态绑定满足条件同类中方法名完全一致参数个数、类型、顺序至少一处不一样返回值、修饰符、异常抛出不参与重载判定 作用同一行为适配不同入参比如println()支持各种类型入参。public void test(){} public void test(int a){} // 合法重载2重写子类重写父类继承的方法核心运行期动态绑定多态核心约束里氏替换原则父子类关系方法名、参数列表、返回值协变必须一致子类访问权限不能严于父类父类 public子类不能改成 private子类抛出受检异常不能比父类更大static/final/private方法不能重写 作用子类个性化实现父类抽象 / 通用逻辑。简明对比维度重载重写位置同一个类父子类方法名必须一致必须一致参数必须不同必须完全一致绑定时机编译期运行期关键字无常搭配 Override 注解校验3、遍历集合时能否直接删除元素1普通 for 循环下标遍历ArrayList可以直接remove(index)但下标会自动收缩容易漏删元素 例遍历删偶数下标元素删除后后续元素前移下一轮下标跳过数据。2增强 for 循环foreach底层基于迭代器Iterator遍历中直接调用集合自身remove()会触发并发修改异常ConcurrentModificationException。 原因集合维护modCount修改计数器迭代器初始化记录expectedModCount新增 / 删除会修改 modCount迭代时校验不一致直接抛异常。3正确安全删除方案Iterator 迭代器自身的 remove ()同步更新expectedModCount不会报错IteratorString it list.iterator(); while(it.hasNext()){ String s it.next(); if(条件) it.remove(); }JDK8removeIf()底层迭代器实现简洁安全新建集合保存需要保留的数据遍历完毕替换原集合。结论禁止 foreach 内直接集合 remove迭代器自带 remove、removeIf 是标准安全写法。4、静态方法不能直接访问非静态属性 / 方法的原因加载时机不同静态资源static 变量、静态方法在类加载阶段就初始化依托类本身 非静态成员属于实例对象必须new出对象后堆内存分配完成才存在。 类加载时还没有任何实例静态方法不知道要访问哪一个对象的成员变量。调用主体不同静态方法调用类名.静态方法()没有隐含的this指针 实例方法内部默认携带this引用指向当前调用的对象访问成员靠this.属性 静态方法没有this找不到对应的实例对象自然无法直接拿实例属性。解决方案在静态方法中手动创建实例对象通过对象引用访问非静态资源。5、Java 实例对象加载与销毁完整生命周期一、对象创建加载→初始化类加载阶段加载.class 文件、验证、准备静态变量赋默认值、解析、初始化执行静态代码块、静态变量赋值分配堆内存new 关键字在堆开辟内存所有实例变量赋予默认初始值int0、引用 null执行父类构造器递归向上执行父类构造方法实例变量显式赋值、实例代码块执行执行当前类构造方法栈中引用变量指向堆内对象对象创建完成。二、对象销毁GC 回收判定可回收对象不存在任何有效强引用引用置空、引用超出作用域、容器移除引用标记阶段GC 通过可达性分析判断该对象不在 GC Roots 引用链中标记为待回收可选执行 finalize ()该方法只会执行一次不建议依赖此方法释放资源清理回收分代回收年轻代 S0/S1、老年代标记复制 / 标记整理清除堆内存内存归还给 JVM 堆。补充程序员无法手动立刻销毁对象只能切断引用由 JVM 垃圾回收器自主调度回收。6、局部变量、实例变量、静态变量多线程安全问题1三类变量存储位置局部变量栈帧中每个线程私有栈线程之间完全隔离实例变量堆内存对象内多个线程拿到同一个对象操作时共享静态变量方法区全局唯一所有线程共享。线程安全风险局部变量天生线程安全每个线程执行方法时创建独立栈变量不存在共享竞争无并发问题。注意如果局部变量持有共享对象引用如 ArrayList并发操作这个共享对象依然不安全。实例变量多线程共用同一个实例则不安全单例 BeanSpring 默认单例中的实例成员变量多线程请求会并发读写出现数据脏读、覆盖。静态变量全局共享并发竞争最严重全局唯一所有线程共用读写不加控制一定会线程不安全。保证线程安全常用方案尽量使用局部变量避免在单例类定义成员变量加锁synchronized同步锁、ReentrantLock显式锁并发工具类Atomic原子类数值、ConcurrentHashMap、CopyOnWriteArrayListThreadLocal线程私有副本每个线程独有一份数据不可变对象String、Integer天然安全读写分离、CAS 乐观锁、分布式锁分布式场景。7、设计模式 策略模式详解一、设计模式总览分为三大类创建型单例、工厂、建造者、原型解决对象创建结构型适配器、装饰器、代理、组合、外观组装对象结构行为型策略、观察者、责任链、模板方法、状态处理对象交互逻辑。二、策略模式Strategy核心思想把一系列可互换的算法 / 业务规则封装成独立策略类统一接口运行时动态切换策略消除大量if-else/switch。组成角色策略接口 Strategy定义统一执行规范具体策略实现类不同分支业务各自实现接口上下文 Context持有策略引用对外统一入口负责调度执行策略。适用场景大量 if else 区分不同业务规则支付方式微信 / 支付宝 / 银行卡、优惠策略满减、折扣、优惠券、文件解析策略算法需要频繁动态切换便于后续新增策略开闭原则新增策略只需新增实现类不用修改原有代码。简单示例// 策略接口 public interface PayStrategy { void pay(BigDecimal money); } // 支付宝、微信各自实现PayStrategy // Context统一调用运行时注入不同策略优点去掉臃肿分支判断、代码解耦、易扩展、单元测试方便 缺点策略类数量会增多。8、接口限流单用户 1 分钟最多 100 次 多接口限流优化方案 1单机限流常用实现计数器固定窗口Redis keylimit:userId:接口名value 访问次数key 过期时间 60s每次请求 incr超过 100 直接拒绝。 缺陷窗口临界点会出现瞬间双倍流量临界突刺。滑动窗口Redis ZSet记录一分钟内所有请求时间戳每次删除一分钟前数据统计剩余数量精准平滑限流。令牌桶 / 漏桶令牌桶匀速生成令牌请求拿到令牌才放行支持突发流量适合后端接口限流Guava RateLimiter 单机令牌桶。分布式推荐Redis Lua 脚本保证计数判断 自增原子化避免并发超量 key 设计rate_limit:{userId}:{interfaceKey}过期 60s。多接口统一限流优化方案统一限流组件封装自定义注解RateLimit(limit100,time60)AOP 切面拦截所有接口注解配置不同接口限流阈值统一校验逻辑分层限流网关层Gateway/Nginx做粗粒度全局限流应用层做精细化用户维度限流网关拦截无效流量减轻服务压力Redis key 统一命名规范区分用户、接口、应用统一前缀方便运维监控统计限流配置热更新将阈值存入 Nacos/Apollo 配置中心不用重启服务动态修改限流次数降级兜底限流触发后返回友好提示也可开启降级走缓存默认数据拒绝无效重试。9、项目中分布式锁、声明式事务Transactional、三级缓存、循环依赖实战拆解1分布式锁业务场景集群部署下防止超卖、重复下单、定时任务重复执行。 主流方案Redis 分布式锁SETNXEXPIRE推荐 Redisson解决死锁、锁续期、可重入、防羊群效应Zookeeper 临时节点Mysql 乐观锁版本号机制。 要点可重入、防死锁、锁失效自动续期、避免长时间占用锁。2声明式事务 Transactional底层 AOP 动态代理生效只有 public 方法调用才生效失效经典场景同类方法内部调用this.xxx () 不走代理非 public 方法、try-catch 吃掉异常不抛出多线程、传播行为配置错误事务传播机制、隔离级别、回滚规则默认只回滚 RuntimeException实操复杂业务手动控制事务边界大事务拆分避免锁持有太久。3三级缓存本地缓存Caffeine Redis DB访问优先级本地缓存 → Redis 分布式缓存 → MySQL 数据库CaffeineJVM 堆内高性能本地缓存访问最快减轻 Redis 压力Redis分布式共享缓存保证集群数据统一MySQL 持久层 解决缓存穿透、击穿、雪崩布隆过滤器、互斥锁、热点数据永不过期、过期时间打散。 流程查询先查本地缓存无则查 Redis还无查 DB回写两级缓存。4Spring 循环依赖场景A 依赖 BB 又依赖 ASpring 三级缓存解决一级缓存完整初始化好的单例 Bean二级缓存实例化完成但未注入属性的半成品 Bean三级缓存Bean 工厂用于生成 AOP 代理对象原理先实例化 A 放入三级缓存注入 A 时需要 B实例化 BB 注入 A 时从三级缓存拿到 A 的早期引用完成注入最后 A 完整初始化移入一级缓存无法解决构造器注入的循环依赖。10、Vibe Coding 提升开发效率解决的实际问题Vibe Coding 定位AI 驱动的智能编码助手深度集成 IDE依托上下文理解项目结构、代码规范、业务上下文自动化编码工作。实际落地价值CRUD 模板一键生成根据数据库表结构自动生成 Entity、Mapper、Service、Controller 基础代码省去重复搬运代码时间复杂逻辑思路拆解 代码实现复杂工具类、正则、日期处理、集合流转换、Redis 工具方法口述需求直接产出可运行代码BUG 定位与修复粘贴异常堆栈、报错代码AI 分析空指针、索引越界、事务失效、并发安全问题给出修复方案单元测试编写自动生成 JUnit 单元测试、Mock 测试用例提升代码覆盖率注释、代码重构、规范优化老旧杂乱代码格式化、抽取工具方法、优化 if 嵌套、遵循项目统一编码规范学习攻坚陌生技术RabbitMQ、RAG、SpringAI快速写 Demo 验证快速踩坑验证方案可行性。总结把机械重复、低价值编码工作交给工具自己聚焦业务架构设计、难点排查、方案选型大幅缩短基础开发工时。11、抗压能力回答面试标准作答回答话术我日常开发本身会面对版本迭代赶排期、线上紧急 bug 修复、需求临时变更等高压场景已经适应高强度工作节奏面对紧急压力先梳理问题优先级线上故障优先止损拆分任务分步解决不会慌乱无序遇到瓶颈先自主排查卡壳及时同步组长沟通求助不硬扛拖延进度心态层面把压力当成技术沉淀的机会上线复盘总结问题根源优化后续开发流程避免重复踩坑长期高压会主动调节作息保证工作状态稳定不会带着负面情绪影响团队协作。12、上司分配简单基础任务如何看待正向思路作答摆正心态没有无用的任务简单任务一般是熟悉项目结构、业务流程、代码规范、团队协作模式的切入点新人阶段首要目标是熟悉整体项目快速融入团队高标准完成小事哪怕简单需求严谨自测、规范编码、做好注释、提交规范 MR让领导看到做事认真靠谱的工作态度主动复盘深挖做完之余思考这个功能为什么这么设计、有没有优化空间、相关联业务链路是什么私下主动钻研相关模块适时主动争取进阶工作熟练吃透手头工作后主动向领导同步学习进度表明希望承接复杂业务、参与需求设计、难点优化等工作循序渐进承担更多职责。杜绝消极敷衍、觉得大材小用抵触工作。13、偏向独立钻研技术还是团队沟通均衡型最优回答面试官最爱二者相辅相成分场景取舍攻克陌生技术难点、底层原理调研、个人技术深耕阶段偏向独立钻研安静梳理文档、动手写 Demo 验证先形成自己完整理解避免频繁打断同事业务需求对接、接口联调、方案评审、疑难卡点、线上问题优先高效沟通闭门造车效率极低需求理解偏差会写出错误代码卡壳超过合理时间半小时左右及时和同事、组长沟通避免卡死耽误整体进度日常习惯独立钻研打好基础工作中保持主动同步定期同步进度、疑问团队协作优先对齐信息个人成长利用业余和碎片化时间深耕技术二者兼顾。