SpingBoot依赖包

Spring Boot的启动器Starter详解

作者:chszs,转载博客主页:http://blog.csdn.net/chszs

Spring Boot应用启动器基本的一共有44种,具体如下:

1)spring-boot-starter
这是Spring Boot的核心启动器,包含了自动配置、日志和YAML。

2)spring-boot-starter-actuator
帮助监控和管理应用。

3)spring-boot-starter-amqp
通过spring-rabbit来支持AMQP协议(Advanced Message Queuing Protocol)。

4)spring-boot-starter-aop
支持面向方面的编程即AOP,包括spring-aop和AspectJ。

5)spring-boot-starter-artemis
通过Apache Artemis支持JMS的API(Java Message Service API)。

6)spring-boot-starter-batch
支持Spring Batch,包括HSQLDB数据库。

7)spring-boot-starter-cache
支持Spring的Cache抽象。

8)spring-boot-starter-cloud-connectors
支持Spring Cloud Connectors,简化了在像Cloud Foundry或Heroku这样的云平台上连接服务。

9)spring-boot-starter-data-elasticsearch
支持ElasticSearch搜索和分析引擎,包括spring-data-elasticsearch。

10)spring-boot-starter-data-gemfire
支持GemFire分布式数据存储,包括spring-data-gemfire。

11)spring-boot-starter-data-jpa
支持JPA(Java Persistence API),包括spring-data-jpa、spring-orm、Hibernate。

12)spring-boot-starter-data-mongodb
支持MongoDB数据,包括spring-data-mongodb。

13)spring-boot-starter-data-rest
通过spring-data-rest-webmvc,支持通过REST暴露Spring Data数据仓库。

14)spring-boot-starter-data-solr
支持Apache Solr搜索平台,包括spring-data-solr。

15)spring-boot-starter-freemarker
支持FreeMarker模板引擎。

16)spring-boot-starter-groovy-templates
支持Groovy模板引擎。

17)spring-boot-starter-hateoas
通过spring-hateoas支持基于HATEOAS的RESTful Web服务。

18)spring-boot-starter-hornetq
通过HornetQ支持JMS。

19)spring-boot-starter-integration
支持通用的spring-integration模块。

20)spring-boot-starter-jdbc
支持JDBC数据库。

21)spring-boot-starter-jersey
支持Jersey RESTful Web服务框架。

22)spring-boot-starter-jta-atomikos
通过Atomikos支持JTA分布式事务处理。

23)spring-boot-starter-jta-bitronix
通过Bitronix支持JTA分布式事务处理。

24)spring-boot-starter-mail
支持javax.mail模块。

25)spring-boot-starter-mobile
支持spring-mobile。

26)spring-boot-starter-mustache
支持Mustache模板引擎。

27)spring-boot-starter-redis
支持Redis键值存储数据库,包括spring-redis。

28)spring-boot-starter-security
支持spring-security。

29)spring-boot-starter-social-facebook
支持spring-social-facebook

30)spring-boot-starter-social-linkedin
支持pring-social-linkedin

31)spring-boot-starter-social-twitter
支持pring-social-twitter

32)spring-boot-starter-test
支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。

33)spring-boot-starter-thymeleaf
支持Thymeleaf模板引擎,包括与Spring的集成。

34)spring-boot-starter-velocity
支持Velocity模板引擎。

35)spring-boot-starter-web
S支持全栈式Web开发,包括Tomcat和spring-webmvc。

36)spring-boot-starter-websocket
支持WebSocket开发。

37)spring-boot-starter-ws
支持Spring Web Services。

Spring Boot应用启动器面向生产环境的还有2种,具体如下:

1)spring-boot-starter-actuator
增加了面向产品上线相关的功能,比如测量和监控。

2)spring-boot-starter-remote-shell
增加了远程ssh shell的支持。

最后,Spring Boot应用启动器还有一些替换技术的启动器,具体如下:

1)spring-boot-starter-jetty
引入了Jetty HTTP引擎(用于替换Tomcat)。

2)spring-boot-starter-log4j
支持Log4J日志框架。

3)spring-boot-starter-logging
引入了Spring Boot默认的日志框架Logback。

4)spring-boot-starter-tomcat
引入了Spring Boot默认的HTTP引擎Tomcat。

5)spring-boot-starter-undertow
引入了Undertow HTTP引擎(用于替换Tomcat)。

PalindromicSubstrings

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
35
36
37
38
39
40
41
package Classify.DP.Medium;

import org.junit.jupiter.api.Test;

public class PalindromicSubstrings {

/**
* 基本思路:这里的 dp 方程的每一个元素就代表我要以当前元素作为回文子串的结尾时候的回文子串的数量
* 那么递推公式就是以上一个元素结尾时候的子串数量加上本次的结尾的子串的数量就能获得总数量了
* 而判断当前结尾的回文子串就是判断到对称的元素,然后翻转操作做判断即可
* @param s
* @return
*/

public int countSubstrings(String s) {
int[] dp = new int[s.length()];
dp[0] = 1;
for (int i = 1; i < dp.length; i++) {
dp[i] = dp[i - 1] + currentCount(s, i);
}
return dp[s.length() - 1];
}

private int currentCount(String string, int i) {
int count = 0;
for (int j = i; j >= 0; --j) {
if (string.charAt(i) != string.charAt(j)) {
continue;
}
if (new StringBuilder(string.substring(j, i + 1)).reverse().toString().equals(string.substring(j, i + 1))) {
++count;
}
}
return count;
}

@Test
public void fun() {
System.out.println(countSubstrings("aaa"));
}
}

DP刷题记录Medium

  • House Robber II

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package Classify.DP.Medium;

    import org.junit.jupiter.api.Test;



    public class HouseRobberII {
    /**
    * 思路一:这道题的意思就是成一个环,也就是偷了第一个不能头最后一个。
    * 所以我们的思路就是让他从第一个偷到倒数第二个
    * 从第二个偷到最后一个
    * 算两个的最大值
    * 思路二:这种方法就是去掉头和尾,计算中间的最大值,然后加上第一个与最后一个中的最大值
    * @param nums
    * @return
    */
    public int rob(int[] nums) {
    if (nums.length == 0) {
    return 0;
    } else if (nums.length == 1) {
    return nums[0];
    } else if (nums.length == 2) {
    return Math.max(nums[0], nums[1]);
    }
    int result1;
    int result2;
    int[] dp=new int[2];
    dp[0] = 0;
    dp[1] = nums[0];
    int tmp;
    for (int i = 1; i < nums.length-1; i++) {
    tmp = dp[0];
    dp[0] = Math.max(dp[0], dp[1]);
    dp[1] = tmp + nums[i];
    }
    result1 = Math.max(dp[0], dp[1]);

    dp[0] = 0;
    dp[1] = nums[1];
    for (int i = 2; i < nums.length; i++) {
    tmp = dp[0];
    dp[0] = Math.max(dp[0], dp[1]);
    dp[1] = tmp + nums[i];
    }

    result2 = Math.max(dp[0], dp[1]);
    return Math.max(result1, result2);
    }

    @Test
    public void fun(){
    System.out.println(rob(new int[]{1,1,1}));
    }
    }
  • 2 Keys Keyboard

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    package Classify.DP.Medium;

    import org.junit.jupiter.api.Test;

    /**
    *
    Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step:

    Copy All: You can copy all the characters present on the notepad (partial copy is not allowed).
    Paste: You can paste the characters which are copied last time.
    Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'.

    Example 1:
    Input: 3
    Output: 3
    Explanation:
    Intitally, we have one character 'A'.
    In step 1, we use Copy All operation.
    In step 2, we use Paste operation to get 'AA'.
    In step 3, we use Paste operation to get 'AAA'.
    Note:
    The n will be in the range [1, 1000].
    */

    public class KeysKeyboard {
    /**
    * 这题的思路就是 dp 代表的就是当前的 A 的数量,然后我们优先考虑上一步复制过的情况,因为这样能够最快的填满 n 个 A ,但是使用这种情况要注意的就是
    * 我们可能上部赋值我们最后收不了尾,所以必须有一个判断就是我们能用上一步的复制的内容填满剩下的 A ,也就是 n % dp[i - 1] == 0
    * 里面的内容的意思就是我们使用了上一步的复制的内容那么我们的字符串就直接翻倍,而且我们进行了一次复制,那么我们 count 就得加2
    * @param n
    * @return
    */
    public int minSteps(int n) {
    if (n == 1) {
    return 0;
    }
    int[] dp = new int[1000];
    dp[0] = 1;
    int paste = 1;
    int i = 0;
    int count = 1;
    while (dp[i] <= n) {
    ++i;
    if (n % dp[i - 1] == 0) {
    paste = dp[i - 1];
    dp[i] = dp[i - 1] * 2;
    ++count;
    if (paste != 1) {
    ++count;
    }
    } else {
    dp[i] = dp[i - 1] + paste;
    ++count;
    }
    if (dp[i] == n) {
    return count;
    }
    }
    return count;
    }


    @Test
    public void fun() {
    System.out.println(minSteps(10));
    }
    }

DP 刷题记录 Easy

  • House robber
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package Classify.DP;

import org.junit.jupiter.api.Test;

public class HouseRobber {

/**
* 解法一:思路就是一个二维的动态规划问题,然后0代表不偷当前的房子,1就是偷
* 那么就可以写出两个地推公式出来,这次不偷的话就是看上一次的最多的情况,然后如果这次偷那么就上一次肯定没有偷,就可以用上一次的没有偷的加上本次的
* @param nums
* @return
*/
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[][] dp = new int[nums.length][2];
dp[0][0] = 0;
dp[0][1] = nums[0];
int i;
for (i = 1; i < nums.length; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + nums[i];
}
return Math.max(dp[i-1][0], dp[i-1][1]);
}

/**
* 解法二:也就是使用上面的方法然后进行降为,从二维到一维,空间复杂度成 o one
* 观察可以发现我们每次进行递推的时候我们只用到了上一步的偷了或者没偷的情况所以我们直接就可以用两个变量来代替
* @param nums
* @return
*/
public int rob_1(int[] nums){
int[] dp=new int[2];
dp[0] = 0;
dp[1] = nums[0];
int tmp;
for (int i = 1; i < nums.length; i++) {
tmp = dp[0];
dp[0] = Math.max(dp[0], dp[1]);
dp[1] = tmp + nums[i];
}
return Math.max(dp[0], dp[1]);
}

@Test
public void fun(){
System.out.println(rob_1(new int[]{1,2,3,43}));
}

}
  • Maximum Subarray

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    package Classify.DP;

    import org.junit.jupiter.api.Test;

    public class MaximumSubarray {
    public int maxSubArray(int[] A) {
    if (A == null || A.length == 0)
    return 0;
    int global = A[0];
    int local = A[0];
    for (int i = 1; i < A.length; i++) {
    local = Math.max(A[i], local + A[i]);
    global = Math.max(local, global);
    }
    return global;
    }

    @Test
    public void fun() {
    System.out.println(maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4}));
    }
    }
  • Best Time to Buy and Sell Stock

    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
    package Classify.DP;

    import org.junit.jupiter.api.Test;

    public class BestTimeBuyAndSellStock {

    /**
    * 思路:这个动态规划问题就是定义 dp 数组就是当前的最大利润。那么递推式就是上一次的最大利润和今天与昨天的差值利润之间的较大的那个,如果是
    * 昨天收盘加上今天的的利润还不如仅仅今天的利润大就直接拿今天的否则就拿昨天的
    * 也就是这一行!
    * dp[1] = Math.max(dp[0] + prices[i] - prices[i - 1], prices[i] - prices[i - 1]);
    * @param prices
    * @return
    */
    public int maxProfit(int[] prices) {
    if (prices.length == 0) {
    return 0;
    }
    int[] dp = new int[2];
    int result = 0;
    for (int i = 1; i < prices.length; i++) {
    dp[1] = Math.max(dp[0] + prices[i] - prices[i - 1], prices[i] - prices[i - 1]);
    dp[0] = dp[1];
    result = Math.max(dp[1], result);
    }
    return result;
    }

    @Test
    public void fun(){
    System.out.println(maxProfit(new int[]{7, 1, 5, 3, 6, 4}));
    }
    }
  • Climbing Stairs

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    package Classify.DP;

    import org.junit.jupiter.api.Test;

    public class ClimbingStairs {


    /**
    * Time Limit Exceeded 暴力破解法
    */
    private int count = 0;

    public int climbStairs(int n) {
    find(0, n);
    return count;
    }

    private void find(int n,int level) {
    if (n == level) {
    count++;
    return;
    } else if (n > level) {
    return;
    }
    find(n + 1,level);
    find(n + 2, level);
    }


    /**
    * 上面的暴力破解的方式导致超时了,其实一般来说绝大多数的 dp 问题都可以使用暴力破解的方法来解决,也就是上面的递归枚举,但是我们知道 dp 的出现就是
    * 为了记录一些东西防止重复计算的,也就是为枚举剪枝,所以说还是要用枚举,这里我们定义了 dp 的含义就是到达当前位置的方法数,而递推公式写法就是
    * 到达当前位置要么是跳两部要么是跳一步来的。所以递推公式就是
    * dp[i] = dp[i - 2] + dp[i - 1];
    * 最重要的就是首先要确定 dp 数组的含义
    * @param n
    * @return
    */

    public int climbStairs_1(int n) {
    int[] dp = new int[n+2];
    dp[0] = 0;
    dp[1] = 1;
    int i;
    for (i = 2; i <= n+1; i++) {
    dp[i] = dp[i - 2] + dp[i - 1];
    }
    return dp[i-1];
    }


    @Test
    public void fun(){
    System.out.println(climbStairs_1(10));

    }
    }

以上的题全部都是 Easy 的题,然后也就是我们发现最后我们都可以转为一维的 dp 问题,我们都没设计二维的问题。下一篇开始就是 Mid 的题,估计主要就是类似背包问题的那一类二维的不可分解的问题。

动态规划

​ 动态规划一般来说和分治有点类似都是让他们去处理相同的子问题,但是在动态规划里面你会遇到更多的相同子问题。然后我们就会导致很多的重复计算,所以一般我们可以使用递归来完成一个动态规划要完成的任务,但是这样一般会重复计算很多东西,所以动态规划一般就增加了一些矩阵来存放上一次计算的结果。

Read More

分治算法

​ 分治算法分为 “分” 和 “治” 两个部分,所谓的分就是寻找分割点,然后对问题划分成相同的子问题,但是问题的规模变小了,这些步骤其实就是使用递归来完成的。之后就是治的问题,也就是递归里面具体的内容。最后一步就是把所分的结果要合并成为一个完整的结果。

​ 一个例子就是求出逆序数对,这个就是分治法来计算,首席我们分就是中间划分,分别求左右的两边的逆序数对,然后还需要加上横跨中间的逆序数对即可完成。重点就是横跨中间的逆序数对,中间的如果直接暴力枚举就会出现 n 平方的,所以我们首先对两边分别排序,然后在进行计算,这样复杂度就变成了 n/2 复杂度。

贪心

​ 贪心算法,这个算法就是大胆的猜测,然后小心求证!求证一般就是使用反证法进行证明。假如我们说这个顺序是对的,也就是始终选取大的,或者小的,我们就要证明一下我们的猜测正确性。这里的反正方式就是交换顺序发现不符合预期结果原来的结论就是对的。

枚举

​ 枚举就是尝试所有的可能性,尤其是当我们在确定一个问题是不是的这一类问题中尤其有用,例如说给一堆数,让我我们判断他们是不是素数,或者素数的数量的时候,这里他们就是判断类问题我们就可以使用枚举。

​ 但是注意这里我们需要考虑的就是枚举的方式,也就是枚举的角度。这里有一个小的例子就是最长回文子串的问题。

Read More

犒劳一下自己

​ 心情不好的时候,可能这时候真的已经很疲惫了。

​ 不要继续沮丧让自己的心情更糟糕,或许这个时候应该犒劳一下自己,让自己的心情放松,晴朗起来或许一切看起来回事那么情切舒服!