跳转至

2026 年

🦞 OpenClaw:给 AI 装上“爪子”的开源革命 —— 数字贾维斯已到来

OpenClaw 是什么?

OpenClaw(原名 Clawdbot → Moltbot → OpenClaw)是一个开源 AI 代理框架,由奥地利独立开发者 Peter Steinberger 创建。它不是一个大模型,而是一个"给 AI 装上爪子的执行系统"

简单来说:

  • GPT/Claude 是"大脑"——只能思考和建议
  • OpenClaw 是"手脚"——能真正操作你的电脑执行任务

它运行在你的本地设备(Mac/PC)或私有服务器上,通过 WhatsApp、Telegram、Slack、飞书、钉钉等日常聊天软件与你交互,拥有读写文件、执行终端命令、操控浏览器、访问邮件日历等系统级权限

一文带你理解Dart空安全

原文:Understanding null safety

作者: 鲍勃·尼斯特罗姆,写于 2020年7月

自 Dart 2.0 中用可靠的静态类型系统替换了原有的不完善的可选类型系统以来,空安全是我们对 Dart 做出的最大改动。Dart 最初发布时,编译时空安全还是一项罕见的特性,需要详细讲解。如今,Kotlin、Swift、Rust 和其他语言都针对这个已经非常普遍的问题提供了各自的解决方案。以下是一个示例:

// 无空安全:
bool isEmpty(String string) => string.length == 0;

void main() {
  isEmpty(null);
}

如果运行这段 Dart 程序时没有启用空安全机制,它会在调用 .length 方法时抛出 NoSuchMethodError 异常。因为空值是 Null 类的一个实例,而 Null 类没有 length 方法。运行时错误非常糟糕。对于像 Dart 这样旨在运行在终端用户设备上的语言来说,这一点尤为重要。如果服务器应用程序崩溃,通常可以在用户注意到之前重启它。但是,当 Flutter 应用在​​用户的手机上崩溃时,用户会非常不满意。用户不满意,开发者自然也不会满意。

开发者喜欢像 Dart 这样的静态类型语言,因为它们允许类型检查器在编译时(通常直接在 IDE 中)查找代码中的错误。越早发现 bug,就能越早修复它。当语言设计者谈到“修复空引用错误”时,他们指的是增强静态类型检查器的功能,使语言能够检测到类似上述尝试对可能为空的值调用 .length 的错误。

掌握Flutter状态管理

原文:Mastering State Management in Flutter

想象一下一群书呆子为如何操作数据争吵了五年。这基本上就是 Flutter 社区一直在发生的事情。

五年过去了,关于 GetX 的帖子仍然会引发风暴。我就是那些书呆子之一。所以,我想最后一次狂热一下,然后继续我的生活。这是我关于状态管理的最终结论

最终结论

使用任何你想用的状态管理方案。如果你在意别人用什么,那就找点更好的事情去关心。

我不在乎你用什么。然而,我强烈建议你了解你所使用的工具,并理解如何仅使用 Flutter 提供的工具来管理你的状态

什么是状态?

状态管理这个短语可以分解为一个用于管理你的状态的系统。什么是状态?

状态是一种数据。应用程序中有两种类型的数据:

  • 常规数据(硬编码且无法更改)
  • 状态(可以更改的奇特数据)

一个典型的状态例子是用户信息。例如,你可以在主屏幕上显示 Hello, Tadas,其中 Tadas 这部分信息是从用户信息状态中获取的。假设你有一个设置页面,可以在其中将名称更改为 T-Dog。这将使用新值更新用户信息状态,你的应用将更改为显示 Hello,T-Dog。状态管理解决方案将促进这一更改数据并在整个应用程序中传播这些更改的过程。

其他一些常见的状态例子包括新闻动态、关注者数量、待办事项、倒计时器等。

状态最简单的定义就是可以更改的数据

Material Design 3 (Material You) 完整开发指南

概述与核心变革

Material Design 3(代号 Material You)是 Google 于 2021 年 I/O 大会发布的第三代设计系统,随 Android 12 正式推出。它代表了从"统一设计"到"个性化表达"的范式转变。

与 Material Design 2 的关键差异

特性 Material 2 Material 3
颜色哲学 固定品牌色(Primary/Secondary) 动态个性化(从壁纸/种子色生成)
颜色数量 12个基础色槽 26+个语义化颜色角色
表面层级 阴影海拔(Elevation) 色调表面(Tone-based Surfaces)
排版体系 6种样式(Headline 1-6等) 15种令牌化样式(Display/Headline/Title/Body/Label)
形状系统 固定圆角 7级可配置圆角体系
个性化 核心特性(壁纸取色、算法生成)

核心设计原则

  1. 个性化优先:系统从用户壁纸提取颜色,生成独一无二的主题
  2. 算法驱动美学:基于 HCT 颜色空间的科学算法确保配色和谐
  3. 无障碍内置:所有颜色组合默认满足 WCAG 2.1 AA 对比度标准
  4. 跨平台一致:提供跨平台实现规范,Android(Compose/View)与 Flutter 为官方完整实现,Web 与 iOS 通过 Material Color Utilities 支持配色算法

Flutter布局终极指南:轻松布局 Flutter 组件的唯一指南

原文:The Ultimate Flutter Layout Guide:The only guide you need to layout your Flutter widgets hassle-free

引言

你在构建 Flutter 应用时是否曾被以下错误困扰过?

  • A RenderFlex overflowed…(RenderFlex 溢出…)
  • RenderBox was not laid out(RenderBox 未布局)
  • Viewport was given unbounded height(Viewport 被赋予了无限高度)
  • An InputDecorator …cannot have an unbounded width(InputDecorator 不能拥有无限宽度)
  • Incorrect use of ParentData widget(ParentData 组件使用不正确)

如果答案是肯定的,那么这篇博客文章就是为你准备的!

在这篇博客文章中,我将讨论并分享一些常见的 Flutter 布局场景和最佳实践。我会更多地关注代码片段,而不是组件细节。对于组件详情,我会分享相关链接。

单个子元素布局组件

Align(对齐)

一个将其子组件在其内部对齐的组件,并可选择根据子组件的大小调整自身大小。

Center(
  child: Container(
    height: 120.0,
    width: 120.0,
    color: Colors.blue[50],
    child: const Align(
      alignment: Alignment.topRight,
      child: FlutterLogo(
        size: 60,
      ),
    ),
  ),
)

马修·伯恩斯坦讲线性代数系列:矩阵-向量乘法

原文: Matrix-vector multiplication

引言

上一篇博客文章中,我们讨论了观察矩阵的三种方式:作为值表格、作为向量列表,以及最终作为函数。正是第三种观察矩阵的方式赋予了矩阵真正的力量。在这里,我们将介绍矩阵和向量之间的一种操作,称为矩阵-向量乘法,这将使我们能够将矩阵用作函数。

矩阵-向量乘法是矩阵和向量之间的一种操作,会产生一个新向量。值得注意的是,矩阵-向量乘法仅定义在矩阵和向量之间,其中向量的长度等于矩阵的列数。其定义如下:

定义 1 (矩阵-向量乘法): 给定矩阵 \(\boldsymbol{A} \in \mathbb{R}^{m \times n}\) 和向量 \(\boldsymbol{x} \in \mathbb{R}^n\)\(\boldsymbol{A}\)\(\boldsymbol{x}\)矩阵-向量乘法定义为

\[\boldsymbol{A}\boldsymbol{x} := x_1\boldsymbol{a}_{*,1} + x_2\boldsymbol{a}_{*,2} + \dots + x_n\boldsymbol{a}_{*,n}\]

其中 \(\boldsymbol{a}_{*,i}\)\(\boldsymbol{A}\) 的第 \(i\) 个列向量。

像大多数数学概念一样,矩阵-向量乘法可以从多个角度审视,具有不同程度的抽象性。这些视角在尝试概念化我们利用矩阵-向量乘法来建模现实世界问题时的各种方式时非常有用。以下是我发现用于概念化矩阵-向量乘法的三种方式,按从最不抽象到最抽象排序:

  1. 作为一种“逐行”的向量生成过程: 矩阵-向量乘法定义了一个使用现有向量创建新向量的过程,其中新向量的每个元素是通过使用向量元素作为系数,对矩阵的每一行取加权和而“生成”的。
  2. 作为矩阵列的线性组合: 矩阵-向量乘法是使用向量元素作为系数,对矩阵的列空间取线性组合的过程。
  3. 作为向量空间之间函数的求值: 矩阵-向量乘法允许矩阵定义两个向量空间之间的映射。

Python 项目结构与打包完全指南:从入门到实践

当你完成一个 Python 项目,想要发布到 PyPI 供全球开发者下载时,你是否遇到过这些困惑:

  • pip install 背后到底发生了什么?
  • 为什么安装 beautifulsoup4 却要 import bs4
  • 项目代码应该放在根目录还是 src 目录?
  • python -m builduv build 有什么区别?

本文将从依赖安装的底层机制出发,逐步深入到 WHL 文件构建流程,最后探讨现代化项目结构的最佳实践。无论你是刚接触 Python 打包的新手,还是希望迁移到现代工具链的开发者,这篇文章都能给你清晰的指引。

依赖安装机制:当你执行 pip install 时发生了什么?

软件包从哪来?——PyPI 与 WHL 文件

当你执行 pip install flask 时,工具背后做了三件核心的事:

  1. 查询元数据:向 PyPI(Python Package Index,Python 官方的软件包仓库)请求 flask 的包信息
  2. 下载 WHL 文件:根据你的 Python 版本和操作系统,选择最合适的 .whl 文件下载
  3. 解压安装:将 WHL 文件解压到当前 Python 环境的 site-packages 目录

WHL(Wheel) 是 Python 的二进制分发格式标准(由 PEP 427 定义)。它本质上就是一个 ZIP 压缩包,里面包含了:

  • 预编译的代码(或纯 Python 源代码)
  • 包的元数据(依赖关系、版本信息等)

让我们以 Flask 3.1.1 为例,看看 WHL 文件的真面目:

# 下载 Flask 的 WHL 文件(不安装)
pip download flask==3.1.1 -d ./downloads

# 查看 WHL 内容(WHL 就是 ZIP)
unzip -l ./downloads/flask-3.1.1-py3-none-any.whl

马修·伯恩斯坦讲线性代数系列:矩阵的介绍

原文:Introducing matrices

在这里,我将介绍思考矩阵的三种主要方法。当我在本科线性代数课程中第一次接触到矩阵时,这种对矩阵多方面思考方式的高级描述将帮助我更好地直觉矩阵。

引言

矩阵是线性代数中的基本概念,在科学和工程领域中无处不在。从表面上看,矩阵只是一个二维的值数组。例如,以下是一个矩阵:

\[\begin{bmatrix}1 & -2 & 0 \\ 4 & -3 & 1 \\ 0 & 6 & -2 \end{bmatrix}\]

正如我在上一篇博客文章中讨论的那样,有些概念需要从多个角度观察才能掌握其真实本质。尽管矩阵表面上很简单,但我认为矩阵是其中一个概念,并且我相信,如果一开始就提供对矩阵的高层次、多视角概述,以便为未来的线性代数学习提供背景,那么对于我--大学线性代数课程的二年级学生来说,这会对我有所帮助。在这篇文章中,我将介绍查看矩阵的三个主要角度,这对我以前的自己有帮助。

预备知识

在介绍观察矩阵的三种角度之前,我将介绍一些符号。首先,一个矩阵是一个矩形的值数组。例如,以下矩阵 \(\boldsymbol{A}\)\(m\) 行和 \(n\) 列:

\[\boldsymbol{A} := \begin{bmatrix} a_{1,1} & a_{1,2} & \dots & a_{1,n} \\ a_{2,1} & a_{2,2} & \dots & a_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m,1} & a_{m,2} & \dots & a_{m,n} \end{bmatrix}\]

马修·伯恩斯坦讲线性代数系列:开篇

马修·伯恩斯(Matthew N. Bernstein) 是计算生物学与机器学习领域的研究者,现任 Cellular Intelligence 首席计算科学家。

他于2019年获威斯康星大学麦迪逊分校计算机科学博士学位,本科毕业于圣母大学。此前曾在 Stellaromics 和 Immunitas Therapeutics 担任机器学习与计算生物学科学家,并在 Morgridge Institute 从事博士后研究。Bernstein 专注于将高维基因组学数据转化为可指导人类健康研究的洞见,在空间转录组学、药物靶点识别和深度学习模型开发方面有丰富经验。

他在技术博客中,撰写了大量关于线性代数、变分自编码器、信息论基础等数学与机器学习概念的科普文章,以清晰的数学解释和直观的可视化著称。本系列是从马修的技术博客中筛选出有关线性代数的文章进行翻译后组成的一个合集。

马修·伯恩斯坦讲线性代数系列目录如下:

Golang源码分析系列之Map底层实现

映射也被称为哈希表(hash table)、字典。它是一种由key-value组成的抽象数据结构。大多数情况下,它都能在O(1)的时间复杂度下实现增删改查功能。若在极端情况下出现所有key都发生哈希碰撞时则退回成链表形式,此时复杂度为O(N)。

映射底层一般都是由数组组成,该数组每个元素称为桶,它使用hash函数将key分配到不同桶中,若出现碰撞冲突时候,则采用链地址法(也称为拉链法)或者开放寻址法解决冲突。下图就是一个由姓名-号码构成的哈希表的结构图:

Go语言中映射中key若出现冲突碰撞时候,则采用链地址法解决,Go语言中映射具有以下特点:

  • 引用类型变量
  • 读写并发不安全
  • 遍历结果是随机的

数据结构

Go语言中映射的数据结构是runtime.hmap(runtime/map.go):

// A header for a Go map.
type hmap struct {
    count     int //  元素个数,用于len函数返回map元素数量
    flags     uint8 // 标志位,标志当前map正在写等状态
    B         uint8  // buckets个数的对数,即桶数量 = 2 ^ B
    noverflow uint16 // overflow桶数量的近似值,overflow桶即溢出桶,即链表法中存在链表上的桶的个数
    hash0     uint32 // 随机数种子,用于计算key的哈希值

    buckets    unsafe.Pointer // 指向buckets数组,如果元素个数为0时,该值为nil
    oldbuckets unsafe.Pointer // 扩容时指向旧的buckets
    nevacuate  uintptr        // 用于指示迁移进度,小于此值的桶已经迁移完成

    extra *mapextra // 额外记录overflow桶信息
}