[置顶] Java面试题全集(上)
2013年年底的时候,我看到了网上流传的1个叫做《Java面试题大全》的东西,认真的浏览了以后发现里面的很多题目是重复且没有价值的题目,还有很多的参考答案也是毛病的,因而我花了半个月时间对这个所谓的《Java面试大全》进行了全面的修订并重新发布在我的CSDN博客。在修订的进程中,参照了当时JDK最新版本(Java 7)给出了题目的答案和相干代码,去掉了EJB 2.x、JSF等无用内容或过时内容,补充了数据结构和算法、大型网站技术架构、设计模式、UML、Spring MVC等内容并对很多知识点进行了深入的剖析,例如hashCode方法的设计、垃圾搜集、并发编程、数据库事务等。当时我乃至希望把面试中常常出现的操作系统、数据库、软件测试等内容也补充进去,但是由于各种缘由,终究只整理出了150道面试题。让我欣慰的是,这150道题还是帮助到了很多人,而且在我CSDN博客上的总访问量超过了5万次,终究还被很多网站和个人以原创的方式转载了。最近1年内,用百度搜索"Java面试"我写的这些东西基本上都排在搜索结果的前5名,这让我觉亚历山东大学,由于这些内容1旦不准确便可能误导很多人。2014年的时候我又整理了30道题,希望把之前遗漏的面试题和知识点补充上去,但是依然感觉挂1漏万,而且Java 8问世后很多新的东西又需要去总结和整理。为此,我不止1次的修改了之前的180题,修改到自己已感觉有些疲惫或厌烦了。2014年至今,自己带的学生又有很多走上了Java程序员、Java工程师的工作岗位,他们的面试经历也还没来得及跟大家分享,因而乎有1种冲动让我决心重新写1篇《Java面试题全集》,因而这篇文章就诞生了。请不要责备我把那些出现过的内容又写了1次,由于每次写东西就算是重复的内容,我也需要对我们使用的编程语言和相干技术进行重新思考,力求字斟句酌以期至臻完善,所以请相信我分享的1定是最好的东西,1定是有益的东西,1定会有新的东西,而这些内容也必定诉说着1个职业程序员的思想、精神和情感。 1、面向对象的特点有哪些方面? 2、访问修饰符public,private,protected,和不写(默许)时的区分?
类的成员不写访问修饰时默许为default。默许对同1个包中的其他类相当于公然(public),对不是同1个包中的其他类相当于私有(private)。受保护(protected)对子类相当于公然,对不是同1包中的没有父子关系的类相当于私有。Java中,外部类的修饰符只能是public或默许,类的成员(包括内部类)的修饰符可以是以上4种。 3、String 是最基本的数据类型吗? 4、float f=3.4;是不是正确? 5、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗? 6、Java有无goto? 7、int和Integer有甚么区分? 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 两个援用没有援用同1对象
System.out.println(a == c); // true a自动拆箱成int类型再和c比较
}
} 最近还遇到1个面试题,也是和自动装箱和拆箱有点关系的,代码以下所示: 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、f44个变量都是Integer对象援用,所以下面的==运算比较的不是值而是援用。装箱的本质是甚么呢?当我们给1个Integer对象赋1个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);
} IntegerCache是Integer的内部类,其代码以下所示: /**
* Cache to support the object identity semantics of autoboxing for values between
* ⑴28 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 [⑴28,127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
} 简单的说,如果整型字面量的值在⑴28到127之间,那末不会new新的Integer对象,而是直接援用常量池中的Integer对象,所以上面的面试题中f1==f2的结果是true,而f3==f4的结果是false。
8、&和&&的区分?
9、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法。 String str = new String("hello"); 上面的语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而"hello"这个字面量放在静态区。
10、Math.round(11.5) 等于多少?Math.round(⑴1.5)等于多少? 11、swtich 是不是能作用在byte 上,是不是能作用在long 上,是不是能作用在String上? 12、用最有效力的方法计算2乘以8?
public class PhoneNumber {
private int areaCode;
private String prefix;
private String lineNumber;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + areaCode;
result = prime * result
+ ((lineNumber == null) ? 0 : lineNumber.hashCode());
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PhoneNumber other = (PhoneNumber) obj;
if (areaCode != other.areaCode)
return false;
if (lineNumber == null) {
if (other.lineNumber != null)
return false;
} else if (!lineNumber.equals(other.lineNumber))
return false;
if (prefix == null) {
if (other.prefix != null)
return false;
} else if (!prefix.equals(other.prefix))
return false;
return true;
}
} 13、数组有无length()方法?String有无length()方法? 14、在Java中,如何跳出当前的多重嵌套循环? 15、构造器(constructor)是不是可被重写(override)? 16、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
17、是不是可以继承String类?
18、当1个对象被当作参数传递到1个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那末这里究竟是值传递还是援用传递? using System;
namespace CS01 {
class Program {
public static void swap(ref int x,ref int y) {
int temp = x;
x = y;
y = temp;
}
public static void Main (string[] args) {
int a = 5,b = 10;
swap (ref a,ref b);
// a = 10,b = 5;
Console.WriteLine ("a = {0},b = {1}",a,b);
}
}
}
19、String和StringBuilder、StringBuffer的区分?
class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program" + "ming";
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s1 == s1.intern());
}
}
20、重载(Overload)和重写(Override)的区分。重载的方法能否根据返回类型进行辨别?
21、描写1下JVM加载class文件的原理机制?
22、char 型变量中能不能存贮1个中文汉字,为何?
23、抽象类(abstract class)和接口(interface)有甚么异同? 24、静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同? /**
* 扑克类(1副扑克)
* @author 骆昊
*
*/
public class Poker {
private static String[] suites = {"黑桃","红桃","草花","方块"};
private static int[] faces = {1,2,3,4,5,6,7,8,9,10,11,12,13};
private Card[] cards;
/**
* 构造器
*
*/
public Poker() {
cards = new Card[52];
for(int i = 0; i < suites.length; i++) {
for(int j = 0; j < faces.length; j++) {
cards[i * 13 + j] = new Card(suites[i],faces[j]);
}
}
}
/**
* 洗牌 (随机乱序)
*
*/
public void shuffle() {
for(int i = 0,len = cards.length; i < len; i++) {
int index = (int) (Math.random() * len);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
}
/**
* 发牌
* @param index 发牌的位置
*
*/
public Card deal(int index) {
return cards[index];
}
/**
* 卡片类(1张扑克)
* [内部类]
* @author 骆昊
*
*/
public class Card {
private String suite; // 花色
private int face; // 点数
public Card(String suite,int face) {
this.suite = suite;
this.face = face;
}
@Override
public String toString() {
String faceStr = "";
switch(face) {
case 1: faceStr = "A"; break;
case 11: faceStr = "J"; break;
case 12: faceStr = "Q"; break;
case 13: faceStr = "K"; break;
default: faceStr = String.valueOf(face);
}
return suite + faceStr;
}
}
} 测试代码: class PokerTest {
public static void main(String[] args) {
Poker poker = new Poker();
poker.shuffle(); // 洗牌
Poker.Card c1 = poker.deal(0); // 发第1张牌
// 对非静态内部类Card
// 只有通过其外部类Poker对象才能创建Card对象
Poker.Card c2 = poker.new Card("红心",1); // 自己创建1张牌
System.out.println(c1); // 洗牌后的第1张
System.out.println(c2); // 打印: 红心A
}
}
class Outer {
class Inner {}
public static void foo() { new Inner(); }
public void bar() { new Inner(); }
public static void main(String[] args) {
new Inner();
}
}
new Outer().new Inner(); 25、Java 中会存在内存泄漏吗,请简单描写。 import java.util.Arrays;
import java.util.EmptyStackException;
public class MyStack<T> {
private T[] elements;
private int size = 0;
private static final int INIT_CAPACITY = 16;
public MyStack() {
elements = (T[]) new Object[INIT_CAPACITY];
}
public void push(T elem) {
ensureCapacity();
elements[size++] = elem;
}
public T pop() {
if(size == 0)
throw new EmptyStackException();
return elements[--size];
}
private void ensureCapacity() {
if(elements.length == size) {
elements = Arrays.copyOf(elements,2 * size + 1);
}
}
} 上面的代码实现了1个栈(先进后出(FILO))结构,乍看之下仿佛没有甚么明显的问题,它乃至可以通过你编写的各种单元测试。但是其中的pop方法却存在内存泄漏的问题,当我们用pop方法弹出栈中的对象时,该对象不会被当作垃圾回收,即便使用栈的程序不再援用这些对象,由于栈内部保护着对这些对象的过期援用(obsolete reference)。在支持垃圾回收的语言中,内存泄漏是很隐蔽的,这类内存泄漏其实就是无意识的对象保持。如果1个对象援用被无意识的保存起来了,那末垃圾回收器不会处理这个对象,也不会处理该对象援用的其他对象,即便这样的对象只有少数几个,也可能会致使很多的对象被排除在垃圾回收以外,从而对性能造成重大影响,极端情况下会引发Disk Paging(物理内存与硬盘的虚拟内存交换数据),乃至造成OutOfMemoryError。 26、抽象的(abstract)方法是不是可同时是静态的(static),是不是可同时是本地方法(native),是不是可同时被synchronized修饰? 27、论述静态变量和实例变量的区分。
28、是不是可以从1个静态(static)方法内部发出对非静态(non-static)方法的调用? 29、如何实现对象克隆? import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class MyUtil {
private MyUtil() {
throw new AssertionError();
}
public static <T> T clone(T obj) throws Exception {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bout);
oos.writeObject(obj);
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bin);
return (T) ois.readObject();
// 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
// 这两个基于内存的流只要垃圾回收器清算对象就可以够释放资源,这1点不同于对外部资源(如文件流)的释放
}
} 下面是测试代码: import java.io.Serializable;
/**
* 人类
* @author 骆昊
*
*/
class Person implements Serializable {
private static final long serialVersionUID = -9102017020286042305L;
private String name; // 姓名
private int age; // 年龄
private Car car; // 座驾
public Person(String name,int age,Car car) {
this.name = name;
this.age = age;
this.car = car;
}
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 Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "Person [name=" + name + ",age=" + age + ",car=" + car + "]";
}
} /**
* 小汽车类
* @author 骆昊
*
*/
class Car implements Serializable {
private static final long serialVersionUID = -5713945027627603702L;
private String brand; // 品牌
private int maxSpeed; // 最高时速
public Car(String brand,int maxSpeed) {
this.brand = brand;
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
@Override
public String toString() {
return "Car [brand=" + brand + ",maxSpeed=" + maxSpeed + "]";
}
} class CloneTest {
public static void main(String[] args) {
try {
Person p1 = new Person("Hao LUO",33,new Car("Benz",300));
Person p2 = MyUtil.clone(p1); // 深度克隆
p2.getCar().setBrand("BYD");
// 修改克隆的Person对象p2关联的汽车对象的品牌属性
// 原来的Person对象p1关联的汽车不会遭到任何影响
// 由于在克隆Person对象时其关联的汽车对象也被克隆了
System.out.println(p1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
30、GC是甚么?为何要有GC?
与垃圾回收相干的JVM参数:
31、String s = new String("xyz");创建了几个字符串对象? 32、接口是不是可继承(extends)接口?抽象类是不是可实现(implements)接口?抽象类是不是可继承具体类(concrete class)? 33、1个".java"源文件中是不是可以包括多个类(不是内部类)?有甚么限制? 34、Anonymous Inner Class(匿名内部类)是不是可以继承其它类?是不是可以实现接口? 35、内部类可以援用它的包括类(外部类)的成员吗?有无甚么限制? 36、Java 中的final关键字有哪些用法? 37、指出下面程序的运行结果。 class A {
static {
System.out.print("1");
}
public A() {
System.out.print("2");
}
}
class B extends A{
static {
System.out.print("a");
}
public B() {
System.out.print("b");
}
}
public class Hello {
public static void main(String[] args) {
A ab = new B();
ab = new B();
}
} 答:履行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用本身构造器。
38、数据类型之间的转换: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |