Java开发日常问题.doc_第1页
Java开发日常问题.doc_第2页
Java开发日常问题.doc_第3页
Java开发日常问题.doc_第4页
Java开发日常问题.doc_第5页
免费预览已结束,剩余12页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java 开发日常问题一、 Java 基础71、String 类为什么是final 的 .final 的出现就是为了为了不想改变,而不想改变的理由有两点:设计(安全 )或者效率。 final修饰的类是不被能继承的,所以final修饰的类是不能被篡改的。1、从设计安全 )上讲,1) 、确保它们不会在子类中改变语义。String 类是 final 类,这意味着不允许任何人定义String 的子类。换言之,如果有一个String 的引用,它引用的一定是一个String 对象,而不可能是其他类的对象。2)、String一旦被创建是不能被修改的,因为java设计者将String为可以共享的2、从效率上讲

2、:1) 、设计成 final ,JVM 才不用对相关方法在虚函数表中查询,而直接定位到String 类的相关方法上,提高了执行效率。2) 、Java 设计者认为共享带来的效率更高。总而言之,就是要保证java.lang.String引用的对象一定是java.lang.String的对象,而不是引用它的子孙类,这样才能保证它的效率和安全。 2、 HashMap 的源码 ,实现原理 , 底层结构 . 在 JDK1.6 , JDK1.7 中, HashMap 采用位桶 +链表实现,即使用链表处理冲突,同一hash 值的链表都存储在一个链表里。 但是当位于一个桶中的元素较多,即 hash值相等的元素较

3、多时,通过key 值依次查找的效率较低。而JDK1.8 中, HashMap采用位桶 + 链表 +红黑树实现, 当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间 .HashMap本来是以空间换时间,所以填充比没必要太大。但是填充比太小又会导致空间浪费。如果关注内存,填充比可以稍大,如果主要关注查找性能,填充比可以稍小。 3、说说你知道的几个 Java 集合类 :list 、 set 、queue 、 map 实现类咯 .Collection 接口 Collection 是Java 中最基本的集合接口。 它描述了一组有关集合操作的方法。 int Size(); / 集合大小

4、boolean isEmpty(); /是否为空boolean contains(Object o); /是否包含某个对象Iterator<E> iterator(); /返回一个迭代对象,用来遍历集合中的元素Object toArray(); / 将集合中的元素以数组形式然后返回 <T> T toArray(T a); / 上一个方法的泛型形式 boolean add(E e); / 将对象 e 添加进集合,添加成功则返回 trueboolean remove(Object o); /移除某个元素boolean containsAll(Collection<?&

5、gt; c); / 传入一个集合 c,如果 c 中的元素都存在,则返回 trueboolean addAll(Collection<? extends E> c); /将集合 c中的元素全部添加进本集合boolean removeAll(Collection<?> c); /本集合减去c 集合中的元素boolean retainAll(Collection<?> c); /取本集合和c 集合的交集void clear(); / 清空集合boolean equals(Object o); /判断相等int hashCode(); / 获取集合当前的 hash

6、值 123456789101112131415Set 接口 Set 接口直接继承自 Collection 接口,并且方法接口上也一模一样。 Set 对添加的元素有一些要求,其不允许出现重复的元素,并且元素之间没有次序。这相当于一个不允许重复的离散的集合。因此,添加进 Set 的元素类型需要定义equals 方法。若是使用自定义的类,则应该重写equals 方法来确保实现自己需要的功能。Set 接口主要实现了两个类:HashSet ,TreeSet 。 HashSet是按照哈希来存取元素的,因此速度较快。HashSet 继承自抽象类 AbstractSet ,然后实现了 Set 、Cloneab

7、le 、 Serializable 接口。 TreeSet 也是继承自 AbstractSet ,不过不同的是其实现的是 NavigableSet 接口。而 NavigableSet继承自 SortedSet 。SortedSet是一个有序的集合。其添加的元素必须实现了Comparable接口,因为其在添加一个元素的时候需要进行排序。NavigableSet则提供了更多的有关元素次序的方法,比如:E lower(E e); /找出小于e 的元素E floor(E e); / 找出小于等于e 的元素E ceiling(E e); /找出大于等于e 的元素E higher(E e); /找出大于

8、e 的元素E pollFirst(); / 弹出第一个(最小)元素,如果集合为空则返回 nullE pollLast(); / 弹出最后一个(最大)元素,如果集合为空则返回 null123456LinkedHashSet 也是 Set 的一个实现。和 HashSet 类似,只不过内部用链表来维护,按照元素插入次序来保存。 List 接口 List 接口也是继承自Collection 。与 Set不同的是, List 可以存储重复的元素。主要有两种实现:ArrayList 和 LinkedList 。 ArrayList没有什么好说的,就像传统的数组一样,有着很快的随机存取速度,但是插入删除的速

9、度就很慢。LinkedList则与 ArrayList 恰恰相反,因为用链表来保存数据,所以插入删除元素的速度很快,但是访问数据的速度就不如ArrayList了。 Map 接口 Map (映射)是一个存储键值对的容器接口。每一个元素包含一个key对象和value对象,且元素不允许重复。Map接口的实现有以下几个:HashMap是最常用的一个实现。HashMap使用hash映射来存取数据,这个速度是相当快,是O(1) 的速度。其容量capacity,和负载因子load factor可以在一开始设定。当元素个数达到capacity*load factor的时候, 就会进行扩容。LinkedHash

10、Map和 HashMap类似,只不过内部用链表来维护次序。因此遍历时候的顺序是其插入顺序。TreeMap 是基于红黑树的Map ,插入的数据被有次序保存,并且有很高的效率。因此在遍历输出的时候可以得到排序的数据。但是这要求插入的数据实现了comparable接口。总结 Collection 、 Set 、List 和 Map 都是接口,不能被实例化。Set 和 List 都继承自 Collection ,而 Map 则和 Collection 没什么关系。 Set 和 List 的区别在于 Set 不能重复,而 List 可以重复。Map 和 Set 与 List 的区别在于, Map 是存取

11、键值对,而另外两个则是保存一个元素。4、描述一下ArrayList和LinkedList各自实现和区别ArrayList没有什么好说的, 就像传统的数组一样,有着很快的随机存取速度,但是插入删除的速度就很慢。LinkedList则与 ArrayList恰恰相反,因为用链表来保存数据,所以插入删除元素的速度很快,但是访问数据的速度就不如ArrayList了。5、Java中的队列都有哪些,有什么区别.queue的实现有:ConcurrentLinkedQueue、 LinkedBlockingQueue、ArrayBlockingQueue、LinkedList 。 LinkedBlockingQ

12、ueue是使用锁机制, ConcurrentLinkedQueue是使用 CAS 算法,虽然 LinkedBlockingQueue的底层获取锁也是使用的 CAS算法关于取元素, ConcurrentLinkedQueue不支持阻塞去取元素, LinkedBlockingQueue支持阻塞的take() 方法,如若大家需要 ConcurrentLinkedQueue的消费者产生阻塞效果,需要自行实现关于插入元素的性能,从字面上和代码简单的分析来看ConcurrentLinkedQueue肯定是最快的, 但是这个也要看具体的测试场景,我做了两个简单的demo做测试,测试的结果如下,两个的性能差不

13、多,但在实际的使用过程中,尤其在多cpu 的服务器上,有锁和无锁的差距便体现出来了, ConcurrentLinkedQueue会比 LinkedBlockingQueue快很多 6、反射中 ,Class.forName 和 classloader 的区别 java 中 class.forName() 和 classLoader 都可用来对类进行加载。 class.forName()前者除了将类的.class 文件加载到jvm中之外,还会对类进行解释,执行类中的static 块。而classLoader只干一件事情,就是将.class 文件加载到jvm中,不会执行static 中的内容 ,只有

14、在 newInstance才会去执行static块。 Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象7、Java7、 Java8的新特性(baidu问的,好BT)Java8新增了非常多的特性,主要以下几个:Lambda表达式?Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中。方法引用? 方法引用提供了非常有用的语法,可以直接引用已有Java 类或对象(实例)的方法或构造器。与 lambda 联合使用,方法引用可以使语言的构造更紧凑

15、简洁,减少冗余代码。默认方法? 默认方法就是一个在接口里面有了一个实现的方法。新工具? 新的编译工具,如:Nashorn 引擎jjs、 类依赖分析器jdeps 。 Stream API ? 新添加的 Stream API ( java.util.stream ) 把真正的函数式编程风格引入到 Java 中。Date Time API ? 加强对日期与时间的处理。 Optional 类 ? Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。 Nashorn, JavaScript 引擎 ? Java 8 提供了一个新的 Nashorn javascript 引擎,它允

16、许我们在 JVM 上运行特定的 javascript 应用。 8、 Java 数组和链表两种结构的操作效率 ,在哪些情况下 (从开头开始 , 从结尾开始 ,从中间开始 ),哪些操作 (插入 ,查找 ,删除 )的效率高(1) 从逻辑结构角度来看 a, 数组必须事先定义固定的长度(元素个数) ,不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。 b, 链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项) (2) 从内存存储角度来看 a,( 静态 )数组从栈中分配空间 (

17、 这个有待确定, 毕竟是 Java 的数组 ), 对于程序员方便快速 ,但自由度小。 b, 链表从堆中分配空间 , 自由度大但申请管理比较麻烦 . 数组和链表的区别整理如下: 数组静态分配内存,链表动态分配内存; 数组在内存中连续, 链表不连续; 数组元素在栈区,链表元素在堆区;数组利用下标定位, 时间复杂度为O(1) ,链表定位元素时间复杂度O(n) ; 数组插入或删除元素的时间复杂度 O(n) ,链表的时间复杂度O(1) 。9、 Java 内存泄露的问题调查定位:jmap,jstack的使用等等A 、jps(Java Virtual Machine Process Status Tool)

18、 :jps 主要用来输出 JVM 中运行的进程状态信息。B、jstack :主要用来查看某个Java 进程内的线程堆栈信息C 、jmap( Memory Map )和 jhat( Java Heap Analysis Tool)jmap 用来查看堆内存使用状况,一般结合jhat 使用。D 、jstat( JVM 统计监测工具)10 、string 、stringbuilder 、stringbuffer区别String 字符串常量;StringBuffer 字符串变量;StringBuilder 字符串变量。在执行速度上,String < StringBuffer <Stringb

19、uilder。StringBuffer 是线程安全的,而StringBuilder是非线程安全的StringBuffer和StringBuilder都继承自 AbstractStringBuilder这个类,而AbstractStringBuilder和 String 都继承自 Object 这个类( Object 是所有 java 类的超类)。所以这三个类之间的关系可以大致表示为:11 、hashtable 和 hashmap 的区别HashMap和 Hashtable都实现了 Map 接口主要的区别有:线程安全性,同步(synchronization),以及速度HashMap 几乎可以等价

20、于 Hashtable ,除了 HashMap 是非 synchronized 的,并可以接受 null(HashMap 可以接受为 null 的键值 (key) 和值 (value) ,而 Hashtable 则不行 )。 HashMap 是非 synchronized ,而 Hashtable 是 synchronized ,这意味着 Hashtable是线程安全的,多个线程可以共享一个Hashtable ;而如果没有正确的同步的话,多个线程是不能共享 HashMap的。Java 5 提供了 ConcurrentHashMap,它是 HashTable 的替代,比 HashTable 的扩

21、展性更好。另一个区别是 HashMap 的迭代器 (Iterator) 是 fail-fast 迭代器,而 Hashtable 的 enumerator 迭代器不是 fail-fast 的。所以当有其它线程改变了 HashMap 的结构(增加或者移除元素) ,将会抛出 ConcurrentModificationException,但迭代器本身的 remove() 方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM 。这条同样也是Enumeration和Iterator 的区别。由于 Hashtable 是线程安全

22、的也是 synchronized ,所以在单线程环境下它比 HashMap 要慢。如果你不需要同步,只需要单一线程,那么使用 HashMap 性能要好过 Hashtable 。 HashMap 不能保证随着时间的推移 Map 中的元素次序是不变的。13 、异常的结构 ,运行时异常和非运行时异常,各举个例子Java 异常机制异常是程序运行过程中出现的错误。此处主要讲的是Java 语言的异常处理。Java 语言的异常处理框架,是Java 语言健壮性的一个重要体现。Java 把异常当作对象来处理, 并定义一个基类java.lang.Throwable作为所有异常的超类。在Java API中已经定义了

23、许多异常类,这些异常类分为两大类,错误 Error 和异常 Exception 。Java异常体系结构呈树状,其层次结构图如图所示: 1)、 Thorwable 类 Thorwable 类所有异常和错误的超类, 有两个子类 Error 和 Exception ,分别表示错误和异常。 其中异常类 Exception 又分为运行时异常 (RuntimeException) 和非运行时异常,这两种异常有很大的区别,也称之为不检查异常( Unchecked Exception )和检查异常( Checked Exception )。2).Error (错误):一般是指 java 虚拟机相关的问题,如系

24、统崩溃、虚拟机出错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断,通常应用程序无法处理这些错误,因此应用程序不应该捕获Error对象,也无须在其throws子句中声明该方法抛出任何Error或其子类。3).Exception:Exception类及其子类是Throwable的一种形式,它指出了合理的应用程序想要捕获的条件(1)SQLException :该异常提供关于数据库访问错误或其他错误的信息。( 2) RuntimeException是那些可能在Java虚拟机正常运行期间抛出的异常的超类(3) IOException :此类为异常的通用类,它是由失败的或中断的I/O

25、 操作生成的。4) 、运行时异常和非运行时异常( 1)运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。( 2)非运行时异常是RuntimeException以外的异常, 类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException 、SQLException等以及用户自定

26、义的Exception异常,一般情况下不自定义检查异常。5) 、异常的捕获和处理Java 异常的捕获和处理是一个不容易把握的事情,如果处理不当,不但会让程序代码的可读性大大降低,而且导致系统性能低下,甚至引发一些难以发现的错。Java 异常处理涉及到五个关键字,分别是:try 、catch 、finally 、throw 、throws 。下面将骤一介绍,通过认识这五个关键字,掌握基本异常处理知识。(1)、 try :它里面放置可能引发异常的代码( 2)、catch :后面对应异常类型和一个代码块,用于表明该catch块用于处理这种类型的代码块,可以有多个catch 块。( 3)、finall

27、y :主要用于回收在try 块里打开的物力资源(如数据库连接、网络连接和磁盘文件),异常机制总是保证finally 块总是被执行。只有finally 块,执行完成之后,才会回来执行try 或者 catch 块中的 return 或者 throw 语句,如果finally中使用了 return 或者 throw 等终止方法的语句,则就不会跳回执行,直接停止。 (4)、 throw :用于抛出一个实际的异常,可以单独作为语句使用,抛出一个具体的异常对象。( 5)、throws :用在方法签名中,用于声明该方法可能抛出的异常。 6) 、throw 与 throws 关键字的区别( 1) throw

28、关键字是用于方法体内部, 用来抛出一个 Throwable 类型的异常。如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该 方法的调用者也必须检查处理抛出的异常。如果所有方法都层层上抛获取的异常,最终JVM会进行处理, 处理也很简单, 就是打印异常消息和堆栈信息。如果抛出 的是 Error 或 RuntimeException ,则该方法的调用者可选择处理该异常。 ( 2)throws 关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵

29、吞枣一般在catch 块中打印一下堆栈信息做个勉强处理。下面给出一个简单例子:常见的RuntimeExceptionNullPointerException-空指针引用异常ClassCastException -类型强制转换异常。IllegalArgumentException -传递非法参数异常。ArithmeticException -算术运算异常ArrayStoreException -向数组中存放与声明类型不兼容对象异常IndexOutOfBoundsException -下标越界异常NegativeArraySizeException - 创建一个大小为负数的数组错误异常 NumberFormatException - 数字格式异常 SecurityException - 安全异常UnsupportedOperationException -不支持的操作异常1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论