2024-08-25

32 篇热帖

1. Arrest of Pavel Durov, Telegram CEO, charges of terrorism, fraud, child porn (decripto.org)

Telegram创始人兼首席执行官帕维尔·杜罗夫于周六晚间在巴黎勒布尔热机场被捕。他当时正从阿塞拜疆乘私人飞机抵达,与保镖及一名女子一同下机。逮捕依据是由法国国家司法警察局在初步调查后发出的搜查令,原因是杜罗夫涉嫌未与法国当局合作,并被列入联邦通缉名单。

杜罗夫被指控多项严重罪行,包括:

  • 恐怖主义
  • 毒品贩运
  • 共谋犯罪活动
  • 欺诈
  • 洗钱
  • 隐匿非法活动
  • 传播儿童性虐待内容

法国当局认为,Telegram在杜罗夫的领导下,因其加密信息服务,成为有组织犯罪的主要平台,据称助长了非法活动。调查人员已将杜罗夫拘留,他预计将很快接受法官审讯。这些指控可能导致最高20年的监禁。

此次逮捕对加密货币市场产生了直接影响。与Telegram相关的加密货币Toncoin在消息传出后大幅下跌,跌幅超过15%。

欧盟当局的主要指控集中于Telegram的加密信息服务,据称被用于助长有组织犯罪。一名调查员指出,“多年来,Telegram已成为有组织犯罪的头号平台”,强调了平台隐私功能与犯罪活动之间的关联。

杜罗夫是法国公民,将在法国受审并面对相关指控。此案可能产生重大法律影响,并影响未来对数字平台和加密货币的监管。

2. Telegram founder Pavel Durov arrested at French airport (www.theguardian.com)

Telegram创始人杜罗夫在法国被捕事件概述

核心事件

  • Telegram创始人兼CEO帕维尔·杜罗夫(Pavel Durov)于周六晚间在巴黎郊外的布尔歇机场被逮捕。
  • 逮捕基于法国签发的逮捕令,当时他正乘坐私人飞机从阿塞拜疆抵达该机场。
  • 预计于周日出庭受审。

人物背景

  • 39岁,俄裔,现居迪拜(Telegram总部所在地)。
  • 持有法国和阿联酋双重国籍。
  • 2014年因拒绝俄罗斯政府要求其关闭社交平台VK上的反对派社区而离开俄罗斯。
  • 据《福布斯》估计,其个人财富约为155亿美元。

公司与事件相关方

  • Telegram于2013年由杜罗夫及其兄弟创立,目前拥有约9亿活跃用户,提供加密通讯及“频道”功能。
  • Telegram官方未立即回应路透社的置评请求。
  • 俄罗斯驻法国大使馆表示正采取“即时措施”核实情况,但称杜罗夫团队尚未与其联系。
3. Study: Air purifier use at daycare centres cut kids' sick days by a third (2023) (yle.fi)
4. NASA announces Boeing Starliner crew will return on SpaceX Crew-9 (twitter.com)

NASA宣布,原定乘坐波音星际客机(Boeing Starliner)飞船返回地球的宇航员,将改乘SpaceX的Crew-9“龙”飞船返航。

这一决定表明,波音星际客机飞船在首次载人飞行测试中可能遇到了需要解决的技术问题。为确保宇航员安全,NASA调整了返回方案,决定依赖SpaceX已获认证的“龙”飞船来执行返程任务。

此决定也凸显了NASA在商业载人航天项目上采取“双供应商”策略的重要性。该策略旨在避免单一供应商出现问题时导致任务中断,确保国际空间站的人员轮换和运输任务能够持续进行。目前,SpaceX的Crew-9任务正按计划准备中。

6. JavaScript dates are about to be fixed (docs.timetime.in)

JavaScript 日期处理即将修复:Temporal API 详解

近期 ECMAScript 的众多变更中,Temporal 提案 是最值得关注的进展。该提案已相当成熟,可通过 FullCalendar 团队提供的 polyfill 提前使用。它从根本上解决了 JavaScript 日期处理的核心缺陷——即无法原生表示带时区的“人类可读日期”。

当前 Date 对象的根本问题

JavaScript 的 Date 对象内部以 数字(毫秒时间戳) 表示时间,基于 POSIX 时间(忽略闰秒),丢失了原始日期的语义和时区信息。这导致:

  • 歧义性:一个时间戳可对应多个不同时区的人类可读日期,无法逆向还原。
  • 时区混乱:即使使用 UTC 或 ISO 格式(带偏移量),仅凭时间戳和偏移量仍无法唯一确定原始时区(例如,多个时区可能拥有相同的偏移量)。
  • 实际困扰:例如,银行若将交易时间统一存为 UTC,用户在不同时区查看记录时会产生误解(如将咖啡消费时间误认为凌晨交易)。

Temporal API 的核心解决方案:ZonedDateTime

Temporal API 引入了 Temporal.ZonedDateTime 对象,专门用于表示一个精确的瞬间及其对应的完整时区信息。其关键优势包括:

1. 精确创建带时区的时间

直接指定年、月、日、时、分、秒和时区(如 "Europe/Madrid"),自动正确处理夏令时(DST)等复杂情况,确保时间点语义准确。

const zonedDateTime = Temporal.ZonedDateTime.from({
  year: 2024, month: 8, day: 16,
  hour: 12, minute: 30, second: 0,
  timeZone: "Europe/Madrid"
});

2. 可靠的日期比较

提供静态方法 compare,直接比较两个 ZonedDateTime 的真实时间顺序,而非钟面时间,避免 DST 等导致的判断错误。

Temporal.ZonedDateTime.compare(date1, date2); // 返回 -1, 0, 或 1

3. 丰富的内置属性

  • hoursInDay:返回实际跨过的小时数(考虑 DST 变化,可能为 23 或 25)。
  • daysInYearinLeapYear 等,方便进行时间计算。

4. 便捷的时区转换

使用 .withTimeZone() 方法可安全地转换到其他时区,得到的新实例保留了精确的瞬间信息。

zdt.withTimeZone("Africa/Accra").toString();

5. 智能的日期算术运算

.add().subtract() 方法支持日历算术持续时间算术两种模式:

  • 日历单位(如天数):保持钟面时间不变(例如“明天同一时间”),自动处理 DST。
  • 时间单位(如小时数):保持绝对时间长度不变(例如“24小时后”),忽略 DST 影响。
zonedDateTime.add({ days: 1 }); // 可能只有23个实际小时
zonedDateTime.add({ hours: 24 }); // 保证24个实际小时

6. 日期差异计算

.until() 方法可计算两个日期之间的精确差值,并返回一个 Temporal.Duration 对象,支持灵活的选项控制。

扩展支持

  • 字符串标准:提案扩展了 RFC 3339 格式,在 ISO 8601 字符串中直接附加 IANA 时区标识符,例如 "1996-12-19T16:39:57-08:00[America/Los_Angeles]",确保无歧义的序列化与反序列化。
  • 多日历系统:支持公历、中国农历、伊斯兰历等多种日历,其中 iso8601 为最常用的格里高利历标准适配。

总结

Temporal API 通过引入 ZonedDateTime 等对象,彻底解决了 JavaScript 长期存在的日期时间处理缺陷,使其能准确、无歧义地表示人类可读的带时区时间。它不仅提供了更符合直觉的 API,还妥善处理了 DST、时区转换等复杂场景,是现代 JavaScript 开发中处理时间问题的必备工具。后续文章将继续探索 InstantPlainDateDuration 等其他相关对象。

8. Anthropic Claude 3.5 can create icalendar files, so I did this (gregsramblings.com)

文章标题:Anthropic Claude 3.5 可创建 iCalendar 文件,以下是实际应用

文章内容: 作者的爵士钢琴老师发送了以 JPG 图片形式提供的秋冬课程表,其中包含作者的 13 节课程日期(用绿色标记勾选)。作者希望将这些日期添加到 Google 日历中,但不想手动输入,因此尝试使用 Claude 3.5 Sonnet 来协助完成。

首先,作者上传了 JPG 图片并提示:“列出以绿色标记勾选的日期”。Claude 准确识别并列出了全部 13 个日期(从 2024 年 9 月 13 日至 2025 年 5 月 23 日的每周五课程)。

接着,作者提示:“创建一个 iCalendar (.ics) 文件,在每个指定日期的太平洋时间下午 2 点设置‘Jazz Piano Lesson’(爵士钢琴课)的预约。” Claude 生成了完整的 ICS 文件内容。

该 ICS 文件具有以下特点:

  • 所有事件标题均为“Jazz Piano Lesson”。
  • 事件时间已根据太平洋时区正确转换为 UTC(协调世界时)。对于非夏令时期间的日期,太平洋时间下午 2 点对应 UTC 晚上 9 点 (21:00);对于夏令时期间的日期,则对应 UTC 晚上 10 点 (22:00)。文件已自动处理了时区变化。
  • 每个事件持续一小时。
  • 为每个事件提供了基于日期的唯一标识符(UID)。
  • 所有事件的 DTSTAMP(时间戳)均设置为对话发生日期(2024年8月24日)作为占位符。

作者随后将生成的 ICS 文件内容保存为 .ics 文件(例如 jazz_piano_lessons.ics),并通过 Google 日历的“导入/导出”功能成功导入了所有课程预约。

作者进行了对比测试,使用了 ChatGPT 处理相同任务。ChatGPT 能够识别图片中的日期,但表示无法直接创建 .ics 文件,而是提供了一段用于生成该文件的 Python 代码。当作者在之后返回并要求“直接显示 .ics 文件内容”时,ChatGPT 最终也提供了文件内容。

总结:作者通过实际案例展示了如何利用 Claude 3.5 Sonnet 的图像理解和文件生成能力,将包含日程的图片快速、准确地转换为可直接导入日历应用程序的 ICS 文件,大大简化了日程管理流程。

9. Facebook Banned Me for Life Because I Help People Use It Less (2021) (slate.com)
10. NASA Decides to Bring Starliner Spacecraft Back to Earth Without Crew (www.nasa.gov)

美国国家航空航天局(NASA)宣布,将安排波音公司的“星际客机”(Starliner)飞船在不搭载宇航员的情况下返回地球,原定搭乘该飞船的宇航员布奇·威尔莫尔和苏尼·威廉姆斯将继续留在国际空间站。

此次决定源于对安全的考量。在飞船于6月6日接近空间站时,工程师发现了氦气泄漏和反应控制系统推进器的问题。尽管后续进行了大量数据分析和测试,但相关问题的不确定性及缺乏专家共识未能达到NASA载人飞行的安全与性能要求。因此,NASA领导层决定让宇航员转移任务。

威尔莫尔和威廉姆斯将作为“远征71/72”任务组的成员,继续在空间站工作至2025年2月,并最终搭乘SpaceX的“载人龙”飞船与另外两名“载人龙-9”任务的宇航员一同返回地球。“星际客机”飞船预计于9月初进行自主离轨、再入和着陆。

NASA局长比尔·尼尔森表示,此决定体现了对核心价值——安全的坚守。波音“星际客机”此前已完成两次无人试飞,此次无人返回将持续收集飞行数据,为后续改进和认证提供关键信息。任务结束后,NASA将审查所有数据,以确定满足认证要求所需的额外措施。

为搭载威尔莫尔和威廉姆斯,“载人龙-9”任务的发射时间不早于9月24日,并需对飞船配置进行调整,包括座位、货物和个人装备。该任务将使用卡纳维拉尔角太空军基地40号发射复合体的新设施,以增加操作灵活性。

NASA的商业载人计划旨在与美国航空航天工业合作,实现安全、可靠、经济的往返空间站运输。国际空间站已连续有人驻留超过二十年,是开展长期太空飞行研究和技术验证的关键试验场,也是NASA阿尔忒弥斯月球探索计划和未来火星任务的重要基础。

11. Vim Racer (vim-racer.com)

Vim Racer 游戏概述

游戏基本玩法

Vim Racer 是一个基于速度的 Vim 编辑器游戏。玩家的目标是在编辑器中尽可能快速地导航到每个目标点(显示为"A")。成功到达一个目标后,下一个目标会随机出现。游戏允许使用所有 Vim 移动命令,因此高效导航的关键在于熟练运用这些命令。点击"重置"按钮后,浏览器焦点将切换到编辑器,玩家可以立即开始使用 Vim 操作。

设计风格与灵感

游戏设计灵感来源于80年代风格,采用霓虹时尚元素和像素艺术字体。官方推荐在游戏时播放80年代流行音乐以增强氛围。

功能设置

  • 相对行号:可通过编辑器左上角的齿轮图标开启。该功能特别适合使用相对前缀命令(如3j向下移动3行)的用户,在大文件中可能比输入绝对行号更高效。
  • 个人设置建议:开发者个人偏好使用相对行号,但光标所在行显示绝对行号,以便快速定位。

技术与运营细节

  • 服务器与数据库:当前使用AWS DynamoDB数据库,虽然免费层对小站点友好,但功能有限。所有新捐赠资金将用于升级到SQL数据库(年费约100美元),以提升性能与功能。
  • 捐赠管理:之前的捐赠被重新投资于产生持续收入,以支持网站运营。首位捐赠者为ThePrimeagen。
  • 排行榜规则
    • 不接受低于1秒的成绩记录,因为这可能违背了游戏手动导航的核心精神(虽然极快成绩展现了Vim技巧,但不属于常规导航操作)。
    • 未来可能增加不同游戏模式(如限制得分与无限制得分两类排行榜)。
    • 用户名每小时仅允许修改一次,以减少排行榜刷屏现象。

学习价值

Vim Racer 可作为学习Vim导航技巧的资源:

  • 每种竞赛类型都提供高效路径的提示。
  • 排行榜中每个成绩记录都包含使用者的按键序列,可供分析学习新的Vim操作命令。
12. Ruby in Jupyter Notebook (nbviewer.org)
  • 目的:在Jupyter Notebook中使用Ruby语言的IRuby.table方法,以表格形式显示数据。
  • 示例类型:展示了多种数据结构的输入,包括:
    • 简单数组(如[1,2,[],3])。
    • 哈希(如{a:1,b:2,c:3})。
    • 混合数组(如包含数字、数组和字符串的列表)。
    • 哈希中包含数组(如{a:[11,12,13,14],b:[21,22,23],c:[31,32,33,34]})。
    • 列表中的混合字典(如包含字典、字符串和其他数组的列表)。
  • 关键功能:IRuby.table能够处理不同数据结构,自动转换为表格显示,增强了Jupyter Notebook中Ruby代码的数据可视化能力。
  • 结构:通过多个代码调用示例,演示了方法的灵活性和适用性,但示例中未处理不规则数据(如非数组元素),可能返回错误或忽略。
14. Golang Interpreter Written in PHP (github.com)

项目概述

这是一个用PHP编写的Golang解释器,旨在在PHP环境中解析和执行Go代码。项目定位为玩具项目,不适用于生产环境,主要用于学习或实验目的。

示例与使用

示例展示了如何通过PHP代码运行Go程序:

  • 使用Interpreter::create()方法传入Go代码字符串。
  • 调用run()方法执行代码。
  • 示例Go代码包括结构体定义(如person)、函数(如newPerson)和main函数,演示了基本语法支持。
  • 运行示例需进入examples/{name}目录并执行php main.php命令。

项目状态

  • 当前为进行中(WIP)项目,功能有限。
  • 已实现功能可通过测试查看,测试驱动开发。
  • 开发指南:需安装依赖,运行测试,并使用make help获取更多命令。

与Go编译器的差异

  • 不支持真正的goroutines;go语句会顺序执行而非并发。
  • 作为解释器,专注于语法解析和执行,而非编译优化。
15. Neurotechnology numbers worth knowing (2022) (milan.cvitkovic.net)

神经技术关键数字与常数参考清单 (2022)

本清单专为神经技术领域工作者整理,旨在提供关键数字与常数参考,帮助研究人员和工程师快速验证想法并进行合理性检查(sanity checking)。内容涵盖从微观分子到宏观运营的多个维度,主要分为以下七个核心板块:

1. 基础物理与化学常数

涵盖微观粒子到宏观物体的尺寸、溶液浓度、人体与环境温度、压力、电磁波谱范围,以及人类意识反应与信息传输速率等基础物理量。

2. 大脑与组织结构

总结大脑的重量、体积构成(脑组织、血液、脑脊液)、血管分布与血流动力学、组织生物力学特性(如杨氏模量、声速),以及头皮、颅骨和脑灰/白质的电阻率。

3. 细胞与神经网络

概述大脑各区域(皮层、小脑等)的神经元与胶质细胞数量、突触密度、关键神经递质(多巴胺、血清素等)的分泌细胞规模、脑电波(Delta至Gamma)频段特征,以及神经信号的传导与刺激反应时间。

4. 细胞内分子机制

包括DNA与蛋白质大分子尺寸、细胞器与突触囊泡大小、细胞骨架运输速度、静息膜电位、动作电位时程、钠钾泵转运速率及神经递质跨突触间隙的扩散时间。

5. 遗传学参数

涉及人类单倍体基因组规模(32亿碱基对)、编码基因数量、线粒体基因组特征、DNA复制速度、RNA转录错误率及每代基因突变率。

6. 硬件与技术指标

列举脑深部电刺激(DBS)电极与光遗传学光纤尺寸、光学显微镜衍射极限,以及计算机缓存延迟、网络通信往返时间、USB/蓝牙带宽和移动芯片算力等工程参数。

7. 运营与商业成本

提供科研实验室租金、MRI扫描、动物模型(小鼠/非人灵长类)饲养、新药研发(平均10亿美元和10年周期)及侵入性脑外科手术的成本估算,并附带物质滥用相关的全球公共卫生与死亡率统计数据。

该清单通过量化神经科学的各个层面,为脑机接口、神经调控及神经生物学研究提供了极具实用价值的直觉参考与数据基准。

16. Ask HN: What are you working on (August 2024)?
17. Papersway – a scrollable window management for Sway/i3wm (spwhitton.name)

Papersway – Sway/i3wm 的可滚动窗口管理器

概述

Papersway 是为 Sway/i3wm 实现的类 PaperWM 可滚动平铺窗口管理器。它在保持 Sway/i3wm 稳定性和简洁性的同时,提供了不同的窗口管理模式。该项目稳定可靠,作者已日常使用数年。

核心功能与工作原理

  • 窗口排列: 每个工作区中的窗口水平排列成一行。
  • 可见窗口: 默认情况下,每行显示两个可见窗口。用户可以左右移动以查看行中的其他窗口。
  • 窗口动态:
    • 打开新窗口: 会将一个可见窗口推出屏幕外,以腾出空间。
    • 关闭窗口: 会将一个屏幕外的窗口拉入填充空缺。
    • 重新排序: 用户可以重新排列窗口顺序。
  • 工作区状态指示: 状态栏中会显示一个符号序列(例如 ‡ ‡ ‡ ‡),用于直观指示当前工作区拥有多少窗口(例如,符号数量表示总窗口数,当前可见的两个窗口位于序列中间)。

高级命令

  • 调整可见窗口的数量
  • 将窗口切换为宽窗口模式(该窗口在可见时始终占据所有可见列)。
  • 快速创建工作区:即在当前聚焦的工作区之后立即创建一个全新的空工作区。例如,从工作区 1 2 操作后将变为 1 2 3

与其他方案的比较

  • 主要缺点:与 PaperWM 相比,缺少动画效果。起初可能不习惯,但很快就能适应。

安装方法

可通过多种方式安装:

  1. CPAN (Perl 包管理器):
    cpanm App::papersway
    
    安装后需将 $HOME/perl5/bin 添加到 PATH 环境变量。
  2. 系统包管理器:
    • Debian 13+ 或 Ubuntu 24.10+:apt-get install papersway
    • NixOS:查找类似 perl540Packages.Apppapersway 的包(名称中的 NNN 代表 Perl 版本号前两位,如 v5.40 对应 540)。

使用与贡献

  • 使用说明:详细的使用方法和示例键绑定请查阅 papersway(1) 手册页。
  • 贡献:关于错误报告和提交补丁/拉取请求的信息,请参阅源代码中的 CONTRIBUTING 文件。

相关项目

  • i3wm, Sway, PaperWM, Material Shell, Spatial Shell, Niri, karousel

许可证

该项目基于 GNU 通用公共许可证 v3.0 或更高版本 发布。作者为 Sean Whitton,版权年份为 2019-2025。

18. If Your World Is Not Enchanted, You're Not Paying Attention (theconvivialsociety.substack.com)

文章摘要:注意力与世界的魔法

文章的核心论点是:魔法感(enchantment)本质上是我们注意力质量的体现。作者围绕“祛魅”(disenchantment)这一现代社会的经典概念展开,探讨注意力、感知与道德之间的关系。

背景:“祛魅”概念

  • 起源:“祛魅”概念由社会学家马克斯·韦伯普及,指现代世界不再被体验为充满魔法、神秘、灵性力量或内在意义的领域。
  • 当代争议:学者们对此提出挑战。有人认为“祛魅”从未真正发生(如杰森·约瑟夫森-斯托姆),有人则认为世界依然“充满魔力”,关键在于我们是否选择拥抱某种存在方式(如简·贝内特)。本文倾向于贝内特的观点。

核心主张:注意力塑造魔法感

作者提出,世界之所以显得“祛魅”,部分原因在于魔法感源于我们对世界所施加的一种特定品质的注意力,而现代人已习惯于缺乏这种必要的注意力。

  • 注意力即方法:贝内特认为,通过“磨砺对万物奇妙特性的感官感受力”等刻意策略,可以培养体验魔力的能力。这本质上是一种学习用心关注世界的方式。
  • 从平凡到浪漫:通过这种关注,平凡的日常观察可以变得浪漫、充满魔力。

深入:何种注意力能带来魔法感?

  1. 沉浸式的耐心:艺术史家詹妮弗·罗伯茨指出,“看见”不等于“理解”。真正的认知需要“时间和战略性的耐心”,这是一种“沉浸式的注意力”。
  2. 主动的被动性:哲学家西蒙娜·薇依将这种注意力视为一种“主动的被动”——不是去搜寻珍贵的礼物,而是等待它们显现。这要求我们向世界敞开,耐心等待它自我揭示。
  3. 关系性的认知:这种注意和认知不仅能揭示更多关于世界的信息,也能揭示更多关于我们自身的信息。它在我们与对象之间建立起更富有人情味的、而非临床或交易性的关系,并可能催生情感。

循环与出路

  • 恶性循环:我们习惯于缺乏耐心和关怀的注意力,从而将世界体验为一堆可供使用的惰性事物。这种体验又进一步强化了我们不再用心关注的倾向,形成自我实现的预言。
  • 打破循环:出路在于有意识地、甚至带着信念去重新审视世界。敢于冒险,准备相信世界可能依然充满魔力,像施法一样将注意力投向世界。这有可能唤醒沉睡的欲望,重新点燃惊奇感。

总而言之,文章呼吁对抗现代生活中常见的浅薄、功利性的关注方式,通过培养耐心、沉浸和关爱性的注意力,重新发现并栖居于一个充满魔力和意义的世界。

19. Show HN: Visualize database schemas with a single query (github.com)

ChartDB:开源数据库图表编辑器

ChartDB 是一个基于网页的数据库图表编辑器,通过单条“智能查询”即可快速可视化数据库模式。无需安装,无需数据库密码。

主要功能

  • 即时模式导入:运行单条查询即可将数据库模式以 JSON 格式提取,便于快速可视化,用于文档编写、团队讨论或理解数据结构。
  • AI 驱动的脚本导出:可使用 AI 功能生成目标数据库方言的 DDL 脚本,简化数据库迁移(如从 MySQL 到 PostgreSQL)。
  • 交互式编辑:提供直观编辑器,可对数据库图表进行微调和注释,以更好地可视化复杂结构。

项目状态

ChartDB 目前处于 公开测试阶段。支持多种数据库。

使用方法

  1. 访问 ChartDB.io 网站。
  2. 点击“Go to app”。
  3. 选择您使用的数据库。
  4. 在您的数据库中运行提供的“神奇查询”。
  5. 将查询得到的 JSON 结果复制并粘贴到 ChartDB 中。
  6. 开始查看和编辑图表。

部署与构建(本地或 Docker)

构建(基础版)

npm install
npm run build

构建(启用 AI 功能)

npm install
VITE_OPENAI_API_KEY=<你的OpenAI密钥> npm run build

运行 Docker 容器

docker run -e OPENAI_API_KEY=<你的OpenAI密钥> -p 8080:80 ghcr.io/chartdb/chartdb:latest

本地构建并运行

docker build -t chartdb .
docker run -e OPENAI_API_KEY=<你的OpenAI密钥> -p 8080:80 chartdb

使用自定义推理服务器

构建时指定端点和模型名称:

docker build \
  --build-arg VITE_OPENAI_API_ENDPOINT=<你的端点> \
  --build-arg VITE_LLM_MODEL_NAME=<你的模型名称> \
  -t chartdb .

运行时同样传入环境变量:

docker run \
  -e OPENAI_API_ENDPOINT=<你的端点> \
  -e LLM_MODEL_NAME=<你的模型名称> \
  -p 8080:80 chartdb

注意:AI 功能必须配置 OpenAI API 密钥自定义端点和模型名称 其中之一,不能混合使用。

启动后

在浏览器中打开 http://localhost:8080

隐私说明:ChartDB 使用 Fathom Analytics 进行隐私友好的统计。可通过添加环境变量 DISABLE_ANALYTICS=true 或构建参数 VITE_DISABLE_ANALYTICS=true 来禁用。

社区与支持

  • Discord:用于社区和开发团队实时交流。
  • GitHub Issues:用于报告错误和问题。
  • Twitter:获取最新动态。

贡献

欢迎社区贡献。请查阅《贡献指南》并遵守《贡献者行为准则》。

许可证

ChartDB 采用 GNU Affero General Public License v3.0 许可。

20. Ruby's official documentation just got a new look (docs.ruby-lang.org)

Ruby 官方文档新面貌

文档概览 Ruby 官方文档现已全新改版,为开发者提供清晰、现代化的参考资源。

主要内容

  • 入门指南:为新手提供学习起点。
  • 核心类与模块:涵盖语言基础,如字符串(String)、数组(Array)、哈希(Hash)、整数(Integer)、浮点数(Float)、可枚举模块(Enumerable)、文件(File)、输入输出(IO)、时间(Time)、正则表达式(Regexp)、范围(Range)、异常(Exception)和线程(Thread)等。
  • 语言参考:深入介绍语法和特性,包括Ruby语法、异常处理和隐式转换。
  • 标准库:列出了常用库,例如日期(Date)、JSON、ERB模板和HTTP客户端(Net::HTTP),并提供了完整的标准库文档链接。
  • 社区贡献:提供了参与社区的途径,包括贡献指南、文档编写指南、问题报告、构建与测试方法以及问题跟踪器。
  • 额外资源:包含Ruby主页、RubyGems和社区相关链接。
21. Rnote – Sketch and take handwritten notes (github.com)

Rnote 摘要

Rnote 是一款开源的基于矢量的绘图应用,专为草图绘制、手写笔记以及文档与图片标注设计。它主要面向学生、教师及绘图板用户,使用 Rust 和 GTK4 编写,提供跨平台支持。

主要功能

  • 自适应界面:专注于手写笔输入,支持压力感应,并可配置多种笔画样式。
  • 绘图工具:包括形状工具(可创建多种形状)和选择工具(可移动、旋转、调整及修改内容)。
  • 文档布局:支持多种页面扩展布局,如固定页面、连续垂直滚动及无限方向画布。
  • 自定义选项:可自定义背景颜色、图案、尺寸及页面格式。
  • 导入导出:支持导入 PDF、位图和 SVG;可将文档导出为 SVG、PDF 和 Xopp,页面或选区可导出为 SVG、PNG 和 JPEG。
  • 文件管理:采用原生 .rnote 文件格式(基于 gzipped JSON),支持多标签页处理多个文档,具备自动保存和打印功能。
  • 工作区集成:内置工作区浏览器,支持拖放和剪贴板操作。
  • CLI 工具:提供命令行界面用于自动化处理 .rnote 文件。

安装方式

  • Linux:通过 Flathub 安装 Flatpak。
  • MacOS:提供第三方打包的应用 bundle。
  • Windows:可从 GitHub 发布页下载安装程序,或使用 winget install flxzt.rnote 命令。
  • 降级指南:因文件格式不稳定,若需访问旧版本文档,可通过 Flatpak 命令降级至指定版本。

已知问题与注意事项

  • X11 支持受限:在 X11 环境下触控笔和触控输入可能不稳定,且上游支持将持续减弱。
  • 拖放权限问题:需在 Flatseal 中授权 Rnote 访问相关文件目录。
  • 手写笔按钮映射异常:部分设备的手写笔按钮可能映射至“橡皮擦”模式,需按特定步骤重新配置工具。
  • 悬停输入阻塞:悬停时可能误触手掌拒绝功能,需在系统平板设置中调整惯用手设置。

其他信息

  • 字体:内置多种字体,包括 Grape Nuts、OpenDyslexic、TT2020 和 Virgil。
  • 许可证:采用 GPL-3.0-or-later 许可。
  • 社区支持:可通过 GitHub Discussions 及 Matrix 聊天室(用户/开发者)进行交流。
  • 贡献指南:欢迎参与翻译及文档补充,具体指引见项目 CONTRIBUTING 文件。

文件格式说明

.rnote 文件为 gzipped JSON 格式,历史上在 v0.2.0、v0.3.0、v0.4.0 和 v0.5.0 版本中出现过不兼容变更。旧版文件可能需要降级应用才能正确打开。


Rnote 是免费开源软件,源代码可通过项目网站及 GitHub 获取。

22. How de-Googled is Lineage OS? (kevinboone.me)

LineageOS去谷歌化程度分析

本文作者分享了使用LineageOS替代手机原厂固件以移除谷歌服务的经历,并详细分析了LineageOS中可能残留的隐私数据泄露点。作者的核心目标是最大限度地减少谷歌的数据收集,同时接受因此可能带来的应用使用限制。

LineageOS与谷歌服务的分离现状

LineageOS基于Android开源项目(AOSP),移除了主要的谷歌Play服务,但与更注重隐私的ROM(如GrapheneOS)相比,它被认为仍与AOSP基础配置较为接近。作者选择LineageOS主要是因为其易于安装和使用。

主要的潜在数据泄露点及分析

  1. 强制门户测试(Captive Portal Test)

    • 机制:设备连接网络时会向服务器发送请求以检测是否需要登录验证。LineageOS默认使用谷歌服务器。
    • 泄露信息:设备的IP地址、有限的设备信息和连接时间。
    • 风险评估:作者认为风险相对较低,因信息有限且可能通过其他途径泄露。
    • 解决方案:可通过命令行修改captive_portal_http_urlcaptive_portal_https_url设置,将其指向其他公共服务器。
  2. DNS查询

    • 机制:将主机名转换为IP地址。谷歌运营公共DNS服务器(如8.8.8.8)。
    • 泄露信息:所访问网站的主机名。
    • 风险评估:虽然LineageOS现在可能优先使用网络提供商或运营商的DNS,但AOSP代码中仍存在对谷歌DNS的引用。加密DNS能防止第三方窥探,但无法保护用户免受DNS服务器端的数据收集。
    • 解决方案:可在网络设置中手动指定其他DNS服务器。
  3. 辅助GPS(A-GPS)

    • 机制:使用环境数据(如基站位置)来加速GPS卫星定位,数据通常由谷歌服务器处理。
    • 泄露信息:设备的IP地址和粗略位置。
    • 风险评估:在LineageOS新版本中默认禁用。启用则会连接谷歌服务器。
    • 解决方案:保持禁用状态,接受首次定位时间较长的缺点。
  4. 时间同步(NTP)

    • 机制:LineageOS目前使用公共NTP服务器池,而非谷歌的专属服务器。
    • 风险评估:作者认为泄露时间同步数据的风险极小。
  5. WebView组件

    • 机制:基于Chromium(谷歌Chrome的开源版本)的AOSP实现,用于在应用内渲染网页。
    • 泄露信息:已知Chromium会进行数据通信,例如下载“不安全网站”列表用于“安全浏览”功能。
    • 风险评估:作者认为这是最令人担忧的隐私问题,尽管当仅作为WebView组件使用时,其数据泄露可能不如作为完整浏览器时显著。LineageOS自带的Jelly浏览器本质上就是Chromium WebView的包装。
    • 解决方案:存在去谷歌化的WebView替代品(如Vanadium),但安装过程复杂。作者选择使用不基于谷歌代码的浏览器(如Firefox)以减少暴露。

作者的整体评估与态度

作者表示,通过不安装任何谷歌服务、禁用A-GPS、不使用基于Chromium的浏览器等措施,LineageOS已阻止了“几乎所有的谷歌数据收集”。他认为这些预防措施是合理的,并非“锡箔帽妄想”。然而,作者也承认,如果设备支持,他会选择使用更彻底的GrapheneOS,但讽刺的是,运行GrapheneOS往往需要购买谷歌品牌的设备。最终,作者在避免成为谷歌数据收集经济一部分的原则与使用便利性之间取得了平衡。

23. Postgres as a Search Engine (anyblockers.com)

使用 PostgreSQL 作为搜索引擎

本文探讨了如何利用 PostgreSQL 构建一个强大、灵活的搜索系统,通过组合全文搜索、语义搜索和模糊匹配三种技术,为 RAG 管道等应用提供可靠的检索基础。核心思想是将多种搜索方法集成到现有的数据库中,避免引入额外的搜索服务。

核心技术栈

  1. 全文搜索:使用 PostgreSQL 内置的 tsvectorGIN 索引,支持基于关键词的词汇搜索。通过 ts_rank_cd 函数进行结果排序。
  2. 语义搜索:使用 pgvector 扩展存储和查询向量嵌入(如1536维),实现基于文本含义的相似性搜索。
  3. 模糊匹配:使用 pg_trgm 扩展处理拼写错误和文本变体。它将文本分解为三字符序列(trigram),通过 % 运算符和相似度阈值进行匹配。

实现方法

混合搜索查询

通过公共表表达式(CTE)分别获取三种搜索方式的结果集,每个结果集都包含一个排名序号(rank_ix)。然后使用互惠排名融合(RRF) 算法合并这些结果。

  • RRF 工作原理:它将文档在不同列表中的排名取倒数后加权求和,从而奖励在多个列表中排名靠前的文档,惩罚仅在个别列表中排名高的文档。$rrf_k 参数用于平滑分数,$_weight 参数允许调整不同搜索方法的权重。
  • 关键操作:使用 COALESCE 处理 FULL OUTER JOIN,确保文档即使只出现在一种搜索结果中也能被包含,并正确计算其最终排名分数。

整合模糊搜索

在基础混合查询中加入模糊搜索(pg_trgm)的 CTE,并为其分配权重($fuzzy_weight),将其结果与全文和语义搜索结果融合。

调试与优化

  1. 排名调试:在最终查询中返回一个包含各搜索方法详细排名信息(如序号、相似度分数)的 JSON 对象(debug_rankings),便于理解结果来源和调整权重。
  2. 全文搜索调优
    • 加权 tsvector:为不同字段(如标题、正文)的 tsvector 设置不同的权重(如标题权重设为 ‘A’,正文设为 ‘C’),以影响相关性评分。
    • 长度归一化ts_rank_cd 函数支持多种归一化选项(如基于文档长度、词汇多样性),用于平衡不同长度文档的排名。

高级优化技术

  1. 交叉编码器重排序:在初步检索后,使用更精确但较慢的交叉编码器模型(如 Cohere Rerank 或自定义 GPT 模型)对结果进行二次排序,以提升准确率。
  2. 结果提升:根据业务逻辑对结果进行提升。例如,根据文档的更新时间(提升近期内容)或用户的交互历史(提升个性化内容)来调整最终排名。

何时考虑替代方案

PostgreSQL 是一个出色的起步和适用范围广泛的解决方案,但当遇到以下情况时,可能需要评估专用搜索引擎:

  • 文档长度差异极大。
  • 需要更先进的算法(如 BM25),它能更好地处理语料库全局统计信息和文档长度归一化。
  • 术语在大型语料库中的稀有性对相关性影响重大。

BM25 补充:可以通过安装 pg_searchpg_bestmatch.rs 等扩展为 PostgreSQL 添加 BM25 支持。

总结

通过组合 PostgreSQL 的扩展(pgvector, pg_trgm)和内置功能,可以构建一个集词汇搜索、语义理解和模糊匹配于一体的搜索系统。通过精细的权重调整、结果融合、重排序和业务逻辑提升,能够不断优化搜索体验。虽然 PostgreSQL 并非为搜索引擎而生,但其强大的功能足以满足许多场景,并能随着应用需求进行扩展和调优。

25. AMD's Radeon 890M: Strix Point's Bigger iGPU (chipsandcheese.com)

AMD Radeon 890M: Strix Point 集成显卡深度解析

AMD的集成显卡(iGPU)近期在Valve的Steam Deck和华硕ROG Ally等手持游戏设备中取得成功。其最新移动芯片代号为Strix Point,搭载了Radeon 890M iGPU(架构代号GFX1150,为RDNA 3.5的缩减版本),旨在延续并提升前代Phoenix系列的性能。

核心架构与规模升级

  • 计算单元增加:Radeon 890M拥有8个工作组处理器(WGPs),相比前两代iGPU的6个WGPs,规模有显著提升。
  • 缓存与内存子系统:GPU缓存结构沿用Phoenix设计,但每个L1中级缓存(256 KB) 现在服务4个WGPs(此前为3个)。共享2 MB L2缓存,并通过4个32字节/周期的Infinity Fabric端口连接芯片其他部分。Fabric链路可在较低频率(如1.6 GHz)下运行,从而节省功耗。
  • 内存配置:支持LPDDR5-7500内存,实测带宽约96 GB/s,高于Phoenix和Intel Meteor Lake,接近Qualcomm Snapdragon X Elite的水平。现代iGPU的带宽已可比肩过去配备GDDR5的低端独立显卡(如GTX 1050)。

性能表现

  • 带宽与延迟:缓存延迟与Phoenix接近,略优于Meteor Lake。AMD采用更多级缓存设计,而Intel的L2缓存容量更大。DRAM延迟有所改善,显著低于Meteor Lake。
  • 计算吞吐量:得益于双发射机制(dual-issue)和更高的时钟频率,Radeon 890M计算能力大幅提升,浮点性能超过5 TFLOPS(若将融合乘加计为两次操作则超过10 TFLOPS),明显优于Phoenix和Steam Deck APU。
  • 内存访问优化:标量内存访问路径延迟更低,本地数据共享(LDS)延迟显著改善,原子操作性能提升。CPU与GPU间数据拷贝带宽接近38 GB/s,优于PCIe 4.0 x16的32 GB/s。
  • 实际应用与游戏:在带宽敏感的流体模拟(FluidX3D)中性能领先;在《赛博朋克2077》(1080P低画质)中帧率表现良好,大幅超越Phoenix。功耗约50W时能效优于Snapdragon X Elite;降至15-20W功耗时,性能与Meteor Lake持平。

策略与展望

  • 设计哲学:AMD未对缓存和内存子系统进行大改,而是沿用已验证的成熟策略,通过增加GPU规模(WGPs)和提升频率来实现性能增长。尽管竞争对手(如Intel)拥有更大L2缓存,AMD仍能以相对较低的缓存容量和通用LPDDR5配置保持性能领先。
  • 移动GPU战略重心转移:以往AMD移动iGPU常使用过时的图形架构(如Vega),但Strix Point搭载的RDNA 3.5架构比其桌面GPU更新。这表明AMD正将移动低功耗游戏市场视为关键发力点。
  • 未来可能性:LLVM代码库中存在更高阶的RDNA 3.5变体(GFX1151,代号“Strix Halo”)支持,暗示AMD正在探索更大规模的集成GPU方案。

总之,Radeon 890M在Strix Point上的表现延续了AMD iGPU的成功,通过规模扩大和频率提升实现了显著的性能代际进步,巩固了其在移动集成显卡领域的竞争力。

26. Birds aren't real – how to create your own "bird" (www.lampysecurity.com)

如何制作自己的“监视鸟”模型

本文介绍了一个3D打印的DIY项目,旨在制作一个外形为鸟类的“监视设备”模型。该项目主要包含设计、编程、组装三个步骤。

核心部件清单

  • ESP32开发板(微控制器)
  • 微型舵机(用于驱动鸟头转动)
  • 移动电源(供电)
  • USB线、磁铁、杜邦线
  • 3D打印部件(鸟身、摄像头头部、磁铁座)
  • 工具:烙铁、热熔胶枪、热缩管、记号笔(用于上色)

设计与3D打印

  1. 鸟身模型:在线获取基础鸽子模型,修改头部结构以安装舵机,并开槽用于走线。为便于携带,在鸟身侧边设计磁铁槽,并加固脚部。
  2. 摄像头头部模型:找到现成摄像头模型,改造顶部以安装LED指示灯,底部开孔连接舵机。

编程(Arduino代码)

代码功能简单,通过ESP32控制:

  1. LED闪烁:在顶部摄像头上的LED随机间歇闪烁。
  2. 舵机转动:舵机(控制鸟头)以看似随机的角度和时长转动,模拟鸟类活动。
    • 使用标准的Servo库。
    • 设置GPIO 8引脚控制LED,GPIO 9引脚控制舵机。
    • 启动后先延迟7秒,再进入循环:LED亮灭、舵机按特定角度序列(如90°、15°、45°、0°)转动并搭配不同延迟时间。

组装与接线

  1. 焊接LED:将电线焊接到LED上,并用热熔胶将其固定在摄像头头部模型顶端。
  2. 连接舵机:将舵机放入鸟身,连接头部。舵机的电线穿过鸟身内部。
  3. 连接主板
    • LED正极接ESP32的GPIO 8引脚,负极接地。
    • 舵机信号线接GPIO 9引脚,正极接5V,负极接地。
    • 使用杜邦线或焊接方式连接,并用热熔胶临时固定以防脱落。
  4. 供电:连接移动电源,设备即可运行。

最终成品可固定在背包上,模拟一个“监视鸟类”。该项目结合了3D建模、基础电子和Arduino编程,适合作为趣味创客实践。

27. Foundation for Human Vision Models (github.com)

Sapiens:人类视觉模型基础

Sapiens 是一套面向人类中心视觉任务(如2D姿势估计、身体部位分割、深度估计、表面法线估计等)的综合性套件。该模型系列在 3亿张 野外真实人类图像上进行了预训练,展现出对非约束条件环境的卓越泛化能力。这些模型专为提取高分辨率特征而设计,其原生训练图像分辨率为 1024 x 1024, patch 大小为 16像素

主要特性与功能

  • 任务覆盖广:支持多种人类中心视觉任务,包括图像编码、姿势估计、身体部位分割、深度估计和表面法线估计。
  • 卓越泛化性:基于海量野外数据预训练,模型在多样化、无约束的真实场景中表现优异。
  • 高分辨率处理:原生支持高分辨率输入,能够提取精细的视觉特征。
  • 便捷的微调:提供了详细的训练指南,使针对特定任务微调模型变得简单。
  • 优化推理:通过 Sapiens-Lite 安装,可获得依赖项更少(仅需 PyTorch、NumPy、OpenCV)、速度提升 4倍 的优化推理环境。
  • 多尺度模型:提供了从 0.3B 到 2B 参数的多种模型规模。

部署与使用

  1. 环境安装
    • Lite 安装(仅推理):推荐用于运行现有模型,依赖少且速度快。
    • 完整安装:使用提供的脚本创建一个包含所有依赖项的 conda 环境,以复现完整的训练设置。
  2. 模型权重:需从 Hugging Face 下载预训练检查点,并按照指定的目录结构组织存放。
  3. 快速开始:克隆代码库并设置环境变量 SAPIENS_ROOTSAPIENS_CHECKPOINT_ROOT 即可开始使用。

评估与资源

  • 项目提供了针对各任务的定量评估结果。
  • 鼓励在研究中使用 Sapiens 并引用相关论文。
  • 项目采用特定许可证,并感谢 OpenMMLab 等开源项目的贡献。
29. Google's New Pipe Syntax in SQL (simonwillison.net)

Google 在 SQL 中引入管道语法

核心问题与解决方案

标准 SQL 存在语句顺序不符合语义逻辑的问题。例如查询必须以 SELECT 子句开头,但语义上应从 FROM(数据源)开始。这种“倒置”逻辑长期困扰开发者。Google 研究团队提出管道语法,通过引入 |> 管道操作符重构查询结构,使其顺序更贴近自然思维。

语法示例对比

传统 SQL:

SELECT component_id, COUNT(*)
FROM ticketing_system_table
WHERE assignee_user.email = 'user@email.com'
  AND status IN ('NEW', 'ASSIGNED')
GROUP BY component_id
ORDER BY component_id DESC;

管道语法:

FROM ticketing_system_table
|> WHERE assignee_user.email = 'user@email.com'
    AND status IN ('NEW', 'ASSIGNED')
|> AGGREGATE COUNT(*)
   GROUP AND ORDER BY component_id DESC;

新语法从数据源开始,逐步通过管道添加过滤、聚合等操作,避免了传统 SQL 中 SELECT 开头的认知跳跃。

应用情况

该语法自 2024 年 2 月起在 Google 内部逐步推广,截至 2024 年 8 月已拥有 1,600 名七日活跃用户。相关文档已整合至 Google 开源项目 ZetaSQL 中。

论文发布形式的争议

Google 以双栏 PDF 格式发布研究报告,引发对移动端可读性、可访问性及 Web 兼容性的批评。PDF 格式难以在手机上舒适阅读、难以复制文本,且不符合 Web 内容分享的最佳实践。

AI 辅助文档转换尝试

作者使用 Google 的 Gemini Pro 1.5 模型将 PDF 转换为 HTML:

  1. 通过提示词“Convert this document to neatly styled semantic HTML”成功生成约一半内容。
  2. 后续通过“and the rest”提示完成剩余部分。
  3. 转换结果存在局限性:缺失论文中的图表、参考文献未完整提取,但展示了 AI 工具在文档格式转换中的潜力。

搜索引擎与内容索引

作者将转换后的 HTML 版本发布后,在 Google 搜索中针对论文标题的查询结果中快速位列第三。为避免未经验证的 AI 生成内容影响搜索结果质量,作者随后添加 <meta name="robots" content="noindex, follow"> 标签。这一现象反映了 HTML 格式在 Web 信息传播中的效率优势。

30. Programming terrain from scratch using C++ and OpenGL by Shamus Young (2006) (www.shamusyoung.com)

从零开始使用C++和OpenGL编程地形引擎(Shamus Young,2006年)

项目概述与目标

本文记录了作者出于自学目的,从头开始构建一个地形渲染引擎的完整过程。作者明确区分了两种游戏视角的地形引擎需求:第一人称视角(注重近景细节、视距较短)和俯视视角(注重远距离渲染、视距较长)。基于个人经验,作者选择了俯视视角作为设计目标,旨在优化大规模地形的渲染性能。

技术实现上,项目使用C++语言和OpenGL图形库,强调编写清晰、高效的代码,并以当前硬件性能为目标平台,避免依赖未来硬件的提升。

开发阶段与关键技术点

1. 基础搭建与初步实现

  • 项目初始阶段设置了基本框架,包括调试窗口、鼠标控制的相机漫游等功能。
  • 首个地形渲染测试使用了一个512×512的网格,直接渲染原始数据,未进行任何优化。
  • 该网格包含524,288个多边形(每个格子分为两个三角形)和1,572,864个顶点,虽然现代显卡可以处理,但随着场景复杂度增加(如添加树木、建筑等),性能瓶颈会迅速暴露。

2. 高程数据的引入与处理

  • 为生成真实感地形,作者避免使用游戏常见的艺术家手动设计地形(常显得不自然),转而采用模拟侵蚀生成的地形数据
  • 高程数据以灰度BMP图像存储,每个像素对应一个网格点的高度(0-255)。但256级灰度不足以表现精细的高程变化,容易产生“阶梯状”地形。
  • 为此,作者创新性地使用BMP图像的三个颜色通道来分层存储不同尺度的高程信息:
    • 红色通道:控制宏观地形(如大型山脉或山谷),作用尺度为数百米。
    • 绿色通道:存储中尺度地形细节(如现实中的丘陵),作用尺度为数十米。
    • 蓝色通道:添加微观噪声(如地表粗糙度),作用尺度为米级或亚米级。
  • 三个通道的数据组合后,形成一张1024×1024的复合高程图(项目中实际使用512×512的部分),最终生成了更自然、细节更丰富的地形。

3. 当前局限性

  • 当前方法仅能通过垂直移动网格点来塑造地形,无法实现悬垂悬崖或垂直峭壁等复杂结构。
  • 作者指出这是大多数基于高度图地形引擎的常见限制,游戏中若需此类结构,通常会通过添加单独物体(如建筑物)来实现。

项目状态与后续方向

截至文章发布,基础地形引擎已能通过高程数据渲染出可视化的地形。作者明确表示,下一步的目标是在保持视觉质量的前提下减少渲染的多边形数量,即进行地形渲染优化。

总结:该项目是一个结构清晰、注重实践与性能的自教育范例,展示了从零开始构建地形引擎的核心步骤,包括视角选择、数据表示、分层细节处理及优化意识。

31. The Tao of Unicode Sparklines (2021) (blog.jonudell.net)

本文介绍了在数据库查询中使用Unicode字符创建火花线(sparklines)的方法。火花线是由Edward Tufte提出的一种小型、紧凑、文字大小的图表,适合嵌入表格或文本中展示数据序列的趋势。

Unicode火花线原理 文章利用一组八个Unicode块字符(U+2581至U+2588)表示不同高度的条形。每个字符对应一个高度等级(从1/8到全高),可将数值序列量化到这八个桶中,形成火花线字符串。例如,序列“1 2 3 4 5 6 7 8 7 6 5 4 3 2 1”会映射为“▁▂▃▄▅▆▇█▇▆▅▄▃▂▁”。

PostgreSQL函数实现 作者通过PL/Python在PostgreSQL中创建了sparkline函数:

  1. 输入为数字数组(bigint[])。
  2. 计算数组的最小值(_min)和最大值(_max),得到范围(extent = _max - _min)。
  3. 若范围为零(所有数值相等),将extent设为1以避免除零错误。
  4. 对每个数值,将其归一化到0-1区间,映射到0-7的索引,再从Unicode字符序列中取出对应字符。
  5. 返回拼接后的火花线字符串。

实际应用示例

  • 在Metabase中展示课程注释活动:每行代表一个课程,火花线显示每周活动变化,便于识别周期性或持续性模式。
  • 可扩展至不同尺度:从学生每日活动、课程每周活动到学校每周活动。
  • 火花线作为文本字符串,可参与排序操作(如按活动开始时间排序)。
  • 结合Metabase的迷你柱状图,可进一步显示行级汇总数据。

挑战与优化

  • 部分Unicode字符宽度不一致或低于基线,影响显示整齐度(尤其在短序列中)。
  • 作者测试了仅使用5个高度均匀的字符的简化方案,但认为在长序列中分辨率不足,故仍沿用8字符版本。

总结 Unicode火花线是一种轻量、可移植的可视化方案,适用于数据库查询结果内嵌迷你图表。尽管存在字符显示一致性问题,但在序列较长时效果尚可。该技术为时间序列数据的快速模式识别提供了直观的工具。

32. From Datalog to SVG (inconvergent.net)

这篇文章主要介绍了作者为解决在生成式算法中存储结果时,SVG格式会丢失图的拓扑结构信息这一问题,所开发的一种基于Datalog查询语言的图数据存储与SVG绘制方案。

核心问题:生成式算法的结果通常导出为SVG矢量图。然而,SVG文件本质上是绘制指令的集合,原始的图形拓扑信息(如边的连接关系、属性)在导出过程中基本丢失,导致无法从该SVG文件中用修改后的绘图逻辑重新绘制原图。

解决方案与流程

  1. 使用专用数据结构:作者利用一个名为cl-grph的内存图数据结构来存储算法生成的图。该结构支持为边(Edge)分配自定义属性(如:pth:stipple),这些属性可用于关联不同的绘图样式。
  2. Datalog查询导出:通过该结构内置的Datalog查询语言,可以灵活地导出图的数据。文中演示了两种查询:
    • 全量导出select (?p ?x ?y) where (?x ?p ?y) 查询所有边的起点、终点及属性,但数据会有很多重复。
    • 高效分组导出select (?p (grp ?x ?y)) where (?x ?p ?y) 将具有相同属性的边进行分组导出,更节省空间。
  3. Datalog驱动的SVG绘制DSL:文章的核心创新是创建了一个小型领域特定语言(DSL),该语言允许直接从Datalog查询结果绘制SVG。在该DSL中,Datalog查询(使用?x?y等变量)被直接用于选择要绘制的图元素。
    • 例如,(.&ws ?x ?y (?x :path ?y) ...) 用于选择所有属性为:path的边,并对其执行绘图操作。
    • 该DSL还集成了随机数生成,支持基于概率的绘图(如点画、随机绘制顶点)。

集成存储与优势: 作者展示了使用grph:write-with-script宏,将图数据空间数据绘图代码(包含Datalog查询和DSL指令)以及伪随机数生成器状态打包存储到一个.grph文件中。

  • 优势.grph文件同时保存了图形的完整拓扑和绘图逻辑。对比显示,.grph文件比等效的.svg文件小10到200倍,且包含了生成相同SVG(或进行不同方式绘制)所需的全部信息。

总结:该方案通过将图结构、属性和与之绑定的绘图逻辑(以Datalog查询和DSL代码的形式)整合存储,克服了SVG格式丢失拓扑信息的缺点。它利用Lisp宏的能力实现了数据与代码的紧密封装,为可逆、可修改的生成式图形工作流提供了一种技术范例。作者也指出,该方案的实际通用性可能有限,但旨在展示Lisp宏在解决特定领域问题上的强大作用。