Skip to main content
· 8 min read

多模态模型的真正瓶颈不是 "看不清",而是 "指不准"。

  1. Reference Gap(指代断裂):模型看到了目标对象,但在推理链中无法稳定引用"到底是哪一个"。"左边那个""他旁边的"这类自然语言描述在视觉空间里不是精确地址——场景越复杂、相似物体越多,语言变量就越容易在几步推理后漂移到另一个实体上。

  2. 解法:把边界框和坐标点变成推理链的中间变量。 每写下一个框 = 在草稿纸上钉一颗钉子,后续推理围绕这些坐标展开,不再依赖模糊的自然语言指代。论文将框和点定义为"视觉原语(Visual Primitive)"——本质上就是把人类"用手指点着数"的动作形式化到了 token 序列里。

  3. 工程压缩比 7056×:2916 patch tokens → 3×3 空间压缩 → 324 → CSA 注意力缓存压缩 → 81。语言模型 DeepSeek V4 Flash(284B/13B MoE)+ 从头训练 DeepSeek ViT,视觉 token 限制在 81–384,不靠无限堆 token。

  4. 数据说话:~90 个视觉缓存条目跑出 77.2 分,Gemini 3 Flash 用 1100 个拿 76.5 分。视觉 token 不是越多越好,关键是模型有没有办法把"这个对象"稳定地绑定到图像坐标上。

· 6 min read

强化学习强在哪?一句话:它不需要正确答案,只需要对错信号。

监督学习从标注数据里找规律,强化学习从环境奖惩里学策略。两者的区别不是"强弱",而是解决问题的类型完全不同——SL 学映射,RL 学决策。

最容易被误解的一点:强化学习的目标不是每次选最优动作,而是最大化长期累积回报。只看眼前奖励的 RL 跟贪心算法没区别,价值函数才是它的灵魂。

Actor-Critic 架构让模型同时扮演"演员"和"评论家"两个角色——一个负责决策,一个负责评判,互相对抗、一起进化,AlphaGo 的底层思路也源于此。

最关键的应用:PPO 算法驱动了 RLHF,让大模型通过人类反馈学会"察言观色"。训练数据见顶的背景下,RL 是提升模型推理能力的核心引擎。

· 5 min read

MECE 是麦肯锡 顶级 结构化思维准则。

  1. 核心思想:相互独立,完全穷尽
  2. 适用场景:职场汇报、任务拆解、问题分析
  3. 效果:将复杂问题"不重复、不遗漏"地拆分
  4. 定位:提高逻辑思考能力的 初级入门方法

关键价值:拆解后能快速定位问题本质,避免思维混乱。

· 4 min read

JS 并发面试,三 道题筛掉九成候选人。

  1. await 在 for 循环里是 串行,10 个请求 10 秒,不是 1 秒
  2. forEach 里写 await 完全无效,外层根本不会等
  3. Promise.all 一个 reject 全盘崩,要容错必须用 Promise.allSettled

正解:并发用 Promise.all(arr.map(fn)),需要限流用 p-limit,要容错换 allSettled。

关键提醒:await 只暂停当前 async 函数,不会暂停外层调用者,更不会暂停 forEach 的迭代。

· 4 min read

JS 中 async/await 不是新功能,是 Promise 的语法糖——本质还是回调。

掌握 await 只需记住 三 件事:

  1. await 只能用在 async 函数里,async 函数永远返回 Promise
  2. await 会"暂停"当前函数,但不会阻塞主线程,其他代码照常跑
  3. 抛错用 try/catch,忘记 try/catch 会导致 UnhandledPromiseRejection

最佳实践:并发请求用 Promise.all,别串行 await,慢到怀疑人生。

· 4 min read

JavaScript 异步异常处理 三 种姿势,try/catch 嵌套地狱 最常见也最糟糕。

  1. try/catch 包 await:层层嵌套,业务和错误处理混成一坨
  2. .catch() 链式:返回 undefined 难以判断错误来源
  3. 元组解构 [err, data]:Go 风格,推荐

封装一个 to(promise) 工具函数,10 行代码消灭所有 try/catch,错误处理变成一行 if (err) return。

关键:业务错误用元组、致命错误仍要抛,别用工具类把所有异常都吞掉。

· 4 min read

JavaScript 中 await 的执行顺序,是面试高频题,也是写异步代码最容易踩的坑。

  1. await 后面的表达式 立即同步执行,只有等号左边的赋值才被推入微任务队列
  2. await 本质是 Promise.then 的语法糖,每个 await 至少消耗 一 个微任务 tick
  3. 循环里 await 串行执行,N 个请求耗时 N 倍,必须用 Promise.all 并发
  4. 同步代码 → 微任务(await/then)→ 宏任务(setTimeout)的顺序永远不变
  5. 判断输出顺序的口诀:先跑同步,再清微任务,最后才轮到宏任务
· 6 min read

ClaudeCode 客户端消息流的有序性,本质上是 单写者 + 显式序号 + 受控并发 换来的工程纪律,不是靠运行时去猜消息该怎么排。

要点拆解:

  1. 所有 stream 事件先汇入统一写入通道,由 序号 决定渲染顺序,不按到达时间。
  2. 工具并发被框死在 读可并行、写必串行 的边界内。
  3. UI 层只信任已经定序的快照,从不直接消费裸 SSE,否则就是乱序事故的源头。
  4. 回合作为原子单位,失败整体丢弃,不修补半截回合。

理解这套规则,比追着 SDK 文档更有用。

· 6 min read

OpenCode 客户端保证消息有序,靠的不是排序算法,而是 "按 partID 分桶 + 桶内就地更新" 的状态合并模型。

核心设计 三 点:

  1. 每个 part 由服务端分配全局唯一 id,创建顺序 = 渲染顺序
  2. 后续 part.updated 事件按 id 就地覆盖,不动 partOrder
  3. 断线重连先拉快照、再续 SSE,幂等更新天然无缝衔接

反面教材:早期每次更新都 setMessages([...messages]) 全量复制,消息一长 CPU 直接飙满。Streaming UI 的性能瓶颈从来不在网络,而在前端的更新粒度。

· 5 min read

closest() 是 DOM 元素方法,从自身开始沿父链向上查找第一个匹配 CSS 选择器的元素。

  1. 查找方向:自身 → 父 → 祖父 → <html>,找到即返回,否则返回 null
  2. 包含自身:当前元素就匹配时直接返回它,不是从父级才开始
  3. 接受任意选择器:标签、类、属性、伪类、复合选择器都支持
  4. 核心场景:事件委托、点击外部关闭、从子节点反查所属组件根
  5. 替代写法:等价于手写 while (el && !el.matches(sel)) el = el.parentElement

最佳实践:原生事件委托里只要涉及"从点击目标反查父级",优先用 closest(),别再手写 parentElement 循环。IE 不支持,老项目需 polyfill。

发文趋势
近 12 个月 · 共 177 篇
10111212345678139