标准SQL下分区函数Partition By结合row_number()的用法,以及排序rank()的用法详解(转)

 数据库  标准SQL下分区函数Partition By结合row_number()的用法,以及排序rank()的用法详解(转)已关闭评论
10月 222020
 
网上看到的一篇文章: 描述分区函数Partition By结合row_number()的用法,以及排序rank()的用法
,比如获取分组(分区)中前几条记录。

partition by关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组,分区函数一般与排名函数一起使用。

准备测试数据:

复制代码
create table Student  --学生成绩表
(
 id int,  --主键
 Grade int, --班级
 Score int --分数
)
go

insert into Student values(1,1,88)
insert into Student values(2,1,66)
insert into Student values(3,1,75)
insert into Student values(4,2,30)
insert into Student values(5,2,70)
insert into Student values(6,2,80)
insert into Student values(7,2,60)
insert into Student values(8,3,90)
insert into Student values(9,3,70)
insert into Student values(10,3,80)
insert into Student values(11,3,80)
复制代码

一、分区函数Partition By的与row_number()的用法

1、不分班按学生成绩排名

select *,row_number() over(order by Score desc) as Sequence from Student

执行结果:

2、分班后按学生成绩排名

select *,row_number() over(partition by Grade order by Score desc) as Sequence from Student

执行结果:

3、获取每个班的前1(几)名

select * from
(
select *,row_number() over(partition by Grade order by Score desc) as Sequence from Student
)T where T.Sequence<=1

执行结果:

 

二、分区函数Partition By与排序rank()的用法

1、分班后按学生成绩排名 该语句是对分数相同的记录进行了同一排名,例如:两个80分的并列第2名,第4名就没有了

select *,rank() over(partition by Grade order by Score desc) as Sequence from Student

执行结果:

2、获取每个班的前2(几)名 该语句是对分数相同的记录进行了同一排名,例如:两个80分的并列第2名,第4名就没有了

select * from
(
select *,rank() over(partition by Grade order by Score desc) as Sequence from Student
)T where T.Sequence<=2

执行结果:

kotlin下 “android.os.NetworkOnMainThreadException” 或 “Only the original thread that created a view hierarchy can touch its views” 解决

 开发  kotlin下 “android.os.NetworkOnMainThreadException” 或 “Only the original thread that created a view hierarchy can touch its views” 解决已关闭评论
9月 272020
 

kotlin下使用协程时,出现错误提示android.os.NetworkOnMainThreadException 或 Only the original thread that created a view hierarchy can touch its views, 可以使用下面的方法解决:

 

1. 使用协程需build.gradle先加入

dependencies {

implementation “org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9”
}

 

2.  套用下面的模版:

GlobalScope.launch {
    //TODO("Background processing...")
    withContext(Dispatchers.Main) {
        // TODO("Update UI here!")
    }
    TODO("Continue background processing...")
}

PM2 如何优雅的重新加载配置文件(How to gracefully reload JSON/JS file)

 Nodejs  PM2 如何优雅的重新加载配置文件(How to gracefully reload JSON/JS file)已关闭评论
9月 102020
 

PM2使用配置文件启动,但如果修改了配置文件,使用如下命令几乎都无效(invalid)

  1. pm2 restart config.js
  2. pm2 reload config.js

似乎只有下面的粗暴方法才有效(roughly):

  1. pm2 kill
  2. pm2 start config.js

 

其实可以使用下面的命令实现优雅的重载配置文件(gracefully reload config JSON/JS file)

pm2 startOrReload config.js –update-env

 

备注:

pm2 -h 可以看到参数startOrReload , –update-env的解释:

–update-env     

force an update of the environment with restart/reload (-a <=> apply)

 

startOrReload <json>

start or gracefully reload JSON file

9个提升逼格的redis命令(keys,scan,slowlog,rename-command,bigkeys,monitor,info,config,set)

 redis  9个提升逼格的redis命令(keys,scan,slowlog,rename-command,bigkeys,monitor,info,config,set)已关闭评论
9月 082020
 

9个提升逼格的redis命令

非常好的文章,特别是使用bigkeys查找占大内存的key真是方便,推荐https://www.jianshu.com/p/4df5f2356de9

keys

我把这个命令放在第一位,是因为笔者曾经做过的项目,以及一些朋友的项目,都因为使用keys这个命令,导致出现性能毛刺。这个命令的时间复杂度是O(N),而且redis又是单线程执行,在执行keys时即使是时间复杂度只有O(1)例如SET或者GET这种简单命令也会堵塞,从而导致这个时间点性能抖动,甚至可能出现timeout。

强烈建议生产环境屏蔽keys命令(后面会介绍如何屏蔽)。

scan

既然keys命令不允许使用,那么有什么代替方案呢?有!那就是scan命令。如果把keys命令比作类似select * from users where username like '%afei%'这种SQL,那么scan应该是select * from users where id>? limit 10这种命令。

官方文档用法如下:

SCAN cursor [MATCH pattern] [COUNT count]

初始执行scan命令例如scan 0。SCAN命令是一个基于游标的迭代器。这意味着命令每次被调用都需要使用上一次这个调用返回的游标作为该次调用的游标参数,以此来延续之前的迭代过程。当SCAN命令的游标参数被设置为0时,服务器将开始一次新的迭代,而当redis服务器向用户返回值为0的游标时,表示迭代已结束,这是唯一迭代结束的判定方式,而不能通过返回结果集是否为空判断迭代结束。

使用方式:

127.0.0.1:6380> scan 0
1) "22"
2)  1) "23"
    2) "20"
    3) "14"
    4) "2"
    5) "19"
    6) "9"
    7) "3"
    8) "21"
    9) "12"
   10) "25"
   11) "7"

返回结果分为两个部分:第一部分即1)就是下一次迭代游标,第二部分即2)就是本次迭代结果集。

slowlog

上面提到不能使用keys命令,如果就有开发这么做了呢,我们如何得知?与其他任意存储系统例如mysql,mongodb可以查看慢日志一样,redis也可以,即通过命令slowlog。用法如下:

SLOWLOG subcommand [argument]

subcommand主要有:

  • get,用法:slowlog get [argument],获取argument参数指定数量的慢日志。
  • len,用法:slowlog len,总慢日志数量。
  • reset,用法:slowlog reset,清空慢日志。

执行结果如下:

127.0.0.1:6380> slowlog get 5
1) 1) (integer) 2
   2) (integer) 1532656201
   3) (integer) 2033
   4) 1) "flushddbb"
2) 1) (integer) 1  ----  慢日志编码,一般不用care
   2) (integer) 1532646897  ----  导致慢日志的命令执行的时间点,如果api有timeout,可以通过对比这个时间,判断可能是慢日志命令执行导致的
   3) (integer) 26424  ----  导致慢日志执行的redis命令,通过4)可知,执行config rewrite导致慢日志,总耗时26ms+
   4) 1) "config"
      2) "rewrite"

命令耗时超过多少才会保存到slowlog中,可以通过命令config set slowlog-log-slower-than 2000配置并且不需要重启redis。注意:单位是微妙,2000微妙即2毫秒。

rename-command

为了防止把问题带到生产环境,我们可以通过配置文件重命名一些危险命令,例如keys等一些高危命令。操作非常简单,只需要在conf配置文件增加如下所示配置即可:

rename-command flushdb flushddbb
rename-command flushall flushallall
rename-command keys keysys

bigkeys

随着项目越做越大,缓存使用越来越不规范。我们如何检查生产环境上一些有问题的数据。bigkeys就派上用场了,用法如下:

redis-cli -p 6380 --bigkeys

执行结果如下:

... ...
-------- summary -------

Sampled 526 keys in the keyspace!
Total key length in bytes is 1524 (avg len 2.90)

Biggest string found 'test' has 10005 bytes
Biggest   list found 'commentlist' has 13 items

524 strings with 15181 bytes (99.62% of keys, avg size 28.97)
2 lists with 19 items (00.38% of keys, avg size 9.50)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

最后5行可知,没有set,hash,zset几种数据结构的数据。string类型有524个,list类型有两个;通过Biggest ... ...可知,最大string结构的key是test,最大list结构的key是commentlist

需要注意的是,这个bigkeys得到的最大,不一定是最大。说明原因前,首先说明bigkeys的原理,非常简单,通过scan命令遍历,各种不同数据结构的key,分别通过不同的命令得到最大的key:

  • 如果是string结构,通过strlen判断;
  • 如果是list结构,通过llen判断;
  • 如果是hash结构,通过hlen判断;
  • 如果是set结构,通过scard判断;
  • 如果是sorted set结构,通过zcard判断。

正因为这样的判断方式,虽然string结构肯定可以正确的筛选出最占用缓存,也可以说最大的key。但是list不一定,例如,现在有两个list类型的key,分别是:numberlist–[0,1,2],stringlist–[“123456789123456789”],由于通过llen判断,所以numberlist要大于stringlist。而事实上stringlist更占用内存。其他三种数据结构hash,set,sorted set都会存在这个问题。使用bigkeys一定要注意这一点。

monitor

假设生产环境没有屏蔽keys等一些高危命令,并且slowlog中还不断有新的keys导致慢日志。那我们如何揪出这些命令是由谁执行的呢?这就是monitor的用处,用法如下:

redis-cli -p 6380 monitor

如果当前redis环境OPS比较高,那么建议结合linux管道命令优化,只输出keys命令的执行情况:

[[email protected] ~]# redis-cli -p 6380 monitor | grep keys 
1532645266.656525 [0 10.0.0.1:43544] "keyss" "*"
1532645287.257657 [0 10.0.0.1:43544] "keyss" "44*"

执行结果中很清楚的看到keys命名执行来源。通过输出的IP和端口信息,就能在目标服务器上找到执行这条命令的进程,揪出元凶,勒令整改。

info

如果说哪个命令能最全面反映当前redis运行情况,那么非info莫属。用法如下:

INFO [section]

section可选值有:

  • Server:运行的redis实例一些信息,包括:redis版本,操作系统信息,端口,GCC版本,配置文件路径等;
  • Clients:redis客户端信息,包括:已连接客户端数量,阻塞客户端数量等;
  • Memory:使用内存,峰值内存,内存碎片率,内存分配方式。这几个参数都非常重要;
  • Persistence:AOF和RDB持久化信息;
  • Stats:一些统计信息,最重要三个参数:OPS(instantaneous_ops_per_sec),keyspace_hitskeyspace_misses两个参数反应缓存命中率;
  • Replication:redis集群信息;
  • CPU:CPU相关信息;
  • Keyspace:redis中各个DB里key的信息;

config

config是一个非常有价值的命令,主要体现在对redis的运维。因为生产环境一般是不允许随意重启的,不能因为需要调优一些参数就修改conf配置文件并重启。redis作者早就想到了这一点,通过config命令能热修改一些配置,不需要重启redis实例,可以通过如下命令查看哪些参数可以热修改:

config get *

热修改就比较容易了,执行如下命令即可:

config set 

例如:config set slowlog-max-len 100config set maxclients 1024

这样修改的话,如果以后由于某些原因redis实例故障需要重启,那通过config热修改的参数就会被配置文件中的参数覆盖,所以我们需要通过一个命令将config热修改的参数刷到redis配置文件中持久化,通过执行如下命令即可:

config rewrite

执行该命令后,我们能在config文件中看到类似这种信息:

# 如果conf中本来就有这个参数,通过执行config set,那么redis直接原地修改配置文件
maxclients 1024
# 如果conf中没有这个参数,通过执行config set,那么redis会追加在Generated by CONFIG REWRITE字样后面
# Generated by CONFIG REWRITE
save 600 60
slowlog-max-len 100

set

set命令也能提升逼格?是的,我本不打算写这个命令,但是我见过太多人没有完全掌握这个命令,官方文档介绍的用法如下:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

你可能用的比较多的就是set key value,或者SETEX key seconds value,所以很多同学用redis实现分布式锁分为两步:首先执行SETNX key value,然后执行EXPIRE key seconds。很明显,这种实现有很严重的问题,因为两步执行不具备原子性,如果执行第一个命令后出现某些未知异常导致无法执行EXPIRE key seconds,那么分布式锁就会一直无法得到释放。

通过SET命令实现分布式锁的正式姿势应该是SET key value EX seconds NX(EX和PX任选,取决于对过期时间精度要求)。另外,value也有要求,最好是一个类似UUID这种具备唯一性的字符串。当然如果问你redis是否还有其他实现分布式锁的方案。你能说出redlock,那对方一定眼前一亮,心里对你竖起大拇指,但嘴上不会说。

Mac 上使用多点触控手势(含鼠标手势)

 mac  Mac 上使用多点触控手势(含鼠标手势)已关闭评论
8月 072020
 

在 Mac 上使用多点触控手势

使用多点触控触控板或妙控鼠标,您可以通过轻点、轻扫、捏合或开合一根或多根手指进行有用的操作。

触控板手势

有关这些手势的更多信息,请选取苹果菜单 () >“系统偏好设置”,然后点按“触控板”。您可以关闭某个手势,更改手势类型,以及了解哪些手势可在您的 Mac 上使用。

触控板手势要求使用妙控板或内建的多点触控触控板。如果您的触控板支持力度触控,您还可以进行“用力点按”操作并获得触感反馈

轻点来点按
用单指轻点来进行点按。

辅助点按(右键点按)
用双指点按或轻点。

智能缩放
用双指轻点两下可放大网页或 PDF,或缩小回原来的大小。

滚动
双指向上或向下滑动可滚动。1

放大或缩小
双指捏合或张开可放大或缩小。

旋转
双指互相以对方为中心移动,可旋转照片或其他项目。

在页面之间轻扫
双指向左或向右轻扫,可显示上一页或下一页。

打开“通知中心”
用双指从右边缘向左轻扫,可显示“通知中心”。

三指拖移
用三根手指拖移屏幕上的项目,然后点按或轻点以放下。可在“辅助功能”偏好设置中开启此功能2

 

查找和数据检测器
用三根手指轻点可查找字词,或者对日期、地址、电话号码和其他数据采取相关操作。

显示桌面
将拇指和另外三根手指同时展开,可显示桌面。

 

“启动台”
将拇指和另外三根手指合拢到一起,可显示“启动台”。

“调度中心”
用四根手指向上轻扫3,可打开“调度中心”。

应用 Exposé
用四根手指向下轻扫3,可查看正在使用的应用的所有窗口。

在全屏应用之间轻扫
用四根手指向左或向右轻扫3,可在桌面与全屏应用之间移动。

 

鼠标手势

有关这些手势的更多信息,请选取苹果菜单 () >“系统偏好设置”,然后点按“鼠标”。您可以从中关闭某个手势,更改手势类型,以及了解哪些手势可在您的 Mac 上使用。鼠标手势要求使用妙控鼠标

辅助点按(右键点按)
点按鼠标的右侧。

滚动
单指向上或向下滑动可滚动。1

智能缩放
用单指轻点两下可放大网页或 PDF,或缩小回原来的大小。

“调度中心”
用双指轻点两下,可打开“调度中心”。

在全屏应用之间轻扫
用双指向左或向右轻扫,可在桌面与全屏应用之间移动。

在页面之间轻扫
用单指向左或向右轻扫,可显示上一页或下一页。

1. 您可以在“辅助功能”偏好设置中关闭触控板滚动功能:选取苹果菜单 >“系统偏好设置”,然后点按“辅助功能”。在“鼠标与触控板”部分中,点按“触控板选项”,然后取消选择“滚动”复选框。

2.“辅助功能”偏好设置还包含单指拖移的选项:选取苹果菜单 >“系统偏好设置”,然后点按“辅助功能”。在“鼠标与触控板”部分中,点按“触控板选项”。选择“启用拖移”,然后从弹出式菜单中选取一个“拖移锁定”选项。点按问号按钮可了解有关每个选项的更多信息。

3. 在某些版本的 macOS中,这个手势使用的是三根手指,而不是四根。

 

转自苹果官网:https://support.apple.com/zh-cn/HT204895

sublimeREPL下python 2 切换为 python 3

 python, sublime  sublimeREPL下python 2 切换为 python 3已关闭评论
7月 202020
 

转自:https://www.jianshu.com/p/41df9da08f60

1、安装python3

 

$ brew search python
$ brew install python3

这里安装完后不需要单独添加环境变量,程序已经处理好,可以直接运行python3命令。

$ which python
/usr/bin/python

$ which python3
/Library/Frameworks/Python.framework/Versions/3.6/bin/python3

$ echo $PATH
/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

2、安装REPL插件,并设置快捷键绑定。

打开后,搜索 SublimeREPL 安装即可。

设置快捷键:

Preferences -> Key Bindings

[   
    {"keys":["f1"],
    "caption": "SublimeREPL: Python - RUN current file",
    "command": "run_existing_window_command", "args":
    {"id": "repl_python_run",
    "file": "config/Python/Main.sublime-menu"}},

    {"keys":["f2"],
    "caption": "SublimeREPL: Python",
    "command": "run_existing_window_command", "args":
    {"id": "repl_python",
    "file": "config/Python/Main.sublime-menu"}}
]

这里我设置的 F1 运行代码,F2 打开终端。

3、按 F2 运行终端,发现默认集成的是 python2,手动改成 pyhton3,方法如下:

$ sudo find / -iname 'Main.sublime-menu'
$ vim /Users/keithtt/Library/Application\ Support/Sublime\ Text\ 3/Packages/SublimeREPL/config/Python/Main.sublime-menu

"cmd": ["python3", "-i", "-u"],
"cmd": ["python3", "-i", "-u", "-m", "pdb", "$file_basename"],
"cmd": ["python3", "-u", "$file_basename"],
"cmd": {
    "osx": ["python3", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"],
    "linux": ["python3", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"],
    "windows": ["python3", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"]
},

将该文件中调用 python 命令的地方全部改成 python3 即可。

改完之后再次按 F2 运行终端,效果如下:

centos 7 中文乱码问题解决

 centos  centos 7 中文乱码问题解决已关闭评论
6月 082020
 

使用aws的centos ec2, 今天编辑一个文件,发现copy进去的中文字变乱码了,原来需要将默认的en_US.UTF-8编码修改为zh_CN中文编码,操作步骤如下:

1.查看安装中文包:

查看系统是否安装中文语言包 (列出所有可用的公共语言环境的名称,包含有zh_CN)

# locale -a |grep "zh_CN"

没有输出,说明没有安装,输入下面的命令安装:

# yum groupinstall "fonts" -y

安装完成,查看安了哪些中文语言包

# locale -a |grep "zh_CN"
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8

说明系统已安装中文语言包,无需再安装。重要提示,如果按照下面的步骤你的系统仍然无法使用中文,那么请一个一个尝试上面的编码方式。比如把LANG=”zh_CN”修改为LANG=”zh_CN.gb18030″。

2.修改配置文件:

在修改配置文件之前,我们先看看当前系统语言环境:

# echo $LANG
en_US.UTF-8

# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

虽然安装了中文语言包但本机的语言环境并不是中文,需要修改locale.conf配置文件:

# vim /etc/locale.conf
LANG="zh_CN"
# source   /etc/locale.conf

也可以使用命令修改locale.conf配置文件:

#  localectl set-locale LANG=zh_CN

之后查看当前语言环境:

# echo $LANG
zh_CN

# locale
LANG=zh_CN
LC_CTYPE="zh_CN"
LC_NUMERIC="zh_CN"
LC_TIME="zh_CN"
LC_COLLATE="zh_CN"
LC_MONETARY="zh_CN"
LC_MESSAGES="zh_CN"
LC_PAPER="zh_CN"
LC_NAME="zh_CN"
LC_ADDRESS="zh_CN"
LC_TELEPHONE="zh_CN"
LC_MEASUREMENT="zh_CN"
LC_IDENTIFICATION="zh_CN"
LC_ALL=

3. 验证是否成功:

[[email protected] ~]# date
2020年 06月 08日 星期一 11:26:03 CST

centos7下让zookeeper开机自启动

 centos  centos7下让zookeeper开机自启动已关闭评论
5月 202020
 

centos 7下zookeeper开机自启动

1将ZooKeeper设置为开机启动
1.1在init.d目录下新建脚本文件
进入到/etc/rc.d/init.d目录下,命令是:

cd    /etc/rc.d/init.d

新建一个名为zookeeper的文件,命令是:

touch    zookeeper

 

1.1.1文件内容的第一种方案(推荐)
使用vim命令修改文件内容,文件内容的写法有很多,除了上面的第一种方案,用下面的这种也可以:

#!/bin/bash
#chkconfig: 2345 10 90
#description: service zookeeper
export JAVA_HOME=/opt/java/jdk1.8.0_121
export ZOO_LOG_DIR=/opt/zookeeper/log
ZOOKEEPER_HOME=/opt/zookeeper/zookeeper-3.4.10
su root ${ZOOKEEPER_HOME}/bin/zkServer.sh “$1”

3.1.2文件内容的第二种方案
使用vim命令修改文件内容,文件内容是:

#!/bin/bash
#chkconfig: 2345 10 90
#description: service zookeeper
export JAVA_HOME=/opt/java/jdk1.8.0_121
export ZOO_LOG_DIR=/opt/zookeeper/log
ZOOKEEPER_HOME=/opt/zookeeper/zookeeper-3.4.10
case “$1” in
start) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh start;;
start-foreground) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh start-foreground;;
stop) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh stop;;
status) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh status;;
restart) su root ${ZOOKEEPER_HOME}/bin/zkServer.sh restart;;
upgrade)su root ${ZOOKEEPER_HOME}/bin/zkServer.sh upgrade;;
print-cmd)su root ${ZOOKEEPER_HOME}/bin/zkServer.sh print-cmd;;
*) echo “requirestart|start-foreground|stop|status|restart|print-cmd”;;
esac

1.1.3 其他说明
注意1:新建文件的命令是touch,编辑文件的命令用vi和vim都行。如果不会使用vi和vim命令,直接在本地把文件编辑好,然后用远程工具上载上去都行,不过需要注意的是如果本地用的windows系统,需要把文件转为UNIX格式。转换工具有很多,例如使用Notepad++

注意2:两个方案中的文件头部#注释的部分不能少,而且文件中诸如JDK路径,zookeeper路径都需要修改为你自己的。

1.2 执行一系列命令
为新建的/etc/rc.d/init.d/zookeeper文件添加可执行权限,命令是:

chmod  +x  /etc/rc.d/init.d/zookeeper

把zookeeper这个脚本添加到开机启动项里面,命令是:

chkconfig  –add   zookeeper

 

如果想看看是否添加成功,命令是:

chkconfig  –list

 

1.3执行测试看是否开机启动
使用命令重启机器,命令是:

reboot

方法一

查看zookeeper的状态

重启机器,然后不手动启动zookeeper的情况下,执行命令:

service  zookeeper   status

 

方法二

查看2181端口是否启用,执行命令:

lsof  -i:2181

 

方法三

查看网络状态,执行命令:

netstat   -lntup

 

 

2报错及解决
2.1 service zookeeper does not support chkconfig
执行chkconfig  –add  zookeeper报错:

servicezookeeper does not support chkconfig

问题原因和解决:

/etc/rc.d/init.d/ zookeeper脚本中头部没有添加下面这几句话(description可以随便写):

#!/bin/bash
#chkconfig:2345 10 90
#description:service zookeeper

2.2Error contacting service. It is probably not running
执行service  zookeeper  status报错:

JMX enabled by default

Usingconfig: /opt/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg

Errorcontacting service. It is probably not running.

 

问题原因和解决:

/etc/rc.d/init.d/ zookeeper没有配置对,请看3.1.1和3.1.2的配置,里面必须要有export  JAVA_HOME这一句话,后面的路径是你自己的JDK安装路径。

至于export    ZOO_LOG_DIR=/opt/zookeeper/log这一句的话可有可无,意思是指定zookeeper的启动日志存放目录,如果该目录不存在,你必须手动创建一个。

 

原文链接:https://blog.csdn.net/pucao_cug/java/article/details/71240246

python 2中希望使用print时将\uxxxx的文字打印为中文

 python  python 2中希望使用print时将\uxxxx的文字打印为中文已关闭评论
5月 092020
 

在python 2里使用print打印含有\uxxx的中文字符时不能直接显示中文,可以使用下面的方式:

举例:

obj = [u’\u53c8\u6765\u5077\u5077\u770b\u6211′,u’\u7231\u6211\u4f60\u5c31\u544a\u8bc9\u6211′]

使用: print(repr(obj).decode(‘unicode-escape’))

 

obj=[‘又来偷偷看我’,’爱我你就告诉我’]

使用:print(repr(obj).decode(‘string-escape’))

 

python 3 没有这个问题

linux下使用自己安装的oracle JDK替换默认的OpenJDK

 java  linux下使用自己安装的oracle JDK替换默认的OpenJDK已关闭评论
4月 272020
 

在linux系统中,由于涉及到版权问题,在大部分linux系统的发行版本中,默认都安装了OpenJDK,并且OpenJDK的java命令也已经加入到环境变量中了。

在刚装好的linux系统中,运行java -version,输出如下(根据JDK版本不同,输出的版本可能不同):

java version “1.7.0_131”
OpenJDK Runtime Environment (rhel-2.6.9.0.el6_8-x86_64 u131-b00)

但在进行java开发时,我们大多是需要使用Sun(准确的说应该是Oracle)的JDK,所以我们会去Oracle官网下载相应版本的JDK进行安装。

如何在linux上安装,在此不在赘述。

在linux上安装完JDK后,我们会在~/.bash_profile 把安装的java加入到环境变量中。原以为就万事大吉了,在运行java程序时会使用自己安装的JDK。

如果你是这么想的就大错特错了,在文章开头讲的,由于linux系统的发行版中默认安装的时OpenJDK,尽管我们把安装的SunJDK的java命令也加入到环境变量中,但是我们运行

java -version,输出确还是和之前一样:

java version “1.7.0_131”
OpenJDK Runtime Environment (rhel-2.6.9.0.el6_8-x86_64 u131-b00)

这要这么破!!!

一、查找原因

不急,先运行

whereis java,输出如下:
java: /usr/bin/java /etc/java /usr/lib/java /usr/share/java /opt/java/bin/java

在几个地方有java命令,其中/opt/java/bin/java是我自己安装的SunJDK的java命令所在的目录,而/usr/bin/java是系统中默认安装的java命令所在的目录。

原因就在这,

我们执行

ls -la /usr/bin/java,输入如下:

lrwxrwxrwx 1 root root 22 May 14 16:53 /usr/bin/java -> /etc/alternatives/java

一看这是一个软连接,我们cd到/etc/alternatives目录下看个究竟,

然后执行 ls -la,输入比较多,而且很多软链,其中有一个

lrwxrwxrwx  1 root root   46 May 14 18:22 java -> /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java

到此,应该明白了,java命令其实指向的是OpenJDK中的java命令,所以才会出现我们把自己安装的SunJDK的java命令配置到环境变量中后,依然不起作用。

所以我们要做的就是需要把java的软链指向我们自己安装的SunJDK的java命令,也即/opt/java/bin/java。

二、使用安装的JDK替代系统默认的OpenJDK

linux中提供了update-alternatives命令,update-alternatives是linux系统(大部分linux系统都支持此命令)中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令、哪个软件版本,而所有的这些就构成了备选方案系统(alternatives system)。

很多时候我们会将拥有相同或相似功能的不同应用程序安装在同一个操作系统上,例如同一个操作系统上的不同文本编辑器。这给了这个系统的用户在编辑文本时有了更多的选择,如果用户愿意他们可以自由选择任意一个来使用。

其实update-alternatives命令的功能很好理解,举个例子:在Window系统中,如果我们安装多个浏览器,比如有火狐、有IE、有360、有Chrome等,当我们从某个链接进去打开网页时,可能会问你使用哪个浏览器,当你选择某个浏览器时,此浏览器会问你是否把它作为默认浏览器,如果你选择了是,那下次点开某个链接时,就直接使用默认浏览器打开了!

现在我们在系统中同时安装了open jdk和sun jdk两个版本,(由于linux发行版本中默认使用OpenJDK的java命令 )而我们又希望系统默认使用的是sun jdk,那怎么办呢?通过update-alternatives就可以很方便的实现了。

首先运行以下命令查看java当前的默认配置

update-alternatives –display java,输出如下(后面有省略):
java – status is manual.
link currently points to /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java – priority 170131
slave keytool: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/keytool
slave orbd: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/orbd
……

可以从输出中看到系统中java默认使用的OpenJDK,其中数字170131表示优先级。

2.1 下面进入正式配置阶段

1. 把自己安装的SunJDK加入到备选系统中

运行命令(注意命令最后的数字表示优先级,其中170130 为SunJDK的alternative的优先级)

update-alternatives  –install /usr/bin/java java /opt/java/bin/java 170130

2. 选择自己安装的SunJDK作为首选java命令

运行命令

update-alternatives –config java,输出如下

There are 2 programs which provide ‘java’.

Selection    Command
———————————————–
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
2           /opt/java/bin/java

Enter to keep the current selection[+], or type selection number:

config命令是交互式的命令,可以根据提示进行选择,此处我们选择2,即使用安装的SunJDK的java命令,然后按回车键!

至此,配置完成了!

说明:在配置步骤1中,我们指定SunJDK的优先级是170130(比当前优先级170131低),所以需要进行步骤二进行手动选择;如果我们指定的优先级比当前优先级170131高,则步骤二可以省略,系统自动会选择优先级高的作为默认alternative!

关于update-alternatives命令更详细的说明,请参照

1.http://www.cnblogs.com/pengdonglin137/p/3462492.html

2. http://www.mamicode.com/info-detail-1144825.html

3. http://persevere.iteye.com/blog/1479524

原文链接:https://blog.csdn.net/rj042/java/article/details/72034650

mybatis中#和$的区别

 mybatis, 开发  mybatis中#和$的区别已关闭评论
4月 232020
 

mybatis写sql语句时会看到#{}, ${}的写法,有什么区别呢?

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。

2. $将传入的数据直接显示生成在sql中。如:select * from ${table};

3. #方式能够很大程度防止sql注入。

4.$方式无法防止Sql注入。

5.$方式一般用于传入数据库对象,例如传入表名,order by、like 语句只能用${}了,用#{}会多个’ ‘导致sql语句失效

6.一般能用#的就别用$.

mybatis下limit有参数计算时的写法

 开发  mybatis下limit有参数计算时的写法已关闭评论
4月 232020
 

mybatis下limit如果想做分页,对limit做参数计算时:

错误的写法:

<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT (#{pageNo}-1)*#{pageSize},#{pageSize}; // 错误
</select>
在MyBatis中LIMIT之后的语句不允许的变量不允许进行算数运算,会报错。

正确的写法一:
<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT ${(pageNo-1)*pageSize},${pageSize}; (正确)
</select>
正确的写法二:(推荐)
<select id=”queryMyApplicationRecord” parameterType=”MyApplicationRequest” resultMap=”myApplicationMap”>
SELECT
a.*,
FROM
tb_user a
WHERE 1=1
<if test=”ids != null and ids.size()!=0″>
AND a.id IN
<foreach collection=”ids” item=”id” index=”index”
open=”(” close=”)” separator=”,”>
#{id}
</foreach>
</if>
<if test=”statusList != null and statusList.size()!=0″>
AND a.status IN
<foreach collection=”statusList” item=”status” index=”index”
open=”(” close=”)” separator=”,”>
#{status}
</foreach>
</if>
ORDER BY a.create_time desc
LIMIT #{offSet},#{limit}; (推荐,代码层可控)
</select>
分析:方法二的写法,需要再请求参数中额外设置两个get函数,如下:
@Data
public class QueryParameterVO {

private List<String> ids;

private List<Integer> statusList;

// 前端传入的页码
private int pageNo; // 从1开始

// 每页的条数
private int pageSize;

// 数据库的偏移
private int offSet;

// 数据库的大小限制
private int limit;

// 这里重写offSet和limit的get方法
public int getOffSet() {
return (pageNo-1)*pageSize;
}

public int getLimit() {
return pageSize;
}
}

 

linux下删除一个大文件的前n行

 linux, shell  linux下删除一个大文件的前n行已关闭评论
4月 102020
 

删除一个大文件的前n行。

方法一:

例1:删除首行
$ sed -i ‘1d’ a.txt
例2:删除前100行
$ sed -i ‘1,100d’ a.txt
例3:删除尾行
$ sed -i ‘$d’ a.txt

方法二:(举例:删除了前2行)
1.将第三行开始的内容导入新文件
tail -n +3 old_file > new_file
2.将新文件重命名为老文件
mv new_file old_file
这样就删除了前2行,速度要比sed命令快