「走過」微軟、優步,老工程師告訴你哪些數據結構和算法最重要

2020-12-19 機器之心Pro

作者:Gergely Orosz

機器之心編譯

參與:小舟、杜偉

數據結構和基礎算法作為計算機科學的必學課程,近幾年卻關注度越來越少。但程式設計師真的不再需要這兩門基礎知識了嗎?一位在 Uber 等科技公司工作過的開發者分享了他的一手經驗,告訴你實際工作中會用到哪些數據結構和算法。

日常工作中,你經常使用算法和數據結構嗎?曾就職於 Uber 等科技公司的工程師 Gergely Orosz 提出了這樣一個問題。此外,他也注意到,越來越多的人覺得算法是無用的,並認為它們只是科技公司提出的一種強制性措施罷了。

本文作者 Gergely Orosz。

不僅如此,也有更多的人抱怨稱算法只是純粹的學術練習。在 Homebrew 作者 Max Howell 發表他的谷歌面試經歷之後,這樣的想法被進一步普及。

雖然 Gergely Orosz 自己也從來不需要使用二叉樹翻轉(binary tree inversion),但是他在 Skype、Microsoft、Skyscanner 以及 Uber 工作時,每天都會遇到使用數據結構和算法的情況。

此外,他有時也需要基於這些概念編寫代碼和做出決策。最後,Gergely Orosz 藉助這些知識來理解有些事物如何和為何構建,以及如何使用或修改它們。

由此可見,數據結構和算法並不是如人們所言用處不大。在本文中,Gergely Orosz 列舉了一系列現實世界的實例,包含生產中會用到的樹、圖等數據結構和各種算法。

值得肯定的,所有這些都出自他的第一手經驗,藉此希望表達他的觀點,即通用數據結構和算法知識並不只是「為了面試」,而是你在快速成長的創新型科技公司工作時,可能會經常遇到的東西。

Gergely Orosz 表示自己曾經用過非常小的算法子集,但幾乎包含了所有的數據結構。毫不奇怪,他不喜歡繁瑣的算法以及包含紅黑樹或 AVL 樹等不常見數據類型的不切實際的面試問題。

接下來具體來看作者列舉出來的實例,以第一人稱的口吻進行講述。

樹和樹遍歷:Skype、Uber 和 UI 框架

在微軟時,當我們構建 Xbox One 遊戲機(由微軟發布)的 Skype 軟體時,我們使用的是內置作業系統 Xbox OS,但缺少關鍵庫。我們當時正在該平臺上構建首個成熟的應用程式之一,所以需要一個能夠結合觸摸手勢和語音命令的導航解決方案。

我們在微軟 WinJS 庫上構建了一個通用的導航框架。為了做到這一點,我們需要維護一個類似於 DOM(文檔對象模型)的圖來跟蹤可操作的元素。為了找出這些元素,我們執行了 DOM 遍歷,基本上是現有 DOM 上的 B - 樹遍歷(B-tree traversal)。這便是 BFS(廣度優先搜索)或者 DFS(深度優先搜索)的經典示例。

在 Uber 時,團隊構建了很多實現節點、依賴關係以及它們之間連接可視化的工具。有一個例子就是 RIB 節點的可視化工具。該可視化工具需要維護一棵樹,將它可視化為可縮放矢量圖形(SVG),然後更新這棵樹,同時行動裝置上的 RIB 樹也發生變化。RIB 自己也會為狀態管理維護一個邏輯樹結構(logical tree structure),但這個樹結構與呈現對象不同,這就是他們設計背後的關鍵所在。

RIB 樹可視化:一個使用樹來表示數據並將其可視化的經典示例。

權重圖和最短路徑:Skyscanner

Skyscanner 會找到最佳機票。為此,它掃描了全球所有的航線,並將它們匯聚在一起。由於航空公司需要考慮中轉站的選擇,所以問題的本質更多地體現在爬蟲,而不是緩存。多城市規劃選項(multi-city planning option)成為了最短路徑問題。

多城市是 Skyscanner 花費大量時間來構建的功能之一。公平地說,產品方面的困難是最多的。最佳的多城市航線選擇就是使用 Dijkstra 或者 A * 這樣的最短路徑算法計算的。

航線用一張有向圖來表示,每條邊都有一個表示票價的權重,算出兩個城市之間票價最便宜的航線就是通過每條航線的改進版的 A * 搜索算法實現的。

但是使用 Skyscanner,實際算法就不那麼重要了。緩存、爬蟲和處理各種網站負載比解決問題本身要難得多。即便如此,最短路徑問題的變體還是在許多基於組合優化價格的旅行公司中使用。

排序:Skype

對於排序這種算法,我很少需要自己實現或深入使用。理解不同類型的排序方法是件很有趣的事,包括冒泡排序、插入排序、歸併排序、選擇排序以及最複雜的快速排序。但是,我還是很少需要自己手動實現這些算法,甚至從來沒有把排序函數作為庫的一部分來編寫。

在微軟 Skype 時,我練習了這方面的知識。另有一位工程師決定為聯繫人列表實現插入排序算法。2013 年,Skype 實現了聯網,網絡用戶呈爆炸式增長,而且用戶數還在持續增長。因此這位工程師認為用插入排序按照用戶姓名來構建聯繫人列表,性能會更佳。

關於為什麼不單單使用默認排序算法這一問題,我們也經過了反覆討論。最後結論是,使用默認排序算法需要對實現進行適當的測試和相應基準測試,這可能需要更多的工作。我個人認為這樣做沒有多大意義,並且當時我們正處在項目階段,有很多時間,所以採用了基於聯繫人列表的插入排序算法。

在現實世界中,一定有一些情況,使用高效的排序算法非常重要,並且基於數據選擇使用的排序算法會更加有效。在執行大規模實時數據流並且為這些數據源構建實時可視化時,插入排序很有用。

如果涉及到存儲在不同節點上的大量數據,那麼「分而治之」的歸併排序算法比較合適。我自己沒有使用過這些算法,因此了解這幾種不同的算法之外,我仍然會標記一些自己沒有用過的排序算法。

哈希表和哈希:隨處常見

我最常用到的數據結構就是哈希表以及哈希函數了。從計數、重複檢測、緩存到分片(sharding)之類的分布式系統用例,都會用到這種很方便的工具。

除了數組之外,在很多情況下用哈希表和哈希函數都是非常合適的。幾乎每種語言都會用到這種數據結構,而且它的實現很簡單。

棧和隊列:偶爾用到

任何調試過具有堆棧追蹤的語言的人都非常熟悉這種數據結構。我在使用這種數據結構時遇到了一些問題,但調試和性能分析讓我慢慢熟悉了它。

我很少在自己的代碼中使用隊列這種數據結構,但卻在代碼庫、代碼 pop 和 push 中遇到過很多次。對於分析和配置 builds 的安裝瓶頸檢測器工具而言,我會使用 Python 堆隊列(heap queue)算法來讀優先隊列優化後的代碼。

加密算法:Uber

Uber 很早就使用了幾種語言和技術,並且加密(cryptography)並不能實現我們需要的穩定性。典型的示例就是 iOS 和安卓。來自客戶端用戶輸入的敏感信息在通過網絡發送之前需要加密,同時僅針對特定服務進行解密。

在某些情況下,我們必須自己構建加密 / 解密實現。但在缺少支持框架或沒有可用審核庫的情況下,我們需要對其進行正式的驗證和審核。

構建加密算法總是充滿樂趣。在實現加密算法上存在許多挑戰:你想不出一種實現加密技術的新算法。取而代之的是,你將採用適合案例的現有的已成文的標準,然後驗證並一遍又一遍地審核它。

這種情況就是在實現 AES 標準。這是一個有趣的挑戰。我們已經構建了一些移動端和網頁端的加密實現,其中我自己深入學習了高級加密標準(AEP)、哈希消息身份驗證碼(HMAC)以及 RSA 公鑰加密的詳細知識。

研究攻擊媒介(如消息篡改或拒絕服務的影響)是審核解決方案的一部分。驗證一系列加密步驟是否可以證明是安全的,這

也是一件有趣的事。

只要證明 Encrypt-and-MAC(EaM)、MAC-then-Encrypt(MtE)和 Encrypt-then-MAC(Etm)三者有一個是安全的即可,但這並不意味著其他的是不安全的。

概率論與預測:Uber 的 SubmitQueue

2016 年,我加入了 Uber。移動端最大的痛點是構建以及合併更改需要花費的時間。從構建和所有測試(單元、集成和端到端)開始,構建一個完整的運行大約需要 40 分鐘。我們在開發中投入了大約 300 個開發者。所有的更改必須在落地之前搭建完成。

我旁邊的開發者體驗團隊想解決以下問題,他們從兩個角度做到了。首先,他們加快了構建和測試過程,耗時不超過 30 分鐘;其次,他們的目標是每個人的變更應該花費 30 分鐘,現有時間的 95%。

但是合併衝突呢?讓我們對其進行預測,並相應地建立隊列。這就是他們通過創建衝突和推測圖所做的事情。

帶有層次化索引的六邊形網格:Uber

這是我沒有參與的最後一個項目,但是我發現並使用了基於它的工具。在這裡,我了解了一種新的數據結構:帶有層次化索引的六邊形網格。

Uber 要解決的最困難和最有趣的問題之一就是優化行程價格以及合作夥伴的調度。價格是動態的,驅動程序也在不斷變化。H3 是 Uber 工程師構建的網格系統,旨在以越來越細化的水平可視化和分析整個城市的數據。數據可視化結構就是帶有層次化索引的六邊形網格。

總結

這些是我多年來在多家公司中實際使用的算法和數據結構的重點。

要在一家高科技公司工作,你不需要了解流行算法或是外來數據結構的工作原理。你應該了解算法是什麼,並且能夠自己提出一些簡單的算法,例如貪婪算法。你還應該了解更多常見的基本數據結構,例如哈希表、隊列、棧等等。但是你不需要記住 Dijkstra 或者 A* 這樣特殊的算法。

你可以將它們作為參考,就像我實現加密算法時一樣。對待紅黑樹或 AVL 樹等一些不常見的數據結構也應如此。我從未用過這些數據結構。即使我用過,也不會反覆查看它們。我也從來沒有問過需要使用這些知識才能解決的問題,將來也不會。

我一直在尋求一些實際的編碼例子,因為實際的例子中會有很多好的解決方案,比如暴力枚舉、貪心算法或其他一些更複雜的算法。比如,有些問題,你只需要一個數組和一些 if/else 語句就可以解決問題,而無需任何複雜的數據結構。

現實情況是,許多團隊和公司都面臨算法的挑戰。應該看到,算法問題具有很大的吸引力,它們能夠在 45 分鐘或者更短的時間內給出信號,並且輕鬆地轉換問題。因此問題洩漏帶來的影響並不會很嚴重。

招聘也比較容易。因為你可以擁有 100 多個問題的問題庫,任何面試官都可以評估其中的任何一個。特別是在矽谷,聽到動態編程和特殊數據結構問題的情況越來越多。這些問題將有助於聘請強大的工程師,但同時也會導致將那些本不需了解一些複雜算法但卻非常優秀的人拒之門外。

原文連結:https://blog.pragmaticengineer.com/data-structures-and-algorithms-i-actually-used-day-to-day/

相關焦點

  • 我們到底該如何學習《數據結構與算法》
    前言:我們到底該不該學習算法與數據結構?1、真的應該學習這個問題本身就不是個問題,所有人都在強調數據結構與算法比較重要,但是好像平時也沒用到,無法直觀的去感受它的重要性,於是把學習重心放在了常見的哪些框架身上,似乎只要熟悉了哪些框架的API,編程就會所向披靡。
  • 20 萬、50 萬、100 萬年薪的算法工程師在能力素質模型上有哪些差距?
    在回答時,儘量不要用一些似是而非的諸如「項目經驗豐富」、「工作年頭長」、「在大平臺工作」、「背景好」、「聰明」、「學習能力強」等看似有理,其實在操作中全無用處的維度來回答;2.儘量使用定量,或者至少是定性的要素來界定,比如「主導過什麼性質什麼級別的項目」,「在算法建模或算法優化中的具體表現和指標」,「處理的數據量級和複雜非標程度」,「為實際的業務帶來怎樣的增長和價值提升」等等;3.
  • 「讀書筆記」《漫畫算法》:克服對算法的恐懼,從漫畫開始
    書裡從算法和數據結構的定義和概念說起,再到時間空間複雜度的介紹,到數據結構基礎,比如數組,鍊表,隊列。最後才是一些具體的算法問題。「如果作為一個完全沒接觸過「程式設計師小灰」公眾號的讀者,那麼這本書的結構是很合理的。尤其適合算法的入門學習。」這裡又想說句題外話了,其實現在很多的優質文章,都在被整理成書籍並出版,我覺得並不是一個壞事。
  • 阿里三面慘遭被虐,關於數據結構與算法竟然一竅不通!
    《數據結構與算法 經典問題解析》一書,涵蓋世界知名IT公司技術面試的程序設計問題及其解題思路解析IT頂尖企業(微軟、谷歌、亞馬遜、雅虎、臉譜、蘋果、Adobe )的面試過程,針對不同問題,提供多個具有不同複雜度的解決方法。兼顧自學教材和面試輔導的不同需求。
  • 「機器學習」機器學習算法優缺點對比(匯總篇)
    「換言之,就是沒有算法能完美地解決所有問題,尤其是對監督學習而言(例如預測建模)」。舉例來說,你不能去說神經網絡任何情況下都能比決策樹更有優勢,反之亦然。它們要受很多因素的影響,比如你的數據集的規模或結構。其結果是,在用給定的測試集來評估性能並挑選算法時,你應當根據具體的問題來採用不同的算法。
  • JAVA必須掌握的數據結構和算法
    常見的數據結構鍊表LinkedHashSet LinkedList 底層數據結構由鍊表和哈希表組成。數據的添加和刪除都較為方便,就是訪問比較耗費時間。數組ArrayList 訪問數據十分簡單,而添加和刪除數據比較耗工夫堆堆是一種圖的樹形結構,被用於實現「優先隊列",優先隊列是一種數據結構,可以自由添加數據,但取出數據時要從最小值開始按順序取出
  • 數據結構與算法在現實中毫無作用?那我們為什麼還要去學習?
    如果公司在日常工作中沒有用,為什麼公司會問與數據結構和算法有關的問題? 許多初學者和經驗豐富的程式設計師都避免學習數據結構和算法,因為它很複雜,而且他們認為現實生活中沒有使用上述所有內容。
  • 面向自然語言和多步推理問題,新型問答數據集HotpotQA面世
    作者張賽崢目前博士就讀於蒙特婁大學,師從 Yoshua Bengio 教授從事深度學習和自然語言處理方面的研究。HotpotQA 數據集的作者寫了一篇博客,介紹了這個「讓人看餓了」的數據集:你是否好奇過以下問題:我們都知道 Facebook 總部在加州,那你知道 Facebook 的誕生地在哪個城市嗎?
  • Python,Java,C++一網打盡,這個GitHub項目用多種語言實現經典算法
    機器之心報導參與:Racoon、Jamin經典數據結構和算法你了解幾個?想去大廠面試?想成為算法工程師?收下這份全面的複習材料。不想做低級碼農,不想成為前端摳圖達人或是後臺「增刪改查」小王子?那你可能需要好好複習下算法與數據結構。想成為算法工程師,基礎知識是繞不開的大山。機器之心這次要推薦的項目是數據結構與算法的開源項目集,覆蓋多種主流語言,實現各類經典數據結構及算法。
  • AI算法可以消除「馬賽克」?網際網路大廠的算法崗OFFER如何拿到?
    那AI算法真的那麼厲害嗎?想要做算法崗,需要做哪些準備?一、算法工程師是做什麼的?提到算法工程師,大家都知道他的薪資水平比其他開發崗要高,很多大廠都開出了年薪幾十萬的薪資去吸引算法崗的高端人才。幾十萬的年薪 你心動嗎?那算法崗具體會做什麼呢?一則知乎高贊答案告訴你:「如果要我用一句話來簡單說算法工程師是做什麼的,那就是,用機器學習的方法來實現人工智慧和數據挖掘。」
  • 微軟和谷歌在SuperGLUE榜單上暴錘人類!用「字生圖」只是前菜
    話說昨天,人類受到了來自AI的2021第一波挑釁:OpenAI的DALL-E 和 CLIP。你只要來段文字命令:給我來個「穿著藍色襯衫和黑色打褶褲的男模特。」叮咚!請查收:數十張對應圖片便出現眼前。想起去年GPT-3橫空出世時,就有人預測AI正逐漸取代文字工作者,小編也自覺飯碗不保。現在,又輪到插畫師出來哭訴了。
  • 成為一名產品結構工程師需要掌握哪些技能
    在決定踏上成為一名產品結構工程師的開始,大家都很迷茫,因為這份職業不像其它職業,在大學有完全對口的專業,更多是相關專業的人轉行過來,比如機械設計師,工業設計師,模具設計師,數控等等人才轉到產品結構設計。
  • 連續四年萬人參賽,騰訊廣告算法大賽逆算賽題火了,冠軍:我用BERT
    毫不誇張地說,騰訊廣告算法大賽已經成為了全球最受矚目的算法競賽之一。當前,大數據技術與應用逐漸成為營銷鏈路上不可或缺的一環,隨之衍生的數據競賽也成為了各家企業探索前沿課題、吸納人才的重要方式之一。本屆騰訊廣告算法大賽則另闢蹊徑,針對廣告行業的經典假設,出具了一道「逆向思維」的全新賽題。
  • 7 Papers & Radios | 微軟亞研麻將AI「Suphx」技術細節
    AI「Suphx」。繼圍棋、德州撲克、Dota、星際爭霸之後,微軟亞洲研究院的「Suphx」創造了 AI 在遊戲領域的另一跨越性突破——麻將。Suphx 代表著 AI 系統在麻將領域取得的最好成績,它也是首個在國際知名專業麻將平臺「天鳳」上榮升十段的 AI 系統,其實力超越了該平臺與之對戰過的 99.9% 的人類選手。
  • 手敲一遍數據結構和排序算法
    排序算法 性質記憶 冒泡排序 選擇排序 插入排序 快速排序 歸併排序 希爾排序 堆排序數據結構 數組 堆 棧 隊列 鍊表 二叉樹 二叉搜索樹 圖 哈希表搜索 廣度優先搜索 深度優先搜索附件 排序算法代碼點擊
  • 谷歌發布地圖「時光機」:100年前,你家街道長啥樣?
    魚羊 發自 凹非寺量子位 報導 | 公眾號 QbitAI10年前,乃至100年前,你長大的那條街道長什麼樣?△大谷Spitzer現在,除了用AI修復老影像資料,谷歌還發布了新的「時光旅行」方案。
  • 「不厚道」的豐巢、「真實」的網民和「次世代」的社交
    從以上數據來看,低齡、中低學歷、中等收入是如今網民群體的主要特徵。學歷不高、收入不高等現象也與網絡上年輕人居多有關,被譽為「網生一代」的「零零後」目前也仍在求學階段,數據似乎可以解釋。Teams 每日會議人數到 2 億 微軟「騰雲」而起受疫情影響,「跌跌不休」成了科技股的常規動作。但是,也有一些公司,似乎並未受到影響。
  • 算法有沒有價值觀?知乎內容推薦算法解析
    本文詳細介紹了知乎算法是如何通過識別垃圾廣告導流信息、識別低質量回答並處理違規信息的,想必對業內不少工程師會有借鑑意義。算法在社區氛圍的應用(一):識別垃圾廣告導流信息近期,我們發現社區內出現了垃圾廣告的導流內容,影響用戶體驗,破壞認真、專業和友善的社區氛圍。為了解決這種情況,我們進行了大量努力和探索。
  • 編程世界中的18個重要的算法
    下面是一些比較重要的算法,原文羅列了32個,但我覺得有很多是數論裡的,和計算機的不相干,所以沒有選取。下面的這些,有的我們經常在用,有的基本不用。有的很常見,有的很偏。