# java 部分

## java基础知识

* 面向对象的三大特征
	* 继承:继承是类与类的一种关系，比较像集合中的从属于关系。
	* 封装:隐藏类的基本信息,不允许外部程序直接访问，而是通过该类的方法实现对隐藏信息的操作和访问。
	* 多态:方法的重写、重载与动态连接构成多态性；
* 面向对象的六大原则 【参考[设计模式](http://www.zeekling.cn/gogs/zeek/designPattern/src/master/principle)】
	* 单一职责原理：一个类只负责一项职责。
	* 里氏替换原则：劲量不要重写父类的已经实现了的方法，可以用接口等其他方法绕开。
	* 依赖倒置原则：高层模块不应该依赖底层模块，二者应依赖其抽象；抽象不应该依赖细节；细节应该依赖抽象。
	* 接口隔离原则：客户端不应该依赖其他不需要的接口；一个类对另一个类的依赖应该建立在最小的接口上。
	* 迪米特法则：又叫做最小知道原则。就是一个类对自己依赖的类知道越少越好。
	* 开闭原则：尽量通过扩展软件实体行为来实现变化。
* 数据类型
	* 基本数据类型
	  * 数值类型
		* 整型:int(4字节)、short(2字节)、long(8字节)、char(2字节)、byte(1字节)、
		* 浮点型:float(4字节)、double(8字节)
	  * boolean: boolean(1字节)
	* 引用数据类型：数组、对象
	  * 强引用：用关键`new`出来的对象，强引用锁指向的对象在任何时候都不会被回收
	  * 软引用:用来描述有用但非必须的对象，在内存不足的时候可以回收
	  * 弱引用：用来描述非必须的对象，但是它的强度比软引用更弱一些，被弱引用关联的对象只能生存到下一次垃圾收集发送之前。
	  * 虚引用:虚引用也称为幽灵引用或者幻影引用，它是最弱的一种引用关系。一个持有虚引用的对象，和没有引用几乎是一样的，随时都有可能被垃圾回收器回收。
* java集合
   ![集合类总图](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/list.png)
	* Collection:集合类的根接口，list和set都继承自此接口
		* List：有序,可以重复，一般用index标示顺序
			* LinkedList：底层用双链表实现:增加删除效率高
			* ArrayList：底层用数组实现:查找效率高
			* Vector：实现了一个动态数组。和ArrayList相似，但是有以下不同：vector是同步的；
				vector包含了许多传统方法，或者只是需要一个可以改变大小的数组的情况。
				* Stack:先进后出
		* set：无序，不能有重复的元素
			* HashSet:HashSet不存入重复元素的规则.使用hashcode和equals
				* LinkedHashSet:是对LinkedHashMap的简单包装，对LinkedHashSet的函数调用都会转换成合适的LinkedHashMap方法
			* TreeSet:让存入的元素自定义比较规则;给TreeSet指定排序规则
		* Queue
	* Map：由键值对组成,和Collection完全不相干，是另一个接口
		* Hashtable：同步的、线程安全的，不能接受为null的键值，不到万不得已不要使用。
		* HashMap：非同步、线程不安全,一般不要求线程安全的情况下建议使用
		  * LinkedHashMap: 是HashMap+LinkedList，即它既使用HashMap操作数据结构，又使用LinkedList维护插入元素的先后顺序。
		  java 7 hashmap实现原理
   ![hashmap实现原理](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/hashmap1.jpeg)
		  java8 实现原理
   ![java8 实现原理](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/hashmap2.png)
		  * ConcurrentHsahMap：可以用来代替HashTable，而且比HashTable的扩展性好。
   ![ConcurrentHsahMap实现原理](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/ConcurrentHashMap.png)
        * TreeMap:是一个有序的key-value集合，它是通过红黑树实现的。是SortedMap的一个实现类
		* WeakHashMap:
		* IdentifyHashMap:
	* 并发集合类
		* java.util.concurrent
		  * Executor:一个接口，其定义了一个接收Runnable对象的方法executor，其方法签名为executor(Runnable command),
		  * ExecutorService:是一个比Executor使用更广泛的子类接口，其提供了生命周期管理的方法，以及可跟踪一个或多个异步任务执行状况返回Future的方法
		  * Future：callable实现的存在返回值的并发编程
		  * CountDownLatch：可以用来在一个线程中等待多个线程完成任务的类
		* Vector
* io流
![io详解](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/io.png)
	* 根据处理数据的类型
		* 字节流:字节流因为操作的是字节，所以可以用来操作媒体文件。
		* 字符流：字符流中的对象融合了编码表，也就是系统默认的编码表。我们的系统一般都是GBK编码。字符流只用来处理文本数据，字节流用来处理媒体数据。
	* 根据数据流向
		* 输入流
		* 输出流
	* RandomAccessFile:
	* 对象序列化
* NIO(非阻塞IO)
  * IO和NIO的区别
![IO和NIO的区别](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/nio_and_io.png)
* AIO (异步IO)

* 多线程
	* 多线程的实现方式
		* 继承自Thread类(不能线程共享)
		* 实现Runnable接口(不可以返回值)
		* 实现Callable接口(可以抛出异常、返回值)
		* ThreadPoolExecutor
		  * ThreadPoolExecutor的策略
			* 线程数量未达到corePoolSize，则新建一个线程(核心线程)执行任务
			* 线程数量达到了corePools，则将任务移入队列等待
			* 队列已满，新建线程(非核心线程)执行任务
			* 队列已满，总线程数又达到了maximumPoolSize,就会(RejectedExecutionHandler)抛出异常
		  * 常见四种线程池
			* CachedThreadPool:线程数无限制;有空闲线程则复用空闲线程，若无空闲线程则新建线程;一定程序减少频繁创建/销毁线程，减少系统开销.
			* FixedThreadPool:可控制线程最大并发数（同时执行的线程数）;超出的线程会在队列中等待
			* ScheduledThreadPool:支持定时及周期性任务执行。
			* SingleThreadExecutor:有且仅有一个工作线程执行任务;所有任务按照指定顺序执行，即遵循队列的入队出队规则
		* Executors
	* 线程同步
		* 同步方法:
		* 同步代码块:synchronized 关键字在编译之后会在同步块的前后加上monitorenter和monitorexit,在执行monitorenter时，需要获取锁，如果占用所得对象是自己则需要将锁计数器加1,monitorexit时将锁计数器减1，如果为0则释放锁
		* 关键字volatile:
		  * 防止指令重排
			* 编译器重排序。编译器在不改变单线程程序语义的前提下，可以重新安排语句的执行顺序；
			* 处理器重排序。如果不存在数据依赖性，处理器可以改变语句对应机器指令的执行顺序；
		  * 实现可见性,不保证原子性
			* 可见性：volatile保证线程所在空间中的volatile修饰的变量的值是最新的;
			* 不保证原子性:两个线程对volatile修饰的变量同时进行赋值操作，可能导致两个线程对该变量进行一次赋值。
		* Reentrantlock:可重入锁,synchronized和Reentrantlock都是重入锁，区别如下:
		  * synchronized:
			1. 依赖JVM实现，加入偏向锁之后性能和Reentrantlock差不多了；
			2. 使用比较方便简洁，由编译器去实现加锁和释放；
			3. 只能是非公平锁；
          * Reentrantlock:
			1. 主要依赖代码控制实现，可以避免进入内核态的阻塞；
			2. 需要手动加锁和释放锁，容易由于忘记释放锁导致死锁；
			3. 既可以是公平锁也可以是非公平锁；
			4. 提供Condition类，可以分组唤醒线程；
			5. 能够中断等待线程；
		* 使用局部变量实现线程的同步，如:ThreadLocal。
	* 相关名词
		* 对象锁、互斥锁、共享锁、公平锁、非公平锁（[公平锁和非公平锁的比较](http://blog.csdn.net/fw0124/article/details/6672522)）、
		* 偏向锁:它会偏向于第一个访问锁的线程，如果在接下来的运行过程中，该锁没有被其他的线程访问，则持有偏向
		  锁的线程将永远不需要触发同步。如果在运行过程中，遇到了其他线程抢占锁，则持有偏向锁的线程会被挂起，
		  JVM会尝试消除它身上的偏向锁，将锁恢复到标准的轻量级锁。引入偏向锁是为了在无多线程竞争的情况下尽量
		  减少不必要的轻量级锁执行路径。
		* 原子操作、原子性、可见性
		* [悲观锁和乐观锁 ](http://www.hollischuang.com/archives/934)
		* [共享锁和排他锁](http://www.hollischuang.com/archives/923)
	* 线程的交互
	 * notify()、 notifyAll()、wait()

* 反射

## java虚拟机
### 简述
java虚拟机我看过周志明的《深入理解java虚拟机》和周志明等人翻译的《java虚拟机规范(java SE 8版)》
### 结构
* 内存管理
    * 虚拟机栈(非共享):
	  * 栈帧
		* 局部变量表:局部变量数组包含了方法执行过程中的所有变量，包括 this 引用、所有方法参数、其他局部变量。
		* 返回值:
		* 操作数栈
		* 类当前方法的运行时常量池引用
	* java堆（共享）：堆包括：新生代( Eden、Survivor(from)、Survivor(to) )、老年代。
	* 本地方法栈(非共享)
	* 程序计数器(非共享)
	* 方法区（共享）：也可以说在堆中，方法区又叫非堆，用来区分对内存，在hotsport虚拟机中方法区又叫做永久带.用来存放类信息，常量等和类相关的数据.
	* 元空间:1.8引入的，用来替换方法区(永久代);不再虚拟机中，使用的是本地内存，取决于电脑的内存大小
***内存结构图***
 1.7及以前版本java内存分布图：
![jvm内存管理](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/jvm.jpg)
 1.8 内存分布图:
![jvm内存管理](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/jvm.png)<br>
* 对象
	* 对象的创建
	* 对象的内存布局
	    * 对象头
		  * MarkWord:对象的MarkWord部分占4个字节，其内容是一系列的标记位，比如轻量级锁的标记位，偏向锁标记位等等。
		  * Class对象指针:其指向的位置是对象对应的Class对象（其对应的元数据对象）的内存地址.
		* 实例数据:存放属性信息，包括父类的信息。
		* 对齐填充（有些对象没有，具体不太懂）:Java对象在内存中将以8字节对齐，也就是对象的总大小必须是8字节的整数倍。
	* 对象的访问
		* 指针方式访问（hotspot 虚拟机用的就是指针方式访问）:指针访问方式访问方式比句柄方式快，节省一次指正定位带来的时间开销。
		* 句柄方式访问（其他虚拟机）：句柄池中存放的是稳定的句柄，当对象被移动时，只需要改变句柄的实例数据就行，不需要改变reference本身的值。
***普通对象的内存分布***
 ![mei对象](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/object.JPEG)
***数组对象的内存分布***
 ![mei对象](http://www.zeekling.cn/gogs/zeek/study/raw/master/java/pics/object_arr.JPEG)
* 垃圾回收
	* 判断对象已死
		* 引用计数法（无法判断循环引用的对象是否已死）:每个对象都有一个引用计数器，对象每被引用一次就加1，对象被释放就减1，引用计数为0表示可以被回收。
		* 可达分析法：如果对象能够到达root，就认为对象不可回收。root对象：
		  * 被启动类（bootstrap加载器）加载的类和创建的对象
		  * jvm运行时方法区类静态变量(static)引用的对象
		  * jvm运行时方法去常量池引用的对象
		  * jvm当前运行线程中的虚拟机栈变量表引用的对象
		  * 本地方法栈中(jni)引用的对象
	* 垃圾收集算法
		* 标记-清除算法（老年代，标记-清理算法容易产生碎片）:标记阶段标记可回收的对象，请理阶段清理被标记的对象所占用的空间
		* 复制算法（新生代，由于新生代对象存活较少，利用复制算法效率较高）:按内存将容量将内存分为等大小的两块，每次只使用其中的一块，当一块的内存满了之后将存活对象复制到另一块上面去。
		* 标记-整理算法（老年代）:标记阶段标记可回收的对象，整理阶段将存活的对象移动到对象的另一边，清除边界以外的对象。
		* 分代收集算法:新生代用复制算法(新生代存活的对象比较少)，老年代用标记-清除和标记-整理算法
	* 垃圾收集器（共六个垃圾收集器）
		* 新生代收集器（新生代收集器一般都利用复制算法）
			* Serial收集器（复制算法）
			* ParNew收集器（复制算法）
			* Parallel Scavenge收集器（复制算法）
		* 老年代收集器
			* Serial Old 收集器（标记-整理算法）
			* CMS收集器（标记-清除算法）： 初始标记、 并发标记、 重新标记、 并发清除
			* Parallel Old 收集器（标记-整理算法）
		* G1收集器
			* 步骤 ： 初始标记、 并发标记、最终标记、筛选标记
			* 特点： 并行与并发、分代收集、空间整合、可预测停顿
* class 文件
	* class文件的结构
		* 魔数:判断class文件是否被虚拟机接受的Class文件，魔术固定值是0xCAFEBABE
		* 版本号（主版本号、次版本号）:主板本和副版本共同构成了Java文件的格式版本
		* 访问标志(标识一些类或者接口的访问信息):用于表示某个类或者接口的访问权限及基础属性
		* 类索引(this_class):this_class的值必须是对constant_pool表中项目的一个有效索引值,表示这个Class文件所定义的类或接口。
		* 父类索引(super_class):对于类来说，super_class的值必须为0或者是对constant_pool表中项目的一个有效索引值。
		* 接口数/接口表:
		* 字段计数器:它用于表示该类或接口声明的类字段或者实例字段。
		* 常量池计数器:constant_pool_count的值等于constant_pool表中的成员数加1。
		* 常量池（主要存放两大类常量）,常量池的索引范围是1至constant_pool_count−1。
			* 字面量
			* 符号引用
		* 字段表集合(含有字段访问标志)
		* 方法数/方法表:
		* 属性数/属性表：
* 类加载机制
	* 类加载过程
		* 加载
		* 链接
			* 验证：
			* 准备：为类变量等赋初始值。如：`public static int a = 123;` 初始值为0，不是123.
			* 解析:将符号引用转化为直接引用的过程。
		* 初始化
		* 使用
		* 卸载
	* 双亲委派模型
		* 启动类加载器：加载`${JAVA_HOME}/jre/lib/`下面的jar包，所有以`java.*`的class都是由启动类加载器加载的。
		* 扩展类加载器：加载`${JAVA_HOME}/jre/ext/*.jar`
		* 应用程序类加载器：用户指定的类。
		* 用户自定义类加载器：
	* 破坏双亲委派模型
		* 线程上下文类加载器
* 虚拟机字节码执行引擎(这部分还没有看懂，就不具体列提纲了)
	*
* 高效并发
	* 内存间的交互
		* lock（锁定）：作用于主存的变量
		* unlock（解锁）：作用于主存的变量
		* read（读取）：作用于主存的变量
		* load（载入）：作用于工作内存的变量
		* use（使用）：作用于工作内存的变量
		* assign（赋值）：作用于工作内存的变量
		* store（存储）：作用于工作内存的变量
		* write（写入）：作用于主存的变量

## 算法部分
### 简述
java部分我主要看过[《剑指offer》](http://pan.baidu.com/s/1c1ZmCww)和[《程序员面试金典》](http://www.duokan.com/book/63706)两本书。感觉两本书都挺不错的。

### 《 剑指offer》

[剑指offer面试题目](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker/offer)

### 《 程序员面试金典》

#### 面试考题型目录

* [数组与字符串](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker/test/test1)
* [链表](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker/test/test2)
* [栈与队列](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [树与图](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [位操作](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [智力题](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [数学与概率](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [面向对象设计](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [递归和动态规划](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [扩展性与存储限制](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)
* [排序与查找](https://github.com/lzh984294471/job/tree/master/job/java/com/thinker)

### 脚本
脚本compile.sh 没有完成
