logo资料库

疯狂Java面试题.pdf

第1页 / 共44页
第2页 / 共44页
第3页 / 共44页
第4页 / 共44页
第5页 / 共44页
第6页 / 共44页
第7页 / 共44页
第8页 / 共44页
资料共44页,剩余部分请下载后查看
疯狂 Java 面试题(疯狂 Java 讲义附赠) 本大全每个月会定期更新,索取网址:http://www.fkit.org Java 核心技术部分 Java 核心技术部分的面试题,可能覆盖 Java 基本语法、面向对象(包括类定义、方法、 构造器、递归、继承、抽象类、接口、枚举以及 final、static 等关键字)、Java 常用 API、Java 集合框架(需要重点掌握)、注解(Annotation)、泛型、输入/输出、多线程、网络通信、反 射、内存管理等相关内容,这些知识基本都可通过《疯狂 Java 讲义》一书找到详细解答。 这部分面试题大部分从网络收集、整理,也有部分题目来自疯狂软件学员面试之后的反 馈。 1、面向对象的特征有哪些? 面向对象的三大特征: 继承:通过继承允许复用已有的类,继承关系是一种“一般到特殊”的关系,比如苹果 类继承水果类,这个过程称为类继承。 派生出来的新类称为原有类的子类(派生类),而原有类称为新类的父类(基类)。 子类可以从父类那里继承得到方法和成员变量,而且子类类可以修改或增加新的方法使 之适合子类的需要。 封装:封装是把对象的状态数据隐藏起来,再通过暴露合适的方法来允许外部程序修改 对象的状态数据。Java 的封装主要通过 private、protected、public 等访问控制符来实现。 多态:多态指的是当同一个类型的引用类型的变量在执行相同的方法时,实际上会呈现 出多种不同的行为特征。比如程序有 Animal a1 = new Animal (); Animal a2 = new Wolf();虽然 a1、a2 两个引用变量的类型都是 Animal,但当它们调用同一个 run()方法时,如果 Wolf()类 重写过 Animal 的 run()方法,这就会导致 a1、a2 两个变量执行 run()方法时呈现出不同的行 为特征,这就是多态。多态增加了编程的灵活性,实际上大量设计模式都是基于多态类实现 的。 除此之外,抽象也是一个重要的特征,抽象就是忽略与当前目标无关的相关方面,以便 更充分地突出与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部 分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2、Java 中实现多态的机制是什么? Java 允许父类或接口定义的引用变量指向子类或具体实现类的实例对象,而程序调用的 方法在运行时才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在 运行的那个对象的方法,而不是引用变量的类型中定义的方法。 正是由于这种机制,两个相同类型的引用变量,但由于它们实际引用了不同的对象,因 此它们运行时可能呈现出多种不同的行为特征,这就被称多态。
3、一个".java"源文件中是否可以包括多个类(不是内部 类)?有什么限制? 可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件的主文件名相 同。 包含多个类的 Java 源文件编译之后会生成多个.class 文件,每个类(包括外部类、内部 类)都会生成一个对应的.class 文件。 4、String 是基本数据类型吗? 基本数据类型包括 byte、short、int、long、char、float、double 和 boolean。String 不是 基本类型。String 是引用类型。 java.lang.String 类是 final 的,因此无法通过 String 类派生子类。 String 也是一个不可变类(它所包含的字符序列是不可改变),因此如果程序需要使用 的字符串所包含的字符序列需要经常改变,建议使用 StringBuffer(线程安全、性能略差) 类或 StringBuilder 类。 5、int 和 Integer 有什么区别 Java 提供两种不同的类型:引用类型和基本数据类型。 int 是基本数据类型,Integer 是 Java 为 int 提供的包装类。 Java 为所有的基本类型提供了对应的包装类。 byte Byte short Short int Integer long Long char Character float Float double Double boolean Boolean 基本类型的变量只能当成简单的直接量、参与表达式运算,不具备面向对对象的特征, 基本类型的变量不能被赋为 null;但包装类的变量则完全可以当成对象使用,它具有面向对 象的特征,包装类的变量可以被赋为 null。 因为 Integer 具有面向对象的特征,因此 Integer 可以区分出未赋值和值为 0 的区别,int 则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为 0 的区别,则只 能使用 Integer。在 JSP 开发中,Integer 的默认为 null,所以用 EL 输出为 null 的 Integer 时, 将会显示为空白字符串,而 int 默认的默认值为 0,用 EL 输出为将显示 0。所以,int 不适 合作为 Web 层的表单数据的类型。 从 Java 5 开始,Java 提供了自动装箱、自动拆箱功能,因此包装类也可以直接参与表
达式运算,因此使用起来十分方便。 另外,Integer 提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数, Integer 中还定义了表示整数的最大值和最小值的常量。 6、Java 有没有 goto? goto 是 Java 中的保留字,Java 程序的标识符不允许使用 goto。但 Java 也不支持使用 goto 进行跳转。 7、String 和 StringBuffer、StringBuilder 的区别 Java 提供了:String、StringBuffer 和 StringBuilder,它们都是 CharSequence 的实现类, 都可以作为字符串使用。 String 代表了字符序列不可变的字符串;而 StringBuffer、StringBuilder 都代表了字符序 列可变的字符串。 StringBuffer 、StringBuilder 的 区 别 是 StringBuffer 是 线 程 安 全 的 、 性 能 略 低 , 而 StringBuilder 是线程不安全的,适合单线程环境使用,性能较好。 8、Collection 和 Collections 的区别。 Collection 是集合类(List、Set、Queue)的根接口。 Collections 是针对集合类的一个工具类,它提供一系列静态方法实现对各种集合的搜 索、排序、线程安全化等操作。 9、说说&和&&的区别。 &和&&都可以用作逻辑与的运算符,当运算符两边的表达式的结果都为 true 时,整个 运算结果才为 true,否则,只要有一方为 false,则结果为 false。 &&还具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式,例如, 对于 if(a >8 && b > 5),当 a 小于等于 8 时,由于&&之前的表达式已经为 false 了,因此&& 之后的表达式根本不会执行; 再例如 if(str != null && !str.equals(""))表达式,当 str 为 null 时,后面的表达式不会执行, 因此不会出现 NullPointerException 如果将&&改为&,则可能抛出 NullPointerException 异常。 再例如 if(x > 8 & ++y)与 if(x > 8 && ++y ),当 a 小于等于 8 时,前一个表达式中 y 的值 会增长;后一个表达式中 y 的值不会增加。 除此之外,&还可以用作位运算符,当&操作符两边的表达式不是 boolean 类型时,& 表示按位与操作,通常使用 0x0f 来与一个整数进行&运算,来获取该整数的最低 4 个 bit 位, 例如,0x31 & 0x0f 的结果为 0x01。
10、Overload 和 Override 的区别。Overloaded 的方法是否 可以改变返回值的类型? Overload 是方法的重载 Override 是方法的重写,也叫覆盖。 Overload 要求两个方法具有方法名相同、形参列表不同的要求,返回值类型不能作为重 载的条件。 Override 要求子类方法与父类方法具有“两同两小一大”的要求。两同指:即父类方法、 子类方法的方法名相同、形参列表相同;两小指:子类方法返回值类型要么是父类方法返回 值类型的子类、要么与父类方法返回值类型相同;子类方法声明抛出的异常类型要么是父类 方法声明抛出的异常类型的子类、要么与父类声明抛出的异常类型相同;一大指:子类方法 的访问权限要么与父类方法的访问权限相同,要么比父类方法的访问权限更大。 Overloaded 的方法是可以改变返回值的类型。 11、Java 如何跳出当前的多重嵌套循环? 在 Java 中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层 循环体的代码中使用带有标号的 break 语句,即可跳出外层循环。例如, outer: System.out.println(“i=” + i + “,j=” + j); if(j == 5) break ouer; for(int i=0;i<10;i++) { } for(int j=0;j<10;j++) { } 12、switch 语句能否作用在 byte 上,能否作用在 long 上, 能否作用在 String 上? 在 Java 7 以前,在 switch(expr1)中,expr1 只能是一个整数表达式(但不包括 long 和 Long)或者枚举常量,整数表达式可以是 int 基本类型或 Integer 包装类型,byte、short、 char 都可以自动转换为 int,它们都可作为 switch 表达式。 从 Java 7 开始,switch 表达式的可以使用 String。 13、String s = new String("xyz");创建了几个 String Object? 两个。一个是直接量的"xyz"字符串对象,该字符串将会被缓存在字符串常量池中,以
便以后复用这个字符串;另一个是通过 new Sting()构造器创建出来的 String 对象,这个 String 对象保存在堆内存中。 通常来说,应该尽量使用直接量的 String 对象,这样具有更好的性能。 14、数组有没有 length()这个方法? String 有没有 length()这 个方法? 数组没有 length()这个方法,有 length 属性。String 有 length()方法。 15、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1; 有什么错? 对于 short s1 = 1; s1 = s1 + 1; 由于 s1+1 运算时会自动提升表达式的类型,所以结果是 int 型,再赋值给 short 类型 s1 时,编译器将报告需要强制转换类型的错误。 对于 short s1 = 1; s1 += 1;由于 +=运算符里已经包括了一个隐式的强制类型转换,因此 Java 会把 s1+=1 计算后的结果进行隐式的强制类型转换,因此它不会有任何错误。 16、char 型变量中能不能存储一个中文字符?为什么? char 型变量是用来存储 Unicode 编码的字符的,Unicode 编码字符集中包含了汉字,因 此 char 型变量中可以存储汉字。不过,如果某个特殊的汉字没有被包含在 Unicode 编码字 符集中,那么,这个 char 型变量中就不能存储这个特殊汉字。 char 类型的变量占两个字节,而 Unicode 编码中每个字符也占两个字节,因此 char 类 型类型的变量可以存储任何一个 Unicode 字符。 17、用最有效率的方法算出 2 乘以 8 等于几? 2 << 3 因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左 移 3 位即可,而位运算 CPU 直接支持的,效率最高,所以,2 乘以 8 等于几的最效率的方 法是 2 << 3。 但需要注意的是,如果这个数字本身已经很大,比如本身已经是 2 的 30 次方了,此时 再用这种位移运算就可能导致“溢出”,这样就得不到正确结果了。 18、使用 final 关键字修饰一个变量时,是引用不能变,还 是引用的对象不能变? 使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的
内容还是可以改变的。例如,对于如下语句: final StringBuilder a = new StringBuilder ("immutable"); 执行如下语句将报告编译错误: a = new StringBuilder (""); 但如下语句则是完全正确的 a.append("fkjava.org"); 有人希望在定义方法的形参时,通过 final 修饰符来阻止方法内部修改传进来的实参: public void method(final StringBuilder param) { } 实际上这没有用,在该方法内部仍然可以增加如下代码来修改实参对象: param.append("fkjava.org"); 19、"=="和 equals 方法究竟有什么区别? ==操作符的作用有两种: A.如果==的两边都是基本类型变量、包装类对象所组成的表达式,==用于比较两边的 表达式的值是否相等——只要两边的表达式的值相等,即使数据类不同,该运算符也会返回 true。例如'a' == 97.0,将会返回 true。 B.如果==的两边是引用类型的变量,==用于判断这两个引用类型的变量是否引用同一 块内存,只有当它们引用同一块内存时,==才会返回 true。 而 equals()则是一个 java.lang.Object 类的一个方法,因此任何 Java 对象都可调用该方法 与其他对象进行比较。java.lang.Object 类的 equals 方法的实现代码如下: boolean equals(Object o) { } 从上面代码可以看出,如果一个类没有重写 java.lang.Object 的 equals()方法时,此时 return this==o; equals()方法的比较结果与==的比较结果是相同的。 但 Java 允许任何类重写 equals()方法,重写该方法就是让程序员来自己决定两个对象相 等的标准——极端的情况下,我们完全可以设计出 Person 对象与 Dog 对象 equals()比较返回 true 的情况——当然一般不会这么设计。 实际上重写 equals()方法时通常会按如下格式: public boolean equals(Object obj) { return false; return false; if (this == obj) return true; if (obj == null) if (getClass() != obj.getClass()) Person other = (Person) obj; if (name == null) {
return false; } if (other.name != null) } else if (!name.equals(other.name)) return false; if (pass == null) { } else if (!pass.equals(other.pass)) return true; 上面重写 equals()方法用于判断两个 Person 对象是否“相等”,程序只要两个 Person 对 象的 name、pass 相等,程序就可以把这两个 Person 对象当成相等——这是系统业务决定的。 如果业务需要,我们也可以增加更多的参与判断的 Field,当然也可以只根据 name 进行判断 ——只要两个 Person 的 name 相等,就认为两个 Person 相等,这都是由系统的业务决定。 总结起来就是一句话:开发者重写 equals()方法就可以根据业务要求来决定两个对象是 if (other.pass != null) return false; return false; 否“相等”。 20、静态变量和实例变量的区别? 在语法定义上的区别:静态变量前要加 static 关键字,而实例变量前则不加。 在程序运行时的区别:实例变量属于一个对象,必须先创建实例对象,它的实例变量才 会被分配空间,才能使用这个实例变量。静态变量则属于类,所以也称为类变量,只要程序 加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被 使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接 使用类名来引用。 例如,对于下面的程序: public class VarTest { } 上面程序中的 staticVar 变量随 VarTest 类初始化而分配内存、执行初始化的,以后无论 public static int staticVar = 0; public int instanceVar = 0; public VarTest () { } staticVar++; instanceVar++; System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar); 创建多少个实例对象,不会再分配 staticVar 变量,因此用永远只有一个 staticVar 变量。 但 instanceVar 变量则是随着 VarTest 对象初始化而分配内存、执行初始化的,因此每创
建一个实例对象,就会分配一个 instanceVar,即可以分配多个 instanceVar。因此上面程序中 每创建一个 VarTest 对象,staticVar 的值就会自加一,但创建每个 VarTest 对象的 instanceVar 都只自加 1。 21、是否可以从一个 static 方法内部调用非 static 方法? 不可以。静态成员不能调用非静态成员。 非 static 方法属于对象,必须创建一个对象后,才可以在通过该对象来调用 static 方法。 而 static 方法调用时不需要创建对象,通过类就可以调用该方法。也就是说,当一个 static 方法被调用时,可能还没有创建任何实例对象,如果允许从一个 static 方法中调用非 static 方法的调用,那个非 static 方法是没有调用对象的。因此 Java 不允许 static 方法内部调用非 static 方法。 22、Math.round(11.5)等於多少? Math.round(-11.5)等於多 少? Math 类中提供了三个与取整有关的方法:ceil()、floor()、round(),这些方法的作用与 它们的英文名称的含义相对应,例如,ceil 的英文意义是天花板,该方法就表示向上取整, 所以,Math.ceil(11.3)的结果为 12,Math.ceil(-11.3)的结果是-11;floor 的英文意义是地板,该 方法就表示向下取整,所以,Math.floor(11.6)的结果为 11,Math.floor(-11.6)的结果是-12;最 难掌握的是 round 方法,它表示“四舍五入”,算法为 Math.floor(x+0.5),即将原来的数字加 上 0.5 后再向下取整,所以,Math.round(11.5)的结果为 12,Math.round(-11.5)的结果为-11。 23、请说出作用域 public,private,protected,以及不写时 的区别 这四个作用域的可见范围如下表所示。 作用域 当前类 同一 package 子类 全局 public √ √ √ √ protected √ √ √ × default √ √ × × private √ × × × 说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 default。 只要记住访问权限由小到大依次是 private → default → protected → public,然后再记 住 Java 存在的 4 个访问范围,就很容易画出上面的表格了。
分享到:
收藏