JAVA面试宝典

引用变量与对象

A aa=new A();

这个最基本语句的含义是,使用new在heap中创建一个A类的对象,并把这个A类对象的引用赋值给aa,即aa本身不是A类的对象,而是A类对象的引用变量,也称为句柄,这点本质上和C++是一个意思。

JAVA字符串与常量池

(1)    常量池Constant Pool。由于JAVA中包含大量字符串,每个字符串都是一个对象,每个对象都要在heap中占据空间,针对上述问题,JAVA为了节省内容空间和提高运行时间,在编译时将所有字符串文字放到常量池中,将所有相同的字符串常量进行合并,只占用一个空间。

例如 String s1=”abc”; String s2=”abs”;那么当进行s1==s2时,返回的是true,因为在内存中s1和s2引用的是同一个副本。

此外,String类的intern()方法是直接与常量池交互的。即当调用intern()方法时,如果常量池中已经包含该字符串,则无需创建直接返回;否则再往常量池中增添此String对象。

(2)    String对象的创建。首先JAVA中任何一个字符串常量或者字符串文字都是一个String对象,即在JAVA中,使用双引号本质上就是创建了一个JAVA对象。那么,String s=new String(“abc”)其实是创建了两个String对象,一个在常量池中,一个在Heap中。如果再加上String s2=new String(“abc”),那么一共创建了三个JAVA对象。

(3)    JAVA中String类是非可变性的(immutable)。因为从原理上讲JAVA中是使用privatefinal char value[]的方式来实现字符串存储的,因此String对象创建之后,就不能再修改此对象中存储的字符串内容。由于同一对象的内容不允许修改,因此有效避免了不一致性的产生。例如String s=”a”; s+=”b”;上述写法是需要避免的,因为它开辟了两个内存段,当执行第二句是其实另外创建了一个对象,而原来s指向的对象就成为了垃圾。为了解决这个问题,可以使用String的配套类StringBuffer。StringBuffer类对象的内容是可变的,像上面那个例子通过调用其append方法即可:StringBuffer sb=new StringBuffer(“a”); sb.append(“b”);

多态

         多态是面向对象中最重要的特性。

(1)    什么是多态?首先形象地讲,“如果它不是晚绑定,就不是多态”,即多态的本质是动态联编,在运行时而不是编译时进行函数绑定。其次讲得技术点,多态是允许将子类类型的指针或者引用赋值给基类类型的指针或者引用,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式进行运作。

(2)    多态有什么好处?多态最大的好处就是接口重用。因为接口往往是一个公司最有价值的资源,接口的设计属于架构设计,比用具体的类来实现这些接口更耗费时间和人力;此外,就如我说的,多态性的另一个重要作用是将接口与实现分开,改善代码的组织结构,增强代码可读性。

(3)    JAVA与C++多态性的区别:在C++中,多态性是通过在基类中定义虚函数来实现的;在JAVA中,不需要定义虚函数,除了static和final方法外,其他所有方法都是在运行时绑定的,也就是说C++中的虚函数也就对应于JAVA中的普通函数,这也是JAVA解释执行而不是编译执行的体现。(注,由于private方法被隐式指定为final的,因此在JAVA中实现多态时不要定义成private的了)

(4)    Override与Overload:Override是覆盖,即子类重新定义父类虚函数的方法,用于实现多态;Overload是重载,即允许存在多个同名函数,只是这些函数的参数表不同而已,与多态性无关,在编译时就可以确定。

(5)    虚函数表

JAVA抽象类

在JAVA中,是通过定义抽象类来实现多态的.如下面的例子,在抽象类中包含一个等着子类覆盖实现的抽象函数(当然,极端情况下,抽象类也可以不定义抽象函数)

如abstract class base

{        publicabstract void myFunc();

         publicvoid print{“print”};

}

         在C++中,概念稍有不同:C++中没有对抽象类进行声明的方法,而是只要在类中定义了虚函数,那么这个类就是抽象类,不需要显式声明。

Class base

{public:

Virtual void myFunc();

Void print(“print”);

}

         JAVA中抽象类与接口的异同:首先相同点是接口可以理解为一种特殊的抽象类;不同点在于抽象类是用于继承的,那么体现出的是一种”is a”的概念;接口是用于实现的,那么体现出的是一种”like a”的概念。此外,从语法上也有一点区别,在抽象类中还能定义其他非抽象的变量和方法,而在接口中则不能。详见:http://www.enet.com.cn/article/2007/1126/A20071126923475.shtml

 

编译执行与解释执行

         总所周知,JAVA是解释执行的,而C++是编译执行的,那么具体有什么区别呢?

(1)    JAVA-编译和解释型语言   

 一个JAVA文件,首先会由JAVA编译器(JAVAC)编译成class(字节码文件)文件,然后由Java虚拟机(JVM)去解释。不同的操作系统只要装有适合不同平台的JDK,JAVA文件都可以被解释运行。JAVA是一种编译和解释型语言。
       字节码文件(class)之所以能够被JAVA虚拟机(JVM)所解释,最主要的原因就是字节码文件(class)里面所包含的内容是可以被JAVA虚拟机(JVM)所解释的一种高度优化指令。而JAVA文件只需要编译一次就可以在不同的操作系统上解释运行,也就是说一次编译处处运行,这就是JAVA可以跨平台的原因。

(2)    C++-编译型语言

       C++没有虚拟机这种概念,也就是说C++一旦编译就可以运行,是一种编译型语言,速度上比JAVA快得多,C++编译完成后是机器码(二进制文件)可以直接在操作系统上运行。

(3)    C#-编译再编译型语言

       C#与一样,同样有虚拟机,但是他的虚拟机是CLR(公共语言运行时)。一个C#文件,首先会由C#编译器编译成低级别的中间语言IL,然后由C#虚拟机也就是公共语言运行时(CLR)即时编译(JIT)编译成机器代码,再由CUP去执行它。所以说C#的执行必须通过二次编译。

 

正则表达式

详见http://deerchao.net/tutorials/regex/regex.htm

大括号{}用来表示重复的次数;中括号[]用来表示列举

在JAVA中使用regex时,对于\要再进行一次转义才行,例如\D就要写成\\D才能编译通过。

 

ACSII码

大写A的ASCII码是65,小写a的ASCII码是97。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章