- Java Web應用開發(fā)給力起飛
- 白靈等編著
- 7263字
- 2018-12-30 08:41:19
1.3 第一個任務——日記本
單純地學習一門語言不是本書的目的,將知識轉化為實際的運用才是筆者的意圖。現(xiàn)在開始本章的實踐任務——日記本程序。
也許讀者會問,最終要完成的不是一個Web社區(qū)系統(tǒng)嗎,做這個日記本有什么用呢?因為Web社區(qū)系統(tǒng)雖然比較龐大,但其核心的機能不過只有一條:信息發(fā)布。信息雖然多種多樣,但是從本質(zhì)上來講它們都一樣——不都是文字嘛。日記也是一種文字信息,把“信息發(fā)布”這個核心機能抽取出來,就成了日記本程序這個小玩意兒。讀者在日記本程序上積累的經(jīng)驗,完全可以遷移到社區(qū)系統(tǒng)上。
此外,在這個程序的完成過程中,讀者會熟悉 Java 的類、接口等基礎知識的具體應用,為以后的任務挑戰(zhàn)打好基礎。
1.3.1 設計日記本程序的類
“哎呀,你那么多廢話,我早就聽得不耐煩了,快告訴我怎么寫這個該死的日記本程序的代碼吧!”
先別著急,程序開發(fā)的第一步應該是分析設計。大多數(shù)人在初學編程的時候,都喜歡上手就開始寫代碼,而不習慣事先做一些設計思考,更別提將這些設計付諸于筆端了。這有兩個方面的原因:一是因為和“設計”這樣看似虛無縹緲的東西比起來,代碼是實實在在的,運行起來就很有成就感;二是初學編程時寫的都是一些小程序,前期設計的作用在這些小規(guī)模的程序上無法體現(xiàn)。但請讀者記住,在實際的編程之前做一些前期設計,必要時動筆在紙上寫一寫、畫一畫,是有百利而無一害的。簡單的設計圖表等能幫助程序員整理思路,回避一些不必要的錯誤。讀者如果能養(yǎng)成這樣的習慣,一定能受益匪淺。好了,下面就請讀者跟隨筆者花兩分鐘做些“煩人”的設計吧。
面向?qū)ο蟮某绦颍举|(zhì)上是對象之間的關系,所以設計的第一步就是找出這個程序里究竟有哪些對象。方法說來也很簡單:分析現(xiàn)實應用情景,從這些情境中抽出相應的“角色”,這些“角色”就是程序中的對象。
什么是“角色”呢?讀者可以把它理解為現(xiàn)實情境中的人和物。程序的根本目的在于解決現(xiàn)實中的應用問題,日記本程序就是為了解決“寫日記”這件事。這個人們再熟悉不過的“寫日記”的情景,涉及的人和物有哪些呢?
如圖1-8所示,筆者簡單抽出了以下角色:

圖1-8
■ 寫日記的人——可以稱之為用戶。
■ 用于寫日記的工具(日記本、筆等)。
■ 日記本身。
角色有了,與其對應的對象也就有了。下一步開始打造這些對象的模板——類。為簡單起見,這里暫時只關注User(用戶)和Diary(日記)兩個類。
User:在這個程序中,User 類只用于承載用戶信息,所以只為它設置幾個簡單屬性,即name(姓名)、gender(性別)、age(年齡)。
Diary:title(標題)、content(內(nèi)容)、time(時間)這3個屬性不難發(fā)現(xiàn)。此外,authorName (作者姓名)也作為屬性加入。
這兩個類的任務都只是信息的承載,除了屬性的讀取和設置的get、set方法之外,沒有其他的方法(在后面章節(jié)的Web開發(fā)任務中,讀者會經(jīng)常遇到這樣的類),用圖簡單表示它們,如圖1-9所示。

圖1-9 User類和Diary類
1.3.2 將類的設計轉為代碼
前期準備做好了,現(xiàn)在就請讀者把注意力轉向開發(fā)工具Eclipse,如圖1-10所示。接下來,筆者要用這個開發(fā)工具將前面的設計轉化為代碼。在此之前,請確認JDK和Eclipse等開發(fā)環(huán)境已經(jīng)準備完畢,筆者在附錄里詳細地介紹了安裝配置的方法。

圖1-10 打開Eclipse
Eclipse是一個開源項目,由著名的IBM公司投入資金主導,關于它的名稱也有不少趣聞。Java的“生父”是原Sun公司(目前Sun公司已被Oracle公司收購),Sun的字面意思為太陽,而Eclipse的意思為“日食”(見圖1-10)。IBM為什么取Eclipse這個名字呢?
“這真的很巧合,”IBM總監(jiān)Sutor表示,“我也不清楚當初為何會選上這個名稱。”
真的只是巧合嗎?不管怎樣,這個名字有待商榷的東西已經(jīng)成為Java領域最為著名的開發(fā)工具,有數(shù)不清的組織和個人為它不斷增添新功能。時至今日,Eclipse已經(jīng)成為一個龐然大物,用“博大精深”來形容它絕不過分,即使是有豐富開發(fā)經(jīng)驗的高手,也不敢說自己能玩轉它。所以,不要被它多得嚇人的按鈕和選項嚇到了,它們中的很大部分,讀者今后都不一定用得到,學習Eclipse 最好的方法是用到什么學什么。在例子學習中,只要按照講解一步一步地做就行了。此外,筆者也會將Eclipse的一些有用技巧告訴讀者。
【第1步】現(xiàn)在開始Eclipse之旅。打開Eclipse進入工作空間后,顯示如圖1-11所示的主界面。

圖1-11 Eclipse主界面
【第 2 步】新建一個工程作為類的容身之所。單擊左上角的“File”菜單項,在彈出的菜單中選擇第一項“New”,出現(xiàn)如圖1-12所示的菜單(也可使用快捷鍵“Alt+Shift+N”調(diào)出該菜單),選擇“Project”。

圖1-12 新建工程
Eclipse的快捷鍵
要用好一個開發(fā)工具,關鍵是熟悉它的快捷鍵,這比起用鼠標在菜單或按鈕上移來點去要快得多。Eclipse為用戶提供了很多方便的快捷鍵,按“Ctrl+Shift+L”組合鍵可以隨時調(diào)出當前可用的快捷鍵列表進行查看,如圖1-13所示。

圖1-13 Eclipse快捷鍵
如果對一些功能的快捷鍵設置不習慣,或者快捷鍵和Windows系統(tǒng)快捷鍵(如輸入法快捷鍵)有沖突,還可以對快捷鍵進行更改,方法是在按“Ctrl+Shift+L”組合鍵調(diào)出快捷鍵列表后,再次按下“Ctrl+Shift+L”組合鍵調(diào)出設置窗口,如圖1-14所示。

圖1-14 快捷鍵設置窗口
“這兩個‘Ctrl+Shift+L’組合鍵還真是簡單啊,Eclipse 快捷鍵的威力還真不小。‘工欲善其事,必先利其器。’很好,很強大!”
【第3步】選擇之后,彈出如圖1-15所示的窗口,在此可以選擇創(chuàng)建各種不同的工程,這里選擇“Java”項下的“Java Project”。

圖1-15 創(chuàng)建Java Project
【第4步】選定后,單擊下方的“Next”按鈕,出現(xiàn)如圖1-16所示的畫面,這一步是對新建的工程進行配置。在“Project name”后的文本框中輸入工程的名稱“diary”,其他的選項保持默認,然后單擊“Finish”按鈕。

圖1-16 創(chuàng)建工程diary
【第5步】初始狀態(tài)下,Eclipse的透視圖是“Java EE”透視圖,所以工程建立之后,Eclipse會彈出如圖1-17所示對話框,提示是否切換到Java 透視圖,單擊“Yes”按鈕。如果勾選對話框左下方的“Remember my decision”,則以后創(chuàng)建工程時,Eclipse均會自動切換到相應的透視圖。

圖1-17 提示是否切換到Java透視圖
Eclipse透視圖
Eclipse開發(fā)環(huán)境是由一個個小窗口——視圖(view)組成的。例如,用于瀏覽工程的“Project Explorer”視圖和用于管理任務的“Task”視圖。一個透視圖就是若干個視圖的組合,打開一個透視圖實際上就是打開與之關聯(lián)的一組視圖。
如圖1-18所示,名為“diary”的Java工程已經(jīng)創(chuàng)建好了,同時Java透視圖包含的視圖也打開了——右上角的等按鈕用于切換透視圖。

圖1-18 diary工程界面
【第6步】工程建立好了,現(xiàn)在來創(chuàng)建User和Diary這兩個類。再次使用快捷鍵“Alt+Shift+N”調(diào)出新建菜單,單擊“Class”新建一個類,出現(xiàn)如圖1-19所示的對話框。在這里對新建的類進行設置:在“Package”后的文本框中輸入包名“chapter1.diary.bean”;在“Name”后的文本框中輸入類名“User”;其他的選項保持默認。然后單擊“Finish”按鈕。完成以上步驟后,Eclipse 生成了標識符為public的類User,User類創(chuàng)建與之同名的源文件“User.java”。

圖1-19 新建User類
包與類的訪問修飾符
包(package)的存在主要是為了保證類名的唯一性,同名的類只要位于不同的包中,就不會產(chǎn)生沖突。包還可以組織類的層次關系,如在標準的Java包中,“java.lang”包下存放著Object和String等Java語言基礎類,“java.net”包下存放著Socket和URL等網(wǎng)絡應用程序類。包的嵌套關系就像操作系統(tǒng)中目錄的嵌套一樣,但是子包和父包之間、同級別的包之間沒有任何關系。一個包中的類可以任意使用同包中的其他類,但若想要使用其他包中的類,則需要通過import引入那個類,或是引入類所在的包。
訪問修飾符可以有兩種:public和默認(什么都不寫)。只有標志為public的類才能被其他包中的類引入使用。一個Java源文件只能有一個聲明為public的類,且該類必須與Java源文件同名(如類A對應源文件A.java)。
【第7步】User類創(chuàng)建完成之后,如圖1-20所示(用快捷鍵“Ctrl+M”可最大化當前視圖,再次按“Ctrl+M”組合鍵則可復原),為它加上name、gender、age 3個屬性。如果沒有特別的目的,類屬性的訪問修飾符應為private(私有)。這3個屬性下的黃色波浪線表示屬性在類中從未被訪問過(將鼠標移動至編輯視圖左側的黃色感嘆號上,可以看到相應的提示信息),暫時無須理會。

圖1-20 定義屬性
屬性及方法的訪問修飾符
可用于方法的訪問修飾符有3種:public、private、默認(就是什么都不寫)。
與類的訪問修飾符類似,標記為public的方法具有最寬松的訪問權限,它能被任意的其他類訪問(無論是同包還是不同包);private只有類自身的方法可以訪問;而使用默認的訪問修飾符的方法,只有同一個包中的類才能使用。
屬性的修飾符用法與方法完全相同,不過在沒有特殊目的的情況下,一般都將其設為private。
【第8步】現(xiàn)在來生成各屬性的get和set方法。選擇頂部菜單Source→Generate Getters and Setters,打開的對話框如圖1-21所示。

圖1-21 生成get和set方法
【第9步】單擊右上方的“Select All”按鈕,選擇全部3個屬性,然后單擊“OK”按鈕,自動生成3個屬性的get和set方法,結果如圖1-22所示。

圖1-22 生成的方法
【第10步】為了方便,筆者為User類加上了一個構造函數(shù)。選擇頂部菜單Source→Generate Constructor using Fields,打開如圖1-23所示的對話框,在這里可以決定構造函數(shù)初始化哪些屬性。默認情況下,全部屬性已經(jīng)選中,直接單擊下方的“OK”按鈕即可。

圖1-23 生成構造函數(shù)
結果如圖1-24所示,Eclipse已經(jīng)創(chuàng)建好了構造函數(shù)。該構造函數(shù)接收3個參數(shù),分別用于初始化3個屬性。

圖1-24 構造函數(shù)
關于super()
構造函數(shù)的第一句“super()”是做什么用的呢?它的作用是“調(diào)用該類的父類的無參數(shù)構造函數(shù)”。雖然這里沒用到繼承,但Java中的任何類,包括用戶自己創(chuàng)建的類,都是繼承自同一個“根”——Object類。由于繼承的存在,對象的創(chuàng)建過程是比較復雜的:假設讀者寫了A和B兩個類,其中B繼承自A,那么在B的構造函數(shù)的第一步必須調(diào)用A的構造函數(shù)(如果A還有父類,那么繼續(xù)調(diào)用該父類的構造函數(shù),依此類推,直到回溯至Object這個根)。這句代碼如果不寫,Java編譯器會自動插入一個對A的無參數(shù)構造函數(shù)的調(diào)用——super()。所以User構造函數(shù)中的super()實際上是不用寫的,不過為了加深讀者對它的印象,筆者沒有刪除它。
如果類B沒有無參數(shù)構造函數(shù)呢?這時就不能指望編譯器幫忙了,讀者只能手工加入對A的有參數(shù)構造函數(shù)的調(diào)用:super(參數(shù)1, 參數(shù)2,…)。
【第 11 步】一個類如果已經(jīng)定義了構造函數(shù),那么編譯器就不會自動為其創(chuàng)建無參數(shù)構造函數(shù)了,所以筆者再按上面的方法為User類創(chuàng)建一個無參數(shù)構造函數(shù),如圖1-25所示。

圖1-25 無參構造函數(shù)
如果讀者在編寫代碼的過程中,覺得代碼擠在一起太難看,可以用代碼格式化快捷鍵“Ctrl+Shift+F”,效果如圖1-26所示。是不是清爽多了?

圖1-26 自動調(diào)整格式
小提示
使用代碼格式化快捷鍵時,Eclipse是按照當前的格式模板來格式化代碼的,格式模板中設定了換行、縮進及代碼對齊的方式等。
如果要更改當前的格式模板或建立自己的格式模板,可以單擊頂部菜單Window→Preferences,在彈出的Preferences窗口的左側樹形菜單中,選擇Java→Code Style→Formatter;在右側界面中,可選擇要使用的代碼模板,初始情況下有3套內(nèi)建模板可供選擇,分別是Java Conventions(Java傳統(tǒng)格式)、Eclipse(默認)及Eclipse2.1。單擊“new”即可基于3套模板之一建立自己的模板。
【第12步】用同樣的方法建立Diary類,其中屬性time為GregorianCalendar類型(Java提供的日歷系統(tǒng)類型),title、content和authorName為String字符串類型。完成后的Diary類如圖1-27所示。

圖1-27 Diary類
現(xiàn)在需要測試一下這兩個類。首先,在User類中產(chǎn)生main方法。讀者應該還記得main方法的寫法,不記得也沒關系,這里要向讀者介紹Eclipse中最方便的功能——內(nèi)容輔助(Content Assist)。
【第1步】在要插入main方法的地方,輸入“main”,然后按快捷鍵“ALT+/”。在main的右方會出現(xiàn)浮動窗口,浮動窗口內(nèi)列出了可供插入的代碼,如圖1-28所示。

圖1-28 浮動窗口
【第2步】默認選中的第1項“main-method”就是需要的main方法,直接按“Enter”鍵或是雙擊這一項即可,結果如圖1-29所示。

圖1-29 添加main方法
小提示
內(nèi)容輔助可以說是Eclipse中最常用的輔助鍵了。長長的類名、變量名記不住?沒關系,只要輸入類名的前幾個字母,按內(nèi)容輔助鍵。Eclipse就會將符合條件的類名或變量名列出。
for和while等循環(huán)語句懶得寫?沒關系,只要輸入一個for或while,按內(nèi)容輔助鍵,Eclipse就會列出許多種循環(huán)語句的代碼讓你選擇……總之,內(nèi)容輔助鍵簡直就是對付代碼的神兵利器,多研究并利用它,可以節(jié)省很多的時間。
現(xiàn)在請讀者來關注這個用于測試User類和Diary類的main方法的內(nèi)容(參見清單1-3):如下的代碼模擬了這樣一個簡單過程:一個名叫“JavaWeb愛好者”的20歲男用戶不停地寫了3篇日記,第i篇日記的標題為“第i篇日記”,內(nèi)容為“第i篇日記的內(nèi)容”(i=1,2,3)。
清單1-3

這段代碼很簡單,首先創(chuàng)建一個User對象,接著用User對象的name作為authorName創(chuàng)建5個Diary對象,將這5個對象放入一個ArrayList容器中。最后,從ArrayList容器中依次取出5個Diary對象,向控制臺輸出每個Diary對象的信息。
請讀者注意代碼中,GregorianCalendar類型提供了get方法,該方法接受類本身提供的一系列類常量作為參數(shù),返回對應的年、月、日等時間值。注意GregorianCalendar中的月份是0~11,換算成實際的月份需要加1。
增強型for循環(huán)與泛型
從 JDK 1.5 開始支持的增強型 for 循環(huán)能自動遍歷數(shù)組等容器中的對象,類似其他語言中的 for each。其語法簡單,使用起來非常方便。
JDK 1.5也支持“泛型”。它主要應用于ArrayList、HashTable等容器類中。在泛型出現(xiàn)以前,容器類對一切類型的對象都來者不拒:比如一個ArrayList,User類和Diary類的對象都可以往里裝。這樣固然方便,但是也有明顯的缺點:第一,容易錯誤地裝入不恰當類型的對象,想象一下,一個全是“羊”類型對象的數(shù)組里,突然混入一個“狼”類型的對象是什么情景;第二,從容器中取出的對象一概被識別為Object,只能通過強制類型轉換將其還原為原本的類型,如:
Diary diary = (Diary)diaries.get(0); (取出diaries容器中的第一個對象)
應用了泛型之后,帶有<E>類型參數(shù)的容器類,只能裝入E類的對象,不僅減少了出錯的可能,對象取出之后也不必再進行強制類型轉換了,使用更加方便,而且不易出錯。
類常量
一個類中被public static final修飾的屬性稱為類常量。3個修飾符的共同作用造就了這種特殊的類屬性,public在前文已有闡述,那么static和final是什么呢?
static(靜態(tài))修飾的屬性可以直接通過“類名.屬性名”的方式進行訪問。它修飾的方法也可以通過“類名.方法名”的方式進行訪問。static就像是一塊將屬性和方法從對象級別墊高到類級別的“磚頭”。
final(終態(tài))修飾的類不能被繼承;final修飾的方法不能在繼承中被覆蓋;final修飾的屬性必須在聲明時直接初始化或在構造函數(shù)中初始化,一旦初始化,其值就不能被更改。final就像是一個將類、屬性、方法固定住的“定型膠水”。
綜上,類常量是類層次的恒值屬性。一些“工具值”常常以類常量的形式出現(xiàn),如java.lang.Math類中表示圓周率的PI和表示自然對數(shù)底數(shù)的E等。
【第3步】在Eclipse中運行一下這段代碼,當前激活窗口為User.java的情況下,選擇頂部菜單Run→Run As→Java Application(或使用快捷鍵“Alt+Shift+X,J”)即可。運行完畢后,在如圖1-30所示的Console視圖中顯示出了程序的輸出語句。注意,其中的時間是作者運行該程序時的時間,讀者的運行結果取決于當時的具體時間。如果Console視圖沒顯示在當前透視圖中或誤將其關閉,選擇頂部菜單Window→Show View→Console或使用快捷鍵“Alt+Shift+Q,C”即可。

圖1-30 Console窗口
現(xiàn)在Use類和Diary類已順利完工。下一小節(jié)就將用這兩個類組裝出日記本程序了。
1.3.3 組裝日記本程序
在本節(jié)中,讀者的任務是用已經(jīng)創(chuàng)建好的User類和Diary類,結合本書提供的圖形界面類,組裝出一個帶有用戶界面的日記本程序。
界面框架使用Java swing的GUI (Graphical User Interface,圖形用戶界面)庫搭建。Java GUI只是作為任務輔助,不在本書的講解范圍內(nèi),讀者對其中的代碼細節(jié)大可不必理會。
【第 1 步】首先為圖形界面類創(chuàng)建獨立的包,使用快捷鍵“Alt+Shift+N”調(diào)出新建菜單,單擊“Package”新建一個包。在“Name”后的文本框中輸入“chapter1.diary.gui”,單擊“Finish”按鈕,如圖1-31所示。

圖1-31 新建包
如圖1-32所示,在Package Explorer視圖中新建的包出現(xiàn)了。不過,它現(xiàn)在只是一個空包。

圖1-32 包瀏覽器窗口
【第2步】打開資源包中的chapter1文件夾,復制其中的DiaryWindow.java、boy.png等文件。然后在Package Explorer視圖中用鼠標右鍵單擊剛才新建的包,在彈出的菜單中單擊“Paste”粘貼,將3個文件導入包中(也可以直接采取拖曳的方式,將3個文件拖入包中)。完成后如圖1-33所示。

圖1-33 導入文件
【第3步】還需要新建一個包“chapter1.diary.main”,在該包下新建一個類作為運行日記本程序的主類,類名為DiaryMain,它只有一個main方法。直接選擇新建一個類,如圖1-34所示,在“Package”后的文本框中填寫“chapter1.diary.main”,在“Name”后的文本框中填寫“DiaryMain”。

圖1-34 創(chuàng)建DiaryMain類
【第4步】參考前面的內(nèi)容,為DiaryMain添加main方法,結果如圖1-35所示。

圖1-35 main方法
新建完DiaryMain類之后,工程的包結構圖就變成了如圖1-36所示的樣子。

圖1-36 diary工程包結構圖
接下來,將要為讀者講解如何編寫這個開啟日記本程序的main方法。
首先,讀者需要了解DiaryWindow這個界面窗口類的使用方法。DiaryWindow需要讀者關注的只有兩個方面:
怎樣創(chuàng)建它?——它的構造函數(shù)是什么?
怎樣顯示它?——調(diào)用的方法是什么?
現(xiàn)在就來解決這兩個方面的問題,首先來看看DiaryWindow的構造函數(shù):
chapter1.diary.gui.DiaryWindow public DiaryWindow (User user)
這個構造函數(shù)非常簡單,只需要傳入一個User對象即可,DiaryWindow會用這個User對象的各項屬性值顯示作者信息。
接下來,要顯示這個窗口只需調(diào)用以下這個方法:
chapter1.diary.gui.DiaryWindow 繼承自 java.awt.window public void setVisible (boolean b)
這個方法接收一個boolean類型的參數(shù),若為“true”則顯示窗口,若為“false”則隱藏窗口。窗口創(chuàng)建和顯示的問題都解決了,現(xiàn)在可以動手來寫DiaryMain類的main方法了(參見清單1-4)。
清單1-4

清單1-4是筆者給讀者的DiaryMain示例代碼,請讀者可以模仿并創(chuàng)建與自己的個人信息相同的User對象傳入,試驗一下。
下面來示范一下用戶是如何在這個程序里寫入并保存日記的。
【第1步】執(zhí)行該main方法,顯示的程序窗口如圖1-37所示。

圖1-37 新日記窗口
【第2步】當前還沒有任何日記。單擊“寫新日記”按鈕,就會顯示如圖1-38所示的窗口。讀者可以輸入新日記標題及內(nèi)容,然后單擊“保存”按鈕。

圖1-38 保存窗口
【第3步】為了避免誤操作,這個程序還需要用戶確認是否保存日記,如圖1-39所示。

圖1-39 確認保存
【第4步】單擊“確定”按鈕保存,日記就保存完畢了,如圖1-40所示。

圖1-40 保存成功
用戶使用同樣的方法,可以不斷添加日記。當用戶需要查看某個日記的具體內(nèi)容時,只需要在圖1-37所示的列表中,雙擊該日記即可。
另外,這個程序還提供了一個“選項”菜單,讀者單擊其中的“主人信息”就會顯示如圖1-41所示的對話框,其內(nèi)容與傳入的user對象的屬性完全一致,根據(jù)user對象的gender屬性,顯示的小人圖標也會不一樣。讀者可以嘗試將傳入?yún)?shù)user的gender設為“女”試試。

圖1-41 主人信息
這里要提醒讀者,因為這個程序是作為基礎講解的,所以并未設置嚴格的錯誤處理。比如,user的 gender 屬性完全可以賦值為“男”和“女”之外的任意字符串,所以請讀者注意將屬性參數(shù)設置正確,并嚴格按照之前的講解配置各種源文件及圖像文件,否則可能會導致運行出錯。
雖然簡陋了點,但至此,讀者的日記本程序算是初步完工了。一直到這里的任務,如果讀者都順利完成的話,可以為自己小小地慶祝一下了!
- 深度實踐OpenStack:基于Python的OpenStack組件開發(fā)
- JavaScript前端開發(fā)模塊化教程
- 數(shù)據(jù)庫程序員面試筆試真題與解析
- Learn Type:Driven Development
- Building a RESTful Web Service with Spring
- Android Development with Kotlin
- Getting Started with PowerShell
- Full-Stack React Projects
- C++ 從入門到項目實踐(超值版)
- Yocto for Raspberry Pi
- Android開發(fā):從0到1 (清華開發(fā)者書庫)
- 時空數(shù)據(jù)建模及其應用
- Spring MVC+MyBatis開發(fā)從入門到項目實踐(超值版)
- 從Excel到Python數(shù)據(jù)分析:Pandas、xlwings、openpyxl、Matplotlib的交互與應用
- Get Your Hands Dirty on Clean Architecture