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

2020-12-08 澎湃新聞

作者: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/

Amazon SageMaker 是一項完全託管的服務,可以幫助開發人員和數據科學家快速構建、訓練和部署機器學習 模型。SageMaker完全消除了機器學習過程中每個步驟的繁重工作,讓開發高質量模型變得更加輕鬆。

現在,企業開發者可以免費領取1000元服務抵扣券,輕鬆上手Amazon SageMaker,快速體驗5個人工智慧應用實例。

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

閱讀原文

相關焦點

  • 「走過」微軟、優步,老工程師告訴你哪些數據結構和算法最重要
    一位在 Uber 等科技公司工作過的開發者分享了他的一手經驗,告訴你實際工作中會用到哪些數據結構和算法。日常工作中,你經常使用算法和數據結構嗎?曾就職於 Uber 等科技公司的工程師 Gergely Orosz 提出了這樣一個問題。此外,他也注意到,越來越多的人覺得算法是無用的,並認為它們只是科技公司提出的一種強制性措施罷了。
  • 我們到底該如何學習《數據結構與算法》
    前言:我們到底該不該學習算法與數據結構?1、真的應該學習這個問題本身就不是個問題,所有人都在強調數據結構與算法比較重要,但是好像平時也沒用到,無法直觀的去感受它的重要性,於是把學習重心放在了常見的哪些框架身上,似乎只要熟悉了哪些框架的API,編程就會所向披靡。
  • 優步:工具是AI開發和部署的關鍵
    蓋世汽車訊據外媒報導,日前,在談及優步在全球數據中心使用AI和物聯網技術時,優步首席科學家Zoubin Ghahramani表示,優步採用數千個機器學習模型,以獲取其業務的全方位信息。(圖片來源:venturebeat.com)Ghahramani表示,與普遍看法相反,在優步,自動駕駛汽車並不是AI和機器學習最主要的驅動力。該公司的大部分算法旨在處理優步出行應用之間的自然語言交互,並檢測欺詐和其他問題。例如,今年5月,優步推出了一款AI系統,可驗證駕駛員是否佩戴了口罩。
  • 前端學習數據結構與算法系列(一):初識數據結構與算法
    前言作為一個對算法沒有任何認知,非科班出身的前端程式設計師,如果想提高自己的能力,不再只寫業務代碼當一個應用工程師,算法是必須掌握的一門本領。算法也是一種思想,當你去讀一些優秀框架的源碼,如果對算法和數據結構一無所知,讀起來很困難,你無法理解人家為什麼要那樣寫,那樣寫的好處是什麼,接下來就跟大家分享下作為一個前端程式設計師,如何學習數據結構與算法。
  • 數據結構和算法 四階段 72 篇總結!
    在所有基本功中,最核心的一定是數據結構與算法。最適用於工程師的算法課,口碑特別好。這個專欄幫到挺多人的,我隨便截了幾個,你可以看看。王爭根據自己研讀數十本算法書籍和多年項目開發的經驗,精選了 20 個最實用數據結構和算法結合具體的軟體開發實例,由淺入深進行講解背後的設計思想,並適時總結一些實用「寶典」,保證你印象深刻,並且能夠迅速對應到實際工作場景中。
  • 數據結構和算法學習指南
    首先,這裡講的都是普通的數據結構和算法,咱不是搞競賽的,野路子出生,只解決常規的問題,以面試為最終目標。另外,以下是我個人的經驗的總結,沒有哪本算法書會寫這些東西,所以請讀者試著理解我的角度,別糾結於細節問題,因為這篇文章就是對數據結構和算法建立一個框架性的認識。
  • 谷歌微軟等科技巨頭數據科學面試107道真題:你能答出多少?
    選自Learndatasci機器之心編譯參與:李澤南來自 Glassdoor 的最新數據可以告訴我們各大科技公司最近在招聘面試時最喜歡向候選人提什麼問題。首先有一個令人惋惜的結論:根據統計,幾乎所有的公司都有著自己的不同風格。由於 Glassdoor 允許匿名提交內容,很多樂於分享的應聘者向大家提供了 Facebook、谷歌、微軟等大公司的面試題。
  • 我們為什麼要學習數據結構和算法?
    對於我們來說,數據結構和算法是那麼熟悉,又是那麼陌生。作為計科院的學生,大學裡都接觸過,但是進入社會以後,我們看起來很少會用到這個。這時候不僅會想到一件問題,學習數據結構和算法真的有用嗎?不學習這個就不能做開發了嗎?在當今的IT行業裡面,有些人不懂數據結構和算法,也能做一輩子的開發,這沒啥毛病,但是兄弟們,開發是開發,那可不是研發啊。
  • 算法與算法工程師,技術與技術人員
    (註:標題裡的算法,指機器學習算法,或者說「算法工程師」這個職位名稱裡的「算法」,不是「算法與數據結構」裡的那個算法。誰能告訴我有沒有什麼更好的名字來區別這它們,或許是「機器學習算法」與「傳統算法」?)算法與算法工程師先來一段我在知乎裡回答「做算法工程師是一種怎樣的體驗?」
  • 面試經驗分享之數據結構、算法題
    前言面試 IT 企業的研發崗位,數據結構和算法顯然是必考的項目。俺只學過普通的數據結構課程,沒讀過 STL,也沒有過 ACM 的訓練和比賽經歷,在一開始面對這樣類型題目的時候,心裡還是十分忐忑的。大大小小几十場面試下來,自己在這方面總算有了一定的心得積累,在此拋磚引玉, 以饗讀者。
  • 快速入門數據結構和算法
    阿里妹導讀:有哪些常見的數據結構?基本操作是什麼?常見的排序算法是如何實現的?各有什麼優缺點?
  • 算法工程師思維導圖 | 數據結構與算法
    算法工程師思維導圖,求職/自我提升/查漏補缺神器。該手冊一共分為數據結構與算法、數學基礎、統計機器學習和深度學習四個部分。點擊這裡查看具體使用指南。該手冊有兩種獲取方式:下面是數據結構與算法部分~數據結構二維矩陣/直方圖最大距形面積矩陣最大面積:https://leetcode-cn.com/problems/maximal-rectangle/solution/zui-da-ju-xing-by-leetcode/
  • 「3步套路」快速掌握機器學習算法和模型 | 極客時間
    然而,機器學習領域浩如煙海,各類教材和入門課程層出不窮。特別是機器學習基礎需要不少的數學知識,這對於想進入這一領域的工程師而言,無疑是一個比較高的門檻。今天,我來和你聊一聊如何學習和掌握機器學習基礎知識,又如何通過核心的知識脈絡快速掌握更多的機器學習算法和模型。
  • 算法推薦組:數據平臺(高級)工程師等
    大數據處理/分析(高級)工程師20k-40k 北京 經驗1-3年 本科及以上 全職 職位描述:從海量的用戶行為數據中,發現和驗證用戶行為特徵,提出評估方法,指導算法和產品改進。建設在線實驗平臺,統計分析報表。對數據敏感,崇尚從數據發現問題,提出方案並驗證上線,從而解決產品問題的端到端模式和綜合能力。
  • 考研計算機 | 數據結構—結構算法
    2021計算機考研數據結構—結構算法算法的設計取決於數據(邏輯)結構,而算法的實現依賴於採用的存儲結構
  • 圖解:數據科學家、數據工程師和軟體工程師之間的區別
    對於新手,也可以通過這張圖來看典型的「數據科學家」、「數據工程師」和「軟體工程師」都要掌握哪些工具。Jake Stein:隨著數據的爆炸式增長,對數據處理的專家技能需求也隨之井噴。這帶來的結果之一,是更精細的分工。對於數據管理工作的核心角色:數據科學家、數據工程師和軟體工程師,過去幾年見證了他們越來越清晰的定位。
  • 數據結構與算法?看這篇就夠了!!!
    我們可以學習很多語言,很多框架,但招聘不會考你用5種語言10種框架實現同一個功能。真正讓程式設計師有區分度,企業招聘萬年不變的重點 —— 算法與數據結構但無論半路出家還是科班出身,除學生時代搞算法競賽的同學外真正用心學習過算法與數據結構太少太少對於後期想要學習算法與數據結構卻不得不面對以下問題:於是我們推出了「數據結構與算法365天特訓營」實時視頻直播
  • 算法與數據結構?看這篇就夠了
    我們可以學習很多語言,很多框架,但招聘不會考你用5種語言10種框架實現同一個功能。真正讓程式設計師有區分度,企業招聘萬年不變的重點 —— 算法與數據結構但無論半路出家還是科班出身,除學生時代搞算法競賽的同學外真正用心學習過算法與數據結構太少太少對於後期想要學習算法與數據結構卻不得不面對以下問題:於是我們推出了「數據結構與算法365天特訓營」實時視頻直播
  • 算法工程師研發技能表
    Learning Lab    由於算法工程師這個崗位根據不同的業務場景和應用方向,各自的工作差異相對較大。所以很難有一個一概而論的算法工程師技術棧。比如說做圖像方向的有機器視覺算法崗、做文本方向的有自然語言處理算法崗、做語音的又有語音識別算法崗。本文僅對算法工程師常用的、基礎的、必備的研發技能進行梳理。也就是說,不論你是做哪個業務場景下的算法工作,這些基礎研發技能都是必知必會的。這組技能清單主要包括兩大類型,一類是理論技術,另一類是程式語言和工具類。
  • 算法工程師都有哪些分類?
    圖像算法工程師,圖像處理工程師,音/視頻處理算法工程師,計算機視覺工程師(1) 精通DirectX HLSL和OpenGL GLSL等shader語言,熟悉常見圖像處理算法GPU實現及優化;(2) 語言:精通C/C++;(3) 工具:Matlab數學軟體,CUDA運算平臺,VTK圖像圖形開源軟體【醫學領域:ITK,醫學圖像處理軟體包】(4)