摘要:減少,減輕壓力。實現測試類無參構造器無參構造器含參構造器含參構造器忽略訪問的安全檢查無參構造器含參構造器獲取方法規則類獲取修飾的指定方法含超類獲取修飾的指定方法含超類類獲取指定方法包括修飾,暴力反射,不
五.繼承
繼承 定義:基于已有的類構造新類
反射 定義:在程序運行期間發現更多的類以及屬性的能力
多態 定義:一個對象變量可以指示多種實際類型的現象
動態綁定 定義:在運行時能夠自動選擇調用方法的現象
5.1 類、超類和子類 5.1.2 覆蓋方法
規則
超類和子類中的方法簽名相同(方法名和參數列表),返回值類型需要保證一樣或者是返回值類型的子類(協變返回類型)
覆蓋和重載的區別
覆蓋是方法簽名相同
重載是方法名相同,參數列表必須不同,對返回類型,訪問修飾符,異常聲明沒有任何限制
5.1.6 方法調用流程圖解
5.1.7 阻止繼承:final類和方法
規則
類用final修飾后,無法被繼承,其中的方法也自動用final修飾。域不包括
方法用final修飾后,子類無法覆蓋當前方法
5.1.8 強制類型轉換
注意
強制類型轉換前,使用instanceof方法判斷是否為所屬類型
5.2 Object:所有類的超類注意:只有基本類型不是對象
5.2.1 equals
特點
自反性:x為任何非空引用,x.equals(x)應該返回true
對稱性:對于任何引用x,y,當且僅當x.equals(y)返回true,則y.equals(x)返回也為true
傳遞性:對于任何引用x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,則x.equals(z)返回也為true
一致性:如果x,y引用的對象沒有變化,則x.equals(y)應一直返回true
equals和等號的區別——重點
等號(==)
基本數據類型(也稱原始數據類型) :byte,short,char,int,long,float,double,boolean。他們之間的比較,應用雙等號(==),比較的是他們的值。
引用數據類型:當他們用(==)進行比較的時候,比較的是他們在內存中的存放地址(確切的說,是堆內存地址)
equals
方法的初始默認行為是比較對象的內存地址值
在一些類庫當中這個方法被重寫了,如String、Integer、Date,比較對象的成員變量值是否相同
合理的equals重寫邏輯
顯示參數聲明為Object
判斷是否引用同一對象
判斷是否為空
判斷是否屬于同一類
將比較對象轉換成相應類型的變量
域的比較
5.2.3 hashCode方法散列碼(hash code) 定義:是由對象導出的一個整型值
注意
字符串和基本數據類型的包裝類創建的對象存在hashCode相同的情況,因為是由內容導出的
public class TestHashCode { public static void main(String[] args) { String s1 = "a"; String s2 = "a"; Integer i = 10; Integer k = 10; System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); System.out.println(s1.equals(s2)); System.out.println(i.hashCode()); System.out.println(k.hashCode()); System.out.println(i.equals(k)); } }/* output 97 97 true 10 10 true */
如果重新定義equals方法,就必須重新定義hashCode方法,以便用戶可以將對象插入到散列表中。如果重新定義,會出現equals相等,hashCode不等——考點
5.2.4 toString方法用途:返回表示對象值的字符串
注意
toString方法常見的原因:當對象與一個字符串通過操作符+連接,編譯將自動使用toString方法
public class TestToString { String name = "asd"; public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString+"jkl"); } }/* output Five.TestToString.TestToString@1218025cjkl */
建議重寫toString方法,默認調用的方法可讀性較差
public class TestToString { String name = "asd"; @Override public String toString() { return "TestToString{" + "name="" + name + """ + "}"; } public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString+"jkl"); } }/* output TestToString{name="asd"}jkl */5.2.5 getClass方法
用途:返回包含對象信息的類對象
public class TestToString { String name = "asd"; public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString.getClass()); } }/* output class Five.TestToString.TestToString */5.3 泛型數組列表
泛型 定義:Java 泛型的參數只可以代表類,不能代表個別對象
1.ArrayList
定義:采用類型參數的泛型類
// 使用方法 ArrayListstaff = new ArrayList (); // 泛型的類型為Employee
規則
使用add方法增加新數據。如果空間用盡,則自動創建更大的數組,并將原數據拷貝到更大的數組中
使用size方法獲取實際元素數量
使用trimToSize將清除多余的存儲空間
使用get和set方法訪問和設置元素
注意
數組列表和數組大小的核心區別:數組分配100的空間是已經在內存中存在的;數組列表在僅是具備存儲100的潛力,即使是完成了初始化之后
使用時,指定泛型的類型。因為不指定泛型類型,存儲和修改數據接受任意類型對象,因為使用的是Object
5.4 對象包裝器和自動裝箱 1.自動裝箱
裝箱 定義:基本數據類型變換為基本類型的包裝類
// 裝箱 public class TestAutoBoxing { public static void main(String[] args) { ArrayListlist = new ArrayList (); list.add(5); // 等于 list.add(Integer.valueOf(5)); } }/* conclusion 1.list中的元素為Integer類型 2.當使用.add()方法添加時,被添加的類型為基本類型int 3.因此將自動變換為 list.add(Integer.valueOf(5)) */
注意
自動裝箱規范要求boolean,byte,char小于等于127,介于-128至127之間的short和int被包裝到固定的對象中。
原因是:IntegerCache.low 默認是-128;IntegerCache.high默認是127,超出范圍的將創建對象存儲,不然直接返回值。減少new,減輕jvm壓力。
public class TestAutoBoxing { public static void main(String[] args) { // 使用包裝類 Integer a = 127; Integer b = 127; Integer c = 128; Integer d = 128; System.out.println("a == b:"+(a == b)); System.out.println("c == d:"+(c == d)); } }/* output a == b:true c == d:false */
由于包裝器類引用可以為null,因此會出現NullPointerException
如果混合使用Integer和Double,Integer會拆箱,提升為double,然后裝箱為Double
自動拆箱和自動裝箱是編譯器認可的,不是虛擬機。
2.自動拆箱
拆箱 定義:將包裝類數據拆成基本類型數據
public class TestAutoBoxing { public static void main(String[] args) { // 裝箱 ArrayList5.5 參數可變的方法list = new ArrayList (); list.add(5); // 拆箱 int intType = list.get(0); // 等于 int intType = list.get(0).intValue(); } }/* conclusion 1.list中的元素為Integer類型 2.當使用.get()方法獲取時,獲得的值類型為Integer 3.因此將自動變換為 int intType = list.get(0).intValue(); */
參數可變 定義:支持用可變的參數數量調用的方法
格式
// 使用 ... Double ... args
// 同時接收多個參數 System.out.printf("%d %s",n,"name"); // 底層實現代碼 public PrintStream printf(String format, Object ... args) { return format(format, args); } /* conclusion 1.“String format”為格式字符串,“Object ... args”為Object對象的數組,因此數量可變 */
public class TestFindMax { static void findMax(Object ... args){ double largest = Double.NEGATIVE_INFINITY; for (Object y: args ) { Double z = (Double) y; if (z > largest) largest = z; } System.out.println(largest); } public static void main(String[] args) { TestFindMax.findMax(3.454,34.3); } }5.6 枚舉類
格式
enum EnumName{ MAX,MIN,DEDIUM; }
注意
枚舉類中是實例,因此能夠創建實例中的變量,但必須使用構造方法賦值
public class TestEnum { public enum Size{ MAX("max",3),MIN("min",1),MEDIUM("medium",2); // 成員變量 private String name; private int num; // 成員變量的構造方法 Size(String name , int i) { this.name = name; this.num = i; } } public static void main(String[] args) { // 在同一個類中,因此可以訪問私有的成員變量name String name = Size.MAX.name; System.out.println(name); } }5.7 反射——重點
反射 定義:支持分析類的能力的程序
反射機制:將類中的各個部分封裝成其他對象
原理圖
獲取Class對象的三種方式
Class.forName("全類名"):在第一階段,將字節碼文件加載進內存,然后獲取Class對象
多用于配置文件
類名.class:在第二階段,通過類名的class屬性
多用于參數的傳遞
對象.getClass():在第三階段,通過Object的getClass方法獲取
多用于對象的字節碼的獲取
public class TestReflectionClass { public static void main(String[] args) throws Exception { /* Class對象獲取的三種方式 1.通過Class.forclass("全類名")獲取 2.通過類名.class()獲取 3.通過對象.getClass()方法 */ // 1.通過Class.forclass("全類名")獲取 Class cls1 = Class.forName("Five.TestReflection.Person"); System.out.println(cls1); // 2.通過類名.class()獲取 Class cls2 = Person.class; System.out.println(cls2); // 3.通過對象.getClass()方法 Person p = new Person(); Class cls3 = p.getClass(); System.out.println(cls3); // 4.比較三個class引用所指向的是否為同一個Class對象 System.out.println("比較三個class引用所指向的是否為同一個Class對象"); System.out.println("cls1 == cls2:"+(cls1 == cls2)); System.out.println("cls1 == cls2:"+(cls1 == cls3)); } }/* output class Five.TestReflection.Person class Five.TestReflection.Person class Five.TestReflection.Person 比較三個class引用所指向的是否為同一個Class對象 cls1 == cls2:true cls1 == cls2:true */
注意
同一個字節碼文件(.class)在一次程序運行中只加載一次,所以三種獲取Class對象的方式獲取到的Class對象都是同一個
用途
在運行時分析類的能力
在運行時操作對象
實現通用的數組操作代碼
利用Mehtod對象,類似C++中的函數指針
5.7.1 Class類 1.Class對象中的功能
規則
Field[] getFields():獲取所有的public修飾的成員變量(包括超類)
Field getField():獲取指定的public修飾的成員變量(包括超類)
Field[] getDeclaredFields():獲取所有的成員變量(即使是private修飾,暴力反射)
Field getDeclaredField():獲取指定的成員變量(即使是private修飾,暴力反射)
注意
getFields和getDeclaredFields()獲取時,getFields能夠同時獲取到超類和子類中的public變量,getDeclaredFields()只能獲取到子類中的所有訪問修飾類型的變量
// 超類 public class Father { // 成員變量 private String priFatherName; private int priFatherAge; public String pubFatherName; public int pubFatherAge; } // 子類 public class Son extends Father { // 成員變量 private String priSonName; private int priSonAge; public String pubSonName; public int pubSonAge; }
// 測試類 package Five.TestReflection; import java.lang.reflect.Field; public class TestField { public static void main(String[] args) throws Exception { /* getField和getDeclaredField */ // getField System.out.println("--測試getField"); Field[] field1 = Son.class.getFields(); for (Field f : field1) { System.out.println(f); } // getDeclaredField System.out.println("--測試getDeclaredField"); Field[] field2 = Son.class.getDeclaredFields(); for (Field f : field2) { System.out.println(f); }}} /* output --測試getField public java.lang.String Five.TestReflection.Son.pubSonName public int Five.TestReflection.Son.pubSonAge public java.lang.String Five.TestReflection.Father.pubFatherName public int Five.TestReflection.Father.pubFatherAge --測試getDeclaredField private java.lang.String Five.TestReflection.Son.priSonName private int Five.TestReflection.Son.priSonAge public java.lang.String Five.TestReflection.Son.pubSonName public int Five.TestReflection.Son.pubSonAge */
Field對象方法
get(Object obj):返回的 Field表示字段的值,指定對象上
set(Object obj, Object value):設置域為代表的這 Field對象指定對象上的參數指定的新價值
setAccessible():忽略訪問修飾符的安全檢查,也稱為暴力反射(如果需要get或者set使用private修飾的變量,則需要使用該方法),用于調試,持久存儲,相似機制。
// 超類 public class Father { // 成員變量 private String priFatherName; private int priFatherAge; public String pubFatherName; public int pubFatherAge; } // 子類 public class Son extends Father { // 成員變量 private String priSonName; private int priSonAge; public String pubSonName; public int pubSonAge; }
// 測試類 package Five.TestReflection; import java.lang.reflect.Field; public class TestField { public static void main(String[] args) throws Exception { /* get和set方法 */ Son son = new Son(); // get,public System.out.println("--測試get方法,使用getField,作用于public修飾對象"); Field field3 = Son.class.getField("pubSonName"); Object value3 = field3.get(son); System.out.println(value3); // get,private System.out.println("--測試get方法,使用getField,作用于private修飾對象"); // 由于getField只能作用于public修飾的成員,因此無法訪問 // Field field4 = Son.class.getField("priSonName"); // field4.setAccessible(true); // Object value4 = field4.get(son); // System.out.println(value4); System.out.println("失敗"); // get,private System.out.println("--測試get方法,使用getDeclaredField,作用于private修飾對象"); Field field5 = Son.class.getDeclaredField("priSonName"); // 獲取前需要忽略訪問的安全檢查 field5.setAccessible(true); Object value5 = field5.get(son); System.out.println(value5); // set,public System.out.println("--測試set方法,使用getField,作用于public修飾對象"); Field field6 = Son.class.getField("pubSonName"); field6.set(son, "Toyz"); Object value6 = field6.get(son); System.out.println(value6); // set,private System.out.println("--測試set方法,使用getDeclaredField,作用于private修飾對象"); Field field7 = Son.class.getDeclaredField("priSonName"); // 獲取前需要忽略訪問的安全檢查 field7.setAccessible(true); Object value7 = field7.get(son); System.out.println("修改前,priSonName:"+value7); field7.set(son, "QQ"); value7 = field7.get(son); System.out.println("修改前,priSonName:"+value7); } } /* output --測試get方法,使用getField,作用于public修飾對象 null --測試get方法,使用getField,作用于private修飾對象 失敗 --測試get方法,使用getDeclaredField,作用于private修飾對象 null --測試set方法,使用getField,作用于public修飾對象 Toyz --測試set方法,使用getDeclaredField,作用于private修飾對象 修改前,priSonName:null 修改前,priSonName:QQ */
規則
getConstructor(類>... parameterTypes):獲取public修飾的指定構造方法(不含超類)
getConstructors():獲取public修飾的所有構造方法(不含超類)
getDeclaredConstructor(類>... parameterTypes):獲取指定構造方法(包括private修飾,暴力反射,不含超類)
getDeclaredConstructors():獲取所有構造方法(包括private修飾,暴力反射,不含超類)
獲取構造方法,無法獲得超類,原因是構造方法無法被繼承,因此無法獲取
// 超類 public class Father { public Father(String priFatherName , int priFatherAge , String pubFatherName , int pubFatherAge) { this.priFatherName = priFatherName; this.priFatherAge = priFatherAge; this.pubFatherName = pubFatherName; this.pubFatherAge = pubFatherAge; } public Father() { } private Father(String priFatherName , int priFatherAge){ this.priFatherName = priFatherName; this.priFatherAge = priFatherAge; } } // 子類 public class Son extends Father { public Son(String priSonName , int priSonAge , String pubSonName , int pubSonAge) { this.priSonName = priSonName; this.priSonAge = priSonAge; this.pubSonName = pubSonName; this.pubSonAge = pubSonAge; } public Son(){} private Son(String priSonName , int priSonAge){ this.priSonName = priSonName; this.priSonAge = priSonAge; } }
// 測試類 public class TestConstructor { public static void main(String[] args) throws Exception { /* getConstructor和getDeclaredConstructor */ // getConstructor,無參構造器和有參構造器 System.out.println("--測試getConstructor"); Constructor constructor1 = Son.class.getConstructor(); System.out.println("無參構造器:"+constructor1); Constructor constructor2 = Son.class.getConstructor(String.class,int.class,String.class,int.class); System.out.println("有參構造器:"+constructor2); // getConstructors System.out.println("--測試getConstructors"); Constructor[] constructors3 = Son.class.getConstructors(); for (Constructor c : constructors3) { System.out.println(c); } // getDeclaredConstructor System.out.println("--測試getDeclaredConstructor"); Constructor constructor4 = Son.class.getDeclaredConstructor(String.class,int.class); System.out.println(constructor4); // getDeclaredConstructors System.out.println("--測試getDeclaredConstructors"); Constructor[] constructor5 = Son.class.getDeclaredConstructors(); for (Constructor c : constructor5){ System.out.println(c); } } } /* output --測試getConstructor 無參構造器:public Five.TestReflection.Son() 有參構造器:public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) --測試getConstructors public Five.TestReflection.Son() public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) --測試getDeclaredConstructor private Five.TestReflection.Son(java.lang.String,int) --測試getDeclaredConstructors private Five.TestReflection.Son(java.lang.String,int) public Five.TestReflection.Son() public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) */
Constructor對象方法
newInstance(Object... initargs):利用這 Constructor對象創建和初始化的構造函數的聲明類的一個新實例構造函數,用指定的初始化參數。
// 測試類 public class TestConstructor { public static void main(String[] args) throws Exception { /* newInstance(Object... initargs) */ // newInstance(Object... initargs)無參構造器 System.out.println("--newInstance(Object... initargs) 無參構造器"); Constructor constructor6 = Son.class.getConstructor(); System.out.println(constructor6.newInstance()); // newInstance(Object... initargs)含參構造器 System.out.println("--newInstance(Object... initargs) 含參構造器"); Constructor constructor7 = Son.class.getDeclaredConstructor(String.class,int.class); constructor7.setAccessible(true); // 忽略訪問的安全檢查 System.out.println(constructor7.newInstance("Toyz",44)); } } /* output --newInstance(Object... initargs) 無參構造器 Son{priSonName="null", priSonAge=0, pubSonName="null", pubSonAge=0} --newInstance(Object... initargs) 含參構造器 Son{priSonName="Toyz", priSonAge=44, pubSonName="null", pubSonAge=0} */
規則
getMethod(String name, 類>... parameterTypes):獲取public修飾的指定方法(含超類)
getMethods():獲取public修飾的指定方法(含超類)
getDeclaredMethod(String name, 類>... parameterTypes):獲取指定方法(包括private修飾,暴力反射,不含超類)
getDeclaredMethods():獲取所有方法(包括private修飾,暴力反射,不含超類)
// 超類 public class Father { // 方法 public void eat(){ System.out.println("father eat..."); } public void eat(String food){ System.out.println("father eat..."+food); } public void edu(){ System.out.println("father edu..."); }; private void run(){ System.out.println("father run..."); } } // 子類 public class Son extends Father { // 方法 public void eat(){ System.out.println("son eat..."); } public void eat(String food){ System.out.println("son eat..."+food); } private void run(){ System.out.println("son run..."); } }
// 測試類 public class TestMethod { public static void main(String[] args) throws Exception { /* getMethod和getDeclaredMethod */ Son son = new Son(); // getMethod,空參方法 System.out.println("--測試getMethod,空參方法"); Method method1 = Son.class.getMethod("eat"); System.out.println(method1); // getMethods,所有方法 System.out.println("--測試getMethods"); Method[] method2 = Son.class.getMethods(); for (Method m : method2) { System.out.println(m); } // getDeclaredMethods,所有方法 System.out.println("--測試getDeclaredMethods"); Method[] method3 = Son.class.getDeclaredMethods(); for (Method m : method3) { System.out.println(m); }}} /* output --測試getMethod,空參方法 public void Five.TestReflection.Son.eat() --測試getMethods public java.lang.String Five.TestReflection.Son.toString() public void Five.TestReflection.Son.eat(java.lang.String) public void Five.TestReflection.Son.eat() public void Five.TestReflection.Father.edu() public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() --測試getDeclaredMethods private void Five.TestReflection.Son.run() public java.lang.String Five.TestReflection.Son.toString() public void Five.TestReflection.Son.eat(java.lang.String) public void Five.TestReflection.Son.eat() */
Method對象方法
invoke(Object obj, Object... args):第一個參數為隱式參數,靜態方法時為null。調用底層的方法,這 方法對象表示,對指定對象的指定參數。能夠調用超類的方法
// 測試類 public class TestMethod { public static void main(String[] args) throws Exception { /* invoke */ // invoke,含參子類public方法 System.out.println("--測試invoke,含參子類public方法"); Method method4 = Son.class.getMethod("eat",String.class); method4.invoke(son, "Fish"); // invoke,含參父類public方法 System.out.println("--測試invoke,含參父類public方法"); Method method5 = Son.class.getMethod("edu"); method5.invoke(son); // invoke,無參子類private方法 System.out.println("--測試invoke,無參子類private方法"); Method method6 = Son.class.getDeclaredMethod("run"); method6.setAccessible(true); method6.invoke(son); } } /* output --測試invoke,含參子類public方法 son eat...Fish --測試invoke,含參父類public方法 father edu... --測試invoke,無參子類private方法 son run... */2.Practice(反射)
要求:寫一個“框架”在不改動代碼的前提下,通過配置文件實現創建任意類的對象,執行任意方法
步驟
將需要創建的類和執行的方法寫在配置文件中
在程序中讀取配置文件
使用反射將類加載進內存
創建對象
執行方法
實現
創建類(配置文件需要用到的示范類)
package Five.TestReflection; public class Father { public Father() { } // 方法 public void eat(){ System.out.println("father eat..."); } }
創建配置文件
className=Five.TestReflection.Father methodName=eat
讀取并執行
package Five.TestReflection; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; public class TestReflection { public static void main(String[] args) throws Exception { // 1.加載配置文件 // 1.1創建pro對象 Properties properties = new Properties(); // 1.2加載配置文件,轉換為集合 // 1.2.1獲取配置文件路徑 ClassLoader classLoader = TestReflection.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("pro.properties"); properties.load(is); // 2.獲取配置文件中定義的數據 String className = properties.getProperty("className"); String methodName = properties.getProperty("methodName"); // 3.加載類進內存 Class cls1 = Class.forName(className); // 4.創建對象-反射 Object object = cls1.newInstance(); // 5.執行方法-反射 Method method1 = cls1.getMethod(methodName); method1.invoke(object); } } /* output father eat... */
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75962.html
摘要:在這一步里,將配置文件的信息裝入到容器的定義注冊表中,但此時還未初始化。注冊后處理器根據反射機制從中找出所有類型的,并將它們注冊到容器后處理器的注冊表中。是屬性編輯器的注冊表,主要作用就是注冊和保存屬性編輯器。 點擊進入我的博客 1 Spring容器整體流程 1.1 ApplicationContext內部原理 AbstractApplicationContext是Applicati...
摘要:哪吒社區技能樹打卡打卡貼函數式接口簡介領域優質創作者哪吒公眾號作者架構師奮斗者掃描主頁左側二維碼,加入群聊,一起學習一起進步歡迎點贊收藏留言前情提要無意間聽到領導們的談話,現在公司的現狀是碼農太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區Java技能樹打卡?【打卡貼 day2...
摘要:動態代理又被稱為代理或接口代理。靜態代理在編譯時產生字節碼文件,可以直接使用,效率高。代理無需實現接口,通過生成類字節碼實現代理,比反射稍快,不存在性能問題,但會繼承目標對象,需要重寫方法,所以目標對象不能為類。 一、代理模式介紹 代理模式是一種設計模式,提供了對目標對象額外的訪問方式,即通過代理對象訪問目標對象,這樣可以在不修改原目標對象的前提下,提供額外的功能操作,擴展目標對象的功...
摘要:注解概念注解也被成為元數據為我們在代碼中添加信息提供了一種形式化的方式,使我們可以在稍后的某個時刻更容易的使用這些數據。 注解 概念 注解(也被成為元數據)為我們在代碼中添加信息提供了一種形式化的方式,使我們可以在稍后的某個時刻更容易的使用這些數據。 注解是 Java 5 所引入的眾多語言變化之一: 注解使得我們可以以編譯器驗證的格式存儲程序的額外信息 注解可以生成描述符文件,甚至是...
摘要:項目地址前言大數據技術棧思維導圖大數據常用軟件安裝指南一分布式文件存儲系統分布式計算框架集群資源管理器單機偽集群環境搭建集群環境搭建常用命令的使用基于搭建高可用集群二簡介及核心概念環境下的安裝部署和命令行的基本使用常用操作分區表和分桶表視圖 項目GitHub地址:https://github.com/heibaiying... 前 言 大數據技術棧思維導圖 大數據常用軟件安裝指...
閱讀 3564·2023-04-26 02:05
閱讀 2003·2021-11-19 11:30
閱讀 4202·2021-09-30 09:59
閱讀 3175·2021-09-10 10:51
閱讀 2605·2021-09-01 10:30
閱讀 1470·2021-08-11 11:20
閱讀 2615·2019-08-30 15:54
閱讀 563·2019-08-30 10:49