第一天早上2017-10-21
1.JVM
java virtual machine java程序需要运行在虚拟机上,不同平台有自己的虚拟机,实现跨平台;
JRE
java running environment java运行环境=jvm+运行所需要的核心类库
JDK
java develop kit java开发工具=jre+java的开发工具(javac.exe,jar.exe)
2.常量分类:
整数常量、小数常量、字符常量、布尔常量、空常量
3.变量:本质上讲内存中的一块区域
java中string a = null表示该变量为空,还没有整整保存对象的值---》一个空对象,即地址不指向任何对象
string a = ""仅仅表示该字符串长度为0,该地址指向""
string a =" ",即地址指向一个空白字符串,其长度为1
在jsECMAScript中有五种基本类型:Undefined,Null,Boolean,Number,String,Object
没有初始化定义的就是undefined。
null 表示一个值被定义了,定义为“空值”;
undefined 表示根本不存在定义。
4.java语言数据类型
基本数据类型
4类8种
整形 byte 1, short 2, int 4, long 8---默认int
浮点型 float 4,double 8---默认double
字符型 char 2
布尔型 boolean 1
引用数据类型
类 class
接口 interface
数组 []
5.数据类型转换
隐式数据类型转换:默认会讲小的数据类型提升为大的再运算
强制类型数据转换:会有精度损失
第一天中午2017-10-21
6.运算符
算术运算符
关系运算符
赋值运算符
逻辑运算符
三元运算符 --(关系表达式)?表达式1:表达式2---int c = (a>b)?a:b
7.switch语句
1)语句里表达式的取值可以是:byte short int char,jdk5以后可以枚举,jdk7以后可以是String
2)与case后面值比较,匹配到后遇到break结束;
3)如果都不匹配就执行default,然后结束;
8.break与continue
break:在switch语句和循环语句中
跳出当前循环,让当前循环提前结束
continue:在循环语句中
退出本次循环,继续下一次循环
9.jvm内存划分:
栈:存储局部变量
堆:存储new出来的东西
方法区:方法
本地方法区:和系统相关
寄存器:和cpu有关
垃圾回收机制:gc--》新生代,老生代new/old,分代处理---》压缩,复制转移等等算法
10.方法重载和重写:
重载:
特点:方法名相同,参数列表不同,与返回值无关
参数列表不同:
参数个数不同,参数对应数据类型不同
重写:
指的是子类继承父类的方法后,重写了父类的方法,这时子类对象调用的就是子类的方法
第一天下午2017-10-21
11.面向过程与面向对象
面向过程:面向具体的每一个步骤和过程,将每个步骤和过程完成,然后这些功能方法相互调用;
面向对象:不断的创建对象,调用对象,完成对应的功能,将我们从执行者变成指挥者;
12.成员变量与局部变量的区别:
1)在类中的位置不同:
成员变量:类中方法外
局部变量:方法中或方法声明上
2)在内存中位置不同:
成员变量:堆内存
局部变量:栈内存
3)声明周期不同:
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
4)初始化值的问题:
成员变量:有默认值
局部变量:没有默认值,必须先定义,赋值,再使用。
13.面向对象的三大特征:
1)封装
1)对客观世界的模拟,即客观世界成员变量都是隐藏在对象内部的,外界无法直接操作和修改;
2)封装原则:
不需要对外提供的内容隐藏
对外提供公共的get/set方法
2)继承
1)描述事物之间的所属关系
2)继承特点:
单一继承,多层继承
3)注意:
子类不能继承父类的私有成员,不能重写父类的私有方法
4)优缺点
提供了代码的复用性和可维护性
但是类的耦合性增强了
3)多态
1)现实事物经常会出项多种形态,多种身份,如人,学生
2)多态成员变量:编译运行都参考父类
多态成员方法:编译看父类,运行看子类
多态静态方法:编译运行看父类
3)优缺点:
提高可维护性,可扩展性
但无法访问子类特有的成员
14.this和super
this:代表所在的类的对象的引用,方法被哪个对象引用,this就代表哪个对象
super:获取父类成员变量和方法
15.String和StringBuilder和StringBuffer
String:字符串是常量,一旦被赋值,就不能改变
通过构造方法创建的字符串对象在堆内存
通过直接赋值的方式创建对象在方法区的常量池
StringBuilder:是一个可变字符串,字符缓冲区类
因此需要字符串拼接的时候建议使用StringBuilder
此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作
StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
StringBuffer:
16.ArrayList、map、set
Collection--接口---定义集合中最常用的功能(单列集合) Map(双列集合--键值对)
List接口 Set接口
ArrayList类 LinkedList类 HashSet类 LinkedHashSet类 不能包含重复的key,可以有重复的value
1)迭代器Iterator接口,一种取数据的方式
hasNext()方法:判断集合是否有元素可以迭代
next()方法:返回迭代的下一个元素,并把指针向后移动一位
2)Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常
迭代器本身依赖于集合,相当于集合的一个副本,如果在迭代器遍历操作过程中,集合发生变化,就会抛出这个异常
可以使用Iterator的子接口ListIterator来实现向集合中添加
3)遍历的三种方式“
1)toArray---转为数组再遍历
2)获得iterator对象进行遍历
Iterator it = c.iterator();
while(it.hasNext()){
String str = it.next();
}
3)增强for循环---其内部原理也是一个iterator迭代器,所以再遍历过程中也不能对集合进行增删操作
for(元素的数据类型 变量:Collection集合或数组){
可以直接使用变量
}
4)常见数据结构
数组:长度固定,有整数索引,查询快,增删慢------ArrayList底层是数组结构
链表:元素间通过地址进行连接,因此查找慢,依次向后遍历查找指定的元素----LinkedList底层结构是链表结构
增删快:只需要修改连接的下个元素的地址既可
堆栈:先进后出,即先进的在底部,然后弹出来
队列:先进先出,就像排队一样,先入队的先领盒饭
5)List体系特点:有序,有整数索引,允许重复
Set体系特点:无序,没有索引,没有重复
唯一性原理:每次添加时都会调用hashcode()方法产生哈希值,如果不同,则存入集合
如果相同,再调用equals(Object obj)比较,如果不等则存入集合
6)Collections:工具类,方法都是用来操作collection
主要方法:
swap(list,i,j),交换两个索引位置
sort(list)按照元素自然顺序排序
shuffle(list)随机置换
reverse(list)反转
binarySearch(list,key)二分法查找指定元素的索引
7)map的遍历方式:
1)Set<String> keys = map.keySet();
for(String key : keys){
String value = map.get(key);
}
2)Set<Map.Entry<String,String>> entrys = map.entrySet();
for(Map.Entry<String,String> entry : entrys){
String key = entry.getKey();
String value = entry.getValue();
}
8)Hashtable和HashMap的区别:
1、版本
1.0 vs 1.2
2、线程安全
安全的所以效率低 vs 不安全的所以效率高
3、null键null值的区别
Hashtable不可以存储null键null值
HashMap可以存储null键null值
17.io
FileWriter 字符输出流
FileReader 字符输入流
BufferedWriter 字符输出缓冲流
BufferedReader 字符输入缓冲流 --一次读一个字符 --一次读一个字符数组 --一次读一行readLine()
InputStream 字节输入流
OutputStream 字节输出流
FileInputStream fis = new FileInputStream("传智学院.jpg");
FileOutputStream fos = new FileOutputStream("d:\\传智学院.jpg");
int len;
byte[] bys= new byte[1024];
while((len = fr.read(chs))!=-1){
fw.write(bys,0,len);
}
fr.close();
fw.close();
第二天上午2017-10-23
18.static
静态的特点:
1)被static修饰的成员属于类,而不属于某个对象,即假如某个对象修改了静态成员变量时,其他对象的静态成员变量也跟着改变;
2)被static修饰的成员建议直接通过过类名调用;
3)静态的加载优先于对象,随着类的加载而加载
静态优点:
1)对对象的共享数据提供单独的空间存储,节省空间,没有必要每个对象都存储一份
2)直接被类名调用,不用在堆内存中创建对象
3)相对创建对象访问成员方便
静态缺点:访问有局限,静态方法只能访问静态的成员或方法
19.类变量与实例变量的区别:
类变量:即静态变量,通过类名直接调用的变量
定义位置:类中方法外
内存区域:方法区
生命周期:随着类的加载而加载
特点:无论创建多少对象,类变量仅在方法区中,且只有一份
实例变量:即非静态变量,通过具体实例对象调用的变量
定义位置:定义在类中方法外
内存区域:堆
生命周期:随着对象的创建而加载
特点:每创建一个对象,堆中的对象就有一份实例变量
20.代码块
局部代码块:
存在于方法中,控制变量的生命周期(作用域)
构造代码块:
定义于类中成员位置的代码块
优先于构造方法执行,是执行所有对象要执行的初始化动作,每个对象都会执行一次构造代码块
静态代码块:
定义在成员位置使用static修饰的代码块
随着类的加载而加载,只加载一次,优先于主方法,构造代码块执行,当以任意形式第一次使用到该类时执行
加载类需要做的一些初始化,如加载驱动
第二天中午2017-10-23
21.final与finally
final:最后的,形容词
final修饰的类不能被继承
final修饰的成员变量是常量,不能被修改
final修饰的方法不能被重写
finally:最后,副词
用在try--catch后,表示必须执行的操作,如释放资源等等收尾工作
第二天下午2017-10-23
22.接口interface
1)接口中成员变量只能是常量,默认public static final修饰
2)接口中只能有抽象方法,默认public abstract修饰
3)接口中没有构造方法
23.权限修饰符
public protected 默认的 private
不同包无关类 可以
不同包子父类 可以 可以
同一包 可以 可以 可以
同一类 可以 可以 可以 可以
第三天上午2017-10-26
24.Object类
Object.getClass():获取其字节码对象
Object.toString():返回该对象的字符串表示
Object.equals(Object obj):两个对象是否相等
不重写的情况下,比较的是对象的地址值,一般会重写,比较两个对象的属性值
system类
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) :
从src源数组的srcPos索引开始,复制length个元素
从destPost位置开始将这些元素放至到dest数组中
static long currentTimeMillis() 返回以毫秒为单位的当前时间
static void exit(int status) 终止当前正在运行的 Java 虚拟机
Date类
new Date()创建的是一个表示当前系统时间的Date对象
new Date(long date)根据指定事件创建date对象
set/getTime()设置获得毫秒值时间
SimpleDateFormat对日期时间格式化,解析,标准化,完成日期和文本之间的转化
构造方法:new SimpleDateFormat()---使用默认的迷失进行对象的构建
new SimpleDateFormat(String pattern)---使用指定的格式进行对象的创建
format(Date date)---格式化,将data格式转为String
parse(String str)---解析,将文本解析成日期
Calendar类
日历类,出现后替代了许多Date的方法,该类将所有可能用到的时间信息封装为静态成员变量,方便获取
Calendar c = Calendar.getInstance();--使用默认时区和语言环境获得一个日历,返回当前时间
c.get(Calendar.YEAR);获取当前年
c.get(Calendar.MONTH)+1;获取当前月
c.get(Calendar.DAY_OF_MONTH);获取当前月的第几天
25.包装类
1)java将基本数据类型封装成了对象,默认为null,代表这个对象不存在,而基本数据类型则表达不了对象不存在
2)byte---Byte,short---Short,int---Integer,long---Long,
char---Character,boolean---Boolean,float---Float,double---Double
3)常用方法:
int a = Integer.parseInt(String str);---将string转为int
String str = Integer.toString(int a);---将int转为String
4)自动装箱与自动拆箱
自动装箱:基本数据类型转为对象
自动拆箱:对象转为基本数据类型
26.正则表达式regex
1)常见:[abc]a,b或者c
[^abc]除去abc的任意字符 [a-zA-Z]匹配一个大写或小写字母
[0-9]匹配0-9的一个数字 [a-zA-Z_0-9]匹配字母数字下划线
预定义字符类:
匹配规则为" . ",那么需要匹配的是一个任意字符
匹配规则为"\d ",那么需要匹配的是一个数字
匹配规则为"\w ",,那么需要匹配的是一个字母或者是一个数字或一个下滑线
2)s.split(",") 通过,来切割表达式
第三天下午2017-10-26
27.异常
Throwable:java语言中所有错误或异常的超类,包括exception和error
Exception:
RuntimeException:在程序运行过程中出现的异常
1)如果没有处理,jvm会处理,将异常的类型原因和位置显示在命令行,并终止程序
2)try...catch...finallly捕获异常
3)throws抛出异常
Error:表示java程序总可能会产生的严重错误----修改代码避免错误
28.File
1)常用方法:file.listFiles()---当前目录下所有文件和文件夹
file.getName()----获取文件或文件夹的名称
isFile()----判断file是否是文件
isDirectory()----判断是文件夹
mkdir()----创建文件夹
29.java中字符串的编码
构造方法(字节数组转字符串):
String():初始化一个新创建的 String 对象,使其表示一个空字符序列
String(byte[] bytes) 使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String
String(byte[] bytes, Charset charset) 通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String
成员方法(字符串转字节数组)
getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中
getBytes(Charset charset) 使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组
——> new String(str.getBytes("utf-8"),"utf-8");
字符流 = 字节流 + 编码
第四天上午2017-10-27
30.线程与进程
进程:正在运行的程序,即一个程序进入内存运行,就变成一个进程
线程:进程中的一个执行单元,一个进程中至少有一个线程---thread
多线程:一个程序中有多个线程在同时执行
主线程:在任何java程序启动时,一个线程立刻执行(即main方法对应的线程),则该线程称为该程序的主线程。
特点:它是产生其他子线程的线程,子线程可能在它结束后还在运行
31.创建线程的两种方式:
1)创建一个类继承Thread---》重写其run方法---》创建该类线程对象---》调用start方法,开启线程
2)创建一个类实现runnable接口--->重写接口中的run方法---》创建Thread对象---》创建runnable接口子类对象,作为参数传递给Thread的构造函数
---》调用其start方法开启线程
32.常用的方法:
start():启动该线程,导致run方法被自动调用;
run():创建线程时重写的run方法,在方法中添加该线程执行的代码;
sleep(long mills):使当前正在执行的线程睡眠指定的时间;
interrupt():将一个中断请求发送给线程
boolean interrupted():用于测试某个线程是否已经中断;
boolean isalive():用于测试线程是否还存活着;
set/getPriority(int newPriority):设置/获得线程的优先级
一个线程的缺省优先级为5,优先级范围1-10;
wait(long timeout):当前线程被中断,并进入到一个对象的等待列表中,直到另一个线程调用同一个对象上的notify()方法
notify():用于将对象等待列表中的一个线程唤醒,使之成为可运行的线程
notifyAll():全部唤醒,使之成为可运行的线程
join(long mills):使某个线程等待指定时间,等待该线程结束后,再进行当前线程,如t.join()代表main线程中断,等待t线程执行完后再执行main()。
33.锁--》对象的监视器---》同一时刻只有一个线程访问一个对象
java中每个对象都包含了一把锁(监视器),它自动成为对象的一部分,在给定的时刻,只有一个线程可以拥有一个对象的锁,
当线程1进入某个方法时,获得监视器(锁),等这个方法执行完毕后,线程二才能进入这个方法。
34.多线程的安全问题
1)为了确保在任何时刻,一个共享对象只被一个线程使用,必须使用同步锁(synochronized)
2)有两种方法实现同步:
a.使用同步方法:synchronized void methodA(){}
b.使用同步块:synchronized(obj){要同步的语句}--obj是被锁定的对象
同步方法:使用关键字synchronized修饰的方法,一旦被一个线程访问,则整个方法全部锁住,其他线程则无法访问
格式:synchronized(锁对象){
//需要同步的代码
}
注意:
同步方法:使用关键字synchronized修饰的方法,一旦被一个线程访问,则整个方法全部锁住,其他线程无法访问
非静态同步方法的锁对象是this
静态的同步方法的锁对象是当前类的字节码对象
wait-notify机制:中断--等待列表--唤醒--接着上次继续运行
35.死锁:
当所有的线程都在等待得到某个资源后才能继续运行下去时,整个程序将被挂起,这种情况就叫做死锁。
36.线程的五大状态:
1)新建状态(new)--new Thread(r),线程处于新建状态,还没开始运行线程中的代码
2)就绪状态(runnable)--start(),调用start方法启动线程,创建运行资源后,此时线程处于就绪状态,之后就可以调用线程体run()方法;
3)运行状态(running)--run(),获得资源后,真正进入run方法执行
4)阻塞状态(blocked)--sleep()/io操作被阻塞/程序试图得到一个锁,而该锁正被其他线程持有/线程在等待触发
5)死亡状态(dead)--run方法正常退出而自然死亡/异常终止run方法,判断是否死亡isAlive方法
2017-10-31上午
37.oracle数据库
1).oracle是甲骨文公司提供的以分布式数据库为核心的一组软件产品,支持分布式数据处理,
支持多用户、大事务的事务处理
2).数据类型
字符型:char--固定长度字符串,varchar2--可变长度字符串,long--大文本类型
数值型:number
日期行:date--日期事件型,精确到秒,timestamp--精确到秒的小数点后9位
二进制型(大数据类型):clob,blob--存储图片声音视频等二进制文件,最多4个G
3)数据增删改DML
insert into t_owners values (1,'xjie','1-1','cug');commit;
update t_owners set adddate = adddate - 3 where id = 1;commit;
delete from t_owners where id = 2;commit;----可以rollback,可能产生碎片,并不释放空间
truncate table ---从表的层次摧毁表结构,不能回滚
4)数据库查询:
1)单表查询
1)简单条件查询:select * from t_owners where id = 10;
2)模糊查询:select * from t_owners where name like '%刘%';
3)and,or:select * from t_owners where name like "%刘%" and housenumber like "%5%";
4)范围查询>,<:select * form t_owners where usernum<100 and usernum>10;
select * from t_owners where usernum between 20 and 1000;
5)空值查询:select * from t_owners where usernum is(is not ) null;
6)去掉重复查询:select distinct addressid form t_owners;
7)排序查询:select * from t_owners order by usernum desc;
8)基于伪列查询:rowid---返回的是改行的物理地址,可以快速定位表中的某一行
select rowid,t.* from t_area t;
rownum---为结果集中每一行表示一个行号,可以用于分页查询
9)聚合统计:select sum(usernum) from t_account where year = '2012';
avg,sum,max,min,count,group by
select areaid,sum(mony) from t_account group by areaid;
select areaid,sum(money) form t_account group by areaid having sum(money)>16900;
2)连接查询
1)多表内连接查询:select o.id,o.name,ad.name,ot.name from t_owners o,t_ownertype ot,t_address ad where o.ownertypeid = ot.id and o.addressid = ad.id;
2)左外连接查询:left join
3)右外连接:right join
3)子查询
1)where 子句中的子查询
1)select * from t_account where year = '2012'and month='01' and usenum>(select avg(usenum)from t_account where year = '2102' and month='01');;
2)select * from t_owners where addressid in(select id from t_address where name like '%花园%');
2)from子句中的子查询
select * from (select o.id 业主编号,o.name 业主名称,ot.name 业主类型 from t_owners o,t_ownertype ot where o.ownertypeid = ot.id)where 业主类型 = '居民';
3)select子句中子查询--必须为单行子查询
select id,name,(select name from t_address where id = addressid)addressname from t_owners;
4)分页查询
1)select * from (select rownum r,t.* from t_account t where rownum<=20)where r>10;
2)select * form (select rownum r,t.* from(select * from t_account order by usenum desc)t where rownum<=20) where r>10;
5)单行函数
1)字符函数:length,concat,substr
2)数值函数:round,mod
3)日期函数:
4)其他函数:nvl
case when then
6)行列转换
7)分析函数:
用于排名的三个:rank相同的值排名相同,排名跳跃
dense_rank相同的值排名相同,排名连续
row_number返回连续的排名,无论值是否相等
8)集合运算:
union all(并集):返回各个查询所有记录,包括重复
union:返回各个查询所有记录,不包括重复
intersect(交集):返回两个查询共有的记录
select * from t_owners where id<=7
intersect
select * from t_owners where id>=5;
minus(差集)返回第一个查询减去第二个查询记录
9)视图:视图是一种数据库对象,是从一个或多个表导出的虚表,存储了要执行检索查询语句的定义,即它存储不是数据,而是一条sql语句
优点:1.简化数据操作
2.着重于特定数据
3.视图提供了一个简单有效的安全机制,可以定制不同客户对数据的访问权限
4.提供向后兼容性
语法:
创建或修改视图:create view view_name
as select * from t_owners where ownertypeid = 1;
然后执行语句:select * from view_name;
删除视图:drop view..
10)物化视图:视图每次访问是都会将查询语句执行一次,为了避免这种情况,可以将查询结果集存储导一个物化视图(实体化视图)
物化视图建立的一个副本,类似一张表,需要占用存储空间。
语法:create meterialized view view_name
as select ad.id,ad.name,ar.name from t_address ad, t_area ar where ad.areaid = ar.id;
然后执行语句select * from view_name;
11)序列:oracle提供的用于产生一系列唯一数字的数据库对象
语法:create sequence 序列名称
select 序列名称.nextval from dual;
select 序列名称.currval from dual;
12)索引:用于加速数据存取的数据对象,合理的使用索引可以大大降低io次数,从而提高数据访问性能,相当于一棵树,树的节点存储的是每条记录的物理地址rowid
语法:
create index 索引名称 on 表名(列名);
常见索引有:普通索引,位图索引,唯一索引,复合索引,反向键索引
13)存储函数与存储过程:
存储函数:自定义函数,可以接收一个或多个参数,返回一个结果。
语法:create[or replace] function 函数名称(参数名称 参数类型,参数名称 参数类型。。。)
return 结果变量数据类型
is 变量声明部分;
begin
逻辑部分;
return 结果变量;
end;
测试此函数:
select 函数名(id)from dual;
存储过程:存储于数据库中,是数据库对象的一种。应用程序调用村村过程,执行相应的逻辑,获得相应的结果集表。
语法:create procedure 名称
两者区别:1)
14)数据库优化方法:
1)从数据库的角度:分库分表,读写分离,主表从表
2)从sql语句出发:减少解析时间,*,别名等等
3)尽量减少全表扫描:索引,伪列。。。
38.同步,异步,阻塞,非阻塞
同步和异步关注的是消息通信机制:synchronous/asynchronous communication
1)同步:发出一个调用,没有结果之前,调用不返回--》调用者主动等待调用的结果
2)异步:调用发出后,调用就直接返回了,没有结果--》而是通过一个通知或者回掉函数来处理这个调用
举例:你去书店买一本书,如果是同步通信机制,老板会说你等一下,我去查查,然后就去查结果了,查好了告诉你(返回结果)
而异步通信机制则是,老板直接说你先回去,我查好了打电话告诉你,直接挂了电话(没有返回结果),查好后电话回调。
阻塞和非阻塞关注的是程序在等待调用结果时的状态。
1)阻塞调用是指调用结果返回之前,当前线程会被挂起,调用线程有结果后才会返回
2)非阻塞是指不能立刻得到结果前,该调用不会阻塞当前线程
举例:你去买书,如果是阻塞式调用,你会一直挂起,等待,直到结果,如果式非阻塞,你不管老板如何回复,你自己先一遍玩去了,然后几分钟check一下,看老板有没有返回结果;
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。
老张爱喝茶,废话不说,煮开水。出场人物:老张,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。
1 老张把水壶放到火上,立等水开。(同步阻塞)老张觉得自己有点傻
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。
3 老张把响水壶放到火上,立等水开。(异步阻塞)老张觉得这样傻等意义不大
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)老张觉得自己聪明了。
所谓同步异步,只是对于水壶而言。普通水壶,同步;响水壶,异步。虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。
所谓阻塞非阻塞,仅仅对于老张而言。立等的老张,阻塞;看电视的老张,非阻塞。情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。
39.设计模式
1)单例模式:1.必须只有一个实例 2.必须自行初始化 3.对外提供访问获得的方法
使用场景:只需要一个实例来管理对象,否则容易秩序破坏,失去管理
举例:jdbc操作中,对外提供一个connection时就采用这种饿汉式的单例模式
饿汉式:
public class Singleton{
//在自己内部定义自己的一个实例,只供内部调用
private static final Singleton instance = new Singleton();
private Singleton(){
//do something
}
//这里提供了一个供外部访问本class的静态方法,可以直接访问
public static Singleton getInstance(){
return instance;
}
}
懒汉式:
public class SingletonClass{
private static volatile SingletonClass instance=null;
public static SingletonClass getInstance(){
synchronized(SingletonClass.class){
if(instance==null){
instance=new SingletonClass();
}
}
return instance;
}
private SingletonClass(){}
}
2)装饰者模式:在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能,它通过一个包装对象来包裹真实的对象
特点:1.装饰对象和真实对象要实现相同的接口
2.装饰对象包含真实对象的引用
3.由装饰对象接收请求,然后转发给真实对象,但是可以在转发请求前后增加一些附加的功能,而不改变给定对象的结构。
应用:java IO流时典型的装饰者模式,bufferedWriter包裹一个filewriter,但读写效率提高了很多;
3)工厂模式:一个抽象工厂角色,它只负责具体工厂的创建,然后具体工厂生产子类产品对象,一层层,通过依赖注入达到解耦,复用,后期
方便维护的目的。
举例:SessionFactory-->session-->session.createQuery()---
4)代理模式:一个是真正的你要访问的对象(目标类),一个是代理对象,
真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。
代理模式分为静态代理、动态代理。
静态代理:是由程序员创建或工具生成代理类的源码,再编译代理类。
所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理:Proxy,是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。
5)桥接模式:桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
6)适配器模式:Adapter模式的宗旨:保留现有类所提供的服务,向客户提供接口,以满足客户的期望。
举例:inputstreamwriter(inputstream),对象适配器,将一个字节流输出对象转为字符流输出对象。
40.垃圾回收机制Garbage Collection-->gc
1.典型的垃圾回收算法:
1.标记清除法:即将垃圾先标记,后清除---》但容易产生碎片,过于分散无法有效增加存储空间
2.复制算法:即有两块空间,一块用完了,则把还存活的对象全部复制出来,原来那块直接清理掉---但是缩小了存储空间,原来两块,现在一块
3.标记整理算法:标记后向一端迁移整理
4.分代手机算法:根据对象存活的生命周期将内存划分为若干个不同的区域--》老年代和新生代及永久代,根据不同代的特点分别设置算法回收,如
对于新生代,由于对象挺多,可以采用copy算法
对于老年代,则可以采用标记清除或整理算法
对于永久代,加载类
2.垃圾回收system.gc();
3.怎么才能判定时垃圾:可达性分析法:
在Java中采取了 可达性分析法。该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,
则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,
如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
4.垃圾回收器
1)串行垃圾回收器
2)并行垃圾回收器
3)并发标记扫描垃圾回收器
4)G1垃圾回收期
5,垃圾回收器的配置:
-XX:+UseSerialGC 串行垃圾回收器
-XX:+UseParallelGC 并行垃圾回收器
-XX:+UseConcMarkSweepGC 并发标记扫描垃圾回收器
-XX:ParallelCMSThreads= 并发标记扫描垃圾回收器 =为使用的线程数量
-XX:+UseG1GC G1垃圾回收器
6.GC的优化配置:
-Xms 初始化堆内存大小
-Xmx 堆内存最大值
-Xmn 新生代大小
-XX:PermSize 初始化永久代大小
-XX:MaxPermSize 永久代最大容量