###################java语法基础
1
数据类型级别比较:byte short char -->int >float-->long-->double
从低的级别到高的级别可以进行自动转 ,从搞得级别转到低的级别需要强制类型转换
byte short char -->int .float .long.double
byte short char -- int folat long double
2
break 跳出本层循环
continue:结束本次循环,即将进行下一次循环
3
函数的作用:1)用于定义功能 2)用于封装代码提高代码复用
注意:函数只能调用函数 不能定义函数
4
java的5个内存区:寄存器;本地方法区;方法区;堆;栈
1)栈:存储的是局部变量(函数中定义的变量,函数上的参数,语句中的变量)
主要数据运算完成所在区域结束,该数据就会被释放
2)堆:用于存储数组和对象,也就是实体
每一个实体都有内存首地址值,堆内存中每个变量都有默认初始化值,
堆中有垃圾回收机制
####################面向对象
1
属性是用于存储数据的,直接被访问,容易出现安全隐患,所以在类中属性通常被私有化,并对外提供公共的访问方法
2
成员变量和局部变量的区别:
1)成员变量直接定义在类中,局部变量定义在方法上,参数上,语句上面
2)局部变量在当前的类体中都会生效,而局部变量在当前代码区的大括号内有效,随着大括号的结束,局部变量的作用域开始失效
3)成员变量存储在堆区,随着对象的产生而存在,随着对象的消失而结束
局部变量存储在栈区,随着所属区域的运行而存在,结束而释放
成员变量和静态变量的区别:
1)成员变量所属于对象,也称实例变量
静态变量所属于类,也成类变量
2)成员变量存储在堆,静态变量存储在方法区
3)成员变量只可以被对象调用,而静态变量既可以被对象也可以被类调用
3
构造函数:
所有对象创建时,都需要初始化的时候才可以使用
构造函数与当前类类的名称相同,没有返回值,不需要定义返回值类型
4
构造函数和一般函数的区别:
1)构造函数是在对象创建时,就会被调用,用于对象初始化,而且初始化动作只执行一次;
2)一般函数是在对象创建之后,需要调用的时候才会执行他,而且它可以被调用多次
5
创建一个对象会在内存中做了什么事情?
1)将硬盘上指定的Student.class文件加载到内存里面;
2)执行main()方法,在栈内存中开辟了main方法的空间,然后在main()方法的栈中分配了一个变量student
3)在堆内存中分配了一个实体空间,然后分配了一个内存首地址值,new
4)在该实体空间中进行属性空间分配,默认初始化;
5)对空间的属性进行显示初始化
6)进行实体的构造代码初始化
7)调用构造函数,进行构造函数初始化
8)将首地址复制给student,student变量就指向了该对象
6
封装
封装是隐藏对象的属性和实现细节,对外提供公共访问方法
峰装是隐藏对象属性和实现方法,对外提供公共的访问方法
7
静态代码块 构造代码块 构造函数
######java中的各种设计模式
1 单例模式
解决的问题:保证一个类在内存中的对象唯一
Runtime()方法
如何保证对象的唯一性:1)不允许其他程序创建该类的对象 2)在本类中创建一个本类的对象3)对外提供方法,让其他程序获取这个对象
步骤:
1)私有化构造函数
2)在类中创建一个本类的对象
3)定义公有并静态的方法,并返回该对象
单例模式代码体现
1)饿汉式
public class Single {
//饿汉式单例模式
//1 构造函数私有化
private Single(){}
//创建一个静态的私有的本类的对象
private static Single s=new Single();
//3 创建一个本地的静态方法
public static Single get(){
System.out.println(s);
return s;
}
}
2懒汉式(延迟加载)
//懒汉式单例模式(延迟加载)
//1 构造函数私有化
private Single(){}
//创建一个静态的私有的本类的对象
private static Single s=null;
//3 创建一个本地的静态方法
public static Single get(){
System.out.println(s);
if(s==null) s=new Single();
System.out.println(s);
return s;
}
单例模式:
1)饿汉式:
private Main(){};
private static Main main=new Main();
public static Main test1(){
return main;
}
2)延迟加载
private Main(){}
private static Main maiin=null;
pbulic static Main test2(){
if(main==null){
main=new Main();
}
return main;
}
######继承
1
继承的好处
1)提高了代码复用2)类与类之间建立了联系
2)研究父与子类的相互调用
在继承的时候,子类对象可以调用父类不是私有的方法和成员变量;
父类对象不能调用子类所特有的方法;会出现编译错误;
上转型就是指父类的引用指向了子类的对象,在这个过程成,对象调用子类重写父类的方法,还可以调用父类所特有的方法,而对于子类所特有的方法,不能调用,会出现编译出错的问题
下转型就是把指向子类对象的父类的引用赋值给子类,在基于上转型的基础上,下转型需要强制类型转换,而上转型不需要,可以调用父类子类所具有的单独的方法以及子类所重写的父类的方法。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
这里用代码的形式举例说名上下转型继承问题
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
public class Test {
public static void main(String[] args) {
//父类对象
Father f=new Father();
System.out.println(f.a);
System.out.println(f.b);
f.show1();
f.father();
//子类对象
Son s=new Son() ;
System.out.println(s.a);
System.out.println(s.b);
s.show1();
s.son();
//父类对象调用子类的方法
System.out.println("父类对象调用子类的方法");
//f.son(); //没有这个方法
//子类对象调用父类的方法
System.out.println("子类对象调用父类的方法");
s.father();
//总结:在继承的时候,子类对象可以调用父类不是私有的方法和成员变量
//上转型:
System.out.println("上转型----父类引用指向子类的对象");
Father f1=new Son(); //父类引用指向子类的对象
f1.show1();
f1.father();
//f1.son(); //编译出错
//总结:上转型就是指父类的引用指向了子类的对象,在这个过程成,对象调用子类重写父类的方法
//还可以调用父类所特有的方法,而对于子类所特有的方法,不能调用,会出现编译出错的问题
System.out.println("下转型");
//把指向子类对象的父类的引用赋值给子类叫做下转型
Son s1=(Son)f1; //下转型
s1.father();
s1.show1();
s1.son();
//下转型调用的方法有:父类、子类所特有的方法,以及子类所重写的父类的方法
}
}
@@@@@@@@@@@@@@以下是运行结果展示:
0
0
father show1()
father........
0
0
son show1()
son.....
父类对象调用子类的方法
子类对象调用父类的方法
father........
上转型----父类引用指向子类的对象
son show1()
father........
下转型
father........
son show1()
son.....
@@@@@@@@@@@@@@@@@@@@@@@
2
定义一个抽象类
pubic abstract class Virtual{}
#######iso七层模型
物理层 ----为了完成信号的传输
数据链路层---
网络层
传输层
会话层
表示层
应用层
物理层数据链路层 网络层 传输层 会话层 表示层 应用层
3
1)成员函数 ---编译看左边 运行看右边
2)成员变量 ----编译看左边 运行看左边
3)静态函数----编译看左边 运行看左边
4内部类与外部类
1)内部类可以直接访问外部类 外部类访问内部类需要建立内部类的对象
2)内部类可以被修饰为Publlic private static
***********************2018年9月13日 看到18/67
3)题目:问什么内部类可以直接调用外部类的成员呢?
答:在内部类中有一个外部内的引用,这个引用就是Outer.this;
4)内部类可以定义在外部类的成员位置:成员内部类;
可以定义在外部类的局部位置上,
5)匿名内部类
没有名字的内部类;其实就是一个匿名子类的对象,前提是内部类必须继承或者实现一个接口
@@@@@@@@@@@@@@@@@举例实现匿名内部类
//匿名内部类
public class Outer1 {
public static void main(String[] args) {
new Object(){
public void oo(){
System.out.println("oooooo");
}
}.oo();
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@运行结果
oooooo
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#######异常
1 常见的异常:
IndexOutOfBoundsException 下标越界异常
NullPointerException 空指针异常
ClassCastException 类型转换异常
2
所有的异常都继承自Throwable 然后是Error Exception
3
同时捕获多个异常的时候,子类在前,父类在后
4 自定义异常
1)定义一个子类,继承Exception或者RuntimeException
2)通过throw或者throws进行操作
注:throws定义在方法上,表示可能会抛出此类异常
#####包
1 包访问权限
作用范围 public protected default private
当前类 OK OK OK OK
同一包 OK OK OK NO
子类 OK OK NO NO
所有类 OK NO NO NO
2 常见的java软件包
1)java.lang: java的核心包
2)java.awt:定义的都是Java图形界面开发的对象
3)java.swing:提供所有的windows桌面应用程序
4) java.net:用于Java网络编程的对象都在该包中
5)java.io:文件io inout ouput
6) java.util:java的工具包,如集合框架所需要
7)java.applet:用于定义java客户端小程序
8)jar:java的压缩包
#############多线程
1进程
一个进程可以有多个线程,每个线程都会有自己独立的执行空间,方法区,变量
2 线程
创建线程的方法
1)继承Thread 子类复写父类的run()方法,使用的时候通过创建Thread类的的子类对象,创建线程对象,然后用线程对象调用start()启动线程
2)实现Runnable接口 覆盖接口中的run()方法,然后用Thread创建线程的对象,然后用此对象调用start()启动线程即可
通常实现多线程都会使用实现Runnable接口这种方法,可以避免java单继承的局限性
3)线程池
4)clonenable接口的实现
3 同步
在操作共享数据的代码的时候,访问时只能让一个线程进去访问,此线程执行完毕退出之后,别的线程才能再对此共享数据代码进行访问
同步的好处:解决了线程安全的问题
弊端:相对降低了性能,产生了死锁
同步的前提:1)多个线程,至少是两个2)他们使用的是同一个锁
同步的表现形式
1)同步代码块
synchronized(对象){
需要被同步的代码块;
}
2)同步函数
同步代码块和同步函数二者的区别:
1)同步代码块使用的锁可以是任意的锁;
2)同步函数使用的锁是this,静态同步函数的锁是该类的字节码文件对象
线程的等待唤醒机制(方法)
sleep(Thread类中):导致线程暂停执行指定的时间,让出cpu给其他的线程,依然保持监控;线程不会释放对象锁
wait(Object类中):线程会释放对象锁,同时将线程对象存储到线程池中
notify(Object类中):唤醒线程池中的某一个线程
notifyAll(Object类中):唤醒线程池中的所有线程
wait()和sleep()区别
1)wait是Object类中的方法,sleep是Thread中的方法
2)sleep释放执行权,不会释放锁;wait释放执行权,释放锁
3)sleep必须指定时间,时间到自动从冻结状态转换成运行状态;wait可以指定也可以不指定时间;
##############String字符串
1 string
1)String类型的字符串一旦被初始化,就不可以被改变,存放在方法区的常量池中
但可以改变对象的引用
2)length():获取字符串的长度
String a="abcdefg";
System.out.println(a.length()); //结果是7
3)
######StringBuffer字符串缓冲区
初始容量16个字符串
1StringBuffer
特点:1)可以对字符串内容进行修改2)是一个可变长度的3)缓冲区可以存储任意类型的数据4)最终需要变成字符串5)是一个容器
方法:
1)添加:append(data) insert(index,data)
2)删除:delete(start,string) delete(index)
3) 修改:
4)查找
5)获取子串
6)反转:StringBuffer.reverse(); //字符串反转
######StringBuilder字符串缓冲区
初始容量16个字符串
使用方法跟StringBuffer一样
StringBuffer和StringBuilder区别:
StringBuffer线程安全
StringBuilder线程不安全
StringBuilder>StringBuffer>String
单线程操作的时候选择StringBuilder效率高;
多线程操作,使用StringBuffer安全
######集合框架
1集合和数组的区别:
1)数组固定长度,集合可变长度
2)数组可以存储基本数据类型,也可以存储引用数据类型,集合只能存储引用数据类型
3) 数组存储的元素必须是同一个数据类型,但是集合存储的对象可以是不同的数据类型
2 Collection
1)List
2)Set
1)将集合变成数组 list.toArray();
3 迭代器 Iterator接口,作用是取出list集合中的元素
3 List ArrayList LinkList Vector区别:
List:有序,元素有索引 可以重复
ArrayList:底层是数组 适合查询操作 不同步
LinkList:底层是链表 适合元素增删 不同步
vector:同步的ArrayList 速度慢
3 Set
1)Set接口取出元素的方式只有一种,迭代器
HashSet
1)hashset底层是哈希表,线程不同步,无序,高效,保证元素的唯一性
2)LinkedHashSet:有序,hashset的子类
3)TreeSet:对Set集合中的元素进行指定顺序的排序,不同步,TreeSet底层的数据结构就是二叉树 元素需要实现Comparable接口,确定元素在TressSet数据结构中的位置
保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果0,表示对象重复,不存
4)TreeSet集合排序的两种方式
Comparable和Compartoru区别;
1)让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo()方法
2)让集合自身具备比较性,需要定义一个实现了Compartor接口的比较器,覆盖compare方法,并将该类参数作为实参传递给TreeSet集合的构造函数
4Map集合
hashmap 底层是哈希表数据结构,是线程不同步的,键和值都可以空;
hashtable:底层是哈希表数据结构,是线程不同步的,键和值不可以为空;
Set set=map.entrySet(); //map集合的遍历
5 Map和Collection区别:
都是集合接口
1)collection中元素一次存取一个,map中一次存取一双
2)collection是单列集合,map是双列集合
3)map中键和值之间有一一对应映射关系
6 Collection 和Collections区别:
Collection是一个接口,旗下子接口有List H和Set
Collections的出现给集合操作提供了更多的功能,无需创建对象,都是静态方法,直接用Collections调用即可。
Collections.sort(list); //排序
Collections.max(max);//集合中的最大元素
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Collections.sort(list); //对集合中的元素进行自然排序
//迭代器迭代集合中的元素
Iterator it=list.iterator();
while(it.hasNext()){ //如果有下一个元素
System.out.println(it.next());
//打印出来,并将光标指向下一个元素
}
Object[] b=list.toArray(); //将集合转换成数组
for(int i=0;i
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
7 Arrays.aList(arr);
用于将数组转换成list集合
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
String [] arr={"lisi","ff","sa","dds","ds"};
List
System.out.println(list);
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
注意事项:
1)数组的长度是固定的,不可以使用集合对象增加或者是删除元素
2)Collection在jdk1.5之后,有了一个父接口Iterable,这个接口的出现将iterator方法进行抽取,提高了扩展性
#######泛型
1泛型的优点:
1)将运行时问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题;
2)避免了强制类型转换的麻烦,
3)泛型是存在于编译时期,在运行的是没有的,它已经被擦出了,编译器在检查检查了泛型的类型是正确的,在生成的类文件中是没有的,泛型的擦除。
4)当类中的操作引起的数据类型不能确定的适合选择使用泛型
5)泛型的通配符:?表示
6)使用泛型的时候,等号两边的泛型必须保持一致
####IO流 用于处理设备上的数据
1字节流:
处理数据的流对象,计算机中最小的数据单元是字节,字节可以处理设备上所有数据,字节流也可以处理字符数据;
2 字符流:
将字节流和编码表封装成对象,这个对象被称为字符流,只要操作的是字符数据,优先选择字符流;
3流的操作
1)明确数据源:如果需要读取,就是InputStream
写入:OutputStream
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//写入
Scanner sc=new Scanner(System.in);
String string=sc.nextLine();
byte b[]=string.getBytes();
File file=new File("d.txt");
FileOutputStream out=new FileOutputStream(file);
out.write(b);
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//读取
File file=new File("d.txt");
FileInputStream in=new FileInputStream(file);
byte b[] =new byte[1000];
in.read(b);
String string=new String (b);
System.out.println(string);
####socket
客户端
Socket socket=new Socket("localhost",端口号);
服务端
ServerSocket server=new ServerSocket(端口号);
Socket socket=server.accept(); //建立连接
2 tcp udp区别:
tcp:面向连接 可靠的 传输大量数据 慢
ucp:面向无连接 不可靠的 传输少量数据 块
tcp: 连接 可靠的 传输大量数据 速度慢
get和post请求就是tcp连接,get产生一个数据包 post产生两个数据包
get数据大小有限制 不安全 post无限制 安全可靠
进程和线程、程序的区别
答:线程是进程的一个实体,是CPU调度和分配的基本单元;
同一个进程中的线程共享进程的全部资源(程序计数器 寄存器 栈)
进程是系统进行资源调度分配的一个独立单位
程序是一组指令的集合,由多个进程共同完成,是一个静态的实体,没有执行的含义
线程是进程的一部分,被称为轻量级或者轻权级进程;
一个没有线程的进程被看作是单线程,
系统不会为线程分配资源,线程组只能共享它所属进程的资源
程序是一组指令的集合,没有执行的含义,而进程是一个动态的实体,有自己的生命周期,一个程序可以有0个或者多个进程,京城具有并发性和交往性。
OSI七层网络模型
物理层 :定义网络设备通过发送数据的物理方式
数据链路层 :定义操作系统连接的程序,封装数据包为数据帧,监测和纠正数据传送的发生的错误 (ATM FDDI)
网络层 :定义网络设备中如何传输数据
(IP IPX)
传输层:管理端到端的信息传输,提供可靠且有序的数据包传送,提供面向无连接的数据包传送(TCP UDP SPX)
会话层 :管理用户会话和对话,控制逻辑 报告上一层发生的错误
表示层:掩盖不同系统间数据格式的不同 数据编码解码 加密解密
()
应用层 :用于在网络中进行通信和数据传输的接口
(TELNET HTTP FIP NFS SMTP )
ATM FDDI
IP IPX
TCP UDP SPX
TELNET SMTP FIP NFS
Interent内部保留IP地址
根据用途和安全性级别的不同,IP地址分为:公公地址 私有地址
公共地址在Internent使用,可以在interent中随意访问;
私有地址:只能在内部网络中使用,只有通过代理服务器从哪能与Internt通信
一个机构如果想要连入Interent必须申请公共Ip地址
串行通信的方向性结构
单工数据传输:只支持在一个方向上传输;
半双工传输:支持双向传输,但是在同一时间只支持一个方向上的数据传输;
全双工数据通信允许数据在两个方向上进行数据传输;
线程的生命周期:是一个动态的执行过程
新建状态:当创建一个Thread类对象,而没有调用start()方法时候 新建状态
就绪状态:线程启动,等待被分配给CPU时间片 t1.start();
运行状态:线程获得CPU资源正在执行任务(run()方法),除非线程主动放弃CPU资源,或者有优先级更高的线程进入,线程会一致运行到结束;
堵塞状态:某些原因导致正在运行的当前线程让出CPU并暂停自己的执行,这就是进入都塞状态
1)sleep():正在睡眠;
2)wait():正在等待,调用notifty()回到就绪状态;
3)被另一个线程所阻塞:调用suspend() 调用resume()可恢复
死亡状态:当前线程执行完毕或被其它线程杀死,线程就进入死亡状态。
1)自然终止:正常运行run()方法结束之后终止
2)异常终止:调用stop()方法
注意:一般不建议使用stop和desory方法使当前线程处于死亡状态,stop会产生异常,destory不会释放线程锁,所以不建议使用;
####java中产生随机数的集中方法和相互之间的比较
1)Math.random();方法:产生随机数 ,小数 在多少之间就乘以多少;Math.random()*100; 产生100以内的随机数 这个如果取整数的时候,就需要用int取整;
2)Random r=new Random(); 产生随机数
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
System.out.println(((int)(Math.random()*100)));
Random r=new Random();
int a=r.nextInt();
System.out.println(a);
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@
hashmap和hashtable:
hashmap初始大小是16 以2的指数形式增加;
hashtable初始大小是11 *2+1形式增加
进程和线程的区别
1)进程是资源分配和调度的一个独立的单元,而线程是CPU调度的基本单元;
2)进程结束后它所拥有的所有线程都将销毁,而线程结束后不会影响同个进程中的其他的线程的结束
3)线程是轻量级的进程,他的创建和销毁所需要的时间都比进程小很多,所有操作系统中的执行功能都是创建线程来实现的;
4)
线程中执行的时候一般都会进行同步和互斥,因为他们共享同一进程的所有资源
常见的web错误代码:
1开头的表示消息 2开头的表示成功 3重定向 4请求错误 5服务器错误
401访问被拒绝
403禁止访问
404表示文件或资源未找到
500内部服务器错误
505Http版本不支持
冒泡排序
平均时间:o(n*n)
最好时间:o(n)
最坏时间:o(n*n)
具有稳定性
空间复杂度为o(1)
n小的时候比较好,适用于算法简单的时候
插入排序
平均时间:o(n*n)
最好时间:o(n)
最坏时间:o(n*n)
具有稳定性
空间复杂度为o(1)
适用于大部分已经排好序的序列
直接排序
平均时间:o(n*n)
最好时间:o(n*n)
最坏时间:o(n*n)
不具有稳定性
空间复杂度为o(1)
n小的时候比较好,适用于算法简单的时候
快速排序
平均时间:o(nlogn)
最好时间:o(nlogn)
最坏时间:o(n*n)
不具有稳定性
空间复杂度为o(logn )
n大的时候比较好
堆排序
平均时间:o(nlogn)
最好时间:o(nlogn)
最坏时间:o(nlogn)
不具有稳定性
空间复杂度o(1)
n大的时候比较好
归并排序
平均时间:o(nlogn)
最好时间: o(nlogn)
最坏时间:o(nlogn)
具有稳定性
空间复杂度o(n)
n大的时候比较好
希尔排序
平均时间:o(nlogn)
最好时间: 与长度有关系
最坏时间:o(nlogn)
不具有稳定性
空间复杂度o(1)
n小的时候比较好
总结:
冒泡 插入 归并排序具有稳定性
冒泡 直接 希尔 适合于n小的时候进行排序
插入 适合于大部分已经排好的
快速 堆排序 归并 适合于n比较大的
快排的空间复杂度是o(nlogn)
归并排序的是o(n)
其他的排序的空间复杂度都是o(1)
@@@@@@@@@@@@@@@@@@@@@@