0%

ip 和子网掩码进行与运算的结果就是网络号。

这里用到了 cut 命令和逻辑运算来求出了网络号。

1
2
3
4
5
6
7
8
9
10
11
12
13
ip=$1
mask=$2
out=''
for index in {1..4}; do
si=$(echo $ip | cut -d "." -f $index)
sm=$(echo $mask | cut -d "." -f $index)
if [ $index -ne 1 ]
then
out="$out."
fi
out="$out$[$si&$sm]"
done
echo $out

SPL 是 PHP 的标准库,定义了一些类和接口,让 PHP 的功能更加丰富。

早就计划对 SPL 进行系统的学习,这里对学习做一些基本的笔记。

先说遍历,能够遍历的类都要实现 Traversable 接口,但是 Traversable 接口不能被单独实现,只能通过实现他的子接口 Iterator 和 IteratorAggregate 来实现 Traversable 接口。因此只要实现了这两个接口中的任何一个,就能让对象用foreach进行遍历。(从 PHP5 开始,任何类如果未实现 Traversable,对类的遍历会转化为对类的公共属性的遍历)。

Iterator 接口

所有实现了 Iterator 接口的类,都可以进行遍历。实现 Iterator 接口需要实现 5 个方法。

1
2
3
4
5
6
7
8
9
10
11
12
interface Iterator extends Traversable {
//返回迭代器当前元素
public function current();
//移动迭代器位置到下一个
public function next();
//返回返回迭代器当前元素的键名
public function key();
//检查迭代器当前位置是否有效
public function valid();
//恢复迭代器的初始位置
public function rewind();
}

举个栗子

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
class MenIterator implements Iterator
{
public $men = [];
public $position = 0;

public function current()
{
return $this->men[$this->position];
}

public function next()
{
$this->position++;
}

public function rewind()
{
$this->position = 0;
}

public function valid()
{
return isset($this->men[$this->position]);
}

public function key()
{
return $this->position;
}
}

通过此接口可以灵活地对任何对象实现遍历操作。

IteratorAggregate

IteratorAggregate 接口和 Iterator 一样,实现了 IteratorAggregte 接口的类也可以进行遍历。Iterator 隐性的通过 getIterator 方法返回一个迭代器,本质上仍然相当于实现了 Iterator 接口。使用这种方式符合“多用组合,少用继承”的面向对象设计思想。

1
2
3
interface IteratorAggregate extends Traversable {
public function getIterator();
}

getIterator 方法必须返回一个 Iterator 实例。

1
2
3
4
5
6
7
8
9
10
11
class Men {
public function __construct(){
//MenIterator见上例
$this->men = new MenIterator;
$this->men->men = ["a", "b"];
}

public function getIterator(){
return $this->men;
}
}

这样,Men 类的实例便可以使用 foreach进行遍历了。

乐观锁

乐观锁是假设不冲突,在提交的时候判断是否冲突。

1
2
3
4
#先查出version
select id, version from tbl_name where id = 100;
#更新时保证 version 没有发生变化
update tbl_name set ..., version = version + 1 where id = 100 and version = last_version;

悲观锁

悲观锁是假设一定会发生冲突,取出数据时就不允许别的操作者取出该条数据。

1
2
select id from tbl_name where id = 100 for update
update tbl_name set ... where id = 100;

前者能够避免死锁,但是如果必须完成此次更新则需要多次尝试。后者必须等待之前操作完成才能完成。

创建表并指定引擎

1
CREATE TABLE tbl_name(column column_type) ENGINE = ENGINE_NAME

例如

1
CREATE TABLE t (i int) ENGINE = ARCHIVE

创建表并指定字符集和排序方式

1
CREATE TABLE tbl_name (column column_type) CHARACTER SET charset COLLATE collation

创建临时表

1
CREATE TEMPORARY TABLE ...

复制表结构和数据

1
2
CREATE TABLE new_tbl_name LIKE old_tbl_name;
INSERT INTO new_tbl_name SELECT * FROM old_tbl_name;

或者

1
CREATE TABLE new_tbl_name SELECT field1, field2 FROM old_tbl_name where ...

后者既灵活又简单,可以选择需要的列,但是如果复制整张表的话前者更安全、不会出错。

  1. SQL 关键字和函数名。 SQL 的关键字和函数名不区分大小写。
  2. 数据库名、表名和视图名。和服务器主机的操作系统在文件名方面的规定保持一致。Linux 和 Unix 区分大小写,MacOS 不区分大小写,Windows不区分大小写。
  3. 存储程序的名字。存储函数、存储过程和事件的名字不区分大小写,触发器的名字区分大小写。
  4. 列名和索引名。列名和索引名不区分大小写。
  5. 别名的名字。不区分大小写。
  6. 字符串值。二进制数据区分大小写,非二进制取决于字符串的排序规则。

基本配置

1
2
set encoding=utf-8set rulerset numberset nowrapset ciset ts=4set sw=4syntax enableset history=1000set wildmenuset expandtabset helplang=cnset sts=4set showmatchset hlsearchfiletype onfiletype plugin onfiletype indent onset autowriteset cursorlineset autoreadset scrolloff=2set autoindent
set backspace=indent,eol,startcolorscheme molokailet g:molokai_original = 1let g:rehash256 = 1set guifont=Source\ Code\ Pro\ Regular:h16set background=darkif has("autocmd") au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endifendif

主题

查看主题

执行以下命令(将 vim80 替换为自己的版本,可以到相应目录下 ls 一下即可)

1
ls /usr/share/vim/vim80/colors

列表中的文件就是可使用的 vim 主题。

添加主题

下载相对应的主题文件到 /usr/share/vim/vim80/colors 或者到 ~/.vim/colors即可。

如拷贝 https://github.com/tomasr/molokai/blob/master/colors/molokai.vim 到对应的文件夹便可以使用 molokai 主题了。

使用主题

1
colorscheme molokai

ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 ! 65 A 97 a
2 STX 34 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 / 124
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 `
31 US 63 ? 95 _ 127 DEL

特殊字符解释

NUL空 VT 垂直制表 SYN 空转同步
STX 正文开始 CR 回车 CAN 作废
ETX 正文结束 SO 移位输出 EM 纸尽
EOY 传输结束 SI 移位输入 SUB 换置
ENQ 询问字符 DLE 空格 ESC 换码
ACK 承认 DC1 设备控制1 FS 文字分隔符
BEL 报警 DC2 设备控制2 GS 组分隔符
BS 退一格 DC3 设备控制3 RS 记录分隔符
HT 横向列表 DC4 设备控制4 US 单元分隔符
LF 换行 NAK 否定 DEL 删除

基础规范:
(1)必须使用InnoDB存储引擎
(2)使用utf8mb4字符集
(3)数据表、数据字段必须加入中文注释
(4)禁止使用存储过程、视图、触发器、Event
(5)禁止存储大文件或者大照片
-–大文件和照片存储在文件系统,数据库里存URI就好

命名规范:
库名、表名:小写,下划线风格,不超过32个字符,必须见名知意(不要用生僻英文),禁止拼音英文混用;
字段名:禁用关键字命名;小写为主,两个单词间首字母大写,例如:cardName,cardId;
时间字段dateline: (datetime) 为主,如有另一种用途再议;
非唯一索引名idx_xxx,唯一索引名uniq_xxx;

表设计规范
(1)单实例表数目必须小于500
(2)单表列数目必须小于30
(3)表必须有主键,例如自增主键
a)主键递增,数据行写入可以提高插入性能,可以避免page分裂,减少表碎片提升空间和内存的使用
b)主键要选择较短的数据类型, Innodb引擎普通索引都会保存主键的值,较短的数据类型可以有效的减少索引的磁盘空间,提高索引的缓存效率
c) 无主键的表删除,在row模式的主从架构,会导致备库夯住
(4)禁止使用外键,如果有外键完整性约束,需要应用程序控制
外键会导致表与表之间耦合,update与delete操作都会涉及相关联的表,十分影响sql 的性能,甚至会造成死锁。高并发情况下容易造成数据库性能,大数据高并发业务场景数据库使用以性能优先

字段设计:
(1)禁止使用小数存储货币
小数容易导致钱对不上(四舍五入问题,保留小数位不一致会出问题)
(2)尽量少使用ENUM,可使用TINYINT代替
a)增加新的ENUM值要做DDL操作
b)ENUM的内部实际存储就是整数
(3)拒绝text和blob类型
实在避免不了要用text和blob类型,拆表吧。或者弄成本地保存,多机器分片存储。

索引设计规范:
(1)单表索引建议控制在5个以内
(2)单索引字段数不允许超过5个
字段超过5个时,实际已经起不到有效过滤数据的作用了
(3)禁止在更新十分频繁、区分度不高的属性上建立索引
a)更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能
b)“性别”这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似
(4)建立组合索引,必须把区分度高的字段放在前面
能够更加有效的过滤数据

SQL使用规范
(1)禁止(少用)使用SELECT *,只获取必要的字段,需要显示说明列属性
a)读取不需要的列会增加CPU、IO、NET消耗
b)不能有效的利用覆盖索引
c)使用SELECT *容易在增加或者删除字段后出现程序BUG
(2)禁止使用INSERT INTO t_xxx VALUES(xxx),必须显示指定插入的列属性
容易在增加或者删除字段后出现程序BUG
(3)禁止使用属性隐式转换
(4)禁止在WHERE条件的属性上使用函数或者表达式
SELECT uid FROM t_user WHERE from_unixtime(day)>=’2017-02-15’ 会导致全表扫描
正确的写法是:SELECT uid FROM t_user WHERE day>= unix_timestamp(‘2017-02-15 00:00:00’)
(5)禁止负向查询,以及%开头的模糊查询
a)负向查询条件:NOT、!=、<>、!<、!>、NOT IN、NOT LIKE等,会导致全表扫描
b)%开头的模糊查询,会导致全表扫描
(6)禁止大表使用JOIN查询,禁止大表使用子查询
解读:会产生临时表,消耗较多内存与CPU,极大影响数据库性能
(7)禁止使用(尽量少用)OR条件,必须改为IN查询
旧版本Mysql的OR查询是不能命中索引的,即使能命中索引,为何要让数据库耗费更多的CPU帮助实施查询优化呢?
(8)应用程序必须捕获SQL异常,并有相应处理

有时候我们的网站仅仅是为了提供简单的查询服务,但是又要保密,这时候如果写一个认证服务又没什么必要,这时候使用 Nginx 的“约束访问”功能可以轻松地实现基本认证服务。

开启认证

简单地更改 Nginx 的配置文件便可开启认证。

1
2
auth_basic "restircted";#启用http基本认证,以字符串作为域的名字。
auth_basic_user_file conf/htpasswd;#认证文件的位置,这里要特别注意,否则会发生403错误

生成认证文件

认证文件的格式是username:password:commentpassword部分需加密处理,comment部分为可选部分。

使用htpasswd生成认证文件

apache 提供了一个htpasswd命令用来生成认证密钥。如果没有这个命令,需要先安装这个工具。

1
yum install httpd-tools-2.4.6-67.el7.centos.x86_64

然后使用这个命令生成密钥文件

1
2
# cd conf
# htpasswd -c -d file_name "$username" #你的用户名

根据系统提示输入两次密码便完成了文件的生成。

使用PHP生成认证文件

1
2
>>> $password = crypt("password", base64_encode("password")); //第二个参数是盐值,随机两个字母即可
>>> file_put_contents("htpasswd", "username:$password")

完成以上步骤,便可在网站中使用 http 基本认证了。

在使用 Git 时,push 到远端后发现 commit 了多余的文件,或者提交到了错误的分支,或者希望能够回退到以前的版本,这时就要撤销提交。

本地回退代码:

1
2
git reset --hard HEAD~1
//git reset --soft HEAD~1

~1代表回退一个版本,--hard会丢弃本地更改,--soft会保留本地更改,具体使用时应根据具体情况斟酌。

将撤销推送到远程服务器。

1
git push -f

直接使用git push会提示本地版本落后于远程版本,所以需要-f参数强制进行 push。