一、PHP基礎(chǔ)
1.對(duì)于0,空值,'=','=='等的考察
以下代碼輸出什么
<?php
function judge(){
$num = 0;
if($num = ''){
echo 'a';
}else{
echo 'b';
}
}
?>
輸出b,if中的空值賦值給$num,因此if條件必定為false,還有其他一些大同小異的題目,用=和==判斷for循環(huán)的,只要把握好基本的概念就行了
2.對(duì)于empty、isset概念的考察
isset()和empty()函數(shù)的區(qū)別在于,前者只驗(yàn)證一個(gè)值是否存在,后者在此基礎(chǔ)上還會(huì)檢驗(yàn)它的值是否非空和非0
注:empty()只檢測(cè)變量,檢測(cè)任何非變量的東西都將導(dǎo)致解析錯(cuò)誤
isset() 判斷一個(gè)變量是否已經(jīng)設(shè)置
當(dāng)設(shè)置一個(gè)變量值為0,empty() 認(rèn)為這個(gè)變量同等于空,即相當(dāng)于沒(méi)有設(shè)置
可以定義一個(gè)變量,設(shè)置值為'',0,null,'aaa'幾種不同情況下,用if判斷empty、isset看看結(jié)果
3.預(yù)定義變量
如:php中輸出當(dāng)前腳本文件名的預(yù)定義變量是$_SERVER['PHP_SELF']
與DOCUMENT_ROOT
有關(guān)。如:地址為http://baidu.com/test/kkk.php的腳本,$_SERVER['PHP_SELF']='/test/kkk.php'
還有一些重要的如$_SERVER['DOCUMENT_ROOT']
,輸出網(wǎng)站所在的根目錄,如D:/work/www $_SERVER['SCRIPT_FILENAME']
,輸出'D:/work/www//kkk.php' $_SERVER['HTTP_USER_AGENT']
,獲取客戶端瀏覽器,操作系統(tǒng)等等
其他一些可以通過(guò)print_r($_SERVER)
測(cè)試獲得,當(dāng)然不止這些,還有其他一些預(yù)定義變量,系統(tǒng)常量如FILE也是需要稍微去看一下
4.函數(shù)、算法考察
主要考察php的原生函數(shù),暫時(shí)分為數(shù)組函數(shù)、字符串處理函數(shù)、時(shí)間函數(shù)、文件操作函數(shù)、數(shù)據(jù)庫(kù)函數(shù),后面再看看需不需要擴(kuò)展。注意這些函數(shù)一定都要去過(guò)一遍。
(1.1)遍歷指定文件夾下的所有文件夾及所有子文件夾
確定是文件夾 —— 打開(kāi)文件夾(產(chǎn)生dh句柄) —— 循環(huán)讀取文件夾內(nèi)容(讀取句柄的內(nèi)容,即為file/folder) —— 遞歸讀取上一步判斷為folder且文件夾不為'.'或者'..'的文件夾內(nèi)容
<?php
$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);
?>
(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)寫(xiě)一個(gè)方法獲取url中的文件類型
如$url = 'http://www.qq.com/test.php?a=...'; 取出'php'
function getFileName($url){
$a = explode('?', $url);
$b = strrpos($a[0], '.'); //strrpos(被搜索字符串,要查找字符串,[查找開(kāi)始的位置]) 查找字符串最后一次出現(xiàn)的位置: 找到則返回最后一次出現(xiàn)的位置;未找到則返回false
$c = substr($a[0], $b+1, 3); //substr(被操作字符串,開(kāi)始位置,[結(jié)束位置]) 返回字符串的一部分
return $c;
}
(3)接口知識(shí)的考察
eg.
用戶登錄認(rèn)證,請(qǐng)求地址為http://www.aa.com/user.php,后臺(tái)需要有一個(gè)接口,驗(yàn)證是否正確
請(qǐng)求參數(shù):時(shí)間戳 Time 什么鬼參數(shù)忘了,即為param 還有一個(gè)是token,token值是Time+param的MD5加密,中間有加號(hào)
返回參數(shù):
成功:res['ret'] = 0; res['msg'] = 'success';
失敗:res['ret'] = 1; res['msg'] = 'fail';
返回?cái)?shù)據(jù)格式: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);
}
}
其實(shí)今天筆試的時(shí)候做這道題忘了怎么返回json格式的數(shù)據(jù)了,就直接用了Thinkphp的ajaxReturn,后來(lái)回來(lái)的時(shí)候查了一下才知道原來(lái)直接echo,這么簡(jiǎn)單,框架還是為輔吧,要多寫(xiě)原生。今天筆試的是一家手游公司,對(duì)數(shù)據(jù)庫(kù)操作和原生要求比較多。
5.對(duì)緩存的了解
php緩存技術(shù)詳細(xì)介紹及php緩存的實(shí)現(xiàn)代碼
二、數(shù)據(jù)庫(kù)知識(shí)
1.數(shù)據(jù)庫(kù)的基本增刪查改
基本的增刪改查語(yǔ)句,關(guān)聯(lián)語(yǔ)句,函數(shù)等過(guò)一遍
2.談?wù)剶?shù)據(jù)庫(kù)優(yōu)化的方法
(1)創(chuàng)建表的時(shí)候避免使用NULL默認(rèn)值,因?yàn)镹ULL對(duì)于大多數(shù)數(shù)據(jù)庫(kù)都需要進(jìn)行特殊處理和索引邏輯等等。所以大多數(shù)時(shí)候不用NOT NULL,可以用特殊值0或1代替
(2)盡可能使用更小的字段類型,因?yàn)閙ysql從磁盤讀取數(shù)據(jù)之后是存到內(nèi)存當(dāng)中,這意味著更小的數(shù)據(jù)類型使得從磁盤讀取或者打包到內(nèi)存效率會(huì)更好
(3)字符集的轉(zhuǎn)換:客戶端或者應(yīng)用程序使用的字符集可能和數(shù)據(jù)庫(kù)使用的字符集不一致,需要在mysql運(yùn)行過(guò)程中隱含轉(zhuǎn)化
(4)創(chuàng)建索引,如果一張表很大然后符合條件的值很多,那么創(chuàng)建索引就能帶來(lái)性能的提升。但是如果像性別,只有兩個(gè)值,就沒(méi)必要建索引,而是用enum。一張表的索引最好不超過(guò)6個(gè),太多的話會(huì)影響Insert和Update的效率,因此要考慮刪除使用不頻繁的索引
(5)先考慮在where和order by這兩列上建立索引。盡量少在where子句中進(jìn)行表達(dá)式操作、函數(shù)操作等等
(6)盡量避免使用select * ,只查詢需要用到的字段。盡量用betwwen and 代替in 和not in,也要避免在大量數(shù)據(jù)的where子句中使用or
(7)模糊查詢優(yōu)化:
使用FULLTEXT全文搜索(注意前提是MyISAM存儲(chǔ)引擎)
FULLTEXT解析器用“ ”(空格)、“,”(逗號(hào))“.”(點(diǎn)號(hào))作為默認(rèn)的單詞分隔符,因此對(duì)于不使用這些分隔符的語(yǔ)言如漢語(yǔ)來(lái)說(shuō),F(xiàn)ULLTEXT解析器不能正確的識(shí)別單詞,對(duì)于這種情況需做額外處理。
(8)盡量滿足范式(有的情況下要用反范式)下面是三大范式的區(qū)別,也要去看一下
第一范式:數(shù)據(jù)庫(kù)表的每一列都是不可分割的原子數(shù)據(jù)項(xiàng),而不能是集合,數(shù)組,記錄等非原子數(shù)據(jù)項(xiàng)。如果實(shí)體中的某個(gè)屬性有多個(gè)值時(shí),必須拆分為不同的屬性
第二范式:滿足第一范式前提,當(dāng)存在多個(gè)主鍵的時(shí)候,才會(huì)發(fā)生不符合第二范式的情況。比如有兩個(gè)主鍵,不能存在這樣的屬性,它只依賴于其中一個(gè)主鍵,這就是不符合第二范式
第三范式:滿足第二范式前提,如果某一屬性依賴于其他非主鍵屬性,而其他非主鍵屬性又依賴于主鍵,那么這個(gè)屬性就是間接依賴于主鍵,這被稱作傳遞依賴于主屬性。
3.談?wù)凪yisam和Innodb存儲(chǔ)引擎
(1)MyISAM強(qiáng)調(diào)性能,其執(zhí)行速度比InnoDB類型更快,但不支持事務(wù),而InnoDB提供事務(wù)支持以及外部鍵、行級(jí)鎖等高級(jí)數(shù)據(jù)庫(kù)功能
(2)如果增刪改操作比較多,或者需要事務(wù)支持,則使用Innodb,如果是讀的操作比較多,則使用Myisam
(3)MyISAM表鎖,Innodb行鎖
4.談?wù)刴emcached和redis的異同
一、關(guān)于讀寫(xiě)性能(QPS)
memcache更加快速,在性能上比redis快,缺點(diǎn)是僅支持字符串。
Redis支持豐富的數(shù)據(jù)結(jié)構(gòu)類型,字符串,散列(哈希),集合,有序集合還支持訂閱發(fā)布,地理位置等。
實(shí)際運(yùn)用中可以結(jié)合二者,memcache可作為session存儲(chǔ)的方式,session都是kv鍵值對(duì)。
Redis提供了多種不同級(jí)別的持久化方式:
RDB持久化可以在指定的時(shí)間間隔內(nèi)生成數(shù)據(jù)集的時(shí)間點(diǎn)快照;
AOF持久化記錄服務(wù)器執(zhí)行的所有寫(xiě)操作命令,并在服務(wù)器啟動(dòng)時(shí),通過(guò)重新執(zhí)行這些命令來(lái)還原數(shù)據(jù)集。
AOF文件中的命令全部以Redis協(xié)議的格式來(lái)保存,新命令會(huì)被追加到文件的尾部,Redis還可以在后臺(tái)對(duì)AOF文件進(jìn)行重寫(xiě)(rewrite),使得AOF文件的體積不會(huì)超出保存數(shù)據(jù)集狀態(tài)所需的實(shí)際大小。
Redis還可以同時(shí)使用AOF持久化和rob持久化,在這種情況下,當(dāng)Redis重啟時(shí),它會(huì)優(yōu)先使用AOF文件來(lái)還原數(shù)據(jù)集,因?yàn)锳OF文件保存的數(shù)據(jù)集通常比rob保存的數(shù)據(jù)更完整。
工作原理
memcache是把所有的數(shù)據(jù)保存在內(nèi)存中,采用hash表的方式,每條數(shù)據(jù)由key,value組成,每個(gè)key都是獨(dú)一無(wú)二的,當(dāng)要訪問(wèn)某個(gè)值得時(shí)候,先按照鍵找到值然后返回結(jié)果。memcache采用LPU(least recently used)算法來(lái)逐漸把過(guò)期數(shù)據(jù)清理掉。
三、算法
1.寫(xiě)一個(gè)函數(shù)判斷數(shù)組的深度
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;
}
四、計(jì)算機(jī)網(wǎng)絡(luò)
1.說(shuō)一下常見(jiàn)的HTTP狀態(tài)碼
(1)消息(臨時(shí)響應(yīng)):1字頭。
這一類型的狀態(tài)碼,代表請(qǐng)求已被接受,需要繼續(xù)處理。這類響應(yīng)是臨時(shí)響應(yīng),只包含狀態(tài)行和某些可選的響應(yīng)頭信息,并以空行結(jié)束。由于 HTTP/1.0 協(xié)議中沒(méi)有定義任何 1xx 狀態(tài)碼,所以除非在某些試驗(yàn)條件下,服務(wù)器禁止向此類客戶端發(fā)送 1xx 響應(yīng)。
eg.
100: 服務(wù)器僅接收到部分請(qǐng)求
101: 服務(wù)器已經(jīng)理解了客戶端的請(qǐng)求,并將通過(guò)Upgrade 消息頭通知客戶端采用不同的協(xié)議來(lái)完成這個(gè)請(qǐng)求。
(2)成功:2字頭。
代表請(qǐng)求已經(jīng)被服務(wù)器所接收、理解、并接受
eg.
200: 請(qǐng)求成功(其后是對(duì)GET和POST請(qǐng)求的應(yīng)答文檔。)
201: 請(qǐng)求被創(chuàng)建完成,同時(shí)新的資源被創(chuàng)建。
(3)重定向:3字頭。
表示要完成請(qǐng)求,需要進(jìn)一步操作。 通常,這些狀態(tài)代碼用來(lái)重定向。
eg.
300: 多重選擇。鏈接列表。用戶可以選擇某鏈接到達(dá)目的地。
301: 頁(yè)面永久重定向
302: 頁(yè)面臨時(shí)重定向
304: 資源未被修改,服務(wù)器告訴客戶,原來(lái)緩沖的文檔還可以繼續(xù)使用
(4)請(qǐng)求錯(cuò)誤:4字頭。
這些狀態(tài)代碼表示請(qǐng)求可能出錯(cuò),妨礙了服務(wù)器的處理
eg.
400: 服務(wù)器未能理解請(qǐng)求
401: 被請(qǐng)求的頁(yè)面需要用戶名和密碼。
403: 對(duì)請(qǐng)求頁(yè)面的訪問(wèn)被禁止。(通常為沒(méi)有讀權(quán)限)
404: 服務(wù)器無(wú)法找到被請(qǐng)求的頁(yè)面。
408: 超出服務(wù)器等待時(shí)間
413: 由于所請(qǐng)求的實(shí)體的太大,服務(wù)器不會(huì)接受請(qǐng)求。
414: 由于url太長(zhǎng),服務(wù)器不會(huì)接受請(qǐng)求。當(dāng)post請(qǐng)求被轉(zhuǎn)換為帶有很長(zhǎng)的查詢信息的get請(qǐng)求時(shí),就會(huì)發(fā)生這種情況。
(5)服務(wù)器錯(cuò)誤:5字頭。
這些狀態(tài)代碼表示服務(wù)器在嘗試處理請(qǐng)求時(shí)發(fā)生內(nèi)部錯(cuò)誤。這些錯(cuò)誤可能是服務(wù)器本身的錯(cuò)誤,而不是請(qǐng)求出錯(cuò)
eg.
500: 請(qǐng)求未完成。服務(wù)器遇到不可預(yù)知的情況。
502: 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從上游服務(wù)器接收到無(wú)效的響應(yīng)。
503: 服務(wù)器臨時(shí)過(guò)載或當(dāng)機(jī)。
504: 網(wǎng)關(guān)超時(shí)。
五、前端
1.考察函數(shù)
<input type="text" good="" />
獲取input標(biāo)簽中的good屬性值所用的函數(shù)是getAttribute("good")
2.考察jquery
<div id='table'></div>
用ajax方法,把請(qǐng)求返回的參數(shù)(格式是json)填充到table中,以表格形式列出
var html = '';
$(function(){
$.ajax({
type:'post',
url:'.....',
data:(忘了發(fā)送的參數(shù)是什么了,隨便寫(xiě)一下){
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(){
}
})
})
六、其他
1.遇到問(wèn)題時(shí)怎么解決(錯(cuò)誤日志)
首先開(kāi)啟錯(cuò)誤日志,配置php.ini
error_reporting = E_ALL ;將會(huì)向PHP報(bào)告發(fā)生的每個(gè)錯(cuò)誤,包括ERROR、NOTICE、WARNING等等
display_errors = Off ;本地測(cè)試開(kāi)啟,項(xiàng)目上線要關(guān)閉,防止服務(wù)器重要信息泄露
log_errors = On ;開(kāi)啟錯(cuò)誤日志
log_errors_max_len = 1024 ;設(shè)置每個(gè)日志項(xiàng)的最大長(zhǎng)度
error_log = /www/phpernote/error.log ;指定產(chǎn)生的錯(cuò)誤報(bào)告寫(xiě)入的日志文件位置
配置完之后重啟服務(wù)器即可,參考了php的異常和處理文章的一小段代碼,自己另外做了測(cè)試
<?php
set_error_handler('myErrorHandler');
function myErrorHandler($errno,$errmsg,$file,$line){
echo "<b>錯(cuò)誤代碼:</b>[{$errno}] {$errmsg} <br/>".PHP_EOL;
echo "<b>錯(cuò)誤行號(hào):</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('時(shí)間:' . $datetime . '錯(cuò)誤的信息:' . $errmsg . '錯(cuò)誤文件所在位置:' . $_SERVER['SCRIPT_FILENAME']);
}
echo $test;
test();
echo 'good';
?>
手動(dòng)分割線
在上面提到的內(nèi)容,其實(shí)有一些可以自己去拓展看一下的,比如提到innodb和myisam,前者是使用行鎖,后者是使用表鎖,那可以去拓展一下,什么是表鎖什么事行鎖,逐漸增大自己的知識(shí)面