最近,春招已经基本接近尾声了,我找了几位拿到名企Offer的小伙伴,请他们总结了面试经验,近期会分批的推送给你们。但愿给那些正在准备秋招的同窗提供些帮助。这是一篇7000字的长文,总结了本身参加京东校招并拿到offer的面试题及答案,还有学习方法。对于一个校招生来讲,能把JVM、网络知识、JDK源码等了解的这么全面,他不进京东,谁进京东。作到他这样,你,也能够。java
面试时间较长,回答速度也较快,全部问题都进行了完整的回答。形式为电话面试,都是基础,难度通常,没关系张,回答知识点便可。linux
内容主要包括jvm相关,网络知识(TCP/IP,DNS),JDK源码(HashMap, ArrayList, HashTable等)nginx
这部分主要考的是知识点的串联能力,面试官提出一个问题时,要把该问题相关的知识点都罗列出来(在说以前能够询问面试官是否须要详细讲述该知识点)。面试
参考书籍:深刻理解Java虚拟机-周志明 神书!神书!神书!建议多刷几遍,书中的全部知识点能够经过JAVA运行时区域和JAVA的内存模型与线程两个大模块罗列彻底。redis
常考内容有:GC,JAVA线程实现方式,volatile底层原理,线程安全,锁与CAS等算法
1. 讲下JAVA的运行时区域spring
回答:运行时数据区总体分为两类 线程私有和线程共享。sql
线程私有的包括:数据库
程序计数器数组
若正在执行的是java方法,则计数器记录的是正在执行的字节码指令的地址
若正在执行的是native方法,则计数器为空
该区域是惟一一个不会致使outofmemoryError的区域
虚拟机栈
描述的是Java方法执行的内存模型:每一个方法都会建立一个栈帧用于存储局部变量表,操做数栈,动态连接,方法出口等信息
局部变量表存放了编译期可知的基本数据类型,对象引用,和returnAddress类型(指向一条字节码指令地址),局部变量表的内存空间在编译器肯定,在运行期不变
可致使两种异常:线程请求的栈深度大于虚拟机容许的深度-StackOverflowError;虚拟机没法申请到足够的内存-OutOfMemoryError
本地方法栈
和虚拟机栈相似,但它是为Native方法服务的
线程共享的包括:
堆
java堆是被全部线程共享的内存区域,在虚拟机启动时建立,用来分配对象实例和数组
堆是垃圾回收器主要管理的区域,堆可分为新生代和老年代
从内存分配角度看,堆可划分出多个线程私有的分配缓冲区(TLAB)
大小可经过 -Xmx 和 -Xms 控制
方法区
用来存放虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等信息
GC会回收该区域的常量池和进行类型的卸载 *运行时常量池
Class文件的常量池用于存放编译期生成的各类字面量和符号引用,这部份内容将在类加载后存放在运行时常量池中
还把翻译出来的直接引用也放在运行时常量池中,运行时产生的常量也放在里面
2. 简单说下垃圾回收机制
大体思路: 要进行垃圾回收,首先要判断一个对象是否活着,这就引出了两种方法…
引用计数法和可达性分析法
gc roots 类型
引用类型
两次标记过程
垃圾回收算法
内存分配策略
触发垃圾回收
垃圾回收器
也会回收方法区
回答:要进行垃圾回收,首先要判断对象是否存活,引出了两个方法:
引用计数法
思想:给对象设置引用计数器,没引用该对象一次,计数器就+1,引用失效时,计数器就-1,当任意时候引用计数器的值都为0时,则该对象可被回收
Java不适用缘由:没法解决对象互相循环引用的问题
可达性分析法
虚拟机栈(栈帧中的局部变量表)中引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI(Native方法)引用的对象
以GC Roots为起点,从这些起点开始向下搜索,通过的路径称为引用链。若一个对象到GC Roots之间没有任何引用链,则该对象是不可达的。
那么可做为GC Roots的对象有
在可达性分析过程当中,对象引用类型会对对象的生命周期产生影响,JAVA中有这几种类型的引用:
强引用:只要该引用还有效,GC就不会回收
软引用:内存空间足够时不进行回收,在内存溢出发生前进行回收、用SoftReference类实现
弱引用:弱引用关联的对象只能存活到下一次Gc收集、用WeakReference类实现
虚引用:没法经过虚引用得到对象实例,也不会对对象的生存时间产生影响、惟一目的:当该对象被Gc收集时,收到一个系统通知。用PhantomReference类实现
一个对象真正不可用,要经历两次标记过程:
首先进行可达性分析,筛选出与GC Roots没用引用链的对象,进行第一次标记
第一次标记后,再进行一次筛选,筛选条件是是否有必要执行finalize()方法。若对象有没有重写finalize()方法,或者finalize()是否已被jvm调用过,则不必执行,GC会回收该对象
如有必要执行,则该对象会被放入F-Queue中,由jvm开启一个低优先级的线程去执行它(但不必定等待finalize执行完毕)。
Finalize()是对象最后一次自救的机会,若对象在finalize()中从新加入到引用链中,则它会被移出要回收的对象的集合。其余对象则会被第二次标记,进行回收
JAVA中的垃圾回收算法有:
标记-清除(Mark-Sweep)
两个阶段:标记, 清除
缺点:两个阶段的效率都不高;容易产生大量的内存碎片
复制(Copying)
把内存分红大小相同的两块,当一块的内存用完了,就把可用对象复制到另外一块上,将使用过的一块一次性清理掉
缺点:浪费了一半内存
标记-整理(Mark-Compact)
标记后,让全部存活的对象移到一端,而后直接清理掉端边界之外的内存
分代收集
把堆分为新生代和老年代
新生代使用复制算法
将新生代内存分为一块大的Eden区和两块小的Survivor;每次使用Eden和一个Survivor,回收时将Eden和Survivor存活的对象复制到另外一个Survivor(HotSpot的比例Eden:Survivor = 8:1)
老年代使用标记-清理或者标记-整理
触发GC又涉及到了内存分配规则: (对象主要分配在Eden,若启动了本地线程分配缓冲,将优先在TLAB上分配)
对象优先在Eden分配
当Eden区没有足够的空间时就会发起一次Minor GC
大对象直接进入老年代
典型的大对象是很长的字符串和数组
长期存活的对象进入老年代
每一个对象有年龄计数器,每通过一次GC,计数器值加一,当到达必定程度时(默认15),就会进入老年代
年龄的阈值可经过参数 -XX:MaxTenuringThreshold设置
对象年龄的断定
Survivor空间中相同年龄全部对象大小的总和大于Survivor空间的一半,年龄大于等于该年龄的对象就可直接进入老年代,无须等到MaxTenuringThreshold要求的年龄
空间分配担保
发生Minor GC前,jvm会检查老年代最大可用的连续空间是否大于新生代全部对象总空间,若大于,则Minor GC是安全的
若不大于,jvm会查看HandlePromotionFailure是否容许担保失败,若不容许,则改成一次Full GC
若容许担保失败,则检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,若大于,则尝试进行Minor GC;若小于,则要改成Full GC
垃圾收集器:
Serial(串行收集器)
特性:单线程,stop the world,采用复制算法
应用场景:jvm在Client模式下默认的新生代收集器
优势:简单高效
ParNew
特色:是Serial的多线程版本,采用复制算法
应用场景:在Server模式下经常使用的新生代收集器,可与CMS配合工做
Parallel Scavenge
特色:并行的多线程收集器,采用复制算法,吞吐量优先,有自适应调节策略
应用场景:须要吞吐量大的时候
SerialOld
特色:Serial的老年代版本,单线程,使用标记-整理算法
Parallel Old
Parallel Scavenge的老年代版本,多线程,标记-整理算法
CMS
对CPU资源敏感
没法处理浮动垃圾(并发清除 时,用户线程仍在运行,此时产生的垃圾为浮动垃圾)
产生大量的空间碎片
初始标记:stop the world 标记GC Roots能直接关联到的对象
并发标记:进行GC Roots Tracing
从新标记:stop the world;修正并发标记期间因用户程序继续运做而致使标记产生变更的 那一部分对象的标记记录
并发清除:清除对象
特色:以最短回收停顿时间为目标,使用标记-清除算法
过程:
优势:并发收集,低停顿
缺点:
G1
初始标记:stop the world 标记GC Roots能直接关联到的对象
并发标记:可达性分析
最终标记:修正在并发标记期间因用户程序继续运做而致使标记产生变更的那一部分标记记录
筛选回收:筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所指望的GC停顿时间来制定回收计划
并行与并发
分代收集
空间整合:从总体看是基于“标记-整理”的,从局部(两个region之间)看是基于“复制”的。
可预测的停顿:使用者可明确指定在一个长度为M毫秒的时间片断内,消耗在垃圾收集上的时间不得超过N毫秒。
特色:面向服务端应用,将整个堆划分为大小相同的region。
执行过程:
GC自适应调节策略 Parallel Scavenge收集器有一个参数-XX:+UseAdaptiveSizePolicy。当这个参数打开以后,就不须要手工指定新生代的大小、Eden与Survivor区的比例、晋升老年代对象年龄等细节参数了,虚拟机会根据当前系统的运行状况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。
(垃圾回收器部分重点讲CMS和G1)
最后提一下也会回收方法区:
永久代中主要回收两部份内容:废弃常量和无用的类
废弃常量回收和对象的回收相似
无用的类需知足3个条件
该类的全部实例对象已被回收
加载该类的ClassLoader已被回收
该类的Class对象没有在任何地方被引用,没法在任何地方经过反射访问该类的方法
上面的知识点在你多刷几遍书,脑中造成相应的知识网后能很全面的说出来。
网络知识在面试中很是重要,尤为是TCP,DNS,HTTP等知识点。
该部分个人参考书籍是:图解HTTP,图解TCP/IP(对于开发来讲,这两本书在网络方面的讲解应该够用了),以及相关博客。
回答该类问题时,依然要从面试官提到的问题进行扩散,把相关的问题本身抛出来进行讲述(在抛出讲述时能够询问面试官是否须要进行详细的讲解)
1. 讲一下TCP三次握手
对于该问题,能够直接关联TCP四次分手进行回答。如果当场面试,能够在纸上画出客户端和服务端的TCP状态序列
而后本身能够抛出相关的问题进行回答,如:
为何不采用两次握手,SYN半链接攻击,TIMEWAIT数量太多怎么办,为何链接的时候是3次握手,关闭的时候是4次分手,为何TIMEWAIT状态须要通过2MSL(最大报文段生存时间)才能回到CLOSE状态等等问题(这些问题在网上都有讲解,这里就不赘述了)。
2. TCP和UDP的区别(很常见的问题):
TCP面向链接(如打电话要先拨号创建链接) UDP是无链接的,即发送数据以前不须要创建链接
TCP提供可靠的服务。也就是说,经过TCP链接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
TCP面向字节流,其实是TCP把数据当作一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,所以网络出现拥塞不会使源主机的发送速率下降(对实时应用颇有用,如IP电话,实时视频会议等)
每一条TCP链接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通讯
TCP首部开销20字节;UDP的首部开销小,只有8个字节
TCP的逻辑通讯信道是全双工的可靠信道,UDP则是不可靠信道
3. 讲下ARP原理
根据目标Ip地址借助ARP请求和ARP响应来肯定目标的MAC地址
原理:经过广播发送ARP请求,Ip地址一致的主机接收该请求,而后将本身的MAC地址加入的ARP响应包返回给源主机。要进行MAC地址缓存来避免占用网络流量
每一个主机都会在本身的ARP缓冲区创建一个ARP列表,表示Ip地址和MAC地址的对应关系
当源主机要发送数据时,首先检查ARP列表中是否有对应Ip地址的目标主机的MAC地址,如有,则直接发送,若无,则向本网段的全部主机发送ARP数据包,该数据包包括的内容有:源Ip地址,源MAC地址,目标主机Ip地址
当本网络的全部主机收到该ARP数据包时,首先检查书包中的Ip地址是不是本身的Ip地址,若不是则丢弃,如果,则首先从数据包中取出源主机的IP和MAC地址写入本身的ARP列表中,若已存在,则覆盖;而后将本身的MAC地址写入ARP响应包中,告诉源主机本身的MAC地址
源主机收到ARP响应包后,将目标主机的IP和MAC地址写入ARP列表中。若源主机一直没有收到ARP响应,则ARP查询失败
(广播发送ARP请求,单播发送ARP响应) 此时,本身能够加上ARP攻击及免费ARP相关知识点(可自行搜索)
这部分主要在于本身平时的积累,能够跟着相关的博客看源码。常考的内容有String,集合框架,foreach(Iterator及fail-fast机制)等内容。
1. HashMap了解吗,说一下
这里就不详细说了,大体思路是jdk7和jdk8的实现原理及区别(重点有实现的数据结构,存储单元从Entry到Node的转变,加载因子,何时扩容,jdk1.8扩容的具体实现方式等等),HashMap和HashTable的区别,HahsMap和HashSet的关系。要结合源码说。
ArrayList了解吗,说一下
重点是底层实现方式,扩容机制,以及LinkedList的底层实现方式;它们之间的区别。要结合源码说
面试时间不长,个别问题回答的有些底虚。主要考察的是知识面的广度和对技术的热爱程度,以及对作过项目的熟悉程度。仍是那句话,坦诚地回答问题,不会就是不会,若是伪装会可是被接下来地问题问倒的话,那就没戏了。
实习时项目的相关问题
每一个人的项目都不一样,只列举几个问题
项目是怎样预防sql注入的
回答:用的是mybatis,sql语句中用#{},#{}表示一个占位符号,经过#{}能够实现preparedStatement向占位符中设置值,jdbc有个预编译的过程能够有效预防sql注入,尽可能不用${},它是个拼接符,用来拼接sql字符串。
项目中你作到的redis缓存相关的切面配置(简历中有写)
切面分析:@Aspect
切面: 查询前先查询redis,若查询不到,则查数据库,获得数据后存到redis中
目标方法:查询数据库
前置:查询以前先查redis
后置:从数据库中查到的内容放到redis中
切面中的通知定位环绕通知:@Around
而后又问了aop的实现原理(jdk动态代理和cglib字节码加强,在回答时要说出底层源码)
喜欢什么技术
答:分布式,实习时虽然本身作的是企业后台,并无涉及到不少分布式的内容,可是会常常从同事那里了解一些分布式的技术感受颇有趣
都了解到了哪些分布式的技术
答:进行反向代理和负载均衡的nginx,及实现高可用的keepalived+nginx;内存数据库redis及它的基本数据类型和持久化方式;用于作注册中心的zookeeper和服务治理的dubbo;防止用户重复登陆的单点登陆;分布式的文件存储系统fastdfs;页面静态化处理的freemarker;以及用于搜索的solr(这部分因为有些技术本身只是会用,不了解底层,因此说的吞吞吐吐,很没底气,其实不必,大大方方说出来后再说明本身了解的程度便可)
感受本身哪方面有欠缺
答:spring源码不太了解,另外linux方面有些薄弱,正在补充相关知识。(能够加上本身目前正在看哪些书)
jdk9有哪些认识
答:不太清楚,还没了解(心里状态:卧槽,jdk9何时出来的) (这个问题能够很好的了解到求职者对技术的热爱程度,平时能够多关注技术的发展方向,版本迭代。这方面能够经过关注一些优质的公众号:如Java技术zhai)
为何想来互联网公司
答:多是第一份实习工做的影响吧, 面试官:还有呢? 我:我也说不清楚,就是想去互联网公司(说完以后就想宰了本身)
hr面重要的也是真诚,还有就是表达好本身想去该公司及对该公司的了解
目前有几个offer
答:1个,可是已经拒了
为何拒了
答:由于它不是互联网公司
你为何想在互联网公司发展
答:工资高是一方面,另外在互联网公司中通常能够更快接触到新的技术
为何想来京东
答:由于京东是我关注好久的公司,从京东第一次作秋招视频直播就开始关注了。首先京东是一家互联网公司,其次京东近些年的发展有目共睹,并且京东正在向技术公司转型,相信本身能够学到不少东西。
你有什么缺点
答:压力大时喜欢经过吃东西来排解压力,因此又要减肥什么的很麻烦
还有呢
答:喜欢熬夜
还有呢
答:emmmm,哎呀,想不起来了 (其实,关于优势和缺点的问题应该好好总结一下,否则问的当时容易懵逼) 还有几个问题不太记得了,大概就是实习时本身意见和同事不同时是怎么解决的。对于这种问题,最好举个实际的例子。
想要了解更多面试经验及面试题的,能够关注我一下,另外顺便给你们推荐一个交流学习群:650385180,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多,如下的课程体系图也是在群里获取。
其实网上的大多数面经已经说的很清楚,必定要造成本身的知识树,若是仅仅想经过看面经来经过面试,会很难。本身日常必定要积累知识,把知识点分类进行记录,在面试过程当中主动说出面试官所提问题的关联问题的解决方案可以加分,体现本身的知识串联能力。关于要积累哪些知识,能够参考上面的建议。