寫喺舊金山(一)——咁耐搞過乜


又一篇標題同內文唔相符嘅文

更新下小弟嘅近況啦下

話說自上次更新個 blog 以來,已經差唔多一年 lu,半荒棄狀態嘅 blog 再唔更新就會好似再鋒利嘅刀一樣生鏽喔~~

話說自上次喺陳舊嘅金山做了三個月的廉價實習生後,輾轉之間又回到了陳舊的金山工作喔。期間都食過幾家茶飯,“真係學到好多野”、先知讀書真係好幸福喔~

第一份工——一間可以唔使用keyboard 打 code 嘅公司

呢間係第一份返黎做嘅 part-time,公司人手極度短缺——一個人負責全部 backend、一個負責 front-end + android、一個負責 iOS 全盤開發、一個 project man,另外加三個 CEO 級別嘅阿頭。呢個格局係典型嘅 startup 格局,但係越滾越多客,仲要分佈亞太區,都係得3 嘅阿頭,好自然唔係太清楚下面嘅 programmer 開發困難,結果工時越來越長,曾經嘅馬拉松跑手都好似有左幾個月身幾咁(不過我有一個月了 T.T);或者可能太難請人跟,因為真係好難跟⋯⋯

因為佢哋有好多個網頁 template比唔同 client 用,由因為好多客,所以有超過 5x 幾個 template,但問題係個個 template其實差唔多樣,所以有一大堆 html 都係一模一樣,如果要更新的話,就要每個都要更新。莫講話 git diff 會慘不忍睹,改都改到噴腦漿。

好彩個老細都知咩事,就叫我整個 template generator,用 react.js gen 噻堆 template,結果因為整合舊有 template 有難度,加上耗時太長,結果做到一半就結束了。不過小弟自問已經盡我所能都整唔到 “css regions + jquery content" (Google 一下,可以話係無個 work)。

或說有次公司打算買新 keyboard 同 mouse ,問同事有咩想要,結果居然有人話唔使買 keyboard 啦,反正平時都淨係用 mouse copy & paste D code。呢句話真係 sad but true,5x 幾個 templates 真係日日都 copy & paste D code 😂。

個人感覺公司文化都太 chur 了,搞到個個同事都無時間打牙骹,一個星期返五日,計埋都40個鐘,咁嘅環境真係好悶,而且無得一齊進步,交流 best practice。公司嘅唯一娛樂,就係⋯⋯,好似無⋯⋯我感覺自己係零⋯⋯。唯一嘅娛樂喺自己比自己嘅娛樂,自我陶醉,算唔算~

第二份工——真係有 startup feel,而且一齊奮鬥嘅感覺

有一種工,你係自願加班、即使,因為返工嘅感覺同喺中學同成班 friend 做 project 嘅一樣。有無諗過返工係可以有無限量零食供應、成班同事咩水都吹得、仲要有一大堆 intern 差唔多年紀,再重重點!有超噻班嘅 senior engineer 帶住,係一班一有問題就可以問,幾秒鐘就可以好 make sense 咁答倒你問題嘅超勁programmer。

公司有一個好重要嘅原則,就是一定要 best practice,係一定!!!不過所謂 best practice 都只係一個 term,只要 future + proof + readable + efficient + … 就係 best practice。係呢方面最有經驗嘅都係大佬們喔~

同埋好幸運地!好重視 team lunch,而且每餐都一齊食。呢段時間係好重要,因為係陳舊金山做野果陣就試過餐餐自己食,真係悶到痴線;不過今次決定左要自己煮就好好多,起碼食飯都仲有同事入廚房吹下水,而且好多時同事都係自己整沙律,或者直接嗌外賣。

打到斷唔倒味,下次正式入正題,係陳舊金山痛上次嘅體驗幾唔同,而且第一次喺呢度參加 Hackathon~

【秒懂】用 Javascript 做 Routing——讓 Single-page webapp 不用 Hashbang (#!) 也能瀏覽


  _     _             _ ____    ____             _   _             
 | |__ | |_ _ __ ___ | | ___|  |  _ \ ___  _   _| |_(_)_ __   __ _ 
 | '_ \| __| '_ ` _ \| |___ \  | |_) / _ \| | | | __| | '_ \ / _` |
 | | | | |_| | | | | | |___) | |  _ < (_) | |_| | |_| | | | | (_| |
 |_| |_|\__|_| |_| |_|_|____/  |_| \_\___/ \__,_|\__|_|_| |_|\__, |
                                                             |___/

【簡介】

做 Single-page webapp 最大的問題就是不能像普通鏈接一樣:

所以,現在要做的是:

  1. 讓網頁的內容能透過 (e.g.) http://www.example.com/webapp/login 來分享
  2. 讓【上一頁】按鈕能運作,真的返回先前的狀態

但,要注意的是:

  1. 網頁一定要透過 Javascript 才能執行
    • 如果要照顧沒有 Javascript 的瀏覽器用戶,只能把整個網頁用 Server-side programme 重寫
  2. 不支援HTML5 的瀏覽器,也可以瀏覽網頁,但
    • 網址還是會有 #!
    • 不能使用【上一頁】、【下一頁】的按鈕

【事前功夫】

  1. 要有已經設定好的 Server:以下的教學會分別說明 Apache 跟 Nginx
  2. 為了簡化內容(還有小弟的技術不足, haha),以下內容用上 Javascript Framework  (e.g.)AngularJS,EmberJS,BareboneJS
    • 在這裡,會以 AngularJS 為目標
  3. 支援 html5 的瀏覽器,尤其是支援 【History.pushState】

【秒懂步驟~開始】

下面的教學,會以一下的設置做背景

  • Server: Apache/ Nginx
  • Website Path: /webapp/exampleApp/
  • 所以內部瀏覽的網址是: 127.0.0.1/webapp/exampleApp

以下內容將會一氣呵成,需要解釋的可以再留言區問~

Read More »

SHTML && Javascript (AJAX) && PHP


SHTML——這看起來很古老的 (Apache 1.3 的官方Tutorial 已經收錄了,應該很有歷史吧),個人認為就是AJAX 的前身。根據維基百科的定義

Server Side Includes (SSI) is a simple interpreted server-side scripting language used almost exclusively for the Web.

The most frequent use of SSI is to include the contents of one or more files into a web page on a web server.

SSI 就是為網頁提供非常基本的 Server 跟 Client 的 Interaction。

(Oreilly)
(Oreilly)

一句話定義

就是 Server 在傳送 網頁 到 Client Side 前,先把 shtml 的相關Script 編譯、把結果加到網頁,然後整張網頁內容輸出。

把時間印到網頁上

  1. 如果看的網頁是 html——用AJAX的方式,從 Client 的瀏覽器召喚一段 CGI 的程序,然後從 Server 傳送回 Client。比如說要 Server 的現在時間,就可用以下 PHP Code:
    <?php
        ...
        $now = new DateTime();
        echo $now->format('Y-m-d H:i:s');
    ?>

    然後在Client 的瀏覽器,用Javascipt 收取現在的時間資料,再編譯到網頁上。

  2. 如果直接用 php 網頁——直接就 echo 出去了。
  3. 如果用SHTML——
    (HTML Comment Begin)#config timefmt="%A %B %d, %Y" (HTML Comment End)
    
    Today is(HTML Comment Begin)#echo var="DATE_LOCAL" (HTML Comment End)
    

這樣的代碼,在 Server 的運作過程是這樣的: Server 先讀取 .shtml 這檔案 –> 解讀 “ 融合到 .shtml –> 傳給 Client 的瀏覽器

把通用的網頁合併到不同的網頁 (e.g. header, footer, navbar)

個人認為這個作用比較大,但對於 Server-side 和 Client-side 的負載 vs. 把 header 的 code 放到所有網頁,所以實際應用還是不大。

用一下 shtml 代碼解釋一下:

<!--#include virtual="/footer.html" -->
<!--#include file="/header.html" -->

(用 “virtual" 或者 “file" 效果都是一樣的,但 “virtual"  的可以用 absolute path,而 “file" 不可以)

  1. 跟Javascript 比較——
    • (v) 沒有開啟 Javascript 的瀏覽器都可以編譯內容,雖然現在所有瀏覽器都有開啟 javascript
    • (x) 一旦載入了網頁,如果要變更內容,還是需要 javascript
    • (~) 倒不如直接把 header, footer 的代碼寫入網頁
  2. 跟php 比較——
    • (x) 雖然 Server 要編譯的代碼很少,不需要 “echo",但相對 php,Server workload 應該沒分別的

初步探究,還是用回 javascript/ cgi 算了~

跟 Javascript || PHP 相比,shtml 實在是太陽春了,畢竟當年還未有成熟的 AJAX 技術,所以在當時可能就會用到,但現在已經銷聲匿跡了(很多網頁還有 .shtml 的網頁,但相關的教學極其稀有)。

閱讀更多

  1. Apache Tutorial: Introduction to Server Side Includes
  2. Washington University – An SHTML sample
  3. SSI-Developer.net – SSI Tutorials, Server Side Includes

[Performance] Memory allocation and array structure


In most of the modern programming language I have learnt, such as C++ and Python, as well as Javascript, the memory allocation for array data structure is like this:

/* (e.g.) */ var a = [["a", "b", 'c"], [1, 2, 3], ["甲", "乙", "丙"]] //Java-script
// /* Memory allocation in order  */ "a" -->  'b" --> "c" --> 1 --> 2 --> 3 --> "甲" --> "乙" --> "丙"

Little thought

Suppose I am gonna store the following sets of data into an array, what’s the most best way to make it accessible most efficiently?

Name No Index
Peter

1

0

Mary

5

1

Lily

30

2

Jonathan 

25

3

Given that the items can be accessed by knowing the index, I have thought of 2 ways of storage

Method 1: The traditional way

var data = [["Peter", 1], ["Mary", 5], ["Lily", 30], ["Jonathan", 25]];
// /* Memory storage: */ "Peter" --> 1 --> "Mary" --> 5 --> "Lily" --> 30 --> "Jonathan" --> 25

This way is very clear and easy to understand, but may not be quite efficient to access the {No} of each element. For instance, the computer has to read pass all {Name}s of each item, and the memory access footprint is long.

Method 2: The “Split" way

var data = [["Peter", "Mary", "Lily", "Jonathan"], [1, 5, 30, 25]];
// /* Memory storage: */ "Peter" --> "Mary" --> "Lily" --> "Jonathan" --> 1 --> 5 --> 30 --> 25

To loop through all {No}s of all data items, just loop within data[1], and the memory access footprint is limited to number of data items.

To access {Name}s and {No}s, just need data[0][x] and data[1][x], where “x" is the index of the item.

There may be a problem associated with this kind of array structure, such as deleting a datum element, it has to loop through different parts of the data (can be understood as “columns" of data in a table). Nonetheless, for storing rare-updated data, I prefer the “split" way.