1. 面向对象和面向过程
面向过程:以过程为核心,强调事件的流程,顺序。其性能比面向对象高。
面向对象:以对象为核心,强调事件的角色,主体。面向对象易维护,易复用,易扩展,具有封装、继承、多态的特点。
2. JVM,JRE,JDK三者的关系
- JVM是运行java字节码的虚拟机。
- JRE是java运行时的环境。
- JDK是java开发套件。
JDK包括编译器等开发工具和JRE运行环境,JRE包括JVM和java类库,java命令和一些基础构件。
3. 基本数据类型与引用数据类型
基本数据类型:4类8种
- 字节型 byte
- 短整型 short
- 整型 int
- 长整型 long
- 单精度浮点数 float
- 双精度浮点数 double
- 字符型 char
- 布尔类型 boolean
引用数据类型
- 字符串 string
- 数组 array
- 类 class
- 接口 interface
- Lamba
4. 重载与重写
重载
:指在同一个类中,存在一个以上的方法名相同,参数列表不同,与修饰符和返回值无关。
好处:只需要记住唯一一个方法名,就可以实现类似的多个功能。
重写
:在继承关系中,方法的名称一样,参数列表一样,返回值范围小于等于父类,抛出异常范围小于等于父类,访问修饰符范围大于等于父类。
被private修饰的父类方法不能被子类重写。
5. Java虚拟机的划分(5个部分)
- (1)方法栈(Method Stack):存放方法的局部变量。main方法入栈。
- 局部变量:方法的参数,或者方法内部的变量。
- 作用域:一旦超出作用域,立刻从栈中消失。
- (2)堆内存(Heap Memory) :存储对象或者数组。
- 堆中存放的数据,默认值。
- 整数:0
- 浮点数:0.0
- 字符:‘\u0000’
- 布尔:false;
- 引用类型:null
- (3)方法区(Method Area):存储.class相关信息,包含方法的信息。
- (4)本地方法栈(Native Method Stack):与操作系统相关。
- (5)寄存器(PC Register):与CPU相关。
6. 局部变量和成员变量
- (1) 定义位置不一样
局部变量:在方法的内部
成员变量:在方法的外部,类内部。 - (2)作用范围不一样
局部变量:在方法中才可以使用。
成员变量:整个类中都可以使用。 - (3)默认值不一样
局部变量:没有默认值,使用时必须手动赋值。
成员变量:未赋值,则用默认值。 - (4)内存位置不一样
局部变量:位于方法栈内存。
成员变量:位于堆内存中。 - (5)生命周期不一样
局部变量:随着方法栈而诞生,方法出栈即消失。
成员变量:随着对象创建而诞生,对象被垃圾回收即消失。
7. 面向对象的三大特征:封装,继承,多态
(一)封装:把一个对象的属性私有化,同时提供一些可以被外界访问属性的方法。
- 在java中的体现:1.方法就是一种封装。2.关键字private也是一种封装。
- (二)继承:
1.子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类无法访问,只能拥有。
2.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
3.子类可以用自己的方式实现父类的方法。 - (三)多态:实现多态的方式(1)继承,多个子类对同一方法的重写。(2)接口,实现接口并覆盖接口中同一方法。
8. 自动装箱和拆箱
- 装箱:将基本类型转换为包装类型。
- 拆箱:将包装类转换为基本数据类型。
9.String类,StringBuffer与StringBuilder的区别
1.String类中使用final关键字修饰符来保存字符串,所以String的值是不可变的
,这就导致每次操作String都会生成新的String对象。而StringBuffer和StringBuilder类的对象能够被多次修改
。
2. StringBuffer:可变字符序列,效率低,线程安全。
StringBuilder:可变字符序列,效率高,线程不安全。
总结:
- 操作少量数据用string
- 单线程操作字符串缓冲区下操作大量数据:StringBuilder
- 多线程操作字符串缓冲区下操作大量数据:StringBuffer
10.Static相关问题
类变量(静态变量)
:static修饰成员变量,该变量称为类变量。该类的每个对象共享同一个类变量的值。
类方法(静态方法)
:static修饰成员方法,该方法称为类方法。可通过类名直接调用。
注意:1.静态不能直接访问非静态
,因为在内存中先有静态的内容,后有非静态的内容。
2.静态方法中不能用this
:因为this代表当前对象,通过谁调用的方法,谁就是当前对象。
11. 继承关系中,父子类构造访问特点
*(一)子类构造方法中有一个默认隐含的super()
调用,所以一定是先调用父类构造,后执行子类构造。
*(二)子类构造通过super()
关键字调用父类的重载构造。
*(三)super的父类调用,必须是子类构造方法的第一句,不能一个子类构造调用多次super构造。
总结:子类必须调用父类构造方法,不写则赠送super(),写了则用写的指定的super调用,super只能有一个,还必须是第一个
。
12. 抽象类和接口的区别
(一)抽象类:抽象方法所在类,必须是抽象类才行。
抽象类的使用:
-
- 必须用一个子类来继承该抽象父类。
-
子类必须覆盖重写抽象父类中的所有抽象方法。
-
- 创建子类对象进行使用。
(二) 接口:一种公共规范标准
接口中的内容:常量,抽象方法,默认方法,静态方法,私有方法。
接口的使用:
- 创建子类对象进行使用。
-
- 必须有一个实现类实现该接口。
-
接口的实现类必须覆盖重写(实现接口中所有抽象方法。)
(若实现类没有覆盖重写接口中所有的抽象方法,那么这个实现类自己必须是抽象类)
-
- 创建实现类对象进行使用。
13. 类与接口
类与类之间是单继承的
,直接父类只有一个。- 类与接口之间是多实现的,
一个类可以实现多个接口。
接口与接口之间是多继承的.
14. Collection接口(单列集合)与Map(双列集合)
15.什么是构造方法?
- 名称和类名相同
- 没有返回值,不能用void声明构造函数
- 生成类的对象时自动执行,无需调用。
16.两个对象相等于指向两个对象的引用相等的区别?
两个对象相等:比的是内存中存放的内容是否相等。
引用相等:比较的是他们指向的内存地址是否相等。
17. 调用子类构造方法前会先调用父类中的无参构造目的?
帮助子类完成初始化工作
18. == 与 equals区分
==:判断两个对象的地址是否相等(基本数据类型 :比较的是值,引用数据类型比较的是内存地址)
equals:判断两个对象是否相等。
- 情况一:类没有覆盖equals()方法,则通过equals()比较该类的两个对象时,等价于==
- 情况二:类覆盖了equals()方法。若内容相等,则返回true.
19. hashCode()的作用?
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。
20. 为什么重写equals时必须重写hashCode方法?
- 如果两个对象相等,则hashcode一定也是相同的
- 两个对象相等,对两个对象分别调用equals方法都返回true
- 两个对象有相同的hashcode值,他们也不一定是相等的。
- 因此,equals方法被重写过,则hashcode方法也必须被重写。
- hashcode()默认行为是对堆上的对象产生独特值。如果没有重写hashcode(),则该class的两个对象无论如何都不会相等。
21. java中为什么只有值传递?
- 按值调用:表示方法接收的是调用者提供的值
- 按引用调用:表示方法接收的是调用者提供的变量地址。
Java语言采用的是按值调用。
方法得到的是参数的一个拷贝值,就是说,方法不能修改传递给它的任何参数变量的内容。
22. 进程,线程,程序之间的关系?
线程
与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
进程
是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
程序
是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
23. 关于final关键字总结
- final变量:基本类型变量,初始化之后不能修改,引用型变量在初始化之后便不能指向另外一个对象。
- final类:被final修饰后,则该类不能被继承。final类中所有的成员方法都会被隐式指定为final方法。
- final方法:使用final方法的原因1.以防任何继承类修改它的涵义。2.效率。
24. Java中异常处理
Error(错误)
:是程序无法处理的错误,表示运行应用程序中较严重问题。
Exception(异常)
:是程序本身可以处理的异常。
Throwable类常用方法
- public string getMessage():返回异常发生时的简要描述
- public string toString():返回异常发生时的详细信息
- public string getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同
- public void printStackTrace():在控制台上打印Throwable对象封装的异常信息
异常处理总结
- try 块: 用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
- catch 块: 用于处理try捕获到的异常。
- finally 块: 无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return 语句时,finally语句块将在方法返回之前被执行。
25. Java序列化中如果有些字段不想进行序列化怎么办?
序列化:将java对象转换成字节流的过程。
反序列化:将字节流转换成Java对象的过程。
当 Java 对象需要在网络上传输 或者 持久化存储到文件中时,就需要对 Java 对象进行序列化处理。
序列化的实现:类实现Serializable接口。
注意:
- 某个类可以被序列化,则其子类也可以被序列化。
- 声明为static和transient的成员变量不能被序列化。
- 反序列化读取序列化对象的顺序要保持一致。
以上:对于不想序列化的字段可以使用transient关键字修饰。
transient关键字的作用:阻止实例中那些用此关键字修饰的变量序列化;当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。
transient只能修饰变量,不能修饰类和方法。
26.获取键盘输入的两种常用方法
(1)通过Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
(2)通过BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();
27. 线程有哪些状态?
28. 深拷贝和浅拷贝
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝/,创建一个新的对象,并复制其内容。
29. BIO,NIO,AIO有什么区别?
- BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
- NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。
对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发。
- AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,
它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作
。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。
30. Java中的IO流
- 按照流的流向分,可以分为输入流和输出流;
- 按照操作单元划分,可以划分为字节流和字符流;
- 按照流的角色划分为节点流和处理流。
既然有了字节流,为什么还要有字符流?
问题本质想问:不管是文件读写还是网络发送接收,信息的最小存储单元都是字节,那为什么 I/O 流操作要分为字节流操作和字符流操作呢?
回答:字符流是由 Java 虚拟机将字节转换得到的,问题就出在这个过程还算是非常耗时,并且,如果我们不知道编码类型就很容易出现乱码问题。所以, I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。