git
把 Git 想成项目的“拍照机”就够了:你先挑好这张照片要包含哪些改动,再按下快门;以后随时可以回到任意一张照片,或者从某张照片开始开一条新分支。 真正需要分清的只有三处:工作目录是你正在修改的文件,暂存区是下一张照片的候选内容,版本库是已经拍好的历史照片。git add 是挑选内容,git commit 才是按下快门。 数据模型 不必先记 blob、tree 这些名字。先跟着一次最普通的...
Oh My Pi 高阶玩家手册
Oh My Pi(omp)不只是一个终端里的 AI 编码助手。用顺手之后,它更像一个可配置、可约束、可编排的本地开发代理:多模型角色路由、子代理编排、Skills/Hooks 扩展体系、MCP 集成、多种 compaction 策略、headless JSON 输出,以及一套跨 Claude Code / Codex / Gemini 配置的兼容发现层。 这篇不是入门教程。安装、登录、第一次...
容斥原理
容斥原理不是一套需要背的数学公式。把它当成一个工程问题就够了:多个规则都会产出同一批对象时,如何只统计一次。 例如,三个上游服务都上报了用户 ID。把三个服务的数量直接相加,会把同时出现于多个服务的用户重复计算。容斥做的事就是: 先把每个来源的数量相加; 把两个来源共同产出的对象减掉; 如果一个对象同时属于三个来源,它被减多了,再加回来。 本文用 LeetCode 3116 说明这个过程...
Rust 工程实践:测试、性能与调试的优先级
课程概览 · 第 19 章 上一篇:Cargo 与依赖:建立可重复的 Rust 开发闭环 Rust 的类型系统在编译期消灭了一大类 bug,但业务逻辑错误、边界输入、资源关闭顺序这些仍要靠测试兜底。本章用一套任务状态转移的测试矩阵收尾整个课程:先明确测什么(可观测行为),再给单元/集成/doctest/should_panic 的确切分工,然后把调试和性能优化放进同一套"证据先...
堆、优先队列与 TopK
堆(heap)解决的不是「把所有元素排好」,而是一个更克制、也更常见的承诺:在持续插入、删除中,始终用很低的代价拿到当前最优元素。最短路每次扩展距离最小的点、事件系统每次取最早到期的任务、流式数据保留最大的 kkk 个数、多路归并选择各路的最小头部,都是同一件事:只维护堆顶,而不维护全局次序。 这使堆成为 BFS 的队列模型、图论 的 Dijkstra/Prim 模型与 排序 的选择模型之间...
单调栈与单调队列
单调栈与单调队列解决的不是「如何排序」,而是「如何让一个元素在恰当的时刻结算」。在线性扫描中,许多元素的答案依赖右侧第一个更大(或更小)元素;许多区间的最值又只关心仍可能胜出的候选。若逐个向右试探,问题很容易退化为 O(n2)O(n^2)O(n2)。单调结构把仍未结算、仍有资格成为答案的下标压缩在一条有序边界上:新元素到来时,它一次性淘汰一批候选;被淘汰者恰好获得答案,或被证明不再可能胜出。...
前缀和与差分
区间问题表面上都在问“这一段的和是多少”或“这一段都加上多少”,但两类操作的重心恰好相反。前缀和把许多次查询共同依赖的历史累积起来,让一次区间查询变成两个边界值的相减;差分把一次覆盖一整段的更新压缩成两个边界事件,最后再统一还原。它们都不是某个题目的技巧,而是把“区间”改写成“边界”的一套坐标语言。 这一章用半开区间 [l, r) 统一一维、二维和可修改结构的叙述:左端属于区间,右端只是边界...
排序算法
引言:排序不是把数字排好看 排序把一个序列重排为满足某个全序或严格弱序的序列。它表面上是“从小到大”,本质上却是在建立一个可利用的顺序结构:有序数组可用二分查找把查找缩到对数级;扫描相邻元素可识别重复、区间和相对次序;按键排序则是数据库、日志、索引与调度系统的公共底座。 选择排序算法时,不能只背一张 O(nlogn)O(n\log n)O(nlogn) 表。数据是否近乎有序、键是否是有限范...
图论
本系列此前多次把「图」当作工具使用:DFS 专篇用遍历求连通分量与拓扑序,BFS 专篇求无权最短路,并查集维护动态连通性。但这些只是图论版图的入口。一旦边带上权重、方向、容量,问题就升级为:加权最短路径怎么求?用什么边把所有点最便宜地连起来?任务间的依赖与冲突如何形式化?这些才是图论的主体。 图论的价值分两层。第一层是建模:把实际问题翻译成「点 + 边 + 边上属性」的语言–城市是点、道路是...
Cargo 与依赖:建立可重复的 Rust 开发闭环
课程概览 · 第 18 章 上一篇:Unsafe 与常用 trait:把不安全性封装在最小边界 下一篇:Rust 工程实践:测试、性能与调试的优先级 Cargo 不只是构建命令,而是 Rust 项目的依赖、测试、文档和发布入口。理解 rustup、rustc、cargo 与两级配置文件(Cargo.toml/Cargo.lock)各自管什么,才能让"我这能跑"变成&q...
GraalVM 使用详解:JIT、Native Image 与多语言运行时
GraalVM 是 Oracle 主导的高性能 JDK 发行版,核心由三部分组成:Graal 编译器(用 Java 编写的 JIT 编译器,可替代 HotSpot 的 C2)、Native Image(AOT 提前编译,将 Java 程序编译为本地可执行文件)、Truffle 多语言框架(支持在同一进程中运行 JavaScript、Python 等语言)。与普通 OpenJDK 相比,Gra...
Maven 使用详解:构建、依赖与多模块管理
Maven 是 Java 生态中最主流的构建与依赖管理工具。它以 POM(Project Object Model)为核心,通过约定优于配置的理念,将编译、测试、打包、部署等流程标准化,同时依托中央仓库解决了依赖分发的难题。本文系统梳理 Maven 的核心概念与日常使用要点。 Maven 解决什么问题 早期 Java 项目依赖管理依赖手工拷贝 jar 包,存在三大痛点: 依赖混乱:第三方库...
Unsafe 与常用 trait:把不安全性封装在最小边界
课程概览 · 第 17 章 上一篇:并发与异步:先划清所有权和取消边界 下一篇:Cargo 与依赖:建立可重复的 Rust 开发闭环 unsafe 不是关闭 Rust 的安全检查,而是把某几项保证交给开发者维护。好的 unsafe 代码应当很小、具有明确前置条件,并让绝大多数调用者保持 safe Rust。本章先讲 safe Rust 依赖的不变量,然后用一个 safe 包装器示范&qu...
Spring Boot 配置体系
配置的消费端(@Value、@ConfigurationProperties 怎么用)见常用注解,Environment 在启动流程中的位置见启动原理。本文讲来源端:配置从哪来、谁覆盖谁、绑定规则是什么。代码基于 Spring Boot 4.x——配置体系自 2.4 定型后未再变动,3.x/4.x 通用。 Environment 抽象:一条有序链表 Spring 把所有配置来源统一抽象为 P...
Spring Boot Startup
Spring Boot 的"约定优于配置"由三条主线支撑:SpringApplication 对启动过程的编排、IoC 容器的 Bean 加载、基于条件注解的自动配置。本文以 Spring Boot 4.x(底层为 Spring Framework 7)源码为基准,沿启动顺序把这三条主线讲清楚。4.x 最大的工程变化是模块化拆分,启动主线本身保持不变。Bean 的实际使用...
并发与异步:先划清所有权和取消边界
课程概览 · 第 16 章 上一篇:智能指针:让资源归属可组合 下一篇:Unsafe 与常用 trait:把不安全性封装在最小边界 线程解决并行执行,异步解决大量等待中的任务。两者都不应从"怎么启动任务"开始,而要先明确:数据归谁、谁能修改、任务何时结束或取消。本章用任务队列业务域把这三条边界逐一落到可运行的代码上——先是标准库的线程与消息传递,再是一个独立的 Tok...
asdf-simple-manual
asdf 是多语言版本管理器:一个工具统一管理 Node.js、Python、Ruby、Java 等几十种运行时的版本,替代 nvm、pyenv、rbenv 各装一套的局面。核心机制是垫片(shim):安装版本时 asdf 在 ~/.asdf/shims/ 下为每个可执行文件生成包装脚本,该目录置于 PATH 最前。执行 node 时先进入垫片,垫片解析出当前应使用的版本,再 exec 真正...
智能指针:让资源归属可组合
课程概览 · 第 15 章 上一篇:模块、属性与宏:控制边界,减少重复 下一篇:并发与异步:先划清所有权和取消边界 当任务列表需要被多个视图同时看到、当任务树需要递归引用自身时,普通所有权开始显得不够用。Rust 的答案不是放宽规则,而是给指针加上明确语义:智能指针回答"数据归谁、谁能改、借用检查发生在什么时候"。本章把 Box/Rc/Arc/RefCell/Cell...
cmake-simple-manual
CMake 不是编译器,也不直接构建代码–它是构建系统的生成器:你用声明式语法描述项目结构(有哪些目标、依赖什么、怎么编译),CMake 据此生成对应构建系统(Makefile、Ninja、VS 工程等)的文件。这层间接性让同一份 CMakeLists.txt 能跨平台、跨编译器工作。 本文从零开始搭建一个 C++ 项目,逐步引入 CMake 的核心概念,最终覆盖目标导向构建、依赖管理、安装...
模块、属性与宏:控制边界,减少重复
课程概览 · 第 14 章 上一篇:错误处理:区分可恢复失败与程序缺陷 下一篇:智能指针:让资源归属可组合 任务项目长到三个文件之后,问题不再是“代码怎么写”,而是“谁能看到什么”:领域类型被 CLI 层直接改了内部字段、存储层的错误泄漏到了展示层、测试为了访问私有函数到处加 pub。模块的职责是建立稳定边界,不是镜像文件夹;宏的职责是消除真正重复的结构,不是把正常控制流藏起来。 ...
错误处理:区分可恢复失败与程序缺陷
课程概览 · 第 13 章 上一篇:迭代器与闭包:让数据转换可组合 下一篇:模块、属性与宏:控制边界,减少重复 任务文件可能不存在、某一行可能是空标题、配置里的端口可能不是数字–这些是可恢复失败,调用方应当能决定重试、报错或忽略。而“任务 ID 为 0 的任务出现在了内存里”是程序缺陷,它说明代码已经违反自己的基本假设。Rust 用 Result 表示前者、用 panic 表示后者;混淆...
迭代器与闭包:让数据转换可组合
课程概览 · 第 12 章 上一篇:集合:从访问模式选择 Vec、Map、Set 与队列 下一篇:错误处理:区分可恢复失败与程序缺陷 第 11 章解决了"数据放哪个容器",本章解决"数据怎么转换":当一条查询要穿过过滤、映射、分组多个步骤,当转换结果要脱离输入长期保存时,手写 for 循环加中间 Vec 开始显得笨重。Rust 的答案是两个配合使用...
集合:从访问模式选择 Vec、Map、Set 与队列
课程概览 · 第 11 章 上一篇:泛型与 trait:复用行为,同时保持接口清晰 下一篇:迭代器与闭包:让数据转换可组合 任务列表要按顺序展示、要按 ID 查找、要统计标签出现次数、还要按优先级取“下一个要做的”。每一种访问模式都指向不同的容器;从访问模式出发选集合,而不是从“哪个理论复杂度最好”出发。多数场景先选 Vec 或 HashMap,只有排序、双端队列、优先队列等需求明确时再...
C++ 易误用的标准库函数
标准库里有不少函数,签名朴素、名字“望文生义”,实际语义却和直觉差一截。用对了是利器,用错了编译能过、跑出错误结果还不报警。本系列收集这类“看着会、用着错”的函数,从二分查找家族的 lower_bound / upper_bound 开始。 前置概念:划分而非“已排序” 二分家族的前置条件比“整个区间升序”更宽松——它要求区间按给定比较被划分: lower_bound:所有满足 elem ...
泛型与 trait:复用行为,同时保持接口清晰
课程概览 · 第 10 章 上一篇:模式匹配:用穷尽分支处理业务状态 下一篇:集合:从访问模式选择 Vec、Map、Set 与队列 同一个“找出最大元素”的算法,你可能会先为整数写一遍,再为任务标题写一遍,最后发现两段代码几乎相同。泛型解决“同一算法处理多种类型”,trait 解决“不同类型提供同一种能力”;本章的重点不是用尽 trait 技巧,而是让抽象只暴露调用方真正需要的行为,并在...
C++ 容器速查手册
STL 容器与原生数组的 API 速查表,按“查得到、抄得来”组织,覆盖构造、访问、容量、修改、查找。原理(内存布局、扩容机制、迭代器失效的根因、选型权衡)见 C++ STL 容器,内存分配细节见 C++ STL Allocator。本文只列怎么用。 容器总览 容器 头文件 底层 迭代器类别 随机访问 T[N] 原生数组 - 连续 指针(随机) ✓ array <ar...
模式匹配:用穷尽分支处理业务状态
课程概览 · 第 9 章 上一篇:枚举:把状态、缺失和失败建模为类型 下一篇:泛型与 trait:复用行为,同时保持接口清晰 模式匹配不仅是更好看的条件判断。它能把枚举、结构体和嵌套数据拆开,同时要求代码处理所有状态,是 Rust 业务代码安全演进的关键工具。第 8 章的状态机把非法转移挡在了方法里,本章负责消费这些状态:把每个 TaskState 变成可显示的文本、可执行的分支,并且保...
枚举:把状态、缺失和失败建模为类型
课程概览 · 第 8 章 上一篇:结构体:组织数据、封装状态与编写方法 下一篇:模式匹配:用穷尽分支处理业务状态 当一个值只可能处于若干互斥状态时,用 enum 表达它。它比"状态码 + 若干可空字段"更可靠:每个状态拥有自己的数据,处理者必须覆盖全部可能。第 7 章的 Task 里已经出现了一个 TaskState 字段,本章把它变成主角:带数据的状态、可观测的非法...
结构体:组织数据、封装状态与编写方法
课程概览 · 第 7 章 上一篇:所有权、借用与生命周期:用数据流理解编译器 下一篇:枚举:把状态、缺失和失败建模为类型 结构体(struct)把一组相关的数据放进一个有名字、有类型的整体。配合 impl,它还能定义行为;配合私有字段和构造器,它还能保证值一创建就是合法的。第 6 章你已经看到了"字段被移动"的后果,本章把这些工具组装成一个能自我保护的领域模型。 日常...
广度优先搜索
如果把图遍历比作探索一座陌生城市,深度优先搜索(DFS)像是一个执着地"一条路走到底、走不通再回头"的探险者,而广度优先搜索(Breadth-First Search,BFS)更像是投入湖面的石子激起的涟漪——从落点出发,一圈一圈匀速向外扩散,先抵达近处,再抵达远处。这种"层层向外"的推进方式,让 BFS 在所有"距离敏感"的场景中...
深度优先搜索
深度优先搜索(Depth-First Search,DFS)是图与隐式状态空间遍历的最自然范式。想象你站在迷宫入口,眼前的岔路通向未知。最直觉的走法是:右手扶墙,遇岔路先挑一条往下走,走到死胡同就退回上一个岔口换路–这套「一条路走到黑、走不通就回退」的策略,正是 DFS 的精神。它和人类走迷宫的行为高度一致,也因此成为最容易「想得到」的搜索算法。 DFS 的适用面远不止迷宫。判断地图里有几个...
字典树
问题引入 给定一个字符串集合,需要频繁执行「插入一个串」「查询某串是否存在」「查询某前缀是否出现过」「枚举所有以某前缀开头的串」等操作。把所有串存进 set 或哈希表,精确查找虽快,但前缀查询只能遍历所有键逐一比对,10510^5105 量级即超时。关键在于:这些查询都围绕公共前缀展开——字典树(Trie,又称前缀树) 把公共前缀压缩到同一条路径上,使前缀相关操作降至 O(L)O(L)O(L...
Python 内置集合类型详解
Python 的内置容器(builtin collections)是这门语言的地基:list、tuple、dict、set、str 这五个类型覆盖了绝大多数日常代码。它们看起来简单,但每一个背后都有精心设计的实现——list 是动态数组而非链表、dict 从 3.7 起保证有序、set 和 dict 共享哈希表思路。理解这些实现细节,才能写出既正确又高效的代码。 本文逐个拆解内置集合类型:它...
并查集
问题引入 nnn 个元素,不断接收「xxx 与 yyy 同集合」的合并指令,并查询「xxx 与 yyy 是否同集合」「当前多少个独立集合」。图遍历每次查询 O(n)O(n)O(n),10510^5105 量级即超时。关键在于:只关心集合归属,不关心内部连接结构–并查集(Union-Find / DSU[Disjoint Set Union]) 即为此设计,配合两种优化后单次操作均摊近似 O(...
Python itertools 详解:迭代器代数与惰性求值
Python 的 for 循环和生成器已经把「按需逐个产出」做得很顺手,但遇到「把两个序列交错」「取前 N 个」「按 key 分组」「笛卡尔积」这类组合操作,手写循环既啰嗦又容易错。标准库的 itertools 提供了一批构建和组合迭代器的工具,像代数运算一样把简单的迭代器拼成复杂的数据流。 它的设计哲学是惰性求值–所有函数都返回迭代器,不预先计算全部结果,只在被消费时才产出元素。这意味着它...
Python 并发编程:threading、multiprocessing、concurrent.futures 与 GIL
Python 的并发比多数语言更绕,因为有个 GIL 横在中间:同样是「开线程」,在 Java 里能并行跑满多核,在 CPython 里却常常只能并发不能并行。于是 Python 的并发分成了三条路线,各自服务的场景泾渭分明: threading --多线程。受 GIL 限制,同一时刻只有一个线程执行 Python 字节码,但 IO 阻塞时会释放 GIL,适合 IO 密集任务。 multi...
Python asyncio 异步编程:事件循环、协程与并发原语
线程是实现并发的经典手段,但内核调度、栈内存、锁竞争、上下文切换都不是免费的。当瓶颈是「等」而不是「算」(等网络、磁盘、数据库),开几万个线程去各自阻塞并不划算。asyncio 给了另一条路:单线程 + 事件循环 + 协作式调度。一个线程里跑成千上万个协程,谁 await 了就把执行权让出去,事件循环负责在「数据就绪」时把它接回来。 难点不在语法(async/await 很简单),而在心智模...
Pi Coding Agent 使用入门
Pi Coding Agent(命令名是 pi)是一个很轻量的终端编码代理。它的核心只提供对话、读写文件和执行命令;计划模式、子代理、MCP、权限弹窗等能力都不强行内置,而是交给扩展、Skill 或你自己的工作流。因此它很适合希望自己决定工具链和约束方式的人。 三分钟开始 安装后,在目标仓库目录里启动即可: 1234npm install -g --ignore-scripts @earen...
C++ 运算符重载(operator)
运算符重载(operator overloading)让用户定义类型可以像内置类型一样参与表达式:a + b、x[i]、*p、if (x)、os << x。它的价值不在于把代码写得“炫”,而在于让一个类型的自然操作具有自然、可预测的写法。 但 operator 不是“给任意符号赋予任意含义”的机制。C++ 已经规定了每个运算符的优先级、结合性、操作数个数与大致语义;重载只是在这些...
Python 进阶语法:推导式、f-string、海象运算符、上下文管理器、装饰器与 match-case
Python 的许多“高级语法”并不难,难的是知道它们各自解决什么问题、该在什么边界内使用。本文把日常代码中最常见的一组语法放在一起:推导式、f-string、海象运算符、with、装饰器和 match-case。 它们的共同目标是让代码更贴近意图,而不是单纯压缩行数。本文示例以 Python 3.12 为基准;最低版本见下表。 语法 最低版本 核心用途 解包 */** Pyt...
回溯算法
引言:为什么需要回溯 许多算法问题不是「求一个最优值」,而是「把所有符合条件的方案枚举出来」,或者「在庞大的状态空间里找一个可行解」。前者如「列出数组的所有全排列」「把字符串切成若干回文子串的所有切法」,后者如「在 9×99 \times 99×9 棋盘上填出一个合法数独」「在字符网格里搜出某个单词」。 这类问题的共同特点是:解空间结构上是一棵巨大的「决策树」,每个节点代表「到目前为止已经做...
二分查找
二分查找(Binary Search)大概是每个程序员最早接触到的算法之一:在有序数组里找目标值,每次砍掉一半,O(log n) 完事。听起来简单到不值一提。但只要稍微写过几道二分题,几乎所有人都经历过「改一个符号就死循环」「差一行就越界」「边界永远是 off-by-one」的折磨。Donald Knuth 在《The Art of Computer Programming》里指出,第一个正...
分治算法
引言:为什么「分而治之」如此自然 面对一个规模为 nnn 的问题,如果它具备某种可分解的内部结构,我们往往不必正面强攻。把问题切成若干个规模更小的同构子问题,递归求解后再把答案拼回来——这就是分治(Divide and Conquer)。这并非某种具体算法,而是一套算法设计范式,与贪心、动态规划、回溯并列。 分治的影子无处不在:归并排序把数组对半切,快速排序按 pivot 分两半,最近点对按...
动态规划
动态规划(Dynamic Programming,DP)是算法世界里最具张力、也最容易让人"卡壳"的一个主题。它的代码往往只有寥寥数行,思想却能在陌生题目面前把人挡在门外;它的理论门槛看似只是一句"分治 + 记忆化",但能否在第一时间构造出正确的状态定义,几乎直接决定了"会做"与"不会做"。本文将以 DP 的三要...
贪心算法
引言:从「走一步看一步」到「步步最优」 在算法世界里,有两类策略恰好处于光谱的两端。一类是「把所有可能都试一遍再回溯」的搜索派——DFS、回溯、动态规划都属于这一脉,它们宁可付出指数级代价也要保证不漏掉任何一种可能。另一类则是「看眼前、不回头」的贪心派——每一步都基于当前可观察的信息做出最优决策,做完就不再反悔。 贪心算法 (Greedy Algorithm) 听起来朴素得近乎天真:在每一步...
双指针技术
双指针(Two Pointers)是数组、字符串、链表上最常用的算法技巧之一。它用一个看似平凡的细节–用两个游标代替一个游标遍历–换取指数级的效率提升。表面上看,从「单指针 O(n²)」到「双指针 O(n)」省下的是一次嵌套循环;往深处理解,双指针真正在做的是利用问题本身的结构(单调性、有序性、区间不变量),把搜索空间裁剪成一个低维流形。 这一篇我们系统地拆解双指针的四大家族:对撞指针、快慢...
数位 dp
数位 dp(digit DP)是一类专门处理「在某个数区间 [L,R][L, R][L,R] 内统计满足特定数位性质的数」的动态规划技术。所谓"数位性质",指的是只取决于数的十进制(或任意进制)表示中各位数字的性质,例如"不含数字 4"、“相邻两位之差至少为 2”、“数字之和等于 K”。这类问题看似简单,但区间上界可能高达 101810^{18}101...
Golang 杂项:embed 与资源嵌入
课程概览 · 上一篇:测试与工程实践 · 第 12 章 //go:embed 指令与 embed 包(Go 1.16 引入)解决了 Go 程序分发时的一个老问题:如何把静态资源——HTML 模板、SQL 迁移、前端构建产物、默认配置、TLS 证书——连同二进制一起发布,做到单文件部署。在 embed 之前,社区用 go-bindata、packr、statik、vfsgen 等代码生成工...
Cargo.toml 配置速查
Cargo.toml 是 Cargo 项目的清单文件(TOML 格式),描述包名、版本、依赖、特性、编译目标等。本文给出常用配置速查。 最小示例 1234567[package]name = "myapp"version = "0.1.0"edition = "2021"[dependencies]serde = { ve...
C++17 any 与 variant
在 C++ 中,我们经常需要“用一个变量持有多种可能的类型”。C 风格的 union 和 void* 是最早的答案,但它们既不安全(不记录当前存的是哪种类型),也缺乏面向对象的扩展能力。C++17 引入了 std::any 和 std::variant,从两个不同方向填补了这块空白: std::any:类型擦除(type erasure)——持有一个任意类型的值,但“忘记”了它的静态类型,...
Python collections 包详解
Python 内置的 dict、list、set、tuple 已经覆盖了绝大多数日常需求,但一旦遇到"按出现次数统计"“给元组字段起名字”“双端高效增删”"层叠的配置查找"这类场景,手写往往既啰嗦又容易出错。标准库的 collections 模块正是为此而生:它在内置类型之上提供了一批专门化的容器,既保留 Pythonic 的简洁,又补齐了数据结构层面...
FastAPI 快速上手
FastAPI 是基于 Python 类型标注的现代 Web 框架,底层是 Starlette(ASGI)和 Pydantic(数据校验)。核心思想很纯粹:函数签名上的类型标注就是一切契约的来源–路由参数解析、请求体校验、响应序列化、OpenAPI 文档全部从同一份标注推导。写一次标注,同时得到校验、文档和编辑器补全,这是对「动态语言写后端」的最大重构。 安装与第一个应用 FastAPI 本...
所有权、借用与生命周期:用数据流理解编译器
课程概览 · 第 6 章 上一篇:函数与 I/O:把所有权、错误和资源边界写进接口 下一篇:结构体:组织数据、封装状态与编写方法 同一段任务数据,往往要被查询函数读取、被编辑函数修改、再被日志函数打印。如果"谁负责释放"和"谁正在改它"只靠人为约定,悬垂指针和数据竞争就藏在这些约定里。Rust 把约定升级为编译期规则:所有权规定清理责任,借用规定读...
函数与 I/O:把所有权、错误和资源边界写进接口
课程概览 · 第 5 章 上一篇:表达式与控制流:让分支、循环和返回值清楚可审查 下一篇:所有权、借用与生命周期:用数据流理解编译器 函数签名是 Rust 最重要的设计文档:参数类型说明谁拥有数据、要不要还,返回类型说明成功产出什么、失败怎么办。文件 I/O 把这两件事逼到真实世界–文件会缺失、配置会为空、读取会中途失败。本章把所有权、错误与资源边界写进签名,用 ? 把失败路径组织成直线...
表达式与控制流:让分支、循环和返回值清楚可审查
课程概览 · 第 4 章 上一篇:切片:为函数设计稳定、低耦合的输入 下一篇:函数与 I/O:把所有权、错误和资源边界写进接口 Rust 是表达式语言:if、match、代码块乃至循环都能产生值。这让"从输入算出一个结果"可以写成一条类型明确的表达式链。但工程上的优先级不是炫技式地消灭临时变量,而是让每个分支的类型、每个循环的退出条件、每条失败路径在评审时一眼可见。 ...
C++ 转换运算符
在 C++ 中,转换运算符(conversion operator) 又称用户定义转换函数(user-defined conversion function),是一种特殊的成员函数,用于把当前类类型的对象转换为另一个类型。它的语法形式是 operator 目标类型(),与构造函数形成对称关系:构造函数把"其他类型"构造成"本类型",而转换运算符把&qu...
切片:为函数设计稳定、低耦合的输入
课程概览 · 第 3 章 上一篇:字符串与切片:String、&str 与 UTF-8 边界 下一篇:表达式与控制流:让分支、循环和返回值清楚可审查 上一章的结论是"只读文本用 &str"。本章把同一思路推广到任意序列:函数应该声明自己需要的是"一段数据"还是"修改一段数据",而不是绑死调用方用 Vec 还是数组...
字符串与切片:String、&str 与 UTF-8 边界
课程概览 · 第 2 章 上一篇:Rust 基础:变量、类型与转换的工程选择 下一篇:切片:为函数设计稳定、低耦合的输入 字符串是 Rust 里被使用得最多、也最容易选错的一对类型:String 拥有数据,&str 只借用数据。更深的坑在 UTF-8–中文字符占 3 个字节,字节下标随时可能落进字符中间。本章把这两个层面一次讲清:所有权层面的 String vs &str...
Rust 基础:变量、类型与转换的工程选择
课程概览 · 第 1 章 下一篇:字符串与切片:String、&str 与 UTF-8 边界 学 Rust 的第一个真实障碍不是新语法,而是默认选择:哪些值该可变、类型标注写在哪里、数值转换在哪个边界必须受检。这些选择做错了,代码照样能编译,但接口会变贵、错误会推迟出现。本章用任务队列 CLI 里的两个小函数,把这些默认选择一次立起来;文本数据(String 与 &str...
Rust 工程课程概览:从能运行到可维护
📚 Rust 课程系列 课程概览(本文) Rust 基础:变量、类型与转换的工程选择 字符串与切片:String、&str 与 UTF-8 边界 切片:为函数设计稳定、低耦合的输入 表达式与控制流:让分支、循环和返回值清楚可审查 函数与 I/O:把所有权、错误和资源边界写进接口 所有权、借用与生命周期:用数据流理解编译器 结构体:组织数据、封装状态与编写方法 枚举:把状态、缺失...
C++ 宏的常见用法与现代替代
C 预处理器宏是 C/C++ 中最古老也最具争议的特性之一。它发生在编译之前——纯文本替换,没有类型检查、没有作用域、调试时不可见。尽管现代 C++ 已为绝大多数宏场景提供了更安全的替代方案,宏仍大量存在于系统编程、跨平台代码和第三方库中。理解宏的常见用法,既是阅读遗留代码的必备技能,也是避免在新代码中误用的前提。 常量定义 最古老的用法——用宏定义编译期常量: 1234#define PI...
C++ 视图
C++ 里的“视图”不是某一个单独类型,而是一类共同思想:用一个轻量对象描述一段数据或一段计算,不拥有数据,尽量不复制,按需访问。它们把“我想看哪一段、以什么方式看”从“数据本身如何存储”里拆出来。 常见视图有三类: 类型 标准 作用 是否拥有元素 能否修改元素 std::string_view C++17 只读地观察一段字符 否 否(只读) std::span C++20...
Redis 底层原理与架构
Redis 是基于内存的键值存储,常被当作缓存、消息队列、分布式锁甚至轻量数据库使用。它之所以通用,关键在于其丰富的数据结构与精巧的底层实现。本文聚焦 Redis 的"内部"——数据结构的底层编码、Lua 执行模型、过期与淘汰机制、持久化、集群架构与故障转移;命令用法与适用场景见姊妹篇《Redis 使用手册》。 全局视角 Redis 的 key 是二进制安全的字符串,va...
golang-arch
写 Go 的人大多停在"写代码 → go build → 跑起来"这一层。但真要追问"go build 到底产出了什么?二进制里塞了哪些东西?程序被 OS 拉起来之后,CPU 第一条指令落在哪?goroutine 又是怎么’凭空’跑起来的?"——能讲清楚的人并不多。 这篇文章把 Go 从源码到执行的全链路拆开:编译格式 → 二进制格式 → 运行时格式 ...
MCP 协议详解:从架构到原语的设计拆解
Model Context Protocol(MCP)是 Anthropic 在 2024 年底推出的开放协议,目标是给 LLM 应用和外部数据源、工具之间定一个标准化的接驳方式。它借用了 Language Server Protocol(LSP)的思路——LSP 让任意编辑器对接任意语言服务,MCP 则让任意 AI 应用对接任意工具与上下文。 这篇文章不写"怎么装一个 MCP S...
Redis 使用手册
Redis 是基于内存的键值存储,常被当作缓存、消息队列、分布式锁甚至轻量数据库使用。它之所以通用,关键在于其丰富的数据结构——选对结构,命令和场景往往自然成立。本文是 Redis 使用侧手册,系统梳理各数据结构的核心命令与适用场景;底层编码、Lua 执行模型、过期淘汰、持久化与集群架构等原理见姊妹篇《Redis 底层原理与架构》。 全局视角 Redis 的 key 是二进制安全的字符串,v...
TypeScript 与 React 实战
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战(本文) 前面的章节我们系统掌握了 TypeScript 的类型系统,并在 Bun 服务端场景里落地。本篇把 TypeSc...
TypeScript 与 Bun 实战
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战(本文) TypeScript 与 React 实战 前面的章节我们系统学习了 TypeScript 的类型系统与工程化能力,但一直停留在"编译成 JS 后...
TypeScript 模块、装饰器与工程化
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化(本文) TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 本篇聚...
TypeScript 高级类型
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型(本文) 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 泛型与类型组合
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合(本文) 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 接口与类
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类(本文) 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 异步编程与错误处理
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理(本文) 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Jav...
TypeScript 集合类型
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符 集合类型(本文) 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 流程控制与运算符
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数 流程控制与运算符(本文) 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 函数
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明 函数(本文) 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 基础类型与变量声明
📚 TypeScript 教程系列 入门与配置 基础类型与变量声明(本文) 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
TypeScript 入门与配置
📚 TypeScript 教程系列 入门与配置(本文) 基础类型与变量声明 函数 流程控制与运算符 集合类型 异步编程与错误处理 接口与类 泛型与类型组合 高级类型 模块、装饰器与工程化 TypeScript 与 Bun 实战 TypeScript 与 React 实战 ⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。 Typ...
Java25 新特性
Java 25 是继 Java 21 之后的又一个长期支持(LTS)版本,于 2025 年 9 月 16 日发布,包含 18 个 JEP。Java 21 引入的虚拟线程、记录模式等在 25 中继续打磨成熟,同时 25 带来了模块导入、紧凑源文件、作用域值正式化等一批新特性,并在 AOT 提前编译、对象头压缩、JFR 可观测性等方面有显著提升。以下是对 Java 25 相比 Java 21 的...
Java Class
类(class)是 Java 面向对象编程的基本构建单元,它既是数据抽象的载体,也是行为封装的边界。理解 class 的核心内容,本质上是理解 Java 如何用类型系统组织数据与行为。本文从现代 Java(25 LTS)视角出发,梳理 class 设计的核心要素。 类的本质:状态与行为的封装 一个 class 由两部分构成:字段(状态)和方法(行为)。封装的目的是把可变状态收敛到最小范围,对...
Intel TBB
TBB (Threading Building Blocks) 是 Intel 出品的 C++ 并行编程库,也贡献给了 oneAPI 项目(oneAPI TBB)。它提供了高层抽象的任务并行、并行算法、并发容器和同步原语,让开发者不用直接操作 pthread/win32 thread 就能写出跨平台的高效并行程序。 安装与配置 获取方式 oneAPI TBB(推荐):https://git...
Vite 构建工具指南
开发时利用浏览器原生 ESM 按需加载,生产时交给 Rollup 打包。它不像 Webpack 那样在开发阶段先打成一个大包,而是让浏览器直接加载源码模块——项目越大,体验差异越明显。 启动快:不用全量打包,直接提供原生 ESM 模块。 HMR 快:热更新只影响变化的模块,不受应用规模影响。 开箱即用:TypeScript、JSX、CSS、静态资源开箱支持。 插件生态清晰:兼容 Rollu...
JavaScript 核心要点详解
ES6+ 关键特性 解构赋值 解构赋值是一种从数组或对象中提取值并赋给变量的语法糖。 数组解构 1234567891011121314151617181920212223242526// 基本数组解构const [a, b, c] = [1, 2, 3];console.log(a, b, c); // 1, 2, 3// 跳过某些元素const [first, , third] = [1,...
前端调试技巧与工具大全
浏览器开发者工具 Chrome DevTools 核心功能 Console 面板 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828...
前端工程化工具链:ESLint、Prettier、Biome、Tailwind CSS
ESLint ESLint 是 JavaScript 和 TypeScript 的代码检查工具,用于发现和修复代码中的问题。 安装与配置 12345678# 安装 ESLintbun add -d eslint# 初始化配置(交互式)bunx eslint --init# 或手动安装推荐的配置bun add -d eslint @eslint/js typescript-eslint ESL...
包管理器完全指南:NPM、Yarn、PNPM、Bun
NPM (Node Package Manager) NPM 是 Node.js 默认的包管理器,也是世界上最大的软件注册表。 安装与初始化 123456789101112131415# 检查版本npm --version# 或npm -v# 初始化项目(交互式)npm init# 快速初始化(使用默认值)npm init -y# 安装所有依赖npm install# 或npm i 包安装 ...
前端性能优化实战指南
性能优化概述 前端性能优化的目标是提升用户体验,让页面加载更快、响应更及时、交互更流畅。 核心 Web 指标 (Core Web Vitals) LCP (Largest Contentful Paint): 最大内容绘制,衡量加载性能,应在 2.5 秒内 INP (Interaction to Next Paint): 交互到下次绘制,衡量响应性,应在 200 毫秒内 CLS (Cumu...
C++ STL 容器
标准库容器是 C++ 日常 80% 工作的载体,但很多人对它们的认知停留在"vector 快、list 能随便插"。真正决定选型的,是三件事:内存布局(连续 or 节点)、迭代器失效规则、各操作的复杂度保证。这篇把这三件事讲透,给一张能照着选的决策表。容器的内存分配细节见 C++ STL Allocator,这里聚焦容器本身。 容器的分类 STL 容器按组织方式分三大类:...
Codex CLI 使用技巧
Codex CLI 不只是一个“在终端里聊天的 AI”。把它用顺手之后,它更像一个可配置、可约束、可脚本化的本地编码代理:能读写仓库、在沙箱里执行命令、调用 MCP 工具、用 AGENTS.md 沉淀规则,也能在 CI 或脚本里以 JSON 输出工作结果。 这篇不是入门教程。安装、登录、第一次提问这些内容只保留最低限度;重点放在日常高强度使用时真正影响效率和安全性的东西:审批与沙箱、配置作用...
Spring Boot Bean 使用规范
Bean 的加载机制、生命周期与三级缓存见启动原理。本文只回答工程问题:Bean 怎么定义、怎么注入、什么时候偏离单例,以及每个决策对应的排错线索。代码基于 Spring Boot 4.x(Spring Framework 7、Jakarta EE 11、Java 17+)。 Bean 定义:按来源选方式 来源 方式 要点 自己的业务类 @Service / @Reposito...
OpenCode 源码解析:从一次提问到工具调用的完整链路
OpenCode 是 SST 团队开源的 AI 编程助手,定位与 Claude Code 类似,但用 TypeScript + Bun 实现,并基于 Effect 与 Vercel AI SDK 构建了一套相当工程化的运行时。这篇以 sst/opencode 的真实源码为依据,逐机制拆解它"为什么是这样设计的"。 本文所有结论均来自 github.com/sst/open...
Java Guava
Google Guava 是 Google 开发的 Java 核心库,提供了集合、缓存、并发、字符串处理、I/O 等领域的增强工具。相比 Apache Commons,Guava 更现代化,设计理念更接近函数式编程风格。 概述 Guava 的设计哲学: 不可变优先:大量使用不可变集合 预防式设计:快速失败(fail-fast),尽早暴露问题 函数式风格:Predicate、Function...
Java Apache Commons
Apache Commons 是 Apache 软件基金会提供的一系列 Java 工具库,它们是 Java 生态中最成熟、使用最广泛的基础设施之一。本文介绍几个最常用的 Commons 库。 概述 Apache Commons 项目起源于 Jakarta 项目,目的是提供可复用的 Java 组件。这些库填补了 JDK 标准库的空白,提供了大量实用工具方法。 核心价值:减少样板代码、处理边界...
Logback 详解:Java 日志框架的核心与实践
Logback 是 Java 生态系统中使用最广泛的日志框架之一,作为 Log4j 的继任者和 SLF4J 的原生实现,它以其卓越的性能、灵活的配置和丰富的功能成为现代 Java 应用的首选日志解决方案。 Logback 简介 什么是 Logback Logback 由 Log4j 创始人 Ceki Gülcü 开发,设计上分为三个核心模块: 模块 作用 logback-cor...
MyBatis 整合
MyBatis 把 SQL 的编写权留给开发者,只接管参数映射、SQL 执行、结果映射这三件重复劳动。Spring Boot 用一个 starter 完成 SqlSessionFactory 构建、Mapper 接口注册、SqlSession 托管的全套装配。本文沿"自动配置 → Mapper 代理 → SqlSession 与事务"这条主线拆解整合原理,再落到实践规范。...
Spring Boot Common Annotations
注解是 Spring Boot 与开发者之间的接口语言:声明组件、绑定请求、注入配置、划定事务边界,全部通过注解表达。本文按功能域整理实际开发中的高频注解,每个注解只保留最简示例与选型决策。启动与自动装配机制见 Spring Boot Startup,Bean 定义与注入方式对比见 Spring Boot Bean 使用规范。 Bean 定义与注入 组件注解均派生自 @Component,差...
Golang Struct Tag
Struct Tag 是 Go 语言中一个简洁但极其强大的特性。它允许你为结构体字段附加元数据,这些元数据可以被反射读取,广泛用于序列化、ORM、验证等场景。 基本语法 Struct Tag 是紧跟在字段类型后面的反引号字符串: 12345type User struct { Name string `json:"name"` Age int...
Golang Versions
1.27 Go 1.27(预计 2026 年 8 月发布) 延续了 1.26 “把痛点都修了"的路线,并在语言表达力和标准库上来了两记重拳:泛型方法终于落地、encoding/json/v2 正式进标准库。如果说 1.26 是"最舒服的小版本”,1.27 就是"标准库开始换代"的版本。 下面按重要程度捋一捋最值得关注的点(基于官方 tip 文档 dra...
Claude Code 高阶玩家手册
Claude Code 不只是一个“在终端里聊天的 AI”。把它用顺手之后,它更像一个可配置、可约束、可编排的本地开发代理:能读写仓库、执行命令、调用 MCP 工具、运行子代理、触发 Hooks,也能在 CI 或脚本里以 JSON 输出工作结果。 这篇不是入门教程。安装、登录、第一次提问这些内容只保留最低限度;重点放在日常高强度使用时真正影响效率和稳定性的东西:上下文、权限、配置、自动化、并...
Rust Tips
& 的各种用法 不可变引用(借用) 最基本的形式,用于借用所有权而不转移: 1234567fn print_length(s: &String) { println!("{}", s.len());} // s 在这里归还,不影响原数据let s = String::from("hello"...

































































































