Android程序员面试分类模拟2.docx
Android程序员面试分类模拟2论述题1. JaVa语言有哪些优点?正确答案:SUN公司对JaVa语言的描述如下:"Javaisasimple,object-oriented,dist(江南博哥)ributed,interpreted,robust,secure,architectureneutral,portable,high-performance,multithreaded,anddynamiclanguage"具体而言,Java语言具有以下几个方面的优点:DJaVa为纯面向对象的语言(Java编程思想提到JaVa语言是一种mEverythingisObjeCt"的语言),它能够直接反映现实生活中的对象,例如火车、动物等,因此通过它,开发人员更容易编写程序。2)平台无关性。JaVa语言可以一次编译,到处运行。无论是在WindoWS平台还是在1.inUx、macOS等其他平台上对JaVH程序进行编译,编译后的程序在其他平台上都可以运行。由于JaVa是解释型语言,编译器会把JaYa代码变成“中间代码”,然后在JVM(JavaVirtualMachine,JaVa虚拟机)上被解释执行。由于中间代码与平台无关,所以,Java语言可以很好地跨平台执行,具有很好的可移植性。3) JaVa提供了很多内置的类库,通过这些类库,简化了开发人员的编程工作,同时缩短了项目的开发时间。例如:提供了对多线程支持,提供了对网络通信的支持,最重要的一点是提供了垃圾回收器,把开发人员从对内存的管理中解脱出来。4)提供了对Web应用开发的支持,例如APPlet、ServIet和JSP可以用来开发Web应用程序。Socket,RMl可以用来开发分布式应用程序的类库。5)具有较好的安全性和健壮性。JaVa语言经常被用在网络环境中,为了增强程序的安全性,Java语言提供了一个防止恶意代码攻击的安全机制(数组边界检测和bytecode校验等3Java的强类型机制、垃圾回收器、异常处理和安全检查机制使得使用Java语言编写的程序有很好的健壮性。6)去除了C+语言中难以理解、容易混淆的特性,例如头文件、指针、结构、单元、运算符重载、虚拟基础类、多重继承等,使得程序更加严i革、简洁。2. instanceof有什么作用?正确答窠:instanceof是Java语言中的一个:元运算符,它的作用是判断一个引用类型的变量所指向的对象是否为一个类(或接口、抽象类、父类)的实例,即它左边的对象是否是它右边的类的实例,返回boolean类型的数据。常见的用法为:resull=objcctinslanccofclass,如果ObjCet是CIaSS的一个实例,则instanceof运算符返回true。如果。bject不是指定类的一个实例,或者object是nu11,则返回false,以如下程序为例:PUbliCclassTest(ublicstaticvoidnain(Stringargs)(Strings="Hello”;inta=l,2;if(sInstanceofString)System.out.PrintIn("true");if(sinstanceofObject)System.out.PrintIn("true");if(ainstanceofint)System,out.Println("true");)程序运行结果为:truetruetrue3. 一个Java文件中是否可以定义多个类?正确答案:一个JaVa文件可以定义多个类,但是最多只能有一个类被PUbliC修饰,并且这个类的类名与文件名必须相同,若这个文件中没有PUbliC的类,则文件名随便是一个类的名字即可。需要注意的是,当用javac指令编译这个java文件的时候,它会给每一个类生成一个对应的.class文件。如下例定义DCriVed.java为:classBase(publicvoidprintO(System.out.PrintIn("Base");)publicclassDerivedextendsBasepublicstaticvoidmain(Stringa)Basec=ncwDerivedO;c.print0;)I使用javacDeriVed.java指令编译上述代码,会生成两个字节码文件:Base.class与Derived.class,然后使用javaDerived指令执行,会输出:Basee4. 变量命名有哪些规则?正确答窠:在JaVa语言中,变量名、函数名、数组名统称为标识符,JaVa语言规定标识符只能由字母(az,AZ)、数字(09)、下划线(J和$组成,并且标识符的第一个字符必须是字母、下划线或$。此外,标识符也不能包含空白字符(换行符、空格和制表符),以卜标识符都是非法的:I)Char:Char是JaVa语言的一个数据类型,是保留字,不能作为标识符,其他的如int、float等类似。2) numberofbook:标识符中不能有空格。3)3com:不能以数字开头。4)a*B:*不能作为标识符的字符。值得注意的是,在Java语言中,变量名是区分大小写的,例如C。Unt与count被认为是两个不同的标识符。5. “="、equals和hashCode的区别是什么?正确答案:“=”运算符用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用“=”运算符。具体而言,如果两个变量是基本数据类型,可以直接用“=”来比较其对应的值是否相等。如果一个变量指向的数据是对象(引用类型),那么,此时涉及了两块内存,对象本身占用一块内存(堆内存),对象的引用也占用一块内存。例如,对于赋值语句Strings=newStringO,变量S占用一块存储空间(一般在栈中),而newString()则存储在另外块存储空间里(一般在堆中),此时,变量S所时应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等(这两个对象是否指向同一块存储空间),这时候就可以用“=”运弊符进行比较。但是,如果要比较这两个对象的内容是否相等,那么用“=”运算符就无法实现了。2)equals是Object类提供的方法之一,每一个Java类都继承自Object类,所以每一个对象都具有equals这个方法。ObjeCt类中定义的equals(Object)方法是直接使用“=”比较的两个对象,所以在没有覆盖equals(Object)方法的情况F,equals(Object)与“=”一样,比较的是引用。相比“="运算符,equals(Object)方法的特殊之处就在于它可以被覆盖,所以可以通过覆盖这个方法让它不是比较引用而是比较对象的属性。例如String类的equals方法是用于比较两个独立对象的内容是否相同,即堆中的内容是否相同。例如,对于下面的代码:Stringsl=newString("HelIo");Strings2三newString(*Hello*);两条new语句在堆中创建了两个对象,然后用si、s2这两个变量分别指向这两个对象,这是两个不同的对象,它们的首地址是不同的,即SI和s2中存储的数值是不相同的,所以,表达式a=b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。如果一个类没有实现equals方法,那么它将继承ObjeCt类的equals方法,Object类的equals方法的实现代码如卜丁booleanequals(Objecto)returnthis=o;)通过以上例子可以说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用“=”运算符,也是在比较两个变量指向的时象是否为同对象,此时使用equals方法和使用“=”会得到同样的结果,如果比较的是两个独立的对象则总返IUlfalse。如果编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么必须覆盖equals方法,由开发人员自己写代码来决定在什么情况即可认为两个对象的内容是相同的。3)hashCode()方法是从ObjeCl类中继承过来的,它也用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象在内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。虽然equals方法也是用来判断两个对象是否相等的,但此二者也有区别的。一般来讲,equals方法是给用户调用的,如果需要判断两个对象是否相等,可以重写equals方法,然后在代码中调用,就可以判断它们是否相等/0对于hashCode()方法,用户一般不会去调用它,例如在HaShMaP中,由于key是不可以重复的,它在判断key是否重复的时候就判断了hashCode()这个方法,而且也用到了equals方法。此外“不可以重夏”指的是equals和hashCode()只要有一个不等就可以了。所以,hashC。加0相当于是一个对象的编码,就好像文件中的md5,它与CqUaIS方法的不同之处就在于它返回的是int型,比较起来不直观。一般在粗盖equals方法的同时也要覆盖hashCOdCo方法,否则,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类(HaShMap、HaShSet和HaShtable)结合在一起正常运行。hashCode()的返回值和equals方法的关系如F:如果x.equals(y)返回true,即两个对象根据equals方法比较是相等的,那么调用这两个对象中任意一个对象的IiashCodeO方法都必须产生同样的整数结果。如果x.equals(y)返回false,即两个对象根据equals。方法比较是不相等的,那么X和y的hashCode()方法的返回值有可能相等,也有可能不等。反过来,hashCode()方法的返回值不等,定能推出equals方法的返回值也不等,而hashC。加0方法的返回值相等,则equals方法的返回值可能相等,也可能不等。6. “V<”运算符与“>>”运算符有何异同?正确答案:“VV”运算符表示左移,左移n位表示原来的值乘2的n次方。经常用来代替乘法操作,例如:一个数m乘以16可以表示为将这个数左移4位(mVV4),由于CPU直接支持位运算,因此位运算比乘法运算的效率高。与右移运算不同的是,左移运算没有有符号与无符号左移,在左移的时候,移除高位的同时再低位补0。以4VV3(4为int型)为例,其运算步骤如下所示:1)把4转换为二进制数字OOoo00000000000000000000000001002)把该数字的高三位移走,同时其他位向左移动3位。3)在最低位补3个零。最终结果为OOOO0000000000000000000000100000,对应的十进制数为32。与右移运算符相同的是,当进行左移运算时,如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。例如对int型移动33位,实际上只移动了33%32=1位。7. Java程序初始化的顺序是怎样的?正确答案:在JaVa语言中,当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建时象。JaVa程序的初始化一般遵循以下3个原则(优先级依次递减):静态对象(变量)优先于非静态对象初始化,其中,静态对象(变量)只初始化一次,而非静态对象(变量)可能会初始化多次。父类优先于子类进行初始化。按照成员变量定义顺序进行初始化。即使变量定义散布于方法定义之中,它们依然在任何方法(包括构造方法)被调用之前先进行初始化。JaVa程序的初始化工作可以在许多不同的代码块中来完成(例如:静态代码块、构造函数等),它们执行的顺序为:父类静态变量一父类静态代码块一子类静态变量一子类静态代码一父类非静态变量一父类非静态代码块父类构造函数一子类非静态变量一子类非静态代码块一子类构造函数.卜面给出一个不同模块初始化时执行顺序的一个例子。classBasestatic(System.out.println(*Basestaticblock");)System,out.PrintJn("Baseblock*);publicBase()“初System,out.PrintIn("Baseconstructor*);I)publicclassDerivedextendsBasestaticSystem.out.printIn(Derivedstaticblock*);(System,out.println(z,Derivedblock*);IpublicDerivedO“System,out.printIn("Derivedconstructor):)publicstaticvoidmain(Stringargs)newDerived();)程序运行结果为:BasestaticblockDerivedstaticblockBaseblockBaseconstructorDerivedblockDerivedconstructor这里需要注意的是,(静态)非静态成员域在定义时初始化和(静态)非静态块中初始化的优先级是平级的,也就走说按照从上到下初始化,最后一次初始化为最终的值(不包括非静态的成员域在构造器中初始化)。所以在(静态)非静态块中初始化的域甚至能在该域声明的上方,因为分配存储空间在初始化之前就完成了。如下例所示:publicclassIestStalicstatica=2;staticinta=l;staticintb=3;staticb=4:publicstaticvoidmain(Stringargs)(System,out.println(八);System,out.println(b):)程序运行结果为:148. JDK中哪些类是不能被继承的?正确答案:不能继承的类是那些用final关键字修饰的类。一般比较基本的类型为防止扩展类无意间破坏原来方法的实现的类型都应该是final的,在JDK中,String,StringBUffer等都是基本类型。所以,String和StringBUffer等是不能继承的。9. 运算符优先级是什么?正确答案:Java语言中有很多运算符,由于运算符优先级的问题经常会导致程序出现意想不到的结果,下表详细介绍了运算符的优先级。运算符优先级£先运算符1.O2+(正)-(负)+I3*/%4+(加)-(减)5<<>>(无符号右移)>>>(有符号右移)6<<=>>=instanceof78&9I结合性从左向右10在实际使用的时候,如果不确定运算符的优先级,最好通过括号运算符来控制运算顺序。10. 数组的初始化方式有哪几种?正确答案:在JaVa语言中,一维数组的声明方式为:typearrayName口或typearrayName其中type既可以是基本的数据类型,也可以是类,arrayName表示数组的名字,口用来表示这个变量的类型为一维数组。与C/C+语言不同的是,在Java语言中,数组被创建后会根据数组存储的数据类型初始化成对应的初始值(例如,int类型会初始化为0,对象会初始化为null)。另外一个不同之处是JaVa数组在定义的时候,并不会给数组元素分配空间,因此口中不需要指定数组的长度,对于使用上面方式定义的数组在使用的时候还必须为之分配空间,分配方法为:arrayName=newtypearraySize;arraySize表示数组的长度在完成数组的声明后,需要对其进行初始化,下面介绍两种初始化方法:l)inta=newint5;动态创建5个整型,默认初始化为O2)inta=l,2,3,4,5;声明一个数组类型变量并初始化。当然,在使用的时候也可以把数组的声明和初始化分开来写,例如:l)inta;声明一个数组类型的对象aa=newint5;给数组a申请可以存储5个int类型大小的空间,默认值为O2)inta;声明一个数组类型的对象aa=newint口U,2,3,4,5;给数组申请存储空间,并初始化为默认值以上主要介绍r-维数组的声明与初始化的方式,下面介绍二维数组的声明与初始化的方式,二维数组有3种声明的方法:1) typearrayName;2) typearrayName;3) typearrayName;其中必须为空。二维数组也可以用初始化列表的方式来进行初始化,它的一般形式为:typearrayNane=(cll,cl2,cl3.),(c21,c22,c23.c31,c32,c33.;也可以通过new关键字来给数组申请存储空间:typearrayname=newtype行数列数与C/C+语言不同的是,在JaVa语言中,:维数组的第维的长度可以不同。假如要定义一个二维数组有两行,第一行有两列,第:行有三列,定义方法如下:4) intarr=12,345);5) inta=newint2;aO=newint1,2;al=newint3,4,5):对二维数组的访问也是通过下标来完成的,一般形式为anyName行号列号,下例介绍二维数组的遍历方法。publicclassTest(publicstaticvoidmain(Stringargs)inta=newint2;a0=newint1,2;a1=newint3,4,5):for(inti=0;i<a.Iengthji+)for(intj=0;j<ai.Iengthjj+)System.out.print(aij+,*);)I程序运行结果为:1234511. Java如何实现类似于C语言中函数指针的功能?正确答案:在C语言中,有个非常重要的概念:函数指针,其最重要的功能是实现回调函数。什么是回调函数呢?所谓回调函数,就是指函数先在某处注册,而它将在稍后某个需要的时候被调用。在IYindOWS系统中,开发人员想让系统D1.1.(Dynamic1.ink1.ibrary,动态链接库)调用自己编写的一个方法,于是利用D1.1.当中回调函数的接口来编写程序,通过传递一个函数的指针来被调用,这个过程就称为回调。回调函数一般用于截获消息、获取系统信息或处理异步事件。举一个简单例子,程序员A写了一段程序a,其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调属于臼己的程序b中的方法。函数指针一般作为函数的参数来使用,开发人员在使用的时候可以根据自己的需求传递自定义的函数来实现指定的功能。例如:在实现排序算法的时候,可以通过传递一个函数指针来决定两个数的先后顺序,从而最终决定该算法是按升序还是降序排列。由于在Java语言中没有指针的概念,那么如何才能实现类似于函数指针的功能呢?可以利用接口与类来实现同样的效果。具体而言,首先定义一个接口,然后在接口中声明要调用的方法,接着实现这个接口,最后把这个实现类的一个对象作为参数传递给调用程序,调用程序通过这个参数来调用指定的方法,从而实现回调函数的功能。如卜例所示:接口中定义了一个用来比较大小的方法interfaceIntCompare(publicintcmp(inta,intb):)classCmplimplements1.ntComparepublicintcmp(inta,intb)if(a>b)return1;elseif(a<b)return-1;elsereturnO;IIclassCmp2implementsIntCompare(publicintcmp(inta,intb)if(a>b)return-1;elseif(a<b)return1;elsereturnO;I)publicclassTest(publicstaticvoidinsertSort(inta,IntComparecmp)if(a!=null)for(inti=l;i<a.Icngthji+)(inttcmp=ai,j=i;if(cmp.cmp(aj-l,temp)=1)(while(j>=lcmp.cmp(aj1,temp)=l)(aj=aj-l;J:)aj=temp;)publicstaticvoidmain(Stringargs)intarray1=7,3,19,40,4,7,1;insertSort(array1,newCmp1();SyStem.out.print("升序排列:”);for(inti=0;i<arrayl.length;i+)System,out.print(array1i+,"):System,out.println():intarray2=7,3,19,40,4,7,1;insertSort(array2,newCmp2O);System,out.Print("降序排列:”);for(inti=0;i<array2.length;i+)System.out.print(array2i+,");)I程序运行结果为:升序排列:134771940降序排列:401977431在上例中,定义了一个用来比较大小的接口IntCompare,这个接口实际上充当rC语言中函数指针的功能,在使用的时候,开发人员可以根据实际需求传入自定义的类。在上例中分别有两个类CmPI和CmP2都实现了这个接口,分别用来在实现升序排序和降序排序的时候使用。其实这也是策略设计模式所用到的思想。12. 如何实现无符号数右移操作?正确答案:JaVa提供了两种右移运算符:”和“>>>”。其中,“>>”被称为有符号右移运算符,“>>>”被称为无符号右移运算符,它们的功能是将参与运算的对象对应的二进制数右移指定的位数。不同点在于“>>”在执行右移操作的时候,如果参与运算的数字为正数时,则在高位补0,若为负数则在高位补1。而“>>>”则不同,无论参与运算的值为正或为负,都会在高位补Oo此外,需要特别注意的是,对于Char、byte.Short等类型的数进行移位操作前,都会自动将数值转化为int型,然后才进行移位操作,由于int型变量只占4个字节(32位),因此当右移的位数超过32时,移位运算没有任何意义。所以,在JaVa语言中,为了保证移动位数的有效性,使得右移的位数不超过32,采用了取余的操作,即a>>n等价于a>>(n%32)°如下例所示:publicclassTestpub!icstaticvoidmai11(Stringa)(inti=-4;System.out.PrintIn("int>>:*+i);System,out.PrintIn("移位前二进制:"+Integer.toBinaryString(i);i>>=1;System,out.PrintIn("移位后二进制:"+Integer.toBinaryString(i):System,out.println(*int>>:*+i);i=-4;System,out.Println("int>>>+i);System,out.PrintIn("移位前二进制:"+Integer.IoBinaryString(i);i>>>=l;System.out.Println(“移位后二进制:*+Integer.toBinaryString(i);System,out.println(wint>>>:*+i);shortj="4;System,out.rintln(wshort>>>+j);System,out.Println("移位前二进制:*+Integer.toBinaryString(j):j>>>=l;System,out.PrintIn("移位后:进制:"+Integer.toBinaryString(j);System.out.Println("Short>>>:"+j);i=5;System,out.println(*int>>:*+i);System.out.PrintIn("移位前二进制:*+Integer.toBinaryString(i);i>>=32;System.out.PrintIn("移位后二进制:*+Integer.toBinaryStri11g(i);System,out.rintln(*int>>:*+i);I)程序运行结果为:int>>:-4移位前二进制:Iiiiiiiiiiiiiiiiiiiiiiiiiiiii100移位后二进制:Iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioint>>:-2int>>>:-4移位前二进制:IlllllllllllllinillllllllllllOO移位后二进制:IllllillllllllllilllllllllilllOint>>>:2147483646short>>>:-4移位前二进制:Iiiiiiiiiiiiiiiiiiiiiiiiiiiii100移位后二进制:IlllullUIUllulIUIlIllUllIOshort>>>:-2int>>:5移位前二进制:101移位后二进制:101int>>:5需要特别说明的是,对于ShOrt类型来说,由于Short只占两字节,在移位操作的时候会先转换为int类型,虽然在进行无符号右移的时候会在高位补1,当把运算结果再赋值给Short类型的时候,只会取其中低位的两个字节,因此,高位无论补0还是补1对运算结果无影响。在上例中,-4的二进制表示为IIIUIululIlO0(负数以补码格式存储),在转换为二进制的时候会以4字节的方式输出,高位会补1,因此输出为UlUUUIUIUluulIuulul00,在执行无符号数右移后其二进制变为OlIUnIIIlIIIllllIIllIulIlll10,当把运算结果再复制给i的时候只会取低位的两个字节,因此,运算结果的二进制表示为IlIIIUIIIlIll10,对应的卜进制值为-2,当把2以二进制形式输出的时候,同理会以4字节的方式输出,高位会补1,因此输出为Iiiiiiiiiiiiiiiiiiiiiiiiiiiiii10013. 多态的实现机制是什么?正确答案:多态是面向时象程序设计中代码重用的个重要机制,它表示当同一个操作作用在不同的对象的时候,会有不同的语义,从而会产生不同的结果。例如:同样是“+”操作,3+4用来实现整数相加,而“3”+“4”却实现了字符串的连接。在JaVa语言中,多态主要有以下两种表现方式。1)重载(OVerload)重载是指同一个类中有多个同名的方法,但这些方法有着不同的参数,因此可以在编译的时候就可以确定到底调用哪个方法,它是一种编译时多态。重我可以被看作一个类中的方法多态性。2)重写(Override)手类可以重写父类的方法,因此同样的方法会在父类与干类中有着不同的衣现形式。在JaVa语言中,基类的引用变量不仅可以指向基类的实例对象,也可以指向其子类的实例对象。同样,接口的引用变量也可以指向其实现类的实例对象。而程序调用的方法在运行期才动态绑定(绑定指的是将一个方法调用和一个方法主体连接到一起),就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。通过这种动态绑定的方法实现了多态。由于只有在运行时才能确定调用哪个方法,因此通过方法重写实现的多态也可以被称为运行时多态。如下例所示:classBase(ublicBase()(g():)publicvoidfOSystem,out.printIn(*Basef()”);)publicvoidg()System.out.printin("Baseg()”);IIclassDerivedextendsBase(publicvoidfOSystem,out.PrintIn("DerivedfO");)publicvoidg()(System.out.PrintIn("Derivedg()”);IpublicclassTest(publicstaticvoidmain(Stringargs)(Baseb=newDerivedO;b.f0;b.g();)程序的输出结果为:Derivedg()Derivedf()Derivedg()上例中,由于子类Derived的f()方法和g()方法与父类Base的方法同名,因此Derived的方法会覆益Base的方法。在执行Baseb=newDeriVedo语句的时候,会调用BaSe类的构造函数,而在BaSe的构造函数中,执行了g()方法,由于JaVa语言的多态特性,此时会调用子类DeriVed的g()方法,而非父类BaSe的g。方法,因此会输出DeriVedg()。由于实际创建的是DeriVed类的对象,后面的方法调用都会调用子类DeriVed的方法。此外,只有类中的方法才有多态的概念,类中成员变量没有多态的概念。如下例所示:classBase(publicinti=l;)classDerivedextendsBase(publicinti=2:)publicclassTestpublicstaticvoidmain(Stringargs)Baseb=newDerivedO:System.out.println(b.i);)程序输出结果为:1由此可见,成员变量是无法实现多态的,成员变量的值取父类还是子类并不取决于创建对象的类型,而是取决于定义的变量的类型。这是在编译期间确定的。在上例中,由于b所属的类型为Base,b.i指的是BaSe类中定义的i,所以程序输出结果为1.14. 什么是构造方法?正确答案:构造方法是一种特殊的方法,用来在对象实例化时初始化对象的成员变量。在JaVa语言中,构造方法具有以下特点。1)构造方法必须与类的名字相同,并且不能有返回值(返回值也不能为void)02)每个类可以有多个构造方法。当开发人员没有提供构造方法的时候,编译器在把源代码编译成字节码的过程中会提供一个没有参数默认的构造方法,但该构造方法不会执行任何代码。如果开发人员提供了构造方法,那么编译器就不会再创建默认的构方法数了。3)构造方法可以有0个、1个或1个以上的参数。4)构造方法总是伴随着new操作一起调用,不能由程序的编写者直接调用,必须要由系统调用。构造方法在对象实例化的时候会被H动调用,且只运行一次,而普通的方法是在程序执行到它的时候被调用的,可以被该对象调用多次。05)构造方法的主要作用是完成时象的初始化工作。6)构造方法不能被继承,因此就不能被重写(OVerride),但是构造方法能够被重载,可以使用不同的参数个数或参数类型来定义多个构造方法。7)子类可以通过SUPer关键字来显式地调用父类的构造方法,当父类没有提供无参数的构造方法时,子类的构造方法中必须显示地调用父类的构造方法,如果父类中提供了无参数的构造方法,此时子类的构造方法就可以不显式地调用父类的构造方法,在这种情况卜.编译器会默认调用父类的无参数的构造方法。当有父类时,在实例化对象时会首先执行父类的构造方法,然后才执行子类的构造方法。8)当父类和夕类都没有定义构造方法的时候,编译器会为父类生成一个默认的无参数的构造方法,给F类也生成个默认的无参数的构造方法。此外,默认构造器的修饰符只跟当前类的修饰符有关(例如:如果一个类被定义为public,那么它的构造方法也是public)»15. static与final结合使用表示什么意思?正确答案:StatiC常与final关键字结合使用,用来修饰成员变量与成员方法,有点类似于“全局常量”。对于变量,如果使用StatiCfinal修饰,则表示一旦赋值,就不可修改,并且通过类名可以访问。对于方法,如果使用StatiCfinal修饰,则表示方法不可覆盖,并且可以通过类名宜接访问。16. Java语言中是否存在goto关键字?正确答案:虽然got。作为JaVa的保留字,但目前没有在JaVa中使用。在C/C+中,goto常被用作跳出多重循环,在Java语言中,可以使用break和continue来达到同样的效果。那么既然gol。没有在Java语言中使用,为什么还要作为保留字呢?其中一个可能的原因就是这个关键字有可能会在将来被使用。如果现在不把got。作为保留字,开发人员就有可能用gol。作为变量名来使用。一旦有一天JaVa支持golo关键字了,这会导致以前的程序无法正常运行。因此把got。作为保留字是拈常有必要的。这里需要注意的是,在JaVa语言中,虽然没有.got。语句,但是却能使用标识符加冒号(:)的形式定义标签,如"mylabel:",其目的主要是为了在多重循环中方便使用break和continue而设计的。17. VOIatile有什么作用?正确答案:VoIatile的使用是为了线程安全,但Volatile不保证线程安全。线程安全有3个要素:可见性、有序性、原子性。线程安全是指在多线程情况下,对共享内存的使用,不会因为不同线程的访问和修改而发生不期望的情况。volatiIe有3个作用:I)VolaIilC用于解决多核CPU高速缓存导致的变量不同步。本质上这是个硬件问题,其根源在于:CPU的高速缓存的读取速度远远快于主存(物理内存)。所以,CPU在读取一个变量的时候,会把数据先读取到缓存,这样下次再访问同一个数据的时候就可以直接从缓存读取了,显著提高了读取的性能。而多核CPU有多个这样的缓存。这就带来了问题,当某个CPU(例如CPUI)修改了这个变量(例如把a的值从1修改为2),但是其他的CPU(例如CPU2)在修改前已经把a=l读取到Fl己的缓存了,当CPU2再次读取数据的时候,它仍然会去自己的缓存区中去读取,此时读取到的值仍然是1,但是实际上这个值已