type
status
date
slug
summary
tags
category
icon
password
大家好,我是鹤涵。
我是一个八年的Java程序员,当过多年面试官,面试过的人数超过百人。
分享下面试的一些方法,流程、实际案例,以及自己的思考。
一、面试方法
一)考察点
面试主要考察:技能、能力、价值观、匹配度
1、技能
一个程序员技能过关才能完成日常开发任务,所以基础知识也是面试的必考内容。
一个Java程序员需要掌握的技能还真不少。Java基础,开源框架,中间件,代码设计,项目实战通通得会。
针对上面的每个Java技术栈的知识点,都有多年的面试题积累了(俗称「八股文」),面试前一定要过一遍,要求广度。
实际工作项目中使用到的技术一定要重点掌握,要求深度。
下面是我整理的知识点详细的脑图:
2、能力
工作年限和职级越高,对能力的要求越大,对技能的要求反而没那么大。
学习能力:
世界变化太快,尤其是在IT行业。面对新的知识和技能时,具备快速学习的能力至关重要,能够迅速掌握并应用新的知识。
沟通能力:
能够清晰、准确地表达自己的想法和观点,并理解他人的意见和观点,以进行有效的沟通和交流。
作为程序员,不仅仅需要会写代码,还需要具备良好的沟通能力。即使不直接面对客户,与产品经理、测试同事、领导和下属之间也需要进行频繁的沟通。
3、价值观
当设定了自己的目标和追求时,面对困难和挑战,是选择坚持不轻易放弃,持之以恒地努力追求目标,还是选择轻易放弃?
这是否与公司的价值观一致?是否具备以公司事务为己任的owner意识?听起来确实有一些「PUA」优点,但这样做确实能在职场获得较好的回报。
4、匹配度
而面试官的目的是找到适合职位要求的候选人。
需要注意的是,这里所说的是“适合”的人选,而不是“最好”的人选。这不仅考虑到用人成本,还考虑到员工的职业发展和工作质量。许多面试官不会选择经验和技能过剩的应聘者,而是选择经验和技能匹配,甚至稍微差一些,但是具备潜力和动机的应聘者。这样的人选会更加珍惜这个机会,对工作充满兴趣,更有动力去接受挑战,主动学习并将工作做好。
二)表达技巧
1、金字塔法则
金字塔原理是美国人巴巴拉·明托提出的一种关于思考逻辑的方法论。它很简单,核心思想是任何事情都可以归纳出一个中心思想,中心思想可由三至七个论点支持,每个论点可以由三至七个论据支撑。这样延伸下去,形状像一个金字塔,所以才叫金字塔原理。
我们在讲解自己的工作经历的时候就比较适合金字塔法则。
先把我们最重要的优势先提出来,然后按照时间顺序从近到远讲解自己的工作经历。用实际做的事来印证我们的优势。
2、STAR法则
STAR法则是一种在面试中有效回答问题的方法。它包括以下几个步骤:
- Situation(情境):描述你所面临的具体情境或挑战。
- Task(任务):解释你在该情境下的任务或目标。
- Action(行动):详细说明你采取的具体行动步骤。
- Result(结果):阐述你的行动带来的具体结果和成就。
使用STAR法则可以帮助你在面试中清晰、有条理地回答问题,展示自己的能力和经验。
我们讲解做过的项目的时候非常适合使用STAR法则。
先介绍我们项目的业务背景技术背景,再说明当前要做一个什么事,然后说明具体的技术方案以及如何落地,最后说明我们这个项目取得了什么结果。
这样面试官就比较容易理解,就会认为面试者逻辑性很强。
3、学会倾听
面试官问一个问题,即使你刚好很熟悉也一定不要「抢答」。一个是可能根本没有理解面试官的问题,二打断别人还是不太尊重的。面试官也是个最普通的人,是人就会被情绪操纵,留下不好印象很可能会影响这次面试的通过率。
面试官就是你的未来同事,你可以把面试官当成你的工作搭档去沟通,方便去做双向筛选。
二、面试流程
一般技术人员的面试为2-3轮技术面,一轮hr面试。
- 一面:
一般是跟你同级别技术能力比较强的同学。主要会考察技能是否过关,做一个初步筛选。
- 二面
一般是你的直系领导,你的升职加薪的直接负责人。主要会考察技能和能力,以及是否适合当前的岗位。
- 三面
一般是你的大领导,跟你直接的工作合作机会不会很多,绝大部分都不负责一线开发工作了。所以技术考察会少一些,会更看重能力,价值观等软性能力
- hr面
恭喜你,终于到了hr面。基本到了hr面只要不作死就安全了。hr主要是聊得内容不外乎职业发展,个人情况,离职原因,期望薪资这些。会根据你前面的面评和对标公司是否有offer来给你定薪资。
三、面试实战
一般Java面试会围绕项目,知识点,算法三个点进行展开。
其中最重要的是项目,因为公司招人一定是来干活,来解决公司的业务问题的,所以对以往项目的考察就比较重要了。
一)自我介绍
第一个阶段就是自我介绍,这个时间就是给面试官制造一个第一印象。用上面的金字塔原则把自己最突出的优势讲出来,引导面试官问你最擅长的部分,否则问到你不擅长的答不上来就会减分。
比如你学熟悉的是JVM调优,那你就是重点提一下,在后续的项目中也可以反复提起这个点。
案例如下
- 面试官:
你先做个自我介绍吧?
- 面试者:
我毕业于西虹市大学,有5年的工作经验。
平常使用Java技术栈偏多,熟悉Spring,Mysql,微服务等技术栈(擅长的)。
最近在西虹市保险公司做Java工作,目前在职状态,在公司里做了架构设计,性能优化,项目管理等工作(做出成绩的)。
再上一家公司同理。
二)项目
项目是信息量最大的部分,能真是反应你的工作状态。写出来的代码是能用就行,还是对边界控制,代码性能,架构设计有自己的思考。
案例如下
- 面试官:
挑一个你最具技术挑战或者成长最大的项目讲一下?
- 面试者:
我们所在的部门是商业化部门,承担了公司的主要营收任务,日收入大约200万。我们小组开发的投放平台旨在为广告主维护广告信息,我在里面承担组长的角色。
该项目主要是使用了Spring,Mysql,Redis等等技术。
由于广告量不断增长产生了严重的性能问题,所以做性能优化。
我使用了Java内存分析的方式进行分析优化,最终实现了内存下降了80%。
三)知识点
根据上面项目中使用的技术,进行知识点追问,有的面试官可能会刨根问底到操作系统层面。
案例如下
- 面试官:
我看你们用Mysql,在使用Mysql的过程中遇到什么问题了么?
- 面试者:
我们遇到了误用Mysql中的limit分页,导致Mysql负载飙高的问题。
MySQL的
LIMIT
子句常用于分页,但在处理大量数据时,如果不加注意,它可能会导致效率问题,特别是当你使用了偏移量。例如:这个查询会找到前100,010个记录,但只返回最后10个。这意味着前100,000个结果实际上是无用的,但仍然会被MySQL检索出来,这会造成不必要的I/O和CPU负载。
我们对 SQL 进行了优化,去掉了大 limit,改成先通过 id 过滤,再对 id 排序,最后使用 limit 的方式解决了这个问题。
- 面试官:
嗯,那上面的id在Mysql一般是用什么数据结构存呢?
- 面试者:
- 结构:
- B+树由根、内部节点和叶节点组成。
- 所有的值都在叶节点上,内部节点不存储数据,只存储关键字和指向子节点的指针。
- 叶节点按键值顺序链接,这使得范围查询更加高效。
- 性质:
- 所有的叶节点都在同一层。
- 节点的子节点数目在预定的最小值和最大值之间。
- 优点:
- 磁盘I/O效率:B+树尤其适合磁盘存储系统,因为其结构减少了磁盘I/O操作。由于磁盘读写操作通常按块(即一页)进行,所以将一个块的内容读入内存的成本与读取单个记录的成本相同。B+树的节点通常与这些块的大小相匹配,从而使每次I/O操作尽可能有效。
- 范围查询优化:由于B+树的叶节点是有序的并且通过指针连接,这使得范围查询非常高效。
- 增加和删除优化:与平衡二叉搜索树相比,B+树在增加或删除键值时的平衡操作更为高效。
- 高度较低:与其他树结构相比,B+树的高度通常较低,这意味着对于大多数键查找,需要的磁盘I/O次数更少。
- 使用场景:
- B+树通常用于数据库和文件系统中,因为它们为磁盘或其他辅助存储器上的大量数据提供了高效的访问、插入和删除操作。
MySQL中最常用的存储引擎是InnoDB,id主要使用B+树作为其索引结构。B+树是B树的一种变体,特别适合于磁盘或其他直接访问辅助存储器。
以下是B+树的特点和结构:
B+树在数据库中的使用是为了充分利用块访问的优点,并减少数据查找时的磁盘I/O次数,从而提高查询的性能。
四)算法
算法常见的就是考leetcode原题,或者基于场景的代码编写。
我一般不考leetcode原题,因为意义不大,背过了就会没背过就会卡壳,即使是高手也没有AI写得快。
应该重点考核工作中实际场景如何解决问题。
我一般会考两个线程交替打印奇数偶数。这道题的的难度不是太大,既能考察面试者的代码能力,也可以考察对多线程的熟悉程度,而且可以深入考察多线程的知识点。
- 面试官:
写一个代码两个线程交替打印奇数偶数
- 面试者:
可以使用
wait()
和notify()
方法来实现线程间的协作。我们使用了一个共享的锁对象
LOCK
。奇数线程和偶数线程会轮流获取这个锁,然后检查当前数字是否符合它们的输出条件。如果符合,就输出数字,增加数字并唤醒其他线程;如果不符合,就让当前线程等待。- 面试官:
还有别的实现方式么?
- 面试者:
使用
volatile
关键字可以确保一个变量的读写操作对所有线程都是可见的,也即某一个线程修改了一个volatile
变量后,其他线程可以立刻看到修改后的值。为了使用
volatile
来控制两个线程交替输出,我们可以使用一个volatile
标志来指示哪一个线程应该进行输出。我们使用了
isOdd
这个volatile
变量来标记当前应该由哪个线程输出。当isOdd
为true
时,奇数线程输出数字并递增,然后设置isOdd
为false
。当isOdd
为false
时,偶数线程输出数字并递增,然后设置isOdd
为true
。使用
volatile
的这种方法可能导致CPU的忙等待,因为线程会在一个循环中不断地检查isOdd
的值而没有进入休眠状态,这可能会增加CPU的使用率。- 面试官:
volatile
的实现原理是啥?- 面试者:
blabla..(又过去十分钟)
- 面试官:
整挺好!
四、最后
是金子总会发光,希望大家都能找到心仪的工作。
- 作者:鹤涵
- 链接:https://www.hehanwang.com/article/java-interview
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。