Skip to content

Commit a0280ea

Browse files
committed
simple update
1 parent cf18ca9 commit a0280ea

File tree

14 files changed

+361
-5
lines changed

14 files changed

+361
-5
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
node_modules
2-
dist
2+
.vitepress/dist
3+
.vitepress/cache
4+
5+
# macOS
6+
.DS_Store

.vitepress/config.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,49 @@
1-
export default {
1+
import { defineConfig } from 'vitepress'
2+
3+
export default defineConfig ({
4+
// 网站元数据
5+
// 网站的lang属性
6+
lang: 'zh-CN',
7+
// 显示在浏览器标签栏里的内容
8+
title: '屠伟伟的博客空间',
9+
// 显示在浏览器标签栏里的后缀,false表示不启用后缀
10+
titleTemplate: false,
11+
// 这将在页面HTML中呈现为<meta>标签
12+
description: '人生,不过是一场体验。',
13+
// 如果您计划将站点部署到https://foo.github.io/bar/,那么您应该将base设置为'/bar/'。它应该总是以斜杠开头和结尾。
14+
base: '/blog/',
15+
16+
// 网站路由配置
17+
// 当设置为true,VitePress将从URL中删除尾随的.html,需要服务器支持
18+
cleanUrls: true,
19+
// 定义自定义目录<-> URL映射
20+
rewrites: {
21+
'source/:page': 'destination/:page'
22+
},
23+
24+
// 网站build设置
25+
// The directory where your markdown pages are stored, relative to project root
226
srcDir: './src',
3-
base: '/blog/'
4-
}
27+
// srcExclude: ['', ''],
28+
outDir: './.vitepress/dist',
29+
cacheDir: './.vitepress/cache',
30+
// VitePress 不会因死链接而构建失败
31+
ignoreDeadLinks: true,
32+
33+
// 网站主题配置
34+
// 根据系统自动决定是否使用dark模式
35+
appearance: true,
36+
// 获取每个页面的最后更新时间
37+
lastUpdated: true,
38+
// 使用VitePress的默认主题作为主题配置
39+
themeConfig: {
40+
41+
},
42+
43+
// 自定义配置
44+
// markdown 相关配置
45+
// markdown: {
46+
// // 在代码块中启用行号
47+
// lineNumbers: true,
48+
// },
49+
})

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "",
55
"main": "index.js",
66
"scripts": {
7-
"dev": "vitepress",
7+
"dev": "vitepress dev",
88
"build": "vitepress build",
99
"preview": "vitepress preview",
1010
"serve": "vitepress serve",

src/Android/self_study_path.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Google Android Developer 自学方案
2+
3+
4+
5+
#### 1. Kotlin 基础
6+
7+
- 面向编程人员的 Kotlin 训练营 [Kotlin Basic](https://developer.android.com/courses/kotlin-bootcamp/overview?hl=zh-cn)
8+
9+
> 在“面向编程人员的 Kotlin 训练营”课程中,您将学习 Kotlin 的基础知识,并使用 IntelliJ IDEA 创建各种小程序。
10+
11+
12+
13+
- Udacity的免费课程 [Kotlin Bootcamp for Programmers](https://www.udacity.com/course/kotlin-bootcamp-for-programmers--ud9011)
14+
15+
> 向 Google 的 Kotlin 专家学习 Kotlin 编程语言的基础知识。 Kotlin 是一种现代、简洁的 JVM 语言,支持函数式编程范例。无论您是 Java 开发人员还是其他面向对象语言的程序员,本课程都将教您基本的语言功能,这些功能使 Kotlin 如此受开发人员欢迎。在本课程结束时,您将获得使用 Kotlin 构建下一个项目所需的技能。
16+
17+
18+
19+
#### 2. 基于Kotlin的Android基础
20+
21+
- [Android Kotlin Fundamentals](https://developer.android.com/codelabs/kotlin-android-training-welcome?index=..%2F..android-kotlin-fundamentals#0)
22+
23+
> 欢迎来到由 Google 开发者培训团队创建的 Android Kotlin 基础知识课程。本课程提供了一系列代码实验室,引导您了解使用 Kotlin 构建 Android 应用程序的基础知识。在本课程中,您将学习基本的 Android Kotlin 编程概念并构建各种应用程序。
24+
25+
26+
27+
- Udacity的免费课程 [Developing Android Apps with Kotlin](https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012)
28+
29+
> 了解如何通过经过行业验证的工具和库用 Kotlin 构建和开发 Android 应用。尝试使用这些 Kotlin 技巧,更快速地创建 Android 应用,同时减少错误和代码。
30+
31+
32+
33+
#### 3. 使用 Kotlin 实现高级 Android 开发
34+
35+
[Advanced Android in Kotlin](https://developer.android.com/codelabs/advanced-android-kotlin-training-welcome?index=..%2F..advanced-android-kotlin-training#0)
36+
37+
> 将您的 Android 编码技能提升到一个新的水平。该课程使用 Kotlin 编程语言,为您介绍 Android 上的通知、图形和动画,教您如何登录用户、向应用添加映射以及如何正确测试应用。每节课都包含一个在 GitHub 中提供解决方案代码的教程。
38+

src/C/develop_problem_collect.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# C 语言开发问题汇总
2+
3+
4+
5+
### vscode 远程开发时未定义 __USE_MISC 宏问题
6+
7+
找到vscode设置 -》工作区 -〉扩展 -》c/c++ -〉IntelliSense -》
8+
9+
`C_Cpp>Default:Compiler Args`设置项添加 `-D _DEFAULT_SOURCE`
10+
11+
解释:`__USE_MISC`宏在`/usr/include/features.h`文件中定义,源代码如下:
12+
13+
```c
14+
#if defined _DEFAULT_SOURCE
15+
# define __USE_MISC 1
16+
#endif
17+
```
18+

src/Java/Optional.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Optional 用法示例
2+
3+
[Guide To Java 8 Optional](https://www.baeldung.com/java-optional)
4+
5+
TODO
6+

src/Java/UML/index.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# UML 设计图
2+
3+
## 用例图(UseCase)
4+
5+
描述操作关系
6+
7+
8+
9+
## 时序图
10+
11+
12+
13+
## 类图
14+

src/Java/concurrent/ThreadLocal.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# ThreadLocal
2+
3+
> 参考了如下文章:
4+
>
5+
> - [使用ThreadLocal - 廖雪峰的官方网站](https://www.liaoxuefeng.com/wiki/1252599548343744/1306581251653666)
6+
> -
7+
8+
#### 是什么
9+

src/MySQL/Install.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# 安装和运行方面的问题
2+
3+
#### mysqld 与 mysqld_safe
4+
5+
`mysqld``mysqld_safe` 都与 MySQL 数据库服务器相关,但在用途和功能上有一些区别。
6+
7+
1. **mysqld:** `mysqld` 是 MySQL 数据库服务器的实际执行文件。它负责处理数据库的实际操作,包括数据存储、查询处理、事务管理等。当您启动 MySQL 服务器时,实际上是在运行 `mysqld` 进程。您可以直接使用命令行或启动脚本来启动 `mysqld`
8+
9+
2. **mysqld_safe:** `mysqld_safe` 是一个用于启动和监控 `mysqld` 进程的脚本。它提供了额外的功能,以确保 MySQL 服务器在运行时更稳定和可靠。具体功能包括:
10+
11+
- **自动重启:** 如果 `mysqld` 进程因某些原因崩溃,`mysqld_safe` 可以检测到并尝试重新启动 `mysqld` 进程,以确保数据库的可用性。
12+
- **日志记录和错误处理:** `mysqld_safe` 会监控 `mysqld` 的输出,捕获任何错误消息,并将其写入日志文件中,以便管理员能够诊断问题。
13+
- **资源限制:** `mysqld_safe` 可以配置一些资源限制,如内存使用和打开文件数,以防止 `mysqld` 进程过度消耗系统资源。
14+
- **后台运行:** 默认情况下,`mysqld_safe` 会将 `mysqld` 进程放在后台运行。
15+
16+
总之,`mysqld` 是 MySQL 数据库服务器的核心进程,而 `mysqld_safe` 是一个用于启动和监控 `mysqld` 进程的辅助脚本,旨在提供更好的稳定性和容错性。在启动 MySQL 服务器时,通常会使用 `mysqld_safe`,因为它可以帮助处理一些常见的问题,并在出现故障时自动重新启动数据库服务器。

src/OS/NetIO.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
内核 网络 IO
2+
3+
4+
5+
马士兵-周志垒老师《从TCP/IP,理解BIO、NIO、多路复用》课程笔记
6+
7+
1、OSI7层网络模型介绍
8+
9+
从低到高依次是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
10+
11+
2、TCP/IP4层网络模型
12+
13+
从低到高依次是:数据链路层、网络层、传输层、应用层
14+
15+
关于各层的详细作用以及OSI和TCP/IP的对比分析并非本次的重点,本次是想通过网络模型作为切入点,提出一个问题。
16+
17+
平时编写的Java网络应用处于网络模型中的哪一层?答案是应用层,那么传输层及以下的层是谁实现的?
18+
19+
答案是操作系统内核。
20+
21+
### 实验案列
22+
23+
```shell
24+
# 利用IO手动创建网络连接发送和接收数据的小实验
25+
ll /proc/$$/fd
26+
# 建立连接
27+
exec 8<> /dev/tcp/www.baidu.com/80
28+
# 向连接写入数据
29+
echo -e 'GET / HTTP/1.0\n\n' >& 8
30+
# 接收数据
31+
cat <& 8
32+
# 关闭连接
33+
exec 8<& -
34+
```
35+
36+
通过这样一个小实验可知,应用程序是通过IO与内核交互,由内核完成实际的数据发送与接收。所以熟悉IO、和内核对于程序员有重要意义。
37+
38+
我们通常听说过,TCP是面向连接的可靠传输协议。那么到底什么是**连接**呢?TCP又为什么可靠呢?带着这样的问题做接下来的实验。
39+
40+
```shell
41+
# 先打开一个终端,叫tty1,输入如下指令:
42+
tcpdump -nn -i eth0 host www.baidu.com
43+
# 再打开一个终端,叫tty2,输入如下指令:
44+
curl www.baidu.com
45+
# 然后可以在tty1中观察到类似如下的输出:
46+
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
47+
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
48+
16:47:10.048106 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [S], seq 148439528, win 29200, options [mss 1460,sackOK,TS val 1177771823 ecr 0,nop,wscale 7], length 0
49+
16:47:10.063425 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [S.], seq 4184912591, ack 148439529, win 8192, options [mss 1452,sackOK,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,wscale 5], length 0
50+
16:47:10.063457 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [.], ack 1, win 229, length 0
51+
# 上面就是3次握手的过程
52+
16:47:10.063659 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [P.], seq 1:78, ack 1, win 229, length 77: HTTP: GET / HTTP/1.1
53+
16:47:10.079171 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [.], ack 78, win 908, length 0
54+
16:47:10.080068 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [P.], seq 1:1441, ack 78, win 908, length 1440: HTTP: HTTP/1.1 200 OK
55+
16:47:10.080078 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [.], ack 1441, win 251, length 0
56+
16:47:10.080085 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [P.], seq 1441:2782, ack 78, win 908, length 1341: HTTP
57+
16:47:10.080089 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [.], ack 2782, win 274, length 0
58+
16:47:10.080217 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [F.], seq 78, ack 2782, win 274, length 0
59+
16:47:10.089536 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [P.], seq 1441:2782, ack 78, win 908, length 1341: HTTP
60+
16:47:10.089573 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [.], ack 2782, win 274, options [nop,nop,sack 1 {1441:2782}], length 0
61+
16:47:10.095643 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [.], ack 79, win 908, length 0
62+
16:47:10.095701 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [F.], seq 2782, ack 79, win 908, length 0
63+
16:47:10.095719 IP 172.17.43.138.52898 > 180.101.50.242.80: Flags [.], ack 2783, win 274, length 0
64+
16:47:13.115932 IP 180.101.50.242.80 > 172.17.43.138.52898: Flags [R], seq 4184915374, win 0, length 0
65+
```
66+
67+
然后,我们来回答上面的问题,什么是连接?连接并不是真的有一根线连接着双方。所以,tcp3次握手后,就会在双方的内核空间开辟一片内存空间,存储我的ip:port <-->对方的ip:port,这样的信息有一个官方的抽象Socket。因为对于类UNIX系统而言,所有都是文件,所以创建连接或者说在内核空间中创建Socket对象后,会有一个指向它的文件描述符fd,上层应用程序持有fd,通过fd操作Socket发送和接收数据。可通过如下方式查看这个Socket。
68+
69+
```shell
70+
netstat -natp
71+
# 命令的输出:
72+
Active Internet connections (servers and established)
73+
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
74+
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 942/sshd
75+
tcp 0 0 0.0.0.0:5355 0.0.0.0:* LISTEN 898/systemd-resolve
76+
tcp 0 0 172.17.43.138:22 39.144.38.45:35744 ESTABLISHED 1008/sshd: root [pr
77+
tcp 0 0 172.17.43.138:53378 100.100.45.106:443 TIME_WAIT -
78+
tcp 0 36 172.17.43.138:22 39.144.38.45:36090 ESTABLISHED 1299/sshd: root [pr
79+
tcp 0 0 172.17.43.138:33318 100.100.30.26:80 ESTABLISHED 1058/AliYunDun
80+
tcp 0 0 172.17.43.138:22 39.144.38.45:36086 ESTABLISHED 1190/sshd: root [pr
81+
tcp 0 0 172.17.43.138:22 39.144.38.45:36088 ESTABLISHED 1242/sshd: root [pr
82+
tcp6 0 0 :::5355 :::* LISTEN 898/systemd-resolve
83+
84+
85+
ss -at
86+
# 命令的输出
87+
State Recv-Q Send-Q Local Address:Port Peer Address:Port
88+
LISTEN 0 128 0.0.0.0:ssh 0.0.0.0:*
89+
LISTEN 0 128 0.0.0.0:hostmon 0.0.0.0:*
90+
ESTAB 0 0 172.17.43.138:ssh 39.144.38.45:35744
91+
TIME-WAIT 0 0 172.17.43.138:53384 100.100.45.106:https
92+
ESTAB 0 36 172.17.43.138:ssh 39.144.38.45:36090
93+
ESTAB 0 0 172.17.43.138:33318 100.100.30.26:http
94+
ESTAB 0 0 172.17.43.138:ssh 39.144.38.45:36086
95+
ESTAB 0 0 172.17.43.138:ssh 39.144.38.45:36088
96+
LISTEN 0 128 [::]:hostmon [::]:*
97+
```
98+
99+
使用Java新建一个ServerSocket后,没有执行accept()之前
100+
101+
此时也是可以通过`nc localhost 8080`连接的
102+
103+
此时通过`ss -na`命令查看到的
104+
105+
`recv-Q`是缓冲的没有被应用程序accept的连接数
106+
107+
`send_Q`是backlog,表示能缓冲多少个没被应用程序accept的连接
108+
109+
应用程序accept后,通过`netstat -natp`查看到的 `recv-Q``send_Q`就是缓冲数据的
110+
111+
112+
113+
java.net.ServerSocket#ServerSocket(int, int, java.net.InetAddress)
114+
115+
java.net.SocketImpl#createPlatformSocketImpl
116+
117+
根据是否存在`jdk.net.usePlainSocketImpl`属性,创建SocketImpl的子类,
118+
119+
对于jdk17的源码:没有属性时,创建NioSocketImpl,否则创建PlainSocketImpl
120+
121+
122+
123+
124+
125+
```mermaid
126+
sequenceDiagram
127+
title BIO Server Socket 调用时序图
128+
actor User
129+
User->>ServerSocket:new ServerSocket(8080, 5)
130+
ServerSocket-->ServerSocket:setImpl()
131+
ServerSocket->>SocketImpl:SocketImpl.createPlatformSocketImpl(true)
132+
alt set -Djdk.net.usePlainSocketImpl=true
133+
SocketImpl->>ServerSocket:impl = new PlainSocketImpl(true)
134+
else not set -Djdk.net.usePlainSocketImpl
135+
SocketImpl->>ServerSocket:impl = new NioSocketImpl(server)
136+
end
137+
ServerSocket->>NioSocketImpl:getImpl(){impl.create(stream: true)}
138+
NioSocketImpl->>Net:FileDescriptor fd = Net.serverSocket(stream: true)
139+
Net->>Net.c:socket0(preferIPv6, stream, reuse, fastLoopback)
140+
Net.c->>Net:int fd
141+
Net->>NioSocketImpl:return IOUtil.newFD(int fd)
142+
NioSocketImpl-->NioSocketImpl:this.fd = fd
143+
ServerSocket-->ServerSocket:return this.impl
144+
ServerSocket->>NioSocketImpl:impl.bind("0.0.0.0/0.0.0.0", 8080)
145+
NioSocketImpl->>Net:Net.bind(this.fd, "0.0.0.0/0.0.0.0", 8080)
146+
Net->>Net.c:bind0(fd, preferIPv6, useExclBind, addr, port)
147+
ServerSocket->>NioSocketImpl:impl.listen(backlog: 5)
148+
NioSocketImpl->>Net:Net.listen(this.fd, backlog)
149+
Net->>Net.c:listen(fd, backlog)
150+
ServerSocket->>User:new ServerSocket instance
151+
```
152+
153+
154+

0 commit comments

Comments
 (0)