2020年10月

通过将日历应用集成到 Ansible 中,确保你的自动化工作流计划不会与其他东西冲突。

“随时”是执行自动化工作流的好时机吗?出于不同的原因,答案可能是否定的。

如果要避免同时进行更改,以最大限度地减少对关键业务流程的影响,并降低意外服务中断的风险,则在你的自动化运行的同时,其他任何人都不应该试图进行更改。

在某些情况下,可能存在一个正在进行的计划维护窗口。或者,可能有大型事件即将来临、一个关键的业务时间、或者假期(你或许不想在星期五晚上进行更改)。

 title=

无论出于什么原因,你都希望将此信息发送到你的自动化平台,以防止在特定时间段内执行周期性或临时任务。用变更管理的行话,我说的是当变更活动不应该发生时,指定封锁窗口。

Ansible 中的日历集成

如何在 Ansible 中实现这个功能?虽然它本身没有日历功能,但 Ansible 的可扩展性将允许它与任何具有 API 的日历应用集成。

目标是这样的:在执行任何自动化或变更活动之前,你要执行一个 pre-task ,它会检查日历中是否已经安排了某些事情(目前或最近),并确认你没有在一个阻塞的时间段中。

想象一下,你有一个名为 calendar 的虚构模块,它可以连接到一个远程日历,比如 Google 日历,以确定你指定的时间是否已经以其他方式被标记为繁忙。你可以写一个类似这样的剧本:

- name: Check if timeslot is taken
  calendar:
    time: "{{ ansible_date_time.iso8601 }}"
  register: output

Ansible 实际会给出 ansible_date_time,将其传递给 calendar 模块,以验证时间的可用性,以便它可以注册响应 (output),用于后续任务。

如果你的日历是这样的:

 title=

那么这个任务的输出就会指明这个时间段被占用的事实 (busy: true):

ok: [localhost] => {
   "output": {
       "busy": true,
       "changed": false,
       "failed": false,
       "msg": "The timeslot 2020-09-02T17:53:43Z is busy: true"
   }
}

阻止任务运行

接下来,Ansible Conditionals 将帮助阻止所有之后任务的执行。一个简单的例子,你可以在下一个任务上使用 when 语句来强制它只有当上一个输出中的 busy 字段不是 true 时,它才会运行:

tasks:
  - shell: echo "Run this only when not busy!"
    when: not output.busy

总结

上一篇文章中,我说过 Ansible 是一个将事物连接在一起的框架,将不同的组成部分相互连接,以协调端到端自动化工作流。

这篇文章探讨了 Ansible 剧本如何与日历应用集成以检查可用性。然而,我只做了一些表面工作!例如,你的任务也可以阻止日历中的一个时间段,这里的发挥空间很大。

在我的下一篇文章中,我将深入 calendar 模块是如何构建的,以及其他编程语言如何与 Ansible 一起使用。如果你和我一样是 Go 的粉丝,请继续关注!


这篇文章最初发表在 Medium 上,名为 Ansible and Google Calendar integration for change management,采用 CC BY-SA 4.0 许可,经许可后转载。


via: https://opensource.com/article/20/10/calendar-ansible

作者:Nicolas Leiva 选题:lujun9972 译者:geekpi 校对:wxy

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

本文是该系列的第九篇,也是最后一篇。

在这篇文章中,我们将对 对话 conversation 页面进行编码。此页面是两个用户之间的聊天室。在顶部我们将显示其他参与者的信息,下面接着的是最新消息列表,以及底部的消息表单。

聊天标题

让我们从创建 static/pages/conversation-page.js 文件开始,它包含以下内容:

import http from '../http.js'
import { navigate } from '../router.js'
import { avatar, escapeHTML } from '../shared.js'

export default async function conversationPage(conversationID) {
    let conversation
    try {
        conversation = await getConversation(conversationID)
    } catch (err) {
        alert(err.message)
        navigate('/', true)
        return
    }

    const template = document.createElement('template')
    template.innerHTML = `
 <div>
 <a href="/">← Back</a>
 ${avatar(conversation.otherParticipant)}
 <span>${conversation.otherParticipant.username}</span>
 </div>
 <!-- message list here -->
 <!-- message form here -->
 `
    const page = template.content
    return page
}

function getConversation(id) {
    return http.get('/api/conversations/' + id)
}

此页面接收路由从 URL 中提取的会话 ID。

首先,它向 /api/ conversations/{conversationID} 发起一个 GET 请求,以获取有关对话的信息。 如果出现错误,我们会将其显示,并重定向回 /。然后我们呈现有关其他参与者的信息。

对话列表

我们也会获取最新的消息并显示它们。

let conversation, messages
try {
    [conversation, messages] = await Promise.all([
        getConversation(conversationID),
        getMessages(conversationID),
    ])
}

更新 conversationPage() 函数以获取消息。我们使用 Promise.all() 同时执行这两个请求。

function getMessages(conversationID) {
    return http.get(`/api/conversations/${conversationID}/messages`)
}

发起对 /api/conversations/{conversationID}/messages 的 GET 请求可以获取对话中的最新消息。

<ol id="messages"></ol>

现在,将该列表添加到标记中。

const messagesOList = page.getElementById('messages')
for (const message of messages.reverse()) {
    messagesOList.appendChild(renderMessage(message))
}

这样我们就可以将消息附加到列表中了。我们以时间倒序来显示它们。

function renderMessage(message) {
    const messageContent = escapeHTML(message.content)
    const messageDate = new Date(message.createdAt).toLocaleString()

    const li = document.createElement('li')
    if (message.mine) {
        li.classList.add('owned')
    }
    li.innerHTML = `
 <p>${messageContent}</p>
 <time>${messageDate}</time>
 `
    return li
}

每个消息条目显示消息内容本身及其时间戳。使用 .mine,我们可以将不同的 css 类附加到条目,这样您就可以将消息显示在右侧。

消息表单

<form id="message-form">
    <input type="text" placeholder="Type something" maxlength="480" required>
    <button>Send</button>
</form>

将该表单添加到当前标记中。

page.getElementById('message-form').onsubmit = messageSubmitter(conversationID)

将事件监听器附加到 “submit” 事件。

function messageSubmitter(conversationID) {
    return async ev => {
        ev.preventDefault()

        const form = ev.currentTarget
        const input = form.querySelector('input')
        const submitButton = form.querySelector('button')

        input.disabled = true
        submitButton.disabled = true

        try {
            const message = await createMessage(input.value, conversationID)
            input.value = ''
            const messagesOList = document.getElementById('messages')
            if (messagesOList === null) {
                return
            }

            messagesOList.appendChild(renderMessage(message))
        } catch (err) {
            if (err.statusCode === 422) {
                input.setCustomValidity(err.body.errors.content)
            } else {
                alert(err.message)
            }
        } finally {
            input.disabled = false
            submitButton.disabled = false

            setTimeout(() => {
                input.focus()
            }, 0)
        }
    }
}

function createMessage(content, conversationID) {
    return http.post(`/api/conversations/${conversationID}/messages`, { content })
}

我们利用 partial application 在 “submit” 事件处理程序中获取对话 ID。它 从输入中获取消息内容,并用它对 /api/conversations/{conversationID}/messages 发出 POST 请求。 然后将新创建的消息添加到列表中。

消息订阅

为了实现实时,我们还将订阅此页面中的消息流。

page.addEventListener('disconnect', subscribeToMessages(messageArriver(conversationID)))

将该行添加到 conversationPage() 函数中。

function subscribeToMessages(cb) {
    return http.subscribe('/api/messages', cb)
}

function messageArriver(conversationID) {
    return message => {
        if (message.conversationID !== conversationID) {
            return
        }

        const messagesOList = document.getElementById('messages')
        if (messagesOList === null) {
            return

        }
        messagesOList.appendChild(renderMessage(message))
        readMessages(message.conversationID)
    }
}

function readMessages(conversationID) {
    return http.post(`/api/conversations/${conversationID}/read\_messages`)
}

在这里我们仍然使用这个应用的部分来获取会话 ID。 当新消息到达时,我们首先检查它是否来自此对话。如果是,我们会将消息条目预先添加到列表中,并向 /api/conversations/{conversationID}/read_messages 发起 POST 一个请求,以更新参与者上次阅读消息的时间。


本系列到此结束。 消息应用现在可以运行了。


via: https://nicolasparada.netlify.com/posts/go-messenger-conversation-page/

作者:Nicolás Parada 选题:lujun9972 译者:gxlct008 校对:wxy

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

我们将所有的 C 语言要素放置到一份易读的备忘录上。

1972 年, 丹尼斯·里奇 Dennis Ritchie 任职于 贝尔实验室 Bell Labs ,在几年前,他和他的团队成员发明了 Unix 。在创建了一个经久不衰的操作系统(至今仍在使用)之后,他需要一种好的方法来对这些 Unix 计算机编程,以便它们可用执行新的任务。在现在看来,这很奇怪,但在当时,编程语言相对较少,Fortran、Lisp、Algol 以及 B 语言都很流行,但是,对于贝尔实验室的研究员们想要做的事情来说,它们还是远远不够的。丹尼斯·里奇表现出一种后来被称为程序员的主要特征的特质:创造了他自己的解决方案。他称之为 C 语言,并且在近 50 年后,它仍在广泛的使用。

为什么你应该学习 C 语言

今天,有很多语言为程序员提供了比 C 语言更多的特性。最明显的是 C++ 语言,这是一种以相当露骨的方式命名的语言,它构建在 C 语言之上,创建了一种很好的面向对象语言。不过,许多其它语言的存在是有充分理由的。计算机擅长一致的重复,因此任何可预见的东西都可以构建在编程语言中,对程序员来说这意味着更少的工作量。为什么在 C++ 语言中用一行语句就可以将一个 int 转换为一个 long 时(long x = long(n);),还要在 C 语言用两行语句呢?

然而,C 语言在今天仍然有用。

首先,C 语言是一种相当简约和直接的语言。除了编程的基础知识之外,并没有很高级的概念,这很大程度上是因为 C 语言实际上就是现代编程语言的基础之一。例如,C 语言的特性之一是数组,但是它不提供字典(除非你自己写一个)。当你学习 C 语言时,你会学习编程的基础组成部分,它可以帮助你认识到如今的编程语言的改进及其的精心设计。

因为 C 语言是一种最小化的编程语言,你的应用程序很可能会获得性能上的提升,这在其它许多编程语言中是看不到的。当你考虑你的代码可以执行多快的时候,很容易陷入锱铢必较的境地,因此,重要的是要问清楚你是否需要为某一特定任务提供更多的速度。与 Python 或 Java 相比,使用 C 语言,你在每行代码中需要纠结的地方更少。C 语言程序运行很快。这是 Linux 内核使用 C 语言编写的一个很好的理由。

最后,C 语言很容易入门,特别是,如果你正在运行 Linux,就已经能运行 C 语言代码了,因为 Linux 系统包含 GNU C 库(glibc)。为了编写和构建 C 语言程序,你需要做的全部工作就是安装一个编译器,打开一个文本编辑器,开始编码。

开始学习 C 语言

如果你正在运行 Linux ,你可以使用你的软件包管理器安装一个 C 编译器。在 Fedora 或 RHEL 上:

$ sudo dnf install gcc

在 Debian 及其衍生系统上:

$ sudo apt install build-essential

在 macOS 上,你可以 安装 Homebrew ,并使用它来安装 GCC

$ brew install gcc

在 Windows 上, 你可以使用 MinGW 安装一套最小的包含 GCC 的 GNU 实用程序集。

在 Linux 或 macOS 上验证你已经安装的 GCC:

$ gcc --version
gcc (GCC) x.y.z
Copyright (C) 20XX Free Software Foundation, Inc.

在 Windows 上,提供 EXE 文件的完整路径:

PS> C:\MinGW\bin\gcc.exe --version
gcc.exe (MinGW.org GCC Build-2) x.y.z
Copyright (C) 20XX Free Software Foundation, Inc.

C 语法

C 语言不是一种脚本语言。它是一种编译型语言,这意味着它由 C 编译器处理来产生一个二进制可执行文件。这不同于脚本语言(如 Bash)或混合型语言(如 Python)。

在 C 语言中,你可以创建函数来执行你希望做到的任务。默认情况下,执行的是一个名为 main 的函数。

这里是一个使用 C 语言写的简单的 “hello world” 程序:

#include <stdio.h>

int main() {
  printf("Hello world");
  return 0;
}

第一行包含一个被称为 stdio.h(标准输入和输出)的 头文件,它基本上是自由使用的、非常初级的 C 语言代码,你可以在你自己的程序中重复使用它。然后创建了一个由一条基本的输出语句构成的名为 main 的函数。保存这些文本到一个被称为 hello.c 的文件中,然后使用 GCC 编译它:

$ gcc hello.c --output hello

尝试运行你的 C 语言程序:

$ ./hello
Hello world$

返回值

这是 Unix 哲学的一部分,一个函数在执行后“返回”一些东西:在成功时不返回任何东西,在失败时返回其它的一些东西(例如,一个错误信息)。这些返回的内容通常使用数字(确切地说是整数)表示:0 表示没有错误,任何大于 0 的数字都表示一些不成功的状态。

Unix 和 Linux 被设计成在运行成功时保持沉默是很明智的。这是为了让你在执行一系列命令时,假设没有任何错误或警告会妨碍你的工作,从而可以始终为成功执行做准备。类似地,在 C 语言中的函数在设计上也预期不出现错误。

你可以通过一个小的修改,让你的程序看起来是失败的,就可以看到这一点:

include <stdio.h>

int main() {
  printf("Hello world");
  return 1;
}

编译它:

$ gcc hello.c --output failer

现在使用一个内置的 Linux 测试方式来运行它。仅在成功时,&& 操作符才会执行一个命令的第二部分。例如:

$ echo "success" && echo "it worked"
success
it worked

失败时,|| 测试会执行一个命令的第二部分。

$ ls blah || echo "it did not work"
ls: cannot access 'blah': No such file or directory
it did not work

现在,尝试你的程序,在成功时,它返回 0;而是返回 1

$ ./failer && echo "it worked"
String is: hello

这个程序成功地执行了,但是没有触发第二个命令。

变量和类型

在一些语言中,你可以创建变量而不具体指定变量所包含的数据的类型。这些语言如此设计使得解释器需要对一个变量运行一些测试来视图发现变量是什么样的数据类型。例如,var=1 定义了一个整型数,当你创建一个表达式将 var 与某些东西相加时,Python 知道显然它是一个整型数。它同样知道当你连接 helloworld 时,单词 world 是一个字符串。

C 语言不会为你做任何这些识别和调查;你必须自己定义你的变量类型。这里有几种变量类型,包括整型(int),字符型(char),浮点型(float),布尔型(boolean)。

你可能也注意到这里没有字符串类型。与 Python 和 Java 和 Lua 以及其它的编程语言不同,C 语言没有字符串类型,而是将字符串看作一个字符数组。

这里是一些简单的代码,它建立了一个 char 数组变量,然后使用 printf 将数组变量和一段简单的信息打印到你的屏幕上:

#include <stdio.h>

int main() {
   char var[6] = "hello";
   printf("Your string is: %s
",var);
}

你可能会注意到,这个代码示例向一个由五个字母组成的单词提供了六个字符的空间。这是因为在字符串的结尾有处一个隐藏的终止符,它占用了数组中的一个字节。你可以通过编译和执行代码来运行它:

$ gcc hello.c --output hello
$ ./hello
hello

函数

和其它的编程语言一样,C 函数也接受可选的参数。你可以通过定义你希望函数接受的数据类型,来将参数从一个函数传递到另一个函数:

#include <stdio.h>

int printmsg(char a[]) {
   printf("String is: %s
",a);
}

int main() {
   char a[6] = "hello";
   printmsg(a);
   return 0;
}

简单地将一个函数分解为两个函数的这种方法并不是非常有用,但是它演示了默认运行 main 函数以及如何在函数之间传递数据。

条件语句

在真实的编程中,你通常希望你的代码根据数据做出判断。这是使用条件语句完成的,if 语句是其中最基础的一个语句。

为了使这个示例程序更具动态性,你可以包含 string.h 头文件,顾名思义,它包含用于检查字符串的代码。尝试使用来自 string.h 文件中的 strlen 函数测试传递给 printmsg 函数的字符串是否大于 0

#include <stdio.h>
#include <string.h>

int printmsg(char a[]) {
  size_t len = strlen(a);
  if ( len > 0) {
    printf("String is: %s
",a);
  }
}

int main() {
   char a[6] = "hello";
   printmsg(a);
   return 1;
}

正如在这个示例中所实现的,该条件永远都不会是非真的,因为所提供的字符串总是 hello,它的长度总是大于 0。这个不够认真的重新实现的 echo 命令的最后一点要做是接受来自用户的输入。

命令参数

stdio.h 文件包含的代码在每次程序启动时提供了两个参数: 一个是命令中包含多少项的计数(argc),一个是包含每个项的数组(argv)。例如, 假设你发出这个虚构的命令:

$ foo -i bar

argc3argv 的内容是:

  • argv[0] = foo
  • argv[1] = -i
  • argv[2] = bar

你可以修改示例 C 语言程序来以字符串方式接受 argv[2],而不是默认的 hello 吗?

命令式编程语言

C 语言是一种命令式编程语言。它不是面向对象的,也没有类结构。使用 C 语言的经验可以教你很多关于如何处理数据,以及如何更好地管理你的代码运行时生成的数据。多使用 C 语言,你最后能够编写出其它语言(例如 Python 和 Lua)可以使用的库。

想要了解更多关于 C 的知识,你需要使用它。在 /usr/include/ 中查找有用的 C 语言头文件,并且看看你可以做什么小任务来使 C 语言对你有用。在学习的过程中,使用来自 FreeDOS 的 Jim Hall 编写的 C 语言忘备录。它在一张双面纸忘备录上放置了所有的基本要素,所以在你练习时,可以立即访问 C 语言语法的所有要素。


via: https://opensource.com/article/20/8/c-programming-cheat-sheet

作者:Seth Kenlon 选题:lujun9972 译者:robsean 校对:wxy

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

微软不再是 Linux 或开源社区的敌人。不管你信不信,Windows 的制造商现在是一个盟友。我知道这很令人震惊,但完全是事实。多亏了 WSL,Linux 现在已经内置于 Windows 中,而微软也有几款应用可供 Linux 使用。

该公司甚至将一些应用程序也开源了。例如,早在 2019 年,微软就在 GitHub 上发布了 Windows 计算器的源代码。而现在,该计算器应用已经被 Uno Platform 移植到 Linux 上。最重要的是,它的安装超简单,因为它是以 Snap 格式打包的。

“Uno Platform 社区的好人们已经将开源的 Windows 计算器移植到了 Linux 上。而且做得比微软把他们的浏览器带到 Linux 上还快。这个计算器发布在 Snap 商店中,可以马上下载。”Canonical 产品经理 Rhys Davies 解释道。

Davies 进一步解释说:“在 UnoConf 2020 期间,Uno Platform 将他们的支持带到了 Linux。Uno Platform 允许你使用 C# 和 XAML 从单一代码库中构建本地移动、桌面和 WebAssembly 应用程序。你可以使用 Visual Studio 和 Ubuntu 在 WSL 上使用 Uno Platform 构建 Linux 应用程序。你可以在 Snap 商店中抓取它们,然后在从 Linux 桌面到树莓派等各种系统上运行你的应用程序。”

那么,在 Linux 上安装 Windows 计算器有多容易呢?如果你有一个现代的操作系统,内置 Snap 支持,比如 Ubuntu 20.04,你可以从这里的 Snap 商店安装它。喜欢使用命令行吗?只需在终端中输入 snap install uno-calculator 即可。

请注意:如果你的发行版没有原生的 Snap 支持,你可以按照这里的说明进行设置。

当然,你可能想知道为什么你应该在 Linux 上安装 Windows 计算器。嗯……只是因为你可以,当然!但说真的,它实际上是一个设计得非常好的应用程序,你可能会发现它比其他计算器程序更优秀 —— 包括任何预装在你的操作系统上的程序。试试吧,伙计们 —— 你可能会喜欢它。


via: https://betanews.com/2020/10/15/how-to-install-windows-calculator-linux/

作者:Brian Fagioli 选题:wxy 译者:wxy 校对:wxy

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

时间: 10月18日 上午 9 点

地点: bilibili 直播间 22566724

年会简介

学生开源年会(sosconf)是首个由学生组织、面向学生的非盈利社区全球性开源技术峰会,峰会基于开放源代码的理念,致力于纯粹的技术交流和多元的思想碰撞,鼓励学生享受开源、了解开源、参与开源、贡献开源,并能从开源中得到实践和乐趣。

该会议旨在积极推动学生参与开放源代码运动的历史进程,2018 年成功地在重庆举办第0届学生开源年会。

中文学生开源年会(sosconf.zh)则是学生开源年会 X 计划中的一员,其是秉承了学生开源年会的基本精神,以中文为主要语言进行的学生开源年会版本。

本次中文学生开源年会将围绕着“开源”主题,由九场主题演讲构成,为学生开源项目、开源思想应用等广义开源技术实践提供分享与交流的平台。

议程安排

9:10-9:30

主题: Welcome Speech

讲者: 朱芮捷

简介: 本次中文学生开源年会总召朱芮捷将代表年会组委会与贡献者团队进行开场致辞。

9:30-10:00

主题: 怎样设计一个没人用的编程语言

讲者: 李登淳

简介: 中文编程? No 炫酷语法? No 坚持三年,发布数十个版本,却没啥用户的编程语言, 背后究竟有什么故事?听 CovScript 创始人为您亲自讲述。

10:00-10:20

中场休息&抽奖

10:20-10:50

主题: WebP Server Go

讲者: Nova Kwok

简介: WebP是一种同时提供了有损压缩与无损压缩的图片文件格式,目标是减少文件大小,但达到和JPEG格式几乎相同的图片质量。

为了让点的图片可以无痛地以 WebP 格式输出,部分云服务商提供了转换服务,对于个人站点而言,为了同样在不改变站点原始 URL 的的情况下将图片压缩 WebP 格式输出,且脱离云服务商的限制,做到节省流量+提升页面加载速度的效果,WebP Server Go 应运而生。

使用 Go 编写的 WebP Server 是一个单一的 binary,性能优异,并且可以无缝转换JPG/PNG为webp。

只需要一次配置即可在不改变 URL 的情况下将站点图片以 WebP 格式输出,唯一改变的只有 content-typelength,无痛加速站点。原来下载10M的图片要花 10 秒钟,使用 WebP Server Go,只需要一秒钟就够了。

10:50-11:20

主题: 编程, 让生活更美好

讲者: 闫放放

简介: 你是否在网上,甚至周围听到过各种关于程序员的段子?你的编程生活是否真的如段子一样?

身为一名程序员,你眼中的生活是怎样的?

这次演讲,让你学会如何使生活井井有条,如何更好的享受生活。

甚至如果可以,如何看待生活与编程。

11:30-12:00

主题: 开源软件与自由软件

讲者: Kiritake Kumi

简介: 介绍开源软件与自由软件的历史渊源

12:00-14:00

午间休息

14:00-15:30

主题: 像个抖 M 一样写代码

讲者: ICE1000

简介: 这一看就是标题党,实际上是讲两个话题,静态类型系统和设计模式的。两者尤其是设计模式在码农间褒贬不一,讲者决定站在自己的角度谈谈如何理性看待这两位限制着程序员自由发挥的抖 S 们(笑)。

15:30-15:40

中场休息+抽奖

15:40-16:20

主题: 开源之我⻅ & SimpleXX 社区介绍

讲者: 牛志宏

简介: 主要分为两个部分。

第一部分为介绍自己的开源经历,第二部分则介绍 Simple-XX 社区。

16:20-16:40

主题: 爬虫,当斩还是当赏?

讲者: 李洋

简介: 随着人工智能的爆发,目前多以深度学习为主,样本数据的采集催生了爬虫的发展。但是爬虫就像是一个生活在阳光下的蠕虫,它有法可依也无法可依,行业内多用道德准绳来约束它。有人用它作恶,有人合法使用。没有一个标准,爬虫永远都是蠕虫。

16:40-17:10

主题: 一款辅助外语学习的词典

讲者: 赵丰

简介: 本次演讲介绍“一款辅助外语学习的词典” 这个 Web 应用及其开发的技术栈。

这款应用让外语学习者通过浏览器添加单词,制作自己的词典。

作为一个 Web 应用,其前端主要采用了传统的 HTML + Jquery

的开发方式,数据采用 XML 保存,用 XSLT 样式表来渲染。

后端使用了 Django 用于处理 POST 表单并在服务器上修改 XML 数据文件。

目前前后端还有许多不完善的地方,欢迎有兴趣的小伙伴参与贡献。

17:10-18:00

主题: 如何做一个好项目

讲者: 杨瀚淩

简介: “什么样的项目才是好项目”,“如何做出一个好项目”,“好项目落地前的准备”等三个方面进行阐述。结合 IT 和 MBA 相关知识,让同学们结合工商管理思维方式开发出更具影响力的程序项目。

18:00-18:40

主题: 红岩网校的后台架构演进与自研 RPC 框架

讲者: Kieran / 胡仓

简介: 红岩网校工作站作为一个服务校内的学生组织,拥有很多围绕着学生开发的服务。当红岩网校已经走过 20 年,积累的陈旧架构与业务已经不足以支持我们向前走。

这一篇演讲将从真实的场景出发,解构业务的复杂性,一步步拆解问题,解决问题。新的技术栈替代老旧的技术栈,旧服务逐步重构为新服务,整体演变为微服务的架构。

于此同时,我们自研了 Begonia RPC 框架,来应对更换架构与技术更新的挑战。

GNOME 3.36 带来大量亟需的改进,同时也带来性能的重大提升。现在,在 6 个月后,我们终于引来了 GNOME 3.38,并带来了一系列重大的变化。

GNOME 3.38 主要特色

这里是 GNOME 3.38 (代码名称:Orbis) 的主要亮点:

可定制应用程序菜单

作为 GNOME 3.38 重大更改中的一部分,应用程序网格(或称应用菜单)现在是可以可定制的。

现在,你可以通过拖拽每个应用程序图标来创建文件夹,将它们移到文件夹,或移出文件夹并将其设置回应用网格。你也可以在应用网格中随心所欲地调整图标的位置。

此外,这些变化是一些即将到来的设计更改的基本组成部分,因此,看到我们可以期待的东西会很令人兴奋。

日历菜单更新

随着最近一次的 GNOME 更新,通知区整洁了很多,但是现在随着 GNOME 3.38 的到来,你终于可以通过日历区域的正下方访问日历事件,使事情变得方便且容易访问。

它不是一个重大的视觉改造,但也是一些改善。

家长控制改善

作为 GNOME 3.38 一部分,你将会注意家长控制服务。它支持与桌面、shell、设置以及其它各种各样组件的集成,来帮助你限制用户可以访问的内容。

重新启动按钮

一些细微的改善导致了巨大的变化,重新启动按钮正是其中的一个变化。先单击 “关闭电源” / “关机” 按钮,再单击 “重新启动” 按钮的操作来重新启动系统总是让人很烦。

因此,随着 GNOME 3.38 的到来,你将最终会注意到一个作为单独按钮的 “重新启动” ,这将节省你的单击次数,平复你烦闷的心情。

屏幕录制改善

GNOME shell 内置的屏幕录制 现在是一项独立的系统服务,这可能会使录制屏幕成为一种平滑流畅的体验。

另外,窗口截屏也有一些改善,并修复了一些错误:

GNOME 应用程序更新

GNOME 计算器也收到很多的错误修复。除此之外,你也将发现 epiphany GNOME 浏览器 的一些重大改变。

GNOME Boxes 现在允许你从一个操作系统列表中选择将要运行的操作系统,GNOME 地图也有一些图像用户界面上的更改。

当然,不仅限于这些,你页将注意到 GNOME 控制中心、联系人、照片、Nautilus,以及其它一些软件包的细微更新和修复。

性能和多显示器支持改善

这里有一大堆底层的改进来全面地改善 GNOME 3.38 。例如,Mutter) 有一些重要的修正,它现在允许在两个显示器中使用不同的刷新频率。

先前,如果一台显示器的刷新频率为 60 Hz,而另一台的刷新频率为 144 Hz ,那么刷新频率较慢的显示器将限制另外一台显示器的刷新频率。但是,随着在 GNOME 3.38 中的改善,它将能够处理多个显示器,而不会使显示器相互限制。

另外,Phoronix 报告的一些更改指出,在一些情况下,缩短大约 10% 的渲染时间。因此,这绝对是一个很棒的性能优化。

各种各样的其它更改

  • 电池百分比指示器
  • 电源菜单中的重新启动选项
  • 新的欢迎指引
  • 指纹登录
  • 二维码扫描以共享 Wi-Fi 热点
  • GNOME 浏览器的隐私和其它改善
  • GNOME 地图现在反应敏捷并能根据屏幕大小改变其大小
  • 重新修订的图标

你可以在它们的官方 更改日志 中找到一个详细的更改列表。

总结

GNOME 3.38 确实是一个令人赞叹的更新,它改善了 GNOME 用户体验。尽管 GNOME 3.36 带来了性能的很大改善,但是针对 GNOME 3.38 的更多优化仍然是一件非常好的事.

GNOME 3.38 将在 Ubuntu 20.10 和 Fedora 33 中可用。Arch 和 Manjaro 用户应该很快就能获得。

我认为有很多变化是朝着正确的方向发展的。你觉得呢?


via: https://itsfoss.com/gnome-3-38-release/

作者:Ankush Das 选题:lujun9972 译者:robsean 校对:wxy

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