一、Java 中实现多态的机制是什么?
靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法
在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。
二、Java 中异常分为哪些种类
1)按照异常需要处理的时机分为编译时异常也叫 CheckedException 和运行时异常也叫 RuntimeException。只有 java 语言提供了 Checked 异常,Java 认为 Checked 异常都是可以被处理的异 常,所以 Java 程序必须显式处理 Checked 异常。如果程序没有处理 Checked 异常,该程序在编译时 就会发生错误无法编译。这体现了 Java 的设计哲学:没有完善错误处理的代码根本没有机会被执行。
对 Checked 异常处理方法有两种:
1 当前方法知道如何处理该异常,则用 try...catch 块来处理该异常。
2 当前方法不知道如何处理,则在定义该方法是声明抛出该异常。 运行时异常只有当代码在运行时才发行的异常,编译时不需要 try catch。Runtime 如除数是 0 和数组下标 越界等,其产生频繁,处理麻烦,若显示申明或者捕获将会对程序的可读性和运行效率影响很大。所以由
系统自动检测并将它们交给缺省的异常处理程序。当然如果你有处理要求也可以显示捕获它们。
三、 Java 的 IO
1、Java 中有几种类型的流 字节流和字符流。字节流继承于 InputStream 和 OutputStream,字符流继承于 InputStreamReader 和 OutputStreamWriter。 2、字节流如何转为字符流 字节输入流转字符输入流通过 InputStreamReader 实现,该类的构造函数可以传入 InputStream 对象。 字节输出流转字符输出流通过 OutputStreamWriter 实现,该类的构造函数可以传入 OutputStream 对象。
3、如何将一个 java 对象序列化到文件里 在 java 中能够被序列化的类必须先实现 Serializable 接口,该接口没有任何抽象方法只是起到一个标记作 用。
四、Java 的多线程
1、多线程的两种创建方式 java.lang.Thread 类的实例就是一个线程但是它需要调用 java.lang.Runnable 接口来执行,由于线程类本身 就是调用的 Runnable 接口所以你可以继承 java.lang.Thread 类或者直接实现 Runnable 接口来重写 run()方 法实现线程。
2、在 java 中 wait 和 sleep 方法的不同? 最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁。wait 通常被用于线程间交互,sleep 通常被 用于暂停执行。
3、synchronized 和 volatile 关键字的作用 一旦一个共享变量(类的成员变量、类的静态成员变量)被 volatile 修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线 程来说是立即可见的。
2)禁止进行指令重排序。 volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
1.volatile 仅能使用在变量级别; synchronized 则可以使用在变量、方法、和类级别的
2.volatile 仅能实现变量的修改可见性,并不能保证原子性; synchronized 则可以保证变量的修改可见性和原子性
3.volatile 不会造成线程的阻塞; synchronized 可能会造成线程的阻塞。 4.volatile 标记的变量不会被编译器优化; synchronized 标记的变量可以被编译器优
五、什么是线程池,如何使用?
1.线程池就是事先将多个线程对象放到一个容器中,当使用的时候就不用 new 线程而是直接去池中 拿线程即可,节省了开辟子线程的时间,提高的代码执行效率。 在 JDK 的 java.util.concurrent.Executors 中提供了生成多种线程池的静态方法。
然后调用他们的 execute 方法即可。
2.请叙述一下您对线程池的理解?
合理利用线程池能够带来三个好处。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统
的稳定性,使用线程池可以进行统一的分配,调优和监控。
3.线程池的启动策略?
1、线程池刚创建时,里面没有一个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务, 线程池也不会马上执行它们。
2、当调用 execute() 方法添加一个任务时,线程池会做如下判断:
a. 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;
b. 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列。
c. 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这 个任务;
d. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会抛出异常,告 诉调用者“我不能再接受任务了”。
3、当一个线程完成任务时,它会从队列中取下一个任务来执行。
4、当一个线程无事可做,超过一定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的大小。
六、Java 中的反射
1、说说你对 Java 中反射的理解 Java 中 的 反 射 首 先 是 能 够 获 取 到 Java 中 要 反 射 类 的 字 节 码 , 获 取 字 节 码 有 三 种 方 法 , 1.Class.forName(className)
2.类名.class 3.this.getClass()。然后将字节码中的方法,变量,构造函数等映射 成相应的 Method、Filed、Constructor 等类,这些类提供了丰富的方法可以被我们所使用。
七、Java 中的设计模式
1.你所知道的设计模式有哪些
Java 中一般认为有 23 种设计模式,总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、
备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
八、Java 的类加载器
1、Java 的类加载器的种类都有哪些?
1、根类加载器(Bootstrap) --C++写的 ,看不到源码
2、扩展类加载器(Extension) --加载位置 :jre\lib\ext 中
3、系统(应用)类加载器(System\App) --加载位置 :classpath 中
4、自定义加载器(必须继承 ClassLoader)
2、类什么时候被初始化?
1)创建类的实例,也就是 new 一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName("com.lyj.load"))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM 启动时标明的启动类,即文件名和类名相同的那个类 只有这 6 中情况才会导致类的类的初始化。
类的初始化步骤:
1)如果这个类还没有被加载和链接,那先进行加载和链接
2)假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一 次),那就初始化直接的父类(不适用于接口) 3)加入类中存在初始化语句(如 static 变量和 static 块),那就依次执行这些初始化语句