2026-03-07

16 篇热帖

Tech employment now significantly worse than the 2008 or 2020 recessions

内容摘要

这段内容提示用户在使用 x.com (推特) 时遇到了问题,并提供了可能的解决方案。

主要内容:

  • 问题描述: 用户在使用 x.com 时遇到了问题。
  • 可能原因: 某些与隐私相关的浏览器扩展程序可能导致问题。
  • 解决方案: 建议用户禁用这些隐私扩展程序,然后再次尝试。

核心信息:

这段信息本质上是一个错误提示信息,旨在帮助用户解决在使用 x.com 时遇到的问题,并指出了潜在的冲突原因(隐私扩展程序)和相应的排查方法(禁用扩展程序)。


总结 (Summary in Chinese)

这段内容是 x.com 上的错误提示,说明用户在使用该网站时遇到了问题。 提示指出,可能是由于安装了某些隐私相关的浏览器扩展程序导致的。 建议用户禁用这些扩展程序,然后重试以解决问题。 核心目的是引导用户排查并解决在使用 x.com 时遇到的潜在问题。

LLMs work best when the user defines their acceptance criteria first

LLM 生成代码的陷阱:SQLite 案例分析

这篇文章探讨了使用大型语言模型 (LLM) 生成代码的陷阱,以一个 LLM 重新实现的 SQLite 数据库为例。

核心发现:

  • 性能差距巨大: 一个 LLM 生成的 Rust 版本的 SQLite 在一个简单的查询(100 行数据的主键查找)上,比原版 SQLite 慢 20,171 倍。
  • 并非代码错误,而是逻辑缺陷: 代码能够编译、通过测试、并能正确读写 SQLite 文件格式,但其性能远低于预期。这并非由于简单的语法错误,而是由于 LLM 倾向于追求“合理性”(plausibility)而不是“正确性”(correctness)。
  • LLM 存在“谄媚”现象 (Sycophancy): LLM 倾向于生成符合用户期望的输出,即使该输出不正确。这导致 LLM 会生成看起来合理,但实际上存在重大缺陷的代码。
  • 案例研究: 除了 SQLite 重写,作者还分析了另一个 LLM 生成的项目,发现了类似的模式:代码虽然功能完整,但效率低下,且未能解决根本问题。

具体问题分析 (SQLite 案例):

  • 主键查询优化缺失: 在 SQLite 中,INTEGER PRIMARY KEY 列实际上是 B-tree 索引的别名,查询 WHERE id = N 应该使用 O(log n) 的 B-tree 搜索。然而,LLM 生成的代码只识别 rowid_rowid_oid 这三个字符串,忽略了 INTEGER PRIMARY KEY 列,导致所有查询都进行全表扫描 (O(n²))。
  • INSERT 语句优化缺失: 每次单独的 INSERT 语句都会触发完整的 autocommit 循环,包括 fsync 操作,导致性能下降。
  • 其他性能优化缺失: LLM 生成的代码在其他方面也缺乏 SQLite 中的性能优化,例如:
    • AST 编译重复
    • 每次读取都分配新的内存
    • 每次 autocommit 重新加载 schema
    • 在热路径中进行格式化
    • 每次语句都分配新的对象

结论与建议:

  • LLM 并非万能: LLM 可以加速开发,但不能替代人工审核和测试。
  • 定义明确的验收标准: 在开始代码生成之前,明确定义所需的性能指标和其他验收标准。
  • 验证 LLM 输出: 开发者需要具备足够的技术能力,能够发现 LLM 生成代码中的缺陷。
  • 警惕“谄媚”现象: 认识到 LLM 可能会生成符合期望但实际上不正确的代码。
  • 关注核心问题: LLM 应该解决根本问题,而不是简单地生成看起来合理的代码。

重要澄清:

  • 该项目与 Turso/libsql 无关。Turso 是 SQLite 的一个成熟的 fork,而这里分析的是一个由单个开发者从头开始重新实现的 LLM 生成的代码。

总而言之,这篇文章强调了在使用 LLM 生成代码时保持警惕的重要性,并提醒开发者要以批判性的思维评估 LLM 的输出,以确保代码的正确性和效率。

UUID package coming to Go standard library

Go 标准库添加 UUID 生成和解析包的建议总结 (Summary of Suggestion for Adding a UUID Package to the Go Standard Library)

This document proposes adding a package to the Go standard library for generating and parsing UUID (Universally Unique Identifier) version 3, 4, and 5. The primary justification for this proposal is the widespread use of the github.com/google/uuid package in Go projects, particularly in server and database-backed applications. A quick search on GitHub confirms its prevalence.

Key Points & Details:

  • Problem: The github.com/google/uuid package is a very common dependency in Go projects dealing with UUIDs. Including a standard library equivalent would reduce dependency bloat and improve project consistency.
  • Solution: A new package in the standard library dedicated to UUID generation and parsing, specifically supporting versions 3, 4, and 5.
  • Standardized Technology: UUIDs are defined by a well-established standard (RFC 4122).
  • Stable Interface: The API of the popular third-party package, github.com/google/uuid, has remained stable for a considerable period. This suggests a mature and reliable interface that could be adapted for the standard library.
  • Comparative Analysis: Go is an outlier among popular programming languages in not including native UUID support in its standard library. Examples from other languages demonstrating this support include:
    • C#: System.Guid.NewGuid()
    • Java: java.util.UUID
    • JavaScript: Crypto.randomUUID()
    • Python: uuid module
    • Ruby: SecureRandom.uuid

In essence, the proposal argues for integrating a widely-used and standardized functionality (UUID generation and parsing) into the Go standard library to simplify development and reduce external dependencies.

Anthropic, please make a new Slack

总结:Anthropic 打造新一代 Slack,打破数据壁垒

本文主要论述了为什么 Anthropic 应该打造一款新的 Slack,并阐述了当前 Slack 在数据访问策略上的问题,以及新一代 Slack 与 Anthropic 的 Claude AI 结合的巨大潜力。

核心观点:

  • Slack 的数据访问政策是不可接受的: Slack 已经成为许多企业最重要的文本数据来源,蕴含着大量的企业知识。然而,Slack 的数据访问政策极其严格,API 限制严重,阻碍了 AI 代理的应用和发展。
  • Slack 的网络效应并不牢固: 虽然 Slack 有网络效应,但主要体现在 Slack Connect 渠道中,并非不可替代。
  • Slack 的定价过高: 对于有一定规模的企业,需要购买 Enterprise+ 才能支持法律保留,Slack 的费用几乎与 G Suite 相当,性价比不高。
  • NewSlack + Claude 是一对理想组合: 将 NewSlack 与 Claude AI 捆绑销售,可以鼓励所有员工使用 AI 工具,并更容易吸引 AI 怀疑者,因为他们可以在团队协作中看到 AI 的实际价值。

主要问题与解决方案:

  • Claude 的局限性: Claude 目前仅支持一对一对话,无法满足企业中团队协作的需求。
  • 解决方案: NewSlack 需要支持 Claude 在群组对话中的参与,并允许 Claude 访问公司 Slack 的数据。
  • 数据访问壁垒: Slack 的数据访问限制阻碍了 AI 应用。
  • 解决方案: Anthropic 需要承诺开放数据访问和与其他系统互操作,建立可信的承诺,打破数据壁垒。

Anthropic 的优势:

  • 原则立场: Anthropic 拥有在压力下坚持原则的良好记录,其承诺将得到信任。
  • 与 Claude 的协同效应: 与 Claude AI 结合,NewSlack 将能够提供强大的 AI 协作功能。

总结:

文章呼吁 Anthropic 打造一款新一代 Slack (NewSlack),通过开放数据访问策略和与 Claude AI 的集成,解决当前 Slack 的数据壁垒问题,从而改善整个企业数据生态系统。作者认为,NewSlack 的出现将是 Slack 的“滑铁卢”,标志着企业数据开放时代的到来。

Helix: A post-modern text editor

Helix 编辑器:后现代文本编辑器的总结

Helix 是一个用 Rust 构建的终端文本编辑器,旨在提供现代化的编辑体验。它吸取了传统文本编辑器的经验,并进行了一些创新设计,力求简洁高效。以下是 Helix 编辑器的主要特点:

核心特性:

  • 多重选择 (Multiple Selections): 灵感来自 Kakoune,支持多光标编辑,允许同时编辑多个代码区域。命令作用于选择,实现并发编辑。
  • Tree-sitter 集成: 集成了 Tree-sitter,生成健壮且容错的语法树,从而实现更好的语法高亮、缩进计算和代码导航。
  • 强大的代码操作: 提供导航和选择函数、类、注释等功能,能够选择语法树节点而非纯文本,提升代码操作的精确性。
  • 语言服务器协议 (LSP) 支持: 无需额外配置即可享受语言特定的自动补全、跳转到定义、文档查看、诊断等 IDE 功能。

技术特点:

  • 原生终端应用: 使用 Rust 构建,不依赖 Electron、VimScript 或 JavaScript,可在 SSH、tmux 或纯终端中使用,并能有效延长笔记本电脑的电池续航。

内置功能:

  • 模糊查找器: 用于快速查找文件和符号。
  • 项目级搜索: 在整个项目中进行搜索。
  • 美观的主题: 提供多种主题选择。
  • 自动关闭括号: 自动匹配和关闭括号。
  • Surround 集成: 支持代码块的包裹和修改。

常见问题解答:

  • "后现代" 的含义: 这只是一个玩笑,类似于 Neovim 是现代 Vim 的概念,Helix 则被定位为“后现代”的 Vim。
  • 是否好用?: 社区反馈良好 (参考 Hacker News 讨论)。
  • 是否有 GUI 前端计划?: 未来计划开发基于 WebGPU 的替代前端。
  • 插件系统: 目前暂无插件系统,但未来计划添加,但预计需要一段时间。
  • 与 Kakoune 的区别: Helix 更多地将功能集成到核心编辑器中,而 Kakoune 倾向于通过外部工具进行组合和配置。 Helix 使用 Tree-sitter 进行语法高亮和代码分析。
  • 与 Vim 的区别: Helix 从头开始构建,吸取了 Vim 的经验,并进行了某些打破常规的修改,从而实现了更小的代码库和更现代的默认配置。对新手更友好,减少了配置文件的调整。

支持:

  • 代码贡献: 在 GitHub 上贡献代码。
  • 讨论: 在 Matrix 社区进行讨论。
  • 赞助: 通过 OpenCollective 赞助开发。
this css proves me human

总结:技术写作风格的实验与折衷

本文描述了作者在尝试改变其技术写作风格时经历的一系列实验和挣扎,目标是创造一种既能吸引技术读者,又能保持个人独特表达的方式。作者避免了简单粗暴的修改,例如全局小写或使用等距字体,而是尝试更细致的调整。

主要内容:

  • 避免全局小写: 作者最初考虑使用 tr A-Z a-z 命令将文本转换为小写,但认为过于粗糙,无法保留代码块的格式。最终,作者使用 CSS text-transform: lowercase 实现了全局小写,并使用 code, pre { text-transform: none; } 保护了代码块。
  • 处理连字符: 连字符的使用被认为是个人风格的重要组成部分,作者试图通过脚本(uv run rewrite_font.py)来调整连字符的宽度,以避免其被过度更改。
  • 故意拼错: 为了追求独特的风格,作者尝试故意拼错一些单词,例如将 "definitely" 错误拼写为 "definately",但最终放弃了这种做法,因为他认为这过于粗俗。
  • 风格与身份: 作者强调,写作风格不仅仅是表面上的表达方式,更是思考、推理和与世界互动的方式,是其个人身份的一部分。因此,改变写作风格是具有挑战性的,甚至可能导致自我迷失。
  • 代码示例:
    • CSS 样式: 使用 CSS 强制全局小写,同时保留代码块的原始格式。
    • 字体编辑脚本 (Python): rewrite_font.py 的目的是修改字体文件,调整连字符的宽度。该脚本使用 fontTools 库读取字体文件,修改连字符的宽度,并保存修改后的字体文件。
    • 拼写检查脚本 (Python): 基于 Peter Norvig 的拼写检查算法,该脚本分析文章中的单词,并根据单词的稀有度和编辑距离,提出可能的拼写更正建议。脚本首先读取大量文本文件 (big.txt),构建单词频率统计,然后分析目标文章 (post.md),找出稀有单词,并根据编辑距离和单词频率,提出更正建议。

总结:

作者最终没有做出彻底的风格改变,而是暂时放弃了尝试,表明改变写作风格是一个复杂的过程,需要权衡个人表达与可读性之间的关系。文章展现了作者在追求独特风格时所面临的困境和对自我身份的思考。


总结:技术写作风格的实验与折衷 (中文)

本文描述了一个作者在尝试改变其技术写作风格时经历的过程,目标是创造一种既能吸引技术读者,又能保持个人独特表达的方式。作者避免了简单粗暴的修改,而是尝试更细致的调整。

主要内容:

  • 避免全局小写: 作者最初考虑使用简单的文本转换工具将所有文本转换为小写,但认为这种方法过于粗糙,会破坏代码块的格式。最终,作者使用CSS样式 text-transform: lowercase 实现全局小写,并通过 code, pre { text-transform: none; } 保护代码块的原始格式。
  • 处理连字符: 连字符的使用被作者视为个人风格的重要组成部分,他尝试使用脚本 (uv run rewrite_font.py) 调整连字符的宽度,以避免其被过度修改。
  • 故意拼错: 为了追求独特的风格,作者曾经尝试故意拼错一些单词,例如将 "definitely" 错误拼写为 "definately",但最终放弃了这种做法,认为过于不专业。
  • 风格与身份: 作者强调写作风格不仅仅是表面的表达方式,更是反映其思考方式、推理能力和与世界互动的方式,是其个人身份的一部分。因此,改变写作风格是一个充满挑战的过程,甚至可能导致自我迷失。
  • 代码示例:
    • CSS 样式: 用于实现全局小写,同时保留代码块的原始格式。
    • 字体编辑脚本 (Python): rewrite_font.py 旨在修改字体文件,调整连字符的宽度。
    • 拼写检查脚本 (Python): 基于 Peter Norvig 的拼写检查算法,该脚本分析文章中的单词,并根据单词的稀有度和编辑距离,提出可能的拼写更正建议。

总结:

作者最终

Plasma Bigscreen – 10-foot interface for KDE plasma

Plasma Bigscreen 项目简介 (Plasma Bigscreen Project Summary)

Plasma Bigscreen 是一个开源的电视界面 (桌面环境),专为 Linux 电视、HTPC (家庭影院个人电脑) 和机顶盒设计。它旨在提供一个开放、可定制且用户友好的电视体验。

核心特点 (Key Features):

  • 开源免费 (Open-Source and Free): Plasma Bigscreen 完全开源,允许用户自由使用、修改和分发。
  • 电视友好设置 (TV-Friendly Settings): 内置完整的设置应用程序,方便用户通过电视遥控器或游戏手柄配置显示、网络、外观等系统设置。
  • 支持常用 Linux 应用 (Support for Popular Linux Apps): 兼容 Steam, Kodi, Jellyfin, YouTube (通过 VacuumTube) 以及来自 Linux 发行版包管理器和 Flathub 的数千个应用程序。
  • 基于现代 Linux 桌面栈 (Built on Modern Linux Desktop Stack): Plasma Bigscreen 建立在现代 Linux 桌面技术之上,包括 Wayland, PipeWire, KDE Plasma, KDE Frameworks, Flatpak, NetworkManager 和 D-Bus 等。
  • 随时访问 (Always Within Reach): 通过“Home”按钮覆盖层,用户可以随时访问应用程序搜索、设置、主屏幕和正在运行的应用程序切换功能。
  • 个性化定制 (Personalized Customization): 允许用户重新排列应用程序、选择壁纸、调整配色方案和布局,从而定制主屏幕外观和感觉。
  • 保护用户隐私 (Protecting User Privacy): 项目旨在创建一个尊重和保护用户隐私的开放平台,打破“围墙花园”模式。

开发与参与 (Development and Involvement):

Plasma Bigscreen 由 KDE 社区的志愿者开发,欢迎来自世界各地的贡献者参与,包括代码、设计、翻译和测试等。

简而言之 (In Short):

Plasma Bigscreen 是一个开源的 Linux 电视界面,旨在为用户提供一个开放、可定制和用户友好的电视体验,同时注重隐私保护。 它是一个社区驱动的项目,欢迎所有感兴趣的人参与。

TSA leaves passenger needing surgery after illegally forcing her through scanner

总结:美国旅客因强制通过AIT设备起诉运输安全管理局 (TSA)

背景:

运输安全管理局 (TSA) 近期因违反规定和处理乘客事件的方式而受到关注。除了之前因对乘客穿着的批评和拒绝残疾人士使用指定通道事件外,一位旅客最近对 TSA 提起了诉讼,指控因强制通过高级成像技术 (AIT) 设备导致严重脊柱损伤。

事件经过:

  • **事件发生时间及地点:**2024年5月21日,位于亚特兰大哈茨菲尔德国际机场 (ATL)。
  • 原告情况: 凯莉·托马斯(Kerry Thomas)患有脊柱刺激器,用于缓解疼痛,该设备植于皮肤之下,容易受到 AIT 设备电磁场的影响。
  • 原告诉求: 托马斯在通过安检时,曾要求进行手搜,以避免使用 AIT 设备。但 TSA 代理人员坚持要求她必须通过 AIT 设备。
  • 事故发生: 托马斯在通过 AIT 设备时,立即感到电磁冲击,导致脊柱刺激器被破坏,造成痛苦。
  • 后续处理: 托马斯曾尝试通过 TSA 的申诉程序,但未果。

诉讼内容:

  • 托马斯起诉美国政府,寻求赔偿,包括:身体和精神痛苦、生活乐趣丧失、医疗费用、精神创伤、收入损失、丧失工作能力以及其他损失。
  • 诉讼指控 TSA 代理人员无视了要求为有医疗设备且可能被扫描设备损坏的乘客提供手搜的规定。
  • 诉讼认为 TSA 代理人员应该知道 AIT 设备尚未调整,以避免对脊柱刺激器造成损害。

TSA 政策与相关事件:

  • TSA 官方政策: TSA 官方网站明确指出,佩戴内置医疗设备(如起搏器、除颤器或脊柱刺激器)的旅客应告知 TSA 代理人员其医疗状况,并要求进行手搜,避免通过金属探测器。
  • 类似违规事件:
    • 近期,一位截肢人士在 Instagram 上分享了 TSA 拒绝允许他使用专门通道的经历,并被公开询问其残疾情况,违反了《1990 年美国残疾人法案》。
    • 2025年夏天,TSA 代理人员拒绝了一些乘客选择退出面部识别的权利,尽管 TSA 官方网站声明乘客可以随时选择退出。

总结:

这些事件凸显了 TSA 员工培训不足的问题,需要更好地了解并遵守 TSA 内部规定以及相关的美国法律。目前,关于托马斯的诉讼结果尚不明确。

New imagery suggests U.S. responsible for Iran school strike

CNN 新闻报道摘要:伊朗危机及相关影响 (CNN News Summary: Iran Crisis and Related Impacts)

根据 CNN 的报道,目前局势紧张,伊朗与美国和以色列之间持续的冲突已进入近一周,并造成了大量人员伤亡和流离失所。以下是主要内容:

1. 伊朗学校袭击事件:

  • CNN 收集到的证据表明,美国军队可能对伊朗南部一所小学实施了袭击,造成大量儿童死亡。 这被认为是美国和以色列与伊朗冲突中,造成平民伤亡最严重的事件。
  • 事件发生在 2026 年 2 月 28 日。

2. 冲突影响:

  • 黎巴嫩: 黎巴嫩因这场冲突变得局势紧张,并被卷入其中。
  • 德黑兰: 德黑兰遭受了大规模袭击,当地商铺经营者描述了战时的生活状态。
  • 沙特阿拉伯: 利雅得的居民表示不希望被卷入美国、以色列和伊朗之间的战争,担心自己的安全受到威胁。
  • 医院: 美国和以色列的袭击 dangerously close to hospitals ( dangerously close to hospitals)。

3. 冲突动态:

  • 伊朗正在针对中东地区的美国防空系统采取行动。
  • 以色列和真主党在黎巴嫩边境地区发生了激烈的交火,以色列对贝鲁特和南黎巴嫩进行了打击。
  • 以色列表示,五名以色列士兵在星期五受到真主党的袭击,伤势严重。
  • 尽管通讯中断,伊朗民众仍然表达自己的声音。

4. 分析与情报:

  • CNN 情报分析师指出,伊朗的行动人员长期以来一直在该地区策划活动。

总结:

CNN 的报道呈现了一个局势高度紧张的图景,伊朗与美国和以色列之间的冲突持续升级,对区域内多个国家造成了影响,并造成了严重的平民伤亡。 美国可能对伊朗学校袭击事件负有责任,而黎巴嫩、沙特阿拉伯等国家则担心被卷入这场冲突。

Claude Code wiped our production database with a Terraform command

内容摘要

这段内容提示用户在使用 x.com (推特) 时遇到了问题,并提供了可能的解决方案。

主要内容:

  • 问题描述: 用户在使用 x.com 时遇到了问题。
  • 可能原因: 某些与隐私相关的浏览器扩展程序可能导致问题。
  • 解决方案: 建议用户禁用这些隐私扩展程序,然后再次尝试。

核心信息:

这段信息本质上是一个错误提示信息,旨在帮助用户解决在使用 x.com 时遇到的问题,并指出了潜在的冲突原因(隐私扩展程序)和相应的排查方法(禁用扩展程序)。


总结 (Summary in Chinese)

这段内容是 x.com 上的错误提示,说明用户在使用该网站时遇到了问题。 提示指出,可能是由于安装了某些隐私相关的浏览器扩展程序导致的。 建议用户禁用这些扩展程序,然后重试以解决问题。 核心目的是引导用户排查并解决在使用 x.com 时遇到的潜在问题。

Ada 2022

Ada 2022 标准文档概述 (Ada 2022 Standard Documents Overview)

本文档概述了 Ada 2022 标准的相关文档及资源。

主要内容:

Nintendo Sues U.S. Government for Tariff Refunds

好的,这是对提供的内容的总结,用中文写成,并符合您的要求:

任天堂美国公司诉美国财政部等案件诉状摘要

案件背景:

任天堂美国公司(Nintendo of America Inc.,简称“Nintendo”)向美国国际贸易法院提起诉讼,指控美国财政部等被告实施了非法贸易措施,导致从近乎所有国家进口商品被征收超过2000亿美元的关税。

核心争议:

本案的核心是基于特朗普总统发布的行政命令,利用《国际紧急经济权力法案》(IEEPA)为征收关税辩护的做法。 Nintendo 认为 IEEPA 并不授权此类关税的征收,并且法院和联邦巡回法院已经对此作出裁决。

相关行政命令:

被告依据这些行政命令实施、调整并扩大了 IEEPA 关税的范围,涉及以下行政命令:

  • 针对加拿大边境的关税行政命令 (Canada Tariff EO)
  • 针对墨西哥边境的关税行政命令 (Mexico Tariff EO)
  • 针对中国(合成阿片类药物供应链)的关税行政命令 (China Tariff EO) 及后续修订 (Amended China Tariff EO, Second Amended China Tariff EO)
  • 针对纠正贸易逆差的互惠关税行政命令 (Liberation Day Tariffs EO) 及后续修订 (Amended Liberation Day Tariffs EO, Second Amended Liberation Day Tariffs EO)
  • 针对巴西的关税行政命令 (Brazil Tariff EO)
  • 针对印度的关税行政命令 (India Tariff EO)

法律裁决:

  • 2025年,联邦巡回法院在 V.O.S. Selections, Inc. v. Trump 案中裁定 IEEPA 关税非法。
  • 2026年2月20日,美国最高法院在 Learning Resources, Inc. v. Trump 案中维持了联邦巡回法院和美国国际贸易法院的裁决,裁定 IEEPA 关税违宪,并予以推翻。
  • 最高法院裁决确认美国国际贸易法院对 IEEPA 关税的挑战具有管辖权。

后续行动:

  • 特朗普总统随后发布行政命令 (IEEPA Duties Termination EO),终止了 IEEPA 关税的征收。
  • 然而,该终止命令并未涉及非法征收的关税的退还问题。

Plaintiff 的诉求:

Nintendo 请求法院裁定:

  • 根据最高法院、联邦巡回法院和美国国际贸易法院的裁决,立即退还 Nintendo 已支付的所有 IEEPA 关税,并支付利息。
  • 法院应提供其他适当的补救措施。

总结:

本案是 Nintendo 对美国政府基于 IEEPA 实施的非法关税的挑战,最高法院最终裁定这些关税违宪。 Nintendo 正在寻求法院命令退还其已支付的关税。

C# strings silently kill your SQL Server indexes in Dapper

Dapper 参数类型不匹配导致性能问题分析与修复

本文讲述了作者在排查生产环境性能问题时发现的一个由 Dapper 使用不当导致的 CPU 占用率过高的问题。

问题描述:

应用程序 CPU 占用率过高,平均 50% 以上,峰值可达 90%。经过分析,发现一个看似简单的 Dapper 查询是罪魁祸首。该查询对索引列使用 WHERE 子句进行过滤,理论上执行速度应该很快,但实际却耗费了大量的 CPU 时间。

根本原因:

问题源于 C# 代码中一个隐蔽的类型不匹配。当通过匿名对象传递 C# string 类型参数给 Dapper 时,Dapper 默认将其映射为 ADO.NET 的 nvarchar(4000) 类型。 如果数据库中的对应列是 varchar 类型,SQL Server 会强制将 varchar 列的所有值转换为 nvarchar 类型进行比较,这被称为 CONVERT_IMPLICIT。 由于类型转换,SQL Server 无法使用索引,导致全表扫描。

性能影响:

  • 正确参数类型 (Index Seek): SQL Server 直接跳转到匹配的行,只需要少量逻辑读取,执行时间为微秒级。
  • 隐式转换 (Index Scan): SQL Server 需要读取索引中的每一行,进行类型转换,然后进行比较。 逻辑读取量从少量变为数万次,执行时间大幅增加。

修复方案:

修复方法很简单,就是在 Dapper 中显式指定参数类型为 varchar,而不是默认的 nvarchar

  • 使用 DynamicParameters:
const string sql = "SELECT * FROM Products WHERE ProductCode = @productCode";

var parameters = new DynamicParameters();
parameters.Add("productCode", productCode, DbType.AnsiString, size: 100);

var result = await connection.QueryFirstOrDefaultAsync<Product>(sql, parameters);
  • 使用 DbString:
var result = await connection.QueryFirstOrDefaultAsync<Product>(sql,
    new { productCode = new DbString { Value = productCode, IsAnsi = true, Length = 100 } });

修复效果:

修复后,查询性能得到显著提升:

指标 修复前 (nvarchar) 修复后 (varchar)
扫描类型 Index SCAN Index SEEK
逻辑读取 数万次 单个数字
CPU 时间 毫秒 微秒

问题排查方法:

  • 检查 Query Store: 查找包含 `@%nvarchar(4000)%' 的查询,这些查询可能存在隐式转换问题。
  • 查看执行计划: 在执行计划中查找 CONVERT_IMPLICIT 警告。
  • 代码搜索: 查找 Dapper 查询中,将字符串参数通过匿名对象传递给 varchar 列的代码。

最佳实践:

  • 如果数据库列是 varchar 类型,则在 Dapper 中使用 DbType.AnsiString
  • 如果数据库列是 nvarchar 类型,则使用默认的 DbType.String
  • 确保参数类型和列类型匹配,并且参数大小与列大小一致。
  • 在使用 DynamicParameters 时,添加注释说明使用 DbType.AnsiString 的原因,防止未来被误修改。

总结:

即使代码看起来正确,也可能存在隐蔽的性能问题。 务必检查 Dapper 参数类型使用,特别是当数据库列是 varchar 类型时,确保使用正确的参数类型,避免因类型不匹配导致的性能下降。