跳转至

翻译

一文带你理解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。状态管理解决方案将促进这一更改数据并在整个应用程序中传播这些更改的过程。

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

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

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. 作为向量空间之间函数的求值: 矩阵-向量乘法允许矩阵定义两个向量空间之间的映射。

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

原文: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 专注于将高维基因组学数据转化为可指导人类健康研究的洞见,在空间转录组学、药物靶点识别和深度学习模型开发方面有丰富经验。

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

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

成为一名优秀的程序员:心智模型和学习策略

前言

在我作为软件工程师的职业生涯中,我遇到了一些伟大的程序员,并从他们身上学到了很多东西。这篇文章将为初学者提供一些关于成为一名优秀程序员的旅程的提示,特别是从心智模型和学习策略方面。

掌握编程需要花费大量时间。 Peter Norvig 说十年可能就足够了,所以请保持耐心,让我们开始吧。

心智模型

每个人都会编程,几岁的孩子也能写出一些可运行的代码。然而,成为一名优秀的程序员需要大量的时间和精力来打磨技能。做好准备的心态会让你在这段漫长的旅程中不断成长。

SSL和SSL证书初学者指南

原文: SSL and SSL Certificates Explained For Beginners

安全套接字层 (SSL,全称Secure Sockets Layer)传输层安全 (TLS,全称Transport Layer security) 是通过计算机网络或链接提供安全通信的协议。它们通常用于网页浏览和电子邮件。在本教程中,我们将了解学习到:

  • TLS 和 SSL
  • 公钥和私钥
  • 为什么我们需要证书以及它们的作用
  • 如何获取数字证书并了解不同的常见证书类型

什么是 TLS?

TLS 基于 SSL,并作为替代方案而开发以应对 SSLv3 中的已知漏洞。SSL 是常用术语,我们说的 SSL 通常指的就是 TLS。

SSL/TLS 提供安全保障

SSL/TLS 提供数据加密、数据完整性和身份验证功能。这意味着当使用 SSL/TLS 时,你可以确保:

  • 没有人读过你的消息
  • 没有人篡改过你的消息
  • 你正在与预期的人(服务器)通信

在两方之间发送消息时,你需要解决两个问题。

  • 你怎么知道没有人读过这条消息?
  • 你怎么知道没有人篡改过该消息?

这些问题的解决办法是:

  • 对其进行加密(Encrypt it) : 这会使内容无法读取,因此对于查看该消息的任何人来说,它只是乱码。
  • 签名(Sign it) : 这可以让收件人确信是你发送的邮件,并且邮件未被篡改。

这两个过程都需要使用密钥。这些密钥只是数字(常见的是 128 位),然后使用特定方法(通常称为算法)与消息组合,例如RSA,对消息进行加密或签名。

如何在微控制器中运行Rust?

原文:Running Rust on Microcontrollers

概览

Rust 是一个相当新的编程语言(它诞生于20101年),但在开发嵌入式固件方面显示出巨大的潜力。它首先被设计为一种系统编程语言,这使得它特别适合用于微控制器。它试图通过实现一个强大的所有权模型(可以消除整个错误类的发生)来改进 C/C++ 的一些最大缺点,这对固件也非常适用。

截至2022年,CC++ 编程语言仍然是嵌入式固件的事实标准。然而 Rust 在固件中的角色看起来很光明。Rust 对固件的支持并不是后面才考虑到,而是一开始就考虑支持。 为此,Rust 专门有官方的 嵌入式设备工作组 和 介绍如何使用 Rust 进行嵌入式开发的 嵌入式Rust之书。下图就是Rust嵌入式设备工作组logo2

Rust嵌入式设备工作组logo

本篇文章旨在探索在微控制器(这里指的是低级嵌入式固件,而不是在 Linux 等主机环境上运行)上运行 Rust,涵盖以下内容:

  • 语言特性
  • 架构支持
  • MCU家族支持
  • IDE, 编码 和 编码体验
  • 实时操作系统
  • Rust缺点

Nasm使用教程:基于X86编程教学

原文:NASM Tutorial

第一个程序

在了解 nasm 之前,让我们确保你可以输入和运行程序。确保 nasm 和 gcc 都已安装。根据你的机器平台,将以下程序之一保存为 hello.asm。然后根据给定的说明运行程序。

如果你使用的是基于 Linux 的操作系统:

; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
; To assemble and run:
;
;     nasm -felf64 hello.asm && ld hello.o && ./a.out
; ----------------------------------------------------------------------------------------

          global    _start

          section   .text
_start:   mov       rax, 1                  ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, message            ; address of string to output
          mov       rdx, 13                 ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60                 ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

          section   .data
message:  db        "Hello, World", 10      ; note the newline at the end