8 年 java 技术岗面试官总结:2022 超强面试大全,抓住 2022 的小尾巴
前言
首先我们需要明白一个事实,招聘的一个很关键的因素是在给自己找未来的同事,同级别下要找比自己优秀的人,面试是一个双向选择的过程,也是一个将心比心去沟通的过程。
就像我们有的人感觉自己很牛逼,但是拿不到 offer,而其他的人菜的一笔,却可以拿到 offer,我们称之为玄学 offer,遇到这种情况大家也不要感觉到有什么不可描述的心情,一切随缘即可!
一眼就能看得到头,不是我们想要的生活,我们为之努力,不是为了飞黄腾达,睥睨群雄,而是努力让自己的生活多一种可能,给自己的未来多一份惊喜。
正文
下面提的问题可以看下你自己是否能回答出来,是否做好准备了,当然面试题准备是一方面,你本身的技能掌握是一方面,本身技能不过硬也会被刷下来
先说下面试流程,一般大公司都有 3-4 轮技术面,1 轮的 HR 面。就搜狐而言,我共经历了 4 轮技术面,前两轮主要是问基础和项目实现,第 3 轮是交叉面,两个面试官,主要是问项目实现和拓展。第 4 轮是部门老大面,主要就问一些架构、技术和业务的理解、个人发展比较抽象的东西了,现在基本也是这样的。
要注意的点
简历一到两页为最佳,将项目经历写 2-3 个左右就差不多了,一定要写最有亮点的项目
工作经历的起始时间要写清楚,另外大公司都有背调,不要合并或省略一些比较短的工作经历,影响的可能不只是这次面试,而是之后可能都无法进这家公司
博客没什么好文章,github 没好项目就不要写在简历中了
对于面试官的问题,想清楚再回答,如果觉得需要的时间可能比较长,可以跟面试官说我思考下、我整理下思路之类的
面试的过程中注意语速和吐字,本人在做面试官后,发现很多人说话语速很快,或吐字不清,导致原本会的问题也会让面试官觉得你没答到点上(尤其是电话面)
面试完后不要直接问面试结果
技术考察
总的来说,技术相关的考察主要分为两大块,一是基础,二是经验,基础包括 java 基础、数据库、中间件等,来自于日常的积累和面试前的准备。
经验包括以往做过的项目、解决的问题、以及一些场景题(比如你的项目如果流量大了十倍如何保证可用)。
开场白简单的介绍一下自己的工作经历与职责,在校或者工作中主要的工作内容,主要负责的内容;(你的信息一清二白的写在简历上,能答出来的最好写在上面,模棱两可不是很清楚的最好不要写,否则会被问的很尴尬)介绍下自己最满意的,有技术亮点的项目或平台,重点介绍下自己负责那部分的技术细节;(主要对自己做过的事情是否有清晰的描述)
因为头条篇幅原因,答案和解析全在末尾了
分享一个写的很不错的框架源码图
部分题目和解析
1、STRING 与 STRINGBUFFER 的区别。
答: STRING 的长度是不可变的,STRINGBUFFER 的长度是可变的。如果你对字符串中的内容经常进行操作,特别是内容要修改时,那么使用 StringBuffer,如果最后需要 String,那么使用 StringBuffer 的 toString()方法
2、谈谈 final, finally, finalize 的区别
答: final—修饰符(关键字)如果一个类被声明为 final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract 的,又被声明为 final 的。将变量或方法声明为 final,可以保证它们在使用中不被改变。被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final 的方法也同样只能使用,不能重载 finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的
3、面向对象的特征有哪些方面
答: 主要有以下四方面:1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。3.封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。4. 多态性:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
4、String 是最基本的数据类型吗
答: 基本数据类型包括 byte、int、char、long、float、double、boolean 和 short。java.lang.String 类是 final 类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用 StringBuffer 类
5、int 和 Integer 有什么区别
答: Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int 是 java 的原始数据类型,Integer 是 java 为 int 提供的封装类。Java 为每个原始类型提供了封装类。原始类型封装类,booleanBoolean,charCharacter,byteByte,shortShort,intInteger,longLong,floatFloat,doubleDouble 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关
6、运行时异常与一般异常有何异同
答: 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
7、说出 ArrayList,Vector, LinkedList 的存储性能和特性
答: ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector 由于使用了 synchronized 方法(线程安全),通常性能上较 ArrayList 差,而 LinkedList 使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
8、HashMap 和 Hashtable 的区别
答: HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,主要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,效率上可能高于 Hashtable。HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey。因为 contains 方法容易让人引起误解。 Hashtable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。最大的不同是,Hashtable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。 Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。
9、heap 和 stack 有什么区别
答: 栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。堆是栈的一个组成元素
10、Java 的接口和 C++的虚类的相同和不同处
答: 由于 Java 不支持多继承,而有可能某个类或对象要使用分别在几个类或对象里面的方法或属性,现有的单继承机制就不能满足要求。与继承相比,接口有更高的灵活性,因为接口中没有任何实现代码。当一个类实现了接口以后,该类要实现接口里面所有的方法和属性,并且接口里面的属性在默认状态下面都是 public static,所有方法默认情况下是 public.一个类可以实现多个接口。
更多面试题
一、性能优化面试专栏
tomcat 性能优化整理
JVM 性能优化专题
Mysql 性能优化整理
Tomcat 顶层架构小结:
(1)Tomcat 中只有一个 Server,一个 Server 可以有多个 Service,一个 Service 可以有多个 Connector 和一个 Container;(2) Server 掌管着整个 Tomcat 的生死大权;(4)Service 是对外提供服务的;(5)Connector 用于接受请求并将请求封装成 Request 和 Response 来具体处理;(6)Container 用于封装和管理 Servlet,以及具体处理 request 请求;
知道了整个 Tomcat 顶层的分层架构和各个组件之间的关系以及作用,对于绝大多数的开发人员来说 Server 和 Service 对我们来说确实很远,而我们开发中绝大部分进行配置的内容是属于 Connector 和 Container 的,所以接下来介绍一下 Connector 和 Container。
Connector 和 Container 的微妙关系
由上述内容我们大致可以知道一个请求发送到 Tomcat 之后,首先经过 Service 然后会交给我们的 Connector,Connector 用于接收请求并将接收的请求封装为 Request 和 Response 来具体处理,Request 和 Response 封装完之后再交由 Container 进行处理,Container 处理完请求之后再返回给 Connector,最后在由 Connector 通过 Socket 将处理的结果返回给客户端,这样整个请求的就处理完了!
Connector 最底层使用的是 Socket 来进行连接的,Request 和 Response 是按照 HTTP 协议来封装的,所以 Connector 同时需要实现 TCP/IP 协议和 HTTP 协议!
Tomcat 既然处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下 Connector!
更多解析
二、微服务架构面试专栏
1、SpringCloud 面试整理
2、SpringBoot 面试整理
3、Dubbo 面试整理
请谈一下 你对 SpringBoot 和 SpringCloud 的理解
SpringBoot:专注于快速方便的开发单个个体微服务(关注微观)
SpringCloud:关注全局的微服务协调治理框架,将 SpringBoot 开发的一个个单体微服务组合并管理起来(关
注宏观)
SpringBoot 可以离开 SpringCloud 独立使用,但是 SpringCloud 不可以离开 SpringBoot,属于依赖关系
什么是服务熔断?什么是服务降级?
服务熔断
这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
熔断机制的注解是 @HystrixCommand
熔断机制是应对雪崩效应的一种链路保护机制,一般存在于服务端
当扇出链路的某个服务出现故障或响应超时,会进行服务降级,进而熔断该节点的服务调用,快速返回“错误”的相应信息
服务降级
当系统整体资源快不够的时候,忍痛将部分服务暂时关闭,带渡过难关后,再重新开启。
降级处理时在客户端完成的,与服务端没有关系
理解:所谓降级,一般是从整体负荷考虑,当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的 FallBack 回调,返回一个缺省值。这样做虽然服务水平下降,但好歹可用,比直接挂掉好
为什么要解耦
如果按照上面的熔断案例来做的话,Controller 下的每个方法,都要给其编写一个 FallBack 方法,当方法慢慢变多,就会造成代码膨胀,一个是增加编写的工作量,另外一个也会增大维护的难度,代码的耦合度也会高,是十分不合理的,所以要将其解耦。
解耦思路:
因为服务端的是通过实现接口访问服务端的,如果在父接口上实现了 FallBack 方法,通过这样一种方式去维护起来就能实现解耦,也顺便完成了降级的机制。
更多解析
三、并发编程高级面试专栏
由于头条篇幅原因,无法全部展示,
需要这份资料可以+ VX: w15629032679
四、开源框架面试专栏
4.1、Spring 面试整理
4.2、SpringMVC 面试整理
4.3、MyBatis 面试整理
1、选择使用 Spring 框架的原因?
使用 Spring: 第一是使用它的 IOC 功能,在解耦上达到了配置级别。 第二是使用它对数据库访问事务相关的封装。 第三就是各种其他组件与 Spring 的融合,在 Spring 中更加方便快捷的继承其他一些组件。
2、Spring 是如何管理事务的?
spring 的事务声明有两种方式,编程式和声明式。spring 主要是通过“声明式事务”的方式对事务进行管理,即在配置文件中进行声明,通过 AOP 将事务切面切入程序,最大的好处是大大减少了代码量。
3、Spring IoC 容器配置 Bean 的方式?
答:
基于 XML 文件进行配置。
基于注解进行配置。
基于 Java 程序进行配置(Spring 3+)
更多解析
五、分布式面试专栏
分布式限流面试整理
分布式通讯面试整理
分布式数据库面试整理
请解释 Nginx 如何处理 HTTP 请求。
Nginx 使用反应器模式。主事件循环等待操作系统发出准备事件的信号,这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。单个线程可以提供数万个并发连接。
在 Nginx 中,如何使用未定义的服务器名称来阻止处理请求?
只需将请求删除的服务器就可以定义为:
这里,服务器名被保留为一个空字符串,它将在没有“主机”头字段的情况下匹配请求,而一个特殊的 Nginx 的非标准代码 444 被返回,从而终止连接。
更多题目和答案解析
最后
欢迎做 Java 的工程师朋友们可以+ VX: w15629032679 免费获取这个近 400 题的面试题 PDF,
还有更多免费的 Java 架构学习资料,其中覆盖了互联网的方方面面,期间碰到各种产品各种场景下的各种问题,希望可以帮助大家扩展自己的技术广度和知识面。
评论