PHP面試總結

前言

只適合工做(1-3)年的PHPerjavascript

寫簡歷的網站:php

超級簡歷 推薦html

冷熊簡歷 剛開始我用的這個,後來感受太過於簡單,不過程序員也不須要什麼花裏胡哨的簡歷,若是不喜歡第一個能夠用這個前端

PHP

基礎

PHP生命週期

  1. 詞法分析:將PHP文件轉換成 Token
  2. 語法分析:根據生成的 Token 和語法規則進行分析
  3. Zend 引擎:將代碼編譯爲 opcode 後並執行
  4. 調用 SAPI 輸出函數返回執行結果

SAPI 是什麼

SAPI 是服務器應用編程接口,做爲應用層(好比 Apache、Nginx、CLI等)和 PHP 交互數據的入口java

SAPI 實現了和各類應用層的兼容,應用層能夠根據自身狀況定製 SAPI,例:程序員

  1. apache2handler 和 apache2filter,這是提供給 Apache mod_php 的 SAPI;
  2. cgi,Web Server fork 出 cgi 進程使用的 sapi;
  3. fastcgi,Web Server 採用網絡通訊或者網絡 IPC 和 PHP 交換數據的 SAPI;
  4. cli,命令行方式運行 PHP 腳本的 SAPI

Session和Cookie的區別

Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中。ajax

Coookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。算法

參考sql

Session和Cookie的區別thinkphp

PHP7跟PHP5的區別,具體多了哪些新特性?

  1. 性能提高了兩倍
  2. 增長告終合比較運算符和??運算符
  3. 增長了標量類型聲明、返回類型聲明(declare(strict_types=1):嚴格模式)
  4. try…catch增長了多條件判斷,能夠對更多的Error錯誤進行異常處理
  5. 增長了匿名類,能夠直接使用new class來實例化一個匿名類
  6. define可定義常量數組

參考

PHP7新特性

PHP 標量類型與返回值類型聲明

魔術常量

__LINE__	  當前行號
__DIR__		  當前目錄
__FILE__	  當前文件完整的文件地址
__FUNCTION__  當前函數名
__METHOD__	  類的方法榠
__CLASS__	  類名
__NAMESPACE__ 當前命名空間名稱
複製代碼

魔術方法

__construct、__destruct、__call、__callStatic、__get、__set、__isset、
__unset、__toString、__set_state、__debuginfo、__clone、__sleep、__wakeup、__invoke
複製代碼

參考

PHP魔術方法

include 和 require 的區別

它們在加上 _ones 後綴時表示已加載文件的不加載

  1. 加載失敗的處理方式不一樣

    require 加載失敗,會報出一個 Fatal error 腳本中止執行

    include 加載失敗,會報出一個 Warning 腳本會繼續執行

  2. 性能不一樣

    include 執行文件每次都要進行讀取和評估;

    require 文件只處理一次

    若是可能執行屢次的代碼,就用 require 效率比較高

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

PHP 5.3 版本以前都是採用引用計數的方式管理內存,PHP 全部的變量存在一個叫 zval 的變量容器中,當變量被引用的時候,引用計數會+1,變量引用計數變爲0時,PHP 將在內存中銷燬這個變量。

可是引用計數中的循環引用,引用計數不會消減爲 0,就會致使內存泄露。

在 5.3 版本以後,作了這些優化:

  1. 並非每次引用計數減小時都進入回收週期,只有根緩衝區滿額後在開始垃圾回收;
  2. 能夠解決循環引用問題;
  3. 能夠總將內存泄露保持在一個閾值如下。

數據結構和算法

快速排序

經過設置一個初始中間值,來將須要排序的數組分紅3部分,小於中間值的左邊,中間值,大於中間值的右邊,繼續遞歸用相同的方式來排序左邊和右邊,最後合併數組

function quickSort($array) {
    if(!isset($array[1]))
        return $array;
    $nMid = $array[0]; //獲取一個用於分割的關鍵字,通常是首個元素
    $arrLeft = array();
    $arrRight = array();

    foreach($array as $v)
    {
        if($v > $nMid)
            $arrRight[] = $v;  //把比$nMid大的數放到一個數組裏
        if($v < $nMid)
            $arrLeft[] = $v;   //把比$nMid小的數放到另外一個數組裏
    }

    $arrLeft   = quickSort($arrLeft); //把比較小的數組再一次進行分割
    $arrLeft[] = $nMid;        //把分割的元素加到小的數組後面,不能忘了它哦

    $arrRight = quickSort($arrRight);  //把比較大的數組再一次進行分割
    return array_merge($arrLeft,$arrRight);  //組合兩個結果
    
}// END quickSort
複製代碼

冒泡排序

$arrArr = array(345,4,17,6,52,16,58,69,32,8,234);
$length = count($arrArr);
for ($i = 1; $i < $length; $i ++)
{
    for ($j = $length-1; $j >= $i; $j --)
    {
        if ($arrArr[$j] < $arrArr[$j-1])
        {
            $interim = $arrArr[$j-1];
            $arrArr[$j-1] = $arrArr[$j];
            $arrArr[$j] = $interim;
        }
    }
}
複製代碼

架構相關

S.O.L.I.D設計原則

  1. 單一功能原則
  2. 開閉原則
  3. 里氏替換原則
  4. 接口隔離原則
  5. 依賴反轉原則

Laravel跟ThinkPHP的區別

  1. 加密方式不一樣,Laravel用的是Hash單向加密,ThinkPHP使用的Md5
  2. Laravel全部控制器的操做要基於路由,ThinkPHP不須要
  3. Laravel有中間件實現訪問先後的處理,ThinkPHP沒有中間件

參考

Laravel跟ThinkPHP的區別

ThinkPHP的生命週期

  1. 入口文件
  2. 引導文件
  3. 註冊自動加載
  4. 註冊錯誤和異常機制
  5. 應用初始化
  6. URL訪問檢測
  7. 路由檢測
  8. 分發請求
  9. 響應輸出
  10. 應用結束

參考

ThinkPHP生命週期

對MVC的理解

MVC是模型、視圖、控制器的縮寫,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯彙集到一個部件裏面

優勢

  1. 低耦合
  2. 重用性高
  3. 部署快
  4. 可維護性高

防禦

  1. XSS跨站腳本攻擊
  2. DDOS流量攻擊
  3. CSRF跨站請求僞造攻擊
  4. SQL注入

在前端表單用戶輸入進行控制或限制

由後端傳參數和數據時進行過濾等等

參考

常見的各類攻擊解決方案

項目

你如何作一個秒殺系統

列出四種解決方案,推薦去看一下前三種解決方案的例子。

  • 用緩存來處理搶購,避免直接操做數據庫,使用 Redis 隊列,由於pop操做是原子的,即便有不少用戶同時到達,也是依次執行,推薦使用
  • 庫存字段number字段設爲unsigned,當庫存爲0時,由於字段不能爲負數,將會返回false
  • 使用 Mysql 的事務,鎖住操做的行
  • (不推薦使用)作一個延時處理,延時一段時間公佈搶購結果

如何在項目中解決併發的問題

在前端控制有效請求,例如一分鐘才正常請求一次

在後端過濾無效請求,將操做放進隊列中實現,也能夠用鎖的機制,第二個等待第一個完成,一個接一個

參考

PHP高併發解決的思路

服務器

協議

Get 和 Post 的區別

Get 的參數包含在 URL,Get 請求會被瀏覽器主動緩存,有字符限制參數爲 ASCII 字符

Post 經過 request body 傳遞參數,有多種編碼方式

HTTP請求包含了什麼

  1. 狀態行
  2. 請求頭
  3. 消息主體

HTTP狀態碼

分類 分類描述
1** 信息,服務器收到請求,須要請求着繼續執行操做
2** 成功,操做被成功接受處理
3** 重定向,須要進一步的操做以完成請求
4** 客戶端錯誤,請求包含語法錯誤或沒法完成請求
5** 服務器錯誤,服務器在處理請求的過程當中發生了錯誤

三次握手

三次握手的目的是:爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤

  1. 客戶端發送一個包,來確保服務端可以接收到客戶端傳來的消息
  2. 服務端返回一個確認包,來代表能夠接收到客戶端傳來的消息並能作出正確應答
  3. 客戶端再次發送確認包,代表並能夠作出正確應答

四次分手

  1. 主機A通知主機B沒有數據要發送了
  2. 主機B收到主機A的信息返回一個報文段,告訴主機A贊成關閉請求
  3. 主機B向主機A請求關閉鏈接,進入 LAST_ACK 狀態
  4. 主機A收到並向主機B發送 ACK 報文段,主機B收到後關閉鏈接;而後主機A等待 2MSL 後依然沒有收到回覆,證實主機B已關閉,主機A關閉

URL執行過程

  1. DNS解析爲IP地址
  2. TCP鏈接
  3. 發送HTTP請求
  4. 服務器處理請求並返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 鏈接結束

軟件架構

RESTful架構是什麼

是以 Web 爲平臺圍繞着資源展開的創建 API 時遵照的一種規則 / 風格

RESTful 規定,數據的 CURD 操做對應着 HTTP 方法:

  • GET(SELECT):從服務器取出資源(一項或多項)
  • POST(CREATE):在服務器新建一個資源
  • PUT(UPDATE):在服務器更新資源(客戶端提供完整資源數據)
  • PATCH(UPDATE):在服務器更新資源(客戶端提供須要修改的資源數據)
  • DELETE(DELETE):從服務器刪除資源

RESTful 的構成

https://api.example.com/v1/employees
複製代碼
  • 協議

    API 與用戶的通訊協議爲 HTTPS 協議

  • 域名

    應該儘可能將 API 部署在專用子域名下,或者獨立域名

  • 版本

    應該將 API 的版本號放入 URL

  • 路徑

    代表 API 的具體功能地址

  • HTTP 動詞

    就是上方對應的 HTTP 方法

  • 過濾信息

    若是記錄數量不少,服務器不可能將它們都返回給用戶,API 應該提供參數,過濾返回結果,好比說指定返回多少條數據,或者頁數之類的。

  • 狀態碼跟提示信息

  • 錯誤處理

  • 返回結果

    針對不一樣操做,返回結果符合規範

Redis

Redis類型有哪些

string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

Mysql

基礎

InnoDB跟MyISAM有什麼區別

MyISAM性能強,執行速度快,支持表鎖和全文索引

InnoDB安全性強,支持事務處理、外鍵跟行鎖

參考

MyISAM跟InnoDB的區別

什麼是索引

索引是一種數據結構,能幫助咱們快速的檢索數據庫中的數據

索引有哪些,有什麼特色

  • PRIMARY KEY 主鍵索引

    主鍵是一種惟一性索引,每一個表只能有一個主鍵,在單表查詢中,PRIMARY主鍵索引與UNIQUE惟一索引的檢索效率並無多大的區別,

    但在關聯查詢中,PRIMARY主鍵索引的檢索速度要高於UNIQUE惟一索引。

  • INDEX 普通索引

    這是最基本的索引類型,並且它沒有惟一性之類的限制。

  • UNIQUE 惟一索引

    這種索引和前面的「普通索引」基本相同,但有一個區別:索引列的全部值都只能出現一次,即必須惟一。

  • FULLTEXT 全文索引

    MySql從3.23版開始支持全文索引和全文檢索。全文索引只能夠在VARCHAR或者TEXT類型的列上建立。

    對於大規模的數據集,經過ALTER TABLE(或者CREATE INDEX)命令建立全文索引要比把記錄插入帶有全文索引的空表更快。

  • 組合索引(較特殊)

    在索引的建立中,有兩種場景,即爲單列索引和多列索引

事務四大特性(ACID)

原子性、一致性、隔離性、持久性

參考

事務ACID原理

如何在項目中實現事務四大特性

原子性

利用 Innodb 的 undo log 回滾日誌實現,當事務回滾時撤銷全部已經成功執行的 sql 語句

一致性

從兩個層面來保證一致性,從數據庫層面來講,能夠經過原子性、隔離性和持久性來保證一致性。

從應用層來講,經過代碼判斷數據庫數據是否有效,而後決定回滾仍是提交數據

隔離性

利用鎖機制來實現隔離性

持久性

利用 Innobd 的 redo log 重寫日誌

事務隔離級別

未提交讀、已提交讀、可重複讀、序列化

參考

Innodb中的事務隔離級別和鎖的關係

優化

初級優化

  1. 開啓慢查詢日誌,監測SQL語句執行

    set global slow_query_log = ON;
    set global long_query_time = 3600;
    複製代碼
  2. 優化不合理的SQL

  3. 在經常使用的字段上創建合理的索引

  4. 在聯合索引查詢中遵循最左原則

分庫分表

參考

數據庫分庫分表思路

前端

如何解決跨域問題

PostMessage 跨域

使用 Iframe 標籤訂義須要跨域的域名,而後使用 contentWindow.postMessage 發送跨域數據,使用 window.addEventListener 接收返回數據

域名 A 下

<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script> var iframe = document.getElementById('iframe'); iframe.onload = function() { var data = { name: 'aym' }; // 向domain2傳送跨域數據 iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com'); }; // 接受domain2返回數據 window.addEventListener('message', function(e) { alert('data from domain2 ---> ' + e.data); }, false); </script>
複製代碼

域名 B 下

// 接收domain1的數據
window.addEventListener('message', function(e) {
    alert('data from domain1 ---> ' + e.data);

    var data = JSON.parse(e.data);
    if (data) {
        data.number = 16;

        // 處理後再發回domain1
        window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
    }
}, false);
複製代碼
Jsonp 跨域
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 請求方式爲jsonp
    jsonpCallback: "handleCallback",    // 自定義回調函數名
    data: {}
});

handleCallback(res)
{
    console.log(JSON.stringify(res));
}// END handleCallback
複製代碼

閉包

概念

閉包就是讀取其餘函數內部變量的函數

閉包的用途
  1. 讀取其餘函數內部的變量
  2. 讓變量常駐內存

Other

小程序受權機制

  1. 首先小程序調用 wx.login 接口來獲取到 code
  2. 拼接 AppId、Appsecret、code 使用curl調用微信接口獲取到 openid 和 session_key
  3. 經過openid查詢,若是用戶是新用戶就插入一條數據,返回新插入的主鍵ID,有的話直接返回ID
  4. 將ID、openid 生成一個字符串做爲Token返回小程序

參考

微信小程序登陸換取Token

小程序 Template 模版跟 Component 組件有什麼區別

Template 模版是用來作顯示做用的,只建立 wxml、wxss 文件就能夠了

Component 組件有本身的業務邏輯,若是涉及到業務邏輯交互較多就用 Component

工做中的業務開發流程是怎樣的

按本身實際理解講

相關文章
相關標籤/搜索