感谢小明同学友情提供面试分享,今天我们一起对面试进行点评一下
首先进行了自我介绍,几乎每次面试的时候都会进行自我介绍,面试的小伙伴也可以提前准备一下。主要从几个方面介绍自己:
- 教育经历
- 工作经历,任职的公司,负责的项目,担任的职责
- 自己的技术栈 (最好能包含技术点,对于技术人员特别敏感的词,引导面试官发问)
问题一 :介绍下感觉比较有成就感的项目
回答:
首先介绍了下项目背景(很明显,面试官并不感兴趣)然后直接让介绍在这个项目中最有成就感的三点
- 压力很大的情况下完成了任务(感觉没啥实质的好处)
- 做了相关的辅助工具(感觉不是面试官关注的东西)
- 配置了完善的策略保证上线的安全
面试官没有很好的反馈(这三点确实没有突出的地方,实在不应该这么总结,应该把性能,框架改造,和解决的难题说一下)
点评:
首先这个问题对于社招是所有的面试中必问,也是最重要的一个环节。答好了就会对面试起到好的效果,答的不好差不多有30%的概率在面试官那已经有了定论。所以这个环节在面试之前一定要好好的准备。小明同学的回答很明显是没有准备的。提到的三点几乎完全和技术不挂钩。面试官更想听到的是难点-解决-亮点-技术词汇。任何一个点出现,面试官都可以深入询问来了解面试者的情况。小茗同学在这个问题上相当于把天聊死了。
可能会有很多人说工作天天写业务也有什么亮点,这里我统一回复一下:为什么别人的项目有亮点你没有?和项目无关,关键是人自己,不要让自己的工作现状成为自己不思考不总结的借口。
问题二:Object的方法有哪些
回答:
hashcode,equals,toString,wait,notify,finalize,getClass,clone(没说出来)
点评:
题目虽然简单,漏掉几个也没有什么问题。不要为了回答问题而回答问题。回答完Object有哪些方法后,需要对各个方法进行解释,例如为什么这几个方法会在Object,其中分成了几类,第一类是做什么的,第二类是做什么的,以此类推。通过这个这道题目可以引申的知识点:
- 可以根据hashcode,equals方法引申出Map,Set的实现,equals与==的区别
- 通过wait, notify可以引申出同步等待的知识点,synchronized关键字,volatile,lock,aqs,线程安全类等一系列知识点的展开。如果能够进一步结合到自己的项目中会更好,例如项目中哪里为了解决什么问题使用了CountDownLatch等等。
- getClass 可以引申出Class类,进而引出ClassLoader,整个类加载器的知识框架都可以聊。
面对面试者的回答,面试官在自己的节奏中,一步步提问
追问:finalize方法是做什么的?
回答:
没有实质的说出来finalize的用途是做什么的,我大致描述了finalize的特点:在对象被Gc之前,必然会调用finalize方法,使用finalize方法可以有一次拯救自己的机会,可以对该对象重新引用
点评:
中规中矩的回答,几乎和书上写的是一样的。针对这种回答,应该直接说明,这只是Java为了对等C++的析构函数的方法,虽然可以做一些回收的工作,但是不建议使用。不要给面试官再次问的机会。这一块,引出了GC居然没有问,尴尬
追问:
见过finalize这么做的吗?
回答:
没有,实际项目中基本不会对finalize重写,也不建议重写(这块对finalize的使用场景不太清楚)
追问:
equals方法和hashcode方法为什么需要同时重写
回答:
hashMap和hashSet的数据结构中,会先对对象进行hashCode码的判断,然后在根据equals方法的判断是否是相同对象
追问:
hashcode一样,equals相等吗?
回答:
不一定
追问:
equals相等,hashcode相同吗?
回答:
相同
点评:
最后两个问题,感觉意义不大,两个方法而已,hashcode本身就是为了不碰撞,即便碰撞上了,equals相等与否无所谓;equals相等,hashcode一定相同吗?一类个放在list中,为了判断相等一般只会重写equals方法,而不会重写hashcode方法。我认为这两个问题的场景如果是在Map中这样的回答是正确的。
问题三:说下db中的乐观锁和悲观锁
回答:
反问了下,没太明白题目的意思(蒙了,db中的乐观锁和悲观锁?这个是要问隔离级别吗?)
追问:
那说下什么是乐观锁,什么是悲观锁
回答:
乐观锁:在使用之前认为该值时不会被改动的,业务执行之后修改值的时候进行比对
悲观锁:在使用之前认为该值会被改动,使用之前先对其进行加锁
点评:
回答要抓重点,首先讲什么是悲观锁,什么是乐观锁,各自使用的场景是什么,结合自己的理解提出哪些地方使用了乐观锁,哪些地方使用了悲观锁。
- 乐观锁:认为发生冲突的概率是非常小的,所以在每次更新的时候都需要判断原值是否发生了变化。主要应用于数据竞争冲突小的情况。例如AQS中的CAS操作使用的就是乐观锁原理
- 悲观锁:认为冲突发生的概率是非常大的,如果冲突一直在发生,乐观锁中有的线程就会陷入饥饿状态,一直修改数据不成功。针对这种情况,在出现竞争的地方设置锁,每次只能有一个线程进行操作。在JAVA中synchronized,Lock的实现即为悲观锁原理。
这样回答中如果有面试者非常熟悉的知识点,面试官就会被你的思路带走。
追问:
说下怎么在db中使用乐观锁和悲观锁,假设db中有个库存的列,需要进行扣减,分别使用乐观锁和悲观锁实现一下
回答:
这块我大脑蒙了,没说出来
面试后自己回顾:
乐观锁实现:在db中增加version字段,读数据把version读出来,修改后对比version是否相同,相同情况下对库存修改,并对version加1
悲观锁实现:这块可以设置新字段标识行锁,先更新行锁锁住该行,然后在读出数据修改数值,把行锁解除掉(感觉会引申出如果宕机了锁没有清掉产生的一直被锁的问题)
点评:
这个回答也是不太好
- 乐观锁的实现,version可以实现,也可以解决乐观锁的ABA问题,但是在库存这种场景下ABA问题不影响业务。首选查询库存为x,现在库存要-1,直接更新库存就可以了,只不过要在where语句中添加stock=x,整体语句为:update xxx set stock = x-1 where stock=x and id=xxxx
- 悲观锁,这里的思想是在数据库中使用一个字段进行标志,先更新标记位,谁更新成功谁获取锁。但是这是有严重问题的:1是线程加锁成功后死掉了怎么办,该条记录永远不能解锁,其他线程死等?2是其他线程完全可以通过操作修改锁状态也就是释放锁,释放锁的线程与加锁的线程可以不一致,这个只能通过代码逻辑控制。其实mysql中提供在在查询的时候加 for update来加锁,保证查询的数据不会被修改,这就是db的悲观锁。
问题四:算法题,两个有序数组,合并
回答:
归并,嘴说代码
点评:
算法题,讲对思想,分析好时间空间复杂度就可以了。如果有更好的改进策略那就更好了。例如存在的问题:
- 递归,如何改成非递归(不会不要说,说了就是给自己挖坑)
- 归并浪费空间 ,两个空间需要来回导数据,如何避免
总结
面试本身就是面试者与面试官的交流,面试者应该尽可能的引申出更深层次以及自己掌握度较好的知识点,引导者面试官的思路进行交流。单单一个知识领域(例如jvm,线程安全等等)就可以占据整个面试80%的时间,面试效果也会非常的好。反之,如果交流不畅,被面试官牵着鼻子走,问的都是自己不擅长的领域,那么面试基本是失败的。大家面试也要多多总结,一块学习,一块进步。