@xxliixin1993
2017-03-28T09:15:19.000000Z
字数 11906
阅读 1277
鸟哥php变量作用域分析
变量的值 类型 引用 放在zval
中, 而变量名放在_zend_executor_globals
结构中,symbol_table
是定义在函数外的变量 key存名字 value存指向zval的指针, 函数中定义的变量会放在active_symbol_table
struct _zend_executor_globals {
....
HashTable *active_symbol_table;/*活动符号表*/
HashTable symbol_table; /*全局符号表*/
HashTable included_files;
jmp_buf *bailout;
int error_reporting;
.....
}
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
worker_connections 设置可由一个worker进程同时打开的最大连接数。
multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接。
use [epoll|rtsig|select|poll] 设置用于复用客户端线程的轮询方法。如果你使用Linux 2.6+,你应该使用epoll。如果你使用*BSD,你应该使用kqueue。
gzip on
worker_connections #
; 设定单个worker进程所能够处理的最大并发连接数量;一般设为:worker_connections 51200; 所能接收的并发数为worker_connections * work_processes,若这个值大于65535就不会有效了keepalive_timeout #
; 长连接的超时时长,默认75s;send_timeout #
; 发送响应报文的超时时长;client_body_timeout #
; 读取http请求报文body部分的超时时长;worker_cpu_affinity cpumask
... 绑定cpumask
假设一共有四颗cpu,表示方法,超过8颗使用更多的位数
cpu1:0000 0001
cpu2:0000 0010
cpu3:0000 0100
cpu4:0000 1000
worker_cpu_affinity 00000001 00000010 00000100;
fastcgi相关配置
fastcgi的相关配置:
LNMP:php启用fpm模型;
location ~ \.php$ {
root /var/www/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME $doucment_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
# fastcgi_params在/etc/nginx/下,若编译时没指定配置文件则在/usr/local/nginx/conf/下
include fastcgi_params;
}
awk -F' ' '{print $1}' /var/log/nginx/access.log |sort|uniq -c|sort -rn|head -10
http://www.uml.org.cn/sjjm/201107145.asp
B+树
MyISAM索引实现 3个文件(表定义文件.frm 数据文件.MYD 索引文件.MYI)
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。
InnoDB索引实现 2个文件(表定义文件.frm 数据索引文件.ibd)
InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。叶节点包含了完整的数据记录,这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
聚簇索引的优点,就是提高数据访问性能。聚簇索引把索引和数据都保存到同一棵B+树数据结构中,并且同时将索引列与相关数据行保存在一起。这意味着,当你访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。
缺点:维护索引很昂贵,特别是插入新行或者主键被更新导至要分页(page split)的时候。表因为使用UUId作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更慢,所以建议使用int的auto_increment作为主键 如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用占用更多的物理空间
ACID
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
事务中的修改,即使没提交,对其他事务也都是可见的。
脏读:事务可以读取未提交的数据。
一个事务从开始知道提交之前,所做的修改对其他事务都是不可见的。避免脏读,但可以出现不可重复读和幻读。
解决了脏读的问题,可以保证在同一事务中多次读取记录的结果是相同的。但是这样也会出现幻读的情况,是指当某个事务在读取某个范围内的记录时另一个事务又在该范围内插入了新的记录,当之前的事务再读取到该范围的记录时,会产生幻行。这是MySQL的默认事务隔离级别。
在读取的每一行数据上都加锁,所以会避免脏读和幻读,但是会导致大量的超时和锁征用问题。
工厂
class Mysql {
public function __construct() {}
}
class SqlServer {
public function __construct() {}
}
class DataFactory {
public static function create($database_type) {
$type = ucfirst($database_type);
switch ($type) {
case 'Mysql':
return new Mysql();
break;
case 'Sqlserver':
return new SqlServer();
break;
default:
return false;
break;
}
}
}
单例
class A {
private static $instance;
private function __construct() {}
private function __clone() {}
public static function getInstance() {
if (self::$instance instanceof self) {
return self::$instance;
} else {
return new self();
}
}
}
策略模式 一种动作根据传入不同的对象做不同的事
interface BaseAgent {
public function alert();
}
class IE implements BaseAgent {
public function alert() {
echo 'IE';
}
}
class Chrome implements BaseAgent {
public function alert() {
echo 'Chrome';
}
}
class Browser {
public function call($anget_obj) {
$anget_obj->alert();
}
}
// $b = new Browser();
// $b->call(new IE()); ====> IE $b->call(new Chrome()); ======> Chrome
观察者模式 有时被称作发布/订阅模式 观察者模式定义了一种一对多的依赖关系 当主程序发生变化时需要通知所有观察者进行更新
interface Observerable {
public function update();
}
//主程序
class Game {
private $_observers = array();
public function register($sub) {
/* 注册观察者 */
$this->_observers[] = $sub;
}
public function trigger() {
if (!empty($this->_observers)) {
foreach ($this->_observers as $observer) {
$observer->update();
}
}
}
}
//第一关
class RoundOne implements Observerable {
public function update() {
echo 'callback ';
}
}
//第二关
class RoundTwo implements Observerable {
public function update() {
echo 'callback ';
}
}
//使用
$ro = new RoundOne();
$rt = new RoundTwo();
$g = new Game();
//注册
$g->register($ro);
$g->register($rt);
//Game do something后 发生更新通知
$g->trigger();
装饰模式 before after模式
interface IComponent {
public function display();
}
//待装饰对象
class Controller implements IComponent {
public function display() {
echo 'this is Controller';
}
}
//装饰器基类
class Decoration implements IComponent {
protected $_com;
public function register(IComponent $com) {
$this->_com = $com;
}
public function display() {
if (!empty($this->_com)) {
$this->_com->display();
}
}
}
//具体装饰器
class AfterBefore extends Controller implements IComponent {
public function display() {
echo '+ before +';
parent::display($this);
echo '+ after +';
}
}
$c = new Controller();
$ab = new AfterBefore();
$d = new Decoration();
$d->register($ab);
$d->display();
优点:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
缺点:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、增加了系统结构和实现的复杂性,有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
empty() 如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
isset() 检测变量是否设置,并且不是 NULL。
OSI:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
IP协议在OSI网络层 TCP协议在传输层
3次握手:
client请求连接->server确认连接并询问client是否确认->client确认
4次断开:
【注意】中断连接端可以是Client端,也可以是Server端。
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
TCP拥塞控制四个主要过程:
慢启动阶段:早期开发的TCP应用在启动一个连接时会向网络中发送大量的数据包,这样很容易导致路由器缓存空间耗尽,网络发生拥塞,使得TCP连接的吞吐量急剧下降。由于TCP源端无法知道网络资源当前的利用状况,因此新建立的TCP连接不能一开始就发送大量数据,而只能逐步增加每次发送的数据量,以避免上述现象的发生。具体地说,当建立新的TCP连接时,拥塞窗口(congestion window,cwnd)初始化为一个数据包大小。源端按cwnd大小发送数据,每收到一个ACK确认,cwnd就增加一个数据包发送量,这样cwnd就将随着回路响应时间(Round Trip Time,RTT)呈指数增长,源端向网络发送的数据量将急剧增加。事实上,慢启动一点也不慢,要达到每RTT发送W个数据包所需时间仅为RTT×logW。由于在发生拥塞时,拥塞窗口会减半或降到1,因此慢启动确保了源端的发送速率最多是链路带宽的两倍。
拥塞避免阶段:如果TCP源端发现超时或收到3个相同ACK副本时,即认为网络发生了拥塞(主要因为由传输引起的数据包损坏和丢失的概率很小(<<1%))。此时就进入拥塞避免阶段。慢启动阈值(ssthresh)被设置为当前拥塞窗口大小的一半;如果超时,拥塞窗口被置1。如果cwnd>ssthresh,TCP就执行拥塞避免算法,此时,cwnd在每次收到一个ACK时只增加1/cwnd个数据包,这样,在一个RTT内,cwnd将增加1,所以在拥塞避免阶段,cwnd不是呈指数增长,而是线性增长。
快速重传和快速恢复阶段:快速重传是当TCP源端收到到三个相同的ACK副本时,即认为有数据包丢失,则源端重传丢失的数据包,而不必等待RTO超时。同时将ssthresh设置为当前cwnd值的一半,并且将cwnd减为原先的一半。快速恢复是基于“管道”模型(pipe model)的“数据包守恒”的原则(conservation of packets principle),即同一时刻在网络中传输的数据包数量是恒定的,只有当“旧”数据包离开网络后,才能发送“新”数据包进入网络。如果发送方收到一个重复的ACK,则认为已经有一个数据包离开了网络,于是将拥塞窗口加1。如果“数据包守恒”原则能够得到严格遵守,那么网络中将很少会发生拥塞;本质上,拥塞控制的目的就是找到违反该原则的地方并进行修正。
发送者:
接收方:
持久化
AOF :相当于binlog,记录下所有命令
RDB :将数据直接写在磁盘文件中
五种数据类型:
list实现队列
一致性 HASH 算法我的理解,简单来说就是 , 在一个大的数据范围内的构建一个虚拟的环,首( 0 )尾( Integer.MAXVALUE )相接的圆环,然后通过 某种 HASH 算法 增加虚拟节点的方式( 1 个实体节点可以虚拟 N 个虚拟阶段,如 160 , 200 , 1000 等)让节点更为均匀的分别在环上。 KEY 请求的时候,也通过相同的某种 HASH 算法 计算出 HASH 值,然后在到环上定位同向最接近的虚拟节点,最后通过虚拟节点与实体节点的对应关系找到服务的实体节点。
http://www.cnblogs.com/WuNaiHuaLuo/p/5225330.html
优点: Memcached 进程运行之后,会预申请一块较大的内存空间,自己进行管理,用完之后再申请,不是每次需要的时候去向操作系统申请。Memcached将对象保存在一个巨大的Hash表中,它还使用NewHash算法来管理Hash表,从而获得进一步的性能提升。所以当分配给Memcached的内存足够大的时候,Memcached的时间消耗基本上只是网络Socket连接了
缺点: 数据是保存在内存当中的,一旦服务进程重启,数据会全部丢失
优点:缓存技术,编译型,速度快
缺点:浪费内存。如$_smarty_tpl_vars = $this->_tpl_vars;
,两个变量,占用了两倍以上的内存(虽然使用后unset掉了)。
浪费处理器。smarty语法最后是要转换成php脚本供输出的。转换要浪费处理器资源。如果是编译好的缓存中的脚本,则浪费判断是否有编译好的脚本的处理器时间。
用插入排序好 一次能排完
$arr = array(3,2,4,5,1,6,7,8,10,9);
function quick_sort($arr){
$len = count($arr);
if ($len <= 1) {
return $arr;
}
$left = array();
$right = array();
//标尺
$base = $arr[0];
for ($i=1;$i<$len;$i++) {
if ($arr[$i] > $base) {
$right[] = $arr[$i];
} else {
$left[] = $arr[$i];
}
}
$left = quick_sort($left);
$right = quick_sort($right);
return array_merge($left,array($base),$right);
}
function odd_even($arr){
$left = array();
$right = array();
foreach ($arr as $key => $val) {
if ($val & 1) {
//奇数
$left[] = $val;
} else {
$right[] = $val;
}
}
return array_merge($left,$right);
}
var_dump(odd_even(quick_sort($arr)));
$arr=array(1,43,54,62,21,66,32,78,36,76,39);
function getpao($arr)
{
$len=count($arr);
//设置一个空数组 用来接收冒出来的泡
//该层循环控制 需要冒泡的轮数
for($i=1;$i<$len;$i++)
{ //该层循环用来控制每轮 冒出一个数 需要比较的次数
for($k=0;$k<$len-$i;$k++)
{
if($arr[$k]>$arr[$k+1])
{
$tmp=$arr[$k+1];
$arr[$k+1]=$arr[$k];
$arr[$k]=$tmp;
}
}
}
return $arr;
}
function select_sort($arr) {
//实现思路 双重循环完成,外层控制轮数,当前的最小值。内层 控制的比较次数
//$i 当前最小值的位置, 需要参与比较的元素
for($i=0, $len=count($arr); $i<$len-1; $i++) {
//先假设最小的值的位置
$p = $i;
//$j 当前都需要和哪些元素比较,$i 后边的。
for($j=$i+1; $j<$len; $j++) {
//$arr[$p] 是 当前已知的最小值
if($arr[$p] > $arr[$j]) {
//比较,发现更小的,记录下最小值的位置;并且在下次比较时,应该采用已知的最小值进行比较。
$p = $j;
}
}
//已经确定了当前的最小值的位置,保存到$p中。
//如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可
if($p != $i) {
$tmp = $arr[$p];
$arr[$p] = $arr[$i];
$arr[$i] = $tmp;
}
}
//返回最终结果
return $arr;
}
<?php
#二分查找
function binarySearch(Array $arr, $target) {
$low = 0;
$high = count($arr) - 1;
while($low <= $high) {
$mid = floor(($low + $high) / 2);
#找到元素
if($arr[$mid] == $target) return $mid;
#中元素比目标大,查找左部
if($arr[$mid] > $target) $high = $mid - 1;
#重元素比目标小,查找右部
if($arr[$mid] < $target) $low = $mid + 1;
}
#查找失败
return false;
}
$arr = array(1, 3, 5, 7, 9, 11);
$inx = binarySearch($arr, 1);
var_dump($inx);
?>
#!/bin/bash
function list() {
for file in `ls $1`
do
if [ -d $1"/"$file ]
then
echo 'this is dir: '$1"/"$file
list $1"/"$file
else
echo $1"/"$file
fi
done
}
list $1
$arr = [3, 4, 5, 1, 2, 6, 9, 7, 10];
function qs($arr) {
$l = [];
$r = [];
if (count($arr) < 1) {
return $arr;
}
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] < $arr[0]) {
$r[] = $arr[$i];
} else {
$l[] = $arr[$i];
}
}
$l = qs($l);
$r = qs($r);
return array_merge($l, (array) $arr[0], $r);
}
print_r(qs($arr));exit;