所有编程语言的最终目的是提供一种“抽象”:汇编语言是对基础机器的少量抽象;命令式语言是对汇编语言的抽象;
在问题和方案之间,程序员必须建立起联系:
以前的语言例如PROLOG将问题都归纳为决策链,每种方法都有自己特殊的用途,适合解决某一类问题; 面向对象可以利用一些工具表达问题空间内的元素,不必受限于特定类型的问题。
对象:将问题空间中的元素以及他们在方案空间的表示物称为对象,有自己的特征和行为。
有类和实例。
亚里士多德或许是研究“类型”概念的第一人:谈及“鱼类和鸟类”。
所有对象都属于某一系列对象的一部分,这些对象具有通用的特征和行为,这就是类:Class.
接口:向对象发出请求的入口方法,规定了可对一个特定对象发出哪些请求。
类创建者目标:从头构建一个类,只开放必要开放的东西,其他所有细节隐藏起来;客户程序员无法修改,保证安全。
为什么要隐藏:
原因1:防止客户程序员接触他们不该接触的东西;
原因2:允许库设计人员修改内部结构,不用担心它会对客户程序员造成影响,达到解耦的作用。
Java三个显式关键字以及一个隐式关键字来设置类边界:public,private,protected;friendly
代码或设计方案的重复使用是面向对象的程序设计提供的最伟大的一种杠杆。
组织:类的对象可以置入一个新类中,例如一辆车包含一个变速箱。
利用现有的数据类型,进行克隆,提高代码复用,提高效率。
上溯造型:把衍生类型当作它的基本类型处理的过程。
多形性(polymorphism):将一条消息发送给对象时,如果并不知道对方具体类型是什么,但采取的行动是正确的,这种情况。
动态绑定:面向对象用来实现多形性,编译器和运行期系统会负责。
抽象的基础类和接口:abstract;我们希望基础类只为自己的衍生类提供一个模版,可以定义一些函数。
interface在抽象类的概念上更延伸一步,禁止所有函数的定义。
内存池中动态创建对象。
集合:只有在运行的时候知道需要多少对象,所以需要一个容器。
集合遍历的类:1.1叫Enumeration,1.2叫Iterator.
单根结构:所有的类都应从单独的一个基础类继承:Object类。
可以方便的实现垃圾收集器:与此相关的必要支持可以安装在基础类中。
c++并不是单根结构:效率和控制之间的权衡;单根结构会带来程序设计上的一些限制;加大了与c的兼容;
单独的一套机制,和程序语言结合在一起,不影响业务程序逻辑。
java的多线程机制已内建到语言中,且在Object对象这一级支持,也提供锁。
一切都是对象,用句柄操作对象。
所有对象都必须被创建。
数据保存的地方:
寄存器:位于处理器内部;
堆栈:ram区域;主要存放对象句柄。
堆:java对象
静态存储:static;也是位于ram具体区域
主要类型:不是用new创建,而是创建一个并非句柄的“自动”变量,置于堆栈中,能够高效的存取。
boolean:1位
char:16位
byte:8位
short:16位
int:32位
long:64位
float:32位
double:64位
高精度数字:
biginteger:任意精度的整数
bigDecimal:任意精度的定点数字
静态stastic/类相关:不与任何对象相关,所以不需要创建对象就能调用。
==是比较句柄;equals()方法默认是比较句柄,如果有需要需要重写比较值。
逻辑运算符的短路:这意味着只有明确得出整个表达式真或假的结论,才会对表达式进行逻辑求值;能提高性能。
按位运算符:
移位:https://blog.csdn.net/tonysong111073/article/details/79480495
方法过载:overload:方法名相同,自变量不同,返回类型可以不同。
static:执行的时候是在首次生成那个类的一个对象时,或者首次访问属于那个类的一个static成员时。
面向对象一项基本考虑:变与不变分开。
如何选择合成还是继承:一个简单的原则是是否需要从新类上溯造型回基础类,若必须上溯,就需要继承。
final:
final数据:表示值不能被修改。
final方法:表示不希望被衍生类重写。
final类:不希望被继承。
hashTable与hashMap的区别:
hashTable是线程安全的,因为有synchronized;但是速度慢。
hashMap是非线程安全,可以接受key,value都是null的情况。
transient:(临时的):序列化的时候表示不需要。
基于字节的操作:
基于字符的操作:
IO常用类:
文件流:FileInputStream/FileOutputStream, FileReader/FileWriter
包装流:PrintStream/PrintWriter/Scanner
字符串流:StringReader/StringWriter
转换流:InputStreamReader/OutputStreamReader
缓冲流:BufferedReader/BufferedWriter,BufferedInputStream/BufferedOutputStream
没有经过Buffered处理的IO, 意味着每一次读和写的请求都会由OS底层直接处理,这会导致非常低效的问题。
BufferedReader提供一个readLine()可以方便地读取一行.
反射
用户线程和守护线程:是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。
创建多线程的方法:
1.继承Thread类:实现run()方法。
2.实现Runable接口。
3.通过Callable(call方法)和Future创建线程:为了解决任务在执行完了之后无法获取返回结果。
Callable定义的方法是call,Runnable定义的方法是run;
Callable定义的方法有返回值,Runnable定义的方法没有返回值;
Callable定义的方法可以抛出异常,Runnable定义的方法不能抛出异常;
Future模式:去除主函数的等待时间,并使原本需要等待的时间段可以用于处理其他业务逻辑;
如果线程A要等待线程B的结果,那么线程A没必要等待B,知道B有结果,可以先拿到一个未来的Future,等B有结果了再取真实的值。
get获取异步结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
Futrue,Callable通常配合ExcutorService配合使用。
比较这两种方式,建议使用第2种:
java不允许多继承,因此实现了Runnable接口的类可以再继承其他类;
推荐组合而不是继承;
synchronized(同步的):
任何时刻,只可有一个线程调用特定对象的一个synchronized方法。
每个对象都包含了一把锁,自动成为对象的一部分;
调用任何synchronized方法时,对象都会被锁定,不可调用那个对象的其他任何synchronized方法,除非完成操作,释放对象锁。
每个类也有自己的一把锁,(作为类Class对象的一部分),所以synchronized static 方法可在一个类的范围内被相互锁定起来,防止与static数据的接触。
线程的状态:
new:线程对象已创建,但尚未启动,所以不可运行;
Runnable:意味着一旦时间分片机制有空闲的cpu周期提供一个线程,那个线程便可立即开始运行;
Dead:
Blocked:线程可以运行,但有某种东西阻碍了它。
线程Blocked的原因:
1.调用sleep:属于Tread的一部分。
2.用suspend()暂停了线程的执行;除非收到resume(),否者不会进入Runnable状态:强烈反对,因为包含了对象锁,容易造成死锁;属于Tread的一部分。
3.用wait()暂停了线程的执行;除非线程收到notify(),notifyAll()消息:属于Object基础类的一部分。
4.线程正在等候一些io操作完成。
5.线程试图调用另外一个对象的同步方法,但那个对象处于锁定状态,暂时无法使用;
yield():Thread类的一个方法,自动放弃cpu,以便其他线程能够运行,但是不会进入blocked状态,还是Runnable状态。
等待和通知:
sleep(),suspend()都不会在自己被调用的时候解除锁定,需要用到对象锁;属于Thread.
wait()方法在被调用的时候会解除锁定,这意味着可在执行wait()期间调用线程对象中的其他同步方法。
wait,notify,notifyAll属于Object.
wait,notify必须在同步方法中使用,必须先获得对象锁。
调用wait之后,会释放获得的对象锁,并放弃cpu,线程进入等待队列;notify之后,会唤醒等待的线程。