2024-12-26

27 篇热帖

1. Blackcandy: Self hosted music streaming server (github.com)

Blackcandy:自托管音乐流媒体服务器

Blackcandy 是一个自托管的音乐流媒体服务器,可作为个人音乐中心。它提供在线演示供用户体验,并采用 Docker 方便部署。

主要特点与功能

  • 自托管:用户可在自己的服务器上运行,完全控制音乐库。
  • 流媒体:提供音乐播放功能。
  • 多平台访问:支持 Web 端和移动端应用(Android 和 iOS)。
  • 集成 Discogs API:可从 Discogs 获取艺术家和专辑图片。
  • 演示模式:可限制用户管理权限。

安装与部署

使用 Docker 镜像是最简单的安装方式。

# 使用 GitHub Container Registry
docker run -p 80:80 ghcr.io/blackcandy-org/blackcandy:latest

# 或使用 Docker Hub
docker run -p 80:80 blackcandy/blackcandy:latest

安装后,可通过浏览器访问 http://localhost 或主机IP,使用初始管理员账户登录(邮箱:admin@admin.com,密码:foobar)。

升级时需注意可能存在的重大变更,并遵循升级指南。基本步骤是拉取新镜像并重建容器。

核心配置

Blackcandy 通过环境变量进行配置,以下为关键配置项:

名称 默认值 说明
DB_ADAPTER sqlite 数据库适配器,支持 sqlitepostgresql
DB_URL 使用 PostgreSQL 时必须设置其连接 URL。
MEDIA_PATH 设置媒体文件的路径。
SECRET_KEY_BASE 用于会话安全的密钥。若不设置,每次启动会重新生成,导致旧会话失效。
DEMO_MODE false 是否启用演示模式,会限制管理员权限。
HTTP_PORT 80 容器内监听的端口。

持久化数据:所有需要持久化的数据存储在 /rails/storage 目录,可通过挂载该目录到主机实现。

使用 PostgreSQL:默认使用 SQLite,但可通过设置 DB_ADAPTERDB_URL 等环境变量切换到 PostgreSQL。

权限处理:挂载卷时可能遇到权限问题,可通过 --user 参数指定与主机相同的 UID 和 GID 解决。

开发指南

  • 环境要求:Ruby 4.0、Node.js 20、libvips、FFmpeg。
  • 启动开发服务:安装依赖并配置数据库后,运行 ./bin/dev
  • 访问:开发时访问 http://localhost:3000,使用相同的初始管理员账户登录。
  • 运行测试:使用 rails test:all 运行所有测试,rails lint:all 运行代码检查。

其他说明

  • 日志:默认输出到标准输出(STDOUT),可通过 Docker 的日志选项进行管理。
  • 边版本:基于 master 分支的不稳定版本,仅建议开发者测试或贡献时使用。
  • 项目赞助:文章末尾列出了赞助方信息。
2. A Minecraft server written in COBOL (github.com)

CobolCraft 是一个用 COBOL 语言编写的 Minecraft 服务器项目,支持游戏最新的 1.21.4 版本。

项目概述与功能

该项目实现了 Minecraft 服务器的诸多核心功能,主要包括:

  • 地形与世界管理:支持无限地形生成、动态区块加载,并能将世界与玩家数据持久化到磁盘。
  • 多人游戏与网络:支持可配置的多人在线游戏,具备服务器列表显示(Ping/状态)功能。
  • 核心游戏机制:包括方块破坏与放置(含自动生成的战利品表)、方块交互(如开门)、玩家物品栏、2x2 与 3x3 合成、物品实体与拾取、聊天以及游戏内/控制台命令。
  • 服务器配置与管理:通过 server.properties 文件进行配置,支持持久化白名单 (whitelist.json)。
  • 物理与生存要素:包含基础的碰撞检测、实体物理、跌落伤害、虚空伤害、死亡与重生机制。

然而,对于拥有多种状态、朝向或交互功能的方块,需要大量专用代码才能使其正常运作,其中许多尚未完全实现。目前已支持的方块包括火把、台阶、楼梯、可旋转的柱状物(如原木)、按钮(非交互式)、门、活板门、床和告示牌等。

技术实现与架构

  • 开发环境:项目主要使用 GnuCOBOL 在 Linux (x86_64/arm64) 上开发,也支持通过 Docker 进行跨平台部署。
  • 源码结构:主要代码位于 src/ 目录,src/main.cob 为入口,src/server.cob 包含服务器启动和游戏逻辑。cpp/ 目录包含用 C++ 编写的底层接口代码(如 TCP 套接字管理),最终所有源码编译为一个 cobolcraft 二进制文件。
  • 数据提取与生成:项目包含一个代码生成器(用 COBOL 编写),可从官方 Minecraft 服务器的 .jar 文件中提取 JSON 格式的数据(如方块类型、协议ID、配方、战利品表等)。这些数据在编译时用于自动生成 COBOL 代码,并在运行时加载到内存。为此还构建了一个完全单元测试的通用 JSON 解析器。
  • 测试:在 tests/ 目录下提供了单元测试,使用自定义的测试框架,重点关注 JSON 和二进制数据的编解码等难以调试的部分。

使用与部署

构建和运行需要一系列依赖项,包括 GnuCOBOL 3.1.2+、make、gcc/g++、zlib、curl 和 Java 21+。

  • Linux 原生部署:执行 make --jobs=$(nproc) 编译,然后 make run 运行。
  • Docker 部署:可使用预构建镜像 (meyfa/cobolcraft:latest) 或本地构建。通过挂载 server.propertieswhitelist.jsonworld 目录进行配置和持久化。
  • 服务器配置:通过 server.properties 文件设置端口、世界名称、白名单、MOTD 和最大玩家数(默认10,最大100)等参数。默认情况下服务器仅可通过 localhost 访问,外部访问需在运行 Docker 时绑定 0.0.0.0

项目动机与挑战

作者表示,此项目源于对 COBOL 语言的好奇,旨在通过实践学习。尽管缺乏 COBOL 经验,但选择用其编写复杂庞大的 Minecraft 服务器既是最佳也是最差的想法。挑战包括从头实现 JSON 解析、二进制数据处理、实时多人网络,并将本质上是面向对象的系统(Minecraft)转换为过程式语言。这种陡峭的学习曲线迫使作者深入研究语言概念,收获颇丰。

法律声明

该项目采用 MIT 许可证。“Minecraft” 是 Mojang Synergies AB 的商标,CobolCraft 与 Mojang 无关联亦未获其认可。

3. Egui – An immediate mode GUI written in Rust (www.egui.rs)

Egui:用 Rust 编写的即时模式 GUI 库

Egui 是一个使用 Rust 语言编写的即时模式(Immediate Mode) 图形用户界面(GUI)库。它的核心设计理念和特点可以概括如下:

核心概念:即时模式

  • 工作原理:在即时模式GUI中,程序的UI代码和渲染逻辑是紧密耦合的。每一帧(或每次交互)都重新调用UI定义代码,描述“当前”界面上应有什么控件以及它们的状态。UI的状态(如按钮是否被点击、文本框的内容)由UI函数的返回值即时反映,而不是存储在某个持久的UI对象树中。
  • 与保留模式对比:这与传统的“保留模式”GUI(如Qt, GTK)不同,后者通常维护一个持久的UI对象树,通过修改对象属性来更新界面。
  • 优势:这种模式使得UI代码与业务逻辑通常位于同一处,减少了状态同步的复杂性,非常适合游戏引擎、工具和需要高度动态界面的应用程序。

主要特性与设计目标

  1. 简洁的 API:旨在提供一个简单、易于使用和理解的API。
  2. 平台无关:本身不包含任何平台特定的渲染或输入处理代码。它通过一个名为 epaint 的子库进行渲染,但具体的渲染后端(如 OpenGL, Vulkan, Web)和输入处理(如窗口事件)需要由宿主程序(或框架如 eframe)提供。
  3. 纯 Rust:整个库完全用 Rust 编写,利用了 Rust 的安全性和性能优势。
  4. 可嵌入性:由于其平台无关的特性,Egui 可以轻松地嵌入到现有的渲染引擎或应用程序框架中。
  5. 易于扩展:支持创建自定义的控件和布局。

典型工作流 使用 Egui 时,开发者通常会使用一个框架(如官方提供的 eframe)作为宿主。宿主负责处理窗口创建、事件循环和渲染后端。然后,在每一帧中,宿主会调用 Egui 的上下文(egui::Context),开发者通过这个上下文来声明UI布局。Egui 会处理布局计算、输入响应和绘制指令的生成,最终由宿主的渲染后端将这些指令绘制到屏幕上。

总结 Egui 是一个为 Rust 生态系统设计的、轻量级且高效的即时模式GUI解决方案。它通过清晰的即时模式范式简化了UI开发流程,特别适合对性能和控制力要求较高的场景,例如游戏内工具、数据可视化工具和自定义编辑器。其核心价值在于提供了一个纯粹、可移植的UI描述层,而将具体的渲染和平台交互留给集成者实现。

4. The trap of "I am not an extrovert" (orkohunter.net)

《“我不是外向者”的陷阱》文章摘要

本文通过作者大学时期的一个经历切入:在欢送会上,一位自称阿迪蒂亚的学弟以“我不是外向者”为由拒绝社交,尽管现场大部分人实际都是内向的技术爱好者。作者指出,许多人像阿迪蒂亚一样,将“内向”当作不成长的借口,但事实上每个人都有内向和外向的一面,这往往是无意识的选择。

核心观点

  • 工作中的外向是一种可学习的技能:作者强调沟通与协作是工作的重要组成部分,并非与生俱来或毫不费力。例如,资深工程师拉姆虽技术出色但独自工作、缺乏展示,而什亚姆善于提问、分解任务、主动协作和演示,因此在晋升时更受青睐。拉姆将此归因于“我不是外向者”,实则是将沟通技能视为不可习得的天赋。
  • 快思考与慢思考的平衡:借鉴《思考,快与慢》的概念,作者区分了大脑的两种决策模式。尽管多数人倾向于节能的快思考,但深度慢思考对高质量工作和协作至关重要。善于思考与合作的人往往更受青睐。
  • “前排学生氛围”的警示:作者提到一类人(包括自己)有时会急于发言、渴望被看到,但需把握分寸,避免成为令人厌烦的存在。
  • 现实中应做“内向者”追求深度友谊:作者主张在现实生活中应更注重深度优先搜索(DFS)式的深层友谊,而非广度优先搜索(BFS)式的浅层社交,尤其是随着年龄增长,深度友谊愈发珍贵。

结论

作者呼吁读者不要躲在“内向”的标签后逃避沟通与协作,这些是可以通过学习和练习掌握的关键技能,对职业发展、家庭和人际关系都有直接影响。同时,在现实生活中应珍视深度社交的价值。

5. Numbers Are Leaves (www.christo.sh)

文章标题:数字即叶片

本文介绍了作者在ZFC集合论背景下,如何通过集合构造自然数,并观察到这些数在可视化时呈现出类似生物叶片的结构。

1. 背景与集合论基础

  • 作者自学Zermelo-Fraenkel集合论(ZFC),该理论旨在建立无悖论的数学基础。
  • 集合是数学的基础,所有数学对象本质上都是集合。
  • 介绍了集合的基本概念(如空集∅、集合的元素)以及基础公理。该公理意味着集合的树状可视化是可行的(集合成员关系对应树中的父子关系)。

2. 用集合表示自然数

  • 最初尝试(使用多个空集):由于外延公理(集合由其元素唯一确定,且无重复元素),此方案无效(如 {∅, ∅} 等同于 {∅})。
  • 后继定义法(单例集):定义 0=∅, n+1={n}。例如 1={∅}, 2={{∅}}。此方案有效,但数字集合结构单一。
  • 冯·诺依曼序数:这是一种更结构化的定义。递归定义为 0=∅, n+1 = n ∪ {n}。因此,n = {0, 1, 2, ..., n-1}。具体构造如下:
    • 0 = ∅
    • 1 = {∅}
    • 2 = {∅, {∅}}
    • 3 = {∅, {∅}, {∅, {∅}}}
    • 4 = {∅, {∅}, {∅, {∅}}, {∅, {∅}, {∅, {∅}}}}
    • 该定义具有自相似性,对应的集合树状图从数字3开始明显展现出分形特征,且节点数为 2^n

3. 可视化与“叶片”现象

  • 最初使用层次布局(如dot工具)绘制这些集合对应的树。
  • 关键转折:使用力导向图布局算法(如sfdp)进行可视化。该算法模拟弹簧力和斥力,使节点分布更对称。
  • 应用力导向布局后,冯·诺依曼序数(从6开始到16)的图形呈现出惊人的自相似叶片状分形结构,这是本文的核心发现。

4. 讨论与后续

  • 作者提出了两个问题:
    1. 为什么是叶片状而非其他分形(如雪花)?
    2. 叶片结构是否仅由布局算法导致?通过将Collatz树(结果呈微生物状)进行对比可视化,初步证明叶片结构与序数本身有关,而非算法单独造成。
  • 未来方向:探索有理数的集合论表示(利用Kuratowski构造有序对)是否也呈现类似叶片结构。
6. Sherlock: Hunt down social media accounts by username across 400 social networks (sherlockproject.xyz)

Sherlock 项目摘要

项目名称:Sherlock

核心功能:这是一个命令行工具,用于通过一个给定的用户名,在超过400个不同的社交媒体网络平台上,查找与该用户名关联的账户。

主要用途

  • 用户名追踪:帮助用户调查一个特定的用户名在哪些主流及非主流社交网站上被注册和使用。
  • 开源情报:常用于OSINT(开源情报)调查,以收集公开的网络身份信息。
  • 安全研究:可用于检查自己或他人的用户名是否被他人在其他平台冒用,或用于渗透测试中的信息收集阶段。

技术特点

  • 平台覆盖广:内置了一个庞大的网站列表,涵盖全球数百个社交媒体、论坛、博客等平台。
  • 自动化检查:通过自动化脚本逐一访问目标网站,并检查输入的用户名是否存在有效的注册页面。
  • 社区维护:作为一个开源项目,其支持的网站列表和功能由社区不断更新和完善。
8. Portspoof: Emulate a valid service on all 65535 TCP ports (github.com)

Portspoof:在65535个TCP端口上模拟有效服务

概述 Portspoof 是一款防御性安全工具,其主要目标是使攻击者的侦察阶段变得缓慢、昂贵且不可靠。它通过将所有65535个TCP端口模拟为开放状态并运行看起来合法的不同服务,极大地增加了攻击者识别真实攻击面的难度和成本。

核心功能

  1. 全端口开放:对所有TCP端口的连接尝试均返回 SYN+ACK,使所有端口显示为开放状态。
  2. 服务模拟:基于正则表达式数据库,动态生成超过9000种逼真的服务签名。每个端口对探测会做出不同的、令人信服的服务身份响应。
  3. 混合响应模式:每个端口在启动时被分配不同的行为特征,包括立即发送横幅、延迟响应或静默保持,且保持时间范围很广(从几十毫秒到几分钟)。这有效干扰了攻击者的版本检测扫描。
  4. 轻量安全:以用户权限运行,无需root权限。每个实例仅绑定一个TCP端口,CPU和内存占用极低。
  5. 主动防御:可作为漏洞利用框架前端,用于反制攻击者扫描工具中的漏洞。

工作原理

  • 挫败端口扫描器:Nmap 等工具扫描时,会看到所有端口都开放,并报告各种不同的服务。
  • 混淆版本检测:对服务探测(如 nmap -sV)响应精心构造的虚假服务签名,使攻击者无法通过常规扫描确定哪些是真实服务。
  • 结果:攻击者无法快速区分真假服务。一次完整的版本扫描可能需要10多个小时并产生大量无用数据,显著消耗攻击者的时间和资源。

设计方法

  • 采用单线程epoll事件循环,避免了多线程的开销,单机可轻松维持超过1万个并发连接。
  • 为不同端口分配固定的混合响应模式(立即响应、等待客户端输入后响应、保持沉默)。
  • 为每个连接的保持时间加入随机抖动,使重复探测的响应时间呈现自然变化,类似于真实服务在负载下的表现,增加了攻击者通过计时进行区分的难度。
  • 这种设计利用了成本不对称性:防御方的资源消耗极低(每个空闲连接约占1-2KB内核内存),而攻击方则需要投入大量时间和精力,最终得到的仍是一个“大海捞针”的结果。

安装与配置

  1. 构建:使用CMake从源代码编译安装。
  2. 防火墙配置(关键):使用 iptables 的 NAT 规则,将除真实服务端口(如22)外的所有入站 TCP 流量重定向到 Portspoof 的监听端口(默认4444)。
    # 示例:将除SSH端口外的所有流量重定向
    sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j RETURN
    sudo iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 4444
    
  3. 启动:可通过脚本配置开机自启。

使用模式

  • 服务模拟模式(推荐):加载配置和签名文件运行。
    portspoof -c /etc/portspoof.conf -s /etc/portspoof_signatures -D
    
  • 开放端口模式:仅使所有端口开放,不发送服务横幅,但仍会拖住连接。
  • 模糊测试模式:可用于对扫描工具发送随机或字典载荷进行模糊测试。

加固与高级配置

  • 提供了一套进阶的 iptables 规则集,用于速率限制(限制单个IP的新连接频率)和自动封禁(对超限连接的IP进行临时屏蔽),以防御试图耗尽资源的暴力扫描。
  • 需要排除运行真实服务的端口。
  • 可调整内核参数(如 xt_recent 列表大小、连接跟踪表大小)以适应高流量环境。

Portspoof Pro 商业专业版本,将欺骗防御扩展到整个网络。单个传感器可模拟整个 /16 网段(数千个IP),每个IP具有独特的服务和个性,并支持有状态的多步对话。具备扫描检测、工具指纹识别、结构化遥测数据输出等功能,支持多种合规标准。

作者与许可 作者:Piotr Duszyński。 许可:GNU通用公共许可证 v2.0。

10. Show HN: A singing synthesizer for the browser with automatic 3-part harmony (pbat.ch)

项目概述:Trio - 浏览器歌唱合成器

核心功能

这是一个名为 Trio 的基于浏览器的歌唱合成器项目,其主要特点是自动生成三声部和声。用户可以通过浏览器界面进行交互和操作。

技术实现

  • 前端架构:项目使用标准的HTML5结构,包含一个全屏的 <canvas> 元素作为主要交互界面。
  • 样式与逻辑分离:通过外部CSS文件(style.css)管理样式,主要的程序逻辑则封装在JavaScript模块(main.js)中,并采用ES模块规范(type="module")进行加载。
  • 响应式设计:在 <head> 中设置了视口元标签(viewport),以确保在移动设备上也能正确显示。

界面设计

界面非常简洁,整个页面由一个全屏的 <canvas> 画布占据,用于渲染视觉内容或提供交互式界面。这表明应用的前端核心依赖于Canvas API进行图形和动画渲染。

项目特点

  1. 浏览器原生运行:无需安装额外软件,直接在网页浏览器中即可使用。
  2. 音乐与和声合成:专注于歌唱声音的合成,并能自动为其生成三声部的和声。
  3. 模块化开发:采用模块化的JavaScript结构,有助于代码的组织和维护。

潜在应用场景

该项目可能用于演示Web Audio API和Canvas技术的结合,或为在线音乐创作、教育互动提供工具。其自动和声功能是核心亮点。

12. Server-Sent Events (SSE) Are Underrated (igorstechnoclub.com)

服务器发送事件(SSE)被低估的技术优势

什么是SSE?

SSE是一种基于HTTP的服务器到客户端的单向通信技术。与WebSocket的双向通信不同,SSE通过保持开放的HTTP连接实现服务器向客户端的实时数据推送,类似于广播电台的模式:服务器作为“发射台”传输数据,客户端作为“接收器”监听。

为何被低估?

  1. WebSocket的流行度:WebSocket的全双工通信能力使其成为开发者首选,掩盖了SSE的简洁性。
  2. 单向性的误解:虽然SSE仅支持服务器到客户端的通信,但许多应用场景实际上只需要这种单向数据流。

SSE的核心优势

  • 实现简单:直接利用标准HTTP协议,无需复杂的连接管理。
  • 基础设施兼容:与现有HTTP基础设施(负载均衡器、代理、防火墙)无缝协作。
  • 资源高效:相比WebSocket,因单向通信和标准HTTP连接而消耗更少资源。
  • 自动重连:浏览器内置支持连接中断后的自动重连机制。
  • 语义清晰:单向模式促进关注点分离,简化应用逻辑。

典型应用场景

  • 实时新闻推送与社交媒体更新
  • 股票行情与金融数据流
  • 进度条与任务监控
  • 服务器日志实时流
  • 协作编辑中的更新通知
  • 游戏排行榜
  • 位置追踪系统

实现示例

服务器端(Flask示例)

from flask import Flask, Response, stream_with_context
import time, random

app = Flask(__name__)

def generate_random_data():
    while True:
        data = f"data: Random value: {random.randint(1, 100)}\n\n"
        yield data
        time.sleep(1)

@app.route('/stream')
def stream():
    return Response(
        stream_with_context(generate_random_data()),
        mimetype='text/event-stream'
    )

客户端(JavaScript示例)

const eventSource = new EventSource("/stream");
eventSource.onmessage = function(event) {
    document.getElementById("data").innerHTML += `<p>${event.data}</p>`;
};
eventSource.onerror = function(error) {
    console.error("SSE error:", error);
};

代码关键点

  • 服务器通过/stream路由处理SSE连接
  • generate_random_data()持续生成格式化的事件流
  • text/event-stream MIME类型标识SSE协议
  • 客户端EventSource对象自动管理连接和重连

限制与注意事项

  1. 单向通信:仅支持服务器到客户端,客户端需通过单独HTTP请求向服务器发送数据。
  2. 浏览器兼容性:现代浏览器普遍支持,旧浏览器需使用polyfill。
  3. 数据格式:主要支持文本数据,二进制数据需Base64编码。
  4. HTTP/2优化:在HTTP/1.1下存在连接数限制(每浏览器/域名约6个),HTTP/2下此限制提升至约100个并发流。

最佳实践

  • 错误处理:监听onerror事件并检查连接状态
  • 连接管理:完成后调用eventSource.close()释放资源
  • 重连策略:实现指数退避算法,限制最大重试次数

现实应用案例:ChatGPT的流式响应

大型语言模型(如ChatGPT)使用SSE实现流式响应,但与标准SSE有重要区别:

  • 请求方式:LLM API使用POST请求,而标准SSE EventSource仅支持GET
  • 数据格式:每个数据块以data: JSON格式传输,用\r\n\r\n分隔
  • 响应结构:包含增量内容、模型信息、使用统计等字段
  • 特殊头信息:返回速率限制、处理时间等元数据

结论

SSE为实时单向数据流提供了优雅的解决方案,其简洁性、高效性和对现有基础设施的良好支持使其成为众多应用场景的理想选择。虽然WebSocket在双向通信中不可或缺,但SSE在专注于服务器到客户端数据推送的场景中,往往提供更简洁、更合适的解决方案。

13. Bird flu kills more than half the big cats at a Washington sanctuary (www.cnn.com)

华盛顿州一家动物庇护所遭受禽流感重创,超过半数的大猫死亡。
华盛顿野生猫科动物保护中心近日宣布,已有20只大猫在数周内因禽流感死亡,该中心原有37只猫科动物,现存仅17只。
死亡动物包括非洲薮猫、山猫、美洲狮、加拿大猞猁、阿穆尔-孟加拉混血虎等多个物种。
其中一只名为塔比的老虎因性格活泼受人喜爱,而一只非洲薮猫尼科仍处于危重状态,后腿功能尚未恢复。
目前尚不清楚大猫如何感染禽流感,但中心推测可能与候鸟迁徙路径或食物污染有关。首例死亡发生在感恩节前后,一只17岁的美洲狮在生病后次日死亡,随后病毒迅速蔓延。
禽流感主要通过呼吸道分泌物和鸟类接触传播,也可通过哺乳动物摄入受感染的禽类传播。
猫科动物尤其易感,症状初期可能不明显,但会迅速恶化,常在24小时内引发类似肺炎的状况并导致死亡。
中心已实施隔离,关闭对外开放,并与联邦及州动物卫生官员合作,对栖息地进行消毒,制定预防策略,同时接受捐赠,计划于3月重新开放。
华盛顿州鱼类和野生动物部门本月早些时候报告称,该州禽流感病例呈上升趋势,并在另一地区确认两只美洲狮感染。
美国疾病控制与预防中心指出,人类通过接触感染动物而感染禽流感的情况罕见,但若长期无保护接触患病动物仍可能发生感染。

14. Three-quarters of the land is drying out, 'redefining life on Earth' (grist.org)

全球土地干旱化与土壤盐碱化加剧,正重新定义地球生命

危机概述
根据联合国防治荒漠化公约(UNCCD)和联合国粮农组织(FAO)的最新报告,全球变暖正导致地球土地日益干燥和盐碱化,对生态系统、农业和人类生存构成严重威胁。过去30年间,77%的陆地变得更加干燥超过40%的陆地(不含南极洲)已成为干旱区,且约10%的全球土壤受盐碱化影响,另有25亿英亩土地面临风险。

干旱化扩张与影响

  • 范围扩大:1990至2020年间,7.6%的全球土地从湿润区转变为干旱区,总面积超过加拿大,2020年这些区域居住着全球30%的人口,较几十年前增长超7%。
  • 长期性:干旱化是长期气候趋势,与临时性干旱不同,一旦发生便难以逆转。联合国专家强调,这些干燥气候“将不会恢复原状”。
  • 全球蔓延:高排放情景下,干旱化可能扩展至美国中西部、墨西哥中部和地中海等非传统干旱地区。
  • 连锁危害:威胁农业生产力、生物多样性,加剧粮食与水资源不安全,推动大规模迁移、经济衰退、疾病和地缘冲突(如苏丹案例)。预计到21世纪末,若不减排,全球三分之二的土地(除格陵兰和南极洲)储水能力将下降。

土壤盐碱化危机

  • 机制:干旱化导致淡水短缺,迫使农民使用咸水灌溉,加速土壤盐分积累。过量盐分会抑制植物吸水、改变土壤结构、加剧侵蚀,造成作物减产高达70%。
  • 现状:全球10%的灌溉农田和类似比例的雨养农田已受影响,中国、俄罗斯、美国等10国占全球盐碱化土壤的70%,每年造成农业损失至少270亿美元。
  • 预测:若按当前升温趋势,到2050年全球超过50%的农田可能遭受盐碱化。

应对挑战与争议

  • 国际行动:UNCCD第16次缔约方大会(COP16)讨论土地退化对策,但未能达成具有法律约束力的协议,仅筹集约120亿美元用于脆弱国家应对。
  • 解决方案:报告呼吁结合自然方案(如生态农业)、技术改进(耐盐作物品种)、水资源管理及投资恢复力项目,预计到2030年需至少2.6万亿美元资金。
  • 质疑声音:部分专家批评某些大型技术方案(如非洲“绿色长城”植树计划)可能加剧水资源短缺和生物多样性损失,呼吁优先采取适应性策略。

结论
研究机构一致认为,干旱化和盐碱化是“100%相互关联”的危机,需立即采取行动。当前趋势表明淡水资源将持续减少,但通过科学适应措施仍可缓解冲击。全球必须加速投资韧性建设,否则数十亿人将面临饥饿、流离失所和经济倒退的未来。

15. Seconds Since the Epoch (aphyr.com)

本文澄清了一个常见误解:POSIX时间(Unix时间)并非严格表示自1970-01-01 00:00:00 UTC以来的真实秒数。以2024-12-25 18:51:26 UTC为例,实际自纪元已过1735152713秒,但POSIX时间为1735152686秒,存在27秒差异。

这是因为POSIX标准(IEEE 1003.1)将时间定义为基于协调世界时(UTC)的简化模型,假设每天恒为86400秒,忽略了闰秒。标准中的计算公式也体现了这一点。现实中,由于闰秒的引入,POSIX时间会偶尔发生回跳,可能导致系统问题。

标准制定者明知“秒数”并非实际秒数,但出于简化计算和兼容性考虑而忽略闰秒,并认为多数系统不需要精确追踪闰秒。附录指出,供应商和管理员需根据应用需求尽可能调整时间值。

然而,这种忽略使得“自纪元以来的秒数”具有误导性,可能引发分布式系统的同步错误。文章建议的替代方案包括:

  • 单机计时:使用CLOCK_MONOTONICCLOCK_BOOTTIME
  • 无需与其他系统交换POSIX时间戳时:采用TAI、GPS等不含闰秒的时间系统。
  • 需与POSIX系统大致对齐时:使用闰秒涂抹(leap second smearing)技术。
  • 转换工具:如qntmt-a-i库可实现POSIX与TAI时间互转。

此外,闰秒问题有望在2035年左右通过国际共识废除,届时时间计算将简化,但需在依赖“86400秒/天”假设的系统中更新转换表。

16. Ask HN: What skills do you want to develop or improve in 2025?
18. I thought I found a bug (www.os2museum.com)

本文记录了作者在调试DOS模拟器时发现的一个C语言文件I/O问题及其历史根源。作者在运行COMMAND.COM命令时,发现预期写入“ABCD”的文件实际得到“ABBC”,原因是COMMAND.COM为处理可能以Ctrl-Z结尾的文件,执行了打开、写入、关闭、再打开、回退、读取、写入的复杂序列。调试发现,C运行时库在读/写模式切换时行为异常:在Microsoft Visual C++ 6.0和IBM C/C++ 3.6中,第二次写入失败,且错误指示不一致。

作者指出,这是由于C标准库在更新模式(读写混合)下,要求读和写操作之间必须插入fflush或文件定位函数(如fseek),否则行为未定义。这一限制源自C语言早期历史:从1979年K&R C开始,仅支持读、写、追加模式,不支持混合更新;1980年AT&T UNIX System III手册已规定类似限制;1988年ANSI C草案正式确立规则,后续标准(C99、C23)延续至今,要求切换方向时需中间操作。

当前实践中,Linux(glibc)和FreeBSD允许自由混合读写,但Microsoft库仍遵循标准限制。作者查阅历史源代码(如32V UNIX、System III、BSD)发现,1970年代末AT&T和BSD已实现混合读写,但标准始终强调谨慎处理。为编写可移植代码,作者建议在切换读写方向时使用fseek(f, 0, SEEK_CUR)作为安全措施。本文揭示了C语言I/O库近50年历史遗留的复杂行为。

19. Differential Growth Addon for Blender (boris.okunskiy.name)

Differential Growth Addon for Blender 摘要

插件简介
Differential Growth Addon 是一个为 Blender 设计的开源免费插件,旨在模拟自然界中的差分生长过程,生成有机形态的图案与模型。该插件完全符合 Blender 开源精神,用户可免费使用并参与开发。

核心功能与特点

  • 程序化生成:通过算法模拟生长过程,无需手动建模即可创建复杂的自然形态。
  • 高度可定制:用户可通过调整参数(如分裂半径、生长方向等)控制生成结果。
  • 多形态输出:支持生成类似地衣、藻类、生菜等自然物体的结构。
  • 开源免费:代码托管于 GitHub,鼓励社区协作与改进。

示例应用

  1. 生菜状形态:从单位圆开始,通过逐步减小分裂半径,模拟生长过程中逐渐细化的结构。
  2. 地衣状形态:通过抑制内部生长并限制 Z 轴移动,形成平面扩散的纹理。
  3. 藻类状形态:沿 Z+ 方向增加生长,同时抑制内部生长,形成立体分支结构。

获取与使用

  • 用户可从 GitHub 仓库下载最新版本。
  • 社区提供教程视频、问题讨论及作品分享平台。

社区支持

  • 用户可通过 GitHub 或相关论坛提问、交流创作心得。
  • 鼓励用户通过 Star 功能支持项目发展。

该插件为艺术创作者、设计师及程序化建模爱好者提供了探索自然生成美学的实用工具。

20. Bad keming: Kerning failures, plus other typographical and font mishaps (badkeming.com)

内容摘要:
本文探讨了排版中的字间距调整失败,即“kerning”错误,这些错误严重到被戏称为“keming”,同时涉及其他排版和字体相关的失误。

21. Siyuan: Privacy-first, self-hosted personal knowledge management software (github.com)

思源笔记:隐私优先的自托管个人知识管理软件

思源笔记是一款以隐私为首要考虑的个人知识管理系统,支持细粒度的块级引用和所见即所得(WYSIWYG)的Markdown编辑。

主要特性

  • 内容块:支持块级引用与双向链接、自定义属性、SQL查询嵌入、siyuan://协议。
  • 编辑器:采用块式编辑,支持所见即所得Markdown、列表大纲、块缩放、百万字大文档编辑、数学公式、图表、Web剪藏、PDF批注链接等。
  • 导出:支持块引用与嵌入、带附件的标准Markdown、PDF/Word/HTML格式,以及复制到微信公众号、知乎、语雀。
  • 数据库:提供表格视图。
  • 其他功能:间隔重复闪卡、通过OpenAI API进行AI写作与问答、Tesseract OCR、多标签页与分屏拖拽、模板片段、JavaScript/CSS代码片段、移动端与桌面端应用、Docker部署、API及社区市场。
  • 大部分功能免费(包括商用),部分高级功能需付费订阅。

架构与生态系统

思源笔记由多个子项目构成,形成了完整的技术栈和生态:

  • lute:编辑器引擎
  • chrome:Chrome/Edge浏览器剪藏扩展
  • bazaar:社区市场
  • dejavu:数据仓库
  • petal:插件API
  • android / ios / harmony:Android、iOS、鸿蒙OS原生应用
  • riff:间隔重复记忆算法模块

部署与安装

推荐优先通过各平台应用商店安装以便于更新。主要的部署方式包括:

  • 应用商店:iOS App Store、Google Play、F-Droid、Microsoft Store。
  • 安装包:从B3log或GitHub获取。
  • Docker部署核心方法):
    • 使用官方镜像 b3log/siyuan
    • 需通过 -v 挂载宿主机目录到容器的 /siyuan/workspace
    • 必须设置 --accessAuthCode 参数以确保安全。
    • 可通过环境变量 PUIDPGID 自定义运行用户和组的ID,以解决挂载目录的权限问题。
    • 重要提示:务必正确配置挂载卷,否则容器删除后数据会丢失。建议使用NGINX反向代理并配置WebSocket支持 (/ws)。
    • 限制:Docker版不支持桌面端/移动端客户端连接、部分格式导出及Markdown文件导入。
  • 其他平台:也提供了在Unraid和TrueNAS上的部署指南。

常见问题解答

  • 数据存储:数据保存在工作区文件夹的data目录下,按功能(附件、表情、代码片段、模板等)和笔记本分类存储,文档数据以.sy(JSON格式)文件保存。
  • 数据同步不支持通过第三方同步盘同步,否则可能导致数据损坏。支持连接第三方云存储(会员功能),或通过手动导出/导入数据实现。
  • 开源情况:完全开源(UI、内核、安卓、iOS、鸿蒙、剪藏扩展均开源)。
  • 版本升级:根据安装方式(应用商店、自动下载更新、手动安装包)选择对应升级途径。
  • 其他:包括块图标显示、数据仓库密钥丢失处理等问题的解决方案。

社区与开发

  • 拥有英文论坛、用户社区及“Awesome SiYuan”资源集合。
  • 提供详细的开发指南,欢迎社区贡献代码。
  • 项目的发展得益于众多开源项目和贡献者。
23. The history of twisted-pair Ethernet [video] (www.youtube.com)

视频摘要:TWISTED: 双绞线以太网的戏剧性历史

基本信息

  • 标题: TWISTED: The dramatic history of twisted-pair Ethernet
  • 频道: The Serial Port(13.1万订阅者,已认证)
  • 发布日期: 2024年12月25日
  • 播放量: 110万次
  • 点赞数: 3.4万
  • 评论数: 1,400条

视频主题

该视频探讨了RJ-45连接器和非屏蔽双绞线(UTP)如何成为以太网标准的漫长历程。这是一个历时十年的研究之旅。

章节结构

时间 章节
00:00 引言
00:53 同轴电缆(Coax)
02:29 1983年
10:37 StarLAN
13:24 更快、更好、更强
16:47 UTP的问题
26:32 前辈技术
27:22 结语

核心内容

视频探索了从不灵活的同轴电缆过渡到利用现有电话基础设施构建局域网所面临的挑战,揭示了行业先驱如何克服怀疑和技术障碍,最终建立了星型拓扑标准,彻底革新了计算机网络。

参考资料

视频引用了多篇学术文献和历史资料,包括IEEE标准文档、AT&T技术出版物以及对行业专家Richard Bennett和Patricia Thaler的采访。

24. Ask HN: Resources for general purpose GPU development on Apple's M* chips?
25. Into CPS, Never to Return (bernsteinbear.com)

CPS(续延传递风格)概述

核心概念

CPS(续延传递风格)是一种程序中间表示形式,主要用于函数式语言(如SML、Scheme)的编译器。其核心规则有两条:

  1. 函数/运算符的参数必须是平凡的(trivial)
  2. 函数调用永不返回(而是通过续延传递结果)

CPS的优势在于天然支持尾调用和非局部控制流(如call/cc),同时也可作为优化目标(类似SSA)。

Mini-Scheme到CPS转换

文章通过一个类似Scheme的小语言示例,逐步构建CPS转换器:

  • 基本元素:支持整数、算术运算、变量绑定、单参数函数(可闭包)、函数调用和条件分支。
  • 转换方法:采用递归函数cps(exp, k),其中exp为待转换表达式,k为续延。转换过程遵循“永不返回”原则,始终通过续延传递结果。
  • 关键步骤
    • 平凡表达式(整数、变量等):直接通过$call-cont传递给续延。
    • 函数调用:递归编译子表达式,合成新续延,并将续延作为额外参数传递给函数。
    • 运算符调用(如+):类似函数调用,但生成以$开头的特殊形式(如$+)。
    • Lambda表达式:创建带续延参数的函数形式(fun),并在函数体内使用续延实现“返回”。
    • 条件表达式if):递归编译条件,使用$if特殊形式分支,并优化续延的重复使用。
    • let绑定:通过续延实现变量绑定。

优化技术

CPS中间表示可通过递归重写进行优化,常见技术包括:

  • 常量折叠:在编译期计算常量表达式(如将(+ 3 4)转换为7)。
  • β归约:将函数应用(如((lambda (x) (+ x 1)) 2))替换为函数体((+ 2 1))。需注意作用域和求值顺序,避免变量捕获或副作用问题。
  • 代码内联:仅当变量在函数体内出现0或1次时,才进行替换以避免代码膨胀。

代码生成

将优化后的CPS转换为可执行代码的几种方法:

  1. 生成C代码:将funcont形式转换为C函数。需进行自由变量分析以支持闭包,但尾调用效率低。
  2. 蹦床(Trampoline):在堆上分配帧结构支持尾调用消除。可结合垃圾回收优化(如Cheney on the MTA算法,用于CHICKEN Scheme)。
  3. 大Switch语句:将所有funcont放入switchcase中,调用转换为goto。易于管理栈根,但可能受限于编译器。
  4. 自定义IR降级:将CPS进一步转换为低级IR或汇编代码。

元续延(Meta-continuation)

为减少生成代码量,可采用元续延方法(即“高阶变换”),在编译器层面使用函数代替某些cont形式,从而减少中间代码规模。

相关资源

文章最后列出多篇相关论文和实现,涵盖CPS转换、优化、编译等方面,如:

  • Matt Might的CPS转换方案
  • Marc Feeley的Scheme到C编译器
  • Appel的《使用续延编译》
  • 面向函数式语言的虚拟机FVM等

本文基于提供的文章内容总结,涵盖了CPS的基本原理、转换示例、优化方法和代码生成策略。