博主总结面试题目终极之战——Java专栏——第一期(15题)

DBC 1.7K 0

一、在Java中,HashMap中是用哪些方法来解决哈希冲突的?

  • 解决哈希冲突常用的两种方法是:开放定址法和链地址法
    •   开放定址法:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败。
    •   链地址法:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。
温馨提示

这里要小心,有时候题目会出一个干扰项:开放地址法,这个在一些答案中是不对的,为了保险起见,统一为开放定址法![aru_13]

二、假设有以下代码String s = "hello";String t = "hello";char c [ ] = {'h','e','l','l','o'};下列选项中返回false的语句是?

s.equals (t);

t.equals (c);

s==t;

t.equals (new String ("hello"));

温馨提示
  • 首先==与equals是有明显区别的。
    • ==强调栈中的比较,可以理解为地址比较
    • equals强调对象的内容比较
      • String s=“hello”;会在栈中生成hello字符串,并存入字符串常量池中。
      • String t=“hello” ;创建时,会在字符串常量池中寻找,当找到需要的hello时,不进行字符串的创建,引用已有的。 所以,s==t返回true,s.equals(t)也是true。
      • char c[]={'h','e','l','l','o'}; c==s这个是不存在的,==两边类型不同
      • t.equals(c)这个语句在anObject instanceof String这步判断不会通过,也就是cha[] 压根不能与String相比较,类型不是相同的。返回false

三、线程开启相关题目,如下图

以下程序的运行结果是?

博主总结面试题目终极之战——Java专栏——第一期(15题)插图

温馨提示

答案为:foobar

  • 这里要仔细,线程开启是用的start,run和普通方法的调用没有什么区别。
    • 调用start()后,线程会被放到等待队列,等待CPU调度,并不一定要马上开始执行,只是将这个线程置于可动行状态。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体。
      • 1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码
      • 2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码, 这样就没有达到写线程的目的。

四、下面哪些类实现或者继承了Collection接口?

博主总结面试题目终极之战——Java专栏——第一期(15题)插图2

五、下面的switch语句中,x可以是哪些类型的数据:()

switch(x)
{
default:
System.out.println("Hello");
}
温馨提示
  • 以java8为准,switch支持10种类型 基本类型:byte char short int 对于包装类 :Byte,Short,Character,Integer String enum
  • 实际只支持int类型 Java实际只能支持int类型的switch语句,那其他的类型时如何支持的
    • 基本类型byte char short 原因:
      • 这些基本数字类型可自动向上转为int, 实际还是用的int
    • 基本类型包装类Byte,Short,Character,Integer 原因:
      • java的自动拆箱机制 可看这些对象自动转为基本类型
    • String 类型 原因:
      • 实际switch比较的string.hashCode值,它是一个int类型 如何实现的,网上例子很多。此处不表。
    • enum类型 原因 :
      • 实际比较的是enumordinal值(表示枚举值的顺序),它也是一个int类型 所以也可以说 switch语句只支持int类型

六、在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的()?

温馨提示
  • 对于管道,有下面这几种类型:
    • ①普通管道(PIPE):通常有两种限制,一是单工,即只能单向传输;二是血缘,即常用于父子进程间(或有血缘关系的进程间)。
    • ②流管道(s_pipe):去除了上述的第一种限制,实现了双向传输。
    • ③命名管道(name_pipe):去除了上述的第二种限制,实现了无血缘关系的不同进程间通信。
  • 显然,要求是对于不同的服务器之间的通信,是要要求全双工形式的,而管道只能是半双工,虽然可以双向,但是同一时间只能有一个方向传输,全双工和半双工的区别可以如下图示理解:
  • 博主总结面试题目终极之战——Java专栏——第一期(15题)插图4

七、mysql数据库,game_order表表结构如下,下面哪些sql能使用到索引()?

博主总结面试题目终极之战——Java专栏——第一期(15题)插图6

select * from game_order where plat_game_id=5 and plat_id=134

select * from game_order where plat_id=134 and plat_game_id=5 and plat_order_id=’100’

select * from game_order where plat_order_id=’100’

select * from game_order where plat_game_id=5 and plat_order_id=’100’ and plat_id=134

select * from game_order where plat_game_id=5 and plat_order_id=’100’

温馨提示
  • 这道题目想考察的知识点是MySQL组合索引(复合索引)的最左优先原则。最左优先就是说组合索引的第一个字段必须出现在查询组句中,这个索引才会被用到。只要组合索引最左边第一个字段出现在Where中,那么不管后面的字段出现与否或者出现顺序如何,MySQL引擎都会自动调用索引来优化查询效率。
  • 根据最左匹配原则可以知道B-Tree建立索引的过程,比如假设有一个3列索引(col1,col2,col3),那么MySQL只会会建立三个索引(col1),(col1,col2),(col1,col2,col3)。
  • 所以题目会创建三个索引(plat_order_id)、(plat_order_idplat_game_id的组合索引)、(plat_order_idplat_game_idplat_id的组合索引)。根据最左匹配原则,where语句必须要有plat_order_id才能调用索引(如果没有plat_order_id字段那么一个索引也调用不到),如果同时出现plat_order_idplat_game_id则会调用两者的组合索引,如果同时出现三者则调用三者的组合索引。
  • 题目问有哪些sql能使用到索引,个人认为只要Where后出现了plat_order_id字段的SQL语句都会调用到索引,只不过是所调用的索引不同而已,所以选BCDE。如果题目说清楚是调用到三个字段的复合索引,那答案才是BD。

八、下面哪些描述是正确的:( )

public class Test {
    public static class A {
        private B ref;
        public void setB(B b) {
            ref = b;
        }
    }
    public static Class B {
        private A ref;
        public void setA(A a) {
            ref = a;
        }
    }
    public static void main(String args[]) {
    …
        start();
    ….
    }
    public static void start() { A a = new A();
        B b = new B();
        a.setB(b);
        b = null; //
        a = null;
    …
    }
}

	

b = null执行后b可以被垃圾回收

a = null执行后b可以被垃圾回收

a = null执行后a可以被垃圾回收

a,b必须在整个程序结束后才能被垃圾回收

类A和类B在设计上有循环引用,会导致内存泄露

a, b 必须在start方法执行完毕才能被垃圾回收

博主总结面试题目终极之战——Java专栏——第一期(15题)插图8

九、下面这条语句一共创建了多少个对象:String s="welcome"+"to"+360;

String test="javaandpython"; 
String str1="java"; 
String str2="and"; 
String str3="python"; 
System. out. println(test=="java"+"and"+"python"): 
System. out. println(test ==str1 + str2 + str3);
温馨提示
  • 对于上面这段代码,结果是true false
    • 这是因为字符串字面量拼接操作是在Java编译器编译期间就执行了,也就是说编译器编译时,直接把"java"、"and"和"python"这三个字面量进行"+"操作得到一个"javaandpython" 常量,并且直接将这个常量放入字符串池中,这样做实际上是一种优化,将3个字面量合成一个,避免了创建多余的字符串对象(只有一个对象"javaandpython",在字符串常量池中)。而字符串引用的"+"运算是在Java运行期间执行的,即str1 + str2 + str3在程序执行期间才会进行计算,它会在堆内存中重新创建一个拼接后的字符串对象。且在字符串常量池中也会有str1,str2与str3,这里创建多少个新的对象与原来字符串常量池中有没有str1\str2\str3有关,如果之前存在就不会创建新的对象。
  • 总结来说就是:字面量"+"拼接是在编译期间进行的,拼接后的字符串存放在字符串池中;而字符串引用的"+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
那么再来看这题,很明显只在编译期间在字符串常量池中创建了"welcometo360"一个字符串

十、下列代码片段中,存在编译错误的语句是()

byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2);  /*语句1*/
b6=b4+b5;    /*语句2*/
b8=(b1+b4);  /*语句3*/
b7=(b2+b5);  /*语句4*/
System.out.println(b3+b6);
温馨提示
  • Java表达式转型规则由低到高转换
    • 1、所有的byte,short,char型的值将被提升为int型;
    • 2、如果有一个操作数是long型,计算结果是long型;
    • 3、如果有一个操作数是float型,计算结果是float型;
    • 4、如果有一个操作数是double型,计算结果是double型;
    • 5、被fianl修饰的变量不会自动改变类型,当2个final修饰相操作时,结果会根据左边变量的类型而转化。
  • 解析
    • 语句1错误:b3=(b1+b2);自动转为int,所以正确写法为b3=(byte)(b1+b2);或者将b3定义为int;
    • 语句2正确:b6=b4+b5;b4、b5为final类型,不会自动提升,所以和的类型视左边变量类型而定,即b6可以是任意数值类型;
    • 语句3错误:b8=(b1+b4);虽然b4不会自动提升,但b1仍会自动提升,所以结果需要强转,b8=(byte)(b1+b4);
    • 语句4错误:b7=(b2+b5); 同上。同时注意b7是final修饰,即只可赋值一次,便不可再改变

十一、哪种调用是正确的

package cn.com.test;

public class EnclosingOne {
    public class InsideOne {}

}
package cn.com.cow;

import cn.com.test.EnclosingOne;
import cn.com.test.EnclosingOne.InsideOne;
public class InerTest
{
    public static void main(String[]args)
    {
        EnclosingOne eo = new EnclosingOne();
        //insert code here 
    }

}

InsideOne ei=eo.new InsideOne();

eo.InsideOne ei=eo.new InsideOne();

InsideOne ei=EnclosingOne.new InsideOne();

EnclosingOne.InsideOne ei=eo.new InsideOne();

温馨提示

对于A答案 主要在开头添加 import EnclosingOne.Insider这一句,不然的话A肯定是错误,其他类不能够直接引用内部类的
博主总结面试题目终极之战——Java专栏——第一期(15题)插图10

十二、@SuppressWarnings(“deprecation”)的功能是什么?

温馨提示

这里就不得不说三大注解了

  • Override 注解
    • 指明被注解的方法需要覆写超类中的方法.
    • 如果某个方法使用了该注解,却没有覆写超类中的方法(比如大小写写错了,或者参数错了,或者是子类自己定义的方法),编译器就会生成一个错误.
  • Deprecated 注解
    • 可以修饰类、方法、变量,在java源码中被@Deprecated修饰的类、方法、变量等表示不建议使用的,可能会出现错误的,可能以后会被删除的类、方法等,如果现在使用,则在以后使用了这些类、方法的程序在更新新的JDK、jar包等就会出错,不再提供支持。     个人程序中的类、方法、变量用@Deprecated修饰同样是不希望自己和别人在以后的时间再次使用此类、方法。  当编译器编译时遇到了使用@Deprecated修饰的类、方法、变量时会提示相应的警告信息。
  • Suppresswarnings 注解
    • 可以达到抑制编译器编译时产生警告的目的,但是很不建议使用@SuppressWarnings注解,使用此注解,编码人员看不到编译时编译器提示的相应的警告,不能选择更好、更新的类、方法或者不能编写更规范的编码。同时后期更新JDK、jar包等源码时,使用@SuppressWarnings注解的代码可能受新的JDK、jar包代码的支持,出现错误,仍然需要修改。
    • 抑制警告的关键字

十三、以下代码结果是什么?

public class foo {
    public static void main(String sgf[]) {

        StringBuffer a=new StringBuffer("A");

        StringBuffer b=new StringBuffer("B");

        operate(a,b);

        System.out.println(a+"."+b);
    }
    static void operate(StringBuffer x,StringBuffer y) {
        x.append(y);
        y=x;
    }
}

代码可以编译运行,输出“AB.AB”。

代码可以编译运行,输出“A.A”。

代码可以编译运行,输出“AB.B”。

代码可以编译运行,输出“A.B”。

温馨提示

不得不说,这一题是真的有意思,哈哈哈 [aru_7]
博主总结面试题目终极之战——Java专栏——第一期(15题)插图12

十四、以下程序的输出结果为

class Base{
    public Base(String s){
        System.out.print("B");
    }
}
public class Derived extends Base{
    public Derived (String s) {
        System.out.print("D");
    }
    public static void main(String[] args){
        new Derived("C");
    }
}

BD

DB

C

编译错误

温馨提示

子类构造方法在调用时必须先调用父类的,由于父类没有无参构造,必须在子类中显式调用,修改子类构造方法如下即可:

public Derived(String s){
		super("s");
		System.out.print("D");
	}

十五、关于访问权限说法正确 的是 ? ( )

外部类前面可以修饰public,protected和private

成员内部类前面可以修饰public,protected和private

局部内部类前面可以修饰public,protected和private

以上说法都不正确

温馨提示
private default protected public
同一个类中
同一个包中
子类中
全局范围内
  • 对于外部类而言,它也可以使用访问控制符修饰,但外部类只能有两种访问控制级别: public 和默认。因为外部类没有处于任何类的内部,也就没有其所在类的内部、所在类的子类两个范围,因此 private 和 protected 访问控制符对外部类没有意义。
  • [aru_19]
  • 内部类的上一级程序单元是外部类,它具有 4 个作用域:同一个类( private )、同一个包( protected )和任何位置( public )。
  • [aru_53]
  • 因为局部成员的作用域是所在方法,其他程序单元永远不可能访问另一个方法中的局部变量,所以所有的局部成员都不能使用访问控制修饰符修饰。

发表评论 取消回复
表情 图片 链接 代码

分享