Swift 隔离式并发实践:actor、Global Actor 与 Sendable
1. 为什么 async/await 不能解决并发问题
Swift Concurrency 带来的第一个直观变化,是 async/await 让异步调用读起来像同步代码。之前一长串回调嵌套,现在可以按顺序写清楚:先请求网络,再解析,再更新状态。但在真实项目里,异步“写起来舒服”只是表面,很多时候真正的痛点不在于“怎么写异步逻辑”,而在于“多个任务同时访问同一份状态时发生的问题”。线程变多、任务变多、入口变多之后,只要可变状态没有明确的限制,就可能带来问题。
获取服务端配置就是一个非常典型的并发场景:有本地缓存,有后台刷新,有多处调用,有UI依赖结果,还有可能叠加服务端推送。表面上只是“拉一份配置下来”,但内部状态在多个任务之间来回穿插,如果不做隔离,async/await 并不能有效处理这些逻辑。
UIKit 项目异步改造:Combine、async/await、@Published
1. 为什么 UIKit 项目也需要现代异步能力?
现在的应用,无论是前端、Flutter 还是移动端原生,都有一个共同趋势:异步操作越来越多、界面状态变化也越来越频繁。Web 有 async/await + Promise 统一异步流程,用事件流和状态管理驱动 UI;Flutter 用 sync/await + Future/Stream 处理异步,用 BLoC、Provider、Riverpod 聚合状态并更新界面。这些体系之所以能稳定,是因为都遵循了同一种现代异步模型:异步逻辑线性化、事件流可组合、UI 完全由状态驱动。
UIKit 项目同样也面临这些问题,随着 Swift Concurrency、Combine 和 @Published 逐渐成熟,UIKit 也具备了和 Web、Flutter 类似的现代异步能力:async/await 负责逻辑,Combine 管事件流,状态集中在 ViewModel,由 UI 自动响应变化。
PyTorch:从搭积木到构建系统
1. 从零搭建一个 PyTorch 模型
在正式讨论 PyTorch 之前,我们先从一个最小可用训练流程入手:用最少的代码搭建并训练一个小型神经网络。通过这个过程来快速建立对 PyTorch 的整体认知:数据从哪里来?如何流入模型?损失如何计算?梯度如何反向传播?参数又是如何被更新的? 后面章节会对这些环节再做细致拆解,我们先做一个“总览式体验”。
1.1 整体思路:从数据到参数更新
我们开始搭建的最小神经网络包含四个核心阶段:
- 数据准备:把原始数据转换为张量,并按批次(batch)组织;
- 模型构建:用 nn.Module 定义前向计算逻辑;
- 损失与优化器:定义“好坏标准”和“如何更新参数”的规则;
- 训练循环:反复执行前向、反向和参数更新。
从 RNN 到 Transformer:时间建模的变革
1. 时间依赖与梯度消失:序列建模的困境
在很多经典的图像任务中,我们通常假设不同样本之间是独立同分布的(i.i.d.)——也就是说,一张图片与另一张图片在统计上是相互独立的,模型只需要把一张图片看作一个整体输入来处理即可。卷积网络(CNN)则利用图像内部像素之间强烈的局部相关性,通过卷积核在空间上提取局部到全局的层级特征。
但在处理序列任务(sequence modeling)时情况就完全不同了:语言、语音、时间序列信号都具有明显的时间依赖,同一个序列内部,不同时间步之间往往高度相关。要正确预测下一个值、下一个词或下一个声音,模型必须记住同一条序列中之前发生过什么。这一点正是循环神经网络(Recurrent Neural Network, RNN)诞生的核心动机。
「无人机系列④」飞行控制算法入门——从PID到仿真验证
1. 控制系统的物理与数学基础
在研究飞控算法(Flight Control Algorithm)之前,理解姿态描述方式、闭环反馈思想及采样周期的作用至关重要。本章节主要介绍这些基础概念,为后续的建模与 PID 控制奠定直观认知。
1.1 坐标系与姿态描述
无人机的姿态描述通常基于两个参考系:惯性系(Inertial Frame)与机体系(Body Frame)。
- 惯性系:固定在地面或某个空间参考点上,其坐标轴多采用“东北下(NED)”方式定义,即以北(North)、东(East)、下(Down)三个方向作为基准,用来描述无人机相对于地球的运动状态。
- 机体系:固定在无人机机体上,原点通常位于质心,$x_b$ 轴沿机头方向,$y_b$ 轴指向右翼,$z_b$ 轴指向机体下方。