Quantcast
Channel: 懒得折腾
Viewing all 764 articles
Browse latest View live

NightWatch

$
0
0

http://nightwatchjs.org/

What is Nightwatch?

Nightwatch.js is an automated testing framework for web applications and websites, written in Node.js and using the W3C WebDriver API (formerly Selenium WebDriver).

It is a complete browser (End-to-End) testing solution which aims to simplify the process of setting up Continuous Integration and writing automated tests. Nightwatch can also be used for writing Node.js unit tests.

Nightwatch got its name from the famous painting The Night Watch by Dutch artist Rembrandt van Rijn. The masterpiece is prominently displayed in the Rijksmuseum, in Amsterdam – The Netherlands.

Overview of WebDriver

WebDriver is a general purpose library for automating web browsers. It was started as part of the Selenium project, which is a very popular and comprehensive set of tools for browser automation, initially written for Java but now with support for most programming languages.

Nightwatch uses the WebDriver API to perform the browser automation related tasks, like opening windows and clicking links for instance.

WebDriver is now a W3C specification, which aims to standardize browser automation. WebDriver is a remote control interface that enables introspection and control of user agents. It provides a platform and a restful HTTP api as a way for web browsers to be remotely controlled.

Theory of Operation

Nightwatch works by communicating over a restful HTTP api with a WebDriver server (typically the Selenium server). The restful API protocol is defined by the W3C WebDriver API. See below for an example workflow for browser initialization.

Theory of Operation

Most of the times, Nightwatch needs to send at least 2 requests to the WebDriver server in order to perform a command or assertion, the first one being the request to locate an element given a CSS selector (or Xpath expression) and the next to perform the actual command/assertion on the given element.

Install Node.js

From nodejs.org:

“Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.”

There are installation packages and instructions for most major Operating systems on its website nodejs.org. Remember to install also the npm tool, which is the node package manager and is distributed with the Node.js installer.

Install Nightwatch

To install the latest version using the npm command line tool, run the following:

$ npm install [-g] nightwatch

Add -g option to make nightwatch runner available globally in your system.

Selenium Server Setup

The most common WebDriver implementation is the Selenium Server. This allows you to manage multiple browser configurations in one place. However, you can also run the individual browser drivers directly, such as the ChromeDriver, more details are available in the Browser Drivers Setup section.

Selenium Server

Selenium Server is a Java application which Nightwatch uses to connect to the various browsers. It runs separately on the machine with the browser you want to test. You will need to have the Java Development Kit (JDK) installed, minimum required version is 7. You can check this by running java -version from the command line.

Download Selenium

Download the latest version of the selenium-server-standalone-{VERSION}.jar file from the Selenium downloads page and place it on the computer with the browser you want to test. In most cases this will be on your local machine and typically inside your project’s source folder.

A good practice is to create a separate subfolder (e.g. bin) and place it there as you might have to download other driver binaries if you want to test multiple browsers.

Running Selenium Automatically

If the server is on the same machine where Nightwatch is running, it can be started/stopped directly by the Nightwatch Test Runner.

Running Selenium Manually

To run the Selenium Server manually, from the directory with the jar run the following:

$ java -jar selenium-server-standalone-{VERSION}.jar

Using Selenium

For viewing all the run-time options, run the previous command adding the -help:

$ java -jar selenium-server-standalone-{VERSION}.jar -help

Starting with Selenium 3, FirefoxDriver is no longer included in the package. Also, starting with version 48, Firefox is no longer compatible with FirefoxDriver which is shipped with Selenium 2.x. Firefox users are advised to use GeckoDriver for their testing. For more info, refer to the browser setup section.

More info about running the Selenium Server can be found here: https://github.com/SeleniumHQ/selenium/wiki/RemoteWebDriverServer

The test runner expects a configuration file to be passed, using by default a nightwatch.json file from the current directory, if present. A nightwatch.conf.js file will also be loaded by default, if found.

Let’s create the nightwatch.json in the project’s root folder and add this inside:

{
  "src_folders" : ["tests"],
  "output_folder" : "reports",
  "custom_commands_path" : "",
  "custom_assertions_path" : "",
  "page_objects_path" : "",
  "globals_path" : "",

  "selenium" : {
    "start_process" : false,
    "server_path" : "",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "",
      "webdriver.gecko.driver" : "",
      "webdriver.edge.driver" : ""
    }
  },

  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : false,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "firefox",
        "marionette": true
      }
    },

    "chrome" : {
      "desiredCapabilities": {
        "browserName": "chrome"
      }
    },

    "edge" : {
      "desiredCapabilities": {
        "browserName": "MicrosoftEdge"
      }
    }
  }
}

Using both configuration files is also possible, with nightwatch.conf.js always taking precedence if both are found.

Example


module.exports = (function(settings) {
  settings.test_workers = false;
  return settings;
})(require('./nightwatch.json'));

Basic settings

Name type default description
src_folders string|array none An array of folders (excluding subfolders) where the tests are located.
output_folder
Optional
string tests_output The location where the JUnit XML report files will be saved.
custom_commands_path Optional string|array none Location(s) where custom commands will be loaded from.
custom_assertions_path Optional string|array none Location(s) where custom assertions will be loaded from.
page_objects_path
Optional
string|array none Location(s) where page object files will be loaded from.
globals_path
Optional
string none Location of an external globals module which will be loaded and made available to the test as a property globals on the main client instance.

Globals can also be defined/overwritten inside a test_settings environment.

selenium
Optional
object An object containing Selenium Server related configuration options. See below for details.
test_settings object This object contains all the test related options. See below for details.
live_output
Optional
boolean false Whether or not to buffer the output in case of parallel running. See below for details.
disable_colors
Optional
boolean false Controls whether or not to disable coloring of the cli output globally.
parallel_process_delay
Optional
integer 10 Specifies the delay(in milliseconds) between starting the child processes when running in parallel mode.
test_workers
Optional
boolean|object false Whether or not to run individual test files in parallel. If set to true, runs the tests in parallel and determines the number of workers automatically.
If set to an object, can specify specify the number of workers as "auto" or a number.

Example: "test_workers" : {"enabled" : true, "workers" : "auto"}

test_runner
Optional since v0.8.0
string|object “default” Specifies which test runner to use when running the tests. Values can be either default (built in nightwatch runner) or mocha.

Example: "test_runner" : {"type" : "mocha", "options" : {"ui" : "tdd"}}

Selenium settings

Below are a number of options for the selenium server process. Nightwatch can start and stop the Selenium process automatically which is very convenient as you don’t have to manage this yourself and focus only on the tests.

If you’d like to enable this, set start_process to true and specify the location of the jar file inside server_path.

Name type default description
start_process boolean false Whether or not to manage the selenium process automatically.
start_session boolean true Whether or not to automatically start the Selenium session. This will typically be set to false when running unit/integration tests that don’t interact with the Selenium server.
server_path string none The location of the selenium jar file. This needs to be specified if start_process is enabled.
E.g.: bin/selenium-server-standalone-2.43.0.jar
log_path string|boolean none The location where the selenium output.log file will be placed. Defaults to current directory.
To disable Selenium logging, set this to false
port integer 4444 The port number Selenium will listen on.
cli_args object none List of cli arguments to be passed to the Selenium process. Here you can set various options for browser drivers, such as:
  • webdriver.firefox.profile: Selenium will be default create a new Firefox profile for each session. If you wish to use an existing Firefox profile you can specify its name here.
    Complete list of Firefox Driver arguments available here.
  • webdriver.chrome.driver: Nightwatch can run the tests using Chrome browser also. To enable this you have to download the ChromeDriver binary and specify it’s location here. Also don’t forget to specify chrome as the browser name in the desiredCapabilities object.
    More information can be found on the ChromeDriver website.
  • webdriver.ie.driver: Nightwatch has support for Internet Explorer also. To enable this you have to download the IE Driver binary and specify it’s location here. Also don’t forget to specify “internet explorer” as the browser name in the desiredCapabilities object.

Test settings

Below are a number of settings that will be passed to the Nightwatch instance. You can define multiple sections (environments) of test settings so you could overwrite specific values per environment.

A “default” environment is required. All the other environments are inheriting from default and can overwrite settings as needed.

{
  ...
  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "globals" : {
        "myGlobalVar" : "some value",
        "otherGlobal" : "some other value"
      }
    },

    "integration" : {
      "launch_url" : "http://staging.host",
      "globals" : {
        "myGlobalVar" : "other value"
      }
    }
  }
}

The key of the settings group can be passed then to the runner as the --env argument to use the specified settings, like so:

$ nightwatch --env integration

This can be useful if you need to have different settings for your local machine and the Continuous Integration server.

The launch_url property

This property will be made available to the main Nightwatch api which is used in the tests. Its value depends on which environment is used.

If you run your tests as in the example above (with --env integrationlaunch_url will be set to http://staging.host, as per the configuration. Otherwise it will have the value defined in the defaultenvironment (i.e. http://localhost).


module.exports = {
  'Demo test' : function (browser) {
    browser
      .url(browser.launchUrl)
      // ...
      .end();
  }
};

Test globals

A very useful concept that Nightwatch provides is test globals. In its most simple form, this is a dictionary of name-value pairs which is defined in your nightwatch.json configuration file. Like the launch_url property, this is made available directly on the Nightwatch api which is passed to the tests. It is also dependent on the environment used, having the ability to overwrite specific globals per environment.

If we still pass the --env integration option to the runner, then our globals object will look like below:


module.exports = {
  'Demo test' : function (browser) {

    console.log(browser.globals);
    // {
    //   "myGlobalVar" : "some value",
    //   "otherGlobal" : "some other value"
    // }

  }
};

By default, a deep object copy will be created for each test suite run. If you’d like to maintain the same object throughout the entire tests run, set the persist_globals option to true, as detailed below.

Full list of settings

Name type default description
launch_url string none A url which can be used later in the tests as the main url to load. Can be useful if your tests will run on different environments, each one with a different url.
selenium_host string localhost The hostname/IP on which the selenium server is accepting connections.
selenium_port integer 4444 The port number on which the selenium server is accepting connections.
request_timeout_options
since v0.9.11
object 60000 / 0 Defines the number of milliseconds an HTTP request to the Selenium server will be kept open before a timeout is reached. After a timeout, the request can be automatically retried a specified number of times, defined by the retry_attempts property.

Example:

"request_timeout_options": {
"timeout": 15000,
"retry_attempts": 5
}

silent boolean true Whether to show extended Selenium command logs.
output boolean true Use to disable terminal output completely.
disable_colors boolean false Use to disable colored output in the terminal.
firefox_profile
deprecated
string|boolean none This options has been deprecated in favor of the cli_args object on the selenium settings object.
chrome_driver
deprecated
string none This options has been deprecated in favor of the cli_args object on the selenium settings object.
ie_driver
deprecated
string none This options has been deprecated in favor of the cli_args object on the selenium settings object.
screenshots object none Selenium generates screenshots when command errors occur. With on_failure set to true, also generates screenshots for failing or erroring tests. These are saved on the disk.

Since v0.7.5 you can disable screenshots for command errors by setting "on_error" to false.

Example:

"screenshots" : {
"enabled" : true,
"on_failure" : true,
"on_error" : false,
"path" : ""
}

username string none In case the selenium server requires credentials this username will be used to compute the Authorizationheader.

The value can be also an environment variable, in which case it will look like this:
"username" : "${SAUCE_USERNAME}"

access_key string none This field will be used together with username to compute the Authorization header.

Like username, the value can be also an environment variable:
"access_key" : "${SAUCE_ACCESS_KEY}"

proxy
since v0.8.6
string none Proxy requests to the selenium server. http, https, socks(v5), socks5, sock4, and pac are accepted. Uses node-proxy-agent.

Example: http://user:pass@host:port

desiredCapabilities object An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities.
Example:

"desiredCapabilities" : {
"browserName" : "firefox",
"acceptSslCerts" : true
}

You can view the complete list of capabilities here.

globals object An object which will be made available within the test and can be overwritten per environment. Example:

"globals" : {
"myGlobal" : "some_global"
}

exclude array An array of folders or file patterns to be skipped (relative to the main source folder).
Example:

"exclude" : ["excluded-folder"]
or:
"exclude" : ["test-folder/*-smoke.js"]

filter string Folder or file pattern to be used when loading the tests. Files that don’t match this pattern will be ignored.
Example:

"filter" : "tests/*-smoke.js"

log_screenshot_data boolean false Do not show the Base64 image data in the (verbose) log when taking screenshots.
use_xpath boolean false Use xpath as the default locator strategy
cli_args object none Same as Selenium settings cli_args. You can override the global cli_args on a per-environment basis.
end_session_on_fail boolean true End the session automatically when the test is being terminated, usually after a failed assertion.
skip_testcases_on_fail boolean true Skip the remaining testcases (or test steps) from the same test suite (i.e. test file), when one testcase fails.
output_folder
since v0.8.18
string|boolean Define the location where the JUnit XML report files will be saved. This will overwrite any value defined in the Basic Settings section. If you’d like to disable the reports completely inside a specific environment, set this to false.
persist_globals
since v0.8.18
boolean false Set this to true if you’d like to persist the same globals object between testsuite runs or have a (deep) copy of it per each testsuite.
compatible_testcase_support
since v0.9.0
boolean false Applies to unit tests. When set to true this allows for tests to be written in the standard Exports interface which is interchangeable with the Mocha framework. Prior unit tests interface support is deprecated and this will become the default in future releases.
detailed_output
since v0.9.0
boolean true By default detailed assertion output is displayed while the test is running. Set this to false if you’d like to only see the test case name displayed and pass/fail status. This is especially useful when running tests in parallel.

This section contains guides for getting started with most of the major browsers and setup instructions on how to configure the individual webdriver implementations to work with Nightwatch.

The individual drivers described here are usually standalone applications which are used to interact with the browsers via the WebDriver HTTP API. You can run them either directly, or through the Selenium Server.

GeckoDriver

Overview

GeckoDriver is a standalone application used to interact with Gecko-based browsers, such as Firefox. It is written in Rust and maintained by Mozilla.

Starting with Firefox 48, GeckoDriver is the only way to automate Firefox, the legacy FirefoxDriver which used to be part of Selenium is no longer supported. Internally it translates the HTTP calls into Marionette, Mozilla’s automation protocol built into Firefox.

Download

Binaries are available for download on the GeckoDriver Releases page on GitHub, for various platforms.

Selenium 2.x users are advised to use version v0.9, whereas Selenium 3 users should use the latest version.

Usage

If you’re using GeckoDriver through Selenium Server, simply set the cli argument "webdriver.gecko.driver" to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.gecko.driver" : "./bin/geckodriver"
    }
  }
}

GeckoDriver can also be used as a standalone application. Usage steps are documented on GitHub: https://github.com/mozilla/geckodriver#usage.

Command line usage
$ ./bin/geckodriver-0.10 -help
geckodriver 0.10.0

USAGE:
    geckodriver-0.10 [FLAGS] [OPTIONS]

FLAGS:
        --connect-existing    Connect to an existing Firefox instance
    -h, --help                Prints help information
        --no-e10s             Start Firefox without multiprocess support (e10s) enabled
    -V, --version             Prints version information
    -v                        Set the level of verbosity. Pass once for debug level logging and twice for trace level logging

OPTIONS:
    -b, --binary            Path to the Firefox binary, if no binary capability provided
        --log                Set Gecko log level [values: fatal, error, warn, info, config, debug, trace]
        --marionette-port     Port to use to connect to gecko (default: random free port)
        --host                Host ip to use for WebDriver server (default: 127.0.0.1)
    -p, --port                Port to use for WebDriver server (default: 4444)

Firefox Capabilities

GeckoDriver supports a capability named firefoxOptions which takes Firefox-specific preference values. Details are available on the GeckoDriver GitHub page: https://github.com/mozilla/geckodriver#firefox-capabilities.

Firefox Profile

Specifying the firefox profile can be done by setting the profile property in the firefoxOptions dictionary, as detailed above. This can be the base64-encoded zip of a profile directory and it may be used to install extensions or custom certificates.

Implementation Status

GeckoDriver is not yet feature complete, which means it does not yet offer full conformance with the WebDriver standard or complete compatibility with Selenium. Implementation status can be tracked on the Marionette MDN page.

ChromeDriver

Overview

ChromeDriver is a standalone server which implements the W3C WebDriver wire protocol for Chromium. ChromeDriver is available for Chrome on Android and Chrome on Desktop (Mac, Linux, Windows and ChromeOS).

Download

Binaries are available for download on the ChromeDriver Downloads page, for various platforms.

Selenium Server Usage

If you’re using ChromeDriver through Selenium Server, simply set the cli argument "webdriver.chrome.driver" to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "./bin/chromedriver"
    }
  }
}

Standalone Usage

If you’re only running your tests against Chrome, running ChromeDriver standalone is easier and slightly faster. Also there is no dependency on Java.

This requires a bit more configuration:

1) First, disable Selenium Server, if applicable:
{
  "selenium" : {
    "start_process" : false
  }
}
2) Configure the port and default path prefix.

ChromeDriver runs by default on port 9515. We also need to clear the default_path_prefix, as it is set by default to /wd/hub, which is what selenium is using.

{
  "test_settings" : {
    "default" : {
      "selenium_port"  : 9515,
      "selenium_host"  : "localhost",
      "default_path_prefix" : "",

      "desiredCapabilities": {
        "browserName": "chrome",
        "chromeOptions" : {
          "args" : ["--no-sandbox"]
        },
        "acceptSslCerts": true
      }
    }
  }
}
3) Start the ChromeDriver server

The easiest way to manage the ChromeDriver process is by using the chromedriver NPM package, which is a third-party wrapper against the binary. This will abstract the downloading of the chromedriver binary and will make it easy to manage starting and stopping of the process.

You can add this to your external globals file, like so:


var chromedriver = require('chromedriver');
module.exports = {
  before : function(done) {
    chromedriver.start();

    done();
  },

  after : function(done) {
    chromedriver.stop();

    done();
  }
};

Using a fixed ChromeDriver version

In some situations you may need to use a specific version of ChromeDriver. For instance, the CI server runs an older version of Chrome. Then you will need an older version of ChromeDriver.

Here’s what your globals file might look like:


var chromedriver = require('chromedriver');
var path = require('path');
var driverInstanceCI;

function isRunningInCI() {
  return this.test_settings.globals.integration;
}

function startChromeDriver() {
  if (isRunningInCI.call(this)) {
    var location = path.join(__dirname, '../bin/chromedriver-linux64-2.17');
    driverInstanceCI = require('child_process').execFile(location, []);
    return;
  }

  chromedriver.start();
}

function stopChromeDriver() {
  if (isRunningInCI.call(this)) {
    driverInstanceCI && driverInstanceCI.kill();
    return;
  }

  chromedriver.stop();
}

module.exports = {
  'ci-server' : {
    integration : true
  },

  before : function(done) {
    startChromeDriver.call(this);

    done();
  },

  after : function(done) {
    stopChromeDriver.call(this);

    done();
  }
};

Run your tests then with (on the CI server):

$ ./node_modules/.bin/nightwatch --env ci-server

ChromeOptions

You can specify Chrome options or switches using the chromeOptions dictionary, under the desiredCapabilities. Refer to the ChromeDriver website for a fill list of supported capabilities and options.

Command line usage

$ ./bin/chromedriver -h
Usage: ./bin/chromedriver [OPTIONS]

Options
  --port=PORT                     port to listen on
  --adb-port=PORT                 adb server port
  --log-path=FILE                 write server log to file instead of stderr, increases log level to INFO
  --verbose                       log verbosely
  --version                       print the version number and exit
  --silent                        log nothing
  --url-base                      base URL path prefix for commands, e.g. wd/url
  --port-server                   address of server to contact for reserving a port
  --whitelisted-ips               comma-separated whitelist of remote IPv4 addresses which are allowed to connect to ChromeDriver

Microsoft WebDriver

Overview

Microsoft WebDriver is a standalone server which implements the W3C WebDriver wire protocol for the Edge browser. It is supported by Windows 10 and onwards.

Download

Binaries are available for download on the Microsoft WebDriver homepage.

Selenium Server Usage

If you’re using Microsoft WebDriver through Selenium Server, simply set the cli argument "webdriver.edge.driver"to point to the location of the binary file. E.g.:

{
  "selenium" : {
    "start_process" : true,
    "server_path" : "bin/selenium-server-standalone-3.{VERSION}.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.edge.driver" : "bin/MicrosoftWebDriver.exe"
    }
  },
  "test_settings" : {
    "default" : {
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",

      "desiredCapabilities": {
        "browserName": "MicrosoftEdge",
        "acceptSslCerts": true
      }
    }
  }
}

Standalone Usage

If you’re only running your tests against Edge, running the EdgeDriver standalone can be slightly faster. Also there is no dependency on Java.

This requires a bit more configuration and you will need to start/stop the EdgeDriver:

1) First, disable Selenium Server, if applicable:
{
  "selenium" : {
    "start_process" : false
  }
}
2) Configure the port and default path prefix.

Microsoft WebDriver runs by default on port 9515. We also need to clear the default_path_prefix, as it is set by default to /wd/hub, which is what selenium is using.

{
  "test_settings" : {
    "default" : {
      "selenium_port"  : 17556,
      "selenium_host"  : "localhost",
      "default_path_prefix" : "",

      "desiredCapabilities": {
        "browserName": "MicrosoftEdge",
        "acceptSslCerts": true
      }
    }
  }
}
3) Start the MicrosoftWebDriver server

From the Windows CMD prompt, simply CD to the folder where the MicrosoftWebDriver.exe binary is located and run:

C:\nightwatch\bin>MicrosoftWebDriver.exe
[13:44:49.515] - Listening on http://localhost:17556/

Full command line usage:

C:\nightwatch\bin>MicrosoftWebDriver.exe -h
Usage:
 MicrosoftWebDriver.exe --host= --port= --package= --verbose

Implementation Status

EdgeDriver is not yet feature complete, which means it does not yet offer full conformance with the WebDriver standard or complete compatibility with Selenium. Implementation status can be tracked on the Microsoft WebDriver homepage.



隐蔽的歧视:华人留学澳洲的交友难题

$
0
0

隐蔽的歧视:华人留学澳洲的交友难题

2016年10月,作者王俊岭在汤斯维尔近海向来自伊朗的大学校友Behnam介绍帆船运动。

Courtesy of Wang Junling

2016年10月,作者王俊岭在汤斯维尔近海向来自伊朗的大学校友Behnam介绍帆船运动。

 

今年6月初我结束两年的硕士课程从位于澳大利亚昆士兰的詹姆斯库克大学(James Cook University)毕业的时候,已经是当地中国留学生里面和本地社区融入得比较好的一个了。我是当地帆船俱乐部的网络管理员,还承担了俱乐部新网站的建设工作,不仅获得了一封充满赞誉的推荐信,还推荐了两个急于积累工作经验的中国同学到这家俱乐部工作。此外,我还在学习帆船的过程中结识了不少当地朋友,获得了难得的归属感。即使在6月份离开汤斯维尔并搬到墨尔本以后,我还和这家俱乐部保持着紧密的联系。

然而这一切并不是我最初的计划,我本来希望在大学宿舍楼里发展自己的社会关系。刚开始我对此很有信心,因为我自认为颇有一些关于西方国家政治正确的知识储备,明白即使一句恭维的话也可能造成对人的歧视,也知道如何避免因为无心的玩笑而冒犯别人。然而当我搬进宿舍区之后,才发现现实远非如此美好和简单,而且我显然忽略了一种必要的准备:被本地人冒犯时应该怎么办。

我来到澳大利亚以后第一次向别人介绍自己的经历就让我有点猝不及防。开学之前,学校为了帮助宿舍区的新生们(其中超过90%都是本科生)相互了解,组织了一个“罗马长袍聚会”(Roman toga party),参加者把床单披在身上模仿古代罗马人。我也兴冲冲地参加了。聚会上一个本地的白人女生问我来自哪个国家,我说我来自中国。她马上转头对身边的伙伴说:“他们中国人为什么说‘中国’(China)这个词的时候总是声音特别大?哈哈!”然后她开始一遍一遍地很大声的模仿我的口音:“China! China!”(中国!中国!)。

一个中国人,刚到一个陌生国家不到两天,半裸上身斜披着一条床单,站在一群本地学生中间被人嘲笑口音。那种体验真是既尴尬又无助。但是我当时的第一反应竟然不是愤怒和反击,而是在反省自己是不是真的把“China”这个词说得很大声。是不是在国内接受的多年的爱国主义教育,让我下意识强调“中国”两个字?因为我完全没有预料到一个文明程度很高的国家的女大学生会如此恶意地对待一个新来的外国人。现在回想起来,嘲笑对方的口音真是欺侮外来者的一件法宝,因为在这件事上,对方永远是错的,而且永远不知道正确答案。

后来我逐渐发现,我的遭遇并不算极端案例。今年7月下旬,墨尔本大学(University of Melbourne)和同样位于这座城市的莫纳什大学(Monash University)校园里的一些建筑物的入口处竟然被亲纳粹的白人青年团体张贴了写有“禁止中国人入内”的海报。此事在中国留学生群体中引发了不小的反响。最近,澳大利亚官方对于来自中国日益增长的投资、移民,以及与其相伴的政治和意识形态影响力越来越焦虑。甚至澳大利亚的教育家指责中国留学生中有很多正把中国官方的立场带入教室,以及澳大利亚情报部门开始调查某些进行过大额政治捐赠的华人富商是否是中国政府的代言人。今年上半年,澳大利亚政府提出一项提案,希望修改现行的“反种族歧视法案”,因为他们认为该法案禁止种族歧视言论的规定妨碍了言论自由。但是,在这一议题的激发下,澳洲少数族群纷纷在社交媒体上分享自己遭受种族歧视的经历。最终,该提案被澳大利亚参议院否决。上述一系列事件至少证明现在的澳大利亚主流白人群体与少数族群之间逐渐显现出一种张力。

当然,这只能算一种隐约的趋势,其实不管在汤斯维尔还是在墨尔本,这种明目张胆的种族攻击行为都是罕见的。对于汤斯维尔这个种族构成相对单一,生存竞争也不太激烈的偏远小城来说,发生歧视行为的机会更少。根据官方统计,在汤斯维尔的19万人口中,说英语的白人占绝大多数。最大的少数族群是占当地人口7%的澳洲原住民。其他少数民族,例如意大利、韩国人、中国人,都少于0.4%。再加上学校官方对于禁止歧视、欺凌做了严格的规定,种族歧视现象虽然还是存在,但往往是以一种更隐蔽、更柔和、甚至是一团和气的方式存在着。

宿舍区有一个来自印度的男生,加入了一个本地学生自发形成的小团体,吃饭、出去玩都在一起。这些小团体一般是以肤色划分的,看见一个印度人和几个白人打成一片,我甚至有点嫉妒他。直到有一天在餐厅吃饭的时候我和他坐得很近,发现那几个白人男生不停模仿他的口音,而他竟然没有任何抗议的表示。旁边还有一个本地的白人女生笑着打趣他:“你只要严肃地抗议,他们立刻就会停下来。真的,试试吧。”印度男生苦笑着摇摇头说:“永远没用的”。

据我观察,至少在我住的这个宿舍区,这种嘲笑行为更像是进入一个小团体的门票。这些小团体往往由一个很有侵略性的学生作为“首领”(例如那个模仿我口音的女生),几个相对温和友好的学生作为忠诚的手下。如果首领不喜欢一个人,那么这个团体的成员都不会和这个人交朋友,虽然表面上可能非常有礼貌。大学生们对关系疏远的人一般很讲礼貌,不过一旦你想进入他们的圈子,则是需要“买票”的——接受对你的嘲讽。

当然,这种看似兄弟情谊般的玩笑并非总是平等和有趣的。有一个来自南非的白人男生,是另一个小团体的首领,走到哪都有两个人跟着。刚开始他对我相当热情,稍微熟悉一些以后,他就根据我名字(Junling)的谐音给我取了一个绰号:King Julien。这个名字来自美国动画片《马达加斯加》(Madagascar)里的一个喜剧角色:一只环尾狐猴。我对此非常反感,因为这个角色眼睛很大像戴眼镜,身材矮小、猥琐滑稽,几乎集合了所有西方人对亚洲人的恶意想象。不过一开始我并没有反击,甚至还会友善地回应他。因为他对自己很好的朋友也总是以各种绰号相称,让人很难分辨这是恶意的嘲讽还是善意的玩笑。后来我发现他尤其喜欢当着女生的面这么叫我,叫完还要唱电影里的很滑稽的主题曲,引得那些女生窃笑。这是我最不能容忍的。于是我就也给他起了个侮辱性的绰号“Piggy”,意思是“猪仔”,因为他有点胖,而且的名字“Jono”听起来像中文词“猪猡”。他每次叫我的时候,我也用那个绰号叫他。结果和我预想的一样,他不再叫我的绰号了,甚至见面不和我打招呼。当然,我也就成了一个圈外人。

另一个让我难以和本地学生融为一体的原因在于我不是他们认为的很“酷”的人。我所在的大学的学生们最流行的交往方式就是喝酒聚会。经常有学生在Facebook群组里夸耀自己如何几周没有做作业,如何每天喝醉,这被看作是最酷的。而像我这样滴酒不沾的学生则被认为是无聊的。不过在我看来,这种肤浅的寻欢作乐才是真正的无聊,我也不愿意改变自己的行事原则。有一次,前文提到那个模仿我口音的女生开生日聚会。她是最受欢迎的女生之一,聚会者占领了整个公共区大厅,几十个人围着她又唱又跳。我本来没有被邀请,路过的时候,正赶上几个女生出来给蛋糕点蜡烛,其中一个一向对我比较友好的女生把我也拉了进去。我站在人群当中自己都觉得有点突兀。另一个女生算是寿星的手下,一边嬉笑一边挨个找人自拍合影,显然是作为Facebook的素材。她到我跟前的时候,竟然如同我不存在一样,直接跳过我,和下一个人合影。那一瞬间,我感觉我从入学开始就花了校外房租两倍的价钱住进学校的宿舍,试图融入本地群体的尝试算是彻底失败了。我准备离开宿舍,到校外租住。

由于前述的种种原因,大学生,尤其是国际学生比例较高的研究生中“自发种族隔离”的现象比较普遍。住在校外的自不必说,中国学生、南亚学生和来自中东的学生大多“聚族而居”,族群之间不相往来。就算在宿舍区为了增进学生相互了解而举行的每周一次的免费晚餐上,也经常是白人学生坐一起,和我坐在一起的永远是那几个亚洲人。我搬出校园后租住在一位来自兰州的挚友家里,每天只用汉语交流。这是我一直想避免的情况。好在他家还有两个四十多岁的澳洲本地男性租客,他们非常友好。为了避免自己的英语退化,我只好尽量多去客厅,和他们一起看板球,虽然我根本看不懂。

其实融入本地社区是有捷径的,那就是参加教会的活动。即使你明确表示自己不打算皈依基督,教会的人还是照样愿意接纳和帮助你。有一个北京来的女同学,就是通过长期参加教会的活动,结交了不少本地朋友,最终受洗,成为了一名虔诚的基督徒。不过作为一个坚信达尔文进化论的人,我一直告诫自己不到万不得已不要加入教会。不过现在似乎已经没有什么选择。入住学生宿舍一年以后,我开始收集一些教会活动的传单,查看了他们的日程表,甚至在平板电脑里下载了一部电子版的圣经。就在此时,发生了一件事让我没有走进教堂——我加入了帆船俱乐部。

我是纯粹出于兴趣才学习帆船的,不带任何诸如拓展社会关系等功利性目的。这个兴趣由何而来我并不清楚,也许是出于对驾驶乐趣的追求,也许是喜欢海上开阔的感觉。经过了一年多繁重而又与世隔绝的学校学习之后,我决定送自己一件略为奢侈的礼物——花300澳元参加一个帆船培训班。经过三个周末总共20个小时的入门课程,我就可以独自驾船下水了,还成了汤斯维尔帆船俱乐部(Townsville Sailing Club)的会员。帆船运动给我带来很大的乐趣,我可以连着几个小时在海上行驶而不觉得枯燥,同时也让我体验到原汁原味的澳洲社团活动。

所谓的俱乐部更像是一个社区活动中心,成员之间都很熟悉。其成员主要由两类人组成:已经退休的老年人和还在上小学的孩子。我发现这两种人都比大学生容易相处。尤其是年纪比较大的人,他们经常主动教我如何正确安装索具,帮我把船调整到最佳状态。虽然他们这样做的结果往往是我最终借助体力优势在比赛中赢过他们,但是他们根本不在乎。我练习结束上岸的时候,他们经常开玩笑地问我今天翻船了没有。如果我回答没有,他们就会露出很失望的表情。作为整个俱乐部里唯一的外国人,也是唯一的亚裔,我在这里完全感觉不出自己与别人有什么不同。

参加活动多了,会自然而然获得一些工作机会。有一次,俱乐部要举办一次“环岛赛事”,参赛船只要绕附近的一个岛屿一圈,全程几个小时。俱乐部的一位管理人员问我想不想到救生船上工作。我说:“我很想去,因为我听说这个岛很漂亮,我还没有环岛游览过。”于是我就成了救生团队的一员。这个工作并不繁重,绝大多数时间都是开着橡皮艇跟在帆船后面。比赛那天,我正在船上欣赏岛上风景,另外一艘救生船靠了过来,我这艘船的驾驶员说:“你跳到另外一艘船上。”我问为什么,他说:“你不是说你想环岛游览吗?其实没有任何一艘救生船会绕岛一圈,每艘船只负责一段水域,下一段由那艘船送你过去。”于是我从一艘船跳到另一艘船,用接力的方式完成了一次免费的环岛观光。那种受到照顾的感觉让身在异国的我体验到久违的温暖。在帆船俱乐部,我只不过是在从事一项自己喜爱的运动,却意想不到地得到了一些之前求之不得的东西。甚至我得到网络管理员和建设新网站的工作,也都是在闲聊的过程中定下来的。

为什么我在大学宿舍和帆船俱乐部的遭遇如此不同?我还没有清晰的答案。也许仅仅是因为在这样一个主要由老人和儿童组成的群体里,我这样一个青年人的存在不会威胁到任何人,也不会有同龄人为了确立威信或在女生面前炫耀而对我发起“羞辱攻击”。我曾经和一位定居墨尔本的30岁左右的朋友谈到我的经历,他竟然说也有类似体验:“现在五六十岁的这一代澳大利亚人,待人接物真的没话说,人品特别好。但是二十多岁这批,就差点儿意思了。”我问他这是不是年龄造成的?如果现在的年轻人到了四五十岁以后,会不会也像他们的父辈一样富有包容心?我的朋友说不会的,因为时代已经不同了。经历过冷战时代的人知道宽容的可贵。当时西方在经济上处于统治地位,因此也更加自信。现在已经不一样了。

他的解释对不对,我不知道。我更愿意相信这些大学生的排外行为并非针对其他种族的有意行为,倒是更像澳洲年轻人群体中普遍存在的小圈子和排外行为。据我在墨尔本就读的翻译学校的一位华人老师讲,澳大利亚崇尚“强者文化”。他举例说,他在澳大利亚出生长大的儿子曾经在自己就读的中学校园里目睹一个女生被另外两个女生架住胳膊,被第三个女生暴击腹部。而澳大利亚政府网站也承认欺凌现象的严重性,2008年的一次覆盖40多个国家的调查显示,澳大利亚是小学校园欺凌现象最严重的国家之一。另一项调查显示,在8到14岁的学生中,有四分之一经常性地受到肢体或言语上的欺凌。这种文化自然也会延伸到大学,就连本地白人学生也可能成为受害者。

这样看来,我在大学宿舍所受到的令我不愉快的对待,不仅不像是种族歧视,倒像是受到了“国民待遇”。然而,在这种看似“一视同仁”的游戏中,像我这样在语言和文化背景上皆处于劣势的外来者很容易成为牺牲品,进而在自我身份认同和融入本地文化的摇摆中被“制造”成一个外来者。

中国人对于留学生活经常有一个说法:“越出国越爱国”。以我的切身体会来看,这大概并非因为资本主义国家人民水深火热的生活让人更加向往祖国,而是由于融入本地社区受到了挫折,被迫通过强化自我身份的认同来实现心理平衡。然而,这种自我强化又恰恰加深了一部分澳洲本地人关于“非我族类,其心必异”的焦虑。

前文提到的大学校园反华海报事件和对中国富商干预澳洲政治的调查就是这种焦虑的反映。甚至有人担心澳大利亚会受到中国人“共产主义价值观”的侵蚀。但是我相信大多数中国留学生都会对这种指控感到冤枉,绝大多数肯定不是肩负国家使命来到这个遥远的国家的。他们只是想来这里寻找更好的教育或生活而已。而这些花费高昂学费、放弃原来的生活来到这里的人,对澳大利亚这个国家的价值观也不可能是反对的。问题在于他们有没有机会被澳大利亚接纳,并分享它的这种价值观的果实,还是成为只有在交学费时才感到被需要的人。

王俊岭曾就职于中国媒体行业,詹姆斯库克大学IT硕士毕业。


Node.JS Top 10 Articles for the Past Month

$
0
0

Node.JS Top 10 Articles for the Past Month (v.Feb 2017)

For Jan-Feb 2017, we’ve ranked nearly 1,000 Node.JS articles to pick the Top 10 stories (1% chance) that can help advance your career.

Topics included in this list are: Best Practices, Home Automation, Notification, Interview Q/A, Docker, NASA, APIs, Microservice, Digital Ocean. The list for JavaScript, React and Angular are posted separately.

Mybridge AI ranks articles based on the quality of content measured by our machine and a variety of human factors including engagement and popularity. This is a competitive list and you’ll find the experience and techniques shared by Node.JS leaders particularly useful.

Rank 1

Best Practices for Writing Node.js REST APIs. Courtesy of Trace by RisingStack


Rank 2

Retrogames Library with Node, React, and Redux 1: Server API and React Frontend. Courtesy of Samuele Zaza and Scotch Development


Rank 3

How to build your own Uber-for-X application [Part 2]. Courtesy of Ashwin Hariharan and Free Code Camp

…………. [ Part I ]


Rank 4

Node.js Interview Questions and Answers (2017 Edition).


Rank 5

Docker Introduction. Courtesy of Tobias T—


Rank 6

Ground Control to Major Tom: How NASA Uses Node.js [Pdf]. Courtesy of Node.js Foundation

…….……. [ Medium Post ]


Rank 7

Beautiful APIs in Node. Courtesy of Azat Mardan


Rank 8

How to Host a Node.js App on Digital Ocean. Courtesy of Chris Ganga


Rank 9

Enlightenments from the Node Gurus. Courtesy of Azat Mardan, Software Engineer at CapitalOne



创始人别那么抠门

$
0
0

创始人别那么抠门

09 年以来,我几乎一直在创业公司,要么自己创业,要么合伙加入朋友的公司。我发现了一个很明显的现象,10年、11年的时候我在极客公园工作,当时招人我只需要发一条微博、一篇博客,在文字里透露出各种情怀,就会有志同道合的人加入。但在近两年,我发现情怀已经不能吸引人才加入了,他们已经不相信创业梦想,只相信现金了。

与其说他们不再相信情怀和梦想,不如说年轻人们变得更实际了,以往可能到了 30 岁的年龄才能深刻意识到创业的高风险性 — 因为这个年龄的人已经不能毫无顾忌地拼了,但现在新一代的年轻人,比如刚毕业的,很多已经变得很实际,他们不再相信期权,不再相信创始人的承诺,你付我多少工资,我就干多少活。

这种心态的变化可能与一些创业公司创始人不兑现承诺有关。

Artboard 2

年轻人不再谈梦想

比如,我的好朋友冯大辉,在一家名为丁香园的公司工作了数年,按常理来说,股权应该已经 100% 解除限制了,但在他准备离开时,创始人并没有兑现给他的承诺,这其中有很多细节,也有不少法律上的模糊地带,当事人没公开说,我也就不说了。但在外界看来,这个故事就是一个 CTO 为公司尽心尽力,不仅把技术带好,还把公司的新媒体做了起来,最后却被踢出局,没有得到应有的利益。

类似的事还有很多,比如某云服务厂商的员工就曾经在 V2EX 论坛吐槽股份问题,当时这件事在技术圈也引起了广泛讨论。

昨天,相信大家也看到一篇关于某游戏公司技术合伙人干了 7 年被无情踢出局,一点股份没拿到的文章。文章矛头直指该公司 CEO,到目前为止,CEO 或 CEO 的夫人均未出来回应。也许像很多刷屏的文章那样,过一段时间剧情说不定会反转,但无法改变的是,一件又一件合伙人、员工被创始人在股份、利益分配问题上设坑的事都在让年轻人加入创业公司失去了信心。

这是一件好事吗?说好不好,说坏不坏。每个人都在为自己的利益最大化着想

有人可能会说,为什么以前没怎么听说这种事,现在却越来越多?以前也不是没有,只是创业大潮来了,创业的人多了,里面的坏人也就自然多了,就好像不是老人变坏了,只是坏人都变老了而已。

合伙人是弱势群体

员工也好、合伙人也好,在创业公司里都是弱势群体。说得不好听一点,如果创始人想耍小心眼,哪怕合伙人被写到工商注册里面,创始人都有办法联合投资人把合伙人踢出局,这里面可以有 10000 种操作手法(这里用了夸张的修辞手法)。

最简单的,创始人联合投资人成立一家新公司,把资产全部转移,在新公司里剔除合伙人。这种操作方法是可行的,如果创始人有意在创业初期就把公司资产放到个人名下,而不是公司名下,这种转移简直是易如反掌。

员工也好、合伙人也好,在创业公司里都是弱势群体。我的一个朋友,曾经短暂加入一家创业,他被创始人忽悠加入时被承诺了一定的股份,以及未来几年的股份外的利润分配,具体的,就是未来几年,公司如果盈利到达某个数值,利润按照特殊的比例分成,而不是股份比例。合伙人们当然很高兴,觉得这位创始人很厚道。

但是,当我这位朋友加入这家公司后才发现,一些后期的合伙人根本没在工商注册的名单里,股份和利润分配也只做了口头承诺,于是他牵头起草合伙人协议,试图把这些细节都落实到纸质文件上。无奈,在利润分配的问题上,创始人反复变卦,甚至把已经签署的文件强行收回希望修改后重签。

后来,我这位朋友离开了这家公司,他的离开已经快一年了,至今那份利润分配协议还是没有签署。因为这位朋友在设计协议时咨询过我,那家公司的一些合伙人也知道,今天看到刷屏的那个故事,有位合伙人跟我说,「这里边故事比较多,不方便多谈。我相信你懂我懂,不用聊的」。

员工也好、合伙人也好,在创业公司里都是弱势群体。他们在创业过程中付出的总时间不比创始人少,因为相信创始人才加入,最后发现被坑,却鲜有利用法律手段保护自己,这里有一个原因是,大多数创业公司给员工的都是「期权」,有的是创始人「代持股份」。如果公司是一家在中国注册的公司,期权都是无效的,中国的法律不认期权。

代持股份,在《公司法》里有相关条文承认其有效性,但这里其实有潜在的风险,实际出资人享有的是投资权益,没有股东权益,股东权益全部都在代持人身上,大多数情况下,也就是创始人。这种操作方法很普遍,其实对双方来说,都是有风险的,在双方和谐相处时当然没有任何问题,而一旦出现意见纠纷,假设代持人想坑出资人,他可以不向实际投资人转交资产收益,而滥用股东权利擅自处置股权(转让、质押)等。

一般来说,出现纠纷时,创始人会和合伙人商量,以「适当」的价格回收其股份。但什么价格是「适当」的,这里又是一个模糊地带。如果合伙人不认可这个「适当价格」,创始人大可以说期权在中国是无效的,但如果适当价格是过低的,自己心里又爽不到哪里去。

说到这里,似乎我们都认为合伙人挺难的,一方面要付出自己全部精力,另一方面,随时都可能被坑。然而,创始人也好不到哪里去,他心里也有很多苦。

创始人心里也有苦

投资人股东一般是站在创始人那边的,当公司有重大决策,比如踢走一个合伙人时,他们大多数情况下会合力去做。有良心的创始人这时会和合伙人商量一个退出机制

比如一家公司的成立时公司估值 1000万,合伙人占 10% 股份,股份价值 100万。公司运作 4 年后,估值已经到了 1 亿,合伙人的股份可能被稀释到 7% (假设),这时他的股份价值应该是 700 万。如果这个时候合伙人退出,公司理应回收他的股份,但大多数创业公司很难在这个时候拿出 700万现金。

于是双方就开始扯皮了,合伙人认为这是合理的价格,但创始人心里知道,如果公司掏出那么多钱,公司就没法周转了。双方谁也不让谁。这时,解决方法有两个。

一是商量。双方协商一个合理的价格,比如 300 万,如果双方都满意,好聚好散。

二是查看当初签订的股权退出协议,有些制度比较完善的公司,会在签订股权协议的时候就规定行权价格,如果是这样,事情也是比较好办的。但是,很多时候创始人还会认为行权价格过高,这时又不得不使用第一个办法:商量。

有些创始人为了避免合伙人退出导致资金短缺,会给合伙人限定行权比例,比如工作满一年,释放股份的 25%,4 年全部释放完毕。有些过度保护自己利益的,会在协议上写上「市场公平价」,什么是市场公平价?谁来定义?这种模糊的说法,对合伙人是不公平的,但反过来想,创始人难道不应该最大限度保护公司的利益么?

创始人保护公司利益无可厚非。在创业初期,每个创始人都很抠,除了那些拿了巨额投资的明星创业者。不管是多熟悉的朋友、多靠谱的合伙人,创始人总会留一个心眼,总会设想最坏的情况,避免合伙人离开导致公司的利益和股东的利益损失。

甚至,在关键的时刻,采取特殊手段把合伙人踢出局。像这两天刷屏那篇文章里说的,虽然这个合伙人在公司干了 7 年,领着比同行低的薪水,但在创始人眼里,他可能认为他已经给这位合伙人合理的退出价格了,因为他在几年前已经给这位合伙人奖励了 100 万(文章里说的)。

7 年,除了基本工资外,获得 100 万收入,这算高么?其实不高,但我们其实无法从文章里获知公司的目前的营收状况,可能 100 万对于公司来说已经是一笔巨额支出,创始人自己已经觉得对得起这个兄弟,已经心安理得了。

又或者,在公司关键时刻,这位 7 年的合伙人的一些做法阻碍了公司进展,创始人不得不把他踢掉。我们当然可以认为这位创始人很无情,但从公司的利益角度去看,可能是对的。但这里,理应有合理的赔偿,至少从外界的报道来看,未见有赔偿的迹象。

当然,这些都是猜测,我们现在只看到一面之词,其实没法客观去评价这件事。但无论如何,创始人最大限度地维护公司利益,这个出发点是对的,只是有些人的做法不厚道,有些坏人混入了创业圈

创业维艰

创业公司初期没什么钱,用股份吸引人才加入是合理的,我在两次创业里都这么做,并且和赠予股份的员工签署了纸质协议。在这件事上,我自认为问心无愧。

之所以这么做,是因为我也作为合伙人被坑过,我知道合伙人的弱势,当我创业时,我不能让我的合伙人付出了但没有得到合理的回报。梦想要有,人民币也需要有。

但我也不得不留心眼,我也会和合伙人签署代持协议,也设定行权比例和行权价格,公司和股东利益是最重要的,我不能容许一个合伙人离开,导致公司的资金链断开或出现大缺口。

合伙人、核心员工与创始人之间的沟通很重要,而且,所有沟通的成果都应该落到纸面文件上,不管是哪一方,都怀着最大的好意去创业,但再好的人,总会有使坏的时候,不落实到纸上,没有法律的承认,所有口头的承诺都是扯蛋。

希望创始人们不要太抠门,我们自己在付出时间和精力的同时,合伙人们、员工们也都付出同样的时间和精力,他们理应得到合理的回报,维护公司利益没错,但应该同时在制度上让员工切切实实地感受到:创始人是慷慨的,是愿意分享利益的,是想和我们一起财务自由的。

不然,谁还愿意参与创业?谁还相信情怀?谁还愿意付出青春给梦想?

创始人别那么抠门,合伙人多留心眼。


Machine Learning Top 10 Articles for the Past Year (v.2017)

$
0
0

Machine Learning Top 10 Articles for the Past Year (v.2017)

For the past year, we’ve ranked nearly 14,500 Machine Learning articles to pick the Top 10 stories (0.069% chance) that can help you advance your career in 2017.

“It was machine learning that enabled AlphaGo to whip itself into world-champion-beating shape by playing against itself millions of times” — Demis Hassabis, Founder of DeepMind

AlphaGo astonishes Go grandmaster Lee Sedol with its winning move

This machine learning list includes topics such as: Deep Learning, A.I., Natural Language Processing, Face Recognition, Tensorflow, Reinforcement Learning, Neural Networks, AlphaGo, Self-Driving Car.

This is an extremely competitive list and Mybridge has not been solicited to promote any publishers. Mybridge A.I. ranks articles based on the quality of content measured by our machine and a variety of human factors including engagement and popularity. Academic papers were not considered in this batch.

Give a plenty of time to read all of the articles you’ve missed this year. You’ll find the experience and techniques shared by the leading data scientists particularly useful.

Rank 1

Complete Deep Learning Tutorial, Starting with Linear Regression. Courtesy of Andrew Ng at Stanford University


Rank 2

Teaching Computer to Play Super Mario with DeepMind & Neural Networks. Courtesy of Ehren J. Brav

……. [ Super Mario Machine Learning Demonstration with MarI/O ]


Rank 3

A Beginner’s Guide To Understanding Convolutional Neural Networks [CNN Part I]. Courtesy of Adit Deshpande

………………………………… [ CNN Part II ]

………………………………… [ CNN Part III ]


Rank 4

Modern Face Recognition with Deep Learning — Machine Learning is Fun [Part 4]. Courtesy of Adam Geitgey


Rank 5

Machine Learning in a Year: From a total beginner to start using it at work. Courtesy of Per Harald Borgen

……………….….…….[ Machine Learning In a Week ]


Rank 6

Building Jarvis AI with Natural Language Processing. Courtesy of Mark Zuckerburg, CEO at Facebook.


Rank 7

Image Completion with Deep Learning in TensorFlow. Courtesy of Brandon Amos, Ph.D at Carnegie Mellon University


Rank 8

The Neural Network Zoo.


Rank 9

How to Code and Understand DeepMind’s Neural Stack Machine. Courtesy of Andrew Trask, PhD at University of Oxford



GeoTrellis 1.0 Release with LocationTech

$
0
0

GeoTrellis 1.0 Release with LocationTech

By Ross Bernet on January 9th, 2017

GeoTrellis 1.0 Release

GeoTrellis, a geographic data processing engine for high performance applications, is a Scala library and framework that uses Spark to work with raster data. GeoTrellis 1.0 was recently released under LocationTech, marking a major achievement for the community that has helped to build the project.

GeoTrellis

A 1.0 release is a significant milestone for an Open Source Project. It’s an indicator of maturity and reliability. GeoTrellis became an Open Source Project in 2011 with the goal of helping people process raster data at scale. We moved to Apache Spark for supporting distributed processing with version 0.10.0 in April of this year. We have come a long way.

This post will explain the motivation to release under LocationTech and what the decision means for GeoTrellis users and contributors.

LocationTech

LocationTech is a working group hosted by the Eclipse foundation with a charter to foster community around commercial-friendly, open source, advanced geospatial technology. GeoTrellis joined LocationTech in 2013. Here are some of the reasons why:

GeoTrellis developers have already benefited from collaboration with other LocationTechn projects since joining in 2013. An example of this is when developers from GeoMesa and GeoTrellis worked together to create the SFCurve library. It’s a solution to the common problem of creating Z-order curve indices based on spatial or spatiotemporal properties of data. Additionally, members from GeoTrellis have participated and presented at the annual LocationTech tour, which has become a global event promoting open source geospatial software.

Impact on Users

There will a number of new features and few inconveniences that come with 1.0. This major release marks our official graduation but only includes minor API breaks with respect to 0.10.3. The release from .09 to 0.10 had many large architectural changes stemming from the transition to Apache Spark which required significant API changes. This is not the case for 1.0. You will need to upgrade your project and change the organization to “org.locationtech” as shown below:

libraryDependencies += "org.locationtech.geotrellis" %% "geotrellis-raster" % "1.0.0"

GeoTrellis will still be available on Maven Central via sonatype’s nexus repository in addition to repo.locationtech.org. The last release 0.10.3 was only available on sonatype’s nexus repository.

Major New Features

  • Streaming GeoTiff support
  • Windowed GeoTiff reading on S3 and Hadoop
  • Improved ETL capabilities
  • HBase and Cassandra backends support
  • Collections API that allows users to avoid Spark in ideal cases
  • Experimental support for Vector Tiles, GeoWave integration, and GeoMesa integration
  • Documentation moved to ReadTheDocs. This greatly improves usability, readability, and searchability

See a comprehensive list of changes here

Color Corrected Aerial Image of Egypt

Considerations

The GeoTrellis team decided that the many benefits to joining LocationTech outweigh any downsides. However, in the name of transparency, it’s important to discuss the possible downsides we considered:

  1. Give GeoTrellis trademark to Eclipse
  2. Ceding some control. There are pros and cons to creating a larger decision-making body for a project. We think the increased number of perspectives will outweigh the possibility of slower decision-making time
  3. One-time requirements to officially graduate involved:
    1. Submitting codebase and dependencies to ensure appropriate licensing
    2. Setup builds that publish to LocationTech infrastructure
    3. Create release review so Project Management Committee can do final review of release
    4. Graduation review to make sure project is up to standards

We are excited about the move and the significance of the achievement. GeoTrellis has grown it’s community and user base over the years. GeoTrellis has been the collective work of more than 50 people and 6,500 commits.

A 1.0 release marks the effort of this community and the maturation of GeoTrellis. Moving forward will see a regular release schedule.

Connect with us

We appreciate hearing about the projects that GeoTrellis supports – please get in touch via Twitter, our mailing list, our Gitter channel, or email to share what you are working on.

GitHub – Issues, codebase, documentation, everything you need

Our mailing list – Stay informed about releases, bug bashes, and GeoTrellis updates

Gitter – Scala is hard. We can help. Come ask questions about your GeoTrellis project

Twitter – We send team members to conferences, workshops, and share Big Data Open Source Geo project news

Email – Have questions about a project idea that could benefit from processing rasters at a scale? Reach out to us via email – we’d love to hear from you!


Node.JS Top 10 Articles of the Year (v.2017)

$
0
0

Node.JS Top 10 Articles of the Year (v.2017)

For the past year, we’ve ranked nearly 8,500 Node.JS articles to pick the Top 10 stories (0.12% chance) that can help you prepare your development career in 2017.

This Node.JS list includes topics such as: Backend, MongoDB, Express, Structure, Test, Passport.

This is an extremely competitive list and Mybridge has not been solicited to promote any publishers. Mybridge AI ranks articles based on the quality of content measured by our machine and a variety of human factors including engagement and popularity. Mybridge AI ranks articles based on parameters including the quality of content, popularity, and other human factors. Hopefully this condensed list will help you read and learn more productively in the area of Node.JS.

Give a plenty of time to read all of the articles you’ve missed this year. You’ll find the experience and lessons shared by Node.JS leaders particularly useful.

Rank 1

Art of Node: A Short Introduction to Node.JS [5,808 stars on Github]. Courtesy of Zeke Sikelianos


Rank 2

Building and Securing a Modern Backend API with Node.JS. Courtesy of Ado Kukic and Scotch Development


Rank 3

19 things I learnt reading the NodeJS docs. Courtesy of David Gilbertson


Rank 4

How I built an app with 500,000 users in 5 days on a $100 server with Node.JS & MongoDB. Courtesy of Erik Duindam


Rank 5

Advanced Node.js Project Structure Tutorial. Courtesy of Trace by RisingStack


Rank 6

How to build a URL Shortener with Node.JS, MongoDB, Hapi.JS.


Rank 7

Test a Node RESTful API with Mocha and Chai.


Rank 8

Introduction to Node & Express. Courtesy of Eric Elliott


Rank 9

How to build your own Uber-for-X App. Courtesy of Ashwin Hariharan



Landsat元数据批量下载工具

$
0
0

Landsat元数据批量下载工具

目录

  1. 前言
  2. landsat数据情况简介
  3. 下载元数据
  4. 总结

一、前言

最近由于工作需要,需要下载部分landsat数据的元数据,老板大手一挥,给了十几年的landsat的path、row以及日期等,就算交待完了。于是我就开始准备吭哧吭哧到USGS官网上去一个个找。程序员应该是世界上最懒的人,懒到哪怕只有几百个也不愿意一个个手动弄,于是在官网上翻腾半天,终于找到这么一个页面(https://landsat.usgs.gov/landsat-bulk-metadata-service),能够给定范围批量下载元数据,这是个好东西,基本几下就解决问题了。懒劲又升级了,这么一批一批的下下来我不是还要手工整理,于是就想写个程序自动下载然后筛选出我想要的部分。

二、landsat数据情况简介

我相信接触过landsat的人这块应该都很清楚了,百度百科介绍如下:

美国NASA的陆地卫星(Landsat)计划(1975年前称为地球资源技术卫星 — ERTS ),从1972年7月23日以来, 已发射8颗(第6颗发射失败)。目前Landsat1—4均相继失效,Landsat 5仍在超期运行(从1984年3月1日发射至今)。 Landsat 7于1999年4月15日发射升空。Landsat8[1] 于2013年2月11日发射升空,经过100天测试运行后开始获取影像。

具体信息可以自行查询,landsat的数据都是以带号进行命名的,信息包含path、row以及数据日期等。我们就要根据这些来实现批量下载landsat元数据。

三、下载元数据

3.1 分析下载元数据页面

下载页面

仔细分析上述usgs官网中的下载元数据页面,不难发现其是将行列号一定范围内以及日期一定范围内的元数据打包成一个文件发送到前台。并且发送的是一个GET请求,请求格式如下:

https://earthexplorer.usgs.gov/EE/InventoryStream/pathrow?start_path=131&end_path=140&start_row=35&end_row=38&sensor=LANDSAT_TM_C1&start_date=2011-06-01&end_date=2011-11-01&format=CSV

参数名称也都通俗易懂,于是一切就豁然开朗了,我只需要写个程序根据需求拼接出此url,然后发送请求,就能得到结果。一切就是这么easy,不过拿到结果后你会发现事情稍微复杂一点,因为请求的区域及时间等都是范围,这就导致结果中有很多不是我们需要的,于是再完善程序循环遍历与我们输入数据的行列号逐一匹配,取出需要的结果即可。

3.2 程序实现

程序整体界面如图所示:

程序截图

程序比较简单,只需要提供一个下载范围文件(csv格式),每行一个,选择下载的landsat的dataset即可。

程序读取用户给定的范围自动算出行列号的范围以及日期范围,代码如下:

var lines = File.ReadAllLines(fileName);
var data = lines.Select(s => s.Split(',')).Select(s => new { Path = int.Parse(s[0]), Row = int.Parse(s[1]), Date = CommonHelper.ParseDate(s[2]) });
StartPath = data.Min(s => s.Path);
StartRow = data.Min(s => s.Row);
StartDate = data.Min(s => s.Date);
EndPath = data.Max(s => s.Path);
EndRow = data.Max(s => s.Row);
EndDate = data.Max(s => s.Date);

之后拼接请求的URL,代码如下:

$"https://earthexplorer.usgs.gov/EE/InventoryStream/pathrow?start_path={StartPath}&end_path={EndPath}&start_row={StartRow}&end_row={EndRow}&sensor={DatasetType}&start_date={CommonHelper.FormatDate(StartDate)}&end_date={CommonHelper.FormatDate(EndDate)}&format=CSV"

其中DatasetType是用户选择的landsat数据源,CommonHelper.FormatDate函数完成日期到字符串格式的转化,代码如下:

public static string FormatDate(DateTime date)
{
    return date.ToString("yyyy-MM-dd");
}

然后发送请求,获取结果,这块在网络爬虫之密码破解一文中已经介绍过,不再赘述。获取到结果后,将其与用户想要的结果一一比对,取出需要的结果,代码如下:

var orginResultList = orginResult.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(1);
var source = File.ReadAllLines(file);
var data = source.Select(s => s.Split(',')).Select(s => new { Path = int.Parse(s[0]), Row = int.Parse(s[1]), Date = CommonHelper.ParseDate(s[2]) });
var endResult = new List<string>();
data.ToList().ForEach(s =>
{
    var temp = orginResultList.Where(re =>
    {
        var arr = re.Split(',');
        return int.Parse(arr[7]) == s.Path && int.Parse(arr[8]) == s.Row /*&& CommonHelper.ParseDate(arr[5]) == s.Date*/;
    });
    if (temp != null && temp.Count() > 0)
        endResult.Add(temp.First());
});
File.WriteAllLines(Path.Combine(Path.GetDirectoryName(file), "res.csv"), endResult);

其中orginResult表示请求返回的结果,这里面存在一个问题就是往往用户想要的元数据日期与返回的元数据日期不一致(原因可能有很多,用户输入不准确,或者有什么我未考虑到的因素),如果时间也进行匹配的话基本取不到结果,所以目前采用的方式只比对行列号。

四、总结

通过以上方式即可实现批量下载landsat元数据,需要下载程序的可以直接点击这里,当然由于刚做出的程序,难免在代码逻辑或者业务逻辑上有BUG或者未考虑到的地方,欢迎批评指正,后续完善之后可能会将源代码开放到Github上,以供需要的人使用。


作者:魏守峰

出处:http://www.cnblogs.com/shoufengwei/

本文版权归作者和博客园共有,欢迎转载、交流,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。



Applying Neural Network and Local Laplace Filter Methods to Very High Resolution Satellite Imagery to Detect Damage in Urban Areas

$
0
0

Applying Neural Network and Local Laplace Filter Methods to Very High Resolution Satellite Imagery to Detect Damage in Urban Areas

by Dariia Gordiiuk

Since the beginning of the human species, we have been at the whim of Mother Nature. Her awesome power can destroy vast areas and cause chaos for the inhabitants. The use of satellite data to monitor the Earths surface is becoming more and more essential. Of particular importance are the disasters and hurricane monitoring systems that can help people to identify damage in remote areas, measure the consequences of the events, and estimate the overall damage to a given area. From a computing perspective, such an important task needs to be implemented to assist in various situations.

To analyze and estimate the effects of a disaster, we use high-resolution, satellite imagery from an area of interest. This can be obtained from Google Earth. We can also get free OSM vector data that has a detailed ground truth mask of houses. This is the latest vector zip from New York (Figure 1).

Figure 1. NY Buildings Vector Layer

Next, we rasterize (convert from vector to raster) the image using a tool from gdal, called gdal_rasterize. As a result we have acquired a training and testing dataset from Long Island (Figure 2).

Figure 2. Training Data Fragment of CNN

We apply a deep learning framework Caffe for training purposes and the learning model of Convolutional Neural Networks (CNN):

Figure 3. CNN Parameters

The derived neural net enables us to identify the predicted houses from the target area after the event (Figure 4). We can also use data from another similar area which hasn’t been damaged for CNN learning (if we can’t access the data for the desired territory).

Figure 4. Predictive Results of CNN Learning

We work with predicates of buildings using vectorization (extracting a contour and then converting lines to polygons) (Figure 5).

Figure 5. Predictive Results of Buildings (Based on CNN)

Also, we need to compute the intersection of the obtained predicate vector and the original OSM vector (Figure 6). This task can be accomplished by creating a new filter, dividing the square of the predicate buildings by the original OSM vector. Then, we filter the predictive houses by applying a threshold of 10%. This means that if the area of houses in green (Figure 6) is 10% less than the area in red, the real buildings have been destroyed.

Figure 6. Calculating CNN-Obtained Building Number (Green) Among Buildings Before Disaster (Red)

Using the 10%-area threshold we can remove the houses that have been destroyed and get a new map that displays existing buildings (Figure 7). By computing the difference between the pre- and post- disaster masks, we obtain a map of the destroyed buildings (Figure 8).

Figure 7. Buildings: Before and After Disaster With CNN Method
Figure 8. Destroyed Buildings With CNN

We have to remember that the roofs of the houses are represented as flat structures in 2D-images. This is an important feature that can also be used to filter input images. A local Laplace filter is a great tool for classifying flat and rough surfaces (Figure 9). The first image has to be a 4-channel image with the fourth Alpha-channel that describes no-data-value pixels in the input image. The second image (img1) is the same, a 3-channel RGB image.

Figure 9. Local Laplace Window Filter

Applying this tool lets you get the map of the flat surface. Let’s look at the new mask of the buildings which have flat and rough textures (Figure 10)after combining this filter and extracting the vector map.

Figure 10. Flat Surface Mask With Laplace Window Filter Followed By Extracted House Mask

A robust library of the OpenCV computer vision has a denoising filter that helps remove noise from the flat buildings masks (Figure 11, 12).

Figure 11. Denoising Filter
Figure 12. Resulting Mask. Pre- and Post- Disaster Images After Applying Denoising Filter

Next, we apply filters to extract the contours and convert the lines into the polygons. This enables us to get new building recognition results (Figure 13).

Figure 13. Predictive Results of Buildings With Laplace Filter

We compute the area of an intersection vector mask obtained from the filter and a ground truth OSM mask and use a 14% threshold to reduce false positives (Figure 14).

Figure 14. Calculations: Buildings With Laplace Filter (Yellow) Before Damage (Green), Using 14% Threshold

As a result, we can see a very impressive new mask that describes houses that have survived the hurricane (Figure 15) and a vector of the ruined buildings (Figure 16).

Figure 15. Before and After Disaster With Laplace Filter
Figure 16. Destroyed Buildings With Laplace Filter

After we have found the ruined houses, we can also pinpoint their location. For this task OpenStreetMap comes in handy. We have installed an OSM plugin in QGis and added an OSM layer to the canvas (Figure 17). Then, we added a layer with the destroyed houses and we can see all their addresses. If we want to get a file with the full addresses of the destroyed buildings we have to:

  1. In QGis use Vector / OpenStreetMap / Download the data and select the images with the desired information.
  2. Then in QGis use Vector / OpenStreetMap / Import a topology from XML and generate a DataBase from the area of interest.
  3. QGis / Vector / Export the topology to Spatialite and select all the required attributes. (Figure 18)
Figure 17. Destroyed Houses Location
Figure 18. Required Attributes Selection To Load Vector Into Ruined Buildings

As a result, we can get a full list, with addresses, of the destroyed buildings (Figure 19).

Figure 19. Address List of Ruined Houses

If we compare these two different approaches to building recognition, we notice that the CNN-based method has 78% accuracy in detecting destroyed houses, whereas the Laplace filter reaches 96.3% accuracy in recognizing destroyed buildings. As for the recognition of existing buildings, the CNN approach has a 93% accuracy, but the second method has a 97.9 % detection accuracy. So, we can conclude that the flat surface recognition approach is more efficient than the CNN-based method.

The demonstrated method can immediately be very useful and let people compute the extent of damage in a disaster area, including the number of houses destroyed and their locations. This would significantly help while estimating the extent of the damage and provide more precise measurements than currently exist.

For more information about EOS Data Analytics follow us on social networks: Facebook, Twitter, Instagram, Linkedin.


OSMDeepOD – OSM and Deep Learning based Object Detection from Aerial Imagery

$
0
0

OSMDeepOD – OSM and Deep Learning based Object Detection from Aerial Imagery

This is a project about object detection from aerial imagery using open data from OpenStreetMap (OSM) project as massive training data and areal imagery, wordwide or local. This project has been formerly known as “OSM-Crosswalk-Detection”; now ot’s called OSMDeepOD, pronounced “OSM Deep ‘Oh ‘Dee”!

Keywords: Big Data; Data Science; Data Engineering; Machine Learning; Artificial Intelligence; Neuronal Nets; Imagery; Volunteered Geographic Information; Crowdsourcing; Geographic Information Systems; Infrastructure; Parallel Programming.

Introduction

OSM-Crosswalk-Detection is a highly scalable image recognition software for aerial photos (orthophotos). It uses the open source software library TensorFlow, with a retrained Inception V3 neuronal network, to detect crosswalks along streets.

This work started as part of a semester thesis autumn 2015 at Geometa Lab, University of Applied Sciences Rapperswil (HSR).

Overview

Marcitecture

Process

Detection-Example1

Getting Started

Prerequisites

  • PythonAt the moment, we support python 3.x
  • DockerIn order to use volumes, I recommend using docker >= 1.9.x
  • Bounding Box of area to analyzeTo start the extraction of crosswalks within a given area, the bounding box of this area is required as arguments for the manager. To get the bounding box the desired area, you can use https://www.openstreetmap.org/export to select the area and copy paste the corresponding coordinates. Use the values in the following order when used as positional arguments to manager: left bottom right top

Usage

The simplest way to use the detection process is to clone the repository and build/start the docker containers.

git clone https://github.com/geometalab/OSM-Crosswalk-Detection.git
cd OSM-Crosswalk-Detection/dockerfiles/
sudo python docker_run.py -r -d

After the previous shell commands you have started a redis instance for data persistance and a container for the detection process. Now you should be connected to a tty of the crosswalk_detection container. If you have a nvida GPU and nvidia-docker installed the detection algorithm will automatically use this GPU1.

To start the detection process use the src/role/main.py2 script.

  1. Use the manger option to select the detection area and generate the jobs stored by the redis instance
python3 main.py --redis 172.17.0.25 --port 40001 --pass crosswalks manager 9.345101 47.090794 9.355947 47.097288 --tag junction roundabout --search roundabout --no_compare --zoom_level 17 --orthofoto other

The default settings of –tag, –search, and –zoom_level are for crosswalk detection. The parameter ‘–orthofoto’ is for the image source.

  1. Start the detection algorithm. The results are also stored by the redis instance.
python main.py --redis 127.0.0.1 --port 40001 --pass crosswalks jobworker
  1. Collect the results in a simple JSON file.
python main.py --redis 127.0.0.1 --port 40001 --pass crosswalks resultworker

If you have execute the result worker in the docker container you can move the crosswalks.json file to the /crosswalk/ directory which is map to your host.

Own Orthofotos

To use your own Orthofotos you have to do the following steps:

1. Add a new directory to src/data/orthofoto
2. Add a new module to the directory with the name: 'your_new_directory'_api.py
3. Create a class in the module with the name: 'Your_new_directory'Api   (First letter needs to be uppercase)
4. Implement the function 'def get_image(self, bbox):' and returns a pillow image of the bbox
5. After that you can use your api with the parameter --orthofots 'your_new_directory'

If you have problems with the implementation have a look at the wms or other example.

Dataset

During this work, we have collected our own dataset with swiss crosswalks and non-crosswalks. The pictures have a size of 50×50 pixels and are available by request.

Crosswalk Examples

Picture 3: Crosswalk Examples

No-Crosswalk Examples

Picture 4: No Crosswalk Examples

Links

Notes

1: The crosswalk_detection container is based on the nvidia/cuda:7.5-cudnn4-devel-ubuntu14.04 image, may you have to change the base image for your GPU. 2: For more information about the main.py use the -h option.


The 10 Most Important Node.js Articles of 2016

$
0
0

The 10 Most Important Node.js Articles of 2016

2016 was an exciting year for Node.js developers. I mean – just take a look at this picture:Every Industry has adopted Node.js

Looking back through the 6-year-long history of Node.js, we can tell that our favorite framework has finally matured to be used by the greatest enterprises, from all around the world, in basically every industry.

Another great news is that Node.js is the biggest open source platform ever – with 15 million+ downloads/month and more than a billion package downloads/week. Contributions have risen to the top as well since now we have more than 1,100 developers who built Node.js into the platform it is now.

To summarize this year, we collected the 10 most important articles we recommend to read. These include the biggest scandals, events, and improvements surrounding Node.js in 2016.

Let’s get started!

#1: How one developer broke Node, Babel and thousands of projects in 11 lines of JavaScript

Programmers were shocked looking at broken builds and failed installations after Azer Koçulu unpublished more than 250 of his modules from NPM in March 2016 –breaking thousands of modules, including Node and Babel.

Koçulu deleted his code because one of his modules was called Kik – same as the instant messaging app – so the lawyers of Kik claimed brand infringement, and then NPM took the module away from him.

“This situation made me realize that NPM is someone’s private land where corporate is more powerful than the people, and I do open source because Power To The People.” – Azer Koçulu

One of Azer’s modules was left-pad, which padded out the lefthand-side of strings with zeroes or spaces. Unfortunately, 1000s of modules depended on it..

You can read the rest of this story in The Register’s great article, with updates on the outcome of this event.

#2: Facebook partners with Google to launch a new JavaScript package manager

In October 2016, Facebook & Google launched Yarn, a new package manager for JavaScript.

The reason? There were a couple of fundamental problems with npm for Facebooks’s workflow.

  • At Facebook’s scale npm didn’t quite work well.
  • npm slowed down the company’s continuous integration workflow.
  • Checking all of the modules into a repository was also inefficient.
  • npm is, by design, nondeterministic — yet Facebook’s engineers needed a consistent and reliable system for their DevOps workflow.

Instead of hacking around npm’s limitations, Facebook wrote Yarn from the scratch:

  • Yarn does a better job at caching files locally.
  • Yarn is also able to parallelize some of its operations, which speeds up the install process for new modules.
  • Yarn uses lockfiles and a deterministic install algorithm to create consistent file structures across machines.
  • For security reasons, Yarn does not allow developers who write packages to execute other code that’s needed as part of the install process.

Yarn, which promises to even give developers that don’t work at Facebook’s scale a major performance boost, still uses the npm registry and is essentially a drop-in replacement for the npm client.

You can read the full article with the details on TechCrunch.

#3: Debugging Node.js with Chrome DevTools

New support for Node.js debuggability landed in Node.js master in May.

To use the new debugging tool, you have to

  • nvm install node
  • Run Node with the inspect flag: node --inspect index.js
  • Open the provided URL you got, starting with “chrome-devtools://..”

Read the great tutorial from Paul Irish to get all the features and details right!

#4: How I built an app with 500,000 users in 5 days on a $100 server

Jonathan Zarra, the creator of GoChat for Pokémon GO reached 1 million users in 5 days.Zarra had a hard time paying for the servers (around $4,000 / month) that were necessary to host 1M active users.

He never thought to get this many users. He built this app as an MVP, caring about scalability later. He built it to fail.

Zarra was already talking to VCs to grow and monetize his app. Since he built the app as an MVP, he thought he can care about scalability later.

He was wrong.

Thanks to it’s poor design, GoChat was unable to scale to this much users, and went down.A lot of users lost with a lot of money spent.

500,000 users in 5 days on $100/month server

Erik Duindam, the CTO of Unboxd has been designing and building web platforms for hundreds of millions of active users throughout his whole life.

Frustrated by the poor design and sad fate of Zarra’s GoChat, Erik decided to build his own solution, GoSnaps: The Instagram/Snapchat for Pokémon GO.

Erik was able to build a scalable MVP with Node.js in 24 hours, which could easily handle 500k unique users.

The whole setup ran on one medium Google Cloud server of $100/month, plus (cheap) Google Cloud Storage for the storage of images – and it was still able to perform exceptionally well.

GoSnap - The Node.js MVP that can Scale

How did he do it? Well, you can read the full story for the technical details:

Read my “How I built an app with 500,000 users in 5 days on a $100 server” https://medium.com/@mr.erik/how-i-built-an-app-with-500-000-users-in-5-days-on-a-100-server-77deeb238e83#.p56pbg2do 

Photo published for How I built an app with 500,000 users in 5 days on a $100 server – Unboxd

How I built an app with 500,000 users in 5 days on a $100 server – Unboxd

There seems to be a general consensus in the world of startups that you should build an MVP (minimum viable product) without caring too…

medium.com

#5: Getting Started with Node.js – The Node Hero Tutorial Series

The aim of the Node Hero tutorial series is to help novice developers to get started with Node.js and deliver software products with it!

Node Hero - Getting started with Node.js

You can find the full table of contents below:

  1. Getting started with Node.js
  2. Using NPM
  3. Understanding async programming
  4. Your first Node.js HTTP server
  5. Node.js database tutorial
  6. Node.js request module tutorial
  7. Node.js project structure tutorial
  8. Node.js authentication using Passport.js
  9. Node.js unit testing tutorial
  10. Debugging Node.js applications
  11. Node.js Security Tutorial
  12. Deploying Node.js application to a PaaS
  13. Monitoring Node.js Applications

#6: Using RabbitMQ & AMQP for Distributed Work Queues in Node.js

This tutorial helps you to use RabbitMQ to coordinate work between work producers and work consumers.

Unlike Redis, RabbitMQ’s sole purpose is to provide a reliable and scalable messaging solution with many features that are not present or hard to implement in Redis.

RabbitMQ is a server that runs locally, or in some node on the network. The clients can be work producers, work consumers or both, and they will talk to the server using a protocol named Advanced Messaging Queueing Protocol (AMQP).

You can read the full tutorial here.

#7: Node.js, TC-39, and Modules

James M Snell, IBM Technical Lead for Node.js attended his first TC-39 meeting in late September.

The reason?

One of the newer JavaScript language features defined by TC-39 — namely, Modules — has been causing the Node.js core team a bit of trouble.

James and Bradley Farias (@bradleymeck) have been trying to figure out how to best implement support for ECMAScript Modules (ESM) in Node.js without causing more trouble and confusion than it would be worth.

ECMAScript modules vs. CommonJS

Because of the complexity of the issues involved, sitting down face to face with the members of TC-39 was deemed to be the most productive path forward.

The full article discusses what they found and understood from this conversation.

#8: The Node.js Developer Survey & its Results

We at Trace by RisingStack conducted a survey during 2016 Summer to find out how developers use Node.js.

The results show that MongoDB, RabbitMQ, AWS, Jenkins, Docker and Amazon Container Services are the go-to choices for developing, containerizing and shipping Node.js applications.

The results also tell Node developers major pain-point: debugging.

Node.js Survey - How do you identify issues in your app? Using logs.

You can read the full article with the Node.js survey results and graphs here.

#9: The Node.js Foundation Pledges to Manage Node Security Issues with New Collaborative Effort

The Node Foundation announced at Node.js Interactive North America that it will oversee the Node.js Security Project which was founded by Adam Baldwin and previously managed by ^Lift.

As part of the Node.js Foundation, the Node.js Security Project will provide a unified process for discovering and disclosing security vulnerabilities found in the Node.js module ecosystem. Governance for the project will come from a working group within the foundation.

The Node.js Foundation will take over the following responsibilities from ^Lift:

  • Maintaining an entry point for ecosystem vulnerability disclosure;
  • Maintaining a private communication channel for vulnerabilities to be vetted;
  • Vetting participants in the private security disclosure group;
  • Facilitating ongoing research and testing of security data;
  • Owning and publishing the base dataset of disclosures, and
  • Defining a standard for the data, which tool vendors can build on top of, and security and vendors can add data and value to as well.

You can read the full article discussing every detail on The New Stack.

#10: The Node.js Maturity Checklist

The Node.js Maturity Checklist gives you a starting point to understand how well Node.js is adopted in your company.

The checklist follows your adoption trough establishing company culture, teaching your employees, setting up your infrastructure, writing code and running the application.

You can find the full Node.js Maturity Checklist here.


Nodejs图片编辑和中文乱码

$
0
0

近期证书生成的活动比较流行,如马拉松证书生成活动,运营同学打算做一个大学录取通知书的活动。以前相关的活动都在nodejs服务器上进行开发,这次也就不例外了。

nodejs的图片处理库不少,使用比较多的有以下几个:

  1. node-images:在cnode上有node-iamges作者写的文章。这个库安装简单,依赖少;借助它可以实现改变图片大小、图片合并等功能。本打算使用它进行开发,但是由于其不支持文字写入,只好另寻他路了。
  2. node canvas:这个库我调研的较少,百度上有不少文章,大家可以自行查看进行判断,其中此文介绍了其在百度地图上的使用,说明其功能还是很强大的。
  3. gm: gm是nodejs对GraphicsMagick和ImageMagick封装。GraphicsMagick和ImageMagick是老牌的图片处理工具,它们功能很强大,包括了图片的创建、编辑、合成、读取、转换、切割、颜色替换等各种图片处理功能。 gm基于它俩进行开发,可知gm的功能强大。功能的强大就可能意味着安装和使用的复杂!本文主要介绍gm的安装和使用方法;同时对经常遇到的中文乱码问题进行了介绍。由于开发机器是mac,所以只覆盖到了mac和linux系统。

安装gm

gm在mac上的安装比较简单,依据npm上的介绍进行即可:

  brew install imagemagick
  brew install graphicsmagick

在linux上安装gm,我参考了GraphicsMagick介绍及安装,,服务器是阿里云,主要步骤如下:

  • 获取安装包
    wget http://iweb.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/1.3.23/GraphicsMagick-1.3.23.tar.gz
  • 解压然后执行configure和make make install
    tar -zvf GraphicsMagick-1.3.23.tar.gz
    cd GraphicsMagick-1.3.23/
    ./configure
    make
    make install
  • 执行:convert -v, 看到如下内容,就说明安装成功了:
Paste_Image.png

在工程目录执行: npm install gm
安装完成后,在nodejs中使用gm:

    var fs = require('fs');
    var gm = require('gm');
    gm('./resources/dev/images/help/1_big.jpg')
        .draw('image Over 100, 100 100, 100 "./resources/dev/images/app/actGuide.png"')
        .write('./resources/dev/images/app/aboutus_modify.jpg', function(err) {
              if (!err){  console.log('done');
              }else{console.log(err.message || "出错了!"); } });

执行后,可以看到aboutus_modify.jpg是1_big.jpg和actGuide.png的合成。

1_big.jpg
actGuide.png
aboutus_modify.jpg

需要特别注意gm中函数参数的写法,其函数说明文档地址是:draw函数说明,对比上述例子中写法,希望大家多加注意。

另外:gm的APi文档地址是:gm API文档 ,可以结合GraphicsMagick的文档使用。

中文乱码

gm正常跑起来后,经常会遇到中文乱码问题。在以往GraphicsMagick的使用中,已经有不少关于这方面的总结:

  1. how to use imagick annotateImage for chinese text? –php
  2. GM中文乱码如何解决? — node
  3. GraphicsMagick中文乱码解决办法 — java
  4. 如何用imagemagick在图片上写中文 — cmd
  5. 用ImageMagick在图片中写中文的问题及解决 –cmd

上述文章中作者都对中文乱码问题提出了自己的解决方法,在GraphicsMagick的文档和社区中也有对这类问题的解答:

  1. ImageMagick v6 Examples
  2. how to apply imagemagic to other language?

总结起来解决乱码需满足两个条件:1. 文档utf-8编码; 2. 指定中文字体库。

结合Demo程序进行说明:

var gm = require('gm');
var _name = "China中文";
gm('./resources/dev/images/help/1_big.jpg')
    .draw('image Over 100, 100 100, 100 "./resources/dev/images/app/actGuide.png"')
    .font('/Library/Fonts/微软雅黑.ttf')
    // .font('/usr/share/fonts/微软雅黑.ttf')  /* 服务器上的路径*/
    .draw('text  100, 100 '+_name)
    // .resize(240, 240)
    .write('./resources/dev/images/app/aboutus_modify.jpg', function(err) {
        if (!err){
            console.log('done');
        }else{
            console.log(err.message || "出错了!");
        }
    });

上面程序得到的结果如下,可以看到中文能正常显示,而且字体也是我们指定的微软雅黑:

文字和图片嵌入成功.png

我们来分析下解决乱码的两个条件:

  1. 文档utf-8编码:这里utf-8编码是指要求文件的存储编码方式是utf-8,而不是对字符进行utf-8编码(如js中的encodeURI)。通过对IDE或者其他方式确定文件的编码方式,如有问题可自行百度。
  2. 指定中文字体库:可以通过 .font('/Library/Fonts/微软雅黑.ttf') //mac系统下.font('/usr/share/fonts/微软雅黑.ttf') //linux系统下指定。 font函数的参数是字体在系统中的存储路径。

Mac电脑的字体存储文件路径是:/Library/Fonts/,如下图所示:

Paste_Image.png

linux下, fc-list: 查询所有安装字体,fc-list :lang=zh:查询安装的中文字体, 字体的安装路径是:/usr/share/fonts。

Paste_Image.png

如果需要安装特定字体,可以到这个网站上下载,然后依据不同平台进行安装:

  1. Windows 7 / Vista – 选定文件点击右键选安装
  2. Windows XP – 复制和粘贴字体文件到C:\WINDOWS\FONTS
  3. Mac OS X – 双击字体文件然后选择安装字体
  4. Linux – 复制字体文件到/USR/SHARE/FONTS

总结

文章简要介绍了gm模块的使用以及可能遇到的中文乱码问题,希望对大家有多帮助。

作者:狐尼克朱迪
链接:http://www.jianshu.com/p/a651258c9135
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


兄弟会虐死案背后:亚裔美国人的身份追寻

$
0
0

兄弟会虐死案背后:亚裔美国人的身份追寻

宾夕法尼亚州的波科诺派恩斯镇离纽约市有两个小时的车程。驶离州际公路之后,前往该镇的道路蜿蜒经过矮小的树木和废弃的加油站,边缘生锈的招牌上显示的还是多年前的价格。这个位于纳奥米湖畔的小镇曾为前往附近缥缈山庄(Mount Airy Lodge)的游客服务,那个度假村的特色是蜜月套房,浴室里配备心形浴缸,但是由于多年失修,于2001年关闭。2007年,缥缈山庄赌场在原址开业。当地法院位于一座破败小楼的二层,楼下是精华美甲水疗店(Elite Nails and Spa)。小楼正面没有任何政府标志,也没有代表公正的天平——没有任何东西能把它与宾夕法尼亚940号公路两侧普通的商业地产区分开来。门罗县法院分发的指南上让你寻找一个带有甜筒标志的冰淇淋店。法院就在街对面。

在2015年10月一个阴沉寒冷的日子里,谢尔顿·王(Sheldon Wong)、查尔斯·黎(Charles Lai)、肯尼·关(Kenny Kwan)、雷蒙德·林(Raymond Lam)和丹尼尔·李(Daniel Li)受到波科诺派恩斯法院传讯。这五个人都是美国大学亚裔兄弟会派-德尔塔-普赛(Pi Delta Psi)的成员。五名年轻男子都是在皇后区的华裔家庭长大的。那天早上我到法院时,聚集在停车场的一名电视摄像开始跟随我。“我不是来受审的,”我说。他笑了一下,向他的同事们摆了一下头,他们已经活跃起来,把设备扛到了肩上。“呃,等那些家伙看见你,也会跟上来的,”他说。他说对了:一堆摄像机涌了上来。考虑到当时的情况,我不能太责怪他们。这些兄弟当时选择在这里的灰色山中举行入会仪式,无意中使得自己的命运可以由当地人组成的陪审团决定——当地人很想知道这些亚裔男子曾在这里干了些什么。

  • 查看大图邓俊贤(Michael Deng)的照片和在他皇后区的家中的壁炉上的奖项。

    Glenna Gordon for The New York Times

    邓俊贤(Michael Deng)的照片和在他皇后区的家中的壁炉上的奖项。

  • 查看大图宾夕法尼亚州斯特劳兹堡的法庭。

    Glenna Gordon for The New York Times

    宾夕法尼亚州斯特劳兹堡的法庭。

  • 查看大图兄弟会的入会仪式在位于波科諾斯的出租房屋中举行。

    Glenna Gordon for The New York Times

    兄弟会的入会仪式在位于波科諾斯的出租房屋中举行。

  • 查看大图2015年,查尔斯·黎(Charles Lai,中)和肯尼·关(Kenny Kwan)在被提审之后。

    Bryan Anselm for The New York Times

    2015年,查尔斯·黎(Charles Lai,中)和肯尼·关(Kenny Kwan)在被提审之后。

  • 查看大图法拉盛的大街(Main Street)和罗斯福大道(Roosevelt Avenue)。

    Glenna Gordon for The New York Times

    法拉盛的大街(Main Street)和罗斯福大道(Roosevelt Avenue)。

五名学生中的四名很快到达了,每个人都梳洗一新。谢尔顿·王、查尔斯·黎、肯尼·关和雷蒙德·林穿着合身的西服和尖头鞋,戴着墨镜,看起来更像是香港电影黄金时代的电影角色,而非因谋杀罪面临审判的兄弟会成员(丹尼尔·李会在当天晚些时候的另一场听证会上受审)。在法庭外潮湿狭窄的走廊上,这几个兄弟会成员中年龄最大的、当时26岁的肯尼·关突然开始啜泣。查尔斯·黎用一只胳膊搂着他,安慰他,同时阴郁地盯着在笔记本上匆忙记录的记者们。第二天上午,《纽约每日新闻报》(The New York Daily News)报道称,“一名兄弟会暴徒”在周四“受审前像孩子一样大哭”。

被告的朋友和家人坐在法庭后部,神情麻木,两眼放空。审判开始后,被告的年轻亲属在走廊里悄悄地为年长的亲属翻译理查德·S·克莱普尔法官(Richard S. Claypool)和一小群辩护律师之间的问候,以及漫长的起诉书宣读过程,罪名包括欺辱新生、妨碍调查、人身侵犯、合谋以及三级谋杀。

克莱普尔身材高大,已经谢顶,看上去好像睡觉都穿着法官袍。辩方律师试图减少50万美元的保释金,把自己的客户描述为全部没有犯罪纪录的守法公民,对此克莱普尔似乎不为所动。“我知道出现在我面前的会是几个衣着得体、积极配合的小孩子,”克莱普尔拖着平淡的语调说。“但是我们在这里看到的和那天晚上发生的事情是不同的。读过书面证词会发现,这些孩子们的判断力很差。”之后克莱普尔的温和态度变成了近乎愤怒:“审阅起诉书时,让我感到惊讶的是,检察官办公室同意了最低金额。50万美元的保释金不会变。”

现在到了明确谁可以取保、谁需要入狱的环节。律师们低声指示自己的客户,后者努力为显然很受打击的父母们摆出勇敢的样子。其后雷蒙德·林和谢尔顿·王与律师一起离开。当时无法提供保释金的肯尼·关与查尔斯·黎被戴上手铐送往旁边的房间。(最后肯尼·关获得了保释,丹尼尔·李以较少的15万美元获得保释)。

在外面,媒体等待着肯尼·关和查尔斯·黎被带到一辆等候的警车上,这期间我跟一个亚裔电视新闻制作人聊了聊,她也是从纽约来的。“我在想象我父母会对这一切怎么看,”她说。我们在进行的是那种任何边缘群体内部都常见的对话,你可以放松神经,不必什么都解释一番。我有点荒唐地告诉她,如果我被指控谋杀,我宁愿假装自己死了,也不让父母知道。

被告的家人零零散散地走出法院大门,一些人举起胳膊挡着脸,不想被拍到。

“他们心里在想什么?”制作人小声问道。

邓俊贤(Michael Deng)和那些因谋杀他而遭到起诉的派-德尔塔-普赛兄弟会成员们一样,是来自别的城镇的华裔美国学生。他的父亲是一个中国商人,于1990年获得了《移民法》为高技能工人签发的签证,与妻子一起搬到肯尼迪机场南端附近的长岛海滨城市长滩。邓夫人发现,过渡期比她想象中更困难。“我怀孕害口——美国的食物对我来说太寡淡了——而且我一直都觉得饿,”她半用英文半用中文告诉我。(因为邓氏夫妇想尽量保留隐私,所以她要求只用姓氏称呼她)。长滩看上去没有什么亚洲社区,也没有让人满意的中餐馆,所以这对待产的夫妇搬到了皇后区北部的法拉盛,那里到处都是移民。

1995年邓俊贤出生时,母亲觉得他需要起个美国名字。她找到一个最受欢迎的美国男孩名字排名,选择了排在第一的“迈克尔”。迈克尔的父亲为了工作在中美之间往返,迈克尔和母亲则艰难地适应着美国生活中各种平凡的调整和小小的羞辱——新食品杂货店、新公交系统,充满各种小团体的移民聚会,其他人看上去可能和你很像,但在一些重要的方面和你一点都不像。

迈克尔很快适应了皇后区的亚裔小环境。1990年,亚裔占法拉盛人口的22.1%。到2010年,这一数字突破了70%。这个人群开始渐渐打入附近的中产阶级社区,比如贝塞(Bayside),那里的学校比较好,安静的街道两边坐落着相对宽敞的房子,房子前面还有整洁、方正的草坪。迈克尔进了贝塞的74中学,当时学校的学生主要是亚裔。

迈克尔的母亲辞去工作,辅导迈克尔在学校里读的科目。“数学和科学方面我当然可以帮他,”她说。“但是英文和历史——那些东西——我只能鼓励他努力跟上。”空闲时间,迈克尔活跃在贝塞的手球场,成了一名优秀的球员。八年级时,他参加了纽约市的特殊高中入学考试,进入了布朗克斯科学高中(Bronx Science),这是纽约一流的择优录取公立学校,与斯泰弗森特高中(Stuyvesant)和布鲁克林技术高中(Brooklyn Tech)齐名。

和74中学一样,布朗克斯科学高中的学生主要是亚裔。学校里有法拉盛亚裔小圈子,曼哈顿亚裔小圈子,布鲁克林日落公园亚裔小圈子。这些团体最初可能是根据移民模式、学区和房地产开发区形成的,但是随着学生们长期接受标准化考试辅导,参加周末的中文或韩文语言课程,长时间乘坐地铁来到布朗克斯,这些圈子还会得到进一步加强。

在这些漫长的旅行之中,迈克尔和威廉·袁(William Yuan)熟识起来。他们在艺术课上结识,打算逃课去玩手球,很快就成了朋友。

邓俊贤和威廉·袁都很受欢迎,他俩不完全属于布朗克斯科学高中那群喜欢热闹派对的学生,但是也不怎么书呆子气。我问威廉·袁他和朋友们平时都玩什么,他描述了一种对于任何在美国的亚裔聚居地长大的人来说都很熟悉的生活:珍珠奶茶店、精灵宝可梦、学习小组、有钱的FOB(是指“刚下船”的亚洲移民),还有父母们不公平的过度关注,他们总觉得需要给孩子施加压力,但是由于语言障碍和文化上的无知,他们往往不知道孩子们究竟变成了什么样子。

“我们会玩英雄联盟(League of Legends)”——一种多人电脑游戏——“打手球,吃饭,”威廉·袁描述他们典型的周末。“我知道这听起来可能像是一种简单的生活,但对我们来说从来不是那么简单。我们出来玩的时候,几乎只和中国孩子混在一起,但这并不是种族主义之类的东西。我觉得物以类聚,这是人类的天性。”

要上大学时,邓俊贤面临选择,要么和威廉·袁一起到长岛石溪大学就读,要么去上当地的学校。他不想离开母亲,所以决定到进入巴鲁克学院(Baruch College),这个走读学校属于纽约市大学(City University of New York),整个校园只有几座大楼,位于曼哈顿格拉梅西公园附近。巴鲁克学院的大部分学生都住在校外,但是邓俊贤希望大学生活能够更像他在电影里看过的那样——恶作剧、姑娘,还有离开父母的自由——所以他搬进了附近的宿舍。他被分配的室友是来自长岛的18岁新生杰伊·陈(Jay Chen)。邓俊贤和杰伊·陈试图建立自己的小小校园生活,邓俊贤充当自大、世故的领导者角色,杰伊·陈扮演他的副手。邓俊贤逝世两年后,杰伊·陈为缅怀老友,给他写了一封信,回忆两人共度的时光:“我记得大一那年,我过生日的时候,你带回六箱科罗娜啤酒为我庆祝。我从来没问过你是怎么弄到的,只是很开心。当然,我们这种人手头是没有开瓶器的。所以眼前的头等大事自然就是想办法不用开瓶器打开酒瓶。拜你所赐,我现在知道900种不用开瓶器就能打开瓶子的办法。”

巴鲁克校园里小小的社交生活主要来自于它的小型希腊式体系,大一新生,特别是那些对校园生活感兴趣的人,都会被尽力招募。晚上,邓俊贤和杰伊·陈躺在房间里的床上,讨论是否加入巴鲁奇的两个大型亚裔兄弟会——派-德尔塔-普赛和人中王(Lambda Phi Epsilon)。杰伊·陈觉得兄弟会不适合他。邓俊贤选择了派-德尔塔-普赛。

“迈克尔回家后就给我讲起他遇到的各种人物,”杰伊·陈说。“起初他似乎还很热心。但是随着入会活动继续下去,他似乎变得更加疲惫,他变得不那么正常了。我们之间的交谈少了,每次他回家总是疲惫不堪,通常直接去睡觉。”

感恩节的周末,邓俊贤回到法拉盛。他在巴鲁克结交的新朋友们有很多都住在附近,他们也来他家拜访。当时邓俊贤已经开始和一个来自巴鲁克的亚裔女生联谊会成员约会,她也是从小在皇后区长大,住的地方离邓家只有几英里远。她告诉他,她们家在感恩节假期没有吃火鸡,所以邓俊贤就让妈妈比平常多做点饭,把多出来的一盒饭给了她家。他没有告诉母亲、女友或杰伊·陈,自己即将前往波科诺斯。

“亚裔美国人”是一个大体上没什么意义的说法。没有谁是说亚裔美国语长大的,没有谁和自己的亚裔美国家长一起吃亚裔美国食物,也没有谁回到自己的祖国亚裔美国去朝圣。邓俊贤以及他在兄弟会的朋友出身于华裔家庭,成长于皇后区,与我毫无共同之处——我在韩国出生,在波士顿和北卡罗来纳州长大成人。但我们基本承受着一些共同的刻板印象——虎妈,音乐课,不经审视的通往成功之路——不管它们被如何定义。我发现,自己作为韩裔的成长经历,与美国的犹太及西非移民的子女,而非中国和日本移民的子女更为相像。我和后者唯一的共同点是心怀同样的焦虑:我们中如果有一个被按在墙上,接着极有可能轮到另一个人。

歧视真的是把亚裔美国人联系起来的东西。早期的一些致力于亚裔美国人研究的学者,出自第三世界解放运动阵线(The Third World Liberation Front),那是一个与大学校园内主要着眼于欧洲裔美国人问题的倾向相对抗的组织。当亚裔美国研究项目于1970年代初开始在加州开枝散叶的时候,其课程源自关于压迫的个人叙事,以及通过发掘共通的艰辛而形成的团结一致。1971年出版的《根源:美国亚裔读本》(Roots: An Asian-American Reader),是最早一批被提供给加州大学洛杉矶分校(UCLA)亚裔美国学生的教科书之一;其编辑曾写道,英文书名中的“Roots”,并不是指某种共同的亚洲血统,而是指“美国亚裔所面临的问题的‘根源’”。

给亚裔美国人身份下定义的项目原本主要以常春藤盟校(Ivy League)以及一些西海岸大学为限,直到1982年。那一年,在底特律一家汽车工程公司工作的陈果仁(Vincent Chin),被一群暴徒殴打致死——那些人把美国汽车市场的滑坡归咎于来自日本人的竞争。当行凶者仅被处以缓刑及3000美元罚金的时候,抗议者纷纷涌上美国诸多城市的街头,进而催生出泛亚裔的团结。把人们团结起来的是这样一种意识:如果进口自日本的汽车可以让身为中国移民之子的陈果仁被杀,那么“亚裔美国人”身份的概念就有其影响。

“他的死亡是一个重大的觉醒时刻,”韩裔美国电影导演、前黑豹党(Black Panther Party)成员崔明慧(Christine Choy)对我说。“这件事刺激了很多人,他们表示无法再忍受下去,不能就这么放任自流,必须有某些立法或政治要求。”

陈果仁去世之时,美国大学的人口构成刚刚开始发生重大变化。在《1965年移民与国籍法》(Immigration and Nationality Act of 1965)通过之后涌入美国的上百万亚裔移民的孩子长大了。从1976年至2008年,被四年制大学录取的亚裔美国学生的人数增长到原来的六倍。这些年轻人中,有很多人毕业于相同的精英学校,去相同的教堂,在相同的补习班上学习,但从来没人跟他们解释他们的亚裔身分,至少是没用多文化学术界的规范语言解释。

他们发现自己身处关于平权法案的国家辩论的中心。在80年代中期,学生和教授开始指责布朗大学(Brown)、斯坦佛大学(Stanford)和加州大学伯克利分校(University of California, Berkeley)等精英大学用配额限制亚裔学生的数量。在那些大学否认这些指责之后,校园里掀起了一场运动,要求设立更多亚裔美国研究课程,以及亚裔美国俱乐部、学生组织和社交俱乐部,最后,还有兄弟会。这场争论仍在继续,而且依然激烈。2014年,反对平权法案的一个组织起诉了哈佛大学,指控它在招生过程中歧视亚裔美国学生。这起诉讼至今没有结果,它启发一个由64个亚裔美国组织组成的联盟在次年对哈佛提起诉讼。本月,司法部公布了一份备忘录,表明该机构计划调查2015年的那起诉讼,这两起诉讼也因此重新引起了人们的关注。

崔明慧和雷妮·田岛-佩尼亚(Renee Tajima-Peña)于1989年执导的纪录片《谁杀死了陈果仁》(Who Killed Vincent Chin?)在美国各地的亚裔美国研究课堂上播放。在之后的十年里,一种集体身分逐渐形成,它植根于陈果仁的死以及对平权法案的争论,但是对那些以华裔、韩裔、日裔和菲律宾裔身分长大的人来说,这个集体身分依然显得陌生。不管是在学术研究中还是在私下的日常谈话中,这个词都不准确,而且只局限在学术界。到了90年代初,洛杉矶的骚乱将亚裔美国人推上了全国的舞台,关于“根源”的热烈讨论已经基本上被一种畏缩的、学术性的恐惧症所取代,它试图弄清为什么亚裔的店铺——尤其是韩裔的店铺——会成为暴徒打击的对象,但它没有提问的平台,也缺乏提问的信心。

现代亚裔美国兄弟会诞生于80年代的抗议,以及亚裔美国学生在校园里日益感受到的孤立。获得全国亚太及印度美国大学校友会协会(National Asian Pacific Islander Desi American Panhellenic Association)认可的18个亚裔美国兄弟会和女生联谊会中有16个是在1990年至2000年创立的。它们的宗旨声明承诺“塑造成功的领导者”,服务社会,以及唤醒“社区意识”。这些兄弟会和女生联谊会的讯息惊人地相似——团结起来,取得意想不到的成功,用兄弟姐妹情谊建立专业高效的校友网络。入会仪式往往是宣传模糊的泛亚洲身分,这个身份反映出亚裔美国学术研究与活动的历史,但是由于多年的冷漠,它的迫切性已经慢慢消失。

1994年,也就是邓俊贤的父母从中国移民到美国的那一年,宾厄姆顿大学(Binghamton University)的11名学生成立了派-德尔塔-普赛兄弟会(Pi Delta Psi)的第一个分会。到2000年,该兄弟会已在四个州的11所大学设有分部。最初,兄弟们用自己在亚裔美国研究课程中学到的零星知识拼凑出一个宗旨。每个兄弟会分会的“教导员”都为宣誓入会者设计了一个课程。有几周会用于研究一些可以想见的话题,比如民族食物或亚洲国旗的起源,但重点主要是在亚裔美国人经历的种族歧视案例上。在过去20年里,每个分会的课程都略有改变。比如,在一个“环节”(这是兄弟会对教育活动的称呼)当中,入会者要研究陈果仁被害案,并撰写报告。另一个环节的重点是洛杉矶骚乱以及它对韩裔小生意人的灾难性影响。大约就是在邓俊贤被害那个时期,兄弟会还计划推出一个关注陈宇晖(Danny Chen)之死的环节,陈宇晖是一个来自曼哈顿中国城的年轻人,在军中遭受捉弄后自杀身亡。“有点像获得期中学分,”纽约大学(New York University)的派-德尔塔-普赛兄弟会校友莱克斯·恩戈托(Lex Ngoto)对我说,他现在在银行业工作。“我们甚至会在教室里开会,领取作业和报告。然后兄弟们会给我们做测试,如果我们有问题答不上来,就得做俯卧撑。”他还说:“最后,我很感激它。我高中时就跟亚裔孩子一起玩,但我们并没有真正觉悟到其中的意义。了解我们——我是指亚裔美国人——的遭遇之后,我看清了很多东西。”

我采访的很多派-德尔塔-普赛兄弟会的校友都表达了类似的感触:通过了解共同的苦难史而产生亲情,通过教育获得觉醒。他们也提到了那些宣誓环节,听上去更像典型的戏弄新生活动,有时甚至只是可笑而无害的。他们总是穿着黑色汗衫或军装,进行信任背摔、寻宝搜索等活动,还有一个环节叫“分开与征服”——在这个环节里,几名入会者被送到不同地点,不许带手机,然后根据指示,在一个预定的会面地点找到彼此。在正式成为兄弟会成员之前,入会者要经历“地狱般的一周”,不能睡觉,还要背着通常装满砖块、混凝土块或保龄球的书包。

不是所有派-德尔塔-普赛兄弟会的入会者都经历了深刻的种族觉醒。纽约州立大学布法罗分校分会的一名前成员告诉我,他对这个兄弟会的文化课程怀有矛盾的感觉。“这个兄弟会声称他们想提高亚裔美国人的觉悟,但那全是瞎扯,”他说。“实际上就是玩乐,然后感觉你好像属于什么组织。”我采访过的派-德尔塔-普赛兄弟会校友都表示,俯卧撑是最常见的一种体罚。布法罗分校分会的那名成员回忆,在他的入会仪式上,他被蒙上眼睛数小时,还被推进垃圾堆。所有人都回忆曾在一个被称为“玻璃天花板”的仪式中遭到殴打。

2013年12月一个阴冷的上午,邓俊贤准备打破“玻璃天花板”,他穿着黑色帽衫、黑色运动裤和军靴。他的背包里有一瓶水和一个笔记本,上面写着他对亚裔美国人遭受压迫的一些想法。

之前一晚,邓俊贤和几名同学从纽约市开车来到波科诺斯市唐克汉诺克镇,这里是一个小小的社区,他们进了坎德尔伍德大道上的一栋房子,这里整个周末都被租了下来。它宽敞朴素,这种空旷的风格在不缺土地的小镇很常见。平坦的后院里长满了草,四周种着一排单薄的小树,邓俊贤和另外几位入会者将在这里举行加入派-德尔塔-普赛兄弟会的仪式。

纽约市立大学巴鲁克学院(Baruch)和皇后区圣约翰大学(St. John’s University)年长的兄弟们在半夜陆续到来,邓俊贤和其他入会者给他们上菜,发牌,并且开始举行兄弟会的一些入会仪式,包括匍匐穿过庭院的“巴丹死亡行军”——这是一种亚裔团结活动,用来让入会者体验日本皇军对菲律宾战俘的折磨。

在午夜过后的某个时间,兄弟们聚集起来举行玻璃天花板仪式,它是该兄弟会最重要的一个仪式,也被称为严酷考验(Gauntlet),简称“G”,每个分会的形式略有不同,但大致包括三个阶段:第一个阶段,入会者被蒙上眼睛,同指派给他的“大哥”(一个年长的兄弟会成员)分开,他们中间隔着一排胳膊挽在一起的兄弟。这道人墙主要是象征着被迫接受亚洲男人软弱、爱拍马屁的美国偏见与实现辉煌成功和男子气概之间的那道障碍。大哥呼喊入会者(也就是“小弟”)的名字,入会者把胳膊抱在胸前,向着大哥的声音走去。他很快会撞到兄弟们的人墙上,他们会说他是“中国佬”、“东方佬”以及他们能想到的任何种族歧视蔑称。咒骂大约持续十多分钟。在第二个阶段,入会者被指示冲过兄弟们组成的人墙,而他们会轮流把他推回起点。第三个阶段跟第二个阶段没有很大差别:宣誓者依然被蒙着眼睛,向着大哥的声音走,但这次,他不是被推回去,而是被打倒在地,在有些分会,甚至会对入会者擒抱摔打。一旦入会教导员认为入会者受的苦已经够了,就会叫停,然后可能会问他,你为什么不叫兄弟们帮忙呢?

我不知道要去求助,入会者这样回答。

向你的兄弟们求助吧,入会教导员指示。

入会者要求帮助。他的兄弟们在他身后站成一条线,以整齐划一的动作庄严地指导他到他的“老大”那里去。

这一切发生的时候,入会者应当想念他的父母、思考他们身为移民所作出的牺牲,他们曾面对的羞辱,以及亚裔在美国生活所面对的隐形压迫。那些推搡、摔打和种族主义的辱骂意在从肉体层面体现他们的斗争。在最后一段路上,所有的兄弟会成员将入会者引向他的“老大”,这是为了教导他,与亚裔同胞团结一致是他在白人世界中取得成功的唯一希望。

正式来说,邓俊贤入会时遭受的这种摔打是不被全国兄弟会允许的。派-德尔塔-普赛的律师称其为“直接违反兄弟会的政策”。但是,来自几个不同学院的前成员都告诉我,“玻璃天花板”在这个兄弟会的文化中可谓根深蒂固。邓俊贤去世时,丹尼尔·李担任巴鲁克学院的派-德尔塔-普赛兄弟会会长,他对法庭讲述他们在该校如何实施这个仪式,他说,“在现实中,”派-德尔塔-普赛兄弟会的全国领导人“知道发生着什么”。

邓俊贤在最后一堂入会课上接受了玻璃天花板的考验。他通过了前两个阶段,但在第三个阶段中期,他在遭到一次摔打攻击之后踉踉跄跄地站起来。然后,根据丹尼尔·李的证词,入会助理肯尼·关从10到15英尺之外全速冲向邓俊贤,把他撞倒在地。这一次他没能站起来。

丹尼尔·李当时21岁,后来他告诉检察机关,邓俊贤倒下后发出了“呻吟声”。据丹尼尔·李的证词,当时21岁的入会教导员谢尔顿·王扶起邓俊贤,在其他人帮助下把他带进租来的房间。邓俊贤的“老大”,当时23岁的查尔斯·黎告诉探员,邓俊贤的身体“直挺挺的,像木板一样”。兄弟会的成员们脱下他那被霜雪浸透的潮湿冰凉的衣服把他放在壁炉边,给他盖上毯子。根据警方的时间表,凌晨5点05分,一名兄弟打电话给当护士的女朋友,问她是什么情况可能导致邓俊贤完全没有任何反应。八分钟后,另一名兄弟用谷歌搜索了“清醒”和“不清醒”。凌晨5点55分,一个名叫雷维尔·邓(Revel Deng)的兄弟会成员四次发短信给朋友,询问关于他祖父从楼梯上跌倒后去世的情形。在此期间,身在波科诺斯的30多名兄弟会成员中没有一个人呼叫救急号码。根据一份对探员做出的口供,之所以没有人叫救护车,是因为有人查询费用之后,觉得价钱太高。

凌晨6点左右,谢尔顿·王、查尔斯·黎和另一名兄弟将邓俊贤带到盖辛格怀俄明谷医院急诊室。不久后,邓俊贤的母亲于上午6:42接到医院电话,通知她她的儿子正处于昏迷状态,问他是否有药物过敏。医院也联系了当地警方。

查尔斯·黎在医院等待“小弟”的消息期间开始发送短信,警察后来发现了他发给派-德尔塔-普赛兄弟会的全国会长孟昭安(Andy Meng)的消息,孟昭安的姐姐孟昭文(Grace Meng)是代表皇后区第六选区的国会议员,该选区主要由亚裔构成。上午7:25,查尔斯·黎给雷维尔·邓发短信:“把所有东西都收起来”。在医院里,查尔斯·黎告诉一个探员,他和一个全国兄弟会的兄弟联系过;他电话中的短信表明,孟昭安鼓励他们隐藏兄弟会的物品。

孟昭安的律师迈克尔·A·文特雷拉(Michael A. Ventrella)表示,孟昭安一直与警方合作。“他当时不在现场,”文特雷拉说,“是事后才了解相关情况的。在他的管理之下,兄弟会之前已经发布了严格的准则,禁止发生这种行为。”(雷维尔·邓、查尔斯·黎和雷蒙德·林拒绝为本文置评。)

第二天早上,邓俊贤在母亲陪伴之下去世。后来一名法医病理学家确定他死于头部多次创伤性损伤,而且治疗的延误对他的死亡“产生重大影响”。

 2015年11月末,派-德尔塔-普赛(Pi Delta Psi)兄弟会成员的第二个开庭日在距孛可诺松林区(Pocono Pines)25分钟车程的斯特劳兹堡(Stroudsburg)举行。关、林、王三人都穿着似乎是一个月前穿的西装,陪伴他们的是同样坐立不安的律师团队。不久后,穿着监狱灰色衣服、戴着手铐的查尔斯·黎(Charles Lai)出现了:他的家人没能成功将他保释。他几乎有些过分殷勤地对兄弟们点了点头,似乎是想表示歉意,但他在诉讼过程的开始一直都只是专心地盯着远处的墙。一名警官对他们掩盖证据的罪行作证,律师团队提交了几项动议,随后检察官办公室让现已是派-德尔塔-普赛前任主席的丹尼尔·李(Daniel Li)起立。在一小时结结巴巴、磨人的证词中,李说他看到了林、黎、关三人相继抱住并摔倒了邓,使他在最后一击之后陷入了昏迷。当所有人都在苦思冥想该做什么的时候,李说,他已经睡下了,错过了整个掩盖证据的过程。

李证实称,四名剩下的兄弟瘫坐在椅子上,盯着自己的手。当所谓的“叛徒”采取立场的时候,法院中并没有上演黑社会电影中的那种戏剧场面;没有人盯着李,也没有人怒气冲冲地与律师密谈。相反,法庭内弥漫着尴尬的沉默,一部分是因为如果不是检察官再次提示他,他可能也答不上来,同时也是因为一个有关团结一致的谎言在这些年轻男子面前揭穿,他们之前竟然愚蠢地相信了这个谎言。因为李配合指证了四名兄弟,宾夕法尼亚州减轻了对他的指控,不再包括谋杀罪,同时也推迟了他的审判程序。

2016年5月的一个周日造成,一名叫Rekstizzy的韩国说唱歌手朋友给我发了一则短信。Rek是他更为人知的名字,他在皇后区长大。和邓俊贤一样,他也是从布朗克斯科学高中(Bronx Science)毕业。现在Rek住在洛杉矶,运作着一个旨在从所谓的另类右派手中夺回名为佩佩(Pepe)的卡通青蛙的运动。但他最初是在2012年联系我的,当时还是林书豪(Jeremy Lin)在纽约尼克斯队(New York Knicks)短暂的神奇巅峰时期,他已经是皇后区亚洲人的代表了。这包括了一个亚洲人的文化博客——美国人将其称为Gumship,还有一系列YouTube视频,Rek在其中向禁欲的男性介绍像Hello Kitty一样可爱的产品可带来的乐趣。Rek在宾汉顿大学(Binghamton)上学期间,曾考虑过加入派-德尔塔-普赛,他在短信中告诉我说他当时正在拉斯维加斯跟几个“兄弟会的兄弟”参加派对。其中一人向他透露说他被控谋杀,他感到非常彷徨无助。这个人正是肯尼·关(Kenny Kwan),他就是在法庭掉下眼泪的派-德尔塔-普赛成员。

几天后,关从布鲁克林的家中给我打了电话。他说他听说一名亚裔作者将要从亚裔的角度撰写这个案件。他停顿了一下,问我是否认识作者能写出一篇关于他的故事,其中不带有对亚洲人的偏见。我告诉他说,我非常愿意跟他交谈,但我也想说清楚:我并不是要写一篇使他和他的兄弟免罪的文章,在给我回电之前,他需要先跟律师谈谈。在过去一年,我发现自己一直在想关说的“亚洲人的角度”究竟是什么意思。他是在要求公平,还是在要我选边站?

关并没有给我回电,但他并不是唯一一名想着与我交谈是否会有价值的巴鲁克学院的兄弟。几个月前,我在下曼哈顿区谢尔顿·王(Sheldon Wong)律师的办公室会见了他。王又高又帅,颧骨突出,当他感到不安的时候,他翘起的嘴会抽搐。在孛可诺传讯期间,当王的兄弟们扭动、耷拉着头,尝试盯着勇敢的面孔的时候,王则一直盯着地毯上的一处。在和王会面的时候,王一直在似乎是紧张和安静的诚挚之间切换。在那些更真诚的时刻,我可以看到为什么他可以担当宣誓教员的原因——原因就是,他说,他妈妈一直鼓励他以心理学家作职业。

他的生活,至少在表面上,和邓俊贤没什么差别。他出生在法拉盛,但童年早期在皇后区的牙买加区里一个以意大利裔美国人为主的社区度过。他的母亲在青少年时期从香港移民到纽约,在王5岁时,她离开了他的父亲,一名建筑工人,他们俩搬到了法拉盛,她在那里做餐厅服务员。“我在牙买加的时候,大多数朋友都是那个社区的意大利孩子,”王说。“当我们搬到了法拉盛,那里当时还没有现在这么多亚洲孩子。我还是仅有的那些其中一个。我的朋友主要是黑人和拉美裔的——我当时会和周围的任何人一起玩。”

王去了皇后区贝赛的185中学读书,距离邓俊贤童年的家仅几英里远。“亚洲孩子总是一起玩,”王说。“小团伙是根据种族和课外活动——体育、社团什么的来划分的。随着时间流逝,我注意到孩子们越来越难走出小圈子,和不同种族的人交谈。”他继续用一种谨慎,几乎文绉绉的方式说:“我知道纽约被认为是一个大熔炉,但如果你来自皇后区,那里更像是一个气泡。你所遇见的人和你自己非常相似。”

在巴鲁克学院读一年级的时候,一名派-德尔塔-普赛兄弟会的“新信徒”(指新加入的兄弟)接触了王。因为巴鲁克学院的通勤-学生文化,更多学生和来自同一城市和高中的朋友社交。派-德尔塔-普赛兄弟会的招揽策略是找到所有符合条件的男生,甚至包括非亚裔的学生,邀请他们加入。王参加了一次会议,和那里的几个男生相处得不错,决定尝试一下兄弟会。

直到他向派-德尔塔-普赛宣誓加入,王说,他都不知道自己的种族过去受过什么样的苦难。他不知道陈果仁(Vincent Chin)之死,也不知道松丰三郎诉美国政府案(Korematsu v. United States),1944年美国最高法院坚持罗斯福(Franklin D. Roosevelt)总统的行政命令,将日裔美国人关进集中营。随着他沉浸在从兄弟会了解到的扭曲但仍具启示性的亚裔美国人被迫害史,他越来越对自己接受的纽约公立学校教育中的空白感到沮丧。王说,这些遗漏是不公平的。“我不明白为什么我们不关注一个种族,或者为什么我们要忽视某个种族,”王说。“有时候,感觉就像发生在亚裔身上的事情不那么重要一样。”

新的教育改变了他;让那些移民家庭的孩子和他们的父母产生距离的沉默开始闭合,生平第一次,王和他的母亲谈了她在美国的早期经历,在这个说着陌生语言的国家里感到了恐惧,在这个以白人为主的国家中,从细小却持续的爆发中她能感受到自己的隐形和无关紧要。他说他从没有像在自己觉醒的那些天里那样亲近母亲。“你知道亚裔家长是什么样的,”王说。“如果你不问,你就不会了解他们的生活。”他开始感到自己是某种东西的一部分。王得到了一次“招标”,他开始了加入兄弟会的程序。在那里,他学到了更多关于亚裔美国人所受的迫害,几年之后,他把同样的课程教给了邓俊贤。

5月15日,邓俊贤死后三年半,关、黎、王、林再次鱼贯走入斯特劳茨伯格法庭。法庭的墙上,暗色调的油画配着落了尘土的红色帷幔,画中是些已经作古的男人。那之前两周,宾夕法尼亚州大学Beta Theta Pi兄弟会的八名成员在另一桩虐死案中被控杀人罪。案件牵涉一个名叫蒂莫西·皮亚萨的18岁新成员。两案颇有相似处:皮亚萨也像邓俊贤一样,经历了一种被称作“铁手套”的仪式之后死亡(但该仪式不包括肉体虐待)。这种相似性让赶来报道的媒体格外多。记者们在法庭外走廊上做准备的时候,很多人的问题都和宾州大学有关。

助理区检察官金伯利·A·麦茨格坐在控方席。她的身体向后倾,注视着越聚越多的人群。家属代表不安地扭动着身子,身下狭窄的木质坐席发出吱呀声。但这一次,被告眼中没有上次出庭时那种安慰和回避的眼神。麦茨格简要概述他们在邓俊贤之死中所发挥的作用(撞人的行为、那些短信、没有及时呼叫医护人员,以及匆忙中销毁有关兄弟会身份的证据)的时候,他们没有彼此看对方。法官问他们,是否理解他们所作申辩的意义。他们同时低声回答:“理解”。

对于故意杀人和拒捕指控,派-德尔塔-普赛兄弟会成员选择有罪申辩。(大约30名成员,包括安迪·孟和来福尔·邓,仍在邓俊贤一案中面临较轻的指控。兄弟会本身也被控三级谋杀和其他罪名。邓俊贤家人还对被告提起了民事诉讼。)上述四名主要被告要到年底才会获得量刑。根据宾夕法尼亚的法规,针对无前科的被告,这些罪名的推荐刑期是22到33个月。

亚裔是美国人中最孤独的群体。80年代的集体政治意识已经被一种无声的、无人理会的孤立取代。那种孤立来自这样一种认识:你可以出生在美国,你可以成绩优异、经济条件优沃,但你仍然感到在这个国家的公共话语中无足重轻。当前,亚裔美国人中对于团结的理解是模糊和漫画式的,仅限于家庭野餐时的闲聊,或者酒醉之后关于菜肴的讨论,让在座的每个人想起他们母亲的厨艺。此外的一切都是困惑,不知道该站在哪一边,因为选择站在我们自己这边很少是一种可能的选项。对多数美国人来说,亚裔的骄傲是一个可笑的概念。种族歧视事件发生之后,也不会引起真正的大声抗议。有人提出种族歧视问题,也会很快被否定。共同的历史只有通过陈年旧事去体会:陈果仁被害案、是松案、巴丹死亡行军,以及我们在共同经历这些事件的幻觉。在这个国家,我们已经没有了行为和自我认知的参照点,而亚裔兄弟会也不过是向着寻找身份认同迈出的笨拙的一步。但是,当他们诚实面对自己的亚裔身份,拒绝堕入那熟悉的沉默之时,他们也是在发出一份自我价值的声明。这些孩子们以他们毁灭性的方式,去尝试用一句警语修改那个美国梦,那个曾经把他们的父辈带到这片土地上的美国梦:

他们说,我会成功。但不能没有兄弟!

邓俊贤的家人仍住在皇后区那座陈设简单的两层住宅里。他这一生大部分时间是在那里度过的。室内唯一可以算作装饰的是一只玻璃橱柜,还有壁炉架台上摆满的邓俊贤的各种奖杯。和他的母亲谈话时,我们坐在皮沙发上;沙发一尘不染,完全看不到家里有孩子的迹象。邓俊贤的父亲坐在一边,已见稀疏的头发被染过,向后梳,手局促地放在膝盖上。每当她谈及任何无关儿子小时候的事,她就从普通话转换成英语。孩子的父亲还没学会英语。她在遵照医嘱:他不久前做过一个心脏手术,医生要求他避免诱发焦虑的活动,包括谈及他死去的儿子。

邓俊贤的母亲带我上楼去他的房间:一间卧室,窗帘拉着;一间书房,有一张精美的深色木质书桌,仿佛是从某个电视剧中律师的办公室里淘回来的。她说,自从邓俊贤去巴鲁克,她就没动过这两个房间。书架上摆放着SAT备考书和几本作文本。在本子上,他用工整圆润而稍向左倾斜的字体,描述着他对Ace手球的看法、纽约市特殊高中的细分情况,还有他对自己周围世界的种种观察。2008年10月,他上八年级时,邓俊贤这样写道:“穿一件大衣,去Alley Pond Park,跑到一棵树下(为了躲雪),看着雪花飘落到树上和地上,我最喜欢这样打发冬日的时光。”

他的母亲为我描述她在波科诺派恩斯医院度过的那个夜晚。儿子已经没有希望了,但她决定让他保持呼吸,好让孩子的父亲有时间从中国赶来。那个晚上,她守在孩子身边,在他的手臂上针灸,竭尽全力地想要挽救孩子的生命。“你无法相信这样的事会发生在这样一个健康、快乐的大小伙子身上,”她对我说。“我在中国学的针灸,我想也许我能让他醒过来。医生知道人已经不行了,所以他们也不拦着,因为他们想让我保留那么一刻的希望,希望我能让他回来。”


关于区块链,投资的一点随想

$
0
0

关于区块链,投资的一点随想 (Part One)

1/ 现在区块链和 ICO 的狂热,堪比95-96 年互联网的第一波热潮。

2/ 97 年之前上市的互联网公司,除了 Netscape, Yahoo, 绝大多数公司六七年后的终局是:破产或者等价于破产(价格缩水90%以上).

3/ Netscape 1995年八月上市当天的收盘市值是二十九亿美元,后来1998年十一月被 America Online 以四十二亿美元收购,三年多回报 44%。Yahoo 1996 年上市时 33 美元, 2000年最高时 475 美元 (等价于市值一千两百亿美元)。人们只是被这些上了头条的新闻所鼓舞.

4/ 但破产或者等价于破产的例子是绝大多数。同期上市的如 Excite, Infoseek, Lycos 要么破产,要么被低价收购.

5/ 具有讽刺意义的是,真正赚大钱的是收购大量域名的公司。有域名大亨囤积数十万个域名,2004年时以接近两亿美元的价格出售。可以参见我的老文章.
王川: 域名大亨叶云的传奇 — 为什么投资不只是买股票

6/ 还有硅谷核心地区的房地产,2000年比 1994年底相比,价格普遍翻了一番还多。少数工程师意外的靠买房的收益,补偿了股票期权破灭的损失.

7/ 单个技术或者应用的初创公司未来谁能成功,最初很难预测。这个在区块链和 ICO 上,也同样适用.

8/ 大多数人根本不理解区块链的技术基础,不知道加密算法的不对称性,不知道 merkel tree, 不知道 Proof-of-work (工作量计算证明),没有看过中本聪最初的白皮书,很难真正理解区块链的概念,因为这是一个全新的,没有先例可以类比的商业模型。即使是有计算机背景的人,要全面深入理解所有的概念,也要花几个月的时间. 而且每天都有新的发展,要想掌握,没有捷径。

9/ 因为不理解,所以最初给这个东西贴上一个标签 “傻B,骗子”等等是一个很自然的事.

10/ 即使因为好奇而参与购买比特币者,很多要么就是卖得太早,要么就是丢失掉 Private Key 或者钱包被盗,要么就是每次价格下跌50%以上时被迫割肉撑不下去,要么就是比特币存在 Mt Gox 拿不回来了。真正长期大量持币坚守到现在的寥寥无几.

11/ 人们对于一个事物可以有多个角度的观察和解读。对于你没有用,并不意味着对于别人没有用。男人觉得一个破包包要几千甚至上万美元毫无道理,女人觉得男人着迷于看足球赛不可理喻,但这对于相应的群体都是客观存在。能够全面理解不同群体在同一时间对同一件事物的不同角度甚至截然相反的解读,非常重要.

12/ 第三世界还有几十亿居民,没有可靠,方便,便宜的金融服务,拉美非洲很多国家常年恶性通货膨胀。一个保值的,加密的,方便的数字货币给了他们新的选择,尽管现在使用界面还很初级,还有各种软件安全问题。这些是很多发达国家居民可能无法理解的.

13/ 这是一个比烂的世界,一个产品即使有各种缺点不足,只要竞争者比他更烂,他就可以脱颖而出。但人们身在其中,往往因为自己的各种缺点看得很清楚,灯下黑,没有横向比较,从而可能过于悲观,得出错误的结论.


通往SegWit的漫长之路:比特币最大的协议升级是如何成为现实的

$
0
0

通往SegWit的漫长之路:比特币最大的协议升级是如何成为现实的

96
作者 Excellion_ 
2017.08.28 15:47 字数 7209 阅读 385评论 1

隔离见证(SegWit)已在比特币上激活了。截至今天,比特币网络上的所有SegWit就绪的节点已经在执行新的规则,标志着比特币迄今为止最大的协议升级成为现实。

但是激活来之不易,也非一朝一夕达成。

这篇文章对通往SegWit的漫长道路的一个回顾。

问题

比特币交易由两个主要部分组成。一部分是“基础交易数据”,这包括了那些比特币被移动和被移向的位置(地址),以及一些其他数据。第二部分被称为“见证”,其中包含了一些加密签名数据的代码,用来证明比特币的所有者确实想要使用比特币。

正是这些签名数据给比特币交易带来了一些复杂性 。在所谓的“延展性漏洞”中,任何人都可以在比特币签名创建之后稍稍改变这些签名,且不会使签名无效。这意味着整个交易的发生,更具体地说是交易编号(txid),可以被交易的中继人或矿工改变。

2015年在比特币网络上发生的延展性攻击的数据。 红线大致代表网络上的被延展的交易

这本身不一定是一个大问题。交易仍然有效, 比特币仍然会从一个地方转移到另一个地方,且这些都是在完全相同的条件下进行。但是,由于未确认的交易的存在,这的确会使创建新的交易变得更加麻烦:新的交易需要知道它们所依赖的交易编号 。这反过来又使在比特币之上构建某些第二层协议(如双向支付渠道)变得更加困难。

想法

通过“分离 ”签名数据与其他交易数据来解决延展性漏洞的想法可以追溯到几年前。

早在2012年,比特币核心的贡献者Russell O’Connor,Matt Corallo,Luke Dashjr和Gregory Maxwell以及Bitcointalk的版主“Theymos”就在IRC 比特币开发渠道上讨论过这个问题,但当时他们没有找到一个可以成功把签名从比特币网络上分离出来的方式。

Russell O’Connor,Gregory Maxwell,Luke Dashjr和Theymos在2012年在IRC上讨论了延展性漏洞

一年后的2013年8月,由于比特币核心的贡献者Peter Todd和Gregory Maxwell在IRC上进行了类似的讨论,这个问题又重新浮出水面。但是在那时,两人在依照各自的想法对抗延展性方面都取得了进展 。“我是说把scriptsig [整个分开]。” Maxwell写道:“我甚至建议使用不含Scriptsigs的交易作为[交易ID]。”

一个月之后, Maxwell又和著名的密码学家Adam Back博士在IRC上讨论了延展性的问题。这次,Back建议在计算交易ID时省略签名。虽然,Maxwell评论说:“把签名从txid中分离出来可能会有所帮助,但这是一个深层的硬分叉变化… 而且实际上很难保证安全性。”

侧链

Blockstream最初为比特币区块链提出侧链扩展方案

Blockstream最初为比特币区块链提出侧链扩展方案

2014年8月, Adam Back,Gregory Maxwell,以及企业家和投资者Austin Hill,和几位比特币核心的开发人员(包括Pieter Wuille博士)合作创立了比特币技术公司Blockstream 。该公司侧重于侧链技术,即可以有效地与比特币挂钩的替代区块链。

到2015年初,Blockstream的工程师决定在该公司的侧链原型产品Elements中添加一项新的功能,并于同年6月公布。该功能将通过将基础交易数据与见证数据分离到不同的数据结构,最终解决侧链上的延展性问题。

当然,这个新功能的名称就是,隔离见证。

区块大小争议

有关区块链大小的争议已经有一段时间了:从技术上讲,是从2010年10月开始;更具体的来说,是从2013年10月起;最终,是在2015年春天破土而出,进入公众视野:

前Bitcoin Core首席开发人员Gavin Andresen和Bitcoinj首席开发人员Mike Hearn认为,Bitcoin的1兆字节大小限制应该通过硬分叉来增加。硬分叉是一项与原有的比特币系统不兼容的协议更改,要求几乎整个比特币生态系统升级。这并不是一项容易的任务 – 因为比特币社区并没有对这一改变达成共识。

无论如何,2015年夏天,Andresen和Hearn宣布,他们将使用Bitcoin XT软件客户端来推进他们的计划。这一备受争议的举措使得比特币开发社区和行业处于一种紧急状态。

为了解决这一分歧,并帮助寻找有可能解决区块大小争议的方法,比特币社区在2015年下半年迅速组织了两场会议(或研讨会):蒙特利尔比特币扩容会议和香港比特币扩容会议。

在蒙特利尔会议上提出的最具发展前景的扩容建议之一是闪电网络,这是一种复杂的第二层扩容解决方案,仅在几个月前在Joseph Poon和Thaddeus Dryja发表的白皮书中进行了详细介绍。唯一的问题是:这个解决方案需要对延展性进行修复 。

软分叉

Lombrozo(CodeShark)、Wladimir van der Laan(wumpus)、Luke Dashjr(luke-jr)以及 Pieter Wuille博士(sipa)在IRC上讨论SegWit作为软分叉的可能

在那个时候,大多数人仍然认为隔离见证不能在没有硬分叉的情况下在比特币的主链上实现。

除了Bitcoin Core的贡献者(和Bitcoin Konts的维护者)Luke Dashjr。

在2015年10月,两场比特币扩容会议之间,Bitcoin Core的贡献者Eric Lombrozo,Pieter Wuille,Wladimir van der Laan和Luke Dashjr在IRC上讨论了一种可能的软分叉的新模式。在这次讨论中,Dashjr指出,会议上所提出的机制不适用于所有潜在的软分叉,如SegWit软分叉。

有趣的是,这件Dashjr认为是显而易见的事情 – 即将SegWit作为软分叉来部署- 从来没有其他人这么想过。甚至连Dashjr自己一开始似乎也没有意识到这种可能性的影响。

为了将SegWit部署为软分叉,见证数据必须放在比特币区块的一个新的独立结构中。而所有这些见证数据的“锚” (“Merkle树根”)都必须转移到比特币区块的一个有些非常规的部分中:奖励矿工新硬币的coinbase交易。

尽管这个做法有些不寻常,在之后的几天和几周内,Bitcoin Core贡献者意识到这种方法带来了一个额外的好处。通过把见证数据放在比特币区块上一个独立开来的结构中,比特币区块的大小会增加,但这些变化并不会被未升级的节点注意到。这实际上可以在不增加比特币现有区块大小的情况下增加比特币区块的大小 。

在第二次比特币扩容研讨会的前几周,一些比特币核心的贡献者认为,他们可能终于找到了一个至少可以暂时区块大小限制争议的解决方案。隔离见证将以向后兼容的方式有效地提高区块的限制,同时修复长期存在的延展性漏洞,从而实现更先进的扩容解决方案,如闪电网络。

一个三赢的解决方案 – 至少他们认为是这样。

展示

隔离见证 – 作为软分叉 – 首先由Pieter Wuille于2015年12月在香港举行的比特币扩容研讨会上提出。很多人是第一次听到这个提案,且最初该提案似乎收到了热情欢迎。

在第二次“比特币扩容”会议结束之后不久,Gregory Maxwell就提出了一份以SegWit为核心,被称为“扩容路线图”的计划。这一路线图很快得到了Bitcoin Core开发团队以及比特币生态系统中的其他开发人员和用户的支持。

批判

尽管最初众人都对此提案感到非常兴奋,隔离见证也受到了许多批判。

有关提出的的协议升级的担忧各不相同。前比特币核心的贡献者Jeff Garzik – 其成立了自己的开发公司Bloq- 并不认为SegWit是一个充分的短期扩容解决方案。 同时,Bitcoin XT的首席开发人员Mike Hearn也没有完全相信这个提案:他把这个解决方案视为一种“会计诈术”,并在不久之后完全退出了比特币的开发。

替代软件客户端Bitcoin Classic的开发人员Jonathan Toomim认为,这个提案既“难看又笨拙”,并建议最好将其作为硬分叉来试试。甚至Bitcoin Core的贡献者Peter Todd也有自己的担心,特别是与挖矿有关。

然而,这些问题中的大多被都被认为是可解决的,不可信的或值得Bitcoin Core开发团队的权衡。软分叉升级就此开始发展。

发展

尽管 “隔离见证”的一个版本已经在Elements上实现,但比特币主要版本的代码大部分尚未被写入,这不仅仅是因为需要将其作为软分叉来实现,还因为比特币上 的SegWit将会包含一系列Elements中不存在的新功能:例如,增加区块大小所需的“见证折扣”,点对点网络的新兼容性等。

具体的比特币改进计划BIP141由Pieter Wuille,Ciphrex首席执行官Eric Lombrozo和独立Bitcoin Core贡献者Johnson Lau撰写。到2016年1月初,随着有关扩容的辩论持续升温,这些人和其他Bitcoin Core贡献者为协议升级启动了一个初始的专用测试网络,称为SegNet。两个星期至后,这个测试网络被公开,以供更广泛的比特币开发社区进行测试。到3月份,SegNet已经升级到可以支持闪电网络的测试版本。

在未来几个月中,开发一直在进行,吸收比特币开发社区的反馈意见,修复漏洞,改进代码库,并推出新版本的SegNet。

“隔离见证”的GitHub页面,其中开发和其他问题都是公开可见的,任何人都可以关注并作出贡献

与此同时,比特币的贡献者也与更多的比特币行业从业者展开了交流,随着时间的推移,承诺支持隔离见证的公司和项目数量也一直在增长。

截至同年6月,“隔离见证”共新增了4,743行代码(包括测试代码),并提出删除或修改554条现有的Bitcoin Core代码行。在几位贡献者对代码进行了更深入的审查之后,Bitcoin Core的主要维护人Wladimir van der Laan在六月底之前将这些代码并入了Core的“主分支”中。

会议

在开发SegWit的同时,有关比特币区块大小的争论在比特币社区再次升温。这一次是由Bitcoin Classic带头,一些比特币公司和矿工似乎下定决心使用硬分叉将区块大小限制增加到2兆字节。

在香港,几位Bitcoin Core贡献者,矿池运营商和其他比特币行业的成员举行了一次紧急会议,讨论了扩容的问题。

会议促成了一项被称为“比特币圆桌共识”(或“香港共识”)的协议。出席会议的Bitcoin Core贡献者和整个比特币开发社区一同开发一个基于隔离见证改善之上的安全硬分叉。反过来,这些矿工们同意在Bitcoin Core发布了一个包含上述硬分叉代码的版本之后在生产环境中运行隔离见证。这场危机似乎已经被避免了- 尽管人们很快就会明白并不是每个人都对协议的结果感到满意。

几个月后,更多的Bitcoin Core贡献者和矿池运营商在加利福尼亚举行了会议。在会议结束之后,出席会议中的Core贡献者确信隔离见证将被矿工激活。

发布

大约在最初计划日程的六个月之后 – 原定于4月发布 – 2016年10月,隔离见证在Bitcoin Core版本0.13.1 中正式推出。协议升级也在其他几个比特币客户端中实现,比如Bitcoin Knots和Bcoin。

使用称为“VersionBits”(BIP9)的激活方法(BIP9)(旨在最大程度地减少网络中断),95%的矿工(通过哈希率)必须表示支持才在比特币网络上激活SegWit。从11月15日起,比特币矿工可以表示支持这个协议升级。同时,用户也被鼓励升级客户端。目前看来,许多用户似乎的确进行了升级。

截至2017年8月,比特币网络的绝大部分由隔离见证就绪节点组成(来源:luke.dashjr.org)

基于与矿池运营商的会议,以及SegWit将是比特币的福音的普遍信念,许多人预计软分叉将很快会被激活。

政治

但事实并非如此。事实证明,香港圆桌会议的几位与会者对他们实际签署的内容有不同意见。

比特大陆的联合首席执行官吴忌寒特别表示,只有在Bitcoin Core开发团队同时实施硬分叉来增加区块大小限制的情况下,他才愿意激活SegWit。其他矿池,包括F2Pool,HaoBTC和bitcoin.com也没有用信号支持软分叉。

比特大陆(和附属AntPool)要求进行硬分叉来提升区块大小限制,作为回报,其将支持SegWit激活

此外,一个新的矿池在中国出现了:ViaBTC。由于其与比特大陆关系密切,ViaBTC拥有足够的哈希率可以单独阻止SegWit激活。而其运营商杨海波则将自己定位为对拟议的协议升级的坚定批评者。

SegWit的激活似乎很遥远。

UASF

匿名比特币和莱特币开发人员Shaolinfry的头像

2017年2月,在SegWit正式发布的三个月后,一个新的机遇出现了。

曾经为莱特币做出贡献的匿名开发者“Shaolinfry”在比特币开发邮件列表和热门的bitcointalk.org论坛中提出了一项新提案:“用户激活软分叉”或“UASF”。

Shaolinfry在他的电子邮件中说,已经成为软分叉标准的哈希率激活机制从来不是一个“投票”。他写道,“信号方法被大部分人误解为意味着哈希率正在对一项提案进行投票,而且很难在更大范围的社区中纠正这种误解。

Shaolinfry提出了一种替代方案:用户激活软分叉(UASF)。与哈希率激活不同,用户激活软分叉将使用“指定日激活”,其中节点会在将来的一个预定时间开始强制执行新规则。“只要UASF被大多数的经济参与者执行,这应该会迫使大多数矿工遵循(或激活)软分叉。”

这个想法立即在比特币论坛和社交媒体上引起轰动。而当前BTCC首席运营官和直言的SegWit倡导者缪永权为UASF软件的开发设立了一个奖励基金时,似乎这个建议可能成为现实。

专利技术

2017年4月的第一个星期,Gregory Maxwell通过比特币邮件列表公开了一个爆炸性的消息。

Maxwell声称其对某制造商的ASIC采矿芯片进行了逆向工程,发现其中包括获得专利的AsicBoost技术。而更重要的是,Maxwell还透露,这种技术的秘密使用与通过软分叉部署SegWit不兼容。他说:“这种不兼容性很大程度上解释了挖矿生态系统中有些人的一些令人费解的行为。”

尽管Maxwell的电子邮件中没有提及具体的ASIC制造商,但比特大陆承认其在挖矿芯片中添加了专利技术 – 尽管它否认在比特币的主网上使用过这些技术。

不管怎样,对于一些用户来说,这项发现加强了某些人在比特币网络上启用隔离见证软叉的愿望。而且,随着哈希率激活变得愈加不可能,用户激活软分叉也变得越来越像可以解决这个问题的办法。

BIP148提案

在提出了UASF的大致想法之后,Shaolinfry和其他十几位比特币社区的成员在比特币核心社区的Slack上开设了一个UASF频道。

该频道成为了有关该倡议的讨论和组织的中心。最初选中的激活日为10月1日,然后改到了8月1日,以便应对可能出现哈希率过低的情況。 Shaolinfry撰写了具体的比特币改进方案:BIP148。Open Dim的创始人Rodolfo Novak也建立了一个信息网站来推广这个想法。

最初的计划是让交易所和其他企业支持UASF。如果这些公司支持这一建议并强制执行软分叉,那么实现所希望的经济大多数就指日可待。

但是,UASF并没有像它的支持者所希望的那样获得支持。尽管许多公司和一些开发人员似乎都支持BIP148,但没有一家大型交易所或其他企业宣布支持,一些公司甚至公开反对这一倡议。

而到4月中旬,Gregory Maxwell在比特币开发邮件列表中表示,他认为BIP148也不是一个好主意。作为最受尊敬和最有影响力的比特币核心贡献者之一,Maxwell对该倡议的拒绝产生了重大影响:此版本的UASF似乎失去了所有的动力。

相反,有些人开始使用UASF的替代品:BIP149。

山寨币

许多山寨币都是基于比特币的代码库。这意味着为比特币而开发的SegWit代码在很大程度上是可以与这些替代加密货币是兼容的。不出所料, 一些山寨币决定实施SegWit。早在2017年1月,Groestlcoin第一个了激活隔离见证。

但其他货币也在纠结。 莱特币,Vertcoin和Viacoin似乎都被比特币的政治游戏所吸引。这些货币在很大程度上依赖与比特币相同的矿工,而且其中大多数都没有发出信号支持升级。

据称,这是由于技术问题或其他原因造成的,但是,正如Viacoin的首席开发人员Romano所属:“似乎更有可能的原因是他们不愿意在山寨币上激活隔离见证,因为这样会给他们更少的理由推迟比特币上隔离见证的激活“。

到2017年4月,这种态度使得莱特币的创始人Charlie Lee主张在莱特币上实施用户激活软分叉。他的倡议收到了莱特币用户的热烈响应;很快, 莱特币矿工,Lee和莱特币生态系统的其他成员安排了一场在线会议,并达成了莱特币全球圆桌会议决议。为了换取Lee的一些承诺,矿工们同意激活SegWit。 ShaolinFry等人认为这次UASF的努力是成功的。

在隔离见证在莱特币上激活后的一周内,一个不知身份的人做出了一个大胆的举动。他(或她)将价值100万美元的莱特币发送到了一个由隔离见证保护的地址,挑战任何人窃取这笔资金。到目前为止,赏金仍然没有变化,这进一步增强了人们对这项技术的信心。

纽约协议

与此同时,有关区块大小的争论仍在激烈进行。 作为另一个通过硬分叉来增加比特币区块大小的客户端软件, Bitcoin Unlimited在比特币矿业社区中十分受到欢迎。特别是在比特大陆的吴先生的支持下,这个项目似乎正在朝着一个潜在的(有争议的)硬分叉方向发展。

这个潜在的威胁,以及在比特币区块链“分裂”的可能性,是DCG创始人兼首席执行官Barry Silbert在2017年的纽约共识召开之前举行会议的理由。 该会议最初是在一份针对比特币企业家和其他知名行业成员的私人电子邮件列表中宣布的,并把比特币行业中 的一大部分人聚集到了一起,包括矿工在内——不过,这里面显然没有Bitcoin Core的贡献者。

那次会议的结果通常被称为“纽约共识”。参与者们对他们认为是那些希望使用硬分叉和那些更想要用SegWit增加比特币区块大小的人之间的妥协达成了一致意见。根据RSK的创始人Sergio Demian Lerner最初提出的想法,SegWit会在特定条件下激活,同时也会有一个硬分叉将比特币的“基本区块大小限制”增加一倍。

“纽约共识”及其两个具体行动点

但并不是比特币生态系统中的所有人都支持该协议,而其中的一个具体的问题尤其突出。 “纽约共识”下的SegWit激活的条件与Bitcoin Core开发团队提出的条件基本不兼容,而Bitcoin Core代码已被比特币用户广泛采用。

不能容忍的少数

由缪永权发布的支持BIP148 UASF的图像

虽然许多人从支持BIP148 UASF转而支持BIP149,但并不是所有人都完全放弃了第一个UASF提案。

在Shaolinfry提出这个概念的时候,他的前提是它将得到经济大多数的支持,否则,它应该在指定日之前就中止。但是,UASF Slack频道上的一些用户却有着不同的想法。其中一些 – 包括Bitcoin Core和Bitcoin Knots的开发人员Luke Dashjr – 正考虑激活软分叉,不管比特币生态系统的其余部分会作何反应。即使他们是少数,即使他们会实际上变成一种山寨币,他们也会继续进行UASF升级。

在五月中旬左右,Alphonse Pace将这一决定与统计学家,作家 Nassim Nicholas Taleb所描述的一个博弈论概念联系起来:“不能容忍的少数”。简而言之,这个想法的前提是即使是经济少数人也应该能够促使矿工激活分离见证软分叉。否则,他们将会失去他们的“客户群”(比特币用户)。

由于有关AsicBoost的传闻,莱特币上隔离见证的激活以及对“纽约共识“的不满 – 这一次,在博弈论的支持下,BIP148的支持在社交媒体和留言板上越来越多,再次成为一股热潮。

另外,还有几篇文章讨论了UASF发展的潜力,社交媒体,YouTube频道,和其他讨论平台上的大量争论则紧随其后 。与此同时,Eric Lombrozo也在全力支持这项提案,而缪永权分发的UASF帽子更是风行一时。受到即将发行的Electrum 钱包的代号的启发,8月1日被称为“比特币独立日”。

唯一的问题是:BIP148和纽约共识的激活方法与纽约共识和Bitcoin Core团队提出的激活方法一样,是不兼容的。

Kludge

Bitmain Warranty的工程师James Hillard成了救星。 Hilliard提出了一个稍显复杂但巧妙的解决方案,可以使一切都能互相兼容:Bitcoin Core开发团队提出的隔离见证激活,BIP148 UASF和纽约共识激活机制。他的BIP91可以使比特币保持完整- 至少在隔离见证激活的时候。

只要大多数矿工在8月1日之前激活BIP91,所有比特币节点都应该仍然是同一网络的一部分。这是一个相对较小的时间窗口,因为该解决方案在5月下旬才被提出,但是纽约协议的主要开发人员Jeff Garzik接受了该提案,并计划在8月1日之前的几周内发布该协议产生的软件客户端。这是可行的。

激活

BIP91锁定时的信息网站XBT.eu的状态

到7月中旬,比特币矿工们已经错过了及时使用Bitcoin Core开发团队提出的方法与BIP148兼容来激活隔离见证的机会。因此,市场似乎对BIP148链和非BIP148链之间存在的潜在的“分裂”而感到紧张。在一周的时间里,比特币的汇率从2500美元左右下跌至1900美元:这是一个多月以来的最低水平。

比特币矿业社区可能被这些市场走势吓了一惊,它开始迅速发出信号表示对BIP91的支持,甚至比纽约协议规定的时间还要提前。而在7月20日,即BIP148指定激活日(原定于8月1号)的前10天,BIP91就被锁定了。两天之后,它就被激活了。

随着BIP91被锁定,隔离见证正式锁定也只是时间问题。隔离见证最终在8月9日被锁定  -—— 而早在8月8日,事情就已经达到了不能回头的地步。

比特币将在两个星期的宽限期之后“正式”开始实施隔离见证。

采用

由Albert Dros设计的隔离见证标志

当然,隔离见证的最后一步是实际的用户采用。由于隔离见证在本文发布时才刚刚启动,所以我们不可能知道实际使用升级的用户数量和速度。一些批评家(也许其中最着名的是Garzik)预测广泛采用可能需要一年甚至更长的时间。其他一些人,包括一些钱包和库的开发人员,认为他们可以在几个星期内使用这项功能,或者他们已经准备好了。而依赖于升级的其他技术,如闪电网络,还有Merkelized抽象语法树(MAST),原子交换,更快的硬件钱包交易签名,以及支付处理器模式下的TumbleBit,都处于不同的开发阶段。

这是一条漫长的道路,但是从今天开始,任何想要使用隔离见证的人应该能够如愿以偿了。

来源:https://bitcoinmagazine.com/articles/long-road-segwit-how-bitcoins-biggest-protocol-upgrade-became-reality/

作者:Aaron van Wirdum



互联网创业者该醒醒了

$
0
0

互联网创业者该醒醒了

互联网创业者该醒醒了

一、慌和丧时代

前些日子,李文星事件爆发,Boss直聘一夜之间成了众矢之的。媒体人、自媒体、网友纷纷声讨,呼吁对招聘平台展开严查。这件事情的背后,是招聘app们为了快速爆发、野蛮生长,而大大降低了审核和互动门槛,对平台上涌入的各种虚假可疑公司熟视无睹,是一种监管的不作为。

对招聘领域来说,这当然不是个好消息。可没有好消息的,又岂止招聘行业?

慌和丧,这两种情绪互相交织,横亘了整个上半年的互联网创投圈。

慌。前些日子,风头正劲的付费社群产品“小密圈”忽然被传下架。尽管公司一再声称这只是“技术性升级”,并且在朋友圈征得新名“知识星球”。但产品“涉及色情和敏感信息”的传言还是甚嚣尘上。一时间满城风雨,同类产品们风声鹤唳、噤若寒蝉。

这不是先例。在此之前,已经有多个被资本们吹上天的“风口”,在政策监管的铁腕面前烟消云散。在国家意志面前,资本的投机炒作不堪一击。

滴滴火了,但是很快最严厉的网约车管制接踵而至,而来自国家的反垄断调查一直在继续。

直播火了,国家一句必须要有试听节目许可证,就让200家直播公司转眼倒下或即将倒下,而诸如黄鳝门等事件打击力度之快之大超出预期。

p2p火了,互金最严整顿也来了,破产跑路无数,从红岭清盘到陆金所传言,现在你还敢进吗,进得了吗?

内容领域火了,但是自媒体当家花旦咪蒙都可以关进黑屋30天,更何况毒舌电影这些热门号一夜倒下,一时间人人都在猜测、下一个被关的会是谁?

游戏火了,王者荣耀火遍全中国,于是官媒的联合声讨也来了……

在这样一种诚惶诚恐的局面下,很多人的情绪已经开始转为“丧”。

当然,也有人根本没把风险放在眼里,先捞到钱再说,能捞到多少是多少。这边互联网金融风声鹤唳,那边他玩ico6得飞起,虚拟货币的暴富神话一时又让人看不明白了。

很多人在问,2017年的风口究竟是什么?在我看来,不论风口是什么,最大的关注点应该是十九大。因为只有十九大开了,国家定了调,我们才知道什么能做、什么不能做,什么国家倡导,什么即便暂时没有禁止、长远来看也一定会面临系统性风险。

而很多人的关注点,已经开始从“究竟做什么赚钱”,转向“什么即使赚钱,长远来看也绝不能做”。

二、上一个周期的逻辑

凛冬将至,上述苦恼绝不仅仅只在互联网一家。

有人说,一个人赚了很多钱是能力问题,但是一个人赚了很多很多很多很多很多……钱,就是时代的问题,是踩准了风口,享受了大趋势带来的红利和泡沫。

回顾这一个经济周期,这样的“红利”非常明显有三个:金融、房地产和互联网。

再往细一点儿说,是金融的“宽松和创新”,是房地产的“投机和炒作”,是互联网的“泡沫和野蛮生长”。本质上说,很多人吃的都是“监管红利”,是在政策宽松或滞后的情况下,通过“钻空子”斩获了史无前例的巨大红利。中国的市场是全球最大的市场,稍微漏出一点风,乘以13亿人,成就的都是亿万资产。

但是今天,全国金融工作会议的召开,金融全面进入“规范和整肃”的时代;伴随着房市严控、租售同权等一系列政策的推出,国家已经给出了信号:这次是动真格的,中国的钱有大用、不能统统吸进楼市黑洞。

而在互联网领域,最严厉高效的监管正在步步走来,以前野蛮生长的方式可能行不通了。

野蛮生长就是互联网的原罪,怎么个野蛮法?

三、互联网原罪的十字口诀

有人说,在中国最挣钱的方法,其实都写在《刑法》里。这句话虽然过于夸张,但反映在互联网上很明显的一点是:创业者们要想异军突起、迅速逆袭,老老实实一般是行不通的,往往要行走在“灰色地带”,打下三路和擦边球。

可以说,过去几年互联网产品的快速爆发,除了日常刚需工具,其他多半是迎合人性的黑暗面,做多巴胺、伏隔核、心流机制的操控家,简言之就是十字口诀:黄毒假抄懒,斗贴装谣灰。

1. 黄,就是色情的力量。性的威力永远是不言而喻的,从传说中的草榴,到约炮神器的横行,从直播平台上晃动的乳沟,到cj上看不尽的大腿……互联网产品即使没有明确的制黄贩黄,也常常作出大量的性暗示和感官刺激。遗憾的是,这一点对于我们这个习惯了故作清高的民族却是异常奏效的,特别是对大多数的底层屌丝用户、几乎立竿见影。这从约炮神器上一度惊人的用户数据和色流诈骗吓人的成功率中可以得证。

2. 毒,就是利用各种类似赌博的上瘾机制、让用户沉迷其中。这一点在游戏领域极其明显,网上一直有传言,《王者荣耀》的团队一个重要的研究是,如何在5分钟内让你上瘾。

3. 假,电商平台相对传统商家,往往可以给出惊人优惠的价格,但其中一些却可能是假冒伪劣。特别在发展的早期,往往成为重灾区,价格便宜往往以品质掺水为代价。

4、抄,擅长抄袭、美其名曰“改良式创新”几乎是中国互联网公司的通病,或者盗版、打着信息公开分享的名义侵犯创作者权益。截至今日,中国的互联网公司已经几乎抄袭了西方所有流行或不流行的产品和商业模式,甚至连综艺、内容和包装设计都能抄即抄、拿来主义。即便本土偶有创新,好不容易从0到1的新创公司只要稍有成就,也会转眼被大公司和资本裹挟的对手们(背景优越的团队)“抄死”。尽管国家一直喊着万众创新,但实际创投圈完全在失控的丛林状态,对创新的不友好到达了史上最严酷的程度。

5、懒,即利用用户的懒惰,提供更加简单高效、可以依赖的解决方案。这是大多数工具性产品的出发点,只要用户对工具产生依赖离不开,就成了任人宰割的羔羊。为什么迅雷、暴风越改版越让人受不了,广告繁多、界面复杂?说到底还是商业诉求在作祟,一开始是用户体验第一,等用户依赖了就翻身做主人、商业诉求力压用户体验。

6、斗,发动群众斗群众,利用各种矛盾造热点、搏眼球、吸流量。从微博的围观到贴吧的爆吧,从知乎的撕逼到网易的评论,从直男癌与田园女权的征战,到地图炮、阶层炮、年龄炮、行业炮的炮火连天……各大平台可谓谙熟了中国人喜好站队互踩、在与人斗其乐无穷中发泄无聊和寻求优越感的心理,网路暴力伴随群体潜意识四处横行。

7、贴,简言之就是补贴。互联网经济总想制造“价格优势”,从低价到特惠到免费到倒贴钱,背后是资本们的人傻钱多、一掷千金、烧钱补贴抢市场。

8、装,利用人们的装逼心理,满足用户的虚荣心。从脸萌到足记,从“你的思维更接近东方、西方”到“你是欢乐颂中的谁”,从星座解读的横行到各种心理测试题,无不抓住中国用户的一种心理:想要装逼又必需表面低调、所以借你产品来释放一下。

9、谣,好事不出门、坏事传千里,中国人对各种谣言八卦总是具有特殊的癖好。早年微博的各种曝光、匿名社交平台的横行、各种八卦号的一度爆火,都论证来这一点,窥私欲具有着不可阻挡的诱惑。

10、灰,就是将各种灰色产业合法化。滴滴刚开始,很多时候就是把“黑车”合法化;p2p的横行,很多是给过去的民间高利贷披上了合法外衣。

往细里看,那些面对c端取得大小成就的互联网公司们,谁敢拍着胸脯,说自己的爆发和以上10条没有一点干系?

四、红利的褪尽

在阶层日益固化的今天,人们越来越关注所谓“红利”。因为只有时代的红利,才能让底层和中产们挣脱可怕的宿命,获得进入“上流城堡”的最后通道。没有这样的红利,你就算赚得还不错,也永远都是做生意、给人打工、挣辛苦钱,富人们早就在“食利”了。

但是很遗憾,在互联网领域,传统意义的红利都在褪尽,而且是从2015年下半年就开始了。

1、人口红利消失了。中国人基本上已经人手一部智能机了,新增手机用户上涨进入了瓶颈期,同时换机的频率也逐步降低,整个移动互联网市场进入了存量时代。新的装机用户越来越少了,谁去应用市场下载你的app呢?于是,获客成本开始激增,互联网创业“低成本起步”的优势消失了。

2、心智瓜分大势确定。打开应用市场,从工具到娱乐到本地商务,所有显而易见的通用需求,都已经有一堆产品堵在那里了,特别是其中的“头部产品”往往已经牢牢占据了用户的心智空间,即便体验已经不是最好,其地位也很难撼动。围绕不同场景、需求和习惯的心智空间已经被瓜分完毕了,互联网创业进入了需求稀缺难寻的时代。此种情况下作出来的产品,要么需求是yy出来的,要么需求不通约天花板太低,要么即便体验确实更好,却沉没在头部产品投射的阴影中,养在深闺人不知,获客成本比头部高出许多倍(没他钱多,还比他获客贵)

3、寡头垄断局面已经形成。过去是BAT,现在是AT,过去是2vc,现在是2at,腾讯和阿里已经开始成为中国互联网中无处不在的巨力。每一条赛道,只要稍微火,很快就会有他们的身影,要么果断跟进抄抄抄,要么砸钱投资买买买。而新公司们赖以生存的流量管道,也多数被他们把在手里,想造反?先让你的产品分享不到朋友圈,先让你的支付接不上。

4、资本“疯投”破坏生态。很多事情一开始是绝对赚钱的,财务模型也很清晰,比如共享单车、共享充电宝、部分o2o甚至刚开始的团购。可惜的是,这都是在良性竞争的理想状态下。中国的问题是,一个领域稍微有一点儿赚钱,资本就可能带着抄袭者们疯狂进场,从千团大战到百播大战到千车大战,现在甚至狼人杀领域都开始千狼混战。这种情况屡屡发生,蓝海转眼变红海,好好的产品创新转眼变成烧钱补贴抢用户的资本修罗场,创业者成了资本的傀儡。于是,一个红利满满的市场转眼做滥做臭做死,各种同质化恶性竞争甚嚣尘上,要不了多久,一拥而上就会变成一哄而上,创业者纷纷倒下,资本收割了速度离场。不要小看这一点,这世上到处是背景优越、团队豪华、被资本看好却没有方向的团队,资本美其名曰“我就是投人”,如果没背景的你不小心发现了一块沃土,他们就像苍蝇闻着肉香一样扑过来了。

5、最关键的是,十字口诀不灵了。

五、新机会

新的经济周期已经到来,这个周期的“房地产、金融、互联网”是谁?

《未来5年大机遇,做贩卖多巴胺的超级玩家》中,笔者已经指出:在经济下行的大背景下,我们迎来了一个“口红经济”和“奶嘴乐”的时代,消费和娱乐会上扬。

对于无法在技术领域取得巨大突破、抑或是在线下无法拥有巨大资本资源的草根玩家们来说,这里确实就是机会:产品和商业模式创新,收割娱乐时间和消费升级(相对上流社会是降级)

说起来容易做起来难,我们又要注意几个点:

1、必须是健康和正面的。不要以为娱乐的崛起就是多巴胺与荷尔蒙的狂欢,就是软色情、暴力、游戏的乐土。《王者荣耀》被围攻和直播管制的例子已经表明:互联网正处在十多个政府部门最严厉的管制之下,更有朝阳群众随时监督,你简单粗暴只怕越来越走不通。所以未来能够做大做强的娱乐一定是健康益智、寓教于乐的,像象棋、健身一样远离红线、不易被指摘。那些一味引人沉迷、荒废正业、低俗色情的娱乐模式,会和过去一样容易速火,但只怕死也死得更快。健康积极的娱乐将贯穿在我们的整个社会生活中,内容、培训、商务……各个方面。

但健康积极的娱乐谈何容易,在处处是“一夜暴富”神话的今天,又有多少创业者和投资人经得起慢工细活的忍耐?

2、警惕潮流性。娱乐爆发也好,消费升级也罢,需要警惕的是其潮流性,即往往“火一把就死”,而不能从流行到经典,这样的速生速死是不可能支撑起一个新时代大公司的。所以你应该去做“标准化”的产品,要设法抢占心智成为头部,甚至有可能成为未来人们娱乐消费生活方式的档次标准或基础设施。

3、越高端,流量越分散。很多人喜欢说服务中高端人群、做消费升级,但是很遗憾,我们发现在中国,越是做“下三路”接近底层的需求,往往用户流量越集中,约炮、打车、便宜货、傻瓜型游戏……但是越往中高端做,越是作用于人性的优点和人们的自我提升,这个流量就越分散。因为越是底层的需求越是相似,越容易成为人们的最大公约数,也越容易平台化。但越是向上的需求就越分散,不同人眼中有不同的情怀兴致,不同人眼中有不同的逼格档次,不同人眼中有不同的健康品味,不同人眼中有不同的充电方式……越是向上的需求就越是小圈子化,所以你很容易触到人群的天花板,如何精准捕获分散的目标客群,如何做高毛利,这些都会非常重要。

4、中产的钱不好赚。很多人认为,屌丝就是免费,中产就是消费升级,消费升级就是人傻钱多有钱任性。但是实践中,中产的消费可能更加理性和谨慎,更善于精打细算,一方面他们有足够的信息源来做这样的“计算”,另一方面中产面临着“向上上不去、向下却随时可能滑落底层”的困境,很多人都是接近上流的精致外表、接近屌丝的可支配收入。所以如何征服他们的心,可没有那么容易。

5、做小弟的思想准备。在这样的情势下,真的不要天天想着做大平台、想着颠覆BAT、想着改变世界了,高筑墙、广积粮、缓称王,先学会容易腾讯和阿里的体系中、老老实实从小弟做起比较重要。想想看,牛如乔布斯,当年不也一样不得不暂时对盖茨“称臣”?创业首先是生意,找到现金活下去才有勃勃野心。

6、快速变现,轻资本依赖。过去几年,大量公司的衰落,其实是因为创业者把大多数时间都放在了融资上,和投资人觥筹交错四处周旋,却始终没有功夫聚焦在产品、员工和市场一线上,而后者才是真正的重要。这样的结果也造成了一种逆淘汰,谁背景好会融资,谁就能一直跑下去,哪怕产品和商业模式很多和一坨屎一样,大不了直接抄袭做的好的就行了。这样的逆淘汰到最后,走出来的公司都是重度资本依赖型公司,都是资本家们的提线木偶。没有显赫背景的草根创业者们显然不能这么玩儿,所以拜托你不要讲“先烧钱、做免费大平台、流量成规模了再变现”的故事,这个故事太奢侈不属于你。你要做的是简化商业模型、缩短盈利链条,尽快地闷声赚钱,这样哪怕有大家伙进场,只要有钱赚至少你活得下去。不要在想什么“英雄不问出身”了,那都是投资人套你点子之前的说辞,人家心里可都是对你的背景明码标价着呢。

7、创新和壁垒更重要。时至今日,从0到1的创新的重要变得史无前例,因为玩“模仿加微创新”,你不仅玩不过BAT,玩不过TMD,恐怕一个陌陌也能把你抄死。草根玩家在别人主场的赛道上再怎么创新,别人只要稍稍动一动产品、玩一玩资本、分分钟就能把你弄死。所以,两种思维会比较重要:一是第一性原理,不比照市面上已经有的产品,而是回归用户需求本初;二是破坏性创新,减少主流对手长期专注、持续发展以至效率过分的部分,把关注点放到其他价值诉求上,并且不断深耕,由于双方基础理念结构不同,强敌不大可能转而追随。但即便这样我也要说,中国现在最关键的是专利制度,是创新保护,否则我苦心孤诣好不容易找到一个杀手锏,申请专利用了一年半,你凭着资本人傻钱多分分钟把我干了,这个局还有什么意义,以后还会有人创新吗?

保护中小创业者,从保护创新开始,救救创业救救创新!

8、找趋势,不追风口。喜马拉雅上卫哲老师一句话非常好:要寻找未来的趋势,而不是追风口。趋势是长期的必然的,而风口则是可以通过短期炒作、资本哄抬制造出来的“热点”。截至今天,相当多的风口已经被证明是“伪需求泡沫”,根本不是未来趋势,你去追不是送死吗?更何况,当一个领域成为风口的时候,往往之前已经有几十家企业在那里深耕了半年一年,主流投资人估计都进去过了一遍,这个时候你才反应过来要追,还来得及吗?当一个事情已经成为风口时,它多半已经和你无关了。所以创业者的核心是找准趋势提前布局深耕细作,时机成熟风自然会来。只不过,很多人是心理还没过断奶期,没有融资就不敢创业,所以一定要2vc,一定要追风口。

六、未必是坏事

总结一句,对于大多数草根玩家来说,可以融入大公司生态、具有创新壁垒、围绕年轻一代(准)中产阶级、盈利路径短、现金流清晰、低资本依赖、健康积极可持续的娱乐和消费,或者大公司体系下的2b服务,会存在越来越多的机会,甚至存在平台级大机遇的可能。

但是回到开头,今年是创业者尤其需要“讲政治”的一年,只有一个最重要的背景,19大的召开。毕竟,经历了前景如此混沌不明、几乎看不到多少大机会的16年,我们迫切地需要知道,这个国家下一个重要的棋子将落在何方?

科技趋势,政治走向,市场规律,社会思潮,这四大合力的系统性结果,才能让我们看清新一个周期下“时代的红利”究竟为何。

过去的路都不灵了,但这未必是坏事。大争之世,英雄方能崛起于草莽之间。

对于新来者来说,最大的优点或许是“没有包袱、没有惯性、没有原罪”,因为上个周期能走得通的模式现在都不灵了,你轻装上阵,很多事情从头开始,这带来了宝贵的重新洗牌的机会。

不要怕寒冬,因为生来就在寒冬中,没有什么可以失去,除了“思维的锁链”。

祝好运,再过个五年,我们看谁是新经济周期中的马云、马化腾、王健林。

作者张俊,上海帅醒创始人,专注tmt领域产品开发和商业分析,事件营销操盘,公众号阿辩论(ID:bianlunlove),个人微信biohazard2010,加请注明来意。


From Bitcoin to Agriculture: How Can Farmers Benefit from Blockchain?

$
0
0

From Bitcoin to Agriculture: How Can Farmers Benefit from Blockchain?

Share on LinkedInTweet about this on TwitterShare on Facebook

Editor’s Note: Emma Weston is co-founder and CEO of Full Profile, where she leads blockchain strategy and development under the AgriDigital brand. She is also a grain grower in Australia. Here, Weston, and co-author Sarah Nolet, founder of food and ag consultancy AgThentic, explain how the agriculture industry is using blockchain, and the challenges ahead for this segment of the industry.

Update: Full Profile recently pitched at Finovate in New York City. Watch their pitch here.


We have all seen the use of (and hype about) blockchain in the context of bitcoin, the digital currency that first brought blockchain to mainstream media and investors.  While bitcoin remains in the news, the applications and potential of blockchain are spreading well beyond cryptocurrency.

Before we take a look at how the agriculture industry is using blockchain, let’s do a quick blockchain 101.

What is Blockchain?

One way to think of blockchain is as a technology that allows users to transfer value, or assets, between each other without the need for a trusted intermediary. The exchange is recorded in a ledger that is shared by all users of that blockchain. Users rely on this shared, or “distributed,” ledger to provide a transparent view into the details of the assets, including who owns the asset, as well as descriptive information such as quality or location. The running history of the transaction is called the blockchain, and each transaction is called a block. Today, when you hear about blockchain, what most really mean is ‘blockchains.

There exist multiple different forms of this distributed ledger technology, each suited to distinct use cases. One popular blockchain technology is Ethereum, which its founders launched around the idea that blockchains can do more than simply record information. This concept, called ‘smart contracts,’ is central to Ethereum and allows users to codify significant parts of a workflow process, agreement, or task. So, when a transaction occurs, the software automatically executes an action, or set of actions, according to the specifications in the smart contract. One example is smart locks; locks that automatically open after receiving the correct fee.

Recently a few other potential use cases for blockchain have emerged, such as tracking goods throughout supply chains (e.g., SkuChain) and IoT-enabled “smart farms” (e.g., Filament). Though we haven’t yet seen the large-scale commercial adoption of blockchain, investors like the Bill and Melinda Gates Foundation and various venture capitalists are paying attention to this space. The R3 consortium has also been in the news for its Corda platform, which enables trade finance and the exchange of letters of credit between its members.

But what about agriculture?

Though agriculture technology is gaining popularity — and capital — there has been very little talk of blockchain applications within core agricultural areas. There should be, though.

Blockchain has huge potential in three key areas of the agriculture industry:

  1. Provenance and radical transparency

2. Mobile payments, credits, and decreased transaction fees

3. Real-time management of supply chain transactions and financing

Enabling Provenance and Radical Transparency in the Food Chain

Consumer demand for “clean” food, including organic, is skyrocketing, but producers and manufacturers are often struggling to verify the accuracy of data from farm to table. Blockchain can help.

Currently, there’s no easy, accurate and efficient way for manufacturers to know about issues like slave labor and pollution, or to identify the exact origin of a commodity. Yet consumers, especially within niche markets like organic food, are increasingly willing to pay for products that provide this information. To date, solutions have revolved around certifications and regulations, both of which add costs, are hard to enforce, and can be confusing to consumers. How do free-range and cage-free chickens differ, and what do the labels actually mean for animal welfare?

Startups liked Provenance and FarmShare are using blockchains to solve this problem for businesses and consumers. The value of blockchain here is its ability to make the supply chain entirely transparent and rich with immutable provenance data from farm to table. In other words, blockchain tracks information about your food and participants along the supply chain cannot tamper with this information. Ultimately, this technology enables farmers, manufacturers, and retailers to justify premiums for certain products, and gives consumers confidence about where their food comes from and how it was produced.

Better Finance for the Developing World

Blockchains also have huge potential to create and improve access to finance in the developing world. Agriculture employs over a billion people worldwide, many of whom are smallholder farmers in developing countries. For many of these farmers, affordable access to capital remains a huge challenge.

As cell phones have largely become ubiquitous, mobile banking creates novel financing opportunities such as micro-financing. Yet, because of a lack of transparency and therefore high risk, the current paradigm is tons of small transactions with extremely high fees (e.g., 10%).

Blockchain can — and already is — solving this problem for financiers and farmers. Examples include agri-ledger out of the UK, BitPesa in East Africa, and Rebit in the Philippines.

Trustworthy, Efficient Supply Chains in Developed Economies

Possibly the highest potential but least realized opportunity for blockchain in agriculture is in the developed world. Each year, trillions of dollars flow between farmers and buyers alone, yet currently, these transactions are hugely inefficient. Blockchain can improve the settlement process for farmers, buyers, and financiers like banks.

Right now, the exchange of the physical commodity decouples from the exchange of payment. In other words, farmers often deliver their harvest but then have to wait weeks or months to be paid. Farmers lack the ability to conduct due diligence on their buyer, so buyers can compete on payment terms, and therefore offer lower prices. This lessens market competition and further lowers prices, as growers go to larger multinationals and incumbents who have less risk of default. Simultaneously, levy collectors and research organizations have no access to data provenance information: they receive their payments, but cannot connect the money to the farmer who has paid. And finally, financing options are both costly and limited because the industry is perceived as risky — and for good reason, as there are many insolvencies.

Blockchain can change all of this by enabling real-time payment on delivery. As a result, farmers get paid immediately, industry competition increases and keeps prices higher, and buyers save time and money. Also, adding transparency, trust, and efficiency to settlements can decrease risk and unlock new financing mechanisms for banks.

Full Profile is addressing this use case, starting with an in-market blockchain pilot for the 2016-2017 grains harvest in Australia.

The Future of Agriculture is Blockchain

Some claim that in a few years’ time blockchain will no longer be a buzzword; it will be as ubiquitous as the internet. Others believe that blockchain is all hype; that it is an untested technology with huge risks and little upside.

Farmers have always been eager adopters of technologies that make sense and deliver real value. It’s clear that blockchain has big potential to solve significant problems in agriculture. The challenge for blockchain, and agtech at large, is connecting the technology to viable business models and compelling use cases. All the startups mentioned above are working hard to do just this.

Put simply; blockchain needs to save time and money as well as take agriculture forward to create new pockets of value. If we can move beyond the hype and simply do better business, the future of agriculture will indeed be blockchain.

Have news or tips? Email Media@AgFunderNews.com


The Supply Side: Blockchain technology traces food from farm to table

$
0
0

The Supply Side: Blockchain technology traces food from farm to table

by Kim Souza (ksouza@talkbusiness.net)  552 views 

Tracking down a bad food product sold by any grocer is obviously important for the customer, but it also can help a supplier more quickly recover the recall cost and intangible costs tied to reputation.

When a customer shops at Wal-Mart they expect great prices, but product safety is the utmost concern, according to Frank Yiannas, vice president of food safety at Wal-Mart. He recently provided an update on the retailer’s “blockchain” partnership with IBM. Blockchain is a technology platform that allows more transparency in the food supply chain, which includes many stakeholders from the farm, to the pickers, to the packing houses and the logistics of shipping to stores.

Yiannas said protocol requires retailers like Wal-Mart to pull all the products linked to a food recall from the shelves and coolers until it is deemed safe. In many cases, the fresh product is lost because of the time it takes to trace an issue through the supply chain. He said an average recall costs about $10 million. Combined with the cost of food borne illness — $93 million annually — this creates much waste and unneeded cost burdens in the food chain.

Wal-Mart and IBM launched blockchain last year in China where food safety is of paramount concern among a distrustful Chinese consumer base. The retailer just finished piloting the process in the U.S. He said suppliers and universities also participated in the U.S. pilot, though he didn’t disclose their names.

Yiannas said in 2006 a massive bagged spinach recall greatly reduced the spinach supply for several years as it took suppliers time to recover. The recall took two weeks to trace, and all the spinach on the shelves was pulled and destroyed. In reality, the contaminated product only involved one supplier’s production one day on a single line.

“It took six to seven years for the spinach farmers to recover,” Yiannas said. “Fast traceability is huge, and being right is crucial.”

Bridget McDermott, vice president of blockchain business development at IBM, said the goal of blockchain is to accelerate the tracing of food from days and weeks to mere seconds. This will enable precise and rapid recalls to preserve consumer trust in the food industry, while also increasing traceability and transparency in the food supply chain.

McDermott said the problem with tracing the food supply chain without blockchain is that it’s very fragmented and also involves many stakeholders using their own systems which do not talk to other systems. She said many certificates, audit records and other required items are kept in paper form. She said this fragmented system is why it takes so long to find the source of a recall through traditional tracing programs.

With blockchain, stakeholders along the food supply chain each take part and enter their records into the system. Product packaging is also embedded with a QR code that facilitates traceability. Blockchain also fosters trust among participants across the chain as they share information so food can be digitized in a way that makes the food supply safer.

Yiannas said while traceability is vital, it’s not the only or most important goal with blockchain. He said consumers want to know more about the origins of the food they consume.

Yiannas and McDermott recently shared results of two tests using blockchain. In China they traced pork, and in the U.S. it was mangoes. The products were tracked through the supply chain. Results of the tests have been encouraging, according to Yiannas.

LIFE OF A MANGO
Yiannas said the life of a mango begins when seeds are planted. It takes about five to eight years before a tree matures to produce fruit. Mangoes are picked by hand at farms primarily in southern Mexico. The mangoes move to a packing house where they are scrutinized by packers. They are loaded onto ships and transported to ports in California.

The mangoes are sent to another processing facility where they are peeled, diced and packed as refrigerated fruit sold in Walmart U.S. The fruit package has a “sell by date” to indicate the shelf-life the product has left. The mangoes are shipped to a Wal-Mart co-packer via the retailer’s own logistics team out to stores. Wal-Mart has to get that product from the backroom out to the sales floor where employees can again trace the product back to the farm with the retailer’s smart app. The product is merchandised and sold within the freshness period stated on the packaging. The customer gets the product home and must consumer rather quickly before the freshness expires.

Without the blockchain technology it took Wal-Mart nearly seven days to trace the mango back to the farm. That time was reduced to two seconds using blockchain. Yiannas said early trials in the U.S. and China have shown blockchain technology can successfully trace food products from suppliers to retail and ultimately to consumers. Farm origination details, batch numbers, factory and processing data, expiration dates and shipping details were digitally connected to food items and entered into the blockchain network at each step of the farm-to-fork process.

Computers in the blockchain, called nodes, contain a copy of a ledger of transactions. When a transaction is made, at least two nodes must approve it before the transaction is added to the ledger. Blockchain provides users a secure database that is auditable and in which transactions can’t be altered, according to McDermott.

“This is just the start of our blockchain exploration. We plan to continue to test the technology, by including more data attributes, for example,” Yiannas said. “And we will continue to test how we can use it to improve food traceability and transparency by collaborating with others throughout the supply chain. This means farmers and suppliers, and other retailers.”

REDUCING FOOD WASTE
Wal-Mart also said blockchain technology has a role in reducing food waste by helping retailers better manage the shelf-life of perishables. He said when the store operator has visibility back to the farm it can help determine how much shelf-life is left for the product.

Yiannas was asked if Wal-Mart would be able to divert shipments to closer stores when the shelf-life is limited. He said the retailer will leverage all the information it can glean from its participation in blockchain.

Yiannas also believes blockchain participation could help reduce the estimated 30% to 40% of food waste in the U.S. through supply chain optimization. He said freshness matters, and the average family wastes about $1,000 annually in food which is equal to one bag of groceries a week.

Many times that waste is fresh items not consumed before their expiration. This waste is estimated at $29 billion annually.
––––––––––––––––––––
Editor’s note: The Supply Side section of Talk Business & Politics focuses on the companies, organizations, issues and individuals engaged in providing products and services to retailers. The Supply Side is managed by Talk Business & Politics and sponsored by Propak Logistics.


From farm to table: How blockchain benefits food supply chains

$
0
0

From farm to table: How blockchain benefits food supply chains

May 8, 2017 | by Elliot Maras

photo istock

Most people are not yet familiar with bitcoin, the virtual currency, but the technology that supports it — known as blockchain — is making inroads in how goods and services are being managed. Blockchain technology, which provides the infrastructure for virtual currencies like bitcoin, is bringing new efficiencies and transparency to supply chains.

As a shared, secure record of exchange, a blockchain allows anyone with access to its electronic ledger to track what went into a product and who handled it along the way. This transparency will impact all sorts of products, but it is especially relevant to food supply chains, given the geographic expansion of these supply chains in recent years and the amount of data companies track.

“Quite a few large food companies have experimented with using the blockchain technology for their supply chain management and quality assurance, such as Wal-Mart for example,” said Angel Versetti, CEO of FoodBlockchain.XYZ, a company looking to bring blockchain technology to the food supply chain.

By digitally recording the identity of goods, blockchains can provide a permanent, immutable record for every food ingredient as it travels from farm to table. This transparency gives processors, wholesalers, distributors, restaurateurs, food trucks and consumers information about where their food comes from, how it was processed and a full accounting of its movement along the supply chain.

What is a blockchain?

A blockchain consists of a decentralized network of servers that can receive data from sensors in real time. Once the data is recorded, it can be accessed by all participating servers and cannot be edited or manipulated. Any authorized party — suppliers, distributors, restaurateurs, food trucks and customers — can access the data and verify the quality and safety control features of their products.

The technology has many uses in the food industry. It has been used, for example, to track fish from a trawler to the supermarket to help stop human rights abuses and illegal fishing.

One company making a bid to become a leading blockchain technology provider to the food supply chain is FoodBlockchain.XYZ, based in Switzerland. It plans to manage commercial relationships among different actors in the food supply chain by issuing a token called Foodcoin. The different players in the supply chain will use the token to ensure compliance to quality and safety standards.

The data will also provide insights about the financial and socio-environmental costs and benefits of sourcing food from specific suppliers. This will enable food businesses to purchase raw inputs from those suppliers offering the best combination of quality, price and socio-environmental indicators.

All players benefit

Suppliers, processors, distributors and retailers will be able to ensure that products meet quality and safety requirements. Parameters to assess the quality and sustainability of seafood, for example, could include temperature, sunlight exposure, pollution of trucks and distance traveled.

Companies will be able to create ID tags for food batches or individual food units that will contain product information from FoodBlockchainXYZ.

These tags will allow consumers to review the history of a product and check what farms the ingredients came from. The information can indicate whether the farm follows sustainable agricultural practices.

The Foodcoin token will allow consumers to reward growers that follow sustainable agricultural practices. This could help establish a new reputation system for farmers and other food suppliers.

Technology advances

“For a long time it was technologically challenging to bring this about,” Versetti said. “With the emergence of bitcoin blockchain, the vision came closer to being realized, but with the limited ability to code on top of the bitcoin, this was still challenging.”

Because blockchain technology continually evolves, Versetti and his team were able to leverage the Ethereum blockchain, a newer technology that many developers hail as being more versatile than the bitcoin blockchain.

“The benefit of Foodcoin would be to power up our Ethereum-based sensor system for food quality control and to be the means of contract execution and reputation establishment for actors in the food industry, allowing the end consumer to use Foodcoin to reward the farmers who follow sustainable practices, or intermediaries with strong ethics, or manufacturers who care most about quality and safety of food,” said Versetti.

“Foodcoin will have valuable use cases for all actors of food supply chains, beginning with farmers, through manufacturers, intermediaries, retailers all the way to the end consumers,” he said.

Safety and quality audits

FoodBlockchain.XYZ also plans to support safety and quality audits. Versetti said the company will perform these audits itself or partner with other companies.

The FoodBlockchain.XYZ team has been working on a quality assurance system to streamline the fragmented information in the food supply chain for quite some time, Versetti said.

The company is presently working with companies in Switzerland, France, Germany and Iceland. It plans to release its first software in June.

 


从经济学角度看区块链

$
0
0

从经济学角度看区块链

本文作者:敖萌 2017-09-05 18:34
导语:无中心的区块链,尤其是无身份许可的公有链没有办法限制信用低的矿工参与整个区块链的运行,因此,在经济学上,公有链存在一定的风险。

雷锋网AI金融评论按:本文作者为中国信息通信研究院(工信部电信研究院)专家敖萌博士,雷锋网独家特约文章,雷锋网与信通院联合首发。未来,敖萌博士原创的区块链系列文章还将继续刊出,雷锋网(公众号:雷锋网)与信通院相关平台同步更新,敬请关注!

提到区块链,大家都会提到“拜占庭将军问题”这个分布式系统中的著名问题。

拜占庭将军问题大概讲的是:拜占庭N个在不同地方的将军围攻一个敌人,忠诚的将军希望通过某种协议达成某个命令的一致(比如约定某个时间一起进攻),但其中一些背叛的将军会通过发送错误的消息阻挠忠诚的将军达成命令上的一致。如果同时发起进攻的将军数量少于M个,那么不足以歼灭敌人反而容易被敌人全部歼灭。怎样做才能保证有多于M个将军在同一时间一起发起进攻?

从经济学角度看区块链

拜占庭将军问题是分布式系统的一个经典模型,当分布式系统没有可靠的中心协调所有节点时,如何确保大多数节点的数据是一致的?拜占庭将军模型就是描述的这个问题。一个区块链系统能够解决拜占庭将军问题,那么我们就说这个区块链系统满足拜占庭容错。

需要注意一点:

在拜占庭将军问题模型中,将军们被分成了“忠诚的”和“背叛的”两种。这种分类事实上是以将军们是否遵守“共识协议”来区分的。在区块链系统中,当一个节点不遵守共识协议,篡改正确的数据等行为,可以被看作是“背叛的”节点。

作为一个信息系统,从“拜占庭将军问题”角度(即分布式系统的数据一致性角度)分析就足够了。然而我在本系列的第一篇文章中就提到过,区块链不仅仅是一个信息化的工具,区块链是深入到业务内部,能够对商业模式起到决定性作用的一种技术。区块链技术不仅仅是一个信息技术,更是一个“经济技术”。因此,我们就不能只从信息技术角度来分析区块链了。

回到本章的正题,我们怎么从经济学角度来看区块链?这个题目太大了,并且我本人不是经济学专业的,只能尝试着从经济学角度简单分析一下比特币区块链系统。

从经济学角度看区块链

从经济学角度来看,仅仅是遵守共识协议并不能保证一个经济系统的稳定性。事实上,“中本聪”在设计比特币系统时,已经考虑到了很多经济学方面的问题,因此比特币系统中对矿工有挖矿奖励,矿工还可以获得转账手续费,以确保有足够的算力能够参与整个比特币系统的维护。

经济学的最基本假设:矿工是要追求利益最大化的

首先,对于矿工来说,遵守整个比特币系统技术协议,有可能获得比特币。不遵守,则直接就会被排除在系统之外,没有收益。因此,从“拜占庭将军问题”分类来说,比特币的矿工都是“忠诚的”,这就能够使得整个比特币系统是趋于稳定的。

从经济学角度看区块链

然而在遵守比特币系统技术协议的前提下,其实还有很多种策略可以选择。这些策略都是在不违背技术协议的行动,但是对整个比特币系统的经济学运行稳定性有影响。比如矿工可以选择对其他矿工发起DDOS攻击,拖慢竞争者的网络,以提高自己挖到区块的概率等。这种情况可以让矿工获得更高的收益,但是一旦所有矿工之间都在相互DDOS攻击,会造成整个比特币网络不可用,交易无法提交生效,进而导致整个比特币的价值降低。

从经济学角度看区块链

还要注意一点,矿工的身份有时候不仅仅是矿工,同时也是比特币的交易者。在这种情况下,矿工如果发起“双花攻击”,则矿工有可能获取到大量的利益。

举例来说,如果一个矿工Alice需要转账给Bob 1000比特币,此时Alice在比特币网络上广播一个Alice转账给Bob账户 1000比特币的交易,被其他矿工接收到,记入了他们的区块中。然而Alice自己则在区块中记录了另一笔交易——Alice转账给Alice_new账户1000比特币,也就是说,Alice人为制造了一个分叉,在这个分叉点,制造了一笔双花交易(一笔钱花了两次)。

之后Alice一直默默的挖矿,直到产生了6个区块后再次广播挖矿结果。如果Alice能够掌握全网51%以上的算力,那么这笔双花交易最终被全网承认的将是Alice转给Alice_new的这笔交易,而转给Bob的将失效。这时如果1比特币的价格是3000美元,那么Bob有可能损失掉了三百万美元。这是一笔非常大的数字。这也就是我们经常提到的比特币中的“51%攻击”。

从经济学角度看区块链

 

由于整个比特币系统是无中心化的,也就是说,我们没有办法记录Alice这个矿工的信用,因此,即便发生了51%攻击,Alice也得不到任何惩罚,相反,Alice还能够继续参与挖矿,并且继续制造51%攻击。当然,如果这种事情频繁发生,整个比特币系统就会变得一文不值,因此,具有超级算力的矿工在发起51%攻击时,也需要考虑是否会把整个比特币系统拖垮。

其实不仅仅是算力超过51%的矿工可以发起双花攻击,如果一个矿工掌握了45%的算力,那么他依然可以发起双花攻击,在我们通常认为6个区块可以确认交易成功的概念下,45%算力发起双花攻击的成功率为(0.45/(1-0.45))的6次方——30%,(考虑到他掌握了45%的算力,那么他单独自己挖自己的分叉,另一个分叉就只有55%的算力了,所以是0.45/(1-0.45))也就是说,如果这个双花交易的额度是1000比特币,那么他收益的期望是300比特币,这种情况下,从博弈论角度来看,矿工发起双花攻击的可能性是极大的。

从经济学角度看区块链

由于比特币区块链系统的设计中,挖矿难度的变化率是比较慢的,因此,对于算力很高的矿工来说,在准备大幅增加硬件提高算力的同时发起双花攻击,这样的行为有可能让矿工获得很高的收益。当然,这种行为也同样会导致比特币的价值受到损害。

综合上面的分析,我们可以得出结论:虽然比特币区块链系统在技术设计上已经非常成熟,但是一旦采用经济学分析,仍然可以发现无中心化的比特币系统依然存在很高的经济风险,这种风险来源于算力的中心化。目前整个比特币网络中,几个大的矿池已经占有了非常高的算力比例,在这种情况下,比特币系统的价值已经很大程度上依赖于这些矿池的道德水平了。不过,上面的所有分析是假设矿工发起了大额转账交易。而目前由于比特币价格非常高,大额交易是比较罕见的,因此,出现上述风险的概率是很低。

雷锋网特约稿件,未经授权禁止转载。详情见转载须知


Viewing all 764 articles
Browse latest View live