個人2015技術學習流水帳

個人2015技術學習流水帳

2015年立刻就要過去了,匆匆忙忙地又是一年。回頭總結整理,發現這一年還挺充實的。在正常上班工做之餘,學習到了很多新東西,不由感到很欣慰!一個多月前就開始寫,終於趕在2016年來臨以前寫完了這篇文章…… 關於本文,儘管叫作流水帳,可是出於程序員條理性的「強迫症」,仍是進行系統分類,分類方法參照Thoughtworks技術雷達的Tecniques、Languages & Frameworks、Tools、Platforms,將其中的Tecniques改成理論。前端


1.理論

從今年開始逐漸的深刻學習計算機科學的理論,繼續按照本身確立的學習路線一步一步走下去。linux

1.1 重拾CSAPP

算上今年此次應該已經「衝擊」了兩三次CSAPP了,此次的效果還算比較滿意,幾乎讀完了厚厚的整本書,收穫頗豐!從彙編語言、計算機組成原理、編譯連接、系統編程,都算是系統的學習了一遍。具體學習筆記以下,其中(2)和(3)我的感受仍是整理的不錯滴:程序員

1.2 算法 & Leetcode

今年讀了幾本算法書,但都是按照內容編排一塊兒並行看的,都沒有看完…… 同時還動手用C++刷了一些Leetcode的題目。C++雖然很是複雜,但作算法題實際上能夠只用其中最核心的部分,當作加強版C,就能很快上手了。golang

這段學習中感受最大的收穫就是:如何證實程序和算法的正確性,以及實現算法時,如何應對各類CornerCase和思惟漏洞。雖然理解和研究的都還不夠深,可是的確開闊了思路,讓我開始系統地思考如何用科學的方法寫出正確的代碼。具體請看《程序員修煉之路》專題以及幾篇Leetcode解題筆記:算法

1.3 Netty網絡編程

項目緣由接觸到了Netty,的確很是強大。經過對Netty的使用,也整理了開發一個網絡通訊中間件所需的方方面面的知識。但限於一直沒有對TCP/IP等網絡知識作系統學習,因此對Netty底層理解的還不夠深,但願將來能補充上這一部分。數據庫

1.4 程序員的自我修養

編譯連接一直是讓我望而卻步的領域。今年藉着學習CSAAP之勢,順帶給編譯連接的學習開了個頭。如今也能解決一些彙編及C語言的連接錯誤了,也算是有點成就。同時還試用了ANTLR,確實不錯,之後要是寫一些小東西就用它了。對這部分最深的感悟就是:原來從高級語言的多態到彙編的jmp是這麼一回事啊!編程


2.工具

今年上手了很多新工具,感謝這些工具和做者,讓我能更高效地專一於要作的事情。你會發現有時只是簡簡單單地用上了某一種工具,你的生活卻發生了根本的改變。就像只是換成Sublime+Markdown寫文章了,才發現原來本身每月能夠寫這麼多文章,並且排版還比之前漂亮十倍!只是開始在豆瓣讀書上看看別人推薦的書和記錄本身讀的書,一不留神,發現原來本身已經讀了這麼多好書。小程序

2.1 Linux Mint

多虧了Mint的多系統支持,讓我終於在本身的電腦上安裝了Linux,以前一直在Windows下用Cygwin和虛擬機將就着呢。用上了Linux後感受思惟都開放了,想用什麼軟件看什麼源碼都行,深深感覺到了軟件世界裏的自由!具體請看《Linux Mint 17一週使用體驗》sublime-text

2.2 Sublime Text

在展轉試用了各類文本編輯器後,終於不用再「漂泊」。Sublime Text幾乎知足了個人各類須要,各類語言的開發、代碼庫管理以及下面要提到的文章編寫。具體請看《Sublime Text 3下C/C++開發環境搭建》設計模式

2.3 Markdown

能夠說是今年最重要的一項改進了!專心寫做內容,減小樣式和其餘瑣碎事情的干擾,配合上Sublime Text的編輯和Preview插件簡直就是絕配!回頭看看之前用Word寫完粘貼到CSDN編輯器裏的博文,版式簡直「慘不忍睹」…… 如今有了Markdown, 寫做效率和排版質量都有很大提高,md純文本文件比doc小多了。再加上CSDN官方的大力支持,雖然渲染出來的效率不是特別漂亮,但徹底能夠放心使用了(在CSDN推廣Markdown的徵文活動中還贏了一件文化衫:)。


3.語言和框架

3.1 Golang

GitHub上涌現了很多Golang編寫的開源項目,讓人不得不重視這門語言。趁着研究豌豆莢Codis的機會,也順帶學習了Golang的基礎語法。有些地方的確很新穎,比直接用C要方便不少,可能會是一些後臺程序員的福音。但有的地方真的仍是不習慣…

3.2 YCSB

今年在對一些新技術作預研時,大量使用了Yahoo的YCSB測試框架。一開始還不太瞭解,後來熟悉了內部源碼後用起來感受駕輕就熟。負載的操做類型和比例、產生數據的分佈等等均可以配置或擴展,功能很是齊全!具體請看《YCSB性能測試工具使用》

3.3 jgroups-raft

基於jgroups網絡棧對RAFT一致性協議的實現,試用了一下仍是不錯的!能夠看作是ZooKeeper或Etcd中一致性算法層的對應,算法背後能夠鏈接各類內容,從簡單的數據增刪改查到複雜的遠程操做。這也是今年一個不小的收穫,能夠在jgroups-raft背後作出各類分佈式的小東西,而不用依賴重型的ZooKeeper服務集羣。具體請看《分佈式一致性協議Raft原理與實例》以及本文最後對分佈式開發的一點思考。

3.4 Thrift

Facebook的Thrift仍是挺好用的,很方便就能馬上開始多組件以及跨語言的分佈式開發,並且對枚舉、集合類等數據類型支持的也不錯。相比Google的Protobuf,免費提供了從序列化到RPC基礎設施的一整套方案。但好像Thrift不提升更加高級的如Watcher等調用方式,同時注意最簡單的TSimpleServer是單線程阻塞服務器,一個請求處理完纔會接受下一個鏈接請求,只能用於測試。具體請看《Java程序員的現代RPC指南》

3.5 Cucumber

體驗了一把BDD,也許用得不是那麼的標準和地道,但的確在使用過程當中能有所啓發。同時在Mock框架方面,還被PowerMock的強大震撼到了!private,static,final方法都能Mock,專治各類疑難雜症。並且還可直接配合Mockito或EasyMock,JUnit或TestNG等框架使用,沒必要徹底從新學習一套新的API。


4.平臺

4.1 In-Memory Computing

IMC是今年的主要研究方向,工做之餘寫了很多相關的文章,其中不少Redis的文章反響不錯,看來Redis依舊是很是火的。個人Redis系列文章的訪問連接以下,按內容由淺入深排序:

藉着在IMC領域的學習機會,也深刻思考了一下分佈式系統,具體請看本文後面對分佈式開發的思考。在工做多年以後可以有機會進入一個不錯的研究領域是幸運的,但願將來能對IMC以及分佈式系統理論有更深的研究。

4.2 虛擬化

今年抽了一些時間學習了火的不得了的Docker。結果Docker沒有讓我失望,的確是很好的東西!如今本身寫一些東西也會用一下Docker,代碼連同環境一塊兒打包提交,在不一樣地方開發的話簡直方便極了!將來還想深刻學習一下Docker底層用了哪些技術。具體請看《Docker新手入門:基本用法》


5.Hacking

除了「一本正經」的學習路線外,固然少不了學習一些有趣的新東西來作調劑。

5.1 緩衝區炸彈

做爲CS頂級名校CMU的教材,CSAPP裏一些經典的實驗都能在網上找到CMU的課件,感受最爲有趣的實驗當屬緩衝區溢出攻擊實驗。它讓你當一把黑客,嘗試攻擊一個有安全漏洞的小程序,當你攻擊成功後看到CMU的祝賀語時,也許會激動得淚流滿面,哈哈!

5.2 Linux 0.11內核

Linux內核也是我最爲感興趣的一個領域,儘管平時並不作嵌入式開發。今年從新撿起《Orange’s:一個操做系統的實現》,但並無徹底仿造,而是參考了Orange’s和Linux 0.11兩個版本的內核,本身動手實現了一個簡化版的內核,最後作到了進程調度器沒有作完…… 以此爲主題,學習了GitHub、GDB、Make、Docker等工具的使用,瞭解了一個現代化的彙編或C語言項目所需的各類技術。


6.思考和領悟

6.1 關於分佈式開發

第一個關於分佈式開發的思考就是:代碼和數據。在傳統軟件開發中,代碼和數據的含義再普通不過,代碼對應應用程序,而數據呢就對應數據庫。進入到分佈式的世界後,看到眼花繚亂的各類後臺中間件難免有些困惑,如下就簡述一下個人主流中間件學習過程:

  • 負載均衡:總聽人說虛IP或者VIP,等到真正本身安裝配置過LVS纔有了直觀的印象,原來簡單的負載均衡的有很多學問,還要看是在三層、四層仍是七層作分發。
  • Web服務器:這一部分是以前最欠缺的,對Apache和Nginx徹底不瞭解,後來一點點熟悉甚至還看了些Nginx源碼,動手寫了插件,才發現Nginx真是好啊!
  • 應用服務器:這一部分應該是傳統Java開發人員最熟悉的了,從重量級的WebLogic到最流行的Tomcat甚至最輕量級的Jetty,每一個Java程序員都能說出幾個本身用過的應用服務器。後來又接觸到了PHP的FastCGI,進一步開闊了眼界。
  • 消息隊列:ActiveMQ確定很多人都用過,很早就知道JMS。但消息隊列的世界也不小,還有RabbitMQ等等高性能的消息中間件。
  • 緩存中間件:最熟悉的是Ehcache,後來很天然地就過渡到了Memcached和Redis,在幾乎任何大型網站後臺都有它們的身影。
  • 任務調度:異步執行的後臺任務在大型網站中也是必不可少的。最先用的是最流行的Quartz。後來用過商業的Autosys,支持各類複雜的執行條件和Job嵌套依賴,很是強大但不知道內部是怎麼個機制。再後來用上了TBSchedule還有Quartz的分佈式版本,對分佈式調度內部也有了必定了解。

中間件就是應用程序之間的軟件膠水,它專一於某一功能,從而使開發者可以集中精力開發業務系統。儘管每款產品的設計初衷和適用場景有很大不一樣,但咱們依然能夠按照代碼和數據的方式劃分。分佈式的代碼其實就是Web服務、調度任務、MR任務等等,分佈式的數據呢就是分佈式存儲、消息隊列、分佈式緩存等等。這樣追本溯源的去想,也許能清晰很多。

第二個思考是關於分佈式開發困難的根本緣由,狀態管理絕對應該算一個。提到分佈式系統的設計目標,咱們的大腦中會馬上蹦出性能、伸縮性、可用性、擴展性、安全性等一些耳熟能詳的詞彙。但仔細思考會發現,其中多個目標都與狀態有着千絲萬縷的聯繫。高性能要考慮狀態的併發控制,伸縮要考慮狀態的一致性保證,高可用要考慮狀態的備份和恢復。以開發去中心化(P2P)的分佈式系統爲例,關於狀態管理有以下一些感悟:

  • 一致性保證:使用ZooKeeper做爲完整的一致性方案,或者使用jgroups-raft半成品做爲協議層的實現。
  • 狀態轉換:手動實現工做量較大,並且功能不全,可使用Squirrel等開源實現,支持外部狀態轉換、內部狀態轉換、事件定時觸發、嵌套子狀態等功能。
  • 中間狀態:像jgroups-raft等一致性協議對通訊時間都要要求,超時會被認爲是宕機了。因此若是協議層背後要作遠程調用等操做,就要將狀態拆分爲中間狀態和最終狀態。從一致性協議層接收到請求後,啓動異步任務後就直接返回,此時整個系統進入中間狀態,Leader等待全部結點的異步響應。每一個結點的異步任務執行完成後,響應給Leader。當Leader收集全全部響應後,經過一致性協議層通知全部結點進入最終狀態
  • 接口防重:分佈式系統的組件常常會出現各類問題,因此對接口進行重試調用在所不免。所以接口要具備冪等性,即可以自動防重,對重複的輸入數據進行檢測。
  • 狀態持久化:jgroups-raft提供了兩種方式:WAL日誌(Write-Ahead Logging)和快照。WAL保證執行真正的操做前先將操做日誌成功寫到持久化存儲,而按期作快照能夠壓縮日誌大小。
  • 狀態恢復:重啓時每一個結點上的jgroups-raft都會根據日誌在本結點「重放」一遍日誌操做,這對於異步中間狀態是有問題的。因此能夠預讀日誌和快照,提早將狀態機恢復到正確的狀態,這樣作完的日誌操做就會被狀態機拒絕掉
  • 局部狀態:經過一致性協議層發送和接收的消息對各個結點必須是同樣的。因此若是每一個結點都須要本身的消息作入參,就經過一致性協議層發送全局的數據,每一個結點根據數據中的標誌位提取出本身想要的數據

6.2 關於軟件工程

今年只作了一個項目,在最近開發了一個無中心化結構的分佈式中間件。因爲中間了隔了一段時間沒有開發具體的業務系統,因此從新上手作項目又對軟件開發過程有了一些新的感悟,尤爲是如何根據需求作出合理的設計,根據設計產生正確的代碼。今年學習到的就是BDD(行爲驅動開發),因而從新梳理一下我的對軟件工程的各個步驟的理解:

  • 需求分析:需求的規格可謂多種多樣,碰見過的有簡略的BRD文檔、有詳細些的PRD文檔,甚至還有直接在郵件裏一段話描述的。我以爲BDD中的Specification跟BRD文檔對應的最準確,都是說明了功能特性、典型場景、以及最重要的對用戶的價值。而不是PRD裏詳細的輸入輸出參數以及界面設計等內容。涉及角色有BA業務分析師、產品經理等。
  • 架構設計:針對系統及系統內的組件層次,涉及角色有架構師、開發骨幹,還要配合項目經理對人員、任務和工時進行分配,作出合理的排期。
    • 技術選型:選用哪些中間件、是否有新技術要預研、技術風險點
    • 外部系統交互:涉及哪些外部系統,系統級別調用的時序圖、開發人員的協調
    • 組件劃分和交互:內部可劃分哪些組件、如何通訊交互、總體的流程圖
  • 詳細設計:針對各個組件內的模塊層次,涉及角色有架構師、開發骨幹或者普通開發人員。這一層以前理解的比較模糊,在某些業務系統中可能被淡化,但在技術性較強的開發框架或中間件開發中卻相當重要。
    • 模塊劃分和協做:模塊之間的訪問控制、每一個模塊哪一個核心類作Facade或Mediator
    • 內部數據模型:獨立的模型,與系統間通訊用的DTO解耦
    • 核心算法設計
    • 業務和技術術語表:影響到各類元素的命名,全部開發人員要統一
    • 編碼規範和註釋風格
  • 編碼階段:針對類和方法層次。主要是類的設計(類圖、時序圖、設計模式),在編碼階段可能會在完善TestCase的同時不斷重構。因此這一部分不穩定,要避免過分設計。涉及角色有架構師、全部開發人員。

要想順利開發出軟件還離不開基礎設施的搭建。因此在上述軟件工程進行時,能夠儘早地利用公司技術資產或我的經驗,提早準備好基礎設施:

  • 環境
    • 依賴管理:Maven/Gradle
    • 構建:Ant/Maven/Make
    • 版本控制:SVN/Git
    • CI持續集成:Jenkins
    • 統一IDE及插件,配合CI
  • 項目結構
    • 工程:腳手架生成或手寫
    • 主要的包和文件夾:根據術語表命名,包括Java的、JS的、配置文件的等
    • 主要的類和文件
  • 代碼
    • 語法加強:JDK 八、Apache Common、Google Guava
    • 依賴注入:Spring或更輕量的Guice
    • 配置參數和文件解析
    • 異常處理:斷言、統一異常類、異常錯誤碼、異常提示語(用於國際化)
    • 併發控制:JDK concurrent提供的Lock和CountdownLatch等都很好用
    • 線程池:一樣JDK concurrent便可,Guava提供了加強
    • 事件總線:Guava
    • 日誌:Slf4j配合具體實現,爲項目定製統一的日誌輸出格式
    • 數學函數:加密解密算法等

我的理解,無論是用BDD仍是TDD,實踐時腦海中都應該至少對關鍵技術選型、頂層架構設計和中層模塊設計有了清晰的認識,而不是直接對着BRD就開始敲代碼。此外,不用嚴格的遵照規則,有一套最適合本身的方法論也很好,你不習慣的實踐規則可能確實不那麼適用,也可能你的水平還不能理解和駕馭,沒有關係慢慢來,不用硬着頭皮全盤接受,最後搞得一點寫代碼的心情都沒有了。

如今感受到軟件開發過程就像是下棋,最重要的就是掌控力。若是說前期設計靠的是對業務和技術的理解和經驗,那麼真正開始着手去作時靠的就是對代碼的掌控。在高速開發中,在不少地方均可以「點到即止」,按照總體的設計掌控住細節,讓代碼去到該去的地方,後期再逐漸重構作到完全。

6.3 技術債務

總結事後,發現了本身技術路線外的一些盲區,也能夠說是欠下的「債務」:

  • Web和移動開發:一直很羨慕能直觀展現本身成果的程序員,但就是對Web和移動開發提不起興致,準備抽一段時間集中學習Bootstrap、AngularJS、React.js等流行的前端框架,像Codis那樣用後臺程序的Dashboard來練手
  • Java 8:曾經是那麼喜歡Java,Java 五、6有一點兒新特性,都會認真學習半天。可Java 6以後好像就不那麼熱衷了,甚至Java 8中這麼大的變化都無動於衷。什麼緣由呢?我想一來是近兩年業餘時間都在深挖底層,體系結構、Linux、C等等;二是公司項目使用JDK版本升級緩慢,幾乎一直停留在了JDK 6。
  • 方法論和應用框架:因爲業務系統開發工做減小,因此沒有特別關注研發的方法論和應用層的新框架。雖然作技術預研時一直在寫原型和實驗代碼,編碼量沒有降低,但要警戒研究內容脫離實際以及代碼質量降低的狀況。
    • 方法論:無論是業務系統仍是原型開發,都是實踐的機會,TDD、重構等都要不斷練習領會
    • 應用框架:Spring Boot等Spring周邊產品,還有最新版的SpringSide都是不錯的從新學習機會
  • 業餘練習項目:儘管大部分書籍閱讀時都動手作了練習和讀書筆記,但並無寫一些對本身或別人很實用的小工具。之後仍是要多動手,寫一些像《用Qt開發簡單的瀏覽器(一)》裏這樣好玩又能對別人有幫助的小開源軟件。

2015的總結就到這裏了,2016還有更大的挑戰!繼續加油,珍惜每一分每一秒!

相關文章
相關標籤/搜索