• 第1篇-如何编写一个面试时能拿的出手的开源项目?


    编写一个不错的开源项目至少有3个好处:

    (1)练技术,长经验

    (2)面试时展现自己的Coding能力

    (3)获取成就感

    练技术,长经验是最实在的,不过如果自己有一个好的开源项目,还可以在开源中国或github上开源,让更多人受益,也许能获得许多的Star,让自已获得满足,激励自己完善项目功能。在面试时,也可以在简历显眼的位置给出开源项目名称和Git地址。面试官一般都会去查看,这是程序员实力的最好见证,是自己Coding能力的最好见证。所以如果要编写一个面试时拿的出手的项目,首先需要做到“规范”,下面谈一下我眼中规范的开源项目。

    1 项目规范

    1.1 规范编写README.md

    README.md文件是一个项目的入门手册,里面介绍了整个项目的使用、功能等等。所以README文件写得好不好,关系到这个项目能不能更容易的被其他人了解和使用。

    首先最起码要做到的就是格式要清晰,让人一眼能看出层次感,例如分几个大标题对项目进行介绍,最简单的就是分为如下的4部分:

    • 项目名及简介:简单介绍一下这个项目是做什么的。有的话最好加上demo地址;
    • 功能:你这个项目可以实现的功能;
    • 用法:这可以说是最重要的,一定要让别人看得懂你这项目是怎么使用的;
    • 其他:作者或者是维护人列表、版权、鸣谢、贡献、logo、联系方式等等,这些有的话当然会更加高大上。
    让面试官能在最短的时间内了解项目才是最重要的,所以简介要简短,三言二语就把项目要做的事儿交待清楚。这样面试官才会想更多的了解这个项目,例如使用了什么技术呀、具体源代码的书写逻辑呀等等。 

    1.2 使用版本管理工具

    最好使用版本管理工具,而且建议使用Git,并且是2个或多个人参与开发最好。许多面试官看到一个项目时通常都会问“这个项目是几个人开发的?”,除了了解项目分工的细节,也能体现团队合作的精神。另外在使用版本管理时,commit代码时一定要认真书写简短的描述,描述此次开发了什么功能或修复了什么Bug等,不能敷衍了事,这是一种习惯,会让自己以后受益。 

    1.3 好的代码书写习惯

    许多面试官司也会看具体的项目实现,所以项目模块划分要清晰,模块名称要见名之意,具体的代码书写要规范,现在许多大公司都有自己的代码规范,我们可以好好学一下阿里的Java代码规范。 

    1.4 有完整的测试用例

    这也是最容易被忽视的,但是却是保证项目功能正确最不可或缺的一部分。项目简单还好说,如果项目稍等复杂一点,没有测试用例保证的项目很容易出问题。试想一下,假如我们修复了一个系统Bug,但是没有为此Bug添加测试用例,那么下一个人在修复其它Bug时,很可能会破坏之前修复Bug的代码逻辑,导致一个Bug的修复引入了另外的Bug。所以要针对代码重要功能及相关Bug有完整的测试用例,必要时还要添加详细的注释。 

    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 fViewer;
    
    	public void createPartControl(Composite parent) {
    		fViewer = new TreeViewer(parent, SWT.SINGLE);
    		fViewer.setLabelProvider(new ViewLabelProvider());
    		fViewer.setContentProvider(new ViewContentProvider());
    		fViewer.setInput(getSite());
    	}
    
    	public void setFocus() {
    		// not supported
    	}
            ...
    }
    

    最后运行后,查看JavacTreeViewer视图,显示效果如下:

    最后就是上传到github了,我的github仓库地址为:

    https://gitee.com/mazhimazh/JavacASTViewer 

    接下来我会不断开发完善这个项目,如果各位能给个“Star”是最好了,你的支持是我继续开发的最大动力。

     

     
     
     
  • 相关阅读:
    Cooperate with Myself
    A brief introduction of myself
    计算1+11+111+1111+........
    Jav实现F(n)=F(n-1)+F(n-2)+.....+F(1)+1
    查找二维数组中是否有符合的目标值
    排序算法
    时间复杂度
    Java代码实现单例模式
    查找一个字符串中重复出现字符的个数
    null,“”,empty的区别
  • 原文地址:https://www.cnblogs.com/extjs4/p/12342287.html
Copyright © 2020-2023  润新知