普通视图
Swift 闭包捕获列表深度解析:内存管理的关键技术
Xcode 26.3 炸裂更新:原生支持 AI Agent 编程
坏习惯是道好题目
我曾有一个坏习惯:常常会忍不住打开推特,看看有什么新闻(尤其是 AI 技术日新月异的当下,容易 FOMO)、关注的人又发布了什么动态、自己的推文有没有被点赞或评论。一开始倒没觉得有什么问题,但当这个行为的发生频率变高之后,我意识到它带来了明显的负面影响:注意力难以集中,思维变得碎片化。于是我想改掉这个坏习惯。
改掉坏习惯不是一件容易的事,所以我把它当作一个课题来研究。首先做的是认知校正:坏习惯不是自身的某个缺点,而是一种被错误引导的能量,是可以被调整的行为,它有对应的习惯回路:触发器(Trigger) -> 行为(Action) -> 奖励(Reward)。
在「刷推」这个 case 里,Trigger 往往是潜意识里的某种不适感(任务太难、无聊、焦虑),Action 是打开推特,Reward 则是短暂的愉悦感和多巴胺分泌。要解开这道题,需要在回路的每一个节点设置观察点和阻断机制。
虽然控制外界的 Trigger(如工作压力)很难,但我们可以识别它。当那个「想刷推」的念头升起时,不急着行动,而是采用「冲动冲浪」(Urge Surfing) 策略:面对冲动(海浪),不筑墙(不压抑),也不随波逐流(不执行)。你踩在滑板上,看着那个浪头升起,感受它的最高点,然后随着它自然落下。
如果这个动作过于自然,以至于来不及冲浪,就需要引入「异物」来唤醒显意识。比如给手机绑一根橡皮筋,这个突兀的触觉会把你从潜意识的自动导航中强行拉出来。
如果冲浪失败,没有熬过浪尖的峰值体验,我们还可以从 Action 入手,增加执行难度。
最有效的方式是环境构建:把手机放到够不着的地方、调至灰度模式,或者去图书馆,让学习的氛围带动自己去学习,同时增加刷手机的心理负担。
如果还是突破了防线,那么就借助坏习惯的动量,绑定一个新的微习惯。我做了一个 Chrome 插件,在每次打开推特页面时,都会弹出一个对话框,要求输入一段预设的文字。这个绑定的微习惯必须满足低脑力消耗、中低执行难度的特点,否则很容易因为成本过高而被跳过。
如果还是开始了这个习惯行为,那就在 Reward 环节做文章。
首先是定时,避免越陷越深。其次是关键的一步:「不带评判的观察」。当带着这种心态去进行那个坏习惯时,会发现它并没有想象中那么有吸引力。如果大脑的预判奖励是 10 分,实际体验下来可能只有 3 分。一旦大脑更新了这个奖励价值(Reward Value),意识到「原来这件事也就那样」,它对这个行为的渴望就会自然下降。
做到以上几步,坏习惯可能暂时被压制了,但解题还没有结束。大脑极其厌恶真空。如果你拿走了一个坏习惯,却没在原地填入一个新东西,那个功能空洞(比如原本用来缓解无聊或焦虑的时间段)会产生巨大的吸力,把你拽回原来的轨道。
此时需要寻找替代行为,重构生态位。这个替代品需要具备两个特征:
- 启动成本极低:就像刷推一样容易开始。
- 反馈即时:能立刻提供某种程度的满足感或安抚感。
比如,当无聊袭来时,可以是用 Kindle 读一页书、整理昨天的笔记、玩一局 Wordle,或者仅仅是站起来做 3 个深呼吸。用这些良性的「微行动」,去占领原本属于坏习惯的生态位。
当这道「题目」被拆解到这个程度,你会发现,改掉坏习惯不再是一场痛苦的意志力拉锯战,而是一次有趣的、关于自我认知的系统重构。
坏习惯是道好题目,因为这个过程可以强化自己的「觉察」能力、认知重构能力(坏习惯不等于缺点,坏习惯可以被用来绑定好习惯等)和产品设计能力(如何设计一套行之有效的解决方案),这些能力很基础又有很强的通用性,可以用来应对其他的坏习惯,帮助构建自己的「心智操作系统」。
最近一周AppStore卡审严重么?
彻底告别 iOS 13+ 输入框“时隐时现” —— 深度解析嵌套布局与键盘库冲突
变幻的光影,不变的干草堆 -- 肘子的 Swift 周报 #121
SwiftUI快速入门指南-Viewbuilder篇
变幻的光影,不变的干草堆 - 肘子的 Swift 周报 #121
两周前,借着参加 iOS Conf SG 2026 的契机,我造访了新加坡国立美术馆,并有幸参观了《走进现代:波士顿美术博物馆印象派大师展》。尽管此前也看过不少优秀的展览,但这次经历仍带来了某种不同寻常的触动。
Swift 中 unowned self 的隐晦陷阱:为什么“无主引用”可能毁掉你的 App
lld 22 ELF changes
For those unfamiliar, lld is theLLVM linker, supporting PE/COFF, ELF, Mach-O, and WebAssembly ports.These object file formats differ significantly, and each port mustfollow the conventions of the platform's system linker. As a result, theports share limited code (diagnostics, memory allocation, etc) and havelargely separate reviewer groups.
With LLVM 22.1 releasing soon, I've added some notes to the
For the first time, I used an LLM agent (Claude Code) to help lookthrough commits(git log release/21.x..release/22.x -- lld/ELF) and draftthe release notes. Despite my request to only read lld/ELF changes,Claude Code also crafted notes for other ports, which I retained sincetheir release notes had been quite sparse for several releases. Changesback ported to the 21.x release are removed(git log --oneline llvmorg-22-init..llvmorg-21.1.8 -- lld).
I'll delve into some of the key changes.
-
--print-gc-sections=<file>has been added toredirect garbage collection section listing to a file, avoidingcontamination of stdout with other linker output. (#159706) - A
VersionNodelexer state has been added for betterversion script parsing. This brings the lexer behavior closer to GNU ld.(#174530) - Unversioned undefined symbols now use version index 0, aligning withGNU ld 2.46 behavior. (
#168189) -
.data.rel.ro.hotand.data.rel.ro.unlikelyare now recognized as RELRO sections, allowing profile-guided staticdata partitioning. (#148920) - DTLTO now supports archive members and bitcode members of thinarchives. (
#157043) - For DTLTO,
--thinlto-remote-compiler-prepend-arg=<arg>has beenadded to prepend an argument to the remote compiler's command line. (#162456) - Balanced Partitioning (BP) section ordering now skips input sectionswith null data, and filters out section symbols. (
#149265) ( #151685) - For AArch64, fixed a crash when using
--fix-cortex-a53-843419with synthetic sections andimproved handling when patched code is far from the short jump. (#170495) - For AArch64, added support for the
R_AARCH64_FUNCINIT64dynamic relocation type for relocating word-sized data using the returnvalue of a function. (#156564) - For AArch64, added support for the
R_AARCH64_PATCHINSTrelocation type to support deactivation symbols. (#133534) - For AArch64, added support for reading AArch64 Build Attributes andconverting them into GNU Properties. (
#147970) - For ARM, fixed incorrect veneer generation for wraparound branchesat the high end of the 32-bit address space branching to the low end.(
#165263) - For LoongArch,
-rnow synthesizesR_LARCH_ALIGNat input section start to preserve alignmentinformation. (#153935) - For LoongArch, added relocation types for LA32R/LA32S. (
#172618) ( #176312) - For RISC-V, added infrastructure for handling vendor-specificrelocations. (
#159987) - For RISC-V, added support for statically resolved vendor-specificrelocations. (
#169273) - For RISC-V,
-rnow synthesizesR_RISCV_ALIGNat input section start to preserve alignmentinformation during two-stage linking. (#151639)This is an interesting relocatablelinking challenge for linker relaxation.
Besides me, Peter Smith (smithp35) and Jessica Clarke (jrtc27) havedone a lot of reviews.
jrtc27 has done great work simplifying the dynamic relocation system,which is highly appreciated.
I should call out
Distributed ThinLTO
Distributed ThinLTO(DTLTO) enables distributing ThinLTO backend compilations toexternal systems (e.g., Incredibuild, distcc-like tools) during the linkstep. This feature was contributed by PlayStation, who had offered it asa proprietary technology before upstreaming.
The traditional distributed ThinLTO is implemented in Bazel in buck2.Bazel-style distribution (build system orchestrated)uses a multi-step workflow:
1 |
# Compile to bitcode (made parallel by build system) |
The build system sees the index files from step 2 as outputs andschedules step 3 jobs across the build cluster. This requires a buildsystem that handles dynamic dependencies—outputs ofstep 2 determine inputs to step 3.
DTLTO (linker orchestrated) integrates steps 2-4into a single link invocation:
1 |
clang -flto=thin -c a.c b.c |
LLD performs the thin-link internally, generates a JSON jobdescription for each backend compilation, invokes the distributorprocess, waits for native objects, and links them. The distributor isresponsible for farming out the compilations to remote machines.
DTLTO works with any build system but requires a separate distributorprocess that speaks its JSON protocol. DTLTO is essentially "ThinLTOdistribution for projects that don't use Bazel".
Pointer Field Protection
R_AARCH64_PATCHINST is a static relocation type usedwith Pointer Field Protection (PFP), which leverages Armv8.3-A PointerAuthentication (PAC) to protect pointer fields in structs.
Consider the following C++ code:
1 |
struct cls { |
With Pointer Field Protection enabled, the compiler generates PACinstructions to sign and authenticate pointers:
1 |
load: |
Each PAC instruction is associated with anR_AARCH64_PATCHINST relocation referencing adeactivation symbol (the __pfp_ds_ prefixstands for "pointer field protection deactivation symbol"). By default,__pfp_ds__ZTS3cls.ptr is an undefined weak symbol in everyrelocatable file.
However, if the field's address escapes in any translation unit(e.g., someone takes &c->ptr), the compiler definesthe deactivation symbol as an absolute symbol (ELFSHN_ABS). When the linker sees a defined deactivationsymbol, it patches the PAC instruction to a NOP(R_AARCH64_PATCHINST acts as R_AARCH64_ABS64when the referenced symbol is defined), disabling the protection forthat field. This is necessary because external code could modify thepointer without signing it, which would cause authenticationfailures.
The linker allows duplicate definitions of absolute symbols if thevalues are identical.
R_AARCH64_FUNCINIT64 is a related static relocation typethat produces an R_AARCH64_IRELATIVE dynamic relocation (
PFP is AArch64-specific because it relies on Pointer Authentication(PAC), a hardware feature introduced in Armv8.3-A. PAC providesdedicated instructions (pacda, autda, etc.)that cryptographically sign pointers using keys stored in systemregisters. x86-64 lacks an equivalent mechanism—Intel CET providesshadow stacks and indirect branch tracking for control-flow integrity,but cannot sign arbitrary data pointers stored in memory.
Takeaways:
- Security features need linker support. This is because many featuresrequire aggregated information across all translation units. In thiscase, if any TU exposes a field's address, the linker disablesprotection for this field everywhere The implementation isusually lightweight.
- Relocations can do more than fill in addresses:
R_AARCH64_PATCHINSTconditionally patches instructions toNOPs based on symbol resolution. This is a different paradigm fromtraditional "compute address, write it" relocations.
RISC-V vendor relocations
RISC-V's openness encourages vendors to add custom instructions.Qualcomm has the uC extensions for their microcontrollers; CHERIoT addscapability-based security.
The RISC-V psABI adopted the vendor relocation system:
1 |
Relocation 0: R_RISCV_VENDOR references symbol "QUALCOMM" |
The R_RISCV_VENDOR marker identifies the vendornamespace via its symbol reference. The subsequent relocation uses avendor-specific type number that only makes sense within that namespace.Different vendors can reuse the same type numbers without conflict.
In lld 22:
- Infrastructure for vendor relocations was added (
#159987).The implementation folds vendor namespace information into the upperbits of RelType, allowing existing relocation processingcode to work with minimal changes. - Support for statically-resolved vendor relocations was added (
#169273),including Qualcomm and Andes relocation types. The patch landed withoutinvolving the regular lld/ELF reviewer pool. For changes that setarchitectural precedents, broader consensus should be sought beforemerging. I've commentedon this.
The
There's a maintainability concern: accepting vendor-specificrelocations into the core linker sets a precedent. RISC-V is uniquelyfragmented compared to other LLVM backends-x86, AArch64, PowerPC, andothers don't have nearly as many vendors adding custom instructions andrelocations. This fragmentation is a direct consequence of RISC-V's opennature and extensibility, but it creates new challenges for upstreamtoolchain maintainers. Accumulated vendor-specific code could become asignificant maintenance burden.
GNU ld compatibility
Large corporate users of lld/ELF don't care about GNU ldcompatibility. They add features for their own use cases and move on. Idiligently coordinate with binutils maintainers and file featurerequests when appropriate. When lld implements a new option or behavior,I often file corresponding GNU ld feature requests to keep the toolsaligned.
This coordination work is largely invisible but essential for thebroader toolchain ecosystem. Users benefit when they can switch betweenlinkers without surprises.
Link: lld 21 ELFchanges
呼吸能改变很多事
我们都知道应该去做那些「难而正确」的事。我们熟读各类方法论:建立系统而非仅盯着目标;先确立身份认同再行动;利用福格行为模型微调习惯……但在现实的引力面前,这些道理往往显得苍白。
因为正确的事通常伴随着当下的痛感(或者枯燥),且反馈周期漫长。相比之下,大脑更原始的本能总是倾向于那些即时满足的选项。
当注意力即将滑向短期快感时,我们需要的不是宏大的意志力,而是一个微小的「阻断器」。深呼吸,就是这个阻断器。
这并非玄学,而是有着明确的生理机制。当我们焦虑或冲动时,身体由处于「战斗或逃跑」的交感神经主导。而深呼吸——特别是呼气长于吸气的呼吸——能激活迷走神经,强制启动副交感神经系统。这就像是给高速运转的大脑物理降温,将我们从应激状态强行拉回「休息与消化」的理智状态。
给自己设一个微小的「绊脚石」:在想要下意识点开那个红色 App 之前,或者伸手拿烟之前,深呼吸 3 次。
这里的难点在于「记得」。在多巴胺渴望飙升的瞬间,理智往往是缺席的。所以,不要指望意志力,要依靠环境暗示。比如给手机套一根橡皮筋,利用这个物理触感的停顿,给自己 3 秒钟的窗口期。如果不做这个动作,惯性会带走你;做了这个动作,选择权才更容易回到手中。
如果说深呼吸是急救包,那么冥想就是长期的肌肉训练。
冥想的核心功效,是培养一种「旁观者」的视角。它能帮我们对抗「注意力经济」的掠夺,打断「刺激-反应」的自动化回路。经过冥想训练的大脑,具备更敏锐的「觉察力」。当你下意识地刷手机时,大脑会突然亮起一盏灯:看,我产生了一个想寻求刺激的念头。
在这「被看见」的一瞬间,你就不再是情绪和欲望的奴隶,而是它们的主人。
现代的注意力经济通过高密度的感官轰炸(短视频、爆款标题),不仅拉高了多巴胺阈值,还让多巴胺受体变得极度迟钝。我们像耐药性极强的病人,对低刺激的事物(读书、深度思考、发呆)感到无法忍受的枯燥。
我们丧失了「无聊」的能力,而无聊恰恰是创造力的温床。冥想本质上是一件主动拥抱无聊的事。通过坚持冥想,你在为大脑进行「多巴胺排毒」,恢复受体的敏感度,重新学会如何与「无刺激」的状态相处,并从中获得平静的喜悦。
除了有点无聊,践行冥想最大的阻力,往往来自于我们把它看得太重,试图寻找一段「不被打扰」的完美时间,更高效的策略可能是「缝隙冥想」。
比如通勤的地铁上、排队等咖啡的间隙、或者是午休结束准备开始工作的瞬间。这些时刻原本也是「垃圾时间」,通常会被用来刷手机填补空白。如果能用这 3-5 分钟来关注呼吸,不需要特意调整坐姿,也不必追求绝对的安静,只要把注意力从纷乱的思绪中收回来。
这种「微冥想」虽然短暂,但因为它发生在高频的、甚至有些嘈杂的日常场景中,反而更能训练我们在混乱中随时「调用」平静的能力。
归根结底,我们无法控制外界的信息洪流,也难以完全屏蔽生活的噪音,但我们始终拥有控制自己呼吸的自由。
在刺激和反应之间,有一个空间。在那个空间里,藏着我们要选择的反应。在我们的反应里,藏着我们的成长和自由。
呼吸,就是撑开这个空间的支柱。它不是为了让你变成一台更高效的执行机器,而是为了让你在这个加速的世界里,依然能保有停顿的权利。在这个微小的停顿里,你不再是算法的猎物,而是自己的主人。
RxSwift 中 asDriver() 详解
lld 22 ELF changes
LLVM 22 will be released. As usual, I maintain lld/ELF and have addedsome notes to
-
--print-gc-sections=<file>has been added toredirect garbage collection section listing to a file, avoidingcontamination of stdout with other linker output. (#159706) - A
VersionNodelexer state has been added for betterversion script parsing. This brings the lexer behavior closer to GNU ld.(#174530) - Unversioned undefined symbols now use version index 0, aligning withGNU ld 2.46 behavior. (
#168189) -
.data.rel.ro.hotand.data.rel.ro.unlikelyare now recognized as RELRO sections, allowing profile-guided staticdata partitioning. (#148920) - DTLTO now supports archive members and bitcode members of thinarchives. (
#157043) - For DTLTO,
--thinlto-remote-compiler-prepend-arg=<arg>has beenadded to prepend an argument to the remote compiler's command line. (#162456) - Balanced Partitioning (BP) section ordering now skips input sectionswith null data, and filters out section symbols. (
#149265) ( #151685) - For AArch64, fixed a crash when using
--fix-cortex-a53-843419with synthetic sections andimproved handling when patched code is far from the short jump. (#170495) - For AArch64, added support for the
R_AARCH64_FUNCINIT64dynamic relocation type for relocating word-sized data using the returnvalue of a function. (#156564) - For AArch64, added support for the
R_AARCH64_PATCHINSTrelocation type to support deactivation symbols. (#133534) - For AArch64, added support for reading AArch64 Build Attributes andconverting them into GNU Properties. (
#147970) - For ARM, fixed incorrect veneer generation for wraparound branchesat the high end of the 32-bit address space branching to the low end.(
#165263) - For LoongArch,
-rnow synthesizesR_LARCH_ALIGNat input section start to preserve alignmentinformation. (#153935) - For LoongArch, added relocation types for LA32R/LA32S. (
#172618) ( #176312) - For RISC-V, added infrastructure for handling vendor-specificrelocations. (
#159987) - For RISC-V, added support for statically resolved vendor-specificrelocations. (
#169273) - For RISC-V,
-rnow synthesizesR_RISCV_ALIGNat input section start to preserve alignmentinformation during two-stage linking. (#151639)
Link: lld 21 ELFchanges
冷水澡是一座小金矿
今年夏天我大概尝试了 3 个月的冷水澡,感觉还不错,一开始不太适应,但慢慢也习惯了,后来天气一冷,就又换回了热水澡。
前几天在看 Andrew Huberman 的视频,他提到了洗冷水澡的诸多好处,尤其是对多巴胺的正面影响,就又开始了冷水澡的尝试,不过这次的挑战明显比夏天的大。
为了避免步子迈太大,我采用了热冷交替法:3 分钟热水(扩张血管),1 分钟冷水(收缩血管),然后做 2-3 个循环,最后以冷水结束。
有了 3 分钟的热水打底,让 1 分钟的冷水变得更能接受些,但当 10 来度的冷水浇在身上时,还是会忍不住地喊出来,甚至跳起来。第一轮的冷水冲击力最大,之后的会稍微好一些,但依旧在舒适区之外。
这看似有点受虐的几分钟,如果从投资的角度看,回报还是挺丰厚的。
硬件的「重启」
人类的身体不是为了恒温环境而设计的。在漫长的进化史上,舒适是异常,寒冷才是常态。当你拧开冷水龙头,实际上是在激活一段古老的代码。
更重要的是,它改变了你的化学环境。冷水能让多巴胺水平显著提升,这种提升不像糖或咖啡因那样会有随后的崩溃(crash),它是一种平稳的、持续的清醒,可以持续 2-3 个小时。
在注意力成为稀缺资源的今天,能够通过一种物理手段,在不服用任何药物的情况下获得这种精神上的敏锐度,这本身就是一种巨大的优势。
软件的「补丁」
洗冷水澡的理念跟斯多葛学派推崇的「自愿不适」(Voluntary Discomfort)也非常 match。但为什么要自找苦吃呢?
因为过度的舒适会让我们变得脆弱。当习惯了恒温、软床和热食,「基准线」会被抬高。一旦环境稍微变得恶劣,就会感到痛苦。冷水澡是一种重置基准线的方式。当你能从容面对冷水时,生活中的其他麻烦——交通堵塞、难缠的邮件、糟糕的天气——似乎就没那么难以忍受了。
这其实是在训练一种极其核心的能力:切断刺激与反应之间的自动连接。
当冷水击中你时,身体的自动反应是恐慌和急促呼吸。这和你在面对工作危机或社交压力时的反应是一样的。通过在冷水中强迫自己冷静下来、控制呼吸,实际上是在重写你的神经回路。你在告诉大脑:「虽然这很不舒服,但我依然掌舵。」
吃掉那只青蛙
早晨通常是一场意志力的博弈。大脑倾向于选择阻力最小的路径。而洗冷水澡是一个反向操作。
这不仅仅是洗澡,可能也是当天的第一个决定。你站在那里,理智告诉你应该拧开冷水,但本能告诉你不要。当你最终执行了理智的命令,你就赢得了一场微小的胜利。
这一胜虽然微不足道,但它至关重要。因为它设定了当天的基调:你不是一个顺从冲动的人,你是一个能够为了长远利益而克服短期不适的人。这种自我认同会像雪球一样滚动,影响你接下来在工作和生活中的每一个选择。
这可能就是为什么这种简单的习惯能带来惊人回报的原因。在这个充满捷径和舒适陷阱的世界里,愿意主动选择不适的人,拥有了一种隐形的竞争优势。
洗冷水澡对场地、器材的要求很低,只需要一个淋浴头,就可以开始,而它带来的回报,又非常丰厚。这就是塔勒布在《反脆弱》中提到的「非对称收益」(低风险,高收益)。这么好的投资机会,不想试试吗?
主线程Runloop
Runloop的无限循环
Routine 就是人生的复利
我们通常会觉得 Routine 是「自由」的反义词,它让人联想到枯燥的重复、僵化的日程表,或者那种一眼就能望到头的生活,这是一个巨大的误解。
在谈论 Routine 之前,我们先来看看复利公式:
把它放到人生这个大背景下,天赋、机遇和单次努力的强度,构成了那个基础的增长率 。很多雄心勃勃的人都盯着 看。他们试图通过一次通宵工作、一个绝妙的点子或者一次爆发式的冲刺来获得巨大的 。
但这很难持久。
Routine 的作用,是掌控指数 。
在很多方面,Routine 就像是定投。如果只有在「感觉来了」的时候才去写作,或者在「状态很好」的时候才去锻炼,你的 是断断续续的,增长曲线是锯齿状的。
而一个好的 Routine 是一种承诺:无论我今天感觉如何,无论 是大是小,那个 都会自动加一。
当 足够大时,它就不再是线性的累加,而是指数级的爆发。那些伟大的小说家每天早起写几千字,不是因为他们每天都有几千字的灵感,而是因为他们把写作变成了一种像刷牙一样的生理节律。他们不对抗它,只是执行它。
这就是 Routine 的本质:它把困难的事情自动化,从而让时间站在你这一边。
很多人认为「我不设计 Routine,是因为我不想被束缚」。但真相是:根本不存在「没有 Routine」这回事。
如果你不主动设计你的生活流程,你的身体和环境会为你设计一套。这套「默认 Routine」通常由你的生物本能(懒惰)和外部世界(诱惑)共同编写。
当你拿起手机无意识地刷了两个小时,这本身就是一个极其高效和稳固的 Routine。
既然「默认 Routine」也是自动化的,为什么我们还会感到疲惫?
因为你并没有完全放弃。内心依然有一个想要变好的声音,它在不断地试图把这辆正滑向舒适区的车拉回来。这就是决策疲劳的来源:一场无休止的内战。
- 你的本能说:“再休息一会。”
- 你的理智说:“不行,该干活了。”
- 你的本能说:“那先倒杯水?”
- 你的理智说:“好吧,但喝完马上开始。”
这种讨价还价非常消耗能量,宝贵的精力被浪费在了「决定要做什么」上,而不是「做这件事」本身。
一个好的 Routine(比如「穿上跑鞋 = 出门」)是一条不可协商的规则。它绕过了「谈判」环节,直接进入行动。在这个过程中,你宝贵的意志力没有被内耗掉,而是被完整地保留给了真正重要的问题:如何解决这个难题?如何把作品打磨得更好?
如果把人生看作是一项长期的投资,建立 Routine,意味着你从一个短视的投机者,变成了一个长期的价值投资者。
投机者依赖心情、运气、状态、灵感(),而投资者诉诸系统和时间()。
当你开始设计 Routine 时,实际上是在重新分配资产。你不再说「没办法,我就是管不住自己」,而是开始像分析一张糟糕的资产负债表一样分析你的生活:「哦,看来我在‘压力大’这个触发条件下,会自动买入‘逃避’这项资产。我需要调整策略,把它换成‘运动’。」
这并不容易。改变习惯总是痛苦的,但如果坚持下去,哪怕只是每天微调一点点,复利的力量就会显现。
最开始,你只是改变了起床后的 30 分钟。一年后,你会发现你变了一个人。
你不仅改变了你做的事,你改变了你是谁。
所以,不要再把 Routine 看作是一张枯燥的时间表。它是你为了结束内耗、夺回控制权而制定的投资策略。它是你对抗熵增、对抗平庸、对抗混乱的武器。
Routine 就是人生的复利。