首發(fā)于PHP
面試12家公司篮赢,收獲9個offer魏铅,2020年PHP 面試問題
PHP高級交流群556094961,分享進階到架構資料
出于一些原因近期做了一次工作變動细移,在職交接近一個半月時間大概面試了十家公司拗引,并且得到了自己比較滿意的offer,最后基本上無縫銜接了新工作橘荠∮旄剑總體來說,雖然準備的很充分砾医,但面試期間還是暴露了許多問題拿撩,所以做下總結,供大家和自己以后參考如蚜,主要分四部分講述:
簡歷方面压恒,格式內容包括七個板塊,個人簡介错邦,求職意向探赫,工作經歷,項目經歷撬呢,技能描述伦吠,學歷背景,自我評價。如果自己或公司沒有其他特殊要求毛仪,這些一般就夠了搁嗓,具體格式不再贅述。
(點擊此處加入php高級交流群一起學習交流箱靴,10年架構師帶你解讀年薪50萬面試通關秘籍腺逛。)
總結幾個要素:
個人簡介名字大寫,內容需要詳實衡怀,一是可以給人留下映像棍矛,二是減少不必要的與面試官交換個人信息的時間。準備一份好的口頭自我介紹是很有必要的抛杨,畢竟準備一次能用很久够委,時間花在上面很實用,面外企英文版的最好也提前準備下怖现。
簡歷上不要寫上期望薪資茁帽,能夠根據面試情況變化是最好的,如果寫上建議高于自身期望真竖,詳細參考錨定效應脐雪。
簡歷要簡潔厌小,最好不要超過兩頁恢共。項目經歷要突出重點(可以具體到某次解決線上問題,某次優(yōu)化效率提升)璧亚,兩到三個為宜讨韭,不重要的可以放在工作經歷中一筆帶過。這樣有個好處癣蟋,即面試官根據項目問的問題就會很集中透硝,在你的預料之中,如果你的項目夸夸
其談寫了很多疯搅,那面試官發(fā)揮起來濒生,你就容易被帶著走。
很多人不重視個人評價欄目幔欧,我的技巧是評價最后中帶上自己的博客罪治,個人項目,因為在尾部還是很容易被看到并當做加分項的礁蔗。
面試流程觉义,其實每個公司大同小異,電話面試浴井,筆試晒骇,技術面(可能兩面),Hr面,部門經理面洪囤,可能不同公司有稍微做調整徒坡。
這里需要強調兩點:
1.電話面試,很多大公司都會有電話面試瘤缩,有些朋友接到面試不管當前情況如何崭参,環(huán)境如何都會爭取這個機會,而我想說的是款咖,如果身邊環(huán)境尚可接了也就接了何暮,但是如果身處鬧市,或者下班回家地鐵上信號不好铐殃,或者自己完全沒有準備海洼,建議直接回復面試官目前不
合適,改約其他時間富腊,這么做好處一是沒有環(huán)境影響坏逢,二是自己有心理準備。
2.抓住機會問問題赘被,如果對技術有追求一定要向技術官問清楚項目所使用技術是整,問開發(fā)人員上下班時間。向HR問清楚公司的薪酬福利體系民假,決定自己開價浮入。向管理層問清楚項目目前所處的階段,以及規(guī)劃方向羊异。
面試題概覽事秀,基本上匯總了這次面試中遇到的所有問題,中間也有一些是自己當時沒有答上來的野舶,這里只做羅列:
1.get,post 的區(qū)別
1易迹、GET在瀏覽器回退時是無害的包晰,而POST會再次提交請求催烘。
2、GET產生的URL地址可以被Bookmark吼和,而POST不可以一屋。
3窘疮、GET請求會被瀏覽器主動cache,而POST不會陆淀,除非手動設置考余。
4、GET請求只能進行url編碼轧苫,而POST支持多種編碼方式楚堤。
5疫蔓、GET請求參數會被完整保留在瀏覽器歷史記錄里,而POST中的參數不會被保留身冬。
6衅胀、GET請求在URL中傳送的參數是有長度限制的,而POST沒有酥筝。
7滚躯、對參數的數據類型,GET只接受ASCII字符嘿歌,而POST沒有限制掸掏。
8、GET比POST更不安全宙帝,因為參數直接暴露在URL上丧凤,所以不能用來傳遞敏感信息。
9步脓、GET參數通過URL傳遞愿待,POST放在Request body中。
10靴患、GET產生一個TCP數據包仍侥,POST產生兩個TCP數據包
2.require,include 區(qū)別
require是無條件包含也就是如果一個流程里加入require,無論條件成立與否都會先執(zhí)行require
include有返回值,而require沒有(可能因為如此require的速度比include快)
包含文件不存在或者語法錯誤的時候require是致命的錯誤終止執(zhí)行,include不是
3.PHP 的垃圾回收機制
PHP 可以自動進行內存管理鸳君,清除不需要的對象农渊。
PHP 使用了引用計數 (reference counting) GC 機制。
每個對象都內含一個引用計數器 refcount相嵌,每個 reference 連接到對象腿时,計數器加 1况脆。當 reference 離開生存空間或被設為 NULL饭宾,計數器減 1。當某個對象的引用計數器為零時格了,PHP 知道你將不再需要使用這個對象看铆,釋放其所占的內存空間。
4.常見的排序算法
1. 冒泡排序
思路分析:在要排序的一組數中盛末,對當前還未排好的序列弹惦,從前往后對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉悄但,較小的往上冒棠隐。即,每當兩相鄰的數比較后發(fā)現它們的排序與排序要求相反時檐嚣,就將它們互換助泽。
代碼實現:
$arr=array(1,43,54,62,21,66,32,78,36,76,39);?
function bubbleSort($arr)
{?
? $len=count($arr);
? //該層循環(huán)控制 需要冒泡的輪數
? for($i=0;$i<$len-1;$i++)
? { //該層循環(huán)用來控制每輪 冒出一個數 需要比較的次數
? ? for($k=0;$k<$len-$i-1;$k++)
? ? {
? ? ? if($arr[$k]>$arr[$k+1])
? ? ? ? {
? ? ? ? ? ? $tmp=$arr[$k+1];
? ? ? ? ? ? $arr[$k+1]=$arr[$k];
? ? ? ? ? ? $arr[$k]=$tmp;
? ? ? ? }
? ? }
? }
? return $arr;
}
2. 選擇排序
思路分析:在要排序的一組數中,選出最小的一個數與第一個位置的數交換。然后在剩下的數當中再找最小的與第二個位置的數交換嗡贺,如此循環(huán)到倒數第二個數和最后一個數比較為止隐解。
代碼實現:
function selectSort($arr) {
//雙重循環(huán)完成,外層控制輪數诫睬,內層控制比較次數
$len=count($arr);
? ? for($i=0; $i<$len-1; $i++) {
? ? ? ? //先假設最小的值的位置
? ? ? ? $p = $i;
? ? ? ? for($j=$i+1; $j<$len; $j++) {
? ? ? ? ? ? //$arr[$p] 是當前已知的最小值
? ? ? ? ? ? if($arr[$p] > $arr[$j]) {
? ? ? ? ? ? //比較煞茫,發(fā)現更小的,記錄下最小值的位置;并且在下次比較時采用已知的最小值進行比較摄凡。
? ? ? ? ? ? ? ? $p = $j;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? //已經確定了當前的最小值的位置续徽,保存到$p中。如果發(fā)現最小值的位置與當前假設的位置$i不同亲澡,則位置互換即可炸宵。
? ? ? ? if($p != $i) {
? ? ? ? ? ? $tmp = $arr[$p];
? ? ? ? ? ? $arr[$p] = $arr[$i];
? ? ? ? ? ? $arr[$i] = $tmp;
? ? ? ? }
? ? }
? ? //返回最終結果
? ? return $arr;
}
3.插入排序
思路分析:在要排序的一組數中,假設前面的數已經是排好順序的谷扣,現在要把第n個數插到前面的有序數中土全,使得這n個數也是排好順序的。如此反復循環(huán)会涎,直到全部排好順序裹匙。
代碼實現:
function insertSort($arr) {
? ? $len=count($arr);
? ? for($i=1, $i<$len; $i++) {
? ? ? ? $tmp = $arr[$i];
? ? ? ? //內層循環(huán)控制,比較并插入
? ? ? ? for($j=$i-1;$j>=0;$j--) {
? ? ? ? ? ? if($tmp < $arr[$j]) {
? ? ? ? ? ? ? ? //發(fā)現插入的元素要小末秃,交換位置概页,將后邊的元素與前面的元素互換
? ? ? ? ? ? ? ? $arr[$j+1] = $arr[$j];
? ? ? ? ? ? ? ? $arr[$j] = $tmp;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? //如果碰到不需要移動的元素,由于是已經排序好是數組练慕,則前面的就不需要再次比較了惰匙。
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return $arr;
}
4.快速排序
思路分析:選擇一個基準元素,通常選擇第一個元素或者最后一個元素铃将。通過一趟掃描项鬼,將待排序列分成兩部分,一部分比基準元素小劲阎,一部分大于等于基準元素绘盟。此時基準元素在其排好序后的正確位置,然后再用同樣的方法遞歸地排序劃分的兩部分悯仙。
代碼實現:
function quickSort($arr) {
? ? //先判斷是否需要繼續(xù)進行
? ? $length = count($arr);
? ? if($length <= 1) {
? ? ? ? return $arr;
? ? }
? ? //選擇第一個元素作為基準
? ? $base_num = $arr[0];
? ? //遍歷除了標尺外的所有元素龄毡,按照大小關系放入兩個數組內
? ? //初始化兩個數組
? ? $left_array = array();? //小于基準的
? ? $right_array = array();? //大于基準的
? ? for($i=1; $i<$length; $i++) {
? ? ? ? if($base_num > $arr[$i]) {
? ? ? ? ? ? //放入左邊數組
? ? ? ? ? ? $left_array[] = $arr[$i];
? ? ? ? } else {
? ? ? ? ? ? //放入右邊
? ? ? ? ? ? $right_array[] = $arr[$i];
? ? ? ? }
? ? }
? ? //再分別對左邊和右邊的數組進行相同的排序處理方式遞歸調用這個函數
? ? $left_array = quick_sort($left_array);
? ? $right_array = quick_sort($right_array);
? ? //合并
? ? return array_merge($left_array, array($base_num), $right_array);
}
5、給出一個字符串锡垄,返回里面連續(xù)字母的個數沦零,比如:abbcddde,返回 1a2b1c3de;
代碼實現:
public function str($str)
? ? {
? ? ? ? $re = '';
? ? ? ? $arr = str_split($str);//把字符串變成數組,開始我想到的是用for循環(huán)來處理货岭,這個函數同事提醒了才發(fā)現
? ? ? ? $key = 0; //key 用來記錄下標路操,為了方便計算前面的數字
? ? ? ? for ($i = 0; $i < count($arr); $i++) {
? ? ? ? ? ? $v = $arr[$i];
? ? ? ? ? ? if ($arr[$i] == $arr[$i + 1]) {
? ? ? ? ? ? ? ? continue;//如果當前的值和下一個值相等序攘,跳出當前循環(huán),進入下一個
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? $re? .= ($i - $key + 1) . $v; //不相等時計算出前面的數字寻拂,
? ? ? ? ? ? ? ? $key = $i + 1;// 同時 key 下標重新復制
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return $re;
? ? }
6程奠、約瑟夫環(huán)問題,猴子選大王
一群猴子排成一圈祭钉,按1,2,…,n依次編號瞄沙。然后從第1只開始數,數到第m只,把它踢出圈慌核,從它后面再開始數距境,再數到第m只,在把它踢出去…垮卓,如此不停的進行下去垫桂,直到最后只剩下一只猴子為止,那只猴子就叫做大王粟按。要求編程模擬此過程诬滩,輸入m、n,
輸出最后那個大王的編號灭将。用程序模擬該過程疼鸟。
function mk($n ,$m){
? ? ? ? $arr = range(1,$n);//構造一個數組
? ? ? ? $i = 1; //從第一個開始循環(huán)
? ? ? ? while(count($arr)>1){ //如果總數大于1
? ? ? ? ? ? ($i % $m != 0) && array_push($arr,$arr[$i-1]);//不被踢出則壓入數組尾部
? ? ? ? ? ? unset($arr[$i-1]);//壓入數組然后刪除
? ? ? ? ? ? $i++;//繼續(xù)循環(huán)
? ? ? ? }?
? ? ? ? return $arr[$i-1]; //直至最后剩下一個為大王
}
print_r(mk(6,8));? //第3只為大王
很多人在剛接觸這個行業(yè)的時候或者是在遇到瓶頸期的時候,總會遇到一些問題庙曙,比如學了一段時間感覺沒有方向感空镜,不知道該從那里入手去學習,對此我整理了一些資料捌朴,需要的可以免費分享給大家(點擊此處加入php高級交流群一起學習交流吴攒,12年架構師帶你解讀年薪50萬面試通關秘籍。)
如果喜歡我的文章砂蔽,想與一群資深開發(fā)者一起交流學習的話洼怔,獲取更多相關大廠面試咨詢和指導,歡迎加入我的學習交流群
一.什么是 CGI察皇?什么是 FastCGI茴厉?php-fpm,FastCGI什荣,Nginx 之間是什么關系?
CGI怀酷,通用網關接口稻爬,用于WEB服務器和應用程序間的交互,定義輸入輸出規(guī)范蜕依,用戶的請求通過WEB服務器轉發(fā)給FastCGI進程桅锄,FastCGI進程再調用應用程序進行處理琉雳,如php解析器,應用程序的處理結果如html返回給FastCGI友瘤,FastCGI返回給Nginx 進行輸出翠肘。假設這里WEB服務器是Nginx,應用程序是 PHP辫秧,而 php-fpm 是管理 FastCGI 的束倍,這也就是 php-fpm,FastCGI盟戏,和 Nginx 之間的關系绪妹。
FastCGI 用來提高 cgi 程序性能,啟動一個master柿究,再啟動多個 worker邮旷,不需要每次解析 php.ini. 而 php-fpm 實現了 FastCGI 協議,是 FastCGI 的進程管理器蝇摸,支持平滑重啟婶肩,可以啟動的時候預先生成多個進程。
二.memcache 和 Redis 的區(qū)別
數據結構:memcache僅支持簡單的key-value形式貌夕,Redis支持的數據更多(string字符串狡孔,set集合,list列表蜂嗽,hash散列苗膝,zset有序集合);
多線程:memcache支持多線程植旧,Redis支持單線程
持久化:Redis支持持久化辱揭,memcache不支持持久化
分布式:Redis做主從結構,memcache服務器需要通過hash一致化來支撐主從結構
實際運用中可以redis病附,memcache結合问窃,memcache可作為session存儲的方式,session都是KV類型鍵值對完沪。
1. Redis中域庇,并不是所有的數據都一直存儲在內存中的,這是和Memcache相比一個最大的區(qū)別覆积。
2. Redis在很多方面具備數據庫的特征听皿,或者說就是一個數據庫系統(tǒng),而Memcache只是簡單的K/V緩存宽档。
3. 他們的擴展都需要做集群尉姨;實現方式:master-slave、Hash吗冤。
4. 在100k以上的數據中又厉,Memcache性能要高于Redis九府。
5. 如果要說內存使用效率,使用簡單的key-value存儲的話覆致,Memcached的內存利用率更高侄旬,而如果Redis采用hash結構來做key-value存儲,由于其組合式的壓縮煌妈,其內存利用率會高于Memcache儡羔。當然,這和你的應用場景和數據特性有關声旺。
6. 如果你對數據持久化和數據同步有所要求笔链,那么推薦你選擇Redis,因為這兩個特性Memcache都不具備腮猖。即使你只是希望在升級或者重啟系統(tǒng)后緩存數據不會丟失鉴扫,選擇Redis也是明智的。
7. Redis和Memcache在寫入性能上面差別不大澈缺,讀取性能上面尤其是批量讀取性能上面Memcache更強
8.Redis 提供了多種不同級別的持久化方式:
RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)坪创。
AOF
持久化記錄服務器執(zhí)行的所有寫操作命令,并在服務器啟動時姐赡,通過重新執(zhí)行這些命令來還原數據集莱预。 AOF 文件中的命令全部以 Redis
協議的格式來保存,新命令會被追加到文件的末尾项滑。 Redis 還可以在后臺對 AOF 文件進行重寫(rewrite)依沮,使得 AOF
文件的體積不會超出保存數據集狀態(tài)所需的實際大小。
Redis 還可以同時使用 AOF 持久化和 RDB 持久化枪狂。 在這種情況下危喉, 當 Redis 重啟時, 它會優(yōu)先使用 AOF 文件來還原數據集州疾, 因為 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整辜限。
你甚至可以關閉持久化功能,讓數據只在服務器運行時存在严蓖。
三.什么是 Redis 穿透和雪崩
**緩存穿透**:就是訪問redis中一個不存在的key的時候,會直接穿過緩存,去數據庫中進行查詢.
如果是黑客,進行惡意攻擊的時候,每次都請求超過2000個/秒的時候,這個時候mysql基本上就掛了.
解決辦法是:每次從數據庫中查詢到一個不存在的key的時候,就寫一個空值到緩存庫中,有惡意攻擊的時候,直接從緩存中取到這個空值.
**緩存雪崩**:就是每秒有5000個請求過來時候,redis緩存庫崩了,然后這些請求瞬間落在了mysql數據庫上,直接導致數據庫死機.
解決方案就是:
事前:提高緩存庫的高可用, 使用主從結構加哨兵 cluster集群,
事中:使用ehcache+hystrix限流組件(當請求量非常巨大的時候,就調用自己開發(fā)好的一個降級餓組件,返回一些默認值,如友情提示,或者空白值)
事后:做持久化,盡快恢復緩存集群,一旦恢復,自動從磁盤上讀取數據,恢復內存中的數據.
四.redis 消息隊列先進先出需要注意什么薄嫡?
通常使用一個list來實現隊列操作,這樣有一個小限制颗胡,所以的任務統(tǒng)一都是先進先出毫深,如果想優(yōu)先處理某個任務就不太好處理了,這就需要讓隊列有優(yōu)先級的概念杭措,我們就可以優(yōu)先處理高級別的任務费什,實現方式有以下幾種方式:
1)單一列表實現:隊列正常的操作是 左進右出(lpush,rpop)為了先處理高優(yōu)先級任務,在遇到高級別任務時手素,可以直接插隊鸳址,直接放入隊列頭部(rpush),這樣泉懦,從隊列頭部(右側)獲取任務時稿黍,取到的就是高優(yōu)先級的任務(rpop)
2)使用兩個隊列,一個普通隊列崩哩,一個高級隊列巡球,針對任務的級別放入不同的隊列,獲取任務時也很簡單邓嘹,redis的BRPOP命令可以按順序從多個隊列中取值酣栈,BRPOP會按照給出的
key 順序查看,并在找到的第一個非空 list 的尾部彈出一個元素汹押,redis> BRPOP list1 list2 0
`list1 做為高優(yōu)先級任務隊列`
`list2 做為普通任務隊列`
`這樣就實現了先處理高優(yōu)先級任務矿筝,當沒有高優(yōu)先級任務時,就去獲取普通任務`
`方式1最簡單棚贾,但實際應用比較局限窖维,方式3可以實現復雜優(yōu)先級,但實現比較復雜妙痹,不利于維護`
`方式2是推薦用法铸史,實際應用最為合適`
五.Redis 如何防止高并發(fā)?
其實redis是不會存在并發(fā)問題的怯伊,因為他是單進程的琳轿,再多的命令都是一個接一個地執(zhí)行的。我們使用的時候耿芹,可能會出現并發(fā)問題崭篡,比如獲得和設定這一對。Redis的為什么 有高并發(fā)問題猩系?Redis的的出身決定
Redis是一種單線程機制的nosql數據庫媚送,基于key-value,數據可持久化落盤寇甸。由于單線程所以redis本身并沒有鎖的概念塘偎,多個客戶端連接并不存在競爭關系,但是利用jedis等客戶端對redis進行并發(fā)訪問時會出現問題拿霉。發(fā)生連接超時吟秩、數據轉換錯誤、阻塞绽淘、客戶端關閉連接等問題涵防,這些問題均是由于客戶端連接混亂造成。
同時沪铭,單線程的天性決定壮池,高并發(fā)對同一個鍵的操作會排隊處理偏瓤,如果并發(fā)量很大,可能造成后來的請求超時椰憋。
在遠程訪問redis的時候厅克,因為網絡等原因造成高并發(fā)訪問延遲返回的問題。
解決辦法
在客戶端將連接進行池化橙依,同時對客戶端讀寫Redis操作采用內部鎖synchronized证舟。
服務器角度,利用setnx變向實現鎖機制窗骑。
六.說說對 SQL 語句優(yōu)化有哪些方法女责?
(1)Where子句中:where表之間的連接必須寫在其他Where條件之前,那些可以過濾掉最大數量記錄的條件必須寫在Where子句的末尾.HAVING最后创译。
(2)用EXISTS替代IN抵知、用NOT EXISTS替代NOT IN。
(3) 避免在索引列上使用計算
(4)避免在索引列上使用IS NULL和IS NOT NULL
(5)對查詢進行優(yōu)化昔榴,應盡量避免全表掃描辛藻,首先應考慮在 where 及 order by 涉及的列上建立索引。
(6)應盡量避免在 where 子句中對字段進行 null 值判斷互订,否則將導致引擎放棄使用索引而進行全表掃描
(7)應盡量避免在 where 子句中對字段進行表達式操作吱肌,這將導致引擎放棄使用索引而進行全表掃描
一.數據庫三范式
第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性仰禽,不可再分解氮墨;
第二范式:2NF是對記錄的惟一性約束,要求記錄有惟一標識吐葵,即實體的惟一性规揪;
第三范式:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來温峭,它要求字段沒有冗余猛铅。
范式化設計優(yōu)缺點:
優(yōu)點:
可以盡量得減少數據冗余,使得更新快凤藏,體積小
缺點:對于查詢需要多個表進行關聯奸忽,減少寫得效率增加讀得效率,更難進行索引優(yōu)化
反范式化:
優(yōu)點:可以減少表得關聯揖庄,可以更好得進行索引優(yōu)化
缺點:數據冗余以及數據異常栗菜,數據得修改需要更多的成本
二.Mysql 中有哪幾種鎖
- MyISAM支持表鎖,InnoDB支持表鎖和行鎖蹄梢,默認為行鎖
- 表級鎖:開銷小疙筹,加鎖快,不會出現死鎖。鎖定粒度大而咆,發(fā)生鎖沖突的概率最高霍比,并發(fā)量最低
- 行級鎖:開銷大,加鎖慢翘盖,會出現死鎖桂塞。鎖力度小凹蜂,發(fā)生鎖沖突的概率小馍驯,并發(fā)度最高
三.什么是存儲過程
我們常用的操作數據庫語言SQL語句在執(zhí)行的時候需要要先編譯,然后執(zhí)行玛痊,而存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集汰瘫,經編譯后存儲在數據庫中,用戶通過指定存儲過程的名字并給定參數(如果該存儲過程帶有參數)來調用執(zhí)行它擂煞。
一個存儲過程是一個可編程的函數混弥,它在數據庫中創(chuàng)建并保存。它可以有SQL語句和一些特殊的控制結構組成对省。當希望在不同的應用程序或平臺上執(zhí)行相同的函數蝗拿,或者封裝特定功能時,存儲過程是非常有用的蒿涎。數據庫中的存儲過程可以看做是對編程中面向對象方法的模擬哀托。它允許控制數據的訪問方式。
優(yōu)點:
(1).存儲過程增強了SQL語言的功能和靈活性劳秋。存儲過程可以用流控制語句編寫仓手,有很強的靈活性,可以完成復雜的判斷和較復雜的運算玻淑。
(2).存儲過程允許標準組件是編程嗽冒。存儲過程被創(chuàng)建后,可以在程序中被多次調用补履,而不必重新編寫該存儲過程的SQL語句添坊。而且數據庫專業(yè)人員可以隨時對存儲過程進行修改,對應用程序源代碼毫無影響箫锤。
(3).存儲過程能實現較快的執(zhí)行速度贬蛙。如果某一操作包含大量的Transaction-SQL代碼或分別被多次執(zhí)行,那么存儲過程要比批處理的執(zhí)行速度快很多麻汰。因為存儲過程是預編譯的速客。在首次運行一個存儲過程時查詢,優(yōu)化器對其進行分析優(yōu)化五鲫,并且給出最終被存儲在系統(tǒng)表中的執(zhí)行計劃溺职。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優(yōu)化,速度相對要慢一些。
(4).存儲過程能過減少網絡流量浪耘。針對同一個數據庫對象的操作(如查詢乱灵、修改),如果這一操作所涉及的Transaction-SQL語句被組織程存儲過程七冲,那么當在客戶計算機上調用該存儲過程時痛倚,網絡中傳送的只是該調用語句,從而大大增加了網絡流量并降低了網絡負載澜躺。
(5).存儲過程可被作為一種安全機制來充分利用蝉稳。系統(tǒng)管理員通過執(zhí)行某一存儲過程的權限進行限制,能夠實現對相應的數據的訪問權限的限制掘鄙,避免了非授權用戶對數據的訪問耘戚,保證了數據的安全。
四.如何處理負載操漠、高并發(fā)
1收津、HTML靜態(tài)化
其實大家都知道,效率最高浊伙、消耗最小的就是純靜態(tài)化的html頁面撞秋,所以我們盡可能使我們的 網站上的頁面采用靜態(tài)頁面來實現涝滴,這個最簡單的方法其實也是最有效的方法鬓长。
2、圖片服務器分離
把圖片單獨存儲鹅髓,盡量減少圖片等大流量的開銷拗慨,可以放在一些相關的平臺上廓八,如七牛等。
3赵抢、數據庫集群和庫表散列及緩存
數據庫的并發(fā)連接為100剧蹂,一臺數據庫遠遠不夠,可以從讀寫分離烦却、主從復制宠叼,數據庫集群方面來著手。另外盡量減少數據庫的訪問其爵,可以使用緩存數據庫如memcache冒冬、redis。
4摩渺、鏡像
盡量減少下載简烤,可以把不同的請求分發(fā)到多個鏡像端。
5摇幻、負載均衡:
Apache的最大并發(fā)連接為1500横侦,只能增加服務器挥萌,可以從硬件上著手,如F5服務器枉侧。當然硬件的成本比較高引瀑,我們往往從軟件方面著手。
負載均衡
(Load Balancing)
建立在現有網絡結構之上榨馁,它提供了一種廉價有效透明的方法擴展網絡設備和服務器的帶寬憨栽、增加吞吐量、加強網絡數據處理能力翼虫,同時能夠提高網絡的靈活性和可用性屑柔。目前使用最為廣泛的負載均衡軟件是Nginx、LVS蛙讥、HAProxy锯蛀。我分別來說下三種的優(yōu)缺點:
**Nginx的優(yōu)點是:**
工作在網絡的7層之上,可以針對http應用做一些分流的策略次慢,比如針對域名、目錄結構翔曲,它的正則規(guī)則比HAProxy更為強大和靈活迫像,這也是它目前廣泛流行的主要原因之一,Nginx單憑這點可利用的場合就遠多于LVS了瞳遍。
Nginx對網絡穩(wěn)定性的依賴非常小闻妓,理論上能ping通就就能進行負載功能,這個也是它的優(yōu)勢之一掠械;相反LVS對網絡穩(wěn)定性依賴比較大由缆,這點本人深有體會;
Nginx安裝和配置比較簡單猾蒂,測試起來比較方便均唉,它基本能把錯誤用日志打印出來。LVS的配置肚菠、測試就要花比較長的時間了舔箭,LVS對網絡依賴比較大。
可以承擔高負載壓力且穩(wěn)定蚊逢,在硬件不差的情況下一般能支撐幾萬次的并發(fā)量层扶,負載度比LVS相對小些。
Nginx可以通過端口檢測到服務器內部的故障烙荷,比如根據服務器處理網頁返回的狀態(tài)碼镜会、超時等等,并且會把返回錯誤的請求重新提交到另一個節(jié)點终抽,不過其中缺點就是不支持url來檢測戳表。比如用戶正在上傳一個文件焰薄,而處理該上傳的節(jié)點剛好在上傳過程中出現故障,Nginx會把上傳切到另一臺服務器重新處理扒袖,而LVS就直接斷掉了塞茅,如果是上傳一個很大的文件或者很重要的文件的話,用戶可能會因此而不滿季率。
Nginx不僅僅是一款優(yōu)秀的負載均衡器/反向代理軟件野瘦,它同時也是功能強大的Web應用服務器。LNMP也是近幾年非常流行的web架構飒泻,在高流量的環(huán)境中穩(wěn)定性也很好鞭光。
Nginx現在作為Web反向加速緩存越來越成熟了,速度比傳統(tǒng)的Squid服務器更快泞遗,可以考慮用其作為反向代理加速器惰许。
Nginx可作為中層反向代理使用,這一層面Nginx基本上無對手史辙,唯一可以對比Nginx的就只有 lighttpd了汹买,不過 lighttpd目前還沒有做到Nginx完全的功能,配置也不那么清晰易讀聊倔,社區(qū)資料也遠遠沒Nginx活躍晦毙。
Nginx也可作為靜態(tài)網頁和圖片服務器,這方面的性能也無對手耙蔑。還有Nginx社區(qū)非臣剩活躍,第三方模塊也很多甸陌。
**Nginx的缺點是:**
Nginx僅能支持http须揣、https和Email協議,這樣就在適用范圍上面小些钱豁,這個是它的缺點耻卡。
對后端服務器的健康檢查,只支持通過端口來檢測寥院,不支持通過url來檢測劲赠。不支持Session的直接保持,但能通過ip_hash來解決秸谢。
LVS:使用Linux內核集群實現一個高性能凛澎、高可用的負載均衡服務器,它具有很好的可伸縮性(Scalability)估蹄、可靠性(Reliability)和可管理性(Manageability)塑煎。
**LVS的優(yōu)點是:**
抗負載能力強、是工作在網絡4層之上僅作分發(fā)之用臭蚁,沒有流量的產生最铁,這個特點也決定了它在負載均衡軟件里的性能最強的讯赏,對內存和cpu資源消耗比較低。
配置性比較低冷尉,這是一個缺點也是一個優(yōu)點漱挎,因為沒有可太多配置的東西,所以并不需要太多接觸雀哨,大大減少了人為出錯的幾率磕谅。
工作穩(wěn)定,因為其本身抗負載能力很強雾棺,自身有完整的雙機熱備方案膊夹,如LVS+Keepalived,不過我們在項目實施中用得最多的還是LVS/DR+Keepalived捌浩。
無流量放刨,LVS只分發(fā)請求,而流量并不從它本身出去尸饺,這點保證了均衡器IO的性能不會受到大流量的影響进统。
應用范圍比較廣,因為LVS工作在4層侵佃,所以它幾乎可以對所有應用做負載均衡麻昼,包括http、數據庫馋辈、在線聊天室等等。
**LVS的缺點是:**
軟件本身不支持正則表達式處理倍谜,不能做動靜分離迈螟;而現在許多網站在這方面都有較強的需求,這個是Nginx/HAProxy+Keepalived的優(yōu)勢所在尔崔。
如果是網站應用比較龐大的話答毫,LVS/DR+Keepalived實施起來就比較復雜了,特別后面有 Windows Server的機器的話季春,如果實施及配置還有維護過程就比較復雜了洗搂,相對而言,Nginx/HAProxy+Keepalived就簡單多了载弄。
**HAProxy的特點是:**
HAProxy也是支持虛擬主機的耘拇。
HAProxy的優(yōu)點能夠補充Nginx的一些缺點,比如支持Session的保持宇攻,Cookie的引導惫叛;同時支持通過獲取指定的url來檢測后端服務器的狀態(tài)。
HAProxy跟LVS類似逞刷,本身就只是一款負載均衡軟件嘉涌;單純從效率上來講HAProxy會比Nginx有更出色的負載均衡速度妻熊,在并發(fā)處理上也是優(yōu)于Nginx的。
HAProxy支持TCP協議的負載均衡轉發(fā)仑最,可以對MySQL讀進行負載均衡扔役,對后端的MySQL節(jié)點進行檢測和負載均衡,大家可以用LVS+Keepalived對MySQL主從做負載均衡警医。
HAProxy負載均衡策略非常多亿胸,HAProxy的負載均衡算法現在具體有如下8種:
① roundrobin,表示簡單的輪詢法严,這個不多說损敷,這個是負載均衡基本都具備的;
② static-rr深啤,表示根據權重拗馒,建議關注;
③ leastconn溯街,表示最少連接者先處理诱桂,建議關注;
④ source呈昔,表示根據請求源IP挥等,這個跟Nginx的IP_hash機制類似,我們用其作為解決session問題的一種方法堤尾,建議關注肝劲;
⑤ ri,表示根據請求的URI郭宝;
⑥ rl_param辞槐,表示根據請求的URl參數’balance url_param’ requires an URL parameter name;
⑦ hdr(name)粘室,表示根據HTTP請求頭來鎖定每一次HTTP請求榄檬;
⑧ rdp-cookie(name),表示根據據cookie(name)來鎖定并哈希每一次TCP請求衔统。
**Nginx和LVS對比的總結:**
Nginx工作在網絡的7層鹿榜,所以它可以針對http應用本身來做分流策略,比如針對域名锦爵、目錄結構等舱殿,相比之下LVS并不具備這樣的功能,所以Nginx單憑這點可利用的場合就遠多于LVS了棉浸;但Nginx有用的這些功能使其可調整度要高于LVS怀薛,所以經常要去觸碰觸碰,觸碰多了迷郑,人為出問題的幾率也就會大枝恋。
Nginx對網絡穩(wěn)定性的依賴較小创倔,理論上只要ping得通,網頁訪問正常焚碌,Nginx就能連得通畦攘,這是Nginx的一大優(yōu)勢!Nginx同時還能區(qū)分內外網十电,如果是同時擁有內外網的節(jié)點知押,就相當于單機擁有了備份線路;LVS就比較依賴于網絡環(huán)境鹃骂,目前來看服務器在同一網段內并且LVS使用direct方式分流台盯,效果較能得到保證。另外注意畏线,LVS需要向托管商至少申請多一個ip來做Visual
IP静盅,貌似是不能用本身的IP來做VIP的。要做好LVS管理員寝殴,確實得跟進學習很多有關網絡通信方面的知識蒿叠,就不再是一個HTTP那么簡單了。
Nginx安裝和配置比較簡單蚣常,測試起來也很方便市咽,因為它基本能把錯誤用日志打印出來。LVS的安裝和配置抵蚊、測試就要花比較長的時間了施绎;LVS對網絡依賴比較大,很多時候不能配置成功都是因為網絡問題而不是配置問題贞绳,出了問題要解決也相應的會麻煩得多粘姜。
Nginx也同樣能承受很高負載且穩(wěn)定,但負載度和穩(wěn)定度差LVS還有幾個等級:Nginx處理所有流量所以受限于機器IO和配置熔酷;本身的bug也還是難以避免的。
Nginx可以檢測到服務器內部的故障豺裆,比如根據服務器處理網頁返回的狀態(tài)碼拒秘、超時等等,并且會把返回錯誤的請求重新提交到另一個節(jié)點臭猜。目前LVS中
ldirectd也能支持針對服務器內部的情況來監(jiān)控躺酒,但LVS的原理使其不能重發(fā)請求。比如用戶正在上傳一個文件蔑歌,而處理該上傳的節(jié)點剛好在上傳過程中出現故障羹应,Nginx會把上傳切到另一臺服務器重新處理,而LVS就直接斷掉了次屠,如果是上傳一個很大的文件或者很重要的文件的話园匹,用戶可能會因此而惱火雳刺。
Nginx對請求的異步處理可以幫助節(jié)點服務器減輕負載,假如使用
apache直接對外服務裸违,那么出現很多的窄帶鏈接時apache服務器將會占用大
量內存而不能釋放掖桦,使用多一個Nginx做apache代理的話,這些窄帶鏈接會被Nginx擋住供汛,apache上就不會堆積過多的請求枪汪,這樣就減少了相當多的資源占用。這點使用squid也有相同的作用怔昨,即使squid本身配置為不緩存雀久,對apache還是有很大幫助的。
Nginx能支持http趁舀、https和email(email的功能比較少用)赖捌,LVS所支持的應用在這點上會比Nginx更多。在使用上赫编,一般最前端所采取的策略應是LVS巡蘸,也就是DNS的指向應為LVS均衡器,LVS的優(yōu)點令它非常適合做這個任務擂送。重要的ip地址悦荒,最好交由LVS托管,比如數據庫的
ip嘹吨、webservice服務器的ip等等搬味,這些ip地址隨著時間推移,使用面會越來越大蟀拷,如果更換ip則故障會接踵而至碰纬。所以將這些重要ip交給
LVS托管是最為穩(wěn)妥的,這樣做的唯一缺點是需要的VIP數量會比較多问芬。Nginx可作為LVS節(jié)點機器使用悦析,一是可以利用Nginx的功能,二是可以利用Nginx的性能此衅。當然這一層面也可以直接使用squid强戴,squid的功能方面就比Nginx弱不少了,性能上也有所遜色于Nginx挡鞍。Nginx也可作為中層代理使用骑歹,這一層面Nginx基本上無對手,唯一可以撼動Nginx的就只有l(wèi)ighttpd了墨微,不過lighttpd目前還沒有能做到
Nginx完全的功能道媚,配置也不那么清晰易讀。另外,中層代理的IP也是重要的最域,所以中層代理也擁有一個VIP和LVS是最完美的方案了谴分。具體的應用還得具體分析,如果是比較小的網站(日PV小于1000萬)羡宙,用Nginx就完全可以了狸剃,如果機器也不少,可以用DNS輪詢狗热,LVS所耗費的機器還是比較多的钞馁;大型網站或者重要的服務,機器不發(fā)愁的時候匿刮,要多多考慮利用LVS僧凰。
更多面試題系列:
很多人在剛接觸這個行業(yè)的時候或者是在遇到瓶頸期的時候,總會遇到一些問題光羞,比如學了一段時間感覺沒有方向感绩鸣,不知道該從那里入手去學習,對此我整理了一些資料纱兑,需要的可以免費分享給大家(點擊此處加入php高級交流群一起學習交流呀闻,10年架構師帶你解讀年薪50萬面試通關秘籍。)
如果喜歡我的文章潜慎,想與一群資深開發(fā)者一起交流學習的話捡多,獲取更多相關大廠面試咨詢和指導,歡迎加入我的學習交流群
我的官方群點擊此處铐炫。鏈接加入群聊【PHP高級學習交流群】,一起學習垒手,相互討論。
群內已經有管理將知識體系整理好(源碼倒信,學習視頻等資料)科贬,歡迎加群免費領取。
這套精品PHP教程絕不是市場上的那些妖艷賤貨可比鳖悠,作為web開發(fā)的佼佼者PHP并不遜色其他語言唆迁,加上Swoole后更加是如虎添翼!進軍通信 竞穷、物聯網行業(yè)開發(fā)百度地圖、百度訂單中心鳞溉、虎牙瘾带、戰(zhàn)旗TV等!寒冬裁員期過后正是各大企業(yè)擴大招人的時期熟菲,現在市場初級程序員泛濫看政,進階中高級程序員絕對是各大企業(yè)急需的人才朴恳,這套學習教程適合那些1-7年以內的PHP開發(fā)者正處于瓶頸期,想要突破自己進階中高級允蚣、架構師于颖!名額有限,先到先得嚷兔!
程序猿的生活:【社群福利】30G-PHP進階資料森渐,助力大家都能30K?
部分進階到架構資料截圖:
>need-to-insert-img
>need-to-insert-img
>need-to-insert-img
還有限時精品福利:
★騰訊高級PHP工程師筆試題目
★億級PV高并發(fā)場景訂單的處理
★laravel開發(fā)天貓商城組件服務
★戰(zhàn)旗TV視頻直播的架構項目實戰(zhàn)
掃描下面二維碼領取
對PHP后端技術,對PHP架構技術感興趣的朋友冒晰,我的官方群點擊此處同衣,一起學習,相互討論壶运。
群內已經有管理將知識體系整理好(源碼耐齐,學習視頻等資料),歡迎加群免費領取蒋情。
本課程深度對標騰訊T3-T4標準埠况,貼身打造學習計劃為web開發(fā)人員進階中高級、架構師提升技術棵癣,為自己增值漲薪辕翰!加入BAT特訓營還可以獲得內推大廠名額以及GO語言學習權限!U阄住金蜀!
編輯于 08-08
文章被以下專欄收錄
資料不斷更新,PHP進階到架構的畴。
推薦閱讀
面試10家公司渊抄,收獲9個offer,2020年PHP 面試問題
八重櫻發(fā)表于PHP 互...
PHP 已死丧裁?最美語言倒下护桦?
IT-南風發(fā)表于PHP全棧...
我有個互聯網公司朋友說 php不知道m(xù)ap,list缓呛,set催享,queue的區(qū)別,數組就可以搞定了坝窗怼因妙;用了php,就不知道還有byte單位,各種類型傻傻的分不清攀涵。用了php铣耘,就不知道程序還要考慮資源的多線程…
程序猿的生...發(fā)表于PHP
Go 是由 Google 設計的一門靜態(tài)類型的編譯型語言。它有點類似于 C以故,但是它包含了更多的優(yōu)點蜗细,比如垃圾回收、內存安全怒详、結構類型和并發(fā)性炉媒。它的并發(fā)機制使多核和網絡機器能夠發(fā)揮最大的作用…
程序猿的生...發(fā)表于PHP
1 條評論
寫下你的評論...
毛英東08-08
POST產生兩個TCP數據包?棘利?