Java面试必知必会

Java面试必知必会反射机制:在运行时通过反射机制获取对象实例的相关信息,获得实例对象的方式有三种一种是直接类的class对象,一种是Class.forName.g

反射机制:在运行时通过反射机制获取对象实例的相关信息,获得实例对象的方式有三种一种是直接类的class对象,一种是Class.forName()方法,另一种是通过类加载器加载,Thread.currentThread().getContextClassLoader().loadClass(),其中forName会执行类的初始化,其他两种不会。获得类的class对象之后,可以获取类中的类、参数、方法、父子类型信息,通过class.Instance()获得类对象。

java注解:元注解有指定运行时机(源码期、编译期、运行期),指定使用范围(类、属性、方法)等;结合反射机制获取类的Class对象,并获得相应的注解,再做处理,从而实现增强或额外处理的功能。

java代理模式的实现方式:有静态代理;JDK动态代理通过与被代理类实现相同接口的方式替换被代理类,代理类需要实现InvocationHandler接口;CGlib动态代理,被代理类不需要实现接口,使用继承的方式替换代理类;javassist 动态代理,动态生成class文件;ASM通过动态修改二进制码的方式生成class文件。动态代理都是新生成代理对象来实现的,而不是通过反射。

JAVA IO模型:应用程序的io操作分为,连接发起和实际数据获取两部分,针对这两部分的操作,划分为同步阻塞IO 一般的Socket文件读取等IO模型,在连接发起和数据获取都是同步阻塞的;另一种是NIO,连接发起可以认为是非阻塞的,IO操作是同步的,面向缓冲区的,借助操作系统的多路复用IO模型,根据注册响应操作;最后就是全异步非阻塞的,应用程序发起IO请求,操作系统帮忙将数据从内核态拷贝到用户态并通知用户态已完成。常见Netty和redis使用的reactor线程模型,单线程负责连接,线程池负责数据处理。Netty中一个channel会被绑定在一个EventLoop上,EventLoop会分配一个具体的Thread负责Channel的处理(保证不跨线程)。

Netty使用reactor线程模型(可理解为主从reactor模型,EventLoopGroup负责连接创建分配Channel,每个EventLoop的线程池负责分配子线程监听并处理具体数据处理)

Redis通过IO多路复用管理客户端的连接监听,通过队列方式处理事务,文件事件派发器由单线程处理。

Java集合:List,ArrayList,LinkedList, ArrayList 有声明随机查询,建议使用for i 的查询,LinkedList双向链表,建议使用foreach遍历;Map,HashMap,TreeMap,ConcurrentHashMap,线程安全,初始大小为16,扩容一般为2的n次方,Hashtable初始大小是11;除了使用Concurrent包外,还可以通过Collections.的内部类初始化为线程安全的集合。Arrays.toList() 返回的是Arrays内部类类型的AbstractArrayList,内部类没有实现对应的方法,会在调用add,remove等方法时报错。

ThreadLocal: Thread的静态内部类,每个线程保存数据,ThreadLocal的内部结构是类似hashmap的弱应用,key是ThreadLocal的弱引用类型,线程私有且需要传递的可以使用ThreadLocal作为传递载体。ThreadLocal能保证线程安全的关键在于,Thread类中的定义了ThreadLocal.ThreadLocalMap threadLocals,可以将其理解为一个特有的 Map 类型,而在 Thread 类中声明了一个 ThreadLocalMap 类型的 threadLocals 属性。针对每个 Thread 对象,也就是每个线程来说都包含了一个 ThreadLocalMap 对象,即每个线程都有一个属于自己的内存数据库,而数据库中存储的就是我们用 ThreadLocal 修饰的对象。

锁机制:java中保持线程安全的方式,volatile关键字,保证工作内存和主内存的可见性,防止重排序,对volatitle的写 hapend-before对它的读;synchronized 静态代码块锁class对象,方法区锁当前实例对象,代码块锁指定对象,加锁操作是在JVM层面对对应的对象的Markword区增加是否持有锁标记,通过monitorenter和monitorexit 加锁和解锁,而对于加锁区可以防止并发而不能防止加锁区的重排序,单重排序不会影响单线程的逻辑,所以对于synchronized加锁之后是线程安全的,synchronized的加锁顺序为偏向锁(获取锁的第一次CAS)-轻量级锁(若有锁竞争则自旋CAS)-重量级锁(加重量级锁);ReentrantLock 借助AQS 从JDK维度实现了公平非公平锁,可重入锁;将线程运行过程中的寄存区、指令等抽象为工作内存,将内存视为主内存,volatile解决了工作线程可见性问题,synchronized是通过对共享区加锁,AQS是将竞争者以队列的方式排序来防止竞争(内部也使用了volatile).

线程池:线程有实现继承Thread,实现Runnable接口或Callable接口 三种方式,想获取结果则使用Callable实现call方法。线程池Executor框架 主要有ThreaPoolExecutor(固定线程池大小,单一线程,和CachedThreadPool工作线程为0,使用SysnchronousQueue队列线程作为工作线程)和ScheduledThreadPoolExeccutor两种,注意设定核心线程数,最大线程数,任务队列,拒绝策略,等数据,防止内存泄漏。

线程&进程:进程间通讯的目的是数据传输、事件通知、进程控制,进程间通信方式有共享内存区,管道,FIFO,消息队列,过程调用(主要是RPC),线程间通讯因为本身共享进程内存空间,所以常用的方式是通过信号和wait,锁等方式进行同步。线程状态:新建、就绪、执行、阻塞、死亡。

JVM:java应用程序流程分为 源码java文件-编译.class文件-类加载器将class文件读入内存放在方法区中(线程共享)–运行过程中的对象实例存放在堆中(线程共享)–运行过程中的程序计数器、虚拟机栈、本地方法区以线程私有的方式存放在运行数据区。垃圾回收算法主要有标记清理和标记整理,将堆分代划分,年轻代一般使用标记清理,老年代一般使用标记整理,而根据与业务线程并行或stop-the-world执行标记清理,也划分出了常规的CMS和G1的收集算法,CMS耗CPU,会有垃圾碎片,G1是吧内存提前划分小块,以块单位的方式并行执行分析,相对CMS垃圾碎片更少。

作为GCroot的对象:虚拟机栈中引用的对象,本地方法栈中引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/4282.html

(0)
编程小号编程小号
上一篇 2022-12-26
下一篇 2023-08-05

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注