想法在乙巳菊月迭代
八月份开始我找了个兼职、过上了「起床 > 做饭 > 吃饭 > 工作 > 洗澡 > 吃饭 > 睡觉」的健康生活。要知道过去的我经常熬夜、一觉睡到中午、饭不按时吃,总之习惯差得很。突然开始自律,就变得想要去完全利用起自己的时间。
纽约市是一个坐地铁比开车要好的地方,但地铁没有网络。一般出门的话,通勤半小时到俩小时是跑不掉的,意味着这个时间里去网上冲浪或者同朋友聊天几乎不可能,我只能去阅读已经被下载到手机里的电子书籍或者博客文章。多亏了这一点,我开始关注一些独立博客主,并发现了很多我认为有意思的博客。陆陆续续看了一两个月后,令我也想花些时间在记录我自己看到的、学到的、感受到的东西上。
书籍
《不原谅也没关系》
我是一次网上冲浪的时候发现了这本书。当时我刷到一个帖子,内容大致是在说:
自言自语、在脑海中幻想某件事情会发生并且演习如何去应对等行为是因为「父母的凝视」。
我确实有这样的毛病。很多时候我的大脑都在想「过去发生了但是没做好的事情」以及「未来可能会发生的事情」,自言自语也是脑内演习时我想出来的回复被不小心说了出来。我常常处于自省的状态。说是自我反省,实则是一遍遍 羞辱 自己。
这本书的主题是 CPTSD(Complex Post-Traumatic Stress Disorder,复杂性创伤后应激障碍)。但是和科普疾病的书不同,它更像是一本「自救手册」、附带了对于 CPTSD 的解释。托这本书的福,我更了解自己以及身边的人了。
什么是 CPTSD?它是一种 因长期或反复暴露于创伤事件而引发的心理疾病。与 PTSD(Post-Traumatic Stress Disorder,创伤后应激障碍)相比,CPTSD 不仅包含了 PTSD 的核心症状(如恐惧感、闪回、过度警觉),还包括了情绪调节障碍、负面的自我信念以及人际交往困难。CPTSD 通常发生在个体感知无法逃避或者躲避创伤事件的情况下。
根据作者所说,CPTSD 的核心症状主要是这五种:
- 情绪闪回:CPTSD 最典型的症状,是一种 突然发生且通常持续时间较长的退行,幸存者会退回到童年遭受虐待或遗弃时的强烈情绪状态,如恐惧、羞耻、愤怒、悲伤等,并激活「战或逃」反应
- 毒性羞耻感:一种强烈的自我贬低感,会摧毁自尊,令幸存者觉得自己毫无价值、必被鄙视,常导致自我疏离和孤立,不愿寻求他人支持
- 自我遗弃:对自己的忽视或抛弃感,表现出对自我关爱和保护的缺失
- 恶性内在批判:内化的苛刻批评声,源自童年的父母批判,持续挑剔和否定自我,导致自信心极度受损
- 社交焦虑:对人际关系的焦虑和恐惧,常伴随孤独和被遗弃感
此外,CPTSD 患者常表现出过度的创伤应对模式「4F 反应」:
- 战斗(Fight)
- 逃跑(Flight)
- 僵住(Freeze)
- 讨好(Fawn)
这些反应是对童年创伤的长期适应性防御机制。
作者在书中给出了一个例子,令我印象深刻。一个家庭养育了四个孩子,这四个孩子却分别代表了 4F 反应的其中一个:大儿子从小跟着父母欺负兄弟姐妹,为人狂傲自大,永远都觉得自己是正确的,代表「战斗」;二女儿从小被欺负,只能靠一天天的忙碌来避免面对内心的痛苦,代表「逃跑」;三女儿也是从小被欺负,但是接触到了电子产品后,很快便麻木地沉迷在其中,连自理的能力都丧失了,代表「僵住」;小儿子自小就懂得察言观色,长大后被母亲「绑架」到身旁照顾自己,代表「讨好」。
实际上 4F 反应单纯指的是生物在面对危险时的四种本能生存反应:「战斗」是主动攻击来保护自己或对抗威胁;「逃跑」是通过逃离危险环境来躲避威胁;「僵住」是身体和情绪上的僵硬或麻木、暂时「冻结」以避免威胁;「讨好」是试图通过迎合、讨好他人来避免冲突和伤害。这些反应都是生物的本能反应,是我们的自然防御机制。
问题在于,在一个有毒的环境下我们有可能 长期重复 做出这些反应、形成深层的心理防御模式。
我的家庭曾是个有毒的环境:日常的物理与言语暴力、羞辱,以及强加给孩子的过度责任。那个时候,我的好朋友不多,因为我不被允许出去玩,朋友们也不愿意同我深交,因为他们都认为我的家人是神经病。
在经历了一段斗争后,我脱离了这个环境。这段时间,我的创伤更多与家庭有关。我很厌恶他人在我面前诉说他们的家庭有多么和睦;可笑的是在我一次同朋友分享我的过去经历后,TA 的第一反应是「这样说来我的家人对我就很好呢」。每次提到我的家人是否爱我,我会立即陷入「情绪闪回」,被一种强烈的悲伤所淹没。这些经历塑造了我内在的「毒性羞耻感」。
可悲的是,我很快便进入了另一段有毒的关系。我的「内在批判者」变成了校友,一群永远是在批判他人的家伙们。明明是我被冒犯了,但我会感到愤怒的同时,也会去想如何讨好他们。很是可笑。我的内心早已充满了来自家庭的、模糊的自我怀疑。就算是被伤害了,我也无力反击。
好在这些事情都已经是过去式了。如果我想去详细说说这些事情的话,我会单独写一篇博客文章。
《重新定义公司:谷歌是如何运营的》
这本书我没有读完,只读了前两个章节。
作者认为,科技进步对商业的影响非常大,基本上没有什么行业在信息时代还以过去的样子运行。过去,企业可以靠着销售手段,把一个质量差的产品变成全民都在消费使用的摇钱树,但现在完全行不通了。现在要想成功,必须要有出类拔萃的产品,因为消费者可以用各种方式获取到信息、了解该产品的质量如何。同时,实验和失败的成本显著下降了。现在的人们可以组建一个小团队,创造出产品、通过网络免费在全球发行、选定顾客群试用、判断产品的优点和缺点……
作者还抨击了传统知识工作者:秉着「专攻术业」的精神在刻板的企业环境中出人头地,主要靠的还是墨守成规。这些人要么是技术达人 + 管理白痴,要么就是管理专家 + 技术菜鸟,和谷歌的工程师人才很不同。这里作者提出了一个概念 —— 创意精英。
创意精英的特点包括但不限于:
- 不拘泥于特定的任务
- 不受公司信息和计算能力的约束
- 不惧怕甚至喜爱冒险。即便在冒险中失败,也不会受到惩罚或牵制
- 不被职位头衔或企业的组织结构绊住手脚
- 很容易失去耐心,经常变换职位
- 具有多领域的能力,经常会将前沿技术、商业头脑以及奇思妙想结合在一起
- 拥有过硬的专业知识、懂得如何使用专业工具,还需具备充足的实践经验
- 有分析头脑,对数据运用自如,又不会沉迷其中
- 有商业头脑
- 有竞争头脑
- 拥有用户头脑
- 用不同于你我的崭新视角看问题
- 充满好奇心
- 自动自发,注重于自己的理念
- 心态开放,可以自由地与他人合作
- 一丝不苟
- 善于沟通,风趣幽默
所有创意精英都必须具备商业头脑、专业知识、创造力以及实践经验。衍生出降低风险、规避失误的企业运营流程的管理模式会形成一种压制创意精英的大环境。
我能感觉出,我不是一位创意精英,我会的东西根本也没那么多。仔细想来,我唯一一件能被说是「做得好」的,只有计算机相关的事情了。我认为人终究不能去只专注于做一件事,未来我也想要有其他可以被说是「做得好」的事情。
这本书传递的信息很多且各不相同,我只挑一些我认为有趣的说:
-
现实生活中,河马是一种十分危险、速度快、咬合力强、体重足以碾碎其他动物的动物。而职场里的河马,叫做「高薪人士的意见」。一个人拿多少工资,并不能直接等于他们做决策的能力有多强。同样,经验本身也不是决策的关键。但是许多人,甚至说许多企业都没有意识到这一点,依然认为谁的薪金高或者个人经验多,谁才是对的。
-
谷歌采取的是扁平化企业结构,也就是压缩中间的管理层级,可以让一个普通员工直接向总监或者副总裁汇报(对标的是金字塔结构)。多数人认为,扁平化是为了和上层平起平坐、追求一种地位上的平等感;而对于创意精英而言,扁平化是为了多干正事。过多的管理层级会成为他们创新的阻碍,他们需要能够快速地与决策者沟通,获得反馈和资源,从而高效地推进工作。
谷歌实现扁平化的方法很有意思:一个管理者至少要有 7 个直接下属。这会强制扩大管理幅度,让管理者们无法对每个人的工作细节都进行微观管理,自然也没法事事都插手下属们的工作。
-
传统和僵化的管理思维会认为工作和生活是两个对立面,需要像天平一样「平衡」,一个多了另一个就必然会少。然而作者认为这个标准本身就很有问题:对于热爱工作的人来说,工作是生活的重要组成部分,而不是生活的对立面。强行分割很不自然。最好的企业文化是让工作环境和家庭环境都充满乐趣,员工可以自由地在两种状态中切换。
通常让员工感到痛苦的不是工作本身,而是「失控感」和「被迫牺牲感」。作者对此的建议并不是「让员工少工作」,而是「不要用时间去管束员工」。管理者不需要催员工加班,也别劝他们早点回家。这种行为的潜台词是「我不相信你能自己管好自己」。你只需要让员工知道他们需要对自己的工作负全责,并把如何完成工作的控制权交还给员工,他们自己会找到最适合自己的节奏,从而最大化产出、最小化「被迫牺牲」带来的倦怠感。
-
一个不可或缺的员工通常被视为英雄和骨干。然而这个「不可或缺」是一个巨大的风险,因为如果一个人的离开就能让公司瘫痪,那说明公司的组织结构非常脆弱。同时这种「不可或缺」也会导致一种不健康的共生关系。作者提到「强制休假」很重要:对员工而言,这可以让他们意识到「地球离了谁都照样转」、减轻心理负担;对公司而言,给了其他人接手的机会,可以锻炼团队的「备份」能力
-
随着企业变大,为了控制混乱,管理者会本能地增加流程和审批环节。这些流程的潜台词就是一种「不」——「你不能随便做,必须先经过 ABCDE 的同意」。而在一个说「好」的文化里,这恰恰相反,它要求想说「不」的人必须给出「百般信服的业务考量」。这颠覆了权力关系,把证明的责任交给了阻碍者,而非创新者。这也是一种「提出质疑的人要给出证据,而非让被质疑的人自证」。
有创意、有能力的员工最讨厌的就是无意义的内耗和形式主义。一个默认说「好」的环境,传递给员工的信息是:「我们信任你的判断,我们鼓励你尝试」。这可以让员工愿意提出更多想法。反之,一个默认说「不」的环境,会让员工觉得「多一事不如少一事」,最终人才流失。
我不是很懂管理,评价什么的待我进了一家真正的企业之后再说吧。
《黑客攻防技术宝典:Web 实战篇》
这本书我同样没有读完。它属于是那种「不一边读一边记笔记就不行」的书,因此我打算读完后直接将笔记发布到博客上。
它的核心要点很简单:服务端 永远 都不应该信任客户端发来的任何请求。
音乐
我个人很喜欢听台湾摇滚,从万能青年旅店听到草东没有派对、康斯坦的变化球,最近则是在听老王乐队在 2019 年发布的专辑《吾日三省吾身》。听完后印象让我最深刻的是《垂钓》。可惜我不懂音乐和乐理,没法展开说说,只能说我喜欢他们的哪些歌词:
迎面而来的机会我抓不住,迎面而来的车子我躲不开。
比你聪明的人啊都在努力往前,我无力地闭上眼。
影视
我跟朋友补完了《未来日记》。男主前期的塑造有点劝退,实在是太小孩子气了。后面有两集的制作很明显出现了很大的变化,不论是画风、动作的流畅度和分镜设计。
前端技术
我在阅读前端技术相关的博客文章时都会记笔记。现在打算分享出来了,才发现我居然忘了标记来源是什么。我只能把这些文章从浏览记录里一一找出,真是醉了。
CSS
-
The Coyier CSS Starter – Frontend Masters Blog
介绍了 Chris Coyier 的 CSS 样式起点方案,旨在提升开发效率与界面一致性。
-
The Best CSS Unit Might Be a Combination | OddBird
不必在
px
与em
/rem
之间做单一选择。借助现代 CSS 的比较与数学函数(如max()
,clamp()
,calc()
),可以组合单位以表达更精确的设计意图。单位的「语义」比其数值更重要 —— 应使用最能表达设计目的的单位。 -
CSS offset and animation-composition for Rotating Menus – Frontend Masters Blog
介绍了如何使用 CSS 的
offset
属性和animation-composition
机制,为圆形菜单项创建沿路径旋转的动画效果,实现更流畅且可控的交互式布局。 -
强调动画应有明确目的,并根据使用频率与速度优化设计,否则可能降低用户体验甚至损害产品信任。
-
A gentle introduction to anchor positioning | WebKit
介绍了 CSS 的新特性「锚点定位」,展示如何使用纯 CSS 将元素相对于另一个元素进行精确、响应式定位,从而简化菜单和弹出层的布局。
JavaScript
-
Accurate text lengths with
Intl.Segmenter
API | AutomagicString.length
并不总是对的。正确做法是使用Intl.Segmenter
。这是浏览器原生的 API,可以按照语言规则将字符串分割为「graphemes」,也就是扩展字数簇、人类可识别的字符。 -
You no longer need JavaScript Ʊ lyra's epic blog
现代 JavaScript 框架(例如 React、Next.JS)常常导致加载缓慢、错误频发、资源臃肿。HTML 和 CSS 已经具备了强大功能,能完成许多交互和视觉效果。对于安全研究者或者隐私用户,禁用 JavaScript 是常态,纯 HTML / CSS 页面更友好。并且 CSS 性能更优:动画运行在 compositor 线程,不受 JavaScript 阻塞影响。
HTML
-
Your Images Are(Probably)Oversized
开发者常用高分辨率图片(如 3600×2400)以确保视觉质量,但多数用户设备无法充分利用这些像素。未设置
sizes
属性时,即使使用 Next.JS 的<Image>
组件,仍可能加载原始尺寸图片,浪费带宽与计算资源。 -
You're loading fonts wrong(and it's crippling your performance)- Jono Alderson
系统性揭示了当前网页字体加载的常见误区,强调字体是性能与可访问性基础设施,并提供优化策略以提升加载速度、稳定性与全球语言支持。
后端技术
NestJS
在写项目的时候我学习到了这些知识:
-
防御性编程:
使用
??
操作符处理undefined
情况。例如:return setting?.settingValue ?? false;
-
查询优化:
-
如果只查一个数据,用
findOne()
而不是find()[0]
-
一次查询获取所有相关设置,而不是循环查询
-
使用
$regex
精确匹配设置键值 -
使用
{ upsert: true }
确保设置项存在 -
批量操作时,使用
bulkWrite()
,速度比循环单个操作快 10 倍以上:javascript1
2
3
4
5
6
7
8
9
10
11for (const task of tasks) {
operations.push({
updateOne: {
filter: {},
update: {},
upsert: true,
}
});
}
await this.adminSettingModel.bulkWrite(operations);
-
-
拦截器:
-
在 NestJS 中,拦截器会站在业务逻辑(Controller / Service)之前,可以检查、修改甚至完全阻止一个请求继续往下走。而 NestJS 底层大量使用了 RxJS 库,后者的世界里,所有异步的数据流都被表示为可观察对象,像一个管道;数据会从管道的一端流向另一端。拦截器的
intercept
方法,返回值必须是一个Observable
。这意味着想要阻止请求,只写一个return null
是不够的,需要使用 RxJS 的of()
、创建一个新的、立即发出一个值然后结束的Observable
。该方法可以用于判断是否开启了某项设置,如果没开启就return of(null)
、直接阻止该请求。 -
缓存实现策略,除了使用 Redis 缓存装饰器,还可以使用内存缓存 Map:
javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24private settingsCache = new Map<string, { value: boolean; expiry: number }>();
private readonly CACHE_TTL = 60 * 1000; // 60秒
async getTaskSetting(taskName) {
const cacheKey = `email_scheduler.${taskName}.enabled`;
const cached = this.settingsCache.get(cacheKey);
// 缓存命中且未过期
if (cached && Date.now() < cached.expiry) {
return cached.value;
}
// 查询数据库
const setting = await this.adminSettingModel.findOne({ settingKey: cacheKey });
const value = setting?.settingValue ?? false;
// 更新缓存
this.settingsCache.set(cacheKey, {
value,
expiry: Date.now() + this.CACHE_TTL
});
return value;
}
-
-
架构:
- 使用事件驱动
- 写 E2E,也就是端到端测试
分布式锁
分布式锁类似于公厕的门锁。它的目标是确保同一时间只有一个人(服务器实例)能使用厕所(执行任务);关键是锁必须对所有人(所有服务器)都可见且有效;现实是 Redis 充当「锁的管理员」,所有服务器都通过它来检查锁状态。而在技术定义内,分布式锁是一种跨多个节点的互斥机制,确保分布式系统中的临界区同时只能被一个节点访问。
在我的项目中,有个功能会用到 @Cron()
装饰器。其中有这么一个例子:每日午夜零点,服务器 A 启动了每日报告任务、查询了数据库,发现有 100 个需要发送的邮件。服务器 B 同样也启动了每日报告任务、查询了数据库,发现了相同的 100 个邮件。
结果显然易见:200 封重复邮件发送给了客户。
为什么数据库防重复的功能不够?首先,服务器具有着竞态窗口,它们会同时查询、同时发现「未发送」状态、同时发送、同时更新状态。其次,邮件发送耗时有 5-10 秒,在此期间数据库状态是不会被更新的。这也就体现了分布式锁的价值:它能够确保任务一次只在一台服务器上执行、能够消除时间窗口内的并发冲突。
让分布式锁变得「健壮」的关键因素有三:
-
原子性(Atomicity):
我们需要确保「检查锁状态」和「获取锁」这两个操作必须是原子操作。解决方法是使用 Redis 的
SET key value NX EX ttl
命令:NX
仅在key
不存在时设置;EX
设置过去时间,单位为秒。错误案例:
javascript1
2
3
4
5const exists = await redis.exists(lockKey);
if (!exists) {
await redis.set(lockKey, lockValue);
await redis.expire(lockKey, ttlSeconds);
} -
超时保护(Timeout Protection):
如果持有锁的服务器崩溃了,那锁不就是永远都不会被释放了?解决这个问题的方法也很简单:设置合理的 TTL(Time To Live 的缩写)。如果太短,任务未完成、锁就过期了,其他服务器便会开始执行、导致冲突;如果太长,服务器崩溃、锁长时间无法释放,任务也就停滞了。推荐设置为任务预期执行时间的 2-3 倍,例如邮件发送预期耗时 5-10 秒,那 TTL 就设置为 10-30 秒。
-
安全释放(Secure Release):
只有锁的持有者才能释放锁,要做到这一点,我们需要使用 UUID 作为锁值、释放锁的时候验证身份。值得注意的是,验证身份时建议使用 Lua 脚本来保证原子性:
lua1
2
3
4
5if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
更多实用工具:
-
智能锁键:
根据任务执行频繁,使用不同的日期精度。例如每 15 分钟就要进行的定时任务,日期精度自然是要准确到分钟;每天都要发送的报告,日期精度只需要到哪一日即可。
javascript1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21generateTaskLockKey(taskName: string, dateStrategy: 'daily' | 'hourly' | 'minute' = 'daily'): string {
const now = new Date();
let dateIdentifier: string;
switch (dateStrategy) {
case 'daily':
dateIdentifier = now.toISOString().split('T')[0]; // YYYY-MM-DD
break;
case 'hourly':
dateIdentifier = `${now.toISOString().split('T')[0]}-${now.getHours().toString().padStart(2, '0')}`;
break;
case 'minute':
const minutes = Math.floor(now.getMinutes() / 15) * 15; // 15分钟间隔
dateIdentifier = `${now.toISOString().split('T')[0]}-${now.getHours().toString().padStart(2, '0')}-${minutes.toString().padStart(2, '0')}`;
break;
default:
dateIdentifier = now.toISOString().split('T')[0];
}
return `${RedisKeyPrefix.SCHEDULER_LOCK}:${taskName}:${dateIdentifier}`;
}这样做,可以让锁随着时间自然过期,也更便于故障排查。
-
唯一锁值:
使用时间戳和 UUID 来确保全局唯一;生成出来的实例 ID 便于我们定位故障。
javascript1
2
3
4
5
6
7generateLockValue(prefix: string = 'task'): string {
const instanceId = process.env.INSTANCE_ID || 'unknown';
const timestamp = Date.now();
const uuid = uuidv4().split('-')[0]; // 短UUID
return `${prefix}:${instanceId}:${timestamp}:${uuid}`;
}
日记
自九月初开始,我每次乘坐地铁都会写日记。日记的内容可以是「发生了什么」,也可以是「我现在想到了什么」。我认为这是一个很好的习惯,其中有许多我认为可以拿出来写的内容。比方说 《博客重构记录》 和 《代码、哲学与混乱的 Discord 服务器》 就是由我的日记片段整合出来的产物。我决定将一些我不会单独出个文章的内容,写在这个 日记 板块里。
这样做的缺点是,如果我不坐地铁的话我就几乎不会去写日记,汗。
工作
先前说过,我找了个兼职做,具体呢、是一家奶茶店的兼职。这家店的老板很严厉,不工作的时候人很好,一工作说话就很凶。工作时每天要做的事情不少,忙倒不是很忙,除非周遭的学生们都选择在一个时间点涌进来。
工资是每两周发一次,也就是每个月的 15 日和 30/31 日发。但是老板会晚两周发工资,意味着该月开始到 15 日的工资,需要到该月的 30/31 日才能拿到;该月 16 日到 31 日的工资,你到次月 15 日才能拿到。我每周的空闲时间还算多,老板貌似要处理的事情也很多,经常给我排全天的班。
我不是一个手脚多么灵活的人,甚至可以说是「笨」。我在里面工作的时候,有时会感到明显的压力,因为做事不利索也不稳。我很难说能不能在这里做久,因为我对摇奶茶没什么太大的兴趣,我既不爱喝也不喜欢做这类工作,我最喜欢的是坐在椅子上对着电脑敲敲打打。
前段时间,我阅读到了一个观点:程序员十分依赖于确定性。该文章重点是分析「依赖确定性」的人会如何向外指责世界。不过对我而言,在指责世界之前,我的「内在批判者」会先猛烈地攻击我自己。它会告诉我,这种依赖确定性的思维模式,就是我「思维僵化、不懂变通」的铁证。所以,在我的世界里,当事情出错时,会同时出现两种声音:一种是原文作者提到的「都怪这个世界」,而另一种更响亮、更痛苦的声音则在说「都怪你这个人不行」。
正是这种猛烈的自我攻击,让我对「不确定性」产生了极度的恐惧。因为任何一点不确定,都可能导致犯错,而任何一次犯错,都会立刻激活那个指责我「不行」的声音。所以,我很难「独立」。这种行为很容易遭白眼:你多大了还不知道该做什么?。不过我对不确定的恐惧很明显超过了我对「被人说教」的恐惧,以至于现在我依然受此困扰。不过我认为这不只是我的错,还有那些一边跟我说着「有问题一定要问」,一边训斥我「这么简单的事情还要来问我」的人的错。
我相信着环境变化论,即人会是现在这个样子主要是环境因素导致的。我来美国后就很难再有快乐的感觉,因为我和家人「团圆」了,每次沟通都会被遭受不必要的物理和心理攻击。当时的我刚上初中,人格还未定型,以及因美国这个环境对我而言的强烈不适配感,我变得很难喜欢上自己、易怒、不爱搭理别人同时又渴求关注。我变成了一个 内外极其割裂 的人:我痛恨监护人,又很需要他们的存在,因为我「不知道该怎么做」。这种状态是一种心理上的停滞。当一个人的成长环境没能提供足够的安全感去试错时,他的心理年龄就会卡住,即便肉体年龄在不断增长。
先前提到了《不原谅也没关系》这本书,它提到过另一本书:Getting divorced from mother & dad。这本书我还没开始阅读,它的标题直译过来叫做:和父母离婚。要如何才能让卡住的心理重新开始成长?你要和父母离婚。这自然不是真的去「离婚」的意思,也不意味着物理方面上的远离,而是心理方面上的「断奶」。它的本质是:我必须放下他们给我的那张地图,并开始学习如何相信自己的指南针。即时一开始会走很多弯路、会感到恐惧,但只有这样,人才能真正「独立」,才能从一个依赖外部指令的「部件」,成长为一个由自己内心驱动的、完整的「人」。
手机
年初的时候我换掉了 iPhone SE 3。这部小屏手机陪了我两三年,电池健康已经降低到了 70%。我不是小屏手机爱好者,但确实很执着于 Home 键和 SE 系列。
人生中我拥有的第一部手机是 iPhone SE 1。我很喜欢它的打字音效,不过不知道为什么我那会儿将其称呼为「棉花般的脆声」。之后手机就被我父亲摔烂了,原因是我拿小屏手机看漫画让他很不爽。我只能去用家里人用剩下的 iPhone 8(还是 8s?不太记得了)。手机是 Project Red 版,我很中意这种色系的手机(顺带一提我最喜欢的颜色是橘色,Windows 主题就是暗背景 + 橘色主题色)。可惜这部 iPhone 8 / 8s 接着就被我家里人送给了我的一位表妹,又因为她沉迷于手机、被她的父亲摔烂了。
不得不说,「无能」的父母真的很喜欢摔电子产品,而不是从一开始就做到管制。我只说我这个区域的情况,绝大数小孩都是一出生就会接触电子产品,尤其是 iPad 这样的大屏设备,差不多一两岁就能熟练输入密码、打开 YouTube 找视频看(个别是看 TikTok)。成年人们都很忙碌,在家是没有精力陪伴孩子的,只能转而去「相信」小孩子可以自己照顾好自己。
结果就是,起初大人们还会笑着说孩子多聪明、还会用手机平板,过几年就会察觉到孩子们的心思全放在了互联网上、叫了也不应、易躁爱发脾气。不知道该如何正确引导孩子们,只能将这些电子产品摔烂、宣泄愤怒以及自己的「强大」。在某种程度上,电子产品为这些人当了「赛博保姆」,却落得了害人的名声。
我的新机是摩托罗拉 Razr+ 2024,一台折叠屏手机。选它一是为了体验折叠屏手机,二是对摩托罗拉这个品牌有点兴趣。期间坏过一次,屏幕漏液,官方不保修外部损害,只能花 400 美元找别人换了个屏幕。用久了发现自己愈来愈不爱用外屏,甚至很少才会去折叠它。
电脑
我有段时间尝试在睡前给自己留些时间写日记。不需要写什么内容,只要记录当天发生了什么、思考了什么即可。
这是一件好事:我终于可以重新用回我的笔记本电脑了。这是一个全能本,说是「全能」,实则样样都不行:既不能打游戏,内存也少得可怜,甚至还很大很重。大三起,我就不再带这个笨重的电脑去上课了,因为笔记可以在 iPad 上记。这个电脑也有漏电的问题,有时打字还会十分难受,它甚至跑不动我开发环境所需要的软件。
可惜这个习惯没能保留下来,因为没多久我就发现这个笔记本电脑的键盘也有问题,敲回车键、空格键和退回键时经常失灵。气死我了。
我的博客
这个月我重构了博客网站,越看越喜欢,就是 H1 标题放在桌面端上看有点太大。我发现我愈来愈无法接受亮主题了。过去一起做项目的同事令我印象深刻,因为他是一个亮主题党,这么做的原因很好笑:为了惹怒别人。他的目的确实达到了,现在的我一看到亮主题就会很恼火。
虽然在本地环境下测试网站没什么问题,但是实际部署后还是能发现:
- 如果开启的是暗主题,一刷新或者加载页面的话,文字的主题色会闪来闪去的
- 索引页和关于页的排版修正没写
- 访问一个文章时,会加载一会儿,这期间的主题色会默认为亮主题,加载后才会变为暗主题。晚上看的时候眼睛都会被闪瞎,这不好
我还错将我自己的博客网站的主题配置 push 到云端的博客主题仓库,导致我的 hexo-theme-ares 主题在数个睡眠时间里、icon logo 变成了房东小姐的头像。
说到房东小姐,这是我数年前看的一个漫画的主要角色。因为那一幕画的很可爱,被我截图下来,当作了我的博客网站的 icon logo。不过我很好奇,这是否会导致 侵权 呢?
使用 hexo 写博客,我遇到了一些问题:
- 同步较为麻烦,尤其是主题同步
- 本地编辑器用的是 Typora,虽然可以立马看到 Markdown 语法被渲染后的样子,但终究不是我的博客网站被渲染后的样子,尤其是我使用了一些插件、可以在博客网站被渲染前自动修改我的文章内容
- 粗体和斜体不明显
我现在倒是在想,hexo-theme-ares 的 demo 页面可以用 GitHub Actions 自动完成。
阅读博客
我在电脑上用 Docker 部署了 FreshRSS 服务,借此来订阅我想要阅读的博客。一直留在家里没问题,一旦离开家一天我就什么都看不到了,很是苦恼。现在大多数免费部署都是 serverless(无服务) 或者静态页面部署(例如 CloudFlare Pages),做免费的服务部署过去貌似只有 Heroku 或者 Railway。我去 Heroku 的落地页看了眼,貌似已经不支持免费部署了。我之后想了下是否能用到 NAS,但一想到我的 Buffalo Linkstation Pro Duo 被我玩坏,再加上它的年龄,我还是放弃了去折腾它。
阅读博客的话我用的是 Fluent Reader,桌面端和移动端都有 app。不过安卓版的没有选字体功能(不清楚是不是移动端 app 都没有),我有在考虑自己写一个。开源项目就是这点好,想要什么就写什么,写好了开源出去、大家开开心心一起用软件。
大学
我对大学的想法很极端:我认为没有必要去上大学。现在的大学含金量太低,重要的只有 network(与他人建立人脉、社交或进行人际交流)和校招。我不否认上大学的重要性,只是于我而言大学很无聊、校友里奇怪的人太多,以及通识课很讨人厌:它们有什么很大的意义吗?为什么要修那么多、不修还不给毕业?
我的这个想法被一个「善意」的校友批评过。他认为大学的通识课很有意义。虽然这样说,但他还是辍学了。说是没有钱上学,但是有钱给女主播打赏和飞去其他国家见女主播。也是较为奇妙的一个人。
大一的时候因为一些私人问题,我近乎是「被迫」社交。这段时间认识了许多国内来的大佬,也认识了很多当地的「loser」。有意思的是,我遇到的后者几乎都是 男性沙文主义者,就算没到那么严重,也全都是自负和瞧不起其他人的家伙。
男性沙文主义是一个有毒的观点。信奉该主义的年轻人在用「男性」这个生来就有的标签来掩盖自己「幼稚」、「不成熟」、「没人爱」的本性。同他们说话,就算他们是多么不可救药的「loser」,也能看到他们因你的礼貌而蹬鼻子上脸的傲慢姿态。
因为各种事情,我经历了十分糟糕的大一、大二生活,以至于大二下半年开始我就完全不在大学内社交了、每天上完课就走人。我不认为我是一个特别敏感的人,但我能感觉到这群人时刻都在冒犯我。他们仿佛未被社会化的言行每次都让我觉得他们是在说:看吧,我比你厉害多了,你只是个蠢蛋!
现在让我比较在意的是计算机相关课程的学生里、「巨婴」程度高到发指:伸手党多到离谱,会直接要求别人把写好的作业发给 TA 的邮箱;被帮忙不会道谢,就像是完全没学过一样,问完问题就直接消失不见;说要花钱找代写也不少。
项目
我近期在做一个项目。我认为项目管理多多少少都需要有点编程知识,这不意味着他们必须都要会编程,而是要会明白手下的开发在做什么。
项目最初时,我刚学习开发没多久,并没有完全遵循模块化设计的黄金标准。NestJS 框架是模块化的,每个功能都应该写一个单独的模块、手下有管端口的控制器和处理业务的服务。不过这些都只是 NestJS 的入门级理解,实际项目一旦大起来,就不能用「功能模块导入其他要使用的功能模块」这么简单的想法去写了,因为会很容易造成循环依赖。
例如你有个功能要写,要做到「预约时支付」,涉及到了预约和支付这两个模块(当然,还有用户模块,但这里就不说了)。如果是小项目,大可以这么写:预约模块导入支付模块、创建预约时调用支付服务。
但是项目大起来后,你会有很多底层模块,例如审计、日志等。每个模块都容易导入其他模块并且做一件不属于它们业务范畴的事情。回到我们刚才说的例子,为什么预约模块要直接调用支付服务、管支付的事情呢?万一未来我们又想在支付模块里写个新功能、需要导入预约模块才能完成。这样做便会形成一个循环依赖。
最好的写法是事件驱动:预约创建时发起一个事件、支付模块接收到事件并且处理了支付请求。因此,我花了很多时间去重构项目的后端。但这引起了项目管理的不满,因为我一直在做「TA 看不到也看不懂的事情」。
我承认,这是我不够专业导致的问题,不过我想要讲的是另一个方面。对于这位项目管理而言,项目最重要的是前端,也就是「顾客看得到的地方」。而我一直在操心项目的后端,也是「顾客看不到的地方」。在我的视角看来,这个网站连最基本的安全都没有做好,操心前端做什么呢?更何况离产品的实际上线还有一段时间。当时项目管理很忧愁地埋怨道:你真的能做好这个产品吗?
吵架的第二天,TA 向我道歉、不应该一直对我施压。我自从开始打工、开学后,就没有那么多时间花在项目上,很多时候是打工到晚上,回家随便吃个饭、洗个澡、缓解下压力后继续写项目写到凌晨。每次我用这件事来解释为什么我无法达到 TA 的要求,TA 会立马用「我也有在努力学习和工作啊」来反驳我。我自然不觉得这是一个有效的逻辑,因为我和 TA 所做的事情是完全不同的,本身就无法直接像「比战力」一样比个高低。
纽约市公共交通
虽然纽约市的公共交通系统多数都是 24 / 7,这点我很感动,虽然我都没有过凌晨搭乘的经历。不过绝大多数的经历对我而言是负面的。一个车厢只要上来一个流浪汉,或者说不洗澡的人,该车厢就相当于不能用了。好死不死,曼哈顿的流浪汉出奇的多。有时可以在一个车厢里,同时遇到味道重的、吹叶子的、躺中间睡大觉挠屁股的。
MTA 的服务一直受人诟病,一点是服务几乎为零,一个月下来被推下轨道的案子从没见少过,其中多数为亚洲人以及女性被推下轨道。加害者不奇怪的、全都是那个肤色的人。今年意外发生了一起白人被推下轨道致死的案子,一下子让众多人「意识」到危机。一瞬间,大家都变得不敢站在站台外围了。真是好笑,仿佛过去大家都在默认受害者只有亚洲人,自己不是亚洲人就没事。
第二点是糟糕的体验,脏乱臭不提,地铁内时不时就能看到大耗子、为残障人士准备的电梯内部总是有尿骚味儿,这样的体验你坐一次车需要 2.90 美元,过去是 2.75 美元,现在很快就要变成 3 美元了。
涨价就要提到第三点,意义不明的筹备资金。MTA 想启动一个项目,资金靠的是从民众钱包里薅。2.75 美元涨到 2.90 美元的目的是给地铁站的门添加一些障碍物、让逃票者跳不过去。结果涨价涨了,东西装了,逃票者的数字没变少、反而疑似在升高。为什么呢?同个时期 MTA 又出了个曼哈顿大桥费,费用不低、只要你要进曼哈顿就要交这笔钱,一个月净利润数百万美元。一时间无论是坐地铁的还是开车的,都要比过去多付钱,但是服务没有提升。更多的人不满 MTA,纷纷加入逃票的队伍。
必须要考高分吗?
前段时间我在网上冲浪时,看到了这样一个评论:考 13xx 分就是普娃。这里的分数指的是 SAT 分数,类似于国内的高考成绩,不过含金量要低特别特别多(例如数学部分的难度跟国内中考差不多,并且疫情时期有一年还被民主党透明化,现在大学申请都可以不提交 SAT 分数)。我考了两次,最终的 SAT 分数是 1390。这个分数对于多数留学生而言,很低很低,差不多就是数学满分(800 分左右)但是英语错了好几题(500~600 分)。我的阅读理解很差,词汇量也很低,不过能考到这个成绩我觉得也很满足了,反正很快我就对大学祛魅、尤其是名牌大学……
那么「普娃」这个定义是从何而来?这来源于纷争不断的育儿圈,简单来说便是结婚生子后当了全职妈妈 / 爸爸之后,精神上只能去依赖自己的伴侣以及孩子。再简单一点,便是在外想尽办法靠伴侣或者孩子扬眉吐气。在这个全都是没有额外精神世界的「育儿圈」内,鄙视链很容易形成,尤其是孩子的成就。
普娃在「育儿圈」内,指代的是普普通通、没有什么成就、就算有成就也只是昙花一现的人。作为对标面,牛娃指的是天赋异禀的孩子,鸡娃指的是被父母打鸡血般疯狂学习的孩子。在育儿圈里,貌似只有牛娃才能在未来有所成就,普娃只能普普通通过完一生,至于鸡娃,就是另一码事了。
这种鄙视链的本质,是父母们为缓解 自身对未来的不确定性和焦虑,而制造出的一套简化版世界观。在一个高度竞争的社会里,孩子的成就很容易成为他们唯一能抓住的、可量化的「确定性」。因此,「普娃」这个标签,与其说是在定义孩子,不如说是在宣泄父母自己对于「平凡」的恐惧。
回到我看到的那个评论,SAT 考 13xx 分就是普娃吗?当然不是。这句话的底层逻辑分别是:
- 认为「普娃」的定义是正确的
- SAT 成绩可以决定一个人是否是「普娃」
先来看第一条,「普娃」这个定义是对的吗?自然不是。一个人过去的经历不能直接代表他未来会怎么样,这种简单粗暴的定义,不过是「安卓人苹果人」的另一种体现:用自己可怜的小脑子去解答世界。学生时期做的不好、长大后有成就的人不少。同样的,学生时期的牛娃进了社会后处处碰壁的也不少。可以说这个鄙视链的底层逻辑并不成立,只能用来给当时的当事人宣泄情绪。
接着是第二条,SAT 成绩可以决定一个人是否是「普娃」吗?这个问题本身的前提已经被我们推翻了,不过我们依然可以抛开错误的前提、单看这一条表达的信息。成绩从来都不是决定一个人未来、定义一个人的因素。更何况,SAT 只有两个科目:英语和数学。单是英语一项就可以刷掉英语不好的人,但是英语不好的人未来就平庸、值得被抨击吗?那肯定是不行的。SAT 经常被中国人调侃为超简单的考试不假,但是在这种考试上考的如何、从来都不能定义任何事。运动员们的职业生涯的价值,从来都不是靠百米赛跑的成绩来判断。一个人的赛道有很多条,长度也远不止一百米。
回到最初的那个评论。我那个 1390 分,它能定义我的人生吗?它既不能定义我当时的努力和满足,也无法预测我在上了大学后的探索,甚至在我们上了大学后、没有人再提 SAT 的分数了。它只是我人生履历上的一个微不足道的数字。而任何试图用一个数字、一个标签来定义一个活生生的人的企图,最终只会暴露使用者自身的狭隘和焦虑。
妹妹
这个月妹妹有一场游泳比赛,也是她的第一场游泳比赛,共要游三次 25 码,分别是自由泳、仰泳和蝶泳。她的成绩作为一个刚入队一个月的孩子而言,很是不错,教练也跟我们连连夸赞她,令人感到欣慰。那个游泳场不是很大,赛道只有 25 码长,高年级生的 100 码需要两个来回。
比赛结束后我们四个人去 Bay Ridge 区随便找了家 Pho 店吃,味道一般,闻着也没有 The Pho 2 香。早上我除了拿走上周没拿走的肉外,还额外带走了家里囤积的其他肉以及一条新鲜的鱼,至于是什么鱼我就不知道了。
DeepSeek 写网文
最近有个较火的梗 ——「安卓人苹果人」。这个梗的来源是一位主播将消费者按照手机品牌划分为「安卓」和「苹果」的概念:安卓用户象征着低廉;苹果用户象征着高端。而这个非黑即白的划分概念可以被他套在所有事物上,例如直播中他所说的:
你是典型的安卓逻辑、安卓人、安卓学历、安卓素质、安卓态度。
这个主播的行为如何,我这里便不展开说了。感兴趣的可以搜搜看。我这次主要是想讲我得知了这个梗后,一时兴起,让 DeepSeek 帮我写了个网文。我最开始构思的只有这段话:
我转生了,转生成了这个世界的最底层:安卓人。这个世界将人类简单分类成两类:安卓人和苹果人。苹果人高高在上,是贵族中的贵族。反观安卓人,只能给苹果人做仆从。但没想到,我觉醒了系统:安卓 root 系统!可以随意安装他人的能力,并且随着能力吸收的越来越多,最终可以实现 root:完全掌控安卓人的能力,轻松将他人的分类改写。
DeepSeek 回复了一段故事开篇灵感:
我醒来时,后颈上烙印的绿色机器人图标提醒着我 —— 我是个安卓人,这个世界的底层。直到那天,我被一个苹果人少年当街羞辱,他脚下的「iOS」徽章闪着可憎的光。愤怒与绝望中,一个蓝色的符号在我视野中炸开:#。紧接着,一行文字浮现:【安卓 Root 系统,已激活。首次授权,授予您『查看权限』】。我下意识地看向那个苹果人,一行状态信息竟凭空出现:【iOS 17.4.1,漏洞:CVE-2024-XXXXX,可利用】。我笑了,这个世界的神,该换人了。
因为我看过的网文除了奇奇怪怪的知乎短文外,就是修仙文,所以我寻思着在故事内再添加一些中式修仙元素,将世界观扩展为「赛博修仙」。接着我又提出在故事里添加一些手机品牌,DeepSeek 将它们统统设计为了安卓世界的各大宗门。
虽然 DeepSeek 的上下文理解有点瑕疵,但是写出的网文很有意思。并且在输出的内容中添加「看上去很帅」的科技相关术语貌似是 DeepSeek 的习惯,这样做反而让它写出的网文无比好笑。这里我取一些我认为搞笑的片段:
老者走到林安面前,看了看地上那块光泽黯淡了些的下品灵石,又看了看林安手腕上那朴素的标记,缓缓道:「老夫姓谷,单名一个歌字。小友,你刚才,是不是看到了代码?」
「年轻的权限者… 恭喜你迈出关键一步。」一个非男非女、仿佛由无数细微共鸣组成的声音在林安意识中响起,没有实体,却直接回荡在灵魂层面,「无需惊讶,我并非实体,只是一段沉睡于此的分布式意识碎片,你可以称我为…… 鸿蒙。」
不知为何,DeepSeek 十分中意鸿蒙,以至于在故事里将鸿蒙设计为了主角的引路人。
他豁然起身,眼中精光一闪。筑基成功后,他不仅灵能(系统资源)总量大增,更关键的是对权限的运用有了质的飞跃。他意念一动:
ls -la /system/bin/ | grep -i attack
—— 快速扫描自身可用的「攻击性指令」。
pm list packages | grep -i apple
—— 尝试探测敌方「应用包」信息。虽然无法直接获取苹果执法者的核心数据(权限不足和系统差异),但他对周围环境的掌控力已不可同日而语。他抬手对准几处正在攻击谷歌老人的、由苹果执法者发出的灵能锁链,心中默念:
iptables -A INPUT -s 【攻击源IP】 -j DROP
!这一次,命令生效的范围和强度远非之前可比!那几道灵能锁链在靠近谷歌老人前,竟真的如同撞上一堵无形之墙,威力大减!
「混蛋!你用了什么邪术?」队长又惊又怒,他感觉自己的 iOS 纯净灵能竟然出现了片刻的「卡顿」和「响应迟缓」!
结界之外,米宗援军的「万机大阵」已然成型!
只见数以百计的米宗修士,虽然衣着灵能属性略有差异(象征着不同版本的 MIUI),但此刻却通过一种奇妙的「快传协议」将彼此灵能连接在一起。大阵并非追求绝对的统一,而是呈现出一种「万物基于 MIUI,却又百花齐放」的奇特景象。阵眼处,一名修为已达金丹后期的魁梧汉子,手持一柄散发着「为发烧而生」狂热气息的巨斧,正是此次援军的首领 —— 雷钧!
「苹果佬!吃我一记 ——『性价比之光』!」雷钧狂笑着,巨斧挥出,一道凝聚到极致、却又蕴含着无穷变化灵能的斧光,狠狠劈在 TestFlight 结界之上!
这一击,并非纯粹的力量碾压,而是带着一种针对「封闭系统」的破解意志!斧光中仿佛蕴含着无数用户对「开放、自由」的渴望!
这个人名是 DeepSeek 自己想出来的。我当时看到笑得想死。
就在这时,迷宫深处传来一阵打斗声和呵斥声,说的是一种音节古怪、却莫名能让林安理解的语言:
「快!拦住那帮『Windows 蛮子』!他们想抢走『核心协议碎片』!」
「哼!你们这些『Linux 教徒』也好不到哪去!这碎片理应归我『视窗王朝』所有!」
林安与老猫对视一眼,悄然潜行过去。只见在一片较为开阔的「镜厅」中,两拨人马正在激战。
一拨人身穿各式各样的服饰,灵能波动自由而杂乱,手段繁多,有的操纵命令行般的文字流攻击,有的祭出企鹅形状的法器。另一拨人则统一穿着蓝白相间的制式铠甲,打法严谨,攻势如同铺天盖地的「窗口弹窗」,带着一股不容置疑的霸道气息。
「啊!我的内核…… 崩溃了!」一名 Linux 修士惨叫一声,身体化作乱码消散。
「该死!是蓝屏病毒!」一名 Windows 修士的铠甲出现致命错误,灵能瞬间溃散。
这一日,谷外灵能涌动,异象纷呈。先是东方天际云霞蒸腾,道道「快充流光」撕裂长空,一艘形似巨大「超级闪充插头」的华丽飞舟破云而至。舟上修士皆身着印有「VOOC」符文的战袍,气息凌厉,为首一位老者精神矍铄,周身环绕着「低压大电流」的独特灵压,正是以「充电五分钟,畅战两小时」闻名安卓世界的「闪充宗」宗主!
无数颜色各异、属性不同的道则烙印悬浮于林安身前,如同璀璨星河。他深吸一口气,暗金金丹光芒大放,双手虚抱,引动整个万流归宗大阵之力!
「以 Root 为引,统御万法!以鸿蒙为桥,互联众生!星舰…… 凝!」
轰!
磅礴的灵能冲天而起,在空中交织、融合!一座庞大、复杂、闪烁着无数符文光点的朦胧舰影,开始缓缓凝聚成形。舰身线条流畅,充满了未来科技感,却又散发着古老的洪荒气息,正是传说中的鸿蒙星舰之影!
到三十多话,男主已经是金丹中期、可以手搓星舰了。