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