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