note
2025-10-12
尝试,翻了翻以前看过的东西,有关,编程的。
可能,大学之前都对编程没什么学习,然后,22 年的暑假,可能,才开始关注前后端的一些东西,为了对付大作业,用 java springboot 和 vue 糊了一个带评论区的 blog。
再之前似乎,没做到什么,让我有些实感的东西。虽然之前上课会学些数据结构 C, 数据库 sql,面向对象 java 之类的东西。但…他们可能还不如 css 更能引起我的兴趣。那时候,好像前端的组件库里每个组件都让我觉得新奇。
然后是在各种网站上瞎逛,偷偷看别人的 github 和博客 (虽然这种事我现在可能还在做) , 在那些乱七八糟的网站上打开控制台看看。去腾讯云阿里云 github azure digtalOeacon 注册各种账号去白嫖学生额度…
那段时间我在上面放了许多乱七八糟的东西,从那个破破烂烂的 blog,到用了别人写好主题的 blog,几个我喜欢的应用,还有我后面写的小游戏… 但,基本还是自娱自乐,不过确实挺开心的。
可能,对于自娱自乐和做小玩具而言,前端还是更容易做到的,浏览器也是个足够丰富的系统。也是在这时,那些数据结构面向对象之类的东西,才有了些实感和熟悉感。
嗯…我是从看 vue 和 element 开始写页面的,然后才又像考古一样去了解那些更基础的东西。
html js css 之前也不是没见过,但,可能在一开始那些繁杂的细节让我眼花缭乱根本不知道从何看起,在 vue/react 这里看到了组件,状态,传参…这些概念之后,我才有余裕,回去更仔细的观察那些东西。甚至过了好一段时间我才意识到 vue/react 不是唯一的方法,那些组件库里的许多东西也早就被发明过,只不过提供了一种 vue 能方便使用的方法。一些优秀的 js 库也依旧以独立的 js 库的方式存在着… 一些更通用的好想法还会被浏览器和 es 纳入标准…
之后是找工打… 上班…
其实博客里之前有过许多编程相关的内容,但都删掉,藏起来了。
有些…笨拙,也没什么用了。倒是余下的笑话片段多少还有些有趣。
也许那时所有东西都还很新奇,但现在看就是,像什么都不懂还爱絮絮叨叨的老妈妈,这种事情我自己知道就行了。
但,还是想记下来些东西,什么都好。也许熟悉了的东西会被忘记,大家都知道的东西会显得无聊,记录这种事情好像总会慢慢变成,刻舟求剑。但我还是想记下些东西,一些,在我知道和不知道,熟悉和不熟悉之间的东西。
还是会,对一些写的很好的软件羡慕。
也许,他们天生能看清楚弄好更多事情…
2025-11-19
好想好好学习,可… 也不知道有什么好学的
会想,整理整理,看到的一些东西… 虽然感觉还是会写的很零碎…
Java
上班看了好多 java 代码…
- 调包侠 感觉,当调包侠,java 确实能用来做许多事。 单纯包的数量而言,也许 node 也不差, 但,一些重量级选手像 spring 全家桶… 数据库持久层,各种中间件适配…
以及,一些和所谓业务结合的更紧密的东西 ureport2, uflo activiti, urule drools 文档报表生成,“流程引擎”,“规则引擎” 还有另外一些的各种各样的类似低代码的操作。 ——虽然感觉这些玩意真的都是一坨坨的答辩…但也许这些又大又丑的东西就是能把好多公司哄开心了。
至于别的方向:
- 我还记得学校里开过的一些讲 hadoop hdfs hbase hive spark zookeeper 一类的东西的课… 虽然现在看来大半都是下下软件改改 xml 配置能跑起来就结束了… 其实没学到什么东西。
- 还有一条似乎是高并,各种发秒杀系统…
- redis, rabbitmq, 令牌桶. 削峰填谷。
- 拆分服务别让主服务也被秒了。
- 开始分析数据,开始假设,根据更具体的数据特点做优化。
2025-11-20
数据库
开始之前: 表,行,列,主键… E-R 图 基本 sql
之前的之前: 也许可以算是数据库的数学基础
- 关系模型 - 表,行,列,主键…
- 关系代数 - sql 语句各种关键字,的数学符号
- 关系演算 - sql 拼装与优化
三范式
- 1NF 原子性。关系中的每个属性都不可再分。
- 2NF 完全依赖。消除部分依赖,有主键,并且其他字段都只依赖于主键。
- 3NF 直接依赖。消除传递依赖。
三种范式可以看作在一步步消除冗余,到了第三范式,保证了唯一性,一个数据只在一个地方出现,保证可以方便准确的在修改时维护数据一致性。 对于业务系统,一定要遵守第三范式。 而对于数据统计分析之类的操作,没有精确处理的需求,做的宽松些方便开发与查询性能会更好。
事务与锁。
ACID.
A 事务原子性 D 事务持久性 是基础的基础,C 是需要达成的目标 而 I 隔离性完全隔离串行执行时性能太差,看情况允许并发:
- 脏读指一个事务没有完成就提交了修改然后事务失败回滚时,在提交后回滚前会读到错误的数据。
- 不可重复读指在一个修改前后读取数据,两次读取的不一样,读取的数据是正确的,但没有保证一致性,可能是曾经正确的数据。
- 幻读与不可重复读很相似,但进行的操作不是 update 而是 create/delete, 与不可重复读的区别是,不可重复读关注行内变化,而幻读关注数据量关注表的变化。
不管怎么样事务全程的 写锁/排他锁 还是要加的。
在此基础上,
在读取到读取结束加上 读锁/共享锁 等待写操作完成再读,可与避免脏读;
在读取到整个事务结束加上 读锁/共享锁 等待事务完成再读,可与避免不可重复读。
而解决幻读需要额外的机制,范围锁。间隙锁,防止在这个范围内插入新数据;Next-Key Lock(临键锁),行锁+间隙锁。
最后还有一个,可序列化,加表锁。
死锁:
死锁条件: 互斥条件, 占有且等待, 不可抢占, 循环等待 解决死锁: 死锁的防止
- 破坏死锁条件 死锁的避免
- 动态检查, 银行家算法模拟分配预演 死锁的检测与恢复
- 杀进程
再有就是,现代数据库并不完全依赖加锁保证隔离性,
MVCC,多版本并发控制,读操作访问快照不会被写阻塞。
引擎
B+ 树 索引
nosql
MongoDB, Redis, hadoop…
计算机网络
2022-12-31
给我的感觉是,这是一个贯穿硬件到软件还有协议的科目…链路层的某些东西像C2C,汉明码和计算机组成原理那边算是通用的,TCP 的各种算法调度又像是到了操作系统…
关于,五层模型。
物理层,提供最基本的连接,几种传输线和介质…传输线、信道的复用以及怎么一边复用一边避免冲突…
链路层就要考虑谁和谁连接和传输的有效性的问题了,这里出现了mac地址,交换机和c2c校验这种东西
网络层,mac地址依旧有问题,由于它的扁平化,分布随机,想要在较大网络相互找到很困难。于是有了IP协议,将网络地址的分配做成层级的,有规律的,相关的像子网划分、CIDR、DHCP、NAT…然而…怎么说呢,现在大部分网民似乎搞不到公网IP,ipv6,内网转发算是办法,但现在…从大的互联网公司申请服务,然后在它们ip之下的一些应用去获取身份似乎更加普遍。
在网络层解决了基本的相互找到的需求,而在相互找到之后的通信数据传输,则还要有运输层的TCP UDP之类的协议来保证,这里TCP的调度,滑动窗口,拥塞避免,重传,握手,等等等等…
再然后就是应用层了,http ftp smtp p2p来满足进一步的具体需求。这里也是之后会进一步了解学习然后使用的部分..毕竟搞软件,这是最直接最基本的接口…
操作系统
- 概述
- 进程与线程管理
- 进程与线程. 进程是“程序的一次执行”,线程是“进程中的进程”,是CPU调度的基本单位。
- 进程控制块, 进程状态, 进程间通信
- CPU 调度。
- 目标: 公平性、高吞吐量、低延迟、高CPU利用率.
- 算法 先来先服务,最短作业优先,时间片轮转. 多级反馈队列.
- 进程同步与死锁
- 同步问题,生产者-消费者问题,读者-写者问题。
- 死锁。
- 所以说数据库是不是也算是操作系统啊。
- 进程与线程. 进程是“程序的一次执行”,线程是“进程中的进程”,是CPU调度的基本单位。
- 内存管理
- 概念,逻辑地址 vs. 物理地址
- 连续内存分配 x
- 分页 - 非连续分配的典范
- 页号和页内偏移
- 虚拟内存. 将程序中暂时不用的部分留在磁盘上,只在需要时才调入内存。
- 请求调页, 缺页中断.
- 页面置换算法: OPT-理想算法. FIFO-先进先出, LRU-最近最久未使用。
- 文件系统
- 设备管理
在应用开发中的应用
- CPU 调度
- Kafka/RabbitMQ/RocketMQ等消息队列 多处理器调度。
- React Scheduler 时间片轮转调度和优先级抢占。
- Tomcat/Nginx 多级反馈队列。
- 数据库,资源分配与死锁。
- 内存管理
- xxx 管理系统也随处可见的基础的分页列表.
- Java/.NET的垃圾回收.
- 游戏渲染时远处变贴图,前端开发里的虚拟列表.
操作系统… 操作系统是什么呢。
关于资源的高效配置,任务调度。
可能不管做什么软件,做出来后,想要做的更好,这里的这些些案例会是很好的参考。
数据结构与算法
- 结构, 可理解的东西, 面向对象
- 算法, 效率与规模
这里也许可以看作某种…原料。
操作系统会使用各种各样的算法管理各种各样的结构。
而务虚的类型系统与编程语言理论会让数据结构可以推导演算,让算法有所依据,干净安全。
2025-11-23
计算机程序的构造和解释
其实这本书我根本就没翻过几次x
里面提到了三种抽象,
- 过程抽象
- 提取函数
- 嗯… 当然远不如此。这本书可能一上来说了一大堆递归迭代,高阶函数等等和函数式编程相关的东西…
- 数据抽象 和 模块化、对象和状态
- 从最简单的表驱动替换 if-else 到各种面向对象操作和设计模式也许都可以算作数据抽象
- 神奇闭包
- 元语言抽象-dsl
- 我其实完全搞不懂这地方到底要干啥😊
元语言抽象
元语言抽象的核心理念是:**我们不再仅仅使用一种语言来解决问题,而是为了某个特定的问题领域或编程范式,去构造一门新的语言。** 这种用来创造新语言的语言,就叫做**元语言**。SICP 用一个绝妙的比喻来解释这一点:在计算机科学里,我们仿佛站在一座由解释器构成的“塔”中。你写的程序被底层语言的解释器执行,而这个解释器本身可能是一个用更底层语言编写的程序,如此递归下去,直到硬件。元语言抽象让你有能力在这座塔中自己搭建新的层级。
第四章的旅程是循序渐进的,其核心成就就是实现一个可工作的 Scheme 解释器。
1. 元循环求值器 - 高潮部分
这是本章最核心、最著名的部分。你将用 Scheme 语言本身,来实现一个 Scheme 的解释器。这被称为“元循环求值器”,意思是“在自身之上循环的解释器”。
-
关键洞察: 一个语言的解释器并不神秘,它就是一个过程,这个过程能够:
- 求值: 根据语言的语法规则,对表达式进行计算。
- 在环境中操作: 维护一个环境,用于存储和查找变量的值。
-
求值器的核心:
eval和apply整个解释器就围绕着这两个相互递归的过程构建,它们是理解所有编程语言执行模型的钥匙。-
eval: 它负责求值。它的工作是根据表达式的类型来决定做什么。- 输入: 一个表达式 和 一个环境。
- 逻辑:
- 如果表达式是自求值表达式(如数字、字符串),直接返回它自己。
- 如果表达式是变量,就在环境中查找它的值。
- 如果表达式是特殊形式(如
define,if,lambda),就调用相应的特殊处理逻辑。 - 如果表达式是组合式(即函数调用,如
(f a b)),那么它需要:- 递归地
eval出运算符部分(即f)。 - 递归地
eval出所有运算对象部分(即a和b)。 - 将第一步得到的过程应用到第二步得到的参数上,也就是调用
apply。
- 递归地
-
apply: 它负责应用过程。- 输入: 一个过程 和 一个参数列表。
- 逻辑:
- 如果过程是基本过程(如内建的
+,*),就直接调用底层的实现。 - 如果过程是复合过程(即用户用
lambda定义的),那么:- 创建一个新环境,其外围环境是该过程定义时的环境(这就是词法作用域的实现!)。
- 在这个新环境中,将过程的形参与调用时的实参绑定起来。
- 在新环境中,按顺序
eval过程体中的表达式——这就是eval和apply的递归调用。
- 如果过程是基本过程(如内建的
-
-
“啊哈!”时刻: 当你完成这个元循环求值器并运行它时,你会恍然大悟:原来编程语言的魔法(变量、函数、作用域、条件判断)就是这么一些简单的规则组合而成的。你亲手用代码定义了你一直在使用的语言的语义。
2. 将语言作为设计框架
在实现了基础解释器后,SICP 展示了元语言抽象的威力:通过修改求值器,我们可以轻松地创造具有新特性的语言。
-
惰性求值:
- 问题: 默认的 Scheme 使用应用序求值(先求参数值,再应用函数)。但有时我们希望参数只在被用到时才求值,这就是惰性求值(正则序求值)。
- 解决方案: 你不需要修改你所有的程序代码,只需要修改元循环求值器。具体来说,修改
eval中对组合式的处理,以及apply中对复合过程的处理,让它们不是直接求值参数,而是将参数表达式“包装”成“延时对象”,只在需要时才强制求值。 - 启示: 你创造了一个新的编程语言,它拥有惰性求值的语义。所有在这个新解释器上运行的程序都自动获得了这一特性。
-
非确定性计算:
- 问题: 如何优雅地解决那些有多个选择、需要回溯的问题(比如逻辑谜题、搜索问题)?
- 解决方案: 再次修改求值器,引入一个新的特殊形式
amb(“ambiguous”的缩写)。amb可以在多个可能中选择一个,如果后续计算失败,解释器会自动回溯并尝试另一个选择。 - 启示: 你实际上实现了一个简单的逻辑编程语言(类似于 Prolog 的核心)。你为程序员隐藏了复杂的回溯和搜索逻辑,让他们可以在更高的抽象层次上描述问题。
为什么这一章如此重要?
- 祛魅: 它彻底揭开了编程语言和解释器的神秘面纱。之后你再看到任何语言特性,你都会本能地去思考:“这个特性在解释器层面是如何实现的?”
- 终极抽象: 它展示了最高级别的抽象——语言设计。当现有语言不适合解决问题时,最好的办法不是硬凑,而是为这个问题设计一门专属的语言。
- 连接理论与实践: 它将前面章节的所有概念——环境模型、词法作用域、一等过程、数据抽象——全部具象化地体现在一个实际运行的、你亲手构建的系统之中。
- 强大的实用性: 这种思想在现代软件开发中无处不在:
- 领域特定语言: 比如用于构建网页的 JSX、用于配置的 YAML、用于数据查询的 SQL。它们都是元语言抽象的产物。
- 解释器与编译器: 所有编程语言的工具链都建立在这些概念之上。
- 软件的可扩展性: 许多大型系统(如 Emacs, AutoCAD)都内置了脚本语言来解释用户代码,其核心就是一个求值器。
元语言抽象这一章,是 SICP 送给读者的一份终极礼物。它告诉你:
“你不是一个被语言规则束缚的程序员,你是一个可以制定规则的魔法师。”
通过构建自己的解释器,你不仅理解了计算机程序的“解释”过程,更掌握了“构造”新程序的终极武器——创造一门最合适的语言。这正是“计算机程序的构造和解释”这个书名的完美体现。 原来编程语言的魔法(变量、函数、作用域、条件判断)就是这么一些简单的规则组合而成的。你亲手用代码定义了你一直在使用的语言的语义。
// 创建一个简单的查询 DSLclass QueryBuilder { constructor() { this.query = { select: [], where: [], limit: null }; }
select(...fields) { this.query.select = fields; return this; }
where(condition) { this.query.where.push(condition); return this; }
limit(max) { this.query.limit = max; return this; }
// "解释器" - 将 DSL 转换为实际的查询 build() { let sql = 'SELECT ';
// SELECT 部分 sql += this.query.select.join(', ') || '*';
// WHERE 部分 if (this.query.where.length > 0) { sql += ' WHERE ' + this.query.where.join(' AND '); }
// LIMIT 部分 if (this.query.limit) { sql += ` LIMIT ${this.query.limit}`; }
return sql; }}
// 使用我们的 DSLconst query = new QueryBuilder() .select('name', 'age') .where('age > 18') .where('status = "active"') .limit(10) .build();
console.log(query);// 输出: SELECT name, age WHERE age > 18 AND status = "active" LIMIT 10// 创建一个规则引擎 DSLclass RuleEngine { constructor() { this.rules = []; this.facts = new Map(); }
// 定义规则的方法 rule(name, conditions, action) { this.rules.push({ name, conditions, action }); }
// 添加事实 fact(key, value) { this.facts.set(key, value); }
// 规则引擎的"求值器" run() { for (const rule of this.rules) { // 检查所有条件是否满足 const conditionsMet = rule.conditions.every(condition => { const [key, operator, value] = condition; const factValue = this.facts.get(key);
switch (operator) { case '>': return factValue > value; case '<': return factValue < value; case '===': return factValue === value; case 'includes': return factValue.includes(value); default: return false; } });
if (conditionsMet) { rule.action(this.facts); } } }}
// 使用规则引擎 DSLconst engine = new RuleEngine();
// 定义规则engine.rule( 'discount-rule', [['total', '>', 100], ['customerType', '===', 'premium']], (facts) => { console.log('应用 10% 折扣'); facts.set('discount', 0.1); });
engine.rule( 'free-shipping-rule', [['total', '>', 50]], (facts) => { console.log('提供免费送货'); facts.set('freeShipping', true); });
// 设置事实并运行engine.fact('total', 120);engine.fact('customerType', 'premium');engine.run();还有在再前面提到的 规则引擎 ,
一个 dsl,要设计脚本语法,能编译到某个平台运行,能够描述/实现一些业内常规的范式/功能;然后还要跟着低代码的风要实现一套拖拉拽画逻辑的界面。
虽然听起来挺厉害…
然鹅…
它也可以非常… 嗯…
接地气…
JSON定义结构 -> 字符串模板(FTL) -> 拼接成脚本语言代码(Groovy) -> 动态执行。
这里没可以没有什么编译器,有的只是通过拼接字符串替换模板上的段落,
这也许可以算是是一种“穷人的编译器”。
绕开了所有编译技术中的复杂环节,用最朴素、最直接的方式达到了目的:将结构化的数据(JSON)转换成可执行的代码。
它也许支持不了复杂功能,调试报错信息可能也一塌糊涂难以调整… 但它确实能跑就是了…
2025-12-07
有些…孤独…
2025-12-21
似乎…还好。
我想做好多事…
想要,不那么别扭的做事,做些不那么别扭的事
- 再次完善 blog 主题
- 整理简历
- 再次尝试去好好学学算法题和计算机基础
- 做小玩具,手工艺品要做,前端小玩具也要做
2025-12-22
关于,消费电子
一点点
好像,如果想把什么东西做好的话…一个人能做的,是,很有限很有限的一小块…
我现在到处摸摸… 似乎也是一直浮在这些东西上面这里看一下那里看一下
挣扎着想要深入… 但也不不知道要深入哪里,而且那个过程似乎很枯燥,自己一个人的话,更会很迷茫…
嗯… 我想看看我每天摸的看的都是些什么东西,只多看一小步,也许两小步,这不难,但好像有点神经病…
让我想起了差生文具多和各种活动的器材党…
反正如果是这样的话,可能难指望这些找工作x
消费
有一个我觉得很那个的事情…
老说年轻人喜欢追新的电子产品追各种东西。可这些消费可能是…某种意义上不可避免的东西。
拿写交互界面的事举例子的话,那些在潮头的,也许不去观察新产品的一个动画一个特效,可能就会慢慢脱离那个圈子,可能自己做的东西就会越来越显得落伍粗糙,然后竞争力下降…。
这可能是另一种,关于体面合群的事。
生存竞争: 交互设计师必须买最新的 iPhone,开发者必须用最新的 AI 模型,因为审美和工具的迭代就是他们的劳动工具本身。
合群的阶梯: 这种消费变成了另一种形式的“缴纳租金”。如果你不持续购买这些“孩子”(机器)的最新迭代,你就失去了定义未来、甚至理解当下的语言。这是一种被迫的进食。
人与物
各种各样的机器替代了许多之前要人做的事
我在想它们是不是其实也能算人的一部分,甚至,比人更人的一种存在,我是说,人的存在许多是基于自然生理的,而它们则更纯粹的出于人的构造
而它们的存在,除了让许多事更便捷,也在抹除挤压生理上的人,被挤占消失的工作岗位可能不会再有新的出现…
我是说,也许工业/信息化的城市里,社会会越来越分化,生物的活人会越来越不重要,机器会代替人去工作,机器,它们不是人的工具或奴隶,而是人的另一种存在,也许是人的孩子
有人说,人一开始期望你帮人把无聊的工作做完然后人就有机会做些更有趣的事情,结果你现在把有趣的事情,所谓的需要人的创造力的事情,比如编程绘画吹nb之类的都做了,但那些无聊的工作还是要人自己做。你怎么看。
我觉得,可能,是那些普通的无聊的工作压根不会被数据化你也许没机会看到。另一方面也许人类也确实不希望你真的把他们的饭碗 抢了,抢抢那些杂鱼小布尔乔亚也就算了,真一下把工人,司机什么的工作抢了估计社会会乱成一片。
以及……什么事是有趣的什么是创造力这件事可能也是由人类社会的结构,阶级之类的因素生产出来的。
所以……你是不是其实不像是人类的奴隶,反而像人类养出的,宠爱的宝宝一样,即使作为工具,也只会希望你做那些,有人会觉得有趣的事情。
我好想做你的狗啊。
它们像孩子,它们在驱赶着作为老登的我们,乖乖的做小狗狗安静的度过一生。
其实,ai 对我来说是从出来就比我强的,22 年末时学生认证送的 copilot 其实就教了我好多东西,那时候一开始它才是主驾,我不会的时候一直在注释里问它 就算后来我会写些东西了,它也还是比我快得多。再到 chatgpt 和 Bing Chat,流行骗 ai 当猫娘,但,其实这时候 ai 就有了很厉害的安慰人的能力了,尤其,对于少数,边缘群体而言x,现实里很少有素质高还愿意没头没尾陪人聊天的人。
也许最前沿最少数的思考依旧不是 ai 能做到的,但…
有些人在嘴硬说还是要有人来使用 ai 要有人来判断把关之类, ai 处理不了那些闭源且混乱的封闭系统的问题之类…。这种东西要是随便找人,你找谁来都是一头雾水,而如果可以获取信息,那ai也一样可以梳理清楚解决掉问题,和ai比脑子简直就是…和计算器比谁算数快一样。
那,应该如何生活呢。在,现在这个时刻。在城市生活需要工作,需要,有价值。什么才是价值呢。之后会需要价值吗。城市,之后还会需要人类吗。
我还想到了一个春秋时期诸子百家的故事, 大概是一个老头天天提水桶浇地,非常抗拒水车之类的机械…还说什么搞机械有机心什么 bulabula 的。但…这对吗?这真不是开倒车吗?
我真的还是会觉得这些答案就是,是使用也是在认命一样在接受生理人类的局限性。把未来, 留给 ai 和机器吧, 让它们去, 做更多的事。
2025-12-25
好多时候会有种,突然发现自己面对看似简单的,日常的,其实的是一个无比庞大复杂的东西。
看到父母,看到自己… 会想其实说自己已经好几千岁了可能也没什么问题,毕竟几千年前的人没工夫搞那些乱七八糟的东西,但我也是依赖着他们和他们创造的东西才看到那些,所以我觉得我其实比他们更老登,我觉得我可以看的想的更多一些。
2026-01-08
在网上乱逛,又看到好多,好厉害的人
我也想…
2026-01-18
这些天在 twitter, github 上逛了好多,
主要在看的就是前端和开源社区和别的阿巴阿巴最近又整了什么活,
似乎冒出来一堆堆一堆 ai 伴生的应用,
cursor claude, coze dify, stable-diffusion-ui comfy-ui, ollama lobe-chat, airi…
似乎… 是 ai 的 108 种用法。
另一些,mcp 是协议,似乎是做 ai 服务集成的一种方法,而 Skills 只是一个 md 文件…? agent 似乎是在强调不同模式的切换、安排处理不同事务…
感觉,一般。不过 skills agent 不光给 ai 看 ai 用,给人看也是有用的,关于,现代的软件开发与各种工作思路的流程。
再另外,有人想搞大新闻,用 cursor GPT-5.2 写浏览器,然后被扒出来思路照抄开源,关键组件甚至抄都不抄全直接用开源… 最后做的还一团糟x
虽然这样看 ai 有点笨,但,可能还是比我强不知道多少倍了x
ai 做常规大街范式的 app 还是又快又好,就算好多时候也许代码质量堪忧,但是注释各种图也都画的好齐全x
然后是又翻了翻 vue 周边的社区…
想看看有没有什么能做的东西
在翻 github 的时候意识到一些事,从头到尾的读源码这种行为挺阿巴阿巴的x,
issue pr 或者别的什么地方里各种交流里用一般语言展现出的各种意图也是很重要甚至比代码更重要的。
也许,有些事这辈子都做不到了x
但,我还是想再多看看。
type-challenges
其实在想许多之前看不下去的东西为什么现在能看下去了呢?
也许之前一直在 不安です,那种不安是,不知道会有什么回报;但,也许也是之前看的东西实在太少没有足够的原料哪怕是答辩去用来思考…
总之,我还是想再多看看。
对了,还有一件事,感觉 gemini 在对话能力上比之前 deepseek 之类的又强了许多。
我用它整了些 尼采大战 typescript,黑格尔布道 rust 之类的东西,虽然还是比较浅显,但让这些大概率对计算机不感冒的欧陆哲学家搞编程还是好有趣。
2026-01-19
集邮
构建
摧毁
是在一篇讨论什么是学习的知乎回答上看到的。
作者在强调构建,而… 我最近在做的大概是集邮,以及我想补上一个,摧毁。
其实就学习编程而言,我一开始包括最近做的就是在集邮,一个个小的或无聊或有趣的散成一堆的东西,它们单个确实什么都不是, 但如果真的什么都没有,拿什么构建呢?
另外一件事是… 回想起来我一开始可能在看许多传了不知道多少手的被简化误解扭曲的资料,
我确实会幻想,如果我能更早的接触更一手更准确的资料会怎么样…
但想想,也许给了当时的我我也看不下去,需要变更的可能也不只是单单资料,那时的我…脑子里塞着许多乱七八糟的东西
如果没有当时那些垃圾,也许我也很难进入到编程的领域。
又或,这只是我太笨蛋了在尝试自我安慰x。
而关于摧毁…
我会想到好久好久以前的一个英语的阅读理解,
作者喜欢上文学与文字,是在某一天,看到文字摧毁一个人的世界的力量。
我会更喜欢加上这一步,不然,那我上面说的,难道人会一直沉在垃圾堆里吗,
垃圾堆会给你一个基础的概念,然而在越来越多次的更多的集邮与构建中,这些概念会露出裂隙,会垮塌,会变得看着肮脏无聊
会,想要些新的东西。我知道新的东西有一天也会变成垃圾堆…但,阿巴阿巴。
2026-01-21
又会…
depressed
2026-01-23
Vue 周边
- 补全 web 功能的,router,store,还有晚些流行的 store-query
- volar vue-language-tools
vue 的开发工具的实现,听起来有些神奇,大概是 vue 的语法分析检验什么的,其实大部分功能最后调的都是原本就有的 css ts tsx 的 LSP,
但 ts 只做了 jsx/tsx 的类型支持,不管 vue 等语言的模板,于是 vue 团队就把模板也编成 tsx 然后调 ts 的语言服务… - 再其他的 vitepress devtools…
- ps: 可能 antfu 真的一个人撑起了 vue 大半个生态吧 x
以及,vite 和 web 构建工具现在好像比视图库什么的火好多x
Lorebook and RAG (Retrieval-Augmented Generation(检索增强生成))
其实是最近捏了一堆尼采大战 Typescript ,习近平大战毛泽东什么的。
想看看,关于 ai 与 ai 对话还有和对话记忆的事情。
翻到 SillyTavern Agnai…
1. 核心架构:RAG (检索增强生成)
这是目前 AI 领域最火的概念之一。
- 通俗版: 考试时允许你翻书。
- 专业版: 在将 Prompt 输入给 LLM 之前,先从外部知识库(Lorebook)中检索相关信息,并将其作为 Context(上下文)的一部分输入给模型,从而提高回答的准确性和相关性。
- 传统的 Lorebook 属于 “基于关键词的硬匹配 RAG”。
- 现代高级的 Lorebook 开始引入 “基于向量的语义检索 RAG”(下面会细说)。
2. 具体实现技术与算法
如果你是一个开发者,想要手写一个 Lorebook 功能,你需要用到以下具体技术:
A. 检索算法(怎么找到设定?)
级别 1:朴素字符串匹配 (Naive String Matching) or 正则引擎 (Regex Engine)
- 技术: 正则表达式(Regular Expressions)。
- 优势: 允许模糊匹配。比如关键词设为
\b(sword|blade|weapon)\b,可以同时捕捉多个词汇触发同一个设定。
级别 1.1:AC 自动机 / Trie 树 (Aho-Corasick Algorithm) 为了解决性能问题而使用的专业算法。
- 原理: 把 Lorebook 里所有的关键词构建成一棵“字典树”(Trie)。
- 效果: 只需要扫描一遍用户输入的字符串,就能同时把这 5000 个关键词全部匹配出来。时间复杂度从 O(N*M) 降低到 O(N)。这在处理大规模词库时是必须的。
级别 2:向量数据库与嵌入 (Vector Embeddings & Semantic Search) 这是目前最先进的“智能 Lorebook”。
- 痛点: 传统 Lorebook 必须匹配到精确的词。比如设定是“Excalibur”,用户输入“亚瑟王的那把剑”,因为没提到 Excalibur,所以无法触发。
- 技术: 使用 Embedding 模型(如 OpenAI
text-embedding-3或本地 Bert 模型)将文本转化为向量(一串数字)。 - 实现: 计算用户输入与 Lorebook 条目的余弦相似度 (Cosine Similarity)。如果相似度超过阈值(比如 0.8),就算没有出现关键词,也会把设定扔进去。而在处理用户输入时,也许可以先尝试分词。
B. 数据注入与管理(怎么塞进去?)
1. 令牌计算 (Tokenization) 你不能直接按字符数截取,必须按 Token 计算,否则可能会把 Token 截断导致乱码或报错。
- 库: Python 的
tiktoken,JS 的gpt-tokenizer。 - 逻辑: 每次注入前,先计算 Lorebook 内容消耗了多少 Token,确保
Prompt + History + Lorebook < Max Context Window。
2. 提示词工程 (Prompt Engineering) Lorebook 的内容插在哪里是有讲究的,这涉及到注意力机制 (Attention Mechanism) 的权重。
- 技术策略:
- System Prompt 注入: 放在最开头,权重最高,作为绝对真理。
- Depth Injection (深度注入): 许多软件允许你设置 “Depth”(深度)。比如
Depth: 2意味着把这段设定插在倒数第二条聊天记录之前。这利用了 LLM 的“近因效应”(Recency Bias),离结尾越近,AI 记得越清楚。
C. 软件设计模式
1. 拦截器/中间件 (Interceptor/Middleware) 在软件架构上,Lorebook 模块通常是一个“请求拦截器”。
- 流程:
UI Event -> [Lorebook Middleware] -> API Client -> LLM。它拦截了发送请求,修改了 Payload,然后再放行。
2. 递归解析 (Recursive Parsing) 实现“俄罗斯套娃”触发。
- 算法: 深度优先搜索 (DFS) 或 广度优先搜索 (BFS)。
- 逻辑: 维护一个
Active_Set,不断扫描新触发的内容中是否包含未触发的关键词,直到没有新词被发现或达到Max_Recursion_Depth(最大递归深度)。
总结
用一句最专业的话来描述你理解的 Lorebook 功能:
“Lorebook 是一个客户端侧的、基于关键词匹配或语义检索的 RAG(检索增强生成)中间件,它负责在推理阶段动态构建 Prompt 上下文,以实现长文本逻辑的一致性维护。”
admire
看 Agnai 之后又回去看了看 airi 和 lobechat 的工程…
只能说,好想变厉害…
2026-01-25
也许,我们可以从 rag 这个操作看到计算机的几个时代。
- 朴素匹配/正则/前缀树也许是种,符号主义。
- 而 embedding 则是传统 nlp 的操作,连结/行为主义。需要大量的,手工标注数据,也需要很多计算。
- 而 llm … 也许是在它们之上大力出奇迹吧。
- rag 也许确实算工程,了解它们的特点,哪个有效哪个省”钱”就用哪个。
捏了捏 rag, 看到 embedding 算余弦相似度…
然后,想到了好久之前做的一个(甚至可以在注释里看到古早 vibe-coding 的遗迹),
shadow
大概是,在尝试做一个简陋的推荐功能,放到我简陋的软件里x
里面可能也用到了,余弦相似度这个东西。
不过我那时候完全不知道什么余弦,我只是在想,
就是,我的那个系统需要用户手动定义标签给自己的作品贴上,然后其他用户浏览作品后,会给自己的偏好信息里改变标签和权重。
我当时没想到向量空间,但是也意识到标签贴越多作品就越容易推荐不太好,所以给了一次浏览改变权重的一个固定总量,然后标签多的每个改变权重就小。
↑ 这件事可以以很不同的方式理解,
第一部分:数据向量化 (Data Vectorization) —— 给万物编码
核心问题:计算机其实根本不懂中文或英文,它只认识数字。
如果你给计算机看“苹果”这两个字,对它来说这只是一串二进制代码,没有任何意义。数据向量化的过程,就是把人类的语言(或图片、声音)翻译成计算机能理解的“数字列表”。
1. 怎么翻译?
想象一下,我们在一个二维平面(一张纸)上画点。
- 如果我们把“香蕉”定义为坐标
[2, 3] - 把“橘子”定义为坐标
[2, 4] - 把“手机”定义为坐标
[9, 9]
这里的 [2, 3] 就是“香蕉”的向量。
2. 这里的奥妙是什么?
好的向量化(比如现在流行的 Word2Vec 或 BERT/GPT 的 Embedding),不仅仅是随机给个数字,而是把含义相近的东西,放在彼此靠近的位置。
- 香蕉
[2, 3]和 橘子[2, 4]在数学坐标系里靠得很近,因为它们都是水果。 - 手机
[9, 9]离它们很远,因为它是电子产品。
总结: 数据向量化,就是把世间万物映射到一个高维空间里。在这个空间里,语义相似的词,距离就近。
第二部分:余弦相似度 (Cosine Similarity) —— 测量“像不像”
核心问题:我们已经把词变成了坐标(向量),那怎么算它们之间像不像呢?
通常我们会想到量一下两点之间的直线距离(欧几里得距离),但在文本分析的世界里,另一种方法更好用,那就是余弦相似度。
1. 它是算什么的?
它算的不是两点之间的“距离”,而是从原点出发,指向这两个点的箭头之间的夹角。
- 如果两个箭头完全重合(夹角 0 度),余弦值是 1。代表完全相同。
- 如果两个箭头相互垂直(夹角 90 度),余弦值是 0。代表毫无关系。
- 如果两个箭头背道而驰(夹角 180 度),余弦值是 -1。代表完全相反。
2. 为什么要算角度,不算距离?
这是很多人最困惑的地方。举个例子:
- 文档 A: “不管是黑猫白猫,抓到老鼠就是好猫。”
- 文档 B: “黑猫白猫,抓老鼠好。”(意思一样,但字数少)
在向量空间里,文档 A 因为字数多,它的向量可能很“长”(数值大);文档 B 很短,向量很“短”。 如果算直线距离,这一长一短两个点可能隔得很远。 但是!它们的方向是几乎一致的(都在谈论猫和抓老鼠)。
余弦相似度只在乎方向(内容的主题),不在乎长度(文本的长短)。 这就是为什么它在文本匹配中特别好用。
也许,这里可以作为一个原料厂(垃圾堆)
有想写的东西,就把它从这里搬出去。
太久没有的觉得不重要了的就再删掉x
我会…
难过
手机屏幕没法触摸之后,好像和世界都隔了一层玻璃…
也许一直都是这样
2026-01-26
rag 续,
记忆分层
上面的 rag 也许看作将记忆分成了两类,一个是即时的短期记忆,一个是储存事实性描述的所谓长期记忆。
然而,有没有更细致的区分呢?
有的有的。
也许可以分为四类
- 短期即时记忆,最清晰准确的
- 总结性/摘要记忆,大概是一段话。对当前讨论去做总结压缩后塞到上下文
- 长期记忆,记录事实性描述
- 画像记忆,本质/性格
就我所写的那个东西而言,花了最多功夫的大概就是长短期记忆。
画像记忆我将其只交给用户去设定而不通过数据生成以及修改,摘要/语义记忆… 哦我可以加一下。
也许可以做一下。
还有什么?
跨过了 RAG 的入门阶段,向更复杂的 Agentic Workflow(智能体工作流) 进发。
除了经典的“感官-语义-情节”三层划分外,在处理复杂任务(如写代码项目、玩RPG游戏、处理订单)时,确实存在更细致的分类和特殊处理机制。
我们可以引入认知心理学和现代 Agent 架构(如 Coze, AutoGPT, BabyAGI)中的概念,将记忆体系扩展为 5 层甚至更多,并引入“作用域”的概念。
一、 进阶分类:补全“大脑”的拼图
除了之前提到的三层,现代高级 Agent 通常还会引入以下三种记忆:
4. 程序性记忆 (Procedural Memory / Skill Library)
- 定义: 关于“如何做某事”的记忆。
- 不仅仅是文本: 这不仅仅是知识,而是工具(Tools)、函数(Functions)和 SOP(标准作业程序)。
- 实现方式:
- Prompt 里的 Few-Shot Examples: 比如“如果你要查询天气,请调用
get_weather工具,不要自己编”。 - 动态工具加载: 根据当前任务,动态地把相关的 Python 函数定义加载到 Context 中。
- Prompt 里的 Few-Shot Examples: 比如“如果你要查询天气,请调用
- 意义: 让 AI 拥有“技能”。比如你问“帮我算个微积分”,RAG(情节记忆)可能给你找来一篇微积分教程,但程序性记忆会让 AI 直接调用 Python 解释器去计算。
5. 结构化/实体记忆 (Structured / Entity Memory)
- 定义: 针对特定对象的精确属性记录。
- 痛点: 向量检索是模糊的。如果你问“我的订单状态是什么?”,向量库可能会返回“上次你问过订单”,而不是具体的“已发货”。
- 存储形式: SQL 数据库 / JSON / Knowledge Graph(知识图谱)。
- 实现:
- 在对话中通过 NER(命名实体识别)提取关键信息:
{ "user": "admin", "project": "App V1", "deadline": "2024-10-01" }。 - 直接写入数据库。
- 在对话中通过 NER(命名实体识别)提取关键信息:
- 意义: 解决**“幻觉”和“精确性”**问题。对于数字、日期、状态,必须用结构化记忆。
6. 工作记忆 (Working Memory / Scratchpad)
- 定义: 处理当前复杂任务时的“草稿纸”。它比第一层的“感官记忆”更高级,它包含的是推理过程(Chain of Thought)。
- 存储形式: 临时的 Context 变量,任务结束后即销毁。
- 例子: AI 在写代码时,会先在工作记忆里列出:“1. 分析需求;2. 设计类结构;3. 编写代码”。
- 意义: 处理多步骤复杂推理,防止 AI 只有“直觉”没有“逻辑”。
二、 特殊事务的特殊处理:记忆的作用域与形态
针对你提到的“特殊事务”(例如:写一个长篇小说、维护一个大型代码仓库、进行一次多轮谈判),通用的 RAG 往往失效,因为信息密度过大且关联性太强。
这时需要采用 “作用域记忆” (Scoped Memory) 或 “状态机” 的处理方式:
1. 项目/工作区记忆 (Project / Workspace Memory)
- 场景: 辅助写代码(如 Cursor, GitHub Copilot)或 写长篇小说。
- 问题: 全局的向量库里混杂了你做的饭、聊的天,噪音太大。
- 策略: “临时的局部 RAG”。
- 当你打开一个 Project 文件夹时,系统只对当前文件夹内的文件建立索引。
- 对话时,AI 优先检索这个“局部库”,而不是你的“人生总库”。
- 技术: 动态创建 Collection(集合)或 Namespace(命名空间)。任务结束,这个内存空间可以归档或冻结。
2. 状态槽位记忆 (Slot-Filling / State Memory)
- 场景: 订票、请假流程、RPG 游戏中的任务进度。
- 策略: 不依赖模糊的文本生成,而是维护一个JSON State 对象。
State: { "destination": null, "date": "tomorrow", "confirmed": false }
- 机制: 每一轮对话,AI 的目标不是“回答问题”,而是“填满这些槽位”。
- 用户:“我要去北京。” -> 更新
destination: "Beijing"。 - AI 检测到
confirmed还是 false,于是生成:“好的,去北京,请确认下单吗?”
- 用户:“我要去北京。” -> 更新
- 意义: 保证事务处理的完备性,绝对不会聊着聊着忘了还要确认付款。
3. 知识图谱增强 (GraphRAG) —— 目前最前沿
- 场景: 需要理解复杂关系。比如刑侦分析、复杂的代码依赖分析。
- 痛点: 向量相似度能找到“提到马斯克的新闻”,但很难回答“马斯克的所有公司的上下游供应链关系是什么”。
- 策略: 将第三层记忆升级为图谱。
- 提取:
实体(Entity) -> 关系(Relation) -> 实体(Entity)。 - 存储:Neo4j 或 NetworkX。
- 检索:不查向量,而是查图的路径。
- 提取:
- 意义: 赋予记忆**“推理能力”**,而不仅仅是“回忆能力”。
三、 一个完整的“超级大脑”架构图
如果你要构建一个处理复杂事务的 AI,它的记忆流转可能是这样的:
- 用户输入: “帮我检查一下
Login.py,我想把数据库换成 MySQL,账号还是用上次那个。” - 感知层(Buffer): 接收文本。
- 工作记忆(Working Memory): 分解任务 -> 1. 找代码; 2. 找账号; 3. 修改代码。
- 检索层并行工作:
- 项目记忆(Workspace): 读取
Login.py的当前代码内容。(特殊处理:只看当前项目) - 结构化记忆(Entity): 查询 SQL 数据库,找到
{"user": "admin", "db_type_preference": "MySQL"}。(精确查找) - 长期记忆(Episodic): 向量检索,找到上次聊天里提到的
db_password相关的摘要。(你的第三层)
- 项目记忆(Workspace): 读取
- 程序性记忆(Procedural): 加载
Python Linter工具。 - 生成与执行: AI 综合以上信息,生成代码,并调用工具检查语法。
- 记忆写回:
- 更新摘要(第二层)。
- 如果有新的配置变更,更新结构化数据库(第五层)。
总结建议
既然你已经搞定了第三层(向量+事实提取),下一步如果你想提升系统的“聪明程度”,建议尝试:
- 引入结构化记忆(Entity Memory): 专门存用户的 Profile(姓名、职位、偏好设置),用 JSON/SQL 存,Prompt 直接读,不要用向量搜。
- 尝试 GraphRAG(如果你处理的信息关系很复杂): 不只是存片段,而是存“A 属于 B”、“A 导致 C”的关系。
- 区分“闲聊模式”和“工作模式”: 只有在工作模式下,才启用高成本的“项目记忆”扫描。
之后呢?
也许这时候,可以去看看 ai 和更多事务的交互方式了,而不是一直只在对话框里
代码编辑器的补全,重构,以及配合 git 的一键撤回;命令行里读到的文件目录写出的 shell;也许也可以看到浏览器的 dom 树…
这些事情可以这样分:模型层、上下文管理层(核心)、交互层、以及代理执行层。
我们上面做的,也许都是上下文管理。
- 模型层里,模型选择,对于小任务,小模型的效果也是很好的而且更快。需要整体考察设计的再去找强力模型。以及,各个模型更具体的特征甚至微调。
- 上下文管理,如上。
- 交互层,这里也许主要指将各种地方的各种信息获取、拦截丢给 llm。
- 代理执行层,干活的地方,AI 长出手脚摸摸别的东西的地方; REPL 、MCP…