final 关键字
-方法:不能被子类重写(override)
-变量:不能被修改
-类:不能够被继承,派生子类java
finally 关键字
与try/catch语句配合使用,即便有异常抛出。 try 语句块执行以后,若是有异常,执行catch,以后会执行finally语句块。若是try有return语句,执行完finally后,再return。算法
finalize方法
此方法是Object类的方法,垃圾回收器回收对象前,若是对象重写的此方法会被调用,主要是作一些对象销毁前的清理动做,通常不建议重写。编程
重载和重写
-重载(overloading)指方法名相同,参数不一样,返回值不影响重载。
-重写(overriding)与父类的方法名相同,函数签名相同设计模式
接口的意义
规范、扩展、回调(回调是能够灵活的让类与类之间创建特定的关系,就像手机中的网络,特别神奇)数组
抽象类的意义
变与不变分开。变化的为抽象方法,交给子类实现。不变的放在父类统一实现。安全
内部类
-匿名内部类 (new 出来的对象)
-静态内部类 与外围类没有关系
-定义内部类 实例须要与外部类this绑定网络
定义内部类从某种意义上实现了多继承,便可以继承父类,同时可使用外围类的属性和方法。数据结构
java 引用类型 多线程
匿名内部类的做用并发
父类的静态方法可否被子类重写,为何?
不能
子类继承父类后,用相同的静态方法和非静态方法,这时非静态方法覆盖父类中的方法(即方法重写),父类的该静态方法被隐藏(若是对象是父类则调用该隐藏的方法),另外子类可继承父类的静态与非静态方法,至于方法重载我以为它其中一要素就是在同一类中,不能说父类中的什么方法与子类里的什么方法是方法重载的体现
Java中==和equals的区别,equals和hashCode的区别
\==是运算符,用于比较两个变量是否相等。
equals,是Objec类的方法,用于比较两个对象是否相等,默认Object类的equals方法是比较两个对象的地址,跟\==的结果同样。若是对象用\==比较,比较内存地址是否相同。
若是两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生一样的整数结果。
若是两个对象根据equals()方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不必定要产生相同的整数结果
将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,若是不相等直接将该对象放入集合中。若是hashcode值相等,而后再经过equals方法判断要放入对象与集合中的任意一个对象是否相等,若是equals判断不相等,直接将该元素放入到集合中,不然不放入。
回过来讲get的时候,HashMap也先调key.hashCode()算出数组下标,而后看equals若是是true就是找到了,因此就涉及了equals。
覆盖equals时总要覆盖hashCode
一个很常见的错误根源在于没有覆盖hashCode方法。在每一个覆盖了equals方法的类中,也必须覆盖hashCode方法。若是不这样作的话,就会违反Object.hashCode的通用约定,从而致使该类没法结合全部基于散列的集合一块儿正常运做,这样的集合包括HashMap、HashSet和Hashtable。
string stringbuffer stringbuilder 区别
String 是不可变的对象, 所以在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,而后将指针指向新的 String 对象,因此常常改变内容的字符串最好不要用String ,由于每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了之后,JVM 的 GC 就会开始工做,那速度是必定会至关慢的。
StringBuffer 对象自己进行操做,而不是生成新的对象,再改变对象引用。因此在通常状况下咱们推荐使用 StringBuffer ,特别是字符串对象常常改变的状况下。
Java.lang.StringBuffer线程安全的可变字符序列。一个相似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但经过某些方法调用能够改变该序列的长度和内容。
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用做 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种状况很广泛)。若是可能,建议优先采用该类,由于在大多数实现中,它比 StringBuffer 要快。二者的方法基本相同
大部分状况 StringBuidler > StringBuffer > String
实例一个对象执行的顺序:静态代码块->main方法-构造代码块->构造方法
抽象类和接口的区别
进程和线程的区别
简而言之,一个程序至少有一个进程,一个进程至少有一个线程。
线程的划分尺度小于进程,使得多线程程序的并发性高。
进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率。
线程在执行过程当中与进程仍是有区别的。每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分能够同时执行。但操做系统并无将多个线程看作多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
-进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源.
一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行.
进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。若是有兴趣深刻的话,我建议大家看看《现代操做系统》或者《操做系统的设计与实现》。对就个问题说得比较清楚。
java多态
面向对象的三大特性:封装、继承、多态。从必定角度来看,封装和继承几乎都是为多态而准备的。这是咱们最后一个概念,也是最重要的知识点。
-多态的定义:指容许不一样类的对象对同一消息作出响应。即同一消息能够根据发送对象的不一样而采用多种不一样的行为方式。(发送消息就是函数调用)
-实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实 际类型,根据其实际的类型调用其相应的方法。
-多态的做用:消除类型之间的耦合关系。
-现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动做,若是当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;若是当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不一样的对象上会产生不一样的结果。 下面是多态存在的三个必要条件,要求你们作梦时都能背出来!
多态存在的三个必要条件 1、要有继承; 2、要有重写; 3、父类引用指向子类对象。
多态的好处:
1.可替换性(substitutability)。多态对已存在代码具备可替换性。例如,多态对圆Circle类工做,对其余任何圆形几何体,如圆环,也一样工做。
2.可扩充性(extensibility)。多态对代码具备可扩充性。增长新的子类不影响已存在类的多态性、继承性,以及其余特性的运行和操做。实际上新加子类更容易得到多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类经过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操做,提升了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤为在处理大量对象的运算和操做时,这个特色尤其突出和重要。
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
什么致使线程阻塞
为了解决对共享存储区的访问冲突,Java 引入了同步机制,如今让咱们来考察多个线程对共享资源的访问,显然同步机制已经不够了,由于在任意时刻所要求的资源不必定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种状况下的访问控制问题,Java 引入了对阻塞机制的支持.
阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操做系统的同窗对它必定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让咱们逐一分析。
sleep() 方法:sleep() 容许 指定以毫秒为单位的一段时间做为参数,它使得线程在指定的时间内进入阻塞状态,不能获得CPU 时间,指定的时间一过,线程从新进入可执行状态。 典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不知足后,让线程阻塞一段时间后从新测试,直到条件知足为止。
suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,而且不会自动恢复,必须其对应的resume() 被调用,才能使得线程从新进入可执行状态。典型地,suspend() 和 resume() 被用在等待另外一个线程产生的结果的情形:测试发现结果尚未产生后,让线程阻塞,另外一个线程产生告终果后,调用 resume() 使其恢复。
yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,可是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另外一个线程.
wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种容许 指定以毫秒为单位的一段时间做为参数,另外一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程从新进入可执行状态,后者则必须对应的 notify() 被调用.
初看起来它们与 suspend() 和 resume() 方法对没有什么分别,可是事实上它们是大相径庭的。区别的核心在于,前面叙述的全部方法,阻塞时都不会释放占用的锁(若是占用了的话),而这一对方法则相反。
上述的核心区别致使了一系列的细节上的区别。
首先,前面叙述的全部方法都隶属于 Thread 类,可是这一对却直接隶属于 Object 类,也就是说,全部对象都拥有这一对方法。初看起来这十分难以想象,可是实际上倒是很天然的,由于这一对方法阻塞时要释放占用的锁,而锁是任何对象都具备的,调用任意对象的 wait() 方法致使线程阻塞,而且该对象上的锁被释放。而调用 任意对象的notify()方法则致使因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到得到锁后才真正可执行)。
其次,前面叙述的全部方法均可在任何位置调用,可是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁能够释放。一样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁能够释放。所以,这一对方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不知足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。
wait() 和 notify() 方法的上述特性决定了它们常常和synchronized 方法或块一块儿使用,将它们和操做系统的进程间通讯机制做一个比较就会发现它们的类似性:synchronized方法或块提供了相似于操做系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则至关于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得咱们能够实现操做系统上一系列精妙的进程间通讯的算法(如信号量算法),并用于解决各类复杂的线程间通讯问题。
关于 wait() 和 notify() 方法最后再说明两点:
第一:调用 notify() 方法致使解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,咱们没法预料哪个线程将会被选择,因此编程时要特别当心,避免因这种不肯定性而产生问题。
第二:除了 notify(),还有一个方法 notifyAll() 也可起到相似做用,惟一的区别在于,调用 notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的全部线程一次性所有解除阻塞。固然,只有得到锁的那一个线程才能进入可执行状态。
谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait() 方法的调用均可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,咱们在编程中必须当心地避免死锁。
以上咱们对 Java 中实现线程阻塞的各类方法做了一番分析,咱们重点分析了 wait() 和 notify() 方法,由于它们的功能最强大,使用也最灵活,可是这也致使了它们的效率较低,较容易出错。实际使用中咱们应该灵活使用各类方法,以便更好地达到咱们的目的。
ArrayList:可动态调整大小的集合,底层依靠数组储存。不支持多线程。是用来替代Vector。
Vecter:与ArrayList,支持同步(synchronised)
HashMap:应用普遍。
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供全部可选的映射操做,并容许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另一个是模拟指针(引用),全部的数据结构均可以用这两个基本结构来构造的,HashMap也不例外。HashMap其实是一个“链表散列”的数据结构,即数组和链表的结合体。
HashMap的实现原理(很重要)
HashMap源码解析
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供全部可选的映射操做,并容许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另一个是模拟指针(引用),全部的数据结构均可以用这两个基本结构来构造的,HashMap也不例外。HashMap其实是一个“链表散列”的数据结构,即数组和链表的结合体。
HashMap与HashTable 的区别
HashTable 线程安全 key和value都不能为null
HashMap 非线程安全,key和value能够为null,数组内索引更高效(使用hash & lengh-1取模)
反射:
1.运行是得到类的方法和属性、接口信息。
2.创造实例
3.经过字段引用直接获取和设置字段,无视访问修饰符。
从继承的角度看,将构造函数声名为私有,有何做用:能够确保类不能够在外部实例化,只能使用公共静态方法创造实例。单例模式就是。
经常使用的设计模式:单例模式,建造者,适配器,策略模式。