0%

这周也是抽空复习了下数据结构,也对Java中比较常见的几个重新熟悉了下,之前虽然会用也都有了解,还是有些不太深刻的地方,今天就一起总结下吧。

每当你稍微感觉自己有点懒惰的时候,想都不要想地放下当下手里所有的事,立刻开始做你最不想做却不得不做的那件事。

最核心的点在于

  1. 稍有懒惰的萌芽就要立刻放下当下手里的任何事(视频,音乐,社交软件,被窝等等),立刻马上。
  2. 这个过程中脑袋里什么都不要想。因为我们生活中绝大部分需要完成的事情,其中80%的精力都消耗在启动这个环节。所以,当你用一种势不可挡的态度在极短的时间内完成了这80%,剩下20%靠惯性就可以了。
    阅读全文 »

太久没回来更新的后果之一,就是整个博客的技术栈已经完全outdate了,需要进行大的升级,NodeJS要升级,Hexo和Next theme都要进行几个大版本的升级。几个简要的步骤记录下吧,用得上的同学自取哦。

阅读全文 »

如果提前了解了你所面对的人生,你是否还有勇气前来?

如果你明知道努力无法改变任何结果,你是否还愿意去努力?

阅读全文 »

我回来了

不知不觉离开了好久呀,2年半的时间,跟我在蚂蚁工作的时间一样长,这两年经历了很多,其实有很多可以分享记录一下,所以趁现在记忆还清晰,最近会留下一些小思考,记录一下自己的成长吧。

分享一段罗翔老师的话,读《小王子》有感:
在芸芸众生之中,我们看似自己选择。但其实是被命运之手安排。

阅读全文 »

Redis Lua脚本的几种应用场景

批量删除符合某种pattern的keys

bin/redis-cli eval “return redis.call(“del”,unpack(redis.call(“keys”,ARGV[1])))” 0 “HelloWorld*”
该命令会删除所有以HelloWorld开头的keys。

迁移db index的lua脚本

1
2
3
4
5
6
7
8
local result={};

local keys =redis.call("keys","*");

for i = 1, #keys do
local val= redis.call("move", keys[i], 0);
end
return result;

以上也是很常见的一种脚本范式,先根据需要查询获取到所有的key,再遍历这些key进行想要的操作,例如move, del, rename等等。

NVM安装新版本node之后的 global packages 迁移

NVM安装新版本node之后,全局的package需要迁移,注意使用以下命令,这样就不用手动一个个安装global package了。
例如我今天安装了v8.12.0的node,之前的版本是v8.11.3,那么执行以下命令就可以了。

1
2
3
4
nvm install v8.12.0
nvm reinstall-packages v8.11.3 # 把在v8.11.3版本node下安装的全部global package安装到新的node下面
nvm uninstall v8.11.3
nvm install-latest-npm # 顺便更新一下npm
阅读全文 »

在前端与后端交互的过程中,很可能会遇到使用RSA公钥加密,然后用私钥解密的情况,
RSA的私钥签名,公钥验签同样也很常用,这里简单介绍一下 JavaScript 语言RSA算法的一些解决方案。

NodeJs环境

可以直接引入NodeJs自带的crypto模块,基于RSA/ECB/PKCS1Padding加密,用法如下:

1
2
3
4
5
6
const crypto = require('crypto');
private RSAEncrypt(rsakey:string, text:string){
let encrypted = crypto.publicEncrypt({key:rsakey,
padding:crypto.constants.RSA_PKCS1_PADDING},new Buffer(text)).toString('base64');
return encrypted;
}

其中rsakey为pem格式的公钥,可以从文件读取,或者指定字符串,字符串格式如下:

1
rsakey='-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm5IN1uRvak0Kod3YviD/b67dj\nzP/ubU+8RgbCnm1HUVYBAVGnvg5epMfGunXKFXSb1ehOvQ2K+fEJLa+pKy2uLZLd\n/6gbUGJn+q8wGiFKfu0U0H3E+2yH6eFX+IPXx5OJNwUE6yqKR6hOBz5qR/AtVRfM\n6aAcDLIR7wE06SnHVQIDAQAB\n-----END PUBLIC KEY-----\n'

text就是准备加密的字符串了,直接调用该方法就可以完成加密过程。

参考:https://nodejs.org/docs/latest-v8.x/api/crypto.html#crypto_crypto_publicencrypt_key_buffer

JavaScript native or a web browser

如果是单纯的浏览器环境,推荐forge.js
代码示例:

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
<!doctype html>
<html>
<head>
<title>JavaScript RSA Encryption</title>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/node-forge@0.7.0/dist/forge.min.js"></script>
<script type="text/javascript">

// Call this code when the page is done loading.
$(function() {

// Run a quick encryption/decryption when they click.
$('#testme').click(function() {

var publicKey = forge.pki.publicKeyFromPem($('#pubkey').val());

// convert string to UTF-8 encoded bytes
var buffer = forge.util.createBuffer($('#input').val());
var bytes = buffer.getBytes();

// encrypt data with a public key using RSAES PKCS#1 v1.5
var encrypted = publicKey.encrypt(bytes, 'RSAES-PKCS1-V1_5');

// base64-encode encrypted data to send to server
var b64Encoded = forge.util.encode64(encrypted);
console.log(b64Encoded);
alert(b64Encoded);
});
});
</script>
</head>
<body>
<label for="pubkey">Public Key</label><br/>
<textarea id="pubkey" rows="15" cols="65">-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY08fkt9d32KHV1JapaZGtk+fL
a7wvxMAdZ0oENhx6HgBisSlDwCgBfRtN5l2iOjKm+eByp7Od24JqIOwgDF6FZ/ol
CQbnXjzPhG0EOeLnu3AXntzhu9A0yS7b3p+pxGR7EvhIz1xkOS4bNABsAgF7Y5Zu
B1RpsOZZdxNHGeStBwIDAQAB
-----END PUBLIC KEY-----</textarea><br/>
<label for="input">Text to encrypt:</label><br/>
<textarea id="input" name="input" type="text" rows=4 cols=70>Hello World!</textarea><br/>
<input id="testme" type="button" value="RSA Encrypt" /><br/>
</body>
</html>

参考:

阅读全文 »

概念

CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),俗称验证码,是一种区分用户是计算机或人的公共全自动程序。在CAPTCHA测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。

目前验证码被广泛应用于网站登录、注册、防刷等处,用于识别和防止自动化程序恶意获取服务和数据。

类型

目前大家常见的几类验证码有:

  • 标准验证码(图片),图片中一般是随机组合的字母和数字,对背景和内容进行扭曲,增加噪点和曲线,使程序难以识别
  • 根据界面图形,进行鼠标、手指(移动端)交互操作(滑动拼图验证,点选验证)
  • No CAPTCHA (Google新一代reCAPTCHA,升级的风险分析技术可以智能无感知的判断人类与机器)
  • 语音验证(播放一段音频给用户,用户获取信息后提交比对)
  • 短信、邮箱验证
    阅读全文 »

Sample Dockerfile

后面的讲解,以该Dockerfile构建的镜像为例说明。

1
2
3
4
5
6
7
FROM openjdk:8-jre-alpine

MAINTAINER leimingshan

ADD xxl-sso-server-0.1.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

xxl-sso-server-0.1.1-SNAPSHOT.jar是Spring Boot打包生成的可执行jar,内嵌tomcat容器,直接使用java -jar启动内嵌
的tomcat容器并监听8080端口,这里是最简单的一种制作Spring Boot程序镜像的方法,java -jar就是容器内的主进程,如果该
进程终止,容器也就相应退出。

另外一种常见的镜像制作方法,就是加入supervisor来管理进程,稍微重一些,适合管理容器内的多个进程,此时,java等进程是supervisord的子进程,Dockerfile中的命令也要变成

1
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"] 

supervisord也是容器内的进程命令,只要supervisord不退出,容器就不会退出。

Spring Boot相关的内容大家可以自行学习下,这里就不详述了。

Detached vs foreground

Docker run命令运行一个容器的时候,有一个-d选项

-d=false: Detached mode: Run container in the background, print new container id

detached的意思是让容器在后台运行,同时与你当前终端的STDIN,STDOUT,STDERR分离,然后告诉你一个容器id。
执行该命令之后,我们只会看到一个容器id。

默认不指定-d选项的时候,即-d=false,容器在前台运行,此时容器
处于attached状态,或者说是foreground前台模式,容器内进程(一般是ENTRYPOINT指定的运行命令)的STDIN,STDOUT,STDERR
会与你当前的命令行终端连接,你就可以直接看到容器内进程执行时候的输出,而你的输入也会重定向到容器内进程。以示例镜像运行产生的容器来说,你的所有输入输出都是和java -jar进程关联的。

参考:https://docs.docker.com/engine/reference/run/#detached-vs-foreground

阅读全文 »