高级java程序员:21道最新Java面试题剖析

纵观几年来的Java面试题,你会发现每家都差不多。你仔细观察就会发现,HashMap的出现几率未免也太高了吧!连考察的知识点都一样,什么hash碰撞啊,并发问题啊!再比如JVM,无外乎考内存结构,GC算法等!因此,如果是为了面试,完全是有套路可以准备的!记住,基础再好,也架不住面试官天马行空的问,所以刷面试题还是很有必要的!

面试题解析

1、Map的底层结构?(HashMap)

评注:老题目了,各位面试的人员必须熟记!

回答:Map是以键值对来存储对象的,它的底层实际上是数组和链表来组成的,经典的一张图如下(别人画的);

当使用put方法时,先查找出数组位置是否存在对象,通过key.hashcode对数组长度取余;存在,则把里面的链表拿出来,判断链表里面是否存在key值与传递过来的key值一样的对象,存在,则把传递过来的value取代链表key对应的value,不存在,则直接通过链表的add()方法加到链表后面;

当使用get方法时,先查找出数组位置是否存在对象,通过key.hashcode对数组长度取余;如果不存在,则返回为空,如果存在,则遍历链表,判断链表里面是否存在key值与传递过来的key值一样的对象,存在,则把key值对应的value取出返回,不存在,则返回为空;

2、线程安全的Map(concurrentHashMap)简单的说了下这两1.7和1.8的区别,本想问下要不要深入的讲下(源码级别),结果面试官说不用了。

回答:

jdk1.7中采用Segment+HashEntry的方式进行实现,结构如下:

Segment数组的意义就是将一个大的table分割成多个小的table来进行加锁,而每一个Segment元素存储的是HashEntry数组+链表,这个和HashMap的数据存储结构一样

而jdk1.8中则

去除Segment+HashEntry+Unsafe的实现,

改为Synchronized+CAS+Node+Unsafe的实现

其结构图如下:

如上图所示,取消了Segment字段,数组中存储的就是Node。它与HashMap中的HashEntry定义很相似,但是有一些差别。它对value和next属性设置了volatile同步锁,它不允许调用setValue方法直接改变Node的value域。

另外,将原先table数组+单向链表的数据结构,变更为table数组+单向链表+红黑树的结构,在hash碰撞过多的情况下会将链表转化成红黑树。

3、项目MySQL的数据量和并发量有多大?

评注:此题为走向题,你的回答不同,后面问题走向就变了。

关于容量:单表行数超过500万行或者单表容量超过2GB,此时就要答分库分表的中间件了!那后面题目的走向就变为mycat、sharing-jdbc等分库分表中间件的底层原理了!

关于并发量:如果并发数过1200,此时就要答利用MQ或者redis等中间件,作为补偿措施,而不能直接操作数据库。那后面的题目走向就是redis、mq的原理了!

介于面试者还是一个应届生,我斗胆猜测面试者是这么答的

回答:数据量估计就三四百万吧,并发量就五六百左右!

4、你对数据库了解多少?

评注:因为你答的数据量和并发量不大,因此中间件这块没啥好问的。因此,题目走向变为数据库底层!另外,此题为引导题,面试官在给你机会引向你最擅长的方面!

回答:了解常见数据库调优方法,索引优化等!

5、你说下数据库的索引实现和非主键的二级索引

评注:这个问题是根据上面,你的回答而问出来的!记得引向自己最擅长的数据库基础知识!默认是回答mysql数据库的

从数据结构角度:

B-Tree索引,数据结构就是一颗B+树。

Hash索引,Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤。基本不用!

R-Tree索引,仅支持geometry数据类型,也基本不用!

至于非主键的二级索引,这个实际上问的就是非聚簇索引!非聚簇索引本身就是一颗B+树,其根节点指向聚簇索引的B+树。

6、项目用的是SpringBoot,你能说下SpringBoot与Spring的区别吗?

评注:基础题,会springboot的,基本都答的上来。就算没准备过,当场思考下都可以回答的出来!也是属于引导题!

SpringBoot可以建立独立的Spring应用程序;

内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。

无需再像Spring那样搞一堆繁琐的xml文件的配置;

可以自动配置Spring;

提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;

提供的POM可以简化Maven的配置

7、SpringBoot的自动配置是怎么做的?

评注:此题也是根据你的第七问,进一步提问而得出。

先答为什么需要自动配置?

顾名思义,自动配置的意义是利用这种模式代替了配置XML繁琐模式。以前使用SpringMVC,需要进行配置组件扫描、调度器、视图解析器等,使用SpringBoot自动配置后,只需要添加MVC组件即可自动配置所需要的Bean。所有自动配置的实现都在spring-boot-autoconfigure依赖中,包括SpringMVC、Data和其它框架的自动配置。

接着答spring-boot-autoconfigure依赖的工作原理

spring-boot-autoconfigure依赖的工作原理很简单,通过@EnableAutoConfiguration核心注解初始化,并扫描ClassPath目录中自动配置类对应依赖。比如工程中有木有添加Thymeleaf的Starter组件依赖。如果有,就按按一定规则获取默认配置并自动初始化所需要的Bean。

其实还能再继续答@EnableAutoConfiguration注解的工作原理!不过篇幅太长,答到上面那个地步就够了!

8、MyBatis定义的接口,怎么找到实现的?

评注:mybatis底层原理题,考察有没有看过mybatis的原理。博主刚好曾经自己写过一个mybatis,所以此题恰巧答的上来。

博主内心活动:"现在校招的都这么牛逼了么!"

回答:一共五步

1.Mapper接口在初始SqlSessionFactory注册的。

2.Mapper接口注册在了名为MapperRegistry类的HashMap中,key=Mapperclassvalue=创建当前Mapper的工厂。

3.Mapper注册之后,可以从SqlSession中get

4.SqlSession.getMapper运用了JDK动态代理,产生了目标Mapper接口的代理对象。

5.动态代理的代理类是MapperProxy,这里边最终完成了增删改查方法的调用。

9、Java内存结构

评注:基础题,这个应该学JAVA的都会吧!送分题!如果博主没理解错应该是在问JVM的内存结构!

回答:JVM内存结构主要有三大块:堆内存、方法区和栈。堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间、FromSurvivor空间、ToSurvivor空间,默认情况下年轻代按照8:1:1的比例来分配;

方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。

10、对象是否可GC?

评注:这个问题就是在问,JVM如何判断对象是否需要被回收!不用答引用计数法,答可达性分析算法就行。

这个算法的基本思路是通过一些列称为“GCRoots”的对象作为起始点,从这些点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GCRoots没有任何引用链相连时,则证明对象需要被回收.

如图:

上图中o3,o4对象没有任何GCRoots可达到,所有这两个对象不可用了,需要被GC回收

Java可作为GCRoots的对象包括下面几种:

虚拟机栈中引用的对象

方法区中类静态属性引用的对象

方法区中产量引用的对象

本地方法栈中JNI引用的对象

11、MinorGC和FullGC

评注:基础题,会JVM调优的,基本都会!我只是奇怪,怎么没问MajorGC呢?我们还是把MajorGC也给答了吧!

堆内存是JVM中最大的一块由年轻代和老年代组成。

那么,从年轻代空间(包括Eden和Survivor区域)回收内存被称为MinorGC。

MajorGC是清理老年代。

FullGC是清理整个堆空间—包括年轻代和老年代。

12、垃圾回收算法

评注:基础题,博主斗胆猜测,应该是在问垃圾回收算法有哪些。面试官应该没有耐心去听你一个个去背算法概念!

标记-清除算法、标记整理算法、复制算法、分代收集算法

13、垃圾回收器G1

评注:上面的题目更深入的问法。JVM可以配置不同的回收器。比如Serial,Parallel和CMS几种垃圾回收器。以SerialCollector(串行回收器)为例,它在在年轻代是一个使用标记-复制算法的回收器。在老年代使用的是标记-清扫-整理算法。

另外,关于G1回收器可以问的点很多,此题作者没有描述清楚究竟问的是G1回收器的那个点,就满回答一下概念吧!

如果是我来问,我就直接给你场景,问你该用哪种回收器了。直接问回收器,那就比较容易了!

常用参数:

-XX:+UseSerialGC:在新生代和老年代使用串行收集器

-XX:+UseParNewGC:在新生代使用并行收集器

//自己查询吧,太多了!

G1GC是Jdk7的新特性之一、Jdk7+版本都可以自主配置G1作为JVMGC选项。G1将整个堆划分为一个个大小相等的小块(每一块称为一个region),每一块的内存是连续的,每个块也会充当Eden、Survivor、Old三种角色,但是它们不是固定的,这使得内存使用更加地灵活。如下图所示

执行垃圾收集时,收集线程在标记阶段和应用程序线程并发执行,标记结束后,G1也就知道哪些区块基本上是垃圾,存活对象极少,G1会先从这些区块下手,因为从这些区块能很快释放得到很大的可用空间,这也是为什么G1被取名为Garbage-First的原因。

14、项目里用过ElasticSearch和Hbase,有深入了解他们的调优技巧吗?

评注:一个应届生搭的ElasticSearch和Hbase,一般都只是demo级别的,懂基本的CRUD的使用即可!一般不会去深入了解调优技巧的!这个问题如果答深入了解过,是给自己挖坑!因为这个问题,答案太广了!

回答:并没有深入了解过!

15、SpringRestTemplate的具体实现

评注:这题问的博主有点懵!如果是我来问,我会先问访问Rest服务的客户端这么多,为什么选SpringRestTemplate?然后才来原理。这个突然就冒出一个具体实现,我是有点懵啦!

其实RestTemplate和sl4fj这种门面框架很像,本质就是在Http的网络请求中增加一个马甲,本身并没有自己的实现。

那么RestTemplate则封装了组装、发送HTTP消息,以及解析响应的底层细节。

答到这个份上可以了,难道你还要把类之间关系的引用图,画出来?太不现实了!

16、描述下网页一个Http请求,到后端的整个请求过程

评注:基础题,感觉属于常识题!必会!

17、多线程的常用方法和接口类及线程池的机制

评注:基础题,基本会点线程知识的,多多少少都会答点!但是这道题,我感觉范围有点大啊!可能是作者没表述清楚吧!

常用方法:

start,run,sleep,wait,notify,notifyAll,join,isAlive,currentThread,interrupt

常用接口类:

Runnable、Callable、Future、FutureTask

线程池的机制:

简单的线程池包括如下四个组成部分即可:

线程池管理器(ThreadPoolManager):用于创建并管理线程池

工作线程(WorkThread):线程池中线程

任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行

任务队列:用于存放没有处理的任务。提供一种缓冲机制

18、总结我的Java基础还是不错,但是一些主流的框架源码还是处在使用的状态,需要继续去看源码

评注:坦白说,我没看出来哪些问题体现出主流的框架还是处在使用的状态。

19、死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。

产生死锁的原因主要是:

(1)因为系统资源不足。

(2)进程运行推进的顺序不合适。

(3)资源分配不当等。

20、自己研究比较新的技术,说下成果!

评注:嗯,凸显自己的潜力,大家自由发挥!

21、你有什么想问的?我就问了下公司那边的情况,这个自由发挥!

学Java可以从事什么工作,职业发展无限可能!

软件培训班学费多少?让我们来一探究竟!

软件开发培训机构如何选择,去哪里学习更好?

人工智能培训机构哪个好?

学编程的学费一般是多少费用?

学Java六个月感觉啥也不会?不要担心,让我来帮助你!

0基础0学费15天面授

有基础直达就业

工作1~3年,加薪神器

工作3~5年,晋升架构

初级202925

初级203221

初级202629

初级203743

答:零基础学Java不要盲目,可以先尝试自己适不适合...查看回答

THE END
1....1.定义一个描述宠物的抽象类Pet,包含重量(weight)和年龄(age...根据题意,利用面向对象程序设计的思想完成如下代码设计: 1.定义一个描述宠物的抽象类Pet,包含重量(weight)和年龄(age)两个成员变量和显示宠物资料的showInfo方法以及获取宠物资料的getInfo方法 ; 2.设计一个可吃的接口Eatable,包含一个被吃(beEatted)的方法 ; 3https://m.ppkao.com/wangke/daan/b979677cf11946dd8b8788209425c153
2.2023Web前端开发八股文&面试题(万字系列)——这篇就够了!代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。 了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。 渲染性能: 属性值为0时,不加单位。 可以省略小数点之前的0。 标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。 https://developer.aliyun.com/article/1353677
3.防水材料简介分类防水材料品种繁多,按其主要原料分为4类:①沥青类防水材料。以天然沥青、石油沥青和煤沥青为主要原材料,制成的沥青油毡、纸胎沥青油毡、溶剂型和水乳型沥青类或沥青橡胶类涂料、油膏,具有良好的粘结性、塑性、抗水性、防腐性和耐久性。②橡胶塑料类防水材料。以氯丁橡胶、丁基橡胶、三元乙丙橡胶、聚氯乙烯、聚...https://jijian.sdwu.edu.cn/info/1014/1027.htm
4.mysql经典面试题MySQL@下一站触发器是一段能自动执行的程序,是一种特殊的存储过程,触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作时触发。诸如: update、 insert、 delete 这些操作的时候,系统会自动调用执行该表上对应的触发器。 SQL Server 2005 中触发器可以分为两类:DML 触发器和 DDL 触发器,其中 DDL 触发器它们会影...https://xie.infoq.cn/article/d1487934db6082b162810ddeb
5.面试题170. test.bns.com.cn 的域名是bns.com.cn ,如果要配置一域名服务器,应在named.conf 文件中定义DNS 数据库的工作目录。 71. Sendmail 邮件系统使用的两个主要协议是:_和 _ ,前者用来发送邮件,后者用来接收邮件。 72. DHCP 是动态主机配置协议的简称,其作用是:为网络中的主机_ 。 https://www.jianshu.com/p/c2ee8bde5210
1.深度刨析“类”类是一种数据类型(引用类型),具体到每一个类上,每一个类都是自定义类型 比如具体到学生类上,它是我们自定义的类。 可以用类声明变量、创造实例(类当成实例的模板)。这就体现了它是数据类型 类代表现实世界的“种类” 类的静态成员,体现的就是类这个种类的特征。比如自定义学生类中静态成员total表示学生总人数...https://blog.csdn.net/m0_65804432/article/details/143767019
2.泛型类其中一个有用的规则是,应用最大程度的约束,同时仍可处理必须处理的类型。 例如,如果知道泛型类仅用于引用类型,则请应用类约束。 这可防止将类意外用于值类型,并使你可在T上使用as运算符和检查 null 值。 是否将泛型行为分解为基类和子类。 因为泛型类可用作基类,所以非泛型类的相同设计注意事项在此也适用。 请...https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/generics/generic-classes
3.java猫狗实验mob64ca12d52440的技术博客步骤1:定义Cat类 首先,我们要定义一个Cat类,用于表示猫的属性和行为。我们可以为猫定义属性,如名字、年龄和颜色,并定义方法,如叫声和行走。 publicclassCat{privateStringname;privateintage;privateStringcolor;publicCat(Stringname,intage,Stringcolor){this.name=name;this.age=age;this.color=color;}publicvoidmeow...https://blog.51cto.com/u_16213319/8774007
4.类型断言·TypeScript入门教程可是swim 函数接受的参数是 Cat | Fish,一旦传入的参数是 Cat 类型的变量,由于 Cat 上没有 swim 方法,就会导致运行时错误了。总之,使用类型断言时一定要格外小心,尽量避免断言后调用方法或引用深层属性,以减少不必要的运行时错误。将一个父类断言为更加具体的子类§当类之间有继承关系时,类型断言也是很常见的:...https://ts.xcatliu.com/basics/type-assertion.html
5.2023年初中英语阅读理解专题(二)英语阅读(一)根据定义或解释猜测词义 A bag is useful and the word “bag” is useful. It gives us some interesting phrases(短语). One is “ to let the cat out of the bag”. It is the same as “to tell a secret”…. Now when someone lets out (泄漏) a secret, he “lets the cat out ...http://www.zhongkao.com/e/20230331/6426c7d83a06d.shtml
6.前端200道面试题及答案(更新中)添加相同的样式,如果想要修改一种样式,又不得不修改所有的 style 中的代码。很显然,内联方式引入 CSS 代码会导致 HTML 代码变得冗长,且使得网页难以维护。 嵌入样式 嵌入方式也称页级CSS或内部CSS,整体是放在head标签里边的,在style标签里边定义样式,作用范围和字面意思相同,仅限于本页面的元素;如果你写的代码超过了...https://leheavengame.com/article/64d7982931f3516f1405dd03
7.自考C++程序设计2016年4月试题自考7.类Cat是类Animal的公有派生类,类Animal和类Cat中都定义了虚函数func( ),p是一个指向类Animal对象的指针,则p-﹥Animal:: func( )将( ) A.调用类Animal中的函数func( ) B.调用类Cat中的函数func( ) C.根据p所指的对象类型而确定调用类Animal中或类Cat中的函数func( ) ...https://www.educity.cn/zikao/26423.html
8.成功斩获腾讯offer,分享我的面试经历(附书籍推荐,资料分享)可以,而且如果说这个类不是final的,也就是说他是某一个类的父类,那么该类的析构函数必须是虚函数,因为如果不是虚函数,那么其子类对象的父类组成部分将无法得到释放,造成资源泄露。 8、析构函数可不可以是纯虚函数? 我觉得不建议是,因为我们知道纯虚函数是没有实现体的,那么子类对象在析构的时候,父类组成部分...https://maimai.cn/article/detail?fid=1367118499&efid=dxTzJOD7aSelu7sneqtM2g
9.计算机二级C语言考试冲刺练习题A、C语言程序总是从第一个定义的函数开始执行 B、在C语言程序中,要调用的函数必须在main( )函数中定义 C、C语言程序总是从main( )函数开始执行 D、C语言程序中的main( )函数必须放在程序的开始部分 4.下列关于C语言的说法错误的是( B ) 。 A、 C程序的工作过程是编辑、编译、连接、运行 ...https://www.oh100.com/kaoshi/ncre2/tiku/538366.html
10.SpringBoot部署与服务配置方式java2、Java类中@Profile注解 下面2个不同的类实现了同一个接口,@Profile注解指定了具体环境 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 // 接口定义 public interface SendMessag...https://www.jb51.net/program/322041ntd.htm
11.价差700你选谁?魅族MX4/MX4Pro对比(全文)魅族MX4其次是锁屏自定义右滑,在Flyme 4.0中也有这一功能,不过是要在锁屏界面右滑然后选择相应功能点击进入的。在Flyme 4.1中用户直接在设置菜单里选中想实现的功能,然后锁屏状态下右滑就直接进入,方便很多。而Flyme 4.1也加入了语音唤醒,开启功能后对着手机说“你好魅族”就可以直接唤醒手机。 https://mobile.zol.com.cn/493/4931233_all.html