Java學(xué)習(xí)路線圖


Java是一個(gè)通用的編程語言,其實(shí)可以干很多事,怎么學(xué)Java就看怎么用了,但有一些一般的步驟:

  • 熟悉一種文本編輯器,比如Vim, Emacs, Notepad++, TextMate等。知道哪些是開源的,哪些是閉源的,哪些要收費(fèi)。養(yǎng)成不用盜版軟件的習(xí)慣。

  • 安裝JDK(建議用你的Linux發(fā)行版自帶的軟件包管理器安裝openjdk,過程中可能需要讀發(fā)行版特定的文檔)

  • 寫一個(gè)Java的Helloworld程序,并用命令行工具javac編譯,再用java命令運(yùn)行這個(gè)程序。過程中熟悉源代碼、字節(jié)碼、虛擬機(jī)這些東西,以及Java的包(package)對(duì).class文件所在的路徑的影響。如果這兩個(gè)命令行工具使用熟練了,可以開始選一個(gè)喜歡的集成開發(fā)環(huán)境,比如Eclipse。當(dāng)然,養(yǎng)成不用盜版軟件的習(xí)慣。熟悉一下如何建立“工程”,以及快捷鍵的使用。

  • 學(xué)習(xí)Java的面向過程編程,包括基本數(shù)據(jù)結(jié)構(gòu)、表達(dá)式、語句、控制流、函數(shù)調(diào)用。

  • 學(xué)習(xí)Java的面向?qū)ο缶幊?,包括類、引用類型和值類型的區(qū)別、成員、方法、訪問控制、繼承、多態(tài)、接口、接口實(shí)現(xiàn)。順便學(xué)習(xí)一下面向?qū)ο蟮幕舅枷?,即?duì)象、消息、封裝、繼承、多態(tài)等,這些通用的內(nèi)容不是Java特有的。這時(shí)候應(yīng)該已經(jīng)涉及了Java的垃圾回收。要留意即使有垃圾回收的情況下也會(huì)發(fā)生的內(nèi)存泄露(如自己設(shè)計(jì)數(shù)組容器,元素是引用,邏輯上刪除了元素,但并沒有清成null)。注意垃圾回收只能回收內(nèi)存中的對(duì)象,除了內(nèi)存以外,其它資源不能依靠垃圾回收來關(guān)閉。比如,文件、管道、Socket、數(shù)據(jù)庫連接等,垃圾回收是不會(huì)幫你關(guān)閉的。

  • 學(xué)習(xí)Java的異常處理,但更重要的是學(xué)習(xí)什么時(shí)候用特殊返回值而不使用異常,什么時(shí)候應(yīng)該拋出異常而不處理異常,知道什么是pokemon catch及其危害,了解為什么Java的checked exception是一個(gè)糟糕的特性。如果愿意,同時(shí)學(xué)習(xí)一下Java1.7的try-with-resource語句和AutoCloseable接口。

  • 熟悉Java常用的數(shù)據(jù)結(jié)構(gòu),如基本的數(shù)組類型,以及泛型容器(java.util.*),尤其是java.util.List接口和java.util.ArrayList實(shí)現(xiàn);以及java.util.Map接口和java.util.HashMap實(shí)現(xiàn)。(java1.5以前的沒有泛型參數(shù)的就不用碰了)同時(shí)留意一下基本類型int, double等和裝箱類型Integer和Double的區(qū)別,以及它們是如何自動(dòng)轉(zhuǎn)換的。

  • 熟悉Java標(biāo)準(zhǔn)庫里的各種工具,包括日期時(shí)間、字符串格式化、IO等。**知道文件要自己在finally子句中close(),或者用Java1.7的try-with-resource,不要妄想垃圾回收器會(huì)幫你關(guān)掉文件。

  • 學(xué)習(xí)一下Java的命名習(xí)慣,以及JavaBeans的常規(guī),知道為什么getter/setter比直接操作成員變量好。按這種方式給Java的變量、方法命名。同時(shí)看看你的IDE能不能自動(dòng)幫你生成getter和setter。

  • 使用一個(gè)第三方的庫(比如Apache Commons Lang通用工具庫),讓你的程序依賴于它的二進(jìn)制jar包(而不是直接拷貝源代碼),用命令行編譯、運(yùn)行(注意classpath等);也熟悉一下如何用你的集成開發(fā)環(huán)境添加第三方依賴。感受一下手動(dòng)管理依賴關(guān)系的麻煩。

  • 學(xué)習(xí)Maven的使用,試著讓Maven幫你解決依賴關(guān)系,再試著讓Maven幫你創(chuàng)建一個(gè)Eclipse工程。再試試用Maven打包發(fā)布。

  • 學(xué)習(xí)軟件測試,以及JUnit的使用,以及怎么在IDE中使用JUnit。有空看一下coverage工具。

  • 讀讀四人幫寫的《設(shè)計(jì)模式》(這本書是用C++和Smalltalk語言為例子的,但仍然適合Java)。具體的是這本書,http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612圖書館應(yīng)該能還借到英文原版,因?yàn)槲医璧竭^。


接下來就看具體要做哪方面的應(yīng)用了,看需求。比如(下面的沒有順序)

  1. 關(guān)于語言

    • 如果學(xué)Java學(xué)得不舒服了,學(xué)Python。
    • 如果對(duì)面向?qū)ο缶幊痰母拍钣悬c(diǎn)不習(xí)慣,學(xué)Smalltalk。(Ruby也行,但不如Smalltalk經(jīng)典。Ruby的文檔是一大硬傷。)
    • 如果嫌Java太啰嗦,學(xué)Python
    • 如果嫌Java太啰嗦,又想用JVM,自己又有精力,學(xué)Scala
    • 如果對(duì)對(duì)象之間的關(guān)系有點(diǎn)暈,學(xué)一學(xué)UML,以及它的一些圖,可以對(duì)程序和運(yùn)行進(jìn)行直觀的建模。你的IDE也許有插件可以生成UML圖。但是不要太沉迷于這些方法論。
  2. 調(diào)試和輔助工具

學(xué)習(xí)一下你的集成開發(fā)環(huán)境提供的調(diào)試工具,加一些斷點(diǎn)試試。

  • 試試用jconsole或者VisualVM監(jiān)控另一個(gè)jvm的狀態(tài)。
  • 用profiling工具尋找程序中慢的地方。Eclipse有profiling工具。VisualVM也有這樣的功能。(如果不介意使用閉源軟件的話,也試試JProfiler和YourKit)
  • 有的JVM允許在運(yùn)行時(shí)更新代碼。Eclipse可以和某些JVM集成。這樣你可以頻繁修改代碼而不用頻繁重啟JVM。對(duì)于某些“重型”工程很有用。(如果不介意使用閉源軟件的話,也試試jRebel)
  1. 多線程

學(xué)習(xí)Java的多線程編程以及l(fā)ock、condition的用法(包括傳統(tǒng)Java的synchronized語句以及新加的java.util.concurrent.*),學(xué)習(xí)一下如何讓線程停下來,以及為什么要頻繁確認(rèn)isInterrupted()而不要用Thread.stop()。了解一下多核處理器、緩存、內(nèi)存的關(guān)系,以及為什么多線程編程這么難。

  • 如果還舒服,學(xué)習(xí)一下Runnable的用法,以及自帶的Executer等基本多線程工具。
  • 應(yīng)該已經(jīng)留意到j(luò)ava.util里面的很多容器不是線程安全的,但是java.util.Collections可以幫你創(chuàng)建一些安全的版本。另外關(guān)注一下java.util.concurrent里面有ConcurrentMap等容器可供使用。
  • 如果有空的話,看看memory model(內(nèi)存一致性模型)和無鎖同步(見java memory model和java.util.concurrent.atomic)。
  • 如果還有空,再了解一下除了“共享內(nèi)存多線程編程”以外有沒有別的模型(多進(jìn)程multi-processing、消息傳遞message passing等)。
  1. 反射、元編程

    • 學(xué)習(xí)Java的反射機(jī)制,以及Annotation的用法。
    • 如果還舒服,試試java.lang.reflect.Proxy的用法。
    • 如果仍然還舒服,玩一玩CGLib(一個(gè)第三方的庫)。
  2. 網(wǎng)絡(luò)編程

學(xué)習(xí)一下IP,TCP協(xié)議(計(jì)算機(jī)專業(yè)的應(yīng)該學(xué)過,復(fù)習(xí)一下),學(xué)習(xí)Socket編程(注意垃圾回收器不會(huì)幫你關(guān)掉Socket)。

  • 如果不是很關(guān)心HTTP,看看java.nio,學(xué)習(xí)單線程輪詢式IO復(fù)用(Selector)。
    1. 如果有點(diǎn)不明白nio的意圖的話,了解一下c10k問題。 http://www.kegel.com/c10k.html
    2. 如果身體沒有異樣的話,大概了解一下操作系統(tǒng)(包括C語言)提供的select, poll, epoll, kqueue等接口。
    3. 如果身體仍然沒有異樣的話,試著用java.nio寫一個(gè)文件服務(wù)器。
    4. 如果還有精力的話,上網(wǎng)扒一扒有沒有其他的通信庫,如netty等。
  • 如果關(guān)心Web還有HTTP,就學(xué)習(xí)一下HTTP協(xié)議,以及用Java進(jìn)行HTTP的客戶端編程。
    1. 如果還舒服,學(xué)學(xué)HTML,寫寫HTML的靜態(tài)網(wǎng)頁(不需要Java)
    2. 如果還舒服,用Java寫一個(gè)基于DOM、XPath或者CSS Selector的網(wǎng)頁解析器(爬網(wǎng)頁)。
    3. 如果還舒服,學(xué)學(xué)Java的Servlet接口(先別學(xué)jsp)進(jìn)行Web服務(wù)器端編程。學(xué)學(xué)標(biāo)準(zhǔn)的Servlet容器怎么用,包括web.xml的用法以及l(fā)istener、filter等概念。以及某個(gè)Servlet容器(如Jetty或者Tomcat)的具體用法。
    4. 如果仍然還舒服,試著學(xué)一種模板語言(如haml, velocity, freemarker,【還有其他更好的框架嗎?我不知道】, String.format,如果真的想學(xué)JSP的話JSP倒是也行,但不推薦)。
    5. 如果仍然覺得舒服,學(xué)學(xué)Spring框架中的Web框架,或者Struts,看你的口味。
    6. 如果還舒服,看看Spring Bean Container以及里面各種亂七八糟的工具。
    7. 如果還舒服,或者有需求,了解一下什么是RESTful Web Service,復(fù)習(xí)一下HTTP,找找適合的Java工具。
    8. 你可能會(huì)覺得Jackson是一個(gè)解析JSON用的好用的東西。
  1. 數(shù)據(jù)庫

學(xué)習(xí)一下關(guān)系數(shù)據(jù)庫(計(jì)算機(jī)專業(yè)的應(yīng)該學(xué)過,復(fù)習(xí)一下),包括SQL。選一個(gè)數(shù)據(jù)庫管理系統(tǒng)熟悉一下(比如MariaDB,或者(如果你不討厭Oracle的話)用被Oracle收購了的MySQL。先脫離Java單獨(dú)學(xué)學(xué))。然后看它們的官方文檔教你怎么用Java連接這種數(shù)據(jù)庫。這中間會(huì)涉及到JDBC接口。同時(shí)一定要知道SQL注入安全漏洞,以及掌握如何用PreparedStatement防止注入??!。建議看 http://bobby-tables.com/

  • 可能中間會(huì)涉及“事務(wù)”問題,讓你不知不覺地開始去了解java transaction api(JTA)。
  • 如果還舒服,學(xué)一學(xué)對(duì)象關(guān)系轉(zhuǎn)換(如Hibernate)。
  • 也可以學(xué)學(xué)非關(guān)系數(shù)據(jù)庫,以及如何用Java訪問它們。
  1. 日志記錄

學(xué)習(xí)一下slf4j和logback的用法。

  • 如果有精力的話,大概了解一下世界上有多少種Java日志框架,以及slf4j是怎么橋接這些框架的。
  1. 構(gòu)建(build)系統(tǒng)

學(xué)習(xí)一下Ant的用法。

  • 如果還舒服的話,學(xué)習(xí)一下用Ivy從Maven的倉庫里下載軟件包,解決依賴關(guān)系。
  1. 版本控制

學(xué)習(xí)一種分布式版本控制器(如Git、Mercurial、Bzr、Darcs等,推薦Git)的基本用法,以及如何用它管理Java工程。希望你已經(jīng)開始使用Maven了,并且知道為什么把IDE生成的工程文件(如eclipse的.project,.classpath和.metadata)放入版本控制器不好。然后了解一下如何在IDE中使用版本控制(Eclipse自帶Git插件)。

  • 如果感覺很舒服的話,為你們實(shí)驗(yàn)室搭建一個(gè)Linux+SSH+Git服務(wù)器,裝個(gè)GitLab(一種Web界面)。
  • 了解“集中式版本控制器”和“分布式版本控制器”的區(qū)別,并說服同事們不要再用SVN、CVS或者SourceSafe等老舊的“集中式版本控制器”了。
  • 開設(shè)一個(gè)GitHub賬戶。如果你不喜歡Git,就用BitBucket等。
  1. 持續(xù)集成

自己(或者為你們實(shí)驗(yàn)室)搭建一個(gè)持續(xù)集成(Continuous Integration)服務(wù)器,如Jenkins,定期編譯你的程序。建議同時(shí)使用Git等分布式版本控制器。

  • 如果你做開源軟件,試試GitHub和Travis。
  1. 零碎工具

淘一淘java.nio.files里面有什么好用的東東,然后再淘一淘Apache Commons Lang和Commons IO里有什么好用的工具。Commons Logging就不要再用了,用SLF4j和Logback。

  1. XML

學(xué)學(xué)XML、DOM、XPath。XML這東西到處都可能用到。也可以用它寫自己的配置文件。

  • 如果覺得不舒服了,就學(xué)學(xué)JSON和YAML。
  • 如果還是不舒服,就學(xué)學(xué)文本文件解析。
  1. 語法分析和編譯器

學(xué)學(xué)Antlr或者別的Parser Generator的用法

  • 如果覺得舒服,自己寫一個(gè)計(jì)算器。
  • 如果還覺得舒服,自己寫一種Domain-Specific Language (DSL)。
  1. 高效容器

學(xué)學(xué)FastUtil或者Trove,如果你需要進(jìn)行大量數(shù)值運(yùn)算的話。

  1. 分布式計(jì)算

學(xué)學(xué)MapReduce的思想以及它的實(shí)現(xiàn)。

  • 如果還舒服,學(xué)學(xué)Scala語言以及號(hào)稱比MapReduce快得多的Apache Spark。
  1. 進(jìn)程間通信

看看ActiveMQ、MINA和RMI。

  1. 其他語言(JVM)

學(xué)習(xí)另一門跑在JVM上的語言或者實(shí)現(xiàn)(如Groovy、Scala、Clojure、JRuby、Jython、JavaScript……)

  1. 其他語言(非JVM)

學(xué)習(xí)另一門通用腳本語言(如Python、Ruby,其實(shí)perl也行,但不推薦),知道什么時(shí)候Java不是最好的選擇。

  1. Java語言和Java虛擬機(jī)

通讀一遍(一目十行地讀,不用細(xì)讀)Java Language Specification,以及Java Virtual Machine Specification。

  • 了解以下解釋器(interpreter)、編譯器(compiler)、即時(shí)編譯器(just-in-time compiler)和優(yōu)化器(optimiser)的概念。
  • 如果對(duì)編譯器的話題不感到畏懼,了解一下method JIT和tracing JIT的概念和區(qū)別。
  1. 內(nèi)存管理

學(xué)學(xué)垃圾回收的幾種基本算法,包括mark-sweep、mark-compact、semi-space、generational、mark-region等,各自的性能,以及為什么樸素的reference counting是不完整的。知道為什么finalizer性能很糟糕,而且標(biāo)準(zhǔn)并不要求finalizer在程序退出前一定會(huì)執(zhí)行。

  • 如果還舒服,了解一下如何設(shè)置Java虛擬機(jī)的堆大小限制(如HotSpot虛擬機(jī)的-Xmx選項(xiàng)等)。
  • 了解一下Java里的WeakReference以及SoftReference和PhantomReference,以及它們什么時(shí)候有用,以及為什么它們實(shí)現(xiàn)起來有些困難。
  • 如果有精力,了解一下Hotspot虛擬機(jī)的內(nèi)存管理算法是什么樣的。
  1. 動(dòng)態(tài)裝載

學(xué)學(xué)Java的動(dòng)態(tài)裝載(class loading)

  • 如果還舒服的話,學(xué)學(xué)OSGI以及它的一種實(shí)現(xiàn)(如Felix或者Equinox)
  • 如果仍然很舒服的話,學(xué)學(xué)寫基于Eclipse平臺(tái)的程序。不是Eclipse集成開發(fā)環(huán)境,只是利用他們的圖形框架,寫自己的應(yīng)用程序。
  • 如果還覺得舒服的話,寫Eclipse集成開發(fā)環(huán)境的插件。
  1. 本地/外語接口

學(xué)習(xí)一下Java Native Interface(JNI),試著寫一個(gè)Java和C語言混合編程的程序。

  • 如果覺得不舒服了或者覺得欲仙欲死,就學(xué)一學(xué)Java Native Access(JNA),試一試不用任何膠水代碼而從Java直接裝載C庫,直接調(diào)用C函數(shù)。
  • 如果連JNA也懶得學(xué),就學(xué)一學(xué)SWIG,自動(dòng)生成綁定。
  • 如果覺得舒服,就學(xué)一學(xué)Java Virtual Machine Tooling Interface(JVMTI),用C程序來監(jiān)視JVM的狀態(tài)。
  1. 密碼學(xué)

學(xué)一學(xué)密碼學(xué),包括編碼、密碼分析、攻擊、對(duì)稱密鑰、公鑰系統(tǒng)、數(shù)字簽名、哈希算法等,看看Java有沒有實(shí)現(xiàn)。

  • 如果覺得有點(diǎn)不舒服(你應(yīng)該不會(huì)覺得舒服吧,除非你是學(xué)密碼學(xué)的,要不然總會(huì)覺得自己寫的程序有安全漏洞),就寫一個(gè)“人品計(jì)算器”來放松一下,要求每次輸入同一個(gè)姓名,得到的人品值是固定的,但又要讓人無法用別人的人品值猜自己的人品值。
  1. 移動(dòng)終端

學(xué)一學(xué)Android開發(fā)。

  • 如果有精力的話,看看Dalvik虛擬機(jī)是怎么回事。
  • 建議買一個(gè)iPhone或者iPad,或許你再也不想用Android手機(jī)或者平板了。
  1. 歷史

如果覺得有些無聊,就去挖一挖歷史上比較火的可能和Java相關(guān)技術(shù),比如:

  • Applet,想想它比起html5+css3+javascript的缺點(diǎn)在哪里。
  • AWT、Swing,想想為什么很少有人用Java寫圖形界面程序。你覺得Swing的程序看上去舒服嗎?中國人和殘疾人喜歡用Swing程序嗎?
  • JNDI,想想它比起Spring Bean Container的缺點(diǎn)在哪里。
  • JSP,想想它比起MVC結(jié)構(gòu)的缺點(diǎn)在哪里。
  • WSDL/SOAP,把它們和XML-RPC、RESTful Web Service比較一下。
  • XSLT,以及為什么它是圖靈完備的。可是它真的比Java本身更好用嗎?
  • Log4j、java.util.logging、Apache Commons Logging,各自有什么問題,以及Log4j的作者本人為什么又開發(fā)了SLF4j和Logback?
  • Java最早是為什么設(shè)計(jì)的?
  • Type erasure是怎么回事?為什么ArrayList<int>不行但ArrayList<Integer>就可以?挖一挖歷史。

其實(shí)Java不算完全面向?qū)ο蟮恼Z言。Java更偏實(shí)用性,很多控制流(if語句、while循環(huán)、for循環(huán)等)來自面向過程的語言;基本數(shù)據(jù)類型(int, char, double等)也不是對(duì)象。但另一些語言,比如SmallTalk,更偏向純粹的面向?qū)ο蟮脑O(shè)計(jì),包括基本的數(shù)據(jù)類型都是對(duì)象,if/while/for等也用對(duì)象和方法來實(shí)現(xiàn)。比如:

基本數(shù)據(jù)類型也是對(duì)象,可以接受消息(即方法),比如:

(a + b) sqrt

這里面,a+b其實(shí)是向a發(fā)送“+”消息,參數(shù)是b。sqrt也是一個(gè)消息,發(fā)給一個(gè)數(shù)。

if分支是這樣做的:

(x < y) ifTrue: [ 
       max := y. 
       i := j 
     ] ifFalse: [ 
       max := x. 
       i := k 
     ]

ifTrue:ifFalse: 是一個(gè)Boolean對(duì)象的一個(gè)方法,取兩個(gè)參數(shù),每個(gè)是一個(gè)“塊”,分別在真和假的情況下執(zhí)行。

還有while循環(huán)是這樣做的:

[i < 100] whileTrue: [ 
       sum := sum + i. 
       i := i + 1 
     ]

whileTrue是“塊”的一個(gè)方法,每次對(duì)塊求值,如果是真,就反復(fù)執(zhí)行第一個(gè)參數(shù)(也是“塊”)。

所以,相對(duì)其他面向?qū)ο蟮恼Z言,Java并不算很“面向?qū)ο蟆?。所以需要補(bǔ)充一些對(duì)面向?qū)ο笳Z言的了解。



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容