當面試官問我們vector擴容機制時,他想問什麼?

2021-10-05 19:18:57 字數 2035 閱讀 7090

【常規】

push_back的話,一般來說,都是按兩倍來擴容,因為push_back每次都是只插入乙個資料

insert的話,因為可以一次插入多個資料,所以要複雜一些。

觸發擴容時,如果要插入的資料量比舊容量小,則按兩倍擴容;如果要插入的資料量比原來的舊容量還要大,即表示即使按兩倍擴容了,依然存不下要插入的資料,此時將會按照舊容量加要插入的資料量來擴容,保證一次擴容就能容下要插入的資料;

即 new_capacity = max ( old_capacity * 2, n + old_capacity )。

【高階】

其實,那個兩倍也不是一定的,c++標準並沒有規定vector到底應該按多少來擴容,有一些選擇2,有一些選擇1.5。那麼一般是根據什麼來選擇這個擴容因子的呢?

確定擴容因子的大小,主要從時間和空間的角度來分析。

從空間上來分析,擴容因子越大,意味著預留空間越大,浪費的空間也越多,所以從空間考慮,擴容因子因越小越好。

從時間上來分析,如果預留空間不足的話,就需要重新開闢一段空間,把原有的資料複製到新空間,如果擴容因子無限大的話,那顯然就不再需要額外開闢空間了。所以時間角度看,擴容因子越大越好。

還可以從攤還分析的角度來分析,為了簡化分析,就不考慮一次性插入大量資料的情況,只考慮push_back的情況:

假設擴容因子為k,vector最後的長度為n

顯然每次常規插入操作需要1的時間,插入n個資料的常規時間為n

現在考慮額外的消耗,擴容因子為k,意味著一共需要擴容logkn次(以k為底,n的對數),為簡化計算,假設是容量是從1開始,也就是要對下面的等比序列求和

s = 1 + k + k^2 + k^3 + k^4  + …… +  k^(logkn) = (n-1)/(k-1)

顯然,也就意味著擴容因子k越大,額外的消耗越小。總消耗為n+(n-1)/(k-1) 。當k大於1時,k越大總消耗越小。

[bytheway]

順便可以再求一下push_back的攤還時間複雜度。即為(n+(n-1)/(k-1))/n = (nk-1)/(k-1)

最普遍的情況下,當擴容因子為2時,最好的評價時間複雜度為2n,發生在n等於2的n次冪時,最差為3n,發生在n等於2的n次冪加1時。

【再高階】

既然從時間上考慮k越大越好,從空間考慮k越小越好,那麼有沒有乙個數為最佳,同時協調好空間與時間呢?

我們從記憶體上來考慮,vector資料實際存放在堆上,vector的每次擴容需要把舊的釋放,再重新開闢一段新的連續記憶體。

我們來看一下k = 2時的情況。

每次擴容後capacity的情況如下:1,2,4,8,16,32 ……..

當我們釋放了4的空間,我們尋找8的新空間,再次擴容,釋放8,尋找16。。

仔細分析,第5次擴容時,需要尋找16的新空間,第4次釋放了8,第3次釋放了4,第2次釋放了2,第1次釋放了1,所以 1 + 2 + 4 + 8 = 15  < 16,也就意味著,之前釋放的空間,永遠無法被下一次的擴容利用,這對記憶體與cache是非常不友好的。

我們再來看一下k = 1.5的情況。

每次擴容之後capacity的情況為:1,2,3,4,6,9,13,19,28 ……

再按剛才的思路分析一遍,1 + 2 >= 3;  2 + 3 + 4 >= 6;  6 + 9 >= 13 …….

所以,當k為1.5時,顯然對記憶體和cache要友好很多,至少從容量上來說,是存在重複利用的可能性的。

因此,我們可以得出結論,當k = 2時,時間上要比 k = 1.5 佔優,而空間上比 1.5 稍有劣勢。

那麼,那個最佳的數是多少呢?

繼續剛才的分析,我們希望的是,上幾次的空間,存在被下一次擴容時利用的可能性。

也就是 x(n-2) + x(n-1) >= x(n),顯然我們也希望時間上也要更好,即x(n-2) + x(n-1) = x(n)

即:1,2,3,5,8,13,21,34,55 。。。。

是不是很熟悉。。。是的,這就是我們的斐波那契數列。。。

那麼當n趨於無限大時,取極限,最佳的擴容因子也就是那個最美的數,**分割率,1.618。

面試官!讓我們聊聊正則

正規表示式是處理字串的利器,並提高工作效率,乙個好的正則能夠幫我們省去幾十甚至上百行 在工作中,也許你會見到在 現很多正則處理字串,也可能見到 中毫無正則,原因在於會正則的人往往處理字串首先想到用正則去處理,不會的那必然用很多api處理。並且在面試的時候很多同學往往掛在正則這裡,所以對於前端正則是乙...

當面試官問你Vue響應式原理,你可以這麼回答他

vue的響應式是如何實現的?聽過太多回答,通過object.defineproperty,可是再詳細的問時,對方渾然不知。先擼為敬 const observer function data const definereactive function obj,key set newval val ne...

碼教授 面試官 你還有什麼要問我的嗎?

面試,除了萬年不變的開場 請介紹一下你自己 結束時還會有乙個100 會遇到的問題 你還有什麼問題嗎?你有什麼要問我的嗎?面試官這樣問只是客套一下嗎?我可以說 沒有 嗎?我可以問工資待遇嗎?我應該問幾個問題,8個夠嗎?面試是乙個雙向選擇的過程 你對面試官的提問雖然不至於改變整個面試的結局 但是如果問出...