文章目錄
- 1. 寫一個 函數,array_remove(),要求最簡潔的清除數組中值為$v的項。
- 2. 以下登陸代碼安全上有什麼問題?
- 3.寫一個函數,算出兩個檔案的相對路徑
- 2. 如何查看當前伺服器1111連接埠的連結總數是?
- 3. 如何列出當前進程裡有多少包含apache名字的進程?
1. 寫一個 函數,array_remove(),要求最簡潔的清除數組中值為$v的項。
解析:
問題的表述很簡潔,無需過多解釋,假設函數原型為array_remove($v , $array)。需要注意的幾點有:
<1> 對於參數的檢查.如果$array不是數組的話,返回錯誤或者拋出異常。
<2> 如何比較數組的值與$v相等?是== 還是 ===?這裡存在分歧。為了簡單起見,我們假設是==比較。
現在我們加一些限制條件,對於以下一些限制條件,應該如何解決:
a.如果不使用系統函數。如何解決?
b.參數傳遞問題:傳遞引用和傳值對於函數的編寫有何影響?分別實現之。
c.可以使用系統函數的情況下,如何解決。
我們先看條件一:如果不使用系統函數。如何解決?直接遍曆吧,遇到value等於$v的項目,就刪除它(或者遇到不等於value的元素,就記錄下來)。因而有兩種形式:
<?php/* * 方式1,直接傳遞引用,修改原數組 */function array_remove($v,&$array){if(!is_array($array)){throw new Exception("input param is not a legel ,should be array\n");}foreach($array as $key=>$value){if($value == $v){unset($array[$key]);}}}/* * 方式2.傳遞值。返回修改後的新數組。 */function array_remove_return($v,$array){if(!is_array($array)){throw new Exception("input param is not a legel ,should be array\n");}$result = array();foreach($array as $key=>$value){if($value != $v){$result[$key] = $value;}}return $result;}$test = array(1,2,3,4,5);$test2 = array(1,2,3,4,5);array_remove(3,$test);print_r($test);$res = array_remove_return(3,$test2);print_r($res);
對於限制條件b。兩種解法分別見限制條件a的兩種解法。
限制條件c:如果可以用系統函數的話。有哪些解法?
這個解法也有很多。最基本的,我們可以用array_search找出value等於$v的索引,然後刪除相應的元素。代碼如下:
function array_remove_with_inside($v,&$array){if(!is_array($array)){throw new Exception("input param is not a legel ,should be array\n");}$key = array_search($v,$array);if($key !== false){unset($array[$key]);}}
代碼中需要注意的地方是第六行:if($key !== false) 。這裡的比較是 !==而不是 != 。為什麼呢?這是因為:
array_search($v,$array);的結果可能是0(數組的第一個元素)。而在php中0==false但是0!== false.這是一個需要注意的地方。與這個情況類似的是遍曆目錄時候。 while(($file = readdir($handler))!==false)這也是防止出現名字為0的目錄或檔案而產生錯誤。
當然也可以使用array_walk刪除相應的元素。代碼稍後補上。
類似的題目還有:reverse($string)的編寫等,對於庫函數的編寫是一項基本能力,主要的考點是:效率,參數檢測,錯誤處理等大多數需要考慮十分仔細和周全。
2. 以下登陸代碼安全上有什麼問題?
<?php
$m = $_GET['m'];
$user = $_GET['user'];
$pass = $_GET['pass'];
include($m.”do.php”);
$sql = ”select count(*) as b from user where username=’”.$user.”‘and password=’”.$pass.”‘;
$r = mysql_query($sql);
list($count) = @mysql_fetch_array($r);
if($count>1){
……登陸成功操作
}
?>
解析:
仔細觀察代碼。我們發現,代碼中的安全隱患還是很多的。大致有一下幾種。
<1>使用者名稱和密碼都是通過get方式明文傳遞的。這是一個很嚴重的問題。雖然post方式也並不是安全的,但是對於這種表單提交,還是post方式最好。
<2>沒有過濾使用者的輸入。存在者嚴重的sql注入隱患。應該htmlspecialchars ,trim,strip_tags處理使用者輸入。有一個原則叫:永遠不要相信使用者的輸入。這裡就是這個道理。
<3>sql查詢部分。貌似資料庫中儲存的明文?至少應該做md5加密,然後比較md5加密的結果。
<4>include($m.”do.php”); 把使用者的輸入作為參數,而且不做處理的話,這裡很容易出現“檔案不存在”的異常
當然還有不是安全隱患的錯誤地方:if($count>1) 題目錯誤,會有兩個以上同使用者名稱同密碼的使用者嗎?if($count >= 1)(好吧假設有,這裡起碼應該有=1)
3.寫一個函數,算出兩個檔案的相對路徑
例如:
- $a = ‘/a/b/c/d/e.php’;
- $b =’/a/b/12/34/c.php’;
則$a 相對於$b 的相對路徑為 ../../../c/d/e.php 。對於任意兩個給定的目錄(目錄的形式是有效,不必做校正)。求出目錄一相對於目錄二的相對路徑。
函數原型為 getRelativeDir($dir1,$dir2)求出$dir1相對於$dir2的相對路徑。
解析:
最簡單的想法。記錄兩個目錄相同的部分並計數。如果計算出記錄dir2跳出到相同目錄下需要的次數。並添加 “ ../”。最後可以求出目錄一相對於目錄二的相對路徑。
代碼如下:
function getRelativePath($dest_dir,$relative_dir){$path_dest = explode('/',dirname($dest_dir));$path_relative = explode('/',dirname($relative_dir));$aLen = count($path_dest);$bLen = count($path_relative);$minLen = min($aLen,$bLen);$count = 0;for($i = 0; $i < $minLen; $i++){if( $path_dest[$i] == $path_relative[$i] ){$count++;}}$path = '';$res_count = $bLen - $count - 1;for($i = 0;$i < $res_count;$i++){$path.= "../";}for($i = $res_count;$i < $aLen;$i++){$path.= $path_dest[$i]."/";}$path.= basename($dest_dir);return $path;}$a = '/a/b/c/f/d/e.php';$b = '/a/b/f/g/k/h/j.php';echo getRelativePath($a,$b);
3. 寫一個程式,遠程抓取
http://www.google.cn/search?q=php 網頁內容,並匹配出該網址網頁內的所有超連結位址,寫入url.txt。
解析:基本考點:file_get_contents 或者curl擷取網路內容 .Regex匹配。file_put_contents或者檔案操作函數。並無太大痛點。
作為測試,(Google被牆了),抓取baidu的相關搜尋結果。測試代碼如下:
<?php$url = "http://www.baidu.com/s?wd=php";set_time_limit(0);$content = '';try{$result = getContentFromUrl($url);foreach($result as $key=>$value){if($value != "#"){$content.= $value."\n";}}file_put_contents('url.txt',$content);}catch(Exception $e){echo $e->getMessage();}function getContentFromUrl($url){if(!$url){return null;}$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$content = curl_exec($ch);if($content === false){throw new Exception("[ curl ]:".curl_erron().":".curl_error());}curl_close($ch);//$content = file_get_contents($url);$result = array();preg_match_all('/<a(?: +[^>]*)? *href *= *"([^"]*)" *[^>]*?>(?:.*)<\/a>/i',$content,$result);var_dump( $result[1] );return $result[1];}
mysql部分:
1. 如何檢驗sql語句的效率索引使用方式?
解析:explain sql語句。可以從表中看出相應的結果。
更多詳細的介紹可參考這篇文章:http://www.1983blue.com/index.php/posts/mysql-explain-index_1
js部分:
<form action=”?do=login” name=”login” method=”post”><input type=”text” value=”" name=”age”/></form>
如何當age的值填入18的時候,form的action變更為?do=login_bak ?
解析:簡單的事件監聽和js函數。
onchange的時候檢測value值,如果為18.則form.login.action = ?do=login_bak.
伺服器部分:
1. 查看當前伺服器負載命令是?
解析:uptime
,top命令。loadavg。 proc系統。
推薦文章:http://www.flybaaa.com/help/69_1.html。講解很清晰,很清晰。
2. 如何查看當前伺服器1111連接埠的連結總數是?
netstat -nat |grep :1111 |wc -l
3. 如何列出當前進程裡有多少包含apache名字的進程?
ps -ef | grep apache
其他
你現在要做的是一套圖片管理系統。關於使用者圖片的上傳。你是如何盡量避免1,圖片被盜用。2,圖片重複上傳。你的上傳儲存目錄如何設定的?
解析:需要注意的是“防止盜用”與“防止盜鏈”是不同的概念。
為了防止被盜用,你需要做的是類片浮水印之類的東西(例如新浪部落格上上傳的圖片會自動加上你的微博id,就是一種防盜用技術)。
怎樣防止圖片被盜用,可以參考本文章:http://blog.sina.com.cn/s/blog_5e3e2a6a0100e658.html
為了防止被盜鏈,需要做目錄或檔案使用權限設定,或者網域名稱檢測(不是本網站的網域名稱時,或跳出提示,或顯示替代圖片)。apache的目錄設定可以實現這個功能。
具體的細節可看:http://blog.csdn.net/mygood322/article/details/7582531。
上傳目錄設定一般為:一個使用者一個大目錄。目錄下面可以分多個具體的目錄。
為了防止圖片重複上傳,可以:
禁止短時間內多次提交按鈕(js控制,點擊按鈕後幾秒內上傳按鈕失效);
防止重新整理提交按鈕;關於這點,看到一個很簡練的方式:
用 令牌機制先產生個隨機字串,存在session裡.例如:if(!isset($_SESSION['verify'])){ $_SESSION['verify'] = gmmktime();}然後在 html的表單中加個隱藏欄位<input type="hidden" name="verify" value="<?=$_SESSION['verify']?>" />在表單提交的時候,檢查提交上來的verify的值 是否等於 session裡存的if($_POST['verify']!=$_SESSION['verify']){ die('請勿重複提交');}else{ unset($_SESSION['verify']); //做上傳需要做的事情.....}
本次php面試題目基本總結完成。