首页/新闻资讯/正文详情

Java基础面试硬核梳理:语法、集合源码、JVM与并发全攻略

发布时间:2026/9/26 6:10:35 来源:云帆数科 栏目:资讯中心
Java基础面试硬核梳理:语法、集合源码、JVM与并发全攻略
先说结论Java基础这一块重点是“语法要扎实、集合要源码级理解、JVM和并发要有画面感”。很多干了三五年的同学回去翻八股文担心的其实不是那些API记不住而是底层原理说得不够透。这篇总结我会按自己带新人、复习面试、做项目踩坑的实际经验来梳理把高频考点和平时容易忽略的细节放到一起讲适合准备校招/社招面试的人也适合刚学完Java语法想系统过一遍的人。1. 基础语法与核心API先过一遍真正重要的东西1.1 数据类型、包装类与缓存机制Java基础里最容易被问穿的就是基本类型和包装类。八种基本类型里long和double是64位其余按字节大小记就行byte(1)、short(2)、int(4)、float(4)、char(2)、boolean(理论上1位但规范没严格定义)。实际开发中我一般建议POJO属性用包装类因为基本类型有默认值0会让“未赋值”和“值为0”混在一起尤其在数据库映射场景特别容易埋雷。包装类有几个细节值得专门记Integer默认缓存-128到127这个范围内Integer a 100; Integer b 100; a b是true超出范围就是false。你用new Integer(100)则是每次新对象永远false。线上踩过的坑从Redis取Integer做比较小值正常大值偶尔出问题排查半天才发现是缓存范围。equals和的区别面试必问但真正重要的是理解比的是栈上的值基本类型比数值引用类型比地址equals默认就是但String、Integer等重写成了内容比较。浮点数不要用比较用BigDecimal。这个不是八股是实际扣过钱的教训。1.2 String、StringBuilder、StringBuffer到底怎么选这三个天天用但很多人没搞透。String是不可变的每次拼接都会产生新对象循环里用拼接字符串是性能杀手。StringBuffer是JDK1.0就有的方法加了synchronized线程安全但慢StringBuilder是JDK1.5加的线程不安全但快。日常开发99%的场景用StringBuilder只有多线程共享同一个可变字符串对象时才考虑StringBuffer。但这里有个进阶点面试官常追问String s a b和String s new String(a) new String(b)有什么区别。前者是编译期常量折叠直接变成ab后者是运行时拼接底层会new StringBuilder。还有字符串常量池a字面量会进常量池new String(a)会创建两个对象如果常量池里没有a的话。JDK7以后常量池挪到了堆里这个演进也要知道。字符串面试的终极问题往往是intern()方法的作用把字符串对象的内容尝试放进常量池如果池里有相同内容的字符串就返回池中的引用没有则加入并返回引用。理解这个再去看String s1 new String(a).intern()这类题就不慌了。1.3 数组、拷贝和边界问题数组是对象length是属性不是方法Arrays工具类提供排序、二分查找、拷贝等方法。深浅拷贝这个问题热搜里也有人问核心在于基本类型数组的clone()是深拷贝引用类型数组的clone()是浅拷贝——拷贝的是引用不是对象本身。对象深度拷贝正确姿势是实现Serializable后用序列化/反序列化或者手动逐字段拷贝别指望clone()接口那个是浅拷贝且还要重写。还有个日常高频数组坑Arrays.asList()返回的List是定长的不能add/remove它底层是直接包装数组改元素会同步到原数组。很多新人在这上面踩坑一调用add直接抛UnsupportedOperationException怀疑人生。2. 面向对象设计不是背定义而是要理解设计动机2.1 封装、继承、多态怎么讲才有深度封装最好讲成“隐藏实现细节暴露稳定接口”因为这样可以让你改内部实现时不影响调用方。做SDK或者公共组件的时候最能体会这个价值你把API设计好内部怎么重构都不怕。继承是is-a关系但强调一点继承是耦合度最高的关系之一父类一改子类就受影响。Effective Java里第一条“优先使用组合而非继承”就是这个道理。面试被问“继承有什么缺点”时别愣住要答出“破坏了封装性、子类与父类强耦合、不灵活”这些点。多态是Java面试的重头戏记住三个条件继承、重写、父类引用指向子类对象。但更有价值的理解是多态让代码面向抽象编程依赖倒置原则的落地靠的就是它。实际项目里接口加策略模式就是多态的典型应用新增一种实现不用改调用方代码。2.2 接口和抽象类的选择逻辑抽象类是模板接口是契约。从设计层面看抽象类适合“多个类有公共代码且需要共享状态”的场景接口适合“只关心能力不关心实现”的场景。Java 8以后接口可以有default方法两者的界限被模糊了但指导思想没变能用接口就别用抽象类接口更灵活一个类可以实现多个接口但只能继承一个父类。还有个常见考点抽象类可以有构造函数但不能直接实例化构造函数是给子类super()调用的接口没有构造函数。抽象类的方法可以是public、protected、default接口的方法除了static/default方法默认是public abstract。如果项目需要定义一组相关类的骨架流程可以用模板方法模式配合抽象类父类定好流程骨架子类重写步骤方法。这个在框架源码里非常常见比如Spring的AbstractApplicationContext内部就是这种思路。2.3 异常体系与try-with-resources异常分两类受检异常Checked Exception和非受检异常RuntimeException。受检异常强制你try-catch或throws比如IOException、SQLException非受检异常可以不处理比如NullPointerException、IndexOutOfBoundsException。实际工作的体会是受检异常在业务代码里容易被滥用很多人捕了异常打印一下就完事等于没处理反而掩盖问题。现代框架比如Spring大量用非受检异常包装受检异常就是为了让事务回滚更干脆。try-with-resources是JDK7引入的配合AutoCloseable接口可以自动关资源。写文件、连数据库的时候比手动finally里close干净太多而且finally里close还有个经典坑如果try块抛异常的同时finally里close也抛异常会覆盖try的异常排查起来非常痛苦。用try-with-resources就不会有这个叠加问题。3. 集合框架面试八股的重灾区也是拉开差距的分水岭3.1 ArrayList和LinkedList的底层差异ArrayList底层是Object数组默认容量10扩容是oldCapacity (oldCapacity 1)也就是1.5倍。扩容会创建新数组并拷贝所以如果预知数据量大用带初始容量的构造方法new ArrayList(10000)能省不少性能。LinkedList底层是双向链表插入删除在已知节点的情况下确实是O(1)但按索引访问是O(n)需要从头或尾遍历。实际项目中LinkedList很少用因为数组的内存连续性和缓存友好性优势太明显。面试被问“什么时候用LinkedList”标准答案是“频繁头尾插入删除”但我常年使用中除非写队列或LRU否则ArrayList始终是首选。线程安全方面这俩都不安全Vector因为所有方法加synchronized性能差基本被弃用。真正需要线程安全的List用Collections.synchronizedList()包装或者并发场景下用CopyOnWriteArrayList。3.2 HashMap从JDK7到JDK8的关键改动HashMap是Java基础里当之无愧的“题眼”。先说结构数组加链表加红黑树。JDK8的改动重点链表长度超过8且数组长度大于等于64时链表转红黑树树节点少于6时退化为链表。为什么是8官方注释说是泊松分布理想情况下负载因子0.75链表长度到8的概率低到千万分之一。头插法改尾插法。JDK7头插法在并发扩容时会形成环形链表导致get死循环JDK8改为尾插法解决这个问题但HashMap依然线程不安全并发下会丢数据。hash方法做了优化(h key.hashCode()) ^ (h 16)让高位也参与低位运算减少碰撞。默认负载因子0.75是时间与空间权衡的结果扩容阈值size 数组长度 * 0.75时扩为两倍。容量始终是2的n次方这样(n - 1) hash就能代替取模运算速度更快且分布均匀。还有个必考细节HashMap允许key和value为nullhashtable不行ConcurrentHashMap的key和value都不允许null。原因设计层面是这样ConcurrentHashMap在多线程场景下get返回null时无法判断是“不存在”还是“value本来就为null”所以干脆禁止避免二义性。3.3 ConcurrentHashMap怎么做到线程安全分段锁是JDK7的设计锁的是Segment默认16段并发度16。JDK8放弃了分段锁用CAS加synchronized锁住数组的每个bin桶锁粒度更细并发度提升明显。理解JDK8版的put流程很重要计算hash定位桶桶为空就用CAS插入桶不为空就锁住这个桶链表的头节点或树的根节点再操作链表长度达标就树化最后检查扩容。这个设计好在锁竞争只发生在同一个桶上不同桶互不影响实际并发性能很高。关于size的计算JDK8用sumCount和一个volatile变量baseCount组合尽量避免全局锁。面试被问就说维护一个CounterCell数组减少竞争最终size是baseCount加CounterCell的和允许一定程度的近似值。3.4 集合的fail-fast机制AQS热搜词也在里面后面并发部分会讲。这里先提醒ArrayList/HashMap迭代时如果被并发修改不是通过迭代器自己的remove会抛ConcurrentModificationException。原理是迭代器内部维护modCount每次next都检查是否和预期值一致。注意fail-fast是及时报错机制不是保证正确性所以不要指望用它来做并发控制。4. JVM内存与类加载基础中的硬核部分4.1 运行时数据区到底有哪些各自的角色JVM内存是面试必考JDK8以后方法区变成了元空间这个是最大的变化。运行时数据区分成线程私有和线程共享两大类线程私有的有程序计数器、虚拟机栈、本地方法栈。程序计数器记录当前线程执行的字节码行号是唯一不会OOM的区域。虚拟机栈存储栈帧每个方法调用对应入栈出栈栈帧里含局部变量表、操作数栈、动态链接、方法返回地址。局部变量表在编译期就确定了大小所以栈深度是固定的上限递归过深就StackOverflowError。线程共享的有堆和方法区。堆是对象实例的主要存储区GC的主要发生地分新生代Eden、两个Survivor区和老年代。元空间Metaspace替代了永久代使用的是本地内存默认无上限但可以设置-XX:MetaspaceSize控制初始值。常量池在JDK7之后移到堆里字符串常量池也是堆的一部分。4.2 ClassLoader和双亲委派模型类加载分三步加载、链接验证、准备、解析、初始化。加载阶段通过类的全限定名获取字节流然后在内存中生成Class对象。双亲委派模型是重点当一个类加载器收到加载请求时先委派给父类加载器父类再往上委派到顶层Bootstrap ClassLoader为止父类能加载就用父类的加载不了才自己加载。这样做的核心目的是防止核心API被篡改保证核心类库的类不会被自定义类加载器重复加载。比如你自己写一个java.lang.String在应用启动时类加载器会把请求委派到Bootstrap加载的是JDK自带的String你的类根本没机会被加载。Tomcat打破双亲委派是因为需要每个Web应用有独立的类隔离不然不同的lib版本就冲突了。4.3 GC基础垃圾对象怎么判断、主流回收器判定垃圾对象有两种方式引用计数法和可达性分析。引用计数法有循环引用问题所以主流JVM用可达性分析从GC Roots出发向下遍历不可达的对象就是可回收的。GC Roots包括栈帧中的局部变量引用、静态变量、JNI引用、活跃线程等。引用类型除了强引用还有软引用、弱引用、虚引用。软引用在内存不足时回收适合做缓存弱引用每次GC都回收虚引用主要用于跟踪对象回收配合ReferenceQueue使用。垃圾收集器这块面试主要问CMS和G1。CMS是标记-清除目标是低停顿缺点是会产生内存碎片且并发阶段占用CPU资源。G1把堆分成Region维护优先列表优先回收垃圾最多的Region可以预测停顿时间JDK8之后慢慢替代CMSJDK9之后G1成为默认。ZGC追求的是超大堆低延迟目前JDK17之后的版本用得越来越多。5. 并发编程面试区分度的核心战场5.1 volatile能保证什么不能保证什么volatile是Java基础里最容易被误解的关键字。它能保证两点可见性和有序性禁重排序但不保证原子性。可见性就是线程修改了volatile变量其他线程能立即看到最新值。原理是写volatile变量时会强制把工作内存中改动刷新到主内存并让其他CPU核心的缓存行失效缓存一致性协议x86上是MESI。为什么不能保证原子性因为像count这种操作是“读取-修改-写入”三步volatile只能保证每次读取是最新值但两个线程同时读到0同时加1同时写回就会丢更新。所以计数场景还是需要AtomicInteger或synchronized。有序性涉及指令重排序和内存屏障单线程执行结果不变的前提下CPU和编译器会调整指令顺序。volatile写会在前面插入StoreStore屏障后面插入StoreLoad屏障防止重排序跨越volatile边界。单例模式的双重检查锁DCL之所以要加volatile就是防止“new对象”过程中的重排序导致返回了一个未初始化完成的实例。5.2 synchronized的锁升级过程synchronized在JDK6之后有锁升级机制无锁 - 偏向锁 - 轻量级锁 - 重量级锁。偏向锁是同一个线程反复进入同步块时省去CAS开销一旦有竞争就升级为轻量级锁通过CAS自旋抢锁自旋超过阈值或竞争加剧就升级为重量级锁即操作系统级的互斥量这时涉及用户态内核态切换性能开销大。JDK15开始偏向锁被废弃标记JDK18默认关闭偏向锁因为偏向锁引入的复杂度和维护成本已经大于收益尤其是在现代应用中大量线程竞争的场景。面试答的时候提一嘴这个演进说明你是关注新版本的。其实synchronized加锁的本质是对象头里的Mark Word里面有锁标志位和持有锁的线程ID等信息。这也是很多人忽略的点任何对象都可以是锁就是因为每个对象头里都有Mark Word。5.3 AQS到底是什么为什么Lock基于它能高效AQSAbstractQueuedSynchronizer是JUC的基石ReentrantLock、CountDownLatch、Semaphore、ReadWriteLock都基于它。很多人在面试时听到AQS就头皮发麻其实核心就三个东西一个volatile int成员变量state表示同步状态一个CLH变体队列先进先出的双向队列保存等待的线程节点基于CAS操作state来获取和释放锁。拿ReentrantLock加锁举例线程CAS把state从0改成1成功就获得锁失败就生成Node节点加入等待队列通过LockSupport.park阻塞自己。可重入的实现就是同一个线程再次进来时state加1释放时减到0才真正释放锁。理解AQS之后很多并发工具的本质就通了。Semaphore就是state表示剩余许可数量CountDownLatch就是state表示还需要等待几个事件。所以我建议学习AQS不要死记源码先去理解state和等待队列这两个核心再去看源码就顺了。5.4 保证数据一致性的几种手段热搜里有“Java怎么保证数据一致性”这个问题从基础层面回答的话分几档单线程内不需要额外机制。多线程共享变量用volatile保证可见性synchronized/Lock保证原子性。CAS无锁方案Atomic类。线程封闭StackLocalThreadLocal每个线程有独立副本通过空间换时间避免竞争。分布式场景那就要靠数据库锁、Redis分布式锁、版本号乐观锁这些了。面试时最好说清楚层次。数据一致性不是单点问题从JVM内存模型到数据库隔离级别再到分布式事务每一层都有对应手段关键是识别并发问题的场景。6. 开发中的高频坑点与面试实操经验6.1 JDK安装与环境变量配置这个热搜出现频率很高简单说下最稳妥的配置方法JDK安装后需要配置JAVA_HOME、PATH、CLASSPATH三个变量。JAVA_HOME指向JDK安装根目录PATH里加%JAVA_HOME%\binWindows或$JAVA_HOME/binLinux/macOSCLASSPATH一般设.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarWindows但JDK9以后模块化后classpath不再是必需项了。验证是否成功命令行执行java -version和javac -version。如果java有输出但javac提示找不到命令基本就是PATH没配好或者配完没重开终端。另外一定要确认安装的是JDK不是JRE很多初学者装了JRE后发现不能编译代码就是因为没有javac。一个容易被忽略的点新版JDK可能自带了旧版本比如Windows下装了多个JDK需要确保PATH顺序把想要的版本放在前面。Linux下可以用update-alternatives --config java来切换版本。6.2 源发行版17需要目标发行版17的编译错误热搜里这句话很真实我经常在社区看到新手问。报错原文大概是“警告: 源发行版 17 需要目标发行版 17”或者“错误: 不支持发行版本 17”。本质上是Maven或者IDE里的编译级别和当前JDK版本不匹配。常见的两种场景IDEA里项目SDK选了JDK17但Project Settings里Java Compiler的Target bytecode version还是1.8导致javac尝试用17的源码特性编译到1.8的字节码结果不支持。Maven项目里pom.xml指定了maven-compiler-plugin的source和target为1.8但本地JDK已经到17编译时也会警告或报错。解决办法统一三处配置——Project Structure里的SDK、Java Compiler的bytecode version、pom.xml里的maven.compiler.source和maven.compiler.target或者用java.version属性统一定。最简单的方式是在pom.xml里加propertiesproperties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target /properties如果只是想消除警告设置Java Compiler的-parameters加上--release 17也行--release比source/target更严格会同时检查API是否用了新版本特性。6.3 POI操作Word能生成图表吗热搜里有“java poi word能生成图表吗”这个是我实际做过的场景。答案是能但不能像Excel那样直接创建Chart对象嵌入。POI操作Word图表通常做法有两种用XWPFChart或手动拼Document XML。你不能直接调一个API生成柱状图要操作的是word/drawings/chart1.xml创建xwpfChart对象并把CategoryAxis和ValueAxis的数据填进去。更务实的做法后端用POI生成基础Word文档图表部分用图片代替。先生成ECharts图片或Java绘图库jfreechart生成图表图片再用XWPFRun.addPicture()插入文档。为什么推荐用图片方案因为POI直接操作图表的API要写的代码量很大而且对模板的兼容性要求高Word里图表本质是internal references如果模板变了很容易出问题。图片方案简单稳定视觉效果也完全可接受图表本身的交互性在Word文档里反正也用不上。6.4 Java动态代理与InvocationHandlerjava.lang.reflect.InvocationHandler配合Proxy可以实现动态代理这是Spring AOP的底层基础。核心步骤就三步// 1. 定义接口 public interface UserService { void addUser(String name); } // 2. 实现InvocationHandler public class LogHandler implements InvocationHandler { private final Object target; public LogHandler(Object target) { this.target target; } Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(before: method.getName()); Object result method.invoke(target, args); System.out.println(after: method.getName()); return result; } } // 3. 创建代理对象 UserService userService new UserServiceImpl(); UserService proxy (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new LogHandler(userService) ); proxy.addUser(zhangsan);基于接口的动态代理底层是在运行时生成新的字节码类继承Proxy并实现传入的接口。面试追问“如果目标类没有接口怎么办”那就要答CGLIB——它通过生成目标类的子类来实现代理所以被代理的类和方法不能是final的。Spring里默认是JDK代理如果没有接口会自动切到CGLIB。6.5 Java对象深度拷贝的正确姿势深度拷贝的三种主流方案对比一下重写clone()并深拷贝所有引用字段只适用于字段少、结构简单的场景字段一变就漏。序列化方式对象实现Serializable通过ObjectOutputStream写到字节数组再读回来。代码量小通用性强但性能一般且对象里所有字段都必须可序列化。MapStruct、Spring BeanUtils等工具做属性拷贝适合DTO/VO转换但注意BeanUtils是浅拷贝嵌套对象会共享引用。要我推荐的话深拷贝用序列化浅拷贝用BeanUtils或手动set。如果是性能敏感的高频操作手写构造函数拷贝反而最可控。热搜里“java对象深度拷贝”大概率是项目中遇到了多层嵌套对象修改互相影响的问题先想清楚拷贝边界比选工具更重要。6.6 Java学习路线怎么安排最合理每次看到热搜里“java学习路线”、“java自学路线图”我就想起自己当初瞎折腾走了不少弯路。如果你是从零开始比较好的顺序是第一个月Java语法基础数据类型、流程控制、数组、面向对象三大特性、异常、常用API配合简单控制台项目。第二个月集合框架源码阅读ArrayList/HashMap/LinkedList、IO流、反射、注解。第三个月JVM内存模型与GC基础、并发编程synchronized、volatile、ThreadLocal、线程池。第四个月数据库MySQL必学重点是索引和事务、JDBC、Maven、Git。第五到六个月Java WebServlet是过时了但过程值得过一遍、Spring、Spring Boot、MyBatis。第七到八个月做一个完整的项目比如权限管理系统、电商后台把前端基础HTML/CSS/JS/Vue过一遍够用就行。之后补Redis、消息队列、Linux、Docker。这版路线偏保守但稳核心思想是先广度后深度。基础阶段的每一天都在为后面的Spring源码打地基尤其是反射和动态代理不懂这两个看Spring AOP会非常痛苦。7. 面试高频问题速查拿得出手的答题框架7.1 高频基础问题答题框架有些基础问题翻来覆去地问我整理一个答题顺序按这个套路答不容易漏问题答题框架面向对象特性定义 - 例子 - 底层设计动机 - Java中的具体体现如多态的三条件String为什么不可变final修饰char数组 - 缓存/安全/线程安全 - 设计权衡HashMap原理数据结构数组链表红黑树- put流程 - 扩容机制 - 线程安全问题JVM内存区域线程私有/共享分类 - 各自作用 - 常见异常StackOverflowError/OOM线程池参数核心线程数 - 最大线程数 - 阻塞队列 - 拒绝策略 - 实际场景配置锁升级无锁 - 偏向锁 - 轻量级锁 - 重量级锁 - 每种锁的触发条件答题逻辑比背结论重要。面试官问HashMap你要让他看到你是从“hash函数设计 - 碰撞处理 - 扩容 - 并发问题”这个链路去理解的而不是只记住“数组加链表”。线程池这块也是基础中比较爱考的ThreadPoolExecutor的核心参数是核心线程数、最大线程数、空闲存活时间、工作队列、线程工厂、拒绝策略。拒绝策略有AbortPolicy默认抛异常、CallerRunsPolicy调用者线程执行、DiscardPolicy直接丢弃、DiscardOldestPolicy丢弃最老任务。实际配置CPU密集型和IO密集型不一样IO密集型核心线程数一般设CPU核数两倍左右具体要按压测结果来。7.2 基础题里的换位思考我在面试别人的时候最怕听到的答案是“这个书上说就是这样”。比如问“为什么HashMap链表转红黑树的阈值是8”如果对方只说“默认就是8”那我基本判定他是背的。但如果说“理想状态下链表长度符合泊松分布8是出现概率极低的临界值而且红黑树节点占空间是链表节点两倍转换要权衡空间和查询性能”这就能看到思考深度。同样的问题比如“为什么重写equals一定要重写hashCode”如果只答“为了放进HashMap不出错”太浅了。要补充两个对象相等则hashCode必须相等但hashCode相等的两个对象不一定相等HashSet、HashMap等散列集合先比较hashCode定位桶再比较equals确定是否同一个对象如果不重写hashCode就是Object默认的地址哈希两个内容相同的对象会进不同桶导致重复数据。8. 实际项目里的Java基础应用片段8.1 写API接口时的基础素养热搜词里“java开发api接口以供外部调用”很对Java写接口看起来简单但基础不牢很容易翻车。几个基础层面的注意点DTO返回统一封装结构至少包含code、message、data三件套。参数校验放Controller层做用javax.validation注解体系少写一堆if判断。全局异常处理用RestControllerAdvice这样业务异常不会被用户直接看到堆栈。接口日志要记得打包括请求参数和响应结果排查线上问题全靠它。基础核心点在于Java的异常体系、注解、泛型在写接口时全部会被用到。比如统一返回结构通常要写一个泛型类ResultT如果泛型通配符不熟这种类写起来会很别扭。8.2 基础扎实的人在阅读源码时的优势很多人问为什么Spring源码读不懂答案通常是反射、泛型、设计模式基础不牢。Spring核心的BeanFactory在创建对象时就是通过反射调用构造器依赖注入时通过反射解析字段上的Autowired注解代理对象通过动态代理生成AOP通知链通过责任链模式组织和执行。这些知识没有一个属于Spring本身全是Java基础。所以我的建议一直是如果源码看不下去倒回去看Java基础而不是硬啃框架。基础夹生的时候看Spring每个类都认识但组合起来的逻辑完全陌生等你把反射和动态代理吃透了再回头看Spring的getBean流程会有那种“原来如此”的顿悟感。9. 写在最后的两个建议第一基础复习不要只刷题一定要带着“为什么”去复习。很多人在牛客、力扣上刷了大量选择题知识点看着都眼熟但面试让手写一个线程池配置或者讲讲ConcurrentHashMap的size怎么计算立刻卡住。Java基础是一张知识网背结论只能答对选择题讲出推导过程才能应对追问。第二回顾知识的时候配合源码看哪怕只看关键部分。ArrayList的扩容代码三五行就能看完HashMap的put方法核心也不到五十行看一遍源码比背十遍八股印象深得多。我自己的习惯是画一张“HashMap put流程”的脑图把hash计算、碰撞、树化、扩容、fail-fast全部串起来复习的时候扫一眼就能找回全部记忆。这个方法推荐给你。

相关推荐

LTE上下行调度原理与工程调优实战指南
LTE上下行调度原理与工程调优实战指南

简介:本资源是一份深入解析LTE上下行调度机制的技术文档,面向通信工程专业学生、4G网络优化工程师及无线协议研发人员,聚焦解决实际网络中资源分配公平性与系统吞吐量平衡这一核心问题。文档系统梳理了下行调度的四大算法(Max C/I… · 2026/9/26 6:09:59

把Shell权限交给LLM会出事吗?Kiro Crew六层纵深防御安全模型完整指南
把Shell权限交给LLM会出事吗?Kiro Crew六层纵深防御安全模型完整指南

把Shell权限交给LLM会出事吗?Kiro Crew六层纵深防御安全模型完整指南 【免费下载链接】KiroCrew A persistent workspace for development work that self-improves and continues beyond one session. 项目地址: https://gitcode.com/gh_mirrors/ki/KiroCrew … · 2026/9/26 6:09:59

函数组合实战:用纯函数与 pipe 写出高可读、易测试的代码
函数组合实战:用纯函数与 pipe 写出高可读、易测试的代码

做了十多年开发,我见过太多种“写着写着就乱掉”的代码:业务逻辑层层嵌套,修一个 bug 要翻七八个文件,谁都怕碰那段历史代码。后来开始系统接触函数式编程思想,情况才慢慢改观——尤其是我在项目里频繁使用函数组合之后… · 2026/9/26 6:09:59

挂轨式巡检机器人怎么选?防爆与电力两类场景拆开看
挂轨式巡检机器人怎么选?防爆与电力两类场景拆开看

在巡检机器人的几种形态里,挂轨式是争议最小、也最容易被选错的一类。它靠顶部轨道行走、沿滑触线持续供电,因此不用回充、不占地面通道,能长期停在充电状态随取随用。但它同时有一条硬约束:轨道铺到哪里,巡检就只能覆… · 2026/9/26 7:15:21

网络安全新手为什么学不会?从Linux到Web安全,一次理清正确学习路线
网络安全新手为什么学不会?从Linux到Web安全,一次理清正确学习路线

引言:网络安全的吸引力与入门困境 网络安全(简称网安)已成为全球最炙手可热的职业领域之一。根据2024年全球网络安全报告,预计全球网络安全人才缺口将超过400万,而薪资水平普遍在15-40万美元/年。然而,许多… · 2026/9/26 7:15:21

AutoCAD批量打印插件Batchplot 3.6.1:高效出图与图框识别实战
AutoCAD批量打印插件Batchplot 3.6.1:高效出图与图框识别实战

1. 批量打印这件事,为什么值得单独拎出来聊干过工程制图或者设计院出图的朋友都懂,图纸画完只是第一步,真正折磨人的是打印。一套项目几十张甚至上百张CAD图纸,一张张打开、选打印机、设纸张、调比例、点确定,一套流程… · 2026/9/26 7:15:15

AGX X2边缘AI芯片:单Token能耗降低50%的能效密码
AGX X2边缘AI芯片:单Token能耗降低50%的能效密码

1. 项目概述:一颗专为边缘场景“省电而生”的AI加速芯最近在几个硬件开发者闭门会上,我反复听到一句话:“这颗芯片,是真把‘省电’刻进硅基DNA里了。”说的就是此芯科技刚发布的AGX X2平台。标题里那句“单Token能耗降低50%以上”… · 2026/9/26 7:15:15

Blender全面实战指南:从建模、材质到渲染与插件生态
Blender全面实战指南:从建模、材质到渲染与插件生态

玩Blender也有不少年头了,从当年那个连界面都看不懂的小白,到现在能靠它吃饭,中间踩过的坑能填满一个硬盘。这个标题我说“从入门到榨干”,不是标题党,而是我真心觉得Blender是那种表面看起来友好、实际上深不见底的软… · 2026/9/26 7:15:15

前端文字批注实现:选区持久化与高亮还原方案
前端文字批注实现:选区持久化与高亮还原方案

简介:一份演示前端页面添加文字批注功能的示例压缩包,面向初中级前端开发者,解决网页中选中文本、实时添加高亮批注、编辑与删除的交互需求。压缩包共10个文件,以3个js脚本(jQuery、artDialog及核心逻辑)为… · 2026/9/26 7:15:15

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码