你为什么使用 Linux 和开源软件？

谁能说说开源和帕累托法则联系    @wxy

单纯的出于自由和浪

对待我自己的成长笔记和技术总结，我个人将会保持共享、共享、共享的原则。要不然自己忘记了都找不到。。。这很像DNA片段。最好的保留就是把自己复制出去！！！

<自由软件 自由社区> 建议通读。。。

82法则么，这里的意思是只需要付出20%，就能得到80%的需求了，剩下的20% 可以付费或者自己搞定。

我使用linux的理由：刚开始是因为老电脑用windows太卡，后来是因为习惯了就不想换了。<br />
我使用开源软件的理由：并没有什么特殊的理由，linux下大多数实用和好用的软件都是开源的。但如果一个很不错的软件不开源，我还是会选择使用它。

来自河南郑州的 Chrome Mobile 58.0|Android 6.0 用户

因为我觉得好玩。就这样。

以前电脑太老，win10巨卡，用上Linux，一年后换新电脑，用习惯了linux……必要条件<br />
恰好用linux相对不卡，恰好linux免费开源……充分条件

完全是因为受不了WINDOWS下的广告软件才逃到LINUX的

比 windows 资源消耗低, 如 RAM 内存, 明显低很多

环境非常适合用于开发, 安装软件也很方便, 一个指令即可

基本BT/迅雷下载, IM, 浏览, 听音乐,看视频都没问题

玩大咖游戏可以用 Steam, 但网上买游戏不是免费

不需要磁盘整理, 也不一定需要防病毒软件

想不到理由为什么我不用 LINUX, 而特意买 windows 来用.

就因为 windows 界面看起来较美? 还是安全? 别开玩笑了. 我才不会买账.

>
> LinuxQuestions.org 的用户分享了他们使用 Linux 和开源技术的原因。我们的用户如何回答这个问题？
>
>
>

![Why do you use Linux and open source software?](/data/attachment/album/201706/08/073956jvpn21ma7mxux8an.png "Why do you use Linux and open source software?")

在网站问答区发布时我曾经提到过，尽管我一般会回答来自用户问题，但偶尔我也会反过来问读者一些问题。我并没有在问答区第一期文章这样做，看起来有点姗姗来迟。我最近在 LinuxQuestions.org 上提问了两个相关的问题，收到了很多回复。让我们看看我们的用户对同样的问题和 LinuxQuestions.org 的回答的对比。

### 你为什么使用 Linux？

我向 LinuxQuestions.org 社区提问的第一个问题是：**[你们使用 Linux 的原因是什么？](http://www.linuxquestions.org/questions/linux-general-1/what-are-the-reasons-you-use-linux-4175600842/)**

#### 回答集锦

*oldwierdal*：我用 Linux 是因为它运行快速、安全、可靠。在全世界的贡献者的参与下，Linux 或许已经成为当前我们能用到的最先进和最具创新的软件。Linux 的用户体验就像红丝绒蛋糕上的糖衣一样令人回味无穷；此外，Linux 是免费的。

*Timothy Miller*：我最开始使用 Linux 是因为它免费的，而且那时候我的经济条件无法承受购买新的 Windows 系统正版授权的费用。

*ondoho* ：因为它是一个拥有全球性社区为之努力、独立的草根操作系统。因为它在各方面都是自由的。因为它有足够多的理由让我们信任它。

*joham34*：稳定、免费、安全，能够运行在低配置的电脑上，提供良好技术支持的社区，感染病毒的几率更小。

*Ook*：我用 Linux 是因为它可以完成工作，对我来说 Windows 系统在某些事上从来都不能做好。我不得不浪费时间和金钱让 Windows 继续正常运行下去。

*rhamel*：我非常担心个人隐私泄露在网上。我意识到我不得不在隐私和便利性之间做出妥协。我可能是在骗自己但我确实认为 Linux 至少在某种程度上给了我一定的隐私权。

*educateme*：我使用 Linux 因为它的开放、好学、热情乐于助人的社区。而且，它是免费的。

*colinetsegers*：我为什么用 Linux？原因不止一个。简单的说有以下几点：

1. 自由分享知识的理念。
2. 浏览网页的时候有安全感。
3. 大量免费、有用的软件。

*bamunds*：因为我热爱自由。

*cecilskinner1989*：我用 Linux 的两个原因：稳定性和隐私。

### 你为什么使用开源软件？

第二个问题相对更加宽泛：**[你为什么使用开源软件？](http://www.linuxquestions.org/questions/linux-general-1/what-are-the-reasons-you-use-open-source-software-4175600843/)**你会注意到尽管有些回复是有重复的部分，但用户的回答大体上的语气是不同的，有些用户的回答得到很多人的赞同和支持，也有不少用户的回答不怎么被其他人认同。

#### 回答集锦

*robert leleu*：温馨、合作的氛围是我沉溺于开源的主要原因。

*cjturner*：对于应用而言，开源正好反映了帕累托法则；不做二次开发的话，一个软件包最终可能只能满足你的 80% 的需求，而你需要自己解决剩下的 20%。开源给了你一个途径，通过社区来解决这种问题，你可以自己努力实现（如果你有相关的技能）或者花钱有偿请人实现你的需求。

*Timothy Miller*：我喜欢这种体验，我能够自己检查源代码来确定我所选择的软件是安全的。

*teckk*：没有繁琐的许可要求或者数字版权管理（DRM），而且每个人都可以获得它。

*rokytnji* ：像零花钱，摩托车部件，孙辈的生日礼物那样令人愉悦。

*timl*：没有自由软件避免隐私的泄露是不可能。

*hazel*：我喜欢自由软件的哲学，但如果 Linux 是一个糟糕的操作系统我也会理性的不去使用它。我使用 Linux 是因为我热爱 Linux，而且你也能免费获得它就像免费的啤酒一样。事实上它也如言论自由一般自由不受拘束，使用开源软件让我感觉很舒服。但是如果我发现我的计算机有一个硬件需要专有固件的配合才能发挥功能，我也会使用专有固件。

*lm8*：我使用开源软件是因为我不必担心由于开发公司的破产或者决定停止维护它而导致它可能会变得过时或者被废弃。我能够自己来完成后续的更新、维护。如果我想让软件能够做我想的任何事情，我也可以进一步定制它，但是如果有更多的特性，那就更好了。我也喜欢开源，因为开源我才能够和朋友、同事们分享我喜欢的程序。

*donguitar*：因为它能够让我学到很多，也让我让别人学到了很多。

### 该你回答了

所以，***你*** 使用 Linux 的原因是什么？ ***你*** 使用开源软件的原因是什么？请在评论区告诉我们。

#### 最后的补充

最后，在以后的文章里你想看到什么问题的回答？是社区的建立和维护的相关问题，还是你想知道如何对一个开源项目作出贡献，还是更有技术性的问题 — 向我们提交你对 Linux 和 开源的问题。

（题图：opensource.com）

---

作者简介：

Jeremy Garcia - Jeremy Garcia 是 LinuxQuestions.org 的创立者同时也是一位热情中不乏现实主义的开源倡导者。你可以在 Twitter 上关注 Jeremy：@linuxquestions

---

via: <https://opensource.com/article/17/3/why-do-you-use-linux-and-open-source-software>

作者：[Jeremy Garcia](https://opensource.com/users/jeremy-garcia) 译者：[WangYueScream](https://github.com/WangYueScream) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（20）：安卓 4.1，果冻豆——Google Now 指明未来

![](/data/attachment/album/201706/10/095808mwnjgofkmnd9s4mf.jpg)

### 安卓 4.1，果冻豆——Google Now指明未来

![](/data/attachment/album/201706/08/213645dwyemmyqk3njykub.jpg)

*华硕制造的 Nexus 7，安卓 4.1 的首发设备*

随着 2012 年 7 月安卓 4.1 果冻豆的发布，谷歌的安卓发布节奏进入每六个月一发布的轨道。平台已经成熟，三个月的发布周期就没那么必要了，更长的发布周期也给了 OEM 厂商足够的时间跟上谷歌的节奏。和蜂巢不同，小数点后的更新发布现在是主要更新，4.1 带来了主要的界面更新和框架变化。

果冻豆最大的变化之一，并且你在截图中看不到的是“黄油计划”，这个名字代表了谷歌工程师让安卓的动画顺畅地跑在 30FPS 上的努力。还有一些核心变化，像垂直同步和三重缓冲，每个动画都经过优化以流畅地绘制。动画和顺滑滚动一直是安卓和 iOS 相比之下的弱点。经过在核心动画框架和单独的应用上的努力，果冻豆让安卓的流畅度大幅接近 iOS。

和果冻豆一起到来的还有 [Nexus](http://arstechnica.com/gadgets/2012/07/divine-intervention-googles-nexus-7-is-a-fantastic-200-tablet/) 7，由华硕生产的 7 英寸平板。不像之前主要是横屏模式的 Xoom，Nexus 7 主要以竖屏模式使用，像个大一号的手机。Nexus 7 展现了经过一年半的生态建设，谷歌已经准备好了给平板市场带来一部旗舰设备。和 Nexus One 和 GSM Galaxy Nexus 一样，Nexus 7 直接由谷歌在线销售。尽管那些早先的设备对习惯于运营商补贴的消费者来说价格高的惊人，Nexus 7 以仅仅 200 美元的价格推向大众市场。这个价格给你带来一部 7 英寸、1280x800 英寸显示屏、四核 1.2GHz Tegra 3 处理器、1GB 内存、8GB 内置存储的设备。Nexus 7 的性价比如此之高，许多人都想知道谷歌到底有没有在其旗舰平板上赚到钱。

更小、更轻、7 英寸，这些因素促成了谷歌巨大的成功，并且将谷歌带向了引领行业潮流的位置。一开始制造 10 英寸 iPad 的苹果，最终也不得不推出和 Nexus 7 相似的 iPad Mini 来应对。

![](/data/attachment/album/201706/08/213729dssy92sz8qsi0a06.jpg)

*4.1 的新锁屏设计，壁纸，以及系统按钮新的点击高亮。 [Ron Amadeo 供图]*

蜂巢引入的电子风格在冰淇淋三明治中有所减少，果冻豆在此之上走得更远。它开始从系统中大范围地移除蓝色。迹象就是系统按钮的点击高亮从蓝色变为了灰色。

![](/data/attachment/album/201706/08/213803y3hh3q4v30ddjmf9.jpg)

*新应用阵容合成图以及新的消息可展开通知面板。 [Ron Amadeo 供图]*

通知中心面板完全重制了，这个设计一直沿用到今天的奇巧巧克力（KitKat）。新面板扩展到了屏幕顶部，并且覆盖了状态栏图标，这意味着通知面板打开的时候不再能看到状态栏。时间突出显示在左上角，旁边是日期和设置按钮。清除所有通知的按钮，在冰淇淋三明治中显示为一个“X”按钮，现在变为阶梯状的按钮，象征着清除所有通知的时候消息交错滑动的动画效果。底部的面板把手从一个小圆换成了一条直线，和面板等宽。所有的排版都发生了变化——通知面板的所有项现在都使用了更大，更细的字体。通知面板是另一个从冰淇淋三明治和蜂巢中引入的蓝色元素被移除的屏幕。除了触摸高亮之外整个通知面板都是灰色的。

通知面板也引入了新功能。相较于之前的两行设计，现在的通知消息可以展开以显示更多信息。通知消息可以显示最多 8 行文本，甚至还能在消息底部显示按钮。屏幕截图通知消息底部有个分享按钮，你也可以直接从未接来电通知中拨号，或者将一个正在响铃的闹钟小睡，这些都可以在通知面板完成。新通知消息默认展开，但当它们堆叠到一起时会恢复原来的尺寸。在通知消息上双指向下滑动可以展开消息。

![](/data/attachment/album/201706/08/213845cdl5ldtxhxc6sx6w.jpg)

*新谷歌搜索应用，带有 Google Now 卡片，语音搜索，以及文字搜索。 [Ron Amadeo 供图]*

果冻豆中不止对安卓而言，也是对谷歌来说最大的特性，是新版谷歌搜索应用。它带来了“Google Now”，一个预测性搜索功能。Google Now 在搜索框下面显示为几张卡片，它会提供谷歌认为你所关心的事物的搜索结果。就比如谷歌地图搜索你最近在桌面电脑查找的地点或日历的约会地点、天气，以及旅行时回家的时间。

新版谷歌搜索应用自然可以从谷歌图标启动，但它还可以在任意屏幕从系统栏上滑访问。长按系统栏会唤出一个类似锁屏解锁的环。卡片部分纵向滚动，如果你不想看到它们，可以滑动消除它们。语音搜索是更新的一个大部分。提问不是无脑地输入进谷歌，如果谷歌知道答案，它还会用文本语音转换引擎回答你。传统的文字搜索当然也支持。只需点击搜索栏然后开始输入即可。

谷歌经常将 Google Now 称作“谷歌搜索的未来”。告诉谷歌你想要什么这还不够好。谷歌想要在你之前知道你想要什么。Google Now 用谷歌所有的数据挖掘关于你的知识为你服务，这也是谷歌对抗搜索引擎竞争对手，比如必应，的最大优势所在。智能手机比你拥有的其它设备更了解你，所以该服务在安卓上首次亮相。但谷歌慢慢也将 Google Now 加入 Chrome，最终似乎会到达 Google.com。

尽管功能很重要，但同时 Google Now 是谷歌产品有史以来最重要的设计工作也是毋庸置疑的。谷歌搜索应用引入的白色卡片审美将会成为几乎所有谷歌产品设计的基础。今天，卡片风格被用在 Google Play 商店以及所有的 Play 内容应用，Youtube、谷歌地图、Drive、Keep、Gmail、Google+ 以及其它产品。同时也不限于安卓应用。不少谷歌的桌面站点和 iOS 应用也以此设计为灵感。设计是谷歌历史上的弱项之一，但 Google Now 开始谷歌最终在设计上采取了行动，带来一个统一的，全公司范围的设计语言。

![](/data/attachment/album/201706/08/213925v92x3iio0veva0a1.jpg)

*又一个 Youtube 的重新设计，信息密度有所下降。 [Ron Amadeo 供图]*

又一个版本，又一个 Youtube 的重新设计。这次列表视图主要基于略缩图，大大的图片占据了屏幕的大部分。信息密度在新列表设计中有所下降。之前 Youtube 每屏大约能显示 6 个项目，现在只能显示 3 个。

Youtube 是首批在应用左侧加入滑动抽屉的应用之一，该特性会成为谷歌应用的标准设计风格。抽屉中有你的账户的链接和订阅频道，这让谷歌可以去除页面顶部标签页设计。

![](/data/attachment/album/201706/08/214002qge6eu88fo8wue3k.jpg)

*Google Play 服务的职责以及安卓的剩余部分职责。 [Ron Amadeo 供图]*

### Google Play 服务——碎片化和让系统版本（几乎）过时

碎片化那时候看起来这并不是个大问题，但 2012 年 12 月，Google Play 服务 1.0 面向所有安卓 2.2 及以上版本的手机推出。它添加了一些 Google+ API 和对 OAuth 2.0 的支持。

尽管这个升级听起来很无聊，但 Google Play 服务最终会成长为安卓整体的一部分。Google Play 服务扮演着正常应用和安卓系统的中间角色，使得谷歌可以升级或替换一些核心组件，并在不发布新安卓版本的前提下添加 API。

有了 Play 服务，谷歌有了直接接触安卓手机核心部分的能力，而不用通过 OEM 更新一集运营商批准的过程。谷歌使用 Play 服务添加了全新的位置系统、恶意软件扫描、远程擦除功能，以及新的谷歌地图 API，所有的这一切都不用通过发布一个系统更新实现。正如我们在姜饼部分的结尾提到的，感谢 Play 服务里这些“可移植的”API 实现，姜饼仍然能够下载现代版本的 Play 商店和许多其他的谷歌应用。

另一个巨大的益处是安卓用户基础的兼容性。最新版本的安卓系统要经过很长时间到达大多数用户手中，这意味着最新版本系统绑定的 API 在大多数用户升级之前对开发者来说没有任何意义。Google Play 服务兼容冻酸奶及以上版本，换句话说就是 99% 的活跃设备，并且更新可以直接通过 Play 商店直接推送到手机上。通过将 API 包含在 Google Play 服务中而不是安卓中，谷歌可以在一周内将新 API 推送到几乎所有用户手中。这对许多版本碎片化引起的问题来说是个[伟大的解决方案](http://arstechnica.com/gadgets/2013/09/balky-carriers-and-slow-oems-step-aside-google-is-defragging-android/)。

---

![](/data/attachment/album/201706/08/214127visusz5iy8ct6z82.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron 是 Ars Technica的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/21/>

译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


cron 与 anacron：如何在 Linux 中计划任务

![](/data/attachment/album/201706/08/230239x0dew0x0mbf1x05m.jpg)

在本篇中，我们会解释 cron 和 anacron，并向你展示如何在 Linux 中设置 anacron。我们也会比较这两个工具。

要[在一个给定时间或者稍后安排一个任务](https://www.tecmint.com/linux-cron-alternative-at-command-to-schedule-tasks/)，你可以使用 `at` 或者 `batch` 命令，要使命令能够重复运行，你可以使用 cron 以及 anacron 工具。

[cron](https://www.tecmint.com/11-cron-scheduling-task-examples-in-linux/) - 是一个用于运行计划任务如系统备份、更新等的守护进程。它适合在那些 24X7 不间断运行的机器如服务器上运行的计划任务。

命令/脚本被写在 cron 任务脚本中，它是在 `crontab` 文件中被安排的。系统默认的 `crontab` 文件是 `/etc/crontab`，但是每个用户也可以创建自己的 `crontab` 文件来在特定时间运行用户定义的命令。

要创建一份个人 `crontab` 文件，只要输入：

```
$ crontab -e

```

### 如何在 Linux 中设置 anacron

anacron 用于以天为单位的频率运行命令。它的工作与 cron 稍有不同，**它假设机器不会一直开机**。

cron 也适合在那些不会 24X7 运行如笔记本以及桌面电脑的机器上运行每日、每周以及每月的计划任务（LCTT 译注：不适合按小时、分钟执行任务）。

假设你有一个计划任务（比如备份脚本）要使用 cron 在每天半夜运行，也许你以及睡着，那时你的桌面/笔记本电脑已经关机。你的备份脚本就不会被运行。

然而，如果你使用 anacron，你可以确保在你下次开启桌面/笔记本电脑的时候，备份脚本会被执行。

### anacron 如何在 Linux 工作

anacron 任务被列在 `/etc/anacrontab` 中，任务可以使用下面的格式（anacron 文件中的注释必须以 `#` 号开始）安排。

```
period   delay   job-identifier   command

```

从上面的格式中：

* `period` - 这是任务的频率，以天来指定，或者是 `@daily`、`@weekly`、`@monthly` 代表每天、每周、每月一次。你也可以使用数字：`1` - 每天、`7` - 每周、`30` - 每月，或者 `N` - 几天。
* `delay` - 这是在执行一个任务前等待的分钟数。
* `job-id` - 这是写在日志文件中任务的独特名字。
* `command` - 这是要执行的命令或 shell 脚本。

要浏览示例文件，输入：

```
$ ls -l /var/spool/anacron/
total 12
-rw------- 1 root root 9 Jun  1 10:25 cron.daily
-rw------- 1 root root 9 May 27 11:01 cron.monthly
-rw------- 1 root root 9 May 30 10:28 cron.weekly

```

这是实际发生的：

* anacron 会检查任务是否已经在 `period` 字段指定的时间被被执行了。如果没有，则在等待 `delay` 字段中指定的分钟数后，执行 `command` 字段中指定的命令。
* 一旦任务被执行了，它会使用 `job-id`（时间戳文件名）字段中指定的名称将日期记录在 `/var/spool/anacron` 目录中的时间戳文件中。

现在让我们看一个例子。这个会每天运行 `/home/aaronkilik/bin/backup.sh` 脚本：

```
@daily    10    example.daily   /bin/bash /home/aaronkilik/bin/backup.sh

```

当机器在 `backup.sh` 期望被运行时是关机的，anacron 会在机器开机十分钟之后运行它，而不用再等待 7 天。

这里有两个你应该理解的 anacrontab 文件的重要变量：

* `START_HOURS_RANGE` - 这个设置任务开始运行的时间范围（也就是任务只在这几个小时内运行）。
* `RANDOM_DELAY` - 这定义添加到用户定义的任务延迟的最大随机延迟（默认为 45）。

这是你的 anacrontab 文件可能看上去的样子。

Anacron – `/etc/anacrontab`：

```
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root
# These replace cron's entries
1       5       cron.daily      run-parts --report /etc/cron.daily
7       10      cron.weekly     run-parts --report /etc/cron.weekly
@monthly        15      cron.monthly    run-parts --report /etc/cron.monthly
@daily    10    example.daily   /bin/bash /home/aaronkilik/bin/backup.sh

```

下面是 cron 以及 anacron 的比较，帮助你理解何时用他们其中一个。

| cron | anacron |
| --- | --- |
| 它是守护进程 | 它不是守护进程 |
| 适合服务器 | 适合桌面/笔记本电脑 |
| 可以让你以分钟级运行计划任务 | 只能让你以天为基础来运行计划任务 |
| 关机时不会执行计划任务 | 如果计划任务到期，机器是关机的，那么它会在机器下次开机后执行计划任务 |
| 普通用户和 root 用户都可以使用 | 只有 root 用户可以使用（使用特定的配置启动普通任务） |

cron 和 anacron 主要的区别在于 cron 能在那些持续运行的机器上有效地运行，而 anacron 是针对那些会在一天内或者一周内会关机的机器。

如果你还知道其他方式，请在评论栏中与我们分享。

（题图：Pixabay，CC0）

---

作者简介：

Aaron Kili 是一个 Linux 和 F.O.S.S 爱好者、Linux 系统管理员、网络开发人员，现在也是 TecMint 的内容创作者，他喜欢和电脑一起工作，坚信共享知识。

---

via: <https://www.tecmint.com/cron-vs-anacron-schedule-jobs-using-anacron-on-linux/>

作者：[Aaron Kili](https://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


AWS 云服务大全（71 种）

![](/data/attachment/album/201706/09/000008n6h42nmzagbm62nv.jpg)

*认识 71 个 AWS 云服务的术语 ! 通过了解 AWS 世界中使用的术语开始你的 AWS 云服务使用生涯 !*

AWS，即<ruby> 亚马逊 Web 服务 <rt>  Amazon Web Services </rt></ruby>，是一个提供了一系列按使用计费的 web 服务的云平台。 它是迄今为止最为著名的云平台之一。由于其灵活性、有效性、弹性、可测量性和无须维护，所以有一些企业正逐步把他们的业务迁移到云端。 由于许多公司目前在使用这些服务，所以对于系统管理员和运维人员来说应该了解一下 AWS。

这篇文章旨在列出这些 AWS 提供的服务并且解释在 AWS 中出现的术语。

截止到目前为止（2017 年 3 月），AWS 提供了分为 17 组的共计 71 种服务：

### 计算型服务

这是一个提供了虚拟服务器配置功能的服务，即所谓的云计算。它提供了包括以下这一系列的服务。

1. EC2：EC2 代表弹性计算云。这种服务提供了可根据个人需求扩展的 [虚拟机][11]。
2. EC2 容器服务：其高性能，高可扩展性使其可在 EC2 集群环境中运行服务。
3. Lightsail：该服务使用户非常容易地启动和管理虚拟服务器（EC2）。
4. Elastic Beanstalk：该服务能够自动管理你的应用程序的容量配置、负载平衡、扩展以及健康监控从而减少你的管理压力。
5. Lambda：它允许你只在你需要的时候运行代码而不用去管理服务器。
6. Batch：它使用户能够以自定义的管理方式运行计算工作负载（批处理）。

### 存储型服务

它是一种云存储服务，即由 Amazon 提供的云存储设施。 该组服务包括：

1. S3：S3 代表简单存储服务（3 个 S）。 它给你提供了在线存储服务，你可随时从任何地方存储/检索任何数据。
2. EFS：EFS 代表弹性文件系统。 它是一个可以和 EC2 服务器一起使用的在线存储服务。
3. Glacier：它是一种低成本/低性能数据存储解决方案，主要针对存档或长期备份。
4. Storage Gateway：这种服务的接口会将你的内部应用程序（托管在 AWS 之外）与 AWS 存储连接。

### 数据库

AWS 还提供在其基础设施上托管数据库，以便客户可以利用亚马逊最先进的技术来获得更快/高效/安全的数据处理。 该组包括：

1. RDS：RDS 代表关系数据库服务。 用于在云上设置，操作和管理关系数据库。
2. DynamoDB：其 NoSQL 数据库提供了快速处理和高可扩展性。
3. ElastiCache：这是一种为你的 Web 应用程序管理内存缓存以便更快运行它们的方案 ！
4. Redshift：它是一个巨大的（PB 级）的完全可升级的云端数据仓库服务。

### 网络 & 内容分发

由于 AWS 提供云端的 EC2 服务器，因此网络相关内容也将在出现在这里。 内容分发用于向位于最近位置的用户提供文件。 现如今有许多非常有名的加速网站。

1. VPC：VPC 代表虚拟私有云。 它是你自己的虚拟网络，是你的专用 AWS 帐户。
2. CloudFront：这是 AWS 的内容分发网络（CDN）服务。
3. Direct Connect：它是将数据中心/场所与 AWS 连接起来的网络方式，以提高吞吐量，降低网络成本，并避免由于基于互联网的连接而导致的连接问题。
4. Route 53：它是一个云端的域名系统的 DNS Web 服务。

### 迁移

它提供了一系列服务来帮助你实现本地服务到 AWS 的迁移工作。 这包括 ：

1. Application Discovery Service：专门用于分析您的服务器、网络、应用程序以帮助/加速迁移的服务。
2. DMS：DMS 指的是数据库迁移服务。 它用于将数据从本地数据库迁移到 EC2 上托管的 RDS 或 DB。
3. Server Migration：也称为 SMS（服务器迁移服务）是一种无代理服务，将您的工作负载从本地移动到 AWS。
4. Snowball： 当你想要使用物理存储设备（而不是基于互联网/基于网络的传输）将大量数据传入/迁出 AWS 时，你应该使用它。

### 开发者工具

顾名思义, 这是一系列帮助开发者简化在云端编码的服务。

1. CodeCommit：它是一个安全的、可扩展的、可管理的源代码管理服务，用于托管代码仓库。
2. CodeBuild：这是一个云端的代码生成器。主要用于执行、测试代码和构建部署软件包。
3. CodeDeploy：这是一个可在 AWS 服务器或本地进行自动化应用程序部署的部署服务。
4. CodePipeline：这个部署服务可以使编码人员可以在发布之前将其应用程序可视化。
5. X-Ray：它可以使用事件调用分析应用程序。

### 管理工具

这是一组可帮助你管理 AWS 上的 Web 服务的服务。

1. CloudWatch：监控你的 AWS 资源或应用程序的监控服务。
2. CloudFormation：基础设施即代码！以集体有序的方式管理 AWS 架构的方式。
3. CloudTrail：AWS 帐户的审计和合规工具。
4. Config : AWS 的资源清单、配置历史记录和配置更改通知，以实现安全性和治理。
5. OpsWorks：它可以自动化地配置，部署 EC2 或内部部署计算。
6. Service Catalog：创建和管理被批准在你/公司帐户中使用的 IT 服务目录。
7. Trusted Advisor：它的 AWS AI 可以通过审查你的 AWS 基础设施使你的 AWS 基础设施更好，更省钱。
8. Managed Service：提供持续的基础设施管理。

### 安全性、身份和合规

这是一组很重要的 AWS 服务以确保你的 AWS 空间的安全性。

1. IAM：IAM 即身份和访问管理，控制用户访问你的 AWS 资源和服务。
2. Inspector：自动安全评估可帮助你在 AWS 上的应用安全和合规。
3. Certificate Manager：为 AWS 应用程序提供，管理和部署 SSL / TLS 证书。
4. Directory Service：相当于 AWS 的 Microsoft Active Directory。
5. WAF & Shield：WAF 即 Web 应用防火墙。 监控和控制对 CloudFront 或负载均衡器上的内容的访问。
6. Compliance Reports：AWS 基础设施空间的合规报告，以确保您的应用程序符合您的策略。

### 数据分析

AWS 空间的数据分析服务，以帮助您查看、计划和对帐户中的事件采取行动。

1. Athena：它是一个基于 SQL 查询的服务，用于分析 S3 存储的数据。
2. EMR：EMR 的全写是 Elastic Map Reduce。 是一个主要用于大数据处理和分析的服务。
3. CloudSearch：AWS 在应用和服务中的搜索功能。
4. Elasticsearch Service：它可以创建一个域并在 AWS Cloud 中部署、操作和扩展 Elasticsearch 集群。
5. Kinesis：这种服务可以实现实时的大量流数据处理。
6. Data Pipeline：它可以帮助我们在不同的 AWS 服务之间实现数据迁移。
7. QuickSight：收集、分析和呈现 AWS 的业务数据。

### 人工智能

AWS 的 AI!

1. Lex：它可以帮助我们在一些使用语音和文本的应用中构建会话界面。
2. Polly：这是一个提供文字到语音转换的服务。
3. Rekognition：使您能够将图像分析添加到应用程序。
4. Machine Learning：它具有学习数据中的模式的算法。

### 物联网

这个服务保证了 AWS 在不同设备上的高可用性。

1. AWS IoT：它使联网硬件设备与 AWS 的应用程序能够交互。

### 游戏开发

顾名思义，这个服务旨在游戏开发。

1. Amazon GameLift：该服务旨在部署、管理用于会话的多人游戏的专用游戏服务器。

### 移动服务

这是一组主要针对手持设备的服务。

1. Mobile Hub：帮助您创建移动应用的后台功能并将其集成到移动应用。
2. Cognito：在连接了互联网设备上控制移动用户的身份验证和 AWS 的访问。
3. Device Farm：移动应用测试服务使你可以在 Android 上托管的真实手机上跨 Android、iOS 测试应用。
4. Mobile Analytics：在 AWS 上测量、跟踪和分析移动应用数据。
5. Pinpoint：针对性的推送通知和移动互动。

### 应用服务

这是一组可以和你在 AWS 上的应用一起使用的服务。

1. Step Functions：定义和使用应用程序中的各种功能。
2. SWF：SWF 代表简单的工作流服务。其云工作流程管理可帮助开发人员在应用程序生命周期的不同阶段进行协调和贡献。
3. API Gateway：帮助开发人员创建、管理和托管 API。
4. Elastic Transcoder：帮助开发人员将媒体文件转换为在各种设备上可以播放的格式。

### 消息

AWS 中的通知和消息服务。

1. SQS：SQS 表示简单队列服务。完全管理的消息队列服务，用于在 AWS 中的服务和应用之间进行通信。
2. SNS：SNS 代表简单通知服务。 为 AWS 用户推送通知服务，提醒他们有关其在 AWS 空间中的服务。
3. SES：SES 代表简单电子邮件服务。 这是 AWS 为自己的客户提供高性价比的电子邮件服务。

### 企业生产率

一组帮你提高业务生产率的服务。

1. WorkDocs：协同文件共享、存储和编辑服务。
2. WorkMail：安全的商务邮件、日程服务。
3. Amazon Chime：在线的企业会议！

### 桌面和应用程序流式传输

实现桌面应用程序通过云端进行流传输。

1. WorkSpaces：完全管理且安全的云计算服务。
2. AppStream 2.0：来自云端的流式桌面应用。

（题图：rackaid.com）

---

via: <http://kerneltalks.com/virtualization/aws-cloud-terminology/>

作者：[Shrikant Lavhate](http://kerneltalks.com/virtualization/aws-cloud-terminology/) 译者：[chenxinlong](https://github.com/chenxinlong) 校对：[wxy](https://github.com/wxy)

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


如何从参与开源项目的过程中获取自信

![如何从参与开源项目的过程中获取自信](/data/attachment/album/201706/09/090159ixbqbwxzq06vqx8q.jpg "How to gain confidence to participate in open source")

随着大脑的发育，你渐渐学会了这世上什么事情可以/应该做，以及什么事情不能/不应该做。你所有的行为都受到周围大众的影响，很多时候，阻碍你参与某事的原因就是你缺乏自信。

纵观我们的生活，我们都或多或少的受到了世俗和社会行为的“教条”影响。我们可能从小就被这样教育：演说家说的都是真理、CEO 都是有远见的、警察维护社会秩序，尊重别人代表着静听让人把话说完，如果人家说错了，你要看场合轻柔的指出来 —— 好吧，这有点复杂。

当你决心参与到开源项目之中去的时候，自信将扮演重要角色。开源社区有其固有的参与性。参与就相当于开源世界的流通货币，持有该货币的量取决于你的自信。你的参与性越高、技能越高、分享你的想法和简洁次数越多，你就越能通过自己的<ruby> 提交 <rp>  （ </rp> <rt>  commit </rt> <rp>  ） </rp></ruby>来改善某一个项目。所有这些都需要你有很强的信念 —— 你有值得分享的事情 —— 并且你会常常思考自己要做什么、分享什么。

这里不得不说说这样一个事实：我们每一个人都一些值得分享的事情。但是你要找出这个值得分享的事情是什么，以及在哪个位置分享它才能把这个分享推向最积极、最有意义的一面。

认真思考一下三点，这将增强你的自信，并能让你在开源社区中更容易取得进步。

### 没有人会站在你的角度来看待你

你要时刻谨记着：你是完全独立的个人，他人对你做出的评论就像是不存在一样，只有这样才能更好的获得自信。

我们都习惯了这样认知，周围的人都是根据我们的行为来做出评判的。这一习惯是学习如何更像社会群体一样生活的副产品。而且很可能在我们的童年，父母根据我们的行为设置的奖励机制时，这个习惯就根植我们心底。到了青春期，老师们对我们的表现来评价，给我们划分等级和分数，拿我们和身边的小伙伴对比。这样的动力和奖励机制给我们的大脑建立了一个包括自我反思在内的反馈回路。我们需要预测自己能否得到回报，并要为那些可能发生的事情做好应对。

现今的我们都有这样第一个疑惑：身边的人是如何看我的？然而，真相是多数人都不会花太多时间来对你进行正确客观的评价。我们所有人只是关注自己的回报，我们有自己热衷于某件事的的热情、有大量急待解决的问题。也有一些人忙于关心他们自己如何影响身边的人，他们并不会在身上花费时间。他们根本不会注意到你是否出错、大声谈话还是像他们的背景音乐一样。所有的那些疑惑都只是在你自己的脑海中而已，而非在其他任何人脑中。

我们需要被人们所接受的愿望也是人生意义的一部分，但是这类受我们所遇之人的一时兴起。这些人可能对我们缺乏全面认识，比如我们叫什么、我们来自哪里、形成我们认知的经历，等等。我们能否为人们所接受是一件不受我们自身控制的事情。但是，我们是可以通过与之交流来改变的。

在开源的社区化世界里，记住这一点是非常重要的：人们是不会过多的考虑你的感受的。因为你的同事和导师都在忙于其它项目或则社区成员。

一旦你认知了这一点，通过积极地沟通来热情拥抱这个世界吧。寻求帮助、告知他人你的需求、指出你的贡献、让人们知道你和他们在一起努力、你也是这个社区中的活跃分子。当人们向你靠拢 ——而非相反 —— 时，你的开源可信度和自信会得到极大的提高。

### 所有人都热衷于分享自己熟知的事情

任何成功的开源社区都是一个包含教和学的社区。为沐浴在开源中，你不仅需要用到自身的已有知识，还需要不断的吸收消化其他人提供课程中的知识。幸运的是，人们都普遍热衷于分享他们熟悉的事情。

思考一下，当他人问及你的观点时，你是什么感受。得知他人认可了你所说的观点，对你的本我和自我是多么美好的一件事。

在儿童期时，我们的大脑并没有那么发达，无法为我们容纳现实世界中大量的信息量。我们曾一度认为自己是世界的中心。在六岁以前，我们的认知一直在不断成长。在此期间，我们的父母会因我们哭泣而做出回应，周围的成年人都会满足我们要求。这会在我们心底形成自己在世界上最重要的证据。

我们的神经回路在此期间建立完成，我们的性格也在此期间形成。随着我们学会参与社会和城市的生活，我们逐渐的认识到自己并非世界的中心。然而，最初形成并深植我们心底那种意识并不会因此马上就消除掉。正确理解我们在整个社会氛围中的个人意识将有助于你与他人建立连接并融洽相处。

在团结协作中慢慢积累学习经验可以很好的磨练自己、发展自己社会关系和提高自身技能。想要进军开源的世界，不断地学习是不可或缺的。

那么，这些和自信有些什么关系呢？通过表明你重视他人的知识和付出，你提高的不仅是他们的自信，还有你自己的自信。那时你将会感到更加灵活。有些时候，你不得不承认自己也有不懂的地方。

自信的人也许会说“是的，我不知道”，但却不会因此而沮丧。

### 一分耕耘，一分收获

你一定听过“不懂装懂，永远是饭桶”。这样说吧，自信就像其他很多的心理现象。积极地提示自己：我很聪明、有趣、引人关注、极富天赋、健谈、是一个很好的伙伴、独一无二、知识面广、学习能力强、常常自省的思想者，或者是其他你想要具备的特质，久而久之你就会觉得自己就是这样的人。并且，如果这可以在你身上生效，在其他人身上也一样。。

我们把这个称为自我肯定。

此外，在开源的世界中，你是如何为人考虑、如何待人，那么反过来，他人也会是这样的。如果你想在开源贡献中获得成功，你就要有足够的自信来相信自己坚持的立场和事物，当然了，你要以一种可以让人接受的方式来表现，同时还要包容其他的意见和观点。领导者的标志就是，在生活中塑造他们想要看到的形象，而不管是否有他人模仿。

那么，你是否有其他增强自信的方法呢？记得在评论区告诉我们哦。

（题图：[Gabriel Kamener, Sown Together](https://www.flickr.com/photos/42647587@N06/) 原创，经 Jen Wike Huger 修改。）

---

作者简介：

Laura Hilliger - 艺术家、教育事业者、作家、技术专家。她是一个多媒体设计师和开发者、技术联络员、项目经理、一个开放且喜欢协作环境的网络黑客。她主张变革，目前为发展壮大绿色和平组织而辛勤工作。Alum @Mozilla，UC Berkeley，BAVC， Adobe。Twitter @epilepticrabbit 。

---

译者简介：

[GHLandy](http://GHLandy.com) —— <ruby> 欲得之，则为之奋斗。 <rp>  （ </rp> <rt>  If you want it, work for it. </rt> <rp>  ） </rp></ruby>

---

via: <https://opensource.com/article/17/1/3-ways-improve-your-confidence>

作者：[Laura Hilliger](https://opensource.com/users/laurahilliger) 译者：[GHlandy](https://github.com/GHlandy) 校对：[Bestony](https://github.com/Bestony)

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


更快的机器学习即将来到 Linux 内核

然后在我们这个世界的某一天，skynet 正式通过加载 LInux 内核的电脑上线？

得益于自由开源生态环境，Linux内核的进化一直进行中。。。

原文标题有问题。内核只是加了HMM功能，并没有加入机器学习，是HMM有利于机器学习提高性能。

GPU驱动是LINUX的痛啊

>
> Linux 内核新增的异构内存管理将解锁加速 GPU 的新途径，并挖掘其它的机器学习硬件的潜能
>
>
>

![更快的机器学习正在来到你身边的 Linux 内核](/data/attachment/album/201706/09/095208u5to9y7oybtoy7zp.jpg)

一项开发了很久的内存管理技术将会给机器学习和其它 GPU 驱动的程序很大幅度的提升，而它也将在接下来的几个版本中进入 Linux 内核。

异构内存管理（HMM）可以允许设备驱动为在其自身内存管理下的进程镜像地址空间。正如红帽的开发者 Jérôme Glisse [所解释的](https://lkml.org/lkml/2017/4/21/872)，这让像 GPU 这样的硬件设备可以直接访问进程内存，而不用花费复制带来的额外开销。它还不违反现代操作系统提供的内存保护功能。

一类会从 HMM 中获益最多的应用是基于 GPU 的机器学习。像 OpenCL 和 CUDA 这样的库能够从 HMM 中获得速度的提升。HMM 实现这个的方式和[加速基于 GPU 的机器学习](http://www.infoworld.com/article/3195437/machine-learning-analytics-get-a-boost-from-gpu-data-frame-project.html)相似，就是让数据留在原地，靠近 GPU 的地方，在那里直接操作数据，尽可能少地移动数据。

像这样的加速对于 CUDA（英伟达基于 GPU 的处理库）来说，只会有益于在英伟达 GPU 上的操作，这些 GPU 也是目前加速数据处理的主要硬件。但是，OpenCL 设计用来编写可以针对多种硬件的代码——CPU、GPU、FPGA 等等——随着这些硬件的成熟，HMM 能够提供更加广泛的益处。

要让 Linux 中的 HMM 处于可用状态还有一些阻碍。第一个是内核支持，在很长一段时间里都受到限制。[早在 2014](https://lwn.net/Articles/597289/)年，HMM 最初作为 Linux 内核补丁集提出，红帽和英伟达都是关键开发者。需要做的工作不少，但是开发者认为代码可以提交上去，也许接下来的几个内核版本就能把它包含进去。

第二个阻碍是显卡驱动支持，英伟达一直在自己单独做一些工作。据 Glisse 的说法，AMD 的 GPU 可能也会支持 HMM，所以这种特殊优化不会仅限于英伟达的 GPU。AMD 一直都在尝试提升它的 GPU 市场占有率，有可能会[将 GPU 和 CPU 整合](http://www.infoworld.com/article/3099204/hardware/amd-mulls-a-cpugpu-super-chip-in-a-server-reboot.html)到同一模具。但是，软件生态系统依然更青睐英伟达；要使其兑现，还需要更多的像 HMM 这样的中立项目，以及让 OpenCL 提供和 CUDA 相当的性能。

第三个阻碍是硬件支持，因为 HMM 的工作需要一项称作<ruby> 可重现页面故障 <rp>  （ </rp> <rt>  replayable page faults </rt> <rp>  ） </rp></ruby>的硬件特性。只有英伟达的帕斯卡系列高端 GPU 才支持这项特性。从某些意义上来说这是个好消息，因为这意味着英伟达只需要提供单一硬件的驱动支持就能让 HMM 正常使用，工作量就少了。

一旦 HMM 到位，对于提供 GPU 实例的公有云提供商就会面临压力，他们需要[支持最新最好一代的 GPU](http://www.infoworld.com/article/3126076/artificial-intelligence/aws-machine-learning-vms-go-faster-but-not-forward.html)。这并不是仅仅将老款的开普勒架构显卡换成最新的帕斯卡架构显卡就行了，因为后续的每一代显卡都会更加优秀，像 HMM 这样的支持优化将提供战略优势。

（题图：Thinkstock）

---

via: <http://www.infoworld.com/article/3196884/linux/faster-machine-learning-is-coming-to-the-linux-kernel.html>

作者：[Serdar Yegulalp](http://www.infoworld.com/author/Serdar-Yegulalp/) 译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


Linux 基金会宣布在华建立正式分支机构

Summary: 在 LinuxCon 2017 （北京）即将召开前夕，我们 Linux 中国会同 51CTO、开源中国对 Linux 基金会执行董事 Jim Zemlin 进行了一场远跨大洋的视频专访。

哈哈哈，老王。为什么不是 wxy 了？

哈哈哈，因为老了~~<br />
:-D

老王up up

Linux在中国肯定比其他国家更好，因为中国法律不认可GPL，公司能用代码赚钱养程序员。------我瞎评论的

Where is wxy ? Who is wxy ?

Jim Zemlin。。。真正的粉丝一定会眼花的。。。

那个光头~

Old King: Linux的专题活动，没使用Linux操作系统的本本吗？

汗，我好像应该带头才对——该换个本子了。

![](/data/attachment/album/201706/09/155244eod0bmoi0eemizto.jpg)

>
> 专访 Linux 基金会执行董事 Jim Zemlin
>
>
>

在 LinuxCon 2017 （北京）即将召开前夕，我们Linux 中国会同 51CTO、开源中国对 [Linux 基金会](http://linuxfoundation.org/)执行董事 Jim Zemlin 进行了一场远跨大洋的视频专访。

在这次专访中，Jim 先生回答了几个开源界和互联网领域关注的问题，并披露了一些有趣的消息和数据。

![Linux 基金会执行董事 Jim Zemlin](/data/attachment/album/201706/09/155304itv6is0toogd707h.jpg)

首先，Jim 先生对 [LinuxCon + ContainerCon + CloudOpen 大会（以下简称 LC3）](https://www.lfasiallc.com/linuxcon-containercon-cloudopen-china)的情况做了介绍：

>
> 首先感谢大家能够出席我们今天的这个活动。先给大家介绍一下我们 LC3 大会。LC3 大会是我们第一次在中国举办这样的活动。在这次活动上，我们邀请到了一些开源界的领袖一起来到中国。
>
>
> 我们可以看到开源在过去这几年在全球都实现了可持续的增长，无论是在云计算，还是在汽车领域，还是在其他的领域。我们也看到中国越来越多地参与到了开源的发展过程中。
>
>
> 在这次活动上，Linux 基金会创始人 Linus Torvalds 会应邀首次访问中国，同时，我们也会邀请一些开源和技术方面的领袖人物来到中国，与中国的开发者和使用 Linux 基础设施的企业，一起来探讨开源方面的事宜。包括 [OpenStack](http://www.openstack.org/) 的项目执行董事、 [Kubernetes](https://kubernetes.io/) 项目的负责人。还有 [hyperledger](https://www.hyperledger.org/)，这是一个在区块链方面的项目，我们也邀请到了它的执行董事。以及 [Open Networking 基金会](https://www.opennetworking.org/)的代表。此外还包括一些大型企业的代表，比如说中国的华为、阿里巴巴、百度等这些企业也会参加这次活动；国外的像 Google、IBM、Amazon 等等这些企业也会来参加这次活动。
>
>
> 我们希望这次活动可以给中国这些利用 Linux 来开发解决方案的企业和组织提供了一个绝佳的机会，让他们可以和世界上一些领先的开源项目开发者或者是负责人一起聊一聊。
>
>
> 我们可以看到 Linux 在中国还是应用得非常广泛的，像阿里云，还有华为的一些产品，包括腾讯、百度，事实上他们都在广泛地使用 Linux，所以说这次活动可以为国内的企业和国内开源方面领先的开发者以及国外领先的开源方面的开发者架设一个桥梁，一起来探讨开源方面的话题。
>
>
>

在之后长达一个小时的采访中，我们还向 Jim 先生提到了若干感兴趣的问题，现将其中一些问题摘录如下：

**1、[LinuxCon](https://www.lfasiallc.com/linuxcon-containercon-cloudopen-china)** **是** **Linux** **基金会第一次高调在中国开展的大型活动，我想了解，这是否代表着** **Linux** **基金会正式地在中国开展活动？如果** **Linux** **基金会加大在中国国内的活动力度，主要的工作方向是建立政府、企业的合作关系呢？还是会扶植和联合高校社团、****LUG****、开源社区这样的团体呢？是否会进一步在中国国内设立正式的分支机构乃至人员？**

*Jim：*

实际上我们去年已经开始在中国建立了一个我们自己的机构。

历史上我们主要和一些开源的企业先开展合作，比如说华为、中国移动；也会和一些本地的社区组织机构开展合作。当然，我们还是希望能够不断地扩展我们在中国的活动，特别是在网络和云计算领域。在网络方面，我们与中国三大电信运营商，包括中国移动、中国电信、中国联通，以及中兴、华为等展开了合作。在云计算方面，我们有[云原生（CNCF）](https://www.cncf.io/)的一些项目，主要是和阿里云、腾讯、百度等三家大的公司来开展合作。

**2、在当前的互联网、移动互联网和物联网迅猛发展形势下，我们面临的安全威胁越来越多，越来越广泛，比如说近年来的几次重大安全事件，从<ruby> 破壳 <rp>  （ </rp> <rt>  Shellshock </rt> <rp>  ） </rp></ruby>****、<ruby> 心血 <rp>  （ </rp> <rt>  heartbleed </rt> <rp>  ） </rp></ruby>****，到最近的** **SMB** **的几个病毒，都给互联网和社会造成了很大影响。那么** **Linux** **的安全性是否能够胜任面对安全的攻击，乃至阻止和遏制安全风险所带来的威胁？** **Linux** **基金会在指导** **Linux** **发展的方向上，是否会把安全性放在功能性之上？****Jim** **先生您是如何看待这个问题的？**

*Jim：*

其实如果要在安全方面拿 Linux 和 Windows 相比，我觉得不是太准确。因为从安全的角度来说你要开发任何一个比较复杂的软件系统，只要这个系统一复杂，就难免会有安全漏洞。

从安全性的角度来看，Linux 这个软件的开发过程，它实际上会有成千上万个开源开发者对它的安全性进行审议，所有的这些代码实际上我们会经过一个“同行审议”的过程，通过这样一些做法和流程可以保证开发出来的 Linux 软件是安全的。

所以，在我们 Linux 开发的过程中，我们希望能够建立一些安全代码的规范。我们启动了 CoreOS 这样一些项目，主要是希望能够帮助我们开发出安全的可靠的软件，这些代码可以经过审计，能够保证我们开发出来的代码是最安全的。总而言之，安全是我们包括 Linux 在内的所有的项目的重中之重，非常关注的、重视的一个问题。

**3、Linux** **与人工智能、云技术、物联网等的结合会在近期进入爆发阶段吗？**

*Jim：*

在云计算方面，像大家都比较熟知的 Kubernetes，它的发展得是非常非常快的，也是参与的开发者非常多的。我们了解到有 380 家企业和 2500 多名开发者在致力于 Kubernetes 的开发，在 GitHub 的仓库中已经有近 5 万个提交和 8000 个 fork。所以，我们可以看到这个规模是非常非常大的。顺便说一句，Kubernetes 的执行董事三周后也会来中国给大家介绍 Kubernetes 发展的情况。

除了在云计算，我们在物联网的项目方面，比如说我们的 [EdgeX](http://www.edgexfoundry.org/) 项目和 IoT 的项目，这些也是有很多开源的项目的，像人工智能、云计算或者是物联网，我们在中国举办的这些活动会越来越多，我们在中国的布局也会扩大，大家参加我们的大会可以了解到这些领域的更多信息。

**4、越来越多的企业都加入代码贡献中，这对于** **Linux** **的发展与推动带来哪些变化？**

*Jim：*

新的企业和新的机构加入到 Linux 的活动当中，会给 Linux 带来更多的价值。比如说上周在日本丰田宣布它卖得最好的凯美瑞汽车会使用 Linux 系统。汽车行业加入 Linux 意味着他们对我们 Linux 的内核会提出新的要求，对那些为嵌入式系统开发解决方案的这些厂商来说也是很好的消息，因为加入 Linux 意味着他们的测试覆盖范围更大了，有更多的人对这个代码进行审议。

总的来说，我们觉得越多的企业和组织架构加入到 Linux 的阵营，实际上对我们 Linux 的发展是越好的。

**5、您认为开源与人工智能碰撞将出现什么样的火花？**

*Jim：*

谈到人工智能，实际上所有的基础设施都需要人工智能的应用。在人工智能的开源项目，现在最大的是谷歌领导的 [TensorFlow](http://www.tensorflow.org/) 这个项目，本次大会我们也邀请到了一些嘉宾会就这方面的内容做一些介绍。

**6、中国有越来越多的开发者加入了开源，但是在** **GitHub** **上来自中国的高质量开源很少，大部分都是来自于国外，您认为，要实现高质量的开源软件，需要具备哪些环境和条件？**

*Jim：*

实际上我们也看到中国有一些高质量的开源的项目也在不断地发展。去年我们与华为和中国移动宣布了一个开源的项目，后来又有中国电信和中国联通的加入，再后来又有一些国际运营商，像 AT&T 和 Orange 也加入了，和中国一些企业共同联手，希望能够建立世界上最大的开源的电信类基础设施。

中国的开源项目和美国相比数量不够多，第一个就是历史原因，因为在美国软件开发的历史比中国要长一些。但是我们可以看到中国也在大步地迎头赶上。我们之所以在中国举办 LC3 大会也是希望让全世界顶尖的开发者和中国的一些企业、一些顶尖的开发者能够共同坐在一起进行探讨，分享最佳实践，我们相信未来中国会有更多的自主的开源的项目。

我们也知道我们 Linux 创始人 Linus Torvalds 也会来到中国，也会和中国这些开源的开发者进行很好地交流，希望能够推动中国的开源项目不断地发展和扩展。

我觉得这次 LC3 大会是一次难得的机会，因为它让全球领先的开发者齐聚一堂。举个例子，一个精英开发者和一个普通的软件开发者的区别能大到什么程度？就像毕加索和一个普通家里面的画家一样，有这样大的一个区别。所以，这次盛会给大家提供了一个很好的机会和世界上最优秀的开发和计算方面的专家共同探讨问题，我们也希望通过这次活动让大家了解到怎么样更好地利用开源来开发新的产品和服务，我们也致力于和中国的这些开发者和行业进行密切地合作，开发出来更多的可以带来价值的开源的代码。

---

经过了一个小时的面对面沟通，我们了解到 Linux 基金会有志于在中国开展更多、更高层次的交流与合作，为在中国推动开源和技术进步而创造更好的环境。

让我们期待 Jim、Linus 以及更多的开源领袖的到来，在 LC3 大会与大家分享开源和技术进步的经验和体会。

我们也将全程跟踪 LC3大会的消息，并及时分享重要技术信息给大家，敬请期待。

Linux 中国，老王报道于北京

2017 年6 月 9 日


教职人员是否可以运用维基百科教学？

说的都好，墙住了。咋办。哈哈哈

污染了DNS，没有封IP~~改host就行

![](/data/attachment/album/201706/09/221423ncwpjiz43vcs3ipb.png)

自从 2010 年，已经有 29000 个学生完成了 Wiki Ed 这一项目。他们在维基百科上添加了 2500 万词条，相当于 85000 页纸张的内容。这相当于最新出版的 Britannica 百科全书中全部词条的 66%。Wiki Ed 的学生们最积极的时候，他们贡献了维基百科上 10% 的内容， 极大地补充了贫乏的学术板块。

为了了解更多关于这个项目的信息，我联络了 LiAnna Davis -- Wiki Ed 项目的负责人。他极富热情地同意来回答我的问题。

提示：[Wiki 教育基金会 (Wiki Ed)](https://wikiedu.org/) 的平台是用自由软件搭建的，你可以在这里找到： [WikiEdu Dashboard GitHub](https://github.com/WikiEducationFoundation/WikiEduDashboard)。

**Wiki Ed 这一项目是如何启动的？说说你的背景以及你是如何参与进这个项目的。**

在2010年，[维基基金会](https://wikimediafoundation.org/wiki/Home)（简称 WMF，运营维基百科的非营利组织）注意到了一个趋势 -- 大学的教职人员如果本身也是维基词条的编辑者，会成功地将编辑维基词条作为一项任务交给了自己课堂里的学生。WMF 就此开展了一个试行项目试图解决这个问题：如果本身不编辑维基词条的教职人员支持课程中包含维基词条的编辑任务，他们是否可以通过维基百科实现教学呢？

我是这个团队的一员，在 2010 年被试行雇用，我对这个问题的回答是：“可以。” 在 2013年，WMF 将这个项目的美国分部和加拿大分部拆分，形成了一个新的非营利性组织 -- 维基教育基金会（ Wiki Ed）；自此我也从 WMF 到了Wiki Ed。自那以后我们便成为了一个独立组织，我们可以专注于这个项目并且将这个项目拓展开来 -- 起初 WMF 时期每年只有 75 个班级参与，而这个学期已经有 275 班级参与了 Wiki Ed。

**人们总是觉得大学生对科技相关的一切事物都很敏感，尤其是互联网，但是你们的网站上写道，“大学本科学生可能具有高科技敏感度，但这并不代表他们具有数字信息素养。” 你可以稍微解释一下这句话吗？**

仅仅因为一个人可以搞明白自己的 iPhone 如何使用不代表他们可以明辨他们在网上阅读的信息是否值得信赖。 [斯坦福的一项研究](https://sheg.stanford.edu/upload/V3LessonPlans/Executive%20Summary%2011.21.16.pdf) (“评估信息：公民在线推理的基石 November 22, 2016.”)在近期表明：学生们并不具有数字信息素养。然而，当学生们在撰写维基百科文章之时，他们必须这样。他们需要严格遵守维基百科的[可信来源](https://en.wikipedia.org/wiki/Wikipedia:Identifying_reliable_sources) 规范，这些规范明确了维基百科上的任何信息都必须注明来源，这些来源必须是独立的，而且是可以追溯的事实。对于很多学生，这样注明来源还是第一次，多数人之前仅仅是通过谷歌搜索话题或者注明他们亲眼所见的第一手资料来进行资料的检索和查证。他们需要理解哪些资料可靠，哪些资料不可靠，从而成为足够成熟的电子信息消费者。

**你想对那些声称“维基百科不是一个可靠的来源”的人说些什么？**

维基百科是一本百科全书，根据在词典中的定义，它是一个第三手资料。当学生们开始读本科的时候，他们应该学会参考一手和二手资料，而不是第三手资料，因此学生不应该，且不能引用维基百科的内容。但是维基百科在研究之初会是一个不错的选择，它可以给你对这个话题一个广泛的认识，并且帮你发现页面底部那些你可以参考的文章来源。就像我们所鼓励的：“不要引用！用你的语言写！”

>
> 这样做可以让学生们代入知识生产者的身份，而不是知识的消费者……
>
>
>

**一个教授在 Wiki Ed 项目中的参与是如何影响到他的学生的呢？**

通过运用维基百科教学，导师们可以给学生们提供有价值的媒体素养、批判性思维、线上交流以及写作能力，不论他们在毕业之后会继续选择科研或是加入工作大军，这些极富价值的品质和技能都能帮助他们成功。这样做可以让学生们代入知识生产者的身份，而不是知识的消费者，而且这可以给予他们一个真正在这个世界做出改变的机会，而不是学生们到了学期末便会抛之脑后的生硬习题。

我们正在积极鼓励新的班级在春季学期加入这个项目。感兴趣的教职人员可以点击 [维基教育基金会的教学页](https://teach.wikiedu.org/) 由此开始。

**一个教师会需要哪些职业素养来参与这个项目？学生又是需要哪些训练呢？**

当你在[维基教育基金会的教学页](http://teach.wikiedu.org/)上注册的时候，你会发现 Wiki Ed 为新加入的教职人员提供了如何运用维基百科实现教学的在线指南。我们还有为学生提供的一系列的在线训练，根据他们不同的任务自动分配不同的指南（例如，如果你希望你的学生在文章中插入图片，他们会得到一个如何插入编辑图片的教学单元，如果你不需要，他们便不会得到这个单元的指南）。在部分十几个学科中，我们还有特定的指南书展示了这几个学科的特定编辑方式。除此之外，我们还有熟练维基百科编辑的工作人员帮助回答学生和导师们的问题。我们的系统已经在逐步扩大；我们在这个秋季学期已经支持了超过 6300 个学生，并且已经适应了与没有维基编辑经验的教职人员合作，因此这样就保证了没有人会因为资历不够而无法参与。

**“<ruby> 访问学者 <rt>  Visiting Scholars </rt></ruby>”这个项目是指？**

我们正在试着建立学术界和维基百科之间的联系，而鼓励运用维基百科教学的项目只是其中的一环。在“<ruby> 访问学者 <rt>  Visiting Scholars </rt></ruby>”这一项目中，大学图书馆或者教学部门将公开他们的资料，并提供给一个缺乏资料的认证的维基百科编辑人员（被称作是“访问学者”）。通过大学这一渠道，“访问学者”们可以有机会使用这些资源来完善维基百科广泛领域中的文章。这是一个规模相对小却伟大的项目，因为我们花了很多时间来建立这样的联系，但是这些“学者”们都产出了许多真的很精彩的内容。

**你的合作伙伴有谁？他们的参与如何影响到你现在的成功呢，或者在未来将会如何呢？**

我们与那些将我们工作的价值看做对他们的学科的一种服务的学术机构合作。让我们面对这个现实：当人们想要获取关于一个话题的知识之时，他们不会去读那些同行审议过，并在这些机构发表的学术论文，他们会去维基百科。通过鼓励这些机构中的教职人员用维基百科教学，正可以完善维基百科的在这些学科中的内容和信息。我们的合作伙伴扩充了我们的潜在成员，并且让我们以合作身份大量完善了维基百科上特定学科的内容。

我们欢迎读者点击这个[支持我们](http://wikiedu.org/donate) 的页面通过捐赠来支持我们的工作。

（题图：opensource.com）

---

作者简介：

Don Watkins 是一个教育家，专注教育技术，创业家，开源提倡者。教育心理学硕士、教育领导力硕士、Linux 系统管理员、思科认证网络支持工程师、Virtual Box 虚拟化认证。关注他： @Don\_Watkins 。

---

via: <https://opensource.com/article/17/1/Wiki-Education-Foundation>

作者：Don Watkins 译者：[scoutydren](https://github.com/scoutydren) 校对：[Bestony](https://github.com/Bestony)

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


Linux 系统中修复 SambaCry 漏洞（CVE-2017-7494）

Summary: 这个问题在 Samba 网站上被描述为 CVE-2017-7494，并且已知会影响 Samba v3.5（2010 年 3 月初发布）及以后版本。由于与 WannaCry 有相似之处，它被非官方地被命名为 SambaCry：它们均针对 SMB 协议，并且可能是蠕虫病毒 - 这可能导致其从一个系统传播到另一个系统中。

开启SELinux之后是不是就没事了？

![](/data/attachment/album/201706/10/095734grkg01cz9rnrclnk.png)

Samba 很久以来一直是为 \*nix 系统上的 Windows 客户端提供共享文件和打印服务的标准。家庭用户，中型企业和大型公司都在使用它，它作为最佳解决方案在多种操作系统共存的环境中脱颖而出。

由于广泛使用的工具很可能发生这种情况，大多数 Samba 安装都面临着可能利用已知漏洞的攻击的风险，这个漏洞直到 WannaCry 勒索软件攻击的新闻出来之前都被认为是不重要的。

在本文中，我们将解释这个 Samba 漏洞是什么以及如何保护你负责的系统。根据你的安装类型（从仓库或者源码），你需要采取不同的方法。

如果你目前有在任何环境中使用 Samba 或者知道有人在使用，请继续阅读！

### 漏洞

过时和未修补的系统容易受到远程代码执行漏洞的攻击。简单来说，这意味着访问可写共享的人可以上传一段任意代码，并使用服务器中的 root 权限执行该代码。

这个问题在 Samba 网站上被描述为 [CVE-2017-7494](https://www.samba.org/samba/security/CVE-2017-7494.html)，并且已知会影响 Samba v3.5（2010 年 3 月初发布）及以后版本。由于与 WannaCry 有相似之处，它被非官方地被命名为 SambaCry：它们均针对 SMB 协议，并且可能是蠕虫病毒 - 这可能导致其从一个系统传播到另一个系统中。

Debian、Ubuntu、CentOS 和 Red Hat 已采取快速的行动来保护它们的用户，并为其支持的版本发布了补丁。另外，还提供了不受支持的安全临时解决方案。

### 更新 Samba

如先前提到的那样，根据你之前安装的方法有两种方式更新：

#### 如果你从发行版的仓库中安装的 Samba

让我们看下在这种情况下你需要做什么：

**在 Debian 下修复 SambaCry**

添加下面的行到你的源列表中（`/etc/apt/sources.list`）以确保 apt 能够获得最新的安全更新：

```
deb http://security.debian.org stable/updates main
deb-src http://security.debian.org/ stable/updates main

```

接下来，更新可用的软件包：

```
# aptitude update

```

最后，确保 samba 软件包的版本符合漏洞修复的版本（见 [CVE-2017-7494](https://security-tracker.debian.org/tracker/CVE-2017-7494)）：

```
# aptitude show samba

```

![Fix Sambacry in Debian](/data/attachment/album/201706/10/095739iatdzb40jdk4pbzl.png)

*在 Debian 中修复 SambaCry*

**在 Ubuntu 中修复 SambaCry**

要开始修复，如下检查新的可用软件包并更新 Samba 软件包：

```
$ sudo apt-get update
$ sudo apt-get install samba

```

已经修复 CVE-2017-7494 的 Samba 版本有下面这些：

* 17.04: samba 2:4.5.8+dfsg-0ubuntu0.17.04.2
* 16.10: samba 2:4.4.5+dfsg-2ubuntu5.6
* 16.04 LTS: samba 2:4.3.11+dfsg-0ubuntu0.16.04.7
* 14.04 LTS: samba 2:4.3.11+dfsg-0ubuntu0.14.04.8

最后，运行下面命令验证你的 Ubuntu 已经安装了正确的版本。

```
$ sudo apt-cache show samba

```

**在 CentOS/RHEL 7 中修复 SambaCry**

在 EL 7 中打过补丁的 Samba 版本是 samba-4.4.4-14.el7\_3。要安装它，这些做：

```
# yum makecache fast
# yum update samba

```

像先前那样，确保你已经安装了打补丁的 Samba 版本：

```
# yum info samba

```

![Fix Sambacry in CentOS](/data/attachment/album/201706/10/095740l8j3383hjnhmd8ac.png)

*在 CentOS 中修复 SambaCry*

旧支持的 CentOS 以及 RHEL 更老的版本也有修复。参见 [RHSA-2017-1270](https://rhn.redhat.com/errata/RHSA-2017-1270.html) 获取更多。

#### 如果你从源码安装的 Samba

注意：下面的过程假设你先前从源码构建的 Samba。强烈建议你在部署到生产服务器之前先在测试环境尝试。

此外，开始之前确保你备份了 `smb.conf` 文件。

在这种情况下，我们也会从源码编译并更新 Samba。然而在开始之前，我们必须先确保安装了所有的依赖。注意这也许会花费几分钟。

**在 Debian 和 Ubuntu 中：**

```
# aptitude install acl attr autoconf bison build-essential \
debhelper dnsutils docbook-xml docbook-xsl flex gdb krb5-user \
libacl1-dev libaio-dev libattr1-dev libblkid-dev libbsd-dev \
libcap-dev libcups2-dev libgnutls28-dev libjson-perl \
libldap2-dev libncurses5-dev libpam0g-dev libparse-yapp-perl \
libpopt-dev libreadline-dev perl perl-modules pkg-config \
python-all-dev python-dev python-dnspython python-crypto xsltproc \
zlib1g-dev libsystemd-dev libgpgme11-dev python-gpgme python-m2crypto

```

**在 CentOS 7 或相似的版本中：**

```
# yum install attr bind-utils docbook-style-xsl gcc gdb krb5-workstation \
libsemanage-python libxslt perl perl-ExtUtils-MakeMaker \
perl-Parse-Yapp perl-Test-Base pkgconfig policycoreutils-python \
python-crypto gnutls-devel libattr-devel keyutils-libs-devel \
libacl-devel libaio-devel libblkid-devel libxml2-devel openldap-devel \
pam-devel popt-devel python-devel readline-devel zlib-devel

```

停止服务（LCTT 译注：此处不必要）：

```
# systemctl stop smbd

```

下载并解压源码（在写作时 4.6.4 是最新的版本）：

```
# wget https://www.samba.org/samba/ftp/samba-latest.tar.gz
# tar xzf samba-latest.tar.gz
# cd samba-4.6.4

```

出于了解信息的目的，用以下命令检查可用的配置选项。

```
# ./configure --help

```

如果你在先前的版本的构建中有使用到一些选项，你或许可以在上面命令的返回中包含一些选项，或者你可以选择使用默认值：

```
# ./configure
# make
# make install

```

最后重启服务。

```
# systemctl restart smbd

```

并验证你正在使用的是更新后的版本：

```
# smbstatus --version

```

这里返回的应该是 4.6.4。

### 其它情况

如果你使用的是不受支持的发行版本，并且由于某些原因无法升级到最新版本，你或许要考虑下面这些建议：

* 如果 SELinux 是启用的，你是处于保护之下的！
* 确保 Samba 共享是用 `noexec` 选项挂载的。这会阻止二进制文件从被挂载的文件系统中执行。

还有将：

```
nt pipe support = no

```

添加到 `smb.conf` 的 `[global]` 字段中。你或许要记住，根据 Samba 项目，这“或许禁用 Windows 客户端的某些功能”。

重要：注意 `nt pipe support = no` 选项会禁用 Windows 客户端的共享列表。比如：当你在一台 Samba 服务器的 Windows Explorer 中输入 `\\10.100.10.2\` 时，你会看到 “permission denied”。Windows 客户端不得不手动执行共享，如 `\\10.100.10.2\share_name` 来访问共享。

### 总结

在本篇中，我们已经描述了 SambaCry 漏洞以及如何减轻影响。我们希望你可以使用这个信息来保护你负责的系统。

如果你有关于这篇文章的任何提问以及评论，欢迎使用下面的评论栏让我们知道。

---

作者简介：

Gabriel Cánepa 是一名 GNU/Linux 系统管理员，阿根廷圣路易斯 Villa Mercedes 的 web 开发人员。他为一家国际大型消费品公司工作，在日常工作中使用 FOSS 工具以提高生产力，并从中获得极大乐趣。

---

via: <https://www.tecmint.com/fix-sambacry-vulnerability-cve-2017-7494-in-linux/>

作者：[Gabriel Cánepa](https://www.tecmint.com/author/gacanepa/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（21）：安卓 4.2，果冻豆——全新 Nexus 设备，全新平板界面

![](/data/attachment/album/201706/10/202024st8wqmeozzwuaszj.jpg)

### 安卓 4.2，果冻豆——全新 Nexus 设备，全新平板界面

安卓平台成熟的脚步越来越快，谷歌也将越来越多的应用托管到 Play 商店，需要通过系统更新来更新的应用越来越少。但是不间断的更新还是要继续的，2012 年 11 月，安卓 4.2 发布。4.2 还是叫做“果冻豆”，这个版本主要是一些少量变动。

![](/data/attachment/album/201706/10/201447mshxbrrr77s79aap.jpg)

*LG 生产的 Nexus 4 和三星生产的 Nexus 10。 [Google/Ron Amadeo 供图]*

和安卓 4.2 一同发布的还有两部旗舰设备，Nexus 4 和 Nexus 10，都由谷歌直接在 Play 商店出售。Nexus 4 使用了 Nexus 7 的策略，令人惊讶的低价和高质量，并且无锁设备售价 300 美元。Nexus 4 有一个 4 核 1.5GHz 骁龙 S4 Pro 处理器，2GB 内存以及 1280×768 分辨率 4.7 英寸 LCD 显示屏。谷歌的新旗舰手机由 LG 生产，并和制造商一起将关注点转向了材料和质量。Nexus 4 有着正反两面双面玻璃，这会让你爱不释手，它是有史以来触感最佳的安卓手机之一。Nexus 4 最大的缺点是没有 LTE 支持，那时候大部分手机，包括 Version Galaxy Nexus 都有更快的基带。但 Nexus 4 的需求仍大大超出了谷歌的预料——发布当日大量的流量拖垮了 Play 商店网站。手机在一小时之内销售一空。

Nexus 10 是谷歌的第一部 10 英寸 Nexus 平板。该设备的亮点是 2560×1600 分辨率的显示屏，在这个等级上是分辨率最高的。这背后是双核 1.7GHz Cortex A15 处理器和 2GB 内存的强力支持。随着时间一个月一个月地流逝，Nexus 10 似乎逐渐成为了第一部也是最后一部 10 英寸 Nexus 平板。通常这些设备每年都升级，但 Nexus 10 至今面世 16 个月了，可预见的未来还没有新设备的迹象。谷歌在小尺寸的 7 英寸平板上做得很出色，它似乎更倾向于让[像三星](http://arstechnica.com/gadgets/2014/01/hands-on-with-samsungs-notepro-and-tabpro-new-screen-sizes-and-magazine-ui/)这样的合作伙伴探索更大的平板家族。

![](/data/attachment/album/201706/10/201527ftbytzwvhbb7bu7l.jpg)

*新的锁屏，壁纸，以及时钟小部件设计。 [Ron Amadeo 供图]*

4.2 为锁屏带来了很多变化。文字居中，并且对小时使用了较大的字重，对分钟使用了较细的字体。锁屏现在是分页的，可以自定义小部件。锁屏不仅仅是一个简单的时钟，用户还可以将其替换成其它小部件或者添加额外的页面和更多的小部件。

![](/data/attachment/album/201706/10/201605ry0p0yy67y79y11a.jpg)

*锁屏的添加小部件页面，小部件列表，锁屏上的 Gmail 部件，以及滑动到相机。 [Ron Amadeo 供图]*

锁屏现在就像是一个精简版的主屏幕。页面轮廓会显示在锁屏的左右两侧来提示用户可以滑动到有其他小部件的页面。向左滑动页面会显示一个中间带有加号的简单空白页面，点击加号会打开兼容锁屏的小部件列表。锁屏每个页面限制一个小部件，将小部件向上或向下拖动可以展开或收起。最右侧的页面保留给了相机——一个简单的滑动就能打开相机界面，但是你没办法滑动回来。

![](/data/attachment/album/201706/10/201649rs3lcsij9u39if93.jpg)

*新的快速设置面板以及内置应用集合。 [Ron Amadeo 供图]*

4.2 最大的新增特性之一就是“快速设置”面板。安卓 3.0 为平板引入了快速改变电源设置的途径，4.2 终于将这种能力带给了手机。通知中心右上角加入了一枚新图标，可以在正常的通知列表和新的快速设置之间切换。快速设置提供了对屏幕亮度、网络连接、电池以及数据用量更加快捷的访问，而不用打开完整的设置界面。安卓 4.1 中顶部的设置按钮移除掉了，快速设置中添加了一个按钮来替代它。

应用抽屉和 4.2 中的应用阵容有很多改变。得益于 Nexus 4 更宽的屏幕横纵比（5:3，Galaxy Nexus 是 16:9），应用抽屉可以显示一行五个应用图标的方阵。4.2 将自带的浏览器替换为了 Google Chrome，自带的日历换成了 Google Calendar，它们都带来了新的图标设计。时钟和相机应用在 4.2 中经过了重制，新的图标也是其中的一部分。“Google Settings”是个新应用，用于提供对系统范围内所有存在的谷歌账户设置的快捷方式，它有着和 Google Search 和 Google+ 图标一致的风格。谷歌地图拥有了新图标，谷歌纵横，以往是谷歌地图的一部分，作为对 Google+ location 的支持在这个版本退役。

![](/data/attachment/album/201706/10/201730b86ij3thmm86ijc8.jpg)

*浏览器替换为 Chrome，带有全屏取景器的新相机界面。 [Ron Amadeo 供图]*

原来的自带浏览器在一段时间内对 Chrome 的模仿上下了不少功夫——它引入了许多 Chrome 的界面元素，许多 Chrome 的特性，甚至还使用了 Chrome 的 javascript 引擎——但安卓 4.2 来临的时候，谷歌认为安卓版的 Chrome 已经准备好换下这个模仿者了。表面上看起来没有多大不同；界面看起来不一样，而且早期版本的 Chrome 安卓版滚动起来没有原浏览器顺畅。不过从深层次来说，一切都不一样。安卓的主浏览器开发现在由 Google Chrome 团队负责，而不是作为安卓团队的子项目存在。安卓的默认浏览器从绑定安卓版本发布、停滞不前的应用变成了不断更新的 Play 商店应用。现在甚至还有一个每个月接收一些更新的 beta 通道。

相机界面经过了重新设计。它现在完全是个全屏应用，显示摄像头的实时图像并且在上面显示控制选项。布局审美和安卓 1.5 的[相机设计](http://cdn.arstechnica.net/wp-content/uploads/2013/12/device-2013-12-26-11016071.png)有很多共同之处：带对焦的最小化的控制放置在取景器显示之上。中间的控制环在你长按屏幕或点击右下角圆形按钮的时候显示。你的手指保持在屏幕上时，你可以滑动来选择环上的选项，通常是展开进入一个子菜单。在高亮的选项上释放手指选中它。这灵感很明显来自于安卓 4.0 浏览器中的快速控制，但是将选项安排在一个环上意味着你的手指几乎总会挡住一部分界面。

![](/data/attachment/album/201706/10/201807esf0wr00etf4nfts.jpg)

*时钟应用，从一个只有两个界面的应用变成功能强大，实用的应用。 [Ron Amadeo 供图]*

时钟应用经过了完整的改造，从一个简单的两个界面的闹钟，到一个世界时钟、闹钟、定时器，以及秒表俱全。时钟应用的设计和谷歌之前引入的完全不同，有着极简审美和红色高亮。它看起来像是谷歌的一个试验。甚至是几个版本之后，这个设计语言似乎也仅限于这个应用。

时钟的时间选择器是经过特别精心设计的。它显示一个简单的数字盘，会智能地禁用会导致无效时间的数字。设置闹钟时间也不能在没有明确选择 AM 和 PM 时设置，永远地解决了不小心将 9am 的闹钟设置成 9pm 的问题。

![](/data/attachment/album/201706/10/201840b1lq90cs9ccnqxq9.jpg)

*平板的新系统界面使用了延展版的手机界面。 [Ron Amadeo 供图]*

安卓 4.2 中最有争议的改变是平板界面，从单独一个统一的底部系统栏变成带有顶部状态栏和底部系统栏的双栏设计。新设计统一了手机和平板的界面，但批评人士说将手机界面延展到 10 英寸的横向平板上是浪费空间。因为导航按键现在拥有了整个底栏，所以他们像手机界面那样被居中。

![](/data/attachment/album/201706/10/201923yfldpdz0lludklnl.jpg)

*平板上的多用户，以及新的手势键盘。 [Ron Amadeo 供图]*

在平板上，安卓 4.2 带来了多用户支持。在设置里，新增了“用户”部分，你可以在这里管理一台设备上的用户。设置在每个用户账户内完成，安卓会给每个用户保存单独的设置，主屏幕，应用以及应用数据。

4.2 还添加了有滑动输入能力的键盘。用户可以将手指一直保持在屏幕上，按顺序在字母按键上滑动来输入，而不用像以前那样一个一个字母单独地输入。

---

![](/data/attachment/album/201706/10/201949yme3y88glv3v332v.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron是Ars Technica的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/22/>

译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


安卓编年史（22）：周期外更新——谁需要一个新系统？

Summary: 在安卓 4.2 和安卓 4.3 之间，谷歌进行了一次周期外更新，显示了有多少安卓可以不用经过费力的 OTA 更新而得到改进。得益于谷歌 Play 商店和 Play 服务，这些更新可以在不更新任何系统核心组件的前提下送达。

![](/data/attachment/album/201706/10/221859xnw4z7589n7q78lx.jpg)

![](/data/attachment/album/201706/10/222120zgp21c4n5001421p.jpg)

*Play 商店又一次重新设计！这一版非常接近现在的设计，卡片结构让改变布局变得易如反掌。 [Ron Amadeo 供图]*

### 周期外更新——谁需要一个新系统？

在安卓 4.2 和安卓 4.3 之间，谷歌进行了一次周期外更新，显示了有多少安卓可以不用经过费力的 OTA 更新而得到改进。得益于[谷歌 Play 商店和 Play 服务](http://arstechnica.com/gadgets/2013/09/balky-carriers-and-slow-oems-step-aside-google-is-defragging-android/)，这些更新可以在不更新任何系统核心组件的前提下送达。

2013 年 4 月，谷歌发布了谷歌 Play 商店的一个主要设计改动。就如同在这之后的大多数重新设计，新的 Play 商店完全接受了 Google Now 审美，即在灰色背景上的白色卡片。操作栏基于当前页面内容部分更改颜色，由于首屏内容以商店的各部分为主，操作栏颜色是中性的灰色。导航至内容部分的按钮指向热门付费，在那下面通常是一块促销内容或一组推荐应用。

![](/data/attachment/album/201706/10/222249rabjdmbmeebfqbsw.jpg)

*独立的内容部分有漂亮的颜色。 [Ron Amadeo 供图]*

新的 Play 商店展现了谷歌卡片设计语言的真正力量，在所有的屏幕尺寸上能够拥有响应式布局。一张大的卡片能够和若干小卡片组合，大屏幕设备能够显示更多的卡片，而且相对于拉伸来适应横屏模式，可以通过在一行显示更多卡片来适应。Play 商店的内容编辑们也可以自由地使用卡片布局；需要关注的大更新可以获得更大的卡片。这个设计最终会慢慢渗透向其它谷歌 Play 内容应用，最后拥有一个统一的设计。

![](/data/attachment/album/201706/10/222324pl2prp226ljj4dle.jpg)

*Hangouts 取代了 Google Talk，现在仍由 Google+ 团队继续开发。 [Ron Amadeo 供图]*

Google I/O，谷歌的年度开发者会议，通常会宣布一个新的安卓版本。但是 2013 年的会议，谷歌只是发布了一些改进而没有系统更新。

谷歌宣布的大事件之一是 Google Talk 的更新，谷歌的即时消息平台。在很长一段时间里，谷歌随安卓附带四个文本交流应用：Google Talk，Google+ Messenger，信息（短信应用），Google Voice。拥有四个应用来完成相同的任务——给某人发送文本消息——对用户来说很混乱。在 I/O 上，谷歌结束了 Google Talk 并且从头开始创建全新的消息产品 [Google Hangouts](http://arstechnica.com/information-technology/2013/05/hands-on-with-hangouts-googles-new-text-and-video-chat-architecture/)。虽然最初只是想替代 Google Talk，Hangouts 的计划是统一所有谷歌的不同的消息应用到统一的界面下。

Hangouts 的用户界面布局真的和 Google Talk 没什么大的差别。主页面包含你的聊天会话，点击某一项就能进入聊天页面。界面设计上有所更新，聊天页面现在使用了卡片风格来显示每个段落，并且聊天列表是个“抽屉”风格的界面，这意味着你可以通过水平滑动打开它。Hangouts 有已读回执和输入状态指示，并且群聊现在是个主要特性。

Google+ 是 Hangouts 的中心，所以产品的全名实际上是“Google+ Hangouts”。Hangouts 完全整合到了 Google+ 桌面站点。身份和头像直接从 Google+ 拉取，点击头像会打开用户的 Google+ 资料。和将浏览器换为 Google Chrome 类似，核心安卓功能交给了一个单独的团队——Google+ 团队，这是变得越发繁忙的安卓工程师的抗议的结果。随着 Google+ 团队的接手，安卓的主要即时通讯客户端现在成为一个持续开发的应用。它被放进了 Play 商店并且有稳定的更新频率。

![](/data/attachment/album/201706/10/222405bbbmjb5ffsffj957.jpg)

*新导航抽屉界面。 图片来自 [developer.android.com](https://developer.android.com/design/patterns/navigation-drawer.html)*

谷歌还给操作栏引入了新的设计元素：导航抽屉。这个抽屉显示为在左上角应用图标旁的三道横线。点击或从屏幕左边缘向右滑动，会出现一个侧边菜单目录。就像名字所指明的，这个是用来在应用内导航的，它会显示若干应用内的顶层位置。这使得应用首屏可以用来显示内容，也给了用户一致的、易于访问的导航元素。导航抽屉基本上就是个大号的菜单，可以滚动并且固定在左侧。

---

![](/data/attachment/album/201706/10/222515zh9zwfdk0666d9d2.jpg)

[Ron Amadeo](http://arstechnica.com/author/ronamadeo) / Ron是Ars Technica的评论编缉，专注于安卓系统和谷歌产品。他总是在追寻新鲜事物，还喜欢拆解事物看看它们到底是怎么运作的。[@RonAmadeo](https://twitter.com/RonAmadeo)

---

via: <http://arstechnica.com/gadgets/2016/10/building-android-a-40000-word-history-of-googles-mobile-os/23/>

译者：[alim0x](https://github.com/alim0x) 校对：[wxy](https://github.com/wxy)

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


掌握 Git 之美

Summary: 使用 7 条简单的 Git 命令开始你的软件开发之旅

可以

使用 7 条简单的 Git 命令开始你的软件开发之旅

![](/data/attachment/album/201706/12/081112zzoqhsylo41ujshq.jpg)

>
> 使用 7 条简单的 Git 命令开始你的软件开发之旅
>
>
>

你是否曾经想知道如何学好 Git？你长期以来都是跌跌撞撞地在使用 Git。最终，你总需要掌握它的窍门。这就是我写这篇文章的原因，我将带你去启蒙之旅。这儿是我关于如何加快 Git 学习过程的基本指南。我将介绍 Git 的实际情况以及我使用最多的 7 条 Git 命令。本文主要针对有兴趣的开发人员和大学新生，他们需要关于 Git 的介绍以及如何掌握基础知识。

---

>
> 你可以往前继续阅读整篇文章，或者只读 TLDR; 部分，尽管这将使我很受伤。
>
>
>

### TLDR;

在学习 Git 的过程中，请养成下面这些步骤的习惯：

1. 随时使用 `git status`！
2. 只更改那些你真正想更改的文件。
3. `git add -A` 会是你的朋友。
4. 随时使用命令 `git commit -m "meaningful messages"`。
5. 做任何推送（push）之前先使用命令 `git pull`，但是这需要在你提交过一些更改之后。
6. 最后，`git push`推送提交的更改。

---

### 良宵莫辜负

对任何开发人员来说，通常第一步都是选择一个广泛使用的地方托管他或她的代码库。那就是，[GitHub](https://github.com/)。它是一切有关代码的聚集地。要理解 GitHub 的概念，你先需要知道什么是 Git。

Git 是一款基于命令行的版本控制软件，在 Windows 和 Mac 系统上也有几款可用的桌面应用。 Git 由 Linux 之父 Linus Torvalds 开发，Linus Torvalds 还是是计算机科学中最有影响力的人物之一。因为这一优势，Git 已经成为绝大多数软件开发人员关于共享和维护代码的标准。这一大段话，让我们将其细细道来。正如它的名字所说，版本控制软件 Git 让你可以预览你写过的代码的所有版本。从字面上来说， 开发人员的每个代码库都将永远存储在其各自的仓库中，仓库可以叫做任何名字，从 *pineapple* 到 *express* 都行。在此仓库开发代码的过程中，你将进行出无数次的更改，直到第一次正式发布。这就是版本控制软件如此重要的核心原因所在。它让作为开发人员的你可以清楚地了解对代码库进行的所有更改、修订和改进。从另外一个方面说，它使协同合作更容易，下载代码进行编辑，然后将更改上传到仓库。然而，尽管有了这么多好处，然而还有一件事可以锦上添花。你可以下载并使用这些文件，即使你在整个开发过程中什么事也没有做。

让我们回到文章的 GitHub 部分。它只是所有仓库的枢纽（hub），这些仓库可以存储在其中并在线浏览。它是一个让有着共同兴趣的人相聚的地方。

### 千里之行始于足下

OK，记住，Git 是一款软件，像任何其他软件一样，你首先需要安装它：

[Git - 安装 Git，如果你希望从源代码安装 Git，你需要安装这些 Git 的依赖库： autotools —— 来自 git-scm.com](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

*Tips：请点击上面的链接，然后按照说明开始。*

完成了安装过程，很好。现在你需要在你的浏览器地址栏输入 [github.com](https://github.com/) 访问该网站。如果你还没有帐号的话需要新创建一个帐号，这就是你的起舞之处。登录并创建一个新仓库，命名为 Steve ，没有什么理由，只是想要一个名为史蒂夫的仓库好玩而已。选中 “Initialize this repository with a README” 复选框并点击创建按钮。现在你有了一个叫做 Steve 的仓库。我相信你会为你自己感到自豪。

![](/data/attachment/album/201706/12/081217h3111g1k38kbe1wd.jpg)

### 现在开始在使用 Git

现在是比较有趣的部分。你将把 Steve 克隆到你本地的机器上。可以把这个过程看作从 Github 上复制仓库到你的电脑上。点击 “clone or download” 按钮，你将看到一个类似下面这样的 URL:

```
https://github.com/yourGithubAccountName/Steve.git

```

复制这个 URL 并打开命令提示符窗口。现在输入并运行条命令：

```
git clone https://github.com/yourGithubAccountName/Steve.git

```

Abrakadabra！Steve 仓库已经被自动克隆到了你的电脑上。查看你克隆这个仓库的目录，你会看到一个叫做 Steve 的文件夹。这个本地的文件夹现在已经链接到了它的 “origin” ，也就是 GitHub 上的远程仓库。

记住这个过程，在你的软件开发工程人员的职业生涯中你一定会重复这个过程很多次的。完成所有这些准备工作之后，你就可以开始使用最普通且常用的 Git 命令了。

![](/data/attachment/album/201706/12/081300ywes9cb6zhsii4b1.jpeg)

### 你现在已经开始在真实场景使用 Git 了

找到 Steve 目录并在该目录中打开命令提示符窗口，运行下面的命令：

```
git status

```

这会输出你的工作目录的状态，让你知道所有你编辑过的文件。这意味着它显示了远程库中和本地工作目录中之间的文件差异。`status` 命令被用来作为 `commit` 的模版，我将在这篇教程后面进一步谈论 `commit` 。简单的说，`[git status][1]` 告诉你你编辑过哪些文件，以给你一个你想要上传到远程库的概述。

但是，在你做任何上传之前，你首先需要做的是选择你需要发送回远程库的文件。使用下面命令完成：

```
git add

```

接着在 Steve 目录新建一个文本文件，可以取一个好玩的名字 `pineapple.txt`。在这个文件里面随便写些你想写的内容，返回命令提示符，然后再次输入 `git status`。现在，你将看到这个文件以红色出现在标记 “untracked files” 下面。

```
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be commited)

pineapple.txt

```

下一步就是将它添加到暂存区（staging）。暂存区可以看作是这样的一个环境：你做过的所有更改在提交时都将捆绑为一个更改而被提交。现在，你可以将这个文件加入暂存区：

```
git add -A

```

`-A` 选项意味着所有你更改过的文件都会被加到暂存区等待提交。然而， `git add` 非常灵活，它也可以像这样一个文件一个文件的添加：

```
git add pineapple.txt

```

这种方法让你有能力选择你想要暂存的每一个文件，而不用担心加入那些你不想改变的东西。

再次运行 `git status`，你会看到如下输出：

```
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

new file:   pineapple.txt

```

准备好提交更改了吗？开始吧。

```
git commit -m "Write your message here"

```

[Git commit](https://git-scm.com/docs/git-commit) 命令会将存储在暂存区中的文件和来自用户的用于描述更改的日志信息一起存储在一个新的地方。`-m`选项加入了写在双引号内的信息。

再次检查状态，你会看到：

```
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

```

所有的更改现在都被加入到一次提交当中了，同时会有一条与你所做相关的信息。现在你可以用 `git push` 将这次提交推送到远程库 “origin”了。这条命令就像字面意义所说，它会把你提交的更改从本地机器上传到 GitHub 的远程仓库中。返回到命令提示符，然后运行：

```
git push

```

你会被要求输入你的 GitHub 帐号和密码，之后你会看到类似下面的这些内容：

```
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 280 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/yourGithubUserName/Steve.git
   c77a97c..08bb95a  master -> master

```

就是这样。你已经成功上传了你本地的更改。看看你在 GitHub 上的仓库，你会看到它现在包含了一叫做 `pineapple.txt` 的文件。

如果你是一个开发小组的一员呢？如果他们都推送提交到 “origin”，将会发生什么？这就是 Git 真正开始发挥它的魔力的时候。你可以使用一条简单的命令轻松地将最新版本的代码库 [pull](https://git-scm.com/docs/git-pull) 到你本地的机器上：

```
git pull

```

但是 Git 也有限制：你需要有相匹配的版本才能推送到 “origin”。这意味着你本地的版本需要和 origin 的版本大致一样。当你从 “origin” 拉取（pull）文件时，在你的工作目录中不能有文件，因为它们将会在这个过程中被覆盖。因此我给出了这条简单的建议。在学习 Git 的过程中，请养成下面这些步骤的习惯：

1. 随时使用 `git status`！
2. 只更改那些你真正想更改的文件。
3. `git add -A` 会是你的朋友。
4. 随时使用命令 `git commit -m "meaningful messages"`。
5. 做任何推送（push）之前先使用命令 `git pull`，但是这需要在你提交过一些更改之后。
6. 最后，`git push`推送提交的更改。

---

嘿！你还在看这篇文章吗？你已经看了很久了，休息一下吧！

![](/data/attachment/album/201706/12/081416aio40l33i60pc0bp.jpg)

休息好了吗？好的！让我们来处理一些错误。如果你不小心更改了一些你本不应该更改的文件后怎么办呢？不需要担心，只需要使用 [git checkout](https://git-scm.com/docs/git-checkout)。让我们在文件 `pineapple.txt` 里更改一些内容：在文件中加入一行，比方说，“Steve is mega-awesome!” 。然后保存更改并用 `git status` 检查一下：

```
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   pineapple.txt

no changes added to commit (use "git add" and/or "git commit -a")

```

正如预料的那样，它已经被记录为一次更改了。但是，假如 Steve 实际上并不是很优秀呢？假如 Steve 很差劲呢？不用担心！最简单的还原更改的方式是运行命令：

```
git checkout -- pineapple.txt

```

现在你会看到文件已经恢复到了先前的状态。

但是假如你玩砸了呢？我是说，事情已经变得混乱，并且需要把所有东西重置到与 “origin” 一样的状态。也不需要担心，在这种紧急情况下我们可以享受 Git 的美妙之处：

```
git reset --hard

```

[git reset](https://git-scm.com/docs/git-reset) 命令和 `--hard` 选项一起可以抛弃自上次提交以来的所有更改，有些时候真的很好用。

---

最后，我想鼓励你尽可能多地使用 Git。这是能够熟练使用它的最好学习方式。除此之外，养成阅读 Git 文档的习惯。一开始可能会有些云里雾里，但是过段时间后你就会明白它的窍门了。

*希望你们（小伙子和姑娘们）读这篇文章的时候会和我写它时一样的开心。如果你认为这篇文章对别人有用，你尽可以与别人分享它。或者，如果你喜欢这篇文章，你可以在下面点下赞以便让更多的人看到这篇文章。*

---

via: <https://hackernoon.com/how-to-master-the-art-of-git-68e1050f3147>

作者：[Adnan Rahić](https://hackernoon.com/@adnanrahic) 译者：[zhousiyu325](https://github.com/zhousiyu325) 校对：[wxy](https://github.com/wxy)

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


Linux 内核文章特辑

Summary: 备受关注的 LinuxCon 2017（北京）即将在一周后在北京首秀，而国内已经连续举办了 11 届的中国 Linux 内核开发者大会（CLK）也将在金秋十月的北京举办第 12 届。值此 Linux 界两大盛会举办之际，我特意收集了一些 Linux 内核方面的文章分享给大家。

![](/data/attachment/album/201706/12/133053w7azr2yxyr06gp76.jpg)

备受关注的 [LinuxCon 2017（北京）](http://www.bagevent.com/event/561769)即将在一周后在北京首秀，而国内已经连续举办了 11 届的[中国 Linux 内核开发者大会（CLK）](http://www.ckernel.org/)也将在金秋十月的北京举办第 12 届。值此 Linux 界两大盛会举办之际，我特意收集了一些 Linux 内核方面的文章分享给大家。

让我们先以一篇漫画开端：《[漫画赏析：Linux 内核到底长啥样](/article-8290-1.html)》，这篇并不算严谨的漫画，来自极客漫画站 TurnOff.us，由 [LCTT 翻译组](https://linux.cn/lctt/)进行汉化和点评，以有趣的方式向大众展示了内核里面都发生了些什么：

![Linux 内核都有啥](/data/attachment/album/201703/20/172808pim5iueyqwa5egww.jpg)

当然， 作为非专业陈述，就不必深究细节了，但是这篇漫画成功地引起了诸多（伪）Linux 内核爱好者的兴趣。

如果你对 Linux 内核发生了兴趣，想要知道 [Linux 内核是如何构建的](/article-6197-1.html)，那这里也有[一篇文章](/article-6197-1.html)可以指导你，这是一篇由 GitHub 上 [0xAX](https://github.com/0xAX) 写的[一系列 Linux 内核文章](https://github.com/0xAX/linux-insides)中的一篇， LCTT 成员 [@mudongliang](https://github.com/mudongliang) 参与了组织翻译。

此系列我们还翻译了数篇数据结构方面的文章，如：[双向链表](/article-7321-1.html)、[基数树](/article-7353-1.html)、[位数组](/article-7707-1.html)，这些在你做内核开发和研究时肯定会用到。当然，Linus Torvalds 大神向来以对进入内核的代码审核严苛而著称，比如说，他曾经就如何[写出具有 “good taste” 的代码](/article-8498-1.html)而发表过演讲。

说起来，现在内核的变化太快了，简直是日新月异，比如说，我们就注意到 [BPF 进入了 4.9 内核](/article-8038-1.html)，它相当于 BSD 中的 DTrace 一样。另外，据闻 Linux 内核将[新增一种异构内存管理](/article-8593-1.html)，将会加快 Linux 上的机器学习处理能力。

这么多的新特性的涌现，背后代表着大量的代码和贡献人员的辛勤付出。据 [2016 年度《Linux 内核开发》报告](/article-7720-1.html)，自版本 3.18 于 2014 年 12 月 7 日发布以来，已合并了近 115000 个变更，这些贡献来自近 500 家公司的 5062 名开发人员。

当然，Linux 内核发展这么迅速，随着影响力的提升，也越来越引起各界的注意，比如说，华盛顿邮报就曾经批评 Linux “没有一个系统性的机制以在骇客之前发现和解决安全问题，或引入更新的防御技术”，“Linux 内核开发社区没有一个首席安全官”等等。针对这篇文章，LWN 上也有人对此进行了一些[回应](/article-7404-1.html)，并就一些问题进行了辨析和反思。

所以，现在 Linux 内核不仅仅需要更好的安全机制的出现和贡献者的努力，也需要[解决 Linux 内核代码审查人员短缺问题](/article-7905-1.html)。

前面说了很多 Linux 内核开发人员更关注的话题， 对于普通的 Linux 用户来说，可能更关注的是如何在 [CentOS](/article-8310-1.html) 和 [Ubuntu](/article-8284-1.html) 上升级内核。不过，现在的内核已经支持[升级后不重启](/article-4656-1.html)了，对于某些内核补丁，可以[热应用](/article-8005-1.html)而不用重启。这对于生产环境中的 Linux 服务器很重要，比如 [Ubuntu](/article-7888-1.html)、[Oracle Linux](/article-6874-1.html) 等发行版已经支持了。

作为 Linux 的使用者，尤其是 Linux 服务器的运维人员，密切监控 Linux 的各项性能指标也是必需的工作，无论是[传统工具](/article-5898-1.html)： top、ps、pstree、[vmstat](/article-8157-1.html)、[iostat](/article-4024-1.html)，还是 [htop](/article-7004-1.html)、 [nmon](/article-6886-1.html)、[ntopng](/article-5664-1.html) 这样的新工具；而且不但有 [cpustat](/article-8466-1.html)、[CoreFreq](/article-8241-1.html) 这样专门监控 CPU 的工具，也有各种大而全的全面监控系统，如 [Glances](/article-6882-1.html)、[netdata](/article-7576-1.html)、 [Munin](/article-6920-1.html)。总之，[用于监控的工具和系统不要太多了](/article-6987-1.html)。

那么，你喜欢 Linux ，喜欢研究下 Linux 内核么？如果是，那么这两场大会你一定要关注：

* [LinuxCon + ContainerCon + CloudOpen China 2017](http://www.bagevent.com/event/561769)
* [中国 Linux 内核开发者大会（CLK）](http://www.ckernel.org/)


Linux GRUB2 配置简介

Summary: 学习 GRUB 引导加载程序是如何预备你的系统并启动操作系统内核的。

不应该是 grub2-mkconfig --output=/boot/grub2/grub.cfg ?

把2去掉

不, 就是 /boot/grub2

各个平台的不一样，有的带有2有的没有. 和版本也有关系

学习 GRUB 引导加载程序是如何预备你的系统并启动操作系统内核的。

>
> 学习 GRUB 引导加载程序是如何预备你的系统并启动操作系统内核的。
>
>
>

![Linux GRUB2 配置简介](/data/attachment/album/201706/13/061338lskppuy2khsjop12.png "Linux GRUB2 配置简介")

自从上个月为我的文章《[Linux 引导和启动过程简介](https://opensource.com/article/17/2/linux-boot-and-startup)》做研究开始，我对更深入了解 GRUB2 产生了兴趣。这篇文章提供了配置 GRUB2 的简要介绍。为了简便起见，我大多数情况下会使用 GRUB 指代 GRUB2。

### GRUB

GRUB 来自 GRand Unified Bootloader 的缩写。它的功能是在启动时从 BIOS 接管掌控、加载自身、加载 Linux 内核到内存，然后再把执行权交给内核。一旦内核开始掌控，GRUB 就完成了它的任务，也就不再需要了。

GRUB 支持多种 Linux 内核，并允许用户在启动时通过菜单在其中选择。我发现这是一种非常有用的工具，因为我有很多次遇到一个应用程序或者系统服务在特定内核版本下失败的问题。有好几次，引导到一个较旧的内核时就可以避免类似的问题。默认情况下，使用 `yum` 或 `dnf` 进行更新时会保存三个内核 - 最新的以及两个比较旧的。在被包管理器删除之前所保留的内核数目可以在 `/etc/dnf/dnf.conf` 或 `/etc/yum.conf` 文件中配置。我通常把 `installonly_limit` 的值修改为 9 以便保留 9 个内核。当我不得不恢复到低几个版本的内核时这非常有用。

### GRUB 菜单

GRUB 菜单的功能是当默认的内核不是想要的时，允许用户从已经安装的内核中选择一个进行引导。通过上下箭头键允许你选中想要的内核，敲击回车键会使用选中的内核继续引导进程。

GRUB 菜单也提供了超时机制，因此如果用户没有做任何选择，GRUB 就会在没有用户干预的情况下使用默认内核继续引导。敲击键盘上除了回车键之外的任何键会停止终端上显示的倒数计时器。立即敲击回车键会使用默认内核或者选中的内核继续引导进程。

GRUB 菜单提供了一个 “<ruby> 救援 <rt>  rescue </rt></ruby>” 内核，用于故障排除或者由于某些原因导致的常规内核不能完成启动过程。不幸的是，这个救援内核不会引导到救援模式。文章后面会更详细介绍这方面的东西。

### grub.cfg 文件

`grub.cfg` 文件是 GRUB 配置文件。它由 `grub2-mkconfig` 程序根据用户的配置使用一组主配置文件以及 grub 默认文件而生成。`/boot/grub2/grub.cfg` 文件在 Linux 安装时会初次生成，安装新内核时又会重新生成。

`grub.cfg` 文件包括了类似 Bash 脚本的代码以及一个按照安装顺序排序的已安装内核列表。例如，如果你有 4 个已安装内核，最新的内核索引是 0，前一个内核索引是 1，最旧的内核索引是 3。如果你能访问 `grub.cfg` 文件，你应该去看看感受一下它看起来是什么样。`grub.cfg` 太大也就没有包含在这篇文章中。

### GRUB 配置文件

`grub.cfg` 的主要配置文件都在 `/etc/grub.d` 目录。该目录中的每个文件都包含了最终会整合到 `grub.cfg` 文件中的 GRUB 代码。这些配置文件的命名模式以排序方式设计，这使得最终的 `grub.cfg` 文件可以按正确的顺序整合而成。每个文件都有注释表明该部分的开始和结束，这些注释也是最终的 `grub.cfg` 文件的一部分，从而可以看出每个部分是由哪个文件生成。分隔注释看起来像这样：

```
### BEGIN /etc/grub.d/10_linux ###

### END /etc/grub.d/10_linux ###

```

不要修改这些文件，除非你是一个 GRUB 专家并明白更改会发生什么。无论如何，修改 `grub.cfg` 文件时你也总应该保留一个原始文件的备份。 `40_custom` 和 `41_custom` 这两个特别的文件用于生成用户对 GRUB 配置的修改。你仍然要注意对这些文件的更改的后果，并保存一份原始 `grub.cfg` 文件的备份。

你也可以把你自己的文件添加到 `/etc/grub.d` 目录。这样做的一个可能的原因是为非 Linux 操作系统添加菜单行。要注意遵循命名规则，确保配置文件中额外的菜单选项刚好在 `10_linux` 条目之前或之后。

### GRUB 默认文件

老版本 GRUB 的配置非常简单而明了，我只需要修改 `/boot/grub/grub.conf` 就可以了。对于新版本的 GRUB2，我虽然还可以通过更改 `/boot/grub2/grub.cfg` 来修改，但和老版本的 GRUB 相比，新版本相对更加复杂。另外，安装一个新内核时 `grub.cfg` 可能会被重写，因此任何修改都可能消失。当然，GNU.org 的 GRUB 手册确实有过直接创建和修改 `/boot/grub2/grub.cfg` 的讨论。

一旦你明白了如何做，更改 GRUB2 配置就会变得非常简单。我为之前的文章研究 GRUB2 的时候才明白这个。秘方就在 `/etc/default` 目录里面，一个自然而然称为 `grub` 的文件，它可以通过简单的终端命令操作。`/etc/default` 目录包括了一些类似 Google Chrome、 useradd、 和 grub 程序的配置文件。

`/etc/default/grub` 文件非常简单。这个 `grub` 默认文件已经列出了一些有效的键值对。你可以简单地更改现有键值或者添加其它文件中还没有的键。下面的列表 1 显示了一个没有更改过的 `/etc/default/grub` 文件。

```
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g'
   /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora_fedora25vm/root
   rd.lvm.lv=fedora_fedora25vm/swap
   rd.lvm.lv=fedora_fedora25vm/usr rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

```

*列表 1：Fedora 25 一个原始 grub 默认文件。*

[GRUB 手册 5.1 章节](https://www.gnu.org/software/grub/manual/grub.html#Simple-configuration)包括了所有可以添加到该 `grub` 文件的键的信息。我只需要修改 `grub` 默认文件已经有的一些键值就够了。让我们看看这些键值以及一些在 grub 默认文件中没有出现的每个键的意义。

* `GRUB_TIMEOUT` 这个键的值决定了显示 GRUB 选择菜单的时间长度。GRUB 提供了同时保存多个安装内核并在启动时使用 GRUB 菜单在其中选择的功能。这个键的默认值是 5 秒，但我通常修改为 10 秒使得有更多时间查看选项并作出选择。
* `GRUB_DISTRIBUTOR` 这个键定义了一个从 `/etc/system-release` 文件中提取发行版本的 [sed](https://en.wikipedia.org/wiki/Sed) 表达式。这个信息用于生成出现在 GRUB 菜单中的每个内核发布版的文本名称，例如 “Fedora” 等。由于不同发行版之间 `system-release` 文件结构的差异，在你的系统中这个 sed 表达式可能有些不同。
* `GRUB_DEFAULT` 决定默认引导哪个内核。如果是 `saved`，这代表最新内核。这里的其它选项如果是数字则代表了 `grub.cfg` 中列表的索引。使用索引号 3，就会总是加载列表中的第四个内核，即使安装了一个新内核之后也是。因此使用索引数字的话，在安装一个新内核后会加载不同的内核。要确保引导特定内核版本的唯一方法是设置 `GRUB_DEFAULT` 的值为想要内核的名称，例如 `4.8.13-300.fc25.x86_64`。
* `GRUB_SAVEDEFAULT` 通常，grub 默认文件中不会指定这个选项。当选择不同内核进行引导时，正常操作下该内核只会启动一次。默认内核不会改变。当其设置为 `true` 并和 `GRUB_DEFAULT=saved` 一起使用时，这个选项会保存一个不同内核作为默认值。当选择不同内核进行引导时会发生这种情况。
* `GRUB_DISABLE_SUBMENU` 一些人可能会希望为 GRUB 菜单创建一个内核的层级菜单结构。这个键和 `grub.cfg` 中一些额外内核配置允许创建这样的层级结构。例如，主菜单中可能有 `production` 和 `test` 子菜单，每个子菜单中包括了一些合适的内核。设置它为 `false` 可以启用子菜单。
* `GRUB_TERMINAL_OUTPUT` 一些环境下可能需要或者必要将输出重定向到一个不同的显示控制台或者终端。默认情况下是把输出发送到默认终端，通常 `console` 等价于 Intel 系列个人电脑的标准输出。另一个有用的选择是在使用串行终端或者 Integrated Lights Out (ILO) 终端连接的数据中心或者实验室环境中指定 `serial`。
* `GRUB_TERMINAL_INPUT` 和 `GRUB_TERMINAL_OUTPUT` 类似，可能需要或者必要重定向输入为串行终端或者 ILO 设备、而不是标准键盘输入。
* `GRUB_CMDLINE_LINUX` 这个键包括了在启动时会传递给内核的命令行参数。注意这些参数会被添加到 `grub.cfg` 所有已安装内核的内核行。这意味着所有已安装的内核在启动时都会有相同的参数。我通常删除 `rhgb` 和 `quiet` 参数以便我可以看到引导和启动时内核和 systemd 输出的所有内核信息消息。
* `GRUB_DISABLE_RECOVERY` 当这个键的值被设置为 `false`，GRUB 菜单中就会为每个已安装的内核创建一个恢复条目。当设置为 `true` 时就不会创建任何恢复条目。但不管这个设置怎样，最后的内核条目总是一个 `rescue` 选项。不过在 rescue 选项中我遇到了一个问题，下面我会详细介绍。

还有一些你可能觉得有用但我没有在这里介绍的键。它们的描述可以在 [GRUB 手册 2](https://www.gnu.org/software/grub/manual/grub.html#Simple-configuration) 的 5.1 章节找到。

### 生成 grub.cfg

完成所需的配置之后，就需要生成 `/boot/grub2/grub.cfg` 文件。这通过下面的命令完成。

```
grub2-mkconfig > /boot/grub2/grub.cfg

```

这个命令按照顺序使用位于 `/etc/grub.d` 的配置文件构建 `grub.cfg` 文件，然后使用 grub 默认文件的内容修改输出以便获得最终所需的配置。`grub2-mkconfig` 命令会尝试定位所有已安装的内核并在 `grub.cfg` 文件的 `10_Linux` 部分新建条目。它还创建一个 `rescue` 条目提供一个用于从 Linux 不能启动的严重问题中恢复的方法。

强烈建议你不要手动编辑 `grub.cfg` 文件，因为任何对该文件的直接修改都会在下一次安装新内核或者手动运行 `grub2-mkconfig` 时被重写。

### 问题

我遇到一个如果没有意识到就可能导致严重后果的 GRUB2 问题。这个救援内核没有启动，反而启动了另外一个内核。我发现那是列表中索引为 1 的内核，也就是列表中的第二个内核。额外的测试发现不管使用原始的还是我生成的 `grub.cfg` 配置文件都会发生这个问题。我在虚拟机和真实硬件上都尝试过而且都发生了这个问题。我只测试了 Fedora 25，因此其它 Fedora 发行版本可能没有这个问题。

注意，从救援内核生成的 “recovery” 内核条目不能引导到维护模式。

我推荐将 grub 默认文件中 `GRUB_DISABLE_RECOVERY` 的值更改为 “false”，然后生成你自己的 `grub.cfg`。这会在 GRUB 菜单中为每个已安装的内核生成可用的恢复条目。这些恢复配置能像期望那样工作，从而从那些需要输入密码登录的内核条目中引导到运行级别 1，也就是进入（不需要密码的）单用户维护模式。你也可以按 `Ctrl-D` 继续正常的引导进入默认运行级别。

### 总结

GRUB 是引导 Linux 计算机到可用状态过程的一系列事件中，发生在 BIOS 之后的第一步。理解如何配置 GRUB 对于恢复或者处理多种类型的问题非常重要。

这么多年来我多次不得不引导到恢复或者救援模式以便解决多种类型的问题。其中的一些问题确实是类似 `/etc/fstab` 或其它配置文件中不恰当条目导致的引导问题，也有一些是由于应用程序或者系统软件和最新的内核不兼容的问题。硬件兼容性问题也可能妨碍特定的内核启动。

我希望这些信息能对你开启 GRUB 配置之旅有所帮助。

（ 题图 ： Internet Archive [Book](https://www.flickr.com/photos/internetarchivebookimages/14746482994/in/photolist-ot6zCN-odgbDq-orm48o-otifuv-otdyWa-ouDjnZ-otGT2L-odYVqY-otmff7-otGamG-otnmSg-rxnhoq-orTmKf-otUn6k-otBg1e-Gm6FEf-x4Fh64-otUcGR-wcXsxg-tLTN9R-otrWYV-otnyUE-iaaBKz-ovcPPi-ovokCg-ov4pwM-x8Tdf1-hT5mYr-otb75b-8Zk6XR-vtefQ7-vtehjQ-xhhN9r-vdXhWm-xFBgtQ-vdXdJU-vvTH6R-uyG5rH-vuZChC-xhhGii-vvU5Uv-vvTNpB-vvxqsV-xyN2Ai-vdXcFw-vdXuNC-wBMhes-xxYmxu-vdXxwS-vvU8Zt) [Images](https://www.flickr.com/photos/internetarchivebookimages/14774719031/in/photolist-ovAie2-otPK99-xtDX7p-tmxqWf-ow3i43-odd68o-xUPaxW-yHCtWi-wZVsrD-DExW5g-BrzB7b-CmMpC9-oy4hyF-x3UDWA-ow1m4A-x1ij7w-tBdz9a-tQMoRm-wn3tdw-oegTJz-owgrs2-rtpeX1-vNN6g9-owemNT-x3o3pX-wiJyEs-CGCC4W-owg22q-oeT71w-w6PRMn-Ds8gyR-x2Aodm-owoJQm-owtGp9-qVxppC-xM3Gw7-owgV5J-ou9WEs-wihHtF-CRmosE-uk9vB3-wiKdW6-oeGKq3-oeFS4f-x5AZtd-w6PNuv-xgkofr-wZx1gJ-EaYPED-oxCbFP). Opensource.com 修改。 CC BY-SA 4.0）

---

作者简介：

David Both - David Both 是一个居住在 Raleigh，北卡罗来纳州的 Linux 和开源倡导者。他在 IT 界已经有超过 40 年，并在他工作的 IBM 执教 OS/2 20 多年。在 IBM 的时候，他在 1981 年开设了第一个最初 IBM 个人电脑的培训课程。他在红帽教授过 RHCE 课程并在 MCI Worldcom、 Cisco、 和北卡罗来纳州工作过。他已经在 Linux 和开源软件方面工作将近 20 年。

---

via: <https://opensource.com/article/17/3/introduction-grub2-configuration-linux>

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

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


机器学习的新捷径：通过 SYCL 在 GPU 上加速 C++

Summary: 不幸的是，对于日常程序员，OpenCL 的学习曲线陡峭；一个简单的 Hello World 程序可能就需要上百行晦涩难懂的代码。因此，为了减轻这种痛苦，Khronos 组织已经开发了一个称为 SYCL 的新标准，这是一个在 OpenCL 之上的 C++ 抽象层。

![](/data/attachment/album/201706/13/174644t3bpa2ra424e24e3.jpg)

在机器学习、计算机视觉以及高性能计算领域，充分利用显卡计算应用程序的能力已成为当前的热门。类似 OpenCL 的技术通过硬件无关的编程模型展现了这种能力，使得你可以编写抽象于不同体系架构的代码。它的目标是“一次编写，到处运行”，不管它是 Intel CPU、AMD 独立显卡还是 DSP 等等。不幸的是，对于日常程序员，OpenCL 的学习曲线陡峭；一个简单的 Hello World 程序可能就需要上百行晦涩难懂的代码。因此，为了减轻这种痛苦，Khronos 组织已经开发了一个称为 [SYCL](https://www.khronos.org/sycl) 的新标准，这是一个在 OpenCL 之上的 C++ 抽象层。通过 SYCL，你可以使用干净、现代的 C++ 开发出这些通用 GPU（GPGPU）应用程序，而无需拘泥于 OpenCL。下面是一个使用 SYCL 开发，通过并行 STL 实现的向量乘法事例：

```
#include <vector>
#include <iostream>

#include <sycl/execution_policy>
#include <experimental/algorithm>
#include <sycl/helpers/sycl_buffers.hpp>

using namespace std::experimental::parallel;
using namespace sycl::helpers;

int main() {
  constexpr size_t array_size = 1024*512;
  std::array<cl::sycl::cl_int, array_size> a;
  std::iota(begin(a),end(a),0);

  {
    cl::sycl::buffer<int> b(a.data(), cl::sycl::range<1>(a.size()));
    cl::sycl::queue q;
    sycl::sycl_execution_policy<class Mul> sycl_policy(q);
    transform(sycl_policy, begin(b), end(b), begin(b),
              [](int x) { return x*2; });
  }
}

```

为了作为对比，下面是一个通过 C++ API 使用 OpenCL 编写的大概对应版本（无需花过多时间阅读，只需注意到它看起来难看而且冗长）。

```
#include <iostream>
#include <array>
#include <numeric>
#include <CL/cl.hpp>

int main(){
    std::vector<cl::Platform> all_platforms;
    cl::Platform::get(&all_platforms);
    if(all_platforms.size()==0){
        std::cout<<" No platforms found. Check OpenCL installation!\n";
        exit(1);
    }
    cl::Platform default_platform=all_platforms[0];

    std::vector<cl::Device> all_devices;
    default_platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
    if(all_devices.size()==0){
        std::cout<<" No devices found. Check OpenCL installation!\n";
        exit(1);
    }

    cl::Device default_device=all_devices[0];
    cl::Context context({default_device});

    cl::Program::Sources sources;
    std::string kernel_code=
        "   void kernel mul2(global int* A){"
        "       A[get_global_id(0)]=A[get_global_id(0)]*2;"
        "   }";
    sources.push_back({kernel_code.c_str(),kernel_code.length()});

    cl::Program program(context,sources);
    if(program.build({default_device})!=CL_SUCCESS){
        std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device)<<"\n";
        exit(1);
    }

    constexpr size_t array_size = 1024*512;
    std::array<cl_int, array_size> a;
    std::iota(begin(a),end(a),0);

    cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*a.size());
    cl::CommandQueue queue(context,default_device);

    if (queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*a.size(),a.data()) != CL_SUCCESS) {
        std::cout << "Failed to write memory;n";
        exit(1);
    }

    cl::Kernel kernel_add = cl::Kernel(program,"mul2");
    kernel_add.setArg(0,buffer_A);

    if (queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(a.size()),cl::NullRange) != CL_SUCCESS) {
        std::cout << "Failed to enqueue kernel\n";
        exit(1);
    }

    if (queue.finish() != CL_SUCCESS) {
        std::cout << "Failed to finish kernel\n";
        exit(1);
    }

    if (queue.enqueueReadBuffer(buffer_A,CL_TRUE,0,sizeof(int)*a.size(),a.data()) != CL_SUCCESS) {
        std::cout << "Failed to read result\n";
        exit(1);
    }
}

```

在这篇博文中我会介绍使用 SYCL 加速你 GPU 上的 C++ 代码。

### GPGPU 简介

在我开始介绍如何使用 SYCL 之前，我首先给那些不熟悉这方面的人简要介绍一下为什么你可能想要在 GPU 上运行计算任务。如果已经使用过 OpenCL、CUDA 或类似的库，可以跳过这一节。

GPU 和 CPU 的一个关键不同就是 GPU 有大量小的、简单的处理单元，而不是少量（对于普通消费者桌面硬件通常是 1-8 个）复杂而强大的核。

![CPU 架构](/data/attachment/album/201706/13/174714eahc6khachn6z5hk.png)

上面是一个 4 核 CPU 的简单漫画示意图。每个核都有一组寄存器以及不同等级的缓存（有些是共享缓存、有些不是），然后是主内存。

![GPU 架构](/data/attachment/album/201706/13/174715iziw6x8iueqzienc.png)

在 GPU 上，多个小处理单元被组成一个执行单元。每个小处理单元都附有少量内存，每个执行单元都有一些共享内存用于它的处理单元。除此之外，还有一些 GPU 范围的内存，然后是 CPU 使用的主内存。执行单元内部的单元是 *lockstep* ，每个单元都在不同的数据片上执行相同的指令。

这可以使 GPU 同时处理大量的数据。如果是在 CPU 上，也许你可以使用多线程和向量指令在给定时间内完成大量的工作，但是 GPU 所能处理的远多于此。在 GPU 上一次性能够处理的数据规模使得它非常适合于类似图形（duh）、数学处理、神经网络等等。

GPGPU 编程的很多方面使得它和日常的 CPU 编程完全不同。例如，从主内存传输数据到 GPU 是*很慢的*。*真的*很慢。会完全干掉你的性能使你慢下来。因此，GPU 编程的权衡是尽可能多地利用加速器的高吞吐量来掩盖数据来往的延迟。

这里还有一些不那么明显的问题，例如分支的开销。由于执行单元内的处理单元按照 lockstep 工作，使它们执行不同路径（不同的控制流）的嵌套分支就是个真正的问题。这通常通过在所有单元上执行所有分支并标记出无用结果来解决。这是一个基于嵌套级别的指数级的复杂度，这当然是坏事情。当然，有一些优化方法可以拯救该问题，但需要注意：你从 CPU 领域带来的简单假设和知识在 GPU 领域可能导致大问题。

在我们回到 SYCL 之前，需要介绍一些术语。<ruby> 主机 <rp>  （ </rp> <rt>  host </rt> <rp>  ） </rp></ruby>是主 CPU 运行的机器，<ruby> 设备 <rp>  （ </rp> <rt>  device </rt> <rp>  ） </rp></ruby>是会运行你 OpenCL 代码的地方。设备可能就是主机，但也可能是你机器上的一些加速器、模拟器等。<ruby> 内核 <rp>  （ </rp> <rt>  kernel </rt> <rp>  ） </rp></ruby>是一个特殊函数，它是在你设备上运行代码的入口点。通常还会提供一些主机设置好的缓存给它用于输入和输出数据。

### 回到 SYCL

这里有两个可用的 SYCL 实现：[triSYCL](https://github.com/Xilinx/triSYCL)，由 Xilinx 开发的实验性开源版本（通常作为标准的试验台使用），以及 [ComputeCpp](https://www.codeplay.com/products/computesuite/computecpp)，由 Codeplay（我在 Codeplay 工作，但这篇文章是在没有我雇主建议的情况下使用我自己时间编写的） 开发的工业级实现（当前处于开发测试版）。只有 ComputeCpp 支持在 GPU 上执行内核，因此在这篇文章中我们会使用它。

第一步是在你的机器上配置以及运行 ComputeCpp。主要组件是一个实现了 SYCL API 的运行时库，以及一个基于 Clang 的编译器，它负责编译你的主机代码和设备代码。在本文写作时，已经在 Ubuntu 和 CentOS 上官方支持 Intel CPU 以及某些 AMD GPU。在其它 Linux 发行版上让它工作也非常简单（例如，我让它在我的 Arch 系统上运行）。对更多的硬件和操作系统的支持正在进行中，查看[支持平台文档](https://www.codeplay.com/products/computesuite/computecpp/reference/platform-support-notes)获取最新列表。[这里](https://www.codeplay.com/products/computesuite/computecpp/reference/release-notes/)列出了依赖和组件。你也可能想要下载 [SDK](https://github.com/codeplaysoftware/computecpp-sdk)，其中包括了示例、文档、构建系统集成文件，以及其它。在这篇文章中我会使用 [SYCL 并行 STL](https://github.com/KhronosGroup/SyclParallelSTL)，如果你想要自己在家学习的话也要下载它。

一旦你设置好了一切，我们就可以开始通用 GPU 编程了！正如简介中提到的，我的第一个示例使用 SYCL 并行 STL 实现。我们现在来看看如何使用纯 SYCL 编写代码。

```
#include <CL/sycl.hpp>

#include <array>
#include <numeric>
#include <iostream>

int main() {
      const size_t array_size = 1024*512;
      std::array<cl::sycl::cl_int, array_size> in,out;
      std::iota(begin(in),end(in),0);

      {
          cl::sycl::queue device_queue;
          cl::sycl::range<1> n_items{array_size};
          cl::sycl::buffer<cl::sycl::cl_int, 1> in_buffer(in.data(), n_items);
          cl::sycl::buffer<cl::sycl::cl_int, 1> out_buffer(out.data(), n_items);

          device_queue.submit([&](cl::sycl::handler &cgh) {
              constexpr auto sycl_read = cl::sycl::access::mode::read;
              constexpr auto sycl_write = cl::sycl::access::mode::write;

              auto in_accessor = in_buffer.get_access<sycl_read>(cgh);
              auto out_accessor = out_buffer.get_access<sycl_write>(cgh);

              cgh.parallel_for<class VecScalMul>(n_items,
                  [=](cl::sycl::id<1> wiID) {
                      out_accessor[wiID] = in_accessor[wiID]*2;
                  });
         });
     }
}

```

我会把它划分为一个个片段。

```
#include <CL/sycl.hpp>

```

我们做的第一件事就是包含 SYCL 头文件，它会在我们的命令中添加 SYCL 运行时库。

```
const size_t array_size = 1024*512;
std::array<cl::sycl::cl_int, array_size> in,out;
std::iota(begin(in),end(in),0);

```

这里我们构造了一个很大的整型数组并用数字 `0` 到 `array_size-1` 初始化（这就是 `std::iota` 所做的）。注意我们使用 `cl::sycl::cl_int` 确保兼容性。

```
{
    //...
}

```

接着我们打开一个新的作用域，其目的为二：

1. `device_queue` 将在该作用域结束时解构，它将阻塞，直到内核完成。
2. `in_buffer` 和 `out_buffer` 也将解构，这将强制数据传输回主机并允许我们从 `in` 和 `out` 中访问数据。 `cl::sycl::queue device_queue;`

现在我们创建我们的命令队列。命令队列是所有工作（内核）在分发到设备之前需要入队的地方。有很多方法可以定制队列，例如说提供设备用于入队或者设置异步错误处理器，但对于这个例子默认构造器就可以了；它会查找兼容的 GPU，如果失败的话会回退到主机 CPU。

```
cl::sycl::range<1> n_items{array_size};

```

接下来我们创建一个范围，它描述了内核在上面执行的数据的形状。在我们简单的例子中，它是一个一维数组，因此我们使用 `cl::sycl::range<1>`。如果数据是二维的，我们就会使用 `cl::sycl::range<2>`，以此类推。除了 `cl::sycl::range`，还有 `cl::sycl::ndrange`，它允许你指定工作组大小以及越界范围，但在我们的例子中我们不需要使用它。

```
cl::sycl::buffer<cl::sycl::cl_int, 1> in_buffer(in.data(), n_items);
cl::sycl::buffer<cl::sycl::cl_int, 1> out_buffer(out.data(), n_items);

```

为了控制主机和设备之间的数据共享和传输，SYCL 提供了一个 `buffer` 类。我们创建了两个 SYCL 缓存用于管理我们的输入和输出数组。

```
      device_queue.submit([&](cl::sycl::handler &cgh) {/*...*/});

```

设置好了我们所有数据之后，我们就可以入队真正的工作。有多种方法可以做到，但设置并行执行的一个简单方法是在我们的队列中调用 `.submit` 函数。对于这个函数我们传递了一个运行时调度该任务时会被执行的“命令组伪函数”（伪函数是规范，不是我创造的）。命令组处理器设置任何内核需要的余下资源并分发它。

```
constexpr auto sycl_read = cl::sycl::access::mode::read_write;
constexpr auto sycl_write = cl::sycl::access::mode::write;

auto in_accessor = in_buffer.get_access<sycl_read>(cgh);
auto out_accessor = out_buffer.get_access<sycl_write>(cgh);

```

为了控制到我们缓存的访问并告诉该运行时环境我们会如何使用数据，我们需要创建访问器。很显然，我们创建了一个访问器用于从 `in_buffer` 读入，一个访问器用于写到 `out_buffer`。

```
cgh.parallel_for<class VecScalMul>(n_items,
    [=](cl::sycl::id<1> wiID) {
         out_accessor[wiID] = in_accessor[wiID]*2;
    });

```

现在我们已经完成了所有设置，我们可以真正的在我们的设备上做一些计算了。这里我们根据范围 `n_items` 在命令组处理器 `cgh` 之上分发一个内核。实际内核自身是一个使用 work-item 标识符作为输入、输出我们计算结果的 lamda 表达式。在这种情况下，我们从 `in_accessor` 使用 work-item 标识符作为索引读入，将其乘以 `2`，然后将结果保存到 `out_accessor` 相应的位置。`<class VecScalMul>` 是一个为了在标准 C++ 范围内工作的不幸的副产品，因此我们需要给内核一个唯一的类名以便编译器能完成它的工作。

```
}

```

在此之后，我们现在可以访问 `out` 并期望看到正确的结果。

这里有相当多的新概念在起作用，但使用这些技术你可以看到这些能力和所展现出来的东西。当然，如果你只是想在你的 GPU 上执行一些代码而不关心定制化，那么你就可以使用 SYCL 并行 STL 实现。

### SYCL 并行 STL

SYCL 并行 STL 是一个 TS 的并行化实现，它分发你的算法函数对象作为 SYCL 内核。在这个页面前面我们已经看过这样的例子，让我们来快速过一遍。

```
#include <vector>
#include <iostream>

#include <sycl/execution_policy>
#include <experimental/algorithm>
#include <sycl/helpers/sycl_buffers.hpp>

using namespace std::experimental::parallel;
using namespace sycl::helpers;

int main() {
  constexpr size_t array_size = 1024*512;
  std::array<cl::sycl::cl_int, array_size> in,out;
  std::iota(begin(in),end(in),0);

  {
    cl::sycl::buffer<int> in_buffer(in.data(), cl::sycl::range<1>(in.size()));
    cl::sycl::buffer<int> out_buffer(out.data(), cl::sycl::range<1>(out.size()));
    cl::sycl::queue q;
    sycl::sycl_execution_policy<class Mul> sycl_policy(q);
    transform(sycl_policy, begin(in_buffer), end(in_buffer), begin(out_buffer),
              [](int x) { return x*2; });
  }
}

```

```
  constexpr size_t array_size = 1024*512;
  std::array<cl::sycl::cl_int, array_size> in, out;
  std::iota(begin(in),end(in),0);

```

到现在为止一切如此相似。我们再一次创建一组数组用于保存我们的输入输出数据。

```
cl::sycl::buffer<int> in_buffer(in.data(), cl::sycl::range<1>(in.size()));
cl::sycl::buffer<int> out_buffer(out.data(), cl::sycl::range<1>(out.size()));
cl::sycl::queue q;

```

这里我们创建类似上个例子的缓存和队列。

```
sycl::sycl_execution_policy<class Mul> sycl_policy(q);

```

这就是有趣的部分。我们从我们的队列中创建 `sycl_execution_policy`，给它一个名称让内核使用。这个执行策略然后可以像 `std::execution::par` 或 `std::execution::seq` 那样使用。

```
transform(sycl_policy, begin(in_buffer), end(in_buffer), begin(out_buffer),
          [](int x) { return x*2; });

```

现在我们的内核分发看起来像提供了一个执行策略的 `std::transform` 调用。我们传递的闭包会被编译并在设备上执行，而不需要我们做其它更加复杂的设置。

当然，除了 `transform` 你可以做更多。开发的时候，SYCL 并行 STL 支持以下算法：

* `sort`
* `transform`
* `for_each`
* `for_each_n`
* `count_if`
* `reduce`
* `inner_product`
* `transform_reduce`

这就是这篇短文需要介绍的东西。如果你想和 SYCL 的开发保持同步，那就要看 [sycl.tech](http://sycl.tech/)。最近重要的开发就是移植 [Eigen](https://github.com/ville-k/sycl_starter) 和 [Tensorflow](http://deep-beta.co.uk/setting-up-tensorflow-with-opencl-using-sycl/) 到 SYCL ，为 OpenCL 设备带来引入关注的人工智能编程。对我个人而言，我很高兴看到高级编程模型可以用于异构程序自动优化，以及它们是怎样支持类似 [HPX](https://github.com/STEllAR-GROUP/hpx) 或 [SkelCL](https://github.com/skelcl/skelcl) 等更高级的技术。

---

via: <https://blog.tartanllama.xyz/c++/2017/05/19/sycl/>

作者：[TartanLlama](https://www.twitter.com/TartanLlama) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

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


如何用树莓派控制 GPIO 引脚并操作继电器

Summary: 学习如何用 PHP 和温度传感器实现树莓派控制 GPIO 并操作继电器

树梅派最好玩的就是你可以自由的构建自己的玩具。任何其他硬件没有这种优势

什么叫任何硬件？类似树莓派的硬件就有不好。加上那些爱破解手机，游戏机的。还有自己设计电路板，好像有个俄罗斯人自己用晶体管，还是电子管，体积有几个机柜，但可以玩俄罗斯方块的计算机。P.S. 树莓派的“莓”字错了。

17岁的阿三能写出这样的文章让中国的高中生感到惭愧。另外，我感觉树莓派只适合搭建 demo，稳定性、散热等方面均有不少问题，你不会想因为树莓派放家里电器短路烧了吧。

印度软件就是强啊。

那是你没见识过中国现在的小学生,初中生和高中生.<br />
据我所知, 有个初中生自己设计电路, 自己规划软硬件成本, 在论坛内发起小规模众筹, 做出了一款基于Linux的图形计算器

学习如何用 PHP 和温度传感器实现树莓派控制 GPIO 并操作继电器

>
> 学习如何用 PHP 和温度传感器实现树莓派控制 GPIO 并操作继电器
>
>
>

![How to control GPIO pins and operate relays with the Raspberry Pi](/data/attachment/album/201706/13/221425wq7gz3i7yl0ilggt.jpg "How to control GPIO pins and operate relays with the Raspberry Pi")

你是否曾经想知道怎样使用手机或者电脑在任何地方控制你的风扇和灯等一些家用电器？

我现在想控制我的圣诞彩灯，是使用手机呢，还是使用平板电脑呢，或者是使用笔记本电脑呢？都不是，而是仅仅使用一个树莓派。让我来告诉你如何使用 PHP 和温度传感器实现树莓派控制 GPIO 引脚并操作继电器。我使用 AJAX 把它们整合在了一起。

### 硬件要求：

* 树莓派
* 安装有 Raspbian 系统的 SD 卡（任何一张 SD 卡都可以，但是我更偏向使用大小为 32GB 等级为 class 10 的 SD 卡）
* 电源适配器
* 跳线（母对母跳线和公转母跳线）
* 继电器板（我使用一个用于 12V 继电器的继电器板）
* DS18B20 温度传感器
* 树莓派的 Wi-Fi 适配器
* 路由器（为了访问互联网，你需要有一个拥有端口转发的路由器）
* 10KΩ 的电阻

### 软件要求：

* 下载并安装 Raspbian 系统到你的 SD 卡
* 有效的互联网连接
* Apache web 服务器
* PHP
* WiringPi
* 基于 Mac 或者 Windows 的 SSH 客户端

### 一般的配置和设置

1、 插入 SD 卡到树莓派，然后使用以太网网线将它连接到路由器；

2、 连接 WiFi 适配器；

3、 使用 SSH 方式登录到树莓派，然后使用下面的命令编辑 `interfaces` 文件：

```
sudo nano /etc/network/interfaces

```

这个命令会用一个叫做 `nano` 的编辑器打开这个文件。它是一个非常简单又易于使用的文本编辑器。如果你不熟悉基 Linux 的操作系统，可以使用键盘上的方向键来操作。

用 `nano` 打开这个文件后，你会看到这样一个界面：

![File editor nano](/data/attachment/album/201706/13/221426wvszjemmzmdjvu6v.png "File editor nano")

4、要配置你的无线网络，按照下面所示修改这个文件：

```
iface lo inet loopback
iface eth0 inet dhcp
allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
   wpa-ssid "Your Network SSID"
   wpa-psk "Your Password"

```

5、 按 `CTRL+O` 保存，然后按 `CTRL+X` 退出编辑器。

到目前为止，一切都已经配置完成，接下来你需要做的就是使用命令重新加载网络：

```
sudo service networking reload

```

（警告：如果你是使用远程连接的方式连接的树莓派，连接将会中断。)

### 软件配置

#### 安装 Apache web 服务器

Apache 是一个受欢迎的服务器应用，你可以在树莓派安装这个程序让它提供网页服务。Apache 原本就可以通过 HTTP 方式提供 HTML 文件服务，添加其他模块后，Apache 还可以使用像 PHP 这样的脚本语言来提供动态网页的服务。

可以在命令行输入下面命令安装 Apache：

```
sudo apt-get install apache2 -y

```

安装完成后，可以在浏览器地址栏输入树莓派的 IP 地址来测试 web 服务器。如果你可以获得下面图片的内容，说明你已经成功地安装并设置好了你的服务器。

![Successful server setup](/data/attachment/album/201706/13/221427a3gvppwcrru6gnr3.png "Successful server setup")

要改变这个默认的页面和添加你自己的 html 文件，进入 `var/www/html` 目录：

```
cd /var/www/html

```

添加一些文件来测试是否成功。

#### 安装 PHP

PHP 是一个预处理器，这意味着它是当服务器收到网页请求时才会运行的一段代码。它开始运行，处理网页上需要被显示的内容，然后把网页发送给浏览器。不像静态的 HTML，PHP 在不同的环境下可以显示不同的内容。其他的语言也可以做到这一点，但是由于 WordPress 是用 PHP 编写的，有些时候你需要使用它。PHP 是 web 上一种非常受欢迎的语言，像 Facebok 和 Wikipeadia 这样的大型项目都是用 PHP 编写的。

使用下面的命令安装 PHP 和 Apache 软件包：

```
sudo apt-get install php5 libapache2-mod-php5 -y

```

#### 测试 PHP

创建文件 `index.php`：

```
sudo nano index.php

```

在里面写入一些 PHP 内容：

```
<?php echo "hello world"; ?>

```

保存文件，接下来删除 `index.html`，因为它比 `index.php` 的优先级更高：

```
sudo rm index.html

```

刷新你的浏览器，你会看到 “hello world”。这并不是动态的，但是它仍然由 PHP 提供服务。如果你在上面看到提原始的 PHP 文件而不是“hello world”，重新加载和重启 Apahce（LCTT 译注，重启即可）：

```
sudo /etc/init.d/apache2 reload
sudo /etc/init.d/apache2 restart

```

#### 安装 WiringPi

为了可以对代码的更改进行跟踪，WiringPi 的维护采用 git。但假如你因为某些原因而没法使用 git，还有一种可以替代的方案。（通常你的防火墙会把你隔离开来，所以请先检查一下你的防火墙的设置情况！）

如果你还没有安装 git，那么在 Debian 及其衍生版本中（比如 Raspbian），你可以这样安装它：

```
sudo apt-get install git-core

```

若是你遇到了一些错误，请确保你的树莓派是最新版本的 Raspbian 系统：

```
sudo apt-get update sudo apt-get upgrade

```

使用 git 获取最 WiringPi：

```
sudo git clone git://git.drogon.net/wiringPi

```

如果你之前已经使用过 clone 操作，那么可以使用下面命令：

```
cd wiringPi && git pull origin

```

这个命令会将会获取更新的版本，你然后可以重新运行下面的构建脚本。

有一个新的简化的脚本来构建和安装:

```
cd wiringPi && ./build

```

这个新的构建脚本将会为你完成编译和安装 WiringPi。它曾一度需要使用 `sudo` 命令，所以在运行这它之前你可能需要检查一下这个脚本。

#### 测试 WiringPi

运行 `gpio` 命令来检查安装成功与否:

```
gpio -v gpio readall

```

这将给你一些信心，软件运行良好。

#### 连接 DS18B20 传感器到树莓派

* 传感器上的黑线用于 GND。
* 红线用于 VCC。
* 黄线是 GPIO 线。

![GPIO image](/data/attachment/album/201706/13/221428zfqa01b46b6x386k.png "GPIO image")

连线：

* VCC 连接 3V 的 1 号引脚。
* GPIO 线连接 7 号引脚（GPIO4）。
* 地线连接 GND 的 9 号引脚。

#### 软件配置

为了用 PHP 使用 DS18B20 温度传感器模块，你需要执行下面的命令来激活用于树莓派上 GPIO 引脚和 DS18B20 的内核模块：

```
sudo modprobe w1-gpio
sudo modprobe w1-therm

```

你不想每次 Raspberry 重启后都手动执行上述命令，所以你想每次开机能自动启动这些模块。可以在文件 `/etc/modules` 中添加下面的命令行来做到：

```
sudo nano /etc/modules/

```

添加下面的命令行到它里面:

```
w1-gpio
w1-therm

```

为了测试，输入:

```
cd /sys/bus/w1/devices/

```

现在输入 `ls`。

你会看到你的设备信息。在设备驱动程序中，你的 DS18B20 传感器应该作为一串字母和数字被列出。在本例中，设备被记录为 `28-000005e2fdc3`。然后你需要使用 `cd` 命令来访问传感器，用你自己的序列号替代我的： `cd 28-000005e2fdc3`。

DS18B20 会周期性的将数据写入文件 `w1_slave`，所以你只需要使用命令 `cat`来读出数据： `cat w1_slave`。

这会生成下面的两行文本，输出中 `t=` 表示摄氏单位的温度。在前两位数后面加上一个小数点(例如，我收到的温度读数是 30.125 摄氏度)。

### 连接继电器

1、 取两根跳线，把其中一根连接到树莓派上的 GPIO24（18 号引脚），另一根连接 GND 引脚。你可以参考下面这张图。

2、 现在将跳线的另一端连接到继电器板。GND 连接到继电器上的 GND，GPIO 输出线连接到继电器的通道引脚号，这取决于你正使用的继电器型号。记住，将树莓派上的 GND 与继电器上的 GND 连接连接起来，树莓派上的 GPIO 输出连接继电器上的输入引脚。

![Headers](/data/attachment/album/201706/13/221429upee9x53gi7e8988.png "Headers")

注意！将继电器连接树莓派的时候小心一些，因为它可能会导致电流回流，这会造成短路。

3、 现在将电源连接继电器，可以使用 12V 的电源适配器，也可以将 VCC 引脚连接到什么破上的 3.3V 或 5.5V 引脚。

### 使用 PHP 控制继电器

让我们先写一个借助于 WiringPi 软件用来控制 Paspberry Pi 上 GPIO 引脚的 PHP 脚本。

1、在 Apache 服务器的网站根目录下创建一个文件，使用下面命令切换到该目录：

```
cd /var/www/html

```

2、 新建一个叫 `Home` 的文件夹：

```
sudo mkdir Home

```

3、 新建一个叫 `on.php`的脚本

```
sudo nano on.php

```

4、 在脚本中加入下面的代码：

```
<?php
        system("gpio-g mode 24 out");
        system("gpio-g write 24 1");
?>

```

5、 使用 `CTRL+O` 保存文件，`CTRL+X` 退出。

上面的代码中，你在第一行使用命令将 24 号 GPIO引脚设置为 output 模式：

```
system("gpio-g mode 24 out");

```

在第二行，你使用 `1` 将 24 号引脚 GPIO 打开，在二进制中"1"表示打开，"0"表示关闭。

6、 为了关闭继电器，可以创建另外一个 `off.php` 文件，并用 `0` 替换 `1`。

```
<?php
        system(" gpio-g mode 24 out ");
        system(" gpio-g write 24 1 ");
?>

```

7、 如果你已经将继电器连接了树莓派，可以在浏览器中输入你的树莓派的 IP 地址，并在后面加上目录名和文件名来进行访问：

```
http://{IPADDRESS}/home/on.php

```

这将会打开继电器。

8、 要关闭它，可以访问叫 `off.php` 的文件：

```
http://{IPADDRESS}/home/off.php

```

现在你需要能够在一个单独的页面来控制这两样事情，而不用单独的刷新或者访问这两个页面。你可以使用 AJAX 来完成。

9、 新建一个 HTML 文件，并在其中加入下面代码：

```
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
  $('#on').click(function(){
  var a= new XMLHttpRequest();
  a.open("GET", "on.php"); a.onreadystatechange=function(){
    if (a.readyState==4){
      if(a.status ==200){
      } else alert ("http error");
      }
    }
    a.send();
  });
});
$(document).ready(function()
  {
    $('#Off').click(function(){
      var a= new XMLHttpRequest();
      a.open("GET", "off.php");
      a.onreadystatechange=function(){
        if(a.readyState==4){
          if(a.status ==200){
          } else alert ("http error");
          }
        }
      a.send();
    });
  });
</script>
<button id="on" type="button"``Switch Lights On </button>
<button id="off" type="button"``Switch Lights Off </button>

```

10、 保存文件，进入你的 web 浏览器目录，然后打开那个网页。你会看到两个按钮，它们可以打开和关闭灯泡。基于同样的想法，你还可以使用 bootstrap 和 CSS 来创建一个更加漂亮的 web 界面。

### 在这个网页上观察温度

1、 新建一个 `temperature.php` 的文件：

```
sudo nano temperature.php

```

2、 在文件中加入下面的代码，用你自己的设备 ID 替换 `10-000802292522`：

```
<?php
//File to read
$file = '/sys/devices/w1_bus_master1/10-000802292522/w1_slave';
//Read the file line by line
$lines = file($file);
//Get the temp from second line
$temp = explode('=', $lines[1]);
//Setup some nice formatting (i.e., 21,3)
$temp = number_format($temp[1] / 1000, 1, ',', '');
//And echo that temp
echo $temp . " °C";
?>

```

3、 打开你刚刚创建的 HTML 文件，并创建一个新的带有 `id` 为 “screen” 的 `<div>`标签

```
<div id="screen"></div>

```

4、 在这个标签后或者这个文档的尾部下面的代码：

```
<script>
$(document).ready(function(){
  setInterval(function(){
    $("#screen").load('temperature.php')
  }, 1000);
});
</script>

```

其中，`#screen` 是标签 `<div>` 的 `id` ，你想在它里面显示温度。它会每隔 1000 毫秒加载一次 `temperature.php` 文件。

我使用了 bootstrap 框架来制作一个漂亮的面板来显示温度，你还可以加入多个图标和图形让网页更有吸引力。

这只是一个控制继电器板并显示温度的基础的系统，你可以通过创建基于定时和从恒温器读数等基于事件触发来进一步地对系统进行开发。

（ 题图：opensource.com）

---

作者简介：

Abdul Hannan Mustajab: 我 17 岁，生活在印度。我正在追求科学，数学和计算机科学方面的教育。我在 spunkytechnology.com 上发表关于我的项目的博客。我一直在对使用不同的微控制器和电路板的基于物联网的 AI 进行研究。

---

via: <https://opensource.com/article/17/3/operate-relays-control-gpio-pins-raspberry-pi>

作者：[Abdul Hannan Mustajab](https://opensource.com/users/mustajabhannan) 译者：[zhousiyu325](https://github.com/zhousiyu325) 校对：[wxy](https://github.com/wxy)

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


10 个使用 Cinnamon 作为 Linux 桌面环境的理由

kubuntu17.04倒还挺稳定的，只是少数几个软件偶尔会卡住

不喜欢的理由，一个就足够了。

为什么现在还有人喜欢这种类似 Windows 95 那种窄窄的任务栏，不觉得小吗？

因为我需要更多的工作空间，而不是一条大大的任务栏～

对于现在很多宽屏显示器来说，可以选择竖放任务栏。

说得好！我选择KDE

之前用过linux Mint 17, Cinnamon 确实易用，专有驱动安装很方便。操作跟 Windows 很接近。

但是有个问题就是中文输入法一直没有解决好，最后就放弃了。

现在版本号到18了，不知道中文输入有没有解决。

表示从来没遇到过这个问题，我用的是fcitx～

Cinnamon确实是很不错的界面，美观、适用

优麒麟安装这个，锁屏失效怎么回事

来自河南郑州的 Chrome Mobile 73.0|Android 10 用户

>
> Cinnamon 是一个让人怀旧 GNOME 2 的 Linux 桌面环境，它灵活、快速，并提供了种种的功能。
>
>
>

![10 reasons to use Cinnamon as your Linux desktop environment](/data/attachment/album/201706/14/182656xqq6lxvgrp6nql5n.jpg "10 reasons to use Cinnamon as your Linux desktop environment")

最近我安装了 Fedora 25，我觉得当前的 [KDE](https://opensource.com/life/15/4/9-reasons-to-use-kde) Plasma 版本并不稳定。在我决定尝试其它的桌面之前一天崩溃了好几次。在我安装了几个其它的桌面，并每个尝试了几个小时后，我最终决定在 Plasma 打上补丁并且稳定之前就使用 Cinnamon 了。以下是我所发现的。

### Cinnamon 简介

在 2011，带有新的 GNOME Shell 的 GNOME 3 发布了，新的界面马上引来了或正或反的反馈。许多用户以及开发者非常喜欢原先的 GNOME 界面，因此有多个组织复刻了它，其中一个结果就是 Cinnamon。

开发 GNOME 3 的 GNOME shell 背后的原因之一是许多原先的 GNOME 用户界面组件不再活跃开发了。这同样也是 Cinnamon 以及其他 GNOME 复刻项目的问题。 Linux Mint 项目是 Cinnamon 的一个首要推动者，因为 GNOME 是 Mint 的官方桌面环境。Mint 开发者已经将 Cinnamon 推进到了不需要 GNOME 本身的地步，Cinnamon 已经是一个完全独立的桌面环境，它保留了许多用户喜欢的 GNOME 界面的功能。

![cinnamon-desktop-environment.jpg](/data/attachment/album/201706/14/182657sfflfgzzddqdg9qh.jpg)

*图 1：打开系统设置工具的默认 Cinnamon 桌面。*

Cinnamon 3.2 是当前发布版本。除了 Mint，Cinnamon 还在许多发行版中可用，包括 Fedora、Arch、Gentoo、Debian 和 OpenSUSE 等。

### 使用 Cinnamon 的理由

这是我的使用 Cinnamon 的 10 个重要理由：

1. **集成。** 桌面的选择并不取决于在较长时间内是否有为它写的应用。我使用过的所有应用程序，不管它是在哪个桌面下写的，它都可以在任何其它桌面上运行正常，Cinnamon 也不例外。要运行那些为 KDE、GNOME 或其他桌面编写的程序所需要的库都有，可以在 Cinnamon 上面顺滑地使用这些程序。
2. **外观。** 让我们面对它，外观是很重要的。Cinnamon 有一个明快的、干净的外观，它使用了易于阅读的字体以及颜色的组合。桌面没有不必要的阻碍，你可以使用“系统设置” => “桌面” 菜单配置显示在桌面上的的图标。这个菜单还允许你指定是否在主监视器、次监视器或者所有监视器上显示桌面图标。
3. **桌面组件。** 桌面组件是一些小型的、可以添加到桌面的单一用途的程序。只有一些是可用的，但是你可以从 CPU 或者磁盘监视器、天气应用、便利贴、桌面相簿、时间和日期等之中选择。我喜欢时间和日期桌面组件，因为它比 Cinnamon 面板中的小程序易于阅读。
4. **速度。** Cinnamon 快速又敏捷。程序加载和显示很快。桌面自身在登录时加载也很快，虽然这只是我的主观体验，并没有基于时间测试。
5. **配置。**  Cinnamon 不如 KDE Plasma 那样可配置，但是也要比我第一次尝试它的时候有更多的配置。Cinnamon 控制中心提供了许多桌面配置选项的集中访问。它有一个主窗口，可以从它启动特定功能的配置窗口。可以很容易地在 “系统设置” 的 “主题” 的可用外观中选择新的外观。你可以选择窗口边框、图标、控件、鼠标指针和桌面基本方案。其它选择还包括字体和背景。我发现这些配置工具中有许多是我遇到的最好的。它有适量的桌面主题，从而能够显著改变桌面的外观，而不会像 KDE 那样面临选择困难。
6. **Cinnamon 面板。** Cinnamon 面板，即工具栏，最初的配置非常简单。它包含用于启动程序的菜单、基本的系统托盘和应用程序选择器。这个面板易于配置，并且添加新的程序启动器只需要定位你想要添加到主菜单的程序，右键单击程序图标，然后选择“添加到面板”。你还可以将启动器图标添加到桌面本身，以及 Cinnamon 的 “收藏” 的启动栏中。你还可以进入面板的**编辑**模式并重新排列图标。
7. **灵活性。** 有时可能很难找到最小化或者隐藏的正在运行的程序，如果有许多正在运行的应用程序，则在工具栏的程序选择器上查找它可能会有挑战性。 在某种程度上，这是因为程序并不总是有序地排在选择器中使其易于查找，所以我最喜欢的功能之一就是可以拖动正在运行的程序的按钮并将其重新排列在选择器上。这可以使查找和显示属于程序的窗口更容易，因为现在它们现在在我放的位置上。

Cinnamon 桌面还有一个非常好的弹出菜单，你可以右键单击访问。此菜单有一些常用任务，例如访问桌面设置、添加桌面组件以及其他与桌面相关的任务。

其它菜单项之一是 “创建新文档”，它使用位于 `~/Templates` 目录中的文档模板，并列出它们中的每一个。只需点击要使用的模板，使用这个模板的文档就会使用默认的 Office 程序创建。在我的情况下，那就是 LibreOffice。
8. **多工作空间。** Cinnamon 像其他桌面环境一样提供了多个桌面。Cinnamon 称它为“工作区”。工作区选择器位于 Cinnamon 面板中并展示每个工作区的窗口概览。窗口可以在工作区之间移动或指定到所有工作区。我确实发现工作区选择器有时候会比窗口位置的显示慢一些，所以我将工作区选择器切换为显示工作区编号，而不是在工作区中显示窗口概览。
9. **Nemo。** 大部分桌面因种种目而使用它们自己偏好的默认程序，Cinnamon 也不例外。我偏好的桌面文件管理器是 Krusader，但是 Cinnamon 默认使用 Nemo，因此在测试中我就用它了。我发现我很喜欢 Nemo。它有一个美丽干净的界面，我喜欢大部分功能并经常使用。它易于使用，同时对我的需求也足够灵活。虽然 Nemo 是 Nautilus 的复刻，但是我发现 Nemo 更好地被集成进了 Cinnamon 环境。Nautilus 界面看上去没有与 Cinnamon 很好集成，与 Cinnamon 不太和谐。
10. **稳定性。** Cinnamon 非常稳定且可用。

### 总结

Cinnamon 是 GNOME 3 桌面的复刻，它看上去像一个前所未有的 GNOME 桌面。它的发展看起来是符合逻辑的改进， Cinnamon 开发者认为需要在提升和扩展 GNOME 的同时保留它的独特性以及被大家非常喜欢的特性。它不再是 GNOME 3 - 它是不同的并且是更好的。Cinnamon 看上去很棒，并且对我而言也工作得很好，并且从 KDE 这个我仍旧非常喜欢的环境切换过来也很顺畅。我花费了几天时间学习 Cinnamon 的差异如何使我的桌面体验更好，并且我非常高兴了解这个很棒的桌面。

虽然我喜欢 Cinnamon，但我仍然喜欢体验其它的环境，我目前正切换到 LXDE 桌面，并已经用了几个星期。在我使用一段时间时候，我会分享我的 LXDE 体验。

（题图： [Sam Mugraby](https://commons.wikimedia.org/wiki/File:Cinnamon-other.jpg)，Photos8.com. [CC BY 2.0](https://creativecommons.org/licenses/by/2.0/deed.en)）

---

作者简介：

David Both 是一个 Linux 和开源倡导者，他居住在北卡罗莱纳州的 Raleigh。他在 IT 行业已经超过 40 年，在他工作的 IBM 公司教授 OS/2 超过 20 年，他在 1981 年为最早的 IBM PC 写了第一个培训课程。他教过 Red Hat 的 RHCE 课程，在 MCI Worldcom、 Cisco 和北卡罗莱纳州 工作过。他一直在使用 Linux 和开源软件近 20 年。

---

via: <https://opensource.com/article/17/1/cinnamon-desktop-environment>

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

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


许多 SQL 性能问题来自于“不必要的强制性工作”

Summary: 在编写高效 SQL 时，你可能遇到的最有影响的事情就是索引。但是，一个很重要的事实就是很多 SQL 客户端要求数据库做很多“不必要的强制性工作”。

可惜程序猿大佬不会理你，人家orm用的欢乐自在，性能？不关心

![](/data/attachment/album/201706/15/052446sud033e31e3wnk0d.jpg)

在编写高效 SQL 时，你可能遇到的最有影响的事情就是[索引](http://use-the-index-luke.com/)。但是，一个很重要的事实就是很多 SQL 客户端要求数据库做很多**“不必要的强制性工作”**。

跟我再重复一遍：

>
> 不必要的强制性工作
>
>
>

什么是**“不必要的强制性工作”**？这个意思包括两个方面：

### 不必要的

假设你的客户端应用程序需要这些信息：

![](/data/attachment/album/201706/15/051822srm0z88dd8od3kmk.png)

这没什么特别的。我们运行着一个电影数据库（[例如 Sakila 数据库](https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/Sakila)），我们想要给用户显示每部电影的名称和评分。

这是能产生上面结果的查询：

```
SELECT title, rating
FROM film

```

然而，我们的应用程序（或者我们的 ORM（LCTT 译注：<ruby> 对象关系映射 <rp>  （ </rp> <rt>  Object-Relational Mapping </rt> <rp>  ） </rp></ruby>））运行的查询却是：

```
SELECT *
FROM film

```

我们得到什么？猜一下。我们得到很多无用的信息：

![](/data/attachment/album/201706/15/051905dww82ciazoot8efr.png)

甚至一些复杂的 JSON 数据全程在下列环节中加载：

* 从磁盘
* 加载到缓存
* 通过总线
* 进入客户端内存
* 然后被丢弃

是的，我们丢弃了其中大部分的信息。检索它所做的工作完全就是不必要的。对吧？没错。

### 强制性

这是最糟糕的部分。现今随着优化器变得越来越聪明，这些工作对于数据库来说都是强制执行的。数据库没有办法*知道*客户端应用程序实际上不需要其中 95% 的数据。这只是一个简单的例子。想象一下如果我们连接更多的表...

你想想那会怎样呢？数据库还快吗？让我们来看看一些之前你可能没有想到的地方：

### 内存消耗

当然，单次执行时间不会变化很大。可能是慢 1.5 倍，但我们可以忍受，是吧？为方便起见，有时候确实如此。但是如果你*每次*都为了方便而牺牲性能，这事情就大了。我们不说性能问题（单个查询的速度），而是关注在吞吐量上时（系统响应时间），事情就变得困难而难以解决。你就会受阻于规模的扩大。

让我们来看看执行计划，这是 Oracle 的：

```
--------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes |
--------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1000 |   166K|
|   1 |  TABLE ACCESS FULL| FILM |  1000 |   166K|
--------------------------------------------------

```

对比一下：

```
--------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes |
--------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1000 | 20000 |
|   1 |  TABLE ACCESS FULL| FILM |  1000 | 20000 |
--------------------------------------------------

```

当执行 `SELECT *` 而不是 `SELECT film, rating` 的时候，我们在数据库中使用了 8 倍之多的内存。这并不奇怪，对吧？我们早就知道了。在很多我们并不需要其中全部数据的查询中我们都是这样做的。我们为数据库产生了**不必要的强制性工作**，其后果累加了起来，就是我们使用了多达 8 倍的内存（当然，数值可能有些不同）。

而现在，所有其它的步骤（比如，磁盘 I/O、总线传输、客户端内存消耗）也受到相同的影响，我这里就跳过了。另外，我还想看看...

### 索引使用

如今大部分数据库都有[涵盖索引](https://blog.jooq.org/2015/04/28/do-not-think-that-one-second-is-fast-for-query-execution/)（LCTT 译注：covering index，包括了你查询所需列、甚至更多列的索引，可以直接从索引中获取所有需要的数据，而无需访问物理表）的概念。涵盖索引并不是特殊的索引。但对于一个特定的查询，它可以“意外地”或人为地转变为一个“特殊索引”。

看看这个查询：

```
SELECT *
FROM actor
WHERE last_name LIKE 'A%'

```

执行计划中没有什么特别之处。它只是个简单的查询。索引范围扫描、表访问，就结束了：

```
-------------------------------------------------------------------
| Id  | Operation                   | Name                | Rows  |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                     |     8 |
|   1 |  TABLE ACCESS BY INDEX ROWID| ACTOR               |     8 |
|*  2 |   INDEX RANGE SCAN          | IDX_ACTOR_LAST_NAME |     8 |
-------------------------------------------------------------------

```

这是个好计划吗？如果我们只是想要这些，那么它就不是：

![](/data/attachment/album/201706/15/052004nl115ig8jfujf2gu.png)

当然，我们浪费了内存之类的。再来看看这个查询：

```
SELECT first_name, last_name
FROM actor
WHERE last_name LIKE 'A%'

```

它的计划是：

```
----------------------------------------------------
| Id  | Operation        | Name            | Rows  |
----------------------------------------------------
|   0 | SELECT STATEMENT |                 |     8 |
|*  1 |  INDEX RANGE SCAN| IDX_ACTOR_NAMES |     8 |
----------------------------------------------------

```

现在我们可以完全消除表访问，因为有一个索引涵盖了我们查询需要的所有东西……一个涵盖索引。这很重要吗？当然！这种方法可以将你的某些查询加速一个数量级（如果在某个更改后你的索引不再涵盖，可能会降低一个数量级）。

你不能总是从涵盖索引中获利。索引也有它们自己的成本，你不应该添加太多索引，例如像这种情况就是不明智的。让我们来做个测试：

```
SET SERVEROUTPUT ON
DECLARE
  v_ts TIMESTAMP;
  v_repeat CONSTANT NUMBER := 100000;
BEGIN
  v_ts := SYSTIMESTAMP;

  FOR i IN 1..v_repeat LOOP
    FOR rec IN (
      -- Worst query: Memory overhead AND table access
      SELECT *
      FROM actor
      WHERE last_name LIKE 'A%'
    ) LOOP
      NULL;
    END LOOP;
  END LOOP;

  dbms_output.put_line('Statement 1 : ' || (SYSTIMESTAMP - v_ts));
  v_ts := SYSTIMESTAMP;

  FOR i IN 1..v_repeat LOOP
    FOR rec IN (
      -- Better query: Still table access
      SELECT /*+INDEX(actor(last_name))*/
        first_name, last_name
      FROM actor
      WHERE last_name LIKE 'A%'
    ) LOOP
      NULL;
    END LOOP;
  END LOOP;

  dbms_output.put_line('Statement 2 : ' || (SYSTIMESTAMP - v_ts));
  v_ts := SYSTIMESTAMP;

  FOR i IN 1..v_repeat LOOP
    FOR rec IN (
      -- Best query: Covering index
      SELECT /*+INDEX(actor(last_name, first_name))*/
        first_name, last_name
      FROM actor
      WHERE last_name LIKE 'A%'
    ) LOOP
      NULL;
    END LOOP;
  END LOOP;

  dbms_output.put_line('Statement 3 : ' || (SYSTIMESTAMP - v_ts));
END;
/

```

结果是：

```
Statement 1 : +000000000 00:00:02.479000000
Statement 2 : +000000000 00:00:02.261000000
Statement 3 : +000000000 00:00:01.857000000

```

注意，表 actor 只有 4 列，因此语句 1 和 2 的差别并不是太令人印象深刻，但仍然很重要。还要注意我使用了 Oracle 的提示来强制优化器为查询选择一个或其它索引。在这种情况下语句 3 明显胜利。这是一个好*很多*的查询，也是一个十分简单的查询。

当我们写 `SELECT *` 语句时，我们为数据库带来了**不必要的强制性工作**，这是无法优化的。它不会使用涵盖索引，因为比起它所使用的 `LAST_NAME` 索引，涵盖索引开销更多一点，不管怎样，它都要访问表以获取无用的 `LAST_UPDATE` 列。

使用 `SELECT *` 会变得更糟。考虑一下……

### SQL 转换

优化器工作的很好，因为它们转换了你的 SQL 查询（[看我最近在 Voxxed Days Zurich 关于这方面的演讲](https://www.youtube.com/watch?v=wTPGW1PNy_Y)）。例如，其中有一个称为“表连接消除”的转换，它真的很强大。看看这个辅助视图，我们写了这个视图是因为我们非常讨厌总是连接所有这些表：

```
CREATE VIEW v_customer AS
SELECT
  c.first_name, c.last_name,
  a.address, ci.city, co.country
FROM customer c
JOIN address a USING (address_id)
JOIN city ci USING (city_id)
JOIN country co USING (country_id)

```

这个视图仅仅是把 `CUSTOMER` 和他们不同的 `ADDRESS` 部分所有“对一”关系连接起来。谢天谢地，它很工整。

现在，使用这个视图一段时间之后，想象我们非常习惯这个视图，我们都忘了所有它底层的表。然后，我们运行了这个查询：

```
SELECT *
FROM v_customer

```

我们得到了一个相当令人印象深刻的计划：

```
----------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes | Cost |
----------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |   599 | 47920 |   14 |
|*  1 |  HASH JOIN           |          |   599 | 47920 |   14 |
|   2 |   TABLE ACCESS FULL  | COUNTRY  |   109 |  1526 |    2 |
|*  3 |   HASH JOIN          |          |   599 | 39534 |   11 |
|   4 |    TABLE ACCESS FULL | CITY     |   600 | 10800 |    3 |
|*  5 |    HASH JOIN         |          |   599 | 28752 |    8 |
|   6 |     TABLE ACCESS FULL| CUSTOMER |   599 | 11381 |    4 |
|   7 |     TABLE ACCESS FULL| ADDRESS  |   603 | 17487 |    3 |
----------------------------------------------------------------

```

当然是这样。我们运行了所有这些表连接以及全表扫描，因为这就是我们让数据库去做的：获取所有的数据。

现在，再一次想一下，对于一个特定场景，我们真正想要的是：

![](/data/attachment/album/201706/15/052048ppr060vjj023jrpv.png)

是啊，对吧？现在你应该知道我的意图了。但想像一下，我们确实从前面的错误中学到了东西，现在我们实际上运行下面一个比较好的查询：

```
SELECT first_name, last_name
FROM v_customer

```

再来看看结果！

```
------------------------------------------------------------------
| Id  | Operation          | Name        | Rows  | Bytes | Cost  |
------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |   599 | 16173 |     4 |
|   1 |  NESTED LOOPS      |             |   599 | 16173 |     4 |
|   2 |   TABLE ACCESS FULL| CUSTOMER    |   599 | 11381 |     4 |
|*  3 |   INDEX UNIQUE SCAN| SYS_C007120 |     1 |     8 |     0 |
------------------------------------------------------------------

```

这是执行计划一个*极大的*进步。我们的表连接被消除了，因为优化器可以证明它们是**不必要的**，因此一旦它可以证明这点（而且你不会因使用 `select *` 而使其成为**强制性**工作），它就可以移除这些工作并不执行它。为什么会发生这种情况？

每个 `CUSTOMER.ADDRESS_ID` 外键保证了*有且只有一个* `ADDRESS.ADDRESS_ID` 主键值，因此可以保证 `JOIN` 操作是对一连接，它不会产生或者删除行。如果我们甚至不选择行或查询行，当然我们就不需要真正地去加载行。可以证实地移除 `JOIN` 并不会改变查询的结果。

数据库总是会做这些事情。你可以在大部分数据库上尝试它：

```
-- Oracle
SELECT CASE WHEN EXISTS (
  SELECT 1 / 0 FROM dual
) THEN 1 ELSE 0 END
FROM dual

-- 更合理的 SQL 语句，例如 PostgreSQL
SELECT EXISTS (SELECT 1 / 0)

```

在这种情况下，当你运行这个查询时你可能预料到会抛出算术异常：

```
SELECT 1 / 0 FROM dual

```

产生了：

```
ORA-01476: divisor is equal to zero

```

但它并没有发生。优化器（甚至解析器）可以证明 `EXISTS (SELECT ..)` 谓词内的任何 `SELECT` 列表达式不会改变查询的结果，因此也就没有必要计算它的值。呵！

### 同时……

大部分 ORM 最不幸问题就是事实上他们很随意就写出了 `SELECT *` 查询。事实上，例如 HQL / JPQL，就设置默认使用它。你甚至可以完全抛弃 `SELECT` 从句，因为毕竟你想要获取所有实体，正如声明的那样，对吧？

例如：

`FROM` `v_customer`

例如 [Vlad Mihalcea](https://vladmihalcea.com/2016/09/13/the-best-way-to-handle-the-lazyinitializationexception/)（一个 Hibernate 专家和 Hibernate 开发倡导者）建议你每次确定不想要在获取后进行任何更改时再使用查询。ORM 使解决对象图持久化问题变得简单。注意：持久化。真正修改对象图并持久化修改的想法是固有的。

但如果你不想那样做，为什么要抓取实体呢？为什么不写一个查询？让我们清楚一点：从性能角度，针对你正在解决的用例写一个查询*总是*会胜过其它选项。你可以不会在意，因为你的数据集很小，没关系。可以。但最终，你需要扩展并重新设计你的应用程序以便在强制实体图遍历之上支持查询语言，就会变得很困难。你也需要做其它事情。

### 计算出现次数

资源浪费最严重的情况是在只是想要检验存在性时运行 `COUNT(*)` 查询。例如：

>
> 这个用户有没有订单？
>
>
>

我们会运行：

```
SELECT count(*)
FROM orders
WHERE user_id = :user_id

```

很简单。如果 `COUNT = 0`：没有订单。否则：是的，有订单。

性能可能不会很差，因为我们可能有一个 `ORDERS.USER_ID` 列上的索引。但是和下面的这个相比你认为上面的性能是怎样呢：

```
-- Oracle
SELECT CASE WHEN EXISTS (
  SELECT *
  FROM orders
  WHERE user_id = :user_id
) THEN 1 ELSE 0 END
FROM dual

-- 更合理的 SQL 语句，例如 PostgreSQL
SELECT EXISTS (
  SELECT *
  FROM orders
  WHERE user_id = :user_id
)

```

它不需要火箭科学家来确定，一旦它找到一个，实际存在谓词就可以马上停止寻找额外的行。因此，如果答案是“没有订单”，速度将会是差不多。但如果结果是“是的，有订单”，那么结果在我们不计算具体次数的情况下就会*大幅*加快。

因为我们*不在乎*具体的次数。我们告诉数据库去计算它（**不必要的**），而数据库也不知道我们会丢弃所有大于 1 的结果（**强制性**）。

当然，如果你在 JPA 支持的集合上调用 `list.size()` 做同样的事情，情况会变得更糟！

[近期我有关于该情况的博客以及在不同数据库上的测试。去看看吧。](https://blog.jooq.org/2016/09/14/avoid-using-count-in-sql-when-you-could-use-exists/)

### 总结

这篇文章的立场很“明显”。别让数据库做**不必要的强制性工作**。

它**不必要**，因为对于你给定的需求，你*知道*一些特定的工作不需要完成。但是，你告诉数据库去做。

它**强制性**，因为数据库无法证明它是**不必要的**。这些信息只包含在客户端中，对于服务器来说无法访问。因此，数据库需要去做。

这篇文章大部分在介绍 `SELECT *`，因为这是一个很简单的目标。但是这并不仅限于数据库。这关系到客户端要求服务器完成**不必要的强制性工作**的任何分布式算法。你的 AngularJS 应用程序平均有多少个 N+1 问题，UI 在服务结果 A 上循环，多次调用服务 B，而不是把所有对 B 的调用打包为一个调用？这是一个复发的模式。

解决方法总是相同。你给执行你命令的实体越多信息，（理论上）它能更快执行这样的命令。每次都写一个好的查询。你的整个系统都会为此感谢你的。

### 如果你喜欢这篇文章...

再看看近期我在 Voxxed Days Zurich 的演讲，其中我展示了一些在数据处理算法上为什么 SQL 总是会胜过 Java 的双曲线例子。

（题图：Pixabay， CC0）

---

via: <https://blog.jooq.org/2017/03/08/many-sql-performance-problems-stem-from-unnecessary-mandatory-work>

作者：[jooq](https://blog.jooq.org/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

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