本文我们将会介绍JVM的一个更新,这就是持久代的移除。我们会介绍为什么需要移除持久代,以及它的替代者,元空间(metaspace)。这是上一篇文章内存管理之垃圾回收的续集。
Java的Finalizer引发的内存溢出
本文介绍的是Java里一个内建的概念,Finalizer。你可能对它对数家珍,但也可能从未听闻过,这得看你有没有花时间完整地看过一遍java.lang.Object类了。在java.lang.Object里面就有一个finalize()的方法。这个方法的实现是空的,不过一旦实现了这个方法,就会触发JVM的内部行为,威力和危险并存。
Java中创建URL的常见问题及解决方案
URL无处不在,不过似乎开发人员并没有真正地理解它们,因为我在Stack Overflow上经常看到有人在问如何正确的创建一个URL。想知道URL语法是如何工作的,可以看下Lunatech的这篇文章,非常不错 。
contains与binarySearch的性能比较
查找List中的元素有两种方法,一个是使用contains()方法,还有一个是使用Collectoins.binarySearch()。binarySearch()方法有两种实现,一个版本是接受List和Comparator对象作为参数,另一个是接受List以及Comparable对象。这个方法使用二分查找算法来查询指定列表中的某个元素。在调用这个方法前,列表中的元素得按照它们的自然顺序进行升序排列。如果列表没有排序的话,方法调用的结果是不确定的。如果列表有多个元素与查找的元素一样,那么返回的具体是哪一个是不确定的。对于一个可”随机访问“的列表来说,算法的时间复杂度是O(log(n)。如果指定的列表没有实现RandomAccess接口并且列表长度很大的话,这个方法会基于迭代器来进行二分法的查找,它会执行O(n)次链接的遍历以及O(log n)次元素的比较。在方法的结尾,如果查找到了该元素,则返回对应元素在列表中的序号,否则返回的是(-(插入点序号)-1)。插入点的意思是这个元素应该在这个列表中的这个位置进行插入:第一个大于该查找元素的值所在的位置,如果所有元素都小于它的话则是list.size()。这意味着,当且仅当元素查找成功时,返回值才会大于等于0。List接口常见的实现比如ArrayList, Vector, CopyOnWriteArrayList和Stack都实现了RandomAccess接口,它们可以用来进行二分查找,不过还有些别的实现比如LinkedList,它没有实现RandomAccess接口,因此不适合使用二分查找。由于二分查找只能在排好序的列表中进行,因为在查找前你得先对列表排序,这可能会影响到性能,尤其是你的列表很大并且本来就无序的情况下。
关于Java的10个谎言
下面的这些都算是比较高级的问题了,面试中一般也很少问到,因为它们可能会把面试者拒之门外。不过你可以自己找个时间来实践一下。 1. System.exit(0)会跳过finally块的执行
这段代码为什么会输出In the finally block?为什么没有打印出堆栈跟踪信息呢? 2. String str = "Hello”;其中str是一个字符串对象 跟C++不同的是,Java里的变量要么是基础类型,要么是引用。变量不可能是对象。这意味着像这样的表达式:
Java中字符串switch的实现细节
自从Java允许在switch及case语句中使用字符串以来,许多开发人员都使用了这一特性,不过如果使用整型或者枚举的话会更好。这是JDK7中最受欢迎的特性之一,同样的还有自动资源管理以及多异常捕获。尽管我个人不太喜欢这个特性,因为使用枚举的方式其实更好,但我并不是特别反对使用它。一个原因当然是它很方便,如果程序中已经用到了字符串,这样做的确很顺手,不过我建议在生产环境的代码中使用新特性之前最好了解下它是如何工作的。我第一次听说这个特性的时候,我认为这肯定是通过equals()和hashCode()方法来实现的,我更关心的是Java 7中的字符串的switch是如何实现的。我对这个感兴趣还有一个原因,是我想在面试中问一下这个问题,如果面试中有类似这样的一个问题的话会非常有趣。验证它其实非常简单,你只需用字符串写一段switch的代码,然后反编译一下,看看编译器是如何翻译它们的就可以了。那么还等什么,赶快来看下switch中的字符串是如何工作的吧?
为什么不应该加班?
经常加班有好处也有坏处,下面我会把它们一一都列举出来。有些原因大家都知道,有些则是我个人的经验,如果你还有别的理由,请不吝赐教,我会把它们加到列表里来。