JAVA开发面试题&基础篇&第九部分

本篇内容较多,请耐心看完,必有收益!

JAVA开发面试题&基础篇&第九部分

本篇内容较多,请耐心看完,必有收益!

1.不通过构造函数也能创建对象吗()

选项内容
A
B

分析:答案:A
Java创建对象的几种方式 (重要)
(1) 用new语句创建对象,这是最常见的创建对象的方法。
(2) 运用反射手段,调用java.lang.Class或者
java.lang.reflect.Constructor类的newInstance()实例方法。
(3) 调用对象的clone()方法
(4) 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
注意:
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。

2.下面哪些是对称加密算法()

选项内容
ADES
BMD5
CDSA
DRSA

分析:答案:A
分析:常用的对称加密算法有:DES、3DES、RC2、RC4、AES
常用的非对称加密算法有:RSA、DSA、ECC
使用单向散列函数的加密算法:MD5、SHA

3.下面的代码段,当输入为2的时候返回值是()

publicstaticint get Value(int i){
int result=0;
switch(i){
case 1:
result=result +i
case 2:
result=result+i*2
case 3:
result=result+i*3
}
return result;
}
选项内容
A0
B2
C4
D10

答案:D
分析:result = 0 + 2 * 2;没有break继续执行

4.以下Java代码段会产生几个对象

publicvoid test(){
String a="a";
String b="b";
String c="c";
c=a+""+b+""+c;
System.out.print(c);
}

分析:答案: 一个对象,因为编译期进行了优化,3个字符串常量直接折叠为一个。详细了解String创建对象的方式,点击: https://blog.csdn.net/spring_0534/article/details/3758199.

5.简单举例Math.round()。

分析:小数点后第一位=5
正数:Math.round(11.5)=12
负数:Math.round(-11.5)=-11
小数点后第一位<5
正数:Math.round(11.46)=11
负数:Math.round(-11.46)=-11
小数点后第一位>5
正数:Math.round(11.68)=12
负数:Math.round(-11.68)=-12
根据上面例子的运行结果,我们还可以按照如下方式总结,或许更加容易记忆:
参数的小数点后第一位<5,运算结果为参数整数部分。
参数的小数点后第一位>5,运算结果为参数整数部分绝对值+1,符号(即正负)不变。
参数的小数点后第一位=5,正数运算结果为整数部分+1,负数运算结果为整数部分。
终结:大于五全部加,等于五正数加,小于五全不加。

6.十进制数278的对应十六进制数

分析:十进制数278的对应十六进制数是116
(50以内的10进制数转为其它进制,应该可以口算出结果!!!)

7.Java中int.long占用的字节数分别是

分析:
1:“字节”是byte,“位”是bit ;
2: 1 byte = 8 bit ;
char 在Java中是2个字节。java采用unicode,2个字节(16位)来表示一个字符。
short 2个字节
int 4个字节
long 8个字节

8.System.out.println(‘a’+1);的结果是

分析:'a’是char型,1 是int行,int与char相加,char会被强转为int行,char的 ASCII码 对应的值是97,所以加一起打印98

9.下列语句那一个正确()

选项内容
Ajava程序经编译后会产生machine code
Bjava程序经编译后会产生 byte code
Cjava程序经编译后会产生DLL
D以上都不正确

答案:B
分析:java程序编译后会生成字节码文件,就是.class文件

10.下列说法正确的有()

选项内容
Aclass中的constructor不可省略
Bconstructor必须与class同名,但方法不能与class同名
Cconstructor在一个对象被new时执行
D一个class只能定义一个constructor

答案:C。constructor在一个对象被new时执行。
Constructor简介:
构造函数(Constructor)在对象创du建或者实zhi例化时候被调用的方法。通常使用该方法来初始化dao数据成员和所需资源。构造器Constructor在java不能被继承,因此不能重写Overriding,但可以被重载Overloading
构造函数在C++中如果写成public属性那么可以继承

11.下列语句正确的是()

选项内容
A形式参数可被视为local variable
B形式参数可被字段修饰符修饰
C形式参数为方法被调用时,真正被传递的参数
D形式参数不可以是对象

答案A:
分析:
A:形式参数可被视为local variable。形参和局部变量一样都不能离开方法。都只有在方法内才会发生作用,也只有在方法中使用,不会在方法外可见。
B:对于形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。 不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是:方法内部类。 一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。
C:形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列),也就是说真正被传递的是实参。
D:方法的参数列表指定要传递给方法什么样的信息,采用的都是对象的形式。因此,在参数列表中必须指定每个所传递对象的类型及名字。想JAVA中任何传递对象的场合一样,这里传递的实际上也是引用,并且引用的类型必须正确。–《Thinking in JAVA》想要本书资源请联系公众号:胜科课堂获取

12.成员变量用static修饰和不用static修饰有什么区别?

1、两个变量的生命周期不同。 成员变量随着对象的创建而存在,随着对象的被回收而释放。 静态变量随着类的加载而存在,随着类的消失而消失。
  2、调用方式不同。
成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类名调用。
对象调用:p.country
类名调用 :Person.country
  3、别名不同。 成员变量也称为实例变量。 静态变量称为类变量。
  4、数据存储位置不同。 成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据.
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享
数据

13.如果变量用final修饰,则怎样?如果方法final修饰,则怎样?

1、用final修饰的类不能被扩展,也就是说不可能有子类
2、用final修饰的方法不能被替换或隐藏
① 使用final修饰的实例方法在其所属类的子类中不能被替换(overridden);
② 使用final修饰的静态方法在其所属类的子类中不能被重定义(redefined)而隐藏(hidden);
3、用final修饰的变量最多只能赋值一次,在赋值方式上不同类型的变量或稍有不同:
① 静态变量必须明确赋值一次(不能只使用类型缺省值);作为类成员的静态变量,赋值可以在其声明中通过初始化表达式完成,也可以在静态初始化块中进行;作为接口成员的静态变量,赋值只能在其声明中通过初始化表达式完成;
② 实例变量同样必须明确赋值一次(不能只使用类型缺省值);赋值可以在其声明中通过初始化表达式完成,也可以在实例初始化块或构造器中进行;
③ 方法参数变量在方法被调用时创建,同时被初始化为对应实参值,终止于方法体 (body)结束,在此期间其值不能改变;
④ 构造器参数变量在构造器被调用(通过实例创建表达式或显示的构造器调用)时创建,同时被初始化,为对应实参值,终止于构造器体结束,在此期间其值不能改变;
⑤ 异常处理器参数变量在有异常被try语句的catch子句捕捉到时创建,同时被初始化为实际的异常对象,终止于catch语句块结束,在此期间其值不能改变;
⑥ 局部变量在其值被访问之前必须被明确赋值;

14.在二进制数据中,小数点向右移一位,则数据()

选项内容
A除以10
B除以2
C乘以2
D乘以10

答案:乘以2
分析:可以看个例子
101.1 对应的十进制为 2^21 + 2^10 + 2^01 + 2^-11 = 5.5小数点右移一位
1011 对应的十进制为 2^31 + 2^20 + 2^11 + 2^01 = 11所以是扩大到原来的2倍

15.面向对象的特征有哪些方面?

答:面向对象的特征主要有以下几个方面:
1、抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
2、继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段(如果不能理解请阅读阎宏博士的《Java与模式》或《设计模式精解》中关于桥梁模式的部分)。
3、封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口(可以想想普通洗衣机和全自动洗衣机的差别,明显全自动洗衣机封装更好因此操作起来更简单;我们现在使用的智能手机也是封装得足够好的,因为几个按键就搞定了所有的事情)。
4、多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供的服务,那么运行时的多态性可以解释为:当A系统访问B系统提供的服务时,B系统有多种提供服务的方式,但一切对A系统来说都是透明的(就像电动剃须刀是A系统,它的供电系统是B系统,B系统可以使用电池供电或者用交流电,甚至还有可能是太阳能,A系统只会通过B类对象调用供电的方法,但并不知道供电系统的底层实现是什么,究竟通过何种方式获得了动力)。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:1. 方法重写(子类继承父类并重写父类中已有的或抽象的方法);2. 对象造型(用父类型引用引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。

16.short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

答:对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。

17.Java 有没有goto?

答: goto 是Java中的保留字,在目前版本的Java中没有使用。(根据James Gosling(Java之父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)Java中有类似goto的用法见《Thinking in Java》第四版第88页 书籍可以从公众号:胜科课堂 获取

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

答:在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,所以这种语法其实不知道更好)摘自《Thinking in Java》

19.int 和Integer 有什么区别?

答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入不是对象的基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从JDK 1.5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了包装类型:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

package com.bjsxt;
 
public 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);
    }
}

如果不明白就里很容易认为两个输出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四个变量都是Integer对象,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,如果看看valueOf的源代码就知道发生了什么。
IntegerCache是Integer的内部类,其代码如下所示:

/* Cache to support the object identity semantics of autoboxing for 
*values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high 
*property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */
 
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
 
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer
.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
              // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
 
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
 
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
 
        private IntegerCache() {}
}

简单的说,如果字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。越是貌似简单的面试题其中的玄机就越多,需要面试者有相当深厚的功力。
参见博文: https://blog.csdn.net/snail_rao/article/details/7639194.

20.swtich 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

答:早期的JDK中,switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引入了枚举类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的。

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

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

22.两个对象值相同(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和hashCode方法,很多Java程序都知道,但很多人也就是仅仅知道而已,在Joshua Bloch的大作《Effective Java》(很多软件公司,《Effective Java》、《Java编程思想》以及《重构:改善既有代码质量》是Java程序员必看书籍,如果你还没看过,那就赶紧联系公众号:胜科课堂 获取吧)中是这样介绍equals方法的:首先equals方法必须满足自反性(x.equals(x)必须返回true)、对称性(x.equals(y)返回true时,y.equals(x)也必须返回true)、传递性(x.equals(y)和y.equals(z)都返回true时,x.equals(z)也必须返回true)和一致性(当x和y引用的对象信息没有被修改时,多次调用x.equals(y)应该得到同样的返回值),而且对于任何非null值的引用x,x.equals(null)必须返回false。实现高质量的equals方法的诀窍包括:1. 使用==操作符检查“参数是否为这个对象的引用”;2. 使用instanceof操作符检查“参数是否为正确的类型”;3. 对于类中的关键属性,检查参数传入对象的属性是否与之相匹配;4. 编写完equals方法后,问自己它是否满足对称性、传递性、一致性;5. 重写equals时总是要重写hashCode;6. 不要将equals方法参数中的Object对象替换为其他的类型,在重写时不要忘掉@Override注解。

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

答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对象的引用是永远不会改变的。C++和C#中可以通过传引用或传输出参数来改变传入的参数的值。
补充:Java中没有传引用实在是非常的不方便,这一点在Java 8中仍然没有得到改进,正是如此在Java编写的代码中才会出现大量的Wrapper类(将需要通过方法调用修改的引用置于一个Wrapper类中,再将Wrapper对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从C和C++转型为Java程序员的开发者无法容忍。参见博文: https://blog.csdn.net/u012726702/article/details/72236968.

24.重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

答:Java的三大特征之一,多态机制,包括方法的多态和对象的多态;方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载(overload)发生在同一个类中,相同的方法,如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写(override)发生在子类与父类之间也就是继承机制当中,当父类的方法不能满足子类的要求,此时子类重写父类的方法;要求:方法名、形参列表相同;返回值类型和异常类型,子类小于等于父类;访问权限,子类大于等于父类,切记父类的私有方法以及被final修饰的方法不能被子类重写;重载对返回类型没有特殊的要求。【第二次出现此知识点,记住了么?】
华为的面试题中曾经问过这样一个问题:为什么不能根据返回类型来区分重载?
答:方法的重载,即使返回值类型不同,也不能改变实现功能相同或类似这一既定事实;同时方法的重载只是要求两同三不同,即在同一个类中,相同的方法名称,参数列表当中的参数类型、个数、顺序不同;跟权限修饰符和返回值类无关

25.静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?

答:内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已,这么一点小事,你还要把它放到类内部的一个类中,过分了啊!提供内部类,不是为让你干这种事情,无聊,不让你干。我想可能是既然静态成员类似c语言的全局变量,而内部类通常是用于创建内部对象用的,所以,把“全局变量”放在内部类中就是毫无意义的事情,既然是毫无意义的事情,就应该被禁止),内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中,如下所示:

public class Outer
{
        int out_x  = 0;
        public void method()
              {
               Inner1 inner1 = new Inner1();
               public class Inner2  //在方法体内部定义的内部类
               {
                      public method()
                      {
                             out_x = 3;
                      }
               }
               Inner2 inner2 = new Inner2();
        }
 
        public class Inner1  //在方法体外面定义的内部类
        {
        }
 
}

在方法体外面定义的内部类的访问类型可以是public,protecte,默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如下:

Outer outer = new Outer();
Outer.Inner1 inner1 = outer.new Innner1();

在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。
对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。
在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:

public class Outer
{
        public void start()
        {
               new Thread(
new Runable(){
         public void run(){};
}
).start();
        }
}

最后,在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested Class,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需要创建外部类的实例对象,就可以直接创建Static Nested Class,例如,假设Inner是定义在Outer类中的Static Nested Class,那么可以使用如下语句创建Inner类:

Outer.Inner inner = newOuter.Inner();

由于static Nested Class不依赖于外部类的实例对象,所以,static Nested Class能访问外部类的非static成员变量(不能直接访问,需要创建外部类实例才能访问非静态变量)。当在外部类中访问Static Nested Class时,可以直接使用Static Nested Class的名字,而不需要加上外部类的名字了,在Static Nested Class中也可以直接引用外部类的static的成员变量,不需要加上外部类的名字。
在静态方法中定义的内部类也是Static Nested Class,这时候不能在类前面加static关键字,静态方法中的Static Nested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。
备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。
Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化,其语法看起来挺诡异的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值