1、序言J2SE基础1. 九种基本数据类型的大小,以及他们的封装类。2. Switch能否用string做参数? 3. equals与=的区别。4. Object有哪些公用方法?5. Java的四种引用,强弱软虚,用到的场景。6. Hashcode的作用。7. ArrayList、LinkedList、Vector的区别。8. String、StringBuffer与StringBuilder的区别。9. Map、Set、List、Queue、Stack的特点与用法。10. HashMap和HashTable的区别。11. HashMap和ConcurrentHashMap的区别,HashMap的
2、底层源码。12. TreeMap、HashMap、LindedHashMap的区别。13. Collection包结构,与Collections的区别。14. trycatchfinally,try里有return,finally还执行么?15. Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。16. Java面向对象的三个特征与含义。17. Override和Overload的含义去区别。18. Interface与abstract类的区别。19. Staticclass与nonstaticclass的区别。20. java多态的实现原理。21. 实现多线
3、程的两种方法:Thread与Runable。22. 线程同步的方法:sychronized、lock、reentrantLock等。23. 锁的等级:方法锁、对象锁、类锁。24. 写出生产者消费者模式。25. ThreadLocal的设计理念与作用。26. ThreadPool用法与优势。27. Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。28. wait()和sleep()的区别。29. foreach与正常for循环效率对比。30. JavaIO与NIO。31. 反射的作用于原理。32. 泛型常用特点,List能否转为List
4、。33. 解析XML的几种方式的原理与特点:DOM、SAX、PULL。34. Java与C+对比。35. Java1.7与1.8新特性。36. 设计模式:单例、工厂、适配器、责任链、观察者等等。37. JNI的使用。Java里有很多很杂的东西,有时候需要你阅读源码,大多数可能书里面讲的不是太清楚,需要你在网上寻找答案。推荐书籍:java核心技术卷IThinkinginjavajava并发编程effictivejava大话设计模式JVM1. 内存模型以及分区,需要详细到每个区放什么。2. 堆里面的分区:Eden,survivalfromto,老年代,各自的特点。3. 对象创建方法,对象的内存分配
5、,对象的访问定位。4. GC的两种判定方法:引用计数与引用链。5. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?6. GC收集器有哪些?CMS收集器与G1收集器的特点。7. MinorGC与FullGC分别在什么时候发生?8. 几种常用的内存调试工具:jmap、jstack、jconsole。9. 类加载的五个过程:加载、验证、准备、解析、初始化。10. 双亲委派模型:BootstrapClassLoader、ExtensionClassLoader、ApplicationClassLoader。11. 分派:静态分派与动态
6、分派。JVM过去过来就问了这么些问题,没怎么变,内存模型和GC算法这块问得比较多,可以在网上多找几篇博客来看看。推荐书籍:深入理解java虚拟机操作系统1. 进程和线程的区别。2. 死锁的必要条件,怎么处理死锁。3. Window内存管理方式:段存储,页存储,段页存储。4. 进程的几种状态。5. IPC几种通信方式。6. 什么是虚拟内存。7. 虚拟地址、逻辑地址、线性地址、物理地址的区别。因为是做android的这一块问得比较少一点,还有可能上我简历上没有写操作系统的原因。推荐书籍:深入理解现代操作系统TCP/IP1. OSI与TCP/IP各层的结构与功能,都有哪些协议。2. TCP与UDP的
7、区别。3. TCP报文结构。4. TCP的三次握手与四次挥手过程,各个状态名称与含义,TIMEWAIT的作用。5. TCP拥塞控制。6. TCP滑动窗口与回退N针协议。7. Http的报文结构。8. Http的状态码含义。9. Httprequest的几种类型。10. Http1.1和Http1.0的区别11. Http怎么处理长连接。12. Cookie与Session的作用于原理。13. 电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。14. Ping的整个过程。ICMP报文是什么。15. C/S模式下使用socket通信,几个关键函数。16. I
8、P地址分类。17. 路由器与交换机区别。网络其实大体分为两块,一个TCP协议,一个HTTP协议,只要把这两块以及相关协议搞清楚,一般问题不大。推荐书籍:TCP/IP协议族数据结构与算法1. 链表与数组。2. 队列和栈,出栈与入栈。3. 链表的删除、插入、反向。4. 字符串操作。5. Hash表的hash函数,冲突解决方法有哪些。6. 各种排序:冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。7. 快排的partition函数与归并的Merge函数。8. 对冒泡与快排的改进。9. 二分查找,与变种二分查找。10. 二叉树、B+树、
9、AVL树、红黑树、哈夫曼树。11. 二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。12. 图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。13. KMP算法。14. 排列组合问题。15. 动态规划、贪心算法、分治算法。(一般不会问到)16.大数据处理:类似10亿条数据找出最大的1000个数.等等算法的话其实是个重点,因为最后都是要你写代码,所以算法还是需要花不少时间准备,这里有太多算法题,写不全,我的建议是没事多在OJ上刷刷题(牛客网、leetcode等),剑指offer上的算法要能理解并自己写出来,编程之美也推荐看一看。推荐书籍:大话数据结构剑指offe
10、r编程之美J2SE基础1.九种基本数据类型的大小,以及他们的封装类。java提供了一组基本数据类型,包括boolean, byte, char, short, int, long, float, double, void. 同时,java也提供了这些类型的封装类,分别为Boolean, Byte, Character, Short, Integer, Long, Float, Double, Void类型字节表示范围包装类byte(字节型)1-128127Byteshort(短整型)2-3276832767 Shortint(整型)4-21474836482147483647Integerlo
11、ng(长整型)8-9223372036854775808 9223372036854775807Longfloat(浮点型)4-3.4E383.4E38Floatdouble(双精度型)8-1.7E3081.7E308Doublechar(字符型)2从字符型对应的整型数来划分,其表示范围是065535 Charaterbooealn(布尔型)1true或falseBoolean2.Switch能否用string做参数?在 Java 7之前,switch 只能支持 byte、short、char、int或者其对应的封装类以及 Enum 类型。在 Java 7中,String支持被加上了。3.eq
12、uals与=的区别。“=”比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】 equal用于比较两个对象的值是否相同【不是比地址】 【特别注意】Object类中的equals方法和“=”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“=不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。=比equal运行速度快,因为=只是比较引用.4. Object有哪些公用方法?Object是所有类的父类,任何类都默认继承Object。Object类到底实现了哪些方法
13、?(1)clone方法保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里讲参数改变,这是就需要在类中复写clone方法。(2)getClass方法final方法,获得运行时类型。(3)toString方法该方法用得比较多,一般子类都有覆盖。(4)finalize方法该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。(5)equals方法该方法是非常重要的一个方法。一般equals和=是
14、不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。(6)hashCode方法该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。一般必须满足obj1.equals(obj2)=true。可以推出obj1.hash- Code()=obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进
15、去。(7)wait方法wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。调用该方法后当前线程进入睡眠状态,直到以下事件发生。(7.1)其他线程调用了该对象的notify方法。(7.2)其他线程调用了该对象的notifyAll方法。(7.3)其他线程调用了interrupt中断该线程。(7.4)时间间隔到了。此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。(8)noti
16、fy方法该方法唤醒在该对象上等待的某个线程。(9)notifyAll方法该方法唤醒在该对象上等待的所有线程。5. Java的四种引用,强弱软虚,用到的场景。(1)强引用以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。(2)软引用(SoftReference)如果一个对象只具有软引用,那就类似于可有可无的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果
17、内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。(3)弱引用(WeakReference)如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优
18、先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。(4)虚引用(PhantomReference)虚引用顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃 圾回收器准备回收一
19、个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是 否已经加入了虚引用,来了解6. Hashcode的作用。Hash是散列的意思,就是把任意长度的输入,通过散列算法变换成固定长度的输出,该输出就是散列值。关于散列值,有以下几个关键结论:1、如果散列表中存在和散列原始输入K相等的记录,那么K必定在f(K)的存储位置上2、不同关键字经过散列算法变换后可能得到同一个散列地址,这种现象称为碰撞3、如果两个Hash值不同(前提是同一Hash算法),那么这两个Hash值对应的原始输入必定不同HashCode然后讲下什么是HashC
20、ode,总结几个关键点:1、HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的2、如果两个对象equals相等,那么这两个对象的HashCode一定也相同3、如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写4、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置HashCode有什么用回到最关键的问题,HashCode有什么用?不妨举个例子:1、假设内存中有0 1 2 3 4 5 6 7 8这8个位置,如果我有个字段叫做ID,那么我要把这个字段存放在以上8个
21、位置之一,如果不用HashCode而任意存放,那么当查找时就需要到8个位置中去挨个查找2、使用HashCode则效率会快很多,把ID的HashCode%8,然后把ID存放在取得余数的那个位置,然后每次查找该类的时候都可以通过ID的HashCode%8求余数直接找到存放的位置了3、如果ID的 HashCode%8算出来的位置上本身已经有数据了怎么办?这就取决于算法的实现了,比如ThreadLocal中的做法就是从算出来的位置向后查找第 一个为空的位置,放置数据;HashMap的做法就是通过链式结构连起来。反正,只要保证放的时候和取的时候的算法一致就行了。4、如果ID的 HashCode%8相等怎
22、么办(这种对应的是第三点说的链式结构的场景)?这时候就需要定义equals了。先通过HashCode%8来判断类在哪一 个位置,再通过equals来在这个位置上寻找需要的类。对比两个类的时候也差不多,先通过HashCode比较,假如HashCode相等再判断 equals。如果两个类的HashCode都不相同,那么这两个类必定是不同的。举个实际的例子Set。我们知道Set里面的元素是不可以重复的,那么如何做到?Set是根据equals()方法来判断两个元素是否相等的。比方 说Set里面已经有1000个元素了,那么第1001个元素进来的时候,最多可能调用1000次equals方法,如果equal
23、s方法写得复杂,对比的 东西特别多,那么效率会大大降低。使用HashCode就不一样了,比方说HashSet,底层是基于HashMap实现的,先通过HashCode取一 个模,这样一下子就固定到某个位置了,如果这个位置上没有元素,那么就可以肯定HashSet中必定没有和新添加的元素equals的元素,就可以直接存 放了,都不需要比较;如果这个位置上有元素了,逐一比较,比较的时候先比较HashCode,HashCode都不同接下去都不用比了,肯定不一 样,HashCode相等,再equals比较,没有相同的元素就存,有相同的元素就不存。如果原来的Set里面有相同的元素,只要HashCode的生
24、成方式定义得好(不重复),不管Set里面原来有多少元素,只需要执行一次的equals就可以了。这样一来,实际调用equals方法的次数大大降低, 提高了效率。7. ArrayList、LinkedList、Vector的区别。ArrayList,Vector底层是由数组实现,LinkedList底层是由双线链表实现,从底层的实现可以得出它们的性能问题,ArrayList,Vector插入速度相对较慢,查询速度相对较快,而LinkedList插入速度较快,而查询速度较慢。再者由于Vevtor使用了线程安全锁,所以ArrayList的运行效率高于Vector。8. String、StringBuf
25、fer与StringBuilder的区别。String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuff
26、er ,特别是字符串对象经常改变的情况下。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的StringBuilder并没有对方法进行加同步锁,所以是非线程安全的StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)。9. Map、Set、List、Queue、Stack的特点与用法。Collection 接口的接口 对象的集合 List 子接口 按进入先后有序保存 可重复 LinkedList 接口实现类 链表 插入删除 没有同步 线程不安全 ArrayList 接口实现类 数组 随机访问 没有同步
27、 线程不安全 Vector 接口实现类 数组 同步 线程安全 Stack Set 子接口 仅接收一次,并做内部排序 HashSet LinkedHashSet TreeSet对于 List ,关心的是顺序, 它保证维护元素特定的顺序(允许有相同元素),使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素。对于 Set ,只关心某元素是否属于 Set (不 允许有相同元素 ),而不关心它的顺序。Map 接口 键值对的集合 Hashtable 接口实现类 同步 线程安全 HashMap 接口实现类 没有同步 线程不安全
28、 LinkedHashMap WeakHashMap TreeMap IdentifyHashMap对于 Map ,最大的特点是键值映射,且为一一映射,键不能重复,值可以,所以是用键来索引值。 方法 put(Object key, Object value) 添加一个“值” ( 想要得东西 ) 和与“值”相关联的“键” (key) ( 使用它来查找 ) 。方法 get(Object key) 返回与给定“键”相关联的“值”。Map 同样对每个元素保存一份,但这是基于 键 的, Map 也有内置的排序,因而不关心元素添加的顺序。如果添加元素的顺序对你很重要,应该使用 LinkedHashSet
29、或者 LinkedHashMap.对于效率, Map 由于采用了哈希散列,查找元素时明显比 ArrayList 快。更为精炼的总结:Collection 是对象集合, Collection 有两个子接口 List 和 SetList 可以通过下标 (1,2.) 来取得值,值可以重复而 Set 只能通过游标来取值,并且值是不能重复的ArrayList , Vector , LinkedList 是 List 的实现类ArrayList 是线程不安全的, Vector 是线程安全的,这两个类底层都是由数组实现的LinkedList 是线程不安全的,底层是由链表实现的 Map 是键值对集合HashT
30、able 和 HashMap 是 Map 的实现类 HashTable 是线程安全的,不能存储 null 值 HashMap 不是线程安全的,可以存储 null 值 Stack类:继承自Vector,实现一个后进先出的栈。提供了几个基本方法,push、pop、peak、empty、search等。Queue接口:提供了几个基本方法,offer、poll、peek等。已知实现类有LinkedList、PriorityQueue等。10. HashMap和HashTable的区别。HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安
31、全性,同步(synchronization),以及速度。HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比Hash
32、Table的扩展性更好。另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。由于Hashtable是线程安全的也是synchronized
33、,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。HashMap不能保证随着时间的推移Map中的元素次序是不变的。11. HashMap和ConcurrentHashMap的区别,HashMap的底层源码。ConcurrentHashMap融合了hashtable和hashmap二者的优势。hashtable是做了同步的,hashmap未考虑同步。所以hashmap在单线程情况下效率较高。hashtable在的多线程情况下,同步操作能保证程序执行的正确性。但是hashtable每次同步执行的时候都要锁住整个结构。看
34、下图:图左侧清晰的标注出来,lock每次都要锁住整个结构。oncurrentHashMap正是为了解决这个问题而诞生的。ConcurrentHashMap锁的方式是稍微细粒度的(分段锁)。 ConcurrentHashMap将hash表分为16个桶(默认值),诸如get,put,remove等常用操作只锁当前需要用到的桶。从ConcurrentHashMap代码中可以看出,它引入了一个“分段锁”的概念,具体可以理解为把一个大的Map拆分成N个小的HashTable,根据key.hashCode()来决定把key放到哪个HashTable中。在ConcurrentHashMap中,就是把Map分
35、成了N个Segment,put和get的时候,都是现根据key.hashCode()算出放到哪个Segment中:试想,原来 只能一个线程进入,现在却能同时16个写线程进入(写线程才需要锁定,而读线程几乎不受限制,之后会提到),并发性的提升是显而易见的。更令人惊讶的是ConcurrentHashMap的读取并发,因为在读取的大多数时候都没有用到锁定,所以读取操作几乎是完全的并发操作,而写操作锁定的粒度又非常细,比起之前又更加快速(这一点在桶更多时表现得更明显些)。只有在求size等操作时才需要锁定整个表。而在迭代时,ConcurrentHashMap使用了不同于传统集合的快速失败迭代器的另一种
36、迭代方式,我们称为弱一致迭代器。在这种迭代方式中,当iterator被创建后集合再发生改变就不再是抛出 ConcurrentModificationException,取而代之的是在改变时new新的数据从而不影响原有的数 据,iterator完成后再将头指针替换为新的数据,这样iterator线程可以使用原来老的数据,而写线程也可以并发的完成改变,更重要的,这保证了多个线程并发执行的连续性和扩展性,是性能提升的关键。12. TreeMap、HashMap、LindedHashMap的区别。Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复。Hashmap 是
37、一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。Hashtable与 HashMap类似,它继承自Dictionary类,不同的是:它不允许记录的键或者值为空;它支持线程
38、的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认
39、是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。一般情况下,我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按
40、读取顺序来排列,像连接池中可以应用。13. Collection包结构,与Collections的区别。(1)java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。 Collection List LinkedList ArrayList Vector Stack Set (2)java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法,用于实现对各种集合的搜索、排序、线程
41、安全化等操作。此类不能实例化,就像一个工具类,服务于Java的Collection框架。14. try catch finally,try里有return,finally还执行么?(1)、不管有木有出现异常,finally块中代码都会执行;(2)、当try和catch中有return时,finally仍然会执行;(3)、在try语句中,try要把返回的结果放置到不同的局部变量当中,执行finaly之后,从中取出返回结果,因此,即使finaly中对变量进行了改变,但是不会影响返回结果,因为使用栈保存返回值,即使在finaly当中进行数值操作,但是影响不到之前保存下来的具体的值,所以return影
42、响不了基本类型的值,这里使用的栈保存返回值。而如果修改list,map,自定义类等引用类型时,在进入了finaly之前保存了引用的地址,所以在finaly中引用地址指向的内容改变了,影响了返回值。总结: 1.影响返回结果的前提是在 非 finally 语句块中有 return 且非基本类型 2.不影响返回结果 的前提是 非 finally 块中有return 且为基本类型究其本质 基本类型在栈中存储,返回的是真实的值,而引用类型返回的是其浅拷贝堆地址.所以才会改变。 return的若是对象,则先把对象的副本保存起来,也就是说保存的是指向对象的地址。若对原来的对象进行修改。对象的地址仍然不变,r
43、eturn的副本仍然是指向这个对象,所用finally中对对象的修改仍然有作用。而基本数据类型保存的是原原本本的数据,return保存副本后,在finally中修改都是修改原来的数据。副本中的数据还是不变,所以finally中修改对return无影响。(4)、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。15. Excption与Error包结构。OOM你遇到过哪些情况,SOF你遇到过哪些情况。(1). Throwable Throwable是 Java 语言中所有错误或异常的超类。 Throwable包含两个子类: Error 和
44、Exception 。它们通常用于指示发生了异常情况。 Throwable包含了其线程创建时线程执行堆栈的快照,它提供了printStackTrace()等接口用于获取堆栈跟踪数据等信息。(2). Exception Exception及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。(3). RuntimeException RuntimeException是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。 编译器不会检查RuntimeException异常。 例如,除数为零时,抛出ArithmeticException异常。RuntimeExcep
45、tion是ArithmeticException的超类。当代码发生除数为零的情况时,倘若既”没有通过throws声明抛出ArithmeticException异常”,也”没有通过trycatch处理该异常”,也能通过编译。这就是我们所说的”编译器不会检查RuntimeException异常”! 如果代码会产生RuntimeException异常,则需要通过修改代码进行避免。 例如,若会发生除数为零的情况,则需要通过代码避免该情况的发生!(4). Error 和Exception一样, Error也是Throwable的子类。 它用于指示合理的应用程序不应该试图捕获的严重问题,大多数这样的错误都
46、是异常条件。 和RuntimeException一样, 编译器也不会检查Error。Java将可抛出(Throwable)的结构分为三种类型: 被检查的异常(Checked Exception),运行时异常(RuntimeException)和错误(Error)。(01) 运行时异常 定义 : RuntimeException及其子类都被称为运行时异常。 特点 : Java编译器不会检查它。 也就是说,当程序中可能出现这类异常时,倘若既”没有通过throws声明抛出它”,也”没有用try-catch语句捕获它”,还是会编译通过。例如,除数为零时产生的ArithmeticException异常,数组越界时产生的IndexOutOfBoundsException异常,fail-fail机制产生的ConcurrentModificati