Indie Hackes 是個放各種「成功案例」的網站：
Indie Hackers is a place where the founders of profitable businesses and side projects can share their stories transparently, and where entrepreneurs can come to read and learn from those examples. It's also a community where individual "indie hackers" can come together to share their experiences, give and receive feedback, and rely on one another for support.
而文章的作者把上面的文章拿出來分析，得到了一些有趣的資訊：「Reverse Engineering A Successful Lifestyle Business: Here’s Everything I’ve Learned From Reading IndieHackers.com」。
The 4-Hour Workweek by Tim Ferriss (5x)
The Hard Thing About Hard Things by Ben Horowitz (5x)
Zero to One by Peter Thiel (4x)
The Lean Startup by Eric Ries (4x)
Four Steps to the Epiphany by Steve Blank (3x)
Steve Jobs by Walter Isaacson (2x)
High Output Management by Andy Groove of Intel (2x)
Good to Great by Jim Collins (2x)
Traction by Gabriel Weinberg and Justin Mares (2x)
Built to Sell by John Warrillow (2x)
The Personal MBA by Josh Kaufman (2x)
Start Small, Stay Small by Rob Walling (2x)
The Power Of The Subconscious Mind by Joseph Murphy (2x)
On Raising Prices (19x)
This was the most common advice. The easiest way to increase revenue: raise your prices! Don’t be scared to ask for money.
Real Artists Ship (9x)
Our first idea is a grand opening, a big launch, a press release, or major media coverage. We default to thinking we need an advertising budget. Our delusion is that we should be Transformers and not The Blair Witch Project. – Ryan Holiday
Start Charging Straight Away (8x)
The code owners feature was inspired by Chromium's use of OWNERS files.
To specify code owners, create a file named CODEOWNERS in the repository's root directory (or in .github/ if you prefer) with the following format[.]
這樣一來，在 pull request 的時候就會跳出來：
另外也可以設定需要 code owner 同意才能 merge：
列了 Pros (一行) 跟 Cons (超長 XDDD)：
- We end up with tests that verify the behavior of the code and help prevent regressions
這個是 TDD 的目的。而 Cons：
- It takes us longer to write code using TDD
- The tests get in the way. Because my design does not have low coupling, I end up with tests that also do not have low coupling. This means that if I change the behavior of how class
works, I often have to fix tests for other classes.
- Because I don’t have low coupling, I need to use mocks or other tests doubles often. Tests are good to the extent that the tests use the code in precisely the same way the real system uses the code. As soon as I introduce mocks, I now have a test that only works as long as that mock faithfully matches the behavior of the real system. If I have lots of mocks – and since I don’t have low coupling, I need lots of mocks – then I’m going to have cases where the behavior does not match. This will either show up as a broken test, or a missed regression.
- Design on the fly is a learned skill. If you don’t have the refactoring skills to drive it, it is possible that the design you reach through TDD is going to be worse than if you spent 15 minutes doing up-front design.
這四個問題講的是時間與能力兩個因子的作用，轉一個角度來討論其實是：如果 junior engineer 可以寫出好的測試，他們就不叫 junior engineer 了... 而 senior engineer 是稀缺資源，讓他們多花時間寫出「好的測試」未必是划算的。
反而是另外一種常見的方式常常跟 TDD 在對抗：透過 QA team 在完成後測試，尤其是用手動測試的 QA team XDDD
這個方法很簡單，而且行之有年。而且很無奈的，跟一般軟體工程所期望的相反，junior engineer 就可以做的不錯，所以人力的部份相當好 scale，而品質也有不錯的水準 (畢竟是直接測實際的功能了)。
剛好前陣子有提到另外一篇論文也在討論 TDD 的效果 (參考「又一篇戰文：討論 TDD 的過程」這邊)，也有類似的反思。
前陣子在 Twitter 上看到這則也是很有趣，拿來當結尾 XDDD：
爛 code 在經過長時間的演化之後，就會變成穩定的爛 code：不只爛，而且比任何試圖改進的版本穩定。
— Shiao-An Yuan (@shiaoanyuan) February 22, 2016
論文本身在「A Dissection of the Test-Driven Development Process: Does It Really Matter to Test-First or to Test-Last?」這邊可以下載，是去年 2016 就發出來的論文。
論文拆解 TDD 的行為，分析到底是哪些階段才是有正面幫助的：
Background: Test-driven development (TDD) is a technique that repeats short coding cycles interleaved with testing. The developer first writes a unit test for the desired functionality, followed by the necessary production code, and refactors the code. Many empirical studies neglect unique process characteristics related to TDD iterative nature. Aim: We formulate four process characteristic: sequencing, granularity, uniformity, and refactoring effort. We investigate how these characteristics impact quality and productivity in TDD and related variations. Method: We analyzed 82 data points collected from 39 professionals, each capturing the process used while performing a specific development task. We built regression models to assess the impact of process characteristics on quality and productivity. Quality was measured by functional correctness.
比較特別的是作者指出 refactoring 的負面效果：
Result: Quality and productivity improvements were primarily positively associated with the granularity and uniformity. Sequencing, the order in which test and production code are written, had no important influence. Refactoring effort was negatively associated with both outcomes. We explain the unexpected negative correlation with quality by possible prevalence of mixed refactoring. Conclusion: The claimed benefits of TDD may not be due to its distinctive test-first dynamic, but rather due to the fact that TDD-like processes encourage fine-grained, steady steps that improve focus and flow.
在 The Morning Paper 上的註解也可以看看 (反駁論文的意見)，像是對論文使用自評系統的批評。
And so we've decided to start Increment, a software engineering magazine dedicated to providing practical and useful insight into what effective teams are doing so that the rest of us can learn from them more quickly.
A digital magazine about how teams build and operate software systems at scale.
Increment is dedicated to covering how teams build and operate software systems at scale, one issue at a time.
可以看一看 Stripe 對團隊合作的想法...
之前有不少 Google 內軟體開發的說明 (像是 2015 年的「Google Is 2 Billion Lines of Code—And It’s All in One Place」)，不過這好像是第一次以 paper 的形式整理出來：「Software Engineering at Google」。
當你有一群等級超高的工程師時，軟體工程裡面一堆假設都被推翻，然後一堆工具都是客製化自己開發 (有可能是那個時間點還沒有成熟的工具，也有可能是需要大量客製化)，於是就會看到各種有趣的解法... XD
Here, we report an ultralow-cost (20 cents), lightweight (2 g), human-powered paper centrifuge (which we name ‘paperfuge’) designed on the basis of a theoretical model inspired by the fundamental mechanics of an ancient whirligig (or buzzer toy; 3,300 BC).
The paperfuge achieves speeds of 125,000 r.p.m. (and equivalent centrifugal forces of 30,000 g), with theoretical limits predicting 1,000,000 r.p.m.
在 GitHub 裡面，Redis 有兩種不同的情境，一種叫做 transient Redis，只用做 cache：
We used it as an LRU cache to conveniently store the results of expensive computations over data originally persisted in Git repositories or MySQL. We call this transient Redis.
另外一種則是打開 persistence 功能，叫做 persistent Redis：
We also enabled persistence, which gave us durability guarantees over data that was not stored anywhere else. We used it to store a wide range of values: from sparse data with high read/write ratios, like configuration settings, counters, or quality metrics, to very dynamic information powering core features like spam analysis. We call this persistent Redis.
這邊講的是 persistent Redis 被換成用 MySQL (InnoDB) 儲存：
Recently we made the decision to disable persistence in Redis and stop using it as a source of truth for our data. The main motivations behind this choice were to:
- Reduce the operational cost of our persistence infrastructure by removing some of its complexity.
- Take advantage of our expertise operating MySQL.
- Gain some extra performance, by eliminating the I/O latency during the process of writing big changes on the server state to disk.
For the majority of callsites, we replaced persistent Redis with
GitHub::KV, a MySQL key/value store of our own built atop InnoDB, with features like key expiration. We were able to use
GitHub::KValmost identically as we used Redis: from trending repositories and users for the explore page, to rate limiting to spammy user detection.
後面講了不少轉換的過程 (還包含了某些功能的改寫)，但沒有講的太清楚為什麼不繼續使用 Redis。
目前只能就提到的三點問題來看，persistent 的 i/o 成本可能太高？而且難以再壓榨效能出來？而相反的，InnoDB 已經花了很多力氣在上面，直接拿來用反而可以解決問題？
不過看得出來這個轉換還是花了不少力氣，看得出來有些 application 使用 Redis 的模式不能直接搬到 InnoDB 上，花了時間改寫...