tonglin0325的个人主页

JavaScript排序算法——希尔排序

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>希尔排序</title>
<!--<link rel="stylesheet" type="text/css" href="../style/fdt.css" />-->
<script type="text/javascript" src="../js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../js/jquery.easydrag.handler.beta2.js"></script>
<script type="text/javascript">

$(document).ready(
function() {

var array_1 = [9,8,7,6,5,4,3,2,1];
alert(array_1);
/*shellSort*/
alert(shellSort(array_1));

}
);



</script>

<style type="text/css">

* { padding:0; margin:0; }

body {
padding: 100px;
font-size: 15px;
}




</style>


<script type="text/javascript">
function shellSort(array){
var stepArr = [1031612713, 217378076, 45806244, 9651787, 2034035, 428481, 90358, 19001, 4025, 1750, 836, 701, 301, 132, 57, 23, 10, 4, 1]; // reverse() 在维基上看到这个最优的步长 较小数组
var i = 0;
var stepArrLength = stepArr.length;
var len = array.length;
var len2 = parseInt(len/2);

for(;i < stepArrLength; i++){
if(stepArr[i] > len2){
continue;
}
stepSort(stepArr[i]);
}
// 排序一个步长
function stepSort(step){

//console.log(step) 使用的步长统计

var i = 0, j = 0, f, tem, key;


for(;i < step; i++){// 依次循环列
for(j=1; step * j + i < len; j++){//依次循环每列的每行
tem = f = step * j + i;
key = array[f];
while((tem-=step) >= 0){// 依次向上查找 <-
// <----
// <-------

if(array[tem] > key){
array[tem+step] = array[tem];
}else{
break;
}
}
array[tem + step ] = key;
}
}

}

return array;

}


</script>


</head>




<body>
希尔排序
</body>
</html>

 

JavaScript排序算法——归并排序

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
80
81
82
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>归并排序</title>
<!--<link rel="stylesheet" type="text/css" href="../style/fdt.css" />-->
<script type="text/javascript" src="../js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../js/jquery.easydrag.handler.beta2.js"></script>
<script type="text/javascript">

$(document).ready(
function() {

var array_1 = [9,8,7,6,5,4,3,2,1];
alert(array_1);
/*mergeSort*/
//迭代实现
alert(mergeSort(array_1));

}
);



</script>

<style type="text/css">

* { padding:0; margin:0; }

body {
padding: 100px;
font-size: 15px;
}




</style>


<script type="text/javascript">
function merge(left,right){
var result=[];
while(left.length>0 &amp;&amp; right.length>0){
if(left[0]<right[0]){
result.push(left.shift());
}else{
result.push(right.shift());
}
}
alert(" left="+left+" right"+right+" result="+result);
alert(result.concat(left).concat(right));
return result.concat(left).concat(right);
}

function mergeSort(items){
if(items.length == 1){
return items;
}
var middle=Math.floor(items.length/2),
left=items.slice(0,middle),
right=items.slice(middle);
alert(" middle="+middle+" items.length="+items.length+" left="+left+" right"+right+" items"+items);
return merge(mergeSort(left),mergeSort(right));
}



</script>


</head>




<body>
归并排序
</body>
</html>

 

JavaScript排序算法——插入排序

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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>插入</title>
<!--<link rel="stylesheet" type="text/css" href="../style/fdt.css" />-->
<script type="text/javascript" src="../js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../js/jquery.easydrag.handler.beta2.js"></script>
<script type="text/javascript">

$(document).ready(
function() {

var array_1 = [9,8,7,6,5,4,3,2,1];
alert(array_1);
/*insertSort*/
alert(insertSort(array_1));
}
);

</script>


<script type="text/javascript">
function insertSort(array){
var i = 1,j, step, key, len = array.length;

for (; i < len; i++) {

step = j = i;
key = array[j];

while (--j > -1) {
if (array[j] > key) {
array[j + 1] = array[j];
}
else {
break;
}
}
array[j + 1] = key;
}
return array;
}

</script>



<style type="text/css">

* { padding:0; margin:0; }

body {
padding: 100px;
font-size: 15px;
}




</style>

</head>




<body>
快速排序
</body>
</html>

 

JavaScript排序算法——快速排序

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>快速排序</title>
<!--<link rel="stylesheet" type="text/css" href="../style/fdt.css" />-->
<script type="text/javascript" src="../js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../js/jquery.easydrag.handler.beta2.js"></script>
<script type="text/javascript">

$(document).ready(
function() {

var array_1 = [4,5,3,1,2];
alert(array_1);
/*quickSort*/
alert(quickSort(array_1));

}
);



</script>

<style type="text/css">

* { padding:0; margin:0; }

body {
padding: 100px;
font-size: 15px;
}




</style>


<script type="text/javascript">
function quickSort(array){
//var array = [8,4,6,2,7,9,3,5,74,5];
//var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7];
var i = 0;
var j = array.length - 1;
var Sort = function(i, j){

// 结束条件
if(i == j ){ return };

var key = array[i];
var stepi = i; // 记录开始位置
var stepj = j; // 记录结束位置

while(j > i){
alert(array);
// j <<-------------- 向前查找
if(array[j] >= key){
j--;
}else{
array[i] = array[j]
//i++ ------------>>向后查找
while(j > ++i){
if(array[i] > key){
array[j] = array[i];
break;
}
}
}
}

alert(array);
alert("i="+i+",j="+j+",stepi="+stepi+",stepj="+stepj);

// 如果第一个取出的 key 是最小的数
if(stepi == i){
Sort(++i, stepj);
return ;
}

// 最后一个空位留给 key
array[i] = key;

// 递归
Sort(stepi, i);
Sort(j, stepj);
}

Sort(i, j);

return array;
}


</script>


</head>




<body>
快速排序
</body>
</html>

 

JavaScript排序算法——选择排序

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
80
81
82
83
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>选择排序</title>
<!--<link rel="stylesheet" type="text/css" href="../style/fdt.css" />-->
<script type="text/javascript" src="../js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="../js/jquery.easydrag.handler.beta2.js"></script>
<script type="text/javascript">

$(document).ready(
function() {

var array_1 = [9,8,7,6,5,4,3,2,1];
alert(array_1);
/*selectionSort*/
alert(selectionSort(array_1));

}
);



</script>

<style type="text/css">

* { padding:0; margin:0; }

body {
padding: 100px;
font-size: 15px;
}




</style>


<script type="text/javascript">
function selectionSort(array){
var len = array.length;
var index = 0;
var k;
var item;
var c;
for(var i=0; i<len; i++){

//最小的数
item = array[i];
//最小的数的位置编号
index = i;
//寻找最小的数位置
for(j=i+1; j<len;j++){
if(array[j] < item){
index = j;
item = array[j];
}
}
if(index != i){
c = array[i];
array[i] = array[index];
array[index] = c;
}
}
return array;
}


</script>


</head>




<body>
选择排序
</body>
</html>

 

Ubuntu16.04安装opentsdb2.4.1

官方文档

1
2
https://github.com/OpenTSDB/opentsdb/wiki/Installation-on-Cloudera-Virtual-Machine

opentsdb的安装依赖Hbase,本文中使用的是CDH5.16.2中的Hbase 1.2.0+cdh5.16.2

1.git clone

1
2
git clone https://github.com/OpenTSDB/opentsdb.git

2.安装

1
2
3
4
cd opentsdb
./build.sh
env COMPRESSION=none HBASE_HOME=/opt/cloudera/parcels/CDH/lib/hbase ./src/create_table.sh

如果Hbase启用了kerberos,则需要先认证

1
2
kinit -kt ~/下载/hbase.keytab hbase/master@HADOOP.COM

上面的脚本会在hbase中初始化4张table

全文 >>

jQuery学习笔记——弹出对话框

引用jQuery库文件的

go学习笔记——gorm

gen是gorm官方推出的一个GORM代码生成工具

官方文档:https://gorm.io/zh_CN/gen/

1.使用gen框架生成model和dao

安装gorm gen

1
2
go get -u gorm.io/gen

假设有如下用户表

1
2
3
4
5
6
7
8
CREATE TABLE user
(
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`username` varchar(128) NOT NULL COMMENT '用户名',
`email` varchar(128) NOT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

在cmd目录下创建gen/generate.go文件

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
package main

import (
"fmt"

"gorm.io/driver/mysql"
"gorm.io/gen"
"gorm.io/gorm"
)

const MySQLDSN = "root:123456@tcp(127.0.0.1:55000)/default?charset=utf8mb4&amp;parseTime=True"

func connectDB(dsn string) *gorm.DB {
db, err := gorm.Open(mysql.Open(dsn))
if err != nil {
panic(fmt.Errorf("connect mysql fail: %w", err))
}
return db
}

func main() {
// 指定生成代码的具体相对目录(相对当前文件),默认为:./query
// 默认生成需要使用WithContext之后才可以查询的代码,但可以通过设置gen.WithoutContext禁用该模式
g := gen.NewGenerator(gen.Config{
// 默认会在 OutPath 目录生成CRUD代码,并且同目录下生成 model 包
// 所以OutPath最终package不能设置为model,在有数据库表同步的情况下会产生冲突
// 若一定要使用可以通过ModelPkgPath单独指定model package的名称
OutPath: "./internal/dao",
ModelPkgPath: "./internal/model",

// gen.WithoutContext:禁用WithContext模式
// gen.WithDefaultQuery:生成一个全局Query对象Q
// gen.WithQueryInterface:生成Query接口
Mode: gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface,
})

// 通常复用项目中已有的SQL连接配置db(*gorm.DB)
// 非必需,但如果需要复用连接时的gorm.Config或需要连接数据库同步表信息则必须设置
g.UseDB(connectDB(MySQLDSN))

// 从连接的数据库为所有表生成Model结构体和CRUD代码
//g.ApplyBasic(g.GenerateAllTable()...)

// 也可以手动指定需要生成代码的数据表
//g.ApplyBasic(g.GenerateModel("user"), g.GenerateModel("role"))

// 还可以指定只生成model
var models = [...]string{"user"}
for _, tableName := range models {
// 只生成model
g.GenerateModel(tableName)
// 生成model和query
//tableModel := g.GenerateModel(tableName)
//g.ApplyBasic(tableModel)
}

//g.ApplyInterface(func(model.Filter) {}, g.GenerateModel("user"))
// 执行并生成代码
g.Execute()
}

运行generate.go,将会生成model和dao文件

需要注意mysql的tinyint(1)生成的时候会映射成bool,但是tinyint(1)的实际范围为-128~127,这可能会有些问题;而tinyint(4)生成的时候会映射成int32

2.gorm框架CRUD

1.insert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func init() {
SetDefault(database.DB)
}

func Test_userDo_Create(t *testing.T) {
user := model.User{
Username: "test",
Email: "test@test",
}
err := User.Create(&amp;user)
if err != nil {
fmt.Println("create user fail")
}
}

2.delete

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func Test_userDo_Delete(t *testing.T) {
/*
user := model.User{
ID: 1,
}
result, err := User.Delete(&amp;user)
*/
result, err := User.Where(User.ID.Eq(2)).Delete()
if err != nil {
fmt.Println("delete user fail")
}
fmt.Println(result)
}

3.update

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func Test_userDo_Update(t *testing.T) {
/*
user := model.User{
ID: 2,
Username: "test2",
Email: "test2@test",
}
result, err := User.Updates(&amp;user)
*/
result, err := User.
Where(User.ID.Eq(2)).
Update(User.Username, "test22")

if err != nil {
fmt.Println("update user fail")
}
fmt.Println(result.RowsAffected)
}

4.select

1
2
3
4
5
6
7
8
9
func Test_userDo_Scan(t *testing.T) {
user := model.User{}
err := User.Where(User.ID.Eq(2)).Scan(&amp;user)
if err != nil {
fmt.Println("scan user fail")
}
fmt.Println(user)
}

参考:GORM Gen使用指南

5.Gorm处理可变结果集

在上面例子中使用scan获得查询结果的时候,字段的个数是固定的,如果当字段的个数是不定长度的时候,可以使用gorm来处理可变结果集

可以将**[]interface{}或者[]orm.Params**来保存查询结果,参考:Golang开发实践:把数据库数据保存到map[string]interface{}中 或者【巧妙】GO + MySQL的通用查询方法

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
func (repo *userRepo) ListUsers(ctx context.Context) (*model.User, error) {
connect, err := repo.data.db.DB()
if err != nil {
repo.log.Error(fmt.Sprintf("connect fail, error: %v", err))
return nil, err
}
rows, err := connect.Query("select * from `user`")
if err != nil {
repo.log.Error(fmt.Sprintf("query fail, error: %v", err))
return nil, err
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
return nil, err
}
values := make([]interface{}, 0)
for i := 0; i < len(cols); i++ {
var value interface{}
values = append(values, &amp;value)
}
for rows.Next() {
err = rows.Scan(values...)
if err != nil {
repo.log.Error(fmt.Sprintf("scan fail, error: %v", err))
return nil, err
}
for k, v := range values {
key := cols[k]
var rawValue = *(v.(*interface{}))
switch v := rawValue.(type) {
case string:
fmt.Print("key=>" + key + ":string ")
fmt.Print(v)
case int32:
fmt.Print("key=>" + key + ":int32 ")
fmt.Println(v)
case []uint8:
fmt.Print("key=>" + key + ",type=>uint8[],value=>")
fmt.Print(string(v))
fmt.Print(" ")
default:
fmt.Print(v)
}
}
fmt.Println()
}
return nil, nil
}

输出结果

1
2
3
4
5
6
key=>id,type=>uint8[],value=>5 key=>username,type=>uint8[],value=>test key=>email,type=>uint8[],value=>test@test 
key=>id,type=>uint8[],value=>6 key=>username,type=>uint8[],value=>test key=>email,type=>uint8[],value=>test@test
key=>id,type=>uint8[],value=>7 key=>username,type=>uint8[],value=>test key=>email,type=>uint8[],value=>test@test
key=>id,type=>uint8[],value=>8 key=>username,type=>uint8[],value=>test key=>email,type=>uint8[],value=>test@test
key=>id,type=>uint8[],value=>9 key=>username,type=>uint8[],value=>test key=>email,type=>uint8[],value=>test@test

6.分页

可以使用gorm的scopes来实现分页(先count再分页),参考:Gorm Scopes复用你的逻辑学习gorm系列十之:使用gorm.Scopes函数复用你的查询逻辑

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
func Paginate(pageNum int, pageSize int) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if pageNum <= 0 {
pageNum = 1
}
if pageSize > 100 {
pageSize = 100
} else if pageSize <= 0 {
pageSize = 10
}
offset := (pageNum - 1) * pageSize
return db.Offset(offset).Limit(pageSize)
}
}

func (repo *userRepo) ListUser(ctx context.Context, pageNum int, pageSize int) ([]*model.User, error) {
var result []*model.User
var total int64
err := repo.data.db.Model(&amp;model.User{}).Count(&amp;total).Error
if err != nil {
repo.log.Error(fmt.Sprintf("list user fail, error: %v", err))
}
err = repo.data.db.Scopes(Paginate(pageNum, pageSize)).Find(&amp;result).Error
if err != nil {
repo.log.Error(fmt.Sprintf("update user fail, error: %v", err))
return nil, err
}
return result, nil
}

测试分页函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func Test_userRepo_ListUsers(t *testing.T) {
data, _, err := NewData(zap_logger, db, rdb)
if err != nil {
panic(err)
}
userRepo := userRepo{data: data, log: zap_logger}
result, err := userRepo.ListUser(context.Background(), 1, 5)
if err != nil {
fmt.Println(err)
}
for _, user := range result {
fmt.Println(user)
}
}

输出

1
2
3
4
5
6
&amp;{5 test test@test}
&amp;{6 test test@test}
&amp;{7 test test@test}
&amp;{8 test test@test}
&amp;{9 test test@test}

Mybatis Page Helper分页插件原理:Mybatis分页插件PageHelper的配置和使用方法

3.gorm框架自定义SQL

gorm还支持编写sql模板,来添加自定义sql的函数逻辑,其中使用的语法是text template,可以参考:

全文 >>