java基础面试题1

1.谈谈你对java是解释执行这句话的理解

  1. 这句话不准确。java代码首先是通过javac命令编译成字节码,在运行时被解释器转为机器码。

  2. 但是常见的jvm,例如hotspot,都提供了JIT动态编译,能够在运行时将热点代码编译成机器码,这种情况下的代码就属于是编译执行,而不是解释执行。

  3. 还有一种新的编译方式,即AOT,直接将字节码编译为机器码

2.Exception 和 Error 有什么区别?

  1. 都继承了throwable接口,java中只有Throwable示例才可以被抛出或者是捕获。

  2. Error是指,在正常情况下不大可能出现的情况,会导致程序处于非正常的不可恢复状态。例如OutOfMemeoryError。

  3. Exception分为可检查异常和不可检查异常。可检查异常是在代码里必须显示的进行catch的异常,例如IOException等;不可检查异常就是所谓的运行时异常,例如nullPointException等。

  4. 需要注意的情况。不要捕获类似于Exception这样的通用异常,要对不同的异常进行特定处理;不要生吞异常,可以通过打日志等,展示异常。

  5. try catch 代码快不要包含过多代码,因为会产生额外的性能开销,并且会影响jvm对代码的优化。

3.谈谈你对final,finally,finallize的理解

  1. final可以用来修饰类,方法,变量。修饰类表示类不可被继承,修饰方法表示方法不可被重写,修饰变量表示变量是不可被修改的。

  2. finally 是用来保证重点代码一定会被执行的机制,例如jdbc关闭数据库链接,unlock等操作

  3. finallize 可以用来保证对象在被垃圾回收前完成特定资源的回收。

  4. 在java7中可以用try with resource 来省略掉 finally 关闭资源的代码

  5. 给对象声明final 只是表示对象的引用不会被修改,但是不能防止对象的内容被改变,例如list依然可以用add方法来给集合添加元素。一个有效的方法是,将集合对象声明为final,并且将集合中的每一属性也设置为private final,且不提供set方法。对于get方法可以用 copy on write的方式来实现。

  6. 在什么场景下finally 语句中的代码不会被执行,例如一段try catch finally 代码快中,在try环节抛出异常,进入到catch环节,并且在catch环节又抛出异常,那么finally 部分就不会被执行。或者在finally 代码快执行之前调用了 system.exit()方法。

4.强引用,软引用,弱引用,幻象引用的区别

  1. 强引用就是我们常见的最普通的引用,只要还有强引用指向的一个对象,垃圾回收器就不会回收这个对象

  2. 软引用,是一种相对强引用的弱化引用,还有当jvm内存不足的时候,也就是抛出OOM错误之前才会回收软引用对象,通常用作内存敏感的缓存

  3. 弱引用,不能使对象避免垃圾回收。当试图获取对象的时候,如果对象还在,就返回,如果对象不在,则重新进行实例化。同样可以用作缓存。

  4. 幻象引用,用来提供在finallize之后,做某种事情的机制。也可以用来监控对象的创建和销毁。

5.String、StringsBuffer、StringBuilder的区别

  1. String 是final类,

  2. StringBUffer本质是一个线程安全的字符序列,相关方法都加了synchronized关键字

  3. StringsBuilder是一个线程不安全的字符序列,相对于StringBuffer来说,只是在相关的方法上去掉了synchronized关键字。

  4. 在java8 之后,字符串的拼接操作,会被编译为StringBuilder操作。可以通过反编译手段看。

  5. 最初的String 是用 char数组实现的,后来改为 byte数组。原因是拉丁语的字符只占一个字符位,而char占用两个字符位置。这样做可以使数据更加紧凑。

6.动态代理是基于什么实现的?

  1. JDK的动态代理是基于接口的,需要对应的代理类有实现的接口,通过反射来实现。

  2. Cglib是通过创建代理类的子类来实现对代理类的扩展。

  3. 动态代理的应用:监控,日志,事务,RPC框架的序列化和反序列化,诊断,限流,安全策略。

7.int 和 Integer

  1. Integer会默认缓存 -128 到 127 之间的数据,通过Integer.valueOf(),会调用到缓存,并且可以通过参数 -XX:AutoBoxCacheMax=N 修改缓存的范围。 Boolean会缓存 true 和 false;Short 缓存范围也是 -128 到 127;Byte数值有限会全部缓存;Character 会缓存 ‘\u0000’到’\u007F’。

  2. Integer是一个final类。

  3. 原始的线程安全类型应该是用 AtomicInteger ,AtomicBoolean等。

8.对比Vector、ArrayList、LinkedList有何区别?

  1. Vector 内部以数组存储,随机访问性能较高,除了在尾部删除插入元素,性能会相对较差。方法实现全部加了synchronized 同步,是线程安全的。

  2. ArrayList内部以数组存储,随机访问性能较高,除了在尾部删除插入元素,性能会相对较差。不是线程安全的。

  3. LinkedList 继承了List 和Queen 但是存储形式是以Node的链表的形式存储的,并且是双向链表,每一个节点都保存有前一个和后一个节点的引用。同时也不是线程安全的。

9.TreeSet、HashSet、LinkedHashSet

  1. TreeSet支持自然顺序访问,

  2. HashSet 是利用哈希算法实现,如果哈希散列正常,增删改查等操作都可以达到常数时间

  3. LinkedHashSet 是一个双向链表。

10.Hashtable、HashMap、TreeMap

  1. HashTable扩展了Dictionary类,结构于HashMap明显不同,是线程安全的类,都加了synchronized

  2. HashMap通常就是放入、访问或者删除,而对顺序没有特别要求,HashMap 在这种情况下基本是最好的选择。

  3. LinkedHashMap 通常提供的是遍历顺序符合插入顺序,它的实现是维护一个双向链表。

  4. 对于 TreeMap,它的整体顺序是由键的顺序关系决定的,通过 Comparator 或 Comparable(自然顺序)来决定。

  5. HashMap的存储是一个数组,通过hash算法将不同的值放在不同的索引位置上,然后如果两个索引值相同,则在同一个索引下,搞一个链表。

  6. Java8在链表长度默认>64的时候,会改为红黑树的结构。

  7. HashMap的resize方法,有两个功能,创建初始表格和扩容。

你可能感兴趣的:(Java面试,Java面试)