2026年4月

原文:Porting Our Software to ARM64,作者 Alexander Huynh,Cloudflare Blog。

ARM64 服务器这几年越来越普遍。AWS 的 Graviton、Ampere 的 Altra,包括苹果 M 系列芯片的 Mac,都在把 ARM 架构从移动端推向数据中心和开发者桌面。对于只跑过 x86 的团队来说,迁移这件事听起来简单,做起来往往不是那么回事。

这篇文章是 Cloudflare 工程师 Alexander Huynh 在 2018 年写下的迁移记录,记录了他们把整个边缘软件栈迁移到 ARM64 的过程——包括用了哪些方法,碰了哪些壁,最后怎么解决的。虽然时间稍早,但里面的问题和思路到今天都有参考价值。


规模有多大

要理解这件事的难度,先看看 Cloudflare 的软件栈有多厚。

底层是 Linux 内核,发行版选的是 Debian,往上是他们自己维护的数百个软件包,其中一部分是基于开源项目做了定制,另一部分是完全内部开发的。编程语言横跨 C、C++、Go、Lua、Python、Rust 六种。

好消息是,ARM64 的生态支持已经相当成熟。Linux 内核很早就支持 ARM64,Debian 从 Stretch 版本(2017 年)起把 ARM64 列为一类发行架构,这意味着操作系统本身能比较顺滑地跑起来。真正的工作量在于让那数百个内部包也在 ARM64 上正确构建和运行。


两条主路:Go 和 Rust 的交叉编译

对于 Go 和 Rust,情况相对乐观,两个语言都有成熟的跨平台交叉编译支持。

Go 的迁移方式

Go 官方把 ARM64 列为一类支持架构,交叉编译只需要在 Debian 上额外安装 crossbuild-essential-arm64,然后把原来的 go build 替换为:

GOARCH=arm64 CGO_ENABLED=1 go build

注意 CGO_ENABLED=1 是必须显式指定的,因为交叉编译时 Go 默认会关掉 cgo。他们的做法是把原来的单次构建改成一个循环,同时为 amd64arm64 各跑一遍,产出的二进制再跑测试框架验证。

Rust 的迁移方式

Rust 的交叉编译支持同样完善。同样先安装 crossbuild-essential-arm64,然后在 cargo buildrustc 里指定 --target aarch64-unknown-linux-gnu 即可。

唯一需要留意的地方:如果你的包依赖了很多第三方 crate,每一个 crate 都需要能正确交叉编译。依赖树越深,碰到问题 crate 的概率就越高。


第三条路:QEMU 用户态仿真

C、C++ 以及其他一些语言在交叉编译时就没那么顺了——调 CCLD 各种环境变量往往费时费力,还不一定能覆盖所有情况。

他们选择的方案是 QEMU 用户态仿真(user-space emulation),核心思路是:不去改动构建工具链,而是提供一个仿真层,让 x86 机器(包括开发者的 MacBook)能直接"运行" ARM64 程序。

具体实现借助了 Docker。目标是让开发者能直接 docker run 进入一个 ARM64 环境,就像这样:

host$ uname -m
x86_64
host$ docker run --rm -it stretch-arm64/master:latest
guest# uname -m
aarch64

在 x86 的宿主机上,uname -m 输出 aarch64,仿真层对开发者完全透明。

实现方式的关键在于一个打了补丁的 qemu-user。这个补丁让 QEMU 在每次 execve 系统调用时自动把仿真器前置进去,效果类似于 Linux 内核的 binfmt_misc 机制——每个新进程都会被自动带入仿真环境,整个容器因此形成一个自洽的 ARM64 沙盒。

Dockerfile 的核心结构是这样的:

# 内部构建的带补丁 QEMU
FROM qemu-aarch64/master:latest as qemu

# ARM64 版 Debian 基础镜像
FROM arm64v8/debian@sha256:841bbe...

# 把仿真器复制进来,设为 ENTRYPOINT
COPY --from=qemu /qemu-aarch64 /qemu-aarch64
ENTRYPOINT ["/qemu-aarch64", "--execve", "/qemu-aarch64"]

有了这个镜像,99% 以上的内部代码库都能在仿真环境里正常构建和测试。


真正让人头疼的:四个技术坑

方案看起来很美,但落地时碰到了几个有意思的问题。

坑一:环境变量失效

开发者最早反映的问题之一是 LD_LIBRARY_PATH 不生效。排查之后发现问题不只是这一个变量——所有通过命令行或 export 设置的环境变量,都无法传递进 qemu-user 进程。

根源是 Dockerfile 里的一行 setcap

RUN setcap cap_setuid,cap_setgid+ep /qemu-aarch64

这行命令是为了让容器内的 sudo 能正常工作,但它同时阻断了环境变量的透传。两个需求直接冲突,没有两全的解法,最终只能告知开发者:在容器内,sudo 和环境变量传递只能选其一。

坑二:Go 程序不定时崩溃

CI 系统里跑了大量 Go 代码,很快发现一个规律:Go 程序会以不可预测的间隔发生 segfault。

定位到原因是 Go 运行时与 QEMU 的多线程兼容性问题。Go 的 goroutine 调度器会自由地把 goroutine 分配到不同系统线程上,而 QEMU 的用户态仿真在处理多线程时存在已知问题,上游也明确表示短期内不会修复。

他们的解决方案很实用:在 Go 二进制的 .deb 安装后脚本里,检测当前是否处于 ARM64 仿真环境,如果是,就通过 taskset 把进程限制为只使用单个 CPU:

# 检测是否在 ARM64 仿真下运行
if [ "$(uname -m)" = "aarch64" ] && [ "$(uname -r | grep -c qemu)" -gt 0 ]; then
    taskset -c 0 "$@"
fi

单核运行性能有损耗,但在仿真环境里本来就慢,慢点跑总比随机崩强。加了这个限制之后,随机崩溃降为零。

坑三:动态库加载顺序不一致

Cloudflare 有一个习惯:不覆盖系统目录 /usr/lib 下的库,而是把自己的最新版本装在 /usr/local/lib,保持系统库的稳定性。

这套方案在 x86 上工作了很久,到 ARM64 就出了问题:有团队反映 ARM64 版本的程序无法加载正确的动态库符号。

排查下来,发现根因藏在 Debian 的一个细节里。动态链接器通过 /etc/ld.so.conf.d/ 目录下的文件来确定库的搜索顺序,而这个目录是按文件名字母序遍历的。

在 x86_64 机器上,目录内容是:

libc.conf          ← 含 /usr/local/lib,字母序靠前,先搜索
x86_64-linux-gnu.conf  ← 含 /usr/lib/x86_64-linux-gnu,后搜索

在 ARM64 机器上,目录内容变成了:

aarch64-linux-gnu.conf  ← 含 /usr/lib/aarch64-linux-gnu,字母序靠前,先搜索
libc.conf               ← 含 /usr/local/lib,后搜索

a 排在 l 前面——这个字母序的差异,导致 ARM64 上系统库的优先级高于 /usr/local/lib,而 x86 上恰好相反。同样的代码,行为截然不同。

解决方案是不动系统配置,改为在链接器参数里显式加 --rpath /usr/local/lib,强制运行时先从这里搜索。

值得一提的是,这个问题在仿真环境和物理 ARM64 机器上都存在,说明仿真层在这一点上是忠实地复现了真实环境的行为。

坑四:少数包仍然需要原生编译

99% 的包通过交叉编译或仿真解决了,剩下的 1% 是真正的硬骨头。

llvm 为例,它的构建高度并行化,在原生 x86 机器上跑得很快,但一旦套上仿真层,并行度反而成了负担,构建时间超过 6 小时。还有一些包调用了 QEMU 尚未实现的系统调用,直接失败。

对这部分包,他们的选择是给开发者分配少量真实的 ARM64 机器,以及一台专用的原生 ARM64 CI 节点。这样做的代价是从可用机器池里划走了一些资源,但对于长尾问题来说,这是性价比最高的处理方式。


如何推动整个工程团队跟进

技术方案定了之后,还有一个不小的工程管理问题:数百个包分散在几十个团队手里,怎么让大家都动起来。

初期由移植团队承包了所有包的 ARM64 构建工作,同时与各包的维护者密切协作,在代码变动时保持同步。等 ARM64 平台被评估为生产就绪之后,他们整理了一套自助操作文档,向全工程部门发出了"把 ARM64 作为一等公民支持"的要求,之后各个团队自行负责自己包的 ARM64 兼容性。


这件事给出的几个判断

回顾整个迁移过程,有几个判断值得记下来。

交叉编译能解决大多数问题,但不是万能的。 Go 和 Rust 的交叉编译体验已经很好,但仍然有依赖、crate 兼容性等边界情况。对于 C/C++ 这类语言,交叉编译工具链的配置复杂度明显更高。

仿真层是务实的折中。 QEMU 用户态仿真让团队不需要为每个开发者配一台 ARM64 机器,大幅降低了迁移成本。代价是引入了一些仿真特有的问题(环境变量透传、多线程不稳定),需要有人专门去踩和处理。

架构差异往往藏在细节里。 动态库搜索顺序这个问题,在 x86 上完全感知不到,到 ARM64 就直接导致运行失败。这类问题不是逻辑 bug,而是对平台差异不够了解的结果,只有在真实的 ARM64 环境下跑才能暴露。

原生编译始终是最可靠的。 仿真和交叉编译都是务实的过渡手段。长期来看,随着 ARM64 开发机和 CI 机器越来越普及,直接在原生环境里编译和测试,才是最终的稳态。


2025 年 12 月 13 日,VeloxCon China 2025 在北京成功举办。作为 Velox 项目首次在中国举办的线下技术大会,汇聚了来自Meta、IBM、蚂蚁集团、阿里云、腾讯、小米、小红书等企业的数十位核心贡献者与一线工程师。

大会通过 18 场演讲将 Velox 置于真实业务场景之中,系统展示了其在架构演进、AI 数据处理、湖仓加速、流批融合等方向的最新实践。这些分享不仅直面性能、稳定性与兼容性等落地挑战,也反应了开发者社区对构建可靠、可扩展、可协同的数据基础设施的共同探索,彰显了中国开发者在全球高性能分析生态中的工程深度与协作广度。

夯实底座,突破能力边界
会议伊始,Velox 项目联合发起人 Pedro 发表开幕致辞。他回顾了 Velox 开源项目的发展历程,从项目启动、开源发布到建立技术治理结构,展示了 Axiom 架构、GPU 支持、PyVelox 等关键进展,强调了社区协作与工程严谨性是项目持续演进的核心动力。他特别提到,Velox 已建立了正式的技术治理机制,并迎来来自 IBM、Intel、NVIDIA、Microsoft 等多家企业的新增维护者,标志着项目正迈向更加开放和可持续的阶段。

在明确了社区与架构演进的总体方向后,大会议题迅速深入到如何利用 Velox 构建高性能计算引擎的具体实践中。阿里云 EMR Serverless Spark 技术负责人周克勇系统阐述了“可组合性”在数据计算领域的实践。他详细解析了阿里云如何深度集成并贡献于 Apache Celeborn、Paimon、Velox 及 Gluten 等开源组件,通过模块化组装构建出高性能湖仓一体引擎。他指出,基于该架构,阿里云 EMR Serverless Spark 成功创造了 TPC-DS 100TB 规模性能测试的世界新纪录,实现性能翻倍与性价比大幅提升。

接着,Meta 软件工程师 Masha Basmanova 阐述了现有查询引擎在跨语言通信、优化器能力与开发体验上面临的挑战,并介绍了基于 C++ 的统一前端框架 Axiom。该框架将 SQL 解析、逻辑优化与物理执行融为一体,通过内置的强大优化器与 Velox 运行时无缝对接,能够实现更高效、可扩展的查询处理。演讲最后,她积极展示了 Axiom 的开源路线图,并欢迎全球开发者加入,共同推动该项目的演进。

强大的执行框架,最终需要服务于极具挑战性的数据场景,特别是爆发式增长的 AI 数据。Meta 软件工程师孟晓烜则在之后的演讲中,深入阐述了应对AI训练数据规模激增与成本挑战的解决方案。他重点介绍了 Meta 如何通过数据归一化技术剥离重复特征,并构建可索引的序列存储系统。依托 Velox 技术栈,团队在训练数据的加载、生成与探索三大环节实现了端到端优化,显著提升了处理效率与资源利用率。

在 Meta 多位工程师从框架演进、可组合架构、数据标准化等角度深入分享后,蚂蚁集团高级技术专家黄叶伟也从企业落地实践层面分享了基于 Velox 的 Spark 加速实践。他重点介绍了基于 Gluten 与 Velox 构建的向量化引擎如何通过任务级 Fallback、Spill 优化、Shuffle 优化等关键技术,在混合部署场景下显著提升 Spark 性能与稳定性。他表示,该方案目前已实现日均数十万任务覆盖,平均节省资源超30%,并将在算子优化与架构扩展方面持续演进。

作为连接 Spark 生态与原生加速的关键中间层,Apache Gluten 的进展同样备受关注。来自 IBM 的莫芮与周渊聚焦 Apache Gluten与 Velox 的深度集成,阐述了其如何在大数据分析中驱动创新。他们介绍,Gluten 在保持对 Spark/Flink 作业透明加速能力的同时,正逐步增强对多后端引擎和复杂业务场景的适配能力。目前,该方案已在 Pinterest、顺丰科技及多个内部集群完成规模化验证,有效支撑了从日志分析到物流调度等多样化负载的性能提升与成本优化。

随着向量化加速在通用场景日趋成熟,针对特定存储格式的深度优化成为新的效能突破口。腾讯大数据开发工程师陈锦海分享了微信基于 Velox 加速 lceberg 湖仓分析的优化与实践,重点介绍了原生分桶方案。据他介绍,该方案通过动态识别表元信息自动设置分区数,能有效缓解 AQE 引发的写入倾斜,结合空闲资源灰度发布策略,可保障大规模作业的稳定上线。

扎根场景,释放协同效能
午餐后的议程更加聚焦 Velox 在真实业务中的集成深度与生产韧性,回应了开发者们对兼容性、稳定性与端到端效能等规模化落地的核心关切。
小米计算平台计算引擎负责人王胜杰分享了公司在 Spark 向量化升级中的规模化落地经验。面对业务迁移中的兼容性与稳定性挑战,他表示,小米通过自动兼容校验、双跑结果比对及内存异常感知的三级资源升级机制,已成功推动向量化改造在数十万作业中平稳落地。

面对海量数据挑战,全球科技公司也在探索相似的演进路径。Meta 软件工程经理 Stanley Yao 在演讲中分享了公司基于 Velox 推进 Spark 向量化改造的整体策略。他表示,团队通过从定制化方案到开源架构的持续演进,已实现关键业务管线向 Gluten(Flare)的平稳迁移,并获得显著的效率提升。未来,Meta 计划进一步扩大该架构的应用规模。

在 CPU 向量化趋于普及的同时,利用异构硬件挖掘更高性能成为新的前沿。IBM 研究院资深软件工程师 Zoltán Arnold Nagy 展示了基于 Velox 与 Presto 的 GPU 加速数据处理方案。他介绍道,Velox 通过与 cuDF 集成,可在 GPU 上高效执行算⼦,并针对多 GPU 分布式场景优化通信与数据交换。此外,为突破 I/O 瓶颈,团队正在探索结合 GPUDirect 存储与缓存层的加速策略。

对性能与稳定性的追求,也驱动着查询引擎架构本身的融合与创新。Meta 软件工程师谭家梁与大家分享了 Native Presto-on-Spark 的规模化应用。该架构以 Presto 查询优化、Spark 资源调度与容错机制以及 Velox 原生向量化执行为核心,实现了性能与可靠性的显著提升。他表示,目前该方案已在生产环境中取得成效,并将在未来持续推进全栈原生化演进。

对于国内庞大的云上业务,Velox 同样在支撑着关键数据服务平台。 阿里云高级工程师王彬与范阿冬系统介绍了Velox在阿里云日志服务中的深度集成与应用。他们指出,基于 Velox 构建的高性能查询引擎,通过混合执行、表达式下推、自动增量物化视图及免 Schema 分析等核心技术,可显著提升平台在处理海量实时数据时的查询效率与资源利用率。他们还强调,该架构不仅为日志分析、智能运维等场景提供了稳定支撑,也为面向 AI 的云原生数据平台演进奠定了坚实基础。

除了通用的日志与湖仓分析,Velox 也在向更垂直的时序数据场景渗透。腾讯高级工程师李兆龙分享了基于 Velox 构建云原生时序数据库的落地经验。他表示,通过在 Velox 中实现时序数据去重优化与存储写入增强,系统在应对高频写入与实时查询场景时,可显著提升吞吐效率与响应性能。目前该方案已有效支持物联网、实时监控等业务场景,未来还将进一步完善缓存与压缩机制,持续优化时序数据处理的整体效能。

IBM 软件工程师刘平接着分享了 Velox 在 Iceberg 数据写入能力上的突破性进展。他表示,目前 Velox 对 Iceberg 的支持以读取为主,其写入功能的完善将填补该方向的关键能力空白,为基于 Presto 与 Spark 的数据湖架构提供更统一、高效的数据摄入层。这一进展也标志着 Velox 正从查询加速向数据全链路处理拓展。

接着,来自阿里云的毕岩与周滔分享了 Velox 与 Apache Paimon 深度集成的解决方案,为提升引擎与存储的协同效率提供了另一种集成思路。在他们看来,现有方案存在表类型支持受限、缺乏可移植性等瓶颈, 但可以建立 C++ 原生 Paimon 库,通过其统一的数据协议与插件化设计,使 Paimon 能够被 Velox、StarRocks 等多种计算引擎直接高效调用,从而提升数据读写性能,并为湖仓格式的跨引擎协同提供新的基础支撑。

在批处理场景之外,流计算框架的向量化也正成为新的热点。蚂蚁集团技术专家刘勇介绍了基于 Velox 为 Flink 构建的统一向量化执行引擎 Flex。他表示,Flink 作为流批一体架构的核心,其原生向量化能力的补足至关重要。Flex 通过将 Velox 的高性能算子能力引入 Flink,同时结合自动化验证、可视化计划与精细化回退机制,现已实现了作业性能的显著提升,并支撑多条核心业务链路平稳运行。

随着 Velox 赋能的应用场景日益广泛和复杂,确保其在不同引擎和版本间的整体质量与可靠性变得至关重要。Meta 软件工程师 Eric Liu 阐述了在 AI 数据基础架构下,保障 Velox 多引擎版本可靠性的系统化方法。他指出,面对不同引擎与存储格式交织带来的复杂性,关键在于建立跨引擎测试框架与合成数据工厂。这一实践能有效提前发现全栈潜在问题,从而确保底层变更在大规模生产环境中的稳定与高效。

针对向量化引擎中窗口运算符内存溢出的典型难题,来自英特尔的贾柯分享了她的见解。她认为,通过为 Velox 引入流式窗口处理机制,可使计算随数据到达逐步执行并即时释放内存,从而从架构层面化解多数场景下的内存风险,显著提升复杂查询的稳定性。

最后,小红书 Native Engine 团队技术负责人魏秀利也分享了向量化引擎在公司业务中规模化落地的经验。据他介绍,通过将写入异步化并构建原生 Avro 读取能力,小红书在不增加业务复杂度的前提下,成功缓解了端到端延迟,印证了“执行与存储协同优化”在湖仓场景中的关键价值。

从底层执行引擎的持续创新,到日志分析、湖仓写入、流批融合等复杂场景的稳定运行,在本届 VeloxCon China 上,我们看到 Velox 的技术价值已在真实业务中不断被验证和拓展。同时我们也很高兴看到中国开发者成为这一进程的重要推动者。期待未来有更多志同道合者加入 Velox 开源社区,共建高性能分析基础设施。个weibo.com/ttarticle/p/show?id=2309405291528033009787 weibo.com/ttarticle/p/show?id=2309405291528422817972 weibo.com/ttarticle/p/show?id=2309405291528926396638 weibo.com/ttarticle/p/show?id=2309405291529341632764 weibo.com/ttarticle/p/show?id=2309405291529744286013 weibo.com/ttarticle/p/show?id=2309405291530155327704 weibo.com/ttarticle/p/show?id=2309405291530553786371 weibo.com/ttarticle/p/show?id=2309405291531048452333 weibo.com/ttarticle/p/show?id=2309405291531442716678

Install Virtualbox on macOS

VirtualBox 是一个流行的跨平台虚拟机管理器,它允许您在 Mac 上创建虚拟机,虚拟机可以用来运行同时运行不同的操作系统。它们可以用来隔离测试软件,而不会危及真实的计算机。

VirtualBox 可以在 Windows、macOS 和 Linux 上运行,并支持各种操作系统。这篇博文将介绍如何在 macOS 系统上安装 VirtualBox 软件。

Install VirtualBox

前往 https://www.virtualbox.org/wiki/Downloads 下载页,下载最新的 macOS 版的 VirutalBox,根据您的 CPU (Intel 或 Arm66)下载软件包。

Downloading VirtualBox Package for macOS

下载完成后,点击文件执行安装

Begin the VirtualBox installation
启动安装向导,点击“Continue”按钮继续

Installing VirtualBox on macOS

您可以通过单击“Change Install Location”更改安装位置。要使用默认安装位置,只需单击“Install”按钮。

Input Admin credentials

输入登录凭据以授权安装,然后单击“Install Software”按钮继续安装过程。

Installing VirtualBox on macOS

安装成功后,您将看到如下画面。

Successful Installation of VirtualBox on macOS

Install VirtualBox Extension Pack

VirtualBox 使用扩展包提供了额外的功能。例如,它允许使用物理 USB(2.0 和 3.0)设备连接到主机。它还允许您访问 Webcam 和 VirtualBox 远程桌面(VRDP)协议。

进入 VirtualBox 扩展包下载页面,下载与 VirtualBox 版本一致的扩展包版本。

Download VirtualBox Extension Pack on macOS

接下来,终端执行以下命令来安装扩展包。

sudo VBoxManage extpack install Downloads/Oracle_VM_VirtualBox_Extension_Pack-7.0.0.vbox-extpack

我的开源项目

酷瓜云课堂-开源知识付费解决方案

2025 年 12 月 13 日,VeloxCon China 2025 在北京成功举办。作为 Velox 项目首次在中国举办的线下技术大会,汇聚了来自Meta、IBM、蚂蚁集团、阿里云、腾讯、小米、小红书等企业的数十位核心贡献者与一线工程师。

大会通过 18 场演讲将 Velox 置于真实业务场景之中,系统展示了其在架构演进、AI 数据处理、湖仓加速、流批融合等方向的最新实践。这些分享不仅直面性能、稳定性与兼容性等落地挑战,也反应了开发者社区对构建可靠、可扩展、可协同的数据基础设施的共同探索,彰显了中国开发者在全球高性能分析生态中的工程深度与协作广度。

夯实底座,突破能力边界
会议伊始,Velox 项目联合发起人 Pedro 发表开幕致辞。他回顾了 Velox 开源项目的发展历程,从项目启动、开源发布到建立技术治理结构,展示了 Axiom 架构、GPU 支持、PyVelox 等关键进展,强调了社区协作与工程严谨性是项目持续演进的核心动力。他特别提到,Velox 已建立了正式的技术治理机制,并迎来来自 IBM、Intel、NVIDIA、Microsoft 等多家企业的新增维护者,标志着项目正迈向更加开放和可持续的阶段。

在明确了社区与架构演进的总体方向后,大会议题迅速深入到如何利用 Velox 构建高性能计算引擎的具体实践中。阿里云 EMR Serverless Spark 技术负责人周克勇系统阐述了“可组合性”在数据计算领域的实践。他详细解析了阿里云如何深度集成并贡献于 Apache Celeborn、Paimon、Velox 及 Gluten 等开源组件,通过模块化组装构建出高性能湖仓一体引擎。他指出,基于该架构,阿里云 EMR Serverless Spark 成功创造了 TPC-DS 100TB 规模性能测试的世界新纪录,实现性能翻倍与性价比大幅提升。

接着,Meta 软件工程师 Masha Basmanova 阐述了现有查询引擎在跨语言通信、优化器能力与开发体验上面临的挑战,并介绍了基于 C++ 的统一前端框架 Axiom。该框架将 SQL 解析、逻辑优化与物理执行融为一体,通过内置的强大优化器与 Velox 运行时无缝对接,能够实现更高效、可扩展的查询处理。演讲最后,她积极展示了 Axiom 的开源路线图,并欢迎全球开发者加入,共同推动该项目的演进。

强大的执行框架,最终需要服务于极具挑战性的数据场景,特别是爆发式增长的 AI 数据。Meta 软件工程师孟晓烜则在之后的演讲中,深入阐述了应对AI训练数据规模激增与成本挑战的解决方案。他重点介绍了 Meta 如何通过数据归一化技术剥离重复特征,并构建可索引的序列存储系统。依托 Velox 技术栈,团队在训练数据的加载、生成与探索三大环节实现了端到端优化,显著提升了处理效率与资源利用率。

在 Meta 多位工程师从框架演进、可组合架构、数据标准化等角度深入分享后,蚂蚁集团高级技术专家黄叶伟也从企业落地实践层面分享了基于 Velox 的 Spark 加速实践。他重点介绍了基于 Gluten 与 Velox 构建的向量化引擎如何通过任务级 Fallback、Spill 优化、Shuffle 优化等关键技术,在混合部署场景下显著提升 Spark 性能与稳定性。他表示,该方案目前已实现日均数十万任务覆盖,平均节省资源超30%,并将在算子优化与架构扩展方面持续演进。

作为连接 Spark 生态与原生加速的关键中间层,Apache Gluten 的进展同样备受关注。来自 IBM 的莫芮与周渊聚焦 Apache Gluten与 Velox 的深度集成,阐述了其如何在大数据分析中驱动创新。他们介绍,Gluten 在保持对 Spark/Flink 作业透明加速能力的同时,正逐步增强对多后端引擎和复杂业务场景的适配能力。目前,该方案已在 Pinterest、顺丰科技及多个内部集群完成规模化验证,有效支撑了从日志分析到物流调度等多样化负载的性能提升与成本优化。

随着向量化加速在通用场景日趋成熟,针对特定存储格式的深度优化成为新的效能突破口。腾讯大数据开发工程师陈锦海分享了微信基于 Velox 加速 lceberg 湖仓分析的优化与实践,重点介绍了原生分桶方案。据他介绍,该方案通过动态识别表元信息自动设置分区数,能有效缓解 AQE 引发的写入倾斜,结合空闲资源灰度发布策略,可保障大规模作业的稳定上线。

扎根场景,释放协同效能
午餐后的议程更加聚焦 Velox 在真实业务中的集成深度与生产韧性,回应了开发者们对兼容性、稳定性与端到端效能等规模化落地的核心关切。
小米计算平台计算引擎负责人王胜杰分享了公司在 Spark 向量化升级中的规模化落地经验。面对业务迁移中的兼容性与稳定性挑战,他表示,小米通过自动兼容校验、双跑结果比对及内存异常感知的三级资源升级机制,已成功推动向量化改造在数十万作业中平稳落地。

面对海量数据挑战,全球科技公司也在探索相似的演进路径。Meta 软件工程经理 Stanley Yao 在演讲中分享了公司基于 Velox 推进 Spark 向量化改造的整体策略。他表示,团队通过从定制化方案到开源架构的持续演进,已实现关键业务管线向 Gluten(Flare)的平稳迁移,并获得显著的效率提升。未来,Meta 计划进一步扩大该架构的应用规模。

在 CPU 向量化趋于普及的同时,利用异构硬件挖掘更高性能成为新的前沿。IBM 研究院资深软件工程师 Zoltán Arnold Nagy 展示了基于 Velox 与 Presto 的 GPU 加速数据处理方案。他介绍道,Velox 通过与 cuDF 集成,可在 GPU 上高效执行算⼦,并针对多 GPU 分布式场景优化通信与数据交换。此外,为突破 I/O 瓶颈,团队正在探索结合 GPUDirect 存储与缓存层的加速策略。

对性能与稳定性的追求,也驱动着查询引擎架构本身的融合与创新。Meta 软件工程师谭家梁与大家分享了 Native Presto-on-Spark 的规模化应用。该架构以 Presto 查询优化、Spark 资源调度与容错机制以及 Velox 原生向量化执行为核心,实现了性能与可靠性的显著提升。他表示,目前该方案已在生产环境中取得成效,并将在未来持续推进全栈原生化演进。

对于国内庞大的云上业务,Velox 同样在支撑着关键数据服务平台。 阿里云高级工程师王彬与范阿冬系统介绍了Velox在阿里云日志服务中的深度集成与应用。他们指出,基于 Velox 构建的高性能查询引擎,通过混合执行、表达式下推、自动增量物化视图及免 Schema 分析等核心技术,可显著提升平台在处理海量实时数据时的查询效率与资源利用率。他们还强调,该架构不仅为日志分析、智能运维等场景提供了稳定支撑,也为面向 AI 的云原生数据平台演进奠定了坚实基础。

除了通用的日志与湖仓分析,Velox 也在向更垂直的时序数据场景渗透。腾讯高级工程师李兆龙分享了基于 Velox 构建云原生时序数据库的落地经验。他表示,通过在 Velox 中实现时序数据去重优化与存储写入增强,系统在应对高频写入与实时查询场景时,可显著提升吞吐效率与响应性能。目前该方案已有效支持物联网、实时监控等业务场景,未来还将进一步完善缓存与压缩机制,持续优化时序数据处理的整体效能。

IBM 软件工程师刘平接着分享了 Velox 在 Iceberg 数据写入能力上的突破性进展。他表示,目前 Velox 对 Iceberg 的支持以读取为主,其写入功能的完善将填补该方向的关键能力空白,为基于 Presto 与 Spark 的数据湖架构提供更统一、高效的数据摄入层。这一进展也标志着 Velox 正从查询加速向数据全链路处理拓展。

接着,来自阿里云的毕岩与周滔分享了 Velox 与 Apache Paimon 深度集成的解决方案,为提升引擎与存储的协同效率提供了另一种集成思路。在他们看来,现有方案存在表类型支持受限、缺乏可移植性等瓶颈, 但可以建立 C++ 原生 Paimon 库,通过其统一的数据协议与插件化设计,使 Paimon 能够被 Velox、StarRocks 等多种计算引擎直接高效调用,从而提升数据读写性能,并为湖仓格式的跨引擎协同提供新的基础支撑。

在批处理场景之外,流计算框架的向量化也正成为新的热点。蚂蚁集团技术专家刘勇介绍了基于 Velox 为 Flink 构建的统一向量化执行引擎 Flex。他表示,Flink 作为流批一体架构的核心,其原生向量化能力的补足至关重要。Flex 通过将 Velox 的高性能算子能力引入 Flink,同时结合自动化验证、可视化计划与精细化回退机制,现已实现了作业性能的显著提升,并支撑多条核心业务链路平稳运行。

随着 Velox 赋能的应用场景日益广泛和复杂,确保其在不同引擎和版本间的整体质量与可靠性变得至关重要。Meta 软件工程师 Eric Liu 阐述了在 AI 数据基础架构下,保障 Velox 多引擎版本可靠性的系统化方法。他指出,面对不同引擎与存储格式交织带来的复杂性,关键在于建立跨引擎测试框架与合成数据工厂。这一实践能有效提前发现全栈潜在问题,从而确保底层变更在大规模生产环境中的稳定与高效。

针对向量化引擎中窗口运算符内存溢出的典型难题,来自英特尔的贾柯分享了她的见解。她认为,通过为 Velox 引入流式窗口处理机制,可使计算随数据到达逐步执行并即时释放内存,从而从架构层面化解多数场景下的内存风险,显著提升复杂查询的稳定性。

最后,小红书 Native Engine 团队技术负责人魏秀利也分享了向量化引擎在公司业务中规模化落地的经验。据他介绍,通过将写入异步化并构建原生 Avro 读取能力,小红书在不增加业务复杂度的前提下,成功缓解了端到端延迟,印证了“执行与存储协同优化”在湖仓场景中的关键价值。

从底层执行引擎的持续创新,到日志分析、湖仓写入、流批融合等复杂场景的稳定运行,在本届 VeloxCon China 上,我们看到 Velox 的技术价值已在真实业务中不断被验证和拓展。同时我们也很高兴看到中国开发者成为这一进程的重要推动者。期待未来有更多志同道合者加入 Velox 开源社区,共建高性能分析基础设施。个weibo.com/ttarticle/p/show?id=2309405291406926676034 weibo.com/ttarticle/p/show?id=2309405291407303901581 weibo.com/ttarticle/p/show?id=2309405291407681388881 weibo.com/ttarticle/p/show?id=2309405291514149863444 weibo.com/ttarticle/p/show?id=2309405291514539671581 weibo.com/ttarticle/p/show?id=2309405291514921615372 weibo.com/ttarticle/p/show?id=2309405291515307491368 weibo.com/ttarticle/p/show?id=2309405291515684716867 weibo.com/ttarticle/p/show?id=2309405291516175712409

原文:Cloudflare Argo Tunnel with Rust+Raspberry Pi,作者 Steven Pack

家里有一块吃灰的树莓派,一直想用来跑点什么,但总绕不开两个问题:家庭宽带没有固定 IP,路由器也不想随便开放端口。

这篇文章记录的,就是 Cloudflare 一位工程师的实验:把树莓派、Rust 异步 Web 框架和 Cloudflare Tunnel 三者结合起来,在完全不动路由器、不配 DNS 记录的前提下,把树莓派上的 Web 服务暴露到公网。

整个过程出乎意料地顺滑。


问题在哪里

想让家里的机器对外提供服务,传统方式大概有这几条路:

  • 动态域名解析(DDNS):家庭宽带 IP 会变,得在路由器上跑一个 DDNS 客户端,不稳定,配置也烦琐
  • 端口映射:在路由器上开放指定端口转发到内网机器,等于把内网暴露了一个口子,有安全风险
  • 租云服务器:花钱,而且家里的树莓派就成了摆设

Cloudflare Tunnel(原名 Argo Tunnel)的思路完全不同:让内网机器主动向外建立一条持久连接,流量通过这条连接进来,不需要任何入站规则。


原理:反向隧道

整个架构用一句话描述就是:

树莓派上的 cloudflared 客户端,向最近的 Cloudflare 节点建立一条出站的 HTTP/2 长连接;当外网用户请求你的域名时,Cloudflare 把请求通过这条连接反向推送给树莓派,树莓派处理后再原路返回。

几个关键点:

  • 流量方向是"出站"的。树莓派只需要能访问外网,不需要任何端口对外开放
  • 安全性由证书保证cloudflared 登录时会生成一个证书文件(cert.pem),隧道连接用它来做身份验证
  • Cloudflare 负责域名解析和 HTTPS。你只需要有一个托管在 Cloudflare 上的域名,其余的它帮你搞定

准备工作

需要以下几样东西:

  • 一块树莓派(作者用的是 Raspberry Pi 3 Model B),已安装 Raspbian
  • 一个托管在 Cloudflare 的域名
  • 树莓派能正常访问外网

确认树莓派联网正常,最简单的方法是 curl 一下:

curl -I https://www.cloudflare.com

看到 HTTP/2 200 就说明出站连接没问题。


第一步:安装 cloudflared

cloudflared 是 Cloudflare 提供的隧道客户端。树莓派是 ARM 架构,需要下载对应版本:

wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
mkdir argo-tunnel
tar -xvzf cloudflared-stable-linux-arm.tgz -C ./argo-tunnel
cd argo-tunnel
./cloudflared --version

如果看到版本号输出,就说明可以正常运行了。


第二步:登录并授权域名

运行登录命令:

./cloudflared login

它会输出一个 URL,让你在浏览器里打开(因为树莓派是无头环境,复制到自己的电脑浏览器里打开就行)。登录 Cloudflare 账号后,选择你想用来建隧道的域名,点击授权。

授权成功后,树莓派控制台会显示:

You have successfully logged in.
If you wish to copy your credentials to a server, they have been saved to:
/home/pi/.cloudflared/cert.pem

这个 cert.pem 就是隧道的凭证文件,后续都会用到它。


第三步:用内置 Hello World 验证隧道

在正式部署自己的服务之前,先用 cloudflared 自带的 Hello World 模式验证隧道是否通:

./cloudflared --hostname tunnel.yourdomain.com --hello-world

tunnel.yourdomain.com 换成你自己的子域名。启动后会看到类似这样的日志:

INFO[0005] Connected to LAX
INFO[0010] Connected to SFO-DOG

这说明客户端已经连上了 Cloudflare 节点。此时在浏览器里访问 https://tunnel.yourdomain.com,应该能看到一个 Hello World 页面。

路由器没动,防火墙没动,DNS 没手动配置,就这样通了。


第四步:用 Rust 跑一个真正的 Web 服务

Hello World 验证完隧道没问题,下一步换成一个真实的 Rust Web 服务。原博客作者选择了 Gotham,一个基于异步 I/O 的 Rust Web 框架。

首先安装 Rust 工具链:

curl https://sh.rustup.rs -sSf | sh
# 安装完成后刷新环境变量
source $HOME/.cargo/env

克隆 Gotham 并编译 hello_world 示例:

git clone https://github.com/gotham-rs/gotham
cd gotham/examples/hello_world
cargo build

树莓派编译比较慢,cargo build 花了将近 8 分钟。编译完成后运行:

cd ../../target/debug
./gotham_examples_hello_world
# Listening for requests at http://127.0.0.1:7878

Web 服务现在监听在本地 7878 端口。把隧道指向它:

./cloudflared --hostname gotham.yourdomain.com http://127.0.0.1:7878

访问 https://gotham.yourdomain.com,Rust 服务的响应就出来了。


第五步:配置开机自启

每次 SSH 进去手动启动太麻烦,需要让两个进程在系统启动时自动运行。

配置 cloudflared 自启

先把证书和配置文件放到系统目录:

sudo cp ~/.cloudflared/cert.pem /etc/cloudflared
sudo nano /etc/cloudflared/config.yml

config.yml 内容:

hostname: gotham.yourdomain.com
url: http://127.0.0.1:7878

然后安装为系统服务:

sudo ./cloudflared service install

cloudflared 会自动注册成 systemd 服务,开机自启。

配置 Rust Web 服务自启

把编译好的二进制文件复制到一个稳定的位置:

cp target/debug/gotham_examples_hello_world /home/pi/argo-tunnel/server/bin/

编辑 /etc/rc.local,在 exit 0 之前加一行:

/home/pi/argo-tunnel/server/bin/gotham_examples_hello_world &

重启树莓派,SSH 回来后检查两个进程是否都在运行:

sudo ps -aux | grep cloudflared
sudo ps -aux | grep gotham

看到进程就说明配置成功了。


这件事有意思在哪

纯粹的技术实现层面,这个方案并不复杂,每一步都很直白。但把这几样东西组合在一起,解决的问题其实很实际:

家宽没有固定 IP 不再是障碍。 Cloudflare Tunnel 的连接是从内网发起的,IP 怎么变都无所谓,隧道会自动重连。

不需要开防火墙端口。 对家庭网络来说,不在路由器上开洞,安全性本质上好了一个层次。所有流量都经过 Cloudflare,还能顺带享受 DDoS 防护和 HTTPS。

Rust 在资源受限设备上表现不错。 Gotham 是异步框架,内存占用低,这一点在只有 1GB 内存的树莓派上很重要。编译慢是确实慢,但一次编译、长期运行,是嵌入式类场景的合理取舍。

当然,这个方案也有局限。Cloudflare Tunnel 需要你有一个托管在 Cloudflare 上的域名,流量也会经过 Cloudflare 的节点,如果对数据经过第三方有顾虑,就需要另想办法。


小结

这个实验的路径是这样的:

  1. 树莓派联网,安装 cloudflared
  2. cloudflared login 授权域名,获取证书
  3. 先用内置 Hello World 验证隧道通路
  4. 安装 Rust,编译 Gotham 示例,把隧道指向本地 Web 服务
  5. 配置 systemd 和 rc.local 实现两个进程的开机自启

整个过程没有动过路由器,没有手动配过 DNS,家里的树莓派就这样对外提供了一个有正经域名和 HTTPS 的 Web 服务。

对于那些一直想折腾树莓派但被网络配置挡在门外的人来说,这条路值得一试。


最近一直被信贷的电话轰炸,屏蔽一个号用另一个号打,不胜其烦,感觉手机号也是一些虚拟号码?不太清楚

有没有大佬给支个招可以一次性解决

今天刷到一个讲直流交流电的视频, 看到一个词 "特高压直流输电", 感觉和我之前的认知不太一致(忘了是初中还是高中的物理里的, 高压输电是交流电), 本能的就去搜了下, 原来 2010 年就已经有了 800kV 特高压直流输电, 突然想起来之前应该看过提到"特高压直流输电" 的新闻, 完全没有留意这个词的含义, 大概是脑补成了 "特高压交流输电".

大家最近有什么刷新认知的事吗?

原文:Writing complex macros in Rust: Reverse Polish Notation,作者 Ingvar Stepanyan,Cloudflare Blog。

Rust 的宏系统功能强大,但也以"难以掌握"著称。很多人读完官方文档、照着示例写了几个简单的宏之后,一旦遇到需要处理复杂 token 序列的场景,就完全不知道从何下手了。

这篇文章以 Cloudflare 工程师的一篇技术博客为蓝本,通过实现一个编译期的逆波兰表达式求值宏,把 Rust 声明宏(macro_rules!)的核心技巧完整地走一遍。


什么是逆波兰表达式

逆波兰表达式(Reverse Polish Notation,RPN),也叫后缀表达式,是一种不需要括号就能表达运算优先级的记法。它依赖一个栈来工作:

  • 遇到操作数,压栈
  • 遇到运算符,从栈中取出两个操作数,计算结果后再压回栈

举个例子,RPN 表达式:

2 3 + 4 *

执行步骤如下:

  1. 2 入栈 → 栈:[2]
  2. 3 入栈 → 栈:[3, 2]
  3. 遇到 +,取出 32,计算 2 + 3 = 5,压回 → 栈:[5]
  4. 4 入栈 → 栈:[4, 5]
  5. 遇到 *,取出 45,计算 5 * 4 = 20,压回 → 栈:[20]
  6. 表达式结束,栈顶即为结果 20

对应的中缀表达式是 (2 + 3) * 4

我们的目标是写一个宏,让下面的代码能在编译期完成求值:

println!("{}", rpn!(2 3 + 4 *)); // 20

第一步:用 token 序列模拟栈

Rust 宏没有"变量"这个概念,无法在运行时维护一个真正的栈。但宏可以在递归调用时携带一段 token 序列,用来充当编译期的栈。

我们用方括号包裹的、逗号分隔的 expr 序列来表示栈:

[ $($stack:expr),* ]

每次递归调用时,我们把这个"栈"更新后传给下一次调用,以此来模拟栈的 push/pop 操作。


第二步:处理操作数

先写处理单个数字(操作数)的分支。把数字压入栈,然后继续处理剩余 token:

macro_rules! rpn {
  ([ $($stack:expr),* ] $num:tt $($rest:tt)*) => {
    rpn!([ $num $(, $stack)* ] $($rest)*)
  };
}

这里有两个关键点:

为什么用 tt 而不是 exprliteral

因为 expr 会贪婪地匹配,可能把 2 + 3 整体吃掉,而我们只需要匹配一个 token。tt(token tree)恰好只匹配一个 token 树。

递归是宏处理序列的唯一方式。

宏不能用循环,也不能修改变量。通过递归,每次把处理好的新栈状态传入下一次调用,直到消耗完所有 token,这是声明宏处理列表的标准模式。


第三步:处理运算符

运算符分支需要从栈中弹出两个操作数,组合成中缀表达式后压回:

macro_rules! rpn {
  ([ $b:expr, $a:expr $(, $stack:expr)* ] + $($rest:tt)*) => {
    rpn!([ $a + $b $(, $stack)* ] $($rest)*)
  };
  // - * / 类似...
}

注意栈中元素的顺序:先入栈的 $a 在后,后入栈的 $b 在前(因为栈顶在左侧)。运算时是 $a op $b,而不是 $b op $a,减法和除法的情况下这一点尤为重要。

由于四个运算符的处理逻辑完全相同,重复写四次显然不够优雅。


第四步:用 @op 内部 helper 消除重复

Rust 宏不能调用外部 helper,但可以在同一个宏里定义"内部分支",用一个特殊的标记 token(如 @op)作为标识符,与正常输入区分开:

macro_rules! rpn {
  // 内部 helper:执行实际运算
  (@op [ $b:expr, $a:expr $(, $stack:expr)* ] $op:tt $($rest:tt)*) => {
    rpn!([ $a $op $b $(, $stack)* ] $($rest)*)
  };

  // 四个运算符统一转发给 @op
  ($stack:tt + $($rest:tt)*) => { rpn!(@op $stack + $($rest)*) };
  ($stack:tt - $($rest:tt)*) => { rpn!(@op $stack - $($rest)*) };
  ($stack:tt * $($rest:tt)*) => { rpn!(@op $stack * $($rest)*) };
  ($stack:tt / $($rest:tt)*) => { rpn!(@op $stack / $($rest)*) };

  // 操作数:压栈
  ([ $($stack:expr),* ] $num:tt $($rest:tt)*) => {
    rpn!([ $num $(, $stack)* ] $($rest)*)
  };
}

这里还有一个技巧:在运算符分支里,整个栈 $stack 被作为 tt 整体传递(因为它是一个被方括号包裹的 token 树),不需要展开里面的内容。只有在 @op 分支里,才真正拆解栈的内部结构。


第五步:处理终止条件和入口

当所有 token 处理完毕,栈中应该剩下唯一的结果:

([ $result:expr ]) => {
  $result
};

还需要一个入口分支,让调用者不必手动传入空栈 []

($($tokens:tt)*) => {
  rpn!([] $($tokens)*)
};

注意分支顺序很重要。这个兜底分支必须放在最后,否则它会匹配一切,导致其他分支永远无法触发。

完整宏定义如下:

macro_rules! rpn {
  (@op [ $b:expr, $a:expr $(, $stack:expr)* ] $op:tt $($rest:tt)*) => {
    rpn!([ $a $op $b $(, $stack)* ] $($rest)*)
  };

  ($stack:tt + $($rest:tt)*) => { rpn!(@op $stack + $($rest)*) };
  ($stack:tt - $($rest:tt)*) => { rpn!(@op $stack - $($rest)*) };
  ($stack:tt * $($rest:tt)*) => { rpn!(@op $stack * $($rest)*) };
  ($stack:tt / $($rest:tt)*) => { rpn!(@op $stack / $($rest)*) };

  ([ $($stack:expr),* ] $num:tt $($rest:tt)*) => {
    rpn!([ $num $(, $stack)* ] $($rest)*)
  };

  ([ $result:expr ]) => { $result };

  ($($tokens:tt)*) => { rpn!([] $($tokens)*) };
}

测试:

println!("{}", rpn!(2 3 + 4 *));              // 20
println!("{}", rpn!(15 7 1 1 + - / 3 * 2 1 1 + + -)); // 5

两行都能正确输出,且完全在编译期求值。


第六步:让错误信息更有用

一个生产可用的宏,还需要处理非法输入时给出清晰的错误提示,而不是让编译器抛出莫名其妙的类型错误。

情况一:操作数过多(缺少运算符)

输入 rpn!(2 3 7 + 4 *) 时,栈最终有两个值而不是一个。此时会触发兜底分支,产生难以理解的类型错误。

解决方案:在终止分支和兜底分支之间,插入一个匹配"栈里有多个值"的错误分支:

([ $($stack:expr),* ]) => {
  compile_error!(concat!(
    "表达式求值失败,可能缺少运算符。当前栈状态:",
    stringify!([ $($stack),* ])
  ))
};

情况二:操作数不足(缺少操作数)

输入 rpn!(2 3 + *) 时,栈只有一个值却遇到了运算符,@op 分支无法匹配两个操作数,导致 @ 字符被当成普通 token 压栈,产生奇怪的错误。

解决方案:给 @op 也加一个兜底错误分支:

(@op $stack:tt $op:tt $($rest:tt)*) => {
  compile_error!(concat!(
    "运算符 `",
    stringify!($op),
    "` 无法应用于当前栈:",
    stringify!($stack)
  ))
};

加入这两个分支后,错误信息会清晰地告诉用户问题所在:

error: 运算符 `*` 无法应用于当前栈:[ 2 + 3 ]

调试技巧:trace_macros!

宏的递归展开过程很难在脑子里完整跟踪。Rust nightly 提供了 trace_macros! 宏,可以打印出每一步的展开过程:

#![feature(trace_macros)]

fn main() {
  trace_macros!(true);
  let e = rpn!(2 3 + 4 *);
  trace_macros!(false);
  println!("{}", e);
}

编译时会输出类似这样的展开链:

expanding `rpn! { 2 3 + 4 * }`
to `rpn ! ( [  ] 2 3 + 4 * )`
expanding `rpn! { [  ] 2 3 + 4 * }`
to `rpn ! ( [ 2 ] 3 + 4 * )`
...

写复杂宏时,这是定位问题最直接的工具。


总结:Rust 声明宏的三个核心技巧

通过这个例子,可以总结出编写复杂 macro_rules! 宏的三个核心模式:

1. 用 token 序列模拟状态

宏没有变量,但可以把状态编码在一段 token 序列里,随着递归调用一路传下去。数据结构、栈、累加器,都可以用这种方式实现。

2. 用 @标记 划分内部 helper

在同一个宏里,用特殊前缀(如 @op@parse)标记"内部分支",实现逻辑分层和代码复用,避免大量重复的分支。

3. 分支顺序决定匹配优先级

macro_rules! 按分支定义顺序逐一尝试匹配,更具体的分支要放在更通用的分支之前。兜底的 $($tokens:tt)* 必须永远在最后。

这三个技巧组合在一起,足以应对绝大多数需要在编译期处理复杂 token 序列的场景。


一直都是用 loon ,然后通过订阅加一些插件使用,最近好像很多梯子订阅链接都不支持了,都是用自己的客户端,请问这种情况怎么使用 loon 啊,求教,各位大佬。

Design Expert软件‌是一款专门面向实验设计及相关分析的软件,它专注于实验设计(DOE),提供多种实验设计方法,包括因子设计、响应面方法、混料设计和组合设计等

一、准备工作

安装包下载:https://pan.xunlei.com/s/VOr26pMT4tOP85uoMfkCjucAA1?pwd=zzzk#,下载并保存【Design Expert13(64bit)】压缩包到电脑本地(内含安装程序和 Crack 工具)。

二、安装 Design‑Expert 13

  1. 解压安装包

    • 右键【Design Expert13(64bit)】压缩包 → 选择【解压到 Design Expert13(64bit)】。
  2. 运行安装程序

    • 打开解压后的文件夹,双击运行【Setup】。
  3. 按向导安装

    • 点击【Next】;
    • 自定义安装路径:将路径中的 C盘改为 D盘(如 D:\Program Files\Stat‑Ease\Design‑Expert 13)→【Next】;
    • 点击【Install】开始安装;
    • 安装完成后点击【Finish】。

三、 Design‑Expert 13(Crack 替换)

  1. 复制文件

    • 回到解压后的【Design Expert13(64bit)】文件夹,打开【Crack】文件夹;
    • 右键【dx】文件 →【复制】。
  2. 替换软件文件

    • 右键桌面【Design Expert13】图标 →【打开文件所在的位置】;
    • 在软件安装目录空白处 → 右键【粘贴】;
    • 点击【替换目标中的文件】。

四、首次启动与设置

  1. 双击桌面【Design Expert13】图标启动软件;
  2. 依次点击【Accept】→【Never Register...】→【Ignore..】→【Switch ..13】。

五、验证安装

成功进入 Design‑Expert 13 主界面,即可正常使用全部功能。

现在工作的公司是大小周(有的岗位甚至是单休),我工作的几年一直是在双休的公司,所以在目前公司工作的将近半年里,每天都过的很煎熬很想逃离,也尝试过骑驴找马,但奈何现在的就业环境实在是差或者自身条件不如人,排除非双休公司后投出的简历都没有正向反馈。
但是,公司的大客户是欧盟成员国的一家公司,在国内也有分公司;所以,以欧盟《强迫劳动法案》为由,通过邮件方式向客户公司寻求帮助,给任职公司施压,使其改变大小周,希望是否十分渺茫?
已经问过 AI 了,想听听人类的意见,本人不善表达,略显啰嗦望海涵。祝非双休的身体健康,双休的各位周末愉快

我目前手头上存档的一些资料:

  • 目标客户公司下某个业务往来员工的邮箱(PS.不知道给他发邮件是否会引起重视?)
  • 公司每月考勤汇总表
  • 节假日补班公告(上面有领导的签名和大小周工作制关键字)

我做了一个插件可以在 V2EX 里面插入表情包或者 gif 动图, 但是因为我平常不太收集这些东西(老登我是有点跟不上潮流了), 所以子弹库有点贫瘠, 大家可以分享一下吗? 我实时更新到素材库里.

调试一下看看下周发布.

很多人觉得播放器只支持 SMB 协议在户外没法用,但实际上,只要配合 Tailscale 这样的虚拟局域网(异地组网)工具,你在户外一样能完美地串流家里的 NAS 数据。
所以从本质上讲,Nas Player Pro 🍆 已经是一个完全独立的“全能 NAS 娱乐终端”了。当然,就算你暂时没有 NAS ,直接塞一张装满数据的 SD 卡进去,它也是一个极其强悍的本地播放器。具体的操作和顺滑度,大家可以去官网看看我录的演示视频。

这些全方位的功能,没有恶心的订阅制,只要 800 日元(一次性买断)。
另外,在这里立个 Flag:如果大家能多买几份支持一下开发,我也计划在后续版本中加入 WebDAV 和 FTP 的支持,这样连 Tailscale 都不需要了。
(不过作为开发者,实话实说,从纯粹的安全性角度来看,我个人是非常不推荐把这俩协议直接暴露在公网上的,你们懂的)。

怎么样?各位数据仓鼠( Datahoarder )们,是时候把你们硬盘里费尽心思收集的视频、漫画和无损音乐拿出来,享受一场极致的串流( Extreme Streaming )盛宴了吧?
如果你认同这种折腾的极客精神,欢迎去你喜欢的平台( iOS / Android / Amazon )支持一下,就当请这个还在苦逼优化的日本开发者喝杯咖啡了!

https://killersaca.github.io/Privacy-Policy/NasPlayerPro.html#en

自用的罗技 K835,TTC 青轴,20 年购入,24 年开始出现按键失灵,用砂纸从缝隙中插进去打磨几下能好段时间; 25 年多键失灵严重,打磨法也不好用了,拆解了几个按键发现全部铜片整体黑化严重。
同事的罗技 TTC 红轴 22 年购入,现在也开始失灵了,估计里面的铜片都开始严重氧化发黑了。
外观手感都挺好的,就是轴体不能用了,感觉挺可惜的。
现入手了 ikbc c87,试试这个 cherry 镀金工艺能用几年。

结论:TTC 轴体开封后无论使用频率如何,日历寿命 5 年。

昨天,AI圈格外热闹。深度求索公司正式发布全新大语言模型DeepSeek-V4预览版并同步向全球开源。而我们要宣布一个同样重磅的消息:

TestCopilot平台已正式接入DeepSeek V4系列模型,意味着我们用例生成、AI自动评审、AI执行测试用例的功能会迈入旗舰水平。

你不是一个人在测试,你背后完全可以用一个几乎免费的 AI 智囊团:

  • 几百页的 PRD 加几十个接口 API 文档加历史缺陷报告一股脑丢给它,它都能稳稳接住,几秒钟帮你生成覆盖正向流程、边界条件和异常场景的高质量测试用例;
  • 让它帮你审测试用例,全覆盖度、合理性、异常场景遗漏项一次性标注清楚,比你找同事交叉评审更靠谱;
  • 甚至让它7×24 小时自动执行测试,实时分析失败原因、智能给出修复建议,而你只需把精力放在那些真正需要判断力和业务理解的复杂场景上。

而且,这回 DeepSeek 把 1M(一百万)的上下文窗口直接当成了标配。以前百万上下文是高端功能,技术门槛高;现在人人都能用上顶级 AI,测试工程师的信息处理能力一夜之间拉满。这一切,都是为了帮你用最少的时间和精力,交付最高质量的软件版本

但是——AI 再强,也解决不了一个核心问题:信息差和工程经验差

  • 你知道某个复杂微服务接口的隐藏异常路径怎么测吗?
  • 你知道上次线上事故背后对应的测试覆盖盲区在哪里吗?
  • 你知道哪些测试场景“看着合理,实则业务上必错”吗?

这些答案,不在 AI 的云端,而在真实的、深耕一线的测试工程师脑子里

所以,今天我们不止聊 AI,更要认真说一件事:TestCopilot + DeepSeek V4,让 AI 真正走进你的测试工程流水线里。

一、V4 到底强在哪?对你有什么用?

这次 V4 发了两个版本:

  • V4-Pro:旗舰版,总参数 1.6 万亿,激活参数约 490 亿,上下文长度 1M
  • V4-Flash:经济版,总参数 2840 亿,激活参数 130 亿,上下文长度也是 1M!

    图片

两个版本都原生支持 100 万 token(约合百万汉字)的超长上下文,而且最关键的是——Long Affordability(长上下文经济性) 做到了极致。

怎么做到的?V4 搞了一套全新的混合注意力架构:在 token 维度引入压缩机制,结合自研的 DSA 稀疏注意力。模型处理超长文本时不再对所有 token 做全量计算,而是区分轻重——强关联的 token 精读,弱关联的压缩或跳过。

这套机制的效果用两个数字就能说明白:在百万 token 上下文的设定下,V4-Pro 每个 token 的算力消耗只有前代 V3.2 的 27%,KV 缓存占用更是降到只有 10%。简单翻译一下:以前一页 PRD 读 10 秒,现在一百页 PRD 也就读十几秒——长文档处理效率提升了近四倍。

性能表现上,V4-Pro 在 Agentic Coding 评测中达到当前开源模型最佳水平,内部评测使用体验优于 Claude Sonnet 4.5,交付质量接近 Opus 4.6 非思考模式。在世界知识测评中大幅领先其他开源模型,仅稍逊于顶尖闭源模型 Gemini-Pro-3.1。在数学、STEM、竞赛型代码的测评中,超越当前所有已公开评测的开源模型,取得了比肩世界顶级闭源模型的优异成绩。

定价方面,DeepSeek 延续了一贯的普惠策略。V4-Flash 每百万 token 输入仅需 1 元(缓存命中 0.2 元),输出 2 元。对比国际友商同级别模型,价格优势显而易见。

而在整个测试行业,AI 正从实验性工具走向基础设施。据预测,到 2026 年已有超过 60% 的企业采用 AI 测试方案。AI-Combined Testing(AICT)已成为头部企业质量保障的基础设施,其核心是将大语言模型与符号执行、代码语义分析深度融合,实现“需求文档→测试用例→执行路径→缺陷预测”的端到端自动化闭环。

二、TestCopilot 接入 V4:你的三大 AI 测试能力,这次全部升级

TestCopilot 的设计理念一直是:让测试工程师专注于高价值的质量策略和业务理解,让 AI 接管那些重复、繁琐、高度依赖记忆力的工作。 而 V4 的到来,让我们在这条路上迈出了关键一步。

1. AI 用例生成:从“写脚本”到“一句话生成”

传统测试用例设计是一项高度依赖经验的隐性知识工作:等价类划分、边界值计算、场景流梳理,每一项都耗时耗力。一份中等复杂度的需求,熟手也要一两小时。

现有行业实践早已证明 AI 介入的颠覆性效果。某金融科技公司采用 AICT 后,性能测试用例设计时间从 72 小时缩短至 4 小时,关键路径覆盖率提升至 92.7%。AI 不仅能快速生成测试用例、断言和 Mock 数据,更能覆盖传统方法难以触及的边界值和异常输入场景。

接入 V4 后,TestCopilot 的 AI 用例生成功能实现了质的跃升:

  • 百万上下文撑爆“胃口”:把几百页的 PRD 加几十个接口 API 文档加历史缺陷报告一股脑丢进去,模型自动识别关键业务路径,生成覆盖正向流程、边界条件与异常场景的高质量测试用例。
  • 业务语义深度理解:V4 的 Agent 能力让模型能自主推断业务规则间的隐含依赖,不再机械套模板,生成质量更接近资深测试工程师的水准。
  • 自然语言驱动,零门槛上手:你不需要写脚本,不需要记语法,只需要用自然语言描述需求,AI 就能将功能点映射为可执行的测试场景。

但也要清醒地认识到:AI 生成测试用例并不会直接替代测试工程师,真正分水岭在于是被动使用 AI 输出,还是构建工程化生成体系。TestCopilot 希望帮助每一位测试工程师完成这一跃升。

2. AI 自动评审:从“同事交叉评审”到“智能体全面体检”

软件测试中,测试用例的覆盖完整度、冗余控制及对需求变更的适应能力,直接关乎质量保障成效。面对业务需求指数级增长与用例库持续膨胀,传统人工评审在效率、准确性和可扩展性方面已难以为继。

研究指出,代码评审平均能发现约 60% 的设计与实现缺陷。大语言模型凭借强大的自然语言理解与逻辑推理能力,可以通过深度语义分析实现“需求–用例”语义对齐,精准识别覆盖盲区、冗余用例与设计缺陷,并支持智能补全与优化。

接入 V4 后,TestCopilot 的 AI 自动评审实现了全方位升级:

  • 维度更全面:不再只做格式和语法检查,而是从“测试点是否覆盖关键业务路径”到“是否遗漏异常场景”,多维评估用例质量。
  • 语义理解更深:V4 的强推理能力让评审不再停留在表面——能发现那些“看着合理但逻辑上有漏洞”的隐形缺陷。
  • 自动查漏补缺:评审后不仅给出问题清单,还能自动生成补充用例建议,直接落到你的用例库里。

同时,中国电子商会测试专业委员会近日正式发布了《软件测试智能体技术规范》,为企业测试智能体建设提供能力指导,推动测试智能体的落地应用。TestCopilot 正是沿着这一技术规范路线,将 AI 评审打造为可审计、可追溯、可信任的工程化能力。

3. AI 执行测试用例:从“脚本维护”到“7×24 小时智能守护”

脚本维护成本是传统自动化测试最大的隐形消耗。UI 改版导致脚本失效、接口变更牵一发而动全身,团队往往疲于维护而非真正扩展测试覆盖。

2026 年,自愈式测试框架已从概念走向规模化落地。AI 模型实时监控 UI 结构变化,通过视觉语义分析与 DOM 结构推理,自动更新定位策略,无需人工干预。企业的自动化测试脚本平均生命周期从 3 周延长至 6 个月。以 Katalon True Platform 为例,其 AI Agent 能够分析需求、创建与维护测试用例、执行测试并检测缺陷,且每一步 AI 驱动的操作均可记录、可追溯、可审计。

TestCopilot 的 AI 执行测试用例功能,在 V4 加持下迎来三大突破:

  • 全局视角一次加载:V4 百万上下文的优势,可以让模型从数据角度一次性理解整个测试环境全貌——几十个微服务的接口定义、数据库表结构、业务流程依赖全部纳入视野,不再是碎片化的逐条执行。
  • 实时智能诊断:执行过程中,AI 不仅能按预定脚本运行,更能实时分析执行结果、智能判断失败原因并给出修复建议。是脚本问题还是环境问题?是偶发抖动还是真实缺陷?AI 帮你一眼甄别。
  • 从“人找Bug”到“AI主动探伤”:V4 的 Agent 能力让模型具备了“自主探索”的潜力——不再被动按脚本跑,而是主动挖掘边缘场景和隐藏缺陷。

中国电子商会测试专业委员会指出,AI 正推动软件测试从“脚本时代”迈向“智能体自治时代”,AI 可 7×24 小时自主探索,主动挖掘边缘场景与隐藏缺陷。TestCopilot 正朝着这一方向持续进化。

最后

无论是 AI 用例生成、AI 自动评审,还是 AI 执行测试用例,我们追求的从来不是“用 AI 替代测试工程师”,而是让每个测试工程师都能拥有一个 7×24 小时在线的 AI 伙伴,接管那些重复、繁琐、高度依赖记忆力的人工劳动。

当生成能力变成基础设施,判断力、建模能力和系统设计能力,才是新的门槛。V4 的发布,让 AI 的推理能力和上下文窗口终于配得上测试工程的真正复杂度。

TestCopilot 已正式接入 DeepSeek V4 系列模型。无论你是想尝鲜 AI 用例生成,还是希望用 AI 帮你审用例、跑用例,现在就是最好的时机。

欢迎试用TestCopilot平台https://tgeek.cn/

在探索AI语言模型的实际应用过程中,网络环境的稳定性直接影响使用体验。住宅代理作为优化网络连接的有效工具,能够为Grok等AI服务的使用提供更可靠的访问基础。

Grok的基本概念

Grok是由xAI公司开发的大语言模型,整合于X(原Twitter)平台,具备文本生成与图像编辑等多模态能力。与市场上其他AI模型相比,Grok在推理响应与创意内容生成方面具有独特优势。

然而,用户在实际使用中经常遇到访问卡顿与账户风控问题,理解这些问题的成因,是寻求解决方案的第一步。

问题的排查与优化

在使用Grok等在线服务时,遇到卡顿或响应缓慢的情况并不少见。结合住宅代理的使用经验,可以从以下几个维度进行排查和优化。

网络环境的稳定性

建议用户确认当前带宽是否充足,避免其他高流量应用(如下载、视频会议)抢占资源。同时,检查本地防火墙或安全软件是否误拦截了代理端口,此类问题可能导致代理链路延迟升高或连接中断。

代理配置

代理连接异常往往源于简单的配置错误。用户应仔细检查包括代理IP地址、端口号、账号密码以及所选择的协议类型(HTTP/SOCKS5)是否与使用场景匹配。

优化建议

若配置检查无误后仍出现连接问题,需关注所使用代理IP的质量与有效性,建议选择来自正规ISP分配、纯净度高的住宅代理IP,保障IP的稳定性与可用性。

总结

Grok作为实时性突出的AI工具,在多场景中具备实用价值。然而,顺畅的使用体验不仅取决于AI模型本身,更离不开稳定、可靠的网络环境支持。

以LokiProxy为代表的住宅代理服务,作为优化网络连接的有效工具,能够帮助用户降低访问异常的发生频率,从而更专注地体验Grok在创意生成与智能交互方面的核心能力。