Refactoring English: Month 1

Michael Lynch

《Refactoring English》:第一個月

原文由 Michael Lynch 發布,訂閱此部落格

一句話總結

我發表了新書的第一章。

重點回顧

  • 我發表了新書的第一章,對迴響感到滿意。
  • 嘗試聘請封面設計師以失敗告終。
  • 我可能找到了讓 PicoShare 支援大檔案的方法。

目標評分

每個月月初,我都會訂下當月想完成的目標。以下是這個月的達成狀況:

完成《Refactoring English》兩章

  • 結果:完成一章,下一章完成了 75%。
  • 評分:B

第一章花的時間比預期久,因為我一直發現想重寫的地方。不過我發現先休息一週去寫第二章,再回頭看會有幫助,能以全新的眼光重新審視。

與設計師合作完成《Refactoring English》的封面設計

  • 結果:決定自己做封面設計。
  • 評分:C

和設計師合作到一半,但因為不喜歡設計方向,我就喊停了。決定先自己做封面。

關於完成《Refactoring English》第一章的一些想法

我發表了新書《Refactoring English》的第一章,標題是〈Rules for Writing Software Tutorials〉,內容是基於多年來閱讀各種教學、觀察它們做得好與不好的地方所累積的心得。

第一章獲得不錯的迴響

這一章的迴響落在我預期的高標。以教學規則清單來說,我本來沒指望會爆紅,但在幾個我認為合適的網站上都得到了不錯的回應:

我主要追蹤的指標是電子報訂閱人數。文章發表後一週內新增了 245 位訂閱者,讓這本書的總訂閱數成長了 31%。

第一章讓本書電子報的訂閱人數大幅成長。

發表後,該怎麼迭代修改文章?

幾年前,Redis 的創造者Salvatore Sanfilippo暫停了程式開發工作,轉而寫了一本科幻小說。在寫小說的過程中,他觀察到

我認為寫作和程式設計最鮮明的差異在於,小說一旦寫完、編輯、定稿,大致上就定版不變了。

Salvatore 接著說,程式設計師應該向小說家學習,克制在應用程式完成後重寫核心邏輯的衝動。但我反而得到相反的啟示:作者應該像程式設計師那樣,用更迭代的方式來寫書。

對於《Refactoring English》,我試著以接近完稿的狀態發表各章節,但也希望讀者的回饋能影響我的寫作。

讓章節內容保持浮動帶來了一個我從未遇過的問題:我把留言串搞亂了。在 Hacker News、Lobste.rs 和 Reddit 上,留言者對我關於「讓電腦來判斷條件邏輯」的觀點提出異議。而我覺得他們說得對。那是我最薄弱的論點,所以我已經把它刪掉了。

問題在於,之後再去看那些討論的人,會納悶為什麼大家在反對一個文章裡根本沒出現的觀點。

目前我想得到最好的解決辦法,是在文末加上一則說明,表示本書仍在修訂中,並附上原始版本的連結與重要修改清單。

如何持續找到願意提供回饋的讀者?

到目前為止,我覺得根據讀者回饋來迭代的計畫是可行的。

我對第一章發表的內容感到滿意,同時也收到了許多讀者深思熟慮的批評,這些都將有助於我修訂內容。

我本來想:「好,那我可以繼續把預覽章節分享到同樣的管道。」

但接著我檢視了目錄,才發現其他章節都不適合發在當初分享第一章的那些管道。那些網站大多有明文或不成文的規定:「文章裡沒有程式碼,就不該發在這裡。」舉例來說,/r/programming 大概不會對我那篇痛陳為何討厭被動語態的章節感到興奮。

我想到一個點子:為其他作者做自由接案的編輯,並把經驗回饋到《Refactoring English》中。

不過我覺得「編輯」並不完全是我擅長的事。大家聽到「編輯」,會以為我要幫他們潤飾文字。但我真正想做的是找出他們寫作中的問題,並說明相關的原則與技巧,幫助他們自己改進。我不知道該怎麼稱呼這種角色。寫作指導?教練?

無論如何,如果你對此感興趣,歡迎與我聯繫。我可以協助部落格文章、文件,或任何與軟體相關的寫作。我能教你如何吸引更多讀者、讓文章更引人入勝。基本上,如果你喜歡我在這個部落格的寫作風格,我可以把我在這裡使用的技巧教給你。

  • 兩輪審閱收費 100 美元。
    • 費用包含我審閱你的初稿,以及根據我的回饋修改後的再審閱。
  • 文章長度最多 2,500 字。
  • 收費主要是讓你更有投入感,如果 100 美元超出你的預算,或許我們還是可以商量。

透過 Reedsy 聘請封面設計師的不愉快經驗

11 月我在寫書時分心去說服自己需要一個專業設計的封面。我在 11 月展開這個流程,但實際作業是在 12 月進行的。

我透過 Reedsy 找到設計師,這是在Write Useful Books 社群中好幾個人推薦的平台。普遍的評價是價格偏高,但值得。

我寫了一份設計需求說明,說明我想要什麼,並寄給 Reedsy 上的四位設計師。我列出的預算是 350 至 650 美元。一位設計師的報價比我的上限高出 20%,回覆也很制式,只說「當然,我可以幫你做」,完全看不出有讀過我的需求說明。另一位以預算太低為由婉拒,還有一位則完全沒有回應。

唯一有效的報價來自 Gary,他提出以 350 英鎊(約 434 美元)製作封面。他回了一封用心的訊息,提到了我需求說明中的細節,他的作品集有數十個書籍封面,而且在 Reedsy 上有完美的 5.0 分評價。他提出為期一個月的時程,費用分三期支付。我覺得沒問題,就聘用了他。

與 Gary 合作的過程

過了一週,我都沒收到 Gary 的消息。在第一期款項被自動扣款後,我詢問初稿的預計完成時間。Gary 說隔天會寄來初稿概念,隔天他也真的寄了。

透過 Reedsy 聘請的設計師提供的初期封面構想

範例 1 看起來不錯,但幾乎是照抄Beautiful Code,而這本書我曾在需求說明中引用過。其他範例則讓我覺得平淡乏味,但我把原因歸咎於自己沒有在需求說明上多花點時間。

在檢視這些構想時,我意識到自己最想傳達的是「細心、審慎的工作」這個概念。我覺得禪意庭園的範例 6 和黏土模具的範例 5 方向正確,所以請他進一步發展這兩個方向。我建議可以用雕刻家刻石頭的意象。

又過了一週,Gary 寄來了禪意庭園概念的微小變化版。他也嘗試了雕刻家的概念,放了一張鑿子和原石的照片。但照片中的石頭完全沒有雕刻的痕跡,所以無法呈現細心創作的感覺。

接下來那週是聖誕節,我開始擔心專案無法在 12 月 30 日的截止日前完成。Gary 在聖誕節前的週一寄信給我,說他會在 12 月 27 日回來工作,所以時程仍在軌道上。

到了 27 日下班前,我還是沒收到 Gary 的消息,才意識到自己有點進退兩難。

對我而言是美東時間週五下午 4 點,但 Gary 在英國,他的上班時間早就結束了。Reedsy 將在週一美東時間中午自動向我收費。而 Reedsy 允許對帳單提出爭議的最後期限是扣款前 24 小時,所以我已經沒有任何工作天可以拿到成品了。

我請 Reedsy 客服將我的最後一期付款延後一週,因為 Gary 還沒交件。Reedsy 卻叫我直接跟 Gary 協商。我解釋如果等到下一個工作天才收到 Gary 的回覆,就來不及異動付款了。但 Reedsy 客服仍堅持要我先試著跟 Gary 解決。

我在美東時間週五下午 5 點寫信給 Gary,他回覆說自己不是朝九晚五的「上班族作息」,所以打算週末趕工,專案仍可如期完成。他出於禮貌幫我延後了付款,但似乎對我向 Reedsy 抱怨感到不悅。

相反地,我則是盡量維持正常工時,並不想把週末花在陪 Gary 趕工上。到了週一我再去查看時,Gary 已經寄來兩個概念的更新版本,但兩者都很平庸。一個明顯是用 AI 生成的,看起來很不真實;另一個則完全沒有捕捉到我想要的氛圍。

我問 Gary 這些圖片是否為 AI 生成,以及是否符合我在需求說明中規定的授權要求。他開始支吾其詞,於是我提出取消專案。我表示如果他同意取消最後一期付款並終止專案,我已支付的 231 英鎊(約 287 美元)就歸他。他同意了,事情就此結束。

我給 Gary 的各項評價都是 3 顆星。我不覺得他很糟,只是表現平平,而且在時程溝通上做得很差。我的評價是公開的,但 Reedsy 仍顯示 Gary 擁有完美的 5.0 分,即使我給了他 3.0 分,而他總共也只有另外四則評價。

儘管我給 Gary 3 顆星的評價,他在五則評價下仍顯示完美的 5.0 分。

自己動手做的封面

Gary 退出後,我決定自己試著做封面。我在 Unsplash 上找到一張免費授權的圖片,很能呈現寧靜、細緻工作的氛圍,再加上文字就完成了。

我知道看起來有點業餘,但滿意度大概有我原本期待 Gary 成品的八成。而且這是免費的,只花了我一小時。我把它當作暫時的替代方案,之後隨時可以再請人設計或投入更多時間。

支線專案

讓 PicoShare 支援大檔案

PicoShare 是我幾年前開發的一款極簡、易於自行架設的檔案分享網頁應用程式,我每週都會使用它。

讓我對 PicoShare 有點慚愧的是,它在大檔案的處理上擴展性很差。在一台共享 CPU、256 MB 記憶體的虛擬機器上,PicoShare 處理 1 GB 以內的檔案表現很好。但如果嘗試上傳超過 1 GB 的檔案,PicoShare 通常會耗盡記憶體而當掉。你可以靠堆硬體來解決,但如果 PicoShare 能支援任意大小的檔案上傳當然更好。

我已經深入研究這個問題好幾次,強烈懷疑效能問題是因為 PicoShare 把所有檔案資料都存在 SQLite 裡。這是個不常見的選擇,但好處是 SQLite 的資料就能完整保存應用程式的狀態,包括檔案本身。所以我推測實際發生的情況是,PicoShare 試圖寫入大量資料到 SQLite,耗盡記憶體而當掉。

我一直很好奇是否能使用SQLite 的串流 I/O API,因為它們看起來能讓我更有效率地寫入資料庫。但 PicoShare 是用 Go 寫的,而我當時使用的 Go SQLite 驅動程式並不支援串流 I/O API。

幸好,Nuno Cruces 發布了一個支援串流 I/O 的全新 Go SQLite 驅動程式,而且他主動提出要幫我把 PicoShare 移植到他的函式庫上。我在 9 月和他合作了一小段時間,也取得了一些進展,但我們發現即使使用串流 I/O,PicoShare 在處理大檔案時仍會耗盡記憶體。

Nuno 建議如果把檔案切成多個區塊再寫入 SQLite,或許能降低記憶體用量。其實我目前的實作已經是這樣做了,但串流 I/O 不同的語意意味著我得重寫大量細膩的程式碼。所以當時我就沒動力繼續,把這項工作擱置了。

12 月,我以全新的眼光重新審視串流 I/O 的問題。我發現分塊寫入的問題比我想的簡單。PicoShare 是在寫入大檔案時耗盡記憶體,而不是在讀取時。所以我只需要用更有效率的串流 API 重新實作寫入那一端的邏輯就好。

事實證明,用串流 I/O 分塊寫入檔案,比我用 SQLite 預設 API 實作的方式更簡單。我一開始以為最簡單的做法是用io.Writer 物件來抽象化 SQLite 資料庫,然後讓 io.Copy 把資料倒進去。但這次我發現,直接執行所有寫入而不透過 io.Copy 反而更簡單。

串流 I/O 版本在我有限的測試中表現穩定,但仍需更廣泛的測試。目前的障礙是我家裡的上傳速度非常慢,所以我一直在想辦法在 fly.io 上跑一個桌上型作業系統,讓我可以透過 VNC 遠端存取。

總結

完成了哪些事?

學到的教訓

  • 聘請平面設計師的心得
    • 在聘請專業人士之前,先考慮自己做個暫時的版本。
    • 讓付款與專案里程碑掛鉤,而不是日期。
    • 明確說明是否接受設計師使用 AI 生成圖片或 AI 輔助合成。
    • 明確要求查看第三方素材(如照片或字型)的授權資訊。
      • 我在需求說明中有提到所有素材都必須具備相容的授權。
      • 更好的做法是要求承包商必須交付授權資訊,而不只是口頭保證素材符合授權規範。
    • 不要安排在聖誕節剛結束就截止的專案。
    • Reedsy 的機制明顯偏向承包商而非客戶。

下個月的目標

  • 發表 2024 年的年度回顧部落格文章。
  • 完成書中的另一個章節。
  • 根據讀者回饋修訂教學章節。

需要協助的事

  • 如果你有興趣聘請我協助寫作,歡迎與我聯繫

本文章由 muse-spark-1.2-contributor 進行翻譯

留言