我有过多次这样的奇遇,
从天堂到地狱只在瞬息之间;
每一朵可爱、温柔的浪花,
都成了突然崛起、随即倾倒的高山。

每一滴海水都变脸变色,
刚刚还是那样美丽、蔚蓝;
旋涡纠缠着旋涡,
我被抛向高空又投进深渊……

当时我甚至想到过轻生,
眼前一片苦海无边;
放弃了希望就象放弃了舵柄,
在暴力之下只能沉默和哀叹。

今天我才有资格嘲笑昨天的自己,
为昨天落叶似的惶恐感到羞惭;
虚度了多少年华,
船身多次被礁石撞穿……

千万次在大洋里撒网,
才捕获到一点点生活的经验,
才恍然大悟,
啊!道理原是如此浅显:

你要航行吗?
必然会有千妖百怪出来阻拦;
暴虐的欺凌是它们的游戏,
制造灭亡是它们唯一的才干。

命中注定我要常常和它们相逢,
因为我的名字叫做船;
面对强大于自身千万倍的对手,
能援救自己的只有清醒和勇敢。

恐惧只能使自己盲目,
盲目只能夸大魔鬼的狰狞嘴脸;
也许我的样子比它们更可怕,
当我以生命相拼,一往无前!

只要我还有一根完整的龙骨,
绝不驶进避风的港湾;
把生命放在征途上,
让勇敢来决定道路的宽窄、长短。

我完完全全的自由了,
船头成为埋葬它们的铁铲;
我在波浪中有节奏地跳跃,
就象荡着一个巨大的秋千。

即使它们终于把我撕碎,
变成一些残破的木片;
我不会沉沦,决不!
我还会在浪尖上飞旋。

后来者还会在残片上认出我,
未来的诗人会喟然长叹:
“这里有一个幸福的灵魂,
它曾经是一艘前进着的航船……”

nginx启动、重启、关闭

一、启动

1
2
cd usr/local/nginx/sbin
./nginx

二、重启

更改配置重启nginx  

1
2
3
4
kill -HUP 主进程号或进程号文件路径
或者使用
cd /usr/local/nginx/sbin
./nginx -s reload

判断配置文件是否正确 

1
2
3
4
nginx -t -c /usr/local/nginx/conf/nginx.conf
或者
cd /usr/local/nginx/sbin
./nginx -t

三、关闭

  查询nginx主进程号

  ps -ef | grep nginx

  从容停止 kill -QUIT 主进程号

  快速停止 kill -TERM 主进程号

  强制停止 kill -9 nginx

  若nginx.conf配置了pid文件路径,如果没有,则在logs目录下

  kill -信号类型 ‘/usr/local/nginx/logs/nginx.pid’

四、升级

  1、先用新程序替换旧程序文件

  2、kill -USR2 旧版程序的主进程号或者进程文件名

    此时旧的nginx主进程会把自己的进程文件改名为.oldbin,然后执行新版nginx,此时新旧版本同时运行

  3、kill -WINCH 旧版本主进程号

  4、不重载配置启动新/旧工作进程

    kill -HUP 旧/新版本主进程号

    从容关闭旧/新进程

    kill -QUIT 旧/新进程号

    快速关闭旧/新进程

    kill -TERM 旧/新进程号

慢跑是件痛并者快乐的事情。

正如老罗所说,“失败只有一种,那就是半途而废”。

又如村上春树所说,“今天不想跑,所以才去跑,这才是长跑者的思维方式”。

我们通过终端连接服务器时,当鼠标和键盘长时间不操作,服务器就会自动断开连接,我们还的需要重新连接,感觉很麻烦,总结一下解决此问题的方法

方法一

修改/etc/ssh/sshd_config配置文件,找到ClientAliveCountMax(单位为分钟)修改你想要的值
执行service sshd reload

方法二

找到所在用户的.ssh目录,如root用户该目录在:

/root/.ssh/

在该目录创建config文件

vi /root/.ssh/config

加入下面一句:

ServerAliveInterval 60

保存退出,重新开启root用户的shell,则再ssh远程服务器的时候,
不会因为长时间操作断开。应该是加入这句之后,ssh客户端会每隔一
段时间自动与ssh服务器通信一次,所以长时间操作不会断开。

方法三

修改/etc/profile配置文件

# vi /etc/profile

增加:TMOUT=1800
这样30分钟没操作就自动LOGOUT

方法四

利用expect 模拟键盘动作,在闲置时间之内模拟地给个键盘响应,将下列代码保存为xxx,然后用expect执行

1
2
3
4
5
6
7
#!/usr/bin/expect  
set timeout 60
spawn ssh user@host
interact {
timeout 300 {send "\x20"}
}
expect xxx

接着按提示输入密码就可以了,这样每隔300秒就会自动打一个空格(\x20),具体的时间间隔可以根据具体情况设置。

方法五

如果你在windows下通过工具连接,可以设置为
secureCRT:选项—终端—反空闲 中设置每隔多少秒发送一个字符串,或者是NO-OP协议包

putty:putty -> Connection -> Seconds between keepalives ( 0 to turn off ), 默认为0, 改为300.

完整的URL由这几个部分构成:scheme://host:port/path?query#fragment ,各部分的取法如下:

  • window.location.href:获取完整url的方法:,即scheme://host:port/path?query#fragment
  • window.location.protocol:获取rul协议scheme
  • window.location.host:获取host
  • window.location.port:获取端口号
  • window.location.pathname:获取url路径
  • window.location.search:获取参数query部分,注意此处返回的是?query
  • window.location.hash:获取锚点,#fragment

在js中可以使用escape(), encodeURL(), encodeURIComponent(),三种方法都有一些不会被编码的符号:

  • escape():@ * / +
  • encodeURL():! @ # $& * ( ) = : / ; ? + ‘
  • encodeURIComponent():! * ( ) ‘

在java端可以使用URLDecoder.decode(“中文”, “UTF-8”);来进行解码

但是由于使用request.getParameter() 来获取参数时已经对编码进行了一次解码,所以一般情况下只要在js中使用:

encodeURIComponent("中文");

在java端直接使用request.getParameter()来获取即可返回中文。

如果你想在java端使用URLDecoder.decode(“中文”, “UTF-8”);来解码也可以在js中进行二次编码,即:

encodeURIComponent(encodeURIComponent("中文"));

如果不进行二次编码的话,在java端通过decode方法取的会是乱码。

数据库的索引、视图、存储过程、触发器的功能及其使用情景

  • 数据库的索引
  • 数据库的存储过程
  • 数据库的视图
  • 数据库的触发器

还有什么?等知道了再来补充

数据库的索引

什么是数据的索引

索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度。索引包含由表或视图中的一列或多列生成的键。这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行

表和视图可以包含以下类型的索引

  • 聚集
    • 聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。索引定义中包含聚集索引列。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序排序。
    • 只有当表包含聚集索引时,表中的数据行才按排序顺序存储。如果表具有聚集索引,则该表称为聚集表。如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。
  • 非聚集
    • 非聚集索引具有独立于数据行的结构。非聚集索引包含非聚集索引键值,并且每个键值项都有指向包含该键值的数据行的指针。
    • 从非聚集索引中的索引行指向数据行的指针称为行定位器。行定位器的结构取决于数据页是存储在堆中还是聚集表中。对于堆,行定位器是指向行的指针。对于聚集表,行定位器是聚集索引键。
    • 您可以向非聚集索引的叶级添加非键列以跳过现有的索引键限制(900 字节和 16 键列),并执行完整范围内的索引查询。

聚集索引和非聚集索引都可以是唯一的。这意味着任何两行都不能有相同的索引键值。另外,索引也可以不是唯一的,即多行可以共享同一键值。

每当修改了表数据后,都会自动维护表或视图的索引。

索引和约束

对表列定义了 PRIMARY KEY 约束和 UNIQUE 约束时,会自动创建索引。例如,如果创建了表并将一个特定列标识为主键,则 数据库引擎自动对该列创建 PRIMARY KEY 约束和索引。有关详细信息,请参阅创建索引(数据库引擎)。

索引的作用

与书中的索引一样,数据库中的索引使您可以快速找到表或索引视图中的特定信息。索引包含从表或视图中一个或多个列生成的键,以及映射到指定数据的存储位置的指针。通过创建设计良好的索引以支持查询,可以显著提高数据库查询和应用程序的性能。索引可以减少为返回查询结果集而必须读取的数据量。索引还可以强制表中的行具有唯一性,从而确保表数据的数据完整性。

设计良好的索引可以减少磁盘 I/O 操作,并且消耗的系统资源也较少,从而可以提高查询性能。对于包含 SELECT、UPDATE、DELETE 或 MERGE 语句的各种查询,索引会很有用。例如,在 AdventureWorks 数据库中执行的查询 SELECT Title, HireDate FROM HumanResources.Employee WHERE EmployeeID = 250。执行此查询时,查询优化器评估可用于检索数据的每个方法,然后选择最有效的方法。可能采用的方法包括扫描表和扫描一个或多个索引(如果有)。

扫描表时,查询优化器读取表中的所有行,并提取满足查询条件的行。扫描表会有许多磁盘 I/O 操作,并占用大量资源。但是,如果查询的结果集是占表中较高百分比的行,扫描表会是最为有效的方法。

查询优化器使用索引时,搜索索引键列,查找到查询所需行的存储位置,然后从该位置提取匹配行。通常,搜索索引比搜索表要快很多,因为索引与表不同,一般每行包含的列非常少,且行遵循排序顺序。

查询优化器在执行查询时通常会选择最有效的方法。但如果没有索引,则查询优化器必须扫描表。您的任务是设计并创建最适合您的环境的索引,以便查询优化器可以从多个有效的索引中选择。SQL Server 提供的数据库引擎优化顾问可以帮助分析数据库环境并选择适当的索引。

怎么创建合适的索引

索引其实关键目的是为了加快检索速度而建立的,所以,怎么用索引是数据库系统本身的事情,作为数据库设计或使用者,设计并创建好索引然后体验加上索引后的查询变快的感觉就行了。

索引设计不佳和缺少索引是提高数据库和应用程序性能的主要障碍。 设计高效的索引对于获得良好的数据库和应用程序性能极为重要。为数据库及其工作负荷选择正确的索引是一项需要在查询速度与更新所需开销之间取得平衡的复杂任务。如果索引较窄,或者说索引关键字中只有很少的几列,则需要的磁盘空间和维护开销都较少。而另一方面,宽索引可覆盖更多的查询。您可能需要试验若干不同的设计,才能找到最有效的索引。可以添加、修改和删除索引而不影响数据库架构或应用程序设计。因此,应试验多个不同的索引而无需犹豫。

SQL Server 中的查询优化器可在大多数情况下可靠地选择最高效的索引。总体索引设计策略应为查询优化器提供可供选择的多个索引,并依赖查询优化器做出正确的决定。这在多种情况下可减少分析时间并获得良好的性能。若要查看查询优化器对特定查询使用的索引,请在 SQL Server Management Studio 中的“查询”菜单上选择“包括实际的执行计划”。

不要总是将索引的使用等同于良好的性能,或者将良好的性能等同于索引的高效使用。如果只要使用索引就能获得最佳性能,那查询优化器的工作就简单了。但事实上,不正确的索引选择并不能获得最佳性能。因此,查询优化器的任务是只在索引或索引组合能提高性能时才选择它,而在索引检索有碍性能时则避免使用它。

建议的索引设计策略包括以下任务:

  1. 了解数据库本身的特征。例如,它是频繁修改数据的联机事务处理 (OLTP) 数据库,还是主要包含只读数据的决策支持系统 (DSS) 或数据仓库 (OLAP) 数据库?
  2. 了解最常用的查询的特征。例如,了解到最常用的查询联接两个或多个表将有助于决定要使用的最佳索引类型。
  3. 了解查询中使用的列的特征。例如,某个索引对于含有整数数据类型同时还是唯一的或非空的列是理想索引。筛选索引适用于具有定义完善的数据子集的列。
  4. 确定哪些索引选项可在创建或维护索引时提高性能。例如,对现有某个大型表创建聚集索引将会受益于 ONLINE 索引选项。ONLINE 选项允许在创建索引或重新生成索引时继续对基础数据执行并发活动。
  5. 确定索引的最佳存储位置。非聚集索引可以与基础表存储在同一个文件组中,也可以存储在不同的文件组中。索引的存储位置可通过提高磁盘 I/O 性能来提高查询性能。例如,将非聚集索引存储在表文件组所在磁盘以外的某个磁盘上的一个文件组中可以提高性能,因为可以同时读取多个磁盘。

或者,聚集索引和非聚集索引也可以使用跨越多个文件组的分区方案。在维护整个集合的完整性时,使用分区可以快速而有效地访问或管理数据子集,从而使大型表或索引更易于管理。有关详细信息,请参阅已分区表和已分区索引。在考虑分区时,应确定是否应对齐索引,即,是按实质上与表相同的方式进行分区,还是单独分区。

设计索引

索引设计是一项关键任务。索引设计包括确定要使用的列,选择索引类型(例如聚集或非聚集),选择适当的索引选项,以及确定文件组或分区方案布置。

确定最佳的创建方法。按照以下方法创建索引

  1. 使用 CREATE TABLE 或 ALTER TABLE 对列定义 PRIMARY KEY 或 UNIQUE 约束
    SQL Server 数据库引擎自动创建唯一索引来强制 PRIMARY KEY 或 UNIQUE 约束的唯一性要求。默认情况下,创建的唯一聚集索引可以强制 PRIMARY KEY 约束,除非表中已存在聚集索引或指定了唯一的非聚集索引。默认情况下,创建的唯一非聚集索引可以强制 UNIQUE 约束,除非已明确指定唯一的聚集索引且表中不存在聚集索引。
    还可以指定索引选项和索引位置、文件组或分区方案。
    创建为 PRIMARY KEY 或 UNIQUE 约束的一部分的索引将自动给定与约束名称相同的名称。

  2. 使用 CREATE INDEX 语句或 SQL Server Management Studio 对象资源管理器中的“新建索引”对话框创建独立于约束的索引
    必须指定索引的名称、表以及应用该索引的列。还可以指定索引选项和索引位置、文件组或分区方案。默认情况下,如果未指定聚集或唯一选项,将创建非聚集的非唯一索引。若要创建筛选索引,请使用可选的 WHERE 子句。

创建索引

要考虑的一个重要因素是对空表还是对包含数据的表创建索引。对空表创建索引在创建索引时不会对性能产生任何影响,而向表中添加数据时,会对性能产生影响。

对大型表创建索引时应仔细计划,这样才不会影响数据库性能。对大型表创建索引的首选方法是先创建聚集索引,然后创建任何非聚集索引。在对现有表创建索引时,请考虑将 ONLINE 选项设置为 ON。该选项设置为 ON 时,将不持有长期表锁以继续对基础表的查询或更新。

资源来自百度

数据库的触发器

触发器的定义就是说某个条件成立的时候,你触发器里面所定义的语句就会被自动的执行。因此触发器不需要人为的去调用,也不能调用。

然后,触发器的触发条件其实在你定义的时候就已经设定好的了。这里面需要说明一下,触发器可以分为语句级触发器和行级触发器。详细的介绍可以参考网上的资料,简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发。而行级触发器则是在定义的了触发的表中的行数据改变时就会被触发一次。

具体举例:

  1. 在一个表中定义的语句级的触发器,当这个表被删除时,程序就会自动执行触发器里面定义的操作过程。这个就是删除表的操作就是触发器执行的条件了。

  2. 在一个表中定义了行级的触发器,那当这个表中一行数据发生变化的时候,比如删除了一行记录,那触发器也会被自动执行了。

触发器简介

触发器是一种特殊类型的过程。与普通过程不同的是,过程需要用户显式地调用才执行,而触发器则是当某些事件发生时,由Oracle自动执行。

触发器主要由如下几个部分组成

  • 触发事件:
  • 触发条件:
  • 触发对象:
  • 触发操作:

编写触发器时,需要注意以下几点

  • 触发器不接受参数。
  • 一个表上最多可以有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。还需要注意,各个触发器之间不能有矛盾。
  • 在一个表上的触发器越多,对在该表上的DML操作性能影响就越大。
  • 触发器最大为32KB。如果确实需要,可以先建立过程,然后在触发器中用CALL语句调用。
  • 在DML触发器中只能使用DML语句(select,insert,update,delete)。
  • 在系统触发器中只能包含DDL语句(create,alter,drop)。
  • 触发器中不能包含事务控制语句(commit,rollback,savepoint)。因为触发器是触发语句的一部门,触发语句被提交或回退时,触发器也就被提交或回退了。
  • 在触发器主体中调用的任何过程、函数都不能使用事务控制语句。
  • 在触发器主体中不能声明任何long和blob变量。新值new、旧值old也不能指向表中的任何long和blog列
  • 不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用都有较大区别。

数据库的存储过程

存储过程(Stored Procedure)是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库。中用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

在SQL Server 的系列版本中存储过程分为两类:

  • 系统提供的存储过程
  • 用户自定义存储过程。
  1. 系统过程主要存储在master 数据库中并以sp_为前缀,并且系统存储过程主要是从系统表中获取信息,从而为系统管理员管理SQL Server 提供支持。通过系统存储过程,MS SQL Server 中的许多管理性或信息性的活动(如了解数据库对象、数据库信息)都可以被顺利有效地完成。尽管这些系统存储过程被放在master 数据库中,但是仍可以在其它数据库中对其进行调用,在调用时不必在存储过程名前加上数据库名。而且当创建一个新数据库时,一些系统存储过程会在新数据库中被自动创建。

  2. 用户自定义存储过程是由用户创建并能完成某一特定功能(如查询用户所需数据信息)的存储过程。

存储过程在数据库中的作用是什么

第一:存储过程因为SQL语句已经预编绎过了,因此运行的速度比较快。
第二:存储过程可以接受参数、输出参数、返回单个或多个结果集以及返回值。可以向程序返回错误原因。
第三:存储过程运行比较稳定,不会有太多的错误。只要一次成功,以后都会按这个程序运行。
第四:存储过程主要是在服务器上运行,减少对客户机的压力。
第五:存储过程可以包含程序流、逻辑以及对数据库的查询。同时可以实体封装和隐藏了数据逻辑。
第六:存储过程可以在单个存储过程中执行一系列 SQL 语句。
第七:存储过程可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。

其实存储过程还可以控制权限,比如一个表不直接允许用户直接访问,但要求允许用户访问和修改其中一个或多个字段,那就可以通过一个存储过程来实现并允许该用户使用该存储过程。

还有,如果多条SQL语句执行过程中,过程环节返回了数据作为后面环节的输入数据,如果直接通过SQL语句执行,势必导致大量的数据通过网络返回到客户机,并在客户机运算;如果封装在存储过程中,则将运算放在服务器进行,不但减少了客户机的压力,同时也减少了网络流量,提高了执行的效率。

来自百度

  1. 的确的看你的需求了,处理比复杂的逻辑或多表的连接查询你最好用存储过程,这样可以提高你的服务器性能。
    2、视图本身是一张虚拟表,处理表与表关系不太复杂操作时也可以用了。
    3、触发器一般用在多表间级联操作更新或删除一个表中某个字段,那么相关其他表也一同更新或删除呀!

PHP 编码规范

当一个软件项目尝试着遵守公共一致的标准时,可以使参与项目的开发人员更容易了解项目中的代码、弄清程序的状况。使新的参与者可以很快的适应环境,防止部分参与者出于节省时间的需要,自创一套风格并养成终生的习惯,导致其它人在阅读时浪费过多的时间和精力。而且在一致的环境下,也可以减少编码出错的机会。缺陷是由于每个人的标准不同,所以需要一段时间来适应和改变自己的编码风格,暂时性的降底了工作效率。从使项目长远健康的发展以及后期更高的团队工作效率来考虑暂时的工作效率降低是值得的,也是必须要经过的一个过程。标准不是项目成功的关键,但可以帮助我们在团队协作中有更高的效率并且更加顺利的完成既定的任务。

  • 程序员可以了解任何代码,弄清程序的状况
  • 新人可以很快的适应环境
  • 防止新接触PHP的人出于节省时间的需要,自创一套风格并养成终生的习惯
  • 防止新接触PHP的人一次次的犯同样的错误
  • 在一致的环境下,人们可以减少犯错的机会
  • 程序员们有了一致的敌人

请详细阅读以下规范,并严格遵守。

约定

文件编码

所有文件,默认都用UTF-8编码,注释为中文。

其他涉及具体程序的代码,请调整您的编辑器文件编码为UTF-8,并关闭UTF-8 BOM的功能。请不要使用windows自带的记事本编辑项目文件。

命名

文件命名

文件名与类名保持一致,区分大小写。

类命名

使用骆驼法则
首字母大写
专有名词保持其默认大小写规范。

1
class UserController {}

接口类命名

使用 目录名称 + “_” + 骆驼法则的形式实现(首字母小写)
object/user/User_getUser.php

1
class User_getUser {}

函数命名

骆驼法则的形式实现,首字母小写,专有名词保持其默认大小写规范。

1
2
3
4
5
6
function getUser() {
}

function userAddslashes($value, $force = 0) {
return $value = is_array($value) ? true : false;
}

方法命名

使用骆驼法则,首字母小写, 接口对外提供的方法请声明为 public,其他接口本内部身使用的方法请全部声明为 private 。

1
2
3
4
5
6
7
8
public function stripvTag($s) {
$vtagRegexp = $this->getVtagRegexp();
return true;
}

private function getVtagRegexp() {
return 'something';
}

变量命名

使用骆驼法则,首字母小写。

1
$callbackFunctions;

常量命名

所有字母大写,单词之间用下划线分割。

1
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());

注释

注释是开源项目的重点,请务必重视。

头部注释

头部注释主要用来阐述此文件的版权,协议,作者,版本。对于核心开发组,请按照下列形式书写(你可以把它设置为代码模板)。

1
2
3
4
5
6
7
<?php
/*
More & Original PHP Framwork
Copyright (c) 2009 - 2010 Chuangpingke Inc.

$Id$
*/

其中author为作者的名称,请自己命名。version定义为$Id$是为了匹配svn的关键字,设置此文件的svn:keywords属性为id,每次提交以后,$Id$就会被替换为具体的版本信息,比如:

$Id: User_getUser.php 52 2010-03-31 08:24:35Z kimi $。

引用文件和定义常量注释

文件的引用和常量的定义一般都放置在文件的开头部分。

1
2
/** 定义GPC变量 **/
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());

多行注释,使用如下形式

1
2
3
4
5
6
7
8
/**
* 定义数据库缓存存储方式
* true表示...
* false表示...
*
*/
define('PHP_DB_FILECACHE', true);
define('PHP_DB_DBCACHE', false);

类(接口)注释

一个类(接口)在声明的时候必须声明其作用

1
2
3
4
5
6
/**
* 包含获取数据支持方法的类
*/
class UserController {
//....
}

函数(方法,接口)注释

函数(方法,接口)的声明注释参考phpdoc规范。注意,如果是无返回函数,必须指明@return void,请尽量在函数参数表中使用已知类型。如果函数中抛出异常则必须指明@throws <异常类型>。

1
2
3
4
5
6
7
8
/**
* 获取GPC变量。对于type为integer的变量强制转化为数字型
* @param string $key - 权限表达式
* @param string $type - integer 数字类型;string 字符串类型;array 数组类型
* @param string $var - R $REQUEST变量;G $GET变量;P $POST变量;C $COOKIE变量
* @return string
*/
function UserGetGPC($key, $type = 'integer', $var = 'R') {

程序行间注释

行间注释采用双斜线注释法,反斜杠与描述之间,应该保留一个空格

1
2
3
4
// 禁止对全局变量注入
if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS'])) {
exit('Request tainting attempted.');
}

书写规则

缩进

详细的代码缩进会在后面提到,这里需要注意的是,PHP项目中的代码缩进使用每个缩进的单位约定是一个TAB(4个空白字符宽度),需每个参与项目的开发人员在编辑器(UltraEdit、EditPlus、Zend Studio等)中进行强制设定,以防在编写代码时遗忘而造成格式上的不规范。

本缩进规范适用于PHP、Javascript中的函数、类、逻辑结构、循环等。

UNIX编码规范

如果你正在编写一个php文件,那么根据UNIX的C语言编码规范,必须留出最后一个空行。比如

1
2
3
4
<?php
// this is a test file
echo 'hello';
// <---这行留空

而且,如果此文件为纯php文件(没有嵌套HTML),请不要用?>符号结尾,保持最后一行留空即可。

大括号{}、if和switch

  • 首括号与关键词同行,尾括号与关键字同列;
  • if结构中,else和elseif与前后两个大括号同行,左右各一个空格。另外,即便if后只有一行语句,仍然需要加入大括号,以保证结构清晰;
  • switch结构中,通常当一个case块处理后,将跳过之后的case块处理,因此大多数情况下需要添加break。break的位置视程序逻辑,与case同在一行,或新起一行均可,但同一switch体中,break的位置格式应当保持一致。
    以下是符合上述规范的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if ($condition) {
switch ($var) {
case 1: echo 'var is 1'; break;
case 2: echo 'var is 2'; break;
default: echo 'var is neither 1 or 2'; break;
}
} else {
switch ($str) {
case 'abc':
$result = 'abc';
break;
default:
$result = 'unknown';
break;
}
}

运算符、小括号、空格、关键词

  • 每个运算符与两边参与运算的值或表达式中间要有一个空格;
  • 左括号“(” 应和函数关键词紧贴在一起,除此以外应当使用空格将“(”同前面内容分开;
  • 右括号“)”除后面是“)”以外,其他一律用空格隔开它们;
  • 除字符串中特意需要,一般情况下,在程序以及HTML中不出现两个连续的空格;
  • 任何情况下,PHP程序中不能出现空白的带有TAB或空格的行,即:这类空白行应当不包含任何TAB或空格。同时,任何程序行尾也不能出现多余的TAB或空格。多数编辑器具有自动去除行尾空格的功能,如果习惯养成不好,可临时使用它,避免多余空格产生;
  • 每段较大的程序体,上、下应当加入空白行,两个程序块之间只使用1个空行,禁止使用多行;
  • 程序块划分尽量合理,过大或者过小的分割都会影响他人对代码的阅读和理解。一般可以以较大函数定义、逻辑结构、功能结构来进行划分。少于15行的程序块,可不加上下空白行;
  • 说明或显示部分中,内容如含有中文、数字、英文单词混杂,应当在数字或者英文单词的前后加入空格。

根据上述原则,以下举例说明正确的书写格式:

1
2
3
4
5
6
7
$result = (($a + 1) * 3 / 2 + $num)) . ’Test’;
$condition ? func1($var) : func2($var);
$condition ? $long_statement
: $another_long_statement;
if ($flag) {
// Statements(more than 15 lines)
}

函数定义

  • 参数的名字和变量的命名规范一致;
  • 函数定义中的左小括号,与函数名紧挨,中间无需空格;
  • 开始的左大括号与函数定义为同一行,中间加一个空格,不要另起一行;
  • 具有默认值的参数应该位于参数列表的后面;
  • 函数调用与定义的时候参数与参数之间加入一个空格;
  • 必须仔细检查并切实杜绝函数起始缩进位置与结束缩进位置不同的现象。
1
2
3
4
5
function userGetGPC($k, $type = 'ini', $var = 'R') {
if ($flag) {
// Statement
}
}

rsync快速删除海量文件

由于业务侧使用时,一些脚本文件写的不够严谨,造成/var/spool/postfix/maildrop/目录经常被用户通知邮件文件堆满。而通过rm -rf * 删除时,会提示-bash: /bin/rm: Argument list too long 。通过ls |xargs rm -rf 进行删除时也耗时较长,这里可以通过rsync进行删除。

一、rsync删除文件
针对上面的问题,我们可以通过以下方法清空该目录:

1
2
3
4
先创建一个空目录
# mkdir /tmp/empty/
清空目标目录
# rsync --delete-before -avH --progress --stats /tmp/empty/ /var/spool/postfix/maildrop

选项说明:

  • -delete-before 接收者在传输之前进行删除操作
    – -progress 在传输时显示传输过程
  • -a 归档模式,表示以递归方式传输文件,并保持所有文件属性
  • -H 保持硬连接的文件
  • -v 详细输出模式
    – -stats 给出某些文件的传输状态

不过在使用上面的命令进行清理时,存在一个问题,清空后,目标目录的权限会和源目录的权限一样。如:/tmp/empty是root:root,而maildrop之前是postfix:postdrop ,执行之后也会maildrop目录的权限也会变成root:root 。由于-a权限是-rlptogD几个参数的集合,所以可以将og(owner:group)两个参数去掉。清空时自动保持之前的目录权限,如下:

1
rsync  --delete -rlptD /tmp/empty/ /var/spool/postfix/maildrop/

二、rsync与rm 删除速度比较
便于说明问题,我在一台主机上创建5万个空文件后再分别用rsync和rm 进行清理,以下是测试结果:

1
2
3
4
5
6
7
8
9
10
11
[root@www data1]# mkdir -p /tmp/empty/
[root@www data1]# mkdir 361way;seq 1 50000 | xargs -I{} touch 361way/file_{}
[root@www data1]# time rsync --delete -rlptD /tmp/empty/ /data1/361way/
real 0m0.149s
user 0m0.018s
sys 0m0.091s
[root@www data1]# seq 1 50000 | xargs -I{} touch 361way/file_{}
[root@www data1]# time rm -rf 361way/*
real 0m0.831s
user 0m0.366s
sys 0m0.464s

对比结果已经比较能说明问题了吧。

为什么rsync这么快呢?

rm删除内容时,将目录的每一个条目逐个删除(unlink),需要循环重复操作很多次;rsync删除内容时,建立好新的空目录,替换掉老目录,基本没开销。想要深层次的区分两个命令在调用系统函数时的区别,可以使用SystemTap工具进行分析(由于本人也不懂该工具的使用,所以这里就不献丑了)。

这里是列出了所有文件信息,并打印出一个需要执行的shell脚本

1
ls -al | grep "^-" | awk '{a=toupper(substr($9,1,1));b=substr($9,2);print("git mv "$9" "a""b);}'

输出结果

1
2
3
4
5
6
7
8
9
10
git mv ActiveAskController.class.php ActiveAskController.class.php
git mv AdController.class.php AdController.class.php
git mv AdboardController.class.php AdboardController.class.php
git mv AdminController.class.php AdminController.class.php
git mv AdminLogController.class.php AdminLogController.class.php
git mv AdminRoleController.class.php AdminRoleController.class.php
git mv AnalyseGeneralController.class.php AnalyseGeneralController.class.php
git mv AnalyseUserController.class.php AnalyseUserController.class.php
git mv ApplyController.class.php ApplyController.class.php
git mv ArticleCateController.class.php ArticleCateController.class.php

把文件名第一个字母改成大写。使用mv命令。

Git 的基本操作

Git 提交重置

  • git reset –hard HEAD

git解决冲突与merge
http://blog.csdn.net/lincyang/article/details/45269491

1
<th width="60">参考价格<a  href="javascript:void();" title="三级分类的参考价格(其他不用填)" class="help_icon" /></th>

Git 命令操作

git rev-list HEAD | wc -l 查看提交了多少次。

git log –graph 图形化查看GIT LOG日志。

git log –graph –oneline

git log -3 –oneline 显示3条日志

git log -3 显示3条日志的不同表示形式。

git log -p 显示修改内容

git log –stat 或 git log –stat –oneline 显示每次变更概要

log定制输出

git log --pretty=raw -1
git log --pretty=fuller -1 #显示作者和提交者。
git log --pretty=oneline -1 #提供最精简的日志输出
git show D --stat 显示里程碑及其提交。

文件追溯:git blame

git blame README
1
2
3
4
5
6
7
8
➜  chuangpinke git:(develop) ✗ git log --stat
848056fc (BenVim 2016-04-23 16:15:25 +0800 1) <U+FEFF>ALTER TABLE `gxr_items_cate` ADD `icon` VARCHAR(50) NOT NULL COMMENT '文
字图标 标识' AFTER `deep`;O
2f536062 (BenVim 2016-04-22 14:09:00 +0800 2) ALTER TABLE `gxr_items_cate` ADD `icon_type` VARCHAR(50) NOT NULL DEFAULT 'fa' COMMENT '文字图标类型' AFTER `deep`;
6fc821c9 (BenVim 2016-04-23 16:10:22 +0800 3)
6fc821c9 (BenVim 2016-04-23 16:10:22 +0800 4) ### 修改文件日志
6fc821c9 (BenVim 2016-04-23 16:10:22 +0800 5)
(END)

Git学习—改变历史

一、悔棋

git commit --amend 修改提交注释。

二、多步悔棋

回到之前2步前,把这两次提交合并为一个。或者是再修改后提交

git reset --soft HEAD^^ #