本教程是本人基於 360大牛:全面解讀PHP面試的課程所作的筆記,加上我我的對一些其餘知識的補充,聚集了一些其餘教程聚集。衆人智慧結晶,我的總結所得
轉載請註明出處 PHP面試複習知識點(超級全面,由淺入深)
字符串和數字用等於模糊判斷時,字符串會被先轉換成數字再進行對比
示例代碼eq.phpphp
<?php $arr = [ "'0e123' == ''" => '0e123' == '', "'0e123' == '0'" => '0e123' == '0', "'0e123' == 0" => '0e123' == 0, "'0e123' == 'e'" => '0e123' == 'e', "'0e123' == '000'" => '0e123' == '000', "'1e123' == '1'" => '1a000e123' == '1', "'1e123' == 1" => '1a000e123' == 1, "'000e123' == '0'" => '000e123' == '0', "'e123' == 0" => 'a123' == 0, "'e123' == '0'" => 'a123' == '0', "null == 0" => null == 0, "null == '0'" => null == '0', "null == false" => null == false, "[] == 0" => [] == 0, "[] == '0'" => [] == '0', "[] == false" => [] == false, "false == 0" => false == 0, "false == '0'" => false == '0', ]; foreach ($arr as $key => $value) { echo '( ' . $key . ' ) => ' . ($value === true ? 'true' : 'false') . PHP_EOL; }
輸出結果css
( '0e123' == '' ) => false ( '0e123' == '0' ) => true ( '0e123' == 0 ) => true ( '0e123' == 'e' ) => false ( '0e123' == '000' ) => true ( '1e123' == '1' ) => false ( '1e123' == 1 ) => true ( '000e123' == '0' ) => true ( 'e123' == 0 ) => true ( 'e123' == '0' ) => false ( null == 0 ) => true ( null == '0' ) => false ( null == false ) => true ( [] == 0 ) => false ( [] == '0' ) => false ( [] == false ) => true ( false == 0 ) => true ( false == '0' ) => true
$_SERVER['SERVER_ADDR'] //服務器地址 $_SERVER['SERVER_NAME'] //服務名稱 $_SERVER['REQUEST_TIME'] //請求時間 $_SERVER['QUERY_STRING'] //請求地址中問號後的內容 $_SERVER['HTTP_REFERER'] //上次請求地址 $_SERVER['HTTP_USER_AGENT'] //瀏覽器信息 $_SERVER['REMOTE_ARRR'] //客戶端請求ip $_SERVER['REQUEST_URI'] // 請求中腳本名稱 $_SERVER['PATH_INFO'] // 請求中路徑
必定定義,不可刪除和修改html
用不一樣名字訪問同一個變量內容,用『&』符號表示前端
示例代碼abstract_class.phpmysql
<?php abstract class Animal { protected $name = 'animal'; abstract public function call(); abstract public function run(); public function getName() { return $this->name; } } class Cat extends Animal { protected $name = 'cat'; public function call() { echo $this->getName() . ': 喵喵叫~' . PHP_EOL; } public function run() { echo $this->getName() . '在跑~' . PHP_EOL; } } class Dog extends Animal { protected $name = 'dog'; public function call() { echo $this->getName() . ': 汪汪叫~' . PHP_EOL; } public function run() { echo $this->getName() . '在跑~' . PHP_EOL; } } $cat = new Cat; $cat->call(); $cat->run(); $dog = new Dog; $dog->call(); $dog->run();
運行結果:react
cat: 喵喵叫~ cat在跑~ dog: 汪汪叫~ dog在跑~
示例代碼interface_class.phpnginx
<?php interface Animal { public function call(); public function run(); } class HasName { protected $name = 'name'; public function getName() { return $this->name; } } class Cat extends HasName implements Animal { protected $name = 'cat'; public function call() { echo $this->getName() . ': 喵喵叫~' . PHP_EOL; } public function run() { echo $this->getName() . '在跑~' . PHP_EOL; } } class Dog extends HasName implements Animal { protected $name = 'dog'; public function call() { echo $this->getName() . ': 汪汪叫~' . PHP_EOL; } public function run() { echo $this->getName() . '在跑~' . PHP_EOL; } }
輸出結果laravel
cat: 喵喵叫~ cat在跑~ dog: 汪汪叫~ dog在跑~
implements
,抽象類使用extends
interface
,抽象類定義用abstract
優先級由高到低排序
緣由:由於計算機存儲是二進制,準換進制時會有精度丟失git
解決方案:先將浮點字符串化,再進行整數獲取,輸出可經過printgithub
$f = 0.57; $f = $f * 100; // 輸入可經過print printf('%d', $f); // 用於存儲或二次計算,先將浮點字符串化,再進行整數獲取 $f = strval($f); var_dump($f); echo floor($f); echo intval($f); echo (int)($f);
global
定義,能夠在局部域調用全局變量,可經過$GLOBAL['XXX']
讀取變量的值static
定義,僅在局部域中存在,執行函數離開做用域,其值也不會消失示例代碼ip.php
<?php $ip = '192.168.1.1'; echo $ip. ' => ' . ip2long($ip) . ' => ' . long2ip(ip2long($ip)); // 輸出 // 192.168.1.1 => 3232235777 => 192.168.1.1
示例代碼print.php
<?php print('aaaaaa'); echo PHP_EOL; printf("%s:%2.2f", 'sada', 111.222); echo PHP_EOL; print_r([1, 2]); echo PHP_EOL; echo 11; echo PHP_EOL; echo sprintf("%s:%2.2f", 'sada', 111.222); echo PHP_EOL; var_dump([1, 2]); echo PHP_EOL; var_export([1, 2]); echo PHP_EOL; echo var_export([1, 2], true); echo PHP_EOL;
輸出結果
aaaaaa sada:111.22 Array ( [0] => 1 [1] => 2 ) 11 sada:111.22 array(2) { [0]=> int(1) [1]=> int(2) } array ( 0 => 1, 1 => 2, ) array ( 0 => 1, 1 => 2, )
示例代碼serialize.php
<?php $a = 'klinson'; echo $a . ' =>' . serialize($a) . ' => ' . unserialize(serialize($a));
輸出結果
klinson => s:7:"klinson"; => klinson
示例代碼string.php
<?php $str = 'klinson'; $array = explode('n', $str); var_dump($array, join('n', $array), implode('n', $array)); echo 'strrev(\'klinson\') => ' . strrev($str) . PHP_EOL; $str = ' klinson '; var_dump(trim($str), ltrim($str), rtrim($str)); echo 'strstr(\'klinson\', \'n\') => '.strstr($str, 'n') . PHP_EOL; echo 'number_format(100000000000) => ' . number_format(100000000000) . PHP_EOL;
輸出結果
array(3) { [0]=> string(3) "kli" [1]=> string(2) "so" [2]=> string(0) "" } string(7) "klinson" string(7) "klinson" strrev('klinson') => nosnilk string(7) "klinson" string(8) "klinson " string(8) " klinson" strstr('klinson', 'n') => nson number_format(100000000000) => 100,000,000,000
php.ini
中打開allow_url_fopen
配置,http協議只能使用只讀,ftp協議,只能只讀或只寫
示例代碼fileinfo.php
<?php $filepath = __FILE__; echo '__FILE__ => ' . $filepath . PHP_EOL; echo 'basename(__FILE__) => ' . basename($filepath) . PHP_EOL; echo 'dirname(__FILE__) => ' . dirname($filepath) . PHP_EOL; echo 'pathinfo(__FILE__) => ' . PHP_EOL; var_dump(pathinfo($filepath));
輸出結果
__FILE__ => /home/wwwroot/default/public/index0.php basename(__FILE__) => index0.php dirname(__FILE__) => /home/wwwroot/default/public pathinfo(__FILE__) => array(4) { ["dirname"]=> string(28) "/home/wwwroot/default/public" ["basename"]=> string(10) "index0.php" ["extension"]=> string(3) "php" ["filename"]=> string(6) "index0" }
目錄必須爲空
工廠模式
工廠模式能夠將對象的生產從直接new 一個對象,改爲經過調用一個工廠方法生產。這樣的封裝,代碼若需修改new的對象時,不需修改多處new語句,只需更改生產對象方法
示例代碼factory.php
<?php /*** Interface people 人類 */ interface people { public function say(); } /*** Class man 繼承people的男人類 */ class man implements people { // 實現people的say方法 function say() { echo '我是男人-hi' . PHP_EOL; } } /* Class women 繼承people的女人類 */ class women implements people { // 實現people的say方法 function say() { echo '我是女人-hi' . PHP_EOL; } } /* Interface createPeople 建立人物類 */ interface createPeople { public function create(); } /* Class FactoryMan 繼承createPeople的工廠類-用於實例化男人類 */ class FactoryMan implements createPeople { // 建立男人對象(實例化男人類) public function create() { return new man(); } } /* Class FactoryMan 繼承createPeople的工廠類-用於實例化女人類 */ class FactoryWomen implements createPeople { // 建立女人對象(實例化女人類) function create() { return new women(); } } class Client { // 具體生產對象並執行對象方法測試 public function test() { $factory = new FactoryMan(); $man = $factory->create(); $man->say(); $factory = new FactoryWomen(); $man = $factory->create(); $man->say(); } } // 執行 $demo = new Client; $demo->test();
輸出結果
我是男人-hi 我是女人-hi
單例模式
用於爲一個類生成一個惟一的對象
示例代碼singleton.php
<?php class Db { protected static $instance; public static function getInstance($config = []) { if (is_null(self::$instance)) { self::$instance = new self($config); } return self::$instance; } public function __construct($config = []) { // TODO:: 數據庫鏈接操做 echo '這裏已經完成數據庫的鏈接!' . PHP_EOL; } public function getData($table) { // TODO:: 數據庫讀取數據操做 echo "這裏獲取了表 [ {$table} ] 的數據了!" . PHP_EOL; } } Db::getInstance()->getData('klinson0'); Db::getInstance()->getData('klinson1'); Db::getInstance()->getData('klinson2');
輸出結果
已經完成數據庫的鏈接! 這裏獲取了表 [ klinson0 ] 的數據了! 這裏獲取了表 [ klinson1 ] 的數據了! 這裏獲取了表 [ klinson2 ] 的數據了!
適配器模式
適配器模式將一個類的接口轉換成客戶但願的另一個接口,使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠在一塊兒工做
示例代碼adapter.php
<?php /* 微博提供的登陸類
*/ class Weibo { public function myLogin($username,$password){ echo $username.' is logining weibo with password '. $password. PHP_EOL; } } /* 微信提供的登陸類 */ class Weixin { public function login2($config){ echo $config['username'].' is logining weixin with password '. $config['password']. PHP_EOL; } } /* 咱們設計的適配器接口 */ interface Adapter { public function login($username, $password); } /* 微博的適配器 */ class WeiboAdapter extends Weibo implements Adapter { public function login($username, $password) { $this->myLogin($username, $password); } } /* 微信的適配器類 */ class WeixinAdapter extends WeiXin implements Adapter { public function login($username, $password) { $this->login2(['username'=>$username, 'password'=> $password]); } } /* 主業務類 */ class User { private $adapter; public function setAdapter(Adapter $adapter) { $this->adapter = $adapter; } public function login($username, $password){ $this->adapter->login($username, $password); } } $weiboUser = new User(); // 實例化微博適配器 $adapter = new WeiboAdapter(); // 設置適配器 $weiboUser->setAdapter($adapter); $weiboUser->login('klinson', '123456'); $Wxuser = new User(); // 實例化微博適配器 $adapter = new WeixinAdapter(); // 設置適配器 $Wxuser->setAdapter($adapter); $Wxuser->login('klinson', '123456'); ``` 輸出結果 ``` klinson is logining weibo with password 123456 klinson is logining weixin with password 123456 ```
觀察者模式有時也被稱做發佈/訂閱模式,該模式用於爲對象實現發佈/訂閱功能:一旦主體對象狀態發生改變,與之關聯的觀察者對象會收到通知,並進行相應操做。
將一個系統分割成一個一些類相互協做的類有一個很差的反作用,那就是須要維護相關對象間的一致性。咱們不但願爲了維持一致性而使各種緊密耦合,這樣會給維護、擴展和重用都帶來不便。觀察者就是解決這類的耦合關係的。
消息隊列系統、事件都使用了觀察者模式。
PHP 爲觀察者模式定義了兩個接口:SplSubject 和 SplObserver。SplSubject 能夠看作主體對象的抽象,SplObserver 能夠看作觀察者對象的抽象,要實現觀察者模式,只需讓主體對象實現 SplSubject ,觀察者對象實現 SplObserver,並實現相應方法便可。
定義一系列算法,將每個算法封裝起來,並讓它們能夠相互替換。策略模式讓算法獨立於使用它的客戶而變化,也稱爲政策模式(Policy)
註冊樹模式
註冊模式(Registry)也叫作註冊樹模式,註冊器模式。註冊模式爲應用中常用的對象建立一箇中央存儲器來存放這些對象 —— 一般經過一個只包含靜態方法的抽象類來實現(或者經過單例模式)。參考laravel
框架的app()
定義
示例代碼register.php
<?php class Register { // 樹的枝幹-用於儲存樹上的果實(實例) public static $objects; /** 將實例插入註冊樹中 * ** @param $alias 對象別名-註冊樹中的名稱 ** @param $object 對象實例 */ public static function set($alias, $object) { self::$objects[$alias] = $object; } /** ** 從註冊樹中讀取實例 * ** @param $alias 對象別名-註冊樹中的名稱 * ** @return mixed 返回的對象實例 */ public static function get($alias) { if (isset(self::$objects[$alias])) { return self::$objects[$alias]; } else { echo '您要找的對象實例不存在哦' . PHP_EOL; return false; } } /** ** 銷燬註冊樹中的實例 * ** @param $alias 對象別名-註冊樹中的名稱 */ public static function unset($alias) { unset(self::$objects[$alias]); } } /** ** Class demo 演示類 */ class demo { /* ** 測試方法 */ public function test() { echo '看這裏看這裏' . PHP_EOL; } } // 實例化測試類,獲取對象實例 $demo = new demo(); // 註冊到樹上 $tree = Register::set('demo', $demo); // 取出來 $de_true = Register::get('demo'); // 測試 $de_true->test(); // 銷燬 Register::unset('demo'); // 嘗試再次取出來 $de_true_two = Register::get('de'); // 嘗試再次測試 var_dump($de_true_two);
輸出結果
看這裏看這裏 您要找的對象實例不存在哦 bool(false)
對稱加密又叫作私鑰加密,即信息的發送方和接收方使用同一個密鑰去加密和解密數據
對稱加密的特色是算法公開、加密和解密速度快,適合於對大數據量進行加密
常見的對稱加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。
其加密過程以下:明文 + 加密算法 + 私鑰 => 密文
解密過程以下:密文 + 解密算法 + 私鑰 => 明文
對稱加密中用到的密鑰叫作私鑰,私鑰表示我的私有的密鑰,即該密鑰不能被泄露。
其加密過程當中的私鑰與解密過程當中用到的私鑰是同一個密鑰,這也是稱加密之因此稱之爲「對稱」的緣由。因爲對稱加密的算法是公開的,因此一旦私鑰被泄露,那麼密文就很容易被破解,因此對稱加密的缺點是密鑰安全管理困難。
非對稱加密也叫作公鑰加密。
非對稱加密與對稱加密相比,其安全性更好。對稱加密的通訊雙方使用相同的密鑰,若是一方的密鑰遭泄露,那麼整個通訊就會被破解。而非對稱加密使用一對密鑰,即公鑰和私鑰,且兩者成對出現。私鑰被本身保存,不能對外泄露。
公鑰指的是公共的密鑰,任何人均可以得到該密鑰。用公鑰或私鑰中的任何一個進行加密,用另外一個進行解密。
被公鑰加密過的密文只能被私鑰解密,過程以下:
明文 + 加密算法 + 公鑰 => 密文, 密文 + 解密算法 + 私鑰 => 明文
被私鑰加密過的密文只能被公鑰解密,過程以下:(私鑰加密,公鑰解密通常被用於數字簽名。數字簽名是用於防篡改和防止假冒的,由於只有一人擁有私鑰。甲方經過私鑰對數據進行簽名,乙方經過甲方的公鑰驗證簽名,若是成功,說明確實是甲方發來的,而且數據沒有被修改。一旦相反,公鑰是公開的,你們都能作簽名,就沒意義了)
明文 + 加密算法 + 私鑰 => 密文, 密文 + 解密算法 + 公鑰 => 明文
因爲加密和解密使用了兩個不一樣的密鑰,這就是非對稱加密「非對稱」的緣由。
非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少許數據進行加密。
在非對稱加密中使用的主要算法有:RSA、Elgamal、Rabin、D-H、ECC(橢圓曲線加密算法)等。
工做特色:
工做原理:
客戶端發送請求給服務器,創建一個TCP鏈接,指定端口號,默認80,鏈接到服務器,服務器監聽到瀏覽器的請求,一旦監聽到客戶端的請求,分析請求類型後,服務器會向客戶端發送狀態信息和數據內容
HTTPS是一種基於SSL/TLS的HTTP協議,全部的HTTP數據都是SSL/TLS協議封裝之上傳輸的
HTTPS是在HTTP協議的基礎上,添加了SSL/TLS握手一級數據加密傳輸,也屬於應用層協議
HTTPS爲了兼顧安全與效率,同時使用了對稱加密(快)和非對稱加密(慢)。數據是被對稱加密傳輸的,對稱加密過程須要客戶端的一個密鑰,爲了確保能把該密鑰安全傳輸到服務器端,採用非對稱加密對該密鑰進行加密傳輸,總的來講,對數據進行對稱加密,對稱加密所要使用的密鑰經過非對稱加密傳輸。
如下圖片來源 圖解HTTPS
HTTPS在傳輸的過程當中會涉及到三個密鑰:
服務器端的公鑰和私鑰,用來進行非對稱加密
客戶端生成的隨機密鑰,用來進行對稱加密
一個HTTPS請求實際上包含了兩次HTTP傳輸,能夠細分爲8步。
8.客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,獲得服務器發送的數據。這樣HTTPS中的第二個HTTP請求結束,整個HTTPS傳輸完成。
默認事務型引擎,最重要最普遍的存儲引擎,性能很是優秀
數據存儲在共享表空間,可經過配置分開
對主鍵查詢的性能高於其餘類型的存儲引擎
內部作了不少優化,從磁盤讀取數據時自動在內存構建hash索引,插入數據時自動構建插入緩衝區
經過一些機制和工具支持真正的熱備份
支持崩潰後的安全恢復
支持行級鎖
支持外鍵
5.1版本前是默認引擎
擁有全文索引、壓縮、空間函數
不支持事務和行級鎖,不支持奔潰後安全恢復
表存儲在兩個文件,MYD和MYI
設計簡單,某些場景下性能很好
Archive、Blackhole、CSV、Memory
當多個查詢同一時刻進行數據修改時,會產生併發控制的問題
系統性能開銷最小,會鎖定整張表,myisam使用表鎖
最大程度的支持併發處理,可是也帶來了最大的鎖開銷,innodb實現行級鎖
char是定長的,根據定義的字符串長度分配足量空間 char會根據須要採用空格進行填充以方便比較 char適合存儲很短的字符串,或者全部值都接近同一個長度 char長度超過設定的長度,會被截斷
varchar用於存儲可變長字符串,比定長類型更加節省空間 varchar使用1或2個額外字節記錄字符串的長度,列長度小於255字節用1個字節表示,不然用2個 varchar長度超過設定的長度,會被截斷
對於常常變動的數據,char比varchar更好,char不容易產生碎片 對於很是短的列,char比varchar在存儲空間上更有效率 只分配真正須要的空間,更長的列會消耗更多的內存
set profiling=1;
開啓,服務器上執行的全部語句消耗時間都會記錄到臨時表。show profile for query QUERY_ID
查詢指定查詢count(*)
會忽略全部列,直接統計全部列數,所以不要用count(列名)
GROUP BY
和ORDER BY
中只有一個表的列,這樣MySQL纔有可能使用索引GROUP BY
和DISTINCT
,創建索引進行優化LIMIT
分頁,能夠經過記錄上次查詢的最大ID,若是根據id排序時,下次查詢根據該ID來查詢(如:ID > maxID)UNION
查詢,UNION ALL
性能比UNION
高對用戶而言,分區表是一個獨立的邏輯表,可是底層MySQL將其分紅了多個物理子表,對於用戶來講是透明的,每個分區表都會使用一個獨立的表文件。
建立表的時候使用partition by
子句定義每一個分區存放的數據,執行查詢時,優化器會根據分區定義過濾那些沒有咱們須要數據的分區,這樣查詢只須要查詢所需數據在的分區便可
分區的主要目的是將數據按照一個較粗的粒度分在不一樣的表中,這樣能夠將相關的數據存放在一塊兒,並且若是想一次性刪除整個分區的數據也很方便
經過一些HASH算法或者工具實現將一張數據表垂直或者水平物理切分
使用場景: 1. 表中數據自己就有獨立性,例如表中分別記錄各個地區的數據或者不一樣時期的數據,特別是有些數據經常使用,有些不經常使用 2. 須要把數據存放在多個介質 缺點: 1. 給應用增長複雜度,一般查詢時須要多個表名,查詢全部數據都須要UNION操做 2. 在許多數據庫應用中,這種複雜性會超過他帶來的優勢,查詢時會增長讀一個索引層的磁盤次數
使用場景: 1. 若是一個表中某些列經常使用,而另一些列不經常使用 2. 可使數據行變小,一個數據頁能存儲更多數據,查詢時減小I/O次數 缺點: 1. 管理冗餘列,查詢全部數據須要JOIN操做 2. 有些分表的策略基於應用層的邏輯算法,一旦邏輯算法改變,整個分表邏輯都會改變,擴展性較差 3. 對於應用層來講,邏輯算法無疑增長開發成本
用一個處理程序文件處理全部的HTTP請求,根據請求時的參數的不一樣區分不一樣的模塊和操做請求
PHP是一種HTML內嵌式在服務端執行的腳本語言,可是PHP又不少可使PHP代碼和HTML代碼分開的模板引擎,例如:smarty
模板引擎就是龐大的完善的正則表達式替換庫
示例代碼sort.php
原理:兩兩相鄰的數進行比較,若是反序就交換,不然不交換
時間複雜度:最壞(O(n^2)), 平均(O(n^2))
空間複雜度:O(1)
function bubbling_sort($arr) { $len = count($arr); if ($len <= 1) return $arr; for ($i = 0; $i < $len - 1; $i++) { for ($j = 0; $j < $len - $i -1; $j++) { if ($arr[$j] > $arr[$j+1]) { $tmp = $arr[$j+1]; $arr[$j+1] = $arr[$j]; $arr[$j] = $tmp; } } } return $arr; }
原理:經過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的全部數據和另外一部分的全部數據都要笑,而後按照此方法對這兩部分數據分別進行快速排序,整個排序過程能夠遞歸完成
時間複雜度:最壞(O(n^2)), 平均(O(nlog2n))
空間複雜度:最差(O(n)),平均(O(log2n))
function quick_sort($arr) { $len = count($arr); if ($len <= 1) return $arr; $base = $arr[0]; $left = []; $right = []; 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, [$base], $right); }
原理:每次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,知道所有待排序的數據元素排外
時間複雜度:最壞(O(n^2)), 平均(O(n^2))
空間複雜度:O(1)
function select_sort($arr) { $len = count($arr); if ($len <= 1) return $arr; for ($i = 0; $i < $len - 1; $i++) { $min = $i; for ($j = $i+1; $j < $len; $j ++) { if ($arr[$min] > $arr[$j]) { $min = $j; } } if ($min !== $i) { $tmp = $arr[$i]; $arr[$i] = $arr[$min]; $arr[$min] = $tmp; } } return $arr; }
原理:每次從無序表中取出第一個元素,把他插入到有序表的合適位置,使有序表仍然有序
時間複雜度:最壞(O(n^2)), 平均(O(n^2))
空間複雜度:O(1)
原理:把待排序的數據根據增量分紅幾個子序列,對子序列進行插入排序,知道增量爲1,直接插入進行插入排序;增量的排序,通常是數組的長度的一半,再變爲原來增量的一半,直到增量爲1
時間複雜度:最壞(O(n^2)), 平均(O(nlog2n))
空間複雜度:O(1)
原理:把待排序的元素按照大小在二叉樹位置上排序,排序好的元素要知足:父節點的元素要大於子節點;這個過程叫作堆化過程,若是根節點存放的最大的數,則叫作大根堆,若是是最小,就叫小跟堆,能夠把根節點拿出來,而後再堆化,循環到最後一個節點
時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))
空間複雜度:O(1)
原理:將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分爲若干個有序的子序列,再把有序的子序列合併爲總體有序序列
時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))
空間複雜度:O(n)
原理:從數組的中間元素開始,若是中間元素正好是要查找的元素,搜索結果,若是某一個特定元素大於或者小於中間元素的那一半中查找,並且跟開始同樣從中間開始比較,若是某一步驟數組爲空,表明找不到
時間複雜度:最壞(O(nlog2n)), 平均(O(nlog2n))
空間複雜度:迭代(O(1)), 遞歸(O(log2n))
原理:按必定的順序檢查數組中每個元素,直到要找到鎖要尋找的特定指爲止
時間複雜度:最壞(O(n)), 平均(O(n))
空間複雜度:O(1)
B-Tree是爲磁盤等外存儲設備設計的一種平衡查找樹
一棵m階的B-Tree有以下特性:
B+Tree是在B-Tree基礎上的一種優化,使其更適合實現外存儲索引結構,InnoDB存儲引擎就是用B+Tree實現其索引結構。
B+Tree相對於B-Tree有幾點不一樣:
ab,wrk,Apache JMeter, http_load, Web Bench, Siege
# 模擬併發請求100次,總請求5000次 ab -c 100 -n 5000 http://example.com
防止別人經過一些技術手段繞過本站的資源展現頁面,盜用本站的資源,讓繞開本站資源展現頁面的資源連接失效,能夠大大減輕服務器及帶寬的壓力
valid_referers none|blocked|server_names|string...;
配置例子:
location ~.*\.(gif|jpg|png|flv|swf|rar}zip)$ { valid_referers none blocked imooc.com *.imooc.com; if ($invalid_referer) { #return 403; rewrite ^/ http://www.imooc.com/403.jpg; } }
優先級:Pragma > Cache-Control > Expires
add_header name value [always];
,能夠設置Pragma、Expires、Cache-Control,能夠繼承expires time;
etag on|off
,默認ongzip on|off; #是否開啓gzip gzip_buffers 32 4K|16 8K; #緩衝(在內存中緩存幾塊?每塊多大) gzip_comp_level [1-9] #推薦6,壓縮級別(級別越高,壓得越小,越浪費CPU計算資源) gzip_disable #正則匹配UA,什麼樣的Uri不進行gzip gzip_min_length 200 #開始壓縮的最小長度 gzip_http_version 1.0|1.1 #開始壓縮的http協議版本 gzip_proxied #設置請求者代理服務器,該如何緩存內容 gzip_types text/plain application/xml image/png #對哪些類型的文件壓縮,如txt、xml、css gzip_vary on|off #是否傳輸gzip壓縮標誌
將現有的PHP等動態語言的邏輯代碼生成爲靜態的HTML文件,用戶訪問動態腳本重定向到靜態HTML文件的過程。對實時性要求不高
ob_start();//打開輸出控制緩衝 ob_get_content();//返回輸出緩衝區內容 ob_clean();//清空輸出緩衝區 ob_end_flush();//沖刷出(送出)輸出緩衝區內容並關閉緩衝
是計算機中程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單元,是操做系統結構的基礎。進程是一個執行中的程序
進程的三態模型:運行、就緒、阻塞
進程的五態模型:新建態、活躍就緒/靜止就緒、運行、活躍阻塞/靜止阻塞、終止態
線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程本身不擁有系統資源,只擁有一點兒在運行中必不可少的資源但它可與同屬一個進程的其它線程共享進程所擁有的所有資源。
一個線程能夠建立和撤消另外一個線程,同一進程中的多個線程之間能夠併發執行。
線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位指運行中的程序的調度單位。
在單個程序中同時運行多個線程完成不一樣的工做,稱爲多線程。
協程是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。協程擁有本身的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切換很是快。
如今各類高併發異步IO的服務器程序都是基於epoll實現的
IO複用異步非阻塞程序使用經典的Reactor模型,Reactor顧名思義就是反應堆的意思,它自己不處理任何數據收發。只是能夠監視一個 socket句柄的事件變化
常見reactor模型
查詢緩存能夠看作是SQL文本和查詢結果的映射,第二次查詢的SQL和第一次查詢的SQL全相同,則會使用緩存
表的結構或數據發生改變時,查詢緩存中的數據再也不有效
query_cache_type
查詢緩存類型,有0、一、2三個取值。0則不使用查詢緩存。1表示始終使用查詢緩存。2表示按需使用查詢緩存。
query_cache_size
默認狀況下 query_cache_size
爲0,表示爲查詢緩存預留的內存爲0,則沒法使用查詢緩存
SET GLOBAL query_cache_size= 134217728
querycache_type
爲1時,亦可關閉查詢緩存
SELECT SQL_NO_CACHE FROM my_table WHERE condition;
query_cache_type
爲2時,可按需使用查詢緩存
SELECT SQL_CACHE FROM my_table WHERE condition;
查看命中次數
SHOW STATUS LIKE'Qcache_hits';
清理緩存
FLUSH QUERY CACHE∥清理查詢緩存內存碎片 RESET QUERY CACHE∥從查詢緩存中移出全部查詢 FLUSH TABLES;//關閉全部打開的表,同時該操做將會清空查詢 緩存中的內容
redis
/memcache
緩存參考資料[關於Redis的一些思考和總結
](https://www.jianshu.com/p/b88...
對cpu會成爲Redis的性能瓶頸的擔心是能夠理解的,可是在實際使用過程當中cpu或許不是制約Redis的關鍵因素,網絡io可能纔是最大的瓶頸。
由於CPU並非Redis的瓶頸,Redis的瓶頸最有多是機器內存或者網絡帶寬。既然單線程容易實現,並且CPU不會成爲瓶頸,那麼久瓜熟蒂落的採用了單線程的方案。
no-enviction(驅逐):禁止驅逐數據
儘可能使用 Inno DB存儲引擎
基於URL等應用層信息的負載均衡
Nginx的 proxy是它一個很強大的功能,實現了7層負載均衡
功能強大,性能卓越,運行穩定
配置簡單靈活
可以自動剔除工做不正常的後端服務器
上傳文件使用異步模式
支持多種分配策略,能夠分配權重,分配方式靈活
內置策略: IP Hash、加權輪詢
擴展策略:fair策略、通用hash、一致性hash
首先將請求都分給高權重的機器,直到該機器的權值降到了比其餘機器低,纔開始將請求分給下一個高權重的機器
當全部後端機器都down掉時,Ngnx會當即將全部機器的標誌位清成初始狀態,以免形成全部的機器都處在 timeout的狀態
Nginx內置的另外一個負載均衡的策略,流程和輪詢很相似,只是其中的算法和具體的策略有些變化
IP Hash算法是一種變相的輪詢算法
根據後端服務器的響應時間判斷負載狀況,從中選出負載最輕的機器進行分流
通用hash比較簡單,能夠以 Nginx內置的變量爲key進行hash,
一致性hash採用 Nginx了內置的一致性hash環,支持 memcache
http { upstream cluster { server srvl; server srv2; server srv3; } server { listen 80; location / proxy_pass http: //cluster; } }
經過報文中的目標地址和端口,再加上負載均衡設備設置的服務器選擇方式,決定最終選擇的內部服務器
LvS實現服務器集羣負載均衡有三種方式,NAT,DR和TUN
通過特殊構造的鍵值, 使得PHP每一次插入都會形成Hash衝突, 從而使得PHP中array的底層Hash表退化成鏈表
哈希表是經過特定的哈希算法將索引轉換成特定的index而後映射到對應的槽中,而後採用拉鍊法,在一個槽中使用鏈表將數據進行存儲,鏈表的時間複雜度爲O(n)。
這樣在每次插入的時候須要遍歷一遍這個鏈表, 你們能夠想象, 第一次插入, 須要遍歷0個元素, 第二次是1個, 第三次是3個, 第65536個是65535個, 那麼總共就須要65534*65535/2=2147385345次遍歷….
PHP的Hash算法是開源的, 已知的, 因此有心人也能夠作到
示例攻擊數據
{ "format": "json", "list": { "v1" : 1, "攻擊數據":{ "0":0, "65536":0, "131072":0, ………… "234553344":0 } } }
php示例代碼hash.php
<?php $size = pow(2, 16); $startTime = microtime(true); $array = array(); for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) { $array[$key] = 0; } $endTime = microtime(true); echo '插入 ', $size, ' 個惡意的元素須要 ', $endTime - $startTime, ' 秒', "\n"; $startTime = microtime(true); $array = array(); for ($key = 0, $maxKey = $size - 1; $key <= $maxKey; ++$key) { $array[$key] = 0; } $endTime = microtime(true); echo '插入 ', $size, ' 個普通元素須要 ', $endTime - $startTime, ' 秒', "\n";
輸出結果
插入 65536 個惡意的元素須要 5.0739450454712 秒 插入 65536 個普通元素須要 0.0010519027709961 秒
max_input_vars
=> 1000