工作3年的程式設計師,一次電話Java面試的問題總結

程式設計師生態圈發表於2018-09-09

面試涉及問題含有:

Java

JDK8新特性

集合(雜湊衝突、HashMap的原理、自動排序的集合TreeSet)

多執行緒安全問題

String和StringBuffer

JVM

原理、執行流程、內部結構

Linux

查詢含有某字串內容的命令grep

查詢程式、GC狀態、殺死程式

Hadoop五種節點介紹

--------------------------------------------------------------------------------------------------------

JAVA:

1、JDK8新特性:

Lambda 表示式(閉包)− Lambda允許把函式作為一個方法的引數,函式作為引數傳遞進方法中。

lambda表示式的重要特徵:

可選型別宣告:不需要宣告引數型別,編譯器可以統一識別引數值。

可選的引數圓括號:一個引數無需定義圓括號,但多個引數需要定義圓括號。

可選的大括號:如果主體包含了一個語句,就不需要使用大括號。

可選的返回關鍵字:如果主體只有一個表示式返回值則編譯器會自動返回值,大括號需要指定明表示式返回了一個數值。

Lambda的設計 可以實現簡潔而緊湊的語言結構。最簡單的Lambda表示式可 由逗號分隔的引數列表、->符號和語句塊 組成,例如:

Arrays.asList("a","b","d").forEach( e ->System.out.println( e ) );Arrays.asList("a","b","d").forEach( ( String e ) -> System.out.println( e ) );Arrays.asList("a","b","d").forEach( e -> {    System.out.print( e );    System.out.print( e );} );Stringseparator= ",";Arrays.asList("a","b","d").forEach(    ( String e ) -> System.out.print( e + separator ) );Arrays.asList("a","b","d").sort( ( e1, e2 ) -> e1.compareTo( e2 ) );等同於Arrays.asList("a","b","d").sort( ( e1, e2 ) -> {    int result = e1.compareTo( e2 );returnresult;} );

方法引用− 方法引用提供了非常有用的語法,可以直接引用已有Java類或物件(例項)的方法或構造器。與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘程式碼。

方法引用通過方法的名字來指向一個方法。

方法引用可以使語言的構造更緊湊簡潔,減少冗餘程式碼。

方法引用使用一對冒號   ::  。

Java8使用兩個新概念擴充套件了介面的含義:預設方法和靜態方法。預設方法使得介面有點類似traits,不過要實現的目標不一樣。預設方法使得開發者可以在 不破壞二進位制相容性的前提下,往現存介面中新增新的方法,即不強制那些實現了該介面的類也同時實現這個新加的方法。預設方法和抽象方法之間的區別在於抽象方法需要實現,而預設方法不需要。介面提供的預設方法會被介面的實現類繼承或者覆寫,例子程式碼如下:privateinterfaceDefaulable{defaultStringnotRequired(){return"Default implementation";    }        }privatestaticclassDefaultableImplimplementsDefaulable{}privatestaticclassOverridableImplimplementsDefaulable{@OverridepublicStringnotRequired(){return"Overridden implementation";    }}Defaulable介面使用關鍵字default定義了一個預設方法notRequired()。DefaultableImpl類實現了這個介面,同時預設繼承了這個介面中的預設方法;OverridableImpl類也實現了這個介面,但覆寫了該介面的預設方法,並提供了一個不同的實現。Java8帶來的另一個有趣的特性是在介面中可以定義靜態方法,例子程式碼如下:privateinterfaceDefaulableFactory{// Interfaces now allow static methodsstaticDefaulablecreate( Supplier< Defaulable > supplier ){returnsupplier.get();    }}下面的程式碼片段整合了預設方法和靜態方法的使用場景:publicstaticvoidmain( String[] args ){    Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new);    System.out.println( defaulable.notRequired() );    defaulable = DefaulableFactory.create( OverridableImpl::new);    System.out.println( defaulable.notRequired() );}輸出結果如下:Default implementationOverridden implementation

預設方法− 預設方法就是一個在介面裡面有了一個實現的方法。

privateinterfaceDefaulableFactory{// Interfaces now allow static methodsstaticDefaulablecreate( Supplier< Defaulable > supplier ){returnsupplier.get();    }}

新工具− 新的編譯工具,如:Nashorn引擎 jjs、 類依賴分析器jdeps。

Stream API−新新增的Stream API(java.util.stream) 把真正的函數語言程式設計風格引入到Java中。

Date Time API− 加強對日期與時間的處理。

Optional 類− Optional 類已經成為 Java 8 類庫的一部分,用來解決空指標異常。

Nashorn, JavaScript 引擎− Java 8提供了一個新的Nashorn javascript引擎,它允許我們在JVM上執行特定的javascript應用。

重複註解:

自從Java 5中引入 註解 以來,這個特性開始變得非常流行,並在各個框架和專案中被廣泛使用。不過,註解有一個很大的限制是:在同一個地方不能多次使用同一個註解。Java 8打破了這個限制,引入了重複註解的概念,允許在同一個地方多次使用同一個註解。

在Java 8中使用@Repeatable註解定義重複註解,實際上,這並不是語言層面的改進,而是編譯器做的一個trick,底層的技術仍然相同。可以利用下面的程式碼說明:

packagecom.javacodegeeks.java8.repeatable.annotations;importjava.lang.annotation.ElementType;importjava.lang.annotation.Repeatable;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;publicclassRepeatingAnnotations{@Target( ElementType.TYPE )@Retention( RetentionPolicy.RUNTIME )public@interfaceFilters {        Filter[] value();    }@Target( ElementType.TYPE )@Retention( RetentionPolicy.RUNTIME )@Repeatable( Filters.class )public@interfaceFilter {        String value();    };@Filter("filter1")@Filter("filter2")publicinterfaceFilterable{            }publicstatic void main(String[] args) {for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class) ) {            System.out.println( filter.value() );        }    }}

正如我們所見,這裡的Filter類使用@Repeatable(Filters.class)註解修飾,而Filters是存放Filter註解的容器,編譯器儘量對開發者遮蔽這些細節。這樣,Filterable介面可以用兩個Filter註解註釋(這裡並沒有提到任何關於Filters的資訊)。

另外,反射API提供了一個新的方法:getAnnotationsByType(),可以返回某個型別的重複註解,例如 Filterable.class.getAnnoation(Filters.class) 將返回兩個Filter例項,輸出到控制檯的內容如下所示: filter1 filter2

2、集合:

雜湊衝突:

(見部落格:https://www.cnblogs.com/wuchaodzxx/p/7396599.html)

如果兩個不同的元素,通過雜湊函式得出的實際儲存地址相同怎麼辦?也就是說,當我們對某個元素進行雜湊運算,得到一個儲存地址,然後要進行插入的時候,發現已經被其他元素佔用了,其實這就是所謂的雜湊衝突,也叫雜湊碰撞。

雜湊函式的設計至關重要,好的雜湊函式會盡可能地保證 計算簡單和雜湊地址分佈均勻,但是,我們需要清楚的是,陣列是一塊連續的固定長度的記憶體空間,再好的雜湊函式也不能保證得到的儲存地址絕對不發生衝突。那麼雜湊衝突如何解決呢? 雜湊衝突的解決方案有多種: 開放定址法(發生衝突,繼續尋找下一塊未被佔用的儲存地址),再雜湊函式法,鏈地址法,而HashMap即是採用了鏈地址法,也就是陣列+連結串列的方式。

(1)開放定址法

這種方法也稱再雜湊法,其基本思想是:當關鍵字 key的雜湊地址 p=H( key)出現衝突時,以p為基礎,產生另一個雜湊地址 p1,如果 p1仍然衝突,再以 p為基礎,產生另一個雜湊地址 p2,…,直到找出一個不衝突的雜湊地址 pi ,將相應元素存入其中。這種方法有一個通用的再雜湊函式形式:

Hi=( H( key) +d i ) % m   i=1, 2,…, n

其中 H( key)為雜湊函式, m 為表長, d i 稱為增量序列。增量序列的取值方式不同,相應的再雜湊方式也不同。主要有以下三種:

線性探測再雜湊

d i i=1, 2, 3, …, m-1

這種方法的特點是:衝突發生時,順序檢視錶中下一單元,直到找出一個空單元或查遍全表。

二次探測再雜湊

d i =1 2 , -1 2 , 2 2 , -2 2 , …, k 2 , -k 2 ( k<=m/2 )

這種方法的特點是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。

偽隨機探測再雜湊

d i =偽隨機數序列。

(2) 再雜湊法

這種方法是同時構造多個不同的雜湊函式:

H i =RH 1 ( key) i=1, 2, …, k

當雜湊地址 H i =RH 1 ( key)發生衝突時,再計算 H i =RH 2 ( key)……,直到衝突不再產生。這種方法不易產生聚集,但增加了計算時間。

(3) 鏈地址法

這種方法的基本思想是將所有雜湊地址為 i的元素構成一個稱為同義詞鏈的單連結串列,並將單連結串列的頭指標存在雜湊表的第 i個單元中,因而查詢、插入和刪除主要在同義詞鏈中進行。鏈地址法適用於經常進行插入和刪除的情況。

(4)建立公共溢位區

這種方法的基本思想是:將雜湊表分為基本表和溢位表兩部分,凡是和基本表發生衝突的元素,一律填入溢位表。

HashMap的底層原理:

見部落格:https://www.cnblogs.com/chengxiao/p/6059914.html

HashMap的主幹是一個 Entry陣列 。Entry是HashMap的基本組成單元,每一個Entry包含一個key-value鍵值對。

//HashMap的主幹陣列,可以看到就是一個Entry陣列,初始值為空陣列{},主幹陣列的長度一定是2的次冪,至於為什麼這麼做,後面會有詳細分析。transient Entry[] table = (Entry[]) EMPTY_TABLE;

Entry是HashMap中的一個靜態內部類。程式碼如下:

staticclassEntryimplementsMap.Entry{finalK key;        V value;        Entry next;//儲存指向下一個Entry的引用,單連結串列結構inthash;//對key的hashcode值進行hash運算後得到的值,儲存在Entry,避免重複計算/**        * Creates new entry.        */Entry(inth, K k, V v, Entry n) {            value = v;            next = n;            key = k;            hash = h;        }

簡單來說,HashMap由陣列+連結串列組成的,陣列是HashMap的主體,連結串列則是主要為了解決雜湊衝突而存在的,如果定位到的陣列位置不含連結串列(當前entry的next指向null),那麼對於查詢,新增等操作很快,僅需一次定址即可;如果定位到的陣列包含連結串列,對於新增操作,其時間複雜度為O(n),首先遍歷連結串列,存在即覆蓋,否則新增;對於查詢操作來講,仍需遍歷連結串列,然後通過key物件的equals方法逐一比對查詢。所以,效能考慮,HashMap中的連結串列出現越少,效能才會越好。

自動排序的集合:

TreeSet(樹集)是一個有序集合,可以按照任何順序將元素插入該集合,當對該集合進行迭代時,各個值將自動以排序後的順序出現。 TreeSet中的元素按照升序排列,預設是按照自然順序進行排序,意味著TreeSet中的元素要實現Comparable介面,或者有一個自定義的比較器Comparator。

TreeSet底層使用的是TreeMap,TreeMap的底層實現是紅黑樹(詳細見 http://www.cnblogs.com/xujian2014/p/4645943.html )。

publicTreeSet(){this(newTreeMap()); }

使用示例:

publicclassTest{publicstaticvoidmain(String[] args){        TreeSet treeSet=newTreeSet<>();        treeSet.add("Bili");        treeSet.add("Amy");        treeSet.add("cDy");for(Stringstring: treeSet)        {            System.out.println(string);        } }

由於String類實現了Comparable介面,它的compareTo方法是按照字典順序來對字串進行排序,所以結果如下:

注意:

1、TreeSet的排列順序必須是全域性順序,也就是說任何兩個元素都是必須可比的,同時只有當他們比較相同時才返回0。

2、如果樹集包含了n個元素,那麼平均需要進行log 2 n次比較,才能找到新元素的正確位置。

3、執行緒:

多執行緒安全執行:

在多個執行緒併發執行訪問同一個資料時,如果不採取相應的措施,將會是非常危險的。為避免這種情況發生,我們要將多個執行緒對同一資料的訪問同步,確保執行緒安全。

所謂同步(synchronization)就是指一個執行緒訪問資料時,其它執行緒不得對同一個資料進行訪問,即同一時刻只能有一個執行緒訪問該資料,當這一執行緒訪問結束時其它執行緒才能對這它進行訪問。 同步最常見的方式就是使用鎖(Lock),也稱為執行緒鎖 。鎖是一種非強制機制,每一個執行緒在訪問資料或資源之前,首先試圖獲取(Acquire)鎖,並在訪問結束之後釋放(Release)鎖。在鎖被佔用時試圖獲取鎖,執行緒會進入等待狀態,直到鎖被釋放再次變為可用。

Java裡面一般用以下幾種機制保證執行緒安全:

1.互斥同步鎖(悲觀鎖)

1)Synchorized

2)ReentrantLock

互斥同步鎖也叫做阻塞同步鎖,特徵是會對沒有獲取鎖的執行緒進行阻塞。

要理解互斥同步鎖,首選要明白什麼是互斥什麼是同步。簡單的說互斥就是非你即我,同步就是順序訪問。互斥同步鎖就是以互斥的手段達到順序訪問的目的。作業系統提供了很多互斥機制比如訊號量,互斥量,臨界區資源等來控制在某一個時刻只能有一個或者一組執行緒訪問同一個資源。

Java裡面的互斥同步鎖就是Synchorized和ReentrantLock,前者是由語言級別實現的互斥同步鎖,理解和寫法簡單但是機制笨拙,在JDK6之後效能優化大幅提升,即使在競爭激烈的情況下也能保持一個和ReentrantLock相差不多的效能,所以JDK6之後的程式選擇不應該再因為效能問題而放棄synchorized。ReentrantLock是API層面的互斥同步鎖,需要程式自己開啟並在finally中關閉鎖,和synchorized相比更加的靈活,體現在三個方面:等待可中斷,公平鎖以及繫結多個條件。但是如果程式猿對ReentrantLock理解不夠深刻,或者忘記釋放lock,那麼不僅不會提升效能反而會帶來額外的問題。另外synchorized是JVM實現的,可以通過監控工具來監控鎖的狀態,遇到異常JVM會自動釋放掉鎖。而ReentrantLock必須由程式主動的釋放鎖。

互斥同步鎖都是可重入鎖,好處是可以保證不會死鎖。但是因為涉及到核心態和使用者態的切換,因此比較消耗效能。JVM開發團隊在JDK5-JDK6升級過程中採用了很多鎖優化機制來優化同步無競爭情況下鎖的效能。比如:自旋鎖和適應性自旋鎖,輕量級鎖,偏向鎖,鎖粗化和鎖消除。

2.非阻塞同步鎖

1) 原子類(CAS)

非阻塞同步鎖也叫樂觀鎖,相比悲觀鎖來說,它會先進行資源在工作記憶體中的更新,然後根據與主存中舊值的對比來確定在此期間是否有其他執行緒對共享資源進行了更新,如果舊值與期望值相同,就認為沒有更新,可以把新值寫回記憶體,否則就一直重試直到成功。它的實現方式依賴於處理器的機器指令:CAS(Compare And Swap)

JUC中提供了幾個Automic類以及每個類上的原子操作就是樂觀鎖機制。

不激烈情況下,效能比synchronized略遜,而激烈的時候,也能維持常態。激烈的時候,Atomic的效能會優於ReentrantLock一倍左右。但是其有一個缺點,就是隻能同步一個值,一段程式碼中只能出現一個Atomic的變數,多於一個同步無效。因為他不能在多個Atomic之間同步。

非阻塞鎖是不可重入的,否則會造成死鎖。

3.無同步方案

1)可重入程式碼

在執行的任何時刻都可以中斷-重入執行而不會產生衝突。特點就是不會依賴堆上的共享資源

2)ThreadLocal/Volaitile

執行緒本地的變數,每個執行緒獲取一份共享變數的拷貝,單獨進行處理。

3)  執行緒本地儲存

如果一個共享資源一定要被多執行緒共享,可以儘量讓一個執行緒完成所有的處理操作,比如生產者消費者模式中,一般會讓一個消費者完成對佇列上資源的消費。典型的應用是基於請求-應答模式的web伺服器的設計

4、String和StringBuffer

(1)String:是物件不是原始型別.為不可變物件,一旦被建立,就不能修改它的值.對於已經存在的String物件的修改都是重新建立一個新的物件,然後把新的值儲存進去.String 是final類,即不能被繼承

String的值是不可變的,這就導致每次對String的操作都會生成新的String物件,不僅效率低下,而且大量浪費有限的記憶體空間。

String a = "a"; //假設a指向地址0x0001 

a = "b";//重新賦值後a指向地址0x0002,但0x0001地址中儲存的"a"依舊存在,但已經不再是a所指向的,a 已經指向了其它地址。 

因此String的操作都是改變賦值地址而不是改變值操作。

(2)StringBuffer:是一個可變物件,當對他進行修改的時候不會像String那樣重新建立物件。它只能通過建構函式來建立物件被建立以後,在記憶體中就會分配記憶體空間,並初始儲存一個null.向StringBuffer中賦值的時候可以通過它的 append方法 .

StringBuffer是可變類,和執行緒安全的字串操作類,任何對它指向的字串的操作都不會產生新的物件。 每個StringBuffer物件都有一定的緩衝區容量,當字串大小沒有超過容量時,不會分配新的容量,當字串大小超過容量時,會自動增加容量。

StringBuffer buf=new StringBuffer(); //分配長16位元組的字元緩衝區 

StringBuffer buf=new StringBuffer(512); //分配長512位元組的字元緩衝區 

StringBuffer buf=new StringBuffer("this is a test")//在緩衝區中存放了字串,並在後面預留了16位元組的空緩衝區。 

:heartpulse:StringBuffer類中的方法要偏重於對字串的變化例如追加、插入和刪除等,這個也是StringBuffer和String類的主要區別。

1、append方法

public StringBuffer append(boolean b)

該方法的作用是追加內容到當前StringBuffer物件的末尾,類似於字串的連線。呼叫該方法以後,StringBuffer物件的內容也發生改變

2、deleteCharAt方法

public StringBuffer deleteCharAt(int index)

該方法的作用是刪除指定位置的字元,然後將剩餘的內容形成新的字串。例如:

StringBuffer sb = new StringBuffer(“Test”);

sb. deleteCharAt(1);

該程式碼的作用刪除字串物件sb中索引值為1的字元,也就是刪除第二個字元,剩餘的內容組成一個新的字串。所以物件sb的值變為”Tst”。

還存在一個功能類似的delete方法:

public StringBuffer delete(int start,int end)

該方法的作用是刪除指定區間以內的所有字元,包含start,不包含end索引值的區間。例如:

StringBuffer sb = new StringBuffer(“TestString”);

sb. delete (1,4);

該程式碼的作用是刪除索引值1(包括)到索引值4(不包括)之間的所有字元,剩餘的字元形成新的字串。則物件sb的值是”TString”。

3、insert方法

public StringBuffer insert(int offset, String s)

該方法的作用是在StringBuffer物件中插入內容,然後形成新的字串。例如:

StringBuffer sb = new StringBuffer(“TestString”);

sb.insert(4,“false”);

該示例程式碼的作用是在物件sb的索引值4的位置插入字串false,形成新的字串,則執行以後物件sb的值是”TestfalseString”。

4、reverse方法

public StringBuffer reverse()

該方法的作用是將StringBuffer物件中的內容反轉,然後形成新的字串。例如:

StringBuffer sb = new StringBuffer(“abc”);

sb.reverse();

經過反轉以後,物件sb中的內容將變為”cba”。

5、setCharAt方法

public void setCharAt(int index, char ch)

該方法的作用是修改物件中索引值為index位置的字元為新的字元ch。例如:

StringBuffer sb = new StringBuffer(“abc”);

sb.setCharAt(1,’D’);

則物件sb的值將變成”aDc”。

6、trimToSize方法

public void trimToSize()

該方法的作用是將StringBuffer物件的中儲存空間縮小到和字串長度一樣的長度,減少空間的浪費。

7、構造方法:

StringBuffer s0=new StringBuffer();分配了長16位元組的字元緩衝區

StringBuffer s1=new StringBuffer(512);分配了512位元組的字元緩衝區

8、獲取字串的長度: length()

StringBuffer s = new StringBuffer("www");

int i=s.length();

m.返回字串的一部分值

substring(int start) //返回從start下標開始以後的字串

substring(int start,int end) //返回從start到 end-1字串

9.替換字串

replace(int start,int end,String str)

s.replace(0,1,"qqq");

10.轉換為不變字串:toString()。

StringBuffer和StringBuilder類功能基本相似,主要區別在於StringBuffer類的方法是多執行緒、安全的,而 StringBuilder不是執行緒安全的,相比而言,StringBuilder類會略微快一點。對於經常要改變值的字串應該使用 StringBuffer和StringBuilder類。

執行緒安全 

StringBuffer 執行緒安全 

StringBuilder 執行緒不安全 

速度 

一般情況下,速度從快到慢:StringBuilder>StringBuffer>String,這種比較是相對的,不是絕對的。 

總結 

(1)如果要操作少量的資料用 = String 

(2)單執行緒操作字串緩衝區 下操作大量資料 = StringBuilder 

(3)多執行緒操作字串緩衝區 下操作大量資料 = StringBuffer

JVM:

1、執行流程

java程式經過一次編譯之後,將java程式碼編譯為位元組碼也就是class檔案,然後在不同的作業系統上依靠不同的java虛擬機器進行解釋,最後再轉換為不同平臺的機器碼,最終得到執行。這樣我們是不是可以推演,如果要在mac系統上執行,是不是隻需要安裝mac java虛擬機器就行了。那麼瞭解了這個基本原理後,我們嘗試去做更深的研究,一個普通的java程式它的執行流程到底是怎樣的呢?例如我們寫了一段這樣的程式碼:

public class HelloWorld { public static void main(String[] args) { System.out.print("Hello world"); } }

這段程式從編譯到執行,最終列印出“Hello world”中間經過了哪些步驟呢?我們直接上圖:

2、內部結構

class檔案被jvm裝載以後,經過jvm的記憶體空間調配,最終是由執行引擎完成class檔案的執行。當然這個過程還有其他角色模組的協助,這些模組協同配合才能讓一個java程式成功的執行

3、JVM記憶體空間包含:方法區、java堆、java棧、本地方法棧。

方法區是各個執行緒共享的區域,存放類資訊、常量、靜態變數。

java堆也是執行緒共享的區域,我們的類的例項就放在這個區域,可以想象你的一個系統會產生很多例項,因此java堆的空間也是最大的。如果java堆空間不足了,程式會丟擲OutOfMemoryError異常。

java棧是每個執行緒私有的區域,它的生命週期與執行緒相同,一個執行緒對應一個java棧,每執行一個方法就會往棧中壓入一個元素,這個元素叫“棧幀”,而棧幀中包括了方法中的區域性變數、用於存放中間狀態值的操作棧,這裡面有很多細節,我們以後再講。如果java棧空間不足了,程式會丟擲StackOverflowError異常,想一想什麼情況下會容易產生這個錯誤,對,遞迴,遞迴如果深度很深,就會執行大量的方法,方法越多java棧的佔用空間越大。

本地方法棧角色和java棧類似,只不過它是用來表示執行本地方法的,本地方法棧存放的方法呼叫本地方法介面,最終呼叫本地方法庫,實現與作業系統、硬體互動的目的。

PC暫存器,說到這裡我們的類已經載入了,例項物件、方法、靜態變數都去了自己改去的地方,那麼問題來了,程式該怎麼執行,哪個方法先執行,哪個方法後執行,這些指令執行的順序就是PC暫存器在管,它的作用就是控制程式指令的執行順序。

執行引擎當然就是根據PC暫存器調配的指令順序,依次執行程式指令。

Java程式設計師交流基地:236283328

LINUX:

1、查詢檔案內容命令:

在使用linux時,經常需要進行檔案查詢。其中查詢的命令主要有find和grep。兩個命令是有區的。

區別:(1)find命令是根據 檔案的屬性 進行查詢,如檔名,檔案大小,所有者,所屬組,是否為空,訪問時間,修改時間等。

(2)grep是根據 檔案的內容進行 查詢,會對檔案的每一行按照給定的模式(patter)進行匹配查詢。

一.find命令

基本格式:find  path expression

1.按照檔名查詢

(1)find / -name httpd.conf#在根目錄下查詢檔案httpd.conf,表示在整個硬碟查詢

(2)find /etc -name httpd.conf#在/etc目錄下檔案httpd.conf

(3)find /etc -name '*srm*'#使用萬用字元*(0或者任意多個)。表示在/etc目錄下查詢檔名中含有字串‘srm’的檔案

(4)find . -name 'srm*' #表示當前目錄下查詢檔名開頭是字串‘srm’的檔案

2.按照檔案特徵查詢

(1)find / -amin -10 # 查詢在系統中最後10分鐘訪問的檔案(access time)

(2)find / -atime -2 # 查詢在系統中最後48小時訪問的檔案

(3)find / -empty # 查詢在系統中為空的檔案或者資料夾

(4)find / -group cat # 查詢在系統中屬於 group為cat的檔案

(5)find / -mmin -5 # 查詢在系統中最後5分鐘裡修改過的檔案(modify time)

(6)find / -mtime -1 #查詢在系統中最後24小時裡修改過的檔案

(7)find / -user fred #查詢在系統中屬於fred這個使用者的檔案

(8)find / -size +10000c#查詢出大於10000000位元組的檔案(c:位元組,w:雙字,k:KB,M:MB,G:GB)

(9)find / -size -1000k #查詢出小於1000KB的檔案

3.使用混合查詢方式查詢檔案

引數有: !,-and(-a),-or(-o)。

(1)find /tmp -size +10000c -and -mtime +2 #在/tmp目錄下查詢大於10000位元組並在最後2分鐘內修改的檔案

(2)find / -user fred -or -user george #在/目錄下查詢使用者是fred或者george的檔案檔案

(3)find /tmp ! -user panda#在/tmp目錄中查詢所有不屬於panda使用者的檔案

二、grep命令

 基本格式:find  expression

命令:grep 

格式:grep [option] pattern filenames 

功能:逐行搜尋所指定的檔案或標準輸入,並顯示匹配模式的每一行。 

選項:-i    匹配時忽略大小寫 

-v 找出模式失配的行 

例如:% grep -i 'java*' ./test/run.sh

1.主要引數

[options]主要引數:

-c:只輸出匹配行的計數。

-i:不區分大小寫

-h:查詢多檔案時不顯示檔名。

-l:查詢多檔案時只輸出包含匹配字元的檔名。

-n:顯示匹配行及行號。

-s:不顯示不存在或無匹配文字的錯誤資訊。

-v:顯示不包含匹配文字的所有行。

pattern正規表示式主要引數:

\: 忽略正規表示式中特殊字元的原有含義。

^:匹配正規表示式的開始行。

$: 匹配正規表示式的結束行。

\<:從匹配正則表達 式的行開始。

\>:到匹配正規表示式的行結束。

[ ]:單個字元,如[A]即A符合要求 。

[ - ]:範圍,如[A-Z],即A、B、C一直到Z都符合要求 。

.:所有的單個字元。

* :有字元,長度可以為0。

2.例項

(1)grep 'test' d*#顯示所有以d開頭的檔案中包含 test的行

(2)grep ‘test’ aa bb cc #顯示在aa,bb,cc檔案中包含test的行

(3)grep ‘[a-z]\{5\}’ aa #顯示所有包含每行字串至少有5個連續小寫字元的字串的行

(4)grep magic /usr/src#顯示/usr/src目錄下的 檔案(不含子目錄) 包含magic的行

(5)grep -r magic /usr/src#顯示/usr/src目錄下的 檔案(包含子目錄) 包含magic的行

(6)grep -w pattern files :只匹配 整個單詞 ,而不是字串的一 部分 (如匹配’magic’,而不是’magical’),

2、GC狀態命令

通常執行命令如下:

jstat -gc 30996 3000

即:每3秒一次顯示程式號為30996的java程式的GC情況

或使用命令:jstat -gcutil 30996 3000

1.查程式

ps命令查詢與程式相關的PID號:

ps a 顯示現行終端機下的所有程式,包括其他使用者的程式。

ps -A 顯示所有程式。

2.殺程式

使用kill命令結束程式:kill xxx

常用:kill -9 324

大資料:

HDFS節點、角色

1.Namenode名稱節點

目錄的管理者,每一個叢集都有一個,記錄實時的資料變化,如果沒有namenode,HDFS就無法工作,系統中的檔案將會全部丟失,就無法將位於不同datanode上的檔案快(blocks)重建檔案。因此它的容錯機制很有必要。

它主要負責:

接收使用者的請求;

維護檔案系統的目錄結構;

管理檔案與Block之間的練習;

2.Datanode資料節點

是檔案系統的工作節點,他們根據客戶端或者是namenode的排程儲存和檢索,並且定期向namenode傳送他們所儲存的塊(block)的列表。

叢集中的每個伺服器都執行一個DataNode後臺程式,這個後臺程式負責把HDFS資料塊讀寫到本地的檔案系統。當需要通過客戶端讀/寫某個 資料時,先由NameNode告訴客戶端去哪個DataNode進行具體的讀/寫操作,然後,客戶端直接與這個DataNode伺服器上的後臺程式進行通 信,並且對相關的資料塊進行讀/寫操作。

它主要負責:

存放資料;

檔案被分割以Block的形式被儲存在磁碟上;

3.Secondarynode

SecondaryNameNode是一個用來監控HDFS狀態的輔助後臺程式。就想NameNode一樣,每個叢集都有一個SecondaryNameNode,並且部署在一個單獨的伺服器上。

SecondaryNameNode不同於NameNode,它不接受或者記錄任何實時的資料變化,但是,它會與NameNode進行通訊,以便定期地儲存HDFS後設資料的快照。由於NameNode是單點的,通過SecondaryNameNode的快照功能,可以將NameNode的當機時間和資料損失降低到最小。同時,如果NameNode發生問題,SecondaryNameNode可以及時地作為備用NameNode使用。

它主要將namenode image(fsimage)和Edit log合併的。

SecondaryNameNode的處理,是將fsimage和edites檔案週期的合併,不會造成nameNode重啟時造成長時間不可訪問的情況。

4.Resourcemanager

(1)與客戶端進行互動,處理來自於客戶端的請求,如查詢應用的執行情況等。

(2)啟動和管理各個應用的ApplicationMaster,並且為ApplicationMaster申請第一個Container用於啟動和在它執行失敗時將它重新啟動。

(3)管理NodeManager,接收來自NodeManager的資源和節點健康情況彙報,並向NodeManager下達管理資源命令,例如kill掉某個container。

(4)資源管理和排程,接收來自ApplicationMaster的資源申請,並且為其進行分配。這個是它的最重要的職能。

5.Nodemanager

NM是ResourceManager在每臺機器上的代理,負責容器管理,並監控它們的資源使用情況,以及向ResourceManager/Scheduler提供資源使用報告。

總結:

Java程式設計師交流基地:236283328

(1)NameNode與ResourceManager分開部署(都是老大)

(2)NodeManager 也就是Resoucemanager 的“小弟”,它來做這事情,讀取hdfs 上的資料,資料儲存在datanode上,所以如果資料叢集,datanode 與NodeManager ,一定要儲存在同一個節點上

(3)Resoucemanager : 佔用埠:8088   進行排程資源(老大),進行任務分配的,誰來做這個事情

相關文章