【精選】面試官:聊下常見設計模式有哪些?
單例模式解決的是如何在整個項目中創(chuàng)建唯一對象實例的問題,避免重復創(chuàng)建(實例化)
對象,已經(jīng)有現(xiàn)成的實例就用現(xiàn)成的。減少資源的浪費(因為創(chuàng)建多個實例,浪費內(nèi)存,
完全沒必要),單件模式保證了每時每刻引用的都是同一個實例。最常用的地方是數(shù)據(jù)庫連接。
工廠模式 是一種類,它具有為您創(chuàng)建對象的某些方法。工廠模式解決的是如何不通過 new建立實例對象的方法,您可以使用工廠類創(chuàng)建對象,而不直接使用 new。這樣,如 果您想要更改所創(chuàng)建的對象類型,只需更改該工廠即可。使用該工廠的所有代碼會自動 更改。
適配器模式:將各種截然不同的函數(shù)接口封裝成統(tǒng)一的API,首先定義一個接口(有幾個 方法,以及相應的參數(shù))。然后,有幾種不同的情況,就寫幾個類實現(xiàn)該接口。將完成相 似功能的函數(shù),統(tǒng)一成一致的方法。
策略模式:將一組特定的行為和算法封裝成類,以適應某些特定的上下文環(huán)境,用意是 對一組算法的封裝。動態(tài)的選擇需要的算法并使用。
實現(xiàn)單例模式的要點:
三私一公:私有化靜態(tài)屬性,私有化構造方法,私有化克隆方法,公有化靜態(tài)方法。
//(1).?需要一個保存類的唯一實例的靜態(tài)成員變量:
private??static?$instance;?//私有化靜態(tài)屬性
//(2).?構造函數(shù)和克隆函數(shù)必須聲明為私有的,防止外部程序new類從而失去單例模式?的意義:
private?function?__construct()?//私有化構造方法
{
????$this->_db?=?pg_connect('xxxx');
}
private?function?__clone()?//私有化克隆方法,禁止克隆
{
}
//(3).?必須提供一個訪問這個實例的公共的靜態(tài)方法(通常為getInstance方法),從?而返回唯一實例的一個引用
public?static?function?getInstance()
{
????if?(!(self::$_instance?instanceof?self))?{
//公有化靜態(tài)方法
????????self::$_instance?=?new?self();
????}
????return?self::$_instance;
}
$node?=?new?Node();
$node->set(0,?2);
$node->setAll(3);
return?$node->get(0);
class?Node
{
????private?static?int?$counter?=?0;?//?計數(shù)器,記錄是否被修改過?private?static?array?$array;?//?數(shù)組存儲
????private?static?int?$globalValue;?//?全局的值
????public?function?set($index,?$value)
????{
????????self::$array[$index]?=?[self::$counter,?$value];
????}
????public?function?get($index)
????{
????????$tmp?=?self::$array[$index][0];
????????$value?=?self::$array[$index][1];
????????if?($tmp?==?self::$counter)?return?$value;
????????return?self::$globalValue;
????}
????public?function?setAll($value)
????{
????????self::$counter++;
????????self::$globalValue?=?$value;
????}
}
3.Redis 緩存擊穿,緩存穿透,緩存雪崩區(qū)別及解決方案
緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),而用戶不斷發(fā)起請求,造成了類似攻擊行
為
緩存擊穿是大批量的請求在訪問一個key,這個key失效的瞬間,請求打到了數(shù)據(jù)庫?
緩存雪崩是大批量的請求在訪問大批量的key,這些key同時失效,所有請求打到數(shù)據(jù) 庫,造成數(shù)據(jù)庫無法響應。
避免雪崩是給key加一個隨機生存時間,例如都是 3分鐘,給他們加一個random_int(1,30) 這樣的時間,不會同時失效,或者熱點數(shù)據(jù)長期有效,至少過完高并 發(fā)的這幾天再失效。
避免穿透是接口層增加校驗,比如用戶鑒權校驗,參數(shù)做校驗,不合法的參數(shù)直接代碼
return,同時nginx層面限制ip請求頻率。也可以借助布隆過濾器,從其中判斷key存不
存在,不存在直接return ;
避免擊穿最簡單是讓key長期有效。
4.PHP 查找兩個有序數(shù)組的相同元素 還是雙指針的經(jīng)典妙用
public?function?findTheSameItems($arr1,$arr2)?{
????$size1?=?count($arr1);
????$size2?=?count($arr2);
????$i?=?$j?=?0;
????$result?=?[];
????while?(true)?{//移動值較小的
????????if?($arr1[$i]?>?$arr2[$j])
????????????$j++;
????????elseif?($arr1[$i]?$arr2[$j])
????????????$i++;?else?{
????????????$result[]?=?$arr1[$i];
????????????$j++;?}
????????if?($i?==?$size1?||?$j?==?$size2)
????????????break;
????}
????return?$result;
}
配上二分查找的套路:
#?二分查找
function?binarySearch(array?$arr,?$target)
{
????$low?=?0;
????$high?=?count($arr)?-?1;
????while?($low?<=?$high)?{
????????$mid?=?floor(($low?+?$high)?/?2);?#?找到元素
????????if?($arr[$mid]?==?$target)?return?$mid;?#?中間元素比目標大,查找左邊
????????if?($arr[$mid]?>?$target)?$high?=?$mid?-?1;
????#?中間元素比右邊小,查找右邊
????????if?($arr[$mid]?$target)?$low?=?$mid?+?1;
????}
????#查找失敗
????return?false;
}
借助二分查找實現(xiàn)開根號計算:
function?mySqrt($x)
{
????if?($x?<=?1)?return?$x;
????$left?=?1;
????$right?=?$x?-?1;
????while?($left?<=?$right)?{
????????$mid?=?$left?+?(($right?-?$left)?>>?1);
????????if?($mid?>?$x?/?$mid)?{
????????????$right?=?$mid?-?1;
????????}?else?if?($mid?$x?/?$mid)?{
????????????if?($mid?+?1?>?$x?/?($mid?+?1))?return?$mid;
????????????$left?=?$mid?+?1;
????????}?else?{
????????????return?$mid;
????????}
????}
????return?-1;?//?only?for?return?a?value
}在聊天對話框內(nèi)回復【激活碼】
即可獲取最新idea激活碼(實時更新)
-END-
右下角,您點贊和在看
小編工資漲2毛

