1. 程式人生 > >【技術思路】極客時間-左耳聽風-開篇詞1

【技術思路】極客時間-左耳聽風-開篇詞1

開篇詞 | 洞悉技術的本質,享受科技的樂趣

01 | 程式設計師如何用技術變現(上)

  • 獨立:沒有必要通過打工聽人安排而活著,而是反過來通過在公司工作提高自己的技能,讓自己可以更為獨立和自由地生活。

  • 思考:留出更多的時間,去研究公司裡外那些更為核心更有技術含量的技術。

02 | 程式設計師如何用技術變現(下)

  • 學習力:能夠掌握大多數人不能掌握的技能或技術,學習更多別人沒有的經驗和經歷。
  • 洞察力:能夠分辨出什麼是主流技術,什麼是過渡式的技術。
    • 關注市場需求:看看各個公司都在做什麼,他們的難題是什麼。
    • 關注技術趨勢:要看清技術趨勢,你需要了解歷史。要看一個新的技術是否順應技術發展趨勢,就需要將一些老技術的本質吃得很透。
    • 學習技術過程中一定要多問自己兩個問題:“一、這個技術解決什麼問題,為什麼同類的技術做不到?二、為什麼是這樣解決的,有沒有更好的方式?”
    • 一個新技術出現時,後面一定會有大型的商業公司支援,這類公司支援得越多,就說明越需要關注。
  • 尋找環境:找到能體現自身價值的高速發展公司,大公司技術架構和業務已經定性,高階技術人員很多,無法體現出價值。剛起步的公司,精力放在業務擴充套件上,不需要高精尖的技術。並不排除大公司中找到高速發展的業務。
  • 動手能力:動手能力很重要,程式碼裡全是細節。只有瞭解了細節,才能提出更好更靠譜、可以落地的解決方案。而不是一些籠統和模糊的東西。
  • 付費點:
    關注技術付費點。一個是能幫別人“掙錢”的地方;一個是能幫別人“省錢”的地方。
  • 提升經驗:提升自己的能力和經歷,比如你是一個很知名的開源軟體的核心開發人員,或者是某知名公司核心專案的核心開發人員。

  • 資訊收集:用好Google獲取有價值的資訊源
  • 價值觀:輸出觀點和價值觀,輸出了更先進的價值觀,才能獲得真正的影響力。
  • 朋友圈:朋友圈很重要,一個人在什麼樣的朋友圈,就會被什麼樣的朋友所影響。優質朋友圈特性:

- 這些人比較有想法、有觀點,經驗也比較豐富。
- 涉獵面比較廣
- 有或多或少的成功
- 喜歡折騰喜歡搞事的人
- 對現狀不滿,並想做一些改變
- 有一定的影響力

會掙錢的人一定是會投資的人。最寶貴的財富並不是錢,而是你的時間,時間比錢更寶貴,因為錢不用還在那裡,而時間不用就浪費掉了。把你的時間投資在哪些地方,就意味著你未來會走什麼樣的路。所以投到一些有意義的地方。

03| Equifax資訊洩露始末

作為美國三大信用報告公司中歷史最悠久的一家,Equifax 的主營業務是為客戶提供美國、加拿大和其他多個國家的公民信用資訊。保險公司就是其服務的主要客戶之一,涉及生命、汽車、火災、醫療保險等多個方面。

此外,Equifax 還提供入職背景調查、保險理賠調查,以及針對企業的信用調查等服務。由於 Equifax 掌握了多個國家公民的信用檔案,包括公民的學前、學校經歷、婚姻、工作、健康、政治參與等大量隱私資訊,所以這次的資訊洩露,影響面積很大,而且性質特別惡劣。

受這次資訊洩露影響的美國消費者有 1.43 億左右,另估計約有 4400 萬的英國客戶和大量加拿大客戶受到影響。事件導致 Equifax 市值瞬間蒸發掉逾 30 億美元。

  • 利用了其系統中未修復的 Apache Struts 漏洞(CVE-2017-5638,2017 年 3 月 6 日曝光)來發起攻擊。
  • Shodan搜尋引擎搜尋管理面板,使用者名稱和密碼都是"admin"。
  • 繞過WAF的手法。
  • GitHub
在 GitHub 上有相關的程式碼,連結為:
https://github.com/mazen160/struts-pwn
https://github.com/xsscx/cve-2017-5638

04 從Equifax資訊洩露看資料安全

回顧網際網路時代的其他幾次大規模資料洩露事件,分析背後的原因,給出解決這類安全問題的技術手段和方法。

資料洩露歷史

  • 2012:LinkedIn 在 2012 年也洩露了 6500 萬用戶名和密碼。事件發生後,LinkedIn 為了亡羊補牢,及時阻止被黑賬戶的登入,強制被黑使用者修改密碼,並改進了登入措施,從單步認證增強為帶簡訊驗證的兩步認證。

  • 2013~2014: 繼 2013 年大規模資料洩露之後,雅虎在 2014 年又遭遇攻擊,洩露出 5 億使用者的密碼,直到 2016 年有人在黑市公開交易這些資料時才為大眾所知。雅虎股價在事件爆出的第二天就下跌了 2.4%。

  • 國內也有類似的事件。2014 年攜程網安全支付日誌存在漏洞,導致大量使用者資訊如姓名、身份證號、銀行卡類別、銀行卡號、銀行卡 CVV 碼等資訊洩露。這意味著,一旦這些資訊被黑客竊取,在網路上盜刷銀行卡消費將易如反掌。

資料洩露攻擊

  • 1、利用程式框架或庫的已知漏洞。比如這次 Equifax 被攻擊,就是通過 Apache Struts 的已知漏洞。
  • 2、暴力破解密碼。利用密碼字典庫或是已經洩露的密碼來“撞庫”。
  • 3、程式碼注入。通過程式設計師程式碼的安全性問題,如 SQL 注入、XSS 攻擊、CSRF 攻擊等取得使用者的許可權。
  • 4、利用程式日誌不小心洩露的資訊。攜程的資訊洩露就是本不應該能被讀取的日誌沒有許可權保護被讀到了。
  • 5、社會工程學。第一道防線是人——員工。只有員工的安全意識增強了,才能抵禦此類攻擊。其它的如釣魚攻擊也屬於此類。

資料管理問題:

  • 1、Equifax 只是被黑客攻破了管理面板和資料庫,就造成了資料洩露。顯然這樣只有一層安全防護是不夠的。
  • 2、弱密碼。Equifax 資料洩露事件絕對是管理問題。至少,密碼系統應該不能讓使用者設定如此簡單的密碼,而且還要定期更換。最好的方式是通過資料證書、VPN、雙因子驗證的方式來登入。
  • 3、向公網暴露了內部系統。在公司網路管理上出現了非常嚴重的問題。
  • 4、對系統及時打安全補丁。監控業內的安全漏洞事件,及時做出響應,這是任何一個有高價值資料的公司都需要乾的事。
  • 5、安全日誌被暴露。安全日誌往往包含大量資訊,被暴露是非常危險的。攜程的 CVV 洩露就是從日誌中被讀到的。
  • 6、儲存了不必要儲存的使用者資料。攜程儲存了使用者的信用卡號、有效期、姓名和 CVV 碼,這些資訊足以讓人在網上盜刷信用卡。其實對於臨時支付來說,這些資訊完全可以不儲存在磁碟上,臨時在記憶體中處理完畢立即銷燬,是最安全的做法。即便是快捷支付,也沒有必要儲存 CVV 碼。安全日誌也沒有必要將所有資訊都儲存下來,比如可以只儲存卡號後四位,也同樣可以用於處理程式故障。
  • 7、密碼沒有被合理地雜湊。以現代的安全觀念來說,以明文方式儲存密碼是很不專業的做法。進一步的是隻儲存密碼的雜湊值(用安全雜湊演算法),LinkedIn 就是這樣做的。但是,雜湊一則需要用目前公認安全的演算法(比如 SHA-2 256),而已知被攻破的演算法則最好不要使用(如 MD5,能人為找到碰撞,對密碼驗證來說問題不大),二則要加一個安全隨機數作為鹽(salt)。LinkedIn 的問題正在於沒有加鹽,導致密碼可以通過預先計算的彩虹表(rainbow table)反查出明文。

專家建議

Contrast Security 是一家安全公司,其 CTO 傑夫·威廉姆斯( Jeff Williams)在部落格中表示,雖說最佳實踐是確保不使用有漏洞的程式庫,但是在現實中並不容易做到這一點,因為安全更新來得比較頻繁。

  • 1、理解你的軟體產品中使用了哪些支援性框架和庫,它們的版本號分別是多少。時刻跟蹤影響這些產品和版本的最新安全性宣告。
  • 2、建立一個流程,來快速地部署帶有安全補丁的軟體產品釋出版,這樣一旦需要因為安全方面的原因而更新支援性框架或庫,就可以快速地釋出。最好能在幾個小時或幾天內完成,而不是幾周或幾個月。我們發現,絕大多數被攻破的情況是因為幾個月或幾年都沒有更新有漏洞的軟體元件而引起的。
  • 3、所有複雜的軟體都有漏洞。不要基於“支援性軟體產品沒有安全性漏洞”這樣的假設來建立安全策略。
  • 4、建立多個安全層。在一個面向公網的表示層(比如 Apache Struts 框架)後面建立多級有安全防護的層次,是一種良好的軟體工程實踐。就算表示層被攻破,也不會直接提供出重要(或所有)後臺資訊資源的訪問權。
  • 5、針對公網資源,建立對異常訪問模式的監控機制。現在有很多偵測這些行為模式的開源和商業化產品,一旦發現異常訪問就能發出警報。作為一種良好的運維實踐,我們建議針對關鍵業務的網頁服務應用一定要有這些監控機制。

安全在今天是一個非常嚴肅的事,能做到絕對的安全基本上是不可能的,我們只能不斷提高黑客入侵的門檻。當黑客的投入和收益大大不相符時,黑客也就失去了入侵的意義。

安全還在於“風控”,任何系統就算你做得再完美,也會出現資料洩露的情況,只是我們可以把資料洩露的範圍控制在一個什麼樣的比例,而這個比例就是我們的“風控”。

所謂的安全方案基本上來說就是能夠把這個風險控制在一個很小的範圍。對於在這個很小範圍出現的一些資料安全的洩露,我們可以通過“風控基金”來做業務上的補償,比如賠償使用者損失等等。因為從經濟利益上來說,如果風險可以控制在一個——我防範它的成本遠高於我賠償它的成本,那麼,還不如賠償了。

05 | 何為技術領導力?

技術重要嗎?

  • 亞馬遜、Facebook 這樣的公司,最終都會去發展自己的核心技術,提高自己的技術領導力,從早期的業務型公司轉變成為技術型公司。
  • 谷歌當年舉公司之力不做技術做社交。拉里·佩奇(Larry Page)看到苗頭不對,重新掌權,把產品經理全部移到一邊,讓工程師重新掌權,於是才有了無人車和 AlphaGo 這樣真正能夠影響人類未來的驚世之作。

  • 尊重技術的公司和不尊重技術的公司在初期可能還不能顯現,而長期來看,差距明顯。

什麼是技術領導力?

技術領導力不僅僅是呈現出來的技術,而是一種可以獲得絕對優勢的技術能力。所以,技術領導力也有一些特徵,為了說清楚這些特徵,先讓我們來看一下人類歷史上的幾次工業革命。

  • 第一次工業革命:人類生產逐漸轉向新的製造過程,出現了以機器取代人力、獸力的趨勢。世界被推向了一個嶄新的“蒸汽時代”。
  • 第二次工業革命:第二次工業革命以電力的大規模應用為代表,以電燈、電報以及無線電通訊的發明為標誌。這些發明把人類推向了“電力”時代。
  • 第三次工業革命:第三次工業革命又名資訊科技革命或者數字化革命,指第二次世界大戰後,因計算機和電子資料的普及和推廣而在各行各業發生的從機械和類比電路再到數位電路的變革。

近代這幾百年的人類發展史,從蒸汽機時代,到電力時代,再到資訊時代,我們可以看到這樣的一些資訊。

  • 關鍵技術:蒸汽機、電、化工、原子能、鍊鋼、計算機,如果只看這些東西的話,似乎沒什麼用。但這些核心技術的突破,可以讓我們建造很多更牛的工具,而這些工具能讓人類幹出以前幹不出來的事。
  • 自動化:其中最重要的事就是自動化。三次革命中最重要的事就是用機器來自動化。通訊、交通、軍事、教育、金融等各個領域都是在拼命地自動化,以提高效率——用更低的成本來完成更多的事。
  • 解放生產力:把人從勞動密集型的工作中解放出來,去做更高層次的知識密集型的工作。說得難聽一點,就是取代人類,讓人失業。值得注意的是,今天的 AI 在開始取代人類的知識密集型的工作……

因此,我們可以看到的技術領導力是:

- 尊重技術,追求核心基礎技術。
- 追逐自動化的高效率的工具和技術,同時避免無效率的組織架構和管理。
- 解放生產力,追逐人效的提高。
- 開發抽象和高質量的可以重用的技術元件。
- 堅持高於社會主流的技術標準和要求。

如何擁有技術領導力?

  • 能夠發現問題:發現有方案的問題。
  • 能夠提供解決問題的思路和方案,並能比較這些方案的優缺點。
  • 能夠做出正確的技術決定:用什麼技術、什麼解決方案、怎樣實現來完成一個專案。
  • 能夠用更優雅、更簡單、更容易的方式來解決問題。
  • 能夠提高程式碼或軟體的擴充套件性、重用性和可維護性。

  • 能夠用正確的方式管理團隊:一、正確的人做正確的事,發揮每個人的潛力。二、提升團隊的生產力和人效,找到最有價值的需求,用最少的成本實現。三、不斷提高自身和團隊的標準。
  • 創新能力:能夠使用新的方法、新的方式解決問題,追逐新的工具和技術。

作為一個軟體工程師,要四個方面讓自己擁有技術領導力:

  • 紮實的基礎技術
  • 非同一般的學習能力
  • 堅持做正確的事
  • 不斷得高對自己的要求標準

06 | 如何才能擁有技術領導力?

一、基礎技術

第一、吃透基礎技術。基礎技術是各種上層技術共同的基礎。更好地理解程式的執行原理,並基於這些基礎技術進化出更優化的產品。具體分為兩個部分:程式設計和系統。

程式設計部分

  • C語言:相對於很多其他高階語言來說,C 語言更接近底層。在具備跨平臺能力的前提下,它可以比較容易地被人工翻譯成相應的彙編程式碼。
1、程式是怎麼精細控制底層資源的,比如記憶體管理、檔案操作、網路通訊……
2、需要學習組合語言,寫一些如 lock free 之類高併發的東西。那麼瞭解組合語言,就能有助於更好地理解和思考。
  • 程式設計正規化:各種程式語言都有它們各自的程式設計正規化,用於解決各種問題。比如面向物件程式設計(C++、Java)、泛型程式設計(C++、Go、C#)、函數語言程式設計(JavaScript、 Python、Lisp、Haskell、Erlang)等。
瞭解各種程式設計語言的功能特性
  • 演算法和資料結構:任何有技術含量的軟體中一定有高階的演算法和資料結構。比如 epoll 中使用了紅黑樹,資料庫索引使用了 B+ 樹……而就算是你的業務系統中,也一定使用各種排序、過濾和查詢演算法。學習演算法不僅是為了寫出運轉更為高效的程式碼,而且更是為了能夠寫出可以覆蓋更多場景的正確程式碼。

系統部分

  • 計算機系統原理:CPU 的體系結構(指令集 [CISC/RISC]、分支預測、快取結構、匯流排、DMA、中斷、陷阱、多工、虛擬記憶體、虛擬化等),記憶體的原理與效能特點(SRAM、DRAM、DDR-SDRAM 等),磁碟的原理(機械硬碟 [盤面、磁頭臂、磁頭、啟停區、尋道等]、固態硬碟 [頁對映、塊的合併與回收演算法、TRIM 指令等]),GPU 的原理等。

  • 作業系統原理和基礎:程序、程序管理、執行緒、執行緒排程、多核的快取一致性、訊號量、實體記憶體管理、虛擬記憶體管理、記憶體分配、檔案系統、磁碟管理等。

學習作業系統知識:
一是要仔細觀察和探索當前使用的作業系統
二是要閱讀作業系統原理相關的圖書
三是要閱讀 API 文件(如 man pages 和 MSDN Library),並編寫呼叫作業系統功能的程式。
這裡推薦三本書《UNIX 環境高階程式設計》、《UNIX 網路程式設計》和《Windows 核心程式設計》。
  • 網路基礎:需要了解基本的網路層次結構(ISO/OSI 模型、TCP/IP 協議棧),包括物理層、資料鏈路層(包含錯誤重發機制)、網路層(包含路由機制)、傳輸層(包含連線保持機制)、會話層、表示層、應用層(在 TCP/IP 協議棧裡,這三層可以併為一層)。
底層的 ARP 協議
中間的 TCP/UDP 協議
高層的 HTTP 協議。

《TCP/IP 詳解》,學習這些基礎的網路協議,可以為高維分散式架構中的一些技術問題提供很多的技術方案。
比如 TCP 的滑動視窗限流,完全可以用於分散式服務中的限流方案。
  • 資料庫原理:現代流行的資料庫管理系統有兩大類:SQL(基於 B+ 樹,強一致性)和 NoSQL(較弱的一致性,較高的存取效率,基於雜湊表或其他技術)。
閱讀各類資料庫圖書,並多做資料庫操作以及資料庫程式設計,多觀察分析資料庫在執行時的效能。
  • 分散式技術架構:學習分散式技術架構,包括負載均衡、DNS 解析、多子域名、無狀態應用層、快取層、資料庫分片、容錯和恢復機制、Paxos、Map/Reduce 操作、分散式 SQL 資料庫一致性(以 Google Cloud Spanner 為代表)等知識點。

二、學習能力

提高學習能力。所謂學習能力,就是能夠很快地學習新技術,又能在關鍵技術上深入的能力。

  • 學習的資訊源:常見的資訊源有 Google 等搜尋引擎,Stack Overflow、Quora 等社群,圖書,API 文件,論文和部落格等。
  • 與高手交流:通過技術社群以及參加技術會議與高手交流,也可以通過參加開源專案來和高手切磋。

  • 舉一反三的思考:瞭解了作業系統的快取和網頁快取以後,你要思考其相同點和不同點。瞭解了 C++ 語言的面向物件特性以後,思考 Java 面向物件的相同點和不同點。遇到故障的時候,舉一反三,把同類問題一次性地處理掉。
  • 不怕困難的態度:多思考,多下功夫,能夠不怕困難,並可以找到解決困難的方法和路徑,時間一長,你就能擁有別人所不能擁有的能力。
  • 開放的心態:實現一個目的通常有多種辦法。帶有開放的心態,不拘泥於一個平臺、一種語言,往往能帶來更多思考,也能得到更好的結果。而且,能在不同的方法和方案間做比較,比較它們的優缺點,那麼你會知道在什麼樣的場景下用什麼樣的方案,你就會比一般人能夠有更全面和更完整的思路。

三、堅持正確的事

堅持做正確的事。做正確的事,比用正確的方式做事更重要,因為這樣才始終會向目的地靠攏。

  • 提高效率的事:學習和掌握良好的時間管理方式,管理好自己的時間,能顯著提高自己的效率。
  • 自動化的事:程式設計師要充分利用自己的職業特質,當看見有可以自動化的步驟時,編寫程式來自動化操作,可以顯著提高效率。
  • 掌握前沿技術的事:掌握前沿的技術,有利於拓展自己的眼界,也有利於找到更好的工作。需要注意的是,有些技術雖然當下很火,但未必前沿,而是因為它比較易學易用,或者價效比高。由於學習一門技術需要花費不少時間,你應該選擇自己最感興趣的,有的放矢地去學習。
  • 知識密集型的事:知識密集型是相對於勞動密集型來說的。基本上勞動密集型的事都能通過程式和機器來完成,而知識密集型的事卻仍需要人來完成,所以人的價值此時就顯現出來了。
  • 技術驅動的事:用程式驅動的事,而且還包括一切技術改變生活的事。比如自動駕駛、火星登陸等。就算自己一時用不著,你也要了解這些,以便將來這些技術來臨時能適應它們。

四、高標準要求自己

  • Google的自我評分卡:可以參考 Google 的這個評分卡來給自己做評估,並通過它來不斷地提高對自己的要求。(該評分卡見文末附錄)。

  • 敏銳的技術嗅覺:充分利用資訊源,GET 到新的技術動態,並通過參與技術社群的討論,豐富自己瞭解技術的角度。思考一下是否是自己感興趣的,能解決哪些實際問題,以及其背後的原因,新技術也好,舊技術的重大版本變化也罷。
  • 強調實踐,學以致用:學習知識,一定要實際用一用,可以是工作中的專案,也可以是自己的專案,不僅有利於吸收理解,更有利於深入到技術的本質。並可以與現有技術對比一下,同樣的問題,用新技術解決有什麼不同,帶來了哪些優勢,還有哪些有待改進的地方。
  • Lead by Example:永遠在程式設計。不寫程式碼,你就對技術細節不敏感,你無法做出可以實踐的技術決策和方案。

  • 軟技能:良好的溝通能力、組織能力、驅動力、團隊協作能力等等。《技術領導之路》、《卓有成效的管理者》等多本經典圖書中均有細緻的講解。

附 Google 評分卡

0 - you are unfamiliar with the subject area.
0 - 你不熟悉這個學科領域。

1 - you can read / understand the most fundamental aspects of the subject area.

1 - 您可以閱讀/理解主題領域的最基本問題。


2 - ability to implement small changes, understand basic principles and able to figure out additional details with minimal help.

2 - 能夠實現小的改變,理解基本原理,並能夠在最少的幫助下找出額外的細節。

3 - basic proficiency in a subject area without relying on help.

3 - 在不依賴幫助的情況下對某一學科領域的基本熟練程度。

4 - you are comfortable with the subject area and all routine work on it:

4 - 你對主題領域和所有常規工作感覺很輕鬆:

For software areas - ability to develop medium programs using all basic language features w/o book, awareness of more esoteric features (with book).

對於軟體領域 - 有能力使用所有基礎語言的功能(無書)開發出中等程式,有更深奧的理解(帶書)。

For systems areas - understanding of many fundamentals of networking and systems administration, ability to run a small network of systems including recovery, debugging and nontrivial troubleshooting that relies on the knowledge of internals.

對於系統領域 - 瞭解網路和系統管理的許多基礎知識,執行小型系統網路的能力,包括依賴於內部知識的恢復,除錯和重要故障排除。

5 - an even lower degree of reliance on reference materials. Deeper skills in a field or specific technology in the subject area.

5 - 對參考材料的依賴程度更低。 更深入的領域技能或主題領域的特定技術。

6 - ability to develop large programs and systems from scratch. Understanding of low level details and internals. Ability to design / deploy most large, distributed systems from scratch.

6 - 

7 - you understand and make use of most lesser known language features, technologies, and associated internals. Ability to automate significant amounts of systems administration.

8 - deep understanding of corner cases, esoteric features, protocols and systems including “theory of operation”. Demonstrated ability to design, deploy and own very critical or large infrastructure, build accompanying automation.

9 - could have written the book about the subject area but didn’t; works with standards committees on defining new standards and methodologies.

10 - wrote the book on the subject area (there actually has to be a book). Recognized industry expert in the field, might have invented it.

Subject Areas:

TCP/IP Networking (OSI stack, DNS etc)
Unix/Linux internals
Unix/Linux Systems administration
Algorithms and Data Structures
C
C++
Python
Java
Perl
Go
Shell Scripting (sh, Bash, ksh, csh)
SQL and/or Database Admin
Scripting language of your choice (not already mentioned)
People Management
Project Management