19 7月

Swift 2.0中的错误处理

文 / Juan Pablo Claude:来自智利首都圣地亚哥,毕业于美国北卡罗莱纳大学教堂山分校(University of North Carolina at Chapel Hill),获化学博士学位,后入阿拉巴马大学伯明翰分校(University of Alabama at Birmingham)任教。2005年底作为Cocoa和Django框架程序开发人员加入Big Nerd Ranch。此前,有过DOS环境下C编程,Windows环境下使用C++编写数据分析应用程序的经历。

原文链接:https://www.bignerdranch.com/blog/error-handling-in-swift-2/

苹果公司在今年的全球开发者大会(Worldwide Developers Conference, WWDC)上宣布推出Swift2.0,该语言的首席架构师Chris Lattner表示,Swift2.0主要在语言基本语法、安全性和格式美观度这三方面进行了改进。除了这些新的功能特性,还有对语法的优化、修饰及美化,最后是Swift 1.x中最具影响力的错误处理机制。

这是因为你根本无法回避它。如果打算使用Swift 2.0的话,必须接受错误处理这样的机制,并且错误处理机制将改变Cocoa和Cocoa Touch框架中使用NSError与方法交互的方式。

历史一瞬:不起眼的开端

我们都知道,Swift语言作为Objective-C当前替代语言被推出,是OS X和iOS应用程序开发的“通用语”。在最初的版本中,Objective-C没有原生的异常处理机制。后来通过添加NSException类,还有 NS_DURING, NS_HANDLER和 NS_ENDHANDLER宏才有了异常处理。这种方案现在被称为“经典的异常处理”,还有这些宏都是基于setjmp()和longjmp()这两个C语言函数的。

异常捕获(exception-catching)看起来如下图所示,在NS_DURING和NS_HANDLER宏之间抛出的任何异常都将会导致在NS_HANDLER和NS_ENDHANDLER宏之间执行相应的代码。

  1. NS_DURING
  2.     // Call a dangerous method or function that raises an exception:
  3.     [obj someRiskyMethod];
  4. NS_HANDLER
  5.     NSLog(@“Oh no!”);
  6.     [anotherObj makeItRight];
  7. NS_ENDHANDLER

下面是立刻能触发抛出异常的方法(现在仍然可用):

  1. – (void)someRiskyMethod
  2. {
  3.     [NSException raise:@“Kablam”
  4.                 format:@“This method is not implemented yet. Do not call!”];
  5. }

可以想象,这种手工处理异常的方式戏弄的是早期Cocoa框架程序开发人员。但是这些程序员还不至于到这份儿上,因为他们很少使用这种方式。无论在Cocoa还是Cocoa Touch框架下,异常通常都被归为灾难性的,不可恢复的错误,比如程序员造成的错误。上面的-someRiskyMethod就是很好的例子,由于实现部分没有准备好而引发了异常。在Cocoa和Cocoa Touch框架中,可恢复的错误由稍后讨论的NSError类来处理。

原生的异常处理

我想由于Objective-C中的经典异常处理机制对应的手工处理方式让人感觉闹心,于是苹果公司在Mac OS X 10.3(2003年10月)中发布了原生的异常处理机制,彼时还没有iOS系统。这本质上是将C++的异常处理嫁接到了Objective-C。异常处理的结构目前看起来是这样的:

  1. @try {
  2.     [obj someRiskyMethod];
  3. }
  4. @catch (SomeClass *exception) {
  5.     // Handle the error.
  6.     // Can use the exception object to gather information.
  7. }
  8. @catch (SomeOtherClass *exception) {
  9.     // …
  10. }
  11. @catch (id allTheRest) {
  12.     // …
  13. }
  14. @finally {
  15.     // Code that is executed whether an exception is thrown or not.
  16.     // Use for cleanup.
  17. }

原生的异常处理使你有机会为每个异常类型指定不同@catch部分。无论@try结果如何,@finally都要执行其对应的代码。

尽管原生的异常处理如所预期的那样抛出一个NSException异常,但是最明确的方法还是“@throw <expression>;”语句。通常你抛出的是NSException实例,但说不定什么对象会被抛出。

NSError

尽管Objective-C原生与经典的异常处理有许多优点,但Cocoa和Cocoa Touch框架应用程序开发人员仍然很少使用异常,而是限制程序出现程序员所导致的不可恢复的错误。使用NSError类处理可恢复的错误,这种方法早于使用异常处理。Swift 1.x也继承了NSError的样式。

在Swift 1.x中,Cocoa和Cocoa Touch的方法和函数可能不会返回一个布尔类型的false或者nil来表示一个失败(failure)的对象。另外,NSErrorPointer对象会被当作一个参数返回特定的失败信息。下面是个典型的例子:

  1. // A local variable to store an error object if one comes back:
  2. var error: NSError?
  3. // success is a Bool:
  4. let success = someString.writeToURL(someURL,
  5.                                     atomically: true,
  6.                                     encoding: NSUTF8StringEncoding,
  7.                                     error: &error)
  8. if !success {
  9.     // Log information about the error:
  10.     println(“Error writing to URL: \(error!)”)
  11. }

程序员所导致的错误可以用Swift标准库(Swift Standard Library)函数fatalError(“Error message”)来标记,将其在控制台记录为错误消息并无条件中止执行。还可以使用assert(), assertionFailure(), precondition()和preconditionFailure()这些函数。

Swift第一次发布时,一些非苹果平台开发人员已经准备好了火把和干草叉。他们声称Swift不能算是“真正的语言”,因为它缺乏异常处理。但是,Cocoa和Cocoa Touch社区对此不予理睬,我们知道NSError和NSException那个时候就存在了。就我个人而言,我相信苹果公司仍然在思考实现错误和异常处理的正确方式。我还认为直到问题解决了,苹果公司才会公开Swift源码。这一切问题在Swift 2.0中全被扫清了。

Swift 2.0中的错误处理

在Swift 2.0中,如果想要抛出错误,那么抛出的对象必须符合ErrorType协议。可能正如你所愿,NSError就符合该协议。枚举在这里用来给错误进行分类。

  1. enum AwfulError: ErrorType {
  2.     case Bad
  3.     case Worse
  4.     case Terrible
  5. }

然后如果一个可能抛出一个或多个错误的函数或方法会被抛出关键字标记:

  1. func doDangerousStuff() throws -> SomeObject {
  2.     // If something bad happens throw the error:
  3.     throw AwfulError.Bad
  4.     // If something worse happens, throw another error: 
  5.     throw AwfulError.Worse
  6.     // If something terrible happens, you know what to do: 
  7.     throw AwfulError.Terrible
  8.     // If you made it here, you can return:
  9.     return SomeObject()
  10. }

为了捕获错误,新型的do-catch语句出现了:

  1. do {
  2.     let theResult = try obj.doDangerousStuff()
  3. }
  4. catch AwfulError.Bad {
  5.     // Deal with badness.
  6. }
  7. catch AwfulError.Worse {
  8.     // Deal with worseness.
  9. }
  10. catch AwfulError.Terrible {
  11.     // Deal with terribleness.
  12. }
  13. catch ErrorType {
  14.     // Unexpected error!
  15. }

这个do-catch语句和switch语句有一些相似之处,被捕获的错误详尽无遗,因此你可以使用这种样式来捕获抛出的错误。还要注意关键字try的使用。它是为了明确地标示抛出的代码行,因此当阅读代码的时候,你能够立刻找到错误在哪里。

关键字try的的变体是“try!”。这个关键字大概也适用于那些程序员导致的错误。如果使用“try!”标记一个被调用的抛出对象中的方法,你等于告诉编译器这个错误永远不会发生,并且你也不需要捕获它。如果该语句本身产生了错误(error),应用程序会停止执行,那么你就要开始调试了。

  1. let theResult = try! obj.doDangerousStuff()

与Cocoa和Cocoa Touch框架间的交互

现在的问题是,你如何在Swift 2.0中处理爷爷级的NSError API呢?苹果公司已经Swift 2.0中为统一代码行为作了大量工作,并且已经为未来写入Swift的框架准备方法。Cocoa和Cocoa Touch中可以产生NSError实例的方法和函数有苹果公司的签名( signature),可以自动转换为Swift新的错误处理方式。

例如,这个NSString的构造器( initializer)在Swift 1.x中就有以下签名:

  1. convenience init?(contentsOfFile path: String,
  2.                   encoding enc: UInt,
  3.                   error error: NSErrorPointer)

Swift 2.0中,签名被转换成:

  1. convenience init(contentsOfFile path: String,
  2.                  encoding enc: UInt) throws

注意:在Swift 2.0中,构造器不再被标记为failable,它并不需要NSErrorPointer来做参数,而是使用抛出异常的方式显式地指示潜在的失败。

下面的例子使用了这种新的签名:

  1. do {
  2.     let str = try NSString(contentsOfFile: “Foo.bar”,
  3.                            encoding: NSUTF8StringEncoding)
  4. }
  5. catch let error as NSError {
  6.     print(error.localizedDescription)
  7. }

注意错误是如何被捕获的,并且如何被转换成了一个NSError实例,这样你就可以获取与其相似API的信息了。事实上,任何ErrorType类型的实例都可以转换成NSError类型。

最后说说@finally

细心的读者可能已经注意到,Swift 2.0引入了一个新的do-catch语句,而不是do-catch-finally。不管是否捕捉到错误的情况下,你如何指定必须运行的代码呢?为此,现在可以使用defer语句,用来推迟代码块的执行直到当前的作用域结束。

  1. // Some scope:
  2. {
  3.     // Get some resource.
  4.     defer {
  5.         // Release resource.
  6.     }
  7.     // Do things with the resource.
  8.     // Possibly return early if an error occurs.
  9. // Deferred code is executed at the end of the scope.

Swift 2.0将Cocoa和Cocoa Touch的错误处理机制凝聚为具有现代风格的用法,这是一项伟大的工作,也会使许多程序员倍感亲切。统一行为是不错的定位,会使Swift语言和其所继承的框架逐步发展。

http://www.csdn.net/article/2015-07-01/2825095/2

17 6月

Swift语言那些鲜为人知的特性

文 / Russ Bishop:全能型程序员,使用C#,Objective-C和Swift语言编程,开发了奇特的应用Storm Sim Free。

原文链接:http://www.russbishop.net/more-swift-attributes

Swift语言有各种各样缺乏(或没有)文档记录的特性(attribute)放在那里等着被使用。让我们一起看看其中的一些特性:

@inline

这个特性为编译器提供了内联提示。有效的取值是__always和never。除非我认为必须要用这两个值,否则就不会使用它(特别是__always)。到目前为止与其相关的规则还不是很明确,在有限的测试下,它可以正常地工作,但还要视具体情况而定。

进一步的解释:尽管底层虚拟机(Low Level Virtual Machine, LLVM)有强制内联的概念,但我们目前还不知道这个@inline特性是否与其直接映射,也不知道是否存在大小方面的限制,但这将会导致编译器忽略这一点而跳过内联。理论上说应该是这样的,但我不保证一定是。

注意(当优化设置关闭时)在调试模式下的构建将忽略@inline。

@transparent

我最初并未将这个特性列出来。该特性会导致编译器在管道(pipeline)中更早地将函数内联。它用于“像+(Int, Int)这样非常原始的函数”,而“不应该用于独立函数”

甚至在没有优化设置的调试模式下@transparent特性函数就会被内联,所以在调用“1+1”这样的函数的时候并不会特别慢。另外这个特性与@inline(__always)非常类似。

@availability

这个特性可以用来标识某些函数只在某些平台或版本上可用。第一个参数是平台,可以用星号(*)代表一切可用,还可以是iOS或OSX。因为如果需要针对不同的平台,就要指定多个@availability属性。

如果需要表示该函数在某个给定的平台完全不可用时,可以将第二个参数置为unavailable。此外,还可以用introduced,deprecated和obsoleted来指定一个或是多个版本的组合:obsoleted意味着该项已经删除,deprecated仅仅表示如果使用就会给予警告。最后你可以设置message的值,如果该项被使用了就由编译器输出。下面是一些例子:

  1. @availability(*, unavailable)
  2. func foo() {}
  3. @availability(iOS, unavailable, message=“you can’t call this”)
  4. func foo2() {}
  5. @availability(OSX, introduced=10.4, deprecated=10.6, obsoleted=10.10)
  6. @availability(iOS, introduced=5.0, deprecated=7.0)
  7. func foo3() {}

@noreturn

正如该特性所描述的那样:编译器可以假定这个函数是一个永远循环运行的起点,例如while true { },或者假定是函数abort或者exit进程的情况。

评论者Marco Masser指出,如果调用另一个被标志为@noreturn的函数,那么编译器会忽略掉当前函数中缺失的返回值(missing return values),因为编译器理解程序的控制流。

@asmname

该属性给出了函数、方法或属性实现的符号名称。如果你已经知道对应的函数参数及其类型,那么就可以直接调用Swift的内部标准库函数,甚至不用头文件,也可以方便地调用C语言编写的函数:

  1. @asmname(“function”) func f()

@unsafe_no_objc_tagged_pointer

上面这个仍然是个谜,但我猜测它是在告诉Swift与Objective-C联系的时候不要使用tagged pointer

@semantics

这又是另一个谜。参数看起来像是array.mutate_unknown或array.init这样的字符串数组。想必这是要告诉编译器(或静态分析器)函数是如何工作的。

结论

谁还需要乏味老套的 @objc和@autoclosure呢?还是算了吧!

我今年会去参加苹果全球开发者大会(WWDC),你也一定要去呀!

http://www.csdn.net/article/2015-06-08/2824887-more-swift-attributes

09 6月

ARC中retain cycle揭秘

文 / Ignacio Nieto Carvajal:自由开发者,精通iOS和Mac OSX应用程序开发,还包括Web服务和UX/UI设计。

原文链接:http://digitalleaves.com/blog/2015/05/demystifying-retain-cycles-in-arc/

ARC中的retain cycle就像日本B级恐怖电影一样。开始使用Cocoa或Cocoa Touch做开发时,你甚至不会在意它的存在。直到有一天应用程序由于内存泄漏而出现了崩溃现象,你才意识到它们的存在,看到像幽灵一样的retain cycle无处不在。随着岁月流逝,你学会适应它们,发现它们,避免它们……但最终恐慌还在,无孔不入。

包括我在内,对于许多开发人员来说,ARC的最令人失望之处莫过于苹果公司让ARC来管理内存。不幸的是ARC没有循环引用检测器,因此很容易出现retain cycle现象,从而迫使开发人员在编码时要采取特殊的预防措施。

对于iOS开发人员来说,retain cycle是个难点。在网上有很多误导信息[1][2],人们所给出的这些错误信息和修复方法甚至会导致应用出现新的问题,甚至崩溃掉,基于这样的情况,本文中我会阐明主题,给读者一些启发。

相关理论一瞥

Cocoa框架内存管理可以追溯到MRR(Manual Retain Release),在MRR中,开发人员在创建对象的时候,要为每个内存中的对象声明所有权。并且,当不再需要该对象时,要放弃所有权。MRR通过引用计数系统来实现这种所有权机制。每个对象都被分配一个计数器指示被“拥有”了多少次,每次加一,释放对象的时候每次减一。当引用计数变成零的时候,该对象将不复存在。对于开发人员来说,不得不手动维护引用计数真的是很烦人的事情,于是苹果公司引入了自动引用计数(Automated Reference Counting, ARC)机制,免得开发人员手动添加保留(retain)和释放(release)指令,让他们专注于解决应用程序的问题。在ARC环境下,开发人员要将一个变量定义为“strong”或“weak”。使用weak的话应用程序中被声明的对象不会被retain,而使用strong声明的对象将会被retain,并且其引用计数加一。

为什么要在乎?

ARC的问题在于容易导致retain cycle,它发生在两个不同的对象间彼此包含强引用的时候。试想一个Book对象包含一系列的Page对象,每个Page对象有个属性指向该页所在的这本书。当你释放掉指向Book和Page的变量时,Book和Page之间还存在着强引用。因此,即使没有变量指向Book和Page了,Book和Page及其所占用的内存也不会被释放掉。

不幸之处在于并非所有retain cycle都很容易被发现。对象之间的传递关系(A引用B,B转而引用C,C引用A)会导致retain cycle。更糟糕的是Objective-C里的块(block)和Swift里的闭包(closure)都被认为是独立的内存对象。因此,任何在块或闭包内对像的引用都将会对其变量做retain操作。因此,如果对象仍然retain这个块的话,就会导致潜在的retain cycle发生。

retain cycle可以成为应用程序潜在的危害,导致内存消耗过高,性能低下和崩溃。但还没有来自于苹果公司的文档,针对retain cycle可能发生的不同场景,以及如何避免进行描述。这导致了一些误解并形成了不良的编程习惯。

用例场景

那么闲话少说,我们一起来分析一些场景,确定它们是否会导致retain cycle以及如何避免:

父子对象关系

这是retain cycle的典型例子。不幸的是这也是苹果公司唯一给出相关解决方案文档的例子。就是我上面描述的Book和Page对象的例子。这种情况的典型解决方案是把Child类里面的代表父类的变量定义成weak,这样就可以避免retain cycle。

  1. class Parent {
  2.    var name: String
  3.    var child: Child?
  4.    init(name: String) {
  5.       self.name = name
  6.    }
  7. }
  8. class Child {
  9.    var name: String
  10.    weak var parent: Parent!
  11.    init(name: String, parent: Parent) {
  12.       self.name = name
  13.       self.parent = parent
  14.    }
  15. }

在Swift语言中,代表父类的变量是个弱变量的事实迫使我们将其定义为可选类型。不使用可选类型的另一种做法是将父类型对象声明为“unowned”(意味着我们不会对变量声明进行内存管理或声明所有权)。然而在这种情况下,我们必须非常仔细地确保只有一个Child实例指向Parent,Parent就不能是nil,否则程序就会崩溃:

  1. class Parent {
  2.    var name: String
  3.    var child: Child?
  4.    init(name: String) {
  5.       self.name = name
  6.    }
  7. }
  8. class Child {
  9.    var name: String
  10.    unowned var parent: Parent
  11.    init(name: String, parent: Parent) {
  12.       self.name = name
  13.       self.parent = parent
  14.    }
  15. }
  16. var parent: Parent! = Parent(name: “John”)
  17. var child: Child! = Child(name: “Alan”, parent: parent)
  18. parent = nil
  19. child.parent <== possible crash here!

一般来说公认的做法是父对象必须拥有(强引用)其子对象,这些子对象对其父对象应该只保持一个弱引用。这同样适用于集合,集合必须拥有其所包含的对象。

包含在实例变量中的块和闭包

另一个经典的例子虽然不是那么直观,但正如我们之前所说的那样,闭包和块是独立的内存对象,并retain了它们所引用的对象。因此如果我们有一个包含闭包变量的类,这个变量又恰好引用了其所拥有对象的属性或方法,由于闭包通过创建一个强引用而“捕获”了自己,就会有retain cycle发生。

  1. class MyClass {
  2.    lazy var myClosureVar = {
  3.       self.doSomething()
  4.    }
  5. }

这种情况下的解决方法是将自身定义成“weak”版本,并且将此弱引用赋给闭包或块。在Objective-C语言中,要定义个新的变量:

 

  1. – (id) init() {
  2.    __weak MyClass * weakSelf = self;
  3.    self.myClosureVar = ^{
  4.       [weakSelf doSomething];
  5.    }
  6. }

而在Swift语言中,我们只需要指定“[weak self] in”作为闭包的启动参数:

  1. var myClosureVar = {
  2.    [weak self] in
  3.    self?.doSomething()
  4. }

这样一来,当闭包快执行完毕时,self变量不会被强制retain,因此会得到释放,打破循环。注意,当声明为weak时,self在闭包内是如何变成可选类型的。

GCD中的dispatch_async

与一贯的认识相反,dispatch_async本身并不会导致retain cycle。

  1. dispatch_async(queue, { () -> Void in
  2.    self.doSomething();
  3. });

在这里,闭包对self强引用,但是类(self)的实例对闭包没有任何强引用,因此一旦闭包结束,它将被释放,也不会有环出现,然而,有的时候会被(错误地)认为这种情况会导致retain cycle。一些开发人员甚至一针见血地指出将块或闭包内所有对“self”的引用都声明为weak:

  1. dispatch_async(queue, {
  2.    [weak self] in
  3.    self?.doSomething()
  4. })

在我看来,对每种情况都这样做并不是好的做法。我们假设某个对象启动了一个长时间的后台任务(比如从网络上下载一些东西),然后调用了一个“self”方法。如果对self传递一个弱引用的话,那么类会在闭包结束之前完成它的生命周期。因此,当调用 doSomething()的时候,类的实例已经不存在了,所以这个方法永远不会被执行。这种情况下,(苹果公司)建议的解决方案是对闭包内的弱引用(???)声明一个强引用:

  1. dispatch_async(queue, {
  2.    [weak self] in
  3.    if let strongSelf = self {
  4.       strongSelf.doSomething()
  5.    }
  6. })

我不仅发现语法冗长单调,缺乏直观性,甚至令人感到厌恶,而且使闭包作为独立的处理实体的打算也落空了。我认为要理解对象的生命周期,确切地明白什么时候应该为实例声明一个内部的weak版,还要知道对象存续期间会有哪些影响。但话又说回来,这正是我解决应用程序的问题时分散我注意力的地方,如果Cocoa框架中没有使用ARC的话,这些都是没有必要写的代码。

局部的闭包和块

没有引用或包含任何实例或类变量的函数局部闭包和块本身不会导致retain cycle。常见的例子就是UIView的animateWithDuration方法:

  1. func myMethod() {
  2.    …
  3.    UIView.animateWithDuration(0.5, animations: { () -> Void in
  4.       self.someOutlet.alpha = 1.0
  5.       self.someMethod()
  6.    })
  7. }

对于dispatch_async和其他GCD相关的方法,我们不用担心没有被类实例强引用的局部闭包和块,它们不会发生retain cycle。

代理方案

代理(delegation)是使用弱引用避免retain cycle的一个典型场景。将委托声明为weak一直是一种不错的做法(并且还算安全)。在Objective-C中:

  1. @property (nonatomic, weak) id <MyCustomDelegate> delegate;

Swift中:

  1. weak var delegate: MyCustomDelegate?

在大多数情况下,对象的代理实例化了该对象,或者被认为比对象存在的时间更长久(并且对代理方法做出反应)。因此,在一个设计得很好的类中,我们不会找到与对象声明周期相关的任何问题。

使用Instruments来调试retain cycle

不管我如何努力避免retain cycle,忘记去引入一个弱引用并意外地创建一个(多谢ARC!)这样的事情迟早还有发生。幸运的是XCode套件中的Instruments应用程序是很不错的工具,用于检测和定位retain cycle。一旦开发阶段结束,在提交苹果商店之前就分析(profile)你的应用是个不错的习惯。Instruments有很多模版用来分析应用的不同方面,但我们感兴趣的是“Leaks”选项。

一旦打开Instruments,你就应该启动应用程序并作一些交互操作,特别是在要测试的区域或试图控制器上。任何检测到的泄漏都将会在“Leaks”部分出现一条红线。辅助视图包含一个区域,Instruments用来显示发生泄漏处的堆栈追踪,用来找到问题所在,甚至使你可以直接定位到造成问题的代码。

http://www.csdn.net/article/2015-05-27/2824782-demystifying-retain-cycles-in-arc

15 5月

对近期AFNetworking安全漏洞引发担忧的回应

文 / Alamofire Software Foundation(由Mattt Thompson创立)

Mattt Thompson:毕业于卡内基·梅隆大学(Carnegie Mellon University),获哲学及语言学学士学位。著名的iOS网络通信类库AFNetworking的作者,此外,他还开发了Postgres.app、ASCIIwwdc和Nomad等热门开源项目。

原文链接:https://gist.github.com/AlamofireSoftwareFoundation/f784f18f949b95ab733a

前一段时间,大量关于AFNetworking存在安全漏洞的消息被公之于众,大约1000种应用程序被指称,由于SSL存在Bug,导致这些应用程序容易遭到攻击。这些文章对此存在一些错误的,带有误导性的说法。

我们对此做出回应来澄清和纠正这些说法。

背景信息

就此事,对于那些不熟悉AFNetworking的人,这里有一些与其相关的细节需要了解。

  • AFNetworking是一个第三方的开源库,置于苹果内置框架之上,提供便利的功能。
  • AFSecurityPolicy是AFNetworking的组件之一,根据应用程序设置的规则处理验证挑战(authentication challenge)。包括通过HTTPS连接时,对服务端返回的X.509证书的评估。
  • 证书锁定(certificate pinning)是一项信息安全技术,它在标准TLS评估的基础上做了改进,通过服务器显式地发送证书来匹配包含在客户端的凭证(credentials)。AFNetworking从版本1.2.0开始一直提供证书锁定技术。
  • 中间人攻击(Man-in-the-Middle Attack, MitM)是在客户端和服务器之间插入攻击者本身,使两边都认为自己和对方在直接通信。
  • 这样的一种攻击方式在客户端和服务器之间会涉及某个不可信的Wi-Fi接入点。没有对响应进行恰当地验证,攻击者就可以拦截通讯信息,用户凭证或其他敏感信息因而会遭到泄露。
  • AFNetworking官方文档强烈建议应用程序要通过HTTPS进行通信,并且使用证书或公钥锁定技术来弱化MitM这种攻击行为。工程中所包含的示例代码遵循了这些建议,在应用程序中展示了证书锁定的使用方式。

事件的时间表

收拾心情,整理思绪。下面是与这一事件相关事件的时间表:

  • 2015年2月12日,AFNetworking 2.5.1发布。这一版本包含了一个补丁,修改了证书的安全策略验证方式,将SSLPinningMode修改为AFSSLPinningModeNone。验证挑战过程中,服务器的证书默认是不会被验证的,除非客户端存在与众不同的配置行为,比如使用SSL pinning这样的证书绑定技术。
  • 2015年3月12日,我们从这个GitHub Issue开始意识到上述的修改行为所造成的影响。
  • 2015年3月26日,来自Minded Security Research的Simone Bovi和Mauro Gentile发表了一篇博文,详细说明了AFNetworking 2.5.1潜在的MitM方面的漏洞。
  • 同样在2015年3月26日,AFNetworking 2.5.2发布。这个版本恢复了先前的证书安全策略评估方式。如果安全策略将validatesDomainName设置为YES,那么SSLPinningMode将会被修改为AFSSLPinningModeNone。
  • 2015年4月20日,AFNetworking 2.5.3发布了,该版本做了额外的修改。对所有的安全策略默认设置validatesDomainName为YES。
  • 2015年4月21日,GitHub上新开了一个Issue,要求完善AFNetworking的文档和与安全相关的功能特性。我们正就此积极努力地对参考材料做全面彻底的修改。
  • 还是在2015年4月20日,来自SourceDNA的Nate Lawson发表了一篇博文,宣称某个工具可以识别苹果商店中使用了AFNetworking2.5.1的应用程序。包括来自Ars Technica的Dan Goodin在内的许多记者,在其公布的文章中都引用了该博文并提及了博文的作者。这些公开发布的内容都没有就AFNetworking维护人员的解决方案进行整理而置评。
  • 2015年4月24日,SourceDNA在其后续发布的博文中声称,存在更多带有安全漏洞的应用程序,来自Ars Technica的Dan Goodin随后也发表了一篇带有相同效果的文章。需要强调的是,没有任何一篇公开发表的文章对AFNetworking维护人员的解决方案进行整理而置评。

AFNetworking用户力所能及的事情

下面是AFNetworking用户需要了解的力所能及的事情:

如果应用程序通过HTTPS通信,却没有启用SSL pinning技术的话,应用程序就可能容易受到所报道的MitM攻击。

AFSecurityPolicy的官方文档中的内容:

将固定的SSL证书( pinned SSL)添加到应用程序中,可以帮助应用避免中间人攻击以及存在的其他漏洞。大力鼓励应用程序在处理用户数据或财务信息的时候,所有通信途径都通过HTTPS协议,配置并启用SSL pinning技术。

无论在什么时候,遵循这些建议的应用程序都不应该存在上述安全漏洞。

如果应用使用HTTPS进行通信,并且启用了SSL pinning技术,就不容易遭到所说的MitM攻击

很大一部分应用程序使用AFNetworking是通过推荐的步骤启用了SSL证书或public key pinning机制的,这些应用程序不太不容遭到上面说的MitM攻击。

如果使用的是先前的版本AFNetworking,我们强烈推荐您升级到版本2.5.3

AFNetworking 2.5.1和2.5.2包含的默认配置不适合产品级应用程序——特别是如果不进行额外的配置,就不会提供必要的TLS评估。

AFNetworking 2.5.3默认配置更加安全,即使不使用SSL pinning也会进行域名验证。

如果使用NSURLConnection或NSURLSession代替AFNetworking的话,你仍然需要检查验证挑战的实现方式

苹果内置的NSURLConnection和NSURLSession,还有Security框架所提供的API,都具有对凭证验证的安全实现方式。但是,像任何API一样,某个应用程序的安全性取决于这些API的使用方法。

是否使用AFNetworking本身并不能保证你的应用程序能够灵活应对MitM那样的攻击。是否能够灵活应对攻击完全取决于应用程序使用可用API的方法。在产品环境下,测试应用程序的健壮性和网络安全性最终是开发人员的职责。

如果你要对某个安全漏洞进行吐槽,请发送电子邮件到security@alamofire.org吧!

我们会尽快回应并提出解决方案。

如果你想为AFNetworking更出色而做出贡献,那就在GitHub上提交一个Issue和Pull Request吧!

AFNetworking是开源项目,这意味着每个人都有机会为其更出色而贡献力量,欢迎提交IssuePull Request

对负责任的安全研究和新闻工作的看法

对于终端用户来说,安全研究人员在软件安全方面起着核心作用。研究人员与软件开发人员共同努力,通过遵循既定的负责任的漏洞披露(responsible disclosure),可以快速修复漏洞。同时,将当前用户的风险降到最低。

然而,我们对一些研究人员的做法和一些对AFNetworking的披露感到失望。作为人尽皆知的话题,信息安全从未如此重要。安全研究人员和记者拥有独特的机会来让读者了解这些事实。但不幸的是,这样的披露方式常常通过制造恐惧来增加点击量,而不是客观详实的报道。

尚未有确切的方法可以表明多少应用程序受此问题的影响;这些对安全问题严重程度的揣测摧毁了对问题准确和适度的回应。同样地,根据揣测提出的权利主张对企业和其客户也帮助甚少。

事实上,编写安全的软件一直以来都是一项巨大的挑战。这需要多学科的工程师们一起合作完成。这是一个极其重要的任务,最好由理性且富有责任心的人参与。

作为软件维护人员,我们有很多事情可以做得更好,并积极采取措施来完善自身的组织和流程。从今天起,我们期待与信息安全社区的成员紧密合作,负责任地寻找并解决任何安全漏洞。

对负责任的开源项目维护工作的看法

我们真诚地向使用AFNetworking的开发者和iOS整个开发者社区表示歉意。

作为著名开源项目的维护者,我们有责任提供与高标准相契合的软件,该软件将作为应用程序不可或缺的一部分。我们却没有对应该尽快更新的版本做出回应。我们未能向您有效传达至关重要的安全信息。这所有的一切,我们表示真诚的歉意并负全责。

在未来的几周内,我们将推出重组后的AFNetworking及其相关项目,以确保稳定的通信顺利进行。从用户的角度看,这意味着更加频繁地发布版本,更高的透明度,处理问题与合并请求过程中更多的反馈。我们为此而感到兴奋。

http://www.csdn.net/article/2015-05-12/2824671-AFNetworking

11 5月

应用下载的价值究竟在什么地方?

文 / Scott Stanchak:《纽约时报》移动业务营销总监。此前,他负责Avis Budget Group公司移动营销及产品策略。他还是Winery Passport这款热门应用的创建者,在其站点BakBurner.com撰写了移动营销的相关文章。

原文链接:http://venturebeat.com/2015/02/14/the-value-of-a-download/

下载的价值有多大?

对于我来说,下载没有太大的价值,但是给下载贴上价签以后,它的价值就产生了。

自从我在大公司负责移动营销工作开始,我遇到过许多人,他们把应用的下载量作为应用是否成功的唯一指标。这大概是因为“下载”这个词语与移动应用程序关联最紧密。但除非你的应用程序是付费下载,否则很大的安装量并不代表这些用户完成了你所期望的行动。

我非常清楚下载量和下载速度都会对应用商店排名结果产生影响。这是图表意义上的成功。然而,如果不在市场营销和拓展宣传中投入资金以保持地位,这样的排名常常是难以为继的。如果把钱花在这些地方的话,你要相信,这些钱会生出更多钱的愿景定会实现。

即使是为那些大量廉价的下载花钱做铺天盖地的广告,用来驱动其在应用商店的排名,这样的做法都比单纯的下载更能实现我们所期望的行动。提升排名背后的目的则是使下载量实现连续的增长,这会有更多的益处,非常有可能引出有意图的行动(intended action)。

行动(Action

你的“行动”是什么?这是我在做演示或与他人谈论移动营销问题时常问的一个问题。

在《纽约时报》任职期间,我主要的行动是订阅。在Avis Budget Group公司,我的行动是预定出租车。在Winery Passport公司工作的时候,我的行动是让用户通过一个应用来付费验证他们的护照。多年来,我在营销活动中花费的每一块钱都是在寻找用户的意图,这其中包括订阅者的意图,租客和买方的意图。

无论你的行动是什么,它必须带有一个指定的值。原因很简单:确定投资回报率(Return On Investment, ROI)。我提到的所有这些行动显然都是货币上的价值。但还存在很多并未对我们的产品或服务付费的用户。

工作中观察到所期望的简单行动可能是不同的——登记,电子邮件注册,还有额外的文章阅读等等。总体上了解用户在每个场景中的价值所在,不仅有助于解释递增的营销利润,而且如果这些简单行动没有达到目的,那么这种认识对理解ROI也比较关键。

测量你的行动

几年前,你对应用安装活动唯一可以测量的数据就是点击率。除此之外,你还会从Apple,Google或者其他第三方分析工具得到支持数据,但这些数据并没有与用户间交流的活动。从而无法将特定的点击下载与应用中的事件相联系。

谢天谢地,那些日子已经一去不复返了。第三方公司提出了解决方案,可以测量所有营销活动,不仅是点击,还有用户行动和其间的许多其他事件(event)。

它是这样工作的:当用户点击一个活动后,他们的设备ID将被这些第三方公司的某一家存下来。当同用户再次启动应用的时候,SDK(Software Development Kit)就会读取设备ID,并验证这个设备ID是否与某个活动关联过。如果关联过,就即刻建立起了一对一的关系。你可以追踪该用户对应用的使用状况,包括这些用户是否进行过购买的行动。

未使用这些第三方公司的工具在应用商店对应用进行追踪,应用是不会有市场的。无论是否花钱动用了媒体,或者本身就是媒体。这就像网站上被推荐的资源,有其价值所在,而在这些资源如果在手机上,则会更有价值。

通过移动应用程序成功测得用户有意图的行动,你将能够做出更明智的决定,进而会调整活动的开支,还会对网络的部署进行调整。这会使你获得更高的投资回报率,意味着花同样的钱会获得更大的下载量和更多有行动的用户。

就像漏斗,顶部较小,但底部的回报会更大。这就是作为底部的下载最为有价值的地方。

01 5月

我们需要计划,但需要评估吗?

文 / Johanna Rothman:帮助管理人员和团队解决问题并交付产品。她最近的一本著作是Manage your Project Portfolio: Increase Your Capacity and Finish More Projects。你还可以在jrothman.com阅读博文及她的著作。

原文链接:http://java.dzone.com/articles/we-need-planning-do-we-need?mz=123873-agile

我在撰写项目管理著作的过程中,领教了对大量的工作进行评估的难处。

Essays on EstimationManage It这两本书中,我推荐了几种评估方法,每种方法都表明,对于一个工程或项目,不存在一个绝对的计划日期。

你能做些什么呢?有下面几种选择:

  1. 计划和再计划。要决定对当前的工程或项目投资多少。请参见(图示中)工程/项目进展。还要决定你打算对工程/项目投资多久。
  2. 按照预定日期工作。如果你以迭代的方式或增量的方式进行开发,预定日期就最合适不过了。如果经常有内部版本发布的话,你可以看到工程/项目的进展和重新制定的计划(如果使用瀑布模型进行开发的话,就不太可能满足你想要的所有功能,也无法避免不想看到的缺陷。而如果你以迭代或增量的方式开发的话,就可以按照要达到的目标去完善计划。注意,我说的是完善计划,而不是评估计划)。
  3. 对三种不同情况的评估:任何事情都顺利的情况,正常情况和最不利的情况。这是著名的PERT(计划评审技术,Program Evaluation an Review Technique)估计。
  4. 用百分比给所做的评估一个信心值。你认为在某个特定日期前后能够发布,那么对这个评估有几分把握?这种情况再计划一下最好不过了,那样你可以更新信心值了。

这里的每一项表明所做的计划带有不确定性。工程或项目规模越大,表现出的不确定性明显。

如果你使用敏捷(agile)方法的话,可能根本就不需要进行评估。这些年来,我管理了许多工程和项目。从来没有人过问项目的成本和对进度的评估。有时候只是告诉我那些预期目标,那些目标是如此地乐观,以至于我不得不对其进行总体的评估(gross estimate),用来解释为什么不能满足这个日期要求。

然而,除了总体的评估外,我并不相信其他方式。我相信敏捷方法的路线图(roadmap)。建立项目迭代增量,观察项目进度,并且可以决定下一步做什么,这都是不错的点子。

RoadMapForProduct

当你看到这幅路线图的时候,就会了解每个月如何为内部版本做计划了。

对于内部版本,每一个人都可以看到工程或项目的进度。

另外,我们按季度发布的外部版本。此时你的工程或项目也许无法按季度向客户发布。但这应该是商务上的决定,而不是由你决定的,因为此时工程或项目未达到预期标准而不能发布。如果你没有采用敏捷方法推进项目的话,可能就无法按季度发布。但我姑且认为你会用敏捷方法进行开发的。

AgileRoadmapForProduct
在单季度的视图中,你可以看到“最简可行产品”(Minimum Viable Product, MVP)。

在这里,特别是在项目的开端。你可能需要将MVP换成MIFS(Minimum Indispensable Feature Set)。

如果总是出现这么小的“Story”的话,那就可以统计他们的数量,而不是评估这些“Story”,这样做会更加接近事实。特别是在项目初期,你就不用花时间去评估,也就不用开发相应的产品。

在工程或项目的初期,你对于存在的风险和陷阱了解得最少,甚至连MVP和MIFS都不了解。但是,如果肯向用户发布一些东西,你就可以得到自己所需的反馈。

反馈会告诉你什么:

  • 这些“Story”是否数量太多而无法统计?如果是这样的话,你创建的任何评估就都是错误的。
  • 是否提交了有价值的工作?如果是这样的话,公司将会对此继续进行投资。
  • 是否正在为最具价值的任务工作成果?在工程/项目进行的过程中,其价值所在会发生变化。有时你实现此功能可能在价值上逊色于彼功能。有的时候,你会意识到你正在实现的功能其实已经被实现了。
  • 是否要停下来?如果我们提前完成了项目发布的要求,那很棒!如果还没有做好发布的准备,我们要做些什么呢?

这都是我做评估的心得体会。如果你只拿出一套评估方案,那些经理是不会相信你的。他们会向你施压,说些“少花钱多办事”那样不合常理的话。他们会这样讲:“如果我们裁掉测试的话,你可以进度更快,对吗”?(对此类言论的回应是:“NO!在技术层面所亏欠或产生的债务越少,我们才能进行得越快”。)

但是你确实需要对项目的路线图做规划,包括所积压的工作。如果没有一个路线图,展示人们所期待的东西,这些人就不会相信你,觉得你很假。由于团队所提交的内容并不是每一项都是产品负责人期待的东西,因此你要重新计划路线图。不过没关系的,尽早从反馈中得知团队力所能及之事就很赞。

向要求做评估的人提出的两个问题:

  1. 在团队停下来之前,你愿意为这个工程/计划投入多少资金?
  2. 这个工程/项目对你有多大价值?

如果你为最有价值的工程/项目工作,那还做什么评估呢?你需要了解的是在项目进行中公司打算在这个项目上投多少资金。如果所做的不是最有价值的工程/项目,你也要知道公司打算对其投资多少。或者你要有一个预定日期,有了这个日期,你可以用迭代法或增量法逐步发布版本,直到完成目标。

这就是对评估的风险管理,还有再计划。没错儿,我就是一位“0评估”粉丝,因为我们划分的粒度越小,就越容易明白如何进行计划和再计划。

我们需要计划和再计划。如果使用迭代法和增量法的话,我认为不需要事无巨细的评估。

04 4月

2015年,数据集成进入云端

文 / George Gallegos:在2011年被任命为开源数据集成方案提供商Jitterbit公司首席执行官,曾是甲骨文公司的区域副总裁,拥有18年企业管理和销售经验。

原文链接:http://www.informationweek.com/cloud/software-as-a-service/integration-moves-into-the-cloud-in-2015/a/d-id/1318654

Jitterbit公司首席执行官George Gallegos认为,如果程序开发进入云端,那么应用程序及数据的集成也应该紧随其后。

编者按:本期内容是Jitterbit公司首席执行官Gallegos撰写的文章,其所在公司是“基于云端的数据集成平台”提供商,Jitterbit是此类服务商中的一员,除此之外还有Dell Boomi,以及开源SOA解决方案提供商WSO2等。

随着基于云端的应用、虚拟服务以及可连接设备和传感器在企业的部门间应用数量的激增,企业所使用的技术呈现离散状态。

2014年,企业意识到自身需要进行整合,将已经采用的内部部署(on-premise)系统与新的云解决方案进行整合,以此来补足自身IT部分旧有的系统设计。

已经建立起的中间件,包括企业服务总线(Enterprise Service Bus, ESB)和自定义代码(custom code)都已经被证明不足以满足需求。在新的一年,还未采取快速集成策略的企业要集中精力找到更快,更有效的方法,用以连接膨胀的数据与服务端点(endpoint)。

许多公司会建立起新的云服务中心,还有云服务代理商,也就是业内所说的云服务经纪人(Could Service Brokerage, CSB),用来提供与IT相关的服务以及API,作为其占有市场的一部分,企业用户可以使用这些服务和API,而管理则交给IT部门。这些基于云端的集成平台将为企业提供最快最简单的方式,确保公司那些新技术可以迅速与其他部分相连接,像公司内部以前部署的系统。

ESB的覆灭与实时(Real-Time)API集成的兴起

大数据和云计算的重要性迫使这些企业重新思考他们旧有的IT基础设施。这样就可以利用来自物联网、云端、社会和移动服务端点的巨大信息库了。

例如,物联网对大容量存储的要求到达了一个新的水平,对实时操作的面向外部的API也有个更高的要求。ESB集成模型是10年前构建的了,在云计算变革来临前,设计上从未考虑现代电子商务的规模和速度。相反,下一代集成技术,如PaaS集成平台,在数分钟内将会提供全新层次的敏捷性和连通性,而再用不着几个月了。

在2015年,三个方面的集成创新将会重新定义企业级架构,分别是虚拟集成,基于云端的集成以及被托管的API。

  • 虚拟集成允许应用程序从外部系统访问信息,而不用真的将数据从一个应用程序转移到另一个,系统之间直接可见。需要的存储空间更小,并且不再需要去同步冗余的数据集。
  • 云集成平台开启了混合集成的新一代。这种集成方式在一个单独的云平台上被设计并管理,而这种平台可以安全地运行在云端或防火墙之后。
  • 托管API是数字企业(digital business)新构建的内容。托管集成API不是父辈的SOA API,它们是专门为了当今社会所需的规模和安全性所设计的,可以提供巨大的吞吐量,有限流,分析,监控和集中式的生命周期管理功能。

来吧!这些新的集成创新将重新定义我们与客户,合作伙伴和员工之间的经营方式。

自助集成:终端用户的转变

随着更多业务流程利用相互关联的应用和数据,这些数据集成解决方案将会被越来越多的普通企业用户采纳。取代依靠IT专业人员在各种应用程序中去关联不同的业务流程,这些现代集成方案的浪潮将让使用此业务的用户来管理方案间的联系,这些方案是他们最了解的。由于终端用户需要更多地控制他们日常生活中用到的技术,企业的IT部门和集成服务商将会把注意力放到开放API上,这样可以让全公司的人很快地将传统的解决方案与新技术相融合。

云服务代理商的走俏表明了某种类型的企业数量,这类企业采用更加开放,包容性强的新技术。他们正通过像BlueWolfCloud Sherpas这样的云服务代理商,来调整近期来自企业的影响。这些影响源于现代化企业所需服务端点爆炸式的增长。

云服务代理商在企业级应用技术领域将扮演更重要的角色,帮助填平IT技术关键决策者与业务线上用户之间的沟壑,这些用户一直吵着要使用最新的解决方案。使用这些业务的用户对IT决策过程的影响凸显了企业级应用技术的新道路。那就是让用户满意,让他们选择自己想要的解决方案,并确保这些解决方案可以迅速、轻松地连接到企业的其他平台。

云服务中心和代理商的出现也会给基于云端的集成平台提供商带来机会。通过提供即装即用(out-of-the-box)的集成方案脱离旧有的解决方案。这样就使整个企业更容易迅速采用新技术。

根据IDG的研究报告,这些企业希望他们所管理的数据量在来年达到70%以上的增幅。这些数据对一系列用户来说都是比较重要的,不仅是相应的分析师和企业高管,还包括那些现场服务代表、销售人员、营销人员和产品经理。

随着公司的信息主管的职能从传递信息转变为交付服务,他们将需要采用专门为混合架构所设计的那些新平台,还要为数字企业以及云端的扩展来专门设计新平台,以此来为彼此创造出最大价值。

02 4月

为什么要认真对待与在线学习有关的应用

文 / Ryan Craig:University Ventures公司的执行董事,该公司专注于推动大专院校进行创新。Ryan即将出版新书College Disrupted: The Great Unbundling of Higher Education”。

原文链接:http://venturebeat.com/2015/01/17/why-online-learning-needs-to-get-serious-about-apps/

上个月,中国最大的民营教育服务提供商新东方教育科技集团与在中国拥有近5亿WeChat用户,领先的短信息服务提供商的腾讯公司,同意启动一项以网络聊天为核心的集成服务。每一所大学都应该问的问题是:这对在线学习(online learning)意味着什么?

仅在10年前,我们当中的许多人认为无论何时何地,在线学习意味着取得学位。现在有了智能手机,移动学习成为可能。学习效果却打了折扣。在线学习三位一体的构成包括:内容和讲座(content/lecture),讨论(discussion)以及评估(assessment),但这些内容都没有迁移到智能手机上。也就是说:

导航部分:在智能手机上对课程导航具有一定的挑战性。不仅因为智能手机的屏幕小,导航功能需要有足够大的按钮区域可供手指去选择,而且还有我们使用智能手机体验上的差异。如果内容加载时间超过5秒钟的话,那么相比使用PC的用户,智能手机用户更容易放弃要浏览的内容。

讨论:讨论版在智能手机上使用效果很好。到处都可以参与讨论,同步的视频讨论也不错,但也不适合所有人。会话时间也要比课堂上短得多。然而,使用智能手机提交的帖子要比曾使用的其他方式发的信息要短得多,也没有那么正式。

测试:使用智能手机,无论在课堂环境中还是在课外,对于形成性评价(formative assessment)来说,效果还不错,而终结性评价(summative assessment)效果却不怎么样。

基本脉络应该已经显现了。任何能够在短期内完成的事情,使用智能手机效果都还不错。

所以在线学习是走上坡路还是下坡路,这是否取决于我们对短期学习的整合的能力呢?就像新东方教育科技集团与腾讯公司正在做的事情那样。当然会有很多在智能手机上使用的与之类似的和教育相关的应用(application),但这不会存在正式教育中的那些评估测试和被认可的证书。这主要有两方面原因。首先,需要授予这种证书的各色课程和终结性评估无法在短时间内被整合。其次,对于和教育相关的应用来说,可能不必对这些东西进行整合,因为这些应用开辟的是一条新路。

这些应用是智能手机所面临挑战的解决方案

目前,智能手机用户使用应用所进行会话的时长是浏览网页的3倍。应用的使用频率也比网站要多得多。用户花在应用上的总时间目前以超过20%的速度逐年递增。行业知名的互联网统计公司ComScore称,对于智能手机用户来说,手机上使用应用所占时间超过了其所使用数字媒体时间的五成,18至24岁的用户是主力军。

应用是为特定目的而开发的。因此不难想象,一个是经济学入门的应用,而另一个则是心理学入门的应用。应用是有价值,有目的的模拟,也是学习体验的游戏化模式,它还将现实世界的这些内容(如学生的地理位置)作为输入数据融进了学习。

但如今像“mLearning”这样的移动教学平台忽略了这一点。当前高校中使用的应用根本没有正式的教学内容,全都是关于选课,校园定位的应用。还有就是一些无关紧要的学习内容(像医学缩略语词典)。Blackboard Mobile Learn这个站点就是个典型的例子,有一定的教育意义。所有类别产品的功能(公告、成绩)都以图片的方式展示在智能手机上,但却无法获得展板上所展示的实质课程资料。这是“mCheating”,不是“mLearning”。

目前虽然大部分在线学位课程是以学习管理系统的形式存在的,都声称自己是“移动平台”,这些平台所属机构认为,解决移动问题的方法是简单地基于传统的线上学习系统架构,让移动终端访问教学资源。这等同于认为机构的在线学习模式解决方案就是向YouTube或iTunes放置讲座视频。

26 3月

几种监督式学习算法的比较

文 / Kevin Markham:电脑工程师;热衷烹饪,痴迷戏剧,偶尔参加铁人三项运动;为General Assembly讲授为期11周的数据科学课程,在SlideRule指导学生学习数据科学,还是约翰·霍普金斯大学数据科学Coursera专项课程的社区教学助理(CTA);业余时间制作视频教程参加Kaggle的比赛。

原文链接:http://www.dataschool.io/comparing-supervised-learning-algorithms/

我所讲授的数据科学课程涵盖了该领域大部分内容,但尤其关注机器学习(machine learning。除了讲授模型的评估过程和度量方法以外,很明显,我们还讲算法本身,主要是监督式学习(supervised learning)算法。

在为期11周的课程接近尾声的时候,我们花了几个小时检查所用的课程资料。我们希望学生能够逐渐理解他们所学的东西。要掌握的技能之一就是在解决机器学习的问题时,有能力在不同的监督式学习算法中做出明智的选择。虽然使用“蛮力”(把每种情况都试一遍,看看哪种最好)的方法有其价值所在,但比这价值大得多的是能够在不同算法之间做出权衡利弊的选择

我决定为学生们组织一场比赛。我给他们一张空白的表格,列出所讲的监督式学习算法,让学生从几个不同维度对这些算法进行比较。我在网上找到了这样的表格,自己先弄一张再说,一起看看

贡献出这张表格,有两个原因:其一,它可以用来讲课或者学习下载下来拿去用吧)。其二,这张表格需要完善,人多力量大!

这张表格是集鄙人经验与研究的产物,在任何这些算法的领域,我都称不上是专家。如果你有能够改进表格的建议,给我留言哟!

  • 是否在我的这些评估中存在误导或错误?(当然啦,有些比较维度本身就带有主观性。)
  • 是否存在应该添加到表格中的其他“重要的”对比维度?
  • 是否还有其他你希望加入到这张表格的算法?(目前,表格中只有我所讲授的算法。)

我意识到每种算法的特征及相应的评价都可以基于数据的具体情况(以及数据的调优程度)发生变化。因此有人会认为试图做“客观”的比较是欠考虑的。然而,我认为作为监督式学习算法入门一般性参考,这张表仍然有其价值所在。

Duang~Duang~Duang~!

学习资源

补充说明:要做“锐推”,请点击这里,还可以来KaggleDataTau讨论!

http://www.csdn.net/article/2015-03-17/2824232

19 3月

IT部门的压力:管理、同情心以及对陌生人的友好

文 / David Wagner:在商业及科技领域10余年笔耕不辍,曾在《麻省-斯隆管理评论》(MIT,Sloan,Management,Review)做助理编辑,Enterpriseefficiency.com执行总编,还是许多顶级商业及科技咨询公司的自由撰稿人。

原文链接:
http://www.informationweek.com/strategic-cio/it-stress-management-empathy-and-the-kindness-of-strangers/a/d-id/1318657

压力会让我们更容易忽略其他人的感受,对于当今企业中的IT部门来说这是不利的。

如果你管理着一个四五个人以上的团队,那么你就要清楚压力是怎样改变团队成员之间相互回应方式的。一项研究表明,人们面临压力的时候,对于陌生人就会缺乏同情心,而不管是否喜欢这个人。在大型团队或部门中,你所管理的这些人彼此之间实际上是完全陌生的。

美国与加拿大在McGill大学共同进行的研究部分地表明,对人类和小鼠进行测试,当使用药物阻断了应激激素时,人类以及啮齿类动物显示出更强的移情作用,也就是更具有同情心。举例来说,学生被要求观看一个人正在经历痛苦,用手拿着一桶冰的场景。这些学生可能会过度估计这个人所承受的痛苦,还可能会心怀同情地去触摸自己的手。除非这些学生自己处于压力之下,否则他们不太可能感受到一个陌生人的痛苦。

那么,作为一位IT经理应该做什么呢?购买一些抗应激(抗压)药物吗?让人感到高兴的是,研究还表明,如果在测试前被研究对象与一个陌生人玩有趣的视频游戏,那么这两个被测试对象可能会更有同情心。研究人员认为,单纯地减小压力完全可以使人更具有同情心。

IT从业者们的工作地点日益分散,常常跨时区,甚至跨越大洋。自己的团队成员往往会是陌生人。即使不是,IT从业者也比以往任何时候更多地被要求在不同职能团队工作,其工作与“业务”关联更紧密,与一些陌生人一起工作。

我们经常建议信息主管和IT经理们,对IT部门进行管理的最佳方式是感知企业的痛处。对IT管理来说,管理缺乏同情心的员工是不太好。如果员工处于这样的状态,那么你很可能会听到他们取笑其他部门,对其他部门的服务意识淡薄,而且很少会主动在业务上为这些部门服务。

如果你碰巧在客场为客户提供服务,那样风险可能会更大。有些人可能不会认为在同一家公司工作的人是陌生人,但如果在压力下工作的员工去客户的办公场地办公的话,那么在他眼里一切都是陌生人。

当然,你不能总是邀请你的客户或者业务线主管来玩游戏。你必须要为自己的团队找到一种管理压力的方式。美国职业压力协会表示,25%的人认为他们的工作是压力的主要来源。百分之四十的员工称,他们的工作“非常紧张或极其紧张”。八成的人表示多少都有一点工作压力。令人震惊的是,14%的人说他们感觉像是跟同事在打架。

对工作量进行管理会对此有所帮助,稍做休息也是可以的。在合理的范围内鼓励工作的时候听音乐或者做一些有趣的事情。最重要的是,你需要帮助自己的员工注意到这个问题。这样做就很容易摆脱办公室中的流言蜚语,还有团队之间的对抗。但有时候你还需要团队静下心来,关注一下别人的需要。在驱车前往客户驻地时,你要鼓励团队成员听有趣的音乐,告诉他们在参加大型会议前要找到自己满意的位置。只要意识到压力的影响也许就足以克服其最糟的一面。

换句话说,对你的团队要带点同情心。他们最需要快乐的时候让他们开心,当你最需要合作的时候,他们会展现出自己最好的一面。你怎么看呢?在你的管理方式中,同情心是否是其中的一部分呢?你又如何给自己的IT团队缓解压力呢?你是否认为你的团队成员在公司内外可以对陌生人多一点同情心呢?

04 3月

Open Cloud 2015 to focus on technology innovation and applied practice

大会包含“2015 OpenStack峰会”,“2015 Spark技术峰会”,“2015 Container技术峰会”三大技术峰会及多场深度行业实战培训。主题聚焦技术创新及应用实践,讲师荟萃了国内外真正的云计算专家。 这里都是一线接地气的干货,扎实的产品、技术、服务和平台。Open Cloud 2015,懂行的人都在这里

A total of three Technology Summits including “OpenStack APAC Conference”, “Spark Summit China” and “Container Conference 2015”, and more industry experience in-depth training, bringing together worldwide leading experts in cloud computing, aims to provide a genuine technical feast by discussions over products, technologies, services and platforms. Open Cloud 2015, THE EXPERTs ARE HERE!

02 3月

可穿戴设备制造商们,这才是今年我们想要的产品

原文链接:http://venturebeat.com/2015/01/06/hey-wearables-makers-heres-what-we-expect-from-you-this-year/

文 / Elliott Chenger:移动平台开发人员,热衷于使用新兴技术构建连接彼此的产品。

2015年了,我对可穿戴设备有了更多的期许。虽然现在这些设备可以记录我走路,睡觉,消耗的卡路里还有心率,但是我仍然被那些在我看来没有意义的数据弄得不知所措,搞不懂这些可穿戴设备到底能给我带来什么好处?

就拿Jawbone Up24这款智能手环来说吧,我是很喜欢的。它能够记录我的行踪,睡眠,饮食,甚至是聪明程度(哈哈,我开玩笑的,这个不能滴)。但所有的这些功能只是告诉你正在干什么,却没有说你该如何进行调整及其原因。比如这手环自带的应用没说怎么样去获得更好的睡眠,也没能因地制宜地帮你从锻炼中进行调理。

在新的一年,可穿戴设备需要针对这样的局限进行改进,切实地告诉大家如何才能有效地提高生活质量。这需要有带情境、可操作且精准的数据作为前提来对我们的日程行为进行调整。

情境数据
情境数据会将时间定位到一天的某个时刻后呈现给你。这不仅可以帮助你从杂乱的数据中进行快速筛选,还能让你对自己在一段时间内的状况有更好的认识。

如果数据杂乱且没有正确的情境,接触太多这样的数据就不一定有用了。就拿记录睡眠来说,我们要从睡眠数据中得到更多的信息,就需要知道白天以及就寝前哪些时候需要调整,还需要从周围环境得到一些其他数据来协助验证影响睡眠的方式及原因。

比如说,我们睡觉的时候,有一个连接到可穿戴设备的温度调节器来显示室内温度的变化。这种变化要附带睡眠模式,这样才可以帮助我们定量了解室温对睡眠质量的影响。

由于这些设备变得更加个性化,关联更紧密,因此我们所得到的数据关联性也会更强。如果设备能够将数据情境化,这样就会让我们容易知道如何改善周围的环境,采取恰当的行动。最终手机或者可穿戴设备就能根据这些情境信息以我们的喜好来调节环境。

可操作的数据
没有接下来要说的可操作的数据,情境数据就孤掌难鸣。不要再看我们睡了几小时,失眠了几小时,可操作数据会告诉我们如何让睡眠质量更好。这样做的高明之处在于我们可以看到实时的调整建议。比如可以监视温度调节器,然后根据我们睡眠模式的变化和夜间时间来调节温度。

早期可操作数据的例子就是Jawbone的某款产品,该产品可以根据室内的温度和湿度来提高或降低风扇的转速。

在2015年,消费者需要更多这样的产品,能够通过科技将用户体验与真正的价值相结合给生活带来便捷的产品。企业应该以满足消费者的期待来求得生存。

Whistle是一款宠物狗行踪追踪器。它能帮助宠物医生了解宠物的活动量。这样就可以给宠物的主人提供有益于改善宠物健康的建议。就像HealthKit移动应用平台那样,开发人员可以开发类似的功能,把数据信息传送给医生,医生可以给出可操作的建议,提高我们的生活质量。然而,所有这些功能都需要在精准的设备上工作。

精准程度
可穿戴设备目前并没有那么精准。很多用户都有这样的经历,所测量的步数和心率的变化很诡异,心率的变化好像一会儿心脏停跳了,一会儿又像刚跑完马拉松似的。设备制造商也意识到了这样的问题,他们正努力改进硬件以提高设备的精准度。

美国苹果公司声称,其推出的Apple Watch会像医院里大多数医疗设备那样精准,忠实地去记录使用者的心率。如果这些可穿戴设备像制造商承诺的那样精准,那就真的会使我们的生活更美好。

随着家电设备互联业界和可穿戴设备市场都揣摩着如何融入我们生活的方方面面,我们将会看到两者更多的合作,也会有更多的开发者开放平台出现。这会使设备间可以互相对话,一起工作。奠定这样的基础是下一个情境数据为王计算时代的一部分,而以单纯的数量作为度量标准的做法则会成为过去式。随着企业为消费者提供的用户体验更加个性化,大数据技术也将退居二线。

15 2月

你为什么不是史蒂夫•乔布斯

原文链接 :https://medium.com/@ericzelermyer/why-you-are-not-steve-jobs-869e0bbb8d60

文 / Eric Zelermyer:iOS开发人员,目前供职于Resy Network。

自乔布斯逝世三年以来,关于他个人成就的某些细节已经逐渐在人们的记忆中淡化,在谈论他当年的辉煌时,一些说法也冒了出来。大的科技企业似乎在一夜之间都出现了,像Facebook的扎克伯格,亚马逊的执行长Jeff Bezos,还有特斯拉创始人Elon Musk都是让人心怀崇敬的人。对乔布斯一种常见的漠视是认为他只不过是个脑子灵活,做事霸道的家伙,是一个出色的销售人员罢了,并不比当前这些技术领导者、社交媒体新星更胜一筹。我最近耳闻一个成功的企业家声称自己与乔布斯是路数相近,因此他对乔布斯毫无兴趣。虽然这只是随口一说,但却在我的心里发了芽,我百思不得其解。

我一直困惑人们为啥痴迷乔布斯的演讲和销售技巧。他早期的产品(最早的Mac和iPhone)展示演讲虽然使人着迷,让个人魅力和演讲技巧展露无遗。但我不太相信这样的产品展示对产品的成功会有什么作用。我怀疑重视苹果产品营销的人与把苹果产品与相应Windows/Android平台软件产品进行比较的是一拨人,他们使用不同的数量级比较相同的数据,得出相同甚至价格更优的结论。唯一的区别是苹果产品使用了乔布斯的营销大法,这个东西至今被乔布斯的继任者推崇着。

口若悬河式的产品营销,凭借个人魅力来吸引和左右观众的能力固然难能可贵,但这样的人并不少见。这也是很多商务人士、政治家、励志大师、拳击赛发起人以及蛇油推销员所具有的共同特质。如果所有业界处于领导地位的标杆企业都有一位睿智的演讲者作为企业领导者的话,那么HP公司应该早该让善于表演的Jon Hamm作为公司的CEO,那样我们早就用上HP的PhonePad了。苹果公司推出失败的产品也不是什么新鲜事儿,照样有不少乔布斯式的煽情营销也没能使上劲的烂产品。

乔布斯的实质意义在于他是一个符号,是一个融合了传统商业领导者所有品质的符号。包括市场的洞察力,深知市场竞争的严酷性,财务的管理能力,还有营销能力。营销能力包括对审美的苛求,对用户体验的极致追求。对所有产品的任何细节细致入微,一丝不苟,乔布斯是名声在外的,从字间距到icon的颜色。因为他虔诚地信奉这些东西会使用户体验大为不同,进而影响他们的生活质量。他走的不是纯粹的管理路线。他会亲自构思设计苹果旗舰店的玻璃楼梯,而这只是他诸多贡献的其中之一。

分秒不断地对产品设计进行改进,随着时间的推移,换来的是千千万万“果粉”的追捧,苹果公司在乔布斯的带领克服了短期利益的诱惑,把不断改进产品放在了首位。所以,即使苹果公司曾经一度面临歇业,Mac电脑也没有被塞满尽管会带来巨额收入而用户却不想用的软件。乔布斯宁愿看到自己的产品死掉,也不愿意在用户体验上打折扣。

很难想象,如今还有哪一位企业的领导者具备苹果公司那样对产品吹毛求疵的意愿和能力?亚马逊的Jeff Bezos会关心Kindle难看的字体,糟糕的算法和做作的用户体验吗?亚马逊无疑是个成功的大公司,但如果产品价格上涨,送货时间变长,还会有多少忠实的用户会留下来?还会有人再对亚马逊投入感情吗?有人敢说扎克伯格领导下的Facebook相对从用户个人信息中榨取广告收入来说,更重视用户体验吗?

对于我们很多进行创造性活动的人来说,我们可以看到自己拥有几乎与商业领域成功所需特质相反的能力。自我推销能力,财务上的严谨,经营管理的敏锐,还要有竞争意识。而这些特质都是我们希望拥有却又感到陌生的。一个人拥有所有这些特质到了高处不胜寒的程度,同时还要具备极佳的创意能力,设计上的判断力世界第一,并且孜孜不倦地执行他的审美标准近乎极致。那只是个传说,是极其罕见的基因突变。所以,对那些自认为与乔布斯一样伟大的人,我只能说:你没有那么幸运。

http://www.csdn.net/article/2015-01-29/2823765

12 2月

使用AWS管理跨多个环境的资源

文 / AWS Activate

原文链接:https://medium.com/aws-activate-startup-blog/managing-resources-across-multiple-environments-in-aws-7e139351f9c7

为了开发出优秀的应用程序,处于初创期的企业通常需要多环境(multiple environments)的支持,如产品环境、开发环境、QA环境和预备(staging)环境。但在多环境中对资源进行跟踪和管理可能是个挑战,特别是在业务与日俱增的情况下。

例如,随着企业研发人员数量的增加,企业所耗费资源的速度可能比预期的要快得多。这时你会发现自己需要更加清晰地认识到资源与环境的匹配问题。

有多少实例(Amazon Web Services中的虚拟机被称为实例)属于QA(Quality Assurance)?谁有权开启和关闭产品实例?开发环境的成本有多少?随着初创企业的发展,你可能需要找到这类问题的答案。

使用Amazon Web Services(AWS)不仅可以建立多环境的实例,而且还可以跟踪、管理和控制在不同环境间访问资源的方式。我们一起来看看那些能为你所用的相关功能。

标签

你可以使用标签来标记跨多个环境(甚至多个AWS账户)的AWS资源。标签是由一个键和一个值构成的label,你可以对大多数AWS资源进行标记,可以对每个资源添加的标签数量多达10个。

由于使用标签显然会带来很多好处,所以你要标记能够标记的每个资源。例如,你可以对下列任务使用标签。

  • 查找、组织资源
  • 资源的访问控制
  • 查看详细计费报告

此外,对资源进行标记会让你更有效地利用下列AWS的功能特性。

资源组

资源组(Resource Group)是AWS管理控制台(AWS Management Console)的一个酷酷的新功能特性。它允许你创建、查看和维护带有相同标签的资源集。你还可以创建属于自己的视图,这些视图可以带有不同的环境标签。你可以查看带有同一标签的资源,如Environment=Prod,在支持标签的所有服务中都是如此。你也可以查看所有共享多个标签的资源,如下面的屏幕截图所示。

1

详情请参阅资源组的使用

将标签用于身份识别和访问管理

你想为一组标记为Prod的特定用户锁定服务和资源吗?你可以将标签与AWS的身份识别和访问管理(Identity and Access Management, IAM)结合使用,来对用户或组的访问进行控制。例如,你可以控制哪些IAM用户或组可以对特定的EC2实例做开始、停止、重启和终止的操作。通过这样的方式,你可以让开发人员只能对标记为Environment=Dev的实例进行访问控制。

查看支持IAM资源标签的完整服务列表,点击IAM支持的AWS服务

将标签用于计费报告

你想知道一个特定的环境成本是多少吗?可以使用成本分配标签来对AWS的成本进行分类和跟踪。当你对AWS资源(比如Amazon的EC2实例、S3 bucket)使用标签时,AWS会生成一个由逗号将内容分隔开的成本分配报告(CSV文件),使用情况和所消耗成本按照标签被聚合在一起。你可以使用代表业务类别的标签跨多个服务来组织你所消耗的成本。

成本分配报告包括你使用AWS服务在每个结算期的全部成本。

该报告包括已标记和未标记的资源,所以你可以清楚地对这些资源所产生的费用进行管理。例如,如果将某个应用程序名作为资源的标记,那么你就可以跟踪单个应用程序在这些资源上运行的总成本。

有关更多信息,请参见每月成本分配报告的设置

维护标签

现在我们知道了对资源使用标签的好处,那么我们如何确保一切都能够被标记呢?如何确保一切已经被标记了呢?要做到这一点,你可以使用AWS管理控制台中的一些有关标记的功能特性。例如,向实例添加批量标签。下面的屏幕截图就展示了这种类型的标签管理。

2

然而,当新的资源被加进来的时候,你确实需要登录到控制台去手动更新这些资源。随着时间的推移,这种做法就会显得有些笨拙。以下是一些标记资源的其他方法。

创建自己的启动脚本

为团队成员提供一份或一组脚本来创建他们所需的环境。这样做是确保资源被正确标记的好办法。这还使团队成员的工作变得更轻松。他们会很快得到自己想要的环境,分分钟就被创建起来了。

因为每个AWS服务都有一个API,因此有很多方法去构建用来创建资源的脚本。你可以使用AWS命令行接口(AWS CLI)创建一份脚本,还可以使用平台中众多可用SDK中的某一个创建脚本。诸如此类的做法非常简单。关于SDK的更多信息,请参见开始使用AWS进行开发

你还可以从GitHub这样的网站上找到无数的可用脚本,可以拿过来直接用。

使用CloudFormation模版

模版像脚本一样,为团队提供一种在AWS上创建资源的方式,这种方式简单,并且重现性好。你可以创建一个模版,描述想要的所有AWS资源(如Amazon EC2实例、RDS DB实例),AWS CloudFormation将会为你提供和配置这些资源。

几乎每一个支持标签的资源在CloudFormation模版中也支持标签。你可以针对不同环境创建模版,还可以使用条件语句为多个环境使用一个单独的模版。

使用自动伸缩服务

自动伸缩服务(Auto Scaling Service)为你提供了若干个很给力的功能。当应用程序需求增加时,你可以对EC2实例做横向扩展(scale out)。你还可以减少不必要的实例,替换反映变得迟钝的实例。

你也可以对自动伸缩的实例使用标签。已经启动的实例作为自动伸缩功能的一部分在启动后被自动标识,免得你还要创建一种机制来做到这一点。

使用配置管理

许多常见的配置管理工具都支持在创建资源的时候对其进行标记。如Chef、Puppet、SaltStack和Ansible。这些配置工具通常还为多个环境提供有条件的分离。如果你正在使用这些工具中的某一个,那么可以很容易地对已创建资源进行标记。

发现未加标签的资源

你可能会时不时地想要审核自己的账户来识别未加标签的资源,或者去验证资源是否被正确地标记。看看下面建立审核资源的选项设置。

使用AWS管理控制台

AWS管理控制台提供了一种查看资源的简便方法。这些资源全部基于标签,尤其是EC2实例。你可以为大多数资源视图使用标签来创建列。这样就能够使你发现标记不正确或者根本没有进行标记的资源。如下面截图所示。

3

创建自己的脚本

如前所述,AWS提供了访问服务的API。你可以使用相同的API去查询资源列表所提供的服务。你还可以使用这些列表找到没有标记或被错误标记的资源。

总结

你可以使用标签跨多个环境跟踪和管理那些资源,对这些资源做访问控制。在AWS中使用标签的选择不是唯一的。例如,你可以使用AWS管理控制台、CloudFormation模版,还有自定义脚本。无论你选择哪种方法,你都会发现标签是管理资源不可或缺的方法。

http://www.csdn.net/article/2015-02-11/2823926

09 2月

Matt Cutts:我早年在Google学到的10条经验

文 / Todd Hoff:High Scalability创始人 。

原文链接:http://highscalability.com/blog/2015/2/4/matt-cutts-10-lessons-learned-from-the-early-days-of-google.html

【编者按】本文来自Google公司资深工程师Matt Cutts。加入Google以前,Cutts在北卡罗来纳大学教堂山分校攻读计算机图形学方向博士学位。他写的文章深入浅出,简明易懂,实用价值很高,因此他在互联网上具有相当高的名气。 日前,High Scalability创始人Todd Hoff整理了其与Cutts的谈话,总结了后者早年在Google学到的10条经验,值得很多人学习。以下为原文:

我所认识的Matt Cutts是这样的,他是Google的老员工(2000年入职),目前担任Google公司Webspam团队的负责人,他与This Week in Tech(TWiT)创始人Leo Laporte曾在TWiT一起亮相,从中我们可以看到他一贯的敏锐、体贴,是个真正的好男人。走过路过,不要错过!

出乎意料的是他所做的谈话,早年在Google学到的经验。此番谈话也使Matt看起来异常风趣,像是个讲故事的好手。谈话讲述的是他早期在Google一些故事。故事呈现了一个非常人性化的Google。当你认为在Google所做的一切都是人工智能搞定的一种计算之时,Matt提醒大家,那些都是人工所做的判断,通常只是这些人尽力而为的结果。

谈话的核心内容是借助创造力来进行创新,来解决问题。当你陷入进退维谷的境地时,就要变得富有创造力。质疑自己的设想,下面的谈话也许能帮到你。

谈话虽短,但值得一看。很多有趣的小细节,只有身经百战、远见卓识者才能拥有。谈话中亦充满了智慧。这就是我对Matt谈话的评注!

1. 创造力导致天壤之别

Matt Cutts在Google头一个大型项目是开发色情网站过滤器。孤军奋战了一段时间后,他发现没人能帮到他。于是他的妻子烘焙了一些饼干。任何在服务器上找到色情信息的人,都会得到他发给的饼干。这样的战术相当奏效,以至于这些饼干被周围的人称为色情饼干,其他团队也采用了这个策略。抛出一个难题的同时给予人们小小的、象征性的奖励,这样做能够创造奇迹。

2. 当面对相互矛盾的制约时,一个优秀的管理者常常能够找到冲突双方都满意的创造性解决方案。

撒旦是与上帝为敌的魔王!Google首次面对的重大争议是要找比撒旦更邪恶人,而找到的答案却是微软?当然不是啦!面临的争议是基于《数字千年法案》(The Digital Millennium Copyright Act, DMCA)的删除请求。去年Google收到大约3.5亿条DMCA删除请求。显然,你无法手动去搞定这一切,而同时也很难知道一个请求是合理的还是不合理的。对带有【REEFER MADNESS】(赤裸之城)这样信息的内容来说,删除请求似乎是合法的,但由于它不受版权限制,因此这样的请求是不合理的。

Google最初收到的删除请求来自山达基教会,目的是为了压制对其进行的批评。他们试图压制的网站在挪威,而网站的所有者不愿意处理反向通知(counter notification),因为他们不想承担在美国的诉讼风险。Google应该怎么办呢?

差则思勤,Google是这样解决的:

  • 删除了页面并添加了说明:“由于DMCA删除请求的原因,搜索结果予以删除”。
  • 投诉了chillingeffects.org,这是一项由北美多间大学联合进行的学术研究项目。本项目最关注的是言论自由和知识产权问题。

Google开始对每一项不得不删除的合法请求开始做同样的事情。

3. 要积极主动。没人关心你的职业生涯,相对你所做的事,也没人关心你赚多少钱。要自己想要的。否则你就会完全偏离方向。

Matt是“自告奋勇”去做广告产品前端工作的,他为此大约工作了一年时间。在这期间,Matt看到了人们开始向Google发送垃圾邮件,于是他跑到主管工程的副总裁那里说“我想去做反垃圾信息处理这块内容”,这位副总裁答应他了。就这样一路走来。而在这之前Matt很大程度上依赖于别人指使他应该做什么。

你会惊讶,仅仅告诉别人“我想做某事”,竟然会产生这么大区别。假如你是经理就请记住,如果有人想要做一些事情,那么他们就会加倍地去努力。

4. 明确你的设想,进行反思

如果你完全用传统思维想问题,那很难使你从人群中脱颖而出。很难有冲劲儿,也很难变得与众不同。这些地方往往是最让人拿不准的,也是最好的机会。你相信别人不相信的事情吗?

5. 质疑设想的训练

我们通常不善于质疑自己的设想。近似的一种方法就是拿当前的一些事情问自己:发生了什么变化?与过去相比,世界有哪些不同?

例如,对于美国平价医疗法案来说,有两点显著区别:1)可以使用对已存在疾病的保险获得医疗服务;2)你不必非要从雇主那里上保险,而可以自行去交易所购买。

影响:1)自己经商的人数可能会增加;2)像Uber那样依靠独立承包商运转的公司,可能会支持这项法案。

像医疗保险那样的东西可能会发生非常大的涟漪效应(ripple effect)

拿Google来说,以前Google的搜索引擎依靠规模庞大的真实物理机,都是一些价格昂贵的机器。Google对廉价的商品硬件(commodity hardware)做了横向扩展(scale out)。这就意味着Google可能付出更低廉的代价而获得成长。这也意味着机器越多出现的错误就越多。因此你需要知道如何让整体比局部更可靠,这可不是一件容易事。

这也不仅仅是购买廉价的硬件就能解决的问题。在一些转折点你可以有很多认识和领悟。例如,机械硬盘的寻道时间是10毫秒。如果你在RAM中做同样的事情,每秒钟可以做很多次寻道。把网站全部索引都放到RAM里代价高昂,但你可以获得更高的吞吐量。因此权衡来讲这样做还是值得的。

6. 商品硬件是Google取得成功的原因吗?

不!成功是数以百计创新的结果。这样的成功不是灵感乍现而后万事大吉。因此成功不仅源于廉价的硬件,也不仅源于网页排名。成功源于Map Reduce模型,Spanner数据库等创新性的技术。成就一个成功的公司需要许多创新,成就一番个人事业,也需要很多创新。

7. 设想受到质疑,环境发生变化,你必须适应。使用数据你可以做很多非常酷的东西。

在很长一段时间里,我被人工智能难住了。1999年的时候,人工智能还很笨,不能做任何事情。如今状况已经大为改观。很大程度上是因为世界上有了更多的数据。

“Google Brain”是Google运用深度神经网络算法所建立的系统,用来观看YouTube,看看能学习什么。“Google Brain”具有自身可以识别猫咪的神经网络。这项技术同样被用于地构建更出色的词语识别系统。因此,每部Android手机都具有更佳的语音识别能力,这要归功于深度学习算法。这项技术使错误率下降30%,具有紧凑的模型,可以应用在电话上。

如今,技术已经先进到可以指出所识别的景致身处何方。像瀑布、建筑、美国加利福尼亚州中部的约塞米蒂国家公园、棕榈树、大海和雪景。计算机现在甚至还能给图片加标题。

8. 事情会向不好的方向发展,你必须对此有所准备。

在Google也并不全是成功和甜点这样美好的事情。Matt记得所有的诉讼和证词,这对一位工程师来说挺没意思的。这样的情况源于其他公司的诉讼,而这些诉讼来自于各个国家。

会有苦日子,少不了困难,所以自己要做好准备。

9. 不管将要身处何境,都要与快乐相伴,按动快门,使瞬间永恒。

如果你乐意的话,可以记录每一个会议。这没有多少成本。十年后,你要记住八个伙伴围坐的乒乓球桌,一起谈论如何让Google的搜索质量更好。你要记住那条大狗,要记住过去的美好时光。

碰到有趣或是离奇的事情,拍些照片。比如有人曾经为了再次被搜索收录而寄送过来的一块儿巨大的饼干,其他的例子还有四月的愚人节恶作剧以及万圣节的传统。

Matt曾经与他的团队成员打赌,他们可以对自己的头发任意处置。团队成员出色地拦截了四分之一的垃圾邮件,将Matt的头发全剪掉了

每周例会上的趣事是员工可以盘问公司高层,他们为什么做出这样那样的决定。

10. 不管你正在做什么,尽量确保这件事有价值,确保是你所在乎的事情,是人们想要的东西。

Matt一直认为Google是一个工具,而Google的员工一直尽其所能使Google成为最棒的工具。

Fred Brooks在他的论文The computer scientist as toolsmith(计算机科学家的使命是制造工具)中写到:

如果我们正确地认识自己的角色,那么我们就可以更清晰地认识到成功的标准:工具制造者的成功在于,也只在于,工具的使用者在他的帮助下成功。

http://www.csdn.net/article/2015-02-06/2823866

2015.2.06~2015.02.08CSDN首页焦点大图推荐:

LessonsFromGoogle2

28 1月

我们为什么四个月徒劳,使用OpenStack又为什么失败

文 / David Laube:充满热情的互联网基础设施构建者,工作涉及托管服务,基础设施自动化和可扩展平台的部署。目前担任packet.net主管平台系统的副总裁。

原文链接:https://www.packet.net/blog/how-we-failed-at-openstack

去年初夏,我的同事Zac,也是公司的CEO,向我求助如何构建一个现代化的,任何东西都不安装的云托管平台。我回想自己以往的主要从业经历,包括构建,支持和使用可扩展的基础设施的经历,不禁犯起了嘀咕。我问自己,真的需要这样做吗?不是有很多不错的IaaS(Infrastructure as a Service),基础设施即服务可以拿来用吗?

随着沟通的深入,我最终意识到现在很多云服务不是用户友好型的,使用起来存在很大的困难。另外,我是Docker的早期用户,Docker是应用容器引擎,这种容器支持的部署方案会使高质量的物理裸机在运维工作方面更加给力。但某些公有云的虚拟化情况,还有一些托管服务商存在的问题,都没能与复杂多变的物理硬件发展的需求相匹配。于是我觉得需要为此做一些工作。接下来咱们随着packet.net的部署旅程一起过把瘾吧!

开始安装之旅

我一头扎进了部署packet.net的工作。还同时忙着关注部署策略和云自动化的相关动态,从头到尾地检查特定安装程序,还有所有的开源云平台,以及我们已经安装的那些服务。

Voxel是被Internap收购的一款云主机托管平台,我们在使用的时候部署了很多自己的程序,在这过程中既看到了带来的好处,又体验了自己拥有软件平台的感觉。服务器的安装工作看起来似乎特别容易,好像一旦完成,一劳永逸,对吧?但这是绝对的错觉!因为安装完成后会出现数不清的网络问题,还有随时发生的硬件调整,以及各种操作系统存在的差异。在这样的情况下为用户提供不折不扣的自动化服务,安装并管理数千台服务器,并确保这些服务器正常工作,在五分钟之内还能响应Zac做出的决定。这对我来说可不是件轻松的事情。

为了使 packet.net到达预期的目标,数千台服务器7×24小时不断地安装和启动,并要在数月后上线。我开始关注OpenStack在互联网基础设施方面的独特之处,它可以被当作我们构建服务的手段。这包括联网业务的自动化,IP地址的管理,安装过程的监控,以及硬件的调换和安装。如果我能依靠OpenStack这些核心项目完成工作的话,那么我的团队就可以更加专注于能给用户带来更多价值的事情,像硬件分析,还有对容器机制的应用引擎提供技术支持。

别人提醒过我OpenStack存在的一些隐患,但我还是自己花了数周时间去阅读近期的版本记录,混迹于好几个维基的IRC官方聊天频道,并且玩了一下OpenStack的安装脚本DevStack。我开始对OpenStack的核心项目不再那么陌生。在过去的两年中,DevStack已经发展得非常成熟,而且所逢时机也刚刚好。全球领先的托管服务器及云计算提供商Rackspace最近发布了OnMetal物理裸机服务器部署方案,并公开撰写博客指出如何在其物理机上使用Ironic进行部署。而美国时间2014年10月16日,OpenStack的一个重要的版本,Juno版也正式发布了。

所以我觉得应该使用OpenStack来为公司的物理服务器进行部署。

部署的过程

我知道学习OpenStack的过程不会平坦,并且明白这需要拼命努力学习其中的每一个项目,而不只是安装。我细致深入地研究OpenStack每一个项目,尽力去了解Nova的动态,还有Ironic的驱动程序,特别是Neutron。我们不仅要在物理服务器上安装Ironic,还要支持packet.net托管服务的网络模型,特别是要用Layer3取代Layer2和VLAN层主机的功能。

这个时候你可能说:“喂,要阅读和学习的文档那么多啊”!在过去的一个月里,我明显能感觉到我们所接触到的文档不是过时的就是有错误的。这让我不得不去从以前优质的文档中去删选内容,比如从维基上的文章,IRC(一种聊天工具)的日志,还有版本提交记录,从这些地方去寻找最新的正确信息。这些基础工作完成后,我要用python去做大量的调试工作,去验证各种与文档描述不一致的功能。比如这个是否工作,那个是否正确,这是很漫长的过程。

值得一提的是,存在着那么一群人和公司,他们依靠OpenStack生存,组成一个很大的共生系统,特别是OpenStack的Nova和标准的Neutron项目相关的部分。尽管从规模上这群体可以与其他开源项目进行匹敌,但其实对于Ironic来说,他们很难有人能够达到产品级的使用水平。我就碰到过这样的情况,我向其核心开发人员咨询了一些实施的问题,他们居然答不上来。并且我从Google搜索这些问题,也仅能得屈指可数的几条与问题有关的信息。

经验一:OpenStack规模不小 ,新兴并发展迅速,但要了解一些过去的基本信息,会感到相关的文档良莠不齐。

我把Neutron部分交给了我的同事去处理,而自己又深入地了解了Ironic。但实际的情况是,我们需要OpenStack每个部分特定的开发人员,让他们帮助我们去理解代码库,才能跟上OpenStack每个项目更新的脚步。那我们又怎么去恰如其分地满足自己的需要呢?于是我就通过IRC和来自Rackspace的OnMetal团队成员接触,还通过邮件联系。去逛OpenStack开发者论坛。我敢打保票,自己阅读了每一个相关文档,还有论坛里的每个帖子,而且还通过Google搜索出的相关信息去调试Ironic,这些我都做到了!

尽管对于先前那种Ironic项目来说OpenStack Nova版的物理服务器部署方案取得了突破性进展,但是OpenStack还是以为虚拟化技术为核心进行设计的。仍然存在很多功能和文档的修改还介于Nova的物理机部署方案和带有驱动的Ironic部署方案之间。我把这种情况反馈给了力量有限的Ironic技术支持部门,却硬被要求使用与虚拟技术相关的openvswitch和linuxbridge。我们的网络模型与此存在严重的冲突。于是我发现,OpenStack的Neutron项目不仅缺乏针对特定网络产品厂商的技术支持,也缺乏对不同网络模型的扩展能力。

对OpenStack的核心代码有更深了解的大用户(最典型的就是Rackspace公司),依靠将OpenStack的那些项目高度定制化后,使之能够在实际的物理网络上部署物理机。其中有几个补丁是已经发布了的,但很多重要的补丁都没有公开,需要用户自己重新编写,同时还要对以后新发布的版本进行维护。

经验二:OpenStack是基于虚拟化技术的平台,如果你用的不是虚拟技术,那就要再考虑了!

到了这份儿上,我已经对使用OpenStack部署公司服务产生了严重的怀疑。这么多需要了解的东西,还有要做与每个项目保持同步的工作,这样的情况令人望而生畏。并且,我开始认识到要对Nova和Ironic所做的定制化工作并不是小事一桩,这会抵消掉OpenStack在开源方面所带给我们的好处。

但我还是觉得完全了解Neutron的细节非常重要,这是我目前唯一的念想儿。

对于物理交换机和服务器来说,安装部署服务器并不太困难,而且解决方案十分成熟可靠。而自动化工作却需要很多工具配合工作才能完成。从我的经历来看,大多数基础设置部署工作最容易出错的部分就是网络部分的自动化。你看,物理交换机的操作系统还存在很多不足之处。对当前的自动化工作和API的交互的支持显得捉襟见肘。其实,我用过的另外一款网络自动化工具的蹩脚表现是让我考虑使用OpenStack的主要原因。Neutron项目有非常令人振奋的使命:可以按照需求提供可扩展,不受制于任意一项技术的服务,包括相关的库。我也希望是这样呀!

但现实并不像所承诺的那样。根据软件定义网络(SDN,Software Defined Networking)的说法,大多数在基于虚拟机监视器(hypervisor)的虚拟网络下工作的项目并不是真实的交换机。不仅是因为对于交换机厂商来说严重过时的Neutron驱动,而且OpenStack最新的Juno版本的支持工作也力量有限。另外,Neutron使用了自身并不完善的IP地址管理器(IPAM),根本没有任何自己分配外部访问方式的概念,也没有提供关于IP地址管理方面的书面说法和权限。牺牲用户体验来适应Neutron这些不足,这是不能接受的。

经验三:OpenStack的Neutron项目支持工作并不那么完备、系统。使用之前要先看看自己的交换机能否适应。

这样一来,我们要如何应对?

长话短说。在圣诞节的前一周,我们丢掉了OpenStack,然后又花了三周的时间开发了一套定制化的自动化部署平台。在十二月初搭建好自己的IP管理系统后,团队就卯足了劲要将系统搭建自己定制工具上。而每个新项目都会有自身的使命。作为一家公司,我们的愿景是不断进取,并且我们觉得,在调查和部署OpenStack的过程中,解决了存在的大部分问题:构建了一个灵活且能提供服务功能的IPAM系统(我们管它叫Magnum IP)。在设施管理平台和物理基础设施之间,我们还建立了用户和权限模型。

有时现存的东西并不一定是最好的,也不一定能满足自己的需要。我们使用OpenStack部署packet.net的过程就完全说明了这个道理。同时,我们也会努力发布自己的Neutron插件,与OpenStack项目的发展相适应,我们现在正在做。

之后的一周时间,我们最终完成了CoreOS系统的安装(这也是在考察了Ubuntu,Debian和CentOS后做出的决定)。工作精益高效,对变化反应迅速,对系统记录详尽,这样我们可以做一些高级功能和高可用性工作,而又不会影响到用户体验,这让我感到激动不已。我能说自己工作学习两不误吗?

http://www.csdn.net/article/2015-01-26/2823694

18 1月

在2015年,我们会看到SaaS怎样的转变?

文 / Omri Erel,walkme.com广告与绩效营销的负责人,让SaasAddict致力于寻找新的,创新性的道路来充实软件服务,使初创企业获得了成功。

原文链接:http://saasaddict.walkme.com/saas-2015-new-shifts-will-see/

又到了回首过去,展望未来的时刻了。对大事小事来说,做这样那样的预测都让人觉得有点儿傻。科学技术瞬息万变,变化之中体现出了发展的趋势。某项新技术的应用过程会比最初预想来得要缓慢,所以有时站在全局的角度审视事物也是很重要的。新年就是这样的好时机。

在2015年,我们大致可以看到SaaS(软件即服务)的发展趋势会遵循这样的轨迹:企业和客户之间会存在更多的选择。尽管我们心里企盼平稳,但是在市场,销售和产品研发领域,特别是云计算相关领域仍然会发生持续的变化。

我们在新的一年里会看到SaaS五大发展趋势:

1. 企业会在个体消费研究方面加大投资规模
目前很多对消费者的研究还停留在静态的方式上,比如通过问卷调查和对原始数据进行分析。更多的企业会在个性化定制服务方面加大投入。这些企业往往会通过社交网络,大数据技术的应用以及直接的接触(电子邮件和社交媒体)来了解客户的需要。像购买动机,生活方式以及内心需求这样的细节都很重要。

营销策略的关键是要提高客户的满意度,激发客户的品牌价值意识,所以营销不仅仅是一种服务。

2. 云数据服务将会赶超传统意义上的存储
Forrester Research分析,相对传统的前置应用,微软公司将会从其云服务领域获得更大收益。传统的前置应用受限于自身的前置存储空间,而云数据服务则更加开放。尽管云数据服务成本相对低廉,但企业为了获得有效的发展,还会研究去缩减其开支。

云数据服务需要提防的一点是其合法性问题。希望企业花重金来做好数据的安全工作,避免数据外泄。

3. 更多的SaaS应用会行业化定制
像医疗卫生行业,制造业以及零售业将会开发出更多适用其领域的应用程序。这样做面临的挑战之一就是要承担起客户更深层次,更复杂的体验工作。但在开发新的功能时,企业在特定领域SaaS所具有的用户基础会使企业抢得先机。同时对用户也有好处。这种趋势不容小觑的原因是用户对特定领域相关应用的需要日益增长。在任何一个领域,通用的应用软件都会避免变得过于复杂。过于复杂会提供给用户不切实际的服务而与用户脱节。

4. 多重租用的可选方案将会出现
允许多个用户共享一个应用对于管理云服务数据是有行之有效的,而传统认识是让多个用户使用,具有各自的界面。多重租用则具有更个性化的用户体验。例如,salesforce.com为企业所提供的新服务“Superpod”。这使企业在自己的数据中心拥有自己专用的基础架构,而不是连接到一个单独的服务器。

这些新的混合服务给企业通向未来提供了更多可选项,为系统的开发工作提供了更多的创新空间,这样就解决了云服务市场存在的瓶颈,也为用户提供了更多的选择。

5. 大数据分析更显突出
IDC的报告指出,在2015年DaaS(数据及服务)的应用量会呈现上升的趋势,消费额将达到2150亿美元。DaaS将利用云来提供服务。他们还预测,会有更多的企业使用大数据分析技术作为其商业及开放数据集的一部分。

云存储为企业的接入和整体存储容量提供了更高的灵活性。由于每单位云存储的相对成本在下降,越来越多的企业对大数据分析技术变得兴致有加,该技术则是实施开放数据集的绝佳机会。

http://www.csdn.net/article/1970-01-01/2823495

08 1月

编程语言易用性最低,却是迄今为止最强大的人机接口

文 / Andrew J.Ko:美国西雅图华盛顿大学信息学院助理教授。

原文链接:http://blogs.uw.edu/ajko/2014/03/25/programming-languages-are-the-least-usable-but-most-powerful-human-computer-interfaces-ever-invented/

这样的说法是真的吗?当自己破译一些神秘的错误信息,调试一些悄无声息的故障,或者给一些没有很好存档的函数提供正确的参数时,我经常会思考。上周我在对一个难以理解的PHP错误信息绞尽脑汁时,把这样的说法发到了推特上。但是,编程语言是否真的易用性差呢?

是还是不是,在推特上仁智所见。但我认为,只有部分缺陷是根本。举例来说,Jakob Nielsen[1]经典的易用性推测法,是关于易用性的一个粗略表征。用户界面其中一个最为突出的问题是缺乏系统状态的可见性:可用的接口应该提供用户输入状态及时和清晰的反馈,以便用户知道系统的状态以及接下来要做什么。当你编写程序时,会发现某个人所编写的指令集与这些指令对应的输出和对周围的影响有很大差异。事实上,即使一个简单的程序也可以有很多分支,也存在一些编写指令集的程序员无法看到的执行路径,而只有后来执行程序的人才能看到。再来说说延迟的反馈!具有复现性的全部文字记录,测试以及调试弥合了程序的命令与执行动作之间的脱节,更好地展现了一个程序执行时的行为。这些工具顶多为程序员认识程序提供了信息,因为程序执行过程固有的复杂性,这种认识需要花费大量的努力。

另一条准则是Nielsen的“系统应该对真实世界进行映射”:系统应当使用用户熟悉的概念,短语和比喻。而使用计算机术语表达思想是编程语言的本份。这可以通过标识符良好的命名,语言范式和结构的选择得到改善。你可能认为编程语言的发展是一个缓慢的过程,因而需要刻意去定义更好的抽象模型语意。但用计算机术语表达事物并不像人类思想那样凌乱和含糊其词。

编程语言可以产出非常实用的工具。事实上,编程语言研究人员向语言添加新的抽象,语义,以及尽力形式化的内容,是为了尽可能减少错误,最大化地使错误信息易于理解,有些人可能会争辩说,编程语言研究人员实际上在做什么?比如静态类型检查就是从根本上提供具体的,可操作的及时反馈。同样,Nielsen的准则“有助于用户认识错误、判断错误并从错误中恢复”已经不是通过语言设计来体现,而是通过精心设计语法高亮显示,源文件结构视图,类层次结构视图等这样的特征来体现。

还有编程语言可能超越图形用户接口易用性的其他易用性原则。举例来说,有什么更好的用户接口比编程语言更能支持撤销,重做和取消操作?当今的文本编辑器和版本控制器中,至少在设计期间,什么样的修改是不能够被撤销,重做或取消的?最优秀的编程语言大概是现有的最一致,灵活,简约和美观的接口了。大多数图形用户接口很难平衡这些设计原则,因为实现这些需要做出牺牲,以更好地适应现实世界。

因此,编程语言在某些方面可能缺乏易用性,但在工具设计中付出一定努力,编程语言可以接近图形界面的易用性。易用性方面的这些改进,能够大大提高易达性(accessibility),易学性(learnability)以及用户的使用效率。

现在来说第二部分:编程语言真的是有史以来发明的最“强大”用户接口吗?这取决于我们对强大的定义。这些编程语言当然是我们拥有的最具表达力用户接口,可以比其他任何用户接口创造出更多东西。

但是如果我们把强大理解为可以直接促进人们的特定目标,那么就会有很多任务,使编程语言变成一种蹩脚的工具。像发送邮件,视频聊天,玩游戏,阅读新闻什么的。这些事情最好由围绕这些活动及其相关概念进行设计的应用程序来支持,而不是由编程语言更低层的抽象来完成。从这个角度讲,编程语言可能是最不强大的用户接口。

如果说这个帖子有什么实在的东西,那么就是其隐含的概念,编程语言只是另一种类型的人机接口,是丰富且多样的用户接口范式设计领域。这里有一些有趣的暗示。例如,程序员也是用户,像HCI(Human-Computer Interaction)研究人员那样,他们一样需要像非程序员使用非编程语言接口那样去思考。在这两个领域我们没有发现更多不同的方法和文化,但问题和相关现象却显著地一致。

对于了解我和我工作的人来说,这些说法应该是不足为奇的。我所有研究的前提是编程语言即用户接口。这就是为什么,尽管我事实上主要学习代码,编码和编码器,但在攻读HCI方向的博士学位,而不是PL(Programming Language),软件工程或者其他一些与这些现象有关的领域。编程语言现在并将永远是我最着迷去学习和改造的一种用户接口。

[1] Web易用性专家,在丹麦科技大学获得了人机交互方向的博士学位。

29 12月

移动平台,一切仍然是敞开的

文 / Benedict Evans:拥有英国剑桥大学历史专业文学硕士学位,做过战略咨询以及移动运营行业股票分析师。

编译 / 白云鹏

原文链接:http://ben-evans.com/benedictevans/2014/4/7/in-mobile-everything-is-still-wide-open

移动平台对抗是非常有趣的,也是获得页访问量的可靠途径。但也逐渐形成为其次要面对的问题。到目前为止,苹果和谷歌两家公司以不同的方式平分秋色。斗转星移,苹果公司可能会推出价格低廉的手机,或者苹果开发者抢先转去做安卓开发。但这些都是老生常谈的话题,不必太在意。

对我来说,首先要面对的问题就是移动应用市场的庞大规模。从1.5亿各类非移动PC用户到3亿纯个人智能移动终端,这意味着互联网规模增大了两三倍,乃至四倍。这也意味着,互联网可以吞噬很多新领域,比如零售或支付。

基于这样的现实,我认为个人台式电脑与移动终端有三大区别:

“先Netscape”——桌面互联网很快成为了“web和其他一切”,20年都没有发生重大变化。移动终端不具备单独统一的交互模型。另外,我们拥有应用程序和应用商店,还有消息系统以及iBeacon,但都无一例外地还在变化。我们没有将其整合为一个稳定的方式。

“先PageRank”——这样复杂的局面,造成了移动平台的供求双方相互是敞开的。在Google的PageRank算法出现之前,我们还没有这样一个方法用于移动平台。对于任何相对PC网络浏览器更复杂和先进智能手机平台来说,我们也许从未有过一个统一的工具。

身份——智能手机是PC不曾充当的社交平台。它拥有地址簿和许多其它功能,但并不具有这些功能集合的清晰身份。PSTN号码?Email地址?Facebook账号?还是某些功能的一些乱七八糟的变换?

作为平台的所有者,苹果和谷歌两家公司将在塑造平台方面发挥作用。而事实平台之争已经结束,一切仍然是敞开的。你所见到的,以及自己是如何做的,拿出来分享吧,寻找和发现这些观点的大门都是敞开的。

28 11月

你能听到我说话吗?不行,我没安装那个应用!

文 / Matthew W. Meyer:软件开发人员,以优等成绩毕业,获计算机科学副学士学位。

编译 / 白云鹏

原文链接:http://www.mwmeyer.com/blog/can-you-hear-me-now/

在过去的10年左右的时间里,无论我们的沟通方式,还是我们的日常生活方式,都发生了很多变化。互联网的普及使人与人彼此联系更紧密,也改变了彼此交往的方式。我们目前正处于数字网络初创期的“淘金热”。我始终将新近的应用程序更新到最新,自称使自己轻松的生活更轻松。

结果是我对技术的现状根本不屑一顾。传统的载波通信技术(语音/短信)有很多方式可以去改进,使之现代化。每次我起身懒洋洋地用手机去回复短信时,都忍不住会抱怨。从技术角度说,我肯定可以做这件事。

软件方面的事情就是有些微妙。MightyText只是提供这类功能的众多应用中的一例。这就不得不说OTT[1]应用的崛起。当电信运营商把持他们的用户来赚钱,而非改进其通信体验时,不计其数的软件公司则腾出手来打造基于这些运营商及整个因特网的“Over The Top”服务。像GroupMe,Viber,WhatsApp,iMessage,Hangouts和Skype。这些只是业内规模较大的参与者。

如果我要跟一位朋友视频的话,那就糟了。我首先要确认对方下载了应用,创建了帐号并且登录,确认正常工作等等。对于电信运营商来说,这个问题似乎很早以前就解决了。而事实上,蹩脚的短信服务仍旧占领主导地位的唯一原因是,它有效保证了每个人很容易访问该服务。

未来的运营商只作为网关的作用越来越明显。无论是当今基于超文本传输协议的互联网,还是未来演变出的什么网络,光纤和光谱为因特网提供了连接。主要的市场资产运营商经过多年的发展,耗费了数百万美元,持有物理基础设置。这也是为什么像AT&T和Comcast这样的公司,初创公司在相同的商业模式下无法与其匹敌的原因。

显然,当电信运营商开发健壮的软件来提高自身服务的同时,他们就无力维护这些基础设施。这样一来,以软件为核心的公司间展开了迅速竞争。遗憾的是,人与人之间的沟通在互联网上一直在演变,传统的语音电话,短信已经被淘汰。

这些以软件为核心的公司没有去和其他竞争者互操作的动机。这对于一个封闭性的企业来说也许是好事,但对于全球性通信公司来说就不太好了。

虽然我觉得满足了互联网富通信(语音,消息和视频聊天)互操作性的某种核心通信标准还可以做得更好,但这不是必须的。我无法在业界提出一套可以解决这些互操作性问题的有力意见。而这对于向第三方开发人员提供API的OTT应用来说,看起来是向正确的方向迈了一大步。

说了这么多就一句话,我主张开放的统一通信。统一通信服务不仅让我轻而易举地在任何设备上进行通信,还可以统一三种主要的通信格式(语音,视频和消息)到一个平台。通过发布他们的协议,维护访问平台数据API,开放的通信服务就能让我选择不同的第三方应用和客户端。

数字通信迫切需要具有互操作性的发展方式,可悲的是,我还没有看到相关迹象。

 

[1]OTT是指”over-the-top”服务,通常是指内容或服务建构在基础电信服务之上从而不需要网络运营商额外的支持。

08 11月

我不想成为真正的程序员

文 / Anas Ambri:就读于加拿大Concordia University,是一位志向远大的软件开发者。

编译 / 白云鹏

原文链接:http://verybadalloc.com/blog/2014/03/18/i-dont-want-to-be-a-real-programmer/

我偶然发现了一篇博文,博主提出了成为一位更出色程序员的方法。据他所述,使用最热门的技术和语言不会使你成为一位更棒的程序员,那只会让你学习新工具。我对此深表认同,感触颇多。就拿满眼已经被开发出的东西来说,我并没有机会参与其中。

我们大致梳理一下:我非常喜欢使用橡皮鸭调试法(Rubber Duck Debugging),三年前,这个过程变成了过山车般刺激的编程之夜,还有第二天调试程序时的沮丧,以及项目结束时聚会的释然。在业余时间,我花费在编码上的几个小时是一个礼拜以来最愉快的时光。我喜欢尝试新鲜事物,乐于在白天多次提交代码,对编程马拉松(hackathon)不厌其烦。总之,我已经尽力尝试了“软件工程”中的许多美味,从嵌入式软件到web和移动应用的开发。

冒充者

然而,像许多其他程序员同胞一样,我感到自己毫无价值。这并不是某一天冒充者综合症(imposter syndrome)让我感觉自己所做的一切都是运气使然。甚至在写上一段文字的时候,我都不禁思考自己可能是自我感觉良好。尽管我已经习惯了这种持续恐惧带来的糟糕感觉,但与之相伴的不悦之感却时常困扰着我。

因为我们都很差劲 

你知道TJ Holowaychuk吗?他被个人崇拜的光环笼罩,很高产,自己一手搞定了Node.js中的很多类库。

如果你有哪一点像我,也想变成一位像TJ Holowaychuk那样出色的人,你要更舍得为掌握新的编程语言付出额外的努力。为一些额外的项目搭上无数的夜晚,并无处不在地讨论这些项目。拥有生活比起献身技艺已经微不足道。为了还未完成的项目坐卧不安。如果你有哪一点像我,那你才是想成为一位真正的程序员。 

真正的程序员

一位真正的程序员,是那种热爱编程并乐意为此付出的人。真正的程序员对编程乐此不疲,不会停下额外的项目。真正的程序员会掌握所有形式的编程方法,并且对自己所喜爱平台的API可以倒背如流。要想成为一位真正的程序员,你必须要沉下心去增长自己的知识和经验,并对此不计回报。

在过去的三年中,我时常梦想成为一位真正的程序员。谁又不想呢?你的代码不仅可以给带来名誉和荣耀,而且可以影响许多程序员同胞的生活。相当一段时间,我感觉自己就像一位真正的程序员。

然而,我学的新东西越多,我就越觉得自己不行。当我与JavaScript语法错误奋战的时候,其他人则在重定义我们编写客户端所使用的方式。类似的问题,我无能为力。无论我花多长时间去探求,我永远不会接近成为一位真正的程序员。

结语

我也许只是正在理顺这样一个严峻的事实,自己是无法成为一位真正的程序员。当然,周围也有很多真正的程序员,他们情愿每周80多个小时的工作量,我感觉这些人愿意将他们的人生投身于编程,我对此钦佩有加。

我?我会继续做自己的事情:尽力在这几个小时内产出更多代码。另外,对成为一位真正的程序员这件事评价也过高;显然,当前最热门的新事物是掌握精益软件开发(lean software development)

http://www.csdn.net/article/2014-05-30/2820031

14 9月

编程为什么困难

文 / Joe Armstrong:Erlang语言最初的设计者和实现者,他拥有瑞典皇家理工学院博士学位,是容错系统开发领域的世界级专家。

编译 / 白云鹏

原文链接:http://joearms.github.io/2014/02/07/why-programming-is-difficult.html

很多年前,我认为编程很容易,随着岁月的流逝,我已经意识到编程并不那么容易。这是围绕编程是什么,程序员做什么这两方面感知上的缓慢转变。

起初我还以为编程只是告诉计算机做什么,这样的编程是相对容易的。编了二十多年程序后,我感觉这种编程相当简单。

c

定义一:程序是将输入转化为输出的东西
程序员是编写程序的人,编程是编写程序的行为。

现在让我们给程序定义添加一些约束。

定义二:程序是将输入转化为输出,并受到以下限制的东西。

  • 该程序的输出结果要悠美。
  • 该程序的输入要悠美。
  • 该程序要悠美。
  • 该程序的输入要恰当并被正确归档。
  • 该程序本身要恰当并被正确归档。
  • 该程序通过测试并被证明是正确的。
  • 该程序正在解决中的问题要恰当地说明。
  • 该程序存在的其他问题要恰当地说明。

带着这些约束条件进行编程就变得十分困难了。

对于特定的问题,一些限制可以放宽。

不需要维护的程序
我们通常编写只要输出结果的程序,这种情况,输入和程序本身将来就不需要维护,所以不必有特别漂亮或很好地描述。

我写的关于Erlang语言的书就是这类情况。书一旦出版,就不再需要撰写和维护。结果看起来不错,但输入是一堆乱糟糟的XML文件和不会再被维护的测试程序。

在重印的时候,这本书的勘误信息和必要的修改只涉及输入微小且简单的修改,即使输入没有被很好地归档。

必须要维护的程序
对于必须要维护的程序来说,程序的输入和程序本身,则要悠美并很好地归档。

我与一位Web程序顾问聊天。他说只要程序的输出看起来是正确的,那么客户就会认为项目结束了,项目经理就会投身于下一个项目。

这里没有认识到,在开始下个项目前,网站不仅应该看起来不错,而且代码也要整洁并被归档。当然,也没有时间去这样做。因为这是要在未来进行维护的项目。

使编程困难的其他原因

  • 修复本来以为不可能坏的东西
  • 没有时间学习
  • 恶劣的编程环境

这些因素都是“时间的盗贼”。

修复本来以为不可能坏的东西

通常,我会使用自己并不十分了解的软件去解决特定的问题。

如果运气好,我使用的程序有准确的使用描述。而更多的情况是程序要么没有描述,要么是错误的描述。

如果文档里面的描述与事实不符,你会怎样?如果写文档的人就在你旁边还好,否则只能借助Google或者从源码中寻找答案了。

进了Google这赌场想搏一记,这样的查错经历真是不堪回首。好容易Google到一篇帖子,有个倒霉鬼恰巧和我遭遇了完全一样的问题。我的心脏激动得跳个不停。我用颤抖的指尖把这找来的咒语输入,以为这样诅咒就能解除……结果,还是不行。问题依旧。

为什么我的修复工作这么不顺呢,难道恶意之神有意盯着我?或者我身处区域的物理规律与别处不同不成?其实不然,两台机器的初始状态是不同的,所以在此机器上修复了缺陷的高招,在状态不同的彼机器上就不一定灵验。

修复坏掉的东西会令人感到加倍沮丧的,因为即使问题消失了,你也不知道是否解决了这个问题,或目前的效果是否是你所做的修改导致的。

顺便说一句,这样的问题需要我大部分的时间去处理。我曾经用一周多的时间去修复坏掉的LDAP服务器,而我的老板禁止我自己去做新的。但后来我还是自己做了一个。

说实话,这并不算一个完整的LDAP服务器。我想要的仅仅是两行命令就能工作,这是很容易修复的。

如今,我觉得去实现那些过时的和有悖常情的协议没有什么特别的喜悦,而重新实现它们往往是最快的进步方式。

不通过学习解决问题
我很懒,是个没有出息的懒鬼。当我试图使用LaTex对一个图表做排版时,我不想去阅读长达391页的说明书。我知道你会指责我懒惰,品德不健全。我明白自己应该首先阅读说明书,但我为了文档中的一个图表用十分钟读完一个391页的文档是不现实的。

恶劣的编程环境
工作场所的设计使编程更加困难,无隔板的开放式办公室那嘈杂的环境,破坏了我们的注意力,移动电话的打扰,以及互联网都会分散我们的注意力。

幸运的是我们还可以有可去的地方,那就是睡觉。很多编程问题是在睡觉过程中解决的。

有两种方法。首先将考虑的问题记住,然后睡觉,第二天醒来一些问题就被解决了,很容易。

另一种方法是睡觉前用tweet,在网上发个帖子,第二天就有人将解决方法发给你了。

做一名优秀的程序员需要很长的时间,你需要学习很多东西,当遇到问题的时候,需要知道向谁请教。

令人吃惊的事实
我写完这篇文章的时候,拼写检查工具竟然罢工了。就在我抱怨自己花费大半辈子修复的东西本不应该坏掉时,Emacs上的语法检查工具就坏掉了。

我的Emacs拼写检查器在这台机器上老老实实地工作了好几年。

我并不相信恶意之神,也不认为我这里的物理规律有什么不同。

一切都正常,我不知道为什么拼写检查器会坏掉,而我什么都没做。

幸运的是,用了十一分钟在Google这赌场搏一把后见效了,其中第二条方法解决了我的问题,而我仍然不知道Emacs中为什么找不到Aspell了。人生短暂而有太多不甚明了的事情。

我想有些东西我们永远都不会知道。

从长远来看,选择快速的方法处理问题是个灾难。

拿制作文档来说,我就在TeX/LaTex、XSLT-FO和我的Erlguten之间犹豫不定。

大约每三年一次,我都会有强烈的愿望,将自己所有的文档直接写在附录中,而后唯一做的事情却是深呼气,等待这种感觉消失掉。

如今因为我们可以让机器去做枯燥和危险的事情,我们反而没有更多的时间去做事。

我问过我的老板,他是否需要漂亮的幻灯片来演讲。他说需要,但要我明天之前给他。我权衡了需要时间去学习的几个方案,最终选择了PowerPoint。

http://www.csdn.net/article/2014-03-31/2819060

26 8月

我并非不爱交际,而是很忙

文 / Marco Tabini:作家,也是位半路出家的商人,近些年在php[architect]Macworld发表过文字。

原文链接:http://blog.tabini.ca/i-am-not-an-introvert–i-am-just-busy-/

编译 / 白云鹏

数周以来,我一直在与一个非常奇怪的BUG做斗争。我创建了一个服务端进程,用来打开一个与服务端的持久连接,来验证终端用户,然后执行一系列的流操作。

令人匪夷所思的是,这个进程发生了套接字泄露。尽管不是很频繁,但却是个问题。运行一段时间后,机器的资源就要被耗尽,由于队列请求得不到满足,也变得不稳定。

这让我感到崩溃,我无法弄清楚问题所在,把时间花在了重启服务和与代码对视上。且听我慢慢道来……

我不在办公室,也不在办公桌前,电脑也找不到了,这是什么鬼地方?

周围还有一些人,非常嘈杂,看起来像是个什么聚会。

我的手为什么是湿的?你瞧,冒着泡儿的黑色饮料,看起来像是可口可乐。就是可乐。喝起来冰冰凉,但却没有冰。白色的纸巾已经被浸透,边缘部分也被我撕掉了,我猜想我应该到这里会儿了。

我想起来了。这是Dan邀请我去参加的公司聚会。Dan这个人不错,但我们极为不同,他很健谈,我想这大概是因为他是位保险从业人员吧。

我至少用不着穿正装去参加聚会,也不会穿得像那个等电梯的人那样呆板,不过说真的,谁会穿个帽衫去参加公司聚会呢?
没人在乎的,这个人在等电梯,所以他可能已经上了电梯。不过你瞧,老兄,别再看iPhone上的Facebook帐号啦,否则你会错过电梯的。灯已经灭掉了,电梯马上就到……可你还是错过了,你可真够笨的……

不会吧!

这个人根本没注意电梯,他还是错过了。

我敢说你已经明白我的代码问题出在哪里了。如果远程服务挂起,而我却等待自己的认证令牌,我的应用就不会提醒,报错,这样就会发生套接字泄漏。

就是这样,两个星期的痛苦挣扎后,在满是保险销售人员的办公室我想出了解决问题的办法。

我需要马上离开去验证这种办法是否奏效。我正准备悄悄离开的时候,Dan和另一个人面带微笑地走了过来。

诶,我想我是走不了了。不知道他们是不是冲我来的。可你知道吗,Dan,我不能再聊了,我的想法就像被挂起的线程一样,不能再废话了,否则随着时候的推移,我会忘记的。

嗨,这位是CEO。嗯,很高兴见到你。一番寒暄后,我不能忘记那该死的电梯和认证令牌的事儿。没错儿,Dan是个不错的家伙。哦,他跟您说过我吗?真不错,我敢肯定他没跟您说过您实际上正在阻止我解决我那该死的问题。

别管怎么说,他们离开了,我可能搞砸了,他们可能认为我不可思议,不合群。我真的不需要在意这些,因为我最终修复了那个愚蠢的BUG。

在其他人用什么高招变着法儿地浪费我更多时间之前,我就要按下电梯的按钮。我肯定会这么做。我还有BUG要修呢!

http://www.csdn.net/article/2014-04-15/2819317

26 7月

我的第24个生日

文 / Arpit Jalan:一位科班出身的电气工程师,还是一位有激情的电脑软件工程师。
原文链接:http://techapj.com/24-birthday/

编译 / 白云鹏

此刻我正一边喝茶,一边装模作样地阅读Hacker News,但即将到来的24岁生日伴随着恐惧侵入的我脑海。

我并不希望过24岁生日。这是为什么呢?

在印度,对于一位初入社会,24岁,并拥有学士学位的人来说,他将会是位完美的新郎候选人,所有的亲属都在问同样的三个问题:

你在哪儿工作?

你的薪水是多少?

你打算结婚吗?

我是说,我需要一些私人空间,我才24岁,还没有做好这些担当的准备。

在印度,人们很难相信通过自己创业获得成功。“创业者”几乎与“失业”划等号。而如果你没有工作的话,那就准备听到那些流言蜚语吧。

这里绝大多数人没有听说过Github,没有人关心其上的开源代码所做的贡献,也没人关心代码的质量有多好。这里只关心两件事:

  •  你毕业于哪所学校
  •  你所在公司的品牌名称

如果你达不到上述任何一项要求,那么你将毫无价值。

幸运的是,我的父母支持我从电气行业转到软件行业,激励我追求自己的梦想。

直到18岁我才感到责任的降临,这以后的每个生日都会提醒自己还有许多目标需要实现。

18岁以后,我会思考过往的经历,对现状是否满意,这是我所期待的生活吗?我无愧于自己和父母吗?

直至最近三年,我才回答了上面的问题,但是答案是“否”,我对过往的经历和彼时的状态都不满意。因为我没有追随自己的直觉。

但这个生日我有一种满足感,我能感觉到自己在正确的方向,做自己坚信的事情。对我来说,这是最重要的事情,我正在做自己所热爱的事情(开发软件,研发新技术等),别无他求。

在这一点上,我想引述乔布斯那段最鼓舞人心的颂文:

你的时间有限,别浪费生命过别人的生活。不要被教条所束缚,因为那是别人生活的目的。别让其他人的不同意见压过你自己内心的声音。最重要的是,要勇于追随自己的心和直觉,它们其实早已知道你想要成为什么,除此以外的都是次要的。

此刻,我已年满24岁,伴随着脸上极度激动的表情,我在终端键入了这条命令:

git push origin master

此帖终于大功告成,舒了一口气!

18 6月

10岁起编程,并不认为自己是“黑客”

文 /  Liz Denys:毕业于麻省理工学院,数学和计算机科学与工程双料学士。

原文链接:http://blog.lizdenys.com/2014/01/03/i-do-not-feel-like-a-hacker/

编译:白云鹏

我10岁的时候在学校接触到了Logo语言,用它几乎对每一个练习进行泛化(这都是一些同学没兴趣做的事)。但我并没有受到老师的表扬反而被批评不务正业,因为他们认为这更难去评分。

第二次接触编程是13岁时,我开了博客,穿梭于其他人的博客之间,学习了HTML和CSS标记语言以及PHP,当时我还没意识到这是编程的另外一种形式。

第三次接触编程是16岁时,帮高中学校辅导员开发一套内部注册系统。这是我第一次做被称为“编程”的事情。虽然我承担了大部分工作,但另一个人却得到了几乎所有的称赞,这使我感到沮丧。

大学一年级,第一次所有人对我在编程方面表露出肯定。我果断从数学与经济学转到数学与计算机专业。我意识到,之前所经历的消极氛围,不是因为世人对编程不感兴趣,而因为我是女孩。

我比当时年龄相仿的女性有更多的机会,但经历却不是那么“正面”,这使我感到气馁。许多成年女性从未意识到“编程”或“黑客”是女人可以做的事。对她们来讲完全是被忽视的领域。我有时会认为软件领域的性别歧视不复存在,至少正在隐去。但可悲的是,这些问题并未消失。

美国著名技术作家Paul Graham曾说:“天知道如何让一位13岁的女孩对电脑感兴趣。我们无法使这些女性以黑客视角或从Facebook来看世界,因为在过去的10年间,她们根本没有过黑客行为。”

我不认为Paul Graham所说恰如其分。很多女性在过去没有“黑客”行为的问题,很多男性工程师也同样存在。有些人是有机会在早期成为“黑客”的,我便是幸运儿,但彼时我并不晓得。我认为自己有资格称为“黑客”的理由是早年有广泛的编程经历,但又感到永远无法成为真正“黑客”,因为我不符合人们对“黑客”的传统印象,比如我的着装、规律的作息

以及我不是男性。我想知道,过去10年一直编程的女性,有多少人一直以来都没能意识到自己是黑客呢?

女性在“黑客”群体中缺乏代表性不是因为她们缺乏兴趣。上面所说的被忽视以及性别歧视问题逐步地将女性排挤出了这个圈子。我不知道如何完美地回答怎样让13岁女孩对计算机着迷,但我明白首先要让她们在这个领域不被忽视。除了无法自我认同“黑客”的刻板印象,开始编程的年龄过晚也导致需要加倍努力工作,快马加鞭成为一名“黑客”。女性和还没有成为“黑客”的人真的需要花费必要的时间去追赶。

http://www.csdn.net/article/2014-03-17/2818795

25 5月

蔡格尼克记忆效应:做好工作的科学关键

文 / Alina Vrabie:喜欢发现生活小妙招儿,并与他人分享。以给他人的生活带来便捷为己任。乐于各种形式的沟通,来自罗马尼亚。

编译 / 白云鹏

原文链接:http://blog.sandglaz.com/zeigarnik-effect-scientific-key-to-better-work/

如果你和我们一样,一直在寻找更有效的工作方式的话,那么,你要真心感谢蔡氏效应给了我们答案。这里不得不提一位在立陶宛出生的心理学家的名字,Bluma Zeigarnik。20世纪20年代,她在博士论文中首次描述这种效应。在餐厅观察服务员工作时她发现,当食品摆到客人面前后,似乎只有未完成的订单被服务员记住。

她回到实验室后对此进行了科学实验。实验表明,较未完成的任务,90%被中断的任务被成年人较好地回忆了起来。孩子们则更容易回忆起未完成的任务。

如果你留意周围,会发现蔡氏效应无处不在。特别是在媒体和广告中。正如作家海明威曾经所说,“等待下一天的到来是很难熬的”。但蔡氏效应实际上可以对你的工作效率产生积极的影响。

蔡格尼克记忆效应与生产力

生产力的关键是一段时间专注地工作,同时避免做多个工作和被打断。你放弃一项未完成的任务转而去做其他事情会使你感到焦虑。由于多项任务很容易将你的注意力从一项任务转移到另一项去,由于离开了上一个未完成的任务,因此大脑无法完全专注于新的任务。这也是像番茄时间管理法(Pomodoro Technique)这样的高效方法学行之有效的原因。

 拖沓者的好消息

蔡氏效应对拖沓者是个好消息:如果你真的打算完成一项任务,那就不大可能拖沓。一旦开始,你便更倾向于完成某件事。在面对一个大的项目时,不要想着从最难的部分着手,而要先从当下易于把控的部分开始。蔡氏效应告诉我们击败拖沓的关键是开始的地方。

 预期回报与蔡格尼克记忆效应:为什么8小时工作制不奏效

一项研究表明,蔡氏效应会被预期回报削弱。好比8小时工作制,一天工作的结束就像任务被中断。一旦任务被中断,那么8小时的工作酬劳就是预期回报。研究表明,预期回报会削弱蔡氏效应。换句话说,8小时工作制实际上使我们疏于工作。对付这种自满情绪的方法是进行更灵活的工作安排并提供工作与生活平衡的健康奖赏方式。

http://www.csdn.net/article/2014-03-28/2819029

27 4月

我的第一份工作:首日之中失而复得

文 /  Steve Blank:美国加州大学旧金山分校讲师

编译 / 白云鹏

原文链接:

http://www.linkedin.com/today/post/article/20131029100222-95015-my-first-job-fired-and-rehired-on-day-1?trk=tod-home-art-list-small_1

我的第一份工作是被聘为ESL实验室的技术人员,去支持培训部门。打理好在密歇根的生活后,我花了五天时间驱车前往加州开始工作。

报到当天,一位满怀歉意的经理对我说,“我们上周一直试图与您取得联系,而打算雇佣您的培训部经理是没有得到授权这样做的,他已经被解雇了。对不起,我们事实上没有雇佣您的意向。

此刻,我惊呆了。因为我已经辞掉了工作,处理掉了房子,将我所拥有的一切打包在我的车里了,并且在硅谷举目无亲,身上只有200美元现金。我要求与新任培训部门经理通话,对方的答复是他们没有预算雇佣一名实验室技术人员,但需要一名培训讲师。

工作失而复得

数次会议后,我认为培训部门前任经理被解雇,主要的原因是:

  1. ESL将重大军事情报收集系统部署到了韩国。
  2. 没有培训陆军安全局如何对系统进行维护。
  3. 没有编写为期10周的培训课程。
  4. 培训应该被安排在6周后。

与上级的谈话中,我指出,我曾经在空军做过一些非正式的教学活动,了解所需军用维护培训的情况。我最终说服他们给出了不错的价码——以一位实验室技术人员的薪资来聘请我作为培训讲师。因此,我的工作在ELS失而复得,而此时的身份是一名培训讲师。

虽然得到了这份工作,让人为难的是,我需要在6周内编写一个为期10周的培训课程。还有运维手册。我的时间要被设计工程师、测试和部署团队分开来用。我领悟了系统原理图后,想出了把系统理论、运营和维护融合成一门课程的办法。

在这之后,我则如饥似渴地投入到工作当中。部署团队的负责人将当时还单身的我指派到了他的团队,一起去了韩国工作。

我的一位室友对我说:“你并不是特别聪明,只是在很多方面有所表露”。这就是他对我得到越来越多有趣工作的见解。这些年来我意识到他是对的。

而彼刻的我已经在没有任何人扶持的情况下独立生活,独自来决定自己下一步该做什么,面对和处理生活中的不确定性。

没有人会告诉你,你在从事一个没有前途的工作,也没有人会说,你要继续下去,或者告诉你要拿出更多的时间来陪你的家人等等。而职业道路并非一条直线,乔布斯说过:Stay Hungry,Stay Foolish。

与你分享的经验教训:

  • 相信你的直觉;
  • 展现自己,增加你的胜算;
  • 相信自己的职业节点会被连接起来;
  • 投入激情,而不要热衷于名片上的头衔。

http://www.csdn.net/article/2014-03-24/2818944

20 4月

有生活品味地编程

文 / Andy Brice:在计算机软件行业拥有逾25年专业经验,兴趣领域包括跨平台软件开发、软件优化和商业软件开发等。目前经营自己的公司并提供IT商业咨询服务。

编译 / 白云鹏

原文链接:http://successfulsoftware.net/2013/11/06/lifestyle-programming/

“如果一个人日出而作日落而息,并且随心所欲,那么他就是一位成功的人”——鲍勃•迪伦(Bob Dylan),一位极具历史影响力的美国摇滚、民谣艺术家。

我就是这样一位富有生活品味的程序员,自己开办了由个人经营的软件生意,自由、有意义还可以养活我自己。

“lifestyle business”这个词经常被那些风险投资者们糟蹋。他们会不断地嗅寻给予他们十倍或百倍回报的下一块“肥肉”。通过投资一些高风险初创型企业,他们就可以将自身的整体风险降低到令人心安的程度。而对于被投资人,他们的整体风险则大相径庭。硅谷创业之父、风险投资家、《Hackers & Painters》(《黑客与画家》)作者Paul Graham也承认:

“在每轮投资中最多只有一家公司对我们的收益产生重大影响,而其余的公司仅仅是陪练”。

然而高风险,高回报的风险项目令人垂涎三尺。谁又能抗拒像沃兹(Stephen Gary Wozniak)乔布斯(Steve Jobs)这对奇特的搭档,在他们的车库中缔造了全球最具价值的公司这一英雄史实的诱惑呢?

实际上,多少钱是你所需要的呢?钱能够让你获得快乐吗?一个人一天吃几顿饭?而且,你又能一口气开几辆车呢?大量的研究表明,一旦满足了生活的必须(吃穿和住所),幸福与金钱并无太大关系。“快乐水车”理论(hedonic treadmill)也印证了没有什么样的享受可以使人持久快乐。

经营一家可以养活自己或几个人的小软件公司根本不需要很多钱去购买硬件和软件,需要的仅仅是一个想法,良好的开发技能和充足的时间和毅力。许多lifestyle business开始的时候都是创始人利用晚上和周末的时间开发产品,而同时做了一份全职工作。

那么lifestyle business需要多少钱呢?这得具体情况具体分析。许多失败的例子,通常是因为缺乏市场。但我还认识一些少数将买卖做了起来的lifestyle programmer。我相信他们中的很多人都赚得盆满钵满。就我个人而言,通过销售我自己的软件,相对与我曾经为别人打工的时候,收入平均上涨了很多。

如果你有足够的钱来支撑花销,那做一位lifestyle programmer将会是很美好的生活,可以比较随意地支配自己的生活,随心所欲。

如果你想拥有任何真正的成功机会,那么你就需要在市场营销方面花费大量的时间。我兼任的客户支持工作使我高兴地知道很多人都在用我的软件。总而言之,这是很棒的生活方式,朝九晚五的工作无法替代。

http://www.csdn.net/article/2014-03-21/2818897

29 3月

敏捷已死,敏捷性万岁

文 / Dave Thomas:敏捷软件开发宣言创始人之一,《程序员修炼之道》与《Programming Ruby》的作者。

译 / 白云鹏

原文链接:http://pragdave.me/blog/2014/03/04/time-to-kill-agile/

十三年前,为了分享共同的软件开发理念,我们十七位中年人聚集在犹他州的滑雪胜地雪鸟(Snowbird)雪场。我们想知道是否能把这些理念描述出来。

用了不到一天的时间,我们将这些理念简单罗列,作为敏捷软件开发宣言(Manifesto for Agile Software Development)将其公布:

个体与交互胜于流程和工具

可用的软件胜于详尽的文档

客户合作胜于合同谈判

响应变化胜于遵循计划

我为我们的所作所为感到自豪。我想这个宣言可以帮助开发者摆脱一些八九十年代出现的不良做法。

这次会议以后,我就再也没参加过任何关于敏捷的活动,也不是敏捷联盟的成员,也不做任何“敏捷”咨询业务。也没有参加宣言发表10周年庆祝活动。

这是为什么呢?因为我觉得任何这些事情都不符合我们所发表宣言的精神,有关敏捷的会议与芭蕾舞会没什么两样,并且让我吃惊的是,围绕宣言的四点形成了一个产业群。

遗憾的是,事实证明了我是对的。“敏捷”这个词已经到了被颠覆的地步,敏捷社区看起来像是顾问和商家兜售服务和产品的大舞台。

所以“敏捷”这个词该下课了。

“敏捷”不应该是名词,而应该是一个形容词,它有其相应的含义。

一旦宣言走红,就像环保和天然一样,敏捷这个词就会变成营销术语。因为它变成了一种品牌,会被滥用而失去原有的含义。

这伤害的是每个人,我则对开发者的伤害尤其敏感。敏捷不是简单地编写代码,而是开发者本能地寻求可以帮助他们更有效创造价值的方法。我则仍然坚信,信守这个宣言会有意于开发者。

而一旦敏捷这个词变了味儿,开发者就不会再用它作为实践中的有效指南了。

转向右边

我们再来看看宣言中的四项理念:

个体与交互胜于流程和工具

可用的软件胜于详尽的文档

客户合作胜于合同谈判

响应变化胜于遵循计划

左边的短语代表理想,左右之间选择,敏捷软件开发者则偏爱左边。

从顾问和商家那里看到的则是“敏捷”这个词的贬值和滥用。当然,对于一些顾问,事实可能也不尽然。

回归根本

下面是敏捷方法应该做的事情:

做什么?

  • 找到问题
  • 朝着自己的目标迈出一小步
  • 基于获取的信息,调整自己的认识
  • 重复上述步骤

如何做?

当面对两个类似的选项时,选择容易修改的那个。

上面的四条准则和一项实践原则概括了高效的软件开发方法。

这些准则和原则都是动词短语,它们告诉了我们做什么,如何做。

我也要说两句。让我们摒弃没有敏捷精神的说法,换成一个描述我们应该做哪些事情的词语。

让开发带有敏捷性

你不是一位敏捷程序员,而你是一位具有敏捷性的程序员。 你所在的团队不是敏捷团队,而你的团队显露出敏捷性。 你不使用敏捷工具,而你使用工具增强自己的敏捷性

敏捷这个词很容易联系任何事物,而敏捷性则不容易被挪用。

你不能购买经验,只能自己去实践。

让付出得到保护

总之,行胜于言,但好的称谓有助于高效沟通。

我们已经失去了敏捷。让我们守住敏捷性,让它保持原本的含义。

31 1月

软件测试人员的基本修养

见到题目,你或许会想起电影《喜剧之王》中尹天仇所看的《演员的自我修养》一书,还有那句经典的台词:我是一个演员,跑龙套的也是演员!更会对影片中周星驰所扮演角色对梦想成为一名出色的演员而孜孜以求的情节记忆犹新。人们说行行相通,一通百通。我们这里就说说测试人员的基本修养。

代码编写,不可或缺

乔布斯说:Design is not just what it looks like and feels like, design is how it works(设计不仅是外形和感觉,设计关乎如何运作)。那么可以说测试亦是如此,测试不是简单地拿过来用一用。当开发人员将开发完成的软件提交到测试人员那里以后,测试人员首先需要做的是迅速透彻地理解软件的功能。你会说这是需求讨论阶段已经介入的工作,没错,但除了理想状况,很多时候是赶鸭子上架,容不得按常理出牌。或者你会说要先做版本验证测试(BVT)查看其可测性,但这都是理想状况。

而无论如何,你首先要搞明白提交过来的东西具备哪些功能以及是如何工作的?事先准备好满足测试需要的软硬件环境自然不必多说。开发经验的作用不光局限于对编码及相关技术的理解,还会使你更加了解开发人员的心理感受,从编码心理和工作习惯的角度,更好地弄懂软件是如何工作的。这一点多多少少有点儿只可意会不易言传的感觉。我在工作中切身体会到,有些朋友搞定编码的思路,可以使人强烈感受到一股强大的、严密的逻辑气息。那思路和风格从头到尾自成一体——气派、美妙,令人赞叹不已。

世界著名计算机科学家,1984年图灵奖获得者Niklaus Wirth提出“算法+数据结构=程序”。清代人薛雪所撰《一瓢诗话》中有:如此体会,则诗神诗旨,跃然纸上。那么我要说:如此体会,则码神码旨,亦跃然纸上。

全面深入,T型路线

T字型知识架构是指在细分领域细致专精,相关技术领域也要有所了解。测试人员真的需要了解相关技术吗?答案是肯定的。这里说的相关技术并非指测试相关,而是指开发所用的相关技术。说得再直白些,最好是懂得相关技术,甚至是该领域的技术专家。

我曾亲身经历过这样一件事情:在一个有着广泛市场影响的项目中,新版本发布增加了新的功能,在HTML页面中使用JavaScript来控制控件的显现。而发布时间紧迫,不允许有更多的时间使用正向用例来验证功能的正确性。尽管如此,我们也针对这小小的控件设计了将近百条用例。涉及的方面包括从页面的正反向跳转来验证控件的版本升级,到控件的跨域调用、浏览器的兼容、服务设置及干扰,如此种种,无一不需要通过了解相关技术,才能设计出有价值的用例。当然,有些有价值的用例来自于使用习惯,这可以说是很难有章可循的,需要靠经验的积累。最后,还要检查JavaScript文件内容是否正确。这样一来,最大限度地保证了产品上线后该功能点万无一失。

理清思路,有的放矢

很多人会认为,在测试工作中引入巧妙的编程技巧或者使用酷炫无比的技术手段,就代表测试水平高超。这种做法显然舍本求末,没有明白测试行为本身的目的。对于专业测试人员,这点误区可以理解,但不可接受。软件测试的目的,一方面是为了尽可能发现软件存在的缺陷,追踪直至解决这些缺陷;另一方面是为了度量被测试对象质量的优劣程度,对可能出现的问题从技术和其他方面采取相应的措施。两者都是为了降低潜在的商业风险。

一般来说,我们首先会根据软件系统本身的特点,其应用场景及开发人员等相关资源,去制订相应的测试策略,其中包括制订测试计划、分配测试资源、设计测试用例等。测试工作前期的大部分内容,不仅需要相关的技术知识,还包括更多的相关应用领域的知识和经验,以及分析能力。而这一切行为皆为降低产品潜在的商业风险所服务。诚然,使用优美的代码和酷炫的技术完成测试任务无可厚非,而无论如何,主旨不可偏离。

积基树本,夯实基础

好比说,找来一些帮手来垒墙,这自然不需要什么高深的建筑理论,但要做对整体工程进行把控的建筑工程师则需要读过建筑理论,掌握相关的基础知识。计算机科学领域中的基础知识,包括数据结构、操作系统、编译原理、数据库原理等。基础知识越是夯实饱满,也才越容易被融会贯通、结合实践从而得到宝贵的升华。数据库产品种类繁多,各类软件开发框架也层出不穷,而不变的永远是基础知识和基本原理。假如你明白高级语言应用开发学习的内容无外乎语法、框架和类库这三部分,学习起来自然不会眉毛胡子一把抓。

在计算机科学领域,如果涉及性能优化(时间复杂度、空间复杂度、数据库、操作系统、网络、并行计算、向量计算等)、复杂的数据结构、协议模型等特殊的问题,那么基础知识也就成了解决问题的必要条件。不用多说,作为专业技术人员,牢牢掌握这些知识是走向一流水平的不二法门。顺便说句题外话,这些基础知识同时也被看做试金石,可以帮助你进入一流水平的研发团队。

与人分享,谈吐有致

与人打交道,就难免涉及人际方面的事宜。沟通的技巧和方式自然是举不胜举,说上三天三夜也未必穷尽。所以在这里对此高谈阔论多少会显得有些捉襟见肘。但很重要且有效的一点沟通技巧可能会被忽略,那就是“不抱怨,找方法”。当团队之间、成员之间需要就某个问题进行交涉,甚至可能会发生争论乃至争吵时,最好少说多做,提出解决办法并且付诸行动。这里向大家推荐阅读卡耐基的《人性的弱点》以及费希尔的《沟通力》。希望能汲取其中的营养,完善性格的弱点,潜移默化地在无形之中大显神威。

一丝不苟,持之以恒

在软件测试的整个周期中,可能会出现一些不是总能重现的问题,这类问题的处理方式可大有讲究。从工程学的角度说,遇到这样的问题,不能及时找到原因而修复的话,需要降低该问题的优先级,等待再次重现,保留现场抓取的相关记录。这样既不会影响当前版本的发布,又毫无疏漏地追踪了曾经偶然出现的问题。某个问题一旦出现,是不能轻易放过的。既然不是总能重现,那如何证明此问题是否已经解决呢?当然,反复验证是重要的一方面。经过反复验证,其实还不能有把握地说这类问题已经修复。是不是心里还是没底呢?那就去看一看源码。

每天反复做一件事,坚持10年,任何人都会有所成就。当企业和项目负责人,等待你那封Test Signoff邮件发出的时候,你是否可以满怀信心地点击Send按钮呢?是否可以对发布前提交的版本做到胸有成竹,锦囊之中自有乾坤呢?百年三万六千日,朝着自己的人生目标,努力过好每一天。修养的形成不在于猛攻,而在于点滴的积累和润物无声地打磨。

本文发表在《程序员》杂志2014年1月刊:
http://www.csdn.net/article/2014-01-08/2818071-Tester

2014年1月8日CSDN首页焦点大图推荐:
IMG_0586