• (一)java面试易忘题目精选(1)


      1.  int和Integer有什么区别?

    答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

    Java 为每个原始类型提供了包装类型:
    - 原始类型: boolean,char,byte,short,int,long,float,double
    - 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

    class AutoUnboxingTest {
    
        public static void main(String[] args) {
            Integer a = new Integer(3);
            Integer b = 3;                  // 将3自动装箱成Integer类型
            int c = 3;
            System.out.println(a == b);     // false 两个引用没有引用同一对象
            System.out.println(a == c);     // true a自动拆箱成int类型再和c比较
        }
    }

    最近还遇到一个面试题,也是和自动装箱和拆箱有点关系的

    public class Test03 {
    
        public static void main(String[] args) {
            Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
    
            System.out.println(f1 == f2);
            System.out.println(f3 == f4);
        }
    }

    首先需要注意的是f1、f2、f3、f4四个变量都是Integer对象引用,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,如果看看valueOf的源代码就知道发生了什么。

       public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

    简单的说,如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。

      2.  &和&&的区别?

    答:&运算符有两种用法:(1)按位与;(2)逻辑与。&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

      3.  解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。

    答:通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、"hello"和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。

    String str = new String("hello");

    上面的语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而"hello"这个字面量是放在方法区的。

      4.  Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

    答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。

      5.  switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

    答:在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

         6  数组有没有length()方法?String有没有length()方法?

    答:数组没有length()方法,有length 的属性。String 有length()方法。JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆。

      7  在Java中,如何跳出当前的多重嵌套循环?

     //方法一:  
        public static void method1(){  
            ok:for(int i=0;i<10;i++){  
                for(int j=0;j<10;j++){  
                    System.out.println("i="+i+",j="+j);  
                    if(j==5){  
                        break ok;//跳到循环外的ok出,即终止整个循环  
                    }  
                }  
            }  
        }  
        //方法二:  
        public static void method2(){  
            int[][] arr = {{1,2,3},{4,5,6,7},{9}};  
            boolean found = false;  
            for(int i=0;i<arr.length && !found;i++){  
                for(int j=0;j<arr[i].length;j++){  
                    System.out.println("i="+i+",j="+j);  
                    if(arr[i][j]==5){  
                        found = true;//找到5,使外层循环判断条件变为false则终止整个循环  
                        break;//跳出当前循环  
                    }  
                }  
            }  
        }  

       8.  构造器(constructor)是否可被重写(override)?

    答:构造器不能被继承,因此不能被重写,但可以被重载。

      9.  两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

     不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;(2)如果两个对象的hashCode相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。

    对于equals,我们必须遵循如下规则:

          对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。

          反射性:x.equals(x)必须返回是“true”。

          类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。

          一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。

    任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。

    对于hashCode,我们应该遵循如下规则:

          1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。

          2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。

          3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。

    至于两者之间的关联关系,我们只需要记住如下即可:

    如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。

    如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

    整个处理流程是:

    1、判断两个对象的hashcode是否相等,若不等,则认为两个对象不等,完毕,若相等,则比较equals。

    2、若两个对象的equals不等,则可以认为两个对象不等,否则认为他们相等。

      10  是否可以继承String类?

    答:String 类是final类,不可以被继承。基本数据类型的包装类型(Byte Short Integer Long Double Float Charator Boolean)都是final类不可被继承。

      11  当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

    答:是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。

    •  按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。
        public class TempTest {  
        private void test1(int a){  
        a = 5;  
        System.out.println("test1方法中的a="+a);  
        }  
        public static void main(String[] args) {  
        TempTest t = new TempTest();  
        int a = 3;  
        t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a  
        System.out.println(”main方法中的a=”+a);  
        }  
        }  

    • 传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
        public class TempTest {  
        private void test1(A a){  
        a.age = 20;  
        System.out.println("test1方法中的age="+a.age);  
        }  
        public static void main(String[] args) {  
        TempTest t = new TempTest();  
        A a = new A();  
        a.age = 10;  
        t.test1(a);  
        System.out.println(”main方法中的age=”+a.age);  
        }  
        }  
        class A{  
        public int age = 0;  
        }  

    • “在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

     http://blog.csdn.net/jackfrued/article/details/44921941/  to be continue 19

  • 相关阅读:
    FSLIB.NETWORK 简易使用指南
    在CentOS上安装owncloud企业私有云过程
    用于ViEmu的重置为试用状态的Python脚本
    Microsoft.Office.Interop.Excel 报错
    FineUIMvc表格数据库分页,使用CYQ.Data组件
    如何在已有项目中引入FineUIMvc
    按键精灵-常用脚本命令汇集
    微信分享代码
    [教程] 【原创】媒体扫描耗电的彻底解决办法(申精)
    Less学习笔记
  • 原文地址:https://www.cnblogs.com/shyroke/p/8094802.html
Copyright © 2020-2023  润新知