面向对象
啥是面向对象?
将现实的事物抽象出来,把现实生活的事物以及关系,抽象成类,通过继承,实现,组合的方式把万事万物都给容纳了。实现了对现实世界的抽象和数学建模。
面向对象三大特性:
1、封装
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
2、继承
提高代码复用性;继承是多态的前提。
3、多态
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
多态
简单来说,编译时和运行时类型不一致的情况,同一操作作用于不同的对象,可以产生不同的效果。这就是多态。
多态表现为运行时多态( 重 写 )、编译时多态 ( 重 载 )
Mysql
left 、right 、inner join
- left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录
- right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录
- inner join(等值连接) 只返回两个表中联结字段相等的行
- Java数据库连接库JDBC用到桥连模式
Sql语句执行顺序
- FROM 子句;ON 子句;OUTER(join)子句; 组装来自不同数据源的数据
- WHERE 子句 基于指定的条件对记录进行筛选
- GROUP BY 子句 将数据划分为多个分组
- 使用聚合函数进行计算
- 使用HAVING子句筛选分组
- 计算所有的表达式
- SELECT
- DISTINCT
- 使用ORDER BY对结果集进行排序
- TOP
java
修饰符、变量
- 变量不能用
default
修饰 局部变量
被赋值时创建- final修饰的成员变量为基本数据类型时,在赋值之后无法改变。当final修饰的成员变量为引用数据类型时,在赋值后其指向地址无法改变,但是对象内容还是可以改变的。
对象
-
数组是一个对象,不同类型的数组具有不同的类
-
Java中所有的类都直接或间接继承自ObjeCct,无论是否明确的指明,无论其是否是抽象类。
-
每个类都使用Object类作为超类,Class类是Object的派生类
-
Threadlocalmap使用开放定址法解决hash冲突,hashmap使用链地址法解决hash冲突
-
面向对象方法的多态性是指:针对一消息,不同的对象可以以适合自身的方式加以响应
int和Integer:
构造器
- 由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。
- java继承中对构造函数是不继承的,只是显式或者隐式调用,构造器中可以调用别的方法。
- 子类即使没有显示构造函数,也会有个无参数的默认构造函数,仍然会调用父类的构造函数。无参构造的第一行依然默认是super()。
- **super()和this()**都只能位于构造器的第一行,而且不能同时使用,这是因为会造成初始化两次
- this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块**(static里面不能使用非static类型的)。**
下题的执行结果是?YXYZ 初始化过程:
按顺序 初始化 父类 的 静态成员变量、静态代码块 ;
按顺序 初始化 子类 的 静态成员变量、静态代码块 ;
按顺序 初始化 父类 的 代码块{}、普通成员变量 -> 再执行父类的构造方法;
按顺序 初始化 子类 的 代码块{}、普通成员变量 -> 再执行父类的构造方法
构造方法都是最后执行。
class X{
Y y=new Y();
public X(){
System.out.print("X");
}
}
class Y{
public Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();
public Z(){
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
接口和抽象
- 接口中方法的默认修饰符是public abstract
- 属性默认修饰符 public static final 而且必须初始化
抽象类可以有构造方法,接口中不能有构造方法
- JDK8中,接口中的方法可以被default和static修饰,但是!!!被修饰的方法必须有方法体
- 抽象类中可以有普通成员变量,接口中没有普通成员变量
- 实现接口的类,必须实现接口的方法,修饰符不得低于接口的方法修饰符
static
-
static
方法中,没有this一说 -
static
只能在类中使用
关于执行顺序,如下题:
静态块:用
static
申明,JVM加载类时执行,仅执行一次
构造块:类中直接用{}定义,每一次创建对象时执行
执行顺序优先级:静态块>main()>构造块>构造方法
静态块按照申明顺序执行,先执行Test t1 = new Test();
所以先输出blockA,然后执行静态块,输出blockB,最后执行main方法中的Test t2 = new Test();输出blockA。
线程
run
方法执行完成,线程就销毁
异常
序列化
序列化保存的是对象的状态,静态变量属于类的状态
因此,序列化并不保存静态变量。
什么是序列化?
KMP
i 0 1 2 3 4 5 6 7 8
s a b a b a a b a b
next[i] -1 0 0 1 2 3 1 2 3
先计算前缀next[i]的值:
next[i]的值主要是看s[i]之前的字符串中重复的子串长度。next[0] = -1,定值。
next[1]是看s[1]之前的字符串“a”中重复的子串长度为0,故next[1] = 0。
next[2]是看s[2]之前的字符串“ab”中重复的子串长度为0,故next[2] = 0。
next[3]是看s[3]之前的字符串"aba"中重复的子串长度,s[0]与s[2]重复,长度为1,故next[3] = 1。
next[4]是看s[4]之前的字符串"abab"中重复的子串长度,s[01]与s[23]重复,长度为2,故next[4] = 2。
next[5]是看s[5]之前的字符串"ababa"中重复的子串长度,s[012]与s[234]重复,长度为3,故next[5] = 3。
next[6]是看s[6]之前的字符串"ababaa"中重复的子串长度,s[0]与s[5]重复(因为多了一个a,无法找到长度为3的重复字符串,这只能是s[0]和s[5]重复),长度为1,故next[6] = 1。
同样的,求next[7]和next[8]分别为2和3。
接下来计算nextval[i]的值:
nextval[i]的求解需要比较s中next[i]所在位置的字符是否与s[i]的字符一致,如果一致则用s[next[i]]的nextval的值作为nextval[i],如果不一致,则用next[i]做为nextval[i]。
nextval[0] = -1,和next[0]的值一样。
nextval[1],比较s[next[1]] ?= s[1],next[1] = 0,s[0] = a,而s[1] = b,二者不一致,则nextval[1] = next[1] = 0。
nextval[2],比较s[next[2]] ?= s[2],next[2] = 0,s[0] = a,而s[2] = a,二者一致,则nextval[2] = nextval[s[next[2]]] = nextval[s[0]] = -1**(严谨来看这么表述是有问题的,因为nextval[2]表示nextval数组中** 第3个数值,而nextval[s[0]]表示的是s[0]对应的字母‘a’所对应的nextval值 -1,这里nextval[]的用法并不严谨,只是为了表述方便 )。
nextval[3],比较s[next[3]] ?= s[3],next[3] = 1,s[1] = b,而s[3] = b,二者一致,则nextval[3] = nextval[s[next[3]]] = nextval[s[1]] = 0。
nextval[4],比较s[next[4]] ?= s[4],next[4] = 2,s[2] = a,而s[4] = a,二者一致,则nextval[4] = nextval[s[next[4]]] = nextval[s[2]] = -1。
nextval[5],比较s[next[5]] ?= s[5],next[5] = 3,s[3] = b,而s[5] = a,二者不一致,则nextval[5] = next[5] = 3。
同样的求nextval[6],nextval[7],nextval[8]分别为 0 ,-1 , 0。
这里是nextval的下标从-1开始,如果从1开始,则其余各位均+1,nextval为0,1,0,1,0,4,1,0,1