2020年PHP面試題

1.請問一下你使用過swoole嗎,使用過,怎么設置心跳?
$this->serv->set([
            'heartbeat_check_interval' => 5,
            'heartbeat_idle_time' => 10
        ]);
//上面的設置就是每5秒偵測一次心跳,一個TCP連接如果在10秒內(nèi)未向服務器端發(fā)送數(shù)據(jù),將會被切斷。
2.如果一個訪問量達到100萬,選擇緩存,你會選擇redis還memchache?

我會選擇memchache,因為它只有一種類型,key-value,而redis的類型比memchache多,導致它的并發(fā)沒有memchache好。

3.psr2和psr4的區(qū)別?

意思:psr指的是php standards recommendatiion,意思PHP標準建議。

psr2:編碼風格向?qū)?/p>

<?phpnamespace Vendor\Package;
use FooClass;use BarClass as Bar;use OtherVendor\OtherPackage\BazClass;// ... additional PHP code ...

psr4:自動加載。

psr4:#完整的類名為\a\b\c\Log#命名空間前綴前綴為:a\b#前綴對應的基礎目錄為:./vendor#文件實際目錄為:./vendor/c/Log.php#注:即把去掉最前面的命名空間分隔符后的a\b\c\Log中的命名空間前綴替換成基礎目錄,然后把命名空間分隔符替換成目錄分隔符,并把文件名補上后綴 .php 。
4.mb_strlen和str_len的區(qū)別?
<?php
$a = '中國';
echo strlen($a)."\n";//6
echo mb_strlen($a);//2
5.下面會輸出什么?
<?php
$str = 'abc';
$res = strpos($str,'a');
    if ($res){
        echo '找到了';
    }
     else {
    echo '未找到';
}
//答案是:未找到未找到,因為strpos是查找首字母出現(xiàn)的位置,并且索引是從0開始的,并且PHPs是弱類型的,所以會輸出:未找到
6.使用二分法查找50出現(xiàn)的位置?
//第一種方法
$arr = [1,3,5,12,34,45,50];
function binary(array  &$arr,int $low,int $top,int $target){
    while($low<=$top){
        $mid = floor(($low+$top)/2);
        if($arr[$mid] === $target){
            return $mid;
        } elseif($arr[$mid]>$target){
            $top= $mid-1;
        } else if($arr[$mid]<$target){
            $low= $mid+1;
        }
    }
    return -1;
}
$arr = [1,3,5,12,34,45,50];
echo  binary($arr,0,count($arr),50);//6
//第二種方法
function binaryRecursive(array  &$arr,int $low,int $top,int $target){
        $mid = floor(($low+$top)/2);
        if ($arr[$mid]>$target){
            return binaryRecursive($arr,$low,$mid-1,$target);
        } elseif ($arr[$mid]<$target){
            return binaryRecursive($arr,$mid+1,$top,$target);
        } else if ($arr[$mid]===$target){
            return $mid;
        } else {
            return -1;
        }
}
$arr = [1,3,5,12,34,45,50];
echo  binaryRecursive($arr,0,count($arr),50);//6

7.將上面的數(shù)組進行翻轉(zhuǎn),不使用內(nèi)置函數(shù)?

$arr = [1,3,5,12,34,45,50];

function overturn(array &$arr){
    $temp = [];
    for ($i = count($arr)-1;$i>=0;$i--){

        $temp[] = $arr[$i];
    }
//    print_r($temp);
    return $temp;
}
$arr = [1,3,5,12,34,45,50];
//Array
(
    [0] => 50
    [1] => 45
    [2] => 34
    [3] => 12
    [4] => 5
    [5] => 3
    [6] => 1
)

8.請寫出nginx負載均衡的算法?怎么檢查配置用沒有問題,如果有問題,怎么查看出現(xiàn)是問題,修改了配置文件,怎么生效?

1.round robin(默認)

? 解釋:輪詢方式,依次將請求分配到各個后臺服務器中,默認的負載均衡方式,是否機器性能一致的情況下。

2.weight(權重)`

upstream bakend {    
    server 192.168.0.14 weight=10;    
    server 192.168.0.15 weight=10;    
}  

? 解釋:根據(jù)權重來分發(fā)請求到不同的機器中,指定輪詢幾率,weight和訪問比率成正比,用于后端服務器性能不均的情況。

3.IP_hash

解釋:根據(jù)請求者ip的hash值將請求發(fā)送到后臺服務器中,可以保證來自同一ip的請求被打到固定的機器上,可以解決session問題。

upstream bakend {    
    ip_hash;    
    server 192.168.0.14:88;    
    server 192.168.0.15:80;    
}   

4.url_hash

解釋:根據(jù)請求的url的hash值將請求分到不同的機器中,當后臺服務器為緩存的時候效率高。

upstream backend {    
    server squid1:3128;    
    server squid2:3128;    
    hash $request_uri;    
    hash_method crc32;    
}  

5.fair(第三方)

解釋:根據(jù)后臺響應時間來分發(fā)請求,響應時間短的分發(fā)的請求多。

upstream backend {    
    server server1;    
    server server2;    
    fair;    
}  
tips:
upstream bakend{#定義負載均衡設備的Ip及設備狀態(tài)  
    ip_hash;  
    server 127.0.0.1:9090 down;  
    server 127.0.0.1:8080 weight=2;  
    server 127.0.0.1:6060;  
    server 127.0.0.1:7070 backup;  
} 
//每個設備的狀態(tài)設置為: 
1.down 表示單前的server暫時不參與負載  
2.weight 默認為1.weight越大,負載的權重就越大。  
3.max_fails :允許請求失敗的次數(shù)默認為1.當超過最大次數(shù)時,返回proxy_next_upstream 模塊定義的錯誤  
4.fail_timeout:max_fails次失敗后,暫停的時間。  
5.backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。  
nginx支持同時設置多組的負載均衡,用來給不用的server來使用。  
client_body_in_file_only 設置為On 可以講client post過來的數(shù)據(jù)記錄到文件中用來做debug  
client_body_temp_path 設置記錄文件的目錄 可以設置最多3層目錄  
location 對URL進行匹配.可以進行重定向或者進行新的代理 負載均衡
9.優(yōu)化下面的代碼?
$arr = [1,2,3,...n+1];
$userName = [];
foreach ($arr as $v){
    $userName = $this->getUserNameFromyDb($v);
}
//優(yōu)化代碼如下:
$arr = [1,2,3,...n+1];
$userName = [];
$userName = this->getUserNameFromyDb(implode(',',$arr))
10.請實現(xiàn)一個單列模式。
<?php

class Singleton
{
    //1.創(chuàng)建私有變量保存該對象
    private static $interface;

    //2.禁止使用new
    public function __construct()
    {
    }

    //3.禁止克隆
    public function __clone()
    {
        // TODO: Implement __clone() method.
    }

    //4.判斷對象是否存在
    public static function getInstance()
    {
        if (!self::$interface instanceof self) {
            self::$interface = new self();
        }
        return self::$interface;
    }
    public function test(){
        echo '測試單列模式';
    }

}
$singleton = Singleton::getInstance();
$singleton->test();
//實現(xiàn)單列模式的意義,減少資源的占用
11.docker內(nèi)部配置php+mysql+nginx怎么在內(nèi)部進行連接。

? 沒有配置過

12.請簡述一下觀察者模式?

簡單的一句話就是,多個不同類去執(zhí)行方法名相同的代碼。

實現(xiàn):1.定義一個觀察接口,第二實現(xiàn)該接口里的方法。

生活中的例子:

小明觀察者),狗(被觀察者),貓(被觀察者),牛(被觀察者)

當小明看見狗,就知道它喜歡吃骨頭。

當小明看見貓,就知道它喜歡吃魚。

當小明看見牛,就知道它喜歡吃青草。

代碼如下

?php
//觀察者接口
interface ObjectTest {
    public function register(ObServerTest $obServerTest);//注冊觀察者對象
    public function detach(ObServerTest $obServerTest);//刪除觀察者對象
    public function notify();//通知所有的被觀察者
}
//被觀察者接口
interface ObServerTest{
    public function eat();
}
class Action implements ObjectTest{
    private $_obServersTest = [];

    public function register(ObServerTest $obServerTest)//注冊對象
    {
        $this->_obServersTest[] = $obServerTest;
    }

    public function detach(ObServerTest $obServerTest)
    {
       $index = array_search($obServerTest,$this->_obServersTest);
       if(false === $index || !array_key_exists($index,$this->_obServersTest)){
           throw new \Exception('該對象不存在');
       }
       unset($this->_obServersTest[$index]);
    }

    public function notify()//通知所有的對象
    {
        foreach ($this->_obServersTest as $k=>$v){
                $v->eat();
        }
    }
}
class Dog implements ObServerTest{

    public function eat()
    {
        echo '狗吃骨頭'."\n";
    }
}
class Cat implements ObServerTest{

    public function eat()
    {
        echo '貓吃魚'."\n";
    }
}
class Pink implements ObServerTest{

    public function eat()
    {
        echo '豬吃了睡,睡了吃'."\n";
    }
}
$action = new Action();
$action->register(new Dog());
$action->register(new Cat());
$action->register(new Pink());
$action->notify();
//結(jié)果:
狗吃骨頭
貓吃魚
豬吃了睡,睡了吃
13.請寫出怎么獲取請求頭的信息?
Apache:
    getallheaders();
nginx:
    function nginxGetAllHeaders(){//獲取請求頭
        $headers = [];
        foreach ($_SERVER as $name => $value){
            if (substr($name, 0, 5) == 'HTTP_'){
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
14.高訪問量的網(wǎng)站怎么優(yōu)化?

1.軟件

? 1)將不經(jīng)常變化的數(shù)據(jù),直接靜態(tài)化。

? 2)使用redis和memcha,減少數(shù)據(jù)庫的訪問。

? 3)控制大文件的下載。

? 4)圖片、視頻服務器分離。

? 5)禁止外部的盜鏈。(可以通過refer去實現(xiàn))

? 6)統(tǒng)計流量的使用情況。

2.硬件

? 1)不考慮成本,服務器可以考慮負載均衡,mysql主從復制、讀寫分離。

15.請說一下websoket原理?

? 參照:https://www.cnblogs.com/nnngu/p/9347635.html

16.redis默認有多少個庫?

? 16個庫

17.linux進程之間怎么通信?

? 1.管道

 ls -al /etc | less

? 2.信號量(沒有使用過)

? 3.消息隊列(沒有使用過)

? 4.信號(沒有使用過)

? 5.共享內(nèi)容(沒有使用過)

? 6.套接字(unix socket)

18.如果用戶git,請問一下git怎么合并分支?

? git checkout master

? git merche 分支名

19.laravel外面引入路由.

? 1.在route文件夾中添php文件,并且設置路由。

? 2.在app/Providers/RouteServiceProvider中對應的文件路徑。

? 3.然后laravel啟動就會加載該文件。

20.請求用沒有使用過隊列?
#redis的隊列
//server.php
<?php
$redis = new Redis();

$redis->connect('127.0.0.1',6379);

$password = '123456';

$redis->auth($password);

$arr = array('list1','list2');

foreach($arr as $k=>$v){

    $redis->rpush("mylist",$v);

}
//client.php
<?php
$redis = new Redis();

$redis->connect('127.0.0.1',6379);

$password = '123456';

$redis->auth($password);

//list類型出隊操作

$value = $redis->lpop('mylist');

if($value){

    if($value === 'list1'){
        echo '執(zhí)行l(wèi)ist1的代碼';
    }
    if($value === 'list2'){
        echo '執(zhí)行l(wèi)ist2的代碼';
    }
}else{

    echo "出隊完成";

}
//執(zhí)行兩次
#第一次
執(zhí)行l(wèi)ist1的代碼
#第二次
執(zhí)行l(wèi)ist2的代碼    
//rabbitmq
 #等不忙的時候再寫   
   

21.怎么防止商品不會超賣?

? 采用redis的隊列,去實現(xiàn)。

22.單引號和雙引號的區(qū)別?

? 1.單引號比雙引號執(zhí)行速度快。

? 2.雙引號會解析變量、換行,而單引號不會。

23.微信支付、支付寶回調(diào),如果在回調(diào)區(qū)間服務器崩潰了,有沒有解決辦法?

? 1.確定那些單是沒有收到回調(diào)。

? 2.通過訂單號,去查詢支付寶和微信的訂單狀態(tài),確定是否支付成功。

24.在瀏覽器輸入網(wǎng)址,點回車,經(jīng)歷了什么,才能將數(shù)據(jù)顯示在瀏覽器上?
微信圖片_20200415190139.png
25.請說一下php常見的字符串處理函數(shù)和數(shù)組?

字符串函數(shù)

mb_substr()//截取字符串(中文的)
substr()//·········(英文)
ucfirst()//將字符串首字母變?yōu)榇髮?str_replace()//替換字符串
 #這里參數(shù)就不做詳細的說明(自行去百度哈)   
    

數(shù)組:

array_chunk(array $array , int $size [, bool $preserve_keys = false ])//將一個數(shù)組分割成多個
/*
 array
操作的數(shù)組
size
每個數(shù)組的單元數(shù)目
preserve_keys
設為 TRUE,可以使 PHP 保留輸入數(shù)組中原來的鍵名。如果你指定了 FALSE,那每個結(jié)果數(shù)組將用從零開始的新數(shù)字索引。默認值是 FALSE
*/   
//代碼如下
<?php
$arr = [1,3,45,50];
print_r(array_chunk($arr,1));
/**
Array
(
    [0] => Array
        (
            [0] => 1
        )

    [1] => Array
        (
            [0] => 3
        )

    [2] => Array
        (
            [0] => 45
        )

    [3] => Array
        (
            [0] => 50
        )

)

*/
array_diff_key ( array $array1 , array $array2 [, array $... ] ) : array#使用鍵名比較計算數(shù)組的差集
/**
array1
從這個數(shù)組進行比較

array2
針對此數(shù)組進行比較

...
更多比較數(shù)組
*/
 //代碼如下:
  <?php

$array1 = ['blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4];
$array2 = ['green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8];

print_r(array_diff_key($array1, $array2)); 
/**
Array
(
    [red] => 2
    [purple] => 4
)
    
*/
array_diff ( array $array1 , array $array2 [, array $... ] ) : array# 計算數(shù)組的差集
/**
rray1
要被對比的數(shù)組

array2
和這個數(shù)組進行比較

...
更多相比較的數(shù)組
*/
<?php
$array1 = array("a" => "green", "red", "blue", "red");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);

print_r($result);
/**
Array
(
    [1] => blue
)

*/
array_walk ( array &$array , callable $callback [, mixed $userdata = NULL ] ) : bool#使用用戶自定義函數(shù)對數(shù)組中的每個元素做回調(diào)處理
/**
array
輸入的數(shù)組。

callback
典型情況下 callback 接受兩個參數(shù)。array 參數(shù)的值作為第一個,鍵名作為第二個。
userdata
如果提供了可選參數(shù) userdata,將被作為第三個參數(shù)傳遞給 callback funcname。
*/
 //代碼如下:
 <?php
$fruits = array('a' => 'lemon', 'b' => 'orange');
function testPrint(string $k,string $v){
    echo $k.$v."\n";
}
print_r(array_walk($fruits,'testPrint'));  
/**
lemona
orangeb
1
*/
//1是返回值哦
compact ( mixed $varname1 [, mixed $... ] ) : array# 建立一個數(shù)組,包括變量名和它們的值
 /*
    對每個參數(shù),compact() 在當前的符號表中查找該變量名并將它添加到輸出的數(shù)組中,變量名成為鍵名而變量的內(nèi)容成為該鍵的值
 **/
 //代碼如下:
<?php
$city  = "San Francisco";
$state = "CA";
$event = "SIGGRAPH";
$location_vars = array("city", "state");
$res = compact('event','xxx',$location_vars);
print_r($res);  
/**
Array
(
    [event] => SIGGRAPH
    [city] => San Francisco
    [state] => CA
)

*/
array_key_exists ( mixed $key , array $array ) : bool#檢查數(shù)組里是否有指定的鍵名或索引
 //代碼如下
    $searchArray = array('TEST1' => 1);
var_dump(array_key_exists('test1', $searchArray));
/**
bool(false)

*/
//區(qū)分大小寫
//更多數(shù)組函數(shù):https://www.php.net/manual/zh/function.array-change-key-case.php
26.為什么要減少數(shù)據(jù)庫的訪問次數(shù)?

因為方法數(shù)據(jù)庫,會有大量io、事務、網(wǎng)絡傳輸操作,所有要減少數(shù)據(jù)庫的訪問次數(shù)。

27.require和include的區(qū)別?

include在引入不存文件時產(chǎn)生一個警告且腳本還會繼續(xù)執(zhí)行,
require則會導致一個致命性錯誤且腳本停止執(zhí)行。

28.php7和php5的區(qū)別?

php7新特性:

? 1.支持標量和返回類型。

class Test
{
    private $age;

    /**
     * @return mixed
     */
    public function getAge()
    {
        return $this->age;
    }

    /**
     * @param mixed $age
     */
    public function setAge(int $age): void
    {
        $this->age = $age;
    }

}
$test = new Test();
$test->setAge('1233ddsaf');
echo $test->getAge();//1233,內(nèi)部進行了轉(zhuǎn)換

? 3.太空船運算符號。

$var = $i??1;//判斷變量是否存在,存在將該值給$var,不存在,將1給$var
echo $var;
//1

? 4.可以使用一個 use 從同一個 namespace 中導入類、函數(shù)和常量.

? 5.可以通過 define() 來定義數(shù)組。

define('test',['12',23]);
echo test[1];
//23

? 6.可用使用new class來實現(xiàn)一個匿名類。

<?php
interface Logger{
    public function log(string  $log);
}
class App {
    private $logger;

    /**
     * @return mixed
     */
    public function getLogger()
    {
        return $this->logger;
    }

    /**
     * @param mixed $logger
     */
    public function setLogger($logger): void
    {
        $this->logger = $logger;
    }

}
$app = new App();
$app->setLogger(new class implements Logger{

    public function log(string $log)
    {
       echo $log;
    }
});
$app->getLogger()->log('這是一條日志');
//這是一條日志
29.數(shù)據(jù)庫優(yōu)化策略?

1.合理的表設計。

? 1).依據(jù)三范式,設計表.

? 三范式:1.原子性,每個字段都是不可在分的。

? 2.在1方式的基礎上,表中每一列必須有唯一性,其他字段依賴主鍵。

? 3.在2方式的基礎上,表中的每一列只與主鍵直接相關,而不是間接相關。

? 2).選擇合適的字段。

? I.盡量使用TYPEINT、SMALLINT、MEDIUM_INT代替INT的使用,一般索引,并且是字段遞增,可以考慮設置為UNSIGNED.

? II.使用枚舉代替字符串類型。

? III.將少null的使用,null很難優(yōu)化,并且還占用額外的空間。

? iv.varchar長度分配給真正需要的空間。

? v.建立合適的索引。

3)選擇合適的引擎。

2.sql優(yōu)化

? 1).減少*的使用,只查詢需要的字段。

? 2).使用關聯(lián)查詢,代替子查詢。

? 3).like使用后匹配。

? 4).合理使用索引。

? 5)減少對null字段的判斷、否則引擎放棄索引,對全表進行掃描。

? 6)減少!=,<>的使用。

? 7)減少where 條件中使用or來連接條件

select id from t where num=10 or Name = ‘a(chǎn)dmin’
#可以這樣查詢:
select id from t where num = 10
union
select id from t where Name = ‘a(chǎn)dmin’

3.減少數(shù)據(jù)庫訪問的次數(shù)。

? 1).將不經(jīng)常變化的數(shù)據(jù),進行緩存(分類、權限等),可以使用redis和mememcha,我個人建議,不要使用文件緩存,它也是對iO進行操作。

4.硬件方面。

? 1).可以考慮分庫、分表。

? 2)可以采用主從復制,讀寫分離.(mysql服務器根據(jù)sql,去判斷是讀還是寫)。

30.laravel保存session。
$request->session()->put('admin',$res);
$request->session()->save();//要加這一句,如果不加,不會保存session
//如果要保存session,都要調(diào)用save方法
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 包含的重點內(nèi)容:JAVA基礎JVM 知識開源框架知識操作系統(tǒng)多線程TCP 與 HTTP架構(gòu)設計與分布式算法數(shù)據(jù)庫知...
    消失er閱讀 4,558評論 1 10
  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個如下例子,分析運行結(jié)果: 代碼一: a = 1 def...
    伊森H閱讀 3,177評論 0 15
  • 40 ajax平時是怎么用的,為什么用 有時候只要更新的是頁面某一塊內(nèi)容,這樣頁面的其他內(nèi)容是不需要重新獲取的。 ...
    zhihaoZzz閱讀 837評論 0 2
  • 朋友家聚餐 好多小朋友啊
    三三不惑閱讀 100評論 0 5
  • 學期過半,不知不覺當老師也已經(jīng)有近三個月了。一直處于懵懵懂懂,不斷在反思,改進自己的教學方法,對于班級管理的辦法也...
    沅陵500鄧凱麗閱讀 264評論 0 0

友情鏈接更多精彩內(nèi)容