diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
index 8dbfe95dda..0b256f8f4a 100644
--- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
+++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/ConnectionException.java"
@@ -2,4 +2,12 @@
 
 public class ConnectionException extends Exception {
 
+	/**
+	 * 自定义异常错误
+	 * @param string
+	 */
+	public ConnectionException(String string) {
+		
+	}
+
 }
diff --git "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java" "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
index 4cd0b3eab1..ee55a8cec0 100644
--- "a/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
+++ "b/group03/1196051822/3\346\234\21013\346\227\245\344\275\234\344\270\232\347\232\204\344\273\243\347\240\201/src/download/api/DownloadListener.java"
@@ -1,5 +1,6 @@
 package com.coderising.download.api;
 
 public interface DownloadListener {
+	
 	public void notifyFinished();
 }
diff --git a/group04/1020483199/1020483199Learning/.classpath b/group04/1020483199/1020483199Learning/.classpath
index 3e0fb272a8..04cc82dc42 100644
--- a/group04/1020483199/1020483199Learning/.classpath
+++ b/group04/1020483199/1020483199Learning/.classpath
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..ba70c84329
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.loader;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		/**
+		 * class文件存储位置
+		 */
+		String location = clzPaths.get(0);
+		File file = new File(location);
+		File[] files = file.listFiles();
+		InputStream in = null;
+		byte[] bt = null;
+		
+		int size = 0;
+		for(File fileSon:files){
+			/**
+			 * 判断出为class文件时
+			 */
+			if(fileSon.isFile() && fileSon.getName().endsWith("EmployeeV1.class")){
+				try {
+					long length = fileSon.length();
+					bt = new byte[(int) length];
+					byte[] context = new byte[1024];
+					in = new FileInputStream(fileSon);
+					int tempbyte;
+					while((tempbyte = in.read(context)) != -1){
+						for(int i = 0;i < context.length;i++){
+							System.arraycopy(context, 0, bt, size, tempbyte);
+						}
+						size = tempbyte;
+					}
+					
+				} catch (FileNotFoundException e) {
+					e.printStackTrace();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}finally{
+					if(in != null){
+						try {
+							in.close();
+						} catch (IOException e) {
+						}
+					}
+				}
+				
+			}
+		}
+		return bt;	
+	}
+	
+	
+	public void addClassPath(String path) {
+		
+		clzPaths.add(path);
+		
+	}
+	
+	
+	
+	public String getClassPath(){
+		StringBuilder sb = new StringBuilder();
+		for(int i = 0;i < clzPaths.size();i++){
+			if(i == clzPaths.size() - 1){
+				sb.append(clzPaths.get(i));
+				break;
+			}
+			sb.append(clzPaths.get(i)).append(";");
+			
+		}
+		return sb.toString();
+	}
+
+	
+
+	
+
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..7c7d1bb15a
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,91 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "F:/myGithub/coding2017/group04/1020483199/FourthHomeWork/bin/com/coderising/jvm/test";
+	static String path2 = "C:/temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/EmployeeV1.java b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/Iterator.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/Iterator.java
new file mode 100644
index 0000000000..7a7b2aa313
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/Iterator.java
@@ -0,0 +1,7 @@
+package com.coding.basic.linkedList;
+
+public interface Iterator {
+	public boolean hasNext();
+	public Object next();
+
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrame.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrame.java
new file mode 100644
index 0000000000..72e222ad69
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrame.java
@@ -0,0 +1,141 @@
+package com.coding.basic.linkedList;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static int stateAtHead = 0;
+	private static int stateAtLast = 1;
+	private static int stateAtMid = 2;
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(){
+			
+		}
+	}
+
+	private int capacity;
+	
+	private int size;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		/**
+		 * 空链表
+		 */
+		size ++;
+		Node newNode = new Node();
+		newNode.pageNum = pageNum;
+		if(size <= capacity){
+			if(last == null){
+				last= newNode;
+				first = newNode;
+			}else{
+				Node preHead = first;//记录原来的头节点
+				first = newNode;
+				first.next = preHead;
+				preHead.prev = first;
+			}
+		}else{
+			Node currentNode = first;
+			int judgeNum = currentNode.pageNum;
+			Node preHead = first;//记录原来的头节点
+			Node preLast = last;//记录原来的尾节点
+			int state = -1;//记录当前状态
+			/**
+			 * 当前插入的值为等于链表头的位置
+			 */
+			
+			int k = 0;
+			if(judgeNum == pageNum){
+				state = stateAtHead;
+			}else if(preLast.pageNum == pageNum){
+				state = stateAtLast;
+			}
+			while(currentNode != null && k < capacity - 1){
+				k++;
+				currentNode = currentNode.next;
+				judgeNum = currentNode.pageNum;
+				if(judgeNum == pageNum && judgeNum != preLast.pageNum){
+					state = stateAtMid;
+					break;
+				}
+			}
+			
+			switch (state) {
+			case -1:
+				first = newNode;
+				last = preLast.prev;
+				first.next = preHead;
+				first.prev = null;
+				preHead.next = last;
+				preHead.prev = first;
+				last.next = null;
+				break;
+			case 0:
+				
+				break;
+
+			case 1:
+				last = preLast.prev;
+				last.next = null;//原来尾节点的上一个节点变成了尾节点
+				first = newNode;
+				first.prev = null;
+				first.next = preHead;
+				break;
+			case 2:
+				first = newNode;
+				first.next = preHead;
+				first.prev = null;
+				preHead.next = last;
+				preHead.prev = first;
+				last.prev = preHead;
+				break;
+			}
+			
+		}
+		
+		
+		
+	
+	}
+	
+	
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrameTest.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrameTest.java
new file mode 100644
index 0000000000..f2ffcabf16
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LRUPageFrameTest.java
@@ -0,0 +1,32 @@
+package com.coding.basic.linkedList;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LinkedList.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LinkedList.java
new file mode 100644
index 0000000000..52ecedc5be
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/LinkedList.java
@@ -0,0 +1,374 @@
+package com.coding.basic.linkedList;
+
+import java.util.Stack;
+
+public class LinkedList implements List {
+	private int size;
+	
+	private Node head;
+	
+	public LinkedList(){
+		size = 0;
+		
+		head = null;
+	}
+	
+	public void add(Object o){
+		Node nd = new Node(o);
+		if(head == null){
+			head = nd;
+		}else{
+			Node p = head;
+			while(p.next != null){
+				p = p.next;
+			}
+			p.next = nd;
+		}
+		size ++;
+		
+	}
+	//3 > 2 > 1 > 5 > 4 > 5改变之前
+	//0   1   2   3   4   5index
+	//3 > 2 > 1 > x > 5 > 4 > 5插入之后
+	public void add(int index , Object o){
+		if(head != null){
+			int k = 0;
+			Node p = head;
+			while(k < index - 1 && p.next != null){
+				k++;
+				p = p.next;//当前p为要插入位置的前一个节点
+			}
+			
+			if(p != null){
+				Node nd = new Node(o);
+				nd.next = p.next;
+				p.next = nd;
+			}
+			
+			size++;
+			
+		}
+	}
+	public Object get(int index){
+		if(index < 0 || index >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		Node p = head;
+		int k = 0;
+		while(k < index && p.next !=null){
+			k++;
+			p = p.next;
+		}
+		return p.data;
+	}
+	//3 > 2 > 1 > 5 > 4 > 5改变之前
+	//0   1   2   3   4   5index
+	//3 > 2 > 1 > 4 > 5插入之后
+	public Object remove(int index){
+		if(index < 0 || index >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		if(head == null){
+			return null;
+		}
+		if(index == 0){
+			head = head.next;
+			size--;
+			return head.data;
+		}else{
+			if(head != null){
+				int k = 0;
+				Node p = head;
+				while(k < index - 1 && p != null){
+					k++;
+					p = p.next;
+				}
+				Node pn = p.next;
+				if(pn != null){
+					p.next = pn.next;
+					size--;
+					return pn.data;
+				}
+				
+			}
+		}
+		return null;
+	}
+	
+	public int size(){
+		
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		if(head != null){
+			Node nd = new Node(o);
+			Node first = head;
+			head = nd;
+			first = nd.next;
+		}
+	}
+	public void addLast(Object o){
+		if(head != null){
+			int k = 0;
+			Node p = head;
+			while(p.next != null && k < size - 1){
+				p = p.next;
+				k++;
+			}
+			Node newNode = new Node(o);
+			p.next = newNode;
+		}
+	}
+	public Object removeFirst(){
+		Node node = head;
+		if(head != null){
+			head = head.next;
+		}
+		return node.data;
+	} 
+	public Object removeLast(){
+		Node p = head;
+		int k = 0;
+		while(p.next != null && k < size - 2){
+			k++;
+			p = p.next;
+		}
+		
+		p.next = null;
+		return p.next;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+		private Node(Object o){
+			this.data = o;
+			this.next = null;
+		}
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 			head   				 head
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public void reverse(){
+		/**
+		 * 长度超过1的单链表需要逆转
+		 */
+		if(head == null || head.next == null){
+			return;
+		}
+		Stack<Node> st = new Stack<Node>();
+		Node currentNode = head;
+		while(currentNode != null){
+			st.push(currentNode);
+			Node nextNode = currentNode.next;
+			currentNode.next = null;//断开连接
+			currentNode = nextNode;
+		}
+		
+		head = (Node) st.pop();
+		currentNode = head;
+		while(!st.isEmpty()){
+			Node nextNode = (Node) st.pop();
+			currentNode.next = nextNode;
+			currentNode = nextNode;
+		}
+	}
+	
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public void removeFirstHalf(){
+		int num = size / 2;
+		for(int i = 0; i < num; i++){
+			removeFirst();
+		}
+	}
+	
+	/**
+	 * 从第i个元素开始,删除length个元素 ,注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		if(i < 0 || i >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		int len = size - i >= length ? length : size - i;
+		int k = 0;
+		while(k < len){
+			remove(i);
+			k++;
+		}
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		int[] newList = new int[list.size()];
+		for(int i = 0;i < list.size(); i++){
+			newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString());   
+		}
+		return newList;
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public void subtract(LinkedList list){
+		for(int j = 0;j < list.size();j++){
+			this.remove(list.get(j));
+		}
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public void removeDuplicateValues(){
+		if(head == null){
+			throw new RuntimeException("LinkedList is null");
+			
+		}
+		Node currentNode = head;
+		Node preNode = head;
+		while(currentNode.next != null){
+			currentNode = currentNode.next;
+			Object data = preNode.data;
+			while(currentNode.data == data){
+				if(currentNode.next == null){
+					preNode.next = null;
+					break;
+				}
+				preNode.next = currentNode.next;
+				size--;
+				currentNode = currentNode.next;
+				if(currentNode == null){
+					break;
+				}
+			}
+			preNode = preNode.next;
+		}
+	}
+	/**
+	 * 传入删除数据节点
+	 */
+	public void remove(Object obj){
+		if(head == null){
+			throw new RuntimeException("linkedlist is nuull");
+			
+		}	
+		if(head.data.equals(obj)){
+			head = head.next;
+			size--;
+		}else{
+			Node pre = head;
+			Node currentNode = head.next;
+			while(currentNode != null){
+				if(currentNode.data.equals(obj)){
+					pre.next = currentNode.next;
+					size--;
+				}
+				pre = pre.next;
+				currentNode = currentNode.next;
+			}
+		}
+	}
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public void removeRange(int min, int max){
+		Node node = head;
+		int start = -1;
+		int end = -1;
+		int i = 0;
+		while(node != null){
+			if((Integer)node.data <= min){
+				start = i;
+			}
+			if((Integer)node.data >= max){
+				end = i;
+				break;                                                   
+			}
+			node = node.next;
+			i++;
+		}
+		if(start == -1){
+			start = 0;
+		}
+		if(end == -1){
+			end = size;
+		}
+		this.remove(start+1, end-start-1);
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public LinkedList intersection(LinkedList list){
+		if(list == null){
+			return null;
+		}
+		
+		LinkedList newList = new LinkedList();
+		int fi = 0;
+		int se = 0;
+		while(fi < this.size && se < list.size()){
+			int val1 = (Integer) this.get(fi);
+			int val2 = (Integer) list.get(se);
+			if(val1 == val2){
+				newList.add(val1);
+				fi++;
+				se++;
+			}else if(val1 < val2){
+				fi++;
+			}else{
+				se++;
+			}
+			
+		}
+		return newList;
+	}
+	
+	public static void main(String[] args) {
+		LinkedList linkedList = new LinkedList();
+		linkedList.add(11);
+		linkedList.add(22);
+		linkedList.add(33);
+		linkedList.add(44);
+		linkedList.add(55);
+		linkedList.reverse();
+		for(int i = 0; i < linkedList.size; i++){
+			System.out.println(linkedList.get(i));
+		}
+	}
+}
diff --git a/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java
new file mode 100644
index 0000000000..55ff205b5d
--- /dev/null
+++ b/group04/1020483199/FourthHomeWork/src/com/coding/basic/linkedList/List.java
@@ -0,0 +1,9 @@
+package com.coding.basic.linkedList;
+
+public interface List {
+	public void add(Object o);
+	public void add(int index, Object o);
+	public Object get(int index);
+	public Object remove(int index);
+	public int size();
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..e5ddb476a6
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coderising.array;
+
+public class ArrayUtil {
+	
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换
+		例如： a = [7, 9 , 30, 3]  ,   置换后为 [3, 30, 9,7]
+		如果     a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * @param origin
+	 * @return
+	 */
+	public void reverseArray(int[] origin){
+		
+	}
+	
+	/**
+	 * 现在有如下的一个数组：   int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}   
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为：   
+	 * {1,3,4,5,6,6,5,4,7,6,7,5}  
+	 * @param oldArray
+	 * @return
+	 */
+	
+	public int[] removeZero(int[] oldArray){
+		return null;
+	}
+	
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 ,  创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的
+	 * 例如 a1 = [3, 5, 7,8]   a2 = [4, 5, 6,7]    则 a3 为[3,4,5,6,7,8]    , 注意： 已经消除了重复
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+	
+	public int[] merge(int[] array1, int[] array2){
+		return  null;
+	}
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持
+	 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public int[] grow(int [] oldArray,  int size){
+		return null;
+	}
+	
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21......  ，给定一个最大值， 返回小于该值的数列
+	 * 例如， max = 15 , 则返回的数组应该为 [1，1，2，3，5，8，13]
+	 * max = 1, 则返回空数组 []
+	 * @param max
+	 * @return
+	 */
+	public int[] fibonacci(int max){
+		return null;
+	}
+	
+	/**
+	 * 返回小于给定最大值max的所有素数数组
+	 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * @param max
+	 * @return
+	 */
+	public int[] getPrimes(int max){
+		return null;
+	}
+	
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+	 * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * @param max
+	 * @return
+	 */
+	public int[] getPerfectNumbers(int max){
+		return null;
+	}
+	
+	/**
+	 * 用seperator 把数组 array给连接起来
+	 * 例如array= [3,8,9], seperator = "-"
+	 * 则返回值为"3-8-9"
+	 * @param array
+	 * @param s
+	 * @return
+	 */
+	public String join(int[] array, String seperator){
+		return null;
+	}
+	
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..d16eca2319
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,42 @@
+package com.coderising.download;
+
+
+
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+	
+	
+	private Connection conn;
+	private int startPos;
+	private int endPos;
+	private String filePath;
+	private CyclicBarrier barrier;
+
+	public DownloadThread(Connection conn, int startPos, int endPos,String filePath,CyclicBarrier barrier){
+		this.conn = conn;
+		this.startPos = startPos;
+		this.endPos = endPos;
+		this.filePath = filePath;
+		this.barrier = barrier;
+	}
+	public void run(){	
+		try {
+			System.out.println("线程" + this.getName() + "开始下载. startPos:" + startPos + "; endPos:" + endPos);
+			byte[] buffer = conn.read(startPos, endPos);
+			RandomAccessFile ra = new RandomAccessFile(filePath, "rw");
+			ra.seek(startPos);
+			ra.write(buffer);
+			//关闭流
+			ra.close();
+			conn.close();
+			barrier.await();
+			System.out.println("线程" + this.getName() + "下载完成.");
+			}catch (Exception e) {
+				e.printStackTrace();
+		}
+	}
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..c6cdf3fc4a
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,139 @@
+package com.coderising.download;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+
+import org.junit.internal.runners.statements.RunAfters;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+	
+	private String url;
+	
+	private String localFile;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+	
+	private final static int thread_count = 3;
+	
+	public FileDownloader(String _url,String localFile) {
+		this.url = _url;
+		this.localFile = localFile;
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，
+		//通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 
+		//调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 
+		//这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接，
+		//然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 
+		//返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		CyclicBarrier barrier = new CyclicBarrier(thread_count, new Runnable() {
+			
+			@Override
+			public void run() {
+				listener.notifyFinished();
+			}
+		});
+		Connection conn = null;
+		try {
+			
+			conn = cm.open(this.url);
+			
+			int length = conn.getContentLength();	
+			
+			createPlaceHolderFile(this.localFile,length);
+			
+			int[] [] ranges = allowcateDownloadRange(thread_count,length);
+			
+			for(int i = 0; i < thread_count; i++){
+				
+				DownloadThread thread= new DownloadThread(conn, ranges[i][0], ranges[i][1], localFile, barrier);
+				
+				thread.start();
+				
+			}
+			
+		} catch (Exception e) {			
+			e.printStackTrace();
+			
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+		
+		
+		
+	}
+	
+	private int[][] allowcateDownloadRange(int threadCount, int length) {
+		int[][] ranges = new int[thread_count][2];
+		
+		int eachThreadSize = length / threadCount;
+		
+		int left = length % threadCount;
+		
+		for(int i = 0 ; i < thread_count;i++){
+			int startPos = i * eachThreadSize;
+			
+			int endPos = (i+1) * eachThreadSize - 1;
+			
+			if((i==thread_count -1)){
+				endPos += left;
+			}
+			
+			ranges[i][0] = startPos;
+			ranges[i][1] = endPos;
+		}
+		
+		return ranges;
+	}
+
+	private void createPlaceHolderFile(String localfile, int length) throws IOException {
+		RandomAccessFile file = new RandomAccessFile(localfile, "rw");
+		for(int i = 0;i < length ; i++){
+			file.write(0);
+		}
+		file.close();
+	}
+
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..7393f57040
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,90 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testContentLength() throws Exception{
+		ConnectionManager connMan = new ConnectionManagerImpl();
+		Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");		
+		Assert.assertEquals(35470, conn.getContentLength());
+	}
+	
+	@Test
+	public void testRead() throws Exception{
+		
+		ConnectionManager connMan = new ConnectionManagerImpl();
+		Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");
+		
+		byte[] data = conn.read(0, 35469);
+		
+		Assert.assertEquals(35470, data.length);
+		
+		data = conn.read(0, 1023);
+		
+		Assert.assertEquals(1024, data.length);
+		
+		data = conn.read(1024, 2023);
+		
+		Assert.assertEquals(1000, data.length);
+		
+		
+		// 测试不充分，没有断言内容是否正确
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url = "http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg";
+		
+		FileDownloader downloader = new FileDownloader(url, "F:/picture/a.png");
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..105f00f03a
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,13 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+	/**
+	 * 自定义异常错误
+	 * @param string
+	 */
+	public ConnectionException(Exception e) {
+		super(e);
+	}
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..7b51663ff9
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,6 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	
+	public void notifyFinished();
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..dcaf5883fa
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,89 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+
+class ConnectionImpl implements Connection {
+	
+	URL url;
+	static final int BUFFER_SIZE = 1024;
+	
+	ConnectionImpl(String _url) throws ConnectionException{
+		try {			
+			url = new URL(_url);
+		} catch (MalformedURLException e) {			
+			throw new ConnectionException(e);
+		}
+	}
+	
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {		
+		
+
+		HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
+		
+		httpConn.setRequestProperty("Range", "bytes=" + startPos + "-"
+                + endPos);
+		
+		InputStream is  = httpConn.getInputStream();
+		
+		//is.skip(startPos);		
+		
+        byte[] buff = new byte[BUFFER_SIZE];  
+     
+        int totalLen = endPos - startPos + 1;
+        
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();        
+      
+        while(baos.size() < totalLen){  
+        	
+        	int len = is.read(buff);           
+            if (len < 0) {  
+                break;  
+            }             
+            baos.write(buff,0, len);            
+        }  
+        
+        
+        if(baos.size() > totalLen){
+        	byte[] data = baos.toByteArray();
+        	return Arrays.copyOf(data, totalLen);
+        }
+        
+		return baos.toByteArray();
+	}
+
+	@Override
+	public int getContentLength() {
+		
+        URLConnection con;
+		try {
+			con = url.openConnection();
+			
+			return con.getContentLength(); 
+			
+		} catch (IOException e) {			
+			e.printStackTrace();
+		}  
+        
+		return -1;
+            
+        
+	}
+
+	@Override
+	public void close() {
+		
+		
+	}
+
+}
\ No newline at end of file
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..3af9b21485
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,17 @@
+package com.coderising.download.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		return new ConnectionImpl(url);
+	}
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..6df190d484
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/Struts.java
@@ -0,0 +1,37 @@
+package com.coderising.litestruts;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+	
+    public static View runAction(String actionName, Map<String,String> parameters) {
+
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+    	
+    
+    	return null;
+    }    
+
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+		
+		String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..3fe0a702d4
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coderising/litestruts/View.java
@@ -0,0 +1,27 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	
+	private Map parameters;
+
+	public String getJsp() {
+		return jsp;
+	}
+
+	public void setJsp(String jsp) {
+		this.jsp = jsp;
+	}
+
+	public Map getParameters() {
+		return parameters;
+	}
+
+	public void setParameters(Map parameters) {
+		this.parameters = parameters;
+	}
+	
+	
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java
new file mode 100644
index 0000000000..1f185736f9
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/ArrayList.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class ArrayList implements List {
+	
+	private int size = 0;
+	
+	private Object[] elementData = new Object[100];
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index, Object o){
+		
+	}
+	
+	public Object get(int index){
+		return null;
+	}
+	
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public Iterator iterator(){
+		return null;
+	}
+	
+}
diff --git a/group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java
similarity index 100%
rename from group04/120549547/base/src/com/coding/basic/BinaryTreeNode.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/BinaryTreeNode.java
diff --git a/group04/120549547/base/src/com/coding/basic/Iterator.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java
similarity index 100%
rename from group04/120549547/base/src/com/coding/basic/Iterator.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/Iterator.java
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java
new file mode 100644
index 0000000000..7b10ffb8b6
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/LinkedList.java
@@ -0,0 +1,374 @@
+package com.coding.basic;
+
+import java.util.Stack;
+
+public class LinkedList implements List {
+	private int size;
+	
+	private Node head;
+	
+	public LinkedList(){
+		size = 0;
+		
+		head = null;
+	}
+	
+	public void add(Object o){
+		Node nd = new Node(o);
+		if(head == null){
+			head = nd;
+		}else{
+			Node p = head;
+			while(p.next != null){
+				p = p.next;
+			}
+			p.next = nd;
+		}
+		size ++;
+		
+	}
+	//3 > 2 > 1 > 5 > 4 > 5改变之前
+	//0   1   2   3   4   5index
+	//3 > 2 > 1 > x > 5 > 4 > 5插入之后
+	public void add(int index , Object o){
+		if(head != null){
+			int k = 0;
+			Node p = head;
+			while(k < index - 1 && p.next != null){
+				k++;
+				p = p.next;//当前p为要插入位置的前一个节点
+			}
+			
+			if(p != null){
+				Node nd = new Node(o);
+				nd.next = p.next;
+				p.next = nd;
+			}
+			
+			size++;
+			
+		}
+	}
+	public Object get(int index){
+		if(index < 0 || index >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		Node p = head;
+		int k = 0;
+		while(k < index && p.next !=null){
+			k++;
+			p = p.next;
+		}
+		return p.data;
+	}
+	//3 > 2 > 1 > 5 > 4 > 5改变之前
+	//0   1   2   3   4   5index
+	//3 > 2 > 1 > 4 > 5插入之后
+	public Object remove(int index){
+		if(index < 0 || index >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		if(head == null){
+			return null;
+		}
+		if(index == 0){
+			head = head.next;
+			size--;
+			return head.data;
+		}else{
+			if(head != null){
+				int k = 0;
+				Node p = head;
+				while(k < index - 1 && p != null){
+					k++;
+					p = p.next;
+				}
+				Node pn = p.next;
+				if(pn != null){
+					p.next = pn.next;
+					size--;
+					return pn.data;
+				}
+				
+			}
+		}
+		return null;
+	}
+	
+	public int size(){
+		
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		if(head != null){
+			Node nd = new Node(o);
+			Node first = head;
+			head = nd;
+			first = nd.next;
+		}
+	}
+	public void addLast(Object o){
+		if(head != null){
+			int k = 0;
+			Node p = head;
+			while(p.next != null && k < size - 1){
+				p = p.next;
+				k++;
+			}
+			Node newNode = new Node(o);
+			p.next = newNode;
+		}
+	}
+	public Object removeFirst(){
+		Node node = head;
+		if(head != null){
+			head = head.next;
+		}
+		return node.data;
+	} 
+	public Object removeLast(){
+		Node p = head;
+		int k = 0;
+		while(p.next != null && k < size - 2){
+			k++;
+			p = p.next;
+		}
+		
+		p.next = null;
+		return p.next;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+		private Node(Object o){
+			this.data = o;
+			this.next = null;
+		}
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 			head   				 head
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public void reverse(){
+		/**
+		 * 长度超过1的单链表需要逆转
+		 */
+		if(head == null || head.next == null){
+			return;
+		}
+		Stack<Node> st = new Stack<Node>();
+		Node currentNode = head;
+		while(currentNode != null){
+			st.push(currentNode);
+			Node nextNode = currentNode.next;
+			currentNode.next = null;//断开连接
+			currentNode = nextNode;
+		}
+		
+		head = (Node) st.pop();
+		currentNode = head;
+		while(!st.isEmpty()){
+			Node nextNode = (Node) st.pop();
+			currentNode.next = nextNode;
+			currentNode = nextNode;
+		}
+	}
+	
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public void removeFirstHalf(){
+		int num = size / 2;
+		for(int i = 0; i < num; i++){
+			removeFirst();
+		}
+	}
+	
+	/**
+	 * 从第i个元素开始,删除length个元素 ,注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		if(i < 0 || i >= size){
+			throw new IndexOutOfBoundsException();
+		}
+		int len = size - i >= length ? length : size - i;
+		int k = 0;
+		while(k < len){
+			remove(i);
+			k++;
+		}
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		int[] newList = new int[list.size()];
+		for(int i = 0;i < list.size(); i++){
+			newList[i] = Integer.parseInt(this.get(Integer.parseInt(list.get(i).toString())).toString());   
+		}
+		return newList;
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public void subtract(LinkedList list){
+		for(int j = 0;j < list.size();j++){
+			this.remove(list.get(j));
+		}
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public void removeDuplicateValues(){
+		if(head == null){
+			throw new RuntimeException("LinkedList is null");
+			
+		}
+		Node currentNode = head;
+		Node preNode = head;
+		while(currentNode.next != null){
+			currentNode = currentNode.next;
+			Object data = preNode.data;
+			while(currentNode.data == data){
+				if(currentNode.next == null){
+					preNode.next = null;
+					break;
+				}
+				preNode.next = currentNode.next;
+				size--;
+				currentNode = currentNode.next;
+				if(currentNode == null){
+					break;
+				}
+			}
+			preNode = preNode.next;
+		}
+	}
+	/**
+	 * 传入删除数据节点
+	 */
+	public void remove(Object obj){
+		if(head == null){
+			throw new RuntimeException("linkedlist is nuull");
+			
+		}	
+		if(head.data.equals(obj)){
+			head = head.next;
+			size--;
+		}else{
+			Node pre = head;
+			Node currentNode = head.next;
+			while(currentNode != null){
+				if(currentNode.data.equals(obj)){
+					pre.next = currentNode.next;
+					size--;
+				}
+				pre = pre.next;
+				currentNode = currentNode.next;
+			}
+		}
+	}
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public void removeRange(int min, int max){
+		Node node = head;
+		int start = -1;
+		int end = -1;
+		int i = 0;
+		while(node != null){
+			if((Integer)node.data <= min){
+				start = i;
+			}
+			if((Integer)node.data >= max){
+				end = i;
+				break;                                                   
+			}
+			node = node.next;
+			i++;
+		}
+		if(start == -1){
+			start = 0;
+		}
+		if(end == -1){
+			end = size;
+		}
+		this.remove(start+1, end-start-1);
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public LinkedList intersection(LinkedList list){
+		if(list == null){
+			return null;
+		}
+		
+		LinkedList newList = new LinkedList();
+		int fi = 0;
+		int se = 0;
+		while(fi < this.size && se < list.size()){
+			int val1 = (Integer) this.get(fi);
+			int val2 = (Integer) list.get(se);
+			if(val1 == val2){
+				newList.add(val1);
+				fi++;
+				se++;
+			}else if(val1 < val2){
+				fi++;
+			}else{
+				se++;
+			}
+			
+		}
+		return newList;
+	}
+	
+	public static void main(String[] args) {
+		LinkedList linkedList = new LinkedList();
+		linkedList.add(11);
+		linkedList.add(22);
+		linkedList.add(33);
+		linkedList.add(44);
+		linkedList.add(55);
+		linkedList.reverse();
+		for(int i = 0; i < linkedList.size; i++){
+			System.out.println(linkedList.get(i));
+		}
+	}
+}
diff --git a/group12/446031103/src/com/coding/basic/List.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java
similarity index 100%
rename from group12/446031103/src/com/coding/basic/List.java
rename to group04/1020483199/ThirdHomeWork/src/com/coding/basic/List.java
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java
new file mode 100644
index 0000000000..36e516e266
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Queue.java
@@ -0,0 +1,19 @@
+package com.coding.basic;
+
+public class Queue {
+	
+	public void enQueue(Object o){		
+	}
+	
+	public Object deQueue(){
+		return null;
+	}
+	
+	public boolean isEmpty(){
+		return false;
+	}
+	
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..a25d5b8024
--- /dev/null
+++ b/group04/1020483199/ThirdHomeWork/src/com/coding/basic/Stack.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+public class Stack<T> {
+	private ArrayList elementData = new ArrayList();
+	
+	public void push(Object o){		
+	}
+	
+	public Object pop(){
+		return null;
+	}
+	
+	public Object peek(){
+		return null;
+	}
+	public boolean isEmpty(){
+		return false;
+	}
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group04/120549547/base/buil.bat b/group04/120549547/base/buil.bat
deleted file mode 100644
index 7164a42ac0..0000000000
--- a/group04/120549547/base/buil.bat
+++ /dev/null
@@ -1,5 +0,0 @@
-javac -sourcepath src -d classes -encoding utf-8  src\com\coding\basic\*.java
-
-java -cp classes com.coding.basic.Main	
-
-pause
\ No newline at end of file
diff --git a/group04/120549547/base/src/com/coding/basic/ArrayList.java b/group04/120549547/base/src/com/coding/basic/ArrayList.java
deleted file mode 100644
index 56e7aa4c26..0000000000
--- a/group04/120549547/base/src/com/coding/basic/ArrayList.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.coding.basic;
-import java.util.Arrays;
-
-public class ArrayList implements List {
-	/*默认数组容量*/
-	public static final int DEFAULT_CAPCATITY = 10;
-	
-	/*数组元素个数*/
-	private int size;
-
-	private Object[] elementData;
-	
-	public ArrayList(){
-		this(DEFAULT_CAPCATITY);
-	}
-	
-	public ArrayList(int capacity){
-		if (capacity<0 || capacity>Integer.MAX_VALUE) 
-			throw new IllegalArgumentException("非法容量： " + capacity);
-		elementData = new Object[capacity];
-	}
-	
-	
-	public void add(Object o){
-		/*判断是否需要扩容*/
-		ensureCapacity(size + 1);
-		elementData[size++] = o;
-	}
-	
-	public void add(int index, Object o){
-		checkIndex(index);
-		/*判断是否需要扩容*/
-		ensureCapacity(size + 1);
-		/*将index->size的元素依次向右移一个位置*/
-		System.arraycopy(elementData, index, elementData, index+1, size-index);
-		/*插入o的值*/
-		elementData[index] = o;
-		size++;
-	}
-
-
-	public Object get(int index){
-		
-		checkIndex(index);
-		return elementData[index];
-	}
-	
-	public Object remove(int index){
-		
-		checkIndex(index);
-		Object value = elementData[index];
-		/*将index+1 -> size的元素依次向左移一个位置*/
-		System.arraycopy(elementData,index+1, elementData, index, size-index-1);
-		elementData[--size]=null;   //释放最后一个元素,同时size减一；
-		return value;
-	}
-	
-	public int size(){
-		return this.size;
-	}
-	
-	public Iterator iterator(){
-		return null;
-	}
-	/* 确认容量是否足够，也可以直接调用手动扩容*/
-	public void ensureCapacity(int minCapacity){
-		int oldCapacity = elementData.length;
-		/*容量不足需要扩容*/
-		if(oldCapacity < minCapacity){
-			int newCapacity = oldCapacity * 2; //扩大2倍
-			if (newCapacity < minCapacity){
-				newCapacity = minCapacity;  //扩容后仍不足,取最大值
-			}
-			System.out.println("数据扩容至： " + newCapacity);
-			elementData = Arrays.copyOf(elementData, newCapacity);	
-		}
-		
-	}
-
-	private void checkIndex(int index){
-	if (index<0 || index>= size)
-		throw new IndexOutOfBoundsException ("index非法: " + index);
-	}
-	@Override
-	public String toString(){
-		
-		StringBuffer sb = new StringBuffer("");
-		for(int i=0; i<size; i++){
-			sb.append("["+ i +"]"+ elementData[i] + "->  ");
-		}
-		return sb.toString();
-	}
-}
diff --git a/group04/120549547/base/src/com/coding/basic/LinkedList.java b/group04/120549547/base/src/com/coding/basic/LinkedList.java
deleted file mode 100644
index edfbcc1007..0000000000
--- a/group04/120549547/base/src/com/coding/basic/LinkedList.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.coding.basic;
-
-public class LinkedList implements List {
-	
-	private Node head;
-	private int size;  
-	/*创建一个带头节点的单链表*/
-	public LinkedList(){
-		head = new Node(null);
-	}
-	
-	/*添加一个元素(尾插法)*/
-	public void add(Object o){
-		
-		Node node = new Node(o);
-		Node pos = head;
-		//找到最后一个元素位置
-		while(pos.next != null){
-			pos = pos.next;
-		}
-		pos.next = node;
-		size++;
-		
-	}
-	
-	/*在index位置插入*/
-	public void add(int index , Object o){
-		//判断索引是否合法
-		checkIndex(index);
-		Node node = new Node(o);
-		Node pos = head;
-		//找到插入位置
-		while(index-- != 0){
-			pos = pos.next;
-		}
-		node.next = pos.next;
-		pos.next = node;
-		size++;
-		
-	}
-	public Object get(int index){
-		checkIndex(index);
-		if(this.isEmpty()){
-			throw new IllegalArgumentException ("链表为空");
-		}
-		Node pos = head.next;  //pos指向要获取的节点
-		while(index-- !=0){
-			pos = pos.next;
-		}
-	
-		return pos.data;
-	}
-	public Object remove(int index){
-		checkIndex(index);
-		if(this.isEmpty()){
-			throw new IllegalArgumentException ("链表为空");
-		}
-	
-		Node pos = head;  //pos指向要删除的前一个结点
-		while(index-- != 0){	
-			pos = pos.next;
-		}
-		Node value = pos.next; //要删除的节点
-		pos.next = value.next;
-		size--;
-		return value.data;
-		
-
-	}
-	
-	public int size(){
-		return size;
-	}
-	
-	public void addFirst(Object o){
-		
-	}
-	public void addLast(Object o){
-		this.add(o);
-	}
-	public Object removeFirst(){
-		if(this.isEmpty()){
-			throw new IllegalArgumentException ("链表为空");
-		}
-		return remove(0);
-	}
-	public Object removeLast(){
-		if(this.isEmpty()){
-			throw new IllegalArgumentException ("链表为空");
-		}
-		return remove(size-1);
-	}
-	
-	public boolean isEmpty(){
-		return size == 0;
-	}
-	public Iterator iterator(){
-		return null;
-	}
-	
-	private void checkIndex(int index){
-		if (index<0 || index>=size ){
-			throw new IllegalArgumentException ("index不合法: " + index );
-		}
-	}
-	
-	@Override
-	public String toString(){
-		
-		StringBuffer sb = new StringBuffer("");
-		for(int i=0; i<size; i++){
-			sb.append( this.get(i) + "->  ");
-		}
-		return sb.toString();
-	}
-	
-	private static  class Node{
-		public Object data;
-		public Node next;
-		
-		public Node(Object data){
-			this.data = data;
-			this.next = null;
-		}
-		
-	}
-}
diff --git a/group04/120549547/base/src/com/coding/basic/Main.java b/group04/120549547/base/src/com/coding/basic/Main.java
deleted file mode 100644
index de8a0b0990..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Main.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.*;
-
-class Main{
-
-	public static void  main(String[] args){
-		System.out.println("数组测试开始");
-		ArrayListTest();
-		System.out.println("----------------分割线----------------");
-		System.out.println("链表测试开始");
-		LinkedListTest();	
-		System.out.println("----------------分割线----------------");
-		System.out.println("栈测试开始");
-		StatckTest();
-		System.out.println("----------------分割线----------------");
-		System.out.println("队测试开始");
-		QueueTest();
-	}
-	
-	public static void ArrayListTest(){
-		ArrayList list = new ArrayList(2);
-		list.add("HelloBobi0");
-		list.add("HelloBobi1");
-		list.add("HelloBobi2");
-		list.add("HelloBobi3");
-		list.add("HelloBobi4");
-		list.add("HelloBobi5");
-		System.out.println((String)list.get(0));
-		System.out.println((String)list.get(4));
-		list.add(3, "Hei Man");
-		list.remove(5);
-		System.out.println(list);
-		System.out.println("size:=" + list.size());
-	}
-	
-	public static void LinkedListTest(){
-		LinkedList ll = new LinkedList();
-		
-		
-		ll.add("SingleDog0");
-		ll.add("SingleDog1");
-		ll.add("SingleDog2");
-		ll.add("SingleDog3");
-		ll.add("SingleDog4");
-		ll.add("SingleDog5");
-		
-		System.out.println((String)(ll.get(1)));
-		System.out.println(ll);
-		System.out.println("size:=" + ll.size());
-		ll.remove(0);
-		ll.removeFirst();
-		ll.removeLast();
-		System.out.println(ll);		
-	}
-	
-	public static void StatckTest(){
-		Stack stack = new Stack();
-		stack.push("虾师傅0");
-		stack.push("虾师傅1");
-		stack.push("虾师傅2");
-		stack.push("虾师傅3");
-		stack.push("虾师傅4");
-		
-		stack.pop();
-		System.out.println(stack.peek());
-		System.out.println(stack);
-		
-	}
-	public static void QueueTest(){
-		Queue queue = new Queue();
-		queue.enQueue("龙师傅0");
-		queue.enQueue("龙师傅1");
-		queue.enQueue("龙师傅2");
-		queue.enQueue("龙师傅3");
-		queue.enQueue("龙师傅4");
-		
-		System.out.println(queue.deQueue());
-		System.out.println(queue.deQueue());
-		System.out.println(queue.deQueue());
-		System.out.println(queue.deQueue());
-		System.out.println(queue.size());
-	
-		
-	}
-}
\ No newline at end of file
diff --git a/group04/120549547/base/src/com/coding/basic/Queue.java b/group04/120549547/base/src/com/coding/basic/Queue.java
deleted file mode 100644
index 8f86f7492c..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Queue.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.*;
-public class Queue {
-	private LinkedList list;
-	
-	public Queue(){
-		list = new LinkedList();
-	}
-	/*入队*/
-	public void enQueue(Object o){
-		list.addLast(o);
-	}
-	
-	/*出队*/
-	public Object deQueue(){
-		if (isEmpty()){
-			System.out.println("队空");
-		}
-		return list.removeFirst();
-	}
-	
-	public boolean isEmpty(){
-		return list.isEmpty();
-	}
-	
-	public int size(){
-		return list.size();
-	}
-}
diff --git a/group04/120549547/base/src/com/coding/basic/Stack.java b/group04/120549547/base/src/com/coding/basic/Stack.java
deleted file mode 100644
index f7d3bba3db..0000000000
--- a/group04/120549547/base/src/com/coding/basic/Stack.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.coding.basic;
-import com.coding.basic.LinkedList;
-
-public class Stack {
-	private LinkedList list;
-	
-	public Stack(){
-		list = new LinkedList();
-	}
-	
-	public void push(Object o){
-		list.addLast(o);
-	}
-	
-	public Object pop(){
-		if(isEmpty()){
-			System.out.println("栈空");
-		}
-		return list.removeLast();
-		
-	}
-	
-	public Object peek(){
-		return list.get(list.size()-1);
-	}
-	public boolean isEmpty(){
-		return list.isEmpty();
-	}
-	public int size(){
-		return list.size();
-	}
-	
-	@Override
-	public String toString(){
-		return list.toString();
-	}
-}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java
new file mode 100644
index 0000000000..d7ac820192
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/BinaryTreeNode.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class BinaryTreeNode {
+	
+	private Object data;
+	private BinaryTreeNode left;
+	private BinaryTreeNode right;
+	
+	public Object getData() {
+		return data;
+	}
+	public void setData(Object data) {
+		this.data = data;
+	}
+	public BinaryTreeNode getLeft() {
+		return left;
+	}
+	public void setLeft(BinaryTreeNode left) {
+		this.left = left;
+	}
+	public BinaryTreeNode getRight() {
+		return right;
+	}
+	public void setRight(BinaryTreeNode right) {
+		this.right = right;
+	}
+	
+	public BinaryTreeNode insert(Object o){
+		return  null;
+	}
+	
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java
new file mode 100644
index 0000000000..31d6470bef
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Iterator.java
@@ -0,0 +1,8 @@
+package com.coding.basic;
+
+public interface Iterator<T> {
+	 boolean hasNext();
+
+	 T next();
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/List.java b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java
new file mode 100644
index 0000000000..70a783968e
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/List.java
@@ -0,0 +1,31 @@
+package com.coding.basic;
+
+public interface List<T>{
+	int size();
+
+	boolean isEmpty();
+
+	boolean contains(Object o);
+
+	Object[] toArray();
+
+	boolean add(T o);
+
+	boolean remove(T o);
+
+	void clear();
+
+	T get(int index);
+
+	T set(int index, T o);
+
+	void add(int index, T o);
+
+	T remove(int index);
+
+	int indexOf(T o);
+
+	Iterator<T> iterator();
+
+	void printf();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..459ec560b4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/Stack.java
@@ -0,0 +1,24 @@
+package com.coding.basic;
+
+import com.coding.basic.array.ArrayList;
+
+public class Stack {
+	private ArrayList elementData = new ArrayList();
+	
+	public void push(Object o){		
+	}
+	
+	public Object pop(){
+		return null;
+	}
+	
+	public Object peek(){
+		return null;
+	}
+	public boolean isEmpty(){
+		return false;
+	}
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java
new file mode 100644
index 0000000000..6c392a3618
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayList.java
@@ -0,0 +1,155 @@
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+import java.util.Objects;
+
+public class ArrayList<T> implements List<T> {
+
+	private int size;
+	private Object[] dataArray = new Object[0];
+
+	public int size() {
+		return this.size;
+	}
+
+	public boolean isEmpty() {
+		return this.size == 0;
+	}
+
+	public boolean contains(Object o) {
+		for (Object obj : dataArray) {
+			if (Objects.equals(obj, o)){
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public Object[] toArray() {
+		Object[] array = new Object[size];
+		System.arraycopy(dataArray, 0, array, 0, size);
+		return array;
+	}
+
+	public boolean add(T o) {
+		ensureCapacity(size+1);
+		dataArray[size] = o;
+		size++;
+		return true;
+	}
+
+
+
+	public boolean remove(T o) {
+		int index = indexOf(o);
+		if (index < 0){
+			return false;
+		}
+
+		System.arraycopy(dataArray, index + 1, dataArray, index, size - 1 - index);
+		dataArray[size - 1] = null;
+		size--;
+		return  true;
+	}
+
+	public void clear() {
+		for (int i = 0; i < size; i++) {
+			dataArray[i] = null;
+		}
+		size = 0;
+	}
+    @SuppressWarnings("unchecked")
+	public T get(int index) {
+		if (index < 0 || index >= size){
+			throw new IndexOutOfBoundsException();
+		}
+
+		return (T) dataArray[index];
+	}
+
+	public T set(int index, T o) {
+        if (index < 0 || index >= size){
+            throw new IndexOutOfBoundsException();
+        }
+        dataArray[index] = o;
+        return  o;
+	}
+
+	public void add(int index, T o) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException();
+        }
+        ensureCapacity(size + 1);
+        System.arraycopy(dataArray, index, dataArray, index + 1, size - index);
+
+        dataArray[index] = o;
+
+        size++;
+	}
+
+	public T remove(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException();
+        }
+        T removeData = (T) dataArray[index];
+        System.arraycopy(dataArray, index + 1, dataArray, index, size - index -1 );
+        dataArray[size - 1] = null;
+        size--;
+        return  removeData;
+	}
+
+	public int indexOf(T o) {
+        for (int i = 0; i < size; i++) {
+            if (Objects.equals(o, dataArray[i])){
+                return  i;
+            }
+        }
+        return  -1;
+    }
+
+	public Iterator<T> iterator() {
+		return new ArrayListIterator();
+	}
+
+	@Override
+	public void printf() {
+		for (int i = 0; i < size; i++) {
+			if (i == size - 1){
+				System.out.print(dataArray[i]);
+			}else {
+				System.out.print(dataArray[i] + "->");
+			}
+		}
+	}
+
+	private void ensureCapacity(int minCapacity) {
+		if (minCapacity > dataArray.length){
+			int newCapacity = Math.max(minCapacity, dataArray.length * 2);
+			Object[] newDataArray = new Object[newCapacity];
+			System.arraycopy(dataArray, 0, newDataArray, 0, dataArray.length);
+			dataArray = newDataArray;
+		}
+
+	}
+
+
+    private class ArrayListIterator implements Iterator<T> {
+
+        private int pos;
+
+        @Override
+        public boolean hasNext() {
+            return pos < size();
+        }
+
+        @Override
+        public T next() {
+            if (hasNext()){
+                return get(pos++);
+            }
+            return null;
+        }
+    }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java
new file mode 100644
index 0000000000..411b60990b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/array/ArrayUtil.java
@@ -0,0 +1,269 @@
+package com.coding.basic.array;
+
+import java.util.Arrays;
+
+public class ArrayUtil {
+	
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换
+		例如： a = [7, 9 , 30, 3]  ,   置换后为 [3, 30, 9,7]
+		如果     a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * @param origin
+	 * @return
+	 */
+	public static void reverseArray(int[] origin){
+
+		if (origin == null || origin.length == 0){
+			return;
+		}
+
+		int temp ;
+		for (int i = 0; i < (origin.length / 2); i++) {
+			temp = origin[i];
+			origin[i] = origin[(origin.length - 1) - i];
+			origin[(origin.length - 1)- i] = temp;
+		}
+	}
+
+	/**
+	 * 现在有如下的一个数组：   int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}   
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为：   
+	 * {1,3,4,5,6,6,5,4,7,6,7,5}  
+	 * @param oldArray
+	 * @return
+	 */
+	
+	public static int[] removeZero(int[] oldArray){
+		if (oldArray == null ){
+			return null;
+		}
+
+		if (oldArray.length == 0){
+			return oldArray;
+		}
+
+		int count = 0;
+		int[] temp = new int[oldArray.length];
+
+		for (int i = 0; i < oldArray.length; i++) {
+			if (oldArray[i] != 0){
+				temp[count++] = oldArray[i];
+			}
+		}
+
+		int[] result = new int[count];
+
+		System.arraycopy(temp, 0, result, 0, count);
+		return result;
+	}
+	
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 ,  创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的
+	 * 例如 a1 = [3, 5, 7,8]   a2 = [4, 5, 6,7]    则 a3 为[3,4,5,6,7,8]    , 注意： 已经消除了重复
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+	
+	public static int[] merge(int[] array1, int[] array2){
+		if (array1 == null && array2 == null){
+			return null;
+		}
+
+		if (array1 == null){
+			return array2;
+		}
+
+		if (array2 == null){
+			return array1;
+		}
+
+		int length1 = array1.length;
+		int length2 = array2.length;
+		int[] temp = new int[length1 + length2];
+		int i,j,k;
+		for ( i = 0, j = 0, k = 0; i < length1 && j < length2 ;) {
+
+			if (array1[i] < array2[j]){
+				temp[k++] = array1[i++];
+			}else if (array1[i] > array2[j]){
+				temp[k++] = array2[j++];
+			}else {
+				temp[k++] = array1[i];
+				i++;
+				j++;
+			}
+		}
+
+		while (i < length1){
+			temp[k++] = array1[i++];
+		}
+
+		while (j < length2){
+			temp[k++] = array2[j++];
+		}
+		int[] result = new int[k];
+		System.arraycopy(temp, 0, result, 0, k);
+		return result;
+
+	}
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持
+	 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public static int[] grow(int [] oldArray,  int size){
+
+		int oldSize = oldArray.length;
+		int[] newArray = new int[oldSize + size];
+
+		System.arraycopy(oldArray, 0, newArray, 0, oldSize);
+
+		return newArray;
+	}
+	
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21......  ，给定一个最大值， 返回小于该值的数列
+	 * 例如， max = 15 , 则返回的数组应该为 [1，1，2，3，5，8，13]
+	 * max = 1, 则返回空数组 []
+	 * @param max
+	 * @return
+	 */
+	public static int[] fibonacci1(int max){
+		if (max == 1){
+			return new int[0];
+		}
+
+		int[] temp = new int[max];
+		int count = 0;
+//		for (int i = 1; i < max; i++) {
+//			int num = fibonacci(i);
+//			if (num < max){
+//				temp[count++] = num;
+//			}else {
+//				break;
+//			}
+//		}
+		temp[0] = 1;
+		temp[1] = 2;
+		for (int i = 2; i < max; i++) {
+			temp[i] = temp[i-1] + temp[i-2];  //直接在数组中实现斐波那契数列
+			if (temp[i] >= max){
+				break;
+			}else {
+				count++;
+			}
+		}
+
+
+
+		return Arrays.copyOf(temp, count);
+	}
+
+	private static int fibonacci(int n){
+		if (n <= 0){
+			throw new IllegalArgumentException();
+		}
+
+		if (n == 1 || n == 2) {
+			return 1;
+		}
+
+		return fibonacci(n - 1) + fibonacci(n - 2);
+
+	}
+	/**
+	 * 返回小于给定最大值max的所有素数数组
+	 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * @param max
+	 * @return
+	 */
+	public static int[] getPrimes(int max){
+
+		if (max <= 2){
+			return new int[0];
+		}
+
+		int[] temp = new int[max];
+
+		int count = 0;
+		for (int i = 2; i < max; i++) {
+			int j;
+			for ( j = 2; j * j < i; j++) {
+				if (i % j == 0){
+					break;
+				}
+			}
+
+			if (j * j >= i){
+				temp[count++] = i;
+			}
+		}
+
+		return Arrays.copyOf(temp, count);
+	}
+	
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+	 * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * @param max
+	 * @return
+	 */
+	public static int[] getPerfectNumbers(int max){
+		if ( max <= 1){
+			return new int[0];
+		}
+
+		ArrayList<Integer> array = new ArrayList<>();
+		for (int i = 2; i < max; i++) {
+			int sum = 0; //存储因子和
+			for (int j = 1; j < i; j++) {
+				if (i % j == 0){
+					sum += j;
+				}
+			}
+
+			if (sum == i){
+				array.add(i);
+			}
+		}
+		int[] result = new int[array.size()];
+
+		for (int i = 0; i < array.size(); i++) {
+			result[i] = array.get(i);
+		}
+		return result;
+
+
+	}
+	
+	/**
+	 * 用seperator 把数组 array给连接起来
+	 * 例如array= [3,8,9], seperator = "-"
+	 * 则返回值为"3-8-9"
+	 * @param array
+	 * @param s
+	 * @return
+	 */
+	public static String join(int[] array, String seperator){
+
+		if (array == null || array.length == 0){
+			return null;
+		}
+
+		StringBuilder sb = new StringBuilder("");
+		for (int i = 0; i < array.length-1; i++) {
+			 sb.append(array[i]).append(seperator);
+		}
+
+		sb.append(array[array.length-1]);
+
+		return sb.toString();
+	}
+	
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..a4f2c14606
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,60 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		
+	
+	}
+	
+	
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..67cf36067b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package com.coding.basic.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java
new file mode 100644
index 0000000000..eb128c4b24
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/linklist/LinkedList.java
@@ -0,0 +1,369 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+import java.util.Objects;
+
+public class LinkedList<T> implements List<T> {
+	private int size;
+
+	private Node<T> head;
+
+	private Node<T> last;
+
+
+
+	private static class Node<T> {
+		T data;
+		Node pre;
+		Node next;
+
+		Node(T data) {
+			this.data = data;
+		}
+
+
+	}
+
+	public LinkedList(){
+		this.head = new Node<>(null);
+	}
+
+	@Override
+	public int size() {
+		return this.size;
+	}
+
+	@Override
+	public boolean isEmpty() {
+		return this.size == 0;
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		Node node = this.head;
+		while (node.next != null){
+			if (Objects.equals(node.data, o)){
+
+				return true;
+			}
+			node = node.next;
+		}
+		return false;
+	}
+
+	@Override
+	public Object[] toArray() {
+		Object[] dataArray  = new Object[size];
+		Node node = head.next;
+		for (int i = 0; i < size&& node != null; i++, node = node.next) {
+			dataArray[i] = node.data;
+
+		}
+		return dataArray;
+	}
+
+	@Override
+	public boolean add(T o) {
+		if (this.last == null){
+			this.last = new Node<>(o);
+			this.last.pre = this.head;
+			this.head.next = this.last;
+		}else {
+			Node oldLast = this.last;
+			this.last = new Node<>(o);
+			this.last.pre = oldLast;
+			oldLast.next = this.last;
+
+		}
+		this.size++;
+		return  true;
+	}
+	@SuppressWarnings("unchecked")
+	@Override
+	public boolean remove(T o) {
+
+
+		Node<T> curNode = head.next;
+		Node<T> preNode;
+		while (curNode != null){
+			preNode = curNode.pre;  //指向前一个节点
+
+			if (Objects.equals(curNode.data, o)){
+				removeNode(preNode, curNode);
+				return true;
+			}
+			curNode = curNode.next;
+		}
+
+		return false;
+	}
+
+	private void removeNode(Node<T> preNode, Node<T> node) {
+
+		if (this.last == node){		//如果删除的是last节点的情况
+			if (preNode == this.head){ //如果只有一个节点的情况
+				this.last = null;
+			}else {
+				this.last = preNode;
+			}
+		}else {
+			node.next.pre = node.pre;
+
+		}
+		preNode.next = node.next;
+
+
+
+
+		this.size--;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public void clear() {
+		for (Node x = head; x != null;){
+			Node<T> next = x.next;
+			x.data = null;
+			x.pre = null;
+			x.next = null;
+			x = next;
+		}
+		head = last = null;
+		size = 0;
+		
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public T get(int index) {
+		return (T) getNode(index).data;
+	}
+
+
+
+	@Override
+	public T set(int index, T o) {
+		Node node = getNode(index);
+		node.data = o;
+		return o;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void add(int index, T o) {
+		ensureIndex(index);
+		Node<T> newNode = new Node<>(o);
+		Node curNode = getNode(index);
+		Node pre = curNode.pre;
+
+		newNode.next = curNode;
+		newNode.pre = pre;
+		curNode.pre = newNode;
+		pre.next = newNode;
+
+		size++;
+
+	}
+
+	@Override
+	public T remove(int index) {
+		Node node = getNode(index);
+		Node pre = node.pre;
+		if (node == last){ //如果是最后一个节点
+			if (pre != head){ //如果是唯一节点
+				last = null;
+			}else {
+				last = node.pre;
+			}
+		}
+
+		pre.next = node.next;
+		if (node.next != null){
+			node.next.pre = pre;
+		}
+		size--;
+		return (T) node.data;
+	}
+
+	@Override
+	public int indexOf(T o) {
+		Node node = head;
+		int index = 0;
+
+		while (node.next != null){
+			node = node.next;
+			if (Objects.equals(node.data, o)){
+				return index;
+			}
+			index ++;
+		}
+		return index;
+	}
+
+	@Override
+	public Iterator<T> iterator() {
+		return new LinkedListIterator();
+	}
+
+	@Override
+	public void printf() {
+		Node node = head.next;
+		while (node != null){
+			if (node.next != null) {
+				System.out.print(node.data + " -> ");
+			}else {
+				System.out.print(node.data);
+			}
+			node = node.next;
+		}
+		System.out.println();
+		System.out.println("head = " + head);
+		System.out.println("last = " + last);
+
+	}
+
+
+	private Node getNode(int index) {
+		ensureIndex(index);
+		Node node = this.head;
+		for (int i = 0; i <= index; i++) {
+			node = node.next;
+		}
+		return node;
+	}
+
+	private void ensureIndex(int index) {
+		if (index < 0 || index >= size) {
+			throw new IndexOutOfBoundsException();
+		}
+	}
+
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){		
+		if (head.next == null && head.next.next == null){ //如果链表为空或者只有一个元素,不做变换
+			return;
+		}
+
+		last = head.next;
+
+		Node pre = head.next;
+		Node cur = pre.next;
+		Node next;
+		pre.next = null;
+		while (cur != null){
+			next = cur.next;
+			cur.next = pre;
+			pre = cur;
+			cur = next;
+		}
+		head.next = pre;
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		if (isEmpty()){
+			return;
+		}
+		int halfIndex = size / 2;
+
+		if (halfIndex >= 0){
+			head.next = getNode(halfIndex);
+		}
+
+		size = size - halfIndex;
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		ensureIndex(i);
+		ensureIndex(i + length - 1);
+
+		for (int j = i; j < i + length; j++) {
+			remove(i);
+		}
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		return null;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		return null;
+	}
+
+	private class LinkedListIterator implements Iterator<T> {
+		private Node node;
+
+		LinkedListIterator(){
+			node = head;
+		}
+		@Override
+		public boolean hasNext() {
+			return node.next != null;
+		}
+
+		@Override
+		public T next() {
+			if (hasNext()){
+				node = node.next;
+				return (T) node.data;
+			}
+			return null;
+		}
+	}
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java
new file mode 100644
index 0000000000..db2047f096
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/ArrayQueue.java
@@ -0,0 +1,97 @@
+package com.coding.basic.queue;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayQueue<T> implements Queue<T> {
+
+    private int size;
+    private Object[] dataArray;
+    private int front;
+    private int rear;
+
+    public ArrayQueue(int Capacity) {
+        this.dataArray = new Object[Capacity];
+        this.front = 0;
+        this.rear = 0;
+        this.size = 0;
+    }
+
+    @Override
+    public boolean add(T t) {
+       if (offer(t)){
+           return true;
+       }else {
+           throw new IllegalStateException();
+       }
+    }
+
+    @Override
+    public boolean offer(T t) {
+        if (size >= dataArray.length){
+            return false;
+        }
+
+        dataArray[rear++] = t;
+
+        if (rear == dataArray.length){
+            rear = 0;
+        }
+
+        size++;
+        return true;
+    }
+
+    @Override
+    public T remove() {
+        T value = poll();
+        if (value != null){
+            return value;
+        }else {
+            throw new NoSuchElementException();
+        }
+    }
+
+    @Override
+    public T poll() {
+        if (size == 0){
+            return  null;
+        }
+
+
+        T value = (T) dataArray[front++];
+        if (front == dataArray.length){
+            front = 0;
+        }
+
+        size--;
+        return value;
+
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+
+    @Override
+    public T peek() {
+        if (size == 0){
+            return null;
+        }else {
+            return (T) dataArray[front];
+        }
+    }
+
+    public void printf() {
+        for (int i = 0; i < size; i++) {
+
+            System.out.print(dataArray[(front + i) % dataArray.length] + " ");
+        }
+    }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java
new file mode 100644
index 0000000000..64f86616f4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/basic/queue/Queue.java
@@ -0,0 +1,16 @@
+package com.coding.basic.queue;
+
+public interface Queue<T> {
+
+	boolean add(T t);
+
+	boolean offer(T t);
+
+	T remove();
+
+	T poll();
+
+	boolean isEmpty();
+
+	T peek();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java
new file mode 100644
index 0000000000..9fc2c860d2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/DownloadThread.java
@@ -0,0 +1,21 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+
+	public DownloadThread( Connection conn, int startPos, int endPos){
+		
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+	}
+	public void run(){	
+		
+	}
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java
new file mode 100644
index 0000000000..ec975a9aae
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloader.java
@@ -0,0 +1,73 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+
+public class FileDownloader {
+	
+	String url;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+	
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			
+			conn = cm.open(this.url);
+			
+			int length = conn.getContentLength();	
+			
+			new DownloadThread(conn,0,length-1).start();
+			
+		} catch (ConnectionException e) {
+			e.printStackTrace();
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+		
+		
+		
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..84fbc8afa2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coding.download;
+
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+import com.coding.download.impl.ConnectionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url = "http://localhost:8080/test.jpg";
+		
+		FileDownloader downloader = new FileDownloader(url);
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java
new file mode 100644
index 0000000000..65f3dae9c5
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coding.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1db8b093ec
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..1d1a83caf2
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java
new file mode 100644
index 0000000000..c41045b0e8
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..0ddbf36e1b
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionImpl.java
@@ -0,0 +1,28 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+
+import java.io.IOException;
+
+
+public class ConnectionImpl implements Connection {
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		
+		return null;
+	}
+
+	@Override
+	public int getContentLength() {
+		
+		return 0;
+	}
+
+	@Override
+	public void close() {
+		
+		
+	}
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..0f1c658a60
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,16 @@
+package com.coding.download.impl;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		
+		return null;
+	}
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java
new file mode 100644
index 0000000000..26799a83a4
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Configuration.java
@@ -0,0 +1,124 @@
+package com.coding.litestruts;
+
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class Configuration {
+    Map<String, ActionConfig> actions = new HashMap<>();
+
+
+
+    public Configuration(String path) throws IOException {
+
+        URL pathName = Configuration.class.getClassLoader().getResource(path);
+
+        assert pathName != null;
+//        InputStream is = this.getClass().getClassLoader().getResourceAsStream(path);    默认则是从ClassPath根下获取，path不能以’/'开头
+//        InputStream is = this.getClass().getResourceAsStream("/" + path);                // path 不以’/'开头时默认是从此类所在的包下取资源，以’/'开头则是从ClassPath根下获取
+//        InputStream is = pathName.openStream();
+        InputStream is = new FileInputStream(pathName.getPath());
+
+        parseXML(is);
+
+        try {
+            is.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void parseXML(InputStream is) {
+
+        SAXReader reader = new SAXReader();
+
+        try {
+
+            Document doc = reader.read(is);
+            Element root = doc.getRootElement();
+            Iterator it = root.elementIterator("action");
+
+            while (it.hasNext()){
+
+                Element ActionElement = (Element) it.next();
+
+                String actionName = ActionElement.attributeValue("name");
+                String className = ActionElement.attributeValue("class");
+
+                ActionConfig ac = new ActionConfig(actionName, className);
+
+                Iterator it2 = ActionElement.elementIterator();
+
+                while (it2.hasNext()){
+
+                    Element resultElement = (Element) it2.next();
+
+                    String resultName = resultElement.attributeValue("name");
+                    String viewName = resultElement.getTextTrim();
+
+                    ac.addViewResult(resultName, viewName);
+                }
+
+                this.actions.put(actionName, ac);
+            }
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String getClassName(String actionName) {
+        ActionConfig ac = actions.get(actionName);
+        if (ac == null) {
+            return null;
+        }
+        return ac.getClassName();
+    }
+
+    public String getResultView(String actionName, String resultName) {
+        ActionConfig ac = actions.get(actionName);
+        if (ac == null) {
+            return null;
+        }
+        return ac.getViewName(resultName);
+
+    }
+
+
+    private static class ActionConfig{
+        String name;
+        String clzName;
+        Map<String, String> viewResult = new HashMap<>();
+
+        public ActionConfig(String name, String clzName) {
+            this.name = name;
+            this.clzName = clzName;
+        }
+
+        public String getClassName() {
+            return clzName;
+        }
+
+        public void addViewResult(String name, String viewName){
+            viewResult.put(name, viewName);
+
+        }
+
+        public String getViewName(String resultName){
+            return viewResult.get(resultName);
+        }
+    }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java
new file mode 100644
index 0000000000..39354518df
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coding.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java
new file mode 100644
index 0000000000..6b761355b1
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/ReflectionUtil.java
@@ -0,0 +1,85 @@
+package com.coding.litestruts;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ReflectionUtil {
+
+    public static List<Method> getSetterMethods(Class clz) {
+
+        return getMethods(clz, "set");
+    }
+
+    public static void setParameters(Object o, Map<String, String> params) {
+
+        List<Method> methods = getSetterMethods(o.getClass());
+
+        for (String name : params.keySet()) {
+
+            String methodName = "set" + name;
+
+            for (Method method : methods) {
+
+                if (method.getName().equalsIgnoreCase(methodName)){
+                    try {
+                        method.invoke(o,params.get(name));
+
+
+
+
+
+
+                    } catch (IllegalAccessException | InvocationTargetException e) {
+
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    public static List<Method> getGetterMethods(Class clz) {
+        return getMethods(clz, "get");
+    }
+
+    private static List<Method> getMethods(Class clz, String startWithName) {
+        List<Method> methods = new ArrayList<>();
+
+        for (Method method : clz.getDeclaredMethods()) {
+
+            if (method.getName().startsWith(startWithName)) {
+                methods.add(method);
+            }
+        }
+        return methods;
+    }
+
+    public static Map<String,Object> getParamterMap(Object o) {
+        Map<String, Object> params = new HashMap<>();
+
+        List<Method> methods = getGetterMethods(o.getClass()); //获得"getXXX"方法
+
+        for (Method method : methods) {
+
+            String methodName = method.getName();
+            String name = methodName.replaceFirst("get", "").toLowerCase();  //获得属性名
+
+            try {
+                params.put(name,method.invoke(o));       //将属性名 和属性值添加进去
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return params;
+
+    }
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java
new file mode 100644
index 0000000000..f446bec31c
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/Struts.java
@@ -0,0 +1,67 @@
+package com.coding.litestruts;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+
+
+    public static View runAction(String actionName, Map<String,String> parameters) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
+
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+        try {
+            Configuration cfg = new Configuration("struts.xml");
+
+            String clzName = cfg.getClassName(actionName);
+            if (clzName == null) {
+                return null;
+            }
+            String classPath = Struts.class.getClassLoader().getResource("").getPath();
+
+            System.out.println("clzName = " + clzName);
+            System.out.println("classPath = " + classPath);
+            Class<?> clz = Class.forName(clzName);
+
+            Object o = clz.newInstance();
+            ReflectionUtil.setParameters(o, parameters);  //将参数注入属性
+            Method m = clz.getDeclaredMethod("execute");
+            String resultName = (String) m.invoke(o);    //执行execute方法
+
+            Map<String, Object> params = ReflectionUtil.getParamterMap(o); //根据action获取model参数
+
+            String jsp = cfg.getResultView(actionName, resultName); //通过返回结果去拿视图名
+
+            View view = new View();
+            view.setJsp(jsp);
+            view.setParameters(params);
+            return view;
+        } catch (IOException | InstantiationException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException | IllegalAccessException e) {
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..041fa4d889
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/StrutsTest.java
@@ -0,0 +1,47 @@
+package com.coding.litestruts;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
+		
+		String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() throws IllegalAccessException, InvocationTargetException, IOException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+
+
+}
diff --git a/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java
new file mode 100644
index 0000000000..b6e795aa4a
--- /dev/null
+++ b/group04/120549547/code2017/src/main/java/com/coding/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coding.litestruts;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+	
+	public String getJsp() {
+		return jsp;
+	}
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+	public Map getParameters() {
+		return parameters;
+	}
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java
new file mode 100644
index 0000000000..abd49e98e3
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayListTest.java
@@ -0,0 +1,122 @@
+package com.coding.basic.array;
+
+import com.coding.basic.Iterator;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayListTest {
+
+    private  ArrayList<Integer> arrayList;
+    @Before
+    public void init() {
+        arrayList = new ArrayList<>();
+        for (int i = 0; i < 5; i++) {
+            arrayList.add(i);
+        }
+    }
+
+    @Test
+    public void size() throws Exception {
+        Assert.assertEquals(5, arrayList.size());
+        arrayList.add(6);
+        Assert.assertEquals(6, arrayList.size());
+
+    }
+
+    @Test
+    public void isEmpty() throws Exception {
+        arrayList.clear();
+        Assert.assertEquals(0, arrayList.size());
+        Assert.assertTrue(arrayList.isEmpty());
+    }
+
+    @Test
+    public void contains() throws Exception {
+        Assert.assertTrue(arrayList.contains(0));
+        Assert.assertTrue(arrayList.contains(4));
+        Assert.assertFalse(arrayList.contains(5));
+    }
+
+    @Test
+    public void toArray() throws Exception {
+        Integer[] integers = new Integer[]{0, 1, 2, 3, 4};
+        Assert.assertArrayEquals(integers, arrayList.toArray());
+    }
+
+    @Test
+    public void add() throws Exception {
+        arrayList.add(5);
+        Assert.assertEquals(5, arrayList.get(arrayList.size() - 1).intValue());
+        arrayList.add(0, 6);
+        arrayList.add(3, 7);
+        arrayList.add(arrayList.size(), 8);
+
+        Assert.assertEquals(9, arrayList.size());
+        Assert.assertEquals(6, arrayList.get(0).intValue());
+        Assert.assertEquals(8, arrayList.get(arrayList.size()-1).intValue());
+        Assert.assertEquals(7, arrayList.get(3).intValue());
+    }
+
+    @Test
+    public void remove() throws Exception {
+        arrayList.remove(0);
+        arrayList.remove(3);
+        arrayList.add(5);
+        Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{1,2,3,5});
+
+        arrayList.remove(new Integer(1));
+        arrayList.remove(new Integer(2));
+        arrayList.remove(new Integer(5));
+        arrayList.add(6);
+        arrayList.add(7);
+
+        Assert.assertArrayEquals(arrayList.toArray(), new Integer[]{3,6,7});
+
+    }
+
+
+
+    @Test
+    public void get() throws Exception {
+        Assert.assertEquals(0, arrayList.get(0).intValue());
+        Assert.assertEquals(3, arrayList.get(3).intValue());
+        arrayList.add(5);
+        arrayList.remove(0);
+        Assert.assertEquals(5, arrayList.get(4).intValue());
+    }
+
+    @Test
+    public void set() throws Exception {
+        arrayList.set(0,100);
+        arrayList.set(arrayList.size() - 1, 50);
+        Assert.assertEquals(100, arrayList.get(0).intValue());
+        Assert.assertEquals(50, arrayList.get(arrayList.size() - 1).intValue());
+
+    }
+
+
+
+
+
+    @Test
+    public void indexOf() throws Exception {
+        Assert.assertEquals(0, arrayList.indexOf(0));
+        Assert.assertEquals(1, arrayList.indexOf(1));
+    }
+
+    @Test
+    public void iterator() throws Exception {
+        Iterator iterator = arrayList.iterator();
+        Assert.assertTrue(iterator.hasNext());
+        Assert.assertEquals(0, iterator.next());
+        Assert.assertEquals(1, iterator.next());
+    }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java
new file mode 100644
index 0000000000..f16a7ab5ab
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/array/ArrayUtilTest.java
@@ -0,0 +1,94 @@
+package com.coding.basic.array;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Created by bobi on 2017/4/4.
+ * at code2017
+ */
+public class ArrayUtilTest {
+
+    private static int[] arr;
+
+    @Before
+    public void setUp() throws Exception {
+
+        arr = new int[10];
+
+        for (int i = 0; i < arr.length; i++) {
+            arr[i] = i;
+        }
+
+    }
+
+    private static void arrPrint(int[] arr){
+        for (int i : arr) {
+            System.out.print(i + " ");
+        }
+        System.out.println();
+    }
+
+    @Test
+    public void reverseArray() throws Exception {
+        ArrayUtil.reverseArray(arr);
+        for (int i = 0; i < arr.length; i++) {
+            Assert.assertEquals(9-i, arr[i]);
+        }
+    }
+
+    @Test
+    public void removeZero() throws Exception {
+        int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
+        oldArr = ArrayUtil.removeZero(oldArr);
+
+        Assert.assertArrayEquals(new int[]{1,3,4,5,6,6,5,4,7,6,7,5}, oldArr);
+
+    }
+
+    @Test
+    public void merge() throws Exception {
+        int[] a1 = {3, 5, 7,8};
+        int[] a2 = {4, 5, 6,7} ;
+
+        int[] a3 = ArrayUtil.merge(a1, a2);
+        Assert.assertArrayEquals(new int[]{3,4,5,6,7,8}, a3);
+    }
+
+    @Test
+    public void grow() throws Exception {
+        int[] a1 = {3, 5, 7,8};
+        a1 = ArrayUtil.grow(a1, 3);
+
+        Assert.assertArrayEquals(new int[]{3,5,7,8,0,0,0}, a1);
+    }
+
+    @Test
+    public void fibonacci() throws Exception {
+       int[] arr =  ArrayUtil.fibonacci1(100);
+        arrPrint(arr);
+    }
+
+    @Test
+    public void getPrimes() throws Exception {
+        int[] a1 = ArrayUtil.getPrimes(100);
+        arrPrint(a1);
+    }
+
+    @Test
+    public void getPerfectNumbers() throws Exception {
+        int[] a1 = ArrayUtil.getPerfectNumbers(10000);
+        arrPrint(a1);
+    }
+
+    @Test
+    public void join() throws Exception {
+       int[] a1 = {3,4,5,6,7};
+        String str = ArrayUtil.join(a1, "-");
+        System.out.println("str = " + str);
+
+    }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java
new file mode 100644
index 0000000000..f020e64828
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/linklist/LinkedListTest.java
@@ -0,0 +1,155 @@
+package com.coding.basic.linklist;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Created by bobi on 2017/3/31.
+ * at code2017
+ */
+public class LinkedListTest {
+
+
+    @Before
+    public void init() {
+        linkedList = new LinkedList<>();
+        for (int i = 0; i < 6; i++) {
+            linkedList.add(1<<i);
+        }
+    }
+    @Test
+    public void reverse() throws Exception {
+        linkedList.reverse();
+        linkedList.printf();
+    }
+    @Test
+    public void contains() throws Exception {
+        Assert.assertFalse(linkedList.contains(15));
+        Assert.assertTrue(linkedList.contains(16));
+    }
+
+    @Test
+    public void clear() throws Exception {
+        linkedList.clear();
+        Assert.assertTrue(linkedList.isEmpty());
+        Assert.assertTrue(linkedList.size() == 0);
+    }
+
+    @Test
+    public void get() throws Exception {
+        Assert.assertEquals(8, linkedList.get(3).intValue());
+        linkedList.remove(3);
+        Assert.assertEquals(16, linkedList.get(3).intValue());
+
+        linkedList.set(3, 100);
+
+        Assert.assertEquals(100, linkedList.get(3).intValue());
+
+    }
+
+
+
+
+
+    private LinkedList<Integer> linkedList;
+
+    @Test
+    public void remove() throws Exception {
+        //测试添加删除
+        {
+            linkedList.printf();
+            linkedList.remove(new Integer(1));
+            linkedList.remove(new Integer(8));
+            linkedList.remove(new Integer(32));
+            linkedList.add(50);
+            linkedList.add(0, 100);
+            Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100, 2, 4, 16, 50});
+
+//
+            linkedList.remove(new Integer(16));
+            linkedList.add(linkedList.size() - 1, 25);
+            Assert.assertArrayEquals(linkedList.toArray(), new Integer[]{ 100,2, 4, 25,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             50});
+        }
+
+    }
+
+
+    @Test
+    public void removeFirstHalf() throws Exception {
+        linkedList.removeFirstHalf();
+        linkedList.removeFirstHalf();
+        linkedList.printf();
+    }
+
+    @Test
+    public void getElements() throws Exception {
+
+    }
+
+    @Test
+    public void subtract() throws Exception {
+
+    }
+
+    @Test
+    public void removeDuplicateValues() throws Exception {
+        linkedList.removeFirstHalf();
+        LinkedList list = new LinkedList<Integer>();
+        list.add(8);
+        list.add(16);
+        list.add(32);
+        Assert.assertArrayEquals(linkedList.toArray(), list.toArray());
+        linkedList.removeFirstHalf();
+        list.remove(0);
+        Assert.assertArrayEquals(linkedList.toArray(), list.toArray());
+
+    }
+
+    @Test
+    public void removeByLength() throws Exception {
+        // 测试删除开始节点
+        {
+            linkedList.remove(0, 2);
+            Assert.assertEquals(linkedList.size(), 4);
+            for (int i = 0; i < 3; i++) {
+                Assert.assertEquals(linkedList.get(i).intValue(), 1<<(i+2));
+            }
+        }
+
+        // 测试删除中间节点
+        {
+            init();
+            linkedList.remove(1, 2);
+            Assert.assertEquals(linkedList.size(), 4);
+            Assert.assertEquals(linkedList.get(0).intValue(), 1);
+            Assert.assertEquals(linkedList.get(1).intValue(), 8);
+            Assert.assertEquals(linkedList.get(2).intValue(), 16);
+        }
+//
+        // 测试删除末尾节点
+        {
+            init();
+            linkedList.remove(4, 2);
+            Assert.assertEquals(linkedList.size(), 4);
+            Assert.assertEquals(linkedList.get(0).intValue(), 1);
+            Assert.assertEquals(linkedList.get(1).intValue(), 2);
+            Assert.assertEquals(linkedList.get(2).intValue(), 4);
+            Assert.assertEquals(linkedList.get(3).intValue(), 8);
+        }
+//
+        // 测试删除全部
+        {
+            init();
+            linkedList.remove(0, 6);
+            Assert.assertEquals(linkedList.size(), 0);
+        }
+    }
+
+    @Test
+    public void intersection() throws Exception {
+
+    }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java
new file mode 100644
index 0000000000..cd0d8abcc8
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/basic/queue/ArrayQueueTest.java
@@ -0,0 +1,68 @@
+package com.coding.basic.queue;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ArrayQueueTest {
+    private ArrayQueue<Integer> arrayQueue;
+
+    @Before
+    public void init(){
+        arrayQueue = new ArrayQueue<>(6);
+        for (int i = 0; i < 5; i++) {
+            arrayQueue.add(i);
+        }
+
+    }
+    @Test
+    public void add() throws Exception {
+        Assert.assertTrue(arrayQueue.add(5));
+
+
+        Assert.assertEquals(0, arrayQueue.peek().intValue());
+        Assert.assertEquals(0, arrayQueue.poll().intValue());
+        Assert.assertEquals(1, arrayQueue.poll().intValue());
+
+        for (int i = 0; i < 4; i++) {
+            arrayQueue.remove();
+        }
+        Assert.assertTrue(arrayQueue.isEmpty());
+    }
+
+    @Test
+    public void offer() throws Exception {
+        Assert.assertTrue(arrayQueue.offer(5));
+        Assert.assertFalse(arrayQueue.offer(6));
+    }
+
+    @Test
+    public void remove() throws Exception {
+        arrayQueue.remove();
+        arrayQueue.remove();
+        arrayQueue.remove();
+        arrayQueue.remove();
+
+        arrayQueue.add(5);
+        arrayQueue.add(6);
+        arrayQueue.add(7);
+        arrayQueue.add(8);
+        arrayQueue.add(9);
+
+
+        Assert.assertEquals(4, arrayQueue.remove().intValue());
+        Assert.assertEquals(5, arrayQueue.remove().intValue());
+        Assert.assertEquals(6, arrayQueue.remove().intValue());
+        Assert.assertEquals(7, arrayQueue.remove().intValue());
+        Assert.assertEquals(8, arrayQueue.remove().intValue());
+        Assert.assertEquals(9, arrayQueue.remove().intValue());
+    }
+
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java
new file mode 100644
index 0000000000..40a3013741
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ConfigurationTest.java
@@ -0,0 +1,45 @@
+package com.coding.litestruts;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ConfigurationTest {
+    private Configuration config;
+    @Before
+    public void setUp() throws Exception {
+        config = new Configuration("struts.xml");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+
+    }
+
+
+    @Test
+    public void testGetClassName(){
+        String clzName = config.getClassName("login");
+        Assert.assertEquals("com.coding.litestruts.LoginAction", clzName);
+        clzName = config.getClassName("logout");
+        Assert.assertEquals("com.coding.litestruts.LogoutAction", clzName);
+
+    }
+
+    @Test
+    public void testGetResultView(){
+        String jsp = config.getResultView("login", "success");
+        Assert.assertEquals("jsp/homepage.jsp", jsp);
+
+        jsp = config.getResultView("login", "fail");
+        Assert.assertEquals("jsp/showLogin.jsp", jsp);
+    }
+
+}
\ No newline at end of file
diff --git a/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java
new file mode 100644
index 0000000000..d66188988b
--- /dev/null
+++ b/group04/120549547/code2017/src/test/java/com/coding/litestruts/ReflectionUtilTest.java
@@ -0,0 +1,124 @@
+package com.coding.litestruts;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Created by bobi on 2017/4/1.
+ * at code2017
+ */
+public class ReflectionUtilTest {
+    @Before
+    public void setUp() throws Exception {
+
+    }
+
+    @After
+    public void tearDown() throws Exception {
+
+    }
+
+    @Test
+    public void testGetSetterMethod() throws ClassNotFoundException {
+        String name = "com.coding.litestruts.LoginAction";
+
+        Class clz = Class.forName(name);
+        List<Method> methods = ReflectionUtil.getSetterMethods(clz);
+
+        Assert.assertEquals(2, methods.size());
+
+        List<String> expectedNames = new ArrayList<>();
+        expectedNames.add("setName");
+        expectedNames.add("setPassword");
+
+        List<String> acctualNames = new ArrayList<>();
+        for (Method method : methods) {
+            acctualNames.add(method.getName());
+        }
+
+        Assert.assertTrue(acctualNames.containsAll(expectedNames));
+
+    }
+
+    @Test
+    public  void testSetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
+        String name = "com.coding.litestruts.LoginAction";
+
+        Class clz = Class.forName(name);
+        Object o = clz.newInstance();
+
+        Map<String, String> params = new HashMap<>();
+        params.put("name", "test");
+        params.put("password", "1234");
+
+        ReflectionUtil.setParameters(o, params);
+
+
+        Field f = clz.getDeclaredField("name");
+        f.setAccessible(true);
+        Assert.assertEquals("test", f.get(o));
+
+    }
+
+
+    @Test
+    public void testGetGetterMethod() throws ClassNotFoundException {
+        String name = "com.coding.litestruts.LoginAction";
+
+        Class clz = Class.forName(name);
+        List<Method> methods = ReflectionUtil.getGetterMethods(clz);
+
+        Assert.assertEquals(3, methods.size());
+
+        List<String> expectedNames = new ArrayList<>();
+        expectedNames.add("getName");
+        expectedNames.add("getPassword");
+        expectedNames.add("getMessage");
+
+        List<String> acctualNames = new ArrayList<>();
+
+        for (Method method : methods) {
+            acctualNames.add(method.getName());
+        }
+
+        Assert.assertTrue(acctualNames.containsAll(expectedNames));
+
+    }
+
+    @Test
+    public  void testGetParameters() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
+        String name = "com.coding.litestruts.LoginAction";
+        Class clz = Class.forName(name);
+
+        LoginAction o = (LoginAction) clz.newInstance();
+        o.setName("test");
+        o.setPassword("123456");
+
+        Map<String, Object> params;
+        params = ReflectionUtil.getParamterMap(o);
+
+        Assert.assertEquals(3, params.size());
+        Assert.assertEquals(null, params.get("message"));
+        Assert.assertEquals("test", params.get("name"));
+        Assert.assertEquals("123456", params.get("password"));
+
+
+    }
+
+    @Test
+    public  void testDouble(){
+        double d = 6.02e23;
+        long i = (long) d;
+        System.out.println(i);
+    }
+}
\ No newline at end of file
diff --git a/group04/120549547/my.txt b/group04/120549547/my.txt
deleted file mode 100644
index 3da1ec26e9..0000000000
--- a/group04/120549547/my.txt
+++ /dev/null
@@ -1 +0,0 @@
-HelloWorld
diff --git a/group04/1299310140/src/com/coderising/download/DownloadThread.java b/group04/1299310140/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..ba5dab2a78
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,38 @@
+package com.coderising.download;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+	byte[] result;
+
+	public DownloadThread( Connection conn, int startPos, int endPos, byte[] result){
+		
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+		this.result = result;
+		
+	}
+	public void run(){
+		try {
+			byte[] download = this.conn.read(this.startPos, this.endPos);
+			//synchronized(this.result){
+				System.arraycopy(download, 0, this.result, this.startPos, download.length);
+				System.out.println(this.startPos+"   "+this.endPos);
+			//}
+			FileOutputStream fos = new FileOutputStream("C:\\b.jpg");
+			fos.write(this.result);
+			fos.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/group04/1299310140/src/com/coderising/download/FileDownloader.java b/group04/1299310140/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..23520a9bd3
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,83 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloader {
+	
+	String url;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm = new ConnectionManagerImpl();
+	
+	public FileDownloader(String _url) {
+		this.url = _url;
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection connOne = null;
+		Connection connTwo = null;
+		Connection connThree = null;
+		try {
+			
+			connOne = cm.open(this.url);
+			connTwo = cm.open(this.url);
+			connThree = cm.open(this.url);
+			
+			int length = connOne.getContentLength();	
+			
+			byte[] result = new byte[length];
+			new DownloadThread(connOne,0,length/3,result).start();
+			new DownloadThread(connTwo,length/3+1,length/2,result).start();
+			new DownloadThread(connThree,length/2+1,length-1,result).start();
+			
+		} catch (ConnectionException e) {			
+			e.printStackTrace();
+		}finally{
+			if(connOne != null){
+				connOne.close();
+			}
+			if(connTwo != null){
+				connTwo.close();
+			}
+			if(connThree != null){
+				connThree.close();
+			}
+		}
+		
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+	public static void main(String[] args){
+		new FileDownloader("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg").execute();
+	}
+	
+}
diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..3628dd486f
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,59 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+	private URLConnection urlconn;
+	private InputStream fis;
+	
+	public ConnectionImpl(URLConnection urlconn) {
+		super();
+		this.urlconn = urlconn;
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException{
+		this.fis = this.urlconn.getURL().openStream();
+		byte[] buffer = new byte[512];
+		int count = 0;//某次read的字节数
+		int sum = 0;//read的总字节数
+		int length = endPos - startPos + 1;//当前线程需读取的字节数
+		byte[] download = new byte[length];
+		fis.skip(startPos);
+		while((count = fis.read(buffer)) != -1){
+			if(sum + count >= length){
+				System.arraycopy(buffer, 0, download, sum, length - sum);
+				sum = length;
+				break;
+			}else{
+				System.arraycopy(buffer, 0, download, sum, count);
+				sum = sum + count;
+			}
+		}
+		return download;
+	}
+
+	@Override
+	public int getContentLength() {
+		return this.urlconn.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		if(this.fis != null){
+			try {
+				this.fis.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+
+}
diff --git a/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..3035ce9459
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,31 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		try {
+			URL myurl = new URL("http://img1.gtimg.com/17/1724/172495/17249563_980x1200_281.jpg");
+			URLConnection urlconn = myurl.openConnection();
+			ConnectionImpl conn = new ConnectionImpl(urlconn);
+			return conn;
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+}
diff --git a/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..3b0b086ee4
--- /dev/null
+++ b/group04/1299310140/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,56 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) throws Exception{
+		//com.coderising.jvm.test.EmployeeV1
+		//"com\\coderising\\jvm\\test\\EmployeeV1"
+		String clzFileName = this.getClassPath() + "\\" + className.replace(".", "\\") + ".class";
+		//FileInputStream   BufferedInputStream   ByteArrayOutputStream
+		File file = new File(clzFileName);
+		
+		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+		
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		
+		byte[] buffer = new byte[1024];
+		
+		int length = -1;
+		
+		while((length = bis.read(buffer)) != -1){
+			bos.write(buffer,0,length);
+		}
+		
+		byte[] result = bos.toByteArray();
+		bis.close();
+		bos.close();
+		
+		return result;	
+	}
+	
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+	
+	public String getClassPath(){
+		String result = "";
+		for(int i = 0;i < clzPaths.size();i++){
+			result = result + clzPaths.get(i);
+			if(i == clzPaths.size() - 1){
+				break;
+			}
+			result = result + ";";
+		}
+		return result;
+	}
+
+}
diff --git a/group04/1299310140/src/com/coding/basic/LinkedList.java b/group04/1299310140/src/com/coding/basic/LinkedList.java
index 4636bbd279..3e908613db 100644
--- a/group04/1299310140/src/com/coding/basic/LinkedList.java
+++ b/group04/1299310140/src/com/coding/basic/LinkedList.java
@@ -208,4 +208,285 @@ public String toString(){
 			return result;
 		}
 	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public void reverse(){		
+		if(this.size <= 1){
+			return;
+		}
+		Node before = null;
+		Node pres = this.head;
+		Node after = pres.next;
+		while(after != null){
+			pres.next = before;
+			before = pres;
+			pres = after;
+			after = after.next;
+		}
+		//此时pres指向最后一个节点
+		pres.next = before;
+		this.head = pres;
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+	 */
+	public void removeFirstHalf(){
+		if(this.size <= 1){
+			return;
+		}
+		Node pres = this.head;
+		Node temp = pres;
+		for(int i = 0;i < this.size / 2;i++){
+			temp = pres;
+			pres = pres.next;
+			temp.data = null;
+			temp.next = null;
+		}
+		this.head = pres;
+		this.size = this.size - this.size / 2;
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param index
+	 * @param length
+	 */
+	public void remove(int index, int length){//若length太大，size不够，则取到末尾
+		if(index < 0 || index >= this.size || length <= 0){//index小于0or大于等于size，length小于等于0，参数错误
+			return;
+		}
+		if(this.size <= 0){
+			return;
+		}
+		if(index == 0){
+			//此时index=0&&length>0&&size>0
+			Node temp = this.head;
+			for(int i = 0;i < length;i++){
+				temp = temp.next;
+				if(temp == null){
+					break;
+				}
+			}
+			this.head = temp;
+			if(temp == null){
+				this.size = 0;
+			}else{
+				this.size = this.size - length;
+			}
+		}else{
+			//此时0<index<size&&length>0&&size>0
+			Node start = this.head;
+			for(int j = 0;j < index-1;j++){
+				start = start.next;
+			}//start指向index-1
+			
+			Node end = start;
+			for(int l = 0;l <= length;l++){
+				end = end.next;
+				if(end == null){
+					break;
+				}
+			}//end指向index+length
+			start.next = end;
+			if(end == null){
+				this.size = index;
+			}else{
+				this.size = this.size - length;
+			}
+		}
+	}
+	
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public int[] getElements(LinkedList list){//若listB中的index不在0~this.size-1之中，则返回-1
+		if(this.size <= 0 || list == null || list.size <= 0){
+			return null;
+		}
+		
+		int[] result = new int[list.size()];
+		Node presIndex = list.head;
+		int index = (int)presIndex.data;
+		for(int i = 0;i < list.size();i++){
+			if(index < 0 || index >= this.size){
+				result[i] = -1;
+			}else{//index:0~this.size-1
+				result[i] = (int)this.get(index);
+			}
+			presIndex = presIndex.next;
+			if(presIndex != null){
+				index = (int)presIndex.data;
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+	 * @param list
+	 */
+	public void subtract(LinkedList list){//当前链表以及参数列表均递增有序，可有重复值
+		if(this.size == 0 || list == null || list.size() == 0){
+			return;
+		}
+		
+		//头节点的删除比较特殊，先不予考虑
+		Node thisPres = this.head.next;//指向被删除节点
+		Node thisPresBefore = this.head;//指向被删除节点的前一个节点
+		Node listPres = list.head;
+		while(thisPres != null && listPres != null){
+			if((int)thisPres.data > (int)listPres.data){
+				listPres = listPres.next;
+			}else if((int)thisPres.data < (int)listPres.data){
+				thisPresBefore = thisPresBefore.next;
+				thisPres = thisPres.next;
+			}else{//(int)thisPres.data == (int)listPres.data
+				thisPresBefore.next = thisPres.next;
+				thisPres = thisPres.next;
+				this.size--;
+			}
+		}
+		
+		//最后考虑头节点的删除情况
+		Node first = this.head;
+		Node listPresTwo = list.head;
+		while((int)first.data > (int)listPresTwo.data){
+			listPresTwo = listPresTwo.next;
+		}
+		if((int)first.data == (int)listPresTwo.data){//删除头节点
+			this.head = this.head.next;
+			this.size--;
+		}
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public void removeDuplicateValues(){
+		if(this.size <= 1){
+			return;
+		}
+		
+		Node start = this.head;
+		Node end = start.next;
+		while(end != null){
+			if((int)start.data != (int)end.data){
+				start = end;
+				end = end.next;
+			}else{//start.data == end.data
+				while((int)start.data == (int)end.data){
+					end = end.next;
+					if(end == null){
+						break;
+					}
+				}
+				start.next = end;
+			}
+		}
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public void removeRange(int min, int max){
+		if(this.size == 0 || max - min < 2 || (int)this.head.data >= max){
+			return;
+		}
+		
+		//this.size >= 1 && max - min >= 2 && this.head.data < max
+		int thisHeadData = (int)this.head.data;
+		if(thisHeadData > min && thisHeadData < max){
+			//this.size >= 1 && max - min >= 2 && 
+			//min < this.head.data < max
+			//找到新的头节点即可，this.size减小
+			Node notSmallToMax = this.head.next;
+			int sizeDec = 1;
+			while(notSmallToMax != null){
+				if((int)notSmallToMax.data >= max){
+					break;
+				}
+				notSmallToMax = notSmallToMax.next;
+				sizeDec++;
+			}
+			this.head = notSmallToMax;
+			this.size = this.size - sizeDec;
+		}else{
+			//this.size >= 1 && max - min >= 2 && 
+			//this.head.data <= min
+			Node startBefore = this.head;//第一个>min节点的前一个节点
+			Node start = startBefore.next;//第一个>min的节点
+			while(start != null){
+				if((int)start.data > min){
+					break;
+				}
+				startBefore = start;
+				start = start.next;
+			}
+			if(start == null || (int)start.data >= max){
+				//链表中不存在满足删除条件的元素
+				return;
+			}
+			
+			//至少有一个元素需要被删除
+			int sizeDec = 1;
+			Node end = start;//最后一个<max的节点
+			Node endAfter = end.next;//最后一个<max节点的后一个节点
+			while(endAfter != null){
+				if((int)endAfter.data >= max){
+					break;
+				}
+				end = endAfter;
+				endAfter = endAfter.next;
+				sizeDec++;
+			}
+			startBefore.next = endAfter;
+			this.size = this.size - sizeDec;
+		}
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public LinkedList intersection(LinkedList list){
+		if(list == null || list.size() == 0){
+			return 	new LinkedList();
+		}
+		if(this.size == 0){
+			return new LinkedList();
+		}
+		LinkedList result = new LinkedList();
+		Node thisPres = this.head;
+		Node listPres = list.head;
+		while(thisPres != null && listPres != null){
+			if((int)thisPres.data < (int)listPres.data){
+				thisPres = thisPres.next;
+			}else if((int)thisPres.data > (int)listPres.data){
+				listPres = listPres.next;
+			}else{
+				//(int)thisPres.data == (int)listPres.data
+				result.add(thisPres.data);
+				thisPres = thisPres.next;
+				listPres = listPres.next;
+			}
+		}
+		return result;
+	}
 }
diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..025327e934
--- /dev/null
+++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,136 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(int pageNum) {
+			this.pageNum = pageNum;
+		}
+		
+	}
+
+	private int capacity;
+	private int size = 0;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+	
+	public LRUPageFrame(int capacity) {		
+		this.capacity = capacity;	
+	}
+	
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		removeElement(pageNum);
+		addFirst(pageNum);
+		if(this.size > this.capacity){
+			removeLast();
+		}
+	}
+	
+	//删除链表的尾节点
+	private void removeLast(){
+		if(this.size == 0){
+			return;
+		}
+		if(this.size == 1){
+			this.first = null;
+			this.last = null;
+			this.size--;
+		}
+		Node curr = this.last;
+		this.last = curr.prev;
+		this.last.next = null;
+		curr.prev = null;
+		this.size--;
+	}
+	
+	//根据参数删除双向链表中的某个节点
+	private void removeElement(int pageNum){
+		if(this.size == 0){
+			return;
+		}
+		Node curr = this.first;
+		while(curr.pageNum != pageNum){
+			if(curr.next == null){
+				break;
+			}
+			curr = curr.next;
+		}
+		//此时curr指向被删除节点or链表最后一个节点
+		if(curr.pageNum == pageNum){
+			if(this.first == this.last){//size为1，且该节点需要被删除
+				this.first = null;
+				this.last = null;
+				this.size--;
+				return;
+			}
+			if(curr == this.first){//删除头节点
+				this.first = curr.next;
+				this.first.prev = null;
+				curr.next = null;
+				this.size--;
+				return;
+			}
+			if(curr == this.last){//删除尾节点
+				this.last = curr.prev;
+				this.last.next = null;
+				curr.prev = null;
+				this.size--;
+				return;
+			}
+			
+			//删除中间节点
+			//此时size至少为3
+			curr.next.prev = curr.prev;
+			curr.prev.next = curr.next;
+			curr.prev = null;
+			curr.next = null;
+			this.size--;
+		}
+	}
+	
+	//向双向链表的头部添加节点
+	private void addFirst(int pageNum){
+		Node curr = new Node(pageNum);
+		if(this.size == 0){
+			this.first = curr;
+			this.last = curr;
+			this.size++;
+		}else{
+			curr.next = this.first;
+			this.first.prev = curr;
+			this.first = curr;
+			this.size++;
+		}
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..52347f721d
--- /dev/null
+++ b/group04/1299310140/src/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,73 @@
+package com.coding.basic.linklist;
+
+import  org.junit.Assert;
+import org.junit.Test;
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(7);
+		frame.access(0);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+		
+		LRUPageFrame frameFive = new LRUPageFrame(5);
+		frameFive.access(7);//7
+		frameFive.access(7);//7
+		frameFive.access(0);//0 7
+		frameFive.access(7);//7 0
+		frameFive.access(0);//0 7
+		frameFive.access(1);//1 0 7
+		Assert.assertEquals("1,0,7", frameFive.toString());
+		frameFive.access(2);//2 1 0 7
+		Assert.assertEquals("2,1,0,7", frameFive.toString());
+		frameFive.access(0);//0 2 1 7
+		Assert.assertEquals("0,2,1,7", frameFive.toString());
+		frameFive.access(0);//0 2 1 7
+		Assert.assertEquals("0,2,1,7", frameFive.toString());
+		frameFive.access(3);//3 0 2 1 7
+		Assert.assertEquals("3,0,2,1,7", frameFive.toString());
+		frameFive.access(0);//0 3 2 1 7
+		Assert.assertEquals("0,3,2,1,7", frameFive.toString());
+		frameFive.access(4);//4 0 3 2 1
+		Assert.assertEquals("4,0,3,2,1", frameFive.toString());
+	}
+	
+//	@Test
+//	public void testAddFirst(){
+//		LRUPageFrame frame = new LRUPageFrame(3);
+//		frame.addFirst(1);
+//		frame.addFirst(2);
+//		Assert.assertEquals("2,1", frame.toString());
+//		frame.addFirst(3);
+//		Assert.assertEquals("3,2,1", frame.toString());
+//		frame.addFirst(4);
+//		Assert.assertEquals("4,3,2,1", frame.toString());
+//		frame.removeElement(3);
+//		Assert.assertEquals("4,2,1", frame.toString());
+//		frame.removeElement(1);
+//		Assert.assertEquals("4,2", frame.toString());
+//		frame.removeElement(4);
+//		Assert.assertEquals("2", frame.toString());
+//		frame.removeElement(2);
+//		Assert.assertEquals("", frame.toString());
+//	}
+	
+}
diff --git a/group04/1796244932/learn01/1.png b/group04/1796244932/learn01/1.png
new file mode 100644
index 0000000000..a25be7d057
Binary files /dev/null and b/group04/1796244932/learn01/1.png differ
diff --git a/group04/1796244932/learn01/pom.xml b/group04/1796244932/learn01/pom.xml
index 06c26f00c8..f62b63ec4b 100644
--- a/group04/1796244932/learn01/pom.xml
+++ b/group04/1796244932/learn01/pom.xml
@@ -21,17 +21,29 @@
       <artifactId>dom4j</artifactId>
       <version>1.6</version>
     </dependency>
+
+
+    <!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
+    <dependency>
+      <groupId>org.jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <version>2.0.2</version>
+    </dependency>
+
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.11</version>
-      <scope>test</scope>
+      <version>4.12</version>
     </dependency>
-      <dependency>
-          <groupId>org.junit.jupiter</groupId>
-          <artifactId>junit-jupiter-api</artifactId>
-          <version>RELEASE</version>
-      </dependency>
+
+    <!-- https://mvnrepository.com/artifact/io.netty/netty -->
+    <dependency>
+      <groupId>io.netty</groupId>
+      <artifactId>netty</artifactId>
+      <version>4.0.0.Alpha8</version>
+    </dependency>
+
   </dependencies>
 
 
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
index 60254997aa..a425f54e81 100644
--- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/base/MyLinkedList.java
@@ -1,6 +1,13 @@
 package com.dudy.learn01.base;
 
 
+import java.util.LinkedList;
+
+/**
+ * 单链表：
+ * 因为没有尾节点
+ * 存放时  add  1 2 3 4  实际是 4 3 2 1
+ */
 public class MyLinkedList implements MyList {
 
 	private int size = 0;
@@ -24,6 +31,7 @@ public void add(int index, Object o) {
 	}
 
 	private Node getCurrentNode(int index) {// 获取当前节点
+		checkRange(index);
 		Node current = head;
 		for(int i = 0; i< size-index -1; i++){
 			current = current.next;
@@ -56,7 +64,7 @@ public Object remove(int index) {
 		return node.data;
 	}
 
-	public int size() {
+	public  int size() {
 		return size;
 	}
 
@@ -108,6 +116,7 @@ public Object next() {
         }
     }
 
+
 	private static class Node {
 		Object data;
 		Node next;
@@ -118,15 +127,107 @@ public Node(Object data) {
 		}
 	}
 
-	
-	private void displayLink() {// 自己调试使用
-		Node current = head;
-		while(current != null){
-			System.out.print(current.data);
-			current = current.next;
+
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){
+
+		if(head == null || head.next == null){
+			return ;
+		}
+
+		Node current = head; // 当前节点  我的头节点是有数据的
+
+		while (current.next != null){
+			Node p = current.next; // 当前节点的下一个
+			current.next = p.next; // 当前节点的next ->  current.next.next (p.next)
+			p.next = head; //   current.next(p) -> head.next (插入到 head 和 第一个数据之间)
+			head = p;
 		}
-		System.out.println("");
 	}
-	
+
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+
+		int base = size;
+		Node currentNode = getCurrentNode(base / 2);
+		currentNode = null;
+		size = size - base/2;
+	}
+
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+
+        Node preNode = getCurrentNode(size - i -1);
+        Node nextNode = getCurrentNode(size - i - length-1);
+        nextNode.next = preNode;
+        size = size -length;
+    }
+	/**
+	 * 假定当前链表和list均包含已升序排列的整数
+	 * 从当前链表中取出那些list所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]
+	 * @param src
+	 */
+	public Object[] getElements(int[] src){
+		Object des[] = new Object[src.length];
+
+		for (int i = 0; i < src.length; i++){
+		    des[i] = getCurrentNode(size - 1 - i).data;
+        }
+
+	    return des;
+	}
+
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在list中出现的元素
+
+	 * @param list
+	 */
+
+	public  void subtract(LinkedList list){
+
+	}
+
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+
+	}
+
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+
+	}
+
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		return null;
+	}
 	
 }
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java
new file mode 100644
index 0000000000..84e9bd5d2c
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/EnumSingleton.java
@@ -0,0 +1,40 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by dudy on 2017/3/6.
+ */
+public enum  EnumSingleton {
+
+    SINGLETON;
+    private EnumSingleton(){}
+
+
+    public static void main(String[] args) {
+
+        ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 6000 * 10, TimeUnit.MILLISECONDS,
+                new ArrayBlockingQueue<Runnable>(5));
+
+
+        for (int i = 0; i< 16; i++){
+            executor.execute(new EnumSingletonTest());
+        }
+
+        executor.shutdown();
+
+
+    }
+}
+
+
+class  EnumSingletonTest implements  Runnable{
+
+    @Override
+    public void run() {
+        EnumSingleton singleton = EnumSingleton.SINGLETON;
+        System.out.println(singleton.hashCode());
+    }
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java
new file mode 100644
index 0000000000..8de831c354
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/SingletonDemo1.java
@@ -0,0 +1,66 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.io.Serializable;
+import java.util.concurrent.*;
+
+/**
+ * Created by dudy on 2017/3/6.
+ * 双检索 方式
+ * jdk1.5 以后 其实是线程安全的。
+ * 序列化会 破坏 单利
+ *
+ */
+public class SingletonDemo1 implements Serializable{
+
+    private  static volatile SingletonDemo1  singleton  = null; // 加 volatile 是为了 可见性，另一个就是 避免重排序
+
+    private  SingletonDemo1(){}
+
+    public  static   SingletonDemo1 getIntance(){
+
+        if (singleton == null){// 第一个避免 在 synchronized 中 一直排队
+            synchronized (SingletonDemo1.class){
+
+                if (singleton == null){// 如果对象为空，才被创建
+                    singleton = new SingletonDemo1();
+                }
+
+            }
+        }
+
+        return  singleton;
+    }
+
+
+    /**
+     * 解决 反序列化的问题
+     * @return
+     */
+    private Object readResolve() {
+        return singleton;
+    }
+
+    public static void main(String[] args) {
+
+        ExecutorService threadPool = Executors.newFixedThreadPool(10);
+
+        for (int i= 0 ;i < 5; i++){
+            threadPool.execute(new TestRunable());
+        }
+
+        threadPool.shutdown();
+
+        //new ThreadPoolExecutor(10,20,1000*2,new BlockingQueue<Thread>(),)
+
+
+    }
+
+}
+
+ class   TestRunable  implements  Runnable{
+
+     public void run() {
+         SingletonDemo1 intance = SingletonDemo1.getIntance();
+         System.out.println(intance.hashCode());
+     }
+ }
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java
new file mode 100644
index 0000000000..d8b484cd15
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/designPattern/singleton/StaticClassInnerSingleton.java
@@ -0,0 +1,63 @@
+package com.dudy.learn01.designPattern.singleton;
+
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by dudy on 2017/3/6.
+ *
+ * 静态内部类方式 实现
+ *
+ * 这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程，
+ * 它跟饿汉式不同的是（很细微的差别）：饿汉式是只要Singleton类被装载了，
+ * 那么instance就会被实例化（没有达到lazy loading效果），而这种方式是Singleton类被装载了，
+ * instance不一定被初始化。因为SingletonHolder类没有被主动使用，
+ * 只有显示通过调用getInstance方法时，才会显示装载SingletonHolder类，
+ * 从而实例化instance。想象一下，如果实例化instance很消耗资源，我想让他延迟加载，
+ * 另外一方面，我不希望在Singleton类加载时就实例化，
+ * 因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载，
+ * 那么这个时候实例化instance显然是不合适的。这个时候，这种方式相比饿汉式更加合理
+ *
+ */
+public class StaticClassInnerSingleton {
+
+    // 构造器 私有化
+    private StaticClassInnerSingleton(){}
+
+    private static  class   SingletonHolder{
+        private  static  final StaticClassInnerSingleton INSTANCE  = new StaticClassInnerSingleton();
+    }
+
+
+    public  static StaticClassInnerSingleton getInstance(){
+        return  SingletonHolder.INSTANCE;
+    }
+
+
+    public static void main(String[] args) {
+
+
+        ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10,
+                6000 * 10, TimeUnit.MILLISECONDS,
+                new LinkedBlockingDeque<Runnable>());
+
+        for (int i= 0; i<20; i++){
+            pool.execute(new StaicSingletonTest());
+            //System.out.println(StaticClassInnerSingleton.getInstance().hashCode());
+        }
+
+        pool.shutdown();
+    }
+
+
+
+}
+
+class   StaicSingletonTest  implements  Runnable{
+
+    public void run() {
+        StaticClassInnerSingleton intance = StaticClassInnerSingleton.getInstance();
+        System.out.println(intance.hashCode());
+    }
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java
new file mode 100644
index 0000000000..97ca01e13b
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/DownloadThread.java
@@ -0,0 +1,59 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.Connection;
+
+import java.io.*;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+
+public class DownloadThread extends Thread{
+
+	private Connection conn;
+    private int startPos;
+	private int endPos;
+	private RandomAccessFile raf;
+	//private CyclicBarrier cb;
+	private  CountDownLatch downLatch;
+
+
+	public DownloadThread(Connection conn, int startPos, int endPos,
+						   /*CyclicBarrier cb*/
+						   CountDownLatch downLatch){
+		
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+//		this.cb = cb;
+		this.downLatch = downLatch;
+	}
+	public void run(){
+		try {
+			byte[] read = conn.read(startPos, endPos);
+
+			System.out.println("read length: -> "+read.length);
+			//这里要注意新创建一个RandomAccessFile对象，而不能重复使用download方法中创建的
+			raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw");
+			//将写文件的指针指向下载的起始点
+			raf.seek(startPos);
+			raf.write(read, 0, read.length);
+
+			downLatch.countDown();
+//			cb.await();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}  finally {
+			try {
+				if (raf != null){
+					raf.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			if (conn != null){
+				conn.close();
+			}
+
+		}
+	}
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java
new file mode 100644
index 0000000000..eee5825b84
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/FileDownloader.java
@@ -0,0 +1,93 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.Connection;
+import com.dudy.learn01.download.api.ConnectionManager;
+import com.dudy.learn01.download.api.DownloadListener;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+
+public class FileDownloader {
+
+	private static  final  int  THREAD_NUM = 3;
+
+    private  String url;
+	
+	private  DownloadListener listener;
+	
+	private  ConnectionManager cm;
+	
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute() throws IOException {
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			//CyclicBarrier cb = new CyclicBarrier(THREAD_NUM);
+			CountDownLatch downLatch = new CountDownLatch(THREAD_NUM);
+
+			conn = cm.open(this.url);
+
+			int length = conn.getContentLength();	
+
+			for (int i = 0;i < THREAD_NUM; i++){
+
+				int start=i*length/THREAD_NUM;
+				int end = (i+1)*length/THREAD_NUM-1;
+				if(i==THREAD_NUM-1)
+				{
+					end =length;
+				}
+
+				new DownloadThread(cm.open(url),start,end,downLatch).start();
+			}
+
+			//cb.await();
+			downLatch.await();
+			getListener().notifyFinished();
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+		
+		
+		
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java
new file mode 100644
index 0000000000..513c0004e9
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.dudy.learn01.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+    /**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java
new file mode 100644
index 0000000000..71af9bf06d
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.dudy.learn01.download.api;
+
+public class ConnectionException extends Exception {
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..5f4777f6e0
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/ConnectionManager.java
@@ -0,0 +1,13 @@
+package com.dudy.learn01.download.api;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public interface ConnectionManager {
+    /**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException, IOException;
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java
new file mode 100644
index 0000000000..fa3b5bead0
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.dudy.learn01.download.api;
+
+public interface DownloadListener {
+    public void notifyFinished();
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..5eb6b45d41
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionImpl.java
@@ -0,0 +1,89 @@
+package com.dudy.learn01.download.impl;
+
+import com.dudy.learn01.download.api.Connection;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ConnectionImpl implements Connection {
+
+
+	private HttpURLConnection  connection;
+
+	public ConnectionImpl(String url) {
+		try {
+			this.connection = (HttpURLConnection) new URL(url).openConnection();
+        } catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+    public  byte[] read(int startPos, int endPos) throws IOException {
+
+        connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+
+        InputStream in = connection.getInputStream();
+        byte buffer[] = new byte[endPos-startPos+1];
+        byte result[] = new byte[endPos-startPos+1];
+        int count = 0; // 记录已经读取的数据
+        int length = -1 ;
+
+        while ((length = in.read(buffer)) > 0){
+           System.arraycopy(buffer,0,result,count,length);
+           count += length;
+        }
+        return result;
+	}
+
+	@Override
+	public int getContentLength() {
+		return connection.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		if (connection != null){
+			connection.disconnect();
+		}
+	}
+
+    public static void main(String[] args) throws  Exception{
+	    //String PATH = "http://demo2.yun.myuclass.com/upload/demo2.yun.myuclass.com/winshare/pagelogo/250617391.png";
+        String PATH = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png";
+
+        URL url = new URL(PATH);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        //conn.setConnectTimeout(5000);
+        //conn.setRequestMethod("GET");
+        //设置头部的参数，表示请求服务器资源的某一部分
+        //conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+        //设置了上面的头信息后，响应码为206代表请求资源成功，而不再是200
+        int code = conn.getResponseCode();
+        System.out.println(conn.getContentLength());
+        if(code == 200){
+
+            InputStream is = conn.getInputStream();
+            int hasRead = 0;
+            byte[] buf = new byte[conn.getContentLength()];
+            System.out.println(buf.length);
+            //这里要注意新创建一个RandomAccessFile对象，而不能重复使用download方法中创建的
+            RandomAccessFile raf = new RandomAccessFile(new File("/Users/dudy/Desktop/1.png"), "rw");
+            //将写文件的指针指向下载的起始点
+            raf.seek(0);
+
+            while((hasRead = is.read(buf,0,conn.getContentLength())) > 0) {
+                System.out.println("hasRead = " + hasRead);
+                raf.write(buf, 0, hasRead);
+            }
+            is.close();
+            raf.close();
+            conn.disconnect();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..809f98d91b
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,25 @@
+package com.dudy.learn01.download.impl;
+
+import com.dudy.learn01.download.api.Connection;
+import com.dudy.learn01.download.api.ConnectionException;
+import com.dudy.learn01.download.api.ConnectionManager;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+
+	private Connection connection = null;
+
+	@Override
+    public Connection open(String url) throws ConnectionException, IOException {
+
+		connection = new ConnectionImpl(url);
+
+		return connection;
+	}
+
+}
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java
new file mode 100644
index 0000000000..e4239ae521
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/juc/ThreadLocalTest.java
@@ -0,0 +1,64 @@
+package com.dudy.learn01.juc;
+
+/**
+ * Created by dudy on 2017/3/9.
+ *
+ * 4. ThreadLocal  这个类实现原理和用途，在哪里用到了
+ * 每个ThreadLocal可以放一个线程级别的变量,但是它本身可以被多个线程共享变量，而且又可以达到线程安全的目的，且绝对线程安全
+ * spring的事物管理Session, 连接池管理 Connection
+ * https://my.oschina.net/huangyong/blog/159725
+ * 数据库事物的前提是: 必须是同一个连接
+ */
+public class ThreadLocalTest {
+
+    static  class  Resource{
+        public  static final ThreadLocal RESOURCE1 = new ThreadLocal();
+        public  static final ThreadLocal RESOURCE2 = new ThreadLocal();
+    }
+
+    static class  A {
+        public  void setOne(String str){
+            Resource.RESOURCE1.set(str);
+        }
+
+        public  void setTwo(String str){
+            Resource.RESOURCE2.set(str);
+        }
+    }
+
+    static  class B {
+        public void display(){
+            System.out.println(Resource.RESOURCE1.get()
+                +":" + Resource.RESOURCE2.get());
+        }
+    }
+
+    public static void main(String[] args) {
+
+        final  A a = new A();
+        final  B b = new B();
+
+        for (int i = 0; i< 5 ;i++){
+
+            final String resource1 = "Thread_" + i;
+            final String resource2 = "value " + i;
+
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        a.setOne(resource1);
+                        a.setTwo(resource2);
+                        b.display();
+                    }finally {
+                        Resource.RESOURCE2.remove();
+                        Resource.RESOURCE1.remove();
+                    }
+                }
+            }).start();
+        }
+
+    }
+
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
index bbe8c108ca..c08ae7ae49 100644
--- a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/Struts.java
@@ -46,6 +46,7 @@ public static View runAction(String actionName, Map<String,String> parameters) {
             for (Map.Entry<String, String> entry : parameters.entrySet()) {
                 System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
                 // 这里 只能传递object吧
+                //actionClass.gett
                 Method method = actionClass.getDeclaredMethod(methodNameconversion(entry.getKey()), String.class);
                 method.setAccessible(true);
                 method.invoke(base,entry.getValue());
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java
new file mode 100755
index 0000000000..987696acde
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Configuration.java
@@ -0,0 +1,113 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+
+public class Configuration {
+
+	Map<String,ActionConfig> actions = new HashMap<>();
+	
+	public Configuration(String fileName) {		
+		
+		String packageName = this.getClass().getPackage().getName();
+		
+		packageName = packageName.replace('.', '/');
+		
+		InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName);
+		
+		parseXML(is);
+		
+		try {
+			is.close();
+		} catch (IOException e) {			
+			throw new ConfigurationException(e);
+		}
+	}
+	
+	private void parseXML(InputStream is){
+		
+		 SAXBuilder builder = new SAXBuilder();
+		 
+		 try {
+			 
+			Document doc = builder.build(is);
+			
+			Element root = doc.getRootElement();
+			
+			for(Element actionElement : root.getChildren("action")){
+				
+				String actionName = actionElement.getAttributeValue("name");
+				String clzName = actionElement.getAttributeValue("class");
+				
+				ActionConfig ac = new ActionConfig(actionName, clzName);
+				
+				for(Element resultElement : actionElement.getChildren("result")){
+					
+					String resultName = resultElement.getAttributeValue("name");
+					String viewName = resultElement.getText().trim();
+					
+					ac.addViewResult(resultName, viewName);
+					
+				}
+				
+				this.actions.put(actionName, ac);
+			}
+			
+			
+		} catch (JDOMException e) {
+			throw new ConfigurationException(e);
+			
+		} catch (IOException e) {
+			throw new ConfigurationException(e);
+			
+		}
+		 
+		 
+	}
+
+	public String getClassName(String action) {
+		ActionConfig ac = this.actions.get(action);
+		if(ac == null){
+			return null;
+		}
+		return ac.getClassName();
+	}
+
+	public String getResultView(String action, String resultName) {
+		ActionConfig ac = this.actions.get(action);
+		if(ac == null){
+			return null;
+		}
+		return ac.getViewName(resultName);
+	}
+	
+	private static class ActionConfig{
+		
+		String name;
+		String clzName;
+		Map<String,String> viewResult = new HashMap<>();
+		
+		
+		public ActionConfig(String actionName, String clzName) {
+			this.name = actionName;
+			this.clzName = clzName;
+		}
+		public String getClassName(){
+			return clzName;
+		}
+		public void addViewResult(String name, String viewName){
+			viewResult.put(name, viewName);
+		}
+		public String getViewName(String resultName){
+			return viewResult.get(resultName);
+		}
+	}
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java
new file mode 100755
index 0000000000..a584a7077d
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationException.java
@@ -0,0 +1,21 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.io.IOException;
+
+import org.jdom2.JDOMException;
+
+public class ConfigurationException extends RuntimeException {
+
+	public ConfigurationException(String msg) {
+		super(msg);
+	}
+
+	public ConfigurationException(JDOMException e) {
+		super(e);
+	}
+
+	public ConfigurationException(IOException e) {
+		super(e);
+	}
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java
new file mode 100755
index 0000000000..0f3c74e69a
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ConfigurationTest.java
@@ -0,0 +1,50 @@
+package com.dudy.learn01.litestruts.format;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class ConfigurationTest {
+
+	
+	Configuration cfg = new Configuration("struts.xml");
+	
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testGetClassName() {
+		
+		String clzName = cfg.getClassName("login");
+		Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName);
+		
+		
+		clzName = cfg.getClassName("logout");
+		Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName);
+	}
+	
+	@Test
+	public void testGetResultView(){
+		String jsp = cfg.getResultView("login","success");
+		Assert.assertEquals("/jsp/homepage.jsp", jsp);
+		
+		jsp = cfg.getResultView("login","fail");
+		Assert.assertEquals("/jsp/showLogin.jsp", jsp);
+		
+		jsp = cfg.getResultView("logout","success");
+		Assert.assertEquals("/jsp/welcome.jsp", jsp);
+		
+		jsp = cfg.getResultView("logout","error");
+		Assert.assertEquals("/jsp/error.jsp", jsp);
+		
+	}
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java
new file mode 100755
index 0000000000..3672d5a990
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/LoginAction.java
@@ -0,0 +1,39 @@
+package com.dudy.learn01.litestruts.format;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java
new file mode 100755
index 0000000000..6ab3715730
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtil.java
@@ -0,0 +1,123 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ReflectionUtil {
+
+	public static List<Method> getSetterMethods(Class clz) {
+		
+		return getMethods(clz,"set");
+		
+	}
+
+	public static void setParameters(Object o, Map<String, String> params) {
+		
+		List<Method> methods  =  getSetterMethods(o.getClass());
+		
+		for(String name : params.keySet() ){
+			
+			String methodName = "set" + name;
+			
+			for(Method m: methods){
+				
+				if(m.getName().equalsIgnoreCase(methodName)){
+					try {
+						m.invoke(o, params.get(name));
+					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+		
+	}
+
+	public static List<Method> getGetterMethods(Class<?> clz) {
+		return getMethods(clz,"get");
+	}
+	
+	private static List<Method> getMethods(Class<?> clz, String startWithName){
+		
+		List<Method> methods = new ArrayList<>();
+		
+		for(Method m : clz.getDeclaredMethods()){
+			
+			if(m.getName().startsWith(startWithName)){
+				
+				methods.add(m);
+				
+			}
+			
+		}
+		
+		return methods;
+	}
+	
+	public static Map<String, Object> getParamterMap(Object o) {
+		
+		Map<String ,Object> params = new HashMap<>();
+		
+		List<Method> methods = getGetterMethods(o.getClass());
+		
+		for(Method m : methods){
+			
+			String methodName = m.getName();
+			String name = methodName.replaceFirst("get", "").toLowerCase();
+			try {
+				Object value = m.invoke(o);
+				params.put(name, value);
+			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+				
+				e.printStackTrace();
+			} 
+		}
+		
+		return params;
+	}
+	
+	////////////////////////Backup ///////////////////////////////////
+	
+	public static List<Method> getGetterMethods_V1(Class<?> clz) {
+		
+		List<Method> methods = new ArrayList<>();
+		
+		for(Method m : clz.getDeclaredMethods()){
+			
+			if(m.getName().startsWith("get")){
+				
+				methods.add(m);
+				
+			}
+			
+		}
+		
+		return methods;
+	}
+	
+	public static List<Method> getSetterMethods_V1(Class clz) {
+		
+		List<Method> methods = new ArrayList<>();
+		
+		for(Method m : clz.getDeclaredMethods()){
+			
+			if(m.getName().startsWith("set")){
+				
+				methods.add(m);
+				
+			}
+			
+		}
+		
+		return methods;
+		
+	}
+
+	
+	
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java
new file mode 100755
index 0000000000..174808fe62
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/ReflectionUtilTest.java
@@ -0,0 +1,113 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+public class ReflectionUtilTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testGetSetterMethod() throws Exception {
+		
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		List<Method> methods = ReflectionUtil.getSetterMethods(clz);
+		
+		Assert.assertEquals(2, methods.size());
+		
+		List<String> expectedNames = new ArrayList<>();
+		expectedNames.add("setName");
+		expectedNames.add("setPassword");
+		
+		Set<String> acctualNames = new HashSet<>();
+		for(Method m : methods){
+			acctualNames.add(m.getName());
+		}
+		
+		Assert.assertTrue(acctualNames.containsAll(expectedNames));
+	}
+	
+	@Test	
+	public void testSetParameters() throws Exception{
+		
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		Object o = clz.newInstance();
+		
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+		
+		ReflectionUtil.setParameters(o,params);
+		
+
+		
+		Field f = clz.getDeclaredField("name");
+		f.setAccessible(true);
+		Assert.assertEquals("test", f.get(o));
+		
+		f = clz.getDeclaredField("password");
+		f.setAccessible(true);
+		Assert.assertEquals("1234", f.get(o));
+	}
+	@Test
+	public void testGetGetterMethod() throws Exception{
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		List<Method> methods = ReflectionUtil.getGetterMethods(clz);
+		
+		Assert.assertEquals(3, methods.size());
+		
+		List<String> expectedNames = new ArrayList<>();
+		expectedNames.add("getMessage");		
+		expectedNames.add("getName");
+		expectedNames.add("getPassword");
+		
+		Set<String> acctualNames = new HashSet<>();
+		for(Method m : methods){
+			acctualNames.add(m.getName());
+		}
+		
+		Assert.assertTrue(acctualNames.containsAll(expectedNames));
+	}
+	
+	@Test
+	public void testGetParamters() throws Exception{
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		LoginAction action = (LoginAction)clz.newInstance();
+		action.setName("test");
+		action.setPassword("123456");
+		
+		
+		
+		
+		Map<String,Object> params = ReflectionUtil.getParamterMap(action);
+		
+		Assert.assertEquals(3, params.size());
+		
+		Assert.assertEquals(null, params.get("messaage") );
+		Assert.assertEquals("test", params.get("name") );
+		Assert.assertEquals("123456", params.get("password") );
+	}
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java
new file mode 100755
index 0000000000..661fd96ebe
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/Struts.java
@@ -0,0 +1,68 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+	private final static Configuration cfg = new Configuration("struts.xml");
+	
+    public static View runAction(String actionName, Map<String,String> parameters) {
+
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+    	
+    
+    	
+    	String clzName = cfg.getClassName(actionName);
+    	
+    	if(clzName == null){
+    		return null;
+    	}
+    	
+    	try {
+    		
+    		Class<?> clz = Class.forName(clzName);    		
+			Object action = clz.newInstance();
+			
+			ReflectionUtil.setParameters(action, parameters);
+			
+			Method m = clz.getDeclaredMethod("execute");			
+			String resultName = (String)m.invoke(action);
+			
+			Map<String,Object> params = ReflectionUtil.getParamterMap(action);	
+			String resultView = cfg.getResultView(actionName, resultName);			
+			View view = new View();			
+			view.setParameters(params);
+			view.setJsp(resultView);
+			return view;
+			
+			
+			
+		} catch (Exception e) {
+			
+			e.printStackTrace();
+		}
+    	return null;
+    }    
+
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java
new file mode 100755
index 0000000000..f3b177e54c
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+		
+		String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java
new file mode 100755
index 0000000000..93c73bd359
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/View.java
@@ -0,0 +1,23 @@
+package com.dudy.learn01.litestruts.format;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+	
+	public String getJsp() {
+		return jsp;
+	}
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+	public Map getParameters() {
+		return parameters;
+	}
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml
new file mode 100755
index 0000000000..4c6eeabbd4
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/litestruts/format/struts.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<struts>
+    <action name="login" class="com.coderising.litestruts.LoginAction">
+        <result name="success">/jsp/homepage.jsp</result>
+        <result name="fail">/jsp/showLogin.jsp</result>
+    </action>
+    <action name="logout" class="com.coderising.litestruts.LogoutAction">
+    	<result name="success">/jsp/welcome.jsp</result>
+    	<result name="error">/jsp/error.jsp</result>
+    </action>
+</struts>
\ No newline at end of file
diff --git a/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java
new file mode 100644
index 0000000000..2763af6d55
--- /dev/null
+++ b/group04/1796244932/learn01/src/main/java/com/dudy/learn01/utils/ArraySortDemo.java
@@ -0,0 +1,104 @@
+package com.dudy.learn01.utils;
+
+import java.util.Arrays;
+
+/**
+ * Created by dudy on 2017/3/6.
+ * 练习数组的各种排序
+ * 参考：http://wiki.jikexueyuan.com/project/java-special-topic/sort.html
+ *      http://www.cnblogs.com/liuling/p/2013-7-24-01.html
+ *
+ * 内排序有可以分为以下几类：
+
+ 　　(1)、插入排序：直接插入排序、二分法插入排序、希尔排序。
+
+ 　　(2)、选择排序：简单选择排序、堆排序。
+
+ 　　(3)、交换排序：冒泡排序、快速排序。
+
+ 　　(4)、归并排序
+
+ 　　(5)、基数排序
+ *
+ */
+public class ArraySortDemo {
+
+
+    /**
+     * 二分法查找 插入
+     * 和 直接插入排序不同的是： 查找 要插入的位置的方式不同
+     * 二分法前提是有序的**
+     */
+    public static void dichotomySort(int src[]){
+
+        for (int i = 0; i< src.length ; i++){
+            int temp = src[i];
+            int right = i - 1;
+            int mid = 0;
+            int left = 0;
+            while (left <= right){
+                mid = (left + right)/2;
+                if (temp > src[mid]){
+                    left  = mid + 1;
+                } else {
+                    right = mid - 1;
+                }
+            }
+
+            for (int j = i-1;j>=left ; j--){
+                src[j+1] = src[j];
+            }
+
+            System.out.println("left = " + left +" ,mid = " + mid + " ,right = " + right);
+            src[left] = temp;
+
+        }
+    }
+
+
+
+
+    /**
+     * 直接插入排序
+     * 思想：假定前边是有序地部分， 后边无序的插入到前边部分
+     * 可以转变思想: 从后往前遍历， 将有序部分大于当前的值 往后移
+     * @param src
+     */
+    public static  void directInsertSort(int[] src){
+
+        for (int i = 1;i < src.length ; i++){
+            // 待插入的元素
+            int temp =  src[i];
+            int j;
+            for ( j = i -1; j >= 0; j--){
+                // 大于 temp的往后移动
+                if (src[j] > temp){
+                    src[j+1] = src[j];
+                } else {
+                    break;
+                }
+            }// 此时遍历完 j+1 为要插入的位置
+            src[j+1] = temp;
+        }
+
+    }
+
+
+
+    public static void main(String[] args) {
+        int a[] = new int[]{46,89,14,44,90,32,25,67,23};
+        // 14,23,25,32,44,46,67,89,90
+        //Arrays.sort(a);
+
+
+        //directInsertSort(a);
+
+        dichotomySort(a);
+
+        for (int i = 0; i< a.length ; i++){
+            System.out.print(a[i] + ",");
+        }
+
+    }
+
+}
diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
index c6ebb096ec..cce7a1c163 100644
--- a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
+++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/base/MyLinkedListTest.java
@@ -2,10 +2,69 @@
 
 import java.util.LinkedList;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
 public class MyLinkedListTest {
 
+	MyLinkedList list = new MyLinkedList();
+
+	@Before
+	public void  init(){
+		list.add(1);
+		list.add(2);
+		list.add(3);
+		list.add(4);
+		list.add(5);
+	}
+
+	@After
+	public void after(){
+		for(MyIterator it = list.iterator(); it.hasNext();){
+			System.out.print(it.next() + " ");
+		}
+	}
+
+	@Test
+	public void reverse() throws Exception {
+		list.reverse();
+	}
+
+	@Test
+	public void removeFirstHalf() throws Exception {
+		list.removeFirstHalf();
+	}
+
+	@Test
+	public void remove() throws Exception {
+		list.remove(0,2);
+	}
+
+	@Test
+	public void getElements() throws Exception {
+
+	}
+
+	@Test
+	public void subtract() throws Exception {
+
+	}
+
+	@Test
+	public void removeDuplicateValues() throws Exception {
+
+	}
+
+	@Test
+	public void removeRange() throws Exception {
+
+	}
+
+	@Test
+	public void intersection() throws Exception {
+
+	}
 
 
 	@Test
diff --git a/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..fc427e2171
--- /dev/null
+++ b/group04/1796244932/learn01/src/test/java/com/dudy/learn01/download/FileDownloaderTest.java
@@ -0,0 +1,53 @@
+package com.dudy.learn01.download;
+
+import com.dudy.learn01.download.api.ConnectionManager;
+import com.dudy.learn01.download.api.DownloadListener;
+import com.dudy.learn01.download.impl.ConnectionManagerImpl;
+import org.junit.Test;
+
+
+import java.io.IOException;
+
+
+public class FileDownloaderTest {
+    boolean downloadFinished = false;
+
+
+
+	@Test
+	public void testDownload() throws IOException {
+
+		//String url = "http://www.lgstatic.com/www/static/mycenter/modules/common/img/tou_42952f6.png";
+		String url = "http://img.lanrentuku.com/img/allimg/1606/14665573271238.jpg";
+		FileDownloader downloader = new FileDownloader(url);
+
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+		});
+
+
+		downloader.execute();
+
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+
+
+
+	}
+
+}
\ No newline at end of file
diff --git a/group04/349184132/Study/bin/com/test/student2.xml b/group04/349184132/Study/bin/com/test/student2.xml
deleted file mode 100644
index e21862ec75..0000000000
--- a/group04/349184132/Study/bin/com/test/student2.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<student name="zhangsan">
-    <hello>hello text</hello>
-    <world>world text</world>
-</student>
diff --git a/group04/349184132/Study/bin/com/test/students.xml b/group04/349184132/Study/bin/com/test/students.xml
deleted file mode 100644
index 0a503c9f6c..0000000000
--- a/group04/349184132/Study/bin/com/test/students.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<students name="zhangsan">
-	<hello name="lisi">hello Text1</hello>
-	<hello name="lisi2">hello Text2</hello>
-	<hello name="lisi3">hello Text3</hello>
-	<world name="wangwu">world text1</world>
-	<world name="wangwu2">world text2</world>
-	<world>world text3</world>
-</students>
\ No newline at end of file
diff --git a/group04/349184132/Study/src/com/coderising/download/DownloadThread.java b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..2b806a7f44
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,49 @@
+package com.coderising.download;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread {
+	Connection conn;
+	int startPos;
+	int endPos;
+	int threadId = 0;
+	CyclicBarrier barrier;
+
+	public DownloadThread(CyclicBarrier barrier, Connection conn, int threadId,
+			int startPos, int endPos) {
+		this.barrier = barrier;
+		this.conn = conn;
+		this.threadId = threadId;
+		this.startPos = startPos;
+		this.endPos = endPos;
+	}
+
+	public void run() {
+		RandomAccessFile raf = null;
+		try {
+			raf = new RandomAccessFile("yunpan.exe", "rwd");
+
+			raf.seek(startPos);
+
+			byte[] buffer = conn.read(startPos, endPos);
+
+			raf.write(buffer, 0, buffer.length);
+			raf.close();
+			barrier.await();
+			System.out.println("threadId" + threadId +"download success !");
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		} catch (BrokenBarrierException e) {
+			e.printStackTrace();
+		}
+
+	}
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/FileDownloader.java b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..281dafde96
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,112 @@
+package com.coderising.download;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+public class FileDownloader {
+	
+	boolean isFinished = false;
+	
+	String url;
+
+	DownloadListener listener;
+
+	ConnectionManager cm;
+	
+	private static final int THREAD_NUM = 3;
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+
+	}
+
+	public void execute() {
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos,
+		// endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		// 线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接，
+		// 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载， 注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		
+		CyclicBarrier barrier = new CyclicBarrier(THREAD_NUM,new Runnable(){
+
+			@Override
+			public void run() {
+				listener.notifyFinished();
+			}
+			
+		});
+		
+		Connection conn = null;
+		try {
+			conn = cm.open(url);
+			
+			int length = conn.getContentLength();
+			System.out.println("----文件总长度---- :" + length);
+			RandomAccessFile raf = new RandomAccessFile("yunpan.exe","rwd");
+			
+			raf.setLength(length);
+			
+			int block = length / THREAD_NUM;
+			
+			for(int threadId = 0; threadId < THREAD_NUM; threadId++){
+				int startPos = (threadId) * block;
+				int endPos = (threadId + 1 ) * block -1;
+				if(threadId-1 == THREAD_NUM){
+					endPos = length;
+				}
+				System.out.println("---threadId--- :" + threadId +
+						   "---startIndex---" + startPos +
+						   "---endIndex---" + endPos);
+				//开启 线程
+				URL u = new URL(url);
+				new DownloadThread(barrier,cm.open(url),threadId,startPos,endPos).start();
+			}
+			
+			
+		} catch (ConnectionException e) {
+
+			e.printStackTrace();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally{
+			if(conn!=null){
+				conn.close();
+			}
+		}
+
+	}
+
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	public void setConnectionManager(ConnectionManager ucm) {
+		this.cm = ucm;
+	}
+
+	public DownloadListener getListener() {
+		return this.listener;
+	}
+
+	
+}
diff --git a/group12/446031103/src/com/coderising/download/FileDownloaderTest.java b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java
similarity index 90%
rename from group12/446031103/src/com/coderising/download/FileDownloaderTest.java
rename to group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java
index 4ff7f46ae0..604712d2a9 100644
--- a/group12/446031103/src/com/coderising/download/FileDownloaderTest.java
+++ b/group04/349184132/Study/src/com/coderising/download/FileDownloaderTest.java
@@ -21,8 +21,7 @@ public void tearDown() throws Exception {
 	@Test
 	public void testDownload() {
 		
-		String url = "http://localhost:8080/test.jpg";
-		
+		String url = "http://down.360safe.com/yunpan/360wangpan_setup.exe"; 
 		FileDownloader downloader = new FileDownloader(url);
 
 	
@@ -40,7 +39,7 @@ public void notifyFinished() {
 		
 		downloader.execute();
 		
-		// 等待多线程下载程序执行完毕
+//		 等待多线程下载程序执行完毕
 		while (!downloadFinished) {
 			try {
 				System.out.println("还没有下载完成，休眠五秒");
diff --git a/group04/349184132/Study/src/com/coderising/download/api/Connection.java b/group04/349184132/Study/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1599be1296
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+	public ConnectionException(String string) {
+		// TODO 自动生成的构造函数存根
+	}
+
+	
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..3ad903146b
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,52 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+	private HttpURLConnection conn ;
+	public ConnectionImpl(HttpURLConnection conn) {
+		this.conn = conn;
+	}
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		conn.setRequestMethod("GET");
+		conn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+		conn.setConnectTimeout(5000);
+		
+		InputStream is = conn.getInputStream();
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		int length = 0;
+		byte[] buffer = new byte[1024];
+		while(-1 != ( length = is.read(buffer))){
+			bos.write(buffer,0,length);
+		}
+		bos.flush();
+		is.close();
+		bos.close();
+		
+		
+		return bos.toByteArray();
+	}
+
+	@Override
+	public int getContentLength() {
+		
+		return conn.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		if(conn!=null){
+			conn = null;
+		}
+	}
+
+}
diff --git a/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..9132787cf8
--- /dev/null
+++ b/group04/349184132/Study/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,37 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		
+			URL u;
+			HttpURLConnection hc ;
+			try {
+				u = new URL(url);
+				hc = (HttpURLConnection) u.openConnection();
+				Connection conn = new ConnectionImpl(hc);;
+				return conn;
+			} catch (MalformedURLException e) {
+				e.printStackTrace();
+				
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			return null;
+
+		
+			
+			
+			
+	}
+
+}
diff --git a/group04/349184132/Study/src/com/linked/Iterator.java b/group04/349184132/Study/src/com/linked/Iterator.java
new file mode 100644
index 0000000000..b2397b9aa7
--- /dev/null
+++ b/group04/349184132/Study/src/com/linked/Iterator.java
@@ -0,0 +1,7 @@
+package com.linked;
+
+public interface Iterator<T> {
+	public boolean hasNext();
+	public Object next();
+
+}
diff --git a/group04/349184132/Study/src/com/linked/LinkedList.java b/group04/349184132/Study/src/com/linked/LinkedList.java
new file mode 100644
index 0000000000..44aba236b4
--- /dev/null
+++ b/group04/349184132/Study/src/com/linked/LinkedList.java
@@ -0,0 +1,388 @@
+package com.linked;
+
+import java.util.Objects;
+
+
+
+public class LinkedList<T> implements List<T> {
+	
+	private Node head;
+	
+	private int size = 0;
+	
+	public LinkedList(){
+		this.head = new Node(null,null);
+	}
+	
+	public boolean add(T o){
+		
+		if(head.next == null){
+			Node element = new Node(o,null);
+			head.next = element;
+			size++;
+			return true;
+		}
+		
+		Node current = head.next;
+		while(current != null){
+			if(current.next==null){
+				Node element = new Node(o,null);
+				current.next = element;
+				size++;
+				return true;
+			}
+			current = current.next;
+		}
+		
+		return false;
+	}
+	
+
+	private void rangeCheck(int index) {
+		if (index < -1 || index > size - 1)
+			throw new IndexOutOfBoundsException(" index ");
+	}
+	public boolean add(int index , T o){
+		rangeCheck(index);
+		
+		Node node = getNode(index);
+		Node pre = getNode(index-1);
+		Node newNode = new Node(o,node);
+		pre.next = newNode;
+		size++;
+		return true;
+	}
+	
+	
+	private Node getNode(int index){
+		rangeCheck(index);
+		Node current = head.next;
+		int count = 0;
+		while(current!=null){
+			if(count==index){
+				return current;
+			}
+			count++;
+			current = current.next;
+		}
+		return null;
+	}
+	
+	public T get(int index){
+		Node node = getNode(index);
+		return (T)node.data;
+	}
+	public T remove(int index){
+		rangeCheck(index);
+		
+		Node pre = getNode(index-1);
+		Node cur = getNode(index);
+		Node next = cur.next;
+		pre.next = next;
+		cur.next = null;
+		size--;
+		return (T)cur.data;
+	}
+	
+	
+	public T remove(T o) {
+		int index = 0;
+		for (Node x = head.next; x != null; x = x.next) {
+			if (Objects.deepEquals(x.data, o)) {
+				return remove(index);
+			}
+			index++;
+		}
+		size--;
+
+		return null;
+	}
+	
+	@Override
+	public T set(int index, T element) {
+		Node node = getNode(index);
+		node.data = element;
+		
+		return (T)node.data;
+	}
+
+	@Override
+	public boolean contains(Object o) {
+		
+		return indexOf(o)!=-1;
+	}
+
+	@Override
+	public int indexOf(Object o) {
+		int index = 0;
+
+		for (Node x = head.next; x != null; x = x.next) {
+			if (Objects.deepEquals(x.data, o))
+				return index;
+			index++;
+		}
+		return -1;
+	}
+
+	@Override
+	public Object[] toArray() {
+		Object[] result = new Object[size];
+		int i = 0;
+		for(Node x = head.next; x != null; x = x.next){
+			result[i++] = x.data;
+		}
+		return null;
+	}
+
+	@Override
+	public void clear() {
+		for(Node cur = head.next;cur!=null;cur = cur.next){
+			Node x = cur;
+			x.data = null;
+			x.next = null;
+		}
+		head = null;
+		size = 0;
+	}
+
+	
+	public int size(){
+		return size;
+	}
+	public boolean isEmpty() {
+		return size == 0;
+	}
+	public void addFirst(Object o){
+		Node newFirst = new Node(o,null);
+		Node oldFirst = head.next;
+		head.next = newFirst;
+		newFirst.next = oldFirst;
+		size++;
+	}
+	public void addLast(Object o){
+		Node last = getNode(size-1);
+		Node newLast = new Node(o,null);
+		last.next = newLast;
+		size++;
+	}
+	public T removeFirst(){
+		Node oldFirst = head.next;
+		Node nextNode = oldFirst.next;
+		head.next = nextNode;
+		size--;
+		return (T)oldFirst;
+	}
+	public T removeLast(){
+		Node x = getNode(size-2);//倒数第二个结点
+		Node last = x.next;
+		x.next = null;
+		size--;
+		return (T)last;
+	}
+	public Iterator<T> iterator(){
+		return new LinkedListIterator();
+	}
+	
+	private class LinkedListIterator implements Iterator<T> {
+		int pos = 0;
+
+		@Override
+		public boolean hasNext() {
+			return pos < size;
+		}
+
+		@Override
+		public Object next() {
+			if (pos > size)
+				throw new IllegalArgumentException();
+			return get(pos++);
+		}
+	}
+
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		private Node(Object data, Node next) {
+			this.data = data;
+			this.next = next;
+
+		}
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  Node reverseFor(Node head){
+		if(head==null){
+			return null;
+		}
+		Node pre = null;
+		Node curr = head;
+		Node next = head.next;
+		while(curr.next!=null){
+			
+			head.next = pre;
+			pre = curr;
+			curr = curr.next;
+			next = next.next;
+			head = curr;
+		}
+		pre = null;
+		curr = null;
+		return head;
+	}
+	/**
+	 * 递归写法
+	 * @param node
+	 * @return
+	 */
+	public Node reverseRecursion(Node current){
+		if(current == null || current.next == null){
+			return current;
+		}
+		Node nextNode = current.next;
+		current = null;
+		Node reverseNode = reverseRecursion(current.next);
+		nextNode.next = current;
+		
+		
+		return reverseNode;
+		
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		int delectLength = size/2;
+		for(int i=0;i<delectLength;i++){
+			Node x = (Node) removeFirst();
+			x.data = null;
+			x.next = null;
+		}
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		if( i<0 && i>size-length){
+			throw new IllegalArgumentException(i +" or "+length +" error");
+		}
+		for(int j=i;j<length+i+1;j++){
+			remove(i);
+		}
+	}
+	/**
+	 * 假定当前链表和list均包含已升序排列的整数
+	 * 从当前链表中取出那些list所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		if(list==null){
+			throw new NullPointerException("List is null");
+		}
+		int[] result = new int[list.size()];
+		int index = 0;
+		for(Iterator iter = list.iterator();iter.hasNext();){
+			int LinkIndex = (int)iter.next();
+			result[index] = (int)get(LinkIndex);
+		}
+		return result;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在list中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		if(list == null){
+			throw new NullPointerException("List is null");
+		}
+		int index = 0;
+		for(Node cur = head.next ; cur !=null ; cur = cur.next){
+			for(Node newList = list.head.next ; newList != null; newList = newList.next ){
+				if(Objects.deepEquals(cur.data, newList.data)){
+					remove(index);
+				}
+			}
+			index++;
+		}
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		for(Node current=head.next;current!=null;current=current.next){
+			Node nextNode = current.next;
+			
+			if(current.data.equals(nextNode.data)){
+				Node nextNodeNext = nextNode.next;
+				if(nextNodeNext==null){
+					current.next = null;
+				}else{
+					current.next = nextNodeNext;
+					nextNode.next = null;
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public void removeRange(int min, int max) {
+		if (min + max > size && min == max) {
+			throw new IndexOutOfBoundsException("Arguement is Illegal");
+		}
+		int index = 0;
+		for (Node curr = head.next; curr != null; curr = curr.next) {
+			if(((int)curr.data>min) && ((int)curr.data<min)){
+				remove(index);
+			}
+			index++;
+			
+		}
+
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		LinkedList cList = new LinkedList();
+		for(Node a = head.next ; a!=null ;a = a.next){
+			for(Node b = list.head.next; b != null ; b = b.next){
+				if(Objects.deepEquals(a.data, b.data)){
+					cList.add(a.data);
+				}
+			}
+		}
+		
+		
+		return cList;
+	}
+
+	
+}
diff --git a/group04/349184132/Study/src/com/linked/List.java b/group04/349184132/Study/src/com/linked/List.java
new file mode 100644
index 0000000000..60ec0a4a14
--- /dev/null
+++ b/group04/349184132/Study/src/com/linked/List.java
@@ -0,0 +1,32 @@
+package com.linked;
+
+
+public interface List<T> {
+	public boolean add(T o);
+
+	public boolean add(int index, T o);
+
+	public T get(int index);
+	
+	T set(int index, T element);
+
+	public T remove(int index);
+
+	public T remove(T o);
+
+	public int size();
+
+	public boolean isEmpty();
+	
+	public Iterator<T> iterator();
+	
+	public boolean contains(Object o);
+	
+	int indexOf(Object o);
+	
+	
+	Object[] toArray();
+	
+	void clear();
+	
+}
diff --git a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
index 06944cd8b1..4acbbf8880 100644
--- a/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
+++ b/group04/349184132/Study/src/com/second/Array/ArrayUtilTest.java
@@ -64,7 +64,7 @@ public void testFibonacci() {
 	public void testGetPrimes() {
 		int[] primes = {2,3,5,7,11,13,17,19};
 		int max = 23;
-		Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(max));
+		Assert.assertArrayEquals(primes, ArrayUtil.getPrimes(27));
 	}
 
 	@Test
diff --git a/group04/351121278/src/com/coding/download/DownloadThread.java b/group04/351121278/src/com/coding/download/DownloadThread.java
new file mode 100644
index 0000000000..e0b396a5e6
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/DownloadThread.java
@@ -0,0 +1,34 @@
+package com.coding.download;
+
+import com.coding.download.api.Connection;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+	File file;
+
+	public DownloadThread(File file, Connection conn, int startPos, int endPos){
+		this.file = file;
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+	}
+	public void run(){
+		try {
+			System.out.println("DownloadThread.run");
+			byte[] buffer = conn.read(startPos, endPos);
+			RandomAccessFile raf = new RandomAccessFile(file, "rw");
+			raf.seek(startPos);
+			raf.write(buffer, 0, buffer.length);
+			raf.close();
+		} catch (IOException e) {
+			System.out.println("e = " + e.getMessage());
+		}
+	}
+}
diff --git a/group04/351121278/src/com/coding/download/FileDownloader.java b/group04/351121278/src/com/coding/download/FileDownloader.java
new file mode 100644
index 0000000000..13d24f5b2b
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/FileDownloader.java
@@ -0,0 +1,76 @@
+package com.coding.download;
+
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+
+import java.io.File;
+
+public class FileDownloader {
+	
+	String url;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+	
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			
+			conn = cm.open(this.url);
+			File file = new File("D:/test");
+			int length = conn.getContentLength();	
+			for (int i=0; i<3; i++) {
+				new DownloadThread(file, conn, 0, length-1).start();
+			}
+
+		} catch (ConnectionException e) {
+			e.printStackTrace();
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+		
+		
+		
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
diff --git a/group04/351121278/src/com/coding/download/FileDownloaderTest.java b/group04/351121278/src/com/coding/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..84fbc8afa2
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coding.download;
+
+import com.coding.download.api.ConnectionManager;
+import com.coding.download.api.DownloadListener;
+import com.coding.download.impl.ConnectionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url = "http://localhost:8080/test.jpg";
+		
+		FileDownloader downloader = new FileDownloader(url);
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group04/351121278/src/com/coding/download/api/Connection.java b/group04/351121278/src/com/coding/download/api/Connection.java
new file mode 100644
index 0000000000..bd75d6cad0
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coding.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos, int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/351121278/src/com/coding/download/api/ConnectionException.java b/group04/351121278/src/com/coding/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1f57f86606
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/ConnectionException.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public class ConnectionException extends Exception {
+
+    public ConnectionException(String exceptionMessage) {
+
+    }
+    public ConnectionException() {
+    }
+}
diff --git a/group04/351121278/src/com/coding/download/api/ConnectionManager.java b/group04/351121278/src/com/coding/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..1d1a83caf2
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coding.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/351121278/src/com/coding/download/api/DownloadListener.java b/group04/351121278/src/com/coding/download/api/DownloadListener.java
new file mode 100644
index 0000000000..c41045b0e8
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coding.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..7d524ec4a0
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/impl/ConnectionImpl.java
@@ -0,0 +1,50 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+
+public class ConnectionImpl implements Connection {
+
+	private static final int THEAD_COUNT = 3;
+	private URL url;
+	private HttpURLConnection httpURLConnection;
+	private final int BUFFER_SIZE = 1024;
+
+	public ConnectionImpl(URL url) {
+		this.url = url;
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		URLConnection urlConnection = url.openConnection();
+		httpURLConnection = (HttpURLConnection)urlConnection;
+		httpURLConnection.setRequestMethod("GET");
+		InputStream in = httpURLConnection.getInputStream();
+		ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
+		int len;
+		byte[] buffer = new byte[BUFFER_SIZE];
+		while ((len = in.read(buffer)) != -1) {
+			byteOutputStream.write(buffer, startPos, len);
+		}
+		return byteOutputStream.toByteArray();
+	}
+
+	@Override
+	public int getContentLength() {
+		return httpURLConnection.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		httpURLConnection.disconnect();
+	}
+
+}
diff --git a/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..c07a0b545a
--- /dev/null
+++ b/group04/351121278/src/com/coding/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,23 @@
+package com.coding.download.impl;
+
+import com.coding.download.api.Connection;
+import com.coding.download.api.ConnectionException;
+import com.coding.download.api.ConnectionManager;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		URL urlObj;
+		try {
+			urlObj = new URL(url);
+		} catch (MalformedURLException e) {
+			throw new ConnectionException("URL无法访问" + e.getMessage());
+		}
+		return  new ConnectionImpl(urlObj);
+	}
+
+}
diff --git a/group04/474772605/.classpath b/group04/474772605/.classpath
index 28e2b79383..8d7ead9fe8 100644
--- a/group04/474772605/.classpath
+++ b/group04/474772605/.classpath
@@ -1,7 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="test"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/user"/>
+	<classpathentry kind="lib" path="test/dom4j-1.6.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/group04/474772605/jsp/homepage.jsp b/group04/474772605/jsp/homepage.jsp
new file mode 100644
index 0000000000..83fa84db7d
--- /dev/null
+++ b/group04/474772605/jsp/homepage.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+    pageEncoding="ISO-8859-1"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>homepage</title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/group04/474772605/jsp/showLogin.jsp b/group04/474772605/jsp/showLogin.jsp
new file mode 100644
index 0000000000..1e6cda01b1
--- /dev/null
+++ b/group04/474772605/jsp/showLogin.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+    pageEncoding="ISO-8859-1"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>showLogin</title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/group12/382266293/src/com/coderising/action/LoginAction.java b/group04/474772605/src/com/coderising/action/LoginAction.java
similarity index 95%
rename from group12/382266293/src/com/coderising/action/LoginAction.java
rename to group04/474772605/src/com/coderising/action/LoginAction.java
index b1224eb80d..69ad2750c0 100644
--- a/group12/382266293/src/com/coderising/action/LoginAction.java
+++ b/group04/474772605/src/com/coderising/action/LoginAction.java
@@ -1,39 +1,40 @@
-package com.coderising.action;
-
-/**
- * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
- * @author liuxin
- *
- */
-public class LoginAction{
-    private String name ;
-    private String password;
-    private String message;
-
-    public String getName() {
-        return name;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public String execute(){
-            if("test".equals(name) && "1234".equals(password)){
-                this.message = "login successful";
-                return "success";
-            }
-            this.message = "login failed,please check your user/pwd";
-            return "fail";
-    }
-
-    public void setName(String name){
-        this.name = name;
-    }
-    public void setPassword(String password){
-        this.password = password;
-    }
-    public String getMessage(){
-        return this.message;
-    }
-}
\ No newline at end of file
+package com.coderising.action;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+    	
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/474772605/src/com/coderising/action/LogoutAction.java b/group04/474772605/src/com/coderising/action/LogoutAction.java
new file mode 100644
index 0000000000..10e4eb37c7
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/LogoutAction.java
@@ -0,0 +1,40 @@
+package com.coderising.action;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LogoutAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success1";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+    	
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/474772605/src/com/coderising/action/Struts.java b/group04/474772605/src/com/coderising/action/Struts.java
new file mode 100644
index 0000000000..7db0e4687f
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/Struts.java
@@ -0,0 +1,122 @@
+package com.coderising.action;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Attribute;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+
+
+public class Struts {
+	
+	
+	
+	public static void main(String[] args) throws DocumentException {
+         String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");      
+        View view  = Struts.runAction(actionName,params);  
+        System.out.println(view.getJsp());
+        System.out.println(view.getParameters());
+	}
+	
+ 
+    public static View runAction(String actionName, Map<String,String> parameters)  {
+    	 View view = new View();
+    	    SAXReader reader = new SAXReader();  
+	      //读取文件 转换成Document  
+	        org.dom4j.Document document;
+		   try {
+				document = reader.read(new File("src/struts.xml"));
+				Element root = document.getRootElement();  
+				@SuppressWarnings("unchecked")
+				List<Element> elements = root.elements();
+				for (Element element : elements) {
+		            Attribute actionAttribute = element.attribute("name");
+		            Attribute classAttribute = element.attribute("class");      
+		            if(actionName.equals(actionAttribute.getValue())){	            	
+		            	 String clazz = null;	 	    		
+	 	    			 clazz = classAttribute.getValue();
+	 	    			 Object o = Class.forName(clazz).newInstance();
+	 	    			for (Map.Entry<String,String> entry : parameters.entrySet()) {  
+	 	    				String name = entry.getKey();
+	 	    				String value =entry.getValue();
+	 	    				String methodname = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
+	 	    				Method m = o.getClass().getMethod(methodname, String.class);
+	 	    				m.invoke(o, value);
+	 	    			  
+	 	    			} 
+						Method m3 = o.getClass().getMethod("execute");					
+						String result = (String) m3.invoke(o);	
+						String jspPath = null;
+						List<Element> element1s = element.elements("result");
+						if(result.equals("success")){		            	
+			            	for (int i = 0; i < element1s.size(); i++) {
+			            		Attribute attribute2 = element1s.get(i).attribute("name");
+			            		if (attribute2.getValue().equals("success")) {
+									jspPath = element1s.get(i).getStringValue();
+								}	            		
+							}	            	
+						}else if(result.equals("fail")){
+							for (int i = 0; i < element1s.size(); i++) {
+			            		Attribute attribute2 = element1s.get(i).attribute("name");
+			            		if (attribute2.getValue().equals("fail")) {
+									jspPath = element1s.get(i).getStringValue();
+								}
+						}
+		        }
+						HashMap<String, Object>viewparamterHashMap = new HashMap<String, Object>();
+						Method[]methods = o.getClass().getMethods();
+					    String  methodname;
+						for (int j = 0; j < o.getClass().getMethods().length; j++) {
+							methodname = methods[j].getName();								
+							if(methodname.startsWith("get")&&!methodname.equals("getClass")){
+								String methodname1 = methods[j].getName();
+								methodname1 = methodname.substring(3,4).toUpperCase()+methodname1.substring(4);
+								viewparamterHashMap.put(methodname1, methods[j].invoke(o));								
+							}
+						}						
+						  view.setJsp(jspPath);		
+						  view.setParameters(viewparamterHashMap);
+						  return view;						
+				}	   
+	    }
+		} catch (Exception e) {
+			// TODO: handle exception
+		}		
+		   return null;
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+    	
+    	
+    }			   
+
+}
diff --git a/group04/474772605/src/com/coderising/action/StrutsTest.java b/group04/474772605/src/com/coderising/action/StrutsTest.java
new file mode 100644
index 0000000000..c161c0f932
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.action;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+		
+		String actionName = "com.coderising.action.LoginAction";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group04/474772605/src/com/coderising/action/View.java b/group04/474772605/src/com/coderising/action/View.java
new file mode 100644
index 0000000000..11cb1872e5
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/View.java
@@ -0,0 +1,23 @@
+package com.coderising.action;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+	
+	public String getJsp() {
+		return jsp;
+	}
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+	public Map getParameters() {
+		return parameters;
+	}
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group04/474772605/src/com/coderising/action/struts.xml b/group04/474772605/src/com/coderising/action/struts.xml
new file mode 100644
index 0000000000..a6cfe43e6c
--- /dev/null
+++ b/group04/474772605/src/com/coderising/action/struts.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<struts>
+    <action name="login" class="com.coderising.action.LoginAction">
+        <result name="success">/jsp/homepage.jsp</result>
+        <result name="fail">/jsp/showLogin.jsp</result>
+    </action>
+    <action name="logout" class="com.coderising.action.LogoutAction">
+    	<result = "success">/jsp/welcome.jsp</result>
+    	<result = "error">/jsp/error.jsp</result>
+    </action>
+</struts>
\ No newline at end of file
diff --git a/group04/474772605/src/com/coderising/array/ArrayUtil.java b/group04/474772605/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..ddb00c17b6
--- /dev/null
+++ b/group04/474772605/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,146 @@
+package com.coderising.array;
+
+import java.util.ArrayList;
+import java.util.Stack;
+
+import com.coding.basic.LinkedList;
+
+public class ArrayUtil {
+	
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换
+		例如： a = [7, 9 , 30, 3]  ,   置换后为 [3, 30, 9,7]
+		如果     a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * @param origin
+	 * @return
+	 */
+	public void reverseArray(int[] origin){
+		Stack<Integer> stack = new Stack<Integer>();
+		for (int i = 0; i < origin.length; i++) {
+			stack.add(origin[i]);
+		}
+		
+		for (int j = 0; j < stack.size(); j++) {
+			origin[j] = (Integer) stack.pop();
+		}
+		
+	}
+	
+	/**
+	 * 现在有如下的一个数组：   int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}   
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为：   
+	 * {1,3,4,5,6,6,5,4,7,6,7,5}  
+	 * @param oldArray
+	 * @return
+	 */
+	
+	public int[] removeZero(int[] oldArray){
+		ArrayList<Integer> newarray = new ArrayList<Integer>();
+		for (int i = 0; i < oldArray.length; i++) {
+			if(0!=oldArray[i]){
+				newarray.add(oldArray[i]);
+			}
+		}
+		int result [] = new int [newarray.size()];
+		for (int j = 0; j < result.length; j++) {
+			result[j]=newarray.get(j);
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 ,  创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的
+	 * 例如 a1 = [3, 5, 7,8]   a2 = [4, 5, 6,7]    则 a3 为[3,4,5,6,7,8]    , 注意： 已经消除了重复
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+	
+	public int[] merge(int[] array1, int[] array2){
+		ArrayList<Integer> newarray = new ArrayList<Integer>();
+		for (int i = 0; i < array1.length; i++) {
+			newarray.add(i, array1[i]);
+		}
+		for (int j = 0; j < array2.length; j++) {
+			if (newarray.get(j)>array2[j]&&newarray.get(j+1)>array2[j]) {
+				newarray.add(j+1, array2[j]);
+			}
+		}
+		
+		int result [] = new int [newarray.size()];
+		for (int z = 0; z < result.length; z++) {
+			result[z]=newarray.get(z);
+		}
+		return result;
+	}
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持
+	 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public int[] grow(int [] oldArray,  int size){
+		ArrayList<Integer> newarray = new ArrayList<Integer>();
+		for (int i = 0; i < oldArray.length; i++) {
+			newarray.add(i, oldArray[i]);
+		}
+		while (newarray.size()<oldArray.length+size) {
+			newarray.add(0);
+			
+		}
+		int result [] = new int [newarray.size()];
+		for (int z = 0; z < result.length; z++) {
+			result[z]=newarray.get(z);
+		}
+		return result;
+	}
+	
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21......  ，给定一个最大值， 返回小于该值的数列
+	 * 例如， max = 15 , 则返回的数组应该为 [1，1，2，3，5，8，13]
+	 * max = 1, 则返回空数组 []
+	 * @param max
+	 * @return
+	 */
+	public int[] fibonacci(int max){
+		return null;
+	}
+	
+	/**
+	 * 返回小于给定最大值max的所有素数数组
+	 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * @param max
+	 * @return
+	 */
+	public int[] getPrimes(int max){
+		return null;
+	}
+	
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+	 * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * @param max
+	 * @return
+	 */
+	public int[] getPerfectNumbers(int max){
+		return null;
+	}
+	
+	/**
+	 * 用seperator 把数组 array给连接起来
+	 * 例如array= [3,8,9], seperator = "-"
+	 * 则返回值为"3-8-9"
+	 * @param array
+	 * @param s
+	 * @return
+	 */
+	public String join(int[] array, String seperator){
+		return null;
+	}
+	
+
+}
diff --git a/group04/474772605/src/com/coding/basic/LinkedList.java b/group04/474772605/src/com/coding/basic/LinkedList.java
index dab237cc4a..07c396c7a6 100644
--- a/group04/474772605/src/com/coding/basic/LinkedList.java
+++ b/group04/474772605/src/com/coding/basic/LinkedList.java
@@ -129,6 +129,7 @@ public Iterator iterator(){
 	}
 	public  class Iteratorimp implements Iterator{
 		Node newnode = new Node();
+		
 		public Iteratorimp(Node node){
 			this.newnode = node;		
 		}
diff --git a/group04/474772605/src/com/coding/basic/List.java b/group04/474772605/src/com/coding/basic/List.java
index 10d13b5832..3ef34db464 100644
--- a/group04/474772605/src/com/coding/basic/List.java
+++ b/group04/474772605/src/com/coding/basic/List.java
@@ -1,7 +1,7 @@
 package com.coding.basic;
 
 public interface List {
-	public void add(Object o);
+	public void add(Object o)throws Exception;
 	public void add(int index, Object o);
 	public Object get(int index);
 	public Object remove(int index);
diff --git a/group04/474772605/src/com/coding/basic/Node.java b/group04/474772605/src/com/coding/basic/Node.java
new file mode 100644
index 0000000000..143dfce9d9
--- /dev/null
+++ b/group04/474772605/src/com/coding/basic/Node.java
@@ -0,0 +1,12 @@
+package com.coding.basic;
+
+import org.omg.CosNaming.NamingContextExtPackage.AddressHelper;
+
+abstract class Node {
+	public static int i ;
+	public static String method(){
+		return "原来的";
+	}
+	abstract  String delete();
+
+}
diff --git a/group04/474772605/src/com/coding/basic/Stack.java b/group04/474772605/src/com/coding/basic/Stack.java
index 7a5a56bdf0..0158d4936e 100644
--- a/group04/474772605/src/com/coding/basic/Stack.java
+++ b/group04/474772605/src/com/coding/basic/Stack.java
@@ -1,31 +1,37 @@
 package com.coding.basic;
 
 public class Stack {
-	private ArrayList elementData = new ArrayList();
-	int size =0;
+	private Object[] elementData = new Object[100];
+	int nextindex =0;
 	
-	public void push(Object o){		//入栈
-		elementData.add(o);
-		size++;
+	public void push(Object o) throws Exception{		//入栈
+	if(nextindex==100){
+		throw new Exception("数组越界异常！");
+	}
+	elementData[nextindex++]=o;
 	}
 	
-	public Object pop(){ //移走栈顶对象，将该对象作为函数值返回
-		Object top = elementData.get(size);
-		elementData.remove(size);
-		size--;
-		return top;
+	public Object pop() throws Exception{ //移走栈顶对象，将该对象作为函数值返回
+		if(nextindex == 0){
+			throw new Exception("数组越界异常！");
+		}
+		return elementData[--nextindex];
 	}
 	
-	public Object peek(){//查找栈顶对象，而不从栈中移走
-		return elementData.get(size);
+	public Object peek() throws Exception{//查找栈顶对象，而不从栈中移走
+		if(nextindex == 0){
+			throw new Exception("数组越界异常！");
+			
+		}
+		return elementData[nextindex-1];
 	}
 	public boolean isEmpty(){
-		if(this.size ==0){
+		if(this.nextindex ==0){
 			return true;
 		}
 		return false;
 	}
 	public int size(){
-		return this.size;
+		return this.nextindex;
 	}
 }
diff --git a/group04/474772605/src/com/coding/basic/Testclassextends.java b/group04/474772605/src/com/coding/basic/Testclassextends.java
new file mode 100644
index 0000000000..49fc1d7dd7
--- /dev/null
+++ b/group04/474772605/src/com/coding/basic/Testclassextends.java
@@ -0,0 +1,17 @@
+package com.coding.basic;
+
+public class Testclassextends extends Node {
+	
+	public static Object add(){
+		return null ;
+	}
+/*	public static String method(){
+		return "新的类";
+	}
+	*/
+	
+	String delete(){
+		return "抽象类";
+	}
+
+}
diff --git a/group04/474772605/src/com/coding/basic/testarraylist.java b/group04/474772605/src/com/coding/basic/testarraylist.java
index df5e814ccf..42371740d9 100644
--- a/group04/474772605/src/com/coding/basic/testarraylist.java
+++ b/group04/474772605/src/com/coding/basic/testarraylist.java
@@ -6,9 +6,10 @@ public static void main(String[] args) {
 		String  i = "aaa";
 		String  y = "bbb";
 		Object o = new Object();
+		Testclassextends abcTestclassextends = new Testclassextends();
+		System.out.println(abcTestclassextends.delete());
 		
-		
-		abc.add(i);
+	/*	abc.add(i);
 		System.out.println(abc.get(0));
 	//	System.out.println(abc.get(1));
 		abc.add(y);
@@ -16,7 +17,7 @@ public static void main(String[] args) {
 		System.out.println(abc.get(1));
 		abc.remove(1);
 		System.out.println(abc.get(0));
-		System.out.println(abc.get(1));
+		System.out.println(abc.get(1));*/
 	}
 
 }
diff --git a/group04/474772605/src/com/coding/iostreams/inteface.java b/group04/474772605/src/com/coding/iostreams/inteface.java
new file mode 100644
index 0000000000..b0df92bd6b
--- /dev/null
+++ b/group04/474772605/src/com/coding/iostreams/inteface.java
@@ -0,0 +1,11 @@
+package com.coding.iostreams;
+
+public class inteface implements test{
+	
+	public float method() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+}
+
diff --git a/group04/474772605/src/com/coding/iostreams/readfile.java b/group04/474772605/src/com/coding/iostreams/readfile.java
new file mode 100644
index 0000000000..e91ecd3749
--- /dev/null
+++ b/group04/474772605/src/com/coding/iostreams/readfile.java
@@ -0,0 +1,67 @@
+package com.coding.iostreams;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+public class readfile {
+
+	public static void main(String[] args) {
+		String filename = "/test.txt";
+		fileread(filename);
+	}
+	
+	public static void fileread(String filename){	
+	
+		File file = new File(filename);		
+		Reader reader = null;
+		int  n1=0;
+		int  n2=2;
+		try {
+			reader = new InputStreamReader(new FileInputStream(file));
+			int num ;
+			while((num = reader.read())!= -1){
+				if((char)num != '\r'){
+					if((char)num >='A'&&(char)num <='z'){
+						n1++;
+					}
+					if((char)num >='A'&&(char)num <='Z'){
+						n2++;
+					}
+				}
+			}			
+			reader.close();	
+			System.out.println(n1+""+n2);
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}	
+	}
+	
+	
+		
+		public  float method(){
+			return 13.21f;
+		}
+	
+	
+
+		
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
diff --git a/group04/474772605/src/com/coding/iostreams/test.java b/group04/474772605/src/com/coding/iostreams/test.java
new file mode 100644
index 0000000000..1bd474ca7b
--- /dev/null
+++ b/group04/474772605/src/com/coding/iostreams/test.java
@@ -0,0 +1,14 @@
+package com.coding.iostreams;
+
+public interface test {
+	public  float  method();
+	
+}
+	
+
+
+
+
+	
+	
+	
diff --git a/group04/349184132/Study/bin/com/second/struts.xml b/group04/474772605/src/struts.xml
similarity index 57%
rename from group04/349184132/Study/bin/com/second/struts.xml
rename to group04/474772605/src/struts.xml
index 554dbbe227..8bd00bb1f0 100644
--- a/group04/349184132/Study/bin/com/second/struts.xml
+++ b/group04/474772605/src/struts.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <struts>
-    <action name="login" class="com.second.LoginAction">
+    <action name="login" class="com.coderising.action.LoginAction">
         <result name="success">/jsp/homepage.jsp</result>
         <result name="fail">/jsp/showLogin.jsp</result>
     </action>
-    <action name="logout" class="com.second.LogoutAction">
+    <action name="logout" class="com.coderising.action.LogoutAction">
     	<result name= "success">/jsp/welcome.jsp</result>
-    	<result name= "error">/jsp/error.jsp</result>
+    	<result name= "fail">/jsp/error.jsp</result>
     </action>
 </struts>
\ No newline at end of file
diff --git a/group04/474772605/test/Test.java b/group04/474772605/test/Test.java
new file mode 100644
index 0000000000..8c0f62930b
--- /dev/null
+++ b/group04/474772605/test/Test.java
@@ -0,0 +1,50 @@
+
+
+	import java.io.File;
+	import java.io.FileInputStream;
+	import java.io.InputStreamReader;
+	import java.io.Reader;
+
+
+
+
+	public  class Test{
+		 static int n1 =0 ;
+		 static int n2 =0 ;
+
+		public static void main(String[] args) throws Exception{
+			 
+			Test.readFileByChars("D://Text.txt");
+			
+			System.out.println("字母个数为："+n1+"  字母个数为"+n2);
+			
+	}
+
+		 public static void readFileByChars(String fileName) {
+		        File file = new File(fileName);
+		        Reader reader = null;
+		        try {
+		            System.out.println("以字符为单位读取文件内容，一次读一个字节：");
+		            // 一次读一个字符
+		            reader = new InputStreamReader(new FileInputStream(file));
+		            int tempchar;
+		            while ((tempchar = reader.read()) != -1) {
+		                // 对于windows下，\r\n这两个字符在一起时，表示一个换行。
+		                // 但如果这两个字符分开显示时，会换两次行。
+		                // 因此，屏蔽掉\r，或者屏蔽\n。否则，将会多出很多空行。
+		                if (((char) tempchar) != '\r') {
+		                    System.out.print((char) tempchar);
+		                      n1++;
+		                    if((char)tempchar >='A'&&(char)tempchar<='Z'){
+		                    	n2++;
+		                    }
+		                    
+		                }
+		            }
+		            reader.close();
+		        } catch (Exception e) {
+		            e.printStackTrace();
+		        }
+		    }
+	}
+
diff --git a/group04/474772605/test/com/coding/basic/Heros.java b/group04/474772605/test/com/coding/basic/Heros.java
new file mode 100644
index 0000000000..878204aede
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Heros.java
@@ -0,0 +1,51 @@
+package com.coding.basic;
+
+import java.lang.reflect.Method;
+
+public class Heros {
+    private String name;//名字
+    private String type;//类型
+    private int camp;//0,近卫；1，天灾
+	public Heros(){
+    	
+    }
+ /*
+    public Heros(String name, String type, int camp) {
+    	
+        super();
+      
+        this.name = name;
+        this.type = type;
+        this.camp = camp;
+    }*/
+ 
+    public String getName() {
+        return name;
+    }
+ 
+    public void setName(String name) {
+        this.name = name;
+    }
+ 
+    public String getType() {
+        return type;
+    }
+ 
+    public void setType(String type) {
+        this.type = type;
+    }
+ 
+    public int getCamp() {
+        return camp;
+    }
+ 
+    public void setCamp(int camp) {
+        this.camp = camp;
+    }
+ 
+    @Override
+    public String toString() {
+        return "Heros [\n name=" + name + ", \n type=" + type + ", \n camp=" + camp + "\n]";
+    }
+     
+}
\ No newline at end of file
diff --git a/group04/474772605/test/com/coding/basic/Test.java b/group04/474772605/test/com/coding/basic/Test.java
new file mode 100644
index 0000000000..97f7254c82
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Test.java
@@ -0,0 +1,43 @@
+package com.coding.basic;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class Test {
+
+    public static void main(String args[]) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        Foo foo = new Foo("这个一个Foo对象！");
+        Class clazz = foo.getClass(); 
+        Field[] abc =clazz.getDeclaredFields();
+     
+       // Object value = getFieldValueByName(key, obj); 
+        Method m1 = clazz.getDeclaredMethod("outInfo");
+        Method m2 = clazz.getDeclaredMethod("setMsg", String.class);
+        Method m3 = clazz.getDeclaredMethod("getMsg");
+        m1.invoke(foo); 
+        m2.invoke(foo, "重新设置msg信息！"); 
+        String msg = (String) m3.invoke(foo); 
+        System.out.println(msg); 
+    } 
+} 
+
+class Foo { 
+    private String msg; 
+
+    public Foo(String msg) { 
+        this.msg = msg; 
+    } 
+
+    public void setMsg(String msg) {
+        this.msg = msg; 
+    } 
+
+    public String getMsg() { 
+        return msg; 
+    } 
+
+    public void outInfo() {
+        System.out.println("这是测试Java反射的测试类"); 
+    } 
+}
diff --git a/group04/474772605/test/com/coding/basic/TestStack.java b/group04/474772605/test/com/coding/basic/TestStack.java
new file mode 100644
index 0000000000..e4caa84d98
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/TestStack.java
@@ -0,0 +1,35 @@
+package com.coding.basic;
+
+import junit.framework.TestCase;
+
+public class TestStack extends TestCase{
+private Stack stack;	
+	
+
+public void setUp() throws Exception {
+	 stack = new Stack();
+	
+}
+
+public void testpop(){
+//	Stack stack = new Stack();
+	Object o = null ;
+	try {
+		stack.push(o);
+	} catch (Exception e) {
+		// TODO Auto-generated catch block
+		e.printStackTrace();
+	}
+	
+	
+	
+	
+}
+
+
+
+
+
+
+
+}
diff --git a/group04/474772605/test/com/coding/basic/Testarray.java b/group04/474772605/test/com/coding/basic/Testarray.java
new file mode 100644
index 0000000000..19edb9f85d
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/Testarray.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+import junit.framework.TestCase;
+
+public class Testarray extends TestCase{
+	
+	public void testararry(){
+		Throwable tx = null;
+		try {
+			ArrayList n = new ArrayList();
+			Object o = null ;
+		
+			n.add(o);
+			fail();
+		} catch (Exception e) {
+			tx =e;
+			assertEquals(Exception.class, tx.getClass());
+			assertEquals("对象不能为空", e.getMessage());
+		}
+	}
+
+}
diff --git a/group04/474772605/test/com/coding/basic/teest.java b/group04/474772605/test/com/coding/basic/teest.java
new file mode 100644
index 0000000000..e8004c14b6
--- /dev/null
+++ b/group04/474772605/test/com/coding/basic/teest.java
@@ -0,0 +1,24 @@
+package com.coding.basic;
+
+import java.lang.reflect.Method;
+
+public class teest {
+	 public static void main(String[] args) {
+	        Class<?> herosClass = Heros.class;
+	        try {
+	            Method m1 = herosClass.getMethod("setName",String.class);
+	            Method m3 = herosClass.getMethod("setCamp",int.class);
+	            Method m2 = herosClass.getMethod("getName");
+	            
+	          
+	            Object userInfo = herosClass.newInstance();
+	            System.out.println("调用构造函数："+userInfo);
+	            m1.invoke(userInfo,"影魔");
+	            m3.invoke(userInfo, 1);
+	            System.out.println("调用set方法："+userInfo);
+	            System.out.println("调用get方法："+m2.invoke(userInfo));
+	        } catch (Exception e) {
+	            e.printStackTrace();
+	        }
+	    }
+}
diff --git a/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..d4e0f52537
--- /dev/null
+++ b/group04/498654356/mini-jvm/jvm/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,83 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+
+
+public class ClassFileLoader {
+
+	private static final String CLASS_SUFFIX = ".class";
+	private static final byte[] EMPTY_BYTES = new byte[0];
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		if(StringUtils.isEmpty(className)) {
+			return EMPTY_BYTES;
+		}
+		String child = className.replaceAll("\\.", "\\\\") + CLASS_SUFFIX;
+		for (String parent: clzPaths) {
+			File file = new File(parent, child);
+			if(file.exists()) {
+				return doReadBinaryCode(file);
+			}
+		}
+		return EMPTY_BYTES;	
+	}
+	
+	
+	private byte[] doReadBinaryCode(File file) {
+		FileInputStream fis = null;
+		ByteArrayOutputStream baos = null;
+		try {
+			fis = new FileInputStream(file);
+			baos = new ByteArrayOutputStream();
+			byte[] b = new byte[1024];
+			int len = 0;
+			while((len = fis.read(b)) > 0) {
+				baos.write(b, 0, len);
+			}
+			return baos.toByteArray();
+		} catch (Exception e) {
+			new RuntimeException(e);
+		} finally {
+			close(baos);
+			close(fis);
+		}
+		return EMPTY_BYTES;
+	}
+
+
+	private void close(Closeable stream) {
+		if(stream != null ) {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+	
+	public String getClassPath(){
+		StringBuilder builder = new StringBuilder();
+		for (String path : clzPaths) {
+			builder.append(path).append(";");
+		}
+		if(builder.length() > 0) {
+			builder = builder.deleteCharAt(builder.length() - 1);
+		}
+		return builder.toString();
+	}
+	
+}
diff --git a/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..3f4a585db7
--- /dev/null
+++ b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,93 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	private static final String CAFEBABE = "cafebabe";
+	static String path1 = "D:\\Dev\\git_repository\\coding2017\\group04\\498654356\\mini-jvm\\jvm\\target\\test-classes";
+	static String path2 = "C:\\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals(CAFEBABE, acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/EmployeeV1.java b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..9a36573dd3
--- /dev/null
+++ b/group04/498654356/mini-jvm/jvm/src/test/java/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group04/498654356/one/src/org/coding/four/lru/LRUPageFrame.java b/group04/498654356/one/src/org/coding/four/lru/LRUPageFrame.java
new file mode 100644
index 0000000000..1113e39e7a
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/four/lru/LRUPageFrame.java
@@ -0,0 +1,134 @@
+package org.coding.four.lru;
+
+/**
+ * 用双向链表实现LRU(最近最少使用)算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		if(first == null) {
+			first = new Node();
+			first.pageNum = pageNum;
+			last = first;
+		} else {
+			if(isFull()) { 
+				Node node = findNode(pageNum);
+				if(node == null) { // not found
+					removeLastNode();
+					push(pageNum);
+				} else {
+					if(node == first) {
+						return ;
+					}
+					if(node == last) {
+						removeLastNode();
+						node.next = first;
+						first.prev = node;
+						first = node;
+						return;
+					}
+					node.prev.next = node.next;
+					node.next.prev = node.prev;
+					node.prev = null;
+					node.next = first;
+					first = node;
+				}
+			} else {
+				push(pageNum);
+			}
+		}
+	
+	}
+
+	private boolean isFull() {
+		return getSize() == capacity;
+	}
+
+	private void removeLastNode() {
+		last = last.prev;
+		last.next = null;
+	}
+
+	private void push(int pageNum) {
+		Node node = new Node();
+		node.pageNum = pageNum;
+		node.next = first;
+		first.prev = node;
+		first = node;
+	}
+	
+	
+
+	private Node findNode(int pageNum) {
+		if(first.pageNum == pageNum) {
+			return first;
+		}
+		Node node = first;
+		while(node.next != null)  {
+			node = node.next;
+			if(node.pageNum == pageNum) {
+				return node;
+			}
+		}
+		return null;
+	}
+
+	private int getSize() {
+		if(first == null) {
+			return  0;
+		}
+		Node node = first;
+		int size = 1;
+		while(node.next != null) {
+			size++;
+			node = node.next;
+		}
+		return size;
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group04/498654356/one/src/org/coding/one/LinkedList.java b/group04/498654356/one/src/org/coding/one/LinkedList.java
index 183f634418..3f98db326f 100644
--- a/group04/498654356/one/src/org/coding/one/LinkedList.java
+++ b/group04/498654356/one/src/org/coding/one/LinkedList.java
@@ -1,5 +1,8 @@
 package org.coding.one;
 
+/**
+ *  双链表/双向链表
+ */
 public class LinkedList implements List {
 
 	private Node first;
diff --git a/group04/498654356/one/src/org/coding/three/download/DownloadThread.java b/group04/498654356/one/src/org/coding/three/download/DownloadThread.java
new file mode 100644
index 0000000000..84a0d94c73
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/DownloadThread.java
@@ -0,0 +1,36 @@
+package org.coding.three.download;
+
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+import org.coding.three.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+	CyclicBarrier barrier;
+	Connection conn;
+	int startPos;
+	int endPos;
+	String destpath;
+
+	public DownloadThread(CyclicBarrier barrier, Connection conn, int startPos, int endPos, String destpath) {
+		this.barrier = barrier;
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+		this.destpath = destpath;
+	}
+	public void run(){	
+		try {
+			byte[] b = conn.read(startPos, endPos);
+			RandomAccessFile raf = new RandomAccessFile(destpath, "rw");
+			raf.seek(startPos);
+			raf.write(b);
+			raf.close();
+			conn.close();
+			barrier.await();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/FileDownloader.java b/group04/498654356/one/src/org/coding/three/download/FileDownloader.java
new file mode 100644
index 0000000000..69e83d1eae
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/FileDownloader.java
@@ -0,0 +1,108 @@
+package org.coding.three.download;
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+import org.coding.three.download.api.Connection;
+import org.coding.three.download.api.ConnectionManager;
+import org.coding.three.download.api.DownloadListener;
+
+public class FileDownloader {
+	
+	String url;
+	String destPath;
+	private int threadCount;
+	
+	DownloadListener listener;
+	ConnectionManager cm;
+	
+	public FileDownloader(String _url, String destPath, int threadCount) {
+		this.url = _url;
+		this.destPath = destPath;
+		this.threadCount = threadCount;
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			conn = cm.open(this.url);
+			int length = conn.getContentLength();
+			createDownloadFile(length);
+			int[][] threadData = allocationData(length);
+			CyclicBarrier barrier = new CyclicBarrier(this.threadCount, new Runnable() {
+				@Override
+				public void run() {
+					listener.notifyFinished();
+				}
+			});
+			// TODO
+			for(int i = 0; i < this.threadCount; i++) {
+				new DownloadThread(barrier, conn, threadData[i][0], threadData[i][1], this.destPath).start();
+			}
+		} catch (Exception e) {			
+			e.printStackTrace();
+		} finally {
+			conn.close();
+		}
+		
+	}
+	
+	private int[][] allocationData(int length) {
+		int[][] threadData = new int[this.threadCount][2];
+		int size = length / this.threadCount;
+		int offset = length % this.threadCount;
+		for(int i = 0; i < this.threadCount; i++) {
+			int start = i * size;
+			int end = (i + 1) * size -1;
+			if(i + 1 == this.threadCount) {
+				end += offset;
+			}
+			threadData[i][0] = start;
+			threadData[i][1] = end;
+			
+		}
+		return threadData;
+	}
+
+
+	private void createDownloadFile(int length) throws Exception {
+		File file = new File(destPath);
+		if(file.exists()) {
+			file.delete();
+		}
+		RandomAccessFile raf = new RandomAccessFile(destPath, "rw");
+		for(int i = 0; i < length; i++) {
+			raf.writeByte(0);
+		}
+		raf.close();
+	}
+
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+	
+	
+}
+ 
\ No newline at end of file
diff --git a/group04/498654356/one/src/org/coding/three/download/api/Connection.java b/group04/498654356/one/src/org/coding/three/download/api/Connection.java
new file mode 100644
index 0000000000..6c3a0e66d6
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/api/Connection.java
@@ -0,0 +1,23 @@
+package org.coding.three.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/api/ConnectionException.java b/group04/498654356/one/src/org/coding/three/download/api/ConnectionException.java
new file mode 100644
index 0000000000..a07cc52e39
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/api/ConnectionException.java
@@ -0,0 +1,16 @@
+package org.coding.three.download.api;
+
+@SuppressWarnings("serial")
+public class ConnectionException extends Exception {
+	
+	public ConnectionException() {}
+	
+	public ConnectionException(String msg) {
+		super(msg);
+	}
+
+	public ConnectionException(Throwable t) {
+		super(t);
+	}
+	
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/api/ConnectionManager.java b/group04/498654356/one/src/org/coding/three/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..c4bc02e65b
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package org.coding.three.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/api/DownloadListener.java b/group04/498654356/one/src/org/coding/three/download/api/DownloadListener.java
new file mode 100644
index 0000000000..0d9dc0974d
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package org.coding.three.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/impl/ConnectionImpl.java b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..b81dc72dc4
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionImpl.java
@@ -0,0 +1,67 @@
+package org.coding.three.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+
+import org.coding.three.download.api.Connection;
+import org.coding.three.download.api.ConnectionException;
+
+
+public class ConnectionImpl implements Connection{
+	private static final int BUFFER_SIZE = 1024;
+	private URL url;
+	public ConnectionImpl (String url) throws ConnectionException {
+		try {
+			this.url = new URL(url);
+		} catch (MalformedURLException e) {
+			throw new ConnectionException(e);
+		}
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+		// ***
+		urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+		InputStream is = urlConnection.getInputStream();
+		int size = endPos - startPos + 1;
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		byte[] buffer = new byte[BUFFER_SIZE];
+		int len = 0;
+		while(baos.size() < size) {
+			if((len = is.read(buffer)) < 0) {
+				break;
+			}
+			baos.write(buffer, 0, len);
+		}
+		if(baos.size() > size) {
+			return Arrays.copyOf(baos.toByteArray(), size);
+		}
+		return baos.toByteArray();
+	}
+
+	@Override
+	public int getContentLength() {
+		try {
+			return url.openConnection().getContentLength();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return -1;
+	}
+
+	@Override
+	public void close() {
+		try {
+			url.openStream().close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..e595cb3ccb
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,14 @@
+package org.coding.three.download.impl;
+
+import org.coding.three.download.api.Connection;
+import org.coding.three.download.api.ConnectionException;
+import org.coding.three.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		return new ConnectionImpl(url);
+	}
+
+}
diff --git a/group04/498654356/one/src/org/coding/three/list/List.java b/group04/498654356/one/src/org/coding/three/list/List.java
new file mode 100644
index 0000000000..d06cf962da
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/list/List.java
@@ -0,0 +1,9 @@
+package org.coding.three.list;
+
+public interface List {
+	public void add(Object o);
+	public void add(int index, Object o);
+	public Object get(int index);
+	public Object remove(int index);
+	public int size();
+}
diff --git a/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java
new file mode 100644
index 0000000000..ef38ca811d
--- /dev/null
+++ b/group04/498654356/one/src/org/coding/three/list/impl/LinkedList.java
@@ -0,0 +1,422 @@
+package org.coding.three.list.impl;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.coding.three.list.List;
+/**
+ * 单链表/单向链表
+ */
+public class LinkedList implements List {
+	/**
+	 * 0. head 节点存储数据
+	 * 1. 这里的 head 第一次添加之后 "引用" 将不再改变；"值" 可以被修改已表示往首节点插入新的值。 
+	 * 2. 可以将 head 修改为对 node 引用, 不存储任何数据。
+	 */
+	private Node head;
+	
+	public void add(Object o){
+		Node node = new Node(o);
+		if(head == null){ //第一次
+			head = node;
+		} else {
+			getNode(size() - 1).next = node;
+		}
+	}
+	
+	private Node getNode(int index) {
+		checkIndex(index);
+		Node node = head;
+		for(int i = 0; i < index; i++) {
+			node = node.next;
+		}
+		return node;
+	}
+	
+	private void checkIndex(int index) {
+		int size = size();
+		if(index < 0 || index > (size - 1)) {
+			throw new IndexOutOfBoundsException("size = "  + size + ", index = " + index);
+		}
+	}
+	public void add(int index , Object o){
+		checkIndex(index);
+		if(index == 0) {	//更新 head 的值, 将旧值创建新的Node插入到 head 后
+			Object data = head.data;
+			head.data = o;
+			Node node = new Node(data);
+			node.next = head.next;
+			head.next = node;
+		} else {
+			Node pre = getNode(index - 1);
+			Node node = new Node(o);
+			node.next = pre.next;
+			pre.next = node;
+		}
+	}
+	public Object get(int index){
+		checkIndex(index);
+		return getNode(index).data;
+	}
+	public Object remove(int index){
+		checkIndex(index);
+		Object data = null;
+		if(index == 0) {
+			Node next = head.next;
+			data = head.data;
+			if(next == null) {
+				head = null;
+			} else {
+				head.data = next.data;
+				head.next = next.next;
+				next.next = null;
+			}
+		} else {
+			Node pre = getNode(index - 1);
+			Node node = pre.next;
+			pre.next = node.next;
+			node.next = null;
+			data = node.data;
+		}
+		return data;
+	}
+	
+	public int size(){
+		Node temp = head;
+		int size = 0;
+		while(temp != null) {
+			size++;
+			temp = temp.next;
+		}
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		add(0, o);
+	}
+	public void addLast(Object o){
+		add(o);
+	}
+	public Object removeFirst(){
+		return remove(0);
+	}
+	public Object removeLast(){
+		return remove(size() - 1); 
+	}
+	public Iterator<?> iterator(){
+		return new LinkedIterator();
+	}
+
+	class LinkedIterator implements Iterator<Object> {
+        int cursor = 0;
+        int lastRet = -1;
+		@Override
+		public boolean hasNext() {
+			return cursor != LinkedList.this.size();
+		}
+
+		@Override
+		public Object next() {
+			int i = cursor;
+			Object data = LinkedList.this.get(i);
+			lastRet = i;
+			cursor = i + 1;
+			return data;
+		}
+		
+		@Override
+		public void remove() {
+			if(lastRet < - 1) {
+				throw new RuntimeException("非法操作");
+			}
+			LinkedList.this.remove(lastRet);
+			cursor--;
+			lastRet = -1;
+		}
+	}
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		public Node(Object data) {
+			super();
+			this.data = data;
+		}
+		
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){		
+		int size = size();
+		if(size < 2) {
+			return ;
+		}
+		int preIndex = 0;
+		int behindIndex = size - 1;
+		Node preNode = head;
+		while(preIndex < behindIndex) {
+			Node behindNode = getNode(behindIndex);
+			Object temp = preNode.data;
+			preNode.data = behindNode.data;
+			behindNode.data = temp;
+			preIndex++;
+			behindIndex--;
+			preNode = preNode.next;
+		}
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		if(size() < 2) {
+			return;
+		}
+		int count = size() / 2;
+		Node preNode = getNode(count - 1);
+		Node nextNode = preNode.next;
+		preNode.next = null;
+		head.data = nextNode.data;
+		head.next = nextNode.next;
+		nextNode.next = null;
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int index, int length){
+		checkIndex(index);
+		int size = size();
+		if(index + length > size) {
+			length = size;
+		}
+		if(index == 0 && length == size) {
+			head = null;
+			return;
+		}
+		int tempIndex = index + length - 1;
+		Node endNode = getNode(tempIndex);
+		Node nextNode = endNode.next;
+		endNode.next = null;
+		if(index == 0) { //head
+			Node nnextNode = nextNode.next;
+			nextNode.next = null;
+			head.data = nextNode.data;
+			head.next = nnextNode;
+		} else {
+			Node preStartNode = getNode(index - 1);
+			preStartNode.next = nextNode;
+		}
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		Iterator<?> it = list.iterator();
+		int[] array = new int[list.size()];
+		int size = size();
+		int length = 0;
+		while(it.hasNext()) {
+			int index = (int) it.next();
+			if(index >= size)  {
+				break;
+			}
+			array[length++] = (int) get(index);
+		}
+		if(length == array.length) {
+			return array;
+		} else {
+			return Arrays.copyOf(array, length); 
+		}
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		Iterator<?> it = list.iterator();
+		while(it.hasNext()) {
+			Object next = it.next();
+			Iterator<?> iterator = this.iterator();
+			while(iterator.hasNext()) {
+				if(next.equals(iterator.next())) {
+					iterator.remove();
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		if(size() < 2) {
+			return;
+		}
+		Iterator<?> it = iterator();
+		Object pre = null;
+		while(it.hasNext()){
+			Object data = it.next();
+			if(pre != null && pre.equals(data)) {
+				it.remove();
+			} else {
+				pre = data;
+			}
+		}
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		int size = size();
+		if(size < 1) {
+			return;
+		}
+		int minVal = (int)get(0);
+		int maxVal = (int)get(size - 1);
+		if(minVal > min && maxVal < max) {	//直接清空
+			this.head = null;
+			return;
+		}
+		if(max <= minVal) {
+			return;
+		}
+		if(min >= maxVal) {
+			return;
+		}
+		int startIndex = getMinIndex(min, size);
+		int endIndex = getMaxIndex(max, size);
+		if(endIndex - startIndex < 0) {
+			return;
+		}
+		remove(startIndex, (endIndex - startIndex) + 1);
+		
+	}
+
+	private int getMaxIndex(int max, int size) {
+		int start = 0;
+		int end = size - 1;
+		while(start < end) {
+			int index = (end + start) / 2;
+			int midVal = (int) get(index);
+			if(midVal == max) {
+				return index - 1;
+//				index = index - 1;
+//				Node node = getNode(index);
+//				if((int)node.data < maxVal) {
+//					return index ;
+//				}//不考虑重复 TODO
+			}
+			if(midVal > max) {
+				end = index - 1;
+			} else {
+				start = index + 1;
+			}
+		}
+		if((int)get(end) >= max) {
+			return 0;
+		}
+		return end;
+	}
+
+	private int getMinIndex(int min, int size) {
+		int start = 0;
+		int end = size - 1;
+		while(start < end) {
+			int index = (end + start) / 2;
+			int midVal = (int) get(index);
+			if(midVal == min) {
+				return index + 1;
+//				Node node = getNode(index);	//暂无考虑重复 TODO
+//				if(node.next != null && (int)node.next.data > midVal) {
+//					return index + 1;
+//				} else {
+//					while(node.next != null && (int)node.next.data == midVal) {	// 重复值
+//						node = node.next;
+//						index++;
+//					}
+//					return index;
+//					
+//				}
+			}
+			if(midVal > min) {
+				end = index - 1;
+			} else {
+				start = index + 1;
+			}
+		}
+		if((int)get(start) <= min) {
+			return size;
+		}
+		return start;
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		LinkedList linkedList = new LinkedList();
+		if(list == null || size() == 0 || list.size() == 0) {
+			return linkedList;
+		}
+		Iterator<?> it = iterator();
+		int index = 0;
+		boolean iseqFlag = false;
+		boolean isgtFlag = false;
+		while(it.hasNext()) {
+			int v1 = (int) it.next();
+			if(index != 0) {
+				if(iseqFlag) {
+					list.remove(0, index + 1);
+					iseqFlag = false;
+				}
+				if(isgtFlag) {
+					list.remove(0, index);
+					isgtFlag = false;
+				}
+			}
+			Iterator<?> it2 = list.iterator();
+			while(it2.hasNext()) {
+				int v2 = (int) it2.next();
+				if(v2 == v1) {
+					linkedList.add(v1);
+					iseqFlag = true;
+					break;
+				} else if(v2 > v1) {
+					isgtFlag = true;
+					break;
+				}
+				index++;
+			}
+			if(index == list.size()) {	//第二个链表中的值是否全部小于现在第一个链表中正在进行比较的值
+				break;
+			}
+		}
+		return linkedList;
+	}
+}
diff --git a/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java b/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java
new file mode 100644
index 0000000000..0d08db77e9
--- /dev/null
+++ b/group04/498654356/one/test/org/coding/four/lru/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package org.coding.four.lru;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java b/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..63d98a4636
--- /dev/null
+++ b/group04/498654356/one/test/org/coding/three/download/FileDownloaderTest.java
@@ -0,0 +1,61 @@
+package org.coding.three.download;
+
+import org.coding.three.download.api.ConnectionManager;
+import org.coding.three.download.api.DownloadListener;
+import org.coding.three.download.impl.ConnectionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+//		String url = "http://7xq43s.com1.z0.glb.clouddn.com/yunanding-6.jpg";
+//		String url = "http://www.yinwang.org/blog-cn/2016/11/17/all-about-hillary";
+//		String url = "http://orig04.deviantart.net/93d4/f/2007/314/9/5/audrey_tautou_by_shimoda7.jpg";
+		String url = "http://pic36.nipic.com/20131230/1081324_162447228136_2.jpg";
+		String destpath = "D:/b.jpg";
+		int threadCount = 3;
+		
+		FileDownloader downloader = new FileDownloader(url, destpath, threadCount);
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java b/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java
new file mode 100644
index 0000000000..88a8bdf9b3
--- /dev/null
+++ b/group04/498654356/one/test/org/coding/three/list/impl/LinkedListTest.java
@@ -0,0 +1,477 @@
+package org.coding.three.list.impl;
+
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class LinkedListTest {
+	private LinkedList linkedList;
+
+	@Before
+	public void setUp() throws Exception {
+		linkedList = new LinkedList();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		linkedList = null;
+	}
+
+	@Test
+	public void testAddObject() {
+		int expected = 0;
+		int actual = linkedList.size();
+		Assert.assertEquals(expected, actual);
+
+		linkedList.add(1);
+		expected = 1;
+		actual = linkedList.size();
+		Assert.assertEquals(expected, actual);
+
+		linkedList.add(2);
+		expected = 2;
+		actual = linkedList.size();
+		Assert.assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testAddIntObject() {
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		
+		linkedList.add(0, 4);
+		int expected = 4;
+		int actual = (int) linkedList.get(0);
+		Assert.assertEquals(expected, actual);
+		Assert.assertEquals(4, linkedList.size());
+		
+		linkedList.add(2, 5);
+		Assert.assertEquals(5, linkedList.size());
+		expected = 5;
+		actual = (int) linkedList.get(2);
+		Assert.assertEquals(expected, actual);
+		
+	}
+
+	@Test
+	public void testGet() {
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		
+		int expected = 1;
+		int actual = (int) linkedList.get(0);
+		Assert.assertEquals(expected, actual);
+		
+		expected = 2;
+		actual = (int) linkedList.get(1);
+		Assert.assertEquals(expected, actual);
+		
+		expected = 3;
+		actual = (int) linkedList.get(2);
+		Assert.assertEquals(expected, actual);
+	}
+
+	@Test
+	public void testRemoveInt() {
+		linkedList.add(1);
+		
+		int v = (int) linkedList.remove(0);
+		Assert.assertEquals(1, v);
+		Assert.assertEquals(0, linkedList.size());
+		
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		
+		v = (int) linkedList.remove(1);
+		Assert.assertEquals(2, v);
+		Assert.assertEquals(2, linkedList.size());
+		
+		linkedList.add(4);
+		linkedList.add(5);
+		linkedList.add(6);
+		
+		v = (int) linkedList.remove(linkedList.size() - 1);
+		Assert.assertEquals(6, v);
+		Assert.assertEquals(4, linkedList.size());
+	}
+
+	@Test
+	public void testSize() {
+		Assert.assertEquals(0, linkedList.size());
+		linkedList.add(1);
+		Assert.assertEquals(1, linkedList.size());
+		linkedList.remove(0);
+		Assert.assertEquals(0, linkedList.size());
+	}
+
+	@Test
+	public void testAddFirst() {
+		linkedList.add(4);
+		linkedList.add(5);
+		linkedList.add(6);
+		linkedList.addFirst(1);
+		Assert.assertEquals(4, linkedList.size());
+		Assert.assertEquals(1, linkedList.get(0));
+	}
+
+	@Test
+	public void testAddLast() {
+		linkedList.addLast(1);
+		Assert.assertEquals(1, linkedList.size());
+		Assert.assertEquals(1, linkedList.get(0));
+		linkedList.addLast(2);
+		Assert.assertEquals(2, linkedList.size());
+		Assert.assertEquals(2, linkedList.get(1));
+	}
+
+	@Test
+	public void testRemoveFirst() {
+		linkedList.add(4);
+		linkedList.add(5);
+		linkedList.add(6);
+		int v = (int) linkedList.removeFirst();
+		Assert.assertEquals(2, linkedList.size());
+		Assert.assertEquals(4, v);
+	}
+	
+	@Test(expected = IndexOutOfBoundsException.class)
+	public void testRemoveFirstException() {
+		linkedList.removeFirst();
+	}
+
+	@Test
+	public void testRemoveLast() {
+		linkedList.add(4);
+		int v = (int) linkedList.removeLast();
+		Assert.assertEquals(0, linkedList.size());
+		Assert.assertEquals(4, v);
+		
+		linkedList.add(5);
+		linkedList.add(6);
+		v = (int) linkedList.removeLast();
+		Assert.assertEquals(1, linkedList.size());
+		Assert.assertEquals(6, v);
+	}
+
+	@Test(expected = IndexOutOfBoundsException.class)
+	public void testRemoveLastException() {
+		linkedList.removeLast();
+	}
+	@Test
+	public void testIterator() {
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		Iterator<?> it = linkedList.iterator();
+		int expected = 1;
+		while(it.hasNext()) {
+			Object v = it.next();
+			Assert.assertEquals(expected++, v);
+		}
+		
+	}
+
+	@Test
+	public void testIteratorRemove() {
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		Iterator<?> it = linkedList.iterator();
+		while(it.hasNext()) {
+			it.next();
+			it.remove();
+		}
+		Assert.assertEquals(0, linkedList.size());
+		
+	}
+	@Test
+	public void testReverse() {
+		linkedList.add(3);
+		linkedList.add(7);
+		linkedList.add(10);
+		linkedList.reverse();
+		Assert.assertEquals(10, linkedList.get(0));
+		Assert.assertEquals(7, linkedList.get(1));
+		Assert.assertEquals(3, linkedList.get(2));
+	}
+	
+	@Test
+	public void testReverse2() {
+		linkedList.add(3);
+		linkedList.reverse();
+		Assert.assertEquals(3, linkedList.get(0));
+	}
+	
+	@Test
+	public void testReverse3() {
+		linkedList.add(3);
+		linkedList.add(7);
+		linkedList.reverse();
+		Assert.assertEquals(7, linkedList.get(0));
+		Assert.assertEquals(3, linkedList.get(1));
+	}
+
+
+
+	@Test
+	public void testRemoveFirstHalf() {
+		linkedList.add(2);
+		linkedList.add(5);
+		linkedList.add(7);
+		linkedList.add(8);
+		linkedList.removeFirstHalf();
+		Assert.assertEquals(7, linkedList.get(0));
+		Assert.assertEquals(8, linkedList.get(1));
+	}
+
+	@Test
+	public void testRemoveFirstHalf2() {
+		linkedList.add(2);
+		linkedList.add(5);
+		linkedList.add(7);
+		linkedList.add(8);
+		linkedList.add(10);
+		linkedList.removeFirstHalf();
+		Assert.assertEquals(7, linkedList.get(0));
+		Assert.assertEquals(8, linkedList.get(1));
+		Assert.assertEquals(10, linkedList.get(2));
+	}
+
+	@Test
+	public void testRemoveIntInt() {
+		linkedList.add(2);
+		linkedList.add(5);
+		linkedList.add(7);
+		linkedList.add(8);
+		linkedList.add(10);
+		linkedList.remove(1, 2);
+		Assert.assertEquals(3, linkedList.size());
+		Assert.assertEquals(2, linkedList.get(0));
+		Assert.assertEquals(8, linkedList.get(1));
+		Assert.assertEquals(10, linkedList.get(2));
+	}
+	
+
+	@Test
+	public void testRemoveIntIntFull() {
+		linkedList.add(2);
+		linkedList.add(5);
+		linkedList.add(7);
+		linkedList.add(8);
+		linkedList.add(10);
+		linkedList.remove(0, 10);
+		Assert.assertEquals(0, linkedList.size());
+	}
+	
+
+	@Test
+	public void testRemoveIntIntHead() {
+		linkedList.add(2);
+		linkedList.add(5);
+		linkedList.add(7);
+		linkedList.add(8);
+		linkedList.add(10);
+		linkedList.remove(0, 2);
+		Assert.assertEquals(3, linkedList.size());
+		Assert.assertEquals(7, linkedList.get(0));
+		Assert.assertEquals(8, linkedList.get(1));
+		Assert.assertEquals(10, linkedList.get(2));
+	}
+
+	@Test
+	public void testGetElements() {
+//		11->101->201->301->401->501->601->701
+		linkedList.add(11);
+		linkedList.add(101);
+		linkedList.add(201);
+		linkedList.add(301);
+		linkedList.add(401);
+		linkedList.add(501);
+		linkedList.add(601);
+		linkedList.add(701);
+//		1->3->4->6
+		LinkedList list = new LinkedList();
+		list.add(1);
+		list.add(3);
+		list.add(4);
+		list.add(6);
+		int[] actuals = linkedList.getElements(list );
+		int[] expecteds = {101,301,401,601};
+		Assert.assertArrayEquals(expecteds, actuals);
+	}
+
+
+	@Test
+	public void testGetElements2() {
+//		11->101->201->301->401->501->601->701
+		linkedList.add(11);
+		linkedList.add(101);
+		linkedList.add(201);
+		linkedList.add(301);
+		linkedList.add(401);
+		linkedList.add(501);
+		linkedList.add(601);
+		linkedList.add(701);
+//		1->3->4->20
+		LinkedList list = new LinkedList();
+		list.add(1);
+		list.add(3);
+		list.add(4);
+		list.add(20);
+		int[] actuals = linkedList.getElements(list );
+		int[] expecteds = {101,301,401};
+		Assert.assertArrayEquals(expecteds, actuals);
+	}
+
+	@Test
+	public void testSubtract() {
+		linkedList.add(11);
+		linkedList.add(101);
+		linkedList.add(201);
+		linkedList.add(301);
+		linkedList.add(401);
+		linkedList.add(501);
+		linkedList.add(601);
+		linkedList.add(701);
+		LinkedList list = new LinkedList();
+		list.add(11);
+		list.add(201);
+		list.add(501);
+		linkedList.subtract(list );
+		Assert.assertEquals(5, linkedList.size());
+		
+	}
+	
+	@Test
+	public void testSubtract2() {
+		linkedList.add(11);
+		linkedList.add(101);
+		LinkedList list = new LinkedList();
+		list.add(11);
+		list.add(201);
+		list.add(501);
+		linkedList.subtract(list );
+		Assert.assertEquals(1, linkedList.size());
+		
+	}
+
+
+	@Test
+	public void testRemoveDuplicateValues() {
+		linkedList.add(11);
+		linkedList.add(101);
+		linkedList.add(201);
+		linkedList.add(201);
+		linkedList.add(201);
+		linkedList.add(301);
+		linkedList.add(301);
+		linkedList.add(401);
+		Assert.assertEquals(8, linkedList.size());
+		linkedList.removeDuplicateValues();
+		Assert.assertEquals(5, linkedList.size());
+		Assert.assertEquals(301, linkedList.get(linkedList.size() - 2));
+		Assert.assertEquals(201, linkedList.get(linkedList.size() - 3));
+		
+	}
+
+	@Test
+	public void testRemoveRange() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.removeRange(4, 6);
+		Assert.assertEquals(2, linkedList.size());
+		
+	}
+
+	@Test
+	public void testRemoveRange2() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.removeRange(0, 6);
+		Assert.assertEquals(0, linkedList.size());
+		
+	}
+
+	@Test
+	public void testRemoveRange3() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.removeRange(3, 5);
+		Assert.assertEquals(3, linkedList.size());
+		
+	}
+
+	@Test
+	public void testRemoveRange4() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.removeRange(1, 3);
+		Assert.assertEquals(3, linkedList.size());
+		
+	}
+
+	@Test
+	public void testRemoveRange5() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.add(6);
+		linkedList.removeRange(3, 5);
+		Assert.assertEquals(4, linkedList.size());
+		
+	}
+
+	@Test
+	public void testIntersection() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.add(6);
+		LinkedList list = new LinkedList();
+		list.add(1);
+		list.add(3);
+		LinkedList newList = linkedList.intersection(list );
+		Assert.assertEquals(2, newList.size());
+		Assert.assertEquals(1, newList.get(0));
+		Assert.assertEquals(3, newList.get(1));
+	}
+
+	@Test
+	public void testIntersection2() {
+		linkedList.add(1);
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.add(6);
+		LinkedList list = new LinkedList();
+		list.add(10);
+		list.add(13);
+		LinkedList newList = linkedList.intersection(list );
+		Assert.assertEquals(0, newList.size());
+	}
+
+	@Test
+	public void testIntersection3() {
+		linkedList.add(3);
+		linkedList.add(5);
+		linkedList.add(6);
+		LinkedList list = new LinkedList();
+		list.add(1);
+		list.add(2);
+		LinkedList newList = linkedList.intersection(list );
+		Assert.assertEquals(0, newList.size());
+	}
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..c1c4bc9032
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/DownloadThread.java
@@ -0,0 +1,62 @@
+package com.coderising.download;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+	private RandomAccessFile tempFile = null;
+	public DownloadThread( Connection conn, RandomAccessFile tempFile,String treadName){
+		super.setName(treadName);
+		this.conn = conn;	
+		this.startPos = conn.getStartPos();
+		this.endPos = conn.getEndPos();
+		this.tempFile = tempFile;
+	}
+	public void run(){	
+		
+		byte buf[] = null;
+		int count = (endPos - startPos)/1024;
+		int seekPos = 0;
+		try {
+			for (int i = 1; i < count; i++) {	
+				System.out.println(this.getName() + "    : " + (startPos+ 1024*(i-1)) + "-------" + (startPos + 1024*i) );
+				buf = new byte[1024];
+				conn.read(buf);
+				seekPos = startPos+ 1024*(i-1);
+				if (0 != seekPos) {
+					seekPos--;
+				}
+				tempFile.seek(seekPos);
+				writeToFile(buf);
+				buf = null;
+			}
+			
+			System.out.println(this.getName()  + "    : " + (startPos+ 1024*(count-1)) + "-------	" + (endPos) );
+			buf = new byte[endPos-(startPos+ 1024*(count-1))];
+			conn.read(buf);
+			seekPos = startPos+ 1024*(count-1)-1;
+			tempFile.seek(seekPos);
+			writeToFile(buf);
+			
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} 
+	}
+	
+	private synchronized void writeToFile(byte[] buf) throws IOException {
+		tempFile.write(buf, 0, buf.length);
+	}
+	
+
+	
+	
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..d1c189316b
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloader.java
@@ -0,0 +1,115 @@
+package com.coderising.download;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.UUID;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+	
+	private String url;
+	private String localPath = "";
+	private DownloadListener listener;
+	private ConnectionManager cm;
+	
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+			
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		try {
+			
+			int length = cm.open(url).getContentLength();	
+			RandomAccessFile tempFile = CreateTempFile(localPath,cm.open(url));
+			
+			int step = length / 4;
+			DownloadThread downloadThread0 = new DownloadThread(cm.open(this.url,0,step-1),tempFile,"downLoad_Thread0");
+			DownloadThread downloadThread1 = new DownloadThread(cm.open(this.url,step,2*step-1),tempFile,"downLoad_Thread1");
+			DownloadThread downloadThread2 = new DownloadThread(cm.open(this.url,2*step,3*step-1),tempFile,"downLoad_Thread2");
+			DownloadThread downloadThread3 = new DownloadThread(cm.open(this.url,3*step,length),tempFile,"downLoad_Thread3");
+			downloadThread0.start();
+			downloadThread1.start();
+			downloadThread2.start();
+			downloadThread3.start();
+			
+			while(true) {
+				if (!(downloadThread0.isAlive()||downloadThread1.isAlive()||downloadThread2.isAlive()||downloadThread3.isAlive())) {
+					tempFile.close();
+					this.listener.notifyFinished();
+					break;
+				}
+			}
+			
+		} catch (ConnectionException e) {			
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+
+	private RandomAccessFile CreateTempFile(String path,Connection _conn) {
+		String tempFileName = UUID.randomUUID().toString() + ".jpg";
+		RandomAccessFile randomAccessFile = null;
+		try {
+			randomAccessFile = new RandomAccessFile(path + File.separator +tempFileName,"rw");
+			randomAccessFile.setLength(_conn.getContentLength());
+		} catch (FileNotFoundException e1) {
+			e1.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+		return randomAccessFile;
+	}
+	
+	private boolean ChangeFileName(File _f,Connection _conn) {
+		String fileName = _conn.getURL().getFile().substring(url.lastIndexOf("/"));
+		return _f.renameTo(new File(_f.getAbsolutePath()+File.separator+fileName));
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	public String getLocalPath() {
+		return localPath;
+	}
+
+	public void setLocalPath(String localPath) {
+		this.localPath = localPath;
+	}
+	
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..be1fbff668
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,58 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url = "https://static.oschina.net/uploads/img/201701/09170848_HsPK.jpg";
+		
+		FileDownloader downloader = new FileDownloader(url);
+		downloader.setLocalPath("E:/temp_backup/temp");
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..cd390c9296
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/Connection.java
@@ -0,0 +1,29 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+import java.net.URL;
+
+public interface Connection {
+
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public int read(byte data[]) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+	
+	public URL getURL();
+	public int getStartPos();
+	public int getEndPos();
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..f4f05269df
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+	private static final long serialVersionUID = 4776347926322882920L;
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..0b3167cd90
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,11 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url,int startPos ,int endPos) throws ConnectionException;	
+	public Connection open(String url)  throws ConnectionException;
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..4cd0b3eab1
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..4d6fbc4b87
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,87 @@
+package com.coderising.download.impl;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+	
+	private URLConnection uc = null;
+	private BufferedInputStream bs = null;
+	private URL url;
+	int startPos;
+	int endPos;
+	public ConnectionImpl(String path,int _startPos,int _endPos) throws Exception {
+		try {
+			if (startPos >= _endPos || _startPos < 0) {
+				throw new IllegalArgumentException();
+			}
+			this.startPos = _startPos;
+			this.endPos = _endPos;
+			url = new URL(path);
+			uc = url.openConnection();
+			uc.setRequestProperty("Range", "bytes=" + _startPos + "-" + _endPos);
+			bs = new BufferedInputStream(uc.getInputStream());
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+			throw e;
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+	public ConnectionImpl(String path) throws Exception {
+		try {
+			
+			url = new URL(path);
+			uc = url.openConnection();
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+			throw e;
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+	
+	public int read(byte data[])  {
+		int ret = 0;
+		try {
+			ret  = bs.read(data);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}	
+		return ret;
+	}
+
+	public int getContentLength() {
+		return uc.getContentLength();
+	}
+	
+	public URL getURL() {
+		return url;
+	}
+	
+	public void close() {
+		try {
+			if (null != bs) {
+				bs.close();
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+	}
+
+	public int getStartPos() {
+		return this.startPos;
+	}
+	public int getEndPos() {
+		return this.endPos;
+	}
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..68a5b7a7fc
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,42 @@
+package com.coderising.download.impl;
+
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	public Connection open(String url,int startPos ,int endPos) throws ConnectionException {
+		if (null == url || "".equals(url)) {
+			throw new IllegalArgumentException("参数异常");
+		}
+		
+		Connection conn = null;
+		try {
+			conn = new ConnectionImpl(url,startPos,endPos);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new ConnectionException();
+		}
+		
+		return conn;
+	}
+	
+	public Connection open(String url) throws ConnectionException {
+		if (null == url || "".equals(url)) {
+			throw new IllegalArgumentException("参数异常");
+		}
+		
+		Connection conn = null;
+		try {
+			conn = new ConnectionImpl(url);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new ConnectionException();
+		}
+		
+		return conn;
+	}
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java
index c168b5efa8..ee70db2150 100644
--- a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/ArrayList.java
@@ -1,119 +1,122 @@
-package com.coding.basic;
-
-/** 
- * @ClassName: ArrayList 
- * @Description: 自增长数组
- * @author: tangxp
- * @date: 2017年2月23日 下午10:43:03  
- */
-public class ArrayList implements List {
-	
-	private final int  step = 10;
-	private Object elementData[] = new Object[100];
-	private int size = 0 ;
-	
-	
-	/**
-	 * @Title: add
-	 * @Description: TODO
-	 * @param o , elements of this ArrayList
-	 * @see com.coding.basic.List#add(java.lang.Object) 
-	 */
-	public void add(Object o) {
-		add(size,o);
-	}
-
-	
-	/**
-	 * @Title: add
-	 * @Description: TODO
-	 * @param index
-	 * @param o 
-	 * @see com.coding.basic.List#add(int, java.lang.Object) 
-	 */
-	public void add(int index, Object o) {
-		if(index < 0 || index> size) {
-			throw new IllegalArgumentException("下标越界");
-		}
-		
-		if(null == o) {
-			throw new IllegalArgumentException("元素不能为空");
-		}
-		
-		if(this.checkOutOfBounds()) {
-			this.autoGrow(this.step);
-		}
-		
-		int i = size;
-		while(i>index) {
-			elementData[i] = elementData[--i];
-		}
-		addDriect(i,  o);
-	}
-
-	
-	public Object get(int index) {
-		if(index < 0 || index>= size) {
-			throw new IllegalArgumentException("下标越界");
-		}
-		
-		return elementData[index];
-	}
-
-	public Object remove(int index) {
-		if(index < 0 || index>= size) {
-			throw new IllegalArgumentException("下标越界");
-		}
-		
-		Object o = elementData[index];
-		while (index<size-1) {
-			elementData[index] = elementData[++index];
-		}
-		elementData[size] = null;
-		this.size--;
-		return o;
-	}
-
-	public int size() {
-		return this.size;
-	}
-	
-	
-	/**
-	 * @param growSize
-	 * 扩展elementData数组growSize大小
-	 */
-	private void autoGrow(int growSize) {
-		if (elementData.length>this.size) {
-			return;
-		}
-		Object newElementData[] = new Object[elementData.length+growSize];
-		System.arraycopy(elementData, 0, newElementData, 0, elementData.length);
-		elementData = newElementData;
-		return;
-	}
-	
-	private void addDriect(int index, Object o) {
-		elementData[index] = o;
-		this.size++;
-	}
-	
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder("[");
-		for(int i =0;i<this.size;i++) {
-			sb.append(elementData[i].toString());
-			sb.append(","); 
-		}
-		sb.replace(sb.length()-1, sb.length(), "]");
-		return sb.toString();
-	}
-	
-	private boolean checkOutOfBounds()  {
-		if (elementData.length>this.size) {
-			return false;
-		}else {
-			return true;
-		}
-	}
-}
+package com.coding.basic;
+
+import java.util.concurrent.CyclicBarrier;
+
+/** 
+ * @ClassName: ArrayList 
+ * @Description: 自增长数组
+ * @author: tangxp
+ * @date: 2017年2月23日 下午10:43:03  
+ */
+public class ArrayList implements List {
+	
+	private final int  step = 10;
+	private Object elementData[] = new Object[100];
+	private int size = 0 ;
+	
+	
+	/**
+	 * @Title: add
+	 * @Description: TODO
+	 * @param o , elements of this ArrayList
+	 * @see com.coding.basic.List#add(java.lang.Object) 
+	 */
+	public void add(Object o) {
+		add(size,o);
+	}
+
+	
+	/**
+	 * @Title: add
+	 * @Description: TODO
+	 * @param index
+	 * @param o 
+	 * @see com.coding.basic.List#add(int, java.lang.Object) 
+	 */
+	public void add(int index, Object o) {
+		if(index < 0 || index> size) {
+			throw new IllegalArgumentException("下标越界");
+		}
+		
+		if(null == o) {
+			throw new IllegalArgumentException("元素不能为空");
+		}
+		
+		if(this.checkOutOfBounds()) {
+			this.autoGrow(this.step);
+		}
+		
+		int i = size;
+		while(i>index) {
+			elementData[i] = elementData[--i];
+		}
+		addDriect(i,  o);
+	}
+
+	
+	public Object get(int index) {
+		if(index < 0 || index>= size) {
+			throw new IllegalArgumentException("下标越界");
+		}
+		
+		return elementData[index];
+	}
+
+	public Object remove(int index) {
+		if(index < 0 || index>= size) {
+			throw new IllegalArgumentException("下标越界");
+		}
+		
+		Object o = elementData[index];
+		while (index<size-1) {
+			elementData[index] = elementData[++index];
+		}
+		elementData[size] = null;
+		this.size--;
+		return o;
+	}
+
+	public int size() {
+		return this.size;
+	}
+	
+	
+	/**
+	 * @param growSize
+	 * 扩展elementData数组growSize大小
+	 */
+	private void autoGrow(int growSize) {
+		if (elementData.length>this.size) {
+			return;
+		}
+		Object newElementData[] = new Object[elementData.length+growSize];
+		System.arraycopy(elementData, 0, newElementData, 0, elementData.length);
+		elementData = newElementData;
+		return;
+	}
+	
+	private void addDriect(int index, Object o) {
+		elementData[index] = o;
+		this.size++;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder("[");
+		for(int i =0;i<this.size;i++) {
+			sb.append(elementData[i].toString());
+			sb.append(","); 
+		}
+		sb.replace(sb.length()-1, sb.length(), "]");
+		return sb.toString();
+	}
+	
+	private boolean checkOutOfBounds()  {
+		if (elementData.length>this.size) {
+			return false;
+		}else {
+			return true;
+		}
+	}
+	
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java
index a824ad9372..cad618d536 100644
--- a/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java
+++ b/group04/821655640/learning_projects/project_basic_001/src/main/java/com/coding/basic/LinkedList.java
@@ -1,134 +1,349 @@
-package com.coding.basic;
-
-
-/** 
- * @ClassName: LinkedList 
- * @Description: 带头结点的单向列表.
- * @author: tangxp
- * @date: 2017年2月23日 下午9:14:28  
- */
-public class LinkedList implements List {
-	
-	private Node head = new Node();
-	private int size ;
-	
-	public void add(Object o){
-		add(size,o);
-	}
-	
-	public void add(int index , Object o){
-		if(index<0 || index>size) {
-			throw new IllegalArgumentException("目前链表长度不够!");
-		}
-		Node tempHead = head;
-		int i = 0;
-		while(i++ < index) {
-			tempHead = tempHead.next;
-		}
-		addDriect(getNode(o),tempHead);
-	}
-
-
-	/**
-	 * @Title: get	
-	 * @Description: TODO
-	 * @param index
-	 * @return 
-	 * @see com.coding.basic.List#get(int) 
-	 */
-	public Object get(int index){
-		if(index<0|| index>=size) {
-			throw new IllegalArgumentException("下标超出链表范围!");
-		}
-		Node tempHead = head;
-		int i = 0;
-		while(i++ < index) {
-			tempHead = tempHead.next;
-		}
-		return tempHead.next.data;
-	}
-	
-	public Object remove(int index){
-		if(index<0  || index>=size) {
-			throw new IllegalArgumentException("下标超出链表范围!");
-		}
-		Node tempHead = head;
-		int i = 0;
-		while(i++ < index) {
-			tempHead = tempHead.next;
-		}
-		
-		Node removingNode = tempHead.next;
-		tempHead.next = removingNode.next;
-		removingNode.next = null;
-		size--;
-		return removingNode.data;
-	}
-	
-	public int size(){
-		return size;
-	}
-	
-	public void addFirst(Object o){
-		add(0,o);
-	}
-	public void addLast(Object o){
-		add(o);
-	}
-	public Object removeFirst(){
-		return remove(0);
-	}
-	
-	public Object removeLast(){
-		return remove(size-1);
-	}
-	
-	public Iterator iterator(){
-		return null;
-	}
-	
-	private void addDriect(Node n,Node before) {
-		Node temp =  before.next;
-		n.next = temp;
-		before.next = n;
-		size++;
-	}
-	
-	private Node getNode(Object o) {
-		
-		if(null == o) {
-			throw new IllegalArgumentException("节点值不能为空");
-		}
-		
-		Node  n = new Node();
-		n.data = o;
-		return n;
-	}
-	
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder("size: "+size+" {null | ---}--->");
-		if(null == head.next) {
-			return sb.toString();
-		}
-		
-		Node tempHead = head;
-		while(null != tempHead.next ) {
-			sb.append(tempHead.next.toString());
-			tempHead = tempHead.next;
-		}
-		sb.append("null");
-		return sb.toString();
-	}
-	
-	private static  class Node{
-		Object data;
-		Node next;
-		
-		@Override
-		public String toString() {
-			return "{" + this.data +"  |---}--->";
-		}
-		
-	}
-}
+package com.coding.basic;
+
+import java.util.concurrent.CyclicBarrier;
+
+
+/** 
+ * @ClassName: LinkedList 
+ * @Description: 带头结点的单向列表.
+ * @author: tangxp
+ * @date: 2017年2月23日 下午9:14:28  
+ */
+public class LinkedList implements List {
+	
+	private Node head = new Node();
+	private int size ;
+	
+	public void add(Object o){
+		add(size,o);
+	}
+	
+	public void add(int index , Object o){
+		if(index<0 || index>size) {
+			throw new IllegalArgumentException("目前链表长度不够!");
+		}
+		Node tempHead = head;
+		int i = 0;
+		while(i++ < index) {
+			tempHead = tempHead.next;
+		}
+		addDriect(getNode(o),tempHead);
+	}
+
+
+	/**
+	 * @Title: get	
+	 * @Description: TODO
+	 * @param index
+	 * @return 
+	 * @see com.coding.basic.List#get(int) 
+	 */
+	public Object get(int index){
+		if(index<0|| index>=size) {
+			throw new IllegalArgumentException("下标超出链表范围!");
+		}
+		Node tempHead = head;
+		int i = 0;
+		while(i++ < index) {
+			tempHead = tempHead.next;
+		}
+		return tempHead.next.data;
+	}
+	
+	public Object remove(int index){
+		if(index<0  || index>=size) {
+			throw new IllegalArgumentException("下标超出链表范围!");
+		}
+		Node tempHead = head;
+		int i = 0;
+		while(i++ < index) {
+			tempHead = tempHead.next;
+		}
+		
+		Node removingNode = tempHead.next;
+		tempHead.next = removingNode.next;
+		removingNode.next = null;
+		size--;
+		return removingNode.data;
+	}
+	
+	public int size(){
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		add(0,o);
+	}
+	public void addLast(Object o){
+		add(o);
+	}
+	public Object removeFirst(){
+		return remove(0);
+	}
+	
+	public Object removeLast(){
+		return remove(size-1);
+	}
+	
+	public Iterator iterator(){
+		return null;
+	}
+	
+	private void addDriect(Node n,Node before) {
+		Node temp =  before.next;
+		n.next = temp;
+		before.next = n;
+		size++;
+	}
+	
+	private Node getNode(Object o) {
+		
+		if(null == o) {
+			throw new IllegalArgumentException("节点值不能为空");
+		}
+		
+		Node  n = new Node();
+		n.data = o;
+		return n;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder("size: "+size+" {null | ---}--->");
+		if(null == head.next) {
+			return sb.toString();
+		}
+		
+		Node tempHead = head;
+		while(null != tempHead.next ) {
+			sb.append(tempHead.next.toString());
+			tempHead = tempHead.next;
+		}
+		sb.append("null");
+		return sb.toString();
+	}
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+		@Override
+		public String toString() {
+			return "{" + this.data +"  |---}--->";
+		}
+	}
+	
+
+	//数据结构习题
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  boolean reverse(){
+		if (this.size()<=0) {
+			return false;
+		}
+		Stack stack = new Stack();
+		
+		while(this.size()>0) {
+			stack.push(this.removeFirst());
+		}
+		
+		while(stack.size()>0) {
+			this.addLast(stack.pop());
+		}
+		
+		return true;
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  boolean removeFirstHalf(){
+		if (this.size()<=0) {
+			return false;
+		}
+		//计算中间位置
+		int tempCount =  this.size();
+		tempCount = tempCount%2 == 0 ? tempCount/2 : (tempCount-1)/2;
+		tempCount--;
+		while(tempCount >= 0) {
+			this.removeFirst();
+			tempCount --;
+		}
+		return true;
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		if(i<0|| i>=size) {
+			throw new IllegalArgumentException("下标超出链表范围!");
+		}
+		if (!(length>0|| (i+1+length)<=this.size())) {
+			throw new IllegalArgumentException("参数非法!");
+		}
+		
+		Node tempHead = head;
+		head = getNode(i-1);
+		while(length-->0){
+			this.removeFirst();
+		}
+		head = tempHead;
+	}
+	
+	/**
+	 * 获取第i个元素的引用
+	 */
+	public Node getNode(int index) {
+		if(index<0|| index>=size) {
+			throw new IllegalArgumentException("下标超出链表范围!");
+		}
+		Node tempHead = head;
+		int i = 0;
+		while(i++ < index) {
+			tempHead = tempHead.next;
+		}
+		
+		return tempHead.next;
+	}
+	
+	
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  Integer[] getElements(LinkedList list){
+		int listSizeB = list.size();
+		int i=0;
+		Integer res[] = new Integer[listSizeB];
+		while(listSizeB-- > 0) {
+			res[i] = (Integer) this.get((Integer)list.get(i));
+			i++;
+		}
+		return res;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		Node tempNodePre = this.head;
+		Node tempNode = this.head.next;
+		Node tempNodeB = list.head.next;
+		Node temp = null;
+		while(null != tempNode && null != tempNodeB) {
+			Integer a = (Integer) tempNode.data;
+			Integer b = (Integer) tempNodeB.data;
+			if (a < b) {
+				tempNodePre = tempNodePre.next;
+				tempNode = tempNode.next;
+			} else if(a > b){
+				tempNodeB = tempNodeB.next;
+			}else {
+				temp = tempNode;
+				tempNodePre.next = tempNode.next;
+				tempNode = tempNode.next;
+				temp.next = null;
+				temp = null;
+			}
+		}
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		Node tempPre = this.head;
+		Node tempCur = this.head.next;
+		Node temp = null;
+		while(null != tempCur) {
+			Integer a = (Integer) tempPre.data;
+			Integer b = (Integer) tempCur.data;
+			if(a == b) {
+				temp = tempCur;
+				tempPre.next = tempCur.next;
+				tempCur = tempCur.next;
+				temp.next = null;
+				temp = null;
+			}else {
+				tempPre = tempPre.next;
+				tempCur = tempCur.next;
+			}
+		}
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		if (min<0 || max<min || this.size()<2) {
+			throw new IllegalArgumentException();
+		}
+		
+		Node pre = this.head.next;
+		Node cur = this.head.next.next;
+		Node preMin = null;
+		Node preMax = null;
+		while(null != cur) {
+
+			Integer a = (Integer) pre.data;
+			Integer b = (Integer) cur.data;
+			
+			if (a<min && b>=min) {
+				preMin = pre;
+			}
+			if (a<=max && b>max) {
+				preMax = pre;
+			}
+			pre = pre.next;
+			cur = cur.next;
+		}
+		preMin.next = preMax.next;
+		preMax = null;
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList listB){
+		Node nodeA = this.head.next;
+		Node nodeB = listB.head.next;
+		LinkedList listC = new LinkedList();
+		while (null != nodeA && null != nodeB) {
+			Integer a = (Integer) nodeA.data;
+			Integer b = (Integer) nodeB.data;
+			if (a>b) {
+				nodeB = nodeB.next;
+			} else if(a<b){
+				nodeA = nodeA.next;
+			}else {
+				listC.add(nodeA.data);
+				nodeA = nodeA.next;
+				nodeB = nodeB.next;
+			}
+		}
+		return listC;
+	}
+	
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coding/basic/TestLinkedList.java b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coding/basic/TestLinkedList.java
new file mode 100644
index 0000000000..ce4446b6b6
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/coding/basic/TestLinkedList.java
@@ -0,0 +1,110 @@
+package com.coding.basic;
+
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class TestLinkedList {
+
+	@Test
+	public void testReverse() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<10;i++) {
+			link.add(i);
+		}
+		System.out.println(link);
+		link.reverse();
+		System.out.println(link);
+	}
+	
+	@Test
+	public void testRemoveFirstHalf() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i);
+		}
+		System.out.println(link);
+		link.removeFirstHalf();
+		System.out.println(link);
+	}
+	
+	@Test
+	public void testRemove() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i);
+		}
+		System.out.println(link);
+		link.remove(2,3);
+		System.out.println(link);
+	}
+	
+	@Test
+	public void testGetElements() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i+ new java.util.Random().nextInt(10));
+		}
+		LinkedList linkB = new LinkedList();
+		linkB.add(2);
+		linkB.add(4);
+		linkB.add(6);
+		System.out.println(link);
+		Integer printArray[] = link.getElements(linkB);
+		System.out.println(Arrays.toString(printArray));
+	}
+	
+	@Test
+	public void testSubtract() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i);
+		}
+		LinkedList linkB = new LinkedList();
+		linkB.add(2);
+		linkB.add(4);
+		linkB.add(6);
+		System.out.println(link);
+		link.subtract(linkB);
+		System.out.println(link);
+	}
+	
+	@Test
+	public void testRemoveDuplicateValues() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i);
+			link.add(i);
+		}
+		System.out.println(link);
+		link.removeDuplicateValues();
+		System.out.println(link);
+	}
+	@Test
+	public void testRemoveRange() {
+		LinkedList link = new LinkedList();
+		for(int i=0;i<9;i++) {
+			link.add(i);
+		}
+		System.out.println(link);
+		link.removeRange(2, 5);
+		System.out.println(link);
+	}
+	@Test
+	public void testIntersection() {
+		LinkedList link = new LinkedList();
+		for(int i=3;i<9;i++) {
+			link.add(i);
+		}
+		LinkedList linkB = new LinkedList();
+		for(int i=0;i<7;i++) {
+			linkB.add(i);
+		}
+		
+		System.out.println(link);
+		System.out.println(linkB);
+		System.out.println(link.intersection(linkB));
+	}
+
+}
diff --git a/group04/821655640/learning_projects/project_basic_001/src/test/java/com/txp/temp/Test.java b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/txp/temp/Test.java
new file mode 100644
index 0000000000..1f41927e18
--- /dev/null
+++ b/group04/821655640/learning_projects/project_basic_001/src/test/java/com/txp/temp/Test.java
@@ -0,0 +1,9 @@
+package com.txp.temp;
+
+public class Test {
+	private int m;
+
+	public int inc() {
+		return m + 1;
+	}
+}
\ No newline at end of file
diff --git a/group04/844028312/four/linklist/LRUPageFrame.java b/group04/844028312/four/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..0d305f7b06
--- /dev/null
+++ b/group04/844028312/four/linklist/LRUPageFrame.java
@@ -0,0 +1,127 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(Node prev,Node next,int pageNum) {
+			this.prev=prev;
+			this.next=next;
+			this.pageNum=pageNum;
+		}
+	}
+
+	private int capacity;
+	
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		if(this.first==null){
+			first=new Node(null,null,pageNum);
+			return ;
+		}
+		else{
+			 if(last==null){
+				if(!moveToFirst(pageNum)){ 
+					Node nf=new Node(null,this.first,pageNum);
+					this.first.prev=nf;
+					this.first=nf;
+					//判断是否为最后一个
+					Node cur=this.first;
+					int i=1;
+					while(cur!=null){
+						cur=cur.next;
+						i++;
+						if(i==this.capacity){
+							this.last=cur;
+							break;
+						}
+					}
+				}
+			}
+			else{
+				if(!moveToFirst(pageNum)){
+					Node nf=new Node(null,this.first,pageNum);
+					this.first.prev=nf;
+					this.first=nf;
+					this.last.prev.next=null;
+					this.last=this.last.prev;
+				}
+			}
+		}
+	
+	}
+	public boolean moveToFirst(int pageNum){
+		Node indexOf=indexOf(pageNum);
+		if(indexOf!=null){
+			if(indexOf==this.first){
+				return true;
+			}
+			else if(indexOf==this.last){
+				this.first.prev=indexOf;
+				this.last=indexOf.prev;
+				this.last.next=null;
+				indexOf.next=this.first;
+				this.first=indexOf;
+			}
+			else{
+				indexOf.next.prev=indexOf.prev;  
+				indexOf.prev.next=indexOf.next;
+				this.first.prev=indexOf;
+				indexOf.prev=null;
+				indexOf.next=this.first;
+				this.first=indexOf;
+			}
+			return true;
+		}
+		return false;
+	}
+	public Node indexOf(int pageNum){
+		Node cur=this.first;
+		while(cur!=null){
+			if(cur.pageNum==pageNum){
+				return cur;
+			}
+			cur=cur.next;
+		}
+		return null;
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);	
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group04/844028312/four/linklist/LRUPageFrameTest.java b/group04/844028312/four/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..67cf36067b
--- /dev/null
+++ b/group04/844028312/four/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package com.coding.basic.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group04/844028312/four/linklist/LinkedList.java b/group04/844028312/four/linklist/LinkedList.java
new file mode 100644
index 0000000000..f4c7556a2e
--- /dev/null
+++ b/group04/844028312/four/linklist/LinkedList.java
@@ -0,0 +1,125 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+public class LinkedList implements List {
+	
+	private Node head;
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index , Object o){
+		
+	}
+	public Object get(int index){
+		return null;
+	}
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public void addFirst(Object o){
+		
+	}
+	public void addLast(Object o){
+		
+	}
+	public Object removeFirst(){
+		return null;
+	}
+	public Object removeLast(){
+		return null;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){		
+		
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		return null;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		return null;
+	}
+}
diff --git a/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..d2bed45b48
--- /dev/null
+++ b/group04/844028312/four/min-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+import javax.annotation.Resources;
+
+
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className)  {
+		InputStream ips = null;
+		ByteArrayOutputStream bao = null;
+		try {
+			String name=className.replace(".", "\\")+".class";
+			for(int i=0;i<clzPaths.size();i++){
+				String path=clzPaths.get(i)+"\\"+name;
+				File file =new File(path);
+				if(file.exists()){
+					ips=new FileInputStream(file);
+					byte[] b=new byte[1024];
+					bao=new ByteArrayOutputStream();
+					while(ips.read(b, 0, b.length)!=-1){
+						bao.write(b);
+					}
+					return bao.toByteArray();
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}finally{
+			if(ips!=null){
+				try {
+					ips.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			if(bao!=null){
+				try {
+					bao.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		return null;	
+		
+		
+	}
+	
+	
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+	
+	
+	
+	public String getClassPath(){
+		StringBuffer sb=new StringBuffer();
+		for(int i=0;i<clzPaths.size();i++){
+			if(i==clzPaths.size()-1){
+				sb.append(clzPaths.get(i));
+			}
+			else
+			  sb.append(clzPaths.get(i)+";");
+		}
+		return sb.toString();
+	}
+
+	
+
+	
+
+}
diff --git a/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..6c617b54ce
--- /dev/null
+++ b/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "F:\\workspace\\min-jvm\\bin";
+	static String path2 = "C:\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		int i=byteCodes.length;
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(2048, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/EmployeeV1.java b/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group04/844028312/four/min-jvm/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group04/349184132/Study/.classpath b/group04/844028312/three/.classpath
similarity index 56%
rename from group04/349184132/Study/.classpath
rename to group04/844028312/three/.classpath
index 2a9fa78d5e..3e0fb272a8 100644
--- a/group04/349184132/Study/.classpath
+++ b/group04/844028312/three/.classpath
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="lib" path="E:/javalab/dom4j/dom4j-1.6.1/dom4j-1.6.1.jar" sourcepath="E:/javalab/dom4j/dom4j-1.6.1/dom4j-1.6.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/group04/844028312/three/.gitignore b/group04/844028312/three/.gitignore
new file mode 100644
index 0000000000..ae3c172604
--- /dev/null
+++ b/group04/844028312/three/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/group04/844028312/three/.project b/group04/844028312/three/.project
new file mode 100644
index 0000000000..64a356de63
--- /dev/null
+++ b/group04/844028312/three/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>coding2017</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs b/group04/844028312/three/.settings/org.eclipse.jdt.core.prefs
similarity index 78%
rename from group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs
rename to group04/844028312/three/.settings/org.eclipse.jdt.core.prefs
index a698e59674..d17b6724d1 100644
--- a/group04/349184132/Study/.settings/org.eclipse.jdt.core.prefs
+++ b/group04/844028312/three/.settings/org.eclipse.jdt.core.prefs
@@ -1,12 +1,12 @@
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.compliance=1.7
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/group04/844028312/three/src/com/coderising/array/ArrayUtil.java b/group04/844028312/three/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..e5ddb476a6
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coderising.array;
+
+public class ArrayUtil {
+	
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换
+		例如： a = [7, 9 , 30, 3]  ,   置换后为 [3, 30, 9,7]
+		如果     a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * @param origin
+	 * @return
+	 */
+	public void reverseArray(int[] origin){
+		
+	}
+	
+	/**
+	 * 现在有如下的一个数组：   int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}   
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为：   
+	 * {1,3,4,5,6,6,5,4,7,6,7,5}  
+	 * @param oldArray
+	 * @return
+	 */
+	
+	public int[] removeZero(int[] oldArray){
+		return null;
+	}
+	
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 ,  创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的
+	 * 例如 a1 = [3, 5, 7,8]   a2 = [4, 5, 6,7]    则 a3 为[3,4,5,6,7,8]    , 注意： 已经消除了重复
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+	
+	public int[] merge(int[] array1, int[] array2){
+		return  null;
+	}
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持
+	 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public int[] grow(int [] oldArray,  int size){
+		return null;
+	}
+	
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21......  ，给定一个最大值， 返回小于该值的数列
+	 * 例如， max = 15 , 则返回的数组应该为 [1，1，2，3，5，8，13]
+	 * max = 1, 则返回空数组 []
+	 * @param max
+	 * @return
+	 */
+	public int[] fibonacci(int max){
+		return null;
+	}
+	
+	/**
+	 * 返回小于给定最大值max的所有素数数组
+	 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * @param max
+	 * @return
+	 */
+	public int[] getPrimes(int max){
+		return null;
+	}
+	
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+	 * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * @param max
+	 * @return
+	 */
+	public int[] getPerfectNumbers(int max){
+		return null;
+	}
+	
+	/**
+	 * 用seperator 把数组 array给连接起来
+	 * 例如array= [3,8,9], seperator = "-"
+	 * 则返回值为"3-8-9"
+	 * @param array
+	 * @param s
+	 * @return
+	 */
+	public String join(int[] array, String seperator){
+		return null;
+	}
+	
+
+}
diff --git a/group04/844028312/three/src/com/coderising/download/DownloadThread.java b/group04/844028312/three/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..580da85576
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,48 @@
+package com.coderising.download;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+	CyclicBarrier barrier;
+	String url;
+	public DownloadThread(CyclicBarrier barrier, String url, int startPos, int endPos){
+		this.barrier=barrier;
+		//this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+		this.url=url;
+	}
+	public void run(){	
+		try {
+			ConnectionManager cm = new ConnectionManagerImpl();
+			conn=cm.open(url);
+			
+			byte[] b=conn.read(startPos, endPos);
+			
+			RandomAccessFile randomFile = new RandomAccessFile("D://test.zip", "rw");
+			write(randomFile,b);
+			barrier.await();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	public  synchronized void write(RandomAccessFile randomFile ,byte[] b) throws IOException{
+		randomFile.seek(startPos);
+		randomFile.write(b);
+		randomFile.close();
+	}
+}
diff --git a/group04/844028312/three/src/com/coderising/download/FileDownloader.java b/group04/844028312/three/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..9d81ef03be
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,86 @@
+package com.coderising.download;
+
+import java.util.concurrent.CyclicBarrier;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+	
+	String url;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+	
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			
+			
+			CyclicBarrier cb = new CyclicBarrier(4, new Runnable() {
+					@Override
+					public void run() {
+						// TODO Auto-generated method stub
+						listener.notifyFinished();
+           
+					} 
+			});
+			conn=cm.open(url);
+			int length = conn.getContentLength();	
+			new DownloadThread(cb,url,0,length/4).start();
+			new DownloadThread(cb,url,length/4+1,(length/4)*2).start();
+			new DownloadThread(cb,url,(length/4)*2+1,(length/4)*3).start();
+			new DownloadThread(cb,url,(length/4)*3+1,length-1).start();
+		
+				
+		} catch (Exception e) {			
+			e.printStackTrace();
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+		
+		
+		
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
diff --git a/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java b/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..b1cc492c33
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,115 @@
+package com.coderising.download;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	  private static Integer pages=1; // 网页数
+	     
+	    private static boolean exeFlag=true; // 执行标识
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url="http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.0.41/bin/apache-tomcat-8.0.41-windows-x64.zip";
+		FileDownloader downloader = new FileDownloader(url);
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				//Thread.sleep(5000);
+			} catch (Exception e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+	
+	//http://image.so.com/v?ie=utf-8&src=hao_360so&q=%E9%AB%98%E5%9C%86%E5%9C%86&correct=%E9%AB%98%E5%9C%86%E5%9C%86&fromurl=http%3A%2F%2Fwww.cesiu.org.cn%2Fomdsj%2F2010674.html&gsrc=1#multiple=0&dataindex=57&id=537876d111c8adfec7fbda2b80a4f67b
+	@Test
+	public void testOpen() throws ConnectionException {
+
+	  
+	     
+		ExecutorService executorService=Executors.newFixedThreadPool(10); // 创建ExecutorService 连接池创建固定的10个初始线程
+        
+        while(exeFlag){
+            if(pages<=100){
+//                executorService.execute(new Runnable(){
+// 
+//                    @Override
+//                    public void run() {
+//                        // TODO Auto-generated method stub
+//                    	System.out.println(Thread.currentThread().getName());
+//                      System.out.println("爬取了第"+pages+"网页...");
+//                        pages++;
+//                    }
+//                     
+//                });
+                new Runnable(){
+                	 
+                    @Override
+                    public void run() {
+                        // TODO Auto-generated method stub
+                    	System.out.println(Thread.currentThread().getName());
+                      System.out.println("爬取了第"+pages+"网页...");
+                        pages++;
+                    }
+                     
+                }.run();;
+               
+            }else{
+                if(((ThreadPoolExecutor)executorService).getActiveCount()==0){ // 活动线程是0
+                    executorService.shutdown(); // 结束所有线程
+                    exeFlag=false;
+                    System.out.println("爬虫任务已经完成");
+                }
+            }
+            try {
+              // Thread.sleep(2000); // 线程休息0.1秒
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            
+        }
+       
+	}
+}
diff --git a/group04/844028312/three/src/com/coderising/download/api/Connection.java b/group04/844028312/three/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/844028312/three/src/com/coderising/download/api/ConnectionException.java b/group04/844028312/three/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..c3ed7396e7
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+	
+}
diff --git a/group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java b/group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/844028312/three/src/com/coderising/download/api/DownloadListener.java b/group04/844028312/three/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java b/group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..4849434761
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,54 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.Arrays;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+	HttpURLConnection urlConnection;
+	
+	
+
+	public HttpURLConnection getUrlConnection() {
+		return urlConnection;
+	}
+
+	public void setUrlConnection(HttpURLConnection urlConnection) {
+		this.urlConnection = urlConnection;
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		byte[] buffer = new byte[endPos-startPos+1];
+		int count=0;
+		urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+		InputStream ips=urlConnection.getInputStream();
+		//ips.skip(startPos);
+		while(count<buffer.length-1){
+			int len=ips.read(buffer, count, endPos-startPos-count);
+			if(len==-1){
+				break;
+			}
+			count=count+len;
+		}
+		return buffer;
+
+	}
+
+	@Override
+	public int getContentLength() {
+		
+		return urlConnection.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		urlConnection.disconnect();
+		
+	}
+
+}
diff --git a/group04/844028312/three/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group04/844028312/three/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..4e282c1bc2
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,33 @@
+package com.coderising.download.impl;
+
+
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		HttpURLConnection urlConnection;
+		ConnectionImpl conImpl=new ConnectionImpl();
+			try {
+				URL u=new URL(url);
+				urlConnection=(HttpURLConnection) u.openConnection();
+				conImpl.setUrlConnection(urlConnection);
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+		
+		
+		return conImpl;
+	}
+
+}
diff --git a/group04/844028312/three/src/com/coderising/litestruts/LoginAction.java b/group04/844028312/three/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group04/844028312/three/src/com/coderising/litestruts/Struts.java b/group04/844028312/three/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..6df190d484
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/litestruts/Struts.java
@@ -0,0 +1,37 @@
+package com.coderising.litestruts;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+
+
+public class Struts {
+
+	
+    public static View runAction(String actionName, Map<String,String> parameters) {
+
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+    	
+    
+    	return null;
+    }    
+
+}
diff --git a/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+		
+		String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group04/844028312/three/src/com/coderising/litestruts/View.java b/group04/844028312/three/src/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..07df2a5dab
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+	
+	public String getJsp() {
+		return jsp;
+	}
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+	public Map getParameters() {
+		return parameters;
+	}
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group04/844028312/three/src/com/coderising/litestruts/struts.xml b/group04/844028312/three/src/com/coderising/litestruts/struts.xml
new file mode 100644
index 0000000000..e5d9aebba8
--- /dev/null
+++ b/group04/844028312/three/src/com/coderising/litestruts/struts.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<struts>
+    <action name="login" class="com.coderising.litestruts.LoginAction">
+        <result name="success">/jsp/homepage.jsp</result>
+        <result name="fail">/jsp/showLogin.jsp</result>
+    </action>
+    <action name="logout" class="com.coderising.litestruts.LogoutAction">
+    	<result name="success">/jsp/welcome.jsp</result>
+    	<result name="error">/jsp/error.jsp</result>
+    </action>
+</struts>
\ No newline at end of file
diff --git a/group04/844028312/three/src/com/coding/basic/ArrayList.java b/group04/844028312/three/src/com/coding/basic/ArrayList.java
new file mode 100644
index 0000000000..1f185736f9
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/ArrayList.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class ArrayList implements List {
+	
+	private int size = 0;
+	
+	private Object[] elementData = new Object[100];
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index, Object o){
+		
+	}
+	
+	public Object get(int index){
+		return null;
+	}
+	
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public Iterator iterator(){
+		return null;
+	}
+	
+}
diff --git a/group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java b/group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java
new file mode 100644
index 0000000000..d7ac820192
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/BinaryTreeNode.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class BinaryTreeNode {
+	
+	private Object data;
+	private BinaryTreeNode left;
+	private BinaryTreeNode right;
+	
+	public Object getData() {
+		return data;
+	}
+	public void setData(Object data) {
+		this.data = data;
+	}
+	public BinaryTreeNode getLeft() {
+		return left;
+	}
+	public void setLeft(BinaryTreeNode left) {
+		this.left = left;
+	}
+	public BinaryTreeNode getRight() {
+		return right;
+	}
+	public void setRight(BinaryTreeNode right) {
+		this.right = right;
+	}
+	
+	public BinaryTreeNode insert(Object o){
+		return  null;
+	}
+	
+}
diff --git a/group12/446031103/src/com/coding/basic/Iterator.java b/group04/844028312/three/src/com/coding/basic/Iterator.java
similarity index 100%
rename from group12/446031103/src/com/coding/basic/Iterator.java
rename to group04/844028312/three/src/com/coding/basic/Iterator.java
diff --git a/group04/844028312/three/src/com/coding/basic/LinkedList.java b/group04/844028312/three/src/com/coding/basic/LinkedList.java
new file mode 100644
index 0000000000..df43a6dec7
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/LinkedList.java
@@ -0,0 +1,417 @@
+package com.coding.basic;
+
+import java.util.Arrays;
+
+public class LinkedList implements List {
+	
+	private Node head;
+	private Node last;
+	private int size=0;
+	public void add(Object o){
+		if(head==null){
+			head =new Node();
+			head.data=o;
+			last=head;
+		}
+		else{
+			Node temp=new Node();
+			temp.data=o;
+			last.next=temp;
+			last=temp;
+		}
+		size++;
+	}
+	public boolean enCapacity(int index){
+		if(index>=0&&index<size){
+			return true;
+		}
+		return false;
+	}
+	public Node indexOf(int index){
+		if(enCapacity(index)){
+				Node current=head;
+				int currentIndex=0;
+				while(current!=null){
+					if(currentIndex==index){
+						return current;
+					}
+					current=current.next;
+					currentIndex++;
+				}
+			
+		}
+		return null;
+	}
+	public void add(int index , Object o){
+		 if(enCapacity(index)){
+			 Node newNode=new Node();
+			 newNode.data=o;
+			 if(index==0){
+				 newNode.next=head;
+				 head=newNode;
+			 }
+			 else{
+				 Node BIndexOf=indexOf(index-1);
+				 Node indexOf=indexOf(index);
+				 newNode.next=indexOf;
+				 BIndexOf.next=newNode;
+			 }
+			size++;
+		}
+		 else if(index==size){
+			 Node newNode=new Node();
+			 newNode.data=o;
+			last.next=newNode;
+			last=newNode;
+		 }
+		
+		
+	}
+	public Object get(int index){
+		if(enCapacity(index)){
+			Node current=head;
+			int currentIndex=0;
+			while(current!=null){
+				if(currentIndex==index){
+					return current.data;
+				}
+				current=current.next;
+				currentIndex++;
+			}
+		}
+		return null;
+	}
+	public Object remove(int index){
+		Node remove =indexOf(index);
+		if(index==0){
+			head=head.next;
+			size--;
+			return remove.data;
+		}
+		else if(index+1==size){
+			Node bRemove =indexOf(index-1);
+			bRemove.next=null;
+			last=bRemove;
+			size--;
+			return remove.data;
+		}
+		else if(remove!=null){
+			Node bRemove =indexOf(index-1);
+			Node aRemove =indexOf(index+1);
+			bRemove.next=aRemove;
+			size--;
+			return remove.data;
+		}
+		return null;
+	}
+	
+	public int size(){
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		Node first=new Node();
+		first.data=o;
+		first.next=head;
+		head=first;
+		size++;
+		
+	}
+	public void addLast(Object o){
+		Node last=new Node();
+		last.data=o;
+		this.last.next=last;
+		this.last=last;
+		size++;
+	}
+	public Object removeFirst(){
+		Node temp=head;
+		head=head.next;
+		size--;
+		return temp.data;
+	}
+	public Object removeLast(){
+		Node temp=last;
+		last=indexOf(size-2);
+		last.next=null;
+		size--;
+		return temp.data;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+	}
+	
+	public class ListIterator implements Iterator{
+		private int curos;
+		@Override
+		public boolean hasNext() {
+			// TODO Auto-generated method stub
+			return curos!=size;
+		}
+
+		@Override
+		public Object next() {
+			// TODO Auto-generated method stub
+			int i=0;
+			curos=i+1;
+			return get(i);
+		}
+		
+	}
+	/**
+	 * 把该链表逆置  1 2 3 4 5
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){
+		Node temp1=last;
+		for(int i=size-2;i>=0;i--){
+			Node temp2=indexOf(i);
+			temp1.next=temp2;
+			temp1=temp2;
+		}
+		head.next=null;
+		temp1=head;
+		head=last;
+		last=temp1;
+	}
+	
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		if(size>1){
+			Node index=indexOf(size/2-1);
+			index.next=null;
+			last=index;
+			size=size-size/2;
+		}
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){//1 2 3 4 5
+		if( i<size && i>=0){
+			int len=length+i>size? size-i:length;
+			int j=0;
+			while(j<len){
+				remove(i);
+				j++;
+			}
+		}
+		/*if((length+i)<=size && length>0 && i>=0){
+			Node before=indexOf(i-1);
+			Node after=indexOf(length+i);
+			if(before==null&&after==null){
+				head=null;
+				last=null;
+				size=0;
+			}
+			else if(before==null&&after!=null){
+				head=after;
+				size=size-length;
+			}
+			else if(before!=null&&after==null){
+				before.next=null;
+				last=before;
+				size=size-length;
+			}
+			else{
+				before.next=after;
+				size=size-length;
+			}
+		}*/
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		if(list==null){
+			return null;
+		}
+		int size=list.size;
+		int jude=0;
+		int [] newInt=new int[size];
+		while(jude<size&&size>0){
+			int index=(int) list.get(jude);
+			if(index>=0&&index<this.size){
+				newInt[jude]=(int) get(index);
+				jude++;
+			}
+			
+		}
+		return Arrays.copyOf(newInt, jude);
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		if(list==null){
+			return ;
+		}
+		int size=list.size;
+		int jude=0;
+		while(jude<size&&size>0){
+			int index=(int) list.get(jude);
+			for(int i=0;i<this.size;i++){
+				int data=(int) get(i);
+				if(data==index){
+					if(i==0){
+						head=indexOf(i+1);
+					}
+					else if(i==this.size-1){
+						last=indexOf(i-1);
+						last.next=null;
+					}
+					else{
+						Node bIndex=indexOf(i-1);
+						Node aindex=indexOf(i+1);
+						bIndex.next=aindex;
+					}
+					this.size--;
+					break;
+				}
+			}
+			jude++;
+		}
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		int i=0;
+		int j=0;
+		Node pre=head;
+		Node next=head.next;
+		while(i<size-1){
+			if((int)pre.data==(int)next.data){
+				Node temp=indexOf(j);
+				temp.next=next.next;
+				size--;
+			}
+			j++;
+			next=next.next;
+			if(next==pre){
+				next=next.next;
+			}
+			
+			if(j==size-1){
+				pre=pre.next;
+				next=head;
+				j=0;
+				i++;
+			}
+		}
+		/*for(int i=0;i<size;i++){
+			int data1=(int) get(i);
+			for(int j=i+1;j<size;j++){
+				int data2=(int) get(j);
+				if(data1==data2){
+					if(j==0){
+						head=indexOf(j+1);
+					}
+					else if(j==this.size-1){
+						last=indexOf(j-1);
+						last.next=null;
+					}
+					else{
+						Node bIndex=indexOf(j-1);
+						Node aindex=indexOf(j+1);
+						bIndex.next=aindex;
+					}
+					this.size--;
+				}
+			}
+		}*/
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min       1 2 3 4 5 6 7 8   3 ,6 
+	 * @param max        
+	 */  
+	public  void removeRange(int min, int max){
+		if(head==null){
+			return;
+		}
+		int start=-1;
+		int end=-1;
+		Node temp=head;
+		int i=0;
+		while(temp!=null){
+			if((start == -1) &&(int)temp.data>min){
+				start=i;
+			}
+			if((int)temp.data>=max){
+				end=i;
+				break;
+			}
+			i++;
+			temp=temp.next;
+		}
+		if(start==-1){
+			start=0;
+		}
+		if(end==-1){
+			end=size;
+		}
+		this.remove(start,end-start);
+	
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		if(list==null){
+			return null;
+		}
+		int i=0;
+		int j=0;
+		LinkedList c=new LinkedList();
+		while(i<this.size&&j<list.size){
+			if((int)get(i)==(int)list.get(j)){
+				c.add(get(i));
+				i++;
+				j++;
+			}
+			else if((int)get(i)>(int)list.get(j)){
+				j++;
+			}
+			else{
+				i++;
+			}
+		}
+		return c;
+	}
+}
diff --git a/group04/844028312/three/src/com/coding/basic/LinkedListTest.java b/group04/844028312/three/src/com/coding/basic/LinkedListTest.java
new file mode 100644
index 0000000000..0c965c90bd
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/LinkedListTest.java
@@ -0,0 +1,145 @@
+package com.coding.basic;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LinkedListTest {
+	private LinkedList linkedList;
+	@Before
+	public void setUp() throws Exception {
+		linkedList=new LinkedList();
+		for(int i=0;i<10;i++){
+			linkedList.add(i);
+		}
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testAddObject() {
+		
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testAddIntObject() {
+		linkedList.add(10, "@");
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testGet() {
+		System.out.println(linkedList.get(100));
+	}
+
+	@Test
+	public void testRemoveInt() {
+		System.out.println(linkedList.remove(9));
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testSize() {
+		fail("Not yet implemented");
+	}
+
+	@Test
+	public void testAddFirst() {
+		linkedList.addFirst("aa");
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testAddLast() {
+		linkedList.addLast("bb");
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testRemoveFirst() {
+		linkedList.removeFirst();
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testRemoveLast() {
+		linkedList.removeLast();
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testIterator() {
+		fail("Not yet implemented");
+	}
+
+	@Test
+	public void testReverse() {
+		linkedList.reverse();
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testRemoveFirstHalf() {
+		linkedList.removeFirstHalf();
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testRemoveIntInt() {
+		linkedList.remove(2, 5);//0 1 2 3 4 5 6 7 8 9
+		System.out.println(linkedList.size());
+	}
+
+	@Test
+	public void testGetElements() {
+		LinkedList list=new LinkedList();
+		list.add(1);
+		list.add(3);
+		list.add(2);
+		list.add(7);
+		int [] a=linkedList.getElements(list);
+		System.out.println(a);
+		
+	}
+
+	@Test
+	public void testSubtract() {
+		LinkedList list=new LinkedList();
+		list.add(1);
+		list.add(3);
+		list.add(2);
+		list.add(10);
+		linkedList.subtract(list);
+		System.out.println(linkedList);
+	}
+
+	@Test
+	public void testRemoveDuplicateValues() {
+		linkedList.add(1);
+		linkedList.add(2);
+		linkedList.add(3);
+		linkedList.removeDuplicateValues();
+		System.out.println(linkedList);
+	}
+
+	@Test
+	public void testRemoveRange() {
+		linkedList.removeRange(2, 5);
+		System.out.println(linkedList);
+	}
+
+	@Test
+	public void testIntersection() {
+		LinkedList list=new LinkedList();
+		list.add(5);
+		list.add(6);
+		LinkedList c=linkedList.intersection(list);
+		System.out.println(c);
+	}
+
+}
diff --git a/group04/120549547/base/src/com/coding/basic/List.java b/group04/844028312/three/src/com/coding/basic/List.java
similarity index 99%
rename from group04/120549547/base/src/com/coding/basic/List.java
rename to group04/844028312/three/src/com/coding/basic/List.java
index d47df585d9..10d13b5832 100644
--- a/group04/120549547/base/src/com/coding/basic/List.java
+++ b/group04/844028312/three/src/com/coding/basic/List.java
@@ -1,7 +1,6 @@
 package com.coding.basic;
 
 public interface List {
-	
 	public void add(Object o);
 	public void add(int index, Object o);
 	public Object get(int index);
diff --git a/group04/844028312/three/src/com/coding/basic/Queue.java b/group04/844028312/three/src/com/coding/basic/Queue.java
new file mode 100644
index 0000000000..36e516e266
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/Queue.java
@@ -0,0 +1,19 @@
+package com.coding.basic;
+
+public class Queue {
+	
+	public void enQueue(Object o){		
+	}
+	
+	public Object deQueue(){
+		return null;
+	}
+	
+	public boolean isEmpty(){
+		return false;
+	}
+	
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group04/844028312/three/src/com/coding/basic/Stack.java b/group04/844028312/three/src/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..a5a04de76d
--- /dev/null
+++ b/group04/844028312/three/src/com/coding/basic/Stack.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+public class Stack {
+	private ArrayList elementData = new ArrayList();
+	
+	public void push(Object o){		
+	}
+	
+	public Object pop(){
+		return null;
+	}
+	
+	public Object peek(){
+		return null;
+	}
+	public boolean isEmpty(){
+		return false;
+	}
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group04/844028312/two/src/com/coderising/array/ArrayUtil.java b/group04/844028312/two/src/com/coderising/array/ArrayUtil.java
index 309610c6be..504c07640e 100644
--- a/group04/844028312/two/src/com/coderising/array/ArrayUtil.java
+++ b/group04/844028312/two/src/com/coderising/array/ArrayUtil.java
@@ -12,14 +12,16 @@ public class ArrayUtil {
 	 * @return
 	 */
 	public void reverseArray(int[] origin){
+		if(origin==null){
+			return;
+		}
 		int size=origin.length;
-		if(size>1){
-				for(int i=0;i<size/2;i++){
-					int temp=origin[i];			//记录origin[i]的值
-					origin[i]=origin[size-1-i];
-					origin[size-1-i]=temp;
-				}
+		for(int i=0;i<size/2;i++){
+				int temp=origin[i];			//记录origin[i]的值
+				origin[i]=origin[size-1-i];
+				origin[size-1-i]=temp;
 		}
+		
 	}
 	
 	/**
@@ -33,25 +35,20 @@ public void reverseArray(int[] origin){
 	public int[] removeZero(int[] oldArray){
 		int size=oldArray.length;
 		int zero=0;	//记录0的数目
+		int []array=new int[size];
 		for(int i=0;i<size;i++){
-			if(oldArray[i]==0){
+			if(oldArray[i]!=0){
+				array[i]=oldArray[i];
+			}
+			else{
 				zero++;
 			}
 		}
 		if(zero==0){
 			return oldArray;
-		}
-		else{
-			int [] newArray=new int[size-zero];	//新建一个数组
-			int now=0;//记录新数组的下标
-			for(int i=0;i<size;i++){
-				if(oldArray[i]!=0){
-					newArray[now]=oldArray[i];
-					now++;
-				}
-			}
-			return newArray;
-		}
+		}	
+		return Arrays.copyOf(array, zero);
+		
 	}
 	
 	/**
@@ -63,37 +60,38 @@ public int[] removeZero(int[] oldArray){
 	 */
 	
 	public int[] merge(int[] array1, int[] array2){
+		if(array1==null){
+			return array2;
+		}
+		if(array2==null){
+			return array1;
+		}
 		int size1=array1.length;
 		int size2=array2.length;
-		int newArray[];
-		if(size1==0&&size2==0){
-			return  null;
+		int newArray[]=new int[size1+size2];
+		int count=0;
+		int i=0;int j=0;
+		while(i<size1 && j<size2){
+			 if(array1[i]>array2[j]){
+				 newArray[count++]=array2[j++];
+				
+			 }
+			 if(array1[i]<array2[j]){
+				 newArray[count++]=array1[i++];
+				
+			 }
+			 if(array1[i]==array2[j]){
+				 newArray[count++]=array1[i++];
+				 j++;
+			 }
 		}
-		else{
-			newArray=new int[size1+size2];
+		while(i==size1&&j<size2){
+			 newArray[count++]=array2[j++];
 		}
-		if(size1>0)
-			System.arraycopy(array1, 0, newArray, 0, size1);
-		if(size2>0)
-			System.arraycopy(array2,0, newArray,  size1, size2);
-		for(int i=0;i<newArray.length;i++){
-			int min=newArray[i];
-			for(int j=i+1;j<newArray.length;j++){	// [2, 4, 2, 5, 9, 6, 3, 1, 10, 8]
-				if(min==newArray[j]){				//去除重复数
-					System.arraycopy(newArray,j+1, newArray,  j, newArray.length-j-1);
-					int [] a=new int[newArray.length-1];
-					System.arraycopy(newArray,0, a,  0, newArray.length-1);
-					newArray=a;
-				}
-				if(min>newArray[j]){
-					int temp=min;
-					min=newArray[j];
-					newArray[i]=min;
-					newArray[j]=temp;
-				}
-			}
+		while(j==size1&&i<size1){
+			 newArray[count++]=array1[i++];
 		}
-		return  newArray;
+		return  Arrays.copyOf(newArray, count);
 	}
 	/**
 	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
@@ -120,22 +118,15 @@ public int[] grow(int [] oldArray,  int size){
 	public int[] fibonacci(int max){
 		int [] a = null;
 		if(max>2){
-			a=new int[10];
+			a=new int[max];
 			int record=2;
 			do{
 				a[0]=1;
 				a[1]=1;
-				if(a.length>record)
-					a[record]=a[record-2]+a[record-1];
-				else{
-					a=grow(a,3);
-					a[record]=a[record-2]+a[record-1];
-				}
+				a[record]=a[record-2]+a[record-1];
 				record++;
 			}while(a[record-1]<max);
-			int[] b=new int[record-1];
-			System.arraycopy(a, 0, b, 0, record-1);
-			a=b;
+			a=Arrays.copyOf(a, record-1);
 		}
 		else if(max==2){
 			a=new int[2];
@@ -153,39 +144,28 @@ else if(max==2){
 	 */
 	public int[] getPrimes(int max){
 		int n=2;//初始素数大小
-		int[] primes=new int[10];
+		int[] primes=new int[max];
 		int record=0;
-		while(true){
-			boolean isPrime=true;//是否是质数的标志
-			if(max<=n){
-				break;
-			}
-			int jude=(int) Math.sqrt(n);
-			for(int i=jude;i>1;i--){
-				if(n%i==0){
-					 isPrime=false;
+		if(max>=2){
+			while(n<max){
+				int jude=(int) Math.sqrt(n);
+				boolean isPrime=true;//是否是质数的标志
+				for(int i=jude;i>1;i--){
+					if(n%i==0){
+						isPrime=false;
+						break;
+					}
+					
 				}
-			}
-			if(isPrime){
-				if(record<primes.length)
-					primes[record]=n;
-				else{
-					primes=grow(primes,5);
+				if(isPrime){
 					primes[record]=n;
+					record++;
 				}
-				record++;
+				n++;
 			}
-			n++;
-		}
-		if(record<10){			//如果小于初始数组要去除0
-			primes=removeZero(primes);
 		}
-		if(record<primes.length-1){
-			int[] newArray=new int [record];
-			System.arraycopy(primes, 0, newArray, 0, record);
-			primes=newArray;
-		}
-		return primes;
+		
+		return Arrays.copyOf(primes, record);
 	}
 	
 	/**
@@ -196,48 +176,25 @@ public int[] getPrimes(int max){
 	 */
 	public int[] getPerfectNumbers(int max){
 		int min=6;
-		int[] perfect=new int[3];
+		int[] perfect=new int[10];
 		int record=0;
 		if(max>=min){
-			while(true){
-				boolean isPerfect=false;//是否是完数的标志
-				if(max<=min){
-					break;
-				}
-				int n=(int) Math.sqrt(min);
-				int count=0;
-				for(int i=n;i>=1;i--){
+			while(min<max){
+				int sum=0;
+				for(int i=min-1;i>0;i--){
 					if(min%i==0){
-						count=count+i;
-						int b=min/i;
-						if(b!=min)
-							count=count+b;
+						sum=sum+i;
 					}
 				}
-				if(count==min){
-					isPerfect=true;
-				}
-				if(isPerfect){
-					if(record<perfect.length)
-						perfect[record]=min;
-					else{
-						perfect=grow(perfect,1);
-						perfect[record]=min;
-					}
+				if(sum==min){
+					perfect[record]=min;
 					record++;
 				}
 				min++;
-			}
-			if(record<3){			//如果小于初始数组要去除0
-				perfect=removeZero(perfect);
-			}
-			if(record<perfect.length-1){
-				int[] newArray=new int [record];
-				System.arraycopy(perfect, 0, newArray, 0, record);
-				perfect=newArray;
+				
 			}
 		}
-		return perfect;
+		return Arrays.copyOf(perfect, record);
 	}
 	
 	/**
diff --git a/group04/844028312/two/src/com/coderising/array/ArrayUtilTest.java b/group04/844028312/two/src/com/coderising/array/ArrayUtilTest.java
index 6215bec0cf..3060612a40 100644
--- a/group04/844028312/two/src/com/coderising/array/ArrayUtilTest.java
+++ b/group04/844028312/two/src/com/coderising/array/ArrayUtilTest.java
@@ -30,8 +30,8 @@ public void testRemoveZero() {
 	}
 	@Test
 	public void testMerge() {
-		int []array1={2,4,2,5,9};
-		int []array2={6,3,1,10,8};
+		int []array1={2,4,5,6,7};
+		int []array2={6,7,8,9,10};
 		int []newArray=arrayUtil.merge(array1, array2);
 		System.out.println(newArray);
 	}
@@ -53,7 +53,7 @@ public void testGetPrimes() {
 	}
 	@Test
 	public void testGetPerfectNumbers() {
-		int []newArray=arrayUtil.getPerfectNumbers(10000000);
+		int []newArray=arrayUtil.getPerfectNumbers(500);
 		System.out.println(newArray);
 	}
 	@Test
diff --git a/group04/916758663/learn01/learn01.iml b/group04/916758663/learn01/learn01.iml
index 6e0c17c683..97c857d442 100644
--- a/group04/916758663/learn01/learn01.iml
+++ b/group04/916758663/learn01/learn01.iml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
     <output url="file://$MODULE_DIR$/target/classes" />
     <output-test url="file://$MODULE_DIR$/target/test-classes" />
     <content url="file://$MODULE_DIR$">
diff --git a/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java b/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java
index 0c9e702951..b4ac9cf2b9 100644
--- a/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java
+++ b/group04/916758663/learn01/src/main/java/com/coding/basic/ArrayList.java
@@ -9,23 +9,30 @@ public class ArrayList implements List {
 	private Object[] elementData = new Object[3];
 	
 	public void add(Object o){
-		add(size,o);
+		ensureCapacity(size + 1);
+		elementData[size] = o;
+		size++;
 	}
+
 	public void add(int index, Object o){
 		if (index > size){
 			throw new IndexOutOfBoundsException();
 		}
+
 		// 扩容
-		if (size == elementData.length || index + 1 > elementData.length) {
-			int newLength = index + 1 > size * 2 ? index + 1 :size * 2;
-			elementData = Arrays.copyOf(elementData, newLength);
-		}
+		ensureCapacity(size + 1);
+
 		// 移动元素
 		System.arraycopy(elementData,index,elementData,index + 1 ,size-index);
 		elementData[index] = o;
 		size ++ ;
 	}
-	
+
+	private void ensureCapacity(int minCapacity) {
+		int newLength = Math.max(minCapacity, size * 2);
+		elementData = Arrays.copyOf(elementData, newLength);
+	}
+
 	public Object get(int index){
 		checkIndex(index);
 		return elementData[index];
@@ -55,17 +62,17 @@ public Iterator iterator(){
 
 	private class ArrayListIterator implements Iterator {
 
-		private int currentIndex = 0;
+		private int position = 0;
 
 		@Override
 		public boolean hasNext() {
-			return currentIndex < size();
+			return position < size();
 		}
 
 		@Override
 		public Object next() {
-			Object o = get(currentIndex);
-			currentIndex ++ ;
+			Object o = get(position);
+			position++ ;
 			return o;
 		}
 	}
diff --git a/group04/916758663/learn03/pom.xml b/group04/916758663/learn03/pom.xml
new file mode 100644
index 0000000000..82848b035e
--- /dev/null
+++ b/group04/916758663/learn03/pom.xml
@@ -0,0 +1,32 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>com.example</groupId>
+  <artifactId>download</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>download</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>3.6.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java b/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java
new file mode 100644
index 0000000000..6239bc13d2
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/DownloadThread.java
@@ -0,0 +1,50 @@
+package com.example.download;
+
+
+import com.example.download.api.Connection;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.CountDownLatch;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+	String file;
+	CountDownLatch latch;
+
+	public DownloadThread( Connection conn, int startPos, int endPos,String file,CountDownLatch latch){
+		
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+		this.file = file;
+		this.latch = latch;
+	}
+	public void run(){
+		RandomAccessFile randomAccessFile = null;
+		try {
+			byte[] data = conn.read(startPos, endPos);
+			randomAccessFile = new RandomAccessFile(file, "rw");
+			randomAccessFile.seek(startPos);
+			randomAccessFile.write(data);
+			latch.countDown();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}finally {
+			try {
+				if (randomAccessFile != null) {
+					randomAccessFile.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			conn.close();
+		}
+	}
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java b/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java
new file mode 100644
index 0000000000..743955e329
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/FileDownloader.java
@@ -0,0 +1,76 @@
+package com.example.download;
+
+
+import com.example.download.api.Connection;
+import com.example.download.api.ConnectionException;
+import com.example.download.api.ConnectionManager;
+import com.example.download.api.DownloadListener;
+import java.util.concurrent.CountDownLatch;
+
+public class FileDownloader {
+	
+	String url;
+
+	String localFile;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+
+	private CountDownLatch latch = new CountDownLatch(3);
+	
+
+	public FileDownloader(String _url,String localFile) {
+		this.url = _url;
+		this.localFile = localFile;
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			conn = cm.open(this.url);
+			int length = conn.getContentLength();
+			int[][] array = Utils.split(length, 3);
+			for (int i = 0; i < 3; i++) {
+				new DownloadThread(conn,array[i][0],array[i][1],localFile,latch).start();
+			}
+
+			latch.await();
+
+			this.getListener().notifyFinished();
+			
+		} catch (ConnectionException e) {
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		} finally{
+		}
+
+	}
+	
+	public void setListener(DownloadListener listener) {
+		this.listener = listener;
+	}
+
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/Utils.java b/group04/916758663/learn03/src/main/java/com/example/download/Utils.java
new file mode 100644
index 0000000000..521583d7e5
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/Utils.java
@@ -0,0 +1,24 @@
+package com.example.download;
+
+/**
+ * Created by qilei on 17/3/26.
+ */
+public class Utils {
+
+  public static int[][] split(int len, int count) {
+    int[][] result = new int[count][2];
+    int baseLen = (int)Math.ceil(((double)len / count));
+    for (int i = 0; i < count; i++) {
+      int startPos = baseLen * i ;
+      int endPos = baseLen * (i + 1) -1;
+      if (i == count - 1) {
+        if (endPos > len - 1) {
+          endPos = len - 1;
+        }
+      }
+      result[i][0] = startPos;
+      result[i][1] = endPos;
+    }
+    return result;
+  }
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java b/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java
new file mode 100644
index 0000000000..d3906b1859
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.example.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos, int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java
new file mode 100644
index 0000000000..ffbd61ec31
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.example.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..1888a879ef
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.example.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java b/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java
new file mode 100644
index 0000000000..9cc73ddee6
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.example.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..62ee66f1c5
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionImpl.java
@@ -0,0 +1,58 @@
+package com.example.download.impl;
+
+import com.example.download.api.Connection;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+
+public class ConnectionImpl implements Connection {
+
+	private URL url;
+
+	ConnectionImpl(String urlStr){
+		try {
+			url = new URL(urlStr);
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+    URLConnection urlConnection = url.openConnection();
+    urlConnection.setRequestProperty("Range", "bytes=" + startPos + "-"
+        + endPos);
+    InputStream inputStream = urlConnection.getInputStream();
+    int len = endPos + 1 - startPos;
+    int bytesRead = 0;
+		byte[] buffer = new byte[len];
+    while (bytesRead < len) {
+      int result = inputStream.read(buffer, bytesRead, len - bytesRead);
+      if (result == -1){
+        break;
+      }
+      bytesRead += result;
+    }
+    inputStream.close();
+		return buffer;
+	}
+
+	@Override
+	public int getContentLength() {
+		try {
+      URLConnection urlConnection = url.openConnection();
+      return urlConnection.getContentLength();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+    return -1;
+	}
+
+	@Override
+	public void close() {
+	}
+
+}
diff --git a/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..d346c4d350
--- /dev/null
+++ b/group04/916758663/learn03/src/main/java/com/example/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,16 @@
+package com.example.download.impl;
+
+
+import com.example.download.api.Connection;
+import com.example.download.api.ConnectionException;
+import com.example.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		Connection conn = new ConnectionImpl(url);
+		return conn;
+	}
+
+}
diff --git a/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java b/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..7dbeffd108
--- /dev/null
+++ b/group04/916758663/learn03/src/test/java/com/example/download/FileDownloaderTest.java
@@ -0,0 +1,57 @@
+package com.example.download;
+
+
+import com.example.download.api.ConnectionManager;
+import com.example.download.api.DownloadListener;
+import com.example.download.impl.ConnectionManagerImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Created by qilei on 17/3/14.
+ */
+public class FileDownloaderTest {
+  boolean downloadFinished = false;
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testDownload() {
+    String url ="http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg";
+    String file = "/Users/qilei/tmp/tmp.jpg";
+    FileDownloader downloader = new FileDownloader(url,file);
+
+    ConnectionManager cm = new ConnectionManagerImpl();
+    downloader.setConnectionManager(cm);
+
+    downloader.setListener(new DownloadListener() {
+      @Override
+      public void notifyFinished() {
+        downloadFinished = true;
+      }
+
+    });
+
+
+    downloader.execute();
+
+    // 等待多线程下载程序执行完毕
+    while (!downloadFinished) {
+      try {
+        System.out.println("还没有下载完成，休眠五秒");
+        //休眠5秒
+        Thread.sleep(5000);
+      } catch (InterruptedException e) {
+        e.printStackTrace();
+      }
+    }
+    System.out.println("下载完成！");
+  }
+
+}
\ No newline at end of file
diff --git a/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java b/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java
new file mode 100644
index 0000000000..ff41d07731
--- /dev/null
+++ b/group04/916758663/learn03/src/test/java/com/example/download/UtilsTest.java
@@ -0,0 +1,31 @@
+package com.example.download;
+
+import org.junit.Test;
+import static org.assertj.core.api.Assertions.*;
+
+/**
+ * Created by qilei on 17/3/26.
+ */
+public class UtilsTest {
+
+  @Test
+  public void testSplit(){
+    int len = 10;
+
+    int[][] result = Utils.split(10,3);
+
+    assertThat(result[0][0]).isEqualTo(0);
+    assertThat(result[0][1]).isEqualTo(3);
+    assertThat(result[2][0]).isEqualTo(8);
+    assertThat(result[2][1]).isEqualTo(9);
+  }
+
+  @Test
+  public void testMath(){
+    double a = Math.ceil((double)10 / 3);
+    double b = Math.floor((double)10 / 3);
+    System.out.println("");
+
+  }
+
+}
diff --git a/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java b/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java
new file mode 100644
index 0000000000..7b21df4109
--- /dev/null
+++ b/group04/916758663/learn03/src/test/java/com/example/download/impl/ConnectionImplTest.java
@@ -0,0 +1,49 @@
+package com.example.download.impl;
+
+import static org.assertj.core.api.Assertions.*;
+
+import com.example.download.api.Connection;
+import com.example.download.api.ConnectionException;
+import com.example.download.api.ConnectionManager;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Created by qilei on 17/3/24.
+ */
+public class ConnectionImplTest {
+
+  private Connection connection;
+
+  @Before
+  public void setup(){
+    ConnectionManager cm = new ConnectionManagerImpl();
+    String url ="http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg";
+    try {
+      connection = cm.open(url);
+    } catch (ConnectionException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void read() throws Exception {
+    byte[] data = null;
+    data = connection.read(0, 35469);
+    assertThat(data.length).isEqualTo(35470);
+
+    data = connection.read(0, 1023);
+    assertThat(data.length).isEqualTo(1024);
+
+    data = connection.read(1024, 2023);
+    assertThat(data.length).isEqualTo(1000);
+
+  }
+
+  @Test
+  public void getContentLength() throws Exception {
+    int contentLength = connection.getContentLength();
+    assertThat(contentLength).isEqualTo(35470);
+  }
+
+}
\ No newline at end of file
diff --git a/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java b/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..cb860bf053
--- /dev/null
+++ b/group04/916758663/minijvm/src/main/java/com/example/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,70 @@
+package com.example.jvm.loader;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		String filePartPath = className.replace(".", "/") + ".class";
+		for (String clzPath : clzPaths) {
+			String filePath = clzPath + "/" + filePartPath;
+			File file = new File(filePath);
+			if (file.exists()) {
+				try {
+					FileInputStream inputStream = new FileInputStream(file);
+					int bytesRead = 0;
+					int len = inputStream.available();
+					byte[] buffer = new byte[len];
+					while (bytesRead < len) {
+						int result = inputStream.read(buffer, bytesRead, len - bytesRead);
+						if (result == -1){
+							break;
+						}
+						bytesRead += result;
+					}
+					inputStream.close();
+					return buffer;
+				} catch (FileNotFoundException e) {
+					e.printStackTrace();
+				}catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		throw new RuntimeException("未找到类");
+	}
+	
+	
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+
+	public String getClassPath(){
+		String result = "";
+		StringBuilder sb = new StringBuilder();
+		for(String path : clzPaths){
+			sb.append(path + ";");
+		}
+		result = sb.toString();
+		if (result != "") {
+			result = result.substring(0, result.length() - 1);
+		}
+		return result;
+	}
+
+	
+
+	
+
+}
diff --git a/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java
new file mode 100644
index 0000000000..04bb301b5e
--- /dev/null
+++ b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/ClassFileLoaderTest.java
@@ -0,0 +1,78 @@
+package com.example.jvm.loader;
+
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Created by qilei on 17/4/3.
+ */
+public class ClassFileLoaderTest {
+
+  static String path1 = "/Users/qilei/idea/coding2017/coding2017/group04/916758663/minijvm/target/test-classes";
+  static String path2 = "/Users/qilei/idea/coding2017/coding2017/group04/916758663/minijvm/target/classes";
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testClassPath(){
+    ClassFileLoader loader = new ClassFileLoader();
+    loader.addClassPath(path1);
+    loader.addClassPath(path2);
+
+    String clzPath = loader.getClassPath();
+
+    Assert.assertEquals(path1+";"+path2,clzPath);
+  }
+
+  @Test
+  public void testClassFileLength() {
+
+    ClassFileLoader loader = new ClassFileLoader();
+    loader.addClassPath(path1);
+    String className = "com.example.jvm.loader.EmployeeV1";
+
+    byte[] byteCodes = loader.readBinaryCode(className);
+
+    // 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+    Assert.assertEquals(1054, byteCodes.length);
+
+  }
+
+  @Test
+  public void testMagicNumber(){
+    ClassFileLoader loader = new ClassFileLoader();
+    loader.addClassPath(path1);
+    String className = "com.example.jvm.loader.EmployeeV1";
+    byte[] byteCodes = loader.readBinaryCode(className);
+    byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+    String acctualValue = this.byteToHexString(codes);
+
+    Assert.assertEquals("cafebabe", acctualValue);
+  }
+
+  private String byteToHexString(byte[] codes ){
+    StringBuffer buffer = new StringBuffer();
+    for(int i=0;i<codes.length;i++){
+      byte b = codes[i];
+      int value = b & 0xFF;
+      String strHex = Integer.toHexString(value);
+      if(strHex.length()< 2){
+        strHex = "0" + strHex;
+      }
+      buffer.append(strHex);
+    }
+    return buffer.toString();
+  }
+
+}
\ No newline at end of file
diff --git a/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/EmployeeV1.java b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/EmployeeV1.java
new file mode 100644
index 0000000000..91d629e922
--- /dev/null
+++ b/group04/916758663/minijvm/src/test/java/com/example/jvm/loader/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.example.jvm.loader;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group05/1094051862/mini-jvm/.classpath b/group05/1094051862/mini-jvm/.classpath
new file mode 100644
index 0000000000..9b2ed0d520
--- /dev/null
+++ b/group05/1094051862/mini-jvm/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="lib" path="lib/dom4j-1.6.1.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/group05/1094051862/mini-jvm/.gitignore b/group05/1094051862/mini-jvm/.gitignore
new file mode 100644
index 0000000000..ae3c172604
--- /dev/null
+++ b/group05/1094051862/mini-jvm/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/group05/1094051862/mini-jvm/.project b/group05/1094051862/mini-jvm/.project
new file mode 100644
index 0000000000..ec3aa61015
--- /dev/null
+++ b/group05/1094051862/mini-jvm/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mini-jvm</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..86f1100e6c
--- /dev/null
+++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,88 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+
+	public byte[] readBinaryCode(String className) throws ClassNotFoundException, IOException {
+		if (clzPaths.size() == 0) {
+			return new byte[0];
+		}
+		String actualPath = getActualPath(className);
+		
+		File f = new File(actualPath);  
+		
+        if (!f.exists()) {  
+            throw new ClassNotFoundException(actualPath);  
+        }  
+  
+        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());  
+        BufferedInputStream is = null;  
+        try {  
+            is = new BufferedInputStream(new FileInputStream(f));  
+            
+            byte[] buffer = new byte[1024];  
+            int len = 0;  
+            
+            while (-1 != (len = is.read(buffer))) {  
+                bos.write(buffer, 0, len);  
+            } 
+
+            return bos.toByteArray();  
+            
+        } catch (IOException e) {  
+            e.printStackTrace();  
+            throw e;  
+        } finally {  
+            is.close();
+            bos.close();  
+        }  
+	}
+
+	private String getActualPath(String className) {
+		
+		String fileName = className.substring(className.lastIndexOf(".") + 1) + ".class";
+		String dirPath = className.substring(0, className.lastIndexOf(".")).replace(".", "\\");
+		
+		return clzPaths.get(clzPaths.size() - 1) + "\\" + dirPath + "\\" + fileName;   //classPath  取最近添加的一个
+		
+	}
+
+	public void addClassPath(String path) {
+
+		if (path == null) {
+			return;
+		}
+
+		clzPaths.add(path);
+
+	}
+
+	public String getClassPath() {
+
+		if (clzPaths.size() == 0) {
+			return "";
+		}
+
+		StringBuffer buffer = new StringBuffer("");
+
+		for (String str : clzPaths) {
+			buffer.append(str);
+			buffer.append(";");
+		}
+
+		return buffer.substring(0, buffer.length() - 1);// 去除最后一个分号
+
+	}
+
+}
diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..b15eb7e99d
--- /dev/null
+++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,95 @@
+package com.coderising.jvm.test;
+
+import java.io.IOException;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "E:\\practise\\group05\\1094051862\\mini-jvm\\bin";
+	static String path2 = "C:\\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() throws ClassNotFoundException, IOException {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber() throws ClassNotFoundException, IOException{
+    	
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+		
+	}
+    
+    /**
+     * 二进制数组转换成16进制
+     * @param codes
+     * @return
+     */
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..9a36573dd3
--- /dev/null
+++ b/group05/1094051862/mini-jvm/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group05/1094051862/test01/.classpath b/group05/1094051862/test01/.classpath
index 9794cd8084..6f95a0c3bd 100644
--- a/group05/1094051862/test01/.classpath
+++ b/group05/1094051862/test01/.classpath
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="lib" path="lib/dom4j-1.6.1.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/dom4j-1.6.1.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/group05/1094051862/test01/.gitignore b/group05/1094051862/test01/.gitignore
index ae3c172604..3e2fcc7171 100644
--- a/group05/1094051862/test01/.gitignore
+++ b/group05/1094051862/test01/.gitignore
@@ -1 +1 @@
-/bin/
+/bin/
diff --git a/group05/1094051862/test01/.project b/group05/1094051862/test01/.project
index 1dfd9165c6..6be5013dd0 100644
--- a/group05/1094051862/test01/.project
+++ b/group05/1094051862/test01/.project
@@ -1,17 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>test01</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>test01</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs b/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs
index d17b6724d1..980b98c1d5 100644
--- a/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs
+++ b/group05/1094051862/test01/.settings/org.eclipse.jdt.core.prefs
@@ -1,12 +1,12 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.7
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.7
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/group05/1094051862/test01/src/com/coding/basic/ArrayList.java b/group05/1094051862/test01/src/com/coding/basic/ArrayList.java
index 60fe8b9150..2e837dd195 100644
--- a/group05/1094051862/test01/src/com/coding/basic/ArrayList.java
+++ b/group05/1094051862/test01/src/com/coding/basic/ArrayList.java
@@ -1,79 +1,79 @@
-package com.coding.basic;
-
-import java.util.Arrays;
-
-public class ArrayList implements List {
-	
-	private int size = 0;
-	
-	private Object[] elementData = new Object[10];
-	
-	private int increaseSize = 10;
-	private void increaseArray() {
-		Object[] newData = Arrays.copyOf(elementData, elementData.length + increaseSize);
-		elementData = newData;
-	}
-	public void add(Object o){
-		if (size == elementData.length) {
-			increaseArray();
-			elementData[size++] = o;
-		} else {
-			elementData[size++] = o;
-		}
-	}
-	public void add(int index, Object o){
-		if (index < 0 || index > size) {
-			System.out.println("错误提示：index > size || index < 0");
-			return;
-		}
-		Object temp;
-		for (int i = index; i < size; i++) {
-			temp = elementData[i];
-			elementData[i] = o;
-			o = temp;
-		}
-		elementData[size ++] = o;
-	}
-	
-	public Object get(int index){
-		if (index < 0 || index > size ){
-			return null;
-		}
-		return elementData[index];
-	}
-	
-	public Object remove(int index){
-		if (index < 0 || index > size ){
-			return null;
-		}
-		Object result = elementData[index];
-		for (int i = index; i < size-1; i++) {
-			elementData[i] = elementData[i + 1];
-		}
-		elementData[size-1] = null;
-		size --;
-		return result;
-	}
-	
-	public int size(){
-		return size;
-	}
-	
-	public Iterator iterator(){
-		return new Iterator() {
-			private int cusor = 0;
-			@Override
-			public Object next() {
-				if (!hasNext()) {
-					System.out.println("next: !hasNext");
-					return null;
-				}
-				return elementData[cusor ++];
-			}
-			@Override
-			public boolean hasNext() {
-				return cusor < size;
-			}
-		};
-	}
-}
+package com.coding.basic;
+
+import java.util.Arrays;
+
+public class ArrayList implements List {
+	
+	private int size = 0;
+	
+	private Object[] elementData = new Object[10];
+	
+	private int increaseSize = 10;
+	private void increaseArray() {
+		Object[] newData = Arrays.copyOf(elementData, elementData.length + increaseSize);
+		elementData = newData;
+	}
+	public void add(Object o){
+		if (size == elementData.length) {
+			increaseArray();
+			elementData[size++] = o;
+		} else {
+			elementData[size++] = o;
+		}
+	}
+	public void add(int index, Object o){
+		if (index < 0 || index > size) {
+			System.out.println("错误提示：index > size || index < 0");
+			return;
+		}
+		Object temp;
+		for (int i = index; i < size; i++) {
+			temp = elementData[i];
+			elementData[i] = o;
+			o = temp;
+		}
+		elementData[size ++] = o;
+	}
+	
+	public Object get(int index){
+		if (index < 0 || index > size ){
+			return null;
+		}
+		return elementData[index];
+	}
+	
+	public Object remove(int index){
+		if (index < 0 || index > size ){
+			return null;
+		}
+		Object result = elementData[index];
+		for (int i = index; i < size-1; i++) {
+			elementData[i] = elementData[i + 1];
+		}
+		elementData[size-1] = null;
+		size --;
+		return result;
+	}
+	
+	public int size(){
+		return size;
+	}
+	
+	public Iterator iterator(){
+		return new Iterator() {
+			private int cusor = 0;
+			@Override
+			public Object next() {
+				if (!hasNext()) {
+					System.out.println("next: !hasNext");
+					return null;
+				}
+				return elementData[cusor ++];
+			}
+			@Override
+			public boolean hasNext() {
+				return cusor < size;
+			}
+		};
+	}
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java b/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java
index d7ac820192..266eff3d56 100644
--- a/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java
+++ b/group05/1094051862/test01/src/com/coding/basic/BinaryTreeNode.java
@@ -1,32 +1,32 @@
-package com.coding.basic;
-
-public class BinaryTreeNode {
-	
-	private Object data;
-	private BinaryTreeNode left;
-	private BinaryTreeNode right;
-	
-	public Object getData() {
-		return data;
-	}
-	public void setData(Object data) {
-		this.data = data;
-	}
-	public BinaryTreeNode getLeft() {
-		return left;
-	}
-	public void setLeft(BinaryTreeNode left) {
-		this.left = left;
-	}
-	public BinaryTreeNode getRight() {
-		return right;
-	}
-	public void setRight(BinaryTreeNode right) {
-		this.right = right;
-	}
-	
-	public BinaryTreeNode insert(Object o){
-		return  null;
-	}
-	
-}
+package com.coding.basic;
+
+public class BinaryTreeNode {
+	
+	private Object data;
+	private BinaryTreeNode left;
+	private BinaryTreeNode right;
+	
+	public Object getData() {
+		return data;
+	}
+	public void setData(Object data) {
+		this.data = data;
+	}
+	public BinaryTreeNode getLeft() {
+		return left;
+	}
+	public void setLeft(BinaryTreeNode left) {
+		this.left = left;
+	}
+	public BinaryTreeNode getRight() {
+		return right;
+	}
+	public void setRight(BinaryTreeNode right) {
+		this.right = right;
+	}
+	
+	public BinaryTreeNode insert(Object o){
+		return  null;
+	}
+	
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/Iterator.java b/group05/1094051862/test01/src/com/coding/basic/Iterator.java
index 06ef6311b2..dbe8b9afb2 100644
--- a/group05/1094051862/test01/src/com/coding/basic/Iterator.java
+++ b/group05/1094051862/test01/src/com/coding/basic/Iterator.java
@@ -1,7 +1,7 @@
-package com.coding.basic;
-
-public interface Iterator {
-	public boolean hasNext();
-	public Object next();
-
-}
+package com.coding.basic;
+
+public interface Iterator {
+	public boolean hasNext();
+	public Object next();
+
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/Queue.java b/group05/1094051862/test01/src/com/coding/basic/Queue.java
index b65d01ab8e..e16a80b13c 100644
--- a/group05/1094051862/test01/src/com/coding/basic/Queue.java
+++ b/group05/1094051862/test01/src/com/coding/basic/Queue.java
@@ -1,25 +1,25 @@
-package com.coding.basic;
-
-public class Queue {
-	private List list = new ArrayList();
-	private int size = 0;
-	public void enQueue(Object o){		
-		list.add(o);
-		size ++;
-	}
-	
-	public Object deQueue(){
-		if (size == 0)
-			return null;
-		size --;
-		return list.remove(0);
-	}
-	
-	public boolean isEmpty(){
-		return size == 0;
-	}
-	
-	public int size(){
-		return size;
-	}
-}
+package com.coding.basic;
+
+public class Queue {
+	private List list = new ArrayList();
+	private int size = 0;
+	public void enQueue(Object o){		
+		list.add(o);
+		size ++;
+	}
+	
+	public Object deQueue(){
+		if (size == 0)
+			return null;
+		size --;
+		return list.remove(0);
+	}
+	
+	public boolean isEmpty(){
+		return size == 0;
+	}
+	
+	public int size(){
+		return size;
+	}
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/QueueTest.java b/group05/1094051862/test01/src/com/coding/basic/QueueTest.java
index f75beb397f..1feee8dde1 100644
--- a/group05/1094051862/test01/src/com/coding/basic/QueueTest.java
+++ b/group05/1094051862/test01/src/com/coding/basic/QueueTest.java
@@ -1,26 +1,24 @@
-package com.coding.basic;
-
-import static org.junit.Assert.*;
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-import sun.org.mozilla.javascript.internal.ast.NewExpression;
-
-public class QueueTest {
-
-	@Test
-	public void test() {
-		Queue queue = new Queue();
-		for (int i = 0; i < 100; i++) {
-			queue.enQueue(i);
-		}
-		Assert.assertEquals(100, queue.size());
-		for (int i = 0; i < 100; i++) {
-			Assert.assertEquals(i, queue.deQueue());
-		}
-		Assert.assertEquals(0, queue.size());
-		
-	}
-	
-}
+package com.coding.basic;
+
+import static org.junit.Assert.*;
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class QueueTest {
+
+	@Test
+	public void test() {
+		Queue queue = new Queue();
+		for (int i = 0; i < 100; i++) {
+			queue.enQueue(i);
+		}
+		Assert.assertEquals(100, queue.size());
+		for (int i = 0; i < 100; i++) {
+			Assert.assertEquals(i, queue.deQueue());
+		}
+		Assert.assertEquals(0, queue.size());
+		
+	}
+	
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/Stack.java b/group05/1094051862/test01/src/com/coding/basic/Stack.java
index 7fabb3494f..57eae3d31d 100644
--- a/group05/1094051862/test01/src/com/coding/basic/Stack.java
+++ b/group05/1094051862/test01/src/com/coding/basic/Stack.java
@@ -1,28 +1,28 @@
-package com.coding.basic;
-
-public class Stack {
-	private List elementData = new ArrayList();
-	private int size = 0;
-	public void push(Object o){		
-		elementData.add(o);
-		size ++;
-	}
-	
-	public Object pop(){
-		if (size == 0)
-			return null;
-		return elementData.remove(--size);
-	}
-	
-	public Object peek(){
-		if (size == 0)
-			return null;
-		return elementData.get(size - 1);
-	}
-	public boolean isEmpty(){
-		return size == 0;
-	}
-	public int size(){
-		return size;
-	}
-}
+package com.coding.basic;
+
+public class Stack {
+	private List elementData = new ArrayList();
+	private int size = 0;
+	public void push(Object o){		
+		elementData.add(o);
+		size ++;
+	}
+	
+	public Object pop(){
+		if (size == 0)
+			return null;
+		return elementData.remove(--size);
+	}
+	
+	public Object peek(){
+		if (size == 0)
+			return null;
+		return elementData.get(size - 1);
+	}
+	public boolean isEmpty(){
+		return size == 0;
+	}
+	public int size(){
+		return size;
+	}
+}
diff --git a/group05/1094051862/test01/src/com/coding/basic/StackTest.java b/group05/1094051862/test01/src/com/coding/basic/StackTest.java
index adcb2c6522..e3eabe44a1 100644
--- a/group05/1094051862/test01/src/com/coding/basic/StackTest.java
+++ b/group05/1094051862/test01/src/com/coding/basic/StackTest.java
@@ -1,26 +1,26 @@
-package com.coding.basic;
-
-import static org.junit.Assert.*;
-import junit.framework.Assert;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class StackTest {
-
-	@Test
-	public void test() {
-		Stack stack = new Stack();
-		for (int i = 0; i < 100; i++) {
-			stack.push(i);
-		}
-		Assert.assertEquals(100, stack.size());
-		Assert.assertEquals(99, stack.pop());
-		for (int i = 98; i >= 0; i--) {
-			Assert.assertEquals(i, stack.peek());
-			Assert.assertEquals(i, stack.pop());
-		}
-		Assert.assertEquals(0, stack.size());
-	}
-
-}
+package com.coding.basic;
+
+import static org.junit.Assert.*;
+import junit.framework.Assert;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class StackTest {
+
+	@Test
+	public void test() {
+		Stack stack = new Stack();
+		for (int i = 0; i < 100; i++) {
+			stack.push(i);
+		}
+		Assert.assertEquals(100, stack.size());
+		Assert.assertEquals(99, stack.pop());
+		for (int i = 98; i >= 0; i--) {
+			Assert.assertEquals(i, stack.peek());
+			Assert.assertEquals(i, stack.pop());
+		}
+		Assert.assertEquals(0, stack.size());
+	}
+
+}
diff --git a/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java
new file mode 100644
index 0000000000..3788724596
--- /dev/null
+++ b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrame.java
@@ -0,0 +1,129 @@
+package com.coding.lru;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		
+		if (first == null) {
+			accessFirst(pageNum);
+			return;
+		}
+		if (capacity > 0) {  
+			accessNormally(pageNum);
+			capacity --;
+		} else {
+			Node node = first;
+			while(node != null) {
+				
+				if (node.pageNum == pageNum) {
+					accessNodeExisting(node);
+					return;
+				}
+				
+				node = node.next;
+			}
+			
+			accessNormally(pageNum);
+			
+			removeLast();
+		}
+		
+	}
+
+	private void accessNodeExisting(Node node) {
+		if (node.next == null) {  //最后一个元素为要添加的元素
+			removeLast();          
+			exchangeFirstWithNode(node);
+		} else if (node.prev != null) {  //要添加的元素在中间
+			Node n = node.next;
+			Node p = node.prev;
+			p.next = n;
+			n.prev = p;
+			
+			exchangeFirstWithNode(node);
+		}
+	}
+
+	private void exchangeFirstWithNode(Node node) {
+		node.next = first;
+		first.prev = node;
+		node.prev = null;	//忘记这个就会导致找不到第一个添加的元素，测试出现堆溢出
+		first = node;
+	}
+
+	private void removeLast() {
+		last = last.prev;
+		last.next = null;
+	}
+
+	private void accessNormally(int pageNum) {
+		
+		Node temp = first;
+		first = new Node();
+		first.pageNum = pageNum;
+		first.next = temp;
+		temp.prev = first;
+		
+	}
+
+	private void accessFirst(int pageNum) {
+		
+		first = new Node();
+		first.pageNum = pageNum;
+		last = first;
+		capacity --;
+		
+	}
+	
+	
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+			
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java
new file mode 100644
index 0000000000..5f56d9483f
--- /dev/null
+++ b/group05/1094051862/test01/src/com/coding/lru/LRUPageFrameTest.java
@@ -0,0 +1,38 @@
+package com.coding.lru;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		System.out.println(frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+		System.out.println(frame.toString());
+	}
+
+}
diff --git a/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java b/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..a15237f0cb
--- /dev/null
+++ b/group05/284422826/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,46 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+public class ClassFileLoader {
+
+    private List<String> clzPaths = new ArrayList<>();
+
+    public byte[] readBinaryCode(String className) {
+        String name = this.getClassPath() + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
+        File file = new File(name);
+        byte[] bytes = new byte[(int)file.length()];
+        try {
+            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+            while (bis.read(bytes) != -1) {
+                System.out.println(Arrays.toString(bytes));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return bytes;
+    }
+
+
+    public void addClassPath(String path) {
+        clzPaths.add(path);
+    }
+
+
+    public String getClassPath() {
+        StringBuilder path = new StringBuilder();
+        for (String str : clzPaths) {
+            path.append(str).append(";");
+        }
+        return path.substring(0, path.length() - 1);
+    }
+
+
+}
diff --git a/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..ca669de57a
--- /dev/null
+++ b/group05/284422826/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,74 @@
+package com.coderising.jvm.test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClassFileloaderTest {
+	static String path1 = "D:\\git\\coding2017\\group05\\284422826\\bin";
+	static String path2 = "C:\\temp";
+
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+
+	private String byteToHexString(byte[] codes ){
+		StringBuilder buffer = new StringBuilder();
+		for (byte b : codes) {
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if (strHex.length() < 2) {
+				strHex = "0" + strHex;
+			}
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java b/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group05/284422826/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group05/284422826/src/com/coding2017/basic/Queue.java b/group05/284422826/src/com/coding2017/basic/Queue.java
index 57d63f43bf..0148cc7c38 100644
--- a/group05/284422826/src/com/coding2017/basic/Queue.java
+++ b/group05/284422826/src/com/coding2017/basic/Queue.java
@@ -1,5 +1,7 @@
 package com.coding2017.basic;
 
+import com.coding2017.basic.linklist.LinkedList;
+
 import java.util.EmptyStackException;
 
 public class Queue {
diff --git a/group05/284422826/src/com/coding2017/basic/ArrayList.java b/group05/284422826/src/com/coding2017/basic/array/ArrayList.java
similarity index 100%
rename from group05/284422826/src/com/coding2017/basic/ArrayList.java
rename to group05/284422826/src/com/coding2017/basic/array/ArrayList.java
diff --git a/group05/284422826/src/com/coderising/array/ArrayUtil.java b/group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java
similarity index 100%
rename from group05/284422826/src/com/coderising/array/ArrayUtil.java
rename to group05/284422826/src/com/coding2017/basic/array/ArrayUtil.java
diff --git a/group05/284422826/src/com/coderising/array/ArrayUtilTest.java b/group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java
similarity index 100%
rename from group05/284422826/src/com/coderising/array/ArrayUtilTest.java
rename to group05/284422826/src/com/coding2017/basic/array/ArrayUtilTest.java
diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..d43bbc13d7
--- /dev/null
+++ b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,113 @@
+package com.coding2017.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ *
+ * @author liuxin
+ */
+public class LRUPageFrame {
+    private static class Node {
+        Node prev;
+        Node next;
+        int pageNum;
+
+        Node() {
+        }
+    }
+
+    private int capacity;
+
+    private Node first;// 链表头
+    private Node last;// 链表尾
+
+    private int size = 0;
+
+    public LRUPageFrame(int capacity) {
+        this.capacity = capacity;
+    }
+
+    /**
+     * 获取缓存中对象
+     *
+     * @param pageNum
+     * @return
+     */
+    public void access(int pageNum) {
+        if (size < capacity) {
+            Node node = new Node();
+            node.pageNum = pageNum;
+            if (first == null && last == null) {
+                node.prev = null;
+                node.next = null;
+                first = node;
+                last = node;
+            } else {
+                if (last.prev == null) {
+                    last.prev = node;
+                    node.next = last;
+                } else {
+                    assert first != null;
+                    first.prev = node;
+                    node.next = first;
+                }
+                node.prev = null;
+                first = node;
+            }
+            size++;
+        } else {
+            Node node = last;
+            while (node != null) {
+                if (pageNum == node.pageNum) {
+                    Node temp = node;
+                    if(node == last){
+                        last = last.prev;
+                        last.prev = temp.prev.prev;
+                        last.next = null;
+                    }else if(node == first){
+                        first = temp.next;
+                        first.prev = null;
+                        first.next = temp.next.next;
+                    }else{
+                        node.next.prev = temp.prev;
+                        node.prev.next = temp.next;
+                    }
+                    temp = null;
+                    break;
+                }
+                node = node.prev;
+            }
+
+            if(node == null){
+                Node temp = last;
+                last = last.prev;
+                last.prev = temp.prev.prev;
+                last.next = null;
+                temp = null;
+            }
+
+            Node newNode = new Node();
+            newNode.pageNum = pageNum;
+            first.prev = newNode;
+            newNode.prev = null;
+            newNode.next = first;
+            first = newNode;
+
+        }
+
+    }
+
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        Node node = first;
+        while (node != null) {
+            buffer.append(node.pageNum);
+
+            node = node.next;
+            if (node != null) {
+                buffer.append(",");
+            }
+        }
+        return buffer.toString();
+    }
+
+}
diff --git a/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..7e0e79767c
--- /dev/null
+++ b/group05/284422826/src/com/coding2017/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package com.coding2017.basic.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group05/284422826/src/com/coding2017/basic/LinkedList.java b/group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java
similarity index 98%
rename from group05/284422826/src/com/coding2017/basic/LinkedList.java
rename to group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java
index fbc92ff474..e1dce5568c 100644
--- a/group05/284422826/src/com/coding2017/basic/LinkedList.java
+++ b/group05/284422826/src/com/coding2017/basic/linklist/LinkedList.java
@@ -1,4 +1,7 @@
-package com.coding2017.basic;
+package com.coding2017.basic.linklist;
+
+import com.coding2017.basic.Iterator;
+import com.coding2017.basic.List;
 
 import java.util.Arrays;
 import java.util.NoSuchElementException;
diff --git a/group05/289326186/src/com/coderising/download/DownloadThread.java b/group05/289326186/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..9690e741a2
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,35 @@
+package com.coderising.download;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import com.coderising.download.api.Connection;
+
+public class DownloadThread extends Thread{
+
+	Connection conn;
+	int startPos;
+	int endPos;
+
+	public DownloadThread( Connection conn, int startPos, int endPos){
+		
+		this.conn = conn;		
+		this.startPos = startPos;
+		this.endPos = endPos;
+	}
+	public void run(){	
+		try {
+			byte[] b = conn.read(startPos, endPos);
+			String path = "D:" + File.separator + "test"+File.separator+"123.jpg";
+			RandomAccessFile f = new RandomAccessFile(path, "rw");
+			f.seek(startPos);
+			f.write(b);
+			f.close();
+			System.out.println(Thread.currentThread().getName()+"线程下载完毕");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+	}
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/FileDownloader.java b/group05/289326186/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..d8a37c3abe
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,104 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+
+public class FileDownloader {
+	
+	String url;
+	
+	DownloadListener listener;
+	
+	ConnectionManager cm;
+	
+	int threadCount = 3;
+	
+	private DownloadThread[] threads = new DownloadThread[threadCount];
+	
+	int length = 0;//文件总长度
+
+	public FileDownloader(String _url) {
+		this.url = _url;
+		
+	}
+	
+	public void execute(){
+		// 在这里实现你的代码， 注意： 需要用多线程实现下载
+		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// 具体的实现思路：
+		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 3. 把byte数组写入到文件中
+		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+		
+		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		Connection conn = null;
+		try {
+			
+			conn = cm.open(this.url);
+			
+			length = conn.getContentLength();	
+			System.out.println("length:"+length);
+			
+			//计算每个线程需要下载的文件大小
+			int perLen = 0;
+			int lastLen = 0;
+			int tail = length % threadCount;
+			perLen = length/threadCount;
+			if(tail == 0){
+				lastLen = perLen;
+			}else{
+				lastLen = perLen + tail;
+			}
+			for(int i=0; i<threads.length; i++){
+				if(i == threads.length -1){
+					int startPos = perLen * i;
+					threads[i] = new DownloadThread(conn, startPos, startPos+lastLen);
+					threads[i].start();
+				}else{
+					int startPos = perLen * i;
+					threads[i] = new DownloadThread(conn, startPos, startPos+perLen);
+					threads[i].start();
+				}
+			}
+		} catch (ConnectionException e) {			
+			e.printStackTrace();
+		}finally{
+			if(conn != null){
+				conn.close();
+			}
+		}
+		
+	}
+	
+	public void setListener(DownloadListener downloadListener) {
+		this.listener = downloadListener;
+	}
+
+	
+	
+	public void setConnectionManager(ConnectionManager ucm){
+		this.cm = ucm;
+	}
+	
+	public DownloadListener getListener(){
+		return this.listener;
+	}
+	
+	public boolean isFinished(){
+		int sumSize = 0;
+		for(int i=0; i<threads.length; i++){
+			int currentSize = threads[i].endPos - threads[i].startPos;
+			sumSize += currentSize;
+		}
+		return sumSize==length;
+	}
+	
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/FileDownloaderTest.java b/group05/289326186/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..c249911841
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,56 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	
+	boolean downloadFinished = false;
+	
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+//		String url = "http://localhost:8080/haha.jpg";
+		String url = "http://article.fd.zol-img.com.cn/t_s501x2000/g1/M07/0C/0D/Cg-4jVOpQWmIVPnYAAHFv0U3gXkAAOjOwAtyyUAAcXX661.jpg";
+		FileDownloader downloader = new FileDownloader(url);
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+		});
+		
+		//执行下载
+		downloader.execute();
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+			    if(downloader.isFinished()){
+	                downloader.listener.notifyFinished();
+	            }
+				System.out.println("还没有下载完成，休眠5秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("----下载完毕----");
+	}
+
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/api/Connection.java b/group05/289326186/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..cebc046f39
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/api/ConnectionException.java b/group05/289326186/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..c9ea6f71ed
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/api/ConnectionManager.java b/group05/289326186/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..5d255abd8f
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/api/DownloadListener.java b/group05/289326186/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..64ac13231b
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/impl/ConnectionImpl.java b/group05/289326186/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..717201482b
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,46 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection{
+	
+	URLConnection conn;
+	
+	public ConnectionImpl(URLConnection conn){
+		this.conn = conn;
+	}
+
+	@Override
+	public byte[] read(int startPos, int endPos) throws IOException {
+		InputStream is = null;
+		ByteArrayOutputStream bos = null;
+		conn.connect();
+		is = conn.getInputStream();
+		bos = new ByteArrayOutputStream();
+		int len = endPos - startPos;
+		byte[] b = new byte[len];
+		while((len = is.read(b)) != -1) {
+            bos.write(b, 0, len);
+        }
+		bos.flush();
+		is.close();
+		bos.close();
+		return bos.toByteArray();
+	}
+
+	@Override
+	public int getContentLength() {
+		return conn.getContentLength();
+	}
+
+	@Override
+	public void close() {
+		
+	}
+
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group05/289326186/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..9f12994fd8
--- /dev/null
+++ b/group05/289326186/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,29 @@
+package com.coderising.download.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		ConnectionImpl connection = null;
+		URL u = null;
+		URLConnection conn = null;
+		try {
+			u = new URL(url);
+			conn = u.openConnection();
+			connection = new ConnectionImpl(conn);
+			return connection;
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/group05/289326186/src/com/coderising/litestruts/Struts.java b/group05/289326186/src/com/coderising/litestruts/Struts.java
index de7474534e..2603852e74 100644
--- a/group05/289326186/src/com/coderising/litestruts/Struts.java
+++ b/group05/289326186/src/com/coderising/litestruts/Struts.java
@@ -56,7 +56,7 @@ public static View runAction(String actionName, Map<String, String> parameters)
 						String key = entry.getKey();
 						if(pd.getName().equals(key)){
 							Method setMethod = pd.getWriteMethod();//获得set方法
-							setMethod .invoke(obj, entry.getValue());//调用
+							setMethod.invoke(obj, entry.getValue());//调用
 							break;
 						}
 					}
@@ -65,23 +65,14 @@ public static View runAction(String actionName, Map<String, String> parameters)
 		        Method method = clazz.getMethod("execute", null);
 		        Object result = method.invoke(obj);
 		        Map<String, String> map = new HashMap<String, String>();
-		        if("success".equals(result)){
-		        	map.put("message", "login successful");
-		        }else{
-		        	map.put("message", "login failed,please check your user/pwd");
-		        }
 		        // 3. 通过反射找到对象的所有getter方法（例如 getMessage）,
 				// 通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
 				// 放到View对象的parameters
 		        for(PropertyDescriptor pd : pds){
-					for (Entry<String, String> entry : parameters.entrySet()) {
-						String key = entry.getKey();
-						if(pd.getName().equals(key)){
-							Method getMethod = pd.getReadMethod();//获得get方法
-							Object getresult = getMethod .invoke(obj);//调用
-							map.put(pd.getName(), getresult.toString());
-							break;
-						}
+					Method getMethod = pd.getReadMethod();//获得get方法
+					Object getresult = getMethod.invoke(obj);//调用
+					if(!"class".equals(pd.getName())){
+						map.put(pd.getName(), getresult.toString());
 					}
 				}
 		        view.setParameters(map);
diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java b/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java
index b4d218399f..3c13facd32 100644
--- a/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java
+++ b/group12/2258659044/zj-2017/src/com/coderising/download/DownloadThread.java
@@ -1,8 +1,6 @@
 package com.coderising.download;
 
 import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.RandomAccessFile;
 
@@ -31,35 +29,6 @@ public DownloadThread(String downloadPath, Connection conn, int startPos,
 		this.endPos = endPos;
 	}
 
-	/**
-	 * 这种操作存在弊端，
-	 * 若文件过大，调用conn.read读取过程中程序中断
-	 * 将无法缓存任何数据
-	 */
-	/*public void run() {
-
-		try {
-			
-			//请求服务器下载部分文件 指定文件的位置 读取指定位子的字节
-			byte[] buffer = conn.read(startPos, endPos);
-			//随机访问文件流
-			RandomAccessFile raf = new RandomAccessFile(tempFile, "rwd");  
-			//随机写文件的时候从哪个位置开始写  
-			raf.seek(startPos);//定位文件 
-			//写文件
-			raf.write(buffer);
-			raf.close();
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		} finally {
-			if (conn != null) {
-				conn.close();
-			}
-		}
-	}*/
-	
 	public void run() {
 
 		try {
@@ -75,8 +44,8 @@ public void run() {
 			tempFile = file;
 			//获取指定文件段的下载流
 			InputStream in = conn.getDownloadStream(startPos, endPos);
-			if(in == null){
-				return;
+			if(in == null){//重新请求连接
+				run();
 			}
 			//随机访问文件流
 			RandomAccessFile raf = new RandomAccessFile(tempFile, "rwd"); 
@@ -90,10 +59,9 @@ public void run() {
 	        	downloadSize += length;
 	        }	 
 			raf.close();
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
+		} catch (Exception e) {
+			run();
+			e.printStackTrace();			
 		} finally {
 			if (conn != null) {
 				conn.close();
diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java b/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java
index cb84d148c7..721f2c77e0 100644
--- a/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java
+++ b/group12/2258659044/zj-2017/src/com/coderising/download/FileDownloader.java
@@ -31,18 +31,7 @@ public void execute(){
 			conn = cm.open(this.url);			
 			int length = conn.getContentLength();			
 			//分配下载块
-			int blockSize = length / threadNum;
-			DownloadThread[] threads = new DownloadThread[threadNum];
-			for (int thread = 1; thread <= threadNum; thread++) {				
-                int startIndex = (thread - 1) * blockSize;  
-                int endIndex = thread * blockSize-1;  
-                if (thread == threadNum) {//最后一个线程下载的长度
-                    endIndex = length;  
-                }                   
-                DownloadThread thr = new DownloadThread(downloadPath,cm.open(this.url),startIndex,endIndex);
-                threads[thread-1] = thr;
-                thr.start();
-            }
+			DownloadThread[] threads = assignDownloadPart(length);
 			//判断所有线程是否下载完成
 			new NotifyCaller(listener,threads,length).start();
 			
@@ -54,6 +43,29 @@ public void execute(){
 			}
 		}								
 	}
+
+	/**
+	 * 分配下载块并启动下载
+	 * @param length
+	 * @return
+	 * @throws ConnectionException
+	 */
+	private DownloadThread[] assignDownloadPart(int length)
+			throws ConnectionException {
+		int blockSize = length / threadNum;
+		DownloadThread[] threads = new DownloadThread[threadNum];
+		for (int thread = 1; thread <= threadNum; thread++) {				
+		    int startIndex = (thread - 1) * blockSize;  
+		    int endIndex = thread * blockSize-1;  
+		    if (thread == threadNum) {//最后一个线程下载的长度
+		        endIndex = length;  
+		    }                   
+		    DownloadThread thr = new DownloadThread(downloadPath,cm.open(this.url),startIndex,endIndex);
+		    threads[thread-1] = thr;
+		    thr.start();
+		}
+		return threads;
+	}
 		
 	public void setListener(DownloadListener listener) {
 		this.listener = listener;
diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java b/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java
index 03f4149688..df49a92a07 100644
--- a/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java
+++ b/group12/2258659044/zj-2017/src/com/coderising/download/NotifyCaller.java
@@ -65,7 +65,7 @@ private String getDownloadSpeed(int timeDiff){
         if(num==null||num.isEmpty()){
         	num = "0";
         }
-    	return num+"M/s";
+    	return num+"Mb/s";
     }
     
     /**
diff --git a/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java b/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java
index ec8e503fe9..8f5a0a8757 100644
--- a/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java
+++ b/group12/2258659044/zj-2017/src/com/coderising/download/impl/ConnectionImpl.java
@@ -7,7 +7,7 @@
 
 import com.coderising.download.api.Connection;
 
-public class ConnectionImpl implements Connection{
+class ConnectionImpl implements Connection{
 
 	/*http连接*/
 	private HttpURLConnection httpConnection;
@@ -18,19 +18,8 @@ public class ConnectionImpl implements Connection{
 	@Override
 	public byte[] read(int startPos, int endPos) throws IOException {
 
-		byte[] data = null;
 		InputStream is = getDownloadStream(startPos,endPos);		
-		if(is !=null){
-			ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
-	        byte[] buffer = new byte[1024]; 
-	        int length = -1; 
-	        while ((length = is.read(buffer)) != -1) { 
-	            baos.write(buffer, 0, length); 
-	        } 
-	        baos.flush();
-	        data = baos.toByteArray(); 		
-		}
-        return data;
+		return inputStremCovertToArray(is);
 	}
 
 	@Override
@@ -53,6 +42,27 @@ public void close() {
 		httpConnection.disconnect();
 	}
 	
+	/**
+	 * 将输入流转换为byte数组
+	 * @param is
+	 * @return
+	 * @throws IOException
+	 */
+	private byte[] inputStremCovertToArray(InputStream is) throws IOException{
+		
+		byte[] data = null;	
+		if(is !=null){
+			ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+	        byte[] buffer = new byte[1024]; 
+	        int length = -1; 
+	        while ((length = is.read(buffer)) != -1) { 
+	            baos.write(buffer, 0, length); 
+	        } 
+	        baos.flush();
+	        data = baos.toByteArray(); 		
+		}
+        return data;
+	}
 	public void setHttpConnection(HttpURLConnection httpConnection) {
 		this.httpConnection = httpConnection;
 	}
diff --git a/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..59d12540fc
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,33 @@
+package com.coderising.jvm.loader;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		
+		File clzFile = ClassFileLoaderUtil.getClzFile(clzPaths,className);
+        		
+		return ClassFileLoaderUtil.readClz(clzFile);	
+				
+	}
+		
+	public void addClassPath(String path) {
+		
+		this.clzPaths.add(path);
+	}
+			
+	public String getClassPath(){
+		
+		StringBuffer buff = new StringBuffer();
+		for (String str : clzPaths) {
+			buff.append(str+";");
+		}		
+		return buff.substring(0, buff.length()-1);
+	}
+
+}
diff --git a/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java
new file mode 100644
index 0000000000..61faafb77d
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/com/coderising/jvm/loader/ClassFileLoaderUtil.java
@@ -0,0 +1,71 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+public class ClassFileLoaderUtil {
+
+	/**
+	 * 根据类完整包名与classPath获取类class文件
+	 * @return
+	 */
+	public static File getClzFile(List<String> clzPaths ,String className){
+		
+		File clazFile = null;
+		//将com.zj.className 转化为 com\\zj\\className.class;
+		if(className!=null){
+			className = className.replace(".", "\\")+".class";
+		}
+		//寻找文件所在目录
+		for (String clzPath : clzPaths) {
+			clazFile = new File(clzPath+"\\"+className);
+			if(clazFile.exists()){
+				break;
+			}
+		}
+		return clazFile;
+	}
+	
+	/**
+	 * 读取文件并返回该文件的字节数组
+	 * @param clzFile
+	 * @return
+	 */
+	public static byte[] readClz(File file){
+		
+		byte[] data = null;
+		InputStream is = null;
+		ByteArrayOutputStream baos = null;
+		try {			
+			is = new FileInputStream(file);	
+			if(is !=null){
+				baos = new ByteArrayOutputStream(); 
+			    byte[] buffer = new byte[1024]; 
+			    int length = -1; 
+			    while ((length = is.read(buffer)) != -1) { 
+			        baos.write(buffer, 0, length); 
+			    } 
+			    baos.flush();
+			    data = baos.toByteArray(); 		
+			}		
+		} catch (Exception e) {
+			e.printStackTrace();
+		}finally{
+			try {
+				if(baos!=null){
+					baos.close();
+				}
+				if(is!=null){
+					is.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		return data;
+	}
+}
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java b/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java
index 3449517197..0b8eafc282 100644
--- a/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/BinaryTree.java
@@ -1,64 +1,66 @@
-package com.coding.basic;
-
-public class BinaryTree {
-	
-	//根节点
-	private BinaryTreeNode root;	
-	    
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public <T extends Comparable<? super T>> BinaryTreeNode insert(T o){
-		
-		BinaryTreeNode treeNode = new BinaryTreeNode();
-		treeNode.setData(o);
-		if(root == null){
-			root =  treeNode;
-		}else{				
-			BinaryTreeNode currentNode = root;
-			BinaryTreeNode parent;
-			while(true){
-				parent = currentNode;
-				if(((Comparable)currentNode.getData()).compareTo(o)>0){//向左放					
-					currentNode = currentNode.getLeft();
-					if(currentNode == null){
-						parent.setLeft(treeNode);
-						treeNode.setParent(parent);
-						break;
-					}					
-				}else{//向右放
-					currentNode = currentNode.getRight();
-					if(currentNode == null){
-						parent.setRight(treeNode);
-						treeNode.setParent(parent);
-						break;
-					}
-				}
-			}			
-		}
-		return treeNode;
-	}
-
-	/**
-	 * 先序遍历
-	 * @param node
-	 * @return
-	 */
-	public List traversalBefore(BinaryTreeNode node){
-		//所有数据集合
-	    List datas = new ArrayList();
-	    return traversal(node,datas);
-	}
-	private List traversal(BinaryTreeNode node,List datas){
-		
-		if(node !=null){
-			datas.add(node.getData());
-			traversal(node.getLeft(),datas);
-			traversal(node.getRight(),datas);
-		}
-		return datas;
-	}
-
-	public BinaryTreeNode getRoot() {
-		return root;
-	}
-		
-}
+package com.coding.basic;
+
+import com.coding.basic.array.ArrayList;
+
+public class BinaryTree {
+	
+	//根节点
+	private BinaryTreeNode root;	
+	    
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public <T extends Comparable<? super T>> BinaryTreeNode insert(T o){
+		
+		BinaryTreeNode treeNode = new BinaryTreeNode();
+		treeNode.setData(o);
+		if(root == null){
+			root =  treeNode;
+		}else{				
+			BinaryTreeNode currentNode = root;
+			BinaryTreeNode parent;
+			while(true){
+				parent = currentNode;
+				if(((Comparable)currentNode.getData()).compareTo(o)>0){//向左放					
+					currentNode = currentNode.getLeft();
+					if(currentNode == null){
+						parent.setLeft(treeNode);
+						treeNode.setParent(parent);
+						break;
+					}					
+				}else{//向右放
+					currentNode = currentNode.getRight();
+					if(currentNode == null){
+						parent.setRight(treeNode);
+						treeNode.setParent(parent);
+						break;
+					}
+				}
+			}			
+		}
+		return treeNode;
+	}
+
+	/**
+	 * 先序遍历
+	 * @param node
+	 * @return
+	 */
+	public List traversalBefore(BinaryTreeNode node){
+		//所有数据集合
+	    List datas = new ArrayList();
+	    return traversal(node,datas);
+	}
+	private List traversal(BinaryTreeNode node,List datas){
+		
+		if(node !=null){
+			datas.add(node.getData());
+			traversal(node.getLeft(),datas);
+			traversal(node.getRight(),datas);
+		}
+		return datas;
+	}
+
+	public BinaryTreeNode getRoot() {
+		return root;
+	}
+		
+}
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java b/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java
index e29ff65ddf..aa8429ac59 100644
--- a/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/Queue.java
@@ -1,26 +1,28 @@
-package com.coding.basic;
-
-public class Queue {
-	
-	private LinkedList element = new LinkedList();
-	
-	public void enQueue(Object o){	
-		
-		element.add(o);
-	}
-	
-	public Object deQueue(){
-		
-		return element.removeFirst();
-	}
-	
-	public boolean isEmpty(){
-		
-		return element.size()==0;
-	}
-	
-	public int size(){
-		
-		return element.size();
-	}
-}
+package com.coding.basic;
+
+import com.coding.basic.linklist.LinkedList;
+
+public class Queue {
+	
+	private LinkedList element = new LinkedList();
+	
+	public void enQueue(Object o){	
+		
+		element.add(o);
+	}
+	
+	public Object deQueue(){
+		
+		return element.removeFirst();
+	}
+	
+	public boolean isEmpty(){
+		
+		return element.size()==0;
+	}
+	
+	public int size(){
+		
+		return element.size();
+	}
+}
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java b/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java
index 03709097e5..2b08e856c1 100644
--- a/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/Stack.java
@@ -1,28 +1,30 @@
-package com.coding.basic;
-
-public class Stack {
-	
-	private ArrayList elementData = new ArrayList();
-	
-	public void push(Object o){	
-		
-		elementData.add(o);
-	}
-	
-	public Object pop(){
-		
-		return elementData.remove(size()-1);
-	}
-	
-	public Object peek(){
-		
-		return elementData.get(size()-1);
-	}
-	public boolean isEmpty(){
-
-		return size()==0;
-	}
-	public int size(){
-		return elementData.size();
-	}
-}
+package com.coding.basic;
+
+import com.coding.basic.array.ArrayList;
+
+public class Stack {
+	
+	private ArrayList elementData = new ArrayList();
+	
+	public void push(Object o){	
+		
+		elementData.add(o);
+	}
+	
+	public Object pop(){
+		
+		return elementData.remove(size()-1);
+	}
+	
+	public Object peek(){
+		
+		return elementData.get(size()-1);
+	}
+	public boolean isEmpty(){
+
+		return size()==0;
+	}
+	public int size(){
+		return elementData.size();
+	}
+}
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java
similarity index 91%
rename from group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java
rename to group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java
index f1fbf7e8b1..4bbf60adf9 100644
--- a/group12/2258659044/zj-2017/src/com/coding/basic/ArrayList.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayList.java
@@ -1,7 +1,10 @@
-﻿package com.coding.basic;
+﻿package com.coding.basic.array;
 
 import java.util.NoSuchElementException;
 
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
 public class ArrayList implements List {
 	
 	private int size = 0;	
diff --git a/group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java
similarity index 94%
rename from group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java
rename to group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java
index 3f41a350e8..de11fdbca5 100644
--- a/group12/2258659044/zj-2017/src/com/coderising/array/ArrayUtil.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/array/ArrayUtil.java
@@ -1,6 +1,5 @@
-package com.coderising.array;
+package com.coding.basic.array;
 
-import com.coding.basic.ArrayList;
 
 public class ArrayUtil {
 	
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..4d1c587fd3
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,163 @@
+package com.coding.basic.linklist;
+
+
+/**
+ * 用双向链表实现LRU算法
+ * @author ZJ
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		Object obj;
+
+		Node() {
+		}
+	}
+
+	private int capacity;//容量
+	
+	private int size;//已经存放的数量
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(Object obj) {
+		
+		if(obj == null){
+			return;
+		}
+		Node node = getNode(obj);
+		if(node!=null){
+			move2head(node);
+		}else{
+			refresh(obj);
+		}			
+	}
+
+	/**
+	 * 刷新LRU队列
+	 * @param obj
+	 */
+	private void refresh(Object obj) {
+		//添加元素
+		if(size<capacity){
+			add(obj);
+		}else{
+			remove();
+			add(obj);
+		}
+	}
+	
+	/**
+	 * 添加
+	 * @param obj
+	 */
+	private void add(Object obj){
+		
+		Node node = new Node();
+		node.obj = obj;
+		if(first == null){
+			first = node;
+			last = node;
+		}else{
+			node.next = first;
+			node.next.prev = node;
+			first = node;
+		}
+		size++;
+	}
+
+	/**
+	 * 删除
+	 * @return
+	 */
+	private Object remove(){
+		
+		Object obj = last.obj;
+		last = last.prev;
+		last.next = null;
+		size --;
+		return obj;
+	}
+	
+	/**
+	 * 是否存在缓存中
+	 * @param obj
+	 * @return
+	 */
+	@SuppressWarnings("unused")
+	private boolean isExist(Object obj){
+		
+		return getNode(obj)!=null?true:false;
+	}
+	
+	/**
+	 * 获取包含值为obj的节点
+	 * @param obj
+	 * @return
+	 */
+	private Node getNode(Object obj){
+		
+		for (Node node = first; node != null; node = node.next) {
+			if(node.obj.equals(obj)){
+				return node;
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * 将节点置为头结点
+	 * @param obj
+	 */
+	private void move2head(Node node){
+		
+		if(node != null){
+			if(node.equals(first)){//该节点为头结点
+				return;
+			}else if(node.equals(last)){//该节点为尾节点				
+				last = last.prev;
+				last.next = null;
+			}else{
+				node.prev.next = node.next;
+				node.next.prev = node.prev;								
+			}
+			//将本节点置为头结点
+			first.prev = node;
+			node.next = first;
+			first = node;
+		}
+		
+	}
+	
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.obj);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
\ No newline at end of file
diff --git a/group12/2258659044/zj-2017/src/com/coding/basic/LinkedList.java b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LinkedList.java
similarity index 93%
rename from group12/2258659044/zj-2017/src/com/coding/basic/LinkedList.java
rename to group12/2258659044/zj-2017/src/com/coding/basic/linklist/LinkedList.java
index 3bf26a1a1c..0132efaa00 100644
--- a/group12/2258659044/zj-2017/src/com/coding/basic/LinkedList.java
+++ b/group12/2258659044/zj-2017/src/com/coding/basic/linklist/LinkedList.java
@@ -1,7 +1,11 @@
-package com.coding.basic;
+package com.coding.basic.linklist;
 
 import java.util.NoSuchElementException;
 
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+import com.coding.basic.Stack;
+
 public class LinkedList implements List {
 	
 	private Node head;
@@ -180,7 +184,6 @@ public  void remove(int i, int length){
 			if(length<(size-i)){
 				getPointNode(i-1).next = getPointNode(i+length);
 				size = size-length;
-				size = size-length;
 			}else{
 				getPointNode(i-1).next = null;
 				size = i;
diff --git a/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/ClassFileloaderTest.java b/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/ClassFileloaderTest.java
new file mode 100644
index 0000000000..b274338091
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/ClassFileloaderTest.java
@@ -0,0 +1,87 @@
+package test.com.coderising.jvm.loader;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+public class ClassFileloaderTest {
+	
+	static String path1 = "F:\\githubRes\\coding2017\\group12\\2258659044\\zj-2017\\bin";
+	static String path2 = "C:\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "test.com.coderising.jvm.loader.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1070, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "test.com.coderising.jvm.loader.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
\ No newline at end of file
diff --git a/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/EmployeeV1.java b/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/EmployeeV1.java
new file mode 100644
index 0000000000..463fb4a15f
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/test/com/coderising/jvm/loader/EmployeeV1.java
@@ -0,0 +1,28 @@
+package test.com.coderising.jvm.loader;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
diff --git a/group12/2258659044/zj-2017/src/test/com/coding/basic/ArrayListTest.java b/group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayListTest.java
similarity index 91%
rename from group12/2258659044/zj-2017/src/test/com/coding/basic/ArrayListTest.java
rename to group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayListTest.java
index badcb2968f..9c4d91e8b3 100644
--- a/group12/2258659044/zj-2017/src/test/com/coding/basic/ArrayListTest.java
+++ b/group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayListTest.java
@@ -1,109 +1,109 @@
-package test.com.coding.basic;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.coding.basic.ArrayList;
-import com.coding.basic.Iterator;
-
-public class ArrayListTest {
-
-	ArrayList ls ;
-	@Before
-    public void setup() {
-        ls = new ArrayList();       
-    }
-	
-	/**
-	 * 测试一个参数的add方法
-	 * ArrayList当数据超过10时进行第一次扩容
-	 */
-	@Test
-	public void add(){
-		
-		ls.add(3);
-		ls.add("a");
-		for (int i = 0; i < 10; i++) {
-			ls.add(i);
-		}
-		Assert.assertEquals(ls.size(), 12);
-		Assert.assertEquals(ls.get(1), "a");
-	}
-
-	/**
-	 *  两个参数的add方法
-	 */
-	@Test//(expected = IndexOutOfBoundsException.class)
-	public void add4ToPramter(){
-		
-		ls.add(0, 0);
-		ls.add(1,1);
-		ls.add(2, 2);
-		ls.add(3,3);
-		for (int i = 0; i < 10; i++) {
-			ls.add(3,i);
-		}
-		Assert.assertEquals(ls.size(), 14);
-		Assert.assertEquals(ls.get(3), 9);
-		Assert.assertEquals(ls.get(13), 3);
-		//打开下面操作抛出异常
-		//ls.add(15, "a");
-	}
-
-	/**
-	 * get(i)
-	 */
-	@Test//(expected = IndexOutOfBoundsException.class)
-	public void get(){
-		
-		for (int i = 0; i < 10; i++) {
-			ls.add(i);
-		}
-		
-		Assert.assertEquals(ls.get(9), 9);	
-		//打开下面操作抛出异常
-		//ls.get(12);
-	}
-	
-	@Test
-	public void remove(){
-		
-		for (int i = 0; i < 10; i++) {
-			ls.add(i);
-		}	
-		Assert.assertEquals(ls.remove(5),5);
-		Assert.assertEquals(ls.size(),9);
-		Assert.assertEquals(ls.remove(8),9);
-		Assert.assertEquals(ls.size(),8);
-	}
-	
-	@Test
-	public void size(){
-		
-		Assert.assertEquals(ls.size(),0);
-		ls.add("a");
-		Assert.assertEquals(ls.size(),1);
-		ls.add(0,0);
-		Assert.assertEquals(ls.size(),2);
-		ls.remove(0);
-		Assert.assertEquals(ls.size(),1);
-		
-	}
-	
-	@Test//(expected = NoSuchElementException.class)
-	public void iterator(){
-		
-		for (int i = 0; i < 10; i++) {
-			ls.add(i);
-		}
-		Iterator it = ls.iterator();
-		Assert.assertEquals(it.hasNext(),true);
-		for (int i = 0; i < 10; i++) {
-			it.next();
-		}		
-		Assert.assertEquals(it.hasNext(),false);
-		//打开下面操作抛出异常
-		//it.next();
-	}
-}
+package test.com.coding.basic.array;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.array.ArrayList;
+
+public class ArrayListTest {
+
+	ArrayList ls ;
+	@Before
+    public void setup() {
+        ls = new ArrayList();       
+    }
+	
+	/**
+	 * 测试一个参数的add方法
+	 * ArrayList当数据超过10时进行第一次扩容
+	 */
+	@Test
+	public void add(){
+		
+		ls.add(3);
+		ls.add("a");
+		for (int i = 0; i < 10; i++) {
+			ls.add(i);
+		}
+		Assert.assertEquals(ls.size(), 12);
+		Assert.assertEquals(ls.get(1), "a");
+	}
+
+	/**
+	 *  两个参数的add方法
+	 */
+	@Test//(expected = IndexOutOfBoundsException.class)
+	public void add4ToPramter(){
+		
+		ls.add(0, 0);
+		ls.add(1,1);
+		ls.add(2, 2);
+		ls.add(3,3);
+		for (int i = 0; i < 10; i++) {
+			ls.add(3,i);
+		}
+		Assert.assertEquals(ls.size(), 14);
+		Assert.assertEquals(ls.get(3), 9);
+		Assert.assertEquals(ls.get(13), 3);
+		//打开下面操作抛出异常
+		//ls.add(15, "a");
+	}
+
+	/**
+	 * get(i)
+	 */
+	@Test//(expected = IndexOutOfBoundsException.class)
+	public void get(){
+		
+		for (int i = 0; i < 10; i++) {
+			ls.add(i);
+		}
+		
+		Assert.assertEquals(ls.get(9), 9);	
+		//打开下面操作抛出异常
+		//ls.get(12);
+	}
+	
+	@Test
+	public void remove(){
+		
+		for (int i = 0; i < 10; i++) {
+			ls.add(i);
+		}	
+		Assert.assertEquals(ls.remove(5),5);
+		Assert.assertEquals(ls.size(),9);
+		Assert.assertEquals(ls.remove(8),9);
+		Assert.assertEquals(ls.size(),8);
+	}
+	
+	@Test
+	public void size(){
+		
+		Assert.assertEquals(ls.size(),0);
+		ls.add("a");
+		Assert.assertEquals(ls.size(),1);
+		ls.add(0,0);
+		Assert.assertEquals(ls.size(),2);
+		ls.remove(0);
+		Assert.assertEquals(ls.size(),1);
+		
+	}
+	
+	@Test//(expected = NoSuchElementException.class)
+	public void iterator(){
+		
+		for (int i = 0; i < 10; i++) {
+			ls.add(i);
+		}
+		Iterator it = ls.iterator();
+		Assert.assertEquals(it.hasNext(),true);
+		for (int i = 0; i < 10; i++) {
+			it.next();
+		}		
+		Assert.assertEquals(it.hasNext(),false);
+		//打开下面操作抛出异常
+		//it.next();
+	}
+}
diff --git a/group12/2258659044/zj-2017/src/test/com/coderising/array/ArrayUtilTest.java b/group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayUtilTest.java
similarity index 91%
rename from group12/2258659044/zj-2017/src/test/com/coderising/array/ArrayUtilTest.java
rename to group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayUtilTest.java
index ea04dbbf3b..e8303b8aba 100644
--- a/group12/2258659044/zj-2017/src/test/com/coderising/array/ArrayUtilTest.java
+++ b/group12/2258659044/zj-2017/src/test/com/coding/basic/array/ArrayUtilTest.java
@@ -1,10 +1,10 @@
-package test.com.coderising.array;
+package test.com.coding.basic.array;
 
 import org.junit.Assert;
 import org.junit.Test;
 
-import com.coderising.array.ArrayUtil;
-import com.coding.basic.ArrayList;
+import com.coding.basic.array.ArrayList;
+import com.coding.basic.array.ArrayUtil;
 
 public class ArrayUtilTest {
 
diff --git a/group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LRUPageFrameTest.java b/group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..923682a8a6
--- /dev/null
+++ b/group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package test.com.coding.basic.linklist;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.coding.basic.linklist.LRUPageFrame;
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
\ No newline at end of file
diff --git a/group12/2258659044/zj-2017/src/test/com/coding/basic/LinkedListTest.java b/group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LinkedListTest.java
similarity index 93%
rename from group12/2258659044/zj-2017/src/test/com/coding/basic/LinkedListTest.java
rename to group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LinkedListTest.java
index c43e66abf9..9a6e86000e 100644
--- a/group12/2258659044/zj-2017/src/test/com/coding/basic/LinkedListTest.java
+++ b/group12/2258659044/zj-2017/src/test/com/coding/basic/linklist/LinkedListTest.java
@@ -1,11 +1,11 @@
-package test.com.coding.basic;
+package test.com.coding.basic.linklist;
 
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
 import com.coding.basic.Iterator;
-import com.coding.basic.LinkedList;
+import com.coding.basic.linklist.LinkedList;
 
 public class LinkedListTest {
 
diff --git a/group12/247565311/week2/Struts.java b/group12/247565311/week2/Struts.java
index 45658881eb..9c8135be38 100644
--- a/group12/247565311/week2/Struts.java
+++ b/group12/247565311/week2/Struts.java
@@ -18,7 +18,7 @@ public static View runAction(String actionName,Map<String,String>parameters){
 		if(actionName == null || parameters == null) return null;
 		List<Element> actions = null; 
 		try {
-			File xmlfile = new File("D:\\5Java\\coding2017\\group12\\247565311\\week2\\struts.xml");
+			File xmlfile = new File(System.getProperty("user.dir")+"\\bin\\week2\\struts.xml");
 			Document doc = new SAXReader().read(xmlfile);
 			Element root = doc.getRootElement();
 			actions = root.elements();
diff --git a/group12/247565311/week3/DownloadThread.java b/group12/247565311/week3/DownloadThread.java
index 3271ba2e99..2670bef00b 100644
--- a/group12/247565311/week3/DownloadThread.java
+++ b/group12/247565311/week3/DownloadThread.java
@@ -1,24 +1,31 @@
 package week3;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardOpenOption;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
 
 import week3.api.Connection;
 
 public class DownloadThread extends Thread{
 	Connection conn;
+	CyclicBarrier barrier;
 	int startPos;
 	int endPos;
 	String path = "";
-	public DownloadThread( Connection conn, int startPos, int endPos,String filepath){
+	int step = 1024*200; // ÿ200kдһ���ļ�
+	public DownloadThread(CyclicBarrier _barrier, Connection conn, int startPos, int endPos,String filepath){
 		this.conn = conn;		
 		this.startPos = startPos;
 		this.endPos = endPos;
 		this.path = filepath;
+		this.barrier = _barrier;
 	}
 	public void run(){	
 		// ��ȡ���ص��ֽ����飬д���ļ���ע������һ�����̳߳���
@@ -27,27 +34,28 @@ public void run(){
 		// ��connect�����ȡ�ֽ����飬���û���ֽ������ˣ��ͱ�ʾ�ⲿ���������
 		// ��filepathд�ļ�
 		if(conn == null) return;
-		ByteBuffer buffer = ByteBuffer.allocate(endPos-startPos);
-		Path filepath = Paths.get(path);
-
-		if(filepath == null) return;
 		int curEndPos = startPos;
-	//	while(curEndPos<endPos){
+		while(curEndPos<endPos){
 			startPos = curEndPos;
-			curEndPos += 4096;
-			//if (curEndPos > endPos) 
+			curEndPos += step;
+			if (curEndPos > endPos) 
 				curEndPos = endPos;
 			try {
 				byte[] data = conn.read(startPos, curEndPos);
-				FileChannel channel = FileChannel.open(filepath,StandardOpenOption.WRITE);
-				// System.out.println("startPos"+startPos + ", length:"+data.length);
-				buffer.put(data);
-                channel.write(buffer);
+				RandomAccessFile files = new RandomAccessFile(path,"rw");
+				files.seek(startPos);
+				files.write(data);
+				files.close();
+				System.out.println("startPos"+startPos + ", length:"+data.length);
 			} catch (IOException e) {
-				//e.printStackTrace();
-				System.out.println("д�ļ�����");
+				e.printStackTrace();
 			}
-	//	}
+		}
 		conn.close();
+		try {
+			barrier.await();
+		} catch (InterruptedException | BrokenBarrierException e) {
+			e.printStackTrace();
+		}
 	}
 }
diff --git a/group12/247565311/week3/FileDownloader.java b/group12/247565311/week3/FileDownloader.java
index c5ab5fb5d0..1a426c3682 100644
--- a/group12/247565311/week3/FileDownloader.java
+++ b/group12/247565311/week3/FileDownloader.java
@@ -1,6 +1,5 @@
 package week3;
-
-import java.io.FileNotFoundException;
+import java.util.concurrent.CyclicBarrier;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
@@ -11,6 +10,7 @@
 import week3.impl.ConnectionManagerImpl;
 
 public class FileDownloader {
+	private int MaxThreadNum = 4;
 	private String url = null,path=null;
 	DownloadListener listener = null;
 	private ConnectionManager cm = new ConnectionManagerImpl();
@@ -20,7 +20,7 @@ public FileDownloader(String weburl,String localpath) {
 		this.path = localpath;
 	}
 	
-	public void execute(){
+	public void execute() throws InterruptedException{
 		// 在这里实现你的代码， 注意： 需要用多线程实现下载
 		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
 		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
@@ -35,6 +35,11 @@ public void execute(){
 		
 		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
 		Connection conn = null;
+		CyclicBarrier barr= new CyclicBarrier(MaxThreadNum,new Runnable(){
+			public void run(){
+				listener.notifyFinished();
+			}
+		});
 		try {
 			conn = cm.open(this.url);
 			int length = conn.getContentLength();	
@@ -43,18 +48,13 @@ public void execute(){
 			tarfile.setLength(length);
 			tarfile.close();
 			Thread[] threads = new Thread[4];
-			threads[0] = new DownloadThread(cm.open(this.url),0,length/4,path);
-			threads[1] = new DownloadThread(cm.open(this.url),length/4,length/2,path);
-		    threads[2] = new DownloadThread(cm.open(this.url),length/2,3*length/4,path);
-		    threads[3] = new DownloadThread(cm.open(this.url),3*length/4,length,path);
+			threads[0] = new DownloadThread(barr,cm.open(this.url),0,length/4,path);
+			threads[1] = new DownloadThread(barr,cm.open(this.url),length/4,length/2,path);
+		    threads[2] = new DownloadThread(barr,cm.open(this.url),length/2,3*length/4,path);
+		    threads[3] = new DownloadThread(barr,cm.open(this.url),3*length/4,length,path);
 			for(int i=0;i<4;i++)
 			    threads[i].start();
-			threads[0].join();
-			threads[1].join();
-			threads[2].join();
-			threads[3].join();
-			this.getListener().notifyFinished();
-		} catch (ConnectionException | IOException | InterruptedException e) {
+		} catch (ConnectionException | IOException e) {
 			e.printStackTrace();
 		}finally{
 			if(conn != null){
@@ -71,4 +71,7 @@ public void setConnectionManager(ConnectionManager ucm){
 	public DownloadListener getListener(){
 		return this.listener;
 	}
+	public double getDownPercent(){
+		return 0.0;
+	}
 }
diff --git a/group12/247565311/week3/FileDownloaderTest.java b/group12/247565311/week3/FileDownloaderTest.java
index 96893b71e9..3c729218d3 100644
--- a/group12/247565311/week3/FileDownloaderTest.java
+++ b/group12/247565311/week3/FileDownloaderTest.java
@@ -19,8 +19,8 @@ public void tearDown() throws Exception {
 
 	@Test
 	public void testDownload() {
-		String url = "https://edmullen.net/test/rc.jpg";
-		String path = "D:\\hellp.jpg";
+		String url = "http://music.163.com/api/pc/download/latest";
+		String path = "D:\\hellp.exe";
 		FileDownloader downloader = new FileDownloader(url,path);
 		ConnectionManager cm = new ConnectionManagerImpl();
 		downloader.setConnectionManager(cm);
@@ -30,16 +30,21 @@ public void notifyFinished() {
 				downloadFinished = true;
 			}
 		});
-		downloader.execute();
-		// 等待多线程下载程序执行完毕
+		double time = 0;
+		try {
+			downloader.execute();
+		} catch (InterruptedException e1) {
+			e1.printStackTrace();
+		}
 		while (!downloadFinished) {
 			try {
-				System.out.println("还没有下载完成，休眠五秒");
-				Thread.sleep(5000);//休眠5秒
+				Thread.sleep(100);//休眠0.1秒
+				
+				time += 1;
 			} catch (InterruptedException e) {				
 				e.printStackTrace();
 			}
 		}
-		System.out.println("下载完成！");
+		System.out.println("下载完成！耗时："+time/10.0+" 秒。");
 	}
 }
diff --git a/group12/247565311/week3/impl/ConnectionImpl.java b/group12/247565311/week3/impl/ConnectionImpl.java
index bdd28aa4ec..7173caf56d 100644
--- a/group12/247565311/week3/impl/ConnectionImpl.java
+++ b/group12/247565311/week3/impl/ConnectionImpl.java
@@ -1,43 +1,65 @@
 package week3.impl;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
 
 import week3.api.Connection;
 
 public class ConnectionImpl   implements Connection{
-	HttpURLConnection conn = null;
+	URL url = null;
+	public ConnectionImpl(String str){
+		try {
+			url = new URL(str);
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		}
+	}
 	// ��������Ҫ������ִ�����أ���ȡ�ֽ�����
 	// ����ฺ��򿪡��ر���������
 	@Override
-	public byte[] read(int startPos, int endPos) throws IOException {
-		if(conn == null || startPos>=endPos) return null;
+	public byte[] read(int startPos, int endPos)  {
+		HttpURLConnection conn = null;
 		byte[]res = null;
-		conn.setRequestProperty("Range","bytes="+startPos+"-"+endPos);
-		int responcode = conn.getResponseCode();
-		if(200 < responcode && responcode < 300){
-			InputStream input = conn.getInputStream();
-			res = new byte[endPos-startPos];
-			input.read(res);
-			input.close();
+		try {
+			conn = (HttpURLConnection) url.openConnection();
+			conn.setRequestProperty("Range","bytes="+startPos+"-"+endPos);
+			int responcode = conn.getResponseCode();
+			if(200 < responcode && responcode < 300){
+				InputStream input = conn.getInputStream();
+				ByteArrayOutputStream output = new ByteArrayOutputStream();
+				res = new byte[2048];
+				while(output.size()<endPos - startPos){
+					int len = input.read(res);
+					if(len>0)output.write(res,0,len);
+					else break;
+				}
+				return Arrays.copyOf(output.toByteArray(), endPos-startPos);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
 		}
-		conn.disconnect();
+		if(conn!=null) conn.disconnect();
 		return res;
 	}
 
 	@Override
 	public int getContentLength() {
-		if(conn == null) return 0;
-		return conn.getContentLength();
+		try{
+			URLConnection con = url.openConnection();
+			return con.getContentLength();
+		}catch(Exception e){
+			e.printStackTrace();
+		}
+        return -1;
 	}
 
 	@Override
 	public void close() {
-		if(conn == null) return;
-		conn.disconnect();
-	}
-	public void setConn(HttpURLConnection urlconn) {
-		conn = urlconn;
 	}
 }
diff --git a/group12/247565311/week3/impl/ConnectionManagerImpl.java b/group12/247565311/week3/impl/ConnectionManagerImpl.java
index 68e458b1ca..b4a7cf381f 100644
--- a/group12/247565311/week3/impl/ConnectionManagerImpl.java
+++ b/group12/247565311/week3/impl/ConnectionManagerImpl.java
@@ -13,16 +13,6 @@ public class ConnectionManagerImpl implements ConnectionManager {
     ConnectionImpl conImpl = null;
 	@Override
 	public Connection open(String url) throws ConnectionException {
-		try {
-			URL urllink = new URL(url);
-			conImpl = new ConnectionImpl();
-			HttpURLConnection httpconn = (HttpURLConnection)urllink.openConnection();
-			httpconn.setConnectTimeout(5*1000);
-			httpconn.setRequestProperty("User-Agent","Mozilla/4.0 (compatiable; MSIE 5.0; Windows NT; DigExt)"); // ģ�������
-			conImpl.setConn(httpconn);
-		} catch (Exception e) {
-			throw (ConnectionException)e;
-		}
-		 return conImpl;
+		 return new ConnectionImpl(url);
 	}
 }
diff --git a/group12/247565311/week5/ClassFileLoader.java b/group12/247565311/week5/ClassFileLoader.java
new file mode 100644
index 0000000000..fc5e920f19
--- /dev/null
+++ b/group12/247565311/week5/ClassFileLoader.java
@@ -0,0 +1,63 @@
+package week5;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+public class ClassFileLoader {
+    private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) throws Exception {
+		for(String s:clzPaths){
+			String filename = s+className+".class";
+			File file = new File(filename);
+			if(file.exists())return loadClassFile(filename);
+		}
+		return null;
+	}
+	
+	private byte[] loadClassFile(String clzFileName) throws Exception {
+		File file = new File(clzFileName);
+		long filelength = file.length();
+		byte[]res = null;
+		if(filelength>Integer.MAX_VALUE)throw new IOException("�ļ�����");
+		try {
+			FileInputStream fileinput = new FileInputStream(file);
+			res = new byte[(int) filelength];
+			int offset=0,length=0;
+			while(offset<res.length && ((length=fileinput.read(res,offset,res.length-offset))>-1))
+				offset += length;
+			fileinput.close();
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		}
+		return res;
+	}
+	
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+	
+	public String getClassPath_V1(){
+		String res = "";
+		int size = clzPaths.size();
+		for(int i=0;i<size-1;i++){
+			res += clzPaths.get(i);
+		}
+		res += clzPaths.get(size-1);
+		return  res;
+	}
+	
+	public String getClassPath(){
+		String res = "";
+		int size = clzPaths.size();
+		for(int i=0;i<size-1;i++){
+			res += clzPaths.get(i);
+			res += ";";
+		}
+		res += clzPaths.get(size-1);
+		return  res;
+	}
+}
diff --git a/group12/247565311/week5/ClassFileLoaderTest.java b/group12/247565311/week5/ClassFileLoaderTest.java
new file mode 100644
index 0000000000..565203556a
--- /dev/null
+++ b/group12/247565311/week5/ClassFileLoaderTest.java
@@ -0,0 +1,72 @@
+package week5;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClassFileLoaderTest {
+	static String path1 = "F:\\code_language\\demo\\Homework\\bin\\week5\\";
+	static String path2 = "C:\temp";
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		String clzPath = loader.getClassPath();
+		Assert.assertEquals(path1+";"+path2,clzPath);
+	}
+	
+	@Test
+	public void testClassFileLength() {
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "EmployeeV1";
+		byte[] byteCodes = new byte[0];
+		try {
+			byteCodes = loader.readBinaryCode(className);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		// ע�⣺����ֽ������ܺ����JVM�汾�й�ϵ�� ����Կ�������õ��ൽ���ж��
+		Assert.assertEquals(267, byteCodes.length);
+	}
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "EmployeeV1";
+		byte[] byteCodes = new byte[0];
+		try {
+			byteCodes = loader.readBinaryCode(className);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		String acctualValue = this.byteToHexString(codes);
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+}
diff --git a/group12/247565311/week5/EmployeeV1.java b/group12/247565311/week5/EmployeeV1.java
new file mode 100644
index 0000000000..22949d2a0b
--- /dev/null
+++ b/group12/247565311/week5/EmployeeV1.java
@@ -0,0 +1,5 @@
+package week5;
+
+public class EmployeeV1 {
+
+}
diff --git a/group12/247565311/week5/LRU.java b/group12/247565311/week5/LRU.java
new file mode 100644
index 0000000000..705b0b0c87
--- /dev/null
+++ b/group12/247565311/week5/LRU.java
@@ -0,0 +1,67 @@
+package week5;
+import java.util.HashSet;
+
+import week1.ArrayList;
+public class LRU {
+	int size;
+	Node head = new Node(0);
+	HashSet<Integer> lib = new HashSet<Integer>();
+	class Node{
+		int val;
+		Node next;
+		public Node(int _val){
+			val = _val;
+			next = null;
+		}
+	}
+    public LRU(int _size){
+    	if(_size>0) {
+    		this.size = _size;
+    	}
+    }
+    public int[] getAll(){
+    	int length = lib.size(),index = 0;
+    	int []res = new int[length];
+    	Node p = head.next;
+    	while(p!=null){
+    		res[index] = p.val;
+    		index += 1;
+    		p = p.next;
+    	}
+    	return res;
+    }
+    public void add(int e){
+    	int index = 0;
+    	if(lib.contains(e)){
+    		Node p = head;
+            while(p.next!= null){
+                if(p.next.val == e){
+                    Node newn = p.next;
+                    p.next = newn.next;
+                    newn.next = head.next;
+                    head.next = newn;
+                    break;
+                }
+                p = p.next;
+            }
+    	}else{
+    		if(lib.size() == size){
+    			lib.add(e);
+    			Node newn = new Node(e);
+    			newn.next = head.next;
+    			head.next = newn;
+                Node p = head;
+                while(p.next.next != null)
+                    p = p.next;
+                Node deln = p.next;
+                lib.remove(deln.val);
+                p.next = null;
+    		}else{
+                Node newn = new Node(e);
+                newn.next = head.next;
+                head.next = newn;
+                lib.add(e);
+            }
+    	}
+    }
+}
diff --git a/group12/247565311/week5/LRUTest.java b/group12/247565311/week5/LRUTest.java
new file mode 100644
index 0000000000..0ee0d95309
--- /dev/null
+++ b/group12/247565311/week5/LRUTest.java
@@ -0,0 +1,36 @@
+package week5;
+
+import static org.junit.Assert.*;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LRUTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testAdd() {
+        LRU lru = new LRU(5);
+        lru.add(3);
+        lru.add(7);
+        lru.add(5);
+        lru.add(8);
+        lru.add(10);
+        Assert.assertArrayEquals(new int[]{10,8,5,7,3}, lru.getAll());
+        lru.add(5);
+        lru.add(3);
+        Assert.assertArrayEquals(new int[]{3,5,10,8,7}, lru.getAll());
+        lru.add(8);
+        lru.add(11);
+        Assert.assertArrayEquals(new int[]{11,8,3,5,10}, lru.getAll());
+	}
+}
diff --git a/group12/349166103/LRUPageFrame.java b/group12/349166103/LRUPageFrame.java
new file mode 100644
index 0000000000..4dda68632d
--- /dev/null
+++ b/group12/349166103/LRUPageFrame.java
@@ -0,0 +1,108 @@
+
+
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(int Num) {
+			pageNum=Num;
+		}
+	}
+
+	private int capacity;
+	
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	private int nodeNum = 0;
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		int isPageNum = isContained(pageNum);
+		if(isPageNum!=-1){
+			int index = 0;
+			Node node = first;
+			while(index!=isPageNum){	// move to the Node
+				node=node.next;
+				index++;
+			}
+			if(index != 0){
+				if(node.next == null){
+					node.prev.next = null;
+				}else{
+					node.prev.next = node.next;
+				}
+				node.next = first;
+				first = node;
+			}
+		}else{
+			if(first != null){
+				Node tmp = new Node(pageNum);
+				tmp.next = first;
+				first.prev = tmp;
+				first = tmp;
+				nodeNum++;
+				if(nodeNum > capacity){
+					Node node = first;
+					for(int i=0;i<capacity-1;i++){
+						node=node.next;
+					}
+					node.next.prev = null;
+					node.next = null;
+				}
+			}else{
+				first = new Node(pageNum);
+				nodeNum++;
+			}
+		}
+	
+	}
+	
+	private int isContained(int pageNum){
+		Node node = first;
+		int result = 0;
+		while(node != null){
+			if(node.pageNum == pageNum){
+				return result;
+			}else{
+				node = node.next;
+				result++;
+			}
+		}
+		result = -1;
+		return result;
+	}
+	
+	
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group12/377401843/learning/pom.xml b/group12/377401843/learning/pom.xml
index f252611284..447c5546ce 100644
--- a/group12/377401843/learning/pom.xml
+++ b/group12/377401843/learning/pom.xml
@@ -20,6 +20,17 @@
 			<version>1.6.1</version>
 		</dependency>
 
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>3.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.4</version>
+		</dependency>
 	</dependencies>
 
 	<build>
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java b/group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java
similarity index 87%
rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java
rename to group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java
index d3afc5e01a..d5c5fe04cc 100644
--- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/ArrayList.java
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/array/ArrayList.java
@@ -1,7 +1,10 @@
-package com.zhaogd.collection;
+package com.zhaogd.array;
 
 import java.util.Arrays;
 
+import com.zhaogd.collection.Iterator;
+import com.zhaogd.collection.List;
+
 public class ArrayList implements List {
 
 	private int size = 0;
@@ -13,7 +16,7 @@ public class ArrayList implements List {
 	 *
 	 * @Method add
 	 * @param o
-	 * @see com.guodong.datastructure.List#add(java.lang.Object)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#add(java.lang.Object)
 	 */
 	public void add(Object o) {
 		ensureCapacityInternal(size + 1);
@@ -27,7 +30,7 @@ public void add(Object o) {
 	 * @Method add
 	 * @param index
 	 * @param o
-	 * @see com.guodong.datastructure.List#add(int, java.lang.Object)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#add(int, java.lang.Object)
 	 */
 	public void add(int index, Object o) {
 		checkRangeForAdd(index);
@@ -46,7 +49,7 @@ public void add(int index, Object o) {
 	 * @Method get
 	 * @param index
 	 * @return
-	 * @see com.guodong.datastructure.List#get(int)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#get(int)
 	 */
 	public Object get(int index) {
 		checkRangeForGetOrRemove(index);
@@ -60,7 +63,7 @@ public Object get(int index) {
 	 * @Method remove
 	 * @param index
 	 * @return
-	 * @see com.guodong.datastructure.List#remove(int)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#remove(int)
 	 */
 	public Object remove(int index) {
 		checkRangeForGetOrRemove(index);
@@ -80,7 +83,7 @@ public Object remove(int index) {
 	 *
 	 * @Method size
 	 * @return
-	 * @see com.guodong.datastructure.List#size()
+	 * @see com.zhaogd.collection.guodong.datastructure.List#size()
 	 */
 	public int size() {
 		return size;
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java
index d4a0647ab6..b81d015351 100644
--- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/Queue.java
@@ -1,5 +1,7 @@
 package com.zhaogd.collection;
 
+import com.zhaogd.collection.linkedlist.LinkedList;
+
 public class Queue {
 	private LinkedList element = new LinkedList();
 
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java
new file mode 100644
index 0000000000..39a4e4063d
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrame.java
@@ -0,0 +1,164 @@
+package com.zhaogd.collection.linkedlist;
+
+
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	
+	private int currentSize;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		this.currentSize = 0;
+		this.capacity = capacity;
+		
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		
+		Node node = find(pageNum);
+		//在该队列中存在， 则提到队列头
+		if (node != null) {
+			
+			moveExistingNodeToHead(node);		
+			
+		} else{
+			
+			node = new Node();
+			node.pageNum = pageNum;
+			
+			// 缓存容器是否已经超过大小.
+			if (currentSize >= capacity) {			
+				removeLast();
+							
+			} 
+			
+			addNewNodetoHead(node);
+			
+			
+			
+						
+		}
+	}
+	
+	private void addNewNodetoHead(Node node) {
+		
+		if(isEmpty()){
+			
+			node.prev = null;
+			node.next = null;
+			first = node;
+			last = node;
+			
+		} else{
+			node.prev = null;
+			node.next = first;
+			first.prev = node;
+			first = node;
+		}
+		this.currentSize ++;
+	}
+
+	private Node find(int data){
+		
+		Node node = first;
+		while(node != null){
+			if(node.pageNum == data){
+				return node;
+			}
+			node = node.next;
+		}
+		return null;
+		
+	}
+
+	
+
+	
+	
+
+	/**
+	 * 删除链表尾部节点 表示 删除最少使用的缓存对象
+	 */
+	private void removeLast() {
+		Node prev = last.prev;
+		prev.next = null;
+		last.prev = null;
+		last = prev;
+		this.currentSize --;
+	}
+
+	/**
+	 * 移动到链表头，表示这个节点是最新使用过的
+	 * 
+	 * @param node
+	 */
+	private void moveExistingNodeToHead(Node node) {
+		
+		if (node == first) {
+			
+			return;
+		}
+		else if(node == last){
+			//当前节点是链表尾， 需要放到链表头
+			Node prevNode = node.prev;
+			prevNode.next = null;	
+			last.prev = null;
+			last  = prevNode;				
+			
+		} else{
+			//node 在链表的中间， 把node 的前后节点连接起来
+			Node prevNode = node.prev;
+			prevNode.next = node.next;
+			
+			Node nextNode = node.next;
+			nextNode.prev = prevNode;
+			
+			
+		}
+		
+		node.prev = null;
+		node.next = first;
+		first.prev = node;
+		first = node;	
+		
+	}
+	private boolean isEmpty(){		
+		return (first == null) && (last == null);
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+	
+
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..b2fc8c8323
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LRUPageFrameTest.java
@@ -0,0 +1,34 @@
+package com.zhaogd.collection.linkedlist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+		frame.access(5);
+		Assert.assertEquals("5,4,0", frame.toString());
+		
+	}
+
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java
similarity index 94%
rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java
rename to group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java
index 136f53284e..78721b060a 100644
--- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/LinkedList.java
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/linkedlist/LinkedList.java
@@ -1,7 +1,10 @@
-package com.zhaogd.collection;
+package com.zhaogd.collection.linkedlist;
 
 import java.util.NoSuchElementException;
 
+import com.zhaogd.collection.Iterator;
+import com.zhaogd.collection.List;
+
 public class LinkedList implements List {
 
 	private int size;
@@ -15,7 +18,7 @@ public class LinkedList implements List {
 	 *
 	 * @Method add
 	 * @param o
-	 * @see com.guodong.datastructure.List#add(java.lang.Object)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#add(java.lang.Object)
 	 */
 	public void add(Object o) {
 		linkLast(o);
@@ -27,7 +30,7 @@ public void add(Object o) {
 	 * @Method add
 	 * @param index
 	 * @param o
-	 * @see com.guodong.datastructure.List#add(int, java.lang.Object)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#add(int, java.lang.Object)
 	 */
 	public void add(int index, Object o) {
 		checkIndexForAdd(index);
@@ -54,7 +57,7 @@ public void add(int index, Object o) {
 	 * @Method get
 	 * @param index
 	 * @return
-	 * @see com.guodong.datastructure.List#get(int)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#get(int)
 	 */
 	public Object get(int index) {
 		checkIndexForGet(index);
@@ -71,7 +74,7 @@ public Object getLast() {
 	 * @Method remove
 	 * @param index
 	 * @return
-	 * @see com.guodong.datastructure.List#remove(int)
+	 * @see com.zhaogd.collection.guodong.datastructure.List#remove(int)
 	 */
 	public Object remove(int index) {
 		checkIndexForGet(index);
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java
similarity index 80%
rename from group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java
rename to group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java
index afb01f5f92..85a8800f39 100644
--- a/group12/377401843/learning/src/main/java/com/zhaogd/collection/Stack.java
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/Stack.java
@@ -1,4 +1,6 @@
-package com.zhaogd.collection;
+package com.zhaogd.collection.stack;
+
+import com.zhaogd.collection.linkedlist.LinkedList;
 
 public class Stack {
 	private LinkedList elementData = new LinkedList();
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java
new file mode 100644
index 0000000000..ecf128b27e
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/collection/stack/StackUtil.java
@@ -0,0 +1,45 @@
+package com.zhaogd.collection.stack;
+
+public class StackUtil {
+	
+	
+	/**
+	 * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后， 元素次序变为: 1,2,3,4,5
+	 * 注意：只能使用Stack的基本操作，即push,pop,peek,isEmpty， 可以使用另外一个栈来辅助
+	 */
+	public static void reverse(Stack s) {
+
+	}
+
+	/**
+	 * 删除栈中的某个元素 注意：只能使用Stack的基本操作，即push,pop,peek,isEmpty， 可以使用另外一个栈来辅助
+	 * 
+	 * @param o
+	 */
+	public static void remove(Stack s,Object o) {
+
+	}
+
+	/**
+	 * 从栈顶取得len个元素, 原来的栈中元素保持不变
+	 * 注意：只能使用Stack的基本操作，即push,pop,peek,isEmpty， 可以使用另外一个栈来辅助
+	 * @param len
+	 * @return
+	 */
+	public static Object[] getTop(Stack s,int len) {
+		return null;
+	}
+	/**
+	 * 字符串s 可能包含这些字符：  ( ) [ ] { }, a,b,c... x,yz
+	 * 使用堆栈检查字符串s中的括号是不是成对出现的。
+	 * 例如s = "([e{d}f])" , 则该字符串中的括号是成对出现， 该方法返回true
+	 * 如果 s = "([b{x]y})", 则该字符串中的括号不是成对出现的， 该方法返回false;
+	 * @param s
+	 * @return
+	 */
+	public static boolean isValidPairs(String s){
+		return false;
+	}
+	
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java
new file mode 100644
index 0000000000..1557b0ead2
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/AccessFlag.java
@@ -0,0 +1,25 @@
+package com.zhaogd.jvm.clz;
+
+public class AccessFlag {
+	private int flagValue;
+
+	public AccessFlag(int value) {
+		this.flagValue = value;
+	}
+
+	public int getFlagValue() {
+		return flagValue;
+	}
+
+	public void setFlagValue(int flag) {
+		this.flagValue = flag;
+	}
+	
+	public boolean isPublicClass(){
+		return (this.flagValue & 0x0001) != 0;
+	}
+	public boolean isFinalClass(){
+		return (this.flagValue & 0x0010) != 0;
+	}
+	
+}
\ No newline at end of file
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java
new file mode 100644
index 0000000000..bf6abbe3fd
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassFile.java
@@ -0,0 +1,75 @@
+package com.zhaogd.jvm.clz;
+
+import com.zhaogd.jvm.constant.ClassInfo;
+import com.zhaogd.jvm.constant.ConstantPool;
+
+public class ClassFile {
+	
+	private int minorVersion;
+	private int majorVersion;
+	
+	private AccessFlag accessFlag;
+	private ClassIndex clzIndex;
+	private ConstantPool pool;
+	
+	
+	public ClassIndex getClzIndex() {
+		return clzIndex;
+	}
+	public AccessFlag getAccessFlag() {
+		return accessFlag;
+	}
+	public void setAccessFlag(AccessFlag accessFlag) {
+		this.accessFlag = accessFlag;
+	}
+	
+	
+	
+	public ConstantPool getConstantPool() {		
+		return pool;
+	}
+	public int getMinorVersion() {
+		return minorVersion;
+	}
+	public void setMinorVersion(int minorVersion) {
+		this.minorVersion = minorVersion;
+	}
+	public int getMajorVersion() {
+		return majorVersion;
+	}
+	public void setMajorVersion(int majorVersion) {
+		this.majorVersion = majorVersion;
+	}
+	public void setConstPool(ConstantPool pool) {
+		this.pool = pool;
+		
+	}
+	public void setClassIndex(ClassIndex clzIndex) {
+		this.clzIndex = clzIndex;		
+	}
+	
+	
+	
+	
+	public void print(){
+		
+		if(this.accessFlag.isPublicClass()){
+			System.out.println("Access flag : public  ");
+		}
+		System.out.println("Class Name:"+ getClassName());
+		
+		System.out.println("Super Class Name:"+ getSuperClassName());
+		
+		
+	}
+	
+	private String getClassName(){
+		int thisClassIndex = this.clzIndex.getThisClassIndex();
+		ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex);
+		return thisClass.getClassName();
+	}
+	private String getSuperClassName(){
+		ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex());
+		return superClass.getClassName();
+	}
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java
new file mode 100644
index 0000000000..0bdf47d002
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/clz/ClassIndex.java
@@ -0,0 +1,19 @@
+package com.zhaogd.jvm.clz;
+
+public class ClassIndex {
+	private int thisClassIndex;
+	private int superClassIndex;
+	
+	public int getThisClassIndex() {
+		return thisClassIndex;
+	}
+	public void setThisClassIndex(int thisClassIndex) {
+		this.thisClassIndex = thisClassIndex;
+	}
+	public int getSuperClassIndex() {
+		return superClassIndex;
+	}
+	public void setSuperClassIndex(int superClassIndex) {
+		this.superClassIndex = superClassIndex;
+	}
+}
\ No newline at end of file
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java
new file mode 100644
index 0000000000..9851e063c0
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ClassInfo.java
@@ -0,0 +1,24 @@
+package com.zhaogd.jvm.constant;
+
+public class ClassInfo extends ConstantInfo {
+	private int type = ConstantInfo.CLASS_INFO;
+	private int utf8Index ;
+	public ClassInfo(ConstantPool pool) {
+		super(pool);
+	}
+	public int getUtf8Index() {
+		return utf8Index;
+	}
+	public void setUtf8Index(int utf8Index) {
+		this.utf8Index = utf8Index;
+	}
+	public int getType() {
+		return type;
+	}
+	
+	public String getClassName() {		
+		int index = getUtf8Index();
+		UTF8Info utf8Info = (UTF8Info)constantPool.getConstantInfo(index);
+		return utf8Info.getValue();		
+	}
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java
new file mode 100644
index 0000000000..0afd79256b
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantInfo.java
@@ -0,0 +1,29 @@
+package com.zhaogd.jvm.constant;
+
+public abstract class ConstantInfo {
+	public static final int UTF8_INFO = 1;
+	public static final int FLOAT_INFO = 4;
+	public static final int CLASS_INFO = 7;
+	public static final int STRING_INFO = 8;
+	public static final int FIELD_INFO = 9;
+	public static final int METHOD_INFO = 10;
+	public static final int NAME_AND_TYPE_INFO = 12;
+	protected ConstantPool constantPool;
+	
+	public ConstantInfo(){
+		
+	}
+	
+	public ConstantInfo(ConstantPool pool) {
+		this.constantPool = pool;
+	}
+	public abstract int getType();
+	
+	public ConstantPool getConstantPool() {
+		return constantPool;
+	}
+	public ConstantInfo getConstantInfo(int index){
+		return this.constantPool.getConstantInfo(index);
+	}
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java
new file mode 100644
index 0000000000..4663d4d195
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/ConstantPool.java
@@ -0,0 +1,29 @@
+package com.zhaogd.jvm.constant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConstantPool {
+	
+	private List<ConstantInfo> constantInfos = new ArrayList<ConstantInfo>();
+	
+	
+	public ConstantPool(){
+		
+	}
+	public void addConstantInfo(ConstantInfo info){
+		
+		this.constantInfos.add(info);
+		
+	}
+	
+	public ConstantInfo getConstantInfo(int index){
+		return this.constantInfos.get(index);
+	}
+	public String getUTF8String(int index){
+		return ((UTF8Info)this.constantInfos.get(index)).getValue();
+	}
+	public Object getSize() {		
+		return this.constantInfos.size() -1;
+	}
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java
new file mode 100644
index 0000000000..bba61aea27
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/FieldRefInfo.java
@@ -0,0 +1,54 @@
+package com.zhaogd.jvm.constant;
+
+public class FieldRefInfo extends ConstantInfo{
+	private int type = ConstantInfo.FIELD_INFO;
+	private int classInfoIndex;
+	private int nameAndTypeIndex;
+	
+	public FieldRefInfo(ConstantPool pool) {
+		super(pool);
+	}
+	public int getType() {
+		return type;
+	}
+	
+	public int getClassInfoIndex() {
+		return classInfoIndex;
+	}
+	public void setClassInfoIndex(int classInfoIndex) {
+		this.classInfoIndex = classInfoIndex;
+	}
+	public int getNameAndTypeIndex() {
+		return nameAndTypeIndex;
+	}
+	public void setNameAndTypeIndex(int nameAndTypeIndex) {
+		this.nameAndTypeIndex = nameAndTypeIndex;
+	}
+	
+	public String toString(){
+		
+		NameAndTypeInfo  typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+		
+		return getClassName() +" : "+  typeInfo.getName() + ":" + typeInfo.getTypeInfo() +"]";
+	}
+	
+	public String getClassName(){
+		
+		ClassInfo classInfo = (ClassInfo) this.getConstantInfo(this.getClassInfoIndex());
+		
+		UTF8Info utf8Info = (UTF8Info)this.getConstantInfo(classInfo.getUtf8Index());
+		
+		return utf8Info.getValue();
+		
+	}
+	
+	public String getFieldName(){
+		NameAndTypeInfo  typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+		return typeInfo.getName();		
+	}
+	
+	public String getFieldType(){
+		NameAndTypeInfo  typeInfo = (NameAndTypeInfo)this.getConstantInfo(this.getNameAndTypeIndex());
+		return typeInfo.getTypeInfo();	
+	}
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java
new file mode 100644
index 0000000000..61c965bc0a
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/MethodRefInfo.java
@@ -0,0 +1,55 @@
+package com.zhaogd.jvm.constant;
+
+public class MethodRefInfo extends ConstantInfo {
+	
+	private int type = ConstantInfo.METHOD_INFO;
+	
+	private int classInfoIndex;	
+	private int nameAndTypeIndex;
+	
+	public MethodRefInfo(ConstantPool pool) {
+		super(pool);
+	}
+
+	public int getType() {
+		return type;
+	}
+	
+	public int getClassInfoIndex() {
+		return classInfoIndex;
+	}
+	public void setClassInfoIndex(int classInfoIndex) {
+		this.classInfoIndex = classInfoIndex;
+	}
+	public int getNameAndTypeIndex() {
+		return nameAndTypeIndex;
+	}
+	public void setNameAndTypeIndex(int nameAndTypeIndex) {
+		this.nameAndTypeIndex = nameAndTypeIndex;
+	}
+	
+	public String toString(){
+	
+		return getClassName() +" : "+ this.getMethodName() + " : " + this.getParamAndReturnType() ;
+	}
+	public String getClassName(){
+		ConstantPool pool = this.getConstantPool();		
+		ClassInfo clzInfo = (ClassInfo)pool.getConstantInfo(this.getClassInfoIndex());
+		return clzInfo.getClassName();
+	}
+	
+	public String getMethodName(){
+		ConstantPool pool = this.getConstantPool();
+		NameAndTypeInfo  typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex());
+		return typeInfo.getName();
+	}
+	
+	public String getParamAndReturnType(){
+		ConstantPool pool = this.getConstantPool();
+		NameAndTypeInfo  typeInfo = (NameAndTypeInfo)pool.getConstantInfo(this.getNameAndTypeIndex());
+		return typeInfo.getTypeInfo();
+	}
+	
+	
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java
new file mode 100644
index 0000000000..aef7f16d1e
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NameAndTypeInfo.java
@@ -0,0 +1,45 @@
+package com.zhaogd.jvm.constant;
+
+public class NameAndTypeInfo extends ConstantInfo{
+	public  int type = ConstantInfo.NAME_AND_TYPE_INFO;
+	
+	private int index1;
+	private int index2;
+	
+	public NameAndTypeInfo(ConstantPool pool) {
+		super(pool);
+	}
+	
+	public int getIndex1() {
+		return index1;
+	}
+	public void setIndex1(int index1) {
+		this.index1 = index1;
+	}
+	public int getIndex2() {
+		return index2;
+	}
+	public void setIndex2(int index2) {
+		this.index2 = index2;
+	}
+	public int getType() {
+		return type;
+	}
+	
+	
+	public String getName(){
+		ConstantPool pool = this.getConstantPool();
+		UTF8Info utf8Info1 = (UTF8Info)pool.getConstantInfo(index1);
+		return utf8Info1.getValue();
+	}
+	
+	public String getTypeInfo(){
+		ConstantPool pool = this.getConstantPool();
+		UTF8Info utf8Info2 = (UTF8Info)pool.getConstantInfo(index2);
+		return utf8Info2.getValue();
+	}
+	
+	public String toString(){
+		return "(" + getName() + "," + getTypeInfo()+")";
+	}
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java
new file mode 100644
index 0000000000..1cb411bee2
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/NullConstantInfo.java
@@ -0,0 +1,13 @@
+package com.zhaogd.jvm.constant;
+
+public class NullConstantInfo extends ConstantInfo {
+
+	public NullConstantInfo(){
+		
+	}
+	@Override
+	public int getType() {		
+		return -1;
+	}
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java
new file mode 100644
index 0000000000..c58bcb59d7
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/StringInfo.java
@@ -0,0 +1,26 @@
+package com.zhaogd.jvm.constant;
+
+public class StringInfo extends ConstantInfo{
+	private int type = ConstantInfo.STRING_INFO;
+	private int index;
+	public StringInfo(ConstantPool pool) {
+		super(pool);
+	}
+
+	public int getType() {
+		return type;
+	}
+	
+	public int getIndex() {
+		return index;
+	}
+	public void setIndex(int index) {
+		this.index = index;
+	}
+
+	
+	public String toString(){
+		return this.getConstantPool().getUTF8String(index);
+	}
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java
new file mode 100644
index 0000000000..c8b2e6a4c0
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/constant/UTF8Info.java
@@ -0,0 +1,32 @@
+package com.zhaogd.jvm.constant;
+
+public class UTF8Info extends ConstantInfo{
+	private int type = ConstantInfo.UTF8_INFO;
+	private int length ;
+	private String value;
+	public UTF8Info(ConstantPool pool) {
+		super(pool);
+	}
+	public int getLength() {
+		return length;
+	}
+	public void setLength(int length) {
+		this.length = length;
+	}
+	public int getType() {
+		return type;
+	}
+	@Override
+	public String toString() {
+		return "UTF8Info [type=" + type + ", length=" + length + ", value=" + value +")]";
+	}
+	public String getValue() {
+		return value;
+	}
+	public void setValue(String value) {
+		this.value = value;
+	}
+	
+	
+
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java
new file mode 100644
index 0000000000..7147060b84
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ByteCodeIterator.java
@@ -0,0 +1,5 @@
+package com.zhaogd.jvm.loader;
+
+public class ByteCodeIterator {
+
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..6d04787a99
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,140 @@
+package com.zhaogd.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.zhaogd.jvm.clz.ClassFile;
+
+
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		
+		className = className.replace('.', File.separatorChar) +".class";
+		
+		for(String path : this.clzPaths){
+			
+			String clzFileName = path + File.separatorChar + className;
+			byte[] codes = loadClassFile(clzFileName);
+			if(codes != null){
+				return codes;
+			}			
+		}
+		
+		return null;
+		
+		
+		
+	}
+	
+	private byte[] loadClassFile(String clzFileName) {
+		
+		File f = new File(clzFileName);
+		
+		try {
+		
+			return IOUtils.toByteArray(new FileInputStream(f));
+			
+		} catch (IOException e) {			
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	
+	
+	public void addClassPath(String path) {
+		if(this.clzPaths.contains(path)){
+			return;
+		}
+		
+		this.clzPaths.add(path);
+		
+	}
+	
+	
+	
+	public String getClassPath(){
+		return StringUtils.join(this.clzPaths,";");
+	}
+
+	public ClassFile loadClass(String className) {
+		byte[] codes = this.readBinaryCode(className);
+		ClassFileParser parser = new ClassFileParser();
+		return parser.parse(codes);
+		
+	}
+	
+	
+	
+	// ------------------------------backup------------------------
+    public String getClassPath_V1(){
+		
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<this.clzPaths.size();i++){
+			buffer.append(this.clzPaths.get(i));
+			if(i<this.clzPaths.size()-1){
+				buffer.append(";");
+			}
+		}
+		return buffer.toString();
+	}
+	
+	private byte[] loadClassFile_V1(String clzFileName) {
+		
+		BufferedInputStream bis = null;
+		
+		try {
+			
+			File f = new File(clzFileName);
+			
+						
+			bis = new BufferedInputStream(new FileInputStream(f));
+			
+			ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			
+			
+			byte[] buffer = new byte[1024];
+			int length = -1;
+			
+			while((length = bis.read(buffer)) != -1){
+				bos.write(buffer, 0, length);				
+			}
+			
+			byte [] codes = bos.toByteArray();
+			
+			return codes;
+			
+		} catch(IOException e){
+			e.printStackTrace();
+			
+		} finally{
+			if(bis != null){
+				try {
+					bis.close();
+				} catch (IOException e) {					
+					e.printStackTrace();
+				}
+			}
+		}
+		return null;
+		
+	}
+
+
+	
+
+}
\ No newline at end of file
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileParser.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileParser.java
new file mode 100644
index 0000000000..fe3a75c0f0
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/loader/ClassFileParser.java
@@ -0,0 +1,35 @@
+package com.zhaogd.jvm.loader;
+
+import com.zhaogd.jvm.clz.AccessFlag;
+import com.zhaogd.jvm.clz.ClassFile;
+import com.zhaogd.jvm.clz.ClassIndex;
+import com.zhaogd.jvm.constant.ConstantPool;
+
+public class ClassFileParser {
+
+	public ClassFile parse(byte[] codes) {
+
+		
+		
+
+		return null;
+	}
+
+	private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
+
+		return null;
+	}
+
+	private ClassIndex parseClassInfex(ByteCodeIterator iter) {
+
+		return null;
+
+	}
+
+	private ConstantPool parseConstantPool(ByteCodeIterator iter) {
+
+		return null;
+	}
+
+	
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/ClassFileloaderTest.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..0391dd86be
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,202 @@
+package com.zhaogd.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.zhaogd.jvm.clz.ClassFile;
+import com.zhaogd.jvm.clz.ClassIndex;
+import com.zhaogd.jvm.constant.ClassInfo;
+import com.zhaogd.jvm.constant.ConstantPool;
+import com.zhaogd.jvm.constant.MethodRefInfo;
+import com.zhaogd.jvm.constant.NameAndTypeInfo;
+import com.zhaogd.jvm.constant.UTF8Info;
+import com.zhaogd.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	private static final String FULL_QUALIFIED_CLASS_NAME = "com/coderising/jvm/test/EmployeeV1";
+	
+	static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin";
+	static String path2 = "C:\temp";
+	
+	static ClassFile clzFile = null;
+	static {
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		clzFile = loader.loadClass(className);
+		clzFile.print();
+	}
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+   	private String byteToHexString(byte[] codes ){
+   		StringBuffer buffer = new StringBuffer();
+   		for(int i=0;i<codes.length;i++){
+   			byte b = codes[i];
+   			int value = b & 0xFF;
+   			String strHex = Integer.toHexString(value);
+   			if(strHex.length()< 2){
+   				strHex = "0" + strHex;
+   			}		
+   			buffer.append(strHex);
+   		}
+   		return buffer.toString();
+   	}
+    
+    /**
+     * ----------------------------------------------------------------------
+     */
+    
+    
+    @Test
+    public void testVersion(){    			
+		
+		Assert.assertEquals(0, clzFile.getMinorVersion());
+		Assert.assertEquals(52, clzFile.getMajorVersion());
+		
+    }
+    
+    @Test
+    public void testConstantPool(){
+    	
+
+		ConstantPool pool = clzFile.getConstantPool();
+		
+		Assert.assertEquals(53, pool.getSize());
+	
+		{
+			ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(1);
+			Assert.assertEquals(2, clzInfo.getUtf8Index());
+			
+			UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(2);
+			Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, utf8Info.getValue());
+		}
+		{
+			ClassInfo clzInfo = (ClassInfo) pool.getConstantInfo(3);
+			Assert.assertEquals(4, clzInfo.getUtf8Index());
+			
+			UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(4);
+			Assert.assertEquals("java/lang/Object", utf8Info.getValue());
+		}
+		{
+			UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(5);
+			Assert.assertEquals("name", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(6);
+			Assert.assertEquals("Ljava/lang/String;", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(7);
+			Assert.assertEquals("age", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(8);
+			Assert.assertEquals("I", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(9);
+			Assert.assertEquals("<init>", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(10);
+			Assert.assertEquals("(Ljava/lang/String;I)V", utf8Info.getValue());
+			
+			utf8Info = (UTF8Info) pool.getConstantInfo(11);
+			Assert.assertEquals("Code", utf8Info.getValue());
+		}
+		
+		{
+			MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(12);
+			Assert.assertEquals(3, methodRef.getClassInfoIndex());
+			Assert.assertEquals(13, methodRef.getNameAndTypeIndex());
+		}
+		
+		{
+			NameAndTypeInfo nameAndType = (NameAndTypeInfo) pool.getConstantInfo(13);
+			Assert.assertEquals(9, nameAndType.getIndex1());
+			Assert.assertEquals(14, nameAndType.getIndex2());
+		}
+		//抽查几个吧
+		{
+			MethodRefInfo methodRef = (MethodRefInfo)pool.getConstantInfo(45);
+			Assert.assertEquals(1, methodRef.getClassInfoIndex());
+			Assert.assertEquals(46, methodRef.getNameAndTypeIndex());
+		}
+		
+		{
+			UTF8Info utf8Info = (UTF8Info) pool.getConstantInfo(53);
+			Assert.assertEquals("EmployeeV1.java", utf8Info.getValue());
+		}
+    }
+    @Test
+    public void testClassIndex(){
+    	
+    	ClassIndex clzIndex = clzFile.getClzIndex();
+    	ClassInfo thisClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getThisClassIndex());
+    	ClassInfo superClassInfo = (ClassInfo)clzFile.getConstantPool().getConstantInfo(clzIndex.getSuperClassIndex());
+    	
+    	
+    	Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName());
+    	Assert.assertEquals("java/lang/Object", superClassInfo.getClassName());
+    }
+    
+   
+
+}
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..e9f656131b
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.zhaogd.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java
new file mode 100644
index 0000000000..9c2fcc183e
--- /dev/null
+++ b/group12/377401843/learning/src/main/java/com/zhaogd/jvm/util/Util.java
@@ -0,0 +1,24 @@
+package com.zhaogd.jvm.util;
+
+public class Util {
+	public static int byteToInt(byte[] codes){
+    	String s1 = byteToHexString(codes);
+    	return Integer.valueOf(s1, 16).intValue();
+    }
+    
+    
+    
+	public static String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+}
diff --git a/group12/377401843/learning/src/test/java/com/zhaogd/collection/ArrayListTest.java b/group12/377401843/learning/src/test/java/com/zhaogd/collection/ArrayListTest.java
index c54e99b4db..f051ffc521 100644
--- a/group12/377401843/learning/src/test/java/com/zhaogd/collection/ArrayListTest.java
+++ b/group12/377401843/learning/src/test/java/com/zhaogd/collection/ArrayListTest.java
@@ -8,6 +8,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import com.zhaogd.array.ArrayList;
+
 public class ArrayListTest {
 
 	ArrayList arrayList;
diff --git a/group12/377401843/learning/src/test/java/com/zhaogd/collection/LinkedListTest.java b/group12/377401843/learning/src/test/java/com/zhaogd/collection/LinkedListTest.java
index 32cac4bc6d..144d7ab466 100644
--- a/group12/377401843/learning/src/test/java/com/zhaogd/collection/LinkedListTest.java
+++ b/group12/377401843/learning/src/test/java/com/zhaogd/collection/LinkedListTest.java
@@ -8,6 +8,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import com.zhaogd.collection.linkedlist.LinkedList;
+
 public class LinkedListTest {
 
 	private LinkedList linkedList;
diff --git a/group12/377401843/learning/src/test/java/com/zhaogd/collection/StackTest.java b/group12/377401843/learning/src/test/java/com/zhaogd/collection/StackTest.java
index 510e4c45f6..f393481ef5 100644
--- a/group12/377401843/learning/src/test/java/com/zhaogd/collection/StackTest.java
+++ b/group12/377401843/learning/src/test/java/com/zhaogd/collection/StackTest.java
@@ -8,6 +8,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import com.zhaogd.collection.stack.Stack;
+
 public class StackTest {
 
 	private Stack stack;
diff --git a/group12/382266293/src/com/coderising/download/DownloadUtil.java b/group12/382266293/src/com/coderising/download/DownloadUtil.java
index 8e8f2de727..b01200c51d 100644
--- a/group12/382266293/src/com/coderising/download/DownloadUtil.java
+++ b/group12/382266293/src/com/coderising/download/DownloadUtil.java
@@ -45,7 +45,7 @@ public static void createTempFile(String tempName, int len) {
 	}
 
 	public static int calculateConnects(int length) {
-		int conns = length / 1024 / 1024 / 25;
+		int conns = length / 1024 / 1024 / 10;
 		if (conns < MIN_CONNECTIONS) {
 			return MIN_CONNECTIONS;
 		} else if (conns > MAX_CONNECTIONS) {
diff --git a/group12/382266293/src/com/coderising/download/FileDownloader.java b/group12/382266293/src/com/coderising/download/FileDownloader.java
index cc77b380a9..c756248bb1 100644
--- a/group12/382266293/src/com/coderising/download/FileDownloader.java
+++ b/group12/382266293/src/com/coderising/download/FileDownloader.java
@@ -44,7 +44,7 @@ public void execute() {
 		try {
 			Connection conn = cm.open(this.url);
 			int length = conn.getContentLength();
-			checkLength(length, conn);
+
 
 			System.out.println("file length:" + length);
 			setLocation("C:\\");
@@ -52,7 +52,8 @@ public void execute() {
 			String name = conn.getFileName();
 			setFileName(name);
 			setTempName(name);
-
+			checkLength(length, conn);
+			
 			DownloadUtil.createTempFile(tempName, length);
 
 			int connNumbers = DownloadUtil.calculateConnects(length);
@@ -143,14 +144,17 @@ private void setAndStartThreadPool(Connection conn, DownloadThread[] threadPool,
 		threadPool[0] = new DownloadThread(conn, beginPos, endPos);
 		setAndStartThread(threadPool[0], tempName);
 		for (int i = 1; i < connectionNumbers; i++) {
-			Connection con = cm.open(this.url);
 			beginPos = endPos + 1;
 			endPos = beginPos + batch_size;
+			Connection con = cm.open(this.url);
+
 			if (i == connectionNumbers - 1) {
 				endPos = length - 1;
 			}
 			threadPool[i] = new DownloadThread(con, beginPos, endPos);
 			setAndStartThread(threadPool[i], tempName);
+			
+
 		}
 	}
 
diff --git a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java
index 05f31103de..61ed430106 100644
--- a/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java
+++ b/group12/382266293/src/com/coderising/download/impl/ConnectionImpl.java
@@ -33,17 +33,27 @@ public byte[] read(int startPos, int endPos) throws IOException {
 		InputStream in = null;
 		ByteArrayOutputStream out = null;
 		try {
+			httpConn = (HttpURLConnection) url.openConnection();
+			httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
 			in  = httpConn.getInputStream();
 			out = new ByteArrayOutputStream();
 			in = httpConn.getInputStream();
-			in.skip(startPos);
-			byte[] buffer = new byte[endPos-startPos + 1];
+			//in.skip(startPos);
+			
 			int len = 0;
 			byte[] b = new byte[1024];
 			while((len = in.read(b)) != -1) {
 				out.write(b, 0, len);
 			}
+			int totalLen = endPos - startPos + 1;
+			
+			if (out.size() >  totalLen) {
+				byte[] data = out.toByteArray();
+				return data;
+			}
+			
 			return out.toByteArray();
+			
 		} catch (IOException e) {
 			e.printStackTrace();
 		} 
diff --git a/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..9ba4ff935b
--- /dev/null
+++ b/group12/382266293/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,93 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+
+	public byte[] readBinaryCode(String className) {
+
+		String clzFileName = "//" + className.replaceAll("\\.", "//") + ".class";
+		return loadClassFile(clzFileName);
+	}
+
+	@SuppressWarnings("resource")
+	private byte[] loadClassFile(String clzFileName) {
+		File classFile = getClassFile(clzFileName);
+		if (null == classFile) {
+			try {
+				throw new ClassNotFoundException(clzFileName + " does not exist.");
+			} catch (ClassNotFoundException e) {
+				e.printStackTrace();
+			}
+		}
+
+		RandomAccessFile raf = null;
+		ByteArrayOutputStream out = null;
+		try {
+			out = new ByteArrayOutputStream();
+			raf = new RandomAccessFile(classFile, "r");
+			int len = 0;
+			byte[] b = new byte[1024];
+			while ((len = raf.read(b)) != -1) {
+				out.write(b, 0, len);
+			}
+			int totalLen = (int) classFile.length();
+
+			if (out.size() > totalLen) {
+				byte[] data = out.toByteArray();
+				return data;
+			}
+
+			return out.toByteArray();
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;
+
+	}
+
+	private File getClassFile(String clzFileName) {
+
+		for (String path : clzPaths) {
+			File file = new File(path + "//" + clzFileName);
+			if (file.exists()) {
+				return file;
+			}
+		}
+		return null;
+
+	}
+
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+
+	public String getClassPath_V1() {
+
+		return null;
+	}
+
+	public String getClassPath() {
+
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < clzPaths.size(); i++) {
+
+			sb.append(clzPaths.get(i));
+			if (i < clzPaths.size() - 1) {
+				sb.append(";");
+			}
+
+		}
+
+		return sb.toString();
+	}
+
+}
diff --git a/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..fb2f3be0a6
--- /dev/null
+++ b/group12/382266293/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,80 @@
+package com.coderising.jvm.test;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+public class ClassFileloaderTest {
+
+	static String path1 = "C:\\Users\\Administrator\\git\\coding2017n\\group12\\382266293\\bin";
+	static String path2 = "C:\temp";
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testClassPath() {
+
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+
+		String clzPath = loader.getClassPath();
+
+		Assert.assertEquals(path1 + ";" + path2, clzPath);
+
+	}
+
+	@Test
+	public void testClassFileLength() {
+
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+
+		String className = "com.coderising.jvm.test.EmployeeV1";
+
+		byte[] byteCodes = loader.readBinaryCode(className);
+
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+
+	}
+
+	@Test
+	public void testMagicNumber() {
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[] { byteCodes[0], byteCodes[1], byteCodes[2], byteCodes[3] };
+
+		String acctualValue = this.byteToHexString(codes);
+
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+
+	private String byteToHexString(byte[] codes) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < codes.length; i++) {
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if (strHex.length() < 2) {
+				strHex = "0" + strHex;
+			}
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java b/group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..d36b122f60
--- /dev/null
+++ b/group12/382266293/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,30 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+
+	private String name;
+	private int age;
+
+	public EmployeeV1(String name, int age) {
+		this.name = name;
+		this.age = age;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setAge(int age) {
+		this.age = age;
+	}
+
+	public void sayHello() {
+		System.out.println("Hello , this is class Employee ");
+	}
+
+	public static void main(String[] args) {
+		EmployeeV1 p = new EmployeeV1("Andy", 29);
+		p.sayHello();
+
+	}
+}
\ No newline at end of file
diff --git a/group12/382266293/src/com/coderising/litestruts/LoginAction.java b/group12/382266293/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..a3ce652047
--- /dev/null
+++ b/group12/382266293/src/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
\ No newline at end of file
diff --git a/group12/382266293/src/litestruts/Configuration.java b/group12/382266293/src/litestruts/Configuration.java
index 9b7d4e8466..4efedbce67 100644
--- a/group12/382266293/src/litestruts/Configuration.java
+++ b/group12/382266293/src/litestruts/Configuration.java
@@ -1,9 +1,9 @@
 package litestruts;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
-
 import org.jdom2.Document;
 import org.jdom2.Element;
 import org.jdom2.JDOMException;
@@ -11,15 +11,13 @@
 import static util.Print.*;
 public class Configuration {
 
-	
-	ActionCfg actionCfg = new ActionCfg();
-	
+	Map<String,ActionCfg> actions = new HashMap<>();
+
 	private static Configuration cfg = new Configuration();
 	
 	private Configuration() {
-		
+
 	}
-	
 	public static Configuration getNewInstance() {
 		
 		if (cfg == null) {
@@ -28,75 +26,108 @@ public static Configuration getNewInstance() {
 		return cfg;
 	}
 	
-	private String getFile(String fileName) {
+	public void parse(String fileName) {
 		
 		String src = this.getClass().getPackage().getName();
-		return "file://" + src + "\\" + fileName + ".xml";
+		String filepath = src.replace(".", "/") + "/" +fileName;
+
+		InputStream is = this.getClass().getResourceAsStream("/" + filepath);
+		
+		parseXML(is);
+		
+		try {
+			is.close();
+		} catch (IOException e) {			
+			
+		}
+		
 	}
 	
-	public void parseAction(String src) {
-		
-		String fileName = getFile(src);
+	public void parseXML(InputStream is) {
+
 		SAXBuilder reader = new SAXBuilder();
 	    try {
-			Document doc = reader.build("C:\\struts.xml");
+			Document doc = reader.build(is);
 			Element root = doc.getRootElement();
 			
 			for(Element element : root.getChildren("action")) {
 				
-				String name = element.getAttributeValue("name");
+				String actionName = element.getAttributeValue("name");
 				String clz = element.getAttributeValue("class");
-				actionCfg.actionInfo.put(name, clz);
+				ActionCfg ac = new ActionCfg(actionName,clz);
 				
 				for(Element e : element.getChildren("result")) {
 					
 					String result = e.getAttributeValue("name");
 					String jsp = e.getText().trim();
-					println("result:" + result + "jsp:" + jsp);
-					Map<String,String> res = new HashMap<>();
-					res.put(result, jsp);
-					actionCfg.resultInfo.put(name, res);
+					ac.addViewResult(result, jsp);
 				}
+				
+				actions.put(actionName, ac);
 			}
 			
 		} catch (JDOMException | IOException e) {
 			e.printStackTrace();
 		}
- 
+	}
+	
+	
+	public String getClassName(String action) {
+		ActionCfg cfg = this.actions.get(action);
+		if (cfg == null) {
+			return null;
+		}
+		return cfg.getClassName(); 
+	}
+	
+	
+	public String getResultView(String action, String resultName) {
+		ActionCfg cfg = this.actions.get(action);
+		if (cfg == null) {
+			return null;
+		}
+		return cfg.getViewResult().get(resultName); 
 	}
 
 	public static void main(String[] args) {
 		Configuration cfg = new Configuration();
-		cfg.parseAction("struts");
-		Map info = cfg.getActionInfo();
-		Map result = cfg.getResultInfo().get("login");
-		println(info);
-		println(result);
+		cfg.parse("struts.xml");
+		String clz = cfg.getClassName("login");
+		println(clz);
+		
+
 	}
 
+
 	
 	private static class ActionCfg {
 		
-		private Map<String,String> actionInfo;
-		private Map<String,Map<String,String>> resultInfo;
-		public ActionCfg() {
-			this.actionInfo = new HashMap<String,String>();
-			this.resultInfo = new HashMap<String,Map<String,String>>();
+		String name;
+		String clz;
+		Map<String,String> viewResult = new HashMap<>();
+
+		public Map<String, String> getViewResult() {
+			return viewResult;
+		}
+
+		public ActionCfg(String name, String clz) {
+			this.name = name;
+			this.clz = clz;
 		}
-		
-	}
 
+		public void addViewResult(String result, String jsp) {
+			viewResult.put(result, jsp);
+			
+		}
 
-	public Map<String, Map<String,String>> getResultInfo() {
-		
-		return actionCfg.resultInfo;
-	}
+		public String getClassName() {
+			return clz;
+		}
 
-	public Map<String, String> getActionInfo() {
-		
-		return actionCfg.actionInfo;
 	}
-	
+
+
+
 	
 	
 
diff --git a/group12/382266293/src/litestruts/ConfigurationTest.java b/group12/382266293/src/litestruts/ConfigurationTest.java
index 1b5d2f43e1..e9d41a07c9 100644
--- a/group12/382266293/src/litestruts/ConfigurationTest.java
+++ b/group12/382266293/src/litestruts/ConfigurationTest.java
@@ -1,32 +1,54 @@
 package litestruts;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+
+
 public class ConfigurationTest {
 
+	
+	Configuration cfg = Configuration.getNewInstance();
+	
+	
+	
 	@Before
 	public void setUp() throws Exception {
+		
+		cfg.parse("struts.xml");
 	}
 
 	@After
 	public void tearDown() throws Exception {
+
 	}
 
 	@Test
-	public void testGetGetterMethods() {
-		Configuration cfg = Configuration.getNewInstance();
-		Map<String,String> actionName = new HashMap<>();
-		actionName.put("login","com.coderising.action.LoginAction");
-		actionName.put("logout","com.coderising.action.LogoutAction");
+	public void testGetClassName() {
+		
+		String clzName = cfg.getClassName("login");
+		Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName);
+		
+		
+		clzName = cfg.getClassName("logout");
+		Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName);
+	}
+	
+	@Test
+	public void testGetResultView(){
+		String jsp = cfg.getResultView("login","success");
+		Assert.assertEquals("/jsp/homepage.jsp", jsp);
 		
-		//Assert.assertTrue(cfg.getActionName().containsKey(actionName));
+		jsp = cfg.getResultView("login","fail");
+		Assert.assertEquals("/jsp/showLogin.jsp", jsp);
 		
+		jsp = cfg.getResultView("logout","success");
+		Assert.assertEquals("/jsp/welcome.jsp", jsp);
 		
+		jsp = cfg.getResultView("logout","error");
+		Assert.assertEquals("/jsp/error.jsp", jsp);
 		
 	}
 
diff --git a/group12/382266293/src/litestruts/StrutsTest.java b/group12/382266293/src/litestruts/StrutsTest.java
index 35686c8e30..4b59f846f5 100644
--- a/group12/382266293/src/litestruts/StrutsTest.java
+++ b/group12/382266293/src/litestruts/StrutsTest.java
@@ -1,17 +1,19 @@
 package litestruts;
 
-import java.beans.IntrospectionException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.junit.Assert;
 import org.junit.Test;
 
+
+
+
+
 public class StrutsTest {
 
 	@Test
-	public void testLoginActionSuccess() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
+	public void testLoginActionSuccess() {
 		
 		String actionName = "login";
         
@@ -27,7 +29,7 @@ public void testLoginActionSuccess() throws InstantiationException, IllegalAcces
 	}
 
 	@Test
-	public void testLoginActionFailed() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
+	public void testLoginActionFailed() {
 		String actionName = "login";
 		Map<String,String> params = new HashMap<String,String>();
         params.put("name","test");
@@ -38,4 +40,4 @@ public void testLoginActionFailed() throws InstantiationException, IllegalAccess
         Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
         Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
 	}
-}
\ No newline at end of file
+}
diff --git a/group12/382266293/src/litestruts/struts.xml b/group12/382266293/src/litestruts/struts.xml
index fb0c2be3de..4c6eeabbd4 100644
--- a/group12/382266293/src/litestruts/struts.xml
+++ b/group12/382266293/src/litestruts/struts.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <struts>
-    <action name="login" class="com.coderising.action.LoginAction">
+    <action name="login" class="com.coderising.litestruts.LoginAction">
         <result name="success">/jsp/homepage.jsp</result>
         <result name="fail">/jsp/showLogin.jsp</result>
     </action>
-    <action name="logout" class="com.coderising.action.LogoutAction">
+    <action name="logout" class="com.coderising.litestruts.LogoutAction">
     	<result name="success">/jsp/welcome.jsp</result>
     	<result name="error">/jsp/error.jsp</result>
     </action>
diff --git a/group12/446031103/src/com/coderising/download/DownloadThread.java b/group12/446031103/src/com/coderising/download/DownloadThread.java
index 900a3ad358..4daa1baf3c 100644
--- a/group12/446031103/src/com/coderising/download/DownloadThread.java
+++ b/group12/446031103/src/com/coderising/download/DownloadThread.java
@@ -1,5 +1,10 @@
 package com.coderising.download;
 
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
 import com.coderising.download.api.Connection;
 
 public class DownloadThread extends Thread{
@@ -7,14 +12,34 @@ public class DownloadThread extends Thread{
 	Connection conn;
 	int startPos;
 	int endPos;
-
-	public DownloadThread( Connection conn, int startPos, int endPos){
+	CyclicBarrier barrier;
+	String localFile;
+	public DownloadThread( Connection conn, int startPos, int endPos, String localFile, CyclicBarrier barrier){
 		
 		this.conn = conn;		
 		this.startPos = startPos;
 		this.endPos = endPos;
+		this.localFile = localFile;
+		this.barrier  = barrier;
 	}
 	public void run(){	
-		
+		try {
+			byte[] data =conn.read(startPos, endPos);
+			RandomAccessFile file = new RandomAccessFile(localFile,"rw");
+			file.seek(startPos);
+			file.write(data);
+			file.close();
+			conn.close();
+			barrier.await();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (BrokenBarrierException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 	}
 }
diff --git a/group12/446031103/src/com/coderising/download/FileDownloader.java b/group12/446031103/src/com/coderising/download/FileDownloader.java
index c3c8a3f27d..5cbb88410a 100644
--- a/group12/446031103/src/com/coderising/download/FileDownloader.java
+++ b/group12/446031103/src/com/coderising/download/FileDownloader.java
@@ -1,7 +1,11 @@
 package com.coderising.download;
 
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
 import com.coderising.download.api.Connection;
-import com.coderising.download.api.ConnectionException;
 import com.coderising.download.api.ConnectionManager;
 import com.coderising.download.api.DownloadListener;
 
@@ -14,9 +18,12 @@ public class FileDownloader {
 	
 	ConnectionManager cm;
 	
+	private String localFile;
+	private static final int DOWNLOAD_TRHEAD_NUM = 3;
 
-	public FileDownloader(String _url) {
+	public FileDownloader(String _url,String _localFile) {
 		this.url = _url;
+		this.localFile = _localFile;
 		
 	}
 	
@@ -34,16 +41,36 @@ public void execute(){
 		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
 		
 		// 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+		CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_TRHEAD_NUM , new Runnable(){
+			public void run(){
+				listener.notifyFinished();
+			}
+		}); 
+		
 		Connection conn = null;
 		try {
 			
 			conn = cm.open(this.url);
 			
 			int length = conn.getContentLength();	
+
+			createPlaceHolderFile(this.localFile,length);
+			
+			int[][] ranges = allocateDownloadRange(DOWNLOAD_TRHEAD_NUM, length);
 			
-			new DownloadThread(conn,0,length-1).start();
+			for(int i=0; i< DOWNLOAD_TRHEAD_NUM; i++){
 			
-		} catch (ConnectionException e) {			
+				
+				DownloadThread thread = new DownloadThread(
+						cm.open(url), 
+						ranges[i][0], 
+						ranges[i][1], 
+						localFile, 
+						barrier);
+				
+				thread.start();				
+			}
+		} catch (Exception e) {			
 			e.printStackTrace();
 		}finally{
 			if(conn != null){
@@ -56,6 +83,37 @@ public void execute(){
 		
 	}
 	
+	private int[][] allocateDownloadRange(int threadNum, int contentLen) {
+		int[][] ranges = new int[threadNum][2];
+		
+		int eachThreadSize = contentLen / threadNum;// 每个线程需要下载的文件大小
+		int left = contentLen % threadNum;// 剩下的归最后一个线程来处理
+		
+		for(int i=0;i<threadNum;i++){
+			
+			int startPos = i * eachThreadSize;
+			
+			int endPos = (i + 1) * eachThreadSize - 1;
+			
+			if ((i == (threadNum - 1))) {
+				endPos += left;
+			}
+			ranges[i][0] = startPos;
+			ranges[i][1] = endPos;
+			
+		}
+		
+		return ranges;
+	}
+
+	private void createPlaceHolderFile(String fileName, int length) throws IOException {
+		RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
+		for (int i = 0; i < length; i++) {
+			raf.write(0);
+		}
+		raf.close();
+	}
+
 	public void setListener(DownloadListener listener) {
 		this.listener = listener;
 	}
diff --git a/group12/446031103/src/com/coderising/download/impl/ConnectionImpl.java b/group12/446031103/src/com/coderising/download/impl/ConnectionImpl.java
index 36a9d2ce15..ee1fe3490f 100644
--- a/group12/446031103/src/com/coderising/download/impl/ConnectionImpl.java
+++ b/group12/446031103/src/com/coderising/download/impl/ConnectionImpl.java
@@ -1,20 +1,63 @@
 package com.coderising.download.impl;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
 
 import com.coderising.download.api.Connection;
-
-public class ConnectionImpl implements Connection{
+	
+ class ConnectionImpl implements Connection{
+	 static final int BUFFER_SIZE = 1024;
+	 URL url;
+	 ConnectionImpl(String theUrl) {
+		try {
+			url=new URL(theUrl);
+		} catch (MalformedURLException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
 
 	@Override
 	public byte[] read(int startPos, int endPos) throws IOException {
-		
-		return null;
+		HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+		//?????
+		httpConn.setRequestProperty("Range", "bytes=" + startPos + "-"
+                + endPos);
+		InputStream is = httpConn.getInputStream();
+		 byte[] buff = new byte[BUFFER_SIZE];
+		 int totalLen = endPos - startPos + 1;
+		 ByteArrayOutputStream baos = new ByteArrayOutputStream();    
+		 while(baos.size()<totalLen){
+			int len = is.read();
+			if(len<0){
+				break;
+			}
+			//????
+			baos.write(buff,0, len);  
+		 }
+		 if(baos.size() > totalLen){
+	        	byte[] data = baos.toByteArray();
+	        	return Arrays.copyOf(data, totalLen);
+	        }
+		return baos.toByteArray();
 	}
 
 	@Override
 	public int getContentLength() {
-		
+		URLConnection openConnection;
+		try {
+			openConnection = url.openConnection();
+			return openConnection.getContentLength();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 		return 0;
 	}
 
diff --git a/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java
index 172371dd55..18836b4a28 100644
--- a/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java
+++ b/group12/446031103/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -9,7 +9,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
 	@Override
 	public Connection open(String url) throws ConnectionException {
 		
-		return null;
+		return new ConnectionImpl(url);
 	}
 
 }
diff --git a/group12/446031103/src/com/coderising/download/test/ConnectionTest.java b/group12/446031103/src/com/coderising/download/test/ConnectionTest.java
new file mode 100644
index 0000000000..cda74451ca
--- /dev/null
+++ b/group12/446031103/src/com/coderising/download/test/ConnectionTest.java
@@ -0,0 +1,53 @@
+package com.coderising.download.test;
+
+
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class ConnectionTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testContentLength() throws Exception{
+		ConnectionManager connMan = new ConnectionManagerImpl();
+		Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");		
+		Assert.assertEquals(35470, conn.getContentLength());
+	}
+	
+	@Test
+	public void testRead() throws Exception{
+		
+		ConnectionManager connMan = new ConnectionManagerImpl();
+		Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");
+		
+		byte[] data = conn.read(0, 35469);
+		
+		Assert.assertEquals(35470, data.length);
+		
+		data = conn.read(0, 1023);
+		
+		Assert.assertEquals(1024, data.length);
+		
+		data = conn.read(1024, 2023);
+		
+		Assert.assertEquals(1000, data.length);
+		
+		
+		// 测试不充分，没有断言内容是否正确
+	}
+
+}
diff --git a/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java b/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java
new file mode 100644
index 0000000000..a3e7d24429
--- /dev/null
+++ b/group12/446031103/src/com/coderising/download/test/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coderising.download.test;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.FileDownloader;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		String url = "http://images2015.cnblogs.com/blog/610238/201604/610238-20160421154632101-286208268.png";
+		
+		FileDownloader downloader = new FileDownloader(url,"E:\\TEST\\test.jpg");
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+
+	}
+
+}
diff --git a/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..e021b94d38
--- /dev/null
+++ b/group12/446031103/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,43 @@
+package com.coderising.jvm.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		
+		return null;	
+		
+		
+	}
+	
+	private byte[] loadClassFile(String clzFileName) {
+		
+		return null;
+	}
+	
+	
+	
+	public void addClassPath(String path) {
+		
+	}
+	
+	public String getClassPath_V1(){
+		
+		return  null;
+	}
+	
+	public String getClassPath(){
+		return null;
+	}
+
+	
+
+	
+
+}
diff --git a/group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..50eb1be6fa
--- /dev/null
+++ b/group12/446031103/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin";
+	static String path2 = "C:\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java b/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..5e2bd8668f
--- /dev/null
+++ b/group12/446031103/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
diff --git a/group12/446031103/src/com/coderising/litestruts/Configuration.java b/group12/446031103/src/com/coderising/litestruts/Configuration.java
new file mode 100644
index 0000000000..1df7369eff
--- /dev/null
+++ b/group12/446031103/src/com/coderising/litestruts/Configuration.java
@@ -0,0 +1,91 @@
+package com.coderising.litestruts;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+public class Configuration {
+	Map<String,ActionConfig> actions = new HashMap<>();
+	
+	public Configuration(String fileName){
+		String packageName = this.getClass().getPackage().getName();		
+		packageName = packageName.replace('.', '/');		
+		InputStream is = this.getClass().getResourceAsStream("/" + packageName + "/" + fileName);
+		parseXML(is);
+	}
+	
+	
+
+	private void parseXML(InputStream is) {
+		SAXReader reader = new SAXReader();
+		try {
+			Document document = reader.read(is);
+			Element struts = document.getRootElement();
+			Iterator<?> actions = struts.elementIterator();
+			while (actions.hasNext()) {
+				Element action = (Element) actions.next();
+				String actionName=action.attributeValue("name");
+				String actionClass=action.attributeValue("class");
+				ActionConfig ac = new ActionConfig(actionName,actionClass);
+					Iterator<?> results = action.elementIterator();
+					while (results.hasNext()) {
+						Element result = (Element) results.next();
+						String name = result.attributeValue("name");
+						String viewName = result.getStringValue();
+						ac.addViewResult(name, viewName);					
+				}
+					this.actions.put(actionName, ac);
+			}
+		} catch (DocumentException e) {
+			
+			e.printStackTrace();
+		}
+		
+	}
+
+
+
+	public String getClassName(String actionName) {
+		ActionConfig actionConfig = actions.get(actionName);
+		if(null==actionConfig)
+			return null;
+		return actionConfig.getClassName();
+	}
+	
+	public String getResultView(String actionName, String resultName) {
+		ActionConfig actionConfig =actions.get(actionName);
+		if(null==actionConfig)
+			return null;
+		return actionConfig.getViewName(resultName);
+	}
+	
+	private static class ActionConfig{
+		
+		String name;
+		String clzName;
+		Map<String,String> viewResult = new HashMap<>();
+		
+		
+		public ActionConfig(String actionName, String clzName) {
+			this.name = actionName;
+			this.clzName = clzName;
+		}
+		public String getClassName(){
+			return clzName;
+		}
+		public void addViewResult(String name, String viewName){
+			viewResult.put(name, viewName);
+		}
+		public String getViewName(String resultName){
+			return viewResult.get(resultName);
+		}
+	}
+
+	
+}
diff --git a/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java b/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java
new file mode 100644
index 0000000000..f4af430eef
--- /dev/null
+++ b/group12/446031103/src/com/coderising/litestruts/ConfigurationTest.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class ConfigurationTest {
+	Configuration cfg = new Configuration("struts.xml");
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testGetClassName() {
+		String clzName = cfg.getClassName("login");
+		Assert.assertEquals("com.coderising.litestruts.LoginAction", clzName);
+		 clzName = cfg.getClassName("logout");
+		Assert.assertEquals("com.coderising.litestruts.LogoutAction", clzName);
+	}
+	@Test
+	public void testGetResultView() {
+		String jsp=cfg.getResultView("login","success");
+		Assert.assertEquals("/jsp/homepage.jsp", jsp);
+		 jsp=cfg.getResultView("login","fail");
+		Assert.assertEquals("/jsp/showLogin.jsp", jsp);
+		jsp=cfg.getResultView("logout","success");
+		Assert.assertEquals("/jsp/welcome.jsp", jsp);
+		jsp=cfg.getResultView("logout","error");
+		Assert.assertEquals("/jsp/error.jsp", jsp);
+	}
+}
diff --git a/group12/446031103/src/com/coderising/litestruts/LoginAction.java b/group12/446031103/src/com/coderising/litestruts/LoginAction.java
index 39af2d5c26..dcdbe226ed 100644
--- a/group12/446031103/src/com/coderising/litestruts/LoginAction.java
+++ b/group12/446031103/src/com/coderising/litestruts/LoginAction.java
@@ -36,7 +36,4 @@ public void setPassword(String password){
     public String getMessage(){
         return this.message;
     }
-    public void setMessage(String message){
-    	this.message = message;
-    }
 }
diff --git a/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java b/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java
new file mode 100644
index 0000000000..c9bbd312ef
--- /dev/null
+++ b/group12/446031103/src/com/coderising/litestruts/ReflectionUtil.java
@@ -0,0 +1,75 @@
+package com.coderising.litestruts;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ReflectionUtil {
+
+	public static List<Method> getSetterMethods(Class<?> clz) {
+		
+		return getMethods(clz,"set");
+	}
+
+	public static List<Method> getGetterMethods(Class<?> clz) {		
+		return getMethods(clz,"get");
+	}
+
+	public static List<Method> getMethods(Class<?> clz,String startsWithName) {
+		List<Method> methods = new ArrayList<>();
+		for (Method method : clz.getDeclaredMethods()) {
+			if(method.getName().startsWith(startsWithName)){
+				methods.add(method);
+			}
+		}
+		return methods;
+	}
+
+	public static void setParams(Object o, Map<String, String> params) {
+		List<Method> methods = getSetterMethods(o.getClass());
+		for (String name : params.keySet()) {
+			String methodName = "set"+name;
+			for (Method method : methods) {
+				if(methodName.equalsIgnoreCase(method.getName())){
+					try {
+						method.invoke(o, params.get(name));
+					} catch (IllegalAccessException e) {
+						e.printStackTrace();
+					} catch (IllegalArgumentException e) {
+						e.printStackTrace();
+					} catch (InvocationTargetException e) {
+						e.printStackTrace();
+					}
+				};
+			}
+			
+		}
+	}
+
+	public static Map<String, Object> getParams(Object o) {
+		Map<String ,Object> params = new HashMap<>();
+		List<Method> methods = getGetterMethods(o.getClass());
+		for (Method method : methods) {
+			try {
+				String name=method.getName();
+				 name = name.replaceFirst("get", "").toLowerCase();
+				Object value = method.invoke(o);
+				params.put(name, value);
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (InvocationTargetException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		return params;
+	}
+
+}
diff --git a/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java b/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java
new file mode 100644
index 0000000000..f1b233be37
--- /dev/null
+++ b/group12/446031103/src/com/coderising/litestruts/ReflectionUtilTest.java
@@ -0,0 +1,96 @@
+package com.coderising.litestruts;
+
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ReflectionUtilTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testGetSetterMethod() throws ClassNotFoundException {
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		List<Method> methods=ReflectionUtil.getSetterMethods(clz);
+		Assert.assertEquals(2, methods.size());
+		
+		List<String> expectedNames = new ArrayList<>();
+		expectedNames.add("setName");
+		expectedNames.add("setPassword");
+		
+		Set<String> acctualNames = new HashSet<>();
+		for(Method m : methods){
+			acctualNames.add(m.getName());
+		}
+		Assert.assertTrue(acctualNames.containsAll(expectedNames));
+	}
+	@Test
+	public void testGetGetterMethod() throws ClassNotFoundException {
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		List<Method> methods=ReflectionUtil.getGetterMethods(clz);
+		Assert.assertEquals(3, methods.size());
+		
+		List<String> expectedNames = new ArrayList<>();
+		expectedNames.add("getName");
+		expectedNames.add("getPassword");
+		expectedNames.add("getMessage");
+		Set<String> acctualNames = new HashSet<>();
+		for(Method m : methods){
+			acctualNames.add(m.getName());
+		}
+		Assert.assertTrue(acctualNames.containsAll(expectedNames));
+	}
+	@Test
+	public void testSetterParams() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		Object o = clz.newInstance();
+		
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        ReflectionUtil.setParams(o,params);
+        
+        Field f = clz.getDeclaredField("name");
+		f.setAccessible(true);
+		Assert.assertEquals("test", f.get(o));
+		
+		f = clz.getDeclaredField("password");
+		f.setAccessible(true);
+		Assert.assertEquals("1234", f.get(o));
+	}
+	@Test
+	public void testGetterParams() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+		String name = "com.coderising.litestruts.LoginAction";
+		Class<?> clz = Class.forName(name);
+		LoginAction la = (LoginAction) clz.newInstance();
+		la.setName("test");
+		la.setPassword("123456");
+		Map<String,Object> params =ReflectionUtil.getParams(la);
+		Assert.assertEquals(3, params.size());
+		
+		Assert.assertEquals(null, params.get("messaage") );
+		Assert.assertEquals("test", params.get("name") );
+		Assert.assertEquals("123456", params.get("password") );
+	}
+}
diff --git a/group12/446031103/src/com/coderising/litestruts/Struts.java b/group12/446031103/src/com/coderising/litestruts/Struts.java
index 8f5913d836..c4466c1d02 100644
--- a/group12/446031103/src/com/coderising/litestruts/Struts.java
+++ b/group12/446031103/src/com/coderising/litestruts/Struts.java
@@ -9,6 +9,7 @@
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.dom4j.Document;
@@ -24,92 +25,42 @@
  * @version: V1.0
  */
 public class Struts {
+	private final static Configuration cfg = new Configuration("struts.xml");
 	public static View runAction(String actionName, Map<String, String> parameters) {
-		Map<String, String> xmlDoc = getXMLDOC(actionName);
-		Map<String, String> viewMap = new HashMap<String, String>();
-		View view = new View();
-		view.setParameters(viewMap);
-		try {
-			Class<?> classz = Class.forName(xmlDoc.get(actionName));
-			LoginAction la = (LoginAction) classz.newInstance();
-			la.setName(parameters.get("name"));
-			la.setPassword(parameters.get("password"));
-			Method exectue = classz.getMethod("execute", null);
-			Object result = exectue.invoke(la, null);
-			Field[] fields = classz.getDeclaredFields();
-			for (Field field : fields) {
-				PropertyDescriptor pd = new PropertyDescriptor(field.getName(), classz);
-				Method readMethod = pd.getReadMethod();
-				viewMap.put(field.getName(), (String) readMethod.invoke(la, null));
-			}
-			view.setJsp(xmlDoc.get(result));
-		} catch (ClassNotFoundException e) {
-			e.printStackTrace();
-		} catch (InstantiationException e) {
-			e.printStackTrace();
-		} catch (IllegalAccessException e) {
-			e.printStackTrace();
-		} catch (SecurityException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (NoSuchMethodException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IllegalArgumentException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (InvocationTargetException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IntrospectionException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
+		
 		/*
-		 * 0. 读取配置文件struts.xml 1. 根据actionName找到相对应的class ， 例如LoginAction, 通过反射实例化（创建对象），
+		 * 0. 读取配置文件struts.xml 
+		 * 1. 根据actionName找到相对应的class ， 例如LoginAction, 通过反射实例化（创建对象），
 		 * 据parameters中的数据，调用对象的setter方法 例如parameters中的数据是 ("name"="test" , "password"="1234") ,
-		 * 那就应该调用 setName和setPassword方法 2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success" 3.
-		 * 通过反射找到对象的所有getter方法（例如 getMessage）, 通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
-		 * 放到View对象的parameters 4. 根据struts.xml中的 <result> 配置,以及execute的返回值， 确定哪一个jsp，
+		 * 那就应该调用 setName和setPassword方法 
+		 * 2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success" 
+		 * 3.通过反射找到对象的所有getter方法（例如 getMessage）, 通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message": "登录成功"} ,
+		 * 放到View对象的parameters 
+		 * 4. 根据struts.xml中的 <result> 配置,以及execute的返回值， 确定哪一个jsp，
 		 * 放到View对象的jsp字段中。
 		 */
-		return view;
-	}
-	/**
-	 * @MethodName: getXMLDOC
-	 * @Description: 解析xml文件
-	 * @param actionName
-	 * @return
-	 * @return: Map<String,String>
-	 */
-	private static Map<String, String> getXMLDOC(String actionName) {
-		Map<String, String> xmldoc = new HashMap<String, String>();
-		// 解析struts.xml文件
-		// 创建SAXReader的对象reader
-		SAXReader reader = new SAXReader();
+		String className = cfg.getClassName(actionName);
+		
 		try {
-			// 通过reader对象的read方法读取struts.xml，得到document对象
-			Document document = reader.read(new File("src/com/coderising/litestruts/struts.xml"));
-			// 获取根节点<struts></struts>
-			Element struts = document.getRootElement();
-			// 迭代节点
-			Iterator<?> actions = struts.elementIterator();
-			while (actions.hasNext()) {
-				Element action = (Element) actions.next();
-				if (actionName.equals(action.attributeValue("name"))) {
-					xmldoc.put(action.attributeValue("name"), action.attributeValue("class"));
-					Iterator<?> results = action.elementIterator();
-					while (results.hasNext()) {
-						Element result = (Element) results.next();
-						xmldoc.put(result.attributeValue("name"), result.getStringValue());
-					}
-					break;
-				}
-			}
-		} catch (DocumentException e) {
+			Class<?> clz = Class.forName(className);
+			Object o = clz.newInstance();
+			ReflectionUtil.setParams(o, parameters);
+			Method exectue = clz.getDeclaredMethod("execute");
+			String resultName=(String) exectue.invoke(o);
+			Map<String, Object> params = ReflectionUtil.getParams(o);
+			String resultView = cfg.getResultView(actionName, resultName);
+			View v = new View();
+			v.setJsp(resultView);
+			v.setParameters(params);
+			return v;
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
 			e.printStackTrace();
-		} 
-		return xmldoc;
+		}
+
+		
+		return null;
 	}
 	
+	
 }
diff --git a/group12/446031103/src/com/coding/basic/ArrayList.java b/group12/446031103/src/com/datastructure/array/ArrayList.java
similarity index 87%
rename from group12/446031103/src/com/coding/basic/ArrayList.java
rename to group12/446031103/src/com/datastructure/array/ArrayList.java
index bc3d75c3f6..9731daec06 100644
--- a/group12/446031103/src/com/coding/basic/ArrayList.java
+++ b/group12/446031103/src/com/datastructure/array/ArrayList.java
@@ -1,7 +1,10 @@
-package com.coding.basic;
+package com.datastructure.array;
 
 import java.util.Arrays;
 
+import com.datastructure.basic.Iterator;
+import com.datastructure.basic.List;
+
 
 
 /**
@@ -21,7 +24,7 @@ public class ArrayList implements List {
 	 *
 	 * @Method add 添加
 	 * @param o 元素
-	 * @see com.coding.basic.List#add(java.lang.Object)
+	 * @see com.datastructure.basic.List#add(java.lang.Object)
 	 */
 	public void add(Object o){
 		ensureCapacity(size + 1);
@@ -35,7 +38,7 @@ public void add(Object o){
 	 * @Method add 添加
 	 * @param index 下标
 	 * @param o 元素
-	 * @see com.coding.basic.List#add(int, java.lang.Object)
+	 * @see com.datastructure.basic.List#add(int, java.lang.Object)
 	 */
 	public void add(int index, Object o){
 		validate(index);
@@ -51,7 +54,7 @@ public void add(int index, Object o){
 	 * @Method get 取得
 	 * @param index 下标
 	 * @return
-	 * @see com.coding.basic.List#get(int)
+	 * @see com.datastructure.basic.List#get(int)
 	 */
 	public Object get(int index){
 		validate(index);
@@ -64,7 +67,7 @@ public Object get(int index){
 	 * @Method remove 删除
 	 * @param index 下标
 	 * @return 删除的元素
-	 * @see com.coding.basic.List#remove(int)
+	 * @see com.datastructure.basic.List#remove(int)
 	 */
 	public Object remove(int index){		
 		validate(index);
@@ -80,7 +83,7 @@ public Object remove(int index){
 	 *
 	 * @Method size 集合大小
 	 * @return 集合大小
-	 * @see com.coding.basic.List#size()
+	 * @see com.datastructure.basic.List#size()
 	 */
 	public int size(){
 		return this.size;
diff --git a/group12/446031103/src/com/coderising/array/ArrayUtil.java b/group12/446031103/src/com/datastructure/array/ArrayUtil.java
similarity index 51%
rename from group12/446031103/src/com/coderising/array/ArrayUtil.java
rename to group12/446031103/src/com/datastructure/array/ArrayUtil.java
index a771999a22..a5b62040bc 100644
--- a/group12/446031103/src/com/coderising/array/ArrayUtil.java
+++ b/group12/446031103/src/com/datastructure/array/ArrayUtil.java
@@ -1,9 +1,11 @@
-package com.coderising.array;
+package com.datastructure.array;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
+
 public class ArrayUtil {
 	
 	/**
@@ -14,13 +16,15 @@ public class ArrayUtil {
 	 * @return
 	 */
 	public void reverseArray(int[] origin){
-		int end = origin.length-1;
-		int temp ;
-		for (int i = 0; i < end; i++,end--) {
-			temp=origin[i];
-			origin[i]=origin[end];
-			origin[end] = temp;
+		if(null ==origin ||0==origin.length){
+			return;
+		}
+		for (int i = 0,j=origin.length-1; i < j; i++,j--) {
+			int temp=origin[i] ;
+			origin[i]= origin[j];
+			origin[i]=temp;
 		}
+		
 	}
 	
 	/**
@@ -32,23 +36,18 @@ public void reverseArray(int[] origin){
 	 */
 	
 	public int[] removeZero(int[] oldArray){		
-		int zeroCnt = 0;
-		for (int i : oldArray) {
-			if(0==i){
-				zeroCnt++;
-			}
-			
-		}		
-		int size = 0;
-		int [] result = new int[oldArray.length-zeroCnt];
-		for (int i : oldArray) {
-			if(0!=i){
-				result[size]=i;
-				size++;
+		if(null==oldArray||oldArray.length ==0){
+			return null;
+		}
+		int notZeroCnt = 0;
+		int [] temp = new int[oldArray.length];
+		for (int i = 0; i < oldArray.length; i++) {
+			if(oldArray[i]!=0){
+				temp[notZeroCnt++] = oldArray[i];
 			}
-			
 		}
-		return result;
+		System.arraycopy(temp, 0, temp, 0, notZeroCnt);
+		return temp;
 	}
 	
 	/**
@@ -60,31 +59,34 @@ public int[] removeZero(int[] oldArray){
 	 */
 	
 	public int[] merge(int[] array1, int[] array2){		
-		//合拼数组，缺排序，缺去重
+		if(null==array1&&null==array2){
+			return null;
+		}		
 		int [] temp = new int[array1.length+array2.length];
-		System.arraycopy(array1, 0, temp, 0, array1.length);
-		System.arraycopy(array2, 0, temp, array1.length, array2.length);		
-		List<Integer>  resultList= new ArrayList<Integer>();
-		for (int i : temp) {
-			if(!resultList.contains(i))
-				resultList.add(i);
-		}//已去重数组，缺排序
-		int [] result = new int[resultList.size()];
-		for (int i = 0; i < resultList.size(); i++) {
-			result[i] = resultList.get(i);
-		}
-		//冒泡排序
-		for (int i = 0; i < result.length-1; i++) {
-			for (int j = 0; j < result.length-i-1; j++) {
-				if(result[j]>result[j+1]){
-					int tempInt = result[j];
-					result[j] =result[j+1];
-					result[j+1] = tempInt;					
-				}
+		int i = 0;
+		int j = 0;
+		int count = 0;
+		while (i<array1.length&&j<array2.length) {
+			if(array1[i]<array2[j]){
+				temp[count++] = array1[i++];
+			}
+			if(array1[i]>array2[j]){
+				temp[count++] = array2[j++];
+			}
+			if(array1[i]==array2[j]){
+				temp[count++] = array2[j];
+				i++;
+				j++;
 			}
-				
-		}						
-		return  result;
+		}
+		while(i==array1.length&&j<array2.length){
+			temp[count++] = array2[j++];
+		}
+		while(j==array2.length&&i<array1.length){
+			temp[count++] = array1[i++];
+		}
+		System.arraycopy(temp, 0, temp, 0, count);
+		return  temp;
 	}
 	/**
 	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
@@ -107,16 +109,25 @@ public int[] grow(int [] oldArray,  int size){
 	 * @return
 	 */
 	public int[] fibonacci(int max){
-		int first =0;
-		int second = 1;
-		List<Integer>  resultList= new ArrayList<Integer>();		
-		if(max!=second)
-		add(first,second,max,resultList);
-		int [] result = new int[resultList.size()];
-		for (int i = 0; i < resultList.size(); i++) {
-			result[i] = resultList.get(i);
-		}
-		return result;
+		if(1==max){
+			return new int[0];
+		}
+		if(2==max){
+			return new int[]{1,1};
+		}
+		int [] temp = new int [max]  ;
+		temp[0] = 1;
+		temp[1] = 1;
+		int cnt = 2;
+		for (int i = 2 ; i < max; i++) {
+			temp[i] = temp[i-1] + temp[i-2];
+			if(temp[i]>=max){
+				break;
+			}else{
+				cnt++;
+			}
+		}
+		return Arrays.copyOf(temp, cnt);
 	}
 	
 	/**
@@ -126,23 +137,30 @@ public int[] fibonacci(int max){
 	 * @return
 	 */
 	public int[] getPrimes(int max){
-		List<Integer>  resultList= new ArrayList<Integer>();
+		if(max<2){
+			return new int[0];
+		}
+		int [] temp = new int[max];
+		int cnt = 0;
 		for (int i = 2; i < max; i++) {
-			boolean isAdd = true;
-			for (int j = 2; j < i; j++) {
-				if(0==i%j){
-					isAdd = false;
-					break;
-				}					
+			if(isPrime(i)){
+				temp[cnt++] = i;
 			}
-			if(isAdd)
-				resultList.add(i);
 		}
-		int [] result = new int[resultList.size()];
-		for (int i = 0; i < resultList.size(); i++) {
-			result[i] = resultList.get(i);
+		return Arrays.copyOf(temp, cnt);
+	}
+	
+	private boolean isPrime(int n){
+		int i = 2;
+		while(i<n){
+			if(n%i==0){
+				break;
+			}
+			if(n%i!=0){
+				i++;
+			}
 		}
-		return result;
+		return i==n;
 	}
 	
 	/**
@@ -152,22 +170,23 @@ public int[] getPrimes(int max){
 	 * @return
 	 */
 	public int[] getPerfectNumbers(int max){
-		List<Integer>  resultList= new ArrayList<Integer>();
-		for (int i = 1; i < max; i++) {
-			int temp = 0;
+		if(max<0){
+			return null;
+		}
+		int cnt = 0;
+		int [] temp = new int[max];
+		for (int i = 2; i < max; i++) {
+			int sum = 0;
 			for (int j = 1; j < i; j++) {
-				if(0==i%j){
-					temp+=j;
+				if(i%j==0){
+					sum+=j;
 				}
 			}
-			if(i==temp)
-				resultList.add(i);
-		}
-		int [] result = new int[resultList.size()];
-		for (int i = 0; i < resultList.size(); i++) {
-			result[i] = resultList.get(i);
+			if(sum==i){
+				temp[cnt++] = i;
+			}
 		}
-		return result;
+		return Arrays.copyOf(temp, cnt);
 	}
 	
 	/**
@@ -179,24 +198,19 @@ public int[] getPerfectNumbers(int max){
 	 * @return
 	 */
 	public String join(int[] array, String seperator){
-		return Arrays.toString(array).replace("[", "").replace("]", "").replace(", ", seperator);
+		if(null==array||array.length==0){
+			return "";
+		}
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < array.length; i++) {
+			sb.append(array[i]);
+			if(i<array.length-1){
+				sb.append(seperator);
+			}
+		}
+		return sb.toString();
 	}
 	
-	/**
-	 * 
-	 * @param number1
-	 * @param number2
-	 * @param max
-	 * @param resultList
-	 * @return
-	 */
-	public List<Integer> add(int number1,int number2,int max,List<Integer>  resultList){
-		if(number2<max){
-			resultList.add(number2);
-			return add(number2,number1+number2,max,resultList);
-		}else{
-			return resultList;
-		}			
-	};
+	
 
 }
diff --git a/group12/446031103/src/com/coderising/array/ArrayUtilTest.java b/group12/446031103/src/com/datastructure/array/ArrayUtilTest.java
similarity index 98%
rename from group12/446031103/src/com/coderising/array/ArrayUtilTest.java
rename to group12/446031103/src/com/datastructure/array/ArrayUtilTest.java
index a22ac30c9b..295a463754 100644
--- a/group12/446031103/src/com/coderising/array/ArrayUtilTest.java
+++ b/group12/446031103/src/com/datastructure/array/ArrayUtilTest.java
@@ -1,4 +1,4 @@
-package com.coderising.array;
+package com.datastructure.array;
 
 import static org.junit.Assert.*;
 
diff --git a/group12/446031103/src/com/coding/basic/BinaryTreeNode.java b/group12/446031103/src/com/datastructure/basic/BinaryTreeNode.java
similarity index 96%
rename from group12/446031103/src/com/coding/basic/BinaryTreeNode.java
rename to group12/446031103/src/com/datastructure/basic/BinaryTreeNode.java
index ed26d946bb..73be06fad2 100644
--- a/group12/446031103/src/com/coding/basic/BinaryTreeNode.java
+++ b/group12/446031103/src/com/datastructure/basic/BinaryTreeNode.java
@@ -1,4 +1,4 @@
-package com.coding.basic;
+package com.datastructure.basic;
 
 
 public class BinaryTreeNode {
diff --git a/group12/446031103/src/com/datastructure/basic/Iterator.java b/group12/446031103/src/com/datastructure/basic/Iterator.java
new file mode 100644
index 0000000000..bee5d797c9
--- /dev/null
+++ b/group12/446031103/src/com/datastructure/basic/Iterator.java
@@ -0,0 +1,7 @@
+package com.datastructure.basic;
+
+public interface Iterator {
+	public boolean hasNext();
+	public Object next();
+
+}
diff --git a/group12/446031103/src/com/datastructure/basic/List.java b/group12/446031103/src/com/datastructure/basic/List.java
new file mode 100644
index 0000000000..633f1f73e2
--- /dev/null
+++ b/group12/446031103/src/com/datastructure/basic/List.java
@@ -0,0 +1,9 @@
+package com.datastructure.basic;
+
+public interface List {
+	public void add(Object o);
+	public void add(int index, Object o);
+	public Object get(int index);
+	public Object remove(int index);
+	public int size();
+}
diff --git a/group12/446031103/src/com/coding/basic/Queue.java b/group12/446031103/src/com/datastructure/basic/Queue.java
similarity index 93%
rename from group12/446031103/src/com/coding/basic/Queue.java
rename to group12/446031103/src/com/datastructure/basic/Queue.java
index 3844d9dd24..b82627d59f 100644
--- a/group12/446031103/src/com/coding/basic/Queue.java
+++ b/group12/446031103/src/com/datastructure/basic/Queue.java
@@ -1,4 +1,6 @@
-package com.coding.basic;
+package com.datastructure.basic;
+
+import com.datastructure.linklist.LinkedList;
 
 /**
  * 
diff --git a/group12/446031103/src/com/coding/basic/Stack.java b/group12/446031103/src/com/datastructure/basic/Stack.java
similarity index 94%
rename from group12/446031103/src/com/coding/basic/Stack.java
rename to group12/446031103/src/com/datastructure/basic/Stack.java
index 4d1c58b671..3088b0a000 100644
--- a/group12/446031103/src/com/coding/basic/Stack.java
+++ b/group12/446031103/src/com/datastructure/basic/Stack.java
@@ -1,4 +1,6 @@
-package com.coding.basic;
+package com.datastructure.basic;
+
+import com.datastructure.array.ArrayList;
 
 /**
  * 
diff --git a/group12/446031103/src/com/datastructure/linklist/LRUPageFrame.java b/group12/446031103/src/com/datastructure/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..5e20d9a49e
--- /dev/null
+++ b/group12/446031103/src/com/datastructure/linklist/LRUPageFrame.java
@@ -0,0 +1,158 @@
+package com.datastructure.linklist;
+
+import java.util.Objects;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(Node prev,Node next,int pageNum) {
+			this.prev = prev;
+			this.next = next;
+			this.pageNum = pageNum;
+		}
+		Node(){
+			
+		}
+	}
+
+	private int capacity;
+	private int addCnt ;
+	private int size;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		first = new Node();
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		if(null==this.last){
+			this.last = new Node(this.first,null,pageNum);
+			this.first.next = this.last;
+			addCnt++;
+			size++;
+			return;
+		}
+		if(contain(pageNum)){
+			 if(Objects.equals(this.first.next.pageNum, pageNum)){
+				 return;
+			 }
+			 boolean temp = Objects.equals(getLastNode(size).pageNum, pageNum);
+			 Node currentNode = getNode(pageNum);
+			 Node nextNode = currentNode.next;
+			 Node preNode = currentNode.prev;
+			 
+			 currentNode.prev = this.first;
+			 currentNode.next = this.first.next;
+			 this.first.next = currentNode;
+			 
+			 if(temp){
+				 preNode.next = null;
+				 if(null==preNode.prev)
+					 preNode.prev = currentNode;
+			 }else{
+				 preNode.prev = currentNode;
+				 preNode.next = nextNode;
+				 nextNode.next = null;
+				 nextNode.prev = preNode;
+			 }
+			 this.last = getLastNode(size);
+			 return;
+		}
+		Node addNode = new Node(this.first,this.first.next,pageNum);
+		Node oldFirstnode=this.first.next ;
+		oldFirstnode.prev = addNode;
+		this.first.next = addNode;
+		if(isOut()){
+			
+			addCnt++;
+			if(this.size !=this.capacity )
+				size++;			
+			if(addCnt>size)
+				this.last.prev.next = null;
+			this.last = getLastNode(size);
+		}else{
+			this.last.prev.next = null;
+		}
+		
+	
+	}
+	
+	private boolean isOut(){
+		return this.addCnt<=this.capacity;
+	}
+	
+	private Node getLastNode(int sizes) {		
+		Node node=this.first;
+		for (int i = 0; i < sizes; i++) {
+			node = node.next;
+		}
+		return node;
+	}
+
+	private boolean contain(Object o){
+		Node node = this.first;
+		
+		while(null!=node.next){	
+			
+			node = node.next;
+			
+			if(Objects.equals(node.pageNum,o)){
+				return true;
+			}	
+			
+		}		
+		return false;		
+	}
+	
+	private Node getNode(Object o){
+		Node node = this.first;
+		
+		while(null!=node.next){	
+			
+			node = node.next;
+			
+			if(Objects.equals(node.pageNum,o)){
+				return node;
+			}	
+			
+		}
+		return null;
+	}
+	
+	
+	
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node.next != null){
+			node = node.next;
+			buffer.append(node.pageNum);
+			if(node.next != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
\ No newline at end of file
diff --git a/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java b/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..956aa6c697
--- /dev/null
+++ b/group12/446031103/src/com/datastructure/linklist/LRUPageFrameTest.java
@@ -0,0 +1,46 @@
+package com.datastructure.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+		
+//		frame.access(7);
+//		Assert.assertEquals("7", frame.toString());
+//		frame.access(7);
+//		Assert.assertEquals("7", frame.toString());
+//		frame.access(2);
+//		Assert.assertEquals("2,7", frame.toString());
+//		frame.access(7);
+//		Assert.assertEquals("7,2", frame.toString());
+//		frame.access(3);
+//		Assert.assertEquals("3,7,2", frame.toString());
+//		frame.access(2);
+//		Assert.assertEquals("2,3,7", frame.toString());
+//		frame.access(2);
+//		Assert.assertEquals("2,3,7", frame.toString());
+	}
+
+}
diff --git a/group12/446031103/src/com/coding/basic/LinkedList.java b/group12/446031103/src/com/datastructure/linklist/LinkedList.java
similarity index 74%
rename from group12/446031103/src/com/coding/basic/LinkedList.java
rename to group12/446031103/src/com/datastructure/linklist/LinkedList.java
index 33f6d79e65..1236734423 100644
--- a/group12/446031103/src/com/coding/basic/LinkedList.java
+++ b/group12/446031103/src/com/datastructure/linklist/LinkedList.java
@@ -1,11 +1,8 @@
-package com.coding.basic;
+package com.datastructure.linklist;
+import java.util.Stack;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.junit.experimental.theories.Theories;
-
-import sun.reflect.Reflection;
+import com.datastructure.basic.Iterator;
+import com.datastructure.basic.List;
 
 /**
  * 
@@ -26,7 +23,7 @@ public class LinkedList implements List {
 	 *
 	 * @Method add 添加
 	 * @param o 元素
-	 * @see com.coding.basic.List#add(java.lang.Object)
+	 * @see com.datastructure.basic.List#add(java.lang.Object)
 	 */
 	public void add(Object o){
 		Node newNode = new Node(o, null);
@@ -48,7 +45,7 @@ public void add(Object o){
 	 * @Method add 增加
 	 * @param index 下标
 	 * @param o 元素
-	 * @see com.coding.basic.List#add(int, java.lang.Object)
+	 * @see com.datastructure.basic.List#add(int, java.lang.Object)
 	 */
 	public void add(int index , Object o){
 		validate(index);
@@ -85,7 +82,7 @@ public void add(int index , Object o){
 	 * @Method get 取得
 	 * @param index 下标
 	 * @return
-	 * @see com.coding.basic.List#get(int)
+	 * @see com.datastructure.basic.List#get(int)
 	 */
 	public Object get(int index){
 		validate(index);
@@ -102,7 +99,7 @@ public Object get(int index){
 	 * @Method remove 删除
 	 * @param index 下标
 	 * @return
-	 * @see com.coding.basic.List#remove(int)
+	 * @see com.datastructure.basic.List#remove(int)
 	 */
 	public Object remove(int index){
 		Node removeNode = (Node) get(index);
@@ -128,7 +125,7 @@ public Object remove(int index){
 	 *
 	 * @Method size 集合大小
 	 * @return 集合大小
-	 * @see com.coding.basic.List#size()
+	 * @see com.datastructure.basic.List#size()
 	 */
 	public int size(){
 		return size;
@@ -233,13 +230,21 @@ public Node(Object data, Node next) {
 	 * 把该链表逆置
 	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
 	 */
-	public  void reverse(){		
-		for (int i = size; i <0; i--) {
-			Node last=(Node) get(i);
-			if(0==i)
-				last.next = null;
-			else
-			last.next = (Node) get(i-1);
+	public  void reverse(){	
+		Stack s=new Stack();
+		Node currentNode = head;
+		while(null!=currentNode){
+			s.push(currentNode);
+			Node tempNode=currentNode.next;
+			currentNode.next = null;
+			currentNode = tempNode;
+		}
+		head = (Node) s.pop();
+		currentNode= head;
+		while(!s.isEmpty()){
+			Node tempNode=(Node) s.pop();
+			currentNode.next = tempNode;
+			currentNode = tempNode;
 		}
 	}
 	
@@ -250,7 +255,7 @@ public  void reverse(){
 	 */
 	public  void removeFirstHalf(){
 		
-			for (int i = 0; i < size%2; i++) {
+			for (int i = 0; i < size/2; i++) {
 				remove(i);
 			}
 	}
@@ -261,10 +266,15 @@ public  void removeFirstHalf(){
 	 * @param length
 	 */
 	public  void remove(int i, int length){
-		for (int a = i; a < i+length; a++) {
-			remove(a);
+		if(i<0||i>=size){
+			throw new IndexOutOfBoundsException();
+		}
+		int len = size-1>=length?length:size-1;
+		int k = 0;
+		while(k<len){
+			remove(i);
+			k++;
 		}
-		
 	}
 	/**
 	 * 假定当前链表和list均包含已升序排列的整数
@@ -274,29 +284,12 @@ public  void remove(int i, int length){
 	 * 返回的结果应该是[101,301,401,601]  
 	 * @param list
 	 */
-	public static int[] getElements(LinkedList list){
-		int [] result =new int[list.size];
-		Class<?> callClass=Reflection.getCallerClass();
+	public  int[] getElements(LinkedList list){
+		int [] arr = new int [list.size()];
 		for (int i = 0; i < list.size; i++) {
-			Node node=(Node) list.get(i);
-			try {
-				Method method=callClass.getDeclaredMethod("get", new Class[]{int.class});
-				result[i]=(int) method.invoke(callClass, new Object[]{node.data});
-			} catch (NoSuchMethodException | SecurityException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (IllegalArgumentException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			} catch (InvocationTargetException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
+			arr[i] = (int) get((int)list.get(i));		
 		}
-		return null;
+		return arr;
 	}
 	
 	/**
@@ -321,15 +314,29 @@ public  void subtract(LinkedList list){
 	/**
 	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
 	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 * @throws Exception 
 	 */
-	public  void removeDuplicateValues(){
-		for (int i = 0; i < size; i++) {
-			Node node=(Node) get(i);
-			for (int j = i+1; j < size; j++) {
-				Node newNode=(Node) get(j);
-				if(newNode.data.equals(node.data))
-					remove(j);
+	public  void removeDuplicateValues() throws Exception{
+		if(null==head){
+			throw new Exception();
+		}
+		Node pre = head;
+		Node cur =head;
+		while(null!=cur.next){
+			cur = cur.next;
+			Object o=pre.data;
+			while(cur.data == o){
+				if(null==cur.next){
+					pre.next = null;
+				}
+				pre.next  = cur.next;
+				size--;
+				cur = cur.next;
+				if(null==cur){
+					break;
+				}
 			}
+			pre = pre.next;
 		}
 	}
 	
@@ -340,11 +347,24 @@ public  void removeDuplicateValues(){
 	 * @param max
 	 */
 	public  void removeRange(int min, int max){
-		for (int i = 0; i < size; i++) {
-			Node node=(Node) get(i);
-			if((int)node.data>min && (int)node.data<max)
-				remove(i);
+		if(null==head){
+			return ;
+		}
+		Node node = head;
+		int star = 0;
+		int end = 0;
+		int i = 0;
+		while(null!=node){
+			if((int)node.data<=min){
+				star = i;
+			}
+			if((int)node.data>=max){
+				end = i;
+				break;
+			}
+			i++;
 		}
+		remove(star,end-star);
 	}
 	
 	/**
@@ -352,17 +372,24 @@ public  void removeRange(int min, int max){
 	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
 	 * @param list
 	 */
-	public  LinkedList intersection( LinkedList list){
+	public  LinkedList intersection( LinkedList list){		
+		if(list==null){
+			return null;
+		}
 		LinkedList newList = new LinkedList();
-		for (int i = 0; i < size; i++) {
-			Node node=(Node) get(i);
-			for (int j = 0; j < list.size; j++) {
-				Node newNode=(Node) get(j);
-				if(newNode.data.equals(node.data)){
-					newList.add(node);
-					break;
-				}
-					
+		int i1=0;
+		int i2=0;
+		if(i1<this.size&&i2<list.size()){
+			int value1=(int) this.get(i1);
+			int value2=(int) list.get(i2);
+			if(value1==value2){
+				newList.add(value2);
+				i1++;
+				i2++;
+			}else if(value1<value2){
+				i1++;
+			}else if(value1>value2){
+				i2++;
 			}
 		}
 		return newList;
diff --git a/group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java b/group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java
new file mode 100644
index 0000000000..e5ddb476a6
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/array/ArrayUtil.java
@@ -0,0 +1,96 @@
+package com.coderising.array;
+
+public class ArrayUtil {
+	
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换
+		例如： a = [7, 9 , 30, 3]  ,   置换后为 [3, 30, 9,7]
+		如果     a = [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * @param origin
+	 * @return
+	 */
+	public void reverseArray(int[] origin){
+		
+	}
+	
+	/**
+	 * 现在有如下的一个数组：   int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}   
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为：   
+	 * {1,3,4,5,6,6,5,4,7,6,7,5}  
+	 * @param oldArray
+	 * @return
+	 */
+	
+	public int[] removeZero(int[] oldArray){
+		return null;
+	}
+	
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 ,  创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的
+	 * 例如 a1 = [3, 5, 7,8]   a2 = [4, 5, 6,7]    则 a3 为[3,4,5,6,7,8]    , 注意： 已经消除了重复
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+	
+	public int[] merge(int[] array1, int[] array2){
+		return  null;
+	}
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持
+	 * 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public int[] grow(int [] oldArray,  int size){
+		return null;
+	}
+	
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21......  ，给定一个最大值， 返回小于该值的数列
+	 * 例如， max = 15 , 则返回的数组应该为 [1，1，2，3，5，8，13]
+	 * max = 1, 则返回空数组 []
+	 * @param max
+	 * @return
+	 */
+	public int[] fibonacci(int max){
+		return null;
+	}
+	
+	/**
+	 * 返回小于给定最大值max的所有素数数组
+	 * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * @param max
+	 * @return
+	 */
+	public int[] getPrimes(int max){
+		return null;
+	}
+	
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+	 * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * @param max
+	 * @return
+	 */
+	public int[] getPerfectNumbers(int max){
+		return null;
+	}
+	
+	/**
+	 * 用seperator 把数组 array给连接起来
+	 * 例如array= [3,8,9], seperator = "-"
+	 * 则返回值为"3-8-9"
+	 * @param array
+	 * @param s
+	 * @return
+	 */
+	public String join(int[] array, String seperator){
+		return null;
+	}
+	
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java b/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java
new file mode 100644
index 0000000000..a3dc676a90
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/DownloadThread.java
@@ -0,0 +1,50 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.sun.org.apache.xpath.internal.SourceTree;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+public class DownloadThread extends Thread {
+
+    Connection conn;
+    int startPos;
+    int endPos;
+    CyclicBarrier barrier;
+    String localFile;
+
+    public DownloadThread(Connection conn, int startPos, int endPos, String localFile, CyclicBarrier barrier) {
+
+        this.conn = conn;
+        this.startPos = startPos;
+        this.endPos = endPos;
+        this.localFile = localFile;
+    }
+
+    public void run() {
+        System.out.println("Begin to read [" + startPos + "-" + endPos + "]");
+
+        try {
+			byte[] data= conn.read(startPos,endPos);
+            RandomAccessFile file = new RandomAccessFile(localFile, "rw");
+            file.seek(startPos);
+            file.write(data);
+            file.close();
+            conn.close();
+            barrier.await();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (BrokenBarrierException e) {
+            e.printStackTrace();
+        }
+
+    }
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java
new file mode 100644
index 0000000000..8b35a9a11d
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloader.java
@@ -0,0 +1,126 @@
+package com.coderising.download;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.concurrent.CyclicBarrier;
+
+
+public class FileDownloader {
+
+    String url;
+    String localFile;
+    DownloadListener listener;
+
+    ConnectionManager cm;
+
+    private static final int DOWNLOAD_TRHEAD_NUM = 3;
+
+    public FileDownloader(String _url, String _localFile) {
+        this.url = _url;
+        this.localFile = _localFile;
+
+    }
+
+    public void execute() {
+        // 在这里实现你的代码， 注意： 需要用多线程实现下载
+        // 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
+        // (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
+        // (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+        //     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+        // 具体的实现思路：
+        // 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+        // 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
+        // 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+        // 3. 把byte数组写入到文件中
+        // 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
+
+        // 下面的代码是示例代码， 也就是说只有一个线程， 你需要改造成多线程的。
+
+
+        CyclicBarrier barrier = new CyclicBarrier(DOWNLOAD_TRHEAD_NUM, new Runnable() {
+            @Override
+            public void run() {
+                listener.notifyFinished();
+            }
+        });
+
+
+        Connection conn = null;
+        try {
+
+            conn = cm.open(this.url);
+
+            int length = conn.getContentLength();
+
+            this.createPlaceHolderFile(localFile, length);
+
+            int[][] ranges = allocateDownloadRange(DOWNLOAD_TRHEAD_NUM, length);
+
+            for (int i = 0; i < DOWNLOAD_TRHEAD_NUM; i++) {
+                DownloadThread thread = new DownloadThread(cm.open(url), ranges[i][0], ranges[i][1], localFile, barrier);
+                thread.start();
+            }
+
+            //new DownloadThread(conn, 0, length - 1, localFile, barrier).start();
+
+        } catch (ConnectionException e) {
+            e.printStackTrace();
+        } finally {
+            if (conn != null) {
+                conn.close();
+            }
+        }
+    }
+
+    private void createPlaceHolderFile(String fileName, int contentLen) {
+        try {
+            RandomAccessFile file = new RandomAccessFile(fileName, "rw");
+            for (int i = 0; i < contentLen; i++) {
+                file.write(0);
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    private int[][] allocateDownloadRange(int threadNum, int contentLen) {
+        int[][] ranges = new int[threadNum][2];
+        int eachThreadSize = contentLen / threadNum;
+        int left = contentLen % threadNum;
+
+        for (int i = 0; i < threadNum; i++) {
+            int startPos = i * eachThreadSize;
+            int endPos = (i + 1) * eachThreadSize - 1;
+            if (i == (threadNum - 1)) {
+                endPos += left;
+            }
+            ranges[i][0] = startPos;
+            ranges[i][1] = endPos;
+        }
+        return ranges;
+    }
+
+
+    public void setListener(DownloadListener listener) {
+        this.listener = listener;
+    }
+
+
+    public void setConnectionManager(ConnectionManager ucm) {
+        this.cm = ucm;
+    }
+
+    public DownloadListener getListener() {
+        return this.listener;
+    }
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java
new file mode 100644
index 0000000000..7ec4c1f2e3
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/FileDownloaderTest.java
@@ -0,0 +1,59 @@
+package com.coderising.download;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.download.api.ConnectionManager;
+import com.coderising.download.api.DownloadListener;
+import com.coderising.download.impl.ConnectionManagerImpl;
+
+public class FileDownloaderTest {
+	boolean downloadFinished = false;
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDownload() {
+		
+		//String url = "http://localhost:8080/test.jpg";
+		String url ="http://desk.fd.zol-img.com.cn/t_s1920x1080c5/g3/M04/0B/06/Cg-4V1Q_K_2IS20UAAvKmTmHyYIAAQLGwOZI-YAC8qx308.jpg";
+		FileDownloader downloader = new FileDownloader(url,"d:/test.jpg");
+
+	
+		ConnectionManager cm = new ConnectionManagerImpl();
+		downloader.setConnectionManager(cm);
+		
+		downloader.setListener(new DownloadListener() {
+			@Override
+			public void notifyFinished() {
+				downloadFinished = true;
+			}
+
+		});
+
+		
+		downloader.execute();
+		
+		// 等待多线程下载程序执行完毕
+		while (!downloadFinished) {
+			try {
+				System.out.println("还没有下载完成，休眠五秒");
+				//休眠5秒
+				Thread.sleep(5000);
+			} catch (InterruptedException e) {				
+				e.printStackTrace();
+			}
+		}
+		System.out.println("下载完成！");
+		
+		
+
+	}
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java
new file mode 100644
index 0000000000..0957eaf7f4
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/api/Connection.java
@@ -0,0 +1,23 @@
+package com.coderising.download.api;
+
+import java.io.IOException;
+
+public interface Connection {
+	/**
+	 * 给定开始和结束位置， 读取数据， 返回值是字节数组
+	 * @param startPos 开始位置， 从0开始
+	 * @param endPos 结束位置
+	 * @return
+	 */
+	public byte[] read(int startPos,int endPos) throws IOException;
+	/**
+	 * 得到数据内容的长度
+	 * @return
+	 */
+	public int getContentLength();
+	
+	/**
+	 * 关闭连接
+	 */
+	public void close();
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java
new file mode 100644
index 0000000000..1551a80b3d
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionException.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public class ConnectionException extends Exception {
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java
new file mode 100644
index 0000000000..ce045393b1
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/api/ConnectionManager.java
@@ -0,0 +1,10 @@
+package com.coderising.download.api;
+
+public interface ConnectionManager {
+	/**
+	 * 给定一个url , 打开一个连接
+	 * @param url
+	 * @return
+	 */
+	public Connection open(String url) throws ConnectionException;	
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java b/group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java
new file mode 100644
index 0000000000..bf9807b307
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/api/DownloadListener.java
@@ -0,0 +1,5 @@
+package com.coderising.download.api;
+
+public interface DownloadListener {
+	public void notifyFinished();
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java
new file mode 100644
index 0000000000..37b413558d
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionImpl.java
@@ -0,0 +1,73 @@
+package com.coderising.download.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+
+import com.coderising.download.api.Connection;
+
+public class ConnectionImpl implements Connection {
+
+    static final int BUFFER_SIZE = 1024;
+    URL url;
+
+    ConnectionImpl(String _url) {
+        try {
+            url = new URL(_url);
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    @Override
+    public byte[] read(int startPos, int endPos) throws IOException {
+        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
+        httpConn.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);
+        InputStream is = httpConn.getInputStream();
+        byte[] buffer = new byte[BUFFER_SIZE];
+        int totalLen = endPos - startPos + 1;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        while (baos.size() < totalLen) {
+            int len = is.read(buffer);
+            if (len < 0) {
+                break;
+            }
+            baos.write(buffer);
+        }
+        if (baos.size() > totalLen) {
+            byte[] temp = baos.toByteArray();
+            return Arrays.copyOf(temp, totalLen);
+        }
+        return baos.toByteArray();
+
+
+    }
+
+    @Override
+    public int getContentLength() {
+        try {
+            URLConnection conn = url.openConnection();
+            return conn.getContentLength();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return -1;
+
+
+    }
+
+    @Override
+    public void close() {
+
+
+    }
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java
new file mode 100644
index 0000000000..f4a83cdbf6
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/download/impl/ConnectionManagerImpl.java
@@ -0,0 +1,15 @@
+package com.coderising.download.impl;
+
+import com.coderising.download.api.Connection;
+import com.coderising.download.api.ConnectionException;
+import com.coderising.download.api.ConnectionManager;
+
+public class ConnectionManagerImpl implements ConnectionManager {
+
+	@Override
+	public Connection open(String url) throws ConnectionException {
+		return new ConnectionImpl(url);
+		//return null;
+	}
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java
new file mode 100644
index 0000000000..dcdbe226ed
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/litestruts/LoginAction.java
@@ -0,0 +1,39 @@
+package com.coderising.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * @author liuxin
+ *
+ */
+public class LoginAction{
+    private String name ;
+    private String password;
+    private String message;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String execute(){
+            if("test".equals(name) && "1234".equals(password)){
+                this.message = "login successful";
+                return "success";
+            }
+            this.message = "login failed,please check your user/pwd";
+            return "fail";
+    }
+
+    public void setName(String name){
+        this.name = name;
+    }
+    public void setPassword(String password){
+        this.password = password;
+    }
+    public String getMessage(){
+        return this.message;
+    }
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java
new file mode 100644
index 0000000000..85e2e22de3
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/litestruts/Struts.java
@@ -0,0 +1,34 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+
+
+public class Struts {
+
+    public static View runAction(String actionName, Map<String,String> parameters) {
+
+        /*
+         
+		0. 读取配置文件struts.xml
+ 		
+ 		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+        
+        */
+    	
+    	return null;
+    }    
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java
new file mode 100644
index 0000000000..b8c81faf3c
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/litestruts/StrutsTest.java
@@ -0,0 +1,43 @@
+package com.coderising.litestruts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+
+
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+		
+		String actionName = "login";
+        
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","1234");
+        
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+        Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String,String> params = new HashMap<String,String>();
+        params.put("name","test");
+        params.put("password","123456"); //密码和预设的不一致
+        
+        View view  = Struts.runAction(actionName,params);        
+        
+        Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+        Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java b/group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java
new file mode 100644
index 0000000000..07df2a5dab
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coderising/litestruts/View.java
@@ -0,0 +1,23 @@
+package com.coderising.litestruts;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+	
+	public String getJsp() {
+		return jsp;
+	}
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+	public Map getParameters() {
+		return parameters;
+	}
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java b/group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java
new file mode 100644
index 0000000000..1f185736f9
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/ArrayList.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class ArrayList implements List {
+	
+	private int size = 0;
+	
+	private Object[] elementData = new Object[100];
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index, Object o){
+		
+	}
+	
+	public Object get(int index){
+		return null;
+	}
+	
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public Iterator iterator(){
+		return null;
+	}
+	
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java b/group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java
new file mode 100644
index 0000000000..d7ac820192
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/BinaryTreeNode.java
@@ -0,0 +1,32 @@
+package com.coding.basic;
+
+public class BinaryTreeNode {
+	
+	private Object data;
+	private BinaryTreeNode left;
+	private BinaryTreeNode right;
+	
+	public Object getData() {
+		return data;
+	}
+	public void setData(Object data) {
+		this.data = data;
+	}
+	public BinaryTreeNode getLeft() {
+		return left;
+	}
+	public void setLeft(BinaryTreeNode left) {
+		this.left = left;
+	}
+	public BinaryTreeNode getRight() {
+		return right;
+	}
+	public void setRight(BinaryTreeNode right) {
+		this.right = right;
+	}
+	
+	public BinaryTreeNode insert(Object o){
+		return  null;
+	}
+	
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java b/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java
new file mode 100644
index 0000000000..06ef6311b2
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/Iterator.java
@@ -0,0 +1,7 @@
+package com.coding.basic;
+
+public interface Iterator {
+	public boolean hasNext();
+	public Object next();
+
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/LinkedList.java b/group12/563253496/week3_file_download/src/com/coding/basic/LinkedList.java
new file mode 100644
index 0000000000..4fdb03db8a
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/LinkedList.java
@@ -0,0 +1,124 @@
+package com.coding.basic;
+
+
+
+public class LinkedList implements List {
+	
+	private Node head;
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index , Object o){
+		
+	}
+	public Object get(int index){
+		return null;
+	}
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public void addFirst(Object o){
+		
+	}
+	public void addLast(Object o){
+		
+	}
+	public Object removeFirst(){
+		return null;
+	}
+	public Object removeLast(){
+		return null;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){		
+		
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		
+	}
+	/**
+	 * 假定当前链表和list均包含已升序排列的整数
+	 * 从当前链表中取出那些list所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public static int[] getElements(LinkedList list){
+		return null;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在list中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		return null;
+	}
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/List.java b/group12/563253496/week3_file_download/src/com/coding/basic/List.java
new file mode 100644
index 0000000000..10d13b5832
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/List.java
@@ -0,0 +1,9 @@
+package com.coding.basic;
+
+public interface List {
+	public void add(Object o);
+	public void add(int index, Object o);
+	public Object get(int index);
+	public Object remove(int index);
+	public int size();
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/Queue.java b/group12/563253496/week3_file_download/src/com/coding/basic/Queue.java
new file mode 100644
index 0000000000..36e516e266
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/Queue.java
@@ -0,0 +1,19 @@
+package com.coding.basic;
+
+public class Queue {
+	
+	public void enQueue(Object o){		
+	}
+	
+	public Object deQueue(){
+		return null;
+	}
+	
+	public boolean isEmpty(){
+		return false;
+	}
+	
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group12/563253496/week3_file_download/src/com/coding/basic/Stack.java b/group12/563253496/week3_file_download/src/com/coding/basic/Stack.java
new file mode 100644
index 0000000000..a5a04de76d
--- /dev/null
+++ b/group12/563253496/week3_file_download/src/com/coding/basic/Stack.java
@@ -0,0 +1,22 @@
+package com.coding.basic;
+
+public class Stack {
+	private ArrayList elementData = new ArrayList();
+	
+	public void push(Object o){		
+	}
+	
+	public Object pop(){
+		return null;
+	}
+	
+	public Object peek(){
+		return null;
+	}
+	public boolean isEmpty(){
+		return false;
+	}
+	public int size(){
+		return -1;
+	}
+}
diff --git a/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..5f56b80bff
--- /dev/null
+++ b/group12/563253496/week4_jvm1/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,81 @@
+package com.coderising.jvm.loader;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class ClassFileLoader {
+
+    private List<String> clzPaths = new ArrayList<String>();
+
+    public byte[] readBinaryCode(String className) {
+        String path = getClassFilePath(className);
+        if (path != null) {
+            try {
+                BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
+                int count = bis.available();
+                byte[] content = new byte[count];
+                int len = bis.read(content,0,count);
+                return content;
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+
+
+    }
+
+    private byte[] loadClassFile(String clzFileName) {
+
+        return null;
+    }
+
+
+    public void addClassPath(String path) {
+        clzPaths.add(path);
+    }
+
+    public String getClassPath_V1() {
+
+        return null;
+    }
+
+    public String getClassPath() {
+        StringBuilder sb = new StringBuilder();
+        for (String s : clzPaths) {
+            sb.append(s);
+            sb.append(";");
+        }
+        sb.deleteCharAt(sb.length() - 1);
+        return sb.toString();
+    }
+
+    private String getClassFilePath(String className) {
+        StringBuilder sb = new StringBuilder();
+        for (String path : clzPaths
+                ) {
+            sb.append(path);
+            sb.append("\\");
+            char[] classname = className.toCharArray();
+            for (int i = 0; i < classname.length; i++) {
+                if (classname[i] == '.') {
+                    sb.append("\\");
+
+                } else {
+                    sb.append(classname[i]);
+                }
+            }
+            sb.append(".class");
+            String classpath = sb.toString();
+            File file = new File(classpath);
+            if (file.exists()) {
+                return classpath;
+            }
+        }
+        return null;
+    }
+}
diff --git a/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..4127673b7e
--- /dev/null
+++ b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "D:\\mygit\\coding2017\\group12\\563253496\\week4_jvm1\\out\\production\\week4_jvm1";
+	static String path2 = "C:\\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/EmployeeV1.java b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group12/563253496/week4_jvm1/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group12/563253496/week4_lru/src/LRUPageFrame.java b/group12/563253496/week4_lru/src/LRUPageFrame.java
new file mode 100644
index 0000000000..80c23f5cfd
--- /dev/null
+++ b/group12/563253496/week4_lru/src/LRUPageFrame.java
@@ -0,0 +1,135 @@
+/**
+ * Created by bdl19 on 2017/3/29.
+ */
+public class LRUPageFrame {
+
+    private static class Node {
+
+        Node prev;
+        Node next;
+        int pageNum;
+
+        Node() {
+        }
+    }
+
+    private int capacity;
+
+
+    private Node first;// 链表头
+    private Node last;// 链表尾
+
+
+    public LRUPageFrame(int capacity) {
+
+        this.capacity = capacity;
+        initialize();
+        //count = 0;
+    }
+
+    /**
+     * 获取缓存中对象
+     *
+     * @param
+     * @return
+     */
+    public void access(int pageNum) {
+        int index = checkPageNum(pageNum);
+        if (index < 0) {
+            addNewNode(pageNum);
+        } else {
+            moveNode(index);
+        }
+
+    }
+
+    private void moveNode(int index) {
+        Node temp = first;
+        if (index == capacity - 1) {
+            Node node = last;
+            last = last.prev;
+            node.prev.next=null;
+
+            node.prev = null;
+            node.next=first;
+
+
+            first.prev=node;
+            first = node;
+            return;
+        }
+
+        if(index==0){
+            return;
+        }
+
+        for (int i = 0; i < index; i++) {
+            temp = temp.next;
+        }
+
+        temp.prev.next = temp.next;
+        temp.next.prev = temp.prev;
+        temp.next = first;
+        temp.prev = null;
+        first.prev = temp;
+        first = temp;
+    }
+
+    private void addNewNode(int pageNum) {
+        Node node = new Node();
+        first.prev = node;
+        node.next = first;
+        first.prev = node;
+        node.pageNum = pageNum;
+        first = node;
+        last = last.prev;
+        last.next = null;
+    }
+
+
+    private int checkPageNum(int num) {
+        Node node = first;
+        int index = 0;
+        while (node != null) {
+            if (node.pageNum == num) {
+                return index;
+            }
+            index++;
+            node = node.next;
+        }
+        return -1;
+    }
+
+
+    private void initialize() {
+        if (capacity <= 0) {
+            throw new IndexOutOfBoundsException();
+        }
+        Node node = new Node();
+        first = node;
+        last = node;
+        for (int i = 0; i < capacity - 1; i++) {
+            Node n = new Node();
+            Node temp = last;
+            last.next = n;
+            last = n;
+            last.prev = temp;
+        }
+    }
+
+
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        Node node = first;
+        while (node != null) {
+            buffer.append(node.pageNum);
+
+            node = node.next;
+            if (node != null) {
+                buffer.append(",");
+            }
+        }
+        return buffer.toString();
+    }
+
+}
diff --git a/group12/563253496/week4_lru/src/LRUPageFrameTest.java b/group12/563253496/week4_lru/src/LRUPageFrameTest.java
new file mode 100644
index 0000000000..41e3727e34
--- /dev/null
+++ b/group12/563253496/week4_lru/src/LRUPageFrameTest.java
@@ -0,0 +1,34 @@
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Assert;
+/**
+* LRUPageFrame Tester.
+*
+* @author <Authors name>
+* @since <pre>���� 29, 2017</pre>
+* @version 1.0
+*/ public class LRUPageFrameTest {
+
+    @Test
+    public void testAccess() {
+        LRUPageFrame frame = new LRUPageFrame(3);
+        frame.access(7);
+        frame.access(0);
+        frame.access(1);
+        Assert.assertEquals("1,0,7", frame.toString());
+        frame.access(2);
+        Assert.assertEquals("2,1,0", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(3);
+        Assert.assertEquals("3,0,2", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,3,2", frame.toString());
+        frame.access(4);
+        Assert.assertEquals("4,0,3", frame.toString());
+    }
+
+}
diff --git a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java
index 3c3462637e..c0cce5af0a 100644
--- a/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java
+++ b/group17/1204187480/code/homework/basic/src/main/java/com/coding/basic/LinkedList.java
@@ -185,16 +185,21 @@ public void removeFirstSize(int firstSize) {
      * @param length
      */
     public void remove(int i, int length) {
-        if (i == 0 ) {removeFirstSize(length); return;}
-        if (i >= size || length == 0) {return;}
+        if (i == 0) {
+            removeFirstSize(length);
+            return;
+        }
+        if (i >= size || length == 0) {
+            return;
+        }
 
         int lastLenth = size - i;
-        length = length <= lastLenth? length : lastLenth;
-        Node pre = node(i-1);
+        length = length <= lastLenth ? length : lastLenth;
+        Node pre = node(i - 1);
         int j = 0;
 
         Node next = pre;
-        while (j++ < length){
+        while (j++ < length) {
             next = next.next;
         }
         pre.next = next.next;
@@ -213,9 +218,44 @@ public void remove(int i, int length) {
      * @param list
      */
     public int[] getElements(LinkedList list) {
-        return null;
+        if (size() == 0) {
+            return new int[0];
+        }
+        Iterator iterator = list.iterator();
+        Node fromNode = iterator().nextNode();
+        int fromIndex = 0;
+
+        int[] retArray = new int[list.size()];
+        int retIndex = 0;
+        while (iterator.hasNext()) {
+            int index = (int) iterator.next();
+            Node node = node(fromNode, fromIndex, index);
+            fromIndex = index;
+            fromNode = node;
+            if (node == null) {
+                return retArray;
+            } else {
+                retArray[retIndex++] = (int)node.data;
+            }
+        }
+        return retArray;
     }
 
+    private Node node(Node fromNode, int fromIndex, int index) {
+        Node next = fromNode;
+        int nextIndex = fromIndex;
+        while (next != null && nextIndex < index) {
+            next = next.next;
+            nextIndex++;
+        }
+        if (nextIndex == index) {
+            return next;
+        } else {
+            return null;
+        }
+    }
+
+
     /**
      * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
      * 从当前链表中中删除在listB中出现的元素
diff --git a/group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java b/group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java
deleted file mode 100644
index 95f0085b66..0000000000
--- a/group17/1204187480/code/homework/basic/src/test/java/com/coding/api/ArrayListTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.coding.api;
-
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Created by luoziyihao on 2/25/17.
- */
-public class ArrayListTest {
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    @Test
-    public void testAdd(){
-        List<Object> list = new ArrayList<Object>(Arrays.asList(0, 1, 2, 3));
-        logger.info("list={}", list);
-        list.add(5, 2);
-        logger.info("list={}", list);
-    }
-}
diff --git a/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java b/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java
index baca03b06b..0424c2945e 100644
--- a/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java
+++ b/group17/1204187480/code/homework/basic/src/test/java/com/coding/basic/LinkedListTest.java
@@ -3,6 +3,8 @@
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.Arrays;
+
 /**
  * Created by luoziyihao on 3/23/17.
  */
@@ -83,9 +85,12 @@ private LinkedList createAndFillLinkedList() {
     }
 
     private LinkedList createAndFillLinkedList(int length) {
+        return createAndFillLinkedList(1, length);
+    }
 
+    private LinkedList createAndFillLinkedList(int start, int length) {
         LinkedList linkedList = new LinkedList();
-        for (int i = 1; i <= length; i++) {
+        for (int i = start; i <= length; i++) {
             linkedList.add(i);
         }
         return linkedList;
@@ -136,6 +141,9 @@ public void remove7() throws Exception {
 
     @Test
     public void getElements() throws Exception {
+        LinkedList listA= createAndFillLinkedList(0,8);
+        LinkedList listB = createAndFillLinkedList(4, 4);
+        Assert.assertEquals("[4,5,6,7]", Arrays.toString(listA.getElements(listB)));
 
     }
 
diff --git a/group17/1204187480/code/homework/parent/pom.xml b/group17/1204187480/code/homework/parent/pom.xml
index 7af48c6fed..ace9bf9cc5 100644
--- a/group17/1204187480/code/homework/parent/pom.xml
+++ b/group17/1204187480/code/homework/parent/pom.xml
@@ -92,4 +92,13 @@
         </plugins>
     </build>
 
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.19.1</version>
+            </plugin>
+        </plugins>
+    </reporting>
 </project>
\ No newline at end of file
diff --git a/group17/1264835468/.gitignore b/group17/1264835468/.gitignore
index 71f96b185c..1517b9e684 100644
--- a/group17/1264835468/.gitignore
+++ b/group17/1264835468/.gitignore
@@ -1,5 +1,7 @@
-/bin/
+/bin/
 
 .classpath
 .project
-.gitignore
\ No newline at end of file
+.gitignore
+/.idea/
+.iml
diff --git a/group17/1264835468/src/assignment2_26/ArrayUtil.java b/group17/1264835468/src/assignment0226/ArrayUtil.java
similarity index 95%
rename from group17/1264835468/src/assignment2_26/ArrayUtil.java
rename to group17/1264835468/src/assignment0226/ArrayUtil.java
index 89d2a0db29..f8be858ad9 100644
--- a/group17/1264835468/src/assignment2_26/ArrayUtil.java
+++ b/group17/1264835468/src/assignment0226/ArrayUtil.java
@@ -1,183 +1,183 @@
-package assignment2_26;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.TreeSet;
-
-public class ArrayUtil {
-
-	/**
-	 * 给定一个整形数组a , 对该数组的值进行置换 例如： a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] 如果 a =
-	 * [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
-	 * 
-	 * @param origin
-	 * @return
-	 */
-	public static void reverseArray(int[] origin) {
-		int mid = origin.length / 2;
-		for (int i = 0; i < mid; i++) {
-			int temp = origin[i];
-			int reversePosition = origin.length - 1;
-			origin[i] = origin[reversePosition];
-			origin[reversePosition] = temp;
-		}
-	}
-
-	/**
-	 * 现在有如下的一个数组： int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
-	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为： {1,3,4,5,6,6,5,4,7,6,7,5}
-	 * 
-	 * @param oldArray
-	 * @return
-	 */
-
-	public static int[] removeZero(int[] oldArray) {
-		int count = 0;
-		for (int i : oldArray) {
-			if (i != 0)
-				count++;
-		}
-		int[] newArray = new int[count];
-		int currentPos = 0;
-		for (int i = 0; i < oldArray.length; i++) {
-			if (oldArray[i] != 0)
-				newArray[currentPos++] = oldArray[i];
-		}
-		return newArray;
-	}
-
-	/**
-	 * 给定两个已经排序好的整形数组， a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的 例如 a1 =
-	 * [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意： 已经消除了重复
-	 * 
-	 * @param array1
-	 * @param array2
-	 * @return
-	 */
-
-	public static int[] merge(int[] array1, int[] array2) {
-		TreeSet<Integer> set = new TreeSet<>();
-		for (Integer integer : array1) {
-			set.add(integer);
-		}
-		for (Integer integer : array2) {
-			set.add(integer);
-		}
-		int[] result = new int[set.size()];
-		for (int i = 0; i < result.length; i++) {
-			result[i] = set.pollFirst();
-		}
-		return result;
-	}
-
-	/**
-	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
-	 * 注意，老数组的元素在新数组中需要保持 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
-	 * [2,3,6,0,0,0]
-	 * 
-	 * @param oldArray
-	 * @param size
-	 * @return
-	 */
-	public static int[] grow(int[] oldArray, int size) {
-		return Arrays.copyOf(oldArray, size);
-	}
-
-	/**
-	 * 斐波那契数列为：1，1，2，3，5，8，13，21...... ，给定一个最大值， 返回小于该值的数列 例如， max = 15 ,
-	 * 则返回的数组应该为 [1，1，2，3，5，8，13] max = 1, 则返回空数组 []
-	 * 
-	 * @param max
-	 * @return
-	 */
-	public static int[] fibonacci(int max) {
-		if (max <= 1)
-			return new int[0];
-		List<Integer> fList = new ArrayList<>();
-		fList.add(1);
-		fList.add(1);
-		int last = fList.size() - 1;
-		while (fList.get(last) < max) {
-			fList.add(fList.get(last) + fList.get(last - 1));
-			last++;
-		}
-		int[] result = new int[fList.size() - 1];
-		for (int i = 0; i < result.length; i++) {
-			result[i] = fList.get(i);
-		}
-		return result;
-	}
-
-	/**
-	 * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
-	 * 
-	 * @param max
-	 * @return
-	 */
-	public static int[] getPrimes(int max) {
-		boolean[] isPrime = new boolean[max];
-		List<Integer> primes = new ArrayList<>();
-		for (int i = 0; i < isPrime.length; i++) {
-			isPrime[i] = true;
-		}
-		for (int i = 2; i * i < max; i++) {
-			for (int j = i; i * j < max; j++)
-				isPrime[i * j] = false;
-		}
-		for (int i = 2; i < isPrime.length; i++) {
-			if (isPrime[i])
-				primes.add(i);
-		}
-		int[] result = new int[primes.size()];
-		for (int i = 0; i < result.length; i++) {
-			result[i] = primes.get(i);
-		}
-		return result;
-	}
-
-	/**
-	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
-	 * 
-	 * @param max
-	 * @return
-	 */
-	public static int[] getPerfectNumbers(int max) {
-		int sum = 0;
-		ArrayList<Integer> perfectNumbers = new ArrayList<>();
-		for (int i = 1; i < max; i++) {
-			for (int j = 1; j < i; j++) {
-				if (i % j == 0) {
-					sum += j;
-				}
-			}
-			if (sum == i)
-				perfectNumbers.add(i);
-			sum = 0;
-		}
-
-		int[] result = new int[perfectNumbers.size()];
-		for (int i = 0; i < result.length; i++) {
-			result[i] = perfectNumbers.get(i);
-		}
-		return result;
-	}
-
-	/**
-	 * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9"
-	 * 
-	 * @param array
-	 * @param s
-	 * @return
-	 */
-	public static String join(int[] array, String seperator) {
-		StringBuilder stringBuilder = new StringBuilder();
-		for (int i : array) {
-			stringBuilder.append(i + seperator);
-		}
-		stringBuilder.delete(stringBuilder.length() - seperator.length(), stringBuilder.length());
-
-		return stringBuilder.toString();
-	}
-
-}
+package assignment0226;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.TreeSet;
+
+public class ArrayUtil {
+
+	/**
+	 * 给定一个整形数组a , 对该数组的值进行置换 例如： a = [7, 9 , 30, 3] , 置换后为 [3, 30, 9,7] 如果 a =
+	 * [7, 9, 30, 3, 4] , 置换后为 [4,3, 30 , 9,7]
+	 * 
+	 * @param origin
+	 * @return
+	 */
+	public static void reverseArray(int[] origin) {
+		int mid = origin.length / 2;
+		for (int i = 0; i < mid; i++) {
+			int temp = origin[i];
+			int reversePosition = origin.length - 1;
+			origin[i] = origin[reversePosition];
+			origin[reversePosition] = temp;
+		}
+	}
+
+	/**
+	 * 现在有如下的一个数组： int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5}
+	 * 要求将以上数组中值为0的项去掉，将不为0的值存入一个新的数组，生成的新数组为： {1,3,4,5,6,6,5,4,7,6,7,5}
+	 * 
+	 * @param oldArray
+	 * @return
+	 */
+
+	public static int[] removeZero(int[] oldArray) {
+		int count = 0;
+
+		for (int i : oldArray) {
+			if (i != 0)
+				count++;
+		}
+		int[] newArray = new int[count];
+		int currentPos = 0;
+		for (int i = 0; i < oldArray.length; i++) {
+			if (oldArray[i] != 0)
+				newArray[currentPos++] = oldArray[i];
+		}
+		return newArray;
+	}
+
+	/**
+	 * 给定两个已经排序好的整形数组， a1和a2 , 创建一个新的数组a3, 使得a3 包含a1和a2 的所有元素， 并且仍然是有序的 例如 a1 =
+	 * [3, 5, 7,8] a2 = [4, 5, 6,7] 则 a3 为[3,4,5,6,7,8] , 注意： 已经消除了重复
+	 * 
+	 * @param array1
+	 * @param array2
+	 * @return
+	 */
+
+	public static int[] merge(int[] array1, int[] array2) {
+		TreeSet<Integer> set = new TreeSet<>();
+		for (Integer integer : array1) {
+			set.add(integer);
+		}
+		for (Integer integer : array2) {
+			set.add(integer);
+		}
+		int[] result = new int[set.size()];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = set.pollFirst();
+		}
+		return result;
+	}
+
+	/**
+	 * 把一个已经存满数据的数组 oldArray的容量进行扩展， 扩展后的新数据大小为oldArray.length + size
+	 * 注意，老数组的元素在新数组中需要保持 例如 oldArray = [2,3,6] , size = 3,则返回的新数组为
+	 * [2,3,6,0,0,0]
+	 * 
+	 * @param oldArray
+	 * @param size
+	 * @return
+	 */
+	public static int[] grow(int[] oldArray, int size) {
+		return Arrays.copyOf(oldArray, size);
+	}
+
+	/**
+	 * 斐波那契数列为：1，1，2，3，5，8，13，21...... ，给定一个最大值， 返回小于该值的数列 例如， max = 15 ,
+	 * 则返回的数组应该为 [1，1，2，3，5，8，13] max = 1, 则返回空数组 []
+	 * 
+	 * @param max
+	 * @return
+	 */
+	public static int[] fibonacci(int max) {
+		if (max <= 1)
+			return new int[0];
+		List<Integer> fList = new ArrayList<>();
+		fList.add(1);
+		fList.add(1);
+		int last = fList.size() - 1;
+		while (fList.get(last) < max) {
+			fList.add(fList.get(last) + fList.get(last - 1));
+			last++;
+		}
+		int[] result = new int[fList.size() - 1];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = fList.get(i);
+		}
+		return result;
+	}
+
+	/**
+	 * 返回小于给定最大值max的所有素数数组 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+	 * 
+	 * @param max
+	 * @return
+	 */
+	public static int[] getPrimes(int max) {
+		boolean[] isPrime = new boolean[max];
+		List<Integer> primes = new ArrayList<>();
+		for (int i = 0; i < isPrime.length; i++) {
+			isPrime[i] = true;
+		}
+		for (int i = 2; i * i < max; i++) {
+			for (int j = i; i * j < max; j++)
+				isPrime[i * j] = false;
+		}
+		for (int i = 2; i < isPrime.length; i++) {
+			if (isPrime[i])
+				primes.add(i);
+		}
+		int[] result = new int[primes.size()];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = primes.get(i);
+		}
+		return result;
+	}
+
+	/**
+	 * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+	 * 
+	 * @param max
+	 * @return
+	 */
+	public static int[] getPerfectNumbers(int max) {
+		int sum = 0;
+		ArrayList<Integer> perfectNumbers = new ArrayList<>();
+		for (int i = 1; i < max; i++) {
+			for (int j = 1; j < i; j++) {
+				if (i % j == 0) {
+					sum += j;
+				}
+			}
+			if (sum == i)
+				perfectNumbers.add(i);
+			sum = 0;
+		}
+
+		int[] result = new int[perfectNumbers.size()];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = perfectNumbers.get(i);
+		}
+		return result;
+	}
+
+	/**
+	 * 用seperator 把数组 array给连接起来 例如array= [3,8,9], seperator = "-" 则返回值为"3-8-9"
+	 * 
+	 * @param array
+	 * @param seperator
+	 * @return
+	 */
+	public static String join(int[] array, String seperator) {
+		StringBuilder stringBuilder = new StringBuilder();
+		for (int i : array) {
+			stringBuilder.append(i + seperator);
+		}
+		stringBuilder.delete(stringBuilder.length() - seperator.length(), stringBuilder.length());
+
+		return stringBuilder.toString();
+	}
+}
diff --git a/group17/1264835468/src/assignment2_26/ArrayUtilTest.java b/group17/1264835468/src/assignment0226/ArrayUtilTest.java
similarity index 95%
rename from group17/1264835468/src/assignment2_26/ArrayUtilTest.java
rename to group17/1264835468/src/assignment0226/ArrayUtilTest.java
index 753c026796..1ccd845e1c 100644
--- a/group17/1264835468/src/assignment2_26/ArrayUtilTest.java
+++ b/group17/1264835468/src/assignment0226/ArrayUtilTest.java
@@ -1,100 +1,100 @@
-package assignment2_26;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ArrayUtilTest {
-
-	@Test
-	public void testReverseArray() {
-		int[] array = new int[] {};
-		ArrayUtil.reverseArray(array);
-		assertArrayEquals(new int[] {}, array);
-
-		array = new int[] { 1 };
-		ArrayUtil.reverseArray(array);
-		assertArrayEquals(new int[] { 1 }, array);
-
-		array = new int[] { 1, 2, 3 };
-		ArrayUtil.reverseArray(array);
-		assertArrayEquals(new int[] { 3, 2, 1 }, array);
-	}
-
-	@Test
-	public void testRemoveZero() {
-		int[] array = new int[] {};
-		assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array));
-
-		array = new int[] { 0 };
-		assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array));
-
-		array = new int[] { 1 };
-		assertArrayEquals(new int[] { 1 }, ArrayUtil.removeZero(array));
-
-		array = new int[] { 1, 2, 0, 0, 3 };
-		assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array));
-
-		array = new int[] { 1, 2, 3 };
-		assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array));
-	}
-
-	@Test
-	public void testMerge() {
-		int[] array1 = { 3, 5, 7, 8 };
-		int[] array2 = { 4, 5, 6, 7 };
-		assertArrayEquals(new int[] { 3, 4, 5, 6, 7, 8 }, ArrayUtil.merge(array1, array2));
-	}
-
-	@Test
-	public void testGrow() {
-		int[] array = { 3, 5, 7 };
-		assertArrayEquals(new int[] { 3, 5, 7, 0, 0 }, ArrayUtil.grow(array, 5));
-		assertArrayEquals(new int[] { 3, 5, 7 }, ArrayUtil.grow(array, 3));
-	}
-
-	@Test
-	public void testFibonacci() {
-		assertArrayEquals(new int[] {}, ArrayUtil.fibonacci(1));
-
-		assertArrayEquals(new int[] { 1, 1 }, ArrayUtil.fibonacci(2));
-
-		assertArrayEquals(new int[] { 1, 1, 2, 3, 5, 8, 13 }, ArrayUtil.fibonacci(15));
-	}
-
-	@Test
-	public void testGetPrimes() {
-		assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(1));
-
-		assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(2));
-
-		assertArrayEquals(new int[] { 2 }, ArrayUtil.getPrimes(3));
-
-		assertArrayEquals(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }, ArrayUtil.getPrimes(20));
-	}
-
-	@Test
-	public void testGetPerfectNumbers() {
-		assertArrayEquals(new int[] { 6 }, ArrayUtil.getPerfectNumbers(10));
-
-		assertArrayEquals(new int[] { 6, 28 }, ArrayUtil.getPerfectNumbers(100));
-
-		assertArrayEquals(new int[] { 6, 28, 496 }, ArrayUtil.getPerfectNumbers(1000));
-
-		assertArrayEquals(new int[] { 6, 28, 496, 8128 }, ArrayUtil.getPerfectNumbers(10000));
-
-	}
-
-	@Test
-	public void testJoin() {
-		assertEquals("3-4-5", ArrayUtil.join(new int[] { 3, 4, 5 }, "-"));
-
-		assertEquals("345", ArrayUtil.join(new int[] { 3, 4, 5 }, ""));
-
-		assertEquals("3", ArrayUtil.join(new int[] { 3 }, ""));
-
-		assertEquals("3--4--5", ArrayUtil.join(new int[] { 3, 4, 5 }, "--"));
-	}
-
-}
+package assignment0226;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class ArrayUtilTest {
+
+	@Test
+	public void testReverseArray() {
+		int[] array = new int[] {};
+		ArrayUtil.reverseArray(array);
+		assertArrayEquals(new int[] {}, array);
+
+		array = new int[] { 1 };
+		ArrayUtil.reverseArray(array);
+		assertArrayEquals(new int[] { 1 }, array);
+
+		array = new int[] { 1, 2, 3 };
+		ArrayUtil.reverseArray(array);
+		assertArrayEquals(new int[] { 3, 2, 1 }, array);
+	}
+
+	@Test
+	public void testRemoveZero() {
+		int[] array = new int[] {};
+		assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array));
+
+		array = new int[] { 0 };
+		assertArrayEquals(new int[] {}, ArrayUtil.removeZero(array));
+
+		array = new int[] { 1 };
+		assertArrayEquals(new int[] { 1 }, ArrayUtil.removeZero(array));
+
+		array = new int[] { 1, 2, 0, 0, 3 };
+		assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array));
+
+		array = new int[] { 1, 2, 3 };
+		assertArrayEquals(new int[] { 1, 2, 3 }, ArrayUtil.removeZero(array));
+	}
+
+	@Test
+	public void testMerge() {
+		int[] array1 = { 3, 5, 7, 8 };
+		int[] array2 = { 4, 5, 6, 7 };
+		assertArrayEquals(new int[] { 3, 4, 5, 6, 7, 8 }, ArrayUtil.merge(array1, array2));
+	}
+
+	@Test
+	public void testGrow() {
+		int[] array = { 3, 5, 7 };
+		assertArrayEquals(new int[] { 3, 5, 7, 0, 0 }, ArrayUtil.grow(array, 5));
+		assertArrayEquals(new int[] { 3, 5, 7 }, ArrayUtil.grow(array, 3));
+	}
+
+	@Test
+	public void testFibonacci() {
+		assertArrayEquals(new int[] {}, ArrayUtil.fibonacci(1));
+
+		assertArrayEquals(new int[] { 1, 1 }, ArrayUtil.fibonacci(2));
+
+		assertArrayEquals(new int[] { 1, 1, 2, 3, 5, 8, 13 }, ArrayUtil.fibonacci(15));
+	}
+
+	@Test
+	public void testGetPrimes() {
+		assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(1));
+
+		assertArrayEquals(new int[] {}, ArrayUtil.getPrimes(2));
+
+		assertArrayEquals(new int[] { 2 }, ArrayUtil.getPrimes(3));
+
+		assertArrayEquals(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 }, ArrayUtil.getPrimes(20));
+	}
+
+	@Test
+	public void testGetPerfectNumbers() {
+		assertArrayEquals(new int[] { 6 }, ArrayUtil.getPerfectNumbers(10));
+
+		assertArrayEquals(new int[] { 6, 28 }, ArrayUtil.getPerfectNumbers(100));
+
+		assertArrayEquals(new int[] { 6, 28, 496 }, ArrayUtil.getPerfectNumbers(1000));
+
+		assertArrayEquals(new int[] { 6, 28, 496, 8128 }, ArrayUtil.getPerfectNumbers(10000));
+
+	}
+
+	@Test
+	public void testJoin() {
+		assertEquals("3-4-5", ArrayUtil.join(new int[] { 3, 4, 5 }, "-"));
+
+		assertEquals("345", ArrayUtil.join(new int[] { 3, 4, 5 }, ""));
+
+		assertEquals("3", ArrayUtil.join(new int[] { 3 }, ""));
+
+		assertEquals("3--4--5", ArrayUtil.join(new int[] { 3, 4, 5 }, "--"));
+	}
+
+}
diff --git a/group17/1264835468/src/assignment2_26/LoginAction.java b/group17/1264835468/src/assignment0226/LoginAction.java
similarity index 91%
rename from group17/1264835468/src/assignment2_26/LoginAction.java
rename to group17/1264835468/src/assignment0226/LoginAction.java
index 3101d322b8..652b5359ac 100644
--- a/group17/1264835468/src/assignment2_26/LoginAction.java
+++ b/group17/1264835468/src/assignment0226/LoginAction.java
@@ -1,42 +1,42 @@
-package assignment2_26;
-
-/**
- * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
- * 
- * @author liuxin
- *
- */
-public class LoginAction {
-	private String name;
-	private String password;
-	private String message;
-
-	public String getName() {
-		return name;
-	}
-
-	public String getPassword() {
-		return password;
-	}
-
-	public String execute() {
-		if ("test".equals(name) && "1234".equals(password)) {
-			this.message = "login successful";
-			return "success";
-		}
-		this.message = "login failed,please check your user/pwd";
-		return "fail";
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public void setPassword(String password) {
-		this.password = password;
-	}
-
-	public String getMessage() {
-		return this.message;
-	}
-}
+package assignment0226;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ * 
+ * @author liuxin
+ *
+ */
+public class LoginAction {
+	private String name;
+	private String password;
+	private String message;
+
+	public String getName() {
+		return name;
+	}
+
+	public String getPassword() {
+		return password;
+	}
+
+	public String execute() {
+		if ("test".equals(name) && "1234".equals(password)) {
+			this.message = "login successful";
+			return "success";
+		}
+		this.message = "login failed,please check your user/pwd";
+		return "fail";
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public String getMessage() {
+		return this.message;
+	}
+}
diff --git a/group17/1264835468/src/assignment2_26/Struts.java b/group17/1264835468/src/assignment0226/Struts.java
similarity index 96%
rename from group17/1264835468/src/assignment2_26/Struts.java
rename to group17/1264835468/src/assignment0226/Struts.java
index ad704e0433..457b6ad953 100644
--- a/group17/1264835468/src/assignment2_26/Struts.java
+++ b/group17/1264835468/src/assignment0226/Struts.java
@@ -1,99 +1,99 @@
-package assignment2_26;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Struts {
-
-	private static File configFile = new File("./src/struts.xml");;
-
-	public static View runAction(String actionName, Map<String, String> parameters) {
-
-		/*
-		 
-		0. 读取配置文件struts.xml
-		
-		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
-		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
-		("name"="test" ,  "password"="1234") ,     	
-		那就应该调用 setName和setPassword方法
-		
-		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
-		
-		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
-		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
-		放到View对象的parameters
-		
-		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
-		放到View对象的jsp字段中。
-		
-		*/
-		// 0
-		XmlParser phraser = new XmlParser(configFile);
-		String className = phraser.getClassNameByActionName(actionName);
-		View view = new View();
-		try {
-			// 1
-			Class<?> actionClass = Class.forName(className);
-			Constructor<?> constructor = actionClass.getConstructor();
-			Object instance = constructor.newInstance();
-			invokeSetters(actionClass, instance, parameters);
-
-			// 2
-			String result = invokeExecute(actionClass, instance);
-
-			// 3
-			Map<String, String> getterResult = invokeGetters(actionClass, instance);
-			view.setParameters(getterResult);
-
-			// 4
-			String resultJsp = phraser.getResultJsp(actionName, result);
-			view.setJsp(resultJsp);
-
-		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
-				| IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-			e.printStackTrace();
-		}
-
-		return view;
-	}
-
-	private static Map<String, String> invokeGetters(Class<?> actionClass, Object instance)
-			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-		Map<String, String> result = new HashMap<>();
-		for (Method method : actionClass.getDeclaredMethods()) {
-			if (method.getName().matches("get.*")) {
-				String fieldName = method.getName().substring(3).toLowerCase();
-				String value = (String) (method.invoke(instance));
-				result.put(fieldName, value);
-			}
-		}
-		return result;
-	}
-
-	private static String invokeExecute(Class<?> actionClass, Object instance) throws NoSuchMethodException,
-			SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-		Method method = actionClass.getDeclaredMethod("execute");
-		return (String) method.invoke(instance);
-	}
-
-	private static void invokeSetters(Class<?> actionClass, Object instance, Map<String, String> parameters)
-			throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
-			InvocationTargetException {
-		for (String fieldName : parameters.keySet()) {
-			invokeSetter(actionClass, instance, fieldName, parameters.get(fieldName));
-		}
-	}
-
-	private static void invokeSetter(Class<?> actionClass, Object instance, String fieldName, String value)
-			throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
-			InvocationTargetException {
-		String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
-		Method setter = actionClass.getDeclaredMethod(setterName, String.class);
-		setter.invoke(instance, value);
-	}
-}
+package assignment0226;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Struts {
+
+	private static File configFile = new File("./src/struts.xml");;
+
+	public static View runAction(String actionName, Map<String, String> parameters) {
+
+		/*
+		 
+		0. 读取配置文件struts.xml
+		
+		1. 根据actionName找到相对应的class ， 例如LoginAction,   通过反射实例化（创建对象）
+		据parameters中的数据，调用对象的setter方法， 例如parameters中的数据是 
+		("name"="test" ,  "password"="1234") ,     	
+		那就应该调用 setName和setPassword方法
+		
+		2. 通过反射调用对象的exectue 方法， 并获得返回值，例如"success"
+		
+		3. 通过反射找到对象的所有getter方法（例如 getMessage）,  
+		通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,  
+		放到View对象的parameters
+		
+		4. 根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，  
+		放到View对象的jsp字段中。
+		
+		*/
+		// 0
+		XmlParser phraser = new XmlParser(configFile);
+		String className = phraser.getClassNameByActionName(actionName);
+		View view = new View();
+		try {
+			// 1
+			Class<?> actionClass = Class.forName(className);
+			Constructor<?> constructor = actionClass.getConstructor();
+			Object instance = constructor.newInstance();
+			invokeSetters(actionClass, instance, parameters);
+
+			// 2
+			String result = invokeExecute(actionClass, instance);
+
+			// 3
+			Map<String, String> getterResult = invokeGetters(actionClass, instance);
+			view.setParameters(getterResult);
+
+			// 4
+			String resultJsp = phraser.getResultJsp(actionName, result);
+			view.setJsp(resultJsp);
+
+		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
+				| IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+			e.printStackTrace();
+		}
+
+		return view;
+	}
+
+	private static Map<String, String> invokeGetters(Class<?> actionClass, Object instance)
+			throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+		Map<String, String> result = new HashMap<>();
+		for (Method method : actionClass.getDeclaredMethods()) {
+			if (method.getName().matches("get.*")) {
+				String fieldName = method.getName().substring(3).toLowerCase();
+				String value = (String) (method.invoke(instance));
+				result.put(fieldName, value);
+			}
+		}
+		return result;
+	}
+
+	private static String invokeExecute(Class<?> actionClass, Object instance) throws NoSuchMethodException,
+			SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+		Method method = actionClass.getDeclaredMethod("execute");
+		return (String) method.invoke(instance);
+	}
+
+	private static void invokeSetters(Class<?> actionClass, Object instance, Map<String, String> parameters)
+			throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
+			InvocationTargetException {
+		for (String fieldName : parameters.keySet()) {
+			invokeSetter(actionClass, instance, fieldName, parameters.get(fieldName));
+		}
+	}
+
+	private static void invokeSetter(Class<?> actionClass, Object instance, String fieldName, String value)
+			throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
+			InvocationTargetException {
+		String setterName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
+		Method setter = actionClass.getDeclaredMethod(setterName, String.class);
+		setter.invoke(instance, value);
+	}
+}
diff --git a/group17/1264835468/src/assignment2_26/StrutsTest.java b/group17/1264835468/src/assignment0226/StrutsTest.java
similarity index 94%
rename from group17/1264835468/src/assignment2_26/StrutsTest.java
rename to group17/1264835468/src/assignment0226/StrutsTest.java
index f47410209b..1e677c38b3 100644
--- a/group17/1264835468/src/assignment2_26/StrutsTest.java
+++ b/group17/1264835468/src/assignment0226/StrutsTest.java
@@ -1,38 +1,38 @@
-package assignment2_26;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class StrutsTest {
-
-	@Test
-	public void testLoginActionSuccess() {
-
-		String actionName = "login";
-
-		Map<String, String> params = new HashMap<String, String>();
-		params.put("name", "test");
-		params.put("password", "1234");
-
-		View view = Struts.runAction(actionName, params);
-
-		Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
-		Assert.assertEquals("login successful", view.getParameters().get("message"));
-	}
-
-	@Test
-	public void testLoginActionFailed() {
-		String actionName = "login";
-		Map<String, String> params = new HashMap<String, String>();
-		params.put("name", "test");
-		params.put("password", "123456"); // 密码和预设的不一致
-
-		View view = Struts.runAction(actionName, params);
-
-		Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
-		Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
-	}
-}
+package assignment0226;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StrutsTest {
+
+	@Test
+	public void testLoginActionSuccess() {
+
+		String actionName = "login";
+
+		Map<String, String> params = new HashMap<String, String>();
+		params.put("name", "test");
+		params.put("password", "1234");
+
+		View view = Struts.runAction(actionName, params);
+
+		Assert.assertEquals("/jsp/homepage.jsp", view.getJsp());
+		Assert.assertEquals("login successful", view.getParameters().get("message"));
+	}
+
+	@Test
+	public void testLoginActionFailed() {
+		String actionName = "login";
+		Map<String, String> params = new HashMap<String, String>();
+		params.put("name", "test");
+		params.put("password", "123456"); // 密码和预设的不一致
+
+		View view = Struts.runAction(actionName, params);
+
+		Assert.assertEquals("/jsp/showLogin.jsp", view.getJsp());
+		Assert.assertEquals("login failed,please check your user/pwd", view.getParameters().get("message"));
+	}
+}
diff --git a/group17/1264835468/src/assignment2_26/View.java b/group17/1264835468/src/assignment0226/View.java
similarity index 87%
rename from group17/1264835468/src/assignment2_26/View.java
rename to group17/1264835468/src/assignment0226/View.java
index e96197fad6..3bd518e451 100644
--- a/group17/1264835468/src/assignment2_26/View.java
+++ b/group17/1264835468/src/assignment0226/View.java
@@ -1,26 +1,26 @@
-package assignment2_26;
-
-import java.util.Map;
-
-public class View {
-	private String jsp;
-	private Map parameters;
-
-	public String getJsp() {
-		return jsp;
-	}
-
-	public View setJsp(String jsp) {
-		this.jsp = jsp;
-		return this;
-	}
-
-	public Map getParameters() {
-		return parameters;
-	}
-
-	public View setParameters(Map parameters) {
-		this.parameters = parameters;
-		return this;
-	}
-}
+package assignment0226;
+
+import java.util.Map;
+
+public class View {
+	private String jsp;
+	private Map parameters;
+
+	public String getJsp() {
+		return jsp;
+	}
+
+	public View setJsp(String jsp) {
+		this.jsp = jsp;
+		return this;
+	}
+
+	public Map getParameters() {
+		return parameters;
+	}
+
+	public View setParameters(Map parameters) {
+		this.parameters = parameters;
+		return this;
+	}
+}
diff --git a/group17/1264835468/src/assignment2_26/XmlParser.java b/group17/1264835468/src/assignment0226/XmlParser.java
similarity index 95%
rename from group17/1264835468/src/assignment2_26/XmlParser.java
rename to group17/1264835468/src/assignment0226/XmlParser.java
index aa34335cb6..4969951082 100644
--- a/group17/1264835468/src/assignment2_26/XmlParser.java
+++ b/group17/1264835468/src/assignment0226/XmlParser.java
@@ -1,72 +1,72 @@
-package assignment2_26;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-public class XmlParser {
-	private File file;
-	List<Element> actionElements;
-
-	public XmlParser(File file) {
-		this.file = file;
-		actionElements = new ArrayList<>();
-		getActionsFromFile();
-	}
-
-	public String getClassNameByActionName(String actionName) {
-		Element action = getElementByActionName(actionName);
-		return action.getAttribute("class");
-	}
-
-	public String getResultJsp(String actionName, String resultName) {
-		Element action = getElementByActionName(actionName);
-		NodeList results = action.getChildNodes();
-		for (int i = 0; i < results.getLength(); i++) {
-			Node child = results.item(i);
-			if (child instanceof Element) {
-				Element result = (Element) child;
-				if (result.getAttribute("name").equals(resultName))
-					return result.getTextContent();
-			}
-		}
-		throw new RuntimeException("not found result named:" + resultName);
-	}
-
-	private Element getElementByActionName(String actionName) {
-		for (Element element : actionElements) {
-			if (element.getAttribute("name").equals(actionName)) {
-				return element;
-			}
-		}
-		throw new RuntimeException("no such element named " + actionName);
-	}
-
-	private void getActionsFromFile() {
-		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-		try {
-			DocumentBuilder builder = factory.newDocumentBuilder();
-			Document document = builder.parse(file);
-			Element root = document.getDocumentElement();
-			NodeList children = root.getChildNodes();
-			for (int i = 0; i < children.getLength(); i++) {
-				Node child = children.item(i);
-				if (child instanceof Element)
-					actionElements.add((Element) child);
-			}
-		} catch (ParserConfigurationException | SAXException | IOException e) {
-			e.printStackTrace();
-		}
-	}
-}
+package assignment0226;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class XmlParser {
+	private File file;
+	List<Element> actionElements;
+
+	public XmlParser(File file) {
+		this.file = file;
+		actionElements = new ArrayList<>();
+		getActionsFromFile();
+	}
+
+	public String getClassNameByActionName(String actionName) {
+		Element action = getElementByActionName(actionName);
+		return action.getAttribute("class");
+	}
+
+	public String getResultJsp(String actionName, String resultName) {
+		Element action = getElementByActionName(actionName);
+		NodeList results = action.getChildNodes();
+		for (int i = 0; i < results.getLength(); i++) {
+			Node child = results.item(i);
+			if (child instanceof Element) {
+				Element result = (Element) child;
+				if (result.getAttribute("name").equals(resultName))
+					return result.getTextContent();
+			}
+		}
+		throw new RuntimeException("not found result named:" + resultName);
+	}
+
+	private Element getElementByActionName(String actionName) {
+		for (Element element : actionElements) {
+			if (element.getAttribute("name").equals(actionName)) {
+				return element;
+			}
+		}
+		throw new RuntimeException("no such element named " + actionName);
+	}
+
+	private void getActionsFromFile() {
+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+		try {
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			Document document = builder.parse(file);
+			Element root = document.getDocumentElement();
+			NodeList children = root.getChildNodes();
+			for (int i = 0; i < children.getLength(); i++) {
+				Node child = children.item(i);
+				if (child instanceof Element)
+					actionElements.add((Element) child);
+			}
+		} catch (ParserConfigurationException | SAXException | IOException e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java b/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..a5add91113
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,59 @@
+package assignment0326.jvm.loader;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Administrator on 2017/3/30.
+ */
+public class ClassFileLoader {
+
+
+        private List<String> clzPaths = new ArrayList<String>();
+
+        public byte[] readBinaryCode(String className) {
+            String path = className.replace(".", File.separator);
+            File classFile=null;
+            for (String p: clzPaths) {
+                classFile=new File(p+File.separator+path+".class");
+                if(classFile.exists())
+                    break;
+            }
+            if(classFile==null)
+                throw new RuntimeException("no such class file");
+
+            byte[] bytes=new byte[(int)classFile.length()];
+            try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(classFile))){
+                bufferedInputStream.read(bytes, 0, bytes.length);
+
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            return bytes;
+        }
+
+
+        public void addClassPath(String path) {
+            clzPaths.add(path);
+        }
+
+
+
+        public String getClassPath(){
+            StringBuilder stringBuilder=new StringBuilder();
+            for (int i = 0; i <clzPaths.size()-1; i++) {
+                stringBuilder.append(clzPaths.get(i) + ";");
+            }
+            stringBuilder.append(clzPaths.get(clzPaths.size()-1));
+            return stringBuilder.toString();
+        }
+
+
+
+
+
+}
diff --git a/group17/1264835468/src/assignment0326/jvm/test/ClassFileLoaderTest.java b/group17/1264835468/src/assignment0326/jvm/test/ClassFileLoaderTest.java
new file mode 100644
index 0000000000..5ebb4075a6
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/jvm/test/ClassFileLoaderTest.java
@@ -0,0 +1,95 @@
+package assignment0326.jvm.test;
+
+/**
+ * Created by Administrator on 2017/3/30.
+ */
+
+import assignment0326.jvm.loader.ClassFileLoader;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+
+
+
+public class ClassFileLoaderTest {
+
+
+    static String path1 = "D:\\GitHub\\group17\\1264835468\\bin";
+    static String path2 = "C:\\Temp";
+
+
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void testClassPath(){
+
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+        loader.addClassPath(path2);
+
+        String clzPath = loader.getClassPath();
+
+        Assert.assertEquals(path1+";"+path2,clzPath);
+
+    }
+
+    @Test
+    public void testClassFileLength() {
+
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+
+        String className = "assignment0326.jvm.test.EmployeeV1";
+
+        byte[] byteCodes = loader.readBinaryCode(className);
+
+        // 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+        Assert.assertEquals(1056, byteCodes.length);
+
+    }
+
+
+    @Test
+    public void testMagicNumber(){
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+        String className = "assignment0326.jvm.test.EmployeeV1";
+        byte[] byteCodes = loader.readBinaryCode(className);
+        byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+        String acctualValue = this.byteToHexString(codes);
+
+        Assert.assertEquals("cafebabe", acctualValue);
+    }
+
+
+
+
+
+
+    private String byteToHexString(byte[] codes ){
+        StringBuffer buffer = new StringBuffer();
+        for(int i=0;i<codes.length;i++){
+            byte b = codes[i];
+            int value = b & 0xFF;
+            String strHex = Integer.toHexString(value);
+            if(strHex.length()< 2){
+                strHex = "0" + strHex;
+            }
+            buffer.append(strHex);
+        }
+        return buffer.toString();
+    }
+
+}
\ No newline at end of file
diff --git a/group17/1264835468/src/assignment0326/jvm/test/EmployeeV1.java b/group17/1264835468/src/assignment0326/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..72b3febb92
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package assignment0326.jvm.test;
+
+public class EmployeeV1 {
+
+
+    private String name;
+    private int age;
+
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+        this.age = age;
+    }
+    public void sayHello() {
+        System.out.println("Hello , this is class Employee ");
+    }
+    public static void main(String[] args){
+        EmployeeV1 p = new EmployeeV1("Andy",29);
+        p.sayHello();
+
+    }
+}
\ No newline at end of file
diff --git a/group17/1264835468/src/assignment0326/lru/Clock.java b/group17/1264835468/src/assignment0326/lru/Clock.java
new file mode 100644
index 0000000000..274b6ebc80
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/lru/Clock.java
@@ -0,0 +1,99 @@
+package assignment0326.lru;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ *  Created by Administrator on 2017/3/29.
+ */
+public class Clock {
+    private PageFrame[] pages;
+    private int capacity;
+    private int accessPtr;
+    private int size;
+    public Clock(int capacity) {
+        this.capacity = capacity;
+        pages = new PageFrame[capacity];
+        accessPtr = 0;
+        size=0;
+    }
+
+    private void access(int pageNum) {
+        int index = search(pageNum);
+        if(index==-1){
+            if(size<capacity){
+                add(new PageFrame(pageNum));
+            }else{
+                pages[findLRUIndex()].pageNum=pageNum;
+            }
+        }else {
+            pages[findLRUIndex()].accessFlag=true;
+        }
+        accessPtr = (accessPtr + 1) % capacity;
+    }
+
+    private int search(int pageNum) {
+        for (int i = 0; i <size; i++) {
+            if(pages[i].pageNum==pageNum)
+                return i;
+        }
+        return -1;
+    }
+
+    private void add(PageFrame pageFrame) {
+        pages[size++]=pageFrame;
+    }
+
+    private int findLRUIndex() {
+        while (pages[accessPtr].shouldGiveAnotherChance()) {
+            accessPtr = (accessPtr + 1) % capacity;
+        }
+        return accessPtr;
+    }
+
+    private static class PageFrame {
+        int pageNum;
+        boolean accessFlag;
+
+        public PageFrame(int pageNum) {
+            this.pageNum = pageNum;
+            accessFlag = true;
+        }
+
+        public boolean shouldGiveAnotherChance() {
+            if (accessFlag) {
+                accessFlag = false;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    public static void main(String[] args) {
+
+        List<String> strings=new ArrayList<>();
+        for (int i = 0; i <10; i++) {
+            strings.add(String.valueOf(new Random().nextInt(3000)));
+        }
+        System.out.println(strings);
+        System.out.println(strings.stream().map(s-> s.charAt(0)).sorted().distinct().limit(5).collect(Collectors.toList()));
+    }
+
+    public int findMinDifference(List<String> timePoints) {
+        List<Integer> list=new ArrayList<>();
+
+        for (String s:timePoints) {
+            list.add(parse(s));
+        }
+        Collections.sort(list);
+        int min=Integer.MAX_VALUE;
+        for (int i = 0; i < list.size()-1; i++) {
+            min=Math.min(min,Math.min(Math.abs(list.get(i+1)-list.get(i)),24*60-Math.abs(list.get(i+1)-list.get(i))));
+        }
+        return min;
+    }
+
+    private Integer parse(String s) {
+        return Integer.parseInt(s.substring(0, 2)) * 60 + Integer.parseInt(s.substring(3, 5));
+    }
+}
diff --git a/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java b/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java
new file mode 100644
index 0000000000..fd2f2693c4
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/lru/LRUPageFrame.java
@@ -0,0 +1,128 @@
+package assignment0326.lru;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+
+    private static class Node {
+        Node prev;
+        Node next;
+        int pageNum;
+        Node() {
+        }
+        public Node(int pageNum) {
+            this.pageNum = pageNum;
+        }
+
+    }
+
+    private int capacity;
+
+
+    private Node first;// 链表头
+    private Node last;// 链表尾
+
+    private int size;
+    public LRUPageFrame(int capacity) {
+        if(capacity<=0)
+            throw new IllegalArgumentException("capacity:"+capacity+" <= 0");
+        this.capacity = capacity;
+        first=null;
+        last=null;
+        size=0;
+
+    }
+
+    /**
+     * 获取缓存中对象
+     *
+     * @param pageNum
+     * @return
+     */
+    public void access(int pageNum) {
+        Node target=search(pageNum);
+        if (target == null) {
+            target=new Node(pageNum);
+            linkFirst(target);
+        }else{
+            moveToFirst(target);
+        }
+        if(size>capacity){
+            removeLast();
+        }
+    }
+
+    private Node search(int pageNum) {
+        Node f=first;
+        while (f!=null){
+            if (f.pageNum == pageNum) {
+                return f;
+            }
+            f=f.next;
+        }
+        return null;
+    }
+
+    private void linkFirst(Node target) {
+        if(first==null){
+            first=last=target;
+        }else {
+            target.next = first;
+            first.prev = target;
+            first = target;
+        }
+        size++;
+    }
+
+    private void moveToFirst(Node target) {
+        if(target==first){
+            return;
+        }
+
+        Node prevOfTarget=target.prev;
+        prevOfTarget.next=target.next;
+
+        if(target==last) {
+            last=prevOfTarget;
+        }else {
+            target.next.prev = prevOfTarget;
+        }
+
+        target.next=first;
+        first.prev=target;
+        first=target;
+
+    }
+
+    private void removeLast() {
+        Node prevOfLast=last.prev;
+        last.prev=null;
+        last=prevOfLast;
+
+        if(last==null){
+            first=null;
+        }else {
+           last.next=null;
+        }
+        size--;
+    }
+
+
+    public String toString(){
+        StringBuilder buffer = new StringBuilder();
+        Node node = first;
+        while(node != null){
+            buffer.append(node.pageNum);
+
+            node = node.next;
+            if(node != null){
+                buffer.append(",");
+            }
+        }
+        return buffer.toString();
+    }
+
+}
\ No newline at end of file
diff --git a/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java b/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java
new file mode 100644
index 0000000000..7a54f54c8d
--- /dev/null
+++ b/group17/1264835468/src/assignment0326/lru/LRUPageFrameTest.java
@@ -0,0 +1,34 @@
+package assignment0326.lru;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Created by Administrator on 2017/3/29.
+ */
+
+
+public class LRUPageFrameTest {
+
+    @Test
+    public void testAccess() {
+        LRUPageFrame frame = new LRUPageFrame(3);
+        frame.access(7);
+        frame.access(0);
+        frame.access(1);
+        Assert.assertEquals("1,0,7", frame.toString());
+        frame.access(2);
+        Assert.assertEquals("2,1,0", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(3);
+        Assert.assertEquals("3,0,2", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,3,2", frame.toString());
+        frame.access(4);
+        Assert.assertEquals("4,0,3", frame.toString());
+    }
+
+}
\ No newline at end of file
diff --git a/group17/1264835468/src/struts.xml b/group17/1264835468/src/struts.xml
index ad43b47967..9ba23d1e24 100644
--- a/group17/1264835468/src/struts.xml
+++ b/group17/1264835468/src/struts.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <struts>
-    <action name="login" class="assignment2_26.LoginAction">
+    <action name="login" class="assignment0226.LoginAction">
         <result name="success">/jsp/homepage.jsp</result>
         <result name="fail">/jsp/showLogin.jsp</result>
     </action>
diff --git a/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java b/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..6d669e294f
--- /dev/null
+++ b/group17/1282579502/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,86 @@
+package com.coderising.jvm.loader;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		String classPath = convertToFilePath(className);
+		File targetFile = null;
+		for(int i = 0; i< clzPaths.size(); i++){
+			String fullPath = clzPaths.get(i)+File.separator+classPath;
+			System.out.println("path: " + fullPath); 
+			File temp = new File(fullPath);
+			if(temp.exists()) {
+				targetFile = temp;
+				break;
+			}
+		}
+		
+		if(targetFile != null){
+			System.out.println("targetFile: " + targetFile.getAbsolutePath());
+		}
+		long fileLength = targetFile.length();
+		System.out.println("File length: " + fileLength); 
+		byte[] byteArray = new byte[(int)fileLength];
+		FileInputStream is = null;
+		try {
+			is = new FileInputStream(targetFile);
+			is.read(byteArray);
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}finally{
+			if(is != null){
+				try {
+					is.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		
+		
+		return byteArray;	
+		
+		
+	}
+	
+	private String convertToFilePath(String className){
+		return className.replaceAll("\\.", File.separator) + ".class";
+	}
+	
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+	
+	
+	
+	public String getClassPath(){
+		StringBuilder sb = new StringBuilder();
+		for(String item : clzPaths){
+			sb.append(item + ";");
+		}
+		return sb.substring(0, sb.length()-1);
+	}
+
+	
+
+	
+
+}
\ No newline at end of file
diff --git a/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..4df3f4b529
--- /dev/null
+++ b/group17/1282579502/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,103 @@
+package com.coderising.jvm.test;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin";
+	static String path2 = "C:\temp";
+	static String path3 = "/Users/erlisuo/Documents/workspace/codeRising2017working/1282579502/bin";
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		loader.addClassPath(path3);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	
+    @Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path3);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    @Test
+    public void testToHexString(){
+    	byte b1 = 'a';
+    	byte b2 = 'b';
+    	System.out.println("Binary: " + Integer.toBinaryString(b1) + " decimal: " + Integer.toString(b1) + " hex: " + Integer.toHexString(b1));
+    	System.out.println("Binary: " + Integer.toBinaryString(b2) + " decimal: " + Integer.toString(b2) + " hex: " + Integer.toHexString(b2));
+
+    	byte[] bArray = new byte[]{b1, b2};
+    	System.out.println(byteToHexString(bArray));
+    }
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
\ No newline at end of file
diff --git a/group17/1282579502/src/com/coderising/jvm/test/EmployeeV1.java b/group17/1282579502/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group17/1282579502/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group17/1282579502/src/com/coding/basic/LinkedList.java b/group17/1282579502/src/com/coding/basic/LinkedList.java
index 55db7e97bc..8f6ce0a9d3 100644
--- a/group17/1282579502/src/com/coding/basic/LinkedList.java
+++ b/group17/1282579502/src/com/coding/basic/LinkedList.java
@@ -2,9 +2,9 @@
 
 public class LinkedList implements List {
 	
-	private Node head = null;
-	private Node tail = null;
-	private int size = 0;
+	protected Node head = null;
+	protected Node tail = null;
+	protected int size = 0;
 	
 	public void add(Object o){
 		if(head == null){
@@ -109,7 +109,7 @@ public Iterator iterator(){
 		return new LinkedListIterator(this);
 	}
 	
-	private  class Node{
+	protected  class Node{
 		public Object data = null;
 		public Node next = null;
 		public Node(Object o){
diff --git a/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrame.java b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..7e8a8a531a
--- /dev/null
+++ b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,170 @@
+package com.coding.basic.linklist;
+
+import java.util.HashMap;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	public static void main(String[] args){
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		System.out.println("array: " + frame.toString());
+		frame.access(2);
+		System.out.println("array: " + frame.toString());
+		
+		frame.access(0);
+		System.out.println("array: " + frame.toString());
+		frame.access(0);
+		System.out.println("array: " + frame.toString());
+		frame.access(3);
+		System.out.println("array: " + frame.toString());
+		//frame.printList();
+		frame.access(0);
+		//frame.printList();
+		System.out.println("array: " + frame.toString());
+		System.out.println();
+		frame.access(4);
+		//frame.printList();
+		System.out.println(frame);
+	}
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	
+	private int count;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	private HashMap<Integer, Node> keyHash;
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		this.count = 0;
+		keyHash = new HashMap<Integer, Node>();
+		first = new Node();
+		first.pageNum = -99;
+		last = new Node();
+		last.pageNum = -99;
+		first.next = last;
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		Node targetPageNode = keyHash.get(new Integer(pageNum));
+		
+		if(targetPageNode == null){
+			targetPageNode = new Node();
+			targetPageNode.pageNum = pageNum;
+			addNewPage(targetPageNode);
+		}
+		else{
+			moveToTop(targetPageNode);
+		}
+	
+	}
+	/*
+	 * null - first - f1 - f2 -f3
+	 */
+	private void moveToTop(Node targetNode){
+		if(targetNode != first.next){
+			targetNode.prev.next = targetNode.next;
+			if(targetNode.next != null){
+				targetNode.next.prev = targetNode.prev;
+			}
+			
+			targetNode.next = first.next;
+			if(first.next != null){
+				first.next.prev = targetNode;
+			}
+			
+			first.next = targetNode;
+			targetNode.prev = first;
+		}
+	}
+	
+	private void addNewPage(Node targetPageNode){
+		//first.next ?= null
+		//
+		targetPageNode.next = first.next;
+		if(first.next != null){
+			first.next.prev = targetPageNode;
+		}
+		
+		first.next = targetPageNode;
+		targetPageNode.prev = first;
+		
+		keyHash.put(targetPageNode.pageNum, targetPageNode);
+		count++;
+		if(count > capacity){
+			popOutLast();
+		}	
+	}
+	/*
+	 * t3 - t2 - t1 - last - null
+	 */
+	private void popOutLast(){
+		Node tailNode = last.prev; //t1
+		if(tailNode != null){
+			Node preTailNode = tailNode.prev; //t2
+			if(preTailNode != null){
+				keyHash.remove(preTailNode.pageNum);
+				preTailNode.next = last; //t2 -> last
+				last.prev = preTailNode; 
+				count --;
+			}
+		}
+	}
+	public void printList(){
+		int tmpcount = 0;
+		Node node = first.next;
+		while(node != last && tmpcount++<20){
+			System.out.println("current: "+node.pageNum+ " parent: " + node.prev.pageNum);
+			node = node.next;
+		}
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first.next;
+		while(node != null){
+			if(node == last) break;
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+			
+		}
+		
+		String returnStr = null;
+		if(buffer.charAt(buffer.length() -1 ) == ','){
+			returnStr = buffer.substring(0, buffer.length() -1);
+		}else{
+			returnStr = buffer.toString();
+		}
+		return returnStr;
+	}
+	
+}
\ No newline at end of file
diff --git a/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..0bfbe14fd0
--- /dev/null
+++ b/group17/1282579502/src/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,55 @@
+package com.coding.basic.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+//	@Test
+//	public void toStringTest(){
+//		LRUPageFrame frame = new LRUPageFrame(3);
+//		frame.access(7);
+//		frame.access(0);
+//		frame.access(1);
+//		System.out.println("array: " + frame.toString());
+//		frame.access(2);
+//		System.out.println("array: " + frame.toString());
+//		
+//		frame.access(0);
+//		System.out.println("array: " + frame.toString());
+//		frame.access(0);
+//		System.out.println("array: " + frame.toString());
+//		frame.access(3);
+//		System.out.println("array: " + frame.toString());
+//		
+//		frame.access(0);
+//		System.out.println("array: " + frame.toString());
+//		
+//		frame.access(4);
+//		System.out.println("array: " + frame.toString());
+//	}
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+	
+}
\ No newline at end of file
diff --git a/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java
new file mode 100644
index 0000000000..638cf181ae
--- /dev/null
+++ b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrame.java
@@ -0,0 +1,126 @@
+package com.coding.basic.linklist;
+
+/**
+ * 用双向链表实现LRU算法
+ * @author liuxin
+ *
+ */
+public class LRUPageFrame {
+	
+	private static class Node {
+		
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node() {
+		}
+	}
+
+	private int capacity;
+	private int currentSize;
+	
+	private Node first;// 链表头
+	private Node last;// 链表尾
+
+	
+	public LRUPageFrame(int capacity) {
+		
+		this.capacity = capacity;
+		currentSize = 0;
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		
+		// 判断缓存是否命中
+		Node n = find(pageNum);
+		if(n != null){
+			// 命中，则把节点提到表头
+			moveNodeToHead(n);
+		}else{
+			// 若未命中，新增节点放到表头，如果链表长度超过capacity，移除链表尾部节点
+			n = new Node();
+			n.pageNum = pageNum;
+			
+			if(currentSize >= capacity){
+				removeLast();
+			}
+			addNodeToHead(n);
+		}
+	}
+	
+	
+
+	private void addNodeToHead(Node n) {
+		if(first == null){
+			first = n;
+			last = n;
+		}else{
+			n.next = first;
+			first.prev = n;
+			first = n;
+		}
+		currentSize++;
+	}
+
+	private void removeLast() {
+		Node prevN = last.prev;
+		prevN.next = null;
+		last.prev = null;
+		last = prevN;
+		currentSize--;
+	}
+
+	private void moveNodeToHead(Node n) {
+		if(n == first){
+			return ;
+		}else if(n == last){
+			Node preN = n.prev;
+			preN.next = null;
+			last.prev = null;
+			last = preN;
+		}else{
+			// 中间节点 
+			Node preN = n.prev;
+			Node nextN = n.next;
+			preN.next = nextN;
+			nextN.prev = preN;
+		}
+		n.prev = null;
+		n.next = first;
+		first.prev = n;
+		first = n;
+	}
+
+	private Node find(int pageNum) {
+		Node n = first;
+		while(n != null){
+			if(n.pageNum == pageNum){
+				return n;
+			}
+			n = n.next;
+		}
+		return null;
+	}
+
+	public String toString(){
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while(node != null){
+			buffer.append(node.pageNum);			
+			
+			node = node.next;
+			if(node != null){
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+	
+}
diff --git a/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java
new file mode 100644
index 0000000000..67cf36067b
--- /dev/null
+++ b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LRUPageFrameTest.java
@@ -0,0 +1,31 @@
+package com.coding.basic.linklist;
+
+import  org.junit.Assert;
+
+import org.junit.Test;
+
+
+public class LRUPageFrameTest {
+	
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java
new file mode 100644
index 0000000000..f4c7556a2e
--- /dev/null
+++ b/group17/240094626/work_jvm_1/data-structure/src/com/coding/basic/linklist/LinkedList.java
@@ -0,0 +1,125 @@
+package com.coding.basic.linklist;
+
+import com.coding.basic.Iterator;
+import com.coding.basic.List;
+
+public class LinkedList implements List {
+	
+	private Node head;
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index , Object o){
+		
+	}
+	public Object get(int index){
+		return null;
+	}
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		return -1;
+	}
+	
+	public void addFirst(Object o){
+		
+	}
+	public void addLast(Object o){
+		
+	}
+	public Object removeFirst(){
+		return null;
+	}
+	public Object removeLast(){
+		return null;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+		
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public  void reverse(){		
+		
+	}
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public  void removeFirstHalf(){
+		
+	}
+	
+	/**
+	 * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		return null;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public  void removeRange(int min, int max){
+		
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public  LinkedList intersection( LinkedList list){
+		return null;
+	}
+}
diff --git a/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java b/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..b9d924a887
--- /dev/null
+++ b/group17/240094626/work_jvm_1/src/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,73 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+
+public class ClassFileLoader {
+
+	private List<String> clzPaths = new ArrayList<String>();
+	
+	public byte[] readBinaryCode(String className) {
+		if(null == className || "".equals(className)){
+			return null;
+		}
+		className = className.replace(".", File.separator)+".class";
+		Iterator<String> it = clzPaths.iterator();
+		byte[] bytes = null;
+		while(it.hasNext() && bytes == null){
+			String filePath = it.next()+File.separator+className;
+			bytes = getClassFile(filePath);
+		}
+		return bytes;	
+		
+	}
+	
+	
+	private byte[] getClassFile(String filePath) {
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		try {
+			InputStream is = new FileInputStream(new File(filePath));
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			while((len=is.read(buffer)) > 0){
+				bos.write(buffer,0, len);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return bos.toByteArray();
+	}
+
+
+	public void addClassPath(String path) {
+		if(null != path && !"".equals(path)){
+			clzPaths.add(path);
+		}
+	}
+	
+	
+	
+	public String getClassPath(){
+		StringBuilder sb = new StringBuilder();
+		Iterator<String> it = clzPaths.iterator();
+		while(it.hasNext()){
+			if(sb.length() > 0){
+				sb.append(";");
+			}
+			sb.append(it.next());
+		}
+		return sb.toString();
+	}
+
+	
+
+	
+
+}
diff --git a/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java
new file mode 100644
index 0000000000..a205045d2e
--- /dev/null
+++ b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -0,0 +1,92 @@
+package com.coderising.jvm.test;
+
+import java.io.File;
+
+import org.junit.After;
+import  org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.coderising.jvm.loader.ClassFileLoader;
+
+
+
+
+
+public class ClassFileloaderTest {
+
+	
+	static String path1 = "E:\\workspace-indigo-32-statsdb\\warm-up\\bin";//"C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin";
+	static String path2 = "C:\temp";
+	
+	
+	
+	@Before
+	public void setUp() throws Exception {		 
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+	
+	@Test
+	public void testClassPath(){		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+		
+	}
+	
+	@Test
+	public void testClassFileLength() {		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+	
+	@Test
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+    
+    
+    
+    
+    
+    
+	private String byteToHexString(byte[] codes ){
+		StringBuffer buffer = new StringBuffer();
+		for(int i=0;i<codes.length;i++){
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if(strHex.length()< 2){
+				strHex = "0" + strHex;
+			}		
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/EmployeeV1.java b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..12e3d7efdd
--- /dev/null
+++ b/group17/240094626/work_jvm_1/src/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	
+	
+	private String name;
+    private int age;
+    
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;        
+    }    
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    public void setAge(int age){
+    	this.age = age;
+    }
+    public void sayHello() {        
+    	System.out.println("Hello , this is class Employee ");    	
+    }
+    public static void main(String[] args){
+    	EmployeeV1 p = new EmployeeV1("Andy",29);
+    	p.sayHello();    
+    	
+    }
+}
\ No newline at end of file
diff --git a/group17/785396327/3.12/link/LinkedList.java b/group17/785396327/3.12/link/LinkedList.java
new file mode 100644
index 0000000000..3c3b987f41
--- /dev/null
+++ b/group17/785396327/3.12/link/LinkedList.java
@@ -0,0 +1,317 @@
+package link;
+
+import list.ArrayList;
+import list.List;
+
+import java.util.*;
+
+/**
+ * Created by gongxun on 2017/3/13.
+ */
+public class LinkedList<T> {
+    private Node<T> head;
+    private int size = 0;
+
+    public void add(T o) {
+        if (head == null) {
+            head = new Node<T>(null, o);
+            size++;
+        } else
+            addLast(o);
+    }
+
+    private Node<T> getLast() {
+        Node<T> last = head;
+        while (last.next != null) {
+            last = last.next;
+        }
+        return last;
+    }
+
+    private Node<T> getNodeIndex(int index) {
+        if (index > size - 1)
+            throw new IndexOutOfBoundsException("size : " + size + ", index : " + index);
+        Node target = head;
+        for (int i = 0; i < size; i++) {
+            if (i == index)
+                return target;
+            target = target.next;
+        }
+        return null;
+    }
+
+    public void add(int index, T o) {
+        Node<T> node = getNodeIndex(index - 1);
+        Node<T> nextNode = node.next;
+        node.next = new Node<T>(nextNode, o);
+        size++;
+    }
+
+    public T get(int index) {
+        Node<T> node = getNodeIndex(index);
+        return node.data;
+    }
+
+    public T remove(int index) {
+        Node<T> prev = getNodeIndex(index - 1);
+        Node<T> now = getNodeIndex(index);
+        prev.next = now.next;
+        size--;
+        return now.data;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public void addFirst(T o) {
+        if (head != null)
+            head = new Node<T>(null, o);
+        else {
+            Node newNode = new Node(head, o);
+            head = newNode;
+        }
+        size++;
+    }
+
+    public void addLast(T o) {
+        add(size, o);
+    }
+
+    public T removeFirst() {
+        Node<T> removeNode = head;
+        if (head != null)
+            head = head.next;
+        size--;
+        return removeNode == null ? null : removeNode.data;
+    }
+
+    public T removeLast() {
+        Node<T> last = getNodeIndex(size - 1);
+        Node<T> prev = getNodeIndex(size - 2);
+        prev.next = null;
+        size--;
+        return last.data;
+    }
+
+    public Iterator iterator() {
+        return null;
+    }
+
+    private int getIndex(Node<T> node) {
+        Node temp = head;
+        int index = 0;
+        while (temp != null) {
+            if (temp == node) {
+                return index;
+            }
+        }
+        return -1;
+    }
+
+    private int getIndexByData(T data) {
+        Node temp = head;
+        int index = 0;
+        while (temp != null) {
+            if ((data == null && temp.data == null) || temp.data.equals(data))
+                return index;
+            index++;
+            temp = temp.next;
+        }
+        return -1;
+    }
+
+
+    private static class Node<T> {
+        T data;
+        Node<T> next;
+
+        Node(Node next, T data) {
+            this.next = next;
+            this.data = data;
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        Node temp = head;
+        while (temp != null) {
+            sb.append(temp.data).append("-->");
+            temp = temp.next;
+        }
+        return sb.toString().substring(0, sb.lastIndexOf("-->"));
+    }
+
+    /**
+     * 把该链表逆置
+     * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+     */
+    public void reverse() {
+        Node cur = null;
+        Node prev = null;
+        while (head != null) {
+            cur = head;
+            head = head.next;
+            cur.next = prev;
+            prev = cur;
+        }
+        head = cur;
+    }
+
+    /**
+     * 删除一个单链表的前半部分
+     * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+     * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+     */
+    public void removeFirstHalf() {
+        head = getNodeIndex(size / 2);
+    }
+
+    /**
+     * 从第i个元素开始， 删除length 个元素 ， 注意i从0开始
+     *
+     * @param i
+     * @param length
+     */
+    public void remove(int i, int length) {
+        if (size <= (i + length) || i < 0)
+            throw new IndexOutOfBoundsException("size : " + size + ", i + length : " + (i + length));
+        Node<T> rightNode = getNodeIndex(i + length);
+        if (i == 0)
+            head = rightNode;
+        else {
+            Node<T> leftNode = getNodeIndex(i - 1);
+            leftNode.next = rightNode;
+        }
+    }
+
+    /**
+     * 假定当前链表和list均包含已升序排列的整数
+     * 从当前链表中取出那些list所指定的元素
+     * 例如当前链表 = 11->101->201->301->401->501->601->701
+     * listB = 1->3->4->6
+     * 返回的结果应该是[101,301,401,601]
+     *
+     * @param list
+     */
+    public Object[] getElements(LinkedList<Integer> list) {
+        Object[] result = new Object[list.size];
+        if (list != null) {
+            for (int i = 0; i < list.size; i++) {
+                result[i] = get(list.get(i));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+     * 从当前链表中中删除在list中出现的元素
+     *
+     * @param list
+     */
+
+    public void subtract(LinkedList<T> list) {
+        if (list != null && list.size > 0) {
+            for (int i = 0; i < list.size; i++) {
+                int index = getIndexByData(list.get(i));
+                if (index != -1)
+                    remove(index);
+                else
+                    throw new RuntimeException("wrong element of removed list");
+            }
+        }
+    }
+
+    /**
+     * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+     * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+     */
+    public void removeDuplicateValues() {
+        Node<T> temp = head;
+        List<T> list = new ArrayList<T>();
+        int index = 0;
+        while (temp != null) {
+            if (list.contains(temp.data))
+                remove(index--);
+            else
+                list.add(temp.data);
+            temp = temp.next;
+            index++;
+        }
+    }
+
+    /**
+     * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+     * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+     *
+     * @param min
+     * @param max
+     */
+    public void removeRange(int min, int max) {
+        Integer first = (Integer) get(0);
+        Integer last = (Integer) getLast().data;
+        if (first > max || last < min)
+            return;
+        List<Integer> indexRange = new ArrayList<Integer>();
+        Node<Integer> temp = (Node<Integer>) head;
+        int index = 0;
+        while (temp != null) {
+            if (temp.data >= min && temp.data <= max) {
+                indexRange.add(index);
+            }
+            index++;
+            temp = temp.next;
+        }
+        remove(indexRange.get(0), indexRange.size());
+    }
+
+    /**
+     * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+     * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+     *
+     * @param list
+     */
+    public LinkedList intersection(LinkedList<Integer> list) {
+        LinkedList<Integer> newList = new LinkedList<Integer>();
+        merge(newList, (Node<Integer>) this.head, list.head);
+        return newList;
+    }
+
+    private void merge(LinkedList<Integer> newList, Node<Integer> thisHead, Node<Integer> mergeHead) {
+        if (thisHead == null && mergeHead == null)
+            return;
+        if (thisHead == null) {
+            //无论是否包含，有元素的链表必须指向next
+            if (!newList.contains(mergeHead.data))
+                newList.add(mergeHead.data);
+            mergeHead = mergeHead.next;
+            merge(newList, null, mergeHead);
+        }
+        if (mergeHead == null) {
+            if (!newList.contains(thisHead.data))
+                newList.add(thisHead.data);
+            thisHead = thisHead.next;
+            merge(newList, thisHead, null);
+        }
+        //要再进行一次判断是因为递归到最底层return之后，返回上一层时某个链表已经为null了，但是上一层还是会将剩下的执行完
+        if (thisHead != null && mergeHead != null) {
+            if (thisHead.data < mergeHead.data && !newList.contains(thisHead.data)) {
+                newList.add(thisHead.data);
+                thisHead = thisHead.next;
+                merge(newList, thisHead, mergeHead);
+            } else if (!newList.contains(mergeHead.data)) {
+                newList.add(mergeHead.data);
+                mergeHead = mergeHead.next;
+                merge(newList, thisHead, mergeHead);
+            }
+        }
+    }
+
+    private boolean contains(Integer data) {
+        int index = this.getIndexByData((T) data);
+        return index != -1;
+    }
+}
diff --git a/group17/785396327/3.12/link/LinkedListTest.java b/group17/785396327/3.12/link/LinkedListTest.java
new file mode 100644
index 0000000000..87edc35e99
--- /dev/null
+++ b/group17/785396327/3.12/link/LinkedListTest.java
@@ -0,0 +1,145 @@
+package link;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+/**
+ * Created by gongxun on 2017/3/13.
+ */
+public class LinkedListTest {
+    private LinkedList<String> linkedList;
+
+    @Before
+    public void startUp() {
+        linkedList = new LinkedList();
+        linkedList.add("1");
+        linkedList.add("2");
+        linkedList.add("3");
+//        System.out.println(linkedList);
+    }
+
+    @After
+    public void tearDown() {
+
+    }
+
+    @Test
+    public void addFirst() {
+        linkedList.addFirst("1");
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void add() {
+        linkedList.add("1");
+        linkedList.add("2");
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void add2() {
+        linkedList.add("1");
+        linkedList.add("2");
+        linkedList.add("3");
+        linkedList.add(1, "0");
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void addLast() {
+        linkedList.add("1");
+        linkedList.addLast("2");
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void get() {
+        String value = linkedList.get(2);
+        System.out.println(value);
+    }
+
+    @Test
+    public void remove() {
+        String removeValue = linkedList.remove(3);
+        System.out.println(removeValue);
+    }
+
+    @Test
+    public void reverse() {
+        linkedList.reverse();
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void removeFirstHalf() {
+        linkedList.removeFirstHalf();
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void removeByRange() {
+        linkedList.remove(0, 2);
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void getElements() {
+        LinkedList<Integer> indexList = new LinkedList();
+        indexList.add(0);
+        indexList.add(2);
+        indexList.add(3);
+        Object[] elements = linkedList.getElements(indexList);
+        System.out.println(Arrays.toString(elements));
+    }
+
+    @Test
+    public void subtract() {
+        LinkedList<String> indexList = new LinkedList<String>();
+        indexList.add("2");
+        indexList.add("0");
+        linkedList.subtract(indexList);
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void removeDuplicateValues() {
+        linkedList.add("3");
+        linkedList.add("7");
+        linkedList.add("0");
+        linkedList.add("1");
+        System.out.println(linkedList);
+        linkedList.removeDuplicateValues();
+        System.out.println(linkedList);
+    }
+
+    @Test
+    public void removeRange() {
+        LinkedList<Integer> list = new LinkedList<Integer>();
+        list.add(1);
+        list.add(3);
+        list.add(4);
+        list.add(5);
+        list.add(7);
+        System.out.println(list);
+        list.removeRange(1, 6);
+        System.out.println(list);
+    }
+
+    @Test
+    public void intersection() {
+        LinkedList<Integer> list1 = new LinkedList<Integer>();
+        list1.add(2);
+        list1.add(3);
+        list1.add(7);
+        LinkedList<Integer> list2 = new LinkedList<Integer>();
+        list2.add(2);
+        list2.add(3);
+        list2.add(7);
+        LinkedList newList = list1.intersection(list2);
+        System.out.println(newList);
+    }
+
+}
diff --git a/group17/785396327/3.26/jvm_1/ClassFileLoader.java b/group17/785396327/3.26/jvm_1/ClassFileLoader.java
new file mode 100644
index 0000000000..95f68a5a7f
--- /dev/null
+++ b/group17/785396327/3.26/jvm_1/ClassFileLoader.java
@@ -0,0 +1,50 @@
+package jvm_1;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by william on 2017/4/5.
+ */
+public class ClassFileLoader {
+    private List<String> clzPaths = new ArrayList<String>();
+
+    public byte[] readBinaryCode(String className) {
+        InputStream fis = null;
+        String filePath = clzPaths.get(0) + "\\\\" + className.replaceAll("\\.", "\\\\") + ".class";
+        byte[] buffer = new byte[(int) new File(filePath).length()];
+        try {
+            if (clzPaths.size() > 0 && className != null && !className.trim().equals("")) {
+                fis = new FileInputStream(filePath);
+                while (fis.read(buffer) != -1) ;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fis != null)
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                } finally {
+                    fis = null;
+                }
+        }
+        return buffer;
+    }
+
+
+    public void addClassPath(String path) {
+        clzPaths.add(path);
+    }
+
+
+    public String getClassPath() {
+        StringBuilder sb = new StringBuilder();
+        for (String clzPath : clzPaths) {
+            sb.append(clzPath).append(";");
+        }
+        return sb.substring(0, sb.length() - 1);
+    }
+}
diff --git a/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java
new file mode 100644
index 0000000000..067cd93c2b
--- /dev/null
+++ b/group17/785396327/3.26/jvm_1/ClassFileloaderTest.java
@@ -0,0 +1,86 @@
+package jvm_1;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Created by william on 2017/4/5.
+ */
+public class ClassFileloaderTest {
+    static String path1 = "D:\\workspace\\IDEA\\homework\\coding2017\\group17\\785396327\\out\\production\\785396327";
+    static String path2 = "C:\temp";
+
+
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test
+    public void testClassPath(){
+
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+        loader.addClassPath(path2);
+
+        String clzPath = loader.getClassPath();
+
+        Assert.assertEquals(path1+";"+path2,clzPath);
+
+    }
+
+    @Test
+    public void testClassFileLength() {
+
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+
+        String className = "jvm_1.EmployeeV1";
+
+        byte[] byteCodes = loader.readBinaryCode(className);
+
+        // 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+        Assert.assertEquals(1020, byteCodes.length);
+
+    }
+
+
+    @Test
+    public void testMagicNumber(){
+        ClassFileLoader loader = new ClassFileLoader();
+        loader.addClassPath(path1);
+        String className = "jvm_1.EmployeeV1";
+        byte[] byteCodes = loader.readBinaryCode(className);
+        byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+
+
+        String acctualValue = this.byteToHexString(codes);
+
+        Assert.assertEquals("cafebabe", acctualValue);
+    }
+
+
+
+
+
+
+    private String byteToHexString(byte[] codes ){
+        StringBuffer buffer = new StringBuffer();
+        for(int i=0;i<codes.length;i++){
+            byte b = codes[i];
+            int value = b & 0xFF;
+            String strHex = Integer.toHexString(value);
+            if(strHex.length()< 2){
+                strHex = "0" + strHex;
+            }
+            buffer.append(strHex);
+        }
+        return buffer.toString();
+    }
+}
diff --git a/group17/785396327/3.26/jvm_1/EmployeeV1.java b/group17/785396327/3.26/jvm_1/EmployeeV1.java
new file mode 100644
index 0000000000..bb23d04390
--- /dev/null
+++ b/group17/785396327/3.26/jvm_1/EmployeeV1.java
@@ -0,0 +1,32 @@
+package jvm_1;
+
+/**
+ * Created by william on 2017/4/5.
+ */
+public class EmployeeV1 {
+    private String name;
+    private int age;
+
+    public EmployeeV1(String name, int age) {
+        this.name = name;
+        this.age = age;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    public void sayHello() {
+        System.out.println("Hello , this is class Employee ");
+    }
+
+    public static void main(String[] args) {
+        EmployeeV1 p = new EmployeeV1("Andy", 29);
+        p.sayHello();
+
+    }
+}
diff --git a/group17/785396327/3.26/lru/LRUPageFrame.java b/group17/785396327/3.26/lru/LRUPageFrame.java
new file mode 100644
index 0000000000..d296335978
--- /dev/null
+++ b/group17/785396327/3.26/lru/LRUPageFrame.java
@@ -0,0 +1,131 @@
+package lru;
+
+/**
+ * Created by william on 2017/3/31.
+ * 1. 新数据插入到链表头部；
+ * 2. 每当缓存命中（即缓存数据被访问），则将数据移到链表头部；
+ * 3. 当链表满的时候，将链表尾部的数据丢弃。
+ */
+public class LRUPageFrame {
+    private static class Node {
+
+        Node prev;
+        Node next;
+        int pageNum;
+
+        Node() {
+        }
+
+        @Override
+        public String toString() {
+            return pageNum + "";
+        }
+    }
+
+    private int capacity;
+
+
+    private Node first;// 链表头
+    private Node last;// 链表尾
+    private int size;
+
+    private void removeLast() {
+        if (last != null) {
+            if (size == 1) {
+                first = last = null;
+                size = 0;
+            } else {
+                last = last.prev;
+                last.next = null;
+                size--;
+            }
+        }
+    }
+
+    private void remove(Integer pageNum) {
+        for (Node temp = first; temp != null; temp = temp.next) {
+            if (temp.pageNum == pageNum) {
+                unlink(temp);
+            }
+        }
+    }
+
+    private void unlink(Node node) {
+        final Node prev = node.prev;
+        final Node next = node.next;
+        if (prev == null) {
+            first = next;
+            size--;
+        } else if (next == null)
+            removeLast();
+        else {
+            node.next.prev = prev;
+            node.prev.next = next;
+            size--;
+        }
+    }
+
+    private void addFirst(Integer pageNum) {
+        Node newNode = new Node();
+        newNode.pageNum = pageNum;
+        if (first == null) {
+            first = last = newNode;
+        } else {
+            newNode.next = first;
+            first.prev = newNode;
+            first = newNode;
+            //在插入第二个元素时设置last元素的前项
+            if (size == 1) last.prev = first;
+        }
+        size++;
+    }
+
+    private boolean contains(Integer pageNum) {
+        Node temp = first;
+        while (temp != null) {
+            if (temp.pageNum == pageNum)
+                return true;
+            temp = temp.next;
+        }
+        return false;
+    }
+
+
+    public LRUPageFrame(int capacity) {
+        this.capacity = capacity;
+    }
+
+    /**
+     * 获取缓存中对象
+     *
+     * @param pageNum
+     * @return
+     */
+    public void access(int pageNum) {
+        //存在链表元素
+        if (this.contains(pageNum)) {
+            remove(pageNum);
+            addFirst(pageNum);
+        } else {
+            //不存在
+            if (size == capacity)
+                removeLast();
+            addFirst(pageNum);
+        }
+    }
+
+
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        Node node = first;
+        while (node != null) {
+            buffer.append(node.pageNum);
+
+            node = node.next;
+            if (node != null) {
+                buffer.append(",");
+            }
+        }
+        return buffer.toString();
+    }
+}
diff --git a/group17/785396327/3.26/lru/LRUPageFrameTest.java b/group17/785396327/3.26/lru/LRUPageFrameTest.java
new file mode 100644
index 0000000000..ff619f5b6d
--- /dev/null
+++ b/group17/785396327/3.26/lru/LRUPageFrameTest.java
@@ -0,0 +1,47 @@
+package lru;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Created by william on 2017/3/31.
+ */
+public class LRUPageFrameTest {
+    @Test
+    public void testAccess() {
+        LRUPageFrame frame = new LRUPageFrame(3);
+        frame.access(7);
+        frame.access(0);
+        frame.access(1);
+        Assert.assertEquals("1,0,7", frame.toString());
+        frame.access(2);
+        Assert.assertEquals("2,1,0", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,2,1", frame.toString());
+        frame.access(3);
+        Assert.assertEquals("3,0,2", frame.toString());
+        frame.access(0);
+        Assert.assertEquals("0,3,2", frame.toString());
+        frame.access(4);
+        Assert.assertEquals("4,0,3", frame.toString());
+    }
+
+    @Test
+    public void testInnerMethod() {
+//        lru.LRUPageFrame lruPageFrame = new lru.LRUPageFrame(3);
+//        lruPageFrame.access(1);
+//        lruPageFrame.access(2);
+//        lruPageFrame.access(3);
+//        lruPageFrame.access(4);
+//        System.out.println(lruPageFrame);
+//        System.out.println(lruPageFrame.last);
+//        lruPageFrame.removeLast();
+//        System.out.println(lruPageFrame);
+//        lruPageFrame.addFirst(0);
+//        System.out.println(lruPageFrame);
+//        lruPageFrame.remove(2);
+//        System.out.println(lruPageFrame);
+    }
+}
diff --git a/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
new file mode 100644
index 0000000000..fafac43407
--- /dev/null
+++ b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/loader/ClassFileLoader.java
@@ -0,0 +1,104 @@
+package com.coderising.jvm.loader;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassFileLoader {
+	private static final int BUFFERSIZE = 1024;
+	private List<String> clzPaths = new ArrayList<String>();
+
+	public byte[] readBinaryCode(String className) {
+		if (clzPaths.size()<=0){
+			return null;
+		}
+		for (int i = 0; i < clzPaths.size(); i++) {
+			String path = clzPaths.get(i) + convertName(className);
+			File f = new File(path);
+			if(f.exists()){
+				try {
+					return readFile(f);
+				} catch (FileNotFoundException e) {
+					e.printStackTrace();
+				}
+			}else{
+				f = null;
+				continue;
+			}
+		}
+		System.err.println("classpath:" +getClassPath()+ "class:" + convertName(className)+" not found.");
+		return null;
+	}
+	/**
+	 * 文件读取二进制字节流
+	 * @param f
+	 * @return
+	 * @throws FileNotFoundException
+	 */
+	private byte[] readFile(File f) throws FileNotFoundException {
+		FileInputStream fis = new FileInputStream(f);
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		byte[] b = new byte[BUFFERSIZE];
+		try {
+			int len = 0;
+			while((len = fis.read(b))!=-1){
+				baos.write(b,0,len);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally{
+			try {
+				fis.close();
+				baos.flush();
+				baos.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			
+		}
+		return baos.toByteArray();
+	}
+
+	public void addClassPath(String path) {
+		clzPaths.add(path);
+	}
+
+	public String getClassPath() {
+		StringBuilder sb = new StringBuilder();
+		for (int i = 0; i < clzPaths.size(); i++) {
+			sb.append(clzPaths.get(i)).append(";");
+		}
+		int len = sb.length();
+		if(len!=0){
+			sb.deleteCharAt(len-1);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * convert className to FilePath style className <br/>
+	 * For example:com.sun.lang to \com\sun\lang
+	 * 
+	 * @param className
+	 * @return FilePath style className
+	 */
+	private String convertName(String className) {
+		StringBuilder sb = new StringBuilder();
+		String[] pack = className.split("\\.");
+		for (int i = 0; i < pack.length; i++) {
+			sb.append("\\").append(pack[i]);
+		}
+		sb.append(".class");
+		return sb.toString();
+	}
+
+	public static void main(String[] args) {
+		String d = "com.taiji.array.Load";
+		ClassFileLoader cc = new ClassFileLoader();
+		System.out.print(cc.convertName(d));
+	}
+}
diff --git a/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java
new file mode 100644
index 0000000000..70ec469ee6
--- /dev/null
+++ b/group17/82427129/JavaUtil/src/main/java/com/coderising/jvm/test/EmployeeV1.java
@@ -0,0 +1,29 @@
+package com.coderising.jvm.test;
+
+public class EmployeeV1 {
+	private String name;
+	private int age;
+
+	public EmployeeV1(String name, int age) {
+		this.name = name;
+		this.age = age;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public void setAge(int age) {
+		this.age = age;
+	}
+
+	public void sayHello() {
+		System.out.println("Hello , this is class Employee ");
+	}
+
+	public static void main(String[] args) {
+		EmployeeV1 p = new EmployeeV1("Andy", 29);
+		p.sayHello();
+
+	}
+}
diff --git a/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java b/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java
new file mode 100644
index 0000000000..45638bd851
--- /dev/null
+++ b/group17/82427129/JavaUtil/src/main/java/com/coding/basic/LRU/LRUPageFrame.java
@@ -0,0 +1,147 @@
+package com.coding.basic.LRU;
+
+public class LRUPageFrame {
+	private int capacity;
+	private Node first;// 链表头
+	private Node last;// 链表尾
+	private int length = 0;
+
+	public LRUPageFrame(int capacity) {
+		this.capacity = capacity;
+	}
+
+	/**
+	 * 获取缓存中对象
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public void access(int pageNum) {
+		// this loop select for pageNum,grow it first when 'found'.
+		for (Node n = first; n != null; n = n.next) {
+			if (n.pageNum == pageNum) {
+				growFirst(n);
+				return;
+			}
+		}
+		// if didn't found it
+		if (ensureFull()) {
+			removeLast();
+		}
+		add(pageNum);
+	}
+
+	private void add(int pageNum) {
+		if (isEmpty()) {
+			Node newNode = new Node(null, null, pageNum);
+			first = newNode;
+			last = newNode;
+			length++;
+		} else {
+			addToFirst(pageNum);
+		}
+	}
+
+	private void addToFirst(int pageNum) {
+		Node newNode = new Node(null, null, pageNum);
+		newNode.next = first;
+		first.prev = newNode;
+		first = newNode;
+		length++;
+	}
+
+	/**
+	 * ensure the LRUPageFrame is full or Not
+	 * 
+	 * @return if full return true,else false
+	 */
+	private boolean ensureFull() {
+		if (length < capacity) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	/**
+	 * grow the Node'position to first
+	 * 
+	 * @param n
+	 */
+	private void growFirst(Node n) {
+		// if the node is already first ,return.
+		if (first.pageNum == n.pageNum) {
+			return;
+		}
+		remove(n);
+		addToFirst(n.pageNum);
+	}
+
+	private void remove(Node n) {
+		if (isEmpty()) {
+			return;
+		}
+		if (n.next == null) {
+			removeLast();
+			return;
+		}
+		if (n.prev == null) {
+			removeFirst();
+			return;
+		}
+		Node prev = n.prev;
+		Node next = n.next;
+		n.next = null;
+		n.prev = null;
+		prev.next = next;
+		next.prev = prev;
+		length--;
+	}
+
+	private void removeFirst() {
+		Node next = first.next;
+		first.next = null;
+		first = next;
+	}
+
+	private void removeLast() {
+		Node prev = last.prev;
+		prev.next = null;
+		last.prev = null;
+		last = prev;
+		length--;
+	}
+	/**
+	 * ensure the LRUPageFrame is empty or Not.
+	 * @return
+	 */
+	public boolean isEmpty() {
+		return length < 1;
+	}
+
+	public String toString() {
+		StringBuilder buffer = new StringBuilder();
+		Node node = first;
+		while (node != null) {
+			buffer.append(node.pageNum);
+
+			node = node.next;
+			if (node != null) {
+				buffer.append(",");
+			}
+		}
+		return buffer.toString();
+	}
+
+	private static class Node {
+		Node prev;
+		Node next;
+		int pageNum;
+
+		Node(Node prev, Node next, int pageNum) {
+			this.prev = prev;
+			this.next = next;
+			this.pageNum = pageNum;
+		}
+	}
+}
diff --git a/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java b/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java
new file mode 100644
index 0000000000..e2ed056cc3
--- /dev/null
+++ b/group17/82427129/JavaUtil/src/test/java/com/coderising/jvm/loader/ClassFileLoaderTest.java
@@ -0,0 +1,73 @@
+package com.coderising.jvm.loader;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClassFileLoaderTest {
+	static String path1 = "C:\\Users\\liuxin\\git\\coding2017\\liuxin\\mini-jvm\\bin";
+	static String path2 = "D:\\workProgram\\GitRepo\\coding2017\\group17\\82427129\\JavaUtil\\target\\classes";
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testClassFileLength() {		
+		
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path2);
+		
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		
+		byte[] byteCodes = loader.readBinaryCode(className);
+		
+		// 注意：这个字节数可能和你的JVM版本有关系， 你可以看看编译好的类到底有多大
+		Assert.assertEquals(1056, byteCodes.length);
+		
+	}
+
+	@Test
+	public void testGetClassPath() {
+		ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path1);
+		loader.addClassPath(path2);
+		
+		String clzPath = loader.getClassPath();
+		
+		Assert.assertEquals(path1+";"+path2,clzPath);
+	}
+	
+	@Test	
+	public void testMagicNumber(){
+    	ClassFileLoader loader = new ClassFileLoader();
+		loader.addClassPath(path2);
+		String className = "com.coderising.jvm.test.EmployeeV1";
+		byte[] byteCodes = loader.readBinaryCode(className);
+		byte[] codes = new byte[]{byteCodes[0],byteCodes[1],byteCodes[2],byteCodes[3]};
+		
+		
+		String acctualValue = this.byteToHexString(codes);
+		
+		Assert.assertEquals("cafebabe", acctualValue);
+	}
+
+	private String byteToHexString(byte[] codes) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < codes.length; i++) {
+			byte b = codes[i];
+			int value = b & 0xFF;
+			String strHex = Integer.toHexString(value);
+			if (strHex.length() < 2) {
+				strHex = "0" + strHex;
+			}
+			buffer.append(strHex);
+		}
+		return buffer.toString();
+	}
+
+}
diff --git a/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java b/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java
new file mode 100644
index 0000000000..e05d4b750e
--- /dev/null
+++ b/group17/82427129/JavaUtil/src/test/java/com/coding/basic/LRU/LRUPageFrameTest.java
@@ -0,0 +1,29 @@
+package com.coding.basic.LRU;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class LRUPageFrameTest {
+
+	@Test
+	public void testAccess() {
+		LRUPageFrame frame = new LRUPageFrame(3);
+		frame.access(7);
+		frame.access(0);
+		frame.access(1);
+		Assert.assertEquals("1,0,7", frame.toString());
+		frame.access(2);
+		Assert.assertEquals("2,1,0", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,2,1", frame.toString());
+		frame.access(3);
+		Assert.assertEquals("3,0,2", frame.toString());
+		frame.access(0);
+		Assert.assertEquals("0,3,2", frame.toString());
+		frame.access(4);
+		Assert.assertEquals("4,0,3", frame.toString());
+	}
+
+}
diff --git a/group17/article/20170326-20170402.md b/group17/article/20170326-20170402.md
new file mode 100644
index 0000000000..5df4ce08e6
--- /dev/null
+++ b/group17/article/20170326-20170402.md
@@ -0,0 +1,56 @@
+# 自由写作
+
+## 须知
+---
+
+交作业时请在QQ 号后面填上各自的文章链接, 比如:
+
+51075907 http://m.blog.csdn.net/article/details?id=57083764
+
+## 文章
+---
+
+1204187480 
+
+102228177  
+
+876385982 
+
+785396327
+
+1059107701
+
+240094626
+
+82427129 
+
+296910598
+
+1264835468 http://www.jianshu.com/p/848fd6be5247
+
+516886559
+
+1282579502 https://www.evernote.com/l/AZ2Rx5pxgf9I-JqkSpFANMwTK9fXR0KFV50
+
+614982500
+
+865797761
+
+1540186032  
+
+176653813
+
+116665530
+
+51075907 
+
+1158154002
+
+345450234
+
+919764878
+
+1368331120
+
+517970312
+
diff --git a/group17/article/20170402-20170409.md b/group17/article/20170402-20170409.md
new file mode 100644
index 0000000000..3d45ad0516
--- /dev/null
+++ b/group17/article/20170402-20170409.md
@@ -0,0 +1,56 @@
+# 自由写作
+
+## 须知
+---
+
+交作业时请在QQ 号后面填上各自的文章链接, 比如:
+
+51075907 http://m.blog.csdn.net/article/details?id=57083764
+
+## 文章
+---
+
+1204187480 
+
+102228177  
+
+876385982 
+
+785396327
+
+1059107701
+
+240094626
+
+82427129 
+
+296910598
+
+1264835468 
+
+516886559
+
+1282579502 
+
+614982500
+
+865797761
+
+1540186032  
+
+176653813
+
+116665530
+
+51075907 
+
+1158154002
+
+345450234
+
+919764878
+
+1368331120
+
+517970312
+
diff --git a/group17/article/template.md b/group17/article/template.md
index 09c7951d71..0b06ef733e 100644
--- a/group17/article/template.md
+++ b/group17/article/template.md
@@ -10,9 +10,9 @@
 ## 文章
 ---
 
-1204187480 http://blog.leanote.com/post/luoziyihao/js%E9%97%AD%E5%8C%85
+1204187480 
 
-102228177  
+102228177  http://note.youdao.com/noteshare?id=1f8f4a9d861e24948cdf0219a0d39f4e
 
 876385982 
 
@@ -26,11 +26,11 @@
 
 296910598
 
-1264835468 http://www.jianshu.com/p/634ca8cdd6e3
+1264835468 
 
 516886559
 
-1282579502 https://www.evernote.com/shard/s413/sh/142601dd-edc3-4e37-871e-37a7489d7634/a092bf080e1aefbaeab96d34edac8cf0
+1282579502 
 
 614982500
 
diff --git a/group17/count/homework.md b/group17/count/homework.md
index e474336779..640cf4698f 100644
--- a/group17/count/homework.md
+++ b/group17/count/homework.md
@@ -17,3 +17,7 @@
 
  * [20170305-20170312](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170305-20170312.md) 
 
+ * [20170326-20170402](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170326-20170402.md) 
+ * [20170402-20170409](https://github.com/luoziyihao/coding2017/blob/master/group17/article/20170402-20170409.md) 
+
+20170326-20170402.md 20170402-20170409.md
diff --git a/group17/count/reward.md b/group17/count/reward.md
new file mode 100644
index 0000000000..4a0fe7ea81
--- /dev/null
+++ b/group17/count/reward.md
@@ -0,0 +1,16 @@
+## 17组 201703 获奖
+
+### 代码坚持奖
+
+82427129
+1282579502
+102228177
+1264835468
+
+### 博客坚持奖
+
+82427129
+1282579502
+102228177
+1264835468
+
diff --git a/group23/565832157/src/com/coding/basic/LinkedList.java b/group23/565832157/src/com/coding/basic/LinkedList.java
index 09fe0a8ff3..7d037a6428 100644
--- a/group23/565832157/src/com/coding/basic/LinkedList.java
+++ b/group23/565832157/src/com/coding/basic/LinkedList.java
@@ -1,3 +1,145 @@
+<<<<<<< HEAD:liuxin/src/com/coding/basic/LinkedList.java
+package com.coding.basic;
+
+public class LinkedList implements List {
+	private int size;
+	
+	private Node head;
+	
+	public void add(Object o){
+		
+	}
+	public void add(int index , Object o){
+		
+	}
+	public Object get(int index){
+		return null;
+	}
+	public Object remove(int index){
+		return null;
+	}
+	
+	public int size(){
+		
+		return size;
+	}
+	
+	public void addFirst(Object o){
+		
+	}
+	public void addLast(Object o){
+		
+	}
+	public Object removeFirst(){
+		return null;
+	}
+	public Object removeLast(){
+		return null;
+	}
+	public Iterator iterator(){
+		return null;
+	}
+	
+	
+	private static  class Node{
+		Object data;
+		Node next;
+	}
+	
+	/**
+	 * 把该链表逆置
+	 * 			head   				 head
+	 * 例如链表为 3->7->10 , 逆置后变为  10->7->3
+	 */
+	public void reverse(){	
+		/**
+		 * 长度超过1的单链表需要逆转
+		 */
+		if(size>1){
+			Node pre = head;
+			Node cur = head.next;
+			Node next = null;
+			while(cur!=null){
+				next = cur.next;
+				cur.next = pre;
+				pre = cur;
+				cur = next;
+			}
+			
+		}
+	}
+	
+	
+	/**
+	 * 删除一个单链表的前半部分
+	 * 例如：list = 2->5->7->8 , 删除以后的值为 7->8
+	 * 如果list = 2->5->7->8->10 ,删除以后的值为7,8,10
+
+	 */
+	public void removeFirstHalf(){
+		
+	}
+	
+	/**
+	 * 从第i个元素开始,删除length个元素 ,注意i从0开始
+	 * @param i
+	 * @param length
+	 */
+	public  void remove(int i, int length){
+		
+	}
+	/**
+	 * 假定当前链表和listB均包含已升序排列的整数
+	 * 从当前链表中取出那些listB所指定的元素
+	 * 例如当前链表 = 11->101->201->301->401->501->601->701
+	 * listB = 1->3->4->6
+	 * 返回的结果应该是[101,301,401,601]  
+	 * @param list
+	 */
+	public  int[] getElements(LinkedList list){
+		return null;
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 从当前链表中中删除在listB中出现的元素 
+
+	 * @param list
+	 */
+	
+	public  void subtract(LinkedList list){
+		
+	}
+	
+	/**
+	 * 已知当前链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 删除表中所有值相同的多余元素（使得操作后的线性表中所有元素的值均不相同）
+	 */
+	public  void removeDuplicateValues(){
+		
+	}
+	
+	/**
+	 * 已知链表中的元素以值递增有序排列，并以单链表作存储结构。
+	 * 试写一高效的算法，删除表中所有值大于min且小于max的元素（若表中存在这样的元素）
+	 * @param min
+	 * @param max
+	 */
+	public void removeRange(int min, int max){
+		
+	}
+	
+	/**
+	 * 假设当前链表和参数list指定的链表均以元素依值递增有序排列（同一表中的元素值各不相同）
+	 * 现要求生成新链表C，其元素为当前链表和list中元素的交集，且表C中的元素有依值递增有序排列
+	 * @param list
+	 */
+	public LinkedList intersection(LinkedList list){
+		
+		return null;
+	}
+}
+=======
 package com.coding.basic;
 
 public class LinkedList implements List {
@@ -120,3 +262,4 @@ public  LinkedList intersection( LinkedList list){
 		return null;
 	}
 }
+>>>>>>> upstream/master:group23/565832157/src/com/coding/basic/LinkedList.java
diff --git a/group27/513274874/homework/.project b/group27/513274874/homework/.project
index b6d8ce6204..8a1c96cafa 100644
--- a/group27/513274874/homework/.project
+++ b/group27/513274874/homework/.project
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>coding2017</name>
+	<name>ThirdHomework</name>
 	<comment></comment>
 	<projects>
 	</projects>
diff --git a/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java b/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java
index eca4a105e6..04cf3e4fe7 100644
--- a/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java
+++ b/group27/513274874/homework/src/com/coding/coderising/download/DownloadThread.java
@@ -1,11 +1,15 @@
 package com.coding.coderising.download;
 
+
 import com.coding.coderising.download.api.Connection;
 
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
+
 public class DownloadThread extends Thread{
+	
+	
 
 	Connection conn;
 	int startPos;
@@ -17,14 +21,18 @@ public class DownloadThread extends Thread{
 	public DownloadThread( Connection conn, int startPos, int endPos){
 		
 		this.conn = conn;		
+
 		this.startPos = startPos;
 		this.endPos = endPos;
+		this.filePath = filePath;
 	}
+
 	public void run(){
 		try {
 			conn.read(startPos,endPos);
 		} catch (IOException e) {
 			e.printStackTrace();
+
 		}
 	}
 }
diff --git a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java
index dc99e91598..7a010983f8 100644
--- a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java
+++ b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloader.java
@@ -1,11 +1,13 @@
 package com.coding.coderising.download;
 
+
 import com.coding.coderising.download.api.Connection;
 import com.coding.coderising.download.api.ConnectionException;
 import com.coding.coderising.download.api.ConnectionManager;
 import com.coding.coderising.download.api.DownloadListener;
 
 
+
 public class FileDownloader {
 	
 	String url;
@@ -14,7 +16,10 @@ public class FileDownloader {
 	
 	ConnectionManager cm;
 	
-
+	private final static int thread_count = 3;
+	
+	private final static String BASE_PATH = "E:\\";
+	
 	public FileDownloader(String _url) {
 		this.url = _url;
 		
@@ -23,13 +28,18 @@ public FileDownloader(String _url) {
 	public void execute(){
 		// 在这里实现你的代码， 注意： 需要用多线程实现下载
 		// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
-		// (1) ConnectionManager , 可以打开一个连接，通过Connection可以读取其中的一段（用startPos, endPos来指定）
-		// (2) DownloadListener, 由于是多线程下载， 调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
-		//     线程都执行完以后， 调用listener的notifiedFinished方法， 这样客户端就能收到通知。
+		// (1) ConnectionManager , 可以打开一个连接，
+		//通过Connection可以读取其中的一段（用startPos, endPos来指定）
+		// (2) DownloadListener, 由于是多线程下载， 
+		//调用这个类的客户端不知道什么时候结束，所以你需要实现当所有
+		//     线程都执行完以后， 调用listener的notifiedFinished方法， 
+		//这样客户端就能收到通知。
 		// 具体的实现思路：
-		// 1. 需要调用ConnectionManager的open方法打开连接， 然后通过Connection.getContentLength方法获得文件的长度
+		// 1. 需要调用ConnectionManager的open方法打开连接，
+		//然后通过Connection.getContentLength方法获得文件的长度
 		// 2. 至少启动3个线程下载，  注意每个线程需要先调用ConnectionManager的open方法
-		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 返回值是byte[]数组
+		// 然后调用read方法， read方法中有读取文件的开始位置和结束位置的参数， 
+		//返回值是byte[]数组
 		// 3. 把byte数组写入到文件中
 		// 4. 所有的线程都下载完成以后， 需要调用listener的notifiedFinished方法
 		
@@ -41,10 +51,54 @@ public void execute(){
 			
 			int length = conn.getContentLength();	
 			
-			new DownloadThread(conn,0,length-1).start();
+			String targetPath = BASE_PATH + "targetfile." + url.substring(url.lastIndexOf(".") + 1);
+			
+			int startPos = 0;
+			
+			int endPos = 0;
+			
+			List<DownloadThread> list = new ArrayList<DownloadThread>();
+			
+			for(int i = 0; i < thread_count; i++){
+				
+				conn = cm.open(url);
+				
+				startPos = i * (length / thread_count);
+
+				endPos = (i == thread_count - 1) ? length - 1 : (i + 1) * (length / thread_count) - 1;
+				
+				DownloadThread thread = new DownloadThread(conn, startPos, endPos, targetPath);
+
+				list.add(thread);
+
+				thread.start();
+			}
+			
+			// 调用线程的join方法，保证所有的线程都结束后再发出结束通知
+
+			for (int i = 0; i < list.size(); i++) {
+	
+				try {
+	
+					list.get(i).join();
+	
+				} catch (InterruptedException e) {
+	
+					// TODO Auto-generated catch block
+	
+					e.printStackTrace();
+	
+				}
+	
+			}
+
+
+
+			listener.notifyFinished();
 			
 		} catch (ConnectionException e) {			
 			e.printStackTrace();
+			
 		}finally{
 			if(conn != null){
 				conn.close();
diff --git a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java
index 8a9531530f..60aa517b5b 100644
--- a/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java
+++ b/group27/513274874/homework/src/com/coding/coderising/download/FileDownloaderTest.java
@@ -21,7 +21,7 @@ public void tearDown() throws Exception {
 	@Test
 	public void testDownload() {
 		
-		String url = "http://localhost:8080/test.jpg";
+		String url = "C:/Users/苏磊/Desktop/R%T[DQRU~@$6TKZ7)TD81JW.png";
 		
 		FileDownloader downloader = new FileDownloader(url);
 
diff --git a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java
index e1f649b88b..a56ee74918 100644
--- a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java
+++ b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionImpl.java
@@ -1,7 +1,9 @@
 package com.coding.coderising.download.impl;
 
+
 import com.coding.coderising.download.api.Connection;
 
+
 import java.io.*;
 import java.net.URL;
 import java.net.URLConnection;
@@ -9,6 +11,7 @@
 public class ConnectionImpl implements Connection {
     private URL url;
 
+
     // 定义字节数组（取水的竹筒）的长度
     private final int BUFF_LEN = 32;
 
@@ -16,6 +19,7 @@ public class ConnectionImpl implements Connection {
     private InputStream is;
 
 
+
     ByteArrayOutputStream bos;
 
     @Override
diff --git a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java
index 2295167f6d..5250910126 100644
--- a/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java
+++ b/group27/513274874/homework/src/com/coding/coderising/download/impl/ConnectionManagerImpl.java
@@ -1,5 +1,6 @@
 package com.coding.coderising.download.impl;
 
+
 import com.coding.coderising.download.api.Connection;
 import com.coding.coderising.download.api.ConnectionException;
 import com.coding.coderising.download.api.ConnectionManager;
@@ -7,11 +8,13 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 
+
 public class ConnectionManagerImpl implements ConnectionManager {
 
 	@Override
 	public Connection open(String url) throws ConnectionException {
 
+
         Connection connection = null;
         try {
             if(url == null || "".equals(url.trim())) return null;
@@ -24,6 +27,7 @@ public Connection open(String url) throws ConnectionException {
             e.printStackTrace();
         }
         return connection;
+
 	}
 
 }
diff --git a/liuxin/.settings/org.eclipse.core.resources.prefs b/liuxin/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/liuxin/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java
index 434d991447..d4c496a2f9 100644
--- a/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java
+++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtil.java
@@ -1,23 +1,65 @@
 package com.coding.basic.stack;
-
+import java.util.Stack;
 public class StackUtil {
 	
+	public static void bad_reverse(Stack<Integer> s) {
+		if(s == null || s.isEmpty()){
+			return;
+		}
+		Stack<Integer> tmpStack = new Stack();
+		while(!s.isEmpty()){
+			tmpStack.push(s.pop());
+		}
+		
+		s = tmpStack;
+		
+	}
 	
 	/**
 	 * 假设栈中的元素是Integer, 从栈顶到栈底是 : 5,4,3,2,1 调用该方法后， 元素次序变为: 1,2,3,4,5
 	 * 注意：只能使用Stack的基本操作，即push,pop,peek,isEmpty， 可以使用另外一个栈来辅助
 	 */
-	public static void reverse(Stack s) {
-
+	public static void reverse(Stack<Integer> s) {
+		if(s == null || s.isEmpty()){
+			return;
+		}
+		Integer top = s.pop();
+		reverse(s);
+		addToBottom(s,top);
+		
+		
+	}
+	public static void addToBottom(Stack<Integer> s,  Integer value){
+		if(s.isEmpty()){
+			s.push(value);
+		} else{
+			Integer top = s.pop();
+			addToBottom(s,value);
+			s.push(top);
+		}
+		
 	}
-
 	/**
 	 * 删除栈中的某个元素 注意：只能使用Stack的基本操作，即push,pop,peek,isEmpty， 可以使用另外一个栈来辅助
 	 * 
 	 * @param o
 	 */
 	public static void remove(Stack s,Object o) {
-
+		if(s == null || s.isEmpty()){
+			return;
+		}
+		Stack tmpStack = new Stack();
+		
+		while(!s.isEmpty()){
+			Object value = s.pop();
+			if(!value.equals(o)){
+				tmpStack.push(value);
+			} 			
+		}
+		
+		while(!tmpStack.isEmpty()){
+			s.push(tmpStack.pop());
+		}
 	}
 
 	/**
@@ -27,7 +69,24 @@ public static void remove(Stack s,Object o) {
 	 * @return
 	 */
 	public static Object[] getTop(Stack s,int len) {
-		return null;
+		
+		if(s == null || s.isEmpty() || s.size()<len || len <=0 ){
+			return null;
+		}
+		
+		Stack tmpStack = new Stack();
+		int i = 0;
+		Object[] result = new Object[len];
+		while(!s.isEmpty()){
+			Object value = s.pop();			
+			tmpStack.push(value);
+			result[i++] = value;
+			if(i == len){
+				break;
+			}
+		}
+		
+		return result;
 	}
 	/**
 	 * 字符串s 可能包含这些字符：  ( ) [ ] { }, a,b,c... x,yz
@@ -38,7 +97,39 @@ public static Object[] getTop(Stack s,int len) {
 	 * @return
 	 */
 	public static boolean isValidPairs(String s){
-		return false;
+		
+		Stack<Character> stack = new Stack();
+		for(int i=0;i<s.length();i++){
+			char c = s.charAt(i);
+			
+			if(c == '(' || c =='[' || c == '{'){
+				
+				stack.push(c);
+				
+			} else if( c == ')'){
+				
+				char topChar = stack.pop();
+				if(topChar != '('){
+					return false;
+				}
+				
+			} else if( c == ']'){
+				
+				char topChar = stack.pop();
+				if(topChar != '['){
+					return false;
+				}
+					
+			} else if( c == '}'){
+				
+				char topChar = stack.pop();
+				if(topChar != '{'){
+					return false;
+				}
+				
+			}
+		}
+		return stack.size() == 0;
 	}
 	
 	
diff --git a/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java b/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java
new file mode 100644
index 0000000000..766c7eeb29
--- /dev/null
+++ b/liuxin/data-structure/src/com/coding/basic/stack/StackUtilTest.java
@@ -0,0 +1,78 @@
+package com.coding.basic.stack;
+
+import static org.junit.Assert.fail;
+
+import java.util.Stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+public class StackUtilTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testAddToBottom() {
+		Stack<Integer> s = new Stack();
+		s.push(1);
+		s.push(2);
+		s.push(3);
+		
+		StackUtil.addToBottom(s, 0);
+		
+		Assert.assertEquals("[0, 1, 2, 3]", s.toString());
+		
+	}
+	@Test
+	public void testReverse() {
+		Stack<Integer> s = new Stack();
+		s.push(1);
+		s.push(2);
+		s.push(3);
+		s.push(4);
+		s.push(5);
+		Assert.assertEquals("[1, 2, 3, 4, 5]", s.toString());
+		StackUtil.reverse(s);
+		Assert.assertEquals("[5, 4, 3, 2, 1]", s.toString());
+	}
+
+	@Test
+	public void testRemove() {
+		Stack<Integer> s = new Stack();
+		s.push(1);
+		s.push(2);
+		s.push(3);
+		StackUtil.remove(s, 2);
+		Assert.assertEquals("[1, 3]", s.toString());
+	}
+
+	@Test
+	public void testGetTop() {
+		Stack<Integer> s = new Stack();
+		s.push(1);
+		s.push(2);
+		s.push(3);
+		s.push(4);
+		s.push(5);
+		{
+			Object[] values = StackUtil.getTop(s, 3);
+			Assert.assertEquals(5, values[0]);
+			Assert.assertEquals(4, values[1]);
+			Assert.assertEquals(3, values[2]);
+		}
+	}
+
+	@Test
+	public void testIsValidPairs() {
+		Assert.assertTrue(StackUtil.isValidPairs("([e{d}f])"));
+		Assert.assertFalse(StackUtil.isValidPairs("([b{x]y})"));
+	}
+
+}
diff --git a/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java
new file mode 100644
index 0000000000..0a145ff047
--- /dev/null
+++ b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExpr.java
@@ -0,0 +1,18 @@
+package com.coding.basic.stack.expr;
+
+public class InfixExpr {
+	String expr = null;
+	
+	public InfixExpr(String expr) {
+		this.expr = expr;
+	}
+
+	public float evaluate() {		
+		
+		return 0.0f;
+	}
+	
+
+	
+	
+}
diff --git a/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java
new file mode 100644
index 0000000000..92d130cddd
--- /dev/null
+++ b/liuxin/data-structure/src/com/coding/basic/stack/expr/InfixExprTest.java
@@ -0,0 +1,48 @@
+package com.coding.basic.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class InfixExprTest {
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testEvaluate() {
+		//InfixExpr expr = new InfixExpr("300*20+12*5-20/4");
+		{
+			InfixExpr expr = new InfixExpr("2+3*4+5");
+			Assert.assertEquals(19.0, expr.evaluate(), 0.001f);
+		}
+		{
+			InfixExpr expr = new InfixExpr("3*20+12*5-40/2");
+			Assert.assertEquals(100.0, expr.evaluate(), 0.001f);
+		}
+		
+		{
+			InfixExpr expr = new InfixExpr("3*20/2");
+			Assert.assertEquals(30, expr.evaluate(), 0.001f);
+		}
+		
+		{
+			InfixExpr expr = new InfixExpr("20/2*3");
+			Assert.assertEquals(30, expr.evaluate(), 0.001f);
+		}
+		
+		{
+			InfixExpr expr = new InfixExpr("10-30+50");
+			Assert.assertEquals(30, expr.evaluate(), 0.001f);
+		}
+		
+	}
+
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java
new file mode 100644
index 0000000000..89fb53394e
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/AttributeInfo.java
@@ -0,0 +1,19 @@
+package com.coderising.jvm.attr;
+
+public abstract class AttributeInfo {
+	public static final String CODE = "Code";
+	public static final String CONST_VALUE = "ConstantValue";
+	public static final String EXCEPTIONS = "Exceptions";
+	public static final String LINE_NUM_TABLE = "LineNumberTable";
+	public static final String LOCAL_VAR_TABLE = "LocalVariableTable";
+	public static final String STACK_MAP_TABLE = "StackMapTable";
+	int attrNameIndex;				
+	int attrLen ;
+	public AttributeInfo(int attrNameIndex, int attrLen) {
+		
+		this.attrNameIndex = attrNameIndex;
+		this.attrLen = attrLen;
+	}
+	
+	
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java
new file mode 100644
index 0000000000..b0c67b4b93
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/CodeAttr.java
@@ -0,0 +1,56 @@
+package com.coderising.jvm.attr;
+
+import com.coderising.jvm.clz.ClassFile;
+import com.coderising.jvm.constant.ConstantPool;
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+
+public class CodeAttr extends AttributeInfo {
+	private int maxStack ;
+	private int maxLocals ;
+	private int codeLen ;
+	private String code;
+	public String getCode() {
+		return code;
+	}
+
+	//private ByteCodeCommand[] cmds ;
+	//public ByteCodeCommand[] getCmds() {
+	//	return cmds;
+	//}
+	private LineNumberTable lineNumTable;
+	private LocalVariableTable localVarTable;
+	private StackMapTable stackMapTable;
+	
+	public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,String code /*ByteCodeCommand[] cmds*/) {
+		super(attrNameIndex, attrLen);
+		this.maxStack = maxStack;
+		this.maxLocals = maxLocals;
+		this.codeLen = codeLen;
+		this.code = code;
+		//this.cmds = cmds;
+	}
+
+	public void setLineNumberTable(LineNumberTable t) {
+		this.lineNumTable = t;
+	}
+
+	public void setLocalVariableTable(LocalVariableTable t) {
+		this.localVarTable = t;		
+	}
+	
+	public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter){
+		
+		
+		return null;
+	}
+	private void setStackMapTable(StackMapTable t) {
+		this.stackMapTable = t;
+		
+	}
+
+	
+	
+	
+	
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java
new file mode 100644
index 0000000000..22941f83b1
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LineNumberTable.java
@@ -0,0 +1,42 @@
+package com.coderising.jvm.attr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+public class LineNumberTable extends AttributeInfo {
+	List<LineNumberItem> items = new ArrayList<LineNumberItem>();
+	
+	private static class LineNumberItem{
+		int startPC;
+		int lineNum;
+		public int getStartPC() {
+			return startPC;
+		}
+		public void setStartPC(int startPC) {
+			this.startPC = startPC;
+		}
+		public int getLineNum() {
+			return lineNum;
+		}
+		public void setLineNum(int lineNum) {
+			this.lineNum = lineNum;
+		}
+	}
+	public void addLineNumberItem(LineNumberItem item){
+		this.items.add(item);
+	}
+	public LineNumberTable(int attrNameIndex, int attrLen) {
+		super(attrNameIndex, attrLen);
+		
+	}
+	
+	public static LineNumberTable parse(ByteCodeIterator iter){
+		
+		return null;
+	}
+	
+	
+
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java
new file mode 100644
index 0000000000..3eb2654e36
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableItem.java
@@ -0,0 +1,39 @@
+package com.coderising.jvm.attr;
+
+public class LocalVariableItem {
+	private int startPC;
+	private int length;
+	private int nameIndex;
+	private int descIndex;
+	private int index;
+	public int getStartPC() {
+		return startPC;
+	}
+	public void setStartPC(int startPC) {
+		this.startPC = startPC;
+	}
+	public int getLength() {
+		return length;
+	}
+	public void setLength(int length) {
+		this.length = length;
+	}
+	public int getNameIndex() {
+		return nameIndex;
+	}
+	public void setNameIndex(int nameIndex) {
+		this.nameIndex = nameIndex;
+	}
+	public int getDescIndex() {
+		return descIndex;
+	}
+	public void setDescIndex(int descIndex) {
+		this.descIndex = descIndex;
+	}
+	public int getIndex() {
+		return index;
+	}
+	public void setIndex(int index) {
+		this.index = index;
+	}
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java
new file mode 100644
index 0000000000..fa69dc9bdb
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/LocalVariableTable.java
@@ -0,0 +1,28 @@
+package com.coderising.jvm.attr;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.coderising.jvm.constant.ConstantPool;
+
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+public class LocalVariableTable extends AttributeInfo{
+
+	List<LocalVariableItem> items = new ArrayList<LocalVariableItem>();
+	
+	public LocalVariableTable(int attrNameIndex, int attrLen) {
+		super(attrNameIndex, attrLen);		
+	}
+	
+	public static LocalVariableTable parse(ByteCodeIterator iter){
+		
+		return null;
+	}
+	private void addLocalVariableItem(LocalVariableItem item) {
+		this.items.add(item);		
+	}
+	
+	
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java b/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java
new file mode 100644
index 0000000000..44c5d90d46
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/attr/StackMapTable.java
@@ -0,0 +1,30 @@
+package com.coderising.jvm.attr;
+
+
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+public class StackMapTable extends AttributeInfo{
+	
+	private String originalCode;
+
+	public StackMapTable(int attrNameIndex, int attrLen) {
+		super(attrNameIndex, attrLen);		
+	}
+
+	public static StackMapTable parse(ByteCodeIterator iter){
+		int index = iter.nextU2ToInt();
+		int len = iter.nextU4ToInt();
+		StackMapTable t = new StackMapTable(index,len);
+		
+		//后面的StackMapTable太过复杂， 不再处理， 只把原始的代码读进来保存
+		String code = iter.nextUxToHexString(len);
+		t.setOriginalCode(code);
+		
+		return t;
+	}
+
+	private void setOriginalCode(String code) {
+		this.originalCode = code;
+		
+	}
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java
index 650ca8375d..c21a0988e5 100644
--- a/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/clz/ClassFile.java
@@ -1,75 +1,92 @@
-package com.coderising.jvm.clz;
-
-import com.coderising.jvm.constant.ClassInfo;
-import com.coderising.jvm.constant.ConstantPool;
-
-public class ClassFile {
-	
-	private int minorVersion;
-	private int majorVersion;
-	
-	private AccessFlag accessFlag;
-	private ClassIndex clzIndex;
-	private ConstantPool pool;
-	
-	
-	public ClassIndex getClzIndex() {
-		return clzIndex;
-	}
-	public AccessFlag getAccessFlag() {
-		return accessFlag;
-	}
-	public void setAccessFlag(AccessFlag accessFlag) {
-		this.accessFlag = accessFlag;
-	}
-	
-	
-	
-	public ConstantPool getConstantPool() {		
-		return pool;
-	}
-	public int getMinorVersion() {
-		return minorVersion;
-	}
-	public void setMinorVersion(int minorVersion) {
-		this.minorVersion = minorVersion;
-	}
-	public int getMajorVersion() {
-		return majorVersion;
-	}
-	public void setMajorVersion(int majorVersion) {
-		this.majorVersion = majorVersion;
-	}
-	public void setConstPool(ConstantPool pool) {
-		this.pool = pool;
-		
-	}
-	public void setClassIndex(ClassIndex clzIndex) {
-		this.clzIndex = clzIndex;		
-	}
-	
-	
-	
-	
-	public void print(){
-		
-		if(this.accessFlag.isPublicClass()){
-			System.out.println("Access flag : public  ");
-		}
-		System.out.println("Class Name:"+ getClassName());
-		
-		System.out.println("Super Class Name:"+ getSuperClassName());
-		
-		
-	}
-	
-	private String getClassName(){
-		int thisClassIndex = this.clzIndex.getThisClassIndex();
-		ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex);
-		return thisClass.getClassName();
-	}
-	private String getSuperClassName(){
-		ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex());
-		return superClass.getClassName();
-	}
-}
+package com.coderising.jvm.clz;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.coderising.jvm.constant.ClassInfo;
+import com.coderising.jvm.constant.ConstantPool;
+import com.coderising.jvm.field.Field;
+import com.coderising.jvm.method.Method;
+
+public class ClassFile {
+	
+	private int minorVersion;
+	private int majorVersion;
+	
+	private AccessFlag accessFlag;
+	private ClassIndex clzIndex;
+	private ConstantPool pool;
+	private List<Field> fields = new ArrayList<Field>();
+	private List<Method> methods = new ArrayList<Method>();
+	
+	public ClassIndex getClzIndex() {
+		return clzIndex;
+	}
+	public AccessFlag getAccessFlag() {
+		return accessFlag;
+	}
+	public void setAccessFlag(AccessFlag accessFlag) {
+		this.accessFlag = accessFlag;
+	}
+	
+	
+	
+	public ConstantPool getConstantPool() {		
+		return pool;
+	}
+	public int getMinorVersion() {
+		return minorVersion;
+	}
+	public void setMinorVersion(int minorVersion) {
+		this.minorVersion = minorVersion;
+	}
+	public int getMajorVersion() {
+		return majorVersion;
+	}
+	public void setMajorVersion(int majorVersion) {
+		this.majorVersion = majorVersion;
+	}
+	public void setConstPool(ConstantPool pool) {
+		this.pool = pool;
+		
+	}
+	public void setClassIndex(ClassIndex clzIndex) {
+		this.clzIndex = clzIndex;		
+	}
+	
+	public void addField(Field f){
+		this.fields.add(f);
+	}
+	public List<Field> getFields(){
+		return this.fields;
+	}
+	public void addMethod(Method m){
+		this.methods.add(m);
+	}
+	public List<Method> getMethods() {
+		return methods;
+	}
+	
+	
+	public void print(){
+		
+		if(this.accessFlag.isPublicClass()){
+			System.out.println("Access flag : public  ");
+		}
+		System.out.println("Class Name:"+ getClassName());
+		
+		System.out.println("Super Class Name:"+ getSuperClassName());
+		
+		
+	}
+	
+	private String getClassName(){
+		int thisClassIndex = this.clzIndex.getThisClassIndex();
+		ClassInfo thisClass = (ClassInfo)this.getConstantPool().getConstantInfo(thisClassIndex);
+		return thisClass.getClassName();
+	}
+	private String getSuperClassName(){
+		ClassInfo superClass = (ClassInfo)this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex());
+		return superClass.getClassName();
+	}
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java b/liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java
new file mode 100644
index 0000000000..09bae5a1ae
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/field/Field.java
@@ -0,0 +1,33 @@
+package com.coderising.jvm.field;
+
+import com.coderising.jvm.constant.ConstantPool;
+import com.coderising.jvm.constant.UTF8Info;
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+
+public class Field {
+	private int accessFlag;
+	private int nameIndex;
+	private int descriptorIndex;
+	
+	
+	
+	private ConstantPool pool;
+	
+	public Field( int accessFlag, int nameIndex, int descriptorIndex,ConstantPool pool) {
+		
+		this.accessFlag = accessFlag;
+		this.nameIndex = nameIndex;
+		this.descriptorIndex = descriptorIndex;
+		this.pool = pool;
+	}
+
+	
+	
+	
+	public static Field parse(ConstantPool pool,ByteCodeIterator iter){
+		
+		return null;
+	}
+
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java
index 9c9fac2839..5c5173fbe8 100644
--- a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ByteCodeIterator.java
@@ -1,5 +1,57 @@
-package com.coderising.jvm.loader;
-
-public class ByteCodeIterator {
-
-}
+package com.coderising.jvm.loader;
+
+import java.util.Arrays;
+
+import com.coderising.jvm.util.Util;
+
+public  class ByteCodeIterator {
+	byte[] codes;
+	int pos = 0;
+
+	ByteCodeIterator(byte[] codes) {
+		this.codes = codes;
+	}
+
+	
+
+	public byte[] getBytes(int len) {
+		if (pos + len >= codes.length) {
+			throw new ArrayIndexOutOfBoundsException();
+		}
+
+		byte[] data = Arrays.copyOfRange(codes, pos, pos + len);
+		pos += len;
+		return data;
+	}
+
+	public int nextU1toInt() {
+
+		return Util.byteToInt(new byte[] { codes[pos++] });
+	}
+
+	public int nextU2ToInt() {
+		return Util.byteToInt(new byte[] { codes[pos++], codes[pos++] });
+	}
+
+	public int nextU4ToInt() {
+		return Util.byteToInt(new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] });
+	}
+
+	public String nextU4ToHexString() {
+		return Util.byteToHexString((new byte[] { codes[pos++], codes[pos++], codes[pos++], codes[pos++] }));
+	}
+
+	public String nextUxToHexString(int len) {
+		byte[] tmp = new byte[len];
+
+		for (int i = 0; i < len; i++) {
+			tmp[i] = codes[pos++];
+		}
+		return Util.byteToHexString(tmp).toLowerCase();
+
+	}
+
+	public void back(int n) {
+		this.pos -= n;
+	}
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java
index 8e29f14a0c..444ec4c60d 100644
--- a/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/loader/ClassFileParser.java
@@ -1,44 +1,151 @@
-package com.coderising.jvm.loader;
-
-import java.io.UnsupportedEncodingException;
-
-import com.coderising.jvm.clz.AccessFlag;
-import com.coderising.jvm.clz.ClassFile;
-import com.coderising.jvm.clz.ClassIndex;
-import com.coderising.jvm.constant.ClassInfo;
-import com.coderising.jvm.constant.ConstantPool;
-import com.coderising.jvm.constant.FieldRefInfo;
-import com.coderising.jvm.constant.MethodRefInfo;
-import com.coderising.jvm.constant.NameAndTypeInfo;
-import com.coderising.jvm.constant.NullConstantInfo;
-import com.coderising.jvm.constant.StringInfo;
-import com.coderising.jvm.constant.UTF8Info;
-
-public class ClassFileParser {
-
-	public ClassFile parse(byte[] codes) {
-
-		
-		
-
-		return null;
-	}
-
-	private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
-
-		return null;
-	}
-
-	private ClassIndex parseClassInfex(ByteCodeIterator iter) {
-
-		return null;
-
-	}
-
-	private ConstantPool parseConstantPool(ByteCodeIterator iter) {
-
-		return null;
-	}
-
-	
-}
+package com.coderising.jvm.loader;
+
+import java.io.UnsupportedEncodingException;
+
+import com.coderising.jvm.clz.AccessFlag;
+import com.coderising.jvm.clz.ClassFile;
+import com.coderising.jvm.clz.ClassIndex;
+import com.coderising.jvm.constant.ClassInfo;
+import com.coderising.jvm.constant.ConstantPool;
+import com.coderising.jvm.constant.FieldRefInfo;
+import com.coderising.jvm.constant.MethodRefInfo;
+import com.coderising.jvm.constant.NameAndTypeInfo;
+import com.coderising.jvm.constant.NullConstantInfo;
+import com.coderising.jvm.constant.StringInfo;
+import com.coderising.jvm.constant.UTF8Info;
+import com.coderising.jvm.field.Field;
+import com.coderising.jvm.method.Method;
+
+public class ClassFileParser {
+
+	public ClassFile parse(byte[] codes) {
+
+		
+		ClassFile clzFile = new ClassFile();
+
+		ByteCodeIterator iter = new ByteCodeIterator(codes);
+
+		String magicNumber = iter.nextU4ToHexString();
+
+		if (!"cafebabe".equals(magicNumber)) {
+			return null;
+		}
+
+		clzFile.setMinorVersion(iter.nextU2ToInt());
+		clzFile.setMajorVersion(iter.nextU2ToInt());
+
+		ConstantPool pool = parseConstantPool(iter);
+		clzFile.setConstPool(pool);
+
+		AccessFlag flag = parseAccessFlag(iter);
+		clzFile.setAccessFlag(flag);
+
+		ClassIndex clzIndex = parseClassInfex(iter);
+		clzFile.setClassIndex(clzIndex);
+
+		parseInterfaces(iter);
+
+		
+		return clzFile;
+	}
+
+	private AccessFlag parseAccessFlag(ByteCodeIterator iter) {
+
+		AccessFlag flag = new AccessFlag(iter.nextU2ToInt());
+		// System.out.println("Is public class: " + flag.isPublicClass());
+		// System.out.println("Is final class : " + flag.isFinalClass());
+
+		return flag;
+	}
+
+	private ClassIndex parseClassInfex(ByteCodeIterator iter) {
+
+		int thisClassIndex = iter.nextU2ToInt();
+		int superClassIndex = iter.nextU2ToInt();
+
+		ClassIndex clzIndex = new ClassIndex();
+
+		clzIndex.setThisClassIndex(thisClassIndex);
+		clzIndex.setSuperClassIndex(superClassIndex);
+
+		return clzIndex;
+
+	}
+
+	private ConstantPool parseConstantPool(ByteCodeIterator iter) {
+
+		int constPoolCount = iter.nextU2ToInt();
+
+		System.out.println("Constant Pool Count :" + constPoolCount);
+
+		ConstantPool pool = new ConstantPool();
+		
+		pool.addConstantInfo(new NullConstantInfo());
+		
+		for (int i = 1; i <= constPoolCount - 1; i++) {
+
+			int tag = iter.nextU1toInt();
+			
+			if (tag == 7) {
+				// Class Info
+				int utf8Index = iter.nextU2ToInt();
+				ClassInfo clzInfo = new ClassInfo(pool);
+				clzInfo.setUtf8Index(utf8Index);
+
+				pool.addConstantInfo(clzInfo);
+			} else if (tag == 1) {
+				// UTF-8 String
+				int len = iter.nextU2ToInt();
+				byte[] data = iter.getBytes(len);
+				String value = null;
+				try {
+					value = new String(data, "UTF-8");
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+				}
+
+				UTF8Info utf8Str = new UTF8Info(pool);
+				utf8Str.setLength(len);
+				utf8Str.setValue(value);
+				pool.addConstantInfo(utf8Str);
+			}else if (tag == 8) {
+				StringInfo info = new StringInfo(pool);
+				info.setIndex(iter.nextU2ToInt());
+				pool.addConstantInfo(info);
+			} else if (tag == 9) {
+				FieldRefInfo field = new FieldRefInfo(pool);
+				field.setClassInfoIndex(iter.nextU2ToInt());
+				field.setNameAndTypeIndex(iter.nextU2ToInt());
+				pool.addConstantInfo(field);
+			} else if (tag == 10) {
+				// MethodRef
+				MethodRefInfo method = new MethodRefInfo(pool);
+				method.setClassInfoIndex(iter.nextU2ToInt());
+				method.setNameAndTypeIndex(iter.nextU2ToInt());
+				pool.addConstantInfo(method);
+			} else if (tag == 12) {
+				// Name and Type Info
+				NameAndTypeInfo nameType = new NameAndTypeInfo(pool);
+				nameType.setIndex1(iter.nextU2ToInt());
+				nameType.setIndex2(iter.nextU2ToInt());
+				pool.addConstantInfo(nameType);
+			} else {
+				throw new RuntimeException("the constant pool tag " + tag + " has not been implemented yet.");
+			}
+		}
+
+		System.out.println("Finished reading Constant pool ");
+
+		return pool;
+	}
+	private void parseInterfaces(ByteCodeIterator iter) {
+		int interfaceCount = iter.nextU2ToInt();
+
+		System.out.println("interfaceCount:" + interfaceCount);
+
+		// TODO : 如果实现了interface, 这里需要解析
+	}
+
+	
+	
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java b/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java
new file mode 100644
index 0000000000..ba5f7848d1
--- /dev/null
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/method/Method.java
@@ -0,0 +1,57 @@
+package com.coderising.jvm.method;
+
+import com.coderising.jvm.clz.ClassFile;
+import com.coderising.jvm.attr.AttributeInfo;
+import com.coderising.jvm.attr.CodeAttr;
+import com.coderising.jvm.constant.ConstantPool;
+import com.coderising.jvm.constant.UTF8Info;
+import com.coderising.jvm.loader.ByteCodeIterator;
+
+
+
+public class Method {
+	
+	private int accessFlag;
+	private int nameIndex;
+	private int descriptorIndex;
+	
+	private CodeAttr codeAttr;
+	
+	private ClassFile clzFile;
+	
+	
+	public ClassFile getClzFile() {
+		return clzFile;
+	}
+
+	public int getNameIndex() {
+		return nameIndex;
+	}
+	public int getDescriptorIndex() {
+		return descriptorIndex;
+	}
+	
+	public CodeAttr getCodeAttr() {
+		return codeAttr;
+	}
+
+	public void setCodeAttr(CodeAttr code) {
+		this.codeAttr = code;
+	}
+
+	public Method(ClassFile clzFile,int accessFlag, int nameIndex, int descriptorIndex) {
+		this.clzFile = clzFile;
+		this.accessFlag = accessFlag;
+		this.nameIndex = nameIndex;
+		this.descriptorIndex = descriptorIndex;
+	}
+
+	
+	
+	
+	
+	public static Method parse(ClassFile clzFile, ByteCodeIterator iter){
+		return null;
+		
+	}
+}
diff --git a/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java b/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
index 4ac0698801..c29ff5181f 100644
--- a/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
+++ b/liuxin/mini-jvm/src/com/coderising/jvm/test/ClassFileloaderTest.java
@@ -1,5 +1,7 @@
 package com.coderising.jvm.test;
 
+import java.util.List;
+
 import org.junit.After;
 import  org.junit.Assert;
 import org.junit.Before;
@@ -12,7 +14,9 @@
 import com.coderising.jvm.constant.MethodRefInfo;
 import com.coderising.jvm.constant.NameAndTypeInfo;
 import com.coderising.jvm.constant.UTF8Info;
+import com.coderising.jvm.field.Field;
 import com.coderising.jvm.loader.ClassFileLoader;
+import com.coderising.jvm.method.Method;
 
 
 
@@ -196,7 +200,78 @@ public void testClassIndex(){
     	Assert.assertEquals(FULL_QUALIFIED_CLASS_NAME, thisClassInfo.getClassName());
     	Assert.assertEquals("java/lang/Object", superClassInfo.getClassName());
     }
+
+    /**
+     * 下面是第三次JVM课应实现的测试用例
+     */
+    @Test
+    public void testReadFields(){
+   
+    	List<Field> fields = clzFile.getFields();
+    	Assert.assertEquals(2, fields.size());
+    	{
+    		Field f = fields.get(0);
+    		Assert.assertEquals("name:Ljava/lang/String;", f.toString());
+    	}
+    	{
+    		Field f = fields.get(1);
+    		Assert.assertEquals("age:I", f.toString());
+    	}
+    }
+    @Test
+    public void testMethods(){
+   
+    	List<Method> methods = clzFile.getMethods();
+    	ConstantPool pool = clzFile.getConstantPool();
+    	
+    	{
+    		Method m = methods.get(0);    		
+    		assertMethodEquals(pool,m,
+    				"<init>",
+    				"(Ljava/lang/String;I)V",
+    				"2ab7000c2a2bb5000f2a1cb50011b1");
+    		
+    	}
+    	{
+    		Method m = methods.get(1);    
+    		assertMethodEquals(pool,m,
+    				"setName",
+    				"(Ljava/lang/String;)V",
+    				"2a2bb5000fb1");
+    		
+    	}
+    	{
+    		Method m = methods.get(2);    
+    		assertMethodEquals(pool,m,
+    				"setAge",
+    				"(I)V",
+    				"2a1bb50011b1");
+    	}
+    	{
+    		Method m = methods.get(3); 
+    		assertMethodEquals(pool,m,
+    				"sayHello",
+    				"()V",
+    				"b2001c1222b60024b1");
+    		
+    	}
+    	{
+    		Method m = methods.get(4);    
+    		assertMethodEquals(pool,m,
+    				"main",
+    				"([Ljava/lang/String;)V",
+    				"bb000159122b101db7002d4c2bb6002fb1");
+    	}
+    }
     
+    private void assertMethodEquals(ConstantPool pool,Method m , String expectedName, String expectedDesc,String expectedCode){
+    	String methodName = pool.getUTF8String(m.getNameIndex());
+		String methodDesc = pool.getUTF8String(m.getDescriptorIndex());    		
+		String code = m.getCodeAttr().getCode();
+		Assert.assertEquals(expectedName, methodName);
+		Assert.assertEquals(expectedDesc, methodDesc);
+		Assert.assertEquals(expectedCode, code);
+    }
    
 
 }
