做者:PHP學習網 出處:https://www.viphper.com/?p=1236 本文版權歸做者,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。php
公司出了一些自我評測的PHP題目,現將題目和答案記錄於此,以方便記憶。mysql
1. 魔術函數有哪些,分別在何時調用?
__construct(),類的構造函數
__destruct(),類的析構函數
__call(),在對象中調用一個不可訪問方法時調用
__callStatic(),用靜態方式中調用一個不可訪問方法時調用
__get(),得到一個類的成員變量時調用
__set(),設置一個類的成員變量時調用
__isset(),當對不可訪問屬性調用isset()或empty()時調用
__unset(),當對不可訪問屬性調用unset()時被調用。
__sleep(),執行serialize()時,先會調用這個函數
__wakeup(),執行unserialize()時,先會調用這個函數
__toString(),類被當成字符串時的迴應方法
__invoke(),調用函數的方式調用一個對象時的迴應方法
__set_state(),調用var_export()導出類時,此靜態方法會被調用。
__clone(),當對象複製完成時調用redis
2.isset和empty函數有什麼區別?算法
PHP的isset()函數 通常用來檢測變量是否設置
格式:bool isset ( mixed var [, mixed var [, ...]] )sql
功能:檢測變量是否設置數據庫
返回值:緩存
若變量不存在則返回 FALSE
若變量存在且其值爲NULL,也返回 FALSE
若變量存在且值不爲NULL,則返回 TURE
同時檢查多個變量時,每一個單項都符合上一條要求時才返回 TRUE,不然結果爲 FALSE
版本:PHP 3, PHP 4, PHP 5
更多說明:
使用 unset() 釋放變量以後,它將再也不是 isset()。
PHP函數isset()只能用於變量,傳遞任何其它參數都將形成解析錯誤。
檢測常量是否已設置可以使用 defined() 函數。安全
PHP的empty()函數 判斷值爲否爲空性能優化
格式:bool empty ( mixed var )服務器
功能:檢查一個變量是否爲空
返回值:
若變量不存在則返回 TRUE
若變量存在且其值爲""、0、"0"、NULL、、FALSE、array()、var $var; 以及沒有任何屬性的對象,則返回 TURE
若變量存在且值不爲""、0、"0"、NULL、、FALSE、array()、var $var; 以及沒有任何屬性的對象,則返回 FALSE
版本:PHP 3, PHP 4, PHP 5
更多說明:
empty()的返回值=!(boolean) var,但不會由於變量未定義而產生警告信息。參見轉換爲布爾值獲取更多信息。
empty() 只能用於變量,傳遞任何其它參數都將形成Paser error而終止運行。
檢測常量是否已設置可以使用 defined() 函數。
3.PHP的與定義變量有哪些,分別是什麼?
超全局變量 — 超全局變量是在所有做用域中始終可用的內置變量
$GLOBALS — 引用全局做用域中可用的所有變量
$_SERVER — 服務器和執行環境信息
$_GET — HTTP GET 變量
$_POST — HTTP POST 變量
$_FILES — HTTP 文件上傳變量
$_REQUEST — HTTP Request 變量
$_SESSION — Session 變量
$_ENV — 環境變量
$_COOKIE — HTTP Cookies
$php_errormsg — 前一個錯誤信息
$HTTP_RAW_POST_DATA — 原生POST數據
$http_response_header — HTTP 響應頭
$argc — 傳遞給腳本的參數數目
PHP 中的許多預約義變量都是「超全局的」,這意味着它們在一個腳本的所有做用域中均可用。在函數或方法中無需執行 global $variable; 就能夠訪問它們。
這些超全局變量是:
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
4.簡述PHP的垃圾回收機制
php 5.3以前使用的垃圾回收機制是單純的「引用計數」,也就是每一個內存對象都分配一個計數器,當內存對象被變量引用時,計數器+1;當變量引用撤掉後,計數器-1;當計數器=0時,代表內存對象沒有被使用,該內存對象則進行銷燬,垃圾回收完成。
「引用計數」存在問題,就是當兩個或多個對象互相引用造成環狀後,內存對象的計數器則不會消減爲0;這時候,這一組內存對象已經沒用了,可是不能回收,從而致使內存泄露;
php5.3開始,使用了新的垃圾回收機制,在引用計數基礎上,實現了一種複雜的算法,來檢測內存對象中引用環的存在,以免內存泄露。
php變量存在一個叫"zval"的變量容器中,"zval"變量容器包括含變量的類型和值,還包括額外的兩個字節信息,分別是「is_ref」表示變量是否屬於引用,「refcount」指向這個zval變量容器的變量個數。
5.列舉PHP的性能優化方法和技巧
opcache
通信緩存
查詢緩存
6.MySQL存儲引擎中,innodb和myisam的區別
MyISAM 和 InnoDB 講解
InnoDB和MyISAM是許多人在使用MySQL時最經常使用的兩個表類型,這兩個表類型各有優劣,視具體應用而定。基本的差異爲:MyISAM類型不支持事務處理等高級處理,而InnoDB類型支持。MyISAM類型的表強調的是性能,其執行數度比InnoDB類型更快,可是不提供事務支持,而InnoDB提供事務支持已經外部鍵等高級數據庫功能。
如下是一些細節和具體實現的差異:
◆1.InnoDB不支持FULLTEXT類型的索引。
◆2.InnoDB 中不保存表的具體行數,也就是說,執行select count() from table時,InnoDB要掃描一遍整個表來計算有多少行,可是MyISAM只要簡單的讀出保存好的行數便可。注意的是,當count()語句包含 where條件時,兩種表的操做是同樣的。
◆3.對於AUTO_INCREMENT類型的字段,InnoDB中必須包含只有該字段的索引,可是在MyISAM表中,能夠和其餘字段一塊兒創建聯合索引。
◆4.DELETE FROM table時,InnoDB不會從新創建表,而是一行一行的刪除。
◆5.LOAD TABLE FROM MASTER操做對InnoDB是不起做用的,解決方法是首先把InnoDB表改爲MyISAM表,導入數據後再改爲InnoDB表,可是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。
另外,InnoDB表的行鎖也不是絕對的,假如在執行一個SQL語句時MySQL不能肯定要掃描的範圍,InnoDB表一樣會鎖全表,例如update table set num=1 where name like 「%aaa%」
兩種類型最主要的差異就是Innodb 支持事務處理與外鍵和行級鎖.而MyISAM不支持.因此MyISAM每每就容易被人認爲只適合在小項目中使用。
我做爲使用MySQL的用戶角度出發,Innodb和MyISAM都是比較喜歡的,可是從我目前運維的數據庫平臺要達到需求:99.9%的穩定性,方便的擴展性和高可用性來講的話,MyISAM絕對是個人首選。
緣由以下:
一、首先我目前平臺上承載的大部分項目是讀多寫少的項目,而MyISAM的讀性能是比Innodb強很多的。
二、MyISAM的索引和數據是分開的,而且索引是有壓縮的,內存使用率就對應提升了很多。能加載更多索引,而Innodb是索引和數據是緊密捆綁的,沒有使用壓縮從而會形成Innodb比MyISAM體積龐大不小。
三、從平臺角度來講,常常隔1,2個月就會發生應用開發人員不當心update一個表where寫的範圍不對,致使這個表無法正經常使用了,這個時候MyISAM的優越性就體現出來了,隨便從當天拷貝的壓縮包取出對應表的文件,隨便放到一個數據庫目錄下,而後dump成sql再導回到主庫,並把對應的binlog補上。若是是Innodb,恐怕不可能有這麼快速度,別和我說讓Innodb按期用導出xxx.sql機制備份,由於我平臺上最小的一個數據庫實例的數據量基本都是幾十G大小。
四、從我接觸的應用邏輯來講,select count(*) 和order by 是最頻繁的,大概能佔了整個sql總語句的60%以上的操做,而這種操做Innodb其實也是會鎖表的,不少人覺得Innodb是行級鎖,那個只是where對它主鍵是有效,非主鍵的都會鎖全表的。
五、還有就是常常有不少應用部門須要我給他們按期某些表的數據,MyISAM的話很方便,只要發給他們對應那表的frm.MYD,MYI的文件,讓他們本身在對應版本的數據庫啓動就行,而Innodb就須要導出xxx.sql了,由於光給別人文件,受字典數據文件的影響,對方是沒法使用的。
六、若是和MyISAM比insert寫操做的話,Innodb還達不到MyISAM的寫性能,若是是針對基於索引的update操做,雖然MyISAM可能會遜色Innodb,可是那麼高併發的寫,從庫可否追的上也是一個問題,還不如經過多實例分庫分表架構來解決。
七、若是是用MyISAM的話,merge引擎能夠大大加快應用部門的開發速度,他們只要對這個merge表作一些select count(*)操做,很是適合大項目總量約幾億的rows某一類型(如日誌,調查統計)的業務表。
固然Innodb也不是絕對不用,用事務的項目如模擬炒股項目,我就是用Innodb的,活躍用戶20多萬時候,也是很輕鬆應付了,所以我我的也是很喜歡Innodb的,只是若是從數據庫平臺應用出發,我仍是會首選MyISAM。
另外,可能有人會說你MyISAM沒法抗太多寫操做,可是我能夠經過架構來彌補,說個我現有用的數據庫平臺容量:主從數據總量在幾百T以上,天天十多億 pv的動態頁面,還有幾個大項目是經過數據接口方式調用未算進pv總數,(其中包括一個大項目由於初期memcached沒部署,致使單臺數據庫天天處理 9千萬的查詢)。而個人總體數據庫服務器平均負載都在0.5-1左右。
7.Mysql的存儲類型有哪幾種?什麼是聚簇索引非聚簇索引?
一、B+樹索引(O(log(n))):關於B+樹索引,能夠參考 MySQL索引背後的數據結構及算法原理
二、hash索引:
a 僅僅能知足"=","IN"和"<=>"查詢,不能使用範圍查詢
b 其檢索效率很是高,索引的檢索能夠一次定位,不像B-Tree 索引須要從根節點到枝節點,最後才能訪問到頁節點這樣屢次的IO訪問,因此 Hash 索引的查詢效率要遠高於 B-Tree 索引
c 只有Memory存儲引擎顯示支持hash索引
三、FULLTEXT索引(如今MyISAM和InnoDB引擎都支持了)
四、R-Tree索引(用於對GIS數據類型建立SPATIAL索引)
從物理存儲角度
一、彙集索引(clustered index)
二、非彙集索引(non-clustered index)
從邏輯角度
一、主鍵索引:主鍵索引是一種特殊的惟一索引,不容許有空值
二、普通索引或者單列索引
三、多列索引(複合索引):複合索引指多個字段上建立的索引,只有在查詢條件中使用了建立索引時的第一個字段,索引纔會被使用。使用複合索引時遵循最左前綴集合
四、惟一索引或者非惟一索引
五、空間索引:空間索引是對空間數據類型的字段創建的索引,MYSQL中的空間數據類型有4種,分別是GEOMETRY、POINT、LINESTRING、POLYGON。MYSQL使用SPATIAL關鍵字進行擴展,使得可以用於建立正規索引類型的語法建立空間索引。建立空間索引的列,必須將其聲明爲NOT NULL,空間索引只能在存儲引擎爲MYISAM的表中建立
CREATE TABLE table_name[col_name data type]
unique|fulltext|spatialindex_name[asc|desc]
一、unique|fulltext|spatial爲可選參數,分別表示惟一索引、全文索引和空間索引;
二、index和key爲同義詞,二者做用相同,用來指定建立索引
三、col_name爲須要建立索引的字段列,該列必須從數據表中該定義的多個列中選擇;
四、index_name指定索引的名稱,爲可選參數,若是不指定,MYSQL默認col_name爲索引值;
五、length爲可選參數,表示索引的長度,只有字符串類型的字段才能指定索引長度;
六、asc或desc指定升序或降序的索引值存儲
8.Memcache和Redis的過時機制是什麼?什麼是一致性哈希?
數據存儲方式:Slab Allocation
數據過時方式:Lazy Expiration + LRU
Slab Allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊,以徹底解決內存碎片問題。
Slab Allocation的原理至關簡單。 將分配的內存分割成各類尺寸的塊(chuk),並把尺寸相同的塊分紅組(chunk的集合)
Page:分配給Slab的內存空間,默認是1MB。分配給Slab以後根據slab的大小切分紅chunk。
Chunk:用於緩存記錄的內存空間。
Slab Class:特定大小的chunk的組。
memcached根據收到的數據的大小,選擇最適合數據大小的slab。
memcached中保存着slab內空閒chunk的列表,根據該列表選擇chunk,而後將數據緩存於其中。
Slab Alloction 缺點
這個問題就是,因爲分配的是特定長度的內存,所以沒法有效利用分配的內存。例如,將100字節的數據緩存到128字節的chunk中,剩餘的28字節就浪費了。
數據過時方式
Lazy Expiration
memcached內部不會監視記錄是否過時,而是在get時查看記錄的時間戳,檢查記錄是否過時。這種技術被稱爲lazy(惰性)expiration。所以,memcached不會在過時監視上耗費CPU時間
LRU
memcached會優先使用已超時的記錄的空間,但即便如此,也會發生追加新記錄時空間不足的狀況,此時就要使用名爲 Least Recently Used(LRU)機制來分配空間。這是刪除「最近最少使用」的記錄的機制。所以,當memcached的內存空間不足時(沒法從slab class 獲取到新的空間時),就從最近未被使用的記錄中搜索,並將其空間分配給新的記錄
你們經常說 memcached命中率低也是LRU策略引發的。你們可能經常遇到當個人內存足夠大的時候,爲什麼還會觸發LRU那。由於LRU 是針對SLAB 來講的。
例如:我存儲的數據在100K 左右。內部會選擇適合大小的SLAB,這時候他會選擇合適他大小的,他會選擇上圖的SLBA CLASS 2. 若是這時候SLAB CLASS 2 滿了或者不足100K。他就會調用LRU機制。會把SLAB CLASS 2 中chunck中最近不多使用的數據清理掉,致使數據被清理掉,即便它沒有過時。
因此使用memcached 時候 必定要注意數據大小匹配模式和增加因子。
REDIS 過時時間機制
1.volatile-lru:從設置了過時時間的數據集中,選擇最近最久未使用的數據釋放
2.allkeys-lru:從數據集中(包括設置過時時間以及未設置過時時間的數據集中),選擇最近最久未使用的數據釋放
3.volatile-random:從設置了過時時間的數據集中,隨機選擇一個數據進行釋放
4.allkeys-random:從數據集中(包括了設置過時時間以及未設置過時時間)隨機選擇一個數據進行入釋放
5.volatile-ttl:從設置了過時時間的數據集中,選擇立刻就要過時的數據進行釋放操做
6.noeviction:不刪除任意數據(但redis還會根據引用計數器進行釋放呦~),這時若是內存不夠時,會直接返回錯誤
默認的內存策略是noeviction,在Redis中LRU算法是一個近似算法,默認狀況下,Redis隨機挑選5個鍵,而且從中選取一個最近最久未使用的key進行淘汰,在配置文件中能夠經過maxmemory-samples的值來設置redis須要檢查key的個數,可是檢查的越多,耗費的時間也就越久,可是結構越精確(也就是Redis從內存中淘汰的對象未使用的時間也就越久~), 設置多少,具體業務權衡吧通常都是按照默認。
REDIS 還有按期策略,按期刪除過時的緩存數據,來節省內存。這種方式仍是蠻好的。這種策略優先於LRU。
目前對比MEMCACHED 和REDIS 過時時間機制對比。
REDIS 命中率明顯高於MEMCACHED,對於業務適合哪一種場景,你們各自匹配吧!目前來講 我認爲REDIS 是 MEMCACHED 補充的一款NOSQL 產品。
一致性哈希,一種分佈式節點key分佈算法,可選;
9.MySQL索引底層數據結構是怎樣存儲的,爲何使用索引會查詢的快?
數據結構及算法基礎
索引的本質
B-Tree和B+Tree
特殊的存儲結構,尋道成本低;
MySQL索引實現
MyISAM索引實現
非聚簇索引
InnoDB索引實現
聚簇索引
第一個重大區別是InnoDB的數據文件自己就是索引文件。
第二個與MyISAM索引的不一樣是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。
彙集索引這種實現方式使得按主鍵的搜索十分高效,可是輔助索引搜索須要檢索兩遍索引:首先檢索輔助索引得到主鍵,而後用主鍵到主索引中檢索得到記錄。
10.優化mysql的方法
避免複查查詢
避免模糊查詢
避免數據庫內運算
避免大量吞吐
儘量縮小檢索範圍
儘量使用索引,惟一或者接近惟一的索引
聯查中儘可能使用const字段
11.find 和 grep的區別
find是查找文件
grep是查找文件內的內容
12.寫出下列的服務的用途和默認端口
FTP: | 21/tcp | 依照FTP協議提供服務,專門用來傳輸文件的協議。
SSH: | 22/tcp | 專爲遠程登陸會話和其餘網絡服務提供安全性的協議。利用 SSH 協議能夠有效防止遠程管理過程當中的信息泄露問題。
HTTP: | 80/tcp | 是互聯網上應用最爲普遍的一種網絡協議。全部的WWW文件都必須遵照這個標準。
telnet:| 23/tcp | Telnet協議是TCP/IP協議族中的一員,是Internet遠程登錄服務的標準協議和主要方式,它爲用戶提供了在本地計算機上完成遠程主機工做的能力
https:| 443/tcp 443/udp | 是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL
13.給text.txt文件除全部者以外增長執行權限,最終以數字寫出文件權限
chmod g+x,o+x text.txt