1、面向过程和面向对象编程思想比较
//
面向过程:偏重实现步骤
//
面向对象:从对象功能属性出发考虑问题
2、类的由来与抽象
//
关键字:
class
//
如何抽象一个类的步骤,需要考虑的原则
//1
、类具有哪些名词属性(对应类中属性)和功能(对应类中方法)
//2
、将此类事物共同的基本属性和功能放到父类中
//3
、将与其他类共有的方法放到接口中
//4
、接口的分类:通过单一职责原则将功能剥离,通过接口隔离原则将以剥离的接口重新分类、考虑后期维护的时候是否符合开闭原则进一步优化接口结构
//5
、类对象的创建通过
new
关键字 后跟相应的构造函数
//6
、构造函数特征:与类名相同且没有返回值的函数
3、封装与访问权限
//private\protected\default\public
//
将类属性私有化,并提供
get()
或者
set
()访问和修改私有属性
4、继承与接口
//
关键字:
extends\interface\implements\abstract
//1、接口里面可以定义属性,但是属性的修饰必须为public static final,而且必须被初始化
//2、接口里面的函数是默认修饰为public abstract
//Java
不支持多继承通过接口实现类似多继承的效果
5、抽象方法与抽象类
//
关键字:
abstract
// 1、抽象方法是由abstract修饰的,只能位于抽象类里面,
抽象类是由
abstract
修饰的,
但是抽象类里面不一定要有抽象方法
// 2、抽象方法没有方法体,如需实现它的访问属性不能被设置为private、static
//3、抽象方法需要被实现,所以也不能被final修饰
// 4、如果父类里面存在抽象方法,子类可以选择是否实现该方法
// (1)如果要实现,方法的“修饰属性”以及方法的“标示特征”都相同
// (2)如果不实现,将父类方法copy一份到子类中,然后将子类修改为abstract修饰的抽象类
6、多态与函数特征标
// Java 多态的使用条件
// 1、必须有继承,说明多态这种关系是存在于子类与父类之间的
// 2、必须有重写,塑造多态的环境
// 3、父类的引用必须指向子类对象,创建这种多态的关系
// 4
、如果判断两个函数是否是一个函数,答案通过函数特征标,函数特征标包括:函数的名字、函数的参数类型和顺序、函数的参数数量
7、内部类定义与对象创建
// 内部类:普通内部类、静态内部类、局部内部类、匿名内部类
// 普通内部类:(成员内部类)
// (1)[访问权限修饰] class 类名 {}
// (2)private、proteced、 public 、 默认的访问权限都可以、final….
//
成员内部类创建对象
+
方法调用
//
InnerTest out = new InnerTest();
//
InnerTest.InnerInner innerInner = out.new InnerInner();
//
innerInner.getTestA();
// 静态内部类
// (1)static [访问权限修饰] class 类名 {}
// (2)private、proteced、 public 、 默认的访问权限都可以、final….
//
静态内部类创建对象
//
InnerTest.StaticInnerInner staticInner = new InnerTest.StaticInnerInner();
//
InnerTest.StaticInnerInner.testStaticMethod();
//
staticInner.testMethods();
// 局部内部类
// (1)方法体或者代码段内部定义的类
//
匿名内部类(未讲)
//
局部内部类的创建和调用
//
out.test();
8、变量与作用域
//所有的变量都只能先声明后使用
//局部变量 :方法体内部,随函数(方法)调用(执行)而被创建,只能在函数内部使用
//全局变量:方法体外部,在局部变量作用域内,具有同名的变量,则全局变量会被隐藏
//
特别注意静态变量只会初始化一遍
9、数组的声明与定义
//1、数组的定义:
//
(1)用来存储相同数据类型的(目的是告诉内存,程序每次操作的内存空间是该类型在内存中所分配的大小),
//
(2)一块连续的内存空间,遍历速度相比较链表要快,插入操作通常比链表效率要低
//
1、静态声明
//
char a[] = {‘H’,’E’,’L’,’L’,’O’};
//
2、动态声明
//
int[] b = new int[5];
//
int[] c = new int[]{0,1,2,3,4};
10、字符串与数组
//字符串的创建方式
//
char[] value = {‘E’, ‘F’, ‘G’, ‘H’};
//
byte[] bytes = {65, 66, 67, 68};
//
String str = new String(bytes);
//
String str2 = new String(value);
//
String str3 = “IJKLMN”;
//字符串的比较:
//比较顺序:从左向右挨个字符串进行比较,以较短的字符串依次去与较长的字符串里对应位置的字符进行比较
//
1、如果在较短的字符串的长度范围内存在某个字符与较长字符串内的字符比匹配则返回两个字符的差
//
2、如果较短的字符串长度范围内对应位置的字符都相同,然后在比较两个字符串的长度
11、异常处理与继承
//
通过try catch finally捕捉并处理异常
//
1、try用来监控可能发生异常的代码段,try后可跟多个catch代码段
//
2、用catch来处理try到的异常
//3
、
catch
异常要先捕获子类异常,层层捕获方能疏而不漏
12、Java API的学习使用
//
以
String
类为例,了解
JAVA API
的使用,同时进一步学习了一个类的层次结构以及如何结合
API
学习一个类
13、包装类
//
1
、包装类是
Java
为基本数据类型赋予对象操作的功能
//2
、基本类型包装成包装类型的过程称为装箱,反过来包装类型转换为基本类型的过程称之为拆箱。
//3
、包装类除了可以与基本类型之间互相转换外还可以与
String
类型之间互相转换,原因是包装类和
String
类都提供了两种类型转换的方法
14、集合框架
//
集合框架的特点:数据可重复或不重复、 有序或无序、可同步访问或可非同步访问
//Collection
超级接口
//HashMap\ArrayList
可变非同步
//Vector\Stack
同步访问
15、软件开发周期
//
周期各个阶段:提出问题
->
需求分析
->
总体设计
->
详细设计
->
编码
->
维护
1)
需求分析:根据用户提出的问题、进行数据采集、在可行性的基础上分析出,用户的真是需求和软件的大体功能模块;此阶段的结果是生成需求分析文档;
2)
总体设计:按照需求分析的文档将软件模块进一步设计得出软件总体的系统结构;此阶段结果生成系统结构图;
3)
详细设计:根据系统结构图对系统的各个子系统模块进行详细的设计,例如按钮的形状、图标的尺寸、类的结构;此阶段的结果将作为编码的指导手册;
4)
按照代码详细设计图同时考虑到后期的维护和扩展进行编写代码
5)
维护
//
扩展:自己学习几种常用的开发模型
16、总结作业:
//1
、学生信息管理系统
//2
、运算符号表
17、进程\线程
//
进程:是动态运行着的,进程包含共有资源
+
线程
//
线程的创建方式
Runable+Thread
//
线程的状态
生命周期:创建
-start()-
就绪
-CPU-
阻塞或者运行
–
结束
//
线程分类
用户线程:前台运行
守护线程:后台运行,用户线程结束后随
JVM
结束工作,例如一些监听线程、垃圾回收线程,补充测试工具:
JDK\bin
文件下
jstat.exe
生成线程快照,帮助定位程序存在问题
1、
通过
start()
启动、
run
()方法执行完成声明结束
2、
针对循环执行的线程,正确的停止方法是通过终止标示完成的,一般是
volatitle
修饰的
boolean
变量,而系统提供的
stop
()会直接终止线程是不够友好的,
interrupt
()受到
sleep
()、
wait()
等方法的
clear
状态的影响
3、
争用条件:多个线程争夺同一资源的使用权,导致资源“损失”
4、
Join
()迫使其他方法在当前线程执行结束之前不占用资源且处于等待状态,保证当前线程优先执行
//
线程的同步与互斥
1、
同步
=
》线程的通信
wait()/notify()/notifyAll()
2、
互斥
=
》线程之间制约
sychronized
块
//Runnable VS Thread
1、
Runnable
可以解决
java
多继承的问题,区别于
Thread
2、
Runnable
适合解决多线程共享同一资源的问题(调用同一
Runnable
对象的
run()
方法)
//
线程的进阶
1、
JMM
(
Java Memory Model
)
描述
Java
程序中各种变量的访问规则,以及
JVM
中读写变量的底层细节,主内存与工作内存的关系
规定一:线程的工作内存不能直接将数据写入到主内存中
规定二
:
线程不能操作其他线程的工作内存,只能操作自己的工作内存
结合上面两条规定,线程间的共享变量,必须通过与主内存之间的通信,才能实现共享变量的可见性
2、
Locks&Condition
3、
线程安全性
(1)
原子性与可见性
.
可见性:一个线程对共享变量值的修改,能够及时的被其他的线程看到。语言层面解决
:synchronized/volitile
.
共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量
(2)
JMM
对
synchronized
的两条规定
.
线程解锁前,必须把共享变量的最新值刷新到主内存中
.
线程加锁时,将清空工作内存中的共享变量的值,从而在使用共享变量的时候需要重新从主内存中重新读取最新的值(
Note:
加锁和解锁用的是同一把锁)
.
原子性:同步
(3)
指令重排序:重排序后代码书写顺序和实际执行顺序可能不同,重排序是编译器或者处理器为了提高程序性能而做的优化:编译器优化、指令集并行、内存系统重排序等
,
在单线程不会给内存带来可见性的问题,多线程却无法保证
(4)as_if_serial
无论如何冲排序,程序执行结果应该与顺序执行的结果一致
(5)volatile
实现内存可见性
.volatile
深人理解:通过加入内存屏障和禁止重排序优化来实现的
.volatile
通俗的理解:每次对强迫调用线程重新读取最新工作内存数据
.volatile
不能对自身值复合操作是不保证原子性的,例如
num++
,
low<up;
.volatitle
不保证原子性操作解决方法:
synchronized\JDK 1.5
引入的
ReentrantLock
和
AutoicInterger
类
(6)64
位(
long\double
)多线程可能不会保证原子性操作
(
7
)死锁
4、
多线程编程常用交互模型
(1)
生产者消费者
(2)
读写锁
(3)
Future
(4)
Worker Thread
5、
Java5
并发编程工具
(1)
Java.util.concurrent
(2)
线程池
ExecutorService
(3)
Callable & Future
(4)
BlockingQueue
18、I/O操作
//
文件编码
1、
java
双字节编码格式
utf-16be
2、
不同编码格式,字节序列可能不同,如将某一编码格式的字节序列装换成字符串,采用生成它相同的编码格式进行转换
//File
类的使用
1、
java.io.File
表示文件或者目录,只用于表示其信息,不可用于文件内容的访问
2、
过滤、遍历
(
子目录
)
操作
(
1
)
exists()\isDirectory()\list()\listFiles()\
//RandomAccessFile
的使用
1
、提供对文件内容的访问,即可以读写文件
2
、支持随机访问文件内容,可以访问文件的任意位置
3
、
java
文件模型:在硬盘上是
byte
存储的,是数据的集合
4
、文件操作:两种模式
rw\r
RandomAccessFile raf = new RandomeAccessFile(file,
“
rw
”
);
5、
文件指针,打开文件时文件指针指向文件的开头
6、
write()\read()\seek
基于字节的操作方法
7、
各种数据类型的读写,以各种进制形式输出
//
字节流和字符流
1、
InputStream\OutputStream
2、
File…\Data…\Buffered…
3、
EOF = end
对到
-1
就读到了结尾
4、
FileInputStream
文件流的读取操作
read()
重载方法的理解
5、
装饰者模式
(1)
装饰者与被装饰者都集成同一个父类
(2)
都重载了父类的需要被装饰得方法
(3)
动态的为被装饰者添加或者删除功能(方法)
(4)
目的:降低类继承的耦合性
6、
字符流
(1)
InputStreamReader
就是将
byte[]
转成
char
的桥梁,遵循一定的编码格式
(2)
OutputStreamWriter
就是将
char
转成
byte[]
的桥梁,遵循一定的编码格式
(3)
byte byte byte=>byte[]
文件
(4)
char
文本, 文本文件
7、
对象流
//
对象的序列化和反序列化
(1)
ObjectInputStream\ObjectOutputStream
(2)
对象的序列化:
Object
转换成
byte[]
(3)
对象的反序列化:
byte[]
装换成
Object
(
4
)实现序列化接口,才能实现对象的序列化