主頁 > 軟體設計 > 【死磕JVM】這可能是最全的JVM面試題了

【死磕JVM】這可能是最全的JVM面試題了

2021-04-27 18:25:50 軟體設計

1. 描述一下jvm記憶體模型,以及這些空間的存放的內容 ?

1. 描述一下jvm記憶體模型,以及這些空間的存放的內容 ?

2.堆記憶體劃分的空間,如何回收這些記憶體物件,有哪些回收演算法?

在這里插入圖片描述
垃圾回收演算法: 標記清除、復制(多為新生代垃圾回收使用)、標記整理

3.如何解決線上gc頻繁的問題?

  1. 查看監控,以了解出現問題的時間點以及當前FGC的頻率(可對比正常情況看頻率是否正常)

  2. 了解該時間點之前有沒有程式上線、基礎組件升級等情況,

  3. 了解JVM的引數設定,包括:堆空間各個區域的大小設定,新生代和老年代分別采用了哪些垃 圾收集器,然后分析JVM引數設定是否合理,

  4. 再對步驟1中列出的可能原因做排除法,其中元空間被打滿、記憶體泄漏、代碼顯式呼叫gc方法 比較容易排查,

  5. 針對大物件或者長生命周期物件導致的FGC,可通過 jmap -histo 命令并結合dump堆記憶體檔案作進一步分析,需要先定位到可疑物件,

  6. 通過可疑物件定位到具體代碼再次分析,這時候要結合GC原理和JVM引數設定,弄清楚可疑 物件是否滿足了進入到老年代的條件才能下結論,

4.描述一下class初始化程序?

一個類初始化就是執行clinit()方法,程序如下:

  • 父類初始化
  • static變數初始化/static塊(按照文本順序執行)

Java Language Specification中,類初始化詳細程序如下(最重要的是類初始化是執行緒安全的):

  1. 每個類都有一個初始化鎖LC,行程獲取LC(如果沒有獲取到,就一直等待)

  2. 如果C正在被其他執行緒初始化,釋放LC并等待C初始化完成

  3. 如果C正在被本執行緒初始化,即遞回初始化,釋放LC

  4. 如果C已經被初始化了,釋放LC

  5. 如果C處于erroneous狀態,釋放LC并拋出例外NoClassDefFoundError

  6. 否則,將C標記為正在被本執行緒初始化,釋放LC;然后, 初始化那些final且為基礎型別的類成員變數

  7. 初始化C的父類SC和各個介面SI_n(按照implements子句中的順序來) ;如果SC或SIn初始化程序中拋出例外,則獲取LC,將C標記為erroneous,并通知所有執行緒,然后釋放LC,然后 再拋出同樣的例外,

  8. 從classloader處獲取assertion是否被打開

  9. 接下來, 按照文本順序執行類變數初始化和靜態代碼塊,或介面的欄位初始化,把它們當作是一個個單獨的代碼塊,

  10. 如果執行正常,獲取LC,標記C為已初始化,并通知所有執行緒,然后釋放LC

  11. 否則,如果拋出了例外E,若E不是Error,則以E為引數創建新的例外ExceptionInInitializerError作為E,如果因為OutOfMemoryError導致無法創建ExceptionInInitializerError,則將OutOfMemoryError作為E,

  12. 獲取LC,將C標記為erroneous,通知所有等待的執行緒,釋放LC,并拋出例外E

5.簡述一下記憶體溢位的原因,如何排查線上問題?

記憶體溢位的原因

  • java.lang.OutOfMemoryError: …java heap space. 堆疊溢位,代碼問題的可能性極大

  • java.lang.OutOfMemoryError: GC over head limit exceeded 系統處于高頻的GC狀態,而且回收的效果依然不佳的情況,就會開始報這個錯誤,這種情況一般是產生了很多不可以被釋放 的物件,有可能是參考使用不當導致,或申請大物件導致,但是java heap space的記憶體溢位有可能提前不會報這個錯誤,也就是可能記憶體就直接不夠導致,而不是高頻GC.

  • java.lang.OutOfMemoryError: PermGen space jdk1.7之前才會出現的問題 ,原因是系統的代碼非常多或參考的第三方包非常多、或代碼中使用了大量的常量、或通過intern注入常量、 或者通過動態代碼加載等方法,導致常量池的膨脹

  • java.lang.OutOfMemoryError: Direct buffer memory 直接記憶體不足,因為jvm垃圾回收不會回收掉直接記憶體這部分的記憶體,所以可能原因是直接或間接使用了ByteBuffer中的allocateDirect方法的時候,而沒有做clear

  • java.lang.StackOverflowError - Xss設定的太小了

  • java.lang.OutOfMemoryError: unable to create new native thread 堆外記憶體不足,無法為執行緒分配記憶體區域

  • java.lang.OutOfMemoryError: request {} byte for {}out of swap 地址空間不夠

6.jvm有哪些垃圾回收器,實際中如何選擇?

在這里插入圖片描述
圖中展示了7種作用于不同分代的收集器,如果兩個收集器之間存在連線,則說明它們可以搭配使用,虛 擬機所處的區域則表示它是屬于新生代還是老年代收集器,

新生代收集器(全部的都是復制演算法):Serial、ParNew、Parallel Scavenge

老年代收集器:CMS(標記-清理)、Serial Old(標記-整理)、Parallel Old(標記整理) 整堆收集器: G1(一個Region中是標記-清除演算法,2個Region之間是復制演算法)

同時,先解釋幾個名詞:

  1. 并行(Parallel):多個垃圾收集執行緒并行作業,此時用戶執行緒處于等待狀態
  2. 并發(Concurrent):用戶執行緒和垃圾收集執行緒同時執行
  3. 吞吐量:運行用戶代碼時間/(運行用戶代碼時間+垃圾回收時間)

1.Serial收集器是最基本的、發展歷史最悠久的收集器,

特點: 單執行緒、簡單高效(與其他收集器的單執行緒相比),對于限定單個CPU的環境來說,Serial收集器 由于沒有執行緒互動的開銷,專心做垃圾收集自然可以獲得最高的單執行緒手機效率,收集器進行垃圾回收 時,必須暫停其他所有的作業執行緒,直到它結束(Stop The World),

應用場景: 適用于Client模式下的虛擬機,

Serial / Serial Old收集器運行示意圖:
在這里插入圖片描述
2.ParNew收集器其實就是Serial收集器的多執行緒版本,

除了使用多執行緒外其余行為均和Serial收集器一模一樣(引數控制、收集演算法、Stop The World、物件分配規則、回收策略等),

特點: 多執行緒、ParNew收集器默認開啟的收集執行緒數與CPU的數量相同,在CPU非常多的環境中,可以 使用-XX:ParallelGCThreads引數來限制垃圾收集的執行緒數,

和Serial收集器一樣存在Stop The World問題

應用場景: ParNew收集器是許多運行在Server模式下的虛擬機中首選的新生代收集器,因為它是除了
Serial收集器外,唯一一個能與CMS收集器配合作業的,

ParNew/Serial Old組合收集器運行示意圖如下:

在這里插入圖片描述
3.Parallel Scavenge 收集器與吞吐量關系密切,故也稱為吞吐量優先收集器,

特點: 屬于新生代收集器也是采用復制演算法的收集器,又是并行的多執行緒收集器(與ParNew收集器類 似),
該收集器的目標是達到一個可控制的吞吐量,還有一個值得關注的點是:GC自適應調節策略(與
ParNew收集器最重要的一個區別)

GC自適應調節策略: Parallel Scavenge收集器可設定-XX:+UseAdptiveSizePolicy引數,當開關打開時不需要手動指定新生代的大小(-Xmn)、Eden與Survivor區的比例(-XX:SurvivorRation)、晉升老年代 的物件年齡(-XX:PretenureSizeThreshold)等,虛擬機會根據系統的運行狀況收集性能監控資訊,動 態設定這些引數以提供最優的停頓時間和最高的吞吐量,這種調節方式稱為GC的自適應調節策略,

Parallel Scavenge收集器使用兩個引數控制吞吐量:
XX:MaxGCPauseMillis 控制最大的垃圾收集停頓時間
XX:GCRatio 直接設定吞吐量的大小,

4.Serial Old是Serial收集器的老年代版本,

特點: 同樣是單執行緒收集器,采用標記-整理演算法,
應用場景: 主要也是使用在Client模式下的虛擬機中,也可在Server模式下使用,
Server模式下主要的兩大用途(在后續中詳細講解···):

  1. 在JDK1.5以及以前的版本中與Parallel Scavenge收集器搭配使用,
  2. 作為CMS收集器的后備方案,在并發收集Concurent Mode Failure時使用,

Serial / Serial Old收集器作業程序圖(Serial收集器圖示相同):

在這里插入圖片描述
5.Parallel Old是Parallel Scavenge收集器的老年代版本,

特點: 多執行緒,采用標記-整理演算法,
應用場景: 注重高吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge+Parallel Old 收集器,

6.CMS收集器是一種以獲取最短回收停頓時間為目標的收集器,

特點: 基于標記-清除演算法實作,并發收集、低停頓,

應用場景: 適用于注重服務的回應速度,希望系統停頓時間最短,給用戶帶來更好的體驗等場景下,如web程式、b/s服務,

CMS收集器的運行程序分為下列4步:

初始標記: 標記GC Roots能直接到的物件,速度很快但是仍存在Stop The World問題,
并發標記: 進行GC Roots Tracing 的程序,找出存活物件且用戶執行緒可并發執行,
重新標記: 為了修正并發標記期間因用戶程式繼續運行而導致標記產生變動的那一部分物件的標記記 錄,仍然存在Stop The World問題,
并發清除: 對標記的物件進行清除回收,
CMS收集器的記憶體回收程序是與用戶執行緒一起并發執行的,

CMS收集器的作業程序圖:
在這里插入圖片描述
CMS收集器的缺點:

  • 對CPU資源非常敏感,
  • 無法處理浮動垃圾,可能出現Concurrent Model Failure失敗而導致另一次Full GC的產生,
  • 因為采用標記-清除演算法所以會存在空間碎片的問題,導致大物件無法分配空間,不得不提前觸發
    一次Full GC,

在這里插入圖片描述
7.G1收集器一款面向服務端應用的垃圾收集器,

特點如下:

并行與并發:G1能充分利用多CPU、多核環境下的硬體優勢,使用多個CPU來縮短Stop-The-World停頓時間,部分收集器原本需要停頓Java執行緒來執行GC動作,G1收集器仍然可以通過并發的方式讓Java程式繼續運行,

分代收集:G1能夠獨自管理整個Java堆,并且采用不同的方式去處理新創建的物件和已經存活了一段時間、熬過多次GC的舊物件以獲取更好的收集效果,

空間整合:G1運作期間不會產生空間碎片,收集后能提供規整的可用記憶體,

可預測的停頓:G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間段內,消耗在垃圾收集上的時間不得超過N毫秒,

G1收集器運行示意圖:

在這里插入圖片描述
關于gc的選擇
除非應用程式有非常嚴格的暫停時間要求,否則請先運行應用程式并允許VM選擇收集器(如果沒有特別要求,使用VM提供給的默認GC就好),

如有必要,調整堆大小以提高性能, 如果性能仍然不能滿足目標,請使用以下準則作為選擇收集器的起點:

  • 如果應用程式的資料集較小(最大約100 MB),則選擇帶有選項-XX:+ UseSerialGC的串行收集器,
  • 如果應用程式將在單個處理器上運行,并且沒有暫停時間要求,則選擇帶有選項-XX:+UseSerialGC的串行收集器
  • 如果(a)峰值應用程式性能是第一要務,并且(b)沒有暫停時間要求或可接受一秒或更長時間的暫停,則讓VM選擇收集器或使用-XX:+ UseParallelGC選擇并行收集器 ,
  • 如果回應時間比整體吞吐量更重要,并且垃圾收集暫停時間必須保持在大約一秒鐘以內,則選擇具有-XX:+ UseG1GC,(值得注意的是JDK9中CMS已經被Deprecated,不可使用!移除該選項)
  • 如果使用的是jdk8,并且堆記憶體達到了16G,那么推薦使用G1收集器,來控制每次垃圾收集的時間,
  • 如果回應時間是高優先級,或使用的堆非常大,請使用-XX:UseZGC選擇完全并發的收集器,(值得注意的是JDK11開始可以啟動ZGC,但是此時ZGC具有實驗性質,在JDK15中
  • [202009發布]才取消實驗性質的標簽,可以直接顯示啟用,但是JDK15默認GC仍然是G1)

這些準則僅提供選擇收集器的起點,因為性能取決于堆的大小,應用程式維護的實時資料量以及可用處理器的數量和速度,
如果推薦的收集器沒有達到所需的性能,則首先嘗試調整堆和新生代大小以達到所需的目標, 如果性能仍然不足,嘗試使用其他收集器
總體原則:減少STOP THE WORD時間,使用并發收集器(比如CMS+ParNew,G1)來減少暫停時間,加快回應時間,并使用并行收集器來增加多處理器硬體上的總體吞吐量,

7. 簡述一下Java類加載模型?

在這里插入圖片描述
雙親委派模型
在某個類加載器加載class檔案時,它首先委托父加載器去加載這個類,依次傳遞到頂層類加載器(Bootstrap),如果頂層加載不了(它的搜索范圍中找不到此類),子加載器才會嘗試加載這個類,雙親委派的好處

  • 每一個類都只會被加載一次,避免了重復加載
  • 每一個類都會被盡可能的加載(從引導類加載器往下,每個加載器都可能會根據優先次序嘗試加載它)
  • 有效避免了某些惡意類的加載(比如自定義了Java.lang.Object類,一般而言在雙親委派模型下會加載系統的Object類而不是自定義的Object類)

9. JVM8為什么要增加元空間,帶來什么好處?

原因:

  1. 字串存在永久代中,容易出現性能問題和記憶體溢位,
  2. 類及方法的資訊等比較難確定其大小,因此對于永久代的大小指定比較困難,太小容易出現永久代溢
    出,太大則容易導致老年代溢位,
  3. 永久代會為 GC 帶來不必要的復雜度,并且回收效率偏低,

元空間的特點:

  1. 每個加載器有專門的存盤空間,
  2. 不會單獨回收某個類,
  3. 元空間里的物件的位置是固定的,
  4. 如果發現某個加載器不再存貨了,會把相關的空間整個回收,

10. 堆G1垃圾收集器有了解么,有什么特點

G1的特點:

  1. G1的設計原則是"首先收集盡可能多的垃圾(Garbage First)",因此,G1并不會等記憶體耗盡(串行、并行)或者快耗盡(CMS)的時候開始垃圾收集,而是在內部采用了啟發式演算法,在老年代找出具有高收集收益的磁區進行收集,同時G1可以根據用戶設定的暫停時間目標自動調整年輕代和總堆大小,暫停目標越短年輕代空間越小、總空間就越大;
  2. G1采用記憶體磁區(Region)的思路,將記憶體劃分為一個個相等大小的記憶體磁區,回收時則以磁區為單位進行回收,存活的物件復制到另一個空閑磁區中,由于都是以相等大小的磁區為單位進行操作,因此G1天然就是一種壓縮方案(區域壓縮);
  3. G1雖然也是分代收集器,但整個記憶體磁區不存在物理上的年輕代與老年代的區別,也不需要完全獨立的survivor(to space)堆做復制準備,G1只有邏輯上的分代概念,或者說每個磁區都可能隨G1的運行在不同代之間前后切換;
  4. G1的收集都是STW的,但年輕代和老年代的收集界限比較模糊,采用了混合(mixed)收集的方式,即每次收集既可能只收集年輕代磁區(年輕代收集),也可能在收集年輕代的同時,包含部分老年代磁區(混合收集),這樣即使堆記憶體很大時,也可以限制收集范圍,從而降低停頓,
  5. 因為G1建立可預測的停頓時間模型,所以每一次的垃圾回收時間都可控,那么對于大堆(16G左右)的垃圾收集會有明顯優勢

11. 介紹一下垃圾回收演算法?

標記-清除

在這里插入圖片描述
缺點: 產生記憶體碎片,如上圖,如果清理了兩個1kb的物件,再添加一個2kb的物件,無法放入這兩個位置

標記-整理(老年代)

在這里插入圖片描述
缺點:移動物件開銷較大

復制(新生代)

在這里插入圖片描述

12. Happens-Before規則?

先行發生原則(Happens-Before)是判斷資料是否存在競爭、執行緒是否安全的主要依據,
先行發生是Java記憶體,模型中定義的兩項操作之間的偏序關系,如果操作A先行發生于操作B,那么操作A產生的影響能夠被操作B觀察到,

口訣:如果兩個操作之間具有happen-before關系,那么前一個操作的結果就會對后面的一個操作可見,是Java記憶體模型中定義的兩個操作之間的偏序關系,

常見的happen-before規則:
1.程式順序規則:
一個執行緒中的每個操作,happen-before在該執行緒中的任意后續操作,(注解:如果只有一個執行緒的操作,那么前一個操作的結果肯定會對后續的操作可見,)
程式順序規則中所說的每個操作happen-before于該執行緒中的任意后續操作并不是說前一個操作必須要在后一個操作之前執行,而是指前一個操作的執行結果必須對后一個操作可見,如果不滿足這個要求那就不允許這兩個操作進行重排序
2.鎖規則:
對一個鎖的解鎖,happen-before在隨后對這個鎖加鎖,(注解:這個最常見的就是synchronized方法和syncronized塊)
3.volatile變數規則:
對一個volatile域的寫,happen-before在任意后續對這個volatile域的讀,該規則在CurrentHashMap的讀操作中不需要加鎖有很好的體現,
4.傳遞性:
如果A happen-before B,且B happen-before C,那么A happen - before C.
5.執行緒啟動規則
Thread物件的start()方法happen-before此執行緒的每一個動作,
6.執行緒終止規則:
執行緒的所有操作都happen-before對此執行緒的終止檢測,可以通過Thread.join()方法結束,Thread.isAlive()的回傳值等手段檢測到執行緒已經終止執行,
7.執行緒中斷規則:
對執行緒interrupt()方法的呼叫happen-before發生于被中斷執行緒的代碼檢測到中斷時事件的發生,

13. 描述一下java類加載和初始化的程序?

JAVA類的加載機制
Java類加載分為5個程序,分別為:加載,鏈接(驗證,準備,決議),初始化,使用,卸載,

加載
加載主要是將.class檔案通過二進制位元組流讀入到JVM中, 在加載階段,JVM需要完成3件事:
1)通過classloader在classpath中獲取XXX.class檔案,將其以二進制流的形式讀入記憶體,
2)將位元組流所代表的靜態存盤結構轉化為方法區的運行時資料結構;
3)在記憶體中生成一個該類的java.lang.Class物件,作為方法區這個類的各種資料的訪問入口,

  1. 鏈接
    2.1. 驗證
    主要確保加載進來的位元組流符合JVM規范,驗證階段會完成以下4個階段的檢驗動作:
    1)檔案格式驗證
    2)元資料驗證(是否符合Java語言規范) 3)位元組碼驗證(確定程式語意合法,符合邏輯)
    4)符號參考驗證(確保下一步的決議能正常執行)
    2.2. 準備
    準備是連接階段的第二步,主要為靜態變數在方法區分配記憶體,并設定默認初始值,
    2.3. 決議
    決議是連接階段的第三步,是虛擬機將常量池內的符號參考替換為直接參考的程序,
  2. 初始化
    初始化階段是類加載程序的最后一步,主要是根據程式中的賦值陳述句主動為類變數賦值,
    當有繼承關系時,先初始化父類再初始化子類,所以創建一個子類時其實記憶體中存在兩個物件實
    例,
  3. 使用
    程式之間的相互呼叫,
  4. 卸載
    即銷毀一個物件,一般情況下中有JVM垃圾回收器完成,代碼層面的銷毀只是將參考置為null,

15. 吞吐量優先和回應時間優先的回收器是哪些?

  • 吞吐量優先:Parallel Scavenge+Parallel Old(多執行緒并行)
  • 回應時間優先:cms+par new(并發回收垃圾)

16. 什么叫做阻塞佇列的有界和無界,實際中有用過嗎?

  • ArrayBlockingQueue:一個由陣列結構組成的有界阻塞佇列,執行緒池,生產者消費者
  • LinkedBlockingQueue:一個由鏈表結構組成的無界阻塞佇列,執行緒池,生產者消費者
  • PriorityBlockingQueue:一個支持優先級排序的無界阻塞佇列,可以實作精確的定時任務
  • DelayQueue:一個使用優先級佇列實作的無界阻塞佇列,可以實作精確的定時任務
  • SynchronousQueue:一個不存盤元素的阻塞佇列,執行緒池
  • LinkedTransferQueue:一個由鏈表結構組成的無界阻塞佇列
  • LinkedBlockingDeque:一個由鏈表結構組成的雙向無界阻塞佇列,可以用在“作業竊取”模式

17. jvm監控系統是通過jmx做的么?

一般都是,但是要是記錄比較詳細的性能定位指標,都會導致進入 safepoint,從而降低了線上應用性能
例如 jstack,jmap列印堆疊,列印記憶體使用情況,都會讓 jvm 進入safepoint,才能獲取執行緒穩定狀態從而采集資訊,
同時,JMX暴露向外的介面采集資訊,例如使用jvisualvm,還會涉及rpc和網路消耗,以及JVM忙時,無法采集到資訊從而有指標斷點,這些都是基于 JMX 的外部監控很難解決的問題,所以,推薦使用JVM內部采集 JFR,這樣即使在JVM很忙時,也能采集到有用的資訊

18. 記憶體屏障的匯編指令是啥?

1.硬體記憶體屏障 X86
sfence: store| 在sfence指令前的寫操作當必須在sfence指令后的寫操作前完成,
lfence: load | 在lfence指令前的讀操作當必須在lfence指令后的讀操作前完成,
mfence: modify/mix | 在mfence指令前的讀寫操作當必須在mfence指令后的讀寫操作前完成,
2.原子指令,如x86上的”lock …” 指令是一個Full Barrier,執行時會鎖住記憶體子系統來確保執行順序,甚至跨多個CPU,Software Locks通常使用了記憶體屏障或原子指令來實作變數可見性和保持程式順序,
3.JVM級別如何規范(JSR133)

LoadLoad屏障:
對于這樣的陳述句Load1; LoadLoad; Load2, 在Load2及后續讀取操作要讀取的資料被訪問前,保證Load1要讀取的資料被讀取完畢,
StoreStore屏障:
對于這樣的陳述句Store1; StoreStore; Store2, 在Store2及后續寫入操作執行前,保證Store1的寫入操作對其它處理器可見,
LoadStore屏障:
對于這樣的陳述句Load1; LoadStore; Store2, 在Store2及后續寫入操作被刷出前,保證Load1要讀取的資料被讀取完畢,
StoreLoad屏障:
對于這樣的陳述句Store1; StoreLoad; Load2, 在Load2及后續所有讀取操作執行前,保證Store1的寫入對所有處理器可見,

我是牧小農,怕什么真理無窮,進一步有進一步的歡喜,大家加油!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/280736.html

標籤:其他

上一篇:你居然不會狄杰斯特演算法?驚了!

下一篇:【滲透測驗工具beef】XSS滲透測驗工具beef如何安裝使用?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more