我們為什麼選擇Rust開發頂尖實時通信產品?|應用程式|代碼|編譯器|...

2021-01-07 網易



  作者 | Jake McGinty

  譯者 | 王強

  策劃 | 趙鈺瑩

  tonari 的目標是在虛擬世界為人們建立真正自然的交互體驗。我們開發了2年,它應該是時延最低的高解析度「電話會議」產品,並且準備好投入生產環境。

  

  我們對比了 Zoom 和 WebRTC 的典型延遲,在辦公室同一網絡上的兩臺筆記本電腦(X1 Carbon 和 MacBook Pro)之間測得 315-500ms 的數字,其中的差距非常巨大。如此大的延遲意味著通話雙方要不斷打斷對方,而 tonari 卻可以做到自然而流暢的遠程交流。從圖像質量來說,市面方案只能提供模糊的面部畫面,攝像頭看起來對準的是對方的鼻子;而 tonari 則能傳輸寬視角的高保真圖像,順暢地通過網絡遠程傳遞當面交流中所見的那些微妙肢體語言。

  自 2 月份啟動第一個試點項目以來,我們沒有遇到過軟體導致的停機時間(乙太網電纜斷開是另一回事)。雖然我們很想認為自己是天才般的工程師,但我們真要感謝 Rust,沒有它我們實在沒自信能達到如此高的穩定水平。

  https://blog.tonari.no/changing-communication-and-culture-in-an-organization

  1為什麼我們不用 WebRTC

  tonari 的第一個概念驗證產品使用了一臺基本的投影儀、藍牙揚聲器和一個運行在標準 WebRTC(JavaScript)之上的網站。自那時以來,我們已經走了很長一段旅程。

  儘管這個原型(以及我們對未來的願景)為我們贏得了投資,但我們知道 tonari 只靠它是會撞得頭破血流的,除非我們可以實現比 WebRTC 更低的延遲和更高的保真度——在 2020 年的今天,這兩種特性都是市面上的視頻通話產品不具備的。

  我們想到了一個法子:「好吧,所以我們可以直接修改 WebRTC 並用 C++ 寫的漂亮 UI 給它打個包,然後就能快速發布了。」

  在 WebRTC 將近 75 萬 LoC 的龐大代碼庫中苦苦掙扎一周之後,我們意識到哪怕僅僅是一個小小的更改都可能帶來巨大的痛苦——要測試這些代碼是很難的事情,想要真正對它們產生信心更是痴心妄想。

  因此,在一次討論會上,我們認定從頭開始重新實現整個技術棧是容易得多的路線。我們想要了解和理解在我們的硬體上運行的每一行代碼,並且應該針對我們想要的具體硬體進行針對性設計。

  因此,我們開始了全新的旅程,從瀏覽器或現有 RTC 項目之類的高級界面深入到更內核的部分,並從零開始進入了底層系統和硬體交互的世界。

  我們需要系統本身具有足夠的安全性,以保護 tonari 用戶的隱私。我們需要它具有強大的性能,以使通話過程儘可能人性化和實時流暢。而且,隨著新員工的不斷加入,他們要學習我們的現有工作並在此基礎上進行擴展,我們需要在代碼變得更加成熟的同時使其具備良好的可維護性。

  我們討論並排除了一些選項:

  


  安全性:C 和 C++ 的內存和並發都是不安全的,並且它們紛繁複雜的構建系統使我們很難獲得一致且簡單的開發體驗。

  


  性能:Java、C# 和 Go 的內存管理是不透明的,在對延遲敏感的應用程式中,如果要完全控制內存,它們可能會很難用。

  


  可維護性:Haskell、Nim、D 和其他幾種定製語言在工具鏈、社區和人才資源方面不盡如人意。

  

  實際上在我們看來,Rust 是能滿足這些需求的唯一一種可用於生產的語言。

  2從 Rust 開始

  Rust 的優勢來源於開發社區做出的無數決策。

  


  它的構建系統是 opinionated,而且設計簡潔。它本身就是一個完整的生態系統,你可以輕鬆引導新工程師進入項目並建立開發環境。

  


  內存和並發安全性保證簡直不能更贊。我們相信,如果我們繼續使用 C++ 來開發,那麼到現在都無法進行第一次部署——我們可能還是卡在許多細節上。

  


  我們通過 CUDA 之類的 API 與硬體進行最底層交互的能力,通常是通過現有的板條箱(crate,Rust 的代碼庫術語)實現的,這使我們有能力為第一個生產版本的延遲定下更高的標準。

  

  隨著 tonari 不斷前進,我們現在選擇的嵌入式微控制器的固件可以用 Rust 編寫,因此我們就不用在不安全的編程系統舊世界上興建世外桃源了。

  3我們依賴的工具箱

  這裡不談 cat Cargo.toml,而是會專注於一些精挑細選過的工具箱。

  「優於 std 的」工具箱

  


  在幾乎所有方面,crossbeam 都比 std::sync::mpsc 更適合線程間通信,並且最終可能會合併到 std 中。

  


  parking_lot 在幾乎所有方面都具有優於 std::sync::Mutex 的 mutex 實現,並且某一天可能合併到標準庫中。它還提供了其他許多有用的同步原語。

  


  與 Vec 相比,bytes 是一種更健壯且通常性能更高的字節處理方式。

  


  如果你要進行底層網絡優化,socket2 會是你的最終選項。

  

  錦上添花

  fern 是一種自定義和美化日誌記錄輸出的簡單方法。我們使用它來保持日誌的可讀性和內部標準化。

  structopt 是你一直夢寐以求的 CLI 參數處理方式。除非你的依賴項幾乎沒有,否則沒有理由不使用它。

  Cargo 經典傳奇

  


  cargo-release 使我們能夠輕鬆減少內部版本。

  


  cargo-udeps 可以識別未使用的依賴項,並儘可能減少我們的構建時間。

  


  cargo tree(最近集成進了 cargo)顯示了一個依賴樹,它在許多方面都很有用,但主要用於找出最小化依賴項的途徑。

  


  cargo-geiger 幫助我們快速評估外部依賴,以解決可能的安全性(或正確性)問題。

  


  cargo-flamegraph 在跟蹤代碼中的性能熱點時給了我們巨大的幫助。

  

  4項目結構

  tonari 代碼庫是單體架構。從本質上講,我們有一個帶有 binaries 板條箱和許多支持庫板條箱的 Cargo 工作區。

  我們將工具箱放在一個存儲庫中,這樣就很容易在我們的 binaries 板條箱中引用,而無需發布到 crates.io,或在我們的 Cargo.toml 中指定 git 依賴項那麼麻煩了。當需要將這些庫開源發布時,很容易就能把它們分解成單獨的存儲庫

  庫,二進位,為什麼不兩者並用?

  我們有一個主庫,其中包含一個用來與硬體、媒體編解碼器、網絡協議等通信的統一 API。除了這個私有 API 外,我們在工作區中還有獨立的板條箱,我們將這些板條箱視為開放原始碼的候選人。例如,我們已經自行編寫了適合長期運行的高吞吐量 actor 的 actor 框架,以及用於可靠、高帶寬、低延遲媒體流的網絡協議。

  我們將不同的二進位文件用於 tonari 系統的不同部分,並且每個二進位文件都位於 binaries 中。它的庫模塊包含一組可重用的 actor,將我們的私有 API 與 actor 系統結合在一起,然後是消費這些 actor 並定義它們之間管道的單個二進位文件的集合。

  視野所及的標誌

  我們廣泛使用功能標誌,以在不同的 OS(例如古老的 MacBook Pro)或不同的硬體配置上開發項目。這使我們能夠輕鬆更換攝像頭硬體,而無需進行額外的運行時檢查或使用可怕的 sed 編程技巧。

  例如,Linux 使用 v4l2(Video For Linux...2)來訪問大多數網絡攝像頭,但是其他網絡攝像頭可能有自己的 SDK。要針對不使用 v4l2 的平臺或在特定作業系統不可用的 SDK 進行編譯時,我們可以將這些 SDK 放在功能標誌後面,並導出一個公共接口。

  舉一個(簡化的)具體示例,假設我們有一個定義為一個 trait 的通用攝像頭接口:

  
pub trait Capture {/// Capture a frame from a camera, returning a Vec of RGB image bytes.fn capture(&mut self) -> Vec;}

  假設我們有三種不同的攝像頭界面:v4l2、corevideo 和 polaroid。我們可以讓 binaries 專門針對此 trait 來獲得靈活性,並且可以使用功能標誌切換不同的 Capture 實現。

  
#[cfg(feature = "v4l2")]mod v4l2 {pub struct V4l2Capture {...}

impl Capture for V4l2Capture {fn capture(&mut self) -> Vec {...}}}

#[cfg(feature = "corevideo")]mod corevideo {pub struct CoreVideoCapture {...}

impl Capture for CoreVideoCapture {fn capture(&mut self) -> Vec {...}}}

#[cfg(feature = "polaroid")]mod polaroid {pub struct PolaroidCapture {...}

impl Capture for PolaroidCapture {fn capture(&mut self) -> Vec {...}}}

#[cfg(feature = "v4l2")]pub type VideoCapture = v4l2::V4l2Capture;

#[cfg(feature = "corevideo")]pub type VideoCapture = corevideo::CoreVideoCapture;

#[cfg(feature = "polaroid")]pub type VideoCapture = polaroid::PolaroidC

  如果讓我們的代碼與實現 Capture trait 的事物搭配,而不是與具體類型搭配,那麼現在我們可以簡單地切換功能標誌來在各種目標平臺上編譯。例如,我們可以有一個結構,該結構具有一個欄位 video_capture: Box ,它能使我們存儲可從攝像機 Capture 的任何類型。

  一個支持上面我們編寫的捕獲實現的示例 Cargo.toml 文件可能是這個樣子:

  
[package]name = "tonari"version = "1.0.0"edition = "2018"

[features]default = ["v4l2"]macos = ["corevideo"]classic = ["polaroid"]v4l2 = ["rscam"]

[dependencies]rscam = { version = "0.5", optional = true } # v4l2 linux camera librarycorevideo = { version = "0.1", optional = true } # MacOS camera librarypolaroid = { version = "0.1", optional = true } # Polaroid camera librar

  這樣,我們就可以避免構建並連結到特定於平臺的庫,例如 v4l2 這樣並非完全通行的選項。

  5在工作中學習 Rust

  轉換到 Rust 一年後,我們的第四位工程師加入了團隊,他在 Rust 或系統工程方面都沒有很多經驗。雖然學習曲線是不可否認的,但我們發現 Rust 為那些剛接觸底層編程的新手提供了驚人的力量。

  如前所述,該語言內置的內存和並發安全性意味著一籮筐問題不僅是無法編譯的,而且編譯器本身往往就是你唯一需要的老師,因為它給出的警告解釋得非常清楚。關於 Rust 出色的編譯器消息以及出色的文檔(可以看一下關於字符串的長長討論),已經有很多文獻做出了介紹。對於我們來說,這些都是非常有用的資源。

  https://doc.rust-lang.org/stable/book/

  https://doc.rust-lang.org/book/ch08-02-strings.html

  與其他許多語言不同,在 Rust 中通常有一種顯而易見的「正確方法」來做各種事情。並非以「正確方式」編寫的代碼往往會非常顯眼,並且很容易在審核中跳出來,往往是由 cargo clippy 自動識別出來的。

  實際上,這意味著新工程師可以快速開始貢獻可用於生產的代碼。代碼審查可以繼續專注於實現,而不是花費更多精力手動做正確性檢查。

  IDE 普查

  在 IDE 部門中,我們發現 Rust 與某些前輩相比還相對不夠成熟。尤其是今年,我們取得了長足的進步,每個人都找到了一個非常舒適的開發環境。

  

  我們經常分享設置並互相嘗試對方的環境(Brian 除外,他在 29 歲之後就停滯不前了),並且我們一直在關注可以幫助我們更好地協作的新開發工具。

  代碼風格指南已死,rustfmt 萬歲

  體驗過狂野的開發人生嗎?提交代碼之前,我們沒有必須閱讀的代碼樣式指南文件。我們不需要這種東西。我們只是強制執行 rustfmt。告訴你吧:這確實是代碼審查的前沿陣地。

  我們如何審查代碼

  我們的代碼審查非常簡單,因為到目前為止我們只有四個人,而且我們很幸運在彼此之間贏得了很多信任。我們的主要目標是在每一行代碼上至少有兩對眼睛盯著,並且不要互相擋路,以便我們保持活力。

  6持續測試

  我們使用谷歌的 Cloud Builder 來運行 CI 構建,因為我們的基礎架構棧主要基於 GCP 構建,並且可以輕鬆調整構建機器規格和自定義構建映像。每次提交都會觸發它,並運行 cargo clippy 和 cargo build。我們將 -D warnings 傳遞給編譯器,以將警告升級為錯誤,確保我們的更改不會在可憐的同事下次拉取更改時劈頭蓋臉迎來大堆 rustc 警告。

  為了縮短配置項構建時間,我們將 target 和.cargo 目錄緩存在 Cloud Storage 中,以便下次可以下載並增量構建。

  
for crate in $(ls */Cargo.toml | xargs dirname); dopushd $crate

# Lint.cargo +$NIGHTLY_TOOLCHAIN clippy --no-default-features -- -D warnings

# Build.time RUSTFLAGS="-D warnings" cargo build --no-default-features

# Test.time cargo test --no-default-features

popdd

  我們也聽說了關於 sccache 的好消息,並將很快對其進行評估!

  7與現有的 C/C++ 庫集成

  Rust 生態系統很棒,但是有大量現有項目需要大量時間投入才能移植到 Rust。webrtc- audio- processing 就是一個很好的例子。它提供的好處(沒有回聲或刺音的清晰音頻)很明顯,並且不太可能在短期內將其移植到 Rust(它大約包含 8 萬行 C 和 C++ 代碼)。

  值得慶幸的是,Rust 很容易使用現有的 C 和 C++ 庫。bindgen 這個板條箱完成了大部分繁重的工作。給它一個用 C 或 C++ 編寫的頭文件,它將自動生成(不安全的)Rust 代碼,該代碼可以調用頭文件中定義的函數。到那時,由你決定是否創建一個更高級別的 Rust 板條箱,以暴露一個安全的 API。

  https://crates.io/crates/bindgen

  對於具有簡單或常用構建過程的庫,這個過程中的大部分是相當自動化的。但是,創建更高級別的安全 API 很重要——bindgen 提供的 Rust API 不適合直接使用,因為它不安全且不太符合習慣。幸運的是,一旦有了更高級別的 API,你最後就可以將 C 庫換成你自己的 Rust 版本,而板條箱的消費者並不會察覺其中的變化。

  這些特性使我們可以使用很多永遠沒有原生 Rust API,或者需要數月或數年才能重新實現的 API 和硬體。底層 OS 庫、大型代碼庫(如 webrtc- audio- processing)和製造商提供的相機 SDK 都可以用在我們的 Rust 代碼庫中,而無需將整個應用程式語言轉移到 C++,同時仍然可以提供良好的性能。

  一些 C++ 庫很難直接從 Rust 對接。你必須將類型列入白名單,因為 bindgen 無法處理引入的一部分 std::* 類型,它不適用於模板化函數和複製 / 移動構造器,以及此處記錄的其他許多問題。

  https://rust-lang.github.io/rust-bindgen/cpp.html

  為了解決這些問題,我們通常會創建一個簡化的 C++ 頭文件和源包裝程序,以導出對 bindgen 友好的函數。這種工作要複雜一些,但與將整個庫移植到 Rust 相比工作量要少得多。你可以在此處查看這個包裝器創建的示例。

  https://github.com/tonarino/webrtc-audio-processing/tree/2a973929c3afbc24beea75aa235f3341a7be275a/webrtc-audio-processing-sys/src

  由於 Rust 的所有生態系統以及 C/C++ 項目僅僅是對 bindgen 的調用,我們可以輕鬆訪問現有的一些最高質量的軟體包,而不必犧牲執行速度。

  8Rust 的痛點

  Rust 並非沒有問題。這是一種相對較新的語言,並且在不斷發展,大家在評估向 Rust 的遷移選項時應該考慮到它的一些缺點。這裡是我們總結的一部分痛點清單:

  


  編譯時間長。著名的 xkcd 漫畫諷刺說等待 Rust 代碼編譯時可以去喝咖啡休息一陣兒,這是很真實的。例如,我們的代碼庫大約需要 8 分鐘才能在中等性能的筆記本電腦上以非增量方式完成編譯,但實際情況可能會更糟。Rust 編譯器有很多工作要做,以實施強大的語言保證,並且它必須從原始碼編譯整個依賴樹。增量構建的情況會好些,但是一些板條箱附帶了構建腳本,這些腳本可以拉出並編譯非 Rust 的依賴項代碼,並且在升級版本和切換分支時可能需要清除構建緩存。

  


  庫覆蓋率。Rust 的庫生態系統已經相當成熟,但與 C/C++ 相比覆蓋範圍還是有限。我們最終實現了自己的抖動緩衝區,並且還使用 Rust 的 bindgen 包裝了多個 C/C++ 庫,這意味著我們的 Rust 代碼中存在 unsafe 區域。不常見的項目往往會有少量的不安全代碼,這惡化了學習曲線,帶來了更多出現內存錯誤的機會。

  


  Rust 要求你首先編寫正確和明確的代碼。如果弄錯了,編譯器不會漏掉它的。如果你不太在意並發性和內存保證,那麼開發時會感覺到速度緩慢,卻並沒有必要。但是,Rust 開發人員一直在努力改善錯誤消息。它們友好且可操作,通常包含修復建議。良好的內存和並發基礎模型還有助於更快地克服最初的駝峰,因此我們建議你花一些時間來真正理解語言及其保證。

  


  Rust 的類型推斷器是如此強大,它使你有時感覺就像正在使用動態類型的語言一樣。就是說,有時它並不能完全按照你想要的方式工作,特別是當涉及到泛型和 deref coercion 時,你最後不得不四處摸索才能讓這個推斷器滿意。這可能會帶來挫敗感,而團隊中如果有人經歷了這一學習階段,那就太有幫助了。有了足夠的耐心,這種挫敗感通常會變成令人驚嘆的時刻,可以加深我們對語言設計及其用途的理解,避免可能會引入的錯誤。

  


  語言進化。Rust 語言正在不斷發展。某些語言結構(例如 async)仍然是脆弱的,你可能會發現最好還是堅持使用線程和標準庫。

  

  9選擇 Rust 後,到目前為止的情況

  到目前為止,我們沒有發生與軟體相關的停機,這既令人驚喜,又是 Rust 保證提供的安全性的證明。Rust 還使我們可以輕鬆使用高效資源來編寫高性能代碼——我們的 CPU 和內存使用率都是可預測且一致的。因為沒有垃圾收集器,我們可以保證一致的延遲和幀速率。

  我們維護 Rust 代碼庫的體驗也很棒。對我們的代碼庫進行大量更改後,我們可以放心地對延遲部分進行重大改進。乾淨的編譯並不總是意味著一切都會正常工作,但老實說,這種情況還是很平常的。

  我們的最終成果是獲得了可靠的產品,也不需要噩夢般的維護工作,並且可以符合我們要求的幀速率、延遲和資源效率的高標準。同樣,很難想像如果沒有 Rust,我們現在會是什麼樣子!

  到目前為止,我們已經開源了一個 FFI 板條箱,即 webrtc-audio-processing。這是過去我們存儲庫中最高級的板條箱之一,在開源過程中還有更多類似的板條箱。

  https://doc.rust-lang.org/nomicon/ffi.html

  以後,隨著我們發布更多代碼,關於這個主題的內容將會越來越多。但有一件事情是不變的:在開源之前,我們私下創建的每個板條箱都已經做好了開源的準備。這種理念使我們板條箱之間的界限更加清晰,並鼓勵我們更流暢地做出要將代碼庫中哪些部分開源的決策。

  https://blog.tonari.no/why-we-love-rust

相關焦點

  • 為什麼選擇Rust?
    「程序正確性是通過測試來檢驗的」和「程序正確性是經過邏輯驗證的」之間存在著巨大的差異。不幸的是,即使我們對代碼的每一行都進行了測試,我們仍然不能確保它是正確的。然而,擁有一個形式系統來證明我們的代碼是正確的(至少在某些方面是正確的)則是另一回事了。
  • 和C++ 相比,我為什麼要選擇 Rust 來開發軟體?
    Rust 可以構建強大的 Web 應用程式Rust 越來越像是構建 Web 應用程式的不錯選擇之一,其中有些應用程式提供的功能是使用 JavaScript(Web 應用程式常用語言)無法實現的。Rust 可以編譯成 WebAssembly,它以接近原生的速度在每個主要的 Web 瀏覽器中運行。
  • Rust可太香了!AWS為此拿下其編譯器團隊負責人
    AWS 高級軟體工程經理 Shane Miller 表示:「我們不僅為 Tokio 和 Rust 編譯器僱用了幾個人。 「Rust 是我們長期戰略的關鍵組成部分,我們正在投資以提供 Amazon 規模的 Rust 工程。這包括開發人員工具、基礎設施組件、互操作性和驗證。」
  • AWS偏愛Rust,已將Rust編譯器團隊負責人收入囊中
    AWS 高級軟體工程經理 Shane Miller 也表示,他們聘用這些人並不只是為了 Tokio 和 Rust 編譯器。Rust 是 AWS 長期發展戰略的重要組成部分,他們正投入資金以在亞馬遜實現全面的 Rust 工程開發,其中包括開發者工具、基礎設施組件、互操作和驗證等。
  • Rust 語言入門
    最近的一項 Stack Overflow 調查 發現,近 80% 的受訪者都喜歡或希望使用 Rust 語言進行開發。這個數字令人難以置信!那麼 Rust 有什麼益處呢?本文探討這種類似 C 的語言的精彩亮點,演示為什麼它應該是您要學習的下一種語言。Rust 及其家譜首先,讓我們快速了解一下它的發展歷史。
  • 兩種開發 RFID 應用程式的方法分析
    在本文中,我將首先討論兩種開發 RFID 應用程式的方法:傳統方法和 RFID Web服務。然後,我將討論把 RFID Web服務集成到多個 SOA 中的 EAI 應用程式將如何提高帶 RFID 標記的物品、盒子和託盤的可見性,並將提供有關它們的解決辦法的信息。我將演示如何跨多個 SOA 將 RFID Web服務集成到 EAI 應用程式中。
  • Rust 語言常用技巧匯集
    rustup update可以隨時獲取最新代碼Clippy可以在代碼中捕獲各種lints,並檢查代碼是否符合rust慣用寫法,地道不地道、高效不高效?。同樣的可以用rustfmt.toml來配置rustfmt的風格:cargo fix工具可以自動修復編譯器中警告項。
  • ARM/uClinux應用程式的開發
    更適合於資源緊張的嵌入式系統(上回分解已經說了,應用程式很大一部分是在和庫函數打交道,而且大家最終是鏈在一起,所以庫函數大了,你的程序也小不了)。  於是基於這種開發模式的應用程式開發變成了linux下的程序開發。
  • Python在實時嵌入式系統開發中的主要應用
    樹莓派和Arduino應用Python的的例子實在是多,比如,利用Raspberry Pi的硬體和Python語言來完成一個機器人製作。實際上如今,Python可以直接進行單片機的開發了! 用Python語言開發STM32單片機 MicroPython基於ANSI C,語法跟Pyton 3基本一致,可以通過Python腳本語言開發單片機程序。
  • 微軟解釋為什麼 Rust 是系統編程的最佳選擇
    在該系列最新一篇文章中,MSRC 團隊首席雲開發布道師 Ryan Levick 解釋了為什麼他們認為 Rust 程式語言目前是業界採用的最佳選擇,不僅僅是因為它能夠以內存安全的方式編寫系統級程序。「首先,已經有很多出色的內存安全語言在微軟內外廣泛使用,包括 .NET 語言(像是 C# 或 F#)和其他語言(例如 Swift、Go 和 Python)。
  • 華為終於放出方舟編譯器原始碼,網友:硬核項目
    方舟編譯器開源了什麼?方舟編譯器,是華為歷時十多年研發出的編譯器,是一種靜態的編譯方式,於今年4月份正式對外公布。現有的安卓系統,運行一個應用程式首先啟動虛擬機,然後讀入應用代碼逐條解釋執行,無法做到100%做到擺脫虛擬機,這也是當前安卓陣營面臨的問題。
  • Linux下C應用程式開發
    本文介紹了在 Linux 下能用於 C 應用程式開發和調試的工具. 本文的主旨是介紹如何在 Linux 下使用 C 編譯器和其他 C 編程工具, 而非 C 語言編程的教程.  GNU C 編譯器  GNU C 編譯器(GCC)是一個全功能的 ANSI C 兼容編譯器. 如果你熟悉其他作業系統或硬體平臺上的一種 C 編譯器, 你將能很快地掌握 GCC. 本節將介紹如何使用 GCC 和一些 GCC 編譯器最常用的選項.
  • 編譯器 | 五款好用的C/C++編譯器(IDE利器)
    最後放了手機可編譯的APP,為方便下載都放在了雲盤方便各位直接拿來使用IDE 主要是在程式設計師開發時提供各種軟體應用組件,最受程式設計師受歡迎的 IDE 都有一個共同點,那就是非常有吸引力的用戶界面。這裡我們收集了一些最好的 C 和 C++ 的 IDEs 和編譯器。
  • 淺談嵌入式MCU軟體開發之SEGGER實時傳輸(RTT)的移植和printf()重定向應用(附S32K144移植工程)
    1.2 基於目標MCU內存中RTT控制塊結構體實現實時數據讀寫管理1.5 RTT支持的內核和與上位機軟體通信連接以及文本顏色輸出2.本文就給大家詳細介紹一下SEGGER RTT的實現原理和應用以及其在NXP S32K1xx MCU平臺(以S32K144為例)上的移植方法和過程,希望對大家有所幫助和啟發。SEGGER的實時傳輸(RTT)是一種用於嵌入式應用程式中的交互式用戶I / O的技術。它以很高的性能結合了SWO和半主機的優點。
  • 15 款最好的 C/C++ 編譯器和集成開發環境
    今天我們主要討論的是兩大古老而又流行的語言: C 和 C++ ,它們有著許多卓越的特性,更高效的功能和支持工具。現在這兩種語言依然那麼活躍,因為它們的 rubout 函數集提供了巨大的安全保障,可靠性非常強。今天我們圍繞的主角是一些超級棒的 C 和 C++ 的集成開發環境(IDE)和編譯器。
  • 學術界開始從Python轉向Rust
    關注用戶使用體驗「為了提高語言的影響力,Rust 開發人員著重對用戶體驗進行了優化。」Manish Goregaokar 說,他是 Rust 開發人員工具團隊的負責人,現居加州伯克利。例如,編譯器會產生信息特別豐富的錯誤消息,甚至會突出顯示出錯的代碼並給出修復建議。
  • aPaas與低代碼又是如何促進應用程式開發現代化的?
    隨著aPaaS市場預計將從 2018 年的近 90 億美元增長到 2023 年的約 117 億美元,更加注重成本、效率的企業用戶可能會見證aPaaS產品的擴展壯大。什麼是aPaaS?aPaaS代表應用程式平臺即服務,是一類雲計算服務。aPaaS中的「a」=應用程式或商業軟體。PaaS =平臺即服務(PaaS)。
  • 一行代碼都不用,你也可以構建App!谷歌收購無代碼應用程式開發平臺AppSheet
    近日,Google以未公開的價格收購了無代碼應用開發平臺AppSheet,AppSheet執行長表示,現有的AppSheet服務不會很快消失,但最終會遷移到Google Cloud。戳右邊連結上 新智元小程序 了解更多!新年伊始,Google就開啟了瘋狂收購模式。
  • C語言學習:C語言編譯器和IDE的選擇(有資源)
    這就需要一個工具,將C語言代碼轉換成CPU能夠識別的二進位指令,也就是將代碼加工成 .exe 程序;這個工具是一個特殊的軟體,叫做編譯器(Compiler)。編譯器能夠識別代碼中的詞彙、句子以及各種特定的格式,並將他們轉換成計算機能夠識別的二進位形式,這個過程稱為編譯(Compile)。
  • 華為方舟編譯器深入解讀:已有45款第三方應用
    通過多語言統一IR表示,方舟編譯器可實現應用中多種程式語言聯合編譯優化提升性能,而且在支持多平臺的同時,根據設備特徵提供便捷的開發與部署策略提升效率。華為方舟編譯器提供了全新的系統及應用的編譯和運行機制,從動態編譯變為靜態編譯,就是直接將高級語言直接編譯成機器碼,徹底消除了虛擬機動態編譯的額外開銷,實現了開發和運行效率的兼容並舉。