From 354cd21453505638455350aabe70ff29c435a50a Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Fri, 17 Mar 2017 18:28:34 +0800 Subject: [PATCH 01/25] translating... --- ...Why most High Level Languages are Slow.md | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/sources/tech/20150413 Why most High Level Languages are Slow.md b/sources/tech/20150413 Why most High Level Languages are Slow.md index 547e9867f5..337e9cb160 100644 --- a/sources/tech/20150413 Why most High Level Languages are Slow.md +++ b/sources/tech/20150413 Why most High Level Languages are Slow.md @@ -1,50 +1,82 @@ [kenxx](https://github.com/kenxx) -[Why (most) High Level Languages are Slow][7] +[为什么(大部分)高级语言运行效率较慢Why (most) High Level Languages are Slow][7] ============================================================ -Contents +内容 -* * [Cache costs review][1] +* * [回顾缓存消耗问题Cache costs review][1] * [Why C# introduces cache misses][2] - * [Garbage Collection][3] -* [Closing remarks][5] + * [垃圾回收Garbage Collection][3] +* [结语Closing remarks][5] In the last month or two I’ve had basically the same conversation half a dozen times, both online and in real life, so I figured I’d just write up a blog post that I can refer to in the future. +上一两个月中,我不下六次的和线上线下的朋友讨论了这个话题,所以我干脆直接把它写在博客中,以便以后查阅。 + The reason most high level languages are slow is usually because of two reasons: +大部分高级语言运行效率较慢的原因通常有两点: + 1. They don’t play well with the cache. 2. They have to do expensive garbage collections +1. 没有很好的利用缓存; +2. 垃圾回收机制性能消耗高。 + But really, both of these boil down to a single reason: the language heavily encourages too many allocations. +但事实上,这两个原因可以归因于:高级语言强烈地鼓励去使用很多的内存。 + First, I’ll just state up front that for all of this I’m talking mostly about client-side applications. If you’re spending 99.9% of your time waiting on the network then it probably doesn’t matter how slow your language is – optimizing network is your main concern. I’m talking about applications where local execution speed is important. +首先,以下内容大部分是关于客户端应用的。如果你花费了 99.9% 的时间去等待网络,那么这很可能不是拖慢语言运行效率的原因——优化网络是优先考虑的问题。在本文中程序本地执行速度才是重要的。 + I’m going to pick on C# as the specific example here for two reasons: the first is that it’s the high level language I use most often these days, and because if I used Java I’d get a bunch of C# fans telling me how it has value types and therefore doesn’t have these issues (this is wrong). +我将选用 C# 语言作为本文参考语言,其原因有二:首先这是个最近我常用的高级语言;其次如果我使用 Java 语言,许多使用 C# 的朋友会告诉我 C# 不会有这些问题,因为它有值类型(但这是错误的)。 + In the following I will be talking about what happens when you write idiomatic code. When you work “with the grain” of the language. When you write code in the style of the standard libraries and tutorials. I’m not very interested in ugly workarounds as “proof” that there’s no problem. Yes, you can sometimes fight the language to avoid a particular issue, but that doesn’t make the language unproblematic. +接下来我将会讨论,出于编程习惯编写的代码、使用普遍编程方法(with the grain)的代码或使用库或教程中提到的常用代码来编写程序时会发生什么。我对编程时使用丑陋的解决方法来“证明”语言本身没问题这事没有兴趣,当然你可以和语言抗争来避免该语言独有的问题,但这并不能说明语言本身是没有问题的。 + ### Cache costs review +### 回顾缓存消耗问题 + First, let’s review the importance of playing well with the cache. Here’s a graph based on [this data][10] on memory latencies for Haswell: +首先我们先来回顾一下合理使用缓存的重要性。下图是基于在 Haswell 架构下内存潜在因素对其影响的 [数据][10]: + ![](https://www.sebastiansylvan.com/img/041315_0638_whymosthigh1.png) The latency for this particular CPU to get to memory is about 230 cycles, meanwhile the cost of reading data from L1 is 4 cycles. The key takeaway here is that doing the wrong thing for the cache can make code ~50x slower. In fact, it may be even worse than that – modern CPUs can often do multiple things at once so you could be loading stuff from L1 while operating on stuff that’s already in registers, thus hiding the L1 load cost partially or completely. +内存的潜在因素对于这款 CPU 要读取内存的数据需要近 230 个运算周期,同时需要从 L1 缓冲区消耗 4 个运算周期来读取数据。此处的关键是当错误的去使用缓存可导致运行速度拖慢近 50 倍。事实上,这并不是最糟糕的——在现代的 CPU 中它们都能同时地做多种操作,所以当你一边加载 L1 缓冲区的内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗被完整的隐藏了起来。 + Without exaggerating we can say that aside from making reasonable algorithm choices, cache misses are the main thing you need to worry about for performance. Once you’re accessing data efficiently you can worry about fine tuning the actual operations you do. In comparison to cache misses, minor inefficiencies just don’t matter much. +撇开选择合理的算法不谈,不夸张地讲,在性能优化中你要考虑的最主要因素其实是缓存未命中。当你能够有效的访问一个数据时候,你才可以调整你的每个具体的操作。与缓存未命中问题相比,次要的低效问题对效率并没有什么过多的影响。 + This is actually good news for language designers! You don’t  _have_  to build the most efficient compiler on the planet, and you totally can get away with some extra overhead here and there for your abstractions (e.g. array bounds checking), all you need to do is make sure that your design makes it easy to write code that accesses data efficiently and programs in your language won’t have any problems running at speeds that are competitive with C. +这对于编程语言的设计者来说是一个好消息!你都_不需要_去建造一个最高效的编译器,你可以完全摆脱一些额外的开销(比如:数组边界检查),你只需要专注怎么设计能使你的语言访问数据更高效、又不用担心与 C 语言代码比较运行速度。 + + ### Why C# introduces cache misses +### 为什么介绍 C# 的缓存未命中问题 + To put it bluntly, C# is a language that simply isn’t designed to run efficiently with modern cache realities in mind. Again, I’m now talking about the limitations of the design and the “pressure” it puts on the programmer to do things in inefficient ways. Many of these things have theoretical workarounds that you could do at great inconvenience. I’m talking about idiomatic code, what the language “wants” you to do. +坦率地讲,C# 在设计时就没打算在现代缓存中实现高效运行。我又一次提到程序语言设计的局限性以及其带给程序员无法编写高效的代码的“压力”。大部分的理论解决方法都非常的不便。我是在说那些编程语言“希望”你这样编写的习惯性代码。 + The basic problem with C# is that it has very poor support for value-based programming. Yes, it has structs which are values that are stored “embedded” where they are declared (e.g. on the stack, or inside another object). But there are a several big issues with structs that make them more of a band-aid than a solution. +C# 最基本的问题是对于 `value-based` 低下的支持性 + * You have to declare your data types as struct up front – which means that if you  _ever_  need this type to exist as a heap allocation then  _all_  of them need to be heap allocations. You could make some kind of class-wrapper for your struct and forward all the members but it’s pretty painful. It would be better if classes and structs were declared the same way and could be used in both ways on a case-by-case basis. So when something can live on the stack you declare it as a value, and when it needs to be on the heap you declare it as an object. This is how C++ works, for example. You’re not encouraged to make everything into an object-type just because there’s a few things here and there that need them on the heap. * _Referencing_  values is extremely limited. You can pass values by reference to functions, but that’s about it. You can’t just grab a reference to an element in a List, you have to store both a reference to the list and an index. You can’t grab a pointer to a stack-allocated value, or a value stored inside an object (or value). You can only copy them, unless you’re passing them to a function (by ref). This is all understandable, by the way. If type safety is a priority, it’s pretty difficult (though not imposible) to support flexible referencing of values while also guaranteeing type safety. The rationale behind these restrictions don’t change the fact that the restrictions are there, though. From 4a09b4cf89fa639e82b5751031e9196737d0e98e Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Tue, 21 Mar 2017 19:47:53 +0800 Subject: [PATCH 02/25] continue --- ...Why most High Level Languages are Slow.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sources/tech/20150413 Why most High Level Languages are Slow.md b/sources/tech/20150413 Why most High Level Languages are Slow.md index 337e9cb160..af6b367529 100644 --- a/sources/tech/20150413 Why most High Level Languages are Slow.md +++ b/sources/tech/20150413 Why most High Level Languages are Slow.md @@ -7,14 +7,14 @@ * * [回顾缓存消耗问题Cache costs review][1] - * [Why C# introduces cache misses][2] + * [为什么 C# 存在缓存未命中问题Why C# introduces cache misses][2] * [垃圾回收Garbage Collection][3] * [结语Closing remarks][5] In the last month or two I’ve had basically the same conversation half a dozen times, both online and in real life, so I figured I’d just write up a blog post that I can refer to in the future. -上一两个月中,我不下六次的和线上线下的朋友讨论了这个话题,所以我干脆直接把它写在博客中,以便以后查阅。 +在近两个个月中,我多次的和线上线下的朋友讨论了这个话题,所以我干脆直接把它写在博客中,以便以后查阅。 The reason most high level languages are slow is usually because of two reasons: @@ -28,19 +28,19 @@ The reason most high level languages are slow is usually because of two reasons: But really, both of these boil down to a single reason: the language heavily encourages too many allocations. -但事实上,这两个原因可以归因于:高级语言强烈地鼓励去使用很多的内存。 +但事实上,这两个原因可以归因于:高级语言强烈地鼓励编程人员分配很多的内存。 First, I’ll just state up front that for all of this I’m talking mostly about client-side applications. If you’re spending 99.9% of your time waiting on the network then it probably doesn’t matter how slow your language is – optimizing network is your main concern. I’m talking about applications where local execution speed is important. -首先,以下内容大部分是关于客户端应用的。如果你花费了 99.9% 的时间去等待网络,那么这很可能不是拖慢语言运行效率的原因——优化网络是优先考虑的问题。在本文中程序本地执行速度才是重要的。 +首先,下文内容主要讨论客户端应用。如果你的程序有 99.9% 的时间都在等待网络,那么这很可能不是拖慢语言运行效率的原因——优先考虑的问题当然是优化网络。在本文中,我们主要讨论程序在本地执行的速度。 I’m going to pick on C# as the specific example here for two reasons: the first is that it’s the high level language I use most often these days, and because if I used Java I’d get a bunch of C# fans telling me how it has value types and therefore doesn’t have these issues (this is wrong). -我将选用 C# 语言作为本文参考语言,其原因有二:首先这是个最近我常用的高级语言;其次如果我使用 Java 语言,许多使用 C# 的朋友会告诉我 C# 不会有这些问题,因为它有值类型(但这是错误的)。 +我将选用 C# 语言作为本文的参考语言,其原因有二:首先它是我常用的高级语言;其次如果我使用 Java 语言,许多使用 C# 的朋友会告诉我 C# 不会有这些问题,因为它有值类型(但这是错误的)。 In the following I will be talking about what happens when you write idiomatic code. When you work “with the grain” of the language. When you write code in the style of the standard libraries and tutorials. I’m not very interested in ugly workarounds as “proof” that there’s no problem. Yes, you can sometimes fight the language to avoid a particular issue, but that doesn’t make the language unproblematic. -接下来我将会讨论,出于编程习惯编写的代码、使用普遍编程方法(with the grain)的代码或使用库或教程中提到的常用代码来编写程序时会发生什么。我对编程时使用丑陋的解决方法来“证明”语言本身没问题这事没有兴趣,当然你可以和语言抗争来避免该语言独有的问题,但这并不能说明语言本身是没有问题的。 +接下来我将会讨论,出于编程习惯编写的代码、使用普遍编程方法(with the grain)的代码或使用库或教程中提到的常用代码来编写程序时会发生什么。我对那些使用难搞的办法来解决语言自身毛病以“证明”语言没毛病这事没兴趣,当然你可以和语言抗争来避免它的毛病,但这并不能说明语言本身是没有问题的。 ### Cache costs review @@ -54,24 +54,24 @@ First, let’s review the importance of playing well with the cache. Here’s a The latency for this particular CPU to get to memory is about 230 cycles, meanwhile the cost of reading data from L1 is 4 cycles. The key takeaway here is that doing the wrong thing for the cache can make code ~50x slower. In fact, it may be even worse than that – modern CPUs can often do multiple things at once so you could be loading stuff from L1 while operating on stuff that’s already in registers, thus hiding the L1 load cost partially or completely. -内存的潜在因素对于这款 CPU 要读取内存的数据需要近 230 个运算周期,同时需要从 L1 缓冲区消耗 4 个运算周期来读取数据。此处的关键是当错误的去使用缓存可导致运行速度拖慢近 50 倍。事实上,这并不是最糟糕的——在现代的 CPU 中它们都能同时地做多种操作,所以当你一边加载 L1 缓冲区的内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗被完整的隐藏了起来。 +针对这款 CPU 的内存因素,读取内存的数据需要近 230 个运算周期,同时需要消耗 L1 缓冲区的 4 个运算周期。因此错误的去使用缓存可导致运行速度拖慢近 50 倍。还好这并不是最糟糕的——在现代 CPU 中它们能同时地做多种操作,所以当你加载 L1 缓冲区内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗就被完整的隐藏了起来。 Without exaggerating we can say that aside from making reasonable algorithm choices, cache misses are the main thing you need to worry about for performance. Once you’re accessing data efficiently you can worry about fine tuning the actual operations you do. In comparison to cache misses, minor inefficiencies just don’t matter much. -撇开选择合理的算法不谈,不夸张地讲,在性能优化中你要考虑的最主要因素其实是缓存未命中。当你能够有效的访问一个数据时候,你才可以调整你的每个具体的操作。与缓存未命中问题相比,次要的低效问题对效率并没有什么过多的影响。 +撇开选择合理的算法不谈,不夸张地讲,在性能优化中你要考虑的最主要因素其实是缓存未命中。当你能够有效的访问一个数据时候,你才可以调整你的每个具体的操作。与缓存未命中的问题相比,那些次要的低效问题对运行速度并没有什么过多的影响。 This is actually good news for language designers! You don’t  _have_  to build the most efficient compiler on the planet, and you totally can get away with some extra overhead here and there for your abstractions (e.g. array bounds checking), all you need to do is make sure that your design makes it easy to write code that accesses data efficiently and programs in your language won’t have any problems running at speeds that are competitive with C. -这对于编程语言的设计者来说是一个好消息!你都_不需要_去建造一个最高效的编译器,你可以完全摆脱一些额外的开销(比如:数组边界检查),你只需要专注怎么设计能使你的语言访问数据更高效、又不用担心与 C 语言代码比较运行速度。 +这对于编程语言的设计者来说是一个好消息!你都_不必_去编写一个更高效的编译器,你可以完全摆脱一些额外的开销(比如:数组边界检查),你只需要专注怎么设计能使你的语言访问数据更高效,也不用担心与 C 语言代码比较运行速度。 ### Why C# introduces cache misses -### 为什么介绍 C# 的缓存未命中问题 +### 为什么 C# 存在缓存未命中问题 To put it bluntly, C# is a language that simply isn’t designed to run efficiently with modern cache realities in mind. Again, I’m now talking about the limitations of the design and the “pressure” it puts on the programmer to do things in inefficient ways. Many of these things have theoretical workarounds that you could do at great inconvenience. I’m talking about idiomatic code, what the language “wants” you to do. -坦率地讲,C# 在设计时就没打算在现代缓存中实现高效运行。我又一次提到程序语言设计的局限性以及其带给程序员无法编写高效的代码的“压力”。大部分的理论解决方法都非常的不便。我是在说那些编程语言“希望”你这样编写的习惯性代码。 +坦率地讲 C# 在设计时就没打算在现代缓存中实现高效运行。我又一次提到程序语言设计的局限性以及其带给程序员无法编写高效的代码的“压力”。大部分的理论解决方法都非常的不便。我是在说那些编程语言“希望”你这样编写的习惯性代码。 The basic problem with C# is that it has very poor support for value-based programming. Yes, it has structs which are values that are stored “embedded” where they are declared (e.g. on the stack, or inside another object). But there are a several big issues with structs that make them more of a band-aid than a solution. From 60dea920ee82566d8579af3dc96c2976f48aba09 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Wed, 22 Mar 2017 19:36:00 +0800 Subject: [PATCH 03/25] just few lines --- .../tech/20150413 Why most High Level Languages are Slow.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/tech/20150413 Why most High Level Languages are Slow.md b/sources/tech/20150413 Why most High Level Languages are Slow.md index af6b367529..5f52fc447b 100644 --- a/sources/tech/20150413 Why most High Level Languages are Slow.md +++ b/sources/tech/20150413 Why most High Level Languages are Slow.md @@ -75,11 +75,13 @@ To put it bluntly, C# is a language that simply isn’t designed to run efficien The basic problem with C# is that it has very poor support for value-based programming. Yes, it has structs which are values that are stored “embedded” where they are declared (e.g. on the stack, or inside another object). But there are a several big issues with structs that make them more of a band-aid than a solution. -C# 最基本的问题是对于 `value-based` 低下的支持性 +C# 最基本的问题是对基础值类型(value-base)低下的支持性。其大部分的数据结构都是“内置”在语言内定义的(例如:栈,或其他内置对象)。但这些具有帮助性的内置结构体恰恰好会造成一些大问题。 * You have to declare your data types as struct up front – which means that if you  _ever_  need this type to exist as a heap allocation then  _all_  of them need to be heap allocations. You could make some kind of class-wrapper for your struct and forward all the members but it’s pretty painful. It would be better if classes and structs were declared the same way and could be used in both ways on a case-by-case basis. So when something can live on the stack you declare it as a value, and when it needs to be on the heap you declare it as an object. This is how C++ works, for example. You’re not encouraged to make everything into an object-type just because there’s a few things here and there that need them on the heap. +* 你得把自己定义的结构体类型在最先声明——这意味着你如果需要用到这个类型作为堆分配,那么所有的结构体都会被堆分配。你也可以使用一些类包装器来打包你的结构体和其中的成员变量,但这十分的痛苦。如果类和结构体可以相同的方式声明,并且可根据具体情况来使用,这将是更好的。当数据可以作为值地存储在自定义的栈中,当这个数据需要被对分配时你就可以将其定义为一个对象,比如 C++ 就是这样工作的。因为只有少数的内容需要被堆分配,所以我们不鼓励所有的内容都被定义为对象类型。 * _Referencing_  values is extremely limited. You can pass values by reference to functions, but that’s about it. You can’t just grab a reference to an element in a List, you have to store both a reference to the list and an index. You can’t grab a pointer to a stack-allocated value, or a value stored inside an object (or value). You can only copy them, unless you’re passing them to a function (by ref). This is all understandable, by the way. If type safety is a priority, it’s pretty difficult (though not imposible) to support flexible referencing of values while also guaranteeing type safety. The rationale behind these restrictions don’t change the fact that the restrictions are there, though. +* _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然不可能)。 * [Fixed sized buffers][6] don’t support custom types and also requires you to use an unsafe keyword. From 4235a30e9078deb2baf0e55926b2b1ad5c143b65 Mon Sep 17 00:00:00 2001 From: kenneth Date: Wed, 22 Mar 2017 23:24:31 +0800 Subject: [PATCH 04/25] translating --- .../tech/20150413 Why most High Level Languages are Slow.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename {sources => translated}/tech/20150413 Why most High Level Languages are Slow.md (99%) diff --git a/sources/tech/20150413 Why most High Level Languages are Slow.md b/translated/tech/20150413 Why most High Level Languages are Slow.md similarity index 99% rename from sources/tech/20150413 Why most High Level Languages are Slow.md rename to translated/tech/20150413 Why most High Level Languages are Slow.md index 5f52fc447b..a0d145b385 100644 --- a/sources/tech/20150413 Why most High Level Languages are Slow.md +++ b/translated/tech/20150413 Why most High Level Languages are Slow.md @@ -81,9 +81,10 @@ C# 最基本的问题是对基础值类型(value-base)低下的支持性。 * 你得把自己定义的结构体类型在最先声明——这意味着你如果需要用到这个类型作为堆分配,那么所有的结构体都会被堆分配。你也可以使用一些类包装器来打包你的结构体和其中的成员变量,但这十分的痛苦。如果类和结构体可以相同的方式声明,并且可根据具体情况来使用,这将是更好的。当数据可以作为值地存储在自定义的栈中,当这个数据需要被对分配时你就可以将其定义为一个对象,比如 C++ 就是这样工作的。因为只有少数的内容需要被堆分配,所以我们不鼓励所有的内容都被定义为对象类型。 * _Referencing_  values is extremely limited. You can pass values by reference to functions, but that’s about it. You can’t just grab a reference to an element in a List, you have to store both a reference to the list and an index. You can’t grab a pointer to a stack-allocated value, or a value stored inside an object (or value). You can only copy them, unless you’re passing them to a function (by ref). This is all understandable, by the way. If type safety is a priority, it’s pretty difficult (though not imposible) to support flexible referencing of values while also guaranteeing type safety. The rationale behind these restrictions don’t change the fact that the restrictions are there, though. -* _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然不可能)。 +* _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然这不可能)。 * [Fixed sized buffers][6] don’t support custom types and also requires you to use an unsafe keyword. +* * Limited “array slice” functionality. There’s an ArraySegment class, but it’s not really used by anyone, which means that in order to pass a range of elements from an array you have to create an IEnumerable, which means allocation (boxing). Even if the APIs accepted ArraySegment parameters it’s still not good enough – you can only use it for normal arrays, not for List, not for [stack-allocated array][4]s, etc. From 1de30b3c6ffe827c8b4738fbcd8f244b7e0f9f86 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Thu, 23 Mar 2017 19:15:01 +0800 Subject: [PATCH 05/25] just few lines --- ...150413 Why most High Level Languages are Slow.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sources/tech/20150413 Why most High Level Languages are Slow.md b/sources/tech/20150413 Why most High Level Languages are Slow.md index 5f52fc447b..9ebf5e0b6d 100644 --- a/sources/tech/20150413 Why most High Level Languages are Slow.md +++ b/sources/tech/20150413 Why most High Level Languages are Slow.md @@ -84,23 +84,33 @@ C# 最基本的问题是对基础值类型(value-base)低下的支持性。 * _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然不可能)。 * [Fixed sized buffers][6] don’t support custom types and also requires you to use an unsafe keyword. +* [固定大小的缓冲区][6] 不支持自定义类型,而且还必须使用 `unsafe` 关键字。 * Limited “array slice” functionality. There’s an ArraySegment class, but it’s not really used by anyone, which means that in order to pass a range of elements from an array you have to create an IEnumerable, which means allocation (boxing). Even if the APIs accepted ArraySegment parameters it’s still not good enough – you can only use it for normal arrays, not for List, not for [stack-allocated array][4]s, etc. +* 有限的“数组切片”功能。虽然有提供 `ArraySegment` 类,但并没有人会使用它,这意味着如果只需要传递数组的一部分,你必须去创建一个 `IEnumerable` 对象,也就意味着要分配大小(包装)。就算接口接受 `ArraySegment` 对象作为参数,也是不够的——你只能用普通数组,而不能用 `List`,也不能用 [栈数组][4] 等等。 The bottom line is that for all but very simple cases, the language pushes you very strongly towards heap allocations. If all your data is on the heap, it means that accessing it is likely to cause a cache misses (since you can’t decide how objects are organized in the heap). So while a C++ program poses few challenges to ensuring that data is organized in cache-efficient ways, C# typically encourages you to allocate each part of that data in a separate heap allocation. This means the programmers loses control over data layout, which means unnecessary cache misses are introduced and performance drops precipitously. It doesn’t matter that [you can now compile C# programs natively][11] ahead of time – improvement to code quality is a drop in the bucket compared to poor memory locality. +最重要的是,除了非常简单的情况之外,C# 非常惯用堆分配。如果所有的数据都被堆分配,这意味着被访问时会造成缓存未命中(从你无法决定对象是如何在堆中存储开始)。所以当 C++ 程序面临着如何有效的组织数据在缓存中的存储这个挑战时,C# 则鼓励程序员去将数据分开的存放在一个个堆分配空间中。这就意味着程序员无法控制数据层了,也就意味着开始产生不必要的缓存未命中问题,也就导致性能急速的下降了。[C# 已经支持原生编译][11] 也不会提升太多性能——毕竟在内存不足的情况下,提高代码质量本就杯水车薪。 -Plus, there’s storage overhead. Each reference is 8 bytes on a 64-bit machine, and each allocation has its own overhead in the form of various metadata. A heap full of tiny objects with lots of references everywhere has a lot of space overhead compared to a heap with very few large allocations where most data is just stored embedded within their owners at fixed offsets. Even if you don’t care about memory requirements, the fact that the heap is bloated with header words and references means that cache lines have more waste in them, this in turn means even more cache misses and reduced performance. +Plus, there’s storage overhead. Each reference is 8 bytes on a 64-bit machine, and each allocation has its own overhead in the form of various metadata. A heap full of tiny objects with lots of references everywhere has a lot of space overhead compared to a heap with very few large allocations where most data is just stored embedded within their owners at fixed offsets. +Even if you don’t care about memory requirements, the fact that the heap is bloated with header words and references means that cache lines have more waste in them, this in turn means even more cache misses and reduced performance. +存储是有开销的。在64位的机器上每个地址值占8位内存,而每次分配都会有存储元数据而产生的开销。与存储着少量大数据(以固定偏移的方式存储在其中)的堆相比,存储着大量小数据的堆(并且其中的数据到处都被引用)会产生更多的内存开销。尽管你可能不怎么关心内存怎么用,但事实上就是那些头部内容和地址信息导致堆变得臃肿,也就是在浪费缓存了,所以也造成了更多的缓存未命中,降低了代码性能。 There are sometimes workarounds you can do, for example you can use structs and allocate them in a pool using a big List. This allows you to e.g. traverse the pool and update all of the objects in-bulk, getting good locality. This does get pretty messy though, because now anything else wanting to refer to one of these objects have to have a reference to the pool as well as an index, and then keep doing array-indexing all over the place. For this reason, and the reasons above, it is significantly more painful to do this sort of stuff in C# than it is to do it in C++, because it’s just not something the language was designed to do. Furthermore, accessing a single element in the pool is now more expensive than just having an allocation per object - you now get  _two_  cache misses because you have to first dereference the pool itself (since it’s a class). Ok, so you can duplicate the functionality of List in struct-form and avoid this extra cache miss and make things even uglier. I’ve written plenty of code just like this and it’s just extremely low level and error prone. +当然有些时候也是有办法的,比如你可以使用一个很大的 `List` 来构造数据池以存储分配你需要的数据和自己的结构体。这样你就可以方便的遍历或者批量更新你的数据池中的数据了。但这也会很混乱,因为无论你在哪要引用什么对象都要先能引用这个池,然后每次引用都需要做数组索引。从上文可以得出,在 C# 中做类似这样的处理的痛感比在 C++ 中做来的更痛,因为 C# 在设计时就是这样。此外,通过这种方式来访问池中的单个对象比直接将这个对象分配到内存来访问更加的昂贵——前者你得先访问池(这是个类)的地址,这意味着可能产生 _2_ 次缓存未命中。你还可以通过复制 `List` 的结构形式来避免更多的缓存未命中问题,但这就更难搞了。我就写过很多类似的代码,自然这样的代码只会很低水平而且容易出错。 Finally, I want to point out that this isn’t just an issue for “hot spot” code. Idiomatically written C# code tends to have classes and references basically  _everywhere_ . This means that all over your code at relatively uniform frequency there are random multi-hundred cycle stalls, dwarfing the cost of surrounding operations. Yes there could be hotspots too, but after you’ve optimized them you’re left with a program that’s just [uniformly slow.][12] So unless you want to write all your code with memory pools and indices, effectively operating at a lower level of abstraction than even C++ does (and at that point, why bother with C#?), there’s not a ton you can do to avoid this issue. +最后,我想说我指出的问题不仅是那些“热门”的代码。惯用手段编写的 C# 代码倾向于几乎所有地方都用类和引用。意思就是在你的代码中会均匀频率地随机出现数百次的运算周期损耗,使得操作的损耗似乎降低了。这虽然也可以被找出来,但你优化了这问题后,这还是一个 [均匀变慢][12] 的程序。 ### Garbage Collection +### 垃圾回收 I’m just going to assume in the following that you already understand why garbage collection is a performance problem in a lot of cases. That pausing randomly for many milliseconds just is usually unacceptable for anything with animation. I won’t linger on it and move on to explaining why the language design itself exacerbates this issue. +在读下文之前我会假设你已经知道为什么在许多用例中垃圾回收是影响性能问题的重要原因。播放动画时总是随机的暂停通常都是大家都不能接受的吧。我会继续解释为什么设计语言时还加剧了这个问题。 Because of the limitations when it comes to dealing with values, the language very strongly discourages you from using big chunky allocations consisting mostly of values embedded within other values (perhaps stored on the stack), pressuring you instead to use lots of small classes which have to be allocated on the heap. Roughly speaking, more allocations means more time spent collecting garbage. + There are benchmarks that show how C# or Java beat C++ in some particular case, because an allocator based on a GC can have decent throughput (cheap allocations, and you batch all the deallocations up). However, this isn’t a common real world scenario. It takes a huge amount of effort to write a C# program with the same low allocation rate that even a very naïve C++ program has, so those kinds of comparisons are really comparing a highly tuned managed program with a naïve native one. Once you spend the same amount of effort on the C++ program, you’d be miles ahead of C# again. I’m relatively convinced that you could write a GC more suitable for high performance and low latency applications (e.g. an incremental GC where you spend a fixed amount of time per frame doing collection), but this is not enough on its own. At the end of the day the biggest issue with most high level languages is simply that the design encourages far too much garbage being created in the first place. If idiomatic C# allocated at the same low rate a C program does, the GC would pose far fewer problems for high performance applications. And if you  _did_  have an incremental GC to support soft real-time applications, you’ll probably need a write barrier for it – which, as cheap as it is, means that a language that encourages pointers will add a performance tax to the mutators. From 46f25da6c33e96335c7d3f349d99caf01e0bce69 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Thu, 23 Mar 2017 19:23:33 +0800 Subject: [PATCH 06/25] conflicts --- .../tech/20150413 Why most High Level Languages are Slow.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/translated/tech/20150413 Why most High Level Languages are Slow.md b/translated/tech/20150413 Why most High Level Languages are Slow.md index 0ed6929e74..d3be05cf31 100644 --- a/translated/tech/20150413 Why most High Level Languages are Slow.md +++ b/translated/tech/20150413 Why most High Level Languages are Slow.md @@ -84,11 +84,7 @@ C# 最基本的问题是对基础值类型(value-base)低下的支持性。 * _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然这不可能)。 * [Fixed sized buffers][6] don’t support custom types and also requires you to use an unsafe keyword. -<<<<<<< HEAD:sources/tech/20150413 Why most High Level Languages are Slow.md * [固定大小的缓冲区][6] 不支持自定义类型,而且还必须使用 `unsafe` 关键字。 -======= -* ->>>>>>> 4235a30e9078deb2baf0e55926b2b1ad5c143b65:translated/tech/20150413 Why most High Level Languages are Slow.md * Limited “array slice” functionality. There’s an ArraySegment class, but it’s not really used by anyone, which means that in order to pass a range of elements from an array you have to create an IEnumerable, which means allocation (boxing). Even if the APIs accepted ArraySegment parameters it’s still not good enough – you can only use it for normal arrays, not for List, not for [stack-allocated array][4]s, etc. * 有限的“数组切片”功能。虽然有提供 `ArraySegment` 类,但并没有人会使用它,这意味着如果只需要传递数组的一部分,你必须去创建一个 `IEnumerable` 对象,也就意味着要分配大小(包装)。就算接口接受 `ArraySegment` 对象作为参数,也是不够的——你只能用普通数组,而不能用 `List`,也不能用 [栈数组][4] 等等。 From 4f0a6f9ad0bea3fd4a55f2d273b8b8b4464bc655 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Fri, 24 Mar 2017 18:23:04 +0800 Subject: [PATCH 07/25] done --- ...Why most High Level Languages are Slow.md | 87 +++++-------------- 1 file changed, 20 insertions(+), 67 deletions(-) diff --git a/translated/tech/20150413 Why most High Level Languages are Slow.md b/translated/tech/20150413 Why most High Level Languages are Slow.md index d3be05cf31..1b6d5beb1d 100644 --- a/translated/tech/20150413 Why most High Level Languages are Slow.md +++ b/translated/tech/20150413 Why most High Level Languages are Slow.md @@ -1,140 +1,93 @@ -[kenxx](https://github.com/kenxx) - -[为什么(大部分)高级语言运行效率较慢Why (most) High Level Languages are Slow][7] +[为什么(大部分)高级语言运行效率较慢][7] ============================================================ 内容 -* * [回顾缓存消耗问题Cache costs review][1] - * [为什么 C# 存在缓存未命中问题Why C# introduces cache misses][2] - * [垃圾回收Garbage Collection][3] -* [结语Closing remarks][5] +* * [回顾缓存消耗问题][1] + * [为什么 C# 存在缓存未命中问题][2] + * [垃圾回收][3] +* [结语][5] -In the last month or two I’ve had basically the same conversation half a dozen times, both online and in real life, so I figured I’d just write up a blog post that I can refer to in the future. - 在近两个个月中,我多次的和线上线下的朋友讨论了这个话题,所以我干脆直接把它写在博客中,以便以后查阅。 -The reason most high level languages are slow is usually because of two reasons: - 大部分高级语言运行效率较慢的原因通常有两点: -1. They don’t play well with the cache. -2. They have to do expensive garbage collections - 1. 没有很好的利用缓存; 2. 垃圾回收机制性能消耗高。 -But really, both of these boil down to a single reason: the language heavily encourages too many allocations. - 但事实上,这两个原因可以归因于:高级语言强烈地鼓励编程人员分配很多的内存。 -First, I’ll just state up front that for all of this I’m talking mostly about client-side applications. If you’re spending 99.9% of your time waiting on the network then it probably doesn’t matter how slow your language is – optimizing network is your main concern. I’m talking about applications where local execution speed is important. - 首先,下文内容主要讨论客户端应用。如果你的程序有 99.9% 的时间都在等待网络,那么这很可能不是拖慢语言运行效率的原因——优先考虑的问题当然是优化网络。在本文中,我们主要讨论程序在本地执行的速度。 -I’m going to pick on C# as the specific example here for two reasons: the first is that it’s the high level language I use most often these days, and because if I used Java I’d get a bunch of C# fans telling me how it has value types and therefore doesn’t have these issues (this is wrong). - 我将选用 C# 语言作为本文的参考语言,其原因有二:首先它是我常用的高级语言;其次如果我使用 Java 语言,许多使用 C# 的朋友会告诉我 C# 不会有这些问题,因为它有值类型(但这是错误的)。 -In the following I will be talking about what happens when you write idiomatic code. When you work “with the grain” of the language. When you write code in the style of the standard libraries and tutorials. I’m not very interested in ugly workarounds as “proof” that there’s no problem. Yes, you can sometimes fight the language to avoid a particular issue, but that doesn’t make the language unproblematic. - 接下来我将会讨论,出于编程习惯编写的代码、使用普遍编程方法(with the grain)的代码或使用库或教程中提到的常用代码来编写程序时会发生什么。我对那些使用难搞的办法来解决语言自身毛病以“证明”语言没毛病这事没兴趣,当然你可以和语言抗争来避免它的毛病,但这并不能说明语言本身是没有问题的。 -### Cache costs review - ### 回顾缓存消耗问题 -First, let’s review the importance of playing well with the cache. Here’s a graph based on [this data][10] on memory latencies for Haswell: +首先我们先来回顾一下合理使用缓存的重要性。下图是基于在 Haswell 架构下内存延迟对CPU影响的 [数据][10]: -首先我们先来回顾一下合理使用缓存的重要性。下图是基于在 Haswell 架构下内存潜在因素对其影响的 [数据][10]: +![](https://www.sebastiansylvan.com/img/041315_0638_whymosthigh1.png) - ![](https://www.sebastiansylvan.com/img/041315_0638_whymosthigh1.png) - -The latency for this particular CPU to get to memory is about 230 cycles, meanwhile the cost of reading data from L1 is 4 cycles. The key takeaway here is that doing the wrong thing for the cache can make code ~50x slower. In fact, it may be even worse than that – modern CPUs can often do multiple things at once so you could be loading stuff from L1 while operating on stuff that’s already in registers, thus hiding the L1 load cost partially or completely. - -针对这款 CPU 的内存因素,读取内存的数据需要近 230 个运算周期,同时需要消耗 L1 缓冲区的 4 个运算周期。因此错误的去使用缓存可导致运行速度拖慢近 50 倍。还好这并不是最糟糕的——在现代 CPU 中它们能同时地做多种操作,所以当你加载 L1 缓冲区内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗就被完整的隐藏了起来。 - -Without exaggerating we can say that aside from making reasonable algorithm choices, cache misses are the main thing you need to worry about for performance. Once you’re accessing data efficiently you can worry about fine tuning the actual operations you do. In comparison to cache misses, minor inefficiencies just don’t matter much. +针对这款 CPU 读取内存的延迟,CPU 需要消耗近 230 个运算周期从内存读取数据,同时需要消耗 4 个运算周期来读取 L1 缓冲区。因此错误的去使用缓存可导致运行速度拖慢近 50 倍。还好这并不是最糟糕的——在现代 CPU 中它们能同时地做多种操作,所以当你加载 L1 缓冲区内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗就被完整的隐藏了起来。 撇开选择合理的算法不谈,不夸张地讲,在性能优化中你要考虑的最主要因素其实是缓存未命中。当你能够有效的访问一个数据时候,你才可以调整你的每个具体的操作。与缓存未命中的问题相比,那些次要的低效问题对运行速度并没有什么过多的影响。 -This is actually good news for language designers! You don’t  _have_  to build the most efficient compiler on the planet, and you totally can get away with some extra overhead here and there for your abstractions (e.g. array bounds checking), all you need to do is make sure that your design makes it easy to write code that accesses data efficiently and programs in your language won’t have any problems running at speeds that are competitive with C. - 这对于编程语言的设计者来说是一个好消息!你都_不必_去编写一个更高效的编译器,你可以完全摆脱一些额外的开销(比如:数组边界检查),你只需要专注怎么设计能使你的语言访问数据更高效,也不用担心与 C 语言代码比较运行速度。 - -### Why C# introduces cache misses - ### 为什么 C# 存在缓存未命中问题 -To put it bluntly, C# is a language that simply isn’t designed to run efficiently with modern cache realities in mind. Again, I’m now talking about the limitations of the design and the “pressure” it puts on the programmer to do things in inefficient ways. Many of these things have theoretical workarounds that you could do at great inconvenience. I’m talking about idiomatic code, what the language “wants” you to do. - 坦率地讲 C# 在设计时就没打算在现代缓存中实现高效运行。我又一次提到程序语言设计的局限性以及其带给程序员无法编写高效的代码的“压力”。大部分的理论解决方法都非常的不便。我是在说那些编程语言“希望”你这样编写的习惯性代码。 -The basic problem with C# is that it has very poor support for value-based programming. Yes, it has structs which are values that are stored “embedded” where they are declared (e.g. on the stack, or inside another object). But there are a several big issues with structs that make them more of a band-aid than a solution. - C# 最基本的问题是对基础值类型(value-base)低下的支持性。其大部分的数据结构都是“内置”在语言内定义的(例如:栈,或其他内置对象)。但这些具有帮助性的内置结构体恰恰好会造成一些大问题。 -* You have to declare your data types as struct up front – which means that if you  _ever_  need this type to exist as a heap allocation then  _all_  of them need to be heap allocations. You could make some kind of class-wrapper for your struct and forward all the members but it’s pretty painful. It would be better if classes and structs were declared the same way and could be used in both ways on a case-by-case basis. So when something can live on the stack you declare it as a value, and when it needs to be on the heap you declare it as an object. This is how C++ works, for example. You’re not encouraged to make everything into an object-type just because there’s a few things here and there that need them on the heap. * 你得把自己定义的结构体类型在最先声明——这意味着你如果需要用到这个类型作为堆分配,那么所有的结构体都会被堆分配。你也可以使用一些类包装器来打包你的结构体和其中的成员变量,但这十分的痛苦。如果类和结构体可以相同的方式声明,并且可根据具体情况来使用,这将是更好的。当数据可以作为值地存储在自定义的栈中,当这个数据需要被对分配时你就可以将其定义为一个对象,比如 C++ 就是这样工作的。因为只有少数的内容需要被堆分配,所以我们不鼓励所有的内容都被定义为对象类型。 -* _Referencing_  values is extremely limited. You can pass values by reference to functions, but that’s about it. You can’t just grab a reference to an element in a List, you have to store both a reference to the list and an index. You can’t grab a pointer to a stack-allocated value, or a value stored inside an object (or value). You can only copy them, unless you’re passing them to a function (by ref). This is all understandable, by the way. If type safety is a priority, it’s pretty difficult (though not imposible) to support flexible referencing of values while also guaranteeing type safety. The rationale behind these restrictions don’t change the fact that the restrictions are there, though. * _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然这不可能)。 -* [Fixed sized buffers][6] don’t support custom types and also requires you to use an unsafe keyword. * [固定大小的缓冲区][6] 不支持自定义类型,而且还必须使用 `unsafe` 关键字。 -* Limited “array slice” functionality. There’s an ArraySegment class, but it’s not really used by anyone, which means that in order to pass a range of elements from an array you have to create an IEnumerable, which means allocation (boxing). Even if the APIs accepted ArraySegment parameters it’s still not good enough – you can only use it for normal arrays, not for List, not for [stack-allocated array][4]s, etc. * 有限的“数组切片”功能。虽然有提供 `ArraySegment` 类,但并没有人会使用它,这意味着如果只需要传递数组的一部分,你必须去创建一个 `IEnumerable` 对象,也就意味着要分配大小(包装)。就算接口接受 `ArraySegment` 对象作为参数,也是不够的——你只能用普通数组,而不能用 `List`,也不能用 [栈数组][4] 等等。 -The bottom line is that for all but very simple cases, the language pushes you very strongly towards heap allocations. If all your data is on the heap, it means that accessing it is likely to cause a cache misses (since you can’t decide how objects are organized in the heap). So while a C++ program poses few challenges to ensuring that data is organized in cache-efficient ways, C# typically encourages you to allocate each part of that data in a separate heap allocation. This means the programmers loses control over data layout, which means unnecessary cache misses are introduced and performance drops precipitously. It doesn’t matter that [you can now compile C# programs natively][11] ahead of time – improvement to code quality is a drop in the bucket compared to poor memory locality. -最重要的是,除了非常简单的情况之外,C# 非常惯用堆分配。如果所有的数据都被堆分配,这意味着被访问时会造成缓存未命中(从你无法决定对象是如何在堆中存储开始)。所以当 C++ 程序面临着如何有效的组织数据在缓存中的存储这个挑战时,C# 则鼓励程序员去将数据分开的存放在一个个堆分配空间中。这就意味着程序员无法控制数据层了,也就意味着开始产生不必要的缓存未命中问题,也就导致性能急速的下降了。[C# 已经支持原生编译][11] 也不会提升太多性能——毕竟在内存不足的情况下,提高代码质量本就杯水车薪。 +最重要的是,除了非常简单的情况之外,C# 非常惯用堆分配。如果所有的数据都被堆分配,这意味着被访问时会造成缓存未命中(从你无法决定对象是如何在堆中存储开始)。所以当 C++ 程序面临着如何有效的组织数据在缓存中的存储这个挑战时,C# 则鼓励程序员去将数据分开的存放在一个个堆分配空间中。这就意味着程序员无法控制数据存储方式了,也开始产生不必要的缓存未命中问题,而导致性能急速的下降。[C# 已经支持原生编译][11] 也不会提升太多性能——毕竟在内存不足的情况下,提高代码质量本就杯水车薪。 -Plus, there’s storage overhead. Each reference is 8 bytes on a 64-bit machine, and each allocation has its own overhead in the form of various metadata. A heap full of tiny objects with lots of references everywhere has a lot of space overhead compared to a heap with very few large allocations where most data is just stored embedded within their owners at fixed offsets. -Even if you don’t care about memory requirements, the fact that the heap is bloated with header words and references means that cache lines have more waste in them, this in turn means even more cache misses and reduced performance. 存储是有开销的。在64位的机器上每个地址值占8位内存,而每次分配都会有存储元数据而产生的开销。与存储着少量大数据(以固定偏移的方式存储在其中)的堆相比,存储着大量小数据的堆(并且其中的数据到处都被引用)会产生更多的内存开销。尽管你可能不怎么关心内存怎么用,但事实上就是那些头部内容和地址信息导致堆变得臃肿,也就是在浪费缓存了,所以也造成了更多的缓存未命中,降低了代码性能。 -There are sometimes workarounds you can do, for example you can use structs and allocate them in a pool using a big List. This allows you to e.g. traverse the pool and update all of the objects in-bulk, getting good locality. This does get pretty messy though, because now anything else wanting to refer to one of these objects have to have a reference to the pool as well as an index, and then keep doing array-indexing all over the place. For this reason, and the reasons above, it is significantly more painful to do this sort of stuff in C# than it is to do it in C++, because it’s just not something the language was designed to do. Furthermore, accessing a single element in the pool is now more expensive than just having an allocation per object - you now get  _two_  cache misses because you have to first dereference the pool itself (since it’s a class). Ok, so you can duplicate the functionality of List in struct-form and avoid this extra cache miss and make things even uglier. I’ve written plenty of code just like this and it’s just extremely low level and error prone. 当然有些时候也是有办法的,比如你可以使用一个很大的 `List` 来构造数据池以存储分配你需要的数据和自己的结构体。这样你就可以方便的遍历或者批量更新你的数据池中的数据了。但这也会很混乱,因为无论你在哪要引用什么对象都要先能引用这个池,然后每次引用都需要做数组索引。从上文可以得出,在 C# 中做类似这样的处理的痛感比在 C++ 中做来的更痛,因为 C# 在设计时就是这样。此外,通过这种方式来访问池中的单个对象比直接将这个对象分配到内存来访问更加的昂贵——前者你得先访问池(这是个类)的地址,这意味着可能产生 _2_ 次缓存未命中。你还可以通过复制 `List` 的结构形式来避免更多的缓存未命中问题,但这就更难搞了。我就写过很多类似的代码,自然这样的代码只会很低水平而且容易出错。 -Finally, I want to point out that this isn’t just an issue for “hot spot” code. Idiomatically written C# code tends to have classes and references basically  _everywhere_ . This means that all over your code at relatively uniform frequency there are random multi-hundred cycle stalls, dwarfing the cost of surrounding operations. Yes there could be hotspots too, but after you’ve optimized them you’re left with a program that’s just [uniformly slow.][12] So unless you want to write all your code with memory pools and indices, effectively operating at a lower level of abstraction than even C++ does (and at that point, why bother with C#?), there’s not a ton you can do to avoid this issue. 最后,我想说我指出的问题不仅是那些“热门”的代码。惯用手段编写的 C# 代码倾向于几乎所有地方都用类和引用。意思就是在你的代码中会均匀频率地随机出现数百次的运算周期损耗,使得操作的损耗似乎降低了。这虽然也可以被找出来,但你优化了这问题后,这还是一个 [均匀变慢][12] 的程序。 -### Garbage Collection ### 垃圾回收 -I’m just going to assume in the following that you already understand why garbage collection is a performance problem in a lot of cases. That pausing randomly for many milliseconds just is usually unacceptable for anything with animation. I won’t linger on it and move on to explaining why the language design itself exacerbates this issue. 在读下文之前我会假设你已经知道为什么在许多用例中垃圾回收是影响性能问题的重要原因。播放动画时总是随机的暂停通常都是大家都不能接受的吧。我会继续解释为什么设计语言时还加剧了这个问题。 -Because of the limitations when it comes to dealing with values, the language very strongly discourages you from using big chunky allocations consisting mostly of values embedded within other values (perhaps stored on the stack), pressuring you instead to use lots of small classes which have to be allocated on the heap. Roughly speaking, more allocations means more time spent collecting garbage. +因为 C# 在处理变量上的一些局限性,它不会鼓励你去使用大内存块分配来存储很多里面是内置对象的变量(可能存在栈中),这就使得你必须使用很多分配在堆中的小型类对象。说白了就是内存分配越多会导致花在垃圾回收上的时间就越多。 +有些测评说 C# 或者 Java 是怎么在一些特定的例子中打败 C++ 的,其实是因为内存分配器都基于一种吞吐还算不错的垃圾回收机制(廉价的分配,允许统一的释放分配)。然而,这些测试场景都太特殊了。想要使 C# 的程序的内存分配率变得和那些非常普通的 C++ 程序都能达到的一样就必须要耗费更大的精力来编写它,所以这种比较就像是拿一个高度优化的管理程序和一个最简单原生的程序相比较一样。当你花同样的精力来写一个 C++ 程序时,肯定比你用 C# 来写性能好的多。 -There are benchmarks that show how C# or Java beat C++ in some particular case, because an allocator based on a GC can have decent throughput (cheap allocations, and you batch all the deallocations up). However, this isn’t a common real world scenario. It takes a huge amount of effort to write a C# program with the same low allocation rate that even a very naïve C++ program has, so those kinds of comparisons are really comparing a highly tuned managed program with a naïve native one. Once you spend the same amount of effort on the C++ program, you’d be miles ahead of C# again. +我还是相信你可以写出一套适用于高性能低延迟的应用的垃圾回收机制的(比如维护一个增量的垃圾回收,每次消耗固定的时间来做回收),但这还是不够的,大部分的高级语言在设计时就没考虑程序启动时就会产生大量的垃圾,这将会是最大的问题。当你就像写 C 一样习惯的去少去在 C# 分配内存,垃圾回收在高性能应用中可能就不会暴露出很多的问题了。而就算你 _真的_ 去实现了一个增量垃圾回收机制,这意味着你还可能需要为其做一个写屏障——这就相当于又消耗了一些性能了。 -I’m relatively convinced that you could write a GC more suitable for high performance and low latency applications (e.g. an incremental GC where you spend a fixed amount of time per frame doing collection), but this is not enough on its own. At the end of the day the biggest issue with most high level languages is simply that the design encourages far too much garbage being created in the first place. If idiomatic C# allocated at the same low rate a C program does, the GC would pose far fewer problems for high performance applications. And if you  _did_  have an incremental GC to support soft real-time applications, you’ll probably need a write barrier for it – which, as cheap as it is, means that a language that encourages pointers will add a performance tax to the mutators. +看看 `.Net` 库里那些基本类,内存分配几乎无处不在!我数了下,在 [.Net 核心框架][13] 中公共类比结构体的数量多出 19 倍之多,为了使用它们,你就得把这些东西全都弄到内存中去。就算是 `.Net` 框架的创造者们也无法抵抗设计语言时的警告啊!我都不知道怎么去统计了,使用基础类库时,你会很快意识到这不仅仅是值或对象的选择问题了,就算如此也还是 _伴随_ 着超级多的内存分配。这一切都让你觉得分配内存好像很容易一样,其实怎么可能呢,没有内存分配你连一个整形值都没法输出!不说这个,就算你使用预分配的 `StringBuilder`,你要是不用标准库来分配内存,也还不是连个整型都存不住。你要这么问我那就挺蠢的了。 -Look at the base class library for .Net, allocations are everywhere! By my count the [.Net Core Framework][13] contains 19x more public classes than structs, so in order to use it you’re very much expected to do quite a lot of allocation. Even the creators of .Net couldn’t resist the siren call of the language design! I don’t know how to gather statistics on this, but using the base class library you quickly notice that it’s not just in their choice of value vs. object types where the allocation-happiness shines through. Even  _within_  this code there’s just a ton of allocations. Everything seems to be written with the assumption that allocations are cheap. Hell, you can’t even print an int without allocating! Let that sink in for a second. Even with a pre-sized StringBuilder you can’t stick an int in there without allocating using the standard library. That’s pretty silly if you ask me. +当然还不仅仅是标准库,其他的 C# 库也一样。就算是 `Unity`(一个 _游戏引擎_,可能能多的关心平均性能问题)也会有一些全局返回已分配对象(或数组)的接口,或者强制调用时先将其分配内存再使用。举个例子,在一个 `GameObject` 中要使用 `GetComponents` 来调用一个数组,`Unity` 会强制地分配一个数组以便调用。就此而言,其实有许多的接口可以采用,但他们不选择,而去走常规路线来直接使用内存分配。写 `Unity` 的同胞们写的一手“好 C#”呀,但就是不那么高性能罢了。 -This isn’t just in the standard library. Other C# libraries follow suit. Even Unity (a  _game engine_ , presumably caring more than average about performance issues) has APIs all over the place that return allocated objects (or arrays) or force the caller to allocate to call them. For example, by returning an array from GetComponents, they’re forcing an array allocation just to see what components are on a GameObject. There are a number of alternative APIs they could’ve chosen, but going with the grain of the language means allocations. The Unity folks wrote “Good C#”, it’s just bad for performance. +# 结语 -# Closing remarks +如果你在设计一门新的语言,拜托你可以考虑一下我提到的那些性能问题。在你创造出一款“足够聪明的编译器”之后这些都不是什么难题了。当然,没有垃圾回收器就要求类型安全很难。当然,没有一个规范的数据表示就创造一个垃圾回收器很难。当然,出现指向随机值的指针时难以去推出其作用域规则。当然,还有大把大把的问题摆在那里,然而解决了这些所有的问题,设计出来的语言就会是我们想的那样吗?那为什么这么多主要的语言都是在那些六十年代就已经被设计出的语言的基础上迭代的呢? -If you’re designing a new language,  _please_  consider efficiency up front. It’s not something a “Sufficiently Smart Compiler” can fix after you’ve already made it impossible. Yes, it’s hard to do type safety without a garbage collector. Yes, it’s harder to do garbage collection when you don’t have uniform representation for data. Yes, it’s hard to reason about scoping rules when you can have pointers to random values. Yes, there are tons of problems to figure out here, but isn’t figuring those problems out what language design is supposed to be? Why make another minor iteration of languages that were already designed in the 1960s? - -Even if you can’t fix all these issues, maybe you can get most of the way there? Maybe use region types (a la Rust) to ensure safety. Or maybe even consider abandoning “type safety at all costs” in favor of more runtime checks (if they don’t cause extra cache misses, they don’t really matter… and in fact C# already does similar things, see covariant arrays which are strictly speaking a type system violation, and leads to a runtime exception). - -The bottom line is that if you want to be an alternative to C++ for high performance scenarios, you need to worry about data layout and locality. +尽管你不能修复这些问题,但也许你可以尽可能的靠近?或者可以使用域类型(比如 `Rust` 语言)去保证其类型安全。或者也许可以考虑直接放弃“类型安全成本”去使用更多的运行时检查(如果这不会造成更多的缓存未命中的话,这其实没什么所谓。其实 C# 也有类似的东西,叫协变式数组,严格上讲是违背系统数据类型的,会导致一些运行时异常)。 +如果你想在高性能场景中替代 C++,最基本的一点就是要考虑数据的存放布局和存储方式。 -------------------------------------------------------------------------------- 作者简介: -My name is Sebastian Sylvan. I’m from Sweden but live in Seattle. I work at Microsoft on Hololens. Obviously my views are my own and don’t necessarily represent those of Microsoft. +我叫 Sebastian Sylvan。我来自瑞典,目前居住在西雅图。我在微软工作,研究全息透镜。诚然我的观点仅代表本人,与微软公司无关。 -I typically blog graphics, languages, performance, and such. Feel free to hit me up on twitter or email (see links in sidebar). +我的博客以图像、编程语言、性能等内容为主。联系我请点击我的 Twitter 或 E-mail。 ------------ From 89c9418ef1061bf32482a7895318cc428604aa41 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Mon, 27 Mar 2017 11:13:47 +0800 Subject: [PATCH 08/25] translating ddos --- .../20170315 Hire a DDoS service to take down your enemies.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md index ce772c955d..79276757d8 100644 --- a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md +++ b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md @@ -1,3 +1,5 @@ +translating by [kenxx](https://github.com/kenxx) + Hire a DDoS service to take down your enemies ======================== @@ -57,7 +59,7 @@ The solution to cutting down on these attacks involves users resetting factory p via: http://www.csoonline.com/article/3180246/data-protection/hire-a-ddos-service-to-take-down-your-enemies.html 作者:[Ryan Francis][a] -译者:[译者ID](https://github.com/译者ID) +译者:[kenxx](https://github.com/kenxx) 校对:[校对者ID](https://github.com/校对者ID) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 6b6c44b2918dca849bdc4757fe8bab9e385b2e14 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Mon, 27 Mar 2017 11:20:44 +0800 Subject: [PATCH 09/25] delete old file --- ...Why most High Level Languages are Slow.md | 116 ------------------ 1 file changed, 116 deletions(-) delete mode 100644 translated/tech/20150413 Why most High Level Languages are Slow.md diff --git a/translated/tech/20150413 Why most High Level Languages are Slow.md b/translated/tech/20150413 Why most High Level Languages are Slow.md deleted file mode 100644 index 1b6d5beb1d..0000000000 --- a/translated/tech/20150413 Why most High Level Languages are Slow.md +++ /dev/null @@ -1,116 +0,0 @@ -[为什么(大部分)高级语言运行效率较慢][7] -============================================================ - -内容 - - -* * [回顾缓存消耗问题][1] - * [为什么 C# 存在缓存未命中问题][2] - * [垃圾回收][3] -* [结语][5] - - -在近两个个月中,我多次的和线上线下的朋友讨论了这个话题,所以我干脆直接把它写在博客中,以便以后查阅。 - -大部分高级语言运行效率较慢的原因通常有两点: - -1. 没有很好的利用缓存; -2. 垃圾回收机制性能消耗高。 - -但事实上,这两个原因可以归因于:高级语言强烈地鼓励编程人员分配很多的内存。 - -首先,下文内容主要讨论客户端应用。如果你的程序有 99.9% 的时间都在等待网络,那么这很可能不是拖慢语言运行效率的原因——优先考虑的问题当然是优化网络。在本文中,我们主要讨论程序在本地执行的速度。 - -我将选用 C# 语言作为本文的参考语言,其原因有二:首先它是我常用的高级语言;其次如果我使用 Java 语言,许多使用 C# 的朋友会告诉我 C# 不会有这些问题,因为它有值类型(但这是错误的)。 - -接下来我将会讨论,出于编程习惯编写的代码、使用普遍编程方法(with the grain)的代码或使用库或教程中提到的常用代码来编写程序时会发生什么。我对那些使用难搞的办法来解决语言自身毛病以“证明”语言没毛病这事没兴趣,当然你可以和语言抗争来避免它的毛病,但这并不能说明语言本身是没有问题的。 - -### 回顾缓存消耗问题 - -首先我们先来回顾一下合理使用缓存的重要性。下图是基于在 Haswell 架构下内存延迟对CPU影响的 [数据][10]: - -![](https://www.sebastiansylvan.com/img/041315_0638_whymosthigh1.png) - -针对这款 CPU 读取内存的延迟,CPU 需要消耗近 230 个运算周期从内存读取数据,同时需要消耗 4 个运算周期来读取 L1 缓冲区。因此错误的去使用缓存可导致运行速度拖慢近 50 倍。还好这并不是最糟糕的——在现代 CPU 中它们能同时地做多种操作,所以当你加载 L1 缓冲区内容的同时这个内容已经进入到了寄存器,因此数据从 L1 缓冲区加载这个过程的性能消耗就被完整的隐藏了起来。 - -撇开选择合理的算法不谈,不夸张地讲,在性能优化中你要考虑的最主要因素其实是缓存未命中。当你能够有效的访问一个数据时候,你才可以调整你的每个具体的操作。与缓存未命中的问题相比,那些次要的低效问题对运行速度并没有什么过多的影响。 - -这对于编程语言的设计者来说是一个好消息!你都_不必_去编写一个更高效的编译器,你可以完全摆脱一些额外的开销(比如:数组边界检查),你只需要专注怎么设计能使你的语言访问数据更高效,也不用担心与 C 语言代码比较运行速度。 - -### 为什么 C# 存在缓存未命中问题 - -坦率地讲 C# 在设计时就没打算在现代缓存中实现高效运行。我又一次提到程序语言设计的局限性以及其带给程序员无法编写高效的代码的“压力”。大部分的理论解决方法都非常的不便。我是在说那些编程语言“希望”你这样编写的习惯性代码。 - -C# 最基本的问题是对基础值类型(value-base)低下的支持性。其大部分的数据结构都是“内置”在语言内定义的(例如:栈,或其他内置对象)。但这些具有帮助性的内置结构体恰恰好会造成一些大问题。 - -* 你得把自己定义的结构体类型在最先声明——这意味着你如果需要用到这个类型作为堆分配,那么所有的结构体都会被堆分配。你也可以使用一些类包装器来打包你的结构体和其中的成员变量,但这十分的痛苦。如果类和结构体可以相同的方式声明,并且可根据具体情况来使用,这将是更好的。当数据可以作为值地存储在自定义的栈中,当这个数据需要被对分配时你就可以将其定义为一个对象,比如 C++ 就是这样工作的。因为只有少数的内容需要被堆分配,所以我们不鼓励所有的内容都被定义为对象类型。 - -* _引用_ 值被苛刻的限制。你可以将一个引用值传给函数,但只能这样。你不能直接引用 `List` 中的元素,你必须先把所有的引用和索引全部存储下来。你不能直接取得指向栈、对象中的变量(或其他变量)的指针。你只能把他们复制一份,除了将他们传给一个函数(使用引用的方式)。当然这也是可以理解的。如果类型安全是一个先驱条件,灵活的引用变量和保证类型安全这两项要同时支持太难了(虽然这不可能)。 - -* [固定大小的缓冲区][6] 不支持自定义类型,而且还必须使用 `unsafe` 关键字。 - -* 有限的“数组切片”功能。虽然有提供 `ArraySegment` 类,但并没有人会使用它,这意味着如果只需要传递数组的一部分,你必须去创建一个 `IEnumerable` 对象,也就意味着要分配大小(包装)。就算接口接受 `ArraySegment` 对象作为参数,也是不够的——你只能用普通数组,而不能用 `List`,也不能用 [栈数组][4] 等等。 - -最重要的是,除了非常简单的情况之外,C# 非常惯用堆分配。如果所有的数据都被堆分配,这意味着被访问时会造成缓存未命中(从你无法决定对象是如何在堆中存储开始)。所以当 C++ 程序面临着如何有效的组织数据在缓存中的存储这个挑战时,C# 则鼓励程序员去将数据分开的存放在一个个堆分配空间中。这就意味着程序员无法控制数据存储方式了,也开始产生不必要的缓存未命中问题,而导致性能急速的下降。[C# 已经支持原生编译][11] 也不会提升太多性能——毕竟在内存不足的情况下,提高代码质量本就杯水车薪。 - -存储是有开销的。在64位的机器上每个地址值占8位内存,而每次分配都会有存储元数据而产生的开销。与存储着少量大数据(以固定偏移的方式存储在其中)的堆相比,存储着大量小数据的堆(并且其中的数据到处都被引用)会产生更多的内存开销。尽管你可能不怎么关心内存怎么用,但事实上就是那些头部内容和地址信息导致堆变得臃肿,也就是在浪费缓存了,所以也造成了更多的缓存未命中,降低了代码性能。 - -当然有些时候也是有办法的,比如你可以使用一个很大的 `List` 来构造数据池以存储分配你需要的数据和自己的结构体。这样你就可以方便的遍历或者批量更新你的数据池中的数据了。但这也会很混乱,因为无论你在哪要引用什么对象都要先能引用这个池,然后每次引用都需要做数组索引。从上文可以得出,在 C# 中做类似这样的处理的痛感比在 C++ 中做来的更痛,因为 C# 在设计时就是这样。此外,通过这种方式来访问池中的单个对象比直接将这个对象分配到内存来访问更加的昂贵——前者你得先访问池(这是个类)的地址,这意味着可能产生 _2_ 次缓存未命中。你还可以通过复制 `List` 的结构形式来避免更多的缓存未命中问题,但这就更难搞了。我就写过很多类似的代码,自然这样的代码只会很低水平而且容易出错。 - -最后,我想说我指出的问题不仅是那些“热门”的代码。惯用手段编写的 C# 代码倾向于几乎所有地方都用类和引用。意思就是在你的代码中会均匀频率地随机出现数百次的运算周期损耗,使得操作的损耗似乎降低了。这虽然也可以被找出来,但你优化了这问题后,这还是一个 [均匀变慢][12] 的程序。 - -### 垃圾回收 - -在读下文之前我会假设你已经知道为什么在许多用例中垃圾回收是影响性能问题的重要原因。播放动画时总是随机的暂停通常都是大家都不能接受的吧。我会继续解释为什么设计语言时还加剧了这个问题。 - -因为 C# 在处理变量上的一些局限性,它不会鼓励你去使用大内存块分配来存储很多里面是内置对象的变量(可能存在栈中),这就使得你必须使用很多分配在堆中的小型类对象。说白了就是内存分配越多会导致花在垃圾回收上的时间就越多。 - -有些测评说 C# 或者 Java 是怎么在一些特定的例子中打败 C++ 的,其实是因为内存分配器都基于一种吞吐还算不错的垃圾回收机制(廉价的分配,允许统一的释放分配)。然而,这些测试场景都太特殊了。想要使 C# 的程序的内存分配率变得和那些非常普通的 C++ 程序都能达到的一样就必须要耗费更大的精力来编写它,所以这种比较就像是拿一个高度优化的管理程序和一个最简单原生的程序相比较一样。当你花同样的精力来写一个 C++ 程序时,肯定比你用 C# 来写性能好的多。 - -我还是相信你可以写出一套适用于高性能低延迟的应用的垃圾回收机制的(比如维护一个增量的垃圾回收,每次消耗固定的时间来做回收),但这还是不够的,大部分的高级语言在设计时就没考虑程序启动时就会产生大量的垃圾,这将会是最大的问题。当你就像写 C 一样习惯的去少去在 C# 分配内存,垃圾回收在高性能应用中可能就不会暴露出很多的问题了。而就算你 _真的_ 去实现了一个增量垃圾回收机制,这意味着你还可能需要为其做一个写屏障——这就相当于又消耗了一些性能了。 - -看看 `.Net` 库里那些基本类,内存分配几乎无处不在!我数了下,在 [.Net 核心框架][13] 中公共类比结构体的数量多出 19 倍之多,为了使用它们,你就得把这些东西全都弄到内存中去。就算是 `.Net` 框架的创造者们也无法抵抗设计语言时的警告啊!我都不知道怎么去统计了,使用基础类库时,你会很快意识到这不仅仅是值或对象的选择问题了,就算如此也还是 _伴随_ 着超级多的内存分配。这一切都让你觉得分配内存好像很容易一样,其实怎么可能呢,没有内存分配你连一个整形值都没法输出!不说这个,就算你使用预分配的 `StringBuilder`,你要是不用标准库来分配内存,也还不是连个整型都存不住。你要这么问我那就挺蠢的了。 - -当然还不仅仅是标准库,其他的 C# 库也一样。就算是 `Unity`(一个 _游戏引擎_,可能能多的关心平均性能问题)也会有一些全局返回已分配对象(或数组)的接口,或者强制调用时先将其分配内存再使用。举个例子,在一个 `GameObject` 中要使用 `GetComponents` 来调用一个数组,`Unity` 会强制地分配一个数组以便调用。就此而言,其实有许多的接口可以采用,但他们不选择,而去走常规路线来直接使用内存分配。写 `Unity` 的同胞们写的一手“好 C#”呀,但就是不那么高性能罢了。 - -# 结语 - -如果你在设计一门新的语言,拜托你可以考虑一下我提到的那些性能问题。在你创造出一款“足够聪明的编译器”之后这些都不是什么难题了。当然,没有垃圾回收器就要求类型安全很难。当然,没有一个规范的数据表示就创造一个垃圾回收器很难。当然,出现指向随机值的指针时难以去推出其作用域规则。当然,还有大把大把的问题摆在那里,然而解决了这些所有的问题,设计出来的语言就会是我们想的那样吗?那为什么这么多主要的语言都是在那些六十年代就已经被设计出的语言的基础上迭代的呢? - -尽管你不能修复这些问题,但也许你可以尽可能的靠近?或者可以使用域类型(比如 `Rust` 语言)去保证其类型安全。或者也许可以考虑直接放弃“类型安全成本”去使用更多的运行时检查(如果这不会造成更多的缓存未命中的话,这其实没什么所谓。其实 C# 也有类似的东西,叫协变式数组,严格上讲是违背系统数据类型的,会导致一些运行时异常)。 - -如果你想在高性能场景中替代 C++,最基本的一点就是要考虑数据的存放布局和存储方式。 - --------------------------------------------------------------------------------- - -作者简介: - -我叫 Sebastian Sylvan。我来自瑞典,目前居住在西雅图。我在微软工作,研究全息透镜。诚然我的观点仅代表本人,与微软公司无关。 - -我的博客以图像、编程语言、性能等内容为主。联系我请点击我的 Twitter 或 E-mail。 - ------------- - - -via: https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow - -作者:[Sebastian Sylvan ][a] -译者:[kenxx](https://github.com/kenxx) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:https://www.sebastiansylvan.com/about/ -[1]:https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow/?imm_mid=0ee8ca&cmp=em-prog-na-na-newsltr_20170311#cache-costs-review -[2]:https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow/?imm_mid=0ee8ca&cmp=em-prog-na-na-newsltr_20170311#why-c-introduces-cache-misses -[3]:https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow/?imm_mid=0ee8ca&cmp=em-prog-na-na-newsltr_20170311#garbage-collection -[4]:https://msdn.microsoft.com/en-us/library/vstudio/cx9s2sy4(v=vs.100).aspx -[5]:https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow/?imm_mid=0ee8ca&cmp=em-prog-na-na-newsltr_20170311#closing-remarks -[6]:https://msdn.microsoft.com/en-us/library/vstudio/zycewsya(v=vs.100).aspx -[7]:https://www.sebastiansylvan.com/post/why-most-high-level-languages-are-slow/ -[8]:https://www.sebastiansylvan.com/categories/programming-languages -[9]:https://www.sebastiansylvan.com/categories/software-engineering -[10]:http://www.7-cpu.com/cpu/Haswell.html -[11]:https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx -[12]:http://c2.com/cgi/wiki?UniformlySlowCode -[13]:https://github.com/dotnet/corefx From a85a07ca15d79ebad6c64e9dff09bf5de69fc998 Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Fri, 31 Mar 2017 11:46:18 +0800 Subject: [PATCH 10/25] a few lines --- ... Hire a DDoS service to take down your enemies.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md index 79276757d8..3cbbd628a5 100644 --- a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md +++ b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md @@ -1,25 +1,35 @@ translating by [kenxx](https://github.com/kenxx) Hire a DDoS service to take down your enemies +雇个 `DDoS` 服务干掉你的对手 ======================== >With the rampant availability of IoT devices, cybercriminals offer denial of service attacks to take advantage of password problems. +>随着物联网设备的普及,网络犯罪分子提供拒绝服务攻击来占密码问题的便宜。 + ![](http://images.techhive.com/images/article/2016/12/7606416730_e659cea89c_o-100698667-large.jpg) With the onrush of connected internet of things (IoT) devices, distributed denial-of-service attacks are becoming a dangerous trend. Similar to what happened to [DNS service provider Dyn last fall][3], anyone and everyone is in the crosshairs. The idea of using unprotected IoT devices as a way to bombard networks is gaining momentum. +随物联网设备飞速发展,分布式拒绝服务攻击也变得越来越具有危险性了。就如 [DNS 服务商 Dyn 上年秋季之遭遇][3] 一样,黑客似乎瞄上了每个人,使用未受保护的物联网设备来轰炸网络正迎面而来。 The advent of DDoS-for-hire services means that even the least tech-savvy individual can exact  revenge on some website. Step on up to the counter and purchase a stresser that can systemically take down a company. +可雇用的分布式拒绝服务攻击的出现意味着每个会点技术的人都能精准报复一些网站。加大攻击能力甚至可以从系统级别的让一个公司完蛋。 According to [Neustar][4], almost three quarters of all global brands, organizations and companies have been victims of a DDoS attack. And more than 3,700 [DDoS attacks occur each day][5]. +根据 [Neustar][4] 的报告,全球四分之三的品牌、组织和公司都是 `DDos` 攻击的受害者。[每天 `DDoS` 攻击发生次数][5] 不少于 3700 次。 #### [■ RELATED: How can you detect a fake ransom letter?][1] +#### [■ 相关阅读:如何判断假绑架信?][1] -Chase Cunningham, director of cyber operations at A10 Networks, said to find IoT-enabled devices, all you have to do is go on an underground site and ask around for the Mirai scanner code. Once you have that you can scan for anything talking to the internet that can be used for that type of attack.   + +Chase Cunningham, director of cyber operations at A10 Networks, said to find IoT-enabled devices, all you have to do is go on an underground site and ask around for the Mirai scanner code. Once you have that you can scan for anything talking to the internet that can be used for that type of attack. + 睿科网络公司(A10 Networks)网络运营总监 Chase Cunningham 说:“想要找个可用的物联网设备,你只需要在地下网站找一个 `Mirai` 扫描器,一旦你得到了这款扫描器,你将能够利用在线的每一台设备来进行攻击”。 “Or you can go to a site like Shodan and craft a couple of simple queries to look for device specific requests. Once you get that information you just go to your DDoS for hire tool and change the configuration to point at the right target and use the right type of traffic emulator and bingo, nuke whatever you like,” he said. +或者你可以去一些类似 `Shodan` 的网站然后简单的搜一下设备特殊请求, “Basically everything is for sale," he added. "You can buy a 'stresser', which is just a simple botnet type offering that will allow anyone who knows how to click the start button access to a functional DDoS botnet.” From ab9484a32b1b03f025e2ae158dbd42205e4750bb Mon Sep 17 00:00:00 2001 From: robot527 Date: Wed, 12 Apr 2017 22:32:41 +0800 Subject: [PATCH 11/25] [GDB common commands] translated and edited by robot527 --- translated/tech/GDB-common-commands.md | 259 +++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 translated/tech/GDB-common-commands.md diff --git a/translated/tech/GDB-common-commands.md b/translated/tech/GDB-common-commands.md new file mode 100644 index 0000000000..cdf7430529 --- /dev/null +++ b/translated/tech/GDB-common-commands.md @@ -0,0 +1,259 @@ +#常用的 GDB 命令中文释义 + +## 目录 + + - [break](#break) -- 缩写 `b`,在指定的行或函数处设置断点 + - [info breakpoints](#info-breakpoints) -- 简写 `i b`,打印未删除的所有断点,观察点和捕获点的列表 + - [disable](#disable) -- 禁用断点,可以缩写为 `dis` + - [enable](#enable) -- 启用断点 + - [clear](#clear) -- 清除指定行或函数处的断点 + - [delete](#delete) -- 缩写 `d`,删除断点 + - [tbreak](#tbreak) -- 设置临时断点,参数同 `break`,但在程序第一次停住后会被自动删除 + - [watch](#watch) -- 为表达式(或变量)设置观察点,当表达式(或变量)的值有变化时,停住程序 + + - [step](#step) -- 缩写 `s`,单步跟踪,如果有函数调用,会进入该函数 + - [reverse-step](#reverse-step) -- 反向单步跟踪,如果有函数调用,会进入该函数 + - [next](#next) -- 缩写 `n`,单步跟踪,如果有函数调用,不会进入该函数 + - [reverse-next](#reverse-next) -- 反向单步跟踪,如果有函数调用,不会进入该函数 + - [return](#return) -- 使选定的栈帧返回到其调用者 + - [finish](#finish) -- 缩写 `fin`,执行直到选择的栈帧返回 + - [until](#until) -- 缩写 `u`,执行直到...(用于跳过循环、递归函数调用) + - [continue](#continue) -- 同义词 `c`,恢复程序执行 + + - [print](#print) -- 缩写 `p`,打印表达式 EXP 的值 + - [x](#x) -- 查看内存 + + - [display](#display) -- 每次程序停止时打印表达式 EXP 的值(自动显示) + - [info display](#info-display) -- 打印早先设置为自动显示的表达式列表 + - [disable display](#disable-display) -- 禁用自动显示 + - [enable display](#enable-display) -- 启用自动显示 + - [undisplay](#undisplay) -- 删除自动显示项 + + - [help](#help) -- 缩写 `h`,打印命令列表(带参数时查找命令的帮助) + + - [attach](#attach) -- 挂接到已在运行的进程来调试 + - [run](#run) -- 缩写 `r`,启动被调试的程序 + + - [backtrace](#backtrace) -- 缩写 `bt`,查看程序调用栈的信息 + + +************ + +## break +使用 `break` 命令(缩写 `b`)来设置断点。 参见[官方文档][1]。 + + - `break` 当不带参数时,在所选栈帧中执行的下一条指令处设置断点。 + - `break ` 在函数体入口处打断点,在 C++ 中可以使用 `class::function` 或 `function(type, ...)` 格式来指定函数名。 + - `break ` 在当前源码文件指定行的开始处打断点。 + - `break -N` `break +N` 在当前源码行前面或后面的 `N` 行开始处打断点,`N` 为正整数。 + - `break ` 在源码文件 `filename` 的 `linenum` 行处打断点。 + - `break ` 在源码文件 `filename` 的 `function` 函数入口处打断点。 + - `break
` 在程序指令的地址处打断点。 + - `break ... if ` 设置条件断点,`...` 代表上述参数之一(或无参数),`cond` 为条件表达式,仅在 `cond` 值非零时停住程序。 + +## info breakpoints +查看断点,观察点和捕获点的列表。用法: +`info breakpoints [list…]` +`info break [list…]` +`list…` 用来指定若干个断点的编号(可省略),可以是 `2`, `1-3`, `2 5` 等。 + +## disable +禁用一些断点。 参见[官方文档][2]。 +参数是用空格分隔的断点编号。 +要禁用所有断点,不加参数。 +禁用的断点不会被忘记,但直到重新启用才有效。 +用法: `disable [breakpoints] [list…]` +`breakpoints` 是 `disable` 的子命令(可省略),`list…` 同 `info breakpoints` 中的描述。 + +## enable +启用一些断点。 参见[官方文档][2]。 +给出断点编号(以空格分隔)作为参数。 +没有参数时,所有断点被启用。 + + - `enable [breakpoints] [list…]` 启用指定的断点(或所有定义的断点)。 + - `enable [breakpoints] once list…` 临时启用指定的断点。GDB 在停止您的程序后立即禁用这些断点。 + - `enable [breakpoints] delete list…` 使指定的断点启用一次,然后删除。一旦您的程序停止,GDB 就会删除这些断点。等效于用 `tbreak` 设置的断点。 + +`breakpoints` 同 `disable` 中的描述。 + +## clear +在指定行或函数处清除断点。 参见[官方文档][3]。 +参数可以是行号,函数名称或 "*" 跟一个地址。 + + - `clear` 当不带参数时,清除所选栈帧在执行的源码行中的所有断点。 + - `clear `, `clear ` 删除在命名函数的入口处设置的任何断点。 + - `clear `, `clear ` 删除在指定的文件指定的行号的代码中设置的任何断点。 + - `clear
` 清除指定程序指令的地址处的断点。 + +## delete +删除一些断点或自动显示表达式。 参见[官方文档][3]。 +参数是用空格分隔的断点编号。 +要删除所有断点,不加参数。 +用法: `delete [breakpoints] [list…]` + +## tbreak +设置临时断点。参数形式同 `break` 一样。 参见[官方文档][1]。 +除了断点是临时的之外像 `break` 一样,所以在命中时会被删除。 + +## watch +为表达式设置观察点。 参见[官方文档][4]。 +用法: `watch [-l|-location] ` +每当一个表达式的值改变时,观察点就会停止执行您的程序。 +如果给出了 `-l` 或者 `-location`,则它会对 `expr` 求值并观察它所指向的内存。 +例如,`watch *(int *)0x12345678` 将在指定的地址处观察一个 4 字节的区域(假设 int 占用 4 个字节)。 + +## step +单步执行程序,直到到达不同的源码行。 参见[官方文档][5]。 +用法: `step [N]` +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 +警告:如果当控制在没有调试信息的情况下编译的函数中使用 `step` 命令,则执行将继续进行, +直到控制到达具有调试信息的函数。 同样,它不会进入没有调试信息编译的函数。 +要执行没有调试信息的函数,请使用 `stepi` 命令,后文再述。 + +## reverse-step +反向步进程序,直到到达另一个源码行的开头。 参见[官方文档][6]。 +用法: `reverse-step [N]` +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 + +## next +单步执行程序,执行完子程序调用。 参见[官方文档][5]。 +用法: `next [N]` +与 `step` 不同,如果当前的源代码行调用子程序,则此命令不会进入子程序,而是继续执行,将其视为单个源代码行。 + +## reverse-next +反向步进程序,执行完子程序调用。 参见[官方文档][6]。 +用法: `reverse-next [N]` +如果要执行的源代码行调用子程序,则此命令不会进入子程序,调用被视为一个指令。 +参数 `N` 表示执行 N 次(或由于另一个原因直到程序停止)。 + +## return +您可以使用 `return` 命令取消函数调用的执行。 参见[官方文档][7]。 +如果你给出一个表达式参数,它的值被用作函数的返回值。 +`return ` 将 `expression` 的值作为函数的返回值并使函数直接返回。 + +## finish +执行直到选定的栈帧返回。 参见[官方文档][5]。 +用法: `finish` +返回后,返回的值将被打印并放入到值历史记录中。 + +## until +执行直到程序到达大于当前栈帧或当前栈帧中的指定位置(与 [break](#break) 命令相同的参数)的源码行。 参见[官方文档][5]。 +此命令用于通过一个多次的循环,以避免单步执行。 +`until ` 或 `u ` 继续运行程序,直到达到指定的位置,或者当前栈帧返回。 + +## continue +在信号或断点之后,继续运行被调试的程序。 参见[官方文档][5]。 +用法: `continue [N]` +如果从断点开始,可以使用数字 `N` 作为参数,这意味着将该断点的忽略计数设置为 `N - 1`(以便断点在第 N 次到达之前不会中断)。 +如果启用了非停止模式(使用 `show non-stop` 查看),则仅继续当前线程,否则程序中的所有线程都将继续。 + +## print +求值并打印表达式 EXP 的值。 参见[官方文档][8]。 +可访问的变量是所选栈帧的词法环境,以及范围为全局或整个文件的所有变量。 +用法: `print [expr]` 或 `print /f [expr]` +`expr` 是一个(在源代码语言中的)表达式。 +默认情况下,`expr` 的值以适合其数据类型的格式打印;您可以通过指定 `/f` 来选择不同的格式,其中 `f` 是一个指定格式的字母;参见[输出格式][9]。 +如果省略 `expr`,GDB 再次显示最后一个值。 + +## x +检查内存。 参见[官方文档][10]。 +用法: `x/nfu ` 或 `x ` +`n`, `f`, 和 `u` 都是可选参数,用于指定要显示的内存以及如何格式化。 +`addr` 是要开始显示内存的地址的表达式。 +`n` 重复次数(默认值是 1),指定要显示多少个单位(由 `u` 指定)的内存值。 +`f` 显示格式(初始默认值是 `x`),显示格式是 `print('x','d','u','o','t','a','c','f','s')` 使用的格式之一,再加 `i`(机器指令)。 +`u` 单位大小,`b` 表示单字节,`h` 表示双字节,`w` 表示四字节,`g` 表示八字节。 +例如,`x/3uh 0x54320` 表示从地址 0x54320 开始以无符号十进制整数的方式,双字节为单位显示 3 个内存值。 + +## display +每次程序停止时打印表达式 EXP 的值。 参见[官方文档][11]。 +用法: `display `, `display/fmt ` 或 `display/fmt ` +`fmt` 用于指定显示格式。像 [print](#print) 命令里的 `/f` 一样。 +对于格式 `i` 或 `s`,或者包括单位大小或单位数量,将表达式 `addr` 添加为每次程序停止时要检查的内存地址。 + +## info display +打印自动显示的表达式列表,每个表达式都带有项目编号,但不显示其值。 +包括被禁用的表达式和不能立即显示的表达式(当前不可用的自动变量)。 + +## undisplay +取消某些表达式在程序停止时自动显示。 +参数是表达式的编号(使用 `info display` 查询编号)。 +不带参数表示取消所有自动显示表达式。 +`delete display` 具有与此命令相同的效果。 + +## disable display +禁用某些表达式在程序停止时自动显示。 +禁用的显示项目不会被自动打印,但不会被忘记。 它可能稍后再次被启用。 +参数是表达式的编号(使用 `info display` 查询编号)。 +不带参数表示禁用所有自动显示表达式。 + +## enable display +启用某些表达式在程序停止时自动显示。 +参数是重新显示的表达式的编号(使用 `info display` 查询编号)。 +不带参数表示启用所有自动显示表达式。 + +## help +打印命令列表。 参见[官方文档][12]。 +您可以使用不带参数的 `help`(缩写为 `h`)来显示命令的类别名的简短列表。 +使用 `help ` 您可以获取该类中各个命令的列表。 +使用 `help ` 显示如何使用该命令的简述。 + +## attach +挂接到 GDB 之外的进程或文件。 参见[官方文档][13]。 +该命令可以将进程 ID 或设备文件作为参数。 +对于进程 ID,您必须具有向进程发送信号的权限,并且必须具有与调试器相同的有效的 uid。 +用法: `attach ` +GDB 在安排调试指定的进程之后做的第一件事是停住它。 +您可以使用所有通过 `run` 命令启动进程时可以使用的 GDB 命令来检查和修改挂接的进程。 + +## run +启动被调试的程序。 参见[官方文档][14]。 +可以直接指定参数,也可以用 [set args][15] 设置(启动所需的)参数。 +例如: `run arg1 arg2 ...` 等效于 +``` +set args arg1 arg2 ... +run +``` +还允许使用 ">", "<", 或 ">>" 进行输入和输出重定向。 + +## backtrace +打印整个栈的回溯。 参见[官方文档][16]。 + + - `bt` 打印整个栈的回溯,每个栈帧一行。 + - `bt n` 类似于上,但只打印最内层的 n 个栈帧。 + - `bt -n` 类似于上,但只打印最外层的 n 个栈帧。 + - `bt full n` 类似于 `bt n`,还打印局部变量的值。 + +`where` 和 `info stack`(缩写 `info s`) 是 `backtrace` 的别名。 + +************ + +## 参考资料 + + - [Debugging with GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/) + - [用 GDB 调试程序(二)](http://blog.csdn.net/haoel/article/details/2880) + +-------------------------------------------------------------------------------- + +编译者:[robot527](https://github.com/robot527) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[1]:https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Breaks.html +[2]:https://sourceware.org/gdb/current/onlinedocs/gdb/Disabling.html +[3]:https://sourceware.org/gdb/current/onlinedocs/gdb/Delete-Breaks.html +[4]:https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Watchpoints.html +[5]:https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html +[6]:https://sourceware.org/gdb/current/onlinedocs/gdb/Reverse-Execution.html +[7]:https://sourceware.org/gdb/current/onlinedocs/gdb/Returning.html +[8]:https://sourceware.org/gdb/current/onlinedocs/gdb/Data.html +[9]:https://sourceware.org/gdb/current/onlinedocs/gdb/Output-Formats.html +[10]:https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html +[11]:https://sourceware.org/gdb/current/onlinedocs/gdb/Auto-Display.html +[12]:https://sourceware.org/gdb/current/onlinedocs/gdb/Help.html +[13]:https://sourceware.org/gdb/current/onlinedocs/gdb/Attach.html +[14]:https://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html +[15]:https://sourceware.org/gdb/current/onlinedocs/gdb/Arguments.html +[16]:https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html + From 0f7304f8e0ed3b0249bc966327818c977f2f6f29 Mon Sep 17 00:00:00 2001 From: robot527 Date: Thu, 13 Apr 2017 10:24:23 +0800 Subject: [PATCH 12/25] updated GDB common commands --- translated/tech/GDB-common-commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/GDB-common-commands.md b/translated/tech/GDB-common-commands.md index cdf7430529..4ba6de54ef 100644 --- a/translated/tech/GDB-common-commands.md +++ b/translated/tech/GDB-common-commands.md @@ -1,4 +1,4 @@ -#常用的 GDB 命令中文释义 +# 常用的 GDB 命令中文释义 ## 目录 From 45f14775f26a08805eb31f1985a515e9cf29a89a Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 14 Apr 2017 09:03:33 +0800 Subject: [PATCH 13/25] translating --- sources/tech/20170406 Anbox - Android in a Box.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/tech/20170406 Anbox - Android in a Box.md b/sources/tech/20170406 Anbox - Android in a Box.md index 69cc224b12..8ca37900b8 100644 --- a/sources/tech/20170406 Anbox - Android in a Box.md +++ b/sources/tech/20170406 Anbox - Android in a Box.md @@ -1,3 +1,5 @@ +translating---geekpi + # Anbox Anbox is container based approach to boot a full Android system on a From 6b7fb433e0a3c1257c3e0896e7860763f6764456 Mon Sep 17 00:00:00 2001 From: geekpi Date: Fri, 14 Apr 2017 10:14:16 +0800 Subject: [PATCH 14/25] translated --- .../tech/20170406 Anbox - Android in a Box.md | 213 ------------------ .../tech/20170406 Anbox - Android in a Box.md | 174 ++++++++++++++ 2 files changed, 174 insertions(+), 213 deletions(-) delete mode 100644 sources/tech/20170406 Anbox - Android in a Box.md create mode 100644 translated/tech/20170406 Anbox - Android in a Box.md diff --git a/sources/tech/20170406 Anbox - Android in a Box.md b/sources/tech/20170406 Anbox - Android in a Box.md deleted file mode 100644 index 8ca37900b8..0000000000 --- a/sources/tech/20170406 Anbox - Android in a Box.md +++ /dev/null @@ -1,213 +0,0 @@ -translating---geekpi - -# Anbox - -Anbox is container based approach to boot a full Android system on a -regular GNU Linux system like Ubuntu. - -## Overview - -Anbox uses Linux namespaces (user, pid, uts, net, mount, ipc) to run a -full Android system in a container and provide Android applications on -any GNU Linux based platform. - -The Android inside the container has no direct access to any hardware. -All hardware access is going through the anbox daemon on the host. We're -reusing what Android implemented within the QEMU based emulator for Open -GL ES accelerated rendering. The Android system inside the container uses -different pipes to communicate with the host system and sends all hardware -access commands through these. - -For more details have a look at the following documentation pages: - - * [Android Hardware OpenGL ES emulation design overview](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/android-emugl/DESIGN) - * [Android QEMU fast pipes](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMU-PIPE.TXT) - * [The Android "qemud" multiplexing daemon](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) - * [Android qemud services](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD-SERVICES.TXT) - -Anbox is currently suited for the desktop use case but can be used on -mobile operating systems like Ubuntu Touch, Sailfish OS or Lune OS too. -However as the mapping of Android applications is currently desktop specific -this needs additional work to supported stacked window user interfaces too. - -The Android runtime environment ships with a minimal customized Android system -image based on the [Android Open Source Project](https://source.android.com/). -The used image is currently based on Android 7.1.1 - -## Installation - -The installation process currently consists of a few steps which will -add additional components to your host system. These include - - * Out-of-tree kernel modules for binder and ashmem as no distribution kernel - ships both enabled. - * A udev rule to set correct permissions for /dev/binder and /dev/ashmem - * A upstart job which starts the Anbox session manager as part of - a user session. - -To make this process as easy as possible we have bundled the necessary -steps in a snap (see https://snapcraft.io) called "anbox-installer". The -installer will perform all necessary steps. You can install it on a system -providing support for snaps by running - -``` -$ snap install --classic anbox-installer -``` - -Alternatively you can fetch the installer script via - -``` -$ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer -``` - -Please note that we don't support any possible Linux distribution out there -yet. Please have a look at the following chapter to see a list of supported -distributions. - -To proceed the installation process simply called - -``` -$ anbox-installer -``` - -This will guide you through the installation process. - -**NOTE:** Anbox is currently in a **pre-alpha development state**. Don't expect a -fully working system for a production system with all features you need. You will -for sure see bugs and crashes. If you do so, please don't hestitate and report them! - -**NOTE:** The Anbox snap currently comes **completely unconfined** and is because of -this only available from the edge channel. Proper confinement is a thing we want -to achieve in the future but due to the nature and complexity of Anbox this isn't -a simple task. - -## Supported Linux Distributions - -At the moment we officially support the following Linux distributions: - - * Ubuntu 16.04 (xenial) - -Untested but likely to work: - - * Ubuntu 14.04 (trusty) - * Ubuntu 16.10 (yakkety) - * Ubuntu 17.04 (zesty) - -## Install and Run Android Applications - -## Build from source - -To build the Anbox runtime itself there is nothing special to know. We're using -cmake as build system. A few build dependencies need to be present on your host -system: - - * libdbus - * google-mock - * google-test - * libboost - * libboost-filesystem - * libboost-log - * libboost-iostreams - * libboost-program-options - * libboost-system - * libboost-test - * libboost-thread - * libcap - * libdbus-cpp - * mesa (libegl1, libgles2) - * glib-2.0 - * libsdl2 - * libprotobuf - * protobuf-compiler - * lxc - -On an Ubuntu system you can install all build dependencies with the following -command: - -``` -$ sudo apt install build-essential cmake cmake-data debhelper dbus google-mock \ - libboost-dev libboost-filesystem-dev libboost-log-dev libboost-iostreams-dev \ - libboost-program-options-dev libboost-system-dev libboost-test-dev \ - libboost-thread-dev libcap-dev libdbus-1-dev libdbus-cpp-dev libegl1-mesa-dev \ - libgles2-mesa-dev libglib2.0-dev libglm-dev libgtest-dev liblxc1 \ - libproperties-cpp-dev libprotobuf-dev libsdl2-dev lxc-dev pkg-config \ - protobuf-compiler -``` - -Afterwards you can build Anbox with - -``` -$ mkdir build -$ cd build -$ cmake .. -$ make -``` - -A simple - -``` -$ make install -``` - -will install the necessary bits into your system. - -If you want to build the anbox snap instead you can do this with the following -steps: - -``` -$ mkdir android-images -$ cp /path/to/android.img android-images/android.img -$ snapcraft -``` - -The result will be a .snap file you can install on a system supporting snaps - -``` -$ snap install --dangerous --devmode anbox_1_amd64.snap -``` - -## Run Anbox - -Running Anbox from a local build requires a few more things you need to know -about. Please have a look at the ["Runtime Setup"](docs/runtime-setup.md) -documentation. - -## documentation - -You will find additional documentation for Anbox in the *docs* subdirectory -of the project source. - -Interesting things to have a look at - - * [Runtime Setup](docs/runtime-setup.md) - * [Build Android image](docs/build-android.md) - -## Reporting bugs - -If you have found an issue with Anbox, please [file a bug](https://github.com/anbox/anbox/issues/new). - -## Get in Touch - -If you want to get in contact with the developers please feel free to join the -*#anbox* IRC channel on [FreeNode](https://freenode.net/). - -## Copyright and Licensing - -Anbox reuses code from other projects like the Android QEMU emulator. These -projects are available in the external/ subdirectory with the licensing terms -included. - -The anbox source itself, if not stated differently in the relevant source files, -is licensed under the terms of the GPLv3 license. - ------------------------------------------------ - -via: https://github.com/anbox/anbox/blob/master/README.md - -作者:[ Anbox][a] -译者:[译者ID](https://github.com/译者ID) -校对:[校对者ID](https://github.com/校对者ID) - -本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 - -[a]:http://anbox.io/ diff --git a/translated/tech/20170406 Anbox - Android in a Box.md b/translated/tech/20170406 Anbox - Android in a Box.md new file mode 100644 index 0000000000..a206f29624 --- /dev/null +++ b/translated/tech/20170406 Anbox - Android in a Box.md @@ -0,0 +1,174 @@ +# Anbox + +Anbox 是一个基于容器的方式来在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。 + +## 概述 + +Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统并提供任何基于 GNU Linux 平台的 Android 程序。 + +容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于QEMU的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信并通过它发送所有硬件访问命令。 + +有关更多详细信息,请参考下文档: + + * [Android 硬件 OpenGL ES 仿真设计概述](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/android-emugl/DESIGN) + * [Android QEMU 快速管道](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMU-PIPE.TXT) + * [Android 的 "qemud" 复用守护进程](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) + * [Android qemud 服务](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD-SERVICES.TXT) + +Anbox 目前适合桌面使用,但也可使用移动操作系统,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于目前 Android 程序映射针对桌面环境,因此这还需要额外的工作来支持其他的用户界面。 + +Android 运行时环境带有一个基于[ Android 开源项目](https://source.android.com/)镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1 + +## 安装 + +安装过程目前由几个需要添加其他组件到系统中的步骤组成。包括: + +  * 没有分发版内核同时启用的 binder 和 ashmen 原始内核模块 +  * 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限 +  * 能够启动 Anbox 会话管理器作为用户会话的一个启动任务 + +为了使这个过程尽可能简单,我们做了一个简单的步骤(见 https://snapcraft.io),称为 “anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。 + +``` +$ snap install --classic anbox-installer +``` + +另外你可以通过下面的命令下载安装脚本。 + +``` +$ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer +``` + +请注意,我们还不支持除本文列出的其他 Linux 发行版。请查看下面的章节了解支持的发行版。 + +运行下面的命令进行安装。 + +``` +$ anbox-installer +``` + +本篇会引导你完成安装过程。 + +**注意:** Anbox 目前处于** pre-alpha 的开发状态**。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告他们! + +**注意:** Anbox snap 目前 **完全没有约束**,这是因为它只能从前沿频道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。 + +## 已支持的 Linux 发行版 + +目前我们官方支持下面的 Linux 发行版: + + * Ubuntu 16.04 (xenial) + +未测试但可能支持的: + + * Ubuntu 14.04 (trusty) + * Ubuntu 16.10 (yakkety) + * Ubuntu 17.04 (zesty) + +## 安装并运行 Android 程序 + +## 从源码构建 + +要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你系统中只需要一点构建依赖: + + * libdbus + * google-mock + * google-test + * libboost + * libboost-filesystem + * libboost-log + * libboost-iostreams + * libboost-program-options + * libboost-system + * libboost-test + * libboost-thread + * libcap + * libdbus-cpp + * mesa (libegl1, libgles2) + * glib-2.0 + * libsdl2 + * libprotobuf + * protobuf-compiler + * lxc + +在 Ubuntu 系统中你可以用下面的命令安装所有的依赖: + +``` +$ sudo apt install build-essential cmake cmake-data debhelper dbus google-mock \ + libboost-dev libboost-filesystem-dev libboost-log-dev libboost-iostreams-dev \ + libboost-program-options-dev libboost-system-dev libboost-test-dev \ + libboost-thread-dev libcap-dev libdbus-1-dev libdbus-cpp-dev libegl1-mesa-dev \ + libgles2-mesa-dev libglib2.0-dev libglm-dev libgtest-dev liblxc1 \ + libproperties-cpp-dev libprotobuf-dev libsdl2-dev lxc-dev pkg-config \ + protobuf-compiler +``` + +之后用下面的命令构建 Anbox: + +``` +$ mkdir build +$ cd build +$ cmake .. +$ make +``` + +一个简单的 + +``` +$ make install +``` + +会将必要的二进制安装到你的系统中。 + +如果你想要构建 anbox snap,你可以按照下面的步骤: + +``` +$ mkdir android-images +$ cp /path/to/android.img android-images/android.img +$ snapcraft +``` + +T结果是会有一个 .snap 文件,你可以在支持 snap 的系统上安装。 + +``` +$ snap install --dangerous --devmode anbox_1_amd64.snap +``` + +## 运行 Anbox + +要从本地构建运行 Anbox ,你需要了解更多一点。请参考["运行时步骤"](docs/runtime-setup.md)文档。 + +## 文档 + +在项目源代码的子目录下,你可以找到额外的关于 Anbox 的文档。 + +有兴趣可以看下: + + * [运行时步骤](docs/runtime-setup.md) + * [构建 Android 镜像](docs/build-android.md) + +## 报告 bug + +如果你发现了一个 Anbox 问题,请[提交一个 bug](https://github.com/anbox/anbox/issues/new)。 + +## 取得联系 + +如果你想要与开发者联系,你可以在 [FreeNode](https://freenode.net/) 中加入 *#anbox* 的 IRC 频道。 + +## 版权与许可 + +Anbox 重用了像 Android QEMU 模拟器这样的其他项目。这些项目可在外部、带有许可声明的子目录中得到。 + +anbox 源码本身,如果没有在相关源码中声明其他的许可,默认是 GPLv3 许可。 + +----------------------------------------------- + +via: https://github.com/anbox/anbox/blob/master/README.md + +作者:[ Anbox][a] +译者:[geekpi](https://github.com/geekpi) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://anbox.io/ From 0ac03f092e9752a28383fdafdf4066ed1d4bc0cd Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Fri, 14 Apr 2017 10:50:01 +0800 Subject: [PATCH 15/25] translated --- ... DDoS service to take down your enemies.md | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md index 3cbbd628a5..f6db2d15bf 100644 --- a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md +++ b/sources/talk/20170315 Hire a DDoS service to take down your enemies.md @@ -1,68 +1,54 @@ -translating by [kenxx](https://github.com/kenxx) - -Hire a DDoS service to take down your enemies 雇个 `DDoS` 服务干掉你的对手 ======================== ->With the rampant availability of IoT devices, cybercriminals offer denial of service attacks to take advantage of password problems. - >随着物联网设备的普及,网络犯罪分子提供拒绝服务攻击来占密码问题的便宜。 ![](http://images.techhive.com/images/article/2016/12/7606416730_e659cea89c_o-100698667-large.jpg) -With the onrush of connected internet of things (IoT) devices, distributed denial-of-service attacks are becoming a dangerous trend. Similar to what happened to [DNS service provider Dyn last fall][3], anyone and everyone is in the crosshairs. The idea of using unprotected IoT devices as a way to bombard networks is gaining momentum. 随物联网设备飞速发展,分布式拒绝服务攻击也变得越来越具有危险性了。就如 [DNS 服务商 Dyn 上年秋季之遭遇][3] 一样,黑客似乎瞄上了每个人,使用未受保护的物联网设备来轰炸网络正迎面而来。 -The advent of DDoS-for-hire services means that even the least tech-savvy individual can exact  revenge on some website. Step on up to the counter and purchase a stresser that can systemically take down a company. 可雇用的分布式拒绝服务攻击的出现意味着每个会点技术的人都能精准报复一些网站。加大攻击能力甚至可以从系统级别的让一个公司完蛋。 -According to [Neustar][4], almost three quarters of all global brands, organizations and companies have been victims of a DDoS attack. And more than 3,700 [DDoS attacks occur each day][5]. 根据 [Neustar][4] 的报告,全球四分之三的品牌、组织和公司都是 `DDos` 攻击的受害者。[每天 `DDoS` 攻击发生次数][5] 不少于 3700 次。 -#### [■ RELATED: How can you detect a fake ransom letter?][1] - #### [■ 相关阅读:如何判断假绑架信?][1] - -Chase Cunningham, director of cyber operations at A10 Networks, said to find IoT-enabled devices, all you have to do is go on an underground site and ask around for the Mirai scanner code. Once you have that you can scan for anything talking to the internet that can be used for that type of attack.  睿科网络公司(A10 Networks)网络运营总监 Chase Cunningham 说:“想要找个可用的物联网设备,你只需要在地下网站找一个 `Mirai` 扫描器,一旦你得到了这款扫描器,你将能够利用在线的每一台设备来进行攻击”。 -“Or you can go to a site like Shodan and craft a couple of simple queries to look for device specific requests. Once you get that information you just go to your DDoS for hire tool and change the configuration to point at the right target and use the right type of traffic emulator and bingo, nuke whatever you like,” he said. -或者你可以去一些类似 `Shodan` 的网站然后简单的搜一下设备特殊请求, +“或者你可以去一些类似 `Shodan` 的网站,然后简单的搜一下特殊设备的请求。当你得到这些信息之后,你就可以将你的雇佣的 `DDoS` 工具配置正确的流量模拟器类型、指向正确的目标并发动攻击。” -“Basically everything is for sale," he added. "You can buy a 'stresser', which is just a simple botnet type offering that will allow anyone who knows how to click the start button access to a functional DDoS botnet.” +“几乎所有东西都是可售的。”他补充道,“你可以购买一个‘stresser’,这就是个随便哪个会点按钮的人都会使用的 `DDoS` 功能的僵尸网络。” ->Once you get that information you just go to your DDoS for hire tool and change the configuration to point at the right target and use the right type of traffic emulator and bingo, nuke whatever you like. +>当你得到这些信息之后,你就可以将你的雇佣的 `DDoS` 工具配置正确的流量模拟器类型、指向正确的目标并发动攻击。 ->Chase Cunningham, A10 director of cyber operations +>Chase Cunningham,睿科网络公司(A10 Networks)网络运营总监 -Cybersecurity vendor Imperva says for just a few dozen dollars, users can quickly get an attack up and running. The company writes on its website that these kits contain the bot payload and the CnC (command and control) files. Using these, aspiring bot masters (a.k.a. herders) can start distributing malware, infecting devices through a use of spam email, vulnerability scanners, brute force attacks and more. +网络安全提供商 Imperva 说,用户只需要出几十元美金,就可以快速发动攻击。有些公司编写了一些工具包含了肉鸡负载和 `CnC`(命令与控制)文件。使用这些工具,那些有点想法的肉鸡大师(或者说 `herders`)就可以开始通过垃圾邮件来传播使设备感染恶意软件、漏洞扫描程序、暴力攻击等等。 +大部分 [stressers and booters][6] 都会有一个常见的、基于订阅的 `SaaS`(软件即服务)业务模式。来自 Incapsula 公司的 [Q2 2015 DDoS 报告][7] 显示,一个月范围内平均每小时就会有38美元(规模较低的在19.99美元)花在购买 `DDoS` 服务上。 -Most [stressers and booters][6] have embraced a commonplace SaaS (software as a service) business model, based on subscriptions. As the Incapsula [Q2 2015 DDoS report][7] has shown, the average one hour/month DDoS package will cost $38 (with $19.99 at the lower end of the scale). + ![雇佣ddos服务](http://images.techhive.com/images/article/2017/03/ddos-hire-100713247-large.jpg) - ![ddos hire](http://images.techhive.com/images/article/2017/03/ddos-hire-100713247-large.jpg) +“`Stresser` 和 `booter` 只是一个新型现实的副产品,这些可以扳倒企业和组织的服务只被允许运作在灰色领域”,Imperva 写道。 -“Stresser and booter services are just a byproduct of a new reality, where services that can bring down businesses and organizations are allowed to operate in a dubious grey area,” Imperva wrote. +虽然成本不同,但是企业受到 [攻击可在任何地方,每次损失在 1.4 万美元到 235 万美元][8]。然而企业受到一次攻击后,[有 82% 的可能性会再次受到攻击][9]。 -While cost varies, [attacks can run businesses anywhere from $14,000 to $2.35 million per incident][8]. And once a business is attacked, there’s an [82 percent chance they’ll be attacked again][9]. +物联网洪水攻击(DoT, DDoS of Things)使用物联网设备建立僵尸网络可造成非常大规模的 `DDoS` 攻击。物联网洪水攻击会利用成百上千的物联网设备造成杠杆来攻击大型服务提供商。 -DDoS of Things (DoT) use IoT devices to build botnets that create large DDoS attacks. The DoT attacks have leveraged hundreds of thousands of IoT devices to attack anything from large service providers to enterprises.  +“大部分可信的 `DDoS` 卖家都会将他们的工具的配置设置的很简单,这样你就可以简单的更换配置开始攻击。虽然我还没怎么看到有哪些可以‘付费’物联网流量模拟器的选项,但我敢肯定准备要有了。如果是我来搞这个服务,我是绝对会加入这个选项的。”Cunningham 如是说。 -“Most of the reputable DDoS sellers have changeable configurations for their tool sets so you can easily set the type of attack you want to take place. I haven’t seen many yet that specifically include the option to ‘purchase’ an IoT-specific traffic emulator but I’m sure it’s coming. If it were me running the service I would definitely have that as an option,” Cunningham said. +由 IDG 新闻服务的故事我们可知,要建造一个攻击服务的 `DDoS` 服务也可以很简单。通常黑客会租用 6 到 12 个左右的服务器,然后使用他们随意的攻击任何目标。十月下旬,HackForums.net [关闭][10]了他们的”服务器压力测试“部分,此次做法就是考虑到黑客可能通过使用他们十美元每月的服务建造可雇佣的 `DDoS` 服务。 -According to an IDG News Service story, building a DDoS-for-service can also be easy. Often the hackers will rent six to 12 servers, and use them to push out internet traffic to whatever target. In late October, HackForums.net [shut down][10] its "Server Stress Testing" section, amid concerns that hackers were peddling DDoS-for-hire services through the site for as little as $10 a month. +同样地在十二月时,美国和欧洲的执法机构 [逮捕][11] 34个参与可雇佣的 `DDoS` 服务的嫌犯。 -Also in December, law enforcement agencies in the U.S. and Europe [arrested][11] 34 suspects involved in DDoS-for-hire services. +如果这很简单,怎么还没有经常发生攻击? -If it is so easy to do so, why don’t these attacks happen more often?   +Cunningham 说这其实每时每刻都在发生,实际上每天每秒没完没了。他说:”你不知道的原因是因为大部分的都是扰乱攻击,而不是大规模的、想要搞倒公司的攻击。“ -Cunningham said that these attacks do happen all the time, in fact they happen every second of the day. “You just don’t hear about it because a lot of these are more nuisance attacks than big time bring down the house DDoS type events,” he said. +他说,大部分的攻击平台只出售那些会让系统宕机一个小时或就长一点点的攻击。通常宕机一小时的攻击大概需要15到50美元的成本。当然这得看平台,有些可能想让其一小时就要花上百美元。 -Also a lot of the attack platforms being sold only take systems down for an hour or a bit longer. Usually an hour-long attack on a site will cost anywhere from $15 to $50\. It depends, though, sometimes for better attack platforms it can hundreds of dollars an hour, he said. - -The solution to cutting down on these attacks involves users resetting factory preset passwords on anything connected to the internet. Change the default password settings and disable things that you really don’t need. +减少这些攻击的解决方案是让用户把所有联网设备的恢复出厂设置的预设密码改掉,改掉默认密码然后还要禁用那些你不需要的功能。 -------------------------------------------------------------------------------- From e43d31212eaef9829ed3625b705110ab3ac9425d Mon Sep 17 00:00:00 2001 From: Kenneth Hawk Date: Fri, 14 Apr 2017 10:52:31 +0800 Subject: [PATCH 16/25] translate --- .../20170315 Hire a DDoS service to take down your enemies.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sources => translated}/talk/20170315 Hire a DDoS service to take down your enemies.md (100%) diff --git a/sources/talk/20170315 Hire a DDoS service to take down your enemies.md b/translated/talk/20170315 Hire a DDoS service to take down your enemies.md similarity index 100% rename from sources/talk/20170315 Hire a DDoS service to take down your enemies.md rename to translated/talk/20170315 Hire a DDoS service to take down your enemies.md From 6e75e79bc696e31da32cbc70d69ffa8094912067 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 16:17:33 +0800 Subject: [PATCH 17/25] PRF&PUB:20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md @GitFuture --- ...ing visual diffmerge tool Meld on Linux.md | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 deletions(-) rename {translated/tech => published}/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md (76%) diff --git a/translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md b/published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md similarity index 76% rename from translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md rename to published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md index aca65df359..401235218c 100644 --- a/translated/tech/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md +++ b/published/20170119 A beginners guide to comparing files using visual diffmerge tool Meld on Linux.md @@ -1,24 +1,17 @@ -Linux 系统可视化的比较与合并工具 Meld 的新手使用教程 +Linux 系统上的可视化比较与合并工具 Meld ============================================================ -### 本页内容 - -1. [关于 Meld][1] -2. [安装 Meld][2] -3. [使用 Meld][3] -4. [总结][4] - -我们已经[讲过][5] Linux 中[一些][6]基于命令行的比较和合并工具,再来讲解该系统的一些可视化的比较与合并工具也很合理。首要的原因是,不是每个人都习惯使用命令行,而且对于某些人来说,基于命令行的比较工具可能很难学习和理解。 +我们已经[讲过][5] Linux 中[一些][6]基于命令行的比较和合并工具,再来讲解该系统的一些可视化的比较与合并工具也很合理。首要的原因是,不是每个人都习惯使用命令行,而且对于某些人来说,基于命令行的比较工具可能很难学习和理解。 因此,我们将会推出关于可视化工具 **Meld** 的系列文章。 -在跳到安装和介绍部分前,分享这篇教程所有指令和用例是很有用的,而且它们已经在 Ubuntu 14.04 中测试过了,我们使用的 Meld 版本是 3.14.2。 +在跳到安装和介绍部分前,我需要说明这篇教程里所有的指令和用例是都是可用的,而且它们已经在 Ubuntu 14.04 中测试过了,我们使用的 Meld 版本是 3.14.2。 ### 关于 Meld -[Meld][7] 主要是一个可视化的比较和合并的工具,目标人群是开发者(当然,我们将要讲到的其它部分也会考虑到终端用户)。这个工具同时支持双向和三向的比较,不仅仅是比较文件,还可以比较目录,以及版本控制的项目。 +[Meld][7] 主要是一个可视化的比较和合并的工具,目标人群是开发者(当然,我们将要讲到的其它部分也会考虑到最终用户)。这个工具同时支持双向和三向的比较,不仅仅是比较文件,还可以比较目录,以及版本控制的项目。 -“Meld 帮你回顾代码改动,理解补丁,”官网如是说。“它甚至可以告知你如果你不进行合并将会发生什么事情。”该工具使用 GPL v2 协议进行授权。 +“Meld 可以帮你回顾代码改动,理解补丁,”其官网如是说。“它甚至可以告知你如果你不进行合并将会发生什么事情。”该工具使用 GPL v2 协议进行授权。 ### 安装 Meld @@ -28,11 +21,13 @@ Linux 系统可视化的比较与合并工具 Meld 的新手使用教程 sudo apt-get install meld ``` -或者你也可以用系统自带的包管理软件下载这个工具。比如在 Ubuntu 上,你可以用 Ubuntu 软件中心(Ubuntu Software Center),或者用 [Ubuntu Software][8],Ubuntu Software 从 Ubuntu 16.04 版本开始取代了软件中心。 +或者你也可以用系统自带的包管理软件下载这个工具。比如在 Ubuntu 上,你可以用 Ubuntu 软件中心(Ubuntu Software Center),或者用 [Ubuntu 软件][8],它从 Ubuntu 16.04 版本开始取代了 Ubuntu 软件中心。 -当然,Ubuntu 官方仓库里的 Meld 版本很有可能比较陈旧。因此如果你想要用更新的版本,你可以在[这里][9]下载软件包。如果你要用这个方法,你要做的就是解压下载好的软件包,然后运行 “bin” 目录下的 “meld” 程序。 +当然,Ubuntu 官方仓库里的 Meld 版本很有可能比较陈旧。因此如果你想要用更新的版本,你可以在[这里][9]下载软件包。如果你要用这个方法,你要做的就是解压下载好的软件包,然后运行 `bin` 目录下的 `meld` 程序。 -~/Downloads/meld-3.14.2/bin$ **./meld**  +``` +~/Downloads/meld-3.14.2/bin$ ./meld  +``` 以下是 Meld 依赖的软件,仅供参考: @@ -67,9 +62,9 @@ sudo apt-get install meld ![Compare files in Meld](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-diff-in-action-3.png) ][12] -两个文件的不同之处在第二行,差别在于 “file2” 文件的第二行多了一个 “3”。你看到的黑色箭头是用来进行合并或修改的操作的。该例中,向右的箭头将会把 “file2” 文件的第二行改成文件 “file1” 中对应行的内容。左向箭头做的事情相反。 +两个文件的不同之处在第二行,差别在于 `file2` 文件的第二行多了一个 `3`。你看到的黑色箭头是用来进行合并或修改的操作的。该例中,向右的箭头将会把 `file2` 文件的第二行改成文件 `file1` 中对应行的内容。左向箭头做的事情相反。 -做完修改后,按下 Ctrl+s 来保存。 +做完修改后,按下 `Ctrl+s` 来保存。 这个简单的例子,让你知道 Meld 的基本用法。让我们看一看稍微复杂一点的比较: @@ -77,13 +72,13 @@ sudo apt-get install meld ![Meld advanced file comparison](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-multiple-changes-4.png) ][13] -在讨论这些变化前,这里提一下, Meld GUI 中有几个区域,可以给出文件之间的差异,让概况变得直观。这里特别需要注意窗口的左右两边垂直的栏。比如下面这个截图: +在讨论这些变化前,这里提一下, Meld 的界面中有几个区域,可以给出文件之间的差异,让概况变得直观。这里特别需要注意窗口的左右两边垂直的栏。比如下面这个截图: [ ![Visual Comparison](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-multiple-colors-5.png) ][14] -仔细观察,图中的这个栏包含几个不同颜色的区块。这些区块是用来让你对文件之间的差异有个大概的了解。“每一个上色的区块表示一个部分,这个部分可能是插入、删除、修改或者有差别的,取决于区块所用的颜色。”官方文档是这样说的。 +仔细观察,图中的这个栏包含几个不同颜色的区块。这些区块是用来让你对文件之间的差异有个大概的了解。“每一个着色的区块表示一个部分,这个部分可能是插入、删除、修改或者有差别的,取决于区块所用的颜色。”官方文档是这样说的。 现在,让我们回到我们之前讨论的例子中。接下来的截图展示了用 Meld 理解文件的改动是很简单的(以及合并这些改动): @@ -105,19 +100,19 @@ sudo apt-get install meld ![Go to next change in Meld](https://www.howtoforge.com/images/how-to-use-visual-diff-and-merge-tools-in-linux-meld-and-kdiff/meld-go-next-prev-9.png) ][18] -这些是你使用 Meld 时做的一般性的事情:可以用标准的 “Ctrl+f” 组合键在编辑区域内进行查找,按 “F11” 键让软件进入全屏模式,再按 “Ctrl+f” 来刷新(通常在所有要比较的文件改变的时候使用)。 +这些是你使用 Meld 时做的一般性的事情:可以用标准的 `Ctrl+f` 组合键在编辑区域内进行查找,按 `F11` 键让软件进入全屏模式,再按 `Ctrl+r` 来刷新(通常在所有要比较的文件改变的时候使用)。 以下是 Meld 官方网站宣传的重要特性: * 文件和目录的双向及三向比较 * 输入即更新文件的比较 -* 自动合并模式,改动区块的动作让合并更加简单 +* 自动合并模式,按块改动的动作让合并更加简单 * 可视化让比较文件更简单 * 支持 Git,Bazaar,Mercurial,Subversion 等等 -注意还不仅仅只有以上所列的。网站上有个专门的[特性页面][19],里面提到了 Meld 提供的所有特性。这个页面列出的所有特性分为几个部分,以该软件是用来做文件比较,目录比较,版本控制还是处于合并模式下为基础进行划分。 +注意还不仅仅只有以上所列的。网站上有个专门的[特性页面][19],里面提到了 Meld 提供的所有特性。这个页面列出的所有特性分为几个部分,以该软件是用来做文件比较、目录比较、版本控制还是处于合并模式下为基础进行划分。 -和其它软件相似,有些事情 Meld 做不到。官方网站上列出了其中的一部分:“当 Meld 展示文件之间的差异时,它同时显示两个文件,看起来就像在普通的文本编辑器中。它不会添加额外的行,让左右两边文件的特殊改动是同样的行数。没有做这个事情的选项。” +和其它软件相似,有些事情 Meld 做不到。官方网站上列出了其中的一部分:“当 Meld 展示文件之间的差异时,它同时显示两个文件,看起来就像在普通的文本编辑器中。它不会添加额外的行,让左右两边文件的特殊改动处于同样的行数。没有做这个事情的选项。” ### 总结 @@ -129,7 +124,7 @@ via: https://www.howtoforge.com/tutorial/beginners-guide-to-visual-merge-tool-me 作者:[Ansh][a] 译者:[GitFuture](https://github.com/GitFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 75bbdc938347cde6194374c72f50afb07a686af1 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 16:50:16 +0800 Subject: [PATCH 18/25] PRF&PUB:20170128 How communities in India support privacy and software freedom.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @geekpi 这篇翻译质量很高! --- ...ia support privacy and software freedom.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) rename {translated/tech => published}/20170128 How communities in India support privacy and software freedom.md (65%) diff --git a/translated/tech/20170128 How communities in India support privacy and software freedom.md b/published/20170128 How communities in India support privacy and software freedom.md similarity index 65% rename from translated/tech/20170128 How communities in India support privacy and software freedom.md rename to published/20170128 How communities in India support privacy and software freedom.md index 56cb37cb2a..f5005dc98d 100644 --- a/translated/tech/20170128 How communities in India support privacy and software freedom.md +++ b/published/20170128 How communities in India support privacy and software freedom.md @@ -1,24 +1,25 @@ -印度社区如何支持隐私和软件自由 +印度的社区如何支持隐私和软件自由 ============================================================ ![How communities in India support privacy and software freedom](https://opensource.com/sites/default/files/styles/image-full-size/public/images/life/people_remote_teams_world.png?itok=wI-GW8zX "How communities in India support privacy and software freedom") + 图片提供: opensource.com -印度的自由和开源社区,特别是 Mozilla 和 Wikimedia 社区,它们正在引领两个独特的全球性活动,以提高隐私及支持自由软件。 +印度的自由和开源社区,特别是 Mozilla 和 Wikimedia 社区,它们正在引领两个独特的全球性活动,以提高隐私保护及支持自由软件。 [1 月份的隐私月][3]是由印度 Mozilla 社区领导,通过在线和线下活动向群众教育网络隐私。而[ 2 月份的自由月][4]是由[互联网与社会中心][5]领导,教育内容创作者如博主和摄影师就如何在[开放许可证][6]下捐赠内容。 ### 1 月隐私月 -从[去年开始][7]的 Mozilla “1 月隐私月”用来帮助庆祝年度[数据隐私日][8]。在 2016 年,该活动举办了几场涉及[全球 10 个国家 14,339,443 人][9]的线下和线上活动。其中一个核心组织者,[Ankit Gadgil][10]这样说到:“每天分享一个隐私提示,持续一个月 31 天是有可能的。今年,我们共有三个重点领域,首先是我们让这个运动更加开放和全球化。巴西、意大利、捷克共和国的 Mozilla 社区今年正在积极参与,所有的必要文件都是本地化的,所以我们可以针对更多的用户。其次,我们在线下活动中教导用户营销 Firefox 以及 Mozilla 的其他产品,以便用户可以亲身体验使用这些工具来帮助保护他们的隐私。第三点,我们鼓励大家参加线下活动并记录他们的学习,例如,最近在印度古吉拉特邦的一个节目中,他们使用 Mozilla 产品来教授隐私。” +从[去年开始][7]的 Mozilla “1 月隐私月”用来帮助庆祝年度[数据隐私日(Data Privacy Day)][8]。在 2016 年,该活动举办了几场涉及到[全球 10 个国家 14,339,443 人][9]的线下和线上活动。其中一个核心组织者,[Ankit Gadgil][10] 这样说到:“每天分享一个隐私提示,持续一个月就能分享 31 天。”今年,我们共有三个重点领域,首先是我们让这个运动更加开放和全球化。巴西、意大利、捷克共和国的 Mozilla 社区今年正在积极参与,所有必要的文档都是本地化的,所以我们可以针对更多的用户。其次,我们在线下活动中教导用户推广 Firefox 以及 Mozilla 的其他产品,以便用户可以亲身体验使用这些工具来帮助保护他们的隐私。第三点,我们鼓励大家参加线下活动并把他们的学习写到博客里面去,例如,最近在印度古吉拉特邦的一个节目中,他们使用 Mozilla 产品来教授隐私方面的知识。” 今年的活动继续有线下和线上活动。关注 #PrivacyAware 参加。 -### 安全提示 +#### 安全提示 -像 Firefox 这样的 Mozilla 产品具有安全性设置-同时还有[内建][11]还有附加的对残疾人完全[可用][12]的库-这有助于保护用户的隐私和安全性,这些都是协同构建的并且是开源的。 +像 Firefox 这样的 Mozilla 产品具有安全性设置-有[内置的][11]还有对残疾人完全[可用][12]的附件库-这有助于保护用户的隐私和安全性,这些都是协同构建的并且是开源的。 -[Chrome][14] 和[ Opera][15] 中的 [HTTPS Everywhere][13] 可用于加密用户通信,使外部网站无法查看用户信息。该项目由 [Tor Project][16]以及[电子前沿基金会][17]合作建成。 +[Chrome][14] 和[ Opera][15] 中的 [HTTPS Everywhere][13] 插件可用于加密用户通信,使外部网站无法查看用户信息。该项目由 [Tor Project][16] 以及[电子前沿基金会][17]合作建成。 ### 2 月自由月 @@ -27,15 +28,15 @@ ** 参加规则:** * 你在二月份制作或出版的作品必须获得[自由许可证][1]许可。 -* 内容类型包括博客帖子、其他文字和图像。 +* 内容类型包括博客文章、其他文字和图像。 -多媒体,基于文本的内容,艺术和设计等创意作品可以通过多个[知识共享许可证][20](CC)进行许可,其他类型的文档可以根据[ GNU 免费文档许可][21](GFDL)许可。Wikipedia 上可以找到很好的例子,其内容根据 CC 和 GFDL 许可证获得许可,允许人们使用、分享、混合和分发衍生用于商业上和非商业性的作品。此外,还有允许开发人员共享他们的软件和软件相关文档的[自由软件许可证][22]。 +多媒体,基于文本的内容,艺术和设计等创意作品可以通过多个[知识共享许可证][20](CC)进行许可,其他类型的文档可以根据 [GNU 免费文档许可][21](GFDL)许可。Wikipedia 上可以找到很好的例子,其内容根据 CC 和 GFDL 许可证获得许可,允许人们使用、分享、混合和分发衍生用于商业上和非商业性的作品。此外,还有允许开发人员共享他们的软件和软件相关文档的[自由软件许可证][22]。 -------------------------------------------------------------------------------- 作者简介: -Subhashish Panigrahi - Subhashish Panigrahi(@shhapa)是 Mozilla 参与团队的亚洲社区催化师,并从 Wikimedia 基金会印度计划的早期扮演了互联网及社会知识获取中心项目官的角色,另外他是一名印度教育者, +Subhashish Panigrahi(@shhapa)是 Mozilla 参与团队的亚洲社区催化师,并在 Wikimedia 基金会印度计划的早期扮演了互联网及社会知识获取中心项目官的角色,另外他是一名印度教育工作者, -------------------------------------------------------------------------------- @@ -43,7 +44,7 @@ via: https://opensource.com/article/17/1/how-communities-india-support-privacy-s 作者:[Subhashish Panigrahi][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 1728b0cfdb0cfecd64d36326a1a18df252d0f90d Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:07:27 +0800 Subject: [PATCH 19/25] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对中 --- ...0403 Yes Python is Slow and I Dont Care.md | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md index c32d2ffb51..cd5587f971 100644 --- a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md +++ b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md @@ -5,75 +5,75 @@ python 是慢,但是爷就喜欢它 ![](https://cdn-images-1.medium.com/max/800/0*pWAgROZ2JbYzlDgj.jpg) - 我从关于Python中的asyncio这个标准库的讨论中休息一会,这次讨论是要谈论我最近正在思考的一些东西:Python的速度。相比那些不了解Python的人,我是一个Python的粉丝,而且我在我能想到的所有地方都积极地使用Python。人们对Python最大的抱怨之一就是它的速度比较慢,有些人甚至拒绝尝试使用Python,因为它比其他语言更慢的速度。这里我对于为什么你应该尝试使用Python的一些想法,尽管它是有点慢。 +我从关于 Python 中的 asyncio 这个标准库的讨论中休息一会,谈谈我最近正在思考的一些东西:Python 的速度。对不了解我的人说明一下,我是一个 Python 的粉丝,而且我在我能想到的所有地方都积极地使用 Python。人们对 Python 最大的抱怨之一就是它的速度比较慢,有些人甚至拒绝尝试使用 Python,因为它比其他语言速度慢。这里说说为什么我认为应该尝试使用 Python,尽管它是有点慢。 ### 速度不再重要 -过去的情形是,程序需要花费很长的时间来运行,CPU比较贵,内存更加贵。程序的运行时间是一个很重要的指标。计算机非常的昂贵,计算机运行所需要的电也是相当贵的。对这些资源进行优化是因为一个永恒的商业法则: +过去的情形是,程序需要花费很长的时间来运行,CPU 比较贵,内存也很贵。程序的运行时间是一个很重要的指标。计算机非常的昂贵,计算机运行所需要的电也是相当贵的。对这些资源进行优化是因为一个永恒的商业法则: -> 优化你最贵的资源 +> 优化你最贵的资源Optimize your most expensive resource。 在过去,最贵的资源是计算机的运行时间。这就是导致计算机科学致力于研究不同算法的效率的原因。然而,这已经不再是正确的,因为现在硅芯片很便宜,确实很便宜。运行时间不再是你最贵的资源。公司最贵的资源现在是它的员工的时间。或者换句话说,就是你。把事情做完比快速地做事更加重要。实际上,这是相当的重要,我将把它再次放在这里,仿佛它是一个引用一样(对于那些只是粗略浏览的人): -> 把事情做完比快速地做事更加重要。 +> 把事情做完比快速地做事更加重要It’s more important to get stuff done than to make it go fast。 -你可能会说:"我的公司在意速度,我开发一个web应用程序,那么所有的响应时间必须少于x毫秒。"或者,"我们失去了客户,因为他们认为我们的app运行太慢了。"我并不是想说速度一点也不重要,我只是想说速度不再是最重要的东西;它不再是你最贵的资源。 +你可能会说:“我的公司在意速度,我开发一个 web 应用程序,那么所有的响应时间必须少于 x 毫秒。”或者,“我们失去了客户,因为他们认为我们的 app 运行太慢了。”我并不是想说速度一点也不重要,我只是想说速度不再是最重要的东西;它不再是你最贵的资源。 ![](https://cdn-images-1.medium.com/max/800/0*Z6j9zMua_w-T25TC.jpg) ### 速度是唯一重要的东西 -当你在编程的背景下说 _速度_ 时,你通常意味着性能,也就是CPU周期。当你的CEO在编程的背景下说 _速度_ 时,他指的是业务速度,最重要的指标是产品上市的时间。基本上,你的产品/web程序是多么的快并不重要。它是用什么语言写的也不重要。甚至它需要花费多少钱也不重要。在一天结束时,让你的公司存活下来或者死去的唯一事物就是产品上市时间。我不只是说创业公司的想法--你开始赚钱需要花费多久,更多的是"从想法到客户手中"的时间期限。企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。如果在你将立产品上市之前,你的竞争对手已经提前上市了,那么你想出了多少好的主意也将不再重要。你不得不成为第一个上市的,或者至少能跟上。你但你放慢了脚步,你就输了。 +当你在编程的背景下说 _速度_ 时,你通常意味着性能,也就是 CPU 周期。当你的 CEO 在编程的背景下说 _速度_ 时,他指的是业务速度,最重要的指标是产品上市的时间。基本上,你的产品/web 程序是多么的快并不重要。它是用什么语言写的也不重要。甚至它需要花费多少钱也不重要。在一天结束时,让你的公司存活下来或者死去的唯一事物就是产品上市时间。我不只是说创业公司的想法 -- 你开始赚钱需要花费多久,更多的是“从想法到客户手中”的时间期限。企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。如果在你的产品上市之前,你的竞争对手已经提前上市了,那么你想出了多少好的主意也将不再重要。你必须第一个上市,或者至少能跟上。一但你放慢了脚步,你就输了。 -> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新。 +> 企业能够存活下来的唯一方法就是比你的竞争对手更快地创新The only way to survive in business is to innovate faster than your competitors。 -### 一个微服务的案例 +#### 一个微服务的案例 -像Amazon、Google和Netflix这样的公司明白快速前进的重要性。他们创建了一个业务系统,他们可以使用这个系统迅速地前进和快速的创新。微服务是针对他们的问题的解决方案。这篇文章与你是否应该使用微服务没有关系,但是至少得接受Amazon和Google认为他们应该使用微服务。 +像 Amazon、Google 和 Netflix 这样的公司明白快速前进的重要性。他们创建了一个业务系统,可以使用这个系统迅速地前进和快速的创新。微服务是针对他们的问题的解决方案。这篇文章不谈你是否应该使用微服务,但是至少要接受 Amazon 和 Google 认为他们应该使用微服务。 ![](https://cdn-images-1.medium.com/max/600/0*MBM9zatYv_Lzr3QN.jpg) - 微服务本来就很慢。微服务的一个恰当的概念是用网络调用来打破一个边界。这意味着你正在采取一个函数调用(几个cpu周期)并把这转变为一个网络调用。没有什么比这更影响性能了。和CPU想比较,网络调用真的很慢。但是这些大公司仍然选择使用微服务。我所知道的架构里面没有任何一个比微服务还要慢。微服务最大的弊端就是它的性能,但是最大的长处就是上市的时间。通过团结较小的项目和代码库建立团队,一个公司能够以更快的速度进行迭代和创新。这恰恰表明了,非常大的公司也很在意上市时间,而不仅仅只是只有创业公司。 +微服务本来就很慢。微服务的主要概念是用网络调用来打破边界。这意味着你正在使用一个函数调用(几个 cpu 周期)并将它转变为一个网络调用。没有什么比这更影响性能了。和 CPU 相比较,网络调用真的很慢。但是这些大公司仍然选择使用微服务。我所知道的架构里面没有比微服务还要慢的了。微服务最大的弊端就是它的性能,但是最大的长处就是上市的时间。通过在较小的项目和代码库上建立团队,一个公司能够以更快的速度进行迭代和创新。这恰恰表明了,非常大的公司也很在意上市时间,而不仅仅只是只有创业公司。 -### CPU不是你的瓶颈 +#### CPU不是你的瓶颈 ![](https://cdn-images-1.medium.com/max/800/0*s1RKhkRIBMEYji_w.jpg) - 如果你在写一个网络应用程序,如web服务器,很有可能的情况会是,CPU时间并不是你的程序的瓶颈。当你的web服务器处理一个请求时,可能会进行几次网络调用,例如数据库,或者像Redis这样的缓存服务器。虽然这些服务本身可能比较快速,但是对它们的网络调用却很慢。[有一篇很好的关于特定操作的速度差异的博客文章][1]。在这篇文章里,作者把CPU周期时间缩放到更容易理解的人类时间。如果一个单独的周期等同于1秒,那么一个从California到New York的网络调用将相当于4年。那就说明了网络调用是多少的慢。对于一些粗略估计,我们可以假设在同一数据中心内的普通网络调用大约需要3ms。这相当于我们“人类比例”3个月。现在假设你的程序是高CPU密集型,这需要100000个CPU周期来对单一调用进行响应。这相当于刚刚超过1天。现在让我们假设你使用的是一种要慢5倍的语言,这将需要大约5天。很好,将那与我们3个月的网络调用时间相比,4天的差异就显得并不是很重要了。如果有人为了一个包裹不得不至少等待3个月,我不认为额外的4天对他们来说真的很重要。 + 如果你在写一个网络应用程序,如 web 服务器,很有可能的情况会是,CPU 时间并不是你的程序的瓶颈。当你的 web 服务器处理一个请求时,可能会进行几次网络调用,例如到数据库,或者像 Redis 这样的缓存服务器。虽然这些服务本身可能比较快速,但是对它们的网络调用却很慢。[有一篇很好的关于特定操作的速度差异的博客文章][1]。在这篇文章里,作者把 CPU 周期时间缩放到更容易理解的人类时间。如果一个单独的周期等同于 1 秒,那么一个从 California 到 New York 的网络调用将相当于 4 年。那就说明了网络调用是多少的慢。按一些粗略估计,我们可以假设在同一数据中心内的普通网络调用大约需要 3 ms。这相当于我们“人类比例” 3 个月。现在假设你的程序是高 CPU 密集型,这需要 100000 个 CPU 周期来对单一调用进行响应。这相当于刚刚超过 1 天。现在让我们假设你使用的是一种要慢 5 倍的语言,这将需要大约 5 天。很好,将那与我们 3 个月的网络调用时间相比,4 天的差异就显得并不是很重要了。如果有人为了一个包裹不得不至少等待 3 个月,我不认为额外的 4 天对他们来说真的很重要。 -上面所说的终极意思是,尽管Python速度慢,但是这并不重要。语言的速度(或者CPU时间)几乎从来不是问题。实际上谷歌曾经就这一概念做过一个研究,[并且他们发表过一篇关于这的论文][2]。那篇论文论述了设计高吞吐量的系统。在结论里,他们说到: +上面所说的终极意思是,尽管 Python 速度慢,但是这并不重要。语言的速度(或者 CPU 时间)几乎从来不是问题。实际上谷歌曾经就这一概念做过一个研究,[并且他们就此发表过一篇论文][2]。那篇论文论述了设计高吞吐量的系统。在结论里,他们说到: -> 在高吞吐量的环境中使用解释性语言似乎是矛盾的,但是我们已经发现CPU时间几乎不是限制因素;语言的表达性是指,大多数程序是源程序,同时花费它们的大多数时间在I/O读写和本机运行时代码。而且,解释性语言无论是在语言层面的轻松实验还是在允许我们在很多机器上探索分布计算的方法都是很有帮助的, +> 在高吞吐量的环境中使用解释性语言似乎是矛盾的,但是我们已经发现 CPU 时间几乎不是限制因素;语言的表达性是指,大多数程序是源程序,同时花费它们的大多数时间在 I/O 读写和本机运行时代码。而且,解释性语言无论是在语言层面的轻松实验还是在允许我们在很多机器上探索分布计算的方法都是很有帮助的, 再次强调: -> CPU时间几乎不是限制因素。 +> CPU 时间几乎不是限制因素the CPU time is rarely the limiting factor。 -### 如果CPU时间是一个问题怎么办? +### 如果 CPU 时间是一个问题怎么办? -你可能会说,"前面说的情况真是太好了,但是我们确实有过一些问题,这些问题中CPU成为了我们的瓶颈,并造成了我们的web应用的速度十分缓慢",或者"在服务器上X语言比Y语言需要需要更少的硬件资源来运行。"这些都可能是对的。关于web服务器有这样的美妙的事情:你可以几乎无限地负载均衡它们。换句话说,可以在web服务器上投入更多的硬件。当然,Python可能会比其他语言要求更好的硬件资源,比如c语言。只是把硬件投入在CPU问题上。相比于你的时间,硬件就显得非常的便宜了。如果你在一年内节省了两周的生产力时间,那将远远多于所增加的硬件开销的回报。 +你可能会说,“前面说的情况真是太好了,但是我们确实有过一些问题,这些问题中 CPU 成为了我们的瓶颈,并造成了我们的 web 应用的速度十分缓慢”,或者“在服务器上 X 语言比 Y 语言需要更少的硬件资源来运行。”这些都可能是对的。关于 web 服务器有这样的美妙的事情:你可以几乎无限地负载均衡它们。换句话说,可以在 web 服务器上投入更多的硬件。当然,Python 可能会比其他语言要求更好的硬件资源,比如 c 语言。只是把硬件投入在 CPU 问题上。相比于你的时间,硬件就显得非常的便宜了。如果你在一年内节省了两周的生产力时间,那将远远多于所增加的硬件开销的回报。 * * * ![](https://cdn-images-1.medium.com/max/1000/0*mJFOcWsdEQq98gkF.jpg) -### 那么,Python是更快吗? +### 那么,Python 是更快吗? -这一次我一直在谈论最重要的是开发时间。所以问题依然存在:当就开发时间而言,Python要比其他语言更快吗?按常规惯例来看,我、[google][3][还有][4][其他][5][几个人][6]可以告诉你Python是多么的[高效][7]。它为你抽象出很多东西,帮助你关注那些你真正应该编写代码的地方,而不会被困在琐碎事情的杂草里,比如你是否应该使用一个向量或者一个数组。但你可能不喜欢别人的对Python说的些话,所以让我们来看一些更多的经验数据。 +这一次我一直在谈论最重要的是开发时间。所以问题依然存在:当就开发时间而言,Python 要比其他语言更快吗?按常规惯例来看,我、[google][3] [还有][4][其他][5][几个人][6]可以告诉你 Python 是多么的[高效][7]。它为你抽象出很多东西,帮助你关注那些你真正应该编写代码的地方,而不会被困在琐碎事情的杂草里,比如你是否应该使用一个向量或者一个数组。但你可能不喜欢只是听别人说的这些话,所以让我们来看一些更多的经验数据。 -在大多数情况下,关于python是否是更高效语言的争论可以归结为脚本语言(或动态语言)与静态类型语言两者的争论。我认为人们普遍接受的是静态类型语言的生产力较低,但是,[这里有一篇解释了为什么是这样的优秀的论文][8]。就Python而言,这里是一项研究中的给出的一个很好的总结][9],这项研究调查了用不同的语言编写对字符串处理的代码所需要花费的时间。 +在大多数情况下,关于 python 是否是更高效语言的争论可以归结为脚本语言(或动态语言)与静态类型语言两者的争论。我认为人们普遍接受的是静态类型语言的生产力较低,但是,[这有一篇优秀的论文][8]解释了为什么不是这样。就 Python 而言,这里有一项[研究][9],它调查了不同语言编写字符串处理的代码所需要花费的时间,供参考。 ![](https://cdn-images-1.medium.com/max/800/1*cw7Oq54ZflGZhlFglDka4Q.png) -在上述研究中,Python的效率比Java高出2倍。有一些其他研究也显示相似的东西。 Rosetta Code对编程语言的差异进行了[深入的研究][10]。在论文中,他们把python与其他脚本语言/解释性语言相比较,得出结论: +在上述研究中,Python 的效率比 Java 高出 2 倍。有一些其他研究也显示相似的东西。 Rosetta Code 对编程语言的差异进行了[深入的研究][10]。在论文中,他们把 python 与其他脚本语言/解释性语言相比较,得出结论: -> Python侧重于更简洁,甚至反对函数式语言(平均要短1.2到1.6倍) -> +> Python 更简洁,即使与函数式语言相比较(平均要短 1.2 到 1.6 倍) +>   -普遍的趋势似乎是Python中的代码行总是更少。代码行听起来可能像一个可怕的指标,但是包括上面已经提到到的两项研究在内的[多项研究][11]表明每种语言中每行代码所需要花费的时间大约是一样的。因此,通过限制代码行数提高生产效率。甚至codinghorror(一名C#程序员)他本人[写了一篇关于Python是如何更有效率的文章][12]。 +普遍的趋势似乎是 Python 中的代码行总是更少。代码行听起来可能像一个可怕的指标,但是包括上面已经提到的两项研究在内的[多项研究][11]表明,每种语言中每行代码所需要花费的时间大约是一样的。因此,限制代码行数就可以提高生产效率。甚至 codinghorror(一名 C# 程序员)本人[写了一篇关于 Python 是如何更有效率的文章][12]。 -我认为说Python比其他的很多语言更加的有效率是公正的。这主要是由于 Python 有大量的自带以及第三方库。[这里是一篇讨论Python和其他语言间的差异的简单的文章][13]。如果你不知道为何Python是如此的小巧和高效,我邀请你借此机会学习一点python,自己多实践。这儿是你的第一个程序: +我认为说 Python 比其他的很多语言更加的有效率是公正的。这主要是由于 Python 有大量的自带以及第三方库。[这里是一篇讨论 Python 和其他语言间的差异的简单的文章][13]。如果你不知道为何 Python 是如此的小巧和高效,我邀请你借此机会学习一点 python,自己多实践。这儿是你的第一个程序: _import __hello___ @@ -83,6 +83,7 @@ python 是慢,但是爷就喜欢它 -------------------------------------------------------------------------------- + via: https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 作者:[Nick Humrich ][a] From f7bf220dbc56a7a705dc596aff3797fcaf3069a3 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:13:44 +0800 Subject: [PATCH 20/25] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对中 --- translated/tech/20170406 Anbox - Android in a Box.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170406 Anbox - Android in a Box.md b/translated/tech/20170406 Anbox - Android in a Box.md index a206f29624..05ac1eeb9e 100644 --- a/translated/tech/20170406 Anbox - Android in a Box.md +++ b/translated/tech/20170406 Anbox - Android in a Box.md @@ -167,7 +167,7 @@ via: https://github.com/anbox/anbox/blob/master/README.md 作者:[ Anbox][a] 译者:[geekpi](https://github.com/geekpi) -校对:[校对者ID](https://github.com/校对者ID) +校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From 9b6d127691f1a9f41bd838d1057b690361c9bb7b Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:37:16 +0800 Subject: [PATCH 21/25] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 校对完毕 谢谢@geekpi --- .../tech/20170406 Anbox - Android in a Box.md | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/translated/tech/20170406 Anbox - Android in a Box.md b/translated/tech/20170406 Anbox - Android in a Box.md index 05ac1eeb9e..fac422a9ac 100644 --- a/translated/tech/20170406 Anbox - Android in a Box.md +++ b/translated/tech/20170406 Anbox - Android in a Box.md @@ -1,33 +1,33 @@ # Anbox -Anbox 是一个基于容器的方式来在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。 +Anbox 是一个基于容器的方式,在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。 ## 概述 -Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统并提供任何基于 GNU Linux 平台的 Android 程序。 +Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统,并提供任何基于 GNU Linux 平台的 Android 程序。 -容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于QEMU的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信并通过它发送所有硬件访问命令。 +容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于 QEMU 的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信,并通过它发送所有硬件访问命令。 有关更多详细信息,请参考下文档: * [Android 硬件 OpenGL ES 仿真设计概述](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/android-emugl/DESIGN) * [Android QEMU 快速管道](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMU-PIPE.TXT) - * [Android 的 "qemud" 复用守护进程](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) + * [Android 的 “qemud” 复用守护进程](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD.TXT) * [Android qemud 服务](https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-QEMUD-SERVICES.TXT) -Anbox 目前适合桌面使用,但也可使用移动操作系统,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于目前 Android 程序映射针对桌面环境,因此这还需要额外的工作来支持其他的用户界面。 +Anbox 目前适合桌面使用,但也可使用移动操作系统,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于 Android 程序映射目前只针对桌面环境,因此还需要额外的工作来支持其他的用户界面。 -Android 运行时环境带有一个基于[ Android 开源项目](https://source.android.com/)镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1 +Android 运行时环境带有一个基于[ Android 开源项目](https://source.android.com/)镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1。 ## 安装 -安装过程目前由几个需要添加其他组件到系统中的步骤组成。包括: +目前,安装过程包括一些添加额外组件到系统的步骤。包括: -  * 没有分发版内核同时启用的 binder 和 ashmen 原始内核模块 -  * 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限 -  * 能够启动 Anbox 会话管理器作为用户会话的一个启动任务 +  * 没有分发版内核同时启用的 binder 和 ashmen 原始内核模块。 +  * 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限。 +  * 能够启动 Anbox 会话管理器作为用户会话的一个启动任务。 -为了使这个过程尽可能简单,我们做了一个简单的步骤(见 https://snapcraft.io),称为 “anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。 +为了使这个过程尽可能简单,我们将必要的步骤绑定在一个 snap(见 https://snapcraft.io) 中,称为“anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。 ``` $ snap install --classic anbox-installer @@ -39,7 +39,7 @@ $ snap install --classic anbox-installer $ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer ``` -请注意,我们还不支持除本文列出的其他 Linux 发行版。请查看下面的章节了解支持的发行版。 +请注意,我们还不支持除所有 Linux 发行版。请查看下面的章节了解支持的发行版。 运行下面的命令进行安装。 @@ -47,11 +47,11 @@ $ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer. $ anbox-installer ``` -本篇会引导你完成安装过程。 +它会引导你完成安装过程。 -**注意:** Anbox 目前处于** pre-alpha 的开发状态**。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告他们! +**注意:** Anbox 目前处于** pre-alpha 开发状态**。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告它们! -**注意:** Anbox snap 目前 **完全没有约束**,这是因为它只能从前沿频道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。 +**注意:** Anbox snap 目前 **完全没有约束**,因此它只能从边缘渠道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。 ## 已支持的 Linux 发行版 @@ -69,7 +69,7 @@ $ anbox-installer ## 从源码构建 -要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你系统中只需要一点构建依赖: +要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你的主机系统中应已有下面这些构建依赖: * libdbus * google-mock @@ -112,14 +112,12 @@ $ cmake .. $ make ``` -一个简单的 +一个简单的命令会将必要的二进制安装到你的系统中,如下。 ``` $ make install ``` -会将必要的二进制安装到你的系统中。 - 如果你想要构建 anbox snap,你可以按照下面的步骤: ``` @@ -128,7 +126,7 @@ $ cp /path/to/android.img android-images/android.img $ snapcraft ``` -T结果是会有一个 .snap 文件,你可以在支持 snap 的系统上安装。 +结果会有一个 .snap 文件,你可以在支持 snap 的系统上安装。 ``` $ snap install --dangerous --devmode anbox_1_amd64.snap @@ -136,7 +134,7 @@ $ snap install --dangerous --devmode anbox_1_amd64.snap ## 运行 Anbox -要从本地构建运行 Anbox ,你需要了解更多一点。请参考["运行时步骤"](docs/runtime-setup.md)文档。 +要从本地构建运行 Anbox ,你需要了解更多一点。请参考[“运行时步骤”](docs/runtime-setup.md)文档。 ## 文档 @@ -157,7 +155,7 @@ $ snap install --dangerous --devmode anbox_1_amd64.snap ## 版权与许可 -Anbox 重用了像 Android QEMU 模拟器这样的其他项目。这些项目可在外部、带有许可声明的子目录中得到。 +Anbox 重用了像 Android QEMU 模拟器这样的其他项目的代码。这些项目可在外部/带有许可声明的子目录中得到。 anbox 源码本身,如果没有在相关源码中声明其他的许可,默认是 GPLv3 许可。 From cdb8f474d95d80db1b11a74fc1814af2a6642098 Mon Sep 17 00:00:00 2001 From: jasminepeng Date: Fri, 14 Apr 2017 17:39:04 +0800 Subject: [PATCH 22/25] =?UTF-8?q?=E6=A0=A1=E5=AF=B9=E5=AE=8C=E6=AF=95=20@z?= =?UTF-8?q?housiyu325?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 但是翻译没有完成,还请全部完成后再提交哦。谢谢。 --- translated/tech/20170403 Yes Python is Slow and I Dont Care.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md index cd5587f971..95f83385c3 100644 --- a/translated/tech/20170403 Yes Python is Slow and I Dont Care.md +++ b/translated/tech/20170403 Yes Python is Slow and I Dont Care.md @@ -87,7 +87,7 @@ python 是慢,但是爷就喜欢它 via: https://hackernoon.com/yes-python-is-slow-and-i-dont-care-13763980b5a1 作者:[Nick Humrich ][a] -译者:[译者ID](https://github.com/译者ID) +译者:[zhousiyu325](https://github.com/zhousiyu325) 校对:[jasminepeng](https://github.com/jasminepeng) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From ec4d4836f39b016defdeb0c36fb0b5794b8fb228 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 17:40:20 +0800 Subject: [PATCH 23/25] PRF:20170217 Understanding the difference between sudo and su.md @zhb127 --- ...ding the difference between sudo and su.md | 91 ++++++++----------- 1 file changed, 36 insertions(+), 55 deletions(-) diff --git a/translated/tech/20170217 Understanding the difference between sudo and su.md b/translated/tech/20170217 Understanding the difference between sudo and su.md index 5fc1672b00..b4bdb24757 100644 --- a/translated/tech/20170217 Understanding the difference between sudo and su.md +++ b/translated/tech/20170217 Understanding the difference between sudo and su.md @@ -1,38 +1,25 @@ -理解 sudo 与 su 之间的区别 +深入理解 sudo 与 su 之间的区别 ============================================================ -### 本文导航 - -1. [Linux su 命令][7] - 1. [su -][1] - 2. [su -c][2] -2. [Sudo vs Su][8] -2. [Sudo vs Su][8] - 1. [关于密码][3] - 2. [默认行为][4] - 3. [日志记录][5] - 4. [灵活性][6] -3. [Sudo su][9] - -在[早前的一篇文章][11]中,我们深入讨论了 `sudo` 命令的相关内容。同时,在该文章的末尾有提到相关的命令 `su` 的部分内容。本文,我们将详细讨论关于 su 命令与 sudo 命令之间的区别。 +在[早前的一篇文章][11]中,我们深入讨论了 `sudo` 命令的相关内容。同时,在该文章的末尾有提到相关的命令 `su` 的部分内容。本文,我们将详细讨论关于 `su` 命令与 `sudo` 命令之间的区别。 在开始之前有必要说明一下,文中所涉及到的示例教程都已经在 Ubuntu 14.04 LTS 上测试通过。 ### Linux su 命令 -su 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户。换句话说,这个工具可以让你在不登出当前用户的情况下登录另外一个用户(以该用户的身份)。 +`su` 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户。换句话说,这个工具可以让你在不登出当前用户的情况下登录为另外一个用户。 -su 命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。 +`su` 命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。 -如何使用 su 命令切换到 root 用户,如下: +如何使用 `su` 命令切换到 root 用户,如下: [ ![不带命令行参数的 su 命令](https://www.howtoforge.com/images/sudo-vs-su/su-command.png) ][12] -如上,su 命令要求输入的密码是 root 用户密码。所以,一般 su 命令需要输入目标用户的密码。在输入正确的密码之后,su 命令会在终端的当前会话中打开一个子会话。 +如上,`su` 命令要求输入的密码是 root 用户的密码。所以,一般 `su` 命令需要输入目标用户的密码。在输入正确的密码之后,`su` 命令会在终端的当前会话中打开一个子会话。 -### su - +#### su - 还有一种方法可以切换到 root 用户:运行 `su -` 命令,如下: @@ -40,41 +27,36 @@ su 命令经常被用于切换到超级用户或 root 用户(因为在命令 ![su - 命令](https://www.howtoforge.com/images/sudo-vs-su/su-hyphen-command.png) ][13] -那么,`su` 命令与 `su -` 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持旧的或原始用户的环境,而后者则是创建一个新的环境(由 root 用户 ~/.bashrc 文件所设置的环境),相当于使用 root 用户正常登录(从登录屏幕显示登录)。 +那么,`su` 命令与 `su -` 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持旧的(或者说原始用户的)环境,而后者则是创建一个新的环境(由 root 用户 `~/.bashrc` 文件所设置的环境),相当于使用 root 用户正常登录(从登录屏幕登录)。 `su` 命令手册页很清楚地说明了这一点: -``` -可选参数 `-` 可提供的环境为用户在直接登录时的环境。 -``` +> 可选参数 `-` 可提供的环境为用户在直接登录时的环境。 -因此,你会觉得使用 `su -` 登录更有意义。但是,同时存在 `su` 命令,那么大家可能会想知道它在什么时候用到。以下内容摘自[ArchLinux wiki website][14] - 关于 `su` 命令的好处和坏处: +因此,你会觉得使用 `su -` 登录更有意义。但是, `su` 命令也是有用的,那么大家可能会想知道它在什么时候用到。以下内容摘自 [ArchLinux wiki 网站][14] - 关于 `su` 命令的好处和坏处: -* 有的时候,对于系统管理员来讲,使用其他普通用户的 Shell 账户而不是自己的 Shell 账户更会好一些。尤其是在处理用户问题时,最有效的方法就是是:登录目标用户以便重现以及调试问题。 +* 有的时候,对于系统管理员(root)来讲,使用其他普通用户的 Shell 账户而不是自己的 root Shell 账户更会好一些。尤其是在处理用户问题时,最有效的方法就是是:登录目标用户以便重现以及调试问题。 +* 然而,在多数情况下,当从普通用户切换到 root 用户进行操作时,如果还使用普通用户的环境变量的话,那是不可取甚至是危险的操作。因为是在无意间切换使用普通用户的环境,所以当使用 root 用户进行程序安装或系统更改时,会产生与正常使用 root 用户进行操作时不相符的结果。例如,以普通用户安装程序会给普通用户意外损坏系统或获取对某些数据的未授权访问的能力。 -* 然而,在多数情况下,当从普通用户切换到 root 用户进行操作时,如果还使用普通用户的环境变量的话,那是不可取甚至是危险的操作。因为是在无意间切换使用普通用户的环境,所以当使用 root 用户进行程序安装或系统更改时,会产生与正常使用 root 用户进行操作时不相符的结果。例如,可以给普通用户安装电源意外损坏系统的程序或获取对某些数据的未授权访问的程序。 +注意:如果你想在 `su -` 命令的 `-` 后面传递更多的参数,那么你必须使用 `su -l` 而不是 `su -`。以下是 `-` 和 `-l` 命令行选项的说明: -注意:如果你想在 `su -` 命令后面传递更多的参数,那么你必须使用 `su -l` 来实现。以下是 `-` 和 `-l` 命令行选项的说明: +> `-`, `-l`, `--login` -``` --, -l, --login -提供相当于用户在直接登录时所期望的环境。 +> 提供相当于用户在直接登录时所期望的环境。 -当使用 - 时,必须放在 su 命令的最后一个选项。其他选项(-l 和 --login)无此限制。 -``` +> 当使用 - 时,必须放在 `su` 命令的最后一个选项。其他选项(`-l` 和 `--login`)无此限制。 -### su -c +#### su -c 还有一个值得一提的 `su` 命令行选项为:`-c`。该选项允许你提供在切换到目标用户之后要运行的命令。 `su` 命令手册页是这样说明: -``` --c, --command COMMAND -使用 -c 选项指定由 Shell 调用的命令。 +> `-c`, `--command COMMAND` -被执行的命令无法控制终端。所以,此选项不能用于执行需要控制 TTY 的交互式程序。 -``` +> 使用 `-c` 选项指定由 Shell 调用的命令。 + +> 被执行的命令无法控制终端。所以,此选项不能用于执行需要控制 TTY 的交互式程序。 参考示例: @@ -90,11 +72,11 @@ su [target-user] -c [command-to-run] 示例中的 `shell` 类型将会被目标用户在 `/etc/passwd` 文件中定义的登录 shell 类型所替代。 -### Sudo vs Su +### sudo vs. su 现在,我们已经讨论了关于 `su` 命令的基础知识,是时候来探讨一下 `sudo` 和 `su` 命令之间的区别了。 -### 关于密码 +#### 关于密码 两个命令的最大区别是:`sudo` 命令需要输入当前用户的密码,`su` 命令需要输入 root 用户的密码。 @@ -102,28 +84,27 @@ su [target-user] -c [command-to-run] 此外,如果要撤销特定用户的超级用户/root 用户的访问权限,唯一的办法就是更改 root 密码,然后再告知所有其他用户新的 root 密码。 -而使用 `sudo` 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 `sudo` 命令要求输入的是其他用户的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 `sudoers` 文件中的相应配置即可。 +而使用 `sudo` 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 `sudo` 命令要求输入的是其他用户自己的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 `sudoers` 文件中的相应配置即可。 -### 默认行为 +#### 默认行为 -两个命令之间的另外一个区别是默认行为。`sudo` 命令只允许使用提升的权限运行单个命令,而 `su` 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到显示退出登录。 +两个命令之间的另外一个区别是其默认行为。`sudo` 命令只允许使用提升的权限运行单个命令,而 `su` 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。 -因此,`su` 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 `rm -rf` 命令)。关于为什么不鼓励以 root 用户身份进行工作的详细内容,请参考[这里][10] +因此,`su` 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 `rm -rf` 命令!)。关于为什么不鼓励以 root 用户身份进行工作的详细内容,请参考[这里][10]。 -### 日志记录 +#### 日志记录 -尽管 `sudo` 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是他们会使用 sudoer 所配置的用户名来记录是谁执行命令。而 `su` 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。 +尽管 `sudo` 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是它们会使用 `sudoer` 所配置的用户名来记录是谁执行命令。而 `su` 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。 -### 灵活性 +#### 灵活性 -`sudo` 命令会比 `su` 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 `sudo` 命令只能访问他们工作需要的命令。而 `su` 命令让用户有权限做任何事情。 +`sudo` 命令比 `su` 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 `sudo` 命令只能访问他们工作需要的命令。而 `su` 命令让用户有权限做任何事情。 -### Sudo su +#### sudo su 大概是因为使用 `su` 命令或直接以 root 用户身份登录有风险,所以,一些 Linux 发行版(如 Ubuntu)默认禁用 root 用户帐户。鼓励用户在需要 root 权限时使用 `sudo` 命令。 -However, you can still do 'su' successfully, i.e, without entering the root password. All you need to do is to run the following command: -然而,您还是可以成功执行 `su` 命令,即不用输入 root 用户的密码。运行以下命令: +然而,您还是可以成功执行 `su` 命令,而不用输入 root 用户的密码。运行以下命令: ``` sudo su @@ -131,7 +112,7 @@ sudo su 由于你使用 `sudo` 运行命令,你只需要输入当前用户的密码。所以,一旦完成操作,`su` 命令将会以 root 用户身份运行,这意味着它不会再要求输入任何密码。 -** PS **:如果你想在系统中启用 root 用户帐户(虽然强烈反对,但你还是可以使用 `sudo` 命令或 `sudo su` 命令),你必须手动设置 root 用户密码 可以使用以下命令: +**PS**:如果你想在系统中启用 root 用户帐户(强烈反对,因为你可以使用 `sudo` 命令或 `sudo su` 命令),你必须手动设置 root 用户密码,可以使用以下命令: ``` sudo passwd root @@ -139,7 +120,7 @@ sudo passwd root ### 结论 -这篇文章以及之前的教程(其中侧重于 `sudo` 命令)应该能给你一个比较好的建议,当你需要可用的工具来提升(或一组完全不同的)权限来执行任务时。 如果您也想分享关于 `su` 或 `sudo` 的相关内容或者经验,欢迎您在下方进行评论。 +当你需要可用的工具来提升(或一组完全不同的)权限来执行任务时,这篇文章以及之前的教程(其中侧重于 `sudo` 命令)应该能给你一个比较好的建议。 如果您也想分享关于 `su` 或 `sudo` 的相关内容或者经验,欢迎您在下方进行评论。 -------------------------------------------------------------------------------- @@ -147,7 +128,7 @@ via: https://www.howtoforge.com/tutorial/sudo-vs-su/ 作者:[Himanshu Arora][a] 译者:[zhb127](https://github.com/zhb127) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From b8e2479c6f23520b3290d044327317506165b7e4 Mon Sep 17 00:00:00 2001 From: wxy Date: Fri, 14 Apr 2017 17:40:42 +0800 Subject: [PATCH 24/25] PUB:20170217 Understanding the difference between sudo and su.md @zhb127 --- .../20170217 Understanding the difference between sudo and su.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {translated/tech => published}/20170217 Understanding the difference between sudo and su.md (100%) diff --git a/translated/tech/20170217 Understanding the difference between sudo and su.md b/published/20170217 Understanding the difference between sudo and su.md similarity index 100% rename from translated/tech/20170217 Understanding the difference between sudo and su.md rename to published/20170217 Understanding the difference between sudo and su.md From 89b43f0059dab89d47f5e5c8008998733a4b6f68 Mon Sep 17 00:00:00 2001 From: ictlyh Date: Fri, 14 Apr 2017 22:00:11 +0800 Subject: [PATCH 25/25] Translating 2 posts --- ...all Jenkins Automation Server with Apache on Ubuntu 16.04.md | 2 +- ...0170319 How to Add a New Disk to an Existing Linux Server.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md b/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md index abe2cbcc40..c1f983a017 100644 --- a/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md +++ b/sources/tech/20161125 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04.md @@ -1,4 +1,4 @@ -willcoderwang 翻译中 +ictlyh 接手 willcoderwang 翻译 How to Install Jenkins Automation Server with Apache on Ubuntu 16.04 ============================================================ diff --git a/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md index c4d32941bc..699fc42b8c 100644 --- a/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md +++ b/sources/tech/20170319 How to Add a New Disk to an Existing Linux Server.md @@ -1,3 +1,4 @@ +ictlyh Translating How to Add a New Disk to an Existing Linux Server ============================================================