跳到主要內容

發表文章

目前顯示的是 2015的文章

[轉載] 新創公司上市了,員工能不能獲利?

作為Starup的創始成員的收入大多沒外人想的豐厚
其實拿著計算機算算所有的股權乘上公司估值大概就有個底
而且絕大多數的公司很可能失敗,活下來的公司也不見得能順利上市
沒上市的股權的價值也就是...嗯,可能不會差壁紙很多

當然這不代表參與新創公司的價值不高
只是如果沒有堅定的動機,單純追求財富可能去大公司會比較好

原文連結

糖、脂肪、鹽:食品工業誘人上癮的三詭計 讀摘

有滿長一段時間沒閱讀職業及娛樂以外的書了
雖然就目的而言,這本報導類型書就是大家想像中的那種書
不過我想這是本很適合食品業界的人閱讀的書籍,介紹很多食品界的"成功案例"
包含各種投注在食品科學研究、腦科學研究、法律及標準訂定遊說、廣告的手段

糖、脂肪、鹽這三種不外乎就是食品界成功產品的關鍵之鑰
糖跟脂肪都能替大腦帶來相當強烈的滿足感,效用甚至接近毒品
鹽分是這3者中最容易戒掉的,離開高鹽份食品一段時間後再吃原先日常的食物便能察覺過鹹
這3者能提升美味,促進食品保存及運輸、去除異味、降低售價等等的功用
書中介紹為什麼食品中的這3種成分越加越多寫得很完整

大腦的機制應該是給予古早人類食用糖份、脂肪以獲得能量的強烈動機
不過在現代社會食物容易取得的狀況下,反而造就世界的胖子越來越多的狀況
書中提到的一段話,食品界的目標是開發、銷售最好吃的產品,而不是最好的產品
而且食品宣傳與食品本身一樣重要
胖子的生活品質差,且會耗用更大量的醫療資源
但在工作時間長的現在工作型態,加上大量的食品宣傳,讓很多人選擇了高熱量又沒營養的食品
雀巢公司除了一般商品開發外,現在還多投入了流質營養食品的開發
想想這些公司的高層很多都不吃自家公司的產品,例如魏應充,雖然他的例子有更黑心的原因
他們卻宣傳要人們去吃這些造成肥胖的食物,等吃到消化系統有問題後再改吃他們的流質營養食品
這是多麼可怕的狀況

一些觀點值得思考
企業以賺錢為目的,這些狀況都是正常演變,像家樂氏最早的產品是健康玉米片
資本體系有什麼方式可以降低這些問題嗎?
一般人不會想讓兒童或青少年觀看菸酒的廣告,那麼為什麼能允許這些產品針對他們宣傳呢?
高糖、高油脂的產品帶來的社會成本越來越高,政府該怎麼處理呢?
管制的話勢必有一大部分的聲音會說是自由選擇,責任在於選擇的人上
管制企業生產過程,則勢必會將成本轉嫁給消費者
希望未來能找出適用於現代社會的合理處理方式

Java JavaScriptEngine Nashorn 設定 Date Instance 預設時間

Java 的 JavaScriptEngine 的時間會依照 Java 程式所在的環境時間、設定的時區為準
所以執行 JavaScript code 的 new Date(),取得的時間也會跟環境時間相同 我這次的需求是希望 new Date 取得的時間是客戶瀏覽器端的時間,而不是Server本地時間 讓運算結果更貼近客戶用瀏覽器取得的結果
查過了 ScriptEngine 的 Source code,他並沒有公開的方法可以設定 Instance 的時間 底層的 native date 型別的時間其實是使用 Java 的 System.currentTimeMillis(); 似乎是沒有插手的空間了?
不過好在 JavaScript 的特色就是彈性大 手動 override 掉 Date function 也可以解決
var timeMilliseconds = 1447739048291;  // millisecond is passed from client side. var d = new Date(timeMilliseconds),      _ODATE = Date;
Date = function (a1, a2, a3, a4, a5, a6, a7) {
    if (arguments.length === 0) {
        return d;
    } else if (arguments.length === 1) {
        return new _ODATE(a1);
    } else {
        a3 = a3 || 0;
        a4 = a4 || 0;
        a5 = a5 || 0;
        a6 = a6 || 0;
        a7 = a7 || 0;
        return new _ODATE(a1, a2, a3, a4, a5, a6, a7);
    }
};
不指定時間的 Date constructor 就直接回傳已經建立好的客戶端時間 如果有指定時間就跑原本的 Date constructor 比原先預期還要容易些的解法

2015/11/25追記 Java 7 及以前用的 ScriptEngine Rhino會因此碰到 Exce…

日光節約時間的程式計算方式

參考討論:
subtract two dates in milliseconds considering daylight time saving
Android/Java - Date Difference in days

最近一個外國客戶反映了個程式計算的日期相減結果不正確的問題
原本該算出10天的,結果卻給出了9.95天這樣微妙的結果
追查原因後才恍然大悟這是個之前都不曾想過的議題

很多計算日期差的程式的算法是這樣的
取出日期物件的 milliseconds 相減後,再除以一天的 millisecond  1000*60*60*24
不過國外有日光節約時間這回事,所以在那段期間的一天的 milliseconds 就和一般時間的不同
所以日光節約時間內的日期減掉一般日期,算出來的時間差就不是完整一天的時間的整數倍

看過討論後
最合適的解法是將時間轉換到UTC時區再進行計算,呈現在前端的日期再轉換成使用者時區
Java裡可以使用將會被納入到標準規格的 Joda Time 的API來進行
其他的程式語言就看是否有類似的時間處理規格,不然就轉成UTC計算了

羅技滑鼠送修過程紀錄

今天拿到替換品的滑鼠,整個送修事件算是告一個段落
寫一下流程紀錄讓有需要的人參考

之前購買鍵盤滑鼠的時候已經稍微查過現在的滑鼠生態
似乎現在滑鼠的微動裝置出現問題的時間都不會太短
羅技的滑鼠相較便宜貨較貴的價值就在3年保固
品質的話不熟悉這個產業也不多說什麼
不過聽說羅技早期是用日本製的微動,現在都改用中國製的

這次送修的滑鼠有兩隻,M705 跟 M105
M705是滿好用的滑鼠,不過買的時候也查到滿多案例是不長的時間內會出現連點問題
M105是價位低的有線滑鼠,這隻買來跟筆電帶來帶去也還能湊合用
前陣子M705出現連點狀況,並能排除靜電因素
結果過沒幾天,比他晚買的M105居然也開始有連點狀況
這下更是讓我打定主意非得兩隻都送修
畢竟滑鼠雖是消耗品,但價格也沒便宜到能夠讓我隨便換
都買了比較貴的保固,沒有用到比其他牌更久的時間,那不修真的是浪費錢

AWS Java code samples

紀錄最近在處理 AWS 相關 issue 時用的部分 method
最基本的 download、upload等等還滿好在 AWS 上找到範例
不過似乎有些要求就沒那麼好找

從AWS下載檔案的檔案名稱(alias name)或其他 Header 調整 AWS示範了建立供下載使用的連結的範例

public static URL getURLPresigned(String bucket, String s3name) {
    AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
    Date expire = new Date(new Date().getTime() + 86400000L);    // set to be available for 1 day.
    return s3client.generatePresignedUrl(bucket, s3name, expire, HttpMethod.GET);
}

但是會使用AWS的,絕大多數都是有大量檔案存取需求
應該有不少公司的做法也會是上傳的檔案會加上 hash
避免檔案被覆蓋或作為多版本紀錄用途
但是給使用者下載的檔案名稱還是要使用原先上傳時的才比較合理

一個可行的做法就是調整下載的回應的 Content-Disposition Header
這個 Header 可以用來設定下載的檔案名稱,規格的說明可以查看定義文件
寫出來的範例如下:

public static URL getURLPresigned(String bucket, String s3name, String contentDisposition) {
    AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
    Date expire = new Date(new Date().getTime() + 86400000L);   // set to be available for 1 day.

    ResponseHeaderOverrides headers = …

避免 scroll bar 影響網頁元件的外觀

Scroll bar 是網頁上常見的設計之一
只是有時候不太能預期你的 element 的內容是否多到需要用 scroll bar
或者是 element 的內容會隨著操作而變動
這種不確定性會對網頁的排版造成影響,很可能 scroll bar 的產生會擠壓到原本的元素



上面的示範提供了兩個例子
先注意原本的外觀後繼續操作
移動滑鼠到 element 上就可以看到 scroll bar 的產生
第一個例子的當 scroll bar 出現後,原本的文字排版也跟著變化
第二個例子則是出現 scroll bar 前後的文字排版都相同

建議不要想著去計算 scroll bar 的寬度
首先是 scroll bar 的寬度依各家瀏覽器廠商的實作而不同
再來是用 JavaScript 計算會有效能上的損耗,以及可能有相容性的問題

第二個例子的處理方式是在外面的 element 及內部的 element 中間塞入了個 div
這個 div 的外觀依需求將寬或長指定的跟外層 element 相同
這樣就能保持內容的外觀,scroll bar 也只會影響這個中介 div
很多 web 的設計都能使用這個想法,插入中介 element 讓外層跟內部的顯示效果區隔

Java 實現 JavaScript 的 encodeURIComponent

參考文章:encodeURIComponent and decodeURIComponent in Java

很多時候需要將字串轉成 UTF-8 編碼後的ascii,特別是在 Web 端的輸出
Java 裡的內建 Class URLEncoder 裡的 encode 方法看起來雖然像是為此產生
少部分沒那麼嚴謹的教學也會說用這個方式就能編譯 UTF-8
但之後可能會碰到意料之外的問題
雖然大部分的文字編碼結果都沒有問題,但極少部分的符號編碼卻跟JavaScript的不同
最明顯的就是 space,空白用Java的 URLEncoder 會編譯成 + 而不是 %20
在 Java 端產生的網址字串可能就因此不能作用

[轉載] [Growth Hack] 如何系統性的救回半死不活的 MVP 產品?

原文連結:
[Growth Hack] 如何系統性的救回半死不活的 MVP 產品?

這篇將工具推薦跟使用理由都寫得不錯
進行轉換率增加的步驟時可以參考這篇文章

=================================

坦白說,這個標題若照 Growth Hack 的定義,有點誤用
因為若照矽谷的建議來說,Growth Hack 的 tunning 是建議 Product Market Fit 之後才進行
這個原因是因為 Growth Hack 屬於 Marketing 範圍的一種,而且是創意的 Marketing
實作需要大量資源。而且沒進入 PMF 的話, Funnel 漏水率太兇

所以比較正確的標題應該是:
「如何用 Growth Hack 中使用的技術工具,將自己半死不活的 MVP 產品推破 Product Market Fit 的下限」
不過顯然這樣「政治正確」的下標法,沒有人要看
所以我還是沿用原標題好了 XD

每月在舉辦 Intro to Growth Hack 講座傳授「Growth Hack 心法」的緣故
我有時候會收到聽眾事前一些相當精彩的問題,發現大家困擾其實都長的差不多

這一次因為收到一個「典型技術開發者」的問題,我覺得相當適合整理成具體的 FAQ
因此取得提問者的同意,把產品細節馬賽克之後放上來

(因為這個問題的相同變形實在出現太多次了,包括我以前也有這樣的困擾)

[轉載] 王功權:不是所有創業公司都適合拿風投

我喜歡這篇的一段話
人一生的才華、資源、熱情一定要放在自己最感興趣的一件事上,這樣工作才不至於成為你的負擔
不至於企業走到半路要大幅調整方向,不至於在生命快要結束的時候感到後悔

原文連結

8月2日,第三屆常春藤論壇在北京召開
大會邀請了著名投資人王功權先生分享對年輕人創業的建議
以下為經過編輯的演講實錄。

人的一生,首先要趕上時代的潮流,趕上了就有很大贏的希望
回顧我自己的一生,幾乎每一次有所作為、有所突破,都是因為趕上了大時代中某個關鍵的機會
但年輕人去追趕大潮也有一個問題,就是定了大方向之後依然沒有辦法起步
比如移動互聯網、人工智能是大趨勢,這個人人都能看到
但對年輕人來說最重要的問題是:你能否在大趨勢中找到適合自己的奮鬥方向?

你一定要明白,自己是在什麼狀態下出來創業的,要做一件什麼事情
阿里巴巴上市之前一共拿了 95 億美金,京東拿了 20 億
但不是所有創業者都應該去追求這種規模非常大的創業
更多人創業最後做的其實是應該中型、甚至是小而精緻的企業

人一生的才華、資源、熱情一定要放在自己最感興趣的一件事上,這樣工作才不至於成為你的負擔
不至於企業走到半路要大幅調整方向,不至於在生命快要結束的時候感到後悔
創業者應該去把這件事情找到,如果它是一件規模很大的事情,那就去找大資本
如果不是一件大規模的事情,就去找相適應的團隊和資本

這個過程不應該是反過來的
比如因為大家都在做平台、做互聯網金融,都在拿大筆風投,你也去這麼做
如果你在做的事情不是一種快速成長的模式,即使拿到了一大筆風投,也注定會死亡的
就我這些年的經驗
由於拿的錢、找的團隊和項目本身不契合,而使企業陷入困境甚至死亡的案例至少佔到 30%
這只是保守估計

不同類型的項目,需要不同類型的團隊,拿不同類型的資金
並不是所有項目都需要常青藤畢業的豪華團隊,也並不是所有項目都適合拿風險投資

如果你拿到了風險投資,目標是快速成長到 IPO 階段,那麼創始人需要更加警醒
要注意在每個操作環節都必須規範經營,不能違規、變通,甚至偷稅漏稅,和特權結合
這些都有可能導致企業走向毀滅
這裡我說的不是道德問題,不是法律問題,而是企業的風險問題

曾經有一個創業者告訴我,某企業的老總要把一塊場地以很便宜的價格租給他
條件是在這家創業公司佔股
我馬上就很警覺的問:場地和股份分別是公司持有還是老闆持有?
答案果然不出所料:場地是公司的…

設定 Microsoft Edge 的預設檔案下載目錄

參考文章:How To Change Default Download Location In Microsoft Edge

欸,沒想到不是解Bug的時候也能發文譙Microsoft的瀏覽器
升Win10後可以看到 Win8不少愚蠢的設計被移除了,整體來說進步很多
但還是有新增一些愚蠢的地方,像是這個問題

當我進入Edge的進階設定後發現竟然沒有地方可以變更下載預設目錄
這個設定不出現在一般設定我覺得是很合理的作法
但是進階設定也沒有...WTF...不知道Edge預期的進階使用者是怎麼樣的程度

這個調整首先要打開Windows的Regedit
可以用快捷鍵 Win+R 或是直接用Win10的搜尋框,輸入Regedit後按Enter
啟用之後依著以下目錄搜尋就能找到Edge的登錄設定值
HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\Main

在這個目錄下新增字串值
數值名稱打上  Default Download Directory
數值資料填入你想設定的預設檔案下載目錄

儲存完後再開啟Edge測試看看,這樣應該就行了

Java 8 JavaScript Engine 引入 Java Class 的方法變更

Java 8 使用了新的JavaScript Engine "Nashorn"
使用上的一些方式跟過去不太一樣
在跑程式碼時發現了過去版本用來引入 Java class 的importClass、importPackage會跳Exception
看了 Open JDK的回報 ScriptEngine throws exception when evaluating importClass and importPackage
Nashorn 採用了不一樣的方式引入 Java class,如果要維持相容性
可以在 JavaScript Engine 建立後執行這段程式碼
try { engine.eval("try {load('nashorn:mozilla_compat.js');} catch (e) {}"); } catch (ScriptException e) {}
因為用try catch包起來,所以如果Rhino讀到這段丟 Exception 會被包起來
這樣 Nashorn 也可以執行過去跑在 Java 上的有引入 Java class 的 JavaScript Code了

至於 Nashorn 的正式引入 Java class 用法看到這篇文章會是

var BigDecimal = Java.type('java.math.BigDecimal');

function calculate(amount, percentage) {
   var result = new BigDecimal(amount).multiply(
      new BigDecimal(percentage)).divide(
         new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
   return result.toPlainString();
}

型別會作為一個物件產生,這樣也比較符合 JavaScript 中的做法

IE IFRAME 不儲存Cookie

參考文章: Cookie blocked/not saved in IFRAME in Internet Explorer

之前沒特別注意過這問題
前一陣子才發現開放給外部嵌入網頁使用的IFRAME元件在 IE 上居然不會有Session存在
以往使用 IFRAME 都是在自家產品內嵌入,使用上都沒碰過問題
這次客戶回報 IE 11的測試有這問題後才發現當網頁網域跟IFRAME網域不同時
IE 會要求提供IFRAME頁面提供 P3P 標籤,否則就不能存Cookie
也因為這個原因,連帶地使得 Session 也不能用了

P3P的相關議題在參考文章的那篇 stackoverflow 討論的滿詳細的
這是一個宣告自己不會蒐集使用者資料或諸如此類的隱私權宣告標籤
參考了許多文章得到的結論是,這是一個逐漸死亡的標準,Chrome跟Firefox都已經放棄了
他的問題包含
1. 不確定有實質法律效力
2. 很難有網站可以完全做到不蒐集使用者資料
    再說就算網站說一套做一套,使用者也得有能力證明網站有蒐集資料

結論是碰到這個問題最簡單的作法是在response中加入P3P header
至於實質效力? 看到一個有點酸的評論 Problem solved, and IE is happy :)
連 IE 11也有是比較讓我意外,希望 M$ 新的Edge可以不要再做這種沒實質效益的行為了

JavaScript 可變參數函式撰寫與其參數傳遞

用一個簡單的例子示範JavaScript的可變參數函數
function demo () { console.log(arguments); }
demo (1, 2 , 3 , 4);

// output
[1, 2, 3, 4]

可以從這邊得知 JavaScript 實際上是用類似陣列的方式處理傳入的參數
傳進去的所有參數會用 arguments 這個函式自身的變數儲存
即使函式撰寫時不註明會使用到的參數也不會影響

C++或Java的 Programmer 應該都很習慣 function overloading(method overloading)的使用
只要參數不同,就會是不同版本的函式
但是對 JavaScript 就不是如此
它會將同名的函式視作相同的物件,只是使用者傳入長度不一樣的陣列
function overloading的寫法在JavaScript會變成覆寫函式,算是初學者要注意的地方

JavaScript的arguments物件只要用陣列的一般處理方式就能接觸到所有參數
function demo2 () {
    for(var i = 0, max = arguments.length; i < max; i++){
   console.log(arguments[i]);
}
}

使用可變參數函式還可能碰到一個需求
怎麼樣將一個可變參數的函式傳遞到另一個可變參數函式呢?
function demo3 () {
    demo2.apply(this, arguments);
}
demo3(1, "test")

// output
1
test


這個是我覺得比較簡潔的方式
用JavaScript function 的 apply 機制讓它過程中套用到另一個函式

範例 - JavaScript 實作 Excel 頁籤移動元件

最近想調整之前做的在有限空間內的選單內容切換元件
參考的項目來源則是Excel的下方頁籤選擇器
Excel這類廣泛使用的軟體,設計都還滿值得參考的
一方面是Microsoft將它做得滿直覺的
另一方面則是一般大眾也被訓練到能接受它的操作流程

實作的成果如下:


點擊下一項時,選單容器會自動往右邊捲動一個不定長度的子元件的距離
長按著下一項按鈕不放,則會持續往右捲動到底

[轉載] 當心從10億估值淪落到一無所獲!創業者簽訂融資協議時該注意什麼?

個人心得:
從原文的回應看來似乎是某個美劇的劇透,這讓人有點興趣了XD
拿了投資人的錢就是要對他們負責
這並不是說不會從他們那邊得到協助
而是並不是投資人的每個要求都對公司有所幫助
也就是並不是有拿到投資就好的原因

原文網址:http://36kr.com/p/532911.html

本文編譯自Heidi Roizen的Blog
Heidi Roizen曾創辦自己的公司並管理了14年之久
後來她擔任蘋果公司負責開發者關係的高級副總裁
現在她是風投機構DFJ Venture的合夥人
在這篇文章,Heidi Roizen透過一個虛構故事,向創業者說明為什麼融資協議比公司的高估值要重要的多

用 Firebug 紀錄網頁 DOM 的所有事件

先說結論(?)
大致上有2種狀況你可能會需要查詢 DOM 被觸發的事件
1.瀏覽器行為變動使你的JavaScript運作不正確
   例如部分行為不再被觸發,或者是事件的優先順序被調整
2.你撰寫的JavaScript中會自行觸發 DOM 事件,而且有問題需要除錯
   例如自行觸發 onchange、onfocus等等

在這些情況下你可能很難判斷問題是由那些事件引發
特別是有部分事件是透過JavaScript引發而非一般輸入(鍵盤、滑鼠)引起的
最好的方式是紀錄該DOM元件中被觸發的所有事件,再依此判斷解決方式

我查過最好的處理方式應該還是透過Firefox的Firebug套件,省掉撰寫測試程式的工

上圖就是Firebug此功能的示意圖
你可以先透過Firebug的選取器選好這次要測試的DOM元件
選好後會看到被選取的原件會顯示為藍底反白
在該區塊按右鍵就會跳出圖片中的選單,選擇紀錄事件->你想紀錄的事件
之後再執行一次操作,就可以看到該元件有那些事件會在操作中被觸發

JavaScript 偵測輸入法(IME)狀態

相關參考文章:http://mdn.beonex.com/en/DOM/CompositionEvent.html

輸入法(Input Method Editor,以下全用IME代稱)的處理一直是我們漢字文化圈的麻煩之一
在前端滿常碰到客製化 key event 的需求
當客戶按了某個鍵或輸入某段文字後會執行我們自訂的程式
只是這樣的處理方式在輸入法啟用狀態滿常有例外

例如:選字時會用到上下移動鍵,刪除、或確定選字用到 Esc、Enter、Backspace
選字的時候我們會希望在這段時間的輸入不會影響原先的狀態

麻煩的點是這一段在瀏覽器的處理並沒有完整的規範
大概是其他國家沒什麼選字的需求,即使在HTML5規格接近定稿的時刻,IME在W3C依然是草案狀態
該草案推動者是在日本Google工作的日本人,顯得願意投入的資源並不多
也因此目前瀏覽器的實作略有不同,在輸入法狀態甚至有keyup event被吃掉等等的奇怪狀態
最後我找到的是下面這樣簡單的瀏覽器共通實作,起碼在近代的瀏覽器可以簡單的判斷輸入法狀態

document.addEventListener("compositionstart", function(){
    window.IMEStatus=1;
});
document.addEventListener("compositionend", function(){
    window.IMEStatus=2;
});

至少能夠判斷那些時候是在輸入法啟用狀態,避免執行不該啟動的程式碼

[轉載] 創業公司分配股權時,如何計算每個人的貢獻?

原文連結:http://www.36kr.com/p/220229.html

創始人合夥創業,有的提供資金,有的提供場地,有的提供技術能力,有的提供銷售渠道,有的提供融資資源
各個創始人提供不同的貢獻,各個貢獻性質不同,似乎完全無法等價對比
如果沒有明確的標準,很難說研發就比銷售更重要,也很難說拉來投資的工作就比提供辦公場的貢獻更重要
所以創始人之間如何分配股權,往往成為一個難題往往不得不用「拍腦袋」的方法劃分比例
這經常會導致埋下不滿的情緒,並在創業最艱難的時候爆發

有沒有一種方法,可以在同一維度上,量化創始人的各種貢獻呢?
如果能按一個統一的計算單位,量化各個創始人的不同貢獻
創始人分股權或許會稍稍科學客觀一些,至少能讓大家更信服、讓團隊更團結

Python Http Request 自訂範例

last update:2015/05/20

因為一些因素,又回來寫了一些 Python
Python 3 和 Python 2 就如同大家所知的是完全兩回事
只是這次有必要寫出一段可以相容的程式碼,所以在這部分花了一點工
查詢過很多範例,撰寫 Python 大多會推薦使用 Library

大概是因為我不是 Pythoner ,還是不喜歡完全使用無法控制的東西
所以下面就是用爛透的 Python 的原生 HTTP API 做的示範
純紀錄,沒有技術難度就是

收到未預期的重複 HTTP Request

參考文章:What happens when no response is received for a request?

最近碰上的一個問題是後端接收到重覆的 request
在前端的JavaScript留下的 log 也確認送出的 request 只有一個
那麼後端收到重複的 request 的原因反而令人困惑

其實這個問題的原因我在之前就聽過類似的例子
不過直到這次採到痛點才又回想起來
也多虧於此,沒花太多時間就克服了這個問題

根據 HTTP 1.1 RFC 8.2.4 的協定
If an HTTP/1.1 client sends a request which includes a request body, but which does not include an Expect request-header field with the “100-continue” expectation, and if the client is not directly connected to an HTTP/1.1 origin server, and if the client sees the connection close before receiving any status from the server, the client SHOULD retry the request.

也就是HTTP裡有著上述的規範
當 Server 接收了 request 後,理所當然的需要吐出 response
瀏覽器端使用了 Collision Avoidance 的規則
當超過一定時間沒有接收到 response 後,會自動重發 request
所以就會有 JavaScript 的 log 紀錄只有發出一個 request,但 Server 卻收到很多個的狀況

如果後端的頁面需要進行一項長時間的作業
就算你送出這個 request 後並不需要取得任何回應內容也一樣
考量到瀏覽器需要在一定時間內得到回應,那麼可以採取的方式有兩種
第一種就是強迫頁面 flush buffer,先吐些東西讓瀏覽器能接收
當然在這個狀況下,如何讓瀏覽器接收後續的內容就是另一個問題
第二種則是將需要進行長時間作業的部份另外開一個 Thread 進行

這不是常發生的狀況,但是發生後若不熟HT…

[轉載] 聯合創始人退出,他手裡的股權怎麼辦?

原文網址

編者按:創始人中途退出創業了,他手中的股權怎麼辦?這個問題經常困擾創業者
Dan Shapiro、Güimar Vaca Sittic和Simeon Simeonov的三篇文章介紹了從離職創始人手中收回股權的機制
本文編譯並彙總了該三文中的基本理念並參考了《合夥人股權的進入機制和退出機制》一文,整理如下

創業初期,創始團隊不穩定,經常會出現一種窘迫的局面:
股權分給創始人後,有的合夥人中途離開,但手中還持著公司股權
這種局面,常常會讓留守創業的合夥人們,憤憤不平又無可奈何

在 Dan Shapiro 的《聯合創始人股權分配:五五分是最糟糕的做法》一文中
作者 Dan Shapiro 簡單提及:聯合創始人的股權在任何情況下都需要設定成熟機制
這種創始人股權成熟機制,就是指從離職創始人手中收回股權的安排
原譯文中限於篇幅未刊載此點內容,本文將綜合此三篇文章,結合中國法律,初步介紹創始人股權成熟機制

Android Webview 使用 Basic Authentication 通訊

參考文章:
http://en.wikipedia.org/wiki/Basic_access_authentication

這篇沒有技術成分,當成聊聊 Basic Authentication 就好

Basic Authentication 的說明看英文的wiki會比較明顯,中文的wiki我反而看不懂...
作為早期開發的使用者身分認證交換機制
他的優點在於簡單,不需要cookie、session
只需要在瀏覽器送出的Request裡加入header即可,所有瀏覽器均支援此機制
缺點也很明顯,就是安全性不夠好
所以現在的網路身分認證基本上不會用這個方式進行
現在會看到他的場合大多是軟體服務商提供的 API 通訊

不少的公開API服務的進行方式會是:
進行使用者身分認證 -> 取得Token -> 用Token 進行 Basic Authentication,並進行API操作

服務商的Server端會根據Token判別使用者,並依此決定回傳的內容
在JavaScript添加 request header 的需求常見,所以做法好找也不多提了
之前開發 Android 程式時需要用webview
查了下發現做法非常簡單,loadUrl method有一個版本能傳入Header為第二個參數

HashMap<String, String> extraHeaders = new HashMap<String, String>();
traHeaders.put("Authorization", "Basic " + Token);
mWebView.loadUrl(url, extraHeaders);

這樣就是常見的API Token在Webview裡的使用方式囉