java基础面试题2

11. java的io方式

  1. java.io 包中的同步阻塞方式的io

  2. java.nio 包中的NIO框架,例如Channel、selector、Buffer等,可以提供同步非阻塞的调用方式

  3. NIO2 也叫AIO 异步非阻塞的方式,是基于事件和回调机制。可以理解为,操作直接返回,当后台处理操作完成之后,操作系统会通知相应的线程进行后续工作。

12.java文件的几种拷贝方式

  1. 普通的流操作拷贝,读取数据是,会先在内核态将数据从磁盘读取到内核缓存,然后切换到用户态,将数据从内核缓存读取到用户缓存。

  2. 基于NIO的transferTo,数据传输不需要用户态参与,减少了线程上下文切换的开销。

  3. java标准类库提供的File.copy方法,是基于用户态的读写或者拷贝。

  4. 拷贝等IO操作的优化:使用缓存机制减少IO次数;使用transferTo操作减少上下文切换和额外的IO开销;减少编解码比如编解码;对象的序列化和反序列化,例如用二进制传输,而不是文本传输。

  5. Buffer的几个要素:capcity为Buffer数组的大小,position为操作数据的起始位置,limit操作数据的容量上限。

  6. DirectBuffer,Java会对这样的缓存仅做本地IO操作,对于大量数据的IO密集操作,会有很大的性能优势,创建和销毁开销很大,建议长期使用。占用的不是堆内存,所以不会受到-Xmx之类的参数的影响。

  7. 跟踪和诊断DirectBuffer,激活NMT -XX:NativeMemoryTracking={summary|detail},性能会下降 5%-10%

13. 谈谈你对接口和抽象类的理解

  1. 利用接口可以达到Api和实现分离的目的,接口不能实例化,不能包含任何非常量成员,没有非静态方法的实现

  2. 抽象类是 abstract的抽象类,主要作用是代码重用

  3. java8中接口可以实现default method的默认方法

14.synchronized和ReentrantLock的区别

  1. 保证线程安全的办法:封装,变量私有化;不可变,声明为final

  2. 线程安全的几个基本特征:原子性, 同步或者原子机制;可见性,volatile;有序性,避免指令重排序。

  3. ReentenLock更加灵活,可以选择公平性,可以在指定情况设定wait和notify。需要显示的指定unlock。

  4. 在早期版本synchronized性能不高,但是在后来的版本对synchronized进行了优化,在并发量不是很高的情况下synchronized性能更好,在高并发情况下ReentenLock性能更好。

  5. 典型应用场景,ArrayBlockingQueen的take方法,在发现队列长度为0的时候,会进行wait操作,然后在enqueen方法中,在元素插入的时候会进行notify的唤醒操作。

15.synchronized底层的实现,以及锁的种类和升级

  1. synchronized底层是由MonitorEnter和MonitorExit实现的,Monitor依靠的是操作系统内部的互斥锁。

  2. 三种锁实现:偏向锁,轻量级锁,重量级锁。

  3. 偏向锁:没有竞争的时候,锁只由一个线程持有,JVM就会在对象头的Mark Word部分设置线程ID就是对应线程的偏向锁。

  4. 轻量级锁:如果某个线程试图获取某个锁的的对象的时候,发现这个锁已经是偏向锁了,如果获取锁成功,就会是轻量级锁。

  5. 重量级锁:如果某个线程试图获取某个锁的的对象的时候,发现这个锁已经是偏向锁了,如果获取锁失败,就会是重量级锁。

16.对java线程的理解

  1. 从操作系统的角度理解,线程是最小的任务调度单元,一个进程包含多个线程,每个线程都有自己独有的栈、寄存器、本地存储。

  2. 线程还分为内核线程和用户线程,现在的jdk基本上都是一对一的操作系统内核线程。

  3. 线程的实现方式,继承Thread类,实现Runnable接口,实现Callable接口。

17.java的死锁

  1. 什么是死锁?死锁是一种特定的程序状态,一般为多个线程彼此持有对方需要的锁,彼此还在等待获取对方会持有的锁。

  2. 定位死锁的方式。jstack打印线程信息。

  3. 死锁发生的原因:1.长期持有锁,使用完不释放;2.循环依赖。

  4. 如何避免死锁:1.尽量避免使用多个锁,并且只有需要的时候才持有;2.如果必须要使用多个锁,尽量设计好锁的获取顺序,可以将对象和锁的关系图形化展示出来;3.使用超时机制;4.通过不同的工具进行代码分析,查抄可能出现死锁的场景。

18 java并发包提供了哪些工具类

  1. 比synchronized更加高级的同步结构,包括countDownLantch等,可以实现更加丰富的多线程操控。

  2. 各种线程安全的容器例如concurrentHashMap、concurrentSkipListMap、CopyOnWriteArrayList等

  3. 各种并发队列ArrayBlockingQueue等,ArrayBlockingQueue等。

  4. 强大的Excutor框架,各种线程池。

19.java的并发容器

  1. 其实只有Concurrent*的类型才是并发容器,是基于lock-free,一般的queue队列则是基于锁实现的。

  2. concurrent包中的容器总共分三种:concurrent,没有相对较重的拷贝修改操作开销,但是遍历一致性较低,如果在迭代过程中,发生修改,则会继续遍历,size结果不能保证一定准确;copyOnWrite,每次获取的时候复制操作较重;Block,就是阻塞队列,用锁实现,相对来说并发性能较弱。

  3. Queue:
    ArrayBlockingQueue|有界队列,内部是final的数组
    –|--
    LinkedBlockingQueue|内部其实是有界队列,如果没有设置边界,边界会默认为int的最大值
    SynchronizedQueue|内部容量为0,每个删除操作都要等待插入,每个插入操作都要等待删除
    DelayedQueue,LinkedTransferQueue|都是无界队列,put永远不会等待

20.java的线程池

线程池名字 Queue 应用场景
newCachedThreadPool SynchronizedQueue 用来处理大量的短时间任务
newFixedThreadPool 无界工作队列
newSingleThreadExcutor 单个线程,无界工作队列 顺序执行任务
ScheduleExecutor 定时或者周期性的执行任务
newSingleStealingPool ForkJoinPool

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