游戲引擎學習第299天:改進排序鍵 第二部分

回顧并為當天內容做準備

我們會現場編寫完整的游戲代碼。回顧上周發現自己對游戲中正確的排序規則并沒有清晰的理解。主要原因是我們更擅長三維游戲開發,缺乏二維游戲和二維游戲技術的經驗,對于二維精靈排序、模擬三維效果的最佳方案等沒有太多技巧和經驗。

因此,今天的目標是專注于研究和理清二維游戲中的Z軸排序問題。我們希望通過深入思考,理解各種排序方案的權衡,找到在大多數情況下能夠產生最佳效果且最少依賴臨時解決辦法的規則。

黑板講解:瓦片的Z軸排序

目前我們關注的是在同一層內的排序問題,假設不同層可以單獨排序。游戲中的房間被劃分成若干離散的部分,這些部分會分別淡入顯示。在一個具體的房間內,我們重點考慮瓷磚的排序方式。

開始思考時,我們想到了如何合理地對這些瓷磚進行排序,使得視覺上符合預期效果。重點是處理好瓷磚之間在同一層中的先后關系,而不是跨層排序。這樣可以保證房間內部的圖層渲染順序正確,同時也方便整體房間在不同層之間進行排序和切換。

黑板講解:從正上方俯視時如何進行排序

我們分析了從完全正上方(100%俯視角度)觀察瓷磚時的排序規則。在這種視角下,我們可以非常清楚地知道,排序只需要根據物體的最高Z值來進行。因為瓷磚之間不會相互重疊,只會有高低關系,所以只要按照角色或精靈的最高點的Z值排序,就能得到正確的視覺效果。最高的Z點決定了哪個物體會被看到。

然而,情況變得復雜的是當攝像機稍微傾斜時。雖然在完全俯視時排序相對簡單,但傾斜后物體會跨越多個瓷磚,導致排序不再那么直接。此時,我們可能會遇到精靈覆蓋多個瓷磚的情況,不能單純地按一個Z值排序。

盡管如此,大多數情況下還是可以通過對每個瓷磚和相關物體分別排序來解決問題。比如一個跨越多個瓷磚的地毯,在Z值排序中,地毯會相對這些瓷磚進行排序,任何Z值比地毯高的瓷磚會繪制在前,反之則繪制在后。雖然這可能導致一些看似不合邏輯的畫面(比如地毯部分“穿透”瓷磚),但這是合理的渲染結果,因為如果地毯和瓷磚發生交叉,那就是模型本身的問題,而非渲染算法的問題。

總結來說,從正上方看,排序規則非常簡單,只需按最高Z點排序;而傾斜視角帶來了物體跨瓷磚的問題,但通過分別對每個瓷磚和物體排序,也能基本解決,雖然存在極少數不完美的邊緣情況。

黑板講解:相機傾斜帶來的排序復雜性

問題的復雜性出現在我們不再是純粹正上方觀察物體,而是攝像機稍微傾斜的情況下。這樣一來,單純按最高Z值排序就不能保證得到正確的繪制順序。

具體來說,雖然某個物體的最高Z值最大,按理應該最后繪制,但由于攝像機角度的變化,視線射線(viewing ray)會先遇到畫面中靠前的物體,而后遇到靠后的物體。這樣,單純依據Z值排序會導致繪制順序錯誤。

這個錯誤的原因在于,影響排序的關鍵維度不再只是Z軸,而是發生在Y軸方向上。假設攝像機是圍繞X軸旋轉的,實際上物體的距離遠近更多取決于它們在Y軸上的位置。

之前嘗試的解決思路是,既然攝像機傾斜,物體在Y軸上的位置其實反映了它們離攝像機的遠近。最靠近的物體Y值較低,最遠的Y值較高。因此,先按照Y軸從近到遠排序,再按照Z軸排序,可能就能解決這個問題。

還可以進一步擴展這個排序規則,從物體離攝像機最近到最遠,先根據Y值排序,再用Z值細化排序,這樣有望得到合理的繪制順序。之前對此考慮不足,這是現在需要補充和深入分析的地方。

黑板講解:將實體量化到瓦片上

困擾我們的是,當游戲中有連續移動的實體時,排序變得復雜和混亂。因為這些實體的位置不斷變化,很難判斷某個實體相對于另一個實體應該如何排序。

為了解決這個問題,一個可能的辦法是將實體的位置量化到它所處的瓦片(tile)中心。也就是說,在進行排序時,無論實體實際在瓦片內的哪個位置,都將其視為位于瓦片的中心點。這樣,實體始終被歸類到某個特定的瓦片列中進行排序。

在同一個瓦片列內,再按Z值升序排序,從而保證實體之間的正確繪制順序。這個想法的靈感是在觀察藝術資源時突然產生的,覺得或許可以解決連續移動實體排序難題。

關鍵點是,雖然視線會先遇到某些瓦片中的物體再遇到另一些瓦片的物體,但只要我們先將實體量化到瓦片中,然后在每個瓦片中根據Z值排序,就能較好地理清繪制順序,避免排序混亂。

這意味著,為了讓排序合理且易于管理,必須先把實體定位限制在瓦片級別,再在瓦片內進一步細化排序,這樣才有可能得到一致且正確的視覺結果。

黑板講解:地毯(Rug)問題

我們假設所有物體都被量化到瓦片大小,并且物體尺寸大致和瓦片一致,這種情況下排序應該是比較合理的。但問題在于,并不是所有物體都符合這個假設。

比如,有些物體會跨越多個瓦片,比如桌子或者地毯這樣的地面覆蓋物。特別是地毯這種東西,角色是可以站在它上面的,這樣的物體就不能簡單地被量化到單個瓦片中心去排序。

一種可能的量化方法是將這類跨瓦片的物體歸到它最前面的瓦片去排序,不管具體是哪一個瓦片,關鍵是要和它前面的瓦片在同一行進行排序,因為X軸位置在這里是相關的。但是問題是,如果這樣做,這個物體就會被繪制在后面那排瓦片的物體前面,這并不是我們想要的結果。

理想情況是,這種跨瓦片的物體應該覆蓋后面那排瓦片的物體,但同時允許站在這些瓦片上的角色顯示在它的上面,也就是仍然在視覺上覆蓋住后面的瓦片但不遮擋站在其上的角色。

這個情況就很復雜,因為一旦涉及到跨越多個瓦片的物體,排序關系就變得難以用簡單的規則表示。不能簡單地說“這一堆物體都在前面,這一堆都在后面”,因為這些跨瓦片的物體實際上是在兩個層次之間交叉,這種“交叉”的排序關系非常棘手。

我們可以嘗試設計一種特殊的排序系統來處理這類情況,但理想的做法是找到一條智能的規則,能夠合理且自動地處理這些跨越多個瓦片的物體,能夠根據它們的空間關系正確地進行排序,而不是靠特殊處理。

總之,這個跨瓦片的排序問題非常復雜,現有的簡單量化方案在這種情況下開始失效,需要更高級的思考和設計來解決。

黑板講解:畫家算法(Painter’s Algorithm)

我們想開始用更系統化的方法來考慮排序問題。想到的一種可能的思路是借鑒“畫家算法”(Painter’s Algorithm),即排序時不僅僅簡單比較Z值,而是考慮物體實際的空間形狀和它們的平面如何延展,從而決定正確的繪制順序。

具體來說,比如有一個平鋪的物體,上面站著一個豎直的物體,我們可以通過知道這兩個物體的Z坐標,以及它們所在的平面類型,來判斷哪個應該先繪制,哪個應該后繪制。比如,豎直物體的高度隨著向上延伸可能并不會變化太大,通過對平面方程的了解,我們可以更精確地進行排序。

這就回到了之前討論的“豎直物體”和“非豎直物體”的分類問題。我們甚至可以進一步推廣,給每個物體一個平面方程,根據這個方程來輔助排序。

不過,我們對這種方法是否劃算持懷疑態度,感覺這條路可能比較復雜,且代價較大。我們希望能找到一種更巧妙、更聰明的排序方式,而不是簡單粗暴地用物理平面計算來處理。

總之,這個思路在腦海中存在,但還不確定是否是最佳方案,仍需要進一步探索和嘗試。

黑板講解:地毯情況的多種場景

我們來詳細列舉一下關于地毯(rug)排序的具體情況。假設我們有四塊地板瓷磚,分別標記為A、B、C、D,然后把一塊地毯E放在它們上面,另外一個英雄角色F站在地毯上。理想的繪制順序是從后到前依次繪制這些元素。具體來說:

  • A和B的繪制順序相互之間不太重要,可以互換。
  • C和D的繪制順序同樣可以互換。
  • 但是整體排序需要保證A、B先繪制,接著是C、D,然后是地毯E,最后繪制站在上面的英雄F。

如果我們僅考慮按瓷磚分列進行排序,比如只看B這塊瓷磚,那么排序規則依然成立,可以得到正確的局部順序 B → E → F。

問題出現在C和D之間的排序。每個瓷磚內部的排序可能正確,但當試圖將所有瓷磚的排序結果合并成一個整體繪制順序時,可能出現沖突和矛盾。

舉個更復雜的例子:假設一個3D視角中,塊A豎直穿過地毯E,導致地毯和A相互穿插。地毯是平鋪的,穿插的塊A是豎直的實體,這會導致排序變得非常困難。因為:

  • 地毯E需要覆蓋在C前面,
  • 但是在某些排序中,A可能被繪制在E之前,
  • 這就產生了不可能滿足的排序沖突:E既要在C前面,又不能在A前面,這兩者之間的順序難以調和。

即使我們對每個瓷磚分別排序,整體合并時依然會遇到排序矛盾,導致無法確定一個唯一的正確繪制順序。

可能的解決方案之一是把地毯“切割”成多塊,分別排序。這雖然不一定是糟糕的主意,反而可能是合理的做法,但仍然增加了復雜性。

這也說明為什么很多2D游戲很少做復雜的3D排序。通常做法是:

  • 避免在地板上放置會導致穿插的覆蓋物(比如禁止地毯跨越高低不同的地磚),
  • 或者根本不允許地板高度發生變化,
  • 這樣只用簡單的Z排序就可以解決問題。

總的來說,單純靠Z值排序在完全頂視角下非常簡單且有效,但一旦涉及復雜的覆蓋和穿插,排序問題就變得棘手且難以優雅解決。

或許可以嘗試將Y坐標與Z坐標結合,找到一個簡化排序的辦法,但目前還沒有明確的好思路。

我們對這個問題依然持開放態度,還沒有找到一個滿意的、優雅的解決方案。

黑板講解:頂視二維與三維的比較

我們從俯視角度來看這個問題。假設有一個英雄角色站在一個略微凹陷的區域里,地形高度不一,有的地方高,有的地方低。英雄站在相對低洼的位置。單純用Z值排序,從純頂視角看,這種排序對于大多數情況是可行的,雖然可能存在一些小瑕疵,但總體上是可以接受的。

但是一旦視角稍微傾斜,視線從側面看時,原本后面的某個物體可能會遮擋前面的位置,這時候單純用Z值排序就不夠了。比如有個物體在更高的Z值處,它會正確地排在前面,遮擋后面的物體,這是符合預期的。但另一個問題是,低Z值但Y值更大的物體有可能錯誤地被排在高Z值物體前面,造成視覺上的錯亂。

這時,Y坐標的排序就變得重要。如果先按Y排序,再按Z排序,可以保證:

  • 位于不同Y位置的物體有合理的層疊關系,
  • 而站在某個位置上方的英雄,其Z值較高,始終排在覆蓋物的前面,避免被錯誤遮擋。

這種結合Y和Z排序的方式,對于局部瓷磚內的元素排序來說,是較為合理且有效的。

接下來考慮跨瓷磚的情況,比如有一張地毯或類似的覆蓋物跨越多個瓷磚。此時,為了讓跨瓷磚的覆蓋物正確顯示,地面必須相對平坦,各個瓷磚的Z值變化不大,否則無法合理疊放桌子或其他物品。

在這種較為平坦的情況下,覆蓋物(如地毯)可以疊加在地面上。但問題出現在Y排序上。因為英雄站在地毯的某個后方瓷磚上時,按Y排序,地毯可能會被錯誤地分配到其他位置,導致排序出現矛盾:英雄應該排在地毯前面,但由于Y值排序,地毯反而被排在英雄前面或錯位,造成視覺錯誤。

總結來說:

  • 純Z排序在頂視圖下大多數情況下可行,
  • 視角傾斜時,結合Y和Z排序能更合理處理遮擋關系,
  • 但跨瓷磚覆蓋物導致的排序問題比較復雜,Y排序可能帶來沖突,
  • 要求地面高度平坦才能較好處理跨瓷磚覆蓋物的排序,
  • 依然存在英雄和覆蓋物排序矛盾的問題,排序邏輯難以完全簡單化。

整體來看,Y和Z的結合排序是當前較合理的解決方案,但仍有細節和特殊情況需要特別處理。

黑板講解:使用平面數學方法

我們思考用平面排序的方法來處理復雜的排序問題。假設我們為每個物體定義一個平面方程,通過平面數學來判斷兩個物體在它們重疊的點上哪個應該排在前面。

這種思路在某種程度上是合理的:在它們相交的位置,我們可以判斷哪個物體應該覆蓋另一個,從而確定正確的繪制順序。但困難在于,如果有多個物體分布在不同的位置,涉及的平面交叉會非常復雜。我們不僅要判斷排序順序,還可能需要裁剪物體的一部分來避免繪制錯誤。

例如,有時候我們希望某個瓷磚先繪制,但基于平面排序卻顯示另一個瓷磚應該先繪制,這會導致視覺上的干擾,物體“穿插”在不該穿插的位置。這種情況讓平面排序的方案顯得不夠可靠。

因此,雖然理論上可以用平面排序并寫出相應的規則,但在實際應用中,問題非常棘手。為了完全解決這類復雜的排序關系,可能必須真正地用3D模型表示所有物體,從3D視角來處理遮擋和排序。

如果不走3D的路,我們可能就必須放棄那些跨瓷磚鋪設的覆蓋物(比如地毯),要求所有東西嚴格按照瓷磚邊界擺放,不允許跨越多個瓷磚。這無疑會限制設計的靈活性,令制作更大或跨多瓷磚的家具(例如沙發)變得困難。

總體來看,雖然平面排序方案有其邏輯基礎,但它帶來的復雜裁剪和不確定排序問題,讓我們難以找到理想的解決方法。可能唯一的辦法就是承認無法完全解決跨瓷磚復雜排序問題,要么限制設計,要么采用3D系統處理。

黑板講解:將問題視為三維問題

我們把問題看作一個真正的三維排序問題。假設有兩個瓷磚,每個瓷磚有中心點,從上方俯視它們。地毯疊加在瓷磚上面,英雄人物站在一邊,每個對象都有它們的最高點。我們關注這些對象在視線方向上的投影位置和對應的Z值。

關鍵難點在于:不同選取物體上的點會導致排序結果不同。比如選取地毯的一個點,可能排在英雄前面;選另一個點,則可能在英雄后面。也就是說,排序依賴于選取的參考點,導致排序結果不穩定。而通常在渲染時,我們是基于每個像素的深度進行排序,因此不會遇到選擇單點的問題。

為了解決這個問題,可以考慮物體的最低點和最高點(即物體在視線方向上的范圍,稱為投影范圍),用物體的投影范圍來判斷排序。具體來說,觀察兩個物體在視線方向上的投影區間,可以歸納出幾種情況:

  1. 不相交(投影區間不重疊)
    如果物體A的所有點都在物體B之前,那么A總是應該先繪制,B后繪制。這種情況排序非常明確。

  2. 部分重疊
    兩個物體的投影區間有部分交叉,這種情況比較模糊,不容易判定誰先繪制。比如地毯和站在上面的英雄之間的關系,這時候存在一定的排序歧義。

  3. 完全包含
    一個物體的投影范圍完全包含另一個物體。此時也比較難判斷,排序會更加復雜。

舉例來說,假設英雄站在地毯上,投影范圍部分重疊,理論上英雄應該覆蓋地毯被繪制在后面。但如果英雄向后移動,投影關系可能反轉,導致排序出現問題。換句話說,單靠投影區間無法準確、穩定地判斷正確繪制順序。

總結來看,這種基于投影范圍的排序方法雖然能在部分情況有效區分物體遮擋關系,但面對物體交疊或動態移動,依然存在明顯的歧義和排序沖突,沒有簡單、通用的解決方案。除非采用更精細的每像素深度排序或者直接用三維渲染技術,否則難以解決復雜場景下的排序難題。

黑板講解:平面實體與豎直實體的區別

我們考慮將場景中的物體分為兩類:平面的和豎立的。針對這兩種類型,排序問題可能會有所不同。對于豎立的物體和鋪在地面上的平面物體,可以通過觀察它們投影交匯處的高度(Z值范圍)來判斷哪個應該在前面繪制。也就是說,判斷兩者重疊時哪個在上方,依據它們在交匯點處的高度來確定繪制順序。

這其實歸結為:豎立的物體主要根據它們的Z值進行排序,而平面物體主要根據Y值進行排序。這樣的劃分和排序邏輯可以幫助解決兩類物體混合時的遮擋問題。

但實際上,除了這種豎立和平面的區別之外,我們還是會遇到更復雜的情況,尤其是那些跨越多個格子的物體。對于單個格子里的物體,只要先按照Y排序格子,再在格子內部根據Z排序物體,排序問題大部分都能得到合理解決。

真正的難點還是跨格子的物體,它們會跨越多個格子,導致簡單的Y+Z排序無法完美解決。針對這種情況,可以考慮限制跨格子的物體只能跨越固定大小的格子,但這種做法在實際應用中可能會顯得比較笨拙、不夠靈活,也不一定好實現。

綜上,除了跨格子物體的情況之外,采用先按Y排序格子,再按Z排序格子內部物體的方式,配合豎立物體以Z為主,平面物體以Y為主的排序策略,整體排序問題基本可以得到有效處理。其他情況的排序難題較少,當前看來并沒有更理想的排序算法。

黑板講解:單個格子內Y軸排序的問題

在單個格子(cell)內部,我們仍然面臨Y軸排序的問題。即使物體都在同一個格子里,我們也需要根據它們在Y方向上的位置來決定繪制順序,比如從上方俯視圖來看,Y值較小的物體應當先繪制,Y值較大的物體后繪制,這樣視覺上才不會出現遮擋錯誤。

對于完全平面的物體,可以采用一種偏置的方法,比如將它們的排序點設在物體末端,從而在單格子內部實現合理的排序。這種偏置能幫助平面物體在Y排序中表現正確,避免被誤判遮擋順序。

不過,問題更復雜的是那些能在格子內自由移動的物體,比如飛行中的投射物(子彈、飛箭等)。由于通常一個格子內不會同時存在兩個站立的角色,格子內的豎立物體不會堆疊,但這些小的浮動物體卻會帶來排序難題。它們的位置在Y軸上隨時變化,排序不易準確處理。

最初提出的“豎立卡片(upright cards)”和“非豎立卡片”的分類,正是為了應對這種復雜的排序需求。豎立物體和非豎立物體需要采用不同的排序策略,但這仍然沒有完全解決所有問題。

目前來看,純粹靠二維排序難以完美解決這個問題。雖然考慮使用深度緩沖區(z-buffer)進行三維渲染可以避免排序問題,但這會帶來額外的復雜性和資源浪費,尤其是在帶寬和計算上,因為二維場景通常不需要完整的3D光柵化處理。

傳統方法里,這類排序通常是手動固定好的,比如預先設定好物體的高度和遮擋關系,類似地毯這種東西直接“烘焙”到貼圖里,不需要實時排序,簡化了流程。

總結來說,單格子內的排序問題依然存在,尤其是動態移動的物體和完全平面的物體混合時的排序仍然棘手。傳統2D排序方式有限,三維渲染能解決問題但代價大。手動預設物體層級和高度依然是業界常用的折中方案。

黑板講解:傾斜相機俯視站在地毯上的角色的排序問題

我們從上方視角看一個場景,有一張地毯和一個英雄角色。如果使用z-buffer進行排序,英雄會顯示在地毯前面,因為他們在三維空間中其實是無限薄的平面。在用3D卡片模擬時,這些平面會被正交投影到一個平面上。

在這種情況下,會把這些對象投影到某個軸線上,比如x軸或者y軸,然后觀察它們投影的范圍。英雄和地毯的投影區域會有重疊部分,正是這個重疊區域決定了它們的排序關系。

關鍵點是,我們只關心它們在屏幕上的重疊部分,也就是它們投影在同一條軸線上重合的區域。只要知道它們在屏幕上出現的具體位置,就能判斷哪個應該繪制在前面。

所以,可以嘗試用類似畫家算法(painter’s algorithm)的思路,找到它們在某個軸上的投影范圍重疊處,來確定排序關系。具體操作是將物體的范圍投影到x軸或y軸,然后找出它們的交集區間,在這個區間內比較深度信息,從而決定繪制順序。

這個方法的核心是,將三維排序問題簡化成投影軸上的區間重疊比較,利用物體在屏幕上的投影位置來解決遮擋和排序問題。

黑板講解:使用實體共有的最近點來確定排序

我們從視角出發,定義視圖的Z軸和Y軸,區別于世界坐標的Z軸和Y軸,關注的是相對于觀察者的坐標。考慮一個場景,有地毯和人物,我們用二維卡片表示它們,分別在Y軸上有各自的最小值和最大值,也就是它們在Y軸上的范圍。

首先,我們知道這些精靈在Y軸上的位置范圍。如果兩個對象在Y軸上的范圍有重疊,那么它們之間就存在排序的必要。如果不重疊,從理論上講,它們的繪制順序可以不影響最終效果,因為沒有交集,不存在遮擋問題。但是,這里也存在潛在的問題:

如果兩個對象在Y軸上不重疊,我們隨意決定繪制順序,可能會影響另一個同時與這兩個對象有交集的第三個對象的繪制順序。因為這個第三個對象需要依賴正確的排序順序來決定自己該繪制在誰前面或后面,如果我們排序順序錯誤,第三個對象的遮擋關系就會出錯。

為了解決這個問題,我們提出了一個思路:找出兩個對象在Y軸上“最近的共同點”,也就是說,要么是它們重疊的區域,要么是它們范圍最接近的兩個端點之間的點。在這個共同點處比較它們在Z軸上的深度值,深度小的先繪制,深度大的后繪制,從而確定繪制順序。

進一步思考,這個過程實際上可以看作一種空間劃分。每個精靈對應一個平面,我們可以通過判斷實體相對于這些平面的位置,來確定誰離觀察者更近。具體來說,如果一個實體位于某個平面的觀察者一側,那么它應該比位于另一側的實體更靠近觀察者,因而優先繪制。

唯一復雜的情況是實體“穿插”了平面,即部分實體位于平面一側,部分位于另一側,這種情況下很難確定繪制順序,甚至無法保證繪制正確。這屬于特殊情況,需要額外處理或拆分對象。

總的來說,這種排序規則基于每個精靈都有對應的平面方程,且平面的法線方向是固定的(例如世界坐標中的Z軸或Y軸),所以計算相對位置比較簡單且高效。對于較厚的對象,雖然理論上可能需要多個平面來描述,但實際中可以用單一平面近似,效果應該也足夠好。

這種方法的優點是:

  • 每個精靈只需知道自己的邊界和對應的平面;
  • 利用簡單的幾何關系判斷相對深度和繪制順序;
  • 對大部分情況有效,只需特別處理穿插情況。

總之,通過視圖坐標下的平面位置關系判斷排序,是一種較為穩妥且易于實現的繪制順序解決方案。

問答環節

如果只關注跨越多個格子的精靈,為什么不在格子邊界處分割多邊形?應該不多,也不太耗性能吧?

針對存在于多個格子(cell)中的精靈,有一種想法是將這些精靈的多邊形沿著格子邊界進行切分。理論上,這樣做不會產生太多的多邊形,計算開銷也不一定很大。但是問題不完全在于計算成本,更重要的是這些精靈實際上并不是普通的多邊形,而是“直立的假卡片”(upright fake cards)。這種情況下,切分操作不僅是幾何上的拆分,還涉及到基于二維原始圖形的切割和重組。

雖然從技術上講,切割并分別排序是可行的,但即使這樣做了,在單個格子內部仍然需要對切割后的部分進行排序。這意味著切分只是解決了跨格子排序的問題,但格子內的排序問題依然存在。

因此,雖然切割精靈以適應格子邊界看似一種可行方案,但并沒有徹底解決所有排序上的難題。內部排序依然需要處理,整體流程并沒有因此變得簡單。

總結來看,切割方法可能會增加處理流程的復雜度,而不是顯著降低問題的復雜度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906341.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906341.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906341.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis從入門到實戰 - 高級篇(中)

一、多級緩存 1. 傳統緩存的問題 傳統的緩存策略一般是請求到達Tomcat后,先查詢Redis,如果未命中則查詢數據庫,存在下面的問題: 請求要經過Tomcat處理,Tomcat的性能成為整個系統的瓶頸Redis緩存失效時,會…

Python訓練營打卡 Day31

文件的規范拆分和寫法 今日的示例代碼包含2個部分 notebook文件夾內的ipynb文件,介紹下今天的思路項目文件夾中其他部分:拆分后的信貸項目,學習下如何拆分的,未來你看到的很多大項目都是類似的拆分方法 知識點回顧:文件…

2025年護網行動藍隊防御全解析:構建智能動態防御體系

2025年,隨著網絡攻擊手段的智能化、混合化升級,護網行動中的藍隊防御已從傳統的被動防護轉向“動態感知、智能研判、主動反制”的立體化模式。如何在攻防不對稱的對抗中實現“看得見、防得住、溯得清”?本文將結合前沿技術與實戰經驗&#xf…

React Contxt詳解

React Contxt詳解 React 的 Context API 是用于跨組件層級傳遞數據的解決方案,尤其適合解決「prop drilling」(多層組件手動傳遞 props)的問題。以下是關于 Context 的詳細解析: 文章目錄 React Contxt詳解一、Context 核心概念二…

使用 lock4j-redis-template-spring-boot-starter 實現 Redis 分布式鎖

在分布式系統中,多個服務實例可能同時訪問和修改共享資源,從而導致數據不一致的問題。為了解決這個問題,分布式鎖成為了關鍵技術之一。本文將介紹如何使用 lock4j-redis-template-spring-boot-starter 來實現 Redis 分布式鎖,從而…

Vue響應式系統演進與實現解析

一、Vue 2 響應式實現詳解 1. 核心代碼實現 // 依賴收集器(觀察者模式) class Dep {constructor() {this.subscribers new Set();}depend() {if (activeEffect) {this.subscribers.add(activeEffect);}}notify() {this.subscribers.forEach(effect &g…

Mujoco 學習系列(一)安裝與部署

這個系列文章用來記錄 Google DeepMind 發布的 Mujoco 仿真平臺的使用過程,Mujoco 是具身智能領域中非常知名的仿真平臺,以簡單易用的API和精準的物理引擎而著稱(PS:原來Google能寫好API文檔啊),也是我平時…

Ai學習之openai api

一、什么是openai api 大家對特斯拉的馬斯克應該是不陌生的,openai 就是馬斯克投資的一家研究人工智能的公司,它就致力于推動人工智能技術的發展,目標是確保人工智能對人類有益,并實現安全且通用的人工智能。 此后,O…

leetcode 合并區間 java

用 ArrayList<int[]> merged new ArrayList<>();來定義數組的list將數組進行排序 Arrays.sort(intervals,(a,b) -> Integer.compare(a[0],b[0]));如果前面的末尾>后面的初始&#xff0c;那么新的currentInterval的末尾這兩個數組末尾的最大值&#xff0c;即…

std::vector<>.emplace_back

emplace_back() 詳解&#xff1a;C 就地構造的效率革命 emplace_back() 是 C11 引入的容器成員函數&#xff0c;用于在容器尾部就地構造&#xff08;而非拷貝或移動&#xff09;元素。這一特性顯著提升了復雜對象的插入效率&#xff0c;尤其適用于構造代價較高的類型。 一、核…

Dify實戰案例《AI面試官》更新,支持語音交互+智能知識庫+隨機題庫+敏感詞過濾等...

大模型應用課又更新了&#xff0c;除了之前已經完結的兩門課&#xff08;視頻圖文&#xff09;&#xff1a; 《Spring AI 從入門到精通》《LangChain4j 從入門到精通》 還有目前正在更新的 《Dify 從入門到實戰》 本周也迎來了一大波內容更新&#xff0c;其中就包括今天要介紹…

AGI大模型(29):LangChain Model模型

1 LangChain支持的模型有三大類 大語言模型(LLM) ,也叫Text Model,這些模型將文本字符串作為輸入,并返回文本字符串作為輸出。聊天模型(Chat Model),主要代表Open AI的ChatGPT系列模型。這些模型通常由語言模型支持,但它們的API更加結構化。具體來說,這些模型將聊天消…

動態IP技術在跨境電商中的創新應用與戰略價值解析

在全球化4.0時代&#xff0c;跨境電商正經歷從"流量紅利"向"技術紅利"的深度轉型。動態IP技術作為網絡基礎設施的關鍵組件&#xff0c;正在重塑跨境貿易的運營邏輯。本文將從技術架構、應用場景、創新實踐三個維度&#xff0c;揭示動態IP如何成為跨境電商突…

android雙屏之副屏待機顯示圖片

摘要&#xff1a;android原生有雙屏的機制&#xff0c;但需要芯片廠商適配框架后在底層實現。本文在基于芯發8766已實現底層適配的基礎上&#xff0c;僅針對上層Launcher部分對系統進行改造&#xff0c;從而實現在開機后副屏顯示一張待機圖片。 副屏布局 由于僅顯示一張圖片&…

STM32之中斷

一、提高程序實時性的架構方案 輪詢式 指的是在程序運行時&#xff0c;首先對所有的硬件進行初始化&#xff0c;然后在主程序中寫一個死循環&#xff0c;需要運行的功能按照順序進行執行&#xff0c;輪詢系統是一種簡單可靠的方式&#xff0c;一般適用于在只需要按照順序執行…

LLM應用開發平臺資料

課程和代碼資料 放下面了&#xff0c;自取&#xff1a; https://pan.quark.cn/s/57a9d22d61e9

硬盤健康檢測與性能測試的實踐指南

在日常使用 Windows 系統的過程中&#xff0c;我們常常需要借助各種工具來優化性能、排查問題或管理文件。針對windows工具箱進行實測解析&#xff0c;發現它整合了多種實用功能&#xff0c;能夠幫助用戶更高效地管理計算機。 以下為測試發現的功能特性&#xff1a; 硬件信息查…

正則表達式進階(三):遞歸模式與條件匹配的藝術

在正則表達式的高級應用中&#xff0c;遞歸模式和條件匹配是處理復雜嵌套結構和動態模式的利器。它們突破了傳統正則表達式的線性匹配局限&#xff0c;能夠應對嵌套括號、HTML標簽、上下文依賴等復雜場景。本文將詳細介紹遞歸模式&#xff08;(?>...)、 (?R) 等&#xff0…

從零開始創建React項目及制作頁面

一、React 介紹 React 是一個由 Meta&#xff08;原Facebook&#xff09; 開發和維護的 開源JavaScript庫&#xff0c;主要用于構建用戶界面&#xff08;User Interface, UI&#xff09;。它是前端開發中最流行的工具之一&#xff0c;廣泛應用于單頁應用程序&#xff08;SPA&a…

【前端部署】通過 Nginx 讓局域網用戶訪問你的純前端應用

在日常前端開發中&#xff0c;我們常常需要快速將本地的應用展示給局域網內的同事或測試人員&#xff0c;而傳統的共享方式往往效率不高。本文將指導你輕松地將你的純前端應用&#xff08;無論是 Vue, React, Angular 或原生項目&#xff09;部署到本地&#xff0c;并配置局域網…