@xxliixin1993
2018-07-21T16:29:09.000000Z
字数 11785
阅读 1078
从性能上说,静态方法效率要稍微高一些,但是它会常驻内存
静态调用是在一开始分配好内存,实例化是在创建对象的时候
1、存储变量的结构体变小,尽量使结构体里成员共用内存空间,减少引用,这样内存占用降低,变量的操作速度得到提升
2、字符串结构体的改变,字符串信息和数据本身原来是分成两个独立内存块存放,php7尽量将它们存入同一块内存,提升了cpu缓存命中率
3、数组结构的改变,数组元素和hash映射表在php5中会存入多个内存块,php7尽量将它们分配在同一块内存里,降低了内存占用、提升了cpu缓存命中率
4、改进了函数的调用机制,通过对参数传递环节的优化,减少一些指令操作,提高了执行效率
鸟哥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}' access.log| sort|uniq -c|head -10
1NF:字段不可分;
2NF:有主键,非主键字段依赖主键;
3NF:非主键字段不能相互依赖;
解释:
1NF:原子性 字段不可再分,否则就不是关系数据库;
2NF:唯一性 一个表只说明一个事物;
3NF:有主键 每列都与主键有直接关系,不存在传递依赖;
http://www.uml.org.cn/sjjm/201107145.asp
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作为主键 如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用占用更多的物理空间
工厂
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 {
self::$instance = new self();
return self::$instance;
}
}
}
策略模式 一种动作根据传入不同的对象做不同的事
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、增加了系统结构和实现的复杂性,有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
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实现队列
https://www.cnblogs.com/houziwty/p/5167075.html
一致性 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连接了
缺点: 数据是保存在内存当中的,一旦服务进程重启,数据会全部丢失
用插入排序好 一次能排完
$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]) {
$l[] = $arr[$i];
} else {
$r[] = $arr[$i];
}
}
$l = qs($l);
$r = qs($r);
return array_merge($l, (array) $arr[0], $r);
}
print_r(qs($arr));exit;