Python 3.3 为改进代码中的异常处理所做的工作

Summary: 探索异常处理和其他未被充分利用但仍然有用的 Python 特性。

探索异常处理和其他未被充分利用但仍然有用的 Python 特性。

# Python 3.3 为改进代码中的异常处理所做的工作

>
> 探索异常处理和其他未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202105_29_221357mxpj2kitltdez6zj.jpg" alt="" title="Coding on a computer">

这是 Python 3.x 首发特性系列文章的第四篇。Python 3.3 于 2012 年首次发布，尽管它已经发布了很长时间，但它引入的许多特性都没有得到充分利用，而且相当酷。下面是其中的三个。

### yield from

`yield` 关键字使 Python 更加强大。可以预见的是，人们都开始使用它来创建整个迭代器的生态系统。[itertools](https://docs.python.org/3/library/itertools.html) 模块和 [more-itertools](https://more-itertools.readthedocs.io/en/stable/) PyPI 包就是其中两个例子。

有时，一个新的生成器会想要使用一个现有的生成器。作为一个简单的（尽管有点故意设计）的例子，设想你想枚举所有的自然数对。

一种方法是按照“自然数对的和，自然数对的第一项”的顺序生成所有的自然数对。用 `yield from` 来实现这个方法是很自然的。

`yield from <x>` 关键字是以下的简称：

```
for item in x:
    yield item

```

```
import itertools

def pairs():
    for n in itertools.count():
        yield from ((i, n-i) for i in range(n+1))

```

```
list(itertools.islice(pairs(), 6))

```

```
    [(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0)]

```

### 隐式命名空间包

假设有一个叫 Parasol 的虚构公司，它制造了一堆东西。它的大部分内部软件都是用 Python 编写的。虽然 Parasol 已经开源了它的一些代码，但其中一些代码对于开源来说过于专有或专业。

该公司使用内部 [DevPI](https://opensource.com/article/18/7/setting-devpi) 服务器来管理内部软件包。对于 Parasol 的每个 Python 程序员来说，在 PyPI 上找一个未使用的名字是没有意义的，所以所有的内部包都被称为 `parasol.<business division>.<project>`。遵守最佳实践，开发人员希望包的名字能反映出这个命名系统。

这一点很重要！如果 `parasol.accounting.numeric_tricks` 包安装了一个名为 `numeric_tricks` 的顶层模块，这意味着依赖这个包的人将无法使用名为 `numeric_tricks` 的 PyPI 包，不管它写的有多好。

然而，这给开发者留下了一个两难的选择：哪个包拥有 `parasol/__init__.py` 文件？从 Python 3.3 开始，最好的解决办法是把 `parasol`，可能还有 `parasol.accounting`，变成没有 `__init__.py` 文件的 [命名空间包](https://www.python.org/dev/peps/pep-0420/)。

### 抑制异常的上下文

有时，在从异常中恢复的过程中出现的异常是一个问题，有上下文来跟踪它是很有用的。然而，有时却不是这样：异常已经被处理了，而新的情况是一个不同的错误状况。

例如，想象一下，在字典中查找一个键失败后，如果不能分析它，则希望失败并返回 `ValueError()`。

```
import time

def expensive_analysis(data):
    time.sleep(10)
    if data[0:1] == ">":
        return data[1:]
    return None

```

这个函数需要很长的时间，所以当你使用它时，想要对结果进行缓存：

```
cache = {}

def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data)
        cached[data] = analyzed
    return analyzed[-1]

```

不幸的是，当出现缓存没有命中时，回溯看起来很难看：

```
last_letter_analyzed("stuff")

```

```
    ---------------------------------------------------------------------------

    KeyError                                  Traceback (most recent call last)

    <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
          4     try:
    ----> 5         analyzed = cache[data]
          6     except KeyError:

    KeyError: 'stuff'

```

在处理上述异常的过程中，发生了另一个异常：

```
    ValueError                                Traceback (most recent call last)

    <ipython-input-17-40dab921f9a9> in <module>
    ----> 1 last_letter_analyzed("stuff")

    <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
          7         analyzed = expensive_analysis(data)
          8         if analyzed is None:
    ----> 9             raise ValueError("invalid data", data)
         10         cached[data] = analyzed
         11     return analyzed[-1]

    ValueError: ('invalid data', 'stuff')

```

如果你使用 `raise ... from None`，你可以得到更多可读的回溯：

```
def last_letter_analyzed(data):
    try:
        analyzed = cache[data]
    except KeyError:
        analyzed = expensive_analysis(data)
        if analyzed is None:
            raise ValueError("invalid data", data) from None
        cached[data] = analyzed
    return analyzed[-1]

```

```
last_letter_analyzed("stuff")

```

```
    ---------------------------------------------------------------------------

    ValueError                                Traceback (most recent call last)

    <ipython-input-21-40dab921f9a9> in <module>
    ----> 1 last_letter_analyzed("stuff")

    <ipython-input-20-5691e33edfbc> in last_letter_analyzed(data)
          5         analyzed = expensive_analysis(data)
          6         if analyzed is None:
    ----> 7             raise ValueError("invalid data", data) from None
          8         cached[data] = analyzed
          9     return analyzed[-1]

    ValueError: ('invalid data', 'stuff')

```

### 欢迎来到 2012 年

尽管 Python 3.3 在十年前就已经发布了，但它的许多功能仍然很酷，而且没有得到充分利用。如果你还没有，就把它们添加到你的工具箱中吧。

---

via: <https://opensource.com/article/21/5/python-33>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Btrfs 文件系统入门

# Btrfs 文件系统入门

>
> B-tree 文件系统（Btrfs）融合了文件系统和卷管理器。它为 Linux 操作系统提供了高级文件系统应当拥有的诸多不错的功能特性。
>
>
>

好几年前 Btrfs 就已经可以在 Linux 中使用了，所以你可能已经熟悉它了。如果没有，你可能对它尚有疑虑，尤其是如果你使用的是 Fedora 工作站 （Btrfs 现在是它的默认文件系统）。本文旨在帮助你熟悉它及其高级功能，例如 [写时复制](https://en.wikipedia.org/wiki/Copy-on-write) 和 [校验和](https://en.wikipedia.org/wiki/Checksum)。

Btrfs 是 “B-Tree Filesystem” 的缩写，实际上是文件系统和卷管理器的结合体。它通常被视为对 ZFS 的回应，ZFS 早在 2005 年就被引入 Sun 微系统的 Solaris 操作系统中，现在基本上被一个名为 OpenZFS 的开源实现所取代。Ubuntu 和 FreeBSD 常常使用 OpenZFS。其他具有类似特性的示例有红帽的 Stratis 和 Linux <ruby> 逻辑卷管理器 <rt>  Logical Volume Manager </rt></ruby>（LVM）。

### 安装

为了尝试 Btrfs，我下载了 Fedora 33 工作站 [ISO 文件](https://getfedora.org/en/workstation/download/) 并将其安装到一个新的虚拟机（VM）中。安装过程与以前的版本没有变化。我没有自定义任何设置，包括驱动器分区和格式化，以保持本教程的准确“开箱即用”设置。当虚拟机启动并运行后，我安装并运行了 GNOME 分区编辑器（[GParted](https://gparted.org/)），以获得一个良好的、工厂级的驱动器布局视图。

从安装这一点来说，与你以前所习惯的情况没什么不同；事实上，你可以正常使用该系统，甚至可能没有注意到文件系统是 Btrfs。然而，拥有这个新的默认文件系统使你能够利用几个很酷的特性。

### 检查 Btrfs 文件系统

我暂时没有找到特定于 Btrfs 的图形工具，尽管它的一些功能已经被合并到现有的磁盘管理工具中。

在命令行中，你可以更仔细地查看 Btrfs 格式：

```
# btrfs filesystem show
Label: 'fedora_localhost-live'  uuid: f2bb02f9-5c41-4c91-8eae-827a801ee58a
        Total devices 1 FS bytes used 6.36GiB
        devid    1 size 10.41GiB used 8.02GiB path /dev/vda3

```

### 修改 Btrfs 标签

我首先注意到的是安装程序设置的文件系统标签：`fedora_localhost-live`。这是不准确的，因为它现在是一个已安装的系统，不再是 [livecd](https://en.wikipedia.org/wiki/Live_CD)。所以我使用 `btrfs filesystem label` 命令对其进行了更改。

修改 Btrfs 标签非常的简单：

```
# btrfs filesystem label /
fedora_localhost-live
# btrfs filesystem label / fedora33workstation
# btrfs filesystem label /
fedora33workstation

```

### 管理 Btrfs 子卷

子卷看起来像是可以由 Btrfs 管理的标准目录。我的新 Fedora 33 工作站上有几个子卷：

```
# btrfs subvolume list /
ID 256 gen 2458 top level 5 path home
ID 258 gen 2461 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines

```

使用 `btrfs subvolume Create` 命令创建新的子卷，或使用 `btrfs subvolume delete` 删除子卷：

```
# btrfs subvolume create /opt/foo
Create subvolume '/opt/foo'
# btrfs subvolume list /
ID 256 gen 2884 top level 5 path home
ID 258 gen 2888 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines
ID 276 gen 2888 top level 258 path opt/foo
# btrfs subvolume delete /opt/foo
Delete subvolume (no-commit): '/opt/foo'

```

子卷允许设置配额、拍摄快照以及复制到其他位置和其他主机等操作。那么系统管理员如何利用这些功能？用户主目录又是如何操作的呢？

#### 添加用户

就像从前一样，添加一个新的用户帐户会创建一个主目录供该帐户使用：

```
# useradd student1
# getent passwd student1
student1:x:1006:1006::/home/student1:/bin/bash
# ls -l /home
drwx------. 1 student1 student1  80 Oct 29 00:21 student1

```

传统上，用户的主目录是 `/home` 的子目录。所有权和操作权是为所有者量身定制的，但是特殊功能来没有管理它们。而企业服务器环境是另外一种情况。通常，目录是为特定的应用程序及其用户保留的。你可以利用 Btrfs 来管理和应用对这些目录的约束。

为了将 Btrfs 子卷作为用户主页，在 `useradd` 命令中有一个新选项：`--Btrfs-subvolume-home`。尽管手册页尚未更新（截至本文撰写之时），但你可以通过运行 `useradd --help` 来查看该选项。通过在添加新用户时传递此选项，将创建一个新的 Btrfs 子卷。它的功能与创建常规目录时的 `-d` 选项类似：

```
# useradd --btrfs-subvolume-home student2
Create subvolume '/home/student2'

```

使用 `getent passwd student2` 验证用户，它将显示为正常。但是，运行 `btrfs subvolume` 命令列出子卷，你将看到一些有趣的内容：新用户的主目录！

```
# btrfs subvolume list /
ID 256 gen 2458 top level 5 path home
ID 258 gen 2461 top level 5 path root
ID 265 gen 1593 top level 258 path var/lib/machines
ID 272 gen 2459 top level 256 path home/student2

```

探索企业服务器环境的第二个场景。假设你需要在 `/opt` 中安装一个 [WildFly](https://www.wildfly.org/) 服务器并部署一个 Java web 应用程序。通常，你的第一步是创建一个 `wildfly` 用户。使用新的 `--btrfs-subvolume-home` 选项和 `-b` 选项来指定 `/opt` 作为基本目录：

```
# useradd -b /opt --btrfs-subvolume-home wildfly
Create subvolume '/opt/wildfly'

```

于是，`wildfly` 用户可以使用了，并且主目录设置在了 `/opt/wildfly`。

#### 删除用户

删除用户时，有时需要同时删除该用户的文件和主目录。`userdel` 命令有 `-r` 选项，它可以同时删除 Btrfs 子卷：

```
# userdel -r student2
Delete subvolume (commit): '/home/student2'

```

#### 设置磁盘使用配额

在我的一节计算机科学课上，一个学生运行了一个失控的 C 程序，然后写进了磁盘，将我们院的 Unix 系统上整个 `/home` 目录都填满了！在管理员终止失控进程并清除一些空间之前，服务器将无法使用。上述情况也是如此；那个 Wildfly 企业应用程序将为其用户提供越来越多的日志文件和内容存储。如何防止服务器因磁盘已满而死机？设置磁盘使用限制是个好主意。幸运的是，Btrfs 通过设置配额的方式支持这一点。

配置配额需要几个步骤。第一步是在 Btrfs 文件系统上启用配额：

```
# btrfs quota enable /

```

确保你知道每个子卷的配额组（qgroup）ID 号，该编号由 `btrfs subvolume list` 命令显示。每个子卷都需要基于 ID 号码来关联配额组。这可以通过 `btrfs qgroup create` 单独完成，但是，btrfs 维基提供了以下命令来加快为文件系统上的子卷创建配额组：

```
> btrfs subvolume list \<path> | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup destroy 0/{} \<path>

```

在新安装的 Fedora 33 工作站系统中，你在根文件系统路径上操作，`/`。用根路径替换 `\<path>`：

```
# btrfs subvolume list / | cut -d' ' -f2 | xargs -I{} -n1 btrfs qgroup create 0/{} /

```

然后运行 `btrfs quota rescan`，查看新的配额组：

```
# btrfs quota rescan /
quota rescan started
# btrfs qgroup show /
qgroupid         rfer         excl
--------         ----         ----
0/5          16.00KiB     16.00KiB
0/256       272.04MiB    272.04MiB
0/258         6.08GiB      6.08GiB
0/265        16.00KiB     16.00KiB
0/271        16.00KiB     16.00KiB
0/273        16.00KiB     16.00KiB

```

于是现在，你可以将配额分配给其中一个配额组，然后将配额应用于其关联的子卷。因此，如果要将 `student3` 的主目录使用限制为 1 GB，请使用 `btrfs qgroup limit` 命令：

```
# btrfs qgroup limit 1G /home/student3

```

查看特定子卷的配额：

```
# btrfs qgroup show -reF /home/student3
qgroupid         rfer         excl     max_rfer     max_excl
--------         ----         ----     --------     --------
0/271        16.00KiB     16.00KiB      1.00GiB         none

```

稍有不同的选项参数将显示所有配额组和设置的所有配额：

```
# btrfs qgroup show -re /
qgroupid         rfer         excl     max_rfer     max_excl
--------         ----         ----     --------     --------
0/5          16.00KiB     16.00KiB         none         none
0/256       272.04MiB    272.04MiB         none         none
0/258         6.08GiB      6.08GiB         none         none
0/265        16.00KiB     16.00KiB         none         none
0/271        16.00KiB     16.00KiB      1.00GiB         none
0/273        16.00KiB     16.00KiB         none         none

```

### 其他特性

这些例子提供了 Btrfs 特性的一些思考。运行 `btrfs --help` 查看命令的完整列表。还有许多其他值得注意的功能；例如，快照和发送/接收是两个值得学习的功能。

### 总结讨论

Btrfs 为向 Linux 提供高级文件系统特性集贡献了很多特性。这不是第一次；我知道 ZFS 在大约 15 年前引入了这种类型的文件系统，但是 Btrfs 是完全开源的，不受专利的限制。

如果你想探索这个文件系统，我建议从虚拟机或备用系统开始。

我想能够出现一些图形化的管理工具，为那些喜欢用图形工具的系统管理员提供便利。幸运的是，Btrfs 具有强大的开发活动，Fedora 33 项目决定将其设置为工作站上的默认值就证明了这一点。

---

via: <https://opensource.com/article/20/11/btrfs-linux>

作者：[Alan Formy-Duval](https://opensource.com/users/alanfdoss) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Chao-zhi](https://github.com/Chao-zhi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #287 谷歌强调：Chrome“隐私沙盒”功能将不会为自己定制后门

Summary: 更多：• Chrome 浏览器将会有一定的性能提升，但可能没有什么用 • 自由软件基金会寻求新的执行董事

# 硬核观察 #287 谷歌强调：Chrome“隐私沙盒”功能将不会为自己定制后门

### 谷歌强调：Chrome“隐私沙盒”功能将不会为自己定制后门

Google 在周四的线上营销活动中声称，不会在「隐私沙盒」功能中为自家的业务定制单独的规则。

>
> 近年来隐私问题逐渐被大众所关注。无论是昨天报道的苹果的保护方式还是 Google 推出的隐私沙盒，都是希望让用户的隐私得到保护。但 Google 和苹果不同，Google 本身却是一个依赖广告盈利的公司，很难保证不给自己留后路。毕竟，2018 年 Google 就将 Don't be Evil 移出了自己的座右铭。
>
>
>

### Chrome 浏览器将会有一定的性能提升，但可能没有什么用

 在 Google 的 Chrome 浏览器中，将会加入一个新的名为 Sparkplug 的 JavScript 编译器，用以提升 Chrome 中的浏览性能。谷歌声称该编译器可以将性能提升 23%。

>
> 提升性能是一个好事情。不过，想想日新月异的前端领域，可能这个性格的提升很快就会被前端技术的提升而消磨掉。这难道就是新时代的「安迪 · 比尔定律」？
>
>
>

安迪·比尔定律：指新软件总将耗尽新硬件所提高的任何计算能力。

### 自由软件基金会寻求新的执行董事

自由软件基金会的现任董事 John Sullivan 在周五发推特声称自己即将离开自由软件基金会。自由软件基金会发布了文章向全网招募新的执行董事。值得注意的是，在其中的职位描述中写道，这个职位需要「指导、激励、协调和管理FSF的所有员工，营造一种坚持FSF思想原则（责任心、同理心、效率和卓越）的文化」

>
> 看起来像是为 RMS 提供的专属岗位。
>
>
>


体验 /e/ OS：开源的去谷歌化的安卓

在国内这都是常规操作hhh

我也想用“斜杠e斜杠”这个系统??

来自广东佛山的 Chrome Mobile 71.0|Android 6.0 用户

# 体验 /e/ OS：开源的去谷歌化的安卓

/e/ 安卓操作系统是一个以隐私为导向的去谷歌化的移动操作系统，是 Lineage OS 的复刻，由 Mandrake Linux（现在的 [Mandriva Linux](https://en.wikipedia.org/wiki/Mandriva_Linux)）的创建者 [Gaël Duval](https://en.wikipedia.org/wiki/Ga%C3%ABl_Duval) 于 2018 年中期创立。

尽管安卓在 2007 年成为了一个开源项目，但当安卓得到普及时，谷歌使用专有软件取代了一些操作系统元素。/e/ 基金会用 [MicroG](https://en.wikipedia.org/wiki/MicroG) 取代了其中的专有的应用程序和服务，这是一个开源的替代框架，可以最大限度地减少跟踪和设备活动。

我们收到的 [Fairphone 3](https://esolutions.shop/shop/e-os-fairphone-3-fr/) 预装了 /e/ OS，这是一个来自 /e/ 基金会的 [以道德的方式创造的智能手机](https://www.fairphone.com/en/story/?ref=header)。我使用了一个月这个设备，然后把它返还给了他们，我将分享我对这个隐私设备的体验。我忘了截图，所以我将分享来自官方网站的通用图片。

### 在道德的 Fairphone 设备上体验 /e/ 移动操作系统

在我进一步说明之前，让我澄清一下，Fairphone 3 并不是使用 /e/ 的唯一选择。如果你要从他们那里购买设备，/e/ 基金会会给你 [一些智能手机的选择](https://esolutions.shop/shop/)。

你不需要购买设备来使用 /e/ OS。按照 /e/ 基金会的说法，你可以 [在 100 多个支持的设备上使用它](https://doc.e.foundation/devices/)。

尽管我很喜欢使用 Fairphone 3，而且我的个人信仰与 Fairphone 的宣言一致，但我不会把注意力放在设备上，而只是放在 /e/ OS 上。

#### 有评级隐私的应用程序

我把 Fairphone 3 作为我的日常使用设备用了几天时间，以比较与我的“普通”安卓手机在现实中的使用情况。

首先，我想看看我使用的所有应用程序是否都可以在 /e/ 基金会创建的“[应用商店](https://e.foundation/e-os-available-applications/)”上找到。/e/ 应用商店包含有隐私评级的应用程序。

我可以找到许多应用程序，包括来自谷歌的应用程序。这意味着，如果有人真的想使用一些谷歌的服务，它仍然可以作为一个选项来下载。尽管与其他安卓设备不同，没有强行将谷歌服务塞进你的嘴里。

虽然有很多应用程序，但我无法找到我在英国使用的手机银行应用程序。我不得不承认，手机银行应用程序可以在一定程度上促进便利。作为替代方案，我不得不在需要时进入电脑使用网上银行平台。

从可用性的角度来看，/e/ OS 可以取代我的“标准”安卓操作系统，但会有一些小插曲，比如银行应用程序。

#### 如果不是谷歌的，那是什么？

想知道 /e/ OS 使用哪些基本的应用程序，而不是谷歌的那些？这里有一个快速列表：

* [魔法地球](https://www.magicearth.com/) —— 逐向道路导航
* 浏览器 —— Chromium 的一个非谷歌复刻版本
* 邮件 —— [K9-mail](https://k9mail.app/) 的一个复刻
* 短信 —— QKSMS 的一个复刻
* 照相机 —— OpenCamera 的一个复刻
* 天气 —— GoodWeather 的一个复刻
* OpenTasks —— 任务组织者
* 日历：[Etar calendar](https://github.com/Etar-Group/Etar-Calendar) 的一个复刻

#### Bliss Launcher 和整体设计

/e/ OS 的默认启动程序被称为 “Bliss Launcher”，其目的是为了获得有吸引力的外观和感觉。对我来说，这个设计感觉与 iOS 相似。

通过向左滑动面板，你可以访问 /e/ 选择的一些有用的小工具。

* 搜索：快速搜索预装的应用程序或搜索 Web
* APP 建议：前 4 个最常用的应用程序将出现在这个小部件上
* 天气：天气小部件显示的是当地的天气。它不会自动检测位置，需要进行配置。
* 编辑：如果你想在屏幕上有更多的小部件，你可以通过点击“编辑”按钮添加它们。

总而言之，用户界面是干净整洁的简单明了，增强了愉快的用户体验。 \* 天气。天气小部件显示的是当地的天气。它不会自动检测位置，需要进行配置。

* 编辑：如果你想在屏幕上有更多的小部件，你可以通过点击编辑按钮添加它们。

总而言之，用户界面干净整洁、简单明了，增强了愉快的用户体验。

#### 去谷歌化和面向隐私的操作系统

如前所述，/e/ 操作系统是一个去谷歌化的操作系统，它基于 [Lineage OS](https://lineageos.org/) 的开源核心。所有的谷歌应用程序已经被删除，谷歌服务已经被 MicroG 框架所取代。/e/ OS 仍然与所有的安卓应用兼容。

主要的隐私功能：

* 谷歌搜索引擎已被 DuckDuckGo 等替代品取代
* 谷歌服务已被 microG 框架所取代
* 使用替代的默认应用程序，而不是谷歌应用程序
* 取消了对谷歌服务器的连接检查
* NTP 服务器已被替换为标准的 NTP 服务：[pool.ntp.org](http://pool.ntp.org)
* DNS 默认服务器由 9.9.9.9 取代，可以根据用户的选择进行编辑
* 地理定位是在 GPS 的基础上使用 Mozilla 定位服务

>
> 隐私声明
>
>
> 请注意，使用由 /e/ 基金会提供的智能手机并不自动意味着无论你做什么都能保证你的隐私。分享你的个人信息的社交媒体应用程序应在你的意识下使用。
>
>
>

### 结论

我成为安卓用户已经超过十年了。/e/ OS 给我带来了积极的惊喜。关注隐私的用户可以发现这个解决方案非常吸引人，而且根据所选择的应用程序和设置，可以再次感觉到使用智能手机的安全。

如果你是一个有隐私意识的技术专家，并且能够自己找到解决问题的方法，我向你推荐它。对于那些习惯于谷歌主流服务的人来说，/e/ 生态系统可能会让他们不知所措。

你使用过 /e/ OS 吗？你的使用经验如何？你怎么看这些关注隐私的项目？

---

via: <https://itsfoss.com/e-os-review/>

作者：[Dimitrios](https://itsfoss.com/author/dimitrios/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


回顾一下 Python 3.4 中的枚举

Summary: 另外探索一些未被充分利用但仍然有用的 Python 特性。

另外探索一些未被充分利用但仍然有用的 Python 特性。

# 回顾一下 Python 3.4 中的枚举

>
> 另外探索一些未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202105_30_230947j19r2772m12tccrh.jpg" alt="" title="old school calculator">

这是 Python 3.x 首发特性系列文章的第五篇。Python 3.4 在 2014 年首次发布，尽管它已经发布了很长时间，但它引入的许多特性都没有被充分利用，而且相当酷。下面是其中的三个。

### 枚举

我最喜欢的逻辑谜题之一是自我描述的 [史上最难的逻辑谜题](https://en.wikipedia.org/wiki/The_Hardest_Logic_Puzzle_Ever)。在其中，它谈到了三个“神”，他们被称为 A、B 和 C，他们的身份是真、假和随机，按一定顺序排列。你可以问他们问题，但他们只用神的语言回答，其中 “da” 和 “ja” 表示 “是” 和 “不是”，但你不知道哪个是哪个。

如果你决定使用 Python 来解决这个问题，你将如何表示神的名字和身份以及神的语言中的词语？传统的答案是使用字符串。然而，字符串的拼写错误可能会带来灾难性的后果。

如果在解题的关键部分，你用字符串 “jaa” 而不是 “ja” 进行比较，你就会得到一个错误的答案。虽然谜题没有说明风险是什么，但这可能是最好的避免方式。

`enum` 模块让你能够以一种可调试但安全的方式来定义这些东西：

```
import enum

@enum.unique
class Name(enum.Enum):
    A = enum.auto()
    B = enum.auto()
    C = enum.auto()

@enum.unique
class Identity(enum.Enum):
    RANDOM = enum.auto()
    TRUE = enum.auto()
    FALSE = enum.auto()

@enum.unique
class Language(enum.Enum):
    ja = enum.auto()
    da = enum.auto()

```

枚举的一个好处是，在调试日志或异常中，枚举的呈现方式是有帮助的：

```
name = Name.A
identity = Identity.RANDOM
answer = Language.da
print("I suspect", name, "is", identity, "because they answered", answer)

```

```
    I suspect Name.A is Identity.RANDOM because they answered Language.da

```

### functools.singledispatch

在开发游戏的“基础设施”层时，你想通用地处理各种游戏对象，但仍然允许这些对象自定义动作。为了使这个例子更容易解释，假设这是一个基于文本的游戏。当你使用一个对象时，大多数情况下，它只会打印 `You are using <x>`。但是使用一把特殊的剑可能需要随机滚动，否则会失败。

当你获得一个物品时，它通常会被添加到库存中。然而，一块特别重的石头会砸碎一个随机物品。如果发生这种情况，库存中会失去该物体。

处理这个问题的一个方法是在物品上设置 `use` 和 `acquire` 方法。随着游戏复杂性的增加，这些方法会越来越多，使游戏对象变得难以编写。

相反，`functools.singledispatch` 允许你以安全和尊重命名空间的方式追溯性地添加方法。

你可以定义没有行为的类：

```
class Torch:
    name="torch"

class Sword:
    name="sword"

class Rock:
    name="rock"

```

```
import functools

@functools.singledispatch
def use(x):
    print("You use", x.name)

@functools.singledispatch
def acquire(x, inventory):
    inventory.add(x)

```

对于火炬来说，这些通用的实现已经足够了：

```
inventory = set()

def deploy(thing):
    acquire(thing, inventory)
    use(thing)
    print("You have", [item.name for item in inventory])

deploy(Torch())

```

```
    You use torch
    You have ['torch']

```

然而，剑和石头需要一些专门的功能：

```
import random

@use.register(Sword)
def use_sword(sword):
    print("You try to use", sword.name)
    if random.random() < 0.9:
        print("You succeed")
    else:
        print("You fail")

deploy(sword)

```

```
    You try to use sword
    You succeed
    You have ['sword', 'torch']

```

```
import random

@acquire.register(Rock)
def acquire_rock(rock, inventory):
    to_remove = random.choice(list(inventory))
    inventory.remove(to_remove)
    inventory.add(rock)

deploy(Rock())

```

```
    You use rock
    You have ['sword', 'rock']

```

岩石可能压碎了火炬，但你的代码更容易阅读。

### pathlib

从一开始，Python 中文件路径的接口就是“智能字符串操作”。现在，通过 `pathlib`，Python 有了一种面向对象的方法来操作路径。

```
import pathlib

```

```
gitconfig = pathlib.Path.home() / ".gitconfig"
text = gitconfig.read_text().splitlines()

```

诚然，用 `/` 作为操作符来生成路径名有点俗气，但在实践中却不错。像 `.read_text()` 这样的方法允许你从小文件中获取文本，而不需要手动打开和关闭文件句柄。

这使你可以集中精力处理重要的事情：

```
for line in text:
    if not line.strip().startswith("name"):
        continue
    print(line.split("=")[1])

```

```
     Moshe Zadka

```

### 欢迎来到 2014 年

Python 3.4 大约在七年前就发布了，但是在这个版本中首次出现的一些功能非常酷，而且没有得到充分利用。如果你还没使用，那么将他们添加到你的工具箱中。

---

via: <https://opensource.com/article/21/5/python-34-features>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察｜Google 员工承认用户无法在公司的限制下保护自己的隐私

Summary: 更多：• 微软为开发者推出了 Java 开发文档 • Jim Keller：AMD 员工曾认为无法超越 Intel

# 硬核观察｜Google 员工承认用户无法在公司的限制下保护自己的隐私

### Google 员工承认用户无法在公司的限制下保护自己的隐私

根据 The Verge 的报道，在一场针对 Google 的诉讼中所暴露出来的原始文件表示，Google 的高管和工程师都知道，公司让用户保护自己的位置数据的隐私有多么的困难。

>
> 在昨天的硬核观察中，我们提到， Google 表示自己不会在设定功能的时候为自己添加后门，但同时我们也表达了对此的不信任。如今可以看到，Google 在种种方面依然表现出对于个人隐私的渴望。毕竟，他需要通过隐私来获取广告收益。
>
>
>

### 微软为开发者推出了 Java 开发文档

微软发布了其 OpenJDK 的 GA (一般可用版本)，并且发布了新的 Java 开发教程,帮助开发者在 Windows 上更好的开发 Java 应用程序。此次发布提供了 OpenJDK、VScode 插件、Github 使用指南、Java 在 Azure 上的部署教程等信息。

>
> 作为一门使用人数众多的编程语言，终于 Java 也进入了微软的支持列表，为开发者提供了一系列的使用指南。
>
>
>

### Jim Keller：AMD 员工曾认为无法超越 Intel

在 anandtech 的一个针对 Tenstorrent 公司的访谈中，该公司 CTO Jim Keller，前 AMD Zen 架构的研发团队负责人，谈到了一些关于 AMD Zen 的轶闻。他提到，在设计 Zen 的时候，一小部分人相信 Zen 将会在一代人的时间内追赶上 Intel；一部分人认为如果成功了，那会非常的酷；更多的人都认为这个事情不可能。

>
> AMD Zen 架构的成功我们都看在眼里，这让我想起了一句话，「悲观者往往正确，但乐观者往往成功」，正是像 Jim Keller 这样的乐观者，最终带着工程师们做出了 AMD 的 Zen 架构，让 AMD 成功翻身做主人。
>
>
>


不是程序员？那就找到自己的定位

# 不是程序员？那就找到自己的定位

>
> 无论你是已经工作了几十年的还是刚开始从业的非工程型技术人，此建议都可以帮助你确定你的位置归属。
>
>
>

<img src="content_image/album_202105_31_192647jl354n1jezx1ea1c.jpg" alt="" title="Looking at a map for career journey">

在 [本系列第一篇文章](/article-13168-1.html) 中 ，我解释了将人员和角色分为“技术”或“非技术”类别的问题。在 [第二篇文章](/article-13178-1.html) 中，我为不写代码的人分享了一些技术岗位角色。这一次，我将把这次探索总结为——“技术或非技术意味着什么”，并提供一些能够在职业发展上帮到你的建议。

无论你是已经从事技术工作数十年，或是刚刚起步，还是正在寻求职业变更，请考虑本文中来自非技术人员但在技术角色方面取得成功的人士的建议。

>
> “不要把你的工作和身份捆绑起来 —— 把它们分开。”
>
>
> —— Adam Gordon Bell，Earthly Technologies 开发者关系部
>
>
>

转换角色，并不意味着你的技能会消失且你不再具有价值。如果你担任了新角色，则需要专注于该角色的关键技能。培养技能是需要时间的。花点时间，找出新职位的重要技能。

如果你管理工程师们，请鼓励他们提升技术技能的同时发展非工程技能，这些技能往往能比编程能力和技术技能对职业发展和成功产生更显著的变化。

### 做你自己

>
> “不要让其他人定义你是技术人员还是非技术人员。什么是技术人员，什么不是技术人员，以及这是否重要，是人们必须自己搞清楚的事情。”
>
>
> —— Adam Gordon Bell
>
>
>

>
> “永远不要用‘我不是技术人员’为开头进行对话。因为很可能让对方产生‘这点我需要提醒你’的想法，这在面试的时候可从来不会留下好印象，而且还有可能会让人觉得你对自己技能缺乏信心。”
>
>
> —— Mary Thengvall，Camunda 开发者关系总监
>
>
>

避免刻板成见；不是所有的工程师都喜欢《星球大战》或《星际迷航》。不是所有工程师都穿连帽卫衣。工程师也可以和别人交流。

>
> “单单就你的行为举止，旁人就有很多关于技术或非技术方面的看法。在办公室工作的时候，我会穿裙子，因为只有这样我才能舒服一点。”
>
>
> —— Shailvi Wakhlu，Strava 高级数据总监
>
>
>

### 了解你的价值

正如我在第一篇文章中讨论的那样，被打上“非技术”的标签会导致 [冒充者综合症](https://opensource.com/business/15/9/tips-avoiding-impostor-syndrome)。承认自己的价值，不要在自己身上贴上“非技术”标签，因为它会限制你的收入潜力和职业发展。

>
> “人们之所以把我重新包装成其他东西，是因为他们认为我和工程师的刻板印象不一样。我很高兴我没有听这些人的话，因为他们本质上是在告诉我，在我拥有的技能之外，去找一份低薪的工作。”
>
>
> —— Shailvi Wakhlu
>
>
>

>
> “年轻的或者女性技术人，特别是刚接触技术的女性，更容易患上冒名综合症，认为自己技术不够好。比如，‘哦，我只会前端。’，什么叫你*只会*前端？前端也很难的好吧。”
>
>
> —— Liz Harris
>
>
>

### 寻找那些可以提升价值并帮到人们的地方

你不需要创建 PR 就可以参与开源。

>
> “当有人想为开源项目做点贡献时，我总是对他说，‘不要想着，得是一个提交才行、得提一个 PR 才可以。’这就好像，‘不行。怎么才能为那个项目贡献点价值呢？’ 如果你没时间提交 PR，那你是不是提个议题并把要点写下来？”
>
>
> —— Eddie Jaoude，Jaoude Studios 开源程序员
>
>
>

### 思维的多样性有助于事业成功

看看所有角色和人员的价值和贡献。不要根据头衔将人归到同能力的一组。

>
> “要认识到，所有人（包括自己在内），在任何时候，以及事情全貌的重要性。创造力这个事儿不应该由自我驱动。要知道，对于你所做的事情，你可以做的更好，也可以做的更糟。不要害怕寻求帮助，知道到我们在一起。”
>
>
> —— Therese Eberhard，电影/广告和视频场景画师
>
>
>

>
> “在我参加过的黑客马拉松中，我们都是技术人员，组建了一支四五个硬核程序员组成的强大团队，但我们输了。我不骗你，我们输了。在新冠疫情之前，我赢了前六次的黑客马拉松，而且当时团队中一半的人属于其他领域的专家。在我们赢过的比赛中，大多数人会认为团队一半人是非技术的，尽管我不喜欢这个术语，因为这像是给团队/项目贴金。我们之所以获胜，是因为我们对所构建的东西有很多不同的看法。”
>
>
> —— Eddie Jaoude
>
>
>

>
> “我们越能摆脱‘技术/非技术’、‘开发人员/非开发人员’的标签，并理解到一个连续统一的整体存在，我们就越能全力以赴地雇用到合适的人来做这项工作，只要不被你需要‘技术团队’的假设所困扰。”
>
>
> —— Mary Thengvall
>
>
>

我们的社区和团队越多样化，它们的包容性就越大。

>
> “老实说，无论是从社区角度还是从产品角度，我认为，总的来说，最重要的事情都是，我们应该确保我们建立的是一个包容性的社区，这不仅是为了我们的产品，也不仅是为了我们正在使用的技术，还为了整个人类社会，我想……我敢打赌，如果我们做到了这一点，那么作为人类，我们就比过去更进步了。”
>
>
> —— Leon Stigter，Lightbend 高级产品经理
>
>
>

如果你以非程序员的技术身份工作，你会给那些认为自己“非技术”的人（或被他人认为是“非技术”的人）提供什么建议？ 在评论中分享你的见解。

---

via: <https://opensource.com/article/21/2/advice-non-technical>

作者：[Dawn Parzych](https://opensource.com/users/dawnparzych) 选题：[lujun9972](https://github.com/lujun9972) 译者：[max27149](https://github.com/max27149) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


在 Flutter 移动应用程序中创建一个列表

Summary: 了解如何创建 Flutter 应用的界面以及如何在它们之间进行数据传递。

了解如何创建 Flutter 应用的界面以及如何在它们之间进行数据传递。

# 在 Flutter 移动应用程序中创建一个列表

>
> 了解如何创建 Flutter 应用的界面以及如何在它们之间进行数据传递。
>
>
>

Flutter 是一个流行的开源工具包，它可用于构建跨平台的应用。在文章《[用 Flutter 创建移动应用](/article-12693-1.html)》中，我已经向大家展示了如何在 Linux 中安装 [Flutter](https://flutter.dev/) 并创建你的第一个应用。而这篇文章，我将向你展示如何在你的应用中添加一个列表，点击每一个列表项可以打开一个新的界面。这是移动应用的一种常见设计方法，你可能以前见过的，下面有一个截图，能帮助你对它有一个更直观的了解：

Flutter 使用 [Dart](https://dart.dev/) 语言。在下面的一些代码片段中，你会看到以斜杠开头的语句。两个斜杠（`//`）是指代码注释，用于解释某些代码片段。三个斜杠（`///`）则表示的是 Dart 的文档注释，用于解释 Dart 类和类的属性，以及其他的一些有用的信息。

### 查看Flutter应用的主要部分

Flutter 应用的典型入口点是 `main()` 函数，我们通常可以在文件 `lib/main.dart` 中找到它:

```
void main() {
 runApp(MyApp());
}

```

应用启动时，`main()` 会被调用，然后执行 `MyApp()`。 `MyApp` 是一个无状态微件（`StatelessWidget`），它包含了`MaterialApp()` 微件中所有必要的应用设置（应用的主题、要打开的初始页面等）：

```
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     title: 'Flutter Demo',
     theme: ThemeData(
       primarySwatch: Colors.blue,
       visualDensity: VisualDensity.adaptivePlatformDensity,
     ),
     home: MyHomePage(title: 'Flutter Demo Home Page'),
   );
 }
}

```

生成的 `MyHomePage()` 是应用的初始页面，是一个有状态的微件，它包含包含可以传递给微件构造函数参数的变量（从上面的代码看，我们传了一个 `title` 变量给初始页面的构造函数）：

```
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

```

有状态微件（`StatefulWidget`）表示这个微件可以拥有自己的状态：`_MyHomePageState`。调用 `_MyHomePageState` 中的 `setState()` 方法，可以重新构建用户界面：

```
class _MyHomePageState extends State<MyHomePage> {
 int _counter = 0; // Number of taps on + button.

 void _incrementCounter() { // Increase number of taps and update UI by calling setState().
   setState(() {
     _counter++;
   });
 }
 ...
}

```

不管是有状态的，还是无状态的微件，它们都有一个 `build()` 方法，该方法负责微件的 UI 外观。

```
@override
Widget build(BuildContext context) {
 return Scaffold( // Page widget.
   appBar: AppBar( // Page app bar with title and back button if user can return to previous screen.
     title: Text(widget.title), // Text to display page title.
   ),
   body: Center( // Widget to center child widget.
     child: Column( // Display children widgets in column.
       mainAxisAlignment: MainAxisAlignment.center,
       children: <Widget>[
         Text( // Static text.
           'You have pushed the button this many times:',
         ),
         Text( // Text with our taps number.
           '$_counter', // $ sign allows us to use variables inside a string.
           style: Theme.of(context).textTheme.headline4,// Style of the text, “Theme.of(context)” takes our context and allows us to access our global app theme.
         ),
       ],
     ),
   ),
        // Floating action button to increment _counter number.
   floatingActionButton: FloatingActionButton(
     onPressed: _incrementCounter,
     tooltip: 'Increment',
     child: Icon(Icons.add),
   ),
 );
}

```

### 修改你的应用

一个好的做法是，把 `main()` 方法和其他页面的代码分开放到不同的文件中。要想将它们分开，你需要右击 `lib` 目录，然后选择 “New > Dart File” 来创建一个 .dart 文件：

将新建的文件命名为 `items_list_page`。

切换回到 `main.dart` 文件，将 `MyHomePage` 和 `_MyHomePageState` 中的代码，剪切并粘贴到我们新建的文件。然后将光标放到 `StatefulWidget` 上（下面红色的下划线处）, 按 `Alt+Enter` 后出现下拉列表，然后选择 `package:flutter/material.dart`：

经过上面的操作我们将 `flutter/material.dart` 包添加到了 `main.dart` 文件中，这样我们就可以使用 Flutter 提供的默认的 material 主题微件。

然后, 在类名 `MyHomePage` 右击，“Refactor > Rename...”将其重命名为 `ItemsListPage`：

Flutter 识别到你重命名了 `StatefulWidget` 类，它会自动将它的 `State` 类也跟着重命名:

回到 `main.dart` 文件，将文件名 `MyHomePage` 改为 `ItemsListPage`。 一旦你开始输入, 你的 Flutter 集成开发环境（可能是 IntelliJ IDEA 社区版、Android Studio 和 VS Code 或 [VSCodium](https://opensource.com/article/20/6/open-source-alternatives-vs-code)），会给出自动代码补完的建议。

按回车键即可完成输入，缺失的导入语句会被自动添加到文件的顶部。

到此，你已经完成了初始设置。现在你需要在 `lib` 目录创建一个新的 .dart 文件，命名为 `item_model`。（注意，类命是大写驼峰命名，一般的文件名是下划线分割的命名。）然后粘贴下面的代码到新的文件中：

```
/// Class that stores list item info:
/// [id] - unique identifier, number.
/// [icon] - icon to display in UI.
/// [title] - text title of the item.
/// [description] - text description of the item.
class ItemModel {
 // class constructor
 ItemModel(this.id, this.icon, this.title, this.description);

 // class fields
 final int id;
 final IconData icon;
 final String title;
 final String description;
}

```

回到 `items_list_page.dart` 文件，将已有的 `_ItemsListPageState` 代码替换为下面的代码:

```
class _ItemsListPageState extends State<ItemsListPage> {

// Hard-coded list of [ItemModel] to be displayed on our page.
 final List<ItemModel> _items = [
   ItemModel(0, Icons.account_balance, 'Balance', 'Some info'),
   ItemModel(1, Icons.account_balance_wallet, 'Balance wallet', 'Some info'),
   ItemModel(2, Icons.alarm, 'Alarm', 'Some info'),
   ItemModel(3, Icons.my_location, 'My location', 'Some info'),
   ItemModel(4, Icons.laptop, 'Laptop', 'Some info'),
   ItemModel(5, Icons.backup, 'Backup', 'Some info'),
   ItemModel(6, Icons.settings, 'Settings', 'Some info'),
   ItemModel(7, Icons.call, 'Call', 'Some info'),
   ItemModel(8, Icons.restore, 'Restore', 'Some info'),
   ItemModel(9, Icons.camera_alt, 'Camera', 'Some info'),
 ];

 @override
 Widget build(BuildContext context) {
   return Scaffold(
       appBar: AppBar(
         title: Text(widget.title),
       ),
       body: ListView.builder( // Widget which creates [ItemWidget] in scrollable list.
         itemCount: _items.length, // Number of widget to be created.
         itemBuilder: (context, itemIndex) => // Builder function for every item with index.
             ItemWidget(_items[itemIndex], () {
           _onItemTap(context, itemIndex);
         }),
       ));
 }

 // Method which uses BuildContext to push (open) new MaterialPageRoute (representation of the screen in Flutter navigation model) with ItemDetailsPage (StateFullWidget with UI for page) in builder.
 _onItemTap(BuildContext context, int itemIndex) {
   Navigator.of(context).push(MaterialPageRoute(
       builder: (context) => ItemDetailsPage(_items[itemIndex])));
 }
}

// StatelessWidget with UI for our ItemModel-s in ListView.
class ItemWidget extends StatelessWidget {
 const ItemWidget(this.model, this.onItemTap, {Key key}) : super(key: key);

 final ItemModel model;
 final Function onItemTap;

 @override
 Widget build(BuildContext context) {
   return InkWell( // Enables taps for child and add ripple effect when child widget is long pressed.
     onTap: onItemTap,
     child: ListTile( // Useful standard widget for displaying something in ListView.
       leading: Icon(model.icon),
       title: Text(model.title),
     ),
   );
 }
}

```

为了提高代码的可读性，可以考虑将 `ItemWidget` 作为一个单独的文件放到 `lib` 目录中。

现在唯一缺少的是 `ItemDetailsPage` 类。在 `lib` 目录中我们创建一个新文件并命名为 `item_details_page`。然后将下面的代码拷贝进去：

```
import 'package:flutter/material.dart';

import 'item_model.dart';

/// Widget for displaying detailed info of [ItemModel]
class ItemDetailsPage extends StatefulWidget {
 final ItemModel model;

 const ItemDetailsPage(this.model, {Key key}) : super(key: key);

 @override
 _ItemDetailsPageState createState() => _ItemDetailsPageState();
}

class _ItemDetailsPageState extends State<ItemDetailsPage> {
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text(widget.model.title),
     ),
     body: Center(
       child: Column(
         children: [
           const SizedBox(height: 16),
           Icon(
             widget.model.icon,
             size: 100,
           ),
           const SizedBox(height: 16),
           Text(
             'Item description: ${widget.model.description}',
             style: TextStyle(fontSize: 18),
           )
         ],
       ),
     ),
   );
 }
}

```

上面的代码几乎没什么新东西，不过要注意的是 `_ItemDetailsPageState` 里使用了 `widget.item.title` 这样的语句，它让我们可以从有状态类中引用到其对应的微件（`StatefulWidget`）。

### 添加一些动画

现在让我们来添加一些基础的动画：

1. 找到 `ItemWidget` 代码块（或者文件）
2. 将光标放到 `build()` 方法中的 `Icon()` 微件上
3. 按 `Alt+Enter`，然后选择“Wrap with widget...”

输入 `Hero`，然后从建议的下拉列表中选择 `Hero((Key key, @required this, tag, this.create))`：

下一步, 给 Hero 微件添加 `tag` 属性 `tag: model.id`：

最后我们在 `item_details_page.dart` 文件中做相同的修改：

前面的步骤，其实我们是用 `Hero()` 微件对 `Icon()` 微件进行了封装。还记得吗？前面我们定义 `ItemModel` 类时，定义了一个 `id field`，但没有在任何地方使用到。因为 Hero 微件会为其每个子微件添加一个唯一的标签。当 Hero 检测到不同页面（`MaterialPageRoute`）中存在相同标签的 Hero 时，它会自动在这些不同的页面中应用过渡动画。

可以在安卓模拟器或物理设备上运行我们的应用来测试这个动画。当你打开或者关闭列表项的详情页时，你会看到一个漂亮的图标动画：

### 收尾

这篇教程，让你学到了:

* 一些符合标准的，且能用于自动创建应用的组件。
* 如何添加多个页面以及在页面间传递数据。
* 如何给多个页面添加简单的动画。

如果你想了解更多，查看 Flutter 的 [文档](https://flutter.dev/docs)（有一些视频和样例项目的链接，还有一些创建 Flutter 应用的“秘方”）与 [源码](https://github.com/flutter)，源码的开源许可证是 BSD 3。

---

via: <https://opensource.com/article/20/11/flutter-lists-mobile-app>

作者：[Vitaly Kuprenko](https://opensource.com/users/kooper) 选题：[lujun9972](https://github.com/lujun9972) 译者：[ywxgod](https://github.com/ywxgod) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 | 微软前高管解释了为什么 Windows 10 删除了开机声音

Linux中国 ｜ 小白

Summary:
更多 · 英特尔以一些奇怪的角度嘲讽苹果 M1 芯片  ·
 QUIC 协议正式发布了 RFC 9000 ，成为 IETF 标准

# 硬核观察 | 微软前高管解释了为什么 Windows 10 删除了开机声音

### 微软前高管解释了为什么 Windows 10 删除了开机声音

Windows 用户体验团队项目管理前总监 Jensen Harris 在 Youtube 上发布的[一段视频](https://www.youtube.com/watch?v=UWUBjM2LNJU&t=632s&ab_channel=JensenHarris)解释了为什么从 2010 年开始， Windows 上开始听不到开机声音。

据 Jensen 描述，在 2008 年，他们意识到人们使用电脑已经不同以往，PC 可以在卧室或床上使用，而开机声音在卧室的夜晚显得十分吵闹，可能会吵醒配偶和小孩。

>
> 在 Jensen 的视频中，详细的介绍了开机音频的历史，我强烈建议你去看看整个视频，了解一下开机声音的演变历史。
>
>
>

### 英特尔以一些奇怪的角度嘲讽苹果 M1 芯片

Intel 的首席性能策略师 Ryan Shrout 在最近的一个针对第 11 代 Intel H系列处理器进行推广时，吐槽了 Apple 的M1 芯片。不过，吐槽的点有些无厘头，

Intel 吐槽 macOS 上无法运行一些热门的游戏，但其实此事与 Intel 还是 M1 芯片无关；Intel 还吐槽过去所有的 MacBook Pro 的 PC 都不如 Intel 的第 11 代处理器性能强劲。

>
> Intel 的吐槽看起来颇为无厘头，明明是芯片之争，但吐槽的似乎都是系统。背后可能是 Intel 发现苹果在逃离 Intel 生态后，决定转向支持 PC 市场。
>
>
>

### QUIC 协议正式发布了 RFC 9000 ，成为 IETF 标准

QUIC 协议全称为”quick udp internet connection“，快速 UDP 互联网连接，相比于标准的 HTTP2.0 ，他提供了更加安全、可靠和低延时等特性。
QUIC 协议是将过去需要 TCP 协议传递的数据通过由 UDP 传递并添加冗余数据的方式，来确保数据的可靠性，确保服务端所接收到的数据是可靠的。

>
> QUIC 协议发布的 RFC 是互联网基础设施前进的一个重要的里程碑。
>
>
>


Python 3.5 带给我们的方便的矩阵以及其他改进

Summary: 探索一些未被充分利用但仍然有用的 Python 特性。

探索一些未被充分利用但仍然有用的 Python 特性。

# Python 3.5 带给我们的方便的矩阵以及其他改进

>
> 探索一些未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202106_01_201953lua9t9f3vvwqbqet.jpg" alt="" title="Hacker code matrix">

这是 Python 3.x 首发特性系列文章的第六篇。Python 3.5 在 2015 年首次发布，尽管它已经发布了很长时间，但它引入的许多特性都没有被充分利用，而且相当酷。下面是其中的三个。

### @ 操作符

`@` 操作符在 Python 中是独一无二的，因为在标准库中没有任何对象可以实现它！它是为了在有矩阵的数学包中使用而添加的。

矩阵有两个乘法的概念。元素积是用 `*` 运算符完成的。但是矩阵组合（也被认为是乘法）需要自己的符号。它是用 `@` 完成的。

例如，将一个“八转”矩阵（将轴旋转 45 度）与自身合成，就会产生一个四转矩阵。

```
import numpy

hrt2 = 2**0.5 / 2
eighth_turn = numpy.array([
    [hrt2, hrt2],
    [-hrt2, hrt2]
])
eighth_turn @ eighth_turn

```

```
    array([[ 4.26642159e-17,  1.00000000e+00],
           [-1.00000000e+00, -4.26642159e-17]])

```

浮点数是不精确的，这比较难以看出。从结果中减去四转矩阵，将其平方相加，然后取其平方根，这样就比较容易检查。

这是新运算符的一个优点：特别是在复杂的公式中，代码看起来更像基础数学：

```
almost_zero = ((eighth_turn @ eighth_turn) - numpy.array([[0, 1], [-1, 0]]))**2
round(numpy.sum(almost_zero) ** 0.5, 10)

```

```
    0.0

```

### 参数中的多个关键词字典

Python 3.5 使得调用具有多个关键字-参数字典的函数成为可能。这意味着多个默认值的源可以与更清晰的代码”互操作“。

例如，这里有个可笑的关键字参数的函数：

```
def show_status(
    *,
    the_good=None,
    the_bad=None,
    the_ugly=None,
    fistful=None,
    dollars=None,
    more=None
):
    if the_good:
        print("Good", the_good)
    if the_bad:
        print("Bad", the_bad)
    if the_ugly:
        print("Ugly", the_ugly)
    if fistful:
        print("Fist", fistful)
    if dollars:
        print("Dollars", dollars)
    if more:
        print("More", more)

```

当你在应用中调用这个函数时，有些参数是硬编码的：

```
defaults = dict(
    the_good="You dig",
    the_bad="I have to have respect",
    the_ugly="Shoot, don't talk",
)

```

从配置文件中读取更多参数：

```
import json

others = json.loads("""
{
"fistful": "Get three coffins ready",
"dollars": "Remember me?",
"more": "It's a small world"
}
""")

```

你可以从两个源一起调用这个函数，而不必构建一个中间字典：

```
show_status(**defaults, **others)

```

```
    Good You dig
    Bad I have to have respect
    Ugly Shoot, don't talk
    Fist Get three coffins ready
    Dollars Remember me?
    More It's a small world

```

### os.scandir

`os.scandir` 函数是一种新的方法来遍历目录内容。它返回一个生成器，产生关于每个对象的丰富数据。例如，这里有一种打印目录清单的方法，在目录的末尾跟着 `/`：

```
for entry in os.scandir(".git"):
    print(entry.name + ("/" if entry.is_dir() else ""))

```

```
    refs/
    HEAD
    logs/
    index
    branches/
    config
    objects/
    description
    COMMIT_EDITMSG
    info/
    hooks/

```

### 欢迎来到 2015 年

Python 3.5 在六年前就已经发布了，但是在这个版本中首次出现的一些特性非常酷，而且没有得到充分利用。如果你还没使用，那么将他们添加到你的工具箱中。

---

via: <https://opensource.com/article/21/5/python-35-features>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Nyxt 浏览器：一个受 Emacs 和 Vim 启发的面向键盘的网页浏览器

# Nyxt 浏览器：一个受 Emacs 和 Vim 启发的面向键盘的网页浏览器

你可以得到很多适用于 Linux 的开源网页浏览器，不只是基于 Chrome 的浏览器，而且还有 [其它的替代品](https://itsfoss.com/open-source-browsers-linux/)。

它们大多数都侧重于提供漂亮的用户体验，并同时兼顾隐私功能。

然而，Nyxt 浏览器可能不是为最好的用户体验而建立的，而是为资深用户喜欢的某些东西而打造的。

### Nyxt 浏览器：专注于键盘快捷键和命令的开源浏览器

[Nyxt](https://nyxt.atlas.engineer/) 是一个面向键盘的开源网页浏览器，可在 Linux 和 macOS 上使用。

当然，不是每个资深用户都会去使用键盘快捷键，但这旨在满足那些喜欢通过键盘导航的用户的需求。

它的灵感来自于 Vim 和 Emacs 中的键盘快捷键的工作方式 —— 所以如果你对这些编辑器很熟悉，那么你也会对这些快捷键感到熟悉。

与主流的网页浏览器不同，你不必在多个设置和菜单中导航，只需一个快速快捷键或一个命令，你就会获得所有你需要访问的功能。

如果你想知道的话，它不特定于某种网页引擎，它目前支持 WebEngine 和 WebKit。

因此，如果你是一个喜欢使用键盘导航的人，它可以节省时间并改善你的浏览体验。

它提供了相当多的有用功能，我将在下面指出。

### Nyxt 浏览器的特点

你会发现这里提供了许多非常规的功能。在探索这里提到的每一个关键亮点之前，你可能想先浏览一下官方文档（按 `F1` 找到它），你可以在欢迎屏幕中可以找到链接。

* 无损的树形的历史记录（跟踪你的浏览历史的确切层次，并轻松回忆你导航到的内容）
* 剪贴板历史，帮助你快速找到你之前复制的内容
* 开始输入命令的键盘快捷方式（`CTRL+Space`）
* 使用键盘快捷键在冗长的文件中导航，可以跳到一个特定的标题
* 缓冲区替代了标签，它将每个标签的行为和设置相互隔离
* 通过将多个标签映射到一个共同的元素来一同关闭
* 无鼠标导航
* 使用搜索快速找到一个缓冲区，而不是在许多标签中寻找它
* 能够根据你的工作流程运行简短的脚本
* 可定制的自动填写功能，你也可以在表单中自动填写当前日期
* 内置的广告拦截器

除了上面提到的功能外，你还可以切换**黑暗模式**、**HTTPS 模式**，以及在命令菜单中有大量的选项。

此外，它是完全可定制和可编程的。因此，你可以选择为自己量身定做。

### 在 Linux 中安装 Nyxt 浏览器

对于基于 Ubuntu 的发行版，你可以从 [官方下载页面](https://nyxt.atlas.engineer/download) 找到一个 deb 包。

如果你还不会，你可能想读一下 [安装 deb 文件的方法](https://itsfoss.com/install-deb-files-ubuntu/)。

它也为 Arch Linux 用户提供了 [AUR](https://itsfoss.com/aur-arch-linux/)，并为 Alpine Linux、Nix 和 Guix 提供了包。

如果你需要编译它，你也可以在 [GitHub 页面](https://github.com/atlas-engineer/nyxt) 中找到源代码。

* [下载 Nyxt 浏览器](https://nyxt.atlas.engineer/download)

### 总结

虽然 Nyxt 浏览器可能不是最友好的浏览体验，但对于能够充分利用键盘快捷键和命令的用户来说，它肯定是一个特殊的选择。

如果你想要一个无鼠标的导航体验，这是一个值得尝试的浏览器。我建议你尝试一下 —— 但如果你一般不使用键盘快捷键来导航，这对你来说将是一个复杂的体验。

你尝试过 Nyxt 浏览器吗？请在下面的评论中告诉我你的想法。

---

via: <https://itsfoss.com/nyxt-browser/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #290 蚂蚁再次开源 OceanBase 数据库

Summary: 更多：• AI 出现在战争之中 • 谷歌承诺 FLoC 隐私沙箱不留后门，广告商对此持怀疑态度

# 硬核观察 #290 蚂蚁再次开源 OceanBase 数据库

### 蚂蚁再次开源 OceanBase 数据库

从 2010 诞生以来，[OceanBase](https://open.oceanbase.com/) 再次[开源](https://gitee.com/oceanbase)了。在 6 月 1 日召开的 OceanBase 发布会上，蚂蚁旗下的奥星贝斯公司发布了最新的 OceanBase 3.0 版本，并宣布全面开源，采用 “Open Core” 模式。此次开源采用了国产的木兰许可证 MulanPubL-2.0，开源了多达 300 万行的核心代码。OceanBase 称，“同时具备了在事务处理和数据分析两类任务的高性能能力，升级为一款支持 HTAP 混合负载的企业级分布式数据库。和过去相比，事务处理性能提升 50%，数据分析性能提升 10 倍。”

>
> 据一些反馈称，OceanBase 数据库指标不错。虽然经历了开源、闭源又开源，但是最终还是走向了开源，并日益强大，也值得肯定。
>
>
>

### AI 出现在战争之中

以色列军方称，最近在加沙地带爆发的以巴冲突是[世界首次 AI 战争](https://www.jpost.com/arab-israeli-conflict/gaza-news/guardian-of-the-walls-the-first-ai-war-669371)，AI 首次成为战争中的力量倍增器。以色列军队除了依赖已有的情报，军方还在之前几年建立一个 AI 技术平台，对收集到的所有数据进行分析，利用 AI 向情报部队生成建议，情报部队根据建议制定高价值目标，交给军方实施打击。军方相信使用 AI 有助于缩短战斗时间。

此外，也有报道称，一架携带武器的无人机在没有指定命令的情况下自主[猎杀了一个人类目标](https://nypost.com/2021/05/29/killer-drone-hunted-down-a-human-target-without-being-told-to/)。

>
> 科技的进步，不知道最终是造福人类，还是消灭人类。
>
>
>

### 谷歌承诺 FLoC 隐私沙箱不留后门，广告商对此持怀疑态度

谷歌一直在积极向 Web 浏览器的 Cookie 发起战争，尤其是那些严重侵犯用户隐私的第三方跨站追踪 Cookie。谷歌给出了两个解决方案：其一是隐私沙箱，另一个就是所谓的“联合学习队列”（FLoC）。

但是包括电子前沿基金会（EFF）在内的组织机构、各大浏览器开发商、甚至广告商们，都对谷歌的 FLoC 追踪提出了严厉的批评。谷歌称，该公司不会在 FLoC 中留有后门，也不会按照其它广告商与合作伙伴的规则意图来行事。但是这并不让人信服，因为谷歌拥有保留第一方属性的个人用户数据的权利，意味着本质上仍可能换汤不换药。更何况，谷歌很有可能在不久的将来推翻这一承诺，正如此前屡次发生过的类似事件那样。

>
> 从一个广告商的角度来做的这些事情，自然没有足够的说服力让大家相信，更何况谷歌早放弃了“不作恶”守则。
>
>
>


Make 命令未找到？这是修复它的方法

Summary: 有一天，我试图在一个新的 Ubuntu 系统上编译一个程序，当我试图使用 make 命令时，它向我抛出一个错误

# Make 命令未找到？这是修复它的方法

有一天，我试图在一个新的 Ubuntu 系统上编译一个程序，当我试图使用 `make` 命令时，它向我抛出一个错误：

```
The program 'make' is currently not installed. You can install it by typing:
sudo apt install make

```

这表明 `make` 命令还没有安装。你可以用这些命令在 Ubuntu 上逐步安装 `make`：

```
sudo apt update
sudo apt install make

```

第一个命令是更新本地的软件包缓存。如果是一个新安装的 Ubuntu 系统，这是很有必要的。有了刷新的软件包缓存，你的系统就会知道应该从哪个仓库下载 `make` 包。

并验证 `make` 是否已经正确安装：

```
make --version

```

### 在 Ubuntu 上安装 make 的更好方法

安装 `make` 命令的一个更好的方法是使用 `build-essential` 包。这个包包含 `make`、`gcc`、`g++` 和其他一些编译器和开发工具。

```
sudo apt install build-essential

```

安装了这个 `build-essential` 包后，你就可以[在 Linux 中轻松地运行 C/C++ 程序](https://itsfoss.com/c-plus-plus-ubuntu/)。

### 如果 make 已经安装了，但它没有工作怎么办？

在一些罕见的情况下，可能会发生 `make` 已经安装了，但却无法工作的情况。

其原因是 `make` 命令不在 `$PATH` 变量中。你可以用这个命令重新安装 `make`：

```
sudo apt install --reinstall make

```

如果这不起作用，你可以尝试 [手动添加二进制文件到你的 PATH 中](https://itsfoss.com/add-directory-to-path-linux/)，但这应该不需要手动。

我希望这个快速提示能帮助你。仍然有问题或对相关主题有疑问？请随时在评论区留言。

---

via: <https://itsfoss.com/make-command-not-found-ubuntu/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用 systemd 作为问题定位工具

# 使用 systemd 作为问题定位工具

>
> 虽然 systemd 并非真正的故障定位工具，但其输出中的信息为解决问题指明了方向。
>
>
>

<img src="content_image/album_202106_02_214321uqzzrqza9mlt9iam.jpg" alt="" title="Magnifying glass on code">

没有人会认为 systemd 是一个故障定位工具，但当我的 web 服务器遇到问题时，我对 systemd 和它的一些功能的不断了解帮助我找到并规避了问题。

我遇到的问题是这样，我的服务器 yorktown 为我的家庭办公网络提供名称服务 、DHCP、NTP、HTTPD 和 SendMail 邮件服务，它在正常启动时未能启动 Apache HTTPD 守护程序。在我意识到它没有运行之后，我不得不手动启动它。这个问题已经持续了一段时间，我最近才开始尝试去解决它。

你们中的一些人会说，systemd 本身就是这个问题的原因，根据我现在了解的情况，我同意你们的看法。然而，我在使用 SystemV 时也遇到了类似的问题。（在本系列文章的 [第一篇](https://opensource.com/article/20/4/systemd) 中，我探讨了围绕 systemd 作为旧有 SystemV 启动程序和启动脚本的替代品所产生的争议。如果你有兴趣了解更多关于 systemd 的信息，也可以阅读 [第二篇](https://opensource.com/article/20/4/systemd-startup) 和 [第三篇](https://opensource.com/article/20/4/understanding-and-using-systemd-units) 文章。）没有完美的软件，systemd 和 SystemV 也不例外，但 systemd 为解决问题提供的信息远远多于 SystemV。

### 确定问题所在

找到这个问题根源的第一步是确定 httpd 服务的状态：

```
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Thu 2020-04-16 11:54:37 EDT; 15min ago
     Docs: man:httpd.service(8)
  Process: 1101 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 1101 (code=exited, status=1/FAILURE)
   Status: "Reading configuration..."
      CPU: 60ms

Apr 16 11:54:35 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 11:54:37 yorktown.both.org httpd[1101]: (99)Cannot assign requested address: AH00072: make_sock: could not bind to address 192.168.0.52:80
Apr 16 11:54:37 yorktown.both.org httpd[1101]: no listening sockets available, shutting down
Apr 16 11:54:37 yorktown.both.org httpd[1101]: AH00015: Unable to open logs
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Failed with result 'exit-code'.
Apr 16 11:54:37 yorktown.both.org systemd[1]: Failed to start The Apache HTTP Server.
[root@yorktown ~]#

```

这种状态信息是 systemd 的功能之一，我觉得比 SystemV 提供的任何功能都要有用。这里的大量有用信息使我很容易得出逻辑性的结论，让我找到正确的方向。我从旧的 `chkconfig` 命令中得到的是服务是否在运行，以及如果它在运行的话，进程 ID（PID）是多少。这可没多大帮助。

该状态报告中的关键条目显示，HTTPD 不能与 IP 地址绑定，这意味着它不能接受传入的请求。这表明网络启动速度不够快，因为 IP 地址还没有设置好，所以 HTTPD 服务还没有准备好与 IP 地址绑定。这是不应该发生的，所以我查看了我的网络服务的 systemd 启动配置文件；在正确的 `after` 和 `requires` 语句下，所有这些似乎都没问题。下面是我服务器上的 `/lib/systemd/system/httpd.service` 文件：

```
# Modifying this file in-place is not recommended, because changes
# will be overwritten during package upgrades.  To customize the
# behaviour, run "systemctl edit httpd" to create an override unit.

# For example, to pass additional options (such as -D definitions) to
# the httpd binary at startup, create an override unit (as is done by
# systemctl edit) and enter the following:

#    [Service]
#    Environment=OPTIONS=-DMY_DEFINE

[Unit]
Description=The Apache HTTP Server
Wants=httpd-init.service
After=network.target remote-fs.target nss-lookup.target httpd-init.service
Documentation=man:httpd.service(8)

[Service]
Type=notify
Environment=LANG=C

ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
# Send SIGWINCH for graceful stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target

```

`httpd.service` 单元文件明确规定，它应该在 `network.target` 和 `httpd-init.service`（以及其他）之后加载。我试着用 `systemctl list-units` 命令找到所有这些服务，并在结果数据流中搜索它们。所有这些服务都存在，应该可以确保在设置网络 IP 地址之前，httpd 服务没有加载。

### 第一个解决方案

在互联网上搜索了一下，证实其他人在 httpd 和其他服务也遇到了类似的问题。这似乎是由于其中一个所需的服务向 systemd 表示它已经完成了启动，但实际上它却启动了一个尚未完成的子进程。通过更多搜索，我想到了一个规避方法。

我搞不清楚为什么花了这么久才把 IP 地址分配给网卡。所以我想，如果我可以将 HTTPD 服务的启动推迟合理的一段时间，那么 IP 地址就会在那个时候分配。

幸运的是，上面的 `/lib/systemd/system/httpd.service` 文件提供了一些方向。虽然它说不要修改它，但是它还是指出了如何操作：使用 `systemctl edit httpd` 命令，它会自动创建一个新文件（`/etc/systemd/system/httpd.service.d/override.conf`）并打开 [GNU Nano](https://www.nano-editor.org/) 编辑器（如果你对 Nano 不熟悉，一定要看一下 Nano 界面底部的提示）。

在新文件中加入以下代码并保存：

```
[root@yorktown ~]# cd /etc/systemd/system/httpd.service.d/
[root@yorktown httpd.service.d]# ll
total 4
-rw-r--r-- 1 root root 243 Apr 16 11:43 override.conf
[root@yorktown httpd.service.d]# cat override.conf
# Trying to delay the startup of httpd so that the network is
# fully up and running so that httpd can bind to the correct
# IP address
#
# By David Both, 2020-04-16

[Service]
ExecStartPre=/bin/sleep 30

```

这个覆盖文件的 `[Service]` 段有一行代码，将 HTTPD 服务的启动时间推迟了 30 秒。下面的状态命令显示了等待时间里的服务状态：

```
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: activating (start-pre) since Thu 2020-04-16 12:14:29 EDT; 28s ago
     Docs: man:httpd.service(8)
Cntrl PID: 1102 (sleep)
    Tasks: 1 (limit: 38363)
   Memory: 260.0K
      CPU: 2ms
   CGroup: /system.slice/httpd.service
           └─1102 /bin/sleep 30

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.
[root@yorktown ~]#

```

这个命令显示了 30 秒延迟过后 HTTPD 服务的状态。该服务已经启动并正常运行。

```
[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: active (running) since Thu 2020-04-16 12:15:01 EDT; 1min 18s ago
     Docs: man:httpd.service(8)
  Process: 1102 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
 Main PID: 1567 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
    Tasks: 213 (limit: 38363)
   Memory: 21.8M
      CPU: 82ms
   CGroup: /system.slice/httpd.service
           ├─1567 /usr/sbin/httpd -DFOREGROUND
           ├─1569 /usr/sbin/httpd -DFOREGROUND
           ├─1570 /usr/sbin/httpd -DFOREGROUND
           ├─1571 /usr/sbin/httpd -DFOREGROUND
           └─1572 /usr/sbin/httpd -DFOREGROUND

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.

```

我本来可以实验下更短的延迟时间是否也能奏效，但是我的系统并不用那么严格，所以我觉得不这样做。目前系统的工作状态很可靠，所以我很高兴。

因为我收集了所有这些信息，我将其作为 Bug[1825554](https://bugzilla.redhat.com/show_bug.cgi?id=1825554) 报告给红帽 Bugzilla。我相信报告 Bug 比抱怨 Bug 更有有用。

### 更好的解决方案

把这个问题作为 bug 上报几天后，我收到了回复，表示 systemd 只是一个管理工具，如果 httpd 需要在满足某些要求之后被拉起，需要在单元文件中表达出来。这个回复指引我去查阅 `httpd.service` 的手册页。我希望我能早点发现这个，因为它是比我自己想出的更优秀的解决方案。这种方案明确的针对了前置目标单元，而不仅仅是随机延迟。

来自 [httpd.service 手册页](https://www.mankier.com/8/httpd.service#Description-Starting_the_service_at_boot_time):

>
> **在启动时开启服务**
>
>
> `httpd.service` 和 `httpd.socket` 单元默认是 *禁用* 的。为了在启动阶段开启 httpd 服务，执行：`systemctl enable httpd.service`。在默认配置中，httpd 守护进程会接受任何配置好的 IPv4 或 IPv6 地址的 80 口上的连接（如果安装了 mod\_ssl，就会接受 443 端口上的 TLS 连接）。
>
>
> 如果 httpd 被配置成依赖任一特定的 IP 地址（比如使用 `Listen` 指令），该地址可能只在启动阶段可用，又或者 httpd 依赖其他服务（比如数据库守护进程），那么必须配置该服务，以确保正确的启动顺序。
>
>
> 例如，为了确保 httpd 在所有配置的网络接口配置完成之后再运行，可以创建一个带有以下代码段的 drop-in 文件（如上述）：
>
>
>
> ```
> [Unit]
> After=network-online.target
> Wants=network-online.target
>
> ```
>
>

我仍然觉得这是个 bug，因为在 `httpd.conf` 配置文件中使用 Listen 指令是很常见的，至少在我的经验中。我一直在使用 Listen 指令，即使在只有一个 IP 地址的主机上，在多个网卡和 IP 地址的机器上这显然也是有必要的。在 `/usr/lib/systemd/system/httpd.service` 默认配置文件中加入上述几行，对不使用 `Listen` 指令的不会造成问题，对使用 `Listen` 指令的则会规避这个问题。

同时，我将使用建议的方法。

### 下一步

本文描述了一个我在服务器上启动 Apache HTTPD 服务时遇到的一个问题。它指引你了解我在解决这个问题上的思路，并说明了我是如何使用 systemd 来协助解决问题。我也介绍了我用 systemd 实现的规避方法，以及我按照我的 bug 报告得到的更好的解决方案。

如我在开头处提到的那样，这有很大可能是一个 systemd 的问题，特别是 httpd 启动的配置问题。尽管如此，systemd 还是提供了工具让我找到了问题的可能来源，并制定和实现了规避方案。两种方案都没有真正令我满意地解决问题。目前，这个问题根源依旧存在，必须要解决。如果只是在 `/usr/lib/systemd/system/httpd.service` 文件中添加推荐的代码，那对我来说是可行的。

在这个过程中我发现了一件事，我需要了解更多关于定义服务启动顺序的知识。我会在下一篇文章中探索这个领域，即本系列的第五篇。

### 资源

网上有大量的关于 systemd 的参考资料，但是大部分都有点简略、晦涩甚至有误导性。除了本文中提到的资料，下列的网页提供了跟多可靠且详细的 systemd 入门信息。

* Fedora 项目有一篇切实好用的 [systemd 入门](https://docs.fedoraproject.org/en-US/quick-docs/understanding-and-administering-systemd/index.html)，它囊括了几乎所有你需要知道的关于如何使用 systemd 配置、管理和维护 Fedora 计算机的信息。
* Fedora 项目也有一个不错的 [备忘录](https://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet)，交叉引用了过去 SystemV 命令和 systemd 命令做对比。
* 关于 systemd 的技术细节和创建这个项目的原因，请查看 [Freedesktop.org](http://Freedesktop.org) 上的 [systemd 描述](http://www.freedesktop.org/wiki/Software/systemd)。
* [Linux.com](http://Linux.com) 的“更多 systemd 的乐趣”栏目提供了更多高级的 systemd [信息和技巧](https://www.linux.com/training-tutorials/more-systemd-fun-blame-game-and-stopping-services-prejudice/)。

此外，还有一系列深度的技术文章，是由 systemd 的设计者和主要开发者 Lennart Poettering 为 Linux 系统管理员撰写的。这些文章写于 2010 年 4 月至 2011 年 9 月间，但它们现在和当时一样具有现实意义。关于 systemd 及其生态的许多其他好文章都是基于这些文章：

* [Rethinking PID 1](http://0pointer.de/blog/projects/systemd.html)
* [systemd for Administrators，Part I](http://0pointer.de/blog/projects/systemd-for-admins-1.html)
* [systemd for Administrators，Part II](http://0pointer.de/blog/projects/systemd-for-admins-2.html)
* [systemd for Administrators，Part III](http://0pointer.de/blog/projects/systemd-for-admins-3.html)
* [systemd for Administrators，Part IV](http://0pointer.de/blog/projects/systemd-for-admins-4.html)
* [systemd for Administrators，Part V](http://0pointer.de/blog/projects/three-levels-of-off.html)
* [systemd for Administrators，Part VI](http://0pointer.de/blog/projects/changing-roots)
* [systemd for Administrators，Part VII](http://0pointer.de/blog/projects/blame-game.html)
* [systemd for Administrators，Part VIII](http://0pointer.de/blog/projects/the-new-configuration-files.html)
* [systemd for Administrators，Part IX](http://0pointer.de/blog/projects/on-etc-sysinit.html)
* [systemd for Administrators，Part X](http://0pointer.de/blog/projects/instances.html)
* [systemd for Administrators，Part XI](http://0pointer.de/blog/projects/inetd.html)

---

via: <https://opensource.com/article/20/5/systemd-troubleshooting-tool>

作者：[David Both](https://opensource.com/users/dboth) 选题：[lujun9972](https://github.com/lujun9972) 译者：[tt67wq](https://github.com/tt67wq) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #291 演示 IBM 中文打字机的女打字员

Summary: 更多：• GCC 9.4 发布，不再强制要求代码贡献版权转让给 FSF • 俄罗斯地下论坛推出加密货币和 NFT 黑客竞赛活动

# 硬核观察 #291 演示 IBM 中文打字机的女打字员

### 演示 IBM 中文打字机的女打字员

1947 年，IBM 推出了一款[中文打字机](https://zh.wikipedia.org/wiki/%E4%B8%AD%E6%96%87%E6%89%93%E5%AD%97%E6%A9%9F)，有 36 个键能打 5400 个汉字。在演示中，一位华裔女性熟练的敲出了一个个汉字。她是谁？斯坦福大学的中国史教授 Tom Mullaney 一篇关于中文打字机的博文吸引了一则留言，[留言者称她就是那位打字员](https://www.fastcompany.com/90635203/ibm-chinese-typewriter-lois-lew)。她叫 Lois Lew，在 IBM 的宣传片里，她只有 22 岁，现在她 95 岁了。她出生在纽约，后来回到了中国。她 16 岁，又独自一人去了纽约，她不会多少英文，工作机会寥寥。这个时候 IBM 需要一位会说中文的人去演示它的中文打字机。Lew 去应聘后留用了她。但中文打字机从未能进入市场，而 Lew 在离开 IBM 之后开了一家中餐馆。

>
> 满满的历史沧桑感。这个故事很精彩，建议阅读一下上面的链接。
>
>
>

### GCC 9.4 发布，不再强制要求代码贡献版权转让给 FSF

虽然 GCC 11 是 GCC 的最新稳定系列，但对于那些仍在使用 2019 年最初亮相的 GCC 9 的人来说，本周有一个[新的点版本发布](https://gcc.gnu.org/pipermail/gcc/2021-June/236177.html)。

长期以来，GCC 要求任何补丁都要向 FSF 转让版权，这对于某些人来说会是个问题。而鉴于 RMS 重返 FSF 董事层引发的风波，GCC 指导委员会决定[不再](https://www.phoronix.com/scan.php?page=news_item&px=GCC-Drops-FSF-CA)强制要求有争议的版权转让。贡献者可以在他们的 Git 信息中使用带有 Signed-off-by 标签的开发者起源证书。该版权转让（以及 GPLv2 到 GPLv3 的变化）在十年前就阻止了苹果对 GCC 的贡献。版权转让在过去也阻止了其他组织对 GCC 的贡献。

>
> 现在看起来，FSF 之前的一些做法是有问题，应该根据社区对开源的认识采用得到更多人支持的做法。
>
>
>

### 俄罗斯地下论坛推出加密货币和 NFT 黑客竞赛活动

夺旗比赛、会议论文征集以及旨在让学习者掌握实践技能的网络安全课程中的游戏化，在白帽子领域都很常见；但在另一面，网络犯罪分子也在发起比赛，以创造新的进攻技术。

据[报道](https://www.zdnet.com/article/russian-underground-forums-launch-competitions-for-cryptocurrency-hacks/)，在过去的一个月里，俄罗斯地下论坛的运营者一直在开展一项竞赛，悬赏十余万美元征集从盗窃加密货币私钥和钱包到提交“不寻常的”加密货币采矿软件，以及与智能合约和 NFT 有关的提案。

>
> 这种竞赛并不新鲜，地下论坛过去也曾推出征集各种漏洞方案的竞赛。但这也说明了加密货币是如何有利可图，而不仅仅是被用来支付勒索。
>
>
>


你使用过 Python 3.6 中针对文件系统的这个神奇方法吗？

# 你使用过 Python 3.6 中针对文件系统的这个神奇方法吗？

>
> 探索 os.fspath 和其他两个未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202106_03_164403a6m2c989hh963lm6.jpg" alt="" title="Computer screen with files or windows open">

这是 Python 3.x 首发特性系列文章中的第七篇。Python 3.6 首次发布于 2016 年，尽管它已经发布了一段时间，但它引入的许多特性都没有得到充分利用，而且相当酷。下面是其中的三个。

### 分隔数字常数

快回答哪个更大，`10000000` 还是 `200000`？你在看代码时能正确回答吗？根据当地的习惯，在写作中，你会用 10,000,000 或 10.000.000 来表示第一个数字。问题是，Python 使用逗号和句号是用于其他地方。

幸运的是，从 Python 3.6 开始，你可以使用下划线来分隔数字。这在代码中和使用字符串的 `int()` 转换器时都可以使用：

```
import math
math.log(10_000_000) / math.log(10)

```

```
    7.0

```

```
math.log(int("10_000_000")) / math.log(10)

```

```
    7.0

```

### Tau 是对的

45 度角用弧度表示是多少？一个正确的答案是 `π/4`，但这有点难记。记住 45 度角是一个八分之一的转角要容易得多。正如 [Tau Manifesto](https://tauday.com/tau-manifesto) 所解释的，`2π`，称为 `Τ`，是一个更自然的常数。

在 Python 3.6 及以后的版本中，你的数学代码可以使用更直观的常数：

```
print("Tan of an eighth turn should be 1, got", round(math.tan(math.tau/8), 2))
print("Cos of an sixth turn should be 1/2, got", round(math.cos(math.tau/6), 2))
print("Sin of a quarter turn should be 1, go", round(math.sin(math.tau/4), 2))

```

```
    Tan of an eighth turn should be 1, got 1.0
    Cos of an sixth turn should be 1/2, got 0.5
    Sin of a quarter turn should be 1, go 1.0

```

### os.fspath

从 Python 3.6 开始，有一个神奇的方法表示“转换为文件系统路径”。当给定一个 `str` 或 `bytes` 时，它返回输入。

对于所有类型的对象，它寻找 `__fspath__` 方法并调用它。这允许传递的对象是“带有元数据的文件名”。

像 `open()` 或 `stat` 这样的普通函数仍然能够使用它们，只要 `__fspath__` 返回正确的东西。

例如，这里有一个函数将一些数据写入一个文件，然后检查其大小。它还将文件名记录到标准输出，以便追踪：

```
def write_and_test(filename):
    print("writing into", filename)
    with open(filename, "w") as fpout:
        fpout.write("hello")
    print("size of", filename, "is", os.path.getsize(filename))

```

你可以用你期望的方式来调用它，用一个字符串作为文件名：

```
write_and_test("plain.txt")

```

```
    writing into plain.txt
    size of plain.txt is 5

```

然而，可以定义一个新的类，为文件名的字符串表示法添加信息。这样可以使日志记录更加详细，而不改变原来的功能：

```
class DocumentedFileName:
    def __init__(self, fname, why):
        self.fname = fname
        self.why = why
    def __fspath__(self):
        return self.fname
    def __repr__(self):
        return f"DocumentedFileName(fname={self.fname!r}, why={self.why!r})"

```

用 `DocumentedFileName` 实例作为输入运行该函数，允许 `open` 和 `os.getsize` 函数继续工作，同时增强日志：

```
write_and_test(DocumentedFileName("documented.txt", "because it's fun"))

```

```
    writing into DocumentedFileName(fname='documented.txt', why="because it's fun")
    size of DocumentedFileName(fname='documented.txt', why="because it's fun") is 5

```

### 欢迎来到 2016 年

Python 3.6 是在五年前发布的，但是在这个版本中首次出现的一些特性非常酷，而且没有得到充分利用。如果你还没使用，那么将他们添加到你的工具箱中。

---

via: <https://opensource.com/article/21/5/python-36-features>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #292 诺顿销售带有以太坊挖矿功能的杀毒软件

Summary: 更多：• Stack Overflow 以 18 亿美元出售给腾讯的最大股东 • 移动版 UC 浏览器被曝收集用户信息

# 硬核观察 #292 诺顿销售带有以太坊挖矿功能的杀毒软件

### 诺顿销售带有以太坊挖矿功能的杀毒软件

NortonLifeLock 开始为其 Norton 360 安全套件[提供](https://investor.nortonlifelock.com/About/Investors/press-releases/press-release-details/2021/NortonLifeLock-Unveils-Norton-Crypto/default.aspx)以太坊挖矿功能了。该功能已被添加到部分客户的安装中，预计在未来几周内将对所有 Norton 360 客户开放。

诺顿认为，多年来，许多加密矿工不得不在挖掘加密货币的过程中承担风险，为了运行挖矿软件而禁用他们的安全机制，并允许在他们的机器上运行未经审核的代码，这些代码可能会从他们的收入中窃取加密货币，甚至植入勒索软件。甚至该公司表示，更好的方法是让其计算机安全软件在运行时挖掘以太坊，然后将结果存储在诺顿云中，以避免本地硬盘发生故障而造成损失。

>
> 好像有点道理？而且挖到的以太坊不但可以用来支付反病毒软件的费用，而且没准还能挣钱？但是我总觉得这个思路有点清奇。
>
>
>

### Stack Overflow 以 18 亿美元出售给腾讯的最大股东

著名编程问答网站 Stack Overflow 宣布以 18 亿美元[出售](https://www.wsj.com/articles/software-developer-community-stack-overflow-sold-to-tech-giant-prosus-for-1-8-billion-11622648400)给 Prosus。Stack Overflow 创办于 2008 年，每月能吸引超过 1 亿访问者。Stack Overflow 的收入主要来自企业推广其产品和招聘员工。

Prosus 是腾讯大股东 Naspers 旗下的投资部门，Naspers 在 2001 年以 3400 万美元控制了腾讯 28.9% 的股份。Prosus 在 4 月份以 146 亿美元的价格出售了其在腾讯的一小部分股权，现在还持有超过 2000 亿美元的腾讯股份。收购 Stack Overflow 是该公司至今最大的交易之一。

>
> 看来技术社区积累下来的知识和技术用户是真金白银啊。
>
>
>

### 移动版 UC 浏览器被曝收集用户信息

[外媒报道](https://www.forbes.com/sites/thomasbrewster/2021/06/01/exclusive-alibabas-huge-browser-business-is-recording-millions-of-android-and-iphone-users-private-web-habits/)，安全研究人员发现在安卓和 iOS 版本的 UC 浏览器上，用户的 IP 地址及其访问的每个网站，无论他们是否处于隐身模式，都会被发送到 UCWeb 拥有的服务器。

安全研究人员通过对他发现的一些被送回服务器的加密数据进行逆向工程而发现了这个问题。一旦密钥被破解，他就能看到每次访问的网站被传回 UCWeb。而在苹果的 iOS 系统上，他甚至不需要对加密进行逆向工程，因为设备上实际上没有加密（尽管在传输过程中是加密的）。

安全研究人员表示，他从未见过其它主流浏览器会像 UC 浏览器这样。

>
> 下面的剧本我都想好了，“为失误”而道歉。
>
>
>


在 2021 年你需要知道 Quarkus 些什么？

# 在 2021 年你需要知道 Quarkus 些什么？

>
> Quarkus 受益于 20 多年的 Java 开发历史，使开发应用变得更快、更容易。
>
>
>

<img src="content_image/album_202106_04_221812ja1b5btxpgwapsap.jpg" alt="" title="Tools in a cloud">

在云上发布服务部分是为了通过简单可靠的方式为用户和开发者提供对这些服务的便捷访问。与在线应用对接的最流行的方法之一是通过应用编程接口（API），这是一个花哨的术语，意味着你允许用户通过代码与你的应用进行互动。

API 的概念很重要，因为它可以帮助其他人在你的应用基础上进行开发。假设你设计了一个网站，当用户点击一个按钮时返回一个随机数字。通常情况下，这需要用户打开你的网站并点击一个按钮。网站可能是有用的，但只是在一定程度上。如果你包含一个 API，用户可以直接向你的服务器发送一个信号，要求一个随机数，或者他们可以自己编程，“调用”你的服务器来获取一个数字，而不需要点击或手动交互。开发者可以使用你的随机数作为游戏的数值，或作为密码生成器的一部分，或其他任何开发者需要随机数的地方（总是有的）。一个好的 API 可以解锁你的应用，让其他人使用你的代码结果，本质上，将你在网络上的工作转变为一个软件库。

### 什么是 Quarkus？

[Quarkus](https://quarkus.io) 是一个原生 Kubernetes Java 栈，为无服务器应用交付而设计。与有 20 年历史的 Java 相比，[Quarkus](https://developers.redhat.com/blog/2019/03/07/quarkus-next-generation-kubernetes-native-java-framework/) 相对年轻，但受益于这 20 年的发展，用该项目的话说，是 “超音速的亚原子 Java”。可能没有人知道这句话的确切含义，但你肯定可以通过一下午使用 Quarkus 来感受到它对你的开发生活的意义。

Quarkus 让你用一个有用的 API 开发应用，几乎不需要配置，也不用担心启动一个复杂的环境。你不需要学习关于云计算或边缘计算的所有知识，就可以学习并擅长使用 Quarkus。了解 Quarkus 可以使你的开发更快，它可以帮助你为现代计算机网络制作灵活的应用。

下面是我们最近的一些涉及 Quarkus 的文章。

### 开始使用 Quarkus

在 Saumya Singh 的《[如何创建你的第一个 Quarkus 应用](https://opensource.com/article/21/4/quarkus-tutorial)》中，你可以了解 Quarkus 和无服务器交付的好处，并在大约 10 分钟内创建了一个简单的演示应用。事实上，*10* 分钟以内更准确，因为在 Maven 和 Quarkus 之间，几乎没有你想象中的那么多设置。它几乎感觉不到像 Java 一样的坏处，而感觉像 Java 一样好。

### 边缘开发

Linux 是创建物联网 （IoT） [边缘应用](https://opensource.com/article/17/9/what-edge-computing) 的一个流行平台。这有很多原因，包括安全性、编程语言和开发模型的广泛选择以及协议支持。不出所料，Quarkus 对物联网的处理非常好。Quarkus 的内存效率高，启动快，并且有快速的运行时，所以它不仅是物联网的可行解决方案，而且是理想的解决方案。你可以通过 Daniel Oh 的《[在 Linux 上使用开源的边缘开发入门](https://opensource.com/article/21/5/edge-quarkus-linux)》来开始使用 Quarkus 和物联网。

### Quarkus 和 VS Code

当你处理代码时，一个集成开发环境（IDE）会有很大的不同。微软的开源 [VS Code](https://github.com/microsoft/vscode)（或无品牌标志的 [VSCodium](https://opensource.com/article/20/6/open-source-alternatives-vs-code)）是一个伪装成 IDE 的流行文本编辑器（或者说是伪装成文本编辑器的 IDE？），它有很多扩展，可以使它成为几乎任何编程语言的专门环境。如果你正在使用或考虑使用 VS Code，那么请阅读 Daniel Oh 的《[Quarkus in VS Code](https://opensource.com/article/20/4/java-quarkus-vs-code)》使用指南，了解一些关于 Maven、Quarkus 和 VS Code 如何协同工作的专业技巧。

### 获得 Quarkus

使用 Quarkus 开发，可以像 Python 一样简单地设置环境，但它为你提供了强大的 Java 语言及其众多的库。它是进入云计算、[Knative](https://www.openshift.com/learn/topics/quarkus) 和边缘计算的一个重要入口。获取 Quarkus 并开始编码。

---

via: <https://opensource.com/article/21/5/quarkus>

作者：[Alan Smithee](https://opensource.com/users/alansmithee) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


鸿蒙之路，道阻且长

小编求生欲很强，说得极其委婉

鸿蒙牛逼

发两篇分别站在两边的偏激议论，会收获两篇10w+

发一篇客观中立的评论，会被口水淹死

这个小编真的很谨慎，幸好这里也不是10w+平台。。。。

来自四川成都的 Chrome Mobile 58.0|Android 8.1 用户

皇帝的新衣

来自广东深圳的 Chrome Mobile iOS 87.0|iOS 14.4 用户

皇帝的新衣

皇帝的新衣

安卓套壳说的太偏激了，但是华为不应该把安卓的“衍生”或“分支”说成全自研操作系统。

知道为什么取关你吗？

几岁了？

广东那位IOS的，有必要发三次？深仇大恨？

网卡了，所以三次吧？问题是发三次也没啥啊？

华为消费者业务软件部总裁王成录告诉德国媒体，手机版的鸿蒙是基于 AOSP，它遵守了开源许可证规定，履行了相关责任义务。

所以，裁缝没说谎，他们就是想耍猴

手表用的LiteOS确实是自研的。手机用的确实是基于别人的。

国内国外宣传方式表里不一，说白了就是拿情怀骗钱的，耍猴玩

支持态度,有总比没有好,要开放开源的没有后顾之忧的!

哈哈哈！确实。

我看不懂，华为要干什么，各个生态位都已经有巨头了。我觉得这个手机鸿蒙只是用来接手以前积累的华为用户的。

所谓的哄蒙，其实就是Android 10

# 鸿蒙之路，道阻且长

6 月 2 日晚上八点，鸿蒙召开了 2.0 的发布会，发布了鸿蒙 OS，以及一大批的新品。这两天想必大家也都看到了不少。这篇文章不想讨论鸿蒙系统本身的体验层面的变化，而是将会将精力更多的投放在鸿蒙的生态发展中。

### 鸿蒙想要的是什么？

从 2019 年鸿蒙发布，有几个关键词就是核心，**分布式、全场景、自主研发**，其中自主研发比较好理解，而分布式、全场景一直是我无法理解的，直到看了发布会，我才意识到鸿蒙真正想要的是什么。

由于我近几年来，使用的都是苹果的生态，使用 Macbook Pro 办公，使用 Homepod 听歌，出门会使用 Airpods Pro 来降噪。所以，在看鸿蒙发布会的时候，我时常有一个想法：这个功能苹果生态里已经有了啊？ 或者是这个功能的 UI 交互确实是新的，但核心的体验我在苹果生态中也已经体验了啊？

也正是这一刻，我悟了，鸿蒙想要的分布式、全场景，其实就是过去我在苹果生态一直体验的那些东西，不同的是，鸿蒙的分布式、全场景，是超出了苹果生态所给予我的东西。

*鸿蒙的 1 + 8 + N 战略*

鸿蒙的产品架构是 1+8+N，1 指的是手机，8 指的是 PC、平板、智慧屏、手表、智能音箱、车机、耳机、AR/VR，N 则是更多的生态。

对比着我们来看苹果的生态，1 指的是 iPhone，8 指的是 Macbook Pro、iPad、Apple TV、Apple Watch、Homepod、Apple Car、AirPods 以及不知道有没有的 VR/AR 产品。

截止到这一步，鸿蒙和苹果看起来都很像，那为什么我又说华为超越了苹果生态？

**原因在于 8 加的 N。**

在鸿蒙的描述中，N 是指更多的 IoT 设备，他们可以通过鸿蒙系统借助 4G/5G/HiLink 等方式，和核心的 8 个产品进行连接，沟通，从而提升产品的智能性，让用户真正感受到产品的智能特性。

而在苹果生态中，苹果是不做 IoT 设备的操作系统的。**鸿蒙既做了手机、核心设备的操作系统，还做了嵌入式的操作系统，确实可以让 IoT 设备的操作体验，如同 8 个核心设备的体验，这一点是只制定标准，不下场做事的苹果所无法达到的**。

可以说，**鸿蒙生态假设真的铺设起来了，体验、易用性，可能都要超过苹果生态目前能够提供给我们的**。

### 鸿蒙生态之乱象

鸿蒙作为一个看起来还不错的产品，为何近几年来饱受争议？我觉得主要是在宣传策略上的混乱。

*鸿蒙系统近几年的搜索关注度*

提起鸿蒙，数码圈的人往往说的是鸿蒙 OS；而互联网/科技圈的人说的往往是 OpenHarmony 操作系统。二者在宣传的过程中，往往都是被人称作是鸿蒙系统。

但实际上，鸿蒙 OS 是真正的鸿蒙 OS，OpenHarmony 仅仅是鸿蒙生态的一个基座，如果你将之与 Android 对比，便是 Android 与 AOSP 的区别。

*OpenHarmony 架构图*

我们真正在使用的鸿蒙系统，是一个完整的、加入了各项系统设定的操作系统，而我们所看到的源码的部分，只是一个操作系统的基座，你真正在使用的过程中，还需要做大量的修改和剪裁的版本。

不过，这样的区分是一件好事。Android 当年之所以能够盛行，AOSP 功不可没。OpenHarmony 同样承载了鸿蒙系统发扬光大的路线。

不过，OpenHarmony 本身也在宣传上有硬伤。

一直以来，OpenHarmony 都被称之为 Android 套壳，在我看来，是不完全准确的。OpenHarmony 在手机/平板/智慧屏部分，使用的是兼容 Android 的机制，而且兼容 Android 的路线也是没有问题的；但在覆盖面更广的嵌入式设备中，产生的价值的是 2012 年就开发的 LiteOS；对于一些特定的场景下，OpenHarmony 可能会使用 Linux Kernel 来完成自己的工作。OpenHarmony 不是 Android 套壳，而是基于 Android /LiteOS/Linux Kernel 的土壤所诞生出来的操作系统。

操作系统的研发一直以来都不是技术问题，而是生态问题，用户不太会裸用操作系统提供的基础功能，能够留下用户的，必然是操作系统之上的应用生态，对于 OpenHarmony 这样的一个后来者，一个最为简单高效获得生态的方式，就是与原有生态的兼容，所以 OpenHarmony 兼容 Android 生态是在我意料之中的事情，倘若鸿蒙真的将整个系统完全重写，那我反而不看好 OpenHarmony。

相比于说 OpenHarmony 套壳 Android，我更倾向于 OpenHarmony 编写了一个抽象层，磨平了 LiteOS 和 Android 的系统 API，从而使得一些功能特性可以更加容易的在两种系统之上来实现。而这些，也正是鸿蒙所宣传的 1 + 8 + N战略下的核心体验的由来。

但不得不说，在宣传上，OpenHarmony 做的很一般，甚至可能没有起到好的作用，而是一个坏的作用。

### 鸿蒙生态的未来

说完了鸿蒙想要的东西和鸿蒙生态的乱象，最后，我想聊一聊关于鸿蒙的未来。

鸿蒙生态看起来非常的不错，但，能否达到所预想的水平，又是另外一个问题，对于鸿蒙来说，前路依然坎坷。

在国内方面，鸿蒙如果希望进行推广，就必须要考虑合作伙伴的问题，鸿蒙生态的建设不仅仅是华为的事情，华为可以完成 1+8 的建设，可后面的 N，是需要无数的中小 IoT 设备生产厂商共同建设而来的。

但，**国内的厂商可能要面临的问题就是，面对曾经的对手，是否还要继续合作？如果合作了，未来是否会被华为卡脖子？华为又是否会在 OpenHarmony 中为自家系统添加单独的优化？这些问题都会让国内的厂商在面临选择时产生困惑。**

此外，国内的厂商在完成了接入后， 鸿蒙想要扩大生态范围，就必然需要进行出海，出海时就要正面与 Android、iOS 所构建的生态进行竞争，在海外生态不足的情况下，如何取得竞争的胜利，也是一个需要研究和探讨的话题。

不过，说了这么多困难，我还是想说，鸿蒙看起来真的很好，或许，有朝一日我会面临这样的选择“花 15000 元，获得完整的苹果生态体验；花 10000 元，获得完整的鸿蒙生态体验，可以实现苹果生态 80% 甚至是 120% 的体验”，你会怎么选？

鸿蒙之路，道阻且长。


硬核观察 #293 Google 用自己的专用芯片取代了数百万英特尔的芯片

Summary: 更多：• openSUSE Leap 15.3 现在与 SUSE 企业版的二进制软件包完全相同 • 美国将勒索软件攻击视为恐怖主义

# 硬核观察 #293 Google 用自己的专用芯片取代了数百万英特尔的芯片

### Google 用自己的专用芯片取代了数百万英特尔的芯片

今年早些时候，YouTube [披露](https://blog.youtube/inside-youtube/new-era-video-infrastructure)了自己设计的芯片 Argos VCU，它专门用于将视频转码成十多个版本。YouTube 称相比以前使用软件在传统服务器的转码，Argos 的视频转码芯片性能提升了 20-33 倍。相比使用英特尔 Skylake CPU 或 Nvidia T4 Tensor core GPU 的方案，VCU 能节省大量的钱。分析师估计，Google 可能已经用 VCU 替代了 400 万到 3300 万的英特尔 CPU。Google 已经在设计第二代 Argos VCU，支持 AV1、H.264 和 VP9 编解码器。

>
> 有芯片设计能力的大企业就是豪横，这种专用芯片往往能在特定领域取得非常好的效果。
>
>
>

### openSUSE Leap 15.3 现在与 SUSE 企业版的二进制软件包完全相同

openSUSE Leap 是一个稳定版本，其核心是由与 SUSE 企业版（SLE）相同的源代码构建的。Leap 与 SLE 并不完全相同；它更像是一个超集，因为它从相同的 SLE 核心开始，并进一步增加了自己的软件包。

SUSE 说，openSUSE Leap 15.3 与以前的版本相比有一个巨大变化：它不仅是由 SLE 源代码构建的，而且其二进制包[完全相同](https://www.theregister.com/2021/06/04/opensuse_leaps_to_153_now/)。该公司将 openSUSE 定位为用于运行和测试工作负载，可以迁移到 SLE 进行长期维护。它也适合在不需要 SLE 支持的情况下用于生产环境。

>
> 就像红帽最近对 CentOS 所做的那样，SUSE 的做法也是为了提高 SLE 的市场份额，但 SUSE 的努力对社区来说更容易接受。
>
>
>

### 美国将勒索软件攻击视为恐怖主义

美国司法部的一位高级官员表示，在 Colonial 石油管道网络遭黑客攻击以及网络犯罪分子造成的损害日益严重之后，司法部正在将勒索软件攻击的调查提升到与恐怖主义类似的优先地位。FBI 将政府对[勒索软件的打击](https://www.zdnet.com/article/fbi-doj-to-treat-ransomware-attacks-with-similar-priority-as-terrorism/)比作美国在 9/11 之后面临的情况。他补充说，FBI 已经确定了近一百种不同类型的勒索软件。美国司法部发出的备忘录称，“任何涉及加密货币交易所、僵尸网络、数字洗钱、非法在线论坛、‘防弹托管服务’和攻击反病毒服务的网络犯罪案件都需要通知司法部高级官员。”

>
> 勒索软件愈演愈烈，确实需要提高对勒索软件的重视。
>
>
>


用这个 Python 3.7 的特性来切片无限生成器

Summary: 了解更多关于这个和其他两个未被充分利用但仍然有用的 Python 特性。

了解更多关于这个和其他两个未被充分利用但仍然有用的 Python 特性。

# 用这个 Python 3.7 的特性来切片无限生成器

>
> 了解更多关于这个和其他两个未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202106_05_230956bgcjacwcyujlndez.jpg" alt="" title="Hands on a keyboard with a Python book ">

这是关于 Python 3.x 首发特性系列文章的第八篇。[Python 3.7](https://opensource.com/downloads/cheat-sheet-python-37-beginners) 于 2018 年首次发布，尽管它已经发布了几年，但它引入的许多特性都未被充分利用，而且相当酷。下面是其中的三个。

### 注解推迟评估

在 Python 3.7 中，只要激活了正确的 `__future__` 标志，注解在运行时就不会被评估：

```
from __future__ import annotations

def another_brick(wall: List[Brick], brick: Brick) -> Education:
    pass

```

```
another_brick.__annotations__

```

```
    {'wall': 'List[Brick]', 'brick': 'Brick', 'return': 'Education'}

```

它使递归类型（指向自己的类）和其他有趣的事情成为了可能。然而，这意味着如果你想做自己的类型分析，你需要明确地使用 `ast`。

```
import ast
raw_type = another_brick.__annotations__['wall']
[parsed_type] = ast.parse(raw_type).body

```

```
subscript = parsed_type.value
f"{subscript.value.id}[{subscript.slice.id}]"

```

```
    'List[Brick]'

```

### itertools.islice 支持 **index**

Python 中的序列切片长期以来一直接受各种 *类 int 对象*（具有 `__index__()` 的对象）作为有效的切片部分。然而，直到 Python 3.7，`itertools.islice`，即核心 Python 中对无限生成器进行切片的唯一方法，才获得了这种支持。

例如，现在可以用 `numpy.short` 大小的整数来切片无限生成器：

```
import numpy
short_1 = numpy.short(1)
short_3 = numpy.short(3)
short_1, type(short_1)

```

```
    (1, numpy.int16)

```

```
import itertools
list(itertools.islice(itertools.count(), short_1, short_3))

```

```
    [1, 2]

```

### functools.singledispatch() 注解注册

如果你认为 [singledispatch](https://opensource.com/article/19/5/python-singledispatch) 已经很酷了，你错了。现在可以根据注解来注册了：

```
import attr
import math
from functools import singledispatch

@attr.s(auto_attribs=True, frozen=True)
class Circle:
    radius: float

@attr.s(auto_attribs=True, frozen=True)
class Square:
    side: float

@singledispatch
def get_area(shape):
    raise NotImplementedError("cannot calculate area for unknown shape",
                              shape)

@get_area.register
def _get_area_square(shape: Square):
    return shape.side ** 2

@get_area.register
def _get_area_circle(shape: Circle):
    return math.pi * (shape.radius ** 2)

get_area(Circle(1)), get_area(Square(1))

```

```
    (3.141592653589793, 1)

```

### 欢迎来到 2017 年

Python 3.7 大约是四年前发布的，但是在这个版本中首次出现的一些特性非常酷，而且没有得到充分利用。如果你还没使用，那么将它们添加到你的工具箱中。

---

via: <https://opensource.com/article/21/5/python-37-features>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #294 萨尔瓦多可能成为第一个将比特币视为法币的国家

Summary: 更多：• 用文本描述创造安卓应用 • 主要浏览器开发商对浏览器插件进行标准化

更多：• 用文本描述创造安卓应用 • 主要浏览器开发商对浏览器插件进行标准化

# 硬核观察 #294 萨尔瓦多可能成为第一个将比特币视为法币的国家

### 萨尔瓦多可能成为第一个将比特币视为法币的国家

在美国迈阿密举行的 Bitcoin 2021 会议上，中美洲国家[萨尔瓦多的总统宣布](https://www.msn.com/en-us/money/markets/el-salvador-becomes-the-world-s-first-country-to-adopt-bitcoin-as-legal-tender/ar-AAKK3CW)，计划立法将比特币视为法币，和美元并列。萨尔瓦多已经组建了一个由比特币领袖组成的团队，以帮助建立一个以比特币为基础层的新金融生态系统。萨尔瓦多主要使用现金，70% 的居民没有银行账号或信用卡。3 月，Strike 在萨尔瓦多推出了它的移动支付应用，并迅速成为该国下载量最大的应用。

>
> 对于没有现代金融体系的国家来说，比特币可能要比落后的金融体系更可靠，当然，也可能更危险。
>
>
>

### 用文本描述创造安卓应用

研究人员开发出一种[框架](https://techxplore.com/news/2021-06-text2app-framework-android-apps-text.html)，能从文本描述创造安卓应用。这项研究在人类语言和编程语言之间架起桥梁，让编程变得更容易。大部分此类的技术是基于端对端的神经网络机器翻译，类似 Google 翻译使用的技术。但绝大部分它们都无法生成包含数百行代码的应用。为了克服这一限制，研究人员创造了一种形式语言，能抓住应用代码中的复杂性。他们开发的框架被称为 [Text2App](https://techxplore.com/news/2021-06-text2app-framework-android-apps-text.html)，其演示发布在 GitHub 上。

>
> 这也是低代码的一种形式，其实对于很多应用来说，低代码是一种可能的开发方式。
>
>
>

### 主要浏览器开发商对浏览器插件进行标准化

[苹果、Mozilla、谷歌、微软等](https://appleinsider.com/articles/21/06/04/apple-mozilla-google-microsoft-form-group-to-standardize-browser-plug-ins)组成了 “WebExtensions 社区小组”（[WECG](https://github.com/w3c/webextensions/blob/main/charter.md)），试图为未来的 Web 扩展打造一个共同的架构。该组织有两个目标。通过指定一个一致的模型和功能、API 和权限的共同核心，使开发人员更容易创建扩展；以及概述一个架构，以提高性能，甚至更安全和防止滥用。该小组不希望指定 Web 扩展平台的每一个方面，也不希望扼杀创新。每个浏览器供应商将继续以他们自己的政策独立运作。

>
> 标准化带来的好处毋庸置疑，同时也宽泛地没有约束更多创新更是好事。
>
>
>


在 Linux 终端将图像转换成 ASCII 艺术

# 在 Linux 终端将图像转换成 ASCII 艺术

想在 Linux 终端中做一些有趣的事情吗？把一张普通的图片转换成 ASCII 艺术怎么样？

你知道 [什么是 ASCII](https://www.computerhope.com/jargon/a/ascii.htm) 么？它是一个标准，在 8 位码中的 256 个空位上分配字母、数字和其他字符。ASCII 艺术是一个由可打印的 ASCII 字符组成的图形。基本上，它是由一堆字母、数字和特殊字符组成的。

你可能见过有人 [以 ASCII 格式显示他们发行版的标志](https://itsfoss.com/display-linux-logo-in-ascii/)，像这样：

这很酷，对吗？把一张普通的图片转换成 ASCII 艺术怎么样？这就是在这篇文章中要探讨的问题。

### Ascii Image Converter

顾名思义，[Ascii Image Converter](https://github.com/TheZoraiz/ascii-image-converter) 是一个将图片转换为 ASCII 艺术的工具。它是一个用 Go 语言编写的基于命令行的工具，它打印出提供给它的图片的ASCII版本。

你可能认不出我，但下面的图片中的 ASCII 版就是我。那是我的 8 位头像。

该工具支持以下格式的输入图像：

* JPEG/JPG
* PNG
* BMP
* WEBP
* TIFF/TIF

让我们看看如何安装和使用它。

### 在 Linux 上安装 Ascii Image Converter

这个有趣的工具也可以在 Windows 上使用，但我不打算这么做。在本教程中，让我们坚持使用 Linux。

如果你的发行版中启用了 [Snap](https://itsfoss.com/enable-snap-support-linux-mint/)，你可以用下面的命令轻松地安装它的 snap 包：

```
sudo snap install ascii-image-converter

```

你也可以从它的发布页面下载 Linux 的可执行文件，并把可执行文件放在 `/usr/local/bin/` 目录下。这样，你就能像普通的 Linux 命令一样运行它。如果你想知道为什么会这样，请了解一下 [Linux 目录层次结构](https://linuxhandbook.com/linux-directory-structure/)。

### 使用 Ascii Image Converter

使用很简单。安装后，你只需要提供你想转换的图像的路径。

```
ascii-image-converter path_to_image

```

你也可以提供图片的 URL，直接从网上把图片转换成 ASCII。

这是我的个人资料照片转换成 ASCII 格式。我把我的原始照片放在这里供大家参考。

你也可以转换成彩色的 ASCII。

```
ascii-image-converter -C path_to_image

```

你可以通过提供它们的路径将多个图像转换为 ASCII。它将在终端显示器上一个接一个地打印 ASCII 版本。

也有一个选项可以保存生成的 ASCII 艺术。在旧版本中，它只会被保存为文本文件，而不是图像。开发者 Zoraiz Hassan 发布了一个新版本，现在该工具默认将生成的 ASCII 图像保存为 PNG 格式。

```
ascii-image-converter path_to_image -s .

```

还有一些可用的选项，比如给输出一个特定的尺寸，使用更多的 ASCII 字符，或者使用你自己的字符集来打印 ASCII 艺术。你可以在 [项目的仓库](https://github.com/TheZoraiz/ascii-image-converter) 上阅读相关内容。

### 喜欢它吗？

你喜欢更多的 ASCII 相关的东西吗？那么 [在 Linux 上玩 ASCII 游戏](https://itsfoss.com/best-ascii-games/) 怎么样？是的，你完全可以这么做。

如果你喜欢在终端做实验，你可能会喜欢这个工具。虽然我不知道 ASCII 转换后的图像能有什么好的实际用途。有什么想法吗？

---

via: <https://itsfoss.com/ascii-image-converter/>

作者：[Abhishek Prakash](https://itsfoss.com/author/abhishek/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


使用开源工具识别 Linux 的性能瓶颈

# 使用开源工具识别 Linux 的性能瓶颈

>
> 不久前，识别硬件瓶颈还需要深厚的专业知识。今天的开源 GUI 性能监视器使它变得相当简单。
>
>
>

计算机是一个集成的系统，它的性能取决于最慢的硬件组件。如果一个组件的能力比其他组件差，性能落后而不能跟上，它就会拖累你的整个系统。这就是一个 *性能瓶颈*。消除一个严重的瓶颈可以使你的系统飞起来。

本文解释了如何识别 Linux 系统中的硬件瓶颈。这些技术同时适用于个人的电脑和服务器。我强调的是个人电脑 —— 我不会涉及局域网管理或数据库系统等领域的服务器特定的瓶颈。这些通常涉及专门的工具。

我也不会多谈解决方案。这对本文来说是个太大的话题。相反，我将写一篇关于性能调整的后续文章。

我将只使用开源的图形用户界面（GUI）工具来完成这项工作。大多数关于 Linux 瓶颈的文章都相当复杂。它们使用专门的命令，并深入研究神秘的细节。

开源提供的 GUI 工具使得识别许多瓶颈变得简单。我的目标是给你一个快速、简单的方法，你可以在任何地方使用。

### 从哪里开始

一台计算机由六个关键的硬件资源组成。

* 处理器
* 内存
* 存储器
* USB 端口
* 互联网连接
* 图形处理器

如果任何一个资源表现不佳，就会产生一个性能瓶颈。为了识别瓶颈，你必须监测这六种资源。

开源提供了大量的工具来完成这项工作。我会使用 [GNOME 系统监视器](https://wiki.gnome.org/Apps/SystemMonitor)。它的输出很容易理解，而且你可以在大多数软件库中找到它。

启动它并点击“资源”标签。你可以马上发现许多性能问题。

*图 1. 系统监控器发现问题。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

在“资源”面板上显示三个部分：CPU 历史、内存和交换历史，以及网络历史。一眼就能看出你的处理器是否不堪负荷了，还是你的电脑没有内存了，抑或你的网络带宽被用光了。

我将在下面探讨这些问题。现在，当你的电脑速度变慢时，首先检查系统监视器。它可以立即为你提供最常见的性能问题的线索。

现在让我们来探讨一下如何识别特定方面的瓶颈。

### 如何识别处理器的瓶颈

要发现瓶颈，你必须首先知道你有什么硬件。开源为这个目的提供了几个工具。我喜欢 [HardInfo](https://itsfoss.com/hardinfo/)，因为它的屏幕显示很容易阅读，而且广泛流行。

启动 HardInfo。它的“计算机->摘要”面板可以识别你的 CPU 并告诉你它的核心数、线程数和速度。它还能识别你的主板和其他计算机部件。

*图 2. HardInfo 显示了硬件细节。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

HardInfo 显示，这台计算机有一个物理 CPU 芯片。该芯片包含两个处理器（或称为核心）。每个核心支持两个线程（或称为逻辑处理器）。这就是总共四个逻辑处理器 —— 正是图 1 中系统监控器的 CPU 历史部分所显示的。

当处理器不能在其时间内对请求做出反应时，就会出现 *处理器瓶颈*，说明它们已经很忙了。

当系统监控器显示逻辑处理器的利用率持续在 80% 或 90% 以上时，你就可以确定这一点。这里有一个例子，四个逻辑处理器中有三个被淹没在 100% 的利用率中。这是一个瓶颈，因为它没有留下多少 CPU 用于其他工作。

*图 3. 一个处理器的瓶颈。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

#### 哪个程序导致了这个问题？

你需要找出是哪个程序在消耗所有的 CPU。点击系统监视器的“进程”标签。然后点击“CPU 百分比”标头，根据它们消耗的 CPU 的多少对进程进行排序。你将看到哪些应用程序正在扼杀你的系统。

*图 4. 识别违规的进程。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

前三个进程各消耗了 *总 CPU 资源的 24%*。由于有四个逻辑处理器，这意味着每个进程消耗了一整个处理器。这就像图 3 所示。

在“进程”面板上，一个名为“analytical\_AI”的程序被确定为罪魁祸首。你可以在面板上右键单击它，以查看其资源消耗的更多细节，包括内存使用、它所打开的文件、其输入/输出细节，等等。

如果你的登录会话有管理员权限，你可以管理这个进程。你可以改变它的优先级，并停止、继续、结束或杀死它。因此，你可以在这里立即解决你的瓶颈问题。

*图 5. 右键点击一个进程来管理它。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

如何解决处理瓶颈问题？除了实时管理违规的进程外，你也可以防止瓶颈的发生。例如，你可以用另一个应用程序来代替违规进程，绕过它，改变你使用该应用程序的行为，将该应用程序安排在非工作时间，解决潜在的内存问题，对该应用程序或你的系统软件进行性能调整，或升级你的硬件。这里涉及的内容太多，所以我将在下一篇文章中探讨这些方式。

#### 常见的处理器瓶颈

在用系统监控器监控你的 CPU 时，你会遇到几种常见的瓶颈问题。

有时一个逻辑处理器出现瓶颈，而其他所有的处理器都处于低利用率。这意味着你有一个应用程序，它的代码不够智能，无法利用一个以上的逻辑处理器，而且它已经把正在使用的那个处理器耗尽了。这个应用程序完成的时间将比使用更多的处理器要长。但另一方面，至少它能让你的其他处理器腾出手来做别的工作，而不会接管你的电脑。

你也可能看到一个逻辑处理器永远停留在 100% 的利用率。要么它非常忙，要么是一个进程被挂起了。判断它是否被挂起的方法是，是看该进程是否从不进行任何磁盘活动（正如系统监视器“进程”面板所显示的那样）。

最后，你可能会注意到，当你所有的处理器都陷入瓶颈时，你的内存也被完全利用了。内存不足的情况有时会导致处理器瓶颈。在这种情况下，你要解决的是根本的内存问题，而不是体现出症状的 CPU 问题。

### 如何识别内存瓶颈

鉴于现代 PC 中有大量的内存，内存瓶颈比以前要少得多。然而，如果你运行内存密集型程序，特别是当你的计算机没有很多的随机存取内存（RAM）时，你仍然可能遇到这些问题。

Linux [使用内存](https://www.networkworld.com/article/3394603/when-to-be-concerned-about-memory-levels-on-linux.html) 既用于程序，也用于缓存磁盘数据。后者加快了磁盘数据的访问速度。Linux 可以在它需要的任何时候回收这些内存供程序使用。

系统监视器的“资源”面板显示了你的总内存和它被使用的程度。在“进程”面板上，你可以看到单个进程的内存使用情况。

下面是系统监控器“资源”面板中跟踪总内存使用的部分。

*图 6. 一个内存瓶颈。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

在“内存”的右边，你会注意到 [交换空间](https://opensource.com/article/18/9/swap-space-linux-systems)。这是 Linux 在内存不足时使用的磁盘空间。它将内存写入磁盘以继续操作，有效地将交换空间作为你的内存的一个较慢的扩展。

你要注意的两个内存性能问题是：

1. 内存被大量使用，而且你看到交换空间的活动频繁或不断增加。
2. 内存和交换空间都被大量使用。

情况一意味着更慢的性能，因为交换空间总是比内存更慢。你是否认为这是一个性能问题，取决于许多因素（例如，你的交换空间有多活跃、它的速度、你的预期，等等）。我的看法是，对于现代个人电脑来说，交换空间任何超过象征性的使用都是不可接受的。

情况二是指内存和交换空间都被大量使用。这是一个 *内存瓶颈*。计算机变得反应迟钝。它甚至可能陷入一种“咆哮”的状态，在这种状态下，除了内存管理之外，它几乎不能完成其他任务。

上面的图 6 显示了一台只有 2GB 内存的旧电脑。当内存使用量超过 80% 时，系统开始向交换空间写入，响应速度下降了。这张截图显示了内存使用量超过了 90%，而且这台电脑已经无法使用。

解决内存问题的最终答案是要么少用内存，要么多买内存。我将在后续文章中讨论解决方案。

### 如何识别存储瓶颈

如今的存储有固态和机械硬盘等多个品种。设备接口包括 PCIe、SATA、雷电和 USB。无论有哪种类型的存储，你都要使用相同的程序来识别磁盘瓶颈。

从系统监视器开始。它的“进程”面板显示各个进程的输入/输出率。因此，你可以快速识别哪些进程做了最多的磁盘 I/O。

但该工具并不显示每个磁盘的总数据传输率。你需要查看特定磁盘上的总负载，以确定该磁盘是否是一个存储瓶颈。

要做到这一点，使用 [atop](https://opensource.com/life/16/2/open-source-tools-system-monitoring) 命令。它在大多数 Linux 软件库中都有。

只要在命令行提示符下输入 `atop` 即可。下面的输出显示，设备 `sdb` 达到 `busy 101%`。很明显，它已经达到了性能极限，限制了你的系统完成工作的速度。

*图 7. atop 命令识别了一个磁盘瓶颈。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

注意到其中一个 CPU 有 85% 的时间在等待磁盘完成它的工作（`cpu001 w 85%`）。这是典型的存储设备成为瓶颈的情况。事实上，许多人首先看 CPU 的 I/O 等待时间来发现存储瓶颈。

因此，要想轻松识别存储瓶颈，请使用 `atop` 命令。然后使用系统监视器上的“进程”面板来识别导致瓶颈的各个进程。

### 如何识别 USB 端口的瓶颈

有些人整天都在使用他们的 USB 端口。然而，他们从不检查这些端口是否被最佳地使用。无论你是插入外部磁盘、U 盘，还是其他东西，你都要确认你是否从 USB 连接的设备中获得了最大性能。

这个图表显示了原因。潜在的 USB 数据传输率差异 *很大*。

*图 8. USB 速度变化很大。(Howard Fosdick，根据 [Tripplite](https://www.samsung.com/us/computing/memory-storage/solid-state-drives/) 和 [Wikipedia](https://en.wikipedia.org/wiki/USB) 提供的数字，[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

HardInfo 的“USB 设备”标签显示了你的计算机支持的 USB 标准。大多数计算机提供不止一种速度。你怎么知道一个特定端口的速度呢？供应商对它们进行颜色编码，如图表中所示。或者你可以在你的计算机的文档中查找。

要看到你得到的实际速度，可以使用开源的 [GNOME 磁盘](https://wiki.gnome.org/Apps/Disks) 程序进行测试。只要启动 GNOME 磁盘，选择它的“磁盘基准”功能，然后运行一个基准测试。这将告诉你在一个端口插入特定设备时，你将得到的最大实际速度。

你可能会得到不同的端口传输速度，这取决于你将哪个设备插入它。数据速率取决于端口和设备的特定组合。

例如，一个可以以 3.1 速度运行的设备如果使用 2.0 端口就会以 2.0 的速度运行。（而且它不会告诉你它是以较慢的速度运行的！）相反，如果你把一个 USB 2.0 设备插入 3.1 端口，它能工作，但速度是 2.0 的速度。所以要获得快速的 USB，你必须确保端口和设备都支持它。GNOME 磁盘为你提供了验证这一点的方法。

要确定 USB 的处理瓶颈，使用你对固态和硬盘所做的同样程序。运行 `atop` 命令来发现 USB 存储瓶颈。然后，使用系统监视器来获取违规进程的详细信息。

### 如何识别互联网带宽瓶颈

系统监控器的“资源”面板会实时告诉你互联网连接速度（见图 1）。

有 [很好的 Python 工具](https://opensource.com/article/20/1/internet-speed-tests) 可以测试你的最大网速，但你也可以在 [Speedtest](https://www.speedtest.net/)、[Fast.com](https://fast.com/) 和 [Speakeasy](https://www.speakeasy.net/speedtest/) 等网站进行测试。为了获得最佳结果，关闭所有东西，只运行 *速度测试*；关闭你的虚拟私有网络；在一天中的不同时间运行测试；并比较几个测试网站的结果。

然后将你的结果与你的供应商声称的下载和上传速度进行比较。这样，你就可以确认你得到的是你所付费的速度。

如果你有一个单独的路由器，在有和没有它的情况下进行测试。这可以告诉你，你的路由器是否是一个瓶颈。如果你使用 WiFi，在有 WiFi 和没有 WiFi 的情况下进行测试（通过将你的笔记本电脑直接与调制解调器连接）。我经常看到人们抱怨他们的互联网供应商，而实际上他们只是有一个 WiFi 瓶颈，可以自己解决。

如果某些程序正在消耗你的整个互联网连接，你想知道是哪一个。通过使用 `nethogs` 命令找到它。它在大多数软件库中都有。

有一天，我的系统监视器突然显示我的互联网访问量激增。我只是在命令行中输入了 `nethogs`，它立即确定带宽消耗者是 Clamav 防病毒更新。

*图 9. Nethogs 识别带宽用户。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

### 如何识别图形处理瓶颈

如果你把显示器插在台式电脑后面的主板上，你就在使用 *板载显卡*。如果你把它插在后面的卡上，你就有一个专门的图形子系统。大多数人称它为 *视频卡* 或 *显卡*。对于台式电脑来说，附加显卡通常比主板上的显卡更强大、更昂贵。笔记本电脑总是使用板载显卡。

HardInfo 的“PCI 设备”面板告诉你关于你的图形处理单元（GPU）。它还显示你的专用视频内存的数量（寻找标有“可预取”的内存）。

*图 10. HardInfo提供图形处理信息。(Howard Fosdick, [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/))*

CPU 和 GPU [非常密切地](https://www.wepc.com/tips/cpu-gpu-bottleneck/) 一起工作。简而言之，CPU 为 GPU 准备渲染的帧，然后 GPU 渲染这些帧。

当你的 CPU 在等待 100% 繁忙的 GPU 时，就会出现 *GPU 瓶颈*。

为了确定这一点，你需要监控 CPU 和 GPU 的利用率。像 [Conky](https://itsfoss.com/conky-gui-ubuntu-1304/) 和 [Glances](https://opensource.com/article/19/11/monitoring-linux-glances) 这样的开源监控器，如果它们的扩展插件支持你的图形芯片组，就可以做到这一点。

看一下 Conky 的这个例子。你可以看到，这个系统有很多可用的 CPU。GPU 只有 25% 的使用率。想象一下，如果这个 GPU 的数量接近 100%。那么你就会知道 CPU 在等待 GPU，你就会有一个 GPU 的瓶颈。

*图 11. Conky 显示 CPU 和 GPU 的利用率。 (图片来源：[AskUbuntu论坛](https://askubuntu.com/questions/387594/how-to-measure-gpu-usage))*

在某些系统上，你需要一个供应商专属的工具来监控你的 GPU。它们可以从 GitHub 上下载，并在 [GPU 监控和诊断命令行工具](https://www.cyberciti.biz/open-source/command-line-hacks/linux-gpu-monitoring-and-diagnostic-commands/) 这篇文章中有所描述。

### 总结

计算机由一系列集成的硬件资源组成。如果它们中的任何一个在工作量上远远落后于其他资源，就会产生性能瓶颈。这可能会拖累你的整个系统。你需要能够识别和纠正瓶颈，以实现最佳性能。

不久前，识别瓶颈需要深厚的专业知识。今天的开源 GUI 性能监控器使它变得相当简单。

在我的下一篇文章中，我将讨论改善你的 Linux 电脑性能的具体方法。同时，请在评论中分享你自己的经验。

---

via: <https://opensource.com/article/21/3/linux-performance-bottlenecks>

作者：[Howard Fosdick](https://opensource.com/users/howtech) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Ubuntu 上安装和使用 XRDP 进行远程桌面连接

# 如何在 Ubuntu 上安装和使用 XRDP 进行远程桌面连接

>
> 这是一份初学者指南，展示了在基于 Ubuntu 的 Linux 发行版上设置 XRDP 所需要遵循的步骤。有了它，你就可以从不同的电脑上访问你的 Ubuntu 系统，并以图形方式使用它。
>
>
>

微软的 [远程桌面协议](https://en.wikipedia.org/wiki/Remote_Desktop_Protocol)（RDP） 是一个允许从一台计算机到另一台计算机进行图形化远程桌面连接的协议。RDP 的工作原理是让一台主机运行软件，允许其他几台计算机连接到它。

[XRDP](https://en.wikipedia.org/wiki/Xrdp) 是 RDP 的一个开源实现，不需要运行任何专有程序。XRDP 不仅试图遵循 RDP，而且还与常规的 RDP 客户端兼容，如 [Remmina](https://remmina.org/) 和 [GNOME Boxes](https://wiki.gnome.org/Apps/Boxes)。

下面是 XRDP 连接屏幕的样子。

### 使用 XRDP 需要注意的事项

虽然 XRDP 对于机器的远程访问非常好用，但重要的是要知道 XRDP **不** 适合什么。

#### 如果你需要一个安全的连接，请不要使用 XRDP

通过 XRDP 建立的连接可以被攻击者查看和修改，因此应避免任何敏感信息。这一点可以通过使用 SSH 连接或证书来缓解，但这两者都需要更复杂的设置，这里就不一一介绍了。

#### XRDP 在默认情况下不能很好地应用主题

在我的测试中，XRDP 默认似乎从未应用过 [Ubuntu](https://ubuntu.com/) 主题。在文章的结尾处有关于解决这个问题的说明。

#### 如果你只想/需要一个 CLI 环境，就不要使用 XRDP

XRDP 是为在 GUI 环境中使用而设计和制造的。如果你打算在 CLI 环境中使用它，比如在服务器上，你应该看看其他工具，比如 SSH。

### 在 Ubuntu 上安装和使用 XRDP

下面是这个远程连接设置正常工作所需的设置：

* 一个安装了 XRDP 服务器的 Linux 系统。这是一个将被远程访问的系统。
* 远程系统应该和你的系统在同一个网络上，或者它应该有一个 [公共 IP 地址](https://itsfoss.com/check-ip-address-ubuntu/)。
* 远程 Linux 系统的用户名和密码。
* 安装有 RDP 客户端的另一个系统（无论是 Linux、macOS 还是 Windows）。

#### 第 1 步：在远程计算机上安装 XRDP

安装 XRDP 只需几个步骤，而且是相当直接的操作。

>
> 备注：在访问任何地方之前，请注意，这里说的 “远程机器” 是其他人连接到的机器。
>
>
>

XRDP 包含在大多数发行版的软件库中。在 Ubuntu 上，你可以在 universe 库中找到它。

你可以用下面的命令来安装它：

```
sudo apt install xrdp

```

#### 第 2 步：连接到远程机器

好消息是，XRDP 开箱就能使用！

要连接到你安装了 XRDP 的机器上，你首先需要在本地机器上安装一个 RDP 客户端。

我将使用 GNOME Boxes，它可以通过以下方式安装：

```
sudo apt install gnome-boxes

```

GNOME Boxes 更多的是以虚拟机使用而闻名，但它也支持其他各种协议，包括 XRDP。

如果由于某种原因你不想使用 Boxes，你也可以使用一个叫做 Remmina 的客户端。

```
sudo apt install remmina

```

不过，请注意，在本教程的其余部分，我将使用 Boxes。

首先，启动 GNOME Boxes，并点击 “+” 号，选择 “连接到远程计算机…”。

接下来，输入你要连接的机器的 IP 地址，前缀为 `rdp://`，然后按下图连接：

>
> **不确定你的 IP 地址是什么？**
>
>
> 你可以用 `ip address` 命令找到你的 IP 地址。你需要寻找一个看起来像分成四组的数字的东西：
>
>
>
> ```
> abhishek@its-foss:~$ ip address
> 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> inet 127.0.0.1/8 scope host lo
> valid_lft forever preferred_lft forever
> 2: wlp0s20f3: mtu 1500 qdisc noqueue state UP group default qlen 1000
> link/ether dc:46:b9:fb:7a:c5 brd ff:ff:ff:ff:ff:ff
> inet 192.168.0.107/24 brd 192.168.0.255 scope global dynamic noprefixroute  wlp0s20f3
> valid_lft 6183sec preferred_lft 6183sec
>
> ```
>
>

避免任何名为 `127.0.0.1` 的 IP 地址，因为那个地址指向你运行命令的机器。输出中应该有更多的 IP 地址，如上图所示。

然后，你应该会看到一个登录页面。将“会话”设置为 “Xorg”，只需输入你的用户名和密码，然后点击 “OK”。

之后，你应该看到远程主机的桌面：

至此，一切都会像机器在你面前时一样表现。

### 故障排除：修复 XRDP 连接的主题问题

在我对 Ubuntu 20.04 的测试中，默认的 Yaru 主题似乎在连接时没有应用。这可以通过一些努力来解决。

首先，在远程计算机上运行这个命令：

```
sudo apt install gnome-tweaks gnome-shell-extensions dconf-editor -y

```

接下来，打开 “扩展” 应用，并打开如下开关：

接下来，关闭你的远程桌面会话并重新登录。现在，打开 Tweaks，按照下面的截图配置：

最后，打开 dconf 编辑器，并进入 `/org/gnome/shell/extensions/dash-toock/`。设置如下所示的值：

* `custom-theme-shrink`：`On`
* `dock-fixed`：`On`
* `transparency-mode`：`FIXED`

### 总结

至此，一切都准备好了，可以做你需要做的事了。

如果有什么地方做得不太对，或者你有什么问题或意见，请在下面留言。我会尽力帮助你的。

---

via: <https://itsfoss.com/xrdp-ubuntu/>

作者：[Hunter Wittenborn](https://itsfoss.com/author/hunter/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 5.10 LTS 延长至六年支持期背后的故事

广告写这么长啊，回馈社区是应该的，有什么可夸耀的，一直吸血那是寄生虫。

找回密码收不到邮件啊

他急了他急了

不管如何,希望能一直持之以恒,openEuler20.03还没有桌面加入,20.03.sp1自己倒是测试源码编译了xfce4桌面,21.03是否有加入桌面,希望能加入多个桌面以供用户选择.虽说openEuler是rpm系,自己用debian,但感觉比redflag要好,表示支持!!

你回馈了社区什么,一句冷嘲热讽?

我为什么看不到图片？？

基金會的 CIP 延長 kernel 支持到10年

# Linux 5.10 LTS 延长至六年支持期背后的故事

>
> 可能你已经知道原计划支持 2 年的 Linux 5.10 LTS 已经延长支持到 6 年了，但是你可能不知道是谁站出来提供了支持。
>
>
>

### 支持到 2026 年的 Linux 5.10！

去年年底，Linux 内核社区发布最新长期支持版本 Linux 5.10 LTS 时，该内核只支持到 2022 年 12 月，这让很多社区成员不解，因为发布于 2016 年底的 4.9 版本都支持到 2023 年 1 月。

*未延长前的 LTS 支持计划*

面对疑问，Linux 内核维护者 Greg Kroah-Hartman 解释说，“我希望看到公司们将如何帮助我测试和维护该内核版本，以使支持它 6 年成为实际可能。”

前不久，我们看到了 Linux 内核社区发布的一则[新消息](https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.10-LTS-EOL-EOY-2026)，“在有足够多的公司加强帮助测试之后，Linux 5.10 LTS 现在将[维护到 2026 年底](https://www.kernel.org/category/releases.html)。”

发生了什么？在偶然的一个机会，我得知了是谁为 5.10 LTS 承诺了支持。这其中有一家中国公司，这是一家将开源置于战略级高度的公司，我想，你也许已经猜到了，是**华为**。

说实话，听到这个消息时，既有些意外也不意外。意外的是，我没想到中国开发者和 IT 企业已经在承担这样的重任了；不意外的是，毕竟华为已经是全球首屈一指的 Linux 内核贡献大厂了，就在 Linux 5.10 中，华为以提交 1434 个补丁而位列内核代码贡献第一名，同时以代码修改行数 41049 行位列第二名。

*Linux 5.10 贡献排行榜，华为名列榜首*

可能作为普通用户并不关心使用的是不是 Linux，更不关心使用的是什么版本和有多久的支持期，但作为一家专注于 Linux 与开源的技术社区，我深刻理解其中的含义，也更关心华为在做出这样的决定背后的考虑、付出和可持续性。于是，我和 Linux ARM64 ACPI Maintainer、openEuler Maintainer、华为工程师郭寒军约了一个访谈，现在将其中主要内容分享给诸位读者。

### 为 LTS 提供支持

杭州的梅雨季显得并不炎热，在一间很大的房间中，我和看起来比我年轻多了的受访者郭寒军同学进行了一段简短而精炼的对话。

*郭寒军（左）接受老王（右）的专访*

首先，我直奔主题问到了为什么华为会做出对 5.10 LTS 支持的承诺？从事了 Linux 内核开发十余年的郭寒军很有技术人员本色，他坦诚说，“华为将 Linux 内核用于各种各样的产品。我们在 Linux 内核上积累了很多经验，包括开发、测试和维护的能力。我们觉得可以做这些支持。”在华为内部进行了简单的讨论，讨论了需要投入的机器的资源、人的资源等等。在资源协调到位之后，“我们就公开地在邮件列表上向 Linux 内核社区与 Greg 表态说，我们愿意从公司的角度协助做维护和测试工作。”

据我所知，Linux 5.10 LTS 也将是 Debian 11 和安卓的下一个版本的内核，而在一众已经或即将采用 Linux 5.10 LTS 的软件或产品中，openEuler 发行版家族并不是最引人注目的一个，但是华为却是最主动站出来的一个。当然，在华为的表态带动之下，也有更多企业参与到了 LTS 的支持工作当中。

郭寒军还说，“其实我们提供支持的不仅仅是 Linux 5.10 LTS，而是会对目前较新的 4 个 LTS 内核都提供支持，并且会持续支持更多的 LTS 内核。”这又是一个令我意外的事情。作为一位从业互联网软件开发二十多年，眼看着 Linux 内核从一张低密度软盘即可承载的软件变成了世界上最大的软件项目，我深知要支持现在这么庞大的软件项目背后的代价有多大。其实，之所以 Greg 在一开始给 Linux 5.10 LTS 只计划了 2 年的支持期，就是因为 Linux 内核社区已经积累了 6 个 LTS 支持版本，在支持力量上有些力不从心了。目前，Linux 稳定内核的维护负责人只有两位 Greg Kroah-Hartman 和 Sasha Levin，可想而知，仅仅两人是很难照顾这么多的 LTS 内核维护工作的。

据我了解，华为对 Linux LTS 内核的测试用例已经有 8000 多项，而且还支持包括 x86\_64、ARM64 等多种架构，每个版本的测试就需要 7-8 个小时，这就需要投入大量的基础设施。

当然，我想华为在 Linux 内核方面的偌大投入，绝非是一时心血来潮，也不仅仅是技术极客们的热情奉献所致。这个支持决定不仅符合华为整体的开源战略，也给鲲鹏和 openEuler 等提供了一个坚实的底座。

### 内核能力对云原生社区的重要性

Linux 内核是整个系统的底座。所有的上层的技术，包括其上的一些应用软件都是构建在内核上面的。内核的稳定性、性能以及内核的后续的技术创新方向，都会对整个 Linux 生态和社区产生重要影响。这就是为什么我们要花这么多精力去保证它的稳定性，也是为什么要主动去承担 Linux LTS 支持的原因。

为了打造这样的一个底座，华为在内核方面进行了长期而卓有成效的投入，并把在内核方面的积累在 openEuler 社区开放。郭寒军认为 openEuler 在内核方面的能力主要体现在三个方面：兼容性、性能提升和创新。

从兼容性来说，这包括 CPU 架构和硬件的兼容性。除了支持 ARM64 架构的鲲鹏、飞腾处理器之外，openEuler 还可以支持 x86\_64 架构的兆芯、英特尔、AMD 等 CPU 架构，以及 RISC-V 家族。

从性能提升方面来说，openEuler 的多核并行等技术，针对调度机制、CPU 资源管控等来提升整个业务的线性度以提升性能。这些技术已经通过 openEuler 的下游发行版提供给了更多行业用户，真正使社区和行业用户受惠于软件技术带来的全新使用体验。

从创新方面来说，openEuler 内核的创新包括：

* 第一个创新是文件系统方面的。文件系统是华为的强项之一，从可扩展只读文件系统 EROFS 到基于非易失性内存的新型文件系统，随着存储技术的发展，也需要有新型的文件系统做支撑。
* 第二个创新是弹性软内存。这是指如何有效的利用不同速度和不同容量的存储系统，做一些分级控制，既能使用到大容量的存储，而又不降低性能。
* 第三个是目前正在重点打造的云原生内核。在云原生内核方面，业界已经有了一些探索，而华为可以结合其硬件能力做全栈的云原生支持，从进程的调度，到内存、网络以及存储，再到最底层的硬件，提供一个 QoS 控制来支持高优先级任务。

### openEuler 对 Linux 生态的意义

自 2019 年 12月 31 日 openEuler 开源以来，已有 70多家企业、机构和组织加入了 openEuler 社区，4700 多位社区开发者，成立了 83个 SIG，并有 8 家合作伙伴推出基于 openEuler 的商业发行版，在金融、政府、运营商和电力等各行业得到了广泛商用。而在去年，openEuler 社区理事会正式成立、技术委员会升级；今年，又新成立了用户委员会和品牌宣传委员会，社区治理逐步完善，走向“共建、共享、共治”。

对此，郭寒军认为，建立在 openEuler 下游的发行版天然会具备一些优势。华为一直坚持并倡导“上游优先”原则，积极地将其对 Linux 内核的改进推送到上游 Linux 内核主线，但是基于内核社区的运作机制，这个过程必然是较为漫长和复杂的。因此，openEuler 开源社区拥有的强大的 Linux 内核能力，对 openEuler 及下游的发行版来说，可以更快的响应一些特定的功能需求和硬件支持。这对于国内的一些硬件厂商来说尤为重要，可以统合更多的力量而做到更广泛的支持。

### 结语

作为一家迅速崛起的 Linux 生态开源社区，openEuler 所取得的进展令人侧目。一两年间，openEuler 及其背后的华为、麒麟、统信、联通数科、中科院软件所等一批企业，已经在整个 Linux 生态、云原生领域取得了长足发展。而在企业战略级的支持下， openEuler 社区所回哺给 Linux 社区的也足以令人赞叹，这让我对开源、对中国开源的未来有更多信心。


硬核观察 #295 推动苹果公司成为万亿公司的一封邮件

Summary: 更多：• Linux 内核将一直保留前 1MB 内存 • Torvalds 继续反对在编译 Linux 内核时使用 -O3 优化标志

# 硬核观察 #295 推动苹果公司成为万亿公司的一封邮件

### 推动苹果公司成为万亿公司的一封邮件

2007 年，苹果的市值约为 1500 亿美元。今天，它已经超过了 2 万亿美元，主要是基于 iPhone 的成功，而 iPhone 的成功，至少部分是基于 App Store 的成功。而这一切，都[始于](https://www.inc.com/jason-aten/14-years-ago-steve-jobs-sent-most-important-email-in-history-of-business.html)乔布斯的一封邮件。

最初，iPhone 在每台设备上只预装了 16 个应用。乔布斯告诉开发者，如果他们想为 iPhone 创造应用，他们可以制作在 Safari 浏览器中运行的网页应用。用户立即开始想办法越狱，以便在他们的设备上安装应用。所以，苹果只能通过某种官方 SDK 使开发应用程序成为可能。乔布斯给该公司软件工程高级副总裁 Bertrand Serlet 回答到：“当然，只要我们能在 2008 年 1 月 15 日的 Macworld 上把它全部推出来。”2008 年，我们见到了苹果的 SDK 和 App Store。

>
> 无论主动还是被动，App Store 这种划时代的创举，真正开创了新的智能手机时代。
>
>
>

### Linux 内核将一直保留前 1MB 内存

在一些特定的情况下，前 64kb 的内存会被 BIOS 破坏；在另外一些罕见情况下，前面的内存也会被 BIOS 或 EGA/VGA 帧缓冲区所破坏。因此，与其针对不同情况分别设置内存规避区域，不如将整个前 1MB 内存设置为[保留](https://lore.kernel.org/lkml/YLx%2FiA8xeRzwhXJn@zn.tnic/T/#u)。因此，在 5.13 中将永久保留前 1MB 内存而不使用。

>
> 现在真是内存富余了，可以随便将 1MB 内存保留不用了。而就在 20 多年前，那时候还是按 KB 计算着使用内存的。
>
>
>

### Torvalds 继续反对在编译 Linux 内核时使用 -O3 优化标志

由于 GCC 的较旧版本可能会在 `-O3` 编译器优化级别下产生坏的代码，而且有时没有性能上的好处，Linus Torvalds 仍然反对在编译 Linux 内核时使用这种优化标志。Torvalds 总结了他目前对 `-O3` 的看法：“它在历史上一直有可怕的错误。它已经变好了，但‘变好’并不是一个很高的标准。”WireGuard 项目从开始就一直用 `-O3` 优化级别构建，也并没有看到因此而产生不良代码的情况，但由于 Torvalds 的指导意见，该项目放弃了这个选项。除了 WireGuard 之外，LZ4 和 Zstd 是仍然在用 `-O3` 的内核模块。

>
> 一方面很多厂商转向使用新版本的编译器非常缓慢，另外一方面一些没有那么严谨的代码也并不适合更高级别的优化。理想化的优化措施，在现实情况中往往不能采用。
>
>
>


用 Python 3.8 中的这个位置技巧让你的 API 变得更好

Summary: 探索只接受位置参数和其他两个未被充分利用但仍然有用的 Python 特性。

探索只接受位置参数和其他两个未被充分利用但仍然有用的 Python 特性。

# 用 Python 3.8 中的这个位置技巧让你的 API 变得更好

>
> 探索只接受位置参数和其他两个未被充分利用但仍然有用的 Python 特性。
>
>
>

<img src="content_image/album_202106_07_164929k51eccocxkx4xf11.jpg" alt="" title="Women in computing and open source v5">

这是 Python 3.x 首发特性系列文章的第九篇。Python 3.8 于 2019 年首次发布，两年后，它的许多很酷的新特性仍然没有被使用。下面是其中的三个。

### importlib.metadata

[入口点](https://packaging.python.org/specifications/entry-points/) 在 Python 包中被用来做各种事情。大多数人熟悉的是 [console\_scripts](https://python-packaging.readthedocs.io/en/latest/command-line-scripts.html) 入口点，不过 Python 中的许多插件系统都使用它们。

在 Python 3.8 之前，从 Python 中读取入口点的最好方法是使用 `pkg_resources`，这是一个有点笨重的模块，它是 `setuptools` 的一部分。

新的 `importlib.metadata` 是一个内置模块，它允许访问同样的东西：

```
from importlib import metadata as importlib_metadata

distribution = importlib_metadata.distribution("numpy")
distribution.entry_points

```

```
    [EntryPoint(name='f2py', value='numpy.f2py.f2py2e:main', group='console_scripts'),
     EntryPoint(name='f2py3', value='numpy.f2py.f2py2e:main', group='console_scripts'),
     EntryPoint(name='f2py3.9', value='numpy.f2py.f2py2e:main', group='console_scripts')]

```

入口点并不是 `importlib.metadata` 允许访问的唯一东西。可以调试、报告，或者（在极端情况下）触发兼容模式，你也可以在运行时检查依赖的版本！

```
f"{distribution.metadata['name']}=={distribution.version}"`[/code] [code]`    'numpy==1.20.1'

```

### 只接受位置参数

强制关键字的参数在传达 API 作者的意图方面取得巨大成功之后，另一个空白被填补了：只接受位置参数。

特别是对于那些允许使用任意关键字的函数（例如，生成数据结构），这意味着对允许的参数名称的限制更少：

```
def some_func(prefix, /, **kwargs):
    print(prefix, kwargs)

```

```
some_func("a_prefix", prefix="prefix keyword value")

```

```
   a_prefix {'prefix': 'prefix keyword value'}`

```

注意，令人困惑的是，*变量* `prefix` 的值与 `kwargs["prefix"]` 的值不同。就像在很多地方一样，要注意小心使用这个功能。

### 自我调试表达式

50 多年来，`print()` 语句（及其在其他语言中的对应语句）一直是快速调试输出的最爱。

但是我们在打印语句方面取得了很大的进展，比如：

```
special_number = 5
print("special_number = %s" % special_number)

```

```
    special_number = 5

```

然而，自我记录的 f-strings 使它更容易明确：

```
print(f"{special_number=}")

```

```
    special_number=5`

```

在 f-string 插值部分的末尾添加一个 `=`，可以保留字面部分，同时添加数值。

当更复杂的表达式在该部分内时，这就更有用了：

```
values = {}
print(f"{values.get('something', 'default')=}")

```

```
    values.get('something', 'default')='default'

```

### 欢迎来到 2019 年

Python 3.8 大约在两年前发布，它的一些新特性非常酷，而且没有得到充分利用。如果你还没使用，那么将他们添加到你的工具箱中。

---

via: <https://opensource.com/article/21/5/python-38-features>

作者：[Moshe Zadka](https://opensource.com/users/moshez) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: 更多：• Colonial 管道公司向黑客支付的 230 万美元比特币赎金被追回 • 苹果发布下一代 Mac 桌面操作系统：macOS Monterey

US gov get the sever which store the keys.

# 硬核观察 #296 App Store 上销售额最高的 1000 个应用程序中，有 2% 是骗局

### App Store 上销售额最高的 1000 个应用程序中，有 2% 是骗局

《华盛顿邮报》[报道](https://www.adn.com/nation-world/2021/06/06/apples-tightly-controlled-app-store-is-teeming-with-scams/)，根据市场研究公司 Appfigures 的数据，这些应用在 App Store 上已经从消费者那里骗取了约 4800 万美元。更重要的是，苹果公司从这些应用程序中获利，抽取了高达 30% 的比例。

长期以来，苹果公司一直坚持认为其只让最好的应用程序进入其系统。但这种垄断实际上会给客户一种虚假的安全感。当涉及到一种类型的骗局时，有证据表明苹果的商店并不比谷歌的更安全。

>
> 如果真是这样，声称进行严格审查的苹果商店未必比谷歌商店更安全，反而用户可能在虚假的安全感之下损失更多。
>
>
>

### Colonial 管道公司向黑客支付的 230 万美元比特币赎金被追回

美国司法部在一次[新闻发布会上说](https://edition.cnn.com/2021/06/07/politics/colonial-pipeline-ransomware-recovered/)：“通过执法机构，受害者的资金被从钱包中没收，以防止 DarkSide 的人使用它们。” 他们已经[缴获](https://www.wsj.com/articles/u-s-retrieves-millions-paid-to-colonial-pipeline-hackers-11623094399)了所支付的 75 个比特币赎金中的近 64 个比特币。FBI 特工们确认了 DarkSide 黑客用来从 Colonial 管道公司收钱的一个加密货币钱包，但 拒绝透露具体是如何进入该比特币钱包的，理由是需要对情报技术保密。不过，Colonial 公司在支付赎金时已采取早期措施通知 FBI，并遵循指示，帮助调查人员追踪支付给黑客使用的加密货币钱包。FBI 特工说，即使是 DarkSide 这样的外国网络犯罪分子，在犯罪过程中的某个时刻，也会使用美国的基础设施。一旦他们这样做，就给了 FBI 一个收回资金的合法窗口。

>
> 我好奇的是 FBI 是如何拿到该钱包的私钥的。
>
>
>

### 苹果发布下一代 Mac 桌面操作系统：macOS Monterey

将在今年秋季推出的 macOS Monterey 的最大[新功能](https://arstechnica.com/gadgets/2021/06/apple-macos-monterey-announced-details-new-features/)之一，是能够在 iMac、MacBook 和 iPad 上共享键盘和鼠标。它被称为“通用控制”，这意味着用户可以直接在设备之间拖放文件。除此之外，macOS Monterey 将使 iPad 或 iPhone 上的视频、音频、文件和其他项目可以直接 AirPlay 到 Mac 上。

>
> 这似乎和前两天华为鸿蒙推出的概念类似。
>
>
>


寻找为 Linux 内核贡献数千补丁的“超能力者”！

我敲？原来老王长这样。

哈哈。你没看过视频版的硬核观察吗？

吐了?。centos 的 fork版 好意思说自己独立开发…………

来自湖北随州的 Chrome Mobile iOS 91.0|iOS 14.6 用户

吐了?。centos 的 fork版 好意思说自己独立开发…………

# 寻找为 Linux 内核贡献数千补丁的“超能力者”！

在 [LWN.net](http://lwn.net/) 发布的 Linux 内核报告中，常年可以看到一个贡献者 —— “Yue Hai Bing”，自 2018 年底以来，TA 对每个版本都会贡献大量的补丁，帮助 Linux 内核不断迭代。为了找到这个来自华为的优秀贡献者，我开始找到朋友圈的华为同学，了解相关信息。每次提到 “Yue Haibing” ，大家都是神秘的一笑，就不再说话。

这让我更加好奇，到底是谁，能如此频繁的在 Linux 内核中贡献，又从未在各种会议聚会中见到 TA？这让我产生了极大的好奇心。直到 openEuler 的问世，我们和 openEuler 社区的合作渐渐变多，终于知道，原来 Yue HaiBing 背后，竟然是华为的自动内核缺陷发现机器人 HULK Robot！正是 HULK Robot 完成了如此高频且优质的内核代码贡献。**没想到，我以为的大神，背后竟然是一个机器人！**

而为了能够了解到更多关于 HULK Robot 的信息，我采访了 HULK Robot 的架构师 —— 魏勇军先生，和魏勇军先生聊了聊关于 HULK Robot 的故事。

*魏勇军（左）接受老王（右）的专访*

### HULK Robot 的由来

提及 HULK Robot 的诞生，魏勇军提到，其实 HULK Robot 很早便已经在社区应用。在 2017 年的时候，HULK Robot 的前身已经进入到 Linux 内核社区当中，发挥自己的作用。

在当时，HULK Robot 以 “Wei Yongjun” 这个身份，在 Linux 内核社区中贡献代码，提交代码修复补丁。“Wei Yongjun” 提交代码的频率之高，质量之优，让 Linux 内核的核心维护者 Greg Kroah-Hartman 都为之惊叹。在 2017 年北京举办的首次 LC3 大会上，Greg Kroah-Hartman 还专门提到了“Wei Yongjun”。

而来自社区的积极反馈，让魏勇军意识到，这个机器人对 Linux 内核社区是有价值的，可以帮助 Linux 内核越变越好。那为什么不让这个事情更进一步呢？

于是，HULK Robot 正式立项了。

但，说起来容易做起来难。HULK Robot 想要给 Linux 内核贡献代码、提供补丁，却绝非易事。但魏勇军找到了思路。华为多年来虽然在做自己的服务器操作系统，但始终坚持“上游优先”，积累了大量的 Linux 内核维护经验，HULK Robot 可以通过整理过去的华为开发者的经验、测试用例，并将这些进行对比验证，确保这些修改是正确的、有价值的，再将其迁移至 HULK Robot 中，让机器人自动进行更多代码的扫描。

而随着华为对于 Linux 内核的不断进行代码贡献，终于，HULK Robot 成为了一个拥有丰富的测试集和探测能力的机器人。

### HULK Robot 如何提交代码？

HULK Robot 随着不断的发展，能够为社区贡献更多的代码，从 Linux 内核的统计报告来看，从 Linux 5.1 开始，一直到最新的 5.10、5.12 ，HULK Robot 的提交能力在逐渐变强，为社区贡献的代码也越来越多, 已经在内核社区历史 Reported-By 榜单排名 TOP2。

魏勇军说，HULK Robot 背后是一套非常复杂的分布式系统。其本质上是一个海量的测试集与一系列先进的自动化测试、问题检测的手段。HULK Robot 和别的 Linux 内核测试机器人不同的是华为因为开发 openEuler 发行版，在内核的维护上付出了不少的时间和精力，拥有丰富的经验，也因此可以在其中贡献更多的代码。

对于魏勇军来说，HULK Robot 如今的重点已经远不是准备更多的测试集，而是要进一步的优化整个内核检测的流程。目前每次版本变更 HULK Robot 都需要跑一次完整的测试集，费时费力，他希望可以让 HULK Robot 可以更加的智能，当代码更改之后，只检测牵涉到相应功能的测试集，而不是测试庞大的全部测试集。此外，加入更多的 DevOps 能力，让更多的人可以参与到 HULK Robot 的开发工作中，更好的为内核贡献代码。这些修改，都可以让 HULK Robot 可以更好的为整个社区提供贡献，更加高效的贡献代码。

也正因为 HULK Robot ，让整个社区可以拥有一个更加稳健和安全的操作系统，整个社区都因 HULK Robot 受益。

### 社区、开源、机器人

其实一直以来，机器人的应用在开源项目的维护当中是广泛应用的，但对于开源项目本身的维护，一直以来机器人参与的都不多，我也借此机会与魏勇军交流了想法。

魏勇军表示，Linux 内核的维护风格是非常社区化的，社区的维护者默认信任每一个提交贡献者都是为了社区的长期发展而贡献代码，因此，社区的维护者并不拒绝机器人参与到内核的维护中。如果对于整个社区的长期发展是有益的、做出了优质的贡献，社区支持更多的自动化机器人参与到贡献当中。

也许在未来， 我们能看到HULK Robot 会开源，让整个社区一起参与到贡献当中，更好的让 Linux 内核得到维护。

### 用技术赋能社区

一直以来，Linux 社区都因为资深维护者的流失而担忧，担心社区不再有年轻的血液注入，最终失去了活力。

而 HULK Robot 则为这个事情提供了一种新的思路：可以将资深维护者的经验变成固化的代码，从而使得知识得以传承，而 HULK Robot 的自动化运行机制，又为社区提供了源源不断的贡献和补丁，让这个系统成为一个更加好用和安全的系统。从某种角度来看， HULK Robot 解放了 Linux 内核的贡献者，让贡献者们可以更加专心的做更加重要的事情，把这些繁琐复杂的事情，交给机器人来完成，从而降低了对于社区新鲜血液的需求度。

HULK Robot 不仅仅是为上游提供了新鲜的血液，也更是 openEuler 长期发展不可或缺的护道人，正是 HULK Robot 背后的默默无闻的工作，才能让 openEuler 可以更加稳固的运行，为广大开发者提供一个简单、好用、实用的 Linux 发行版。

我们需要新鲜血液么？当然需要，但如果我们能把门槛降低，这不也是一件好事么？

---

2021 年 6 月 10 日，openEuler 社区将发起一场面向社区开发者的技术盛会 openEuler Developer Day 2021 ，会上将对多样性计算、云原生全栈、全场景协同等技术发展方向进行持续探索和创新；技术委员会、用户委员会、品牌委员会等 20 个 SIG 组同期举办开放工作会议；技术委员会主席将深入解读 openEuler 21.03，发布下个社区版的技术定位并分享社区创新思路；客户、伙伴、厂商、研究机构将在开源圆桌中共同探讨开源软件供应链的意义和风险，开源模式如何推动以及独立演进操作系统的技术发展。

更多活动信息： <https://openeuler.org/zh/interaction/summit-list/devday2021/>


Summary: 对于开发团队来说，这应该是一个令人兴奋的用于测试的更新。

对于开发团队来说，这应该是一个令人兴奋的用于测试的更新。

# openSUSE Leap 15.3 版本缩小了与 SUSE Linux 企业版的差距

>
> 随着 openSUSE 15.3 的发布，与 SUSE Linux 企业版的差距终于缩小了。对于开发团队来说，这应该是一个令人兴奋的用于测试的更新。
>
>
>

去年，在 [openSUSE Leap 15.2 发行版](https://itsfoss.com/opensuse-leap-15-2-release/) 中他们希望通过使用与企业版相同二进制软件包来构建 openSUSE Leap，从而缩小 openSUSE Leap 与 SUSE Linux 企业版之间的差距。

这样一来的话，如果有人在使用 openSUSE 测试后切换到 SUSE Linux 企业版，部署的迁移过程都将大大简化。此外，openSUSE Leap 将是开发团队进行测试的一个轻松选择。

随着 openSUSE Leap 15.3 的发布，这个构想成为了现实。本文我将重点介绍这次发布的主要变化。

### openSUSE Leap 15.3: 最新变化

最重要的变化是，它使用与 SUSE Linux 企业版相同的二进制软件包构建。

并且，[发布公告](https://news.opensuse.org/2021/06/02/opensuse-leap-bridges-path-to-enterprise/) 中提到了这一巨大变化的好处：

>
> 此版本对于迁移项目和用户验收测试非常有益，使用 openSUSE leap 15.3 进行运行调优和测试工作负载的大型开发团队将会获得最大的好处，因为这些工作负载可以轻松提升并转移到 SUSE Linux 企业版 15 SP3 上进行长期维护。
>
>
>

除了这个巨大的变化，还有其他几个重要的变化使它成为一个令人激动的版本。

对于 Xfce 4.16 桌面，有一些视觉变化，包括新的图标和调色板。设置管理器还增加了一个视觉刷新功能，提供了更清晰的外观。

如果有需要，KDE Plasma 5.18 也可以作为 LTS 选项与此版本一起提供。而且，GNOME 3.34 在某些应用程序的外观和感觉上有一些细微的变化。虽然 Cinnamon 没有大的变化，但是你会发现它有了一个新的模式。

在这个版本中，你将发现 gnu health 3.8 添加了一些新特性供你探索。

DNF 包管理器有一个更新计划，但是当前没有释放出来，你可以通过后续的维护更新获得它。

IBM Z 和 LinuxONE（s390x）是 Leap 15.3 中新支持的两种架构。

所包含的容器技术仍然保持不变，但是它们在本版本中收到了安全更新。当然，你需要去找 Linode 等托管解决方案提供的最新云镜像。

几个应用程序升级包括 Ononishare 2.2、Chromium 89 等。你可以在 [官方特性列表](https://en.opensuse.org/Features_15.3) 中找到更多详细信息。

### 下载 openSUSE Leap 15.3

需要注意的是，从今天起，Leap 15.2 将有六个月的寿命（EOL）。

在尝试升级到 Leap 15.3 之前，你必须确保运行的是 Leap 15.2。你可以在他们的 [官方发行说明](https://en.opensuse.org/Release_announcement_15.3) 中找到有关升级过程的更多信息。

从下面的按钮链接的官方下载页面获取最新的 ISO。

* [下载 openSUSE Leap 15.3](https://get.opensuse.org/leap/)

---

via: <https://news.itsfoss.com/opensuse-leap-15-3-release/>

作者：[Ankush Das](https://news.itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Chao-zhi](https://github.com/Chao-zhi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


硬核观察 #297 Lotus Notes 表示还可以抢救一把

Summary: 更多：• 调查显示在 RHEL 上部署 SQL Server 很流行 • 即使 iPhone 被关机或擦除，iOS 15 仍然可以定位它

所以现在的小偷需要带个特制的包包，然后苹果这是加速了偷盗科学化吗？

# 硬核观察 #297 Lotus Notes 表示还可以抢救一把

### Lotus Notes 表示还可以抢救一把

HCL [发布](https://www.theregister.com/2021/06/08/hcl_domino_12_debuts/)了群件服务器 Domino 12，并在一个视频中宣称，“Notes 和 Domino 已经转型了”。这个 2018 年被 HCL 从 IBM 收购过来的群件软件，现在是一个云原生、低代码的产品，并提供了一个可行的 Exchange 替代品。如今，低调发布的 Domino 应用程序可以在浏览器中运行，也提供了低代码开发环境。Domino 可以运行在包括 AWS、Azure 和 Google 等云环境中，甚至还可运行在 Kubernetes 和 OpenShift 上。

>
> 我都以为只在一些大型企业内使用的 Lotus Notes 已经被淘汰了呢，没想到居然还与时俱进了。
>
>
>

### 调查显示在 RHEL 上部署 SQL Server 很流行

2020 年底，红帽委托对 SQL Server 专业协会的 300 多名成员进行了调研，其中 54% 的受访者拥有数据库管理员的头衔。[结果显示](https://mp.weixin.qq.com/s/fmWlkkw0FJrxKNioiz5aGg)：31% 受访者在他们的站点上至少运行了一个 Linux 操作系统；12% 的表示他们正在 RHEL 上运行 SQL Server；采用 Linux 作为 SQL Server 平台的人数预计将在未来两年内增加两倍以上。

>
> 虽然微软发布 Linux 版的 SQL Server 已经有一段时间了，但是我没想到还真有不少用户在 Linux 上使用它。
>
>
>

### 即使 iPhone 被关机或擦除，iOS 15 仍然可以定位它

在 iOS 15 之前，iPhone 关机后并不能通过“查找我的网络”找到它，而在新发布的 iOS 15 中，即使 iPhone 关机甚至被擦除，仍然可以[定位到它的位置](https://9to5mac.com/2021/06/07/ios-15-find-my-network-can-find-your-iphone-when-it-is-powered-off/)。在 iOS 15 中，手机并没有真正完全“断电”，它一直处于低功耗状态，就像一个 AirTag，允许任何附近的 iOS 设备接收蓝牙信号并发送回其位置。当然，这种行为可以关闭。

此外，当手机被重置为启用激活锁的出厂设置时，位置追踪甚至会继续工作。如果丢失的 iPhone 被卖给别人，欢迎屏幕将清楚地显示“设备被锁定，可被定位。”

>
> 关机的 iPhone 可能仍然在“偷偷”工作着……
>
>
>