【面试】一篇文章帮你彻底清楚"java"必考面试题

简介: 【面试】一篇文章帮你彻底清楚"java"必考面试题

基础部分(上)

◆ ◆ ◆  ◆ ◆

1. JAVA的基本数据类型有哪些 ? String 是不是基本数据类型 ?

   Java 有 8 种基本数据类型: byte int short long double float Boolean char byte int short long 都属于整数类型. Double float 属于浮点类型. Boolean 为布尔类型 Char 为字符型 String 不是基本数据类型.它定义的为对象

◆ ◆ ◆  ◆ ◆

2. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

可以有多个类,但只能有一个 public 的类,并且 public 的类名必须与文件名相一致。

◆ ◆ ◆  ◆ ◆

3. Java 有没有 goto?

 java 中的保留字,现在没有在 java 中使用。

◆ ◆ ◆  ◆ ◆

4. 说说&和&&的区别.

     &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都 为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。&&还具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式,例如,对 于 if(str !=null &&!str.equals(“”))表达式,当 str 为 null 时,后面的表达式不会执行,所以不 会出现 NullPointerException 如果将&&改为&,则会抛出 NullPointerException 异常。If(x==33 &++y>0)y 会增长,If(x==33&&++y>0)不会增长 &还可以用作位运算符,当&操作符两边的表达式不是 boolean 类型时,&表示按位与操作, 我们通常使用 0x0f 来与一个整数进行&运算,来获取该整数的最低 4 个 bit 位,例如,0x31 &0x0f 的结果为 0x01。备注:这道题先说两者的共同点,再说出&&和&的特殊之处,并列举一些经典的例子来表 明自己理解透彻深入、实际经验丰富。

◆ ◆ ◆  ◆ ◆

5. 在 JAVA中如何跳出当前的多重嵌套循环?

在 Java 中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环 体的代码中使用带有标号的 break 语句,即可跳出外层循环。

例如, ok:

 

 for(inti=0;i<10;i++){
                for(intj=0;j<10;j++){
                    System.out.println(“i=”+i+“,j=”+ j);
                    if(j ==5)breakok;
        }
}

另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里 层循环体代码的控制,例如,要在二维数组中查找到某个数字。


intarr[][] ={{1,2,3},{4,5,6,7},{9}};
booleanfound=false;
         for(inti=0;i<arr.length&&!found;i++){
         for(intj=0;j<arr[i].length;j++){
         System.out.print("i=" + i + "j=" + j );
         if()arr[i][j] == 5){
         found = true;
         break;
        }
}

◆ ◆ ◆  ◆ ◆

6. switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

   在 switch(expr1)中,expr1 只能是一个整数表达式或者枚举常量(更大字体),整数表达 式可以是 int 基本类型或 Integer 包装类型,由于,byte,short,char 都可以隐含转换为 int,所 以,这些类型以及这些类型的包装类型也是可以的。显然, long 和 String 类型都不符合 switch 的语法规定,并且不能被隐式转换成 int 类型,所以,它们不能作用于 swtich 语句中。

◆ ◆ ◆  ◆ ◆

7. shorts1=1;s1=s1+1;有什么错?shorts1=1;s1+=1;有什么错?

对于 shorts1=1;s1= s1+ 1; 由于 s1+1运算时会自动提升表达式的类型,所以结果是 int型, 再赋值给 short 类型 s1 时,编译器将报告需要强制转换类型的错误。对于 shorts1=1;s1+= 1;由于 += 是 java 语言规定的运算符, java 编译器会对它进行特殊处 理,因此可以正确编译。

◆ ◆ ◆  ◆ ◆

8. char 型变量中能不能存贮一个中文汉字?为什么?

   char 型变量是用来存储 Unicode 编码的字符的,unicode 编码字符集中包含了汉字,所以, char 型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在 unicode 编码 字符集中,那么,这个 char 型变量中就不能存储这个特殊汉字。补充说明:unicode 编码占 用两个字节,所以,char 类型的变量也是占用两个字节。

027bbca2b822e62cd5318ec51ce90d59.jpg 

9. 用最有效率的方法算出 2 乘以 8 等於几?

   2<< 3, 因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左移 3 位即可,而位运算 cpu 直接支持的,效率最高,所以, 2 乘以 8 等於几的最效率的方法是 2<< 3。

10. 请设计一个一百亿的计算器

   首先要明白这道题目的考查点是什么,一是大家首先要对计算机原理的底层细节要清楚、要 知道加减法的位运算原理和知道计算机中的算术运算会发生越界的情况,二是要具备一定的 面向对象的设计思想。

   首先,计算机中用固定数量的几个字节来存储的数值,所以计算机中能够表示的数值是有一 定的范围的,为了便于讲解和理解,我们先以 byte 类型的整数为例,它用 1 个字节进行存 储,表示的最大数值范围为-128 到+127。-1 在内存中对应的二进制数据为 11111111,如果 两个-1 相加,不考虑 Java 运算时的类型提升,运算后会产生进位,二进制结果为 1,11111110, 由于进位后超过了 byte 类型的存储空间,所以进位部分被舍弃,即最终的结果为 11111110, 也就是-2,这正好利用溢位的方式实现了负数的运算。-128 在内存中对应的二进制数据为 10000000,如果两个-128 相加,不考虑 Java 运算时的类型提升,运算后会产生进位,二进 制结果为 1,00000000,由于进位后超过了 byte 类型的存储空间,所以进位部分被舍弃,即 最终的结果为 00000000,也就是 0,这样的结果显然不是我们期望的,这说明计算机中的算术运算是会发生越界情况的,两个数值的运算结果不能超过计算机中的该类型的数值范围。 由于 Java 中涉及表达式运算时的类型自动提升,我们无法用 byte 类型来做演示这种问题和 现象的实验,大家可以用下面一个使用整数做实验的例子程序体验一下:

inta=Integer.MAX_VALUE; 
intb=Integer.MAX_VALUE; 
intsum=a+b; 
System.out.println(“a=”+a+”,b=”+b+”,sum=”+sum);

   先不考虑 long 类型,由于 int 的正数范围为 2 的 31 次方,表示的最大数值约等于 2*1000*1000*1000,也就是 20 亿的大小,所以,要实现一个一百亿的计算器,我们得自己 设计一个类可以用于表示很大的整数,并且提供了与另外一个整数进行加减乘除的功能,大 概功能如下:

   (1)这个类内部有两个成员变量,一个表示符号,另一个用字节数组表示数值的二进制数 。

   (2)有一个构造方法,把一个包含有多位数值的字符串转换到内部的符号和字节数组中 。

   (3)提供加减乘除的功能 。

publicclassBigInteger{ 
    intsign; byte[]val; 
    publicBiginteger(String val){ 
    sign= ; 
    val =;
 }
publicBigIntegeradd(BigInteger other){ 
} 
publicBigIntegersubtract(BigInteger other){
 } 
publicBigIntegermultiply(BigInteger other){ 
} 
publicBigIntegerdivide(BigInteger other){ 
} 
}

    备注:要想写出这个类的完整代码,是非常复杂的,如果有兴趣的话,可以参看 jdk 中自带 的 java.math.BigInteger 类的源码。面试的人也知道谁都不可能在短时间内写出这个类的完整 代码的,他要的是你是否有这方面的概念和意识,他最重要的还是考查你的能力,所以,你 不要因为自己无法写出完整的最终结果就放弃答这道题,你要做的就是你比别人写得多,证 明你比别人强,你有这方面的思想意识就可以了,毕竟别人可能连题目的意思都看不懂,什 么都没写,你要敢于答这道题,即使只答了一部分,那也与那些什么都不懂的人区别出来, 拉开了距离,算是矮子中的高个,机会当然就属于你了。另外,答案中的框架代码也很重要, 体现了一些面向对象设计的功底,特别是其中的方法命名很专业,用的英文单词很精准,这 也是能力、经验、专业性、英语水平等多个方面的体现,会给人留下很好的印象,在编程能 力和其他方面条件差不多的情况下,英语好除了可以使你获得更多机会外,薪水可以高出一 千元。11. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。例如,对于如下语句:


finalStringBuffera=newStringBuffer("immutable");

执行如下语句将报告编译期错误:


a=newStringBuffer("");

但是,执行如下语句则可以通过编译:


a.append("broken!");

有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:


publicvoid method(final StringBuffer param){}

实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:


param.append("a");

12. "=="和 equals 方法究竟有什么区别?

==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存 储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作 符。

如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块 内存(堆内存),变量也占用一块内存,例如 Objet obj=newObject();变量 obj 是一个内存, newObject()是另一个内存,此时,变量 obj 所对应的内存中存储的数值就是对象占用的那块 内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要 看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。 equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相 同,它比较的两个对象是独立的。例如,对于下面的代码:


Stringb=newString("foo");
Stringb=newString("foo");


      两条 new 语句创建了两个对象,然后用 a,b 这两个变量分别指向了其中一个对象,这是两个 不同的对象,它们的首地址是不同的,即 a 和 b 中存储的数值是不相同的,所以,表达式 a==b 将返回 false,而这两个对象中的内容是相同的,所以,表达式 a.equals(b)将返回 true。 在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上 找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都 是使用 equals 方法。 如果一个类没有自己定义 equals 方法,那么它将继承 Object 类的 equals 方法,Object 类的 equals 方法的实现代码如下:


booleanequals(Objecto){ returnthis==o; }

这说明,如果一个类没有自己定义 equals 方法,它默认的 equals 方法(从 Object 类继承的) 就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用 equals 和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回 false。如果你编写的 类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖 equals 方法,由 你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。


13. 静态变量和实例变量的区别?

语法定义上的区别:静态变量前要加 static 关键字,而实例变量前则不加。

程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量 才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所 以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分 配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来 使用,静态变量则可以直接使用类名来引用。例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个 staticVar 变量,并 且每创建一个实例对象,这个 staticVar 就会加 1;但是,每创建一个实例对象,就会分配一 个 instanceVar,即可能分配多个 instanceVar,并且每个 instanceVar 的值都只自加了 1 次。


publicclassVariantTest{ 
publicstatic intstaticVar=0; 
publicint instanceVar=0; 
publicVariantTest(){ 
    staticVar++; 
    instanceVar++; 
    System.out.println(“staticVar=”+ staticVar+”,instanceVar=”+instanceVar); 
  } 
}

备注:这个解答除了说清楚两者的区别外,最后还用一个具体的应用例子来说明两者的差异, 体现了自己有很好的解说问题和设计案例的能力,思维敏捷,超过一般程序员,有写作能力!

14. 是否可从一个 static 方法内发出对非 static 方法的调用?

不可以。因为非 static 方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对 象上进行方法调用,而 static 方法调用时不需要创建对象,可以直接调用。也就是说,当一 个 static 方法被调用时,可能还没有创建任何实例对象,如果从一个 static 方法中发出对非 static 方法的调用,那个非 static 方法是关联到哪个对象上的呢?这个逻辑无法成立,所以, 一个 static 方法内部发出对非 static 方法的调用。


java进阶之路

15. Integer 与 int 的区别

int 是 java 提供的 8 种原始数据类型之一。Java 为每个原始类型提供了封装类, Integer 是 java 为 int 提供的封装类。int 的默认值为 0,而 Integer 的默认值为 null,即 Integer 可以区分出 未赋值和值为 0 的区别,int 则无法表达出未赋值的情况,例如,要想表达出没有参加考试 和考试成绩为 0 的区别,则只能使用 Integer。在 JSP 开发中,Integer 的默认为 null,所以用 el 表达式在文本框中显示时,值为空白字符串,而 int 默认的默认值为 0,所以用 el 表达式 在文本框中显示时,结果为 0,所以,int 不适合作为 web 层的表单数据的类型。在 Hibernate 中,如果将 OID 定义为 Integer 类型,那么 Hibernate 就可以根据其值是否为 null 而判断一个对象是否是临时的,如果将 OID 定义为了 int 类型,还需要在 hbm 映射文件中 设置其 unsaved-value 属性为 0。另外,Integer 提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer 中还定义了表示整数的最大值和最小值的常量。


16. 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.ceil(11.6)的结果为 11,Math.ceil(-11.6)的结果是-12;最难掌握的是 round 方法,它表示“四舍五入”,算法为 Math.floor(x+0.5),即将原来的数字加上 0.5 后再向下取整,所以, Math.round(11.5)的结果为 12,Math.round(-11.5)的结果为-11。

 

17. 下面的代码有什么不妥之处?


if(username.equals(“zxx”){}


int x=1; returnx==1?true:false;


18. 请说出作用域 public,private,protected,以及不写时的区别说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly。        作用域 当前类 同一 package 子孙类 其他 package

public √         √               √                              √

protected √    √              √                               ×

friendly √        √              ×                               ×

private √         ×              ×                               ×

备注:只要记住了有 4 种访问权限,4 个访问范围,然后将全选和范围在水平和垂直方向上 分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。


19. Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值的类型?

Overload 是重载的意思,Override 是覆盖的意思,也就是重写。

重载 Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相 同(即参数个数或类型不同)。

重写 Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类 创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个 完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法 时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决 父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能 更小。如果父类的方法是 private 类型,那么,子类则不存在覆盖的限制,相当于子类中增 加了一个全新的方法。

至于 Overloaded 的方法是否可以改变返回值的类型这个问题,要看你到底想问什么呢?这 个题目很模糊。如果几个 Overloaded 的方法的参数列表不一样,它们的返回者类型当然也 可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它 们的返回值不同来实现重载 Overload。这是不行的,我们可以用反证法来说明这个问题,因 为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如, 我们调用 map.remove(key)方法时,虽然 remove 方法有返回值,但是我们通常都不会定义接 收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回 类型不同, java 就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型 来判断。

override 可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达 到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法 进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外, 我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:

1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;

3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;4、被覆盖的方法不能为 private,否则在其子类中只是新定义了一个方法,并没有对其进行 覆盖。

overload 对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的 方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM 就会根据不同的参数 样式,来选择合适的方法执行。在使用重载要注意以下的几点:

1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不 同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是 fun(int,float), 但是不能为 fun(int,int));

2、不能通过访问权限、返回类型、抛出的异常进行重载;

3、方法的异常类型和数目不会对重载造成影响;

4、对于继承来说,如果某一方法在父类中是访问权限是 priavte,那么就不能在子类对其进 行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。

20. 同学贡献的一些题?

1.搞了多个重载方法,参数分别是 int ,char,和 double,然后将 doublex= 2,传递进去,会选 择哪个方法?

2.说说对 javaee 中的 session 的理解,你是怎么用 session 的?cvs/svn 下载

3.jdk 中哪些类是不能继承的:System,String,StringBuffer 等。

4.在 eclipse 中调试时,怎样查看一个变量的值。

5.判断身份证:要么是 15 位,要么是 18 位,最后一位可以为字母,并写程序提出其中的年 月日。

6.一个房子里有椅子,椅子有腿和背,房子与椅子是什么关系,椅子与腿和背是什么关系?

7.如果房子有多个椅子,就是聚合关系,否则是一种关联关系,当然,聚合是一种特殊的关 联。椅子与腿和背时组合关系。

8.说说 hasa 与 isa 的区别。

9.工厂模式的类图 。


21. 线程如何同步和通讯?

同学回答说 synchronized 方法或代码块!面试官似乎不太满意!只有多个 synchronized 代码块使用的是同一个监视器对象,这些 synchronized 代码块之间才 具有线程互斥的效果,假如 a 代码块用 obj1 作为监视器对象,假如 b 代码块用 obj2 作为监 视器对象,那么,两个并发的线程可以同时分别进入这两个代码块中。…这里还可以分析 一下同步的原理。对于同步方法的分析,所用的同步监视器对象是 this 接着对于静态同步方法的分析,所用的同步监视器对象是该类的 Class 对象 接着对如何实现代码块与方法的同步进行分析。


22. ClassLoader 如何加载 class ?

jvm 里有多个类加载,每个类加载可以负责加载特定位置的类,例如,bootstrap 类加载负责 加载 jre/lib/rt.jar 中的类, 我们平时用的 jdk 中的类都位于 rt.jar 中。extclassloader 负责加载 jar/lib/ext/*.jar 中的类, appclassloader 负责 classpath 指定的目录或 jar 中的类。除了 bootstrap 之外,其他的类加载器本身也都是 java 类,它们的父类是 ClassLoader。

 

23. Servlet 的生命周期?

Servlet 被服务器实例化后,容器运行其 init 方法,请求到达时运行其 service 方法,service方法自动派遣运行与请求对应的 doXXX 方法(doGet,doPost)等,当服务器决定将实例销 毁的时候调用其 destroy 方法。与 cgi 的区别在于 servlet 处于服务器进程中,它通过多线程方式运行其 service 方法,一个 实例可以服务于多个请求,并且其实例一般不会销毁,而 CGI 对每个请求都产生新的进程, 服务完成后就销毁,所以效率上低于 servlet。


24. 抽象类的作用?

25. ArrayList 如何实现插入的数据按自定义的方式有序存放?


classMyBeanimplementsComparable{ 
publicint compareTo(Objectobj){ 
if(!objinstanceofMyBean) thrownewClassCastException()
//具体异常的名称,我要查 jdk 文档。
MyBeanother=(MyBean)obj; 
returnage >other.age?1:age== other.age?0:-1; 
  } 
} 
classMyTreeSet{ 
privateArrayList datas=newArrayList(); 
publicvoid add(Objectobj){ 
for(inti=0;i<datas.size();i++){ 
if(obj.compareTo(datas.get(i)!= 1){ 
datas.add(i,obj); 
        } 
      } 
    }
}

26. 分层设计的好处?

把各个功能按调用流程进行了模块化,模块化带来的好处就是可以随意组合,举例说明:如 果要注册一个用户,流程为显示界面并通过界面接收用户的输入,接着进行业务逻辑处理, 在处理业务逻辑又访问数据库,如果我们将这些步骤全部按流水帐的方式放在一个方法中编 写,这也是可以的,但这其中的坏处就是,当界面要修改时,由于代码全在一个方法内,可 能会碰坏业务逻辑和数据库访问的码,同样,当修改业务逻辑或数据库访问的代码时,也会 碰坏其他部分的代码。分层就是要把界面部分、业务逻辑部分、数据库访问部分的代码放在 各自独立的方法或类中编写,这样就不会出现牵一发而动全身的问题了。这样分层后,还可 以方便切换各层,譬如原来的界面是 Swing,现在要改成 BS 界面,如果最初是按分层设计 的,这时候不需要涉及业务和数据访问的代码,只需编写一条 web 界面就可以了。 下面的仅供参考,不建议照搬照套,一定要改成自己的语言,发现内心的感受: 分层的好处:

1.实现了软件之间的解耦;

2.便于进行分工;

3.便于维护;

4.提高软件组件的重 用;

5.便于替换某种产品,比如持久层用的是 hibernate,需要更换产品用 toplink,就不用其他 业务代码,直接把配置一改;

6.便于产品功能的扩展;

7.便于适用用户需求的不断变化 。


休息一下,消化消化,精彩继续呈现。


27. 序列化接口的 id 有什么用?

对象经常要通过 IO 进行传送,让你写程序传递对象,你会怎么做?把对象的状态数据用某 种格式写入到硬盘,Person->“zxx,male,28,30000”Person,既然大家都要这么干,并且没有个统一的干法,于是,sun 公司就提出一种统一的解决方案,它会把对象变成某个格式进 行输入和输出,这种格式对程序员来说是透明(transparent)的,但是,我们的某个类要想 能被 sun 的这种方案处理,必须实现 Serializable 接口。


ObjectOutputStream.writeObject(obj); 
Objectobj=ObjectInputStream.readObject();


假设两年前我保存了某个类的一个对象,这两年来,我修改该类,删除了某个属性和增加了 另外一个属性,两年后,我又去读取那个保存的对象,或有什么结果?未知!sun 的 jdk 就 会蒙了。为此,一个解决办法就是在类中增加版本后,每一次类的属性修改,都应该把版本 号升级一下,这样,在读取时,比较存储对象时的版本号与当前类的版本号,如果不一致, 则直接报版本号不同的错!


28. StringBuffer 与 StringBuilder 的区别?

因为 StringBuildersbuilder=;是线程不安全的,运行效率高,如果一个字符串变量是在方法 里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用 StringBuilder。 如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用 StringBuffer。


29. hashCode 方法的作用?

首先,想要明白 hashCode 的作用,你必须要先知道 Java 中的集合。

总的来说,Java 中的集合(Collection)有两类,一类是 List,再有一类是 Set。你知道 它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重 复。那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该 依据什么来判断呢?这就是 Object.equals 方法了。但是,如果每增加一个元素就检查一次, 那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中 现在已经有 1000 个元素,那么第 1001 个元素加入集合时,它就要调用 1000 次 equals 方法。 这显然会大大降低效率。于是,Java 采用了哈希表的原理。可以简单理解,hashCode 方法 实际上返回的就是对象存储的物理地址(实际可能并不是)。这样一来,当集合要添加新的 元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的物理位置上。 如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果 这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了, 不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用 equals 方法的次数就大大降低了,几乎只需要一两次。

所以,Java 对于 eqauls 方法和 hashCode 方法是这样规定的:

1、如果两个对象相同,那么它们的 hashCode 值一定要相同;

2、如果两个对象的 hashCode 相同,它们并不一定相同 上面说的对象相同指的是用 eqauls 方法比较。 你当然可以不按要求去做了,但你会发现,相同的对象可以出现在 Set 集合中。同时,增 加新元素的效率会大大下降。

96753ebae4eaf16d8952a919f67dd509.jpg

30. webservice 问得很多

31. 设计出计算任意正整数的阶层?

32. 在 oracle 数据库中需要查询出前 8 条记录的 sql 语句怎么写?

目录
相关文章
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
12天前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第17天】本文详细介绍了Java编程中Map的使用,涵盖Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的并发处理和性能优化技巧,适合初学者和进阶者学习。
30 3
|
2月前
|
存储 负载均衡 Java
Elasticsearch集群面试系列文章一
【9月更文挑战第9天】Elasticsearch(简称ES)是一种基于Lucene构建的分布式搜索和分析引擎,广泛用于全文搜索、结构化搜索、分析以及日志实时分析等场景。
94 7
|
10天前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
35 4
|
26天前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
59 2
|
30天前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
26 0
|
3月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
3月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
183 0
|
3月前
|
Java 编译器 开发工具
JDK vs JRE:面试大揭秘,一文让你彻底解锁Java开发和运行的秘密!
【8月更文挑战第24天】JDK(Java Development Kit)与JRE(Java Runtime Environment)是Java环境中两个核心概念。JDK作为开发工具包,不仅包含JRE,还提供编译器等开发工具,支持Java程序的开发与编译;而JRE仅包含运行Java程序所需的组件如JVM和核心类库。一个简单的&quot;Hello, World!&quot;示例展示了两者用途:需借助JDK编译程序,再利用JRE或JDK中的运行环境执行。因此,开发者应基于实际需求选择安装JDK或JRE。
51 0
|
3月前
|
算法 Java
【多线程面试题十八】、说一说Java中乐观锁和悲观锁的区别
这篇文章讨论了Java中的乐观锁和悲观锁的区别,其中悲观锁假设最坏情况并在访问数据时上锁,如通过`synchronized`或`Lock`接口实现;而乐观锁则在更新数据时检查是否被其他线程修改,适用于多读场景,并常通过CAS操作实现,如Java并发包`java.util.concurrent`中的类。