[{"data":1,"prerenderedAt":649},["ShallowReactive",2],{"java:jvm\u002F":3,"java-wiki-navigation":129},{"id":4,"title":5,"body":6,"commentId":116,"description":117,"difficulty":118,"draft":119,"extension":120,"meta":121,"navigation":122,"order":105,"path":123,"section":124,"seo":125,"stem":126,"updated":127,"__hash__":128},"java\u002Fjava\u002Fjvm.md","JVM 知识地图",{"type":7,"value":8,"toc":103},"minimark",[9,14,18,21,25,41,44,58,61,75,78,92,95],[10,11,13],"h2",{"id":12},"为什么要理解-jvm","为什么要理解 JVM",[15,16,17],"p",{},"JVM 把 Java 源代码和具体硬件隔开，但生产问题最终仍会落到内存、线程、字节码和操作系统资源上。理解 JVM 的目标不是记参数，而是能解释和诊断程序行为。",[10,19,20],{"id":20},"知识路线",[22,23,24],"h3",{"id":24},"类加载",[26,27,28,32,35,38],"ul",{},[29,30,31],"li",{},"加载、验证、准备、解析和初始化",[29,33,34],{},"双亲委派模型",[29,36,37],{},"类加载器隔离",[29,39,40],{},"静态字段和初始化顺序",[22,42,43],{"id":43},"运行时数据区",[26,45,46,49,52,55],{},[29,47,48],{},"堆与对象分配",[29,50,51],{},"虚拟机栈与栈帧",[29,53,54],{},"方法区与元空间",[29,56,57],{},"直接内存",[22,59,60],{"id":60},"垃圾回收",[26,62,63,66,69,72],{},[29,64,65],{},"可达性分析",[29,67,68],{},"分代收集",[29,70,71],{},"CMS、G1 与现代收集器",[29,73,74],{},"停顿时间、吞吐量和内存占用之间的权衡",[22,76,77],{"id":77},"性能排查",[26,79,80,83,86,89],{},[29,81,82],{},"GC 日志",[29,84,85],{},"线程快照",[29,87,88],{},"堆转储",[29,90,91],{},"CPU、内存和锁竞争定位",[10,93,94],{"id":94},"一句话原则",[15,96,97,98,102],{},"先确定现象属于 CPU、内存、线程还是外部依赖，再选择工具；不要看到 ",[99,100,101],"code",{},"OutOfMemoryError"," 就先调整堆大小。",{"title":104,"searchDepth":105,"depth":105,"links":106},"",2,[107,108,115],{"id":12,"depth":105,"text":13},{"id":20,"depth":105,"text":20,"children":109},[110,112,113,114],{"id":24,"depth":111,"text":24},3,{"id":43,"depth":111,"text":43},{"id":60,"depth":111,"text":60},{"id":77,"depth":111,"text":77},{"id":94,"depth":105,"text":94},"wiki:java:jvm","从类加载、运行时内存到垃圾回收与性能排查，理解 Java 程序如何真正运行。","intermediate",false,"md",{},true,"\u002Fjava\u002Fjvm","JVM",{"title":5,"description":117},"java\u002Fjvm","2026-07-10","ZPK0OT5czgBvYvU-AowqKfXfaGqS5bqnDP2N5bWKN5k",[130,218,293,400,497,573],{"id":131,"title":132,"body":133,"commentId":208,"description":209,"difficulty":210,"draft":119,"extension":120,"meta":211,"navigation":122,"order":212,"path":213,"section":214,"seo":215,"stem":216,"updated":127,"__hash__":217},"java\u002Fjava\u002Ffundamentals.md","Java 基础知识地图",{"type":7,"value":134,"toc":202},[135,138,141,143,167,170,173,176],[10,136,137],{"id":137},"这一部分解决什么问题",[15,139,140],{},"Java 基础不是 API 的罗列，而是理解类型、对象和运行时行为之间的关系。后续的并发、JVM 和框架知识都建立在这些概念之上。",[10,142,20],{"id":20},[144,145,146,149,155,158,161,164],"ol",{},[29,147,148],{},"基本类型、包装类型与自动装箱",[29,150,151,154],{},[99,152,153],{},"String","、不可变对象与对象比较",[29,156,157],{},"集合框架与常见数据结构",[29,159,160],{},"泛型、类型擦除与边界",[29,162,163],{},"反射、注解与动态代理",[29,165,166],{},"异常体系和资源管理",[10,168,169],{"id":169},"推荐学习方式",[15,171,172],{},"先用一句话回答“它是什么”，再通过小段代码验证边界，最后把它放回 JVM 和框架运行机制中理解。知识库会逐步把每个主题拆成独立条目。",[10,174,175],{"id":175},"面试时容易出现的问题",[26,177,178,185,196,199],{},[29,179,180,181,184],{},"只背诵 ",[99,182,183],{},"HashMap"," 的结论，不理解哈希冲突和扩容成本。",[29,186,187,188,191,192,195],{},"把 ",[99,189,190],{},"=="," 和 ",[99,193,194],{},"equals"," 简化成“地址比较”和“内容比较”。",[29,197,198],{},"知道泛型语法，但无法解释类型擦除带来的限制。",[29,200,201],{},"会使用反射，却不了解它为什么被 Spring 等框架广泛使用。",{"title":104,"searchDepth":105,"depth":105,"links":203},[204,205,206,207],{"id":137,"depth":105,"text":137},{"id":20,"depth":105,"text":20},{"id":169,"depth":105,"text":169},{"id":175,"depth":105,"text":175},"wiki:java:fundamentals","Java 类型系统、集合、泛型、反射、异常与常用语言机制的学习入口。","basic",{},1,"\u002Fjava\u002Ffundamentals","Java 基础",{"title":132,"description":209},"java\u002Ffundamentals","TZ18cq4bXSr9iscSOTSlgfMfbmTp2H5kOdVxAbnY_2s",{"id":4,"title":5,"body":219,"commentId":116,"description":117,"difficulty":118,"draft":119,"extension":120,"meta":291,"navigation":122,"order":105,"path":123,"section":124,"seo":292,"stem":126,"updated":127,"__hash__":128},{"type":7,"value":220,"toc":281},[221,223,225,227,229,239,241,251,253,263,265,275,277],[10,222,13],{"id":12},[15,224,17],{},[10,226,20],{"id":20},[22,228,24],{"id":24},[26,230,231,233,235,237],{},[29,232,31],{},[29,234,34],{},[29,236,37],{},[29,238,40],{},[22,240,43],{"id":43},[26,242,243,245,247,249],{},[29,244,48],{},[29,246,51],{},[29,248,54],{},[29,250,57],{},[22,252,60],{"id":60},[26,254,255,257,259,261],{},[29,256,65],{},[29,258,68],{},[29,260,71],{},[29,262,74],{},[22,264,77],{"id":77},[26,266,267,269,271,273],{},[29,268,82],{},[29,270,85],{},[29,272,88],{},[29,274,91],{},[10,276,94],{"id":94},[15,278,97,279,102],{},[99,280,101],{},{"title":104,"searchDepth":105,"depth":105,"links":282},[283,284,290],{"id":12,"depth":105,"text":13},{"id":20,"depth":105,"text":20,"children":285},[286,287,288,289],{"id":24,"depth":111,"text":24},{"id":43,"depth":111,"text":43},{"id":60,"depth":111,"text":60},{"id":77,"depth":111,"text":77},{"id":94,"depth":105,"text":94},{},{"title":5,"description":117},{"id":294,"title":295,"body":296,"commentId":392,"description":393,"difficulty":118,"draft":119,"extension":120,"meta":394,"navigation":122,"order":111,"path":395,"section":396,"seo":397,"stem":398,"updated":127,"__hash__":399},"java\u002Fjava\u002Fconcurrency.md","Java 并发知识地图",{"type":7,"value":297,"toc":383},[298,301,304,311,314,324,327,330,332,366,369],[10,299,300],{"id":300},"并发问题的三个核心维度",[22,302,303],{"id":303},"可见性",[15,305,306,307,310],{},"一个线程修改的数据，何时能够被另一个线程观察到。",[99,308,309],{},"volatile","、锁和线程启动\u002F终止规则都与 happens-before 有关。",[22,312,313],{"id":313},"原子性",[15,315,316,317,320,321,323],{},"一个操作能否被其他线程观察到中间状态。",[99,318,319],{},"count++"," 即使使用 ",[99,322,309],{}," 也不是原子操作。",[22,325,326],{"id":326},"有序性",[15,328,329],{},"编译器和处理器可以在不改变单线程结果的前提下重排序。并发程序必须通过同步规则建立必要顺序。",[10,331,20],{"id":20},[144,333,334,337,342,348,351,354,357,363],{},[29,335,336],{},"Java 内存模型与 happens-before",[29,338,339,341],{},[99,340,309],{}," 与内存屏障",[29,343,344,347],{},[99,345,346],{},"synchronized"," 与对象监视器",[29,349,350],{},"CAS、原子类和 ABA 问题",[29,352,353],{},"AQS、锁和同步器",[29,355,356],{},"线程池与任务调度",[29,358,359,362],{},[99,360,361],{},"CompletableFuture"," 与异步编排",[29,364,365],{},"并发容器",[10,367,368],{"id":368},"生产实践原则",[26,370,371,374,377,380],{},[29,372,373],{},"尽量减少共享可变状态。",[29,375,376],{},"明确线程池的职责、队列容量和拒绝策略。",[29,378,379],{},"不要把耗时不可控的任务提交到公共线程池。",[29,381,382],{},"监控活跃线程数、队列长度、拒绝次数和任务耗时。",{"title":104,"searchDepth":105,"depth":105,"links":384},[385,390,391],{"id":300,"depth":105,"text":300,"children":386},[387,388,389],{"id":303,"depth":111,"text":303},{"id":313,"depth":111,"text":313},{"id":326,"depth":111,"text":326},{"id":20,"depth":105,"text":20},{"id":368,"depth":105,"text":368},"wiki:java:concurrency","理解可见性、原子性、有序性，以及 Java 并发工具如何建立在这些规则之上。",{},"\u002Fjava\u002Fconcurrency","并发编程",{"title":295,"description":393},"java\u002Fconcurrency","EkMZP12_4LdF-05WBbKP344weaqz3uif-3l5nazF3xk",{"id":401,"title":402,"body":403,"commentId":488,"description":489,"difficulty":118,"draft":119,"extension":120,"meta":490,"navigation":122,"order":491,"path":492,"section":493,"seo":494,"stem":495,"updated":127,"__hash__":496},"java\u002Fjava\u002Fspring.md","Spring 知识地图",{"type":7,"value":404,"toc":481},[405,409,412,416,433,437,451,454,471,474],[10,406,408],{"id":407},"理解-spring-的主线","理解 Spring 的主线",[15,410,411],{},"Spring 的核心不是注解数量，而是容器如何创建对象、建立依赖，并在合适的扩展点改变对象行为。",[10,413,415],{"id":414},"ioc-容器","IOC 容器",[26,417,418,421,424,427,430],{},[29,419,420],{},"BeanDefinition 的来源",[29,422,423],{},"Bean 创建生命周期",[29,425,426],{},"依赖注入",[29,428,429],{},"BeanPostProcessor",[29,431,432],{},"循环依赖",[10,434,436],{"id":435},"aop","AOP",[26,438,439,442,445,448],{},[29,440,441],{},"JDK 动态代理和 CGLIB",[29,443,444],{},"切点与通知",[29,446,447],{},"代理对象调用边界",[29,449,450],{},"自调用为什么可能导致切面失效",[10,452,453],{"id":453},"事务",[26,455,456,459,462,465,468],{},[29,457,458],{},"事务管理器",[29,460,461],{},"传播行为",[29,463,464],{},"隔离级别",[29,466,467],{},"回滚规则",[29,469,470],{},"声明式事务失效场景",[10,472,473],{"id":473},"学习建议",[15,475,476,477,480],{},"选择一条最短链路，从 ",[99,478,479],{},"ApplicationContext"," 启动到一个带事务的 Service 被调用，跟踪其中的对象创建、代理生成和拦截过程。这样比孤立背诵源码类名更有效。",{"title":104,"searchDepth":105,"depth":105,"links":482},[483,484,485,486,487],{"id":407,"depth":105,"text":408},{"id":414,"depth":105,"text":415},{"id":435,"depth":105,"text":436},{"id":453,"depth":105,"text":453},{"id":473,"depth":105,"text":473},"wiki:java:spring","从 IOC、AOP 和事务出发，理解 Spring 如何组织和增强应用程序。",{},4,"\u002Fjava\u002Fspring","Spring",{"title":402,"description":489},"java\u002Fspring","jZmHr0WwrtcGUGlcEdj8z-shlR3YZc-UdEZSfPZYgNE",{"id":498,"title":499,"body":500,"commentId":564,"description":565,"difficulty":118,"draft":119,"extension":120,"meta":566,"navigation":122,"order":567,"path":568,"section":569,"seo":570,"stem":571,"updated":127,"__hash__":572},"java\u002Fjava\u002Fdatabase.md","数据库与缓存知识地图",{"type":7,"value":501,"toc":558},[502,505,508,512,532,535,552,555],[10,503,504],{"id":504},"数据库知识的核心问题",[15,506,507],{},"后端开发关注的不只是 SQL 能否执行，还要理解数据如何被定位、并发修改如何协调、失败后如何恢复，以及缓存加入后怎样维持可接受的一致性。",[10,509,511],{"id":510},"mysql","MySQL",[26,513,514,517,520,523,526,529],{},[29,515,516],{},"B+Tree 与索引组织",[29,518,519],{},"联合索引和最左匹配",[29,521,522],{},"执行计划",[29,524,525],{},"MVCC 与 Read View",[29,527,528],{},"行锁、间隙锁和死锁",[29,530,531],{},"redo log、undo log 与 binlog",[10,533,534],{"id":534},"缓存",[26,536,537,540,543,546,549],{},[29,538,539],{},"Cache Aside",[29,541,542],{},"缓存穿透、击穿和雪崩",[29,544,545],{},"热点 Key",[29,547,548],{},"数据更新与失效",[29,550,551],{},"最终一致性",[10,553,554],{"id":554},"排查顺序",[15,556,557],{},"面对慢查询，先确认实际执行 SQL 和参数，再看执行计划、扫描行数、锁等待和数据分布。不要只根据 SQL 外观判断是否使用索引。",{"title":104,"searchDepth":105,"depth":105,"links":559},[560,561,562,563],{"id":504,"depth":105,"text":504},{"id":510,"depth":105,"text":511},{"id":534,"depth":105,"text":534},{"id":554,"depth":105,"text":554},"wiki:java:database","围绕索引、事务、锁、缓存与数据一致性，建立后端开发需要的数据库认知。",{},5,"\u002Fjava\u002Fdatabase","数据库",{"title":499,"description":565},"java\u002Fdatabase","3gza7dGQZPwMSHFISiZ7Jy-iB_2rQD2ozomZ8OuiyHw",{"id":574,"title":575,"body":576,"commentId":640,"description":641,"difficulty":210,"draft":119,"extension":120,"meta":642,"navigation":122,"order":643,"path":644,"section":645,"seo":646,"stem":647,"updated":127,"__hash__":648},"java\u002Fjava\u002Finterview.md","Java 面试专题使用说明",{"type":7,"value":577,"toc":635},[578,581,584,587,620,623,632],[10,579,580],{"id":580},"这里不会做什么",[15,582,583],{},"不会把数百道问题堆在一个页面，也不会只给出适合背诵但无法解释的标准答案。",[10,585,586],{"id":586},"每个问题的组织方式",[144,588,589,596,602,608,614],{},[29,590,591,595],{},[592,593,594],"strong",{},"一句话回答","：先准确回答问题。",[29,597,598,601],{},[592,599,600],{},"核心原理","：说明这个结论为什么成立。",[29,603,604,607],{},[592,605,606],{},"代码验证","：使用尽可能小的例子验证边界。",[29,609,610,613],{},[592,611,612],{},"常见误区","：指出容易混淆的地方。",[29,615,616,619],{},[592,617,618],{},"继续追问","：把当前问题连接到更深层知识。",[10,621,622],{"id":622},"示例追问链",[624,625,630],"pre",{"className":626,"code":628,"language":629,"meta":104},[627],"language-text","HashMap 为什么线程不安全？\n  → put 操作包含哪些步骤？\n  → 扩容时发生什么？\n  → ConcurrentHashMap 如何降低竞争？\n  → JDK 不同版本的实现有什么变化？\n","text",[99,631,628],{"__ignoreMap":104},[15,633,634],{},"面试题的价值不是预测题目，而是帮助自己检查知识之间是否已经形成连接。",{"title":104,"searchDepth":105,"depth":105,"links":636},[637,638,639],{"id":580,"depth":105,"text":580},{"id":586,"depth":105,"text":586},{"id":622,"depth":105,"text":622},"wiki:java:interview","用简明回答、原理解释、代码验证和追问路径组织 Java 面试知识。",{},6,"\u002Fjava\u002Finterview","面试专题",{"title":575,"description":641},"java\u002Finterview","AWxAYmdi1IahbXu7QwVZPfsiCXbVU4YTMMoshQkzEl8",1783807996402]