引言:Java八股文是真滴该死啊,怎么会这么多要去记,真是太可恶了呜呜,可是更让人难过的是复习完了才发现,难怪当初大一一点不懂封装继承多态异常,自己早点认真去接触就好了呜呜,希望后面的小伙伴引以为鉴,(ps: 人类从历史里学习到的唯一教训就是人类无法从历史中学到任何教训(狗头保命))
1)Java语言特点:
1.面向对象编程(封装,继承,多态)
2.平台无关性,run any where,可移植性
3.可靠,安全
4.支持多编程
5编程方便
(Java不支持多继承,但是允许一个类有多个接口)
2)JDK、JVM、JRE三者关系
JDK = JRE + 编译器和工具(能够创建和编译程序)
JRE = JVM + Java类库 + Java命令 + 基础构建 (运行已编译的Java程序所需的所有内容的集合)
JVM:Java虚拟机(是运行所有Java程序的抽象计算机,是Java语言的运行环境)
3)字节码
-
字节码(.class文件)仅供JVM使用,由不同平台生成。
-
由十六进制组成(JVM由两个十六进制为一组,字节为单位)
-
Java中一般是用javac命令编译源代码为字节码文件
4)基本数据类型
数值型:(整型:byte short int long) (浮点型:float double)
字符型:char
布尔型: boolean
顺口溜:byte short int long float double char boolean
5)引用数据类型:
类:class
接口:interface
数组:[ ]
6)访问修饰符
public:对所有类可见
private:在同一类内可见
protected:对同一包内的类和所有子类可见
default:(即默认,什么也不写)
-
同一类可见:private --> 同一包可见:default --> 不同包但有子孙类:protected --> 其他包:public
7)break、continue、return的区别及作用
break:结束当前的循环体
continue:结束正在执行的循环 进入下一个循环条件
return:结束当前的方法 直接返回
8)final、finally、finalize
final:修使用的变量(无法被重写)、方法和类(无法被继承)
finally:用于异常处理 try/catch
finalize: java.lang.Object里的一个点,仅在对象回收时调用
9)static 关键字
1.通常是new的时候,调用方法,但是static可以让方法、对象未被创建时调用
2.static 会自己初始化变量(所以static不能访问非static 变量)
3.static 静态方法不能引用非静态资源(还为new,没有东西被引用)
4.但是静态方法里面可以引用非静态资源,因为静态方法内部已经自动初始化了,是有东西的欸嘿
5.非静态方法(已经被new过了,产生了东西)可以引用静态资源
10)方法重载、重写
重载:方法名不变,参数不同
重写:方法名相同,内容不同,适用于继承类、子类和父类
-
构造器不能被重写,但是可以被重载
-
重载无法根据返回值判断区分(因为调用时没有说明类型,只调用方法名,参数什么的也不知道)
11)对象相等判断
“==” 如果比较的是基本数据类型,比较的是值
如果比较的是两个对象的引用,判断是否指向相同一块内存区域
“equals” 判断两对象是否相等 具有 自反性、对称性、传递性、一致性
12)hashcode 获取哈希码
散列表(哈希表):存放“键值对”的数组,存在k1 != k2,f(k1) = f(k2)情况,冲突
-
如果两对象相等,那么hashcode一定相等
(对两个对象分别调用equals方法,返回true)
-
hashcode相等,但是两个对象不一定相等
(只能表明两个对象再散列表中存在于相同位置)
举例:首先我们要知道hashcode一般是变量取模的余数
假设你需要用数组存放1000个不同的数字,存放到第901个时,你需要把这个数字和前900个数字对比,显然,这是一件很消耗计算的,
那么如果我们用hash表来存储,表里有8个位置,哈希码分别是1到8,那么一个位置需要存放100多个,此时第901个数字假设取模后是1,那么它只需要和1对应的100多个数字对比,相比普通数组900个少多了,那么如果hash表有80个位置,那么每一组只需要对比10来个,更少了。而且实际上哈希表是很大的,所以此时用哈希表来存储高效多了。
重写equals方法不重写hashcode方法会导致hashcode值不同,但(equals 值是true)
所以二者需要同时重写,而且Java某些容器中是不允许出现有两个完全相同的对象。
13)String、StringBuilder和StringBuffer的区别
String 是线程安全且不可变的:private final char value[ ]
StringBuilder是非线程安全的:char[ ] value
StringBuffer线程安全(加了同步锁):char[ ] value
14)String为什么设计 “ 不可变 ”
1.便于实现 “ 字符串池 ” String pool,存有字符串变量
(每次声明一个string就无需创建一个string对象)
2.多线程安全:不可变不能别写,不会引发竞争
3.避免安全问题:网络连接和数据库连接中字符串常常是参数(need不可变)
4.加快字符处理速度:string不变,保证hashcode唯一性
(所以创建字符串时,hashcode自动缓存,无需再次计算)
15)字符型常量与字符串常量
字符型常量:单引号,相当于整型,2字节
字符串常量:双引号,代表一个地址值,多个字节 (char 是两字节)
16)String 和 new String
String a = "aaa" 只会在常量池中查找”aaa”字符串,若没有,会将”aaa”字符串放进常量池,再将其地址赋给a;若有,将找到的”aaa”字符串的地址赋给a。
String b = new String("aaa") 会将”aaa”字符串放入常量池,同时会在堆内存中开辟一片新空间存放新对象
17)包装类型
原始类型:byte short int long float double char boolean
包装类型:Byte Short Integer Long Float Double Character Boolean
包装类型值可以为null,基本数据类型不行,而数据库的查询结果会出现null,如果此时用的是基本数据类型会抛出异常,这里需要自动拆箱(包装类型转基本数据类型)。(自动装箱:基本数据类型转为对象)
Integer默认值是 null,int 默认值是 0;
Integer是对对象的引用,所以两个new生成的Integer变量永远不相等,内存地址不同
-
Integer 与 int变量相比,实际上是两个int变量对比,(前一个自动拆箱为int)
-
Integer 与 new Integer变量对比,false,因为一个存放的是常量池,一个新的内存地址
-
两个非 new Integer变量对比,如果变量值位于区间[-128,127],true(此区间会自动装箱,超出会new新地址),所以不在此区间,如128,false
基本数据类型比包装类型高效
18)泛型
泛型:只存在于编译阶段,而不存在于运行阶段。
类型擦除:大部分情况下都会使用Object替换到泛型的类型
Array用不了泛型,但可以用List取代
19)序列化
Java序列化:把Java对象转换为字节序列
因为Java对象保存于JVM堆内存,若JVM堆不存在,对象就会消失,而序列化可以在JVM 停机的时候保存对象!
作用:方便对内存中的对象进行持久化或者网络传输。
20)序列化实现方式:接口
Serializable接口:系统自动存储必要信息,只需实现接口,无需代码支持,性能略差、
Externalizable接口:程序员决定存储哪些信息,必须实现接口的两个办法:writeExternal()和readExternal()(否则所有变量值都会变成默认值),性能略好
21)serialVersionUID:用来表明类的不同版本间的兼容性
用于表明类的版本一致性(序列化和反序列化UID需要一致)
why? 若UID不指定不变,每次改变类中的内容,自动生成的UID都不一致,会报错
22)异常
Exception:程序员本身可以处理的异常,可以通过catch进行捕获,这样程序就可以接着进行
运行时异常:RuntimeException(非受检查异常)
NullPointException:空指针
NumberFormatException:字符串转换为数字
IndexOutOfBoundsException:数组越界
ClassCastException:类转换异常
ArrayStoreException:数据存储异常,操作数组时类型不一致
非运行时异常:受检查异常(调用者必须处理此异常)
IO 相关异常
ClassNotFoundException:
SQLException
23)throw 和 throws 的区别
throws:声明异常,用在方法声明上,可以抛出多个异常
调用此方法的方法内部需要包含可处理异常的代码(如catch),或者也用throw声明异常。
throw:抛出异常,用在方法内部,遇到异常抛出
ClassCastException:类转换异常,可用try-catch捕获或者throws声明
NoClassDefFoundError:Error类型异常,由JVM引起,不该被捕获
24)try-catch-finally(这里的catch可以省略)
try只适合处理运行时异常
try-catch适合处理运行时异常+普通异常(ps:普通异常必须有catch)
finally中不能放return,应该只在catch中放return,因为自上而下执行到catch的return时会停下去先执行finally,再回来执行catch的return语句;
25)IO流的种类
按照流的方向:输入流,输出流
按照实现的功能:节点流(如FileReader),处理流(如BufferReader)
按照处理数据的单位:字节流和字符流:inputStream、outputStream、Reader、Writer
26)字符流和字节流的区别:
读写:字节流按字节读取,适合所有类型文件的数据传输
字符流按字符读取,只适用于纯文本(速度比字节流快)
(只是读取文件,和文件内容无关,选择字节流;如果处理文件某一行数据,选字符流)
BIO:同步且阻塞,一个连接一个线程,一般适用于连接数目小且固定的结构。
NIO:同步并非阻塞,一个请求一个线程,一般适用于连接数目多且连接比较短的结构(轻操作)
AIO:异步并非操作,一个有效请求一个线程,一般适用于连接数目多且连接比较长的(重操作)
27)适配器模式和装饰器模式
适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作
装饰器模式:一种动态地往一个类中添加新的行为的设计模式。就功能而言,装饰器模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
今天结束了终于,当当明天继续,今年形势不好啊,要坚持,要加油┭┮﹏┭┮
冲冲冲!!!