PHP工程師面試題+筆試題

最近在廣州找工做,大四狗,讀着三本前兩年剛升二本的學校,文科生,好像一切條件都很是不利,但我仍是毅然選擇這條路——拍黃片,人不能固步自封,仍是要拓展一下本身的知識面,不能只學php而不拓展視野,仍是要學學python、java、前端這些
面試得有點心塞,各類由於學歷被刷,校招只投了幾個,不是被刷了簡歷就是沒勇氣投,默默告訴本身,之後必定要叫本身的兒子多考幾分!
她說我最近看起來很疲憊。
對啊由於找工做數日睡很差了
他說還好,咱們如今惟一的目標是找工做,不用考慮其餘的。
是啊,就像高考那會同樣。
話很少說,下面寫一下最近所經歷的一些面試題,之後會繼續補充的php

1、PHP基礎

1.對於0,空值,'=','=='等的考察

如下代碼輸出什麼css

<?php
    function judge(){
        $num = 0;
        if($num = ''){
            echo 'a';
        }else{
            echo 'b';
        }
    }
?>

輸出b,if中的空值賦值給$num,所以if條件一定爲false,還有其餘一些大同小異的題目,用=和==判斷for循環的,只要把握好基本的概念就好了html

2.對於emptyisset概念的考察

isset()empty()函數的區別在於,前者只驗證一個值是否存在,後者在此基礎上還會檢驗它的值是否非空和非0
注:empty()只檢測變量,檢測任何非變量的東西都將致使解析錯誤
isset() 判斷一個變量是否已經設置
當設置一個變量值爲0,empty() 認爲這個變量同等於空,即至關於沒有設置前端

能夠定義一個變量,設置值爲'',0,null,'aaa'幾種不一樣狀況下,用if判斷empty、isset看看結果java

3.預約義變量

如:php中輸出當前腳本文件名的預約義變量是$_SERVER['PHP_SELF']
DOCUMENT_ROOT有關。如:地址爲http://baidu.com/test/kkk.php...$_SERVER['PHP_SELF']='/test/kkk.php'
還有一些重要的如$_SERVER['DOCUMENT_ROOT'],輸出網站所在的根目錄,如'D:/work/www'
$_SERVER['SCRIPT_FILENAME'],輸出'D:/work/www//kkk.php'
$_SERVER['HTTP_USER_AGENT'],獲取客戶端瀏覽器,操做系統等等
其餘一些能夠經過print_r($_SERVER)測試得到,固然不止這些,還有其餘一些預約義變量,系統常量如__FILE__也是須要稍微去看一下python

4.函數、算法考察

主要考察php的原生函數,暫時分爲數組函數、字符串處理函數、時間函數、文件操做函數、數據庫函數,後面再看看需不須要擴展。注意這些函數必定都要去過一遍。mysql

(1.1)遍歷指定文件夾下的全部文件夾及全部子文件夾

肯定是文件夾 —— 打開文件夾(產生dh句柄) —— 循環讀取文件夾內容(讀取句柄的內容,即爲file/folder) —— 遞歸讀取上一步判斷爲folder且文件夾不爲'.'或者'..'的文件夾內容jquery

<?phpnginx

$dir = "D:/www/project/";
 function readDirectory($dir){
    if(is_dir($dir)){        //
         if ($dh = opendir($dir)) {
             while (($file = readdir($dh)) != false) {
                 if (is_dir($dir.$file) && $file!="." && $file!="..") {
                     echo $dir.$file."<br/>";
                     readDirectory($dir.$file."/");
                 }
             }
             closedir($dh);
         }
     }
} 
readDirectory($dir);

?>web

(1.2)遍歷指定文件夾下的全部文件及其子文件夾中的全部文件

<?php
    $dir = "D:/www/project/";
    function readDirectory($dir){
        if(is_dir($dir)){        //
             if ($dh = opendir($dir)) {
                 while (($file = readdir($dh)) != false) {
                     if (is_file($dir.$file)) {
                         echo "filename:".$file."<br/>";
                         // echo $dir.$file."<br/>";
                         echo "filetype:".filetype($dir.$file)."<br/>";
                     } 
                     if (is_dir($dir.$file) && $file!="." && $file!="..") {
                         readDirectory($dir.$file."/");
                     }
                 }
                 closedir($dh);
             }
         }
    }
    readDirectory($dir);

?>

(2)寫一個方法獲取url中的文件類型

如$url = 'http://www.qq.com/test.php?a=...'; 取出'php'

function getFileName($url){
    $a = explode('?', $url);
    $b = strrpos($a[0], '.');   //strrpos(被搜索字符串,要查找字符串,[查找開始的位置])  查找字符串最後一次出現的位置: 找到則返回最後一次出現的位置;未找到則返回false
    $c = substr($a[0], $b+1, 3);  //substr(被操做字符串,開始位置,[結束位置])  返回字符串的一部分
    return $c;
}

(3)接口知識的考察

eg.
用戶登陸認證,請求地址爲http://www.aa.com/user.php,後...,驗證是否正確
請求參數:時間戳 Time 什麼鬼參數忘了,即爲param 還有一個是token,token值是Time+param的MD5加密,中間有加號
返回參數:
成功:res['ret'] = 0; res['msg'] = 'success';
失敗:res['ret'] = 1; res['msg'] = 'fail';
返回數據格式:json
下面是個人思路:

function valid(){
    $data = $_GET['data'];
    if(!$data){
        $res['ret'] = 1;
        $res['msg'] = 'fail';
        echo json_encode($res);
    }
    $str = $data['Time'] . '+' . $data['param'];
    if($data['token'] != md5($str)){
        $res['ret'] = 1;
        $res['msg'] = 'fail';
        echo json_encode($res);
    }else{
        $res['ret'] = 0;
        $res['msg'] = 'success';
        echo json_encode($res);
    }
}

其實今天筆試的時候作這道題忘了怎麼返回json格式的數據了,就直接用了Thinkphp的ajaxReturn,後來回來的時候查了一下才知道原來直接echo,這麼簡單,框架仍是爲輔吧,要多寫原生。今天筆試的是一家手遊公司,對數據庫操做和原生要求比較多。

5.get和post的區別

是http協議的兩種請求方式,而http是基於TCP/IP應用層的協議,因此兩種都是用的同一個傳輸層協議
get是將請求信息以鍵值對的形式放在URL上,post是經過HTTP Header 傳遞數據
當咱們使用get時,全部的信息都會出如今URL地址中,安全性比較低。
使用get最大傳遞的數據長度是2kb(根據服務器配置以及用戶瀏覽器配置考慮),因此若是在傳輸量小或者安全性不那麼重要的狀況下可使用get
post並無長度限制,安全性較高
有人說post比get更安全,這只是相對的,但都是能夠被抓包的。要想安全傳輸,就只有加密,也就是 HTTPS

6.cookie和session

(1)cookie數據存放在客戶的瀏覽器上,session數據放在服務器上
(2)cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙,若是主要考慮到安全應當使用session
(3)session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能,若是主要考慮到減輕服務器性能方面,應當使用COOKIE
(4)單個cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能3K。
(5)因此:將登錄信息等重要信息存放爲SESSION;其餘信息若是須要保留,能夠放在COOKIE

7.cookie禁用後如何使用session

第一種方式:在每一個超連接上添加一個PHPSESSID=$sid

//防止返回初始頁產生新的session

if(isset($_GET["PHPSESSID"])){
session_id($_GET["PHPSESSID"]);
}
//啓動一個session
session_start();
//獲取當前session的session_id()
$sid=session_id();
//在每一個連接上添加參數PHPSESSID=$sid
其餘頁面的獲取方式爲:
if(isset($_GET["PHPSESSID"])){
//設置當前的session爲初始的session,session_id()一致便可
session_id($_GET["PHPSESSID"]) 
}
session_start();

第二種方式:使用 SID 常量替換連接上的 PHPSESSID=$sid (SID的值相似:PHPSESSID=sddg34r593dfdlksrewr)

if(isset($_GET["PHPSESSID"])){
session_id($_GET["PHPSESSID"]);
}
//啓動一個session
session_start();

其餘頁面的獲取方式爲:
if(isset($_GET["PHPSESSID"])){
//設置當前的session爲初始的session,session_id()一致便可
session_id($_GET["PHPSESSID"]) 
}
session_start();

第三種方式:使用session.use_trans_sid=1,php.ini中配置
這種方式會在url上自動加上SID(href,location,action,注意:js跳轉不會添加上SID)

8.對緩存的瞭解

分佈式緩存瞭解一下

9.PHP7升級遇到的問題(針對簡歷)

相關的問題還有PHP7性能提高了,爲何

10.PHP經常使用到的拓展

curl(鏈接通信各類服務器、使用各類協議)、gd(圖像生成和處理)、mcrypt(加密擴展庫)、mysqli(跟mysql系統函數的區別:mysqli是mysql系統函數的加強版,更穩定更高效更安全,與mysql_query()對應的有mysqli_query(),屬於面向對象,用對象的方式操做驅動mysql數據庫。mysqli是永遠鏈接函數,mysqli屢次運行mysqli將使用同一鏈接進程,從而減小了服務器的開銷。) openssl(對稱/非對稱加解密)、pcre(正則,相關的問題還有經常使用的正則庫PCRE/POSIX)

11.常見的錯誤級別有哪些,解決方案

notice、warning、error、exception等
————————————————

2、mysql數據庫知識

1.數據庫的基本增刪查改

基本的增刪改查語句,關聯語句,函數等過一遍就行,能夠過一下imooc的教程
慕課網——與MySQL的零距離接觸

2.談談數據庫優化/複雜sql優化的方法

(1)遇到一個頁面查詢緩慢的時候,由於可能會有多個sql,因此我首先是會去開啓慢查詢日誌,定位到是哪一條sql
(2)肯定sql以後,若是是非查詢類型的如修改刪除就改成查詢類型。
(3)檢查sql是否是有一些複雜查詢,好比子查詢,聯合查詢等等,將這些能夠拆分的sql拆解出來
(4)把拆解出來的sql進行show profiles檢查,查看具體每條子sql的執行時間
(5)或者直接explain你的sql語句,
最主要的一個是type類型,能夠看到指定的表使用的鏈接方式,是null,system,const,eq_ref,ref,range,index仍是all(各自表明的含義)
比較好的sql查詢至少達到range級別,最好達到ref
看看id列,id列表示執行順序,id越大,則越先執行
(6)一張表的索引最好不超過6個。考慮刪除使用不頻繁的索引。理想的索引狀況下,查詢頻繁,區分度高(如字段值只有男和女區分度就不高),長度小,儘可能能覆蓋經常使用的查詢字段
針對列中的值從左往右創建索引,截的越短,重複度越高區分度越小,因此效果越很差
截的越長,區分度越高,索引效果好,可是增刪改慢間接影響查詢速度
優先考慮在where 和orderby創建索引。

還有其它常見的就

  • 把不須要的字段去掉
  • 給每一個字段加默認值,避免使用NULL默認值
  • 字段長度能省則省,
  • 避免使用select *,
  • 減小在where中進行表達式、函數操做和or條件判斷
  • 儘量使用更小的字段類型(由於mysql從磁盤讀取數據以後是存到內存當中,這意味着更小的數據類型使得從磁盤讀取或者打包到內存效率會更好)等等

(7)字符集的轉換:客戶端或者應用程序使用的字符集可能和數據庫使用的字符集不一致,須要在mysql運行過程當中隱含轉化
(8)模糊查詢優化:
使用FULLTEXT全文搜索(注意前提是MyISAM存儲引擎)
FULLTEXT解析器用「 」(空格)、「,」(逗號)「.」(點號)做爲默認的單詞分隔符,所以對於不使用這些分隔符的語言如漢語來講,FULLTEXT解析器不能正確的識別單詞,對於這種狀況需作額外處理。
(9)儘可能知足範式(有的狀況下要用反範式)下面是三大範式的區別,也要去看一下
第一範式:數據庫表的每一列都是不可分割的原子數據項,而不能是集合,數組,記錄等非原子數據項。若是實體中的某個屬性有多個值時,必須拆分爲不一樣的屬性

clipboard.png

第二範式:知足第一範式前提,當存在多個主鍵的時候,纔會發生不符合第二範式的狀況。好比有兩個主鍵,不能存在這樣的屬性,它只依賴於其中一個主鍵,這就是不符合第二範式

![clipboard.png](/img
clipboard.png

第二範式:知足第一範式前提,當存在多個主鍵的時候,纔會發生不符合第二範式的狀況。好比有兩個主鍵,不能存在這樣的屬性,它只依賴於其中一個主鍵,這就是不符合第二範式

clipboard.png

第三範式:知足第二範式前提,若是某一屬性依賴於其餘非主鍵屬性,而其餘非主鍵屬性又依賴於主鍵,那麼這個屬性就是間接依賴於主鍵,這被稱做傳遞依賴於主屬性。

clipboard.png

3.談談Myisam和Innodb存儲引擎

(1)MyISAM強調性能,其執行速度比InnoDB類型更快,但不支持事務,而InnoDB提供事務支持以及外部鍵、行級鎖等高級數據庫功能
(2)若是增刪改操做比較多,或者須要事務支持,則使用Innodb,若是是讀的操做比較多,則使用Myisam
(3)MyISAM表鎖,Innodb行鎖

4.談談memcached和redis的異同

(1)memcached只能使用簡單的key-value形式進行存儲,而redis還支持hash,list,set等等。所以須要其餘的數據類型支持的時候用redis更方便
(2)memcached是多核,redis是單核,因此在存儲小數據上redis性能更高,反之大數據上memcached的性能比redis要高
(3)memcached不支持持久化操做,數據不能備份,只能用於緩存使用,重啓後數據所有丟失。
redis支持持久化操做能夠數據備份和數據恢復
(4)redis只能使用單線程,性能受限於cpu性能,memecached是多線程

5.事務應用場景、隔離級別等

(1)事務的四大特性(ACID

Atomicity原子性:事務是一個不可分割的工做單位,要麼都發生要麼都不發生
Consistency一致性:必須使數據庫從一個一致性狀態變換到另一個一致性狀態(即開啓一個事務以後不能再開啓一個事務,除非提交或者新建一個線程)
Isolation隔離性:多個用戶併發訪問數據庫時,數據庫爲每一個用戶開啓的事務不能被其它事務的操做數據干擾,多個併發事務之間要相互隔離
Durability持久性:未commit以前能夠回滾,一旦commit對數據的改變就是永久性的
事務保存點

能夠設置多個保存點 savepoint a;savepoint b;savepoint c;
可是回退須要按照順序回退,即若是回退rollback to b; c保存點就不存在了

(2)事務的隔離級別

①讀未提交(read uncommitted)
set session transaction isolation level read uncommitted
②讀已提交(read committed)
set session transaction isolation level read committed
③可重複讀(repeatable read) 系統默認的隔離級別
set session transaction isolation level repeatable read
④可串行化(serializable)(獨佔某個線程的時候使用,直到A程序commit後B程序才能成功update,在那以前是在隊列中)
set session transaction isolation level serializable
隔離程度,從上到下愈來愈強

(3)隔離級別帶來的問題

①髒讀:一個事務讀取另外一個事務還沒有提交的修改
②不可重複讀:同一查詢在同一事務中屢次進行,因爲其餘提交事務所作的修改或刪除,每次返回不一樣的結果集
③幻讀(虛讀):同一查詢在同一事務中屢次進行,因爲其餘提交事務所作的插入操做,每次返回不一樣的結果集
image.png

6.mysql分庫分表分區

3、算法

1.寫一個函數判斷數組的深度

function getDepth($arr){

$max_depth = 1;
foreach($arr as $key=>$val){
    if(is_array($val)){
        $depth = getDepth($val) + 1;
        if($depth > $max_depth){
            $max_depth = $depth;
        }
    }
    
}
return $max_depth;

}

4、計算機網絡

1.說一下常見的HTTP狀態碼

(1)消息(臨時響應):1字頭。
這一類型的狀態碼,表明請求已被接受,須要繼續處理。這類響應是臨時響應,只包含狀態行和某些可選的響應頭信息,並以空行結束。因爲 HTTP/1.0 協議中沒有定義任何 1xx 狀態碼,因此除非在某些試驗條件下,服務器禁止向此類客戶端發送 1xx 響應。
eg.
100: 服務器僅接收到部分請求
101: 服務器已經理解了客戶端的請求,並將經過Upgrade 消息頭通知客戶端採用不一樣的協議來完成這個請求。
(2)成功:2字頭。
表明請求已經被服務器所接收、理解、並接受
eg.
200: 請求成功(其後是對GET和POST請求的應答文檔。)
201: 請求被建立完成,同時新的資源被建立。
(3)重定向:3字頭。
表示要完成請求,須要進一步操做。 一般,這些狀態代碼用來重定向。
eg.
300: 多重選擇。連接列表。用戶能夠選擇某連接到達目的地。
301: 頁面永久重定向
302: 頁面臨時重定向
304: 資源未被修改,服務器告訴客戶,原來緩衝的文檔還能夠繼續使用
(4)請求錯誤:4字頭。
這些狀態代碼表示請求可能出錯,妨礙了服務器的處理
eg.
400: 服務器未能理解請求
401: 被請求的頁面須要用戶名和密碼。
403: 對請求頁面的訪問被禁止。(一般爲沒有讀權限)
404: 服務器沒法找到被請求的頁面。
408: 超出服務器等待時間
413: 因爲所請求的實體的太大,服務器不會接受請求。
414: 因爲url太長,服務器不會接受請求。當post請求被轉換爲帶有很長的查詢信息的get請求時,就會發生這種狀況。
(5)服務器錯誤:5字頭。
這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。這些錯誤多是服務器自己的錯誤,而不是請求出錯
eg.
500: 請求未完成。服務器遇到不可預知的狀況。
502: 做爲網關或者代理工做的服務器嘗試執行請求時,從上游服務器接收到無效的響應。
503: 服務器臨時過載或當機。
504: 網關超時。

5、前端

1.考察函數

<input type="text" good="" />
獲取input標籤中的good屬性值所用的函數是getAttribute("good")

2.考察jquery

<div id='table'></div>

用ajax方法,把請求返回的參數(格式是json)填充到table中,以表格形式列出
21號下午一道筆試題,由於須要聯繫上文有點麻煩,大概講一下思路吧,主要是考察對jq的ajax函數還有其餘一些jq函數的熟悉程度,我直接上代碼

var html = '';
$(function(){
    $.ajax({
        type:'post',
        url:'.....',
        data:(忘了發送的參數是什麼了,隨便寫一下){
            a:111,
            b:222
        },
        dataType:json,
        success:function(data){
            var res = jQuery.parseJSON(data);
            for(var i=0;i<res.length;i++){
                html += '<tr><td>' + res[i].Time + '</td><td>' + res[i].num + '</td></tr>'; 
            }
            $('#table').html('<table>' + html + '</table>');
        },
        error:function(){
        }
    })
})

6、服務器相關知識

1.經常使用指令

隨便寫些經常使用指令:mkdir cd chmod rm cp tar make cat vi ps等等
查看文件最後10行:tail 1.txt
最後25行:tail -25 1.txt
頭5行:head -5 1.txt

2.文件權限

755 rwxr-xr-x表明含義:
第一位7等於4+2+1,因此就是rwx,全部者有讀取、寫入、執行的權限
第二位5是4+1,r-x,同組用戶具備讀取、執行權限,
第三位5,表明其餘用戶有讀取、執行的權限。
從左至右,1-3位表明文件全部者的權限,4-6位表明同組用戶的權限,7-9表明其餘用戶的權限。

3.高併發大數據處理經驗

(1)流量優化:

防盜鏈處理(在nginx上配置),防止圖片、資源等被非法調用

(2)前端優化:

①合併一些css、js文件,減小http請求

雪碧圖css spirites
前端自動構建工具打包
圖片使用base64編碼

②啓用瀏覽器緩存和文件壓縮

給靜態資源文件指定過時時間
文件壓縮如把圖片壓縮小一些,減小流量帶寬消耗

③CDN加速

把一些前端資源文件放到cdn中,還能夠把數據緩存到cdn節點中
cdn原理:

image.png
④創建獨立圖片服務器
⑤一些不重要的數據,能夠作成ajax異步請求,在須要的時候再進行引入、展現,如js、jquery等等

(3)服務端

①頁面靜態化,如smarty
②作一些程序上的併發處理,如多線程多進程的異步處理、隊列處理等
③隊列處理

(4)數據庫

①數據庫緩存(memcache redis等)
②分庫分表、分區操做

垂直拆分、水平拆分
分區

③讀寫分離

把一些服務器、一些數據徹底分開
一些服務器作讀操做(查詢) 一些服務器作些操做(增刪改)

④負載均衡
⑤索引、高併發安全問題加鎖

(5)web服務器優化

使用nginx的反向代理來實現負載均衡

4.負載均衡

7、其餘

1.遇到問題時怎麼解決(錯誤日誌)

我回答的時候舉了作項目的時候的例子,先縷一下思路。由於後臺這一塊,只要思路縷清了,在紙上寫出來,接下來一步一步去debug,不斷var_dump、print_r、echo,最後exit()一下,其實很好debug
後來發現面試官想問的其實不是這個,而是錯誤日誌,今天特地去搜了一下,研究了一個下午終於會一點點

首先開啓錯誤日誌,配置php.ini
error_reporting = E_ALL ;將會向PHP報告發生的每一個錯誤,包括ERROR、NOTICE、WARNING等等
display_errors = Off ;本地測試開啓,項目上線要關閉,防止服務器重要信息泄露
log_errors = On ;開啓錯誤日誌
log_errors_max_len = 1024 ;設置每一個日誌項的最大長度
error_log = /www/phpernote/error.log ;指定產生的錯誤報告寫入的日誌文件位置

配置完以後重啓服務器便可,參考了php的異常和處理文章的一小段代碼,本身另外作了測試

<?php
set_error_handler('myErrorHandler');
function myErrorHandler($errno,$errmsg,$file,$line){
    echo "<b>錯誤代碼:</b>[{$errno}] {$errmsg} <br/>".PHP_EOL;
    echo "<b>錯誤行號:</b>{$file}文件中的第 {$line} 行<br/>".PHP_EOL;
    echo "<b>PHP版本:</b>".PHP_VERSION."(".PHP_OS.") <br/>".PHP_EOL;
    $datetime = date('Y-m-d H:i:s',time()); 
    error_log('時間:' . $datetime  . '錯誤的信息:' . $errmsg . '錯誤文件所在位置:' . $_SERVER['SCRIPT_FILENAME']);
 }

echo $test;
test();
 echo 'good';
?>

下面是error.log輸出的內容
clipboard.png

網頁輸出的內容:

clipboard.png


手動分割線
在上面提到的內容,其實有一些能夠本身去拓展看一下的,好比提到innodb和myisam,前者是使用行鎖,後者是使用表鎖,那能夠去拓展一下,什麼是表鎖什麼事行鎖,逐漸增大本身的知識面

先更新到這,明天還得去招聘會碰壁...
2017/03/18

先寫到這裏。前兩天跑了廣工招聘會,今天有一家聯繫明天面試了 ,繼續去撞壁...
2017/03/20

今天基本肯定offer,去一家手遊公司,實習期一天100,轉正後6K,包三餐,單雙休,上午九點上班,週五週六6點下班,平時都是到8點,8~8.5小時的工做時間,上班時間有點大,不過應屆畢業生嘛,學歷也通常,其實這樣的工做強度加上薪資我以爲已是能夠接受了。hr姐姐今天跟我說其實我筆試成績通常,面試不錯。但願實習期之間表現好一點,爭取可以轉正吧,但願各位應屆畢業生也能有一份好的offer,多去嘗試,學歷高的當然好,學歷低的也不要怕,多去跑一下招聘會宣講會,仍是感謝一直鼓勵我去投其餘公司的黑妹(男的),多嘗試,總會有機會的!昨天剛過完22歲生日,今天肯定offer,明天五月天演唱會,一切來得剛恰好。切驕切燥,加油!
2017/03/24

七月底裸辭了,順便考了駕照,瀟灑了一陣子。可是辭職時有多灑脫,如今就有多焦慮,找工做仍是須要看緣分,不知道之後會不會繼續作技術,仍是以爲本身對技術沒有太多的天分,不少東西仍是比較文科生思惟,但願能肯定一份好的offer吧,期待下午這聲鈴響。2019/10/21

相關文章
相關標籤/搜索