您的位置:首页 > 编程语言 > Java开发

JAVA人力、项目面试常谈问题以及个人开场介绍模板

2020-08-10 22:36 881 查看

JAVA人力、技能、项目面试常谈问题以及个人开场介绍模板


--------------------------------------------------------------华丽的分割线----------------------------------------------------
-大道理想必大家都懂,所以直入主题,不说概念性的废话(本来要写的内容就很多,全文目前87474字,2434行);
-【提示!!!】文章内容会逐渐越来越多,若想针对性的寻觅想要的内容,可尝试CTRL+F找到自己感兴趣的内容!
-【文章结构】=【百道人力面试】+【几篇介绍模板】+【模块化技能面试】+【面试项目问题】+【扩展内容】,详情请先参考文章目录!!!选择性拿!!!
--------------------------------------------------------------华丽的分割线----------------------------------------------------



JAVA 人力面试(目前101个)常谈问题


后面的技术问题会两三天更新一次!!!不断完善 本次更新时间【2020-8-10】
小声哔哔:写就一个人写,看就大家一起看?!



1. 请你自我介绍一下

回答提示:一般人回答这个问题过于平常,只说姓名、年龄、爱好、工作经验,这些在简历上都有,其实,企业最希望知道的是求职者能否胜任工作,包括:最强的技能、最深入研究的知识领域、个性中最积极的部分、做过的最成功的事,主要的成就等,这些都可以和学习无关,也可以和学习有关,但要突出积极的个性和做事的能力,说得合情合理企业才会相信。企业很重视一个人的礼貌,求职者要尊重考官,在回答每个问题之后都说一句谢谢.。企业喜欢有礼貌的求职者。

2. 你觉得你个性上最大的优点是什么?

回答提示:沉着冷静、条理清楚、立场坚定、顽强向上。
乐于助人和关心他人、适应能力和幽默感、乐观和友爱。我在北大青鸟经过一到两年的培训及项目实战,加上实习工作,使我适合这份工作。我相信我能成功。

3. 说说你最大的缺点?

回答提示:这个问题企业问的概率很大,通常不希望听到直接回答的缺点是什么等,如果求职者说自己小心眼、爱忌妒人、非常懒、脾气大、工作效率低,企业肯定不会录用你。绝对不要自作聪明地回答我最大的缺点是过于追求完美.,有的人以为这样回答会显得自己比较出色,但事实上,他已经岌芨可危了。企业喜欢求职者从自己的优点说起,中间加一些小缺点,最后再把问题转回到优点上,突出优点的部分。企业喜欢聪明的求职者。

4. 你对加班的看法?

回答提示:实际上好多公司问这个问题,并不证明一定要加班。只是想测试你是否愿意为公司奉献。
回答样本:如果是工作需要我会义不容辞加班。我现在单身,没有任何家庭负担,可以全身心的投入工作。但同时,我也会提高工作效率,减少不必要的加班

5. 你对薪资的要求?

回答提示:如果你对薪酬的要求太低,那显然贬低自己的能力;如果你对薪酬的要求太高,那又会显得你分量过重,公司受用不起。一些雇主通常都事先对求聘的职位定下开支预算,因而他们第一次提出的价钱往往是他们所能给予的最高价钱。他们问你只不过想证实一下这笔钱是否足以引起你对该工作的兴趣。
回答样本一:我对工资没有硬性要求。我相信贵公司在处理我的问题上会友善合理。我注重的是找对工作机会,所以只要条件公平,我则不会计较太多
回答样本二:我受过系统的软件编程的训练,不需要进行大量的培训。而且我本人也对编程特别感兴趣。因此,我希望公司能根据我的情况和市场标准的水平,给我合理的薪水。
回答样本三:如果你必须自己说出具体数目,请不要说一个宽泛的范围,那样你将只能得到最低限度的数字。最好给出一个具体的数字,这样表明你已经对当今的人才市场作了调查,知道像自己这样学历的雇员有什么样的价值。

6. 在五年的时间内,你的职业规划?

回答提示:这是每一个应聘者都不希望被问到的问题,但是几乎每个人都会被问到。比较多的答案是管理者.。但是近几年来,许多公司都已经建立了专门的技术途径。这些工作地位往往被称作顾问.、参议技师.或高级软件工程师.等等。当然,说出其他一些你感兴趣的职位也是可以的,比如产品销售部经理,生产部经理等一些与你的专业有相关背景的工作。要知道,考官总是喜欢有进取心的应聘者,此时如果说不知道.,或许就会使你丧失一个好机会。最普通的回答应该是我准备在技术领域有所作为.或我希望能按照公司的管理思路发展.。

7. 你朋友对你的评价?

回答提示:想从侧面了解一下你的性格及与人相处的问题。
回答样本:我的朋友都说我是一个可以信赖的人。因为,我一旦答应别人的事情,就一定会做到。如果我做不到,我就不会轻易许诺。
回答样本:.我觉的我是一个比较随和的人,与不同的人都可以友好相处。在我与人相处时,我总是能站在别人的角度考虑问题

8. 你还有什么问题要问吗?

回答提示:企业的这个问题看上去可有可无,其实很关键,企业不喜欢说没有问题.的人,因为其很注重员工的个性和创新能力。企业不喜欢求职者问个人福利之类的问题,如果有人这样问:贵公司对新入公司的员工有没有什么培训项目,我可以参加吗?或者说贵公司的晋升机制是什么样的?企业将很欢迎,因为体现出你对学习的热情和对公司的忠诚度以及你的上进心。

9. 如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?

回答提示:一段时间发现工作不适合我,有两种情况:
① 如果你确实热爱这个职业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个职业的精神内涵和职业要求,力争减少差距;
② 你觉得这个职业可有可无,那还是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,对单位和个人都有好处。

10. 在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?

回答提示:
① 原则上我会尊重和服从领导的工作安排;同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法;
② 如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作;
③ 还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见;如领导仍固执己见,我会毫不犹豫地再向上级领导反映。

11. 如果你的工作出现失误,给本公司造成经济损失,你认为该怎么办?

回答提示:
① 我本意是为公司努力工作,如果造成经济损失,我认为首要的问题是想方设法去弥补或挽回经济损失。如果我无能力负责,希望单位帮助解决;
② 是责任问题。分清责任,各负其责,如果是我的责任,我甘愿受罚;如果是一个我负责的团队中别人的失误,也不能幸灾乐祸,作为一个团队,需要互相提携共同完成工作,安慰同事并且帮助同事查找原因总结经验。
③ 总结经验教训,一个人的一生不可能不犯错误,重要的是能从自己的或者是别人的错误中吸取经验教训,并在今后的工作中避免发生同类的错误。检讨自己的工作方法、分析问题的深度和力度是否不够,以致出现了本可以避免的错误。

12. 如果你在这次考试中没有被录用,你怎么打算?

回答提示:现在的社会是一个竞争的社会,从这次面试中也可看出这一点,有竞争就必然有优劣,有成功必定就会有失败.往往成功的背后有许多的困难和挫折,如果这次失败了也仅仅是一次而已,只有经过经验经历的积累才能塑造出一个完全的成功者。我会从以下几个方面来正确看待这次失败.
第一、要敢于面对,面对这次失败不气馁,接受已经失去了这次机会就不会回头这个现实,从心理意志和精神上体现出对这次失败的抵抗力。要有自信,相信自己经历了这次之后经过努力一定能行.能够超越自我.
第二、善于反思,对于这次面试经验要认真总结,思考剖析,能够从自身的角度找差距。正确对待自己,实事求是地评价自己,辩证的看待自己的长短得失,做一个明白人.
第三、走出阴影,要克服这一次失败带给自己的心理压力,时刻牢记自己弱点,防患于未然,加强学习,提高自身素质.
第四、认真工作,回到原单位岗位上后,要实实在在、踏踏实实地工作,三十六行,行行出状元,争取在本岗位上做出一定的成绩.
第五、再接再厉,成为软件工程师或网络工程师一直是我的梦想,以后如果有机会我仍然后再次参加竞争.

13. 如果你做的一项工作受到上级领导的表扬,但你主管领导却说是他做的,你该怎样?

回答提示:我首先不会找那位上级领导说明这件事,我会主动找我的主管领导来沟通,因为沟通是解决人际关系的最好办法,但结果会有两种:
① 我的主管领导认识到自己的错误,我想我会视具体情况决定是否原谅他;
② 他更加变本加厉的来威胁我,那我会毫不犹豫地找我的上级领导反映此事,因为他这样做会造成负面影响,对今后的工作不利。

14. 谈谈你对跳槽的看法?

回答提示:
①正常的
② 频繁的跳槽对单位和个人双方都不利,应该反对。

15. 工作中你难以和同事、上司相处,你该怎么办?

回答提示:
① 我会服从领导的指挥,配合同事的工作。
② 我会从自身找原因,仔细分析是不是自己工作做得不好让领导不满意,同事看不惯。还要看看是不是为人处世方面做得不好。如果是这样的话我会努力改正。
③ 如果我找不到原因,我会找机会跟他们沟通,请他们指出我的不足。有问题就及时改正。
④ 作为优秀的员工,应该时刻以大局为重,即使在一段时间内,领导和同事对我不理解,我也会做好本职工作,虚心向他们学习,我相信,他们会看见我在努力,总有一天会对我微笑的!

16.假设你在某单位工作,成绩比较突出,得到领导的肯定。但同时你发现同事们越来越孤立你,你怎么看这个问题?你准备怎么办?

回答提示:
① 成绩比较突出,得到领导的肯定是件好事情,以后更加努力
② 检讨一下自己是不是对工作的热心度超过同事间交往的热心了,加强同事间的交往及共同的兴趣爱好。
③ 工作中,切勿伤害别人的自尊心
④ 不再领导前拨弄是非
⑤乐于助人对面

17. 你最近是否参加了培训课程?谈谈培训课程的内容。是公司资助还是自费参加?

回答提示:是自费参加,就是北大青鸟的培训课程(可以多谈谈自己学的技术)。

18. 你对于我们公司了解多少?

回答提示:在去公司面试前上网查一下该公司主营业务。如回答:贵公司有意改变策略,加强与国外大厂的OEM合作,自有品牌的部分则透过海外经销商。

19. 请说出你选择这份工作的动机?

回答提示:这是想知道面试者对这份工作的热忱及理解度,并筛选因一时兴起而来应试的人,如果是无经验者,可以强调就算职种不同,也希望有机会发挥之前的经验.。

20. 你最擅长的技术方向是什么?

回答提示:说和你要应聘的职位相关的课程,表现一下自己的热诚没有什么坏处。

21. 你能为我们公司带来什么呢?

回答提示:
① 假如你可以的话,试着告诉他们你可以减低他们的费用;;我已经接受过北大青鸟近两年专业的培训,立刻就可以上岗工作.。
② 企业很想知道未来的员工能为企业做什么,求职者应再次重复自己的优势,然后说:就我的能力,我可以做一个优秀的员工在组织中发挥能力,给组织带来高效率和更多的收益.。企业喜欢求职者就申请的职位表明自己的能力,比如申请营销之类的职位,可以说:我可以开发大量的新客户,同时,对老客户做更全面周到的服务,开发老客户的新需求和消费。.等等。

22. 最能概括你自己的三个词是什么?

回答提示:我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具体例子向主考官解释,

23. 你的业余爱好是什么?

回答提示:找一些富于团体合作精神的,这里有一个真实的故事:有人被否决掉,因为他的爱好是深海潜水。主考官说:因为这是一项单人活动,我不敢肯定他能否适应团体工作。

24. 作为被面试者给我打一下分

回答提示:试着列出四个优点和一个非常非常非常小的缺点,(可以抱怨一下设施,没有明确责任人的缺点是不会有人介意的)。

25. 你怎么理解你应聘的职位?

回答提示:把岗位职责和任务及工作态度阐述一下

26. 喜欢这份工作的哪一点?

回答提示:相信其实大家心中一定都有答案了吧!每个人的价值观不同,自然评断的标准也会不同,但是,在回答面试官这个问题时可不能太直接就把自己心理的话说出来,尤其是薪资方面的问题,不过一些无伤大雅的回答是不错的考虑,如交通方便,工作性质及内容颇能符合自己的兴趣等等都是不错的答案,不过如果这时自己能仔细思考出这份工作的与众不同之处,相信在面试上会大大加分。

27. 为什么要离职?

回答提示:
① 回答这个问题时一定要小心,就算在前一个工作受到再大的委屈,对公司有多少的怨言,都千万不要表现出来,尤其要避免对公司本身主管的批评,避免面试官的负面情绪及印象;建议此时最好的回答方式是将问题归咎在自己身上,例如觉得工作没有学习发展的空间,自己想在面试工作的相关产业中多加学习,或是前一份工作与自己的生涯规划不合等等,回答的答案最好是积极正面的。
② 我希望能获得一份更好的工作,如果机会来临,我会抓住;我觉得目前的工作,已经达到顶峰,即沒有升迁机会。

28. 说说你对行业、技术发展趋势的看法?

回答提示:企业对这个问题很感兴趣,只有有备而来的求职者能够过关。求职者可以直接在网上查找对你所申请的行业部门的信息,只有深入了解才能产生独特的见解。企业认为最聪明的求职者是对所面试的公司预先了解很多,包括公司各个部门,发展情况,在面试回答问题的时候可以提到所了解的情况,企业欢迎进入企业的人是知己.,而不是盲人.。

29. 对工作的期望与目标何在?

回答提示:这是面试者用来评断求职者是否对自己有一定程度的期望、对这份工作是否了解的问题。对于工作有确实学习目标的人通常学习较快,对于新工作自然较容易进入状况,这时建议你,最好针对工作的性质找出一个确实的答案,如业务员的工作可以这样回答:我的目标是能成为一个超级业务员,将公司的产品广泛的推销出去,达到最好的业绩成效;为了达到这个目标,我一定会努力学习,而我相信以我认真负责的态度,一定可以达到这个目标。.其他类的工作也可以比照这个方式来回答,只要在目标方面稍微修改一下就可以了。

30. 说说你的家庭。

回答提示:企业面试时询问家庭问题不是非要知道求职者家庭的情况,探究隐私,企业不喜欢探究个人隐私,而是要了解家庭背景对求职者的塑造和影响。企业希望听到的重点也在于家庭对求职者的积极影响。企业最喜欢听到的是:我很爱我的家庭!我的家庭一向很和睦,虽然我的父亲和母亲都是普通人,但是从小,我就看到我父亲起早贪黑,每天工作特别勤劳,他的行动无形中培养了我认真负责的态度和勤劳的精神。我母亲为人善良,对人热情,特别乐于助人,所以在单位人缘很好,她的一言一行也一直在教导我做人的道理。企业相信,和睦的家庭关系对一个人的成长有潜移默化的影响。

31. 就你申请的这个职位,你认为你还欠缺什么?

回答提示:企业喜欢问求职者弱点,但精明的求职者一般不直接回答。他们希望看到这样的求职者:继续重复自己的优势,然后说:对于这个职位和我的能力来说,我相信自己是可以胜任的,只是缺乏经验,这个问题我想我可以进入公司以后以最短的时间来解决,我的学习能力很强,我相信可以很快融入公司的企业文化,进入工作状态。.企业喜欢能够巧妙地躲过难题的求职者。

32. 你欣赏哪种性格的人?

回答提示:诚实、不死板而且容易相处的人、有

33. 你通常如何处理別人的批评?

回答提示:①沈默是金。不必说什么,否则情况更糟,不过我会接受建设性的批评;②我会等大家冷靜下来再讨论。

34. 你怎样对待自己的失敗?

回答提示:我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错误。

35. 什么会让你有成就感?

回答提示:为贵公司竭力效劳;尽我所能,完成一个项目

36. 眼下你生活中最重要的是什么?

回答提示:对我来说,能在这个领域找到工作是最重要的;望能在贵公司任职对我说最重要。

37. 你为什么愿意到我们公司来工作?

回答提示:对于这个问题,你要格外小心,如果你已经对该单位作了研究,你可以回答一些详细的原因,像公司本身的高技术开发环境很吸引我。.,我同公司出生在同样的时代,我希望能够进入一家与我共同成长的公司。.你们公司一直都稳定发展,在近几年来在市场上很有竞争力。.或者我认为贵公司能够给我提供一个与众不同的发展道路。.这都显示出你已经做了一些调查,也说明你对自己的未来有了较为具体的远景规划。

38. 你和别人发生过争执吗?你是怎样解决的?

回答提示:这是面试中最险恶的问题。其实是考官布下的一个陷阱。千万不要说任何人的过错。应知成功解决矛盾是一个协作团体中成员所必备的能力。假如你工作在一个服务行业,这个问题简直成了最重要的一个环节。你是否能获得这份工作,将取决于这个问题的回答。考官希望看到你是成熟且乐于奉献的。他们通过这个问题了解你的成熟度和处世能力。在没有外界干涉的情况下,通过妥协的方式来解决才是正确答案。

39. 问题:你做过的哪件事最令自己感到骄傲?

回答提示:这是考官给你的一个机会,让你展示自己把握命运的能力。这会体现你潜在的领导能力以及你被提升的可能性。假如你应聘于一个服务性质的单位,你很可能会被邀请去午餐。记住:你的前途取决于你的知识、你的社交能力和综合表现。

40. 你新到一个部门,一天一个客户来找你解决问题,你努力想让他满意,可是始终达不到群众得满意,他投诉你们部门工作效率低,你这个时候怎么作?

回答提示:
① 首先,我会保持冷静。作为一名工作人员,在工作中遇到各种各样的问题是正常的,关键是如何认识它,积极应对,妥善处理。
② 其次,我会反思一下客户不满意的原因。一是看是否是自己在解决问题上的确有考虑的不周到的地方,二是看是否是客户不太了解相关的服务规定而提出超出规定的要求,三是看是否是客户了解相关的规定,但是提出的要求不合理。
③ 再次,根据原因采取相对的对策。如果是自己确有不周到的地方,按照服务规定作出合理的安排,并向客户作出解释;如果是客户不太了解政策规定而造成的误解,我会向他作出进一步的解释,消除他的误会;如果是客户提出的要求不符合政策规定,我会明确地向他指出。
④ 再次,我会把整个事情的处理情况向领导作出说明,希望得到他的理解和支持。(5)我不会因为客户投诉了我而丧失工作的热情和积极性,而会一如既往地牢记为客户服务的宗旨,争取早日做一名领导信任、公司放心、客户满意的职员。

41. 对这项工作,你有哪些可预见的困难?

回答提示:
① 不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行;
② 可以尝试迂回战术,说出应聘者对困难所持有的态度;工作中出现一些困难是正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周密而充分的准备,任何困难都是可以克服。.
分析:一般问这个问题,面试者的希望就比较大了,因为已经在谈工作细节。但常规思路中的回答,又被面试官骗了。当面试官询问这个问题的时候,有两个目的。第一,看看应聘者是不是在行,说出的困难是不是在这个职位中一般都不可避免的问题。第二,是想看一下应聘者解决困难的手法对不对,及公司能否提供这样的资源。而不是想了解应聘者对困难的态度。

42. 如果我录用你,你将怎样开展工作?

回答提示:
① 如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出自己开展工作的具体办法;
② 可以尝试采用迂回战术来回答,如首先听取领导的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计划并报领导批准,最后根据计划开展工作。.
分析:这个问题的主要目的也是了解应聘者的工作能力和计划性、条理性,而且重点想要知道细节。如果向思路中所讲的迂回战术,面试官会认为回避问题,如果引导了几次仍然是回避的话。此人绝对不会录用了。

43. 你希望与什么样的上级共事?

回答提示:
① 通过应聘者对上级的希望.可以判断出应聘者对自我要求的意识,这既上一个陷阱,又是一次机会;
② 最好回避对上级具体的希望,多谈对自己的要求;
③ 如做为刚步入社会的新人,我应该多要求自己尽快熟悉环境、适应环境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了
分析:这个问题比较好的回答是,希望我的上级能够在工作中对我多指导,对我工作中的错误能够立即指出。总之,从上级指导这个方面谈,不会有大的纰漏。

44. 在完成某项工作时,你认为领导要求的方式不是最好的,自己还有更好的方法,你应该怎么做?

回答提示:
① 原则上我会尊重和服从领导的工作安排;同时私底下找机会以请教的口吻,婉转地表达自己的想法,看看领导是否能改变想法;
② 如果领导没有采纳我的建议,我也同样会按领导的要求认真地去完成这项工作;
③ 还有一种情况,假如领导要求的方式违背原则,我会坚决提出反对意见;如领导仍固执己见,我会毫不犹豫地再向上级领导反映。

45. 与上级意见不一是,你将怎么办?

回答提示:
① 一般可以这样回答我会给上级以必要的解释和提醒,在这种情况下,我会服从上级的意见。
② 如果面试你的是总经理,而你所应聘的职位另有一位经理,且这位经理当时不在场,可以这样回答:对于非原则性问题,我会服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。.
分析:这个问题的标准答案是思路1,如果用2的回答,必死无疑。你没有摸清楚改公司的内部情况,先想打小报告,这样的人没有人敢要。

46. 你工作经验欠缺,如何能胜任这项工作?

常规思路:
① 如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘公司并不真正在乎经验.,关键看应聘者怎样回答;
② 对这个问题的回答最好要体现出应聘者的诚恳、机智、果敢及敬业;
③ 如作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。
点评:这个问题思路中的答案尚可。突出自己的吃苦能力和适应性以及学习能力(不是学习成绩)为好。

47. 您在前一家公司的离职原因是什么?

回答提示:
① 最重要的是:应聘者要使找招聘单位相信,应聘者在过往的单位的离职原因.在此家招聘单位里不存在;
② 避免把离职原因.说得太详细、太具体;
③ 不能掺杂主观的负面感受,如太辛苦.、人际关系复杂.、管理太混乱.、公司不重视人才.、公司排斥我们某某的员工.等;
④ 但也不能躲闪、回避,如想换换环境.、个人原因.等;
⑤ 不能涉及自己负面的人格特征,如不诚实、懒惰、缺乏责任感、不随和等;
⑥ 尽量使解释的理由为应聘者个人形象添彩;
⑦ 相关例子:如我离职是因为这家公司倒闭;我在公司工作了三年多,有较深的感情;从去年始,由于市场形势突变,公司的局面急转直下;到眼下这一步我觉得很遗憾,但还要面对显示,重新寻找能发挥我能力的舞台。.同一个面试问题并非只有一个答案,而同一个答案并不是在任何面试场合都有效,关键在应聘者掌握了规律后,对面试的具体情况进行把握,有意识地揣摩面试官提出问题的心理背景,然后投其所好。
分析:除非是薪资太低,或者是最初的工作,否则不要用薪资作为理由。求发展.也被考官听得太多,离职理由要根据每个人的真实离职理由来设计,但是在回答时一定要表现得真诚。实在想不出来的时候,家在外地可以说是因为家中有事,须请假几个月,公司又不可能准假,所以辞职。这个答案一般面试官还能接受。

48. 你工作经验欠缺,如何能胜任这项工作?

回答提示:
① 如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘公司并不真正在乎经验.,关键看应聘者怎样回答;
② 对这个问题的回答最好要体现出应聘者的诚恳、机智、果敢及敬业;
③ 如作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。分析:这个问题思路中的答案尚可。突出自己的吃苦能力和适应性以及学习能力(不是学习成绩)为好。

49. 为了做好你工作份外之事,你该怎样获得他人的支持和帮助?

回答提示:每个公司都在不断变化发展的过程中;你当然希望你的员工也是这样。你希望得到那些希望并欢迎变化的人,因为这些人明白,为了公司的发展,变化是公司日常生活中重要组成部分。这样的员工往往很容易适应公司的变化,并会对变化做出积极的响应。此外,他们遇到矛盾和问题时,也能泰然处之。下面的问题能够考核应聘者这方面的能力。
据说有人能从容避免正面冲突。请讲一下你在这方面的经验和技巧。
有些时候,我们得和我们不喜欢的人在一起共事。说说你曾经克服了性格方面的冲突而取得预期工作效果的经历。

50. 如果你在这次面试中没有被录用,你怎么打算?

回答提示:现在的社会是一个竞争的社会,从这次面试中也可看出这一点,有竞争就必然有优劣,有成功必定就会有失败.往往成功的背后有许多的困难和挫折,如果这次失败了也仅仅是一次而已,只有经过经验经历的积累才能塑造出一个完全的成功者。我会从以下几个方面来正确看待这次失败.
第一、要敢于面对,面对这次失败不气馁,接受已经失去了这次机会就不会回头这个现实,从心理意志和精神上体现出对这次失败的抵抗力。要有自信,相信自己经历了这次之后经过努力一定能行.能够超越自我.
第二、善于反思,对于这次面试经验要认真总结,思考剖析,能够从自身的角度找差距。正确对待自己,实事求是地评价自己,辩证的看待自己的长短得失,做一个明白人.
第三、走出阴影,要克服这一次失败带给自己的心理压力,时刻牢记自己弱点,防患于未然,加强学习,提高自身素质.
第四、认真工作,回到原单位岗位上后,要实实在在、踏踏实实地工作,三十六行,行行出状元,争取在本岗位上做出一定的成绩.
第五、再接再厉,成为国家公务员一直是我的梦想,以后如果有机会我仍然后再次参加竞争.

51. 假如你晚上要去送一个出国的同学去机场,可单位临时有事非你办不可,你怎么办?

回答提示:我觉得工作是第一位的,但朋友间的情谊也是不能偏废的。这个问题我觉得要按照当时具体的情况来决定。
① 如果我的朋友晚上9点中的飞机,而我的加班八点就能够完成的话,那就最理想了,干完工作去机场,皆大欢喜。
② 如果说工作不是很紧急,加班仅仅是为了明天上班的时候能把报告交到办公室,那完全可以跟领导打声招呼,先去机场然后回来加班,晚点睡就是了。
③ 如果工作很紧急,两者不可能兼顾的情况下,我觉得可以由两种选择。1)如果不是全单位都加班的话,是不是可以要其他同事来代替以下工作,自己去机场,哪怕就是代替你离开的那一会儿。2)如果连这一点都做不到的话,那只好忠义不能两全了,打电话给朋友解释一下,小心他会理解,毕竟工作做完了就完了,朋友还是可以再见面的。

52. 如果通过这次面试我们单位录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?

回答提示:一段时间发现工作不适合我,有两种情况:
① 如果你确实热爱这个职业,那你就要不断学习,虚心向领导和同事学习业务知识和处事经验,了解这个职业的精神内涵和职业要求,力争减少差距;
② 你觉得这个职业可有可无,那还是趁早换个职业,去发现适合你的,你热爱的职业,那样你的发展前途也会大点,对单位和个人都有好处。

53. 你做过的哪件事最令自己感到骄傲?

回答提示:这是考官给你的一个机会,让你展示自己把握命运的能力。这会体现你潜在的领导能力以及你被提升的可能性。假如你应聘于一个服务性质的单位,你很可能会被邀请去午餐。记住:你的前途取决于你的知识、你的社交能力和综合表现。

54. 谈谈你过去做过的成功案例

回答提示:举一个你最有把握的例子,把来龙去脉说清楚,而不要说了很多却没有重点。切忌夸大其词,把别人的功劳到说成自己的,很多主管为了确保要用的人是最适合的,会打电话向你的前一个主管征询对你的看法及意见,所以如果说谎,是很容易穿梆的。

55. 谈谈你过去的工作经验中,最令你挫折的事情

回答提示:曾经接触过一个客户,原本就有耳闻他们以挑剔出名,所以事前的准备功夫做得十分充分,也投入了相当多的时间与精力,最后客户虽然并没有照单全收,但是接受的程度已经出乎我们意料之外了。原以为从此可以合作愉快,却得知客户最后因为预算关系选择了另一家代理商,之前的努力因而付诸流水。尽管如此,我还是从这次的经验学到很多,如对该产业的了解,整个team的默契也更好了。
分析:借此了解你对挫折的容忍度及调解方式。

56. 如何安排自己的时间?会不会排斥加班?

回答提示:基本上,如果上班工作有效率,工作量合理的话,应该不太需要加班。可是我也知道有时候很难避免加班,加上现在工作都采用责任制,所以我会调配自己的时间,全力配合。
分析:虽然不会有人心甘情愿的加班,但依旧要表现出高配合度的诚意。

57. 为什么我们要在众多的面试者中选择你?

回答提示:根据我对贵公司的了解,以及我在这份工作上所累积的专业、经验及人脉,相信正是贵公司所找寻的人才。而我在工作态度、EQ上,也有圆融、成熟的一面,和主管、同事都能合作愉快。
分析:别过度吹嘘自己的能力,或信口开河地乱开支票,例如一定会为该公司带来多少钱的业务等,这样很容易给人一种爱说大话、不切实际的感觉。

58. 对这个职务的期许?

回答提示:希望能借此发挥我的所学及专长,同时也吸收贵公司在这方面的经验,就公司、我个人而言,缔造双赢.的局面。
分析:回答前不妨先询问该公司对这项职务的责任认定及归属,因为每一家公司的状况不尽相同。以免说了一堆理想抱负却发现牛头不对马嘴。

59. 为什么选择这个职务?

回答提示::这一直是我的兴趣和专长,经过这几年的磨练,也累积了一定的经验及人脉,相信我一定能胜任这个职务的。
分析:适时举出过去的丰功伟业.,表现出你对这份职务的熟稔度,但避免过于夸张的形容或流于炫耀。

60. 为什么选择我们这家公司?

回答提示:曾经在报章杂志看过关于贵公司的报道,与自己所追求的理念有志一同。而贵公司在业界的成绩也是有目共睹的,而且对员工的教育训练、升迁等也都很有制度。
分析:去面试前先做功课,了解一下该公司的背景,让对方觉得你真的很有心想得到这份工作,而不只是探探路。

61. 你认为你在学校属于好学生吗?

回答提示:企业的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标准,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。.如果求职者成绩不尽理想,便会说:我认为是不是一个好学生的标准是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过;;活动,锻炼了我的团队合作精神和组织能力。.有经验的招聘者一听就会明白,企业喜欢诚实的求职者。

62. 请谈谈如何适应办公室工作的新环境?

回答提示:
① 办公室里每个人有各自的岗位与职责,不得擅离岗位。
② 根据领导指示和工作安排,制定工作计划,提前预备,并按计划完成。
③ 多请示并及时汇报,遇到不明白的要虚心请教。
④ 抓间隙时间,多学习,努力提高自己的政治素质和业务水平。

63. 在工作中学习到了些什么?

回答提示:这是针对转职者提出的问题,建议此时可以配合面试工作的特点作为主要依据来回答,如业务工作需要与人沟通,便可举出之前工作与人沟通的例子,经历了哪些困难,学习到哪些经验,把握这些要点做陈述,就可以轻易过关了

64. 有想过创业吗?

回答提示:这个问题可以显示你的冲劲,但如果你的回答是有的话,千万小心,下一个问题可能就是那么为什么你不这样做呢?.

65. 最能概括你自己的三个词是什么?

回答提示:我经常用的三个词是:适应能力强,有责任心和做事有始终,结合具体例子向主考官解释,使他们觉得你具有发展潜力

66. 你认为你在学校属于好学生吗?

回答提示:企业的招聘者很精明,问这个问题可以试探出很多问题:如果求职者学习成绩好,就会说:是的,我的成绩很好,所有的成绩都很优异。当然,判断一个学生是不是好学生有很多标准,在学校期间我认为成绩是重要的,其他方面包括思想道德、实践经验、团队精神、沟通能力也都是很重要的,我在这些方面也做得很好,应该说我是一个全面发展的学生。.如果求职者成绩不尽理想,便会说:我认为是不是一个好学生的标准是多元化的,我的学习成绩还可以,在其他方面我的表现也很突出,比如我去很多地方实习过,我很喜欢在快节奏和压力下工作,我在学生会组织过;;活动,锻炼了我的团队合作精神和组织能力。.有经验的招聘者一听就会明白,企业喜欢诚实的求职者。

67. 除了本公司外,还应聘了哪些公司?

回答提示:很奇怪,这是相当多公司会问的问题,其用意是要概略知道应徵者的求职志向,所以这并非绝对是负面答案,就算不便说出公司名称,也应回答销售同种产品的公司.,如果应聘的其他公司是不同业界,容易让人产生无法信任的感觉。

68. 何时可以到职?

回答提示:大多数企业会关心就职时间,最好是回答’如果被录用的话,到职日可按公司规定上班.,但如果还未辞去上一个工作、上班时间又太近,似乎有些强人所难,因为交接至少要一个月的时间,应进一步说明原因,录取公司应该会通融的

69. 你并非毕业于名牌院校?

回答提示:是否毕业于名牌院校不重要,重要的是有能力完成您交给我的工作,我接受了北大青鸟的职业培训,掌握的技能完全可以胜任贵公司现在工作,而且我比一些名牌院校的应届毕业生的动手能力还要强,我想我更适合贵公司这个职位。

70. 你怎样看待学历和能力?

回答提示:学历我想只要是大学专科的学历,就表明觉得我具备了根本的学习能力。剩下的,你是学士也好,还是博士也好,对于这一点的讨论,不是看你学了多少知识,而是看你在这个领域上发挥了什么,也就是所说的能力问题。一个人工作能力的高低直接决定其职场命运,而学历的高低只是进入一个企业的敲门砖,如果贵公司把学历卡在博士上,我就无法进入贵公司,当然这不一定只是我个人的损失,如果一个专科生都能完成的工作,您又何必非要招聘一位博士生呢?

71. 你经历太单纯,而我们需要的是社会经验丰富的人?

回答提示:经历丰富的人也未必适合这个职位,如果他在以前的经历中养成的是一个良好的职业习惯还好,如果是不好的职业习惯呢?我在这方面是一片空白,更可以尽快地融入贵公司的企业文化,养成良好的职业习惯,一个人具有良好的职业习惯,更会发挥自己的长处为公司做更多的事。

72. 你性格过于内向,这恐怕与我们的职业不合适?

回答提示:没关系呀,性格内向可以踏实地完成技术工作。况且性格内向并不能说明我无法讲述清楚我做的项目,
克林顿小时候性格还内向呢,并不能阻止他成为美国总统。

73. 假如领导派你和一个有矛盾的同志一起出差,你如何处理?在日常生活中,出现这样的事情你是如何处理的?试举例说明。

回答提示:在日常生活中,由于每个人的观点和立场,看待和分析问题的方法不同,矛盾是不可避免的。假如我和一个和我有矛盾的同志一起出差,我想首先应该开诚布公,因为有矛盾,就把许多东西隐藏起来,这只会加深误会,假如互相坦诚相见,以一种客观,不带个人情绪的态度看问题,你会发现你原先自认为十分得意的想法并不完全正确,你先前反对的看法和观点可能只是一个事物的另一侧面,你们原来在许多方面可以互相补充,互相完善。我个人认为在处理矛盾问题上要有一种宽容的态度,俗话说的好:宰相肚里能撑船。心胸狭隘是化解矛盾的大敌,而一个心胸狭隘的人是绝不可能成就一番大事业的。
我在上大学时,同寝室一个同学喜欢在寝室随地吐痰,我很不喜欢这一点,但他脾气比较暴躁,如果我直接向他说,矛盾就会激化,对此我采取了以下方法:一是通过别的同学委婉地表达我对他随地吐痰的反对态度;二是经常拿一些有关随地吐痰危害自己和他人健康的书籍放在寝室的桌子上,使他能够看到;三是我在他在寝室的时候也吐痰,但是不在寝室里吐,而是在外边吐,暗示其应到外边吐痰.,

74. 如果你遇到了挫折你将怎么办?

回答提示:事业有成一帆风顺时许多人的美好想法,其实很难做到一帆风顺,要接受这样一个现实,
人的一生不可能是一帆风顺的,成功的背后会有许许多多的艰辛,痛苦甚至挫折.在人生的一段时期遇到一些挫折是很正常的.只有经验知识和经历的积累才能塑造出一个成功者.我觉得面对挫折要做到以下几点:
① 第一要敢于面对.哪里跌倒要从哪里爬起来,小平同志还是三起三落呢,不要惧怕困难,要敢于向困难挑战.
② 再者要认真分析失败的原因,寻根究源,俗话说失败乃成功之母,在挫折中掌握教训,为下一次奋起提供经验.
③ 还有在平时的工作生化中要加强学习,人的一生是有限的,不可能经历所有的事,要在别人的经验吸取教训.
④ 最后可能由于当局者迷或者知识经历的不足,自己对于挫折并没有特别好的处理方法,这是可以求教自己的亲人朋友,群策群力渡过难关。

75. 你最喜欢的一本书是那本?

回答提示:我喜欢读书,一个人最早看的一本书可能会对个人的一生产生很大的影响,我小时候最早看的一本书是三国演义,三国演义这本书博大精深,书中描写的一些人物我对我的成长起了许多潜移默化的作用,现在看来我还是最喜欢三国演义如果我说我喜欢关羽,可能俗了一点,但从关羽身上表现出来的诚信和忠诚一直是我很推崇的。我觉得诚心是立身之本,而对单位的忠诚是你能不能做出一番事业的前提条件。当然这个忠诚还包括对领导的忠诚.
从周瑜身上我学到对别人要宽容,不要又嫉妒心;从诸葛亮身上学到要加强自己学习等等。三国演义这本书博大精深,对我的影响也是全方位的,时间原因我不再赘述。

76. 请告知你的工作观?

回答提示:常被问到你的**观是什么?.时,可别把它想得太复杂,可回答为何而工作.、从工作方面得到了什么.*年後想变成怎样.等的话。

77. 如果你有一位固执武断的领导,你会经常提合理化建议吗?

回答提示:
① 在一般情况下,领导和同事是不能选择的,每个人有每个人的个性和脾气,要学会适应和相处。
② 领导脾气直也好,悠也好,固执也好,只要是出自为公,为工作,应该尊重和原谅他,并且按他的安排去做。
③ 适当的时候,可以用谈心、汇报思想等方式委婉地提出自己的看法,但点到为止。
④ 在有合理化的建议时,照提不误。因为那是对自己和工作负责。

78. 假如在一次学习讨论会上,领导对你的发言很不满意,并当场批评了你,你怎么办?

回答提示:
好:能谈到在情绪产生波动时,自己的自我控制方法,并取得良好的效果。
中:有控制自我情绪的努力,但方法不够有效。
差:思前想后,顾虑重重,言语中流露出气愤、委屈,或长时间沉默,显得心情难以言表。

79. 针对你们单位业务工作中出现的问题,你提出了一些很好的建议,得到了同事们的赞同,但你的领导并不满意。在这种情况下,你怎么办?

回答提示:
好:能认真分析,仔细推敲自己建议存在的问题,认真领会领导意图,找出两者之间的共同点,圆满解决问题,考生心理冷静,自制力强,方法正确,陈述问题条理清楚,有说服力。
中:能找出问题的根源并冷静对待,处理问题有一定方法,陈述问题有一定说服力。
差:行为偏激,自制力差,方法不正确,或长时间沉默,显得无以应对。

80. 假设你手头上有好几项工作没有完成,可是上级又给你安排了一项任务。你感到自己完成这项工作有困难。你如何处理这个矛盾?

回答提示:出题思路:情境性问题。该题用于考查考生的人际交往的意识与技巧,主要是在组织中处理权属关系的能力。
参考评分标准:
好:能够很好地与人沟通,有很好的交往方法和技巧;能够在尊重他人的前提下恰当地表达自己的意见。如:能用适当方法让领导了解到自己现有任务已很重,并能向领导提出完成该任务的可行建议。
中:能与人沟通,交往中有一些方法、技巧,能适当地表达出自己的意见。如:能让领导认识到自己的困难。差:不能与他人沟通,交往中缺乏技巧;难以表达自己的意见。如:无法让领导了解自己的困难,或直接顶撞领导。

81. 当前对有些单位实施的末位淘汰制?,有不同争议,你怎么看待这种用人措施?.

回答提示:末位淘汰制是一种向竞争机制发展的过渡性措施,可以试行;但要因情况而异,不能一刀切。再说末位淘汰制.也不完全等同于竞争机制。对于规模较大、人数较多的单位最初实行,然后实施竞争机制,未尝不可。如果在规模小、人数少的单位实行,效果就不一定好,因为也确有些单位人数不多,几乎所有人员都很努力,成绩都不错,甚至难分上下,如果实行就会造成人心惶惶、人际关系紧张的不利局面。

82. 物质待遇和工作条件是人们选择工作的重要因素之一,这次报考谈一谈你在选择工作时都考虑哪些因素?为什么?

回答提示:
好:既能够坦率承认在择业过程中的个人利益因素,又能够超越物质利益因素,有正确的择业观,积极向上,叙述有条理,具有说服力。
中:基本能够正视现实,实事求是地考虑择业问题,叙述问题基本清楚,有一定说理性。差:隐瞒自己的真实想法,假、大、空,或者过分注重自己的个性需求,叙述无条理,说理性差。

83. 直接领导要求你在30日内完成一项工作,你会怎样去完成?

回答提示:提前做准备,制订完备的计划,会准时甚至更早地完成工作任务。

84. 你认为这份工作最重要的是什么?

回答提示:叙述工作特性的同时,也要加上自己的看法,如果是有工作经验的人,最好说明自己的基本心态。

85. 上班的时候,往往有多件事需要你处理,你会如何安排?

回答提示:事有三件,紧要处着手。要先处理重要事件,其他依次统筹安排

86. 找这份工作,你最重要的考虑因素为何?

回答提示:如回答:工作的性质是否能让我发挥所长,并不断成长。.因为公司要找工作表现好、能够真正有贡献的人,而非纯粹慕名、求利而来的人。

87. 在你参加我们这次面试前,你做了哪些准备工作?

回答提示:公司的背景知识及岗位要求;可能要问的问题(技术+技巧);调整状态、保持一颗平常心等
88. 你争取成功的动力是什么?
回答提示:自我实现,展现自身的价值。

89. 怎样理解团队?请举例并说明启示。

回答提示:团队成员共同承担领导职能,共同努力,以各自独特的方式,在所处的环境中共同完成预先设定的目标。(明确的目标、勇于负责、协作增效、能力资源各异)
例如:大雁团队,其合作精神体现在以下几个方面:
①大雁会共同拍动翅膀.。拍翅膀是大雁的本能,但只要排成人字队形,就可以提高飞行效率。
② 所有的大雁都愿意接受团体的飞行队形,而且都实际协助队形的建立。如果有一只大雁落在队形外面,它很快就会感到自己越来越落后,便会立即回到雁群中。
③ 大雁的领导工作是由群体共同分担的。虽然有带头雁出来整队,但是当它疲倦时,便会自动退到队伍之中,另一只大雁马上替补领头的位置。
④ 队形后边的大雁不断发出鸣叫,目的是为了给前方的伙伴打气激励。
⑤ 如果一只大雁生病或被猎人击伤,雁群中就会有两只大雁脱离队形,靠近这只遇到困难的同伴,协助它降落在地面上,直至它能够重回群体,或是不幸死亡。
通过分析大雁的合作行为,我们可以得出以下启示:
① 每个人都要忠诚于自己的团队,忠诚于自己的事业,做好自己的本职工作。如果你不拍翅膀,他不拍翅膀,这个团体还会存在吗?
② 如果我们与大雁一样聪明的话,我们就会留在与自己的事业目标一致的队伍里,而且乐意接受他人的协助,也愿意协助他人。
③ 我们必须确定从背后传来的是鼓励的叫声,而不是其他声音。想要在职业生涯中生存和发展,需要把工作伙伴变成啦啦队,一队快乐的工作伙伴是成功最好的助手。你的工作伙伴散播的有利消息远比你个人所有的努力更有助于你职业生涯的发展

90. 为什么下水道的井盖是圆的?

回答提示:圆的井盖立起来时不会掉到井里。

91.如果你是公司老板,最不喜欢的是哪种员工?

回答提示:遇到问题事不关己、凡事三缄其口、总是墨守城规,没有创新、背后议论上司、随遇而安、追名逐利、拒绝加班、不善交际、既然预定了假期就不可改变。

92. 面试进行时,大脑出现短路怎么办?

回答提示:
① 坦白的讲,我对这个问题不太了解。但我对XX问题倒是有一些研究。我可以讲讲这方面的内容吗?
② 您的意思是;;;?(进一步确认)
③ 不知道您看出来没有,我太重视这次面试,因此有些紧张,您能给我一分种的时间让我考虑一下这个问题好吗.(如果你确信,多给你一些时间,你可以考虑出来)
④ 很坦白的讲,对于这个问题我不太了解。(没有人可以知道所有的知识)
给出解决问题的方法所设计的知识点。(虽然不知道怎么解决,你会按照什么思路解决)

93. 怎样与上级沟通?

回答提示:
① 仔细聆听领导的命令
② 与领导探讨目标的可行性
③ 拟定详细的工作计划
④ 在工作进行之中随时向领导汇报
⑤ 在工作完成后及时总结汇报

95. 你为什么觉得自己能够在这个职位上取得成就?

回答提示:分析这是一个相当宽泛的问题,它给求职者提供了一个机会,可以让求职者表明自己的热情和挑战欲。对这个问题的回答将为面试人在判断求职者是否对这个职位有足够的动力和自信心方面提供关键信息。
错误回答:我不知道。我擅长做很多事情。如果我能得到并且决定接受这份工作,我确信自己可以把它做得相当好,因为我过去一直都很成功。
正确回答:从我的经历来看,这是我的职业生涯中最适合我的一份工作。几年来,我一直在研究这个领域并且关注贵公司,一直希望能有这样的面试机会。我拥有必备的技能(简单讲述一个故事来加以说明),我非常适合这一职位,也确实能做好这份工作。

96. 你最大的长处和弱点分别是什么?这些长处和弱点对你在企业的业绩会有什么样的影响?

回答提示:这个问题的最大陷阱在于,第一个问题实际上是两个问题,而且还要加上一个后续问题。这两个问题的陷阱并不在于你是否能认真地看待自己的长处,也不在于你是否能正确认识自己的弱点。记住,你的回答不仅是向面试人说明你的优势和劣势,也能在总体上表现你的价值观和对自身价值的看法。
错误回答:从长处来说,我实在找不出什么突出的方面,我认为我的技能是非常广泛的。至于弱点,我想,如果某个项目时间拖得太久,我可能会感到厌倦。
正确回答:从长处来说,我相信我最大的优点是我有一个高度理性的头脑,能够从混乱中整理出头绪来。我最大的弱点是,对那些没有秩序感的人,可能缺乏足够的耐心。我相信我的组织才能可以帮助企业更快地实现目标,而且有时候,我处理复杂问题的能力也能影响我的同事。
评论这个回答做到了一箭三雕.。首先,它确实表明了求职者的最大长处。其次,它所表达的弱点实际上很容易被理解为长处。最后,它指出了这个求职者的长处和弱点对企业和其他员工的好处。

97. 请谈谈你个人的最大特色。

回答提示:我的坚持度很高,事情没有做到一个令人满意的结果,绝不罢手。这种回答,最能和工作结合,能够与工作表现相结合的优点、特质,才是面谈者比较感兴趣的回答。

98. 关于你的个人隐私(是否有男/女朋友,或是否结婚)

回答提示:在大多数情况下,面谈者会竭力地打探证明你不稳定或不可靠的信息,还有其他一些可能使某个雇主关注的问题,这些只是对某些性格的人的推测,都是些不相关的问题,但是,如果雇主想以此来了解你是否可靠,你就得全力以赴地去应付了。要记住即使是随意地闲谈也要避免提及隐晦的问题。在回答个人情况时,要态度友好而且自信。

99.你能简述一下XX岗位工作流程吗

100.你能讲述一下你过去工作的基本职责吗

101.你怎样评价上一家公司




JAVA 技能面试项目常谈问题

开场白——模棱两可没把握的不要写,切勿给自己挖坑!

至于是说老师,面试官还是考官,因自己个人情况而异;

一、简短版

  1.        (各位)老师好,我叫XXX,来应聘JAVA开发工作岗位,今年XX岁,20XX年毕业于XXX大学,在校期间积极参与项目活动,从中学到一些实用的开发经验和积累了一些个人心得;本人性格温和,谦虚,有较强的社会适应能力和一定的抗压能力,也能快速的融入团队开发工作中,所以希望能够加入贵公司,一起努力奋斗,共创辉煌,谢谢!

  2.        (各位)老师好,大家好,我叫XXX,毕业于XXX大学,在校期间曾担任XX。我来应聘的是职位是JAVA开发工程师。我所拥有的是年轻和知识。年轻也许意味着欠缺经验,但是年轻也意味着热情和活力,我自信能凭自己的能力和学识在毕业以后的工作和生活中克服各种困难,不断实现自我的人生价值和追求的目标。

  3.        (各位)老师好,我叫XXX,我来应聘的是职位是JAVA开发工程师。我是一个性格开朗、自信,不轻易服输的人。生活中我喜欢与人交往,通过与各种朋友相处,学习到了很多自身缺乏的优点。在学习上我积极认真,努力掌握专业知识,现在已经具有相关的办公室事务管理、文书拟写与处理公共关系策划与活动组织等能力。


二、简短项目版

  1.        (各位)老师好,我叫XXX,毕业于XXX大学,今年XX岁,从事JAVA开发已有X年,参与了(简历上的项目名称)等项目开发,主要负责(简历项目上拿手的业务,HOLD住的话就谈亮眼的地方)等业务,在项目中也积累了一些个人开发心得和经验,

三、加长带项目版—(涉及内容过多,if you really hold 住)

  1.        (各位)老师好,我叫XXX,今年XX岁,今天来面试贵公司JAVA开发工程师,之前在(曾经工作的公司)任职,主要的任务是(1、与项目经理到客户现场沟通并确认需求,2、参与需求文档的编写,3、后端业务模块的逻辑实现…根据面试岗位需求针对性回答),从事这一行已经有X年。这X年的开发主要涉及(项目领域)等,在开发过程中,也用过些好的框架,如(dubbo+zk,springboot,mvc,spring…)等框架,熟练掌握框架之间的整合技术;有时候因为项目需求或是为了开发的高效性,自己也会研究一些技术,使用一些常用的主流java技术,例如:(你觉得什么牛皮就吹什么);闲暇时喜欢钻研感兴趣的技术,例如(数据结构中的什么,什么算法,架构思想等等),并把自己研究的过程以及心得与同事分享交流,因为我一直坚信一个人的能力是有限的,只有团队协作才会给公司带来更大的价值;
           我承认自己还不是最优秀的人才,但是我希望自己是此岗位最合适的人选,希望有幸能够被贵公司领导予以特别考虑。今后我在好的方面再接再厉,不足之处有所改善。我的介绍到此结束。谢谢!


技能部分

基础知识(有待归类)

1 什么是字符串常量池?
创建字符串的方式

String str = new String("hello");
String str = "hello";

使用相同的字符序列而不是使用new关键字创建的两个字符串会创建指向Java字符串常量池中的同一个字符串的指针。字符串常量池是Java节约资源的一种方式

字符串常量池: JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为 了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中, 就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。Java能够进行这样的优化是因为字符串是不可变的,可以不用担心数据冲突 进行共享;每一个字符串常量都是指向一个字符串类实例的引用。字符串对象有一个固定值。字符串常量,或者一般的说,常量表达式中的字符串都被使用方法 String.intern进行保留来共享唯一的实例;

2 String为什么是不可变的?
不可变的是什么: 指的是字符串的值不可变;
为什么不可变: 从源码来看, String类内部是用char数组来保存字符串的值, 并且char[]是final的,所以value必须在构造时为其赋值,
赋值后value的引用不能再变

3 String s = new String(“xyz”);究竟产生了几个对象,从JVM角度谈谈?
jvm 首先在 string 池内里面看找不找得到字符串 , 如果找得到, 不做任何事情,
否则的话就会创建新的 string 对象,放到 string 池里面。
由于遇到了 new,还会在内存上(不是 string 池里面)创建 string 对象存储;

所以总共是 1个 或者 2个对象

  1. 首先在 string 池内找,找到了,不创建 string 对象,否则创建一个对象;【这里创建0个或1个】
  2. 遇到 new 运算符号了,在内存上创建 string 对象,并将其返回给 s,又一个对象;【这里创建1个】

new String(…)创建了第二个对象

4 String拼接字符串效率低,你知道原因吗?
String的+在编译后会被编译为StringBuilder来运行,如果你对JVM有所了解,凡是new出来的对象绝对不会放在常量池中,toString会发生一次内容拷贝,但是也不会在常量池中,所以在这里常量池String+放在了堆中;每做一次"+"就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后append字符串,如此循环直至结束。如果我们直接采用StringBuilder对象进行append的话,我们可以节省创建和销毁对象的时间。

如果只是简单的字面量拼接或者很少的字符串拼接,性能都是差不多的。

5 你真的了解String的常见API吗?

6 Java中的subString()真的会引起内存泄露么?
1 这个bug发生在jdk1.6版本,bai后续修复了du。原因是比如我们有一个1G的字符串a,我们使用substring(0,2)得到了一个只有两个字符的字符串b,如果b的生命周期要长于a或者手动设置a为null,当垃圾回收进行后,a被回收掉,b没有回收掉,那么这1G的内存占用依旧存在,因为b持有这1G大小的字符数组的引用。
2 所以推荐的方式是substring中生成的字符串与原字符串共享内容数组,这样避免了每次进行substring重新进行字符数组复制。
3 jdk1.7之后substring的实现抛弃了之前的内容字符数组共享的机制,对于子字符串(自身除外)采用了数组复制实现单个字符串持有自己的应该拥有的内容来避免内存泄漏。

7 浅析Java中的final关键字?
1 修饰类
当用final修饰一个类时,表明这个类不能被继承。但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

2 修饰方法
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。
 注:类的private方法会隐式地被指定为final方法。

3 修饰变量(包括成员变量和局部变量)
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

8 浅析Java中的static关键字?
1 在Java中static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰代码块;
2 在JVM加载一个类的时候,若该类存在static修饰的成员变量和成员方法,则会为这些成员变量和成员方法在固定的位置开辟一个固定大小的内存区域(只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们);
3 同时被static修饰的成员变量和成员方法是独立于该类的,它不依赖于某个特定的实例变量,也就是说它被该类的所有实例共享。所有实例的引用都指向同一个地方,任何一个实例对其的修改都会导致其他实例的变化。

静态变量:
 static修饰的变量我们称之为静态变量,没有用static修饰的变量称之为实例变量,他们两者的区别是:
 静态变量是随着类加载时被完成初始化的,它在内存中仅有一个,且JVM也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问它。但是实例变量则不同,它是伴随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死。
 所以我们一般在这两种情况下使用静态变量:对象之间共享数据、访问方便。

静态方法:
 static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。
  但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
   因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。

总结一下,对于静态方法需要注意以下几点:
 (1)它们仅能调用其他的static 方法。
 (2)它们只能访问static数据。
 (3)它们不能以任何方式引用this 或super。

静态代码块:
 static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次;
 特性:只会在类加载的时候执行一次;

9 你对Java中的volatile关键字了解多少?
VOLATILE关键字:保证内存模型中的可见性与有序性,不保证原子性;
 可见性 : 是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果,另一个线程马上就能看到。
 有序性 :
 原子性 :
为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。

12 请谈谈什么是CAS?
一种高效实现线程安全性的方法
支持原子更新操作,适用于计数器,序列发生器(就是给变量自增的工具)等场景
属于乐观锁机制,号称lock-free(底层也是有加锁行为的)
CAS操作失败是,由开发者决定是否继续尝试,还是其他操作,因此争用CAS失败的线程不会被阻塞挂起;

CAS思想:
包含三个操作数——内存位置(V)、预期原值(A)和新值(B):当一个线程需要修改一个共享变量的值,完成这个操作需要先取出共享变量的值,赋给A,基于A进行计算,得到新值B,在用预期原值A和内存中的共享变量值进行比较(这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成),如果相同就认为其他线程没有进行修改,而将新值写入内存;

CAS的缺点:
1 CPU开销比较大:在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,又因为自旋的时候会一直占用CPU,如果CAS一直更新不成功就会一直占用,造成CPU的浪费。

2 不能保证代码块的原子性:CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。

3 ABA问题:线程1从内存X中取出A,这时候另一个线程2也从内存X中取出A,并且线程2进行了一些操作将内存X中的值变成了B,然后线程2又将内存X中的数据变成A,这时候线程1进行CAS操作发现内存X中仍然是A,然后线程1操作成功。虽然线程1的CAS操作成功,但是整个过程就是有问题的。

CAS引起的ABA问题:
比如说我要取100,但是由于机器故障开启了两次取钱的线程,由于采用的是CAS操作,线程一如果执行成功,而线程二由于某些原因阻塞了,并且在这个阶段中有其他用户向我的账户中转了50元,并且该线程执行成功,那么线程二恢复的时候,会发现地址的值V=100,线程二比较V、A发现相同,就更新余额为50.这样就发生错误。

CAS的ABA问题解决方案:
不是只是更新某个引用的值, 而是更新两个值,包含一个引用和一个版本号。
AtomicStampedReference以及AtomicMarkableReference支持在两个变量上执行原子的条件更新。
AtomicStampedReference将更新一个“对象引用——版本号”二元组,通过在引用上加上“版本号”,从而避免ABA问题(reference——stamp)
AtomicMarkableReference将更新一个“对象引用——布尔值”二元组,在某些算法中将通过这种二元组使节点保存在链表中同时又将其标记为“已删除节点”(reference——mark)

List Set 与Map的区别
一、List接口
List是一个继承于Collection的接口,即List是集合中的一种。List是有序的队列,List中的每一个元素都有一个索引;第一个元素的索引值是0,往后的元素的索引值依次+1。和Set不同,List中允许有重复的元素。实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

(1)ArrayList
ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量:

private static final int DEFAULT_CAPACITY = 10;

随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。

ArrayList擅长于随机访问。同时ArrayList是非同步的。

(2)LinkedList
同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。

由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端,节约一半时间)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。

与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:

List list = Collections.synchronizedList(new LinkedList(…));

(3)Vector
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

(4)Stack
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

二、Set接口
Set是一个继承于Collection的接口,Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,关于API方面。Set的API和Collection完全一样。实现了Set接口的集合有:HashSet、TreeSet、LinkedHashSet、EnumSet。

(1)HashSet
HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。集合元素可以是null,但只能放入一个null。它内部元素的顺序是由哈希码来决定的,所以它不保证set的迭代顺序;特别是它不保证该顺序恒久不变。

(2)TreeSet
TreeSet是二叉树实现的,基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现,不允许放入null值。它是使用元素的自然顺序对元素进行排序,或者根据创建Set时提供的 Comparator 进行排序,具体取决于使用的构造方法。

(3)LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

三、Map接口
Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。实现map的集合有:HashMap、HashTable、TreeMap、WeakHashMap。

(1)HashMap
以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。

(2)HashTable
也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式。HashTable继承Dictionary类,实现Map接口。其中Dictionary类是任何可将键映射到相应值的类(如 Hashtable)的抽象父类。每个键和每个值都是一个对象。在任何一个 Dictionary 对象中,每个键至多与一个值相关联。Map是”key-value键值对”接口。 HashTable采用”拉链法”实现哈希表不过性能比HashMap要低。

(3)TreeMap
有序散列表,实现SortedMap接口,底层通过红黑树实现。

(4)WeakHashMap
谈WeakHashMap前先看一下Java中的引用(强度依次递减)

强引用:普遍对象声明的引用,存在便不会GC
软引用:有用但并非必须,发生内存溢出前,二次回收
弱引用:只能生存到下次GC之前,无论是否内存足够
虚引用:唯一目的是在这个对象被GC时能收到一个系统通知
以弱键实现的基于哈希表的Map。在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除,因此,该类的行为与其他的 Map 实现有所不同。null值和null键都被支持。该类具有与HashMap类相似的性能特征,并具有相同的效能参数初始容量和加载因子。像大多数集合类一样,该类是不同步的。

四、总结
1、List、Set都是继承自Collection接口,Map则不是
2、List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复,重复元素会覆盖掉,(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的,加入Set 的Object必须定义equals()方法 ,另外list支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。)
3、Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
4、Map适合储存键值对的数据
5、线程安全集合类与非线程安全集合类 :
LinkedList、ArrayList、HashSet是非线程安全的,Vector是线程安全的;
HashMap是非线程安全的,HashTable是线程安全的;
StringBuilder是非线程安全的,StringBuffer是线程安全的。

13 从源码角度看看ArrayList的实现原理?
添加元素是一个一个添加的,当添加元素的时候,发现装不下了,才会进行扩容,扩容后的数组长度是原来的 1.5 倍。

特点:
1 快速随机访问
2 允许存放多个null元素
3 底层是Object数组
4 增加元素个数可能很慢(可能需要扩容),删除元素可能很慢(可能需要移动很多元素),改对应索引元素比较快

总结
1 底层是Object数组存储数据;
2 扩容机制:默认大小是10,扩容是扩容到之前的1.5倍的大小,每次扩容都是将原数组的数据复制进新数组中. 我的领悟:如果是已经知道了需要创建多少个元素,那么尽量用new ArrayList<>(13)这种明确容量的方式创建ArrayList.避免不必要的浪费;
3 添加:如果是添加到数组的指定位置,那么可能会挪动大量的数组元素,并且可能会触发扩容机制;如果是添加到末尾的话,那么只可能触发扩容机制;
4 删除:如果是删除数组指定位置的元素,那么可能会挪动大量的数组元素;如果是删除末尾元素的话,那么代价是最小的. ArrayList里面的删除元素,其实是将该元素置为null;
5 查询和改某个位置的元素是非常快的( O(1) );

14 手写LinkedList的实现,彻底搞清楚什么是链表?

15 Java中方法参数的传递规则?

16 Java中throw和throws的区别是什么?

17 重载(Overload) 和重写(Override)的区别?
1.重写必须继承,重载不用。
2.重写的方法名,参数数目相同,参数类型兼容,重载的方法名相同,参数列表不同
3.重写的方法修饰符大于等于父类的方法,重载和修饰符无关。
4.重写不可以抛出父类没有抛出的一般异常,可以抛出运行时异常
18 手写ArrayList的实现,在笔试中如何过关斩将?

19 finally语句块你踩过哪些坑?

20 为什么重写equals方法需同时重写hashCode方法?

21 equals() 与 == 的区别?
在Java中,equals方法被认为是对象的值进行深层次的比较,而操作符==是进行的浅层次的比较。 equals方法比较两个对象的内容而不是引用。==两侧是引用类型(例如对象)时,如果引用是相同的-即指向同一个对象-则执行结果为真。如果是值类型 (例如原生类型),如果值相同,则执行结果为真。equals方法在两个对象具有相同内容时返回真-但是,java.lang.Object类中的 equals方法返回真-如果类没有覆盖默认的equals方法,如果两个引用指向同一个对象;

22 String StringBuffer和StringBuilder的区别,从源码角度分析?
(1)String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁(底层使用 final char[]存储,因此String中的字符内容不可变);
(2)StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。所以说StringBuffer对象是一个字符序列可变的字符串,它没有重新生成一个对象,而且在原来的对象中可以连接新的字符串;
(3)StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高;

23 HashMap
1 底层数组+链表实现,可以存储null键和null值,线程不安全
2 初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂
3 扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
4 插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)
5 当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀
6 计算index方法:index = hash & (tab.length – 1)

23 你知道HashMap的数据结构吗?
通常在我们的应用中,HashMap是用到最多的数据结构之一,在JDK1.8之前,它的底层结构是数组+链表,而在JDK1.8之后,为了查询效率的优化(主要是当哈希碰撞较多的时候),它的底层结构变成了数组+链表+红黑,以增强查询效率;

简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,
也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry;Entry就是数组中的元素,每个 Map.Entry 其实就是一个key-value对,它持有一个指向下一个元素的引用,这就构成了链表。

HashMap遍历方式:

Map map = new HashMap();
  Iterator iter = map.entrySet().iterator();
  while (iter.hasNext()) {
  Map.Entry entry = (Map.Entry) iter.next();
  Object key = entry.getKey();
  Object val = entry.getValue();
  }

HashMap如何将数据存入
当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标), 如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上;
24 为何HashMap的数组长度一定是2的次幂?

25 HashMap何时扩容以及它的扩容机制?
什么时候扩容:
1、 存放新值的时候当前已有元素的个数必须大于等于阈值
2、 存放新值的时候当前存放数据发生hash碰撞(当前key计算的hash值换算出来的数组下标位置已经存在值)

HashMap使用的是懒加载,构造完HashMap对象后,只要不进行put 方法插入元素之前,HashMap并不会去初始化或者扩容table。当首次调用put方法时,HashMap会发现table为空然后调用resize方法进行初始化,当添加完元素后,如果HashMap发现size(元素总数)大于threshold(阈值),则会调用resize方法进行扩容;

扩容过程:
(1)若threshold(阈值)不为空,table的首次初始化大小为阈值,否则初始化为缺省值大小16;
(2)默认的负载因子大小为0.75,当一个map填满了75%的bucket时候,就会扩容,扩容后的table大小变为原来的两倍;
(3)假设扩容前的table大小为2的N次方,有上述put方法解析可知,元素的table索引为其hash值的后N位确定;
(4)扩容后的table大小即为2的N+1次方,则其中元素的table索引为其hash值的后N+1位确定,比原来多了一位;
(5)重新调整map的大小,并将原来的对象放入新的bucket数组中。这个过程叫作rehashing;

26 HashMap的key一般用字符串,能用其他对象吗?

27 HashMap的key和value都能为null么?如果key能为null,那么它是怎么样查找值的?

29 从源码角度分析HashSet实现原理?

30 HashTable与HashMap的实现原理有什么不同?

31 String方法intern() 你真的会用吗?

32 什么是自动拆装箱?

33 String.valueOf和Integer.toString的区别?

34 反射原理,反射创建类实例有哪几种方式?

35 反射中 Class.forName和ClassLoader区别

36 有没有顺序的Map实现类,如果有,它们是怎么保证有序的

37 描述动态代理的几种实现方式,分别有哪写优缺点

38 泛型的存在是用来解决什么问题的

39 Java中的HashSet内部是如何工作的

41 SpringAOP实现原理

42 Spring怎么配置事务(具体说一些关键的XML元素)

43 SpringMVC中DispatcherServlet初始化过程

44 Lock和Synchronized区别
(1)来源:lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现;
(2)异常是否释放锁:synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。)
(3)是否响应中断:lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断;
(4)是否知道获取锁:Lock可以通过trylock来知道有没有获取锁,而synchronized不能;
(5)Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)
(6)在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
(7)synchronized使用Object对象本身的wait 、notify、notifyAll调度机制,而Lock可以使用Condition进行线程之间的调度,
45 Spring的controller是单例还是多例,怎么保证并发安全的

46 你所了解的几种简单的HASH算法

47 如何将已经构建好的TreeSet完成倒排序

48 数据库隔离级别有哪些,各自含义是什么,Mysql默认的隔离级别是什么

49 聚集索引和非聚集索引的区别是什么

50 final,finally,finalize的区别?

51 &和&&的区别?

19 两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?

不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同。Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;(2)如果两个对象的hashCode相同,它们并不一定相同。当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降);

20 try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行

21 swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

22 构造器Constructor是否可被override?

23 是否可以继承String类?

24 数组有没有length()这个方法?String有没有length()这个方法?

25 abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

26 接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类(concreteclass)?

28 Java有没有goto?

30 什么时候用assert?

33 运行时异常与一般异常有何异同?

34 int和Integer有什么区别?

35 List,Set,Map是否继承自Collection接口?

36 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?用contains来区分是否有重复的对象,还是都不用。

37 Collection和Collections的区别。

38 说出ArrayList,Vector,LinkedList的存储性能和特性HashMap和Hashtable的区别


JVM

1 谈谈你对JVM调优的理解
JVM内存的调优主要的目的是减少Minor GC的频率和Full GC的次数,过多的Minor GC和Full GC是会占用很多的系统资源,影响系统的吞吐量。

**Full GC:**会对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比较慢,因此应该尽可能减少Full GC的次数。

原则上:
大多数的java应用不需要GC调优
大部分需要GC调优的的,不是参数问题,是代码问题
在实际使用中,分析GC情况优化代码比优化GC参数要多得多;
GC调优是最后的手段

导致Full GC的原因:
(1)老年代(Tenured)被写满
调优时尽量让对象在新生代GC时被回收、让对象在新生代多存活一段时间和不要创建过大的对象及数组避免直接在旧生代创建对象 。
(2)持久代(永久代)Pemanet Generation空间不足
增大Perm Gen空间,避免太多静态对象 , 控制好新生代和旧生代的比例
(3)System.gc()被显示调用
垃圾回收不要手动触发,尽量依靠JVM自身的机制

常用的性能优化手段
避免过早优化:不应该把大量的时间耗费在小的性能改进上,过早考虑优化是所有噩梦的根源;

前端优化常用手段
1 使用客户端缓冲: 静态资源文件(css、图标等)缓存在浏览器中,需要更新,则通过改变文件名来解决。
2 启用压缩: 减少网络传输量,但会给浏览器和服务器带来性能的压力,需要权衡使用。
3 资源文件加载顺序: css放在页面最上面,js放在最下面。这样页面的体验才会比较好。浏览器会加载完CSS才会对页面进行渲染。JS只要加载后就会立刻执行;
4 减少Cookie传输: cookie包含在每次的请求和响应中,因此哪些数据写入cookie需要慎重考虑;
5 CDN加速: CDN,又称内容分发网络,本质是一个缓存,而且是将数据缓存在用户最近的地方。无法自行实现CDN的时候,可以根据经济实力考虑商用CDN服务。
6 反向代理缓存: 将静态资源文件缓存在反向代理服务器上,一般是Nginx。
7 WEB组件分离: 将js,css和图片文件放在不同的域名下。可以提高浏览器在下载web组件的并发数。因为浏览器在下载同一个域名的的数据存在并发数限制。
应用服务性能优化:
1 缓存: 网站性能优化第一定律:优先考虑使用缓存优化性能;优先原则:缓存离用户越近越好;缓存是将数据存在访问速度较高的介质中。可以减少数据访问的时间,同时避免重复计算。频繁修改的数据,尽量不要缓存,读写比2:1以上才有缓存的价值。
2 一致性哈希:
(1)首先求出服务器(节点)的哈希值,并将其配置到0~2的32次方的圆(continuum)上。
(2)然后采用同样的方法求出存储数据的键的哈希值,并映射到相同的圆上。
(3)然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2^32仍然找不到服务器,就会保存到第一台服务器上。
一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。
3 数据倾斜:
集群:
1 异步:
同步和异步,阻塞和非阻塞:
同步和异步关注的是结果消息的通信机制
同步:同步的意思就是调用方需要主动等待结果的返回
异步:异步的意思就是不需要主动等待结果的返回,而是通过其他手段比如,状态通知,回调函数等。
阻塞和非阻塞主要关注的是等待结果返回调用方的状态
阻塞:是指结果返回之前,当前线程被挂起,不做任何事
非阻塞:是指结果在返回之前,线程可以做一些其他事,不会被挂起。

1)同步阻塞:同步阻塞基本也是编程中最常见的模型,打个比方你去商店买衣服,你去了之后发现衣服卖完了,那你就在店里面一直等,期间不做任何事(包括看手机),等着商家进货,直到有货为止,这个效率很低,jdk里的BIO就属于 同步阻塞。
2)同步非阻塞:同步非阻塞在编程中可以抽象为一个轮询模式,你去了商店之后,发现衣服卖完了,这个时候不需要傻傻的等着,你可以去其他地方比如奶茶店,买杯水,但是你还是需要时不时的去商店问老板新衣服到了吗。jdk里的NIO就属于 同步非阻塞
3)异步阻塞:异步阻塞这个编程里面用的较少,有点类似你写了个线程池,submit然后马上future.get(),这样线程其实还是挂起的。有点像你去商店买衣服,这个时候发现衣服没有了,这个时候你就给老板留给电话,说衣服到了就给我打电话,然后你就守着这个电话,一直等着他响什么事也不做。这样感觉的确有点傻,所以这个模式用得比较少。
4)异步非阻塞:好比你去商店买衣服,衣服没了,你只需要给老板说这是我的电话,衣服到了就打。然后你就随心所欲的去玩,也不用操心衣服什么时候到,衣服一到,电话一响就可以去买衣服了。jdk里的AIO就属于异步。

常见异步的手段:
1 Servlet异步:servlet3中才有,支持的web容器在tomcat7和jetty8以后。
2 多线程
3 消息队列

调优是个很复杂、很细致的过程,要根据实际情况调整,不同的机器、不同的应用、不同的性能要求调优的手段都是不同的。也没有一个放之四海而皆准的配置或者公式。即使是jvm参数也是如此,再比如说性能有关的操作系统工具,和操作系统本身相关的所谓大页机制,都需要平时去积累,去观察,去实践。



2 JVM内存区域如何划分?

最常谈到的区域:
(1)方法区: 这也是所有线程共享的一块内存区域,用于存储对象的类型数据,例如类结构信息,静态变量,以及常量池、字段、方法代码等。JVM对永久代垃圾回收(如,常量池回收、对象类型的卸载)非常不积极,所以当我们不断添加新类型的时候,永久代会出现OutOfMemoryError,尤其是在运行时存在大量动态类型生成的场合;类似Intern字符串缓存占用太多空间,也会导致OOM问题;
(2)JAVA堆: Java 堆是被所有线程共享的一块内存区域,在JVM启动时创建,随着JVM的结束而消亡。此内存区域所占的面积最大,他主要是用于存放对象实例,几乎所有的对象实例都在这里分配内存。因此他也是垃圾回收器主要关注的区域,当创建的对象实例特别多导致顿内存空间不够时,此区域会发上OOM异常。堆内空间还会被不同的垃圾收集器进行进一步的细分,最有名的就是新生代、老年代的划分。
(3)本地方法栈: 它和Java虚拟机栈的内存机制相同,本地方法栈则是为执行本地方法(Native Method)服务的。
(4)JAVA虚拟机栈: 每个线程在创建时都会创建一个虚拟机栈,因此它是线程私有的,其内部保存一个个的栈帧,对应着一次次的Java方法调用。当有方法调用的时候就会将方法封装到一个栈帧中进行压栈,方法执行完成后弹栈,某一时间对应的只会有一个活动的栈帧,通常叫作当前帧,方法所在的类叫作当前类。如果在该方法中调用了其他方法,对应的新的栈帧会被创建出来,成为新的当前帧,一直到它返回结果或者执行结束。在每一个栈帧中都有一个区域存放本地变量表用于存放此方法执行过程所需要的基本类型和对象引用(注:这部分空间是在预编译阶段可预测的)。
(5)程序计数器: 程序计数器是很少的一部分内存空间,它保存的是程序当前执行的指令的地址,当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令;

注:1.8版本取消了老年代,取而代之的是元空间;

还会用到的空间:
(1)直接内存: 并不是虚拟机运行时数据区的一部分,也不是JVM规范中定义的内存区域,但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError 异常出现,所以我们放到这里一起讲解。在JDK 1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用Native 函数库直接分配堆外内存,然后通过一个存储在Java 堆里面的DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java 堆和Native 堆中来回复制数据;
(2)Code Cache : JVM本身是个本地程序,还需要其他的内存去完成各种基本任务,比如,JIT 编译器在运行时对热点方法进行编译,就会将编译后的方法储存在Code Cache里面;GC等功能。需要运行在本地线程之中,类似部分都需要占用内存空间;



3 JVM堆中对象是如何创建的?
步骤:
(1)类加载检查: 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
(2)分配内存: 在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配方式由 Java 堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
(3)初始化零值: 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
(4)设置对象头: 初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。
(5)执行init方法: 在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从 Java 程序的视角来看,对象创建才刚开始,(init) 方法还没有执行,所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 (init)方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。



4 JVM对象的结构?

对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding);

对象头(Header): 记录了对象在运行过程中所需要使用的一些数据:哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳;
对象头可能包含类型指针,通过该指针能确定对象属于哪个类。如果对象是一个数组,那么对象头还会包括数组长度。
实例数据(Instance Data): 实例数据部分就是成 4000 员变量的值,其中包括父类成员变量和本类成员变量。
对齐填充(Padding): 用于确保对象的总长度为 8 字节的整数倍。HotSpot VM(JVM默认虚拟机) 的自动内存管理系统要求对象的大小必须是 8 字节的整数倍。而对象头部分正好是 8 字节的倍数(1 倍或 2 倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。



5 对象访问的定位方式
(1) 句柄访问方式:堆中需要有一块叫做“句柄池”的内存空间,句柄中包含了对象实例数据与类型数据各自的具体地址信息。引用类型的变量存放的是该对象的句柄地址(reference)。访问对象时,首先需要通过引用类型的变量找到该对象的句柄,然后根据句柄中对象的地址找到对象。
(2) 直接指针访问方式:引用类型的变量直接存放对象的地址,从而不需要句柄池,通过引用能够直接访问对象。但对象所在的内存空间需要额外的策略存储对象所属的类信息的地址。

注:HotSpot 采用第二种方式,即直接指针方式来访问对象,只需要一次寻址操作,所以在性能上比句柄访问方式快一倍。但像上面所说,它需要额外的策略来存储对象在方法区中类信息的地址。



5 如何判断一个对象是否存活(如何判断对象是否是垃圾对象)
(1)引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是不能再被引用的。
(2)可达性分析算法: 可达性分析算法的基本思路是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时,则证明此对象是不可用的。

  即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。
  如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中。并在稍后由一个虚拟机自动建立的,低优先级的Finalizer线程去执行它。这里所谓“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果有一个对象在finalize()方法中执行缓慢,或者发生死循环,将可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。
  
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象这个时候,未被重新引用,那它基本上就真的被回收了。



**5 **

6 JVM垃圾回收算法有哪些?

6 垃圾回收的优点和原理

7 JVM垃圾收集器有哪些?

8 JVM内存是如何分配的?

9 分析类的加载过程?

16 描述一下JVM加载class文件的原理机制?

10 JVM双亲委派机制?

11 JVM可以作为GC Root的对象有哪些?

12 请写出几段可以导致内存溢出、内存泄漏、栈溢出的代码?

13 哪些情况会导致Full GC?

14 频繁GC问题或内存溢出问题,如何定位?

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

17 垃圾回收的优点和原理。并考虑2种回收机制。

18 Java中的异常处理机制的简单原理和应用。

39 JVM参数有哪些
-xms: 堆内存的初始化大小
-xmx: 堆内存的最大空间
-xmn: 年轻代的空间
-xx:PermSize 方法区初始化大小
-xx:MaxPermSize 方法区最大空间
-XX:PretenureSizeThreshold 令大于这个设置值的对象直接在老年代分配
-MaxTenuringThreshold :年龄大于这个值的直接进入老年代

29 GC是什么?为什么要有GC?

27 给我一个你最常见到的runtimeexception


多线程及其安全问题


1 (1次)谈谈你对多线程安全问题的理解

怎样才算是线程安全的: 当多个线程访问一个对象时,如果不用进行额外的同步控制或其他的协调操作,调用这个对象的行为都可以获得正确的结果,我们就说这个对象是线程安全的(另一种说法:如果多线程的程序的运行过程和单线程运行的结果一致,则认为它是线程安全的);
如果所有的线程都是读操作,而没有写操作,那么我们可以认为也是线程安全的,如果多个线程读写操作都有的话才会容易产生线程安全问题。这个时候我们就需要采取加锁,同步等手段来解决线程安全问题。
怎样做到线程安全: 实现线程安全的方式有多种,其中在源码中常见的方式是,采用synchronized关键字给代码块或方法加锁,比如StringBuffer(如果是多个线程访问同一个资源,那么就需要上锁,才能保证数据的安全性;这个时候如果使用的是非线程安全的对象,比如StringBuilder,那么就需要借助外力,给他加synchronized关键字。或者直接使用线程安全的对象StringBuffer)
什么时候需要考虑使用线程安全:
(1)多个线程访问同一个资源;
(2)资源是有状态的,比如字符串的拼接,这个时候数据是会有变化的;

2 程序,进程,线程

程序(进程(线程))

程序: 是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码;
进程: 是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等;
线程: 是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响;

3 多线程生命周期包括哪几个阶段

4 多线程有几种实现方式
(1)继承thread
(2)实现runnable
(3)实现callable
(4)使用线程池

5 多线程的分类
用户线程:运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程;

守护线程:运行在后台,为其他前台线程服务;
特点: 一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作;
应用: 数据库连接池中的检测线程,JVM虚拟机启动后的检测线程;
最常见的守护线程: 垃圾回收线程;

可以通过调用 Thead 类的 setDaemon(true) 方法设置当前的线程为守护线程。

5 启动线程是用start()方法还是run()方法?

调用start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start()会执行线程的相应准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。 而直接执行run()方法,会把run方法当成一个mian线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。调用start方法方可启动线程并使线程进入就绪状态,而run方法只是thread的一个普通方法调用,还是在主线程里执行;

6 说说线程安全问题,什么实现线程安全,如何实现线程安全

7 什么是线程阻塞,分别有哪几种阻塞
阻塞: 阻塞状态是指线程因为某种原因放弃了cpu使用权,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。(timeslice:时间片是操作系统分配给每个线程在CPU上计算的时间,并非CPU分配,CPU只管计算)

阻塞的情况分三种:
(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放 入等待队列(waiting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步 锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

7 sychronized和Lock的区别?
(1)来源:lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现;
(2)异常是否释放锁:synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生。(所以最好将同步代码块用try catch包起来,finally中写入unlock,避免死锁的发生。)
(3)是否响应中断:lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断;
(4)是否知道获取锁:Lock可以通过trylock来知道有没有获取锁,而synchronized不能;
(5)Lock可以提高多个线程进行读操作的效率。(可以通过readwritelock实现读写分离)
(6)在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
(7)synchronized使用Object对象本身的wait 、notify、notifyAll调度机制,而Lock可以使用Condition进行线程之间的调度,

8 sleep()和wait()的区别?
(1) 两者最主要的区别在于:sleep方法没有释放锁,而wait方法释放了锁 。
(2) 两者都可以暂停线程的执行。
(3) wait通常被用于线程间交互/通信,sleep通常被用于暂停执行。
(4) wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒。
9 深入分析ThreadLocal的实现原理?

10 你看过AbstractQueuedSynchronizer源码阅读吗,请说说实现原理?

11 谈谈对synchronized的偏向锁、轻量级锁、重量级锁的理解?

12 通过三种方式实现生产者消费者模式?

13 JVM层面分析sychronized如何保证线程安全的?

14 JDK层面分析sychronized如何保证线程安全的?

15 如何写一个线程安全的单例?

16 通过AQS实现一个自定义的Lock?

17 ThreadLocal什么时候会出现OOM的情况?为什么?

18 为什么wait, notify 和 notifyAll这些方法不在thread类里面?

19 你真的理解CountDownLatch与CyclicBarrier使用场景吗?

20 出现死锁,如何排查定位问题?

21 notify和notifyAll的区别?

22 线程池启动线程submit和execute有什么不同?

23 SimpleDateFormat是线程安全的吗?如何解决?

24 请谈谈ConcurrentHashmap底层实现原理?

25 使用synchronized修饰静态方法和非静态方法有什么区别?

26 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其方法?

27 线程池的原理,为什么要创建线程池?创建线程池的方式?

28 创建线程池有哪几个核心参数? 如何合理配置线程池的大小?

29 Synchronized修饰的静态方法和非静态方法有什么区别?

30 什么时候考虑多线程安全;
多个线程访问同一个资源;

31 多线程的安全隐患以及synchronized监视器(锁)

32 怎样保证线程安全
不要跨线程访问共享变量;
使共享变量是final类型的;
使共享变量只读;
将共享变量的操作加上同步;

32 i++是线程安全的吗?如何解决线程安全性?

33 从字节码角度深度解析 i++ 和 ++i 线程安全性原理?

34 HashMap是线程安全的吗?如何实现线程安全?
HashMap并非线程安全,多线程使用时,会导致值覆盖,会导致ConcurrentModificationException错误;如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须保持外部同步。这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用Collections.synchronizedMap方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的非同步访问。

那么在Java中线程安全的map有没有呢?答案是肯定的,有以下几种方式:
HashTable
(1)底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化;
(2)初始size为11,扩容:newsize = olesize*2+1;
(3)计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length;
Synchronized Map

ConcurrentHashMap
(1) 底层采用分段的数组+链表实现,线程安全;
(2) 通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)
(3) Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允 20000 许多个修改操作并发进行,其关键在于使用了锁分离技术;
(4) 有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁;
(5) 扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容;

其中前两种方式是同步加锁的方式,会影响程序运行效率,第三种ConcurrentHashMap是Java 中支持高并发,高吞吐量的hashMap实现。ConcurrnetHashMap是基于线程安全的一个类;

证明类是线程不安全,证明的方法一般有如下几种:

  1. 对象不能安全发布,构造过程逃逸;
  2. 内存的可见性,内容不能及时发布;
  3. 操作不是原子的;
  4. 读写不能同步;
  5. 存在死锁的可能性;

数据库

Mysql与Oracle的区别
(1) 对事务的提交
MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮;
(2) 分页查询
MySQL是直接在SQL语句中写"select… from …where…limit x, y",有limit就可以实现分页;而Oracle则是需要用到伪列ROWNUM和嵌套查询;
(3) 事务隔离级别
MySQL是read commited的隔离级别,而Oracle是repeatable read的隔离级别,同时二者都支持serializable串行化事务隔离级别,可以实现最高级别的
读一致性。每个session提交后其他session才能看到提交的更改。Oracle通过在undo表空间中构造多版本数据块来实现读一致性,每个session查询时,如果对应的数据块发生变化,Oracle会在undo表空间中为这个session构造它查询时的旧的数据块,MySQL没有类似Oracle的构造多版本数据块的机制,只支持read commited的隔离级别。一个session读取数据时,其他session不能更改数据,但可以在表最后插入数据。session更新数据时,要加上排它锁,其他session无法访问数据;
(4) 对事务的支持
MySQL在innodb存储引擎的行级锁的情况下才可支持事务,而Oracle则完全支持事务;
(5) 保存数据的持久性
MySQL是在数据库更新或者重启,则会丢失数据,Oracle把提交的sql操作线写入了在线联机日志文件中,保持到了磁盘上,可以随时恢复;
(6) 并发性
MySQL以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据。虽然InnoDB引擎的表可以用行级锁,但这个行级锁的机制依赖于表的索引,如果表没有索引,或者sql语句没有使用索引,那么仍然使用表级锁;Oracle使用行级锁,对资源锁定的粒度要小很多,只是锁定sql需要的资源,并且加锁是在数据库中的数据行上,不依赖与索引。所以Oracle对并发性的支持要好很多;
(7) 逻辑备份
MySQL逻辑备份时要锁定数据,才能保证备份的数据是一致的,影响业务正常的dml使用,Oracle逻辑备份时不锁定数据,且备份的数据是一致
(8) 复制
MySQL:复制服务器配置简单,但主库出问题时,丛库有可能丢失一定的数据。且需要手工切换丛库到主库。
Oracle:既有推或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出现问题是,可以自动切换备库到主库,但配置管理较复杂。
(9) 性能诊断
MySQL的诊断调优方法较少,主要有慢查询日志。
Oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、sqltrace、tkproof等
(10)权限与安全
MySQL的用户与主机有关,感觉没有什么意义,另外更容易被仿冒主机及ip有可乘之机。
Oracle的权限与安全概念比较传统,中规中矩。
(11)分区表和分区索引
MySQL的分区表还不太成熟稳定。
Oracle的分区表和分区索引功能很成熟,可以提高用户访问db的体验。
(12)管理工具
MySQL管理工具较少,在linux下的管理工具的安装有时要安装额外的包(phpmyadmin, etc),有一定复杂性。
Oracle有多种成熟的命令行、图形界面、web管理工具,还有很多第三方的管理工具,管理极其方便高效。
(13)最重要的区别
MySQL是轻量型数据库,并且免费,没有服务恢复数据。
Oracle是重量型数据库,收费,Oracle公司对Oracle数据库有任何服务。

1 (1次)数据库三范式
1FS:原子性 ,字段数据不可再分;
2FS:唯一性 ,使得每一行 数据具有唯一性,并消除数据之间的部分依赖;
3FS:独立性 ,使得每个字段都独立依赖与主键字段,消除传递依赖;

2 数据库的事务、ACID及隔离级别?

数据库事务:
数据库事务是构成单一逻辑工作单元的操作集合;

基本要素ACID:
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位;
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到;
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账;
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚;

事务的并发问题:

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

MYSQL的事务隔离级别:

事务隔离级别 脏读 不可重复读 幻读
读未提交
不可重复读
可重复读
串行化(serializable)

3 不考虑事务的隔离性,容易产生哪三种情况?
4 数据库连接池原理?
首先为什么要用数据库连接池:因为数据库连接对象的创建比较消耗性能;
1.原理:一般来说,java应用程序访问数据库的过程是:
  ①装载数据库驱动程序;
  ②通过jdbc建立数据库连接;
  ③访问数据库,执行sql语句,处理结果集;
  ④断开数据库连接;

5 什么是BTree?
BTree 即二叉搜索树

B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中;否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字;如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;实际使用的B树都是在原B树的基础上加上平衡算法,即“平衡二叉树”;如何保持B树结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略。常见的平衡二叉树有:AVL,RBT,Treap,Splay Tree。

5 什么是B-Tree?
是一种多路搜索树(并不是二叉的):
1.定义任意非叶子结点最多只有M个儿子;且M>2;
2.根结点的儿子数为[2, M];
3.除根结点以外的非叶子结点的儿子数为[M/2,M];
4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
5.非叶子结点的关键字个数=指向儿子的指针个数-1;
6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
8.所有叶子结点位于同一层;
如:(M=3)

B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

B-树的特性:
1.关键字集合分布在整颗树中;
2.任何一个关键字出现且只出现在一个结点中;
3.搜索有可能在非叶子结点结束;
4.其搜索性能等价于在关键字全集内做一次二分查找;
5.自动层次控制;
由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少利用率,其最底搜索性能为:log2N , 所以B-树的性能总是等价于二分查找(与M值无关),也就没有B树平衡的问题;

6 什么是B+Tree?
B+树是B-树的变体,也是一种多路搜索树:
1.其定义基本与B-树同,除了:
2.非叶子结点的子树指针与关键字个数相同;
3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
5.为所有叶子结点增加一个链指针;
6.所有关键字都在叶子结点出现;
如:(M=3)

B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

B+的特性:
1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
2.不可能在非叶子结点命中;
3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
4.更适合文件索引系统;

小结
(1) B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;
(2) B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;
(3) 所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
(4) B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
7 MySQL数据库索引结构?
B树:
B-树:
B+树:
位图索引:
Hash索引:
索引列会被存储在匹配到的hash bucket里面的表里,这个表里会有实际的数据行指针,再根据实际的数据行指针查找对应的数据行;

概括来说,要查找一行数据或者处理一个where子句,SQL Server引擎需要做下面几件事:
1、根据where条件里面的参数生成合适的哈希函数;
2、索引列进行匹配,匹配到对应hash bucket,找到对应hash bucket意味着也找到了对应的数据行指针(row pointer);
3、读取数据;
哈希索引比起B树索引简单,因为它不需要遍历B树,所以访问速度会更快;

Hash索引的缺点:
1、因为Hash索引比较的是经过Hash计算的值,所以只能进行等式比较,不能用于范围查询;
2、由于哈希值是按照顺序排列的,但是哈希值映射的真正数据在哈希表中就不一定按照顺序排列,所以无法利用Hash索引来加速任何排序操作;
3、不能用部分索引键来搜索,因为组合索引在计算哈希值的时候是一起计算的;
4、当哈希值大量重复且数据量非常大时,其检索效率并没有Btree索引高的;

8 什么是索引?什么条件适合建立索引?什么条件不适合建立索引?
索引: 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍;

索引的类型:
普通索引
这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
创建索引:例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表:例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( […], INDEX [索引的名字] (列的列表) );

唯一性索引
这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。唯一性索引可以用以下几种方式创建:
创建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( […], UNIQUE [索引的名字] (列的列表) );

主键
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( […], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。

全文索引
MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快

适合建立索引:
1.主键自动建立唯一索引;
2.频繁作为查询条件的字段应该创建索引;
3.查询中与其他表有关联的字段,例如外键关系;
4.高并发的情况下一般选择复合索引;
5.查询中统计或者分组的字段;
6.经常增删改的表;
7.查询中排序的字段创建索引将大大提高排序的速度(索引就是排序加快速查找);
8.数据量超过300的表应该有索引;

不适合简历索引:
1.频繁更新的字段不适合创建索引,因为每次更新不单单是更新记录,还会更新索引,保存索引文件;
2.where条件里用不到的字段,不创建索引;
3.表记录太少,不需要创建索引;

Mysql 四种连接

详情参考这里 0

内连接
  inner join 或者 join
外连接
  左连接 left join 或者 left outer join
  右连接 right join 或者 right outer join
  完全外连接 full join 或者 full outer join

左外连接: 左外连接会把左面表中的数据全部取出来,而右边表中的数据,如果有相等的就像是出来,如果没有就补充NULL;

mysql> select * from person left  join card on person.cardid=card.id;
+------+------+--------+------+--------+
| id   | name | cardid | id   | name   |
+------+------+--------+------+--------+
|    1 | 张三 |      1 |    1 | 饭卡   |
|    2 | 李四 |      3 |    3 | 农行卡 |
|    3 | 王五 |      6 | NULL | NULL   |
+------+------+--------+------+--------+

右外连接: 右外连接会把右面表中的数据全部取出来,而左边表中的数据,如果有相等的就像是出来,如果没有就补充NULL;

mysql> select * from person right  join card on person.cardid=card.id;
+------+------+--------+------+--------+
| id   | name | cardid | id   | name   |
+------+------+--------+------+--------+
|    1 | 张三 |      1 |    1 | 饭卡   |
|    2 | 李四 |      3 |    3 | 农行卡 |
| NULL | NULL |   NULL |    2 | 建行卡 |
| NULL | NULL |   NULL |    4 | 工商卡 |
| NULL | NULL |   NULL |    5 | 邮政卡 |
+------+------+--------+------+--------+

内连接: (典型的联接运算,使用像 = 或 <> 之类的比较运算符)。包括相等联接和自然联接。
内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索 students和courses表中学生标识号相同的所有行;内连接查询就是两张表中的数据,通过某个相等的字段进行查询,查询出的结果是两张表都有的数据,即查询两张表的交集;

mysql> select * from person inner join card on person.cardid=card.id;
+------+------+--------+------+--------+
| id   | name | cardid | id   | name   |
+------+------+--------+------+--------+
|    1 | 张三 |      1 |    1 | 饭卡   |
|    2 | 李四 |      3 |    3 | 农行卡 |
+------+------+--------+------+--------+

全连接: Mysql不支持全连接(full join),要想实现全连接,可以使用左外连接和右外连接的并集union进行连接;

mysql> select * from person right  join card on person.cardid=card.id
union
select * from person left join card on person.cardid=card.id;
+------+------+--------+------+--------+
| id   | name | cardid | id   | name   |
+------+------+--------+------+--------+
|    1 | 张三 |      1 |    1 | 饭卡   |
|    2 | 李四 |      3 |    3 | 农行卡 |
| NULL | NULL |   NULL |    2 | 建行卡 |
| NULL | NULL |   NULL |    4 | 工商卡 |
| NULL | NULL |   NULL |    5 | 邮政卡 |
|    3 | 王五 |      6 | NULL | NULL   |
+------+------+--------+------+--------+

注:On后面条件与Where后面条件的区别:
ON条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。
WHERE条件:在有ON条件的SELECT语句中是过滤中间表的约束条件。在没有ON的单表查询中,是限制物理表或者中间查询结果返回记录的约束。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。
从这里可以看出,将WHERE条件移入ON后面是不恰当的。推荐的做法是:
ON只进行连接操作,WHERE只过滤中间表的记录。

总结:
总结一下两表连接查询选择方式的依据:
1、 查两表关联列相等的数据用内连接。
2、 Col_L是Col_R的子集时用右外连接。
3、 Col_R是Col_L的子集时用左外连接。
4、 Col_R和Col_L彼此有交集但彼此互不为子集时候用全外。
5、 求差操作的时候用联合查询。
多个表查询的时候,这些不同的连接类型可以写到一块。例如:
SELECT T1.C1,T2.CX,T3.CY
FROM TAB1 T1
INNER JOIN TAB2 T2 ON (T1.C1=T2.C2)
INNER JOIN TAB3 T3 ON (T1.C1=T2.C3)
LEFT OUTER JOIN TAB4 ON(T2.C2=T3.C3);
WHERE T1.X >T3.Y;

9 索引失效的原因有哪些?如何优化避免索引失效?
10 MySQL如何启动慢查询日志?
11 MySQL如何使用show Profile进行SQL分析?
12 一条执行慢的SQL如何进行优化,如何通过Explain+SQL分析性能?
13 什么是行锁、表锁、读锁、写锁,说说它们各自的特性?
14 什么情况下行锁变表锁?
15 什么情况下会出现间隙锁?
16 谈谈你对MySQL的in和exists用法的理解?
17 MySQL的数据库引擎有哪些,如何确定在项目中要是用的存储引擎?
18 count(*)、count(列名)和count(1)的区别?
19 union和union all的区别?
20 一张表五条记录,分别有三门不同的成绩,用一条sql语句求出每门成绩最高和最低的和对应的学生姓名

详情参考here sql查询成绩表中每一科成绩最高的分数以及这个学生的名字,学科名
SELECT “最高分”,student.*
FROM student ,(SELECT MAX(score) AS score,subject FROM student GROUP BY subject)b
WHERE student.score = b.score
AND student.subject = b.subject
UNION
SELECT “最低分”,student.*
FROM student ,(SELECT MIN(score) AS score,subject FROM student GROUP BY subject)b
WHERE student.score = b.score
AND student.subject = b.subject;


WEB知识

1 什么是Servlet,Servlet生命周期方法?单例还是多例?
Servlet: Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页;

servlet是单例的,严格地说是一个ServletMapping对应一个单例实例(如果一个Servlet被映射了两个URL地址,会生成两个实例)。早期的CGI模式是原型式的,例如同时并发2000次请求一个Servlet,如果不是单例的,内存瞬间要创建2000个对象,同时为了线程安全还得阻塞对方线程,其性能非常之差。
要维护Servlet线程安全有很多办法,通常是使用同步块(或方法)来保护共享数据,其次可以volatile、Lock一些锁机制,还可以使用ThreadLocal来打通安全通道,另外还有原子操作也是用来保护数据安全,有非常多的选择。

生命周期: Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

(1)Servlet 通过调用 init () 方法进行初始化。
(2)Servlet 调用 service() 方法来处理客户端的请求。
(3)Servlet 通过调用 destroy() 方法终止(结束)。
(4)最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

扩展:
init(): init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

service(): service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。doGet() 和 doPost() 方法是每次服务请求中最常用的方法。

destroy(): destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。

2 什么Session和Cookie,它们之间有什么联系?

**Session(会话跟踪):**指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。
session共享:
对于多网站(同一父域不同子域)单服务器,我们需要解决的就是来自不同网站之间SessionId的共享。由于域名不同(aaa.test.com和bbb.test.com),而SessionId又分别储存在各自的cookie中,因此服务器会认为对于两个子站的访问,是来自不同的会话。解决的方法是通过修改cookies的域名为父域名达到cookie共享的目的,从而实现SessionId的共享。带来的弊端就是,子站间的cookie信息也同时被共享了。

常用的会话跟踪技术:session和cookie——Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。客户端浏览器再次访问服务端时只需要从该Session中查找该客户的状态就可以了。

Cookie : Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

**cookie主要内容包含:**名字,值,过期时间,路径和域(路径和域一起构成cookie的作用范围);

HttpCookie cookie = new HttpCookie("MyCook");//初使化并设置Cookie的名称
DateTime dt = DateTime.Now;
TimeSpan ts = new TimeSpan(0, 0, 1, 0, 0);//过期时间为1分钟
cookie.Expires = dt.Add(ts);//设置过期时间
cookie.Values.Add("userid", "value");
cookie.Values.Add("userid2", "value2");
Response.AppendCookie(cookie);

**会话Cookie:**若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。

**持久Cookie:**若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在浏览器的不同进程间共享。

Cookie具有不可跨域名性: cookie不可跨浏览器,例如访问百度不会带上Google的Cookie;

总结:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。

3 JSP的八个隐含对象有哪些?

4 JSP的四个域对象的作用范围?

5 Post和Get请求的区别?

GET和POST是什么:HTTP协议中的两种发送请求的方法;
HTTP又是什么:HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议;

1.安全性:Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的;
2.数据量: Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制;
3.字符: Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集
4. 效率:Get执行效率却比Post方法好。Get是form提交的默认方法;
5. GET产生一个TCP数据包;POST产生两个TCP数据包;

6 转发和重定向有什么区别?

7 JSP自定义标签,如何实现循环打印功能?

8 Http1.0和Http1.1的区别是什么?

10 (1次)HTTP中的TCP三次握手

三次握手主要是规避网络传输当中延迟而导致服务器开销的一些问题
第一次:客户端发送一个TCP的SYN标志位置1的包指明发送的服务器端口,以及初始化序号 X(客户端什么都不确定。服务端确认对方发送正常)
第二次:服务器返回确认包ACK应答,及SYN标志位和ACK标志位均为1,同时将确认序号设置为 X+1(客户端发送/接受正常,对方发送接收正常。服务端确认自己发送正常,客户端发送正常。)
第三次:客户端再次发送确认(ACK) SYN标志为0,ACK标志为1,并把服务器发送过来的ACK序号字段+1(客户端发送/接受正常,服务端发送接受正常。服务端确认自己发送/接受正常,客户端发送接受正常。)

11 TCP四次挥手

第一次:客户端请求断开FIN,seq=u
第二次:服务器确认客户端的断开请求ACK,ack=u+1,seq=v
第三次:服务器请求断开FIN,seq=w,ACK,ack=u+1
第四次:客户端确认服务器的断开ACK,ack=w+1,seq=u+1

12 HTTP与TCP协议区别
1 TCP协议对应于传输层,而HTTP协议对应于应用层
2 TCP是有状态的长连接,而HTTP是无状态的连接

13 (1次)使用过的前端框架

14 当在地址栏输入www.XX.com的时候会发生什么
1、DNS解析地址
2、找到相应的服务器
3、TCP的三次握手建立TCP连接
4、找到入口文件
5、解析入口文件
6、TCP的四次挥手
7、返回资源页面

15 ajax是什么?如何创建一个ajax?

有关Ajax面试题或者复习请参考这儿

ajax并不算是一种新的技术,全称是asynchronous javasript and xml,可以说是已有技术的组合,主要用来实现客户端服务器的异步通信效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可以使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持。

//ajax编写步骤
// 1、创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 2、设置请求参数
xhr.open(请求方式,请求地址,异步或同步);
// 3、设置回调函数
xhr.onreadystatechange = function(){
if(xhr.reasyState===4){
if(xhr.status === 200) {
//5、接受响应
console.log(xhr.responseText);
}
}
}
// 4、发送请求
xhr.send();

16 同步和异步的区别?
  同步:浏览器向服务器请求数据,服务器比较忙,浏览器一直等着(页面白屏),直到服务器返回数据,浏览器才能显示页面。

异步:浏览器向服务器请求数据,服务器比较忙,浏览器可以自如的干原来的事情(显示页面),服务器返回数据的时候通知浏览器一声,浏览器把返回的数据再渲染到页面,局部更新。

17 如何理解跨域?如何解决跨域问题?
  理解跨域的概念:协议、域名、端口都相同才同域,否则都是跨域;
  
需要使用一些跨域请求的技术:
一:
利用JQuery的方法,使用JSONP模式访问,dataType:‘jsonp’并且再url后传入callback=?
JQuery会生成随机回调函数名称,或者你自己起名字。
后台会获取callback的值,连接上() 把数据放入() 中,返回页面,
相当于调用函数function名(data);
注::jsonp 只能解决get跨域(问的最多);

二:
使用js标签加载方式,动态创建一个script标签。利用script标签的src属性不受同源策略限制。因为所有的src属性和href属性都不受同源策略限制。可以请求第三方服务器数据内容;
利用script标签 src写想要请求的URL,地址后面连接上参数?callback = 函数名
后台会获取callback的值,连接上() 把数据放入() 中,返回页面,
相当于调用函数function名(data);

步骤:
(1)去创建一个script标签;
(2)script的src属性设置接口地址;
(3)接口参数,必须要带一个自定义函数名 要不然后台无法返回数据;
(4)通过定义函数名去接收后台返回数据;

//去创建一个script标签
var  script = document.createElement("script");
//script的src属性设置接口地址 并带一个callback回调函数名称
script.src = "http://127.0.0.1:8888/index.html?callback=jsonpCallback";
//插入到页面
document.head.appendChild(script);
//通过定义函数名去接收后台返回数据
function jsonpCallback(data){
//注意  jsonp返回的数据是json对象可以直接使用
//ajax  取得数据是json字符串需要转换成json对象才可以使用。
}

三:
后台直接开启同源策略的访问限制,设置响应头信息。
response.setHeader(“Access-Control-Allow-Origin”, “*”);

出于安全考虑,服务器不允许ajax跨域获取数据,但是可以跨域获取文件内容,所以基于这一点,可以动态创建script标签,使用标签的src属性访问js文件的形式获取js脚本,并且这个js脚本中的内容是函数调用,该函数调用的参数是服务器返回的数据,为了获取这里的参数数据,需要事先在页面中定义回调函数,在回调函数中处理服务器返回的数据,这就是解决跨域问题的主流解决方案。

18 CORS:跨域资源共享
原理:服务器设置Access-Control-Allow-OriginHTTP响应头之后,浏览器将会允许跨域请求;

限制:浏览器需要支持HTML5,可以支持POST,PUT等方法兼容ie9以上;

18 请解释一下javaScript的同源策略
  同源策略是客户端脚本的重要安全度量标准,所谓同源指的是:协议,域名,端口相同,同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。

18 Ajax几种请求,优缺点都是啥
常用的post,get,delete。不常用copy、head、link等等;

代码上的区别
1:get通过url传递参数;
2:post设置请求头 规定请求数据类型;

使用上的区别
1:post比get安全;
(因为post参数在请求体中。get参数在url上面)
2:get传输速度比post快 根据传参决定的;
(post通过请求体传参,后台通过数据流接收。速度稍微慢一些。而get通过url传参可以直接获取)
3:post传输文件大理论没有限制 get传输文件小大概7-8k ie4k左右;
4:get获取数据 post上传数据;
(上传的数据比较多 而且上传数据都是重要数据。所以不论在安全性还是数据量级 post是最好的选择)

19 GET和POST的区别,何时使用POST?
  GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符,有的浏览器是8000个字符。

POST:一般用于修改服务器上的资源,对所发送的信息没有限制。

以下情况中,请使用POST请求:

①、无法使用缓存文件(更新服务器上的文件或数据库)

②、向服务器发送大量数据(POST没有数据量限制)

③、发送包含未知字符的用户输入时,POST比GET更稳定也更可靠。

20 ajax的最大特点是什么?
  ajax可以实现异步通信效果,实现页面局部刷新,带来更好的用户体验;按需要获取数据,节约带宽资源。

21 ajax的缺点?
①、ajax不支持浏览器back按钮。
②、安全问题ajax暴露了与服务器交互的细节。
③、对搜索引擎的支持比较弱。
④、破坏了程序的异常机制。

22 解释jsonp的原理,以及为什么不是真正的ajax?
  jsonp并不是一种数据格式,而是json是一种数据格式,jsonp是用来解决跨域获取数据的一种解决方案,具体是通过动态创建script标签,然后通过标签src属性获取js文件中的js脚本,该脚本的内容是一个函数调用,参数就是服务器返回的数据,为了处理这些返回的数据,需要事先在页面定义好回调函数,本质上使用的并不是ajax技术。

23 HTTP状态码都有哪些?   
  200 OK 客户端请求成功
  301 资源(网页等)被永久转移到其他URL
  400 Bad Request 客户端请求有语法错误,不能被服务器所理解
  403 Forbidden 服务器收到请求,但是拒绝提供服务
  404 Not Found 请求资源部存在,输入了错误的URL
  500 Internal Server Error 服务器发生不可预期的错误
  503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常。

24 为什么利用多个域名来存储网站资源会更有效?
  确保用户在不同地区能用最快的速度打开网站,其中某个域名崩溃用户也能通过其他域名访问网站,并且不同的资源放到不同的服务器上有利于减轻单台服务器的压力;

25 为什么异步加载JS文件?加载方式?
平时常用的引入JS方式,是同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,也就是说,浏览器在下载或执行该js代码块时,后面的标签不会被解析。
异步加载(async)JS文件,允许页面内容异步加载,仅适用于外部脚本。
延迟加载(defer) 属性规定是否对脚本执行进行延迟,直到页面加载为止。

26 什么是闭包?
简单理解成:定义在一个函数内部的函数;
闭包本质:将函数内部和函数外部连接起来的一座桥梁;
最大用处:
1、可以读取函数内部变量;
2、就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在;

27 json字符串转换集json对象、json对象转换json字符串

Json串转化为对象
Json.parse(json);
对象转化为Json串
Json.Stringify(json);

前端框架知识

1 说说你理解中的bootstrap
Bootstrap是基于HTML5和CSS3开发的,它在jQuery的基础上进行了更为个性化和人性化的完善,只需要给标签起上响应的Class名称,就可以形成一套Bootstrap自己独有的网站风格,并兼容大部分jQuery插件;

后端框架知识

Spring框架

1 (1次)谈谈你对Spring的理解
Spring 是一个轻量级的 DI / IoC 和 AOP 容器的开源框架,提倡以“最少侵入”的方式来管理应用中的代码,这意味着我们可以随时安装或者卸载 Spring;

1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 ;
2.可以使用容易提供的众多服务,如事务管理,消息服务等 ;
3.容器提供单例模式支持 ;
4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 ;
5.容器提供了众多的辅助类,能加快应用的开发 ;
6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 ;
7.spring属于低侵入式设计,代码的污染极低 ;
8.独立于各种应用服务器 ;
9.spring的DI机制降低了业务对象替换的复杂性 ;
10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部 ;

spring的不足:
1 spring基于大量的xml 配置文件,使得我们花了大量的时间放在配置上,拖慢了开发的进度;
2 spring 的内容太庞大,随便打断点查看的时候会出现十几二十层代码,阅览性不强,在实际开发的过程中spring的角色更像是胶水一样,充当整合各种技术的角色;

2 (1次)Spring的IOC和AOP机制?

IOC
 控制反转也叫依赖注入,IOC利用java反射机制,AOP利用代理模式。所谓控制反转是指,本来被调用者的实例是由调用者来创建的,这样的缺点是耦合性太强,IOC则是统一交给spring来管理创建,将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类。

AOP

关于AOP的文章,详情参考另一篇AOP

 AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码,属于静态代理;

一 、面向切面编程(AOP)完善spring的依赖注入(DI),面向切面编程在spring中主要表现为两个方面:
1.面向切面编程提供声明式事务管理 ;
2.spring支持用户自定义的切面;

二 、面向切面编程(aop)是对面向对象编程(oop)的补充,面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。 AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,从而获得步骤之间的逻辑划分。

三 、aop框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性

3 Spring中Autowired和Resource关键字的区别?

4 依赖注入的方式有几种,各是什么?
依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念,具体的讲:当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者
因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的三种方式,设置(setter)注入、注解注入和构造注入。
设置注入的优点:直观,自然
注解注入:
构造注入的优点:可以在构造器中决定依赖关系的顺序。

5 Spring容器对Bean组件是如何管理的?

6 Spring容器如何创建?

7 Spring事务分类?

8 Spring事务的管理
Spring的事务管理机制实现的原理,就是通过一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。
Spring中的AOP实现更为复杂和灵活,不过基本原理是一致的。

Spring事务的4种特性 ACID
**(1)原子性(Atomicity):**事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
(2)一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
**(3)隔离性(Isolation):**可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
**(4)持久性(Durability):**一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

8 Spring事务的7种传播行为

spring事务的传播行为说的是当一个方法调用另一个方法时,事务该如何操作。因此:当事务方法被另一个事务方法调用时,必须指定事务应该如何传播;
(1)PROPAGATION_MANDATORY:该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。
(2)PROPAGATION_NESTED:如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。
(3)PROPAGATION_NEVER:当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常。
(4)PROPAGATION_NOT_SUPPORTED:当前方法不应该运行在一个事务中。如果一个事务正在运行,它将在该方法的运行期间挂起。
(5)PROPAGATION_REQUIRED:该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务。
(6)PROPAGATION_REQUIRES_NEW:该方法必须运行在自己的事务中。它将启动一个新的事务。如果一个现有的事务正在运行,将在这个方法的运行期间挂起。
(7)PROPAGATION_SUPPORTS:当前方法不需要事务处理环境,但如果一个事务已经在运行的话,这个方法也可以在这个事务里运行。

在现实的应用中,由于业务上的需要,要求不同表中的数据保持一致,即要求不同表中的数据同时更新或者出错时同时回滚,事务的本质其实就是为了解决这样的问题。

9 Spring事务的5种隔离级别?(不要与Mysql4种隔离级别混淆)

并发事务引起的问题:
**脏读(Dirty read):**脏读发生在一个事务读取了被另一个事务改写但还未提交的数据时。如果这些改变在稍后被回滚,那么之前的事务读取的到数据就是无效的。
**不可重复读(Nonrepeatable read):**不可重复读发生在一个事务执行相同的查询两次或两次以上,但每一次的查询结果不同时。这通常是由于另一个并发的事务在两次查询之间更新了数据。
**幻读(Phantom read):**幻读是一个事务读取几行记录后,另一个事务插入了一些记录,幻读就发生了。在后来的查询中第一个事务就会发现有一些原来没有的额外的记录。

(1)ISOLATION_DEFAULT:使用数据库默认的隔离级别。
(2)ISOLATION_READ_UNCOMMITTED:允许读取改变了的还未提交的数据,可能导致脏读、不可重复读和幻读。
(3)ISOLATION_READ COMMITTED:允许并发事务提交之后读取,可以避免脏读,可能导致重复读和幻读。
(4)ISOLATION_REPEATABLE_READ:对相同字段的多次读取结果一致,可导致幻读。
(5)ISOLATION_SERIALIZABLE:完全服从ACID的原则,确保不发生脏读、不可重复读和幻读。
可以根据自己的系统对数据的要求采取适应的隔离级别,因为隔离牵涉到锁定数据库中的记录,对数据正性要求越严格,并发的性能也越差。

10 Spring中AOP的通知类型有哪些?

关于AOP通知类型的文章,详情参考另一篇AOP详解

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常);
(2)返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回;
(3)抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知;
(4)后通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出);
(5)环绕通知(Around Advice):在目标方法执行之前和之后都可以执行额外代码的通知。在环绕通知中必须显式的调用目标方法,否则目标方法不会执行。这个显式调用时通过ProceedingJoinPoint来实现的,可以在环绕通知中接收一个此类型的形参,spring容器会自动将该对象传入,这个参数必须处在环绕通知的第一个形参位置;
要注意,只有环绕通知可以接收ProceedingJoinPoint,而其他通知只能接收JoinPoint;

五种通知类型执行顺序:
在目标方法没有抛出异常的情况下:
1 前置通知
2 环绕通知的调用目标方法之前的代码——取决于配置顺序
3 目标方法
4 环绕通知的调用目标方法之后的代码
5 后置通知——取决于配置顺序
6 最终通知——最终通知 后置通知和环绕通知结束取决于配置反向顺序

在目标方法抛出异常的情况下:
1 前置通知
2 环绕通知的调用目标方法之前的代码——取决于配置顺序
3 目标方法 抛出异常
4 异常通知
5 最终通知
如果存在多个切面:
 多切面执行时,采用了责任链设计模式;

五种通知常用场景:
前置通知 :记录日志(方法将被调用)
环绕通知 :控制事务 权限控制
后置通知 :记录日志(方法已经成功调用)
异常通知 :异常处理 控制事务
最终通知 :记录日志(方法已经调用,但不一定成功)

9 Spring拦截器与Servlet过滤器(Filter)的区别?
共同点: 两者都是AOP编程思想的体现,都能实现权限检查、日志记录等;
不同点:
(1)范围不同:Filter是Servlet规范规定的,只能用于Web程序中;而拦截器既可以用于Web程序,也可以用于Application、Swing程序中;
(2)规范不同:Filter是在Servlet规范中定义的,是Servlet容器支持的;而拦截器是在Spring容器内的,是Spring框架支持的;
(3)资源不同:拦截器是一个Spring组件,归Spring管理,配置在Spring文件中,因此能适用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可;而Filter不能;
(4)深度不同:Filter只在Servlet前后起作用;而拦截器能够深入到方法前后、异常抛出前后等;因此拦截器的使用具有更大的弹性,所以在Spring架构程序中,要优先使用拦截器;


SpringMVC框架

1 (1次)SpringMVC完整工作流程,熟读源码流程?

1 用户发起请求到前端控制器(DispatcherServlet),该控制器会过滤出哪些请求可以访问Servlet、哪些不能访问。就是url-pattern的作用,并且会加载springmvc.xml配置文件。
2 前端控制器会找到处理器映射器(HandlerMapping),通过HandlerMapping完成url到controller映射的组件,简单来说,就是将在springmvc.xml中配置的或者注解的url与对应的处理类找到并进行存储,用map<url,handler>这样的方式来存储。
3 HandlerMapping有了映射关系,并且找到url对应的处理器,HandlerMapping就会将其处理器(Handler)返回,在返回前,会加上很多拦截器。
4 DispatcherServlet拿到Handler后,找到HandlerAdapter(处理器适配器),通过它来访问处理器,并执行处理器。
5 执行处理器
6 处理器会返回一个ModelAndView对象给HandlerAdapter
7 通过HandlerAdapter将ModelAndView对象返回给前端控制器(DispatcherServlet)
8 前端控制器请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),其实就是将ModelAndView对象中存放视图的名称进行查找,找到对应的页面形成视图对象
9 返回视图对象到前端控制器。
10 视图渲染,就是将ModelAndView对象中的数据放到request域中,用来让页面加载数据的。
11 通过第8步,通过名称找到了对应的页面,通过第10步,request域中有了所需要的数据,那么就能够进行视图渲染了。最后将其返回即可

2 SpringMVC如何处理JSON数据?

3 SpringMVC拦截器原理,如何自定义拦截器?
 SpringMVC 拦截器也是Aop(面向切面)思想构建,但不是 Spring Aop 动态代理实现的,主要采用责任链和适配器的设计模式来实现,直接嵌入到 SpringMVC 入口代码里面。

 DispatcherServlet 执行调用 doService(request, response) 作为 Servlet 主要执行者,doService(request, response) 通过调用 doDispatch(request, response) 来真正执行请求处理;

拦截器原理:
(1) 通过 getHandler(HttpServletRequest request) 获取到 HandlerExecutionChain 处理器执行链;
(2)将拦截器注入到 HandlerExecutionChain 的属性中;
(3)分别调用 HandlerExecutionChain 的三个方法,applyPreHandle、applyPostHandle、triggerAfterCompletion;
(4)实现前置拦截/请求提交拦截和请求完成后拦截;
如何自定义拦截器:

4 SpringMVC如何将请求映射定位到方法上面?结合源码阐述?

5 SpringMVC常见注解有哪些?

6 SpringMVC容器和Spring容器的区别?

6 SpringMVC容器和Mybatis区别?

首先你bai要清楚springmvc和mybatis都是干什么的du,springmvc负责的是zhi接受用户请求以及业务的分发和视图的渲染,mybatis只是用来与数据库做交互的,mybatis侧重sql语言的编写,如果你不用spring做粘合剂将这两个框架粘合起来的话,需要做的步骤也很多。

MyBatis就是对JDBC的封装,操作的是数据库连接,执行各种增删改查的语句。主要关注SQL的组装和结果集的封装。
SpringMVC可以是Servlet的封装,甚至说它本质上就是Servlet。主要关注的是接收请求和发送响应。
如果没有他们,直接用Servlet+JDBC一样可以开发,只不过自己要写的简单重复的东西更多了。

7 SpringMVC的控制器是不是单例模式,如果是,有什么问题,怎么解决?


MyBatis框架

1 看过MyBatis源码吗,请说说它的工作流程?

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录;

Mybatis底层还是采用原生jdbc来对数据库进行操作的,通过下列几个处理器封装了这些过程:
**SqlSessionFactory(核心类):**每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,建议使用单例模式或者静态单例模式。一个SqlSessionFactory对应配置文件中的一个环境(environment),如果你要使用多个数据库就配置多个环境分别对应一个SqlSessionFactory;
SqlSession(核心类): SqlSession是一个接口,它有2个实现类,分别是DefaultSqlSession(默认使用)以及SqlSessionManager。SqlSession通过内部存放的执行器(Executor)来对数据进行CRUD。此外SqlSession不是线程安全的,因为每一次操作完数据库后都要调用close对其进行关闭,官方建议通过try-finally来保证总是关闭SqlSession;
Executor(核心类): Executor(执行器)接口有两个实现类,其中BaseExecutor有三个继承类分别是BatchExecutor(重用语句并执行批量更新),ReuseExecutor(重用预处理语句prepared statement,跟Simple的唯一区别就是内部缓存statement),SimpleExecutor(默认,每次都会创建新的statement);
MappedStatement(核心类):
StatementHandler:
ParameterHandler:
ResultHandler:
TypeHandler(类型转换):

执行器:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
sql查询处理器:
StatementHandler
参数处理器:
ParameterHandler
结果处理器 :
ResultSetHandler
StatementHandler用通过ParameterHandler与ResultHandler分别进行参数预编译与结果处理;

工作流程:
1:加载配置文件(mybatis-config.xml 、 *…Mapper.xml)并初始化,
将SQL的配置信息加载成为一个个MappedStatement对象(包括了传
入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
2:接收调用请求(调用Mybatis提供的API即增删改查的方法)并传入参数:
即SQL的ID和传入参数对象
3:处理操作请求,过程:
(1)根据SQL的ID查找对应的MappedStatement对象。
(2)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(3)获取数据库连接,根据得到的最终SQL语句和执行传入参数,到数据库执行,并得到执行结果。
(4)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(5)释放连接资源。
4:返回处理结果将最终的处理结果返回。

优点:
1:半自动化的ORM实现(实体类和SQL语句之间建立映射关系)
2:SQL代码从程序代码中彻底分离,可重用
3:与JDBC相比,减少了50%以上的代码量
4:小巧灵活、简单易学,是最简单的持久化框架
5:提供XML标签,支持编写动态SQL
6:提供映射标签,支持对象与数据库的ORM字段映射

缺点:
1:SQL语句编写工作量大,对开发人员有一定sql技术要求
2:数据库移植性差(不同数据库,sql语句语法有所不同)

2 MyBatis中#和$的区别?
#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,并自动加上" ",#{}是经过预编译的,是安全的;
${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。

能使用 #{} 的地方就用 #{}
表名作为变量时,必须使用 ${}

3 MyBatis一级缓存原理以及失效情况?
一级缓存是默认开启的,当创建SqlSession对象时候就开启了;
一级缓存通过简单Map集合来实现,并没有对Map集合的大小,容量进行限制;
一级缓存是一个粗粒度的缓存,没有办法去精确控制缓存中的数据是否过期以及去更新缓存数据;

4 MyBatis二级缓存的使用?
mybatis的二级缓存是基于application为生命周期
默认采用基于PerpetualCache的HashMap存储,其存储作用域为Mapper(Namespace)。
当某一个作用域(二级缓存Namespaces)进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear。

为什么要避免使用二级缓存:
多个Mapper(Namespace)可能对同一个表有相同的操作,会发送错误(两个命名空间下的数据不一致)

5 MyBatis拦截器原理
mybatis给Executor、StatementHandler、ResultSetHandler、ParameterHandler提供了拦截器功能;

Executor提供了增删改查的接口;
StatementHandler负责处理Mybatis与JDBC之间Statement的交互;
ResultSetHandler负责处理Statement执行后产生的结果集,生成结果列表;
ParameterHandler是Mybatis实现Sql入参设置的对象;

拦截器采用了责任链模式,把请求发送者和请求处理者分开,各司其职;


SpringBoot框架

1 请说说SpringBoot自动装配原理?
其实现自动装配的原理是在@SpringBootApplication —>@EnableAutoConfiguration—>@Import(AutoConfigurationImportSelector.class)这个注解中;
那么自动装配到底加载的是什么类:

会自动扫描所有项目下FACTORIES_RESOURCE_LOCATION这个路径下的类;

总结: springboot的自动装配就是通过自定义实现ImportSelector接口,从而导致项目启动时会自动将所有项目META-INF/spring.factories路径下的配置类注入到spring容器中,从而实现了自动装配;

2 谈谈你对SpringBoot的理解
spring boot 是微服务框架的起点,他简化了配置过程、部署过程、监控过程;
它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了很多的框架,同时将其他技术同spring结合起来;

使用SpringBoot的好处:
1 提供了各种组件便于功能的开箱即用:围绕着Spring Boot生态圈目前已经涌现出了不计其数的starter,这样我们只需将相应的starter配置项引入到项目中即可很方便地使用对应的功能;
2 自动装配:Spring Boot在启动时会自动探测类路径下的各种类型,实现类型的自动装配,无需开发者再通过XML或是注解进行显式的类型装配了,这一点要拜@EnableAutoConfiguration注解或是更为全面的@SpringBootApplication注解所赐;
3 yml配置的支持:它通过缩进的方式来表示层次化的配置项,相比于传统的properties属性文件来说,其层次感会更好一些;当然,顺便也可以让我们少敲一些字母;

使用SpringBoot的不足:
Spring Boot作为一个微框架,离微服务的实现还是有距离的。
没有提供相应的服务发现和注册的配套功能,自身的acturator所提供的监控功能,也需要与现有的监控对接。没有配套的安全管控方案,对于REST的落地,还需要自行结合实际进行URI的规范化工作;

3 SpringBoot核心配置文件
application.properties 或者 application.yml 所有配置项的集中配置文件;


网络架构问题

详情请参考另一篇文章互联网架构发展及其专业术语

1 (1次)Dubbo,Zookeeper;
Dubbo:
Zookeeper: 详情请参考here
首先在服务启动的时候,将服务提供者信息主动上报到服务注册中心进行服务注册。服务调用者启动的时候,将服务提供或者信息从注册中心下拉倒服务调用者本机缓存。当需要调用服务时,从本地缓存列表中找到服务提供者的地址列表,基于某种负载均衡策略(随机、轮询等)选择一台服务器发起远程调用。ZooKeeper就是实现这些功能的分布式协调服务(服务发现就是将服务提供者信息主动上报到服务注册中心进行服务注册,如将其提供的服务和对应的IP和端口注册到ZooKeeper中,服务调用者启动的时候,将ZooKeeper注册中心信息下拉倒服务调用者本机缓存,到需要用到到某个服务时,通过某种算法,去选择其中一个IP+端口,然后调用。);

2 Dubbo完整的一次调用链路介绍?

详细Dubbo调用过程源码please 参考 here!

Dubbo调用过程大致可以分为六步:
(1):服务消费方(dubbo-consumer)发布请求

(2):请求(request)编码

(3):服务提供方(dubbo-provider)解码请求

(4):服务提供方调用服务

(5):服务提供方返回调用结果(response)

(6):服务消费方接收调用结果

4 有用过SpringCloud吗,请说说SpringCloud和Dubbo有什么不一样?

5 什么是WebService,如何基于WebService开发接口?

6 谈谈项目中分布式事务应用场景?

7 使用Redis如何实现分布式锁?

Redis实现分布式锁请参考here
and Here

其实想要通过Redis实现分布式锁并不难,只要保证能满足可靠性里的四个条件:

(1) 互斥性: 在任意时刻,只有一个客户端能持有锁;
(2) 不会发生死锁: 即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁;
(3) 具有容错性: 只要大部分的Redis节点正常运行,客户端就可以加锁和解锁;
(4) 解铃还须系铃人: 加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了;

加锁代码:

public class RedisTool {

private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";

/**
* 尝试获取分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {

String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);

if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;

}

}

可以看到,我们加锁就一行代码:jedis.set(String key, String value, String nxxx, String expx, int time),这个set()方法一共有五个形参:
第一个为key,我们使用key来当锁,因为key是唯一的。
第二个为value,我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用UUID.randomUUID().toString()方法生成。
第三个为nxxx,这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
第四个为expx,这个参数我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
第五个为time,与第四个参数相呼应,代表key的过期时间。
总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。

解锁代码:

public class RedisTool {

private static final Long RELEASE_SUCCESS = 1L;

/**
* 释放分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {

String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));

if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;

}

}

可以看到,我们解锁只需要两行代码就搞定了!

8 请谈谈SSO单点登录原理?

SSO单点登陆详情参考here

SSO: 是目前比较流行的企业业务整合的解决方案之一,同时也是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统;

单点登录解决了什么问题: 解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录;

优点:
1)提高用户的效率
用户不再被多次登录困扰,也不需要记住多个 ID 和密码。另外,用户忘记密码并求助于支持人员的情况也会减少;
2)提高开发人员的效率
SSO 为开发人员提供了一个通用的身份验证框架。实际上,如果 SSO 机制是独立的,那么开发人员就完全不需要为身份验证操心。他们可以假设,只要对应用程序的请求附带一个用户名,身份验证就已经完成了;
3)简化管理
如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。简化的程度取决于应用程序,因为 SSO 只处理身份验证。所以,应用程序可能仍然需要设置用户的属性(比如访问特权);

缺点:
1)不利于重构
因为涉及到的系统很多,要重构必须要兼容所有的系统,可能很耗时;
2) 无人看守桌面
因为只需要登录一次,所有的授权的应用系统都可以访问,可能导致一些很重要的信息泄露;

如何实现:
Server端: 以server群如何生成、验证ID的方式大致分为两种:
 “共享Cookie”这个就是上面提到的共享session的方式,我倒觉得叫“共享session”来得好一点,本质上cookie只是存储session-id的介质,session-id也可以放在每一次请求的url里。据说这种方式不安全,我没去细究,哪位大神可以推荐下相关的资料,我后期补上。其实也是,毕竟session这项机制一开始就是一个server一个session的,把session拿出来让所有server共享确实有点奇怪。

 SSO-Token方式因为共享session的方式不安全,所以我们不再以session-id作为身份的标识。我们另外生成一种标识,把它取名SSO-Token(或Ticket),这种标识是整个server群唯一的,并且所有server群都能验证这个token,同时能拿到token背后代表的用户的信息。

浏览器端: 单点登录还有非常关键的一步,这一步跟server端验证token的方式无关,用最早的“共享session”的方式还是现在的“token”方式,身份标识到了浏览器端都要面临这样的一个问题:用户登录成功拿到token(或者是session-id)后怎么让浏览器存储和分享到其它域名下?同域名很简单,把token存在cookie里,把cookie的路径设置成顶级域名下,这样所有子域都能读取cookie中的token。这就是共享cookie的方式(这才叫共享Cookie嘛,上面那个应该叫共享session)。比如:谷歌公司,google.com是他的顶级域名,邮箱服务的mail.google.com和地图服务的map.google.com都是它的子域。但是,跨域的时候怎么办?谷歌公司还有一个域名,youtube.com,提供视频服务。

要实现SSO,需要以下主要的功能:
所有应用系统共享一个身份认证系统。
  统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。
所有应用系统能够识别和提取ticket信息;
  要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能;

9 Tomcat如何优化?

10 后台系统怎么防止请求重复提交?

防止请求重复提交详情请参考here

客户端的抖动,快速操作,网络通信或者服务器响应慢,造成服务器重复处理。为了防止重复提交,除了从前端控制,后台也需要控制。因为前端的限制不能解决彻底。接口实现,通常要求幂等性,保证多次重复提交只有一次有效。对于更新操作,达到幂等性很难;

重复提交的后果:
1 用户在界面看到两个一模一样的订单,不知道应该支付哪个;
2 系统出现异常数据,影响正常的校验;

前端常用做法
思路: 进入添加页面时,获取服务器端的token,提交时把token提交过去,判断token是否存在,若存在,则进行后续正常业务逻辑,如不存在,则报错重复提交;

后端常用做法:
(1)token: 访问请求到达服务器,服务器端生成token,分别保存在客户端和服务器。提交请求到达服务器,服务器端校验客户端带来的token与此时保存在服务器的token是否一致,如果一致,就继续操作,删除服务器的token。如果不一致,就不能继续操作,即这个请求是重复请求;
(2)缓存: request进来,没有就先存在缓存中,继续操作业务,最后删除缓存或者缓存设置生命周期。如果存在,就直接对request进行验证,就不能继续操作业务;
(3)索引: 数据库中创建唯一索引,记录每次request请求。添加索引成功,就获取锁,继续操作,最后设置索引失效。添加索引失败,获取锁失败,不能继续操作;
(4)Redis计数器: Redis的计数器是原子操作,不存储请求,又能提升QPS的峰值。每次request请求,若相同请求,计数器+1,否则新建id为key的计数器。如果>1,不能获取锁;如果=1,获取锁,操作,最后删除计数器(删除锁);
(5)Post/Redirect/Get: 提交(Post)后执行页面重定向,成功后转到提交成功页面(Get),整个流程才算结束。当刷新页面,或者浏览器前进和后退,都不会引起Post请求的重复提交。这里可以在head中设置control-cache,保存表单信息。这个方法依赖前端限制比较多;

11 Linux常见命令有哪些?

12 请说说什么是Maven的依赖、继承以及聚合?

13 Git暂存区和工作区的区别?

14 Git如何创建、回退以及撤销版本?

15 常见的设计模式有哪些?

23种设计模式超详细文章

创建型模式(五种):
(1)工厂方法模式: 定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类;
(2)抽象工厂模式: 定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类。
(3)单例模式: 确保一个类最多只有一个实例,并提供一个全局访问点;
(4)建造者模式:
(5)原型模式: 通过复制现有实例来创建新的实例,无需知道相应类的信息;

结构型模式(七种):

(1)适配器模式: 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题;
(2)装饰器模式: 动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性;
(3)代理模式: 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介;
(4)外观模式: 隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口;
(5)桥接模式: 将抽象部分与它的实现部分分离,使它们都可以独立地变化;
(6)组合模式: 有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性;
(7)享元模式: 通过共享的方式高效的支持大量细粒度的对象;

行为型模式(十一种):
策略模式:
模板方法模式:
观察者模式:
迭代子模式:
责任链模式:
命令模式:
备忘录模式:
状态模式:
访问者模式:
中介者模式:
解释器模式:

16 你是怎么理解的shrio

Shiro是一个强大易用的java安全框架,提供了认证、授权、加密、会话管理、与web集成、缓存等功能,对于任何一个应用程序,都可以提供全面的安全服务,相比其他安全框架,shiro要简单的多;

核心概念:
Subject: 主体,代表了当前“用户”,这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如爬虫、机器人等;即一个抽象概念;所有Subject都绑定到SecurityManager,与Subject的所有交互都会委托给SecurityManager;可以把Subject认为是一个门面;

SecurityManager: 才是实际的执行者,为安全管理器;即所有与安全有关的操作都会与SecurityManager交互;且它管理着所有Subject;可以看出它是shiro的核心, SecurityManager相当于spring mvc中的dispatcherServlet前端控制器;

Realm: 域,shiro从Realm获取安全数据(如用户、角色、权限),就是说SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法;也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource,即安全数据源;

优点:
1、 简单的身份验证,支持多种数据源;
2、对角色的简单授权,支持细粒度的授权(方法);
3、支持一级缓存,以提升应用程序的性能;
4、内置基于POJO的企业会话管理,适用于web及非web环境;
5、非常简单的API加密;
6、不跟任何框架绑定,可以独立运行;

17 谈谈nginx在项目中的作用

18 谈谈redis在项目中的作用
详情请戳这里
或者戳这里


项目部分

一、请你自我介绍一下

二、请你描述一下你的项目(为谁开发、介绍、功能、你负责的模块等等)

三、谈谈此项目由多少张表组成,你参与了哪写,如何设计

四、此项目是否上线、开发周期、开发人员组成

五、请你谈谈你在这个项目中遇到的问题(解决办法)

六、阅读过哪些源码(并根据你说的源码问一些细节的问题)

七、谈谈XX技术在你项目中是怎么实现的,流程等

首先,XX技术主要功能是…从而达到XX效果;在项目中主要…,其优势在于…能够实现…目的,所以…能够帮助我们在项目上做到…;

八、谈谈XX技术是怎么工作的;

例如RDB:默认 Redis 是会以快照"RDB"的形式将数据持久化到磁盘的一个二进制文件 dump.rdb,当 Redis 需要做持久化时,Redis 会 fork 一个子进程,子进程将数据写到磁盘上一个临时 RDB 文件中,当子进程完成写临时文件后,将原来的 RDB 替换掉,这样的好处是可以 copy-on-write;


扩展内容

一、 数据结构(代码算法参考下一部分)

查找(适用场景,案例)
排序(适用场景,案例)

二、基本算法

三、逻辑算法

四、银行面试题

1、在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环
HashMap本身没有什么问题,有没有问题取决于你是如何使用它的。比如,你在一个线程里初始化了一个HashMap然后在多个其他线程里对其进行读取,这肯定没有任何问题。有个例子就是使用HashMap来存储系统配置项。当有多于一个线程对HashMap进行修改操作的时候才会真正产生问题,比如增加、删除、更新键值对的时候。因为put()操作可以造成重新分配存储大小(re-sizeing)的动作,因此有可能造成无限循环的发生,所以这时需要使用Hashtable或者ConcurrentHashMap,而后者更优。

2、不重写Bean的hashCode()方法是否会对性能带来影响?
这个问题非常好,每个人可能都会有自己的体会。按照我掌握的知识来说,如果一个计算hash的方法写得不好,直接的影响是,当向HashMap中添加元素的时候会更频繁地造成冲突,因此最终增加了耗时。但是自从Java 8开始,这种影响不再像前几个版本那样显著了,因为当冲突的发生超出了一定的限度之后,链表类的实现将会被替换成二叉树(binary tree)实现,这时你仍可以得到O(logN)的开销,优于链表类的O(n)。

3、对于一个不可修改的类,它的每个对象是不是都必须声明成final的?
不尽然,因为你可以通过将成员声明成非final且private,并且不要在除了构造函数的其他地方来修改它。不要为它们提供setter方法,同时不会通过任何函数泄露出对此成员的引用。需要记住的是,把对象声明成final仅仅保证了它不会被重新赋上另外一个值,你仍然可以通过此引用来修改引用对象的属性。这一点是关键,面试官通常喜欢听到你强调这一点。

4、String的substring()方法内部是如何实现的?
又一个Java面试的好问题,你应该答出“substring方法通过原字符串创建了一个新的对象”,否则你的回答肯定是不能令人满意的。这个问题也经常被拿来测试应聘者对于substring()可能带来的内存泄漏风险是否有所了解。直到Java 1.7版本之前,substring会保存一份原字符串的字符数组的引用,这意味着,如果你从1GB大小的字符串里截取了5个字符,而这5个字符也会阻止那1GB内存被回收,因为这个引用是强引用。

5、你在写存储过程或者在Java里调用存储过程的时候如何来处理错误情况?
这是个很棘手的Java面试题,答案也并不固定。我的答案是,写存储过程的时候一旦有操作失败,则一定要返回错误码。但是在调用存储过程的时候出错的话捕捉SQLException却是唯一能做的。

6、Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?
如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。多线程和并发编程中使用 lock 接口的最大优势是它为读和写提供两个单独的锁,可以让你构建高性能数据结构,比如 ConcurrentHashMap 和条件阻塞。这道 Java 线程面试题越来越多见,而且随后的面试题都基于面试者对这道题的回答。我强烈建议在任何 Java 多线程面试前都要多看看有关锁的知识,因为如今电子交易系统的客户端和数据交互中,锁被频繁使用来构建缓存。

7、Executor.submit()和Executor.execute()这两个方法有什么区别?
前者返回一个Future对象,可以通过这个对象来获得工作线程执行的结果。当我们考察异常处理的时候,又会发现另外一个不同。当你使用execute提交的任务抛出异常时,此异常将会交由未捕捉异常处理过程来处理(uncaught exception handler),当你没有显式指定一个异常处理器的话,默认情况下仅仅会通过System.err打印出错误堆栈。当你用submit来提交一个任务的时候,这个任务一旦抛出异常(无论是否是运行时异常),那这个异常是任务返回对象的一部分。对这样一种情形,当你调用Future.get()方法的时候,这个方法会重新抛出这个异常,并且会使用ExecutionException进行包装。

8、能否写一段用Java 4或5来遍历一个HashMap的代码?
事实上,用Java可以有四种方式来遍历任何一个Map,一种是使用keySet()方法获取所有的键,然后遍历这些键,再依次通过get()方法来获取对应的值。第二种方法可以使用entrySet()来获取键值对的集合,然后使用for each语句来遍历这个集合,遍历的时候获得的每个键值对已经包含了键和值。这种算是一种更优的方式,因为每轮遍历的时候同时获得了key和value,无需再调用get()方法,get()方法在那种如果bucket位置有一个巨大的链表的时候的性能开销是O(n)。第三种方法是获取entrySet之后用iterator依次获取每个键值对。第四种方法是获得key set之后用iterator依次获取每个key,然后再根据key来调用get方法。

9、你在什么时候会重写hashCode()和equals()方法?
当你需要根据业务逻辑来进行相等性判断、而不是根据对象相等性来判断的时候你就需要重写这两个函数了。例如,两个Employee对象相等的依据是它们拥有相同的emp_id,尽管它们有可能是两个不同的Object对象,并且分别在不同的地方被创建。同时,如果你准备把它们当作HashMap中的key来使用的话,你也必须重写这两个方法。现在,作为Java中equals-hashcode的一个约定,当你重写equals的时候必须也重写hashcode,否则你会打破诸如Set, Map等集合赖以正常工作的约定。你可以看看我的另外一篇博文来理解这两个方法之间的微妙区别与联系。

10、如果不重写hashCode方法会有什么问题?
如果不重写equals方法的话,equals和hashCode之间的约定就会被打破:当通过equals方法返回相等的两个对象,他们的hashCode也必须一样。如果不重写hashCode方法的话,即使是使用equals方法返回值为true的两个对象,当它们插入同一个map的时候,因为hashCode返回不同所以仍然会被插入到两个不同的位置。这样就打破了HashMap的本来目的,因为Map本身不允许存进去两个key相同的值。当使用put方法插入一个的时候,HashMap会先计算对象的hashcode,然后根据它来找到存储位置(bucket),然后遍历此存储位置上所有的Map.Entry对象来查看是否与待插入对象相同。如果没有提供hashCode的话,这些就都做不到了。

11、HashMap在调用get()方法的时候equals()和hashCode()方法都起了什么样的作用?
应聘者应该知道的是,一旦你提到了hashCode()方法,人们很可能要问HashMap是如何使用这个函数的。当你向HashMap插入一个key的时候,首先,这个对象的hashCode()方法会被调用,调用结果用来计算将要存储的位置(bucket)。因为某个位置上可能以链表的方式已经包含了多个Map.Entry对象,所以HashMap会使用equals()方法来将此对象与所有这些Map.Entry所包含的key进行对比,以确定此key对象是否已经存在。

12、在Java中如何避免死锁?
你可以通过打破互相等待的局面来避免死锁。为了达到这一点,你需要在代码中合理地安排获取和释放锁的顺序。如果获得锁的顺序是固定的,并且获得的顺序和释放的顺序刚好相反的话,就不会产生出现死锁的条件了。

13、说说ClassLoader.loadClass()与Class.forName()的区别
ClassLoader.loadClass()与Class.forName()大家都知道是反射用来构造类的方法,但是他们的用法还是有一定区别的。在讲区别之前,我觉得很有不要把类的加载过程在此整理一下。在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

装载:查找和导入类或接口的二进制数据;
链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
校验:检查导入类或接口的二进制数据的正确性;
准备:给类的静态变量分配并初始化存储空间;
解析:将符号引用转成直接引用;
初始化:激活类的静态变量的初始化Java代码和静态Java代码块。
于是乎我们可以开始看2者的区别了。

Class.forName(className)方法,其实调用的方法是Class.forName(className,true,classloader);注意看第2个boolean参数,它表示的意思,在loadClass后必须初始化。比较下我们前面准备jvm加载类的知识,我们可以清晰的看到在执行过此方法后,目标对象的 static块代码已经被执行,static参数也已经被初始化。

再看ClassLoader.loadClass(className)方法,其实他调用的方法是ClassLoader.loadClass(className,false);还是注意看第2个 boolean参数,该参数表示目标对象被装载后不进行链接,这就意味这不会去执行该类静态块中间的内容。因此2者的区别就显而易见了。

最后还有必要在此提一下new方法和newInstance方法的区别

newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
例如,在JDBC编程中,常看到这样的用法,Class.forName(“com.mysql.jdbc.Driver”),如果换成了 getClass().getClassLoader().loadClass(“com.mysql.jdbc.Driver”),就不行。

全篇总结一些经验:

1.先投一些普通公司,等面出了心得再去投理想的公司;
2.不熟悉的技术不要主动提;
3.对于那种实习期6个月还打8折的公司,除非你没有其他选择了,否则不要去;
4.小公司喜欢在薪水上压你,开的时候适当提高;
5.不要去参加招聘会,纯粹是浪费时间;
6.把面试当作一次技术的交流,不要太在意是否能被录取;
7.公司一般面完就决定是否录取了,让你回去等消息这种情况一般没戏,无论你自己觉得面的有多好;
8.尽量少通过电话面试,效果不好;
9.在面试的日子里,要保持每天学习,无论是学习新东西还是复习旧东西;
10.拿到offer了,问问自己这个公司让自己100%满意了吗,如果不是,请继续努力找更好的;
11.通过面试官可以大概判断这家公司的情况;
12.拉勾投的简历很多会被筛掉,但是拉勾还是面试机会的最主要来源;
13.理想的公司可以多投几次,我有好几次都是第一次投被筛掉,多投几次就过的经验;

每一个你不满意的当下,都有一个你不曾努力的过去

最后送给大家的一句话,面试完以后一定要去总结你不会的问题,去网上找找它的答案,否则你是不会有进步的!!!








(未完待续)欢迎留言提出宝贵意见,将不断完善!所有资料均来自网络,有错误请及时指正,蟹蟹

注:文章所涉及表情包来自[麦田]的[抱抱]系列,如有侵权,请联系;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: