Java复习
1、基础语法
**标识符命名规范:**以字母、_、$开头的字母字符(仅仅是 _ $)数字串
8种基本数据类型:(内存中的最小逻辑存储单元)
整数: byte (1B) short(2B) int(4B) long(8B)
小数:float(4B) double(8B)
非数值: char(2B) boolean(1B)
**引用数据类型:**除了上述的8种基本数据类型外的其他类型
(变量后放的不是值,是值的引用地址)
三元(目)运算符: 布尔表达式 ? 为true时结果 : 为false时结果
移位运算(结果自动升级为int)
<< N 左移N位: 向左移动指定N位数,右边补0 (相当于 * 2)
>> N 带符号右移: 向右移动指定N位,左边补符号位 (相当于正数 /2)
>>> N 无符号右移: 向右移动指定N位,左边0 (相当于正数 / 2)
类型升级带来的强制类型转换问题:
1、byte类型变量运算后的结果为int类型;
2、char类型变量运算后的结果为int类型;
不规则数组:
上三角:
//定义了5个一维数组
int[][] a = new int[5][];
//循环定义每行的元素个数
for(int i; i<a.length; i++){
a[i] = new int[i+1];
}
下三角:
//定义了5个一维数组
int[][] a = new int[5][];
//循环定义每行的元素个数
for(int i; i<a.length; i++){
a[i] = new int[a.length-i];
}
int[] a = new int[0];
int[] b = null;
String:
String类中包含了许多操作当前字符串的方法:
equals(),length(),charAt(),compareTo(),indexOf(),lastIndexOf(),substring(start, end), replace(), replaceAll(), split(“limit”)、trim()、 toUpperCase()、toLowerCase() 等
String、StringBuffer、StringBuilder区别:
String不可变、StringBuffer和StringBuilder可变
StringBuffer线程安全(synchronized)、StringBuilder非线程安全;
final:
1- 方法中修饰常量
2- 方法中修饰InnerClass
3- 修饰方法为最终方法,不能被覆盖
4- 修饰属性为常量属性
5- 修饰类为最终类,不能被继承
finally:
try代码段后,必须被执行的代码段修饰,一般用来关闭流,保存必要信息等不可缺少的操作
finalize:
是Object定义的protected方法,每个对象都有,一般在对象被销毁前被JVM调用。
但是注意:如果JVM轮巡销毁对象前,进程就结束了,则此方法无法被调用。
如果希望某个对象销毁前要做的动作,而且其运行环境允许(不是立即结束进程),可以将动作代码写到finalize中
**重载:**在一个类中,同名不同参(形参),称为重载;重载的意义:给方法的使用者提供遍历,不用记忆太多的功能相似的方法名称;
**重写(方法的覆盖):**子类继承父类的方法,但是被继承的方法对子类不适用,则可以定义与父类被继承方法,同名、同参、同返回类型的方法加以覆盖,则子类对象只能调用子类定义的覆盖方法,而无法调用父类的被覆盖方法;
注意:子类覆盖方法的访问规则要小于等于父类被覆盖方法的访问规则
子类覆盖方法的显性异常的再抛出(throws 异常列表)异常类型范围,要小于等于父类显性再抛出异常的范围,原因是多态(要用父类方法签名 获取 子类方法执行体)
**多态:**父类对象名获取了子类对象的引用,则父类对象调用被覆盖方法时,只能调用子类定义的覆盖方法,而无法调用父类自己定义的被覆盖方法。
**继承的意义:**扩展功能
接口和抽象类的区别:
1- 接口没有实现的方法(jdk1.8以后出现默认实现的方法),接口没有成员属性,没有构造器;
抽象类可以有抽象或者实现的方法,可以有成员属性,可以有构造器;
2- 接口为了实现预设算法的接入而出现的一种变相的类,如果有类需要预设算法,则接入接口,例如 Comparator接口 可以使用 Collections.sort() 排序算法
抽象类,对上层属性和算法做了规则,由子类进行具体实现,例如:AbstractList , ArrayList 用数组结构实现算法;LinkedList用链表结构实现算法
静态导入:
导入其他类中静态成员,其后可以象使用自己定义的静态成员一样,不需要加类限定;
import static com.yq.mvn06.tset.sub.TestClass.FINAL_VAL;
static {
int x = FINAL_VAL;
}
throw和throws的区别:
throw是手动抛出异常对象,格式: throw 异常对象;
throws 是在方法签名上说明这个方法体中可能抛出的异常;(显性再抛出)
try代码段的结构:
try{
...
}catch( Exception e){
...
}
try{}finally{
...
}
try{
...
}catch( Exception e){
...
}finally{
...
}
自动打包注意: 如果自动打包,数值范围 -128~127之间使用预设的对象,否则才建立新对象
Integer i = 10;
Integer k = 10;
System.out.println(i == k); //结果为true
Integer i = 128;
Integer k = 128;
System.out.println(i == k); //结果为false
集合:接口依赖
ArrayList和LinkedList的区别:
1- ArrayList使用数组存储元素:由于数组是连续存储空间,所以遍历读取,替换元素内容效率较高;
2- Vector 也是使用数组结构存储元素,但是所有对外操作元素的方法都是同步方法,所以线程安全;
3- LinkedList使用链表存储元素:非连续空间,每个空间记录保存元素外,还记录了下一个(或者同时也记录上一 个)空间的索引,实现了(单向或者双向链表),由于空间非连续,所以遍历性能较差,但是对元素的增删操作性能较高;
注意:由Arrays.asList(数组)从数组生成的 List,属于常量List,不可变其长度
String[] strs = {"1", "2", "3", "5", "6", "7", "8", "9"};
List<String> finalList = Arrays.asList(strs);
finalList.set(0,"10"); //替换元素是允许的
finalList.add("10"); //修改其长度不允许,会报出:java.lang.UnsupportedOperationException finalList.remove("10"); //错误同上
HashSet和LinkedHashSet、TreeSet的区别:
1- HashSet 采用添加元素时生成的hash值保存元素,无序
2- LinkedHashSet 采用链表保存元素,添加顺序(重复元素忽略)
3- TreeSet 实现了 SortedSet接口,实现了其comparator方法,内部采用二叉树保存数据,则使用元素的本身的比较器比较大小,从而实现有序(注意,不能保存null值)
HashMap和TreeMap的区别:
1- HashMap无序
2- TreeMap有序(内部采用二叉树)
Map三种遍历方式
// 1-map.entrySet() 生成: Set<Map.Entry<key的类型, Value的类型>> 对象 (效率最高) Set<Map.Entry<String, String>> entrySet = map.entrySet();
for(Map.Entry<String, String> entry : entrySet ){
System.out.println( entry.getKey() + " = " + entry.getValue());
}
//2- 将所有key生成Set,通过遍历key的Set集合,分别从Map中获取Value
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key + " - " + map.get(key));
}
//3- 将所有值生成 Collection对象,遍历所有Collection元素中的 value
Collection<String> coll = map.values();
for(String val : coll){
System.out.println(val);
}
比较器的实现
Collections.sort(newList, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//nulls last方式,将null值放到最后
if(o1 == null){
//o1的物理位置在o2之前,如果为空则交换到o2以后,则就实现了 nulls last
return 1; }
if(o2 == null){
//如果o2为空则不交换,就实现了 nulls last
return -1; }
return o2.compareTo(o1);
}
} );
java.io.File:
1- 构造器:
new File(String 路径, String 文件名);
new File(File 路径, String 文件名);
new File(String 路径或者带文件名的路径);
new File(URI 网络路径文件);
2- 常用方法:
boolean exists() :测试此抽象路径名表示的文件或目录是否存在。
boolean isDirectory() :测试此抽象路径名表示的文件是否为目录并且实际存在。 boolean isFile() : 测试此抽象路径名表示的文件是否为普通文件并且实际存在。 boolean mkdirs() : 创建由此抽象路径名命名的目录树。
long length() : 返回由此抽象路径名表示的文件的大小(字节)。
String[] list() : 返回一个字符串数组,命名由此抽象路径名表示的目录中的子文件和子目录。
String[] list(FilenameFilter filter) : 可过滤的(仅仅提取需要的文件,可以是名称,后缀的信息), 返回一个字符串数组,命名由此抽象路径名表示的目录中的子文件和子目录。
File[] listFiles() : 返回一个抽象路径的File数组,表示由该抽象路径名表示的目录中的子文件和子目录。
File[] listFiles(FilenameFilter filter) : 可过滤的,返回一个抽象路径的File数组,表示由该抽象路 径名表示的目录中的子文件和子目录。
URI toURI() : 构造一个表示此抽象路径名的
file: URI。 delete() : 删除由此抽象路径名表示的文件或目录。
IO分类
1- 按照方向分:输入流、输出流
2- 按照功能分: 字节流(InputStream、 OutputStream 抽象类); 字符流(Reader、Writer 抽象类)
3- 处理方式分: 节点流、处理流
格式化输出:String.format(格式字符串, 参数 …);
格式标志符
对小数保留两位小数的格式化
String result = String.format("%06.2f", 30.1456);
//会四舍五入,整数不足位会补零
System.out.println(result); // 结果: 030.15
正则规则:
句点.表示任意单个字符
方括号[]表示集合里的单个字符
括号()表示子表达式,里面可包含多个字符串,使用|表示或关系
大括号{}表示前一个元素的重复次数
转义字符\
中括号中的^符号表示“否”,中括号外的^表示字符串开始
$表示字符串结束
\d \D \w \W \s \S等简洁符号
线程
实现自定义线程方式
1- 继承Thread类(无返回)
2- 实现Runnable接口(无返回)
3- 实现Callable接口(有返回值)
常用方法
boolean isAlive() : 判断是否线程状态是否还在运行返回true,如果死亡则返回false;
while(t.isAlive()){
Thread.sleep(5);
}
//当线程结束后的执行程序
void start(): 启动线程,让线程对象拥有独立的执行时间片
**线程池:**规定同时执行的线程数量,如果到达上限,则必须等待有线程结束才能加入新线程的执行,保护CPU的执行效率
//创建固定数量的线程池
Executor pool = Executors.newFixedThreadPool(线程同时运行的数量上限);
//创建单线程的线程池
Executor pool = Executors.newSingleThreadExecutor();
//在不影响CPU性能前提下,尽可能多的运行线程
Executor pool = Executors.newCachedThreadPool();
//使用线程池执行线程
pool.execute(线程对象);
**线程的同步:**多个线程访问同一个资源对象时,需要串行访问,不能并行,否则可能出现读取“脏数据”的情况;
同步实现方式:
1- synchronized关键字:
1.1- 同步方法(写在资源对象的需要同步执行的方法前)
1.2- 同步语句块(写在线程直接调用的功能代码段中)
2- 可重入锁:ReentrantLock
**线程的死锁:**多个线程访问多个互斥资源时,线程相互获取并期望别的线程释放资源,而出现的一种现象。
**死锁条件:**1- 多线程、 2- 多个互斥资源 、 3-多线程同时无控制的访问互斥资源
**如何解除死锁:**破除死锁条件; 使用可重入锁进行尝试锁的方式;
**资源对象:**线程工作时,需要线程run方法处理的对象(可能是数据对象,也可能是业务对象,可以是任何POJO对象)
使用wait和notify、notifyAll的限制
1- 认识wait 和 notify、notifyAll:
都是Object的方法,所有对象都有
2- waite的作用,资源对象调用.waite方法, 线程对象去调用“资源对象.wait()”这条语句,则线程被 挂起
3- notify的作用,资源对象调用.notify(), 则只有被 此资源对象wait的线程会被唤醒
4- 必须在资源对象自己的同步语境(同步方法、同步语句块),才能有这个资源对象去调用 wait 和 notify方法,
否则:java.lang.IllegalMonitorStateException 异常
MySQL:
数据库前三范式:
1- 所有数据原子性:列的信息单一化,不可拆分
2- 满足第一范式基础上,除了主外键列以外的其他列,都和主键有唯一依赖。
员工编号(主键) 姓名 工资 部门编号(外键) 部门编号(主键) 部门名称
3- 满足第二范式基础上,所有列都和主键直接依赖,不能有传递依赖
员工编号(主键) 姓名 工资 奖金 (总工资 查询计算,不能出现实际的存储值)
**索引:**根据指定的一列(单列索引)或者多列(多列索引、或者称复合索引); 对于不重复列可以建立唯一性索引 (默认主键和加了 unique约束的列,建立表时,或者添加上述两个约束时会自动生成唯一性索引)
实际情况:正常情况下(列的个数 < 20 时; 行数 < 4W时) 重复数据 大于总数据 5 % 时,索引几乎无法提高性能。
**注意:**一张表最多1000列
使用索引:不能主动使用索引,仅当SQL语句的筛选条件含有索引列时,会自动启用。
语法:
MySQL: ALTER TABLE 表名 ADD [unique] INDEX 索引名 ( 索引列[,索引列] );
Oracle:CREATE [unique] INDEX索引名 表名(索引列 [,索引列])
聚簇索引:
聚簇索引也叫簇类索引,是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。提高查询中标几率 的索引:
相当于对全范围的搜索,转化成某种类别的局部搜索,例如:
对一张人员信息表,将所有人姓名的声母进行聚簇分类,则 “张三” 的记录,只能在 一层聚簇的 “Z” 这个页中, 如
果信息依然很大,则可以对“Z”对应数据进行第二层聚簇分类,例如:按照名的声母进行分类 ,依次类推,分割数
据页,以提高查询中标几率。
此种情况在Oracle中经常使用“分区表”的手段完成;
SQL语句主要可以划分为以下四类:
– DDL(Data Defifinition Language):数据定义语言
对数据库对象(库、表、列、索引)的操作。
CREATE、DROP、ALTER、RENAME、TRUNCATE等
– DML(Data Manipulation Language): 数据操作语言
对数据库记录的操作。
INSERT、DELETE、UPDATE、SELECT等
– DCL(Data Control Language): 数据控制语言
对数据库、表、字段、用户的访问权限进行控制。
GRANT、REVOKE等
– Transaction Control:事务控制
COMMIT、ROLLBACK、SAVEPOINT等
大部分数据库支持下面五种约束:
– NOT NULL 非空
– UNIQUE 唯一
– PRIMARY KEY 主键
– FOREIGN KEY 外键 (主表的 主键、唯一性约束列才能作为子表的外键列)
– CHECK 检查(MySQL不支持)
Mybatis框架
常用标签元素:
<insert> <update> <delete> 返回值全部是 int (影响行数), 不用写 resultType 或者 resultMap属性;
<select resultType="返回类型的别名或者带包的全名" (别名可以是自定义的,也可以是 MyBatis定义的:org.apache.ibatis.type.TypeAliasRegistry 别名定义类
resultMap="自定义的对象属性和列的对应关系">
动态SQL标签:
<sql id=""> 公共SQL代码 </sql> 由需要的地方 <include ref="sqlId"/>引用
<if test="参数表达式" (注意不能放置列条件,只能是参数条件)/>
<foreach collection="引用集合、数组参数" item="当前定义的循环元素名" open="循环开始字符" close="循环结束字符信息" separator="元素之间的分割字符信息"/>
<where> 条件表达式信息 </where> 当条件表达式不成立时没有 WHERE 关键字,否则自动产生WHERE关键字会删除WHERE字符后紧跟的 AND 或者 OR 逻辑与、或的SQL关键字
关联查询:
子表关联主表(外键关联时):
<association property=“外键列实体属性名" resultMap="主表的映射id"/>
主表关联子表信息集合:
<collection property="集合属性名" resultMap="元素实体映射id" javaType="集合类型,例如:java.util.Set">
#{} 和 ${} 区别:
#{参数名} : 普通参数替换,结果 '参数值'
${参数名} : 直接替换(硬替换), 结果 参数值, 使用场景:传递列名进行排序或者分组用
直接替换有SQL注入风险,例如:
select userid, username where ${登录条件} 可以将参数写成: 1=1
select userid, username where username='${登录条件}'
Servlet
Servlet(对象)生命周期:
1- 没有配置load-on-startup 参数的,第一次请求时建立Servlet对象,后续每次请求时都仅仅执行 service方法 (分发到 doGet 或者 doPost方法中); 关闭应用服务器时会销毁Servlet(对象);
2- 配置load-on-startup 参数的,启动应用服务器时建立Servlet对象,每次请求时都仅仅执行 service方法(分发 到 doGet 或者 doPost方法中); 关闭应用服务器时会销毁Servlet(对象);
注意:load-on-startup 配置正整数参数,数字越小,启动越优先。
请求转发和重定向:
请求转发:客户端请求了Servlet,这个Servlet将请求转发给客户端需要显示的目标地址,期间request对象不变
request.getRequestDispatcher("转发目标地址").forward(req, resp);
场景:需要将Servlet中的查询数据带给客户端时使用
重定向:客户端请求了Servlet,这个Servlet处理完毕后,告诉客户端需要再次重新发出的目标地址请求(由浏览器自动完成新请求),期间发出了两次请求,有两个不同的request对象;
response.sendRedirect("目标地址");
场景:对数据做了修改(添加和删除、修改)时,需要断开第一次请求,让浏览器重新发出请求。否则,刷新页面时会重新发起数据修改请求。
Cookie和Session的区别
Cookie是服务器存放在客户端的一段文本,借助Cookie,服务器端可以对用户进行身份验证,会话跟踪等;
Session是在服务器端记录用户信息的一种机制,客户端发起后续的请求时,浏览器默认会将Cookie发回给服务器, 服务器通过这个编号(JSESSIONID)就可以获取到关联的Session对象。
在JSP页面中,可使用如下9个内置对象:
1,out引用了JspWriter类的实例。
2,request引用了HttpServletRequest类的实例。
3,response引用了HttpServletResponse类的实例。
4,session引用了HttpSession类的实例。它是和当前用户关联的服务器端的对象,用来在服务器端保存用户的信息。
5,application引用了ServletContext类的实例。该实例由Servlet容器自动创建,且一直存在到Web服务器关闭。因此,该对象通常用来存放web应用全局共享数据。
6,exception引用了Exception类的实例。该变量只能在错误页面使用(page指令元素属性
isErrorPage=ture),它封装了上个页面的异常信息。
7,page引用当前JSP页面本身,类似于this指针。 java.lang.Object page = this;
8,config引用了ServletConfig实例。是在Servlet初始化时容器传入的对象,包含了Servlet的配置参数。
9,pageContext 引用了一个PageContext实例,该对象是获取其它对象的总入口,其包含了application,session,out,config,page等对象。 该对象还可用来给page范围设置属性值:
pageContext.setAttribute("", "",PageContext.PAGE_SCOPE);
四个范围
page(本页面有效,实现:pageContext);
request(本次请求有效);
session(当前用户的所有请求有 效);
application(所有用户的所有请求都有效,可以用来在不同用户间共享数据,ServletContext类实现)
Spring
IOC容器
由Spring管理的,需要共享的业务对象、数据访问层对象、工具类对象的集合;
通常通过单例方式对外提供服务; 通过修改 scope="singleton" 单例; scope="prototype" 非单例方式控制IOC中对象的生成方式
AOP:
面向切面编程的一种规范,Spring实现AOP规范,使用了 JDK的动态代理和 cglib的动态继承实现;
AOP的概念:
Target --目标对象。表示将被添加横切逻辑的目标对象。
JoinPoint -- 连接点。表示程序中可以插入横切功能的点。Spring中仅支持方法调用前后作为连接点。
PointCut -- 切入点、切点。表示需要插入横切功能的一系列连接点。
Advice -- 通知、增强。代表了横切逻辑功能。
Aspect -- 切面、方面。表示一整套Advice、PointCut的组合,既包括了横切功能,也包括了切点定义。
Weaving --织入。织入是指将增强(Advice)添加到切入点(PointCut)上的过程。
SpringMVC
工作原理:
1- 客户端发出请求给DispatchServlet(中央控制器、处理器)
2- 中央控制器调用 ”处理器分发器“ 寻找Controller类
3- 调用”处理器适配器“ 进行参数转换、封装,并定位到具体的Controller处理方法
4.1 - Controller返回 ModelAndView或者String(封装了目标视图、信息对象)
4.2 - 中央控制器调用“视图解析器”,解析 ModelAndView中的视图,返回的视图(
View接口对象)
4.3 - 中央控制器调用View视图对象的 render()方法给客户端返回相应的信息(页面信息、数据信息)
5.1 - Controller不返回 或者返回 ResponseEntity对象,或者添加了注解:ResponseBody的方法,则走消息 转换,SpringMVC默认使用 Jackson 包进行 Object -> JSON字符串的转换工作交给客户端
客户端发出请求给DispatchServlet请求分发器)
调用HandlerMapping寻找Controller类
调用HandlerAdapter进行参数转换,封装,并定位到具体的Controller处理方法,Controller返回ModelAndView或者String(封装了目标视图。信息对象)
调动handlerresolver 解析ModelAndView中的视图,返回视图(View接口对象)
调用View视图对象的reader()方法给客户端返回相应的信息(页面信息,数据信息)
Controller不返回 或者返回 ResponseEntity对象,或者添加了注解:ResponseBody的方法,则走消息 转换,SpringMVC默认使用 Jackson 包进行 Object -> JSON字符串的转换工作交给客户端
MVN
POM的文件结构
1- POM版本说明xsd
2- 项目坐标(组id,项目名,版本)+打包方式(工具项目:jar; web项目:war)
3- 全局属性配置(可以自定义属性标签)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
4- 项目依赖
<dependencies>
<dependency>
依赖项目坐标
<scope>使用依赖项目的范围:test、compire、runtime、provide</scope>
</dependency>
...
</dependencies>
5- 配置项目构建
<build>
5.1- 默认目标(打包)
<defaultGoal>package</defaultGoal>
5.2- 配置打包静态资源(例如Mapper.xml如果在src目录下,就需要配置,否则打包会忽略)
<resources>
<resource></resource>
</resources>
5.3- pom自定义的替换属性文件
<filters>
<filter>替换属性文件.properties</filter>
</filters>
5.4- 配置项目插件
<pluginManagement>
<plugins>
<plugin>
插件名、版本
</plugin>
...
<plugins>
</pluginManagement>
6- 用户自定义配置
<profiles>
<profile id="">
可以包含上述所有标签的配置,进行不同目标操作时的不同配置;
</profile>
</profiles>
ler.target>
4- 项目依赖
依赖项目坐标
使用依赖项目的范围:test、compire、runtime、provide
...
5- 配置项目构建
5.1- 默认目标(打包) package 5.2- 配置打包静态资源(例如Mapper.xml如果在src目录下,就需要配置,否则打包会忽略)5.3- pom自定义的替换属性文件
替换属性文件.properties
5.4- 配置项目插件
插件名、版本
...
<plugins>
6- 用户自定义配置
可以包含上述所有标签的配置,进行不同目标操作时的不同配置; ```