ArrayList、Vector的初始容量为10
Vector的加载因子未1,扩容为增加原来的1倍(原来:10;扩容后:20)
ArrayList的加载因子为0.5,扩容为增加原来的0.5倍再+1(原来:10;扩容后:16)
HashSet、HashMap扩容,初始容量为16,加载因子为1,扩容后增加原来的1倍(原来:16;扩容后:32)
重写是子类重写了父类同名的方法或是抽象方法
重载是参数列表的类型、顺序、参数数量不同都构成重载,返回值对重载不影响,可以改变,但是单一只改变返回值类型不构成重载,因为jvm无法判断重载的方法
x.equals(y)==true则他们的hashcode一定相同,若x和y的hashcode相同,那么他们不一定相同。若是违背这个原则,会产生频繁的哈希冲突,如果是在set集合中,增加新值的效率就大大降低了,导致性能下降。
equals需要满足自反性(x.equals(y)为true,y.equals(x)则也为true)
需满足传递性(x.equals(y)为true y.equals(z)为true x.equals(y)为true)
需满足一致性
字符串连接"+"实际上是转换成了new stringBuilder然后append,最后将引用指向改变后的字符串
例如
String s = "abc";
String ss = "ok" + s + "xyz" + 5;
反编译后
String s = "abc";
String ss = (new StringBuilder("ok")).append(s).append("xyz").append(5).toString();
抽象类和接口,接口是比抽象方法更抽象的抽象类,继承抽象类的或是实现接口的类必须实现全部的抽象方法
抽象类:
- 内部成员可以是4中修饰类型
- 可以定义成员变量
- 可以有构造器和具体的方法
- 抽象类可以实现接口,也可以继承具体类和抽象类
接口:
- 成员只能是public修饰
- 成员变量只能是常量
- 不能定义构造方法且方法必须全部为抽象方法(jdk8新特性,接口中可以定义普通方法)
- 接口可以继承接口,支持多重继承
继承关系的加载顺序
静态字段或代码块相当于全局变量,即在class文件被加载进内存时就为static修饰的变量或方法分配了内存,其他变量则是创建之后分配的内存
- 加载父类的静态字段和静态代码块
- 加载子类的静态子丢按和静态代码块
- 加载父类的普通变量以及普通语句块
- 加载父类的构造方法
- 加载子类的普通变量和普通代码块
- 加载子类的构造函数
注意的是
- 静态代码块只加载一次
- 构造方法创建一次对象加载一次
- 静态方法,调用的时候才会加载,不调用则不会加载
- 静态代码块和静态变量的执行顺序与代码的先后顺序有关
常见的运行时异常
- ArithmeticException(算术异常)
- ClassCastException(类转换异常)
- IndexOutOfBoundsException(下标越界异常)
- IllegalArgumentException(非法参数异常)
- NullPointerException(空指针异常)
- SecurityException(安全异常)
Sleep()和wait()都能使线程暂停,区别是sleep()不会释放同步锁,调用后进行阻塞状态(差CPU和其他资源),待时间结束后恢复就绪状态(只差CPU资源),wait()方法会释放同步锁,使用后进入等待队列,只有在notify()(随机抽取等待队列中的一个线程恢复),或是notifyAll()方法才能恢复,待获取到同步锁之后进入就绪状态
注意
sleep()是一个静态方法,在使用时要处理InterruptedException异常
yield()执行后转就绪状态,可能立马又获取到cpu资源进入运行状态,也可能其他优先级资源获取到cpu资源
JDBC可以通过prepareStatement语句进行批处理提升性能,因为prepareStatement会缓存SQL,下次执行的速度更快
Mysql中锁的类型有三种:表级锁、行级锁、页面锁
- 表级锁:开销小、加锁块,不会出现死锁,冲突概率高,并发度低
- 页面锁:开销和加锁时间介于二者之间,会出现死锁,并发度一般
- 行级锁:开销大,加锁慢,会出现死锁,冲突概率低,并发度高
MYISAM和InnoDB的区别
MYISAM:不支持事务,每次查询都是原子的,支持表级锁
InnoDB:支持ACID事务,支持事务的4种隔离级别,支持行级锁,可以做并发
隔离级别
- read uncommited(读未提交)相当于未设置隔离级别,会出现脏读、不可重复读、幻读
- read commited(读提交)可以解决脏读
- repeatable read(可重复读)解决了不可重复读(Mysql默认隔离级别)
- serializable(串行事务)解决了幻读----------(读锁、写锁互斥)性能大大降低
不可重复读和幻读
两者都表现为前后两次读取的数据不一致
不可重复读的重点在update和delete,幻读的重点在insert,不可重复读在给查找的数据加锁后避免其他事务对其进行修改就实现了可重复读,但是这样无法阻止其他事务进行insert插入数据,会导致读出新插入的数据(幻影数据),即幻读
SQL中的limit的用法
//一个参数,表示查询从索引0到n的数据,等同于limit 0,n
select * from table_name limit n
//带两个参数,查询从索引为n的位置开始的m条数据
select * from table_name limit n,m
索引失效的情况
- 有or必须全有索引,否则失效
- 复合索引(左匹配原则),若未使用左列字段,失效
- like以%开头
- 需要进行类型转化(字符串类型必须加引号,否则失效)
- where中索引列有数学运算
- where中索引列使用了函数
- 不使用索引速度反而更快的情况(数据量很少)
索引的左匹配原则
创建联合索引(index1,index2,index3)相当于创建了3个索引(index1)、(index1,index2)、(index1、index2、index3)
使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间
自连接、左外连接、右外连接、全连接(Mysql不支持)
mysql数据库设计的三大范式
- 第一范式
- 表的列具有原子性不可再分
- 第二范式
- 必须满足第一范式,要求数据库表中的每个实例或行必须被唯一的区分,通俗理解:任意字段都只依赖表中同一个字段,消除了非主属性对主键属性的部分依赖。
- 第三范式
- 必须满足第二范式,要求表中字段能从其他表中获取,使用join进行连接推导获取,而不是单独设计一个字段,消除了传递依赖
JDBC操作流程
- 加载(注册)数据库驱动(到JVM)
- 建立(获取)连接Connection
- 创建(获取)数据库操作对象
- 编写sql,执行(Excute)数据库操作
- 关闭对象,回收数据库资源
Mysql的一级缓存和二级缓存
- 一级缓存:本地缓存,默认为打开状态,其存储作用域为当前session,session flush或关闭后,session中的所有缓存被清空
- 二级缓存:全局缓存,与一级缓存机制相同,为hanshMap存储,作用域为namespace,一级缓存失效后(session关闭),一级缓存中的数据据转到二级缓存中,二级缓存需要手动开启,同时使用二级缓存的数据类要实现序列化接口来保存对象的状态
- 缓存更新机制:进行C/U/D操作后,默认作用域下中所有select中的缓存都会被清空(clear)
#和$符号的区别
- #是预编译,参数通过一个?占位,即占位符,编译完成之后通过prepareStatement的set方法注入sql中,这样可以有效避免sql注入
- 是 通 过 字 符 串 拼 接 的 方 式 , 也 就 是 把 s q l 中 的 是通过字符串拼接的方式,也就是把sql中的 是通过字符串拼接的方式,也就是把sql中的{}替换成变量的值
- #会自动转换类型,例如使用#{}时,会把#{}替换成“变量内容”
- $不会自动转化类型
- order by 这 种 只 能 使 用 {}这种只能使用 这种只能使用符,因为使用#会变成order by “值”,不符合
什么是控制反转(IOC)
-
IOC是Inversion of Control的缩写,翻译为控制反转
-
观点:借助第三方实现具有依赖关系的对象之间的解耦
-
被称为控制反转的原因:
- 在没有引入IOC容器时,对象A依赖于对象B,那么A对象在实例化时就需要我们手动创建B对象,所以控制权在我们手上
- 引入IOC之后,在创建实例化A对象的时候,IOC会自动创建A对象依赖的B对象,然后注入到A对象中
- 对比之下,B对象的创建由之前的主动变成了IOC被动创建,控制权反转了,所以被称为控制反转
-
IOC的别名:依赖注入
IOC的控制反转实际上实在“获得依赖的过程中反转了”,所以取名为“依赖注入(DI----------Dependency Injection)”更合适。依赖注入就是IOC容器运行期间,动态地将依赖关系注入到对象之中,所以IOC和DI是从不同角度描述同一件事情,通过IOC容器,利用依赖注入地方式,实现对象之间地解耦