文档章节

最近5年183个Java面试问题列表及答案[最全]

圣洁之子
 圣洁之子
发布于 03/14 11:42
字数 3087
阅读 101
收藏 13

Java面试随着时间的流逝而改变。在过去,当你知道String和StringBuilder的区别(String类和StringBuilder类的主要区别在于String是不可变的对象。因此灭此对String对象进行改变的时候其实都等同于生成了一个新的String对象,然后将引用指向新的String对象,所以经常改变内容的字符串最好不要用String,因为每次生成String对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,影响性能,可以考虑使用可变字符序列StringBuilder),就能让你直接进入第二轮面试,但是现在问题变得越来越高级,面试官问的问题也更深入。在我初入职的时候,类似于Vector与Array的区别、HashMap与Hashtable的区别是最流行的问题,只需要记住它们,就能在面试中获得更好的机会,但这种情形已经不复存在。如今,你将会被问到许多Java程序员都没有看过的领域,如NIO、设计模式、成熟的单元测试,或那些很难掌握的知识,如并发、算法、数据结构以及字符集编码解码。

由于我喜欢研究面试题,因此我已经收集了许多的面试问题,包括许多不同的主题。我已经为这众多的问题准备一段时间了,现在我将它们分享给你们。这里不但包含经典的面试问题,如线程、集合、equals和hashcode、socket,还包含了NIO、数组、字符串、Java 8等主题。

该列表包含了入门级Java程序员和多年经验的高级开发者的问题。无论你是1、2、3、4、5、6、7、8、9还是10年经验的开发者,你都能在其中找到一些有趣的问题。这里包含了一些超级容易回答的问题,也包含经验丰富的Java程序员也会棘手的问题。

当然你们也是非常幸运的,当今有许多好书来帮助你准备Java面试,其中有一本我觉得特别有用和有趣的是 Markham 的《Java程序面试揭秘》(Java Programming Interview Exposed)。这本书会告诉你一些Java和JEE面试中最重要的主题,即使你不是准备Java面试,也值得一读。

该问题列表特别长,我们有各个方面的问题。所以,答案必须短小、简洁、干脆,不拖泥带水。因此,除了这一个段落,你只会听到问题与答案,再无其他内容,没有反馈,也没有评价。为此,我已经写好了一些博文,在这些文章中你可以找到我对某些问题的观点,如我为什么喜欢这个问题,这个问题的挑战是什么?期望从面试者获得什么样的答案?

这个列表有一点不同。我鼓励你采用类似的方式去分享问题和答案,这样容易温习。我希望这个列表对面试官和候选人都有很好的用处。面试官可以对这些问题做一些改变以获取新奇的元素,这对一次好的面试来说非常重要。而候选者,可以扩展和测试Java程序语言和平台关键领域的知识。2015年,我会更多得关注并发、JVM内助,32位JVM和64位JVM的区别、单元测试以及简洁的代码。我确信,如果你读过这个庞大的Java面试问题列表,无论电话面试还是面对面的面试,你都能有很好的表现。

Java面试的重要问题

除了你看到的惊人的问题数量,我也尽量保证质量。我不止一次分享各个重要主题中的问题,也确保包含所谓的高级话题。这些话题很多程序员不喜欢准备或直接放弃,因为他们的工作不会涉及到这些。Java NIO和JVM底层就是最好的例子。你也可以将设计模式划分到这一类中,但是越来越多有经验的程序员了解GoF设计模式并应用这些模式。我也尽量在这个列表中包含2015年最新的面试问题。这些问题可能是来年关注的核心。为了给你一个大致的了解,下面列出这份Java面试问题列表包含的主题:

  • 多线程、并发和线程基础
  • 数据类型转换的基本原则
  • 垃圾回收(GC)
  • Java集合框架
  • 数组
  • 字符串
  • GoF设计模式
  • SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)设计原则
  • 接口与抽象类
  • Java基础,如equals和hashcode
  • 泛型与枚举
  • Java IO 与 NIO
  • 常用网络协议
  • Java中的数据结构和算法
  • 正则表达式
  • JVM底层
  • Java最佳实践
  • JDBC
  • Date、Time与Calendar
  • Java处理XML
  • JUnit
  • 编程

120大Java面试题及答案

现在是时候给你展示我近5年从各种面试中收集来的120个问题了。我确定你在自己的面试中见过很多这些问题,很多问题你也能正确回答。

多线程、并发及线程的基础问题

1)Java中能创建 volatile 数组吗?

能,Java中可以创建volatile类型数组,不过只是一个指向数组的引用,而不是整个数组。我的意思是,如果改变引用指向的数组,将会受到volatile的保护,但是如果多个线程同时改变数组的元素,volatile标识符就不能起到之前的保护作用了。

2)volatile 能使得一个非原子操作变成原子操作吗?

一个典型的例子是在类中有一个long类型的成员变量,如果你知道该成员变量会被多个线程访问,如计数器、价格等,你最好将其设置为volatile。为什么?因为Java中读取long类型变量不是原子的,需要分成两步,如果一个线程正在修改该long变量的值,另一个线程可能看到该值得一半(前32位)。但是对一个 volatile 型的 long 或 double 变量的读写是原子操作。

3)对 volatile 修饰符有过什么实践?

一种实践是用 volatile 修饰 long 和 double 变量,使其能按原子类型来读写。double 和 long 都是64位宽,因此对这两种类型的读是分为两部分的,第一次读取前32位,然后再读取剩下的32位,这个过程不是原子的,但 Java 中 volatile 修饰的 long 或 double 变量的读写是原子的。volatile 修饰符的另一个作用是提供内存屏障(memory barrier),例如在分布式框架中的应用。简单地说,就是当你写一个 volatile 变量之前,Java 内存模型会插入一个写屏障(write barrier),读一个 volatile 变量之前,会插入一个读屏障(read barrier)。意思是说,在你写一个 volatile 域时,能保证任何线程都能看到你写的值;同时,在写之前,也能保证任何数值的更新对所有线程是可见的,因为内存屏障会将其他所有写的值更新到缓存。

4)volatile 修饰的变量提供什么保证?

volatile 变量提供顺序和可见性保证。例如,JVM 或 JIT 为了获得更好的性能会对语句重排序,但 volatile 修饰的变量即使在没有同步块的情况下赋值也不会与其他语句重排序。volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。某些情况下,volatile 还能提供原子性,如读 64 位数据类型,像 long 和 double 都不是原子的,但 volatile 修饰的 double 和 long 就是原子的。

5)10 个线程和 2 个线程的同步代码,哪个更容易些?

从写代码的角度来说,两者的复杂度是相同的,因为同步代码与线程数量是相互独立的。但是同步策略的选择依赖于线程的数量,因为越多的线程意味着更大的竞争,所以你需要利用同步技术,如锁分离,这要求更复杂的代码和专业知识。

6)你是如何调用 wait() 方法的?使用 if 块还是循环?为什么?

wait() 方法应该在循环中调用,因为当线程获取到 CPU 开始执行的时候,其他条件可能还没有满足,所以在处理前,循环检测条件是否满足会更好。下面是一段标准的使用 wait 和 notify 方法的代码:

// The standard idiom for using the wait method
synchronized(obj){
    while(condition does not hold)
        obj.wait(); // (Release lock, and reacquires on wakeup)
        ... // Perform action appropriate to condition
}

参见 《Effective Java》第 69 条,获取更多关于为什么应该在循环中调用 wait 方法的内容。

7)什么是多线程环境下的伪共享(false sharing)?

伪共享是多线程系统(每个处理器有自己的局部缓存)中一个众所周知的性能问题。伪共享发生在不同处理器上的线程对变量的修改依赖于相同的缓存行,如下图所示:

伪共享问题很难被发现,因为线程可能访问完全不同的全局变量,内存中却碰巧在很相近的位置上。如其他诸多的并发问题,避免伪共享的最基本方式是仔细审查代码,根据缓存行来调整你的数据结构。关于伪共享的扩展阅读

有经验程序员的 Java 面试题

8)什么是 Busy spin?我们为什么要使用它?

Busy spin 是一种在不释放 CPU 的基础上等待事件的技术。它经常用于避免丢失 CPU 缓存中的数据(如果线程先暂停,之后在其他CPU上运行就会丢失)。所以,如果你的工作要求低延迟,并且你的线程目前没有任何顺序,这样你就可以通过循环检测队列中的新消息来代替调用 sleeep() 或 wait() 方法。它唯一的好处就是你只需等待很短的时间,如几微秒或几纳秒。LMAX 分布式框架是一个高性能线程间通信的库,该库有一个 BusySpinWaitStrategy 类就是基于这个概念实现的,使用 busy spin 循环 EventProcessors 等待屏障。关于Busy spin的扩展阅读 Disruptor入门   Java 核心

9)Java 中怎么获取一份线程 dump 文件?

在 Linux 下,你可以通过命令 kill -3 PID (Java 的进程D)来获取 Java 应用的 dump 文件。在 Windows 下,你可以按下 Ctrl + Break 来获取。这样 JVM 就会将线程的 dump 文件打印到标准输出或错误文件中,它可能打印在控制台或日志文件中,具体位置依赖应用的配置。假设你使用Tomcat。

10)Swing 是线程安全的吗?

不是,Swing 不是线程安全的。你不能通过任何线程来更新 Swing 组件,如 JTable、JList 或 JPanel。事实上,它们只能通过 GUI 或 AWT 线程来更新。这就是为什么 Swing 提供 invokeAndWait() 和 invokeLater() 方法来获取其他线程的 GUI 更新请求。这些方法将更新请求放入 AWT 的线程队列中,可以一直等待,也可以通过异步更新直接返回结果。你也可以在参考答案中查看和学习到更详细的内容。

11)什么是线程局部变量?

当使用 ThreadLocal 维护变量时,ThreadLocal 

 

本文转载自:https://www.cnblogs.com/goody9807/p/6425399.html

圣洁之子
粉丝 10
博文 398
码字总数 123464
作品 0
深圳
后端工程师
私信 提问
金九银十,史上最强 Java 面试题整理。

以下会重新整理所有 Java 系列面试题答案、及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新。 Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spring 面试...

Java技术栈
2018/09/13
0
0
去投资银行面试会遇到的10个Java问题

本文由ImportNew -大瓜细瓜 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 很多Java开发人员会到巴克莱、瑞士信贷、花旗等投资银行申请Java开发职位,但他们中很多人都不知道面试时会遇...

ImportNew
2018/07/25
0
0
工作5年的Java程序员,才学会阅读源码,可悲吗?

最近一位5年开发经验的群友与我聊天 他说:最近慢慢的尝试去看spring的源码,学习spring,以前都只是会用就行了,但是越是到后面,发现只懂怎么用还不够,在面试的时候经常被问到一些开源框架...

Java架构
02/14
0
0
大佬分享:180+道Java面试题目!含答案解析!

作者:我是offer 链接:https://www.nowcoder.com/discuss/84736 来源:牛客网 大厂常见问题 写视频点播网站文件下载接口 基础变量/数组写出模拟maven导入包过程 写出新变脸内存分配,模拟垃...

Java高级架构
2018/07/24
0
0
想跳槽?还是先看看这些Github上的面试项目吧

对于很多人来说,找到一份工作不是问题,但找到一个合适而满意的工作,却不那么简单。 本文我们将盘点几个面试的开源项目,希望对你们有所帮助。 1coding-interview-university https://git...

程序员之家_
2018/09/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
21分钟前
4
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
今天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
今天
5
0
轻量级 HTTP(s) 代理 TinyProxy

CentOS 下安装 TinyProxy yum install -y tinyproxy 启动、停止、重启 # 启动service tinyproxy start# 停止service tinyproxy stop# 重启service tinyproxy restart 相关配置 默认...

Anoyi
今天
2
0
Linux创建yum仓库

第一步、搞定自己的光盘 #创建文件夹 mkdir -p /media/cdrom #挂载光盘 mount /dev/cdrom /media/cdrom #编辑配置文件使其永久生效 vim /etc/fstab 第二步,编辑yun源 vim /ect yum.repos.d...

究极小怪兽zzz
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部