2023年5月

使用一个简单的计数程序比较古老的 C 语言和现代的 Go 语言。

Go 是一种现代编程语言,它很大程度上源自于 C 编程语言。因此,对于写 C 程序的程序员来说,Go 应该会感觉很熟悉。Go 让编写新程序变得容易,同时让 C 程序员感觉熟悉,但避免了 C 编程语言的许多常见陷阱。

本文比较了一个简单的 C 和 Go 程序,该程序将数字从一相加到十。由于这个程序只使用了小的数值,所以结果不会变得太大,因此只使用了普通的整数变量。像这样的循环在编程中非常常见,所以这个简单的程序很容易比较 C 和 Go。

如何在 C 中执行循环

C 语言中最基本的循环是 for 循环,它允许你对一组值进行迭代。for 循环的基本语法是:

for (起始条件 ; 结束条件 ; 每次迭代后执行的操作) { 循环内要执行的内容 ; }

你可以编写一个 for 循环,以打印从 1 到 10 的数字,将起始条件设置为 count = 1,将结束条件设置为 count <= 10。这样就以 count 变量等于 1 时开始循环。结束条件意味着只要 count 变量小于或等于 10 ,循环就会继续。

每次迭代之后,你使用 count = count + 1count 变量的值增加 1。在循环内部,你可以使用 printf 打印 count 变量的值:

for (count = 1; count <= 10; count = count + 1) {
  printf("%d\n", count);
}

C 程序中常见的惯例是 ++,它表示 “将某个值加一”。如果你写 count++,那就相当于 count = count + 1。大多数 C 程序员会使用 count++ 来编写 for 循环中每次迭代后要执行的操作,像这样:

for (count = 1; count <= 10; count++) {
  printf("%d\n", count);
}

这是一个示例程序,将从 1 到 10 的数字相加,然后打印结果。使用 for 循环对数字进行迭代,但不要打印数字,而是将数字添加到 sum 变量中:

#include <stdio.h>

int main() {
  int sum;
  int count;
  puts("adding 1 to 10 ..");
  sum = 0;

  for (count = 1; count <= 10; count++) {
    sum = sum + count;
  }

这个程序使用了两个不同的 C 函数来向用户打印结果。puts 函数打印引号中的字符串。如果你需要打印纯文本,使用 puts 是个不错的选择。

printf 函数 使用特殊字符在格式字符串中打印格式化的输出。printf 函数可以打印许多不同种类的值。关键字 %d 打印十进制(整数)值。

如果你编译并运行这个程序,你会看到这个输出:

adding 1 to 10 ..
The sum is 55

如何在 Go 中执行循环

Go 提供了与 C 中非常相似的 for 循环。C 程序中的 for 循环可以直接转换为 Go 的 for 循环,并具有相似的表示形式:

for count = 1; count <= 10; count++ {
  fmt.Printf("%d\n", count)
}

使用这个循环,你可以直接转换为 Go 的示例程序:

package main
import "fmt"

func main() {
  var sum, count int
  fmt.Println("adding 1 to 10 ..")

  for count = 1; count <= 10; count++ {
    sum = sum + count
  }
  fmt.Printf("The sum is %d\n", sum)
}

虽然上述方式在 Go 中是正确的,但它并不是最常用的 Go 写法。采用惯例是“使用与本地语言为人所知的表达方式”。任何语言的目标都是高效的沟通,编程语言也不例外。在不同的编程语言之间进行转换时,重要的是意识到尽管物似而意不同,一种编程语言中的典型写法在另一种编程语言中可能不完全相同。

为使用更符合惯例的 Go,你可以进行几个小修改:

  • 通过使用 += 操作符来将 sum = sum + count 更简洁地表达为 sum += count
  • 通过使用 分配并推断类型运算符 来表达 count := 1 而不是 var count int 跟着 count = 1:= 语法同时定义并初始化 count 变量。
  • count 的声明移到 for 循环的头中。这减少了一些认知负担,也通过减少程序员在任何时候都必须心里记着的变量数目来提高可读性。这个更改还通过在最接近其使用的地方和最小的范围中声明变量来增加安全性,从而减少了在代码不断演进的过程中对变量进行意外操作的可能性。

上述改动的组合将产生以下代码:

package main
import "fmt"

func main() {
  fmt.Println("adding 1 to 10 ..")
  var sum int
  for count := 1; count <= 10; count++ {
    sum += count
  }

  fmt.Printf("The sum is %d\n", sum)
}

你可以使用这个 Go.dev 的 链接 在 Go 试验场中尝试这个示例程序。

C 和 Go 相似但不同

通过在两种编程语言中编写相同的程序,你可以看到 C 和 Go 这两种语言虽然相似但仍然不同。将从 C 转换到 Go 时需要注意以下几点:

  • 在 C 中,每个程序指令都必须以分号结尾。这告诉编译器一个语句在哪里结束,下一个在哪里开始。在 Go 中,分号是有效的,但几乎总是可以推断出来。
  • 虽然大多数现代 C 编译器会为你将变量初始化为零值,但 C 语言规范指出,变量得到的是内存中的任意值。Go 值总是初始化为其零值。这有助于使 Go 成为一种更具内存安全的语言。这种差异在使用指针时变得更加有趣。
  • 注意 Go 程序包对导入标识符的使用方式。例如,fmt 是一个实现格式化输入和输出的函数,类似于 C 中的 stdio.h 中的 printfscanffmt 程序包在 pkg.go.dev/fmt 中有文档描述。
  • 在 Go 中,main 函数总是以退出代码 0 返回。如果你希望返回其他值,你必须调用 os.Exit(n),其中 n 通常为 1 以表示错误。这可以从任何地方调用,不仅仅是 main 函数,来终止程序。你可以在 C 中使用在 stdlib.h 中定义的 exit(n) 函数来实现相同的效果。

(题图:MJ/8f731484-2dc3-4bac-b895-cbc92a63b48b)


via: https://opensource.com/article/23/4/c-vs-go-programming-languages

作者:Jim Hall 选题:lkxed 译者:ChatGPT 校对:wxy

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

在 Rust 系列的第四篇中,学习复合数据类型、数组和元组。

在上一篇文章中,你学习到了 Rust 中的 标量数据类型。它们是整型、浮点数、字符和布尔值。

在本文中,我们将会看看 Rust 编程语言中的复合数据类型。

Rust 中的复合数据类型是什么?

复合数据类型可以在一个变量中存储多个值。这些值可以是相同的标量数据类型,也可以是不同的标量数据类型。

Rust 编程语言中有两种这样的数据类型:

  • 数组 Array :存储相同类型的多个值。
  • 元组 Tuple :存储多个值,可以是相同的类型,也可以是不同的类型。

让我们了解一下它们吧!

Rust 中的数组

Rust 编程语言中的数组具有以下特性:

  • 每一个元素都必须是相同的类型
  • 数组有一个固定的长度
  • 数组存储在堆栈中,即其中存储的数据可以被 迅速 访问

创建数组的语法如下:

// 无类型声明
let variable_name = [element1, element2, ..., elementn];

// 有类型声明
let variable_name: [data_type; array_length] = [element1, element2, ..., elementn];

数组中的元素是在方括号中声明的。要访问数组的元素,需要在方括号中指定要访问的索引。

来让我们看一个例子来更好地理解这个。

fn main() {
    // 无类型声明
    let greeting = ['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'];

    // 有类型声明
    let pi: [i32; 10] = [1, 4, 1, 5, 9, 2, 6, 5, 3, 5];

    for character in greeting {
        print!("{}", character);
    }

    println!("\nPi: 3.1{}{}{}{}", pi[0], pi[1], pi[2], pi[3]);
}

这里,我定义了一个字符数组和另一个存储 i32 类型的值的数组。greeting 数组以单独字符的形式存储了字符串 "Hello world!" 的字符。pi 数组以单独数字的形式存储了圆周率小数点后的前 10 位数字。

然后,我使用 for 循环打印了 greeting 数组的每个字符。(我很快就会讲到循环。)然后,我打印了 pi 数组的前 4 个值。

Hello world!
Pi: 3.11415

如果你想创建一个数组,其中每个元素都是 y,并且出现 x 次,你可以使用以下快捷方式在 Rust 中实现:

let variable_name = [y; x];

来看一个演示……

fn main() {
    let a = [10; 5];

    for i in a {
        print!("{i} ");
    }
    println!("");
}

我创建了一个变量 a,它的长度为 5。数组中的每个元素都是 '10'。我通过使用 for 循环打印数组的每个元素来验证这一点。

它的输出如下:

10 10 10 10 10
? 作为练习,尝试创建一个长度为 x 的数组,然后尝试访问数组的第 x+1 个元素。看看会发生什么。

Rust 中的元组

Rust 中的元组具有以下特性:

  • 就像数组一样,元组的长度是固定的
  • 元素可以是相同的/不同的标量数据类型
  • 元组存储在堆栈中,所以访问速度更快

创建元组的语法如下:

// 无类型声明
let variable_name = (element1, element2, ..., element3);

// 有类型声明
let variable_name: (data_type, ..., data_type) = (element1, element2, ..., element3);

元组的元素写在圆括号中。要访问元素,使用点运算符,后跟该元素的索引。

fn main() {
    let a = (38, 923.329, true);
    let b: (char, i32, f64, bool) = ('r', 43, 3.14, false);

    println!("a.0: {}, a.1: {}, a.2: {}", a.0, a.1, a.2);
    println!("b.0: {}, b.1: {}, b.2: {}, b.3: {}", b.0, b.1, b.2, b.3);

    // 元组解构
    let pixel = (50, 0, 200);
    let (red, green, blue) = pixel;
    println!("red: {}, green: {}, blue: {}", red, green, blue);
}

在上面的代码中,我在第 2 行和第 3 行声明了两个元组。它们只包含我当时想到的随机值。但是仔细看,两个元组中每个元素的数据类型都不同。然后,在第 5 行和第 6 行,我打印了两个元组的每个元素。

在第 9 行,我声明了一个名为 pixel 的元组,它有 3 个元素。每个元素都是组成像素的颜色红色、绿色和蓝色的亮度值。这个范围是从 0 到 255。所以,理想情况下,我会声明类型为 (u8, u8, u8),但是在学习代码时不需要这样优化 ; )

然后,在第 10 行,我“解构”了 pixel 元组的每个值,并将其存储在单独的变量 redgreenblue 中。然后,我打印了 redgreenblue 变量的值,而不是 pixel 元组的值。

让我们看看输出……

a.0: 38, a.1: 923.329, a.2: true
b.0: r, b.1: 43, b.2: 3.14, b.3: false
red: 50, green: 0, blue: 200

看起来不错 : )

额外内容:切片

准确的来说, 切片 Slice 不是 Rust 中的复合数据类型。相反,切片是现有复合数据类型的 “切片”。

一个切片由三个元素组成:

  • 一个初始索引
  • 切片运算符(....=
  • 一个结束索引

接下来是数组切片的一个示例:

fn main() {
    let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let my_slice = &my_array[0..4];

    for element in my_slice {
        println!("{element}");
    }
}

就像 C 和 C++ 一样,& 用于存储变量的引用(而不是原始指针)。所以 &my_array 意味着对变量 my_array 的引用。

然后,来看看切片。切片由 [0..4] 表示。这里,0 是切片开始的索引。而 4 是切片结束的索引。这里的 4 是一个非包含索引。

这是程序输出,以更好地理解正在发生的事情:

0
1
2
3

如果你想要一个 包含 范围,你可以使用 ..= 作为包含范围的切片运算符。

fn main() {
    let my_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    let my_slice = &my_array[0..=4];

    for element in my_slice {
        println!("{element}");
    }
}

现在,这个范围是从第 0 个元素到第 4 个元素,下面是输出来证明这一点:

0
1
2
3
4

总结

本文讲到了 Rust 编程语言中的复合数据类型。你学习了如何声明和访问存储在数组和元组类型中的值。此外,你还了解了切片“类型”,以及如何解构元组。

在下一章中,你将学习如何在 Rust 程序中使用函数。敬请关注。

(题图:MJ/22a0d143-2216-439f-8e1d-abd94cdfdbd0)


via: https://itsfoss.com/rust-arrays-tuples/

作者:Pratham Patel 选题:lkxed 译者:Cubik65536 校对:wxy

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

澳证交所宣告用区块链改造其核心交易系统失败

澳大利亚证券交易所(ASX)在 2017 年曾宣布用基于区块链的替代品取代其核心交易系统 CHESS,但一直到 2022 年都 未曾完工,并在去年 11 月 “暂停” 了该工作,因为外部审查发现该软件在开发了七年后必须进行大量的返工。ASX 表示它正在考虑再次尝试重建这个有 30 年历史的软件的方案,但不会涉及区块链或相关的分布式账本技术。

消息来源:路透社
老王点评:这原本是世界上最引人注目的概念用例之一。在区块链技术被热捧时,似乎什么都应该用区块链来重新写一下。当热潮退去,另外一个热潮来临时,一切都打回了原形。但是我依然认为区块链有其价值,在褪去那些炫目的光环后,它本质的东西才能剩下。

英特尔研究开发仅支持 64 位的 x86S 架构

自 Windows 7 以来,大部分 PC 用户运行的 Windows 操作系统都是 64 位,搭载的内存也超过了 4GB,64 位应用和游戏都逐渐成为了主流。对英特尔而言,简化 x86 指令集架构,只支持 64 位显然有诸多好处。英特尔发表了一份白皮书,探索了仅 64 位的 x86S 架构。在新的架构中,用 64 位的简化分段模型分段支持 32 位应用,移除了 16 位寻址支持。64 位的 x86S 芯片仍然支持 32 位应用,但不再支持 32 位操作系统。

消息来源:英特尔
老王点评:是时候考虑全面转向 64 位了,就像当时从 8 位、16 位升级到 32 位一样。抛掉历史包袱,显然更好。虽然这一天来的不算早,但是依然有点意外。

大量恶意项目导致 PyPi 暂停新注册两天

上周六,官方的 Python 软件包第三方注册机构 PyPI “暂时停止了新用户的注册和新项目的上传”。PyPI 称,在过去的一周里,在其上创建的恶意用户和恶意项目的数量已经超过了应对能力,“特别是在多个 PyPI 管理员休假的情况下”。现在,PyPI 表示“暂停服务已被解除”,但没有提供更多细节。

消息来源:Bleeping Computer
老王点评:在第三方软件库越来越成为基础设施的重要一环时,其承担了太多原本没有预料的压力。也许是该考虑在新的形势下,如何改进已经用了数十年的第三方中心化的软件库的机制、架构和流程了。

一个灵巧的剪贴板管理器,提供视觉丰富的界面和有价值的选项。

pano clipboard manager

你知道,有一种比 Ctrl+C/Ctrl-V 更好的方法来处理剪贴板文本。不,我不是在谈论使用右键单击菜单。

我是指使用一个合适的剪贴板管理器。而且,不仅仅是一个普通的剪贴板管理器,而是一个非常有用的东西。如果你喜欢,我相信它将成为 Linux 上必不可少的应用程序 之一。

认识 Pano 剪贴板管理器。让我告诉你它能做什么。

Pano 剪贴板管理器:概述 ⭐

a screenshot of how pano looks on gnome

Pano 是一个易于使用且高度可定制的剪贴板应用,它在一个非常紧凑的包中提供了一些很好的实用程序(以 GNOME 扩展的形式)。

它可以让你存储任何东西,从文本和表情符号,一直到颜色。

正如你在上面看到的,复制的内容根据其类型进行分类,并在界面中整齐排列。

除此之外,当你复制某些内容时,它会显示一个漂亮的通知,其中包含复制内容的简短预览。

a screenshot showing the notification feature of pano

该扩展最近进行了更新,进行了全面的视觉改造,并重新设计了托盘图标、占位符图像等。

你现在可以在配置菜单中调整 Pano 的高度,以及自定义背景颜色和不透明度、调整内容类型、字体大小等。

pano customization options

但是,当我的同事 Shivam 试用 Pano 时,他发现它还会将密码从 Bitwarden 复制到剪贴板。

我必须说,这是 Pano 的一个失误。它应该有排除特定应用的选项,如密码管理器。尽管如此,你应该是安全的,因为它没有云同步连接。

除此之外,这里有一些快捷方式可以在使用 Pano 时派上用场:

  • 使用 super+shift+V 来切换 Pano。
  • 使用 ctrl+super+shift+V 来进入隐身模式,以处理那些隐私剪贴板文本。
  • 使用 箭头键在项目之间导航。
  • 使用 箭头键将焦点放在搜索框和项目上。
  • 使用 Ctrl+S 将处于输入焦点的项目添加到收藏夹。

对于更多这样的快捷方式,你可以参考它的 GitHub 仓库

让我们继续。

Linux 和 GNOME 有类似的应用可以提供此类功能,比如 CopyQ

但 Pano 提供的功能有点不同,尤其是在如此紧凑的包中。

? 获取 Pano 剪贴板管理器

你可以从 Gnome 扩展网站 获取 Pano,或单击下面的下载按钮获取它:

Pano 剪贴板管理器

请记住,它需要两个依赖项,libgdagsound 才能工作,这可以使用以下命令完成:

sudo apt install gir1.2-gda-5.0 gir1.2-gsound-1.0

你还可以参考我们关于 使用 GNOME 扩展 的指南来启用它。


via: https://news.itsfoss.com/pano-clipboard-manager/

作者:Sourav Rudra 选题:lkxed 译者:geekpi 校对:wxy

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

学习如何在 Ubuntu 中正确安装 Qemu,然后在虚拟机中配置 Linux 发行版。

如果你需要运行 Linux 虚拟机,Qemu 是目前最快的管理程序之一,甚至没有“之一”。

除了速度之外,你还可以获得出色的配置选项。即使你不是一个资深用户,它也给你足够的调整空间。

在本教程中,我将引导你完成:

  • 在 Ubuntu 上安装 Qemu 和 KVM
  • 在 Qemu 上安装另一个发行版
  • 在 Qemu 中启用共享文件夹、自动调整大小和复制粘贴(可选,但会使你的虚拟机体验更顺畅)。

那么让我们从安装开始吧。

在 Ubuntu 上安装 Qemu 和 KVM

✋ 在开始安装之前,让我们检查一下你的机器是否支持虚拟化。

要做到这一点,请使用以下命令:

LC_ALL=C lscpu | grep Virtualization

如果你有一个英特尔处理器,它应该带来以下输出:

检查该计算机是否支持基于硬件的虚拟化

如果你有一个 AMD 处理器,它应该得到以下输出:

Virtualization:                  AMD-V

另外,确保你的系统有多个处理器核心,这样你可以分配一些给你的虚拟机,并且仍然有足够的处理能力提供给宿主机。

如果你不确定,使用下面的命令,输出应该大于零

egrep -c '(vmx|svm)' /proc/cpuinfo

检查 Linux 中系统的核心总数和线程数

一旦你都准备好了,你就可以用以下命令在 Ubuntu 上安装 Qemu 和 KVM:

sudo apt install qemu qemu-kvm virt-manager bridge-utils

安装结束后,重新启动你的系统

将用户添加到适当的组中

为了使 Qemu 工作,你必须 将你的用户加入两个组libvirt-kvmlibvirt

要做到这一点,请逐一使用以下命令:

sudo useradd -g $USER libvirt
sudo useradd -g $USER libvirt-kvm

接下来,启用并启动 libvirt 服务:

sudo systemctl enable libvirtd.service && sudo systemctl start libvirtd.service

这就行了!Qemu 的安装已经完成。

用 Qemu 安装另一个 Linux 虚拟机

? 请下载你想在 Qemu 虚拟机中安装的 Linux 发行版的 ISO 文件。

首先,从系统菜单中打开 虚拟机管理器 Virtual Machine Manager

从系统菜单中启动 Qemu

接下来,点击 “ 文件 File ” 菜单,选择 “ 新建虚拟机 New Virtual Machine ” 选项:

在 Qemu 中创建新的虚拟机

从这里,选择第一个选项 “ 本地安装介质 Local install media ”,这将允许你从文件管理器中选择 ISO:

选择本地 ISO 文件以在 Qemu 中创建新的虚拟机

接下来,你将被要求添加 ISO 文件。在这里,点击 “ 浏览 Browse ” 按钮;它将打开一个新的提示窗口,在那里,点击 “ 浏览本地 Browse Local ”。

它将打开文件管理器,从那里选择 ISO 文件:

在 Qemu 中导入 ISO 文件

在大多数情况下,ISO 文件会被检测到,但如果你发现它没有自动检测到,请按照以下步骤操作:

  • 取消勾选 “ 自动从安装介质/源检测 Automatically detect from the installtion media / source ” 选项
  • 选择 “ 常见的 Linux Generic Linux ” 选项

解决 Qemu 中未检测到 ISO 的问题

接下来,你将被要求根据你的需要分配内存和存储。我建议桌面版至少要有 2 个核心、4GB 内存和 25GB 的存储空间:

在 Qemu 中为虚拟机分配内存、内核和存储空间

? 除了磁盘空间,CPU 和内存等系统资源只在 VM 中运行操作系统时使用。

最后,给你的虚拟机起一个合适的名字;完成后,点击 “ 完成 Finish ” 按钮:

在 Qemu 中命名你的虚拟机

它将加载 ISO,所以你可以从这里开始安装。

这就完成了。你可能会觉得这已经很不错了,但如果你启用共享文件夹、剪贴板共享等,你会更喜欢它。下面的几节将介绍如何做到这一点。

在 Qemu 中启用共享文件夹(可选)

在本节中,我将向你展示如何将宿主机的现有目录与虚拟机共享。

要做到这一点,你必须执行以下步骤:

  • 通过 Qemu 中的虚拟机设置添加一个共享文件系统
  • 在虚拟机中挂载文件系统

因此,首先从系统菜单中打开虚拟机管理器,选择虚拟机,并点击 “ 打开 Open ” 按钮来管理控制台:

打开 Qemu 中虚拟机的设置

现在,点击 “ 信息 Info ” 按钮,选择 “ 内存 Memory ” 并启用共享内存:

在 Qemu 中启用共享内存

接下来,点击 “ 添加硬件 Add Hardware ” 按钮,选择 “ 文件系统 Filesystem ” 选项。

在这里,你必须做以下工作:

  • 在 “ 源路径 Source Path ” 部分添加一个你想共享的目录的路径
  • 在 “ 目标路径 Target Path ” 部分添加该目录的名称

在 Qemu 中创建共享文件夹

完成后,点击 “ 完成 Finish ” 按钮,启动虚拟机。

在虚拟机中,打开终端,使用下面的语法来挂载共享目录:

sudo mount -t virtiofs sharename path/to/shared/directory

在我的例子中,它是 Downloads 目录,所以我将使用下面的方式:

sudo mount -t virtiofs Downloads /home/sagar/Downloads

在 Qemu 中挂载共享文件夹

这就行了。

但这是一个临时的解决方案。

要使它成为永久性的,你必须在虚拟机的 /etc/fstab 中创建一个条目。

要这样做,首先,用下面的方法打开 /etc/fstab 配置文件:

sudo nano /etc/fstab

按下Alt + /在 nano 文本编辑器中转到文件的末尾 ,并使用以下语法创建一个条目:

sharename path/to/shared/directory virtiofs defaults 0 0

这是我的配置,看起来像这样:

使 Qemu 中的共享文件夹永久化

一旦完成,保存更改并退出 nano 文本编辑器。

这里我展示了我是如何在主机上的 Downloads 目录下创建一个新文件,并且这些变化反映在我的虚拟机上:

在 Qemu 中使用共享文件夹

因此,现在你可以使用这个共享文件夹在主机和虚拟机之间传输文件,没有任何问题了!

在 Qemu 中启用共享剪贴板(可选)

要启用共享剪贴板,你所要做的就是在虚拟机中安装 spice-vdagent 工具。

因此,如果你的虚拟机是基于 Ubuntu/Debian 的,你可以使用以下方法:

sudo apt install spice-vdagent

对于基于 Arch 的发行版:

sudo pacman -S spice-vdagent

对于基于 Fedora 的发行版:

sudo yum install spice-vdagent

一旦你完成了安装,重启你的虚拟机,剪贴板应该可以如期工作了。

在 Qemu 中启用自动调整大小(可选)

自动调整大小的功能没什么,但当你调整虚拟机窗口的大小时,虚拟机的显示会立即适应大小的变化:

Qemu 中的自动调整大小

要启用 Qemu 中的自动调整大小功能,你必须遵循 2 个简单的步骤:

  • 点击 “ 视图 View ”(从顶部菜单栏)。
  • 选择 “ 缩放显示 Scale Display ” 并选择 “ 总是 Always ” 选项。

这就是我这边看到的情况了。

想要使用 Qemu 的即插即用版本?

在本教程中,我介绍了如何在 Qemu 中手动安装虚拟机,但如果我告诉你,你可以自动完成整个过程,如分配存储空间、内存等步骤呢?

是的,它提供了同样的效率,但当你想尽快创建一个新的虚拟机时,它就会派上用场!这个工具叫 Quickgui,我们有一个专门的安装教程:

用基于 Qemu 的 Quickgui 轻松地创建虚拟机

我希望你会发现这个指南对你有帮助。如果你有任何疑问,欢迎在评论中提问。

(题图:MJ/b3c4d5b2-e727-4b70-9bb8-e864941eef9a)


via: https://itsfoss.com/qemu-ubuntu/

作者:Sagar Sharma 选题:lkxed 译者:wxy 校对:wxy

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

拥有最多电子支付的国家是印度

据《经济学人》报道,谷歌首席执行官 Sundar Pichai 惊叹于印度在统一支付接口(UPI)方面取得的成就,称它“在 2022 年处理了超过 1 万亿美元的交易,相当于印度 GDP 的三分之一”。根据数据,UPI 从 2019 年的 310 亿次数字交易中增长到了 2022 年的 884 亿次交易。印度总理夸口说,“印度在实时数字支付方面领先于世界,几乎占所有此类交易的 40%”。管理 UPI 平台的印度国家支付公司的 CEO 认为,“与中国的支付宝不同,它是开放的,因此用户不会被锁定在一家公司,可以将他们的财务记录带到竞争对手那里”。

消息来源:《经济学人》
老王点评:我原以为中国才是拥有最多电子支付的国家,这个报道实在是令我惊讶 —— 如果印度没有吹牛的话。不过,至少有一点 UPI 的优点是值得重视的,就是它没有被绑定在某一家公司里面。而抛开聚合支付商不说,现在你往往需要扫两张码之一,或者,只有一张码可选。

惠普禁止使用第三方墨盒的固件更新导致打印机瘫痪

惠普打印机最近发布固件更新,以“阻止客户使用除装有惠普芯片的墨盒外的任何其他墨盒,这些墨盒通常比较昂贵。如果客户试图使用非惠普墨盒,打印机将拒绝打印”。惠普为这一“功能”辩护,称为了“确保最佳的客户打印体验,并保护客户免受不包含惠普原始安全芯片和侵犯惠普知识产权的假冒和第三方墨盒的影响”。不但如此,这一固件本身存在缺陷,导致一些 OfficeJet 打印机瘫痪,这些打印机的触摸屏上将显示一个带有错误代码的蓝色屏幕。更不幸的是,似乎没有办法让客户自己修复,唯一办法是把坏掉的打印机送回该公司进行维修。

消息来源:Bleeping Computer
老王点评:这实在太糟糕了。

谷歌批评 Meta 开源 AI LLaMA 的做法

谷歌和 OpenAI 都没有公开其最新的大模型,并对 Meta 开源了其大语言模型 LLaMA 表示了批评,称“没有约束的开源方法是危险的”,可能会导致被滥用。Meta AI 首席科学家 Yann LeCun 表示,谷歌和 OpenAI 对 AI 保密的做法是一个巨大的错误,除非 AI 不受谷歌等大科技公司的控制,否则消费者和政府将拒绝拥抱 AI。他相信一个最有活力的生态系统必须是开放的,人人都可以做贡献。

消息来源:纽约时报
老王点评:历史已经一再证明,开放将胜过封闭。虽然 Meta 近些年屡有昏招,但是这次在 AI 上“掀桌式开源”,其带来的影响之大和深远,我觉得甚至能与 ChatGPT 问世相比。