Java是一個通用的編程語言,其實可以干很多事,怎么學(xué)Java就看怎么用了,但有一些一般的步驟:
熟悉一種文本編輯器,比如Vim, Emacs, Notepad++, TextMate等。知道哪些是開源的,哪些是閉源的,哪些要收費。養(yǎng)成不用盜版軟件的習(xí)慣。
安裝JDK(建議用你的Linux發(fā)行版自帶的軟件包管理器安裝openjdk,過程中可能需要讀發(fā)行版特定的文檔)
寫一個Java的Helloworld程序,并用命令行工具javac編譯,再用java命令運行這個程序。過程中熟悉源代碼、字節(jié)碼、虛擬機這些東西,以及Java的包(package)對.class文件所在的路徑的影響。如果這兩個命令行工具使用熟練了,可以開始選一個喜歡的集成開發(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)、接口、接口實現(xiàn)。順便學(xué)習(xí)一下面向?qū)ο蟮幕舅枷耄磳ο蟆⑾ⅰ⒎庋b、繼承、多態(tài)等,這些通用的內(nèi)容不是Java特有的。這時候應(yīng)該已經(jīng)涉及了Java的垃圾回收。要留意即使有垃圾回收的情況下也會發(fā)生的內(nèi)存泄露(如自己設(shè)計數(shù)組容器,元素是引用,邏輯上刪除了元素,但并沒有清成null)。注意垃圾回收只能回收內(nèi)存中的對象,除了內(nèi)存以外,其它資源不能依靠垃圾回收來關(guān)閉。比如,文件、管道、Socket、數(shù)據(jù)庫連接等,垃圾回收是不會幫你關(guān)閉的。
學(xué)習(xí)Java的異常處理,但更重要的是學(xué)習(xí)什么時候用特殊返回值而不使用異常,什么時候應(yīng)該拋出異常而不處理異常,知道什么是pokemon catch及其危害,了解為什么Java的checked exception是一個糟糕的特性。如果愿意,同時學(xué)習(xí)一下Java1.7的try-with-resource語句和AutoCloseable接口。
熟悉Java常用的數(shù)據(jù)結(jié)構(gòu),如基本的數(shù)組類型,以及泛型容器(java.util.*),尤其是java.util.List接口和java.util.ArrayList實現(xiàn);以及java.util.Map接口和java.util.HashMap實現(xiàn)。(java1.5以前的沒有泛型參數(shù)的就不用碰了)同時留意一下基本類型int, double等和裝箱類型Integer和Double的區(qū)別,以及它們是如何自動轉(zhuǎn)換的。
熟悉Java標(biāo)準(zhǔn)庫里的各種工具,包括日期時間、字符串格式化、IO等。**知道文件要自己在finally子句中close(),或者用Java1.7的try-with-resource,不要妄想垃圾回收器會幫你關(guān)掉文件。
學(xué)習(xí)一下Java的命名習(xí)慣,以及JavaBeans的常規(guī),知道為什么getter/setter比直接操作成員變量好。按這種方式給Java的變量、方法命名。同時看看你的IDE能不能自動幫你生成getter和setter。
使用一個第三方的庫(比如Apache Commons Lang通用工具庫),讓你的程序依賴于它的二進制jar包(而不是直接拷貝源代碼),用命令行編譯、運行(注意classpath等);也熟悉一下如何用你的集成開發(fā)環(huán)境添加第三方依賴。感受一下手動管理依賴關(guān)系的麻煩。
學(xué)習(xí)Maven的使用,試著讓Maven幫你解決依賴關(guān)系,再試著讓Maven幫你創(chuàng)建一個Eclipse工程。再試試用Maven打包發(fā)布。
學(xué)習(xí)軟件測試,以及JUnit的使用,以及怎么在IDE中使用JUnit。有空看一下coverage工具。
讀讀四人幫寫的《設(shè)計模式》(這本書是用C++和Smalltalk語言為例子的,但仍然適合Java)。具體的是這本書,http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612圖書館應(yīng)該能還借到英文原版,因為我借到過。
接下來就看具體要做哪方面的應(yīng)用了,看需求。比如(下面的沒有順序)
-
關(guān)于語言
- 如果學(xué)Java學(xué)得不舒服了,學(xué)Python。
- 如果對面向?qū)ο缶幊痰母拍钣悬c不習(xí)慣,學(xué)Smalltalk。(Ruby也行,但不如Smalltalk經(jīng)典。Ruby的文檔是一大硬傷。)
- 如果嫌Java太啰嗦,學(xué)Python
- 如果嫌Java太啰嗦,又想用JVM,自己又有精力,學(xué)Scala
- 如果對對象之間的關(guān)系有點暈,學(xué)一學(xué)UML,以及它的一些圖,可以對程序和運行進行直觀的建模。你的IDE也許有插件可以生成UML圖。但是不要太沉迷于這些方法論。
調(diào)試和輔助工具
學(xué)習(xí)一下你的集成開發(fā)環(huán)境提供的調(diào)試工具,加一些斷點試試。
- 試試用jconsole或者VisualVM監(jiān)控另一個jvm的狀態(tài)。
- 用profiling工具尋找程序中慢的地方。Eclipse有profiling工具。VisualVM也有這樣的功能。(如果不介意使用閉源軟件的話,也試試JProfiler和YourKit)
- 有的JVM允許在運行時更新代碼。Eclipse可以和某些JVM集成。這樣你可以頻繁修改代碼而不用頻繁重啟JVM。對于某些“重型”工程很有用。(如果不介意使用閉源軟件的話,也試試jRebel)
- 多線程
學(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)存多線程編程”以外有沒有別的模型(多進程multi-processing、消息傳遞message passing等)。
-
反射、元編程
- 學(xué)習(xí)Java的反射機制,以及Annotation的用法。
- 如果還舒服,試試java.lang.reflect.Proxy的用法。
- 如果仍然還舒服,玩一玩CGLib(一個第三方的庫)。
網(wǎng)絡(luò)編程
學(xué)習(xí)一下IP,TCP協(xié)議(計算機專業(yè)的應(yīng)該學(xué)過,復(fù)習(xí)一下),學(xué)習(xí)Socket編程(注意垃圾回收器不會幫你關(guān)掉Socket)。
- 如果不是很關(guān)心HTTP,看看java.nio,學(xué)習(xí)單線程輪詢式IO復(fù)用(Selector)。
- 如果有點不明白nio的意圖的話,了解一下c10k問題。 http://www.kegel.com/c10k.html
- 如果身體沒有異樣的話,大概了解一下操作系統(tǒng)(包括C語言)提供的select, poll, epoll, kqueue等接口。
- 如果身體仍然沒有異樣的話,試著用java.nio寫一個文件服務(wù)器。
- 如果還有精力的話,上網(wǎng)扒一扒有沒有其他的通信庫,如netty等。
- 如果關(guān)心Web還有HTTP,就學(xué)習(xí)一下HTTP協(xié)議,以及用Java進行HTTP的客戶端編程。
- 如果還舒服,學(xué)學(xué)HTML,寫寫HTML的靜態(tài)網(wǎng)頁(不需要Java)
- 如果還舒服,用Java寫一個基于DOM、XPath或者CSS Selector的網(wǎng)頁解析器(爬網(wǎng)頁)。
- 如果還舒服,學(xué)學(xué)Java的Servlet接口(先別學(xué)jsp)進行Web服務(wù)器端編程。學(xué)學(xué)標(biāo)準(zhǔn)的Servlet容器怎么用,包括web.xml的用法以及l(fā)istener、filter等概念。以及某個Servlet容器(如Jetty或者Tomcat)的具體用法。
- 如果仍然還舒服,試著學(xué)一種模板語言(如haml, velocity, freemarker,【還有其他更好的框架嗎?我不知道】, String.format,如果真的想學(xué)JSP的話JSP倒是也行,但不推薦)。
- 如果仍然覺得舒服,學(xué)學(xué)Spring框架中的Web框架,或者Struts,看你的口味。
- 如果還舒服,看看Spring Bean Container以及里面各種亂七八糟的工具。
- 如果還舒服,或者有需求,了解一下什么是RESTful Web Service,復(fù)習(xí)一下HTTP,找找適合的Java工具。
- 你可能會覺得Jackson是一個解析JSON用的好用的東西。
- 數(shù)據(jù)庫
學(xué)習(xí)一下關(guān)系數(shù)據(jù)庫(計算機專業(yè)的應(yīng)該學(xué)過,復(fù)習(xí)一下),包括SQL。選一個數(shù)據(jù)庫管理系統(tǒng)熟悉一下(比如MariaDB,或者(如果你不討厭Oracle的話)用被Oracle收購了的MySQL。先脫離Java單獨學(xué)學(xué))。然后看它們的官方文檔教你怎么用Java連接這種數(shù)據(jù)庫。這中間會涉及到JDBC接口。同時一定要知道SQL注入安全漏洞,以及掌握如何用PreparedStatement防止注入!!。建議看 http://bobby-tables.com/
- 可能中間會涉及“事務(wù)”問題,讓你不知不覺地開始去了解java transaction api(JTA)。
- 如果還舒服,學(xué)一學(xué)對象關(guān)系轉(zhuǎn)換(如Hibernate)。
- 也可以學(xué)學(xué)非關(guān)系數(shù)據(jù)庫,以及如何用Java訪問它們。
- 日志記錄
學(xué)習(xí)一下slf4j和logback的用法。
- 如果有精力的話,大概了解一下世界上有多少種Java日志框架,以及slf4j是怎么橋接這些框架的。
- 構(gòu)建(build)系統(tǒng)
學(xué)習(xí)一下Ant的用法。
- 如果還舒服的話,學(xué)習(xí)一下用Ivy從Maven的倉庫里下載軟件包,解決依賴關(guān)系。
- 版本控制
學(xué)習(xí)一種分布式版本控制器(如Git、Mercurial、Bzr、Darcs等,推薦Git)的基本用法,以及如何用它管理Java工程。希望你已經(jīng)開始使用Maven了,并且知道為什么把IDE生成的工程文件(如eclipse的.project,.classpath和.metadata)放入版本控制器不好。然后了解一下如何在IDE中使用版本控制(Eclipse自帶Git插件)。
- 如果感覺很舒服的話,為你們實驗室搭建一個Linux+SSH+Git服務(wù)器,裝個GitLab(一種Web界面)。
- 了解“集中式版本控制器”和“分布式版本控制器”的區(qū)別,并說服同事們不要再用SVN、CVS或者SourceSafe等老舊的“集中式版本控制器”了。
- 開設(shè)一個GitHub賬戶。如果你不喜歡Git,就用BitBucket等。
- 持續(xù)集成
自己(或者為你們實驗室)搭建一個持續(xù)集成(Continuous Integration)服務(wù)器,如Jenkins,定期編譯你的程序。建議同時使用Git等分布式版本控制器。
- 如果你做開源軟件,試試GitHub和Travis。
- 零碎工具
淘一淘java.nio.files里面有什么好用的東東,然后再淘一淘Apache Commons Lang和Commons IO里有什么好用的工具。Commons Logging就不要再用了,用SLF4j和Logback。
- XML
學(xué)學(xué)XML、DOM、XPath。XML這東西到處都可能用到。也可以用它寫自己的配置文件。
- 如果覺得不舒服了,就學(xué)學(xué)JSON和YAML。
- 如果還是不舒服,就學(xué)學(xué)文本文件解析。
- 語法分析和編譯器
學(xué)學(xué)Antlr或者別的Parser Generator的用法
- 如果覺得舒服,自己寫一個計算器。
- 如果還覺得舒服,自己寫一種Domain-Specific Language (DSL)。
- 高效容器
學(xué)學(xué)FastUtil或者Trove,如果你需要進行大量數(shù)值運算的話。
- 分布式計算
學(xué)學(xué)MapReduce的思想以及它的實現(xiàn)。
- 如果還舒服,學(xué)學(xué)Scala語言以及號稱比MapReduce快得多的Apache Spark。
- 進程間通信
看看ActiveMQ、MINA和RMI。
- 其他語言(JVM)
學(xué)習(xí)另一門跑在JVM上的語言或者實現(xiàn)(如Groovy、Scala、Clojure、JRuby、Jython、JavaScript……)
- 如果還舒服,學(xué)一學(xué)Java Scripting API(注意不是JavaScript。給個鏈接:http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/ ),然后試著在自己的Java程序里嵌入腳本。
- 其他語言(非JVM)
學(xué)習(xí)另一門通用腳本語言(如Python、Ruby,其實perl也行,但不推薦),知道什么時候Java不是最好的選擇。
- Java語言和Java虛擬機
通讀一遍(一目十行地讀,不用細(xì)讀)Java Language Specification,以及Java Virtual Machine Specification。
- 了解以下解釋器(interpreter)、編譯器(compiler)、即時編譯器(just-in-time compiler)和優(yōu)化器(optimiser)的概念。
- 如果對編譯器的話題不感到畏懼,了解一下method JIT和tracing JIT的概念和區(qū)別。
- 內(nèi)存管理
學(xué)學(xué)垃圾回收的幾種基本算法,包括mark-sweep、mark-compact、semi-space、generational、mark-region等,各自的性能,以及為什么樸素的reference counting是不完整的。知道為什么finalizer性能很糟糕,而且標(biāo)準(zhǔn)并不要求finalizer在程序退出前一定會執(zhí)行。
- 如果還舒服,了解一下如何設(shè)置Java虛擬機的堆大小限制(如HotSpot虛擬機的-Xmx選項等)。
- 了解一下Java里的WeakReference以及SoftReference和PhantomReference,以及它們什么時候有用,以及為什么它們實現(xiàn)起來有些困難。
- 如果有精力,了解一下Hotspot虛擬機的內(nèi)存管理算法是什么樣的。
- 動態(tài)裝載
學(xué)學(xué)Java的動態(tài)裝載(class loading)
- 如果還舒服的話,學(xué)學(xué)OSGI以及它的一種實現(xiàn)(如Felix或者Equinox)
- 如果仍然很舒服的話,學(xué)學(xué)寫基于Eclipse平臺的程序。不是Eclipse集成開發(fā)環(huán)境,只是利用他們的圖形框架,寫自己的應(yīng)用程序。
- 如果還覺得舒服的話,寫Eclipse集成開發(fā)環(huán)境的插件。
- 本地/外語接口
學(xué)習(xí)一下Java Native Interface(JNI),試著寫一個Java和C語言混合編程的程序。
- 如果覺得不舒服了或者覺得欲仙欲死,就學(xué)一學(xué)Java Native Access(JNA),試一試不用任何膠水代碼而從Java直接裝載C庫,直接調(diào)用C函數(shù)。
- 如果連JNA也懶得學(xué),就學(xué)一學(xué)SWIG,自動生成綁定。
- 如果覺得舒服,就學(xué)一學(xué)Java Virtual Machine Tooling Interface(JVMTI),用C程序來監(jiān)視JVM的狀態(tài)。
- 密碼學(xué)
學(xué)一學(xué)密碼學(xué),包括編碼、密碼分析、攻擊、對稱密鑰、公鑰系統(tǒng)、數(shù)字簽名、哈希算法等,看看Java有沒有實現(xiàn)。
- 如果覺得有點不舒服(你應(yīng)該不會覺得舒服吧,除非你是學(xué)密碼學(xué)的,要不然總會覺得自己寫的程序有安全漏洞),就寫一個“人品計算器”來放松一下,要求每次輸入同一個姓名,得到的人品值是固定的,但又要讓人無法用別人的人品值猜自己的人品值。
- 移動終端
學(xué)一學(xué)Android開發(fā)。
- 如果有精力的話,看看Dalvik虛擬機是怎么回事。
- 建議買一個iPhone或者iPad,或許你再也不想用Android手機或者平板了。
- 歷史
如果覺得有些無聊,就去挖一挖歷史上比較火的可能和Java相關(guān)技術(shù),比如:
- Applet,想想它比起html5+css3+javascript的缺點在哪里。
- AWT、Swing,想想為什么很少有人用Java寫圖形界面程序。你覺得Swing的程序看上去舒服嗎?中國人和殘疾人喜歡用Swing程序嗎?
- JNDI,想想它比起Spring Bean Container的缺點在哪里。
- JSP,想想它比起MVC結(jié)構(gòu)的缺點在哪里。
- WSDL/SOAP,把它們和XML-RPC、RESTful Web Service比較一下。
- XSLT,以及為什么它是圖靈完備的。可是它真的比Java本身更好用嗎?
- Log4j、java.util.logging、Apache Commons Logging,各自有什么問題,以及Log4j的作者本人為什么又開發(fā)了SLF4j和Logback?
- Java最早是為什么設(shè)計的?
- Type erasure是怎么回事?為什么ArrayList<int>不行但ArrayList<Integer>就可以?挖一挖歷史。
其實Java不算完全面向?qū)ο蟮恼Z言。Java更偏實用性,很多控制流(if語句、while循環(huán)、for循環(huán)等)來自面向過程的語言;基本數(shù)據(jù)類型(int, char, double等)也不是對象。但另一些語言,比如SmallTalk,更偏向純粹的面向?qū)ο蟮脑O(shè)計,包括基本的數(shù)據(jù)類型都是對象,if/while/for等也用對象和方法來實現(xiàn)。比如:
基本數(shù)據(jù)類型也是對象,可以接受消息(即方法),比如:
(a + b) sqrt
這里面,a+b其實是向a發(fā)送“+”消息,參數(shù)是b。sqrt也是一個消息,發(fā)給一個數(shù)。
if分支是這樣做的:
(x < y) ifTrue: [
max := y.
i := j
] ifFalse: [
max := x.
i := k
]
ifTrue:ifFalse: 是一個Boolean對象的一個方法,取兩個參數(shù),每個是一個“塊”,分別在真和假的情況下執(zhí)行。
還有while循環(huán)是這樣做的:
[i < 100] whileTrue: [
sum := sum + i.
i := i + 1
]
whileTrue是“塊”的一個方法,每次對塊求值,如果是真,就反復(fù)執(zhí)行第一個參數(shù)(也是“塊”)。
所以,相對其他面向?qū)ο蟮恼Z言,Java并不算很“面向?qū)ο蟆薄K孕枰a充一些對面向?qū)ο笳Z言的了解。
- 文章轉(zhuǎn)自:北郵論壇