diff --git a/.env.example b/.env.example
deleted file mode 100644
index d9ceeba272..0000000000
--- a/.env.example
+++ /dev/null
@@ -1,5 +0,0 @@
-DOCS_DEPLOY_HOST=your.server.ip
-DOCS_DEPLOY_PORT=22
-DOCS_DEPLOY_USER=root
-DOCS_DEPLOY_KEY_PATH=/absolute/path/to/your-key.pem
-DOCS_DEPLOY_REMOTE_DIR=/home/www/javabetter
diff --git a/.gitattributes b/.gitattributes
index 695c98056e..2f2cad2e13 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,11 +1,4 @@
-# 让 Markdown 内容计为 Java(项目是 Java 学习指南)
-*.md linguist-language=Java
-
-# 排除前端/构建文件的语言统计
-*.py linguist-vendored
-*.js linguist-vendored
-*.css linguist-vendored
-*.scss linguist-vendored
-*.ts linguist-vendored
-*.vue linguist-vendored
-*.sh linguist-vendored
+* text=auto
+*.js linguist-language=java
+*.css linguist-language=java
+*.html linguist-language=java
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8910b42377..f594577c86 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,12 @@
node_modules
-.env
.cache
.temp
package-lock.json
+yarn.lock
.DS_Store
dump.rdb
docs/.vuepress/.cache/
docs/.vuepress/.temp/
-docs/dist/
-dist.zip
images
*.log
-.yarn
-*-vip.md
-/.vscode
-.claude/
-.codex/
-.qoder/
-.agents/
-plugins/
+package.json
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000000..a6ef790d74
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+registry=https://registry.npm.taobao.org/
diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index 00c7affee4..0000000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,26 +0,0 @@
-- OK
-
-## 工具权限设置
-
-以下工具默认允许使用,不需要用户确认:
-- mcp__playwright__* (所有 playwright 浏览器相关工具)
-
-## 工具使用规则
-
-### 获取网页内容
-
-遇到以下情况时,**直接使用 `mcp__playwright` 工具打开浏览器获取内容**,不要询问用户:
-
-- 微信公众号文章链接(mp.weixin.qq.com)
-- 需要登录才能访问的页面
-- WebFetch 返回错误或超时的页面
-- 动态渲染的页面内容
-
-**使用方式:**
-```
-1. mcp__playwright__browser_navigate 打开目标URL
-2. mcp__playwright__browser_snapshot 获取页面内容
-3. mcp__playwright__browser_close 关闭页面(可选)
-```
-
-这是默认行为,不需要再询问用户是否使用浏览器。
diff --git a/CLAUDE.md b/CLAUDE.md
deleted file mode 100644
index c2a8bae25d..0000000000
--- a/CLAUDE.md
+++ /dev/null
@@ -1,342 +0,0 @@
-# CLAUDE.md
-
-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-
-## 写作任务(优先级最高)
-
-当我要求写文章、出选题、搜集热点、或者任何内容创作相关的任务时:
-
-### 第一步:确认当前日期
-```bash
-date "+%Y年%m月%d日"
-```
-后续所有操作以这个日期为准,不要使用训练数据中的日期。
-
-### 第二步:判断任务类型并读取对应 Skill
-
-**AI技术类文章** → 读取 `.claude/skills/ai-article/SKILL.md`
-触发关键词:
-- "写一篇AI文章"、"AI技术文章"
-- "大模型测评"、"AI工具实测"
-- "GLM"、"Claude Code"、"Qoder"、"Cursor"、"TRAE"等AI工具名
-- "SpringAI"、"RAG"、"Agent"、"工作流"等AI技术词
-- "搜集AI热点"、"AI选题"
-
-**标题生成** → 读取 `.claude/skills/title-generator/SKILL.md`
-触发关键词:
-- "帮我起标题"、"生成标题"、"想几个标题"、"取标题"
-- "爆款标题"、"打开率"、"标题优化"
-- 文章写完后用户要求起标题的场景
-
-注意:标题生成 Skill 是独立的,可以单独使用,也可以在写完文章后作为最后一步调用。
-
-### 第三步:执行任务
-- 素材参考目录:对应 Skill 的 `./sample/` 目录
-- 文章输出目录:`docs/src/sidebar/itwanger/`
-- 只读取对应 Skill 目录下的文件,不要跨目录读取
-
-### 使用示例
-
-**AI技术类:**
-```
-写一篇关于GLM-4.7实测的AI文章
-```
-```
-搜集最近的AI热点,出2个选题
-```
-```
-按照AI文章风格,写一篇Claude Code使用教程
-```
-
-**标题生成:**
-```
-帮我给这篇文章起5个标题,文章路径:docs/src/sidebar/itwanger/ai/xxx.md
-```
-```
-文章主题是微信接入OpenClaw,帮我想几个爆款标题
-```
-```
-写完了,帮我生成标题
-```
-
----
-
-## Project Overview
-
-**toBeBetterJavaer** (二哥的Java进阶之路) is a comprehensive Java learning guide and interview preparation resource, built as a static documentation website using VuePress 2. The site contains 595+ Markdown files covering Java fundamentals, enterprise development, databases, distributed systems, and interview preparation - all in Chinese.
-
-**Tech Stack:**
-- VuePress 2.0.0-rc.14 with vuepress-theme-hope 2.0.0-rc.52
-- Vite as the build tool
-- Vue 3.4.31
-- TypeScript (ES2022 target)
-- Package manager: **pnpm** (required)
-
-## Common Development Commands
-
-All commands must be run from the `docs/` directory:
-```bash
-# Install dependencies (run from docs/ directory)
-pnpm install
-
-# Start development server (with hot reload)
-pnpm docs:dev
-
-# Start dev server with cache cleared (use if you see stale content)
-pnpm docs:clean-dev
-
-# Build for production
-pnpm docs:build
-
-# Update VuePress packages
-pnpm docs:update-package
-```
-
-**Note:** The development server typically runs on `http://localhost:8080` by default.
-
-## Architecture & Structure
-
-### Directory Layout
-```
-toBeBetterJavaer/
-├── docs/ # Main documentation directory
-│ ├── src/ # Source content (595+ MD files)
-│ │ ├── .vuepress/ # VuePress configuration
-│ │ │ ├── config.ts # Main site configuration
-│ │ │ ├── theme.ts # Theme settings
-│ │ │ ├── navbar.ts # Top navigation bar
-│ │ │ ├── sidebar.ts # Sidebar structure
-│ │ │ ├── client.ts # Client-side enhancements
-│ │ │ ├── components/ # Custom Vue components
-│ │ │ ├── public/ # Static assets (images, icons)
-│ │ │ └── styles/ # Custom SCSS styles
-│ │ │
-│ │ ├── [Content Directories] # 47 topic directories (see below)
-│ │ ├── blog.md # Blog page
-│ │ ├── home.md # Home page
-│ │ └── README.md
-│ │
-│ ├── package.json # NPM scripts
-│ ├── pnpm-lock.yaml
-│ └── tsconfig.json # TypeScript config
-├── .claude/ # Claude Code Skills
-│ └── skills/
-│ ├── ai-article/ # AI技术文章 Skill
-│ │ ├── SKILL.md
-│ │ └── sample/ # AI技术类素材
-│ └── title-generator/ # 标题生成 Skill
-│ ├── SKILL.md
-│ └── references/ # 高/低打开率标题参考数据
-│ └── title-data.md
-└── images/ # Additional image assets
-```
-
-### Content Organization
-
-The 47 main content directories are organized into these categories:
-
-**Java Core:**
-- `overview/` - Introduction & environment setup
-- `basic-grammar/` - Syntax fundamentals
-- `array/`, `string/` - Data types
-- `oo/` - Object-oriented programming
-- `collection/` - Collections framework
-- `exception/` - Exception handling
-- `io/` - Input/Output streams
-
-**Advanced Java:**
-- `thread/` - Multithreading & concurrency (37 files)
-- `jvm/` - Java Virtual Machine (31 files)
-- `java8/` - Java 8+ features (Lambda, Stream, Optional)
-- `nio/` - Non-blocking I/O
-- `socket/` - Network programming
-
-**Enterprise Development:**
-- `springboot/` - Spring Boot tutorials (26 files)
-- `mybatis/` - Database ORM
-- `maven/` - Build tool
-- `git/` - Version control
-
-**Databases:**
-- `mysql/` - MySQL tutorials (23 files)
-- `redis/` - Caching
-- `mongodb/` - NoSQL
-
-**Distributed Systems:**
-- `mq/` - Message queues (RabbitMQ, Kafka)
-- `elasticsearch/` - Search engine
-- `zookeeper/` - Distributed coordination
-- `microservice/` - Microservices
-- `netty/` - Network framework
-
-**Interview & Career:**
-- `interview/` - Interview Q&A (16 files)
-- `mianjing/` - Interview experiences
-- `cityselect/` - Company recommendations by city (15 files)
-- `sidebar/sanfene/` - "面渣逆袭" (Mianza Nixi) interview prep series
-
-**Learning Resources:**
-- `xuexiluxian/` - Learning roadmaps (19 files)
-- `pdf/` - PDF downloads
-- `xuexijianyi/` - Study advice
-- `cs/` - Computer science basics
-
-**Special Sections:**
-- `zhishixingqiu/` - Premium content (paid membership)
-- `sidebar/itwanger/` - Author's articles (二哥原创文章)
-- `sidebar/sjtu/` - Shanghai Jiao Tong University survival guide
-- `szjy/` - Website building tutorials
-
-### Configuration Files
-
-**Key Config Files:**
-- `docs/src/.vuepress/config.ts` - Main site config (title, description, head meta, analytics)
-- `docs/src/.vuepress/theme.ts` - Theme settings (PWA, comments, search, encryption)
-- `docs/src/.vuepress/navbar.ts` - Top navigation menu structure
-- `docs/src/.vuepress/sidebar.ts` - Sidebar structure (auto-generated from directories)
-- `docs/tsconfig.json` - TypeScript configuration (ES2022, NodeNext modules)
-
-**Theme Features Enabled:**
-- Dark mode switch
-- PWA support (offline capability)
-- Blog functionality
-- Giscus comments integration
-- DocSearch (Algolia) for site search
-- Encryption for premium content
-- Article metadata display
-- Social media links (Zhihu, CSDN, GitHub, Gitee)
-
-### Markdown Front Matter
-
-Content files use front matter for metadata:
-```yaml
----
-title: Page Title
-shortTitle: Short Title
-description: Page description for SEO
-tag:
- - AI
- - 大模型
-category:
- - 技术文章
-author: 二哥
-date: 2026-01-21
----
-```
-
-### Supported Markdown Features
-
-- Code blocks with syntax highlighting
-- Mathematical formulas (MathJax)
-- PlantUML diagrams
-- Tabs component
-- Task lists
-- Image lazy loading
-- Custom Vue components
-
-## Development Workflow
-
-### Adding/Editing Content
-
-1. Create or edit Markdown files in appropriate directories under `docs/src/`
-2. Add front matter with relevant metadata
-3. Test locally: `pnpm docs:dev` (from `docs/` directory)
-4. View changes at `http://localhost:8080`
-
-### Building & Deployment
-```bash
-# From docs/ directory
-pnpm docs:build
-
-# Output is in docs/dist/
-# Deploy by uploading dist/ to Nginx static directory
-```
-
-The deployment process is manual:
-1. Build: `pnpm docs:build`
-2. Compress: `zip -r dist.zip dist`
-3. Upload to server Nginx directory
-4. Extract: `unzip dist.zip`
-
-### Navigation Structure
-
-**Top Navbar** (configured in `navbar.ts`):
-- 博客 (Blog)
-- 进阶之路 (Learning Path)
-- 知识星球 (Knowledge Planet - premium content)
-- 学习路线 (Learning Roadmaps)
-- 面渣逆袭 (Interview Prep)
-- 珍藏资源 (Resources - PDFs, articles, etc.)
-
-**Sidebars** are auto-generated from the directory structure in `sidebar.ts`.
-
-## Important Notes
-
-### Content Guidelines
-
-- All content is in **Chinese** (Simplified)
-- This is an educational resource focused on **Java learning and interview preparation**
-- Writing style should be "通俗易懂、风趣幽默" (easy to understand, humorous)
-- Target audience: Java learners from beginners to experienced developers
-
-### Technical Considerations
-
-- **Image Assets:** Use CDN URLs (`cdn.paicoding.com`) for images to reduce bundle size
-- **Analytics:** Baidu Analytics integration is configured
-- **Search:** Algolia DocSearch is integrated for site search
-- **Premium Content:** Some sections (like `zhishixingqiu/`) use encryption
-- **Performance:** PWA enabled for offline access
-
-### File Naming
-
-- Use lowercase with hyphens: `my-tutorial.md`
-- Avoid special characters and spaces
-- Keep names descriptive but concise
-
-### Testing
-
-There are **no automated tests** in this project. Testing is manual:
-1. Run dev server
-2. Visually inspect pages
-3. Check links and rendering
-4. Verify navigation works correctly
-
-### TypeScript Configuration
-
-- Target: ES2022
-- Module: NodeNext
-- Only `.vuepress/` directory files are compiled
-- Content files remain as Markdown
-
-## Key Dependencies
-
-**Core:**
-- vuepress: 2.0.0-rc.14
-- vuepress-theme-hope: 2.0.0-rc.52
-- vue: 3.4.31
-- @vuepress/bundler-vite: 2.0.0-rc.14
-
-**Plugins:**
-- @vuepress/plugin-docsearch: 2.0.0-rc.40
-- @vuepress/plugin-pwa: 2.0.0-rc.40
-- mathjax-full: ^3.2.2
-
-## Common Issues
-
-**Stale Content After Changes:**
-- Run `pnpm docs:clean-dev` instead of `pnpm docs:dev`
-- Or manually delete `.cache` and `.temp` directories
-
-**Build Errors:**
-- Ensure you're using **pnpm**, not npm or yarn
-- Delete `node_modules` and run `pnpm install`
-- Check Node.js version compatibility
-
-**Missing Images:**
-- Use CDN URLs when possible
-- Local images go in `docs/src/.vuepress/public/`
-
-**Navigation Not Updating:**
-- Check `navbar.ts` for top menu items
-- Check `sidebar.ts` for sidebar structure
-- Restart dev server after config changes
\ No newline at end of file
diff --git a/README.md b/README.md
index 4ee8d15859..851c098656 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,23 @@
-
-
+
+
-
+
-
-
- 
+
+
+ 
Github |
Gitee
# 为什么会有这个开源知识库
-> 知识库取名 **toBeBetterJavaer**,即 **To Be Better Javaer**,意为「成为一名更好的 Java 程序员」,是我自学 Java 以来所有原创文章和学习资料的大聚合。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。学 Java,就认准 二哥的Java进阶之路😄。
+> 知识库取名 **toBeBetterJavaer**,即 **To Be Better Javaer**,意为「成为一名更好的 Java 程序员」,是我自学 Java 以来所有原创文章和学习资料的大聚合。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。学 Java,就认准 Java程序员进阶之路😄。
>
> 知识库旨在为学习 Java 的小伙伴提供一系列:
> - **优质的原创 Java 教程**
@@ -28,396 +28,367 @@
>
> 赠人玫瑰手有余香。知识库会持续保持**更新**,欢迎收藏品鉴!
>
-> **转载须知** :以下所有文章如非文首说明为转载皆为我(沉默王二)的原创,且不允许转载,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
+> **转载须知** :以下所有文章如非文首说明为转载皆为我(沉默王二)的原创,转载在文首注明出处,如发现恶意抄袭/搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
>
> 推荐你通过在线阅读网站进行阅读,体验更好,速度更快!
>
-> - [**二哥的Java进阶之路在线网站(新域名:javabetter.cn 好记,推荐👍)**](https://javabetter.cn)
-> - [老版 Java 程序员进阶之路在线网址(老域名 tobebetterjavaer.com 难记)](https://tobebetterjavaer.com)
-> - [技术派之二哥的Java进阶之路专栏](https://paicoding.com/column/5/1)
+> - [**Java程序员进阶之路在线阅读网站(新版,推荐👍)**](https://tobebetterjavaer.com/)
+> - [技术派之Java程序员进阶之路专栏](https://paicoding.com/column/5/1)(二哥的另外一个网站)
>
-> 如果你更喜欢离线的 PDF 版本,戳这个链接获取[👍二哥的 Java 进阶之路.pdf](docs/src/overview/readme.md)
+> 如果你更喜欢离线的 PDF 版本,戳这个链接获取[👍二哥的 Java 进阶之路.pdf](docs/overview/readme.md)
-# 知识库地图
-
-> 知识库收录的核心内容就全在这里面了,大类分为 Java 核心、Java 企业级开发、数据库、计算机基础、求职面试、学习资源、程序人生,几乎你需要的这里都有。
+# 知识库的学习圈子
-
-
-一个人可以走得很快,但一群人才能走得更远。[二哥的编程星球](https://javabetter.cn/zhishixingqiu/)已经有 **10000 多名** 球友加入了(马上涨价到 169 元,抓紧时间趁没涨价前加入吧),如果你也需要一个优质的学习环境,扫描下方的优惠券加入我们吧。
-
-
-
-
-
-
-
-
+一个人可以走得很快,但一群人才能走得更远。知识库的学习圈子已经有 **1700 多名** 球友加入了,如果你也需要一个良好的学习氛围,[戳链接](https://tobebetterjavaer.com/zhishixingqiu/)加入我们吧!这是一个编程学习指南+ Java 项目实战+ LeetCode 刷题的私密圈子,你可以阅读知识库的配套专栏、向作者提问、帮你制定学习计划、和球友一起打卡成长。里面已经沉淀了非常多优质的内容,**相信能帮助你走的更快、更稳、更远**。
-新人可免费体验 3 天,不满意可全额退款(只能帮你到这里了😄)。
+# 知识库地图
-这是一个 **简历精修 + AI/Agent实战项目 + Java 面试指南 + LeetCode 刷题**的私密圈子,你可以阅读星球专栏、向二哥提问、帮你制定学习计划、和球友一起打卡成长。两个置顶帖「球友必看」和「知识图谱」里已经沉淀了非常多优质的内容,**相信能帮助你走的更快、更稳、更远**。
+> 知识库收录的核心内容就全在这里面了,大类分为 Java 核心、Java 企业级开发、数据库、计算机基础、求职面试、学习资源、程序人生,几乎你需要的这里都有。
-- [二哥精修简历服务,让你投了就有笔试&面试✌️](https://javabetter.cn/zhishixingqiu/jianli.html)
-- [二哥的PaiFlow工作流Agent项目派派工作流上线了,Agent时代你必须掌握✌️](https://javabetter.cn/zhishixingqiu/paiflow.html)
-- [二哥的RAG知识库项目派聪明上线了,AI时代你必须拥有的实战项目✌️](https://javabetter.cn/zhishixingqiu/paismart.html)
-- [Go 版本的派聪明RAG知识库项目上线了,学习 Go 语言的小伙伴有福了✌️](https://javabetter.cn/zhishixingqiu/paismart-go.html)
-- [二哥的技术派实战项目更新了,秋招&暑期/日常实习大杀器✌️](https://javabetter.cn/zhishixingqiu/paicoding.html)
-- [二哥的PmHub微服务实战项目上线了,校招和社招均可用✌️](https://javabetter.cn/zhishixingqiu/paicoding.html)
-- [二哥的Java面试指南专栏更新了,求职面试必备✌️](https://javabetter.cn/zhishixingqiu/mianshi.html)
+
# 学习路线
> 除了 Java 学习路线,还有 MySQL、Redis、C语言、C++、Python、Go 语言、操作系统、前端、数据结构与算法、蓝桥杯、大数据、Android、.NET等硬核学习路线,欢迎收藏品鉴!
- * [Java学习路线一条龙版(建议收藏🔥)](docs/src/xuexiluxian/java/yitiaolong.md)
- * [Java并发编程学习路线(建议收藏🔥)](docs/src/xuexiluxian/java/thread.md)
- * [Java虚拟机学习路线(建议收藏🔥)](docs/src/xuexiluxian/java/jvm.md)
- * [MySQL 学习路线(建议收藏🔥)](docs/src/xuexiluxian/mysql.md)
- * [Redis 学习路线(建议收藏🔥)](docs/src/xuexiluxian/redis.md)
- * [C语言学习路线(建议收藏🔥)](docs/src/xuexiluxian/c.md)
- * [C++学习路线(建议收藏🔥)](docs/src/xuexiluxian/ccc.md)
- * [Python学习路线(建议收藏🔥)](docs/src/xuexiluxian/python.md)
- * [Go语言学习路线(建议收藏🔥)](docs/src/xuexiluxian/go.md)
- * [操作系统学习路线(建议收藏🔥)](docs/src/xuexiluxian/os.md)
- * [前端学习路线(建议收藏🔥)](docs/src/xuexiluxian/qianduan.md)
- * [算法和数据结构学习路线(建议收藏🔥)](docs/src/xuexiluxian/algorithm.md)
- * [蓝桥杯学习路线(建议收藏🔥)](docs/src/xuexiluxian/lanqiaobei.md)
- * [大数据学习路线(建议收藏🔥)](docs/src/xuexiluxian/bigdata.md)
- * [Android 安卓学习路线(建议收藏🔥)](docs/src/xuexiluxian/android.md)
- * [.NET 学习路线(建议收藏🔥)](docs/src/xuexiluxian/donet.md)
- * [Linux 学习路线(建议收藏🔥)](docs/src/xuexiluxian/linux.md)
+ * [Java学习路线一条龙版(建议收藏🔥)](docs/xuexiluxian/java/yitiaolong.md)
+ * [Java并发编程学习路线(建议收藏🔥)](docs/xuexiluxian/java/thread.md)
+ * [Java虚拟机学习路线(建议收藏🔥)](docs/xuexiluxian/java/jvm.md)
+ * [MySQL 学习路线(建议收藏🔥)](docs/xuexiluxian/mysql.md)
+ * [Redis 学习路线(建议收藏🔥)](docs/xuexiluxian/redis.md)
+ * [C语言学习路线(建议收藏🔥)](docs/xuexiluxian/c.md)
+ * [C++学习路线(建议收藏🔥)](docs/xuexiluxian/ccc.md)
+ * [Python学习路线(建议收藏🔥)](docs/xuexiluxian/python.md)
+ * [Go语言学习路线(建议收藏🔥)](docs/xuexiluxian/go.md)
+ * [操作系统学习路线(建议收藏🔥)](docs/xuexiluxian/os.md)
+ * [前端学习路线(建议收藏🔥)](docs/xuexiluxian/qianduan.md)
+ * [算法和数据结构学习路线(建议收藏🔥)](docs/xuexiluxian/algorithm.md)
+ * [蓝桥杯学习路线(建议收藏🔥)](docs/xuexiluxian/lanqiaobei.md)
+ * [大数据学习路线(建议收藏🔥)](docs/xuexiluxian/bigdata.md)
+ * [Android 安卓学习路线(建议收藏🔥)](docs/xuexiluxian/android.md)
+ * [.NET 学习路线(建议收藏🔥)](docs/xuexiluxian/donet.md)
# 面渣逆袭
-> **面试前必读系列**!包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis、MyBatis、MySQL、操作系统、计算机网络、RocketMQ、分布式、微服务、设计模式、Linux 等等。
+> **面试前必读系列**!包括 Java 基础、Java 集合框架、Java 并发编程、Java 虚拟机、Spring、Redis、MyBatis、MySQL、操作系统、计算机网络、RocketMQ、分布式 等等。
-- [面渣逆袭(MySQL八股文面试题)必看👍](docs/src/sidebar/sanfene/mysql.md)
-- [面渣逆袭(Redis八股文面试题)必看👍](docs/src/sidebar/sanfene/redis.md)
-- [面渣逆袭(Spring八股文面试题)必看👍](docs/src/sidebar/sanfene/spring.md)
-- [面渣逆袭(Java 基础篇八股文面试题)必看👍](docs/src/sidebar/sanfene/javase.md)
-- [面渣逆袭(Java 集合框架篇八股文面试题)必看👍](docs/src/sidebar/sanfene/collection.md)
-- [面渣逆袭(Java 并发编程篇八股文面试题)必看👍](docs/src/sidebar/sanfene/javathread.md)
-- [面渣逆袭(Java 虚拟机篇八股文面试题)必看👍](docs/src/sidebar/sanfene/jvm.md)
-- [面渣逆袭(MyBatis八股文面试题)必看👍](docs/src/sidebar/sanfene/mybatis.md)
-- [面渣逆袭(操作系统八股文面试题)必看👍](docs/src/sidebar/sanfene/os.md)
-- [面渣逆袭(计算机网络八股文面试题)必看👍](docs/src/sidebar/sanfene/network.md)
-- [面渣逆袭(RocketMQ八股文面试题)必看👍](docs/src/sidebar/sanfene/rocketmq.md)
-- [面渣逆袭(分布式面试题八股文)必看👍](docs/src/sidebar/sanfene/fenbushi.md)
-- [面渣逆袭(微服务面试题八股文)必看👍](docs/src/sidebar/sanfene/weifuwu.md)
-- [面渣逆袭(设计模式面试题八股文)必看👍](docs/src/sidebar/sanfene/shejimoshi.md)
-- [面渣逆袭(Linux面试题八股文)必看👍](docs/src/sidebar/sanfene/linux.md)
-- [面渣逆袭(OpenClaw面试题八股文)必看👍](docs/src/sidebar/sanfene/openclaw.md)
-- [面渣逆袭(Skills面试题八股文)必看👍](docs/src/sidebar/sanfene/skills.md)
+- [面渣逆袭(Java 基础篇八股文面试题)必看👍](docs/sidebar/sanfene/javase.md)
+- [面渣逆袭(Java 集合框架篇八股文面试题)必看👍](docs/sidebar/sanfene/collection.md)
+- [面渣逆袭(Java 并发编程篇八股文面试题)必看👍](docs/sidebar/sanfene/javathread.md)
+- [面渣逆袭(Java 虚拟机篇八股文面试题)必看👍](docs/sidebar/sanfene/jvm.md)
+- [面渣逆袭(Spring八股文面试题)必看👍](docs/sidebar/sanfene/spring.md)
+- [面渣逆袭(Redis八股文面试题)必看👍](docs/sidebar/sanfene/redis.md)
+- [面渣逆袭(MyBatis八股文面试题)必看👍](docs/sidebar/sanfene/mybatis.md)
+- [面渣逆袭(MySQL八股文面试题)必看👍](docs/sidebar/sanfene/mysql.md)
+- [面渣逆袭(操作系统八股文面试题)必看👍](docs/sidebar/sanfene/os.md)
+- [面渣逆袭(计算机网络八股文面试题)必看👍](docs/sidebar/sanfene/network.md)
+- [面渣逆袭(RocketMQ八股文面试题)必看👍](docs/sidebar/sanfene/rocketmq.md)
+- [面渣逆袭(分布式面试题八股文)必看👍](docs/sidebar/sanfene/fenbushi.md)
-# Java基础
+# Java核心
-> **Java基础非常重要**!包括基础语法、面向对象、集合框架、异常处理、Java IO、网络编程、NIO、并发编程和 JVM。
+> **Java核心非常重要**!我将其分成了Java 基础篇(包括基础语法、面向对象、集合框架、异常处理、Java IO 等)、Java 并发篇和 Java 虚拟机篇。
## Java概述及环境配置
-- [《二哥的Java进阶之路》小册简介](docs/src/overview/readme.md)
-- [Java简史、特性、前景](docs/src/overview/what-is-java.md)
-- [Windows和macOS下安装JDK教程](docs/src/overview/jdk-install-config.md)
-- [在macOS和Windows上安装Intellij IDEA](docs/src/overview/IDEA-install-config.md)
-- [编写第一个程序Hello World](docs/src/overview/hello-world.md)
+- [Java简介](docs/overview/what-is-java.md)
+- [安装Java开发工具包JDK](docs/overview/jdk-install-config.md)
+- [安装集成开发环境Intellij IDEA](docs/overview/IDEA-install-config.md)
+- [编写第一个Java程序:Hello World](docs/overview/hello-world.md)
+
## Java基础语法
-- [48个关键字及2个保留字全解析](docs/src/basic-extra-meal/48-keywords.md)
-- [了解Java注释](docs/src/basic-grammar/javadoc.md)
-- [基本数据类型与引用数据类型](docs/src/basic-grammar/basic-data-type.md)
-- [自动类型转换与强制类型转换](docs/src/basic-grammar/type-cast.md)
-- [Java基本数据类型缓存池剖析(IntegerCache)](docs/src/basic-extra-meal/int-cache.md)
-- [Java运算符详解](docs/src/basic-grammar/operator.md)
-- [Java流程控制语句详解](docs/src/basic-grammar/flow-control.md)
-- [Java 语法基础练习题](docs/src/basic-grammar/basic-exercise.md)
+- [简单过一下Java中常用的48个关键字和2个保留字](docs/basic-extra-meal/48-keywords.md)
+- [Java注释](docs/basic-grammar/javadoc.md)
+- [Java中的数据类型(8种基本数据类型和引用数据类型)](docs/basic-grammar/basic-data-type.md)
+- [Java数据类型转换(强制类型转换+自动类型转换)](docs/basic-grammar/type-cast.md)
+- [聊聊Java基本数据类型缓存池](docs/basic-extra-meal/int-cache.md)
+- [Java运算符](docs/basic-grammar/operator.md)
+- [Java流程控制语句](docs/basic-grammar/flow-control.md)
## 数组&字符串
-- [掌握Java数组](docs/src/array/array.md)
-- [掌握 Java二维数组](docs/src/array/double-array.md)
-- [如何优雅地打印Java数组?](docs/src/array/print.md)
-- [深入解读String类源码](docs/src/string/string-source.md)
-- [为什么Java字符串是不可变的?](docs/src/string/immutable.md)
-- [深入理解Java字符串常量池](docs/src/string/constant-pool.md)
-- [详解 String.intern() 方法](docs/src/string/intern.md)
-- [String、StringBuilder、StringBuffer](docs/src/string/builder-buffer.md)
-- [Java中equals()与==的区别](docs/src/string/equals.md)
-- [最优雅的Java字符串拼接是哪种方式?](docs/src/string/join.md)
-- [如何在Java中拆分字符串?](docs/src/string/split.md)
+- [一文吃透Java数组](docs/array/array.md)
+- [聊聊Java的二维数组](docs/array/double-array.md)
+- [如何优雅地打印Java数组?](docs/array/print.md)
+- [聊聊Java字符串,以及为什么String是不可变的?](docs/string/immutable.md)
+- [深入理解Java字符串常量池](docs/string/constant-pool.md)
+- [深入解析String.intern()方法](docs/string/intern.md)
+- [聊聊String、StringBuilder、StringBuffer 三兄弟](docs/string/builder-buffer.md)
+- [Java如何判断两个字符串是否相等?](docs/string/equals.md)
+- [最优雅的Java字符串拼接是哪种方式?](docs/string/join.md)
+- [如何在Java中优雅地分割String字符串?](docs/string/split.md)
+- [Java 9为什么要将String的底层实现由char数组改成了byte数组?](docs/basic-extra-meal/jdk9-char-byte-string.md)
## Java面向对象编程
-- [类和对象](docs/src/oo/object-class.md)
-- [Java中的包](docs/src/oo/package.md)
-- [Java变量](docs/src/oo/var.md)
-- [Java方法](docs/src/oo/method.md)
-- [Java可变参数详解](docs/src/basic-extra-meal/varables.md)
-- [手把手教你用 C语言实现 Java native 本地方法](docs/src/oo/native-method.md)
-- [Java构造方法](docs/src/oo/construct.md)
-- [Java访问权限修饰符](docs/src/oo/access-control.md)
-- [Java代码初始化块](docs/src/oo/code-init.md)
-- [Java抽象类](docs/src/oo/abstract.md)
-- [Java接口](docs/src/oo/interface.md)
-- [Java内部类](docs/src/oo/inner-class.md)
-- [深入理解Java三大特性:封装、继承和多态](docs/src/oo/encapsulation-inheritance-polymorphism.md)
-- [详解Java this与super关键字](docs/src/oo/this-super.md)
-- [详解Java static 关键字](docs/src/oo/static.md)
-- [详解Java final 关键字](docs/src/oo/final.md)
-- [掌握Java instanceof关键字](docs/src/basic-extra-meal/instanceof.md)
-- [聊聊Java中的不可变对象](docs/src/basic-extra-meal/immutable.md)
-- [方法重写 Override 和方法重载 Overload 有什么区别?](docs/src/basic-extra-meal/override-overload.md)
-- [深入理解Java中的注解](docs/src/basic-extra-meal/annotation.md)
-- [Java枚举:小小enum,优雅而干净](docs/src/basic-extra-meal/enum.md)
+- [一文彻底讲清楚Java中的类和对象](docs/oo/object-class.md)
+- [简单过了一下Java中的包](docs/oo/package.md)
+- [Java中的变量:局部变量、成员变量、静态变量、常量](docs/oo/var.md)
+- [Java中的方法:实例方法、静态方法、抽象方法](docs/oo/method.md)
+- [聊聊Java中的可变参数](docs/basic-extra-meal/varables.md)
+- [手把手教你用 C语言实现 Java native 方法](docs/oo/native-method.md)
+- [构造方法:Java对象创建时的必经之路](docs/oo/construct.md)
+- [聊一聊Java中的访问权限修饰符](docs/oo/access-control.md)
+- [Java中的代码初始化块](docs/oo/code-init.md)
+- [Java抽象类,看这一篇就够了,豁然开朗](docs/oo/abstract.md)
+- [Java接口,看这一篇就够了,简单易懂](docs/oo/interface.md)
+- [Java 抽象类和接口的区别](docs/oo/abstract-vs-interface.md)
+- [聊聊Java内部类:成员内部类、局部内部类、匿名内部类、静态内部类](docs/oo/inner-class.md)
+- [聊聊 Java 封装](docs/oo/encapsulation.md)
+- [深入理解 Java 继承](docs/oo/extends-bigsai.md)
+- [聊聊 Java 多态](docs/oo/polymorphism.md)
+- [Java中this和super关键字的用法总结](docs/oo/this-super.md)
+- [详解 static 关键字的作用:静态变量、静态方法、静态代码块、静态内部类](docs/oo/static.md)
+- [一文彻底搞懂 final 关键字](docs/oo/final.md)
+- [聊聊instanceof关键字](docs/basic-extra-meal/instanceof.md)
+- [聊聊Java中的不可变对象](docs/basic-extra-meal/immutable.md)
+- [方法重写 Override 和方法重载 Overload 有什么区别?](docs/basic-extra-meal/override-overload.md)
+- [深入理解Java中的注解](docs/basic-extra-meal/annotation.md)
## 集合框架(容器)
-- [Java集合框架概览,包括List、Set、Map、队列](docs/src/collection/gailan.md)
-- [深入探讨 Java ArrayList](docs/src/collection/arraylist.md)
-- [深入探讨 Java LinkedList](docs/src/collection/linkedlist.md)
-- [Java Stack详解](docs/src/collection/stack.md)
-- [Java HashMap详解](docs/src/collection/hashmap.md)
-- [Java LinkedHashMap详解](docs/src/collection/linkedhashmap.md)
-- [Java TreeMap详解](docs/src/collection/treemap.md)
-- [Java 双端队列 ArrayDeque详解](docs/src/collection/arraydeque.md)
-- [Java 优先级队列PriorityQueue详解](docs/src/collection/PriorityQueue.md)
-- [Java Comparable和Comparator的区别](docs/src/collection/comparable-omparator.md)
-- [时间复杂度,评估ArrayList和LinkedList的执行效率](docs/src/collection/time-complexity.md)
-- [ArrayList和LinkedList的区别](docs/src/collection/list-war-2.md)
-- [Java 泛型深入解析](docs/src/basic-extra-meal/generic.md)
-- [Java迭代器Iterator和Iterable有什么区别?](docs/src/collection/iterator-iterable.md)
-- [为什么禁止在foreach里执行元素的删除操作?](docs/src/collection/fail-fast.md)
+- [聊聊Java的集合框架](docs/collection/gailan.md)
+- [简单聊一下时间复杂度](docs/collection/time-complexity.md)
+- [Java ArrayList详解(附源码分析)](docs/collection/arraylist.md)
+- [Java LinkedList详解(附源码分析)](docs/collection/linkedlist.md)
+- [聊聊ArrayList和LinkedList的区别](docs/collection/list-war-2.md)
+- [深入理解Java中的泛型](docs/basic-extra-meal/generic.md)
+- [迭代器Iterator和Iterable有什么区别?](docs/collection/iterator-iterable.md)
+- [为什么不能在foreach里执行删除操作?](docs/collection/fail-fast.md)
+- [Java HashMap详解(附源码分析)](docs/collection/hashmap.md)
+- [Java LinkedHashMap详解(附源码分析)](docs/collection/linkedhashmap.md)
+- [Java TreeMap详解(附源码分析)](docs/collection/treemap.md)
+- [详解 Java 中的双端队列(ArrayDeque附源码分析)](docs/collection/arraydeque.md)
+- [详解 Java 中的优先级队列(PriorityQueue 附源码分析)](docs/collection/PriorityQueue.md)
+- [Comparable和Comparator的区别](docs/basic-extra-meal/comparable-omparator.md)
## Java IO
-- [深入了解 Java IO](docs/src/io/shangtou.md)
-- [Java File:IO 流的起点与终点](docs/src/io/file-path.md)
-- [Java 字节流:Java IO 的基石](docs/src/io/stream.md)
-- [Java 字符流:Reader和Writer的故事](docs/src/io/reader-writer.md)
-- [Java 缓冲流:Java IO 的读写效率有了质的飞升](docs/src/io/buffer.md)
-- [Java 转换流:Java 字节流和字符流的桥梁](docs/src/io/char-byte.md)
-- [Java 打印流:PrintStream & PrintWriter](docs/src/io/print.md)
-- [Java 序列流:Java 对象的序列化和反序列化](docs/src/io/serialize.md)
-- [Java Serializable 接口:明明就一个空的接口嘛](docs/src/io/Serializbale.md)
-- [深入探讨 Java transient 关键字](docs/src/io/transient.md)
+- [Java IO分类](docs/io/shangtou.md)
+- [详解Java File](docs/io/file-path.md)
+- [文件的世界,一切皆字节流(Stream)](docs/io/stream.md)
+- [Java字符流Reader和Writer的故事](docs/io/reader-writer.md)
+- [Java缓冲流(Buffered):读写速度有了质的飞升](docs/io/buffer.md)
+- [Java转换流,解决字符与字节之间编码、解码的乱码问题](docs/io/char-byte.md)
+- [Java序列化流,字节和对象之间的序列化和反序列化](docs/io/serialize.md)
+- [Java Serializable:明明就一个空的接口嘛](docs/io/Serializbale.md)
+- [招银面试官:说说Java transient关键字](docs/io/transient.md)
+- [Java打印流:PrintStream & PrintWriter](docs/io/print.md)
+
## 异常处理
-- [一文彻底搞懂Java异常处理,YYDS](docs/src/exception/gailan.md)
-- [深入理解 Java 中的 try-with-resources](docs/src/exception/try-with-resources.md)
-- [Java异常处理的20个最佳实践](docs/src/exception/shijian.md)
-- [空指针NullPointerException的传说](docs/src/exception/npe.md)
-- [try-catch 捕获异常真的会影响性能吗?](docs/src/exception/try-catch-xingneng.md)
+- [一文彻底搞懂Java异常处理,YYDS](docs/exception/gailan.md)
+- [深入理解 Java 中的 try-with-resouces 语法糖](docs/exception/try-with-resouces.md)
+- [Java异常处理的20个最佳实践](docs/exception/shijian.md)
+- [Java空指针NullPointerException的传说](docs/exception/npe.md)
## 常用工具类
-- [Java Scanner:扫描控制台输入的工具类](docs/src/common-tool/scanner.md)
-- [Java Arrays:专为数组而生的工具类](docs/src/common-tool/arrays.md)
-- [Apache StringUtils:专为Java字符串而生的工具类](docs/src/common-tool/StringUtils.md)
-- [Objects:专为操作Java对象而生的工具类](docs/src/common-tool/Objects.md)
-- [Java Collections:专为集合而生的工具类](docs/src/common-tool/collections.md)
-- [Hutool:国产良心工具包,让你的Java变得更甜](docs/src/common-tool/hutool.md)
-- [Guava:Google开源的Java工具库,太强大了](docs/src/common-tool/guava.md)
-- [其他常用Java工具类:IpUtil、MDC、ClassUtils、BeanUtils、ReflectionUtils](docs/src/common-tool/utils.md)
+- [Java Arrays:专为数组而生的工具类](docs/common-tool/arrays.md)
+- [Java Collections:专为集合框架而生的工具类](docs/common-tool/collections.md)
+- [Hutool:国产良心工具包,让你的Java变得更甜](docs/common-tool/hutool.md)
+- [Guava:Google开源的工具库,太强大了](docs/common-tool/guava.md)
+- [这10个工具类,让我的开发效率提升了50%](docs/common-tool/utils.md)
## Java新特性
-- [Java 8 Stream流:掌握流式编程的精髓](docs/src/java8/stream.md)
-- [Java 8 Optional最佳指南:解决空指针问题的优雅之选](docs/src/java8/optional.md)
-- [深入浅出Java 8 Lambda表达式:探索函数式编程的魅力](docs/src/java8/Lambda.md)
-- [Java 14 开箱,新特性Record、instanceof、switch香香香香](docs/src/java8/java14.md)
+- [Java 8 Stream流详细用法](docs/java8/stream.md)
+- [Java 8 Optional最佳指南](docs/java8/optional.md)
+- [深入浅出Java 8 Lambda表达式](docs/java8/Lambda.md)
+
+## Java重要知识点
+
+- [Java命名规范](docs/basic-extra-meal/java-naming.md)
+- [彻底弄懂Java中的Unicode和UTF-8编码](docs/basic-extra-meal/java-unicode.md)
+- [深入剖析Java中的拆箱和装箱](docs/basic-extra-meal/box.md)
+- [一文彻底讲明白的Java中的浅拷贝与深拷贝](docs/basic-extra-meal/deep-copy.md)
+- [深入理解Java中的hashCode方法](docs/basic-extra-meal/hashcode.md)
+- [为什么重写equals方法的时候必须要重写hashCode方法?](docs/basic-extra-meal/equals-hashcode.md)
+- [Java重写(Overriding)时应当遵守的11条规则](docs/basic-extra-meal/Overriding.md)
+- [Java到底是值传递还是引用传递?](docs/basic-extra-meal/pass-by-value.md)
+- [为什么JDK源码中,无限循环大多使用for(;;)而不是while(true)?](docs/basic-extra-meal/jdk-while-for-wuxian-xunhuan.md)
+- [instanceof关键字是如何实现的?](docs/basic-extra-meal/instanceof-jvm.md)
+- [Java不能实现真正泛型的原因是什么?](docs/basic-extra-meal/true-generic.md)
+- [新来个技术总监,彻底把 Java 枚举(enum)讲清楚了](docs/basic-extra-meal/enum.md)
+- [大白话说清楚Java反射:入门、使用、原理](docs/basic-extra-meal/fanshe.md)
## Java网络编程
-- [Java网络编程的基础:计算机网络](docs/src/socket/network-base.md)
-- [Java Socket:飞鸽传书的网络套接字](docs/src/socket/socket.md)
-- [牛逼,用Java Socket手撸了一个HTTP服务器](docs/src/socket/http.md)
+- [Java Socket:飞鸽传书的网络套接字](docs/socket/socket.md)
+- [牛逼,用Java Socket手撸了一个HTTP服务器](docs/socket/http.md)
## Java NIO
-- [Java NIO 比传统 IO 强在哪里?](docs/src/nio/nio-better-io.md)
-- [一文彻底解释清楚Java 中的NIO、BIO和AIO](docs/src/nio/BIONIOAIO.md)
-- [详解Java NIO的Buffer缓冲区和Channel通道](docs/src/nio/buffer-channel.md)
-- [聊聊 Java NIO中的Paths、Files](docs/src/nio/paths-files.md)
-- [Java NIO 网络编程实践:从入门到精通](docs/src/nio/network-connect.md)
-- [一文彻底理解Java IO模型](docs/src/nio/moxing.md)
+- [为什么我们要使用 Java NIO?](docs/nio/why.md)
+- [Java NIO 快速入门(buffer缓冲区、Channel管道、Selector选择器)](docs/nio/rumen.md)
+- [一文彻底理解Java IO模型(阻塞IO非阻塞IO/IO多路复用)](docs/nio/moxing.md)
+- [使用Java NIO完成网络通信](docs/nio/network-connect.md)
+- [如何给女朋友解释什么是 BIO、NIO 和 AIO?](docs/nio/BIONIOAIO.md)
-## 重要知识点
-
-- [Java命名规范:编写可读性强的代码](docs/src/basic-extra-meal/java-naming.md)
-- [解决中文乱码:字符编码全攻略 - ASCII、Unicode、UTF-8、GB2312详解](docs/src/basic-extra-meal/java-unicode.md)
-- [深入浅出Java拆箱与装箱](docs/src/basic-extra-meal/box.md)
-- [深入理解Java浅拷贝与深拷贝](docs/src/basic-extra-meal/deep-copy.md)
-- [Java hashCode方法解析](docs/src/basic-extra-meal/hashcode.md)
-- [Java到底是值传递还是引用传递?](docs/src/basic-extra-meal/pass-by-value.md)
-- [为什么无法实现真正的泛型?](docs/src/basic-extra-meal/true-generic.md)
-- [Java 反射详解](docs/src/basic-extra-meal/fanshe.md)
## Java并发编程
-- [并发编程小册简介](docs/src/thread/readme.md)
-- [Java多线程入门](docs/src/thread/wangzhe-thread.md)
-- [获取线程的执行结果](docs/src/thread/callable-future-futuretask.md)
-- [Java线程的6种状态及切换](docs/src/thread/thread-state-and-method.md)
-- [线程组和线程优先级](docs/src/thread/thread-group-and-thread-priority.md)
-- [进程与线程的区别](docs/src/thread/why-need-thread.md)
-- [多线程带来了哪些问题?](docs/src/thread/thread-bring-some-problem.md)
-- [Java的内存模型(JMM)](docs/src/thread/jmm.md)
-- [volatile关键字解析](docs/src/thread/volatile.md)
-- [synchronized关键字解析](docs/src/thread/synchronized-1.md)
-- [synchronized的四种锁状态](docs/src/thread/synchronized.md)
-- [深入浅出偏向锁](docs/src/thread/pianxiangsuo.md)
-- [CAS详解](docs/src/thread/cas.md)
-- [AQS详解](docs/src/thread/aqs.md)
-- [锁分类和 JUC](docs/src/thread/lock.md)
-- [重入锁ReentrantLock](docs/src/thread/reentrantLock.md)
-- [读写锁ReentrantReadWriteLock](docs/src/thread/ReentrantReadWriteLock.md)
-- [等待通知条件Condition](docs/src/thread/condition.md)
-- [线程阻塞唤醒类LockSupport](docs/src/thread/LockSupport.md)
-- [Java的并发容器](docs/src/thread/map.md)
-- [并发容器ConcurrentHashMap](docs/src/thread/ConcurrentHashMap.md)
-- [非阻塞队列ConcurrentLinkedQueue](docs/src/thread/ConcurrentLinkedQueue.md)
-- [阻塞队列BlockingQueue](docs/src/thread/BlockingQueue.md)
-- [并发容器CopyOnWriteArrayList](docs/src/thread/CopyOnWriteArrayList.md)
-- [本地变量ThreadLocal](docs/src/thread/ThreadLocal.md)
-- [线程池](docs/src/thread/pool.md)
-- [定时任务ScheduledThreadPoolExecutor](docs/src/thread/ScheduledThreadPoolExecutor.md)
-- [原子操作类Atomic](docs/src/thread/atomic.md)
-- [魔法类 Unsafe](docs/src/thread/Unsafe.md)
-- [通信工具类](docs/src/thread/CountDownLatch.md)
-- [Fork/Join](docs/src/thread/fork-join.md)
-- [生产者-消费者模式](docs/src/thread/shengchanzhe-xiaofeizhe.md)
+- [室友打了一把王者就学会了创建Java线程的3种方式](docs/thread/wangzhe-thread.md)
+- [Java线程的6种状态及切换(透彻讲解)](docs/thread/thread-state-and-method.md)
+- [线程组是什么?线程优先级如何设置?](docs/thread/thread-group-and-thread-priority.md)
+- [进程与线程的区别是什么?](docs/thread/why-need-thread.md)
+- [并发编程带来了哪些问题?](docs/thread/thread-bring-some-problem.md)
+- [全面理解Java的内存模型(JMM)](docs/thread/jmm.md)
+- [Java并发编程volatile关键字解析](docs/thread/volatile.md)
+- [Java中的synchronized锁的到底是什么?](docs/thread/synchronized.md)
+- [Java实现CAS的原理](docs/thread/cas.md)
+- [Java并发AQS详解](docs/thread/aqs.md)
+- [大致了解下Java的锁接口和锁](docs/thread/lock.md)
+- [公司空降一个美团大佬,彻底把Java中的锁”讲清楚了](docs/thread/suo.md)
+- [Java 15 终于把难搞的偏向锁移除了](docs/thread/pianxiangsuo.md)
+- [深入理解Java并发重入锁ReentrantLock](docs/thread/reentrantLock.md)
+- [深入理解Java并发读写锁ReentrantReadWriteLock](docs/thread/ReentrantReadWriteLock.md)
+- [深入理解Java并发线程协作类Condition](docs/thread/condition.md)
+- [深入理解Java并发线程线程阻塞唤醒类LockSupport](docs/thread/LockSupport.md)
+- [简单聊聊Java的并发集合容器](docs/thread/map.md)
+- [吊打Java并发面试官之ConcurrentHashMap](docs/thread/ConcurrentHashMap.md)
+- [吊打Java并发面试官之ConcurrentLinkedQueue](docs/thread/ConcurrentLinkedQueue.md)
+- [吊打Java并发面试官之CopyOnWriteArrayList](docs/thread/CopyOnWriteArrayList.md)
+- [吊打Java并发面试官之ThreadLocal](docs/thread/ThreadLocal.md)
+- [吊打Java并发面试官之BlockingQueue](docs/thread/BlockingQueue.md)
+- [面试必备:Java线程池](docs/thread/pool.md)
+- [为什么阿里巴巴要禁用Executors创建线程池?](docs/thread/ali-executors.md)
+- [深入剖析Java计划任务ScheduledThreadPoolExecutor](docs/thread/ScheduledThreadPoolExecutor.md)
+- [Java atomic包中的原子操作类总结](docs/thread/atomic.md)
+- [Java并发编程通信工具类CountDownLatch等一网打尽](docs/thread/CountDownLatch.md)
+- [深入理解Java并发编程之Fork/Join框架](docs/thread/fork-join.md)
+- [从根上理解生产者-消费者模式](docs/thread/shengchanzhe-xiaofeizhe.md)
## Java虚拟机
-- [JVM小册简介](docs/src/jvm/readme.md)
-- [大白话带你认识JVM](docs/src/jvm/what-is-jvm.md)
-- [JVM是如何运行Java代码的?](docs/src/jvm/how-run-java-code.md)
-- [Java的类加载机制(付费)](docs/src/jvm/class-load.md)
-- [Java的类文件结构](docs/src/jvm/class-file-jiegou.md)
-- [从javap的角度轻松看懂字节码](docs/src/jvm/bytecode.md)
-- [栈虚拟机与寄存器虚拟机](docs/src/jvm/vm-stack-register.md)
-- [字节码指令详解](docs/src/jvm/zijiema-zhiling.md)
-- [深入理解JVM的栈帧结构](docs/src/jvm/stack-frame.md)
-- [深入理解JVM的运行时数据区](docs/src/jvm/neicun-jiegou.md)
-- [深入理解JVM的垃圾回收机制](docs/src/jvm/gc.md)
-- [深入理解 JVM 的垃圾收集器:CMS、G1、ZGC](docs/src/jvm/gc-collector.md)
-- [Java 创建的对象到底放在哪?](docs/src/jvm/whereis-the-object.md)
-- [深入理解JIT(即时编译)](docs/src/jvm/jit.md)
-- [JVM 性能监控之命令行篇](docs/src/jvm/console-tools.md)
-- [JVM 性能监控之可视化篇](docs/src/jvm/view-tools.md)
-- [阿里开源的 Java 诊断神器 Arthas](docs/src/jvm/arthas.md)
-- [内存溢出排查优化实战](docs/src/jvm/oom.md)
-- [CPU 100% 排查优化实践](docs/src/jvm/cpu-percent-100.md)
-- [JVM 核心知识点总结](docs/src/jvm/zongjie.md)
-
-
-# Java进阶
-
-> - **到底能不能成为一名合格的 Java 程序员,从理论走向实战?Java进阶这部分内容就是一个分水岭**!
+- [JVM到底是什么?](docs/jvm/what-is-jvm.md)
+- [JVM到底是如何运行Java代码的?](docs/jvm/how-run-java-code.md)
+- [我竟然不再抗拒Java的类加载机制了](docs/jvm/class-load.md)
+- [详解Java的类文件(class文件)结构](docs/jvm/class-file-jiegou.md)
+- [从javap的角度轻松看懂字节码](docs/jvm/bytecode.md)
+- [JVM字节码指令详解](docs/jvm/zijiema-zhiling.md)
+- [虚拟机是如何执行字节码指令的?](docs/jvm/how-jvm-run-zijiema-zhiling.md)
+- [HSDB(Hotspot Debugger)从入门到实战](docs/jvm/hsdb.md)
+- [史上最通俗易懂的ASM教程](docs/jvm/asm.md)
+- [自己编译JDK](docs/jvm/compile-jdk.md)
+- [深入理解JVM的内存结构](docs/jvm/neicun-jiegou.md)
+- [Java 创建的对象到底放在哪?](docs/jvm/whereis-the-object.md)
+- [咱们从头到尾说一次Java垃圾回收](docs/jvm/gc.md)
+- [图解Java的垃圾回收机制](docs/jvm/tujie-gc.md)
+- [Java中9种常见的CMS GC问题分析与解决](docs/jvm/meituan-9-gc.md)
+- [Java问题诊断和排查工具(查看JVM参数、内存使用情况及分析)](docs/jvm/problem-tools.md)
+- [Java即时编译(JIT)器原理解析及实践](docs/jvm/jit.md)
+- [一次内存溢出排查优化实战](docs/jvm/oom.md)
+- [一次生产CPU 100% 排查优化实践](docs/jvm/cpu-percent-100.md)
+- [JVM 核心知识点总结](docs/jvm/zongjie.md)
+
+
+# Java企业级开发
+
+> - **到底能不能成为一名合格的 Java 程序员,从理论走向实战?Java 企业级开发这部分内容就是一个分水岭**!
> - 纸上得来终觉浅,须知此事要躬行。
## 开发/构建工具
> 工欲善其事必先利其器,这句话大家都耳熟能详了,熟练使用开发/构建工具可以让我们极大提升开发效率,解放生产力。
-- [5分钟带你深入浅出搞懂Nginx](docs/src/nginx/nginx.md)
+- [5分钟带你深入浅出搞懂Nginx](docs/nginx/nginx.md)
### IDEA
> 集成开发环境,Java 党主要就是 Intellij IDEA 了,号称史上最强大的 Java 开发工具,没有之一。
-- [分享 4 个阅读源码必备的 IDEA 调试技巧](docs/src/ide/4-debug-skill.md)
-- [分享 1 个可以在 IDEA 里下五子棋的插件](docs/src/ide/xechat.md)
-- [分享 10 个可以一站式开发的 IDEA 神级插件](docs/src/ide/shenji-chajian-10.md)
+- [分享 4 个阅读源码必备的 IDEA 调试技巧](docs/ide/4-debug-skill.md)
+- [分享 1 个可以在 IDEA 里下五子棋的插件](docs/ide/xechat.md)
+- [分享 10 个可以一站式开发的 IDEA 神级插件](docs/ide/shenji-chajian-10.md)
### Maven
> Maven 是目前比较流行的一个项目构建工具,基于 pom 坐标来帮助我们管理第三方依赖,以及项目打包。
-- [终于把项目构建神器Maven捋清楚了~](docs/src/maven/maven.md)
+- [终于把项目构建神器Maven捋清楚了~](docs/maven/maven.md)
### Git
> Git 是一个分布式版本控制系统,缔造者是大名鼎鼎的林纳斯·托瓦茲 (Linus Torvalds),Git 最初的目的是为了能更好的管理 Linux 内核源码。如今,Git 已经成为全球软件开发者的标配。如果说 Linux 项目促成了开源软件的成功并改写了软件行业的格局,那么 Git 则是改变了全世界开发者的工作方式和写作方式。
-- [1小时彻底掌握Git](docs/src/git/git-qiyuan.md)
-- [GitHub 远程仓库端口切换](docs/src/git/port-22-to-443.md)
+- [1小时彻底掌握Git,(可能是)史上最简单明了的 Git 教程](docs/git/git-qiyuan.md)
## Spring
-- [Spring AOP扫盲](docs/src/springboot/aop-log.md)
-- [Spring IoC扫盲](docs/src/springboot/ioc.md)
+- [Spring AOP扫盲](docs/springboot/aop-log.md)
+- [Spring IoC扫盲](docs/springboot/ioc.md)
## SpringBoot
-- [一分钟快速搭建Spring Boot项目](docs/src/springboot/initializr.md)
-- [Spring Boot 整合 lombok](docs/src/springboot/lombok.md)
-- [Spring Boot 整合 MySQL 和 Druid](docs/src/springboot/mysql-druid.md)
-- [Spring Boot 整合 JPA](docs/src/springboot/jpa.md)
-- [Spring Boot 整合 Thymeleaf 模板引擎](docs/src/springboot/thymeleaf.md)
-- [Spring Boot 如何开启事务支持?](docs/src/springboot/transaction.md)
-- [Spring Boot 中使用过滤器、拦截器、监听器](docs/src/springboot/Filter-Interceptor-Listener.md)
-- [Spring Boot 整合 Redis 实现缓存](docs/src/redis/redis-springboot.md)
-- [Spring Boot 整合 Logback 定制日志框架](docs/src/springboot/logback.md)
-- [Spring Boot 整合 Swagger-UI 实现在线API文档](docs/src/springboot/swagger.md)
-- [Spring Boot 整合 Knife4j,美化强化丑陋的Swagger](docs/src/gongju/knife4j.md)
-- [Spring Boot 整合 Spring Task 实现定时任务](docs/src/springboot/springtask.md)
-- [Spring Boot 整合 MyBatis-Plus AutoGenerator 生成编程喵项目骨架代码](docs/src/kaiyuan/auto-generator.md)
-- [Spring Boot 整合Quartz实现编程喵定时发布文章](docs/src/springboot/quartz.md)
-- [Spring Boot 整合 MyBatis](docs/src/springboot/mybatis.md)
-- [一键部署 Spring Boot 到远程 Docker 容器](docs/src/springboot/docker.md)
-- [如何在本地(macOS环境)跑起来编程喵(Spring Boot+Vue)项目源码?](docs/src/springboot/macos-codingmore-run.md)
-- [如何在本地(Windows环境)跑起来编程喵(Spring Boot+Vue)项目源码?](docs/src/springboot/windows-codingmore-run.md)
-- [编程喵🐱实战项目如何在云服务器上跑起来?](docs/src/springboot/linux-codingmore-run.md)
-- [SpringBoot中处理校验逻辑的两种方式:Hibernate Validator+全局异常处理](docs/src/springboot/validator.md)
+- [一分钟快速搭建Spring Boot项目](docs/springboot/initializr.md)
+- [Spring Boot 整合 MySQL 和 Druid](docs/springboot/mysql-druid.md)
+- [Spring Boot 整合 JPA](docs/springboot/jpa.md)
+- [Spring Boot 整合 Thymeleaf 模板引擎](docs/springboot/thymeleaf.md)
+- [Spring Boot 如何开启事务支持?](docs/springboot/transaction.md)
+- [Spring Boot 中使用过滤器、拦截器、监听器](docs/springboot/Filter-Interceptor-Listener.md)
+- [Spring Boot 整合 Redis 实现缓存](docs/redis/redis-springboot.md)
+- [Spring Boot 整合 Logback 定制日志框架](docs/springboot/logback.md)
+- [Spring Boot 整合 Swagger-UI 实现在线API文档](docs/springboot/swagger.md)
+- [Spring Boot 整合 Knife4j,美化强化丑陋的Swagger](docs/gongju/knife4j.md)
+- [Spring Boot 整合 Spring Task 实现定时任务](docs/springboot/springtask.md)
+- [Spring Boot 整合 MyBatis-Plus AutoGenerator 生成编程喵项目骨架代码](docs/kaiyuan/auto-generator.md)
+- [Spring Boot 整合Quartz实现编程喵定时发布文章](docs/springboot/quartz.md)
+- [Spring Boot 整合 MyBatis](docs/springboot/mybatis.md)
+- [一键部署 Spring Boot 到远程 Docker 容器](docs/springboot/docker.md)
+- [如何在本地(macOS环境)跑起来编程喵(Spring Boot+Vue)项目源码?](docs/springboot/macos-codingmore-run.md)
+- [如何在本地(Windows环境)跑起来编程喵(Spring Boot+Vue)项目源码?](docs/springboot/windows-codingmore-run.md)
+- [编程喵🐱实战项目如何在云服务器上跑起来?](docs/springboot/linux-codingmore-run.md)
+- [SpringBoot中处理校验逻辑的两种方式:Hibernate Validator+全局异常处理](docs/springboot/validator.md)
## Netty
-- [超详细Netty入门,看这篇就够了!](docs/src/netty/rumen.md)
+- [超详细Netty入门,看这篇就够了!](docs/netty/rumen.md)
## 辅助工具
-- [Chocolatey:一款GitHub星标8.2k+的Windows命令行软件管理器,好用到爆!](docs/src/gongju/choco.md)
-- [Homebrew,GitHub 星标 32.5k+的 macOS 命令行软件管理神器,功能真心强大!](docs/src/gongju/brew.md)
-- [Tabby:一款逼格更高的开源终端工具,GitHub 星标 21.4k](docs/src/gongju/tabby.md)
-- [Warp:号称下一代终端神器,GitHub星标2.8k+,用完爱不释手](docs/src/gongju/warp.md)
-- [WindTerm:新一代开源免费的终端工具,GitHub星标6.6k+,太酷了!](docs/src/gongju/windterm.md)
-- [chiner:干掉 PowerDesigner,国人开源的数据库设计工具,界面漂亮,功能强大](docs/src/gongju/chiner.md)
-- [DBeaver:干掉付费的 Navicat,操作所有数据库就靠它了!](docs/src/gongju/DBeaver.md)
+- [Chocolatey:一款GitHub星标8.2k+的Windows命令行软件管理器,好用到爆!](docs/gongju/choco.md)
+- [Homebrew,GitHub 星标 32.5k+的 macOS 命令行软件管理神器,功能真心强大!](docs/gongju/brew.md)
+- [Tabby:一款逼格更高的开源终端工具,GitHub 星标 21.4k](docs/gongju/tabby.md)
+- [Warp:号称下一代终端神器,GitHub星标2.8k+,用完爱不释手](docs/gongju/warp.md)
+- [WindTerm:新一代开源免费的终端工具,GitHub星标6.6k+,太酷了!](docs/gongju/windterm.md)
+- [chiner:干掉 PowerDesigner,国人开源的数据库设计工具,界面漂亮,功能强大](docs/gongju/chiner.md)
+- [DBeaver:干掉付费的 Navicat,操作所有数据库就靠它了!](docs/gongju/DBeaver.md)
## 开源轮子
-- [Forest:一款极简的声明式HTTP调用API框架](docs/src/gongju/forest.md)
-- [Junit:一个开源的Java单元测试框架](docs/src/gongju/junit.md)
-- [fastjson:阿里巴巴开源的JSON解析库](docs/src/gongju/fastjson.md)
-- [Gson:Google开源的JSON解析库](docs/src/gongju/gson.md)
-- [Jackson:GitHub上star数最多的JSON解析库](docs/src/gongju/jackson.md)
-- [Log4j:Java日志框架的鼻祖](docs/src/gongju/log4j.md)
-- [Log4j 2:Apache维护的一款高性能日志记录工具](docs/src/gongju/log4j2.md)
-- [Logback:Spring Boot内置的日志处理框架](docs/src/gongju/logback.md)
-- [SLF4J:阿里巴巴强制使用的日志门面担当](docs/src/gongju/slf4j.md)
+- [Forest:一款极简的声明式HTTP调用API框架](docs/gongju/forest.md)
+- [Junit:一个开源的Java单元测试框架](docs/gongju/junit.md)
+- [fastjson:阿里巴巴开源的JSON解析库](docs/gongju/fastjson.md)
+- [Gson:Google开源的JSON解析库](docs/gongju/gson.md)
+- [Jackson:GitHub上star数最多的JSON解析库](docs/gongju/jackson.md)
+- [Log4j:Java日志框架的鼻祖](docs/gongju/log4j.md)
+- [Log4j 2:Apache维护的一款高性能日志记录工具](docs/gongju/log4j2.md)
+- [Logback:Spring Boot内置的日志处理框架](docs/gongju/logback.md)
+- [SLF4J:阿里巴巴强制使用的日志门面担当](docs/gongju/slf4j.md)
## 分布式
-- [全文搜索引擎Elasticsearch入门教程](docs/src/elasticsearch/rumen.md)
-- [可能是把ZooKeeper概念讲的最清楚的一篇文章](docs/src/zookeeper/jibenjieshao.md)
-- [微服务网关:从对比到选型,由理论到实践](docs/src/microservice/api-wangguan.md)
+- [全文搜索引擎Elasticsearch入门教程](docs/elasticsearch/rumen.md)
+- [可能是把ZooKeeper概念讲的最清楚的一篇文章](docs/zookeeper/jibenjieshao.md)
+- [微服务网关:从对比到选型,由理论到实践](docs/microservice/api-wangguan.md)
## 消息队列
-- [RabbitMQ入门教程(概念、应用场景、安装、使用)](docs/src/mq/rabbitmq-rumen.md)
-- [怎么确保消息100%不丢失?](docs/src/mq/100-budiushi.md)
-- [Kafka核心知识点大梳理](docs/src/mq/kafka.md)
+- [RabbitMQ入门教程(概念、应用场景、安装、使用)](docs/mq/rabbitmq-rumen.md)
+- [怎么确保消息100%不丢失?](docs/mq/100-budiushi.md)
+- [Kafka核心知识点大梳理](docs/mq/kafka.md)
# 数据库
@@ -425,29 +396,20 @@
## MySQL
-- [MySQL 的安装和连接,结合技术派实战项目来讲](docs/src/mysql/install.md)
-- [MySQL 的数据库操作,利用 Spring Boot 实现数据库的自动创建](docs/src/mysql/database.md)
-- [MySQL 表的基本操作,结合技术派的表自动初始化来讲](docs/src/mysql/table.md)
-- [MySQL 的数据类型,4000 字 20 张手绘图,彻底掌握](docs/src/mysql/data-type.md)
-- [MySQL 的字符集和比较规则,从跟上掌握](docs/src/mysql/charset.md)
-- [MySQL bin目录下的那些可执行文件,包括备份数据库、导入 CSV 等](docs/src/mysql/bin.md)
-- [MySQL 的字段属性,默认值、是否为空、主键、自增、ZEROLFILL等一网打尽](docs/src/mysql/column.md)
-- [MySQL 的简单查询,开始踏上 SELECT 之旅](docs/src/mysql/select-simple.md)
-- [MySQL 的 WEHRE 条件查询,重点搞懂 % 通配符](docs/src/mysql/select-where.md)
-- [如何保障MySQL和Redis的数据一致性?](docs/src/mysql/redis-shuju-yizhixing.md)
-- [从根上理解 MySQL 的事务](docs/src/mysql/lijie-shiwu.md)
-- [浅入深出 MySQL 中事务的实现](docs/src/mysql/shiwu-shixian.md)
+- [如何保障MySQL和Redis的数据一致性?](docs/mysql/redis-shuju-yizhixing.md)
+- [从根上理解 MySQL 的事务](docs/mysql/lijie-shiwu.md)
+- [浅入深出 MySQL 中事务的实现](docs/mysql/shiwu-shixian.md)
## Redis
-- [Redis入门(适合新手)](docs/src/redis/rumen.md)
-- [聊聊缓存雪崩、穿透、击穿](docs/src/redis/xuebeng-chuantou-jichuan.md)
+- [Redis入门(适合新手)](docs/redis/rumen.md)
+- [聊聊缓存雪崩、穿透、击穿](docs/redis/xuebeng-chuantou-jichuan.md)
## MongoDB
-- [MongoDB最基础入门教程](docs/src/mongodb/rumen.md)
+- [MongoDB最基础入门教程](docs/mongodb/rumen.md)
# 计算机基础
@@ -455,8 +417,8 @@
> - **计算机基础包括操作系统、计算机网络、计算机组成原理、数据结构与算法等**。对于任何一名想要走得更远的 Java 后端开发来说,都是必须要花时间和精力去夯实的。
> - 万丈高露平地起,勿在浮沙筑高台。
-- [操作系统核心知识点大梳理](docs/src/cs/os.md)
-- [计算机网络核心知识点大梳理](docs/src/cs/wangluo.md)
+- [操作系统核心知识点大梳理](docs/cs/os.md)
+- [计算机网络核心知识点大梳理](docs/cs/wangluo.md)
# 求职面试
@@ -466,54 +428,53 @@
## 面试题&八股文
-- [34 道 Java 精选面试题👍](docs/src/interview/java-34.md)
-- [13 道 Java HashMap 精选面试题👍](docs/src/interview/java-hashmap-13.md)
-- [60 道 MySQL 精选面试题👍](docs/src/interview/mysql-60.md)
-- [15 道 MySQL 索引精选面试题👍](docs/src/interview/mysql-suoyin-15.md)
-- [12 道 Redis 精选面试题👍](docs/src/interview/redis-12.md)
-- [40 道 Nginx 精选面试题👍](docs/src/interview/nginx-40.md)
-- [17 道 Dubbo 精选面试题👍](docs/src/interview/dubbo-17.md)
-- [40 道 Kafka 精选面试题👍](docs/src/interview/kafka-40.md)
-- [Java 基础背诵版八股文必看🍉](docs/src/interview/java-basic-baguwen.md)
-- [Java 并发编程背诵版八股文必看🍉](docs/src/interview/java-thread-baguwen.md)
-- [Java 虚拟机背诵版八股文必看🍉](docs/src/interview/java-jvm-baguwen.md)
-- [携程面试官👤:大文件上传时如何做到秒传?](docs/src/interview/mianshiguan-bigfile-miaochuan.md)
-- [阿里面试官👤:为什么要分库分表?](docs/src/interview/mianshiguan-fenkufenbiao.md)
-- [淘宝面试官👤:优惠券系统该如何设计?](docs/src/interview/mianshiguan-youhuiquan.md)
+- [34 道 Java 精选面试题👍](docs/interview/java-34.md)
+- [13 道 Java HashMap 精选面试题👍](docs/interview/java-hashmap-13.md)
+- [60 道 MySQL 精选面试题👍](docs/interview/mysql-60.md)
+- [15 道 MySQL 索引精选面试题👍](docs/interview/mysql-suoyin-15.md)
+- [12 道 Redis 精选面试题👍](docs/interview/redis-12.md)
+- [40 道 Nginx 精选面试题👍](docs/interview/nginx-40.md)
+- [17 道 Dubbo 精选面试题👍](docs/interview/dubbo-17.md)
+- [40 道 Kafka 精选面试题👍](docs/interview/kafka-40.md)
+- [Java 基础背诵版八股文必看🍉](docs/interview/java-basic-baguwen.md)
+- [Java 并发编程背诵版八股文必看🍉](docs/interview/java-thread-baguwen.md)
+- [Java 虚拟机背诵版八股文必看🍉](docs/interview/java-jvm-baguwen.md)
+- [携程面试官👤:大文件上传时如何做到秒传?](docs/interview/mianshiguan-bigfile-miaochuan.md)
+- [阿里面试官👤:为什么要分库分表?](docs/interview/mianshiguan-fenkufenbiao.md)
+- [淘宝面试官👤:优惠券系统该如何设计?](docs/interview/mianshiguan-youhuiquan.md)
## 优质面经
-- [硕士读者春招斩获深圳腾讯PCG和杭州阿里云 offer✌️](docs/src/mianjing/shanganaliyun.md)
-- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](docs/src/mianjing/shezynmjfxhelmtttjddd.md)
-- [非科班读者,用一年时间社招拿下阿里 Offer✌️](docs/src/mianjing/xuelybdzheloffer.md)
-- [二本读者社招两年半10家公司28轮面试面经✌️](docs/src/mianjing/huanxgzl.md)
-- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](docs/src/mianjing/quzjlsspdx.md)
-- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](docs/src/mianjing/zheisnylzldhzd.md)
-- [深漂 6 年了,回西安的一波面经总结✌️](docs/src/mianjing/chengxyspnhxagzl.md)
+- [硕士读者春招斩获深圳腾讯PCG和杭州阿里云 offer✌️](docs/mianjing/shanganaliyun.md)
+- [本科读者小公司一年工作经验社招拿下阿里美团头条京东滴滴等 offer✌️](docs/mianjing/shezynmjfxhelmtttjddd.md)
+- [非科班读者,用一年时间社招拿下阿里 Offer✌️](docs/mianjing/xuelybdzheloffer.md)
+- [二本读者社招两年半10家公司28轮面试面经✌️](docs/mianjing/huanxgzl.md)
+- [双非一本秋招收获腾讯ieg、百度、字节等6家大厂offer✌️](docs/mianjing/quzjlsspdx.md)
+- [双非学弟收割阿里、字节、B站校招 offer,附大学四年硬核经验总结✌️](docs/mianjing/zheisnylzldhzd.md)
+- [深漂 6 年了,回西安的一波面经总结✌️](docs/mianjing/chengxyspnhxagzl.md)
## 面试准备
-- [面试常见词汇扫盲+大厂面试特点分享💪](docs/src/nice-article/weixin/miansmtgl.md)
-- [有无实习/暑期实习 offer 如何准备秋招?💪](docs/src/nice-article/weixin/zijxjjdyfqzgl.md)
-- [简历如何优化,简历如何投递,面试如何准备?💪](docs/src/nice-article/weixin/luoczbmsddyb.md)
-- [校招时间节点、简历编写、笔试、HR面、实习等注意事项💪](docs/src/nice-article/weixin/youdxzhhmjzlycfx.md)
+- [面试常见词汇扫盲+大厂面试特点分享💪](docs/nice-article/weixin/miansmtgl.md)
+- [有无实习/暑期实习 offer 如何准备秋招?💪](docs/nice-article/weixin/zijxjjdyfqzgl.md)
+- [简历如何优化,简历如何投递,面试如何准备?💪](docs/nice-article/weixin/luoczbmsddyb.md)
+- [校招时间节点、简历编写、笔试、HR面、实习等注意事项💪](docs/nice-article/weixin/youdxzhhmjzlycfx.md)
## 城市选择
-- [武汉都有哪些值得加入的IT互联网公司?](docs/src/cityselect/wuhan.md)
-- [北京都有哪些值得加入的IT互联网公司?](docs/src/cityselect/beijing.md)
-- [广州都有哪些值得加入的IT互联网公司?](docs/src/cityselect/guangzhou.md)
-- [深圳都有哪些值得加入的IT互联网公司?](docs/src/cityselect/shenzhen.md)
-- [西安都有哪些值得加入的IT互联网公司?](docs/src/cityselect/xian.md)
-- [青岛都有哪些值得加入的IT互联网公司?](docs/src/cityselect/qingdao.md)
-- [郑州都有哪些值得加入的IT互联网公司?](docs/src/cityselect/zhengzhou.md)
-- [苏州都有哪些值得加入的IT互联网公司?](docs/src/cityselect/suzhou.md)
-- [南京都有哪些值得加入的IT互联网公司?](docs/src/cityselect/nanjing.md)
-- [杭州都有哪些值得加入的IT互联网公司?](docs/src/cityselect/hangzhou.md)
-- [成都都有哪些值得加入的IT互联网公司?](docs/src/cityselect/chengdu.md)
-- [济南都有哪些值得加入的IT互联网公司?](docs/src/cityselect/jinan.md)
+- [北京都有哪些值得加入的IT互联网公司?](docs/cityselect/beijing.md)
+- [广州都有哪些值得加入的IT互联网公司?](docs/cityselect/guangzhou.md)
+- [深圳都有哪些值得加入的IT互联网公司?](docs/cityselect/shenzhen.md)
+- [西安都有哪些值得加入的IT互联网公司?](docs/cityselect/xian.md)
+- [青岛都有哪些值得加入的IT互联网公司?](docs/cityselect/qingdao.md)
+- [郑州都有哪些值得加入的IT互联网公司?](docs/cityselect/zhengzhou.md)
+- [苏州都有哪些值得加入的IT互联网公司?](docs/cityselect/suzhou.md)
+- [南京都有哪些值得加入的IT互联网公司?](docs/cityselect/nanjing.md)
+- [杭州都有哪些值得加入的IT互联网公司?](docs/cityselect/hangzhou.md)
+- [成都都有哪些值得加入的IT互联网公司?](docs/cityselect/chengdu.md)
+- [济南都有哪些值得加入的IT互联网公司?](docs/cityselect/jinan.md)
# 学习资源
@@ -523,84 +484,71 @@
## PDF下载
-- [👏下载→30天速通 Java.pdf](docs/src/pdf/java30day.md)
-- [👏下载→Linux速查备忘手册.pdf](docs/src/pdf/linux.md)
-- [👏下载→超1000本计算机经典书籍分享](docs/src/pdf/java.md)
-- [👏下载→2022年全网最全关于程序员学习和找工作的PDF资源](docs/src/pdf/programmer-111.md)
-- [👏下载→深入浅出Java多线程PDF](docs/src/pdf/java-concurrent.md)
-- [👏下载→GitHub星标115k+的Java教程](docs/src/pdf/github-java-jiaocheng-115-star.md)
-- [👏下载→重学Java设计模式PDF](docs/src/pdf/shejimoshi.md)
-- [👏下载→Java版LeetCode刷题笔记](docs/src/pdf/java-leetcode.md)
-- [👏下载→阿里巴巴Java开发手册](docs/src/pdf/ali-java-shouce.md)
-- [👏下载→阮一峰C语言入门教程](docs/src/pdf/yuanyifeng-c-language.md)
-- [👏下载→BAT大佬的刷题笔记](docs/src/pdf/bat-shuati.md)
-- [👏下载→给操作系统捋条线PDF](docs/src/pdf/os.md)
-- [👏下载→豆瓣9.1分的Pro Git中文版](docs/src/pdf/progit.md)
-- [👏下载→简历模板](docs/src/pdf/jianli.md)
+- [👏下载→超1000本计算机经典书籍分享](docs/pdf/java.md)
+- [👏下载→2022年全网最全关于程序员学习和找工作的PDF资源](docs/pdf/programmer-111.md)
+- [👏下载→深入浅出Java多线程PDF](docs/pdf/java-concurrent.md)
+- [👏下载→GitHub星标115k+的Java教程](docs/pdf/github-java-jiaocheng-115-star.md)
+- [👏下载→重学Java设计模式PDF](docs/pdf/shejimoshi.md)
+- [👏下载→Java版LeetCode刷题笔记](docs/pdf/java-leetcode.md)
+- [👏下载→阿里巴巴Java开发手册](docs/pdf/ali-java-shouce.md)
+- [👏下载→阮一峰C语言入门教程](docs/pdf/yuanyifeng-c-language.md)
+- [👏下载→BAT大佬的刷题笔记](docs/pdf/bat-shuati.md)
+- [👏下载→给操作系统捋条线PDF](docs/pdf/os.md)
+- [👏下载→豆瓣9.1分的Pro Git中文版](docs/pdf/progit.md)
+- [👏下载→简历模板](docs/pdf/jianli.md)
## 学习建议
-- [计算机专业该如何自学编程,看哪些书籍哪些视频哪些教程?](docs/src/xuexijianyi/LearnCS-ByYourself.md)
-- [如何阅读《深入理解计算机系统》这本书?](docs/src/xuexijianyi/read-csapp.md)
-- [电子信息工程最好的出路的是什么?](docs/src/xuexijianyi/electron-information-engineering.md)
-- [如何填报计算机大类高考填志愿,计科、人工智能、软工、大数据、物联网、网络工程该怎么选?](docs/src/xuexijianyi/gaokao-zhiyuan-cs.md)
-- [测试开发工程师必读经典书籍有哪些?](docs/src/xuexijianyi/test-programmer-read-books.md)
-- [校招 Java 后端开发应该掌握到什么程度?](docs/src/xuexijianyi/xiaozhao-java-should-master.md)
-- [大裁员下,程序员如何做“副业”?](docs/src/xuexijianyi/chengxuyuan-fuye.md)
-- [如何在繁重的工作中持续成长?](docs/src/xuexijianyi/ruhzfzdgzzcxcz.md)
-- [如何获得高并发的经验?](docs/src/xuexijianyi/gaobingfa-jingyan-hsmcomputer.md)
-- [怎么跟 HR 谈薪资?](docs/src/xuexijianyi/hr-xinzi.md)
-- [程序员 35 岁危机,如何破局?](docs/src/xuexijianyi/35-weiji.md)
-- [不到 20 人的 IT 公司该去吗?](docs/src/xuexijianyi/20ren-it-quma.md)
-- [本科生如何才能进入腾讯、阿里等一流的互联网公司?](docs/src/xuexijianyi/benkesheng-ali-tengxun.md)
-- [计算机考研 408 统考该如何准备?](docs/src/xuexijianyi/408.md)
+- [计算机专业该如何自学编程,看哪些书籍哪些视频哪些教程?](docs/xuexijianyi/LearnCS-ByYourself.md)
+- [如何阅读《深入理解计算机系统》这本书?](docs/xuexijianyi/read-csapp.md)
+- [电子信息工程最好的出路的是什么?](docs/xuexijianyi/electron-information-engineering.md)
+- [如何填报计算机大类高考填志愿,计科、人工智能、软工、大数据、物联网、网络工程该怎么选?](docs/xuexijianyi/gaokao-zhiyuan-cs.md)
+- [测试开发工程师必读经典书籍有哪些?](docs/xuexijianyi/test-programmer-read-books.md)
+- [校招 Java 后端开发应该掌握到什么程度?](docs/xuexijianyi/xiaozhao-java-should-master.md)
+- [大裁员下,程序员如何做“副业”?](docs/xuexijianyi/chengxuyuan-fuye.md)
+- [如何在繁重的工作中持续成长?](docs/xuexijianyi/ruhzfzdgzzcxcz.md)
+- [如何获得高并发的经验?](docs/xuexijianyi/gaobingfa-jingyan-hsmcomputer.md)
+- [怎么跟 HR 谈薪资?](docs/xuexijianyi/hr-xinzi.md)
+- [程序员 35 岁危机,如何破局?](docs/xuexijianyi/35-weiji.md)
+- [不到 20 人的 IT 公司该去吗?](docs/xuexijianyi/20ren-it-quma.md)
+- [本科生如何才能进入腾讯、阿里等一流的互联网公司?](docs/xuexijianyi/benkesheng-ali-tengxun.md)
+- [计算机考研 408 统考该如何准备?](docs/xuexijianyi/408.md)
# 知识库搭建
-> 从购买阿里云服务器+域名购买+域名备案+HTTP 升级到 HTTPS,全方面记录《二哥的Java进阶之路》知识库的诞生和改进过程,涉及到 docsify、Git、Linux 命令、GitHub 仓库等实用知识点。
-
-- [购买云服务器](docs/src/szjy/buy-cloud-server.md)
-- [安装宝塔面板](docs/src/szjy/install-baota-mianban.md)
-- [购买域名&域名解析](docs/src/szjy/buy-domain.md)
-- [备案域名](docs/src/szjy/record-domain.md)
-- [给域名配置HTTPS证书](docs/src/szjy/https-domain.md)
-- [使用docsify+Git+GitHub+码云+阿里云服务器搭建知识库网站](docs/src/szjy/tobebetterjavaer-wangzhan-shangxian.md)
-
-本知识库使用 VuePress 搭建,并基于[VuePress Theme Hope](https://theme-hope.vuejs.press/zh/)主题,你可以把[仓库](https://github.com/itwanger/toBeBetterJavaer)拉到本地后直接通过 `pnpm docs:clean-dev` 跑起来。
+> 从购买阿里云服务器+域名购买+域名备案+HTTP 升级到 HTTPS,全方面记录《Java程序员进阶之路》知识库的诞生和改进过程,涉及到 docsify、Git、Linux 命令、GitHub 仓库等实用知识点。
->前提是你已经安装好 node.js 和 pnpm 环境。
-
+- [购买云服务器](docs/szjy/buy-cloud-server.md)
+- [安装宝塔面板](docs/szjy/install-baota-mianban.md)
+- [购买域名&域名解析](docs/szjy/buy-domain.md)
+- [备案域名](docs/szjy/record-domain.md)
+- [给域名配置HTTPS证书](docs/szjy/https-domain.md)
+- [使用docsify+Git+GitHub+码云+阿里云服务器搭建知识库网站](docs/szjy/tobebetterjavaer-wangzhan-shangxian.md)
-点击链接就可以在本地看到运行后的效果了。
-
-
-
-如果想部署服务器,可以进入 scripts 目录,执行 `./deploy-docs.sh` 脚本,需要先 `cp .env.example .env`,把你的服务器地址、用户名、密钥、远程路径等信息填进去。
# 联系作者
>- 作者是一名普通普通普通普通三连的 Java 后端开发者,热爱学习,热爱分享
>- 参加工作以后越来越理解交流和分享的重要性,在不停地汲取营养的同时,也希望帮助到更多的小伙伴们
->- 二哥的Java进阶之路,不仅是作者自学 Java 以来所有的原创文章和学习资料的大聚合,更是作者向这个世界传播知识的一个窗口。
+>- Java程序员进阶之路,不仅是作者自学 Java 以来所有的原创文章和学习资料的大聚合,更是作者向这个世界传播知识的一个窗口。
## 心路历程
-- [走近作者:个人介绍 Q&A](docs/src/about-the-author/readme.md)
-- [我的第一个,10 万(B站视频播放)](docs/src/about-the-author/bzhan-10wan.md)
-- [我的第一个,一千万!知乎阅读](docs/src/about-the-author/zhihu-1000wan.md)
-- [我的第二个,一千万!CSDN阅读](docs/src/about-the-author/csdn-1000wan.md)
+- [走近作者:个人介绍 Q&A](docs/about-the-author/readme.md)
+- [我的第一个,10 万(B站视频播放)](docs/about-the-author/bzhan-10wan.md)
+- [我的第一个,一千万!知乎阅读](docs/about-the-author/zhihu-1000wan.md)
+- [我的第二个,一千万!CSDN阅读](docs/about-the-author/csdn-1000wan.md)
## 联系方式
### 原创公众号
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
-
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
+关注二哥的原创公众号 **沉默王二**,回复**111** 即可免费领取。
-
+
### star趋势图
@@ -610,142 +558,27 @@ GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https
### 友情链接
-- [paicoding](https://github.com/itwanger/paicoding),⭐️一款好用又强大的开源社区,附详细教程,包括Java、Spring、MySQL、Redis、微服务&分布式、消息队列、操作系统、计算机网络、数据结构与算法等计算机专业核心知识点。学编程,就上技术派😁。
- [Hippo4J](https://github.com/acmenlt/dynamic-threadpool),🔥 强大的动态线程池,附带监控报警功能(没有依赖中间件),完全遵循阿里巴巴编码规范。
- [JavaGuide](https://github.com/Snailclimb/JavaGuide),「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识。准备 Java 面试,首选 JavaGuide!
### 捐赠鼓励
-开源不易,如果《二哥的Java进阶之路》对你有些帮助,可以请作者喝杯咖啡,算是对开源做出的一点点鼓励吧!
+开源不易,如果《Java程序员进阶之路》对你有些帮助,可以请作者喝杯咖啡,算是对开源做出的一点点鼓励吧!
-

+
:gift_heart: 感谢大家对我资金的赞赏,每隔一个月会统计一次。
时间|小伙伴|赞赏金额
---|---|---
-2025-07-02|橘子|4元
-2025-06-28|m*u|10元
-2025-06-15|l*y|5元
-2025-05-28|*航|6元
-2025-05-25|*星|10元
-2025-05-25|*(|6.66元
-2025-05-17|*鋈|4元
-2025-05-10|*庆|1元
-2025-05-08|芋*3|10元
-2025-04-17|*南|10元
-2025-03-31|:*D|4元
-2025-03-26|A*.|6.66元
-2025-02-18|R*.|6.66元
-2025-02-08|*金|5元
-2025-01-17|*蓝|8.88元
-2024-12-30|*甜|2元
-2024-12-26|*阳|1元
-2024-12-18|*。|1.5元
-2024-12-06|E*g|5元
-2024-12-04|*佚|0.88元
-2024-12-02|A*g|6.66元
-2024-11-30|1*0|10元
-2024-11-23|W*Z|11元
-2024-11-17|*旺|2元
-2024-11-16|*年|1元
-2024-11-14|*🤖|10元
-2024-11-13|*光|0.1元
-2024-10-25|*陈|1元
-2024-10-06|*天|10元
-2024-10-04|2*2|20元
-2024-09-25|c*l|1元
-2024-09-14|.*6|1.9元
-2024-08-16|*了|20元
-2024-08-14|*李|0.66元
-2024-08-12|*Z|6.66元
-2024-08-09|*峰|2元
-2024-07-13|*运|20元
-2024-07-01|*风|1元
-2024-06-30|*迷|1元
-2024-06-23|*瓦|1元
-2024-06-17|*芒|5元
-2024-06-13|*啊|9.99元
-2024-06-03|S*d|1元
-2024-05-23|*气|3元
-2024-05-22|w*r|6.6元
-2024-05-01|*笑|0.01元
-2024-04-24|1*0|3元
-2024-04-10|迷*x|21元
-2024-04-08|*青|5元
-2024-04-08|敲不出来的一个符号|1元
-2024-04-07|*i|0.01元
-2024-04-06|*牛|10元
-2024-04-03|Y*T|10元
-2024-04-02|B*E|2元
-2024-03-20|*卡|1元
-2024-03-18|*嘎|6.66元
-2024-03-17|*兴|0.01元
-2024-03-12|*鹏|0.02元
-2024-03-12|y*u|0.01元
-2024-02-29|r*y|6元
-2024-02-23|*~|9.99元
-2024-02-21|从头再来|5元
-2024-02-15|*斗|10元
-2024-02-02|*切|2元
-2024-02-01|*康|9元
-2024-01-31|*康|1元
-2024-01-22|*妙|10元
-2024-01-17|*清|9.9元
-2024-01-12|*奥|5元
-2024-01-04|*👈🏻|1元
-2024-01-03|*|3元
-2024-01-03|Y*o|2元
-2023-12-22|*逗|50元
-2023-11-25|*君|2元
-2023-10-23|*🐻|6.66元
-2023-10-17|*哈|5元
-2023-10-12|0*7|7.77元
-2023-10-03|S*d|0.5元
-2023-09-27|*1|1元
-2023-09-25|L*e|10.24元
-2023-09-19|*人|2元
-2023-09-15|L*D|2元
-2023-09-15|*暖|5元
-2023-09-11|A*B|1元
-2023-08-21|*氏|2元
-2023-08-18|*寻|1元
-2023-08-03|*案|10.24元
-2023-08-02|*,|1元
-2023-07-24|m*l|3元
-2023-07-20|lzy|6元
-2023-07-14|s*!|2元
-2023-07-02|*晴|1元
-2023-06-26|*雨|6.66元
-2023-06-21|*航|6元
-2023-06-21|*狼|3元
-2023-06-19|*定|2元
-2023-06-18|*道|5元
-2023-06-16|* 文|1元
-2023-06-14|G*e|66.6元
-2023-06-07|*.|0.5元
-2023-05-23|*W|5元
-2023-05-19|*飞|6元
-2023-05-10|c*r|1元
-2023-04-26|r*J|10.24元
-2023-04-22|*明|1元
-2023-04-09|* 刀|10元
-2023-04-03|*意|0.02元
-2023--03-17|*昌|8 元
-2023-03-16|~*~|66.6 元
-2023-03-15|*枫|6.6 元
-2023-03-10|十年|1 元
-2023-03-04|*风|5 元
-2023-02-26|一个表情(emoji)|1 元
-2023-02-23|曹*n|5元
-2023-02-11|昵称加载中.|6.6元
+2023-02-11|昵*.|6.6元
2023-02-09|*明|10元
2023-02-09|*风|5元
2023-02-09|*z|3元
2023-02-09|*夫|10元
-2023-02-08|*宝|5 元
+2023-02-08|*相|6元
2023-01-18|*念|0.01元
2023-01-18|*来|1元
2023-01-10|*A*t|1元
@@ -755,17 +588,18 @@ GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https
2022-11-10|*车|1元
2022-11-10|F*k|1元
2022-11-05|*H|3元
-2022-11-04|*金|0.02元
+2022-11-04|*千|0.02元
2022-11-04|*尘|15元
2022-11-02|*峰|1元
+2022-11-10|*车|1元
2022-10-29|~*~|6元
-2022-10-28|k*k|1元
+2022-10-28|*官|1元
2022-10-20|*电|2元
2022-10-15|*深|5元
2022-09-30|*君|1元
2022-09-28|*懂|1元
2022-09-27|*府|1元
-2022-09-23|*问号(emogji)|5元
+2022-09-23|*物|5元
2022-09-23|H*n|1元
2022-09-23|*a|0.01元
2022-09-08|*👀|20元
@@ -778,34 +612,28 @@ GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https
2022-06-10|*❤|1元
2022-06-09|'*'|1元
2022-06-07|*勇|1元
-2022-06-03|*鸭|1元
+2022-06-03|*张|1元
2022-05-12|*烟|10元
2022-04-25|*思|5元
2022-04-20|w*n|1元
-2022-04-12|E*e|10 元
-2022-03-19|*风|9.9元
-2022-03-04|袁晓波|99元
+2022-04-12|*生|10元
+2022-03-04|袁*波|99元
2022-02-17|*色|1元
2022-02-17|M*y|1元
2022-01-28|G*R|6.6元
2022-01-20|*光|50元
2022-01-14|*浩|1元
-2022-01-01|刚*好|3.6元
2022-01-01|马*谊|6.6元
+2022-01-01|刚*好|3.6元
2021-12-20|t*1|5 元
-2021-10-26|*猫|28 元
+2021-10-26|*鱼|28 元
2021-10-11|*人|28 元
-2021-09-28|*人|1 元
-2021-09-05|N*a|3 元
-2021-09-02|S*n|6.6 元
-2021-08-21|z*s|3 元
-2021-08-20|A*g|10 元
-2021-08-09|*滚|0.1 元
+2021-09-01|S*n|6.6 元
2021-08-02|*秒|1 元
2021-06-13|*7| 28 元
-2021-05-04|*学|169 元
2021-04-29|p*e|2 元
-2021-04-28|追风筝的神|1 元
+
+
### 参与贡献
diff --git a/_sidebar.md b/_sidebar.md
new file mode 100644
index 0000000000..360c465abf
--- /dev/null
+++ b/_sidebar.md
@@ -0,0 +1,49 @@
+* [为什么会有这个开源知识库](README.md?id=为什么会有这个开源知识库)
+* [知识库地图](README.md?id=知识库地图)
+* [学习路线](README.md?id=学习路线)
+* [Java核心](README.md?id=java核心)
+ * [Java面渣逆袭](README.md?id=Java面渣逆袭)
+ * [Java概述](README.md?id=java概述)
+ * [Java基础语法](README.md?id=java基础语法)
+ * [Java面向对象编程](README.md?id=Java面向对象编程)
+ * [字符串&数组](README.md?id=字符串&数组)
+ * [集合框架(容器)](README.md?id=集合框架(容器))
+ * [Java输入输出](README.md?id=Java输入输出)
+ * [异常处理](README.md?id=异常处理)
+ * [常用工具类](README.md?id=常用工具类)
+ * [Java新特性](README.md?id=Java新特性)
+ * [Java重要知识点](README.md?id=java重要知识点)
+ * [Java并发编程](README.md?id=Java并发编程)
+ * [Java虚拟机](README.md?id=Java虚拟机)
+* [Java企业级开发](README.md?id=Java企业级开发)
+ * [开发工具](README.md?id=开发工具)
+ * [IDE/编辑器](README.md?id=IDE/编辑器)
+ * [Spring](README.md?id=Spring)
+ * [SpringBoot](README.md?id=SpringBoot)
+ * [辅助工具/轮子](README.md?id=辅助工具)
+ * [安全篇](README.md?id=安全篇)
+ * [分布式](README.md?id=分布式)
+ * [高性能](README.md?id=高性能)
+ * [高可用](README.md?id=高可用)
+* [数据库](README.md?id=数据库)
+ * [MySQL](README.md?id=MySQL)
+ * [Redis](README.md?id=Redis)
+ * [MongoDB](README.md?id=MongoDB)
+* [计算机基础](README.md?id=计算机基础)
+* [求职面试](README.md?id=求职面试)
+ * [面试题集合](README.md?id=面试题集合)
+ * [背诵版八股文](README.md?id=背诵版八股文)
+ * [优质面经](README.md?id=优质面经)
+ * [面试准备](README.md?id=面试准备)
+ * [城市选择](README.md?id=城市选择)
+* [学习资源](README.md?id=学习资源)
+ * [PDF下载](README.md?id=PDF下载)
+ * [图文教程](README.md?id=图文教程)
+ * [视频教程](README.md?id=视频教程)
+ * [优质书单](README.md?id=优质书单)
+ * [学习建议](README.md?id=学习建议)
+* [知识库建设](README.md?id=知识库建设)
+* [联系作者](README.md?id=联系作者)
+ * [心路历程](README.md?id=心路历程)
+ * [联系方式](README.md?id=联系方式)
+
diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts
new file mode 100644
index 0000000000..aa813f2c82
--- /dev/null
+++ b/docs/.vuepress/config.ts
@@ -0,0 +1,163 @@
+import { docsearchPlugin } from "@vuepress/plugin-docsearch";
+import { commentPlugin } from "vuepress-plugin-comment2";
+import { pwaPlugin } from "vuepress-plugin-pwa2";
+import { defineUserConfig } from "vuepress";
+import theme from "./theme";
+
+export default defineUserConfig({
+ // 中文
+ lang: "zh-CN",
+ // 标题
+ title: "Java程序员进阶之路",
+ // 描述
+ description: "一份通俗易懂、风趣幽默的Java学习指南,内容涵盖Java基础、Java并发编程、Java虚拟机、Java企业级开发、Java面试等核心知识点。学Java,就认准Java程序员进阶之路",
+ // HTML 目录
+ dest: "./dist",
+ // 如果你正在使用 PWA 插件,我们推荐在你的 VuePress 配置文件中设置
+ shouldPrefetch: false,
+
+ head: [
+ // meta
+ ["meta", { name: "robots", content: "all" }],
+ ["meta", { name: "author", content: "沉默王二" }],
+ [
+ "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, Java基础, 并发编程, JVM, 虚拟机, 数据库, MySQL, Spring, Redis, MyBatis, SpringBoot, IDEA, 求职面试, 面渣逆袭, 学习路线",
+ },
+ ],
+ ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
+ [
+ "script",{},
+ `
+ var _hmt = _hmt || [];
+ (function() {
+ var hm = document.createElement("script");
+ hm.src = "https://hm.baidu.com/hm.js?5230ac143650bf5eb3c14f3fb9b1d3ec";
+ var s = document.getElementsByTagName("script")[0];
+ s.parentNode.insertBefore(hm, s);
+ })();
+ `
+ ],
+ [
+ "link",
+ {
+ rel: "stylesheet",
+ href: "//at.alicdn.com/t/font_3180624_7cy10l7jqqh.css",
+ },
+ ],
+ ],
+
+ plugins: [
+ // Progressive Web app,即渐进式网络应用程序,
+ // 允许网站通过支持该特性的浏览器将网站作为 App 安装在对应平台上。
+ pwaPlugin({
+ // favicon.ico一般用于作为缩略的网站标志,它显示位于浏览器的地址栏或者在标签上,用于显示网站的logo,
+ favicon: "https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/favicon.ico",
+ // 主题色
+ themeColor: "#096dd9",
+ apple: {
+ icon: "/assets/icon/apple-icon-152.png",
+ statusBarColor: "black",
+ },
+ msTile: {
+ image: "/assets/icon/ms-icon-144.png",
+ color: "#ffffff",
+ },
+ manifest: {
+ icons: [
+ {
+ src: "/assets/icon/chrome-mask-512.png",
+ sizes: "512x512",
+ purpose: "maskable",
+ type: "image/png",
+ },
+ {
+ src: "/assets/icon/chrome-mask-192.png",
+ sizes: "192x192",
+ purpose: "maskable",
+ type: "image/png",
+ },
+ {
+ src: "/assets/icon/chrome-512.png",
+ sizes: "512x512",
+ type: "image/png",
+ },
+ {
+ src: "/assets/icon/chrome-192.png",
+ sizes: "192x192",
+ type: "image/png",
+ },
+ ],
+ },
+ }),
+ // 留言
+ commentPlugin({
+ provider: "Giscus",
+ repo :"itwanger/tobebetterjavaer-giscus",
+ repoId:"R_kgDOHBJssg",
+ category:"Announcements",
+ categoryId:"DIC_kwDOHBJsss4COJOx",
+ }),
+ // 只能搜索
+ docsearchPlugin({
+ appId: "O566AMFNJH",
+ apiKey: "d9aebea8bd1a4f1e01201464bbab255f",
+ indexName: "tobebetterjavaer",
+ locales: {
+ "/": {
+ placeholder: "搜索文档",
+ translations: {
+ button: {
+ buttonText: "搜索文档",
+ buttonAriaLabel: "搜索文档",
+ },
+ modal: {
+ searchBox: {
+ resetButtonTitle: "清除查询条件",
+ resetButtonAriaLabel: "清除查询条件",
+ cancelButtonText: "取消",
+ cancelButtonAriaLabel: "取消",
+ },
+ startScreen: {
+ recentSearchesTitle: "搜索历史",
+ noRecentSearchesText: "没有搜索历史",
+ saveRecentSearchButtonTitle: "保存至搜索历史",
+ removeRecentSearchButtonTitle: "从搜索历史中移除",
+ favoriteSearchesTitle: "收藏",
+ removeFavoriteSearchButtonTitle: "从收藏中移除",
+ },
+ errorScreen: {
+ titleText: "无法获取结果",
+ helpText: "你可能需要检查你的网络连接",
+ },
+ footer: {
+ selectText: "选择",
+ navigateText: "切换",
+ closeText: "关闭",
+ searchByText: "搜索提供者",
+ },
+ noResultsScreen: {
+ noResultsText: "无法找到相关结果",
+ suggestedQueryText: "你可以尝试查询",
+ },
+ },
+ },
+ },
+ },
+ }),
+ ],
+
+ theme,
+});
diff --git a/docs/.vuepress/navbar.ts b/docs/.vuepress/navbar.ts
new file mode 100644
index 0000000000..37e39839a7
--- /dev/null
+++ b/docs/.vuepress/navbar.ts
@@ -0,0 +1,50 @@
+import { navbar } from "vuepress-theme-hope";
+
+export default navbar([
+ {
+ text: "博客",
+ icon: "gaishu",
+ link: "/blog.md"
+ },
+ {
+ text: "进阶之路",
+ icon: "lujing",
+ link: "/home.md"
+ },
+ {
+ text: "知识星球",
+ icon: "Artboard",
+ link: "/zhishixingqiu/"
+ },
+ {
+ text: "学习路线",
+ icon: "luxian",
+ link: "/xuexiluxian/"
+ },
+ {
+ text: "珍藏资源",
+ icon: "youzhi",
+ children: [
+ {
+ text: "PDF下载",
+ icon: "java",
+ link: "/pdf/readme.md"
+ },
+ {
+ text: "面渣逆袭",
+ icon: "zhunbei",
+ link: "/sidebar/sanfene/nixi.md"
+ },
+ {
+ text: "破解合集",
+ icon: "zhongyaotishi",
+ link: "/nice-article/itmind/"
+ },
+ ],
+ },
+ {
+ text: "B站视频",
+ icon: "bzhan",
+ link: "https://space.bilibili.com/513340480"
+ },
+]);
diff --git a/docs/src/.vuepress/public/assets/icon/apple-icon-152.png b/docs/.vuepress/public/assets/icon/apple-icon-152.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/apple-icon-152.png
rename to docs/.vuepress/public/assets/icon/apple-icon-152.png
diff --git a/docs/src/.vuepress/public/assets/icon/chrome-192.png b/docs/.vuepress/public/assets/icon/chrome-192.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/chrome-192.png
rename to docs/.vuepress/public/assets/icon/chrome-192.png
diff --git a/docs/src/.vuepress/public/assets/icon/chrome-512.png b/docs/.vuepress/public/assets/icon/chrome-512.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/chrome-512.png
rename to docs/.vuepress/public/assets/icon/chrome-512.png
diff --git a/docs/src/.vuepress/public/assets/icon/chrome-mask-192.png b/docs/.vuepress/public/assets/icon/chrome-mask-192.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/chrome-mask-192.png
rename to docs/.vuepress/public/assets/icon/chrome-mask-192.png
diff --git a/docs/src/.vuepress/public/assets/icon/chrome-mask-512.png b/docs/.vuepress/public/assets/icon/chrome-mask-512.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/chrome-mask-512.png
rename to docs/.vuepress/public/assets/icon/chrome-mask-512.png
diff --git a/docs/src/.vuepress/public/assets/icon/itwanger-282.png b/docs/.vuepress/public/assets/icon/itwanger-282.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/itwanger-282.png
rename to docs/.vuepress/public/assets/icon/itwanger-282.png
diff --git a/docs/src/.vuepress/public/assets/icon/itwanger-maskable.png b/docs/.vuepress/public/assets/icon/itwanger-maskable.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/itwanger-maskable.png
rename to docs/.vuepress/public/assets/icon/itwanger-maskable.png
diff --git a/docs/src/.vuepress/public/assets/icon/itwanger-monochrome.png b/docs/.vuepress/public/assets/icon/itwanger-monochrome.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/itwanger-monochrome.png
rename to docs/.vuepress/public/assets/icon/itwanger-monochrome.png
diff --git a/docs/src/.vuepress/public/assets/icon/ms-icon-144.png b/docs/.vuepress/public/assets/icon/ms-icon-144.png
similarity index 100%
rename from docs/src/.vuepress/public/assets/icon/ms-icon-144.png
rename to docs/.vuepress/public/assets/icon/ms-icon-144.png
diff --git a/docs/src/.vuepress/public/favicon.ico b/docs/.vuepress/public/favicon.ico
similarity index 100%
rename from docs/src/.vuepress/public/favicon.ico
rename to docs/.vuepress/public/favicon.ico
diff --git a/docs/src/.vuepress/public/itwanger.png b/docs/.vuepress/public/itwanger.png
similarity index 100%
rename from docs/src/.vuepress/public/itwanger.png
rename to docs/.vuepress/public/itwanger.png
diff --git a/docs/src/.vuepress/public/itwanger.svg b/docs/.vuepress/public/itwanger.svg
similarity index 100%
rename from docs/src/.vuepress/public/itwanger.svg
rename to docs/.vuepress/public/itwanger.svg
diff --git a/docs/src/.vuepress/public/logo.png b/docs/.vuepress/public/logo.png
similarity index 100%
rename from docs/src/.vuepress/public/logo.png
rename to docs/.vuepress/public/logo.png
diff --git a/docs/src/.vuepress/public/logo.svg b/docs/.vuepress/public/logo.svg
similarity index 100%
rename from docs/src/.vuepress/public/logo.svg
rename to docs/.vuepress/public/logo.svg
diff --git a/docs/src/.vuepress/sidebar.ts b/docs/.vuepress/sidebar.ts
similarity index 75%
rename from docs/src/.vuepress/sidebar.ts
rename to docs/.vuepress/sidebar.ts
index 64d7e186fb..4ca88b1c07 100644
--- a/docs/src/.vuepress/sidebar.ts
+++ b/docs/.vuepress/sidebar.ts
@@ -1,30 +1,38 @@
import { sidebar } from "vuepress-theme-hope";
-
-export default sidebar({
+export const sidebarConfig = sidebar({
"/zhishixingqiu/": [
"readme.md",
- "jianli",
- "paiflow",
- "paismart",
- "paismart-go",
- "paicoding",
- "pmhub",
- "mianshi",
"map",
- "qiuzhao-gongsi-mingdan",
+ "may",
+ "june",
+ "july",
+ "august"
],
+ // 你可以省略 .md 扩展名,以 / 结尾的路径会被推断为 /README.md(区分大小写)
"/nice-article/itmind/": [
"readme.md",
"shangwang.md",
+ "ideapxideajhideayjjhmideazxjhzcmpjjcyjjhqcyx",
+ "yigkymxczideatsyqdffblwxjcywdxbxt",
+ "ideapjazjczxjhmzcmyjjhcxgxz",
+ "ideajhmideajhmideapxideajhmideazcmideayjjhm",
+ "intellijidearhgbgxdsxbxt",
+ "navicatmacyjpx",
+ "navicatzxbwindowspjbjc",
+ "typorayjpx",
+ "typoramaczwpjbhyjjdkptmarkdownbjqmksimacsocom",
+ "xshellazpjbjcxshellpxffxbxt",
+ "pycharmjhpxmazjcnyrgxxbxt",
+ "webstormjhmwebstormwdzsjhmxbxt",
+ "visualstudiopxbazjcnfvisualstudiojhmmyxbxt",
+ "sublimetextzcmpjazjcqckyxbxt",
+ "termius-macos",
],
-
- // 你可以省略 .md 扩展名,以 / 结尾的路径会被推断为 /README.md(区分大小写)
"/pdf/": [
- "java30day",
- "linux",
"java",
"programmer-111",
"java-concurrent",
+ "github-java-jiaocheng-115-star",
"shejimoshi",
"java-leetcode",
"ali-java-shouce",
@@ -58,49 +66,21 @@ export default sidebar({
"bigdata",
"android",
"donet",
- "linux",
],
"/sidebar/sanfene/": [
"nixi",
- "mysql",
- "redis",
- "spring",
"javase",
"collection",
"javathread",
"jvm",
- "openclaw",
- "skills",
+ "spring",
+ "redis",
"mybatis",
+ "mysql",
"os",
"network",
"rocketmq",
"fenbushi",
- "weifuwu",
- "shejimoshi",
- "linux",
- ],
- "/sidebar/sjtu/": [
- {
- text: "心得篇",
- link: "fly/",
- },
- {
- text: "立志篇",
- link: "li-zhi-pian/",
- },
- {
- text: "访谈篇",
- link: "fang-tan-ji//",
- },
- {
- text: "人生篇",
- link: "fu-lu/",
- },
- {
- text: "生存技巧篇",
- link: "sheng-cun-ji-qiao/",
- }
],
// 必须放在最后面
"/": [
@@ -109,16 +89,15 @@ export default sidebar({
link: "home",
},
{
- text: "二、Java基础",
+ text: "二、Java核心",
collapsible: true,
children: [
- // readme小写一定要带上.md,否则找不到
- // Java核心开始
{
prefix: "overview/",
text: "2.1 Java概述及环境配置",
collapsible: true,
children: [
+ // readme小写一定要带上.md,否则找不到
"readme.md",
"what-is-java",
"jdk-install-config",
@@ -137,7 +116,6 @@ export default sidebar({
"basic-extra-meal/int-cache",
"basic-grammar/operator",
"basic-grammar/flow-control",
- "basic-grammar/basic-exercise",
],
},
{
@@ -147,7 +125,6 @@ export default sidebar({
"array/array",
"array/double-array",
"array/print",
- "string/string-source",
"string/immutable",
"string/constant-pool",
"string/intern",
@@ -155,6 +132,7 @@ export default sidebar({
"string/equals",
"string/join",
"string/split",
+ "basic-extra-meal/jdk9-char-byte-string",
],
},
{
@@ -172,8 +150,11 @@ export default sidebar({
"oo/code-init",
"oo/abstract",
"oo/interface",
+ "oo/abstract-vs-interface",
"oo/inner-class",
- "oo/encapsulation-inheritance-polymorphism",
+ "oo/encapsulation",
+ "oo/extends-bigsai",
+ "oo/polymorphism",
"oo/this-super",
"oo/static",
"oo/final",
@@ -181,34 +162,31 @@ export default sidebar({
"basic-extra-meal/immutable",
"basic-extra-meal/override-overload",
"basic-extra-meal/annotation",
- "basic-extra-meal/enum",
],
},
{
text: "2.5 集合框架(容器)",
collapsible: true,
- prefix: "collection/",
children: [
- "gailan",
- "arraylist",
- "linkedlist",
- "stack",
- "hashmap",
- "linkedhashmap",
- "treemap",
- "arraydeque",
- "PriorityQueue",
- "time-complexity",
- "list-war-2",
- "generic",
- "iterator-iterable",
- "fail-fast",
- "comparable-omparator",
- "WeakHashMap",
+ "collection/gailan",
+ "collection/time-complexity",
+ "collection/arraylist",
+ "collection/linkedlist",
+ "collection/list-war-2",
+ "basic-extra-meal/generic",
+ "collection/iterator-iterable",
+ "collection/fail-fast",
+ "collection/hashmap",
+ "collection/linkedhashmap",
+ "collection/treemap",
+ "collection/arraydeque",
+ "collection/PriorityQueue",
+ "basic-extra-meal/comparable-omparator",
+
],
},
{
- text: "2.6 Java IO",
+ text: "2.6 IO",
collapsible: true,
prefix:"io/",
children: [
@@ -230,10 +208,9 @@ export default sidebar({
prefix:"exception/",
children: [
"gailan",
- "try-with-resources",
+ "try-with-resouces",
"shijian",
"npe",
- "try-catch-xingneng",
],
},
{
@@ -241,64 +218,62 @@ export default sidebar({
collapsible: true,
prefix:"common-tool/",
children: [
- "scanner",
- "arrays",
- "StringUtils",
- "Objects",
- "collections",
- "hutool",
- "guava",
- "utils",
+ "arrays",
+ "collections",
+ "hutool",
+ "guava",
+ "utils",
],
},
{
text: "2.9 Java新特性",
prefix: "java8/",
- link: "/java8/",
collapsible: true,
children: [
"stream",
"optional",
"Lambda",
- "java14",
],
},
{
- text: "2.10 网络编程",
+ text: "2.10 Java重要知识点",
+ prefix:"basic-extra-meal/",
collapsible: true,
- prefix: "socket/",
children: [
- "network-base",
- "socket",
- "http",
+ "java-naming",
+ "java-unicode",
+ "box",
+ "deep-copy",
+ "hashcode",
+ "equals-hashcode",
+ "Overriding",
+ "pass-by-value",
+ "jdk-while-for-wuxian-xunhuan",
+ "instanceof-jvm",
+ "true-generic",
+ "enum",
+ "fanshe",
],
},
{
- text: "2.11 NIO",
+ text: "2.11 网络编程",
collapsible: true,
- prefix: "nio/",
+ prefix: "socket/",
children: [
- "nio-better-io",
- "BIONIOAIO",
- "buffer-channel",
- "paths-files",
- "network-connect",
- "moxing",
+ "socket",
+ "http",
],
},
{
- text: "2.12 Java重要知识点",
- prefix:"basic-extra-meal/",
+ text: "2.12 NIO",
collapsible: true,
+ prefix: "nio/",
children: [
- "java-naming",
- "java-unicode",
- "box",
- "deep-copy",
- "hashcode",
- "pass-by-value",
- "true-generic",
- "fanshe",
+ "why",
+ "rumen",
+ "moxing",
+ "network-connect",
+ "BIONIOAIO",
],
},
{
@@ -306,38 +281,36 @@ export default sidebar({
collapsible: true,
prefix: "thread/",
children: [
- "readme.md",
- "wangzhe-thread",
- "callable-future-futuretask",
- "thread-state-and-method",
- "thread-group-and-thread-priority",
- "why-need-thread",
- "thread-bring-some-problem",
- "jmm",
- "volatile",
- "synchronized-1",
- "synchronized",
- "pianxiangsuo",
- "cas",
- "aqs",
- "lock",
- "reentrantLock",
- "ReentrantReadWriteLock",
- "condition",
- "LockSupport",
- "map",
- "ConcurrentHashMap",
- "ConcurrentLinkedQueue",
- "BlockingQueue",
- "CopyOnWriteArrayList",
- "ThreadLocal",
- "pool",
- "ScheduledThreadPoolExecutor",
- "atomic",
- "Unsafe",
- "CountDownLatch",
- "fork-join",
- "shengchanzhe-xiaofeizhe",
+ "wangzhe-thread",
+ "thread-state-and-method",
+ "thread-group-and-thread-priority",
+ "why-need-thread",
+ "thread-bring-some-problem",
+ "jmm",
+ "volatile",
+ "synchronized-1",
+ "synchronized",
+ "cas",
+ "aqs",
+ "lock",
+ "suo",
+ "pianxiangsuo",
+ "reentrantLock",
+ "ReentrantReadWriteLock",
+ "condition",
+ "LockSupport",
+ "map",
+ "ConcurrentHashMap",
+ "ConcurrentLinkedQueue",
+ "CopyOnWriteArrayList",
+ "ThreadLocal",
+ "BlockingQueue",
+ "pool",
+ "ScheduledThreadPoolExecutor",
+ "atomic",
+ "CountDownLatch",
+ "fork-join",
+ "shengchanzhe-xiaofeizhe",
],
},
{
@@ -345,33 +318,33 @@ export default sidebar({
prefix: "jvm/",
collapsible: true,
children: [
- "readme.md",
"what-is-jvm",
"how-run-java-code",
"class-load",
"class-file-jiegou",
"bytecode",
- "vm-stack-register",
"zijiema-zhiling",
- "stack-frame",
+ "how-jvm-run-zijiema-zhiling",
+ "hsdb",
+ "asm",
+ "compile-jdk",
"neicun-jiegou",
- "gc",
- "gc-collector",
"whereis-the-object",
+ "gc",
+ "tujie-gc",
+ "meituan-9-gc",
+ "problem-tools",
"jit",
- "console-tools",
- "view-tools",
- "arthas",
"oom",
"cpu-percent-100",
"zongjie",
+
],
},
- //Java核心结束
],
},
{
- text: "三、Java进阶",
+ text: "三、Java企业级开发",
collapsible: true,
children: [
{
@@ -379,7 +352,13 @@ export default sidebar({
collapsible: true,
children: [
{
- text: "3.1.1 IDE",
+ text: "3.1.1 Nginx",
+ children: [
+ "nginx/nginx",
+ ],
+ },
+ {
+ text: "3.1.2 IDE",
collapsible: true,
children: [
"ide/4-debug-skill",
@@ -388,102 +367,43 @@ export default sidebar({
],
},
{
- text: "3.1.2 Maven",
+ text: "3.1.3 Maven",
collapsible: true,
children: [
"maven/maven",
],
},
{
- text: "3.1.3 Git",
+ text: "3.1.4 Git",
collapsible: true,
- prefix: "git/",
- children: [
- "git-qiyuan",
- "port-22-to-443",
- ],
- },
- {
- text: "3.1.4 Nginx",
children: [
- "nginx/nginx",
+ "git/git-qiyuan",
],
},
],
},
{
- text: "3.2 辅助工具",
+ text: "3.3 Spring",
collapsible: true,
children: [
- "gongju/choco",
- "gongju/brew",
- "gongju/tabby",
- "gongju/warp",
- "gongju/windterm",
- "gongju/chiner",
- "gongju/DBeaver",
- ],
- },
- {
- text: "3.3 开源轮子",
- collapsible: true,
- children: [
- {
- text: "HTTP调用框架Forest",
- link: "gongju/forest",
- },
- {
- text: "单元测试Junit",
- link: "gongju/junit",
- },
- {
- text: "阿里开源的fastjson",
- link: "gongju/fastjson",
- },
- {
- text: "谷歌开源的Gson",
- link: "gongju/gson",
- },
- {
- text: "SpringBoot内置的Jackson",
- link: "gongju/jackson",
- },
- {
- text: "日志框架的鼻祖Log4j",
- link: "gongju/log4j",
- },
{
- text: "高性能日志框架Log4j2",
- link: "gongju/log4j2",
+ text: "Spring AOP扫盲",
+ link: "springboot/aop-log",
},
{
- text: "Spring Boot内置的Logback",
- link: "gongju/logback",
+ text: "Spring IoC扫盲",
+ link: "springboot/ioc",
},
- {
- text: "日志门面SLF4J",
- link: "gongju/slf4j",
- },
-
- ],
- },
- {
- text: "3.4 Spring",
- collapsible: true,
- children: [
- "springboot/aop-log",
- "springboot/ioc",
],
},
{
- text: "3.5 Spring Boot",
+ text: "3.4 SpringBoot",
collapsible: true,
children: [
{
text: "搭建第一个Spring Boot项目",
link: "springboot/initializr",
},
- "springboot/lombok",
{
text: "整合MySQL和Druid",
link: "springboot/mysql-druid",
@@ -538,36 +458,70 @@ export default sidebar({
],
},
{
- text: "3.6 Netty",
+ text: "3.5 Netty",
collapsible: true,
children: [
"netty/rumen",
],
},
{
- text: "3.7 MongoDB",
+ text: "3.6 辅助工具",
collapsible: true,
children: [
- "mongodb/rumen",
+ "gongju/choco",
+ "gongju/brew",
+ "gongju/tabby",
+ "gongju/warp",
+ "gongju/windterm",
+ "gongju/chiner",
+ "gongju/DBeaver",
],
},
{
- text: "3.8 消息队列",
+ text: "3.7 开源轮子",
collapsible: true,
children: [
{
- text: "RabbitMQ入门",
- link: "mq/rabbitmq-rumen"
+ text: "HTTP调用框架Forest",
+ link: "gongju/forest",
},
{
- text: "如何保障消息不丢失",
- link: "mq/100-budiushi"
+ text: "单元测试Junit",
+ link: "gongju/junit",
},
- "mq/kafka",
+ {
+ text: "阿里开源的fastjson",
+ link: "gongju/fastjson",
+ },
+ {
+ text: "谷歌开源的Gson",
+ link: "gongju/gson",
+ },
+ {
+ text: "SpringBoot内置的Jackson",
+ link: "gongju/jackson",
+ },
+ {
+ text: "日志框架的鼻祖Log4j",
+ link: "gongju/log4j",
+ },
+ {
+ text: "高性能日志框架Log4j2",
+ link: "gongju/log4j2",
+ },
+ {
+ text: "Spring Boot内置的Logback",
+ link: "gongju/logback",
+ },
+ {
+ text: "日志门面SLF4J",
+ link: "gongju/slf4j",
+ },
+
],
},
{
- text: "3.9 微服务/分布式",
+ text: "3.8 分布式",
collapsible: true,
children: [
{
@@ -584,39 +538,62 @@ export default sidebar({
},
],
},
+ {
+ text: "3.9 消息队列",
+ collapsible: true,
+ children: [
+ {
+ text: "RabbitMQ入门",
+ link: "mq/rabbitmq-rumen"
+ },
+ {
+ text: "如何保障消息不丢失",
+ link: "mq/100-budiushi"
+ },
+ "mq/kafka",
+ ],
+ },
],
},
{
- text: "四、MySQL",
- collapsible: true,
- prefix: "mysql/",
- children: [
- "install",
- "database",
- "table",
- "data-type",
- "charset",
- "bin",
- "column",
- "select-simple",
- "select-where",
- "redis-shuju-yizhixing",
- "lijie-shiwu",
- "shiwu-shixian",
- ],
- },
- {
- text: "五、Redis",
+ text: "四、数据库",
collapsible: true,
- prefix: "redis/",
children: [
- "install",
- "rumen",
- "xuebeng-chuantou-jichuan",
+ {
+ text: "MySQL",
+ collapsible: true,
+ prefix: "mysql/",
+ children: [
+ "redis-shuju-yizhixing",
+ "lijie-shiwu",
+ "shiwu-shixian",
+ ],
+ },
+ {
+ text: "Redis",
+ collapsible: true,
+ children: [
+ {
+ text: "Redis入门",
+ link: "redis/rumen"
+ },
+ {
+ text: "缓存雪崩、穿透、击穿",
+ link: "redis/xuebeng-chuantou-jichuan"
+ },
+ ],
+ },
+ {
+ text: "MongoDB",
+ collapsible: true,
+ children: [
+ "mongodb/rumen",
+ ],
+ },
],
},
{
- text: "六、计算机基础",
+ text: "五、计算机基础",
collapsible: true,
prefix: "cs/",
children: [
@@ -631,7 +608,7 @@ export default sidebar({
],
},
{
- text: "七、求职面试",
+ text: "六、求职面试",
collapsible: true,
children: [
{
@@ -684,7 +661,6 @@ export default sidebar({
prefix: "cityselect/",
collapsible: true,
children: [
- "wuhan",
"beijing",
"chengdu",
"guangzhou",
@@ -696,13 +672,12 @@ export default sidebar({
"xian",
"zhengzhou",
"jinan",
- "hefei",
],
},
],
},
{
- text: "八、学习建议",
+ text: "七、学习建议",
collapsible: true,
prefix: "xuexijianyi/",
children: [
@@ -723,7 +698,7 @@ export default sidebar({
],
},
{
- text: "九、知识库搭建",
+ text: "八、知识库搭建",
collapsible: true,
prefix: "szjy/",
children: [
@@ -735,7 +710,7 @@ export default sidebar({
],
},
{
- text: "十、联系作者",
+ text: "九、联系作者",
collapsible: true,
prefix: "about-the-author/",
children: [
@@ -743,7 +718,11 @@ export default sidebar({
"zhihu-1000wan",
"csdn-1000wan",
"readme.md",
+
],
},
],
});
+
+
+
diff --git a/docs/.vuepress/styles/config.scss b/docs/.vuepress/styles/config.scss
new file mode 100644
index 0000000000..a1b7f5ba10
--- /dev/null
+++ b/docs/.vuepress/styles/config.scss
@@ -0,0 +1,2 @@
+$code-light-theme: "one-light";
+$code-dark-theme: "one-dark";
\ No newline at end of file
diff --git a/docs/.vuepress/styles/index.scss b/docs/.vuepress/styles/index.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/.vuepress/styles/palette.scss b/docs/.vuepress/styles/palette.scss
new file mode 100644
index 0000000000..87361d7c73
--- /dev/null
+++ b/docs/.vuepress/styles/palette.scss
@@ -0,0 +1,5 @@
+// 颜色
+$theme-color: #096dd9;
+
+// 左侧菜单栏的宽度
+$sidebar-mobile-width: 16rem;
\ No newline at end of file
diff --git a/docs/.vuepress/theme.ts b/docs/.vuepress/theme.ts
new file mode 100644
index 0000000000..c1f6700324
--- /dev/null
+++ b/docs/.vuepress/theme.ts
@@ -0,0 +1,126 @@
+import { hopeTheme } from "vuepress-theme-hope";
+import navbar from "./navbar";
+import { sidebarConfig } from "./sidebar";
+
+export default hopeTheme({
+ hostname: "https://tobebetterjavaer.com",
+ // 网站图标
+ logo: "https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/logo-02.png",
+ // Git 仓库和编辑链接
+ repo: "https://github.com/itwanger/toBeBetterJavaer",
+ repoLabel: "GitHub",
+ docsDir: "docs",
+ // 以前的默认仓库分支名,方便提交 pr 和 issue
+ docsBranch: "master",
+
+ // 全屏按钮
+ fullscreen: true,
+ // 在深色模式,浅色模式和自动之间切换 (默认)
+ darkmode: "switch",
+ // 纯净模式,会禁用一些花哨的动画以及一些色彩
+ // pure: true,
+
+ // 阿里妈妈图标的前缀
+ iconPrefix: "iconfont icon-",
+ // Iconfont 精选图标 和 阿里妈妈的互斥
+ // iconAssets: "iconfont",
+
+ // 全局默认作者
+ author: {
+ name: "沉默王二",
+ url: "/about-the-author/",
+ },
+
+ // 加密
+ encrypt: {
+ config: {
+ // 这只会加密 config/page.html
+ "/nice-article/itmind/ideapjazjczxjhmzcmyjjhcxgxz.html": ["1110", "5210"],
+ "/nice-article/itmind/webstormjhmwebstormwdzsjhmxbxt.html": ["1110", "5210"],
+ "/nice-article/itmind/sublimetextzcmpjazjcqckyxbxt.html": ["1110", "5210"],
+ },
+ },
+ // 提示文字
+ encryptLocales: {
+ placeholder: "微信搜‘沉默王二’回复‘密码’获取口令",
+
+ /**
+ * Passwrod error hint
+ */
+ errorHint: "哈哈,别调戏人家啦,按规则来嘛",
+ },
+
+ // navbar
+ navbar: navbar,
+
+ // sidebar
+ sidebar: sidebarConfig,
+
+ // 页脚支持
+ footer: '豫ICP备2021038026号-1'
+ +'
'
+ +''
+ +'豫公网安备 41030502000411号'
+ +'',
+ displayFooter: true,
+
+ // 文章信息,可以填入数组,数组的顺序是各条目显示的顺序
+ pageInfo: ["Author", "Original", "Date", "Category", "Tag", "Word","ReadingTime"],
+
+ blog: {
+ // 个人介绍页地址
+ intro: "/about-the-author/",
+ sidebarDisplay: "mobile",
+ // 博主头像
+ avatar: "/assets/icon/itwanger-282.png",
+ // 圆角
+ roundAvatar: true,
+ // 座右铭
+ description:"没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。",
+ medias: {
+ Zhihu: "https://www.zhihu.com/people/cmower",
+ CSDN: "https://blog.csdn.net/qing_gee",
+ Github: "https://github.com/itwanger",
+ Gitee: "https://gitee.com/itwanger",
+ },
+ },
+
+ plugins: {
+ // 启用博客自动摘要
+ blog: {
+ autoExcerpt: true,
+ },
+ // 该插件会监听页面滚动事件。当页面滚动至某个 标题锚点 后,如果存在对应的 标题链接 ,那么该插件会将路由 Hash 更改为该 标题锚点 。
+ activeHeaderLinks: true,
+
+ mdEnhance: {
+ // 添加选项卡支持
+ tabs: true,
+ // 流程图
+ mermaid: true,
+ // 支持任务列表
+ tasklist: true,
+
+ // 启用图片懒加载
+ imgLazyload: true,
+ // 启用图片标记
+ imgMark: true,
+ // 启用图片大小
+ imgSize: true,
+ // 启用图片标题
+ figure: true,
+
+ // 自定义对齐
+ align: true,
+
+ // 支持幻灯片
+ presentation: true,
+
+ // 链接检查
+ linkCheck: "always",
+
+ // 你的 Markdown 行为与 GitHub 保持一致
+ gfm: true,
+ },
+ },
+});
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000000..d3a645a575
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,42 @@
+---
+home: true
+icon: home
+title: 主页
+heroImage: https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/logo.png
+heroText: Java程序员进阶之路
+tagline: 沉默王二BB:这是一份通俗易懂、风趣幽默的Java学习指南,内容涵盖Java基础、Java并发编程、Java虚拟机、Java企业级开发、Java面试等核心知识点。学Java,就认准Java程序员进阶之路😄
+actions:
+ - text: 立马上路→
+ link: /home.md
+ type: primary
+ - text: 二哥的编程星球
+ link: /zhishixingqiu/
+ type: default
+footer: |-
+ 豫ICP备2021038026号-1 | 主题: VuePress Theme Hope
+---
+
+## 推荐阅读
+
+- [学习路线👉](/xuexiluxian/) : 一份涵盖 Java、C 语言、C++、Python、Go、操作系统、前端、数据结构与算法、蓝桥杯、大数据、Android、MySQL、.NET的全方位编程学习路线!清晰且有效!
+- [面渣逆袭📗](sidebar/sanfene/nixi.md) :面试前必刷,硬核理解版八股文,包括 Java 基础(JavaSE)、Java 集合框架、Java 并发编程(Java 多线程)、Java 虚拟机(JVM)、Spring、Redis、MyBatis、MySQL、操作系统、计算机网络、RocketMQ等等,助你拿到心仪 offer!
+- [Java程序员常读书单📚](/pdf/):超1000本PDF,助力Java 程序员构建最强知识体系,涵盖Java、设计模式、数据库、数据结构与算法、大数据、架构、其他编程语言等等,再也不用辛苦去找下载地址了,这里全都有。
+- [编程喵喵🐱实战项目学习教程](https://github.com/itwanger/codingmore-learning) :codingmore(Spring Boot+Vue 的前后端分离项目,一款值得一试的开源知识库学习网站)的学习教程,需要项目经验的 Java 开发者必备!
+
+## 公众号
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
+
+
+## star趋势图
+
+[](https://star-history.com/#itwanger/toBeBetterJavaer&Date)
+
+## 参与贡献
+
+1. 如果你对本项目有任何建议或发现文中内容有误的,欢迎提交 issues 进行指正。
+2. 对于文中我没有涉及到知识点,欢迎提交 PR。
\ No newline at end of file
diff --git a/docs/src/about-the-author/bzhan-10wan.md b/docs/about-the-author/bzhan-10wan.md
similarity index 89%
rename from docs/src/about-the-author/bzhan-10wan.md
rename to docs/about-the-author/bzhan-10wan.md
index 503848d6d3..cda97bd1f2 100644
--- a/docs/src/about-the-author/bzhan-10wan.md
+++ b/docs/about-the-author/bzhan-10wan.md
@@ -10,13 +10,13 @@ tag:
恭喜这个 B。。。。。。站上的 UP,上一期视频播放量突破了 10 万!这也是二哥人生当中的第一次,凭借单条视频突破 10 万播放,必须得纪念下。
-
+
从众多的宫斗剧中我得出了一条宝贵的人生经验:“母凭子贵”。这条经验同样适用于二哥本人,可能会因为这一期视频,吹这辈子最多的牛逼:这不,荣获哔哩哔哩第 3 周【校园优秀奖&校园新星奖】。
-
+
我已经按捺不住激动的心情,在两万人的朋友圈大肆炫耀了。十万播放,对于百大 UP 来说,可能就是分分钟的事,可对于我这个(未来的) B站百大来说,苦苦等了 149 天!!!!!!!
@@ -36,13 +36,13 @@ tag:
三不三连没关系,有关系的是不三连可能会对不起二哥的肝,所以还是三连吧,哈哈哈哈,瞧瞧我们这该死的生物钟,起这么早。。。
-
+
接下来,上干货,我把这期 10万+ 播放的视频台本重新整理了一下,本来不想发的,很多小伙伴私信说二哥偏爱 B 站,同步都懒得同步了吗?
这不,赶紧发到公众号上来,希望学生党们现在立刻马上收藏起来,这个寒假你会过得非常充实;至于工作党嘛,像二哥这样的,既要工作,又要读书写作照顾家庭的,忙都忙死了,就算了吧!
-
+
啊,不,还是要稍微卷一卷吧,免得被那群还有半年就毕业的家伙们拍死在沙滩上。。。。
@@ -60,7 +60,7 @@ tag:
所以我的建议是,**趁寒假打打王者上上分吧**!
-
+
啊,不!**趁寒假刷一波清华在 GitHub 上 20k+ star 的开源课程吧**!
@@ -70,7 +70,7 @@ tag:
>地址:https://github.com/PKUanonym/REKCARC-TSC-UHT
-
+
我来带小伙伴们过一下清华的课程安排哈,主要是针对计算机专业的。
@@ -105,7 +105,7 @@ tag:
学完这些,大家至少能学会下面这幅思维导图中列出来的内容。
-
+
更多 C 语言的学习内容,可以戳下面这个链接,之前在公众号上发过了,这里就不再复制粘贴了:
@@ -190,7 +190,7 @@ class 二哥 {
第一本,《趣学数据结构》
-
+
说到这,多说一嘴。2018 年的时候,人民邮电出版社的张老师邀请我出一本 Java 方面的书,我当时想命名为《趣学 Java》。张老师说,刚好之前和陈小玉老师合作出了一本《趣学算法》的书,要不发一本你看看吧。
@@ -198,11 +198,11 @@ class 二哥 {
第二本,《数据结构(C++语言版)》
-
+
对,清华大学邓俊辉教授编著的,豆瓣评分也蛮高的。这本书还配套了视频课程,是免费的,可以在学堂在线上看,我之前也有推荐过。
-
+
课程质量木得说,算是国家级精品课了。大家有时间的话,一定要刷一遍。
@@ -217,13 +217,13 @@ class 二哥 {
第一本,《数据结构与算法分析(Java 语言描述)》
-
+
虽然翻译得不怎么样,但内容很全面,适合拿来作为一本数据结构的入门书。
第二本,《算法(第 4 版)》
-
+
虽然名为算法,但大家都知道,算法是基于数据结构的,数组、队列、栈、堆、二叉树、哈希表等等,这些数据结构都讲到了。
diff --git a/docs/src/about-the-author/csdn-1000wan.md b/docs/about-the-author/csdn-1000wan.md
similarity index 79%
rename from docs/src/about-the-author/csdn-1000wan.md
rename to docs/about-the-author/csdn-1000wan.md
index fce9224f7b..1bdd09d2b0 100644
--- a/docs/src/about-the-author/csdn-1000wan.md
+++ b/docs/about-the-author/csdn-1000wan.md
@@ -14,15 +14,15 @@ tag:
我努力的回想着,回想自己在 2021 年做出了哪些耀眼的成绩,正襟危坐,回想良久,也只想到这最后一件:**CSDN 的博文访问量也突破了一千万**。
-
+
但这算不算得上是成绩,很难说,因为喜欢这个平台的人有很多,不喜欢这个平台的也有很多。也许,GitHub 上有 110k+ star 的 JavaGuide 的话最具有说服力了,这个平台不规范转载的很多,垃圾资源下载的很多,但也有几个优秀的作者撑起了 CSDN 的半边天,二哥就是其中一个。
-
+
老读者都知道,我是从2014 年,开始坚持写技术博客的。一开始,还没敢在 CSDN 上写,只敢在 JavaEye 上写(估计很多新读者都不太知道这个平台)。
-
+
那时候的 JavaEye 真的是非常非常非常的纯粹(比博客园更纯粹),没有任何商业广告,还时不时送送书,头部作者有 fastjson 的作者温少,《亿级流量网站架构核心技术》作者开涛,想必做技术的大家应该都知道他们俩。
@@ -30,13 +30,13 @@ tag:
就这样写着写着,我成了 CSDN 的博客专家,出版了一本技术图书,成为了两届博客之星。
-
+
就这样写着写着,我遇到了越来越多的读者,给他们提供帮助的同时,也成为了他们前进的动力。
据我自己的不完全统计,2021 年,我在朋友圈和公众号送出去了超过 200 本技术图书,每次我都会留个小心机,问中奖的读者是怎么认识二哥的,有没有什么建议,留言中竟然很多都来自 CSDN,这让我又惊又喜。
-
+
经常有读者夸赞二哥好有写作的天赋啊,其实哪里是有天赋,纯粹是因为写得多,所以才写得好。我现在的文笔,讲真,还不如上高中那会,那会才是真的笔下生花,诗都能写得出来,情书就更不用说了。
@@ -50,47 +50,47 @@ tag:
2 月 15 日,我和奶奶的合影。
-
+
3 月 26 日,读者考上研究生了,特意发来祝贺。
-
+
4 月 3 日,和教练小姐姐在健身房合影。
-
+
5 月 25 日,二哥的读者群体扩大了台湾省。
-
+
6 月 13 日,和家人畅游青岛。
-
+
7 月 20 日,被某某女粉追着要联系方式。
-
+
8 月 21 日,在十八线县城的老家砸核桃吃。
-
+
9 月 23 日,收到掘金和 CSDN 寄来的月饼。
-
+
-10 月 11 日,收到《二哥的Java进阶之路》专栏在 GitHub 上开源以来的两笔大额打赏。
+10 月 11 日,收到《Java程序员进阶之路》专栏在 GitHub 上开源以来的两笔大额打赏。
-
+
11 月 6 日,和四位河科大的学弟撸完串后在校园里的合影。
-
+
12 月 27 日,CSDN 生成的年度报告。
-
+
不知道大家的 2021 过得怎么样?
@@ -107,7 +107,7 @@ tag:
一年时间过得可真快,有很多想做好的事情,到最后都差了点意思。就说一件吧,B 站的视频播放量没有达到预期。
-
+
8 月份还能坚持一周输出一个,从一开始面对镜头时的恐惧,到慢慢接纳自己。但好景不长,9 月份的时候,视频播放量呈现下降趋势,我就开始胡思乱想了。
@@ -159,21 +159,21 @@ B 站我一定做到一万粉——这个 flag 不能到。
展望 2022 年,有太多的期待了。
-这不,新的惊喜就是《二哥的Java进阶之路》专栏第一次上了 GitHub 的 trending 榜单!
+这不,新的惊喜就是《Java程序员进阶之路》专栏第一次上了 GitHub 的 trending 榜单!
-
+
正应了那句话,功夫不负有心人。
对于这个开源专栏,我投入了大量的心血,一开始的名字叫《教妹学 Java》,主打 Java 的入门级路线,一直连载了近 100篇原创内容。
-后来有朋友建议我,要想走国际化的话,就必须得换个名字,得和国际接轨,于是我就想破脑袋,征求了很多朋友的建议,改成这个《二哥的Java进阶之路》了,因为我之前出版过一本技术书《Web 全栈开发进阶之路》,叫这个名字刚好也非常适合。
+后来有朋友建议我,要想走国际化的话,就必须得换个名字,得和国际接轨,于是我就想破脑袋,征求了很多朋友的建议,改成这个《Java程序员进阶之路》了,因为我之前出版过一本技术书《Web 全栈开发进阶之路》,叫这个名字刚好也非常适合。
英文名字叫 toBeBetterJavaer, 前后呼应,一气呵成。
立个 flag 吧,**2022 年,冲 5000 star**!
-
+
这个 flag 绝不能倒!
diff --git a/docs/about-the-author/readme.md b/docs/about-the-author/readme.md
new file mode 100644
index 0000000000..38a24f3930
--- /dev/null
+++ b/docs/about-the-author/readme.md
@@ -0,0 +1,103 @@
+---
+title: 个人介绍 Q&A
+category: 联系作者
+---
+
+大家好,我是二哥呀!这篇文章会通过 QA 的形式简单介绍一下我自己。
+
+## 一、我取得了哪些成绩?
+
+又到了晒成绩的环节,真让人迫不及待啊(瞧我这该死的自信)!
+
+### 01、公众号
+
+目前我的原创公众号“**沉默王二**”有 10.5 万+ 读者关注,专注于分享硬核的 Java 后端技术文章。平均阅读 5500 左右,综合排名能排在全国开发者中的前 50 名左右(数据来源于二十次幂)。
+
+可以微信搜索 **沉默王二** 关键字或者扫码直接关注,关注后回复 **00** 还可以拉取我为你精心准备的学习资料。
+
+
+
+学习资料有 BAT 大佬的刷题笔记,有《Java程序员进阶之路》的 PDF 版电子书等等。
+
+
+
+
+
+### 02、CSDN
+
+两届博客之星,总榜前 10 选手,访问量 1100 万+,粉丝 34 万+,妥妥的裆部博主,哦,不,头部博主。
+
+>访问地址:[https://blog.csdn.net/qing_gee](https://blog.csdn.net/qing_gee)
+
+
+
+### 03、知乎
+
+LV9 选手,阅读总数超 1590 万,今年卷一卷的话,破 2000 万阅读没什么问题。
+
+>访问地址:[https://www.zhihu.com/people/cmower](https://www.zhihu.com/people/cmower)
+
+
+
+### 04、B 站
+
+>访问地址:[https://space.bilibili.com/513340480](https://space.bilibili.com/513340480)
+
+
+
+### 05、GitHub
+
+目前主要维护的《Java程序员进阶之路》开源版在 GitHub 上有 2.7k+ 的 star,和出版社约定的是,超过 1 万 star 就出书,小伙伴们可以来点赞支持下。
+
+>访问地址:[https://github.com/itwanger/toBeBetterJavaer](https://github.com/itwanger/toBeBetterJavaer)
+
+
+
+
+### 05、知识星球
+
+目前还处在试运营阶段,正在筹备星球用户专属的 5 份小册,质量高的一笔。
+
+
+
+内容涵盖实战项目开发笔记、面试指南、Java学习、LeetCode Java 版刷题笔记等优质内容,价值远超门票!
+
+- 编程喵喵开源 Spring Boot+Vue 的前后端分离项目实战笔记
+- **Java 面试指南**,今年重点更新内容,涵盖面试准备篇、技术面试题篇、面经篇、职场修炼篇等等硬核内容。
+- Java程序员进阶之路优化重构版(星球专属)
+- GitHub 上星标 147k+ 的 Java 教程(更多优质教程持续更新)
+- LeetCode 题解 Java 版(持续更新 300 道)
+
+这是《Java 面试指南》专栏目前已经更新的内容,讲真,就这一个专栏就值回票价(新人优惠价只有 69 元)。
+
+
+
+还有星球内部我也在坚持每天更新优质的内容。
+
+
+
+喜欢的小伙伴可以直接扫码加入。
+
+
+
+## 二、为什么叫沉默王二
+
+其实原因很简单,我个人比较喜欢王小波,小波是个程序员,还是个作家,写的小说和杂文我都特别喜欢,有一本叫《沉默的大多数》,我就取了沉默二字,《黄金时代》里和陈清扬搞破鞋的男主就叫王二,加上小波在家排行老二,上面有个哥哥,下面有个弟弟,所以综合到一起就叫“沉默王二”了。
+
+## 三、为什么做这个开源知识库
+
+> [!NOTE]
+> 知识库取名 **toBeBetterJavaer**,即 **To Be Better Javaer**,意为「成为一名更好的 Java 程序员」,是自学 Java 以来所有原创文章和学习资料的大聚合。内容包括 Java 基础、Java 并发编程、Java 虚拟机、Java 企业级开发、Java 面试等核心知识点。据说每一个优秀的 Java 程序员都喜欢她,风趣幽默、通俗易懂。学 Java,就认准 Java程序员进阶之路😄。
+>
+> 知识库旨在为学习 Java 的小伙伴提供一系列:
+> - **优质的原创 Java 教程**
+> - **全面清晰的 Java 学习路线**
+> - **免费但靠谱的 Java 学习资料**
+> - **精选的 Java 岗求职面试指南**
+> - **Java 企业级开发所需的必备技术**
+>
+> 赠人玫瑰手有余香。知识库会持续保持**更新**,欢迎收藏品鉴!
+
+>访问地址:[https://tobebetterjavaer.com](https://tobebetterjavaer.com)
+
+## 四、未完待续
diff --git a/docs/src/about-the-author/zhihu-1000wan.md b/docs/about-the-author/zhihu-1000wan.md
similarity index 88%
rename from docs/src/about-the-author/zhihu-1000wan.md
rename to docs/about-the-author/zhihu-1000wan.md
index 4fc276dbde..9c87a540d8 100644
--- a/docs/src/about-the-author/zhihu-1000wan.md
+++ b/docs/about-the-author/zhihu-1000wan.md
@@ -13,7 +13,7 @@ tag:
前几天,偷偷摸摸过了自己的第 N 个 18 岁,本来不想过生日的,就想当做是平常的一天。结果我妹非要提醒我,大家伙瞧瞧,这像妹妹该说的话吗?
-
+
呜呜呜~
@@ -23,7 +23,7 @@ tag:
**经营了近一年的知乎,阅读总数突破了一千万,这也是我人生当中的第一个**。
-
+
其实早在 11 月就破了千万,当时就想记录一下,但细想一下,好像这点成绩也算不上什么。毕竟逼乎上人均 985、年薪百万、刚下飞机的大佬多的是。
@@ -33,13 +33,13 @@ tag:
这不,前几天一个帖子莫名其妙被知乎删除了,我是无感知的。一个小伙伴为了看这个帖子,还特意发起了一次 9.8 元的付费咨询。
-
+
这足以说明这个帖子的内容是足够硬核的。
写知乎这近一年时间里,有一个帖子无声无息地爆了:**60 万+的阅读,7000+赞同,2.3 万+次的收藏**。
-
+
不对啊,收藏竟然是点赞的 3 倍还多。。嗯,此时此刻天空飘出来了四个字:白票真香。
@@ -101,7 +101,7 @@ tag:
我在知乎上还有不少硬核输出,尤其是这些千赞以上的帖子,真心推荐给大家看看,看完后绝壁是有收获的。
-
+
虽然有些埋没的帖子我觉得价值也很高。不过,埋没就埋没吧。
diff --git a/docs/array/array.md b/docs/array/array.md
new file mode 100644
index 0000000000..966c54e57b
--- /dev/null
+++ b/docs/array/array.md
@@ -0,0 +1,271 @@
+---
+title: 一文吃透Java数组
+shortTitle: 吃透Java数组
+category:
+ - Java核心
+tag:
+ - 数组&字符串
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,Java数组
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java数组,数组
+---
+
+# 4.1 一文吃透Java数组
+
+“二哥,我看你公众号的一篇文章里提到,[ArrayList](https://tobebetterjavaer.com/collection/arraylist.html) 的内部是用数组实现的,我就对数组非常感兴趣,想深入地了解一下,今天终于到这个环节了,好期待呀!”三妹的语气里显得很兴奋。
+
+“的确是的,看 ArrayList 的源码就一清二楚了。”我一边说,一边打开 Intellij IDEA,并找到了 ArrayList 的源码。
+
+```java
+/**
+ * The array buffer into which the elements of the ArrayList are stored.
+ * The capacity of the ArrayList is the length of this array buffer. Any
+ * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
+ * will be expanded to DEFAULT_CAPACITY when the first element is added.
+ */
+transient Object[] elementData; // non-private to simplify nested class access
+
+/**
+ * The size of the ArrayList (the number of elements it contains).
+ *
+ * @serial
+ */
+private int size;
+```
+
+“瞧见没?`Object[] elementData` 就是数组。”我指着显示屏上这串代码继续说。
+
+数组是一个对象,它包含了一组固定数量的元素,并且这些元素的类型是相同的。数组会按照索引的方式将元素放在指定的位置上,意味着我们可以通过索引来访问这些元素。在 Java 中,索引是从 0 开始的。
+
+“哥,能说一下为什么索引从 0 开始吗?”三妹突然这个话题很感兴趣。
+
+“哦,Java 是基于 C/C++ 语言实现的,而 C 语言的下标是从 0 开始的,所以 Java 就继承了这个良好的传统习惯。C语言有一个很重要概念,叫做指针,它实际上是一个偏移量,距离开始位置的偏移量,第一个元素就在开始的位置,它的偏移量就为 0,所以索引就为 0。”此刻,我很自信。
+
+“此外,还有另外一种说法。早期的计算机资源比较匮乏,0 作为起始下标相比较于 1 作为起始下标,编译的效率更高。”
+
+“哦。”三妹意味深长地点了点头。
+
+我们可以将数组理解为一个个整齐排列的单元格,每个单元格里面存放着一个元素。
+
+数组元素的类型可以是基本数据类型(比如说 int、double),也可以是引用数据类型(比如说 String),包括自定义类型。
+
+数组的声明方式分两种。
+
+先来看第一种:
+
+```java
+int[] anArray;
+```
+
+再来看第二种:
+
+```java
+int anOtherArray[];
+```
+
+不同之处就在于中括号的位置,是跟在类型关键字的后面,还是跟在变量的名称的后面。前一种的使用频率更高一些,像 ArrayList 的源码中就用了第一种方式。
+
+同样的,数组的初始化方式也有多种,最常见的是:
+
+```java
+int[] anArray = new int[10];
+```
+
+看到了没?上面这行代码中使用了 new 关键字,这就意味着数组的确是一个对象,只有对象的创建才会用到 new 关键字,[基本数据类型](https://tobebetterjavaer.com/basic-grammar/basic-data-type.html)是不用的。然后,我们需要在方括号中指定数组的长度。
+
+这时候,数组中的每个元素都会被初始化为默认值,int 类型的就为 0,Object 类型的就为 null。 不同数据类型的默认值不同,可以参照[之前的文章](https://tobebetterjavaer.com/basic-grammar/basic-data-type.html)。
+
+另外,还可以使用大括号的方式,直接初始化数组中的元素:
+
+```java
+int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
+```
+
+这时候,数组的元素分别是 1、2、3、4、5,索引依次是 0、1、2、3、4,长度是 5。
+
+“哥,怎么访问数组呢?”三妹及时地插话到。
+
+前面提到过,可以通过索引来访问数组的元素,就像下面这样:
+
+```java
+anArray[0] = 10;
+```
+
+变量名,加上中括号,加上元素的索引,就可以访问到数组,通过“=”操作符可以对元素进行赋值。
+
+如果索引的值超出了数组的界限,就会抛出 `ArrayIndexOutOfBoundException`。
+
+既然数组的索引是从 0 开始,那就是到数组的 `length - 1` 结束,不要使用超出这个范围内的索引访问数组,就不会抛出数组越界的异常了。
+
+当数组的元素非常多的时候,逐个访问数组就太辛苦了,所以需要通过遍历的方式。
+
+第一种,使用 for 循环:
+
+```java
+int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
+for (int i = 0; i < anOtherArray.length; i++) {
+ System.out.println(anOtherArray[i]);
+}
+```
+
+通过 length 属性获取到数组的长度,然后从 0 开始遍历,就得到了数组的所有元素。
+
+第二种,使用 for-each 循环:
+
+```java
+for (int element : anOtherArray) {
+ System.out.println(element);
+}
+```
+
+如果不需要关心索引的话(意味着不需要修改数组的某个元素),使用 for-each 遍历更简洁一些。当然,也可以使用 while 和 do-while 循环。
+
+在 Java 中,可变参数用于将任意数量的参数传递给方法,来看 `varargsMethod()` 方法:
+
+```java
+void varargsMethod(String... varargs) {}
+```
+
+该方法可以接收任意数量的字符串参数,可以是 0 个或者 N 个,本质上,可变参数就是通过数组实现的。为了证明这一点,我们可以看一下反编译一后的字节码:
+
+```java
+public class VarargsDemo
+{
+
+ public VarargsDemo()
+ {
+ }
+
+ transient void varargsMethod(String as[])
+ {
+ }
+}
+```
+
+所以,我们其实可以直接将数组作为参数传递给该方法:
+
+```java
+VarargsDemo demo = new VarargsDemo();
+String[] anArray = new String[] {"沉默王二", "一枚有趣的程序员"};
+demo.varargsMethod(anArray);
+```
+
+也可以直接传递多个字符串,通过逗号隔开的方式:
+
+```java
+demo.varargsMethod("沉默王二", "一枚有趣的程序员");
+```
+
+在 Java 中,数组与 List 关系非常密切。List 封装了很多常用的方法,方便我们对集合进行一些操作,而如果直接操作数组的话,有很多不便,因为数组本身没有提供这些封装好的操作,所以有时候我们需要把数组转成 List。
+
+“怎么转呢?”三妹问到。
+
+最原始的方式,就是通过遍历数组的方式,一个个将数组添加到 List 中。
+
+```java
+int[] anArray = new int[] {1, 2, 3, 4, 5};
+
+List aList = new ArrayList<>();
+for (int element : anArray) {
+ aList.add(element);
+}
+```
+
+更优雅的方式是通过 Arrays 类的 `asList()` 方法:
+
+```java
+List aList = Arrays.asList(anArray);
+```
+
+不过需要注意的是,Arrays.asList 的参数需要是 Integer 数组,而 anArray 目前是 int 类型,我们需要换另外一种方式。
+
+```java
+List aList = Arrays.stream(anArray).boxed().collect(Collectors.toList());
+```
+
+这又涉及到了 Java [流](https://tobebetterjavaer.com/java8/stream.html)的知识,后面会讲到。
+
+还有一个需要注意的是,Arrays.asList 方法返回的 ArrayList 并不是 `java.util.ArrayList`,它其实是 Arrays 类的一个内部类:
+
+```java
+private static class ArrayList extends AbstractList
+ implements RandomAccess, java.io.Serializable{}
+```
+
+如果需要添加元素或者删除元素的话,需要把它转成 `java.util.ArrayList`。
+
+```java
+new ArrayList<>(Arrays.asList(anArray));
+```
+
+Java 8 新增了 Stream 流的概念,这就意味着我们也可以将数组转成 Stream 进行操作。
+
+```java
+String[] anArray = new String[] {"沉默王二", "一枚有趣的程序员", "好好珍重他"};
+Stream aStream = Arrays.stream(anArray);
+```
+
+如果想对数组进行排序的话,可以使用 Arrays 类提供的 `sort()` 方法。
+
+- 基本数据类型按照升序排列
+- 实现了 Comparable 接口的对象按照 `compareTo()` 的排序
+
+来看第一个例子:
+
+```java
+int[] anArray = new int[] {5, 2, 1, 4, 8};
+Arrays.sort(anArray);
+```
+
+排序后的结果如下所示:
+
+```java
+[1, 2, 4, 5, 8]
+```
+
+来看第二个例子:
+
+```java
+String[] yetAnotherArray = new String[] {"A", "E", "Z", "B", "C"};
+Arrays.sort(yetAnotherArray, 1, 3,
+ Comparator.comparing(String::toString).reversed());
+```
+
+只对 1-3 位置上的元素进行反序,所以结果如下所示:
+
+```
+[A, Z, E, B, C]
+```
+
+有时候,我们需要从数组中查找某个具体的元素,最直接的方式就是通过遍历的方式:
+
+```java
+int[] anArray = new int[] {5, 2, 1, 4, 8};
+for (int i = 0; i < anArray.length; i++) {
+ if (anArray[i] == 4) {
+ System.out.println("找到了 " + i);
+ break;
+ }
+}
+```
+
+上例中从数组中查询元素 4,找到后通过 break 关键字退出循环。
+
+如果数组提前进行了排序,就可以使用二分查找法,这样效率就会更高一些。`Arrays.binarySearch()` 方法可供我们使用,它需要传递一个数组,和要查找的元素。
+
+```java
+int[] anArray = new int[] {1, 2, 3, 4, 5};
+int index = Arrays.binarySearch(anArray, 4);
+```
+
+“除了一维数组,还有二维数组,三妹你可以去研究下,比如说用二维数组打印一下杨辉三角。”说完,我就去阳台上休息了,留三妹在那里学习,不能打扰她。
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
diff --git a/docs/src/array/double-array.md b/docs/array/double-array.md
similarity index 82%
rename from docs/src/array/double-array.md
rename to docs/array/double-array.md
index bf4a3e32a3..1283f63642 100644
--- a/docs/src/array/double-array.md
+++ b/docs/array/double-array.md
@@ -1,22 +1,24 @@
---
-title: 用一根烟的时间掌握 Java二维数组
+title: 聊聊Java的二维数组
shortTitle: 二维数组
category:
- Java核心
tag:
- 数组&字符串
-description: 本文深入讲解了Java二维数组的基本概念、创建方法、初始化方法以及常用操作。通过阅读本文,您将了解到如何定义二维数组、创建和初始化二维数组,以及如何进行二维数组的常见操作,如添加、删除、查询等。本文将帮助您快速掌握Java二维数组的使用方法和技巧(打印杨辉三角)。
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,Java二维数组
head:
- - meta
- name: keywords
- content: Java, 二维数组, 创建二维数组, 初始化二维数组, 数组操作, 多维数组
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java二维数组,数组
---
+# 4.2 二维数组
+
“二哥,今天我们简单过一下二维数组吧,挺简单的。”三妹放下手机对我说。
“好啊,本来不打算讲了,因为开发中用的其实不多,也很简单,就从一维到二维,也没啥可讲的,就简单聊聊吧。”我掐灭了手中的华子,长呼一口烟,飘过三妹的头顶,引起一阵轻微的咳嗽声(😂)
-### 01、什么是二维数组
+### 什么是二维数组
二维数组是一种数据类型,可以存储多行和多列的数据。它由一系列的行和列组成,每个元素都可以通过一个行索引和列索引来访问。例如,一个3行4列的二维数组可以表示为以下形式:
@@ -32,7 +34,7 @@ array = [
使用二维数组可以有效地存储和处理表格数据,如矩阵、图像、地图等等。
-### 02、创建二维数组
+### 如何在 Java 中声明一个二维数组
要在 Java 中创建二维数组,你必须指定要存储在数组中的数据类型,后跟两个方括号和数组的名称。
@@ -49,7 +51,7 @@ int[][] oddNumbers = { {1, 3, 5, 7}, {9, 11, 13, 15} };
```
-### 03、访问二维数组中的元素
+### 如何在 Java 中访问二维数组中的元素
我们可以使用两个方括号来访问二维中的元素。
@@ -152,7 +154,7 @@ for(int i = 0; i < oddNumbers.length; i++){
上面的代码将会打印出 `oddNumbers` 数组中的所有项目。
-### 04、二维数组打印杨辉三角
+### 二维数组打印杨辉三角
“三妹,上次学一维数组的时候留了一道题,要你尝试用二维数组打印杨辉三角,你试过了吗?”
@@ -210,9 +212,8 @@ public class YangHuiTriangle {
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
-
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-
+
diff --git a/docs/array/print.md b/docs/array/print.md
new file mode 100644
index 0000000000..2040023694
--- /dev/null
+++ b/docs/array/print.md
@@ -0,0 +1,185 @@
+---
+title: 如何优雅地打印Java数组?
+shortTitle: 打印Java数组
+category:
+ - Java核心
+tag:
+ - 数组&字符串
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,如何优雅地打印Java数组?
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java数组,java打印数组
+---
+
+# 4.3 如何优雅地打印Java数组?
+
+“哥,[之前听你说,数组也是一个对象](https://tobebetterjavaer.com/array/array.html),但 Java 中并未明确的定义这样一个类。”看来三妹有在用心地学习。
+
+“是的,因此数组也就没有机会覆盖 `Object.toString()` 方法。如果尝试直接打印数组的话,输出的结果并不是我们预期的结果。”我接着三妹的话继续说。
+
+“那怎么打印数组呢?”三妹心有灵犀地把今天的核心问题提了出来。
+
+### 为什么不能直接打印数组
+
+“首先,我们来看一下,为什么不能直接打印数组,直接打印的话,会出现什么问题。”
+
+来看这样一个例子。
+
+```
+String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
+System.out.println(cmowers);
+```
+
+程序打印的结果是:
+
+```
+[Ljava.lang.String;@3d075dc0
+```
+
+`[Ljava.lang.String;` 表示字符串数组的 Class 名,@ 后面的是十六进制的 hashCode——这样的打印结果太“人性化”了,一般人表示看不懂!为什么会这样显示呢?查看一下 `java.lang.Object` 类的 `toString()` 方法就明白了。
+
+```java
+public String toString() {
+ return getClass().getName() + "@" + Integer.toHexString(hashCode());
+}
+```
+
+再次证明,数组虽然没有显式定义成一个类,但它的确是一个对象,继承了祖先类 Object 的所有方法。
+
+“哥,那为什么数组不单独定义一个类来表示呢?就像字符串 String 类那样呢?”三妹这个问题让人头大,但也好解释。
+
+“一个合理的说法是 Java 将其隐藏了。假如真的存在这么一个类,就叫 Array.java 吧,我们假想一下它真实的样子,必须得有一个容器来存放数组的每一个元素,就像 String 类那样。”一边回答三妹,我一边打开了 String 类的源码。
+
+```java
+public final class String
+ implements java.io.Serializable, Comparable, CharSequence {
+ /** The value is used for character storage. */
+ private final char value[];
+}
+```
+
+“最终还是要用类似一种数组的形式来存放数组的元素,对吧?这就变得很没有必要了,不妨就把数组当做是一个没有形体的对象吧!”
+
+“好了,不讨论这个了。”我怕话题扯远了,扯到我自己也答不出来就尴尬了,赶紧把三妹的思路拽了回来。
+
+### stream 流打印 Java 数组
+
+“我们来看第一种打印数组的方法,使用时髦一点的[Stream 流](https://tobebetterjavaer.com/java8/stream.html)。”
+
+第一种形式:
+
+```java
+Arrays.asList(cmowers).stream().forEach(s -> System.out.println(s));
+```
+
+第二种形式:
+
+```java
+Stream.of(cmowers).forEach(System.out::println);
+```
+
+第三种形式:
+
+```java
+Arrays.stream(cmowers).forEach(System.out::println);
+```
+
+打印的结果如下所示。
+
+```
+沉默
+王二
+一枚有趣的程序员
+```
+
+没错,这三种方式都可以轻松胜任本职工作,并且显得有点高大上,毕竟用到了 Stream,以及 [lambda 表达式](https://tobebetterjavaer.com/java8/Lambda.html)。
+
+### for 循环打印 Java 数组
+
+“当然了,也可以使用传统的方式,for 循环。甚至 for-each 也行。”
+
+```java
+for(int i = 0; i < cmowers.length; i++){
+ System.out.println(cmowers[i]);
+}
+
+for (String s : cmowers) {
+ System.out.println(s);
+}
+```
+
+### Arrays 工具类打印 Java 数组
+
+“哥,你难道忘了[上一篇](https://tobebetterjavaer.com/common-tool/arrays.html)在讲 Arrays 工具类的时候,提到过另外一种方法 `Arrays.toString()` 吗?”三妹看我一直说不到点子上,有点着急了。
+
+“当然没有了,我认为 `Arrays.toString()` 是打印数组的最佳方式,没有之一。”我的情绪有点激动。
+
+`Arrays.toString()` 可以将任意类型的数组转成字符串,包括基本类型数组和引用类型数组。该方法有多种重载形式。
+
+
+
+使用 `Arrays.toString()` 方法来打印数组再优雅不过了,就像,就像,就像蒙娜丽莎的微笑。
+
+
+
+(三妹看到这么一副图的时候忍不住地笑了)
+
+“三妹,你不要笑,来,怀揣着愉快的心情看一下代码示例。”
+
+```java
+String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
+System.out.println(Arrays.toString(cmowers));
+```
+
+程序打印结果:
+
+```
+[沉默, 王二, 一枚有趣的程序员]
+```
+
+哇,打印格式不要太完美,不多不少!完全是我们预期的结果:`[]` 表明是一个数组,`,` 点和空格用来分割元素。
+
+### Arrays工具类打印二维数组
+
+“哥,那如果我想打印二维数组呢?”
+
+“可以使用 `Arrays.deepToString()` 方法。”
+
+```java
+String[][] deepArray = new String[][] {{"沉默", "王二"}, {"一枚有趣的程序员"}};
+System.out.println(Arrays.deepToString(deepArray));
+```
+
+打印结果如下所示。
+
+```
+[[沉默, 王二], [一枚有趣的程序员]]
+```
+
+### POJO 的打印规约
+
+“说到打印,三妹,哥给你提醒一点。阿里巴巴的 Java 开发手册上有这样一条规约,你看。”
+
+
+
+“什么是 POJO 呢,就是 Plain Ordinary Java Object 的缩写,一般在 Web 应用程序中建立一个数据库的映射对象时,我们称它为 POJO,这类对象不继承或不实现任何其它 Java 框架的类或接口。”
+
+“对于这样的类,最好是重写一下它的 `toString()` 方法,方便查看这个对象到底包含了什么字段,好排查问题。”
+
+“如果不重写的话,打印出来的 Java 对象就像直接打印数组的那样,一串谁也看不懂的字符序列。”
+
+“可以借助 Intellij IDEA 生成重写的 `toString()` 方法,特别方便。”
+
+“好的,哥,我记住了。以后遇到的话,我注意下。你去休息吧,我来敲一下你提到的这些代码,练一练。”
+
+“OK,我走,我走。”
+
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
diff --git a/docs/basic-extra-meal/48-keywords.md b/docs/basic-extra-meal/48-keywords.md
new file mode 100644
index 0000000000..48c21fd7c3
--- /dev/null
+++ b/docs/basic-extra-meal/48-keywords.md
@@ -0,0 +1,137 @@
+---
+title: 简单过一下Java中常用的48个关键字和2个保留字
+shortTitle: 48个关键字和2个保留字
+category:
+ - Java核心
+tag:
+ - Java语法基础
+description: Java程序员进阶之路,小白的零基础Java教程,Java中常用的48个关键字和2个保留字
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,Java保留字,Java关键字,关键字,保留字
+---
+
+# 3.1 48个关键字和2个保留字
+
+“二哥,就之前你给我展示的 Java 代码中,有 public、static、void、main 等等,它们应该都是关键字吧?”三妹的脸上泛着甜甜的笑容,我想她在学习 Java 方面已经变得越来越自信了。
+
+“是的,三妹。Java 中的关键字可不少呢!你一下子可能记不了那么多,不过,先保留个印象吧,对以后的学习会很有帮助。”
+
+>PS:这里我们按照首字母的自然顺序排列来简述一下,了解即可,记不住没关系哦。这些关键字我们在后续的学习中会详细讲解的,直到你搞懂为止。
+
+1. **abstract:** 用于声明[抽象类](https://tobebetterjavaer.com/oo/abstract.html),以及抽象方法。
+
+2. **boolean:** 用于将变量声明为布尔值类型,只有 true 和 false 两个值。
+
+3. **break:** 用于中断循环或 switch 语句。
+
+4. **byte:** 用于声明一个可以容纳 8 个比特的变量。
+
+5. **case:** 用于在 switch 语句中标记条件的值。
+
+6. **catch:** 用于捕获 try 语句中的[异常](https://tobebetterjavaer.com/exception/gailan.html)。
+
+7. **char:** 用于声明一个可以容纳无符号 16 位比特的 [Unicode 字符](https://tobebetterjavaer.com/basic-extra-meal/java-unicode.html)的变量。
+
+8. **class:** 用于声明一个[类](https://tobebetterjavaer.com/oo/object-class.html)。
+
+9. **continue:** 用于继续下一个循环,可以在指定条件下跳过其余代码。
+
+10. **default:** 用于指定 switch 语句中除去 case 条件之外的默认代码块。
+
+11. **do:** 通常和 while 关键字配合使用,do 后紧跟循环体。
+
+12. **double:** 用于声明一个可以容纳 64 位浮点数的变量。
+
+13. **else:** 用于指示 if 语句中的备用分支。
+
+14. **enum:** 用于定义一组固定的常量([枚举](https://tobebetterjavaer.com/basic-extra-meal/enum.html))。
+
+15. **extends:** 用于指示一个类是从另一个类或接口[继承](https://tobebetterjavaer.com/oo/extends-bigsai.html)的。
+
+16. **final:** [用于指示该变量是不可更改的](https://tobebetterjavaer.com/oo/final.html)。
+
+17. **finally:** 和 `try-catch` 配合使用,表示无论是否处理异常,总是执行 finally 块中的代码。
+
+18. **float:** 用于声明一个可以容纳 32 位浮点数的变量。
+
+19. **for:** 用于声明一个 for 循环,如果循环次数是固定的,建议使用 for 循环。
+
+20. **if:** 用于指定条件,如果条件为真,则执行对应代码。
+
+21. **implements:** 用于实现[接口](https://tobebetterjavaer.com/oo/interface.html)。
+
+22. **import:** 用于导入对应的类或者接口。
+
+23. **instanceof:** [用于判断对象是否属于某个类型(class)](https://tobebetterjavaer.com/basic-extra-meal/instanceof.html)。
+
+24. **int:** 用于声明一个可以容纳 32 位带符号的整数变量。
+
+25. **interface:** 用于声明接口。
+
+26. **long:** 用于声明一个可以容纳 64 位整数的变量。
+
+27. **native:** 用于指定一个[方法是通过调用本机接口(非 Java)实现的](https://tobebetterjavaer.com/oo/method.html)。
+
+28. **new:** 用于创建一个新的对象。
+
+29. **null:** 如果一个变量是空的(什么引用也没有指向),就可以将它赋值为 null,和空指针异常息息相关。
+
+30. **package:** 用于声明类所在的[包](https://tobebetterjavaer.com/oo/package.html)。
+
+31. **private:** 一个[访问权限修饰符](https://tobebetterjavaer.com/oo/access-control.html),表示方法或变量只对当前类可见。
+
+32. **protected:** 一个访问权限修饰符,表示方法或变量对同一包内的类和所有子类可见。
+
+33. **public:** 一个访问权限修饰符,除了可以声明方法和变量(所有类可见),还可以声明类。`main()` 方法必须声明为 public。
+
+34. **return:** 用于在代码执行完成后返回(一个值)。
+
+35. **short:** 用于声明一个可以容纳 16 位整数的变量。
+
+36. **static:** 表示该变量或方法是[静态变量或静态方法](https://tobebetterjavaer.com/oo/static.html)。
+
+37. **strictfp:** 并不常见,通常用于修饰一个方法,确保方法体内的浮点数运算在每个平台上执行的结果相同。
+
+38. **super:** 可用于[调用父类的方法或者字段](https://tobebetterjavaer.com/oo/this-super.html)。
+
+39. **switch:** 通常用于三个(以上)的条件判断。
+
+40. **synchronized:** [用于指定多线程代码中的同步方法、变量或者代码块](https://tobebetterjavaer.com/thread/synchronized-1.html)。
+
+41. **this:** [可用于在方法或构造函数中引用当前对象](https://tobebetterjavaer.com/oo/this-super.html)。
+
+42. **throw:** 主动抛出[异常](https://tobebetterjavaer.com/exception/gailan.html)。
+
+43. **throws:** 用于声明异常。
+
+44. **transient:** [修饰的字段不会被序列化](https://tobebetterjavaer.com/io/transient.html)。
+
+45. **try:** 于包裹要捕获异常的代码块。
+
+46. **void:** 用于指定方法没有返回值。
+
+47. **volatile:** 保证不同线程对它修饰的变量进行操作时的[可见性](https://tobebetterjavaer.com/thread/volatile.html),即一个线程修改了某个变量的值,新值对其他线程来说是立即可见的。
+
+48. **while:** 如果循环次数不固定,建议使用 while 循环。
+
+
+“好了,三妹,关于 Java 中的关键字就先说这 48 个吧,这只是一个大概的介绍,后面还会对一些特殊的关键字单独拎出来详细地讲,比如说重要的 static、final 等等。”转动了一下僵硬的脖子后,我对三妹说。
+
+“除了这些关键字,Java 中还有两个非常特殊的保留字(goto 和 const),它们不能在程序中使用。”
+
+“goto 在 C语言中叫做‘无限跳转’语句,在 Java 中,不再使用 goto 语句,因为无限跳转会破坏程序结构。”
+
+“const 在 C语言中是声明常量的关键字,在 Java 中可以使用 public static final 三个关键字的组合来达到常量的效果。”
+
+“好的二哥,我了解了,你休息会,我再记一记。”
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
+
diff --git a/docs/src/basic-extra-meal/Overriding.md b/docs/basic-extra-meal/Overriding.md
similarity index 87%
rename from docs/src/basic-extra-meal/Overriding.md
rename to docs/basic-extra-meal/Overriding.md
index 3909563477..911886dcf1 100644
--- a/docs/src/basic-extra-meal/Overriding.md
+++ b/docs/basic-extra-meal/Overriding.md
@@ -5,11 +5,11 @@ category:
- Java核心
tag:
- Java重要知识点
-description: 二哥的Java进阶之路,小白的零基础Java教程,从入门到进阶,Java重写(Overriding)时应当遵守的11条规则
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,Java重写(Overriding)时应当遵守的11条规则
head:
- - meta
- name: keywords
- content: Java,Java SE,Java基础,Java教程,二哥的Java进阶之路,Java进阶之路,Java入门,教程,java,重写,Overriding
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,重写,Overriding
---
@@ -19,7 +19,7 @@ head:
重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。在下面这幅图中,Animal 是父类,Dog 是子类,Dog 重新实现了 `move()` 方法用来和父类进行区分,毕竟狗狗跑起来还是比较有特色的。
-
+
重写的方法和被重写的方法,不仅方法名相同,参数也相同,只不过,方法体有所不同。
@@ -83,7 +83,7 @@ public class Animal {
由于父类 Animal 中的 `move()` 是 final 的,所以子类在尝试重写该方法的时候就出现编译错误了!
-
+
同样的,如果一个方法是 static 的,也不允许重写,因为静态方法可用于父类以及子类的所有实例。
@@ -95,7 +95,7 @@ public class Animal {
重写的目的在于根据对象的类型不同而表现出多态,而静态方法不需要创建对象就可以使用。没有了对象,重写所需要的“对象的类型”也就没有存在的意义了。
-
+
## 04、重写方法的要求
@@ -147,7 +147,7 @@ public class Dog extends Animal {
于是就编译出错了(返回类型不兼容)。
-
+
### **规则五:重写的方法不能使用限制等级更严格的权限修饰符**。
@@ -175,7 +175,7 @@ public class Dog extends Animal {
如果子类中的方法用了更严格的权限修饰符,编译器就报错了。
-
+
### **规则六:重写后的方法不能抛出比父类中更高级别的异常**。
@@ -326,9 +326,8 @@ synchronized 关键字用于在多线程环境中获取和释放监听对象,
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
-
-
+
diff --git a/docs/src/basic-extra-meal/annotation.md b/docs/basic-extra-meal/annotation.md
similarity index 87%
rename from docs/src/basic-extra-meal/annotation.md
rename to docs/basic-extra-meal/annotation.md
index 829a06f6d1..445033d1a1 100644
--- a/docs/src/basic-extra-meal/annotation.md
+++ b/docs/basic-extra-meal/annotation.md
@@ -1,24 +1,26 @@
---
-title: Java注解,请别小看我。
+title: 深入理解Java中的注解
shortTitle: Java注解
category:
- Java核心
tag:
- Java重要知识点
-description: 本文深入探讨了Java注解的概念、分类及其在实际项目中的应用。通过详细的示例和解释,帮助读者更好地理解和掌握Java注解技术,学会如何自定义注解以及在实际开发中灵活运用,提升代码的可读性和可维护性。
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,深入理解Java中的注解
head:
- - meta
- name: keywords
- content: Java,注解,annotation,java 注解,java annotation
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,注解,annotation,java 注解,java annotation
---
+# 5.22 Java注解
+
“二哥,这节讲注解吗?”三妹问。
-“是的。”我说,“注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。`@Override` 注解用过吧?[方法重写](https://javabetter.cn/basic-extra-meal/override-overload.html)的时候用到过。但你知道怎么自定义一个注解吗?”
+“是的。”我说,“注解是 Java 中非常重要的一部分,但经常被忽视也是真的。之所以这么说是因为我们更倾向成为一名注解的使用者而不是创建者。`@Override` 注解用过吧?[方法重写](https://tobebetterjavaer.com/basic-extra-meal/override-overload.html)的时候用到过。但你知道怎么自定义一个注解吗?”
三妹毫不犹豫地摇摇头,摆摆手,不好意思地承认自己的确没有自定义过。
-
+
“好吧,哥来告诉你吧。”
@@ -232,9 +234,8 @@ public class JsonFieldTest {
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
-
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-
+
diff --git a/docs/basic-extra-meal/box.md b/docs/basic-extra-meal/box.md
new file mode 100644
index 0000000000..ca3ade648a
--- /dev/null
+++ b/docs/basic-extra-meal/box.md
@@ -0,0 +1,273 @@
+---
+title: 深入剖析Java中的拆箱和装箱
+shortTitle: 深入剖析Java中的拆箱和装箱
+category:
+ - Java核心
+tag:
+ - Java重要知识点
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,深入剖析Java中的拆箱和装箱
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,装箱,拆箱,包装类型
+---
+
+
+“哥,听说 Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double,是这样吗?”从三妹这句话当中,能听得出来,她已经提前预习这块内容了。
+
+“是的,三妹。基本类型和包装类型的区别主要有以下 4 点,我来带你学习一下。”我回答说。我们家的斜对面刚好是一所小学,所以时不时还能听到朗朗的读书声,让人心情非常愉快。
+
+“三妹,你准备好了吗?我们开始吧。”
+
+“第一,**包装类型可以为 null,而基本类型不可以**。别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行。”
+
+“POJO 是什么呢?”遇到不会的就问,三妹在这一点上还是非常兢兢业业的。
+
+“POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 Java 对象,只有字段以及对应的 setter 和 getter 方法。”
+
+```java
+class Writer {
+ private Integer age;
+ private String name;
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+```
+
+和 POJO 类似的,还有数据传输对象 DTO(Data Transfer Object,泛指用于展示层与服务层之间的数据传输对象)、视图对象 VO(View Object,把某个页面的数据封装起来)、持久化对象 PO(Persistant Object,可以看成是与数据库中的表映射的 Java 对象)。
+
+“那为什么 POJO 的字段必须要用包装类型呢?”三妹问。
+
+“《阿里巴巴 Java 开发手册》上有详细的说明,你看。”我打开 PDF,并翻到了对应的内容,指着屏幕念道。
+
+>数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱,就会抛出 NullPointerException 的异常。
+
+“什么是自动拆箱呢?”
+
+“自动拆箱指的是,将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值;对应的,把基本类型转为包装类型,则称为自动装箱。”
+
+“哦。”
+
+“那接下来,我们来看第二点不同。**包装类型可用于泛型,而基本类型不可以**,否则就会出现编译错误。”一边说着,我一边在 Intellij IDEA 中噼里啪啦地敲了起来。
+
+“三妹,你瞧,编译器提示错误了。”
+
+```java
+List list = new ArrayList<>(); // 提示 Syntax error, insert "Dimensions" to complete ReferenceType
+List list = new ArrayList<>();
+```
+
+“为什么呢?”三妹及时地问道。
+
+“因为泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类——基本类型是个例外。”
+
+“那,接下来,我们来说第三点,**基本类型比包装类型更高效**。”我喝了一口茶继续说道。
+
+“作为局部变量时,基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。”我一边说着,一边打开 `draw.io` 画起了图。
+
+
+
+很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间,不仅要存储对象,还要存储引用。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过 new 一个包装类型就显得非常笨重。
+
+“三妹,你想知道程序运行时,数据都存储在什么地方吗?”
+
+“嗯嗯,哥,你说说呗。”
+
+“通常来说,有 4 个地方可以用来存储数据。”
+
+1)寄存器。这是最快的存储区,因为它位于 CPU 内部,用来暂时存放参与运算的数据和运算结果。
+
+2)栈。位于 RAM(Random Access Memory,也叫主存,与 CPU 直接交换数据的内部存储器)中,速度仅次于寄存器。但是,在分配内存的时候,存放在栈中的数据大小与生存周期必须在编译时是确定的,缺乏灵活性。基本数据类型的值和对象的引用通常存储在这块区域。
+
+3)堆。也位于 RAM 区,可以动态分配内存大小,编译器不必知道要从堆里分配多少存储空间,生存周期也不必事先告诉编译器,Java 的垃圾收集器会自动收走不再使用的数据,因此可以得到更大的灵活性。但是,运行时动态分配内存和销毁对象都需要占用时间,所以效率比栈低一些。new 创建的对象都会存储在这块区域。
+
+4)磁盘。如果数据完全存储在程序之外,就可以不受程序的限制,在程序没有运行时也可以存在。像文件、数据库,就是通过持久化的方式,让对象存放在磁盘上。当需要的时候,再反序列化成程序可以识别的对象。
+
+“能明白吗?三妹?”
+
+“这节讲完后,我再好好消化一下。”
+
+“那好,我们来说第四点,**两个包装类型的值可以相同,但却不相等**。”
+
+```java
+Integer chenmo = new Integer(10);
+Integer wanger = new Integer(10);
+
+System.out.println(chenmo == wanger); // false
+System.out.println(chenmo.equals(wanger )); // true
+```
+
+“两个包装类型在使用“==”进行判断的时候,判断的是其指向的地址是否相等,由于是两个对象,所以地址是不同的。”
+
+“而 chenmo.equals(wanger) 的输出结果为 true,是因为 equals() 方法内部比较的是两个 int 值是否相等。”
+
+```java
+private final int value;
+
+public int intValue() {
+ return value;
+}
+public boolean equals(Object obj) {
+ if (obj instanceof Integer) {
+ return value == ((Integer)obj).intValue();
+ }
+ return false;
+}
+```
+
+虽然 chenmo 和 wanger 的值都是 10,但他们并不相等。换句话说就是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。
+
+“三妹,瞧,`((Integer)obj).intValue()` 这段代码就是用来自动拆箱的。下面,我们来详细地说一说自动装箱和自动拆箱。”
+
+既然有基本类型和包装类型,肯定有些时候要在它们之间进行转换。把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。
+
+在 Java 1.5 之前,开发人员要手动进行装拆箱,比如说:
+
+```java
+Integer chenmo = new Integer(10); // 手动装箱
+int wanger = chenmo.intValue(); // 手动拆箱
+```
+
+Java 1.5 为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能。这下就方便了。
+
+```jav
+Integer chenmo = 10; // 自动装箱
+int wanger = chenmo; // 自动拆箱
+```
+
+来看一下反编译后的代码。
+
+```java
+Integer chenmo = Integer.valueOf(10);
+int wanger = chenmo.intValue();
+```
+
+也就是说,自动装箱是通过 `Integer.valueOf()` 完成的;自动拆箱是通过 `Integer.intValue()` 完成的。
+
+“嗯,三妹,给你出一道面试题吧。”
+
+```java
+// 1)基本类型和包装类型
+int a = 100;
+Integer b = 100;
+System.out.println(a == b);
+
+// 2)两个包装类型
+Integer c = 100;
+Integer d = 100;
+System.out.println(c == d);
+
+// 3)
+c = 200;
+d = 200;
+System.out.println(c == d);
+```
+
+“给你 3 分钟时间,你先思考下,我去抽根华子,等我回来,然后再来分析一下为什么。”
+
+。。。。。。
+
+“嗯,哥,你过来吧,我说一说我的想法。”
+
+第一段代码,基本类型和包装类型进行 == 比较,这时候 b 会自动拆箱,直接和 a 比较值,所以结果为 true。
+
+第二段代码,两个包装类型都被赋值为了 100,这时候会进行自动装箱,按照你之前说的,将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符,我想结果可能为 false。
+
+第三段代码,两个包装类型重新被赋值为了 200,这时候仍然会进行自动装箱,我想结果仍然为 false。
+
+“嗯嗯,三妹,你分析的很有逻辑,但第二段代码的结果为 true,是不是感到很奇怪?”
+
+“为什么会这样呀?”三妹急切地问。
+
+“你说的没错,自动装箱是通过 Integer.valueOf() 完成的,我们来看看这个方法的源码就明白为什么了。”
+
+```java
+public static Integer valueOf(int i) {
+ if (i >= IntegerCache.low && i <= IntegerCache.high)
+ return IntegerCache.cache[i + (-IntegerCache.low)];
+ return new Integer(i);
+}
+```
+
+是不是看到了一个之前从来没见过的类——IntegerCache?
+
+“难道说是 Integer 的缓存类?”三妹做出了自己的判断。
+
+“是的,来看一下 IntegerCache 的源码吧。”
+
+```java
+private static class IntegerCache {
+ static final int low = -128;
+ static final int high;
+ static final Integer cache[];
+
+ static {
+ // high value may be configured by property
+ int h = 127;
+ int i = parseInt(integerCacheHighPropValue);
+ i = Math.max(i, 127);
+ h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
+ high = h;
+
+ cache = new Integer[(high - low) + 1];
+ int j = low;
+ for(int k = 0; k < cache.length; k++)
+ cache[k] = new Integer(j++);
+
+ // range [-128, 127] must be interned (JLS7 5.1.7)
+ assert IntegerCache.high >= 127;
+ }
+}
+```
+
+大致瞟一下这段代码你就全明白了。-128 到 127 之间的数会从 IntegerCache 中取,然后比较,所以第二段代码(100 在这个范围之内)的结果是 true,而第三段代码(200 不在这个范围之内,所以 new 出来了两个 Integer 对象)的结果是 false。
+
+“三妹,看完上面的分析之后,我希望你记住一点:**当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象**。”
+
+“自动装拆箱是一个很好的功能,大大节省了我们开发人员的精力,但也会引发一些麻烦,比如下面这段代码,性能就很差。”
+
+```java
+long t1 = System.currentTimeMillis();
+Long sum = 0L;
+for (int i = 0; i < Integer.MAX_VALUE;i++) {
+ sum += i;
+}
+long t2 = System.currentTimeMillis();
+System.out.println(t2-t1);
+```
+
+“知道为什么吗?三妹。”
+
+“难道是因为 sum 被声明成了包装类型 Long 而不是基本类型 long。”三妹若有所思。
+
+“是滴,由于 sum 是个 Long 型,而 i 为 int 类型,`sum += i` 在执行的时候,会先把 i 强转为 long 型,然后再把 sum 拆箱为 long 型进行相加操作,之后再自动装箱为 Long 型赋值给 sum。”
+
+“三妹,你可以试一下,把 sum 换成 long 型比较一下它们运行的时间。”
+
+。。。。。。
+
+“哇,sum 为 Long 型的时候,足足运行了 5825 毫秒;sum 为 long 型的时候,只需要 679 毫秒。”
+
+“好了,三妹,今天的主题就先讲到这吧。我再去来根华子。”
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
\ No newline at end of file
diff --git a/docs/src/basic-extra-meal/class-object.md b/docs/basic-extra-meal/class-object.md
similarity index 86%
rename from docs/src/basic-extra-meal/class-object.md
rename to docs/basic-extra-meal/class-object.md
index b49fcb7627..a3da44acb5 100644
--- a/docs/src/basic-extra-meal/class-object.md
+++ b/docs/basic-extra-meal/class-object.md
@@ -5,11 +5,11 @@ category:
- Java核心
tag:
- Java重要知识点
-description: 二哥的Java进阶之路,小白的零基础Java教程,从入门到进阶,Java 中,先有Class还是先有Object?
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,Java 中,先有Class还是先有Object?
head:
- - meta
- name: keywords
- content: Java,Java SE,Java基础,Java教程,二哥的Java进阶之路,Java进阶之路,Java入门,教程,java,class,object
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,class,object
---
@@ -21,7 +21,7 @@ Java 对象模型中:
那到底是先有Class还是先有Object? JVM 是怎么处理这个“鸡·蛋”问题呢?
-
+
针对这个问题,我在知乎上看到了 R 大的一个回答,正好解答了我心中的疑惑,就分享出来给各位小伙伴一个参考和启发~
@@ -94,12 +94,11 @@ http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/ade5be2b1758/src/share/vm/cl
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
-
-
+
diff --git a/docs/basic-extra-meal/comparable-omparator.md b/docs/basic-extra-meal/comparable-omparator.md
new file mode 100644
index 0000000000..db6c03c4d2
--- /dev/null
+++ b/docs/basic-extra-meal/comparable-omparator.md
@@ -0,0 +1,201 @@
+---
+title: Comparable和Comparator的区别
+shortTitle: Comparable和Comparator
+category:
+ - Java核心
+tag:
+ - Java重要知识点
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,Comparable和Comparator接口的区别
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,java Comparable和Comparator,java Comparable, java Comparator,Comparable Comparator
+---
+
+# 6.14 Comparable和Comparator
+
+>在前面学习[优先级队列](https://tobebetterjavaer.com/collection/PriorityQueue.html)的时候,我们曾提到过 Comparable和Comparator,那这篇继续以面试官的角度去切入,一起来看。
+
+那天,小二去马蜂窝面试,面试官老王一上来就甩给了他一道面试题:请问Comparable和Comparator有什么区别?小二差点笑出声,因为三年前,也就是 2021 年,他在《[二哥的Java进阶之路](https://tobebetterjavaer.com/basic-extra-meal/comparable-omparator.html)》上看到过这题😆。
+
+Comparable 和 Comparator 是 Java 的两个接口,从名字上我们就能够读出来它们俩的相似性:以某种方式来比较两个对象。
+
+但它们之间到底有什么区别呢?请随我来,打怪进阶喽!
+
+### 01、Comparable
+
+Comparable 接口的定义非常简单,源码如下所示。
+
+```java
+public interface Comparable {
+ int compareTo(T t);
+}
+```
+
+如果一个类实现了 Comparable 接口(只需要干一件事,重写 `compareTo()` 方法),就可以按照自己制定的规则将由它创建的对象进行比较。下面给出一个例子。
+
+```java
+public class Cmower implements Comparable {
+ private int age;
+ private String name;
+
+ public Cmower(int age, String name) {
+ this.age = age;
+ this.name = name;
+ }
+
+ @Override
+ public int compareTo(Cmower o) {
+ return this.getAge() - o.getAge();
+ }
+
+ public static void main(String[] args) {
+ Cmower wanger = new Cmower(19,"沉默王二");
+ Cmower wangsan = new Cmower(16,"沉默王三");
+
+ if (wanger.compareTo(wangsan) < 0) {
+ System.out.println(wanger.getName() + "比较年轻有为");
+ } else {
+ System.out.println(wangsan.getName() + "比较年轻有为");
+ }
+ }
+}
+```
+
+在上面的示例中,我创建了一个 Cmower 类,它有两个字段:age 和 name。Cmower 类实现了 Comparable 接口,并重写了 `compareTo()` 方法。
+
+程序输出的结果是“沉默王三比较年轻有为”,因为他比沉默王二小三岁。这个结果有什么凭证吗?
+
+凭证就在于 `compareTo()` 方法,该方法的返回值可能为负数,零或者正数,代表的意思是该对象按照排序的规则小于、等于或者大于要比较的对象。如果指定对象的类型与此对象不能进行比较,则引发 `ClassCastException` 异常(自从有了[泛型](https://tobebetterjavaer.com/basic-extra-meal/generic.html),这种情况就少有发生了)。
+
+### 02、Comparator
+
+Comparator 接口的定义相比较于 Comparable 就复杂的多了,不过,核心的方法只有两个,来看一下源码。
+
+```java
+public interface Comparator {
+ int compare(T o1, T o2);
+ boolean equals(Object obj);
+}
+```
+
+第一个方法 `compare(T o1, T o2)` 的返回值可能为负数,零或者正数,代表的意思是第一个对象小于、等于或者大于第二个对象。
+
+第二个方法 `equals(Object obj)` 需要传入一个 Object 作为参数,并判断该 Object 是否和 Comparator 保持一致。
+
+有时候,我们想让类保持它的原貌,不想主动实现 Comparable 接口,但我们又需要它们之间进行比较,该怎么办呢?
+
+Comparator 就派上用场了,来看一下示例。
+
+#### 1)原封不动的 Cmower 类。
+
+```java
+public class Cmower {
+ private int age;
+ private String name;
+
+ public Cmower(int age, String name) {
+ this.age = age;
+ this.name = name;
+ }
+}
+```
+
+Cmower 类有两个字段:age 和 name,意味着该类可以按照 age 或者 name 进行排序。
+
+#### 2)再来看 Comparator 接口的实现类。
+
+```java
+public class CmowerComparator implements Comparator {
+ @Override
+ public int compare(Cmower o1, Cmower o2) {
+ return o1.getAge() - o2.getAge();
+ }
+}
+```
+
+按照 age 进行比较。当然也可以再实现一个比较器,按照 name 进行自然排序,示例如下。
+
+```java
+public class CmowerNameComparator implements Comparator {
+ @Override
+ public int compare(Cmower o1, Cmower o2) {
+ if (o1.getName().hashCode() < o2.getName().hashCode()) {
+ return -1;
+ } else if (o1.getName().hashCode() == o2.getName().hashCode()) {
+ return 0;
+ }
+ return 1;
+ }
+}
+```
+
+#### 3)再来看测试类。
+
+```java
+Cmower wanger = new Cmower(19,"沉默王二");
+Cmower wangsan = new Cmower(16,"沉默王三");
+Cmower wangyi = new Cmower(28,"沉默王一");
+
+List list = new ArrayList<>();
+list.add(wanger);
+list.add(wangsan);
+list.add(wangyi);
+
+list.sort(new CmowerComparator());
+
+for (Cmower c : list) {
+ System.out.println(c.getName());
+}
+```
+
+创建了三个对象,age 不同,name 不同,并把它们加入到了 List 当中。然后使用 List 的 `sort()` 方法进行排序,来看一下输出的结果。
+
+```
+沉默王三
+沉默王二
+沉默王一
+```
+
+这意味着沉默王三的年纪比沉默王二小,排在第一位;沉默王一的年纪比沉默王二大,排在第三位。和我们的预期完全符合。
+
+借此机会,再来看一下 sort 方法的源码:
+
+```java
+public void sort(Comparator super E> c) {
+ // 保存当前队列的 modCount 值,用于检测 sort 操作是否非法
+ final int expectedModCount = modCount;
+ // 调用 Arrays.sort 对 elementData 数组进行排序,使用传入的比较器 c
+ Arrays.sort((E[]) elementData, 0, size, c);
+ // 检查操作期间 modCount 是否被修改,如果被修改则抛出并发修改异常
+ if (modCount != expectedModCount) {
+ throw new ConcurrentModificationException();
+ }
+ // 增加 modCount 值,表示队列已经被修改过
+ modCount++;
+}
+```
+
+可以看到,参数就是一个 Comparator 接口,并且使用了[泛型](https://tobebetterjavaer.com/basic-extra-meal/generic.html) `Comparator super E> c`。
+
+### 03、到底该用哪一个?
+
+通过上面的两个例子可以比较出 Comparable 和 Comparator 两者之间的区别:
+
+- 一个类实现了 Comparable 接口,意味着该类的对象可以直接进行比较(排序),但比较(排序)的方式只有一种,很单一。
+- 一个类如果想要保持原样,又需要进行不同方式的比较(排序),就可以定制比较器(实现 Comparator 接口)。
+- Comparable 接口在 `java.lang` 包下,而 `Comparator` 接口在 `java.util` 包下,算不上是亲兄弟,但可以称得上是表(堂)兄弟。
+
+举个不恰当的例子。我想从洛阳出发去北京看长城,体验一下好汉的感觉,要么坐飞机,要么坐高铁;但如果是孙悟空的话,翻个筋斗就到了。我和孙悟空之间有什么区别呢?
+
+孙悟空自己实现了 Comparable 接口(他那年代也没有飞机和高铁,没得选),而我可以借助 Comparator 接口(现代化的交通工具)。
+
+好了,关于 Comparable 和 Comparator 我们就先聊这么多。总而言之,如果对象的排序需要基于自然顺序,请选择 `Comparable`,如果需要按照对象的不同属性进行排序,请选择 `Comparator`。
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
\ No newline at end of file
diff --git a/docs/src/basic-extra-meal/deep-copy.md b/docs/basic-extra-meal/deep-copy.md
similarity index 85%
rename from docs/src/basic-extra-meal/deep-copy.md
rename to docs/basic-extra-meal/deep-copy.md
index f5e662fa53..73419ed845 100644
--- a/docs/src/basic-extra-meal/deep-copy.md
+++ b/docs/basic-extra-meal/deep-copy.md
@@ -1,31 +1,29 @@
---
-title: 深入理解Java浅拷贝与深拷贝
-shortTitle: 深入理解Java浅拷贝与深拷贝
+title: 一文彻底讲明白的Java中的浅拷贝与深拷贝
+shortTitle: Java中的浅拷贝与深拷贝
category:
- Java核心
tag:
- Java重要知识点
-description: 本文详细讨论了Java中的浅拷贝和深拷贝概念,解析了它们如何在实际编程中应用。文章通过实例演示了如何实现浅拷贝与深拷贝,以帮助读者更好地理解这两种拷贝方式在Java编程中的作用与应用场景。
-author: 沉默王二
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,一文彻底讲明白的Java中的浅拷贝与深拷贝
head:
- - meta
- name: keywords
- content: Java,Java SE,Java基础,Java教程,二哥的Java进阶之路,Java进阶之路,Java入门,教程,java,深拷贝,浅拷贝
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,深拷贝,浅拷贝
---
“哥,听说浅拷贝和深拷贝是 Java 面试中经常会被问到的一个问题,是这样吗?”
-“还真的是,而且了解浅拷贝和深拷贝的原理,对 [Java 是值传递还是引用传递](https://javabetter.cn/basic-extra-meal/pass-by-value.html)也会有更深的理解。”我肯定地回答。
+“还真的是,而且了解浅拷贝和深拷贝的原理,对 Java 是值传递还是引用传递也会有更深的理解。”我肯定地回答。
“不管是浅拷贝还是深拷贝,都可以通过调用 Object 类的 `clone()` 方法来完成。”我一边说,一边打开 Intellij IDEA,并找到了 `clone()` 方法的源码。
```java
+@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
```
-需要注意的是,`clone()` 方法同时是一个本地(`native`)方法,它的具体实现会交给 HotSpot 虚拟机,那就意味着虚拟机在运行该方法的时候,会将其替换为更高效的 C/C++ 代码,进而调用操作系统去完成对象的克隆工作。
-
->Java 9 后,该方法会被标注 `@HotSpotIntrinsicCandidate` 注解,被该注解标注的方法,在 HotSpot 虚拟机中会有一套高效的实现。
+其中 `@HotSpotIntrinsicCandidate` 是 Java 9 引入的一个注解,被它标注的方法,在 HotSpot 虚拟机中会有一套高效的实现。需要注意的是,`clone()` 方法同时是一个本地(`native`)方法,它的具体实现会交给 HotSpot 虚拟机,那就意味着虚拟机在运行该方法的时候,会将其替换为更高效的 C/C++ 代码,进而调用操作系统去完成对象的克隆工作。
“哥,那你就先说浅拷贝吧!”
@@ -50,6 +48,7 @@ class Writer implements Cloneable{
Writer 类有两个字段,分别是 int 类型的 age,和 String 类型的 name。然后重写了 `toString()` 方法,方便打印对象的具体信息。
+
“为什么要实现 Cloneable 接口呢?”三妹开启了十万个为什么的模式。
Cloneable 接口是一个标记接口,它肚子里面是空的:
@@ -109,7 +108,7 @@ writer2:Writer@b97c004{age=18, name='三妹'}
可以看得出,浅拷贝后,writer1 和 writer2 引用了不同的对象,但值是相同的,说明拷贝成功。之后,修改了 writer2 的 name 字段,直接上图就明白了。
-
+
之前的例子中,Writer 类只有两个字段,没有引用类型字段。那么,我们再来看另外一个例子,为 Writer 类增加一个自定义的引用类型字段 Book,先来看 Book 的定义。
@@ -208,7 +207,7 @@ writer2:Writer@36d4b5c age=18, name='二哥', book=Book@32e6e9c3 bookName='永
与之前例子不同的是,writer2.book 变更后,writer1.book 也发生了改变。这是因为字符串 String 是不可变对象,一个新的值必须在字符串常量池中开辟一段新的内存空间,而自定义对象的内存地址并没有发生改变,只是对应的字段值发生了改变,见下图。
-
+
“哇,哥,果真一图胜千言,我明白了。”三妹似乎对我画的图很感兴趣呢,“那你继续说深拷贝吧!”
@@ -309,15 +308,15 @@ writer2:Writer@6d00a15d age=18, name='二哥', book=Book@51efea79 bookName='
不只是 writer1 和 writer2 是不同的对象,它们中的 book 也是不同的对象。所以,改变了 writer2 中的 book 并不会影响到 writer1。
-
+
不过,通过 `clone()` 方法实现的深拷贝比较笨重,因为要将所有的引用类型都重写 `clone()` 方法,当嵌套的对象比较多的时候,就废了!
“那有没有好的办法呢?”三妹急切的问。
-“当然有了,利用[序列化](https://javabetter.cn/io/serialize.html)。”我胸有成竹的回答,“序列化是将对象写到流中便于传输,而反序列化则是将对象从流中读取出来。”
+“当然有了,利用序列化。”我胸有成竹的回答,“序列化是将对象写到流中便于传输,而反序列化则是将对象从流中读取出来。”
-“写入流中的对象就是对原始对象的拷贝。需要注意的是,每个要序列化的类都要实现 [Serializable 接口](https://javabetter.cn/io/Serializbale.html),该接口和 Cloneable 接口类似,都是标记型接口。”
+“写入流中的对象就是对原始对象的拷贝。需要注意的是,每个要序列化的类都要实现 Serializable 接口,该接口和 Cloneable 接口类似,都是标记型接口。”
来看例子。
@@ -424,9 +423,8 @@ writer2:Writer@544fe44c age=18, name='二哥', book=Book@31610302 bookName='
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
-
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-
+
diff --git a/docs/src/basic-extra-meal/enum.md b/docs/basic-extra-meal/enum.md
similarity index 75%
rename from docs/src/basic-extra-meal/enum.md
rename to docs/basic-extra-meal/enum.md
index 68eca8ebc6..b4504f10f9 100644
--- a/docs/src/basic-extra-meal/enum.md
+++ b/docs/basic-extra-meal/enum.md
@@ -1,15 +1,15 @@
---
-title: Java枚举:小小enum,优雅而干净
+title: 新来个技术总监,彻底把 Java 枚举(enum)讲清楚了
shortTitle: Java枚举(enum)
category:
- Java核心
tag:
- Java重要知识点
-description: 本文全面介绍了Java枚举的概念、基础语法、高级应用以及在实际项目中的应用。通过详细的示例和解释,帮助读者深入理解枚举类型的使用
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,新来个技术总监,彻底把 Java 枚举(enum)讲清楚了
head:
- - meta
- name: keywords
- content: Java,枚举,enum,java 枚举,java enum
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,枚举,enum
---
“今天我们来学习枚举吧,三妹!”我说,“同学让你去她家玩了两天,感觉怎么样呀?”
@@ -121,25 +121,25 @@ if(player.getType().equals(Player.PlayerType.BASKETBALL)){};
另外, “==”运算符会在编译时进行检查,如果两侧的类型不匹配,会提示错误,而 `equals()` 方法则不会。
-
+
“枚举还可用于 switch 语句,和基本数据类型的用法一致。”我说。
```java
switch (playerType) {
- case TENNIS:
- return "网球运动员费德勒";
- case FOOTBALL:
- return "足球运动员C罗";
- case BASKETBALL:
- return "篮球运动员詹姆斯";
- case UNKNOWN:
- throw new IllegalArgumentException("未知");
- default:
- throw new IllegalArgumentException(
- "运动员类型: " + playerType);
+ case TENNIS:
+ return "网球运动员费德勒";
+ case FOOTBALL:
+ return "足球运动员C罗";
+ case BASKETBALL:
+ return "篮球运动员詹姆斯";
+ case UNKNOWN:
+ throw new IllegalArgumentException("未知");
+ default:
+ throw new IllegalArgumentException(
+ "运动员类型: " + playerType);
-}
+ }
```
“如果枚举中需要包含更多信息的话,可以为其添加一些字段,比如下面示例中的 name,此时需要为枚举添加一个带参的构造方法,这样就可以在定义枚举时添加对应的名称了。”我继续说。
@@ -166,11 +166,12 @@ public enum PlayerType {
“来吧,我准备好了。”
-“EnumSet 是一个专门针对枚举类型的 [Set 接口](https://javabetter.cn/collection/gailan.html)(后面会讲)的实现类,它是处理枚举类型数据的一把利器,非常高效。”我说,“从名字上就可以看得出,EnumSet 不仅和 Set 有关系,和枚举也有关系。”
+“EnumSet 是一个专门针对枚举类型的 Set 接口(后面会讲)的实现类,它是处理枚举类型数据的一把利器,非常高效。”我说,“从名字上就可以看得出,EnumSet 不仅和 Set 有关系,和枚举也有关系。”
“因为 EnumSet 是一个抽象类,所以创建 EnumSet 时不能使用 new 关键字。不过,EnumSet 提供了很多有用的静态工厂方法。”
-
+
+
“来看下面这个例子,我们使用 `noneOf()` 静态工厂方法创建了一个空的 PlayerType 类型的 EnumSet;使用 `allOf()` 静态工厂方法创建了一个包含所有 PlayerType 类型的 EnumSet。”
@@ -201,7 +202,7 @@ public class EnumSetTest {
有了 EnumSet 后,就可以使用 Set 的一些方法了,见下图。
-
+
“除了 EnumSet,还有 EnumMap,是一个专门针对枚举类型的 Map 接口的实现类,它可以将枚举常量作为键来使用。EnumMap 的效率比 HashMap 还要高,可以直接通过数组下标(枚举的 ordinal 值)访问到元素。”
@@ -213,9 +214,9 @@ EnumMap enumMap = new EnumMap<>(PlayerType.class);
有了 EnumMap 对象后就可以使用 Map 的一些方法了,见下图。
-
+
-和 [HashMap](https://javabetter.cn/collection/hashmap.html)(后面会讲)的使用方法大致相同,来看下面的例子。
+和 HashMap(后面会讲)的使用方法大致相同,来看下面的例子。
```java
EnumMap enumMap = new EnumMap<>(PlayerType.class);
@@ -275,7 +276,7 @@ public class Singleton {
}
```
-“要用到 [volatile](https://javabetter.cn/thread/volatile.html)、[synchronized](https://javabetter.cn/thread/synchronized-1.html) 关键字等等,但枚举的出现,让代码量减少到极致。”
+“要用到 volatile、synchronized 关键字等等,但枚举的出现,让代码量减少到极致。”
```java
public enum EasySingleton{
@@ -285,7 +286,7 @@ public enum EasySingleton{
“就这?”三妹睁大了眼睛。
-“对啊,枚举默认实现了 [Serializable 接口](https://javabetter.cn/io/Serializbale.html),因此 Java 虚拟机可以保证该类为单例,这与传统的实现方式不大相同。传统方式中,我们必须确保单例在反序列化期间不能创建任何新实例。”我说。
+“对啊,枚举默认实现了 Serializable 接口,因此 Java 虚拟机可以保证该类为单例,这与传统的实现方式不大相同。传统方式中,我们必须确保单例在反序列化期间不能创建任何新实例。”我说。
“好了,关于枚举就讲这么多吧,三妹,你把这些代码都手敲一遍吧!”
@@ -295,9 +296,8 @@ public enum EasySingleton{
----
-GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
-
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
-微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **222** 即可免费领取。
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
-
+
diff --git a/docs/basic-extra-meal/equals-hashcode.md b/docs/basic-extra-meal/equals-hashcode.md
new file mode 100644
index 0000000000..97da20965e
--- /dev/null
+++ b/docs/basic-extra-meal/equals-hashcode.md
@@ -0,0 +1,245 @@
+---
+title: 为什么重写equals方法的时候必须要重写hashCode方法?
+shortTitle: 为什么重写equals的时候必须重写hashCode
+category:
+ - Java核心
+tag:
+ - Java重要知识点
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,为什么重写equals方法的时候必须要重写hashCode方法
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,hashcode,equals
+---
+
+“二哥,我在读《Effective Java》 的时候,第 11 条规约说重写 equals 的时候必须要重写 hashCode 方法,这是为什么呀?”三妹单刀直入地问。
+
+“三妹啊,这个问题问得非常好,因为它也是面试中经常考的一个知识点。今天哥就带你来梳理一下。”我说。
+
+Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。
+
+Object 类中有这么两个方法:
+
+```java
+public native int hashCode();
+
+public boolean equals(Object obj) {
+ return (this == obj);
+}
+```
+1)hashCode 方法
+
+这是一个本地方法,用来返回对象的哈希值(一个整数)。在 Java 程序执行期间,对同一个对象多次调用该方法必须返回相同的哈希值。
+
+2)equals 方法
+
+对于任何非空引用 x 和 y,当且仅当 x 和 y 引用的是同一个对象时,equals 方法才返回 true。
+
+“二哥,看起来两个方法之间没有任何关联啊?”三妹质疑道。
+
+“单从这两段解释上来看,的确是这样的。”我解释道,“但两个方法的 doc 文档中还有这样两条信息。”
+
+第一,如果两个对象调用 equals 方法返回的结果为 true,那么两个对象调用 hashCode 方法返回的结果也必然相同——来自 hashCode 方法的 doc 文档。
+
+第二,每当重写 equals 方法时,hashCode 方法也需要重写,以便维护上一条规约。
+
+“哦,这样讲的话,两个方法确实关联上了,但究竟是为什么呢?”三妹抛出了终极一问。
+
+“hashCode 方法的作用是用来获取哈希值,而该哈希值的作用是用来确定对象在哈希表中的索引位置。”我说。
+
+哈希表的典型代表就是 HashMap,它存储的是键值对,能根据键快速地检索出对应的值。
+
+```java
+public V get(Object key) {
+ HashMap.Node e;
+ return (e = getNode(hash(key), key)) == null ? null : e.value;
+}
+```
+
+这是 HashMap 的 get 方法,通过键来获取值的方法。它会调用 getNode 方法:
+
+```java
+final HashMap.Node getNode(int hash, Object key) {
+ HashMap.Node[] tab; HashMap.Node first, e; int n; K k;
+ if ((tab = table) != null && (n = tab.length) > 0 &&
+ (first = tab[(n - 1) & hash]) != null) {
+ if (first.hash == hash && // always check first node
+ ((k = first.key) == key || (key != null && key.equals(k))))
+ return first;
+ if ((e = first.next) != null) {
+ if (first instanceof HashMap.TreeNode)
+ return ((HashMap.TreeNode)first).getTreeNode(hash, key);
+ do {
+ if (e.hash == hash &&
+ ((k = e.key) == key || (key != null && key.equals(k))))
+ return e;
+ } while ((e = e.next) != null);
+ }
+ }
+ return null;
+}
+```
+
+通常情况(没有发生哈希冲突)下,`first = tab[(n - 1) & hash]` 就是键对应的值。**按照时间复杂度来说的话,可表示为 O(1)**。
+
+如果发生哈希冲突,也就是 `if ((e = first.next) != null) {}` 子句中,可以看到如果节点不是红黑树的时候,会通过 do-while 循环语句判断键是否 equals 返回对应值的。**按照时间复杂度来说的话,可表示为 O(n)**。
+
+HashMap 是通过拉链法来解决哈希冲突的,也就是如果发生哈希冲突,同一个键的坑位会放好多个值,超过 8 个值后改为红黑树,为了提高查询的效率。
+
+显然,从时间复杂度上来看的话 O(n) 比 O(1) 的性能要差,这也正是哈希表的价值所在。
+
+“O(n) 和 O(1) 是什么呀?”三妹有些不解。
+
+“这是时间复杂度的一种表示方法,随后二哥专门给你讲一下。简单说一下 n 和 1 的意思,很显然,n 和 1 都代表的是代码执行的次数,假如数据规模为 n,n 就代表需要执行 n 次,1 就代表只需要执行一次。”我解释道。
+
+“三妹,你想一下,如果没有哈希表,但又需要这样一个数据结构,它里面存放的数据是不允许重复的,该怎么办呢?”我问。
+
+“要不使用 equals 方法进行逐个比较?”三妹有些不太确定。
+
+“这种方法当然是可行的,就像 `if ((e = first.next) != null) {}` 子句中那样,但如果数据量特别特别大,性能就会很差,最好的解决方案还是 HashMap。”
+
+HashMap 本质上是通过数组实现的,当我们要从 HashMap 中获取某个值时,实际上是要获取数组中某个位置的元素,而位置是通过键来确定的。
+
+```java
+public V put(K key, V value) {
+ return putVal(hash(key), key, value, false, true);
+}
+```
+
+这是 HashMap 的 put 方法,会将键值对放入到数组当中。它会调用 putVal 方法:
+
+```java
+final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
+ boolean evict) {
+ HashMap.Node[] tab; HashMap.Node p; int n, i;
+ if ((tab = table) == null || (n = tab.length) == 0)
+ n = (tab = resize()).length;
+ if ((p = tab[i = (n - 1) & hash]) == null)
+ tab[i] = newNode(hash, key, value, null);
+ else {
+ // 拉链
+ }
+ return null;
+}
+```
+
+通常情况下,`p = tab[i = (n - 1) & hash])` 就是键对应的值。而数组的索引 `(n - 1) & hash` 正是基于 hashCode 方法计算得到的。
+
+```java
+static final int hash(Object key) {
+ int h;
+ return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
+}
+```
+
+“那二哥,你好像还是没有说为什么重写 equals 方法的时候要重写 hashCode 方法呀?”三妹忍不住了。
+
+“来看下面这段代码。”我说。
+
+```java
+public class Test {
+ public static void main(String[] args) {
+ Student s1 = new Student(18, "张三");
+ Map scores = new HashMap<>();
+ scores.put(s1, 98);
+
+ Student s2 = new Student(18, "张三");
+ System.out.println(scores.get(s2));
+ }
+}
+ class Student {
+ private int age;
+ private String name;
+
+ public Student(int age, String name) {
+ this.age = age;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ Student student = (Student) o;
+ return age == student.age &&
+ Objects.equals(name, student.name);
+ }
+ }
+```
+
+我们重写了 Student 类的 equals 方法,如果两个学生的年纪和姓名相同,我们就认为是同一个学生,虽然很离谱,但我们就是这么草率。
+
+在 main 方法中,18 岁的张三考试得了 98 分,很不错的成绩,我们把张三和他的成绩放到 HashMap 中,然后准备取出:
+
+```
+null
+```
+
+“二哥,怎么输出了 null,而不是预期当中的 98 呢?”三妹感到很不可思议。
+
+“原因就在于重写 equals 方法的时候没有重写 hashCode 方法。”我回答道,“equals 方法虽然认定名字和年纪相同就是同一个学生,但它们本质上是两个对象,hashCode 并不相同。”
+
+
+
+“那怎么重写 hashCode 方法呢?”三妹问。
+
+“可以直接调用 Objects 类的 hash 方法。”我回答。
+
+```java
+ @Override
+ public int hashCode() {
+ return Objects.hash(age, name);
+ }
+```
+
+Objects 类的 hash 方法可以针对不同数量的参数生成新的哈希值,hash 方法调用的是 Arrays 类的 hashCode 方法,该方法源码如下:
+
+```java
+public static int hashCode(Object a[]) {
+ if (a == null)
+ return 0;
+
+ int result = 1;
+
+ for (Object element : a)
+ result = 31 * result + (element == null ? 0 : element.hashCode());
+
+ return result;
+}
+```
+
+第一次循环:
+
+```
+result = 31*1 + Integer(18).hashCode();
+```
+
+第二次循环:
+
+```
+result = (31*1 + Integer(18).hashCode()) * 31 + String("张三").hashCode();
+```
+
+针对姓名年纪不同的对象,这样计算后的哈希值很难很难很难重复的;针对姓名年纪相同的对象,哈希值保持一致。
+
+再次执行 main 方法,结果如下所示:
+
+```
+98
+```
+
+因为此时 s1 和 s2 对象的哈希值都为 776408。
+
+
+
+
+“每当重写 equals 方法时,hashCode 方法也需要重写,原因就是为了保证:如果两个对象调用 equals 方法返回的结果为 true,那么两个对象调用 hashCode 方法返回的结果也必然相同。”我点题了。
+
+“OK,get 了。”三妹开心地点了点头,看得出来,今天学到了不少。
+
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
\ No newline at end of file
diff --git a/docs/basic-extra-meal/fanshe.md b/docs/basic-extra-meal/fanshe.md
new file mode 100644
index 0000000000..d46a9126e4
--- /dev/null
+++ b/docs/basic-extra-meal/fanshe.md
@@ -0,0 +1,335 @@
+---
+title: 大白话说清楚Java反射:入门、使用、原理
+shortTitle: Java反射:入门、使用、原理
+category:
+ - Java核心
+tag:
+ - Java重要知识点
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,大白话说清楚Java反射:入门、使用、原理
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,反射
+---
+
+“二哥,什么是反射呀?”三妹开门见山地问。
+
+“要想知道什么是反射,就需要先来了解什么是‘正射’。”我笑着对三妹说,“一般情况下,我们在使用某个类之前已经确定它到底是个什么类了,拿到手就直接可以使用 `new` 关键字来调用构造方法进行初始化,之后使用这个类的对象来进行操作。”
+
+```java
+Writer writer = new Writer();
+writer.setName("沉默王二");
+```
+
+像上面这个例子,就可以理解为“正射”。而反射就意味着一开始我们不知道要初始化的类到底是什么,也就没法直接使用 `new` 关键字创建对象了。
+
+我们只知道这个类的一些基本信息,就好像我们看电影的时候,为了抓住一个犯罪嫌疑人,警察就会问一些目击证人,根据这些证人提供的信息,找专家把犯罪嫌疑人的样貌给画出来——这个过程,就可以称之为**反射**。
+
+```java
+Class clazz = Class.forName("com.itwanger.s39.Writer");
+Method method = clazz.getMethod("setName", String.class);
+Constructor constructor = clazz.getConstructor();
+Object object = constructor.newInstance();
+method.invoke(object,"沉默王二");
+```
+
+像上面这个例子,就可以理解为“反射”。
+
+“反射的写法比正射复杂得多啊!”三妹感慨地说。
+
+“是的,反射的成本是要比正射的高得多。”我说,“反射的缺点主要有两个。”
+
+- **破坏封装**:由于反射允许访问私有字段和私有方法,所以可能会破坏封装而导致安全问题。
+- **性能开销**:由于反射涉及到动态解析,因此无法执行 Java 虚拟机优化,再加上反射的写法的确要复杂得多,所以性能要比“正射”差很多,在一些性能敏感的程序中应该避免使用反射。
+
+“那反射有哪些好处呢?”三妹问。
+
+反射的主要应用场景有:
+
+- **开发通用框架**:像 Spring,为了保持通用性,通过配置文件来加载不同的对象,调用不同的方法。
+- **动态代理**:在面向切面编程中,需要拦截特定的方法,就会选择动态代理的方式,而动态代理的底层技术就是反射。
+- **注解**:注解本身只是起到一个标记符的作用,它需要利用发射机制,根据标记符去执行特定的行为。
+
+“好了,来看一下完整的例子吧。”我对三妹说。
+
+Writer 类,有两个字段,然后还有对应的 getter/setter。
+
+```java
+public class Writer {
+ private int age;
+ private String name;
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+```
+
+测试类:
+
+```java
+public class ReflectionDemo1 {
+ public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+ Writer writer = new Writer();
+ writer.setName("沉默王二");
+ System.out.println(writer.getName());
+
+ Class clazz = Class.forName("com.itwanger.s39.Writer");
+ Constructor constructor = clazz.getConstructor();
+ Object object = constructor.newInstance();
+
+ Method setNameMethod = clazz.getMethod("setName", String.class);
+ setNameMethod.invoke(object, "沉默王二");
+ Method getNameMethod = clazz.getMethod("getName");
+ System.out.println(getNameMethod.invoke(object));
+ }
+}
+```
+
+来看一下输出结果:
+
+```
+沉默王二
+沉默王二
+```
+
+只不过,反射的过程略显曲折了一些。
+
+第一步,获取反射类的 Class 对象:
+
+```java
+Class clazz = Class.forName("com.itwanger.s39.Writer");
+```
+
+第二步,通过 Class 对象获取构造方法 Constructor 对象:
+
+```java
+Constructor constructor = clazz.getConstructor();
+```
+
+第三步,通过 Constructor 对象初始化反射类对象:
+
+```java
+Object object = constructor.newInstance();
+```
+
+第四步,获取要调用的方法的 Method 对象:
+
+```java
+Method setNameMethod = clazz.getMethod("setName", String.class);
+Method getNameMethod = clazz.getMethod("getName");
+```
+
+第五步,通过 `invoke()` 方法执行:
+
+```java
+setNameMethod.invoke(object, "沉默王二");
+getNameMethod.invoke(object)
+```
+
+“三妹,你看,经过这五个步骤,基本上就掌握了反射的使用方法。”我说。
+
+“好像反射也没什么复杂的啊!”三妹说。
+
+我先对三妹点点头,然后说:“是的,掌握反射的基本使用方法确实不难,但要理解整个反射机制还是需要花一点时间去了解一下 Java 虚拟机的类加载机制的。”
+
+要想使用反射,首先需要获得反射类的 Class 对象,每一个类,不管它最终生成了多少个对象,这些对象只会对应一个 Class 对象,这个 Class 对象是由 Java 虚拟机生成的,由它来获悉整个类的结构信息。
+
+也就是说,`java.lang.Class` 是所有反射 API 的入口。
+
+而方法的反射调用,最终是由 Method 对象的 `invoke()` 方法完成的,来看一下源码(JDK 8 环境下)。
+
+```java
+@CallerSensitive
+public Object invoke(Object obj, Object... args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException
+{
+ if (!override) {
+ if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
+ Class> caller = Reflection.getCallerClass();
+ checkAccess(caller, clazz, obj, modifiers);
+ }
+ }
+ MethodAccessor ma = methodAccessor; // read volatile
+ if (ma == null) {
+ ma = acquireMethodAccessor();
+ }
+ return ma.invoke(obj, args);
+}
+```
+
+两个嵌套的 if 语句是用来进行权限检查的。
+
+`invoke()` 方法实际上是委派给 MethodAccessor 接口来完成的。
+
+
+
+MethodAccessor 接口有三个实现类,其中的 MethodAccessorImpl 是一个抽象类,另外两个具体的实现类继承了这个抽象类。
+
+
+
+- NativeMethodAccessorImpl:通过本地方法来实现反射调用;
+- DelegatingMethodAccessorImpl:通过委派模式来实现反射调用;
+
+通过 debug 的方式进入 `invoke()` 方法后,可以看到第一次反射调用会生成一个委派实现 DelegatingMethodAccessorImpl,它在生成的时候会传递一个本地实现 NativeMethodAccessorImpl。
+
+
+
+也就是说,`invoke()` 方法在执行的时候,会先调用 DelegatingMethodAccessorImpl,然后调用 NativeMethodAccessorImpl,最后再调用实际的方法。
+
+“为什么不直接调用本地实现呢?”三妹问。
+
+“之所以采用委派实现,是为了能够在本地实现和动态实现之间切换。动态实现是另外一种反射调用机制,它是通过生成字节码的形式来实现的。如果反射调用的次数比较多,动态实现的效率就会更高,因为本地实现需要经过 Java 到 C/C++ 再到 Java 之间的切换过程,而动态实现不需要;但如果反射调用的次数比较少,反而本地实现更快一些。”我说。
+
+“那临界点是多少呢?”三妹问。
+
+“默认是 15 次。”我说,“可以通过 `-Dsun.reflect.inflationThreshold` 参数类调整。”
+
+来看下面这个例子。
+
+```java
+Method setAgeMethod = clazz.getMethod("setAge", int.class);
+for (int i = 0;i < 20; i++) {
+ setAgeMethod.invoke(object, 18);
+}
+```
+
+在 `invoke()` 方法处加断点进入 debug 模式,当 i = 15 的时候,也就是第 16 次执行的时候,会进入到 if 条件分支中,改变 DelegatingMethodAccessorImpl 的委派模式 delegate 为 `(MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod()`,而之前的委派模式 delegate 为 NativeMethodAccessorImpl。
+
+
+
+“这下明白了吧?三妹。”我说,“接下来,我们再来熟悉一下反射当中常用的 API。”
+
+**1)获取反射类的 Class 对象**
+
+`Class.forName()`,参数为反射类的完全限定名。
+
+```java
+Class c1 = Class.forName("com.itwanger.s39.ReflectionDemo3");
+System.out.println(c1.getCanonicalName());
+
+Class c2 = Class.forName("[D");
+System.out.println(c2.getCanonicalName());
+
+Class c3 = Class.forName("[[Ljava.lang.String;");
+System.out.println(c3.getCanonicalName());
+```
+
+来看一下输出结果:
+
+```
+com.itwanger.s39.ReflectionDemo3
+double[]
+java.lang.String[][]
+```
+
+类名 + `.class`,只适合在编译前就知道操作的 Class。。
+
+```java
+Class c1 = ReflectionDemo3.class;
+System.out.println(c1.getCanonicalName());
+
+Class c2 = String.class;
+System.out.println(c2.getCanonicalName());
+
+Class c3 = int[][][].class;
+System.out.println(c3.getCanonicalName());
+```
+
+来看一下输出结果:
+
+```java
+com.itwanger.s39.ReflectionDemo3
+java.lang.String
+int[][][]
+```
+
+**2)创建反射类的对象**
+
+通过反射来创建对象的方式有两种:
+
+- 用 Class 对象的 `newInstance()` 方法。
+- 用 Constructor 对象的 `newInstance()` 方法。
+
+```java
+Class c1 = Writer.class;
+Writer writer = (Writer) c1.newInstance();
+
+Class c2 = Class.forName("com.itwanger.s39.Writer");
+Constructor constructor = c2.getConstructor();
+Object object = constructor.newInstance();
+```
+
+**3)获取构造方法**
+
+Class 对象提供了以下方法来获取构造方法 Constructor 对象:
+
+- `getConstructor()`:返回反射类的特定 public 构造方法,可以传递参数,参数为构造方法参数对应 Class 对象;缺省的时候返回默认构造方法。
+- `getDeclaredConstructor()`:返回反射类的特定构造方法,不限定于 public 的。
+- `getConstructors()`:返回类的所有 public 构造方法。
+- `getDeclaredConstructors()`:返回类的所有构造方法,不限定于 public 的。
+
+```java
+Class c2 = Class.forName("com.itwanger.s39.Writer");
+Constructor constructor = c2.getConstructor();
+
+Constructor[] constructors1 = String.class.getDeclaredConstructors();
+for (Constructor c : constructors1) {
+ System.out.println(c);
+}
+```
+
+**4)获取字段**
+
+大体上和获取构造方法类似,把关键字 Constructor 换成 Field 即可。
+
+```java
+Method setNameMethod = clazz.getMethod("setName", String.class);
+Method getNameMethod = clazz.getMethod("getName");
+```
+
+**5)获取方法**
+
+大体上和获取构造方法类似,把关键字 Constructor 换成 Method 即可。
+
+```java
+Method[] methods1 = System.class.getDeclaredMethods();
+Method[] methods2 = System.class.getMethods();
+```
+
+“注意,三妹,如果你想反射访问私有字段和(构造)方法的话,需要使用 `Constructor/Field/Method.setAccessible(true)` 来绕开 Java 语言的访问限制。”我说。
+
+“好的,二哥。还有资料可以参考吗?”三妹问。
+
+“有的,有两篇文章写得非常不错,你在学习反射的时候可以作为参考。”我说。
+
+第一篇:深入理解 Java 反射和动态代理
+
+>链接:[https://dunwu.github.io/javacore/basics/java-reflection.html](https://dunwu.github.io/javacore/basics/java-reflection.html)
+
+第二篇:大白话说Java反射:入门、使用、原理:
+
+>链接:[https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html](https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html)
+
+
+----
+
+最近整理了一份牛逼的学习资料,包括但不限于Java基础部分(JVM、Java集合框架、多线程),还囊括了 **数据库、计算机网络、算法与数据结构、设计模式、框架类Spring、Netty、微服务(Dubbo,消息队列) 网关** 等等等等……详情戳:[可以说是2022年全网最全的学习和找工作的PDF资源了](https://tobebetterjavaer.com/pdf/programmer-111.html)
+
+微信搜 **沉默王二** 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 **111** 即可免费领取。
+
+
+
diff --git a/docs/basic-extra-meal/generic.md b/docs/basic-extra-meal/generic.md
new file mode 100644
index 0000000000..49ec722002
--- /dev/null
+++ b/docs/basic-extra-meal/generic.md
@@ -0,0 +1,622 @@
+---
+title: 深入理解Java中的泛型
+shortTitle: 泛型
+category:
+ - Java核心
+tag:
+ - Java重要知识点
+description: Java程序员进阶之路,小白的零基础Java教程,从入门到进阶,深入理解Java中的泛型
+head:
+ - - meta
+ - name: keywords
+ content: Java,Java SE,Java基础,Java教程,Java程序员进阶之路,Java入门,教程,java,泛型,java 泛型,java generic
+---
+
+# 6.6 泛型
+
+“二哥,为什么要设计泛型啊?”三妹开门见山地问。
+
+“三妹啊,听哥慢慢给你讲啊。”我说。
+
+Java 在 1.5 时增加了泛型机制,据说专家们为此花费了 5 年左右的时间(听起来是相当不容易)。有了泛型之后,尤其是对集合类的使用,就变得更规范了。
+
+看下面这段简单的代码。
+
+```java
+ArrayList list = new ArrayList();
+list.add("沉默王二");
+String str = list.get(0);
+```
+
+“三妹,你能想象到在没有泛型之前该怎么办吗?”
+
+“嗯,想不到,还是二哥你说吧。”
+
+嗯,我们可以使用 Object 数组来设计 `Arraylist` 类。
+
+```java
+class Arraylist {
+ private Object[] objs;
+ private int i = 0;
+ public void add(Object obj) {
+ objs[i++] = obj;
+ }
+
+ public Object get(int i) {
+ return objs[i];
+ }
+}
+```
+
+然后,我们向 `Arraylist` 中存取数据。
+
+```java
+Arraylist list = new Arraylist();
+list.add("沉默王二");
+list.add(new Date());
+String str = (String)list.get(0);
+```
+
+“三妹,你有没有发现这两个问题?”
+
+- Arraylist 可以存放任何类型的数据(既可以存字符串,也可以混入日期),因为所有类都继承自 Object 类。
+- 从 Arraylist 取出数据的时候需要强制类型转换,因为编译器并不能确定你取的是字符串还是日期。
+
+“嗯嗯,是的呢。”三妹说。
+
+对比一下,你就能明显地感受到泛型的优秀之处:使用**类型参数**解决了元素的不确定性——参数类型为 String 的集合中是不允许存放其他类型元素的,取出数据的时候也不需要强制类型转换了。
+
+### 动手设计一个泛型
+
+“二哥,那怎么才能设计一个泛型呢?”
+
+“三妹啊,你一个小白只要会用泛型就行了,还想设计泛型啊?!不过,既然你想了解,哥义不容辞。”
+
+首先,我们来按照泛型的标准重新设计一下 `Arraylist` 类。
+
+```java
+class Arraylist {
+ private Object[] elementData;
+ private int size = 0;
+
+ public Arraylist(int initialCapacity) {
+ this.elementData = new Object[initialCapacity];
+ }
+
+ public boolean add(E e) {
+ elementData[size++] = e;
+ return true;
+ }
+
+ E elementData(int index) {
+ return (E) elementData[index];
+ }
+}
+```
+
+一个泛型类就是具有一个或多个类型变量的类。Arraylist 类引入的类型变量为 E(Element,元素的首字母),使用尖括号 `<>` 括起来,放在类名的后面。
+
+然后,我们可以用具体的类型(比如字符串)替换类型变量来实例化泛型类。
+
+```java
+Arraylist list = new Arraylist();
+list.add("沉默王三");
+String str = list.get(0);
+```
+
+Date 类型也可以的。
+
+```java
+Arraylist list = new Arraylist();
+list.add(new Date());
+Date date = list.get(0);
+```
+
+其次,我们还可以在一个非泛型的类(或者泛型类)中定义泛型方法。
+
+```java
+class Arraylist {
+ public T[] toArray(T[] a) {
+ return (T[]) Arrays.copyOf(elementData, size, a.getClass());
+ }
+}
+```
+
+不过,说实话,泛型方法的定义看起来略显晦涩。来一副图吧(注意:方法返回类型和方法参数类型至少需要一个)。
+
+
+
+现在,我们来调用一下泛型方法。
+
+```java
+Arraylist list = new Arraylist<>(4);
+list.add("沉");
+list.add("默");
+list.add("王");
+list.add("二");
+
+String [] strs = new String [4];
+strs = list.toArray(strs);
+
+for (String str : strs) {
+ System.out.println(str);
+}
+```
+
+### 泛型限定符
+
+然后,我们再来说说泛型变量的限定符 `extends`。
+
+在解释这个限定符之前,我们假设有三个类,它们之间的定义是这样的。
+
+```java
+class Wanglaoer {
+ public String toString() {
+ return "王老二";
+ }
+}
+
+class Wanger extends Wanglaoer{
+ public String toString() {
+ return "王二";
+ }
+}
+
+class Wangxiaoer extends Wanger{
+ public String toString() {
+ return "王小二";
+ }
+}
+```
+
+我们使用限定符 `extends` 来重新设计一下 `Arraylist` 类。
+
+```java
+class Arraylist {
+}
+```
+
+当我们向 `Arraylist` 中添加 `Wanglaoer` 元素的时候,编译器会提示错误:`Arraylist` 只允许添加 `Wanger` 及其子类 `Wangxiaoer` 对象,不允许添加其父类 `Wanglaoer`。
+
+```java
+Arraylist list = new Arraylist<>(3);
+list.add(new Wanger());
+list.add(new Wanglaoer());
+// The method add(Wanger) in the type Arraylist is not applicable for the arguments
+// (Wanglaoer)
+list.add(new Wangxiaoer());
+```
+
+也就是说,限定符 `extends` 可以缩小泛型的类型范围。
+
+### 类型擦除
+
+“哦,明白了。”三妹若有所思的点点头,“二哥,听说虚拟机没有泛型?”
+
+“三妹,你功课做得可以啊。哥可以肯定地回答你,虚拟机是没有泛型的。”
+
+“怎么确定虚拟机有没有泛型呢?”三妹问。
+
+“只要我们把泛型类的字节码进行反编译就看到了!”用反编译工具(我写这篇文章的时候用的是 jad,你也可以用其他的工具)将 class 文件反编译后,我说,“三妹,你看。”
+
+```java
+// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3)
+// Source File Name: Arraylist.java
+
+package com.cmower.java_demo.fanxing;
+
+import java.util.Arrays;
+
+class Arraylist
+{
+
+ public Arraylist(int initialCapacity)
+ {
+ size = 0;
+ elementData = new Object[initialCapacity];
+ }
+
+ public boolean add(Object e)
+ {
+ elementData[size++] = e;
+ return true;
+ }
+
+ Object elementData(int index)
+ {
+ return elementData[index];
+ }
+
+ private Object elementData[];
+ private int size;
+}
+```
+
+类型变量 `` 消失了,取而代之的是 Object !
+
+“既然如此,那如果泛型类使用了限定符 `extends`,结果会怎么样呢?”三妹这个问题问的很巧妙。
+
+来看这段代码。
+
+```java
+class Arraylist2 {
+ private Object[] elementData;
+ private int size = 0;
+
+ public Arraylist2(int initialCapacity) {
+ this.elementData = new Object[initialCapacity];
+ }
+
+ public boolean add(E e) {
+ elementData[size++] = e;
+ return true;
+ }
+
+ E elementData(int index) {
+ return (E) elementData[index];
+ }
+}
+```
+
+反编译后的结果如下。
+
+```java
+// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3)
+// Source File Name: Arraylist2.java
+
+package com.cmower.java_demo.fanxing;
+
+
+// Referenced classes of package com.cmower.java_demo.fanxing:
+// Wanger
+
+class Arraylist2
+{
+
+ public Arraylist2(int initialCapacity)
+ {
+ size = 0;
+ elementData = new Object[initialCapacity];
+ }
+
+ public boolean add(Wanger e)
+ {
+ elementData[size++] = e;
+ return true;
+ }
+
+ Wanger elementData(int index)
+ {
+ return (Wanger)elementData[index];
+ }
+
+ private Object elementData[];
+ private int size;
+}
+```
+
+“你看,类型变量 `` 不见了,E 被替换成了 `Wanger`”,我说,“通过以上两个例子说明,Java 虚拟机会将泛型的类型变量擦除,并替换为限定类型(没有限定的话,就用 `Object`)”
+
+“二哥,类型擦除会有什么问题吗?”三妹又问了一个很有水平的问题。
+
+“三妹啊,你还别说,类型擦除真的会有一些问题。”我说,“来看一下这段代码。”
+
+```java
+public class Cmower {
+
+ public static void method(Arraylist list) {
+ System.out.println("Arraylist list");
+ }
+
+ public static void method(Arraylist list) {
+ System.out.println("Arraylist list");
+ }
+
+}
+```
+
+在浅层的意识上,我们会想当然地认为 `Arraylist list` 和 `Arraylist list` 是两种不同的类型,因为 String 和 Date 是不同的类。
+
+但由于类型擦除的原因,以上代码是不会通过编译的——编译器会提示一个错误(这正是类型擦除引发的那些“问题”):
+
+```
+>Erasure of method method(Arraylist) is the same as another method in type
+ Cmower
+>
+>Erasure of method method(Arraylist) is the same as another method in type
+ Cmower
+```
+
+
+大致的意思就是,这两个方法的参数类型在擦除后是相同的。
+
+也就是说,`method(Arraylist list)` 和 `method(Arraylist list)` 是同一种参数类型的方法,不能同时存在。类型变量 `String` 和 `Date` 在擦除后会自动消失,method 方法的实际参数是 `Arraylist list`。
+
+有句俗话叫做:“百闻不如一见”,但即使见到了也未必为真——泛型的擦除问题就可以很好地佐证这个观点。
+
+### 泛型通配符
+
+“哦,明白了。二哥,听说泛型还有通配符?”
+
+“三妹啊,哥突然觉得你很适合作一枚可爱的程序媛啊!你这预习的功课做得可真到家啊,连通配符都知道!”
+
+通配符使用英文的问号`(?)`来表示。在我们创建一个泛型对象时,可以使用关键字 `extends` 限定子类,也可以使用关键字 `super` 限定父类。
+
+我们来看下面这段代码。
+
+```java
+// 定义一个泛型类 Arraylist,E 表示元素类型
+class Arraylist {
+ // 私有成员变量,存储元素数组和元素数量
+ private Object[] elementData;
+ private int size = 0;
+
+ // 构造函数,传入初始容量 initialCapacity,创建一个指定容量的 Object 数组
+ public Arraylist(int initialCapacity) {
+ this.elementData = new Object[initialCapacity];
+ }
+
+ // 添加元素到数组末尾,返回添加成功与否
+ public boolean add(E e) {
+ elementData[size++] = e;
+ return true;
+ }
+
+ // 获取指定下标的元素
+ public E get(int index) {
+ return (E) elementData[index];
+ }
+
+ // 查找指定元素第一次出现的下标,如果找不到则返回 -1
+ public int indexOf(Object o) {
+ if (o == null) {
+ for (int i = 0; i < size; i++)
+ if (elementData[i]==null)
+ return i;
+ } else {
+ for (int i = 0; i < size; i++)
+ if (o.equals(elementData[i]))
+ return i;
+ }
+ return -1;
+ }
+
+ // 判断指定元素是否在数组中出现
+ public boolean contains(Object o) {
+ return indexOf(o) >= 0;
+ }
+
+ // 将数组中的元素转化成字符串输出
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ for (Object o : elementData) {
+ if (o != null) {
+ E e = (E)o;
+ sb.append(e.toString());
+ sb.append(',').append(' ');
+ }
+ }
+ return sb.toString();
+ }
+
+ // 返回数组中元素的数量
+ public int size() {
+ return size;
+ }
+
+ // 修改指定下标的元素,返回修改前的元素
+ public E set(int index, E element) {
+ E oldValue = (E) elementData[index];
+ elementData[index] = element;
+ return oldValue;
+ }
+}
+```
+
+1)新增 `indexOf(Object o)` 方法,判断元素在 `Arraylist` 中的位置。注意参数为 `Object` 而不是泛型 `E`。
+
+2)新增 `contains(Object o)` 方法,判断元素是否在 `Arraylist` 中。注意参数为 `Object` 而不是泛型 `E`。
+
+3)新增 `toString()` 方法,方便对 `Arraylist` 进行打印。
+
+4)新增 `set(int index, E element)` 方法,方便对 `Arraylist` 元素的更改。
+
+因为泛型擦除的原因,`Arraylist list = new Arraylist();` 这样的语句是无法通过编译的,尽管 Wangxiaoer 是 Wanger 的子类。但如果我们确实需要这种 “向上转型” 的关系,该怎么办呢?这时候就需要通配符来发挥作用了。
+
+利用 ` extends Wanger>` 形式的通配符,可以实现泛型的向上转型,来看例子。
+
+```java
+Arraylist extends Wanger> list2 = new Arraylist<>(4);
+list2.add(null);
+// list2.add(new Wanger());
+// list2.add(new Wangxiaoer());
+
+Wanger w2 = list2.get(0);
+// Wangxiaoer w3 = list2.get(1);
+```
+
+list2 的类型是 `Arraylist extends Wanger>`,翻译一下就是,list2 是一个 `Arraylist`,其类型是 `Wanger` 及其子类。
+
+注意,“关键”来了!list2 并不允许通过 `add(E e)` 方法向其添加 `Wanger` 或者 `Wangxiaoer` 的对象,唯一例外的是 `null`。
+
+“那就奇了怪了,既然不让存放元素,那要 `Arraylist extends Wanger>` 这样的 list2 有什么用呢?”三妹好奇地问。
+
+虽然不能通过 `add(E e)` 方法往 list2 中添加元素,但可以给它赋值。
+
+```java
+Arraylist list = new Arraylist<>(4);
+
+Wanger wanger = new Wanger();
+list.add(wanger);
+
+Wangxiaoer wangxiaoer = new Wangxiaoer();
+list.add(wangxiaoer);
+
+Arraylist extends Wanger> list2 = list;
+
+Wanger w2 = list2.get(1);
+System.out.println(w2);
+
+System.out.println(list2.indexOf(wanger));
+System.out.println(list2.contains(new Wangxiaoer()));
+```
+
+`Arraylist extends Wanger> list2 = list;` 语句把 list 的值赋予了 list2,此时 `list2 == list`。由于 list2 不允许往其添加其他元素,所以此时它是安全的——我们可以从容地对 list2 进行 `get()`、`indexOf()` 和 `contains()`。想一想,如果可以向 list2 添加元素的话,这 3 个方法反而变得不太安全,它们的值可能就会变。
+
+利用 ` super Wanger>` 形式的通配符,可以向 Arraylist 中存入父类是 `Wanger` 的元素,来看例子。
+
+```java
+Arraylist super Wanger> list3 = new Arraylist<>(4);
+list3.add(new Wanger());
+list3.add(new Wangxiaoer());
+
+// Wanger w3 = list3.get(0);
+```
+
+需要注意的是,无法从 `Arraylist super Wanger>` 这样类型的 list3 中取出数据。
+
+### 小结
+
+好了,三妹,关于泛型,我们再来做一个简单的总结。
+
+在 Java 中,泛型是一种强类型约束机制,可以在编译期间检查类型安全性,并且可以提高代码的复用性和可读性。
+
+#### 1)类型参数化
+
+泛型的本质是参数化类型,也就是说,在定义类、接口或方法时,可以使用一个或多个类型参数来表示参数化类型。
+
+例如这样可以定义一个泛型类。
+
+```java
+public class Box {
+ private T value;
+
+ public Box(T value) {
+ this.value = value;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+}
+```
+
+在这个例子中,`` 表示类型参数,可以在类中任何需要使用类型的地方使用 T 代替具体的类型。通过使用泛型,我们可以创建一个可以存储任何类型对象的盒子。
+
+```java
+Box intBox = new Box<>(123);
+Box strBox = new Box<>("Hello, world!");
+```
+
+泛型在实际开发中的应用非常广泛,例如集合框架中的 List、Set、Map 等容器类,以及并发框架中的 Future、Callable 等工具类都使用了泛型。
+
+#### 2)类型擦除
+
+在 Java 的泛型机制中,有两个重要的概念:类型擦除和通配符。
+
+泛型在编译时会将泛型类型擦除,将泛型类型替换成 Object 类型。这是为了向后兼容,避免对原有的 Java 代码造成影响。
+
+例如,对于下面的代码:
+
+```java
+List intList = new ArrayList<>();
+intList.add(123);
+int value = intList.get(0);
+```
+
+在编译时,Java 编译器会将泛型类型 `List` 替换成 `List