第1篇-如何編寫一個面試時能拿的出手的開源專案?
編寫一個不錯的開源專案至少有3個好處:
(1)練技術,長經驗
(2)面試時展現自己的Coding能力
(3)獲取成就感
練技術,長經驗是最實在的,不過如果自己有一個好的開源專案,還可以在開源中國或github上開源,讓更多人受益,也許能獲得許多的Star,讓自已獲得滿足,激勵自己完善專案功能。在面試時,也可以在簡歷顯眼的位置給出開源專案名稱和Git地址。面試官一般都會去檢視,這是程式設計師實力的最好見證,是自己Coding能力的最好見證。所以如果要編寫一個面試時拿的出手的專案,首先需要做到“規範”,下面談一下我眼中規範的開源專案。
1 專案規範
1.1 規範編寫README.md
README.md檔案是一個專案的入門手冊,裡面介紹了整個專案的使用、功能等等。所以README檔案寫得好不好,關係到這個專案能不能更容易的被其他人瞭解和使用。
首先最起碼要做到的就是格式要清晰,讓人一眼能看出層次感,例如分幾個大標題對專案進行介紹,最簡單的就是分為如下的4部分:
- 專案名及簡介:簡單介紹一下這個專案是做什麼的。有的話最好加上demo地址;
- 功能:你這個專案可以實現的功能;
- 用法:這可以說是最重要的,一定要讓別人看得懂你這專案是怎麼使用的;
- 其他:作者或者是維護人列表、版權、鳴謝、貢獻、logo、聯絡方式等等,這些有的話當然會更加高大上。
1.2 使用版本管理工具
1.3 好的程式碼書寫習慣
許多面試官司也會看具體的專案實現,所以專案模組劃分要清晰,模組名稱要見名之意,具體的程式碼書寫要規範,現在許多大公司都有自己的程式碼規範,我們可以好好學一下阿里的Java程式碼規範。1.4 有完整的測試用例
2 Javac AST View外掛的開發
下面博主打算寫一個系列的博文,從零編寫一個“規範”的開源專案,好在以後面試中更多的展現自己的實力。今天先簡單介紹一下這個專案,並且為這個專案做一些準備工作。2.1 專案介紹
開發一個類似Eclipse AST View的外掛,安裝的過程見如下博文:
https://www.cnblogs.com/nettee/p/4463841.html
這個外掛的詳細使用說明的連結如下:
https://www.eclipse.org/jdt/ui/astview/
安裝後就可以直觀地檢視抽象語法樹了,舉個例子,如下:
package com.compiler; import java.util.List; public class C { public void test(List<String> list){ list.add("a"); } }
語法樹如下:
不過這個外掛顯示的是基於Eclipse JDT中的增量式編譯器ECJ的抽象語法樹,而我們經常使用的OpenJDK中的Javac編譯器的抽象語法樹與ECJ的抽象語法樹並不相同,不過絕大多數的語法樹節點劃分是一樣的,但是有少量的節點劃分不一樣,我打算開發一個類似Eclipse AST View的外掛,用來顯示Javac編譯器的抽象語法樹。
2.2 專案知識儲備
開發這樣的外掛需要了解JDT編譯器和Javac編譯器的抽象語法樹,同時還需要掌握Eclipse下的外掛開發,參考的相關資源如下:
第一本就是《Eclipse外掛開發學習筆記》,開發Eclipse外掛必須要有外掛開發相關基礎,這本書發版時間很早,但是外掛開發的基本思想是不會變的。另外官方的Eclipse API也是開發中必不可少的資料。
有了外掛開發基礎後就需要了解OpenJDK的Javac編譯器和Eclipse JDT中的增量式編譯器ECJ了,重點就是了解這兩個編譯器對抽象語法樹節點的表示。對Javac編譯器來說,還需要了解從Java原始碼解析為抽象語法樹的過程,參考的資料為《深入解析Java編譯器:原始碼剖析與例項詳解》。Eclipse JDT中的增量式編譯器ECJ的抽象語法樹可以通過博文Eclipse AST抽象語法樹API來了解,沒有相關的書籍。不過由於是在Eclipse中開發外掛,所以直接呼叫Eclipse相關API來獲取抽象語法樹就可以了,不需要自已編寫Java原始碼轉換為抽象語法樹的程式碼實現。所以Eclipse AST View整個專案的實現也相對簡單。
把Eclipse AST View專案的原始碼匯入到Eclipse中,這樣就可以通過閱讀、除錯的方式來學習這個外掛了,然後參考這個外掛來寫我自己的Javac AST View外掛。專案原始碼結構如下:不得不說,閱讀別人的程式碼也是學習的最好方式之一。
2.3 編寫專案框架
編寫的外掛中主要使用了樹外掛,JFace為樹控制元件提供了檢視器Viewer。在檢視器框架中,將模型稱為輸入,檢視器本身充當控制器的角色,而樹控制元件本身作為檢視,當輸入改變時,檢視器負責相應地改變控制元件的內容。
檢視器框架主要由以下幾部分構成。
(1)模型和元素-儲存著要顯示在控制元件中的資料模型,我們編寫的抽象語法樹節點模型如下:
package astview; import java.util.ArrayList; import java.util.List; public class JavacASTNode { private int id; private String name; private List<JavacASTNode> children; private JavacASTNode parent = null; public JavacASTNode() { children = new ArrayList<JavacASTNode>(); } public List<JavacASTNode> getChildren() { return children; } public void setChildren(List<JavacASTNode> children) { this.children = children; } public JavacASTNode getParent() { return parent; } public void setParent(JavacASTNode parent) { this.parent = parent; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return name; } }
(2)內容提供者和標籤提供者-負責將資料模型轉化成可以顯示的圖片和文字。我編寫的內容提供者如下:
class ViewContentProvider extends ArrayContentProvider implements ITreeContentProvider { public Object[] getChildren(Object parentElement) { JavacASTNode node = (JavacASTNode) parentElement; return node.getChildren().toArray(); } public Object getParent(Object element) { JavacASTNode node = (JavacASTNode) element; return node.getParent(); } public boolean hasChildren(Object element) { JavacASTNode node = (JavacASTNode) element; return node.getChildren().size() > 0 ? true : false; } public Object[] getElements(Object inputElement) { JavacASTNode compilatinUnitNode = new JavacASTNode(); compilatinUnitNode.setId(001); compilatinUnitNode.setName("JCCompilationUnit"); JavacASTNode importNode = new JavacASTNode(); importNode.setId(002); importNode.setName("JCImport"); JavacASTNode classNode = new JavacASTNode(); classNode.setId(003); classNode.setName("JCClassDecl"); compilatinUnitNode.getChildren().add(importNode); compilatinUnitNode.getChildren().add(classNode); importNode.setParent(compilatinUnitNode); classNode.setParent(compilatinUnitNode); return new JavacASTNode[] {compilatinUnitNode}; } }
這個類是JavacTreeViewer的內部類。我們只簡單寫了一些測試用的資料,其實這些資料都是要從Javac編譯器中讀取的,而Javac編譯器分析的Java原始碼又需要從當前啟用的編輯器中獲取,後面我會不斷完善更新這些功能。
編寫的標籤提供者如下:
class ViewLabelProvider extends LabelProvider { public Image getColumnImage(Object element) { return null; } public String getColumnText(Object element) { return ((JavacASTNode) element).toString(); } }
這個類也同樣是JavacTreeViewer的內部類。
(3)控制元件,用來顯示內容,這裡用到的為樹控制元件TreeViewer
(4)檢視器
模型和元素以及內容提供者和標籤提供者需要自己編寫,控制元件和檢視器不需要開發者自己編寫。
編寫JavacTreeViewer類,如下:
package astview; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; public class JavacASTViewer extends ViewPart { public static final String ID = "javacastviewer"; private TreeViewer viewer; public void createPartControl(Composite parent) { viewer = new TreeViewer(parent, SWT.SINGLE); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setContentProvider(new ViewContentProvider()); viewer.setInput(getSite()); } public void setFocus() { // not supported } ... }
最後執行後,檢視JavacTreeViewer檢視,顯示效果如下:
最後就是上傳到github了,我的github倉庫地址為:
https://github.com/mazhimazh/JavacASTViewer
接下來我會不斷開發完善這個專案,如果各位能給個“Star”是最好了,你的支援是我繼續開發的最大動力。