遞歸加緩存
A. Hibernate載入樹形結構的數據怎麼用上二級緩存
public Menu getParent() {
return parent;
}
@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "pid")
public Set<Menu> getChildren() {
return children;
}
這些數據由於很修改少,訪問頻繁,因此很適合放在緩存中。
下面是EhCache配置:
?
1
2
3
4
5
6
7
8
9
10
<cache name="Menu"
maxElementsInMemory="100"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
="120"
memoryStoreEvictionPolicy="LRU"
/>
我在程序中用遞歸方式獲得整個樹形結構的數據,觀察後台Hibernate輸出的語句,一直都沒使用上緩存。根據Hibernate使用緩存的機制:
1) Hibernate首先根據這些查詢信息組成一個Query Key,Query Key包括條件查詢的請求一般信息:SQL, SQL需要的參數,記錄范圍(起始位置rowStart,最大記錄個數maxRows),等。 2) Hibernate根據這個Query Key到Query緩存中查找對應的結果列表。如果存在,那麼返回這個結果列表;如果不存在,查詢資料庫,獲取結果列表,把整個結果列表根據Query Key放入到Query緩存中。 3) Query Key中的SQL涉及到一些表名,如果這些表的任何數據發生修改、刪除、增加等操作,這些相關的Query Key都要從緩存中清空。
B. java 用遞歸在字元串中重復出現的字元中添加一個*
Java中方法的概念以及遞歸(漢諾塔問題)
文章目錄
Java中方法的概念以及遞歸(漢諾塔問題)
1、遞歸的概念
2、遞歸的練習
1)、漢諾塔問題
2)、青蛙跳台階
3)、青蛙跳台階(進階)(遞歸->動態規劃)
1、重載所能解決的問題
1、方法的概念
2、實參形參的關系
一、方法的基本使用
二、方法的重載
三、遞歸的概念
能夠使代碼模塊化,使代碼的結構更加清晰。
當重復使用一個功能(代碼)時,只需要寫出方法名進行調用,避免相同代碼重復累贅。
讓代碼更好理解更簡單。
- public class Main { public static void main(String[] args) { int a = 10; int b = 20; int c = add(a, b); //在main方法中,直接調用其他方法,必須為static的方法 } public static int add(int num1, int num2) { return num1 + num2; }}
方法名相同
方法的參數不同。(形參類型不同,個數不同)
方法的返回值類型不影響重載
- public class Main { public static void main(String[] args) { int n = 5; //求5的階乘 System.out.println(fact(n)); } public static int fact (int n) { if (n == 1) { //遞歸結束的條件 return 1; } return n * fact(n - 1); //例如5! = 5 * 4! -》 5 * 4 * 3! ,一直遞歸到1的階乘,就結束 }}
先將N - 1層移動到mid柱子,給最下面那一層讓路。
N - 1層移開之後,路就讓出來了。此時移動第N層圓盤即可。
此時第一步移動的 N- 1層圓盤 還在mid柱子上,現在就是從 mid柱子 移動到 right柱子上。
- public class Main { public static void main(String[] args) { //漢諾塔 int n = 3; hanoiTower(n, "left", "right", "mid"); } public static void hanoiTower(int n, String from, String to, String mid) { if (n == 1) { System.out.println("move 1 from " + from + " to " + to); return; //記得返回,終止遞歸 } hanoiTower(n - 1, from, mid, to); //圖1 -> 圖2 System.out.println("move " + n + " from " + from + " to " + to); //圖2 -> 圖3 hanoiTower(n - 1, mid, to, from); //圖3 -> 圖4 }}
- public class Main { public static void main(String[] args) { int n = 3; //台階數 System.out.println(jumpFloor(n)); } public int jumpFloor(int target) { if (target == 1) { //情況一 return 1; } if (target == 2) { //情況二 return 2; } return jumpFloor(target - 1) + jumpFloor(target - 2); //情況三 }}
- public class Main { public static void main(String[] args) { int n = 3; //假設就是3層台階 System.out.println(frogJumpPlus(n)); } public static int frogJumpPlus(int n) { if (n == 1) { return 1; } if (n == 2) { return 2; } int res = 1; //當前,需要選擇一種的跳法 //此處的for循環,就是去嘗試,跳1步、2步、3步……一直跳到n層台階,將這些情況全部加起來,就是當前的結果 for (int i = 1; i < n; i++) { res += frogJumpPlus(n - i); //i控制台階數,每次循環,都減一步台階。去遞歸所有的台階 } return res; }}
- public class Main { public static void main(String[] args) { int n = 3; //假設就是3層台階 System.out.println(frogJumpPlus(n)); } public static int frogJumpPlus(int n) { if (n == 1) { return 1; } int[] dp = new int[n + 1]; dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i++) { dp[i] = 1; //加上自己需要跳的這一步 for (int j = 1; j < i; j++) { dp[i] += dp[j]; //把前面所有數據,累加一遍,就是當前台階的跳法 } } return dp[n]; }}
一、方法的基本使用
1、方法的概念
Java語言中的「方法」(Method)在其他語言當中也可能被稱為「函數」(Function)。
對於一些復雜的代碼邏輯,如果希望重復使用這些代碼,並且做到「隨時任意使用」,那麼就可以將這些代碼放在一個大括弧「{}」當中,並且起一個名字。使用代碼的時候,直接找到名字調用即可。
方法存在的意義:
接下來看方法的結構:
訪問修飾限定符:自由選擇,告訴編譯器如何調用該方法。定義了該方法的訪問類型。
**靜態static:**當調用的主函數是static時,被調用的函數需要為static的。例如:java中,main方法直接調用add方法。此時的add方法需要static修飾。
返回值類型:方法可能會返回值。return Value Type 是方法返回值的數據類型。有些方法執行所需的操作,但沒有返回值。在這種情況下,return Value Type 是關鍵字void。
參數類型:參數像是一個佔位符。當方法被調用時,傳遞值給參數。這個值被稱為實參或變數。參數列表是指方法的參數類型、順序和參數的個數。參數是可選的,方法可以不包含任何參數。
方法名(函數名):是方法的實際名稱。方法名和參數表共同構成方法簽名。
方法體:方法體包含具體的語句,定義該方法的功能。
2、實參形參的關系
實參:在方法中,實際傳遞的數值就是實際參數。比如上面的main函數中, int c = add(a, b); 這里的a和b就是實際參數,稱為實參。
形參:在被調用的方法里,由實參傳遞過來的數值,就稱為形式參數。形參是實參的一份臨時拷貝。也就是說,main函數傳遞的a和b,與add方法中的a和b,雖然都是10和20(上面代碼中),但是二者並不是來自同一塊內存空間:如下圖所示:
二、方法的重載
1、重載所能解決的問題
在我們平常寫代碼中,少不了數據的加減乘除。也少不了對不同類型的數據進行四則運算。假設:我們就寫了上面的代碼(add方法),我們用浮點數(小數)調用add方法,會有什麼情況發生?
此時大家就會想,我重新寫一個double類型的方法不就行了嗎。
沒錯,就是再次寫一個double類型的add就行啦。在C語言中,我們寫的函數(方法),不能夠寫重命的。比如,我寫兩個add的函數。函數名就是叫add。一模一樣,在C語言中是不允許的。
但是在java中,這是可以。也就是這節所講的 方法重載。
根據形參的類型和形參的個數,去尋找被調用的方法。
上面的代碼,分別調用了add方法,雖然都叫add。但是形參類型不一樣。所以是兩個不同的方法。這就叫重載。
重載的規則
註:當方法的方法名相同,參數相同,但返回值類型不同的時候,這不構成重載。
三、遞歸的概念
1、遞歸的概念
一個方法在自己調用自己時,就稱為「遞歸」。
當一個大問題,是由若干個小問題,並且這些小問題的解決方法,都是一樣的。這樣的問題,很大可能就能用遞歸去解決。
遞歸相當於數學上的**「數學歸納法**」,有一個起始條件, 然後有一個遞推公式
例如,我們求N!
起始條件: N= 1的時候, N!為1. 這個起始條件相當於遞歸的結束條件.
遞歸公式:求N!,直接不好求,可以把問題轉換成N!=> N * (N-1)!
例如代碼:
2、遞歸的練習
1)、漢諾塔問題
漢諾塔游戲(7K7K小游戲鏈接)。在開始講解之前,大家還是先去玩一玩漢諾塔游戲,看看是什麼規則。更容易的理解下面的代碼。
牛客網OJ題鏈接
漢諾塔游戲規則:
現有三根柱子,我們分別叫left, mid,right。現在有3個圓盤left柱子上,3個圓盤的大小關系為:從上往下,圓盤越來越大。
每次只能取出一個圓盤,並且圓盤在取和放的時候,必須在這三根柱子上完成。不能取出來放到其他地方。
且,大的圓盤不能放到小的圓盤上。
問,怎麼移動圓盤,讓圓盤從left柱子,移動到right柱子上。
情況一:我們先從1個圓盤舉例說明, 我們直接從left柱,移動到right柱即可
情況二:2個圓盤的情況
情況三:3個圓盤的情況
這就是大致的思路:
不要去深究每一步的細節,抓好大致的思路,確定好遞歸終止的條件。宏觀的去想這個問題,就能夠很好地抓到問題的本質。
2)、青蛙跳台階
青蛙跳台階 OJ題鏈接
情況一:一步台階只能跳一次,就跳完了;1種
情況二:兩步台階題意是,青蛙一次可以跳一步台階,也可以跳兩步台階。所以情況二的跳法是2 種
情況三:三步台階
現在擺在我面前的問題就是。我要麼跳一步台階。我要麼跳兩步台階。
不對,是擺在青蛙面前的問題!!!口誤口誤!
假設1:青蛙跳一步台階後,還剩兩個台階沒跳。此時是不是又回到了兩層台階的決策問題(上文情況二);
假設2:青蛙跳兩步台階後,還剩一個台階沒跳。此時是不是又回到了一層台階的決策問題(上文情況一);
我們把這兩種情況的假設,結果加起來,就是三層台階的所有跳法了!!!
再往下,四層、五層……,推導的思路,不就展開了嘛
3)、青蛙跳台階(進階)(遞歸->動態規劃)
青蛙跳台階(進階)OJ鏈接
看完題目,各位有什麼感想???
是不是跟初級的,區別不是很大?遞歸終止的條件還是一步台階和兩步台階的情況。
情況一和情況二的情況,我們就不說了,跟上文初階的一模一樣。還是1種跳法和2種跳法;我們重點來看一下三層台階的情況。
情況三:三層台階
三層台階:也就是說青蛙一次可以跳到3層台階。彈跳力見漲啊!(注意:並不是說,青蛙就一次只能跳3層台階,題意是(1 ……n層中 ,每一層 它都可以一次跳過)。
假設青蛙一次最大跳三層:
假設一:青蛙第一次跳一層台階,還剩兩個台階沒跳 ->兩層台階的決策問題。
假設二:青蛙第一次跳兩層台階,還剩一個台階沒跳 ->一層台階的決策問題。
假設三:青蛙第一次跳三層台階,沒有台階跳了 ->0層台階的決策問題。
那如果是四層台階 五層台階 N層台階呢? 那是不是有幾層,就有幾種假設情況?那就需要相加!!!來看這個題的代碼:
上面的代碼,就是經典的遞歸方式,去解這個題。
其實,在台階數足夠大時,這樣的遞歸,會有很多的重復計算:比如:
計算5層台階時:
假設一:第一次跳一層台階,第二次跳一層台階。此時還剩三層台階。 ->三層台階決策問題。
假設二:第一次跳兩層台階,此時還剩下三層台階。 ->三層台階決策問題。
此時我們就發現了,上面兩種假設就會產生重復計算。我們此時就想,有沒有一種方法,讓我們只計算一次,就能解決重復計算的問題。
那就是加緩存,我們用一塊空間,來保存每次計算的結果,當我們需要的時候,直接從內存空間裡面拿就行。
暴力遞歸 -> 動態規劃:
對比兩種方法:
我們畫出前面幾組數據,就能找出規律:
可能你就會疑惑,我寫不出來這動態規劃。那可以先寫遞歸的版本。在遞歸的版本上去修改,加緩存。
具體是以什麼形式來緩存,還得看你的可變參數,例如這個題的可變參數就只有一個n,也就是台階數。那我們就開辟一維數組,就能解決。
那如果是兩個可變參數,那麼此時就可能需要二維數組來做緩存了!!!
總之,像這種考察遞歸的題目。我們都可以加緩存的形式。到底需不需要加緩存,我們就得看看,遞歸的時候,是否涉及了大量的重復計算。
最後考考大家,上面寫的動態規劃的版本,是否還可以優化呢???(提示一下: 兩層for循環,時間復雜度O(N2))
好啦,本期更新就到此結束了,我們下期見!!!
,https://blog.csdn.net/x0919/article/details/119279165
C. 怎麼列動態規劃遞推方程
動態規劃中遞推式的求解方法不是動態規劃的本質。我曾經作為省隊成員參加過NOI,保送之後也給學校參加NOIP的同學多次講過動態規劃,我試著講一下我理解的動態規劃,爭取深入淺出。希望你看了我的答案,能夠喜歡上動態規劃。0.動態規劃的本質,是對問題狀態的定義和狀態轉移方程的定義。引自維基網路.動態規劃是通過拆分問題,定義問題狀態和狀態之間的關系,使得問題能夠以遞推(或者說分治)的方式去解決。本題下的其他答案,大多都是在說遞推的求解方法,但如何拆分問題,才是動態規劃的核心。而拆分問題,靠的就是狀態的定義和狀態轉移方程的定義。1.什麼是狀態的定義?首先想說大家千萬不要被下面的數學式嚇到,這里只涉及到了函數相關的知識。我們先來看一個動態規劃的教學必備題:給定一個數列,長度為N,求這個數列的最長上升(遞增)子數列(LIS)的長度.以172834為例。這個數列的最長遞增子數列是1234,長度為4;次長的長度為3,包括178;123等.要解決這個問題,我們首先要定義這個問題和這個問題的子問題。有人可能會問了,題目都已經在這了,我們還需定義這個問題嗎?需要,原因就是這個問題在字面上看,找不出子問題,而沒有子問題,這個題目就沒法解決。所以我們來重新定義這個問題:給定一個數列,長度為N,設為:以數列中第k項結尾的最長遞增子序列的長度.求中的最大值.顯然,這個新問題與原問題等價。而對於來講,都是的子問題:因為以第k項結尾的最長遞增子序列(下稱LIS),包含著以第中某項結尾的LIS。上述的新問題也可以叫做狀態,定義中的「為數列中第k項結尾的LIS的長度」,就叫做對狀態的定義。之所以把做「狀態」而不是「問題」,一是因為避免跟原問題中「問題」混淆,二是因為這個新問題是數學化定義的。對狀態的定義只有一種嗎?當然不是。我們甚至可以二維的,以完全不同的視角定義這個問題:給定一個數列,長度為N,設為:在前i項中的,長度為k的最長遞增子序列中,最後一位的最小值..若在前i項中,不存在長度為k的最長遞增子序列,則為正無窮.求最大的x,使得不為正無窮。這個新定義與原問題的等價性也不難證明,請讀者體會一下。上述的就是狀態,定義中的「為:在前i項中,長度為k的最長遞增子序列中,最後一位的最小值」就是對狀態的定義。2.什麼是狀態轉移方程?上述狀態定義好之後,狀態和狀態之間的關系式,就叫做狀態轉移方程。比如,對於LIS問題,我們的第一種定義:設為:以數列中第k項結尾的最長遞增子序列的長度.設A為題中數列,狀態轉移方程為:(根據狀態定義導出邊界情況)用文字解釋一下是:以第k項結尾的LIS的長度是:保證第i項比第k項小的情況下,以第i項結尾的LIS長度加一的最大值,取遍i的所有值(i小於k)。第二種定義:設為:在數列前i項中,長度為k的遞增子序列中,最後一位的最小值設A為題中數列,狀態轉移方程為:若則否則:(邊界情況需要分類討論較多,在此不列出,需要根據狀態定義導出邊界情況。)大家套著定義讀一下公式就可以了,應該不難理解,就是有點繞。這里可以看出,這里的狀態轉移方程,就是定義了問題和子問題之間的關系。可以看出,狀態轉移方程就是帶有條件的遞推式。3.動態規劃迷思本題下其他用戶的回答跟動態規劃都有或多或少的聯系,我也講一下與本答案的聯系。a.「緩存」,「重疊子問題」,「記憶化」:這三個名詞,都是在闡述遞推式求解的技巧。以Fibonacci數列為例,計算第100項的時候,需要計算第99項和98項;在計算第101項的時候,需要第100項和第99項,這時候你還需要重新計算第99項嗎?不需要,你只需要在第一次計算的時候把它記下來就可以了。上述的需要再次計算的「第99項」,就叫「重疊子問題」。如果沒有計算過,就按照遞推式計算,如果計算過,直接使用,就像「緩存」一樣,這種方法,叫做「記憶化」,這是遞推式求解的技巧。這種技巧,通俗的說叫「花費空間來節省時間」。都不是動態規劃的本質,不是動態規劃的核心。b.「遞歸」:遞歸是遞推式求解的方法,連技巧都算不上。c."無後效性",「最優子結構」:上述的狀態轉移方程中,等式右邊不會用到下標大於左邊i或者k的值,這是"無後效性"的通俗上的數學定義,符合這種定義的狀態定義,我們可以說它具有「最優子結構」的性質,在動態規劃中我們要做的,就是找到這種「最優子結構」。在對狀態和狀態轉移方程的定義過程中,滿足「最優子結構」是一個隱含的條件(否則根本定義不出來)。對狀態和「最優子結構」的關系的進一步解釋,什麼是動態規劃?動態規劃的意義是什麼?-王勐的回答寫的很好,大家可以去讀一下。需要注意的是,一個問題可能有多種不同的狀態定義和狀態轉移方程定義,存在一個有後效性的定義,不代表該問題不適用動態規劃。這也是其他幾個答案中出現的邏輯誤區:動態規劃方法要尋找符合「最優子結構「的狀態和狀態轉移方程的定義,在找到之後,這個問題就可以以「記憶化地求解遞推式」的方法來解決。而尋找到的定義,才是動態規劃的本質。有位答主說:分治在求解每個子問題的時候,都要進行一遍計算動態規劃則存儲了子問題的結果,查表時間為常數這就像說多加辣椒的菜就叫川菜,多加醬油的菜就叫魯菜一樣,是存在誤解的。文藝的說,動態規劃是尋找一種對問題的觀察角度,讓問題能夠以遞推(或者說分治)的方式去解決。尋找看問題的角度,才是動態規劃中最耀眼的寶石!(大霧)
D. 緩存,遞歸,授權dns的統一和分離部署的區別
系統linux簡單使用dnsmasq用yum或者apt-get裝使用 vi打/etc/dnsmasq.conf配置文件拉使用 server=ip 式添加級伺服器用途用避免dns污染其實能流量經際口遇dns搶答
windowsserver其實自帶dns伺服器工具通伺服器管理器啟用
E. 一個關於遞歸的問題C#,代碼如下
class Program //這句不用說吧
{
static void Main(string[] args) //這句也是,命令行入口,不多說
{
Program pr = new Program(); //新建Porgram類pr,實例化。
pr.Count(3); //總次數三次
Console.ReadKey(); //等待按鍵結束
}
public void Count(int inVal) //函數Count ,依據參數倒序顯示,比如輸入5,那
{ 么顯示5,4,3,2,1
if (inVal == 0) //如果參數為0,則返回,程序不再執行
{
return;
}
Count(inVal - 1); //每次減1
Console.WriteLine("{0}",inVal); //輸出顯示
}
}
F. 路由器的遞歸查詢怎樣解釋
什麼是路由? 所謂路由的過程就是從入站介面接收到數據包,經過CPU的處理(查找路由表,重構二層幀),把「新」包放入到相應的介面的過程。這個過程實際上可以 轉化成下面的一個模型:一輛汽車(數據包)走到了一個十字路口,注意,此時它是有目的地的(目的IP地址),比如這輛汽車想去往北京,到了這個十字路口, 看到了有幾個牌子上面寫著「北京,石家莊,唐山」,那麼這個時候駕駛員(CPU)就應該來選擇那個去往北京的路口(出站介面),這樣也就完成了路由功能。更進一步,微觀上的路由查詢是怎麼進行的。這里所說的微觀,並不去討論路由轉發的各種演算法,而是去討論路由器如何去查找路由表。我們先來看一個簡單的拓撲
有四個路由器,分別是POOH,TIGGER,PIDET,RABBIT,在這個拓撲下面顯示的是POOH的路由表,可以看到,現在已經可以從POOH上查詢到了五個網段,也就是說現在達到了全網互通。
舉 例來說,如果想達到網段10.1.10.0,CPU開始查找路由表,發現了一個路由條目是到達10.1.10.0的,通過192.168.1.194,而 這個地址就是piglet路由器最左邊的那個埠,那麼這個192.168.1.194又是怎麼到達呢?再一次查找路由表,找到了一個網段 192.168.1.192,這裡面就包含了192.168.1.194這個地址,而到達它是通過192.168.1.66來實現的。那麼 192.168.1.66又是應該怎麼到達?還得繼續查找路由表。192.168.1.194
這個過程在周而復始的進行,形成一個遞歸的過程,知道路由器找到直連網段位置,按照上面的那個實例來說就是當找到192.168.1.64這個條目。
好了,這就是路由器遞歸查詢的過程。
但是,這樣的查詢方法有什麼用途呢?你是否考慮過呢?
先讓我們回到一個比較本質的問題上去,路由器和交換機的作用是什麼?其實無非是兩個作用,一是考慮如何把數據包正確的送到目的地址,二是如何更快的送到。 至於其他的各種安全技術,QoS等等都是為這兩個終極目標服務的。由於本篇不涉及到交換機的內容所以在此略過不提,單說路由器,工程師們為了讓路由器更好的完成這兩個任務做出了不懈的努力,其中一個就是不斷改進的包交換方法以達到快速的轉發包的目的。
先讓我們從歷史的角度看一下
最早誕生的是「進程交換」
這種交換很傳統,路由器每收到一個包就會通過CPU查找路由表然後送到出站埠,每過來一個包就會這樣做一次。這種方法是沒有問題的,但是卻很慢,明顯的效率不高。
為了解決這個問題,「快速交換」誕生了
這 裡面有一個前提,也是能開發出「快速交換」的一個先提條件,那就是我們的數據一般都是以流的形式傳播的,流,這個詞十分形象,就是一串數據包都去往同一個 地方。當工程師發現了這個規律之後,「快速交換」的想法誕生了,所謂快速交換就是,先分析每個流的第一個包,按照進程交換的方式進行查詢,然後出站同時把 這個查詢的結果保存在一個獨立的緩存中。當這個流中剩下的包進站時,路由器不是去查路由表而是去查緩存,這樣就能節省CPU的資源,直接把包轉發出去。這 樣不但提高了包轉發的速度,實際上也提高了CPU的使用效率。
最後就是CEF
思科的快速交換,CEF有太多的內容需要講,相對於前兩種交換方式有很大的不同,我在這里只取其在交換形式上的差別。進程交換是當一個新數據流來了後路由第一個包,然後把信息記入緩存來對轉發進行加速。而CEF的做法更絕!
連第一個包都不用查了,直接進行緩存操作!而且是在包之前就進行了緩存。
也就是大名鼎鼎的FIB表。
當一個數據包入站的時候,直接查詢FIB表而不是路由表,這樣就能大大增加轉發的速度。
也 許你有疑問,我當初就是有疑問的,本來有好好的路由表,現在又建立了一個FIB表,一個數據包到了不還是需要查找嗎?這樣有什麼作用?很顯然現在一般的圖 書上並沒有寫明原因,沒有給我一個合理的解釋。不過對於這個問題,以及對於CEF的專題討論我會在下周的時候單獨寫一篇文章來敘述,讓你明白CEF!
現在讓我們尊重一個事實,CEF更快!
我用了大量的篇幅來寫看似與本篇主題無關的「路由器交換」,我想告訴大家的是「加快交換,遠離路由表」,CPU路由查詢的次數越少轉發的效率越高!
那麼現在讓我們回到本篇文章的主題「遞歸路由的查詢」,強烈的困惑!人家查一次路由表都嫌多,你卻使用遞歸查詢查了那麼多遍路由表!
確實,這就是遞歸查詢的最大缺點!也是我們在設計網路的時候必須要考慮的一個問題。不過仔細想一下,既然這是一個極為「不成功」的方法,那麼為什麼還會允許它的存在呢?這又是為了什麼?
遞歸查詢的優勢!無與倫比的優勢!
我們來看一下這個拓撲,注意一下SANDERZ的靜態路由的設計。
這就是一個典型的遞歸路由的使用案例,可以仔細的看一下。
這里我們先設計一個情景,從顯示的路由路由信息來看,現在到達右側網段的所有數據都要從HEFFALUMP路由器通過,這個時候如果HEFFALUMP壞了,那麼必須要從WOOZLE進行路由。
這個時候網路管理員只需要調整一條路由就可以了。
Sanderz(config)# ip route 10.87.14.0 255.255.255.0 10.23.5.95
Sanderz(config)# no ip route 10.87.14.0 255.255.255.0 10.23.5.20
這樣就完成了任務。
那麼如果不使用遞歸路由呢?那麼圖中的每一個路由都要重新設置,如果按照上圖的案例來說,我們需要重新寫26條路由條目。如果你覺得這樣的數量還能忍受, 那麼如果有100個,400個網段呢?你要重寫200條,800條路由!這個工作量就大了吧,你還能忍受嗎?同樣是400個網段,使用遞歸路由還是上面的 兩條命令。
借用並改造演算法中時間復雜度的概念:不使用遞歸路由的時間復雜度為O(n),而使用了遞歸路由的時間復雜度為O(1)!
這也就是遞歸路由最大的優點!
面對遞歸路由的優點與缺點,確實是很難辦,是需要斟酌的。(這是《ROUTING TCP/IP VOL.1 》的說法)
不過我想其實並不是那麼「難辦」
從實際的網路應用來講,現在能夠使用靜態路由的網路拓撲不會很大,相對於路由器CPU的處理能力來講不是很大的負擔,也就不會很影響速度,所以為了管理的方便我們是可以放心的使用遞歸路由的。
但是,我這種說法並不包含 兩個大的園區網之間用靜態路由的情況(教育網),這樣的情況還是使用最普通的路有方式吧。
具體情況具體分析,相必大家對與遞歸路由的優勢和缺點也是很熟悉了,能夠在其間取捨。
G. dns中遞歸查詢與迭代查詢的區別
兩者區別如下:
遞歸是用戶只向本地DNS伺服器發出請求,然後等待肯定或否定答案。而迭代是本地伺服器向根DNS伺服器發出請求,而根DNS伺服器只是給出下一級DNS伺服器的地址,然後本地DNS伺服器再向下一級DNS發送查詢請求直至得到最終答案。
H. 遞歸的時候內存溢出一般用什麼方法解決
遞歸終止條件,一般有多種方式:
1. 添加遞歸深度參數到遞歸函數的參數中
每次調用深度加一,在函數體中添加條件語句,當深度超過某個值時強行return;
2. 引入元素棧結構,每次遞歸的一些需要記錄的內容,通常會壓入棧中,適當的時候再彈出
在函數體中,添加條件語句,判斷棧大小或者棧元素,達到條件時進行return;
I. 什麼是遞歸程序遞歸程序的優缺點是什麼
遞歸程序是指在計算機科學中是指一種通過重復將問題分解為同類的子問題而解決問題的程序。遞歸式方法可以被用於解決很多的計算機科學問題,因此它是計算機科學中十分重要的一個概念。滿足使用遞歸的條件:
子問題為同類事物,且更簡單
必須有個出口
代碼簡潔
符合思維習慣,容易理解
效率較低
遞歸層次太深,耗內存且容易棧溢出一定要使用的話,最好使用緩存避免相同的計算,限制遞歸調用的次數
優點:
缺點:
J. 「遞歸」和「迭代」有什麼區別
「遞歸」和「迭代」的區別如下:
1、遞歸的基本概念:程序調用自身的編程技巧稱為遞歸,是函數自己調用自己.一個函數在其定義中直接或間接調用自身的一種方法,它通常把一個大型的復雜的問題轉化為一個與原問題相似的規模較小的問題來解決,可以極大的減少代碼量.遞歸的能力在於用有限的語句來定義對象的無限集合。