PHP面试
1.什么是面向對象???????
面向對象是程序的一種設計方式,它利于提高程序的重要性,使程序更加清晰。
主要特征:封裝、繼承、多態。
三大特點:
a.封裝性:也稱為信息隱藏,就是將一個類的使用和實現分開,只保留部分接口和方法與外部聯系,或者說只公開了一些供開發人員使用的方法。于是開發人員只需要關注這個類如何使用,不用去關心具體的實現過程,這樣就能實現MVC的分工合作,也可以有效的避免程序之間相互依賴,從而實現代碼模塊之間的松耦合。
b.繼承性:子類自動繼承父類中的屬性和方法,并且可以添加新的屬性和方法或者對父類的部分屬性和方法進行重寫。繼承增加了代碼的可重用性。PHP只支持單繼承,一個子類只能繼承一個父類。
c.多態性:子類繼承了父類中的屬性和方法,并對其中部分方法進行重寫。于是多個子類中雖然都具有用一個方法,但是這些子類實例化的對象調用這些相同的方法后可以得到不同的結果,這就是多態性。
2.面向對象的七大原則:
- 單一職責原則
? ? ? ? 一個類只負責一項職責。
- 開放封閉原則
? ? ? ? 一個軟件實體,如類、模塊和函數應該對擴展開放,對修改關閉
- 里式替換原則
? ? ? ? 子類可擴展父類功能,但不能改變父類原有的功能。
- 依賴倒置原則
? ? ? ? 高層模塊不應該依賴底層模塊,二者都應該依賴細節,細節應該依賴抽象。
- 接口隔離原則
? ? ? ? 客戶端不應該依賴它不需要的接口,并盡力實現單一職責原則。例:訂單接口可分為下單接口、發貨接口、退貨接口等,而不能將訂單相關的方法都定義到一個接口中。
- 迪米特原則
? ? ? ? 又稱為 最少知道法則,只與朋友通信,表示一個對象應該對其他對象表示最少的了解,也就是一個類除了提供公共方法,不對外泄露任何信息。
- 合成/聚合復用原則
????????它要求在軟件復用時,要盡量先使用組合或者聚合等關聯關系來實現,其次才考慮使用繼承關系來實現。
? ? ? ? 如果要使用繼承關系,則必須嚴格遵循里式替換原則。合成復用原則同里氏替換原則相輔相成的,兩者都是開閉原則的具體實現規范。
????????
3.合并兩個數組有幾種方式,比較他們的異同
方式:
array_merge()、+、array_merge_recursive()
異同:
array_merge()簡單的合并數組;
array_merge_recursive()合并兩個數組,如果數組中有完全一樣的數據,將它們遞歸合并;array_merge()和‘+’:合并兩個數組,前者將值作為新數組的鍵。
4.PHP的is_writeable()函數存在bug,無法準確判斷一個目錄/文件是否可寫,請寫一個函數來判斷目錄/文件是否絕對可寫
答:其中bug存在兩個方面,
1.在Windows中,當文件只有只讀屬性時,is_writeable()函數才返回FALSE,當返回TRUE時,改文件不一定是可寫的。
如果是目錄,在目錄中新建文件并通過打開文件來判斷;
如果是文件,可通過打開文件(fopen),來測試文件是否可寫。
2.在Unix中,當PHP配置文件中開啟safe_mode時(safe_mode=on),is_writeable()同樣不可用。
函數:?
function is_really_writable($file) {if (DIRECTORY_SEPARATOR === '/') {return is_writable($file);}if (is_dir($file)) {$file = rtrim($file, '/') . '/' . md5(mt_rand());if (($fp = @fopen($file, 'ab')) === FALSE) {return FALSE;}fclose($fp);@chmod($file, 0777);@unlink($file);return TRUE;} elseif (!is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) {return FALSE;}fclose($fp);return TRUE; }?5.PHP的垃圾收集機制是怎樣的?
PHP可以自動進行內存管理,清除不再需要的對象。
PHP使用了引用計數(reference counting)這種單純的垃圾回收(garbage collection)機制。
每個對象都內含一個引用計數器,每個reference連接到對象,計數器加1。當reference離開生存空間或被設為null,計數器減1。當某個對象的引用計數器為零時,PHP知道你將不再需要這個對象,就會釋放所占的內存空間。
6.寫一個函數,盡可能高效的,從一個標準的URL里提取出文件的擴展名
例如:http://www.abc.com/de/wander.php?id=001 需要取出 ‘php’ 或者 ‘.php’
//方案一 function getExt1($url){$arr = parse_url($url);//Array([scheme]=>http [host]=>www.abc.com [path]=>/de/wander.php [query]=>id=001)$file = basename($arr['path']); //wander.php?id=001$ext = explode('.',$file);return $ext[count($ext)-1]; }//方案二 function getExt2($url){$url = basename($url); //wander.php?id=001$pos1 = strpos($url,'.'); //6$pos2 = strpos($url,'?'); //10if (strstr($url,'?')) {return substr($url,$pos1+1,$pos2-$pos1-1); } else {return substr($url,$pos1);}}$url= "http://www.abc.cn/de/wander.php?id=001";echo getExt1($path);echo "<br />";echo getExt2($path);7.使用正則表達式提取一段表示語言(html或XML)
代碼段中指定標簽的指定屬性值(需要考慮屬性值不規則的情況,如大小寫不敏感,屬性名值與等號之間有空格等)此處假設需要提取test標簽的attr屬性值,請自行構建改標簽的串(騰訊)
代碼如下:
<?phpheader("content-type:text/html;charset=utf-8");function getAttrValue($str,$tagName,$attrName){$pattern1="/<".$tagName."(s+w+s*=s*(['"]?)([^'"]*)())*s+".$attrName."s*=s*(['"]?)([^'"]*)()(s+w+s*=s*(['"]?)([^'"]*)(9))*s*>/i";$arr=array();$re=preg_match($pattern1,$str,$arr);if($re){echo"<br/>$arr[6]={$arr[6]}";}else{echo"<br/>沒找到。";}}// 示例$str1="<test attr='ddd'>";getAttrValue($str1,"test","attr");//找test標簽中attr屬性的值,結果為ddd$str2="<test2 attr='ddd'attr2='ddd2't1="t1 value"t2='t2 value'>";getAttrValue($str2,"test2","t1");//找test2標簽中t1屬性的值,結果為t1 value?>8.php中web上傳文件的原理是什么,如何限制上傳文件的大小?
上傳文件的表單使用post方式,并且要在form中添加enctype=“multipart/form-data“。
一般可以加上隱藏域:<input type= hidden name = 'MAX_FILE_SIZE'? value=1024>,位置在file域前面。value的值一般是上傳文件的客戶端字節限制??梢员苊庥脩粼诨〞r間等待上傳大文件之后才發現文件上傳過大失敗的麻煩。
使用file文件域來選擇上傳的文件,當點擊提交按鈕之后,文件會被上傳到服務器的臨時目錄,在腳本運行結束時會被銷毀,所以應該在在腳本結束之前,將其移動到服務器的某個目錄下,可以通過函數move_uploaded_file()來移動臨時文件,獲取臨時文件的信息可以使用 $_FILES。
限制文件大小的因素有:
客服端隱藏域的MAX_FILE_SIZE的數值(可以被繞開)
服務器端的upload_max_filesize,post_max_size和memory_limit。這幾項不能夠用腳本來設置。
自定義文件大小限制邏輯。即使服務器的限制是能夠自己決定,也會有特殊情況考慮,所以這個限制方式經常是必要的。
9.請說明PHP中傳值和傳引用的區別,什么時候傳值什么時候引用?
按值傳遞:函數范圍內對值的任何改變在函數外部都會被忽略。
按引用傳遞:函數范圍內對值的任何改變在函數外部也能反映出這些修改
優缺點:按值傳遞時,PHP必須復制值。特別是對于大型的字符串和對象來說,這將會是一個代價很大的操作。按引用傳遞不需要復制值。對于性能提高很有好處。
10.mysql數據庫中的字段類型varchar和char的主要區別是什么?
char:
varchar:
日常的設計,對于長度相對固定的字符串,可以使用char,對于長度不確定的,使用 varchar更合適一些。
11.php7的新特性
標量類型聲明:PHP7中的函數的形參類型聲明可以為標量。在PHP5中只能是類名、接口、array或者callable(PHP5.4,既可以是函數,包括匿名函數),現在能使用string、int、float、和bool。
返回值類型聲明:增加了對返回值類型聲明的支持。類似于參數類型聲明,返回值類型聲明指明了函數返回值的類型??捎玫念愋团c參數聲明中可用的類型相同。
null合并運算符:由于日常使用中大量同時使用三元表達式和isset()的情況,null合并運算符使得變量存在且值不為null,它就會返回自身值,否則返回它的第二個操作數。
use加強:從同一namespace導入的類、函數和常量現在可以通過單個use語句一次性導入匿名類,現在支持通過new class 來實例化一個匿名類。
12.如何處理負載,高并發?
1、html靜態化
?效率最高、消耗最少的就是純靜態化的HTML頁面,所有我們盡可能使我們的網站頁面采用靜態化實現,這個最簡單的方法其實也是最有效的方法。
2、圖片服務器分離
把圖片單獨存儲,盡可能減收圖片等大流量的開銷,可以放在一些相關的平臺上,如七牛云、騰訊云等。
3、數據庫集群和庫表散列及緩存
數據庫的并發鏈接為100,一臺數據庫遠遠不夠,可以從讀寫分離、主從復制,數據庫集群方面來入手。另外盡量減少數據庫的訪問,可以使用緩存數據庫如memcache、redis等。
4、鏡像
盡量減少下載,可以把不同的請求分發到多個鏡像端。
5、負載均衡
Apache的最大并發連接為1500,只能增加服務器,可以從硬件上著手,如F5服務器,當然硬件的成本比較高,我們往往是從軟件方面著手。
13.常見的PHP安全性攻擊SQL注入:
用戶利用在表單字段輸入SQL語句的方式來影響正常SQL的執行。
防止:使用mysql_real_escape_string()過濾數據 手動檢查每一數據是否為正確的數據類型,使用預處理語句并綁定變量。
參數化SQL: 是指在設計與數據庫鏈接并訪問數據時,需要再填入數值或數據的地方,試用參數(parameter)來給值,用@或?來表示參數。
XSS攻擊:跨站點腳本攻擊,由用戶輸入一些數據到你的網站,其中包括客戶端腳本(通常JavaScript)。如果你沒有過濾就輸出數據到另一個web頁面,這個腳本將被執行。
防止:為了防止xss攻擊,使用PHP的htmlentitles()函數過濾在輸出到瀏覽器。
CSRF:跨站點請求偽造,是指一個頁面發出的請求,看起來像網站的信任用戶,但是是偽造的。
防止:一般來說,確保用戶來自你的表單,并且匹配每一個你發出去的表單。有兩點一定要記住:對用戶會話采用適當的安全措施,例如:每一個會話更新id和用戶使用SSL。生成另一個一次性的令牌并將其嵌入表單,保存在會話中(一個會話變量),在提交時檢查它。如laravel中的_token。
代碼注入:代碼注入是利用計算機漏洞通過無效數據造成的。問題在于,當你不小心執行任意代碼,通常通過文件包含。寫的很糟糕的代碼可以允許一個遠程文件包含并執行。如許多PHP函數,如require可以包含URL或文件名。
防止:過濾用戶輸入,在php.ini中設置禁用allow_url_fopen和allow_url_include。這將禁用require、include、fopen的遠程文件。
14.靜態化如何實現?偽靜態如何實現?
1、靜態化是指頁面靜態化,就是實實在在的靜態化文件,不需要查詢數據庫就可以直接從文件中獲取數據,指的是真靜態。
實現方式主要有兩種:
a、我們在添加信息入庫的時候就生成的靜態文件,也成為模本替換技術。
b、用戶在訪問我們的頁面時先判斷是否有對應的緩存文件存在,如果存在直接讀取緩存,不存在就讀取數據庫,同時生成緩存文件。
2、偽靜態不是真正意義上的靜態化,之所以使用偽靜態,主要是為了SEO推廣,搜索引擎對動態的文件獲取難度大,不利于網站推廣。
實現原理:基于Apache或Nginx的rewrite。
方式主要有兩種:
a、直接在配置虛擬機的位置配置偽靜態,這個每次修改都要重啟web服務器。
b、采用分布式的,可以在網站的根目錄上創建‘.htaccess’的文件,在里面配置相應的重寫規則來實現偽靜態,這種方式重寫時不需要重啟web服務器,且結構上比較清晰。
15、說說對SQL語句優化有哪些方法?
1、where子句中:where表之間的連接必須寫在其他where條件之前,那些可以過濾最大數量記錄的條件必須寫在where子句的末尾,having寫在最后。
2、用exists代替in、用not exists代替 not in。
3、避免在索引列上使用計算。
4、避免在索引列上使用is null 和is not null 。
5、對查詢進行優化,應該盡量避免全表掃描,首先應該考慮在where及order by 涉及的列上建立索引。
6、應該盡量避免在where子句中對字段進行null值判斷,否則將導致引擎放棄使用而進行全表掃描。
7、應盡量避免在where子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。
8、應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描。
如:
select id from t where num=10 or num=20#可以這樣查詢:select id from twhere num=10union allselect id from twhere num=209、索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
10、在新建臨時表時,如果一次性插入數據量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然后insert。
16、MySQL數據庫作發布系統的存儲,一天五萬條以上的增量,預計運維三年,怎么優化?
1、設計良好的數據庫結構,允許部分數據冗余,盡量避免join查詢,提高效率。
2、選擇合適的表字段數據類型和存儲引擎,適當的添加索引。
3、做mysql的主從復制讀寫分離。
4、對數據表進行分表,減少表單中的數據提高查詢速度。
5、添加緩存機制,如Redis,memcached等。
6、對不經常改動的頁面,生成靜態頁面(比如做ob緩存)。
7、書寫高效率SQL。比如select*from tabel 改為 select field_1,field_2? from table。
17、對于大流量的網站,采用什么樣的方法來解決各頁面訪問量統計問題?
1、確認服務器是否能支持當前訪問量。
2、優化數據庫訪問。
3、禁止外部訪問鏈接(盜鏈),比如圖片盜鏈。
4、控制文件下載。
5、做負載均衡,使用不同主機分流。
6、使用瀏覽統計軟件,了解訪問量,有針對性的進行優化。
18、談談你對mysql引擎中的MyISAM與InnoDB的區別理解?
1、存儲結構
MyISAM:每個MyISAM在磁盤上存儲成三個文件。第一個文件的名字以表的名字開始,擴展名指出文件類型。.frm文件存儲表定義。數據文件的擴展名為.MYD(MYData)。索引文件的擴展名是.MYI(MYIndex)。
InnoDB:所有的表都保存在弄一個數據文件中(也可能是多個文件,或者獨立的表空間文件),InnoDB表的大小只受限于操作系統文件的大小,一般為2GB。
2、存儲空間
MyISAM:可被壓縮,存儲空間較小。支持三種不同的存儲格式:靜態表(默認,但是注意數據末尾不能有空格,會被去掉)、動態表、壓縮表。
InnoDB:需要更多地內存和存儲,它會在主內存中建立其專用的緩沖池用于高速緩沖數據和索引。
3、可移植性、備份及恢復
MyIASM:數據是以文件的形式存儲,所以在跨平臺的數據轉移中會很方便。在備份和恢復時可單獨針對某個表進行操作。
InnoDB:免費的方案可以是拷貝數據文件、備份binlog,或者用mysqldump,在數據量達到幾十G的時候就相對痛苦了。
4、事務支持
MyIASM:強調的是性能,每次查詢都具有原子性,其執行速度比InnoDB類型更快。但是不提供事務支持。
InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe(ACID compliant))型表。
5、AUTO_INCREMENT
MyISAM:可以和其他字段一起建立聯合索引。引擎的自動增長列必須是索引,如果是組合索引,自動增長可以不是第一列,他可以根據前面幾列進行排序后遞增。
InnoDB:InnoDB中必須包含該字段的索引。引擎的自動增長列必須是索引,如果是組合索引也必須是組合索引的第一列。
6、表鎖差異
MyISAM:只支持表級鎖,用戶在操作myisam表時,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以后的表滿足insert并發的情況下,可以在表的尾部插入新的數據。
InnoDB:支持事務和行級鎖,是innodb的最大特色。行鎖大幅度提高了多用戶并發操作的新能。但是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。
7、全文索引
MyISAM:支持 FULLTEXT類型的全文索引
InnoDB:不支持FULLTEXT類型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。
8、表主鍵
MyISAM:允許沒有任何索引和主鍵的表存在,索引都是保存行的地址。
InnoDB:如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6字節的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值。
9、表的具體行數
MyISAM:保存有表的總行數,如果select count(*) from table;會直接取出出該值。
InnoDB:沒有保存表的總行數,如果使用select count(*) from table;就會遍歷整個表,消耗相當大,但是在加了wehre條件后,myisam和innodb處理的方式都一樣。
10、CURD操作
MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇。
InnoDB:如果你的數據執行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表。DELETE 從性能上InnoDB更優,但DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除,在innodb上如果要清空保存有大量數據的表,最好使用truncate table這個命令。
11、外鍵
MyISAM:不支持
InnoDB:支持
通過上述的分析,基本上可以考慮使用InnoDB來替代MyISAM引擎了,原因是InnoDB自身很多良好的特點,比如事務支持、存儲 過程、視圖、行級鎖定等等,在并發很多的情況下,相信InnoDB的表現肯定要比MyISAM強很多。另外,任何一種表都不是萬能的,只用恰當的針對業務類型來選擇合適的表類型,才能最大的發揮MySQL的性能優勢。如果不是很復雜的Web應用,非關鍵應用,還是可以繼續考慮MyISAM的,這個具體情況可以自己斟酌。
19.Redis和memcached緩存的區別?
總結一:
1、數據類型
Redis數據類型豐富,支持set list 等類型
memcached支持簡單數據類型,需要客戶端自己處理復雜對象
2、持久性
Redis支持數據落地持久化存儲
memcached不支持數據持久存儲
3、分布式存儲
Redis支持master-slave復制模式
memcached可以使用一致性hash做分布式
value大小不同
memcache是一個內存緩存,key的長度小于250字符,單個item存儲要小于1M,不適合虛擬機使用,
4、數據一致性不同
Redis使用的是單線程模型,保證了數據按順序提交。
memcache需要使用cas保證數據一致性。CAS(Check and Set)是一個確保并發一致性的機制,屬于‘樂觀鎖’范圍;原理和簡單:拿到版本號,操作,對比版本號,如果一致就操作,不一致就放棄任何操作。
5、cup利用
Redis單線程模型只能使用一個cup,可以開啟多個Redis進程。
總結二:
1、Redis中,并不是所有的數據都一直存儲在內存中的,這是和Memcache相比一個最大的區別。
2、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list、set、hash等數據結構的存儲。
3、Redis支持數據的備份,即master-slave模式的數據備份。
4、Redis支持數據的持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
我個人認為最本質的不同是Redis在很多方面具備數據庫的特征,或者說就是一個數據庫系統,而memcached只是簡單的k/v緩存。
總結三:
Redis和memcached的不同在于:
1、存儲方式:
memcached把數據全部存在之中,斷點后會掛掉,數據不能超過內存大小
Redis有部分存在硬盤上,這樣能保證數據的持久性。
2、數據支持類型:
Redis在數據支持上要比memcached多的多。
3、使用底層模型不同:
新版本的Redis直接自己構建了VM機制,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。
4、運行環境不同:
Redis目前官方只支持Linux上運行,從而省去了對于其他系統的支持,這樣的話可以把更好的把精力用于本系統環境上的優化,雖然后來微軟有一個小組為其寫了補丁。但是沒有放到主干上。
redis的內容是可以落地的,就是說跟MongoDB有些類似,然后redis也可以作為緩存,并且可以設置master-slave
20、Redis消息隊列先進先出需要注意什么?
答:通常使用一個list來實現隊列操作,這樣有一個小限制,所有的任務統一都是先進先出,如果想優先處理某個任務就不太好處理了,這就需要讓隊列有優先級的概念,我們就可以優先處理高級別的任務,實現方式有以下幾種方式:
1)單一列表實現:隊列正常的操作是左進右出(lpush,rpop)為了先處理高優先級任務,在遇到高級別任務時,可以直接插隊,直接放入隊列頭部(rpush),這樣,從隊列頭部(右側)獲取任務時,取到的就是高優先級的任務(rpop)。
2)使用兩個隊列,一個普通隊列,一個高級隊列,針對任務的級別放入不同的隊列,獲取任務時也很簡單,redis的BRPOP命令可以按順序從多個隊列中取值,BRPOP會按照給出的 key 順序查看,并在找到的第一個非空 list 的尾部彈出一個元素,redis> BRPOP list1 list2 0
list1 做為高優先級任務隊列list2 做為普通任務隊列這樣就實現了先處理高優先級任務,當沒有高優先級任務時,就去獲取普通任務方式1 最簡單,但實際應用比較局限,方式3可以實現復雜優先級,但實現比較復雜,不利于維護方式2 是推薦用法,實際應用最為合適21、Redis如何防止高并發?
答:其實Redis是不會存在并發問題的,因為它是單線程的,再多的命令都是一個接一個的去執行的。我們用的時候,可能會出現并發問題,比如獲得和設定這一對。
Redis的為什么有高并發問題?
Redis是一種單線程機制的nosql數據庫,基于key-value,數據可持久化落盤。由于單線程所以redis本身并沒有鎖的概念,多個客戶端連接并不存在競爭關系,但是利用jedis等客戶端對redis進行并發訪問時會出現問題。發生連接超時、數據轉換錯誤、阻塞、客戶端關閉連接等問題,這些問題均是由于客戶端連接混亂造成。
同時,單線程的天性決定,高并發對同一個鍵的操作會排隊處理,如果并發量很大,可能造成后來的請求超時。
在遠程訪問redis的時候,因為網絡等原因造成高并發訪問延遲返回的問題。
解決辦法:
在客戶端將連接進行池化,同時對客戶端讀寫Redis操作采用內部鎖synchronized。
服務器角度,利用setnx變向實現鎖機制。
22、PHP與那些編程語言相似?
Perl、C
23、PHP的全程?
hypwetext Perprocessor (超文本預處理器)
24、PHP是否支持多繼承?
PHP只支持單繼承。使用關鍵字extends。
25、使用final修飾的類和方法代表什么意思?
final修飾的類不允許被繼承,修飾的方法不允許被重寫。
26、PHP中如何比較兩個對象?
可以使用 ‘==’ 來比較兩個對象是否為同一實例,并且擁有相同的屬性和屬性值。
27、PHP和JavaScript是如何交互的?
PHP和JavaScript無法直接進行交互,因為PHP是一種服務器端語言,而JavaScript是一種瀏覽器語言。但是可以交換變量,因為PHP可以生成將由瀏覽器執行的JavaScript代碼,并且通過URL將特定的變量傳遞回PHP。
28、PHP處理圖片需要添加什么擴展?
需要添加GD庫執行處理圖片功能。
29、獲取圖片屬性(size、width和height)的函數是什么?
- 獲取圖片大小size:gettimagesize()?
- 獲取圖片寬度width: imagesx()
- 獲取圖片高度height:imagesy()
30、include() 和 require()? 在執行失敗的情況下有什么不同?
- include() 會產生一個禁告,不影響后去程序的執行
- require() 會產生一個致命錯誤,后去程序停止執行
31、函數的作用?
- is_numeric():檢查是否為數字。
- ctype_alnum():檢查是否為字母數字字符。
- empty():檢查變量是否具有值。
- unlink():用于文件系統處理,刪除文件。
- unset():用于變量管理,可以是變量變為未定義。
- stripslash():刪除字符串中的轉義字符。
- get_magic_quotes_gpc():告訴我們魔術引號
32、怎么在PHP中定義常量?
- 使用define()函數定義,語法“define(常量名, 常量值,是否大小寫敏感)”;
- 使用const關鍵字定義,語法“const 常量名 = 常量值;”。
33、如何在PHP中強制轉化類型?
? ? ?1.?(int) (bool) (float) (string) (array) (object)
? ? ?2. intval() floatval() strval()
?????3.settype()
????????
?
34、PHP中三元運算符如何使用?
(條件)? (返回值1) : (返回值2)
若條件為真,則返回值1,
若條件為假,則返回值2.
35、函數func_num_args()的作用是什么?
函數 func_num_args() 用于提供傳遞給函數的參數數量
?
36、如果變量$var1 = 10,變量$var2 = 'var1' ,那么$$var2的值為多少?
$$var2 = $var1 ,$var1 = 10?
所有 $$var2 值為10
37、通過 ::訪問意味著什么?
:: 用于訪問不需要對象初始化的靜態方法。
38、永久性cookie的含義是什么?
永久性的cookie存儲在瀏覽器計算機的cookie文件中,默認情況下,cookie是臨時的,關閉瀏覽器后,cookie會被刪除。
39、會話合適結束?
會話在PHP建表完成時自動結束,也可以使用session_write_close()手動結束。
40、session_unregister()和session_unset()有什么區別?
- session_unregister():從當前會話中注銷全局變量
- session_unset():釋放所有會話變量
41、$_FILES['userfile']['name']和$_FILES['userfile']['tmp_name']有什么區別?
- $_FILES['userfile']['name'] :表示客戶端上傳文件原始名稱
- $_FILES['userfile']['tmp_name']:表示服務器上存儲的文件的臨時文件名
42、上傳文件出問題時,如何獲取錯誤信息?
$_FILES['userfile']['error'] 包括了上傳文件有關的錯誤代碼。
43、如何更改上傳文件大小的最大值?
通過修改php.ini中的upload_max_filesize來修改上傳文件大小的最大值。
44、函數strstr() 和函數stristr() 有什么區別?
函數?strstr ($haystack, $needle, $before_needle = null)?
區別:stristr() 除了不區分大小寫之外,與 strstr() 完全相同。
45、PHP中默認會話時間是什么?
PHP中默認會話時間是直到瀏覽器關閉為止。
46、http狀態碼
1、狀態碼分類:
- 1××:信息,服務器收到請求
- 2××:成功
- 3××:重定向
- 4××:客戶端錯誤
- 5××:服務端錯誤
2、常用狀態碼
- 200:請求成功
- 301:永久重定向
- 302:臨時移動
- 400 bad request:客戶端請求語法錯誤
- 401 unauthorized:客戶端沒有權限
- 403 forbidden :服務器拒絕客戶端請求
- 404 not found :客戶端請求資源不存在
- 500 Internal Server Error?: 服務器內部錯誤
- 502 bad gateway :作為網關或者代理工作的服務器嘗試執行請求時,從上游服務器接受到無效的響應。
- 503 service unavailable :超載或系統維護
- 504 Gateway timeout :網關超時
3、502的原因及解決辦法
原因:Nginx將請求提交給網關(php-fpm)處理異常導致
1)fastcgi 緩沖區設置過小
fastcgi_buffer_size 32k;
2)php-cgi的進程數設置過少
查看FastCgi進程數:netstat -anpo | grep "php-cgi"| wc -l
調整參數最大子進程數:max_children
一般按照單個進程20M計算需要需要設置的子進程數
3)max_requests(內存溢出或頻繁重啟)
參數指明每個children最多能處理的請求數量,到達最大值之后會重啟children。
設置過小可能導致頻繁重啟children:
php將請求輪詢給每個children,在大流量的場景下,每一個children 到達最大值的時間差不多,如果設置過小可能多個children 在同一時間關閉,nginx無法將請求轉發給php-fpm,cpu降低,負載變高。
設置過大可能導致內存泄露
4)php執行時間超過nginx等待時間
fastcgi_connect_timeout
fastcgi_send_timeout
fastcgi_read_timeout
5)fastcgi執行時間
max_execution_time
47、http和HTTPS的區別
48、mysql的幾個概念
- 主鍵(primary key):能夠唯一表示表中某一行的屬性或屬性組。一個表只能有一個主鍵,但可以有多個候選索引。主鍵常常與外鍵構成參照完整性約束,防止數據不一致。主鍵可以保證記錄的唯一和主鍵域非空,數據庫管理系統對于主鍵自動生成唯一索引,所以主鍵也是一個特殊的索引。
- 外鍵(foreign key):是用于建立和加強兩個表數據之間的鏈接的一列或多列。外鍵約束主要用來維護兩個表之間數據的一致性。簡言之,表的外鍵就是另一表的主鍵,外鍵將兩表聯系起來。一般情況下,要刪除一張表中的主鍵必須首先要確保其它表中的沒有相同外鍵(即該表中的主鍵沒有一個外鍵和它相關聯)。
- 索引(index):是用來快速地尋找那些具有特定值的記錄。主要是為了檢索的方便,是為了加快訪問速度, 按一定的規則創建的,一般起到排序作用。所謂唯一性索引,這種索引和前面的“普通索引”基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一。
總結:
49、數據庫主從復制,讀寫分離
* 什么是主從復制:
主從復制,是用來建立一個和主數據庫完全一樣的數據庫環境,稱為從數據庫;
* 主從復制的原理:
* 主從復制的作用:
* 主從復制的幾種方式:
半同步復制:master只保證slaves中的一個操作成功,就返回,其他slave不管。
這個功能,是由google為MYSQL引入的。
* 關于讀寫分離
在完成主從復制時,由于slave是需要同步master的。所以對于insert/delete/update這些更新數據庫的操作,應該在master中完成。而select的查詢操作,則落下到slave中。
50、常見的排序算法
1. 冒泡排序
思路分析:在要排序的一組數中,對當前還未排好的序列,從前往后對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即,每當兩相鄰的數比較后發現它們的排序與排序要求相反時,就將它們互換。
代碼實現:
$arr=array(1,43,54,62,21,66,32,78,36,76,39);?function bubbleSort($arr){?$len=count($arr);//該層循環控制 需要冒泡的輪數for($i=1;$i<$len;$i++){ //該層循環用來控制每輪 冒出一個數 需要比較的次數for($k=0;$k<$len-$i;$k++){if($arr[$k]>$arr[$k+1]){$tmp=$arr[$k+1];$arr[$k+1]=$arr[$k];$arr[$k]=$tmp;}}}return $arr;}2. 選擇排序
思路分析:在要排序的一組數中,選出最小的一個數與第一個位置的數交換。然后在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最后一個數比較為止。
代碼實現:
function selectSort($arr) {//雙重循環完成,外層控制輪數,內層控制比較次數$len=count($arr);for($i=0; $i<$len-1; $i++) {//先假設最小的值的位置$p = $i;for($j=$i+1; $j<$len; $j++) {//$arr[$p] 是當前已知的最小值if($arr[$p] > $arr[$j]) {//比較,發現更小的,記錄下最小值的位置;并且在下次比較時采用已知的最小值進行比較。$p = $j;}}//已經確定了當前的最小值的位置,保存到$p中。如果發現最小值的位置與當前假設的位置$i不同,則位置互換即可。if($p != $i) {$tmp = $arr[$p];$arr[$p] = $arr[$i];$arr[$i] = $tmp;}}//返回最終結果return $arr;}3.插入排序
思路分析:在要排序的一組數中,假設前面的數已經是排好順序的,現在要把第n個數插到前面的有序數中,使得這n個數也是排好順序的。如此反復循環,直到全部排好順序。
代碼實現:
function insertSort($arr) {$len=count($arr);for($i=1, $i<$len; $i++) {$tmp = $arr[$i];//內層循環控制,比較并插入for($j=$i-1;$j>=0;$j--) {if($tmp < $arr[$j]) {//發現插入的元素要小,交換位置,將后邊的元素與前面的元素互換$arr[$j+1] = $arr[$j];$arr[$j] = $tmp;} else {//如果碰到不需要移動的元素,由于是已經排序好是數組,則前面的就不需要再次比較了。break;}}}return $arr;}4.快速排序?
思路分析:選擇一個基準元素,通常選擇第一個元素或者最后一個元素。通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大于等于基準元素。此時基準元素在其排好序后的正確位置,然后再用同樣的方法遞歸地排序劃分的兩部分。
代碼實現:
function quickSort($arr) {//先判斷是否需要繼續進行$length = count($arr);if($length <= 1) {return $arr;}//選擇第一個元素作為基準$base_num = $arr[0];//遍歷除了標尺外的所有元素,按照大小關系放入兩個數組內//初始化兩個數組$left_array = array();? //小于基準的$right_array = array();? //大于基準的for($i=1; $i<$length; $i++) {if($base_num > $arr[$i]) {//放入左邊數組$left_array[] = $arr[$i];} else {//放入右邊$right_array[] = $arr[$i];}}//再分別對左邊和右邊的數組進行相同的排序處理方式遞歸調用這個函數$left_array = quick_sort($left_array);$right_array = quick_sort($right_array);//合并return array_merge($left_array, array($base_num), $right_array);}51、接口和抽象類的區別:
1、接口
- 對接口的使用是通過關鍵字implements
- 接口不能定義成員變量(包括類靜態變量),能定義常量
- 子類必須實現接口定義的所有方法
- 接口只能定義方法不能實現方法
- 接口中沒有構造函數
- 接口中的方法和實現他的;類默認都是public類型的
2、抽象類
- 對抽象類的使用是通關關鍵字extends
- 不能被實例化,可以定義子類必須實現的方法
- 子類必須實現父類中的所有抽象方法,這些方法的訪問控制必須和父類中的一樣(或者更加寬松)
- 如果一個類中有一個抽象方法。則該類必須定義為抽象方法
- 抽象類中可以有構造函數
- 抽象類種的方法可以使用private、protected、public來修飾
- 一個類可以同時實現多個接口,但是一個類只能繼承一個抽象類
3、final類/方法
- final類不能被繼承
- final方法不能比重寫
4、static類/方法
- 可以不實例化類而直接訪問
- 靜態屬性不可以由對象通過—>操作符來訪問,用::方式來調用
52、常見的設計模式
策略模式:策略模式是對象的行為模式,動態的選擇需要調用的類。
1 策略模式三個角色:
- 抽象策略角色
- 具體策略角色
- 環境角色
2 策略模式實現步驟:
- 定義抽象角色類
- 定義具體策略類
- 定義環境角色類
3 抽象類原則:
- 抽象類不能被實例化
- 有抽象方法的類一定是抽象類;類必須要 abstract 修飾
- 抽象方法不能有函數體;即 abstract function fun();
- 抽象類中的非抽象方法,可以被子類調用
- 非抽象子類繼承抽象類,子類必須實現父類的所有抽象方法
- 抽象子類繼承抽象類,無需繼承父類的抽象方法
策略模式的特點
- 功能:具體算法從具體業務處理中獨立
- 多個if-else出現考慮使用策略模式
- 策略算法是形同行為的不同實現(多態)
- 客戶端選擇,上下文來具體實現策略算法
優缺點
優點:
- 避免讓客戶端涉及到重要算法和數據
- 避免使用難以維護的多重條件選擇語句
- 易擴展
缺點:
- 判斷邏輯在客戶端,需求改變時,要更改客戶端的程序。
- 客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。這就意味著客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。
- 增加了對象的數目
- 只適合扁平的算法結構
工廠模式:
簡單工廠模式包含如下三種角色:
- 抽象產品:定義了產品的規范,描述了產品的主要特性和功能。
- 具體產品:實現或者繼承抽象產品的子類。
- 具體工廠:提供了創建產品的方法,使用者通過該方法來獲取產品。
優缺點:
- 優點在于實現對象的創建和對象的使用分離,將對象的創建交給專門的工廠類負責;
- 缺點在于工廠類不夠靈活,增加新的產品時需要修改工廠類的代碼,一旦產品較多時,工廠類將會變得異常復雜。
53、說一說計算機網路體系結構
計算機網絡體系結構一般有三種:OSI七層模型、TCP/IP四層模型、五層結構
簡單說,OSI是一個理論上的網絡通信模型,TCP/IP是實際上的網絡通信模型,五層結構就是為了介紹網絡原理而折中的網絡通信模型。
?OSI 七層模型
OSI 七層模型是國際標準化組織(International Organization for Standardization)制定 的一個用于計算機或通信系統間互聯的標準體系。
- 應用層:通過應用進程之間的交互來完成特定網絡應用,應用層協議定義的是應用進程間通信和交互的規則,常見的有:HTTP、FTP、SMTP、SNMP、DNS;
- 表示層:數據的表示、安全、壓縮。確保一個系統的應用層所發送的消息可以被另一個系統的應用層讀取;
- 會話層:建立、管理、終止會話,是用戶應用程序和網絡之間的接口;
- 運輸層:提供源端與目的端之間提供可靠的透明數據傳輸,傳輸層協議為不同主機上運行的進程提供邏輯通信;
- 網絡層:將網絡地址翻譯成對應的物理地址,實現不同網絡之間的路徑選擇,協議有ICMP、IGMP、IP等;
- 數據鏈路層:在物理層提供比特流服務的基礎上,建立相鄰節點之間的數據鏈路;
- 物理層:建立、維護、斷開物理連接。
TCP/IP四層模型
- 應用層:對應于 OSI 參考模型的(應用層、表示層、會話層)。
- 傳輸層: 對應 OSI 的傳輸層,為應用層實體提供端到端的通信功能,保證了數據 包的順序傳送及數據的完整性。
- 網際層:對應于 OSI 參考模型的網絡層,主要解決主機到主機的通信問題。
- 網絡接口層:與 OSI 參考模型的數據鏈路層、物理層對應。
五層體系結構
- 應用層:對應于 OSI 參考模型的(應用層、表示層、會話層)。
- 傳輸層:對應 OSI 參考模型的的傳輸層
- 網絡層:對應 OSI 參考模型的的網絡層
- 數據鏈路層:對應 OSI 參考模型的的數據鏈路層
- 物理層:對應 OSI 參考模型的的物理層。
54、說一說每一層對應的網絡協議有哪些?
一張表格總結常見網絡協議:
?55、那么數據在各層之間是怎么傳輸的呢?
對于發送方而言,從上層到下層層層包裝,對于接收方而言,從下層到上層,層層 解開包裝。
- 發送方的應用進程向接收方的應用進程傳送數據
- AP先將數據交給本主機的應用層,應用層加上本層的控制信息H5就變成了下一 層的數據單元
- 傳輸層收到這個數據單元后,加上本層的控制信息H4,再交給網絡層,成為網 絡層的數據單元
- 到了數據鏈路層,控制信息被分成兩部分,分別加到本層數據單元的首部 (H2)和尾部(T2)
- 最后的物理層,進行比特流的傳輸
這個過程類似寫信,寫一封信,每到一層,就加一個信封,寫一些地址的信息。到 了目的地之后,又一層層解封,傳向下一個目的地。
56、從瀏覽器地址欄輸入URL到顯示主頁的過程?
這道題,大概的過程比較簡單,但是有很多點可以細挖:DNS解析、TCP三次握 手、HTTP報文格式、TCP四次揮手等等。
我們以輸入www.baidu.com 為例:
?各個過程都使用了哪些協議?
57、URL和URI有什么區別?
- URI:統一資源標識符(Uniform Resource Identifier? ,URI),標識的是Web上每一種可用的資源,如:HTML文檔、圖像、視頻片段、程序等都是由一個URI進行標識的。
- URL:統一資源定位符(Uniform Resource Location ,URL),它是URI的一種子集,主要作用是提供資源的路徑。
區別:
? ? ? ? URL除了提供資源的標識,還可以提供資源訪問的方式。這么比喻,URI像是身份證,可以唯一標識一個人,而URL更像一個住址,而我們可以通過這個URL找到這個人——人類住址協議://地球/中國/湖南/長沙/岳麓區/xx大學/xx號宿舍/530/張三.男。
58、說說HTTP/1.0,1.1,2.0的區別?
區別:
- HTTP/1.0默認是短連接,可以強制開啟,
- HTTP/1.1默認長鏈接,
- HTTP/2.0采用多路復用。
HTTP/1.0:
- 默認使用短連接,每次請求都需要建立一個TCP連接。它可以設置Connetion:Keep-alive這個字段,強制開啟長鏈接。
HTTP/1.1:
- 引入了持久連接,即TCP默認不連接,可以被多個請求復用。
- 分塊傳輸編碼,即服務端每產生一塊數據,就發送一塊,用“流模式”取代“緩存模式”。
- 管道機制,即在同一個TCP連接里面,客戶端可以同時發送多個請求
HTTP/2.0:
- 二進制協議,1.1 版本的頭信息是文本(ASCII 編碼),數據體可以是文本或者 二進制;2.0 中,頭信息和數據體都是二進制。
- 完全多路復用,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回 應,而且不用按照順序一一對應。
- 報頭壓縮,HTTP 協議不帶有狀態,每次請求都必須附上所有信息。Http/2.0 引 入了頭信息壓縮機制,使用 gzip 或 compress 壓縮后再發送。
- 服務端推送,允許服務器未經請求,主動向客戶端發送資源。
59、HTTP/3了解嗎?
HTTP/3主要有兩大變化,傳輸層基于UDP、使用QUIC保證UDP的可靠性。
HTTP/2存在的一些問題,比如重傳等等,都是由于TCP本身的特性導致的,所以 HTTP/3在QUIC的基礎上進行發展而來,QUIC(Quick UDP Connections)直譯為快速UDP網絡連接,底層使用UDP進行數據傳輸。
HTTP/3主要有這些特點:
- 使用UDP作為傳輸層進行通信
- 在UDP的基礎上QUIC協議保證了HTTP/3的安全性,在傳輸的過程中就完成了 TLS加密握手
- HTTPS 要建??個連接,要花費 6 次交互,先是建?三次握?,然后是 TLS/1.3 的三次握?。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次, 減少了交互次數。
- QUIC 有??的?套機制可以保證傳輸的可靠性的。當某個流發?丟包時,只會 阻塞這個流,其他流不會受到影響。
我們拿一張圖看一下HTTP協議的變遷:
60、如何理解HTTP協議是無狀態的?
這個無狀態的狀態值是什么?是客戶端的狀態,所以字面意思,就是HTTP協議中服務端不會保存客戶端的任何信息。
比如當瀏覽器第一次發送請求給服務器時,服務器響應了;如果同個瀏覽器發起第二次請求給服務器時,它還是會響應,但是呢,服務器不知道你就是剛才的那個瀏覽器。
有什么辦法記錄狀態呢?
主要有兩個辦法:Session和Cookie
61、說說Cookie和Session有什么聯系和區別?
- Cookie是保存在客戶端的一小塊文本串的數據。客戶端向服務器發起請求時,服務器會向客戶端發送一個Cookie,客戶端就把Cookie保存起來。在客戶端下次向同一個服務器在發起請求時,Cookie被攜帶發送到服務器。服務器可以根據這個Cookie判斷用戶的身份和狀態。
- Session指的是服務器和客戶端一次會話的過程。它是另一種記錄客戶狀態的機制。不同的是,cookie保存在客戶端的瀏覽器中,而session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上, 這就是session??蛻舳藶g覽器再次訪問時只需要從該session中查找用戶的狀態。
區別:
- 存儲位置不一樣,Cookie 保存在客戶端,Session 保存在服務器端。
- 存儲數據類型不一樣,Cookie 只能保存ASCII,Session可以存任意數據類型,一 般情況下我們可以在 Session 中保持一些常用變量信息,比如說 UserId 等。
- 有效期不同,Cookie 可設置為長時間保持,比如我們經常使用的默認登錄功 能,Session 一般有效時間較短,客戶端關閉或者 Session 超時都會失效。
- 隱私策略不同,Cookie 存儲在客戶端,比較容易遭到不法獲取,早期有人將用 戶的登錄名和密碼存儲在 Cookie 中導致信息被竊取;Session 存儲在服務端,安 全性相對 Cookie 要好一些。
- 存儲大小不同, 單個Cookie保存的數據不能超過4K,Session可存儲數據遠高于 Cookie。
總結
- 上一篇: 数据中心放入海底?微软开始测试“潜艇式”
- 下一篇: 个人php发卡系统,荔枝个人发卡系统PH