诸位好,我乃程序员小灰。小灰的公众号里存有一位读者朋友鹤涵,此人是有着8年Java经验的资深程序员,还曾担任多年面试官,面试过的人数超出百人。
今日,小灰特地将他邀约而来,为众人去分享一回面试的某些窍门,包括流程,还有实际案例,以及自身的思索。这篇分享极为良心,强烈提议大伙收藏一番。
一、面试方法一)考察点
面试主要考察:技能、能力、价值观、匹配度
1、技能
才能完成为日常开发任务,一个程序员技能要过关,所以基础知识也是面试必考的内容。
身为一名Java程序员,其所必须掌握的技能着实不少,比如有Java基础,还有开源框架,以及中间件,代码设计也得会,另外项目实战同样得通。
关于上面提及的每一个Java技术栈的知识点,都有着经由多年所积累而成的面试题(也就是俗称的「八股文」),在进行面试之前务必要从头到尾浏览一遍,其要求在于具备广阔的知识覆盖面。
实际工作项目中使用到的技术一定要重点掌握,要求深度。
下面是我整理的知识点详细的脑图:
2、能力
工作年限越长,职级越高,那么对于能力的要求就越大,然而对于技能的要求反倒没那么大了。
学习能力:
世界的变化速率极为迅速,特别在那 IT 行业领域,当面临全新的知识范畴以及技能种类瞬间变化时,拥有可以快速学习的那种能力显得至关重要,此能力能够在极短时间内迅速掌握并且应用全新的知识,是这样的一种本事 。
沟通能力:
能够把自己的想法以及观点清晰且准确地予以表达,并且理解他人所表达的意见还有观点,经由如此来开展有效的沟通以及交流。
身为程序员,并非仅需会编写代码,还得拥有良好沟通能力。就算不直接面对客户,跟产品经理、测试同事、领导以及下属之间,也得展开频次颇高的沟通。
3、价值观
既定自身目标与追求之际,直面困难跟挑战之时,做这般选择:是选持续坚持绝不轻易放弃,以持之以恒之态奋力追求目标?抑或是选轻易舍弃?
这是不是跟公司的价值观相契合呢,有没有具备那种 将公司事务当作自己责任的owner意识呢,听起来的确存在一些「PUA」方面的优点,然而如此去做真的能够在职场收获较好的回报吗 。
4、匹配度
而面试官的目的是找到适合职位要求的候选人。
特此需予以注意地讲,此处之所谓指的是“适配”之人选,并非“最优”之人选。这不但在用人成本方面加以了思量,而且在员工职业发展以及工作质量方面也予以了考量。诸多面试官对于经验和技能过度充裕的应聘者不会予以选用,而会挑选经验和技能相匹配,甚或稍微有所欠缺,然而具备潜力以及动机的应聘者。如此这般之人选会愈发极为珍视这个机会,对工作十足满怀兴趣,更具动力去接纳挑战,主动积极地展开学习并把工作圆满妥善地完成好。
二)表达技巧 1、金字塔法则
巴巴拉·明托这位美国人所提出的一种关于思考逻辑方面的方法论是金字塔原理,金字塔原理它挺简单的,其核心思想为任何事情都能够归纳出一个中心思想,这个中心思想能够由三至七个论点予以支持,而每个论点又能够被三至七个论据进行支撑,如此这般不断延伸下去,因其形状类似一个金字塔,故而才被称作金字塔原理。
我们在讲解自己的工作经历的时候就比较适合金字塔法则。
首要地,先将我们最为关键的优势着手提出来,随后,自近向远依照时间的先后顺序去讲解自身的工作经历,借助实际所做的事情来对我们的优势予以印证。
2、STAR法则
在面试里能起到有效回答问题作用的方法是STAR法则,它涵盖着如下几个步骤, 。
借助STAR法则,能够助力你于面试期间,清晰且有条理地去回答问题,进而展示自身的能力以及经验。
我们讲解做过的项目的时候非常适合使用STAR法则。
先是介绍关于咱们项目的业务背景,以及技术背景,接着要讲清楚当下正着手去做的一件什么事情,随后阐述具体的技术方案,以及该如何去落地实施,最后说明在我们从事的这个项目上取得了怎样的结果。
这样面试官就比较容易理解,就会认为面试者逻辑性很强。
3、学会倾听
面试官提出一个问题,哪怕你恰好对其极为熟悉,也绝对不要进行「抢答」。一方面,有可能你根本就没有领会面试官所问的问题;另一方面,打断他人始终还是不太符合尊重他人的行为准则。面试官同样是最为普通的人,只要是人就会受到情绪的操控,一旦给对方留下不好的印象,极有可能就会对此次面试的通过率产生影响。
面试官,乃是会成为你未来同事之人,你能够将面试官当作你的工作搭档来展开沟通,于此便利去实施双向筛选 。
二、面试流程
一般技术人员的面试为2-3轮技术面,一轮hr面试。
三、面试实战
一般Java面试会围绕项目,知识点,算法三个点进行展开。
公司招人是为干活,为解决业务问题,其中最关键的乃是项目,故而对于过往项目的考查便显得颇为重要了。
一)自我介绍
第一阶段是自我介绍,此时间是为给面试官营造一个第一印象,运用上面的金字塔原则来讲出自身最突出的优势,借此引导面试官询问自己最擅长的部分,不然若被问到不擅长的而答不上来便会被减分。
假设你所精通的是JVM调优,那么你就要着重讲一下,在后续的项目里也能够不断提及这个要点。
案例如下
二)项目
项目属于信息量最为大的那一部分,它能够真切反映出你的工作状态,究竟是写出来的代码只要可以使用便行,还是对于边界控制、代码性能以及架构设计有着自身独立的思考呢 。
案例如下
三)知识点
循着上面项目采用的技术,开展知识点追问,存在一些面试官极有可能追根究底直至操作系统层面。
案例如下
面试官:
你们使用Mysql,于Mysql选用使用过程里,是否遭遇了什么问题呢,对我而言,我在看你们用它 。
面试者:
我们遭遇到,Mysql里limit分页被误用,进而致使Mysql负载急剧飙高的状况,出现了问题。
MySQL之中的LIMIT子句常常被用于分页,然而在处理数目众多的数据之际,要是没有加以留意,它极有可能会致使效率方面出现问题,尤其是当你运用了偏移量的时候。比如说:
从表名中选取所有内容,依照id加以排序,限定偏移量为十万,数量为十条 。
进行这样的查找会找寻到前面的100,010个记录,然而仅仅会返回末尾的10个 。这表明前面的100,000个结果于实际情况而言是没有用处的,不过依旧会被MySQL搜索出来,如此便会导致产生没有必要的I/O以及CPU负荷 。
我们针对SQL做了优化,去除了大limit,将其改为先凭借id filter,随后对id进行排序,最终运用limit的方法化解了此问题。
选择所有内容,从表名称当中,在条件是标识大于十万的情况下,按照标识进行排序,限定数量为十条 。
四)算法
常见的算法考核形式,是考leetcode原题,或者进行基于场景的代码编写 。
通常情况下,我不会去考leetcode的原题,这是由于其带来的意义并不是很大,要是背过了,那么就会出现若是没背过之情形可就要卡壳了,就算是那些水平十分高的人,也并不具备AI写得那么快的能力。
应该重点考核工作中实际场景如何解决问题。
我通常会搞两个线程,让它们交替着去打印奇数和偶数。这道题呢,它的难度并非特别大,既能够对面试者的代码能力展开考察,又能够对多线程的熟悉程度予以考察,并且还能够对多线程的知识点进行深入考察。
面试官:
写一个代码两个线程交替打印奇数偶数
面试者:
能够运用wait()以及notify()方法达成线程之间的协作 。
有一个被大家共享的锁对象LOCK,我们使用了它。奇数线程与偶数线程会轮流去获取此锁,之后查看当前数字是不是符合各自的输出条件。要是符合,那就输出数字,让数字增加并且唤醒别的线程;要是不符合,那就使当前线程处于等待状态。
public class AlternatePrint {
私有的静态的最终的对象,被称作LOCK,它是通过新建一个对象而得来的 。
私有的静态的整数类型的变量 number 被赋值为 1 。
私有,静态,最终的整型变量MAX,其值被设定为100 。
公用静态无效主函数,参数为字符串数组形式的参量集合 { } ,标点依次为:句号、逗号、左花括号且无换行。
线程奇数线程等于一个线程(该线程执行的内容为λ表达式其意为将括弧内的代码块作为线程执行体并执行)。
while (number <= MAX) {
synchronized (LOCK) {
if (number % 2 == 1) {

System.out.println(Thread.currentThread().getName() + " : " + number);
number++;
LOCK.notify();
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "OddThread");
Thread evenThread = new Thread(() -> {
while (number <= MAX) {
synchronized (LOCK) {
if (number % 2 == 0) {
System.out.println(Thread.currentThread().getName() + " : " + number);
number++;
LOCK.notify();
} else {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "EvenThread");
oddThread.start();
evenThread.start();
}
}
面试官:
还有别的实现方式么?
面试者:
运用volatile关键字能够保证一个变量的读取与写入操作对于所有线程来讲都是被看见的,也就是说某一个线程更改了一个volatile变量之后,其他线程能够马上察觉到修改之后的值 。
要是想要借助volatile去操控两个线程交替开展输出,那么能够采用一个volatile标志,以此来表明究竟是哪一个线程应当去执行输出 。
我们运用了isOdd这个具有volatile特性的变量,用以标明当下应由哪一个线程进行输出。当isOdd呈现为true之际,奇数线程负责输出数字且使其递增,随后将isOdd设定为false。当isOdd处于false状态之时,偶数线程输出数字并予以递增,之后把isOdd设置成true。
使用volatile的此种方法,有可能致使CPU出现忙等待的情况,原因在于线程会于一个循环里持续地去检查isOdd的值,并且未进入休眠状态,如此一来,便可能会使CPU的使用率有所增加和提高。
公共的类,名为交替打印易变的,{} 注:这里的易变是形容可能会有变化的特性,类名为alternate print volatile,{}。
私有的静态的易变的整型变量 number 被赋值为 1 ,句号。
private static final int MAX = 100;
专门设置为静态的,具有易变特性的布尔类型变量,名为isOdd,其初始值被设定为真,这里要说明的是,真表示奇数线程应当执行打印操作,而假则表示偶数线程应当执行打印操作 。
public static void main(String[] args) {
Thread oddThread = new Thread(() -> {
while (number <= MAX) {
if (isOdd) {
System.out.println(Thread.currentThread().getName() + " : " + number);
number++;
isOdd = false;
}
}
}, "OddThread");
Thread evenThread = new Thread(() -> {
while (number <= MAX) {
if (!isOdd) {
System.out.println(Thread.currentThread().getName() + " : " + number);
number++;
isOdd = true;
}
}
}, "EvenThread");
oddThread.start();
evenThread.start();
}
}
面试官:
volatile的实现原理是啥?
面试者:
blabla..(又过去十分钟)
面试官:
整挺好!
四、最后
是金子总会发光,希望大家都能找到心仪的工作。