PHP面試題收集整理

一、oop是面向對象編程。面向對象編程是一種計算機編程架構,OOP 的一條基本原則是計算機程序是由單個可以起到子程序做用的單元或對象組合而成。php

封裝性:也稱爲信息隱藏,就是將一個類的使用和實現分開,只保留部分接口和方法與外部聯繫,或者說只公開了一些供開發人員使用的方法。因而開發人員只須要關注這個類如何使用,而不用去關心其具體的實現過程,這樣就能實現MVC分工合做,也能有效避免程序間相互依賴,實現代碼模塊間鬆藕合。css

繼承性:就是子類自動繼承其父級類中的屬性和方法,並能夠添加新的屬性和方法或者對部分屬性和方法進行重寫。繼承增長了代碼的可重用性。PHP只支持單繼承,也就是說一個子類只能有一個父類。html

多態性:子類繼承了來自父級類中的屬性和方法,並對其中部分方法進行重寫。因而多個子類中雖然都具備同一個方法,可是這些子類實例化的對象調用這些相同的方法後卻能夠得到徹底不一樣的結果,這種技術就是多態性。多態性加強了軟件的靈活性。前端

易維護 、質量高 、效率高 、易擴展 因爲繼承、封裝、多態的特性,天然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴展,並且成本較低。node

二、各框架
ThinkPHP
優勢:mysql

1.簡化開發、提升效率、易於擴展、易於上手,有豐富的中文文檔;nginx

2.框架的兼容性較強,PHP4和PHP5徹底兼容、徹底支持UTF8等。laravel

3.適合用於中小項目的開發web

缺點:面試

1.對Ajax的支持不是很好;

2.目錄結構混亂,須要花時間整理;

3.上手容易,可是深刻學習較難。

YII
優勢

1.純OOP

2.用於大規模Web應用

3.模型使用方便

4.開發速度快,運行速度也快。性能優異且功能豐富

5.使用命令行工具。

缺點:

1.對Model層的指導和考慮較少

2.文檔實例較少

3.英文太多

4.要求PHP技術精通,OOP編程要熟練!

5.View並非理想view,理想中的view可能只是html代碼,不會涉及PHP代碼。

CodeIgniter
優勢:
推崇簡單,配置簡單,所有的配置使用PHP腳原本配置,執行效率高,快速簡潔,代碼很少,執行性能高,框架簡單,容易上手,學習成本低,文檔詳細;自帶了不少簡單好用的library,框架適合小型應用。
缺點:
內部結構過於混亂,雖然簡單易用,但缺少擴展能力。 把Model層簡單的理解爲數據庫操做. 框架略顯簡單,只可以知足小型應用,略微不太可以知足中型應用須要.

laravel框架的設計思想比較先進,很是適合應用各類開發模式,做爲一個框架,它爲你準備好了一切。 laravel框架最大的特色和優秀之處就是集合了php比較新的特色,以及各類各樣的設計模式,Ioc模式,依賴注入等。

  • 強大的rest router:用簡單的回調函數就能夠調用,快速綁定controller和router
  • artisan:命令行工具,不少手動的工做都自動化
  • 可繼承的模板,簡化view的開發和管理
  • blade模板:渲染速度更快
  • ORM操做數據庫
  • migration管理數據庫和版本控制
  • composer也是亮點
  • 測試功能也很強大
    缺點:
    基於組件式的框架,因此比較臃腫

三、數據庫優化

從結構層: web服務器採用負載均衡服務器,mysql服務器採用主從複製,讀寫分離
從儲存層: 採用合適的存儲引擎,採用三範式
從設計層: 採用分區分表,索引,表的字段採用合適的字段屬性,適當的採用逆範式,開啓mysql緩存
從sql語句層:結果同樣的狀況下,採用效率高、速度快節省資源的sql語句執行
負載均衡:

MySQL之間數據複製的基礎是二進制日誌文件(binary log file)。
Master 將改變記錄到二進制日誌中。
Slave 將 Master 的二進制日誌拷貝到它的中繼日誌( Relay_log )
Slave 重作中繼日誌中的事件,將改變反映它本身的數據

mysql主從複製用途
實時災備,用於故障切換
讀寫分離,提供查詢服務
備份,避免影響業務

主從部署必要條件:
主庫開啓binlog日誌(設置log-bin參數)
主從server-id不一樣
從庫服務器能連通主庫

原理:
主:log dump線程傳binlog;
從:i/o線程接受讀取binlog,並寫入relay log文件
sql線程從relay log 文件中讀取binlog並持久化

主從複製連接:blog.csdn.net/wangyuanjun…

四、如何處理負載、高併發

  • HTML靜態化
  • 圖片服務器分離
  • 數據庫集羣和庫表散列及緩存: 數據庫的併發鏈接爲100,一臺數據庫遠遠不夠,能夠從讀寫分離、主從複製,數據庫集羣方面來着手。另外儘可能減小數據庫的訪問,可使用緩存數據庫如memcache、redis。
  • 負載均衡: Apache的最大併發鏈接爲1500,只能增長服務器,能夠從硬件上着手,如F5服務器。固然硬件的成本比較高,咱們每每從軟件方面着手。

一、流量優化

(1) 防盜鏈處理(去除惡意請求)

(2) 控制大文件的下載。

(3) 確認服務器硬件是否足夠支持當前的流量

(4) 使用流量分析統計軟件

(5) 儘可能使用靜態頁,緩存

二、前端優化

(1) 減小HTTP請求[將css,js等合併]

(2) 添加異步請求(先不將全部數據都展現給用戶,用戶觸發某個事件,纔會異步請求數據)

(3) 啓用瀏覽器緩存和文件壓縮

(4) CDN加速

(5) 創建獨立的圖片服務器(減小I/O)

三、服務端優化

(1) 頁面靜態化

(2) 併發處理

(3) 隊列處理

四、數據庫優化

(1) 數據庫緩存

(2) 分庫分表,分區

(3) 讀寫分離

(4) 負載均衡

五、web服務器優化

(1) nginx反向代理實現負載均衡

(2) lvs實現負載均衡
原文:blog.csdn.net/m_nanle_xia…

悲觀鎖:
一般所說的「一鎖二查三更新」即指的是使用悲觀鎖。須要數據庫自己提供支持,即經過經常使用的select … for update操做來實現悲觀鎖。不一樣的數據庫對select for update的實現和支持都是有所區別的,select for update語句執行中全部掃描過的行都會被鎖上,這一點很容易形成問題。所以若是在mysql中用悲觀鎖務必要肯定走了索引,而不是全表掃描。

樂觀鎖:
在進行完業務操做須要實際更新數據的最後一步再去拿一下鎖就好。不須要數據庫提供特殊的支持。通常的作法是在須要鎖的數據上增長一個版本號或者時間戳:

1. SELECT data AS old_data, version AS old_version FROM …;
2. 根據獲取的數據進行業務操做,獲得new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
    // 樂觀鎖獲取成功,操做完成
} else {
    // 樂觀鎖獲取失敗,回滾並重試
}
複製代碼

高併發:www.cnblogs.com/phpper/p/67…

五、
mysql的默認端口

3306  
複製代碼

獲取IP地址

客戶端 — $_SERVER['REMOTE_ADDR'];  

服務器端 — $_SERVER["SERVER_ADDR"];

gethostname — 獲取主機名

ip2long — 將 IPV4 的字符串互聯網協議轉換成長整型數字

long2ip — 將長整型轉化爲字符串形式帶點的互聯網標準格式地址(IPV4)

例子:
$ip = gethostbyname('www.baidu.com'); //14.215.177.39
$ip2long = ip2long($ip); // 249016615

複製代碼

編碼轉換的函數

Iconv('utf-8', 'gb2312', $str);
複製代碼

六、架構類的東西
數據庫的讀寫分離、主從複製及集羣。

Nginx負載均衡

redis集羣及主從

七、session與cookie的區別
cookie數據存放在第三方應用的瀏覽器上,session數據放在服務器上。

cookie不是很安全,別人能夠分析存放在本地的COOKIE,進行COOKIE欺騙,考慮到安全應當使用session。

session會在必定時間內保存在服務器上。session用新的機制保持與客戶端的同步,不依賴於客戶端設置;會佔用服務器資源,加大服務器端的負載,尤爲當併發用戶不少時,會生成大量的session,影響服務器的性能,考慮到減輕服務器性能方面,應當使用COOKIE。session存儲的信息更敏感,並且是以文件形式保存在服務器中,所以仍然存在着安全隱患。

單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20個cookie。

SESSION存儲在服務器端,COOKIE保存在客戶端。Session比較安全,cookie用某些手段能夠修改,不安全。Session依賴於cookie進行傳遞。禁用cookie後,session還可使用,在存儲session的文件中,生成sessionID,經過get傳參的方式將sessionID傳到要實現session共享的頁面,讀取sessionID,從而從session中獲取數據。

關閉cookie,使用session的方法

  1. 設置php.ini配置文件中的「session.use_trans_sid = 1」,或者編譯時打開打開了「--enable-trans-sid」選項,讓PHP自動跨頁傳遞Session ID。
  2. 手動經過URL傳值、隱藏表單傳遞Session ID。
  3. 用文件、數據庫等形式保存Session ID,在跨頁過程當中手動調用。

總結一下,上面的方法有一個共同點,就是在前一頁取得Session ID,而後想辦法傳遞到下一頁,在下一頁的session_start();代碼以前加代碼Session ID(傳過來的Session ID)。

因此我的建議:
將登錄信息等重要信息存放爲SESSION
其餘信息若是須要保留,能夠放在COOKIE

八、抽象類是一種不能被實例化的類,只能做爲其餘類的父類來使用。抽象類是經過關鍵字abstract來聲明的。
抽象類與普通類類似,都包含成員變量和成員方法,二者的區別在於,抽象類中至少要包含一個抽象方法,抽象方法沒有方法體,該方法天生就是要被子類重寫的。 抽象方法的格式爲:abstract function abstractMethod()

接口是經過 interface 關鍵字來聲明的,接口中的成員常量和方法都是 public 的,方法能夠不寫關鍵字public,接口中的方法也是沒有方法體。接口中的方法也天生就是要被子類實現的。

抽象類和接口實現的功能十分類似,最大的不一樣是接口能實現多繼承。在應用中選擇抽象類仍是接口要看具體實現。 子類繼承抽象類使用 extends,子類實現接口使用implements。

接口中不能夠聲明變量,但能夠聲明類常量。抽象類中能夠聲明各類變量

接口沒有構造函數,抽象類能夠有

接口中的方法默認爲public,抽象類中的方法能夠用public、protected、private修飾

一個類能夠繼承多個接口,但只能繼承一個抽象類

含有抽象方法的類不必定是抽象類

抽象類

<?php
abstract class Animal {
  public $name;
  abstract public function eat($food);
}
?>

<?php
class Whale extends Animal {
  public function __construct() {
    $this->name = "Whale";
  }
  public function eat($food) {
    echo $this->name . " eat " . $food . ".\n";
  }
}
?>

<?php
  $whale = new Whale();
  $whale->eat("fish");
?>
複製代碼

接口

<?php
interface IAction {
  public function eat($food);
  public function swim();
}
?>

<?php
class Whale implements IAction {
  public function eat($food) {
    echo "Whale eat " . $food . "\n.";
  }
  public swim() {
    echo "Whale is swimming.\n";
  }
}
?>

<?php
  $whale = new Whale();
  $whale->eat("fish");
?>
複製代碼
interface Eat
{
    public function eat();
}

class Pig implements Eat
{
    public function eat()
    {
        echo 'pig eat ...';
    }
}

class Cat implements Eat
{
    public function eat()
    {
        echo 'cat eat ....';
    }
}

class Test
{
    function aa(Eat $animal)
    {
        $animal->eat();
    }
}
$test = new Test();
$pig = new Pig();
$cat = new Cat();
$test->aa($pig);
$test->aa($cat);
複製代碼

抽象用於不一樣的事物,而接口用於事物的行爲。 如:水生生物是鯨魚的抽象概念,可是水生生物並非鯨魚的行爲,吃東西纔是鯨魚的行爲。 對於大型項目來講,對象都是由基本的抽象類繼承實現,而這些類的方法一般都由接口來定義。 此外,對於事物屬性的更改,建議使用接口,而不是直接賦值或者別的方式,

九、MySQL設計之三範式
第一範式(1NF):字段具備原子性,不可再分。 全部關係型數據庫系統都知足第一範式, 數據庫表中的字段都是單一屬性的, 不可再分。 例如, 姓名字段, 其中的姓和名必須做爲一個總體, 沒法區分哪部分是姓, 哪部分是名, 若是要區分出姓和名, 必須設計成兩個獨立的字段。

第二範式(2NF):要求數據庫表中的每一個實例或行必須能夠被惟一區分。 一般須要爲表加上一個列, 以存儲各個實例的唯一標識。 這個唯一屬性列被稱爲主關鍵字或主鍵。

第三範式(3NF):要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。

總結
一、 每一列只有一個值(字段不可分)
二、 每一行都能區分。(有主鍵,非主鍵字段依賴主鍵)
三、 每個表都不包含其餘表已經包含的非主關鍵字信息。

反三範式
沒有冗餘的數據庫未必是最好的數據庫,有時爲了提升運行效率,提升讀性能,就必須下降範式標準,適當保留冗餘數據。 在概念數據模型設計時遵照第三範式,下降範式標準的工做放到物理數據模型設計時考慮。下降範式就是增長字段,減小了查詢時的關聯,提升查詢效率,由於在數據庫的操做中查詢的比例要遠遠大於DML的比例。可是反範式化必定要適度,而且在本來已知足三範式的基礎上再作調整的。

十、一種是表鎖定(myisam存儲引擎),一個是行鎖定(innodb存儲引擎)
一、存儲引擎的使用不一樣,冷數據使用MyIsam 能夠有更好的查詢數據。活躍數據,可使用Innodb ,能夠有更好的更新速度。
二、對冷數據進行更多的從庫配置,由於更多的操做是查詢,這樣來加快查詢速度。對熱數據,能夠相對有更多的主庫的橫向分表處理。
三、對於一些特殊的活躍數據,也能夠考慮使用memcache 、redis之類的緩存,等累計到必定量再去更新數據庫.

十一、數據庫引擎

InnoDB:支持事務處理,支持外鍵,支持崩潰修復能力和併發控制。若是須要對事務的完整性要求比較高(好比銀行),要求實現併發控制(好比售票),那選擇InnoDB有很大的優點。若是須要頻繁的更新、刪除操做的數據庫,也能夠選擇InnoDB,由於支持事務的提交(commit)和回滾(rollback)。

MyISAM:插入數據快,空間和內存使用比較低。若是表主要是用於插入新記錄和讀出記錄,那麼選擇MyISAM能實現處理高效率。若是應用的完整性、併發性要求比較低,也可使用。

MEMORY:全部的數據都在內存中,數據的處理速度快,可是安全性不高。若是須要很快的讀寫速度,對數據的安全性要求較低,能夠選擇MEMOEY。它對錶的大小有要求,不能創建太大的表。因此,這類數據庫只使用在相對較小的數據庫表。

merge:用於日誌和數據倉庫

archive:用於日誌,只有select和insert,不支持索引。

注意,同一個數據庫也可使用多種存儲引擎的表。若是一個表要求比較高的事務處理,能夠選擇InnoDB。這個數據庫中能夠將查詢要求比較高的表選擇MyISAM存儲。若是該數據庫須要一個用於查詢的臨時表,能夠選擇MEMORY存儲引擎。

InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如update table set num=1 where name like 「a%」

就是說在不肯定的範圍時,InnoDB仍是會鎖表的。

如下兩點必須使用InnoDB:

1)可靠性高或者要求事務處理,則使用InnoDB。這個是必須的。

2)表更新和查詢都至關的頻繁,而且表鎖定的機會比較大的狀況指定InnoDB數據引擎的建立。

對比之下,MyISAM的使用場景:

1)作不少count的計算的。如一些日誌,調查的業務表。

2)插入修改不頻繁,查詢很是頻繁的。

十二、數據庫事務
事務是指做爲單個邏輯工做單元執行的一系列操做,能夠被看做一個單元的一系列SQL語句的集合。要麼徹底地執行,要麼徹底地不執行。 若是不進行併發控制,可能會產生髒讀、非重複讀、幻像讀、丟失修改的異常狀況。
事務的特性(ACID):
A、atomacity 原子性(全部過程要麼都執行,要麼都不執行。若是異常了那麼回滾)
C、consistency 一致性(例如轉帳前轉帳後的總額度不變)
I、isolation 隔離性(只要事務尚未提交,數據都不會有變化)
D、durability 持久性(事務提交,必定發生變化)

1三、事物隔離是基於鎖實現的。
在DBMS中,能夠把數據庫鎖分爲行級鎖(INNODB引擎)表級鎖(MYISAM引擎)頁級鎖(BDB引擎)

行級鎖是Mysql中鎖定粒度最細的一種鎖,表示只針對當前操做的行進行加鎖。行級鎖能大大減小數據庫操做的衝突。其加鎖粒度最小,但加鎖的開銷也最大。行級鎖分爲共享鎖和排他鎖。特色是開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。

表級鎖是MySQL中鎖定粒度最大的一種鎖,表示對當前操做的整張表加鎖,實現簡單,資源消耗較少,被大部分MySQL引擎支持。MYISAM與INNODB都支持表級鎖定。表級鎖定分爲表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。特色是開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發出鎖衝突的機率最高,併發度最低。

頁級鎖是MySQL中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。因此取了折中的頁級,一次鎖定相鄰的一組記錄。 特色是開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常

1四、分區分表

分區:就是把一個數據表的文件和索引分散存儲在不一樣的物理文件中。 表分區,是指根據必定規則,將數據庫中的一張表分解成多個更小的、容易管理的部分。從邏輯上看,只有一張表,可是底層倒是由多個物理分區組成。

分表:指的是經過必定規則,將一張表分解成多張不一樣的表,每個小表都是完正的一張表,都對應三個文件(MyISAM引擎:一個.MYD數據文件,.MYI索引文件,.frm表結構文件)。好比將用戶訂單記錄根據時間成多個表。

分表與分區的區別:
實現方式上:分區從邏輯上來說只有一張表,而分表則是將一張表分解成多張表。

數據處理上:分表後數據都是存放在分表裏,總表只是一個外殼,存取數據發生在一個一個的分表裏面。分區則不存在分表的概念,分區只不過把存放數據的文件分紅了許多小塊,分區後的表仍是一張表,數據處理仍是由本身來完成。

提升性能上:分表後,單表的併發能力提升了,磁盤I/O性能也提升了。分區突破了磁盤I/O瓶頸,想提升磁盤的讀寫能力,來增長mysql性能。
在這一點上,分區和分表的測重點不一樣,分表重點是存取數據時,如何提升mysql併發能力上;而分區呢,如何突破磁盤的讀寫能力,從而達到提升mysql性能的目的。

實現的難易度上:分表的方法有不少,用merge來分表,是最簡單的一種方式。這種方式和分區難易度差很少,而且對程序代碼來講能夠作到透明的。若是是用其餘分表方式就比分區麻煩了。 分區實現是比較簡單的,創建分區表,跟建日常的表沒什麼區別,而且對代碼端來講是透明的。 分區和分表的目的就是減小數據庫的執行負擔,穩定SQL性能。

分區
mysql支持的分區類型包括Range、List、Hash、Key

CREATE TABLE user (
	id INT NOT NULL auto_increment,
	username VARCHAR (10),
	PRIMARY KEY (id)
) ENGINE = INNODB charset = utf8 PARTITION BY RANGE (id)(
	PARTITION user_1 VALUES less than (10),
	PARTITION user_2 VALUES less than (20),
	PARTITION user_3 VALUES less than MAXVALUE
);
複製代碼

表分區好處:
1)分區表的數據能夠分佈在不一樣的物理設備上,從而高效地利用多個硬件設備。
2)和單個磁盤或者文件系統相比,能夠存儲更多數據
3)優化查詢。在where語句中包含分區條件時,能夠只掃描一個或多個分區表來提升查詢效率;涉及sum和count語句時,也能夠在多個分區上並行處理,最後彙總結果。
4)分區表更容易維護。例如:想批量刪除大量數據能夠清除整個分區。
5)可使用分區表來避免某些特殊的瓶頸,例如InnoDB的單個索引的互斥訪問,ext3問價你係統的inode鎖競爭等。

分區的限制:

  • 主鍵或者惟一索引必須包含分區字段,如primary key (id,username),不過innoDB的大組建性能很差。
  • 不少時候,使用分區就不要在使用主鍵了,不然可能影響性能。
  • 只能經過int類型的字段或者返回int類型的表達式來分區,一般使用year或者to_days等函數(mysql 5.6 對限制開始放開了)。
  • 每一個表最多1024個分區,並且多分區會大量消耗內存。
  • 分區的表不支持外鍵,相關的邏輯約束須要使用程序來實現。
  • 分區後,可能會形成索引失效,須要驗證分區可行性。

分表

// 建立一個完整表存儲着全部的成員信息
CREATE TABLE `member` (
`id`  int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`name`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET = utf8 AUTO_INCREMENT = 1;

// 插入數據(第2條語句多執行幾回就有了不少數據):
insert into member(name) values('a');
insert into member(name) select name from member;

// 建立兩個分表tb_member1,tb_member2
DROP TABLE IF EXISTS tb_member1;
CREATE TABLE tb_member1 (
`id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR (20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE = MyISAM DEFAULT CHARSET = utf8 AUTO_INCREMENT = 1;

DROP TABLE IF EXISTS tb_member2;
CREATE TABLE tb_member2 LIKE tb_member1;

// 建立主表tb_member
DROP TABLE IF EXISTS tb_member;
CREATE TABLE tb_member (
`id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR (20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE = MERGE UNION = (tb_member1, tb_member2) INSERT_METHOD = LAST CHARSET = utf8 AUTO_INCREMENT = 1;

// 把數據分到兩個分表中去
insert into tb_member1(id, name) select id,name from member where id%2=0;
insert into tb_member2(id, name) select id,name from member where id%2=1;
複製代碼

分表存在的問題:

  • 跨庫跨表的join問題
  • 額外的數據管理負擔和數據運算壓力(數據的定位問題和數據的增刪改查的重複執行問題)

分表的幾種常見方法:

  • 預先估計某個大表的數據量,將其均分爲固定數量表(自增id取模、自增id兩位尾數取模、對某個字段進行hash)
  • 時間增加較快的數據能夠按時間拆分(按天、按月、按年等)
  • 按每一個表固定記錄行數拆分
  • 將好久以前的數據遷移到一張歷史表

分表連接:www.cnblogs.com/johnnyzhang…

1五、MySQL索引:
聯合索引(複合索引)由兩個或多個列的索引,可只使用索引中的一部分,更準確地說是最左側部分(最左優先)
前綴索引對於列的值較長,好比BLOB、TEXT、VARCHAR,可創建前綴索引,即將值的前一部分做爲索引
覆蓋索引查詢時只用去讀取索引而取得數據,無需進行二次查詢相關表,對於一個索引覆蓋查詢,經過使用explain,extra顯示爲using index來判斷

假設創建有順序的:c1,c2,c3,c4 這4個索引

  • 在等值查詢時,更改索引列順序,不會影響explain的執行結果,由於mysql底層會進行優化,可是推薦按照索引順序列編寫sql語句。
  • 在使用order by時,注意索引順序、常量,以及可能會致使Using filesort的狀況
  • 範圍右邊索引列失效,可是範圍當前位置的索引是有效的
  • 範圍右邊索引列失效,是有順序的:c1,c2,c3,c4,若是c3有範圍,則c4失效;若是c4有範圍,則沒有失效的索引列,從而會使用所有索引。
  • 在最佳左前綴法則中,若是最左前列的索引失效,則後面的索引都失效。
  • 利用最佳左前綴法則:中間不能斷,用到了c1和c2索引(查找),c3索引列用在排序過程當中。
  • group by容易產生Using temporary

通俗理解口訣:

全值匹配我最愛,最左前綴要遵照;

帶頭大哥不能死,中間兄弟不能斷;

索引列上少計算範圍以後全失效;

LIKE百分寫最右,覆蓋索引不寫星;

不等空值還有or,索引失效要少用。

參見:www.cnblogs.com/morewindows…

索引長度計算:
1.全部的索引字段,若是沒有設置not null,則須要加一個字節。
2.定長字段,int佔四個字節、date佔三個字節、char(n)佔n個字符。
3.對於變成字段varchar(n),則有n個字符+兩個字節。
4.不一樣的字符集,一個字符佔用的字節數不一樣。latin1編碼的,一個字符佔用一個字節,gbk編碼的,一個字符佔用兩個字節,utf8編碼的,一個字符佔用三個字節。

1六、

// 鏈接
$dbhost = 'localhost';  // mysql服務器主機地址
$dbuser = 'root';            // mysql用戶名
$dbpass = '';          // mysql用戶名密碼
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if (!$conn) {
    die('Could not connect: ' . mysqli_error());
}
echo '數據庫鏈接成功!';


// 設置編碼,防止中文亂碼
mysqli_query($conn , "set names utf8");
 
$sql = 'SELECT id, name FROM user';
 
mysqli_select_db($conn, 'test');
$retval = mysqli_query($conn, $sql);
if(!$retval)
{
    die('沒法讀取數據: ' . mysqli_error($conn));
}

while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC)) {
    print_r($row);
}

// 釋放內存
mysqli_free_result($retval);
mysqli_close($conn);
複製代碼

1七、冒泡排序
如數組:$sort = [6,1,2,4,5,3]; 進行冒泡排序(從小到大)

第一輪:
 第一次:1,6,2,4,5,3
 第二次:1,2,6,4,5,3
 第三次:1,2,4,6,5,3
 第四次:1,2,4,5,6,3
 第五次:1,2,4,5,3,6

第二輪:
 第一次:1,2,4,5,3,6
 第二次:1,2,4,5,3,6
 第三次:1,2,4,5,3,6
 第四次:1,2,4,3,5,6

第三輪:
 第一次:1,2,4,3,5,6
 第二次:1,2,4,3,5,6
 第三次:1,2,3,4,5,6

第四輪:
 第一次:1,2,3,4,5,6
 第二次:1,2,3,4,5,6

第五輪:
 第一次:1,2,3,4,5,6

<?php
$arr = [6, 7, 3, 5, 9, 10, 1];
$length = count($arr);
// 輪
for ($i = 1; $i < $length; $i++) {
    // 次
    for ($j = 0; $j < $length - $i; $j++) {
    	if ($arr[$j] > $arr[$j + 1]) {
            $tmp = $arr[$j];
            $arr[$j] = $arr[$j + 1];
            $arr[$j + 1] = $tmp;
    	}
    }
}
echo '<pre>';
print_r($arr);
複製代碼

1八、遍歷出文件夾和他下面子文件的代碼

function getAllFile($dir) {
    $allFileArr = [];
    if (is_dir($dir)) {
        $res = opendir($dir);
        while ($row = readdir($res)) {
            if ($row == '.' || $row == '..') {
                continue;
            }
            if (is_file($dir . '/' . $row)) {
                $allFileArr[] = $row;
            } else if (is_dir($dir . '/' . $row)) {
                $allFileArr[$row] = getAllFile($dir . '/' . $row);
            }
        }
        closedir($res);
    }
    return $allFileArr;
}

$dir = 'E:\ruanjian\wamp64\www\learn';
echo '<pre>';
print_r(getAllFile($dir));
複製代碼

1九、如何防止SQL注入,XSS攻擊和CSRF攻擊

SQL注入:mysqli_real_escape_string()轉義關鍵字符;

CSRF攻擊:跨站攻擊。防止:token、驗證碼

XSS攻擊:alert把一些cookie信息打印出來;
過濾掉<>等關鍵字符串;
對數據解碼,再過濾掉危險標籤、屬性和事件等;
DOM XSS的發生主要是在JS中使用eval形成的,因此應當避免使用eval語句
複製代碼

XSS危害

  • 經過document.cookie盜取cookie
  • 使用js或css破壞頁面正常的結構與樣式
  • 流量劫持(經過訪問某段具備window.location.href定位到其餘頁面)
  • Dos攻擊:利用合理的客戶端請求來佔用過多的服務器資源,從而使合法用戶沒法獲得服務器響應。
  • 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執行一些管理動做,或執行一些通常的如發微博、加好友、發私信等操做。
  • 利用可被攻擊的域受到其餘域信任的特色,以受信任來源的身份請求一些平時不容許的操做,如進行不當的投票活動。

20、PHP程序工做的具體過程

  PHP的運行原理就是Apache、PHP、瀏覽器之間的協做過程:

  ①當用戶在瀏覽器地址中輸入要訪問的PHP頁面文件名,而後回車就會觸發這個PHP請求,並將請求傳送化支持PHP的WEB服務器(apache)。

  ②WEB服務器(apache)接受這個請求,並根據其後綴進行判斷若是是一個PHP請求,WEB服務器(apache)從硬盤或內存中取出用戶要訪問的PHP應用程序,並將其發送給PHP引擎程序。

  ③PHP引擎程序將會對WEB服務器(apache)傳送過來的文件從頭至尾進行掃描並根據命令從後臺讀取,處理數據,並動態地生成相應的HTML頁面。

  ④PHP引擎將生成HTML頁面返回給WEB服務器(apache)。WEB服務器(apache)再將HTML頁面返回給客戶端瀏覽器,最後一個完整的頁面基於經過瀏覽器展示在咱們眼前。

2一、HTTP協議
HTTP請求由三個部分組成,分別是:請求行、請求頭部、空行和請求正文。
HTTP響應由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。
第一部分:狀態行,由HTTP協議版本號、狀態碼、狀態消息三部分組成。
第一行爲狀態行,(HTTP/1.1)代表HTTP版本爲1.1版本,狀態碼爲200,狀態消息爲(ok)

第二部分:消息報頭,用來講明客戶端要使用的一些附加信息
第二行和第三行爲消息報頭, Date:生成響應的日期和時間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8
第三部分:空行,消息報頭後面的空行是必須的
第四部分:響應正文,服務器返回給客戶端的文本信息。
空行後面的html部分爲響應正文。

請求類型GET、POST、HEAD 1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE

HTTP請求報文頭屬性:
Accept:告訴服務端 客戶端接受什麼類型的響應。
Cookie:客戶端的Cookie就是經過這個報文頭屬性傳給服務端的
Referer:表示這個請求是從哪一個URL過來的,假如你經過google搜索出一個商家的廣告頁面,你對這個廣告頁面感興趣,鼠標一點發送一個請求報文到商家的網站,這個請求報文的Referer報文頭屬性值就是http://www.google.com。
Cache-Control:對緩存進行控制

HTTP響應報文頭屬性:
Cache-Control:響應輸出到客戶端後,服務端經過該報文頭屬告訴客戶端如何控制響應內容的緩存
ETag:一個表明響應服務端資源(如頁面)版本的報文頭屬性,若是某個服務端資源發生變化了,這個ETag就會相應發生變化。它是Cache-Control的有益補充,可讓客戶端「更智能」地處理何時要從服務端取資源,何時能夠直接從緩存中返回響應。
Location:讓頁面Redirect到一個某個A頁面中,實際上是讓客戶端再發一個請求到A頁面,這個須要Redirect到的A頁面的URL,其實就是經過響應報文頭的Location屬性告知客戶端的
Set-Cookie:服務端能夠設置客戶端的Cookie

常見狀態碼
1xx 消息,通常是告訴客戶端,請求已經收到了,正在處理,別急...
2xx 處理成功,通常表示:請求收悉、我明白你要的、請求已受理、已經處理完成等信息.
3xx 重定向到其它地方。它讓客戶端再發起一個請求以完成整個處理。
4xx 處理髮生錯誤,責任在客戶端,如客戶端的請求一個不存在的資源,客戶端未被受權,禁止訪問等。
5xx 處理髮生錯誤,責任在服務端,如服務端拋出異常,路由出錯,HTTP版本不支持等。

具體以下:
2XX系列:表明請求已成功被服務器接收、理解、並接受。
200狀態碼:請求已成功,請求所但願的響應頭或數據體將隨此響應返回
201狀態碼:表示請求成功而且服務器建立了新的資源,且其 URI 已經隨Location 頭信息返回。假如須要的資源沒法及時創建的話,應當返回 '202 Accepted'

4XX系列:表示請求錯誤。表明了客戶端看起來可能發生了錯誤,妨礙了服務器的處理。
401狀態碼:請求要求身份驗證。對於須要登陸的網頁,服務器可能返回此響應。
403狀態碼:服務器已經理解請求,可是拒絕執行它。與401響應不一樣的是,身份驗證並不能提供任何幫助,並且這個請求也不該該被重複提交。
404狀態碼:請求失敗,請求所但願獲得的資源未被在服務器上發現。

5xx系列:表明了服務器在處理請求的過程當中有錯誤或者異常狀態發生,也有多是服務器意識到以當前的軟硬件資源沒法完成對請求的處理。
500狀態碼:服務器遇到了一個不曾預料的情況,致使了它沒法完成對請求的處理。通常來講,這個問題都會在服務器的程序碼出錯時出現。
503狀態碼:因爲臨時的服務器維護或者過載,服務器當前沒法處理請求。

blog.csdn.net/u010256388/… 2二、設計模式
參考連接:www.cnblogs.com/leedaily/p/…

2三、向php腳本傳遞參數:

  • php -r "var_dump($argv);" -- -h(若是要傳遞的參數開頭爲-,那麼得使用參數列表分隔符 -- 才能正確傳參)
  • test.php 假設該文件在當前目錄下,代碼:
#!/usr/bin/php 
<?php var_dump($argv);?>    

// 在php文件開頭加入#!/usr/bin/php,便可直接傳遞以-爲開頭得參數
./test.php -h -- foo  
複製代碼

2四、redis和memcached區別

  • redis 系統庫有個快照,即忽然斷電,數據還會存在,而memached 就沒了
  • memcached 是簡單的鍵值對,Key-Value, redis 支持的存儲方式(字符串,雙向鏈表,哈希,集合,有序集合)不少,應用場景不少
  • redis 性能比memached 要高
  • Memcached是多線程,非阻塞IO複用的網絡模型;Redis使用單線程的多路 IO 複用模型。

2五、SQL注入
SQL注入攻擊是黑客對數據庫進行攻擊的經常使用手段之一。在編寫代碼的時候,沒有對用戶輸入數據的合法性進行判斷,注入者能夠在表單中輸入一段數據庫查詢代碼並提交,程序將提交的信息拼湊生成一個完整sql語句,服務器被欺騙而執行該條惡意的SQL命令。注入者根據程序返回的結果,成功獲取一些敏感數據,甚至控制整個服務器,這就是SQL注入。

2六、HTTP與HTTPS的區別?
HTTP協議傳輸的數據都是未加密的,也就是明文的,所以使用HTTP協議傳輸隱私信息很是不安全,爲了保證這些隱私數據能加密傳輸,因而網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來講,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。 HTTPS和HTTP的區別主要以下:

  • https協議須要到ca申請證書,通常免費證書較少,於是須要必定費用。
  • http是超文本傳輸協議,信息是明文傳輸,https則是具備安全性的ssl加密傳輸協議。
  • http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。
  • http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

2七、從輸入URL到頁面加載發生了什麼
segmentfault.com/a/119000000…

2八、消息隊列
從本質上說消息隊列就是一個隊列結構的中間件,也就是說消息放入這個中間件以後就能夠直接返回,並不須要系統當即處理,而另外會有一個程序讀取這些數據,並按順序進行逐次處理。
也就是說當你遇到一個併發特別大而且耗時特別長同時還不須要當即返回處理結果,使用消息隊列能夠解決這類問題。

業務系統入隊->消息隊列出隊->隊列處理系統
由一個業務系統進行入隊,把消息逐次插入到消息隊列中,插入成功以後直接返回成功的結果,後續會有一個消息處理系統,這個系統會把消息系統中的記錄逐次進行取出並進行處理,完成一個出隊的流程。

www.cnblogs.com/dump/p/8243…

2九、定時腳本
blog.csdn.net/xf_come_on/…

30、網絡7層協議
7 應用層
6 表示層
5 會話層
4 傳輸層
3 網絡層
2 數據鏈路層
1 物理層
七、六、五、4層定義了應用程序的功能
三、二、1層主要面向經過網絡的端到端的數據流

TCP UDP
是否鏈接 面向鏈接 面向非鏈接
傳入可靠性 可靠 不可靠
引用場景 傳輸大量數據 傳輸小量數據
速度
舉例 銀行 windows的ping命令 qq發消息

HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎,也是手機聯網經常使用的協議之一,HTTP協議是創建在TCP協議之上的一種應用。因爲HTTP在每次請求結束後都會主動釋放鏈接,所以HTTP鏈接是一種「短鏈接」。
Socket其實並非一個協議,而是爲了方便使用TCP或UDP而抽象出來的一層,是位於應用層和傳輸控制層之間的一組接口。建立Socket鏈接時,能夠指定使用的傳輸層協議,Socket能夠支持不一樣的傳輸層協議(TCP或UDP),當使用TCP協議進行鏈接時,該Socket鏈接就是一個TCP鏈接。

WebSocket同HTTP同樣也是應用層的協議,可是它是一種雙向通訊協議,是創建在TCP之上的。在WebSocket中,只須要服務器和瀏覽器經過HTTP協議進行一個握手的動做,而後單獨創建一條TCP的通訊通道進行數據的傳送。

http和scoket區別:
HTTP是基於應用層,socket是基於傳輸層(tcp/udp)

HTTP鏈接使用的是"請求—響應"的方式,不只在請求時須要先創建鏈接,並且須要客戶端向服務器發出請求後,服務器端才能回覆數據。在請求結束後,會主動釋放鏈接。
一般狀況下Socket鏈接就是TCP鏈接,所以Socket鏈接一旦創建,通訊雙方便可開始相互發送數據內容,直到雙方鏈接斷開。

視頻,圖片,斷點續傳的狀況下要用socket,http的協議的無狀態性實現不了這個功能。

http不斷請求發送的缺點:會致使過多沒必要要的請求,浪費流量和服務器資源,每一次請求、應答,都浪費了必定流量在相同的頭部信息上

WebSocket與HTTP的相同點:
一、都是同樣基於TCP的,都是可靠性傳輸協議。
二、都是應用層協議
不一樣點:
一、WebSocket是雙向通訊協議,模擬Socket協議,能夠雙向發送或接受信息。HTTP是單向的。
二、WebSocket是須要握手進行創建鏈接的。

3一、 mysql時間
date_sub('2012-05-25',interval 1 day) 表示 2012-05-24
date_sub('2012-05-25',interval 0 day) 表示 2012-05-25
date_sub('2012-05-25',interval -1 day) 表示 2012-05-26
date_sub(curdate(),interval 1 day) 表示 2013-05-19
date_sub(curdate(),interval -1 day) 表示 2013-05-21
date_sub(curdate(),interval 1 month) 表示 2013-04-20
date_sub(curdate(),interval -1 month) 表示 2013-06-20
date_sub(curdate(),interval 1 year) 表示 2012-05-20
date_sub(curdate(),interval -1 year) 表示 2014-05-20

// 獲取昨天 跟 今天 00:00:00的 時間戳
select unix_timestamp(DATE_SUB(CURDATE(),INTERVAL 1 day)), unix_timestamp(date_sub(curdate(), interval 0 day));

// 日期轉時間戳
SELECT UNIX_TIMESTAMP('2018-10-31');

// 時間戳轉日期
select FROM_UNIXTIME(1540915200, '%Y-%m-%d');

3二、

//奇偶數
$a = [6, 7, 8, 9];
$arr = array_filter($a, function ($v) {
    return ($v & 1);
});
返回:
[
  1 => 7
  3 => 9
]

第一種:
$file = 'E:\php1\wamp64\www\test.txt';
$content = file($file);
foreach ($content as $key => $value) {
    $value = mb_convert_encoding($value, 'utf-8', 'gbk');
    $v = explode("\t", $value);
}

第二種:
$handle = fopen($file, 'r');
if ($handle) {
    while (($row = fgets($handle)) !== false) {
        $row = mb_convert_encoding($row, 'utf-8', 'gbk');
        $v = explode("\t", $row);
    }
    fclose($handle);
}

// 當前月份的第一天跟最後一天
$monthFirstDay = date('Y-m-01', strtotime(date("Y-m-d")));
$monthLastDay = date('Y-m-d', strtotime($monthFirstDay . ' +1 month -1 day'));

// 指定日期的上個月的最後一天
$lastDay = date('Y-m-t', strtotime('last month', strtotime('20181116'))); //2018-10-31

$arr = range('a', 'z');
$str = implode($arr);// abcdefghijklmnopqrstuvwxyz

$a = "aa";
$b = "bb";
// 交換兩個變量的值
var_dump([$a, $b]); // ['aa', 'bb']
list($a, $b) = [$b, $a];
var_dump([$a, $b]); ['bb', 'aa']

// 反轉字符串
function mb_strrev($str)
{
    $r = '';
    for ($i = mb_strlen($str); $i >= 0; $i--) {
        $r .= mb_substr($str, $i, 1);
    }
    return $r;
}
echo mb_strrev("☆❤world我"); 
// 我dlrow❤☆
複製代碼
echo mb_internal_encoding(); // UTF-8
$str = "AB. cb 測試的"; 
echo strlen($str);//一個UTF8的中文字符=3個字節,因此爲3+1+2+1+9=16
echo mb_strlen($str, "utf-8");//UTF-8會將中文字符當成一個字符,因此爲3+1+2+1+3=10
echo mb_strlen($str, "gbk");//gbk,一箇中文字符當成1.5個字符,3+1+2+1+4.5=11.5
複製代碼
empty() 能夠用來斷定全部的數據類型是否爲空或假,而 is_null 與 isset 基本同樣,只能用來判斷是否爲NULL和未定義。
複製代碼
echo count(strlen('https://www.baidu.com/'));
// 結果:1,count(var)是用來統計數組或對象的元素個數的。當var是null或者空數組時,結果爲0。若是var是普通變量,則返回1。正常狀況下返回var中的元素或屬性個數。
複製代碼

PHP不鼓勵加結束標籤
能夠避免在 PHP 結束標記以後萬一意外加入了空格或者換行符,會致使 PHP 開始輸出這些空白
影響最多的時候應該是在使用 include 和 require 的時候,加告終束標籤若是又在後面加了空格都有可能會引發多餘的輸出、php錯誤、以後的輸出沒法顯示、空白頁,由於session_start()之類的函數的緣由(HTTP報文是header在前,body在後。當你在session_start()以前有了body輸出,就不能再設定header set-cookie了,而session就是依賴cookie)

CGI 表明爲了聯繫PHP 和 Web Server 的一個橋樑
fastCGI 是CGI的改良版
PHP-FPM 進程管理器

CGI:是 Web Server 與 Web Application 之間數據交換的一種協議。
FastCGI:同 CGI,是一種通訊協議,但比 CGI 在效率上作了一些優化。一樣,SCGI 協議與 FastCGI 相似。
PHP-CGI:是 PHP 對 Web Server 提供的 CGI 協議的接口程序。
PHP-FPM:是 PHP 對 Web Server 提供的 FastCGI 協議的接口程序,額外還提供了相對智能一些任務管理。

WEB 中,
Web Server 通常指Apache、Nginx、IIS、Lighttpd、Tomcat等服務器, Web Application 通常指PHP、Java、Asp.net等應用程序。

3四、jsonp

$.ajax({
    type: 'get',
    async: false,
    url: "http://test.com/learn/jsonp.php",
    dataType: 'jsonp',
    jsonp: 'callback', // 傳遞給請求處理程序或頁面的,用以得到jsonp回調函數名的參數名(通常默認爲:callback)
    jsonpCallBack: 'callbackFun', // 自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名,也能夠寫"?",jQuery會自動爲你處理數據
    success: function (res) {
        console.log(res)
    },
    error: function () {
        console.log('fail')
    }
})


jsonp.php頁面

header('Content-type: application/json');
$callback = htmlspecialchars($_REQUEST['callback']);
$jsonData = json_encode(['id' => 1, 'name' => '小貓咪']);
echo $callback . '(' . $jsonData . ')';
exit;
複製代碼

依賴注入
ORM
mysql主從複製 讀寫分離
分佈式
單元測試

其餘面試題網址:
www.cnblogs.com/gaowei521/p…

相關文章
相關標籤/搜索