260319笔记
260319学习总结笔记
算法相关
LLM相关
1.MCP单次调用的上下文占用大于skill,因为MCP的资源与工具是暴露的,凡事都要走LLM过一遍,而skill是原子性的,其资源与工具都是封闭的
2.MCP 不替代 Function Call,而是标准化了 Function Call 的目标端
3.如何写好一个工具?
| 原则 | 说明 | 反例 |
|---|---|---|
| 原子性 | 一个工具只做一件事 | process_data_and_send_email() 应拆分为两个工具 |
| 语义自描述 | 函数名和参数名即文档 | fn(a, b) → search_documents(query, limit) |
| 幂等性 | 多次调用结果一致 | 查询类工具天然幂等;写入类需去重机制 |
| 无副作用(查询类) | 读操作不修改状态 | get_user() 不应触发日志更新 |
4.提示词工程与上下文工程的比较
| 维度 | 提示词工程 (Prompt Engineering) | 上下文工程 (Context Engineering) |
|---|---|---|
| 关注焦点 | 单个指令的措辞与结构 | 多轮对话中的信息状态管理 |
| 时间尺度 | 单次交互(Turn-level) | 跨会话生命周期(Session-level) |
| 核心问题 | “如何问得更好” | “如何让AI记得更准、用得更巧” |
| 技术对象 | Prompt Template、Few-shot示例 | 记忆系统、RAG、上下文窗口策略 |
| 优化目标 | 单次输出质量 | 长期一致性、连贯性、个性化 |
5.
┌─────────────────────────────────────────┐
│ 上下文工程 (Context) │
│ ┌─────────────────────────────────┐ │
│ │ 提示词工程 (Prompt) │ │
│ │ “在当前背景下,如何提问” │ │
│ └─────────────────────────────────┘ │
│ 记忆管理 | RAG | 会话状态 | 个性化 │
└─────────────────────────────────────────┘
6.如何避免不同用户上下文互相污染
1.为每个用户/租户部署独立的LLM实例、数据库和向量存储
2.使用租户ID或用户ID作为上下文标识,确保每个用户/租户的上下文是独立的
3.在每个会话中,根据用户/租户ID或会话ID来管理上下文,确保每个会话的上下文是独立的
4.强制租户ID传递
每个请求必须携带不可伪造的租户标识:
使用JWT令牌嵌入 tenant_id 和 user_id
在中间件层注入租户上下文,而非依赖用户输入
所有工作流节点必须通过guard-rail验证租户权限
会话状态隔离
采用Burn-After-Use(用后即焚)机制:
会话数据存储在临时缓存(如Redis),设置TTL自动过期
对话结束后主动清除上下文窗口和检索缓存
避免使用全局变量存储用户特定信息
5.短期记忆(对话上下文)
使用scoped memory keys:remember(user_id + session_id + key)
禁止在系统提示词中硬编码其他用户的信息
实现上下文沙箱,确保多轮对话不越界
长期记忆(用户画像)
按 user_id 或 tenant_id 分片存储
Mem0等平台通过存储层隔离实现默认安全
7.agent工具调用需要明确区分错误类型,避免对永久性错误进行无效重试
8.入参校验
现在有诸如Pydantic这样的校验库,不需要反复造轮子
9.Agent 系统可观测平台,是专门为 AI Agent 提供全链路监控、调试、评估与治理的一体化平台,解决 Agent 从开发到生产的 “黑盒” 问题,让你清晰看到 Agent 做了什么、为什么这么做、性能与成本如何、是否合规。
Datadog:AI Agent Monitoring,统一 Metrics/Traces/Logs,支持 OpenTelemetry,企业级告警。
New Relic:无代码 AI Agent 平台,动态运行时,深度整合 OTel 与 MCP,面向 SRE 运维。
Elastic Observability:开源栈、AI Assistant、根因分析、日志 / 指标 / 链路统一分析。
阿里云 / 腾讯云 / 华为云:云原生可观测 + AI 监控,无缝对接云服务,适合云上部署。
Web相关
1.HTTP版本
| 版本 | 发布时间 | 现状 |
|---|---|---|
| HTTP/1.1 | 1997年 | 仍在广泛使用 |
| HTTP/2 | 2015年 (RFC 7540) | 目前主流,广泛部署 |
| HTTP/3 | 2022年 (RFC 9114) | 快速普及中,已有大量采用 |
2.
WebSocket 长连接:一次 HTTP 握手成功后,建立持久双向 TCP 连接,服务端和客户端可以随时互相发消息。
HTTP轮询:客户端每隔固定时间发一次请求,问服务端有没有新数据。
3.websocket 服务端示例
1 | package main |
4.示例说明
upgrader:核心升级器,负责将 HTTP 请求升级为 WebSocket 连接,CheckOrigin 用于跨域配置(生产环境需改为校验具体域名)。
心跳检测:通过定时发送 Ping 帧,确保长连接不被网关 / 防火墙断开(默认 30 秒一次)。
客户端管理:用 map 简单管理在线客户端(生产环境建议加互斥锁)。
消息循环:持续读取客户端消息,收到后立即回复(echo 逻辑),异常时清理客户端连接。
5.什么是 WebSocket 消息循环?
WebSocket 是全双工的通信协议(客户端和服务端可同时收发消息),但它的消息收发是事件驱动的 —— 不会主动 “推送” 消息,需要程序持续监听消息事件 / 读取消息流,这个 “持续监听 + 处理消息” 的逻辑就是消息循环。
简单来说:
对服务端:一直盯着每个客户端的连接,只要客户端发消息就立刻处理,直到连接断开。
对客户端:一直盯着和服务端的连接,只要服务端发消息就立刻接收,直到主动 / 被动断开。
在之前的 Go 代码中,服务端的消息循环体现在 handleWebSocket 函数的 for 循环里,这是最典型的服务端消息循环实现:
这歌不错:【依澄しあ】ルミネイト【kyiku】
kyuki真王朝了
令牌桶(Token Bucket)
令牌桶(Token Bucket) 是一种经典的流量控制 / 限流算法,核心是以固定速率生成令牌、请求必须消耗令牌才能通过,既限制长期平均速率,又允许短时间突发流量,是高并发系统中最常用的限流方案之一。
系统按固定速率往 “桶” 里放令牌,桶满则丢弃;请求到达时,必须从桶中取走对应数量的令牌才能被处理;无令牌则限流(拒绝 / 排队)。
设定两个核心参数
桶容量(Capacity, C):桶最多能存多少令牌(决定最大突发量)
令牌生成速率(Rate, R):每秒生成多少令牌(决定长期平均速率)
令牌填充:以速率 R 持续向桶中添加令牌;桶满(达到 C)后,新令牌被丢弃
数据库
乐观锁
乐观锁是一种轻量级并发控制机制,核心假设是并发冲突概率低,读取数据时不加锁,仅在提交更新时校验是否被其他事务修改
Mysql死锁
1. 资源互斥访问顺序不一致
这是人为操作最容易导致的死锁。当两个事务对数据库表的操作顺序相反时,就容易触发。
场景描述:
事务 A:先更新 表 1,再更新 表 2。
事务 B:先更新 表 2,再更新 表 1。
2. 外键关联导致的死锁
父表 Class(班级),子表 Student(学生,关联班级 ID)。
事务 A:删除 Class 中的一条记录(会检查外键,锁住 Student 中对应的行)。
事务 B:先删除 Student 中的对应记录(锁住 Student 行),再删除 Class 记录。
两者操作顺序相反,且互相依赖对方资源,导致死锁。
3. 索引失效导致的死锁
InnoDB(MySQL 默认存储引擎)是基于行锁(Row Lock)工作的,但如果 SQL 语句中的索引失效,行锁就会降级为表锁(Table Lock)。
场景描述:
你有一个 user 表,主键是 id,普通字段 phone 建了索引。
事务 A 执行 UPDATE user SET name=’A’ WHERE phone=138xxxx;(走了索引,锁住行)。
事务 B 执行 UPDATE user SET name=’B’ WHERE id=999;(正常走主键索引)。
如果你写错 SQL,比如 WHERE phone LIKE ‘%xx’ 或 使用了函数运算,导致索引失效,InnoDB 会退化为表级锁,锁住整张表。此时如果两个事务同时操作,就会互相阻塞导致死锁。
这歌好听[【kyiku】一成不变的内心令人畏惧/このままの心で怖かった](https://www.bilibili.com/video/BV1YZ421j7uF)
联合索引
联合索引(也叫复合索引)是数据库中基于多个列共同创建的索引,区别于只基于单个列的 “单列索引”。它的核心是:把多个列的值组合起来作为索引的 key,按照 “先第一列、再第二列、最后第三列……” 的优先级排序,形成一个有序的索引结构。
左前缀法则
联合索引(复合索引)的左前缀法则是数据库索引使用中最核心、最基础的规则之一,理解它能直接决定你的 SQL 查询是否能高效利用索引,避免全表扫描。
一、核心概念(通俗解释)
把联合索引想象成一本按 “省份 + 城市 + 区” 排序的电话簿:
电话簿的排序规则是:先按省份(第一列)排,省份相同再按城市(第二列)排,城市相同再按区(第三列)排。
左前缀法则就是:只有从最左侧的列开始查询,才能利用到这本电话簿的排序规则。比如:
查 “江苏省” 的所有记录 → 能直接定位(用了第一列);
查 “江苏省南京市” 的所有记录 → 能定位(用了第一 + 第二列);
查 “南京市” 的所有记录 → 无法直接定位(跳过了省份,电话簿里南京可能在江苏、广西等不同省份下,只能全本翻);
查 “江苏省南京市秦淮区” → 能定位(用了全部列)。
什么是 AT 模式?
AT 模式 = (Seata 里的一种)分布式事务方案。保证多个服务、多个数据库操作,要么一起成功,要么一起失败。
死信队列
死信队列:管消息异常,处理消费失败的消息,不堵系统、不丢消息。
Mysql超卖与加锁
会的,超卖问题在纯 MySQL 架构下不仅会出现,而且是高并发场景下的高频问题 —— 核心原因是多线程/多请求同时操作库存数据,导致数据一致性被破坏,和是否用分布式架构无关(AT 模式是解决分布式场景的超卖,单库也会有)。
一、先看为什么会出现(用最直观的例子)
假设商品库存 stock = 1,现在有 2 个用户同时下单:
| 时间 | 用户A请求 | 用户B请求 | 库存实际值 |
|---|---|---|---|
| T1 | 查询库存:1 | 查询库存:1 | 1 |
| T2 | 扣减库存:1-1=0 | 扣减库存:1-1=0 | 1 |
| T3 | 提交事务,库存更新为0 | 提交事务,库存更新为0 | 0 |
最终结果:库存变成 0,但两个用户都下单成功 → 超卖。
本质是:MySQL 默认的 READ COMMITTED/REPEATABLE READ 隔离级别,无法阻止“查询-扣减”这个非原子操作的并发问题。
二、纯 MySQL 下超卖的常见场景
- 高并发下单:秒杀、促销时,大量请求同时查库存、扣库存;
- 未加锁/锁粒度不对:比如只查不锁、用了行锁但条件不对(如查范围);
- 事务未控制:扣库存的 SQL 没放在事务里,或事务提交时机错误;
- 乐观锁使用不当:比如版本号没生效,或重试逻辑缺失。
三、纯 MySQL 怎么解决超卖(从易到难)
方案1:悲观锁(简单直接,适合低并发)
核心:查询库存时就加锁,不让其他请求修改,直到当前事务完成。
1 | -- 开启事务 |
⚠️ 缺点:高并发下锁等待会导致性能下降,甚至超时。
方案2:乐观锁(推荐,适合高并发)
核心:不提前锁数据,扣减时校验库存是否被修改,避免并发覆盖。
1 | -- 扣减库存时,加条件 stock > 0 且 版本号匹配(或直接用 stock) |
✅ 优点:无锁等待,性能高;缺点:需要业务层处理“扣减失败”的情况(比如返回“库存不足”)。
方案3:使用 MySQL 原子操作(极简)
核心:把“查库存+扣库存”合并成一条 SQL,利用 MySQL 单条 SQL 的原子性避免并发问题。
1 | -- 一条 SQL 完成校验+扣减,天然原子性,不会出现中间态 |
✅ 最优解(单库场景):最简单、性能最好,没有并发漏洞。
四、和 AT 模式的关系
- 纯 MySQL 方案:解决单库的超卖问题;
- Seata AT 模式:解决多库/多服务的超卖问题(比如订单库和库存库不在一个服务,AT 保证扣库存和创建订单要么都成,要么都回滚)。
总结
- 超卖是 MySQL 单库高并发下的必然问题,核心是“查询-扣减”非原子操作导致的并发覆盖;
- 纯 MySQL 解决超卖的核心思路:把“查+扣”做成原子操作(单条 SQL/加锁),避免并发修改;
- AT 模式是分布式场景的补充,解决跨服务的库存+订单一致性,而非单库超卖本身。
如果需要,我可以给你一段 Java + MySQL 的完整代码示例,演示如何用乐观锁/原子 SQL 彻底解决超卖问题。
个人感觉使用 MySQL 原子操作最舒服
其他
求职语境下的OC是何意味
OC = Offer Call,指录用意向电话。
OC ≠ 正式 Offer:OC 是口头意向,不具备法律约束力。
存在 “毁 OC” 风险:少数公司可能因 HC 冻结、业务调整等原因,在 OC 后不发正式 Offer。
稳妥做法:收到 OC 后,耐心等待正式邮件 Offer并仔细核对条款;签约前不轻易拒绝其他机会
PVZ2
芦笋战机削成废品了
前端
HTML5 语义化标签有哪些
HTML5 语义化标签的核心是用有意义的标签代替无语义的
标签 含义(语义) 典型使用场景