diff --git a/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtil.java b/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtil.java
new file mode 100644
index 000000000..a221c781b
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtil.java
@@ -0,0 +1,296 @@
+package com.github.lqingchenl.coding2017.array;
+
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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 length = origin.length;
+
+        int[] b = new int[length];
+        for (int i = 0; i < length; i++) {
+            b[i] = origin[i];
+        }
+        for (int i = 0; i < length; i++) {
+            origin[length - i - 1] = b[i];
+        }
+    }
+
+    /**
+     * 现在有如下的一个数组：   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) {
+        if (oldArray == null) {
+            return null;
+        }
+        int length = oldArray.length;
+        for (int i : oldArray) {
+            if (i == 0) {
+                length--;
+            }
+        }
+
+        int[] newArray = new int[length];
+        int j = 0;
+        for (int i : oldArray) {
+            if (i != 0) {
+                newArray[j] = i;
+                j++;
+            }
+        }
+        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 int[] merge(int[] array1, int[] array2) {
+        if (array1 == null || array1.length == 0) {
+            return array2;
+        }
+        if (array2 == null || array2.length == 0) {
+            return array1;
+        }
+
+        Map<Integer, Integer> map = new HashMap<>();
+
+
+        int sameNum = 0;
+        for (int i : array1) {
+            for (int j : array2) {
+                if (i == j) {
+                    sameNum++;
+                    map.put(i, 1);
+                }
+            }
+        }
+
+        int length = array1.length + array2.length - sameNum;
+        int[] newArray = new int[length];
+        int index = 0;
+
+        for (int i : array1) {
+            newArray[index] = i;
+            index++;
+        }
+        for (int j : array2) {
+            if (map.get(j) == null) {
+                newArray[index] = j;
+                index++;
+            }
+        }
+
+        for (int i = 0; i < newArray.length - 1; i++) {
+            for (int j = i + 1; j < newArray.length; j++) {
+                if (newArray[i] > newArray[j]) {
+                    int temp = newArray[j];
+                    newArray[j] = newArray[i];
+                    newArray[i] = temp;
+                }
+            }
+        }
+
+        return newArray;
+    }
+
+    /**
+     * 把一个已经存满数据的数组 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) throws Exception {
+
+        if (oldArray == null) {
+            return null;
+        }
+        if (size < 0) {
+            throw new Exception("12");
+        }
+
+        int newLength = oldArray.length + size;
+        int[] newArray = new int[newLength];
+        for (int i = 0; i < newLength; i++) {
+            if (i < oldArray.length) {
+                newArray[i] = oldArray[i];
+            } else {
+                newArray[i] = 0;
+            }
+
+        }
+        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 int[] fibonacci(int max) {
+        if (max == 1) {
+            return new int[0];
+        }
+
+        int index = 0;
+        for (int i = 0; i < Integer.MAX_VALUE; i++) {
+            if (getFibonacci(i) > max) {
+                index = i;
+                break;
+            }
+        }
+        int[] array = new int[index];
+        for (int i = 0; i < index; i++) {
+            array[i] = getFibonacci(i);
+        }
+        return array;
+    }
+
+    /**
+     * 返回小于给定最大值max的所有素数数组
+     * 例如max = 23, 返回的数组为[2,3,5,7,11,13,17,19]
+     *
+     * @param max
+     * @return
+     */
+    public int[] getPrimes(int max) {
+        if (max == 1) {
+            return new int[0];
+        }
+
+        int length = 0;
+        for (int i = 1; i <= max; i++) {
+            if (isPrime(i)) {
+                length++;
+            }
+        }
+        int[] array = new int[length];
+        int j = 0;
+        for (int i = 1; i <= max; i++) {
+            if (isPrime(i)) {
+                array[j] = i;
+                j++;
+            }
+        }
+
+        return array;
+    }
+
+    /**
+     * 所谓“完数”， 是指这个数恰好等于它的因子之和，例如6=1+2+3
+     * 给定一个最大值max， 返回一个数组， 数组中是小于max 的所有完数
+     *
+     * @param max
+     * @return
+     */
+    public int[] getPerfectNumbers(int max) {
+        StringBuffer stringBuffer = new StringBuffer();
+        for (int i = 1; i <= max; i++) {
+            int temp = 0;
+            for (int n = 1; n < i / 2 + 1; n++) {
+                if (i % n == 0) {
+                    temp += n;
+                }
+            }
+            if (temp == i) {
+                stringBuffer.append(i).append("-");
+            }
+        }
+        String[] strArray = stringBuffer.toString().split("-");
+        int length = stringBuffer.toString().split("-").length;
+        int[] intAarray = new int[length];
+        for (int i=0; i<length; i++){
+            intAarray[i] = Integer.parseInt(strArray[i]);
+        }
+        return intAarray;
+    }
+
+    /**
+     * 用seperator 把数组 array给连接起来
+     * 例如array= [3,8,9], seperator = "-"
+     * 则返回值为"3-8-9"
+     *
+     * @param array
+     * @param seperator
+     * @return
+     */
+    public String join(int[] array, String seperator) {
+        if (array==null || array.length==0){
+            return "";
+        }
+
+        StringBuffer stringBuffer = new StringBuffer();
+        for (int i = 0; i<array.length; i++){
+            stringBuffer.append(array[i]);
+            if (i != array.length-1){
+                stringBuffer.append(seperator);
+            }
+        }
+        return stringBuffer.toString();
+    }
+
+
+    /**
+     * 获取斐波那契数列
+     *
+     * @param i
+     * @return
+     */
+    private int getFibonacci(int i) {
+        if (i == 0 || i == 1) {
+            return 1;
+        }
+        return getFibonacci(i - 2) + getFibonacci(i - 1);
+    }
+
+    /**
+     * 判断是否为素数
+     *
+     * @param a
+     * @return
+     */
+    private boolean isPrime(int a) {
+        boolean flag = true;
+        if (a < 2) {// 素数不小于2
+            return false;
+        } else {
+            for (int i = 2; i <= Math.sqrt(a); i++) {
+                if (a % i == 0) {// 若能被整除，则说明不是素数，返回false
+                    flag = false;
+                    break;// 跳出循环
+                }
+            }
+        }
+        return flag;
+    }
+
+}
diff --git a/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtilTest.java b/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtilTest.java
new file mode 100644
index 000000000..ede47a318
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/array/ArrayUtilTest.java
@@ -0,0 +1,142 @@
+package com.github.lqingchenl.coding2017.array;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.*;
+
+public class ArrayUtilTest {
+    private ArrayUtil myArray;
+
+    @Before
+    public void before() throws Exception {
+        myArray = new ArrayUtil();
+    }
+
+    @Test
+    public void testReverseArray() {
+        int[] a = {1, 2, 1, 3, 5, 6};
+        int[] b = {6, 5, 3, 1, 2, 1};
+
+        myArray.reverseArray(a);
+        assertArrayEquals(a, b);
+
+        int[] c = new int[0];
+        myArray.reverseArray(c);
+        assertArrayEquals(c, new int[0]);
+
+    }
+
+    @Test
+    public void testRemoveZero() {
+        int[] oldArr = {1, 3, 4, 5, 0, 0, 6, 6, 0, 5, 4, 7, 6, 7, 1, 2, 0, 5};
+        int b[] = {1, 3, 4, 5, 6, 6, 5, 4, 7, 6, 7, 1, 2, 5};
+        int[] c = myArray.removeZero(oldArr);
+        assertArrayEquals(b, c);
+
+        int[] d = null;
+        int[] e = myArray.removeZero(d);
+        assertNull(e);
+
+    }
+
+    @Test
+    public void testMerge() {
+        int a1[] = {1, 2, 5, 7, 8};
+        int b1[] = {1, 2, 3, 4, 6};
+        int c1[] = {1, 2, 3, 4, 5, 6, 7, 8};
+        int[] newArray1 = myArray.merge(a1, b1);
+        assertArrayEquals(c1, newArray1);
+
+        int a2[] = new int[0];
+        int b2[] = {0, 2, 3, 6, 7, 8};
+        int c2[] = {0, 2, 3, 6, 7, 8};
+        int[] newArray2 = myArray.merge(a2, b2);
+        assertArrayEquals(c2, newArray2);
+
+        int a3[] = {0, 2, 3, 6, 7, 8};
+        int b3[] = new int[0];
+        int c3[] = {0, 2, 3, 6, 7, 8};
+        int[] newArray3 = myArray.merge(a3, b3);
+        assertArrayEquals(c3, newArray3);
+
+        int[] a4 = null;
+        int[] b4 = null;
+        int[] newArray4 = myArray.merge(a4, b4);
+        assertNull(newArray4);
+    }
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void testGrow() throws Exception{
+        int[] a = {3, 5, 7, 8, 9};
+        int[] b = {3, 5, 7, 8, 9, 0, 0, 0};
+        int[] newArray = myArray.grow(a, 3);
+        assertArrayEquals(b, newArray);
+
+        int[] c = null;
+        int[] newArray1 = myArray.grow(c, 3);
+        assertNull(newArray1);
+
+        // size < 0 抛出异常
+        expectedEx.expect(Exception.class);
+        myArray.grow(a, -3);
+    }
+
+    @Test
+    public void testFibonacci() {
+        //max == 1时返回空数组
+        int[] array1 = myArray.fibonacci(1);
+        int[] b = new int[0];
+        assertArrayEquals(array1, b);
+
+
+        int[] array2 = myArray.fibonacci(35);
+        int[] c = {1, 1, 2, 3, 5, 8, 13, 21, 34};
+        assertArrayEquals(c, array2);
+    }
+
+    @Test
+    public void testGetPrimes() {
+        int[] a = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
+        int[] array1 = myArray.getPrimes(35);
+        assertArrayEquals(a, array1);
+
+        //max <= 2的时候没有素数，数组为空数组
+        int[] array2 = myArray.getPrimes(1);
+        int[] b = new int[0];
+        assertArrayEquals(array2, b);
+    }
+
+    @Test
+    public void testGetPerfectNumbers() {
+        int[] array = myArray.getPerfectNumbers(10000);
+        int[] a = {6, 28, 496, 8128};
+        assertArrayEquals(a, array);
+    }
+
+    @Test
+    public void testJoin() {
+        int[] Array0 = {3, 5, 7, 8, 9};
+        String s0 = myArray.join(Array0, "-");
+        String s1 = "3-5-7-8-9";
+        assertEquals(s1, s0);
+
+        int[] Array1 = {3};
+        String s2 = myArray.join(Array1, "-");
+        String s3 = "3";
+        assertEquals(s2, s3);
+//
+//        //传递空数组时，返回空字符串
+        int[] Array2 = new int[0];
+        String s4 = myArray.join(Array2, "-");
+        String s5 = "";
+        assertEquals(s4, s5);
+    }
+
+}
diff --git a/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/LoginAction.java b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/LoginAction.java
new file mode 100644
index 000000000..efcb58f72
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/LoginAction.java
@@ -0,0 +1,44 @@
+package com.github.lqingchenl.coding2017.litestruts;
+
+/**
+ * 这是一个用来展示登录的业务类， 其中的用户名和密码都是硬编码的。
+ *
+ */
+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;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}
diff --git a/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/Struts.java b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/Struts.java
new file mode 100644
index 000000000..e8c6d54b6
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/Struts.java
@@ -0,0 +1,74 @@
+package com.github.lqingchenl.coding2017.litestruts;
+
+import org.jsoup.Jsoup;
+import org.jsoup.helper.StringUtil;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.beans.PropertyDescriptor;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class Struts {
+
+    public static View runAction(String actionName, Map<String, String> parameters) {
+
+        try {
+            Document d = Jsoup.parse(new File("src/com/github/lqingchenl/coding2017/litestruts/struts.xml"), "UTF-8"); //读取配置文件
+            String classStr = null;
+
+            Map<String, String> resultMap = new HashMap<>();
+            for (Element element : d.select("action")) {
+                if (element.attr("name").equals(actionName)) {
+                    classStr = element.attr("class");
+                    for (Element element1 : element.select("result")) {
+                        resultMap.put(element1.attr("name"), element1.text());
+                    }
+                }
+            }
+
+            if (StringUtil.isBlank(classStr)) {
+                return null;
+            }
+            Class<?> c = Class.forName(classStr);
+            Object object = c.newInstance(); //创建对象
+            //写数据 setName和setPassword方法
+            for (Map.Entry<String, String> entry : parameters.entrySet()) {
+                PropertyDescriptor pd = new PropertyDescriptor(entry.getKey(), c);//使用java.beans.PropertyDescriptor获取Method进行方法调用
+                Method method = pd.getWriteMethod();//获得写方法
+                method.invoke(object, entry.getValue());
+            }
+
+            //通过反射，执行execute方法
+            Method method = c.getDeclaredMethod("execute", null);
+            String result = (String) method.invoke(object);
+
+//            通过反射找到对象的所有getter方法（例如 getMessage）,通过反射来调用， 把值和属性形成一个HashMap , 例如 {"message":  "登录成功"} ,
+//            放到View对象的parameters
+            Map<String, String> map = new HashMap<>();
+            Field[] fields = c.getDeclaredFields();
+            for (Field field : fields) {
+                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), c); // message没有set方法，报错
+                Method getMethod = pd.getReadMethod();
+                String str = (String) getMethod.invoke(object);
+                map.put(field.getName(), str);
+
+            }
+//          根据struts.xml中的 <result> 配置,以及execute的返回值，  确定哪一个jsp，放到View对象的jsp字段中。
+            View view = new View();
+            view.setParameters(map);
+            String jsp = resultMap.get(result);
+            view.setJsp(jsp);
+            return view;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+}
diff --git a/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/StrutsTest.java b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/StrutsTest.java
new file mode 100644
index 000000000..e17b6154a
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/StrutsTest.java
@@ -0,0 +1,40 @@
+package com.github.lqingchenl.coding2017.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/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/View.java b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/View.java
new file mode 100644
index 000000000..487232ce7
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/View.java
@@ -0,0 +1,26 @@
+package com.github.lqingchenl.coding2017.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/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/struts.xml b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/struts.xml
new file mode 100644
index 000000000..73218d467
--- /dev/null
+++ b/group02/953840070/src/com/github/lqingchenl/coding2017/litestruts/struts.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<struts>
+    <action name="login" class="com.github.lqingchenl.coding2017.litestruts.LoginAction">
+        <result name="success">/jsp/homepage.jsp</result>
+        <result name="fail">/jsp/showLogin.jsp</result>
+    </action>
+    <action name="logout" class="com.github.lqingchenl.coding2017.litestruts.LogoutAction">
+    	<result name= "success">/jsp/welcome.jsp</result>
+    	<result name= "error">/jsp/error.jsp</result>
+    </action>
+</struts>
\ No newline at end of file
