大搜车面试

        上一个星期趁着秋招的尾声,胡乱投了几家公司(其实是错过了秋招,逼不得已...),也是截止目前收到唯一一家公司的通知(伤感)。
        直接说说这次的经历:
1、先是给了一套试卷做,很基础,只要基础稍微扎实点,基本能答好。
2、笔试通过后,会有一个面试官来面试,面试官看起来是30岁左右,我觉得应该是一个部门的开发主管,问的内容如下:
①为什么hashcode和equal要同时重写;
②有没有hashcode不等但是equal相等的情况,hashmap的原理;
③集合类里的fail-fast机制有没有了解过,说说看;
④子类隐式调用父类默认构造函数(父类中已定义的一个有参数的构造函数)的编译问题;
⑤forward(跳转)和sendRedirect(重定向)的区别,以及重定向时,浏览器发生了什么(根据我的想法是换个角度问从浏览器发起一个request到浏览器接收到一个response的整个流程时怎么样的);
⑥Java的多线程:volatile的作用是什么,sleep和wait的区别,notify和notifyAll的区别
⑦mysql中查询时like不走索引的情况,(其他不走索引的情况?)
⑧mysql的四大特性:原子性、隔离性、一致性、持久性。(因为匆匆忙忙的去面试,好久没有好好刷题,在数据库这块崩了,后面就没了)。
       总体感觉是挺简单的,难度不大,都是基础问题,但是因为好久没有好好准备(其实都是必须掌握的基础,都忘了。。。只是安慰自己找的借口),所以下午的时候就直接受到了拒绝邮件。借着第一次学写博客,记录一下自己的失败。然后最后整理一下这次面试的参考答案。

①为什么hashcode和equal要同时重写?
       首先回答这个问题之前,要搞清楚,hashcode和equal到底是干什么的。
       equal():是根自object类的方法,每个对象都有这个方法,如果没有重写此方法,默认调用的是object中的方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象),即比较的是栈中的值(一般的对象内容都是存放在堆中,栈存放的是这个对象的地址值,也就是我们口中常说的引用),但是String类中重写了该方法,使得同时比较了值的方法。
        hashcode():hashcode()其实也是根自object类的方法,返回的是一个对象的hash值,或者说是hash码。它的作用就是当这个对象在存储时散列存放,作为Key来识别该对象。我们可以这样幻想hash码:它是决定对象存放的物理位置(实际上可能不是)。
         eqauls方法和hashCode方法关系

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

(1)同一对象上多次调用hashCode()方法,总是返回相同的整型值。

(2)如果a.equals(b),则一定有a.hashCode() 一定等于 b.hashCode()。 

(3)如果!a.equals(b),则a.hashCode() 不一定等于 b.hashCode()。此时如果a.hashCode() 总是不等于 b.hashCode(),会提高hashtables的性能。

(4)a.hashCode()==b.hashCode() 则 a.equals(b)可真可假

(5)a.hashCode()!= b.hashCode() 则 a.equals(b)为假。

上面结论简记:

1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。 
2、如果两个对象不equals,他们的hashcode有可能相等。 
3、如果两个对象hashcode相等,他们不一定equals。 
4、如果两个对象hashcode不相等,他们一定不equals。 

关于这两个方法的重要规范: 

规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。 

规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。说的简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。
         为什么覆盖equals时总要覆盖hashCode
 一个很常见的错误根源在于没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap、HashSet和Hashtable。

1.在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。

2.如果两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。

3.如果两个对象根据equals()方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生相同的整数结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能。

③集合类里的fail-fast机制有没有了解过,说说看;

这个是之前根本没有接触过,当时问的时候是一脸懵的,所以一回来马上开始百度。。。

好了,开始上百度了:

       在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则可能会抛出Concurrent Modification Exception(是可能,不是一定,而且这个情况发生在多个线程修改的情况下)

       原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。

       注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。

       场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

       此时会有人会有个疑问,既然java.util包下的集合类都会有这个快速失败的机制,那么在高并发的情况下我们是不是必须要加同步锁(synchronize等)呢?

       加同步锁当然可以避免,但是这样我们的程序的效率就会变得很低。其实还有其他的方法,Java中还有一个机制叫安全失败(fail-safe)。有这种机制的集合容器在遍历时不是直接对原来的集合直接访问,而是先复制一份,在副本上面进行修改。

       原理:迭代器在遍历时不是直接访问集合中的内容,而是在遍历原集合的副本,所以在遍历的过程中不会检测到原集合的修改,所以不会报concurrentModificationException.

      场景:在java.concurrent包下的集合都是安全失败的,不会抛出这个异常。

 

④子类隐式调用父类默认构造函数(父类中已定义的一个有参数的构造函数)的编译问题;

比如:父类 

 public class Father{

    String str;

    public Father (String str){

          this.str=str;

     }

}

子类:

public class Child extends Father {

   public Child(){}

}

        此时在编译的时候就会报错,原因是:在创建子类的对象时,Java虚拟机首先执行父类的构造方法,然后再执行子类的构造方法。在多级继承的情况下,将从继承树的最上层的父类开始,依次执行各个类的构造方法,这可以保证子类对象从所有直接或间接父类中继承的实例变量都被正确地初始化。而且如果一个类中已经存在构造函数(无参或者有参),虚拟机都不会创建默认的构造函数。

在这段程序中,因为子类没有显式的调用父类的构造函数,即没有使用super(),此时在编译的时候,虚拟机就会默认的调用父类的构造函数,但是父类没有默认的构造函数,所以此时程序会报错。

总结:1、构造函数不能继承,只能调用。

           2、如果创建了构造函数,系统将不会帮创建默认的构造函数

           3、如果没有定义构造函数,那么系统将会创建一个默认的无参构造函数

⑤从浏览器发起一个request到浏览器接收到一个response的整个流程时怎么样的?

https://blog.csdn.net/xisuo002/article/details/79161609

https://www.cnblogs.com/echo-hui/p/9298203.html

感觉这两个博客结合起来就描述得很详细了

⑥mysql的四大特性:原子性、隔离性、一致性、持久性

原子性:在数据库中,事务包括的所有操作,要么全部成功,要么全部失败。

隔离性:一个事务不能被其他事务干扰,每个事务都是隔离开来的

一致性:数据库的状态只能是从一个一致性转化为另一个一致性的状态(体现完整性)

持久性:一个事务一旦提交,那么对数据的改变是永久性的,即使系统崩溃了,修改的数据也不会丢失

数据库的隔离级别,这个比较重要,我想放在下一篇博客详细讲。还有其他零零散散的问题(都根基础,如果忘了就等着失业吧!)就不在这里详细写了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值