天天看點

PHP一些面試題

Web篇

1. 談談對Web語義化的了解

語義化的含義就是用正确的标簽做正确的事情,語義化讓網頁的内容結構化,結構更清晰,便于對浏覽器、搜尋引擎解析,利于SEO,也有利于代碼閱讀、便于維護。

2. 寫出一個使用flex布局,在div垂直居中的css代碼

div {
    display: flex;
    justify-content: center;
    align-items: center;
}
           

3. 為什麼把JavaScript放在html底部

  • 因為浏覽器渲染HTML檔案是從上往下渲染的,JavaScript放在HTML頭部,會阻礙浏覽器的渲染速度,增加使用者的等待時間
  • 浏覽器加載 JavaScript 腳本之後會自動執行,如果放在頭部,此時的Dom還沒有加載完,很容易出現BUG。

4. 談談對 JavaScript 閉包的了解

閉包是 JavaScript 函數的一種,聲明即運作,可以在函數内容調用外部變量。

5. 如何處理Ajax跨域問題

  • 代理
  • Jsonp
  • iframe
  • cors

6. 一句話解釋JsonP的原理

Jsonp,即 json padding,原理就是利用

<script>

标簽沒有跨域限制達到與第三方通訊的目的。

前端擴充閱讀

  • 收集的前端面試題和答案
  • 前端開發面試題
  • 史上最全的web前端面試題彙總及答案1
  • 前端工程師手冊
  • HTTP協定:工作原理
  • SSL/TLS協定運作機制的概述

協定篇

1. 網絡協定有哪些?

  • 應用層:HTTP、FTP、SSH、SMTP、SFTP
  • 表示層
  • 會話層
  • 傳輸層:TCP、UDP
  • 網絡層:IP
  • 資料鍊路層
  • 實體層

2. 簡述HTTP協定的工作流程

  1. 位址解析——在浏覽器中輸入URL,浏覽器會從中解析出協定名、主機名、端口、對象路徑等部分
  2. 封裝HTTP請求資料包
  3. 浏覽器擷取主機 IP 位址,建立 TCP 連接配接(TCP的三次握手)
  4. TCP連結建立後發送HTTP請求
    • 請求方式的格式為:統一資源辨別符(URL)、協定版本号、後面是 MIME 資訊包括請求修飾符、客戶機資訊和可用内容
  5. 伺服器接到請求後,給予相應的響應資訊
    • 其格式為一個狀态行,包括資訊的協定版本号、一個成功或錯誤的代碼,後邊是 MIME 資訊包括伺服器資訊、實體資訊和可能的内容
  6. 伺服器斷開 TCP 連接配接

3. 什麼是HTTPS?實作過程是什麼?

HTTPS (超文本傳輸安全協定)是一種通過計算機網絡進行安全通信的傳輸協定,提供對網站伺服器的身份認證,保護資料傳輸的完整性、安全性。

實作過程:

  1. 用戶端發起一個 https 的請求
  2. 服務端接收用戶端請求,傳回數字證書相關資訊
  3. 用戶端收到服務端響應
    1. 驗證證書的合法性
    2. 如果證書受信任,生成随機數的密碼
    3. 使用約定好的HASH算法計算握手資訊,并使用生成的随機數對消息進行加密,然後發送給服務端
  4. 網站接收浏覽器發來的密文後
    1. 使用私鑰來解密握手消息取出随機密碼,再用随機密碼解密,握手消息與HASH值,并與傳過來的HASH值對比确認是否一緻
    2. 使用密碼加密一段握手消息,發送給浏覽器
  5. 浏覽器解密并計算握手消息的HASH,如果與服務端發來的HASH一緻,此時握手過程結束,之後所有的通信資料,将由之前的浏覽器生成的随機密碼,并利用對加密算法進行加密。

4. 數字證書都包括哪些資訊?

  • 證書的版本資訊;
  • 證書的序列号,每個證書都有一個唯一的證書序列号;
  • 證書所使用的簽名算法;
  • 證書的發行機構名稱;
  • 證書的有效期;
  • 證書所有人的名稱、公開密鑰;
  • 證書發行者對證書的簽名;

5. TCP 三次握手的流程

  • 用戶端發送一個 SYN 标志位置 1 的包,指明用戶端要連接配接伺服器端的接口,發送完畢後,用戶端進入SYN_SEND 狀态。
  • 伺服器發回确認包(ACK)應答。即 SYN 标志和 ACK 标志位均為 1。服務端選擇自己的 ISN 序列号,放到Seq 域裡,同時将确認序号(Acknowledgement Number)設定為客戶的 ISN 加 1,即 X + 1。發送完畢後,伺服器端進入 SYN_RCVD 狀态。
  • 用戶端再次發送确認包(ACK),SYN 标志位為 0,ACK 标志位為 1,并且把伺服器發來 ACK 的序号字段 +1,放在确定字段中發送給對方,并且在資料段放寫 ISN 的 +1。
  • 發送完畢後,用戶端進入 ESTABLISHED 狀态,當伺服器端接收到這個包時,也進入 ESTABLISHED 狀态,TCP 握手結束。

6. 什麼是Socket?工作流程是怎樣的?

Socket 又稱 網絡套接字,是一種作業系統提供的程序間通信機制。

工作流程:

  1. 服務端先用Socket函數來建立一個套接字,并調用 listen 函數,使服務端的這個端口和 IP 處于監聽狀态,等待用戶端的連接配接
  2. 用戶端用 socket 函數建立一個套接字,設定遠端 IP 和端口,并調用connect函數
  3. 服務端用 accept 函數來接受遠端計算機的連接配接,建立起與用戶端之間的通信
  4. 完成通信以後,最後使用 close 函數關閉 socket 連接配接

7. HTTP 1.1 與 WebSocket 的差別?

  • HTTP 是一種單連結,隻能單向通訊,而 WebSocket 是一個持久連接配接,可用作雙向通訊。
  • WebSocket 是基于 HTTP 來建立連接配接的,但在建立連接配接之後,真正的資料傳輸階段是不需要 HTTP 協定參與的
  • WebSocket 的請求的頭部和 HTTP 請求頭部不同
  • WebSocket 傳輸的資料是二進制流,是以幀為機關,HTTP 是明文字元串傳輸

8. 什麼是 OAuth 2.0 協定?運作流程是怎麼樣的?

OAuth(Open Authorization)協定為使用者資源的授權提供了一個安全的、開放而有簡易的标準,第三方無需使用使用者的使用者名與密碼,就可以申請獲得該使用者資源的授權。

運作流程:

  1. 使用者打開用戶端以後,用戶端要求使用者給予授權
  2. 使用者同意給予用戶端授權
  3. 用戶端使用上一步獲得的授權,向認證伺服器申請令牌
  4. 認證伺服器對用戶端進行認證以後,确認無誤,同意發放令牌
  5. 用戶端使用令牌,向資源伺服器申請擷取資源
  6. 資源伺服器确認令牌無誤,同意向用戶端開放資源

OAuth 2.0 定義了四種授權方式,授權碼模式、簡化模式、密碼模式、用戶端模式,具體的授權流程,請看阮一峰老師的文章了解OAuth 2.0。

擴充閱讀

  • https 原理
  • HTTPS 原了解析
  • HTTPS 的工作原理
  • socket
  • HTTP與WebSocket的差別
  • 了解OAuth 2.0

PHP基礎篇

1. PHP的兩種用法

  • 正常用法
<body>
<?php echo '<p>Hello World</p>';
</body>
           
  • 進階用法
<html>
<head>
    <body>
        <ul>
    		<?php for ( $i = 1; $i <= 3; i++ ) {?> 
        		<li>listnum<?php echo $i;?></li>
            <?php }?>
        </ul>
    </body>
</head>
</html>
           

2. PHP的輸出語句

  1. echo

    用來輸出字元串到網頁上,由于它不是函數,是以不需要對其使用括号;echo不傳回值,不能對其指派。

<?php
	echo "Hello World";
           
  1. print

    print與echo功能類似,用于将字元輸出到網頁上,echo可以使用的地方print也可以使用;

    print不是函數,不支援都好分隔多個變量,向print傳遞一個以上的參數時會發生解析錯誤;

    print總是傳回1,與echo不一樣,效率沒有echo 搞笑。

<?php
	$x = print("hello world");
	echo $x; // 1
	print "hello world";
           
  1. printf

    用于格式化列印字元串,文法是

    printf(format, arg1, arg2, arg3, ...)

    ,format為轉換的模闆,arg1、arg2、arg++參數被插入format中的%處,此函數逐漸執行,arg1插入到第一個%處,依次類推。
<?php
	printf("Hello %s", "大貓");
           
format content
%% 傳回百分号
%b 二進制數
%c 依照ASCII編碼
%d 帶符号十進制數
%e 科學計數法(例如:1.5e3)
%u 無符号十進制數
%f 浮點數
%o 八進制
%s 字元串
%x 十六進制(小寫字母)
%X 十六進制(大寫字母)
  1. sprintf

    sprintf 與 printf 用法相同,sprintf将格式化的字元串寫入變量中,不直接輸出結果。

<?php
	echo sprintf("This is %1\$s %2\$s\n", "A", "B"); // This is A B
    $out = sprintf("This is %1\$s %1\$s", "A", "B");
    echo $out . PHP_EOL; // This is A A
           
  1. print_r

    print_r 顯示關于一個變量的易于了解的資訊,主要用來輸出數組、對象等複合資料類型,傳回布爾類型

<?php
	$arr = ['a' => 'A', 'b' => 'B', 'c' => ['a', 'b', 'c']];
	print_r($arr);
           
  1. var_dump

    var_dump 用于調試,作用是輸出變量的内容、類型或字元串的内容、類型、長度。

<?php
	$numberOne = 1.5;
	var_dump($numberOne); // 輸出 float(1.5)
	$numberTwo = 2;
	var_dump($numberTwo); // 輸出 int(2)
           

3. 單引号與雙引号的差別

雙引号解析 $ 開頭的變量和轉義字元串,單引号不解析也不轉義字元。

4. Get 與 Post 的差別

  • get參數通過url傳遞,post放在request body中
  • get請求在url中傳遞的參數是有長度限制的,而post沒有
  • get比post更不安全,因為參數直接暴露在url中,是以不能用來傳遞敏感資訊
  • get請求隻能進行url編碼,而post支援多種編碼方式
  • get請求會浏覽器主動cache,而post不可以被緩存
  • get請求參數會被完整保留在浏覽器曆史記錄裡,而post中的參數不會被保留。
  • get産生一個TCP資料包;POST産生兩個TCP資料包
    • get方式的請求,浏覽器會把http header和data一并發送出去,伺服器響應200
    • post方式的請求,浏覽器先發送header,伺服器響應100 continue,浏覽器再發送data,伺服器響應200 ok

5. isset 和 empty 的差別

  • isset 判斷變量是否存在或者變量名是否為null
  • empty 判斷變量是否為空,0、“0”、’‘、FALSE、array()都會被判定成為空。比isset需要判斷更多的條件

6. 什麼是 MVC?

  • M —— Model 模型 多用于處理業務邏輯
  • V —— View 視圖 負責跟使用者進行頁面互動
  • C —— Controller 控制器 用于處理請求和調用 Model 模型把處理結果分發給 View

優點:

  1. 分工明确(開發人員可以關注整個結構中的其中某一層):使用MVC可以把資料庫開發,程式業務邏輯開發,頁面開發分開,每一層都具有相同的特征,友善以後的代碼維護。
  2. 松耦合(可以降低層與層之間的依賴):視圖層和業務層分離,這樣就允許修改視圖層代碼不用重新編譯模型和控制器代碼,同樣,一個應用的業務流程或者業務規劃的改變隻需要改動MVC的模型層即可。因為模型層與資料層和視圖相分離,是以很容易改變應用程式的資料層和業務規則。
  3. 複用性高(利于各層邏輯的複用):像多個視圖能夠共享一個模型,不論你視圖層用的flash界面或是wap界面,用一個模型就能處理。将資料和業務規則從表示層分開,就可以最大化重用代碼
  4. 有利于标準化

缺點:

  1. 有時會導緻級聯的修改。這種修改其實展現在自上而下的方向。如果表示層中增加一個功能,為保證設計符合分層式結構,可能需要再相應的業務邏輯層和資料通路層中都增加相應的代碼。
  2. 降低了系統的性能。如果不采用分層式結構,很多業務直接造訪資料庫,以此擷取相應的資料,現在必須通過中間層來完成。
  3. 由于它沒有明确的定義,是以完全了解MVC并不是很容易。使用MVC需要精心的計劃,由于它的内部原理比較複雜,是以需要花一些時間去思考
  4. MVC并不适合小型甚至中等規模的應用程式,話費大量時間将MVC應用到規模并不是很大的應用程式通常會得不償失。

如何改善:

  • 可以采用一些設計模式來改善
  • 可以通過系統的緩存機制來減小對性能的影響

7. 傳值和傳引用的差別?

  • 傳值隻是傳遞一個變量的拷貝
  • 傳引用實際就是傳遞一個變量的位址,函數可以直接改變變量的值

8. Cookie 和 Session 的差別和關系

  1. Cookie 存在用戶端(浏覽器),Session 存在伺服器端
  2. Session 比 Cookie 安全性更高
  3. 單個 Cookie 儲存的資料不能超過 4K
  4. Session 是基于 Cookie,如果浏覽器禁用了 Cookie,Session 也會失效(但是可以通過其他方式實作,比如在 url 中傳遞 Session ID)

9. 簡述 S.O.L.I.D 設計原則

英文描述 中文描述 備注解釋
SRP 單一職責原則 一個類有且隻有一個更改的原因
OCP 開閉原則 對擴充開放,對修改關閉
LSP 裡氏替換原則 派生類可以替換其基類使用
ISP 接口隔離原則 使用用戶端特定的細粒度接口
DIP 依賴反轉原則 依賴抽象而不是具體實作

10. 列舉一些PHP中的設計模式?

  • 單例模式:保證在整個應用程式的生命周期中,任何一個時刻,單例類的執行個體都隻存在一個,同時這個類還必須提供一個通路該類的全局通路點。
  • 工廠模式:定義一個建立對象的接口,但是讓之類去實作具體類。工廠方法模式讓類的執行個體化延遲到了子類中。
  • 觀察者模式:觀察者模式有時也被成為釋出/訂閱模式,該模式用于對象實作 釋出/訂閱功能:一旦主題對象發生改變,與之關聯的觀察者對象會收到通知,并進行相應操作。
  • 擴充卡模式:擴充卡模式将一個類的接口轉換成為客戶希望的另外一個接口,使得原本由于接口不相容不能一起工作的那些類可以一起工作。

了解更多,請看PHP 設計模式系列。

11. PHP7 和 PHP5 的差別,具體多了哪些新特性?

  1. 性能提升了兩倍
  2. 增加了結合比較運算符(<=>)
  3. 增加了标量類型生命、傳回類型聲明
  4. try...catch

    增加多條件判斷,更多 Error 錯誤可以進行異常處理
  5. 增加了匿名類,現在支援通過

    new class

    來執行個體化一個匿名類,這可以用來替代一些“用後即焚”的完整類定義

12. 為什麼 PHP7 比 PHP5 性能提升了?

  1. 變量存儲位元組減小,減少記憶體占用,提升變量操作速度
  2. 改善數組結構,數組元素和hash映射表被配置設定在同一塊記憶體裡,降低了記憶體占用、提升了 CPU 緩存命中率
  3. 改進了函數的調用機制,通過優化參數傳遞的環節,減少了一些指令,提高了執行效率

13. 簡述一下 PHP 垃圾回收機制(GC)

PHP 5.3 版本之前都是采用引用計數的方式管理記憶體,PHP所有的變量存在一個叫

zval

的變量容器中,當這個變量被引用的時候,引用計數會 +1,變量引用計數變為 0 時, PHP将在記憶體中銷毀這個變量。

但是引用計數中的循環引用,引用計數不會消減為 0,就會導緻記憶體洩漏。

在 5.3版本之後,做了這些優化:

  1. 并不是每次引用計數減少時都進入回收周期,隻有根緩沖區滿額後在開始垃圾回收;
  2. 可以解決循環引用問題;
  3. 可以總将記憶體洩漏保持在一個門檻值一下。

了解更多可以檢視 PHP 手冊,垃圾回收機制。

14. 如何解決 PHP 記憶體溢出問題

  1. 增大 PHP 腳本的記憶體配置設定
  2. 變量引用之後及時銷毀
  3. 将資料分批處理

15. Redis、Memecached 這兩者有什麼差別?

  1. Redis 支援更加豐富的資料存儲類型:
    • String
    • Hash
    • List
    • Set
    • Sorted Set
    Memecached 僅支援簡單的 key-value結構
  2. Memcached key-value存儲比 Redis 采用 hash 結構來做 key-value 存儲的記憶體使用率更高。
  3. Redis 提供了事務的功能,可以保證一系列指令的原子性
  4. Redis 支援資料的持久化,可以将記憶體中的資料保持在磁盤中
  5. Redis 隻使用單核,而 Memcached 可以使用多核,是以平均每一個核上 Redis 在存儲小資料時比 Memcached 性能更高。

16. Redis 如何實作持久化?

  1. RDB 持久化,将 Redis 在記憶體中的狀态儲存到硬碟中,相當于備份資料庫狀态。
  2. AOF 持久化(Append-Only-File),AOF 持久化是通過儲存 Redis 伺服器鎖執行的寫狀态來記錄資料庫的。相當于備份資料庫接收到的指令,所有被寫入 AOF 的指令都是以 Redis 的協定格式來儲存的。

Web 安全防範

1. CSRF 是什麼?如何防範?

CSRF (Cross-site request forgery)通常被叫做【跨站請求僞造】,攻擊者盜用使用者身份,進而欺騙伺服器,來完成攻擊請求。

防範措施:

  1. 使用驗證碼
  2. 給每一個請求添加令牌 token 并驗證

2. XSS 是什麼? 如何防範?

XSS(Cross Site Scripting),跨站腳本攻擊,攻擊者往 Web 頁面裡面插入惡意 Script 代碼,當使用者浏覽該頁之時,嵌入其中 Web 裡面的 Script 代碼會被執行,進而達到惡意攻擊使用者的目的。

防範措施:

  1. 核心本質:永遠不要相信使用者的輸入資料,始終保持對使用者資料的過濾。

3. 什麼是 SQL 注入?如何防範?

SQL 注入就是攻擊者通過一些方式欺騙伺服器,結果執行了一些不該被執行的SQL語句。

常見場景:

  1. 資料庫被注入了大量的垃圾資料,導緻伺服器運作緩慢、崩潰。
  2. 利用 SQL 注入 暴露了應用程式的隐私資料

防範措施:

  1. 保持對使用者資料的過濾
  2. 不要使用動态拼裝 SQL
  3. 對隐私資料加密,禁止明文存儲

擴充閱讀

  • 3年PHPer的面試總結
  • 垃圾回收機制
  • S.O.L.I.D 面向對象設計
  • 淺談IOC--說清楚IOC是什麼
  • Redis和Memcached的差別
  • CSRF攻擊與防禦
  • XSS跨站腳本攻擊
  • PHP 設計模式系列

轉載于:https://my.oschina.net/alexskywinner/blog/3103170