常见Linux发行版

常见的Linux发行版分成以下几个系列

Redhat, Debian, FreeBSD, Gentoo

Redhat下主要有REHL(Redhat Enterprise Linux), Fedora Core, CentOS(Redhat的社区克隆版本,免费)。包分发方式是基于RPM包的YUM包管理方式,包分发方式是编译好的二进制文件

Debian是迄今为止最遵循GNU规范的Linux系统。Debian系列包括了Debian和Ubuntu。Ubuntu继承了Debian几乎所有的优点。Debian系列采用了apt-get/dpkg包管理方式,包分发方式同样是二进制文件。YUM就是借鉴的apt-get的包管理。

FreeBSD是类Unix操作系统,兼容POSIX,以稳健可靠著称。许多网络型公司都在使用FreeBSD。Mac OS X,PS3, PS4都是源于或部分基于FreeBSD的。FreeBSD 包管理方式是基于源码分发。

Gentoo作为最年轻的发行版,是目前所有发行版中安装最复杂,安装后最便于管理,在相同硬件条件下运行最快的发行版。与它本身的包管理方式基于源码分发也密不可分。

目前使用最广的是CentOS和Ubuntu。由于CentOS的发行版稳定且支持时间比较长,基本可以跨越一套硬件设备的使用寿命,因此在提供服务器应用过程中能够减少系统升级或故障维护等运维成本。Ubuntu由于拥有方便且丰富的包管理工具,在桌面端得到很大的推广,也有很多公司使用Ubuntu做服务器。另外,由于目前日益普及的docker化,Ubuntu作为docker社区的主要支撑操作系统,诸如aufs等特性目前在CentOS上还没有被支持。docker官方也推荐用户使用Ubuntu。因此未来CentOS和Ubuntu仍然会被广泛应用,Ubuntu会更多的被应用到服务端。

查看操作系统相关内容方法:

查看内核版本

1.cat /proc/version

2.uname -a

查看Linux版本

1.lsb_release -a

2.cat /etc/issue

3.cat /etc/red-issue(only redhat work)

4.rpm -q redhat-release(only redhat work)

5.cd /bin/ ,file 某bin文件查看信息,如 : file /bin/pwd

参考文档:

CentOS,Ubuntu,Gentoo,Freebsd,RedHat,Debian的区别及选择

维基百科:FreeBSD

linux基础之教你如何查看linux版本

多进程使用文件锁

文件锁

单进程内多线程可以通过抢占内存锁来保持互斥,在多进程中无法通过内存锁完成,其中的一个办法是可以通过文件锁实现。

大致的思路:每个进程当需要执行关键操作时需要判断是否有其他进程已经在执行,通过查看并创建本地特定文件来判断和抢占这次操作的执行权限,道理同锁机制一致。

以上思路中查看并创建需要是一个原子操作,才能保证中间不会被其他进程截胡。

例如:

1
2
3
4
5
6
7
8
#! /bin/bash
file="/tmp/proj_name"
if [ -f "$file" ]
then
touch $file
else
exit 1
fi

这种方法在检测和创建中可能被其他进程抢占,造成两个进程同时创建文件,因此不可取。

这里采用mkdir

1
2
3
4
5
#! /usr/bin/env bash
if ! mkdir /tmp/myscript.lock 2>/dev/null; then
echo "Myscript is already running." >&2
exit 1
fi

依靠mkdir的创建文件夹,如果文件夹存在则返回>0的错误可判断,执行完毕后别忘了删除文件夹,释放这个文件锁

trap

另外,还有一个命令trap,可以根据传入信号在程序退出做指定的操作,例如

1
2
3
4
5
6
7
8
trap 'echo "$$" > "/tmp/pid";exit' SIGINT
count=0
while :
do
sleep 1
count=$(expr $count + 1)
echo $count
done

程序在无限循环并每秒打印一个递增数字, 在进程收到SIGINT(ctrl + c)的中断信号后,将进程号输入到/tmp/pid文件中,trap可以完成一个进程最后的收尾工作,如清理日志和其他操作

flock

flock 分为共享锁和独享锁,共享锁之间可以同时存在,共享锁和独享锁以及独享锁之间不能够共存。

flock -x $file 获取某文件的独享锁,获取到则接着执行后面的语句,因为flock的参数是一个fd,在进程关闭后所有fd会被关闭,flock的锁也会随即消失,避免出现进程意外退出锁未释放的问题。

flock -n $fd, 设置成非阻塞模式,通过判断 $? 可以知道是否锁成功

flock机制是linux提供的现成的文件锁,比mkdir方便。

CentOS 6 安装 python2.7

CentOS 6 预装的python版本是2.6,由于python2.6不支持ipython等一系列库,所以需要安装python2.7,python3如果有需要安装方法应该类似。

安装python2.7不建议直接覆盖python2.6,因为yum本身是需要Python2.6的支持,有见过直接覆盖后yum就失效的情况。因此使用python2.7我们采用virtualenv的方法,不会影响原生的2.6版本。

安装参考 CENTOS 6.5 安装 Python 2.7 总结,总共分为3部分:

1.安装python2.7

2.安装2.7对应的easy_install 和 pip

3.安装virtualenv

安装过程中会需要用到zlib和openssl,需要在安装python2.7前就安装好。因此步骤大致如下:

预安装:

yum install zlib-devel

yum install openssl-devel

1.

wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
tar xf Python-2.7.8.tgz
cd Python-2.7.8
./configure –prefix=/usr/local
make && make install

2.

# First get the setup script for Setuptools:
wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py

# Then install it for Python 2.7 :
python2.7 ez_setup.py

# Now install pip using the newly installed setuptools:
easy_install-2.7 pip

3.

# Install virtualenv for Python 2.7 and create a sandbox called my27project:
pip2.7 install virtualenv
virtualenv-2.7 my27project

# Check the system Python interpreter version:
python –version
# This will show Python 2.6.6

# Activate the my27project sandbox and check the version of the default Python interpreter in it:
source my27project/bin/activate
python –version
# This will show Python 2.7.X

之后每次使用python2.7只需要source一下active文件就可以了

参考:

CENTOS 6.5 安装 Python 2.7 总结

 

django学习第一天

整个流程完全按照django官网的tutorial进行

今天对django的 Writing your first Django app, part 1 和 Writing your first Django app, part 2 进行了学习,边看文档边自己构建一个django项目

学习过程中的关键点:

1.django使用的数据库自带的sqlite3, 这个在目前项目中的UnitTest时也是使用的自带的sqlite3. 在此之外还可以使用 mysql, PostgreSQL等。在settings文件中对DATABASE的描述中,不同的数据库选用不同的ENGINE, 相对应的NAME( sqlite3使用 本地文件路径,默认路径是os.path.join(BASE_DIR,‘db.sqlite3’)), 使用非sqlite3需要填入USER, PASSWORD, HOST信息

2.django在运行前需要先执行 python manage.py migrate对数据库做初始化操作

3.执行 python manage.py runserver 默认端是8000, 如果需要其他ip对服务进行访问,需要执行 python manage.py runserver 0.0.0.0:8000

4.创建新的app,需要执行python manage.py startapp polls, polls 为app名字,然后在settings.py中的INSTALLED_APPS中添加’polls’在最后,例如

mysite/settings.py
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

5.编写app中的models.py文件,定义app中的数据结构,执行

python manage.py makemigrations polls

根据models的变化生成新的migration文件

python manage.py sqlmigrate polls 0001

查询migrate对应的sql操作语句

python manage.py migrate

对数据库进行操作

Migrations are very powerful and let you change your models over time, as you develop your project, without the need to delete your database or tables and make new ones – it specializes in upgrading your database live, without losing data. We’ll cover them in more depth in a later part of the tutorial, but for now, remember the three-step guide to making model changes:

6.创建超级用户

python manage.py createsuperuser

7.注册新的app到admin中

polls/admin.py
from django.contrib import admin

from .models import Question

admin.site.register(Question)

8.自定义admin中app的格式

polls/admin.py
from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

9.admin中对两个model间建立关系

polls/admin.py
from django.contrib import admin

from .models import Choice, Question


class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

10.admin中一些小的展示技巧 list_display,  list_filter,  search_fields, 后续admin专题有更详细的学习

 

常见编码问题

最近工作主要使用的python和java,之前比较少遇到过的编码问题开始浮现出来,再加上自己曾经写过的一个UDF使用的参数被我从java默认的byte[]调成了String,也给自己埋了个大坑。所以解决这些问题之后感觉有必要把编码的问题理一下,避免重蹈覆辙。

常见的编码有 ASCII, unicode, utf-8, ISO-8859-1 等

ASCII 是对应了128个字符,在字节中的第一位全部是0,对应的是英文字符,标点和阿拉伯数字,因此在使用时比较有限,不能够显示很多所需要的字符。ASCII码是python的默认编码方式

1
2
3
import sys
sys.getdefaultencoding()
# 'ascii'

之后,EASCII 成为ASCII码的补充,将字符数量从128增加到256, 扩充的字符包括表格符号,计算符号,希腊字母和特殊的拉丁字符。但表示的字符仍然有限。
另外,ISO-8859-1也是256个字符范围内的编码方式,这种编码与ASCII在前128位保持兼容一致,后面主要补充了拉丁字母,供欧洲使用。但从wiki的图中可以发现,ISO-8859-1并非在256个字符中能够一一对应,图中的绿色部分是没有字符表示的。 目前java在从String转成Byte[]的时候,使用的getbyte[charset]的方法,如果charset未定义则使用默认的ISO-8859-1

以上的三种编码方法都是对应的在一个字节中表示字符,显然,他们都不能对大部分的非英文字符完全表示出来。因此引入了unicode。
unicode 采用多字节进行编码,大大的增加了可表示字符的范围,且unicode可以很好的兼容ISO-8859-1的所有字符。中文也都可以通过unicode表示出来。unicode目前支持的字符还在不断的扩大,目前实际应用的统一码版本对应的UCS-2,使用两个字节表示字符,即65536个字符。
unicode的编码方式和实现方式是不同的,一个字符的unicode是一定的,但在传输过程中为了解决传输字节数,采用了不同的实现方式。

UTF-8 就是最为主要的一种实现方式。通过变长编码,可以将大部分的unicode在两个字节内完成编码,节省了传输资源。具体的前缀码实现在wiki中介绍的很清楚。

毕业一周年

转眼毕业一周年,上学的日子仿佛刚刚过去,却挡不住时间的脚步提醒我已经工作了一年之久。
一年的北京生活,每天两点一线,能想到很多却一时又不知道要感慨什么。过去的留给下次来回忆。未来一年的生活来做下简单的规划

1.接下来把MachineLearning的cousera课程学完,去kaggle上做个数据分析的实战。
2.Linux高级环境编程尽快看完
3.Django,python再系统地学习一遍
4.每周至少跑步累计10公里
5.每天12点睡觉,早上7点半起床

这就是大概的要求,时间已经12点,睡觉先。

yield的用法

python中,正常的函数通常是在一个函数中进行操作,最后return,将控制权交给调用函数的地方。

yield和正常理解的函数执行不同,yield在函数中与return起到的作用类似却又不同。yield从函数中返回一个值,但控制权并未完全交出,而是在保存当前所有变量的情况下暂时地将控制权交给外面,当外面的函数继续进行迭代时,控制权又回到yield处,执行下一行代码。

由此可以看到yield存在的函数实际返回了一个GeneratorType,通过不断地迭代,调用外部的函数来处理yield还回去的结果。

实例代码如下:

1
2
3
4
5
6
7
def x():
    for i in xrange(5):
        yield i
        print 'i value ', i

for k in x():
    print 'k value ', k

代码输出结果:

k value 0
i value 0
k value 1
i value 1
k value 2
i value 2
k value 3
i value 3
k value 4
i value 4

vim配置插件

pathogen

vim的插件统一由pathogen管理

1.mkdir -p ~/.vim/autoload ~/.vim/bundle 
2.curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

之后将想要安装的插件统一放在~/.vim/bundle 下面

python-mode

支持python的编写模式

1.cd ~/.vim
2.mkdir -p bundle && cd bundle
3.git clone git://github.com/klen/python-mode.git

 NERDTree

支持侧栏显示文件系统

1.cd ~/.vim/bundle 
2.git clone https://github.com/scrooloose/nerdtree.git
3.Then reload vim, run :Helptags, and check out :help NERD_tree.txt.

taglist

支持ctag分析文件,将当前文件的宏、变量、函数列在symbol表中

因为mac中默认的/usr/bin/ctags不是exuberant ctags,所以使用时会出现问题,需要自己下载ctags编译安装到非/usr/bin 目录下
从 http://www.vim.org/scripts/script.php?script_id=273 下载最新的ctag包
tar -xvzf ctags-5.8.tar.gz
cd ctags-5.8
./configure
make && sudo make install
我们已经安装了自己的ctag,此时需要修改系统路径
which ctags  此时显示是/usr/bin/ctags
vim ~/.profile
添加 export PATH="/usr/local/bin:/usr/local/sbin:$PATH"
source ~/.profile
which ctags 此时显示是/usr/local/bin/ctags
在~/.vimrc中配置
let Tlist_Ctags_Cmd = '/usr/local/bin/ctags'
let Tlist_Show_One_File = 1 "不同时显示多个文件的tag,只显示当前文件的
let Tlist_Exit_OnlyWindow = 1 "如果taglist窗口是最后一个窗口,则退出vim
let Tlist_Use_Right_Window = 1 "在右侧窗口中显示taglist窗口

 More~

有时会用鼠标进行复制,当有行号时默认会复制到行号,如果不想复制行号,可以在~/.vimrc中设置

set mouse=a

此时鼠标可以像IDE中一样通过滚动来上下查看,并在选中时不会包括到行号。

常见加密算法

Crypto

根据密钥类型不同分为两类:对称加密和非对称加密
对称加密算法常见的包括:DES、3DES、AES
非对称加密算法常见的包括:RSA、DSA、ECC

AES:Advanced Encryption Standard,是一种区块加密标准。
AES加密是在4*4的字节矩阵上运作的,这个矩阵叫做“体state”,其初值是一个明文区块。若需要加密的数据不是16字节的整数倍,则后面补位至16的倍数。若正好是16的倍数,则后面再补16字节。(padding采用PKCS7Padding

python:

length = 16 – (len(message) % 16)
message += chr(length)*length


加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:
  1. AddRoundKey —矩阵中得每一个字节与下一轮的RoundKey做异或运算
  2. SubBytes — 非线性的替换函数,在S-Box中用对应位置的值替换当前字节值
  3. ShiftRows — 将矩阵中的每一行做循环移位
  4. MixColumns — 混合每个矩阵中每列的操作

AES_Encryption_Process

上图来自波士顿大学的Howard Straubing做了这么一个动画来展示AES加密算法的演示(援引自coolshell http://coolshell.cn/articles/3161.html
在这个展示中对加密的过程和wiki中的描述看起来有些不同,其实是一样,都是在initial round时对Cipher key做一次或运算,然后9轮循环加密,最后再做一次替换函数,移位操作和异或运算。
每一轮做抑或运算的Round key值也是根据Cipher key推算出来的。
AES_key
在每次计算第 4*i+1列时都会将 4*i列向上移位1位,然后根据S-Box做SubBytes,然后和4*i-3列异或,再和Rcon左边一列异或。
计算非4*i+1列(如j)时则直接计算列(j-1) 异或 列(j-4)得到。
可见整个AES state加密过程中Cipher Key对加密结果起到关键作用,AES也是通过Cipher Key来做对称解密的。
AES的密钥长度可以为128,192,256 Bytes,分别对应的加密Round数为10,12,14
而这种情况每一个state对应一个加密的4*4的块。state之间不存在互相影响的关系,这样在加密时可以并行计算,但随之带来的问题可能会让对方根据字母的统计频次来破解CipherKey值。
因此AES在这个加密的基础上又分为以下几种mode:
  • ECB模式
每个state单独地进行加密,相同的明文state会得到相同的密文块
  • CBC模式
第一块明文会和初始化向量IV做异或再加密,之后的明文块都需要上一个密文块做异或再进行加密。这样不容易主动攻击,也不利用并行计算。
  • CFB模式
  • OFB模式

BASE64

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email、在XML中存储复杂数据。
MIME格式的电子邮件中,base64可以用来将binary的字节序列数据编码成ASCII字符序列构成的文本。使用时,在传输编码方式中指定base64。使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。
编码”man”:
编码“Man”
base64 补位:
base64补位
文本为1Byte的A,相应的二进制上补4个0,生成QQ,对应文本缺少两个Byte到3的倍数,最后的Base64编码补2个=
文本为2Byte的BC,相应的二进制上补2个0,生成QKM,对应文本缺少一个Byte到3的倍数,最后的Base64编码补1个=