今天看了一下关于java的一些挺经典、全面的面试题 所以今晚总结了一下 和 大家多交流交流.

1.java中九种基本数据类型的大小及他们的封装类. 

  其中包括六种数字类型(四个整数型,两个浮点型),一种布尔型,一个是void

  整型:short,int,long,byte

        16   32   64     8

  浮点型:float,double

          32     64

  字符型:char

          16(unicode)

  布尔型:boolean

           1

  void   

  

  解释:java中有两种数据类型,一种是基本数据类型 一种是引用型数据类型 在Java的圣经Thinking in java中把void也列为基本数据类型,里面认为两种个数据类型的区别在于,基本数据类型是在堆栈中分配空间存“值”,而引用数据类型是在堆中分配空间存“值”,但是void他不能通过new来实例化出来,只能在堆栈中分配空间存储,所以认为void是一种基本数据类型.

  建议:在面试中 大家可以先说有8中基本数据类型,然后再说有些书 如thinking in java也把void归为基本数据类型中的一种 故为九种.

  疑问:这么说的话,那任何不能实例化 但在堆栈中存储的都算基本数据类型吗?

 2.Switch能否用string做参数?

  可以 凡是可以自动转换为整型数据类型的数据类型都可以作为switch的参数.如:byte short int string 但是 float long double boolean不能自动转换为int的就不能作为其参数.

  比如:

public class Main { 
     public static void main(String[] args) { 
         String s="abc"; 
         switch(s){ 
         case("abc"): 
             System.out.println("i love xingxing"); 
             break; 
         case("123"): 
             System.out.println("i love jiming"); 
             break; 
         default: 
             break; 
         } 
     } 
 }

 3.== 与 equals的区别:

  首先==是基本数值的比较(原生类型和对象),如比较int , boolean等的值比较,但是也可以用来比较两个对象,但是是比较的两个对象在堆栈中的引用,而不是比较的两个对象在堆中的具体值;再者,如果大家去查看equals的源码就不难发现

public boolean equals(Object obj) { 
     return (this == obj); 
   }

  其实equals的内部实现也是用==来进行两个对象比较的,所以java其实是希望开发人员结合自己的业务逻辑来重写equals和equals的契约小伙伴Hashcode(),从而完成对业务逻辑的具体比较,比如是判断两个员工是不是同一个人则判断他们的name是不是相等。

public boolean equals(Object object){ 
             if(object instanceof Person){ 
                 Person p = (Person) object; 
                 if(p.getName() == null || name == null){ 
                     return false; 
                 } 
                 else{ 
                     return name.equals(p.getName ()); 
                 } 
             } 
             return false; 
        }

   而为什么在比较String字符串时,equals就是比较的两个字符串的值呢,那是因为字符串自己早就把equals给重写了, 如下:

public boolean equals(Object anObject) { 
         if (this == anObject) { 
             return true; 
         } 
         if (anObject instanceof String) { 
             String anotherString = (String)anObject; 
             int n = count; 
             if (n == anotherString.count) { 
             char v1[] = value; 
             char v2[] = anotherString.value; 
             int i = offset; 
             int j = anotherString.offset; 
             while (n-- != 0) { 
                 if (v1[i++] != v2[j++]) 
                 return false; 
             } 
             return true; 
             } 
         } 
         return false; 
         }

    说简单点,java不支持操作符重载,所以对于==规定了是什么比较规则就怎么比,而equals返回的true或false都是可以自己来定义的,如两个值相等,也可以根据自己的意愿让它返回false.

    小口诀:==值,址比较  equals自定义比较,string已定义了比较。

  4.Object有哪些公用方法: clone() 、 finlize() 、 toString() 、getClass()、 equals() 、hashcode() 、wait() 、 notify()喚醒等待的綫程 、notifyAll()喚醒等待的全部綫程.

   这里需要解释一下常用的toString方法,为什么呢?因为我不太会=D 

   toString() 方法:

    toString()方法在Object类中定义,其返回值是String类型,描述当前对象的有关信息

    在进行String与其它类型数据的连接操作时,自动调用toString()方法

    可以根据需要在用户自定义类型中重写toString()方法

    基本类型数据转换为String类型时,调用了对应封装类的toString()方法

public class Person { 
     private String name; 
     private int age; 
     private char sex; 
     public Person() 
     { 
     } 
     public Person(String name,int age, char sex) 
     { 
         this.name = name; 
         this.age = age; 
         this.sex = sex; 
     } 
     public String getName() { 
         return name; 
     } 
     public void setName(String name) { 
         this.name = name; 
     } 
     public int getAge() { 
         return age; 
     } 
     public void setAge(int age) { 
         this.age = age; 
     } 
     public char getSex() { 
         return sex; 
     } 
     public void setSex(char sex) { 
         this.sex = sex; 
     } 
     public boolean equals(Object obj) 
     { 
         if(obj==null) 
         { 
             return false; 
         } 
         if(obj==this)//传递进来的参数是否等于本对象 
         { 
             return true; 
         } 
         if(obj instanceof Person) 
         { 
             Person p = (Person)obj;//强制类型转换成Person 
             return p.getName().equals(this.name);//String内重写的equals方法,写这句的目的是重写equeals方法,如果姓名相等,则p1跟p2相等。 
         } 
         return super.equals(obj); 
     } 
     //重写hashCode方法 
     public int hashCode() 
     { 
         return this.name.hashCode()*328; 
     } 
     //重写toString 方法 
     public String toString() 
     { 
         return "姓名为:"+this.name+"年龄为:"+this.age+"性别为:"+this.sex; 
     } 
 } 
   
 public class TestPerson { 
     public static void main(String args[]) 
     { 
         Person p1 = new Person("王惠", 24, '女'); 
         Person p2 = new Person("吴嫚真",23,'女'); 
          
         if(p1.equals(p2)) 
         { 
             System.out.println("她们相等.."); 
         } 
         else 
         { 
             System.out.println("她们不相等"); 
         } 
         System.out.println(p1.hashCode()); 
         System.out.println(p2.hashCode()); 
         System.out.println(p1); 
         System.out.println(p2); 
     } 
 }

输出结果:

她们不相等

308893672

-1548821240

姓名为:王惠年龄为:24性别为:女

姓名为:吴嫚真年龄为:23性别为:女

注:如果    Person p2 = new Person("王惠",23,'女');

则输出:

她们相等..

308893672

308893672

姓名为:王惠年龄为:24性别为:女

姓名为:王惠年龄为:23性别为:女

 

如果没有重写toString 方法,那么最后输出结果(因为toString返回的是 hashCode码):

她们不相等

308893672

-1548821240

com.cstp.java1223.Person@126957e8

com.cstp.java1223.Person@a3aedd08

  

  5.内存泄漏问题:

  内存泄漏的原理:我们可将对象视为图的有向边的一个顶点,有向边是从引用指向对象.大多数程序从main函数开始执行所以该图就是以main函数的开始进程作为一颗根树.在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC 回收。

  内存泄漏要满足两个条件:对象可达 但对象已经不再使用或不常使用,占据内存又不能被回收. 

给一个内存泄漏的典型案例:

Vector v = new Vector(10); 
 for (int i = 1; i < 100; i++) { 
     Object o = new Object(); 
     v.add(o); 
     o = null;    
 }

若有错误,请路过的大神多指教哈=)

未完待续。。。