主頁 >  其他 > 找作業再也不愁之面試題全覆寫-Java基礎篇

找作業再也不愁之面試題全覆寫-Java基礎篇

2021-12-20 14:52:11 其他

一.JavaSE 部分

基礎篇

Java中基本資料型別有哪些?

byte:8位,最大存盤資料量是255,存放的資料范圍是-128~127之間,

short:16位,最[大資料]存盤量是65536,資料范圍是-32768~32767之間,

int:32位,最大資料存盤容量是2的32次方減1,資料范圍是負的2的31次方到正的2的31次方減1,

long:64位,最大資料存盤容量是2的64次方減1,資料范圍為負的2的63次方到正的2的63次方減1,

float:32位,資料范圍在3.4e-45~1.4e38,直接賦值時必須在數字后加上f或F,

double:64位,資料范圍在4.9e-324~1.8e308,賦值時可以加d或D也可以不加,

boolean:只有true和false兩個取值,

char:16位,存盤Unicode碼,用單引號賦值,

Integer 和 int的區別

int是基本資料型別,變數中直接存放數值,變數初始化時值是0

Integer是參考資料型別,變數中存放的是該物件的參考,變數初始化時值時null

Integer是int型別的包裝類,將int封裝成Integer,符合java面向物件的特性,可以使用各種方法比如和其他資料型別間的轉換

Integer和int的深入對比:

  1. 兩個通過new生成的Integer物件,由于在堆中地址不同,所以永遠不相等

  2. int和Integer比較時,只要數值相等,結果就相等,因為包裝類和基本資料型別比較時,會自動拆箱,將Integer轉化為int

  3. 通過new生成的Integer物件和非通過new生成的Integer物件相比較時,由于前者存放在堆中,后者存放在Java常量池中,所以永遠不相等

  4. 兩個非通過new生成的Integer物件比較時,如果兩個變數的數值相等且在-128到127之間,結果就相等,這是因為給Integer物件賦一個int值,java在編譯時,會自動呼叫靜態方法valueOf(),根據java api中對Integer型別的valueOf的定義,對于-128到127之間的整數,會進行快取,如果下次再賦相同的值會直接從快取中取,即享元模式

String和StringBuilder和StringBuffer區別

三者底層都是char[]存盤資料,JDK1.9之后使用的是byte[] ,因為往往我們存盤都是短字串,使用byte[]這樣更節約空間,

由于String底層的char[]有final修飾,因此每次對String的操作都會在記憶體中開辟空間,生成新的物件,所以String不可變

StringBuilder和StringBuffer是可變字串,沒有final修飾,適合字串拼接,另外StringBuffer是執行緒安全的,方法有synchronized修飾,但是性能較低,StringBuilder是執行緒不安全的,方法沒有synchronized修飾,性能較高

String a = “A” 和 String a = new String(“A”) 創建字串的區別

String c = “A” 首先去常量池找 “A”,如果有,會把a指向這個物件的地址 ,如果沒有則在堆疊中創建三個char型的值’A’,堆中創建一個String物件object,值為"A",接著object會被存放進字串常量池中,最后將a指向這個物件的的地址

new String(“A”) : 如果常量池中么有“A”就會走上面相同的流程先創建“A”,然后在堆中創建一個String物件,它的值共享堆疊中已有的char值“A”,

下面代碼創建了幾個物件

  • String s = “a” +“b” + “c” + “d”;這條陳述句創建了幾個物件?

創建了一個物件,因為相對于字串常量相加的運算式,編譯器會在編譯期間進行優化,直接將其編譯成常量相加的結果,

  • String s; 創建幾個物件?
    沒有創建物件,

  • String a = “abc”; String b = “abc”; 創建了幾個物件

    創建了一個物件,只是在第一條陳述句中創建了一個物件,a和b都指向相同的物件"abc",參考不是物件

== 和 equals 的區別是什么

==比較物件比較的是地址,對于Object物件中的equals 方法使用的也是 == ,比較的是物件的地址,默認情況下使用物件的equals比較Object中的equals方法,也就是比較地址,如果要實作自己的比較方式需要復寫equals 方法,

對于包裝類比如:Integer都是復寫過equals方法,比較的是int 值,

final 和 finally 和 finalize 的區別

當用final修飾類的時,表明該類不能被其他類所繼承,當我們需要讓一個類永遠不被繼承,此時就可以用final修飾

finally作為例外處理的一部分,它只能用在try/catch陳述句中,并且附帶一個陳述句塊,表示這段陳述句最終一定會被執行(不管有沒有拋出例外),經常被用在需要釋放資源的情況下

finalize()是在java.lang.Object里定義的,也就是說每一個物件都有這么個方法,這個方法在gc啟動,該物件被回收的時候被呼叫,其實gc可以回收大部分的物件(凡是new出來的物件,gc都能搞定,一般情況下我們又不會用new以外的方式去創建物件),所以一般是不需要程式員去實作finalize的,

JDK 和 JRE 有什么區別?

JRE(Java Runtime Enviroment) :是Java的運行環境,JRE是運行Java程式所必須環境的集合,包含JVM標準實作及 Java核心類別庫

JDK(Java Development Kit) :是Java開發工具包,它提供了Java的開發環境(提供了編譯器javac等工具,用于將java檔案編譯為class檔案)和運行環境(提 供了JVM和Runtime輔助包,用于決議class檔案使其得到運行),JDK是整個Java的核心,包括了Java運行環境(JRE),一堆Java工具tools.jar和Java標準類別庫 (rt.jar),

面向物件四大特性

抽象 : 是將一類物件的共同特征總結出來構造類的程序,包括資料抽象和行為抽象兩方面,抽象只關注物件的哪些屬性和行為,并不關注這此行為的細節是什么 - 舉例:定義一個persion類,了就是對這種事物的抽象

封裝:對資料的訪問只能通過已定義的介面,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡單的編程介面,比如在Java中,把不需要暴露的內容和實作細節隱藏起來,或者private修飾,然后提供專門的訪問方法,如JavaBean, - 生活舉例:電腦主機就是把主板等封裝到機殼,提供USB介面,網卡介面,電源介面等, JavaBean就是一種封裝,

繼承:新類(子類,派生類)繼承了原始類的特性,子類可以從它的父類哪里繼承方法和實體變數,并且類可以修改或增加新的方法使之更適合特殊的需要,

多型:多型是指允許不同類的物件對同一訊息做出回應,物件的多種形態,當編譯時型別和運行時型別不一樣,就是多型,意義在于屏蔽子類差異

方法覆寫和多載

方法的覆寫是子類和父類之間的關系,方法的多載是同一個類中方法之間的關系,
覆寫只能由一個方法,或只能由一對方法產生關系;方法的多載是多個方法之間的關系,
覆寫要求引數串列相同;多載要求引數串列不同,

普通類和抽象類

抽象類不能被實體化, 需要通過子類實體化
抽象類可以有建構式,被繼承時子類必須繼承父類一個構造方法,抽象方法不能被宣告為靜態,
抽象方法只需申明,而無需實作,抽象類中可以允許普通方法有主體
含有抽象方法的類必須申明為抽象類
抽象的子類必須實作抽象類中所有抽象方法,否則這個子類也是抽象類

介面和抽象類

定義介面使用interface,定義抽象類使用abstract class

介面由全域常量,抽象方法,(java8后:靜態方法,默認方法)

抽象類由構造方法,抽象方法,普通方法

介面和類是實作關系,抽象類和類是繼承關系


IO流

你知道BIO,NIO,AIO么?講一下你的理解

BIO (Blocking I/O):同步阻塞I/O 模式,以流的方式處理資料,資料的讀取寫入必須阻塞在一個執行緒內等待其完成,適用于連接數目比較小且固定的架構

NIO (New I/O):同時支持阻塞與非阻塞模式,以塊的方式處理資料,適用于連接數目多且連接比較短(輕操作)的架構,比如聊天器

AIO ( Asynchronous I/O):異步非阻塞I/O 模型,適用于連接數目多且連接比較長(重操作)的架構

java 中四大基礎流

InputStream : 輸入位元組流, 也就是說它既屬于輸入流, 也屬于位元組流 ,

OutputStream: 輸出位元組流, 既屬于輸出流, 也屬于位元組流

Reader: 輸入字符流, 既屬于輸入流, 又屬于字符流

Writer: 輸出字符流, 既屬于輸出流, 又屬于字符流

讀文本用什么流,讀圖片用什么流

文本用字符輸入流,讀圖片用直接輸入流

字符流和位元組流有什么區別

字符流適用于讀文本,位元組流適用于讀圖片,視頻,檔案等,

位元組流操作的基本單元為位元組;字符流操作的基本單元為Unicode碼元,

位元組流默認不使用緩沖區;字符流使用緩沖區,

位元組流通常用于處理二進制資料,實際上它可以處理任意型別的資料,但它不支持直接寫入或讀取Unicode碼元;字符流通常處理文本資料,它支持寫入及讀取Unicode碼元

BufferedInputStream 用到什么設計模式

主要運用了倆個設計模式,配接器和裝飾者模式

帶緩沖區的流

BufferedInputStream 帶緩沖區的位元組輸入

BufferedOutputStream 帶緩沖區的輸出流

BufferedReader : 帶緩沖區的字符輸入流

BufferedWriter : 帶緩沖區的字符輸出流


集合篇

說一下Java中的集合體系

Collection介面

List:

  • ArrayList:底層資料結構是陣列,查詢性能高,增刪性能低

  • Vector:底層資料結構是陣列,查詢性能高,增刪性能低

  • LinkedList:底層資料結構是雙向鏈表,查詢性能低,增刪性能高

Set:

  • HashSet:無序不重復的,使用HashMap的key存盤元素,判斷重復依據是hashCode()和equals()

  • TreeSet:有序不重復的,底層使用TreeMap的key存盤元素,排序方式分為自然排序,比較器排序

Map介面

  • HashMap:key的值沒有順序,執行緒不安
  • TreeMap:key的值可以自然排序,執行緒不安全
  • HashTable:它的key和value都不允許為null,執行緒安全
  • Properties:它的key和value都是String型別的,執行緒安全

HashMap和HashTable的區別

HashMap和HashTable都是實作了Map介面的集合框架,他們的區別

  • HashTable是執行緒安全的,它的實作方法都加了synchronized關鍵字,因此它的性能較低

  • HashMap是執行緒不安全的,它實作方法沒有加synchronized,因此它的性能較高

  • HashMap的key和value都允許為null,HashTable中的key和value都不能為null,如果不考慮執行緒安全,建議使用HashMap,如果需要考慮執行緒安全的高并發實作,建議使用ConcurrentHashMap

ArrayList和LinkedList區別

都屬于線性結構,ArrayList是基于陣列實作的,開辟的記憶體空間要求聯系,可以根據索引隨機訪問元素性能高,但是插入和洗掉元素性能差,因為這會涉及到移位操作

LinkedList是基于雙鏈表實作的,開配的記憶體空間不要求連續,因此不支持索引,查找元素需要從頭查找,因此性能差,但是添加洗掉只需要改變指標指向即可,性能高. LinkedList會增加記憶體碎片化,增加記憶體管理難度

根據實際需要,如果專案中使用查找較多,使用ArrayList,如果使用增刪較多,請使用LinkedList

ArrayList和Vector區別

ArrayList是執行緒不安全的,Vector相反是執行緒安全的,方法加了同步鎖,執行緒安全但是性能差,ArrayList底層陣列容量不足時,會自動擴容0.5倍,Vector會自動擴容1倍

一個User的List集合,如何實作根據年齡排序

第一種方式,讓User類實作Comparable介面,覆寫compareTo方法,方法中自定義根據年齡比較的演算法

第二種方式,呼叫Collections.sort方法,傳入一個比較器,覆寫compare方法,方法中自定義根據年齡比較的演算法

HashMap底層用到了那些資料結構?

JDK1.7及其之前:陣列,鏈表 ; JDK1.8開始:陣列,鏈表,紅黑樹

什么是Hash沖突

哈希沖突,也叫哈希碰撞,指的是兩個不同的值,計算出了相同的hash,也就是兩個不同的資料計算出同一個下標,通常解決方案有:

  • 拉鏈法,把哈希碰撞的元素指向一個鏈表

  • 開放尋址法,把產生沖突的哈希值作為值,再進行哈希運算,直到不沖突

  • 再散列法,就是換一種哈希演算法重來一次

  • 建立公共溢位區,把哈希表分為基本表和溢位表,將產生哈希沖突的元素移到溢位表

HashMap為什么要用到鏈表結構

當我們向HashMap中添加元素時,會先根據key盡心哈希運算,把hash值模與陣列長度得到一個下標,然后將該元素添加進去,但是如果產生了哈希碰撞,也就是不同的key計算出了相同的hash值,這就出問題了,因此它采用了拉鏈法來解決這個問題,將產生hash碰撞的元素,掛載到鏈表中

HashMap為什么要用到紅黑樹

當HashMap中同一個索引位置出現哈希碰撞的元素多了,鏈表會變得越來越長,查詢效率會變得越來越慢,因此在JDK1.8之后,當鏈表長度超過8個,會將鏈表轉壞為紅黑樹來提高查詢

HashMap鏈表和紅黑樹在什么情況下轉換的?

當鏈表的長度大于等于8,同時陣列的長度大于64,鏈表會自動轉化為紅黑樹,當樹中的節點數小于等于6,紅黑樹會自動轉化為鏈表

HashMap在什么情況下擴容?HashMap如何擴容的?

HashMap的陣列初始容量是16,負載因子是0.75,也就是說當陣列中的元素個數大于12個,會成倍擴容

tips:為啥子是0.75:負載因子過小容易浪費空間,過大容易造成更多的哈希碰撞,產生更多的鏈表和樹,因此折衷考慮采用了0.75

為啥子是成倍擴容:需要保證陣列的長度是2的整數次冪

為嘛陣列的長度必須是2的整數次冪:我們在存盤元素到陣列中的時候,是通過hash值模與陣列的長度,計算出下標的,但是由于計算機的運算效率,加減法>乘法>除法>取模,取模的效率是最低的,開發者們為了讓你用的開心,也是嘔心瀝血,將取模運算轉化成了與運算,即陣列長度減1的值和hash值的與運算,以此來優化性能,但是這個轉化有一個前提,就是陣列的長度必須為2的整數次冪

HashMap是如何Put一個元素的

首先,將key進行hash運算,將這個hash值與上當前陣列長度減1的值,計算出索引,此時判斷該索引位置是否已經有元素了,如果沒有,就直接放到這個位置

如果這個位置已經有元素了,也就是產生了哈希碰撞,那么判斷舊元素的key和新元素的key的hash值是否相同,并且將他們進行equals比較,如果相同證明是同一個key,就覆寫舊資料,并將舊資料回傳,如果不相同的話

再判斷當前桶是鏈表還是紅黑樹,如果是紅黑樹,就按紅黑樹的方式,寫入該資料,

如果是鏈表,就依次遍歷并比較當前節點的key和新元素的key是否相同,如果相同就覆寫,如果不同就接著往下找,直到找到空節點并把資料封裝成新節點掛到鏈表尾部,然后需要判斷,當前鏈表的長度是否大于轉化紅黑樹的閾值,如果大于就轉化紅黑樹,最后判斷陣列長度是否需要擴容,

HashMap是如何Get一個元素的

首先將key進行哈希運算,計算出陣列中的索引位置,判斷該索引位置是否有元素,如果沒有,就回傳null,如果有值,判斷該資料的key是否為查詢的key,如果是就回傳當前值的value

如果第一個元素的key不匹配,判斷是紅黑樹還是鏈表,如果是紅黑樹,就就按照紅黑樹的查詢方式查找元素并回傳,如果是鏈表,就遍歷并匹配key,讓后回傳value值

你知道HahsMap死回圈問題嗎

HashMap在擴容陣列的時候,會將舊資料遷徙到新陣列中,這個操作會將原來鏈表中的資料顛倒,比如a->b->null,轉換成b->a->null

這個程序單執行緒是沒有問題的,但是在多執行緒環境,就可能會出現a->b->a->b…,這就是死回圈

在JDK1.8后,做了改進保證了轉換后鏈表順序一致,死回圈問題得到了解決,但還是會出現高并發時資料丟失的問題,因此在多執行緒情況下還是建議使用ConcurrentHashMap來保證執行緒安全問題

說一下你對ConcurrentHashMap的理解

ConcurrentHashMap,它是HashMap的執行緒安全,支持高并發的版本

在jdk1.7中,它是通過分段鎖的方式來實作執行緒安全的,意思是將哈希表分成許多片段Segment,而Segment本質是一個可重入的互斥鎖,所以叫做分段鎖,

在jdk1.8中,它是采用了CAS操作和synchronized來實作的,而且每個Node節點的value和next都用了volatile關鍵字修飾,保證了可見性


多執行緒

創建執行緒是幾種方式

方式一:繼承Thread類,覆寫run方法,創建實體物件,呼叫該物件的start方法啟動執行緒
方式二:創建Runnable介面的實作類,類中覆寫run方法,再將實體作為此引數傳遞給Thread類有參構造創建執行緒物件,呼叫start方法啟動

方式三:創建Callable介面的實作類,類中覆寫call方法,創建實體物件,將其作為引數傳遞給FutureTask類有參構造創建FutureTask物件,再將FutureTask物件傳遞給Thread類的有參構造創建執行緒物件,呼叫start方法啟動

Thread有單繼承的局限性,Runnable和Callable三避免了單繼承的局限,使用更廣泛,Runnable適用于無需回傳值的場景,Callable使用于有回傳值的場景

Thread的start和run的區別

start是開啟新執行緒, 而呼叫run方法是一個普通方法呼叫,還是在主執行緒里執行,沒人會直接呼叫run方法

sleep 和 wait的區別

第一,sleep方法是Thread類的靜態方法,wait方法是Object類的方法

第二:sleep方法不會釋放物件鎖,wait方法會釋放物件鎖

第三:sleep方法必須捕獲例外,wait方法不需要捕獲例外

執行緒的幾種狀態

新建狀態:執行緒剛創建,還沒有呼叫start方法之前

就緒狀態:也叫臨時阻塞狀態,當呼叫了start方法后,具備cpu的執行資格,等待cpu調度器輪詢的狀態

運行狀態:就緒狀態的執行緒,獲得了cpu的時間片,真正運行的狀態

凍結狀態:也叫阻塞狀態,指的是該執行緒因某種原因放棄了cpu的執行資格,暫時停止運行的狀態,比如呼叫了wait,sleep方法

死亡狀態:執行緒執行結束了,比如呼叫了stop方法

Synchronized 和 lock的區別

他們都是用來解決并發編程中的執行緒安全問題的,不同的是

  • synchronized是一個關鍵字,依靠Jvm內置語言實作,底層是依靠指令碼來實作;Lock是一個介面,它基于CAS樂觀鎖來實作的
  • synchronized在執行緒發生例外時,會自動釋放鎖,不會發生例外死鎖,Lock在例外時不會自動釋放鎖,我們需要在finally中釋放鎖
  • synchronized是可重入,不可判斷,非公平鎖,Lock是可重入,可判斷的,可手動指定公平鎖或者非公平鎖

你知道AQS嗎

AQS:AbstractQuenedSynchronizer抽象的佇列式同步器,是除了java自帶的synchronized關鍵字之外的鎖機制,它維護了一個volatile修飾的 int 型別的,state(代表共享資源)和一個FIFO執行緒等待佇列(多執行緒爭用資源被阻塞時會進入此佇列),

作業思想是如果被請求的資源空閑,也就是還沒有執行緒獲取鎖,將當前請求資源的執行緒設定為有效的作業執行緒,并將共享資源設定為鎖定狀態,如果請求的資源被占用,就將獲取不到鎖的執行緒加入佇列,

悲觀鎖和樂觀鎖

悲觀鎖和樂觀鎖,指的是看待并發同步問題的角度

  • 悲觀鎖認為,對同一個資料的并發操作,一定是會被其他執行緒同時修改的,所以在每次操作資料的時候,都會上鎖,這樣別人就拿不到這個資料,如果不加鎖,并發操作一定會出問題,用陽間的話說,就是總有刁民想害朕

  • 樂觀鎖認為,對同一個資料的并發操作,是不會有其他執行緒同時修改的,它不會使用加鎖的形式來操作資料,而是在提交更新資料的時候,判斷一下在操作期間有沒有其他執行緒修改了這個資料

悲觀鎖一般用于并發小,對資料安全要求高的場景,樂觀鎖一般用于高并發,多讀少寫的場景,通常使用版本號控制,或者時間戳來解決.

你知道什么是CAS嘛

CAS,compare and swap的縮寫,中文翻譯成比較并交換,它是樂觀鎖的一種體現,CAS 操作包含三個運算元 —— 記憶體位置(V)、預期原值(A)和新值(B), 如果記憶體位置的值與預期原值相匹配,那么處理器會自動將該位置值更新為新值 ,否則,處理器不做任何操作,

Synchronized 加非靜態和靜態方法上的區別

實體方法上的鎖,鎖住的是這個物件實體,它不會被實體共享,也叫做物件鎖

靜態方法上的鎖,鎖住的是這個類的位元組碼物件,它會被所有實體共享,也叫做類鎖

Synchronized(this) 和 Synchronized (User.class)的區別

Synchronized(this) 中,this代表的是該物件實體,不會被所有實體共享

Synchronized (User.class),代表的是對類加鎖,會被所有實體共享

Synchronized 和 volatitle 關鍵字的區別

這兩個關鍵字都是用來解決并發編程中的執行緒安全問題的,不同點主要有以下幾點

第一:volatile的實作原理,是在每次使用變數時都必須重主存中加載,修改變數后都必須立馬同步到主存;synchronized的實作原理,則是鎖定當前變數,讓其他執行緒處于阻塞狀態

第二:volatile只能修飾變數,synchronized用在修飾方法和同步代碼塊中

第三:volatile修飾的變數,不會被編譯器進行指令重排序,synchronized不會限制指令重排序

第四:volatile不會造成執行緒阻塞,高并發時性能更高,synchronized會造成執行緒阻塞,高并發效率低

第五:volatile不能保證操作的原子性,因此它不能保證執行緒的安全,synchronized能保證操作的原子性,保證執行緒的安全

synchronized 鎖的原理

synchronized是基于JVM內置鎖實作,通過內部物件Monitor(監視器鎖)實 現,基于進入與退出Monitor物件實作方法與代碼塊同步,監視器鎖的實作依賴 底層作業系統的Mutex lock(互斥鎖)實作,它是一個重量級鎖性能較低,涉及到用戶態到內核態的切換,會讓整個程式性能變得很差,

因此在JDK1.6及以后的版本中,增加了鎖升級的程序,依次為無鎖,偏向鎖,輕量級鎖,重量級鎖,而且還增加了鎖粗化,鎖消除等策略,這就節省了鎖操作的開銷,提高了性能

synchronized 鎖升級原理

每個物件都擁有物件頭,物件頭由Mark World ,指向類的指標,以及陣列長度三部分組成,鎖升級主要依賴Mark Word中的鎖標志位和釋放偏向鎖標識位,

  • 偏向鎖(無鎖)

大多數情況下鎖不僅不存在多執行緒競爭,而且總是由同一執行緒多次獲得,偏向鎖的目的是在某個執行緒 獲得鎖之后(執行緒的id會記錄在物件的Mark Word鎖標志位中),消除這個執行緒鎖重入(CAS)的開銷,看起來讓這個執行緒得到了偏護,(第二次還是這個執行緒進來就不需要重復加鎖,基本無開銷),如果自始至終使用鎖的執行緒只有一個,很明顯偏向鎖幾乎沒有額外開銷,性能極高,

  • 輕量級鎖(CAS):

輕量級鎖是由偏向鎖升級來的,偏向鎖運行在一個執行緒進入同步塊的情況下,當第二個執行緒加入鎖爭用的時候,偏向鎖就會升級為輕量級鎖自旋鎖);沒有搶到鎖的執行緒將自旋,獲取鎖的操作,輕量級鎖的意圖是在沒有多執行緒競爭的情況下,通過CAS操作嘗試將MarkWord鎖標志位更新為指向LockRecord的指標,減少了使用重量級鎖的系統互斥量產生的性能消耗,

長時間的自旋操作是非常消耗資源的,一個執行緒持有鎖,其他執行緒就只能在原地空耗CPU,執行不了任何有效的任務,這種現象叫做忙等(busy-waiting)

  • 重量級鎖:

如果鎖競爭情況嚴重,某個達到最大自旋次數(10次默認)的執行緒,會將輕量級鎖升級為重量級鎖,重量級鎖則直接將自己掛起,在JDK1.6之前,synchronized直接加重量級鎖,很明顯現在得到了很好的優化,

虛擬機使用CAS操作嘗試將MarkWord更新為指向LockRecord的指標,如果更新成功表示執行緒就擁有該物件的鎖;如果失敗,會檢查MarkWord是否指向當前執行緒的堆疊幀,如果是,表示當前執行緒已經擁有這個鎖;如果不是,說明這個鎖被其他執行緒搶占,此時膨脹為重量級鎖,

樂觀鎖的使用場景(資料庫,ES)

場景一:ES中對version的控制并發寫,

場景二:資料庫中使用version版本號控制來防止更新覆寫問題,

場景三:原子類中的CompareAndSwap操作

AtomicInterger怎么保證并發安全性的

通過CAS操作原理來實作的,就可見性和原子性兩個方面來說

它的value值使用了volatile關鍵字修飾,也就保證了多執行緒操作時記憶體的可見性

Unsafe這個類是一個很神奇的類,而compareAndSwapInt這個方法可以直接操作記憶體,依靠的是C++來實作的,它呼叫的是Atomic類的cmpxchg函式,而這個函式的實作是跟作業系統有關的,比如在X86的實作就利用匯編語言的CPU指令lock cmpxchg,它在執行后面的指令時,會鎖定一個北橋信號,最終來保證操作的原子性

什么是重入鎖,什么是自旋鎖,什么是阻塞

可重入鎖是指允許同一個執行緒多次獲取同一把鎖,比如一個遞回函式里有加鎖操作

自旋鎖不是鎖,而是一種狀態,當一個執行緒嘗試獲取一把鎖的時候,如果這個鎖已經被占用了,該執行緒就處于等待狀態,并間隔一段時間后再次嘗試獲取的狀態,就叫自旋

阻塞,指的是當一個執行緒嘗試獲取鎖失敗了,執行緒就就進行阻塞,這是需要作業系統切換CPU狀態的

你用過JUC中的類嗎,說幾個

Lock鎖體系 ,ConcurrentHashMap ,Atomic原子類,如:AtomicInteger ;ThreadLoal ; ExecutorService

ThreadLocal的作用和原理

ThreadLocal,翻譯成中國話,叫做執行緒本地變數,它是為了解決執行緒安全問題的,它通過為每個執行緒提供一個獨立的變數副本,來解決并發訪問沖突問題 - 簡單理解它可以把一個變數系結到當前執行緒中,達到執行緒間資料隔離目的,

原理:ThredLocal是和當前執行緒有關系的,每個執行緒內部都有一個ThreadLocal.ThreadLocalMap型別的成員變數threadLocals,它用來存盤每個執行緒中的變數副本,key就是ThreadLocal變數,value就是變數副本,

當我們呼叫get方法是,就會在當前執行緒里的threadLocals中查找,它會以當前ThreadLocal變數為key獲取當前執行緒的變數副本

它的使用場景比如在spring security中,我們使用SecurityContextHolder來獲取SecurityContext,比如在springMVC中,我們通過RequestContextHolder來獲取當前請求,比如在 zuul中,我們通過ContextHolder來獲取當前請求

執行緒池的作用

請求并發高的時候,如果沒有執行緒池會出現執行緒頻繁創建和銷毀而浪費性能的情況,同時沒辦法控制請求數量,所以使用了執行緒池后有如下好處

  • 主要作用是控制并發數量,執行緒池的佇列可以緩沖請求
  • 執行緒池可以實作執行緒的復用效果
  • 使用執行緒池能管理執行緒的生命周期

Executors創建四種執行緒池

  • CachedThreadPool:可快取的執行緒池,它在創建的時候,沒有核心執行緒,執行緒最大數量是Integer最大值,最大空閑時間是60S

  • FixedThreadPool:固定長度的執行緒池,它的最大執行緒數等于核心執行緒數,此時沒有最大空閑時長為0

  • SingleThreadPool:單個執行緒的執行緒池,它的核心執行緒和最大執行緒數都是1,也就是說所有任務都串行的執行

  • ScheduledThreadPool:可調度的執行緒池,它的最大執行緒數是Integer的最大值,默認最長等待時間是10S,它是一個由延遲執行和周期執行的執行緒池

執行緒池的執行流程

corePoolSize,maximumPoolSize,workQueue之間關系,

  1. 當執行緒池中執行緒數小于corePoolSize時,新提交任務將創建一個新執行緒(使用核心)執行任務,即使此時執行緒池中存在空閑執行緒,
  2. 當執行緒池中執行緒數達到corePoolSize時(核心用完),新提交任務將被放入workQueue中,等待執行緒池中任務調度執行 ,
  3. 當workQueue已滿,且maximumPoolSize > corePoolSize時,新提交任務會創建新執行緒(非核心)執行任務,
  4. 當workQueue已滿,且提交任務數超過maximumPoolSize(執行緒用完,佇列已滿),任務由RejectedExecutionHandler處理,
  5. 當執行緒池中執行緒數超過corePoolSize,且超過這部分的空閑時間達到keepAliveTime時,回收這些執行緒,
  6. 當設定allowCoreThreadTimeOut(true)時,執行緒池中corePoolSize范圍內的執行緒空閑時間達到keepAliveTime也將回收,

執行緒池執行流程 : 核心執行緒 => 等待佇列 => 非核心執行緒 => 拒絕策略

執行緒池構造器的7個引數

  • CorePoolSize:核心執行緒數,它是不會被銷毀的

  • MaximumPoolSize :最大執行緒數,核心執行緒數+非核心執行緒數的總和

  • KeepAliveTime:非核心執行緒的最大空閑時間,到了這個空閑時間沒被使用,非核心執行緒銷毀

  • Unit:空閑時間單位

  • WorkQueue:是一個BlockingQueue阻塞佇列,超過核心執行緒數的任務會進入佇列排隊

  • ThreadFactory:它是一個創建新執行緒的工廠

  • Handler:拒絕策略,任務超過最大執行緒數+佇列排隊數 ,多出來的任務該如何處理取決于Handler

執行緒池拒絕策略有幾種

拒絕策略,當執行緒池任務超過 最大執行緒數+佇列排隊數 ,多出來的任務該如何處理取決于Handler

  1. AbortPolicy丟棄任務并拋出RejectedExecutionException例外;
  2. DiscardPolicy丟棄任務,但是不拋出例外;
  3. DiscardOldestPolicy丟棄佇列最前面的任務,然后重新嘗試執行任務;
  4. CallerRunsPolicy由呼叫執行緒處理該任務

可以定義和使用其他種類的RejectedExecutionHandler類來定義拒絕策略,

你知道ScheduledThreadPool使用場景嗎

這是帶定時任務的執行緒池,EurekaClient拉取注冊表&心跳續約就是使用的這個執行緒池,

JVM篇

你們用什么工具監控JVM

jconsule, jvisualvm

JVM類加載流程

loading加載:class檔案從磁盤加載到記憶體中

verification驗證:校驗class檔案,包括位元組碼驗證,元資料驗證,符號參考驗證等等

preparation準備:靜態變數賦默認值,只有final會賦初始值

resolution決議:常量池中符號參考,轉換成直接訪問的地址

initializing初始化:靜態變數賦初始值

JVM類加載器有幾種型別,分別加載什么東西,用到什么設計模式?

  1. BootStrap ClassLoader 啟動類加載器,加載<JAVA_HOME>\lib下的類

  2. Extenstion ClassLoader 擴展類加載器,加載<JAVA_HOME>\lib\ext下的類

  3. Application ClassLoader 應用程式類加載器,加載Classpath下的類

  4. 自定義類加載器

這里是用到了雙親委派模式,從上往下加載類,在這程序中只要上一級加載到了,下一級就不會加載了,這麼做的目的

  • 不讓我們輕易覆寫系統提供功能
  • 也要讓我們擴展我們功能,

JVM組成,以及他們的作用

運行時資料區:

  • 堆:存放物件的區域,所有執行緒共享

  • 虛擬機堆疊:對應一個方法,執行緒私有的,存放區域變數表,運算元堆疊,動態鏈接等等

  • 本地方法堆疊:對應的是本地方法,在hotspot中虛擬機堆疊和本地方法堆疊是合為一體的

  • 程式計數器:確定指令的執行順序

  • 方法區:存放虛擬機加載的類的資訊,常量,靜態變數等等,JDK1.8后,改為元空間

執行引擎:

  • 即時編譯器,用來將熱點代碼編譯成機器碼(編譯執行)

  • 垃圾收集,將沒用的物件清理掉

本地方法庫:融合不同的編程語言為java所用

在JVM層面,一個執行緒是如何執行的

執行緒執行,每個方法都會形成一個堆疊幀進行壓榨保存到虛擬機堆疊中,方法呼叫結束就回出堆疊,呼叫程序中創建的變數在虛擬機堆疊,物件實體存放在堆記憶體中,堆疊中的變數指向了對中的記憶體,當方法執行完成就出堆疊,創建的變數會被銷毀,堆中的物件等待GC,

程式記憶體溢位了,如何定位問題出在哪兒?

增加啟動引數-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\ 可以把記憶體溢位的日志輸出到檔案,然后通過JVM監視工具VisualVM來分析日志,定位錯誤所在,在linux服務器也可以使用命令: jmap -dump 來下載堆快照,

垃圾標記演算法

垃圾標記演算法有:參考計數和可達性演算法

  • 參考計數 : 給每一個物件添加一個參考計數器,每當有一個地方參考它時,計數器值加1;每當有一個地方不再參考它時,計數器值減1,這樣只要計數器的值不為0,就說明還有地方參考它,它就不是無用的物件. 這種演算法的問題是當某些物件之間互相參考時,無法判斷出這些物件是否已死
  • GC Roots :找到一個物件作為 CG Root , 當一個物件到GC Roots沒有任何參考鏈相連(GC Roots到這個物件不可達)時,就說明此物件是不可用的

垃圾回收演算法

  • 標記清除演算法 :分為標記和清除兩個階段,首先標記出所有需要回收的物件,標記完成后統一回收所有被標記的物件 ;缺點:標記和清除兩個程序效率都不高;標記清除之后會產生大量不連續的記憶體碎片,

  • 復制演算法 :把記憶體分為大小相等的兩塊,每次存盤只用其中一塊,當這一塊用完了,就把存活的物件全部復制到另一塊上,同時把使用過的這塊記憶體空間全部清理掉,往復回圈 ,缺點:實際可使用的記憶體空間縮小為原來的一半,比較適合

  • 標記整理演算法 :先對可用的物件進行標記,然后所有被標記的物件向一段移動,最后清除可用物件邊界以外的記憶體

  • 分代收集演算法 :把堆記憶體分為新生代和老年代,新生代又分為Eden區、From Survivor和To Survivor,一般新生代中的物件基本上都是朝生夕滅的,每次只有少量物件存活,因此新生代采用復制演算法,只需要復制那些少量存活的物件就可以完成垃圾收集;老年代中的物件存活率較高,就采用標記-清除和標記-整理演算法來進行回收,

垃圾回收器有哪些

  • 新生代:Serial :一款用于新生代的單執行緒收集器,采用復制演算法進行垃圾收集,Serial進行垃圾收集時,不僅只用一條執行緒執行垃圾收集作業,它在收集的同時,所有的用戶執行緒必須暫停(Stop The World

  • 新生代:ParNew : ParNew就是一個Serial的多執行緒版本`,其它與Serial并無區別,ParNew在單核CPU環境并不會比Serial收集器達到更好的效果,它默認開啟的收集執行緒數和CPU數量一致,可以通過-XX:ParallelGCThreads來設定垃圾收集的執行緒數,

  • 新生代:Parallel Scavenge(掌握) Parallel Scavenge也是一款用于新生代的多執行緒收集器,與ParNew的不同之處是,ParNew的目標是盡可能縮短垃圾收集時用戶執行緒的停頓時間,Parallel Scavenge的目標是達到一個可控制的吞吐量.Parallel Old收集器以多執行緒,采用標記整理演算法進行垃圾收集作業,

  • 老年代:Serial Old ,Serial Old收集器是Serial的老年代版本,同樣是一個單執行緒收集器,采用標記-整理演算法,

  • 老年代CMS收集器是一種以最短回收停頓時間為目標的收集器,以“最短用戶執行緒停頓時間”著稱,整個垃圾收集程序分為4個步驟

    • 初始標記:標記一下GC Roots能直接關聯到的物件,速度較快
    • 并發標記:進行GC Roots Tracing,標記出全部的垃圾物件,耗時較長
    • 重新標記:修正并發標記階段參考戶程式繼續運行而導致變化的物件的標記記錄,耗時較短
    • 并發清除:用標記-清除演算法清除垃圾物件,耗時較長

    整個程序耗時最長的并發標記和并發清除都是和用戶執行緒一起作業,所以從總體上來說,CMS收集器垃圾收集可以看做是和用戶執行緒并發執行的,

  • 老年代:Parallel Old ,Parallel Old收集器是Parallel Scavenge的老年代版本,是一個多執行緒收集器,采用標記-整理演算法,可以與Parallel Scavenge收集器搭配,可以充分利用多核CPU的計算能力

  • 堆收集:G1 收集器, G1 收集器是jdk1.7才正式參考的商用收集器,現在已經成為jdk1.9默認的收集器,前面幾款收集器收集的范圍都是新生代或者老年代,G1進行垃圾收集的范圍是整個堆記憶體,它采用“化整為零”的思路,把整個堆記憶體劃分為多個大小相等的獨立區域(Region)在每個Region中,都有一個Remembered Set來實時記錄該區域內的參考型別資料與其他區域資料的參考關系(在前面的幾款分代收集中,新生代、老年代中也有一個Remembered Set來實時記錄與其他區域的參考關系),在標記時直接參考這些參考關系就可以知道這些物件是否應該被清除,而不用掃描全堆的資料

Jdk1.7.18新生代使用Parallel Scavenge,老年代使用Parallel Old

Minor GC和Full GC

新生代的回收稱為Minor GC,新生代的回收一般回收很快,采用復制演算法,造成的暫停時間很短 ,而Full GC一般是老年代的回收,并伴隨至少一次的Minor GC,新生代和老年代都回收,而老年代采用標記-整理演算法這種GC每次都比較慢造成的暫停時間比較長`,通常是Minor GC時間的10倍以上,盡量減少 Full GC

JVM優化的目的是什么?

優化程式的記憶體使用大小,以及減少CG來減少程式的停頓來提升程式的性能,

堆怎么調,堆疊怎么調

-Xms : 初始堆,1/64 物理記憶體

-Xmx : 最大堆,1/4物理記憶體

-Xmn :新生代大小

-Xss : 堆疊大小

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

標籤:其他

上一篇:Mac安裝git

下一篇:第二講 外部物體注入

標籤雲
其他(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)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more