Java编程面试
wiseph
这个作者很懒,什么都没留下…
展开
-
synchronized和ReentrantLock有什么区别?
典型回答synchronized是Java内建的同步机制,它提供了互斥的语义和可见性。当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里。在Java 5以前,synchronized是仅有的同步手段。在代码中,synchronized可以用来修饰方法,也可以使用在特定的代码块上,本质上synchronized方法等同于把方法全部语句用synchronized块包起来。Re...转载 2018-08-02 15:23:40 · 1011 阅读 · 0 评论 -
synchronized底层如何实现?
典型回答如果你使用反编译工具查看synchronized代码块,会发现是由一对儿monitorentry/monitorexit指令实现的,Monitor对象是同步的基本实现单元。在Java 6之前,Monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作。现代的(Oracle)JDK中,JVM对此进行了大刀阔斧地改进,...转载 2018-08-02 15:24:05 · 1182 阅读 · 0 评论 -
一个线程两次调用start()方法会出现什么情况?
典型回答Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常,多次调用start被认为是编程错误。关于线程生命周期的不同状态,在Java 5以后,线程状态被明确定义在其公共内部枚举类型java.lang.Thread.State中,分别是:NEW(新建),表示线程被创建出来还没真正启动的状态,可以认为它是个Ja...转载 2018-08-02 15:25:15 · 3449 阅读 · 0 评论 -
什么情况下Java程序会产生死锁?
典型回答死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅会发生在线程之间,存在资源独占的进程之间同样也可能出现死锁。通常来说,我们大多是聚焦在多线程场景中的死锁,指两个或多个线程之间,由于互相持有对方需要的锁,而永久处于阻塞的状态。就像下图中所示:定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位互相之...转载 2018-08-02 15:26:10 · 3198 阅读 · 0 评论 -
Java并发包提供了哪些并发工具类?
典型回答我们通常所说的并发包也就是java.util.concurrent及其子包,集中了Java并发的各种基础工具类,具体主要包括几个方面:提供了比synchronized更加高级的各种同步结构,包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作。比如利用Semaphore作为资源控制器,限制同时进行工作的线程数量。 各种线...转载 2018-08-02 15:26:50 · 1662 阅读 · 0 评论 -
CountDownLatch和CyclicBarrier有什么区别?
CountDownLatch有时被称为“闭锁”,其作用相当于一扇门:在CountDownLatch达到结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。当CountDownLatch到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。CountDownLatch可以用来确保某些活动直到其它活动都完成后才继续执行。Cycli...转载 2018-08-13 16:43:37 · 3071 阅读 · 0 评论 -
ConcurrentLinkedQueue和LinkedBlockingQueue有什么区别?
典型回答有时候我们把并发包下面的所有容器都习惯叫作并发容器,但是严格来讲,只有以“Concurrent”为前缀的容器才是真正的并发容器。ConcurrentLinkedQueue基于lock-free,在常见的多线程访问场景,一般可以提供较高吞吐量。 而LinkedBlockingQueue内部则是基于锁,并提供了BlockingQueue的等待性方法。不知道你有没有注意到,java....转载 2018-08-13 16:43:47 · 2907 阅读 · 0 评论 -
Java并发类库提供的线程池有哪几种?
既然创建或销毁线程存在一定的开销,所以利用线程池技术来提高系统资源利用效率,并简化线程管理,已经是非常成熟的选择。典型回答通常开发者都是利用Executors提供的通用线程池创建方法,去创建不同配置的线程池,主要区别在于不同的ExecutorService类型或者不同的初始参数。Executors目前提供了5种不同的线程池创建配置:newCachedThreadPool(),它是一种用...转载 2018-08-13 16:44:08 · 2620 阅读 · 0 评论 -
AtomicInteger底层实现原理是什么?
典型回答AtomicInteger是对int类型的一个封装,提供原子性的访问和更新操作,其原子性操作的实现是基于CAS(compare-and-swap)技术。所谓CAS,表现为一组指令,当利用CAS执行试图进行一些更新操作时。会首先比较当前数值,如果数值未变,代表没有其它线程进行并发修改,则成功更新。如果数值改变,则可能出现不同的选择,要么进行重试,要么就返回是否成功。也就是所谓的“乐观...转载 2018-08-13 16:44:21 · 9053 阅读 · 0 评论 -
类加载过程是怎样的?
典型回答一般来说,我们把Java的类加载过程分为三个主要步骤:加载、链接、初始化,具体行为在Java虚拟机规范里有非常详细的定义。加载阶段(Loading):它是Java将字节码数据从不同的数据源读取到JVM中,并映射为JVM认可的数据结构(Class对象)。这里的数据源可能是各种各样的形态,如jar文件、class文件,甚至是网络数据源等。如果输入数据不是ClassFile的结构,则会抛...转载 2018-08-13 16:43:58 · 11485 阅读 · 0 评论 -
Java反射机制与动态代理的原理是什么?
典型回答反射机制是Java语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或构造对象,甚至可以运行时修改类定义。动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的。比如用来包装RPC调用、面向切面的编程(AOP)。...转载 2018-08-13 16:44:30 · 3375 阅读 · 0 评论 -
MySQL字符串类型字段值大小写问题
太长不看版MySQL数据库默认情况下,字符串字段的所有相关运算是大小写“不敏感”的。这一点与其它流行的数据库都不相同。 本文介绍了三种方法解决这个问题。 其中一种在查询时指定大小写敏感,但可能存在性能风险。 另外两种则是在表结构定义时定义。MySQL数据库备受争议的特性先看一句SQL语句:SELECT * FROM fruit WHERE name = 'Apple'这是...转载 2018-08-13 16:44:40 · 2669 阅读 · 0 评论 -
掌握这些搜索技巧,你将成为一名高效的程序员!
对于缺乏编程知识的人来说,完全有可能编写一个网页或小程序。如果在用Google搜索相关示例时幸运的话,可以搜到现成的代码。即使是经验丰富的程序员,通常也会为了节省时间和精力而在网上搜索解决方案。如果不借助搜索技术、网络及集体智慧,现代化高效编程是难以想象的。因此,搜索技巧对高效程序员变得愈发重要。现在,我们不需要了解和记住如何解决众多的编程问题,可以采用搜索技术。我们正变得更加高效、高生产...转载 2018-08-13 16:45:02 · 232 阅读 · 0 评论 -
并行计算执行器——ParallelExecutor
今天要给大家介绍一个新的来自Rumba Commons Mini的工具——ParallelExecutor,正如其名字所表达的,它提供并行计算执行器的功能。让我们通过一个简单的例子来了解ParallelExecutor的工作原理。假设某家全国性的大型连锁经营企业,旗下有分布于全国的连锁门店100,000家,现在需要我们统计今年所有门店总销售额。问题在于一方面由于某种原因我们必须直接从原始销售数...转载 2018-08-13 16:45:14 · 1046 阅读 · 0 评论 -
单例的几种实现
作为GoF 23种设计模式之一的单例模式,在程序之中有大量的使用。所谓单例模式,简单说就是确保类在程序中只会被创建一个实例。看起来似乎很简单,那么下面这个样例符合基本需求吗?public class Singleton { private static Singleton instance = new Singleton(); public static Singleton getI...转载 2018-08-02 15:22:34 · 153 阅读 · 0 评论 -
Java有几种文件拷贝方式?哪一种最高效?
典型回答Java有多种比较典型的文件拷贝实现方法。方法1:利用java.io类库。直接为源文件创建一个FileInputStream负责读取,然后再为目标文件创建一个FileOutputStream负责写入:public static void copyFileByStream(File source, File target) throws IOException { try ...转载 2018-08-02 15:22:09 · 3071 阅读 · 0 评论 -
Java提供了哪些IO方式?
首先,传统的java.io包基于流模型实现,提供了我们最熟知的一些IO功能,比如File抽象、输入输出流等,交互方式是同步、阻塞的方式。也就是说,在读取输入流或者写入输出流时,在读、写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线形顺序。java.io包的好处是代码比较简单、直观,缺点则是IO效率和扩展存在局限性,容易成为应用性能的瓶颈。很多时候,人们也把java.net下面...转载 2018-08-02 15:20:53 · 421 阅读 · 0 评论 -
Error、Exception与RuntimeException的区别
先搞清楚它们三者的关系。Error与Exception都继承自Throwable,而RuntimeException则继承自Exception。在Java中只有Throwable类型的实例才可以被抛出(throw)或捕获(catch)。Error和Exception体现了Java平台设计者对不同异常情况的分类。Exception是程序正常运行中可以预料的意外情况,可能并且应该被捕获,进行相...转载 2018-08-01 13:37:41 · 7787 阅读 · 0 评论 -
try-with-resources和multiple catch
从Java 7开始提供了两个有用的特性:try-with-resources和multiple catch。先来看看try-with-resources。当处理某些资源的时候,通常都会在finally里面做一些资源回收的工作。比如:FileInputStream fis = new FileInputStream(file);try { // do something} fina...转载 2018-08-01 13:48:40 · 1685 阅读 · 1 评论 -
异常处理的两个基本原则
先来看一段代码:try { // do something Thread.sleep(1000L);} catch (Exception e) { // ignore it}代码虽短,但已经违反了异常处理的两个基本原则。第一,尽量不要捕获类似Exception这样的通用异常,而是应该捕获特定异常。在这段代码中Thread.sleep()会抛出的Interrupted...转载 2018-08-01 14:00:55 · 1268 阅读 · 0 评论 -
可以在finally代码块中处理返回值么?
先来看一段代码:public boolean doSomething() { try { // do something } finally { // ... return true; }}这段代码的finally代码块中出现return语句。首先Java并不会阻止你写出这样的代码,但这样是合理么?其实之所以写出这样的代码,是因为程序员不确定在...转载 2018-08-01 14:17:53 · 492 阅读 · 0 评论 -
final的几种用法
“谈谈final、finally、finalize有什么不同?”这是个非常经典的问题。finally是Java保证重点代码一定要被执行的一种机制。finalize是基础类java.lang.Object的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。今天我们重点谈谈final,多年的面试经验告诉我,很多人其实失分就是在final上,而非另外两者。final可以用来修饰类、方...转载 2018-08-01 14:28:18 · 423 阅读 · 0 评论 -
finalize真的那么不堪?
是的,真的那么不堪! 业界实践一再证明java.lang.Object中的finalize不是个好的办法,在Java 9中,甚至明确将它标记为deprecated!如果没有特别的原因,不要实现finalize方法,也不要指望利用它来进行资源回收。为什么呢?简单说,你无法保证finalize什么时候执行,执行的是否符合预期。相反使用不当会影响性能,导致程序死锁、挂起等。 fi...转载 2018-08-01 14:34:41 · 829 阅读 · 0 评论 -
String、StringBuffer与StringBuilder有什么区别?
典型的回答 String是Java语言非常基础和重要类,提供了构造和管理字符串的各种基本逻辑。它是典型的不可变类,被声明成final class,所有属性也都是final的。由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的String对象。由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。 StringBuffer是为了解决上面提到拼接产生太多中...转载 2018-08-01 15:06:11 · 1192 阅读 · 0 评论 -
int和Integer有什么区别?
典型的回答int是我们常说的整型数字,是Java的8个原始数据类型之一。Java语言虽然号称一切都是对象,但原始数据类型是例外。Integer是int对应的包装类,它有一个int类型的字段存储数据,并且提供了基本操作,比如数学运算、int和字符串之间转换等。在Java 5中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java可以根据上下文,自动进行转换,极大地简化了相...转载 2018-08-01 15:20:44 · 426 阅读 · 0 评论 -
Vector、ArraysList和LinkedList有什么区别?
典型的回答这三者都是集合框架中List的实现,也就是所谓的有序集合,它们在功能上比较近似。Vector是Java早期提供的线程安全的动态数组,如果不需要线程安全,不建议选择。Vector内部是使用对象数组来保存数据,可以根据需要自动增加容量。当数据已满时,会创建新的数组,并拷贝原有数组数据。ArrayList是应用更加广泛的动态数组实现,它不是线程安全的,所以性能要好很多。与Vecto...转载 2018-08-01 16:06:49 · 1195 阅读 · 0 评论 -
Hashtable、HashMap和TreeMap有什么区别?
典型的回答Hashtable、HashMap、TreeMap都是最常见的Map接口的实现,是以键值对的形式存储和操作数据的容器类型。Hashtable是早期Java类库提供的一个哈希表实现,本身是线程安全的,不支持null键和值。由于线程安全导致的性能开销,所以已经很少被推荐使用。HashMap是应用更加广泛的哈希表实现,行为上大致与Hashtable一致,主要区别在于HashMap不...转载 2018-08-01 22:18:00 · 1032 阅读 · 0 评论 -
HashMap深度解析
HashMap是最被广泛使用的Map接口的实现,了解它的内部实现机制将有利于我们更好的使用这个强有力的工具。首先,我们来一起看看HashMap内部的结构。它可以看作是数组(Node[] table)和链表结合组成的复合结构。数组被分为一个个桶(Bin),通过哈希值决定了键值对在这个数组的寻址。落在同一个桶内的键值对,则以链表形式存储,参考下图。需要注意的是,如果链表大小超过阈值(TREEIFY...转载 2018-08-02 15:22:53 · 298 阅读 · 0 评论 -
如何保证集合是线程安全的?
典型回答Java提供了不同层面的线程安全支持。在传统集合框架内部,除了Hashtable等同步容器,还提供了所谓的同步包装器(Synchronized Wrapper),可以调用Collections工具类提供的包装方法,来获取一个同步的包装容器,例如Collections.synchronizedMap()。但是它们都是利用非常粗粒度的同步方式,在高并发情况下的性能比较低下。另外,更加普...转载 2018-08-02 15:22:46 · 2538 阅读 · 0 评论 -
HashMap实现原理分析
HashMap实现原理分析 Attachments:2 添加者:廖志, 最后更新者: 廖志 于 九月 26, 20171. HashMap的数据结构数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。数组数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;链表链表存储区间离...转载 2018-08-14 19:07:59 · 254 阅读 · 0 评论