普通视图

发现新文章,点击刷新页面。
昨天以前TimochanのBlog

两年三站:腾讯云、百度,以及我的 PostgreSQL 之路

2026年4月5日 23:38
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/46

最近偶尔会回头想想过去两年的事情,感觉像是几段完全不同的生活被硬生生拼在了一起。

最早是在腾讯云实习。那时候做的是 SRE,主要负责 Kubernetes 集群的运维。对当时的我来说,那算是第一次真正踏入基础设施的世界。以前在学校学操作系统和网络,大多停留在理论层面,到了真实环境才意识到,这些系统每天都在运转着:集群调度、监控告警、自动化运维、服务稳定性,这些都是工程,而不是文档里的概念。

腾讯云的团队对实习生保护得很好,系统成熟、流程规范,新人很难犯大错。但也正因如此,真正能放手去做事情的机会并不多。那段时间更像是工程启蒙,让我第一次真正接触到 SRE 和基础设施的世界。

后来去了北京,在百度实习。同样是 SRE,同样面对 Kubernetes 集群,但体验完全不同。很多人把百度称为互联网的"黄埔军校",实习期间多少能感受到这种工程文化。Mentor 很愿意放权,很多事情会直接交给你做,出了问题再一起复盘分析。这种方式让人成长很快,因为你必须真正理解系统是怎么运作的,而不只是站在旁边观察。

可惜最后因为一些个人原因,没能继续留在北京。说实话,那座城市本身也一直让我提不起多少快乐。所以有点讽刺的是,我在百度最快乐的两个时间点,是入职的时候和离职的时候,入职的时候是因为对未来有期待,离职的时候,是因为终于要离开北京。每天从昌平站往西二旗通勤,我总会有一种奇怪的感觉:昌平线像是一辆巨大的罐头车,每天准时把一车一车的血肉送进城市中心的工厂:地铁是传送带,人群是原料,晚上再被整批运回来。那种生活节奏,很难真正喜欢得起来。

离开北京之后,我回学校准备毕业。那两个月几乎都在宿舍肝毕业设计,每天写代码、跑测试、改论文,偶尔去实验室坐一会儿,参加学弟们的组会,聊聊他们的研究方向。节奏突然慢了下来,像是从一个高速运转的系统里跳出来,才终于能听见自己的呼吸。

毕业之后,我进入了一家做 PostgreSQL 生态的数据库公司,也是从这里开始,我真正走上了 DBA 这条路。面试时岗位就是 DBA,但说实话,当时的数据库经验并不算扎实——很多概念理论上知道,真正面对生产环境却是另一回事。公司很愿意让新人直接参与项目,一边做一边学,从最开始写 SQL 还有些生疏,到慢慢能分析执行计划、做查询优化、独立排查问题,能力就这样一点点积累起来。

也是因为这份工作,我来到了南京。这里的生活节奏和北京完全不同,没有噩梦一样的通勤,也没有每天被时间追着跑的感觉。人可以慢一点,也可以更专注地做事情。

现在除了 DBA 的工作,我也做一些全栈开发。其实早在 2022 年,我就开始用 AI 辅助开发,但那时候的工具能力很有限,上下文关联很差,更多只能充当重复代码的搬运工。没想到短短三四年,这些工具已经彻底改变了软件开发的形态。写代码、查资料、做设计,很多工作都可以和 AI 一起高效完成,Web Application 的开发流程在被重新定义,就连游戏开发也感觉在悄悄发生变化。

不过基础软件似乎有些不一样。数据库、操作系统、分布式系统,本质上还是 infrastructure。AI 可以帮助工程师开发和运维,但底层系统本身不会被替代,更多是进入了一种"AI 助力"的阶段。某种意义上,我挺庆幸自己还扎在这个领域,既能用 AI,也没有离开核心系统。

回头看,这两年给我的感受不只是技能的积累,还有一个更微妙的东西:对时间和成长的感知。快节奏、高压力的环境里,你能学到很多,但也容易迷失;慢节奏、可控的环境里,你会更清楚地知道自己想要什么,也能更从容地选择下一步。生活和工作,本质上都是在找自己的节奏。

与此同时,技术的发展也在提醒我一件事:我们只是站在历史某个节点上的人。三四年前 AI 只能做重复搬运,如今已开始重新定义开发流程;基础软件依然稳固,但周围的世界在飞速变化。能跟上节奏的人,才能把握机会。过去两年,从 SRE 到 DBA,我也算是一直在努力跟上这个节奏。

如果再过几年回头看,这两年也许只是很普通的一段经历,但对现在的我来说,它们却是一个真正的起点,一个让我看清自己,也看清世界变化方向的起点。

看完了?说点什么呢

从一加到小米:从「TEE 损坏」到「TEE 自身完备」

2026年3月15日 14:00
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/any_pen/from_oneplus_to_xiaomi

两串指令干碎一加魂,长官我是小米人✋😭🤚

原本我其实更偏向一加。

原因很简单:一加的 BootLoader 解锁一直相对省心。对我这种本来就喜欢折腾系统的人来说,设备能不能顺利解锁,几乎会直接影响购买意愿。

反过来看,小米这几年在解锁上的门槛确实高了不少:

  • 要申请
  • 要等待
  • 甚至还要小米高考

对只想折腾系统的人来说,这套流程多少有点劝退。所以一开始,我其实是打算继续买一加的。

结果后来情况变了。

小米这边突然爆出了新的解锁漏洞,相当于把原本最麻烦的门槛直接绕过去了。再加上这一代机器价格确实很香,3899 拿下旗舰机,几个因素叠加下来,我最后还是入手了 Xiaomi 17 标准版 16+512。

关于漏洞细节,可以去看 3.8 解锁节漏洞解析深度解析小米 8e5 系列漏洞解锁 BL 原理

准备动作

我最后选的是酷安上 白羊唐黎明 的官改 ROM,版本是:3.0.301.0

这个包并不是直接拿来刷就行,它需要配合指定的官方底包:3.0.44.0

所以整套流程的第一步,不是直接梭哈官改,而是先把官方底包刷进去

和一加类似,一加那边阿木大侠维护了一个一加 ROM 站,可以直接检索下载一加的 ROM,小米这边也有 ,可以快速检索 ROM。

刷机工具选择的是 MiFlash,看起来足够简单? MiFlash 本身是 Windows 下的线刷工具,常见做法就是搭配 Fastboot 固件 使用。它也自带一些驱动,正常情况下装好后就能直接识别设备。

不过这里有个我自己踩过的坑,必须单独提一下:

MiFlash 最好放在中文 Windows 环境下运行。

如果你用的是其他非 ZH-CN 的语言环境,可能会碰到一些莫名其妙的报错。表面上看像是驱动问题、路径问题,甚至像底包有问题,结果最后一排查,根源其实是环境。所以如果你想尽量少走弯路,直接在中文环境下操作会省事很多。当时我甚至都开始怀疑 mirom 下载的包有问题了。

刷官方底包

先把下载好的 Fastboot 线刷包 解压到任意目录。

然后让手机进入 BootLoader

这一点我想刻意讲清楚,因为很多文章喜欢笼统地写“进入 Fastboot 模式”,但这个说法其实非常模糊,如果是一加转小米,更容易把人带偏。

在小米设备上:

adb reboot bootloader

如果不用命令,也可以关机后按住:音量下 + 电源键 进入 BootLoader 界面。

之所以要写得这么细,还有另一个原因:不同厂商对“Fastboot”这个词的使用场景并不一致。比如在一加上, Recovery / fastbootd 界面里本身也能刷 Fastboot 包,所以“Fastboot”这个词本来就不够精确,因为存在用户态的 Fastboot -> Fastbootd,也存在解锁后的 BootLoader Fastboot。统一叫 BootLoader,反而最不会出歧义。 进入之后,打开 MiFlash,流程很标准:

  1. 点击 Driver 安装驱动
  2. 点击 刷新设备,确认手机已经被识别
  3. 选择刚刚解压好的底包目录

这里最关键的一步一定要记住:

右下角选择「全部删除」,不要选「删除并回锁」

如果这里手滑回锁,会变得麻烦,你还得重新利用漏洞解锁,44 版本还好,还可以利用漏洞解锁。

不得不提 miflash 的默认选项真的有点大病。

这不是简单的“麻烦一点”,而是真有可能直接把后路堵死。如果你真的想回锁了,出于保留退路的考虑,建议是走降级回锁这条路,永不更新,这样才还有继续解锁的机会,所以这一步千万不要心存侥幸。

确认没问题之后,点击 Flash,接下来耐心等它刷完即可。

刷官改 ROM

底包刷完后,先让手机正常开机。快速走完初始化流程,确认都没问题之后,再重新进入 BootLoader,把官改包解压出来。

如果包里附带驱动,那就先把驱动装一下。接着一般直接双击它自带的刷机脚本,剩下的就是等进度条跑完、手机自动重启。

到这里,官改 ROM 基本就刷好了。

Root:我选择了SukiSU-Ultra

官改包里其实自带了 KernelSU,但我没有沿用这一套。我选择的是 SukiSU-Ultra。 至于原因,其实非常朴素:主要是 SukiSU-Ultra 的图标好看,没别的。

我的做法也很直接:

  1. 从官改包里拿出来 init_boot.img ,adb push 到手机里面
  2. 让 SukiSU-Ultra 对 init-boot 进行修补
  3. 把修补后的镜像刷回设备
  4. 直接切换到 SukiSU-Ultra

刷入命令是

adb reboot bootloader
fastboot flash init_boot_ab .\kernelsu_patched_20260314_152108.img

Root 定下来之后,后面的模块环境就比较清晰了。Meta Module 用的是 Hybrid Mount
这种东西平时不一定最显眼,但底层挂载方案其实会直接影响整体体验,所以我这里干脆一步到位,直接用了它。

Play 完整性与环境处理:TEE 模拟器组合拳

这一部分,我最后采用的组合是:

  • ZygiskNext
  • TEE Simulator-RS
  • tricky-addon-enhanced
  • Integrity-Box

项目地址:

为什么不用 Tricky Store

原因很简单:Tricky Store 现在已经闭源了。 对我来说,这就不再是最优选。

而且从 Integrity-Box 的项目说明来看,它本身的前置条件就是:

  • Official Tricky Store / TEE Simulator 二选一
  • ZygiskNext / ReZygisk 二选一

所以我的选择非常明确: ZygiskNext + TEE Simulator + Integrity-Box

模块刷入顺序

我的顺序是:

  1. ZygiskNext
  2. TEE Simulator
  3. Integrity-Box

刷完之后重启即可。

顺带一提,ZygiskNext 本身的定位也很明确:它是 Zygisk 的独立实现,主要给 KernelSU 等环境提供 Zygisk API 支持,用来替代 Magisk 内置的 Zygisk。这一点对于后面整套模块的兼容性很关键。

而 Integrity-Box 则更像是一个总控型工具:既管 Play Integrity,也管 Keybox 实现,还会处理 target、keybox、认证状态、系统清理等一整套东西。它自己 README 里写得也很直白,本质上就是一个 Play Integrity 与系统环境管理工具箱

关于 TS 模块的 WebUI,我选择了 Tricky Addon Enhanced,因为它能自动把新安装的 App 添加到 TEE Simulator 的 Target 中,避免我去手动设置。

TEE 完整

如果只看表面,这一套主要解决的是这些问题:

  • Play 完整性
  • 系统环境信号
  • Root 隐藏
  • 应用对 BootLoader 解锁状态的检测

但如果只把重点放在“能不能过完整性”,其实还不够。对我来说,这次折腾里真正有意思的地方反而是:TEE 本身是不是完整的

以前在一加上,BootLoader 解锁之后经常会碰到一个很典型的问题:TEE 损坏 这是高通给的机制,解锁 BL 以后 TEE 假死,OPPO 的做法是切换密钥槽,这个槽的密钥不完整,三星就更离谱,直接熔断,没办法玩,小米比较特殊,魔改了 TEE 是 miTEE,解锁后不掉。

系统当然还是能刷,Root 当然也还能做,甚至可以折腾得很深。但底层信任链一旦断掉,很多事情就总有种“补出来的感觉”。

这次换到小米上,用我现在这套方案之后,最让我满意的点反而不是“完整性能不能过”,而是:TEE 本身就是完整的

这件事对我来说,比单纯看到几项检测变绿更有意义。 也正因为这样,这篇文章标题里写的 “从 TEE 损坏到 TEE 自身完整可用”,其实比“刷机成功”更接近我这次折腾真正想表达的东西。

HyperCeiler

好像叫做西米露?这个我也很喜欢,定位上有点像 ColorOS 的 Lucky Tool,但我自己会更偏向它一点;这样说有点倒反天罡,应该是先有西米露,后有 Lucky Tool 类似的工具。

它主要是拿来改:

  • 系统行为
  • 界面逻辑
  • 细节设置

属于那种刷完之后基本会第一时间装上的工具。

总结:为什么我执着于「TEE 完整」

这次折腾下来,我始终在意的一件事,其实不是“检测能不能过”,而是:**TEE 本身到底是不是完整的。**很多人玩 Root、模块和完整性环境,最终目标往往很明确: 把各种检测绕过去。 比如:

  • Play Integrity 过了
  • 国内银行 App 能正常打开
  • 国内钱包功能可以使用

对不少人来说,只要结果达成,中间到底是怎么实现的,并没有那么重要。但这是一场猫捉老鼠的游戏,检测与绕过是一直在对抗的。我这次更在意的,反而是另一件事:TEE 到底是真实可信,还是只是伪装出来的

原因也很简单:Android 的信任体系,正在发生变化。

本地 Keybox 的时代,正在结束

以前 Android 设备的硬件认证,在很大程度上依赖 本地 Keybox

设备出厂时,会在 TEE 中写入一组密钥。当应用发起 硬件级 Attestation 时,TEE 就会使用这些 Keybox Key 来签名并证明一些关键信息,例如:

  • 设备型号
  • Boot 状态
  • Verified Boot 状态
  • 系统完整性

所以过去很多“过检测”的方案,本质上都是这一套思路:

拿到泄露的 Keybox
↓
导入到设备
↓
伪装成官方设备

这一套在过去几年里确实非常流行,也确实有效。但问题同样很明显:对于 Google 来说,Keybox 一旦泄露,就很难彻底回收。

如果 Google 想吊销某个泄露的 Keybox,整个流程其实很复杂:

  • 收集泄露证据(报告给对应的 OEM,说明有吊销的必要性)
  • 更新吊销列表
  • 推送到系统组件
  • 等设备更新生效

这个过程周期很长,而且很难做到真正实时。也正因为如此,Google 一直在推进本地 Keybox 信任到云端的 RKP 信任

Google 正在全面转向 RKP

现在 Google 正在逐步推进新的体系:Android Remote Key Provisioning(RKP)

RKP 的核心思路很直接: 设备不再长期持有 Attestation Key,而是改为通过 Google 云端动态下发。

简化后的流程大致是这样:

设备 TEE
↓
向 Google RKP 服务请求 Attestation Key
↓
Google 下发短期证书
↓
TEE 使用该证书完成硬件 Attestation

这里有两个非常关键的变化。

1. 证书是短期的

RKP 下发的不是长期固定证书,而是短期证书。典型有效期通常只有:两周。到期之后,设备需要重新向云端申请新的证书。

2. Google 可以更快吊销

如果 Google 发现某个设备密钥泄露、异常,或者某条链路存在风险,那么它不再需要沿用过去那套笨重的 Keybox 吊销流程。它只需要在云端:吊销对应设备的 Attestation Key。这样一来,设备去做 TEE Challenge 请求的时候,直接认定是失败。

这对“伪装方案”意味着什么

这件事带来的变化,其实已经非常明显了。过去的逻辑大概是:

泄露 Keybox
↓
导入设备
↓
长期稳定使用

而未来更可能变成:

没有 Google 云端签发的有效 Attestation Key
↓
硬件认证直接失败

换句话说: 依赖泄露 Keybox 来伪装 TEE、伪装官方设备的路线,未来只会越来越难走。

过去那种“拿到一套东西,导进去,长期稳定骗过检测”的思路,在新体系下未必还能持续成立。

我在 OnePlus 上遇到过的真实情况

这一点,其实我在 OnePlus 上已经切身遇到过了。

有时候即使你已经做到这些:

  • Play Integrity 全绿
  • 环境隐藏得很彻底
  • Root 检测基本全部绕过

Google Wallet 依然有可能识别出设备状态异常。

最典型的提示通常就是:

This device doesn't meet security requirements

也就是说,哪怕系统层面的环境已经“看起来很干净”,Wallet 依然可能判断这台设备没有通过官方安全认证

类似的问题,在一些海外银行 App 上也能看到。

甚至还有一种说法是:**抖音的设备安全检测级别非常高。**一些逆向分析的结论甚至认为,抖音在设备检测上的强度,可能还高于部分银行 App。

当然,具体实现细节外界很难完全确认,但有一点基本可以确定: 越来越多的 App,正在直接依赖硬件 Attestation 的结果。

这意味着,单纯“把表层环境伪装干净”,未来未必还够。

为什么我更在意「TEE 本身完整」

也正因为这样,这次我在小米上的思路,其实和以前不太一样。我不太想继续走这种路线:

伪造环境
↓
伪造 Key
↓
尽量骗过检测

我更希望做到的是:

TEE 本身完整
↓
硬件 Attestation 正常
↓
系统只是 Root

换句话说就是:Soter Key 是正常的,能够正常使用 WeChat Pay 的指纹,而并非使用模块代替输入密码

这也是为什么这篇文章标题里,我会专门写一句:从「TEE 损坏」到「TEE 自身完备」

对我来说,这比单纯“过了完整性检测”更有意义。
因为如果未来 Android 的认证体系继续全面转向 RKP,那么现在很多流行的绕过方式,迟早都可能逐渐失效。

而真正更稳定、也更有长期价值的方案,往往反而是最朴素的那一种:

  • 设备本身可信
  • TEE 完整
  • 信任链存在

至于剩下的折腾,无非只是系统层面的修改而已。

展示

引用

看完了?说点什么呢

都 2025 年了,还不试试 PostgreSQL?

2025年11月8日 23:31
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/study/mysql_vs_postgresql_correctness_not_convenience

一、前言:MySQL 已经成了惰性的象征,而非技术的选择

MySQL 曾经是互联网时代的功臣,它简单、便宜、够快。但到了 2025 年,它更多代表的是行业的惯性与保守。人们继续用它,不是因为它先进,而是因为它“还活着”。然而,如果你把目光放到数据库设计层面,就会发现:MySQL 根本不是一个完整的关系数据库,而是一个带 SQL 外壳的存储系统。

它的事务,只覆盖了一部分数据; 它的 ACID,是有注脚的; 它的优化器,是随缘的; 它的触发器,是残废的; 它的约束,是可关闭的。

MySQL 靠“够用”生存; PostgreSQL 靠“正确”延续。

两者之间的区别,不是实现多少特性, 而是——是否尊重数据库科学本身。


二、优化器:MySQL 靠猜,PostgreSQL 靠算

MySQL 的查询优化器还停留在上个世纪。它基于规则,不基于代价。

CREATE TABLE orders (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id INT,
  status VARCHAR(20),
  created_at DATETIME,
  INDEX idx_user_status (user_id, status)
);

EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'done';
EXPLAIN SELECT * FROM orders WHERE status = 'done' AND user_id = 42;

逻辑上完全相同的两条 SQL:

  • 第一条走索引;
  • 第二条却全表扫描。

因为 MySQL 优化器死板地按索引定义顺序匹配列,不会重排谓词,也不计算组合代价。稍不注意写法,性能直接爆炸。

而 PostgreSQL 的优化器是真正的代价模型(Cost-Based Optimizer)。它通过列统计与数据分布做决策,执行计划稳定、可预测。

PostgreSQL 的计划是理性计算; MySQL 的计划是随机猜测。

当你的系统需要确定性性能,MySQL 这个优化器就成了炸弹。


三、ACID 的幻觉:回滚之后,MySQL “干净地”抹掉历史

MySQL 的最大谎言,是那句印在官网上的口号:

“InnoDB fully supports ACID transactions.”

这句话听上去像承诺,实际上是选择性履行。遇见 DDL,MySQL 立刻撕毁契约。

看看这一段再平常不过的表迁移事务:

START TRANSACTION;

-- 1. 改名原表
RENAME TABLE metrics TO metrics_1;

-- 2. 按旧结构创建新表
CREATE TABLE metrics LIKE metrics_1;

-- 3. 导入旧数据
INSERT INTO metrics SELECT * FROM metrics_1;

-- 4. 删除旧表
DROP TABLE metrics_1;

-- 5. 写入日志(假设这里出错)
INSERT INTO system_events(event_type, description)
VALUES ('table_upgrade', 'metrics table upgraded');

ROLLBACK;

你以为 ROLLBACK 是“回到从前”? 在 MySQL 里,它意味着“请擦干净尸体再走”。

执行之后你会得到:

  • 原表 metrics 被改名再删除;
  • 新表 metrics 还在,但空无一物;
  • 数据彻底消失;
  • 那条日志既没写入,也没留下痕迹。

你手动发起了回滚,MySQL 则帮你干净地抹掉了历史。

更荒谬的是,这不是 bug,而是官方设计。 任何 DDL(RENAMECREATEDROP)都会触发隐式提交。事务还没结束,它就自作主张地写死文件。

结果是:**回滚只是摆设,原子性形同虚设。**你的事务,不是安全网,而是引爆器。出错时,它炸的不是异常,而是数据本身。


PostgreSQL 的对比:真正的事务,是一次数据库级时间穿越

在 PostgreSQL 中,同样的操作是完全事务化的:

BEGIN;

ALTER TABLE metrics RENAME TO metrics_1;
CREATE TABLE metrics (LIKE metrics_1 INCLUDING ALL);
INSERT INTO metrics SELECT * FROM metrics_1;
DROP TABLE metrics_1;
INSERT INTO system_events(event_type, description)
VALUES ('table_upgrade', 'metrics table upgraded');

ROLLBACK;

一旦执行 ROLLBACK

  • 所有表、结构、数据、索引全部回退;
  • WAL 写前日志完整重放;
  • 系统状态恢复如初,连指针都不漏一页。

这不仅仅是“支持 DDL 事务”,这是数据库哲学分界线的实证

PostgreSQL 的事务作用于整个数据库状态; MySQL 的事务只作用于部分数据文件。

前者是有意识的系统,它理解什么叫“一致性”、“原子性”、“时间线”;后者只是一个文件操作堆栈——连“状态”都不懂。

毫不夸张地说:

PostgreSQL 的事务是一个原子行为; MySQL 的事务是一个概率事件

前者以逻辑守护数据; 后者赌机器别出错。

PostgreSQL 管整个宇宙;MySQL 只管几张文件。 这是工程实现的鸿沟,更是理念上的耻辱。


四、触发器与逻辑:MySQL 的断肢,PostgreSQL 的神经系统

MySQL 到今天的触发体系依旧严重残缺:

  • 每个事件只能定义一个触发器;
  • 不支持语句级触发;
  • 不支持条件触发;
  • 调试如地狱,复用无可能。

2025 年,你依然能看到这样的报错信息:

ERROR 1235 (HY000): This version of MySQL doesn't yet support multiple triggers for the same table.

而 PostgreSQL 的触发体系,是成熟的事务内逻辑层:

  • 行级与语句级触发并存;
  • 支持条件判断(WHEN);
  • 可指定顺序、共存多个;
  • 可用多语言编写(PL/pgSQL、Python、C)。

在 PostgreSQL,触发器能形成业务层逻辑护城河; 在 MySQL,它只是挂件。


五、约束与一致性:MySQL 允许造假,PostgreSQL 不允许撒谎

MySQL 允许你在一行命令里掐死完整性保障:

SET FOREIGN_KEY_CHECKS = 0;

然后导入任意垃圾数据。再恢复检查,它也不会重验。 完美的“装死”机制。

PostgreSQL 没有这种妥协选项。 约束永远生效、永远执行。 它不会假装一致 —— 它要么成功,要么拒绝。

MySQL 教你撒谎;PostgreSQL 逼你诚实。

更离谱的是,MySQL 在处理外键与复合索引时的行为,完全超出直觉。

假设你有一个主表与子表结构如下:

CREATE TABLE users (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  name VARCHAR(50),
  INDEX idx_user (user_id, name),
  FOREIGN KEY (user_id) REFERENCES users(id)
);

理论上,这里的外键只约束 user_id,与 name 无关。但在 MySQL 中,只因为你建立了联合索引 (user_id, name),它会在某些版本(尤其 5.x 与早期 8.0)中无端把第二列 name 一并纳入外键校验逻辑。任何 name 冲突、甚至非唯一匹配,都会触发外键报错。这意味着你根本没定义外键到 name,却被 MySQL 的外键机制“顺手管了”。

PostgreSQL 不会做这种事。 它认得标准:外键依赖主键或唯一约束列,不会跨字段、不会超范围、不会瞎猜。

MySQL 的问题在于:它将“联合索引”视作“外键实现细节”,把数据约束混在索引选型里,最终让行为变得既不确定又难以调试。

PostgreSQL 则严格区分:索引是优化器的工具,外键是一致性的契约。MySQL 把契约和工具绑死在一起。

当你加个索引时,你同时改变了逻辑规则——这不是数据库,这是雷区。


六、“数据库只是大号 Excel”?

不,那只是被 MySQL 教坏的一代人

有人说:

“逻辑不要放数据库,数据库只是存储。”

这句话听上去理性,其实是悲哀。

悲哀的是:MySQL 把开发者养成了“不信任数据库”的人。

因为:

  • 事务不完整;
  • 约束能关;
  • 触发器假死;
  • 优化器靠缘分。

于是程序员被迫把一致性逻辑搬到应用层,再对自己说:“逻辑不应在数据库中做。”

结果就是 ORM、幂等、防重复、补偿机制满天飞。只是因为 MySQL 从未完成应尽职责。

而 SQL 标准在 1992 年就已完整确立:

  • 标准事务语义(包含 DDL);
  • 外键与约束机制;
  • 触发器与存储过程;
  • 视图、模式、授权体系。

换句话说,在 MySQL 出生之前,SQL 世界已经有了成熟、完整、被各大数据库验证过的科学定义。

但到了 1995 年,MySQL 出场时,它做了一个惊人的选择: 它没有遵守科学,不继承标准,而是自创一套残废版 SQL,命名为——“My SQL”。注意那个 “My”:它不是对个人的归属表达,而是一个注脚

“我只承认属于我自己的 SQL 规则。”

于是它扭曲了语言逻辑、删掉了事务 DDL、阉割了触发器、弱化了外键,再把这些残缺包装成“轻量”“高性能”“互联网友好”。 事实上,那不过是权衡实现复杂度后的技术懒惰与规范背叛

这就是 MySQL 的原罪:当全世界都在遵守《SQL-92》, 它却在实现 “Only My SQL”。

结果,MySQL 教坏了一代开发者:大家开始认为数据库就是 CRUD 容器;开始把一致性逻辑扔回应用代码;一边疲于修补,一边自诩解耦优雅。

MySQL 不止是技术问题,它是一种文化病毒 ——它让人们习惯无标准、无事务、无尊严的数据库生态, 并且还为此自豪。

当他们说“数据库只是 Excel”,真正的意思是:

“我们用的 MySQL 就像 Excel——能存点数据,却没灵魂。”


七、有人说“事务里做 DDL 不科学”?

不,那只是被 MySQL 吓坏的工程师自我安慰

会有人批评文中这一点,说:

“在事务里执行 DDL 是不科学的设计。”

这句话听起来高冷,实际上是 MySQL 弱点导致的错觉。他们不是在阐述数据库原理,而是在为 MySQL 找借口。

事实是:事务中执行 DDL 并不反常,这本应是关系数据库的标准语义。 但因为 MySQL 拉跨,他们被迫认为‘不能做’,然后自我合理化。

他们记住的是 MySQL 的崩溃方式, 于是开始以为数据库就该如此; 于是把“不敢”包装成“原则”; 把数据库降级成“存储层”; 再用代码去弥补数据库应有的功能。

PostgreSQL 没这个问题。 你可以在事务里安全地改表、建表、删表、回滚。 因为它的 DDL 就是事务的一部分, 它不装模作样,不偷偷提交。

所以请停止把 MySQL 当作数据库的定义。 它只是数据库的简化版、阉割版、历史遗迹。

真正科学的,是 PostgreSQL; 真正错误的,是被 MySQL 教坏的世界。

要正确性,就别怕高级。 要数据库,就别怕事务中的 DDL。

MySQL 的恐惧,不该成为你的惯性。 真正的数据库,不需要妥协。

MySQL 教人屈服;PostgreSQL 教人尊重。

八、分库分表:互联网最成功的错误设计

所谓“分库分表”,在今天被吹嘘成互联网架构的成功案例。但事实恰恰相反——它不是进化结果,而是 MySQL 贫瘠设计的自我赎罪。

MySQL 从来没有真正的分区机制、全局索引、全局统计信息,也没有跨表事务优化器。当数据量增大,它无法逻辑扩展,只能物理切割。 于是“分库分表”登场——不是因为聪明,而是因为没办法。

从此,应用层开始接管数据库的职责。程序员被迫在业务代码中:

  • 自行计算分片位置;
  • 写路由中间件决定 SQL 去哪;
  • 实现伪分布式事务补偿;
  • 拼接跨库聚合查询;
  • 再写一层定时脚本同步数据。

这一切,只是为了修补一个不支持现代分区能力的数据库。而这些补丁行为,居然被包装成“高并发经验”,仿佛“用应用弥补数据库的残缺”就成了架构智慧。这就像一辆没有刹车的汽车,司机们开始总结撞墙减速的技巧, 然后把它写进《高速驾驶指南》。

分库分表从来不是架构突破,而是数据库退化的症状。

PostgreSQL 从未需要靠这种土法生存。它的分区、并行与事务一致性都在数据库层自然发生。它遵循 SQL 标准,并实现了真正意义上的逻辑分区表——在保持事务一致的同时,可无限水平扩展。

例如,一个标准的时间分区表:

-- 创建主表并定义分区键
CREATE TABLE logs (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT NOT NULL,
    action TEXT,
    created_at TIMESTAMP NOT NULL
) PARTITION BY RANGE (created_at);

-- 创建分区表
CREATE TABLE logs_2024 PARTITION OF logs
    FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

CREATE TABLE logs_2025 PARTITION OF logs
    FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

-- 插入数据时自动路由到正确分区
INSERT INTO logs (user_id, action, created_at)
VALUES (1, 'login', now());

-- 查询仍然是针对一个逻辑整体
SELECT user_id, COUNT(*) FROM logs
WHERE created_at >= '2025-01-01'
GROUP BY user_id;

-- 扩展新分区只需一句
CREATE TABLE logs_2026 PARTITION OF logs
    FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');

数据量再大,它依然是一个逻辑整体。分区是扩展,不是切割;事务仍完整,优化依然智能;一致性从未退让。

因为 PostgreSQL 的设计宗旨是:

当系统变大,正确性不该变小。

而 MySQL 的哲学是另一种:

“先跑起来,崩溃再想办法。”

于是,一个数据库不承担数据库的职责,行业就开始弥补它的缺陷——写代理、造中间件、讲分片策略、造轮子、开大会、出白皮书。所有人都在修补 MySQL 的伤口,而非构建数据库的未来。

如果说 PostgreSQL 推动了数据库技术的演化,那么 MySQL 推动的,只是分库分表的产业链。它让无数人困在自造的迷宫里,同时以此误以为“这就是大规模架构的真相”。

真相是:**成熟的数据库不需要你去分它。**分库分表不是荣誉勋章,而是系统设计的病历单。它见证的不是成功,而是退化——见证了一个数据库如何拒绝成长,又如何让整个行业去替它长大。

PostgreSQL 让系统扩展正确性; MySQL 让系统扩展复杂性。

分库分表不是智慧,是悲剧的形式美。

九、结语:要正确性,不要幻觉

MySQL 的哲学是:差不多就行

PostgreSQL 的哲学是:必须正确,否则失败。

对比项 MySQL 5.7 PostgreSQL 12
事务原子性 仅 DML,DDL 会隐式提交 全局原子性
优化器 规则匹配,性能漂移 成本模型,推理稳定
外键与约束 可关闭或跳过 严格强制执行
触发器 功能残缺 事务级完整
DDL 事务 不支持,必隐式提交 完全支持,可回滚
SQL 标准 方言化实现 完全兼容 ANSI SQL
扩展方式 分库分表(应用层路由) 原生分区表(数据库层)
事务一致性 跨库 XA,慢如狗 全局 ACID
查询语法 动态拼接 统一 SQL
扩容成本 停机 + 迁移 ATTACH PARTITION
是否优雅 像修下水道 像写 SQL

到了 2025 年,
如果你还在忍受一个:

  • ROLLBACK 会删光你表的数据库;
  • 允许你关闭外键检查的数据库;
  • 靠猜测计划运行的数据库;
  • 需要你写中间件来“分库分表”的数据库

那你不是在用数据库, 你是在赌数据库别出事故

MySQL 属于过去 —— 它是“差不多”的象征; PostgreSQL 属于未来 —— 它是“正确性”的代名词。

停止为 MySQL 的残缺买单。
真正的架构师,不造轮子补洞,而是选择一个不用补的数据库。

要么 PostgreSQL,要么幻觉。
要么正确,要么坍塌。

看完了?说点什么呢

如何用旁路网关接管内网 IPv6 代理:RA 双路由优先级实战

2025年7月6日 20:26
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/jc/catwrt_ipv6_dual_ra

前言

最近笔者搬到新地方工作,租的房子自带中国移动的光纤入户。图方便,就直接把之前购买的华为 CPE 当作主路由使用。然而使用 5G Wi-Fi 时总是莫名其妙断流,起初我以为是 R2S 设备过热,花了不少时间优化散热方案。直到有天晚上漏接了整晚消息,第二天排查才发现——问题根本在 CPE 本身!

虽然配有千兆网口,但实测 PC 与 R2S 点对点传输时只能跑到 600 Mbps,而且还有 120 次丢包重传,实在难以接受。在 miaoer 的推荐下,我在京东入手了中兴巡天 AX3000。测试发现内网点对点速率是 940 Mbps,在什么都不变的情况下,零丢包重传。它的后台管理很简洁,基本没什么可调的地方,不过值得欣慰的是,它支持为单个设备定制 DHCP 设置,包括独立下发 IPv4 地址和网关。就凭这点,旁路网关方案就能跑起来。

众所周知,旁路网关是对现有网络拓扑改动最小的代理方案。对于 IPv4 来说,只需手动为终端设置网关,或在主路由绑定 MAC 地址下发定制 DHCP 即可。但如今 IPv6 越来越普及,每个设备都能轻松获得全球唯一的 IPv6 地址,穿透打洞也更简单。那么,旁路网关能否也“喝口 IPv6 的汤”呢?

准备条件

设备列表

设备名称 固件/型号 角色 备注
R2S CatWrt.v24.11.rkarm64 旁路网关 用于提供 IPv4/IPv6 代理
中兴巡天 AX3000 官方固件(简洁后台) 主路由 支持定制 DHCP 下发
中国移动光猫 默认运营商设备 入户网关 工作在路由模式,不支持桥接

网络拓扑图

实践

原理

在 IPv4 网络中,我们依赖 DHCP 下发 IP、网关和 DNS 信息,想定制给特定设备分配的网络参数,只需在主路由配置即可。

而 IPv6 的机制则不同,它将地址和路由信息的下发分成了两个部分:

  • DHCPv6:负责分配 IPv6 地址和 DNS;

  • RA(Router Advertisement):负责通告路由,同时也可带上 DNS。

因此,我们可以将 DHCPv6 的工作交给主路由,而将 RA 的广播任务交由旁路网关来完成。这样一来,终端设备就会默认使用旁路网关作为 IPv6 出口路由。特别是在手机等非 root 设备上,无法手动设置 IPv6 网关的情况下,这种方式就显得尤为重要。

若由主路由负责 RA 广播,则终端自然会使用主路由作为默认 IPv6 网关,流量也就不会走旁路了。因此,必须让旁路网关承担 主 RA 的角色,才能实现 IPv6 默认走代理

操作

主路由设置

确保光猫和 AX3000 已开启 IPv6 支持,并启用 LAN 端的 DHCPv6:

关闭主路由的 RA 广播功能(即“路由通告”):

其余 IPv6 功能保持默认或开启状态即可。

旁路网关设置(R2S)

LAN 接口配置示例如下:

IPv6 路由前缀可以从主路由上拿

关闭 CatWrt 中的 DHCP 功能:

IPv6 设置示例:

其中:

  • 服务器模式:表示设备主动广播 RA,宣告自身为 IPv6 网关;
  • 中继模式:则是仅转发给上游;
  • NPD 代理无需开启;
  • DNS 填写旁路网关的 Link-Local 地址即可(如 fe80::xxxx)。

成果

PC IPv6 信息如下:

ip add 输出

❯ ip add
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx brd ff:ff:ff:ff:ff:ff permaddr xx
    inet 192.168.100.2/24 brd 192.168.100.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 2409:8a20:423:e684:2/128 scope global dynamic noprefixroute 
       valid_lft 186269sec preferred_lft 99869sec
    inet6 2409:8a20:423:e684::xxxx/64 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::839c:251c:581b:42a5/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

ip -6 route 输出

❯ ip -6 route
::1 dev lo proto kernel metric 30 pref medium
2409:8a20:423:e684:2 dev wlan0 proto kernel metric 600 pref medium
2409:8a20:423:e684::/64 dev wlan0 proto ra metric 600 pref medium
fe80::/64 dev wlan0 proto kernel metric 1024 pref medium
default via fe80::e8fe:1bff:fe6e:614c dev wlan0 proto ra metric 600 pref medium

访问效果

❯ curl -v https://www.google.com           
* Host www.google.com:443 was resolved.
* IPv6: 2404:6800:4005:81e::2004
* IPv4: 142.250.198.68
*   Trying [2404:6800:4005:81e::2004]:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=www.google.com
*  start date: Jun 17 20:03:51 2025 GMT
*  expire date: Sep  9 20:03:50 2025 GMT
*  subjectAltName: host "www.google.com" matched cert's "www.google.com"
*  issuer: C=US; O=Google Trust Services; CN=WE2
*  SSL certificate verify ok.
*   Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA256
*   Certificate level 1: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
*   Certificate level 2: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using ecdsa-with-SHA384
* Connected to www.google.com (2404:6800:4005:81e::2004) port 443
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://www.google.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: www.google.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.14.1]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: www.google.com
> User-Agent: curl/8.14.1
> Accept: */*
> 
* Request completely sent off
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200 

小结

其实在这里,仍然存在一个问题值得深思:如果让旁路网关承担 RA(Router Advertisement)的职责,那么一旦它宕机,整个内网的 IPv6 网络将不可用。这显然违背了旁路网关“最小侵入原则”的设计初衷。

那么该如何解决这个问题呢?

答案是:为内网配置多个 RA 源,设定优先级即可。

在 IPv6 网络中,允许多个设备同时发送 RA,只要优先级设计合理,客户端会自动选择最优路由。我们可以通过以下方式实现主备切换:

  • 旁路网关 作为 主 RA 广播者,优先级设置为高(或默认);
  • 主路由器 也启用 RA,但将其优先级设置为低(low)作为备用。

配置方法示例:

打开主路由的“路由通告”功能,并将优先级设置为 低(low)

此时,内网将拥有两个 RA 广播源:

  • 旁路网关:广播默认路由,优先级较高(中);
  • 主路由器:也广播默认路由,优先级低。

可以通过如下命令查看实际的 IPv6 路由表:

❯ ip -6 route
::1 dev lo proto kernel metric 30 pref medium
2409:8a20:423:e684:2 dev wlan0 proto kernel metric 600 pref medium
2409:8a20:423:e684::/64 dev wlan0 proto ra metric 600 pref medium
fe80::/64 dev wlan0 proto kernel metric 1024 pref medium
default via fe80::e8fe:1bff:fe6e:614c dev wlan0 proto ra metric 600 pref medium
default via fe80::5 dev wlan0 proto ra metric 601 pref low

可以看到:

  • fe80::e8fe:1bff:fe6e:614c 是旁路网关下发的默认路由,优先级为 medium,metric 更低,因此默认使用;
  • fe80::5 是主路由器的默认路由,优先级为 low,metric 稍高,作为备选。

一旦旁路网关失联,内核的邻居不可达检测(NUD) 会将其标记为“不可达”,此时系统会自动切换到主路由器广播的低优先级默认路由,从而保证内网设备的 IPv6 网络依旧可以正常使用。

故障演练,让旁路网关宕机

路由信息如下

❯ ip -6 route
::1 dev lo proto kernel metric 30 pref medium
2409:8a20:423:e684:2 dev wlan0 proto kernel metric 600 pref medium
2409:8a20:423:e684::/64 dev wlan0 proto ra metric 600 pref medium
fe80::/64 dev wlan0 proto kernel metric 1024 pref medium
unreachable default via fe80::e8fe:1bff:fe6e:614c dev wlan0 proto ra metric 600 pref medium
default via fe80::5 dev wlan0 proto ra metric 601 pref low

看完了?说点什么呢

毕业季

2025年6月7日 22:47
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/45

我们终将奔赴各自的那片碧海蓝天, 谢谢你,曾陪我走过那些无悔的岁月。

四年的时光转瞬即逝,仿佛昨日还在初来乍到的校园中懵懂张望,转眼却已站在离别的渡口,迎着夏风收拾青春的行囊。在翻阅档案、整理资料的这一刻,我终于看到了四年前高中班主任在评价表的综合评语写下的一句话:“望今后能够更开朗些,更多发展自己的爱好,争取从各个方面来加强自己的能力。”

一瞬间,往昔如潮水般涌来。我想,他或许早已察觉,当时的我已失去了对高中知识学习的热情。我最热切的目光,早已投向计算机的万千宇宙。课堂上,他曾严厉批评那些“上课还在琢磨微信是怎么发消息”的学生——可那时的我,已经沉迷于一个远比高中课本更浩瀚的世界。

我知道,那份对计算机的热爱,并不是浅尝辄止的爱好,而是深入骨血的执念。在衡水式的高压模式下,我的精神长期处于焦虑和压抑的状态,至今仍常常在梦中惊醒,梦见年级主任的小黑屋惩罚、义务劳动、课间跑操、学生课堂和课间查班、禁止听课式罚站……那些伤痕并未随时间愈合,只是被藏在心底最深处。

可即便如此,我最终选择了计算机这条路——不是为了逃避现实的荒芜,而是因为这是我真正想走的方向,哪怕父母暂时不理解,但他们也宽容。

热爱,从未因风雨褪色,哪怕它最终变成了工作。世人常说,把爱好变成工作,最终会丧失那份热情,这个爱好就被毁掉了。而我却始终相信,真正的热爱是不会被磨灭的。也许,这就是班主任当年所期待的“从各方面增强能力”吧——只是我以我的方式,走出了那条属于自己的路。

大学四年,有幸遇到一群虽不完美却值得铭记的室友。他们也许会在深夜突击抄作业,偶尔有些小毛病让我苦笑摇头,但他们在我生病时送饭、陪诊、排队挂号,在我实习期间帮忙递交材料、邮寄物品,在我奔波与焦虑中给予我切实的帮助与陪伴。是他们,用琐碎却真挚的日常温暖,构筑了我大学岁月中最朴素却最可贵的友谊。若不是他们的支持,我或许早已在孤独与压力中闭口不言,错失许多与世界温柔相处的机会。是他们,让我学会信任,也让我拥有一个更加健全与柔软的人格。

感谢我的队友们,是与他们的协作与碰撞,让我清晰地意识到:我或许不适合信息安全这条路。也正因如此,我才能更早地找到那条真正契合自己的方向。

感谢我的导师,不仅在专业上给予我方向上的点拨,更在学习与生活的边界之间,教会了我如何看待问题、如何处事为人。通过组织学术分享会与技术交流会,他促使实验室内的知识不再沉默于个体,而能在成员之间流动、生长。正是这种氛围,让我接触到更多元的认知路径,也不断激发我探索未知领域的热情与勇气。在他的引导下,我逐渐懂得:真正的成长,不仅是技术能力的提升,更是对世界认知方式的拓展与重塑。

感谢百度提供的实习机会,让我得以走出象牙塔,亲身参与到真实业务的运维体系中。在这段宝贵的实习经历中,我不仅学习到了 SRE 理论在生产环境中如何真正落地,也体会到跨部门协作沟通的重要性,理解了在复杂系统下如何推进降本增效、保障服务稳定的实际路径。感谢我的百度 mentor,很多原本抽象的理念,在实际工作中被一点点具象化、拆解为流程与机制,在潜移默化中,我学会了如何将理论转化为实践,如何用工程思维解决问题,如何以系统性的视角看待服务质量。这段经历,既是一次技术的淬火,更是职业认知与思维方式的革新。

毕业不是告别的终点,而是奔赴远方的起点。愿此去,前程似锦;归来时,仍有少年模样。山高路远,愿我们在各自的海阔天空中,再次相逢。

BGM:secret base 君がくれたもの (10 years after Ver.)

看完了?说点什么呢

OnePlus ACE 3 开箱体验

2024年10月6日 16:41
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/44

前言

实习了三个月,存了一些工资,原本打算攒钱租个新房子,结果没想到提前结束了在腾讯云的实习。既然如此,干脆给自己换个新手机吧!我原来的手机是 realme V15 8+128,用了三年多,现在连打企业微信的卡都卡顿得厉害。它搭载的是天玑 800U 处理器,按性能排行来看,也就稍微比 HuaWei Nova 11 SE 强一些,而两者的售价也都一样——1999 元。

那该换什么手机呢?考虑到 Xiaomi 现在越来越严格的 BootLoader 解锁政策,我果断选择了 OnePlus。OnePlus 解锁方便,也不需要像小米那样通过答题考试,个人实在不喜欢这种流程。

最后我锁定了 OnePlus ACE 3,16+512GB 的版本。一次性解决了内存和存储焦虑,再也不用担心下载个游戏没存储空间了。

至于颜色,我选了 月海蓝,觉得挺好看的。

不过,不得不吐槽一下 OnePlus 的包装盒和充电线。通体红色,总给我一种违和感。如果换成蓝色,不是更搭配嘛。

使用体验

这款手机定位中端,因此在拍照方面有所妥协,主摄使用的是 IMX890,据说是旗舰机的长焦?不过拍照效果明显比我之前的 realme V15 好得多。

操作系统方面,因为是 ColorOS,没有遇到一些奇奇怪怪的 BUG。相比之下,realme UI 现在已经处于一种“爹不疼娘不爱的”状态。OnePlus 毕竟是 OPPO 的“亲儿子”,realme UI 感觉像个“干儿子”。

当时我买 realme V15 的时候,realme 还没完全成为性价比的代表,手机没有红外,也没有 NFC。结果买了一年不到,这些功能全上了,真是“怨种”的体验。如今,像 NFC 这种功能,用起来简直太方便了:支付宝支付、公交地铁、POS机刷卡,都只需要轻轻一碰。之前我为了坐车方便,还特意买了一个支持 NFC 的手环。有人可能问为什么不用二维码?每次看到一大堆人挤在闸机口,掏出手机打开二维码,加载半天,我在后面都替他们着急。有了 NFC,进站速度提升,大家都不耽误时间,或者提前加载二维码也行呀.... 二维码刷卡不一定有优惠,而交通卡在本地刷卡是有折扣的。

三段式按钮 调节静音、震动和响铃模式的设计也很贴心,物理开关非常方便,不需要去找图标。

再说说红外功能,虽然看似鸡肋,但实际上特别实用。操控电视、空调这类家电,遥控器不一定随手可得,但手机是“嵌”在身体里的,所以手机肯定随身带。屏幕的显示效果也比我之前的手机细腻得多,还支持 1-120Hz 的无级自适应。不过目前 Android 端的适配感觉还不是很到位。手机的曲面屏设计握持手感非常好,玻璃背板 + 金属中框 的质感一流。最后,骁龙 8 Gen 2 处理器在性能上简直把我的天玑 800U 吊打。从 socpk 的综合性能来看,综合性能是天玑 800U 的四倍!这种升级体验就像从 速龙时代 直接跃升到 锐龙时代,让人震撼。系统动画流畅得不像话,之前为了减轻处理器负担,我都是尽量关闭动画的。

总结

经济基础决定上层建筑。自己挣钱自己花,不用跟家长商量,也不会受到他们的干预。现在更换手机的目标已经达成,接下来就是组装一台台式机了!

文中有一个 Follow 邀请码?你知道它在哪里么?

https://www.timochan.cn/api/objects/file/8r806hgw1r2acpofp7.png

看完了?说点什么呢

离别

2024年9月27日 22:43
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/43

前言

古语有云:“天下无不散之筵席。”光阴荏苒,韶华易逝。三个月的腾讯云实习时光悄然划过指间,如水东流,不复回首。如今,到了启程告别之时,我将带着一份留恋与憧憬,踏上新的旅程,去探寻未曾触及的风景,迎接尚未相识的事物。

其他

  • Follow 项目

    近日,我一直在跟进名为 follow 的项目,担任其 AUR 软件包的维护者。岂料不久前,一个 AUR User 把我的包提了 Delete Request,令我一时愤愤不平。还好,AUR 的 Admin,似乎见多了这种情况,直接将具争议的软件包移除,解决了矛盾点。更有趣的是,偶然逛闲鱼时,竟发现 follow 的邀请码竟被卖到了每个七十元之高价,实在令我感到震惊。不禁感叹,现在经济真的是不景气呀,连一个 Beta 的邀请码都要卖。

  • 购入新服务器

    适逢腾讯云 lighthouse 四周年庆典之际,优惠不容错过,遂又购入一台服务器,作为我的 k8s 集群中的 Worker Node。至此,我的 k8s 集群终于得以扩容,日后再也不会遭人调侃不如 k3s 的轻量集群了。此事虽小,却不乏成就感,足以令我在未来的架构规划中更为得心应手。

  • k8s 持续学习

    在实习的过程中,我深感自身 Kubernetes 领域的知识尚且薄弱,虽不至茫然,然则不足之处仍显而易见。因此,近来我不懈努力,努力学习,力求补齐短板,使技术层面更加完善。相信日后再遇复杂场景,必能从容应对,游刃有余。“知其然,知其所以然”是我的学习目标。

总结

如果让我去寻找别的地方,我可能会不自觉的去对比一下在腾讯云的实习经历和感受吧。

文中有一个 follow 邀请码,你知道在哪里么?VTJGc2RHVmtYMThmQko0dTBMSWhueWlWUHF3UHNWNmtyQlo0TytTWXpxND0=

看完了?说点什么呢

CatWrt 使用经验

2024年7月21日 01:20
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/study/catwrt_usage_tips

Proxy 软件 DNS 解析模式怎么选?

DNS 解析模式大致分为 Redir-Host 和 Fake-IP 两大类。

Fake-IP

什么是 Fake-IP 模式呢?

通俗地讲,Fake-IP 模式是指 Proxy 软件在处理 DNS 请求时,首先将域名解析到内网 IP 池中,并记住这个域名和内网 IP 的映射关系,然后 Proxy 软件会根据域名分流规则处理这些请求:

  • 在 Proxy 链中的域名:使用 Fallback DNS(通常为国外 DNS)进行实际解析或直接封装为 Proxy 流量发送到对应的服务器。
  • 在 Direct 链中的域名:使用 NameServer(通常为国内 DNS)进行实际解析。

当你对这些内网 IP 发起请求时,Proxy 软件会检查映射表,找到对应的域名,并根据分流规则将流量处理为 Direct 或 Proxy 流量。一般情况下,Meta Core 的配置如下:

fake-ip-range: 192.18.0.0/16

当你的 DNS 请求被 Meta Core 劫持后,返回的 DNS 解析结果就会是这个 IP 池中的地址。

这种做法的目的是:

  • 对抗首次解析的干扰:减少已知 Proxy 域名的 DNS 泄露。第一次的 DNS 解析都会被 Proxy 软件根据分流规则处理,避免国内 DNS 泄露已知的 Proxy 域名。
  • 利用国内 DNS 的速度优势:在访问国内服务时,解析速度不受影响。

然而,这种模式也有一些代价:

  • 部分软件的验证:如果发现是内网网段,可能认为被中间人攻击,拒绝正常工作。
  • 一些软件无法使用:比如 UWP 应用,BT、PT 等应用可能会有问题。UWP 应用尚且可以通过 fake-ip-filter 去解决,那其他类型的情况呢?

综合来看,Fake-IP 只适合大多数普通用户,他们只需要 Proxy 功能,而不对网络进行深入探索,不深度使用 BT、PT 等应用。

Redir-Host

现在说说 Redir-Host 模式。

通俗地讲,Redir-Host 不会将域名解析到内网 IP 池中。你的 DNS 查询会首先使用 NameServer 进行查询,当域名属于 Proxy 域名时,调用 Fallback DNS 进行二次查询。如果 NameServer 和 Fallback DNS 设置为同一个,你会明显观察到 Proxy 域名的查询时延是非 Proxy 域名的两倍。在正确设置下,Redir-Host 模式应始终返回域名的真实 IP,自然没有 Fake-IP 的问题。

然而,这种模式也有一些代价:首次解析使用 NameServer,无论域名是什么,首次解析都会通过 NameServer 进行。当 Proxy 软件匹配分流规则时,如果发现域名在 Proxy 链中,就会调用 Fallback DNS 进行二次查询,确保解析结果没有污染。结果是 Proxy 域名可能会在国内 DNS 泄露。

但也有解决办法:使用无污染的 DNS,例如,自建上游 DNS 或使用 Google DNS。这样就不需要 Fallback DNS,因为你已经能保证 DNS 的纯净,Proxy 域名不会传递给大陆 DNS,在这个过程中,你应该会使用加密 DNS,这样可以防止中间人劫持等。可以使用 ipleak 检查 Redir-Host 模式下的 DNS 泄露。如果没有一个大陆 DNS,则认为可以。

我个人强烈推荐 Redir-Host 模式,因为这个模式才是符合直觉的,不会造成很多非预期行为。

如果想详细了解这些,请在评论区告诉我,我会考虑再写一篇。

防火墙的 IP 动态伪装

这个名字有些拗口,直接称为 NAT 功能总开关更清晰明了。开启该功能即启用该接口的 NAT 模式,如果在 WAN 口开启,来自 LAN 口的流量会进行 FORWARD + NAT。

防火墙的 MSS 钳制

这个名字也不太好理解,称为 MTU 匹配功能开关更清晰明了。其功能非常简单:将发送的数据包匹配到当前接口的 MTU。当数据包大于 MTU 值时,会进行分包发送,使数据包更加碎片化,可能增加丢包率,网络延迟明显增大等,用户会观察到网页加载时间变长。打开这个开关可以避免这些问题,提高网页加载速度。

开启该功能开关后,可以防止 IP 分片,以及超大数据包导致的网络延迟。

这个功能有代价吗?当然有。CPU 处理数据包会有额外的性能开销,增加负载,可能影响极限性能。

如何手动调整网卡的 MTU 值呢?

首先应测试目标接口的 MTU 值。因为我的 CatWrt 是旁路网关,我就测试 PC 到该网关的 MTU 值。

ping -M do -s 1472 175.45.176.100 # 175.45.176.100 为 CatWrt 的 LAN(v4)口地址

如果数据包过大,会返回如下信息:

ping: local error: message too long

示例命令设置的数据包大小为 1472 字节,可以以 2 字节为梯度逐步减小数据包大小,直到找到合适的大小。假设 1472 字节的大小成功 ping 通,对于 IPv4 的计算方法如下:

1472 + 8(ICMP 报文长度)+ 20 (IPv4 头部长度)= 1500

对于 IPv6,假设 1450 字节成功,计算方法如下:

1450 + 8(ICMP 报文长度)+ 40(IPv6 头部长度)= 1498

这个值可以在 CatWrt 的接口设置中调整。如果你的 LANv6 和 LANv4(IPv6 和 IPv4 逻辑接口)绑定的是同一个物理接口,建议以 IPv6 设置 CatWrt LAN 接口的 MTU 值,然后修改 PC 网络接口的 MTU 值(可以不修改,正常的都会去自动设置 MTU 值),与之对应。如图所示:

看完了?说点什么呢

旁路网关:使用 CatWrt 来提升网络体验

2024年7月17日 23:55
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/jc/using_catwrt_to_enhance_network_experience

前言

最近笔者外出实习,购买了一台 HUAWEI CPE 用于上网(主要是电信的签约有些坑)。miaoer 得知后,送了一台已经刷好 CatWrt(OpenWrt)系统的 R2S 给我体验。当然,我也简单体验了一下路由级别的 Proxy,突然理解了为什么他们对这个如此热衷。

网络拓扑图

我的网络拓扑非常简单,如下所示:

CPE 设置

在 CPE 端,对手机设置了 DHCPv6 黑名单,不向手机下发 v6 相关的 IP 配置信息,同时将 DNS 设置为 CatWrt,然后对 MAC 和 IP 进行静态绑定

CatWrt 设置

软件配置

关于 OpenWrt,其实我早在虚拟机中体验过。给其他群友解决软路由问题时,也曾了解过相关的软件生态。大部分软件都强耦合 dnsmasq 这个 DNS + DHCP 软件,虽然简单,但我个人觉得在 OpenWrt 中使用它容易引发很多非预期行为。

首先,我禁用了 dnsmasq 的启动,不允许其自启并关闭该软件(虽然没完全关闭,但至少不再捣乱)。

我希望在内网中使用 AdGuard Home 作为 DNS 解析器,并将我的 DNS 信息加密传送到 DNS 服务器。这一步很简单,通过 WebUI 配置即可。但需注意,AdGuard Home 不能接管 53 端口,可以将其设置为 8053 端口。配置截图如下:

你可能会问,那么谁接管 53 端口呢?当然是 Proxy Software,让 Meta Core 接管 53 端口,这样 Meta 可以第一时间获取 DNS 解析请求,并根据域名进行分流,最大化 Meta 的规则作用。

第一步是,将 Meta 的 DNS 设置为 53 端口。

然后开启自定义上游 DNS,地址为 127.0.0.1:8053,将 DNS 请求转发给 AdGuard Home。

然后使用 redir-host + 混合模式,并开启 Meta Core 的 IPv6 支持。

接口配置

我对 v6 也有追求,所以开启了 Meta Core 的 v6 支持。这需要让 CatWrt 也拥有一个 v6 地址。通过 WebUI 配置这一步很简单,效果如下:

在主路由上,我固定了 CatWrt 的 V4 和 V6 地址。

最后,只需在需要接入的终端设备上设置自定义 IP 地址,网关指向软路由(CatWrt)即可。

成品

最终效果如图:

可见,已经实现了域名分流。

DNS 查询流程图:

问题

Q:手机 WI-FI 不支持自定义 IPv6,但 Meta 开启了 V6 支持,该如何解决?

A: 在主路由一侧,不对手机下发 v6 IP 配置。

看完了?说点什么呢

探究 OCSP(在线证书状态协议)

2023年6月27日 18:01
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/posts/study/ocsp_certificate_status_verification_exploration

前言

在 SSL/TLS 证书领域,我们不得不提到 OCSP(在线证书状态协议)。它是用于在线检查证书状态的一种协议,用于客户端判断目标服务器是否可信。最近与 Steamfinder 的讨论中,他提到卡巴斯基企业版报告某个网站的 SSL/TLS 证书状态错误,而标准版则没有报告。当时我猜测可能是该网站的 OCSP 配置出了问题(可能是需要开启 OCSP Stapling,但是该网站未配置),企业版更注重安全所以检查 OCSP Stapling,而标准版不检查。

验证

首先要说明的是,OCSP 的设计目标是为了更好地检查证书吊销状态,因此在设计上考虑了轻量化等因素。相比之前的证书吊销列表(CRL)方式,需要从证书授权机构(CA)下载一个庞大的文件,并匹配目标证书是否在吊销列表中,非常繁琐且响应速度缓慢。而且,证书的状态需要等待 CA 更新 CRL,这存在一定的时间差。如果在时间差内访问一个被吊销的网站,但是 CRL 尚未更新,那么对于普通用户而言,安全级别就会降低,因为这个被吊销的证书在时间差内被验证为可信!OCSP 的出现正是为了进行轻量级的实时在线验证。

在这之前,我已经验证了 Chrome 和 Firefox 是否会主动发起 OCSP 请求。通过我的 DNS 服务器记录了整个 DNS 请求过程,并访问一个子域名来检查该子域名证书的 OCSP 请求。很明显,Chrome 并不会主动请求 OCSP 来检查证书状态,而 Firefox 则会。而且 Firefox 默认开启了 OCSP 查询,如下图所示:

那么,Chrome 是否有类似的选项呢?我在 Chrome 的设置项中找了很久,并没有找到这个选项。而且在 chrome://flags 页面下尝试寻找类似的设置项,同样没有找到。这是因为 Google 主动关闭了这个选项,认为这可能会泄露用户的隐私信息,并影响 Chrome 的网页加载速度。

实验

通过前文,读者应该已经了解到在一般情况下,Chrome 不会主动检查证书状态。只要证书链完整且可以验证到根证书,一般都会被视为可信。而 Firefox 会通过 OCSP 来验证证书的状态,并根据该状态判断证书是否被吊销。那么为什么 Chrome 会这样呢?因为大多数 OCSP 网站使用的是 HTTP 协议,并没有使用 TLS 层(不可能请求一个 OCSP 网站时还要验证 OCSP 网站的证书,并递归请求它的 OCSP 信息)。如大家所知,HTTP 是明文的,任何人都可以检查没有 TLS 层的 HTTP 数据包。在这个过程中,用户的隐私可能会被泄露,这是 Google 考虑的合理因素。其他人可以通过检查 OCSP 请求了解某个用户访问了哪些网站,因为 OCSP 请求是特定的,每个 SSL/TLS 证书的 OCSP 信息都不相同。鉴于传统的 CRL 更新速度过慢,Google 自己维护了一个 CRL。其实和之前的 CRL 一样,也存在更新的时间差。

我的实验是这样的:我申请了一个针对自己子域名的 SSL/TLS 证书,并安装了该证书。然后分别使用 Chrome 和 Firefox 访问该子域名,当然 Firefox 会检查证书的吊销状态。接着我手动吊销了该证书,并再次分别使用 Chrome 和 Firefox 访问。Chrome 的访问是正常的,而 Firefox 则报告该证书已被吊销。因此,OCSP 是相当及时的。这也显示出了 Chrome 关闭 OCSP 证书验证的不安全性。

Chrome 开启验证 OCSP

那么 Chrome 就真的无法开启 OCSP 验证么?经过一番搜索和测试,如果建立如下两个目录 ^1

  • /etc/opt/chrome/policies/recommended
  • /etc/opt/chrome/policies/managed

并在 managed 目录写一个 JSON 文件,内容如下

[object Object]

就可以打开 Chrome 的 OCSP 质询,通过 DNS,可以检查到 Chrome 请求了 OCSP 网站,如图

讨论

关于 Google 关闭 OCSP 的原因,我认为可能是考虑了速度因素。在整个 TLS 握手过程中,OCSP 的速度会显著影响整体握手速度。如果 OCSP 服务器过载或响应缓慢,会影响网站的加载速度。对于追求速度的 Google 来说,这是无法容忍的。因此,保护用户隐私可能只是一个附带的考虑因素。

同时,Google 还需要与竞争对手 Firefox 竞争。Firefox 更注重安全和隐私,因此默认开启了 OCSP。然而,在某些情况下,开启 OCSP 可能导致无法访问某些网站(例如,OCSP 信息错误或证书要求强制使用 OCSP Stapling,但网站未正确配置)。相比之下,Chrome 可以打开这些网站,这为 Chrome 建立了良好的声誉。

为了解决 OCSP 响应速度的问题,OCSP Stapling 技术被引入。Web 服务器可以提前从 OCSP 服务器获取自己证书的 OCSP 信息,并将其缓存起来。在 TLS 握手过程中,服务器可以直接将 OCSP Stapling 信息响应给客户端,从而节省了客户端单独去查询 OCSP 服务器的时间和延迟。值得注意的是,OCSP 信息是由 CA 的私钥签名的,因此一般不会存在伪造的问题。

然而,在验证过程中,Chrome 对于由 Web 服务器提供的 OCSP Stapling 信息似乎并不给予高优先级。Chrome 的验证优先级是先检查 Google 自己维护的 CRL,然后是 OCSP 查询,最后才考虑 OCSP Stapling 信息。这实际上违背了 OCSP Stapling 的初衷,因为本意是希望客户端直接使用 Web 服务器提供的已验证的 OCSP Stapling 信息。相比之下,Firefox 则能够愉快地接受并使用 Web 服务器提供的 OCSP Stapling 信息。我更新了 Chrome 114(Linux)之后,似乎修改了优先级,OCSP Stapling 为最高优先级。

在中国发生过 Let's Encrypt CA 的 OCSP 域名被污染的情况。由于许多网站使用了由 Let's Encrypt CA 颁发的证书,当 OCSP 域名受到污染时,导致大量 TLS 握手失败。这对访问这些网站的用户产生了一定的影响。这种情况迫使 Let's Encrypt CA 不得不更换 OCSP 域名,以解决该问题,并确保用户能够正常访问使用其证书的网站。

综上,我认为 Chrome 主动关闭 OCSP 是为了和 Firefox 竞争,毕竟给用户的印象是 Chrome 快,Firefox 慢。

希望 Firefox 一直和 Chrome 竞争下去!

引用

看完了?说点什么呢

你的下一个 Arch 何必是 Arch

2023年2月15日 21:58
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/40

前言

之前,我也说了,Arch 因为下载一个混淆的包,导致了我的配置文件全部错乱,所以跑去了 Manjaro;Manjaro 确实简化了安装流程,而且自身确实相对稳定。但是问题也是存在的:由于源是从 ArchLinux Fork 出来的,导致的就是如果选择 stable 分支的话,包的更新速度很慢,和 archlinuxcn 或者 AUR 的打包依赖版本有可能不匹配,而且,Manjaro 维护官方的行为有的时候和社区相冲突,感到很魔幻;但是如果选择 unstable 分支的话,国内的镜像源时不时 404,所以烦得要死。正好看到了 EndeavourOS

^1 ^2

优缺点

优点如下:

  • 遵循 KISS 原则
  • 图形化的安装界面(Manjaro 同款)
  • 仅提供最基础的桌面环境
  • 桌面选择丰富,不仅仅局限于安装镜像自带的那个
  • 安装镜像体积比较小
  • 安装完系统后的引导相对使用且友好
  • 不是又维护一个源,而是直接是 Arch Linux 源

缺点如下:

  • 我想不到这玩意有啥缺点,如果有缺点就是 Arch Linux 的缺点
  • Arch Linux 激进的发行策略
  • AUR 更野的发包

当然,以上缺点我认为都不是缺点,为何?如果你体验过 Debian 系的操作系统,你会对源内的包非常失望的,stable 分支的包老的一批,而且也不够丰富,第三方的包只能依赖于 PPA 扩展;然而,是个人都知道管理第三方 PPA 也是一件麻烦的事情,第三方 PPA 可不会保证兼容性,所以整体使用起来相当割裂;你说切换到 unstable 分支?拜托,你永远不知道你的用户跑在什么分支上,而且 Debian 9-11 三版本都有人在用,打包是相当痛苦的,你永远不知道你的用户环境依赖有多糟糕,虽然 APT / DPKG 这套包管理很牛皮,但是架不住依赖环境混乱,打包不规范,而且你的用户可不会主动切换到 unstable 分支。

也许你会说,Arch 太激进了,我需要的是稳定,如果你需要的是稳定,那就回去用 Debian 系,滚动式更新策略就是不是为你准备的,等你厌烦了 Debian 再来 Arch 系吧。可能这就是著名的 Debian 定律吧,反正我是讨厌死了在桌面系统上使用 Debian 系。

系统

看完了?说点什么呢

我为什么拥抱 Linux

2022年10月31日 22:38
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/39

良好的权限管理

你也许会问,我为啥选择选择 Linux,Linux 相较于 Windows 到底有啥不同。我刚开始看 Linux 纯粹是馋 Linux 良好的用户权限管理。Windows 的用户权限让我感觉非常混乱,即便是 NT 6.0 内核以后大幅缓解了这个问题,但是这个问题依旧存在,用户创建的文件,本来好好的,莫名其妙这个文件的所有者就不是用户了,用户还无权访问这个文件,删也删不掉,恶心的一批。然后软件的安装和删除,在 Linux 下都有对应的包管理器来管理,软件也是从官方源 / 镜像源拉取,并且还校验这个包的签名(你可以理解为校验包的完整性)。软件包的安装和移除都需要 root 权限,只要你平时以普通用户权限运行,如果需要 root 权限,临时提升权限即可.管理好依赖,稳定的一批。实在不行,你还可以使用 timeshift 进行快照,出事了就回滚回去,相比之下 Windows 的备份功能纯粹就是废物。

软件的获取很优雅

使用包管理器 search 某个包,然后 install ,整个过程一气呵成,甚至在绝大部分情况下,不需要你去配置环境变量(因为 bin 目录默认已经全局加载到所有用户的环境变量里面了)。Windows 呢?使用搜索引擎 / 敲网址 到达软件官网 ,分辨是不是官网,找到下载页,下载安装包,安装,然后配置环境变量(如果需要的话)。虽然 Windows 有 Scoop 能缓解这个问题,但是软件源比较分散,让我回想起了管理 PPA 的噩梦。

配置文件集中

我太讨厌 Windows 的注册表了,对于普通用户来说,这个注册表的表值完全不知道在干什么,只能看到对应哪个软件,但是不知道这个表项是啥意思。。动都不敢动,生怕注册表炸了不好重建。而且即便是有了注册表,各个程序还是在自己的目录 OR 用户目录下生成配置文件,不够集中;Linux 下 /etc 下就是软件的全局配置文件目录,集中管理相当方便,对于用户来说,~/.config 就是用户软件配置文件目录,而且各个软件的配置文件的配置项一般都能做到语义化,用户能轻松读懂意思,即便是不懂,也能找到对应的文档解释这些配置项(大部分情况);Windows 下,我也没见哪个软件专门写文档去解释注册表里面的表项是啥意思吧?

可玩性高

Linux 是有很多桌面环境的,例如 Gnome 、 KDE 、xfce、MATE、Cinnamon 等等,你调教的不开心了,随时换到另一个桌面环境,每个桌面环境的可玩性都很不错,而不是像 Windows 就一个桌面环境,玩来玩去就一个样子。Linux 的桌面环境是能玩出花的。不要说 Linux 太难用了,Linux 都是需要自己调教成适合自己的口味的;你都没上手开始调教,是没有发言权的。

配置开启启动 OR 计划任务方便

Linux 下本身就有一个很好的计划任务管理器,你想配置的计划任务交给它就行,不论是执行某个具体的命令,还是文件,还是说一个 Shell 脚本,它都可以。Windows 下计划任务的设置就稍显麻烦些,而且还存在不会执行的这种情况……我属实是麻了。针对单个文件设置开机启动项,对于 Windows 来说略微麻烦;但是对于 Linux 来说就是一件很简单的事情,要么软连接到 ~/.config/autostart/ 要么就在用户目录下写一个启动脚本,之后你想开机执行的文件添加进去,脚本路径写入环境变量配置文件即可。

软链接

软链接这个东西是用了就回不去的东西,实在是方便多了。虽然 Windows 下也有符号链接、目录链接,但是因为 Windows 的权限管理的模糊,导致这玩意容易出 BUG。

丰富的文件系统选择

Linux 下可以选择文件系统有很多,比如 EXT 系列,或者 Btrfs ,其中我最喜欢的是 Btrfs ,写时复制 (CoW) 功能实在是太棒了,对于同一个文件,你复制两份后的修改,对于 Windows 来说占用的就是两份文件的空间,对于 Btrfs 文件系统来说,就是一份源文件的+变更内容的占用;比直接占用两份文件的空间,肯定是小得多。这样说你如果不明白的话,简单举个例子你就明白了。对于一个100 MiB 的文件,你复制了一份,然后对其修改了,修改后的大小是 140 MiB。那么这两份文件的占用在 NTFS 文件系统中就是 240 MiB,但是在 Btrfs 文件系统里面,两份文件就是占用了 140 MiB 。即源文件 + 变更内容占用的空间。而且数据安全也有保障。

生态问题

Linux 的生态是比较差的,尤其是国内软件。谁让国内的大厂向钱看齐,只看重短期利益,没有利益的事情就不干。相比之下,国外大厂对于 Linux 的态度就好多了,也在尝试兼容。就国内而言,大厂做的甚至不如中小厂:迅雷、搜狗输入法、百度网盘、WPS、360 等等,这些做的就相当不错,值得表扬。WPS 的体验非常不错,就是一个去掉所有付费功能的纯净版。哦对,甚至 360 安全浏览器都有 Linux 版本,功能做的还比较全。QQ 浏览器就纯粹套了个壳,功能严重残缺。真不知道国内所谓的大厂在搞什么。QQ / Wechat 甚至到现在都还没有发布一个相对可用的 Linux 版本(特供版不算在内),QQ 那个就别说了... 还不如不发布。

但是对于 Coding OR 运维来说,这些都不是问题,日常用到的软件不多,主要还是集中在开发或者运维上,开发或者运维软件都是对 Linux 友好的,或者有替代的。

人生苦短,我爱 Linux。

看完了?说点什么呢

最后还是选择了 Manjaro

2022年10月18日 18:59
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/38

现在又滚回 ArchLinux 了

前言

终究是现实击败了自己折腾的兴趣。为了给硬盘腾出空间,我把所有的快照删除了,然后去调试了一个看似正常的程序,因为这个程序需要一个包,在下载包的过程中,没有注意到自己下了一个被混淆的包。当我吃完饭后,我的电脑风扇已经起飞了。算是自己疏忽吧,虽然这个异常的包没有造成什么大的损失,但是它把我的配置文件几乎全部破坏了,想着与其重新写配置文件,倒不如重新装系统,这样还干净。为了能尽快投入使用,自然不会再安装 Arch Linux 了,但是 Arch 系的软件源以及维护规则深深的吸引着我,所以就再度尝试 Manjaro Linux

安装

安装过程异常的顺利呀,GUI 在这里功不可没,仅需简单的几下就 OK 了。

不得不提的是, AMD 显卡在 Linux 免驱就是舒服,不像我之前的机器是 NVIDIA 的显卡,难搞的要死;闭源驱动性能很强,但是存在兼容性问题,包括但不限于:不兼容老显卡,没有开机动画,随机黑屏,随机花屏,桌面环境挂掉等等。开源驱动虽然兼容性非常不错,但是性能非常糟糕。在我的印象里面,NVIDIA 的卡的用户还是处于两难的状态。也不知道 NVIDIA 把 GPU 驱动开源这件事情推动的怎么样了。

写配置文件

Manjaro 还是比较适合养老的,很多配置项不需要自己操心,例如网络,蓝牙,虽然都是一次性工作,但是不用配置就是省心很多。KDE 全家桶舒服呀!

之前的桌面环境虽然也是 KDE ,但是没有安装 KDE Connect 这个软件,这次 KDE 全家桶给带上了;用过之后,感觉就是舒服呀,不仅跨平台支持,还相当不错,只要你的设备都在一个网络下即可。

支持如下功能:

  • 手机和电脑互传文件
  • 手机通知推送到电脑上
  • 电脑通知推送到手机上
  • 手机电话推送到电脑上
  • 查看电脑 / 手机 状态,包括但不限于:信号强度,电量
  • 配合其短信功能,可以在电脑上收发短信

单单是第一个功能就已经很吸引我了,这下次手机和电脑互传文件不需要 QQ / WeChat 等工具了。

最后

你也许会问,为啥你不用 Ubuntu / DeepinDebian 系的 Linux 系统呢?

因为 AUR(Arch User Repository) 呀,Linux 上有的包, AUR 几乎都有,管理起来方便;如果是 Debian 系,想使用第三方的软件源,得添加 PPA,还是很麻烦呀,因为我并不想记住那么多的 PPA 地址,还有那繁琐的秘钥添加,在这点上,Debian 系是比不上的,我个人认为 Arch 系相较于 Debian 系,Arch 系可能更适合做桌面系统吧,反正对于 Debian 系来说,依赖处理不好,重启就炸掉了,Arch 系看似非常的野,实则比 Ubuntu 桌面版稳定多了,Ubuntu 真的不耐玩

就我个人使用来看,新手上手 Debian 及其衍生发行版本的系统,很棒!但是,Debian 系的依赖是真的容易爆炸,现有依赖的包和需求的包冲突,这个冲突问题一直得不到很好的解决。那你也许会问, Arch 系解决这个问题了?

Arch 系没有解决这个问题,但是 Arch 系的滚动更新模式及其相关的软件发行策略能很好的缓解这个问题,毕竟你不更新就没有包可以用了,让大家都是相对一致的依赖环境,不似 Debian 系,依赖版本跨度非常大,毕竟你不更新又不影响你下载新的包。不过倒也期待 Gentoo Linux 的依赖共存方案在其他 Linux 发行系发扬,这种解决方案,我觉得很棒;或者就是 AppImage 这种形式的包分发,这种自带依赖的包分发模式,个人感觉也很不错。

如果我还有折腾的心的话?我也许会去尝试 Gentoo Linux 吧,毕竟它的一些东西和特性也是在吸引着我。

看完了?说点什么呢

华硕,“奸”如磐石

2022年9月22日 22:49
该渲染由 marked 生成,可能存在排版问题,最佳体验请前往:https://www.timochan.cn/notes/37

起因

我的室友想重装系统,因为他 Windows 10 家庭版用起来奇奇怪怪的,所以就让我看看,哪些是必须迁移的数据。虽然我知道一个盘分一个区也行,但是不区分系统盘和数据盘的后果就是,重装系统火葬场,准备给他分区,并解锁 Bitlocker 并迁移数据。

他的笔记本只有一个 M.2 接口,要想升级,只能更换,不能加装。

缩水点

硬盘缩水

在迁移数据的过程中,我发现硬盘的写入速度异常的慢,不符合一个 NVMe 协议固态的正常水准,只有 80 Mb/s 左右,然后就去设备管理器查看了硬盘型号。第一个映入眼帘的就是 Intel ,我对 Intel 的盘印象最深的是 660P ,但是那个型号我并不熟悉,查了一下,发现就是 660P ,不论是读写曲线还是跑分,都符合贴吧老哥的 660P ,这样石锤这个就是了。所以给他沟通一下,让他换硬盘,反正都要换了,直接上 1 TiB。花费了 510 元,购入了 致钛 TiPlus 5000 1 TiB

^1

主板 USB-A 接口缩水

给他换好了硬盘,然后借了一个硬盘盒子,把旧的数据迁移过去。那个硬盘盒子是 USB-A 接口的,但是接上去只能跑 20Mb/s,我怀疑接到 USB 2.0 接口上了,于是换了几个位置,发现就没有 USB 3.0 接口。。。这就很无语了 ==,而且其中一个 USB 接口长得像 USB 3.0 但是实际速度是 USB 2.0(跟我的插拔速度没关系),那没办法了,只能慢慢传。

主板 M.2 接口速度缩水

终于迁移好数据了,然后下载图吧工具箱,给硬盘跑了一下分,读的速度始终突破不了 1600 Mb/s ,然后想了想,用了 Diskinfo 查看了走的是什么通道,给我看懵逼了, PCIE 3.0 x 2 ??? 真的就一点富余的都不给呗, 660P 只能用到 PCIE 3.0 x 2 的带宽,所以接口直接限制到 PCIE 3.0 x 2 ???根本没考虑过用户升级?

网卡缩水

这个使用的是一块 Intel AC 9462 ,我的天,真的就不舍的上一个 AX 201,贵了多少钱呀 ==,于是给他升级成 AX 201

拆解方便

整个机器是塑料机身,而且不需要拆机片,当你把 D 壳的螺丝拧下来的时候基本上就完成了,虽然有卡扣,但是拆开异常的简单,用点力气直接就可以掰开了,借用 B 站一个拆解 UP 的一句话,拆这个笔记本像翻书一样简单,实测确实如此。

进风口设计奇怪

这个的机器的散热模组的右边就是风扇,但是 D 壳进风口的开孔在散热模组左边,也就是说没有对着风扇,即风扇没有进风口,虽然也能用,但是不是很能理解为啥这样开孔,而且散热也不好呀 == 。因为是塑料机身的缘故,感受的不太贴切。

总结

这是华硕一款售价 4499 元的 华硕 vivobook 15 轻薄本(2021.7),不得不说,直接把 “华缩” 的精神贯彻到底,整个机器在看不见的地方都在缩水,看得见的地方没有测试,所以不敢下断言。就整体的素质而言,在当时那个时间段不如加 100 块购买 Xiaoxin Air 14 plus。所以就很无语 == 。 很难想象,搜索引擎随手搜这个笔记本,占据前列测评文中,均是好评,真的没看懂,到底为啥能拿到这么高评价,都是恰钱了么?而且评测文章看起来好尬呀!支持 IPV6 都能拿来当优点吹?个人评价,电子垃圾。

看完了?说点什么呢

❌
❌