## 37 結束語
> 機會不會上門來找人,只有人去找機會。
> ——狄更斯
為期半年的 Java 并發專欄終于落下了帷幕。很感謝一直陪伴我走完這段歷程的讀者朋友,是你們的鼓勵讓我堅持完成寫作;是你們的發問,讓我鉆研得更為徹底;是你們的堅持學習,堅定了我寫作的信心。此外也很感謝慕課網的小編給我提出各種建議和鼓勵。最后感謝我的愛人和父母,謝謝家人對家庭的照顧,讓我有更多時間來學習和創作。
作為專欄最后一篇,我想從三個方面和大家聊一聊。
1. Java 并發編程的學習;
2. 關于學習 ;
3. 關于寫作。
## 1、Java 并發編程的學習
Java 并發編程的書籍和教程市面上有很多,這反而造成大家在學習 Java 并發時不知道該選擇哪本書籍。在這里我可以談一談我是如何學習的。我最開始看的是《Java 并發編程實戰》。這本書絕對是經典中的經典。作者都是耳熟能詳的大師。不過對于想要學習 Java 并發的新手來說,我并不推薦上來就學習此書。這一點在此書的序中也被提到:“本書并非是對并發的入門介紹”。對于新人,我推薦先看一些國內作者的書籍或者專欄,無論大綱安排還是語言運用,都更為符合國人的習慣,更為深入淺出。當你有了一定的并發基礎后,一定要反復閱讀《 Java 并發編程實戰》。此時讀此書,才能深刻理解其中的精髓。而不只是停留在語言層面的 “理解”。這本書的作者參與了 java 并發的設計和編寫,所以作者對 java 并發的理解肯定無人能及。這本書的奇妙之處在于,隨著你對 Java 并發學習的深入,每次讀此書,都會汲取到更多的知識。但是如果你上來就通過此書學習并發,會讓你有種云里霧里的感覺。
我們學習 Java 并發編程的最終目的和價值,還是運用于實戰之中。所以關于 Java 并發編程的實戰學習是必不可少的。雖然我在專欄中提到學習的目的之一是為了面試。但其實這也是被迫無奈。我們學習的任何新技術,如果不運用于生產,都是沒有意義的。所以在學習完 Java 并發后,一定要學習并發的設計模式以及實戰。另外最好能夠看一看開源框架中對于多線程的使用,讀一下源代碼。然后在自己的代碼中去嘗試使用。
另外在 Java8 中,通過 lambda 表達式和流 API,可以很方便的并行處理流。這部分內容并不在本專欄范圍內。但是 lambda 已經在 Java 領域應用的十分廣泛,所以十分建議去認真學習,并且運用到日常開發中。
## 2、關于學習
寫了這么久的并發編程,今天想聊聊并發之外的事情。首先想聊一聊我對學習的一些想法。
選擇軟件開發這個工作,也就意味著你需要終身學習。我做企業級開發已經 10 多年。還記得剛畢業 06 年左右,EJB 的書有很多。但過了沒兩年,EJB 就已經不是熱點,取而代之的是滿世界的 SSH 書籍,當時還是 Structs1。如何整合三大框架也算是個難題,居然也可以出本書來講解。當時最流行的數據庫是 Oracle,開源的數據庫使用很少。那個時代,大家對框架還主要停留在使用層面。再往后,開始出現各種源代碼分析的書籍,尤其是 Spring 居多,書很薄,但是賣的很貴。到了互聯網時代,曾經的 SSH(Structs+Spring+Hibernate)變成了 SSM(Spring MVC+Spring+Mybatis)。再到后來的 Spring Cloud,微服務大行其道,分布式架構開始流行。與之而來的消息隊列、分布式事務、容器等技術占據了主流。與此同時,大數據和人工智能單成一套體系,分別快速的發展。這些技術間也互有融合。云服務也給開發者帶來了更多的便利,讓開發者更能專注在軟件開發本身。
從這個發展過程來看,不過 10 多年的功夫,技術已經換了一批又一批。從業者需要一直學習才能跟上技術的進步。這個行業是否過于辛苦了?其實并不是這樣。有句話叫萬變不離其宗。舉個例子,無論是從 Struts1 到 Struts2,還是演變到 Spring MVC,都繞不開 HTTP 協議,都繞不開 MVC 設計模式,都繞不開 Servlet。如果只為了見效快,項目上用啥我就學啥,那么到最后一定是學不過來了。只有把根基打牢固,才能以不變應萬變。無論用什么框架,底層使用的技術都是類似的。框架的應用固然重要,但是我們一定要再往下扎的深一點,扎的越深,學到的知識越不會輕易被淘汰。
我建議大家更多的學習底層知識和理論基礎,不要把時間全花在框架學習上,那么只會讓自己疲于奔命。底子打的牢靠,會讓你從容應對技術的更新換代。
下面我想再談談如何學習一門新的技術。
首先,我們應該從實際需要出發,帶著使用場景學習的效果更好。一般我會通過官網,了解這門技術的出現動機和他的優勢,然后通過官網的文檔目錄對其有一個大概的了解。
接下來就可以跟著文檔寫一個 Hello World 程序,這樣能讓你對這門技術的工作機制有大概的了解。接下來會把這門技術最基礎的知識點學習完成,當然是通過實踐的方式,一步一步跟著教程和示例來做。一般來說我們學習新技術是因為項目上要使用,所以我們一般不會有特別充裕的時間讓你從頭學到尾。這個時候就需要你來分析一下你的使用場景,再結合文檔看他通過什么方式解決你的問題。那么接下來就應該重點學習這些內容。其實就是帶著我們的問題來看這門技術如何解決,然后再去針對性的學習。這樣的學習是效果最好的。問題解決后,再花時間把其他章節學習完。我還是建議系統完整的學習,而不是用哪就只學那一小塊。
其實好多時候我們學習完,并沒有機會使用。學習這件事就變成了只有輸入沒有輸出。不能形成閉環,效果自然也不會好。你會發現學習完如果不去使用,最多兩個月就忘的一干二靜了。如果項目中暫時用不到,我建議你換一種輸出方式。比如可以把你學到的知識做分享,讓自己掌握更牢固的同時,也幫助到其他同事。分享看似大家在從你這收獲知識,但其實收獲最大的還是分享者。不要怕講的不夠深入、不要怕自己會緊張、不要怕被同事問住。這些都無所謂,只要你自己認真準備了,你就有了收獲。
如果你實在不愿意在眾人面前分享。或者公司沒有那么多分享的機會。你也可以選擇寫博客或者專欄。技術寫作也是一項非常好的輸出方式。而且你一個人就能完成,很適合比較宅的程序員。寫作需要你把學習到的知識理解透徹,然后再換做自己的語言寫出來。這個過程會讓你把知識記憶的更為牢固。而且如果你以后有機會用到這門技術,只要翻看一下自己的博客,很快就能回憶起來。
既然聊到了寫作,那么下面我就展開來說說寫作這個事兒。
## 3、關于寫作
我自認為還是個比較喜歡寫作的人。但這半年的專欄寫下來,也是讓我疲憊不堪。我前不久參加了異步社區的作譯者大會。還記得一個嘉賓分享時說到,選擇了寫作,意味著放棄了除寫作外的一切。你沒有時間看電影、看小說,沒時間和朋友吃飯、聚會。甚至陪家人的時間都少了很多。我聽完這位嘉賓的分享,十分身同感受。
我在寫本專欄之初,想用一種新穎點的方式,通過漫畫幫助理解記憶,但是沒有充分考慮這部分的工作量。這導致開始寫作后,占用了我大量的業余時間。除了寫完文章外,每篇文章的配圖還需要 1-2 個小時創作。于是我基本上半年多都是在 12 點以后才睡覺,周末經常是孩子上課,我在肯德基寫文章。說實話,幾度感覺要撐不下去了。尤其是寫到 ConcurrentHashMap 源碼分析。首先我要花大量時間把源碼讀懂,然后再通俗易懂的寫出來。本來計劃一節的內容,越寫越多,最后寫成了兩節。這個時候工作上也很忙,我那段時間加班 9 點半到家,哄孩子睡覺到 10 點半,然后開始寫文章到 1 點。早上 7 點起來送孩子上學。當時真的覺得自己要撐不下去,但沒有退路,硬著頭皮也得往前走。最后咬咬牙也就過來了。
很抱歉和大家訴了這么多苦。其實如果只是寫博客,并沒有這么辛苦。在寫專欄前,我大概寫了兩年的技術博客,涉及 Kafka、zookeeoer 等系列文章。其實這次有機會寫專欄,也是慕課網的小編通過博客聯系到我的。而且如果沒有寫博客的經驗積累,即使小編找到我,我也不敢就答應下來。寫技術博客有幾種方式,我比較喜歡寫成系列的文章,這也是對學習最好的輸出。如果只是記錄解決了什么問題,那就更像是給自己看的筆記。
我寫的第一個系列是 Kafka。起因是項目在實際使用,而我想要做一個 kafka 的分享。分享前我下了挺大的功夫學習和準備。分享過后,覺得短短兩個小時并沒有把我準備的所有東西講出來。看了看手里為分享準備的材料,應該夠支撐我寫幾篇 kafka 的文章。于是我就開始了 Kafka 系列教程的寫作。當時工作不算很忙,基本上一兩天就能寫出一篇。一開始當然沒什么點擊量,不過我也不太在意,就一直堅持寫。大概用了 20 天就完成了全部 9 篇文章。其實到我寫完也沒有多少點擊量。后來又陸續寫了 ZooKeeper、Spring Cloud、Kafka 源代碼等內容,還有一些官方文檔的翻譯。漸漸的瀏覽量和關注量就上來了,還記得大概半年后我的關注量到了 100,當時還挺開心的。又過了半年多,關注量已經達到了 300,也獲得了博客專家的稱號。
其實說這么多,只是想講一個道理。寫作要堅持,另外要不忘初心。寫作不是為了虛名和賺錢。寫作的初衷很簡單,就是為了鞏固自己的知識和分享知識。只要你能堅持寫作,你輸出的知識,別人就一定能看到。千萬不要寫了幾天覺得沒人看,就放棄了。只要你堅持下去,是金子早晚會發光。退一步講,即使沒人看,也有利于你理解和記憶學習過的知識。如果想讓更多的人搜索到你的文章,我可以分享個小竅門,起標題時換位思考,如果自己想學習這門技術時會如何搜索。舉個例子,比如我想學習 Akka,可能我會搜索 Akka 教程、Akka 入門、Akka 實戰、Akka 例子等。以上關鍵詞就可以適當地放入你的標題中。那么能提高別人搜索到你文章的概率。
雖然很不想結束,但還是不得不說再見。希望這個專欄對你的并發編程學習有所幫助。大家關于軟件開發或者職業生涯的任何問題都歡迎和我一塊探討。最后祝大家在技術探索的道路上一路順利!
- 前言
- 第1章 Java并發簡介
- 01 開篇詞:多線程為什么是你必需要掌握的知識
- 02 絕對不僅僅是為了面試—我們為什么需要學習多線程
- 03 多線程開發如此簡單—Java中如何編寫多線程程序
- 04 人多力量未必大—并發可能會遇到的問題
- 第2章 Java中如何編寫多線程
- 05 看若兄弟,實如父子—Thread和Runnable詳解
- 06 線程什么時候開始真正執行?—線程的狀態詳解
- 07 深入Thread類—線程API精講
- 08 集體協作,什么最重要?溝通!—線程的等待和通知
- 09 使用多線程實現分工、解耦、緩沖—生產者、消費者實戰
- 第3章 并發的問題和原因詳解
- 10 有福同享,有難同當—原子性
- 11 眼見不實—可見性
- 12 什么?還有這種操作!—有序性
- 13 問題的根源—Java內存模型簡介
- 14 僵持不下—死鎖詳解
- 第4章 如何解決并發問題
- 15 原子性輕量級實現—深入理解Atomic與CAS
- 16 讓你眼見為實—volatile詳解
- 17 資源有限,請排隊等候—Synchronized使用、原理及缺陷
- 18 線程作用域內共享變量—深入解析ThreadLocal
- 第5章 線程池
- 19 自己動手豐衣足食—簡單線程池實現
- 20 其實不用造輪子—Executor框架詳解
- 第6章 主要并發工具類
- 21 更高級的鎖—深入解析Lock
- 22 到底哪把鎖更適合你?—synchronized與ReentrantLock對比
- 23 按需上鎖—ReadWriteLock詳解
- 24 經典并發容器,多線程面試必備—深入解析ConcurrentHashMap上
- 25 經典并發容器,多線程面試必備—深入解析ConcurrentHashMap下
- 26不讓我進門,我就在門口一直等!—BlockingQueue和ArrayBlockingQueue
- 27 倒數計時開始,三、二、一—CountDownLatch詳解
- 28 人齊了,一起行動—CyclicBarrier詳解
- 29 一手交錢,一手交貨—Exchanger詳解
- 30 限量供應,不好意思您來晚了—Semaphore詳解
- 第7章 高級并發工具類及并發設計模式
- 31 憑票取餐—Future模式詳解
- 32 請按到場順序發言—Completion Service詳解
- 33 分階段執行你的任務-學習使用Phaser運行多階段任務
- 34 誰都不能偷懶-通過 CompletableFuture 組裝你的異步計算單元
- 35 拆分你的任務—學習使用Fork/Join框架
- 36 為多線程們安排一位經理—Master/Slave模式詳解
- 第8章 總結
- 37 結束語