最近在面試,總結(jié)總結(jié)遇到的面試題.
基礎(chǔ)問(wèn)題
LRU算法
[內(nèi)存管理]的一種頁(yè)面置換算法剪菱,對(duì)于在內(nèi)存中但又不用的[數(shù)據(jù)塊](內(nèi)存塊)叫做LRU爬舰,操作系統(tǒng)會(huì)根據(jù)哪些數(shù)據(jù)屬于LRU而將其移出內(nèi)存而騰出空間來(lái)加載另外的數(shù)據(jù),常用于頁(yè)面置換算法势似,是為虛擬頁(yè)式存儲(chǔ)管理服務(wù)的葵陵。
設(shè)計(jì)原則
如果一個(gè)數(shù)據(jù)在最近一段時(shí)間沒(méi)有被訪(fǎng)問(wèn)到冯丙,那么在將來(lái)它被訪(fǎng)問(wèn)的可能性也很小船老。也就是說(shuō)酥筝,當(dāng)限定的空間已存滿(mǎn)數(shù)據(jù)時(shí)滚躯,應(yīng)當(dāng)把最久沒(méi)有被訪(fǎng)問(wèn)到的數(shù)據(jù)淘汰。
實(shí)現(xiàn)LRU
- 1.用一個(gè)數(shù)組來(lái)存儲(chǔ)數(shù)據(jù),給每一個(gè)數(shù)據(jù)項(xiàng)標(biāo)記一個(gè)訪(fǎng)問(wèn)時(shí)間戳掸掏,每次插入新數(shù)據(jù)項(xiàng)的時(shí)候茁影,先把數(shù)組中存在的數(shù)據(jù)項(xiàng)的時(shí)間戳自增,并將新數(shù)據(jù)項(xiàng)的時(shí)間戳置為0并插入到數(shù)組中丧凤。每次訪(fǎng)問(wèn)數(shù)組中的數(shù)據(jù)項(xiàng)的時(shí)候募闲,將被訪(fǎng)問(wèn)的數(shù)據(jù)項(xiàng)的時(shí)間戳置為0。當(dāng)數(shù)組空間已滿(mǎn)時(shí)愿待,將時(shí)間戳最大的數(shù)據(jù)項(xiàng)淘汰浩螺。
- 2.利用一個(gè)鏈表來(lái)實(shí)現(xiàn),每次新插入數(shù)據(jù)的時(shí)候?qū)⑿聰?shù)據(jù)插到鏈表的頭部仍侥;每次緩存命中(即數(shù)據(jù)被訪(fǎng)問(wèn))要出,則將數(shù)據(jù)移到鏈表頭部;那么當(dāng)鏈表滿(mǎn)的時(shí)候农渊,就將鏈表尾部的數(shù)據(jù)丟棄患蹂。
- 3.利用鏈表和hashmap。當(dāng)需要插入新的數(shù)據(jù)項(xiàng)的時(shí)候腿时,如果新數(shù)據(jù)項(xiàng)在鏈表中存在(一般稱(chēng)為命中)况脆,則把該節(jié)點(diǎn)移到鏈表頭部,如果不存在批糟,則新建一個(gè)節(jié)點(diǎn)格了,放到鏈表頭部,若緩存滿(mǎn)了徽鼎,則把鏈表最后一個(gè)節(jié)點(diǎn)刪除即可盛末。在訪(fǎng)問(wèn)數(shù)據(jù)的時(shí)候,如果數(shù)據(jù)項(xiàng)在鏈表中存在否淤,則把該節(jié)點(diǎn)移到鏈表頭部悄但,否則返回-1。這樣一來(lái)在鏈表尾部的節(jié)點(diǎn)就是最近最久未訪(fǎng)問(wèn)的數(shù)據(jù)項(xiàng)石抡。
- 對(duì)于第一種方法檐嚣,需要不停地維護(hù)數(shù)據(jù)項(xiàng)的訪(fǎng)問(wèn)時(shí)間戳,另外啰扛,在插入數(shù)據(jù)嚎京、刪除數(shù)據(jù)以及訪(fǎng)問(wèn)數(shù)據(jù)時(shí),時(shí)間復(fù)雜度都是O(n)隐解。對(duì)于第二種方法鞍帝,鏈表在定位數(shù)據(jù)的時(shí)候時(shí)間復(fù)雜度為O(n)。所以在一般使用第三種方式來(lái)是實(shí)現(xiàn)LRU算法煞茫。
http協(xié)議
一個(gè)HTTP請(qǐng)求報(bào)文由請(qǐng)求行(request line)帕涌、請(qǐng)求頭部(header)摄凡、空行和請(qǐng)求數(shù)據(jù)4個(gè)部分組成
請(qǐng)求行
請(qǐng)求行由請(qǐng)求方法字段、URL字段和HTTP協(xié)議版本字段3個(gè)字段組成蚓曼,它們用空格分隔亲澡。
GET
常見(jiàn)的一種請(qǐng)求方式,當(dāng)客戶(hù)端要從服務(wù)器中讀取文檔時(shí)辟躏,當(dāng)點(diǎn)擊網(wǎng)頁(yè)上的鏈接或者通過(guò)在瀏覽器的地址欄輸入網(wǎng)址來(lái)瀏覽網(wǎng)頁(yè) 的谷扣,使用的都是GET方式。GET方法要求服務(wù)器將URL定位的資源放在響應(yīng)報(bào)文的數(shù)據(jù)部分捎琐,回送給客戶(hù)端。使用GET方法時(shí)裹匙,請(qǐng) 求參數(shù)和對(duì)應(yīng)的值附加在URL后面瑞凑,利用一個(gè)問(wèn)號(hào)(“?”)代表URL的結(jié)尾與請(qǐng)求參數(shù)的開(kāi)始,傳遞參數(shù)長(zhǎng)度受限制概页。例 如籽御,/index.jsp?id=100&op=bind,這樣通過(guò)GET方式傳遞的數(shù)據(jù)直接表示在地址中,所以我們可以把請(qǐng)求結(jié)果以鏈接的形式發(fā) 送給好友
POST
使用POST方法可以允許客戶(hù)端給服務(wù)器提供信息較 多惰匙。POST方法將請(qǐng)求參數(shù)封裝在HTTP請(qǐng)求數(shù)據(jù)中技掏,以名稱(chēng)/值的形式出現(xiàn),可以傳輸大量數(shù)據(jù)项鬼,這樣POST方式對(duì)傳送的數(shù)據(jù)大 小沒(méi)有限制,而且也不會(huì)顯示在URL中,POST方式請(qǐng)求行中不包含數(shù)據(jù)字符串,這些數(shù)據(jù)保存在”請(qǐng)求內(nèi)容”部分彪标,各數(shù)據(jù)之間也是使用”&”符號(hào)隔開(kāi)诗宣。POST方 式大多用于頁(yè)面的表單中。因?yàn)镻OST也能完成GET的功能龄毡,因此多數(shù)人在設(shè)計(jì)表單的時(shí)候一律都使用POST方式吠卷,其實(shí)這是一個(gè) 誤區(qū)。
HEAD
HEAD就像GET沦零,只不過(guò)服務(wù)端接受到HEAD請(qǐng)求后只返回響應(yīng)頭祭隔,而不會(huì)發(fā)送響應(yīng)內(nèi)容。當(dāng)我們只需要查看某個(gè)頁(yè)面的狀態(tài)的時(shí) 候路操,使用HEAD是非常高效的疾渴,因?yàn)樵趥鬏數(shù)倪^(guò)程中省去了頁(yè)面內(nèi)容。
請(qǐng)求頭部
- 請(qǐng)求頭部由關(guān)鍵字/值對(duì)組成寻拂,每行一對(duì)程奠,關(guān)鍵字和值用英文冒號(hào)“:”分隔。
- 請(qǐng)求頭部通知服務(wù)器有關(guān)于客戶(hù)端請(qǐng)求的信息祭钉,典型的 請(qǐng)求頭有:
- User-Agent:產(chǎn)生請(qǐng)求的瀏覽器類(lèi)型瞄沙。
- Accept:客戶(hù)端可識(shí)別的內(nèi)容類(lèi)型列表。
- Host:請(qǐng)求的主機(jī)名,允許多個(gè)域名同處一個(gè)IP地址距境,即虛擬主機(jī)申尼。
空行
后一個(gè)請(qǐng)求頭之后是一個(gè)空行,發(fā)送回車(chē)符和換行符垫桂,通知服務(wù)器以下不再有請(qǐng)求頭师幕。
請(qǐng)求數(shù)據(jù)
請(qǐng)求數(shù)據(jù)不在GET方法中使用,而是在POST方法中使用诬滩。POST方法適用于需要客戶(hù)填寫(xiě)表單的場(chǎng)合霹粥。與請(qǐng)求數(shù)據(jù)相關(guān)的常使 用的請(qǐng)求頭是Content-Type和Content-Length。
HTTP相應(yīng)報(bào)文
HTTP響應(yīng)也由三個(gè)部分組成疼鸟,分別是:狀態(tài)行后控、消息響應(yīng)頭、響應(yīng)正文空镜。
狀態(tài)碼
- 1xx:指示信息表示請(qǐng)求已接收浩淘,繼續(xù)處理。
- 2xx:成功表示請(qǐng)求已被成功接收吴攒、理解张抄、接受。
- 3xx:重定向要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作洼怔。
- 4xx:客戶(hù)端錯(cuò)誤請(qǐng)求有語(yǔ)法錯(cuò)誤或請(qǐng)求無(wú)法實(shí)現(xiàn)署惯。
- 5xx:服務(wù)器端錯(cuò)誤服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求。
常見(jiàn)狀態(tài)代碼茴厉、狀態(tài)描述的說(shuō)明如下
- 200 OK:客戶(hù)端請(qǐng)求成功泽台。
- 400 Bad Request:客戶(hù)端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解矾缓。
- 401 Unauthorized:請(qǐng)求未經(jīng)授權(quán)怀酷,這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用。
- 403 Forbidden:服務(wù)器收到請(qǐng)求嗜闻,但是拒絕提供服務(wù)蜕依。
- 404 Not Found:請(qǐng)求資源不存在,舉個(gè)例子:輸入了錯(cuò)誤的URL琉雳。 500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤样眠。
- 503 Server Unavailable:服務(wù)器當(dāng)前不能處理客戶(hù)端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常翠肘,舉個(gè)例子:HTTP/1.1 200 OK(CRLF)檐束。
GET和POST
- GET提交,請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后(就是把數(shù)據(jù)放置在HTTP協(xié)議頭<request-line>中)束倍,以?分割URL和傳輸數(shù)據(jù)被丧,多個(gè) 參數(shù)用&連接?如果數(shù) 據(jù)是英文字母/數(shù)字盟戏,原樣發(fā)送,如果是空格甥桂,轉(zhuǎn)換為+柿究,如果是中文/其他字符办陷,則直接把字符串用BASE64加密,貌夕,GET提交的數(shù)據(jù)會(huì)在地址欄中顯示出來(lái),而POST提交,地址欄不會(huì)改變, POST提交:把提交的數(shù)據(jù)放置在是HTTP包的包體<request body>中殃恒。
- HTTP協(xié)議沒(méi)有對(duì)傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制,HTTP協(xié)議規(guī)范也沒(méi)有對(duì)URL長(zhǎng)度進(jìn)行限制问窃。 而在實(shí)際開(kāi)發(fā)中存在的限制 主要有:
- GET:特定瀏覽器和服務(wù)器對(duì)URL長(zhǎng)度有限制亥鬓,例如IE對(duì)URL長(zhǎng)度的限制是2083字節(jié)(2K+35)。對(duì)于其他瀏覽器域庇,如 Netscape嵌戈、FireFox等,理論上沒(méi)有長(zhǎng)度限制听皿,其限制取決于操作系統(tǒng)的支持熟呛。
- 因此對(duì)于GET提交時(shí),傳輸數(shù)據(jù)就會(huì)受到URL長(zhǎng)度的限制尉姨。
- POST:由于不是通過(guò)URL傳值庵朝,理論上數(shù)據(jù)不受限。但實(shí)際各個(gè)WEB服務(wù)器會(huì)規(guī)定對(duì)post提交數(shù)據(jù)大小進(jìn)行限制又厉,Apache九府、 IIS6都有各自的配置。
- POST的安全性要比GET的安全性高覆致。注意:這里所說(shuō)的安全性和上面GET提到的“安全”不是同個(gè)概念侄旬。上面“安全”的含義僅僅 是不作數(shù)據(jù)修改,而這里安全的含義是真正的Security的含義煌妈,比如:通過(guò)GET提交數(shù)據(jù)儡羔,用戶(hù)名和密碼將明文出現(xiàn)在URL上宣羊,因 為(1)登錄頁(yè)面有可能被瀏覽器緩存, (2)其他人查看瀏覽器的歷史紀(jì)錄笔链,那么別人就可以拿到你的賬號(hào)和密碼了段只,
數(shù)據(jù)類(lèi)型
- 標(biāo)量 :boolean (布爾型)integer (整型)float (浮點(diǎn)型, 也稱(chēng)作 double) string (字符串)
- 復(fù)合 :數(shù)組 對(duì)象
- 特殊 :NULL resource(資源)
常見(jiàn)的header頭
- // 信息型狀態(tài)碼,提示目前為止一切正常鉴扫,客戶(hù)端應(yīng)該繼續(xù)請(qǐng)求, 如果已完成請(qǐng)求則忽略.
- header('HTTP/1.1 100 OK');
- //通知瀏覽器 頁(yè)面不存在
- header('HTTP/1.1 404 Not Found');
- //資源被永久的重定向 301 ;302:臨時(shí)重定向(該資源臨時(shí)被改變位置)
- header('HTTP/1.1 301 Moved Permanently');
- //跳轉(zhuǎn)到一個(gè)新的地址
- header('Location: http://php.itcast.cn/');
- //延遲轉(zhuǎn)向也就是隔幾秒跳轉(zhuǎn)
- header('Refresh:10;url=http://php.itcast.cn/');
-
內(nèi)容類(lèi)型###
- //網(wǎng)頁(yè)編碼
- header('Content-Type: text/html;charset=utf-8');
- //純文本格式
- header('Content-Type:text/plain');
- //JPG赞枕、JPEG
- header('Content-Type:image/jpeg');
- //ZIP文件
- header('Content-Type:application/zip');
- //PDF文件
- header('Content-Type:application/pdf');
- //音頻文件
- header('Content-Type: ');
- //css文件
- header('Content-type:text/css');
-
聲明一個(gè)下載的文件###
- header('Content-Type:application/octet-stream');
- header('Content-Disposition:attachment;filename="ITblog.zip"');
-
顯示一個(gè)需要驗(yàn)證的登陸對(duì)話(huà)框###
- header('HTTP/1.1 401Unauthorized');
- header('WWW-Authenticate:Basic realm="TopSecret"');
魔術(shù)方法
- __autoload() 類(lèi)文件自動(dòng)加載函數(shù)
- __construct() 構(gòu)造函數(shù),PHP將在對(duì)象創(chuàng)建時(shí)調(diào)用這個(gè)方法
- __destruct() 析構(gòu)函數(shù)坪创,PHP將在對(duì)象被銷(xiāo)毀前(即從內(nèi)存中清除前)調(diào)用這個(gè)方法
- __call() 當(dāng)所調(diào)用的成員方法不存在(或者沒(méi)有權(quán)限)該類(lèi)時(shí)調(diào)用炕婶,用于對(duì)錯(cuò)誤后做一些操作或者提示信息
- __clone() 該函數(shù)在對(duì)象克隆時(shí)自動(dòng)調(diào)用,其作用是對(duì)克隆的副本做一些初始化操作
- __get() 當(dāng)所對(duì)象所調(diào)用的成員屬性未聲明或者級(jí)別為private或者protected等時(shí)莱预,我們可以在這個(gè)函數(shù)里進(jìn)行自己的一些操作
- __set() 當(dāng)所對(duì)未聲明或者級(jí)別為private或者protected等進(jìn)行賦值時(shí)調(diào)用此函數(shù)柠掂,我們可以在這個(gè)函數(shù)里進(jìn)行自己的一些操作
- __isset() 當(dāng)對(duì)一個(gè)未聲明或者訪(fǎng)問(wèn)級(jí)別受限的成員屬性調(diào)用isset函數(shù)時(shí)調(diào)用此函數(shù),共用戶(hù)做一些操作
- __unset() 當(dāng)對(duì)一個(gè)未聲明或者訪(fǎng)問(wèn)級(jí)別受限的成員屬性調(diào)用unset函數(shù)時(shí)調(diào)用此函數(shù)依沮,共用戶(hù)做一些操作
- __toString()函數(shù) 該函數(shù)在將對(duì)象引用作為字符串操作時(shí)自動(dòng)調(diào)用涯贞,返回一個(gè)字符串
- __sleep()函數(shù) 該函數(shù)是在序列化時(shí)自動(dòng)調(diào)用的,序列化這里可以理解成將信息寫(xiě)如文件中更長(zhǎng)久保存
- __wakeup()函數(shù) 該魔術(shù)方法在反序列化的時(shí)候自動(dòng)調(diào)用危喉,為反序列化生成的對(duì)象做一些初始化操作
- __invoke()函數(shù)宋渔,當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個(gè)對(duì)象時(shí),__invoke 方法會(huì)被自動(dòng)調(diào)用辜限。
- _callStatic()函數(shù)皇拣,它的工作方式類(lèi)似于 __call() 魔術(shù)方法,__callStatic() 是為了處理靜態(tài)方法調(diào)用薄嫡,
超全局變量
- $GLOBALS是PHP的一個(gè)超級(jí)全局變量組氧急,在一個(gè)PHP腳本的全部作用域中都可以訪(fǎng)問(wèn)。是一個(gè)包含了全部變量的全局組合數(shù)組毫深。變量的名字就是數(shù)組的鍵吩坝。
- $_SERVER是一個(gè)包含了諸如頭信息(header)、路徑(path)费什、以及腳本位置(script locations)等等信息的數(shù)組钾恢。這個(gè)數(shù)組中的項(xiàng)目由 Web 服務(wù)器創(chuàng)建。不能保證每個(gè)服務(wù)器都提供全部項(xiàng)目鸳址;服務(wù)器可能會(huì)忽略一些瘩蚪,或者提供一些沒(méi)有在這里列舉出來(lái)的項(xiàng)目。
- $_REQUEST 用于收集HTML表單提交的數(shù)據(jù)稿黍。
- $_POST 被廣泛應(yīng)用于收集表單數(shù)據(jù)疹瘦,在HTML form標(biāo)簽的指定該屬性:"method="post"。
- $_GET 同樣被廣泛應(yīng)用于收集表單數(shù)據(jù)巡球,在HTML form標(biāo)簽的指定該屬性:"method="get"言沐。
- $_COOKIE 經(jīng)由 HTTP Cookies 方法提交至腳本的變量
- HTTP_SESSION_VARS 數(shù)組。
- HTTP_POST_FILES 數(shù)組汹押。
- HTTP_ENV_VARS 數(shù)組起便。
http 和 https 區(qū)別
1棚贾、https協(xié)議需要到ca申請(qǐng)證書(shū),一般免費(fèi)證書(shū)較少榆综,因而需要一定費(fèi)用妙痹。
2、http是超文本傳輸協(xié)議鼻疮,信息是明文傳輸怯伊,https則是具有安全性的ssl加密傳輸協(xié)議。
3判沟、http和https使用的是完全不同的連接方式耿芹,用的端口也不一樣,前者是80挪哄,后者是443猩系。
4、http的連接很簡(jiǎn)單中燥,是無(wú)狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸塘偎、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議疗涉,比http協(xié)議安全。
hash取模算法
hash算法
分布式cahce系統(tǒng)中的一致性hash算法應(yīng)該滿(mǎn)足以下幾個(gè)方面
平衡性(Balance)
哈希的結(jié)果能夠盡可能分布到所有的緩沖中去吟秩,這樣可以使得所有的緩沖空間都得到利用咱扣。
單調(diào)性(Monotonicity)
如果已經(jīng)有一些內(nèi)容通過(guò)哈希分派到了相應(yīng)的緩沖中,又有新的緩沖區(qū)加入到系統(tǒng)中涵防,那么哈希的結(jié)果應(yīng)能夠保證原有已分配的內(nèi)容可以被映射到新的緩沖區(qū)中去闹伪,而不會(huì)被映射到舊的緩沖集合中的其他緩沖區(qū)。簡(jiǎn)單的哈希算法往往不能滿(mǎn)足單調(diào)性的要求壮池,如最簡(jiǎn)單的線(xiàn)性哈希:x = (ax + b) mod (P)偏瓤,在上式中,P表示全部緩沖的大小椰憋。不難看出厅克,當(dāng)緩沖大小發(fā)生變化時(shí)(從P1到P2),原來(lái)所有的哈希結(jié)果均會(huì)發(fā)生變化橙依,從而不滿(mǎn)足單調(diào)性的要求证舟。哈希結(jié)果的變化意味著當(dāng)緩沖空間發(fā)生變化時(shí)硕旗,所有的映射關(guān)系需要在系統(tǒng)內(nèi)全部更新。而在P2P系統(tǒng)內(nèi)女责,緩沖的變化等價(jià)于Peer加入或退出系統(tǒng)漆枚,這一情況在P2P系統(tǒng)中會(huì)頻繁發(fā)生,因此會(huì)帶來(lái)極大計(jì)算和傳輸負(fù)荷抵知。單調(diào)性就是要求哈希算法能夠應(yīng)對(duì)這種情況墙基。
分散性(Spread)
在分布式環(huán)境中,終端有可能看不到所有的緩沖辛藻,而是只能看到其中的一部分碘橘。當(dāng)終端希望通過(guò)哈希過(guò)程將內(nèi)容映射到緩沖上時(shí),由于不同終端所見(jiàn)的緩沖范圍有可能不同吱肌,從而導(dǎo)致哈希的結(jié)果不一致痘拆,最終的結(jié)果是相同的內(nèi)容被不同的終端映射到不同的緩沖區(qū)中。這種情況顯然是應(yīng)該避免的氮墨,因?yàn)樗鼘?dǎo)致相同內(nèi)容被存儲(chǔ)到不同緩沖中去纺蛆,降低了系統(tǒng)存儲(chǔ)的效率。分散性的定義就是上述情況發(fā)生的嚴(yán)重程度规揪。好的哈希算法應(yīng)能夠盡量避免不一致的情況發(fā)生桥氏,也就是盡量降低分散性。
負(fù)載(Load)
負(fù)載問(wèn)題實(shí)際上是從另一個(gè)角度看待分散性問(wèn)題猛铅。既然不同的終端可能將相同的內(nèi)容映射到不同的緩沖區(qū)中字支,那么對(duì)于一個(gè)特定的緩沖區(qū)而言,也可能被不同的用戶(hù)映射為不同的內(nèi)容奸忽。與分散性一樣堕伪,這種情況也是應(yīng)當(dāng)避免的,因此好的哈希算法應(yīng)能夠盡量降低緩沖的負(fù)荷栗菜。
平滑性(Smoothness)
平滑性是指緩存服務(wù)器的數(shù)目平滑改變和緩存對(duì)象的平滑改變是一致的欠雌。
hash取模算法
常用的算法是對(duì)hash結(jié)果取余數(shù) (hash() mod N):對(duì)機(jī)器編號(hào)從0到N-1,按照自定義的hash()算法疙筹,對(duì)每個(gè)請(qǐng)求的hash()值按N取模富俄,得到余數(shù)i,然后將請(qǐng)求分發(fā)到編號(hào)為i的機(jī)器而咆。但這樣的算法方法存在致命問(wèn)題霍比,如果某一臺(tái)機(jī)器宕機(jī),那么應(yīng)該落在該機(jī)器的請(qǐng)求就無(wú)法得到正確的處理翘盖,這時(shí)需要將當(dāng)?shù)舻姆?wù)器從算法從去除桂塞,此時(shí)候會(huì)有(N-1)/N的服務(wù)器的緩存數(shù)據(jù)需要重新進(jìn)行計(jì)算;
為何是 (N-1)/N 呢
- 比如有 3 臺(tái)機(jī)器馍驯,hash值 1-6 在這3臺(tái)上的分布就是:
- host 1: 1 4
- host 2: 2 5
- host 3: 3 6
- 如果掛掉一臺(tái)阁危,只剩兩臺(tái)玛痊,模數(shù)取 2 ,那么分布情況就變成:
- host 1: 1 3 5
- host 2: 2 4 6
- 可以看到狂打,還在數(shù)據(jù)位置不變的只有2個(gè): 1擂煞,2,位置發(fā)生改變的有4個(gè)趴乡,占共6個(gè)數(shù)據(jù)的比率是 4/6 = 2/3对省。
虛擬節(jié)點(diǎn)
- 對(duì)于hash取模算法,當(dāng)某個(gè)節(jié)點(diǎn)的服務(wù)器壞了晾捏,算有壓力將轉(zhuǎn)到下個(gè)節(jié)點(diǎn)的服務(wù)器蒿涎。那我們考慮是否能夠?qū)毫D(zhuǎn)到其他節(jié)點(diǎn)。
- 虛擬節(jié)點(diǎn)即:N個(gè)真實(shí)節(jié)點(diǎn),把每個(gè)真實(shí)節(jié)點(diǎn)映射成M個(gè)虛擬節(jié)點(diǎn), 再把M* N個(gè)虛擬節(jié)點(diǎn),
- 散列在圓環(huán)上. 各真實(shí)節(jié)點(diǎn)對(duì)應(yīng)的虛擬節(jié)點(diǎn)相互交錯(cuò)分布惦辛,這樣劳秋,某真實(shí)節(jié)點(diǎn)down后,則把其影響平均分擔(dān)到其他所有節(jié)點(diǎn)上。
訪(fǎng)問(wèn)方法:
如果有一個(gè)寫(xiě)入緩存的請(qǐng)求胖齐,其中Key值為K玻淑,計(jì)算器hash值Hash(K), Hash(K) 對(duì)應(yīng)于環(huán)中的某一個(gè)點(diǎn)呀伙,如果該點(diǎn)對(duì)應(yīng)沒(méi)有映射到具體的某一個(gè)機(jī)器節(jié)點(diǎn)补履,那么順時(shí)針查找,直到第一次找到有映射機(jī)器的節(jié)點(diǎn)剿另,該節(jié)點(diǎn)就是確定的目標(biāo)節(jié)點(diǎn)箫锤,如果超過(guò)了2^32仍然找不到節(jié)點(diǎn),則命中第一個(gè)機(jī)器節(jié)點(diǎn)雨女。
一致性哈希算法
一種特殊的哈希算法麻汰,目前主要應(yīng)用于分布式緩存當(dāng)中,可以有效地解決分布式存儲(chǔ)結(jié)構(gòu)下動(dòng)態(tài)增加和刪除節(jié)點(diǎn)所帶來(lái)的問(wèn)題戚篙。
- 一致性Hash算法是對(duì)232取模,232個(gè)點(diǎn)組成的圓環(huán)稱(chēng)為Hash環(huán)溺职。根據(jù)服務(wù)節(jié)點(diǎn)的IP或者機(jī)器名稱(chēng)進(jìn)行哈希岔擂,就能確定每臺(tái)機(jī)器就能確定其在哈希環(huán)上的位置;
- 將數(shù)據(jù)key使用相同的函數(shù)Hash計(jì)算出哈希值浪耘,并確定此數(shù)據(jù)在環(huán)上的位置乱灵,從此位置沿環(huán)順時(shí)針“行走”,第一臺(tái)遇到的服務(wù)器就是其應(yīng)該定位到的服務(wù)器七冲。
- 添加痛倚、刪除節(jié)點(diǎn)的時(shí)候,只影響相鄰一個(gè)節(jié)點(diǎn)的數(shù)據(jù)澜躺,其他節(jié)點(diǎn)的數(shù)據(jù)不影響蝉稳。具有較好的擴(kuò)展性和容錯(cuò)性抒蚜。
- 為了防止數(shù)據(jù)分布不均勻,可以應(yīng)用虛擬節(jié)點(diǎn)來(lái)映射物理節(jié)點(diǎn)耘戚。
hash槽
Redis準(zhǔn)備了16384個(gè)hash槽嗡髓,類(lèi)似于Memcached Hash環(huán)上的一個(gè)個(gè)位置。 這16384個(gè)hash槽被分配給不同節(jié)點(diǎn)收津,存放數(shù)據(jù)時(shí)饿这,根據(jù)數(shù)據(jù)的key計(jì)算出所在的槽,再根據(jù)槽找到對(duì)應(yīng)的機(jī)器撞秋。hash函數(shù)為:CRC16(key) % 16384长捧。
為什么是16384绣版?
我們需要維護(hù)節(jié)點(diǎn)和槽之間的映射關(guān)系谒拴,每個(gè)節(jié)點(diǎn)需要知道自己有哪些槽,并且需要在結(jié)點(diǎn)之間傳遞這個(gè)消息舞竿。為了節(jié)省存儲(chǔ)空間廓八,每個(gè)節(jié)點(diǎn)用一個(gè)Bitmap來(lái)存放其對(duì)應(yīng)的槽: 2k = 210248 = 16384奉芦,也就是說(shuō),每個(gè)結(jié)點(diǎn)用2k的內(nèi)存空間剧蹂,總共16384個(gè)比特位声功,就可以存儲(chǔ)該結(jié)點(diǎn)對(duì)應(yīng)了哪些槽。然后這2k的信息宠叼,通過(guò)Gossip協(xié)議先巴,在結(jié)點(diǎn)之間傳遞。
php遠(yuǎn)程獲取文件
第一種:file_get_contents
$url = '![](file:///C:\Users\ASUS\AppData\Roaming\Tencent\QQ\Temp\%W@GJ$ACOF(TYDYECOKVDYB.png)http://www.xxx.com/';
$contents = file_get_contents($url)
curl
** 第二種使用 curl **
$url = “![](file:///C:\Users\ASUS\AppData\Roaming\Tencent\QQ\Temp\%W@GJ$ACOF(TYDYECOKVDYB.png)http://www.xxx.com/”;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);\
$contents = curl_exec($ch);
第三種
3.fopen->fread->fclose
$handle = fopen (“![](file:///C:\Users\ASUS\AppData\Roaming\Tencent\QQ\Temp\%W@GJ$ACOF(TYDYECOKVDYB.png)http://www.xxx.com/”, “rb”);
$data = fread($handle, 8192)
一般我們使用 curl 來(lái)進(jìn)行 文章的抓取 他可以設(shè)置 超時(shí)時(shí)間 比較方便
怎么解決請(qǐng)求被劫持的問(wèn)題
推薦用https冒冬,充分測(cè)試無(wú)問(wèn)題以后在服務(wù)器端配置HSTS頭伸蚯,但即使這樣也還不能解決首次訪(fǎng)問(wèn)時(shí)的劫持問(wèn)題,不過(guò)已經(jīng)能解決絕大部分的問(wèn)題了简烤。如果是個(gè)人網(wǎng)站剂邮,建議直接用sha2的證書(shū),sha1的證書(shū)已經(jīng)不安全了横侦,雙證書(shū)費(fèi)用和維護(hù)成本都不低挥萌,何況第三方瀏覽器現(xiàn)在是流量的大頭
用戶(hù)輸入url到頁(yè)面顯示經(jīng)歷了哪些
**通過(guò)DNS找對(duì)應(yīng)的IP **
- 找瀏覽器緩存,瀏覽器會(huì)保存一段時(shí)間你之前訪(fǎng)問(wèn)過(guò)的一些網(wǎng)址的DNS信息
- 通過(guò)dns 找 域 名對(duì)應(yīng)ip 本地的 host 通過(guò)dns 找 域名對(duì)應(yīng)ip
- 接著會(huì)發(fā)送一個(gè)請(qǐng)求到路由器上枉侧,然后路由器在自己的路由器緩存上查找記錄引瀑,路由器一 般也存有DNS信息。
- 通過(guò)dns 找 域名對(duì)應(yīng)ip 你的ISP的DNS服務(wù)器會(huì)將請(qǐng)求發(fā)向根域名服務(wù)器進(jìn)行搜通過(guò)dns 找 域名對(duì)應(yīng)ip
**通過(guò)IP 向?qū)?yīng)的web服務(wù)器發(fā)送請(qǐng)求 **
瀏覽器終于得到了IP以后榨馁,瀏覽器接著給這個(gè)IP的服務(wù)器發(fā)送了一個(gè)http請(qǐng)求憨栽,方式為get,例如訪(fǎng)問(wèn)nbut.cn
**服務(wù)器接受到請(qǐng)求后,如果是nginx 通過(guò)nginx的location匹配 后綴是.php的文件屑柔, 然后如果是屡萤,則將這個(gè)請(qǐng)求轉(zhuǎn)發(fā)到127.0.0.1:9000的個(gè)服務(wù),而9000 這個(gè)服務(wù)是PHP锯蛀, 把請(qǐng)求交給php來(lái)進(jìn)行處理灭衷,php處理完畢,把處理的數(shù)據(jù)發(fā)送給nginx ,nginx把數(shù)據(jù)再 相應(yīng)旁涤,并發(fā)送給瀏覽器 **
服務(wù)器收到瀏覽器的請(qǐng)求以后(其實(shí)是WEB服務(wù)器接收到了這個(gè)請(qǐng)求翔曲,WEB服務(wù)器有iis、 apache等 會(huì)解析這個(gè)請(qǐng)求(讀請(qǐng)求頭)劈愚,然后生成一個(gè)響應(yīng)頭和具體響應(yīng)內(nèi)容 如果是個(gè)靜態(tài)頁(yè)面瞳遍,那么基本上到這一步就沒(méi)了
頁(yè)面還有其他資源(css img js ) 繼續(xù)重復(fù)執(zhí)行
主頁(yè)(index)頁(yè)面框架傳送過(guò)來(lái)以后,瀏覽器還要繼續(xù)向服務(wù)器發(fā)送請(qǐng)求菌羽,請(qǐng)求的內(nèi)容是 主頁(yè)里面包含的一些資源掠械,如圖片,視頻注祖,css樣式等等
php 相關(guān)
cgi 猾蒂,fastcgi,php-fpm 區(qū)別
cgi
- CGI的英文是(COMMON GATEWAY INTERFACE)公共網(wǎng)關(guān)接口是晨,它的作用就是幫助服務(wù)器與語(yǔ)言通信肚菠,這里就是nginx和php進(jìn)行通信,因?yàn)閚ginx和php的語(yǔ)言不通罩缴,因此需要一個(gè)溝通轉(zhuǎn)換的過(guò)程蚊逢,而CGI就是這個(gè)溝通的協(xié)議。
- nginx服務(wù)器在接受到瀏覽器傳遞過(guò)來(lái)的數(shù)據(jù)后箫章,如果請(qǐng)求的是靜態(tài)的頁(yè)面或者圖片等無(wú)需動(dòng)態(tài)處理的則會(huì)直接根據(jù)請(qǐng)求的url找到其位置然后返回給瀏覽器烙荷,這里無(wú)需php參與,但是如果是一個(gè)動(dòng)態(tài)的頁(yè)面請(qǐng)求檬寂,這個(gè)時(shí)候nginx就必須與php通信终抽,這個(gè)時(shí)候就會(huì)需要用到cgi協(xié)議,將請(qǐng)求數(shù)據(jù)轉(zhuǎn)換成php能理解的信息桶至,然后php根據(jù)這些信息返回的信息也要通過(guò)cgi協(xié)議轉(zhuǎn)換成nginx可以理解的信息拿诸,最后nginx接到這些信息再返回給瀏覽器。
fast-cgi
- 傳統(tǒng)的cgi協(xié)議在每次連接請(qǐng)求時(shí)塞茅,會(huì)開(kāi)啟一個(gè)進(jìn)程進(jìn)行處理,處理完畢會(huì)關(guān)閉該進(jìn)程季率,因此下次連接野瘦,又要再次開(kāi)啟一個(gè)進(jìn)程進(jìn)行處理,因此有多少個(gè)連接就有多少個(gè)cgi進(jìn)程,這也就是為什么傳統(tǒng)的cgi會(huì)顯得緩慢的原因鞭光,因此過(guò)多的進(jìn)程會(huì)消耗資源和內(nèi)存吏廉。
- 而fast-cgi每次處理完請(qǐng)求后,不會(huì)kill掉這個(gè)進(jìn)程惰许,而是保留這個(gè)進(jìn)程席覆,使這個(gè)進(jìn)程可以一次處理多個(gè)請(qǐng)求。這樣每次就不用重新fork一個(gè)進(jìn)程了汹买,大大提高效率佩伤。
php-cgi
php-cgi是php提供給web serve也就是http前端服務(wù)器的cgi協(xié)議接口程序,當(dāng)每次接到http前端服務(wù)器的請(qǐng)求都會(huì)開(kāi)啟一個(gè)php-cgi進(jìn)程進(jìn)行處理晦毙,而且開(kāi)啟的php-cgi的過(guò)程中會(huì)先要重載配置生巡,數(shù)據(jù)結(jié)構(gòu)以及初始化運(yùn)行環(huán)境,如果更新了php配置见妒,那么就需要重啟php-cgi才能生效孤荣,例如phpstudy就是這種情況。
php-fpm
- php-fpm是php提供給web serve也就是http前端服務(wù)器的fastcgi協(xié)議接口程序须揣,它不會(huì)像php-cgi一樣每次連接都會(huì)重新開(kāi)啟一個(gè)進(jìn)程盐股,處理完請(qǐng)求又關(guān)閉這個(gè)進(jìn)程,而是允許一個(gè)進(jìn)程對(duì)多個(gè)連接進(jìn)行處理耻卡,而不會(huì)立即關(guān)閉這個(gè)進(jìn)程疯汁,而是會(huì)接著處理下一個(gè)連接。它可以說(shuō)是php-cgi的一個(gè)管理程序劲赠,是對(duì)php-cgi的改進(jìn)涛目。
- php-fpm會(huì)開(kāi)啟多個(gè)php-cgi程序,并且php-fpm常駐內(nèi)存凛澎,每次web serve服務(wù)器發(fā)送連接過(guò)來(lái)的時(shí)候霹肝,php-fpm將連接信息分配給下面其中的一個(gè)子程序php-cgi進(jìn)行處理,處理完畢這個(gè)php-cgi并不會(huì)關(guān)閉塑煎,而是繼續(xù)等待下一個(gè)連接沫换,這也是fast-cgi加速的原理,但是由于php-fpm是多進(jìn)程的最铁,而一個(gè)php-cgi基本消耗7-25M內(nèi)存讯赏,因此如果連接過(guò)多就會(huì)導(dǎo)致內(nèi)存消耗過(guò)大,引發(fā)一些問(wèn)題冷尉,例如nginx里的502錯(cuò)誤漱挎。
- 同時(shí)php-fpm還附帶一些其他的功能:
- 例如平滑過(guò)渡配置更改,普通的php-cgi在每次更改配置后雀哨,需要重新啟動(dòng)才能初始化新的配置磕谅,而php-fpm是不需要私爷,php-fpm分將新的連接發(fā)送給新的子程序php-cgi,這個(gè)時(shí)候加載的是新的配置膊夹,而原先正在運(yùn)行的php-cgi還是使用的原先的配置衬浑,等到這個(gè)連接后下一次連接的時(shí)候會(huì)使用新的配置初始化,這就是平滑過(guò)渡放刨。
參考鏈接:https://blog.csdn.net/belen_xue/article/details/65950658
PHP5 跟php7的區(qū)別
PHP7.0 號(hào)稱(chēng)是性能提升上革命性的一個(gè)版本工秩。面對(duì) Facebook 家的 HHVM 引擎帶來(lái)的壓力,開(kāi)發(fā)團(tuán)隊(duì)重寫(xiě)了底層的 Zend Engine进统,名為 Zend Engine 2助币。
底層內(nèi)核解析
PHP7 中最重要的改變就是 zval 不再單獨(dú)從堆上分配內(nèi)存并且不自己存儲(chǔ)引用計(jì)數(shù)。需要使用 zval 指針的復(fù)雜類(lèi)型(比如字符串麻昼、數(shù)組和對(duì)象)會(huì)自己存儲(chǔ)引用計(jì)數(shù)奠支。這樣就可以有更少的內(nèi)存分配操作、更少的間接指針使用以及更少的內(nèi)存分配抚芦。在PHP7中的zval, 已經(jīng)變成了一個(gè)值指針, 它要么保存著原始值, 要么保存著指向一個(gè)保存原始值的指針. 也就是說(shuō)現(xiàn)在的zval相當(dāng)于PHP5的時(shí)候的zval * . 只不過(guò)相比于zval * , 直接存儲(chǔ)zval, 我們可以省掉一次指針解引用, 從而提高緩存友好性.
參考鏈接:https://www.jb51.net/article/76732.htm
PHP7 為什么比 PHP5 性能提升了
1倍谜、變量存儲(chǔ)字節(jié)減小,減少內(nèi)存占用叉抡,提升變量操作速度
2尔崔、改善數(shù)組結(jié)構(gòu),數(shù)組元素和hash映射表被分配在同一塊內(nèi)存里褥民,降低了內(nèi)存占用季春、提升了 cpu 緩存命中率
3、改進(jìn)了函數(shù)的調(diào)用機(jī)制消返,通過(guò)優(yōu)化參數(shù)傳遞的環(huán)節(jié)载弄,減少了一些指令,提高執(zhí)行效率
安全
函數(shù)修改
- preg_replace()不再支持/e修飾符宇攻,,同時(shí)官方給了我們一個(gè)新的函數(shù)preg_replace_callback
- create_function()被廢棄倡勇,實(shí)際上它是通過(guò)執(zhí)行eval實(shí)現(xiàn)的逞刷。
- mysql_* 系列全員移除,如果你要在PHP7上面用老版本的mysql_* 系列函數(shù)需要你自己去額外裝了妻熊,官方不在自帶夸浅,現(xiàn)在官方推薦的是mysqli或者pdo_mysql。
- unserialize()增加一個(gè)可選白名單參數(shù)扔役,其實(shí)就是一個(gè)白名單帆喇,如果反序列數(shù)據(jù)里面的類(lèi)名不在這個(gè)白名單內(nèi),就會(huì)報(bào)錯(cuò)亿胸。
- assert() 默認(rèn)不在可以執(zhí)行代碼
語(yǔ)法修改
- foreach不再改變內(nèi)部數(shù)組指針
- 8進(jìn)制字符容錯(cuò)率降低坯钦,在php5版本法严,如果一個(gè)八進(jìn)制字符如果含有無(wú)效數(shù)字,該無(wú)效數(shù)字將被靜默刪節(jié)葫笼。在php7里面會(huì)觸發(fā)一個(gè)解析錯(cuò)誤。
- 十六進(jìn)制字符串不再被認(rèn)為是數(shù)字
- 移除了 ASP 和 script PHP 標(biāo)簽
- 超大浮點(diǎn)數(shù)類(lèi)型轉(zhuǎn)換截?cái)噢致瑢⒏↑c(diǎn)數(shù)轉(zhuǎn)換為整數(shù)的時(shí)候路星,如果浮點(diǎn)數(shù)值太大,導(dǎo)致無(wú)法以整數(shù)表達(dá)的情況下诱桂, 在PHP5的版本中洋丐,轉(zhuǎn)換會(huì)直接將整數(shù)截?cái)啵⒉粫?huì)引發(fā)錯(cuò)誤挥等。 在PHP7中友绝,會(huì)報(bào)錯(cuò)。
參考鏈接:https://www.freebuf.com/articles/web/197013.html
總體
- 性能提升:PHP7比PHP5.0性能提升了兩倍肝劲。
- 全面一致的64位支持迁客。
- 以前的許多致命錯(cuò)誤,現(xiàn)在改成[拋出異常]辞槐。
- PHP 7.0比PHP5.0移除了一些老的不在支持的SAPI([服務(wù)器端]應(yīng)用編程端口)和擴(kuò)展掷漱。
- .PHP 7.0比PHP5.0新增了空接合操作符。
- PHP 7.0比PHP5.0新增加了結(jié)合比較運(yùn)算符榄檬。
- PHP 7.0比PHP5.0新增加了函數(shù)的返回類(lèi)型聲明卜范。
- PHP 7.0比PHP5.0新增加了標(biāo)量類(lèi)型聲明。
- PHP 7.0比PHP5.0新增加匿名類(lèi)鹿榜。
多進(jìn)程同時(shí)讀寫(xiě)一個(gè)文件
- PHP是支持進(jìn)程的而不支持多線(xiàn)程(這個(gè)先搞清楚了)海雪,如果是對(duì)于文件操作,其實(shí)你只需要給文件加鎖就能解決舱殿,不需要其它操作奥裸,PHP的flock已經(jīng)幫你搞定了。
- 用flock在寫(xiě)文件前先鎖上怀薛,等寫(xiě)完后解鎖刺彩,這樣就實(shí)現(xiàn)了多線(xiàn)程同時(shí)讀寫(xiě)一個(gè)文件避免沖突。
流程
- flock參數(shù)說(shuō)明:file 必需枝恋,規(guī)定要鎖定或釋放的已打開(kāi)的文件,lock 必需创倔。規(guī)定要使用哪種鎖定類(lèi)型。block 可選焚碌。若設(shè)置為 1 或 true畦攘,則當(dāng)進(jìn)行鎖定時(shí)阻擋其他進(jìn)程。
- LOCK_SH 要取得共享鎖定(讀取的程序)
- LOCK_EX 要取得獨(dú)占鎖定(寫(xiě)入的程序)
- LOCK_UN 要釋放鎖定(無(wú)論共享或獨(dú)占)
- LOCK_NB 如果不希望 flock() 在鎖定時(shí)堵塞
在PHP中十电,flock似乎工作的不是那么好知押!在多并發(fā)情況下叹螟,似乎是經(jīng)常獨(dú)占資源,不即時(shí)釋放台盯,或者是根本不釋放罢绽,造成死鎖,從而使服務(wù)器的cpu占用很高静盅,甚至有時(shí)候會(huì)讓服務(wù)器徹底死掉良价。好所以使用flock之前,一定要慎重考慮蒿叠。
解決方案
- 對(duì)文件進(jìn)行加鎖時(shí)明垢,設(shè)置一個(gè)超時(shí)時(shí)間,超時(shí)設(shè)置為1ms,如果這里時(shí)間內(nèi)沒(méi)有獲得鎖市咽,就反復(fù)獲得痊银,直接獲得到對(duì)文件操作權(quán)為止,當(dāng)然施绎。如果超時(shí)限制已到溯革,就必需馬上退出,讓出鎖讓其它進(jìn)程來(lái)進(jìn)行操作粘姜。
- 不使用flock函數(shù)鬓照,借用臨時(shí)文件來(lái)解決讀寫(xiě)沖突的問(wèn)題
- 將需要更新的文件考慮一份到我們的臨時(shí)文件目錄,將文件最后修改時(shí)間保存到一個(gè)變量孤紧,并為這個(gè)臨時(shí)文件取一個(gè)隨機(jī)的豺裆,不容易重復(fù)的文件名。
- 當(dāng)對(duì)這個(gè)臨時(shí)文件進(jìn)行更新后号显,再檢測(cè)原文件的最后更新時(shí)間和先前所保存的時(shí)間是否一致臭猜。
- 如果最后一次修改時(shí)間一致,就將所修改的臨時(shí)文件重命名到原文件押蚤,為了確保文件狀態(tài)同步更新蔑歌,所以需要清除一下文件狀態(tài)。
- 但是揽碘,如果最后一次修改時(shí)間和先前所保存的一致次屠,這說(shuō)明在這期間,原文件已經(jīng)被修改過(guò)雳刺,這時(shí)劫灶,需要把臨時(shí)文件刪除,然后返回false,說(shuō)明文件這時(shí)有其它進(jìn)程在進(jìn)行操作掖桦。
- 對(duì)操作的文件進(jìn)行隨機(jī)讀寫(xiě)本昏,以降低并發(fā)的可能性。
- 先前需要定義一個(gè)隨機(jī)空間枪汪,空間越大涌穆,并發(fā)的的可能性就越小怔昨,這里假設(shè)隨機(jī)讀寫(xiě)空間為[1-500],那么我們的日志文件的分布就為log1到log500不等。每一次用戶(hù)訪(fǎng)問(wèn)宿稀,都將數(shù)據(jù)隨機(jī)寫(xiě)到log1log500之間的任一文件趁舀。在同一時(shí)刻,有2個(gè)進(jìn)程進(jìn)行記錄日志祝沸,A進(jìn)程可能是更新的log32文件赫编,而B(niǎo)進(jìn)程呢?則此時(shí)更新的可能就為log399.要知道奋隶,如果要讓B進(jìn)程也操作log32,概率基本上為1/500,差不多約等于零。在需要對(duì)訪(fǎng)問(wèn)日志進(jìn)行分析時(shí)悦荒,這里我們只需要先將這些日志合并唯欣,再進(jìn)行分析即可。使用這種方案來(lái)記錄日志的一個(gè)好處時(shí)搬味,進(jìn)程操作排隊(duì)的可能性比較小境氢,可以使進(jìn)程很迅速的完成每一次操作。
- 將所有要操作的進(jìn)程放入一個(gè)隊(duì)列中碰纬。
- 隊(duì)列中的每一個(gè)排除的進(jìn)程相當(dāng)于第一個(gè)具體的操作萍聊,所以第一次我們的服務(wù)只需要從隊(duì)列中取得相當(dāng)于具體操作事項(xiàng)就可以了,如果這里還有大量的文件操作進(jìn)程悦析,沒(méi)關(guān)系寿桨,排到我們的隊(duì)列后面即可,只要愿意排强戴,隊(duì)列的多長(zhǎng)都沒(méi)關(guān)系亭螟。
框架方面
tp框架
優(yōu)點(diǎn)
TP框架是我們中國(guó)人自己開(kāi)發(fā)的框架,各種資料比較齊全,國(guó)內(nèi)用的比較多,比較簡(jiǎn)單
和方便,而且是免費(fèi)開(kāi)源的
特性
- 多表查詢(xún)非常方便,在 model 中幾句代碼就可以完成對(duì)多表的關(guān)聯(lián)操作
- 融合了 smarty 模板,使前后臺(tái)分離
- 支持多種緩存技術(shù),尤其對(duì) memcache 技術(shù)支持非常好
- 命名規(guī)范,模型,視圖,控制器嚴(yán)格遵循命名規(guī)則,通過(guò)命名一一對(duì)應(yīng)
- 支持多種 url 模式
- 內(nèi)置 ajax 返回方法,包括 xml,json,html 等
- 支持應(yīng)用擴(kuò)展,類(lèi)庫(kù)擴(kuò)展,驅(qū)動(dòng)擴(kuò)展
大寫(xiě)字母
U:對(duì) url 的組裝 A:內(nèi)部實(shí)例化控制器 S:緩存處理 R:調(diào)用某個(gè)控制器的操作方法 D:實(shí)例化
自定義模型類(lèi) M:實(shí)例化基礎(chǔ)模型類(lèi) I:獲取參數(shù) L:設(shè)置或者獲取當(dāng)前語(yǔ)言 C:設(shè)置或獲取,
保存配置
laravel框架
簡(jiǎn)介
laravel框架的設(shè)計(jì)思想比較先進(jìn),非常適合應(yīng)用各種開(kāi)發(fā)模式,作為一個(gè)框架,它為你
準(zhǔn)備好了一切,composer是php的未來(lái),沒(méi)有 composer,php肯定要走向沒(méi)落
laravel框架最大的特點(diǎn)和優(yōu)秀之處就是集合了php比較新的特點(diǎn),以及各種各樣的設(shè)計(jì)
模式,Ioc模式,依賴(lài)注入等.
特點(diǎn)
1.強(qiáng)大的rest router:用簡(jiǎn)單的回調(diào)函數(shù)就可以調(diào)用,快速綁定controller和router
2.artisan:命令行工具,很多手動(dòng)的工作都自動(dòng)化
3.可繼承的模板,簡(jiǎn)化 view的開(kāi)發(fā)和管理
4.blade模板:渲染速度更快
5.ORM操作數(shù)據(jù)庫(kù)
6.migration:管理數(shù)據(jù)庫(kù)和版本控制
7.測(cè)試功能也很強(qiáng)大
8.composer也是亮點(diǎn)
laravel框架引入了門(mén)面,依賴(lài)注入,Ioc模式,以及各種各樣的設(shè)計(jì)模式等
composer
簡(jiǎn)介
composer依賴(lài)管理工具,且實(shí)現(xiàn)了自動(dòng)加載骑歹。開(kāi)發(fā)人員只需要幾個(gè)命令行预烙,就能獲取其他開(kāi)發(fā)者的包,PHP開(kāi)發(fā)工作因此變得如同堆積木道媚,可以根據(jù)業(yè)務(wù)的需求扁掸,快速方便地拆解組合代碼。它不是一個(gè)包管理器最域。是的谴分,它涉及 "packages" 和 "libraries",但它在每個(gè)項(xiàng)目的基礎(chǔ)上進(jìn)行管理羡宙,在你項(xiàng)目的某個(gè)目錄中(例如 vendor)進(jìn)行安裝狸剃。默認(rèn)情況下它不會(huì)在全局安裝任何東西。因此狗热,這僅僅是一個(gè)依賴(lài)管理钞馁。
命令
- composer install 依據(jù)當(dāng)前目錄下的 composer.lock(鎖文件) 或 composer.json 文件虑省,所定義的依賴(lài)關(guān)系,安裝依賴(lài)包僧凰。
- composer update 更新依賴(lài)版本探颈,如果你修改了 composer.json 中的依賴(lài)關(guān)系,想讓 composer 按照composer.json 文件中的定義執(zhí)行更新操作训措,就用 update 命令伪节。
- composer require require 命令一般用來(lái)安裝新的依賴(lài)包,并將依賴(lài)寫(xiě)入當(dāng)前目錄的 composer.json 文件中绩鸣。如果 composer.json 文件中怀大,添加或改變了依賴(lài),修改后的依賴(lài)關(guān)系將被安裝或者更新呀闻。
- create-project 你可以使用 create-project 從現(xiàn)有的包中創(chuàng)建一個(gè)新的項(xiàng)目化借。它相當(dāng)于執(zhí)行了 git clone 命令后,將這個(gè)包的依賴(lài)安裝到它自己的 vendor 目錄捡多。
設(shè)計(jì)模式
創(chuàng)建型
在軟件工程中厢洞,創(chuàng)建型設(shè)計(jì)模式是處理對(duì)象創(chuàng)建機(jī)制的設(shè)計(jì)模式寿谴,試圖以適當(dāng)?shù)姆绞絹?lái)創(chuàng)建對(duì)象。對(duì)象創(chuàng)建的基本形式可能會(huì)帶來(lái)設(shè)計(jì)問(wèn)題,亦或增加了設(shè)計(jì)的復(fù)雜度迂尝。創(chuàng)建型設(shè)計(jì)模式通過(guò)控制這個(gè)對(duì)象的創(chuàng)建方式來(lái)解決此問(wèn)題灸异。
抽象工廠(chǎng)模式
在不指定具體類(lèi)的情況下創(chuàng)建一系列相關(guān)或依賴(lài)對(duì)象衷敌。 通常創(chuàng)建的類(lèi)都實(shí)現(xiàn)相同的接口武翎。 抽象工廠(chǎng)的客戶(hù)并不關(guān)心這些對(duì)象是如何創(chuàng)建的,它只是知道它們是如何一起運(yùn)行的榜掌。
建造者模式
- 建造者是創(chuàng)建一個(gè)復(fù)雜對(duì)象的一部分接口鸭丛。
- 有時(shí)候,如果建造者對(duì)他所創(chuàng)建的東西擁有較好的知識(shí)儲(chǔ)備唐责,這個(gè)接口就可能成為一個(gè)有默認(rèn)方法的抽象類(lèi)(又稱(chēng)為適配器)鳞溉。
- 如果對(duì)象有復(fù)雜的繼承樹(shù),那么對(duì)于建造者來(lái)說(shuō)鼠哥,有一個(gè)復(fù)雜繼承樹(shù)也是符合邏輯的熟菲。
- 注意:建造者通常有一個(gè)「流式接口」,例如 PHPUnit 模擬生成器朴恳。
工廠(chǎng)方法模式
- 對(duì)比簡(jiǎn)單工廠(chǎng)模式的優(yōu)點(diǎn)是抄罕,您可以將其子類(lèi)用不同的方法來(lái)創(chuàng)建一個(gè)對(duì)象。
- 舉一個(gè)簡(jiǎn)單的例子于颖,這個(gè)抽象類(lèi)可能只是一個(gè)接口呆贿。
- 這種模式是「真正」的設(shè)計(jì)模式, 因?yàn)樗麑?shí)現(xiàn)了 S.O.L.I.D 原則中「D」的 「依賴(lài)倒置」。
- 這意味著工廠(chǎng)方法模式取決于抽象類(lèi)做入,而不是具體的類(lèi)冒晰。 這是與簡(jiǎn)單工廠(chǎng)模式和靜態(tài)工廠(chǎng)模式相比的優(yōu)勢(shì)。
多例模式
- 多例模式被公認(rèn)為是 反面模式竟块,獲得更好的可測(cè)試性和可維護(hù)性壶运,使用『依賴(lài)注入模式』。
- 多例模式是指存在一個(gè)類(lèi)有多個(gè)相同實(shí)例浪秘,而且該實(shí)例都是該類(lèi)本身蒋情。這個(gè)類(lèi)叫做多例類(lèi)。 多例模式的特點(diǎn)是:
- 多例類(lèi)可以有多個(gè)實(shí)例耸携。
- 多例類(lèi)必須自己創(chuàng)建棵癣、管理自己的實(shí)例夺衍,并向外界提供自己的實(shí)例浙巫。
- 多例模式實(shí)際上就是單例模式的推廣。
對(duì)象池模式
- 對(duì)象池模式是一種提前準(zhǔn)備了一組已經(jīng)初始化了的對(duì)象『池』而不是按需創(chuàng)建或者銷(xiāo)毀的創(chuàng)建型設(shè)計(jì)模式刷后。對(duì)象池的客戶(hù)端會(huì)向?qū)ο蟪刂姓?qǐng)求一個(gè)對(duì)象,然后使用這個(gè)返回的對(duì)象執(zhí)行相關(guān)操作渊抄。當(dāng)客戶(hù)端使用完畢尝胆,它將把這個(gè)特定類(lèi)型的工廠(chǎng)對(duì)象返回給對(duì)象池,而不是銷(xiāo)毀掉這個(gè)對(duì)象护桦。
- 在初始化實(shí)例成本高含衔,實(shí)例化率高,可用實(shí)例不足的情況下二庵,對(duì)象池可以極大地提升性能贪染。在創(chuàng)建對(duì)象(尤其是通過(guò)網(wǎng)絡(luò))時(shí)間花銷(xiāo)不確定的情況下,通過(guò)對(duì)象池在可期時(shí)間內(nèi)就可以獲得所需的對(duì)象催享。
- 無(wú)論如何杭隙,對(duì)象池模式在需要耗時(shí)創(chuàng)建對(duì)象方面,例如創(chuàng)建數(shù)據(jù)庫(kù)連接因妙,套接字連接痰憎,線(xiàn)程和大型圖形對(duì)象(比方字體或位圖等),使用起來(lái)都是大有裨益的攀涵。在某些情況下铣耘,簡(jiǎn)單的對(duì)象池(無(wú)外部資源,只占內(nèi)存)可能效率不高以故,甚至?xí)袚p性能蜗细。
原型模式
相比正常創(chuàng)建一個(gè)對(duì)象 (new Foo () ),首先創(chuàng)建一個(gè)原型怒详,然后克隆它會(huì)更節(jié)省開(kāi)銷(xiāo)炉媒。
簡(jiǎn)單工廠(chǎng)模式
- 簡(jiǎn)單工廠(chǎng)模式是一個(gè)精簡(jiǎn)版的工廠(chǎng)模式踪区。
- 它與靜態(tài)工廠(chǎng)模式最大的區(qū)別是它不是『靜態(tài)』的。因?yàn)榉庆o態(tài)橱野,所以你可以擁有多個(gè)不同參數(shù)的工廠(chǎng)朽缴,你可以為其創(chuàng)建子類(lèi)。甚至可以模擬(Mock)他水援,這對(duì)編寫(xiě)可測(cè)試的代碼來(lái)講至關(guān)重要密强。
單例模式
單例模式被公認(rèn)為是 反面模式,為了獲得更好的可測(cè)試性和可維護(hù)性蜗元,請(qǐng)使用『依賴(lài)注入模式』或渤。主要為了在應(yīng)用程序調(diào)用的時(shí)候,只能獲得一個(gè)對(duì)象實(shí)例奕扣。主要包括:數(shù)據(jù)庫(kù)的連接薪鹦,日志的使用等。
靜態(tài)工廠(chǎng)模式
與抽象工廠(chǎng)模式類(lèi)似惯豆,此模式用于創(chuàng)建一系列相關(guān)或相互依賴(lài)的對(duì)象池磁。 『靜態(tài)工廠(chǎng)模式』與『抽象工廠(chǎng)模式』的區(qū)別在于,只使用一個(gè)靜態(tài)方法來(lái)創(chuàng)建所有類(lèi)型對(duì)象楷兽, 此方法通常被命名為
factory
或build
地熄。
結(jié)構(gòu)型
在軟件工程中,結(jié)構(gòu)型設(shè)計(jì)模式是通過(guò)識(shí)別實(shí)體之間關(guān)系來(lái)簡(jiǎn)化設(shè)計(jì)的設(shè)計(jì)模式芯杀。
行為型
在軟件工程中端考,行為設(shè)計(jì)模式是識(shí)別對(duì)象之間的通用通信模式并實(shí)現(xiàn)這些模式的設(shè)計(jì)模式。 通過(guò)這樣做揭厚,這些模式增加了執(zhí)行此通信的靈活性却特。
生命周期
php的生命周期
- 模塊初始化階段(Module init):即調(diào)用每個(gè)拓展源碼中的的PHP_MINIT_FUNCTION中的方法初始化模塊,進(jìn)行一些模塊所需變量的申請(qǐng),內(nèi)存分配等。
- 請(qǐng)求初始化階段(Request init):即接受到客戶(hù)端的請(qǐng)求后調(diào)用每個(gè)拓展的PHP_RINIT_FUNCTION中的方法,初始化PHP腳本的執(zhí)行環(huán)境筛圆。
- 執(zhí)行該P(yáng)HP腳本裂明。
- 請(qǐng)求結(jié)束(Request Shutdown):這時(shí)候調(diào)用每個(gè)拓展的PHP_RSHUTDOWN_FUNCTION方法清理請(qǐng)求現(xiàn)場(chǎng),并且ZE開(kāi)始回收變量和內(nèi)存
- 關(guān)閉模塊(Module shutdown):Web服務(wù)器退出或者命令行腳本執(zhí)行完畢退出會(huì)調(diào)用拓展源碼中的PHP_MSHUTDOWN_FUNCTION 方法
laravel的生命周期
- 加載項(xiàng)目依賴(lài),注冊(cè)加載composer自動(dòng)生成的class loader太援,也就是加載初始化第三方依賴(lài)漾岳。
- 創(chuàng)建應(yīng)用實(shí)例,生成容器 Container粉寞,并向容器注冊(cè)核心組件尼荆,是從 bootstrap/app.php 腳本獲取 Laravel 應(yīng)用實(shí)例,并且綁定內(nèi)核服務(wù)容器唧垦,它是HTTP 請(qǐng)求的運(yùn)行環(huán)境的不同捅儒,將請(qǐng)求發(fā)送至相應(yīng)的內(nèi)核: HTTP 內(nèi)核 或 Console 內(nèi)核。
- 接收請(qǐng)求并響應(yīng),請(qǐng)求被發(fā)送到 HTTP 內(nèi)核或 Console 內(nèi)核巧还,這取決于進(jìn)入應(yīng)用的請(qǐng)求類(lèi)型鞭莽。HTTP 內(nèi)核繼承自 Illuminate\Foundation\Http\Kernel 類(lèi),該類(lèi)定義了一個(gè) bootstrappers 數(shù)組麸祷,這個(gè)數(shù)組中的類(lèi)在請(qǐng)求被執(zhí)行前運(yùn)行澎怒,這些 bootstrappers 配置了錯(cuò)誤處理、日志阶牍、檢測(cè)應(yīng)用環(huán)境以及其它在請(qǐng)求被處理前需要執(zhí)行的任務(wù)喷面。HTTP 內(nèi)核還定義了一系列所有請(qǐng)求在處理前需要經(jīng)過(guò)的 HTTP 中間件,這些中間件處理 HTTP 會(huì)話(huà)的讀寫(xiě)走孽、判斷應(yīng)用是否處于維護(hù)模式惧辈、驗(yàn)證 CSRF 令牌等等。
- 發(fā)送請(qǐng)求磕瓷,在Laravel基礎(chǔ)的服務(wù)啟動(dòng)之后盒齿,把請(qǐng)求傳遞給路由了。路由器將會(huì)分發(fā)請(qǐng)求到路由或控制器困食,同時(shí)運(yùn)行所有路由指定的中間件边翁。傳遞給路由是通過(guò) Pipeline(管道)來(lái)傳遞的,在傳遞給路由之前所有請(qǐng)求都要經(jīng)過(guò)app\Http\Kernel.php中的$middleware數(shù)組硕盹,也就是中間件符匾,默認(rèn)只有一個(gè)全局中間件,用來(lái)檢測(cè)你的網(wǎng)站是否暫時(shí)關(guān)閉莱睁。所有請(qǐng)求都要經(jīng)過(guò),你也可以添加自己的全局中間件芒澜。然后遍歷所有注冊(cè)的路由仰剿,找到最先符合的第一個(gè)路由,經(jīng)過(guò)它的路由中間件痴晦,進(jìn)入到控制器或者閉包函數(shù)南吮,執(zhí)行你的具體邏輯代碼,把那些不符合或者惡意的的請(qǐng)求已被Laravel隔離在外誊酌。
基礎(chǔ)組件 - 日志
- Laravel 提供了強(qiáng)大的日志服務(wù)來(lái)記錄日志信息到文件部凑、系統(tǒng)錯(cuò)誤日志、甚至是 Slack 以便通知整個(gè)團(tuán)隊(duì)碧浊。在日志引擎之下涂邀,Laravel 集成了 Monolog 日志庫(kù)以便提供各種功能強(qiáng)大的日志處理器,從而允許你通過(guò)它們來(lái)定制自己應(yīng)用的日志處理箱锐。
- 應(yīng)用日志系統(tǒng)的所有配置都存放在配置文件
config/logging.php
中比勉,該文件允許你配置應(yīng)用的日志通道,因此需要查看每個(gè)可用通道及其配置項(xiàng),默認(rèn)情況下浩聋,Laravel 使用 stack 通道來(lái)記錄日志信息观蜗,stack 通道被用于聚合多個(gè)日志通道到單個(gè)通道
配置通道名稱(chēng)
默認(rèn)情況下,Monolog 通過(guò)與當(dāng)前環(huán)境匹配的「通道名稱(chēng)」實(shí)例化衣洁,例如
production
或local
墓捻,要改變這個(gè)值,添加name
項(xiàng)到通道配置
有效通道驅(qū)動(dòng)列表
stack
用于創(chuàng)建「多通道」通道的聚合器single
基于單文件/路徑的日志通道(StreamHandler
)daily
基于RotatingFileHandler
的 Monolog 驅(qū)動(dòng)坊夫,以天為維度對(duì)日志進(jìn)行分隔slack
基于SlackWebhookHandler
的 Monolog 驅(qū)動(dòng)syslog
基于SyslogHandler
的 Monolog 驅(qū)動(dòng)errorlog
基于ErrorLogHandler
的 Monolog 驅(qū)動(dòng)monolog
Monolog 改成驅(qū)動(dòng)砖第,可以使用所有支持的 Monolog 處理器custom
調(diào)用指定改成創(chuàng)建通道的驅(qū)動(dòng)
配置 Single 和 Daily 通道
single
和daily
通道有三個(gè)可選配置項(xiàng):bubble
、permission
和locking
践樱。bubble
表示消息在被處理后是否冒泡到其它通道 厂画,默認(rèn)為true
permission
日志文件權(quán)限,默認(rèn)為644
locking
在日志文件寫(xiě)入前嘗試鎖定它拷邢,默認(rèn)為false
配置 Slack 通道
slack
通道需要一個(gè) url
配置項(xiàng)袱院,這個(gè) URL 需要和你配置的 Slack 團(tuán)隊(duì)[請(qǐng)求 URL]相匹配。
構(gòu)建日志堆棧
stack
驅(qū)動(dòng)允許你將多個(gè)通道合并到單個(gè)日志通道,stack 通道通過(guò) channels 項(xiàng)將聚合了其他兩個(gè)通道:syslog 和 slack瞭稼。因此忽洛,記錄日志信息時(shí),這兩個(gè)通道都有機(jī)會(huì)記錄信息环肘。
參考鏈接:https://laravelacademy.org/post/19467.html
面向?qū)ο髈op
是什么
oop是面向?qū)ο缶幊?面向?qū)ο缶幊淌且环N計(jì)算機(jī)編程架構(gòu),OOP 的一條基本原則是
計(jì)算機(jī)程序是由單個(gè)能夠起到子程序作用的單元或?qū)ο蠼M合而成欲虚。
**三大特點(diǎn) **
1、封裝性:也稱(chēng)為信息隱藏悔雹,就是將一個(gè)類(lèi)的使用和實(shí)現(xiàn)分開(kāi)复哆,只保留部分接口和方
法與外部聯(lián)系,或者說(shuō)只公開(kāi)了一些供開(kāi)發(fā)人員使用的方法腌零。于是開(kāi)發(fā)人員只 需要關(guān)
注這個(gè)類(lèi)如何使用梯找,而不用去關(guān)心其具體的實(shí)現(xiàn)過(guò)程,這樣就能實(shí)現(xiàn)MVC分工合作益涧,
也能有效避免程序間相互依賴(lài)锈锤,實(shí)現(xiàn)代碼模塊間松藕合。
2闲询、繼承性:就是子類(lèi)自動(dòng)繼承其父級(jí)類(lèi)中的屬性和方法久免,并可以添加新的屬性和方法
或者對(duì)部分屬性和方法進(jìn)行重寫(xiě)。繼承增加了代碼的可重用性扭弧。PHP只支持單繼承阎姥,也
就是說(shuō)一個(gè)子類(lèi)只能有一個(gè)父類(lèi)。
3鸽捻、多態(tài)性:子類(lèi)繼承了來(lái)自父級(jí)類(lèi)中的屬性和方法丁寄,并對(duì)其中部分方法進(jìn)行重寫(xiě)氨淌。于
是多個(gè)子類(lèi)中雖然都具有同一個(gè)方法,但是這些子類(lèi)實(shí)例化的對(duì)象調(diào)用這些相同的方法
后卻可以獲得完全不同的結(jié)果伊磺,這種技術(shù)就是多態(tài)性盛正。多態(tài)性增強(qiáng)了軟件的靈活性。
設(shè)計(jì)模式的五大原則
- 單一職責(zé)原則 單一職責(zé)原則可以看做是低耦合屑埋、高內(nèi)聚在面向?qū)ο笤瓌t上的引申豪筝,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性來(lái)減少引起變化的原因
- 開(kāi)發(fā)封閉原則 開(kāi)放-封閉原則是面向?qū)ο笤O(shè)計(jì)的核心所在摘能。遵循這個(gè)原則可以帶來(lái)面向?qū)ο蠹夹g(shù)所聲稱(chēng)的巨大好處续崖,也就是可維護(hù),可擴(kuò)展团搞,可復(fù)用严望,靈活性好。
- 接口隔離原則 通俗點(diǎn)說(shuō)逻恐,不要強(qiáng)迫客戶(hù)使用它們不用的方法像吻,如果強(qiáng)迫用戶(hù)使用它們不使用的方法,那么這些客戶(hù)就會(huì)面臨由于這些不使用的方法的改變所帶來(lái)的改變复隆。
- 依賴(lài)倒置原則 依賴(lài)倒置原則其實(shí)可以說(shuō)是面向?qū)ο笤O(shè)計(jì)的標(biāo)志拨匆,用哪種語(yǔ)言來(lái)編寫(xiě)程序不重要,如果編寫(xiě)時(shí)考慮的都是如何針對(duì)抽象編程而不是針對(duì)細(xì)節(jié)編程挽拂,即程序中所有的依賴(lài)關(guān)系都是終止于抽象類(lèi)或者接口惭每,那就是面向?qū)ο蟮脑O(shè)計(jì),反之那就是過(guò)程化的設(shè)計(jì)了亏栈。
- 里氏替換原則 任何基類(lèi)可以出現(xiàn)的地方台腥,子類(lèi)一定可以出現(xiàn)。 LSP是繼承復(fù)用的基石绒北,只有當(dāng)衍生類(lèi)可以替換掉基類(lèi)黎侈,軟件單位的功能不受到影響時(shí),基類(lèi)才能真正被復(fù)用镇饮,而衍生類(lèi)也能夠在基類(lèi)的基礎(chǔ)上增加新的行為蜓竹。里氏代換原則是對(duì)“開(kāi)-閉”原則的補(bǔ)充箕母。實(shí)現(xiàn)“開(kāi)-閉”原則的關(guān)鍵步驟就是抽象化储藐。而基類(lèi)與子類(lèi)的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范嘶是。
好處
1钙勃、易維護(hù) 采用面向?qū)ο笏枷朐O(shè)計(jì)的結(jié)構(gòu),可讀性高聂喇,由于繼承的存在辖源,即使改變需求蔚携,那么維護(hù)
也只是在局部模塊,所以維護(hù)起來(lái)是非常方便和較低成本的克饶。
2酝蜒、質(zhì)量高 在設(shè)計(jì)時(shí),可重用現(xiàn)有的矾湃,在以前的項(xiàng)目的領(lǐng)域中已被測(cè)試過(guò)的類(lèi)使系統(tǒng)滿(mǎn)足業(yè)務(wù)需求
并具有較高的質(zhì)量亡脑。
3、效率高 在軟件開(kāi)發(fā)時(shí)邀跃,根據(jù)設(shè)計(jì)的需要對(duì)現(xiàn)實(shí)世界的事物進(jìn)行抽象霉咨,產(chǎn)生類(lèi)。使用這樣的方法
解決問(wèn)題拍屑,接近于日常生活和自然的思考方式途戒,勢(shì)必提高軟件開(kāi)發(fā)的效率和質(zhì)量。
4僵驰、易擴(kuò)展 由于繼承喷斋、封裝、多態(tài)的特性矢渊,自然設(shè)計(jì)出高內(nèi)聚继准、低耦合的系統(tǒng)結(jié)構(gòu),使得系統(tǒng)更靈
活矮男、更容易擴(kuò)展移必,而且成本較低。
smarty
- smarty是用php寫(xiě)出來(lái)的模板引擎,也是目前業(yè)界最著名的php模板引擎之一 ,它分離了邏輯代碼和外在的顯示,提供了一種易于管理和使用的方法,用來(lái)將混雜的php
- 邏輯代碼與html代碼進(jìn)行分離,smarty是php中最著名的引擎框架之一,我們公司使用的是TP框架,已經(jīng)封裝好了smarty模板,所以沒(méi)有單獨(dú)使用過(guò)
- smarty是個(gè)模板引擎毡鉴,最顯著的地方就是有可以把模板緩存起來(lái)崔泵。一般模板來(lái)說(shuō),都是做一個(gè)靜態(tài)頁(yè)面猪瞬,然后在里面把一些動(dòng)態(tài)的部分用一切分隔符切開(kāi)憎瘸,然后在PHP里打開(kāi)這個(gè)模板文件,把分隔符里面的值替換掉陈瘦,然后輸出來(lái)幌甘,你可以看下PHPLib里面的template部分。
而smarty設(shè)定了緩存參數(shù)以后痊项,第一次運(yùn)行時(shí)候會(huì)把模板打開(kāi)锅风,在php替換里面值的
時(shí)候把讀取的html和php部分重新生成一個(gè)臨時(shí)的php文件,這樣就省去了每次打
開(kāi)都重新讀取html了鞍泉。如果修改了模板皱埠,只要重新刷下就行了。
socket咖驮,tcp边器,http三者之間的區(qū)別和原理
不同的TCP/IP和其他的協(xié)議在最初OSI模型中的位置
- | 7 | 應(yīng)用層 :HTTP训枢、SMTP、SNMP忘巧、FTP恒界、Telnet、SIP砚嘴、SSH仗处、NFS、RTSP枣宫、XMPP婆誓、Whois、ENRP
- | 6 | 表示層:XDR也颤、ASN.1洋幻、SMB、AFP翅娶、NCP
- | 5 | 會(huì)話(huà)層 :ASAP文留、TLS、SSH竭沫、ISO 8327 / CCITT X.225燥翅、RPC、NetBIOS蜕提、ASP森书、Winsock、BSD sockets
- | 4 | 傳輸層 :TCP谎势、UDP凛膏、RTP、SCTP脏榆、SPX猖毫、ATP、IL
- | 3 | 網(wǎng)絡(luò)層 : IP须喂、ICMP吁断、IGMP、IPX坞生、BGP仔役、OSPF、RIP恨胚、IGRP骂因、EIGRP炎咖、ARP赃泡、RARP寒波、 X.25
- | 2 | 數(shù)據(jù)鏈路層 :以太網(wǎng)、令牌環(huán)升熊、HDLC俄烁、幀中繼绰精、ISDN璃氢、ATM、IEEE 802.11特幔、FDDI蓖柔、PPP
- | 1 | 物理層 :線(xiàn)路辰企、無(wú)線(xiàn)電、光纖况鸣、信鴿
1牢贸、TCP/IP連接
TCP協(xié)議可以對(duì)上層網(wǎng)絡(luò)提供接口,使上層網(wǎng)絡(luò)數(shù)據(jù)的傳輸建立在“無(wú)差別”的網(wǎng)絡(luò)之上镐捧。
- 建立起一個(gè)TCP連接需要經(jīng)過(guò)三次握手
- 第一次握手:客戶(hù)端發(fā)送syn包(syn=j)到服務(wù)器潜索,并進(jìn)入SYN_SEND狀態(tài),等待服務(wù)器確認(rèn)懂酱;
- 第二次握手:服務(wù)器收到syn包竹习,必須確認(rèn)客戶(hù)的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k)列牺,即SYN+ACK包整陌,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
- 第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK包瞎领,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1)蔓榄,此包發(fā)送完畢,客戶(hù)端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài)默刚,完成三次握手
- 握手過(guò)程中傳送的包里不包含數(shù)據(jù)甥郑,三次握手完畢后,客戶(hù)端與服務(wù)器才正式開(kāi)始傳送數(shù)據(jù)荤西。理想狀態(tài)下澜搅,TCP連接一旦建立,在通信雙方中的任何一方主動(dòng)關(guān)閉連接之前邪锌,TCP連接都將被一直保持下去勉躺。斷開(kāi)連接時(shí)服務(wù)器和客戶(hù)端均可以主動(dòng)發(fā)起斷開(kāi)TCP連接的請(qǐng)求,斷開(kāi)過(guò)程需要經(jīng)過(guò)“四次握手”(過(guò)程就不細(xì)寫(xiě)了觅丰,就是服務(wù)器和客戶(hù)端交互饵溅,最終確定斷開(kāi)).
2、HTTP連接
HTTP協(xié)議即超文本傳送協(xié)議(Hypertext Transfer Protocol )妇萄,是Web聯(lián)網(wǎng)的基礎(chǔ)蜕企,也是手機(jī)聯(lián)網(wǎng)常用的協(xié)議之一咬荷,HTTP協(xié)議是建立在TCP協(xié)議之上的一種應(yīng)用。
- HTTP連接最顯著的特點(diǎn)是客戶(hù)端發(fā)送的每次請(qǐng)求都需要服務(wù)器回送響應(yīng)轻掩,在請(qǐng)求結(jié)束后幸乒,會(huì)主動(dòng)釋放連接。從建立連接到關(guān)閉連接的過(guò)程稱(chēng)為“一次連接”唇牧。
- 1)在HTTP 1.0中罕扎,客戶(hù)端的每次請(qǐng)求都要求建立一次單獨(dú)的連接,在處理完本次請(qǐng)求后丐重,就自動(dòng)釋放連接腔召。
- 2)在HTTP 1.1中則可以在一次連接中處理多個(gè)請(qǐng)求,并且多個(gè)請(qǐng)求可以重疊進(jìn)行扮惦,不需要等待一個(gè)請(qǐng)求結(jié)束后再發(fā)送下一個(gè)請(qǐng)求宴咧。
- 由于HTTP在每次請(qǐng)求結(jié)束后都會(huì)主動(dòng)釋放連接,因此HTTP連接是一種“短連接”径缅,要保持客戶(hù)端程序的在線(xiàn)狀態(tài)掺栅,需要不斷地向服務(wù)器發(fā)起連接請(qǐng)求。通常的做法是即時(shí)不需要獲得任何數(shù)據(jù)纳猪,客戶(hù)端也保持每隔一段固定的時(shí)間向服務(wù)器發(fā)送一次“保持連接”的請(qǐng)求氧卧,服務(wù)器在收到該請(qǐng)求后對(duì)客戶(hù)端進(jìn)行回復(fù),表明知道客戶(hù)端“在線(xiàn)”氏堤。若服務(wù)器長(zhǎng)時(shí)間無(wú)法收到客戶(hù)端的請(qǐng)求沙绝,則認(rèn)為客戶(hù)端“下線(xiàn)”,若客戶(hù)端長(zhǎng)時(shí)間無(wú)法收到服務(wù)器的回復(fù)鼠锈,則認(rèn)為網(wǎng)絡(luò)已經(jīng)斷開(kāi)闪檬。
3、SOCKET原理
套接字(socket)概念
- 套接字(socket)是通信的基石购笆,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元粗悯。它是網(wǎng)絡(luò)通信過(guò)程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議同欠,本地主機(jī)的IP地址样傍,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址铺遂,遠(yuǎn)地進(jìn)程的協(xié)議端口衫哥。
- 應(yīng)用層通過(guò)傳輸層進(jìn)行數(shù)據(jù)通信時(shí),TCP會(huì)遇到同時(shí)為多個(gè)應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問(wèn)題襟锐。多個(gè)TCP連接或多個(gè)應(yīng)用程序進(jìn)程可能需要通過(guò)同一個(gè)TCP協(xié)議端口傳輸數(shù)據(jù)撤逢。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng)用層可以和傳輸層通過(guò)Socket接口蚊荣,區(qū)分來(lái)自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信初狰,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。
建立socket連接
- 建立Socket連接至少需要一對(duì)套接字妇押,其中一個(gè)運(yùn)行于客戶(hù)端,稱(chēng)為ClientSocket 姓迅,另一個(gè)運(yùn)行于服務(wù)器端敲霍,稱(chēng)為ServerSocket 。
- 套接字之間的連接過(guò)程分為三個(gè)步驟:服務(wù)器監(jiān)聽(tīng)丁存,客戶(hù)端請(qǐng)求肩杈,連接確認(rèn)。
- 服務(wù)器監(jiān)聽(tīng):服務(wù)器端套接字并不定位具體的客戶(hù)端套接字解寝,而是處于等待連接的狀態(tài)扩然,實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶(hù)端的連接請(qǐng)求聋伦。
- 客戶(hù)端請(qǐng)求:指客戶(hù)端的套接字提出連接請(qǐng)求夫偶,要連接的目標(biāo)是服務(wù)器端的套接字。為此觉增,客戶(hù)端的套接字必須首先描述它要連接的服務(wù)器的套接字兵拢,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請(qǐng)求逾礁。
- 連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽(tīng)到或者說(shuō)接收到客戶(hù)端套接字的連接請(qǐng)求時(shí)说铃,就響應(yīng)客戶(hù)端套接字的請(qǐng)求,建立一個(gè)新的線(xiàn)程嘹履,把服務(wù)器端套接字的描述發(fā)給客戶(hù)端腻扇,一旦客戶(hù)端確認(rèn)了此描述,雙方就正式建立連接砾嫉。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽(tīng)狀態(tài)幼苛,繼續(xù)接收其他客戶(hù)端套接字的連接請(qǐng)求。
4焕刮、SOCKET連接與TCP/IP連接
- 建Socket連接時(shí)蚓峦,可以指定使用的傳輸層協(xié)議,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP)济锄,當(dāng)使用TCP協(xié)議進(jìn)行連接時(shí)暑椰,該Socket連接就是一個(gè)TCP連接。
- socket則是對(duì)TCP/IP協(xié)議的封裝和應(yīng)用(程序員層面上)荐绝。也可以說(shuō)一汽,TPC/IP協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù) 如何在網(wǎng)絡(luò)中傳輸,而HTTP是應(yīng)用層協(xié)議召夹,主要解決如何包裝數(shù)據(jù)岩喷。關(guān)于TCP/IP和HTTP協(xié)議的關(guān)系,網(wǎng)絡(luò)有一段比較容易理解的介紹:
- “我們?cè)趥鬏敂?shù)據(jù)時(shí)监憎,可以只使用(傳輸層)TCP/IP協(xié)議纱意,但是那樣的話(huà),如果沒(méi)有應(yīng)用層鲸阔,便無(wú)法識(shí)別數(shù)據(jù)內(nèi)容偷霉,如果想要使傳輸?shù)臄?shù)據(jù)有意義,則必須使用到應(yīng)用層協(xié)議有很多褐筛,比如HTTP类少、FTP、TELNET等渔扎,也可以自己定義應(yīng)用層協(xié)議硫狞。WEB使用HTTP協(xié)議作應(yīng)用層協(xié)議,以封裝HTTP文本信息晃痴,然后使用TCP/IP做傳輸層協(xié)議將它發(fā)到網(wǎng)絡(luò)上残吩。”
- 我們平時(shí)說(shuō)的最多的socket是什么呢倘核,實(shí)際上socket是對(duì)TCP/IP協(xié)議的封裝世剖,Socket本身并不是協(xié)議,而是一個(gè)調(diào)用接口(API)笤虫,通過(guò)Socket旁瘫,我們才能使用TCP/IP協(xié)議。 實(shí)際上琼蚯,Socket跟TCP/IP協(xié)議沒(méi)有必然的聯(lián)系酬凳。Socket編程接口在設(shè)計(jì)的時(shí)候,就希望也能適應(yīng)其他的網(wǎng)絡(luò)協(xié)議遭庶。所以說(shuō)宁仔,Socket的出現(xiàn),只是使得程序員更方便地使用而已,是對(duì)TCP/IP協(xié)議的抽象峦睡,從而形成了我們知道的一些最基本的函數(shù)接口翎苫,比如create、listen榨了、connect煎谍、accept、send龙屉、read和write等等呐粘。
- “TCP/IP只是一個(gè)協(xié)議棧满俗,就像操作系統(tǒng)的運(yùn)行機(jī)制一樣,必須要具體實(shí)現(xiàn)作岖,同時(shí)還要提供對(duì)外的操作接口唆垃。這個(gè)就像操作系統(tǒng)會(huì)提供標(biāo)準(zhǔn)的編程接口,比如win32編程接口一樣痘儡,TCP/IP也要提供可供程序員做網(wǎng)絡(luò)開(kāi)發(fā)所用的接口辕万,這就是Socket編程接口〕辽荆”
- 實(shí)際上渐尿,傳輸層的TCP是基于網(wǎng)絡(luò)層的IP協(xié)議的,而應(yīng)用層的HTTP協(xié)議又是基于傳輸層的TCP協(xié)議的丑念,而Socket本身不算是協(xié)議涡戳,就像上面所說(shuō)结蟋,它只是提供了一個(gè)針對(duì)TCP或者UDP編程的接口脯倚。socket是對(duì)端口通信開(kāi)發(fā)的工具,它要更底層一些
5、Socket連接與HTTP連接
- 由于通常情況下Socket連接就是TCP連接嵌屎,因此Socket連接一旦建立推正,通信雙方即可開(kāi)始相互發(fā)送數(shù)據(jù)內(nèi)容,直到雙方連接斷開(kāi)宝惰。但在實(shí)際網(wǎng)絡(luò)應(yīng)用中植榕,客戶(hù)端到服務(wù)器之間的通信往往需要穿越多個(gè)中間節(jié)點(diǎn),例如路由器尼夺、網(wǎng)關(guān)尊残、防火墻等,大部分防火墻默認(rèn)會(huì)關(guān)閉長(zhǎng)時(shí)間處于非活躍狀態(tài)的連接而導(dǎo)致 Socket 連接斷連淤堵,因此需要通過(guò)輪詢(xún)告訴網(wǎng)絡(luò)寝衫,該連接處于活躍狀態(tài)。
- 而HTTP連接使用的是“請(qǐng)求—響應(yīng)”的方式拐邪,不僅在請(qǐng)求時(shí)需要先建立連接慰毅,而且需要客戶(hù)端向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器端才能回復(fù)數(shù)據(jù)扎阶。
- 很多情況下汹胃,需要服務(wù)器端主動(dòng)向客戶(hù)端推送數(shù)據(jù),保持客戶(hù)端與服務(wù)器數(shù)據(jù)的實(shí)時(shí)與同步东臀。此時(shí)若雙方建立的是Socket連接着饥,服務(wù)器就可以直接將數(shù)據(jù)傳送給客戶(hù)端;若雙方建立的是HTTP連接惰赋,則服務(wù)器需要等到客戶(hù)端發(fā)送一次請(qǐng)求后才能將數(shù)據(jù)傳回給客戶(hù)端贱勃,因此,客戶(hù)端定時(shí)向服務(wù)器端發(fā)送連接請(qǐng)求,不僅可以保持在線(xiàn)贵扰,同時(shí)也是在“詢(xún)問(wèn)”服務(wù)器是否有新的數(shù)據(jù)仇穗,如果有就將數(shù)據(jù)傳給客戶(hù)端。
- http協(xié)議是應(yīng)用層的協(xié)義
- 有個(gè)比較形象的描述:HTTP是轎車(chē)戚绕,提供了封裝或者顯示數(shù)據(jù)的具體形式纹坐;Socket是發(fā)動(dòng)機(jī),提供了網(wǎng)絡(luò)通信的能力舞丛。
- 兩個(gè)計(jì)算機(jī)之間的交流無(wú)非是兩個(gè)端口之間的數(shù)據(jù)通信,具體的數(shù)據(jù)會(huì)以什么樣的形式展現(xiàn)是以不同的應(yīng)用層協(xié)議來(lái)定義的如HTTP耘子,F(xiàn)TP...
vue
Vue單頁(yè)網(wǎng)頁(yè)路由
什么是單頁(yè)Web應(yīng)用
單頁(yè)Web應(yīng)用(single page web application,SPA)球切,就是只有一張Web頁(yè)面的應(yīng)用谷誓。單頁(yè)應(yīng)用程序 (SPA) 是加載單個(gè)HTML 頁(yè)面并在用戶(hù)與應(yīng)用程序交互時(shí)動(dòng)態(tài)更新該頁(yè)面的Web應(yīng)用程序。^ [1]^ 瀏覽器一開(kāi)始會(huì)加載必需的HTML吨凑、CSS和JavaScript捍歪,所有的操作都在這張頁(yè)面上完成,都由JavaScript來(lái)控制鸵钝。因此糙臼,對(duì)單頁(yè)應(yīng)用來(lái)說(shuō)模塊化的開(kāi)發(fā)和設(shè)計(jì)顯得相當(dāng)重要。
通常spa前端路由實(shí)現(xiàn)有兩種方式
window.history
- window.history 對(duì)象包含瀏覽器的歷史恩商,window.history 對(duì)象在編寫(xiě)時(shí)可不使用 window 這個(gè)前綴变逃。history是實(shí)現(xiàn)SPA前端路由是一種主流方法,它有幾個(gè)原始方法
- history.back() - 與在瀏覽器點(diǎn)擊后退按鈕相同
- history.forward() - 與在瀏覽器中點(diǎn)擊按鈕向前相同
- history.go(n) - 接受一個(gè)整數(shù)作為參數(shù)怠堪,移動(dòng)到該整數(shù)指定的頁(yè)面揽乱,比如go(1)相當(dāng)于forward(),go(-1)相當(dāng)于back()粟矿,go(0)相當(dāng)于刷新當(dāng)前頁(yè)面
- 注意:如果移動(dòng)的位置超出了訪(fǎng)問(wèn)歷史的邊界凰棉,以上三個(gè)方法并不報(bào)錯(cuò),而是靜默失敗
- 在HTML5嚷炉,history對(duì)象提出了 pushState() 方法和 replaceState() 方法渊啰,這兩個(gè)方法可以用來(lái)向歷史棧中添加數(shù)據(jù),就好像 url 變化了一樣申屹,這樣就可以很好的模擬瀏覽歷史和前進(jìn)后退了绘证,現(xiàn)在的前端路由也是基于這個(gè)原理實(shí)現(xiàn)的
- history.pushState(stateObj, title, url) 方法向歷史棧中寫(xiě)入數(shù)據(jù),其第一個(gè)參數(shù)是要寫(xiě)入的數(shù)據(jù)對(duì)象(不大于640kB)哗讥,第二個(gè)參數(shù)是頁(yè)面的 title, 第三個(gè)參數(shù)是 url (相對(duì)路徑)嚷那。pushState方法不會(huì)觸發(fā)頁(yè)面刷新,只是導(dǎo)致history對(duì)象發(fā)生變化杆煞,地址欄會(huì)有反應(yīng),只有當(dāng)觸發(fā)前進(jìn)后退等事件(back()和forward()等)時(shí)瀏覽器才會(huì)刷新
- history.replaceState(stateObj, title, url) 和pushState的區(qū)別就在于它不是寫(xiě)入而是替換修改瀏覽歷史中當(dāng)前紀(jì)錄魏宽,其余和 pushState一模一樣
location.hash
- hash模式:在瀏覽器中符號(hào)“#”腐泻,#以及#后面的字符稱(chēng)之為hash,用window.location.hash讀榷友派桩;
- 特點(diǎn):hash雖然在URL中,但不被包括在HTTP請(qǐng)求中蚌斩;用來(lái)指導(dǎo)瀏覽器動(dòng)作铆惑,對(duì)服務(wù)端安全無(wú)用,hash不會(huì)重加載頁(yè)面送膳。
- hash 模式下员魏,僅 hash 符號(hào)之前的內(nèi)容會(huì)被包含在請(qǐng)求中,如 [http://www.xxx.com]叠聋,因此對(duì)于后端來(lái)說(shuō)撕阎,即使沒(méi)有做到對(duì)路由的全覆蓋,也不會(huì)返回 404 錯(cuò)誤碌补。
Vue的MVVM模式
- MVVM是Model-View-ViewModel的簡(jiǎn)寫(xiě)虏束。即模型-視圖-視圖模型∧曰郏【模型】指的是后端傳遞的數(shù)據(jù)魄眉∨檠危【視圖】指的是所看到的頁(yè)面闷袒。【視圖模型】mvvm模式的核心岩梳,它是連接view和model的橋梁囊骤。
- 它有兩個(gè)方向:
- 一是將【模型】轉(zhuǎn)化成【視圖】,即將后端傳遞的數(shù)據(jù)轉(zhuǎn)化成所看到的頁(yè)面冀值。實(shí)現(xiàn)的方式是:數(shù)據(jù)綁定也物。
- 二是將【視圖】轉(zhuǎn)化成【模型】,即將所看到的頁(yè)面轉(zhuǎn)化成后端的數(shù)據(jù)列疗。實(shí)現(xiàn)的方式是:DOM 事件監(jiān)聽(tīng)滑蚯。這兩個(gè)方向都實(shí)現(xiàn)的,我們稱(chēng)之為數(shù)據(jù)的雙向綁定抵栈。
- Vue就是基于MVVM模式實(shí)現(xiàn)的一套框架告材,在vue中:Model:指的是js中的數(shù)據(jù),如對(duì)象古劲,數(shù)組等等斥赋。View:指的是頁(yè)面視圖viewModel:指的是vue實(shí)例化對(duì)象
漸進(jìn)式的javascript框架
漸進(jìn)式是什么意思?
- 1.如果你已經(jīng)有一個(gè)現(xiàn)成的服務(wù)端應(yīng)用产艾,你可以將vue 作為該應(yīng)用的一部分嵌入其中疤剑,帶來(lái)更加豐富的交互體驗(yàn);
- 2.如果你希望將更多業(yè)務(wù)邏輯放到前端來(lái)實(shí)現(xiàn)滑绒,那么VUE的核心庫(kù)及其生態(tài)系統(tǒng)也可以滿(mǎn)足你的各式需求(core+vuex+vue-route)。和其它前端框架一樣隘膘,VUE允許你將一個(gè)網(wǎng)頁(yè)分割成可復(fù)用的組件疑故,每個(gè)組件都包含屬于自己的HTML、CSS弯菊、JAVASCRIPT以用來(lái)渲染網(wǎng)頁(yè)中相應(yīng)的地方焰扳。
- 3.如果我們構(gòu)建一個(gè)大型的應(yīng)用,在這一點(diǎn)上误续,我們可能需要將東西分割成為各自的組件和文件吨悍,vue有一個(gè)命令行工具,使快速初始化一個(gè)真實(shí)的工程變得非常簡(jiǎn)單(vue init webpack my-project)蹋嵌。
我們可以使用VUE的單文件組件育瓜,它包含了各自的HTML、JAVASCRIPT以及帶作用域的CSS或SCSS栽烂。以上這三個(gè)例子躏仇,是一步步遞進(jìn)的,也就是說(shuō)對(duì)VUE的使用可大可小腺办,它都會(huì)有相應(yīng)的方式來(lái)整合到你的項(xiàng)目中焰手。所以說(shuō)它是一個(gè)漸進(jìn)式的框架。VUE最獨(dú)特的特性:響應(yīng)式系統(tǒng)VUE是響應(yīng)式的(reactive)怀喉,也就是說(shuō)當(dāng)我們的數(shù)據(jù)變更時(shí)书妻,VUE會(huì)幫你更新所有網(wǎng)頁(yè)中用到它的地方。
Vue雙向綁定
- vue實(shí)現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者訂閱者模式的方式躬拢,通過(guò)Object.defineProperty()來(lái)劫持各個(gè)屬性的setter躲履,getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者聊闯,觸發(fā)相應(yīng)監(jiān)聽(tīng)回調(diào)工猜。當(dāng)把一個(gè)普通 Javascript 對(duì)象傳給 Vue 實(shí)例來(lái)作為它的 data 選項(xiàng)時(shí),Vue 將遍歷它的屬性菱蔬,用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter篷帅。用戶(hù)看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴(lài)拴泌,在屬性被訪(fǎng)問(wèn)和修改時(shí)通知變化魏身。
- vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer弛针,Compile和Watcher三者叠骑,通過(guò)Observer來(lái)監(jiān)聽(tīng)自己的model的數(shù)據(jù)變化,通過(guò)Compile來(lái)解析編譯模板指令(vue中是用來(lái)解析 {{}})削茁,最終利用watcher搭起observer和Compile之間的通信橋梁宙枷,達(dá)到數(shù)據(jù)變化 —>視圖更新掉房;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果。
Vue生命周期
什么是vue生命周期慰丛?
Vue 實(shí)例從創(chuàng)建到銷(xiāo)毀的過(guò)程卓囚,就是生命周期。從開(kāi)始創(chuàng)建诅病、初始化數(shù)據(jù)哪亿、編譯模板、掛載Dom→渲染贤笆、更新→渲染蝇棉、銷(xiāo)毀等一系列過(guò)程,稱(chēng)之為 Vue 的生命周期芥永。
Vue生命周期的作用
它的生命周期中有多個(gè)事件鉤子篡殷,讓我們?cè)诳刂普麄€(gè)Vue實(shí)例的過(guò)程時(shí)更容易形成好的邏輯。
Vue生命周期的過(guò)程
它可以總共分為8個(gè)階段:創(chuàng)建前/后, 載入前/后,更新前/后,銷(xiāo)毀前/銷(xiāo)毀后埋涧。
beforeCreate(創(chuàng)建前) 在數(shù)據(jù)觀(guān)測(cè)和初始化事件還未開(kāi)始
created(創(chuàng)建后) 完成數(shù)據(jù)觀(guān)測(cè)板辽,屬性和方法的運(yùn)算,初始化事件棘催,el 替換摄闸,并掛載到實(shí)例上去之后調(diào)用乡革。實(shí)例已完成以下的配置:用上面編譯好的html內(nèi)容替換el屬性指向的DOM對(duì)象橙凳。完成模板中的html渲染到html頁(yè)面中瓤狐。此過(guò)程中進(jìn)行ajax交互胜宇。
beforeUpdate(更新前) 在數(shù)據(jù)更新之前調(diào)用系洛,發(fā)生在虛擬DOM重新渲染和打補(bǔ)丁之前恩够¢苊耍可以在該鉤子中進(jìn)一步地更改狀態(tài)卷雕,不會(huì)觸發(fā)附加的重渲染過(guò)程兜看。
updated(更新后) 在由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁之后調(diào)用。調(diào)用時(shí)葫哗,組件DOM已經(jīng)更新缔刹,所以可以執(zhí)行依賴(lài)于DOM的操作。然而在大多數(shù)情況下劣针,應(yīng)該避免在此期間更改狀態(tài),因?yàn)檫@可能會(huì)導(dǎo)致更新無(wú)限循環(huán)亿扁。該鉤子在服務(wù)器端渲染期間不被調(diào)用捺典。
beforeDestroy(銷(xiāo)毀前) 在實(shí)例銷(xiāo)毀之前調(diào)用。實(shí)例仍然完全可用从祝。
destroyed(銷(xiāo)毀后) 在實(shí)例銷(xiāo)毀之后調(diào)用襟己。調(diào)用后引谜,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷(xiāo)毀擎浴。該鉤子在服務(wù)器端渲染期間不被調(diào)用员咽。
.第一次頁(yè)面加載會(huì)觸發(fā)哪幾個(gè)鉤子?
會(huì)觸發(fā) 下面這幾個(gè)beforeCreate, created, beforeMount, mounted 贮预。
DOM 渲染在 哪個(gè)周期中就已經(jīng)完成贝室?
DOM 渲染在 mounted 中就已經(jīng)完成了。
Vue三種常用傳值方式
父組件向子組件傳值
- 使用props建立數(shù)據(jù)通道的渠道
- 在子組件中通過(guò)props傳遞過(guò)來(lái)的數(shù)據(jù)
子組件向父組件傳值
- 子組件中需要一個(gè)點(diǎn)擊事件觸發(fā)一個(gè)自定義事件
- 在父組件中的子標(biāo)簽監(jiān)聽(tīng)該自定義事件得到傳遞的值
非父子組件傳值
- 1他們之間有一個(gè)共同的容器仿吞,假設(shè)A和B之間傳值滑频,我們可以用localstoage和SessionStorage把A的數(shù)據(jù)傳給共同的容器,然后B從這個(gè)容器中再把A的數(shù)據(jù)取出來(lái)唤冈。
- 2.可以先定義一個(gè)bus的空對(duì)象峡迷,首先A通過(guò)‘emit發(fā)送數(shù)據(jù)到bus這個(gè)空對(duì)象中,然后B通過(guò)emit發(fā)送數(shù)據(jù)到bus這個(gè)空對(duì)象中你虹,然后B通過(guò)on來(lái)接收這個(gè)空對(duì)象的數(shù)據(jù)绘搞。
- 3.vuex集中管理的方式傳值也是和上面一樣的辦法,只是在數(shù)據(jù)較多且復(fù)雜的情況下才用傅物,具體操作都是通過(guò)一個(gè)中間人來(lái)傳遞數(shù)據(jù)看杭。
Vuex
Vuex是什么
Vuex是一個(gè)專(zhuān)門(mén)為Vue.js應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式, 它采用集中式存儲(chǔ)管理所有組件的公共狀態(tài), 并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化.
vuex的核心概念
- vuex五大核心屬性:state,getter挟伙,mutation楼雹,action,module
- getter:可以認(rèn)為是 store 的計(jì)算屬性尖阔,它的返回值會(huì)根據(jù)它的依賴(lài)被緩存起來(lái)贮缅,且只有當(dāng)它的依賴(lài)值發(fā)生了改變才會(huì)被重新計(jì)算。
- mutation:更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation介却。
- action:包含任意異步操作谴供,通過(guò)提交 mutation 間接更變狀態(tài)。
- module:將 store 分割成模塊齿坷,每個(gè)模塊都具有state桂肌、mutation、action永淌、getter崎场、甚至是嵌套子模塊。
vuex的數(shù)據(jù)傳遞流程
當(dāng)組件進(jìn)行數(shù)據(jù)修改的時(shí)候我們需要調(diào)用dispatch來(lái)觸發(fā)actions里面的方法遂蛀。actions里面的每個(gè)方法中都會(huì)有一個(gè)commit方法谭跨,當(dāng)方法執(zhí)行的時(shí)候會(huì)通過(guò)commit來(lái)觸發(fā)mutations里面的方法進(jìn)行數(shù)據(jù)的修改。mutations里面的每個(gè)函數(shù)都會(huì)有一個(gè)state參數(shù),這樣就可以在mutations里面進(jìn)行state的數(shù)據(jù)修改螃宙,當(dāng)數(shù)據(jù)修改完畢后蛮瞄,會(huì)傳導(dǎo)給頁(yè)面。頁(yè)面的數(shù)據(jù)也會(huì)發(fā)生改變谆扎。
為什么要用vuex
由于傳參的方法對(duì)于多層嵌套的組件將會(huì)非常繁瑣挂捅,并且對(duì)于兄弟組件間的狀態(tài)傳遞無(wú)能為力。我們經(jīng)常會(huì)采用父子組件直接引用或者通過(guò)事件來(lái)變更和同步狀態(tài)的多份拷貝堂湖。以上的這些模式非常脆弱闲先,通常會(huì)導(dǎo)致代碼無(wú)法維護(hù)。所以我們需要把組件的共享狀態(tài)抽取出來(lái)苗缩,以一個(gè)全局單例模式管理饵蒂。在這種模式下,我們的組件樹(shù)構(gòu)成了一個(gè)巨大的“視圖”酱讶,不管在樹(shù)的哪個(gè)位置退盯,任何組件都能獲取狀態(tài)或者觸發(fā)行為!另外泻肯,通過(guò)定義和隔離狀態(tài)管理中的各種概念并強(qiáng)制遵守一定的規(guī)則渊迁,我們的代碼將會(huì)變得更結(jié)構(gòu)化且易維護(hù)。
mysql各字段的區(qū)別
char灶挟,varchar和text
- char是采用固定長(zhǎng)度存儲(chǔ)數(shù)據(jù)琉朽,也就是數(shù)據(jù)初始化為該類(lèi)型的字段分配固定長(zhǎng)度的存儲(chǔ)空間,即使沒(méi)有達(dá)到存儲(chǔ)空間的長(zhǎng)度稚铣,實(shí)際占用的存儲(chǔ)空間也是定義時(shí)的長(zhǎng)度箱叁。當(dāng)存儲(chǔ)的字符串沒(méi)有達(dá)到char的最大長(zhǎng)度時(shí),字符串后面是不會(huì)以空格來(lái)填充的惕医,而且char會(huì)過(guò)濾字符串末端的空格然后存儲(chǔ)耕漱,而在比較字符串的時(shí)候又會(huì)自動(dòng)空格填充到字符串的末端。雖然浪費(fèi)存儲(chǔ)空間抬伺,但是它固定長(zhǎng)度螟够,索引效率極高,不存在碎片峡钓。最多能存放的字符個(gè)數(shù) 255妓笙。
- varchar是存儲(chǔ)可變長(zhǎng)度的字符串,我們可以指定的字段長(zhǎng)度的最大長(zhǎng)度能岩,當(dāng)字符串沒(méi)有達(dá)到最大長(zhǎng)度的時(shí)候以字符串的實(shí)際長(zhǎng)度來(lái)存儲(chǔ)的寞宫,不占用多余的存儲(chǔ)空間。varchar不定長(zhǎng)捧灰,索引速度沒(méi)有char快淆九。理論上可以添加全部索引统锤,但是數(shù)據(jù)長(zhǎng)度太大時(shí)索引也會(huì)截取數(shù)據(jù)前面的一部分毛俏。但是如果字段的長(zhǎng)度越大炭庙,在字段不完全填充的情況下,varchar的性能優(yōu)勢(shì)就越明顯煌寇。最多能存放 65532 個(gè)字符焕蹄。
int、tinyint阀溶、float與decimal
- TINYINT一個(gè)很小的整數(shù)腻脏。有符號(hào)的范圍是-128到127,無(wú)符號(hào)的范圍是0到255银锻。一個(gè)字符
- SMALLINT一個(gè)小整數(shù)永品。有符號(hào)的范圍是-32768到32767,無(wú)符號(hào)的范圍是0到65535击纬。兩個(gè)字符
- MEDIUMINT一個(gè)中等大小整數(shù)鼎姐。有符號(hào)的范圍是-8388608到8388607,無(wú)符號(hào)的范圍是0到16777215更振。三個(gè)字符
- INT一個(gè)正常大小整數(shù)炕桨。有符號(hào)的范圍是-2147483648到2147483647,無(wú)符號(hào)的范圍是0到4294967295肯腕。四個(gè)字符
- BIGINT一個(gè)大整數(shù)献宫。有符號(hào)的范圍是-9223372036854775808到9223372036854775807,無(wú)符號(hào)的范圍是0到18446744073709551615实撒。八個(gè)字符姊途。注意,所有算術(shù)運(yùn)算用有符號(hào)的BIGINT或DOUBLE值完成知态,因此你不應(yīng)該使用大于9223372036854775807(63位)的有符號(hào)大整數(shù)捷兰,除了位函數(shù)!
- FLOAT一個(gè)小(單精密)浮點(diǎn)數(shù)字肴甸。不能無(wú)符號(hào)寂殉。允許的值是-3.402823466E+38-1.175494351E-38,0 和1.175494351E-38到3.402823466E+38原在。沒(méi)有參數(shù)的FLOAT或有<24 的一個(gè)參數(shù)表示一個(gè)單精密浮點(diǎn)數(shù)字友扰。
- DOUBLE一個(gè)正常大小(雙精密)浮點(diǎn)數(shù)字。不能無(wú)符號(hào)庶柿。允許的值是-1.7976931348623157E+308到-2.2250738585072014E-308村怪、 0和2.2250738585072014E-308到1.7976931348623157E+308。
- decimal表示數(shù)值的精度,即實(shí)際保存到數(shù)據(jù)庫(kù)的有效數(shù)字的總個(gè)數(shù); 第二個(gè)參數(shù)代表小數(shù)點(diǎn)后的位數(shù)
DATE,DATETIME,TIME,TIMESTAMP,YEAR;
- DATE 為年月日的日期格式浮庐,標(biāo)準(zhǔn)格式為YYYY-MM-DD,但是mysql中還支持一些不嚴(yán)謹(jǐn)?shù)母袷?比如YYYY/MM/DD等其他的符號(hào)來(lái)分割甚负,在插入數(shù)據(jù)的數(shù)據(jù)的也可以使用YY-MM-DD 年份的轉(zhuǎn)換柬焕,可以使用CURRENT_DATE() 函數(shù)獲取當(dāng)前的DATE值,占三個(gè)字節(jié)
- DATETIME 為年月日時(shí)分秒的混合時(shí)間格式梭域,DATE和TIME類(lèi)型的結(jié)合體斑举,占八個(gè)字節(jié)
- YEAR 為年份的時(shí)間的格式,占一個(gè)字節(jié)
- TIME 為時(shí)分秒的時(shí)間格式時(shí)間范圍為0~23,但是為了表示某些特殊的時(shí)間,mysql將小時(shí)的范圍擴(kuò)大了,并且支持負(fù)值病涨。對(duì)于TIME類(lèi)型復(fù)制,標(biāo)準(zhǔn)的格式為HH:MM:SS,但不一定要這個(gè)格式富玷,在mysql中,系統(tǒng)可以自動(dòng)識(shí)別HHMMSS轉(zhuǎn)化為標(biāo)準(zhǔn)格式.我們可以通過(guò)CURRENT_TIME()獲取當(dāng)前的TIME值既穆,三個(gè)字節(jié)
- TIMESTAMP 為年月份時(shí)分秒的混合時(shí)間格式赎懦,以時(shí)間戳的格式存儲(chǔ)。取值范圍比DATETIME小,因此輸入時(shí)一定要注意輸入值的范圍,超過(guò)范圍會(huì)當(dāng)作零值處理幻工。占四個(gè)字節(jié)
PSR0~4
psr0(官方已廢棄)
自動(dòng)加載標(biāo)準(zhǔn)
- 一個(gè)完全合格的namespace和class必須符合這樣的結(jié)構(gòu):“< Vendor Name>(< Namespace>)*< Class Name>”
- 每個(gè)namespace必須有一個(gè)頂層的namespace("Vendor Name"提供者名字)
- 每個(gè)namespace可以有多個(gè)子namespace
- 當(dāng)從文件系統(tǒng)中加載時(shí)励两,每個(gè)namespace的分隔符(/)要轉(zhuǎn)換成DIRECTORY_SEPARATOR(操作系統(tǒng)路徑分隔符)
- 在類(lèi)名中,每個(gè)下劃線(xiàn)要轉(zhuǎn)換成DIRECTORY_SEPARATOR(操作系統(tǒng)路徑分隔符)囊颅。在namespace中当悔,下劃線(xiàn)是沒(méi)有(特殊)意義的。
- 當(dāng)從文件系統(tǒng)中載入時(shí)迁酸,合格的namespace和class一定是以 .php 結(jié)尾的verdor name,namespaces,class名可以由大小寫(xiě)字母組合而成(大小寫(xiě)敏感的)
psr1
基本代碼規(guī)范
PHP源文件必須只使用 <?php 和 <?= 這兩種標(biāo)簽先鱼。(php標(biāo)記有多種方式)
源文件中php代碼的編碼格式必須是不帶字節(jié)順序標(biāo)記(BOM)的UTF-8。(注:PHP在設(shè)計(jì)時(shí)就沒(méi)有考慮BOM的問(wèn)題奸鬓,也就是說(shuō)他不會(huì)忽略UTF-8編碼的文件開(kāi)頭BOM的那三個(gè)字節(jié)導(dǎo)致出現(xiàn)奇怪的錯(cuò)誤焙畔。)
一個(gè)源文件建議只用來(lái)做聲明(類(lèi)(class),函數(shù)(function)串远,常量(constant)等)或者只用來(lái)做一些引起從屬效應(yīng)的操作(例如:輸出信息宏多,包含文件,修改.ini配置等)澡罚,但不能同時(shí)使用兩者伸但。
注:“從屬效應(yīng)”(side effects)一詞的意思是,僅僅通過(guò)包含文件留搔,不直接聲明類(lèi)更胖、函數(shù)和常量等,而執(zhí)行的邏輯操作隔显。 “從屬效應(yīng)”包含卻不僅限于:生成輸出却妨、直接的 require 或 include、連接外部服務(wù)括眠、修改 ini 配置彪标、拋出錯(cuò)誤或異常、修改全局或靜態(tài)變量掷豺、讀或?qū)懳募取?這個(gè)很多人都不遵守捞烟,但是基本上所有框架里都不會(huì)把修改.ini配置和聲明類(lèi)或函數(shù)放到一起薄声,比如框架index.php入口文件只定義宏常量和修改.ini等命名空間(namespace)和類(lèi)(class) 必須遵守PSR0或psr4標(biāo)準(zhǔn)。
類(lèi)名(class name) 必須使用駱駝式(StudlyCaps)寫(xiě)法(注:StudlyCaps即首字母大寫(xiě)駝峰式)题画。
類(lèi)(class)中的常量必須只由大寫(xiě)字母和下劃線(xiàn)組成默辨。
方法名(method name) 必須使用駝峰式(cameCase)寫(xiě)法。
psr2
代碼風(fēng)格
- 代碼必須遵循PSR-1中的編碼規(guī)范
- 代碼必須使用四個(gè)空格符而不是tab鍵進(jìn)行縮進(jìn)婴程。
- 每行的字符數(shù)應(yīng)該軟性保持在80個(gè)內(nèi)廓奕,理論上不可多于120個(gè)抱婉,但一定不能硬性限制
- 每個(gè)namespace命名空間聲明語(yǔ)句和use語(yǔ)句塊后面档叔,必須插入一個(gè)空白行
- 類(lèi)的開(kāi)始花括號(hào)必須在類(lèi)聲明后自成一行,結(jié)束花名號(hào)也必須在類(lèi)主體后自成一行
- 函數(shù)的開(kāi)始花括號(hào)必須在函數(shù)聲明后自成一行蒸绩,結(jié)束花名號(hào)也必須在函數(shù)主體后自成一行
- 類(lèi)的屬性和方法必須添加訪(fǎng)問(wèn)修飾符(private protected以及public)衙四,abstract以及final必須聲明在訪(fǎng)問(wèn)修飾符之前,而static必須聲明在訪(fǎng)問(wèn)修飾符之后患亿。
- 控制結(jié)構(gòu)的關(guān)鍵字后必須要有一個(gè)空格符传蹈,而調(diào)用方法或函數(shù)時(shí)則一定不能有。
- 控制結(jié)構(gòu)的開(kāi)始花括號(hào)必須寫(xiě)在聲明的同一行步藕,而結(jié)束花括號(hào)必須寫(xiě)在主體后自成一行惦界。
- 控制結(jié)構(gòu)的開(kāi)始左括號(hào)后和結(jié)束右括號(hào)前,都一定不能有空格符咙冗。
注意
對(duì)于php文件:
- 所有的php文件都必須以Unix LF(換行)作為結(jié)束符
- 所有的php文件都必須以一個(gè)單獨(dú)的空行結(jié)尾
- 純PHP代碼源文件的關(guān)閉標(biāo)簽?>必須省略沾歪。
關(guān)鍵字和 True/False/Null
- php的關(guān)鍵字,必須小寫(xiě)
- php產(chǎn)量 true 雾消,false灾搏,null也必須小寫(xiě)
命名空間
- 命名空間(namespace)的聲明后面必須有一行空行。
- 所有的導(dǎo)入(use)聲明必須放在命名空間(namespace)聲明的下面立润。
- 一句聲明中狂窑,必須只有一個(gè)導(dǎo)入(use)關(guān)鍵字。
- 在導(dǎo)入(use)聲明代碼塊后面必須有一行空行桑腮。
控制結(jié)構(gòu)
if 泉哈,else ,elseif 破讨,while 丛晦,do while ,switch case 添忘,for采呐, foreach,try catch等搁骑。這一類(lèi)的寫(xiě)法規(guī)范也是經(jīng)常容易出現(xiàn)問(wèn)題的斧吐,也要規(guī)范一下又固。在關(guān)鍵字和后面的判斷條件中間應(yīng)該加空格,在判斷條件和左大括號(hào)之間也要加空格煤率。
psr3
日志接口規(guī)范
- 它的主要目的仰冠,是為了讓類(lèi)庫(kù)以簡(jiǎn)單通用的方式接收一個(gè)Psr\Log\LoggerInterface對(duì)象,來(lái)記錄日志信息蝶糯⊙笾唬框架以及CMS內(nèi)容管理系統(tǒng)如有需要,可以擴(kuò)展接口以用于它們自己的目的昼捍,但須遵循本規(guī)范识虚,才能在使用第三方的類(lèi)庫(kù)文件時(shí),保證日志接口仍能正常對(duì)接妒茬。
- LoggerInterface 接口對(duì)外定義了八個(gè)方法担锤,分別用來(lái)記錄RFC 5424中定義的八個(gè)級(jí)別:debug、info乍钻、notice肛循、warning、error银择、critical多糠、alert,emergency浩考。
- 第九個(gè)方法-log夹孔,其第一個(gè)參數(shù)為日志的等級(jí),可使用一個(gè)預(yù)定義好的等級(jí)常量作為參數(shù)來(lái)調(diào)用此方法怀挠,必須與直接調(diào)用以上八個(gè)方法具有相同的效果析蝴。如果傳入的等級(jí)常量參數(shù)沒(méi)有預(yù)先定義,就必須拋出Psr\Log\InvalidArgumentException類(lèi)型的異常绿淋,在不確定的情況下闷畸,使用者不該使用未支持的等級(jí)常量來(lái)調(diào)用此方法。如果有用過(guò)monolog就應(yīng)該對(duì)這里有較深的理解吞滞。
psr4
升級(jí)版的PSR-0自動(dòng)加載規(guī)范
PSR4是關(guān)于由文件路徑自動(dòng)載入對(duì)應(yīng)的類(lèi)的相關(guān)規(guī)范佑菩,本規(guī)范是可互操作的〔迷可以作為任一自動(dòng)(包括PSR-0)載入規(guī)范的補(bǔ)充殿漠,此外,PSR4還包括自動(dòng)載入的類(lèi)對(duì)應(yīng)的文件存放路徑規(guī)范佩捞。此處的“類(lèi)”泛指所有的class類(lèi)绞幌、接口、traits可復(fù)用代碼塊以及其他類(lèi)似結(jié)構(gòu)一忱。
一個(gè)完整的類(lèi)名需要具有以下結(jié)構(gòu)<命名空間>(<子命名空間>)*<類(lèi)名>
- 完整的類(lèi)名必須要有一個(gè)頂級(jí)命名空間莲蜘,被稱(chēng)為“Vendor namespace”
- 完整的類(lèi)名可以有一個(gè)或多個(gè)子命名空間
- 完整的類(lèi)名必須有一個(gè)最終的類(lèi)名
- 完整的類(lèi)名中任意一部分中的下劃線(xiàn)都是沒(méi)有特殊意義的
- 完整的類(lèi)名可以由任意大小寫(xiě)字母組成
- 所有類(lèi)名都必須是大小寫(xiě)敏感的
當(dāng)根據(jù)完整的類(lèi)名載入相應(yīng)的文件
- 完整的類(lèi)名中谭确,去掉最前面的命名空間分隔符,前面連續(xù)的一個(gè)或多個(gè)命名空間和子命名空間票渠,作為“命名空間前綴”逐哈,其必須至少對(duì)應(yīng)一個(gè)基礎(chǔ)目錄。
- 緊接命名空間前綴后的子命名空間必須與相對(duì)應(yīng)的“基礎(chǔ)目錄”的子目錄相匹配问顷,其中的命名空間分隔符作為目錄分割符
- 末尾的類(lèi)名必須與對(duì)應(yīng)的.php為后綴的文件同名
- 自動(dòng)加載器(autoloader)的實(shí)現(xiàn)一定不能拋出異常昂秃,一定不能觸發(fā)任一級(jí)別的錯(cuò)誤信息以及不應(yīng)該有返回值。
PSR-4和PSR-0最大的區(qū)別是對(duì)下劃線(xiàn)(underscore)的定義不同杜窄。PSR-4中肠骆,在類(lèi)名中使用下劃線(xiàn)沒(méi)有任何特殊含義。而PSR-0則規(guī)定類(lèi)名中的下劃線(xiàn)_會(huì)被轉(zhuǎn)化成目錄分隔符羞芍。