本文的题目出自博客
http://www.54tianzhisheng.cn/2018/07/12/youzan/
可是做者没有给出答案,博主斗胆来制做答案版。css
说在前面的话:
本文适合人群:急等着换工做的人
我认可刷面试题颇有用的,纵观几年来的JAVA面试题,你会发现每家都差很少。好比,你仔细观察,你会发现,HashMap的出现概率未免也过高了吧!连考察的知识点都同样,什么hash碰撞啊,并发问题啊!再好比JVM,无外乎考内存结构,GC算法等!所以,若是是为了面试,彻底是有套路能够准备的!记住,基础再好,也架不住面试官天马行空的问,因此刷面试题仍是颇有必要的!html
本文不适合人群:专攻JAVA某方面技术的人
由于这类人专攻JAVA某块技术,知识容易出现死角。贸然阅读本文,发现本身一堆题目都不会,会以为有一种挫败感,发现本身连校招生都不如。然而,会点面试题不算什么,毕竟Homebrew做者也出现过解不出面试题,被Google拒绝,原因就是,由于他不会翻转二叉树。难道你能说Homebrew的做者水平有问题!java
一、自我介绍
评注:这个地方答什么随意,大部分面试官不会听你介绍,这个时间都在看简历。若是是电话面,回答时间控制在40秒到1分钟左右就行。若是是现场面,那就好办了,你注意看面试官何时抬头看你,通常面试官放下简历,抬头看你的时候,赶忙收尾!
回答:我叫xx,毕业于xxx,兴趣xx,作过xx项目....mysql
二、Map 的底层结构?(HashMap)
评注:老题目了,各位面试的人员必须熟记!
回答:Map是以键值对来存储对象的,它的底层其实是数组和链表来组成的,经典的一张图以下(别人画的);
当使用put方法时,先查找出数组位置是否存在对象,经过key.hashcode对数组长度取余;存在,则把里面的链表拿出来,判断链表里面是否存在key值与传递过来的key值同样的对象,存在,则把传递过来的value取代链表key对应的value,不存在,则直接经过链表的add()方法加到链表后面;面试
当使用get方法时,先查找出数组位置是否存在对象,经过key.hashcode对数组长度取余;若是不存在,则返回为空,若是存在,则遍历链表,判断链表里面是否存在key值与传递过来的key值同样的对象,存在,则把key值对应的value取出返回,不存在,则返回为空;redis
三、线程安全的 Map (concurrentHashMap)简单的说了下这两 1.7 和 1.8的区别,本想问下要不要深刻的讲下(源码级别),结果面试官说不用了。
评注:老题目了,若是有时间,再去了解一下,解决HashMap线程安全的各类方法,以及原理!此题只能大概回答一下结构的变化,由于其中的实现代码都变了,细说能够说好久,估计面试官也没时间听!
回答:
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碰撞过多的状况下会将链表转化成红黑树。算法
四、项目 MySQL 的数据量和并发量有多大?
评注:此题为走向题,你的回答不一样,后面问题走向就变了。
关于容量:单表行数超过 500 万行或者单表容量超过2GB,此时就要答分库分表的中间件了!那后面题目的走向就变为mycat、sharing-jdbc等分库分表中间件的底层原理了!
关于并发量:若是并发数过1200,此时就要答利用MQ或者redis等中间件,做为补偿措施,而不能直接操做数据库。那后面的题目走向就是redis、mq的原理了!
介于面试者仍是一个应届生,我斗胆猜想面试者是这么答的
回答:数据量估计就三四百万吧,并发量就五六百左右!spring
五、你对数据库了解多少?
评注:由于你答的数据量和并发量不大,所以中间件这块没啥好问的。所以,题目走向变为数据库底层!另外,此题为引导题,面试官在给你机会引向你最擅长的方面!
回答:了解常见数据库调优方法,索引优化等!sql
六、你说下数据库的索引实现和非主键的二级索引
评注:这个问题是根据上面,你的回答而问出来的!记得引向本身最擅长的数据库基础知识!默认是回答mysql数据库的
回答:
从数据结构角度:
B-Tree索引,数据结构就是一颗B+树。
Hash索引,Hash索引比较的是进行Hash运算以后的Hash值,因此它只能用于等值的过滤,不能用于基于范围的过滤。基本不用!
R-Tree索引,仅支持geometry数据类型,也基本不用!数据库
至于非主键的二级索引,这个实际上问的就是非聚簇索引!非聚簇索引自己就是一颗B+树,其根节点指向聚簇索引的B+树,具体的请看这篇文章《MySQL(Innodb)索引的原理》
七、项目用的是 SpringBoot ,你能说下 Spring Boot 与 Spring 的区别吗?
评注:基础题,会spring boot的,基本都答的上来。就算没准备过,当场思考下均可以回答的出来!也是属于引导题!
回答:
八、SpringBoot 的自动配置是怎么作的?
评注:此题也是根据你的第七问,进一步提问而得出。
回答:
先答为何须要自动配置?
顾名思义,自动配置的意义是利用这种模式代替了配置 XML 繁琐模式。之前使用 Spring MVC ,须要进行配置组件扫描、调度器、视图解析器等,使用 Spring Boot 自动配置后,只须要添加 MVC 组件便可自动配置所须要的 Bean。全部自动配置的实现都在 spring-boot-autoconfigure 依赖中,包括 Spring MVC 、Data 和其它框架的自动配置。
接着答spring-boot-autoconfigure 依赖的工做原理?
spring-boot-autoconfigure 依赖的工做原理很简单,经过 @EnableAutoConfiguration 核心注解初始化,并扫描 ClassPath 目录中自动配置类对应依赖。好比工程中有木有添加 Thymeleaf 的 Starter 组件依赖。若是有,就按按必定规则获取默认配置并自动初始化所须要的 Bean。
其实还能再继续答@EnableAutoConfiguration 注解的工做原理!不过篇幅太长,答到上面那个地步就够了!
九、MyBatis 定义的接口,怎么找到实现的?
评注:mybatis底层原理题,考察有没有看过mybatis的原理。博主恰好曾经本身写过一个mybatis,因此此题恰巧答的上来。
博主心里活动:"如今校招的都这么牛逼了么!"
回答:一共五步
十、Java 内存结构
评注:基础题,这个应该学JAVA的都会吧!送分题!若是博主没理解错应该是在问JVM的内存结构!
回答:JVM内存结构主要有三大块:堆内存、方法区和栈。堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分红三部分,Eden空间、From Survivor空间、To Survivor空间,默认状况下年轻代按照8:1:1的比例来分配;
方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆);栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。
十一、对象是否可 GC?
评注:这个问题就是在问,JVM如何判断对象是否须要被回收!不用答引用计数法,答可达性分析算法就行。
回答:
这个算法的基本思路是经过一些列称为“GC Roots”的对象做为起始点,从这些点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证实对象须要被回收.
如图:
上图中o3,o4对象没有任何GC Roots可达到,全部这两个对象不可用了,须要被GC回收
Java可做为GC Roots的对象包括下面几种:
十二、Minor GC 和 Full GC
评注:基础题,会JVM调优的,基本都会!我只是奇怪,怎么没问Major GC呢?咱们仍是把Major GC也给答了吧!
回答:
堆内存是JVM中最大的一块由年轻代和老年代组成。
那么,从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。
Major GC 是清理老年代。
Full GC 是清理整个堆空间—包括年轻代和老年代。
1三、垃圾回收算法
评注:基础题,博主斗胆猜想,应该是在问垃圾回收算法有哪些。面试官应该没有耐心去听你一个个去背算法概念!
回答:
标记-清除算法、标记整理算法、复制算法、分代收集算法
1四、垃圾回收器 G1
评注:上面的题目更深刻的问法。JVM能够配置不一样的回收器。好比Serial, Parallel和CMS几种垃圾回收器。以Serial Collector(串行回收器)为例,它在在年轻代是一个使用标记-复制算法的回收器。在老年代使用的是标记-清扫-整理算法。
另外,关于G1回收器能够问的点不少,此题做者没有描述清楚究竟问的是G1回收器的那个点,就满回答一下概念吧!
若是是我来问,我就直接给你场景,问你该用哪一种回收器了。直接问回收器,那就比较容易了!
经常使用参数:
*-XX:+UseSerialGC:在新生代和老年代使用串行收集器
-XX:+UseParNewGC:在新生代使用并行收集器
//本身查询吧,太多了!
回答:
G1 GC是Jdk7的新特性之1、Jdk7+版本均可以自主配置G1做为JVM GC选项。 G1 将整个堆划分为一个个大小相等的小块(每一块称为一个region),每一块的内存是连续的,每一个块也会充当 Eden、Survivor、Old三种角色,可是它们不是固定的,这使得内存使用更加地灵活。以下图所示
执行垃圾收集时,收集线程在标记阶段和应用程序线程并发执行,标记结束后,G1 也就知道哪些区块基本上是垃圾,存活对象极少,G1 会先从这些区块下手,由于从这些区块能很快释放获得很大的可用空间,这也是为何 G1 被取名为 Garbage-First 的缘由。
1五、项目里用过 ElasticSearch 和 Hbase,有深刻了解他们的调优技巧吗?
评注:一个应届生搭的ElasticSearch 和 Hbase,通常都只是demo级别的,懂基本的CRUD的使用便可!通常不会去深刻了解调优技巧的!这个问题若是答深刻了解过,是给本身挖坑!由于这个问题,答案太广了!
回答:并无深刻了解过!
1六、Spring RestTemplate 的具体实现
评注:这题问的博主有点懵!若是是我来问,我会先问访问Rest服务的客户端这么多,为何选Spring RestTemplate?而后才来原理。这个忽然就冒出一个具体实现,我是有点懵啦!
回答:
其实RestTemplate和sl4fj这种门面框架很像,本质就是在Http的网络请求中增长一个马甲,自己并无本身的实现。对此有疑问的,能够看个人另外一篇
《架构师必备,带你弄清混乱的JAVA日志体系!》
底层能够支持多种httpclient的http访问,上层为ClientHttpRequestFactory接口为,底层以下所示:
那么RestTemplate则封装了组装、发送 HTTP消息,以及解析响应的的底层细节。
答到这个份上能够了,难道你还要把类之间关系的引用图,画出来?太不现实了!
1七、描述下网页一个 Http 请求,到后端的整个请求过程
评注:基础题,感受属于常识题!必会!
回答:
利用DNS进行域名解析 --> 发起TCP的3次握手 --> 创建TCP链接后发起http请求 --> 服务器响应http请求,浏览器获得html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户
1八、多线程的经常使用方法和接口类及线程池的机制
评注:基础题,基本会点线程知识的,多多少少都会答点!可是这道题,我感受范围有点大啊!多是做者没表述清楚吧!
回答:
经常使用方法:
start,run,sleep,wait,notify,notifyAll,join,isAlive,currentThread,interrupt
经常使用接口类:
Runnable、Callable、Future、FutureTask
线程池的机制:
在面向对象编程中,建立和销毁对象是很费时间的,由于建立一个对象要获取内存资源或者其它更多资源。因此提升服务程序效率的一个手段就是尽量减小建立和销毁对象的次数,因此出现了池化技术!。
简单的线程池包括以下四个组成部分便可:
1九、总结个人 Java 基础仍是不错,可是一些主流的框架源码仍是处在使用的状态,须要继续去看源码
评注:坦白说,我没看出来哪些问题体现出主流的框架仍是处在使用的状态。
20、死锁
评注:牛客网原题!把缘由一块儿答了吧!
回答:
死锁是指两个或两个以上的进程在执行过程当中,因争夺资源而形成的一种互相等待的现象,若无外力做用,它们都将没法推动下去,若是系统资源充足,进程的资源请求都可以获得知足,死锁出现的可能性就很低,不然就会因争夺有限的资源而陷入死锁。
产生死锁的缘由主要是:
2一、本身研究比较新的技术,说下成果!
评注:嗯,凸显本身的潜力,你们自由发挥!
2二、你有什么想问的?我就问了下公司那边的状况,这个自由发挥!
评注:问问工做内容便可,千万别问什么福利啊,加班状况啊!这种问题,不要在技术面的时候问!
本文就对一面的题目作出了回答,二面的题目,哪天有时间再写吧!