一、Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?
1、定义:
Java在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取信息和动态调用对象方法的功能称为Java的反射机制。
实现:运行时拿到Class对象,生成Java对象。
2、反射的优缺点:
a、优点:
反射赋予了jvm动态编译的能力(运行时改变程序的行为),提高了Java程序的灵活性和扩展性,降低了代码的耦合性,减少了硬编码。
b、缺点:
1、降低了程序的可读性;
2、降低了程序的效率,主要原因是:加载字节码,invoke方法对参数的装箱、拆箱操作,检查方法和参数的合法性。
3、如何理解反射:
反射增加了代码的灵活性和扩展性,使JVM有了动态编译的能力,减少了程序编译的次数,但是缺点是增加了程序的性能损耗,使程序运行起来更慢了;破坏了程序的封装性,让程序的可读性变差了。反射主要的作用是增强程序的抽象性,使我们的程序适应更多的场景,因此反射更多的是使用在了各种框架中,框架的作用就是抽象各种业务场景的共同点,解决各种业务场景的共同问题,这和反射的作用不谋而合。
二、谈谈对 Java 注解的理解,解决了什么问题?
注解本身的作用是标记,真正起作用的是注解解释类,如果没有解释类,那注解和注释的区别不大。注解和解释类的关系是靠反射来实现的,所以注解一般都和反射一起使用。
解决的问题:增加了代码的可读性,使代码变的简洁、易于阅读,降低了代码的耦合性,使代码更灵活,扩展性更高。
三、内部类了解吗?匿名内部类了解吗?
内部类分类:成员内部类、局部内部类、匿名内部类、静态内部类
1、成员内部类:
作为类成员的内部类,特点:可以访问外部类的所有属性和方法;依附于外部类的存在而存在(必须先创建外部类的对象,然后才能创建内部类的对象);拥有自己的访问权限(public、protected、private、默认权限,private访问权限就只能在当前的类中访问到);不能有任何static的属性和方法。作用:实现多继承;实现代码封装,隐藏没必要对外暴露的方法和属性。
2、局部内部类:
只存在于局部的内部类(代码块或者方法里),特点:作用域仅限代码块或者方法。作用:封装。
3、匿名内部类:
没有名字的内部类,特点:没有访问权限修饰符;必须继承抽象类或者实现接口;不能有任何static的属性和方法;没有构造方法,因为没有类名;可以访问外部变量,但是变量必须声明为final,因为变量生命周期和匿名内部类生命周期不一样,所以,匿名内部类会在堆上生成变量的一个备份来使用。作用:增强代码的抽象能力,提高代码的灵活性,最常用到的就是创建线程时的Runnable类了。
4、静态内部类:
用static修饰的内部类,特点:创建对象不依赖于外部类创建对象;不能访问外部类的非static属性和方法,自己可以有static的属性和方法。作用:最常用的就是实现单例了,不仅是延迟加载,而且还是线程安全的。
内存泄露问题:当内部类被其他类的引用时,当内部类的引用被外部类以外的其他类引用时,就会即使外部类没有被引用也无法被GC回收的情况,造成内存泄露。
四、BIO和NIO区别,4核cpu,100个http连接,用BIO和NIO分别需要多少个线程
BIO:同步阻塞式IO,一个请求对应一个处理线程,一般实现是while死循环不断接收客户端请求,接收到请求之后,直接新开一个线程处理。缺点:浪费线程资源,不适用于高并发场景;优点:模式简单,易于实现和维护。
NIO:同步非阻塞IO,关键字是:selector、channel、buffer。selector是多路复用的一种实现,在一个线程中开辟多个通道(channel),然后线程进行轮询选择准备就绪的通道进行读写操作,channel是通道的意思,区别于流,channel是双向的,可以异步读写数据,channel读写的载体是缓存(buffer),buffer是为了解决一次IO请求中需要等待数据流而线程阻塞的问题,线程在流到达缓存区之前是不必阻塞的,等到读写操作就绪之后,线程再来从缓存区批量读取数据即可。
4核,100个连接,BIO需要创建100个线程去处理,也就是100个线程去抢占4个CPU,平均要发生25次上下文切换;而NIO只需要5个线程就能处理(一个selector管理线程,4个处理线程),基本上不会发生CPU上下文切换。
所以NIO的优点:1、减少了线程的开销,2:面向缓存,避免了线程同步等待数据IO,3:减少了多个线程频繁上下文切换的开销。