Notes
这里是我的笔记集合。
DNSControl Setup
exported directly from my Logseq graph cuz I’m lazy.
- Setting up DNSControl
- Referrences
- Troubleshooting
- Complained on Fedi…
- Setup
- Install DNSControl
- via Homebrew, on macOS
brew install StackExchange/tap/dnscontrol - download pre-built binary see releases
- via Homebrew, on macOS
- Set up Git repository for configuration files
mkdir dns && cd dnsgit initnvim creds.json- For Cloudflare credentials
{ "cloudflare": { "TYPE": "CLOUDFLAREAPI", "accountid": "$CLOUDFLARE_ACCOUNT_ID", "apitoken": "$CLOUDFLARE_API_TOKEN" } } - It can read from enviroment variables, as long as it start with a
$
- For Cloudflare credentials
nvim dnsconfig.js- Don’t type
dnscontrol.js… I made that mistake - Set up registrar (
noneis OK) and DNS provider (Cloudflare in this case)var REG_NONE = NewRegistrar("none"); var DSP_CLOUDFLARE = NewDnsProvider('cloudflare'); - Use
D()to add domain.D("example.com", REG_NONE, DSP_CLOUDFLARE, ...)
- Don’t type
- Get existing DNS records in JavaScript
- use
dnscontrol get-zonednscontrol get-zone --format=js -out=draft.js "cloudflare" "CLOUDFLAREAPI" "geedea.pro" dnscontrol get-zone --format=js -out=draft.js "cloudflare" "CLOUDFLAREAPI" "eltr.ac" - copy the content from
draft.jstodnsconfig.js, and modify it correctly
- use
- Preview and push
dnscontrol previewdnscontrol push
- Set up automatic workflow (with Forgejo Action)
name: Push on: push: branches: - master jobs: push: runs-on: docker steps: - uses: actions/checkout@v3 - name: Install and Push env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} run: | curl -sL https://github.com/StackExchange/dnscontrol/releases/download/v4.36.1/dnscontrol_4.36.1_linux_amd64.tar.gz | tar xz ./dnscontrol push
- Install DNSControl
欧洲 VPS 服务商收集整理
Contabo
性价比之王,截止 2026 年 3 月 13 日,最低档 VPS(4C8G 75GB)最低只需 ¥3.96/mo。
据说超售严重,但日常使用没有明显瓶颈。
Hetzner
TODO
Netcup
TODO
OVHCloud
TODO
D2 入门
D2 是声明式绘图语言,用 Go 编写,配合命令行工具,从纯文本生成 SVG/PNG 格式的图片,支持 UML 类图、时序图、网格图、SQL 数据表、代码、图片和图表等元素。生成出来的图片效果在同类工具中算出众的(对比 PlantUML),由于 PlantUML 生成的图片风格不统一且运行在 Java 虚拟机上(谁家命令行工具用 .jar 运行啊……),权衡之后选择了图片类型更少但效果更好的 D2。尽管没有完全实现 UML 而且不支持用例图,但似乎也能用自定义元素实现类似的效果。
安装 D2
官方提供的方法是:
curl -fsSL https://d2lang.com/install.sh | sh -s --
在 macOS 上可以使用 Homebrew 安装:
brew install d2
命令行
d2 input.d2 out.svg
加上 -w 或 --watch Flag,可以监听 input.d2 变化,打开浏览器实时更新查看变更。
d2 -w input.d2 out.svg
输出格式支持 .png,修改拓展名即可。
基本语法
D2 主要有三个概念:形状(Shapes)、连接(Connections)和容器(Containers)。
x -> y: Hello World
以上语句定义了两个形状之间的连接,并添加了名为「Hello World」的标签(label)
定义形状
以下都是合法名称:
imAShape
im_a_shape
im a shape
i'm a shape
# 一个连字符 - 不代表连接,-- 表示一个连接
# 所以 a--shape 代表的是 a 与 shape 的连接
a-shape
用冒号定义形状的标签,也就是显示名称:
Clojure 中的函数和宏
由于在其他编程语言里很少接触宏(macro),只接触过 C 语言里的宏,即 #define。C 语言里的宏在编译器预处理时被处理,由于我没有 C 的开发经验,所以最常用宏的场景仅仅是用 #define 来定义常量。因此,在学习 Clojure 时,我对函数和 Lisp 语言里常见的宏产生了些许疑问。
函数和宏到底有什么区别?在 Clojure 里,它们都以相似的语法被定义。
;; 这是一个函数
(defn do-something [arg] ...)
;; 这是一个宏
(defmacro my-macro [arg] ...)
调用函数和使用宏的方式也一致。
(do-something arg)
(my-macro arg)
而且它们也都支持用 & 来标记可变数量的参数。
区别
最终在 StackOverflow1 上找到了解答。
简单来说,函数和宏被调用时:
- 函数的参数会先被计算(evaluate),然后再用计算得到的值执行函数体。
- 宏会先进行宏展开,将当前代码变成宏定义的形式,再计算整段代码。
以下是几个说明这种区别的例子。
一
用于逻辑运算的 or 是宏,并且不能是函数,因为 (or a b) 在计算时,如果 a 的结果已经为 true,就不会继续计算 b。如果 or 是函数,那么就要把 a 和 b 都计算之后才会计算 or 函数本身,这对逻辑运算来说是低效且不合理的。
二
由于函数的参数会先被计算,所以参数不允许出现无效的表达式,而宏则是允许的。
设有一个宏 (mymacro (1 2 +)) 会被展开为 (+ 1 2),而 (1 2 +) 本身是无效的,因为没有 1 这个函数或者宏。假如 mymacro 是函数而不是宏,就会报错,因为无法计算出参数 (1 2 +) 的值;而宏进行展开得到的 (+ 1 2) 就能够被计算。
使用 SSH 替代 HTTPS 连接 Git
直接一直习惯使用 HTTPS 连接到远程 Git 仓库,偶尔会遇到 SSL 问题,比如这样:
LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to codeberg.org:443
可能是网络环境导致的,但既然是 SSL 问题,那不用 HTTPS 协议不就不会遇到这个问题了吗?改用 SSH 连接至远程仓库可能是更稳定的选择。
一般来说,HTTPS 协议的远程仓库 URL 是这样的:
https://codeberg.org/eltrac/essayer.git
对应的 SSH 链接就是这样:
ssh://[email protected]/eltrac/essayer.Git
Codeberg(Forgejo)和 GitHub 都支持通过 SSH 连接。
设置远程仓库 URL:
git remote set-url origin [email protected]:eltrac/essayer.git
直接 pull 或者 push 会遇到认证问题,需要配置 SSH 密钥进行认证。在 Codeberg/Forgejo/GitHub 的设置中找到「SSH / GPG keys」,添加自己的 SSH 公钥。1
接下来要配置本地的 SSH 在连接至 Codeberg/Forgejo/GitHub 时使用相应的密钥进行认证,编辑 SSH 配置文件(macOS 的在 ~/.ssh/config)。
添加这一段配置
Host codeberg.org
HostName codeberg.org
User git
ProxyCommand nc -X 5 -x 127.0.0.1:7890 %h %p
IdentityFile ~/.ssh/id_ed25519
TCPKeepAlive yes
根据自己的情况修改 Host、HostName、ProxyCommand 和 IdentityFile。比如,如果你要通过 SSH 连接到 GitHub 而非 Codeberg,就把 codeberg.org 改为 github.com;如果你不使用代理,可以把 ProxyCommand 删掉,如果代理的端口不在 7890,也要手动修改;如果你用来跟远程服务器认证的 SSH 密钥名字不叫 id_ed25519,也请自行修改。
Neovim 添加新语言的标准操作流程
这篇笔记基于我的 Neovim 配置进行。
最近学校课程要学 Python,作为 Neovim 用户当然是不会去用老师推荐的 PyCharm 的。要获得比较好的体验就要配置语言服务器(LSP)和 Treesitter,一些语言可能还有其他的辅助工具。为了方便未来配置开发环境,故做此笔记。
LSP
配置 lua/plugins/nvim-lspconfig.lua,找到自己定义的 lsps 变量,在这个数组里添加需要的语言服务器名字。可使用 Telescope 的 help_tags Picker 搜索 lspconfig-all(或者直接 :help lspconfig-all)打开所有 LSP 配置的帮助文档,按下 / 搜索需要的语言,找到准确的语言服务器名称。
例如,Python 的语言服务器可以用 pylsp
local lsps = {
"gopls",
"marksman",
"ts_ls",
"vue_ls",
"cssls",
"html",
"unocss",
"clojure_lsp",
"pylsp"
}
运行 :checkhealth vim.lsp 检查语言服务器状态,比如,配置 pylsp 之后应该能看到这一条。
- pylsp:
- before_init: <function @/Users/eltrac/.local/share/nvim/lazy/mason-lspconfig.nvim/lua/mason-lspconfig/lsp/pylsp.lua:5>
- cmd: { "pylsp" }
- filetypes: python
- root_markers: { "pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", ".git" }
Treesitter
配置 lua/plugins/nvim-treesitter.lua,在 install({}) 方法中添加语言名称即可安装对应语言的 Treesitter。
自定义 Forgejo 的前端界面
Forgejo 是基于 Gitea 开发的,用 Go 语言编写的轻量级远程 Git 服务,功能很丰富,可以视作 GitHub 的自托管、开源替代。自建的 Forgejo 实例如果和别人的看起来一模一样,未免太没个性,故决定自定义。
环境
我使用 Docker 部署 Forgejo,使用 docker compose 管理容器,所以不能直接在宿主机上修改 Forgejo 的文件,要把宿主机上的文件挂载到容器内。在容器内部,Forgejo 会读取 /data 目录下的文件。
Forgejo 的官方文档提供了 docker-compose.yml 的例子:
networks:
forgejo:
external: false
services:
server:
image: codeberg.org/forgejo/forgejo:13
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
networks:
- forgejo
volumes:
- ./forgejo:/data
- /etc/localtime:/etc/localtime:ro
ports:
- '3000:3000'
- '222:22'
关注这一行:
volumes:
- ./forgejo:/data
这里的意思是:把宿主机上的 ./forgejo 目录挂载到容器内的 /data 目录中。简单来说,如果你是用官方提供的 docker-compose.yml 安装的 Forgejo,只需要把 ./forgejo 当成 /data 目录就好了。
Hugo 推送到生产环境不构建 SCSS 的问题
为了给博客添加主题切换按钮,将原先通过媒体查询(@media query)实现的暗色模式切换到了用 CSS 类名(.dark)实现,在本地测试无误,但合并到 master 分支并在 VPS 上构建之后,却出现了问题——当系统配色方案是「暗色」时,就算主动将站内的主题切换为「亮色」,也仍然会保持暗色背景;反之,在系统亮色方案下,将站内主题切换为「暗色」,却没有这个问题。
排查后发现,在本地构建的 Hugo 网站没有这个问题,但是在 VPS 上构建的网站,仍然使用了老旧的 @media 媒体查询方案,即便源代码都是一样的,构建结果却有所不同。
在后续的开发中,发现了类似的问题:修改了 SCSS 文件,本地测试没有问题,但推送到生产环境后,在 VPS 上构建的网站却没有使用最新的 SCSS,仍然使用过时的样式。
Hugo 的构建缓存?
Hugo 的确会缓存资源文件,见文档。不过,一般来说只会在构建过程中缓存,避免在同一个构建过程中反复从磁盘中读取相同的文件;也会在多次构建之间缓存,但照例来说不会持续好几天都只能读取到旧文件。
以下是 Hugo 默认的缓存配置。
[caches]
[caches.assets]
dir = ':resourceDir/_gen'
maxAge = -1
[caches.getresource]
dir = ':cacheDir/:project'
maxAge = -1
[caches.images]
dir = ':resourceDir/_gen'
maxAge = -1
[caches.misc]
dir = ':cacheDir/:project'
maxAge = -1
[caches.modulequeries]
dir = ':cacheDir/modules'
maxAge = '24h'
[caches.modules]
dir = ':cacheDir/modules'
maxAge = -1
可见,除了模块查询(module queries)默认缓存一天之外,包括静态资源在内的其他内容都是默认没有缓存的(即值为 -1)。
那么就不会是构建缓存的问题了。也不可能是 Cloudflare 的网络层缓存,因为网站使用的是行内 CSS,是以 <style> 标签嵌入到 HTML 文件里的,不会被缓存。
升级使用 Docker Compose 管理的应用
是的,文档里找不到 Upgrade 这一栏内容,我就不知道怎么更新应用的版本了 🤦
假设有一个使用 docker-compose.yml 定义、使用 docker compose up -d 命令跑起来的容器化应用,现在需要生气到最新版本。查看 YAML 文件,找到对应的 service,看看有没有指定版本号。一般来说写的是 latest,也就是最新版本。以下是一个例子:
services:
homeserver:
image: forgejo.ellis.link/continuwuation/continuwuity:latest
在 docker-compose.yml 存在的目录下执行以下命令,拉取最新镜像(也可以在执行命令的时候指定要执行拉取操作的服务名称,这样就不用管当前的工作目录了)。
docker compose pull
# or
docker compose pull homeserver
拉取到新版本后,重新创建容器。
docker compose up -d --no-deps
# or
docker compose up -d --no-deps homeserver
现在跑起来的就是最新版本了。
为静态博客添加自动发送 Webmention 的功能
使用 webmention.app 提供的命令行工具,在静态博客构建完成后扫描 RSS Feed。这个工具会扫描最新十个条目(也可以指定数目)中的 URL 并寻找那些提供了 Webmention 接收端口的 URL,然后向他们发送 Webmention。
命令行工具通过 NPM 提供,笔者使用 PNPM,使用如下命令安装。
pnpm install @remy/webmention
接下来需要指定一个源,如果使用的静态网站生成器能够生成 RSS/Atom 的 XML 文件最好。如果是 Hugo,可以用这条命令:
pnpm wm public/index.xml
默认情况下是 dry-run,只会扫描并找到 Webmention 的源和目标网址,不会发送,加上 --send Flag 才会发送;也可以用 --limit 指定扫描的文章数量,如果是 --limit 3 就只会扫描 Feed 中的前三条。
我的构建过程定义在一个 .sh 文件里,把这条命令添加到博客构建完成之后即可。
#!/bin/sh
git pull
pnpm build:uno:prod
hugo --gc --minify
pnpm pagefind --site public
pnpm wm public/index.xml --limit 3 --send
这样就能实现 Webmention 的自动发送了。
参考资料
在 Ghostty 中使用 SSH 的问题
问题描述
我的主力终端模拟器是 Ghostty,直接 SSH 到远程服务器可能遇到一些问题,比如无法打开 htop、使用 systemctl 查看服务的状态时会提示终端 not fully functional,一些颜色的显示也会有问题。
调查后发现原因来自 Ghostty 的 Terminfo(终端信息)。简单来说,Terminfo 是一种很老的格式,许多终端应用会通过读取 Terminfo 来确定终端的能力;如果应用程序不认识这个终端,可能会认为当前运行程序的终端缺少必要的能力,继而无法正常运行。
Ghostty 的终端信息是 xterm-ghostty,如果 SSH 到一台没有 Ghostty 的终端信息条目的机器上,可能会得到这样的提示:
missing or unsuitable terminal: xterm-ghostty
Error opening terminal: xterm-ghostty.
WARNING: terminal is not fully functional
解决方案
根据 Ghossty 的文档,解决方案有两个,我使用的方法是修改环境变量,把 TERM 设置为另一个被广泛支持的终端,比如 xterm-256color。可以在 .ssh/config 里这样写。
Host example
TERM=xterm-256color
这样远程服务器就会把 Ghostty 视作 256color,不会认为 Ghostty 缺少某些功能。
还有一种方法是把 Ghostty 的信息发送到远程服务器上。
infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x -
参考资料
加固 VPS:密钥替代密码
购置了 Contabo VPS,想要在服务器层面加固防护,遂做此笔记。
1. 配置 SSH 密钥登录
在本地生成一对 SSH 密钥对,使用 ed25519 算法而非老旧的 RSA。
ssh-keygen -t ed25519
密钥默认保存在 ~/.ssh/id_ed25519,可以更改位置。生成过后,需要将公钥放到服务器上,具体的原理在此不赘述。最方便的做法是使用 ssh-copy-id,如下:
ssh-copy-id <username>@<ip_address>
SSH 登录到 VPS,测试能否使用保存在本地的 SSH 密钥直接登录。如果在 ssh-keygen 时设置了 Passphrase,此时也需要输入 Passphrase 才能登录。如果觉得麻烦,可以使用 ssh-agent。
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519 # 之后会要求输入 Passphrase
然后再次 SSH 登录到服务器测试,看看能否不输入 Passphrase 直接登录。最后,要保存好 SSH 密钥,最好离线备份在移动硬盘里,或者重复上述步骤生成一个备用密钥放在别处。
2. 禁用密码登录和 Root 登录
密码登录很容易被暴力破解,能够用 SSH 密钥登录之后最好禁用密码登录。这一步要额外小心,不然有可能被锁在服务器外面。
修改服务器上的 SSH 配置:
vim /etc/ssh/sshd_config
找到 PasswordAuthentication(允许密码认证)和 PermitRootLogin(允许 Root 登录),删掉前面的 # 注释,把 yes 改成 no。保存,然后 sudo systemctl restart ssh。
银皮(Silver Skin)
烘焙后的咖啡豆中缝里可能有的褐黄色物质叫作「银皮」,因颜色令人联想到银色且质地薄脆而得名。研磨后的咖啡粉中也会包含银皮,由于质地轻薄,往往不会被磨得很细,会以较宽的形态混杂在咖啡粉中。

银皮主要由纤维组成,直接冲泡银皮会得到类似大麦茶和罗汉果的味道。由于质地很轻,很容易从咖啡粉里吹去。银皮对咖啡风味有影响,如果不喜欢,可以在研磨之后用嘴或吹风机吹去,一边吹一边搅动咖啡粉即可。缺点是会弄脏地面和桌面。
银皮的多少主要和烘焙度以及处理法相关。银皮在咖啡豆的二爆时会被碳化成灰,所在只经历了一爆的浅度烘焙豆中更常见。水洗处理法的咖啡豆也会有比日晒处理法的咖啡豆更多的银皮,因为日晒豆在处理时一直带着果肉,果肉将银皮很好地糖化了,剥去果肉后几乎不被保留。
截止 2026 年 1 月 26 日,我在做手冲咖啡的时候还会用嘴吹去银皮,并不是为了追求风味,而是因为强迫症。
参考
决定论
决定论是一种形而上学观点,有许多变体、许多不同的讨论,但大致来讲,决定论认为宇宙万物都只有可能按照一种预先决定好的方式发展,即一切都是既定的。决定论通常假设世界上一切结果都有其因,并且可以通过因果链追溯到一个最初的因,即第一因;如果观察者掌握被观察事物的所有信息,就能通过因推断出必定会发生的果,尽管这种推断可能无法实现。
不同的哲学家对于自由意志与决定论能否共存这个问题有不同的看法,由此分化出了相容论和不相容论两派。
舶来词
舶来词(Borrowed word),又称借词(loanword),指代完全或部分吸收自另一门语言的词汇。与借译(loan translation,亦称 calque)不同的是,舶来词通常直接采用源语言的形式或读音,而借译则是将源语言中的词翻译成目标语言后得到的新词。还需要区分的是,一些语言可能因为有相同的词源而导致拼写或读音相近,这是语言自然发展的结果,并不是文化交流的副产品。
舶来词很常见,例如幼儿园 kindergarten 实际上是德语,未婚夫 fiancé 实际上是法语。中文中的舶来词通常采取音译的形式,比如沙发(sofa)、罗曼蒂克(romantic)和巧克力(chocolate)等。舶来词从源语言进入目标语言之后,词义可能会发生变化,比如 café 在法语中原本指代「咖啡」,进入英语之后就用来指代「小餐馆」「咖啡馆」。
有趣的是,英语中的 calque(借译)是借词,而 loanword(借词)实际上是借译。
叙事层
在 SCP 基金会及相关写作社区中,有「叙事层」这个概念。一般人们会用「上层叙事」和「下层叙事」分别指代「叙事者及其所处的叙事」和「叙事者讲述的故事」,也就是「作者」和「作者笔下的故事」。实际上,叙事层可以无限划分,只要一层叙事中有人讲了新的故事,叙事层就往下延伸了。
一些 Meta 作品中,会出现「突破叙事层」,也就是「打破第四面墙」的情节——作者笔下的角色可以与作者甚至读者互动——比如《刺杀小说家》这部电影。
叙事层的概念被一些人挪用了,在没有打破第四面墙的作品中,也会有人用上下叙事层代指作者和作者笔下的故事。
联诵
联诵(liaison)是法语的语法规则之一。当前一个词以辅音结尾(通常是不发音的),后一个词以元音或哑音 h 开头,前一个词末尾的辅音会被激活,与后面的元音连接起来,使得语音连贯自然。
例子:
- les^amis
- vouz^avez
- petit^enfants
法语的联诵和英语的连读(linking sound)的区别在于:联诵是强制要求的语法规则,有正确和错误之分,而且联诵还会要求在发音时加入新的音素(即原本不发音的字母需要发音了);连读是自然的语音现象,连读的有无仅仅是口音的差别。
法语中不发音的字母
Les lettres muettes:
- 单词末尾的 P、D、T、S、X 和 Z
- 如:froid、trois、petit、deux
- 复数形式单词末尾的 S 和 X
- 如:châteaux、étoiles、voitures
图灵机和可计算性理论
图灵机(Turing machine)是一种理想的计算模型,是一种假想的由纸带、读写头和一定计算规则组成的机器,可以用来模拟任何可以计算的问题。你可以把图灵机理解为一种抽象的、通用的计算机。
图灵可计算性
如果一个函数可以被图灵机计算并得出答案,这个函数就具有图灵可计算性(Turing-computability)。从现实层面来讲,任何可以在计算机上模拟的问题都是图灵可计算的,只要这个问题可以由计算机程序给出答案而不会陷入死循环。
停机问题(Halting Problem)不是图灵可计算的,它要求计算机判断一个程序在给定的输入下会停机还是会陷入死循环。图灵机和任何计算机都不能解决它。
// 停机问题的伪代码表示
int H(procedure,Input);
int U(P)
{
while(H(P,P)){}
return 0;
}
图灵完备
如果一个系统(一系列操作数据的规则)可以模拟图灵机(Turing machine),就说它是图灵完备的(Turing-complete)。简单来说,具有图灵完备性的系统可以识别另一个系统的数据操作规则,图灵完备的计算机或计算机语言可以模拟另一种计算机或计算机语言的行为和用途。
- 几乎所有编程语言都是图灵完备的,这表示几乎所有编程语言都可以被用来重新编写由另一种编程语言实现的计算机程序,能实现其他语言也能实现的功能。如果一个编程语言能实现条件判断、循环和变量,它基本上就是图灵完备的。
- 标记语言(数据语言)不是图灵完备的,比如 JSON、XML、HTML 和 Markdown,因为他们只能描述数据而不能描述行为。
如果一个系统是图灵完备的,那它就可以被用来模拟另一个图灵完备的系统。也就是说,这两个系统是图灵等价的。
图灵等价
如果系统 A 可以模拟系统 B,而系统 B 也可以模拟系统 A,那么系统 A 和系统 B 就是图灵等价的。
所有图灵完备的系统都是图灵等价于图灵机的。
路灯效应
路灯效应是一种观察偏差(observational bias),意思是说当事人只在最明显的地方搜索样本,忽略了更难找的地方也可能存在的样本,进而造成了偏差。
路灯效应的名字出自一个笑话:
警察看见一个醉汉在路灯下找东西,便问他丢了什么。醉汉说他的钥匙不见了,让警察帮他一起找。两个人找了半天都没有找到钥匙,警察问他:“你确定你的钥匙掉这了吗?”
醉汉说:“不是,我在公园丢的。”
警察说:“那你为什么在路灯下面找?”
醉汉说:“因为这里有光!”
Source: Streetlight effect - Wikipedia
友情链接的翻译
友情链接似乎是中文万维网的产物,因为就目前为止,我还从未在任何类型的英文网站上发现友情链接这种东西。当我在维基百科中搜索友情链接并切换到英文维基时,我发现英文里的 Link Exchange 和中文里的友情链接并不是一个东西。
Webmasters register their websites with a central organization, that runs the exchange, and in turn receive from the exchange HTML code which they insert into their web pages.
站长在一个运营链接交换的中央组织登记他们的网站,然后轮流收到嵌入他们网页的 HTML 代码。
然而中文万维网语境下的友情链接是去中心化的,站长到别人的网站下留言,表明他已经将贵站的链接添加到自己的网站上了,希望贵站能够将自己网站的链接展示出来。英文里的 Link Exchange,更像是独立博客圈熟知的开往等类似的服务。
之前我看到有人把友情链接翻译成 Friendly Links(友好的链接),还和对方争论了一番,如今来看其实这个词没有正确和标准化的翻译,因为英文里就没有友情链接这个东西。
Password, Passcode, Passphrase
密码这个词一般会译作 Password,但 Passcode 这个词也很常见,有时还会有 Passphrase 的说法。这些词都有什么区别呢?
这些词的区别的确很微妙,很多时候可以当作同义词,所以中文基本上都译作「密码」,的使用场景有较明显的区别。
- Password
- 常用于用户登录界面、操作系统解锁
- 一串不定长度的字符串,用于验证身份,通常有较宽松的格式规范,例如长度要求和字符类型多样性的要求
- Passcode
- 常用于手机锁屏界面、密码锁、ATM 机等等
- 一串固定长度的数字,例如六位数字或四位数字,格式要求较为严格
- 也可以发送到邮箱或信息的一次性验证码
- Passphrase
- 常用于安全性要求较高的场合,如加密或解锁 PGP 密钥
- 由几个单词组成(就像一般的 phrase 一样),可读性强,容易被记忆;但通常较长,不容易被暴力破解
另一个常见的词是 Passkey,但 Passkey 的意思是「通行密钥」,而非密码。Passkey 是另一种不同于「用户名/密码」的身份验证方式,将 Passkey 储存到设备后可以通过指纹或面部识别等方式验证身份。
信息的组织结构
网状
知识管理圈子里最受推崇的笔记方法,往往是非线性的、网状的,通过双向链接、知识图谱或白板等形式将知识组织起来。这一方法的核心依据在于,人的大脑理解知识的方式更接近于这种网状结构。
网状结构最典型的呈现,其实是万维网文档的超链接。据说,在任意一个维基百科页面中点击第一个超链接,进入下一个页面后继续点击第一个超链接,如此往复,访客最终会来到「哲学」这个页面。维基百科上 95% 的页面都与哲学相关联。我认为这是因为维基百科致力于搭建一个完备的人类知识框架,除了要在每个条目下做出完备的阐释,还要将知识链接起来,而人类有 95% 甚至更多的知识都最初源自哲学这门古老的学科。
网状结构似乎非常强大,甚至能够呈现出整个人类知识体系的大概面貌。
从计算机的数据结构上看,网(network)即图(graph),树形结构(tree)也是一种特殊的图。树形的思维导图其实也可以归纳在网状结构当中,只不过是一种受限的网络,更适合组织特定主题的信息。
线性
如果不看超链接,单个万维网文档中的内容往往是线性的。一篇文章,从头到尾讲完了一个概念、阐述了一个观点。作者可能有网状的知识体系,但最终呈现的内容是线性的。
时间也是线性的,在这个语境下,用时间来定义线性可能要准确一些。一个视频、一期播客节目从开始播放到结尾,给观众和听众带来的体验就是线性的。其实阅读也是如此,从书页的开头读到结尾,就是一个线性的过程。再发散一些,用户从进入软件界面的开始到离开的过程、玩家从游戏开始界面到结束游戏的过程,都是线性的。简而言之,有明确开始和结束时间点的,都是线性的。
我认为只有线性的结构才能创造「体验感」。观看体验、收听体验、阅读体验、用户体验和游戏体验,都是前文所述线性呈现方式,从开始到结束,给个体带来的体验。个体在开始到结束的过程当中产生的感受和想法,甚至包括结束之后的回味,都是体验感的部分。
在数据结构中,网、图和树有路径一说,即将图中的多个节点按照特定顺序连接起来。在一个路径里,有确定的开始和结尾,所以路径是线性的。可以说,网状结构由若干线性的体验构成,产生的体验是不确定的。
碎片
互联网广泛普及之后,信息的碎片化已经是老生常谈了,并且往往是被批评的对象。
我认为碎片化的也是线性的,只不过从开始到结束的过程非常短。碎片化的另一个特征是连贯性的缺失,再加上短暂的体验使得个体有了更多的时间去摄取更多的信息碎片,个体最终获取到的是转瞬即逝的、无意义的、海量的、低质量的体验。
碎片化的信息可能是缺乏组织的信息,个体无法获得网状结构带来的宏观理解,也无法获得一般线性结构带来的完整体验。可以说,碎片信息只能给个体填充缺乏关联的不完整信息,但无益于建立深刻的理解。
工程
科学领域中涌现了大量以「工程」命名的学科,如材料工程、环境工程、软件工程,软件工程下甚至还有需求工程、提示词工程等学科。人们无论是看到汉语的「工程」一词,还是英语的 Engineering,应都会先想到摆弄机器零件和工具的人,但大部分工程师并非如此。那么「工程」一词到底是什么意思?
定义
简而言之,工程是科学原则的应用,或者构建的方法(manner of construction)。
译文:工程是使用自然科学和数学的实践,是解决技术问题、提高效率和产出率、优化系统的工程设计过程。
在现代语境中,工程常常与这些概念联系起来:设计(design)、构建(construction)、操作(operation)、开发(development)、制造(manufacture)和安全(safety)。一般来说,各种工程学科都包含上述概念的思想、知识和方法论。例如软件工程学科,就包含了软件设计方法、软件的开发模型、软件系统的安全性等。
工程学科是由这一系列工程原则(engineering principles)组成的。工程是对自然科学和数学的应用,除了科学方法和科学原则,工程学科也有自己的原则和方法,
词源
汉语中「机巧」一词,除了「用物理化学原理制造机械的技术」之意以外,还有「欺诈」的意思。在古法语中,engin 的意思是技巧、幽默、聪明,还有欺骗(deceitfulness)和耍花招(trickery)的意思。这可能与过去人们对新事物的不正确认识有关。在电话刚发明的时候,人们认为那是恶魔的发明,使用者会被闪电击中。
在拉丁语中,ingenium 的意思是「天生的特质」「与生俱来的能力」,英语单词 engineering 就源于此。晚期,ingenium 有了「战争机器」的意思。在古法语中,engigneor 的意思就是「制造战争机器的人」;engine 在一开始也特指在战争中使用的机器装置。这显然也与历史有着很大关联。
从一开始的不被理解,被当作骗术,到后来广泛应用于战争,成为一门有倾向的技术,现在,工程一词已经成了「用科学解决实际问题」的学科的统称。
Source: [Search ’engineering’ on etymonline](Engineering - Wikipedia
简单曝光效应
简单曝光效应(Mere-exposure Effect)也叫熟悉感原则,是一种心理现象,指的是个体对某人某物越熟悉、曝光的次数越多,个体就越容易发展对该人该物的喜欢或厌恶。
简单来说,越熟悉的事物越容易产生好感,一开始讨厌的人或事见得越多则越讨厌。
简单曝光效应的适用范围很广,除了人,还包括词、汉字、画、面部图像、几何图形和声音。
Source: Mere-exposure Effect - Wikipedia
错失恐惧症
错失恐惧症(Fear of Missing Out,也称 FOMO),是一种焦虑情绪,由自身未能参与某项社交活动而导致。当个体意识到自己可能错过了有意义的事情、没办法获得他人的关注、可能错过某个机会的时候,就可能产生这种持续性焦虑。
错失恐惧症可以被理解为「置身事外的恐惧」。在互联网时代,人们的社交方式变得泛化,由于任何事情都可以与社交相关,人们变得更容易焦虑。不了解某个网络热梗、不知道某个理论、不了解某一方法论,进而无法与其他人谈论此事,在网络媒介上被众多网友置身事外,让错失恐惧产生的频率变高了。
错失恐惧症可能导致不健康的上网习惯(频繁查看消息、刷新信息流……),进而让个体无法全情参与现实生活中的社交,也会导致注意力不集中,难以专注等问题。
Source: 错失恐惧症 - 维基百科,自由的百科全书
自我实现的预言
自我实现的预言,在社会心理学称「自证预言」(Self-fulfilling prophecy),是一种社会心理学现象——某件事情如某人预期和预言的那样发生了,有可能正是因为个体的预言和信念潜移默化地改变了个体的行为,即预言之所以成真,正是因为个体相信这一预言。
自证预言指出,人的信念是会影响行为的。信念影响行为的过程常常发生在潜意识和不自觉中,所以不易被察觉。
Source: 自证预言 - 维基百科,自由的百科全书
宏
计算机中,宏(macro,也叫「巨集」)的概念很常见,出现在 Excel 和 Word 等办公软件当中,C 语言(#define)、Lisp 语言等编程语言中也有宏,键盘似乎也有宏的概念。这个词即使是在英语中(macro)也显得抽象和模糊,宏到底是什么意思?
简单来说,宏是将短小的命令展开为一系列命令的过程,一般是为解释器、编译器设定的一系列与处理规则,用于进行模式替换。宏的概念也被拓展到了编辑器和键盘映射当中,所以有了键盘宏和 Excel 中的宏。
最常见的宏用于「文本替换」,如 C 语言的宏。
#define N 100
在编译器的预处理阶段,源代码中的 N 就会被替换(或者说展开)为 100。对于 Lisp 语言和其他更强大的宏编程语言,宏展开还能被应用在代码上。宏展开也不总是死板的文本替换,也往往是模式替换,一些笔记软件和效率工具提供的代码段(Snippets)功能也类似于宏。
另一种宏可被视为「快捷指令」,Excel 中录制宏用于之后快速执行某个操作的用法,就属于这种。将一个小的指令自动展开为一系列指令。
总而言之,宏被用于自动化、简化和复用操作。
向内思考与向外思考
从荣格心理类型的「内倾」和「外倾」态度来分析「思考」的两种形式,或许可以分为「向内思考」和「向外思考」。
课题分离
课题分离是阿德勒心理学中的一个概念,是阿德勒认为的、人际交往中应当遵守的法则。要区分一件事是谁的课题,可以思考「这件事情最终影响的是谁?」,例如孩子的学业情况最终影响的是孩子自己,而非父母,那么读书这件事情就是孩子自己的课题,父母原则上不应该干涉。
在人际交往中,分清楚每件事情是谁的课题,并不干涉其他人的课题,就叫做课题分离。阿德勒认为人际交往中的一切问题都是由于干涉其他人的课题导致的。阿德勒认为「可以带马儿去河边,但不能强迫马喝水」。教育子女是父母的课题,学业是孩子的课题;提供物质基础和鼓励是父母的课题,这不一定要干涉孩子自己读书的课题。如果能在人际交往中做到课题分离,人与人之间的冲突就会大大减少。
Source: 《被讨厌的勇气》[日] 岸见一郎
投射
投射(Projection)是一种心理防御机制,指人们常常将自己的不安等情绪代入到别人身上,下意识地否认自身的不良动机、欲望、行为,并将其怪罪于外界。
这一点在许多霸凌者身上很常见,一些人认为霸凌者欺负弱小的行为,实际上反映了他们对自身能力的不安,因为不想被认为是弱小的,所以将「弱小」这一形象强加在别人身上,以此来证明自己的强大。另一个例子是,如果一个人骂你「你这样以后只能孤独终老」,那很有可能说明他自己很害怕「孤独终老」。
简单来说,投射就是将自己的一部分属性设定在别人身上,并且会将自己投射的那部分自我误认为是别人而非自己,通常是为了达成某种自洽。
Sources: Psychological projection - Wikipedia
世界语言的分类
语言往往能通过彼此之间在语音、语法和词汇等方面的相似性进行分类,常见的分类体系是基于语系(language family)、语族(language subfamily)和语支的。每个语系往往有一个共同的原始语言(proto-language)。
以下是一些常见的语系和语族,这种划分呈树形结构。
- 印欧语系
- 日耳曼语族
- 英语
- 德语
- 罗曼语族(拉丁语族)
- 法语
- 西班牙语
- 葡萄牙语
- 意大利语
- 斯拉夫语族
- 俄语
- 波兰语
- 日耳曼语族
- 汉藏语系
- 汉语族
- 官话(普通话)
- 粤语
- 闽语
- 藏缅语族
- 汉语族
- 日本-琉球语系
- 日语
- 琉球语
需要注意的是,这种语言的分类体系似乎没有绝对的标准,学界也有一些争议。比如,一些学者认为日语应该被归类到汉藏语系下的藏缅语族,而非日琉语系;还有一些学者认为日语属于阿尔泰语系,而主流学术界则不认可这个语系存在。
维基百科中也经常混用语族和语系两个词,导致我难以构建一个标准的世界语言体系。
了解这种分类方式,最主要地是可以看到语言之间的联系。深入理解这种联系的一种方式是了解每个语系的原始语言——印欧语系的原始语言是原始印欧语(Proto-Indo-European, PIE),尽管这是一门根据印欧语系下各语言的特色构建出来的假想语言,但仍然是进行词源学研究的重要工具,印欧语系下不同语言中表达相似意思的词汇,很多都被认为有着相同的 PIE 词根。
Sources: 日本-琉球语系 - Wikipedia、原始印欧语 - Wikipedia、Language family - Wikipedia、 语言系属分类 - Wikipedia
原语
原语(primitive)是计算机中不可被中断的一段机器指令,常见于操作系统中的进程调度,用于实现同步(synchronization)。一个操作需要用原语实现,常常是因为这种操作一旦被中断,就会发生非常严重的错误,所以不允许中断。
原语的「原」可以理解为「原子」(Atom),执行原语就是在执行一个原子操作(atomic action)。
要实现原语,有两种方式:
- 禁用中断,这种操作在多核处理器上非常低效。
- 专用机器指令,在多核处理器上实现同步,需要在硬件层面实现一套能够进行原子操作的机器指令(atomic instructions);例如
test-and-set用于操作内存中的单个字(word),compare-and-swap用于交换内存中的两个字。
Sources: 《操作系统 精髓与设计原理》[美] WILLIAM STALLINGS、Synchronization (computer science) - Wikipedia
主导功能与辅助功能
MBTI 理论对荣格的心理类型做出了拓展,指出荣格仅仅使用一种心理功能和一种心理态度确定心理类型的局限性。为了让荣格的理论对普通人也发挥实用价值,MBTI 理论区分个体的主导心理功能和辅助心理功能。
主导心理功能是个体最偏好使用的心理功能,往往也是发展最全面的心理功能,也就是说,行为决策时,个体更倾向于也往往更擅长使用主导功能。
辅助功能是个体第二偏好使用的心理功能。通常情况下,如果主导功能是外倾的,辅助功能就是内倾的,反之亦然。MBTI 理论认为,辅助功能维持了个体外倾和内倾的平衡,当个体专注于内部世界时,就可以用辅助功能应付外部世界的任务。
例如,ESFJ 的主导心理功能是 Fe(外倾情感),意味着 ESFJ 偏好用自身的价值取向对外界做出判断;ESFJ 的辅助心理功能是 Si(内倾感觉),意味着 ESFJ 在使用情感功能处理外部世界时,感觉功能可以用来打理内部世界,用感官关注自己的状态。
Sources:《天生不同》[美]伊莎贝尔·迈尔斯
感知与判断偏好
MBTI 对荣格的心理类型做出了拓展,添加了「感知与判断」的偏好,即个体更偏好使用感知功能还是判断功能。感知功能(Perception)和判断功能(Judgment)是荣格心理类型的两大心理功能。
感知与判断偏好在 MBTI 中用四个字母中的最后一个字母表示,用 P(感知功能)和 J(判断功能)区分。需要注意的是,P 和 J 只表示个体在关注外部世界时更偏好使用的心理功能。
P-J 维度可以用于确定个体的主导功能与辅助功能。对于 ENFP 来说,P 表示个体在关注外部世界时偏好使用「感知功能」,而 ENFP 偏好的感知功能是 N(直觉),那么 ENFP 的主导功能就是外倾直觉(Ne),辅助功能则是判断功能 Fi(内倾情感)。
对于内倾型个体来说,P-J 维度只是间接地反映了其主导功能,因为 P-J 只表示个体对外部世界偏好使用的心理功能。例如,ISTJ 偏好使用的是判断功能,也就是思维(T),那么 ISTJ 的辅助功能就是 Te,主导功能则是 Si。对于内倾型个体来说,主导功能一定是内倾的,因为他们总是更关注内部世界。
Sources:《天生不同》[美]伊莎贝尔·迈尔斯
荣格心理功能
《心理类型》是德国心理学家荣格在 1921 年发表的著作,介绍了四种心理功能和两种心理态度,功能和态度又可以组合成八种心理类型,现在也俗称「荣格八维」。
四种心理功能又可分为感知功能和判断功能,两类功能各有两种功能。
- 感知功能(Perception)
- 感觉(Sensing) 倾向于使用感官认识世界,关注客观事实和能够被观察到的东西。
- 直觉(iNtuition) 倾向于关注可能性,善于用无意识快速、跳跃式地处理信息,不太关注表象。
- 判断功能(Judgment)
- 思维(Thinking) 关注逻辑判断,在乎对错。
- 情感(Feeling) 关注价值取向,在乎重要性。必须要注意的是,情感作为判断功能也是理性的,荣格认为感知功能才是非理性的。
两种心理态度即内倾(Introverted)和外倾(Extraverted)。内倾表示个体在使用感知功能或判断功能时,更关注内部世界的抽象概念和想法,外倾则更关注外部世界的具体事物和现实情况。
组合而成的八种心理功能,在互联网上常常被人们用一种字母组合的格式表达:Ne 代表「外倾直觉型」,Ni 代表「内倾直觉型」,Se 代表「外倾感觉型」,Si 代表「内倾感觉型」,Te 代表「外倾思考型」,Ti 代表「内倾思考型」,Fe 代表「外倾情感型」,Fi 代表「内倾情感型」。
Sources: 心理类型 - Wikipedia、《天生不同》[美]伊莎贝尔·迈尔斯
社会原子论
社会原子论(Atomism)描述了一种社会发展倾向,具有「社会原子化」倾向的社会由一群优先考虑个体利益,并且极大程度上能够自给自足的个体组成,这些人就像相互分离的原子一样运作。
社会原子论认为,个人拥有部分高于社会的权利,人们在大部分情况下优先考虑自己,能保证个体的生存和整个社会的共存。
Source: Atomism (social) - Wikipedia
八条对话规则
公民论坛(捷克语:Občanské fórum)是1989年捷克斯洛伐克天鹅绒革命中成立的政党。其领导人为论坛提出了八条对话规则:
- 对话的目的是寻求真理,不是为了斗争;
- 不做人身攻击;
- 保持主题;
- 辩论时要用证据;
- 不要坚持错误不改;
- 要分清对话与只准自己讲话的区别;
- 对话要有记录;
- 尽量理解对方。
我认为这些规则适用于大多数讨论,无论是现实中发生在群体内的对话,还是互联网论坛或是群聊,这八条规则都值得参与者遵守。在制定社区规则时,这八条规则可以作为参考,甚至可以直接拿来用。
耦合、内聚和解耦
在软件工程中,耦合性(Coupling)度量程序各模块之间信息或参数的依赖程度。耦合程度高的系统会有如下问题:
- 如果一个模块需要修改,与之关联的模块也需要随之修改,造成修改的不便
- 由于一个模块依赖多个模块,模块难以被组合
- 由于一个模块依赖多个模块,模块难以复用
相对的是内聚性(Cohesion),指模块内部的凝聚程度。低耦合往往意味着高内聚,「高内聚低耦合」是软件工程领域常见的「好软件」的标准。
解耦(Decoupling)即降低耦合性,提高内聚性,同时模块被复用和组合的能力也会提高。
全景监狱
全景监狱(panopticon),也叫圆形监狱和环形监狱,是一个哲学概念。
设想一个圆柱形的建筑,内部的墙面上全是牢房,而内部圆的正中央,是一个监察室。从监察室中能看到外部,但外部的囚犯们看不到监察室里是否有人。因为囚犯不知道自己何时会被监视,所以只好假设自己时时刻刻都被监视着。
全景监狱原本是英国哲学家边沁对监狱建筑形式的一种设想,后来,福柯将现代权力结构比作全景监狱,提出了「泛视主义」。你可以将全景监狱理解为社会纪律下的自我规训,这种规训产生于一个可能存在也可能不存在的观察者。
nihil sub sole novum
拉丁谚语「nihil sub sole novum」的意思是「日光之下,并无新事」。这句话出自通俗拉丁语版本的《圣经》,传道书 1:9,这一节的标题叫做「凡事都是虚空」。
人的一切劳碌,就是他在日光之下的劳碌,有什么益处呢?
一代过去,一代又来,地却永远长存。
日头出来,日头落下,急归所出之地。
风往南刮,又往北转,不往地旋转,而且返回转行原道。
江河都往海里流,海却不满;江河从何处流,仍归还何处。
万事令人厌烦,人不能说尽。
眼看,看不饱;耳听,听不足。
已有的事,后必再有;
已行的事,后必再行;
日光之下,并无新事。
岂有一件事人能指着说:“这是新的”?
哪知,在我们以前的世代早已有了。
已过的世代,无人记念;将来的世代,后来的人也不记念。
这里的观点与后世的虚无主义(Nihilism)有相似之处。后来,尼采在《查拉图斯特拉如是说》中提到了类似的「永恒轮回」的观点。


简言而止,「日光之下,并无新事」表达了「历史的循环往复」与「一切都是虚无和无常的」两种观点。==在时间的长河中,人类的一切行为都显得渺小和无意义,而人类以为自己发现的新事物,实际上已经在漫长的过去中被发现了无数次了==。
Anthropomorphic
意为「拟人的」,可以表示一种手法,也可以表示一种设计风格。在这种设计风格当中,你常常能见到穿着人类服装且拥有类人形体的动物。和 Furry 不同的是,Anthropomorphic 是一种美学,而且往往带有复古元素。

词源学上,anthropomorphic 还有几个构词略有差异,但意思相似的兄弟,即 anthropomorphism(名词)和 anthropomorphist(表示人的名词),他们都是 anthropomorphous 的变体。anthropo- 表示「人」,同源的词还有 anthropology(人类学)和 anthropophobia(恐人症);morphē 的词源未知,意思是「形式」。
anthropomorphous 表示在形态上与人相似的,而衍生而来的 anthropomorphic 表示具有人行为、情感和语言能力等。我还想到了 humanoid(类人的)这个词,写怪谈小说时经常用,这个词与 anthropomorphous 很相似,不过 humanoid 常用来指代机器人、外星生物和鬼怪,而 anthropomorphous 其实不常用,因为它有点文绉绉的。