一、linux的多線程和多進程有什麼區別?何時使用多線程,何時使用多進程?javascript
答:(1)進程資源調度的最小單位,線程是cpu調度的最小單位;多進程開銷大,多線程開銷小,這是最基本的區別;一個進程裏面可能有不少線程,把進程分解爲線程以後就能夠有效利用cpu和內存php
(2)當須要頻繁建立和銷燬時優先選用多線程;css
須要進行大量計算的優先使用線程;html
強相關的處理用線程,弱相關的處理用進程;前端
可能要擴展到多機分佈的用進程,多核分佈的用線程;html5
都知足需求的狀況下用最熟悉最拿手的方式java
二、現有的nosql數據庫都有哪些?node
答:NoSQL,指的是非關係型的數據庫,Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB等等都是非關係型數據庫mysql
三、javascript實現跨域的幾種方法?linux
答:(1)document.domain+iframe的設置
對於主域相同而子域不一樣的例子,能夠經過設置document.domain的辦法來解決。 具體的作法是能夠在http://www.a.com/a.html和http://script.a.com/b.html兩個文件中分別加上 document.domain = ‘a.com’;而後經過a.html文件中建立一個iframe,去控制iframe的contentDocument,這樣兩個js文件之間就能夠 「交互」了。固然這種辦法只能解決主域相同而二級域名不一樣的狀況,若是你異想天開的把script.a.com的domian設爲alibaba.com 那顯然是會報錯地!代碼以下:
www.a.com上的a.html
document.domain = 'a.com'; var ifr = document.createElement('iframe'); ifr.src = 'http://script.a.com/b.html'; ifr.style.display = 'none'; document.body.appendChild(ifr); ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; // 在這裏操縱b.html alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue); };
script.a.com上的b.html
document.domain = 'a.com';
這種方式適用於{www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com}中的任何頁面相互通訊。
備註:某一頁面的domain默認等於window.location.hostname。主域名是不帶www的域名,例如a.com,主域名前面 帶前綴的一般都爲二級域名或多級域名,例如www.a.com實際上是二級域名。 domain只能設置爲主域名,不能夠在b.a.com中將domain設置爲c.a.com。
(2)動態建立script
雖然瀏覽器默認禁止了跨域訪問,但並不由止在頁面中引用其餘域的JS文件,並能夠自由執行引入的JS文件中的function(包括操做cookie、Dom等等)。根據這一點,能夠方便地經過建立script節點的方法來實現徹底跨域的通訊。具體的作法能夠參考YUI的Get Utility
這裏判斷script節點加載完畢仍是蠻有意思的:ie只能經過script的readystatechange屬性,其它瀏覽器是script的load事件。如下是部分判斷script加載完畢的方法。
js.onload = js.onreadystatechange = function() { if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') { // callback在此處執行 js.onload = js.onreadystatechange = null; } };
(3)利用iframe和location.hash
這個辦法比較繞,可是能夠解決徹底跨域狀況下的腳步置換問題。原理是利用location.hash來進行傳值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash,改變hash並不會致使頁面刷新,因此可 以利用hash值來進行數據傳遞,固然數據容量是有限的。假設域名a.com下的文件cs1.html要和cnblogs.com域名下的 cs2.html傳遞信息,cs1.html首先建立自動建立一個隱藏的iframe,iframe的src指向cnblogs.com域名下的 cs2.html頁面,這時的hash值能夠作參數傳遞用。cs2.html響應請求後再將經過修改cs1.html的hash值來傳遞數據(因爲兩個頁面不在同一個域下IE、Chrome不容許修改parent.location.hash的值,因此要藉助於a.com域名下的一個代理iframe;Firefox能夠修改)。同時在cs1.html上加一個定時器,隔一段時間來判斷location.hash的值有沒有變化,一點有變化則獲取獲取hash值。代碼以下:
先是a.com下的文件cs1.html文件:
function startRequest(){ var ifr = document.createElement('iframe'); ifr.style.display = 'none'; ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo'; document.body.appendChild(ifr); } function checkHash() { try { var data = location.hash ? location.hash.substring(1) : ''; if (console.log) { console.log('Now the data is '+data); } } catch(e) {}; } setInterval(checkHash, 2000);
cnblogs.com域名下的cs2.html:
//模擬一個簡單的參數處理操做
switch(location.hash){
case '#paramdo':
callBack();
break;
case '#paramset':
//do something……
break;
}
function callBack(){
try {
parent.location.hash = 'somedata';
} catch (e) {
// ie、chrome的安全機制沒法修改parent.location.hash,
// 因此要利用一箇中間的cnblogs域下的代理iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata'; // 注意該文件在"a.com"域下
document.body.appendChild(ifrproxy);
}
}
a.com下的域名cs3.html
//由於parent.parent和自身屬於同一個域,因此能夠改變其location.hash的值 parent.parent.location.hash = self.location.hash.substring(1);
固然這樣作也存在不少缺點,諸如數據直接暴露在了url中,數據容量和類型都有限等……
(4)window.name實現的跨域數據傳輸
有三個頁面:
a.com/app.html:應用頁面。
a.com/proxy.html:代理文件,通常是一個沒有任何內容的html文件,須要和應用頁面在同一域下。
b.com/data.html:應用頁面須要獲取數據的頁面,可稱爲數據頁面。
實現起來基本步驟以下:
在應用頁面(a.com/app.html)中建立一個iframe,把其src指向數據頁面(b.com/data.html)。
數據頁面會把數據附加到這個iframe的window.name上,data.html代碼以下:
<script type="text/javascript">
window.name = 'I was there!'; // 這裏是要傳輸的數據,大小通常爲2M,IE和firefox下能夠大至32M左右 //格式能夠自定義,如json、字符串
</script>
在應用頁面(a.com/app.html)中監聽iframe的onload事件,在此事件中設置這個iframe的src指向本地域的代理文件(代理文件和應用頁面在同一域下,因此能夠相互通訊)。app.html部分代碼以下:
<script type="text/javascript">
var state = 0,
iframe = document.createElement('iframe'),
loadfn = function() {
if (state === 1) {
var data = iframe.contentWindow.name; // 讀取數據
alert(data); //彈出'I was there!'
} else if (state === 0) {
state = 1;
iframe.contentWindow.location = "http://a.com/proxy.html";// 設置的代理文件
}
};
iframe.src = 'http://b.com/data.html';
if (iframe.attachEvent) {
iframe.attachEvent('onload', loadfn);
} else {
iframe.onload = loadfn;
}
document.body.appendChild(iframe);
</script>
獲取數據之後銷燬這個iframe,釋放內存;這也保證了安全(不被其餘域frame js訪問)。
<script type="text/javascript">
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
</script>
總結起來即:iframe的src屬性由外域轉向本地域,跨域數據即由iframe的window.name從外域傳遞到本地域。這個就巧妙地繞過了瀏覽器的跨域訪問限制,但同時它又是安全操做。
(5)使用HTML5 postMessage
HTML5中最酷的新功能之一就是 跨文檔消息傳輸Cross Document Messaging。 下一代瀏覽器都將支持這個功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。 Facebook已經使用了這個功能,用postMessage支持基於web的實時消息傳遞。
a.com/index.html中的代碼:
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
var ifr = document.getElementById('ifr');
var targetOrigin = 'http://b.com'; // 若寫成'http://b.com/c/proxy.html'效果同樣
// 若寫成'http://c.com'就不會執行postMessage了 ifr.contentWindow.postMessage('I was there!', targetOrigin); }; </script>
b.com/index.html中的代碼:
<script type="text/javascript"> window.addEventListener('message', function(event){ // 經過origin屬性判斷消息來源地址 if (event.origin == 'http://a.com') { alert(event.data); // 彈出"I was there!" alert(event.source); // 對a.com、index.html中window對象的引用 // 但因爲同源策略,這裏event.source不能夠訪問window對象 } }, false); </script>
(6)利用flash
這是從YUI3的IO組件中看到的辦法,具體可見http://developer.yahoo.com/yui/3/io/。
能夠看在Adobe Developer Connection看到更多的跨域代理文件規範:ross-Domain Policy File Specifications、HTTP Headers Blacklist。
四、Jquery最核心的部分是什麼?
答:Jquery選擇器
五、冒泡排序、快速排序、選擇排序、堆排序、插入排序各寫一例?說說冒泡排序和快速排序的核心思想
答:假設如下都是從小到大排序:
一、冒泡排序(穩定排序)
我的理解:冒泡排序就是兩個循環,大循環套小循環,從頭或者尾部開始比較連續的兩個元素的大小,若是不符合本身的排序標準(由小到大,或由大到小),則交換其值。
function bubble_sort($array){
$count=count($array);
for($i=0;$i<$count;$i++){
for($j=$count-1;$j>$i;$j--){
if($array[$j]<$array[$j-1]){//若是後面的值小於前面的元素,則交換值
$temp=$array[$j];
$array[$j]=$array[$j-1];
$array[$j-1]=$temp;
}
}
}
}
二、快速排序(又稱數組排序)(不穩定排序)
我的理解:在要排序的數組中找一個關鍵數據(標準值),一般把數組的第一個元素當成關鍵數據,而後循環數組,從第二個元素開始依次將元素值與關鍵數 據進行比較,若是小於關鍵數據,就把該元素放在關鍵值左邊,若是答應關鍵數據,就把該元素放在關鍵數據右邊,將關鍵值左邊元素存成數組,右邊元素也存成數 組,再分別進行以上排序,獲得的數組與關鍵數據合併數組後就排序成功
function quick_sort($array){
$count=count($array);
if($count<=1) retrun $array; //若是數組只有一個元素或爲空,則直接返回數組,不用排序了
$key=$array[0]; //將數組第一個元素設置爲關鍵數據
$left_arr=array();
$right_ar=array();
for($i=1;$i<$count;$i++){
if($array[$i]<=$key)
$left_arr[]=$array[$i];
else
$right_arr[]=$array[$i];
}
$left_arr=quick_sort($left_arr);
$right_arr=quick_sort($right_arr);
//返回合併後的數組
return array_merge($left_arr,array($key),$right_arr);
}
三、選擇排序(不穩定排序)
我的理解:選擇排序就是在要排序的數組中選出最小值與第一個元素交換值,而後再剩下的元素中選出最小值與第二個元素交換值,如此循環到倒數第二個元素和最後一個元素比較爲止。
function select_sort($array){
$count=count($array);
if($count<=1) return $array;
for($i=0;$i<$count-1;$i++){
$min=$array[$i]; //假設當前元素爲數最小,比較後再調整
for($j=$i+1;$j<$count;$j++){
if($array[$j]<$min){
$min=$array[$j];
$key=$j; //將此時值最小的元素的鍵名記下,
}
}
if($min!=$array[$i]){ //若是min在循環中改變了,就須要交換數據
$temp=$array[$i];
$array[$i]=$array[$key];
$array[$key]=$temp;
}
}
}其餘的排序之後再說吧
略
六、當前的web應用程序的網絡協議都有哪些?
答:HTTP(超文本傳輸協議)、TCP/IP(傳輸控制協議/網絡互聯協議)、SMTP(郵件傳輸協議)、POP3(郵局協議第三版)、FTP(文件傳輸協議)等等
七、談談session和cookie的概念?並說說其各自的實現原理
八、nginx是什麼?與linux的區別?
答:nginx(發音同 engine x)一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器。其特色是佔有內存少,併發能力強,因它的穩定性、豐富的功能集、示例配置文件和低系 統資源的消耗而聞名。linux是一種操做系統,兩個根本不屬同一類
九、jsonp和json有什麼區別
答:JSON(JavaScript Object Notation)是Douglas Crockford提出的。他是一個輕量級的數據交換格式,基於JavaScript對象字面量。
使用JSON的優勢在於:
(1) 比XML輕了不少,沒有那麼多冗餘的東西
(2)JSON也是具備很好的可讀性的,可是一般返回的都是壓縮事後的。不像XML這樣的瀏覽器能夠直接顯示,瀏覽器對於JSON的格式化的顯示就須要藉助一些插件了
(3)在JavaScript中處理JSON很簡單
(4)其餘語言例如PHP對於JSON的支持也不錯
JSON也有一些劣勢:
(1) JSON在服務端語言的支持不像XML那麼普遍,不過JSON.org上提供不少語言的庫
(2) 若是你使用eval()來解析的話,會容易出現安全問題
儘管如此,JSON的優勢仍是很明顯的。他是Ajax數據交互的很理想的數據格式。
JSONP是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問
區別:JSON沒有實現跨域,JSONP能夠實現跨域
十、談談tinyint int smallint mediumint的 字節數 和長度範圍
答:類型 字節 最小值(帶符號/無符號) 最大值(帶符號/無符號)
TINYINT 1 -128 / 0 127 / 255
SMALLINT 2 -32768 / 0 32767 / 65535
MEDIUMINT 3 -8388608 / 0 8388607 / 16777215
int 4 -2147483648 / 0 2147483647 / 4294967295
十一、說說對面向對象的理解?
答:面對對象就是: 把數據及對數據的操做方法放在一塊兒,做爲一個相互依存的總體——對象。對同類對象抽象出其共性,造成類。類中的大多數數據,只能用本類的方法進行處理。類 經過一個簡單的外部接口與外界發生關係,對象與對象之間經過消息進行通訊。程序流程由用戶在使用中決定。
面向對象有三個特徵:繼承、封裝、多態
十二、varchar和char的區別,各能存多少字節?
答:char(n) 定長 索引效率高 程序裏面使用trim去除多餘的空白 ,n 必須是一個介於 1 和 8,000 之間的數值,存儲大小爲 n 個字節
varchar(n) 變長 效率沒char高 靈活 ,n 必須是一個介於 1 和 8,000 之間的數值。存儲大小爲輸入數據的字節的實際長度,而不是 n 個字節
1三、一個漢字在utf-8編碼下佔多少字節?
答:3個字節,用mb_strlen($str,'utf8')函數能夠測試出,一個漢字在gbk編碼下佔兩個字節
1四、說說mysql 水平分區和垂直分區?
答:數據庫分區: 數據庫分區是一種物理數據庫設計技術,DBA和數據庫建模人員對其至關熟悉。雖然分區技術能夠實現不少效果, 但其主要目的是爲了在特定的SQL操做中減小數據讀寫的總量以縮減響應時間。
水平分區,垂直分區
分區主要有兩種形式:這裏必定要注意行和列的概念(row是行,column是列)
水平分區(Horizontal Partitioning)
這種形式分區是對錶的行進行分區,經過這樣的方式不一樣分組裏面的物理列分割的數據集得以組合,從而進行個體分割(單分區)或集體分割(1個或多個分區)。
全部在表中定義的列在每一個數據集中都能找到,因此表的特性依然得以保持。
舉個簡單例子:一個包含十年發票記錄的表能夠被分區爲十個不一樣的分區,每一個分區包含的是其中一年的記錄。
必定要經過某個屬性列來分割,譬如這裏使用的列就是年份
垂直分區(Vertical Partitioning)
這種分區方式通常來講是經過對錶的垂直劃分來減小目標表的寬度,使某些特定的列被劃分到特定的分區,每一個分區都包含了其中的列所對應的行。
舉個簡單例子:一個包含了大text和BLOB列的表,這些text和BLOB列又不常常被訪問,這時候就要把這些不常用的text和BLOB了劃分到另外一個分區,
在保證它們數據相關性的同時還能提升訪問速度。
1五、談談你對memcache的瞭解?
答:memcached 是高效、快速的分佈式內存對象緩存系統 ,經過在內存裏維護一個統一的巨大的Hash表,可以用來存儲各類格式的數據。主要用於加速 WEB 動態應用程序。
工做原理:首先 memcached 是以守護程序方式運行於一個或多個服務器中,隨時接受客戶端的鏈接操做,客戶端能夠由各類語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客戶端在與 memcached 服務創建鏈接以後,接下來的事情就是存取對象了,每一個被存取的對象都有一個惟一的標識符 key,存取操做均經過這個 key 進行,保存到 memcached 中的對象其實是放置內存中的,並非保存在 cache 文件中的,這也是爲何 memcached 可以如此高效快速的緣由。注意,這些對象並非持久的,服務中止以後,裏邊的數據就會丟失。
1六、有一隻猴子,旁邊有100根香蕉,他離家有50米遠,每次只能搬50根香蕉,否則就會被壓死,每走一米就要吃掉一根,問最多能將幾根香蕉搬回家?
答:16根.
問題簡化成走最短的路,背更多的水果.但路和水果之間有限制! 題目已經限制,猴子最多背50,咱們計算其消耗僅剩下50根的米處,
假設猴子第一次背了50根,走了X米,在回來搬第2個50根,就有:
100-3X ......... 剩下的香蕉數(先走X,往反2X)
50-X ............ 剩下的米處
問題就明白了:
(100-3X)-(50-X)=50-2X ........回到家時的香蕉數
問題就簡化爲在條件: (100-3X)<=50的狀況下,求
(50-2X)的最大值!
獲得: X=17時, 50-2X 最大值 16
1七、dir/upload.image.jpg請寫出至少五種以上方法,獲取文件類型,必須使用php內置函數,能夠封裝成方法,方法不能明顯重複。
答:$file = "dir/upload.image.jpg";
第一種:
function getTypeOne($filename){
if(empty($filename)) return false;
$arr = array();
$arr = explode('.',$filename);
return $arr[count($arr)-1];
}
echo getTypeOne($file);
第二種:
function getTypeTwo($filename){
if(empty($filename)) return false;
return str_replace('.','',strrchr($filename,'.'));//strrchr() 函數查找字符串在另外一個字符串中最後一次出現的位置,並返回從該位置到字符串結尾的全部字符。若是成失敗,不然返回 false
}
echo getTypeTwo($file);
第三種:
function getTypeThree($filename){
if(empty($filename)) return false;
//substr()截取字符串函數
//strrchr() 函數查找字符串在另外一個字符串中最後一次出現的位置,並返回從該位置到字符串結尾的全部字符。若是成失敗,不然返回 false
return substr(strrchr($filename,'.'),1);
}
echo getTypeThree($file);
第四種://end — 將數組的內部指針指向最後一個單元
echo end(explode('.',$str));
第五種:
//pathinfo — 返回文件路徑的信息
$file = pathinfo($str);
echo $file['extension'];
1八、使用索引的好處和壞處都有哪些?
答:若是表上沒有索引.在對錶進行相關操做時會對錶執行表面掃描.表越大,掃描時間越長.主要是掃描時須要順序的存取數據的每一行.在作簡單的查詢時索引能夠有效地提升速度.
若是在作巨複雜的查詢時.表基本上會進行表掃描操做.索引的存貯主要是包含一個索引搜索鍵值跟一個指向包含該值行的一個指針還有行值.因此索引內存部分比表空間少.使用操做語句時,索取索引時間比表掃描快.
索引也有壞處(小壞處,忽略不計).對一個表進行的INSERT或者是DELETE時 操做都須要對錶上的每一個索引進行額外的更新,增長了處理時間.單索引跟聯合索引對於update 更改索引操做也是如此
1九、MySQL_connect和MySQL_pconnect有什麼不一樣?
簡單的來講MySQL_pconnect是用來在php與MySQL間創建一條持續鏈接, 通常php的執行模式是腳本開始執行時初始化全部資源, 腳本運行結束後釋放全部資源. 而MySQL_pconnect的方式則不這樣, MySQL_connect每次都是從新經過tcp 或者unix domian socket跟sql服務器創建關係, 每次握手都是要消耗很多服務器資源的.
使用pconnect時, 有請求鏈接MySQL時, php會檢查是否以前有條相同的鏈接(以相同的用戶名密碼鏈接到同一個MySQL服務器)已經創建, 若是有的話就直接使用這條鏈接, 值得注意的是這個相同的鏈接的概念是對進程來講的, 不一樣的進程call MySQL_pconnect創建會創建起多條鏈接.
connect與pconnect不會帶來功能的差別, 只有性能上的差異.
通常php有倆種運行模式, 一是做爲cgi運行, 二是做爲apache的模塊運行. 做爲cgi的時候connect跟pconnect沒什麼不一樣, 由於每次cgi進行運行結束後都會被銷燬清理掉資源.
php做爲apache模塊方式運行時, 可使用到數據庫持續鏈接, 但可能會存在潛在的問題, 這也是哥哥回答的一點.
假設MySQL服務器被配置爲最大支持10個併發. 而apache被配置爲使用100個子進程.
apache由一個父進程來協調將收到的http request分發給哪一個空閒中的子進程處理, 這樣很快處理了10個http請求, 假設10個都分配給了不一樣的子進程, 那末10條跟MySQL間的持久鏈接就創建了, MySQL的能力已經到了極限.
這時又來了一個http請求, apache將它分給其餘的任意不在這10個子進程中的進程, 那末這個進程就沒有辦法創建到MySQL的鏈接了, 由於坑位已經滿了.
使用持久鏈接還會有其餘方面的問題.
若是在你腳本中使用了持久鏈接, 又進行了鎖表操做的話, 若是到腳本結束也沒有去解鎖的話. 那麼下次再運行這個腳本的話, 它爲了得到lock table會在那裏無盡地等待過去的它unlock table, 過去的它已經不能回來了, 這裏成了個死循環. 除非重啓web或者MySQL服務器. 另外一個會形成鎖定的就是事務了.
避免這個東東的辦法能夠用register_shutdown_function來註冊個回調函數, 在這裏面釋放表鎖定, 或回滾事務.
20、構造函數和析構函數各是什麼?他們能夠接受參數嗎?
構造函數:__construct() 能夠接受參數 (是在建立對象實例後自動執行的成員方法)
析構函數:__destruct() 不能帶有任何參數 (用來在對象使用結束後釋放所使用的計算機資源)
2一、php代碼:setcookie('key','value');print($_COOKIE['key']);輸出結果?
答案:不會輸出任何結果,此題考查的是cookie機制的實現原理,這就涉及到cookie數據的移動過程了,Cookie數據按照下面的方式移動:
從 以上資料中能夠看出,當用戶訪問題目中代碼所在的頁面時,客戶端瀏覽器將像web服務器發送請求,根據頁面代碼,web服務器將會創建一個名爲key的 cookie值, 只有當用戶請求的頁面返回到客戶端瀏覽器時纔會將key這個cookie值發送到客戶端的機器,而在本次web請求時並無一塊兒發送key這個 cookie值(由於客戶端機器並不存在key這個cookie的值),因此就輸出不了任何東西,只有當客戶端瀏覽器再次向web服務器發送http請求 (刷新或跳轉到別的頁面)時web服務器才能接收到key,才能輸出key的值
順便來一段session的實現與工做原理,由於你們老是把這兩種方式放在一塊兒討論
session的工做流程:當客戶端訪問服務器時,服務器根據需求設置session,將會話信息保存在服務器上,同時將標示session的session_id傳遞給客戶端瀏覽器,
瀏 覽器將這個session_id保存在內存中(也能夠在php.ini裏設置參數將其保存在用戶的url中),咱們稱之爲無過時時間的cookie。瀏覽 器關閉後,這個cookie就清掉了,它不會存在用戶的cookie臨時文件。之後瀏覽器每次請求都會額外加上這個參數值,再服務器根據這個 session_id,就能取得客戶端的數據狀態。
若是客戶端瀏覽器意外關閉,服務器保存的session數據不是當即釋放,此時數據還會存在,只要咱們知道那個session_id,就能夠繼續經過請求得到此session的信息;可是這個時候後臺的session還存在,可是session的保存有一個過時
時間,一旦超過規定時間沒有客戶端請求時,他就會清除這個session。
session的session存儲機制,默認的session是保存在files中,即以文件的方式保存session數據
session的實例問題
現有系統A,B; 假設A系統是能夠獨立運行的web系統,便可以和瀏覽器直接處理session, B系統是基於mobile的,須要調用A系統的功能接口,
在保持A不改變的狀況下,即登錄驗證,session存儲都不變的狀況下,B系統能處理前端用戶的請求。
這裏提供的方案是使用PHP實現
在用戶登錄成功後,將保存的session的session-id返回給B系統,而後B系統每次請求其餘接口都帶session_id。
A系統在session_start前加上session_id(session_id);
這樣B系統就能安全的調用A
2二、php代碼:
try{
require('d:/www/log.txt');//已知此文件已被刪除
echo 'yes';
}catch{
echo 'catch';
}以上一段代碼的輸出的結果?
答案:沒有任何輸出,由於當require包含的文件不存在時,會致使一個致命錯誤(Fatal error),程序就此終止,不會再往下執行。解釋到這裏確定要說一下include包含的文件不存在時產生一個警告(Warning),該語句後面的程序會繼續執行。
2三、sort(),asort(),ksort()三個函數的區別?
答案:1、一維數組
假設有一個一維數組,以下:
1 |
$sortArr = array("name"=>"hiro", "age"=>"23", "city"=>"Shanghai", "code"=>"200051"); |
print_r()輸出的原始數組結果爲:
1 |
Array ( [name] => hiro [age] => 23 [city] => Shanghai [code] => 200051 ) |
1.sort()函數:根據數組下標進行升序排列;print_r()輸出的數組結果爲(輸出時只有數組下標,而不是鍵名):
1 |
Array ( [0] => 23 [1] => 200051 [2] => Shanghai [3] => hiro ) |
2.rsort()函數:與sort()函數相反,根據數組下標進行降序排列;print_r()輸出的數組結果爲(輸出時只有數組下標,而不是鍵名):
1 |
Array ( [0] => hiro [1] => Shanghai [2] => 200051 [3] => 23 ) |
3.asort()函數:根據數組的鍵名進行升序排列;print_r()輸出的數組結果爲:
1 |
Array ( [age] => 23 [code] => 200051 [city] => Shanghai [name] => hiro ) |
4.arsort()函數:與asort()函數相反,根據數組的鍵名進行降序排列;print_r()輸出的數組結果爲:
1 |
Array ( [name] => hiro [city] => Shanghai [code] => 200051 [age] => 23 ) |
5.ksort()函數:根據數組的鍵值進行升序排列;print_r()輸出的數組結果爲:
1 |
Array ( [age] => 23 [city] => Shanghai [code] => 200051 [name] => hiro ) |
6.krsort()函數:與ksort()函數相反,根據數組的鍵值進行降序排列;print_r()輸出的數組結果爲:
1 |
Array ( [name] => hiro [city] => Shanghai [code] => 200051 [age] => 23 ) |
7.reverse_array()函數:反向當前的數組排列順序;print_r()輸出的數組結果爲:
1 |
Array ( [name] => hiro [age] => 23 [city] => Shanghai [code] => 200051 ) |
8.shuffle()函數:隨機地排列數組順序(每次刷新後排列的順序都不相同);print_r()輸出的數組結果爲(只是其中一種隨機排列):
1 |
Array ( [0] => 23 [1] => 200051 [2] => Shanghai [3] => hiro ) |
假設有一個二維數組,以下:
1 2 3 4 5 |
$person = array( array("hiro", "23", "suzhou"), array("yoyo", "25", "shanghai"), array("janstar", "28", "xinjiang") ); |
print_r()輸出的原始數組結果爲:
1 |
Array ( [0] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [1] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) [2] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) ) |
二維數組的排序是根據每維的鍵名排序的,因此須要額外地編寫比較函數。先舉三個例子:
1.按每維的第一個元素升序排列,代碼以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function compare0($x, $y) { if($x[0] == $t[0]) { return 0; } elseif ($x[0] < $y[0]) { return -1; } else { return 1; } } usort($person, compare0); echo "按第一個元素正向排序:"; print_r($person); |
輸出的結果以下:
1 |
按第一個元素正向排序:Array ( [0] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [1] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) [2] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) ) |
2.按每維的第三個元素升序排列,代碼以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function compare2($x, $y) { if($x[2] == $t[2]) { return 0; } elseif ($x[2] < $y[2]) { return -1; } else { return 1; } } usort($person, compare2); echo "按第三個元素正向排序:"; print_r($person); |
輸出的結果以下:
1 |
按第三個元素正向排序:Array ( [0] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) [1] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [2] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) ) |
3.按每維的第三個元素升序排列,代碼以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function reverse_compare2($x, $y) { if($x[2] == $t[2]) { return 0; } elseif ($x[2] < $y[2]) { return 1; //改變後便可反向 } else { return -1; //改變後便可反向 } } usort($person, reverse_compare2); echo "按第三個元素反向排序:"; print_r($person); |
輸出的結果以下:
1 |
按第三個元素反向排序:Array ( [0] => Array ( [0] => janstar [1] => 28 [2] => xinjiang ) [1] => Array ( [0] => hiro [1] => 23 [2] => suzhou ) [2] => Array ( [0] => yoyo [1] => 25 [2] => shanghai ) ) |
2四、php的垃圾收集機制是怎樣的?
答案:「PHP能夠自動進行內存管理,清除再也不須要的對象。PHP使用了引用計數(reference counting)這種單純的垃圾回收(garbage collection)機制。每一個對象都內含一個引用計數器,每一個reference鏈接到對象,計數器加1。當reference離開生存空間或被設爲 NULL,計數器減1。當某個對象的引用計數器爲零時,PHP知道你將再也不須要使用這個對象,釋放其所佔的內存空間。
每一種計算機語言都有本身的自動垃圾回收機制,讓程序員沒必要過度關心程序內存分配,php也不例外,可是在面向對象編程(OOP)編程中,有些對象須要顯式的銷燬;防止程序執行內存溢出。
1、PHP 垃圾回收機制(Garbage Collector 簡稱GC)
在PHP中,沒有任何變量指向這個對象時,這個對象就成爲垃圾。PHP會將其在內存中銷燬;這是PHP的GC垃圾處理機制,防止內存溢出。
當一個PHP線程結束時,當前佔用的全部內存空間都會被銷燬,當前程序中全部對象同時被銷燬。GC進程通常都跟着每起一個SESSION而開始運行的.gc目的是爲了在session文件過時之後自動銷燬刪除這些文件.
2、__destruct /unset
__destruct() 析構函數,是在垃圾對象被回收時執行。
unset 銷燬的是指向對象的變量,而不是這個對象。
3、 Session 與 GC
因爲PHP的工做機制,它並無一個daemon線程來按期的掃描 Session信息並判斷其是否失效,當 一個有效的請求發生時,PHP 會根據全局變量 session.gc_probability和session.gc_divisor的值,來決定是否啓用一個GC, 在默認狀況下,session.gc_probability=1, session.gc_divisor =100也就是說有1%的可能性啓動GC(也就是說100個請求中只有一個gc會伴隨100箇中的某個請求而啓動).
GC的工做就是掃描全部的Session信息,用當前時間減去session最後修改的時間,同session.gc_maxlifetime參數進行比較,若是生存時間超過gc_maxlifetime(默認24分鐘),就將該session刪除。
可是,若是你Web服務器有多個站點,多個站點時,GC處理session可能會出現意想不到的結果,緣由就是:GC在工做時,並不會區分不一樣站點的session.
那麼這個時候怎麼解決呢?
1. 修改session.save_path,或使用session_save_path()讓每一個站點的session保存到一個專用目錄,
2. 提供GC的啓動率,天然,GC的啓動率提升,系統的性能也會相應減低,不推薦。
3. 在代碼中判斷當前session的生存時間,利用session_destroy()刪除.
2五、傳值和傳引用的區別?
答案:傳值的話,若是是非對象,會傳一個值的拷貝,對這個變量作任何改動都不影響原值。
傳引用或者傳對象,是傳真實的內存地址,對這個變量作的改動會影響原值。
function func1($a) {
$a = $a + 1;
}
function func2(&$a) {
$a = $a + 1;
}
$sample = 1;
func1($sample);
echo $sample; // 輸出 1
$sample = 1;
func2($sample);
echo $sample; // 輸出 2
2六、求2012-11-11 11:11:11和2012-12-5 12:28:59 兩個日期的差數(天數)
方法一:先用strtotime轉換成unix時間戳,而後相減,除以一天的秒數86400.
方法二:先用mktime轉換成unix時間戳,而後相減,除以一天的秒數86400.
具體代碼以下:
方法一:
class Dtime{
function get_days($date1, $date2){
$time1 = strtotime($date1);
$time2 = strtotime($date2);
return abs($time2-$time1)/86400;
}
}
$Dtime = new Dtime;
echo $Dtime->get_days('2007-2-5', '2007-3-6');
方法二:
$temp = explode('-', '2007-2-5');
$time1 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
$temp = explode('-', '2007-3-6');
$time2 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]);
echo ($time2-$time1)/86400;
2七、索引分幾種?主鍵和惟一索引的區別?
索引用來快速地尋找那些具備特定值的記錄,全部MySQL索引都以B-樹的形式保存。若是沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表的全部記錄,直至找到符合要求的記錄。表裏面的記錄數量越多,這個操做的代價就越高。若是做爲搜索條件的列上已經建立了索引,MySQL無需掃描任何記錄便可迅速獲得目標記錄所在的位置。若是表有1000個記錄,經過索引查找記錄至少要比順序掃描記錄快100倍。
索引的類型:MySQL提供多種索引類型供選擇:
(一)普通索引
這是最基本的索引類型,並且它沒有惟一性之類的限制。普通索引能夠經過如下幾種方式建立:
建立索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
建立表的時候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );
(二)惟一性索引
這種索引和前面的「普通索引」基本相同,但有一個區別:索引列的全部值都只能出現一次,即必須惟一。惟一性索引能夠用如下幾種方式建立:
建立索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
建立表的時候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表)
);
(三)主鍵
主鍵是一種惟一性索引,但它必須指定爲「PRIMARY KEY」。若是你曾經用過AUTO_INCREMENT類型的列,你可能已經熟悉主鍵之類的概念了。主鍵通常在建立表的時候指定,例如「CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); 」。但是,咱們也能夠經過修改表的方式加入主鍵,例如「ALTER TABLE tablename ADD PRIMARY KEY (列的列表); 」。每一個表只能有一個主鍵。
(四)全文索引
MySQL從3.23.23版開始支持全文索引和全文檢索。在MySQL中,全文索引的索引類型爲FULLTEXT。全文索引能夠在VARCHAR或者TEXT類型的列上建立。它能夠經過CREATE TABLE命令建立,也能夠經過ALTER TABLE或CREATE INDEX命令建立。對於大規模的數據集,經過ALTER TABLE(或者CREATE INDEX)命令建立全文索引要比把記錄插入帶有全文索引的空表更快。本文下面的討論不再涉及全文索引,要了解更多信息,請參見MySQL documentation。
(四)單列索引與多列索引
索引能夠是單列索引,也能夠是多列索引。下面咱們經過具體的例子來講明這兩種索引的區別。假設有這樣一個people表:
CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50)
NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT
NULL, PRIMARY KEY (peopleid) );
2八、用php正則匹配全部包含index.com域名及全部子域名下的超連接的url
2九、靜態緩存機制是如何實現的,如何判斷靜態頁面是否過時,靜態文件的生成時間怎麼保存?
1、能夠 根據模板生成靜態文件:模版是沒有內容的頁面,能夠是html類型的也能夠是php類型的,簡單的說就是:一、獲取模板的結構代碼內容 (非內容性的,如html標籤等)二、將關鍵字進行內容替換(把關鍵字替換爲從數據庫裏面取出來的數據),三、將替換好的內容寫入一個新的html頁面 (fopen、fget、fwrite、fclose)
2、實現即時更新:一、採用計劃任務定時更新過時靜態文件;二、在數據進行增長、修改和刪除操做時從新生成靜態頁面
靜態文件的生成時間無需刻意保存,可根據相應php函數獲取:
filemtime
( string filename )
文件上次被修改的時間,出錯時返回 FALSE。時間以 Unix 時間戳的方式返回,可用於 返回
date
()。
例如:
$a
=
filemtime
(
"log.txt"
);
echo
"修改時間:"
.
date
(
"Y-m-d H:i:s"
,
$a
);
filectime
( string filename )
返回文件建立的時間,若是出錯則返回 FALSE。時間以 Unix 時間戳的方式返回。
例如:
$a
=
filectime
(
"log.txt"
);
echo
"建立時間:"
.
date
(
"Y-m-d H:i:s"
,
$a
);
fileatime
( string filename )
返回文件上次被訪問的時間,若是出錯則返回 FALSE。時間以 Unix 時間戳的方式返回。
例如:
$a
=
fileatime
(
"log.txt"
);
echo
"修改時間:"
.
date
(
"Y-m-d H:i:s"
,
$a
);
30、已知一個用戶評論表comment,包含字段 id,userid,content,instime,四個字段,寫出查詢全部用戶的最後評論時間和用戶id的sql語句
SELECT id,userid,instime FROM `comment` c WHERE c.instime=(SELECT MAX(instime) FROM `comment` WHERE userid = c.userid ) ORDER BY id;