0%

Python 装饰器

装饰器的定义

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。 它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

Python 闭包

首先还得从基本概念说起,什么是闭包呢?来看下维基上的解释: 在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

类之间的关系

泛化(Generalization)

泛化关系:是一种继承关系,表示一般与特殊的关系,通过继承增加子类的能力,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性。


教程地址

SQL语句对大小写不敏感

基础语法

SELECT 列名称 FROM 表名称

DISTINCT 用语返回唯一的值

SELECT DISTINCT 列名称 FROM 表名称

WHERE 有条件从表中选取数据

SELECT 列名称 FROM 表名称 WHERE 列 运算符 值

操作符描述
=等于
<>不等于
>大于
<小于
>=大于等于
<=小于等于
BETWEEN在某个范围内
LIKE搜索某种模式

AND 和 OR 运算符是基于一个以上条件对记录进行过滤

Python 元类(metaclass)

对象

Python 中一切皆对象,连类也不例外。

对象中包含三个关键性属性:

  1. 标识 使用 id() 方法查看
  2. 对象值
  3. 类型 使用 type() 方法查看

类与对象

Python 中使用 class 关键字定义类,通过定义的类生成类实例。实例称之为实例对象。Python 中类是一个对象,所有内建类型的类型都是 type,这个 type 就是元类,元类就是 Python 中的造物主。

Terminal Multiplexers: Screen, Tmux

终端多路复用:Screen,Tmux

命令行选项

术语对照表

英文中文
session会话
attach连接
detach脱离
prefix前缀
multiplexer多路复用
window窗口
regions区域
panes面板
buffer缓存
mark标记
用途screentmux
创建指定名称的会话并连接screen -S footmux new -s foo
创建会话并脱离screen -S foo -d -mtmux new -s foo -d
列出所有会话screen -listtmux ls
连接screen -rtmux attach
连接到指定会话screen -r footmux attach -t foo
通过 pid 连接会话screen -r pid
连接到运行中的会话screen -x foo
销毁指定会话screen -r foo -X quittmux kill-session -t foo
发送命令到指定会话screen -r foo -X commandtmux command -t foo
脱离会话screen -d name

按键绑定

用途screenscreen commandtmuxtmux command
帮助?:help?:help
发送前缀至其他应用a:metaC-b:send-prefix
暂停多路复用C-z:suspendC-z:suspend-client
显示前一个多路复用终端信息m/C-m:lastmsg~:show-messages
加载配置文件:source filename:source-file filename
session
新建会话:new
新建命名会话:new -s name
切换会话s:choose-session
重命名会话:sessionname newname$rename-session newname
销毁会话C-\:quit
windows
创建窗口c/C-c:screenc:new-window
切换下一个窗口n/C-n/<SPACE>:nextnnext-window
切换上一个窗口p/h/C-p/<BACKSPACE>:prevp:previous-window
激活最近使用的窗口C-a:other
选择指定 number 窗口number/' numbernumber:select-window -t number
列出所有窗口w/C-w:windows:list-windows
显示当前窗口信息N:number
重新分配窗口 number. position:move-window
重新分配窗口所在会话. sessname
. sessnum:position
重绘当前窗口l/C-l:redisplayr:refresh-client
交互式选择窗口":windowlist -bw:choose-window
重命名窗口A:title,
选择名为 foo 的窗口':selectf foo
关闭当前窗口k:kill&kill-window
联合窗口 1 到当前窗口:join-pane -s 1
联合窗口 1 的区域 0 到当前窗口:join-pane -s 1.0
regions
上下分割S:split
左右分割`/V`:vsplit
切换到下一区域<TAB>
使区域高度相同:resize =
保留当前区域关闭其他区域Q:only
清除当前区域C:clear
关闭当前区域X:remove
输出日志到文件:log
关闭日志log off
调节当前区域行高:resize +/-n
设置当前区域行高为 nresize n
panes
上下分割":split-window
左右分割%:split-window -h
切换下一区域o:select-pane
列出面板:list-panes
显示面板编号q:list-panes
旋转面板C-o:rotate-window
反向旋转面板M-o:rotate-window -D
相同宽度的面板布局M-1
相同高度的面板布局M-2
交换当前与前一面板{:swap-pane -U
交换当前与后一面板}:swap-pane -D
修改面板布局<SPACE>:next-layout
关闭当前面板x:confim-before kill-pane
break 当前面板至分离窗口!:break-pane
清除当前面板:clear-history
输出日志到文件:pipe-pane "cat > /tmp/tmux.log"
关闭日志:pipe-pane
调节左/上单元大小:resize-pane -L/U n
paste buffer
进入 copy 模式[/C-[/<ESC>:copy[:copy-mode
paste 最近的缓存]]:paste-buffer
缓存列表#:list-buffers
交互式选择缓存=:choose-buffer
缓存保存至文件>:writebuf path:save-buffer path
copy 文件至缓存<:readbuf path:load-buffer path
copy mode
默认绑定Vim styleEmacs-style
设置标记<SPACE>C-<SPACE>
copy from 标记点并退出 copy mode<SPACE>C-w
单列移动h/lC-b/C-h
单行移动j/kC-n/C-p
行开头0C-a
行结尾$C-e
下一个词eM-f
上一个词bM-b
向上翻页C-bM-v
向下翻页C-fC-v
缓存开头gM-<
缓存结尾GM->
向上搜索? phraseC-r phrase
向下搜索/ phraseC-s phrase
退出 copy 模式<ESC>q

自定义


工具函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <ctime>

using namespace std;

void swap(int &a,int &b){
    int tmp = a;
    a = b;
    b = tmp;
}

void printarr(int *a,int n){
    for(size_t i = 0; i < n; i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
}

Bubble Sort 冒泡排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void bubble_sort(int *a, int n){
    for(size_t i = n-1; i > 0;--i){
        for(size_t j = i; j > 0;--j)
        {
            if(a[j] < a[j-1])
                swap(a[j],a[j-1]);
        }
    }
}

void bubble_sort_speedup(int *a, int n){
    for(size_t i = 0; i < n-1; i++){
        int flag = 0;
        for(size_t j = 0; j < n-1-i; ++j){
            if(a[j] > a[j+1]){
                swap(a[j],a[j+1]);
                flag = 1;
            }
        }
        if(!flag)
            break;
    }
}

Cocktail Sort 鸡尾酒排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
void cocktail_sort(int *a,int n){
    int left = 0;
    int right = n-1;
    while(left < right){
        for(size_t i = left; i<right;++i){
            if(a[i] > a[i+1])
                swap(a[i],a[i+1]);
        }
        right--;
        for(size_t j = right;j>left;--j){
            if(a[j-1] > a[j]){
                swap(a[j-1],a[j]);
            }
        }
        left++;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
void cocktail_sort_speedup(int *a,int n){
    bool sorted = false;
    while(!sorted){
        sorted = true;
        for( int i = 0; i < n - 1; i++ ){
            if( a[i] > a[i + 1] ){
                swap( a[i], a[i + 1] );
                sorted = false;
            }
        }
        if(sorted)
            break;
        sorted = true;
        for( int j = n - 1; j > 0; j-- ){
            if( a[j - 1] > a[j] ){
                swap( a[j], a[j - 1] );
                sorted = false;
            }
        }
    }
}

Selection Sort 选择排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
void selection_sort(int *a, int n){
    for(size_t i = 0;i < n-1;i++){
        int index = i;
        for(size_t j = i+1;j < n;j++){
            if(a[j] < a[index])
                index = j;
        }
        if(i!=index)
            swap(a[i],a[index]);
    }
}

Insertion Sort 插入排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
void insertion_sort(int *a, int n){
    for(size_t i = 1;i < n;i++){
        int tmp = a[i];
        size_t j = i;
        while(j > 0 && tmp < a[j-1]){
            a[j] = a[j-1];
            --j;
        }
        a[j] = tmp;
    }
}

Shell Sort 希尔排序

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void shell_sort(int *a,int n){
    int h,i,j,t;
    for(h = n;h/=2;){
        // iterator
        for(i=h;i<n;i++){
            t=a[i];
            for(j=i;j>=h && t<a[j-h];j-=h){
                a[j] = a[j-h];
            }
            a[j] = t;
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void shell_sort_speedup(int *a,int n){
    int i,j,tmp,step;
    step = n;
    while(step>1){
        step = step/3+1;
        // insert sort
        for(i=step;i<n;i++){
            tmp = a[i];
            for(j=i;j>0 && a[j] < a[j-step];j-=step){
                a[j] = a[j-step];
            }
            a[j] = tmp;
        }
    }
}

Merge Sort归并排序

递归版本

Philosophy 哲学

Markdown is designed to be easy to write,and,even more importantly,easy to read.

A Markdown-formatted document should be publishable as-is,as plain text,without looking like it’s been marked up with tags or formatting instructions. - John Gruber

Paragraphs 段落

一个段落包含一行或多行文字,通过行后跟随一个或多个空白行,换行符(newlines)和空格(spaces)作用一样,如果需要硬换行(hard line break),在行后添加两个以上的空格。

Git 基础

基础操作

初始化仓库

git init

git clone [url]

检查文件状态

git status

跟踪文件

git add [file name] 跟踪新文件/暂存已修改文件

对比文件修改内容

git diff [file name]

git diff --cached/staged [file name] 对比暂存区文件

提交更新

git commit

git commit -m [message] 更新纪录

filter,nat,mangle 规则表

filter表

数据包过滤,根据规则决定是否放行数据包(DROP,ACCEPT,REJECT,LOG)

三条规则链

  • INPUT 进入本地的包
  • FORWARD 不是本地产生且负责转发的包
  • OUTPUT 本地产生的包

nat表

修改数据包ip地址、端口等信息(SNAT,DNAT,MASQUERADE,REDIRECT)