文章 · Blog

文章

文章千古事,得失寸心知。——杜甫

277

12

13

个系列

2026 · 20 篇

Agent RSI 复盘
年度封面 · 08-30 · 2 分钟

Agent RSI 复盘

做了什么。 把产品开发全流程交给 Agent 的范式跑通之后,我用过去两周做了两个 Agent 自迭代(RSI)实验:人-Agent 协作平台 Waka,38 小时交付第一版,之后持续自迭代;Vue 转 React 的 V2R-Agent,运行 10 天后停止。 结论。 V2R…

系列:Agent 开发实践与思考·标签:Agent
8 月 · 其余 1 篇
7 月 · 其余 3 篇
6 月 · 其余 6 篇
5 月 · 其余 2 篇

CodeGraph、GitNexus 与 Graphify:代码知识图谱的比较维度

代码知识图谱工具预先从仓库中抽取节点和关系,供 Agent 查询符号、依赖和调用路径。这样可以减少目录遍历和全文检索,但三个工具处理的输入、关系来源和查询方式并不相同。 本文比较三个公开项目: CodeGraph:本地预索引代码图谱和 MCP 服务。 GitNexus…

2 分钟
AI Coding 工程实践
4 月 · 其余 2 篇
3 月 · 其余 1 篇
2 月 · 其余 3 篇

AIMO:用 Agent 开发跨平台闪念笔记

这个春节,我让 Agent 完成了 https://aimo.plus/ 的设计和开发。AIMO 是一款跨平台应用,包含 Web、Android、iOS、Windows、Mac 和 Linux 客户端。 我从 2023 年起就想开发这个应用。当时我开始使用 memos…

2 分钟
AI Coding 工程实践
1 月 · 其余 1 篇

仓库 AI 标准化改造:标准、评估与验证方法

将 AI 编码工具接入仓库后,Agent 仍需要系统边界、改动模块、不可违反的业务规则和验证方式等信息,才能稳定交付需求。缺少这些信息时,Agent 仍能搜索和生成代码,但参考实现选择、领域术语理解和完成条件判断的结果会发生波动。 仓库 AI…

3 分钟
AI Coding 工程实践

2025 · 20 篇

年度封面 · 12-23 · 2 分钟

两年搭 Agent 的复盘:工程约束下的取舍

本文是「Agent 开发实践与思考」系列第 20 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

系列:Agent 开发实践与思考·标签:Agent
12 月 · 其余 3 篇

AICoding概念综述

背景 AI Coding 领域常见的术语包括 Prompt、Prompt 工程、Context 工程、Embedding、RAG、Memory、Tools、Rules、Commands、MCP Server、Agent/Sub Agent、Modes、Hooks 和 Skills…

3 分钟
AI Coding 工程实践
11 月 · 其余 2 篇

多 Agent 协作的真实收益与代价

本文是「Agent 开发实践与思考」系列第 19 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

1 分钟
Agent 开发实践与思考

能力按需加载:从动态提示词到 Agent Skills

本文是「Agent 开发实践与思考」系列第 18 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

1 分钟
Agent 开发实践与思考
10 月 · 其余 3 篇

使用 AI Agent 统一 Web 基础设施的开发复盘

今年处理团队技术债时,我开始大规模使用 AI 辅助项目开发。最近完成的一项工作,是将团队内多套 Web 基础设施整合为一套方案。 Web 基础设施的技术债 由于历史原因,团队内部的 Web 项目同时使用 Vue 2、Vue 3 和 React…

1 分钟
AI Coding 工程实践

AI Coding 上下文摘要的递归压缩、原文保留与回退策略

本文是「Agent 开发实践与思考」系列第 16 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

2 分钟
AI Coding 工程实践
9 月 · 其余 1 篇

后训练扫盲:SFT 记知识、RL 学长处,和 Agent 有什么关系

本文是「Agent 开发实践与思考」系列第 15 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

1 分钟
Agent 开发实践与思考
7 月 · 其余 1 篇

没有评估就没有迭代:我的 Agent 评估落地记

本文是「Agent 开发实践与思考」系列第 14 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

2 分钟
Agent 开发实践与思考
6 月 · 其余 2 篇

从同步问答到事件驱动:异步 Agent 的架构改造笔记

本文是「Agent 开发实践与思考」系列第 13 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

2 分钟
Agent 开发实践与思考

能看会说的 Agent:语音交互与 Computer Use 这半年

本文是「Agent 开发实践与思考」系列第 12 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

2 分钟
Agent 开发实践与思考
5 月 · 其余 1 篇

Agent 如何用代码完成推理、校验、适配与展示

本文是「Agent 开发实践与思考」系列第 11 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent…

1 分钟
Agent 开发实践与思考
3 月 · 其余 1 篇
2 月 · 其余 2 篇

MCP 用了三个月:工具标准化之后 Agent 设计变了什么

本文是「Agent 开发实践与思考」系列第 9 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

2 分钟
Agent 开发实践与思考

利雅得出差游记

业务准备在利雅得展业,系统还有不少问题需要到现场处理。春节前公司协助申请工作签,节后到北京当天便直飞利雅得。 这次工作主要有两项: 第一次出海,对实际网络环境缺少了解,需要考察当地网络情况并梳理竞对体验。两周时间基本都在利雅得各处走访。 评估 H5 承载对 C…

1 分钟
1 月 · 其余 3 篇

长任务不失忆:把 Vue 转 React 做成可验证的迁移流程

本文是「Agent 开发实践与思考」系列第 8 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

2 分钟
Agent 开发实践与思考

知识管理-AI笔记(AI大脑)

“AI 大脑”这个设想让我重新思考笔记系统。 人会遗忘。做决策时,之前接触过的信息如果无法有效召回,决策质量会受影响。 AI…

1 分钟

2024 · 12 篇

年度封面 · 12-24 · 1 分钟

上下文窗口的成本课:KV Cache、Prompt Caching 与消息顺序

本文是「Agent 开发实践与思考」系列第 7 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

系列:Agent 开发实践与思考·标签:Agent
12 月 · 其余 5 篇

双向语序

什么是双向语序? 双向语序(Bidirectional Text)是指在同一文本段落中混合存在两种书写方向的现象: RTL(Right-to-Left):从右向左书写的语言(如阿拉伯语、希伯来语) LTR(Left-to-Right…

1 分钟
国际化

国际化-RTL

什么是RTL? RTL是”Right-to-Left”的缩写,指的是从右向左的书写和阅读方向。与世界上大多数语言(如英语、中文等)采用的LTR(Left-to-Right,从左到右)方向不同,RTL语言有着独特的展示和交互方式。 典型的RTL语言包括: 阿拉伯语(Arabic…

1 分钟
国际化

国际化项目中 ICU 是什么

在 国际化(i18n)和本地化(l10n) 开发中,ICU(International Components for Unicode) 是一个由 Unicode…

1 分钟
国际化

i18n要素

一、货币本地化 1. 货币符号 不同地区使用不同货币符号(如:¥/$/€/£) 示例:人民币(¥)、美元($)、欧元(€) 2. 货币精度 小数位数规范(日本円通常取整,人民币常用2位小数) 示例:100 JPY vs 100.00 CNY 3. 货币符号位置 前置或后置(€…

1 分钟
国际化
11 月 · 其余 2 篇

迁移经验检索的工程细节:混合检索、重排与拒答

本文是「Agent 开发实践与思考」系列第 6 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

1 分钟
Agent 开发实践与思考

迁移知识库的 embedding 召回评测方法

本文是「Agent 开发实践与思考」系列第 5 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

1 分钟
Agent 开发实践与思考
10 月 · 其余 1 篇

给 Agent 做记忆:分层、状态与遗忘

本文是「Agent 开发实践与思考」系列第 4 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环 08-06 工具调用踩坑记:schema、描述与错误返回怎么写 09-10 系统提示词写到几千字之后:让 Agent 迁移 Vue…

2 分钟
Agent 开发实践与思考
9 月 · 其余 1 篇
8 月 · 其余 1 篇
7 月 · 其余 1 篇

我手写了一个 Agent:从一问一答到"思考-行动-观察"循环

本文是「Agent 开发实践与思考」系列第 1 篇。系列目录: 2024 07-02 我手写了一个 Agent:从一问一答到”思考-行动-观察”循环(本篇) chat 模式的限制 2023 年团队陆续在用 GPT 的 API 做一些内部工具,采用一问一答的 chat…

1 分钟
Agent 开发实践与思考

2023 · 14 篇

年度封面 · 10-01 · 2 分钟

如何阅读科学文献

为什么需要掌握科学文献阅读? 在AI快速发展的今天,每天都有大量的研究论文发布。以计算机视觉领域为例,仅arXiv每天就有5…

标签:方法论 / 阅读
10 月 · 其余 0 篇
7 月 · 其余 2 篇
6 月 · 其余 1 篇

精读 Out of the Tar Pi(上)

原文地址:http://curtclifton.net/papers/MoseleyMarks06a.pdf 共12个章节,讨论复杂度性对编程的影响,论文包含66页,分三篇文章进行精读 1 Introduction…

2 分钟
5 月 · 其余 1 篇

手写一个简单的 GPT:把学到的原理跑起来

本文是「零基础学大模型原理」系列的第 8 篇,实战篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN…

2 分钟
零基础学大模型原理
4 月 · 其余 2 篇

RAG:检索增强生成的收益与天花板

最近在研究怎么把大模型接到知识库上,RAG 是绕不开的方案。我看了一些资料,也动手试过。这篇先把它的原理、适用范围和限制理一遍。 RAG 是什么 大模型有两个常见问题:知识会过期,训练结束后不会自动更新;模型也会生成看似合理但实际错误的内容,也就是幻觉。 202…

1 分钟
3 月 · 其余 3 篇

longChain 学习

最近了解 Open AI 的过程中发现这个框架,把中文文档整理如下 LangChain 是一个使用语言模型驱动应用程序开发的框架。最强大、最具差异化的应用程序不仅仅通过 API…

2 分钟

三个月零基础学大模型:收获、疑问与下一步

本文是「零基础学大模型原理」系列的第 7 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN、seq…

2 分钟
零基础学大模型原理

从 GPT-3 到 ChatGPT:指令微调与 RLHF

本文是「零基础学大模型原理」系列的第 6 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN、seq…

2 分钟
零基础学大模型原理
2 月 · 其余 2 篇

GPT 系列:从 GPT-1 到 GPT-3 的演进逻辑

本文是「零基础学大模型原理」系列的第 5 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN、seq…

2 分钟
零基础学大模型原理

Transformer 详解:自注意力、多头与位置编码

本文是「零基础学大模型原理」系列的第 4 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN、seq…

2 分钟
零基础学大模型原理
1 月 · 其余 2 篇

Transformer 之前:RNN、seq2seq 与注意力机制

本文是「零基础学大模型原理」系列的第 3 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec Transformer 之前:RNN、seq…

2 分钟
零基础学大模型原理

词怎么变成向量:从 one-hot 到 Word2Vec

本文是「零基础学大模型原理」系列的第 2 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播 词怎么变成向量:从 one-hot 到 Word2Vec…

1 分钟
零基础学大模型原理

2022 · 16 篇

年度封面 · 12-20 · 2 分钟

神经网络入门:从感知机到反向传播

神经网络入门:从感知机到反向传播 本文是「零基础学大模型原理」系列的第 1 篇。这个系列记录一个没有任何机器学习背景的工程师,在 ChatGPT 发布之后从零补原理的过程。 神经网络入门:从感知机到反向传播(本文) 2022 年 11 月 30 日 ChatGPT…

系列:零基础学大模型原理·标签:大模型
12 月 · 其余 1 篇

JSVM3 的预编译、序列化与运行时优化

系列目录 「JSVM3 原理与思考」系列,基于 jsvm3 源码整理: 从 AST 直驱到字节码:JSVM3 的编译与执行分层 JSVM3 如何执行字节码:指令、栈帧与求值栈 JSVM3 如何实现函数调用、作用域与声明提升 JSVM3 如何编译循环、跳转与 try/catch…

2 分钟
JSVM 实现原理
9 月 · 其余 1 篇

用测试定义解释器的语义边界

系列目录 「JSVM3 原理与思考」系列,基于 jsvm3 源码整理: 从 AST 直驱到字节码:JSVM3 的编译与执行分层 JSVM3 如何执行字节码:指令、栈帧与求值栈 JSVM3 如何实现函数调用、作用域与声明提升 JSVM3 如何编译循环、跳转与 try/catch…

2 分钟
JSVM 实现原理
7 月 · 其余 1 篇

JSVM3 如何编译循环、跳转与 try/catch/finally

系列目录 「JSVM3 原理与思考」系列,基于 jsvm3 源码整理: 从 AST 直驱到字节码:JSVM3 的编译与执行分层 JSVM3 如何执行字节码:指令、栈帧与求值栈 JSVM3 如何实现函数调用、作用域与声明提升 JSVM3 如何编译循环、跳转与 try/catch…

2 分钟
JSVM 实现原理
6 月 · 其余 3 篇

实时 OLAP:列存与预聚合的两条路线

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

MBTI学习与理解

MBTI 的四个维度 MBTI = 4个 我更偏向怎样做选择 的问题 MBTI 用四个维度描述偏好: 能量从哪里来 信息怎么进入脑中,以及怎么观察世界 决策靠什么 生活怎么安排 这些维度描述的是偏好,不能单独用于判断一个人的能力、性格完整性或具体行为。 E / I…

1 分钟
5 月 · 其余 2 篇

TS实现基于字节码的JS 虚拟机

系列目录 「JSVM3 原理与思考」系列,基于 jsvm3 源码整理: 从 AST 直驱到字节码:JSVM3 的编译与执行分层(本篇) JSVM2 系列已经说明过 AST 直驱解释器的实现和边界:Babel 解析出 AST,Visitor…

1 分钟
JSVM 实现原理
3 月 · 其余 4 篇
2 月 · 其余 3 篇

JSVM2:解释器的骨架,visitor、Path 与作用域链

上一篇说明了自研原因和整体链路:源码经 @babel/parser 生成 AST,再由解释器求值。本文展开解释器实现。其分发入口只有 5 行,主要结构是 Path 和 Scope:前者参考 Babel,后者对应 ECMA-262 的环境记录。这套结构的雏形见[202…

2 分钟
JSVM 实现原理

JSVM2:为什么小程序需要一台 JS 虚拟机

2020 年我写过一篇《使用TS 开发 JS 虚拟机》,介绍用 TypeScript 实现基于 AST 的 JS 解释器。项目在 2021 年 7 月正式立项重写,并于 2022 年 2 月发布 1.0.0。本系列整理其实现过程和已知边界;性能与执行模型问题在 JSVM…

2 分钟
JSVM 实现原理

2021 · 21 篇

11 月 · 其余 0 篇
10 月 · 其余 2 篇

链路追踪:Dapper 模型与埋点的取舍

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记
9 月 · 其余 5 篇

React 18 追踪:Fizz,流式 SSR 引擎

此前的文章主要分析客户端 reconciler。服务端渲染在这几个月也发生了变更:6 月 2 日 76f85b3e 将 Fizz bundle 从 experimental 构建移入 stable 构建(入口当时为 react-dom/unstable-fizz.node);…

3 分钟
React 18 源码分析
8 月 · 其余 3 篇

React 18 追踪:事件系统与 Context 传播

第 6 篇分析 重构时,事件入口仍包含一层 。7 月 12 日的 bfa50f8272(Inline discreteUpdates)移除了这层封装:离散事件回调不再预先修改执行上下文,入口函数直接修改模块级变量。事件系统通过事件优先级与调度器连接。本文同时分析 Context…

3 分钟
React 18 源码分析
7 月 · 其余 4 篇

React 18 追踪:自动批处理与交错更新队列

以下组件包含一个按钮;点击后创建 setTimeout,并在回调中连续调用两次 setState: React 17 中点击一次会输出两行 render,两次 setState 分别触发一次完整的渲染和提交。React 18 alpha 的结果取决于挂载入口:createRoot…

2 分钟
React 18 源码分析

React 18 追踪:flushSync 统一同步刷新入口

上一篇介绍了 createRoot 转为正式入口。同一周,master 对同步刷新 API 进行了两次相反的修改:7 月 1 日的两个 commit 将 和 两个内部入口合并到 flushSync,7 月 7 日的 commit 又整体回滚这两个改动,且 commit…

2 分钟
React 18 源码分析
6 月 · 其余 4 篇
3 月 · 其余 1 篇

Elasticsearch 的近实时模型与误用为数据库的后果

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记
1 月 · 其余 1 篇

2020 · 20 篇

年度封面 · 12-25 · 1 分钟

小程序工程化思考

和传统工程化对比 下图列出传统前端工程化关注的内容(from umi)。 image.png image.png 小程序的工程化空间受运行时和框架能力限制,下面按能力逐项比较: 框架:可选方案包括 kbone、taro、remax/r2m、mpvue、mpx…

标签:架构 / 小程序
12 月 · 其余 1 篇
11 月 · 其余 2 篇

分布式事务:2PC 的代价与业务补偿模式

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记
10 月 · 其余 1 篇
9 月 · 其余 1 篇
8 月 · 其余 2 篇

分库分表:用应用层复杂度换数据库容量

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

识别和培养骨干:建立分层培养机制

梯队建设:能力分布与培养路径讨论过,团队扩大到 30 人,增加两个子方向和一个跨团队协作小组后,要检查方向覆盖、能力深度和关键职责后备。还要确认团队是否持续有人能够承担更大职责,以及负责人能否承接日常培养。管理者仍直接支持少数关键成员。 201…

1 分钟
团队管理
7 月 · 其余 2 篇

使用TS 开发 JS 虚拟机

背景 小程序和低代码平台需要执行动态下发的代码。当时调研到的部分 VM 未完整通过 ES5 或 ES2015 测试用例,不能满足生产环境的兼容性要求,因此实现了自己的 JSVM 引擎。 目前已放到 github 上 :jsvm 2 传送门。 目前除了 WithStatement…

1 分钟
JSVM 实现原理
6 月 · 其余 3 篇
5 月 · 其余 4 篇

关于基建工作的思考

技术债务评估 对于技术债务,它的利息表现为系统的不稳定性,以及由于临时性手段和缺乏合适的设计、文档工作和测试带来的不断攀升的维护成本。 —— 《架构师应该知道的 97 件事》 Robert Nord 提出的“技术债务全景图”(Tech Debt Landscape…

1 分钟
4 月 · 其余 1 篇
3 月 · 其余 2 篇

ZooKeeper/etcd:小数据强一致的协调服务

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

2019 · 25 篇

年度封面 · 11-22 · 1 分钟

使用 React 能力开发小程序

最近一年我在小象负责移动端架构工作。此前,我们基于 pixi 实现游戏框架,将 React 桥接到 pixi,因此开始考虑让 React 运行在其他平台。 该小程序承载较复杂的电商业务,与 App 的交互保持一致,需要配套工具和规范。201…

标签:小程序
11 月 · 其余 1 篇

前端视角支持游戏开发

最近实现了一个天天领钱 H5 游戏,一期基础场景如下 image.png 在开发果园前,我们与其他部门负责游戏开发的同学沟通过实现经验: 框架层面:了解到他们使用的是 cocos creator 框架,他们提到 Cocos 框架由 C++ 迁移到 JavaScript…

1 分钟
10 月 · 其余 1 篇

分布式任务调度:同一时刻只跑一份

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记
8 月 · 其余 3 篇

TypeScript 类型体操:条件、映射与递归类型

TypeScript 的类型系统可以根据输入类型计算出另一个类型。这里的“类型体操”通常指把条件类型、映射类型、、模板字面量类型和递归组合起来,给函数、配置对象和 API 增加静态约束。 这些技巧只在编译期间运行,不会生成 JavaScript…

1 分钟
7 月 · 其余 3 篇

RocketMQ 的事务消息与延迟消息

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

授权的范围与责任:决策权如何随任务转移

反馈确认的调整动作里,有一类是把更多决定交给成员自己做。决定交出去的范围,以及管理者仍需承担的责任,需要在授权时事先明确。这里记录培训中的授权框架和我当时的理解。 先说我当时的处境。…

1 分钟
团队管理
6 月 · 其余 3 篇

InversifyJS:容器、作用域与条件绑定

InversifyJS 是面向 TypeScript 和 JavaScript 的依赖注入容器。它将“创建对象”和“使用对象”分开:业务类声明自己依赖什么,容器负责按绑定规则创建并组装对象。 本文使用 InversifyJS 传统的装饰器 API…

1 分钟
5 月 · 其余 5 篇

TypeScript 中的 keyof 与 typeof

背景 下面的 TypeScript 写法: 这两个类型定义等价。下面分别说明这两个操作符的作用。 1.  的作用 获取对象类型的键的联合类型: 这常用于限制函数参数必须为对象的有效键: 2.  的作用 获取变量或表达式的类型: 当变量结构较复杂时,可以用它避免重复定义类型。…

1 分钟

唯一 ID 中间件 Leaf:号段模式与雪花模式

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

小程序实时日志

背景 小程序开发中,真机调试时看不到日志。 如果只需要支持微信小程序,这个问题还能靠 vConsole 缓解——它会在页面上挂一个悬浮的调试面板,把 输出和网络请求都展示出来。同时支持美团小程序后,美团小程序的双线程架构带来了额外限制: 层(逻辑层)运行在独立的 JSCore…

1 分钟
4 月 · 其余 2 篇
3 月 · 其余 1 篇

熔断与限流中间件:把失败当作正常状态管理

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记
2 月 · 其余 5 篇

推进工作的方法论之PDCA循环

意义 每项工作都可以按 PDCA 循环推进:先计划,再实施和检查,并根据检查结果调整下一轮计划。循环的作用是让改进措施进入后续工作,而不是停留在一次检查或复盘中。 细则 Plan:制定目标与计划; Do:展开任务并组织实施; Check…

1 分钟

RASCI模型

团队扩张时,常会出现职责尚未明确的事项:参与者都以为自己在配合,但没有人负责推进或做最终判断。RACI 模型要求在事项开始时确定责任角色,尤其是负责执行的主 R。 谁负责(R = Responsible) 负责执行任务的角色,具体推进项目和解决问题。 谁批准(A…

1 分钟

MECE-金字塔原理

image.png 用 7 个问题理解《金字塔原理》 什么是金字塔原理? 一个主题可以归纳为中心论点,并由 3–…

1 分钟

SWOT分析法

SWOT 分析是一种战略规划方法,用于识别个人、组织或项目的优势(Strengths)、劣势(Weaknesses)、机会(Opportunities)和威胁(Threats)。它将内部条件与外部环境分开整理,为项目、产品、业务或个人的后续判断提供输入。 SWOT…

1 分钟

5WHY分析法

简介 COE 复盘时经常使用 5 WHY 分析法,又称“5 问法”。它通过连续追问“为什么”,沿因果关系查找问题的根本原因。 “5”不是固定次数。追问在找到可验证、可处理的根本原因时停止,可能是 3 次,也可能是 1…

1 分钟

2018 · 45 篇

ProseMirror 系列收官:从这套代码里能拿走的设计
年度封面 · 12-19 · 3 分钟

ProseMirror 系列收官:从这套代码里能拿走的设计

第 59 篇对比了 ProseMirror、Draft.js、Slate、Quill 的文档模型。本系列共 60 篇,从仓库结构和文档 JSON 开始,分析核心四包、从 keymap 到 tables…

系列:ProseMirror 源码分析·标签:源码分析
12 月 · 其余 1 篇
11 月 · 其余 3 篇

多包仓库的构建与发布工程

本文从单个包上移到工程组织层:22 个包各自使用独立 git 仓库,另有 、、 三个辅助仓库。项目未使用 lerna 或 changesets,meta 仓库以一个 384 行脚本统一管理。参考代码为 meta 仓库 的 c7f2f1d…

3 分钟
ProseMirror 源码分析

test-builder:测试文档怎么写得像代码

上一篇分析了 的插件装配。本篇分析各包测试使用的基础设施。 的测试中常见如下写法: 函数调用构造文档,字符串中的尖括号标签表示位置,第三个参数表示期望文档。 用 和 实现这套接口,共约一百六十行。本文说明 builder 如何从 schema…

3 分钟
ProseMirror 源码分析
10 月 · 其余 4 篇

columnresizing:列宽拖拽的实现

、 等命令通过 的格网坐标修改文档结构。列宽拖拽不改变结构,只更新 attr。实现位于两个文件: 处理鼠标事件、拖拽状态和手柄装饰; 的表格 NodeView 将文档中的 同步到 的 元素。参考代码为 的 eb522f2;、 分别为 ffad5d9、ca4c78e…

3 分钟
ProseMirror 源码分析

表格专题(下):addColumn/mergeCells 等编辑命令

的编辑命令集中在 ,包括加列、删行、合并、拆分和导航等二十余个导出。命令通常先用 将选区换算为矩形,在格网坐标中计算目标位置,再换算为文档位置,并通过 、、 修改文档。本文使用前两篇的 和 分析这些命令。参考代码为 的 eb522f2。 系列目录 日期 标题 05-1…

3 分钟
ProseMirror 源码分析

表格专题(中):CellSelection,矩形的选区

上一篇介绍了表格 schema 和 :合并单元格被计算为格网,、、 在格网坐标上执行。本篇分析 ,说明矩形单元格选区的表示、渲染和文档修改后的映射。参考代码为 的 eb522f2;、 分别为 ffad5d9、ca4c78e。 系列目录 日期 标题 05-1…

3 分钟
ProseMirror 源码分析

表格专题(上):表格 schema 与 TableMap

本文开始分析 。合并单元格使行列坐标不能直接对应兄弟节点下标,表格选区是矩形,删除列还需要同步修改多个单元格的 attrs。该包将二维表格结构计算为扁平格网;命令先在格网上计算坐标,再换算为文档位置。 是仅定义表格 schema 的历史包,已由 取代。参考代码为 的 eb…

3 分钟
ProseMirror 源码分析
9 月 · 其余 3 篇

消息语义:按 at-least-once 设计业务代码

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

search:查找替换插件

markdown 处理文档与外部文本的双向转换。本文说明 prosemirror-search 提供的编辑器查找替换功能。整个包只有两个源文件:query.ts 负责匹配和替换内容的计算,search.ts 负责插件状态、命令和装饰。对外导出 SearchQuery…

3 分钟
ProseMirror 源码分析

markdown:文档与 Markdown 的双向转换

changeset 用 span 表示两份文档之间的差异。本文说明文档与 Markdown 文本之间的转换。prosemirror-markdown 做两件事:把文档序列化成 Markdown 字符串,把 Markdown 字符串解析回文档。参考代码是 prosemirror…

3 分钟
ProseMirror 源码分析
8 月 · 其余 3 篇

changeset:变更集的计算与展示

collab 处理本地 step 的发送和远端 step 的重整。协作场景还需要汇总一段时间内的修改,标明删除和插入的内容。prosemirror-changeset 提供这一计算:输入是起始文档和一串 StepMap…

3 分钟
ProseMirror 源码分析
7 月 · 其余 4 篇

RPC 框架:像本地调用一样调远程的代价

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

menu:菜单栏组件体系

此前的扩展包分别处理按键、命令、撤销、输入规则、文档结构和光标位置,基本不负责界面呈现。prosemirror-menu 是系列中的 UI 包,用于将 commands 体系中的命令组织为工具栏。包不大,src 下三个实现文件:menu.ts 定义菜单元素体系,menubar…

3 分钟
ProseMirror 源码分析

dropcursor:拖拽时的插入位置指示

gapcursor 处理块间的光标位置。dropcursor 在拖拽内容经过编辑器时标出松手后的插入位置。浏览器原生拖拽反馈通常只显示鼠标箭头上的图标;在文档中拖动图片或从外部拖入文件时,文档内不会显示插入位置。dropcursor 画的就是这个插入点指示。整个包只有 src…

2 分钟
ProseMirror 源码分析

gapcursor:光标落不进去的地方怎么办

块级节点之间没有文本容器时,光标需要落在两个块之间的位置。gapcursor 处理这类位置。整个包 src 下只有两个源文件:src/gapcursor.ts 定义选区类型,src/index.ts 定义插件,合计 230 来行。参考代码是 prosemirror…

3 分钟
ProseMirror 源码分析
6 月 · 其余 3 篇

schema-basic:官方基础文档结构

上一篇引出 schema-basic。此前的 model 文章说明了 NodeSpec 字段和内容表达式如何编译为匹配自动机,但尚未完整分析一份 schema 实例。prosemirror-schema-basic 提供官方基础结构,example-setup 和多数 demo…

3 分钟
ProseMirror 源码分析

inputrules:「# 空格」变成标题是怎么实现的

上一篇分析 history 的 undo/redo 栈,本文分析 inputrules。该包实现多种 Markdown 风格输入:在空段落输入「# 空格」转换为标题,输入「> 空格」转换为引用块,两个减号转换为破折号,直引号转换为弯引号。参考代码为 prosemirror…

2 分钟
ProseMirror 源码分析
5 月 · 其余 7 篇

Kafka(下):生产端、broker 与消费端的可靠性配置

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

commands:命令的签名约定与组合器

上一篇说明 keymap 如何按按键定位 ,本文分析命令本身。参考代码为 prosemirror-commands 的 52a84a8,整个包只有 ,约八百行。文件包含删除与光标命令、结构命令、参数化命令工厂(wrapIn、setBlockType、toggleMark…

2 分钟
ProseMirror 源码分析

扩展(上):keymap,最小的插件

本文开始分析扩展包。上一篇的最小编辑器已经处理输入、删除和加粗;加粗由按钮直接派发命令,快捷键由官方扩展处理。第一个包是 prosemirror-keymap,参考代码为 d60e24…

2 分钟
ProseMirror 源码分析

算法题-24点

题目 从 1~13 任取四个数字,通过+,-,* ,/和() 来计算 24 点 其实这个是算法分析里面提到过的一个标准做法,使用的方式是逆波兰表达式,也就是后缀表达式 首先把全部运算情况的逆波兰表达式穷举出来,采用逆波兰表达式是因为不用考虑操作符的优先级. 2…

1 分钟

算法题-螺旋化

原题如下 Your task, is to create a NxN spiral with a given . For example, spiral with size 5 should look like this: and with the size 10: Return…

1 分钟

DI&IOC基本概念

DI 和 IOC 的关系 DI(依赖注入)和 IOC(控制反转)相关,但含义不同。 控制反转(IOC)是一种设计原则:组件不在自身代码中解析和管理依赖,而由外部容器或框架负责这些工作。组件因此可以替换依赖实现、复用,并在测试中注入替代依赖。 依赖注入(DI)是实现 IOC…

1 分钟
4 月 · 其余 4 篇

browser.ts:浏览器差异补丁集

上一篇的坐标换算已经使用了 、 等分支。view 的输入管线、DOMObserver、选区同步和剪贴板模块也包含类似判断。这些判断条件来自 ,探测逻辑集中定义,补丁保留在对应模块。本篇说明该文件及其相邻的 DOM 工具集 。参考代码是 prosemirror-view 的 ca…

2 分钟
ProseMirror 源码分析

domcoords:屏幕坐标与文档位置的双向换算

上一篇讨论剪贴板。view 模块中还包括坐标换算和浏览器差异补丁,本篇讨论坐标换算。 负责文档位置与屏幕坐标的双向转换,点击定位、方向键移动、拖拽落点和选区滚动都依赖这里。参考代码是 prosemirror-view 的 ca4c78e。 文档模型里的 pos…

2 分钟
ProseMirror 源码分析
3 月 · 其余 4 篇

clipboard:复制粘贴的序列化与解析

view 模块还包括剪贴板、坐标换算和浏览器差异补丁。本篇讨论剪贴板。选区可能从节点中间切开,直接序列化为 HTML 会丢失结构信息;粘贴的 HTML 可能来自编辑器、Word、网页或终端,结构不受当前 schema 控制。prosemirror-view…

2 分钟
ProseMirror 源码分析

Decoration 体系:不修改文档的视觉标注

上一篇讨论的 NodeView 和 MarkView 用于定制文档节点的渲染。占位符、协作者光标、搜索高亮和选中节点边框不属于文档内容;将它们写入文档会影响序列化结果和协作同步。ProseMirror 使用 Decoration…

3 分钟
ProseMirror 源码分析

实时协作文档复盘

我将转到新零售业务,大象商业化相关工作暂停。过去半年主要投入在实时协作文档业务,现阶段先保留这篇记录,后续补充具体复盘内容。 待续…

1 分钟
实时协作
2 月 · 其余 4 篇

Composition 与 IME:中文输入法事件的处理

上一篇讨论 state 选区与 DOM 选区的双向同步。本篇讨论中文、日文输入法的 composition 场景。从输入「nihao」到上屏「你好」期间,浏览器处于 composition 状态,候选拼音直接写入 contenteditable…

2 分钟
ProseMirror 源码分析

DOMObserver 与 readDOMChange:将 DOM 变化读回文档

前两篇讨论文档到 DOM 的方向:ViewDesc 树如何将 state.doc 渲染为 DOM,增量更新如何只重画变化部分。用户在 contenteditable 中输入、删除或用输入法上屏时,浏览器会直接修改 DOM,文档模型不会预先得到通知。view 层需要将这些 DOM…

3 分钟
ProseMirror 源码分析
1 月 · 其余 4 篇

Kafka(上):吞吐的来源是顺序 IO

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

ViewDesc(下):增量更新怎么做到只改动的部分

上一篇介绍了 中描述树的静态结构:ViewDesc 类族的职责、children 与文档树的对应以及 docViewDesc 的构建。文档变化后,DOM 需要更新以反映新文档。全量替换 innerHTML 会丢失光标和输入法组合状态,也会清空自定义 node view…

3 分钟
ProseMirror 源码分析

ViewDesc(上):文档到 DOM 的描述树

上一篇分析 EditorView 构造函数时,第 4 步调用 将当前文档渲染到 ,并将结果保存为 。 是定义在 的 ViewDesc 描述树。view 层的渲染、选区、坐标换算和 DOM 读回都依赖这棵树。本文说明其静态结构,包括类族职责、children…

2 分钟
ProseMirror 源码分析

2017 · 41 篇

state 示例:三个插件的实现
年度封面 · 12-20 · 2 分钟

state 示例:三个插件的实现

state 阶段已介绍 EditorState 的装配与应用、Selection、Transaction,以及两篇 Plugin 系统文章。本篇通过三个插件示例验证这些接口的使用方式:字符统计使用 StateField,只读开关使用 filterTransaction…

系列:ProseMirror 源码分析·标签:源码分析
12 月 · 其余 2 篇
11 月 · 其余 3 篇
10 月 · 其余 4 篇

Transform 类:构建修改的 API 层

这是 transform 阶段的最后一篇。前面五篇分别讨论了 Step 抽象、ReplaceStep 和 Fitter、StepMap、Mapping,以及 structure.ts 的结构判断函数。这些组件通过 Transform 类()提供给命令层。Transform…

3 分钟
ProseMirror 源码分析

Mapping:多步映射的链式合并,rebase 的地基

上一篇介绍了 StepMap 如何用三元组数组描述单个 step、映射位置,并通过 recover 值记录被删除位置。recover 的消费方位于同一个文件: 的下半部分定义了 Mapping 类,用它可将零到多张 StepMap 组合起来,使位置依次经过多步修改。recover…

2 分钟
ProseMirror 源码分析

StepMap:一步修改怎么映射每个位置

这是 transform 阶段的第三篇。前两篇介绍了 Step 抽象和 ReplaceStep 的实现。step 应用后文档位置会变化,旧选区、装饰和并发修改中记录的位置需要换算到新文档。ProseMirror 中有许多以位置为锚点的对象:选区使用 anchor 和 head…

2 分钟
ProseMirror 源码分析
9 月 · 其余 3 篇

数据库访问层:连接池与 MyBatis 的显式 SQL

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

ProseMirror transform(上):Step 的接口与实现

前十二篇已经分析整体结构与 prosemirror-model:文档树、位置编号、切片和解析。model 层的约束是文档不可变,Node 不提供原地修改方法。prosemirror-transform 将键入、粘贴、加粗等操作表示为一个或多个 Step…

2 分钟
ProseMirror 源码分析
8 月 · 其余 4 篇

Redis(下):超出缓存用途的用法:锁、队列与排行榜

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis(上):缓存用法与单线程模型的限制 Redis…

2 分钟
后端中间件学习笔记

Node 辅助方法与位置约定

本篇是 model 阶段的第九篇。此前已分析 Node 与 Fragment 的结构、Mark、Schema 与内容表达式、ResolvedPos、Slice 与 replace、DOM 序列化与解析以及 diff。 和 中还有三类常用方法:遍历用的 nodesBetween…

2 分钟
ProseMirror 源码分析

DOMParser:parseDOM 规则与 HTML 解析

上一篇分析了 toDOM 如何将文档序列化为 DOM 和 HTML。本篇分析反方向的 :外部 DOM,例如剪贴板 HTML、服务端渲染的初始内容或其他编辑器导出的片段,如何按 schema 的 parseDOM 规则解析回文档。DOMParser…

2 分钟
ProseMirror 源码分析
7 月 · 其余 4 篇

DOMSerializer:文档怎么变成 DOM 和 HTML

前几篇分析了 model 层的存储和修改:Node 与 Fragment 如何存储文档,Mark 如何挂在文本上,Schema 如何约束结构,位置如何解析为路径,以及 Slice 如何切出和插回内容。本篇转向模型输出,分析文档如何转换为浏览器 DOM 和可复制的 HTML…

2 分钟
ProseMirror 源码分析

ResolvedPos:一个数字位置怎么变成路径

前面三篇分析了 model 的静态结构:Node 与 Fragment 组成的树、挂在内联节点上的 Mark,以及约束树形状的 Schema。编辑器使用单个数字表示光标和选区端点,state 的 selection 与 transform 的 step…

2 分钟
ProseMirror 源码分析
6 月 · 其余 3 篇
5 月 · 其余 3 篇

跑通一个最小 ProseMirror:先看文档长什么样

前两篇介绍了阅读 ProseMirror 的原因和 22 个包的分工。本文先运行一个编辑器示例,在控制台检查文档 JSON 与一次输入产生的 Transaction。后续阅读 model 和 state 源码时,可以将字段与这些运行结果对应。参考代码版本:prosemirror…

2 分钟
ProseMirror 源码分析

ProseMirror 仓库全景:22 个包怎么分工

上一篇讨论了 contenteditable 的限制和 ProseMirror 的应对方式。阅读源码前,先确认代码的位置。ProseMirror 的核心和扩展分成 22 个独立包,本地工作区根目录下有 22 个 prosemirror-* 目录;每个目录各有一个 git…

3 分钟
ProseMirror 源码分析
4 月 · 其余 8 篇

实时协作-yjs和ShareDB对比

两个方案都在脑图协作中尝试过,比较如下。 Yjs(基于 CRDT 算法)和 ShareDB(基于 OT 算法)是两种实时协作编辑方案,各自有不同的适用条件。 Yjs(基于 CRDT 算法)的特点: 离线支持和冲突解决: CRDT 算法考虑离线工作和冲突解决,Yjs…

1 分钟
实时协作

Excel 实时协作协议的设计

做大象协作文档时,Excel 的协作模型需要处理表格结构操作对坐标系的影响:插入一行之后,后续所有单元格的行号都会变化。op 如果不理解这个语义,两个客户端各插一行时,改单元格的 op 会落到错误的位置,两端会看到不同的表。 市面上通用的 OT 实现大多面向文本(ot.js…

3 分钟
实时协作

实时协作-yjs基本理解4-Ytext

Yjs 中的 Y.Text 是一种 CRDT(Conflict-free replicated data types),用于处理分布式环境中的实时协作文本编辑。Y.Text 允许多个用户同时在文本任意位置插入和删除,无需处理冲突或数据不一致。 Y.Text…

1 分钟
实时协作

实时协作-yjs基本理解3-操作日志

在 Yjs 中,操作日志(Operation Log)记录对数据的修改,包括插入字符和删除字符。每个操作包含操作类型(插入或删除)、位置、内容和唯一标识符(用户 ID 与时间戳)。操作日志可生成差异(delta),并发送给其他副本以更新其状态。 收到新操作后,Yjs…

1 分钟
实时协作

实时协作-yjs基本理解2-向量时钟

向量时钟(Vector Clock)是分布式系统中记录和比较事件发生顺序的数据结构。每个节点维护一个向量时钟,其中每个元素对应一个系统节点的逻辑时钟值。逻辑时钟值是非负整数,表示节点已发生的事件数量。 在 Yjs…

1 分钟
实时协作

实时协作-yjs基本理解

Yjs 是开源 JavaScript 库,实现基于 CRDT(Conflict-free Replicated Data Type)的共享数据类型。多个用户可以在没有中心协调者的条件下并发编辑共享数据。 Yjs 的基本原理可概括为: 数据结构:Yjs 提供多种 CRDT…

1 分钟
实时协作

实时协作-CRDT基本理解(2)

CRDT 实现还需要处理并发操作和网络延迟。LSEQ tree 是协作编辑中常见的一类 CRDT,但其数据结构较复杂。这里使用简化的列表 CRDT…

1 分钟
实时协作

实时协作-CRDT基本理解

CRDT(Conflict-free Replicated Data Types)通过合并策略和操作转换,使多个端的协作状态最终保持一致。以下用一个简化的文本编辑器示例说明并发插入的处理方式。 假设端 A 和端 B 同时编辑同一段文本,执行以下操作: 端 A…

1 分钟
实时协作
3 月 · 其余 1 篇

Redis(上):缓存用法与单线程模型的限制

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型 Redis…

2 分钟
后端中间件学习笔记
2 月 · 其余 2 篇

Web 容器与 Netty:线程模型之下的 IO 模型

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界 Web 容器与 Netty:线程模型之下的 IO 模型(本篇) 容器怎么处理连接 云盘服务端内嵌 Jetty…

2 分钟
后端中间件学习笔记
1 月 · 其余 3 篇

接入层:Nginx 反向代理与 OpenResty 的边界

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁 接入层:Nginx 反向代理与 OpenResty 的边界(本篇) 把文件传输从业务进程里挪出去 2016 年做 IM 文件转发时,Java…

2 分钟
后端中间件学习笔记

算法题-数组列表中的最大距离

题目 给定 m 个数组,每个数组都已经按照升序排好序了。现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。两个整数 a 和 b 之间的距离定义为它们差的绝对值 |a-b| 。你的任务就是去找到最大距离 代码

1 分钟

2016 · 23 篇

年度封面 · 12-24 · 1 分钟

2016总结

201…

标签:随笔
12 月 · 其余 1 篇

声明式事务之下:InnoDB 的 MVCC 与锁

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描 声明式事务之下:InnoDB 的 MVCC 与锁(本篇) 回滚后读到中间值的原因 2016 年写一个涉及状态流转的接口时,一个事务把某条记录的状态从 A 改成 B…

2 分钟
后端中间件学习笔记
11 月 · 其余 2 篇

高可用的四件兵器:超时、重试、限流与降级

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future 与 CountDownLatch…

2 分钟
服务端工程实践

分布式锁与唯一 ID:多实例部署后的新问题

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

2 分钟
服务端工程实践
10 月 · 其余 2 篇

Tair 缓存的穿透、雪崩与可用性

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

1 分钟
服务端工程实践

压测与容量评估:IM 融合前的流量需求

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

1 分钟
服务端工程实践
9 月 · 其余 1 篇

流对流的失败率、NIO 与零拷贝

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

2 分钟
服务端工程实践
8 月 · 其余 3 篇

logback 日志规范与线上问题定位

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

1 分钟
服务端工程实践

JVM 内存与 GC:线上 Full GC 排查记录

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

2 分钟
服务端工程实践

德州牌型概率

5 张牌组合的牌型概率 以下按从高到低的顺序列出牌型概率: 皇家同花顺(Royal Flush)概率是 ,约每649,739次有一次。 同花顺(Straight Flush)概率是 ,约每72,193次有一次 四条(Four of a Kind)概率是 ,约每4,16…

2 分钟
7 月 · 其余 2 篇

IM 消息文件实现

背景 云盘业务需要与内部使用的大象 IM 融合,云盘负责大象 IM 的文件流转。大象原有协议中的文件消息包含静态链接,当时还没有鉴权。云盘设计为使用带鉴权信息和时效的动态链接。因此,需要设计一个同时包含鉴权信息并满足大象 IM 协议要求的 URL…

1 分钟
云盘同步

轻OA 的一些思考

从技术角度看,信息化系统通常由流程、表单和角色构成。 从业务角度看,不同系统关注的资源不同:ERP 关注物质资产,HR 系统关注人力资产,CRM 关注外部客户资源。 轻 OA 关注周报、日程、TODO 等事务性工作。 如果围绕即时通讯建设 OA…

1 分钟
6 月 · 其余 1 篇

Kafka 异步化与削峰:热点上报和最终一致性

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

1 分钟
服务端工程实践
5 月 · 其余 3 篇

Future 与 CountDownLatch:一个接口聚合一堆下游

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap 与锁:文件元数据的并发读写 Future…

1 分钟
服务端工程实践

ConcurrentHashMap 与锁:文件元数据的并发读写

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 ConcurrentHashMap…

1 分钟
服务端工程实践

解决复杂问题的方法论

用 Cynefin 识别问题类型 日常工作和生活中的问题,可能有标准流程可处理,也可能需要专业分析,或因因果关系难以预测而需要在行动中获取信息。Cynefin 框架提供了一种区分这些情况的方式。 Cynefin 框架 Cynefin 是一个帮助决策的概念框架,由 Dave…

1 分钟
4 月 · 其余 4 篇

数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池不是 new 出来就完事:参数、队列与快慢接口隔离 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上(本篇) 从 Node.js 的事务写法开始准备 做 Java…

1 分钟
服务端工程实践

nodejs addon 结合 libuv 使用经验

基于 electron 开发客户端时,需要通过 nodejs addon 扩展 electron 相关功能。本文记录 libuv 异步 addon 的线程与数据传递方式。 asynchronous addons C++ 中的耗时任务应使用异步 addon…

1 分钟

线程池参数、队列与快慢接口隔离

系列目录 从单线程到线程池:云盘转 Java 后的第一堂并发课 线程池参数、队列与快慢接口隔离(本篇) 数据库连接池与 Spring 声明式事务:把 Node.js 的坑填上 上一篇讨论了 Node.js 单事件循环与 Java 请求线程池的差异。此前写过 Node.js、C…

1 分钟
服务端工程实践
3 月 · 其余 1 篇
1 月 · 其余 2 篇

如何召开一场有效的会议

判断是否需要开会 发起会议前,先确认会议是否必要。 确定开会后,需要管理会前、会中和会后的过程,以便完成会议目标。 会议发起人的职责 会前准备 明确主题和议程 每个会议都应通过议程明确目标和期望结果,包括信息分享会议。 在会议前2…

1 分钟
团队管理

2015 · 20 篇

年度封面 · 12-31 · 1 分钟

2015总结

总的来说,这世界是个好地方,值得为它奋斗。

标签:随笔
12 月 · 其余 2 篇

启发式方法论

启发式(Heuristic)是在信息不完备或精确计算成本不可接受时,依据经验规则寻找可行解的方法。它不保证数学最优,而是在给定时间内获得满足要求的结果。 词源 这个词来自希腊语 heuriskein(εὑρίσκειν),意思是发现、找到。“尤里卡”(Eureka…

1 分钟

如何分析问题

结构化分析的作用 美团的汇报文档通常包括以下部分: 背景(现状) 分析 问题 目标 解决方案 预计结果 这种组织方式将现状、判断和行动方案分开,便于讨论。实际写作中,背景和现状材料往往很多,但还需要进一步分析,明确需要解决的问题。《金字塔原理》提供了两项常用方法:MECE…

1 分钟
11 月 · 其余 1 篇

云盘点击热点图

云盘实现了点击热点上报系统,供 UED 根据页面点击分布调整设计。结果如下: image.png 实现 采集上报 云盘使用 React,常规业务事件由 React 合成事件代理。热点 SDK…

1 分钟
云盘同步
10 月 · 其余 4 篇

云盘文件选择交互实现

本文建立在命令式状态模型与虚拟滚动之上:前者将输入归约为选择状态,后者只挂载可见窗口中的节点。文件列表支持网格(grid)和列表(list)两种视图,并需要处理框选、Shift 范围选择、Ctrl/Meta 单项切换和键盘导航。命中计算不能假设所有 item 都已挂载到 DOM…

1 分钟
云盘同步

MySQL 索引与慢查询:B+ 树如何减少扫描

系列目录 MySQL 索引与慢查询:B+ 树如何减少扫描(本篇) 文件列表越来越慢 云盘 Java 版上线后,文件列表接口随单用户文件数增长越来越慢。页面打开要等好几秒,监控里这条接口的 RT 明显高于其他接口。慢查询日志定位到一条 SQL…

1 分钟
后端中间件学习笔记
9 月 · 其余 3 篇

云盘服务端从nodejs 专项 java 相关复盘

说明 本文总结云盘服务端从 Node.js 转向 Java 的过程。我平时也使用 nodejs、go、python、C#、java 开发,本文只讨论当时的项目约束和工具链。 云盘 Web 前后端和服务端开发在…

1 分钟
服务端工程实践

spring aop 权限拦截

云盘服务端 Java 化后,权限校验通过 HTTP header 中的认证信息完成。请求 body 包含业务数据时,签名计算还需要读取 body。最初实现了一个 ,并在 中从 读取 body 后计算签名;但 Spring MVC 向 handler 参数注入 body…

1 分钟

dozer使用

云盘项目中需要在领域模型、业务模型和 JSON 表示之间转换数据,因此有大量 Java Bean 到 Java Bean…

1 分钟
6 月 · 其余 1 篇
5 月 · 其余 2 篇
4 月 · 其余 1 篇

使用 V8 与 JavaScript 交互:Node.js 的基本原理

全栈开发需要掌握的深度取决于具体工作。使用 Node.js 时,为了理解其运行方式,我阅读了部分源码并尝试直接使用 V8 执行 JavaScript。 当时网上资料大多集中于开发 addons,而且 V8 经历过一次较大的 API 升级,部分旧资料已经不适用。本文记录基于当时 V…

1 分钟
3 月 · 其余 4 篇

D3 扫盲(二):比例尺与 SVG 图形基础

选择集负责创建和更新图形元素;比例尺负责将数据值映射为像素、颜色等视觉属性。 比例尺的作用 拿到的数据和要画的像素、颜色不是一回事。QPS 从 0 到 5000,圆点半径想控制在 0 到 40 像素之间,直接把 QPS 数值当半径用肯定不行,500…

1 分钟

D3 扫盲(一):选择集与数据绑定

服务稳定性大盘需要将服务调用关系绘制为有向图,并按 QPS 为节点和调用线着色。现有图表库未能直接满足动态拓扑图的需求,因此使用 D3.js 实现。本文说明基础概念:选择集(selection)和数据绑定(data join)。 用的是 D3 v…

1 分钟
2 月 · 其余 1 篇

回溯算法:组合、N 皇后与数独

回溯算法(Backtracking)通过递归枚举选择;当前选择无法满足约束时,撤销最后一次状态修改并尝试其他选择。 最近练习 LeetCode 的组合求和(39)、组合(77)、N 皇后(51)和数独(3…

1 分钟