LeetCode - Algorithms - 393. UTF-8 Validation

Just verify code of others.

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public boolean validUtf8(int[] data) {
int count=0;
for(int k : data) {
if (count==0) {
if ((k>>5)==0b110) count=1;
else if ((k>>4)==0b1110) count=2;
else if ((k>>3)==0b11110) count=3;
else if ((k>>7)==1) return false;
}
else {
if ((k>>6)!=0b10) return false;
count--;
}
}
return count==0;
}
}

binary (introduced in Java SE 7) 0b11110101 (0b followed by a binary number)

Submission Detail

  • 49 / 49 test cases passed.
  • Runtime: 6 ms
  • Your runtime beats 27.65 % of java submissions.

ref

LeetCode - Algorithms - 384. Shuffle an Array

It seemed that Spotify only let you click big green SHUFFLE PLAY button if you are not premium user.

Java

1 - Fisher–Yates shuffle

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
import java.util.Random;

class Solution {
private int[] shuffleArr;
private int[] originalArr;

public Solution(int[] nums) {
originalArr = nums.clone();
shuffleArr = nums.clone();
}

/** Resets the array to its original configuration and return it. */
public int[] reset() {
return originalArr;
}

/** Returns a random shuffling of the array. */
public int[] shuffle() {
Random random = new Random();
int temp = 0;
int randomPosition = 0;
final int N = shuffleArr.length;
for(int i=shuffleArr.length-1;i>0;i--) {
randomPosition = random.nextInt(N);
temp = shuffleArr[i];
shuffleArr[i] = shuffleArr[randomPosition];
shuffleArr[randomPosition] = temp;
}
return shuffleArr;
}
}

Submission Detail

  • 10 / 10 test cases passed.
  • Runtime: 210 ms
  • Your runtime beats 38.29 % of java submissions.

2 the Knuth (or Fisher-Yates) shuffling algorithm

© Robert Sedgewick and Kevin Wayne

Proposition. [Fisher-Yates 1938] Knuth shuffling algorithm produces a uniformly random permutation of the input array in linear time.

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
class Solution {
private int[] shuffleArr;
private int[] originalArr;

public Solution(int[] nums) {
originalArr = nums.clone();
shuffleArr = nums.clone();
}

/** Resets the array to its original configuration and return it. */
public int[] reset() {
return originalArr;
}

/** Returns a random shuffling of the array. */
public int[] shuffle() {
final int N = shuffleArr.length;
int swap;
for (int i = 0; i < N; i++) {
int r = (int) (Math.random() * (i + 1));
swap = shuffleArr[r];
shuffleArr[r] = shuffleArr[i];
shuffleArr[i] = swap;
}
return shuffleArr;
}
}

/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* int[] param_1 = obj.reset();
* int[] param_2 = obj.shuffle();
*/

Submission Detail

  • 10 / 10 test cases passed.
  • Runtime: 76 ms, faster than 76.75% of Java online submissions for Shuffle an Array.
  • Memory Usage: 47.2 MB, less than 6.24% of Java online submissions for Shuffle an Array.

3 - Collections.shuffle

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
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

class Solution {
private Integer[] shuffleArr;
private int[] originalArr;

public Solution(int[] nums) {
shuffleArr = new Integer[nums.length];
for(int i=0;i<nums.length;i++)
shuffleArr[i] = nums[i];
originalArr = nums.clone();
}

/** Resets the array to its original configuration and return it. */
public int[] reset() {
return originalArr;
}

/** Returns a random shuffling of the array. */
public int[] shuffle() {
List<Integer> list = Arrays.asList(shuffleArr);
Collections.shuffle(list);
Integer[] a = new Integer[shuffleArr.length];
list.toArray(a);
int[] r = new int[a.length];
for(int i=0;i<a.length;i++)
r[i] = a[i];
return r;
}
}

Submission Detail

  • 10 / 10 test cases passed.
  • Runtime: 141 ms
  • Your runtime beats 96.48 % of java submissions.

ref

LeetCode - Algorithms - 706. Design HashMap

In Java collections framework, HashMap is the class I used most. Hash function is a hard problem.

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
25
26
class MyHashMap {
static final int N = 1000000;
private int[] arr;

/** Initialize your data structure here. */
public MyHashMap() {
arr = new int[N];
Arrays.fill(arr, -1);
}

/** value will always be non-negative. */
public void put(int key, int value) {
arr[key]=value;
}

/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
return arr[key];
}

/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
arr[key]=-1;
}
}

Submission Detail

  • 33 / 33 test cases passed.
  • Runtime: 150 ms
  • Your runtime beats 13.66 % of java submissions.

LeetCode - Algorithms - 53. Maximum Subarray

Tagged as easy, I feel it is not easy to solve. dynamic programming class problem. The solution is others, I only verify it.

Java

1 Kadane’s algorithm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int maxSubArray(int[] nums) {
int max = Integer.MIN_VALUE;
int count = 0;
for(int i=0;i<nums.length;i++) {
count += nums[i];
if (count>max)
max = count;
if (count<0)
count = 0;
}
return max;
}
}

Submission Detail

  • 202 / 202 test cases passed.
  • Runtime: 10 ms
  • Your runtime beats 40.59 % of java submissions.

2 DP

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int maxSubArray(int[] nums) {
int newSum = nums[0];
int max = nums[0];
for(int i=1;i<nums.length;i++) {
newSum = Math.max(newSum+nums[i], nums[i]);
max = Math.max(newSum, max);
}
return max;
}
}

Submission Detail

  • 202 / 202 test cases passed.
  • Runtime: 7 ms
  • Your runtime beats 89.29 % of java submissions.

ref

LeetCode - Algorithms - 69. Sqrt(x)

Java

1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int mySqrt(int x) {
if (x < 0)
return 0;
else if (x < 2)
return x;
else {
long smallCandidate = mySqrt(x >> 2) << 1;
long largeCandidate = smallCandidate + 1;
if (largeCandidate*largeCandidate > x)
return new Long(smallCandidate).intValue();
else
return new Long(largeCandidate).intValue();
}
}
}

Submission Detail

  • 1017 / 1017 test cases passed.
  • Runtime: 36 ms
  • Your runtime beats 17.73 % of java submissions.

2

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public int mySqrt(int x) {
if (x==0 || x==1) return x;
long i=1, result=1;
while(result<=x) {
i++;
result = i*i;
}
return new Long(i-1).intValue();
}
}

Submission Detail

  • 1017 / 1017 test cases passed.
  • Runtime: 33 ms
  • Your runtime beats 24.03 % of java submissions.

3 O(logn)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int mySqrt(int x) {
if (x == 0 || x == 1)
return x;

long start = 1, end = x, ans = 0;
while (start <= end) {
long mid = (start + end) / 2;

if (mid * mid == x)
return new Long(mid).intValue();

if (mid * mid < x) {
start = mid + 1;
ans = mid;
} else
end = mid - 1;
}
return new Long(ans).intValue();
}
}

Submission Detail

  • 1017 / 1017 test cases passed.
  • Runtime: 16 ms
  • Your runtime beats 95.09 % of java submissions.

ref

LeetCode - Algorithms - 217. Contains Duplicate

Tag easy as it is. This problem is like 387. First Unique Character in a String.

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public boolean containsDuplicate(int[] nums) {
boolean r = false;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++) {
if (map.containsKey(nums[i])) {
int val = map.get(nums[i]);
map.put(nums[i], val+1);
}
else {
map.put(nums[i], 1);
}
}
Iterator<Integer> itr = map.values().iterator();
while(itr.hasNext()) {
if (itr.next().intValue()>1) {
r = true;
break;
}
}
return r;
}
}

Submission Detail

  • 18 / 18 test cases passed.
  • Runtime: 13 ms
  • Your runtime beats 48.76 % of java submissions.

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @param {number[]} nums
* @return {boolean}
*/
var containsDuplicate = function(nums) {
var r = false;
var count = {};
for(var i=0;i<nums.length;i++) {
if (typeof count[nums[i]]!="undefined" && count[nums[i]]!=null) {
count[nums[i]]++;
}
else {
count[nums[i]]=1;
}
}
for(var i in count) {
if (count[i]>1) {
r = true;
break;
}
}
return r;
};

Submission Detail

  • 18 / 18 test cases passed.
  • Runtime: 92 ms
  • Your runtime beats 35.80 % of javascript submissions.

AKS test for primes

Manindra Agrawal & Neeraj Kayal & Nitin Saxena present an unconditional deterministic polynomial-time algorithm that determines whether an input number is prime or composite.

The AKS algorithm for testing whether a number is prime is a polynomial-time algorithm based on an elementary theorem about Pascal triangles.

Rust

1

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
use std::iter::repeat;

fn aks_coefficients(k: usize) -> Vec<i64> {
let mut coefficients = repeat(0i64).take(k + 1).collect::<Vec<_>>();
coefficients[0] = 1;
for i in 1..(k + 1) {
coefficients[i] = -(1..i).fold(coefficients[0], |prev, j|{
let old = coefficients[j];
coefficients[j] = old - prev;
old
});
}
coefficients
}

fn is_prime(p: usize) -> bool {
if p < 2 {
false
} else {
let c = aks_coefficients(p);
(1 .. (c.len() - 1) / 2 + 1).all(|i| (c[i] % (p as i64)) == 0)
}
}

fn main() {
for i in 0..8 {
println!("{}: {:?}", i, aks_coefficients(i));
}
for i in (1..51).filter(|&i| is_prime(i)) {
print!("{} ", i);
}
}

2

An alternative version which computes the coefficients in a more functional but less efficient way.

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
fn aks_coefficients(k: usize) -> Vec<i64> {
if k == 0 {
vec![1i64]
} else {
let zero = Some(0i64);
(1..k).fold(vec![1i64, -1], |r, _| {
let a = r.iter().chain(zero.iter());
let b = zero.iter().chain(r.iter());
a.zip(b).map(|(x, &y)| x-y).collect()
})
}
}

fn is_prime(p: usize) -> bool {
if p < 2 {
false
} else {
let c = aks_coefficients(p);
(1 .. (c.len() - 1) / 2 + 1).all(|i| (c[i] % (p as i64)) == 0)
}
}

fn main() {
for i in 0..8 {
println!("{}: {:?}", i, aks_coefficients(i));
}
for i in (1..51).filter(|&i| is_prime(i)) {
print!("{} ", i);
}
}

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class AksTest {

private static final long[] c = new long[64];

public static void main(String[] args) {
for (int n = 0; n < 10; n++) {
coeff(n);
show(n);
}

System.out.print("Primes:");
for (int n = 1; n < c.length; n++)
if (isPrime(n))
System.out.printf(" %d", n);

System.out.println();
}

static void coeff(int n) {
c[0] = 1;
for (int i = 0; i < n; c[0] = -c[0], i++) {
c[1 + i] = 1;
for (int j = i; j > 0; j--)
c[j] = c[j - 1] - c[j];
}
}

static boolean isPrime(int n) {
coeff(n);
c[0]++;
c[n]--;

int i = n;
while (i-- != 0 && c[i] % n == 0)
continue;
return i < 0;
}

static void show(int n) {
System.out.print("(x-1)^" + n + " =");
for (int i = n; i >= 0; i--) {
System.out.print(" + " + c[i] + "x^" + i);
}
System.out.println();
}
}

JavaScript

Translation of: C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function coef(n) {
for (var c=[1], i=0; i<n; c[0]=-c[0], i+=1) {
c[i+1]=1; for (var j=i; j; j-=1) c[j] = c[j-1]-c[j]
}
return c
}

function show(cs) {
var s='', n=cs.length-1
do s += (cs[n]>0 ? ' +' : ' ') + cs[n] + (n==0 ? '' : n==1 ? 'x' :'x<sup>'+n+'</sup>'); while (n--)
return s
}

function isPrime(n) {
var cs=coef(n), i=n-1; while (i-- && cs[i]%n == 0);
return i < 1
}

for (var n=0; n<=7; n++) document.write('(x-1)<sup>',n,'</sup> = ', show(coef(n)), '<br>')

document.write('<br>Primes: ');
for (var n=2; n<=50; n++) if (isPrime(n)) document.write(' ', n)

Translation of: CoffeeScript

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
68
69
70
71
72
73
74
75
76
77
78
79
var i, p, pascal, primerow, primes, show, _i;

pascal = function() {
var a;
a = [];
return function() {
var b, i;
if (a.length === 0) {
return a = [1];
} else {
b = (function() {
var _i, _ref, _results;
_results = [];
for (i = _i = 0, _ref = a.length - 1; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
_results.push(a[i] + a[i + 1]);
}
return _results;
})();
return a = [1].concat(b).concat([1]);
}
};
};

show = function(a) {
var degree, i, sgn, show_x, str, _i, _ref;
show_x = function(e) {
switch (e) {
case 0:
return "";
case 1:
return "x";
default:
return "x^" + e;
}
};
degree = a.length - 1;
str = "(x - 1)^" + degree + " =";
sgn = 1;
for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
str += ' ' + (sgn > 0 ? "+" : "-") + ' ' + a[i] + show_x(degree - i);
sgn = -sgn;
}
return str;
};

primerow = function(row) {
var degree;
degree = row.length - 1;
return row.slice(1, degree).every(function(x) {
return x % degree === 0;
});
};

p = pascal();

for (i = _i = 0; _i <= 7; i = ++_i) {
console.log(show(p()));
}

p = pascal();

p();

p();

primes = (function() {
var _j, _results;
_results = [];
for (i = _j = 1; _j <= 49; i = ++_j) {
if (primerow(p())) {
_results.push(i + 1);
}
}
return _results;
})();

console.log("");

console.log("The primes upto 50 are: " + primes);

Reviewed (ES6)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function pascal(n) {
var cs = []; if (n) while (n--) coef(); return coef
function coef() {
if (cs.length === 0) return cs = [1];
for (var t=[1,1], i=cs.length-1; i; i-=1) t.splice( 1, 0, cs[i-1]+cs[i] ); return cs = t
}
}

function show(cs) {
for (var s='', sgn=true, i=0, deg=cs.length-1; i<=deg; sgn=!sgn, i+=1) {
s += ' ' + (sgn ? '+' : '-') + cs[i] + (e => e==0 ? '' : e==1 ? 'x' : 'x<sup>' + e + '</sup>')(deg-i)
}
return '(x-1)<sup>' + deg + '</sup> =' + s;
}

function isPrime(cs) {
var deg=cs.length-1; return cs.slice(1, deg).every( function(c) { return c % deg === 0 } )
}

var coef=pascal(); for (var i=0; i<=7; i+=1) document.write(show(coef()), '<br>')

document.write('<br>Primes: ');
for (var coef=pascal(2), n=2; n<=50; n+=1) if (isPrime(coef())) document.write(' ', n)

ref

Web Engineering

前端工程化(工具)
前端组件化(生态)

npm

  • NPM的全称是Node Package Manager,Nodejs的包管理器
  • 从API对用户友好这一个角度来说,Node.js的模块机制是非常优秀的。

package.json

必备字段

  • main指定了加载的入口文件,对于require,只需要main属性即可
  • name : 包名,需要在NPM上是唯一的。不能带有空格。
  • description : 包简介。通常会显示在一些列表中。
  • version : 版本号。一个语义化的版本号(http://semver.org/ ),通常为x.y.z。该版本号十分重要,常常用于一些版本控制的场合。
  • keywords : 关键字数组。用于NPM中的分类搜索。
  • maintainers : 包维护者的数组。数组元素是一个包含name、email、web三个属性的JSON对象。
  • contributors : 包贡献者的数组。第一个就是包的作者本人。在开源社区,如果提交的patch被merge进master分支的话,就应当加上这个贡献patch的人。格式包含name和email。
  • bugs : 一个可以提交bug的URL地址。可以是邮件地址(mailto:mailxx@domain),也可以是网页地址(http://url)。
  • licenses : 包所使用的许可证。
  • repositories : 托管源代码的地址数组。
  • dependencies : 当前包需要的依赖。这个属性十分重要,NPM会通过这个属性,帮你自动加载依赖的包。

额外字段

  • bin : 指定各个内部命令对应的可执行文件的位置
  • scripts : 包管理器(NPM)在对包进行安装或者卸载的时候需要进行一些编译或者清除的工作,scripts字段的对象指明了在进行操作时运行哪个文件,或者执行拿条命令。
  • engines
  • devDependencies : 指定项目开发所需要的模块
  • author
  • peerDependencies字段,就是用来供插件指定其所需要的主工具的版本。
  • config字段用于向环境变量输出值
  • browser指定该模板供浏览器使用的版本
  • engines指明了该项目所需要的node.js版本
  • man用来指定当前模块的man文档的位置
  • style指定供浏览器使用时,样式文件所在的位置

dependencies & devDependencies format

  • 指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
  • 波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。
  • 插入号(caret)+指定版本:比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
  • latest:安装最新版本。

webpack

  • webpack以一种非常优雅的方式解决了前端资源依赖管理的问题,它在内部已经集成了许多资源依赖处理的细节,但是对于使用者而言只需要做少量的配置,再结合构建工具,很容易搭建一套前端工程解决方案。
  • 基于webpack的前端自动化工具,可以自由组合各种开源技术栈(Koa/Express/其他web框架、webpack、Sass/Less/Stylus、Gulp/Grunt等),没有复杂的资源依赖配置,工程结构也相对简单和灵活。
  • 根据webpack的设计理念,所有资源都是“模块”,webpack内部实现了一套资源加载机制,除了借助插件体系加载不同类型的资源文件之外,webpack还对输出结果提供了非常精细的控制能力,开发者只需要根据需要调整参数即可
  • test项表示匹配的资源类型,loader或loaders项表示用来加载这种类型的资源的loader
    对于css文件,默认情况下webpack会把css content内嵌到js里边,运行时会使用style标签内联。如果希望将css使用link标签引入,可以使用ExtractTextPlugin插件进行提取。
  • 图片资源的loader配置:意思是,图片资源在加载时先压缩,然后当内容size小于~10KB时,会自动转成base64的方式内嵌进去,这样可以减少一个HTTP的请求。当图片大于10KB时,则会在img/下生成压缩后的图片,命名是[hash:8].[name].[ext]的形式。hash:8的意思是取图片内容hushsum值的前8位,这样做能够保证引用的是图片资源的最新修改版本,保证浏览器端能够即时更新。
1
2
3
4
5
6
7
8
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'image?...',
'url?limit=10000&name=img/[hash:8].[name].[ext]',
]
}

  • 多个入口文件之间可能公用一个模块,可以使用CommonsChunkPlugin插件对指定的chunks进行公共模块的提取,下面代码示例演示提取所有入口文件公用的模块,将其独立打包:
1
2
3
4
5
6
7
8
9
var chunks = Object.keys(entries);
plugins: [
new CommonsChunkPlugin({
name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk
chunks: chunks,
minChunks: chunks.length // 提取所有entry共同依赖的模块
})
]

  • webpack提供了强大的热更新支持,即HMR(hot module replace)。HMR简单说就是webpack启动一个本地webserver(webpack-dev-server),负责处理由webpack生成的静态资源请求。注意webpack-dev-server是把所有资源存储在内存的,所以你会发现在本地没有生成对应的chunk访问却正常。

ref

ES6

ECMAScript 6, ECMAScript 2015

  • 受欢迎的语法糖,例如箭头函数(arrow functions)和简单的字符串插值(string interpolation)
  • 代理(proxies)和生成器(generators)

Responsive Web design

  • 灵活的基于网格的布局:在移动设备上查看页面时,如果设备的朝向从横向改为竖向时,页面布局会自动地调整并在新布局中展开内容进行显示,这就是灵活的基于网格的布局。在Twitter Bootstrap中,可以使用如下的CSS标签(tag)来实现:
  • 灵活的图像:动态调整图像的尺寸
  • Media Queries(媒介查询):这个是CSS3的特性,该特性可以通过查询媒介设备将适当的CSS返回给浏览器。Media queries are at the heart of a recent design trend called responsive web design.

Glosarry

  • MVVM (Model-View-ViewModel)
  • SPA (single-page-application)
  • Responsive Web design

Spring Portfolio

Spring Portfolio 包括多个构建于核心Spring 框架之上的框架和类库。概括地说,整个Spring Portfolio 几乎为每一个领域的Java 开发都提供了Spring 编程模型。

Projects

From configuration to security, web apps to big data – whatever the infrastructure needs of your application may be, there is a Spring Project to help you build it. Start small and use just what you need – Spring is modular by design.

Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.

Spring Boot 大量依赖于自动配置技术,它能消除大部分 Spring 配置。它还提供了多个 Starter 项目,不管你使用 Maven 还是 Gradle,这都能减少 Spring 工程构建文件的大小。

Spring Cloud

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry.

Spring Data

Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.

It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. This is an umbrella project which contains many subprojects that are specific to a given database. The projects are developed by working together with many of the companies and developers that are behind these exciting technologies.

不管你使用文档数据库,如 MongoDB;图数据库,如 Neo4j;还是传统的关系型数据库,Spring Data 都为持久化提供了一种简单的编程模型。这包括为多种数据库类型提供了一种自动化的 Repository 机制,它负责为你创建 Repository 的实现。

Spring Security

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

为 Spring 应用提供了声明式的安全机制。

Spring Integration

Extends the Spring programming model to support the well-known Enterprise Integration Patterns. Spring Integration enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters. Those adapters provide a higher-level of abstraction over Spring’s support for remoting, messaging, and scheduling. Spring Integration’s primary goal is to provide a simple model for building enterprise integration solutions while maintaining the separation of concerns that is essential for producing maintainable, testable code.

提供了多种通用应用集成模式的 Spring 声明式风格实现。

Spring for Apache Kafka

The Spring for Apache Kafka (spring-kafka) project applies core Spring concepts to the development of Kafka-based messaging solutions. It provides a “template” as a high-level abstraction for sending messages. It also provides support for Message-driven POJOs with @KafkaListener annotations and a “listener container”. These libraries promote the use of dependency injection and declarative. In all of these cases, you will see similarities to the JMS support in the Spring Framework and RabbitMQ support in Spring AMQP.

Spring AMQP

The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. It provides a “template” as a high-level abstraction for sending and receiving messages. It also provides support for Message-driven POJOs with a “listener container”. These libraries facilitate management of AMQP resources while promoting the use of dependency injection and declarative configuration. In all of these cases, you will see similarities to the JMS support in the Spring Framework.

The project consists of two parts; spring-amqp is the base abstraction, and spring-rabbit is the RabbitMQ implementation.

Spring Web Services

Spring Web Services (Spring-WS) is a product of the Spring community focused on creating document-driven Web services. Spring Web Services aims to facilitate contract-first SOAP service development, allowing for the creation of flexible web services using one of the many ways to manipulate XML payloads. The product is based on Spring itself, which means you can use the Spring concepts such as dependency injection as an integral part of your Web service.

提供了契约优先的 Web Service 模型,服务的实现都是为了满足服务的契约而编写的。

Spring HATEOAS

Spring HATEOAS provides some APIs to ease creating REST representations that follow the HATEOAS principle when working with Spring and especially Spring MVC. The core problem it tries to address is link creation and representation assembly.

Spring REST Docs

Spring REST Docs helps you to document RESTful services.

It combines hand-written documentation written with Asciidoctor and auto-generated snippets produced with Spring MVC Test. This approach frees you from the limitations of the documentation produced by tools like Swagger.

It helps you to produce documentation that is accurate, concise, and well-structured. This documentation then allows your users to get the information they need with a minimum of fuss.

Spring Batch

A lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operations of enterprise systems.

Spring Batch provides reusable functions that are essential in processing large volumes of records, including logging/tracing, transaction management, job processing statistics, job restart, skip, and resource management. It also provides more advanced technical services and features that will enable extremely high-volume and high performance batch jobs through optimization and partitioning techniques. Simple as well as complex, high-volume batch jobs can leverage the framework in a highly scalable manner to process significant volumes of information.

如果需要开发一个批处理应用,可以通过 Spring Batch,使用 Spring 强大的面向 POJO 的编程模型。

Spring Web Flow

Spring Web Flow builds on Spring MVC and allows implementing the “flows” of a web application. A flow encapsulates a sequence of steps that guide a user through the execution of some business task. It spans multiple HTTP requests, has state, deals with transactional data, is reusable, and may be dynamic and long-running in nature..

建立于 Spring MVC 框架之上,它为基于流程的会话式 Web 应用提供支持。

Spring Cloud Data Flow

Spring Cloud Data Flow is a toolkit for building data integration and real-time data processing pipelines.

Pipelines consist of Spring Boot apps, built using the Spring Cloud Stream or Spring Cloud Task microservice frameworks. This makes Spring Cloud Data Flow suitable for a range of data processing use cases, from import/export to event streaming and predictive analytics.

Spring Session

Spring Session provides an API and implementations for managing a user’s session information.

ref

LeetCode - Algorithms - 98. Validate Binary Search Tree

The solution of wikipedia is the elegant answer to this question. It finally passed on LeetCode after I modified and submited six times.

Sometimes we already have a binary tree, and we need to determine whether it is a BST. This problem has a simple recursive solution.

Essentially we keep creating a valid range (starting from [MIN_VALUE, MAX_VALUE]) and keep shrinking it down for each node as we go down recursively.

Problem

Given a binary tree, determine if it is a valid binary search tree (BST).

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBST(root,Long.MIN_VALUE,Long.MAX_VALUE);
}

public boolean isValidBST(TreeNode root, long minKey, long maxKey) {
if (root==null) return true;
if (root.val<=minKey || root.val>=maxKey) return false;
return isValidBST(root.left,minKey,root.val) && isValidBST(root.right,root.val,maxKey);
}
}

Submission Detail

  • 75 / 75 test cases passed.
  • Runtime: 0 ms
  • Your runtime beats 100.00 % of java submissions.

ref