分享几个你可能忽视的 java 面试题

JAVA herman 324浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

3、4 月份是面试的黄金季,最近不管是知乎还是微信里,都有不是人在问我要资料,也或者是让我下载一些面试资料。

所以,我还是分享一些简单的面试题吧,希望能够帮助到你们!

程序员面试

面试其实就是靠复习,复习的好,就容易找到工作!

那些面试好几次都没有面试上的,面试的多了,见的题多了。最后不都找到了工作吗?所以说,没有差的程序员,只有懒的程序员!

问:Java 中能创建 volatile 数组吗?

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

问:volatile 能使得一个非原子操作变成原子操作吗?

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

问:volatile 修饰符的有过什么实践?

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

问:volatile 类型变量提供什么保证?

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

问:Java 中 sleep 方法和 wait 方法的区别?

答:虽然两者都是用来暂停当前运行的线程,但是 sleep() 实际上只是短暂停顿,因为它不会释放锁,而 wait() 意味着条件等待,这就是为什么该方法要释放锁,因为只有这样,其他等待的线程才能在满足条件时获取到该锁。

推荐阅读:《代码中的Thread.sleep(0) 有什么意义?是写错了吗?》,《java线程最熟悉而又陌生的知识点:sleep与wait》。

问:什么是不可变对象(immutable object)?Java 中怎么创建一个不可变对象?

答:不可变对象指对象一旦被创建,状态就不能再改变。任何修改都会创建一个新的对象,如 String、Integer及其它包装类。详情参见答案,一步一步指导你在 Java 中创建一个不可变的类。

推荐阅读:《String 的“不可变性”是因为 final?请别再错下去了!》、《欲练神功必先自宫,String 自宫后“不可变性”到底有啥好处?》、《Java 11 更新了 String 字符串 API,你得重新认识它》。

问:Java 中 ++ 操作符是线程安全的吗?

答:不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交差。

推荐阅读:《从 i++ 和 ++i 说起局部变量表和操作数栈!》。

问:a = a + b 与 a += b 的区别?

答:+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作。如果加法操作的结果比 a 的最大值要大,则 a+b 会出现编译错误,但是 a += b 没问题,如下:

byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok

问:3*0.1 == 0.3 将会返回什么?true 还是 false?

答:false,因为有些浮点数不能完全精确的表示出来。

问:Serial 与 Parallel GC之间的不同之处?

答:Serial 与 Parallel 在GC执行的时候都会引起 stop-the-world。它们之间主要不同 serial 收集器是默认的复制收集器,执行 GC 的时候只有一个线程,而 parallel 收集器使用多个 GC 线程来执行。

问:32 位和 64 位的 JVM,int 类型变量的长度是多数?

答:32 位和 64 位的 JVM 中,int 类型变量的长度是相同的,都是 32 位或者 4 个字节。

问:Java 中 WeakReference 与 SoftReference的区别?

答:虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候。

问:解释 Java 堆空间及 GC?

答:当通过 Java 命令启动 Java 进程的时候,会为它分配内存。内存的一部分用于创建堆空间,当程序中创建对象的时候,就从对空间中分配内存。GC 是 JVM 内部的一个进程,回收无效对象的内存用于将来的分配。

问:你能保证 GC 执行吗?

答:不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC 的执行。

问:List、Set、Map 和 Queue 之间的区别

答:List 是一个有序集合,允许元素重复。它的某些实现可以提供基于下标值的常量访问时间,但是这不是 List 接口保证的。Set 是一个无序集合。

问:队列的 poll() 方法和 remove() 方法的区别?

答:poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。

问:用哪两种方式来实现集合的排序?

答:你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有顺序的的集合,如 list,然后通过 Collections.sort() 来排序。

问:Java 中怎么打印数组?

答:你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法来打印数组。由于数组没有实现 toString() 方法,所以如果将数组传递给 System.out.println() 方法,将无法打印出数组的内容,但是 Arrays.toString() 可以打印每个元素。

问:Java 中,编写多线程程序的时候你会遵循哪些最佳实践?

答:最佳实践:给线程命名,这样可以帮助调试;最小化同步的范围,而不是将整个方法同步,只对关键部分做同步;如果可以,更偏向于使用 volatile 而不是 synchronized;使用更高层次的并发工具,而不是使用 wait() 和 notify() 来实现线程间通信,如 BlockingQueue,CountDownLatch 及 Semeaphore;优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。

问:说出几点 Java 中使用 Collections 的最佳实践?

答:最佳实践:使用正确的集合类,例如,如果不需要同步列表,使用 ArrayList 而不是 Vector;优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性;使用接口代表和访问集合,如使用List存储 ArrayList,使用 Map 存储 HashMap 等等;使用迭代器来循环集合;使用集合的时候使用泛型。

程序员个人简历

今天我们就先到这里吧,后面我们再加入高难度的面试题!上面这个个人简历,你们看一下吧!有何感想?

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » 分享几个你可能忽视的 java 面试题