第一章 Java基础知识


1、如何在main()方法之前输出“hello world”?

答:在java语言中,由于静态代码块在类加载时就会被调用,故可以利用静态代码块实现该功能。

//在main()方法之前输出Hello world ,静态代码不论顺序在哪里都在main()方法执行之前执行,故以下两种方法的结果时一样的;
public class Test01 {
    //静态代码块在main()方法之前
    static {
        System.out.println("hello world1");
    }
    public static void main(String[] args) {
        System.out.println("hello world2");
    }
}


public class Test02 {
    //静态代码块在main()方法后
    public static void main(String[] args) {
        System.out.println("hello world2");
    }
    static {
        System.out.println("hello world1");
    }
}

2、Java中的作用域:

作用域对比
作用域和可见性 当前类 同一个包 子类 其他包
public
protected  
private      
default      

 

 

 

 

 

 

3、一个Java文件是否可以定义多个类?

答:一个java文件可以定义多个类,但是只有一个类被public修饰,而且这个类与文件名相同,若这个文件中没有public类,则文件名时随便一个类的名字即可。

4、什么是构造函数?

答:构造函数是一类特殊的函数,用来在对象实例化时初始对象的成员变量。

        特点:1、构造函数的名字与类名相同,且没有返回值。

                   2、每个类可以有多个构造函数,若开发人员没有提供构造函数,系统则会默认创建一个,如是开发人员提供了,系统就不会默认创建一个,如是系统默认创建的构造函数是无参的,且不会执行任何代码。

                   3、构造函数的主要作用是完成对象的初始化,且参数可以是0个,1个或者多个。

                   4、构造函数时在对象实例化的时候就自动调用了,且执行一次。

5、浅复制和深复制有什么作用?

答:浅复制::对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅复制。

        深复制:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深复制。

6、面向对象的特征(抽象、封装、继承、多态)   

答:1、封装:将客观事物抽象成类,每个类对自身的数据和方法实行保护。类可以把自己的数据和方法只让可信的类或对象操作,对 不可信的进行信息隐藏。

        2、继承:继承是一种层次模型,新类(子类)会继承基类(父类)的方法和变量,并且子类还可以修改或增加新的方法,更容易满足特殊的需求。

        3、多态:是指允许不同类的对象,对同一个消息做出相应,可以解决应用程序函数同名的问题。

 7、多态的机制是什么?

答:在Java中常用的多态是靠方法的重载和方法的覆盖来表现的,而方法的重载是指同一个类中有多个同名的方法,这些方法有不同的参数,在编译的时候就可以确定到底用的是那个方法,是一种编译时的多态,而方法的重载是子类覆盖父类中的方法。

8、重载和覆盖有什么区别?

答:重载:1、重载是通过不同方法参数来区分的(参数的个数,类型,顺序);

                  2、重载与方法的类型、返回值和抛出权限无关;

      覆盖:1、子类中的覆盖方法必须和父类中被覆盖的方法有相同的函数名和参数;

                 2、子类中的覆盖方法的返回值和父类中被覆盖方法的返回值必须相同;

                 3、子类中的覆盖方法所抛出的异常必须要与父类中被覆盖方法的一场一致;

                 4、父类中的方法不能为private;

       区别:1、覆盖是父类和子类之间的关系是垂直关系,而重载是同一个类中的方法之间的关系是水平关系;

                 2、覆盖只能由一个方法或一对方法产生关系,重载是由多个方法产生关系;

                 3、覆盖要去参数列表相同,重载要去参数列表不同;

                 4、覆盖关系中,调用方法题是根据对象的类型(对象对应存储空间类型)来觉的的,而重载关系是根据调用时的实参与形参来选择方法题的。

9、抽象类和接口有什么区别?

答:

10、break、countinue和return的区别:

答:break跳出当前循环不在;执行剩下的代码;

       countinue停止当前循环,回到循环开始的位置进行执行下一次循环;

        return是从一个方法的返回值,可以使程序返回到掉哟个该方法的地方;

11、final、finally和finalize有什么区别?

答:final修饰的类不可以被继承,修饰的方法不可以被重写,修饰的变量不可以再次赋值;

      finally作为 异常处理的一部分,只能够用于try/catch,而且这段语句一定会被执行;

      finalize是Object类的一个方法,用来实现对其他资源的回收;

12、statci关键字有那些作用?

答:static成员变量,可以使变量作为全局变量使用,static不能在方法体内定义局部变量;

       static修饰的方法可以直接被调用,不需要创建对象;

       static修饰的代码块只能被执行一次,而且在加载的时候就执行;

       static修饰的内部类,。。。

13、值传递和引用传递有那些区别?

答:值传递:在方法的调用中,实参会把他的值传给形参,形参知识用实参的值初始化一个临时的存储单元,因此形参与实参虽然有相同的值但是却有不同的存储单元,修改形参的值不会改边实参的值。

       引用传递:在方法调用中,传递的使对象,这是形参与实参的对象指向同一块存储单元,因此对形参的修改就会影响实参的值。

在Java语言中,原始的数据类型在传递的时候都是按值传递,而包装类型在传递的时候都是按照引用传递的。

14、Math类中round 、ceil和floor方法的功能各是多少?
答:Math方法全是静态方法,可以直接使用。

       round()方法表示四舍五入;

       ceil()方法表示向上取整;

      floor()方法表示向下取整;

15、++i与i++有什么区别?

答:i++是在程序执行完毕后再进行自增;

       ++i是再程序执行前就开始自增;

16、char类型是否可以存储一个中文汉字?

答:在java语言中,默认的是使用的是Unicode编码,每个字符占两个字节,因此可以用来存储中文。

17、“==”、“equals"和hashCode有什么区别?

答:”==“ 是比较两个变量是否相等。也就是比较改变量中对应的值是否相等,要 比较两个基本数据类型或两个引用变量是否相等,只能够使用”==“运算符;

        ”equals“是Object类提供的方法,他主要与”==“不同制醋是可以比较两个独立对象的内容是否相等。

      ”“

18、String、StringBuffer、StringBuider和StringTokenizer有什么区别?

答:String是不可以变类,也就是说,String对象一旦被创建,其值将不能被改变,而StringBuffer是可变类,当对象被创建后任然可以对气质进行修改,由于String类是不可变类,因此适合在需要被共享的场合中使用,而当一个字符串经常需要被修改时,最好使用StringBuffer来实现。

        String与StringBuffer的另外一个区别在于当实例化String时,可以利用构造函数的方式来对其进行初始化,也可以用赋值的方式来初始化,而StringBuffer只能够使用构造函数的方式进行初始化。

       String字串实现修改的原理如下:当用String类型对字符串进行修改时,其实实现方法时首先创建一个StringBuilder,其次调用append()方法,最后调用StringBuilder的toString()方法把结果返回。

     StringBuilder也是可以被修改的字符串,他与StringBuffer类似,都是字符串缓冲区,StringBuilder不是线程安全,如果只是在线程中使用字符串缓冲区,那么StringBuilder的效率会高一点,因此只有在单线程的时候使用字符串缓冲区,StringBuilder的效率会更高一点,当有多个线程进行访问的时候,使用线程安全的StringBuffer,因为StringBuffer必要时可以对这些方法进行同步,所以任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法顺序一致。

    在执行效率方面StringBuilder效率最高,其次是StringBuffer,最后才是String。

19、Java中数组是不是对象?

答:在Java语言中数组不仅有自己的特性(length属性),也有一些方法可以被调用(clone()方法)。由于对象的特点是封装了一些数据,同时提供了一些属性和方法,从这个角度来说数组是对象。

20、Length属性和length()方法有什么区别?

答:  数组:提供的length属性来获取数组的长度。

       字符串:length()方法是针对字符串而言的,String提供的Length()方法来计算字符串的长度。

       size()方法,该方法是针对泛型集合而言的,用于查看泛型中有多少个元素。

21、finally块中的代码是什么时候被执行的(try()里有一个return语句,那么紧跟在这个try后的finally{}中的代码是否会被执行?如果会的话,是在什么时候被执行的,在return之前还是return之后)?

答:在Java语言的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会被执行,由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,因此任何语句都会在return之前执行,(除非碰到exit函数),因此finally的代码块也是在return前执行的。此外,如果try-finally或者catch-finally中都有return,那么finally块中的语句将会覆盖别出的return语句,最终返回到调用者哪里的是finally中return的值。

22、异常处理的原理是什么?

答:异常是指程序运行时(非编译时)所发生的非正常情况或错误,当程序违反了语义规则时,JVM就会将出现的错误表示一个异常并抛出,这个异常可以在catch程序块中进行捕获,然后进行处理,而异常处理的目的则是为了提高程序的安全性和鲁棒性。

         Java语言把异常当作对象来处理,并定义了一个基类,作为所有异常的父类,在java api中定义了所有的异常类,这些异常类可以分为Error和Exception两大类。

              违法语义股则包括两种情况:一种是Java类库内置的语义检查,另外一种情况是Java开发人员扩展这些语义检查,并自由选择在何时用throw关键字抛出异常。

23、运行时异常和普通异常有什么区别?

答:java 提供了两种异常,分别为Error和Exception,且他们拥有共同的父类——Throwable。

 24、简述list、set、map 接口。

答:list,存储的是有序的,能够对列表中的每个元素的插入和删除都进行精确的控制,可以保存重复的对象。ListedList 、 ArrayList 和Vector都实现了LIst接口。

      set、里面的元素不可以重复,因此存入Set中的每个元素都必须定义equals()方法来确保对象的唯一性,该接口有两个实现类Hashset和TreeSet。

     Map、提供的是一个从键映射到值的数据结构,value可以重复,Key值不可以重复,他的实现类很多。

25、什么是迭代器?

答:迭代器是一个对象,主要工作是便利并选择序列中的对象,使用迭代器主要以下3个方面,

      1、使用容器的iterator()方法返回一个Iterator,然后通过Iterator的next()方法返回第一个元素;

      2、使用Iterator的hasNext()方法判断容器中是否还有元素,然后又,可以用next()方法获取下一个元素。

     3、可以通过remove()删除迭代器返回的元素;

26、Iterator与ListIterator有什么区别?

答:iterator只可以正向遍历集合,适用于获取移除元素,而ListIterator继承与Iterator,专门用于Listk可以从两个方向来便利List,同时支持元素的修改。

27、ArrayList 、LinkedList 和 Vector有什么区别?

答:从使用方法的角度分析。ArrayList属于非线程安全,而Vector则属于线程安全。如果是开发中没有线程同步的需求,推荐优先使用ArrayList。因此其内部没有synchronized,执行效率会比Vector快很多。 

  从数据结构的角度分析。ArrayList是一个数组结构(Vector同理),数组在内存中是一片连续存在的片段,在查找元素的时候数组能够很方便的通过内存计算直接找到对应的元素内存。但是它也有很大的缺点。我们假设需要往数组插入或删除数据的位置为i,数组元素长度为n,则需要搬运数据n-i次才能完成插入、删除操作,导致其效率不如LinkedList。
  LinkedList的底层是一个双向链表结构,在进行查找操作的时候需要花费非常非常多的时间来遍历整个链表(哪怕只遍历一半),这就是LinkedList在查找效率不如ArrayList快的原因。但是由于其链表结构的特殊性,在插入、删除数据的时候,只需要修改链表节点的前后指针就可以完成操作,其的效率远远高于ArrayList。
       ArrayList的初始值是10,扩容是1.5倍。

27、foeach的接口是什么?继承了什么方法?

答:foeach的接口是IEnumerator或什么的是GetEnumerator。