0%

创建工程

Gradle->[Java,Web]->[GroupId:com.xuan,Artifactld:projectName]->[Use auto-import,Creat dir…..lly]

添加测试

选中要测试的->ctrl+shift+t

被测试代码

1
2
3
4
5
6
public class JunitHello {
public String printHello(){
System.out.printf("hello junit");
return "hello junit";
}
}

测试代码(目录test/java下有效)

1
2
3
4
5
6
7
public class JunitHelloTest {
@Test
public void printHello() throws Exception {
JunitHello junitHello=new JunitHello();
assertEquals(junitHello.printHello(),"hellojunit");
}
}

测试结果

1
2
3
4
5
6
7
8
9
hello junit
org.junit.ComparisonFailure:
Expected :hello junit
Actual :hellojunit
<Click to see difference>

at com.xuan.test.JunitHelloTest.printHello(JunitHelloTest.java:14)

Process finished with exit code -1
注意

自动导入了junit的包、测试代码只能在\test目录下才能使用,不然招不到junit的包,不需要添加JUnitGenerator V2.0自动生成测试模块插件

mvc目录结构

模块内分mvc层,mvc层内分模块

eg:下面介绍以功能模块(model)进行mvc分层,类的命名以功能模块名字Dao.java命名

dao

ModelDao.java文件结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.xuan.goods.model.dao;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import cn.itcast.jdbc.TxQueryRunner;
import com.xuan.goods.model.domain.Model;
/***
*模块持久层, 操作数据库
*/
public class ModelDao{
private QueryRunner qr=new TxQueryRunner();
/**
*抛出异常
*/
public Model findByName(String name)throws SQLException{
String sql="select result from model where name=?"; //数据库语句
//?的值为第三个name参数值,多个问号依次像后面增加参数
return qr.query(sql, new BeanHandler<Model>(Model.class),name);
}
}
domain

Model.java文件结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.xuan.goods.model.domain;
/**
*实体层
*/
public class Model{
//对应数据库
private String uid;//主键
private String name;//名字
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
/**
*get方法可以在jsp页面里直接用标签引用获得值,${model.name}
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
service

ModelService.java文件结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.xuan.goods.user.service;
/***
*业务逻辑层
*/
public class ModelService{
private ModelDao modelDao=new ModelDao(); //连接数据库操作层
/**
*业务逻辑
*/
public Model findModel(String name) throw ModelException{
Model model=modelDao.findByName(name);
if (model=null){
//将错误转换为自定义异常ModelException自定义异常类只需要extends Exception这个类
throw new ModelException("未找到模块!");
}
try{
return model;
}catch(SQLException e){
throw new RuntimeException(e);//转换异常,并传递异常
}
}
}
web

servlet 包下ModelServlet.java文件结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.xuan.goods.model.web.servlet;
/***
*页面显示层
*/
public class ModelServlet extends BaseServlet{
private ModelService modelService=new ModelService(); //连接业务逻辑层
public string findName(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name"); // 获取名
Model model = modelService.findModel(name);// 通过service得到结果
req.setAttribute("model", model); // 保存成功信息,转发到msg.jsp显示,jsp页面里直接用标签引用获得值,${model.name}
return "f:/jsps/msg.jsp"; // 转发到页面
}

代码见goods项目

MySQL安装

  1. 下载MySQL Community Server 5.7.17文件名

  2. 安装目录C:\Develop\mysql-5.7.17-winx64

  3. 设置工作目录复制my-default.ini重命名为my.ini修改里面

    1
    2
    3
    # These are commonly set, remove the # and set as required.
    basedir = "C:\Develop\mysql-5.7.17-winx64"
    datadir = "E:\DevelopmentWorkspace\mysql-5.7.17-workspase"
    注:其中 basedir=你的mysql目录,datadir=数据存放目录
  4. 管理员身份运行cmd,切换到C:\Develop\mysql-5.7.17-winx64\bin执行mysqld -install

  5. 执行mysqld --initialize 如果执行错误,删除数据存放目录,重新执行

  6. 运行mysql执行net start mysql

  7. 停止mysql执行net stop mysql

Tomcat 安装

  1. 下载apache-tomcat-8.5.12-windows-x64
  2. 安装目录C:\Develop\apache-tomcat-8.5.12

idea 安装

  1. 下载ideaIU-2016.3.5.exe
  2. 安装目录[C:\Develop\IntelliJ IDEA 2016.3.5](C:\Develop\IntelliJ IDEA 2016.3.5)
  3. 智能提示忽略大小写Editor->General->Code Completion:{Casesensitive completion:None}
  4. 取消自动打开上次的项目Appearance->System Settings:{Reopen last project on startup:false}
美化
  1. 安装Material Theme UI插件
  2. 下载主题样式http://color-themes.com
  3. 导入主题Ladies Night 2: File->Import Settings...

eclipse 安装

1.下载https://eclipse.org/

环境搭建

  1. 下载nodejs,并安装,安装过程默认(可修改路径),成功校验(npm -version)

    Javascript的运行环境,这里主要使用npm附属插件(包管理)

  2. npm install -g cordova 安装cordova

    混合开发环境,Cordova提供了js和原生API的调用接口,通过插件,我们可以实现例如拍照,扫码等操作; 并且提供了静态文件转换成APP的功能。

  3. npm install -g cordova ionic安装ionic

    Ionic 是基于 Cordova 的,在 Cordova 上能用的一切同样可以在 Ionic 上使用
    Ionic 在 Cordova 基础上增加了 Ionic UI、AngularJS、一个强大的 CLI 工具和一些云端服务等

快速入门

  1. JavaScript代码可以直接嵌在网页的任何地方,通常放到<head>

  2. <script>...</script>包裹代码

  3. 引入文件<script src="/src/js/xx.js"></script>

  4. alert('hello world');对话框

  5. console.log(var类型); 调试输出打印: 浏览器->右键->检查->Console

  6. 严格区分大小写

  7. ==自动转换数据类型再比较(缺陷),===先比较类型,在比较数据(比较完善)注:NaN(0/0;//NaN)是个特殊的Number,NaN===NaN;//false 应该用isNaN(NaN)

  8. 数组 var arr=[1,2,3.14,"helll",null,true];//可以是任意类型

  9. 对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var person={
    name:'xx',
    age:20,
    skill:['js','java','c'],
    hasCar: true,
    zipcode: null
    };//类似json字符串
    person.name; //值为'xx'
    person.tags[0];//值为'js'
    console.log(person); //调试打印出对象
    person.book='hello'; //新增一个book属性
    delete.person.book;//删除book属性
    'name' in person;// 返回true,判断person是否拥有name属性
    person.hasOwnProperty('name'); //true判断一个属性是否是person自身拥有的,而不是继承得到的
  10. 全局变量i=10;//i是全局变量 会造成混乱这是一缺陷,弥补缺陷方法加 'use strict';//需要浏览器支持,如果用了i=10;,将出现ReferenceError错误

  11. 转义字符串 'I\'m \"ok\"!; //字符串内容I'm "ok"!

  12. 多行字符串 `这是一个多行字符串`;//替代了\n

  13. 模板字符串

    1
    2
    3
    4
    var name="xx";
    var age=20;
    var message='你好,${name},年龄${age}'; //模板字符串法,需要浏览器支持
    var message='你好,'+name+',年龄'+age; //两者等效
  14. 字符串操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var s='hello world!';
    s.length; //字符串长度
    s[0];//'h'
    s[5];//' '
    s[11];//'!'
    s[0]='x';//'h' 只可读(赋值是不成功的)
    s=s.toUpperCase();//'HELLO WORLD!' 转换为大写
    s=s.toLowerCase();//转换为小写
    s.indexOf('wo');//返回它的位置6,如果没有wo则返回-1
    s.substring(0,5);//从0开始到5结束(不包括5),'hello'
    s.substring(7);//从7开始到结束 'orld!'
  15. 数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    var arr=[1,'a',2];
    arr.length; //3
    arr.length=2; //[1,'2']
    arr.length=4; //[1,'2',undefined,undefined]
    arr[2]=3;//[1,'2',3,undefined]
    arr[4]=6;//[1,'2',3,undefined,6]
    arr.slice(0,3); //等效于substring
    var arrCopy= arr.slice(); //从头到尾复制数组
    var arr=[1,2];
    arr.push('a','b'); //返回长度4
    arr;//[1,2,'a','b']
    arr.pop(); //返回'b'
    arr;//[1,2,'a']
    arr.unshift('A'); //返回长度4
    arr;//['A',1,2,'a']
    arr.sort(); //默认规则(0-9,A-Z,a-z)排序
    arr;//[1,2,A,a]
    arr.shift(); //'1'
    arr;//[2,A,'a']
    arr.reverse();
    arr;//['a',A,2] 反转
    //从索引1开始删除2个元素,然后再添加2个元素
    arr.splice(1,2,'b','c');//返回[A,2]
    arr;//[a,b,c]
    var arr2=[1,2,3];
    var added=arr2.concat(arr); //连接
    added;//[1,2,3,a,b,c]
    arr2;//[1,2,3]
    arr;//[a,b,c]
    var arr = ['A', 'B', 'C'];
    arr.concat(1, 2, [3, 4]); //返回['A', 'B', 'C', 1, 2, 3, 4]
    arr.join('-');//'A-B-C'
    var arr=[[1,2,3],[4,5,6],'-']; //多维数组把数组看成一个元素
    arr[1][2];//6
  16. 循环for (var ? in ?){}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var o={
    name:'xx',
    age:20,
    city:'cq'
    };
    //可以把一个对象的所有属性依次循环出来
    for(var key in o){
    alert(key); //'name','age','city'
    }
    var a=['A','B','C'];
    //由于Array也是对象,而它的每个元素的索引被视为对象的属性
    for(var i in a){
    alert(i); //'0','1','2'
    alert(a[i]); //'A','B','C'
    }
  17. Map是一组键值对的结构,具有极快的查找速度。

    1
    2
    3
    4
    5
    6
    7
    var m=new Map([['oo',100],['xx',99],['qq',21]]);
    m.get('oo');//100
    var mm=new Map(); //空Map
    mm.set('aa',12); //添加键值对
    mm.has('ss'); //是否存在key 'ss',不存在false
    mm.get('aa'); //获取key 'aa'的值12
    mm.delete('aa'); //删除'aa'键值对
  18. Set:SetMap类似,也是一组key的集合,但不存储value。

    1
    var s1=new Set([1,2,3,3]); //重复key字动过滤
  19. iterable ArrayMapSet都属于iterable类型。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var a=['A','B','C'];
    for(var x of a){ //遍历Array,Set,Map都可以
    alert(x); //'A','B','C'
    }
    a.name='hello';
    for(var x in a){
    alert(x); //'0','1','2','name'
    }
    //for ... in循环将把name包括在内,但Array的length属性却不包括在内。
    //for ... of循环则完全修复了这些问题,它只循环集合本身的元素。
    a.forEach(function (element,index,array)){
    //element: 指向当前元素的值
    //index:指向当前索引(可省略)
    //array:指向array对象本身(可省略)
    }
    var s = new Set(['A', 'B', 'C']);
    s.forEach(function (element, sameElement, set) {
    alert(element);
    });
    var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
    m.forEach(function (value, key, map) {
    alert(value);
    });

什么是jsp

是动态网页,可以嵌入java 代码 ,jsp 爷爷是servlet

基础语法

1
2
3
4
5
6
7
8
9
10
11
12
13
<%-- page指令,可以配置session,errorPage,iserrorpage等等 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 包含指令:用于设置公共的部分(eg:页头、也脚) --%>
<%@include file="/index.jsp"%>
<%!
// ! 定义在方法外面,可用做类的方法、属性
void function() {
}
%>
<%
String aa = "xaa"; //java 代码
%>
<%=aa%> <%-- 相当于out.print(aa); --%>

jsp九大隐式对象

  • Reqeust
  • Response
  • Session
  • Application
  • Config
  • Page
  • Out
  • Exception (jsp独有)
  • pageContext (jsp独有)

常见问题

idea配置

idea添加tomcat出现application server libraries not found

原因: 权限不足

解决: sudo chown -R 【用户名】 【tomcat目录】

抽象类

思想

动物->抽象类,猴子->子类

注意点:
  1. 抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。
  2. 抽象方法必须由子类来进行重写。
  3. 只要包含一个抽象方法的类,该类必须要定义成抽象类。
  4. 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。
  5. 子类中的抽象方法不能与父类的抽象方法同名。
  6. abstract不能与final并列修饰同一个类。
  7. abstract 不能与private、static、final或native并列修饰同一个方法。
    实例

子类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends baseActity {
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.aa);
super.initdata("s");
}

@Override
public void send(String data) {
textView.setText(data);
}
}

抽象类:

1
2
3
4
5
6
7
8
9
public abstract class baseActity extends AppCompatActivity {
int i = 0;

void initdata(String a) {
send(a + i++);
}

public abstract void send(String data);
}

参考

 java提高篇(四)—–抽象类与接口

快速排序

Sorting_quicksort_anim

思想

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

步骤为:

  1. 从数列中挑出一个元素,称为”基准”(pivot)
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    时间复杂度

    最好时间复杂度 $O(nlog(n))$
    最坏时间复杂度 $O(n^2)$

线性时间选择

问题描述

如何找出数组A中的第 k 小的元素? (1<=k<=n)
timeselect

步骤:

  1. 将n个元素分成5个一组,共ceiling(n/5)组。其中最后1组有n mod 5(余数)个元素。
  2. 用插入排序对每组排序,取其中值。若最后1组有偶数个元素,取较小得中值
  3. 递归的使用本地算法寻找ceiling(n/5)个中位数的中值x //第一次递归调用本身
  4. 用x作为划分元对数组A进行划分,并设x是第k个最小元
  5.  if i=k then return x;
     else if i<k then 找左区间的第i个最小元; //第二次递归调用本身
     else 找右区间的第i-k个最小元
    

流水作业调度

问题描述

n个作业{1,2,…,n}要在由2台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,然后在M2上加工。M1和M2加工作业i所需的时间分别为ai和bi。

最优解:n个作业的加工顺序、完成n个作业所需的最短时间
最优值:T(N,0)

Johnson法则

参考

0018算法笔记——【动态规划】流水作业调度问题与Johnson法则

0-1背包问题

250px-Knapsack.svg

问题描述

给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。

子问题最优值:m(i,j)
原问题最优值:m(1,c)
m(i,j)意为背包容量为j,可选择物品为,i,i+1,……,n时0,1问题的最优值。

贪心算法解

动态规划解

贪心算法

Greedy_algorithm_36_cents.svg

思想

是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

步骤:

  1. 建立数学模型来描述问题。
  2. 把求解的问题分成若干个子问题。
  3. 对每一子问题求解,得到子问题的局部最优解。
  4. 把子问题的解局部最优解合成原来解问题的一个解。
    eg: 0-1背包问题、哈弗曼编码

    二分搜索

    Binary_search_into_array
    时间复杂度 $O(log(n))$
    最优时间复杂度 $O(1)$
    平均时间复杂度 $O(log(n))$

思想

一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

步骤:

给予一个包含n个带值元素的数组A或是记录A0 … An−1,使得A0 ≤ … ≤ An−1,以及目标值T,还有下列用来搜索T在A中位置的子程序[3]。

  1. 令L为0,R为n− 1。
  2. 如果L > R,则搜索以失败告终。
  3. 令m(中间值元素)为“(L + R) / 2”加上下高斯符号。
  4. 如果Am < T,令L为m + 1并回到步骤二。
  5. 如果Am > T,令R为m - 1并回到步骤二。
  6. 当Am = T,搜索结束;回传值m。
    这个迭代步骤会持续通过两个变量追踪搜索的边界。有些实际应用会在算法的最后放入相等比较,让比较循环更快,但平均而言会多一层迭代

矩阵连乘

jx

问题描述

给定n个矩阵:A1,A2,…,An,其中Ai与Ai+1是可乘的,i=1,2…,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。

最优二叉搜索树

分治法

步骤:

  1. 分解:将原问题分解为若干个规模较小,相对独立,与原问题形式相同的子问题。
  2. 解决:若子问题规模较小且易于解决时,则直接解。否则,递归地解决各子问题。
  3. 合并:将各子问题的解合并为原问题的解。

eg: 快速排序

动态规划

基本思想

通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法

基本要素:

重叠子问题、最优子结构性质

试用情况

  1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
  2. 无后效性。即子问题的解一旦确定,就不再改变,不受在这之后、包含它的更大的问题的求解决策影响。
  3. 子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

eg: 背包问题

合并排序(归并排序)

Merge-sort-example-300px
时间复杂度 $O(nlog(n))$
最优时间复杂度 $O(n)$
平均时间复杂度 $O(nlog(n))$

基本思想

将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。

哈弗曼编码

350px-Huffman_tree_2.svg
这个句子“this is an example of a huffman tree”中得到的字母频率来建构霍夫曼树。句中字母的编码和频率如图所示。编码此句子需要135 bit(不包括保存树所用的空间)

Huffman_algorithm