diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index efe78bf3f24..bee4100fa2b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,13 +10,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Install pnpm
- uses: pnpm/action-setup@v4
+ uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
diff --git a/.gitignore b/.gitignore
index 242ea3b9602..2238d42826f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,4 @@ format-markdown.py
.npmrc
package-lock.json
lintmd-config.json
+.claude/settings.local.json
diff --git a/README.md b/README.md
index e97edcb3989..e72c3f463d6 100755
--- a/README.md
+++ b/README.md
@@ -11,29 +11,40 @@
-> - **面试专版**:准备 Java 面试的小伙伴可以考虑面试专版:**[《Java 面试指北 》](./docs/zhuanlan/java-mian-shi-zhi-bei.md)** (质量很高,专为面试打造,配合 JavaGuide 食用)。
-> - **知识星球**:专属面试小册/一对一交流/简历修改/专属求职指南,欢迎加入 **[JavaGuide 知识星球](./docs/about-the-author/zhishixingqiu-two-years.md)**(点击链接即可查看星球的详细介绍,一定确定自己真的需要再加入)。
-> - **使用建议** :有水平的面试官都是顺着项目经历挖掘技术问题。一定不要死记硬背技术八股文!详细的学习建议请参考:[JavaGuide 使用建议](./docs/javaguide/use-suggestion.md)。
-> - **求个Star**:如果觉得 JavaGuide 的内容对你有帮助的话,还请点个免费的 Star,这是对我最大的鼓励,感谢各位一起同行,共勉!Github 地址:[https://github.com/Snailclimb/JavaGuide](https://github.com/Snailclimb/JavaGuide) 。
+> - **大模型实战项目**: [⭐AI 智能面试辅助平台 + RAG 知识库](https://javaguide.cn/zhuanlan/interview-guide.html)(基于 Spring Boot 4.0 + Java 21 + Spring AI 2.0 ,非常适合作为学习和简历项目,学习门槛低)。
+> - **面试资料补充**:
+> - [《Java 面试指北》](https://javaguide.cn/zhuanlan/java-mian-shi-zhi-bei.html):四年打磨,和 [JavaGuide 开源版](https://javaguide.cn/)的内容互补,带你从零开始系统准备面试!
+> - [《后端面试高频系统设计&场景题》](https://javaguide.cn/zhuanlan/back-end-interview-high-frequency-system-design-and-scenario-questions.html):30+ 道高频系统设计和场景面试,助你应对当下中大厂面试趋势。
+> - **使用建议** :如果你想要系统准备 Java 后端面试但又不知道如何开始的,可以参考 [Java 后端面试通关计划(后端通用)](https://javaguide.cn/interview-preparation/backend-interview-plan.html)。
+> - **求个 Star**:如果觉得 JavaGuide 的内容对你有帮助的话,还请点个免费的 Star,这是对我最大的鼓励,感谢各位一起同行,共勉!传送门:[GitHub](https://github.com/Snailclimb/JavaGuide) | [Gitee](https://gitee.com/SnailClimb/JavaGuide)。
> - **转载须知**:以下所有文章如非文首说明为转载皆为 JavaGuide 原创,转载请在文首注明出处。如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
-## 面试突击版本
+## AI 应用开发面试指南
-很多同学有“临时突击面试”的需求,所以我专门做了一个 [JavaGuide 面试突击版](https://interview.javaguide.cn/home.html):在 [JavaGuide](https://javaguide.cn/home.html) 原有内容基础上做了大幅精简,只保留高频必考重点,并一直持续更新。
+[AI 应用开发面试指南](https://javaguide.cn/ai/)(⭐新增,正在持续更新):专门后端开发准备的 AI 应用开发核心知识,涵盖大模型基础、Agent、RAG、MCP 协议等高频面试考点。
-在这些“精简后的重点”里,我又额外用 ⭐️ 标出了**重点中的重点**,方便你优先浏览、快速记忆。
+### AI Agent
-同时提供亮色(白天)和暗色(夜间)PDF,**需要打印的同学记得选亮色版本**,纸质阅读体验会更好。
+- [一文搞懂 AI Agent 核心概念](./docs/ai/agent/agent-basis.md)
+- [大模型提示词工程实践指南](./docs/ai/agent/prompt-engineering.md)
+- [上下文工程实战指南](./docs/ai/agent/context-engineering.md)
+- [万字详解 Agent Skills](./docs/ai/agent/skills.md)
+- [万字拆解 MCP 协议](./docs/ai/agent/mcp.md)
+- [一文搞懂 Harness Engineering](./docs/ai/agent/harness-engineering.md)
+- [AI 工作流中的 Workflow、Graph 与 Loop](./docs/ai/agent/workflow-graph-loop.md)
-如果你**时间比较充裕**,更推荐直接在 [JavaGuide 官网](https://javaguide.cn/) 上**系统学习**:内容比突击版更全面、更深入,更适合打基础和长期提升。
+## 面试准备
-**突击版本网站入口**:[interview.javaguide.cn](https://interview.javaguide.cn/)
-
-对应的 PDF 版本,可以直接在公众号后台回复“**PDF**”获取:
-
-
+- [⭐Java 后端面试通关计划(涵盖后端通用体系)](./docs/interview-preparation/backend-interview-plan.md) (一定要看 :+1:)
+- [如何高效准备 Java 面试?](./docs/interview-preparation/teach-you-how-to-prepare-for-the-interview-hand-in-hand.md)
+- [Java 后端面试重点总结](./docs/interview-preparation/key-points-of-interview.md)
+- [Java 学习路线(最新版,4w+ 字)](./docs/interview-preparation/java-roadmap.md)
+- [程序员简历编写指南](./docs/interview-preparation/resume-guide.md)
+- [项目经验指南](./docs/interview-preparation/project-experience-guide.md)
+- [面试太紧张怎么办?](./docs/interview-preparation/how-to-handle-interview-nerves.md)
+- [校招没有实习经历怎么办?实习经历怎么写?](./docs/interview-preparation/internship-experience.md)
## Java
@@ -217,6 +228,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
**重要知识点:**
- [MySQL 索引详解](./docs/database/mysql/mysql-index.md)
+- [MySQL 索引失效场景总结](./docs/database/mysql/mysql-index-invalidation.md)
- [MySQL 事务隔离级别图文详解)](./docs/database/mysql/transaction-isolation-level.md)
- [MySQL 三大日志(binlog、redo log 和 undo log)详解](./docs/database/mysql/mysql-logs.md)
- [InnoDB 存储引擎对 MVCC 的实现](./docs/database/mysql/innodb-implementation-of-mvcc.md)
@@ -237,6 +249,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
**重要知识点:**
- [3 种常用的缓存读写策略详解](./docs/database/redis/3-commonly-used-cache-read-and-write-strategies.md)
+- [Redis 能做消息队列吗?怎么实现?](./docs/database/redis/redis-stream-mq.md)
- [Redis 5 种基本数据结构详解](./docs/database/redis/redis-data-structures-01.md)
- [Redis 3 种特殊数据结构详解](./docs/database/redis/redis-data-structures-02.md)
- [Redis 持久化机制详解](./docs/database/redis/redis-persistence.md)
@@ -278,8 +291,8 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
## 系统设计
-- [系统设计常见面试题总结](./docs/system-design/system-design-questions.md)
-- [设计模式常见面试题总结](./docs/system-design/design-pattern.md)
+- [⭐系统设计常见面试题总结](./docs/system-design/system-design-questions.md)
+- [⭐设计模式常见面试题总结](https://interview.javaguide.cn/system-design/design-pattern.html)
### 基础
@@ -327,6 +340,7 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
- [敏感词过滤方案总结](./docs/system-design/security/sentive-words-filter.md)
- [数据脱敏方案总结](./docs/system-design/security/data-desensitization.md)
- [为什么前后端都要做数据校验](./docs/system-design/security/data-validation.md)
+- [为什么忘记密码时只能重置,不能告诉你原密码?](./docs/system-design/security/why-password-reset-instead-of-retrieval.md)
### 定时任务
@@ -338,12 +352,15 @@ JVM 这部分内容主要参考 [JVM 虚拟机规范-Java8](https://docs.oracle.
## 分布式
+- [⭐分布式高频面试题](https://interview.javaguide.cn/distributed-system/distributed-system.html)
+
### 理论&算法&协议
- [CAP 理论和 BASE 理论解读](https://javaguide.cn/distributed-system/protocol/cap-and-base-theorem.html)
- [Paxos 算法解读](https://javaguide.cn/distributed-system/protocol/paxos-algorithm.html)
- [Raft 算法解读](https://javaguide.cn/distributed-system/protocol/raft-algorithm.html)
-- [Gossip 协议详解](https://javaguide.cn/distributed-system/protocol/gossip-protocl.html)
+- [ZAB 协议解读](https://javaguide.cn/distributed-system/protocol/zab.html)
+- [Gossip 协议详解](https://javaguide.cn/distributed-system/protocol/gossip-protocol.html)
- [一致性哈希算法详解](https://javaguide.cn/distributed-system/protocol/consistent-hashing.html)
### RPC
diff --git a/README_EN.md b/README_EN.md
index ce2a5bc88e7..ec1366de844 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -64,6 +64,7 @@ Recommended to read through online reading platforms for better experience and f
- [ArrayList Core Source Code + Expansion Mechanism Analysis](./docs/java/collection/arraylist-source-code.md)
- [LinkedList Core Source Code Analysis](./docs/java/collection/linkedlist-source-code.md)
- [HashMap Core Source Code + Underlying Data Structure Analysis](./docs/java/collection/hashmap-source-code.md)
+
# Java Collection & Concurrency Series
## Collection
@@ -128,6 +129,7 @@ The JVM part mainly refers to the [JVM Specification - Java 8](https://docs.orac
- [Java 18 New Features Overview](./docs/java/new-features/java18.md)
- [Java 19 New Features Overview](./docs/java/new-features/java19.md)
- [Java 20 New Features Overview](./docs/java/new-features/java20.md)
+
# Overview of Java 21, 22, 23, 24, and 25 New Features
## Computer Fundamentals
@@ -169,7 +171,7 @@ The JVM part mainly refers to the [JVM Specification - Java 8](https://docs.orac
- [Linear Data Structures: Arrays, Linked Lists, Stacks, Queues](./docs/cs-basics/data-structure/linear-data-structure.md)
- [Graphs](./docs/cs-basics/data-structure/graph.md)
- [Heaps](./docs/cs-basics/data-structure/heap.md)
-- [Trees](./docs/cs-basics/data-structure/tree.md): Focus on [Red-Black Trees](./docs/cs-basics/data-structure/red-black-tree.md), B-, B+, B* Trees, and LSM Trees
+- [Trees](./docs/cs-basics/data-structure/tree.md): Focus on [Red-Black Trees](./docs/cs-basics/data-structure/red-black-tree.md), B-, B+, B\* Trees, and LSM Trees
Other Commonly Used Data Structures:
@@ -205,6 +207,7 @@ Additionally, [GeeksforGeeks](https://www.geeksforgeeks.org/fundamentals-of-algo
### MySQL
**Knowledge Points/Interview Questions Summary:**
+
# MySQL Common Knowledge Points & Interview Questions Summary (Must-Read :+1:)
- [MySQL Common Knowledge Points & Interview Questions Summary](./docs/database/mysql/mysql-questions-01.md)
@@ -233,6 +236,7 @@ Additionally, [GeeksforGeeks](https://www.geeksforgeeks.org/fundamentals-of-algo
**Important Knowledge Points:**
- [Detailed Explanation of 3 Common Cache Read and Write Strategies](./docs/database/redis/3-commonly-used-cache-read-and-write-strategies.md)
+- [Can Redis Be Used as a Message Queue? How to Implement It?](./docs/database/redis/redis-stream-mq.md)
- [Detailed Explanation of Redis' 5 Basic Data Structures](./docs/database/redis/redis-data-structures-01.md)
- [Detailed Explanation of Redis' 3 Special Data Structures](./docs/database/redis/redis-data-structures-02.md)
- [Detailed Explanation of Redis Persistence Mechanism](./docs/database/redis/redis-persistence.md)
@@ -290,6 +294,7 @@ Additionally, [GeeksforGeeks](https://www.geeksforgeeks.org/fundamentals-of-algo
#### Spring/SpringBoot (Must-Read :+1:)
**Knowledge Points/Interview Questions Summary**:
+
- [Summary of Common Spring Knowledge Points and Interview Questions](./docs/system-design/framework/spring/spring-knowledge-and-questions-summary.md)
- [Summary of Common SpringBoot Knowledge Points and Interview Questions](./docs/system-design/framework/spring/springboot-knowledge-and-questions-summary.md)
- [Summary of Common Spring/SpringBoot Annotations](./docs/system-design/framework/spring/spring-common-annotations.md)
@@ -338,7 +343,7 @@ Additionally, [GeeksforGeeks](https://www.geeksforgeeks.org/fundamentals-of-algo
- [Interpretation of CAP Theory and BASE Theory](https://javaguide.cn/distributed-system/protocol/cap-and-base-theorem.html)
- [Interpretation of Paxos Algorithm](https://javaguide.cn/distributed-system/protocol/paxos-algorithm.html)
- [Interpretation of Raft Algorithm](https://javaguide.cn/distributed-system/protocol/raft-algorithm.html)
-- [Detailed Explanation of Gossip Protocol](https://javaguide.cn/distributed-system/protocol/gossip-protocl.html)
+- [Detailed Explanation of Gossip Protocol](https://javaguide.cn/distributed-system/protocol/gossip-protocol.html)
- [Detailed Explanation of Consistent Hashing Algorithm](https://javaguide.cn/distributed-system/protocol/consistent-hashing.html)
### RPC
@@ -364,6 +369,7 @@ Additionally, [GeeksforGeeks](https://www.geeksforgeeks.org/fundamentals-of-algo
- [Design Guide for Distributed ID](https://javaguide.cn/distributed-system/distributed-id-design.html)
### Distributed Lock
+
# Distributed Locks
- [Introduction to Distributed Locks](https://javaguide.cn/distributed-system/distributed-lock.html)
@@ -443,4 +449,4 @@ Deploying multiple instances of the same service to avoid single point of failur
If you want to stay up-to-date with my latest articles and share my valuable content, you can follow my official public account.
-
\ No newline at end of file
+
diff --git a/TRANSLATION_TOOLS.md b/TRANSLATION_TOOLS.md
deleted file mode 100644
index e4ab7acac0d..00000000000
--- a/TRANSLATION_TOOLS.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# Translation Tools for JavaGuide
-
-This repository includes automated translation tools to translate all documentation to multiple languages.
-
-## Available Tools
-
-### 1. Python Version (`translate_repo.py`)
-
-**Requirements:**
-```bash
-pip install deep-translator
-```
-
-**Usage:**
-```bash
-python3 translate_repo.py
-```
-
-**Features:**
-- ✅ Uses Google Translate (free, no API key required)
-- ✅ Translates all `.md` files in `docs/` folder + `README.md`
-- ✅ Preserves directory structure
-- ✅ Progress tracking (saves to `.translation_progress.json`)
-- ✅ Skips already translated files
-- ✅ Rate limiting to avoid API throttling
-- ✅ Supports 20 languages
-
-### 2. Java Version (`TranslateRepo.java`)
-
-**Requirements:**
-```bash
-# Requires Gson library
-# Download from: https://repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar
-```
-
-**Compile:**
-```bash
-javac -cp gson-2.10.1.jar TranslateRepo.java
-```
-
-**Usage:**
-```bash
-java -cp .:gson-2.10.1.jar TranslateRepo
-```
-
-**Features:**
-- ✅ Pure Java implementation
-- ✅ Uses Google Translate API (free, no key required)
-- ✅ Same functionality as Python version
-- ✅ Progress tracking with JSON
-- ✅ Supports 20 languages
-
-## Supported Languages
-
-1. English (en)
-2. Chinese Simplified (zh)
-3. Spanish (es)
-4. French (fr)
-5. Portuguese (pt)
-6. German (de)
-7. Japanese (ja)
-8. Korean (ko)
-9. Russian (ru)
-10. Italian (it)
-11. Arabic (ar)
-12. Hindi (hi)
-13. Turkish (tr)
-14. Vietnamese (vi)
-15. Polish (pl)
-16. Dutch (nl)
-17. Indonesian (id)
-18. Thai (th)
-19. Swedish (sv)
-20. Greek (el)
-
-## Output Structure
-
-Original:
-```
-docs/
-├── java/
-│ └── basics.md
-└── ...
-README.md
-```
-
-After translation to English:
-```
-docs_en/
-├── java/
-│ └── basics.en.md
-└── ...
-README.en.md
-```
-
-## How It Works
-
-1. **Scans** all `.md` files in `docs/` folder and `README.md`
-2. **Splits** large files into chunks (4000 chars) to respect API limits
-3. **Translates** each chunk using Google Translate
-4. **Preserves** markdown formatting and code blocks
-5. **Saves** to `docs_{lang}/` with `.{lang}.md` suffix
-6. **Tracks** progress to resume if interrupted
-
-## Example Workflow
-
-```bash
-# 1. Run translation tool
-python3 translate_repo.py
-
-# 2. Select language (e.g., 1 for English)
-Enter choice (1-20): 1
-
-# 3. Confirm translation
-Translate 292 files to English? (y/n): y
-
-# 4. Wait for completion (progress shown for each file)
-[1/292] docs/java/basics/java-basic-questions-01.md
- → docs_en/java/basics/java-basic-questions-01.en.md
- Chunk 1/3... ✅
- Chunk 2/3... ✅
- Chunk 3/3... ✅
- ✅ Translated (5234 → 6891 chars)
-
-# 5. Review and commit
-git add docs_en/ README.en.md
-git commit -m "Add English translation"
-git push
-```
-
-## Progress Tracking
-
-The tool saves progress to `.translation_progress.json`:
-```json
-{
- "completed": [
- "docs/java/basics/file1.md",
- "docs/java/basics/file2.md"
- ],
- "failed": []
-}
-```
-
-If interrupted, simply run the tool again - it will skip completed files and resume where it left off.
-
-## Performance
-
-- **Speed**: ~1 file per 5-10 seconds (depending on file size)
-- **For JavaGuide**: 292 files ≈ 2-3 hours total
-- **Rate limiting**: 1 second delay between chunks to avoid throttling
-
-## Notes
-
-- ✅ Free to use (no API key required)
-- ✅ Preserves markdown formatting
-- ✅ Handles code blocks correctly
-- ✅ Skips existing translations
-- ⚠️ Review translations for accuracy (automated translation may have errors)
-- ⚠️ Large repos may take several hours
-
-## Contributing
-
-After running the translation tool:
-
-1. Review translated files for accuracy
-2. Fix any translation errors manually
-3. Test that links and formatting work correctly
-4. Create a pull request with your translations
-
-## License
-
-These tools are provided as-is for translating JavaGuide documentation.
diff --git a/TranslateRepo.java b/TranslateRepo.java
deleted file mode 100644
index 626e8345717..00000000000
--- a/TranslateRepo.java
+++ /dev/null
@@ -1,386 +0,0 @@
-import java.io.*;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.*;
-import java.util.*;
-import java.util.stream.Collectors;
-import com.google.gson.*;
-
-/**
- * Repository Documentation Translation Tool
- *
- * Translates all markdown files in docs/ folder to target language.
- * Preserves directory structure and saves to docs_{lang}/ folder.
- *
- * Usage: java TranslateRepo
- */
-public class TranslateRepo {
-
- private static final int CHUNK_SIZE = 4000;
- private static final String PROGRESS_FILE = ".translation_progress.json";
- private static final Map LANGUAGES = new LinkedHashMap<>();
-
- static {
- LANGUAGES.put("1", new Language("English", "en", "en"));
- LANGUAGES.put("2", new Language("Chinese (Simplified)", "zh-CN", "zh"));
- LANGUAGES.put("3", new Language("Spanish", "es", "es"));
- LANGUAGES.put("4", new Language("French", "fr", "fr"));
- LANGUAGES.put("5", new Language("Portuguese", "pt", "pt"));
- LANGUAGES.put("6", new Language("German", "de", "de"));
- LANGUAGES.put("7", new Language("Japanese", "ja", "ja"));
- LANGUAGES.put("8", new Language("Korean", "ko", "ko"));
- LANGUAGES.put("9", new Language("Russian", "ru", "ru"));
- LANGUAGES.put("10", new Language("Italian", "it", "it"));
- LANGUAGES.put("11", new Language("Arabic", "ar", "ar"));
- LANGUAGES.put("12", new Language("Hindi", "hi", "hi"));
- LANGUAGES.put("13", new Language("Turkish", "tr", "tr"));
- LANGUAGES.put("14", new Language("Vietnamese", "vi", "vi"));
- LANGUAGES.put("15", new Language("Polish", "pl", "pl"));
- LANGUAGES.put("16", new Language("Dutch", "nl", "nl"));
- LANGUAGES.put("17", new Language("Indonesian", "id", "id"));
- LANGUAGES.put("18", new Language("Thai", "th", "th"));
- LANGUAGES.put("19", new Language("Swedish", "sv", "sv"));
- LANGUAGES.put("20", new Language("Greek", "el", "el"));
- }
-
- static class Language {
- String name;
- String code;
- String suffix;
-
- Language(String name, String code, String suffix) {
- this.name = name;
- this.code = code;
- this.suffix = suffix;
- }
- }
-
- static class TranslationProgress {
- Set completed = new HashSet<>();
- Set failed = new HashSet<>();
- }
-
- public static void main(String[] args) {
- try {
- printHeader();
-
- // Get repository path
- Scanner scanner = new Scanner(System.in);
- System.out.print("Enter repository path (default: current directory): ");
- String repoPathStr = scanner.nextLine().trim();
- if (repoPathStr.isEmpty()) {
- repoPathStr = ".";
- }
-
- Path repoPath = Paths.get(repoPathStr).toAbsolutePath();
- if (!Files.exists(repoPath)) {
- System.out.println("❌ Repository path does not exist: " + repoPath);
- return;
- }
-
- System.out.println("📁 Repository: " + repoPath);
- System.out.println();
-
- // Select language
- Language language = selectLanguage(scanner);
- System.out.println("\n✨ Selected: " + language.name);
- System.out.println();
-
- // Find markdown files
- System.out.println("🔍 Finding markdown files...");
- List mdFiles = findMarkdownFiles(repoPath);
-
- if (mdFiles.isEmpty()) {
- System.out.println("❌ No markdown files found in docs/ folder or README.md");
- return;
- }
-
- System.out.println("📄 Found " + mdFiles.size() + " markdown files");
- System.out.println();
-
- // Load progress
- TranslationProgress progress = loadProgress(repoPath);
-
- // Filter files
- List filesToTranslate = new ArrayList<>();
- for (Path file : mdFiles) {
- Path outputPath = getOutputPath(file, repoPath, language.suffix);
- if (Files.exists(outputPath)) {
- System.out.println("⏭️ Skipping (exists): " + repoPath.relativize(file));
- } else if (progress.completed.contains(file.toString())) {
- System.out.println("⏭️ Skipping (completed): " + repoPath.relativize(file));
- } else {
- filesToTranslate.add(file);
- }
- }
-
- if (filesToTranslate.isEmpty()) {
- System.out.println("\n✅ All files already translated!");
- return;
- }
-
- System.out.println("\n📝 Files to translate: " + filesToTranslate.size());
- System.out.println();
-
- // Confirm
- System.out.print("Translate " + filesToTranslate.size() + " files to " + language.name + "? (y/n): ");
- String confirm = scanner.nextLine().trim().toLowerCase();
- if (!confirm.equals("y")) {
- System.out.println("❌ Translation cancelled");
- return;
- }
-
- System.out.println();
- System.out.println("=".repeat(70));
- System.out.println("Translating to " + language.name + "...");
- System.out.println("=".repeat(70));
- System.out.println();
-
- // Translate files
- int totalInputChars = 0;
- int totalOutputChars = 0;
- List failedFiles = new ArrayList<>();
-
- for (int i = 0; i < filesToTranslate.size(); i++) {
- Path inputPath = filesToTranslate.get(i);
- Path relativePath = repoPath.relativize(inputPath);
- Path outputPath = getOutputPath(inputPath, repoPath, language.suffix);
-
- System.out.println("[" + (i + 1) + "/" + filesToTranslate.size() + "] " + relativePath);
- System.out.println(" → " + repoPath.relativize(outputPath));
-
- try {
- int[] chars = translateFile(inputPath, outputPath, language.code);
- totalInputChars += chars[0];
- totalOutputChars += chars[1];
-
- progress.completed.add(inputPath.toString());
- saveProgress(repoPath, progress);
-
- System.out.println(" ✅ Translated (" + chars[0] + " → " + chars[1] + " chars)");
- System.out.println();
-
- } catch (Exception e) {
- System.out.println(" ❌ Failed: " + e.getMessage());
- failedFiles.add(relativePath.toString());
- progress.failed.add(inputPath.toString());
- saveProgress(repoPath, progress);
- System.out.println();
- }
- }
-
- // Summary
- System.out.println("=".repeat(70));
- System.out.println("Translation Complete!");
- System.out.println("=".repeat(70));
- System.out.println("✅ Translated: " + (filesToTranslate.size() - failedFiles.size()) + " files");
- System.out.println("📊 Input: " + String.format("%,d", totalInputChars) + " characters");
- System.out.println("📊 Output: " + String.format("%,d", totalOutputChars) + " characters");
-
- if (!failedFiles.isEmpty()) {
- System.out.println("\n❌ Failed: " + failedFiles.size() + " files");
- for (String file : failedFiles) {
- System.out.println(" - " + file);
- }
- }
-
- System.out.println("\n📁 Output directory: docs_" + language.suffix + "/");
- System.out.println("📁 README: README." + language.suffix + ".md");
- System.out.println();
- System.out.println("💡 Next steps:");
- System.out.println(" 1. Review translated files in docs_" + language.suffix + "/");
- System.out.println(" 2. git add docs_" + language.suffix + "/ README." + language.suffix + ".md");
- System.out.println(" 3. git commit -m 'Add " + language.name + " translation'");
- System.out.println(" 4. Create PR");
-
- } catch (Exception e) {
- System.err.println("Error: " + e.getMessage());
- e.printStackTrace();
- }
- }
-
- private static void printHeader() {
- System.out.println("=".repeat(70));
- System.out.println("Repository Documentation Translation Tool");
- System.out.println("=".repeat(70));
- System.out.println();
- }
-
- private static Language selectLanguage(Scanner scanner) {
- System.out.println("=".repeat(70));
- System.out.println("Select target language:");
- System.out.println("=".repeat(70));
-
- for (Map.Entry entry : LANGUAGES.entrySet()) {
- System.out.printf(" %2s. %s%n", entry.getKey(), entry.getValue().name);
- }
-
- System.out.println();
- while (true) {
- System.out.print("Enter choice (1-20): ");
- String choice = scanner.nextLine().trim();
- if (LANGUAGES.containsKey(choice)) {
- return LANGUAGES.get(choice);
- }
- System.out.println("❌ Invalid choice. Please enter a number between 1-20.");
- }
- }
-
- private static List findMarkdownFiles(Path repoPath) throws IOException {
- List files = new ArrayList<>();
-
- // Add README.md
- Path readme = repoPath.resolve("README.md");
- if (Files.exists(readme)) {
- files.add(readme);
- }
-
- // Add all .md files in docs/
- Path docsPath = repoPath.resolve("docs");
- if (Files.exists(docsPath)) {
- Files.walk(docsPath)
- .filter(p -> p.toString().endsWith(".md"))
- .forEach(files::add);
- }
-
- Collections.sort(files);
- return files;
- }
-
- private static Path getOutputPath(Path inputPath, Path repoPath, String langSuffix) {
- String fileName = inputPath.getFileName().toString();
-
- // Handle README.md
- if (fileName.equals("README.md")) {
- return repoPath.resolve("README." + langSuffix + ".md");
- }
-
- // Handle docs/ files
- Path docsPath = repoPath.resolve("docs");
- Path relative = docsPath.relativize(inputPath);
-
- // Change extension: file.md -> file.{lang}.md
- String stem = fileName.substring(0, fileName.length() - 3);
- String newName = stem + "." + langSuffix + ".md";
-
- return repoPath.resolve("docs_" + langSuffix).resolve(relative.getParent()).resolve(newName);
- }
-
- private static int[] translateFile(Path inputPath, Path outputPath, String targetLang) throws IOException {
- // Read input
- String content = Files.readString(inputPath, StandardCharsets.UTF_8);
- int inputChars = content.length();
-
- // Split into chunks
- List chunks = splitContent(content, CHUNK_SIZE);
-
- // Translate chunks
- StringBuilder translated = new StringBuilder();
- for (int i = 0; i < chunks.size(); i++) {
- System.out.print(" Chunk " + (i + 1) + "/" + chunks.size() + "... ");
- String translatedChunk = translateText(chunks.get(i), targetLang);
- translated.append(translatedChunk);
- System.out.println("✅");
-
- try {
- Thread.sleep(1000); // Rate limiting
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
-
- String translatedContent = translated.toString();
- int outputChars = translatedContent.length();
-
- // Create output directory
- Files.createDirectories(outputPath.getParent());
-
- // Write output
- Files.writeString(outputPath, translatedContent, StandardCharsets.UTF_8);
-
- return new int[]{inputChars, outputChars};
- }
-
- private static List splitContent(String content, int chunkSize) {
- List chunks = new ArrayList<>();
- StringBuilder currentChunk = new StringBuilder();
- boolean inCodeBlock = false;
-
- for (String line : content.split("\n")) {
- if (line.trim().startsWith("```")) {
- inCodeBlock = !inCodeBlock;
- }
-
- if (currentChunk.length() + line.length() > chunkSize && !inCodeBlock && currentChunk.length() > 0) {
- chunks.add(currentChunk.toString());
- currentChunk = new StringBuilder();
- }
-
- currentChunk.append(line).append("\n");
- }
-
- if (currentChunk.length() > 0) {
- chunks.add(currentChunk.toString());
- }
-
- return chunks;
- }
-
- private static String translateText(String text, String targetLang) throws IOException {
- // Use Google Translate API (free, no key required)
- String urlStr = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl="
- + targetLang + "&dt=t&q=" + URLEncoder.encode(text, StandardCharsets.UTF_8);
-
- URL url = new URL(urlStr);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- conn.setRequestProperty("User-Agent", "Mozilla/5.0");
-
- BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- StringBuilder response = new StringBuilder();
- String line;
- while ((line = in.readLine()) != null) {
- response.append(line);
- }
- in.close();
-
- // Parse JSON response
- JsonArray jsonArray = JsonParser.parseString(response.toString()).getAsJsonArray();
- StringBuilder translated = new StringBuilder();
-
- JsonArray translations = jsonArray.get(0).getAsJsonArray();
- for (int i = 0; i < translations.size(); i++) {
- JsonArray translation = translations.get(i).getAsJsonArray();
- translated.append(translation.get(0).getAsString());
- }
-
- return translated.toString();
- }
-
- private static TranslationProgress loadProgress(Path repoPath) {
- Path progressFile = repoPath.resolve(PROGRESS_FILE);
- if (Files.exists(progressFile)) {
- try {
- String json = Files.readString(progressFile);
- Gson gson = new Gson();
- return gson.fromJson(json, TranslationProgress.class);
- } catch (Exception e) {
- // Ignore errors, return new progress
- }
- }
- return new TranslationProgress();
- }
-
- private static void saveProgress(Path repoPath, TranslationProgress progress) {
- Path progressFile = repoPath.resolve(PROGRESS_FILE);
- try {
- Gson gson = new GsonBuilder().setPrettyPrinting().create();
- String json = gson.toJson(progress);
- Files.writeString(progressFile, json);
- } catch (Exception e) {
- System.err.println("Warning: Could not save progress: " + e.getMessage());
- }
- }
-}
diff --git a/docs/.vuepress/client.ts b/docs/.vuepress/client.ts
new file mode 100644
index 00000000000..9468f265cd4
--- /dev/null
+++ b/docs/.vuepress/client.ts
@@ -0,0 +1,12 @@
+import { defineClientConfig } from "vuepress/client";
+import { h } from "vue";
+import LayoutToggle from "./components/LayoutToggle.vue";
+import GlobalUnlock from "./components/unlock/GlobalUnlock.vue";
+import UnlockContent from "./components/unlock/UnlockContent.vue";
+
+export default defineClientConfig({
+ enhance({ app }) {
+ app.component("UnlockContent", UnlockContent);
+ },
+ rootComponents: [() => h(LayoutToggle), () => h(GlobalUnlock)],
+});
diff --git a/docs/.vuepress/components/LayoutToggle.vue b/docs/.vuepress/components/LayoutToggle.vue
new file mode 100644
index 00000000000..17eda78cb7f
--- /dev/null
+++ b/docs/.vuepress/components/LayoutToggle.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/components/unlock/GlobalUnlock.vue b/docs/.vuepress/components/unlock/GlobalUnlock.vue
new file mode 100644
index 00000000000..a1abdcb316a
--- /dev/null
+++ b/docs/.vuepress/components/unlock/GlobalUnlock.vue
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 为保障正常阅读体验,本站部分内容已开启一次性验证。验证后全站解锁。
+
+
+
+
![公众号二维码]()
+
+ 扫码/微信搜索关注
+ “JavaGuide”
+
+
回复 “验证码”
+
+
+
+
+
+
+
+
+ 验证码错误,请重试
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/components/unlock/UnlockContent.vue b/docs/.vuepress/components/unlock/UnlockContent.vue
new file mode 100644
index 00000000000..f85351ae8f4
--- /dev/null
+++ b/docs/.vuepress/components/unlock/UnlockContent.vue
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+ 为保障正常阅读体验,本站部分内容已开启一次性验证。验证后全站自动解锁。
+
+
+
+
![公众号二维码]()
+
+ 扫码关注公众号,回复 “验证码”
+
+
+
+
+
+
+
+
+
+ 验证码错误,请重新输入
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts
index eed17cf0e1d..b34f2b96aa5 100644
--- a/docs/.vuepress/config.ts
+++ b/docs/.vuepress/config.ts
@@ -7,54 +7,60 @@ export default defineUserConfig({
title: "JavaGuide",
description:
- "「Java 学习指北 + Java 面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识。准备 Java 面试,复习 Java 知识点,首选 JavaGuide! ",
+ "JavaGuide 是一份面向后端开发/后端面试的学习与复习指南,覆盖 Java、数据库/MySQL、Redis、分布式、高并发、高可用、系统设计等核心知识。",
lang: "zh-CN",
head: [
// meta
["meta", { name: "robots", content: "all" }],
["meta", { name: "author", content: "Guide" }],
- [
- "meta",
- {
- "http-equiv": "Cache-Control",
- content: "no-cache, no-store, must-revalidate",
- },
- ],
- ["meta", { "http-equiv": "Pragma", content: "no-cache" }],
- ["meta", { "http-equiv": "Expires", content: "0" }],
- [
- "meta",
- {
- name: "keywords",
- content:
- "Java基础, 多线程, JVM, 虚拟机, 数据库, MySQL, Spring, Redis, MyBatis, 系统设计, 分布式, RPC, 高可用, 高并发",
- },
- ],
- [
- "meta",
- {
- name: "description",
- content:
- "「Java学习 + 面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识。准备 Java 面试,首选 JavaGuide!",
- },
- ],
+ // [
+ // "meta",
+ // {
+ // name: "keywords",
+ // content:
+ // "JavaGuide, 后端面试, 后端开发, Java面试, Java基础, 并发编程, JVM, 数据库, MySQL, Redis, Spring, 分布式, 高并发, 高性能, 高可用, 系统设计, 消息队列, 缓存, 计算机网络, Linux",
+ // },
+ // ],
+ // [
+ // "meta",
+ // {
+ // name: "description",
+ // content:
+ // "JavaGuide 是一份面向后端开发/后端面试的学习与复习指南,覆盖 Java、数据库/MySQL、Redis、分布式、高并发、高可用、系统设计等核心知识。",
+ // },
+ // ],
+ ["meta", { property: "og:site_name", content: "JavaGuide" }],
+ ["meta", { property: "og:type", content: "website" }],
+ ["meta", { property: "og:locale", content: "zh_CN" }],
+ ["meta", { property: "og:url", content: "https://javaguide.cn/" }],
["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
- // 添加百度统计
+ // 添加百度统计 - 异步加载避免阻塞渲染
[
"script",
- {},
+ { defer: true },
`var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?5dd2e8c97962d57b7b8fea1737c01743";
+ hm.async = true;
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();`,
],
],
- bundler: viteBundler(),
+ bundler: viteBundler({
+ viteOptions: {
+ css: {
+ preprocessorOptions: {
+ scss: {
+ silenceDeprecations: ["if-function"],
+ },
+ },
+ },
+ },
+ }),
theme,
diff --git a/docs/.vuepress/features/unlock/config.ts b/docs/.vuepress/features/unlock/config.ts
new file mode 100644
index 00000000000..c2272adb650
--- /dev/null
+++ b/docs/.vuepress/features/unlock/config.ts
@@ -0,0 +1,37 @@
+import { PREVIEW_HEIGHT } from "./heights";
+
+const withDefaultHeight = (
+ paths: readonly string[],
+ height: string = PREVIEW_HEIGHT.XL,
+): Record =>
+ Object.fromEntries(paths.map((path) => [path, height]));
+
+export const unlockConfig = {
+ // 版本号变更可强制用户重新验证
+ unlockVersion: "v1",
+ // 调试用:设为 true 时无视本地已解锁状态,始终触发限制
+ forceLock: false,
+ code: "8888",
+ // 使用相对路径,图片放在 docs/.vuepress/public/images 下
+ qrCodeUrl: "/images/qrcode-javaguide.jpg",
+ // 路径 -> 可见高度(建议使用 PREVIEW_HEIGHT 预设)
+ protectedPaths: {
+ ...withDefaultHeight([
+ "/java/jvm/memory-area.html",
+ "/java/basis/java-basic-questions-02.html",
+ "/java/collection/java-collection-questions-02.html",
+ "/cs-basics/network/tcp-connection-and-disconnection.html",
+ "/cs-basics/network/http-vs-https.html",
+ "/cs-basics/network/dns.html",
+ ]),
+ // 如需特殊高度,再单独覆盖
+ // "/some/page.html": PREVIEW_HEIGHT.MEDIUM,
+ },
+ // 目录前缀 -> 可见高度(该目录下所有文章都触发验证)
+ // 例如 "/java/collection/" 会匹配 "/java/collection/**"
+ protectedPrefixes: {
+ ...withDefaultHeight(["/database/", "/high-performance/"]),
+ },
+} as const;
+
+export { PREVIEW_HEIGHT };
diff --git a/docs/.vuepress/features/unlock/heights.ts b/docs/.vuepress/features/unlock/heights.ts
new file mode 100644
index 00000000000..34ba390ca45
--- /dev/null
+++ b/docs/.vuepress/features/unlock/heights.ts
@@ -0,0 +1,10 @@
+export const PREVIEW_HEIGHT = {
+ SHORT: "500px",
+ MEDIUM: "1000px",
+ LONG: "1500px",
+ XL: "2000px",
+ XXL: "2500px",
+} as const;
+
+export type PreviewHeight =
+ (typeof PREVIEW_HEIGHT)[keyof typeof PREVIEW_HEIGHT];
diff --git a/docs/.vuepress/navbar.ts b/docs/.vuepress/navbar.ts
index 4ab87e5660f..76aedfd3cc7 100644
--- a/docs/.vuepress/navbar.ts
+++ b/docs/.vuepress/navbar.ts
@@ -1,14 +1,9 @@
import { navbar } from "vuepress-theme-hope";
export default navbar([
- { text: "面试指南", icon: "java", link: "/home.md" },
- { text: "开源项目", icon: "github", link: "/open-source-project/" },
- { text: "技术书籍", icon: "book", link: "/books/" },
- {
- text: "程序人生",
- icon: "article",
- link: "/high-quality-technical-articles/",
- },
+ { text: "后端面试", icon: "java", link: "/home.md" },
+ { text: "AI面试", icon: "a-MachineLearning", link: "/ai/" },
+ { text: "实战项目", icon: "project", link: "/zhuanlan/interview-guide.md" },
{
text: "知识星球",
icon: "planet",
@@ -18,11 +13,7 @@ export default navbar([
icon: "about",
link: "/about-the-author/zhishixingqiu-two-years.md",
},
- {
- text: "星球专属优质专栏",
- icon: "about",
- link: "/zhuanlan/",
- },
+ { text: "星球专属优质专栏", icon: "about", link: "/zhuanlan/" },
{
text: "星球优质主题汇总",
icon: "star",
@@ -30,11 +21,29 @@ export default navbar([
},
],
},
+ {
+ text: "推荐阅读",
+ icon: "book",
+ children: [
+ { text: "开源项目", icon: "github", link: "/open-source-project/" },
+ { text: "技术书籍", icon: "book", link: "/books/" },
+ {
+ text: "程序人生",
+ icon: "code",
+ link: "/high-quality-technical-articles/",
+ },
+ ],
+ },
{
text: "网站相关",
icon: "about",
children: [
{ text: "关于作者", icon: "zuozhe", link: "/about-the-author/" },
+ {
+ text: "PDF下载",
+ icon: "pdf",
+ link: "/interview-preparation/pdf-interview-javaguide.md",
+ },
{
text: "面试突击",
icon: "pdf",
diff --git a/docs/.vuepress/public/images/qrcode-javaguide.jpg b/docs/.vuepress/public/images/qrcode-javaguide.jpg
new file mode 100644
index 00000000000..731d912ae05
Binary files /dev/null and b/docs/.vuepress/public/images/qrcode-javaguide.jpg differ
diff --git a/docs/.vuepress/public/robots.txt b/docs/.vuepress/public/robots.txt
new file mode 100644
index 00000000000..c7609e25d06
--- /dev/null
+++ b/docs/.vuepress/public/robots.txt
@@ -0,0 +1,5 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://javaguide.cn/sitemap.xml
+Host: https://javaguide.cn/
diff --git a/docs/.vuepress/shims-vue.d.ts b/docs/.vuepress/shims-vue.d.ts
new file mode 100644
index 00000000000..525d5f827b6
--- /dev/null
+++ b/docs/.vuepress/shims-vue.d.ts
@@ -0,0 +1,5 @@
+declare module "*.vue" {
+ import type { DefineComponent } from "vue";
+ const component: DefineComponent