Search

12/15/2014

Synergy - Mouse and keyboard sharing software

Synergy - Mouse and keyboard sharing software

Synergy combines your devices together in to one cohesive experience. Seamlessly move your mouse to any computer and start typing. Works on all major operating systems (Windows, Mac OS X, and Linux). Share your clipboard (copy and paste) between your computers. Drag and drop files from one computer to another (Windows and Mac OS X). Encryption keeps sensitive data safe on public networks. Network-based (IP) software KVM switch (non-video).

12/10/2014

About BNF notation

About BNF notation

What is BNF notation? BNF is an acronym for "Backus Naur Form". John Backus and Peter Naur introduced for the first time a formal notation to describe the syntax of a given language (This was for the description of the ALGOL 60 programming language, see [Naur 60]). To be precise, most of BNF was introduced by Backus in a report presented at an earlier UNESCO conference on ALGOL 58. Few read the report, but when Peter Naur read it he was surprised at some of the differences he found between his and Backus's interpretation of ALGOL 58. He decided that for the successor to ALGOL, all participants of the first design had come to recognize some weaknesses, should be given in a similar form so that all participants should be aware of what they were agreeing to. He made a few modificiations that are almost universally used and drew up on his own the BNF for ALGOL 60 at the meeting where it was designed. Depending on how you attribute presenting it to the world, it was either by Backus in 59 or Naur in 60. (For more details on this period of programming languages history, see the introduction to Backus's Turing award article in Communications of the ACM, Vol. 21, No. 8, august 1978. This note was suggested by William B. Clodius from Los Alamos Natl. Lab). Since then, almost every author of books on new programming languages used it to specify the syntax rules of the language. See [Jensen 74] and [Wirth 82] for examples. The following is taken from [Marcotty 86]: The meta-symbols of BNF are: ::= meaning "is defined as" | meaning "or" < > angle brackets used to surround category names. The angle brackets distinguish syntax rules names (also called non-terminal symbols) from terminal symbols which are written exactly as they are to be represented. A BNF rule defining a nonterminal has the form: nonterminal ::= sequence_of_alternatives consisting of strings of terminals or nonterminals separated by the meta-symbol | For example, the BNF production for a mini-language is: ::= program begin end ; This shows that a mini-language program consists of the keyword "program" followed by the declaration sequence, then the keyword "begin" and the statements sequence, finally the keyword "end" and a semicolon. (end of quotation)

12/05/2014

ServiceWorker/explainer.md at master · slightlyoff/ServiceWorker

ServiceWorker/explainer.md at master · slightlyoff/ServiceWorker

ServiceWorkers Explained What's All This Then? The ServiceWorker is like a SharedWorker in that it: runs in its own thread isn't tied to a particular page has no DOM access Unlike a SharedWorker, it: can run without any page at all can terminate when it isn't in use, and run again when needed has a defined upgrade model HTTPS only (more on that in a bit) We can use ServiceWorker: to make sites work faster and/or offline using network intercepting as a basis for other 'background' features such as push messaging and background sync Getting Started First you need to register for a ServiceWorker: if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js', { scope: '/my-app/' }).then(function(reg) { console.log('Yey!', reg); }).catch(function() { console.log('Boo!', err); }); } In this example, /my-app/sw.js is the location of the ServiceWorker script, and it controls pages whose URL begins /my-app/. The scope is optional, and defaults to /. .register returns a promise. If you're new to promises, check out the HTML5Rocks article. Some restrictions: The registering page must have been served securely (HTTPS without cert errors) The ServiceWorker script must be on the same origin as the page, although you can import scripts from other origins using importScripts …as must the scope HTTPS only you say? Using ServiceWorker you can hijack connections, respond differently, & filter responses. Powerful stuff. While you would use these powers for good, a man-in-the-middle might not. To avoid this, you can only register for ServiceWorkers on pages served over HTTPS, so we know the ServiceWorker the browser receives hasn't been tampered with during its journey through the network. Github Pages are served over HTTPS, so they're a great place to host demos. Initial lifecycle Your worker script goes through three stages when you call .register: Download Install Activate You can use events to interact with install and activate: self.addEventListener('install', function(event) { event.waitUntil( fetchStuffAndInitDatabases() ); }); self.addEventListener('activate', function(event) { // You're good to go! }); You can pass a promise to event.waitUntil to extend the installation process. Once activate fires, your ServiceWorker can control pages! So I'm controlling pages now? Well, not quite. A document will pick a ServiceWorker to be its controller when it navigates, so the document you called .register from isn't being controlled, because there wasn't a ServiceWorker there when it first loaded. If you refresh the document, it'll be under the ServiceWorker's control. You can check navigator.serviceWorker.controller to see which ServiceWorker is in control, or null if there isn't one. Note: when you're updating from one ServiceWorker to another, things work a little differently, we'll get onto that in the "Updating" section. If you shift+reload a document it'll always load without a controller, which is handy for testing quick CSS & JS changes. Documents tend to live their whole life with a particular ServiceWorker, or none at all. However, a ServiceWorker can call event.replace() during the install event to do an immediate takeover of all pages within scope. Network intercepting self.addEventListener('fetch', function(event) { console.log(event.request); }); You get fetch events for: Navigations within your ServiceWorker's scope Any requests triggered by those pages, even if they're to another origin The means you get to hear about requests for the page itself, the CSS, JS, images, XHR, beacons… all of it. The exceptions are: iframes & <object>s - these will pick their own controller based on their resource URL ServiceWorkers - requests to fetch/update a ServiceWorker don't go through the SerivceWorker Requests triggered within a ServiceWorker - you'd get a loop otherwise The request object gives you information about the request such as its URL, method & headers. But the really fun bit, is you can hijack it and respond differently: self.addEventListener('fetch', function(event) { event.respondWith(new Response("Hello world!")); }); Here's a live demo (you'll need to enable some flags to get it working in Chrome today). .respondWith takes a Response object or a promise that resolves to one. We're creating a manual response above. The Response object comes from the Fetch Spec. Also in the spec is the fetch() method, which returns a promise for a response, meaning you can get your response from elsewhere: self.addEventListener('fetch', function(event) { if (/\.jpg$/.test(event.request.url)) { event.respondWith( fetch('//www.google.co.uk/logos/…3-hp.gif', { mode: 'no-cors' }) ); } }); In the above, I'm capturing requests that end .jpg and instead responding with a Google doodle. fetch() requests are CORS by default, but by setting no-cors I can use the response even if it doesn't have CORS access headers (although I can't access the content with JavaScript). Here's a demo of that. Promises let you fallback from one method to another: self.addEventListener('fetch', function(event) { event.respondWith( fetch(event.request).catch(function() { return new Response("Request failed!"); }) ); }); The ServiceWorker comes with a cache API, making it easy to store responses for reuse later, more on that shortly, but first… Updating a ServiceWorker The lifecycle of a ServiceWorker is based on Chrome's update model: Do as much as possible in the background, don't disrupt the user, complete the update when the current version closes. Whenever you navigate to page within scope of your ServiceWorker, the browser checks for updates in the background. If the script is byte-different, it's considered to be a new version, and installed (note: only the script is checked, not external importScripts). However, the old version remains in control over pages until all tabs using it are gone (unless .replace() is called during install). Then the old version is garbage collected and the new version takes over. This avoids the problem of two versions of a site running at the same time, in different tabs. Our current strategy for this is "cross fingers, hope it doesn't happen". Note: Updates obey the freshness headers of the worker script (such as max-age), unless the max-age is greater than 24 hours, in which case it is capped to 24 hours. self.addEventListener('install', function(event) { // this happens while the old version is still in control event.waitUntil( fetchStuffAndInitDatabases() ); }); self.addEventListener('activate', function(event) { // the old version is gone now, do what you couldn't // do while it was still around event.waitUntil( schemaMigrationAndCleanup() ) }); Here's how that looks in practice. Unfortunately refreshing a single tab isn't enough to allow an old worker to be collected and a new one take over. Browsers make the next page request before unloading the current page, so there isn't a moment when current active worker can be released. The easiest way at the moment is to close & reopen the tab (cmd+w, then cmd+shift+t on Mac), or shift+reload then normal reload. The Cache ServiceWorker comes with a caching API, letting you create stores of responses keyed by request. self.addEventListener('install', function(event) { // pre cache a load of stuff: event.waitUntil( caches.open('myapp-static-v1').then(function(cache) { return cache.addAll([ '/', '/styles/all.css', '/styles/imgs/bg.png', '/scripts/all.js' ]); }) ) }); self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); }); Matching within the cache is similar to the browser cache. Method, URL and vary headers are taken into account, but freshness headers are ignored. Things are only removed from caches when you remove them. You can add individual items to the cache with cache.put(request, response), including ones you've created yourself. You can also control matching, discounting things such as query string, methods, and vary headers. Other ServiceWorker related specifications Since ServiceWorkers can spin up in time for events, they've opened up the possibility for other features that happen occasionally in the background, even when the page isn't open. Such as: Push Background sync Geofencing Conclusions This document only scratches the surface of what ServiceWorkers enable, and aren't an exhaustive list of all of the available APIs available to controlled pages or ServiceWorker instances. Nor does it cover emergent practices for authoring, composing, and upgrading applications architected to use ServiceWorkers. It is, hopefully, a guide to understanding the promise of ServiceWorkers and the rich promise of offline-by-default web applications that are URL friendly and scalable. Acknowledgments Many thanks to Web Personality of the Year nominee Jake ("B.J.") Archibald, David Barrett-Kahn, Anne van Kesteren, Michael Nordman, Darin Fisher, Alec Flett, Andrew Betts, Chris Wilson, Aaron Boodman, Dave Herman, Jonas Sicking, and Greg Billock for their comments and contributions to this document and to the discussions that have informed it.
Introduction to Service Worker: How to use Service Worker - HTML5 Rocks

12/03/2014

javascript - Is there any way to check if strict mode is enforced? - Stack Overflow

javascript - Is there any way to check if strict mode is enforced? - Stack Overflow

The fact that this inside a function called in the global context will not point to the global object can be used to detect strict mode:
var isStrict = (function() { return !this; })();
> echo '"use strict"; var isStrict = (function() { return !this; })(); console.log(isStrict);' | node
true
> echo 'var isStrict = (function() { return !this; })(); console.log(isStrict);' | node
false

11/24/2014

關於射手字幕網站關閉一事…..實在是沒什麼好大驚小怪的!(個人觀感) @ 美劇盒小品~美劇 英劇 歐美影集 劇情簡介 時間表 :: 痞客邦 PIXNET ::

關於射手字幕網站關閉一事…..實在是沒什麼好大驚小怪的!(個人觀感) @ 美劇盒小品~美劇 英劇 歐美影集 劇情簡介 時間表 :: 痞客邦 PIXNET ::

人人字幕組是各家字幕組之最,最快,最新,最齊,做到此規模模也是近兩年來的事, 如果你喜歡英文人名翻譯成中文,建議你可以到此一遊! http://www.yyets.com/php/subtitle 比較熱門的劇集,人人翻譯的速度很快,品質也不錯,如果家裡有老人家或是英文比較弱的朋友, 古裝劇人物較多的劇,都很適合看人人的翻譯,總之人人翻譯的作品很多, 除了一般劇集之外,歌唱 真人秀之類的也都包辦了 破爛熊http://www.ragbear.com/ 可能需要註冊 習慣使用" iTunes"下載檔案的人,你可以參考伊甸园字幕博客站, http://ytet.org/ 伊甸園有翻譯此種格式,但非每一部劇都有,該站"不翻譯中文人名" 如果你不介意的話,這裡也是一個好選擇 深影論壇www.shinybbs.com會翻譯"中文譯名" 深影大多翻譯小眾劇,加拿大的戲居多,翻譯品質也不錯, 缺點是翻譯速度稍慢,如果你看的劇只有他們才有翻譯,我建議你先等字幕出來 依字幕格式去更新,萬一時間軸不合,你就得邊看邊調,那可真會累死人! 伊甸園字幕組,破爛熊,深影……還有一些較小的字幕組,他們都還活得好好的! 別再大驚小怪了!

10/23/2014

OSCON 2014: How Instagram.com Works; Pete Hunt - YouTube

OSCON 2014: How Instagram.com Works; Pete Hunt - YouTube

# Downloading JS the right way - only download the JS you need for each “page” - single page app “page” == entry point - 17 entry points for Instgram - Subsequent navigations should not download the same JS again - ie. share libraries # Asynchronously load your bundles http://webpack.github.io/docs/code-splitting.html window.onpopstate = function () { if (window.location.pathname === ‘/profile’) { showLoadingIndicator(); require.ensure([], function () { hideLoadingIndicator(); require(‘./pages/profile’).show(); }); } else if (window.location.pathname === ‘/feed’) { showLoadingIndicator(); require.ensure([], function () { hideLoadingIndicator(); require(‘./pages/feed’).show(); } } # They’re part of the dependency graph Images, CSS, fonts, etc ex: ProfileEnteryPoint depends on profile.css // Ensure bootstrap.css stylesheet is in the page require(‘./bootstrap.css’); var Image = document.createElement(‘img’); myIage.src = require(‘./myimage.png’); // following code will only be executed after all the required resources loaded. # CSS the pragmatic way - Namespaced, unambiguous class names - No cascading (reason: a simple grep will know the the rule is no longer used) - single class name selector only - No overriding - <div class=“one two three”> - one, two and three should be orthogonal

fb-flo

fb-flo

fb-flo is a Chrome extension that lets you modify running apps without reloading. It's easy to integrate with your build system, dev environment, and can be used with your favorite editor. Live edit JavaScript, CSS, Images and basically any static resource. Works with your editor of your choice. Easily integrates with your build step, no matter how complex. Easily integrates with your dev environment. Configurable and hackable.

10/15/2014

Dev.Opera — The CSS3 object-fit and object-position Properties

Dev.Opera — The CSS3 object-fit and object-position Properties

The four possible values of object-fit are as follows: - contain: if you have set an explicit height and width on a replaced element, object-fit:contain will cause the content (e.g. the image) to be resized so that it is fully displayed with intrinsic aspect ratio preserved, but still fits inside the dimensions set for the element. - fill: causes the element’s content to expand to completely fill the dimensions set for it, even if this does break its intrinsic aspect ratio. - cover: preserves the intrinsic aspect ratio of the element content, but alters the width and height so that the content completely covers the element. The smaller of the two is made to fit the element exactly, and the larger overflows the element. - none: the content completely ignorse any height or weight set on the element, and just uses the replaced element’s intrinsic dimensions.
anselmh/object-fit

10/13/2014

RequireBin

RequireBin

Shareable JavaScript programs powered by npm and browserify

9/30/2014

It is, spiritual

It is, spiritual

自己总是不够努力,懒惰。有事情做的时候不努力向上,没事情做的时候又懈怠。这样的人格硬伤,和不会法语放在一起,真是残疾。

Material Design for Bootstrap | Hacker News

Material Design for Bootstrap Bootswatch: Paper
via: Material Design for Bootstrap | Hacker News

9/29/2014

Dimensions - Chrome 線上應用程式商店

Dimensions - Chrome 線上應用程式商店

Measure between the following elements: images, input-fields, buttons, videos, gifs, text, icons. You can measure everything you see in the browser.

"Wit — Natural language for the Internet of Things"

"Wit — Natural language for the Internet of Things"\\

The Renaissance of Voice PCs have keyboards. Phones have touchscreens. But for the next generation of devices, voice is the only option. However for us developers, voice interfaces often mean frustration and bad user experience. Wit.AI enables developers to add a natural language interface to their app or device in minutes. It’s faster and more accurate than Siri, and requires no upfront investment, expertise, or training dataset.

9/15/2014

petehunt/webpack-howto

petehunt/webpack-howto

Why webpack 1. It's like browserify but can split your app into multiple files. If you have multiple pages in a single-page app, the user only downloads code for just that page. If they go to another page, they don't redownload common code. 2. It often replaces grunt or gulp because it can build and bundle CSS, preprocessed CSS, compile-to-JS languages and images, among other things.
// webpack.config.js
module.exports = {
  entry: './main.js',
  output: {
    path: './build', // This is where images AND js will go
    publicPath: 'http://mycdn.com/', // This is used to generate URLs to e.g. images
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      { test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // use ! to chain loaders
      { test: /\.css$/, loader: 'style-loader!css-loader' },
      {test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} // inline base64 URLs for <=8k images, direct URLs for the rest
    ]
  }
};

9/04/2014

High Performance Animations - HTML5 Rocks

High Performance Animations - HTML5 Rocks

4 things a browser can animate cheaply
  • Position transform: translate(npx, npx);
  • Scale transform: scale(n);
  • Rotation transform: rotate(ndeg);
  • Opacity opacity: 0...1; The process that the browser goes through is pretty simple: calculate the styles that apply to the elements (Recalculate Style), generate the geometry and position for each element (Layout), fill out the pixels for each element into layers (Paint Setup and Paint) and draw the layers out to screen (Composite Layers). To achieve silky smooth animations you need to avoid work, and the best way to do that is to only change properties that affect compositing -- transform and opacity. The higher up you start on the timeline waterfall the more work the browser has to do to get pixels on to the screen. Animating Layout Properties Here are the most popular CSS properties that, when changed, trigger layout: width, height, padding, margin, display, border-width, border, top, position, font-size, float, text-align, overflow-y, font-weight, overflow, left, font-family, line-height, vertical-align, right, clear, white-space, bottom, min-height Animating Paint Properties Changing an element may also trigger painting, and the majority of painting in modern browsers is done in software rasterizers. Depending on how the elements in your app are grouped into layers, other elements besides the one that changed may also need to be painted. There are many properties that will trigger a paint, but here are the most popular: color, border-style, visibility, background, text-decoration, background-image, background-position, background-repeat, outline-color, outline, outline-style, border-radius, outline-width, box-shadow, background-size If you animate any of the above properties the element(s) affected are repainted, and the layers they belong to are uploaded to the GPU. On mobile devices this is particularly expensive because CPUs are significantly less powerful than their desktop counterparts, meaning that the painting work takes longer; and the bandwidth between the CPU and GPU is limited, so texture uploads take a long time. Animating Composite Properties There is one CSS property, however, that you might expect to cause paints that sometimes does not: opacity. Changes to opacity can be handled by the GPU during compositing by simply painting the element texture with a lower alpha value. For that to work, however, the element must be the only one in the layer. If it has been grouped with other elements then changing the opacity at the GPU would (incorrectly) fade them too. In Blink and WebKit browsers a new layer is created for any element which has a CSS transition or animation on opacity, but many developers use translateZ(0) or translate3d(0,0,0) to manually force layer creation. Forcing layers to be created ensures both that the layer is painted and ready-to-go as soon as the animation starts (creating and painting a layer is a non-trivial operation and can delay the start of your animation), and that there's no sudden change in appearance due to antialiasing changes. Promoting layers should done sparingly, though; you can overdo it and having too many layers can cause jank. Imperative vs Declarative Animations Developers often have to decide if they will animate with JavaScript (imperative) or CSS (declarative). There are pros and cons to each, so let’s take a look: Imperative The main pro of imperative animations happens to also be its main con: it’s running in JavaScript on the browser’s main thread. The main thread is already busy with other JavaScript, style calculations, layout and painting. Often there is thread contention. This substantially increases the chance of missing animation frames, which is the very last thing you want. Animating in JavaScript does give you a lot of control: starting, pausing, reversing, interrupting and cancelling are trivial. Some effects, like parallax scrolling, can only be achieved in JavaScript. Declarative The alternative approach is to write your transitions and animations in CSS. The primary advantage is that the browser can optimize the animation. It can create layers if necessary, and run some operations off the main thread which, as you have seen, is a good thing. The major con of CSS animations for many is that they lack the expressive power of JavaScript animations. It is very difficult to combine animations in a meaningful way, which means authoring animations gets complex and error-prone.
  • 8/27/2014

    Mailgun 提供的電子郵件範本 | Gea-Suan Lin's BLOG

    Mailgun 提供的電子郵件範本 | Gea-Suan Lin's BLOG

    Mailgun 公開了一份電子郵件範本,讓你可以在各種平台上面都正確顯示:「Transactional HTML Email Templates」。 公開的範本在 GitHub 上可以取得:「mailgun/transactional-email-templates」。 不過另外看到 Litmus 這個服務可以提供 Email previews,像是 Mailgun 這次放出來的測試可以在「TRANSACTIONAL EMAIL TEST」這邊看到,這個服務簡化了測試的過程…

    8/19/2014

    Web Speech API (I): 使用 SpeechSynthesis 讓瀏覽器講話 « The Front Row

    Web Speech API (I): 使用 SpeechSynthesis 讓瀏覽器講話 « The Front Row

    var u = new SpeechSynthesisUtterance("持續檢討 積極改進 上緊發條 全力以赴");
    u.lang = "zh-TW" // So system knows the right voice to use
     
    window.speechSynthesis.speak(u);

    A Complete Guide to Flexbox | CSS-Tricks

    A Complete Guide to Flexbox | CSS-Tricks

    Properties for the Parent (flex container)
  • display: flex
  • flex-direction: row | row-reverse | column | column-reverse
  • flex-wrap: nowrap | wrap | wrap-reverse
  • flex-flow: <'flex-direction'> || <'flex-wrap'>
  • justify-content: flex-start | flex-end | center | space-between | space-around
  • align-items: flex-start | flex-end | center | baseline | stretch
  • align-content flex-start | flex-end | center | space-between | space-around | stretch Properties for the Children (flex items)
  • order:
  • flex-grow: ; /* default 0 */
  • flex-shrink: ; /* default 1 */
  • flex-basis: | auto; /* default auto */
  • flex: none | [<'flex-grow'> <'flex-shrink'> ? || <'flex-basis'>] /* default 0 1 auto */
  • align-self: auto | flex-start| flex-end | center | baseline | stretch;
  • 8/12/2014

    TotalFinder brings colored labels back to your Finder and more!

    TotalFinder brings colored labels back to your Finder and more!

    Colored labels Brings full colors back into Mavericks. Folders on top Folders should always go first in list view. You can also easily toggle display of hidden files. Chrome tabs Apple finally introduced tabs in Mavericks. TotalFinder added Chrome tabs in Snow Leopard. Dual mode Display two Finder windows side-by-side on hot-key. Visor window The Finder is always one key-press away! Cut & Paste Use keyboard shortcuts to move files around. Faster than drag & drop.

    OS X Lion 新功能:剪下、貼上檔案與資料夾 | 天藍色

    OS X Lion 新功能:剪下、貼上檔案與資料夾 | 天藍色

    許多從 Windows 轉移到 Mac 的蘋友,首先會遇到的問題就是,為啥檔案沒有剪下貼上的功能?這不是最基本的嗎?其實這對於老玩家來說不是個問題,因為 Mac 系統著名的就是拖拉放的操作環境,不過,咱們倒也不排斥多了個剪下貼上,而 OS X Lion 終於將這功能實現囉!小弟來教教大家如何使用剪下、貼上功能。 首先 Command+C 將所選檔案、資料夾拷貝。 接著到目的地執行 Command+Option+V,即會將檔案『搬移』過去,原地點的檔案會消失,因為已經搬過去了。

    7/31/2014

    Mac App Store - Sip

    Mac App Store - Sip

    The refreshingly simple color picker that instantly samples and encodes any color on your screen. Just one quick click to savor the flavor and you're set! See what’s on special with Sip below.

    7/28/2014

    publicis-indonesia/Waves

    publicis-indonesia/Waves

    Click effect inspired by Google's Material Design http://publicis-indonesia.github.io/Waves/

    How a TED Talk inspired me to leave work to go live on a remote island | TED Blog

    How a TED Talk inspired me to leave work to go live on a remote island | TED Blog

    By Winston Chen Odysseus…Gauguin…Robinson Crusoe…and me? Many people dream of the ultimate escape: throwing all the baggage of civilization away and taking off to live on a remote island. But few people—particularly professional couples with young kids—actually go through with it. And yet, that’s just what my family did: we left Boston, and my reliable job at a software company, to go live on a tiny island north of the Arctic Circle for a year, unsure of what exactly we’d do there or what we would face upon our return. Stefan Sagmeister: The power of time offStefan Sagmeister: The power of time offThe seed of this idea was planted three years before, when a friend made me watch a TED Talk by graphic designer Stefan Sagmeister. He presented a tantalizing idea: “We spend about 25 years of our lives learning. Then there is about 40 years reserved for working. And then, tucked at the end of it, are about 15 years of retirement. I thought it might be helpful to cut off five of those retirement years and intersperse in between those working years.” It struck a deep chord with me. I was an executive at a small software company, a typical management job where I spent the bulk of my working day in PowerPoint. I’d been working for about 10 years, and felt like I was just going through the motions. We live in a society that celebrates strong work ethics and delayed gratification—all good things, but we’ve taken this cultural mindset to the extreme. We deny ourselves the time to do anything significant outside of work until we’re physically and mentally well past our prime. Ever since watching that talk, my wife and I wanted to take time off to go live in a faraway place. It took us three years to work up the nerve to actually do it. We finally decided to seize the moment when our children were old enough to remember the adventure, but not so old that they’d started elementary school. My wife, a teacher from Norway, was itching to get to back into the classroom and found a teaching job at a small island in Arctic Norway called Rødøy. Our launch sequence began. We rented out our house, furniture and car, and packed four big duffle bags. With loads of anxiety and fear, we took off for an island that we had never set foot on with a population of just 108 people, determined to live on my wife’s teacher salary for a year. While Stefan Sagmeister’s goal for his year off was to rejuvenate his creativity, mine was more loosely planned. I wanted to give myself a year without any concrete goals. I spent a lot of one-on-one time with our children with no objectives other than to be together—very different from before when I only had time to manage the children through daily routines. We communicated in a more relaxed and empathetic way, and I got to know both children in profound ways. The Botnen-Chen family. From left: Marcus, Kristin, Winston and Nora, with the beautiful scenery of Rødøy in the background. Photo: Winston Chen The Botnen-Chen family. From left: Marcus, Kristin, Winston and Nora, with the beautiful scenery of Rødøy in the background. Photo: Winston Chen I hiked and fished. After dropping the kids off at the island school, I would carry on with my backpack and fishing rod and go off. I took photography more seriously, because I could afford the time to think about the picture rather than rushing just to capture something. I learned to play the ukulele and started to paint in oil after a long hiatus. Three months into my island year, I rediscovered an old passion: programming. Just for fun, I started to develop a simple app that would read web articles or PDF files out loud using synthesized speech. I called it Voice Dream Reader. It quickly became a full-blown obsession as I realized that the app had the potential to transform the lives of students and adults with difficulties reading. Fun, passion, excitement—suddenly I knew the “next thing.” I worked on developing it slowly but surely, and kept on with the other activities I was enjoying so much on the island too. In the summer, with the kids and my wife out of school, we let the weather steer our days. Warm days meant taking our skiff to a beach on any of hundreds of nearby islands; cooler days were for hiking; rainy days were reserved for crafts projects and board games. Sometimes we stayed up hiking till midnight, taking in spectacular hours-long sunsets. I think that people hesitate to make bold moves like the one my family did not because it’s hard to leave: leaving is actually the easy part. I think it’s the fear of what happens after re-entry that keeps even the most adventurous families from straying far from home. When we headed home after a year, we had no jobs and no medical insurance waiting for us. And we were immediately up against mortgage and car payments, plus all the costs of living in an expensive city. But strangely, we felt truly at ease on our first evening back in the States as we sat on an outdoor patio with good friends talking about our respective summers. For our friends, summer had been a juggling feat—the careful balancing of their two demanding full-time jobs with their children’s jumbled activity schedules. The logistics of this had been worked out with two other sets of parents months in advance, in a strategy session that required laptops, a projector and plenty of wine. In contrast, our summer had entailed waking up in the late morning every day and making a big breakfast, then exploring an unthinkably beautiful island. A stunning sunset over Rødøy. Photo: Winston Chen A stunning sunset over Rødøy. Photo: Winston Chen Throughout that first evening of our return, I could feel palpable stress coming from our friends, a successful couple with substantial means. But my family, even with no income, felt at peace. That was when it dawned on me: our island year wasn’t just a memorable adventure. It had made us different people. After we returned, I trudged on with the Voice Dream Reader app, even though it was not selling much. Focusing on this, rather than getting a traditional job, was a far bigger risk than any I had taken before. But my wife and I often said, “What’s the worst that can happen? We go back and live on the island?” We were clothed with the armor of confidence forged from the newfound knowledge that our family could be very happy living on very little. I continued to improve the app until it started to generate enough income to sustain us. It wasn’t instantaneous, but today, nearly two years later, Voice Dream Reader is a bigger success than I could have ever imagined. It’s been a Top 10 selling education app in 86 countries. But more importantly, my work is immensely satisfying. With Voice Dream Reader, students who struggled with visual reading are able to listen and learn like everyone else. Adults who had trouble reading all their lives—not knowing that they have dyslexia—are now devouring books. It’s making a difference in people’s everyday lives. So many people who hear my story tell me how much they yearn for a similar experience: to take a big chunk of time off to pursue their heart’s desire. To them I say: have no fear. Most people are far more resilient to lifestyle changes than they think. And careers, which are rarely linear, can be just as resilient too. The upsides of taking a mid-career year of retirement are potentially life changing. By giving yourself time off and away, you’re creating a climate teeming with possibilities. Perhaps you’ll find passion in a new kind of work like I did. For sure, you’ll come back with new confidence and fresh perspectives to fuel your career, plus stories and memories to enrich you and your family for life. And you don’t have waited till you’re 65.

    7/26/2014

    厚生市集

    厚生市集

    厚生市集產銷革命3力: 1.強調在地食材,半數食材來自30公里內生產者 2.機車車隊配送,早上11點前訂,當天下午到貨 3.與食譜網站、團購網站、農業議題粉絲團串聯

    7/17/2014

    The Subtle Magic Behind Why the Bootstrap 3 Grid Works | Experience Design at Hello Erik

    The Subtle Magic Behind Why the Bootstrap 3 Grid Works | Experience Design at Hello Erik

    The Reasoning Behind It Container: The container works this way so that the edges of the container can have that virtual 15px padding around the content, but not require the body tag to have a 15px padding. This was a change in the RC1 of Bootstrap 3. Otherwise, the entire body would have a 15px padding, which would make non-bootstrap divs and such not touch the edges, which is bad for full width divs with colored backgrounds. Rows: Rows have negative margin equal to the containers padding so that they also touch the edge of the container, the negative margin overlapping the padding. this lets the row not be pushed in by the container’s padding. Why? Well… Columns: Columns have the 15px padding again so that they finally truly keep your content 15px away from the edge of the container/browser/viewport, and also provide the 15px + 15px gutter between columns. It is like this so that there doesn’t have to be a special first/last column that doesn’t have padding on the left/right, like in grids of old (960, blueprint, etc). Now, there is a consistent 15px space between the edges of the columns at all times, no matter what. Nested Rows: Nested rows work just as above, only now they overlap the padding of the column they are inside, just like the container. Essentially, the column is acting as the container, which is why you never need a container inside of anything. Nested Columns: Nothing is different here now, works the same as before. Offsets: These essentially split gutter widths to increase the space between columns by however many column units you want. Very, very simple. Push/Pull: These make use of positioning to trick HTML into flipping elements from left to right when going from mobile to desktop sizes. Or, for when you have a special use-case where offsets don’t work.

    7/11/2014

    Dropbox Tech Blog » Blog Archive » Improving Dropbox Performance: Retrieving Thumbnails

    Dropbox Tech Blog » Blog Archive » Improving Dropbox Performance: Retrieving Thumbnails

    For our web application, we use the Navigation Timing API to report back performance metrics. The API allows us to collect detailed metrics using JavaScript, for example DNS resolution time, SSL handshake time, page render time, and page load time: Instead of SPDY, we resorted to plain old HTTPS. We used a scheme where clients would send HTTP requests with multiple image urls (batch requests): GET https://photos.dropbox.com/thumbnails_batch?paths= /path/to/thumb0.jpg,/path/to/thumb1.jpg,[...],/path/to/thumbN.jpg The server sends back a batch response: HTTP/1.1 200 OK Cache-Control: public Content-Encoding: gzip Content-Type: text/plain Transfer-Encoding: chunked 1:data:image/jpeg;base64,4AAQ4BQY5FBAYmI4B[...] 0:data:image/jpeg;base64,I8FWC3EAj+4K846AF[...] 3:data:image/jpeg;base64,houN3VmI4BA3+BQA3[...] 2:data:image/jpeg;base64,MH3Gw15u56bHP67jF[...] [...] The response is: 1. Batched: we return all the images in a single plain-text response. Each image is on its own line, as a base-64-encoded data URI. Data URIs are required to make batching work with the web code rendering the photos page, since we can no longer just point an src tag to the response. JavaScript code sends the batch request with AJAX, splits the response and injects the data URIs directly into src tags. Base-64 encoding makes it easier to manipulate the response with JavaScript (e.g. splitting the lines). For mobile apps, we need to base64-decode the images before rendering them. 2. Progressive with chunked transfer encoding: on the backend, we fire off thumbnail requests in parallel to read the image data from our storage system. We stream the images back the moment they’re retrieved on the backend, without waiting for the entire response to be ready; this avoids head-of-line blocking, but also means we potentially send the images back out of order. We need to use chunked transfer encoding, since we don’t know the content length of the response ahead of time. We also need to prefix each line with the image index based on the order of request urls, to make sure the client can reorder the responses. On the client side, we can start interpreting the response the moment the first line is received. For web code we use progressive XMLHttpRequest; similarly for mobile apps, we simply read the response as it’s streamed down. 3. Compressed: we compress the response with gzip. Base64-encoding generally introduces 33% overhead. However, that overhead goes away after gzip compression. The response is no longer than sending the raw image data. 4. Cacheable: we mark the response as cacheable. When clients issue the same request in the future, we can avoid network traffic and serve the response out of cache. This does require us to make sure the batches are consistent however – any change in the request url would bypass the cache and require us to re-issue the network request.

    regex - Non capturing group? (?:) - Stack Overflow

    regex - Non capturing group? (?:) - Stack Overflow

    Let me try to explain this with an example... Consider the following text: http://stackoverflow.com/ http://stackoverflow.com/questions/tagged/regex Now, if I apply the regex below over it... (http|ftp)://([^/\r\n]+)(/[^\r\n]*)? ... I would get the following result: Match "http://stackoverflow.com/" Group 1: "http" Group 2: "stackoverflow.com" Group 3: "/" Match "http://stackoverflow.com/questions/tagged/regex" Group 1: "http" Group 2: "stackoverflow.com" Group 3: "/questions/tagged/regex" But I don't care about the protocol -- I just want the host and path of the URL. So, I change the regex to include the non-capturing group (?:). (?:http|ftp)://([^/\r\n]+)(/[^\r\n]*)? Now, my result looks like this: Match "http://stackoverflow.com/" Group 1: "stackoverflow.com" Group 2: "/" Match "http://stackoverflow.com/questions/tagged/regex" Group 1: "stackoverflow.com" Group 2: "/questions/tagged/regex" See? The first group has not been captured. The parser uses it to match the text, but ignores it later, in the final result.

    7/08/2014

    【大發現!!!原來我們的都錯了! 科學家揭示真正讓人恢復精力的「休息模式」 ...】 | Giga Circle

    【大發現!!!原來我們的都錯了! 科學家揭示真正讓人恢復精力的「休息模式」 ...】 | Giga Circle

    一、腦力勞動者,補瞌睡對你沒什麽用 你寫了一天的文案,主持了一天的會議,當一切都結束了,你嘆到:太累了,這一天我要睡個好覺。我們的常識使得我們對疲勞的第一反應就是“去躺躺吧”。但這是一個陷阱。 睡眠的確是一種有效的休息方式,但它主要對睡眠不足或體力勞動者適用。對體力勞動者來說,“疲勞”主要是由體內產生大量酸性物質引起,如果十分疲勞,應采取靜的休息方式。通過睡覺,可以把失去的能量補充回來,把堆積的廢物排除出去。如果不是很累,也可以在床上先躺一躺,閉目靜息,讓全身肌肉和神經完全放鬆後,再起來活動活動。 但如果你是坐辦公室的,大腦皮層極度興奮,而身體卻處於低興奮狀態,對待這種疲勞,睡眠能起到的作用不大,(除非你是熬夜加班,連正常睡眠時間都達不到)因為你需要的不是通過“靜止”恢覆體能,而是要找個事兒把神經放松下來。這樣你可以理解為什麽你周末兩天不出門依舊無精打采,而只需下班後遊泳半小時就神采奕奕。 二、不必停下來,只是換一下 既然睡覺不能幫助我們休息大腦,那什麽辦法才可以?答案是不停止活動,而只是改變活動的內容。大腦皮質的一百多億神經細胞,功能都不一樣,它們以不同的方式排列組合成各不相同的聯合功能區,這一區域活動,另一區域就休息。 所以,通過改換活動內容,就能使大腦的不同區域得到休息。心理生理學家謝切諾夫做過一個實驗,為了消除右手的疲勞,他采取兩種方式——一種是讓兩只 手靜止休息,另一種是在右手靜止的同時又讓左手適當活動,然後在疲勞測量器上對右手的握力進行測試。結果表明,在左手活動的情況下,右手的疲勞消除得更 快。這證明變換人的活動內容確實是積極的休息方式。 比如你星期五寫了5個小時的企劃案,最好第二天去給你的盆栽們剪枝而不是睡到太陽曬屁股。還有一點,當你無法選擇由腦力勞動轉入體力勞動時,你不妨在腦力勞動內部轉換。 法國傑出的啟蒙思想家盧梭就講過他的心得:“我本不是一個生來適於研究學問的人,因為我用功的時間稍長一些就感到疲倦,甚至我不能一連半小時集中精力於一個問題上。 但是,我連續研究幾個不同的問題,即使是不間斷,我也能夠輕松愉快地一個一個地尋思下去,這一個問題可以消除另一個問題所帶來的疲勞,用不著休息一 下腦筋。於是,我就在我的治學中充分利用我所發現的這一特點,對一些問題交替進行研究。這樣,即使我整天用功也不覺得疲倦了。”所以,這天你要是有好幾個 問題要處理,最好交替進行,而不要處理完一個再開始的二個,那樣會很快被耗盡。 三、最好的休息,是讓你重燃生活的熱情 我們的疲憊主要來自對現有的一層不變的生活的厭倦。所以最好的休息項目就是那些讓我們重新找到生活和工作熱情的活動。如果你幹完一件事,能夠幸福地感嘆“明天又是新的一天。”那這件事對你來說就是最好的恢覆熱情,調節情緒的方法。但可惜,我們缺乏對“休息”的想象力。我們能想出來的休息方法不是癡睡就是傻玩。 我們給你開了下面一些活動清單,基本思路是以“做”來解決“累”,用積極休息取代消極放縱。當然,最適合你的方法還是要你自己探索。事實上如果你覺得打掃衛生比坐過山車是更好的放松,那麽就去吧,別管世界上的其他人都在玩什麽。 也許你可以: 1.用看兩小時讓你開懷的漫畫或小說代替去KTV唱那些一成不變的口水歌。 2.試著放棄在周六晚上去酒吧,10點入睡,然後在7點起床,去沒有人的街上走走,或是看看你從來沒有機會看到的早間劇場,你會發現這一天可以和過去的千萬個周末都不相同。 3.不要再去你已經去過無數次的度假村找樂子了。找一條你你從沒去過的街道,把它走完。你會發現這個你感到膩味的城市結果你並沒有完全體會到它的妙處。 4.旅行,而不是換個地方消遣。去一個地方對那個地方本身心存好奇,對自己這趟行程心存美意,感受自己經驗範圍以外的人生樣貌。而不是坐了5小時飛機,只是換個地方打麻將,換個地方遊泳,換個地方打球…… 5.從這個周末起學習一項新的技藝,比如彈電子琴,打鼓……每周末練習1小時以上。 6.去社交。不要以為它總是令人疲憊的。雖然和看書比起來,它稍有點令人緊張,但也能讓你更興奮,更有認同感。你必須每周有兩三天是和工作圈子和親 戚外的人打交道。它讓你在朝九晚五的機械運行中不至失去活潑的天性。女性朋友們尤為需要走出去和朋友聚會,這些時刻你不再是滿臉寫著“效率”的中性人,而 是一個裙裾飛揚的魅力焦點。 7.做點困難的事,如果你是精神超級緊張的人。心理學家發現解除神經緊張的方法,是去處理需要神經緊張才能解決的問題。曾經一位精神即將崩潰的總經理找到一位醫師給出治療建議,結果他得到的處方是去動物園當馴獅師。一個月以後完全康覆。所以壓力特別大的時候你可以為自己再找分工作,但不要是和你職業類似的。比如去孤兒院做義工,或者去一個覆雜的機械工廠從學徒幹起,或者做一道超級覆雜的數學題。 往往珍惜生命的人,會不顧任何代價,去求得一個休息。休息十天、半個月,他們回來了。再看呀,是多麽神奇的一種變化!他們簡直是一個新生的人了。生機勃勃,精神飽滿,懷著新的希望,新的計劃,新的生命憧憬,他們己消除疲勞,獲得了從新起航的動力---燃料。 花些時間休息,可以使你獲得大量的精力、體力,使你取得從事任何工作,應付各種問題的力量,使你對於生命,能有一個愉快正確的認識,天下還能有其它時間的投資對於你更加有利嗎? 當我聽到有人說,他工作太忙,沒有時間去休息,我覺得這個人有些反常。或是他的能力不夠應付他的業務,他的工作缺乏系統性;或是他不善於支配他的員工,以致自己離開時事業就無法運行;或是他生性就太吝嗇,沒有部下或團隊。 連上廁所的時間都不肯犧牲。當然,假如他工作沒有計劃、沒有系統,本人一離開崗位,一切事務就要無法運行的話,他自然不能休息了。但是假如他是一個有組織協調能力的人,假如他的工詐有系統、有計劃,適度休息,這正是業務中的有利投資,因為休息回來,他的精力會更加集中、精神會更加飽滿。由此他的生命會延續的更長。人生的價值才能得到更加充分的體現與發揮。 每一個人都應該拋棄只顧工作不顧休息的念頭。那種“生命不止,奮鬥不休”的觀念是錯誤的,應立刻從腦海中消除掉。否則,你還沒有走完你應走完的生命旅程你就長眠於地下了。到那時你的理想、前途、事業不就都成了泡影了嗎?因此舍不得時間休息的人,絕對不是一個聰明人。 從人性的立場上來說,休息一事,利大於弊。古語說得好:“在患病的時候,任何人都是壞人。”即使是心底最善良的人,在身體疲憊不堪、神精衰弱的時 候,也會變得不通情理、脾氣暴噪。因此,當需要休息的候,你應該休息。不然的話,你的行為正如革命導師列寧同志所指出的那樣:“不會休息就不會工作。” 目前不論你是學生還是從事各種職業的男女老少,都不能忽視自然的警告,命令你適當延長你的休息時間,暫時停止你的學習或工作,否則你將受到自然規律的嚴厲處罰。無論你的地位有多高、金錢有多少、還是平頭百姓,在生命面前是一律平等的。這是蒼天賦與自然法官的權力。是人類無法改變的自然法則。 有一種感覺我們叫它無聊,這幾天不經意間我就在體驗無聊。 成年累月忙碌的節奏造就了頑固、可笑的生物節律,它總是讓我無法享受休息時的些許寧靜,閑暇時總覺得生活中缺了什麽、無所事事,甚至還以為知道了什麽是空虛? 前些天偶然看了一篇文章,破天荒知道了還有一種說法叫“享受無聊”。 傳統的教育告誡我們“無聊”是一種消極的情緒,一個奮發向上的人絕對不該有這種情緒,甚至不應該留給自己產生這種情緒的機會。 背負了太多的責任,於是我們活得好累,冠冕堂皇的說壓力來自外界,但我覺得更多的壓力是我們自找,因為在這個充滿壓力的社會我們沒有學會給自己減壓。 看看那些靜靜躺在海灘休假的人們,我們應該懂得無聊是一種難得的境界,或許比兢兢業業、勤勤懇懇的工作更難得。因為它需要你有好的心態、長遠的眼 光,要先接受它,讓自己的心靜下來,然後你才會真正的享受它。它絕不是一種頹廢,它是一種休整、一種積蓄,它會讓我們戒除“只會工作”的毒癮。 很早以前就有人告訴過我們:不會休息的人就不會工作。可我們由於功利的原因,早已將這一說法忘記。於是我們忙碌,我們努力,於是也就害怕無聊、害怕無事可做,甚至會因為閒暇而幾乎惶惶不可終日。 工作不應該成為生活的全部,工作只是為了更好的生活。我們應該是工作的主人,絕不是工作的奴隸。千萬不要以為無聊是消極、是不敬業。 所以忙碌的人們應該去學會享受生活、去習慣感受無聊,習慣這一種新奇的美妙的感受!悠哉樂哉!

    6/24/2014

    Are We There Yet?

    Are We There Yet?

    In his keynote at JVM Languages Summit 2009, Rich Hickey advocated for the reexamination of basic principles like state, identity, value, time, types, genericity, complexity, as they are used by OOP today, to be able to create the new constructs and languages to deal with the massive parallelism and concurrency of the future.

    6/17/2014

    Merrick Christensen - JavaScript Dependency Injection

    Merrick Christensen - JavaScript Dependency Injection

    var WelcomeController = function (Greeter) {
        document.write(Greeter.greet());
    };
    
    var Injector = {
    
        dependencies: {},
    
        process: function(target) {
            console.log('target:', target)
            var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
            var text = target.toString();
            console.log('target.toString():',text)
            var args = text.match(FN_ARGS)[1].split(',');
            console.log('args:', args);
            console.log('this.getDependencies(args):', this.getDependencies(args));
    
            target.apply(target, this.getDependencies(args));
        },
    
        getDependencies: function(arr) {
          console.log('fn: getDependencies', arr);
            var self = this;
            return arr.map(function(value) {
    
                return self.dependencies[value];
            });
        },
    
        register: function(name, dependency) {
            this.dependencies[name] = dependency;
            console.log('fn:register', this.dependencies)
        }
    
    };
    
    var RobotGreeter = {
      greet: function() {
        return 'Domo Arigato';
      }
    };
    
    var OtherGreeter = {
        greet: function() {
          return 'That will do pig.';
        }
    };
    
    // Randomly register a different greeter to show that WelcomeController is truly dynamic.
    Injector.register('Greeter', Math.random() > 0.5 ? RobotGreeter : OtherGreeter);
    
    Injector.process(WelcomeController);

    6/16/2014

    Project Parfait (Beta) from adobe

    Project Parfait (Beta)

    Extract everything you need from PSD comps - in your browser - PSD CSS Extraction, Measurements and Image Optimization Service for the Web
    Avocode – Preview and inspect PSDs
    Get CSS, SVG, image assets, fonts, colors. All without Photoshop.

    6/12/2014

    dc.js - Dimensional Charting Javascript Library

    dc.js - Dimensional Charting Javascript Library

    dc.js is a javascript charting library with native crossfilter support and allowing highly efficient exploration on large multi-dimensional dataset (inspired by crossfilter's demo). It leverages d3 engine to render charts in css friendly svg format. Charts rendered using dc.js are naturally data driven and reactive therefore providing instant feedback on user's interaction. The main objective of this project is to provide an easy yet powerful javascript library which can be utilized to perform data visualization and analysis in browser as well as on mobile device.

    6/09/2014

    Engineering Culture at Airbnb - Airbnb Engineering

    Engineering Culture at Airbnb - Airbnb Engineering

    Engineers own their impact At the core our philosophy is this: engineers own their own impact. Each engineer is individually responsible for creating as much value for our users and for the company as possible. We hire primarily for problem-solving. When you have a team of strong problem-solvers, the most efficient way to move the company forward is to leave decision-making up to individual engineers. Our culture, tools, and processes all revolve around giving individual contributors accurate and timely information that they can use to make great decisions. This helps us iterate, experiment, and learn faster. Making this environment possible requires a few things. Engineers are involved in goal-setting, planning and brainstorming for all projects, and they have the freedom to select which projects they work on. They also have the flexibility to balance long and short term work, creating business impact while managing technical debt. Does this mean engineers just do whatever they want? No. They work to define and prioritize impactful work with the rest of their team including product managers, designers, data scientists and others. Just as importantly, engineers have transparent access to information. We default to information sharing. The more information engineers have, the more autonomously they can work. Everything is shared unless there’s an explicit reason not to (which is rare). That includes access to the analytics data warehouse, weekly project updates, CEO staff meeting notes, and a lot more. This environment can be scary, especially for new engineers. No one is going to tell you exactly how to have impact. That’s why one of our values is that helping others takes priority. In our team, no one is ever too busy to help. In particular, our new grad hires are paired with a team that can help them find leveraged problems. Whether it’s a technical question or a strategic one, engineers always prioritize helping each other first.

    5/31/2014

    Imperative vs Declarative

    Imperative vs Declarative

    Let's generalize and say that there are two ways in which we can write code: imperative and declarative. We could define the difference as follows: Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen. Declarative programming: telling the "machine"1 what you would like to happen, and let the computer figure out how to do it. 1 Computer/database/programming language/etc Imperative:
    var numbers = [1,2,3,4,5]
    var doubled = []
    
    for(var i = 0; i < numbers.length; i++) {
      var newNumber = numbers[i] * 2
      doubled.push(newNumber)
    }
    console.log(doubled) //=> [2,4,6,8,10]
    
    Declarative:
    var numbers = [1,2,3,4,5]
     
    var doubled = numbers.map(function(n) {
      return n * 2
    })
    console.log(doubled) //=> [2,4,6,8,10]
    What the map function does is abstract away the process of explicitly iterating over the array, and lets us focus on what we want to happen. Note that the function we pass to map is pure; it doesn't have any side effects (change any external state), it just takes in a number and returns the number doubled. In many situations imperative code is fine. When we write business logic we usually have to write mostly imperative code, as there will not exist a more generic abstraction over our business domain.

    Array.prototype.reduce() - JavaScript | MDN

    Array.prototype.reduce() - JavaScript | MDN

    The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) has to reduce it to a single value.
    var total = [0, 1, 2, 3].reduce(function(a, b) {
        return a + b;
    });
    // total == 6
    var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
        return a.concat(b);
    });
    // flattened is [0, 1, 2, 3, 4, 5]

    5/16/2014

    JavaScript Promises: There and back again - HTML5 Rocks

    JavaScript Promises: There and back again - HTML5 Rocks - http://chunghe.googlecode.com/git/experiment/es6.promise/

    Domenic Denicola proof read the first draft of this article and graded me "F" for terminology. He put me in detention, forced me to copy out States and Fates 100 times, and wrote a worried letter to my parents. Despite that, I still get a lot of the terminology mixed up, but here are the basics: A promise can be: fulfilled The action relating to the promise succeeded rejected The action relating to the promise failed pending Hasn't fulfilled or rejected yet settled Has fulfilled or rejected
    function get(url) {
      // Return a new promise.
      return new Promise(function(resolve, reject) {
        // Do the usual XHR stuff
        var req = new XMLHttpRequest();
        req.open('GET', url);
    
        req.onload = function() {
          // This is called even on 404 etc
          // so check the status
          if (req.status == 200) {
            // Resolve the promise with the response text
            resolve(req.response);
          }
          else {
            // Otherwise reject with the status text
            // which will hopefully be a meaningful error
            reject(Error(req.statusText));
          }
        };
    
        // Handle network errors
        req.onerror = function() {
          reject(Error("Network Error"));
        };
    
        // Make the request
        req.send();
      });
    }
    
    function getJSON(url) {
      return get(url).then(JSON.parse);
    }
    

    5/15/2014

    Eight Terminal Utilities Every OS X Command Line User Should Know · mitchchn.me

    Eight Terminal Utilities Every OS X Command Line User Should Know · mitchchn.me

    You can have fun with Homebrew too: brew install archey will get you Archey, a cool little script for displaying your Mac’s specs next to a colourful Apple logo. The selection in Homebrew is huge—and because it’s so easy to create formulas, new packages are being added all the time.
    Archey—My command line brings all the boys to the yard.

    javascript - What does the exclamation mark do before the function? - Stack Overflow

    javascript - What does the exclamation mark do before the function? - Stack Overflow

    JavaScript syntax 101. Here is a function declaration:
    function foo() {}
    Note that there's no semicolon: this is a statement; you need a separate invocation of foo() to actually run the function. On the other hand, !function foo() {} is an expression, but that still doesn't invoke the function, but we can now use !function foo() {}() to do that, as () has higher precedence than !. Presumably the original example function doesn't need a self-reference so that the name then can be dropped. So what the author is doing is saving a byte per function expression; a more readable way of writing it would be this:
    (function(){})();
    +1. This really is the best answer here, and sadly, hardly upvoted. Obviously, ! returns boolean, we all know that, but the great point you make is that it also converts the function declaration statement to a function expression so that the function can be immediately invoked without wrapping it in parentheses. Not obvious, and clearly the intent of the coder. – gilly3 Jul 28 '11 at 16:58

    5/09/2014

    共享經濟盛行,Airbnb 和 Lyft 如何重塑人與人的信任關系? - Inside 網摘

    共享經濟盛行,Airbnb 和 Lyft 如何重塑人與人的信任關系? - Inside 網摘

    共享經濟盛行 在過去的幾年中,「共享經濟」已逐漸趨於成熟。主管機關、經濟學家紛紛試圖研究其影響。這些公司引發的消費者行為,在五年前看來,都是那麼難以置信的瘋狂。Lyft、Sidecar、Uber,讓我們跳進陌生人的車裡;Airbnb,使我們主動請陌生人到家裡住;DogVacay、Rover 讓我們放心的把狗狗寄托在陌生人家裡;Feastly 則牽線搭橋,讓我們去陌生人家裡吃飯...... 我們開始相信形形色色的陌生人,邀請他們進入自己的生活。也正因為如此,我們走進了親密網路的新紀元。 「共享經濟」不僅僅是經濟領域的突破,也是對文化的衝擊;它有著複雜的算法系統和明確的獎懲制度。eBay 可謂是帶領市場突破人與人面對面交易的先驅,鼓勵人們相信他人。Lyft 也有一套自己的方法,保證司機們接送的並不是馬路上隨隨便便的路人甲。每一位 Lyft 搭乘者都需要將 Facebook 的個人資料導入帳號。因此,每次他們撥出叫車電話時,自己的照片便會顯示在 Lyft 司機的手機桌面上;司機還會為乘客留下打分評級,信用記錄差的使用者將被自動忽略;此外,搭乘者還需在註冊加入信用卡資料,確保付款沒問題。 經濟飛漲,信任打折 Manit 說,自己的對他人信任門檻較低(low trust threshold)。換句話說,她更樂於信任別人,而非過度的自我保護。 懷疑論反映出一種廣泛而根深蒂固的心理狀態,並被現實中不靠譜的事例而不斷加深。因此,「共享經濟」的奉行者們認為,自己做的不僅僅是生意,而且從根本上改善了人與人的關系。傳統網路幫助陌生人在線上建立虛擬連接,而現代網路則幫助人們完成線下的真實溝通。紐約大學的教授 Arun Sundararajan 說,「人們實際的溝通程度遠遠低於客觀需要。」Lyft 聯合創始人 John Zimmer 則說,「共享經濟」要做的,就是逐漸填補兩者的鴻溝。 相識不易,信任更不易。2012 年全美社會調查數據顯示,僅有 32% 的被試願意相信他人,遠遠低於 1972 年的 46%。實際上,就算對他人信任度極高的 Manit 也並不會在沒有保障的情況下,向陌生人敞開家門。比如,她不接受陌生人租用自己的車,但如果透過 RelayRides 或者 Getaround 有口碑的中間公司,就另當別論了。 事實上,我們所處的商業環境中布滿陌生人的蹤影。每天,我們都把信用卡遞給陌生的收銀員;坐進陌生司機的計程車裡;吃著隔壁廚房裡陌生廚師做的菜;住在陌生的飯店,並從未擔心拿著鑰匙的侍應生會趁我們熟睡時潛入房間。所幸,工業革命時期建立起來的法律條例和保障體系,為如此龐大複雜的體系提供了有力支撐。 在那之前,美國人喜歡群居在小城鎮和農場社區,人際交往多呈現強關系,彼此間親切友善,價值觀也相仿。因此,做熟人生意並非難事。而情況在 19 世紀中葉發生了變化,當美國人從小村莊搬進大城市,小商人變成了大企業,本地市場也受到了跨國公司的衝擊。周圍的人從熟人頃刻變為陌生人,人們無法再依賴傳統的人際交往和文化准則來保障貿易。正如 UCLA 社會學家 Lynne Zucker 所言,曾經維系美國經濟運行的重要元素「信任」,迅速崩塌。在接下來的數年,正規的體系陸續出現,從而取代消失的「信任」。1870 年到 1920 年間,法規像雨後春筍般制定推出,銀行、保險、法律等行業紛紛建立起新制度。同時,政府法規陸續出台,協助規範新型產業。Zucker 說,「規範化的體制重建人與人間的信任,經濟秩序得以恢復。」 新時代下的新型信任關系 但新工業時代到來,體制又面臨新的改變。eBay 無法要求每一位擁有小商品的普通人,經過一系列複雜的法律條款,成為一個掛牌店主。於是,他們打造了自己的信任體系。先是監控 eBay 平台內的各種交易行為,發現買家和賣家的潛在問題,提供獨特的付款方式,並最終得以保障全部購買行為。由此,eBay 從原來「被動的主人」轉變為「積極的參與者」,如同銀行業、保險業在 20 世紀早期的變革,新的體制再一次重塑了信任—人與人不需要完全相信對方,只需依賴一個中間系統就能保障個人利益。 Airbnb 也模仿了該流程。最初,聯合創始人 Brian Chesky、Joe Gebbia、和 Nate Blecharczyk 只是想提供租客和房主的配對服務,隨後的事就留給雙方自行解決了。但幾年後,Airbnb 擴展、完善服務範圍--全面接手配對、付款、評論、溝通平台等。2011 年 6 月爆出「Airbnb 房主被房客洗劫一空」危機,也促使它不得不完善體制,建立信任與安全部門。 Airbnb 的信任與安全部門負責挖掘數據,追蹤每一筆訂單、預約、付款和房東與房客的溝通,以及評論的各個環節。如果交易雙方試圖透過第三方系統繞過 Airbnb,該資訊將被系統自動屏蔽。系統還能辨認出同一位租客是否重複訂房,有無刷高虛假信用記錄等不安全行為的嫌疑。 從多重角度來看,Airbnb 與 eBay 的體系類似--透過演算法為顧客承擔風險,提供充滿信任的交易平台。但問題在於 eBay 是一種雙向平台,你要麼買,要麼不買。對於這樣的系統,中間信任體系是必不可少的,它幫助消費者排除騙子和不良商家。而「共享經濟」公司面向的都是鬆散的個體,即便中間信用體系或許能夠檢測到個別不良使用者,卻沒法避免全部,比如愛開快車的瘋狂司機。因此,共享經濟需要的是更加細微嚴謹的條款。 私家車短租服務 RelayRides 的 CEO Andre Haddad 將「共享經濟」與父母的教養方式類比。「你有 3 個孩子,卻無法完全控制他們,只能引導他們做對的事情。」如果你在 eBay 買一款相機,你只需要知道賣主身份是 NikonIcon1972。 而在共享經濟模式下,人們不再匿名,而是傾向面對面溝通、交易。即便無法當面交流,雙方的帳號都與 Facebook 連通,使得虛擬交流也帶有真實的身份。RelayRides 發現租客和車主更傾向於面對面對接,交換鑰匙。盡管 RelayRides 想要發掘更加方便高效的方式來拓展生意,但沒想到傳統的「面對面」交易,更能增強雙方信任,並最大限度得保護車輛。 介紹人們相互認識,能鼓勵彼此表現得更加可靠,進而減少公司的保險支出。在「共享經濟」裡,商業仿佛已經退居其次,人與人的溝通、連結奠定了整個交易流程。從這一層面來看,當前的貿易仿佛回到了工業革命前--依賴人際關系和真實身份完成。新型的共享經濟公司更能吸引開放、前衛的早期早期採用者(early adopters)。全新的體系在讓人耳目一新的同時,也帶來了更加舒適的人際關系和交易體驗。

    Quill - An Open Source Rich Text Editor with an API

    Quill - An Open Source Rich Text Editor with an API

    Quill is an open source editor built for the modern web. It is built with an extensible architecture and an expressive API so you can completely customize it for your use case. Some built in features include: - Fast and lightweight - Semantic markup - Standardized HTML between browsers - Supports Chrome, Firefox, Safari, and IE 9+

    5/01/2014

    聰明旅行小學堂/機上座位代碼藏玄機!字母為何少了I? | NOWnews 今日新聞

    聰明旅行小學堂/機上座位代碼藏玄機!字母為何少了I? | NOWnews 今日新聞

    有網友問YOYO:她請旅行社飛機選位,要求與同伴座一起,旅行社卻選33H跟33J,請問位子是真的坐在一起嗎?為什麼不是H/I/J連號一起?也就是:航空座位,真的沒有I嗎? 航空公司的座位,基本上是用數字及英文混合表示,因為機型的不同,座位配置也會不一樣。以商務艙來說,座位配置基本上是2-2-2或1-2-1;以經濟艙來說,有的是3-3,有的是2-4-2,或是3-4-3。 那航空公司是怎麼運用英文,去定義機上的座位呢?基本規定如下: 一、會與數字混淆的字母必須避免使用 如:I跟1很像,O跟0很像,S跟5很像,G跟C很像,B跟8很像。故,若您是1I,到底是11,還是1I? 二、發音會混淆的字母必須避免使用 如:I的發音跟走道的英文aisle的音接近,這會造成旅客與航空公司溝通上的誤會,故,你若選I行的座位,你可能會以為是坐到走道。 三、有禁忌的數字不用 如:東方是4,西方是13,有些航空座位數上會故意省去這些號碼。 四、通用規定 航空公司座位安排上不成文規定是:A/K一定是靠窗,C/D/G/H一定是走道,目前,恪遵這規定的航空有國泰、港龍、韓亞、新航、聯合等航空。 所以綜整以上,基本上I是一定不會用到,因為有太多爭議;B有時也不會用到。因此,商務艙常用為:2-2-2:AC-DG-HK、1-2-1:A-DG-K;經濟艙常用為:3-3:ABC-DEF、2-4-2:AC-DEFG-HK、3-4-3:ABC-DEFG-HJK。

    4/10/2014

    Nimble

    Nimble

    Parallel
    _.parallel([
        function (callback) {
            setTimeout(function () {
                console.log('one');
                callback();
            }, 25);
        },
        function (callback) {
            setTimeout(function () {
                console.log('two');
                callback();
            }, 0);
        }
    ]);
    Series
    _.series([
        function (callback) {
            setTimeout(function () {
                console.log('one');
                callback();
            }, 25);
        },
        function (callback) {
            setTimeout(function () {
                console.log('two');
                callback();
            }, 0);
        }
    ]);

    4/08/2014

    Why the (CoffeeScript) arrow matters

    Why the (CoffeeScript) arrow matters

    BONUS POINTS: NO NAMED FUNCTIONS - NO CONFUSION An otherwise forgotten but very important feature on CoffeeScript is the absence of named functions. This is great, because named functions are available to all of your code regardless of the declaration order. This makes it very easy to write some really confusing JS code:
    var importantThing = veryComplicatedFunction()
    
    // (...) A thousand lines later
    
    function veryComplicatedFunction () { ... }
    This type of organization is very damaging to the readability of your code. CoffeeScript requires you to store functions in variables - like everything else.

    4/07/2014

    fikovnik/ShiftIt · GitHub

    fikovnik/ShiftIt · GitHub - use this version: https://github.com/fikovnik/ShiftIt/issues/105

    ShiftIt is an application for OSX that allows you to quickly manipulate window position and size using keyboard shortcuts. It intends to become a full featured window organizer for OSX. It is a complete rewrite of the original ShiftIt by Aravindkumar Rajendiran which is not longer under development. For discussing any sort of stuff about this app, please create a new issue right here.

    McBopomofo

    McBopomofo - 需要重新修改熱鍵

    3/17/2014

    7. Memory : Stack vs Heap

    7. Memory : Stack vs Heap

    Stack vs Heap So far we have seen how to declare basic type variables such as int, double, etc, and complex types such as arrays and structs. The way we have been declaring them so far, with a syntax that is like other languages such as MATLAB, Python, etc, puts these variables on the stack in C. The Stack What is the stack? It's a special region of your computer's memory that stores temporary variables created by each function (including the main() function). The stack is a "FILO" (first in, last out) data structure, that is managed and optimized by the CPU quite closely. Every time a function declares a new variable, it is "pushed" onto the stack. Then every time a function exits, all of the variables pushed onto the stack by that function, are freed (that is to say, they are deleted). Once a stack variable is freed, that region of memory becomes available for other stack variables. The advantage of using the stack to store variables, is that memory is managed for you. You don't have to allocate memory by hand, or free it once you don't need it any more. What's more, because the CPU organizes stack memory so efficiently, reading from and writing to stack variables is very fast. A key to understanding the stack is the notion that when a function exits, all of its variables are popped off of the stack (and hence lost forever). Thus stack variables are local in nature. This is related to a concept we saw earlier known as variable scope, or local vs global variables. A common bug in C programming is attempting to access a variable that was created on the stack inside some function, from a place in your program outside of that function (i.e. after that function has exited). Another feature of the stack to keep in mind, is that there is a limit (varies with OS) on the size of variables that can be store on the stack. This is not the case for variables allocated on the heap. To summarize the stack: the stack grows and shrinks as functions push and pop local variables there is no need to manage the memory yourself, variables are allocated and freed automatically the stack has size limits stack variables only exist while the function that created them, is running The Heap The heap is a region of your computer's memory that is not managed automatically for you, and is not as tightly managed by the CPU. It is a more free-floating region of memory (and is larger). To allocate memory on the heap, you must use malloc() or calloc(), which are built-in C functions. Once you have allocated memory on the heap, you are responsible for using free() to deallocate that memory once you don't need it any more. If you fail to do this, your program will have what is known as a memory leak. That is, memory on the heap will still be set aside (and won't be available to other processes). As we will see in the debugging section, there is a tool called valgrind that can help you detect memory leaks. Unlike the stack, the heap does not have size restrictions on variable size (apart from the obvious physical limitations of your computer). Heap memory is slightly slower to be read from and written to, because one has to use pointers to access memory on the heap. We will talk about pointers shortly. Unlike the stack, variables created on the heap are accessible by any function, anywhere in your program. Heap variables are essentially global in scope. Stack vs Heap Pros and Cons Stack very fast access don't have to explicitly de-allocate variables space is managed efficiently by CPU, memory will not become fragmented local variables only limit on stack size (OS-dependent) variables cannot be resized Heap variables can be accessed globally no limit on memory size (relatively) slower access no guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed you must manage memory (you're in charge of allocating and freeing variables) variables can be resized using realloc()

    Threes! 原來算數學可以讓人上癮!熱門數學遊戲登陸 Android -電腦玩物

    Threes! 原來算數學可以讓人上癮!熱門數學遊戲登陸 Android -電腦玩物

    3/16/2014

    .bash_profile vs .bashrc

    .bash_profile vs .bashrc - .bash_profile 只有在 login 的時候執行一次, .bash_rc 每開一個 new terminal 都會執行一次

    WHEN working with Linux, Unix, and Mac OS X, I always forget which bash config file to edit when I want to set my PATH and other environmental variables for my shell. Should you edit .bash_profile or .bashrc in your home directory? You can put configurations in either file, and you can create either if it doesn’t exist. But why two different files? What is the difference? According to the bash man page, .bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells. What is a login or non-login shell? When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt. But, if you’ve already logged into your machine and open a new terminal window (xterm) inside Gnome or KDE, then .bashrc is executed before the window command prompt. .bashrc is also run when you start a new bash instance by typing /bin/bash in a terminal. Why two different files? Say, you’d like to print some lengthy diagnostic information about your machine each time you login (load average, memory usage, current users, etc). You only want to see it on login, so you only want to place this in your .bash_profile. If you put it in your .bashrc, you’d see it every time you open a new terminal window. Mac OS X — an exception An exception to the terminal window guidelines is Mac OS X’s Terminal.app, which runs a login shell by default for each new terminal window, calling .bash_profile instead of .bashrc. Other GUI terminal emulators may do the same, but most tend not to. Recommendation Most of the time you don’t want to maintain two separate config files for login and non-login shells — when you set a PATH, you want it to apply to both. You can fix this by sourcing .bashrc from your .bash_profile file, then putting PATH and common settings in .bashrc. To do this, add the following lines to .bash_profile: if [ -f ~/.bashrc ]; then source ~/.bashrc fi Now when you login to your machine from a console .bashrc will be called.

    http://stackoverflow.com/questions/1158091/defining-a-variable-with-or-without-export

    http://stackoverflow.com/questions/1158091/defining-a-variable-with-or-without-export

    export makes the variable available to sub-processes. That is, export name=value means that the variable name is available to any process you run from that shell process. If you want a process to make use of this variable, use export, and run the process from that shell. name=value means the variable scope is restricted to the shell, and is not available to any other process. You would use this for (say) loop variables, temporary variables etc. It's important to note that exporting a variable doesn't make it available to parent processes. That is, specifying and exporting a variable in a spawned process doesn't make it available in the process that launched it.
    To illustrate what the other answers are saying:
    al$ foo="Hello, World"
    al$ echo $foo
    Hello, World
    al$ bar="Goodbye"
    al$ export foo
    al$ bash
    bash-3.2$ echo $foo
    Hello, World
    bash-3.2$ echo $bar
    
    bash-3.2$

    node environment

    add to ~/.profile

    export NODE_ENV=production   
    

    then in node
    > process.env.NODE_ENV
    'production'
    

    then in express
    > app.get('env') //will be 'production'
    

    or:
    > NODE_ENV=production node server.js
    

    3/07/2014

    同工不同酬?年薪 50 萬美金的工程師到底作哪些工作啊? | Winston Chen

    同工不同酬?年薪 50 萬美金的工程師到底作哪些工作啊? | Winston Chen

    他們究竟是作哪些事情,或是擁有哪些技術,讓他們如此值錢?這些東西有辦法用『學』的嗎? 首先,這篇是翻譯文章,原文在此:What kind of jobs do the software engineers who earn $500K a year do? 。我偶而會讀到幾篇我想要全文翻譯分享的文章,比如說上一篇祕技 - 沒有人教過你的應徵技巧跟這篇,翻譯分享之前,我都會直接聯絡原文作者,徵求同意,並作交換連結。一般而言(至少這兩篇拉),原文作者都會很啊薩力地大方同意,還會在來往的信件中不經意地露出他暗爽所受的內傷,總之我想說的是,不要亂去翻譯沒有版權的文章放到自己的平台上面,那內容不是你的,要轉載,要翻譯好歹也問一下原作者吧 XD 背景資訊 之前 Business Insider 出了一篇某個 Google 工程師拒絕年薪 50 萬工作,因為 Google 每年附他 300 萬美金的文章,有個對這數字很有興趣的人就上 Quora 問了,我要怎麼作才會跟他一樣?我也要到 Google 上班然後年薪 300 萬美金這樣(誰不想啊?) 這位叫 Amin Ariana 的創業家就上 Quora 寫了一則被讚到破表的回答,我自己非常同意,也受到很多啟發,因此跟 Amin 聯絡獲得允許,分享他的文章如下。 以下正文開始 聲明:我之前也是 Google 的員工,但是我的回答不代表 Google 的觀點。 首先,這問題問得有點奇怪,有點誤導人,好像只要工程師做了哪幾點,或是獲得哪些技能以後,就可以掛到年薪 50 萬的保證。其實 Business Insider 那邊說得很清楚了,50 萬美金其實是薪水跟股票的總和。 一類跟二類勞工 要了解高昂報酬背後的條件,讓我先先來打個比方。 假設你是村子裡面非常重要的,負責水源供給的勞工好了。這裡有兩種勞工類型:一類勞工,與二類勞工。 一類勞工會拎起一到兩個水桶,衝到水源旁邊,裝滿它們,把他們兩個挑回來,大概夠 20 個人喝吧,如此一來有水喝的村民就皆大歡喜了。這個勞工挑水的過程可能會喝掉一些水,然後回到村中,他可能可以分一些水回家作他的報酬。 二類勞工不太理所謂『公平分水』的概念,他會拿起一把鏟子,帶上一止水杯,然後忽然間就消失了。他跑到水源處,挖起一條可以通到村莊的小溪,希望可以把水源引過來。每當他拖著疲憊的身軀,拎著空杯子回到村莊的時候,總會引起一陣失望,但是不知道為什麼那村中的長老相信他,相信他在做的事情(還丟根骨頭給他啃,讓他不致餓肚子)。 某天,他直挺挺的站在村莊前面,他深後白涔涔地流躺著一條飲用水的小溪。這條小溪立刻把一類專門經營『水快遞』的勞工趕出市場,他們只好轉行,加入別的團隊。這個二類勞工呢,看他對這條小溪擁有多少的控制權,一般而言,他有小溪很大部分的擁有權。 後來村莊決定要把小溪整個買下來,整進整個村莊的供水系統,於是村莊拿了他們一部分的財產去換,比如說土地啊什麼的,這個二類勞工於是瞬間升級變成地主了。 村子裡面的媒體注意到村子給這個二類勞工的薪水奇高,別村的人根本挖不動他(他應該是有跟村子簽訂協議,比如要在村子裡留兩年,才能領完全額的報酬之類的),於是出了一篇報導,寫得好像別村出高價挖角,卻因為村子給的薪水太好,以致於這個二類勞工根本不會考慮。 這時候,一類勞工看了媒體報導,覺得村子虧待他們,同工不同酬(請看下面這個兩隻猴子同工不同酬的影片),心生不滿。 沙灘上的掘渠者 來說說一個真實的故事吧。 今年跨年的時候,我跑去 Monterey Bay 玩,沙灘上有個年輕人在挖洞,我饒有興致地站在高處看,我太太欣賞著沙灘美景,其他人根本不在意這個年輕人的舉動,沒有人理他。我指著他轉頭跟太太說:『你等著看,30分鐘以後,周遭的所有人都會加入,幫這個年輕人挖』 30 分鐘以後,他挖出了一條小渠道,從他沙灘上的城堡直挺挺的延伸到海邊有水的地方,希望把海水引入渠道,注入他的護城河。那渠道還不夠深,海水還進不來,於是年輕人忙著加深河道。又過了 5 分鐘,原本站在旁邊看熱鬧的小孩們開始加入,動手幫忙。10 分鐘以後,周遭的機個大人也開始挖掘。15 分鐘以後,一個靦腆的,拎著相機的外國人也投入幫忙。60 分鐘之內,這位二類勞工影響了 15 個一類勞工自願投入,一起把海水引入護城河。 文章開頭的照片就是我當時照的,永久地紀念我對個人力量的賭注。那個拿著紫色桶子的傢伙就是渠道的創始者,不過照片上看不出來就是了。 新聞報導總是很喜歡忽略很多真實的細節,這篇年薪 50 萬的報導就忽略掉『汗水並不等價』這個部分。二類勞工願意突破現狀,孤獨地,有時候可能還要挨餓一小段時間來引入村子賴以維生的水源,一類勞工則是用自己完成的工作與技能去交換薪水,兩者最主要的差異是冒險,而且不保證一定會回收。 村子裡有遠見的那群人可以說都是二類勞工(在 Goolge 裡面領高新的那群),他們篳路藍縷,以啟山林,連結了村莊的水源。這些拿很多股票的傢伙大概是下列其中一種: 在 Goolge 當初創立時,就已經負責創造其核心價值的那群人 自己業餘的時候玩玩自己的專案(side project),然後公司覺得超級有用,很有價值的那群人。[譯注:Gmaill 其實就是這樣從 Side Project 長成現在 Goolge 核心產品的。] 自己開新創公司,被 Google 買進來的 (比較少拉)不知道為什麼有辦法成為某種核心科技或是技能的唯一提供者 除此之外,這種待遇大都是憑空想像出來的,用來賣很多很多 Business Insider 文章的這樣(以台灣的例子來說,就是商周,還有今週刊那些 XD)。 價值 190 億美金的不錄取通知 每顆心都會歌唱,唱得不完整,直到另一顆心跟著附和。 - 柏拉圖 多謝大家的熱情支持,本文在 Quora 上面已經累積了 12 萬則瀏覽,Quora 真是太屌了。 我收到很多評論,有一部分跟我說上列的故事很難應用到他們的生活中,另一部分的評論問到跟公司談判股權的技巧,希望要到 50 萬美金收入的方式,其他的評論則說我這篇文章根本沒有回答到他的問題。大部分的評論者都是一類勞工,還在想怎麼作才能炒高自己的市場價值,獲得更高的『收入』。 那我再來說個故事吧,一個發生在上列文章出來一個禮拜之內的故事,希望這次會具體一點,比較好懂。 2009 年 5 月,有個一類勞工應徵 Twitter ,但是他被拒絕了,於是 2009 年 8 月,他又跑去 Facebook 應徵,他也被拒絕了,怎麼辦?他決定自己出來試試看,挑起二類勞工的大樑,從『增進人類溝通』的水源處,挖起那條之前拒絕他一類服務的那兩間公司都非常需要的小溪。 一路走來,他與跟他一起挖小溪的朋友影響了 55 人加入團隊,一起努力,村中的長老也丟了些骨頭給他,一開始只有 25 萬美元,接下來 8 百萬美元,眼看著小溪越來越成功,紅杉創投到後來注入 5000 萬美元的資金。 我寫這篇文章的 3 小時前, CNN 剛剛報導他們二類勞工的作品被 Facebook 以 190 億美金收購(你沒聽錯, 190 億美元)。 Facebook 買了 Whatsapp。而幫 Facebook 挖了五年小溪的 Brian Acton ,正式成為 Facebook 的股東,正是那個當初拒絕他工作申請的 Facebook 。 在他開挖之前(開 Whatsapp 公司之前),他曾經寫下了這兩條推特訊息: 推特總部不要我。沒有關係,反正從我家過去很遠。 Facebook 也不要我。不過那是個很厲害人們社交的好機會。我很期待接下來的人生旅程。 你覺得那 55 個人有需要去跟 Facebook 談判,要 50 萬美金的薪水嗎?還是你覺得當那些人獲利了結,要離 Facebook 出走時, Facebook 會砸下重金,並拿出股票來留人? 二類勞工不會去比較,或是談判薪水,因為他們不是在出賣他們的勞力給村莊(公司),他們賣的是被低估的財富,那些出價的村莊沒有別的選擇,只能拿出相對於這些財富的數字,這些二類勞工端出來的財富,可以讓村莊與自己雙雙受益(你看看 Facebook 往上衝的股價就知道)。 你可以想想,要賣掉你挖通的水源時,有沒有哪個村莊願意坐在談判桌的另一邊。當村莊決定買水的時候,薪水條中多出來的幾個零,都不過是基本條件罷了。 Amin Ariana 現駐矽谷,是個軟體創業家。

    2/24/2014

    Bitcoins the hard way

    Ken Shirriff's blog: Bitcoins the hard way: Using the raw Bitcoin protocol Ken Shirriff's blog: Bitcoin mining the hard way: the algorithms, protocols, and bytes

    Electrum Bitcoin Wallet

    Electrum Bitcoin Wallet

    Instant on: Your client does not download the blockchain, it uses a remote server. Forgiving: Your wallet can be recovered from a secret seed. Safe: Your seed or private keys are not sent to the server. Information received from the server is verified using SPV No downtimes: Several public servers are available, you can switch instantly. Ubiquitous: You can use the same wallet on different computers, it will auto-synchronize. Cold Storage: You can have secure offline wallets and still safely spend from an online computer. Open: You can export your private keys into other Bitcoin clients. Tested and audited: Electrum is open source and was first released in November 2011.

    2/17/2014

    Oleg Andreev - Bitcoin Non-Technical FAQ

    Oleg Andreev - Bitcoin Non-Technical FAQ

    How fast are the transactions? Transactions are secured by being included in a block. Blocks are generated approximately every 10 minutes. Including the time to propagate a transaction through the network, today it usually takes about 15 minutes to verify inclusion in a block. For better security, one can wait until more blocks are added after the block with the transaction. How transactions are secured? Transactions are grouped into blocks and each block contains the signature of the previous block, thus making up a chain of blocks. The security of the system is based on computational difficulty to generate blocks parallel to the main chain. The more blocks are created after the block containing your transaction, the harder it is to fork the chain and make the transaction invalid. Therefore, no transaction is 100% confirmed. Instead, there is a confirmation number — a number of blocks built after the transaction. Zero confirmations means that the transaction is not yet included in any block (unconfirmed). One confirmation means that the transaction is included in one block and there are no more blocks after it yet. Today for small transactions one or two confirmations (10-20 minutes) are considered enough. For bigger transactions it is recommended to wait for at least six confirmations (1 hour). One known exception is 120 confirmations required by the protocol for the use of generated bitcoins. This is because miners (those who create blocks) have the most of computing power in the network and must have extra incentive to play fairly and generate blocks in the main chain without attempting to double-spend their rewards. What do miners do exactly? Miners create blocks. To create a block one needs to create a file containing unconfirmed transactions (that are not yet included in any other block), add a timestamp, a reference to the latest block and a transaction sending 50 bitcoins from nowhere to any address. Then, the miner needs to compute a signature for the block (which is basically a very long number). This signature is called hash and the process of computing is called hashing. Computing a single hash takes very little time. But to make a valid block, the value of its hash must be smaller than some target number. The hash function is designed to be hard to reverse. That is, you cannot easily find some file contents that will produce the desired hash. You must alternate the contents of the given file and hash it again and again until you get a certain number. In the case of Bitcoin, there is a field in a file called “nonce” which contains any number. Miners increment that number each time they compute a hash until they find a hash small enough to be accepted by other clients. This may take a lot of computing resource depending on how small is the target hash value. The smaller the value, the smaller the probability of finding a valid hash. There is no guarantee that you need to spend a certain amount of time to find a hash. You may find it quickly or not find it at all. But in average, the small enough value of block hash takes time to create. This constitutes a protection against creation of a parallel chain: to fork the chain you will need to spend more resources than the people who created the original blocks What are the parameters of the network? Here are some parameters of the Bitcoin chain. They may be different for alternative currencies based on the Bitcoin software (like Namecoin). The minimum amount of bitcoins is 0.00000001 BTC. Blocks are created every 10 minutes. Block size is limited to 1 Mb. Difficulty is adjusted every 2016 blocks (approx. every two weeks) Initial reward for a block is 50 BTC. Reward is halved every 210 000 blocks (approx. four years). Points #5 and #6 imply that the total number of bitcoins will not exceed 21 million. Why are blocks created every 10 minutes? The 10 minute interval is designed to give enough time for the new blocks to propagate to other miners and allow them to start computation from a new point as soon as possible. If the interval was too short, miners would frequently create new blocks with the same parent block, which would lead to a waste of electricity, a waste of network bandwidth and delays in transaction confirmations. If it was too long, a transaction would take longer to get confirmed. Why is the block size limited to 1 Mb? The block size is limited to make a smoother propagation through the network, the same reason why the 10 minute interval was chosen. If the blocks were allowed to be 100 Mb in size, they would be transferred slower, potentially leading to many abandoned blocks and a decrease in the overall efficiency. Today a typical size of a block is 50-200 Kb which makes a lot of room for growth. In the future it is possible to increase block size when the networks get faster. Decreasing time interval would not change much because the security of transactions depends on the actual time, not the number of blocks. How can the protocol be changed? The protocol is a list of rules that every client must follow in order to validate transactions and have their transactions validated by others. Hence, if you change the rules for yourself, other clients will simply reject your transactions and you probably will not be able to accept theirs. This makes it hard to change the protocol. If there is a change that a vast majority of clients will find useful, then it is possible to publicly agree that starting with the block number X, new rules will apply. This will give a certain amount of time to everyone to update the software.

    Turning speech into actionable data

    Introducing Wit Speech API

    How does it work? Behind the scene, Wit combines various state-of-the-art Natural Language Processing techniques and several speech recognition engines in order to achieve low latency and high robustness to both surrounding noise and paraphrastic variations (there are millions of ways to say the same thing). Fortunately, you don’t need to care about all this machinery. We focus all our energy into creating the simplest developer experience possible. You can be up and running in a few minutes using our website. Wit will adapt to your domain over time, from ice-cream distribution to space missions. Wit makes no assumptions and remains 100% configurable.

    Oleg Andreev - Journalist's guide to describe Bitcoin and not look like an idiot

    Oleg Andreev - Journalist's guide to describe Bitcoin and not look like an idiot

    When writing about Bitcoin many journalists use certain phrases that are not quite correct and do not explain anything to everyone else. Dear journalist, if you read this short article you will finally understand what are you talking about and outperform 99% of your colleagues. In a short paragraph, Bitcoin can be described like this (you can take my text without asking): Bitcoin is a payment network with its own unit of account and no single controlling entity behind it. Users make transactions between each other directly and verify them independently using cryptographic signatures. To prevent duplicate spendings, many specialized computers spend a lot of computing power to agree on a single history of transactions. Due to historical reasons, this process is called “mining” because new bitcoins are created as a reward for performing this work. Anyone who validates next block of transactions can claim transaction fees and a fixed amount of new bitcoins. Transactions are validated at a constant rate (10 minutes in average) and every four years allowed amount of new bitcoins is halved. This means that the total amount of bitcoins is limited by the protocol (21M total, 11M already created). Transaction fees are not fixed and determined by the market. Bitcoin mining is secondary to the whole idea and the term “mining” is unfortunate (early Bitcoins were generated before anyone was doing any transactions yet, so the whole process was called “mining” instead of “paying for transaction verification”). One common pitfall is to start talking about mining without describing its real purpose. It is not to generate new units (who would need them?), it is to validate transactions. Bitcoins are valuable only because of robust payment network which is maintained by the miners. And miners get paid for their work in form of transaction fees and newly generated bitcoins. Second common pitfall is to say that miners “solve complex algorithms”. They do not solve anything. They do two things: transaction verification (checking digital signatures and throwing away invalid and duplicate transactions), and a long and boring computation which means a repetitive computation of a well-known algorithm with slightly different input until a “good enough” number appears as a result that will be accepted by other users as a proof of performed work. This has nothing to do with “math problems” or any other intellectual task. It is merely a way to guarantee that the resulting number really took some time to produce. This allows people to build a single chain of transactions and see that it would be economically impossible to produce a parallel chain (without trusting each other personally). The last pitfall in describing mining is saying something like “tasks are getting more complex over time”. Tasks are not getting any more complex. The are all the same and not complex at all (any amateur programmer can understand them). But the difficulty of a boring “proof of work” is adjusted by everyone every 2 weeks to maintain the same rate of transaction validation (10 minutes). If people throw more resources at mining, difficulty will rise. If mining gets less profitable, some computers will be shut down and the difficulty will get lower. If a miner produces a “proof” which is not difficult enough, it will not be accepted by other users. The last point is related to amount of units available. In fact, “1 Bitcoin” is a name for 100 million smallest units, thus the total amount of units ever possible is around 2100 trillion. Alternative currencies based on Bitcoin source code sometimes advertise more units (e.g. Litecoin has 4 times more), but the difference is only in names and divisibility of the total money supply, not in actual value (if you cut a pie in 10 pieces instead of 5, the total value does not really change). So it would be fair to mention that 1 bitcoin is much more divisible than dollars and euros. Hopefully, this knowledge will help you to avoid common mistakes when writing your article and make some friends in enthusiastic Bitcoin community.

    Tech Notes: React, JSX, and CoffeeScript

    Tech Notes: React, JSX, and CoffeeScript

    CoffeeScript instead of JSX If you're using CoffeeScript, your source code isn't JavaScript to begin with. But turns out that CoffeeScript's flexible syntax makes it relatively painless to use the underlying API directly. Start with shortening the DOM alias and writing more or less the same code as above. Also note that you don't need to explicitly return as the last statement in a function is implictly returned, and that the function literal syntax for argumentless function is just a bare ->:
    R = React.DOM
    # ...
    
    render: ->
      R.p(null, R.a({href:'foo'}, 'bar'))
    But you can do better. First, CoffeeScript knows to insert the curlies on an object literal because of the embedded colon.
      R.p(null, R.a(href:'foo', 'bar'))
    And then you can remove the parens by splitting across lines. When providing args to a function, a comma+newline+indent continues the argument list. Much like Python, the visual layout follows the semantic nesting.
      R.p null,
        R.a href:'foo', 'bar'
    In fact, beyond the first argument, the trailing commas are optional when you have newlines. Here's the same thing again with two links inside the <p>:
      R.p null,
        R.a href:'foo', 'bar'  # note omitted comma here
        R.a href:'foo2', rel:'nofollow', 'second link'
    CoffeeScript also makes every statement into an expression, which is a familiar feeling coming from functional programming. It means you can use statement-like keywords like if and for on the right hand side of an equals sign, or even within a block of code like the above. Here's a translation of the (7-line) <ol> example from above.
    R.ol null,
      for result in @results
        R.li key:result.id, result.text
    There is one final feature of CoffeScript that I find myself using, which is an alternative syntax for object literals. For example, suppose in the above example the "key" attribute needs to be computed from some more complicated expression:
    R.ol null,
      for result, index in @results
        resultKey = doSomeLookup(result, index)
        R.li key:resultKey, result.text
    The simplification is that, within a curly-braced object literal, entries without a colon use the variable name as the key. The above could be equivalently written:
    R.ol null,
      for result, index in @results
        key = doSomeLookup(result, index)
        R.li {key}, result.text
    This is particularly useful when the attributes you want to set have meaningful names -- key is pretty vague, but if you construct an href and a className variable it's pretty clear where they are going to be used. These can be mixed with normal key-value pairs, too, like:
    href = ...
    className = ...
    R.li {href, className, rel:'nofollow'}, ...
    Putting it all together, here's a larger example, part of an implementation of an "inline edit" widget. To the user, this widget is some text with a "change" button to its right, where clicking on "change" swaps the line of text out for an edit field positioned in the same place, allowing the user to make a change to the value directly. (Like how it works in a spreadsheet.) The first branch of the if is the widget's initial state; the @edit function flips on the @state.editing flag.
    render: ->
      if not @state.editing
        R.div null,
          @props.text
          ' '  # space between text and button
          R.span className:'link-button mini-button', onClick:@edit, 'change'
      else
        R.div style:{position:'relative'},
          R.input
            style:{position:'absolute', top:-16, left:-7}
            type:'text', ref:'text', defaultValue:@props.text
            onKeyUp:@onKey, onBlur:@finishEdit
    To get a feel for these rules, you can just experiment and look at the generated JavaScript. Or you can go to coffeescript.org and click the "Try CoffeeScript" tab, where you can enter nonsense expressions there just to experiment with the syntax.

    2/15/2014

    Netflix颠覆HR:我们只雇「成年人」 | 极客公园

    Netflix颠覆HR:我们只雇「成年人」 | 极客公园

    Netflix 究竟是如何吸引和管理人才的? 只招最优秀的,把不够优秀的请走 回溯到 2001 年,互联网泡沫破灭打乱了公司的 IPO 计划,我们还裁掉了 1/3 的员工。但圣诞节时转机来了,DVD 播放机成为热门礼品,公司的 DVD 邮寄订阅业务也意外暴涨。 有一天我和工程师约翰谈话,说希望尽快替他找到帮手。裁员之前,约翰手下有三名工程师。可他的回答却出人意料:“我宁可自己做,也不要二流手下。”原来,过去约翰要花大量时间去管理员工并收拾他们的烂摊子。 这句话日后反复在我耳畔回响:你能为员工提供的最佳福利,不是请客吃饭和团队活动,而是招募优秀的员工,让他们和最优秀的人一起工作! 如果你希望团队里都是最优秀的员工,那么你必须要请能力不足的人离开。 2002 年形势好转后,Netflix 成功 IPO,当时公司急需专业精算师和经验丰富的财务专员,而会计劳拉已经不胜任这份工作。劳拉曾为公司做出了很大的贡献,有人提议给她特设一个职位,但我直接告诉她,我们愿意提供一笔可观的离职补偿金。 当时,我甚至做好了迎接泪水的准备,没想到劳拉很轻松地说:她对离开表示遗憾,但丰厚的离职补偿金可以让她考虑重返校园或参加培训,寻找新的职业发展路径。 只雇用、奖励和容忍「成年人」 从业三十年,我发现很多大公司的 HR 往往花太多时间用于拟定人力资源管理的条例,以应付一小撮与公司利益不一致的员工,结果往往得不偿失。我们根本不会让这种人进入公司,我们筛选出的人是真正的“成年人”。 自 Netflix 创始起,我们就制定了带薪假期的规定,并且一直用内部的办公系统记录出勤情况。公司上市后,审计师提出异议,认为应引入正式的办公考勤系统,对员工的休假时间做出清晰的解释。但里德和我都认为,只要不违反相关法律,何必在意繁文缛节? 现在,Netflix 的员工可以自行决定休假计划,HR 只是给出指导性意见。比如,财务部门的员工不要在季初和季末最繁忙时休假;如果要连续休假 30 天,要先与 HR 面谈。 在差旅和报销制度上,我们告诉员工,公司想节省开支,希望员工把公司的钱当成自己的钱,这大大降低了公司成本。很多公司都通过代理机构订票,但如果相信员工会遵守「公司利益最优先原则」,让他们自行在网上订票,就可以省下一大笔中介费。 和很多经理一样,我也会时不时和员工吃工作餐,如果是为了招聘或销售目的,餐费就可以报销;如果是和同事不涉及工作的用餐,餐费则不能报销。总之,只要遵循「成年人」做法的原则,绝大多数员工都会遵守制度。 对员工直言他们的表现 在很久以前,我们就取消了正式的评估制度。某些职能部门员工的业绩好坏一目了然,而且,偶尔一次的考核也没有连贯性。 比如,工程师玛利亚被招进公司是负责查找漏洞的。但由于技术的更新,我们很快发现这项工作可以全自动化。经理要求玛利亚参加评估,以防炒掉她时可能出现的劳务纠纷。但是我说:“大家都知道这出戏会怎么演下去。你先定目标,她根本无法达标,你每周都要跟她进行一次难堪的谈话,最后她还是会被炒掉。这对 Netflix 又有什么好处?” 我建议他,不妨直接告诉玛利亚:你的能力已经不符合公司需要了。以我的经验,只要告知实情,人们总是能够应对变化。 取消了正式的业绩评估后,我们设立了「非正式的」360 度考评制度。我们提出尽可能简洁的问题:你觉得你的同事「应该做什么」、「不要做什么」。简单、诚恳、定期地以探讨的方式进行评估,效果远远好过正式考评制度。 而对于管理者,我们的要求是,要确保员工理解公司发展的核心动力和盈利模式。即使你招到了充满干劲的员工,你仍需要告诉他们公司是怎么赚钱的,让他们理解怎么做能帮助公司成功。 股票期权不应是“金手铐” 在伊拉克战争期间,时任美国国防部部长拉姆斯菲尔德说:“你是要带着已有的军队参战,而不是带领一支你所期待的队伍。”不过,我却告诉 Netflix 的经理们要反其道而行之:伟大的团队完成伟大的工作,打造一支伟大的团队就是你的首要职责。 Netflix 从 DVD 邮寄租赁业务向流媒体服务转型时,就曾面临这样的挑战。我们急需那些曾在亚马逊和谷歌等大公司有云计算研发经验的人才,但显然,这些人才不容易被挖。 此时,我们的薪酬体制起了很大的作用。Netflix 的薪酬原则也遵循这样的理念:坦诚待人、把员工当成年人对待。比如,公司提供的年薪中没有「绩效奖金」,因为我们相信市场主导的薪酬标准,只要招对了人,没有年终奖既不会让他们变懒,也不会让他们变笨。事实上,我们通常会给出高出市场平均水平的薪酬,在年终也会发放超出员工预期的福利。 另外,一般公司都会在提供一份有竞争力年薪的同时,搭配固定的股票期权。而我们让员工自己选择股票期权在整体薪酬中的占比。每个月公司都以稍低于股价的价格发放一定的期权,而且允许即时兑现。 我们觉得,股票期权不应该是为了降低离职率的「金手铐」,如果你获得了更好的发展机会,就该在离开时带走你应得的全部。

    2/10/2014

    #7300 (Keypress not getting arrow keys in chrome) – jQuery Core - Bug Tracker

    Events - keydown, keypress, keyup

    keypress Fires when an actual character is being inserted in, for instance, a text input. It repeats while the user keeps the key depressed.
    JavaScript Madness: Keyboard Events
    There are many other special keys on a typical keyboard that do not normally send characters. These include the four arrow keys, navigation keys like Home and Page Up, special function keys like Insert and Delete, and the function keys F1 through F12. Internet Explorer and WebKit 525 seem to classify all of these with the modifier keys, since they generate no text, so in those browsers there is no keypress event for them, only keyup and keydown. Many other browsers, like Gecko, do generate keypress events for these keys, however.
    #7300 (Keypress not getting arrow keys in chrome) – jQuery Core - Bug Tracker
    I've reviewed the bulk of tickets regarding keypress on both the Chrome, Chromium and Webkit bug trackers and it would appear that there are no intentions on supporting correct keypress behavior from any of these camps now or in the future. The reason for this is that a) keypress and its behavior is not mentioned specifically in any specs and b) Although FireFox and Opera support this feature, Webkit (used by Chrome and Safari) decided to copy the IE behavior in this case which reserves arrow keypresses for internal browser behavior only. There is no way that jQuery can circumvent this behavior and it is instead recommended that you use keydown instead as this is supported.
    keyboard events -
    Detecting arrow key presses in JavaScript - Stack Overflow Use keydown, not keypress for non-printable keys such as arrow keys:
    function checkKey(e) {
        e = e || window.event;
        alert(e.keyCode);
    }
    
    document.onkeydown = checkKey;
    arrow keys are only triggered by onkeydown, not onkeypress keycodes are: left = 37 up = 38 right = 39 down = 40