惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Last Watchdog
The Last Watchdog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Secure Thoughts
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
T
Tor Project blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
L
LINUX DO - 最新话题
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Vercel News
Vercel News
Last Week in AI
Last Week in AI
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Proofpoint News Feed
博客园 - 叶小钗
NISL@THU
NISL@THU
C
Check Point Blog
K
Kaspersky official blog
N
News and Events Feed by Topic
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
Arctic Wolf
T
Threatpost
GbyAI
GbyAI
L
LINUX DO - 热门话题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
N
News and Events Feed by Topic
Scott Helme
Scott Helme
P
Privacy International News Feed
The Register - Security
The Register - Security
G
GRAHAM CLULEY
Recorded Future
Recorded Future
Apple Machine Learning Research
Apple Machine Learning Research
C
Cybersecurity and Infrastructure Security Agency CISA
B
Blog
Project Zero
Project Zero
Cyberwarzone
Cyberwarzone
Webroot Blog
Webroot Blog
Microsoft Security Blog
Microsoft Security Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
D
DataBreaches.Net
J
Java Code Geeks
AWS News Blog
AWS News Blog
Help Net Security
Help Net Security
Engineering at Meta
Engineering at Meta
M
MIT News - Artificial intelligence
T
Threat Research - Cisco Blogs
Google DeepMind News
Google DeepMind News

Nic Lin's Blog

謝明真 - 高效領導力的課後筆記 NFT 開發實戰!基礎智能合約入門 (3) NFT 開發實戰!基礎智能合約入門 (2) NFT 開發實戰!基礎智能合約入門 (1) 如何自我檢測 log4j CVE 漏洞 Rails 如何在資料寫入時記錄來源 IP 位置 如何經營工程師 Youtube 頻道 - Part 8 營收篇 如何經營工程師 Youtube 頻道 - Part 7 酸民文化篇 如何經營工程師 Youtube 頻道 - Part 5 設備器材篇 如何經營工程師 Youtube 頻道 - Part 4 後製剪輯篇 如何經營工程師 Youtube 頻道 - Part 3 文案企劃篇 如何經營工程師 Youtube 頻道 - Part 2 設備器材篇 如何經營工程師 Youtube 頻道 - Part 1 制訂頻道方向篇 如何經營工程師 Youtube 頻道 - Part 0 Rails 中避免 race condition 的最佳實踐(二) Rails 中避免 race condition 的最佳實踐(一) 10 分鐘整合 google sheet 做自動化開發功能週報 我的 Youtube 影片製作流程 API 設計時必須注意的 HTTP header 底線問題 如何提升你的程式可讀性之實務技巧(三) 如何提升你的程式可讀性之實務技巧(二) 如何提升你的程式可讀性之實務技巧(一) Ruby 中使用 freeze 優化效能的時機 避免 React 中的 useEffect 無限 render 在 Rails 內輕量使用 Vue Component 的最佳實踐 如何在區域網路用 Docker 架設有 SSL 的 Gitlab 從被問到問人,那些我常問的面試問題 [Rails] 如何漂亮寫出可維護的 query (Maintainable Rails Query) 在已知長度情況下優化 slice 的性能 [ReactNative] 如何在 iOS APP 上主動要求用戶評分 Rails 的 scope 為什麼用 lambda? Proc 與 lambda 不同之處 淺談 Active Record 的 Lazy load 特性 Rails 專案搭配 Github Actions 進行 RSpec 自動化測試 JavaScript 中 require, import 的差別及效能 React 效能優化基本招 ES6 箭頭函式 (Arrow functions) 2 個月擁有 6000 用戶 Side project 這樣做(一) 如何讓自己成為失敗的軟體工程師 如何用 Rack::Attack 阻擋 DDOS / 惡意流量 用 OpenSSL 自簽開發用 HTTPS SSL 憑證 為機器加上登入訊息,在 ubuntu 設置登入歡迎詞 Ruby Memoization 性能優化之記憶化 淺談 SSH agent forwarding 和 proxy command 的安全風險與應用 [Rails] Service / Library / Concern 的差異 避免過度的 Defensive Programming 防禦性程式設計 1:1 攪亂器,如何用 Ruby 做可逆推序號 Rails 中的欄位及方法命名原則 [Rails] 用 puma-dev 作為本地開發伺服器 (支援 https 自簽憑證) 將 Rails 專案從手動部屬遷移使用 Capistrano 自動化部屬 工程師提昇自己的教學和簡報技術的方法 [筆記] Rails 3.2 升級 Rails 6.beta 經驗分享 Class method 氾濫帶來什麼問題 RDBMS 課程心得與筆記 常用的 Rails 開發規範 Rest-Client 如何做 Basic Authentication 驗證 [Rails] 何為 tld_lebgth? 遵循 Semantic Versioning 軟體開發語意化版本管理 請直接在 MySQL 裡面直接用 utf8mb4 取代 utf8 如何解決在 awesome print 中遇到 ActionController::Parameters unable to convert unpermitted 如何在 Mac 上升級 PostgreSQL 並遷移資料 如何解決 Mysql2::Error: Incorrect string value 讀書心得 - 「信任因子:信任如何影響大腦運作、激勵員工、達到組織目標」 我是如何寫部落格筆記的 讀書心得 - 「先問,為什麼?:顛覆慣性思考的黃金圈理論,啟動你的感召領導力」 [Rails] 解決 Reset Password 帶來的 token 洩漏問題 我的軟體工程師生涯:如何挑選適合你的公司 Rails 中的 delegate 用法 淺述 SSR SPA 優缺點 Rails 非同步工作請用 Global ID [React] Class Component 傳遞 props 的 2 種方式 好用的隱私權政策 URL 自動生成 Rails 5.1 之後的 tag helper Rails 5.2 Encrypted Credentials 最近面試被給的建議和書單 一般架構需要用到 K8S 嗎 透過 commit SHA 找 github Pull request 從零搭建,如何讓 Rails 跑在 Kubernetes(k8s)(二) 從零搭建,如何讓 Rails 跑在 Kubernetes(k8s)(一) React Stateless Functional Components 搞懂 React 中的 state 和 props 物件導向基本原則 SOLID (Ruby Sample) 在以太坊智能合約上是可以預測隨機數的 在台灣租屋必須注意的事 Rails 5 簡單雙向加解密 如何用 ABA 培養自律型員工 不要在 rake task 中定義 method, 請用 RAKE::DSL rails 非hash只想用array輸出page 如何處理陣列裡有重複的值 [Rails] 如何重設你的專案名稱 Ruby on Rails install on Mac 安裝步驟 使用 Friendly_id 與 Babosa 美化你的Rails 網址 Junior Rails 兩個月實戰心得 Devise使用Google實作登入 [iterm2] 如何新增alias 一個新鮮人找尋Rails工作的面試經驗 如何讓兩個資料表建立關聯 routing 的 namespace strong parameter user story 的格式 user story 是什麼?
經營 Side Project 300 天所帶來的收穫及挑戰
Nic Lin · 2020-05-27 · via Nic Lin's Blog

在去年 2019 年 5 月,我一個人花費 3 天的時間,使用 Ruby on Rails 開發了第一版網站,隨後一個月利用 React Native 完成了 APP 開發並上線。

北宜公路資訊互助網,也就是 Beiyi 北宜 APP。

這個我利用下班及假日空閒時間誕生的專案,在經過 300 天後到底有什麼實質的收穫及遇到的挑戰?

以下會透過實際的一些數據回顧過去一年裡這個 Side project 的成長。

如果你是第一次看到我的文章,前情提要一下,有三個篇幅

當時也因為這個主題有幸獲得「快樂學程式」邀約參加小聚演講,這裡有影片連結

營利不是壞事

一開始其實只是一種工程師單方面的浪漫,可以透過自己喜歡及想學習的技術,建造一個能解決用戶問題的應用程式,也就是說,我本來的目的就沒有打算透過這個 Side project 大撈一筆,所以在初期整個開發的藍圖裡,營利是我完全沒有設想的部分。

也因為這樣,初期無論是 iOS/Android 平台要繳的保護費、機器維運費用,甚至是製作產品的周邊貼紙,都是我自掏腰包拿出來做的。當時也沒去想太多,心想,反正就算虧損也不會比虛擬貨幣一個小時虧的還多 XD

開發這個 Web/APP 的主要目的是希望

  1. 解決自己騎車出門時,要開一堆 APP 才能知道路況及天氣
  2. 挑戰自己過去幾年鍛鍊的技術,能不能做出一個從 Web 到 APP 的完整產品

當時基本的開銷是

  • iOS 3400 NTD / 年
  • android 600 NTD / 一次性永久
  • 機器每個月費用 150 NTD

也就是說平均下來一個月大概就是 500 NTD 的開銷,雖然不是什麼大金額,但其實更多的成本是維護更新及審查一些不符合規定的貼文(APP 內有文章發佈系統)

於是在總用戶數大概上升到 8000 人及 DAU(Daily Active Users) 落在 600-800 左右時,我決定加入橫條式的廣告,計畫透過曝光來增加收入

會做這個決定單純是好奇,在 APP 上掛廣告這件事情究竟可以帶來多少收入?

這時我已經規劃好退路,也就是說,如果掛一個月的收入,連 server 月費 150 NTD 都無法抵銷的話,就會打算移除廣告,至少不要為了這點蠅頭小利葬送了整體應用程式的畫面設計美感。

很有趣的是,在橫幅廣告上線後,用戶們並沒有因為這樣而拒絕使用,這和我當初的心裡預期不太一樣。

反而因為這個契機,用戶給予我更多實質的建議,透過這些對話,讓我知道可以嘗試做應用程式內部購買,使用者可以選擇付費去除廣告,也因為這樣子讓我明白,其實當一個應用程式能真正解決使用者的問題時,在不影響操作前提下放置的收益廣告,也就不那麼令人在意了

在這個時期我和用戶有更多的互動,我會在粉絲專頁分享我的開發進度及遇到的一些瓶頸,用戶也會透過各種渠道讓我們知道建議及支持。

Admob 的廣告營收,從上線第一個月約 600 元到現在平均每個月有 2000 元左右的進帳,雖然稱不上是什麼可觀的收入,但至少做到讓整個應用程式呈現 auto run 的狀態,可以讓 APP 去支撐 server 運作,剩下的維護就倒是小事了。

202002 單月廣告收益

202003 單月廣告收益

然後你會發現,IAP(應用程式內購)的購買數量基本上低的可憐,在 MAU 有 12000 的情況下,平均每個月實際有購買的用戶總數大約在 3 人以下

目前最佳記錄,單月有 6 個人購買

遊戲化 & 留存率

原本留存率就算滿不錯的,一個月後大概還能維持 35~45% 之間。

這邊想挑戰用遊戲化的制度來讓用戶能夠更常回來使用 APP,所以我們做了徽章及打卡簽到機制。

目的是想讓用戶在熱心回報路況時更有榮譽感,系統也會依據每個人的貢獻程度給予相對應的徽章。

這裡在規劃時就參考了一些常見的網路遊戲、手遊的徽章等級制,也因為這樣的機制,我們在觀察數據後發現,用戶黏著度確實有提升,連帶廣告的曝光度也變相增加,原本只有假日才有流量的 APP,現在在平日也有不錯的表現。

有趣的是,沒想到這個機制上線後,演化出新的文章發佈生態,除了用戶從被動查看路況到主動回報,也發現開始會出現遊走規則邊緣的灌水文,雖然用戶停留的時間變長了,但隨之而來的問題也跟著變多了。

路況回報本身屬於比較即時的行為,也就是用戶可能駕駛交通工具經過某處時,覺得路況有異狀會透過 APP 進行回報,就會容易發生同個路段有多個用戶行經後一起發文,造成類似的刷文事件。

後來也因為面臨這樣的問題,又實作一套演算法去檢查一定時間區間內,是否有文章的內容相似度較高的情況,在發佈時給予提示訊息。

技術挑戰

前端(React Native)

期間遇到版本號更新 0.59 => 0.60 有些套件的坑必須處理,花了不少時間,說真的要寫 React Native 要保持持續更新踩坑,不然等你回過神來,跟重寫沒兩樣。

其實我原本對 React 只有基本撰寫功力,大概就是基本 redux / class component / HOC 之類的技能

不過後來因為要實作 APP 上架,就靠著下班自學,上班問同事的節奏,把 React 的部分在摸的更熟一些。

現在 APP 主要結構就是 redux 逐漸往 hooks 移動,然後開始改用 typescript 進行撰寫。

主要遇到比較煩的問題就是每次修 bug 或是新增一些功能時,要送審才能上架,而 iOS / Android 時間又不太相同,雖然現在審核時間相較幾年前快很多了,但不免還是有忽快忽慢的問題產生

也因為這樣,就開始考慮走 OTA(Over the air) 更新。

接著又花點時間把專案引入 expo 的工具鏈來做 OTA,確實省掉很多事情。

例如原本沒有打算做禁言功能,但可能突如其來的臨時事件,導致有一批用戶開始亂發佈文章,這時候你就可以透過線上更新快速封掉發文功能立即止血,事後的細節改進可以在爭取時間後做處理。

不會因為卡在審核階段而導致寸步難行。

後端(Ruby on Rails)

以目前總用戶數 18000,在 MAU 仍有 12000 的情況下,現在依舊維持著 1CPU + 1GB RAM 規格的 server 繼續穩定運行。

目前的 API endpoint 約 30 支,然而高峰時段有出現曾經 1000 人同時在線的狀況,至今沒有出現任何一次因為效能而倒站的問題。

原本一天發文數量非常少,到後來一天最多可能有 40 幾篇,一開始是沒有做分頁的,不過後來要一次 React Native render 40 個卡片時,確實會有效能上的問題,所以這段就用分頁解掉了。

當時在實作的時候,後端能做 Cache 的基本都有做,所以就繼續用這個迷你規格持續運行囉!

總結

其實一年說長不長,說短不短的,這段時間過去,我給 Side project 的時間更少了,但他卻在這時間不斷的滋養下,開始茁壯了。

我用一年的時間摸索學習,接觸了我之前沒碰過的領域,透過做這個 Side project 我收穫還真的滿多的

  • 珍貴的支持者
  • 實際廣告收益
  • 技術能力領域拓展
  • 行銷能力
  • 專案管理能力(目前共 3 人協助設計、維護、開發)

如果你看過一年前這系列的文章,當時的你是否曾經有股衝動猶豫要不要做 Side project?而後來因為各種原因讓想法沈睡。

那麼,我用一年的時間和你分享,付出的人往往收穫最多,別遲疑,隨時準備開始你的 Side project 吧!