编程经验分享

笑看嫣红染半山,
逐风万里白云间,
逍遥此身不为客,
天地三才任平凡。

0%

JWT简介

原始链接:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

JWT - Json Web Token:目前最流行的跨域认证解决方案,本文简单介绍它的原理和用法。

一、跨域认证的问题

互联网服务离不开用户认证。一般流程是下面这样:

  1. 用户向服务器发送用户名和密码。
  2. 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
  3. 服务器向用户返回一个 session_id,写入用户的 Cookie。
  4. 用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。
  5. 服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

这种模式的问题在于,扩展性(scaling)不好。单机当然没有问题,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session。

举例来说,A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?

一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败。

另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。

阅读全文 »

FFmpeg

FFmpeg 由于其丰富的 codec 插件,详细的文档说明,并且与其调试复杂量大的编解码代码(是的,用 MediaCodec 实现起来十分啰嗦和繁琐)还是不如调试一行 ffmpeg 命令来的简单。

利用 FFmpeg 做视频编辑大家一般都会去参考这个 repo ,但是他的 asset 里面的 ffmpeg 大小高达 18MB,即使压缩进 APK 包里也会达到 9MB。对 APK 大小敏感的开发者肯定颇有微词。 ffmpeg-android-java 的原理很简单,交叉编译好可执行的 ffmpeg 二进制文件放到 asset 里,安装后释放二进制文件到 /data/data/ 里,用 Shell command 的形式去执行这个文件,好处是没有任何依赖(依赖全打进二进制了),稳定可靠(不需要动态加载)。 坏处就很明显了,因为是二进制文件,所以 size 会很大。

于是,果断放弃这种方式,转而编译 ffmpeg 的 so 库,动态加载然后执行命令。听起来不错,对不对?动态库的大小肯定比 ffmpeg-android-java 的 executable 要小多了,而且自己编译 ffmpeg 还能对其进行裁减。

阅读全文 »

树莓派安装和配置CentOS 7.2.1511 Minimal

Purpose

The purpose of this article is to describe how to install CentOS 7.2.1511 or 1603 Minimal on the Raspberry PI 3 B+ for use as a starting point to install light-weight services such as DNS, NTP, DHCP, Apache, etc.

安装 CentOS 7

General information

https://wiki.centos.org/SpecialInterestGroup/AltArch/Arm32/RaspberryPi3


root用户的默认密码是: centos.


安装介质

从下面的网址获取镜像文件:CentOS 7 For RaspberryPI

我用的是:CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1804-sda.raw.xz

镜像烧录

有多种方法可以把镜像文件烧录到SD卡上,最常用的:

具体方法可以参考:http://xmodulo.com/write-raspberry-pi-image-sd-card.html

我是在macOS上用 Etcher 把镜像文件烧录到SD卡上的。
另外,在烧录完成后,可以直接进入挂接的文件系统下,修改cmdline.txt文件,在末尾加上 ip=192.168.1.226ip前面有个空格,这样启动后直接设定了IP地址。

README

启动系统后,可以在/root路径下发现有个 /root/README 文件,这个文件中描述了完成安装还需要做的步骤。

1
2
3
4
5
[root@centos-rpi3b ~]# cat /root/README
== CentOS 7 userland ==

If you want to automatically resize your / partition, just type the following (as root user):
rootfs-expand
阅读全文 »

安装nvm

1
# wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

or

1
# curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

.bashrc中已经自动添加,在不退出当前终端的情况下用下面的命令设置环境变量:

1
2
# export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
阅读全文 »

在macOS Sierra上安装MySQL

本文介绍了在macOS Sierra 10.12上如何用Homebrew来安装MySQL

安装Homebrew

  • 打开终端,输入一下命令 :
    $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    注意: 提前装好Command Line Tools for Xcode #.#

安装MySQL

  • 输入命令 : $ brew info mysql
  • 预期输出: mysql: stable x.y.z (bottled)

安装MySQL,输入命令行 : $ brew install mysql

阅读全文 »

调整Launchpad行列数目

开打终端输入

改变行数:defaults write com.apple.dock springboard-rows -int X

改变列数:defaults write com.apple.dock springboard-columns -int X

改变生效:killall Dock

其中X是大于0的整数。根据自己喜好调整即可。

1
2
3
4
# 恢复默认:
$ defaults write com.apple.dock springboard-rows Default
$ defaults write com.apple.dock springboard-columns Default
$ killall Dock

PX

px是绝对单位。

pxpixel的缩写,也就是像素,是实际的显示设备(显示器、手机屏幕)上的一个物理像素点,它的大小和实际的显示用的物理设备有直接关系,也就是设备依赖的。

EM

em是相对单位。

  • em是相对于元素自己的字体大小font-size而言的。
  • 如果元素自己的font-sizeem来表示的话,则是相对于父元素的font-size
  • 如果元素自己的font-size没有设置,则相对于浏览器的默认字体尺寸。

任意浏览器的默认字体大小font-size都是16px,也就是说:1em = 16px, 2px = 0.75em,10px = 0.625em
为了简化font-size的换算,需要在css中的body选择器中声明font-size = 62.5%,这就使em单位值变为16px * 62.5%=10px, 这样12px = 1.2em, 10px = 1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#将日志同时输出到文件和屏幕

import logging

logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='myapp.log',
filemode='w')

##########################################################################################
#定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
##########################################################################################

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')