1. 程式人生 > >phper必知必會(二)

phper必知必會(二)

1.說說你對程序,執行緒以及協程的理解

程序:是系統進行資源分配和排程的基本單位,是基本作業系統結構的基礎。程序是程式基本執行的實體。程序與程序之間是獨立的,擁有完全獨立的地址空間,程序的切換隻發生在核心態,由作業系統排程。

執行緒:執行緒是作業系統進行運算排程的最小單位。它被包含在程序之中,是程序中實際運作的執行單位。一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。

協程:是一種使用者態的輕量級執行緒,協程的排程完全由使用者控制。攜程擁有自己的暫存器上下文和棧。協程排程切換時,將暫存器上下文和棧儲存在其它地方,在切回來的時候,恢復之前儲存的暫存器上下文和棧,直接操作棧則基本沒有核心切換的開銷,可以不加鎖的訪問全域性變數,所以上下文切換的非常快,執行協程只需要極少的棧記憶體。

 

2.請比較下memcached,redis,並說明下redis的常見應用場景

1.redis支援的資料型別比較多不僅支援常見k/v型別還支援list,set,hash等型別,它比memcached更像資料庫

2.memcached只是簡單的key/value的快取,被用來做常規的快取處理

3.memcached不支援持久化儲存,它把全部資料儲存在記憶體中,斷電或重啟時資料會掉

4.redis支援資料持久化,所以斷電或者重啟後之前落地的資料還可以找到

5.redis支援資料的備份,即master-slave模式的資料備份,memcached可以使用一致性hash做分散式

6.redis使用的是單執行緒模型,保證了資料按順序提交,memcached使用的是cas保證資料一致性。cas(check and set)是一個確保併發一致性的機制,屬於“樂觀鎖”範疇;原理就是拿版本號,操作對比版本號,如果一致就操作不一致就放棄。

redis常見應用場景:

排行榜:如果使用傳統的關係型資料庫來做這個事兒,還是有點麻煩的,如果使用redis的sortSet資料結構能夠非常方便搞定。

計數器/限速器:redis中原子性的強悍的自增操作,可以用來統計點贊數,文章的閱讀數,以及電商活動中的秒殺搶購中房子使用者瘋狂點選所帶來的不必要的壓力

好友關係:使用集合的求交集,並集,差集可以方便處理共同好友,相同愛好等一些功能

簡單的訊息佇列:如果使用mysql來做無疑會對db產生一些壓力,如果針對不是特別大佇列任務處理的話,可以使用redis的訊息佇列功能,將一些需求和任務寫到redis佇列,非同步處理

session共享:這個其實是針對分散式部署來說的,session一般是儲存在伺服器中的,如果流量請求分攤到多臺伺服器後,這樣使用者的會話就會產生問題,這個時候可以通過php的配置來將session統一儲存在redis中來報錯session的統一性。

 

3.mysql中的myisam和innodb資料庫儲存引擎的區別

1、儲存結構

myisam:儲存資料落在三個檔案。.FRM檔案儲存表定義,.MYD資料檔案,.MYI索引檔案。

innodb:儲存在兩個檔案,.frm儲存表定義,.ibd其它資料

2、儲存空間

myisam:可被壓縮,儲存空間較小

innod:需要更多的記憶體和儲存空間

3、可移植性、備份及恢復

myisam:資料是以檔案形式儲存,可移植性強,直接拷貝檔案即可。

innodb:使用binlog,mysqldump備份,資料過大就比較費時比較痛苦

4、事務支援

myisam:強調效能查詢速度快,不支援事務

innodb:支援事務,外來鍵等功能

5、AUTO_INCRMENT

myisam:可以和其它欄位建立聯合索引

innodb:具有自動增長的欄位索引必須是獨立的,如果和其它欄位組合必須排在第一列

6、鎖

myisam:只支援表級鎖

innodb:支援事務和行級鎖。但是innodb的行鎖,只是在where的主鍵是有效的,非主鍵where會鎖全表

7、全文索引

myisam:支援FULLTEXT型別的全文索引

innodb:不支援FULLTEXT全文索引,不過可以使用其它第三方的引擎支援比如sphinx

8、表主鍵

myisam:允許沒有任何索引和主鍵的存在,索引都是保持行的地址

innod:如果沒有設定主鍵,會自動建立一個使用者不可見6直接的主鍵,資料是主索引的一部分,附加索引儲存的是主索引的值

9、表的具體行數

myisam:儲存有表的總行數,如果select count,會直接取出快速

innodb:沒有直接保持總行數,查詢所有需要遍歷整個表,若增加where條件後跟myisam處理方式一樣

10、CURD操作

myisam:大量查詢適合使用該引擎

innod:大量的insert,update適合使用該引擎。

11、外來鍵

myisam:不支援外來鍵

innodb:支援外來鍵功能

 

4.闡釋資料庫事務的ACID的四個特性

原子性(Atomicity):一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要麼全部提交完成,要麼全部失敗回滾,對於一個事務來說,不可能只執行其中的一部分操作。

一致性(Consistency):資料庫總是從一個一致性的狀態轉換到另一個一致性的狀態。

隔離性(Isolation):一個事務所做的修改在最終提交之前,對其它事務是不可見的。

永續性(Durability):一旦事務提交,則其修改會永遠的儲存在資料庫中。

 

5.闡述mysql的4種隔離級別

讀未提交(read-uncommitted):事務可以讀取未提交的資料,這也被稱為髒讀

讀提交(read-committed):一個事務從開始直到事務提交之前,所做的任何修改對其他事務都是不可見的。

可重讀(repeatable-read)mysql預設事務級別:當某個事務在讀取某個範圍內的記錄時,另外一個事務又在該範圍內插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會產生幻讀

可序列化(serializable)最高事務級別:避免了前面說的幻讀,即在讀取沒一行資料上都加鎖,所以可能導致大量的超時和鎖爭用的問題。

 

6.select count(*),select count(1),select(column)的區別

1.一般情況下select count(*)與select count(1)結果和速度是一樣的,即查詢所有

2.count(column)對特定的值具有行數進行計算,不包含空值,所以結果可能會有些不一樣(可能會比count(*)統計的要少)

3.count(*)對行的數目進行計算,包括null

4.如果沒有主鍵,那麼count(1)要比count(*)快

5.如果表中只有一個欄位,count(*)最快

6.一般來說大多情況下count(*)是最優的選擇

 

7.如果理解oop?

oop即面向物件程式設計,在面向物件程式設計中最重要的兩個概念就是類和物件。

時間萬物都有其屬性和特點或者說特性,我們將這些屬性特性進行整合起來形成一個類,比如具有貓科類的特點和屬性的我們稱為貓科類。這個時候貓科類只是具有這類的屬性的抽象模型,如果要具體要是那種貓或者說需要得到一個具體的實體這個時候就需要對類進行例項化,類在例項化後就是物件了,此時的貓就是一個更加具體存在的物件。

在程式設計世界裡,就是通過這種思想將具有相同的屬性的和特性進行就行管理,組合生一個類,類中有對應的屬性和實現的方法,通過一些初始化和例項化,或者呼叫一些方法來達到我們需要的功能。

面向物件中有三大特點:

1.封裝性

也成為隱藏性,就是將使用和具體實現分開,只對外開放部分介面和方法與外部聯絡,或者說只公開一部分供開發人員使用的方法和引數。

2.繼承性

子類自動繼承父類的屬性和方法,並可以通過新增新的屬性和方法來對部分屬性和方法進行重寫,這樣增加了程式碼的重用性。

3.多型性

雖然說父類只有一個,但是可以有多個子類,這些子類中雖然呼叫的相同的屬性或者方法,但是由於繼承性這個的存在和重寫,例項化後這些子類卻可以或者完全不同的結果,得到不同形態的東西,這種技術就是多型性。

 

8.請闡述http與https的區別

1.https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用

2.http是超文字傳輸協議,資訊是明文傳遞,https則是更具有安全性的ssl加密傳輸協議

3.http和https使用的是完全不同的連線方式,用的埠也不一樣,前者是80後者是443

4.http的連線很簡單,是無狀態的,https協議是由http+ssl協議構建的可進行加密傳輸,身份認證的網路協議,比http協議安全

 

9.使用php的三種方式獲指定取路徑下的資料夾和檔案

 方法一:通過opendir獲取資源控制代碼,再使用readdir函式並遍歷獲取

$dir = "/data/wwwroot/test";
function oneReadDirs($dir){
    $handle = opendir($dir);
    $outStr = '';
    while(($item = readdir($handle))!==false){
        if($item!='.' && $item!='..' ){
            $path = $dir.'/'.$item;
            if(is_file($path)){
                $outStr .= '[檔案] '.$item.PHP_EOL;
            }elseif(is_dir($path)){
                $outStr .= '[目錄] '.$item.PHP_EOL;
            }
        }
    }
    return $outStr;
}

$dirs = oneReadDirs($dir);
echo $dirs;

 

方法二:使用scandir一次性獲取路徑下的所有資料夾和檔案再進行處理

function twoReadDirs($dir){
    $dirs = scandir($dir);
    $outStr = '';
    foreach($dirs as $k=>$v){
        $path = $dir.'/'.$v;
        if($v!=='.' && $v!=='..' ){
            if(is_file($path)){
                $outStr .= '[檔案] '.$v.PHP_EOL;
            }elseif(is_dir($path)){
                $outStr .= '[目錄] '.$v.PHP_EOL;
            }
        }
    }
    return $outStr;
}

$dirs2 = twoReadDirs($dir);
echo $dirs2;

 

方法三:使用面向物件的dir處理方式獲取

function threeReadDirs($dir){
   $d = dir($dir);
   $outStr = '';
   while(($item = $d->read())!==false){
        if($item!='.' && $item!='..' ){
            $path = $dir.'/'.$item;
            if(is_file($path)){
                $outStr .= '[檔案] '.$item.PHP_EOL;
            }elseif(is_dir($path)){
                $outStr .= '[目錄] '.$item.PHP_EOL;
            }
        }
   }
   $d->close();
   return $outStr;
}

$dirs3 = threeReadDirs($dir);
echo ($dirs3);

 

輸出結果為:

[目錄] app
[檔案] index.html
[目錄] cache
[檔案] .htaccess
[目錄] .phalcon
[目錄] public

 

10.寫一個函式算出兩個檔案的相對路徑

 

$path1 = '/a/b/c/d/e/f/g/h/e.php';
$path2 = '/a/b/1/2/c.php';
function getRelativePath($path1, $path2){  
    $arr1=explode('/',dirname($path1)); 
    $arr2=explode('/',dirname($path2)); 
    for($i=0, $len=count($arr2); $i<$len; $i++ ){
        if($arr1[$i]!=$arr2[$i]){
            break ; 
        } 
    } 
    if($i<$len){
        $return_path=array_fill(0,$len-$i,'..');
    }
    //$path1相對於$path2
    $return_path=array_merge($return_path,array_slice($arr1,$i));
    return implode('/',$return_path);
}
echo getRelativePath($path1,$path2);
//../../c/d/e/f/g/h