Dropbox 與 C++ 的“七年之癢”真的難跨越嗎

chhch86發表於2019-08-19

Dropbox 與 C++ 的“七年之癢”難跨越,跨平臺真的是偽命題嗎?

Perl 語言建立者 Larry Wall 曾總結過好的程式設計師有 3 種美德:懶惰、急躁和傲慢(Laziness, Impatience and hubris)。因為懶惰,程式設計師絞盡腦汁地將大量的重複性勞動交由機器處理;因為懶惰,程式設計師希望透過“一次編寫,處處執行”而實現“一勞永逸”的美好願望。

“一次編寫,處處執行” —— 簡單來說就是跨平臺。然而這個十分符合程式設計師思維,且承載著他們美好願望的方案,在實際操作中往往不能如其所願,甚至會適得其反。

Dropbox 工程師近日在其官方部落格和大家分享了他們“棄暗投明”的經歷 —— 放棄在其 iOS 和 Android 客戶端之間共用同一套程式碼的策略,轉而使用各自平臺的原生語言進行開發。

工程師表示,Dropbox 在 2013 年開發 iOS 和 Android 平臺的移動應用時,採用了透過 C++ 語言在兩個平臺之間共享同一套程式碼的策略。當時的想法十分簡單,開發團隊希望使用 C++ 編寫一次程式碼即可,無需分別針對 iOS 和 Android 平臺各使用 Objective-C 和 Java 編寫兩次程式碼。另外,當時負責移動應用開發的團隊規模相對較小,為支援快速增長的移動應用,他們需要找到一種方法以透過這個小團隊在 iOS 和 Android 平臺上快速部署大量程式碼。

但現在 Dropbox 放棄了這個策略,轉而使用各自平臺的原生語言(主要是 Swift 和 Kotlin)。之所以做出這個決定,是因為在兩個平臺共用同一套程式碼的隱藏開銷其實很高。他們從中總結到的經驗就是:如果遵循廣泛使用的平臺預設標準,而不是以非標準方式編寫程式碼,他們可以不用承擔本應不必考慮的開銷,這種開銷最終比編寫程式碼兩次更昂貴。

Dropbox 工程師將這些隱藏開銷歸納為四類,在介紹這些隱藏開銷之前,工程師強調他們實際上從未達到大多數程式碼庫均使用 C++ 開發的階段,因為正是採用 C++ 帶來的隱藏開銷阻止了他們完全朝這個方向發展。

維護自研框架和庫的開銷

使用 C++ 首先面臨的開銷是需要自己構建框架和庫,這大致分為 2 個子類別:

支援與主機環境互動以構建完整的移動應用程式的框架。例如:

Djinni:用於生成跨語言型別宣告和介面繫結的工具

用於在後臺執行任務與主執行緒的框架(使用平臺原生語言執行簡單任務)

用於替代本可以在平臺原生語言中使用的預設或者開源標準庫。例如:

json11:用於 JSON 的 (反)序列化

nn:C++ 的非可空指標

Dropbox 工程師表示,如果採用平臺原生語言,這些程式碼都不是必需的,而且他們對開源專案的貢獻可能會使更多的開發者受益於平臺原生語言。值得注意的是,上述的這些開銷在 C++ 中尤其高(與其他非原生語言如 Python 和 C# 相比),因為它缺少單一的全功能標準庫。話雖如此,C/C++ 是唯一包含受 Google 和 Apple 支援的編譯器的語言,如果使用不同的語言會產生許多其他需要處理的問題。

維護自研開發環境的開銷

移動生態系統有許多工具可幫助提升開發效率。其中用於移動開發的 IDE 也非常豐富,Google 和 Apple 為其投入了大量資源,讓開發者在相應的平臺上擁有最佳的開發體驗。由於 Dropbox 沒有使用平臺的預設方案,他們自然無法享用這些便利。其中最值得注意的是除錯體驗,在平臺的預設 IDE 中除錯平臺原生語言的體驗通常優於除錯 C++ 程式碼的體驗。

Dropbox 工程師舉了一個尤其令他們印象深刻的例子,在其後臺執行緒框架中出現了導致應用程式隨機崩潰的錯誤。為此他們使用了簡單的標準堆疊,但是也難以定位這些型別的錯誤。因為這個問題涉及除錯在 C++ 和 Java 之間來回執行的多執行緒程式碼,最終他們花費了幾周的時間才定位了問題所在。

除了工具的缺失,工程師還需要花費時間構建支援共用同一套 C++ 程式碼的工具。最重要的是,他們需要一個自定義構建系統,該系統用於建立包含 C++ 程式碼以及封裝 Java 和 Objective-C 程式碼的庫,並且可以生成 Xcodebuild 和 Gradle 都能理解的物件。正是這個系統對 Dropbox 的資源造成巨大的拖累,因為它需要不斷更新以支援兩個構建系統的變更。

可以看到,大量的時間被耗費在造輪子 -> 補輪子的重複中。

解決不同平臺之間的差異的開銷

雖然 iOS 和 Android 應用程式都統稱為“移動應用程式”,並且兩者通常具有相同的特性和功能,但平臺本身存在一些影響功能實現的差異。例如,應用程式在每個平臺上執行後臺任務的方式是不同的。即使剛開始採用這種跨平臺策略時具有一定的相似之處,但隨著時間的推移這些差異會大相徑庭(例如,與系統相簿的互動)。

因此,工程師甚至無法真正實現編寫一次程式碼並讓它在不同平臺上開箱即用地執行。他們必須花費大量時間將程式碼整合到不同的平臺,並編寫特定於平臺的程式碼。

所以這裡的“只編寫一次程式碼”並不能如願以償,大大降低了這種方法的便利性。

招聘、培訓和留住開發者的開銷

當 Dropbox 在其移動應用產品上採用這種策略時,他們擁有一批經驗豐富的 C++ 開發者。這個團隊啟動了 C++ 專案,並對其他的開發者進行了培訓以為專案貢獻程式碼。

但隨著時間的推移,這些有經驗的開發者逐漸去了其他團隊或者其他公司。剩下的開發者缺乏足夠的經驗來支撐和推進專案,而招聘具有相關 C++ 開發經驗的高階工程師也變得越來越困難。

最後團隊缺乏維護 C++ 程式碼庫的關鍵專業知識,而要滿足這一需求團隊有以下兩種選擇:

找到並僱用具有這種特定技能的候選人(現實情況是招聘了一年仍未能找到合適的人選)

針對缺失的技能,在內部培訓移動(或 C++)工程師。但現實情況是缺少擁有所需技能的人員來進行培訓,所以這個目標也難以實現。甚至在培訓前,就有移動工程師透露出對學習 C++ 不感興趣。為此培訓所需的開發者也是一大問題。

在招聘問題上,Dropbox 工程師發現許多移動開發者根本不想在 C++ 專案中工作,這也導致他們許多優秀的工程師離開專案。畢竟移動開發技術的更新非常快,這些開發者希望自己的技術棧能時刻跟上潮流。

結論

Dropbox 表示隱藏開銷導致最終的成本超過了收益,還不如使用各自平臺的 IDE 開發更為簡單和便宜。所以最後他們不再透過 C++(或任何其他非標準方式)共用同一套移動端程式碼,而是使用各自平臺的原生語言編寫程式碼。

無論我們學習什麼程式語言,都要來鄭州達內看看,這裡也許沒有最全的專業,但卻有你需要的熱門技能,如果想要提升,來看看吧,不會後悔了!


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940009/viewspace-2654141/,如需轉載,請註明出處,否則將追究法律責任。

相關文章