分类 技术 下的文章

在本文中我们将继续学习概率论的知识。

在本系列的 上一篇文章中,我们学习了使用 Anaconda,加强了概率论的知识。在本文中我们将继续学习概率论的知识,学习使用 seaborn 和 Pandas 进行数据可视化,并进一步介绍 TensorFlow 和 Keras 的使用。

让我们从增长人工智能和机器学习的理论知识开始。众所周知人工智能、机器学习、数据科学、深度学习等是当今计算机科学的热门话题。然而,计算机科学还其他热门的话题,比如 区块链 blockchain 物联网 Internet of Things (IoT)、 量子计算 quantum computing 等。那么,人工智能领域的发展是否会对这些技术产生积极的影响呢?

首先,让我们讨论一下区块链。根据维基百科的定义,“区块链是一种分布式账本,它由不断增长的记录(称为 区块 block )组成,这些记录使用加密技术安全地连接在一起。”乍一看,人工智能和区块链似乎是两个高速发展的独立技术。但令人惊讶的是,事实并非如此。区块链相关的行话是 完整性 integrity ,人工智能相关的行话是数据。我们将大量数据交给人工智能程序去处理。虽然这些应用程序产生了惊人的结果,但我们如何信任它们呢?这就提出了对可解释的人工智能的需求。它可以提供一定的保证,以便最终用户可以信任人工智能程序提供的结果。许多专家认为,区块链技术可以用来提高人工智能软件做出的决策的可信度。另一方面, 智能合约 smart contract (区块链技术的一部分)可以从人工智能的验证中受益。从本质上讲,智能合约和人工智能通常都是做决策。因此,人工智能的进步将对区块链技术产生积极影响,反之亦然。

下面让我们讨论一下人工智能和物联网之间的影响。早期的物联网设备通常没有强大的处理能力或备用电池。这使得需要大量处理能力的机器学习的软件无法部署在物联网设备上。当时,大多数物联网设备中只部署了基于规则的人工智能软件。基于规则的人工智能的优势在于它很简单,需要相对较少的处理能力。如今的物联网设备具备更强大的处理能力,可以运行更强大的机器学习软件。特斯拉开发的高级驾驶辅助系统 特斯拉自动驾驶仪 Tesla Autopilo 是物联网与人工智能融合的典范。人工智能和物联网对彼此的发展产生了积极影响。

最后,让我们讨论人工智能和量子计算是如何相互影响的。尽管量子计算仍处于起步阶段,但 量子机器学习 quantum machine learning (QML)是其中非常重要的课题。量子机器学习基于两个概念:量子数据和量子-经典混合模型。量子数据是由量子计算机产生的数据。 量子神经网络 quantum neural network (QNN)用于模拟量子计算模型。TensorFlow Quantum 是一个用于量子-经典混合机器学习的强大工具。这类工具的存在表明,在不久的将来将会有越来越多的基于量子计算的人工智能解决方案。

seaborn 入门

seaborn 是一个基于 Matplotlib 的数据可视化 Python 库。用它能够绘制美观且信息丰富的统计图形。通过 Anaconda Navigator 可以轻松安装 seaborn。我用 ESPNcricinfo 网站上 T20 国际板球赛的击球记录,创建了一个名为 T20.csv 的 CSV( 逗号分隔值 comma-separated value )文件,其中包含以下 15 列:球员姓名、职业生涯跨度、比赛场次、局数、未出局次数、总得分、最高得分、平均得分、面对球数、击球率、百分次数、五十分次数、零分次数、四分次数和六分次数。图 1 是使用 Pandas 库读取这个 CSV 文件的程序代码。我们已经在前面介绍过 Pandas 了。

图 1:使用 seaborn 的简单例子

下面逐行解释程序代码的作用。第 1 行和第 2 行导入 Pandas 和 seaborn 包。第 3 行从 JupyterLab 的工作目录中读取文件 T20.csv。第 4 行打印元数据和第一行数据。图 1 显示了这行数据,它显示了 T20 国际板球赛中得分最高的 Virat Kohli 的击球记录。第 5 行将元数据和 T20.csv 中的前五行数据保存到 Best5.csv 中。在执行该行代码时会在 JupyterLab 的工作目录中创建这个文件。第 6 行根据列百分次数按升序对 CSV 文件进行排序,并将前 10 名世纪得分手的详细信息存储到 Highest100.csv 中。该文件也将存储在 JupyterLab 的工作目录中。最后,第7行代码提取了第 5 列(总得分)和第 7 列(平均得分)的数据信息,并生成散点图。图 2 显示了程序在执行时生成的散点图。

图 2:seaborn 绘制的散点图

在程序末尾添加如下代码行并再次运行。

sns.kdeplot(data=df.iloc[:, [5, 7]].head(50), x=’Ave’, y=’Runs’)

图 3:使用 seaborn 绘制的核密度估计图

这行代码调用 kdeplot() 函数绘制第 5 列和第 7 列数据的 核密度估计 Kernel Distribution Estimation (KDE)图。KDE 图可以描述连续或非参数数据变量的概率密度函数。这个定义可能无法让您了解函数 kdeploy() 将要执行的实际操作。图 3 是在单个图像上绘制的 KDE 图和散点图。从图中我们可以看到,散点图绘制的数据点被 KDE 图分组成簇。seaborn 还提供了许多其他绘图功能。在图 1 中程序的第 7 行分别替换为下面的的代码行(一次一行),并再次执行该程序,你会看到不同风格的绘图显示。探索 seaborn 提供的其他绘图功能,并选择最适合你需求的功能。

sns.histplot(data=df.iloc[:, [5, 7]].head(50), x=’Ave’, y=’Runs’)
sns.rugplot(data=df.iloc[:, [5, 7]].head(50), x=’Ave’, y=’Runs’)

更多概率论

在本系列之前的一篇文章中,我们看到可以用正态分布来对现实场景进行建模。但正态分布只是众多重要概率分布中的一种。图 4 中的程序绘制了三种概率分布。

图 4:绘制多种概率分布的程序

下面我来解释这个程序。第 1 行导入 NumPy 的 random 模块。第 2 行和第 3 行导入用于绘图的 Matplotlib 和 seaborn。第 5 行生成带有参数 n(试验次数)和 p(成功概率)的 二项分布 binomial distribution 数据。

二项分布是一种离散概率分布,它给出了在一系列 n 次独立实验中成功的数量。第三个参数 size 决定了输出的形状。第 6 行绘制生成的数据的直方图。由于参数 kde=True,它还会绘制 KDE 图。第三个参数 color='r' 表示绘图时使用红色。第 7 行生成一个泊松分布。泊松分布是一种离散概率分布,它给出了二项分布的极限。参数 lam 表示在固定时间间隔内发生预期事件的次数。这里的参数 size 也决定了输出的形状。第 8 行将生成的数据绘制为绿色的直方图。第 9 行生成大小为 1000 的指数分布。第 10 行将生成的数据绘制为蓝色的直方图。最后,第 11 绘制三个概率分布的所有图像(见图 5)。NumPy 的 random 模块提供了大量的其他概率分布,如 Dirichlet 分布、Gamma 分布、几何分布、拉普拉斯分布等。学习和熟悉它们将是非常值得的。

图 5:概率分布的图像

现在,让我们学习线性回归。使用线性回归分析可以根据一个变量来预测一个变量的值。线性回归的一个重要应用是数据拟合。线性回归非常重要,因为它很简单。机器学习中的监督学习范式实际上就是回归建模。因此,线性回归可以被认为是一种重要的机器学习策略。这种学习范式通常被统计学家称为统计学习。线性回归是机器学习中的重要操作。NumPy 和 SciPy 都提供了线性回归的函数。下面我们展示使用 NumPy 和 SciPy 进行线性回归的示例。

图 6:使用 NumPy 进行线性回归

图 6 是使用 NumPy 进行线性回归的程序。第 1 行和第 2 行导入 NumPy 和 Matplotlib。第 4 行和第 5 行初始化变量 ab。第 6 行使用函数 linspace() 在 0 和 1 之间等间隔地生成 100 个数字。第 7 行使用变量 ab 和数组 x 生成数组 y 中的值。函数 randn() 返回标准正态分布的数据。第 8 行将数组 xy 中的值绘制成散点图(见图 7),图中的 100 个数据点用红色标记。第 9 行使用函数 polyfit() 执行称为 最小二乘多项式拟合 least squares polynomial fit 的线性回归技术。函数 polyfit() 的输入参数包括数组 xy,以及第三个表示拟合多项式的阶数的参数,在本例中为 1,表示拟合一条直线。该函数的返回值是多项式的系数,代码中将其存储在数组 p 中。第 10 行使用函数 polyval() 对多项式求值,并将这些值存储在数组y_l中。第 11 行用蓝色绘制拟合得到的直线(见图 7)。最后,第 12 行显示所有的图像。可以用这条回归直线预测可能的 (x, y) 数据对。

图 7:线性回归散点图 1

图 8 是使用 SciPy 进行线性回归的程序代码。

图 8:使用 SciPy 进行线性回归

下面我解释一下这个程序的工作原理。第 1 行和第 2 行导入库 NumPy 和 Matplotlib。第 3 行从库 SciPy 导入 stats 模块。第 4 到 8 行与前面的程序执行类似的任务。第 9 行使用 SciPy 的 stats 模块的 linregression() 函数计算两组测量值的线性最小二乘回归——在本例中是数组 xy 中的值。该函数返回值中的 mc 分别表示回归直线的 斜率 slope 截距 intercept 。第 10 行使用斜率和截距的值生成回归线。第 11 行用绿色绘制回归线。最后,第 12 行显示所有的图像(见图 9),其中数据点以黄色显示,回归线以绿色显示。

图 9:线性回归散点图 2

在本系列的前面几篇文章中,我们学习了概率和统计学的一些概念。尽管还不够全面的,但我认为这已经打下了一个良好的基础,现在是时候将注意力转移到其他同样重要的问题上了。

Keras 简介

Keras 一般与 TensorFlow 一起使用。因此,我们先从使用 TensorFlow 开始。图 10 所示的程序虽然只包含四行代码,但确实构建了在本系列中的第一个神经网络。下面我来介绍它的工作原理。第 1 行导入库 TensorFlow。第 2 行创建了一个名为 x 的张量。第 3 行和第 4 行分别在张量 x 上应用 ReLU( 整流线性单元 Rectified Linear Unit )和 Leaky ReLU 激活函数。在神经网络中,激活函数定义了节点的输出由输入计算出的规则。ReLU 激活函数是定义为 Relu(x) = max(0,x)。第 3 行代码的输出如图 10 所示。可以观察到,在应用 ReLU 激活函数后,张量 x 中的负值被替换为零。Leaky ReLU 是 ReLU 激活函数的改进版本。从图 10 中的第 4 行代码的输出可以看出 Leaky ReLU 激活函数保留了全量的正值和 20% 的负值。在后面我们将会继续讨论 Keras,同时学习更多神经网络和激活函数的知识。

图 10:使用 TensorFlow 实现的神经网络

下面我们开始使用 Keras。Keras 的安装也可以通过 Anaconda Navigator 轻松完成。图 11 所示的程序导入了我们的第一个数据集并显示了其中的一个数据样本。在下一篇文章中,我们将使用这个数据集来训练和测试模型,从而开启我们开发人工智能和机器学习程序的下一个阶段。

图 11:第一个数据集

下面介绍这个程序的工作原理。第 1 行导入 Keras。第 2 行从 Keras 导入手写数字数据集 MNIST。它包含 6 万个训练样本和 1 万个测试样本。第 3 行导入 Matplotlib。第 5 行加载 MNIST 数据集。第 6 到 9 行打印训练集和测试集的维数和维度。图 12 显示了这些代码行的输出。可以看出,训练集和测试集都是三维的,所有数据样本的分辨率都是 28 × 28。第 10 行加载了第 1234 个训练图像。第 11 行和第 12 行显示这个图像。从图 12 可以看到它是数字 3 的手写图像。

图 12:数据样例

本文中我们开始涉及到神经网络,并通过 Keras 接触到了第一个数据集。在下一篇文章中,我们将继续讲解神经网络和 Keras,并通过使用该数据集训练自己的模型。我们还会遇到 scikit-learn, 它是另一个强大的机器学习 Python 库 。

(题图:DA/2f8f2e0c-c9a7-4a55-8a03-3b5105721013)


via: https://www.opensourceforu.com/2023/01/ai-introduction-to-keras-and-our-first-data-set/

作者:Deepu Benson 选题:lujun9972 译者:toknow-gh 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

没错,即使是 GNOME 登录屏幕也可以自定义。这里有一个方便的实用工具,可以让事情变得更简单。

从停靠区到 GRUB 屏幕,GNOME 都可以根据你的喜好进行定制。

登录界面也在此列,因为一款名为 “ GDM 设置 GDM Settings ”的新工具可让你更改 GNOME 登录界面的外观并调整其功能。

你可以更改壁纸、主题、图标、时间格式、顶部面板项目等。你还可以在登录界面启用轻击功能(我喜欢这个)。

在本教程中,你将了解安装此工具的步骤以及如何使用它来更改 GDM 登录屏幕的各个方面。

不用说,你必须使用 GNOME 桌面环境和 GDM 显示管理器才能按照此处的说明进行操作。

? 以这种方式使用设置可能会产生问题。请使用 Timeshift 备份系统设置。如果你容易手忙脚乱,不喜欢排除故障,这篇文章就不适合你。

使用 GDM 设置工具进行调整

让我们首先看看你可以使用这个很棒的程序进行哪些更改。

1、更改 shell 主题、图标和壁纸

你可以更改登录屏幕的主题、图标和壁纸。这是一个例子。

要更改主题,你应该先下载它。可以从 GNOME Look 网站 获取一个。

接下来,确保主题位于 /usr/share/themes 中。存储在 ~/.themes 中的主题对 GDM 设置应用是不可见的。

在 GDM 设置应用中,转到 “ 外观 Appearance ” 选项卡并选择 “ 主题 Themes ”(Shell/图标/光标)。

GDM 主题设置

如果要设置壁纸,请将 “ 背景 Background ” 更改为 “ 图像 Image ”,然后从文件浏览器浏览图片。

更换壁纸

完成后,单击 “ 应用 Apply ”。这将要求输入密码。请在出现提示时提供。

你将收到注销通知以应用更改。注销后,更改将可见。

注销提示

? 你可以更改所有设置然后单击“应用”,或者每次设置后单击“应用”。如果按“应用”,则会提示你注销,每次都需要重新登录并再次打开该设置应用。

2、更改字体

在更改字体之前,你需要为所有用户在系统上安装该字体。

为了确保这一点,请将下载的自定义字体文件粘贴到 /usr/local/share/fonts,然后使用以下命令创建字体缓存:

fc-cache -f -v

现在,打开 GDM 设置并转到“ 字体 Fonts ”选项卡。在那里,你可以设置字体、抗锯齿设置等。

更改字体设置

你可以看到新字体现已设置为你的登录屏幕。

自定义字体

3、更改顶部面板的颜色

要更改顶部面板颜色,请转到侧栏中的 “ 顶部栏 Top Bar ” 选项。在 “ 调整 Tweaks ” 下,启用 “ 更改背景颜色 Change Background Color ” 按钮,然后设置所需的颜色。

更改顶部面板颜色设置

将顶部栏的文本颜色更改为适合你选择的背景的颜色也同样重要。

更改顶栏颜色

4、更改时间显示格式

使用下拉菜单将时钟更改为 24 小时或 12 小时格式。

更改时间显示格式设置

此外,你可以通过切换相应的按钮使秒在顶部栏上可见。

顶栏显示秒

5、启用登录屏幕轻击

在大多数发行版中,这是默认行为。即使在系统中启用了轻击,GNOME 登录界面也需要使用鼠标左键点击。

要更改此设置,请转到鼠标和触摸板部分并启用 “ 轻击 Tap to Click ” 按钮。

启用屏幕点击

在同一菜单上,你可以选择调整鼠标光标大小(如果你觉得它很小)。

更改鼠标光标大小

6、启用夜灯

你可以为 GDM 启用预定的夜灯。

转到 “ 显示 Display ”,打开 “ 夜灯 Night Light ” 按钮。现在,安排日落到日出或你选择的方便时间。

启用夜灯

7、添加徽标和欢迎消息

转到 “ 登录屏幕 Login Screen ” 选项卡,然后启用 “ 启用徽标 Enable Logo ” 按钮。这将为你提供一个浏览图像的按钮。

添加 logo

选择图像并按 “ 应用 Apply ”。

? 在我的系统显示器上,尺寸高达 128×128 像素的图像看起来是可以接受的,超出这个尺寸对我来说看起来很大。因此,请相应地选择尺寸。

应用图像后,要设置欢迎消息,请启用欢迎消息按钮,然后添加你想要显示的文本。

添加欢迎信息

当你选择用户输入密码时,将显示该消息。

登录屏幕欢迎消息

8、导出和导入设置

如果你想在其他系统上应用相同的设置,你可以导出设置并将其导入到运行 GDM 设置工具的其他系统上。

单击左上角的菜单,然后选择 “ 导出到文件 Export to file ”。

导出到文件

将文件命名为 “.ini” 并将其保存在安全的地方。你可以稍后导入。

命名文件

9、重置所有设置

不喜欢你所做的更改? 有一个简单的方法可以恢复默认值。

要重置调整,请单击左上角的菜单并选择 “ 重置设置 Reset settings ”。

重置设置

现在,按 “ 应用 Apply ”。它会询问你的密码。提供后,系统将提示你注销。

你可以看到,所有更改均已恢复。

10、更多设置

还有其他可用的调整,例如:

  1. 通过 “ 顶栏 Top Bar 电源 Power 显示电池百分比 Show Battery Percentage ”,在顶栏显示电池百分比。
  2. 通过 “ 登录屏幕 Login Screen 禁用用户列表 Disable User List ”,在登录屏幕上禁用或启用用户列表。
  3. 通过 “ 电源 Power ” 选项卡更改屏幕关闭时间、暂停时间和其他电源设置。

安装 GDM 设置工具

既然你知道该工具可以进行哪些调整,你可能想自己尝试一下。让我们看看如何安装它。

? 在 Ubuntu / Pop!\_OS 上,GDM 设置工具对我不起作用。我在 Debian 12 Bookworm 上以 Flatpak 应用使用。

GDM 设置工具可以作为 Flatpak 安装。

flatpak install flathub io.github.realmazharhussain.GdmSettings

或者,它可以作为 AppImage 提供。

对于 Arch Linux 用户,请使用 AUR 中的任何 AUR 助手进行安装。

yay -S gdm-settings

结论

登录屏幕并不是每个人都可以定制的。除了“轻击”更改之外,大多数其他更改都只是外观更改。

总的来说,对于喜欢自定义设置的每个角落的人们来说,有这样的选择是件好事。

?️ 你是那些痴迷于定制的 Linux 用户之一吗? 你会尝试 GDM 设置工具吗?

(题图:DA/fb8961d0-852d-4d89-b5b2-d2912b38f6f8)


via: https://itsfoss.com/customize-gdm-login/

作者:Sreenath 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Kate(KDE Advanced Text Editor)是一款自由开源的文本编辑器,适用于 Linux、Windows 和 macOS。

对于文档编写者来说,Kate 集成的 Git 功能可以帮助简化编写过程。你无需记住 Git 命令,也无需在每次更改文件或切换分支时在终端中输入它们。

本文重点为从事各种 Fedora 文档仓库的贡献者介绍 Kate 的主要功能。这些功能可以扩展到其他文档仓库。

将 Kate 与你的仓库一起使用的准备工作

  1. 将 SSH 密钥添加到 Pagure、GitLab 或 GitHub 上的帐户设置中。

    • 在 Pagure 上,转到 我的设置 My Settings SSH 密钥 SSH Keys 添加 SSH 密钥 Add SSH Key
    • 在 GitLab 上, 首选项 Preferences 用户设置 User Settings 添加 SSH 密钥 Add an SSH Key
    • 在 GitHub 上, 设置 Settings SSH 和 GPG 密钥 SSH and GPG keys 新的 SSH 密钥 New SSH key
  2. 复刻项目:转到上游仓库并选择 “ 复刻 Fork ” 按钮
  3. 克隆仓库

    • 在你的分叉仓库中,选择 “ 使用 SSH 克隆 Clone with SSH ”。
    • 接下来,将该链接复制到剪贴板并将其粘贴到终端中的 GIT URL 中。
    • 克隆仓库时,你可以指定新目录名称作为附加参数。$ git clone <GIT URL> 新目录
  4. 安装 Kate。如果你是 Linux 用户,请转到发行版的包管理器来安装 Kate。如果你使用 Fedora Linux,我们推荐 Fedora Linux RPM 版本或 Flatpak。

会话

Kate 文本编辑器中的会话功能可以将单独的项目分组在一起,并帮助你在单个视图中处理多个文档仓库。

要将仓库保存在会话中:

转到 “ 文件 File ” 下拉菜单 – 选择 “ 打开文件夹 Open folder ” – 选择克隆的目录。

从 “ 会话 Sessions ” 下拉菜单中 – 选择 “ 保存会话 Save session ” – 输入会话名称 – 按 “ 确定 OK ”。

在左侧窗格中,单击 “ 项目列表 project list ” 保存到新会话“Magazine”。下次打开 Kate 时,保存到会话中的克隆仓库将重新出现。

Sessions Menu

使用状态栏签出分支

使用 Kate 编辑器,你可以在状态栏和弹出屏幕上切换分支或创建新分支。

当前分支显示在状态栏的右下角。

要创建新分支,请选择 “Main” 分支。从弹出菜单中选择 “ 创建新分支 Create New Branch ” 并输入新分支名称。

Popup menu showing Create New branch

对 AsciiDoc 高亮显示的内置支持

具有 AsciiDoc 扩展名的文件将使用 asciidoc.xml 中的规则自动高亮显示。你不需要安装外部插件。

即时拼写检查

如果你希望在输入时自动进行拼写检查,请按 Ctrl + Shift + O。此组合键将打开和关闭拼写检查。

Git 工具视图

左侧窗格中的工具视图显示每个打开文件的 Git 状态。

Show diff

已暂存 Staged ” 表示文件已添加(与 Git 添加相同),并且如果你选择顶部的 “ 提交 Commit ” 按钮,文件将被提交。

已修改 Modified ” 显示尚未暂存的更改。

单击左侧面板顶部的 “ 提交 Commit ” 按钮以显示该提交的差异。这将在提交工具视图中打开选定的提交。如果你想查看提交中的所有更改,请右键单击并选择 “ 显示完整提交 Show Full Commit ”,添加一个提交消息。

Git “ 推送 Push ” 按钮在 “ 提交 Commit ” 按钮的右边。Git “ 拉取 Pull ” 按钮在 “ 推送 Push ” 按钮的右边。

选择 “ 刷新 Refresh ” 图标(圆圈箭头)以查看暂存文件和提交的情况。

集成终端

F4 或选择 “ 终端 Terminal ” 按钮可打开和关闭集成终端。

你可以通过集成终端使用构建脚本和 Vale linter,将你的写作提升到一个新的水平,确保文档质量。

步骤 1. 运行构建脚本

要在本地检查文档质量,你可以在集成终端中运行构建和预览脚本。构建和预览脚本可让你准确查看更改如何通过 Antora 静态站点生成器在文档页面中发布。

注意:检查 Fedora 文档仓库的 README 页面,为构建脚本和说明使用正确的文件名。下面是一个例子:

要构建和预览站点,请运行:

$ ./docsbuilder.sh -p

结果可访问 http://localhost:8080

要停止预览:

$ ./docsbuilder.sh -k

步骤 2. 对你的文本运行 Vale

Vale 是一个命令行工具,用于检查文本是否符合定义的样式指南。参考该 指南 在本地运行 Vale。

鸣谢

非常感谢 KDE 开发人员 Nicco,他的视频教程频道 “Nicco loves Linux” 给了我很多灵感。

本文使用的 Kate 版本为 23.08.3

上游文档

以下是本文使用的 Fedora 文档 Git 仓库:

(题图:DA/519568d2-a224-4075-a751-a1a8bc702079)


via: https://fedoramagazine.org/writing-docs-with-kate-and-git/

作者:Hank Lee 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

大家好!我一直在慢慢摸索如何解释 Git 中的各个核心理念(提交、分支、远程、暂存区),而提交这个概念却出奇地棘手。

要明白 Git 提交是如何实现的对我来说相当简单(这些都是确定的!我可以直接查看!),但是要弄清楚别人是怎么看待提交的却相当困难。所以,就像我最近一直在做的那样,我在 Mastodon 上问了一些问题。

大家是怎么看待 Git 提交的?

我进行了一个 非常不科学的调查,询问大家是怎么看待 Git 提交的:是快照、差异,还是所有之前提交的列表?(当然,把它看作这三者都是合理的,但我很好奇人们的 主要 观点)。这是调查结果:

结果是:

  • 51% 差异
  • 42% 快照
  • 4% 所有之前的提交的历史记录
  • 3% “其他”

我很惊讶差异和快照两个选项的比例如此接近。人们还提出了一些有趣但相互矛盾的观点,比如 “在我看来,提交是一个差异,但我认为它实际上是以快照的形式实现的” 和 “在我看来,提交是一个快照,但我认为它实际上是以差异的形式实现的”。关于提交的实际实现方式,我们稍后再详谈。

在我们进一步讨论之前:我们的说 “一个差异” 或 “一个快照” 都是什么意思?

什么是差异?

我说的“差异”可能相当明显:差异就是你在运行 git show COMMIT_ID 时得到的东西。例如,这是一个 rbspy 项目中的拼写错误修复:

diff --git a/src/ui/summary.rs b/src/ui/summary.rs
index 5c4ff9c..3ce9b3b 100644
--- a/src/ui/summary.rs
+++ b/src/ui/summary.rs
@@ -160,7 +160,7 @@ mod tests {
  ";

          let mut buf: Vec<u8> = Vec::new();
-        stats.write(&mut buf).expect("Callgrind write failed");
+        stats.write(&mut buf).expect("summary write failed");
          let actual = String::from_utf8(buf).expect("summary output not utf8");
          assert_eq!(actual, expected, "Unexpected summary output");
      }

你可以在 GitHub 上看到它: https://github.com/rbspy/rbspy/commit/24ad81d2439f9e63dd91cc1126ca1bb5d3a4da5b

什么是快照?

我说的 “快照” 是指 “当你运行 git checkout COMMIT_ID 时得到的所有文件”。

Git 通常将提交的文件列表称为 “树”(如“目录树”),你可以在 GitHub 上看到上述提交的所有文件:

https://github.com/rbspy/rbspy/tree/24ad81d2439f9e63dd91cc1126ca1bb5d3a4da5b(它是 /tree/ 而不是 /commit/

“Git 是如何实现的”真的是正确的解释方式吗?

我最常听到的关于学习 Git 的建议大概是 “只要学会 Git 在内部是如何表示事物的,一切都会变得清晰明了”。我显然非常喜欢这种观点(如果你花了一些时间阅读这个博客,你就会知道我 喜欢 思考事物在内部是如何实现的)。

但是作为一个学习 Git 的方法,它并没有我希望的那么成功!通常我会兴奋地开始解释 “好的,所以 Git 提交是一个快照,它有一个指向它的父提交的指针,然后一个分支是一个指向提交的指针,然后……”,但是我试图帮助的人会告诉我,他们并没有真正发现这个解释有多有用,他们仍然不明白。所以我一直在考虑其他方案。

但是让我们还是先谈谈内部实现吧。

Git 是如何在内部表示提交的 —— 快照

在内部,Git 将提交表示为快照(它存储每个文件当前版本的 “树”)。我在 在一个 Git 仓库中,你的文件在哪里? 中写过这个,但下面是一个非常快速的内部格式概述。

这是一个提交的表示方式:

$ git cat-file -p 24ad81d2439f9e63dd91cc1126ca1bb5d3a4da5b
tree e197a79bef523842c91ee06fa19a51446975ec35
parent 26707359cdf0c2db66eb1216bf7ff00eac782f65
author Adam Jensen <[email protected]> 1672104452 -0500
committer Adam Jensen <[email protected]> 1672104890 -0500

Fix typo in expectation message

以及,当我们查看这个树对象时,我们会看到这个提交中仓库根目录下每个文件/子目录的列表:

$ git cat-file -p e197a79bef523842c91ee06fa19a51446975ec35
040000 tree 2fcc102acd27df8f24ddc3867b6756ac554b33ef    .cargo
040000 tree 7714769e97c483edb052ea14e7500735c04713eb    .github
100644 blob ebb410eb8266a8d6fbde8a9ffaf5db54a5fc979a    .gitignore
100644 blob fa1edfb73ce93054fe32d4eb35a5c4bee68c5bf5    ARCHITECTURE.md
100644 blob 9c1883ee31f4fa8b6546a7226754cfc84ada5726    CODE_OF_CONDUCT.md
100644 blob 9fac1017cb65883554f821914fac3fb713008a34    CONTRIBUTORS.md
100644 blob b009175dbcbc186fb8066344c0e899c3104f43e5    Cargo.lock
100644 blob 94b87cd2940697288e4f18530c5933f3110b405b    Cargo.toml

这意味着检出一个 Git 提交总是很快的:对 Git 来说,检出昨天的提交和检出 100 万个提交之前的提交一样容易。Git 永远不需要重新应用 10000 个差异来确定当前状态,因为提交根本就不是以差异的形式存储的。

快照使用 packfile 进行压缩

我刚刚提到了 Git 提交是一个快照,但是,当有人说 “在我看来,提交是一个快照,但我认为它在实现上是一个差异” 时,这其实也是对的!Git 提交并不是以你可能习惯的差异的形式表示的(它们不是以与上一个提交的差异的形式存储在磁盘上的),但基本的直觉是,如果你要对一个 10,000 行的文件编辑 500 次,那么存储 500 份文件的效率会很低。

Git 有一个将文件以差异的形式存储的方法。这被称为 “packfile”,Git 会定期进行垃圾回收,将你的数据压缩成 packfile 以节省磁盘空间。当你 git clone 一个仓库时,Git 也会压缩数据。

这里,我没有足够的篇幅来完整地解释 packfile 是如何工作的(Aditya Mukerjee 的 《解压 Git packfile》是我最喜欢的解释它们是如何工作的文章)。不过,我可以在这里简单总结一下我对 deltas 工作原理的理解,以及它们与 diff 的区别:

  • 对象存储为 “原始文件” 和一个 “ 变化量 delta ” 的引用
  • 变化量是一系列例如 “读取第 0 到 100 字节,然后插入字节 ‘hello there’,然后读取第 120 到 200 字节” 的指令。它从原始文件中拼凑出新的文本。所以没有 “删除” 的概念,只有复制和添加。
  • 我认为变化量的层次较少:我不知道如何检查 Git 究竟要经过多少层变化量才能得到一个给定的对象,但我的印象是通常不会很多。可能少于 10 层?不过,我很想知道如何才能真正查出来。
  • 原始文件不一定来自上一个提交,它可以是任何东西。也许它甚至可以来自一个更晚的提交?我不确定。
  • 没有一个 “正确的” 算法来计算变化量,Git 只是有一些近似的启发式算法

当你查看差异时,实际上发生了一些奇怪的事情

当我们运行 git show SOME_COMMIT 来查看某个提交的差异时,实际上发生的事情有点反直觉。我的理解是:

  1. Git 会在 packfile 中查找并应用变化量来重建该提交和其父提交的树。
  2. Git 会对两个目录树(当前提交的目录树和父提交的目录树)进行差异比较。通常这很快,因为几乎所有的文件都是完全一样的,所以 git 只需比较相同文件的哈希值就可以了,几乎所有时候都不用做什么。
  3. 最后 Git 会展示差异

所以,Git 会将变化量转换为快照,然后计算差异。它感觉有点奇怪,因为它从一个类似差异的东西开始,最终得到另一个类似差异的东西,但是变化量和差异实际上是完全不同的,所以这是说得通的。

也就是说,我认为 Git 将提交存储为快照,而 packfile 只是一个实现细节,目的是节省磁盘空间并加快克隆速度。我其实从来没必要知道 packfile 是如何工作的,但它确实能帮助我理解 Git 是如何在不占用太多磁盘空间的情况下将提交快照化的。

一个 “错误的” Git 理解:提交是差异

我认为一个相当常见的,对 Git 的 “错误” 的理解是:

  • 提交是以基于上一个提交的差异的形式存储的(加上指向父提交的指针和作者和消息)。
  • 要获取提交的当前状态,Git 需要从头开始重新应用所有之前的提交。

这个理解当然是错误的(在现实中,提交是以快照的形式存储的,差异是从这些快照计算出来的),但是对我来说它似乎非常有用而且有意义!在考虑合并提交时会有一点奇怪,但是或许我们可以说这只是基于合并提交的第一个父提交的差异。

我认为这个错误的理解有的时候非常有用,而且对于日常 Git 使用来说它似乎并没有什么问题。我真的很喜欢它将我们最常使用的东西(差异)作为最基本的元素——它对我来说非常直观。

我也一直在思考一些其他有用但 “错误” 的 Git 理解,比如:

  • 提交信息可以被编辑(实际上不能,你只是复制了一个相同的提交然后给了它一个新的信息,旧的提交仍然存在)
  • 提交可以被移动到一个不同的基础上(类似地,它们是被复制了)

我认为有一系列非常有意义的、 “错误” 的对 Git 的理解,它们在很大程度上都受到 Git 用户界面的支持,并且在大多数情况下都不会产生什么问题。但是当你想要撤销一个更改或者出现问题时,它可能会变得混乱。

将提交视为差异的一些优势

就算我知道在 Git 中提交是快照,我可能大部分时间也都将它们视为差异,因为:

  • 大多时候我都在关注我正在做的 更改 —— 如果我只是改变了一行代码,显然我主要是在考虑那一行代码而不是整个代码库的当前状态
  • 点击 GitHub 上的 Git 提交或者使用 git show 时,你会看到差异,所以这只是我习惯看到的东西
  • 我经常使用变基,它就是关于重新应用差异的

将提交视为快照的一些优势

但是我有时也会将提交视为快照,因为:

  • Git 经常对文件的移动感到困惑:有时我移动了一个文件并编辑了它,Git 无法识别它是否被移动过,而是显示为 “删除了 old.py,添加了 new.py”。这是因为 Git 只存储快照,所以当它显示 “移动 old.py -> new.py” 时,只是猜测,因为 old.py 和 new.py 的内容相似。
  • 这种方式更容易理解 git checkout COMMIT_ID 在做什么(重新应用 10000 个提交的想法让我感到很有压力)
  • 合并提交在我看来更像是快照,因为合并的提交实际上可以是任何东西(它只是一个新的快照!)。它帮助我理解为什么在解决合并冲突时可以进行任意更改,以及为什么在解决冲突时要小心。

其他一些关于提交的理解

Mastodon 的一些回复中还提到了:

  • 有关提交的 “额外的” 带外信息,比如电子邮件、GitHub 拉取请求或者你和同事的对话
  • 将“差异”视为一个“之前的状态 + 之后的状态”
  • 以及,当然,很多人根据情况的不同以不同的方式看待提交

人们在谈论提交时使用的其他一些词可能不那么含糊:

  • “修订”(似乎更像是快照)
  • “补丁”(看起来更像是差异)

就到这里吧!

我很难了解人们对 Git 有哪些不同的理解。尤其棘手的是,尽管 “错误” 的理解往往非常有用,但人们却非常热衷于警惕 “错误” 的心智模式,所以人们不愿意分享他们 “错误” 的想法,生怕有什么 Git 解释者会站出来向他们解释为什么他们是错的。(这些 Git 解释者通常是出于善意的,但是无论如何它都会产生一种负面影响)

但是我学到了很多!我仍然不完全清楚该如何谈论提交,但是我们最终会弄清楚的。

感谢 Marco Rogers、Marie Flanagan 以及 Mastodon 上的所有人和我讨论 Git 提交。

(题图:DA/cc0cada9-4945-4248-8635-3f89dcebd6ef)


via: https://jvns.ca/blog/2024/01/05/do-we-think-of-git-commits-as-diffs--snapshots--or-histories/

作者:Julia Evans 选题:lujun9972 译者:Cubik65536 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Linux 中的 free 命令可以帮助你深入了解系统内存(RAM)的使用情况等。下面介绍如何充分利用它。

free 命令是了解系统内存(RAM)消耗情况,以及是否启用了交换的最简单方法之一。

但问题是:如何使用 free 命令? 嗯,这非常简单,不需要任何复杂的步骤。

因此,在本教程中,我将引导你使用 free 命令,并附有示例和练习题供你练习。

Linux 中如何使用 free 命令

要使用 free 或任何其他命令,最好从命令语法开始,我将从相同的开始。

以下是 free 命令的语法:

free [选项]

有多个选项可以使用,以更改 free 命令的默认行为。

现在,让我分享一些 free 命令常用的选项:

选项描述
-h通过调整 KB、GB 等数据单位,以人类可读的形式打印信息。
-s在给定的时间间隔后更新 free 输出。
-t显示系统和交换内存的总量。
-g以 GB 为单位显示数据。
-m以 MB 为单位打印信息。
-k以 KB 为单位显示输出。

但是如果执行不带选项的 free 命令会怎样呢? 你可以看到下面的内容:

这里,

  • total:表示存储总量。
  • used:显示系统已使用的存储空间。
  • free:可用于新进程的可用内存量。
  • shared:tmpfs(临时文件系统)使用的内存量。
  • buff/cache: 表示缓冲区和缓存使用的内存总和。
  • available:它估计有多少内存可用于启动新应用而无需交换。它是free 内存和可以立即使用的 buff/cache 的一部分的总和。

因此,如果你想要各种信息,只需输入不带选项的命令即可。

现在,让我们看一下 free 命令的一些示例。

1、以人类可读的形式显示信息

默认情况下,free 命令将以千字节为单位显示数据,这不是最易读的形式。

这就是 -h 选项发挥作用的地方,它以人类可读的形式(例如 KB 或 GB)打印值。

free -h

2、连续显示统计数据

一旦执行 free 命令,它只会显示执行该命令时的统计信息。例如,如果我在 12:45 执行 free 命令,那么它只会显示该时间的统计信息。

所以问题是:如何实现类似的行为,如显示实时统计数据的 htop?这不完全相同,但你可以使用 -s 标志以特定时间间隔刷新统计信息,如下所示:

free -s <秒>

例如,如果我想每秒刷新一次 free 命令,那么我将使用以下命令:

free -s 1

3、定义显示统计数据的次数

在前面的示例中,我解释了如何使用 free 命令连续显示统计信息,但你可能不希望它无休止地刷新,而只刷新几次。

为此,你可以使用 -c 标志,如下所示:

free -c <显示统计信息的次数>

假设我想查看统计数据 3 次,那么我将使用以下内容:

free -c 3

默认情况下,它将每秒刷新一次数据,但你可以使用 -s 标志来指定间隔时间:

free -c <显示统计数据的次数> -s <秒数>

例如,在这里,如果我想以 2 秒的间隔显示统计信息 3 次,那么我将使用以下命令:

free -c 3 -s 2

4、指定输出数据类型

虽然对于大多数用户来说,使用 -h 标志以人类可读的形式显示数据就可以完成工作,但是如果你想自己指定数据类型怎么办?

那么,你可以使用以下标志指定数据类型:

标志描述
--kilo-k以 KB 为单位显示内存。
--mega-m以 MB 节为单位显示内存。
--giga-g以 GB 为单位显示内存。
--tera以 TB 为单位显示内存。

你可以通过以下方式使用上述标志:

free --<kilo/mega/giga/tera>

例如,如果我希望以 MB 为单位显示内存统计信息,那么我将使用以下命令:

free --mega

5、获取物理内存和交换内存的总和

默认情况下,可用内存将显示物理内存和交换内存的行,但是如果你想获得它们的总和怎么办?

好吧,你可以使用 -t 标志:

free -t

练习题 ?‍?

你可以练习以下一些问题,以更好地使用 free 命令:

  • 连续打印内存统计数据 3 次,中间间隔 3 秒。
  • 以人类可读的形式获取物理内存和交换内存的总和。
  • 重定向 free 命令的输出到文本文件中。
  • 如何从 free 命令的输出中只打印一列? (提示:使用 awk 命令 并指定列号)。

如果你对这些问题有任何疑问,你可以在此处发表评论。

总结

每个命令都会以某种方式派上用场。free 命令也有这样一个被低估的场景来获取有用的信息。

? 我希望你发现本指南有用! 请让我知道你对我接下来应该介绍什么内容的想法?

(题图:DA/07440245-cdb2-43ac-94d9-c4a394ced646)


via: https://itsfoss.com/free-command/

作者:Sagar Sharma 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

不知道在使用哪个初始化系统?以下是方法。

每个主流 Linux 发行版(包括 Ubuntu、Fedora、openSUSE 和 Arch)默认都使用 systemd。

但是有 许多非 systemd 发行版,例如使用轻量级 runit 来获得更好性能的 Void Linux 或主要使用 sysvinit 的 Devuan。

当你尝试遵循某些教程或文档并且其中包含特定于 systemd 或某些其他初始化服务的命令时,就会出现问题。

这时,你必须检查你的 Linux 系统使用的是 systemd 还是其他系统。

一种方法是检查 PID 为 1 的进程(毕竟,初始化系统是 Linux 系统上运行的第一个进程)。

ps 1

但它的输出可能会产生误导,因为它经常显示 /sbin/init,这只是实际的初始化进程的软链接。

如果你 跟随该符号链接,就可以获取初始化系统信息。有两种方法:

  • 使用 stat 命令
  • 使用 readlink 命令

那么让我们从第一个开始。

? 这些方法在 6 个初始化系统中进行了测试:Systemd、OpenRC、SysVinit、Busybox、runit 和 s6。

方法 1:使用 stat 命令检查 systemd 是否正在使用

以下是如何使用 stat 命令来了解你正在使用的初始化系统:

stat /sbin/init

如果你使用的是 systemd 支持的发行版,那么它将显示以下输出:

但是,如果你使用 systemd 之外的其他任何东西,它将显示初始化系统的名称,但是如果你使用的是 SysVinit,它只会显示 init 而不是 sysvinit

SysVinit only displays "init" instead of sysvinit

方法 2:使用 readlink 命令检查初始化系统

与之前的方法不同,当你使用 readlink 命令时,它只会打印初始化系统的名称。

因此,如果你想知道你是否正在使用 Systemd,只需使用以下命令:

readlink /sbin/init

如果你使用 OpenRC 初始化访问,那么它将显示以下输出:

但如果你使用 SysVinit,那么它会显示以下输出:

我为你写的小“脚本”

另一种方法是检查 /run/systemd/system 目录是否存在。

好吧,最简单的找出方法是在终端中 使用 if-else bash 命令,它将检查你是否正在运行由 systemd 驱动的发行版:

if [ -d /run/systemd/system ]; then echo "System is running systemd"; else echo "System is not running systemd"; fi

有关 systemd 的更多信息

当你知道你正在使用 systemd 支持的发行版,你就可以 使用 systemctl 命令管理服务

当然你也可以从头开始 创建一个 systemd 服务

我希望本指南对你有所帮助。

(题图:DA/02d49f79-0ec4-4e49-ae72-e3d46877dfa6)


via: https://itsfoss.com/check-if-systemd/

作者:Sagar Sharma 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出