第一次開發選服就烙賽

Intro

自從邱威傑市民服務網站上線後,一直想要完成這篇,紀錄一下這一個月多月開發以來的心得感想,但因為專案完成,本身也剛換工作,無預警進入了懈怠期,不知不覺就拖到現在了

晚上和呱吉跟他的政治團隊吃飯,回家後提醒自己寫下紀錄,今天大概就能算是一個圓滿的結束點吧~

18.12.07 確定接下案子

在這之前,第一次和負責的團隊成員——很年輕的法律系學生 @Eddy 見面,一開始當然不知道呱吉會打算怎麼做這個系統,原本以為會有前輩主導開發,去參與討論或插花即可,但實際上是最多找2-3個人做;也以為是要做能讓多個議員註冊、使用的平台,但需求聽起來卻像呱吉個人的宣傳式網站

我認知到一件事,那就是 Eddy 沒辦法準確評估我的技術水準,只知道我有做過網站。令人訝異的是,當天握手之後就直接把任務交給我了。當然,這是風險評估出了問題呢,還是完全信任夥伴?我選擇相信後者。(團隊的風氣感覺是年輕人放手去做就對了,烙賽沒關係?)

專案需求雖然很簡單:使用者填寫表單、送出後可以在後台編輯。但我還是一樣超沒信心,因為認知到:

  • 我希望這是一個開源專案,如果要開源,會有資安上須考量的風險,加上呱吉是公眾人物,容易成為箭靶
  • 短期會有高流量,分散式部署是必要的;自己沒有實際維運過分散系統,大概知道是怎麼做,但沒把握
  • 重點是前端視覺與使用者體驗,但自己頂多做後端,前端雖然會寫,但根本在標準之下

Read More »第一次開發選服就烙賽

Classic Shell Scripting 讀書筆記 (三)

  • Devops

test 命令

  • POSIX 將 test 的參數描述為「表達式」:
    • 一元(unary)表達式:由看似一個選項(如-d)與相對應的運算數組成(基本上是一個文件名)
    • 二元(binary)表達式:兩個運算數與一個內嵌的運算元組成,做某種比較操作
  • test 命令有另一種形式 [ expression ],方括號與表達式一定要以空白隔開
  • 表達式可以前置 ! 表示否定

在 XSI 兼容的系統裡,-a 意義等同於 &&; 為了可移植性,建議使用多重條件而非 -a, -o

使用 test 的訣竅

  • 須有參數(避免 null),因此變量展開都要以引號括起來
  • 為了可移植最大化,可以替比較字符串加上前綴 X,例如 if [ "X$answer" = "Xyes" ],可以避免字符串為空或開頭帶減號而混淆 test 命令
  • test 是可以被愚弄的,例如 test -r a_file && cat_file,a_file 可能會在執行 test 與執行 cat 之間改變
  • 只能做整數測試

範例:檢查輸入參數

Read More »Classic Shell Scripting 讀書筆記 (三)

Classic Shell Scripting 讀書筆記(二)

  • Devops

排序文本 sort

locale 對排序的影響

重音位置不同的法文單字

查看字元在 ISO 的八進位數值

分別用傳統 ASCII 和 Canadian-French(系統必須先安裝法文)排序,結果不同

注意空白

-k 指定排序字段時

  • 如未以 -t 指定分隔符號,預設以空白分隔並忽略開頭與結尾的空白
  • 如果指定 -t,則開頭與結尾的空白不會被忽略,例如 ” -X- ” 以 -t " " 分隔,會被分成三個字段: 空白, “-X-” 及空白
  • 如果僅指定一個字段編號,意思是「從該字段開始,一直比對到行的結尾」
  • -k{n},{m} 格式代表「從第 n 個字段開始,至第 m 個字段結尾」
  • -k{n.i},{m.j} 格式代表「從第 n 個字段第 i 個字元開始,至第 m 個字段第 j 個字元結尾」

穩定性

紀錄內的排序字段都相同,但輸出與輸出不一致,代表 sort 並不穩定。GNU 實現了 coreutils 套件,可透過 --stable 彌補這個不足

排除重複

使用 -u 排除重複是基於 key 而非整筆紀錄,如果是後者,則可以搭配 uniq 工具使用

Read More »Classic Shell Scripting 讀書筆記(二)

Classic Shell Scripting 讀書筆記(一)

  • Devops

入門

printf

  • 格式聲明 (format specfications) 是一種佔位符號 (placeholder),結構包含 1) 百分比符號 (%) 2) 指示符 (specifier),常用的有字符串 %s 及十進位整數 %d

tr

範例:Translate DOS file to UNIX

  • tr -d: 自 stdin 刪除 source-char-list 的字符
  • \r: ASCII carriage return

/dev/tty

範例:Read password via /dev/tty

  • 當程序打開 /dev/tty 時,UNIX 會將它重定向到一個終端再與程序結合,該終端可以是 1)實體的 console 2) 串行端口 (serial port) 3) 偽終端 (pseudoterminal)
  • stty (set tty) 用來控制終端的設置,echo/-echo 選項用來開關自動打印輸入的功能

i18n and l10n

  • 當 i18n 作為設計軟體的過程時,無須再修改軟體或重新編譯程式代碼,就可以給特定的群體使用
  • 當 l10n 作為設計軟體的過程時,目的是讓特定的使用者可以使用軟體。其中包含翻譯輸出的文字、貨幣、日期、時間、單位等格式
  • 對使用者來說,用來控制讓哪種語言或文化環境生效的功能,叫做 locale
  • 除了 CPOSTFIX 以外,locale 名稱並未標準化
  • BSD 與 Mac OS X 完全不支援 locale
  • locale 的支援仍未成熟:Shell 腳本常受到 locale 影響;在大多數 UNIX 系統下,很難從 locale 文件與工具來判定字元集 (character class)、等價字元集 (equivalence class) 實際上包含了哪些字元,以及有哪些排序符號 (collating symbol) 可用。
  • Shell 腳本開發者應了解 locale 對他們代碼所造成的影響

列出所有 locales

取得特定 locale 的資訊

定義 LC_ALL 來覆寫預設的 locale,可查詢的變量有日期時間格式 LC_TIME、貨幣格式LC_MONETARY

Read More »Classic Shell Scripting 讀書筆記(一)

笑忘書

  • Quote

失去的信件

klement-gottwald-vladimír-clementis-vanish

人類對抗權力的鬥爭,就是記憶與遺忘的鬥爭。

憲法保障言論自由,話是沒錯,但是任何有可能被認定是危害國家安全的行為,都會遭到法律的制裁。沒有人知道,我們的國家什麼時候會跳起來厲聲指責說,這句話或哪句話危害到了國家的安全。

知識份子這個詞,在當時慣用的政治語彙裡屬於侮辱性的字眼,意思是說一個人缺乏現實感,跟人民拖了節。在那段時日裡,所有被共產黨員絞死的共產黨員,都曾經被安上這種羞辱。據說,知識份子和腳踏實地的人們不同,他們總是活在半空中,不知自己飄盪在何處。所以就某種意義上來說,跟他們雙腳永遠離開地面也是對的,就讓他們吊在那兒,跟地面保持一點距離也好。

智利總統阿言德的暗殺事件,很快就取代了俄國人入侵波希米亞在我們心中留下的記憶;孟加拉的血腥大屠殺讓人忘記了阿言德;西奈沙漠裡,以色列人和阿拉伯人的殺聲喧天,蓋過了孟加拉傳來的呻吟;柬埔寨大大小小的屠殺事件又讓人忘掉了西奈沙漠;依此類推,類推,再類推,最後每個人會將每件事都徹底遺忘。

在從前的日子裡,歷史還是緩慢前行的,為數不多的事件在人們的記憶裡悠然留下身影,交織成眾人熟悉的佈景。人們的生活就在這幅佈景前,展現著種種令人驚奇的事蹟,演出扣人心弦的戲劇。如今,時間卻踏著大步前進。歷史事件如朝露般一閃即逝,晨光降臨即被遺忘;歷史事件不再是敘事者的背景布幕,它本身就引人注目,它以人們再熟悉不過的庸碌生活為背景,演出一齣齣令人驚奇的事蹟

我再強調一次:牧歌,為所有的人。長久以來,人類總是嚮往著牧歌,嚮往這片夜鷹歌聲繚繞的田園,嚮往這個和諧的國度。在這個國度裡,人類不會遭到陌生世界的侵擾,人與人之間也不會扞格不入;相反地,世界和每一個人都是用同一種材料捏造出來的。在那裡,人人都是巴哈賦格曲裡反覆澎湃歌詠同一崇高主題的一棵音符,不想當音符的,就杵在那兒像個沒用的小黑點似的,毫無意義,只消輕輕拈來,用指甲一掐,小黑點就會像跳蚤一般,被捏得粉身碎骨。

他覺得自己對命運負有責任,但命運卻不覺得它對他有什麼責任。

歷史事件往往前仆後繼,相互模仿而了無心意。但我認為,人類的歷史卻在波希米亞完成了一場史無前例的試驗。這一次,歷史的進程不是依照古老的慣例,由一群人(一個階級,或是一個民族)起來反抗另一群人,而是有人(整個世代的男男女女)奮起造反,對抗自己的青春。

米瑞克的名字也給抹掉了。現在,雖然他踩著一階一階的樓梯走向芝丹娜的家門口,但實際上,他只是一塊污漬抹境之後殘留的白痕,一小片鑲著輪廓的空無,順著迴旋的樓梯向上走去。

他們會逼著他把自己的生命拋擲向遠方,讓自己化為暗影,成為一個沒有過去的人、一個沒有角色的演員,他們甚至會逼他把被人拋向遠方的生命和演員放棄的角色也一併化為暗影。非得如此將他的形體化為暗影,他們才要讓他活下去。

男孩把女孩從他的生命的相本中抹去,那並不是因為他不愛她,而是因為他愛過她。他把她抹掉,她的人以及他對她的愛,他刮落她的身影,直到消失為止,就像黨的宣傳部讓克雷蒙提斯從戈特瓦發表歷史演說的陽台上消失一樣。米瑞克改寫歷史的手法跟共產黨如出一轍,跟所有政黨也毫無二致,跟所有民族,跟全人類,都一樣。人們高聲疾呼,說要打造一個更美好的未來,其實是騙人的,未來不過是一片無足輕重的空白,任誰都不會有興趣,但是,過去卻充滿了活力,它的臉孔激怒我們,反抗我們,傷害我們,其為禍之深,直教人動念將它摧毀,或至少重繪它的面貌。人們想要主宰未來,其實只是為了能夠改變過去。人們相鬥相殘,就是爭著要進入那些神奇的暗房,去修整照片,改寫個人的傳記,甚至人類的歷史。

他們要把幾十萬人的生命從記憶中抹去,好讓無暇的田園牧歌永遠無暇。然而正是在這首牧歌裡,米瑞克要以自己的血肉之軀拋擲其間,橫灑一片污漬。他要一直待在那裡,就像克雷蒙提斯的氈帽一直留在戈特瓦的頭上一樣。

媽媽

這麼說吧:其實所有的愛情都是建立在一些不成文的公約上,那是戀人們還在熱戀的最初幾星期裡,未經深思熟慮就草草擬定的公約。那時戀人們還沈浸在夢裡,但這時候,他們其實已經不知不覺地扮演起難纏的法學家,開始逐條逐字編寫他們的愛情合約。噢!戀人們,開頭這幾個險惡的日子裡要當心哪!如果您幫別人把早餐端到床上,你就得一輩子幫他送早餐過去,否則您就會揹上讓愛情褪色與背叛的罪名。

沒錯,經歷這許多年,夫妻倆已經變成了雙胞胎,兩人用同樣的字彙,有同樣的想法,也擁有相同的命運。夫妻倆彼此都將艾娃當作禮物送給對方,讓對方快樂。夫妻倆都覺得自己在推石頭上山。夫妻倆都覺得倦了。

現在,他眼前浮現那全小城崗巒悠悠的景致,木雕的廊柱、一群群綿羊在山丘上的草原覓食、羊頸上的小鈴叮叮噹噹地晃著。他在腦海裡把娜拉赤裸的身體安插在這片鄉野景致之中(就像拼貼畫的作者在一幅畫裡貼上從另一幅畫剪下來的圖片),他腦中閃現一個想法:美,就是兩個不同的年代跨越了時光之炬,在相遇時迸濺激射的火花。美,就是對編年紀事的棄絕,就是對時間概念的反叛。

天使們

支配世界的權力,誠如我們所知,是由天使和惡魔分享的。然而,世上的善並不能保證天使就比魔鬼佔優勢(像我小時候所相信的那樣),事實上,兩者的權力差不多是平衡的。如果世界上有太多不容爭辯的意義(天使專權),人類就會被這些意義的重量壓垮。而如果世界失去所有的意義(魔鬼統治),人們也一樣活不下去。

笑帶有某種壞的成份(事物的呈現突然跟原本設想的不同),不過也有好的一面,它可以讓人得到紓解(事物變得比其外表來得輕逸,讓我們活得比較自由,事物也不再以其肅穆莊嚴的外表來壓迫我們)。

這世界上有兩種笑,而我們卻沒有詞彙來區辨他們。

最後,她希望至少能和她的學生們處於完全和諧的狀態,也就是說和他們成為一個整體,意思就是說,她要學生們永遠都得跟她有相同的想法、相同的說法,她要學生們跟她形同單一的身體、單一的靈魂,在相同的圈子裡跳著相同的舞步。

如果我們遠離的是一列行伍,或許還有歸隊的機會。但圓圈是封閉的,一旦脫離,斷難回頭。要知道,行星繞著圓周運行絕非偶然,一顆石頭脫離了行星,無可避免地會被離心力拋擲出去。

失去的信件

照我估計,每秒鐘都有兩、三個新的小說人物經歷受洗命名般的過程,來到人間。

這句『對,我也是這樣,我……』看似每種附和的回聲,好像要接續別人的想法,但其中卻有詐:事實上,這句話是一種以暴制暴的粗魯行徑,說話的人粗魯地把自己受奴役的耳朵拯救出來,同時迫使對手的耳朵成為階下囚。人們沉浮在跟自己相似的人群裡,而人生也不過是一場征服他人耳朵的戰爭。

『小說是人類錯覺的結晶,一種自以為可以了解他人的錯覺。』

普遍的疏離引發了寫作狂,而普遍的寫作狂又強化了疏離。過去,印刷術的發明讓人們得以相互瞭解。然而值此寫作狂遍地可見的年代,寫書這回事的意義卻大異其趣:人人都被困在自己的言詞裡,像被大片鑲著鏡子的牆壁所圍繞,任何外界的聲音都無法穿透。

寫書的人,要嘛化身為全部(一個獨特的世界——為他,也為所有人而創的世界),要嘛就是個零。由於沒有人能夠化身為『全部』,所以我們這些寫書的,每個人都是『零』。我們被人看輕,我們善妒又尖刻,我們恨不得別人都去死。

不論政客或是計程車司機、產婦還是情婦,也不論殺手、小偷、妓女、警察局長、醫生還是病人,各行各業裡,寫作狂的激增說明了一件事:人類無一例外,皆有成為作家的潛能,因此大家都可以理直氣壯地跑到街上大喊:我們都是作家!這是因為大家都害怕自己會隱沒在一個無關輕重的世界裡,沒人聽,沒人理,所以要趁著還來得及的時候,把自己轉化成一個世界,一個用話語堆砌而成的世界。

總有一天(這一天也不遠了),每個人都會發現自己是作家,當這一天來臨的時候,人類就會進入一個全面聾聵、全面誤解的年代。

行過死蔭之地

  • Quote

「牢中生活不見得能感化他們,但肯定會加強他們的犯罪技巧。」

人生啊!曾有人說過,對於那些靠思考過日子的人像是一齣喜劇,對於那些憑感覺過日子的來說卻是一場悲劇。對我而言,無論怎麼過日子都是有喜有悲,即使你什麼都不做也逃不掉。

深入理解 Nginx 讀書筆記 (第二章)

進程間的關係

  • Nginx 支持僅單進程(master)提供服務
  • 常態的部署是使用一個 master 進程來管理多個 worker 進程
  • Worker 數量與 CPU 核心數相等,進程切換代價最小

使用多進程的好處

  1. master 進程僅專注於純管理工作,為管理員提供命令行服務(啟動、停止、重配置、升級)
  2. master 進程需要比較大的權限,通常會以 root 使用者啟動
  3. 一個 worker 進程出錯後,其他 worker 仍然可以正常服務
  4. 充分利用 SMP(Symmetric multiprocessing) 多核架構,實現微觀上真正的多核併發處理
  5. Worker 通常不會進入睡眠狀態:可以同時處理多個請求,不像 Apache 每個進程只能同時處理一個請求,以致進程切換代價大

配置語法

每個模組都有自己感興趣的配置項,大部分模組都必須在 nginx.conf 中讀取到某個配置後才會啟用,例如只有當配置 http {…} 時, ngx_http_module 模組才會啟用,其他依賴的模組也才能正常使用

區塊配置項

  • 由名稱及一對大括號組成,如 http, server, location 都屬於區塊配置項
  • 傳入的參數取決於解析這個區塊配置項的模組
  • 大括號表示包含其中的配置同時生效
  • 可以嵌套,內層配置直接繼承外層
  • 當內外層配置發生衝突,以哪層配置為準,取決於解析這個區塊配置項的模組,例如範例的 gzip 開關

配置項語法格式

  • 名稱必須合法的(是某個 Nginx 模組想要處理的)
  • 傳入的參數取決於解析這個區塊配置項的模組
  • 若任一參數包含空格符,須要用單引號或雙引號包住
  • 以分號結尾

Read More »深入理解 Nginx 讀書筆記 (第二章)