凡事预则立不预则废,无论你是近期打算跳槽,还是过完年准备跳槽,我想此刻开始准备面试,无疑是最明智的选择。信息过载的今天,想要找一份靠谱的高频面试题和权威的答案非常不容易,本文为你汇总了大量的干货面试资料,下面一起来看吧。

Java程序是怎么执行的?

我们日常的工作中都使用开发工具(IntelliJ IDEA 或 Eclipse 等)可以很方便的调试程序,或者是通过打包工具把项目打包成 jar 包或者 war 包,放入 Tomcat 等 Web 容器中就可以正常运行了,但你有没有想过 Java 程序内部是如何执行的?其实不论是在开发工具中运行还是在 Tomcat 中运行,Java 程序的执行流程基本都是相同的,它的执行流程如下:
  • 先把 Java 代码编译成字节码,也就是把 .java 类型的文件编译成 .class 类型的文件。这个过程的大致执行流程:Java 源代码 -> 词法分析器 -> 语法分析器 -> 语义分析器 -> 字符码生成器 -> 最终生成字节码,其中任何一个节点执行失败就会造成编译失败;

  • 把 class 文件放置到 Java 虚拟机,这个虚拟机通常指的是 Oracle 官方自带的 Hotspot JVM;

  • Java 虚拟机使用类加载器(Class Loader)装载 class 文件;

  • 类加载完成之后,会进行字节码效验,字节码效验通过之后 JVM 解释器会把字节码翻译成机器码交由操作系统执行。但不是所有代码都是解释执行的,JVM 对此做了优化,比如,以 Hotspot 虚拟机来说,它本身提供了 JIT(Just In Time)也就是我们通常所说的动态编译器,它能够在运行时将热点代码编译为机器码,这个时候字节码就变成了编译执行。

Java 程序执行流程图如下:

Java 虚拟机是如何判定热点代码的?

Java 虚拟机判定热点代码的方式有两种:
  • 基于采样的热点判定:主要是虚拟机会周期性的检查各个线程的栈顶,若某个或某些方法经常出现在栈顶,那这个方法就是“热点方法”。这种判定方式的优点是实现简单;缺点是很难精确一个方法的热度,容易受到线程阻塞或外界因素的影响。

  • 基于计数器的热点判定:主要就是虚拟机给每一个方法甚至代码块建立了一个计数器,统计方法的执行次数,超过一定的阀值则标记为此方法为热点方法。

Hotspot 虚拟机使用的基于计数器的热点探测方法。它使用了两类计数器:方法调用计数器和回边计数器,当到达一定的阀值是就会触发 JIT 编译。

方法调用计数器:在 client 模式下的阀值是 1500 次,Server 是 10000 次,可以通过虚拟机参数:-XX:CompileThreshold=N 对其进行设置。但是JVM还存在热度衰减,时间段内调用方法的次数较少,计数器就减小。回边计数器:主要统计的是方法中循环体代码执行的次数。

以下 Integer 代码输出的结果是?

Integer age = 10;
Integer age2 = 10;
Integer age3 = 133;
Integer age4 = 133;
System.out.println((age == age2) + ","+ (age3 == age4));
答:true,false题目解析:此道题目考察的是,面试者对于基础类型高频区缓存的掌握,因为 Integer 的高频区的取值是 -128-127,所以在这个区间的值会复用已有的缓存,对比的结果自然是 true,false 。

以下 StringBuffer 传值修改后的执行结果是什么?

publicstaticvoid main(String[] args) {
StringBuffer sf = newStringBuffer("hi"); changeStr(sf);
System.out.println(sf);
}
publicstaticvoid changeStr(StringBuffer sf){    sf.append("laowang");
}
答:hilaowang题目解析:String 为不可变类型,在方法内对 String 修改的时候,相当修改传递过来的是一个 String 副本,所以 String 本身的值是不会被修改的,而 StringBuffer 为可变类型,传递过来的参数相当于对象本身,所以打印的结果就为 hilaowang

以下数组比较的结果分别是什么?

String[] strArr = {"dog", "cat", "pig", "bird"};
String[] strArr2 = {"dog", "cat", "pig", "bird"};
System.out.println(Arrays.equals(strArr, strArr2));
System.out.println(strArr.equals(strArr2));
System.out.println(strArr == strArr2);

答:truefalsefalse。题目解析:strArr == strArr2 为引用比较,因此结果一定是 false,而数组本身的比较也就是 strArr.equals(strArr2) 为 false 的原因是因为数组没有重写 equals 方法,因此也是引用比较。数组 equals 源码实现如下:

publicboolean equals(Object obj) {
return(this== obj);
}
而 Arrays.equals 的结果之所以是 true 是因为 Arrays.equals 重写了 equals 方法。源代码实现如下:
publicstaticboolean equals(Object[] a, Object[] a2) {
if(a==a2)
returntrue;
if(a==null|| a2==null)
returnfalse;
int length = a.length;
if(a2.length != length)
returnfalse;
for(int i=0; i<length; i++) {
Object o1 = a[i];
Object o2 = a2[i];
if(!(o1==null? o2==null: o1.equals(o2)))
returnfalse;
}
returntrue;
}

常用的序列化方式都有哪些?

答:常用的序列化方式有以下三种:1) Java 原生序列化方式请参考以下代码:

// 序列化和反序列化
classSerializableTest{
publicstaticvoid main(String[] args) throwsIOException, ClassNotFoundException{
// 对象赋值
User user = newUser(); user.setName("老王");   user.setAge(30);
System.out.println(user);
// 创建输出流(序列化内容到磁盘)
ObjectOutputStream oos = newObjectOutputStream(newFileOutputStream("test.out"));
// 序列化对象    oos.writeObject(user);  oos.flush();    oos.close();
// 创建输入流(从磁盘反序列化)
ObjectInputStream ois = newObjectInputStream(newFileInputStream("test.out"));
// 反序列化
User user2 = (User) ois.readObject();  ois.close();
System.out.println(user2);
}
}
classUserimplementsSerializable{
privatestaticfinallong serialVersionUID = 5132320539584511249L;
privateString name;
privateint age;
@Override
publicString toString() {
return"{name:"+ name + ",age:"+ age + "}";
}
publicString getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}

2) JSON 格式,可使用 fastjson 或 GSONJSON 是一种轻量级的数据格式,JSON 序列化的优点是可读性比较高,方便调试。我们本篇以 fastjson 的序列化为例,请参考以下代码:

// 序列化和反序列化
classSerializableTest{
publicstaticvoid main(String[] args) throwsIOException, ClassNotFoundException{
// 对象赋值
User user = newUser(); user.setName("老王");   user.setAge(30);
System.out.println(user);
String jsonSerialize = JSON.toJSONString(user);
User user3 = (User) JSON.parseObject(jsonSerialize, User.class);
System.out.println(user3);
}
}
classUserimplementsSerializable{
privatestaticfinallong serialVersionUID = 5132320539584511249L;
privateString name;
privateint age;
@Override
publicString toString() {
return"{name:"+ name + ",age:"+ age + "}";
}
publicString getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}

3) Hessian 方式序列化:Hessian 序列化的优点是可以跨编程语言,比 Java 原生的序列化和反序列化效率高。请参考以下示例代码:

// 序列化和反序列化
classSerializableTest{
publicstaticvoid main(String[] args) throwsIOException, ClassNotFoundException{
// 序列化
ByteArrayOutputStream bo = newByteArrayOutputStream();
HessianOutput hessianOutput = newHessianOutput(bo);    hessianOutput.writeObject(user);
byte[] hessianBytes = bo.toByteArray();
// 反序列化
ByteArrayInputStream bi = newByteArrayInputStream(hessianBytes);
HessianInput hessianInput = newHessianInput(bi);
User user4 = (User) hessianInput.readObject();
System.out.println(user4);
}
}
classUserimplementsSerializable{
privatestaticfinallong serialVersionUID = 5132320539584511249L;
privateString name;
privateint age;
@Override
publicString toString() {
return"{name:"+ name + ",age:"+ age + "}";
}
publicString getName() {
return name;
}
publicvoid setName(String name) {
this.name = name;
}
publicint getAge() {
return age;
}
publicvoid setAge(int age) {
this.age = age;
}
}

有哪些方法可以解决哈希冲突?

答:哈希冲突的常用解决方案有以下 4 种:
  • 开放定址法:当关键字的哈希地址 p=H(key)出现冲突时,以 p 为基础,产生另一个哈希地址 p1,如果 p1 仍然冲突,再以 p 为基础,产生另一个哈希地址 p2,循环此过程直到找出一个不冲突的哈希地址,将相应元素存入其中;

  • 再哈希法:这种方法是同时构造多个不同的哈希函数,当哈希地址 Hi=RH1(key)发生冲突时,再计算 Hi=RH2(key),循环此过程直到找到一个不冲突的哈希地址,这种方法唯一的缺点就是增加了计算时间;

  • 链地址法:这种方法的基本思想是将所有哈希地址为 i 的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第 i 个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况;

  • 建立公共溢出区:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。

JVM 内存布局是怎样的?

答:不同虚拟机实现可能略微有所不同,但都会遵从 Java 虚拟机规范,Java 8 虚拟机规范规定,Java 虚拟机所管理的内存将会包括以下几个区域:
  • 程序计数器(Program Counter Register)

  • Java 虚拟机栈(Java Virtual Machine Stacks)

  • 本地方法栈(Native Method Stack)

  • Java 堆(Java Heap)

  • 方法区(Methed Area)
以上面试这几个知识点均来自《Java面试全解析:核心知识点与典型面试题》这门专栏。
扫码查看专栏详情
这门专栏帮助了很多人完成面试准备,来看看读者评价:

通过这门课拿到 Offer 的同学:

这门课所包含的知识点:

专栏作者:王磊

上市公司技术研发经理,资深面试官,阿里云社区认证专家。前奇虎 360 员工,有着 10 余年的编程工作经验,目前主要负责新员工技术面试和平台架构制订的相关事宜。在接下来两个多月的时间里,让我们一起学习 Java 技术核心和面试要点,一起构建一个完整的 Java 认知体系。

你将获得

1. 收获 Java 技术栈的核心知识点

这个课程几乎涵盖了 Java 技术栈的大部分内容,不止对于面试,在日常的工作中也可以发挥很大的作用。

2. 500 多道实用、权威、高频 Java 面试题详解

这 500 多道面试题,都是目前主流企业使用最高频的面试题库,也都是 Java 版本升级之后,重新整理归纳的最新答案,会让面试者少走很多不必要的弯路。同时每道题都做到了详尽的描述,以确保每个阶段的读者都能看得懂,面试题中的专业短语也都确保提供了必要的介绍,部分难懂的题目也提供了题目解析和示例代码。

3. 理解技术背后的实现原理

死记硬背的内容通常会随着时间的推移很快就忘记,所以在学习一门技术的时候,一定要了解其背后的实现原理,从而构建逻辑上的因果关系,这样才能够记的更久。这门课程会深入浅出地对技术背后的原理进行深入的分析,让读者“知其然,并知其所以然”。

点击阅读原文,了解 Java 面试题。

500+ 精选 Java 面试题大放送相关推荐

  1. java用正则表达式 编写简单词法分析器_500+ 精选 Java 面试题大放送

    凡事预则立不预则废,无论你是近期打算跳槽,还是过完年准备跳槽,我想此刻开始准备面试,无疑是最明智的选择.信息过载的今天,想要找一份靠谱的高频面试题和权威的答案非常不容易,本文为你汇总了大量的干货面试资 ...

  2. JAVA学习视频,2020最新全套视频大放送!

    JAVA学习视频,2020最新全套视频大放送!JAVA学习视频,2020最新全套视频大放送!JAVA学习视频,2020最新全套视频大放送!重要的事情说三遍,小编精心准备的内容.希望对初学者有所帮助! ...

  3. 「分布式系统之美」知乎圆桌精选大放送第二期|不要放过任何你感兴趣的话题

    相信大家看完上周「分布式系统之美」知乎圆桌精选大放送后还意犹未尽,新的一轮热门讨论已被小编盘点下来,快来跟随小编一起看看有什么新的答案吧. 标题精选问题 & 回答 MySQL 单表日均 15 ...

  4. r matlab spss,特别放送 | 零基础编程入门:Python、Matlab、R、SPSS资料大放送

    原标题:特别放送 | 零基础编程入门:Python.Matlab.R.SPSS资料大放送 我们一直相信: 一切不能实实在在帮助到同学的资料 都是耍流氓 小助手的目标是: 做一次又一次真正有价值.愉悦感 ...

  5. 【云栖大会精华汇】历届云栖大会精彩资料大放送,一篇看尽云栖大会前世今生...

    [热点头条] 历届云栖大会精彩资料大放送,一篇看尽云栖大会前世今生        如果从2009-2010年算起,2017杭州云栖大会已经是第八届.为帮助更多朋友认识云栖大会,云栖社区特别整理了历届云 ...

  6. 喜迎国庆-好礼大放送

      从2004年开始,沃通(WoSign)专注提供一站式各种全球信任的数字证书产品和技术服务,为了感谢广大用户十年来对沃通(WoSign)的信赖和支持,借此举国欢庆之际,沃通(WoSign)开展&qu ...

  7. 上千个国外免费权威优质编程学习课程大放送 —— 提升篇

    随着互联网的发展,像 MIT 和斯坦福等世界名校,都开始在网上公开一些优质的在线免费课程供大家学习.到现在,已经有来自全球共 1000 所左右的学校提供了非常多的优质课程,最有名的平台就是 MOOC. ...

  8. 阿里系唯一对外开放数据分享平台天池数据集2020收官精品合集大放送

    **简介:**阿里系唯一对外开放数据分享平台天池数据集2020收官精品合集大放送 作为国内"AI众智"首选平台,阿里云天池除了面向国内开发者组织大数据竞赛.免费开放AI学习内容.提 ...

  9. ERP专业词汇大放送

    ERP专业词汇大放送 中英文对照的ERP专业词汇介绍:B2C.B2B.ASP.APS.BOM.C/S.CAD.CAM.CPC.EDI.GUI.ISO.MIS. PM.SCM.SQL.TQM.line ...

最新文章

  1. Pandas 基础 (3)—— 重新索引
  2. 要让GAN生成想要的样本,可控生成对抗网络可能会成为你的好帮手
  3. 新加坡计划通过区块链促进东盟金融包容性
  4. springcloud13---zuul
  5. 烙铁使用规范】—— 烙铁头使用及保养
  6. 【HTML5CSS3进阶学习02】Header的实现·CSS中的布局
  7. springboot-RequestMappingHandlerMapping
  8. php数组 函数,PHP array_uintersect_uassoc() 函数
  9. Win32 控件篇(6)
  10. 深入了解Java的SPI机制
  11. Python学习笔记:函数(Function)
  12. Flash3D的X,Y,Z坐标系调试小工具
  13. linux上svn的使用教程,Linux上SVN的搭建使用
  14. mysql binlog限流问题总结
  15. java高级工程师------struts的知识重点
  16. HTML图片鼠标滑动加边框,鼠标移动到图片上时,用css怎么实现图片加边框效果?...
  17. 房屋租赁合同中“天价违约金”的约定是否有效?
  18. matlab的setup阶跃曲线图,matlab 绘制系统的单位阶跃响应曲线 并编写程序求峰值时间 超调量 | 学步园...
  19. 北京邮电大学计算机考研英语,我的考研心得——北京邮电大学计算机专业
  20. H6062FNL 普思Pulse 网络变压器

热门文章

  1. 今天讲座的感悟--java
  2. asp.net Ajax的应用
  3. SQL trace, 10046, trcsess and tkprof in Oracle 10g(转)
  4. [论文阅读] Deep Automatic Natural Image Matting
  5. [论文阅读] Exploring Dense Context for Salient Object Detection
  6. 矩池云上安装yolov4 darknet
  7. 矩池云中Tensorflow指定GPU及GPU显存设置
  8. dp------最长公共子序列问题
  9. php ajax loading图片居中显示,PHP语言入门之PHP+ajax实现登录按钮加载loading效果
  10. 双系统ubuntu 删除后重装