跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

技术编程

我还在学的技术本身:语言、框架、命令与开发环境

学语言、框架和命令本身。踩过的坑、查到的东西都记在这里。

1 - Python

Python 语言、常用库与数据处理

这里放 Python 的语法、常用库与踩坑记录,从 UV 管环境到 DataFrame 打印。

2 - Docker

Docker 概念、常用命令与容器管理

容器相关的东西都在这:概念、常用命令,还有把服务搬进 Docker 的过程。

2.1 - Docker 学习笔记

说明

Docker 核心概念

容器化技术

  • Docker 是目前最成熟高效的软件部署技术
  • Docker 就是用容器化技术给应用程序封装独立的运行环境
  • 每个运行环境就是一个==容器==
  • 运行容器的计算机被称为==宿主机==

容器与虚拟机的需求

  • 容器:多个容器共用同一个系统内核
  • 虚拟机:每个虚拟机都包含操作系统的完整内核
  • 优势:Docker 容器比虚拟机更轻、更小,启动速度更快

镜像与容器的关系

  • 镜像:镜像是容器的模板,可类比为软件安装包
  • 容器:由“软件安装包”安装出来的软件
  • 类比:
    • 类比于用模具做糕点,镜像是模具,容器是做出来的糕点
    • 可以使用一个模具(镜像)做出很多个糕点(容器)
    • 也可以将模具(镜像)分享给其他人使用

Docker 仓库

  • Docker 仓库是用来存放和分享镜像的地方
  • 用户可以将镜像上传到仓库后,供其他人下载
  • Docker Hub 是 Docker 的官方仓库,可以搜索大量镜像

Docker 安装方式

暂略~ 我日常使用 ==1Panel==、==cnb.cool==、==群晖 Nas== 这些方式管理 Docker 容器 他们都已经配置好了 Docker 环境 暂时不需要去了解 Docker 的安装

Docker 镜像管理

镜像地址

一个完整的镜像地址包含以下四部分:

docker.io/library/nginx:latest
<仓库地址>/<命名空间>/<镜像名称>:<版本标签>
  • docker.io 是 Docker Hub 官方仓库的地址,可以省略
  • library 是 Docker Hub 官方仓库的命名空间,可以省略
  • nginx 是镜像名称
  • latest 是版本标签,latest表示最新版本,可以省略
  • 示例:
    • 从官方仓库下载最新版 nginx 镜像: docker pull nginx
    • 从官方仓库的 n8n 命名空间下载镜像: docker pull n8nio/n8n
    • 从 n8n 私有仓库下载镜像: docker pull docker.n8n.io/n8nio/n8n

官方仓库的镜像往往无法直接下载,需要寻找相应的镜像站或使用代理。

//TODO

2.2 - Docker 常用命令速查

日常使用频率最高的 Docker 命令和配置文件说明。

列出日常使用频率最高的命令。更多可参考 Docker 命令大全 | 菜鸟教程

容器管理

命令说明
docker ps列出运行中的容器
docker ps -a列出所有容器(含已停止的)
docker start <容器>启动已停止的容器
docker stop <容器>停止运行中的容器
docker restart <容器>重启容器
docker rm <容器>删除已停止的容器
docker rm -f <容器>强制删除运行中的容器
docker rename <容器> <新名称>重命名容器

镜像管理

命令说明
docker images列出本地镜像
docker pull <镜像名>从仓库拉取镜像,如 docker pull nginx
docker rmi <镜像名>删除本地镜像
docker build -t <标签> .构建镜像,-t 指定名称和标签
docker tag <镜像> <新标签>给镜像打标签
docker push <镜像名>推送镜像到远程仓库

日志与调试

命令说明
docker logs <容器>查看容器日志
docker logs -f --tail 100 <容器>实时查看最近 100 条日志
docker exec -it <容器> bash进入容器内部(交互式 Shell)
docker inspect <容器>查看容器的详细信息(JSON)
docker stats实时显示容器资源占用(CPU/内存)
docker top <容器>查看容器内运行的进程

Docker Compose

命令说明
docker compose up -d后台启动所有服务
docker compose down停止并移除所有容器和网络
docker compose ps列出项目中的容器状态
docker compose logs -f实时查看所有服务的日志
docker compose restart重启所有服务
docker compose pull拉取所有服务的最新镜像

系统维护

命令说明
docker system df查看磁盘使用情况
docker system prune清理未使用的容器、镜像、网络
docker system prune -a清理所有未使用的资源(含未使用的镜像)
docker info查看 Docker 系统信息

2.3 - Docker 重启策略详解

Docker 容器的重启策略有四种:no、always、on-failure、unless-stopped。

情况noalwayson-failureunless-stopped
容器正常退出 (0 状态)不重启重启不重启重启
容器非正常退出 (非 0 状态)不重启重启重启重启
手动停止 (docker stop)不重启不重启不重启不重启
Docker 服务重启 (如系统重启)不重启重启不重启不重启

下面通过一个 demo 来演示它们的区别。

准备测试环境

创建一个名为 test.sh 的脚本,5 秒后自动退出:

#!/bin/bash
sleep 5
exit 1

创建 Dockerfile 将其打包进镜像:

FROM ubuntu
ADD test.sh /
CMD /bin/bash /test.sh

构建镜像:

docker build -t test-restart .

no

docker run -d --name=test-restart-no test-restart

容器 5 秒后退出,docker daemon 不做任何处理。

结论:容器退出后不重启。

always

docker run -d --restart=always --name=test-restart-always test-restart

容器退出后 docker daemon 自动重启。虽然每次生命周期只有 5 秒,但不断重启,表面上像一直在运行。

如果手动 docker stop 停止,不会自动重启。但重启 Docker daemon 后,容器会再次启动。

结论:除非手动停止,否则总是重启。重启 Docker daemon 也会触发。

on-failure

docker run -d --restart=on-failure:3 --name=test-restart-on-failure test-restart

容器退出后触发重启。容器退出后触发重启。当重启达到 3 次上限后不再重启。

注意:Docker 认为容器成功启动至少需运行 10 秒。脚本 5 秒就退出,触发重启的次数会持续累加直到上限(参考Docker 官方文档)。

结论:仅在容器非正常退出时重启,可设置最大重试次数。

unless-stopped

docker run -d --restart=unless-stopped --name=test-restart-unless-stopped test-restart

表现和 always 一样——容器退出后自动重启。区别在于:手动 docker stop 停止后,重启 Docker daemon 时容器不会自动启动,而 always 会。

结论:与 always 类似,但手动停止后重启 Docker 不会再次启动。

如何选择

  • no:一次性任务、调试环境,不需要自动重启
  • always:Web 服务、数据库等需要持续运行的服务
  • on-failure:脚本任务、批处理作业,只在出错时重试
  • unless-stopped:和 always 类似,但希望手动停止后不再被 Docker 重启时使用

参考资料

2.4 - Docker 远程管理 Portainer

通过 Portainer 的 Web 界面远程管理多台主机的 Docker 容器。
2024-10-08 update 安全提醒

直接暴露 Docker API 端口(2375)到公网没有任何加密和认证。配置完成后务必限制防火墙来源 IP,或配置 TLS 加密。否则可能被加密劫持蠕虫盯上。

配置好远程管理后不久,我收到了云服务器恶意文件通知,并在远程主机中发现了一个莫名的容器 boorish_agelast,运行着 ubuntu:18.04。经确认是针对 Docker 守护进程的加密劫持蠕虫 Cetus。如果你的 Docker 环境不需要频繁集中管理,建议先配置好 TLS 加密再开放远程端口:

本文内容基于 6053537/portainer-ce - Docker Image | Docker Hub 的汉化版。

远程主机设置

  1. 确保远程主机已安装 Docker

  2. 进入主机终端,输入命令:

nano /usr/lib/systemd/system/docker.service
  1. 然后做以下修改:
# 将这一行
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

# 改为这样
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock
  1. 最后再重启 Docker 即可
systemctl daemon-reload
systemctl restart docker
  1. 记得在服务器的防火墙放开 2375 端口

Portainer 设置

  1. 环境 - 添加环境 - 独立的 Docker
  2. 选择 API 连接模式
  3. Docker API URL 处填写被远程连接的主机 IP+ 端口,如 6.6.6.6:2375
  4. 点击链接,完成。

参考资料

3 - Git

Git 常用命令、身份配置与仓库维护

Git 的日常命令、身份配置,以及仓库写坏之后的收拾办法。

3.1 - Git 常用命令速查

日常使用频率最高的 Git 命令速查表,涵盖基本操作、分支管理、查看历史、撤销与暂存、远程协作等场景。

本文基于 Git 2.46.0,日常使用中如有更多需求可查看 git help 或官方文档。

基本操作

命令说明
git init在当前目录初始化一个新的 Git 仓库
git clone <地址>克隆远程仓库到本地
git add .暂存所有修改过的文件
git add <文件>暂存指定文件
git commit -m "说明"提交暂存区的内容
git commit -am "说明"暂存所有已跟踪文件并提交(跳过 git add)
git status查看当前工作区状态

分支管理

命令说明
git branch列出本地分支(当前分支前有 *)
git branch -a列出所有分支(含远程分支)
git branch <名称>创建新分支
git branch -d <名称>删除已合并的分支
git branch -D <名称>强制删除分支(即使未合并)
git switch <名称>切换到已有分支
git switch -c <名称>创建并切换到新分支
git merge <分支>将指定分支合并到当前分支
git rebase <分支>将当前分支变基到指定分支

查看历史

命令说明
git log查看提交历史
git log --oneline单行显示提交历史
git log --oneline --graph以图形方式显示分支历史
git log -p显示每次提交的 diff
git diff比较工作区和暂存区的差异
git diff --staged比较暂存区和上次提交的差异
git show查看最新提交的详细信息
git show <commit-id>查看指定提交的详细信息

撤销与暂存

命令说明
git restore <文件>撤销工作区的修改(未暂存的文件)
git restore --staged <文件>取消暂存(文件回到工作区)
git reset --soft HEAD~1撤销上次提交,保留修改
git reset --hard HEAD~1撤销上次提交,丢弃修改(慎用)
git stash暂存当前工作区的修改
git stash pop恢复最近一次暂存并删除它
git stash list查看暂存列表

远程协作

命令说明
git remote -v查看远程仓库地址
git remote add origin <地址>添加远程仓库
git push origin <分支>推送代码到远程
git push -u origin <分支>首次推送并建立 upstream 关联
git pull拉取远程代码并合并
git fetch拉取远程代码但不合并
git clone <地址>克隆远程仓库

配置

命令说明
git config --list查看当前所有配置
git config --global user.name "名称"设置全局用户名
git config --global user.email "邮箱"设置全局邮箱
git config user.name "名称"设置当前仓库的用户名
git config user.email "邮箱"设置当前仓库的邮箱
git config --global http.proxy <地址>设置 HTTP 代理
git config --global --unset http.proxy取消 HTTP 代理

其他

命令说明
git tag列出所有标签
git tag <名称>创建轻量标签
git mv <旧文件> <新文件>重命名或移动文件
git rm <文件>从仓库中删除文件
git clean -df删除未跟踪的文件和目录
git help查看 Git 帮助信息
git -v查看 Git 版本

3.2 - Git 多仓库身份配置

在个人项目和公司项目中使用不同的 Git 用户名和邮箱提交,避免身份混淆。

工作电脑上同时有个人项目和公司项目时,如果不做配置,所有提交都会使用同一个用户名和邮箱。这篇文章教你如何让 Git 根据仓库自动切换身份。

配置优先级

Git 采用三层配置覆盖,优先级从低到高:

系统级 → 全局级 → 仓库级

仓库级配置会覆盖全局级,所以只需要在个别仓库设置独立身份即可。

操作步骤

1. 设置全局默认身份

适用于大多数仓库(比如你的个人项目):

git config --global user.name "your-name"
git config --global user.email "your@email.com"

2. 设置单个仓库的独立身份

终端切换到需要单独设置的仓库目录,不加 --global:

cd /path/to/company-project
git config user.name "work-name"
git config user.email "work@company.com"

这条命令会写入当前仓库的 .git/config,只影响这个仓库。

3. 验证当前仓库身份

git config user.name
git config user.email

手动编辑配置

也可以直接打开仓库下的 .git/config 文件,找到或添加:

[user]
    name = work-name
    email = work@company.com

常见场景

场景全局身份仓库级身份
个人 GitHub 项目 + 公司 GitLab 项目个人邮箱公司邮箱
开源项目 + 内部项目个人昵称公司实名
多个账号的 GitHub主账号副账号

3.3 - Git 清理远端仓库全部提交历史

删除 Git 仓库全部提交历史但保留仓库本身,适用于清理隐私信息或给仓库瘦身。
注意

此操作不可逆,会永久删除仓库的所有提交历史,请提前做好备份。

背景

当提交记录中包含隐私信息(如密钥、密码),或仓库因上传大量文件导致体积过大、拉取频繁出错时,可以通过清除全部提交历史来"瘦身"仓库,同时保留仓库本身(Star、Issues 等不受影响)。

以下两种方法均以 main 分支为例,操作前请先将仓库克隆到本地。

方法一:创建空白分支替换

通过 --orphan 创建一个没有历史的新分支,替换掉原来的 main:

git checkout --orphan latest_branch  # 创建一个没有历史的新分支
git add -A  # 暂存所有文件
git commit -m "Initial commit"  # 创建初始提交
git branch -D main  # 删除本地的 main 分支
git branch -m main  # 将当前分支重命名为 main
git push -f origin main  # 强制推送到远程仓库,替换远程 main 分支

方法二:删除 .git 重新初始化

直接删除本地的 Git 历史,重新初始化一个全新的仓库:

rm -rf .git  # 删除本地 Git 仓库目录
git init  # 重新初始化一个新的 Git 仓库
git add -A  # 暂存所有文件
git commit -m "Initial commit"  # 创建初始提交
git push -f https://github.com/username/repo.git main  # 强制推送到远程仓库(需替换为实际仓库地址)
两种方法的区别
  • 方法一保留了本地 Git 配置(如 remote、branch tracking),操作更简单
  • 方法二完全重置仓库,但需要手动填写远程仓库地址,且会丢失所有本地 Git 配置

参考资料

4 - 其他

系统命令、云原生、开发工具等暂未单独分类的笔记

系统命令、云原生、开发工具这些暂时没单独分出去的笔记,都先放这里。

4.1 - Linux 常用命令速查

日常使用频率最高的 Linux 命令速查表,涵盖文件操作、进程管理、磁盘网络、权限系统等场景。

列出日常使用频率最高的命令。更多可参考 Linux 命令大全 | 菜鸟教程

系统信息

命令说明
uname -a显示操作系统名称、内核版本、主机名等详细信息
who -b显示系统上次启动时间
uptime显示系统运行时长和负载
hostnamectl查看或修改主机名
shutdown -h now立即关机
shutdown -h 1010 分钟后关机
reboot重启服务器

文件与目录

命令说明
pwd显示当前工作目录
cd <路径>切换目录
ls列出当前目录的文件和子目录
ls -la列出所有文件(含隐藏文件)及详细信息
mkdir <目录名>创建目录
rmdir <目录名>删除空目录
cp <源> <目标>复制文件或目录
mv <源> <目标>移动或重命名
rm <文件>删除文件
rm -rf <目录>强制递归删除目录(慎用)
touch <文件>创建空文件或更新文件时间戳
cat <文件>查看文件全部内容
less <文件>分页查看文件内容(按 q 退出)
head -n 20 <文件>查看文件前 20 行
tail -n 20 <文件>查看文件最后 20 行
tail -f <文件>实时追踪文件新增内容(如日志)

文件查找与内容搜索

命令说明
find <目录> -name "*.py"按文件名递归查找
grep "关键词" <文件>在文件中搜索文本
grep -r "关键词" <目录>递归搜索目录下所有文件
wc <文件>统计文件行数、单词数、字节数
wc -l <文件>仅统计文件行数
sort <文件>对文件内容排序

进程管理

命令说明
ps aux查看所有运行中的进程
ps -ef查看所有进程(另一格式)
top实时显示进程和系统资源占用
htoptop 的增强版(需安装)
kill <PID>终止指定进程
kill -9 <PID>强制终止进程
nohup <命令> &后台运行命令(退出终端后继续)

磁盘与内存

命令说明
df -h查看磁盘分区使用情况(人类可读)
du -sh <目录>查看目录总大小
free -h查看内存使用情况
free -m以 MB 为单位显示内存

网络

命令说明
ping <地址>测试网络连通性
curl <URL>发送 HTTP 请求
wget <URL>下载文件
ss -tlnp查看监听端口和对应进程
netstat -tlnp查看监听端口(ss 的替代)
ip addr查看网络接口和 IP 地址
ifconfig查看网络配置(需安装 net-tools)

文件权限

命令说明
chmod 755 <文件>设置文件权限
chmod +x <文件>给文件添加可执行权限
chown <用户>:<组> <文件>修改文件所属用户和组

压缩与归档

命令说明
tar -czf 包名.tar.gz <目录>打包并压缩为 tar.gz
tar -xzf 包名.tar.gz解压 tar.gz
unzip <文件>.zip解压 zip 文件
zip -r 包名.zip <目录>压缩为 zip

包管理(Debian/Ubuntu)

命令说明
apt update更新软件包索引
apt upgrade升级所有可升级的软件包
apt install <包名>安装软件包
apt remove <包名>卸载软件包
apt search <关键词>搜索软件包

4.2 - Markdown 语法速查

涵盖标题、文本、列表、链接、表格、代码等常用 Markdown 语法,一份速查表快速上手。

语法速查表

功能Markdown 语法效果预览
一级标题# 标题内容最大的标题
二级标题## 标题内容
三级标题### 标题内容(依此类推,可到六级)
加粗**需要加粗的文字**需要加粗的文字
斜体*需要倾斜的文字*需要倾斜的文字
加粗并斜体***又粗又斜的文字***又粗又斜的文字
删除线~~被删除的文字~~被删除的文字
无序列表- 列表项 或 * 列表项• 列表项
有序列表1. 列表项一
2. 列表项二
1. 列表项一
2. 列表项二
任务列表- [ ] 未完成
- [x] 已完成
☐ 未完成
☑ 已完成
引用> 这是一段引用的文字> 这是一段引用的文字
行内代码`code`用于突出显示变量或命令
代码块```python
print("Hello")
```
用于显示多行代码
链接[显示的文字](https://example.com)显示的文字
图片![替代文本](图片路径)直接显示图片
水平分割线--- 或 ***一条横跨页面的线

标题

注意:所有符号都是英文输入法下的符号。井号加空格,几个井号就是几级标题,一级标题字体最大。

# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

文本

**加粗**
*斜体*
***粗斜体***
~~删除线~~

列表

无序列表: 减号/加号/星号 + 空格,三个符号均可,建议用减号。

- 列表项 1
- 列表项 2
 - 嵌套列表项
- 列表项 3

有序列表: 数字 + 点 + 空格。

1. 列表项 a
2. 列表项 b
 1. 嵌套项 b1
3. 列表项 c

任务列表: 方括号内空格代表未完成,x 代表已完成。

- [ ] 未完成的任务
- [x] 已完成的任务

引用

> 这是一段引用
>> 嵌套引用

链接

[显示的文字](https://example.com)

直接链接:<https://github.com>

锚点链接:[链接文字][锚点名]
[锚点名]: https://example.com

图片

![替代文本](图片路径 "可选的标题")

带链接的图片:[![替代文本](图片路径)](https://example.com)

表格

竖线分隔单元格,分隔行至少三个减号,冒号控制对齐。

| 左对齐 | 居中对齐 | 右对齐 |
| :----- | :------: | -----: |
| AAA    |   BBB    |    CCC |

代码

行内代码:用反引号包裹,如 `code`。

代码块:用三个反引号包裹,可指定语言。

```python
import numpy as np
def calc(a):
    return np.sqrt(a) * 3
```

脚注

要添加脚注[^01]

[^01]: 脚注内容

分割线

三个或以上的减号、星号、下划线均可。

---
***
___

注意事项

  • 所有符号都是英文输入法下的符号
  • 井号 # 后要加空格才是标题

4.3 - MySQL 常用 SQL 语句速查

MySQL 常用 SQL 语句速查,涵盖数据库、数据表、数据行的增删改查及常用数据类型。

数据库操作

/* 创建数据库 */
CREATE DATABASE 数据库名称;

/* 删除数据库 */
DROP DATABASE 数据库名称;

/* 查看所有数据库 */
SHOW DATABASES;

/* 查看当前数据库的字符集等信息 */
SHOW CREATE DATABASE 数据库名称;

/* 修改数据库的字符集等属性 */
ALTER DATABASE 数据库名称 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

数据表操作

/* 创建数据表 */
CREATE TABLE 数据表名称 (字段1 数据类型1, 字段2 数据类型2, ...);

/* 删除数据表 */
DROP TABLE 数据表名称;

/* 查看当前数据库中的所有数据表 */
SHOW TABLES;

/* 查看数据表的结构 */
DESCRIBE 数据表名称;

/* 查看数据表的创建语句 */
SHOW CREATE TABLE 数据表名称;

/* 添加新列 */
ALTER TABLE 数据表名称 ADD COLUMN 新字段 数据类型;

/* 修改列的数据类型 */
ALTER TABLE 数据表名称 MODIFY COLUMN 字段1 新数据类型;

/* 重命名列 */
ALTER TABLE 数据表名称 CHANGE COLUMN 字段1 新字段名 数据类型;

/* 删除列 */
ALTER TABLE 数据表名称 DROP COLUMN 字段1;

数据行操作

/* 插入数据行 */
INSERT INTO 数据表名称 (字段1, 字段2, ...) VALUES (值1, 值2, ...);

/* 查询数据行 */
SELECT 字段1, 字段2, ... FROM 数据表名称 WHERE 字段1 = '条件值1';

/* 更新数据行 */
UPDATE 数据表名称 SET 字段1 = '新值1', 字段2 = '新值2', ... WHERE 字段1 = '条件值1';

/* 删除数据行 */
DELETE FROM 数据表名称 WHERE 字段1 = '条件值1';

条件与排序

/* 条件查询 */
SELECT * FROM 数据表 WHERE 字段1 = '值';
SELECT * FROM 数据表 WHERE 字段1 LIKE '%关键词%';
SELECT * FROM 数据表 WHERE 字段1 > 100 AND 字段2 = '值';

/* 排序 */
SELECT * FROM 数据表 ORDER BY 字段1 DESC;        /* 降序 */
SELECT * FROM 数据表 ORDER BY 字段1 ASC;         /* 升序(默认) */

/* 分页 */
SELECT * FROM 数据表 LIMIT 10;                    /* 取前 10 条 */
SELECT * FROM 数据表 LIMIT 10 OFFSET 20;          /* 跳过 20 条,取 10 条 */
SELECT * FROM 数据表 LIMIT 20, 10;                /* 同上,简写形式 */

聚合与分组

/* 聚合函数 */
SELECT COUNT(*) FROM 数据表;                      /* 统计行数 */
SELECT SUM(金额字段) FROM 数据表;                  /* 求和 */
SELECT AVG(价格字段) FROM 数据表;                  /* 平均值 */
SELECT MAX(年龄字段) FROM 数据表;                  /* 最大值 */
SELECT MIN(年龄字段) FROM 数据表;                  /* 最小值 */

/* 分组统计 */
SELECT 分类字段, COUNT(*) FROM 数据表 GROUP BY 分类字段;
SELECT 分类字段, SUM(金额) FROM 数据表 GROUP BY 分类字段 HAVING SUM(金额) > 1000;

索引

/* 创建索引 */
CREATE INDEX 索引名称 ON 数据表 (字段1);
CREATE INDEX 索引名称 ON 数据表 (字段1, 字段2);   /* 联合索引 */

/* 删除索引 */
DROP INDEX 索引名称 ON 数据表;

/* 查看索引 */
SHOW INDEX FROM 数据表;

用户管理

/* 创建用户 */
CREATE USER '用户名'@'localhost' IDENTIFIED BY '密码';
CREATE USER '用户名'@'%' IDENTIFIED BY '密码';     /* 允许远程登录 */

/* 授权 */
GRANT ALL PRIVILEGES ON 数据库名.* TO '用户名'@'localhost';
GRANT SELECT, INSERT, UPDATE ON 数据库名.* TO '用户名'@'%';

/* 刷新权限 */
FLUSH PRIVILEGES;

/* 查看用户 */
SELECT User, Host FROM mysql.user;

/* 修改密码 */
ALTER USER '用户名'@'localhost' IDENTIFIED BY '新密码';

/* 删除用户 */
DROP USER '用户名'@'localhost';

常用数据类型

数值类型

数据类型说明取值范围适用场景
INT普通整数−21亿 ~ 21亿用户ID、文章数量、年份
BIGINT大整数−922亿亿 ~ 922亿亿订单号、日志ID、超大数据量
FLOAT单精度浮点数约 7 位有效数字科学计算、百分比
DOUBLE双精度浮点数约 15 位有效数字科学计算、高精度要求
DECIMAL定点数(精确)取决于定义金额、价格(必须用这个,避免精度丢失)

FLOAT(M,D) / DOUBLE(M,D) / DECIMAL(M,D) 中的 (M,D) 表示总长度 M 位,其中 D 位是小数。例如 DECIMAL(10,2) 总长 10 位,小数 2 位,整数 8 位。

字符串类型

数据类型说明最大长度适用场景
VARCHAR可变长度字符串65535 字符用户名、邮箱、标题(短文本首选)
TEXT长文本65535 字符文章正文、评论内容、日志详情

日期和时间类型

数据类型说明取值范围适用场景
DATETIME日期和时间1000 ~ 9999 年创建时间、更新时间(通用场景)
TIMESTAMP时间戳1970 年起记录日志时间,受时区影响(自动转换为当前时区)

DATETIME 和 TIMESTAMP 的区别:TIMESTAMP 会自动转换为当前时区;DATETIME 不受时区影响。日常场景首选 DATETIME。

JSON 类型

数据类型说明适用场景
JSON存储 JSON 格式数据配置信息、动态属性、非结构化数据存储

4.4 - SSH 密钥配置指南

SSH 密钥的生成、绑定、配置与常用操作,从入门到进阶。

简介

SSH 密钥(SSH Key)是一种用于安全登录远程服务器的"钥匙",它由一对公钥和私钥组成。与密码相比,SSH 密钥更安全,也更方便。

  • 公钥(Public Key):放在远程服务器上,可以公开。
  • 私钥(Private Key):保存在本地电脑,必须保密,不能泄露。

可以将其类比为钥匙(私钥)和锁芯(公钥),公钥放在远程服务器上,私钥保存在本地电脑里,相互配对才能正确打开。

生成密钥

在终端内执行:

  • 使用 ed25519 算法(推荐):ssh-keygen -t ed25519 -C "备注"
  • 使用 rsa 算法(兼容性好):ssh-keygen -t rsa -b 4096 -C "备注"

执行后,会让你确认密钥保存在哪里,是否需要再加一个密码。在一路回车的默认情况下,会在 ~/.ssh 目录下生成两个文件:

  • id_ed25519 或 id_rsa 即私钥
  • id_ed25519.pub 或 id_rsa.pub 即公钥

然后将公钥与远程服务器绑定即可。

绑定公钥

进阶:使用 ~/.ssh/config

服务器多起来后,每次 SSH 都要记 IP 和端口很麻烦。可以在 ~/.ssh/config 中为常用服务器设置别名:

# 个人服务器
Host my-server
    HostName 123.123.123.123
    User root

# Web 服务器
Host web-server
    HostName 456.456.456.456
    User admin
    Port 2222

配置后直接 ssh my-server 即可登录,不用再记 IP 和端口。

4.5 - VSCode 配置机制完整笔记

一、.vscode 目录概述

.vscode 是 VS Code 的项目级配置目录,定义"当 VS Code 打开这个项目时,该如何表现"。

常见文件结构

.vscode/
├── settings.json      # 工作区设置(覆盖用户全局设置)
├── extensions.json    # 推荐安装的扩展列表
├── launch.json        # 调试配置
├── tasks.json         # 自定义任务
└── snippets/          # 代码片段目录

二、配置层级与覆盖机制

三层架构(优先级由低到高)

VS Code 默认设置
    ↓
用户级设置(~/settings.json)
    ↓
工作区设置(.vscode/settings.json)← 项目级,优先级最高

关键区别

文件机制行为
settings.json增量覆盖只写3项 → 继承用户级其余7项
extensions.json全量清单只写a,b,c → 只推荐a,b,c,不继承其他
launch.json全量配置只显示配置的调试方案
tasks.json全量配置只显示定义的任务
snippets/*.json全量配置只提供定义的代码片段

示例对比

settings.json(增量)

// 用户级:a=1, b=2, c=3, d=4, e=5
// 项目级写:{"b": 20}
// 结果:a=1, b=20, c=3, d=4, e=5(继承+覆盖)

extensions.json(全量)

// 用户级:安装了 a,b,c,d
// 项目级写:{"recommendations": ["a","b"]}
// 结果:只推荐 a,b(不会推荐 c,d)

三、配置存储位置

用户级配置

类型路径(macOS/Linux)路径(Windows)
设置文件~/.config/Code/User/settings.json%APPDATA%\Code\User\settings.json
扩展目录~/.vscode/extensions/%USERPROFILE%\.vscode\extensions\
快捷键~/.config/Code/User/keybindings.json同左
代码片段~/.config/Code/User/snippets/同左

项目级配置

  • 位置:.vscode/ 目录下
  • 作用范围:仅当前项目
  • 版本控制:应提交到 Git,确保团队一致

四、扩展管理

用户级 vs 项目级

级别存储位置特点
用户级扩展~/.vscode/extensions/所有项目共享,物理安装在此
项目级推荐.vscode/extensions.json仅提示安装,不自动部署
真正隔离Dev Container容器内独立安装扩展

扩展推荐配置

{
  "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"],
  "unwantedRecommendations": ["some.extension.to.disable"]
}

多项目扩展隔离方案

场景:项目A用a,b,c,项目B用d,e,f,其他项目用a,b,c,d

方案实现方式适用场景
简单推荐extensions.json 分别配置只是提示,不强制
禁用配置settings.json 中禁用对方扩展扩展有冲突时
彻底隔离--user-data-dir 启动独立实例需要完全隔离

五、跨平台路径处理

核心原则

能用相对不用绝对,能用变量不用字符串

内置变量

变量含义跨平台效果
${workspaceFolder}项目根目录自动适配 Windows/macOS/Linux 路径格式
${userHome}用户主目录Windows: C:\Users\123, macOS: /Users/123
${workspaceFolderBasename}项目文件夹名如 project
${env:NAME}环境变量如 ${env:HOME}

正确 vs 错误示例

// ❌ 错误:硬编码绝对路径
"python.defaultInterpreterPath": "C:/Users/123/project/venv/bin/python"

// ✅ 正确:使用变量
"python.defaultInterpreterPath": "${workspaceFolder}/venv/bin/python"
"python.analysis.extraPaths": ["${userHome}/.local/lib/python"]

特殊情况处理

如果路径完全无关(如 Windows D:\project1\123 vs macOS Documents/project1/123):

方案做法
推荐把系统特定路径放用户级 settings.json,项目级保持通用
备选使用环境变量 ${env:PROJECT1_PATH}
避免硬编码不同系统的绝对路径到项目配置

六、VS Code 设置同步

同步内容

  • ✅ 用户级 settings.json
  • ✅ 扩展列表(自动重新安装)
  • ✅ 键盘快捷键
  • ✅ 用户级代码片段
  • ✅ UI 状态

不同步内容

  • ❌ 项目级 .vscode/ 目录(需 Git 管理)
  • ❌ 扩展的本地数据/缓存

分工明确

机制用途
设置同步个人习惯跟着账号走(跨设备)
.vscode + Git团队规范跟着代码走(跨成员)

七、最佳实践总结

1. 配置原则

  • 项目级(.vscode/):放团队共享、通用、跨平台的配置
  • 用户级(~/settings.json):放个人偏好、系统特定的配置

2. 路径原则

  • 优先使用 ${workspaceFolder}(项目内)
  • 其次使用 ${userHome}(用户目录)
  • 避免硬编码盘符(如 D:\、/Volumes/)

3. 扩展原则

  • 项目必需的扩展 → extensions.json 推荐
  • 个人辅助扩展 → 用户级安装,不同步到项目

4. 调试/任务原则

  • 通用任务 → .vscode/tasks.json(全量定义)
  • 个人调试习惯 → 用户级 launch.json

八、快速参考命令

操作命令面板(Ctrl+Shift+P)
打开用户级设置(UI)Preferences: Open User Settings
打开用户级设置(JSON)Preferences: Open User Settings (JSON)
打开工作区设置(JSON)Preferences: Open Workspace Settings (JSON)
打开扩展目录Extensions: Open Extensions Folder
打开键盘快捷键Preferences: Open Keyboard Shortcuts (JSON)

4.6 - MacOS 系统降级流程

本文介绍如何将 Intel 芯片的 MacOS 从 13.x 版本降级到 10.15 或 12.x 版本(已实测),其他版本仅供参考。

重要提示

降级过程会格式化全部磁盘内容,请务必提前备份所有重要数据,并在多处进行备份!

参考链接

MacOS 版本推荐

以下版本信息针对 2017 MacBook Pro 设备:

  • Ventura 13——最后一个支持的版本
  • Monterey 12——稳定性一般,兼容性较好
  • Catalina 10.15——稳定性最佳,兼容性一般

操作步骤

1. 准备工作

  1. 备份所有重要数据
  2. 退出系统的 Apple ID
  3. 准备一个 14GB 以上的 USB 闪存盘

2. 下载 MacOS

  1. 在 本页面 通过 App Store 下载所需的系统版本(如 Monterey 12)
  2. 下载完毕后,若自动打开安装程序,直接关闭退出
  3. 确保应用程序文件夹内有名为 安装macOS Monterey 的安装器

3. 创建 macOS 安装器

  1. 插入准备的 USB 闪存盘
  2. 使用系统自带的 磁盘工具 应用,将其全盘抹掉并格式化:
    • 名称:MyVolume(建议使用此名称,方便后续操作)
    • 格式:Mac OS拓展(日志式)(是否区分大小写不影响)
  3. 启动终端,根据所需的系统版本输入命令(命令来源):
    • Catalina:sudo /Applications/Install\ macOS\ Catalina.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
    • Monterey:sudo /Applications/Install\ macOS\ Monterey.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
  4. 根据终端提示完成安装:
    • 输入登录密码(输入时终端无字符提示)
    • 输入 Y 确认全部抹掉 USB 闪存盘(弹出允许终端访问可移动宗卷的提示时点击允许)
    • 耐心等待,过程较为漫长
  5. 安装完成后,USB 闪存盘名称将改为类似 Install macOS Monterey 的名称

4. 启动 MacOS 安装程序

  1. 重启设备后,立刻按住 Option 键,直到出现可引导安装器的宗卷(即 Install macOS Monterey)
  2. 通过方向键选择安装器(若无法启动,需确保“启动安全性实用工具”已设为允许从外部或可移动介质启动)

5. 安装 MacOS

  1. 进入安装器后,启动磁盘工具,抹掉内置的整个硬盘(通常被命名为 Macintosh HD):
    • 名称:Macintosh HD
    • 格式:APFS
  2. 关闭磁盘工具,返回选择 安装macOS Monterey
  3. 选择安装到 Macintosh HD
  4. 耐心等待,过程较为漫长

6. 完成安装

安装完成后,剩余步骤为初始化新的 MacOS 系统流程。

4.7 - Front Matter 规范

本站约定

  • title 是唯一必填字段,没有它 Hugo 无法渲染页面。
  • 日期使用本站自定义的 created / updated 字段,由 hugo.yml 的 frontmatter 映射到 Hugo 原生的 date / lastmod。
  • updated 一般不写——页面「最后修改」由 :git(最后一次 commit 时间)自动填充;手动写 updated 才会覆盖。
  • 编辑器可能对 created / updated 报 schema 错误,这是误报,勿改名(改名会破坏日期映射)。
  • 字段取值优先级:页面 front matter → 上级 cascade → hugo.yml 站点参数。

文章页字段

字段作用
title必需。页面标题,Hugo 没有它无法渲染页面
created创建日期,YYYY-MM-DD,页面显示为「创建于」
tags标签数组,如 [Docker, NAS],Hugo 自动生成标签页
description页面描述,用于搜索结果与社交分享;不写则自动截取正文前 70 字
updated手动指定更新日期;不写则由最后一次 commit 时间自动填充
weight列表内排序,数字越小越靠前
drafttrue 则页面不构建,hugo server --buildDrafts 下可见

OINK 主题常用字段

字段作用
linkTitle短标题,用于侧栏、面包屑与翻页器(正文大标题不变)
iconFont Awesome 图标类(如 fa-solid fa-rocket),用于侧栏与栏目卡片
categories分类,与 tags 同为 taxonomy,Hugo 自动生成分类页
series系列名;series_weight 决定在系列中的顺序
images封面图,第一项兼作社交分享卡片
sidebar_enabledfalse 隐藏左侧栏,独立页面常用
breadcrumbfalse 隐藏面包屑导航;博客分区默认关,其余默认开
notoctrue 则不显示右栏页面目录
pagerfalse 关闭本页底部上一页/下一页
backlinksfalse 隐藏右栏「反链」组(本站已在站点级开启)
comments评论开关:站点级已关闭
aliases旧路径重定向到本页,页面改名时用于保住旧评论串与外链

完整字段表见 OINK Front Matter 官方文档。

文章页模板

---
created: YYYY-MM-DD
title: 本文标题
tags: [标签1, 标签2]
---

索引页

各分区的 _index.md:

字段作用
title必需。分区名称
description分区描述,用于栏目卡片与 SEO
weight该分区在父级列表中的排序

日期机制

hugo.yml 中配置了 front matter 的取值优先级:

frontmatter:
  date:
    - created       # 第一优先级 → 页面创建日期
    - date
  lastmod:
    - updated       # 手动覆盖(可选)
    - :git          # 由 Git 提交记录自动填充
    - lastmod
  • 创建日期:Hugo 从 created 取值。
  • 更新日期:默认由 :git 自动填充(最后一次 commit 时间),如需手动指定,在 front matter 中写 updated 即可覆盖。

4.8 - 修复 Git 提交时间无法显示

问题现象

文章页面底部的"最后更新"时间始终不显示,检查 Hugo 模板发现 .GitInfo 和 .Lastmod 均为空值。

原因

当文件路径包含中文等非 ASCII 字符时(如 content/docs/实践笔记/Docker 重启策略详解.md),Git 默认会对路径做转义处理,导致 Hugo 的 Git 集成无法正确匹配文件路径,.GitInfo 返回 nil,.Lastmod 随之失效。

这是 Hugo 的已知问题,umlauts(ä、ö、ü)等路径也会触发。

解决方案

本地开发

在仓库根目录执行一次:

git config core.quotePath false

然后删除 .hugo_build.lock(缓存了旧状态),重新构建即可。

CI/CD 构建

.cnb.yml 中在 hugo 命令之前加上同一行:

- name: Hugo 构建
  script: |
    # 文件路径包含中文等字符时会导致 Hugo 拿不到 Git 提交时间,执行以下命令修复此问题
    git config core.quotePath false
    hugo --minify

验证

构建后检查页面 HTML,如果出现 hx:mt-12 而非 hx:mt-16,说明更新日期已正常显示。

参考