Java面试——基础

1,作用域,Java只有public,protect,private,默认是default相当于friendly

作用域 当前类          同一package 子类            其它package
public  T T T T
protect T T T F
private T F F F
default T T F F

    值得注意的是默认default,同一个package下的其它类可以访问,当如果是子类就不可以访问。

      2,String

    • String str = new String("hello");究竟做了什么,与String str="hello"    
      String str = "hello"; 如果内存中已经为hello字符串分配了内存,那么str指向hello内存对象的地址;
      String str = new String("hello"); 内存中重新分配一片内存区域存放hello, 然后str指向hello,也就是内存中实际有2个hello对象,而且存放的地址不一样
    • String str1 = "hello";
      String str2 = "he" + new String("llo");
      System.err.println(str1 == str2);

输出是false. == 比较的是对象的地址,str1是指向hello的引用,而str2是指向he的和llo地址的地址的引用。

equals()比较的是对象的内容。

3,基本数据类型

  boolean:false

  byte: 0,-128-127

  int:0,4个字节,-2的31次方-2147483648,2的31次方

  short:0,2个字节,-2的15次方-32768,2的15次方-1,-1:32767

  long:0L.64位

  float:0.0,

    初始化时:float f = 1.0f;

  double:0.0,

  object:null,

  char:/u0000

char a = 10;//打印a,什么都没有
char s = '2';//打印s,2

自动装箱和自动拆箱:

  Integer i = 10;  //装箱

      int n = i;   //拆箱
      简单一点说,装箱就是  自动将基本数据类型转换为包装器类型;拆箱就是  自动将包装器类型转换为基本数据类型。
      参考:
      http://www.cnblogs.com/dolphin0520/p/3780005.html
      包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比
      较的是数值(即会触发自动拆箱的过程)。另外,对于包装器类型,equals方法并不会进行类型转换。
  • 0.6332的数据类型是()

A float     B double     C Float      D Double

答案:B

解析:默认为double型,如果为float型需要加上f显示说明,即0.6332f

  •  存在使i + 1 < i的数吗()

      答案:存在

      解析:如果i为int型,那么当i为int能表示的最大整数时,i+1就溢出变成负数了,此时不就<i了吗。

    扩展:存在使i > j || i <= j不成立的数吗()

    答案:存在

    解析:比如Double.NaN或Float.NaN

  • 下面程序的输出结果
public class Example {

    String str = new String("good");

    char[] ch = { 'a', 'b', 'c' };

    public static void main(String args[]) {

        Example ex = new Example();

        ex.change(ex.str, ex.ch);

        System.out.print(ex.str + " and ");

        System.out.print(ex.ch);

    }

    public void change(String str, char ch[]) {

        str = "test ok";

        ch[0] = 'g';

    }
}
View Code

    原因

A、 good and abc

B、 good and gbc

C、 test ok and abc

D、 test ok and gbc

答案:B

解析:大家可能以为Java中String和数组都是对象所以肯定是对象引用,然后就会选D,其实这是个很大的误区:因为在java里没有引用传递,只有值传递。这个值指的是实参的地址的拷贝,得到这个拷贝地址后,你可以通过它修改这个地址的内容(引用不变),因为此时这个内容的地址和原地址是同一地址

  • public static void main (String[] args){
            String s;
            System.out.println("s=" + s);
        } 不能编译通过,所有定义的基本类型或对象都必须初始化才能输出值。
  • String 类是final类,不可以被继承
  • 传值调用

  Java中只有传值调用。

  如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
      如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。
  总之一句话,如果改变了传入指向的地址,对调用者来说没有改变,而改变了值的话就会改变。
  • String和StringBuilder、StringBuffer的区别

  String是final类,只能销毁重新建立,不能append

  StringBuffer是StringBuilder线程安全版,可以后续添加,不会重新建立对象。效率较高。

4,Java平台无关

  Java平台无关指的是Java源文件被编译成字节码文件,不管操作系统,只要有Java虚拟机就可以运行。

5,java程序究竟是怎么执行的

  

      JVM获取一个含有main方法的类,用顶层的类加载器Bootstrap启动两个ExtClassLoader和AppClassLoader,AppClassLoader加载main()方法类,校验检测,然后启动main()线程处理此方法,进行分配资源和新的按需加载新类,依次重复,直至遇到程序结束条件。

6.面向对象

 构造函数:

  规则:与类同名,没有返回值,可以定义多个(参数个数,顺序,类型),初始化资源。但不通过构造函数也可以创建对象,可以使用clone()

对象的初始化顺序:(1)类加载之后,按从上到下(从父类到子类)执行被static修饰的语句;(2)当static语句执行完之后,再执行main方法;(3)如果有语句new了自身的对象,将从上到下执行构造代码块、构造器(两者可以说绑定在一起)。

     封装、继承和多态

封装:提供接口,封住关注实现细节,提供给外部调用的API,而抽象关注功能,忽略细节

继承:丰富功能,有规范,体现逻辑关系。

多态:同一行为有多个形式。允许不同类的对象对同一消息做出响应。严格来讲多态是类的特性,例如以下:

AbstractCollection<String> a = new LinkedList<String>();
List<String> b = new LinkedList<String>();

但注意a和b的不同:编译时a会被认为是AbstractCollection对象,所以当a用LinkedList的独有方法时会编译不通过,但b在编译期就会被认为是LinkedList对象,可以使用LinkedList的独有方法

     对方法来讲,多态指的是方法的重载和覆盖。

   方法重载:一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。

      注意,Java的方法重载要求同名的方法必须有不同的参数表,仅有返回类型不同是不足以区分两个重载的方法。

   方法覆盖:子类重写父类的方法。

   抽象类和接口

    抽象类:public abstract class ClassName(){

         abstract void function(); //为了让子类能够继承默认情况下是public类型

         int add(int a,int b){
            return a+b;
         }//也可以有具体实现的方法。     

       }

       子类继承抽象类,必须实现其所有抽象方法。除非子类也是抽象类。

     接口:public interface InterfaceName(){

        int variables;//只能指定为public static final,不能被修改       

          int add(int a,int b);//只能是抽象方法。类如果实现接口必须实现接口所有的抽象方法。

      }

     抽象类和接口:

      相同点:继承抽象类的子类或者实现接口的类必须重写其所有抽象方法

      不同:1,方法:抽象类可以定义有实体的方法,接口不可以

           2,变量,抽象类可以定义属性,接口中定义的变量一定是static final类型,只可以引用,不可以被修改

         3,抽象类只能单类继承,接口可以多重实现。

             4,接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

      设计理念:抽象类是对类的抽象,是继承其所有类的模板,有属性有方法。而接口是对局部行为的抽象,类可以有多种行为,故可以实现多重接口。

  继承子类和父类的执行顺序

class People {
    String name;

    public People() {
        System.out.print(1);
    }

    public People(String name) {
        System.out.print(2);
        this.name = name;
    }
}

class Child extends People {
    People father;

    public Child(String name) {
        System.out.print(3);
        this.name = name;
        father = new People(name + ":F");
    }

    public Child() {
        System.out.print(4);
    }
    
}
View Code

  new Child("mike")

  输出:132

  执行顺序:总之,一句话:子类没有显示调用父类构造函数,不管子类构造函数是否带参数都默认调用父类无参的构造函数,若父类没有则编译出错。

7,Java关键字

transient:不会被序列化

static:Java中是否可以覆盖(override)一个private或者是static的方法?

"static"关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。
static方法跟类的任何实例都不相关,所以概念上不适用。

8,GC

  名词解释:

年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
Major GC 是清理永久代。
Full GC 是清理整个堆空间—包括年轻代和永久代。

  垃圾回收机制在什么时候运行?

    系统自身决定,不可预测的时间/调用System.gc(),具体来讲,新生代对象区满时,当升级的老年代对象大于老年代占用的空间,

    从gcroot搜索已经不可达标记过重新扫描仍然没有复活,

  垃圾回收的对象是什么?

    从gcroot搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象。垃圾回收回收的是无任何引用的对象占据的内存空间而不是对象本身

  垃圾回收的机制?

9,JDK JRE

  JDK:开发环境,有各种工具包,包括jre

  JRE:运行环境,包括jvm.

   10,java控制语句

    switch:case如果没有break,从适合的条件下依次运行。输入为2时,case2开始执行,case3执行。最后返回10。

public static int getValue(int i) {
        int result = 0;
        switch (i) {
        case 1:
            result = result + i;
            System.out.println(1+":"+result);
        case 2:
            result = result + i * 2;
            System.out.println(2+":"+result);//打印
        case 3:
            result = result + i * 3;
            System.out.println(3+":"+result);//打印
        }
        return result;
    }

 

posted @ 2016-07-27 15:18  moye  阅读(326)  评论(0编辑  收藏  举报