面试题

  1. java中的引用有几种?对于强引用,我们平时在编写代码时经常会用到。而对于其他三种类型的引用,使用得最多的就是软引用和弱引用,这2种既有相似之处又有区别。它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。针对上面的特性,软引用适合用来进行缓存,当内存不够时能让JVM回收内存,弱引用能用来在回调函数中防止内存泄露。因为回调函数往往是匿名内部类,隐式保存有对外部类的引用,所以如果回调函数是在另一个线程里面被回调,而这时如果需要回收外部类,那么就会内存泄露,因为匿名内部类保存有对外部类的强引用。
  2. Java中的threadlocal是怎么用的? threadlocal中的内部实现是怎么样的? 哪种引用?
  3. ,那就是ThreadLocal并不是用来并发控制访问一个共同对象,而是为了给每个线程分配一个只属于该线程的对象(这么粗暴的解释可能还不太准确),更准确的说是为了实现线程间的数据隔离。

    get方

    代码很容易理解,首先我们通过Thread.currentThread得到当前线程,然后获取当前线程的threadLocals变量,这个变量就是ThreadLocalMap类型的。然后根据当前的ThreadLocal实例作为key,获取到Entry对象。

    set方法

    代码同样很容易理解。同样根据Thread.currentThread得到当前线程,如果当前线程存在threadLocals这个变量不为空,那么根据当前的ThreadLocal实例作为key寻找在map中位置,然后用新的value值来替换旧值。

    在ThreadLocal这个类中比较引人注目的应该是ThreadLocal->ThreadLocalMap->Entry这个类。这个类继承自WeakReference。关于弱引用的知识,以后我会抽时间写篇文章来介绍下。

  4. java中的"final"关键字在多线程的语义中,有什么含义
  5. 说说nio的架构,为什么变快了,说说select和buffer都是怎么用的?
    1. 在操作系统中的实现原理? 如果都是cpu轮训话,会不会对cpu影响太大?
    2. 应用到了linux中的什么特性?
  6. nio中, 如果不显式的调用 system.gc() 那会出现什么问题?
  7. jvm的垃圾回收分为哪些种类?每一种都是怎么去实现的?讲述一下G1的回收策略?
    1. 串行垃圾回收器(Serial Garbage Collector) -XX:+UseSerialGC
    2. 并行垃圾回收器(Parallel Garbage Collector) -XX:+UseParallelGC
    3. 并发标记扫描垃圾回收器(CMS Garbage Collector) XX:+USeParNewGC
    4. G1垃圾回收器(G1 Garbage Collector) –XX:+UseG1GC
  8. jvm中的参数分为哪些种类,都是做什么的?jvm的监控怎么做?实际项目上线以后的监控怎么做?Xms :设置Java堆栈的初始化大小
    -Xmx :设置最大的java堆大小
    -Xmn :设置Young区大小
    -Xss :设置java线程堆栈大小
    -XX:PermSize and MaxPermSize :设置持久带的大小
    -XX:NewRatio :设置年轻代和老年代的比值
    -XX:NewSize :设置年轻代的大小
    -XX:SurvivorRation=n :设置年轻代中E去与俩个S去的比值-XX:+PrintGCDetails :记录GC运行时的详细数据信息,包括新生占用的内存大小及消耗时间
    -XX:-PrintGCTimeStamps :打印收集的时间戳
    -XX:+UseParallelGC :使用并行垃圾收集器
    -XX:-UseConcMarkSweepGC :使用并发标志扫描收集器
    -XX:-UseSerialGC :使用串行垃圾收集器
    -Xloggc:filename :设置GC记录的文件
    -XX:+UseGCLogFileRotation :启用GC日志文件的自动转储
    -XX:GCLogFileSize=1M :控制GC日志文件的大小
  9. JVM中,如果把堆内存参数配置的超过了本地内存,会怎么样?
  10. JVM中的内存结构分为哪些方面?
    1. 栈空间是怎么样的?每个线程只有一个栈吗?
    2. 栈空间的内部结构是怎么样的?
    3. 线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。
  11. 堆内存为什么要设计为分代?虚拟机的堆内存共划分为三个代:年轻代(Young Generation)年老代(Old Generation)持久代(PermanentGeneration)
    其中持久代主要存放的是Java类的类信息,与垃圾收集器要收集的Java对象关系不大。所以,年轻代和年老代的划分才是对垃圾收集影响比较大的。
  12. ArrayList的实现原理,如何测试ArrayList动态分配内存中带来的内存、cpu变化
  13. ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

     

        ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

     

        ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

  14. ArrayList是不是线程安全的? 怎么实现线程安全的?
  15. synchronizedlock有什么区别?如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断
    如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情;synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中;在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
  16. volatile的作用,如果volatile修饰的对象经过了大量的写,会出现什么问题?
  17. 一个变量经 volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。 
  18. String的+和StringBuilder有什么区别? 放在循环中有什么问题?String:查看源码得知,String类的声明是:public final,所以可以很清楚的知道,fianl的话是改变不了的,所以,如果我们用String来操作字符串的时候,一旦我们字符串的值改变,就会在内存创建多一个空间来保存新的字符串,可想而知,一旦遇到复杂的操作,用String是多么低效率的事啊!StringBuffer和StringBuilder都集成了AbstractStringBuilder,而StringBuffer大部分方法都是synchronized,也就是线程安全的,而StringBuilder就没有,所以,我们查看API可以知道,StringBuilder可以操作StringBuffer,但是StringBuffer不可以操作StringBuilder,这也是线程的原因;
  19. 日志打印的过程中,使用String的+操作和使用占位符输出,对性能上有什么区别
  20. SimpleDateFormat如果是一个全局变量的话,有什么问题?多线程问题
  21. HashMap的操作中,直接使用keySet()遍历有什么问题?
  22. 原因是keyset是通过entryset得到的,然后通过迭代keyset得到键值对,达到遍历的效果,所以会慢一点,但是绝对不是效率低下。所以当HashMap容量比较小的情况下,完全可以使用keyset的方式。
posted @ 2017-05-16 12:31  那家那人那小伙  阅读(459)  评论(0编辑  收藏  举报