大數據面試題

Java部分:
1.什麼是構造函數,構造代碼塊,靜態代碼塊?分別的做用是什麼?三者的順序
構造函數是類用來建立對象使用的一種函數能夠有有參構造函數也能夠有無參構造函數
構造代碼塊的做用和構造函數相似能夠完成類中的成員變量進行初始化也能夠調用成員方法
靜態代碼塊屬於類的,靜態代碼塊能夠隨着類的加載而加載能夠初始化中的靜態成員變量,也
能夠在鏈接JBCD時用於讀取文件中的鏈接信息
先執行靜態代碼塊 在執行構造代碼塊 最後執行構造方法java

2.double和Double的區別?
double是基本數據類型,值會存儲在棧中而且初始值是0.0,不能存在集合中
Double是包裝類即double的引用類型,值會存儲在堆中初始值是null,能夠替代double存儲 集合中node

3.2<<3等於多少
16mysql

4.判斷字符串爲空時如何避免空指針異常?
String str=null;
if(str == null || str.isEmpty())來進行判斷linux

5.什麼是重載和重寫?
重載:是面向對象中多態特性的一種體現,即方法名相同形參列表不一樣(參數,個數,順序)知足其中一個條件便可
重寫:是面向對象中繼承特性的一種體現,即父類中所提供的方法沒法知足子類需求時,子類能夠實現和父類同樣的方法即爲重寫,可是fianl,private,static修飾的方法沒法重寫算法

6.實現線程的三種方式?
繼承Thread類,並複寫run方法,建立該類對象,調用start方法開啓線程。
實現Runnable接口,複寫run方法,建立Thread類對象,將Runnable子類對象傳遞給Thread類對象。調用start方法開啓線程。
建立FutureTask對象,建立Callable子類對象,複寫call(至關於run)方法,將其傳遞給FutureTask對象(至關於一個Runnable)
7.Thread類中的start()和run()方法的區別?
用start方法來啓動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。經過調用Thread類的 start()方法來啓動一個線程,這時此線程處於就緒(可運行)狀態,並無運行,一旦獲得cpu時間片,就開始執行run()方法,這裏方法 run()稱爲線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。spring

8.final修飾的方法能夠被繼承/重載/重寫嗎?
final修飾的方法能夠繼承和重載,可是不能重寫sql

9.遍歷二叉樹的方式有哪些?選擇一種方式用程序實現?
二叉樹遍歷分爲三種先序遍歷
首先訪問根,再先序遍歷左子樹,最後先序遍歷右子樹 根 --> 左 -- > 右
無序中序遍歷首先中序遍歷左子樹,再訪問根,最後中序遍歷右子樹 左 --> 根 --.> 右
升序後序遍歷首前後序遍歷左子樹,再後序遍歷右子樹,最後訪問根 左 --> 右 --> 跟數據庫

左-->根-->右排序
public class BinaryTree {
private Node root;//節點
//添加節點
public void add(int data) {
if(root == null) {
root = new Node(data);
}else {
root.addNode(data);
}
}
public void printBinaryTree() {
root.print();
}後端

class Node{
      private int data;//數據
      private Node left; //左
      private Node right; //右
     public Node(int data) {
         this.data = data;
     }
     //添加節點(左/右)
     public void addNode(int data) {
         if(this.data > data) {
             if(this.left == null) {
                 this.left = new Node(data);
             }else {
                 //遞歸
                 this.left.addNode(data);
             }
         }else {
             if(this.right == null) {
                 this.right =  new Node(data);
             }else {
                 this.right.addNode(data);
             }
         }
     }
     //左 --> 根 ---> 右
     public void print() {
         if(this.left != null) {
             this.left.print();
         }
         System.out.print(this.data+"->");
         if(this.right != null) {
             this.right.print();
         }
     }
  }

}
public class Test {
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.add(8);
bt.add(3);
bt.add(10);
bt.add(6);
bt.add(7);
bt.add(14);
bt.add(13);
bt.add(2);
bt.printBinaryTree();
}
}設計模式

10.java常見的排序方式有哪些?選擇一種實現?
冒泡排序複雜度爲O(nn),插入排序複雜度爲O(nn),堆排序複雜度爲nlog2(n)
快速排序複雜度爲nlog2(n),歸併排序複雜度爲nlog2(n)
冒泡排序:
public class maopao {
public static void main(String[] args) {
int[] numbers = {10,12,2,3,5,78,6,21,99,88};
for(int j =0; j<numbers.length-1; j++){
for(int i = 0; i<numbers.length-1-j;i++){
int temp = 0;
if (numbers[i]>numbers[i+1]){
temp = numbers[i+1];
numbers[i+1] = numbers[i];
numbers[i] = temp;
}
}
}
}
}

11.什麼是反射?如何經過反射訪問私有字段?
JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的字節碼文件對象。而解剖使用的就是Class類中的方法.因此先要獲取到每個字節碼文件對應的Class類型的對象.
能夠用getDeclaredField方法而且須要開啓權限setAccessible(true)

12.常見的排序及複雜度,實現快排算法
冒泡排序複雜度爲O(nn),插入排序複雜度爲O(nn),堆排序複雜度爲nlog2(n)
快速排序複雜度爲nlog2(n),歸併排序複雜度爲nlog2(n)
快排算法:

public class QickSort {
public static void main(String[] args) {
int[] numbers = {10,12,2,3,5,78,6,21,99,88};
int len = numbers.length;
//若是數組大於2的時候纔開始排序
if(len>1){
quickSort(numbers,0,len-1);
}
System.out.println(Arrays.toString(numbers));
}
public static void quickSort(int[] list, int low, int high) {
if(low < high){
int middle = getMiddle(list, low, high);
quickSort(list, low, middle - 1);
quickSort(list, middle + 1, high);
}
}
public static int getMiddle(int[] list, int low, int high) {
int temp = list[low];
while(low < high){
while(low < high && temp <= list[high]){
high--;
}
temp>=list[high]
list[low] = list[high];
while(low < high && list[low] <= temp){
low++;
}
list[low]>temp
list[high] = list[low];
}
list[low] = temp;
return low;
}
}

13.題目:實現Fibonacci(即斐波那契額)數列
public class Demo {
public static int f(int n) throws Exception {
if(n==0){
throw new Exception("參數錯誤!");
}
if (n == 1 || n == 2) {
return 1;
} else {
return f(n-1)+f(n-2);//本身調用本身
}
}
public static void main(String[] args) throws Exception {
for (int i = 1; i <=10; i++) {
System.out.print(f(i)+" ");
}
}
}

14.常見的設計模式,任選模式一種模模式代碼的實現

單例,模板,工廠,裝飾者,適配器,代理,觀察者等設計模式
public class HungrySingle {
private static HungrySingle instance = new HungrySingle();
private HungrySingle() {
}
public static HungrySingle getInstance() {
return instance;
}
}

15.簡述java線程池,並說明線程安全的解決思路
所謂線程池,就是將多個線程放在一個池子裏面(所謂池化技術),而後須要線程的時候不是建立一個線程,而是從線程池裏面獲取一個可用的線程,而後執行咱們的任務。線程池的關鍵在於它爲咱們管理了多個線程,咱們不須要關心如何建立線程,咱們只須要關係咱們的核心業務,而後須要線程來執行任務的時候從線程池中獲取線程。任務執行完以後線程不會被銷燬,而是會被從新放到池子裏面,等待機會去執行任務。
 一個線程池包括如下四個基本組成部分:
                一、線程池管理器(ThreadPool):用於建立並管理線程池,包括 建立線程池,銷燬線程池,添加新任務;
                二、工做線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,能夠循環的執行任務;
                三、任務接口(Task):每一個任務必須實現的接口,以供工做線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工做,任務的執行狀態等;
                四、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩衝機制。

解決線程安全問題的思路是消除產生線程安全問題的環境:
消除共享數據:成員變量與靜態變量多線程共享,將這些全局變量轉化爲局部變量,局部變量存放在棧,線程間不共享,就不存在線程安全問題產生的環境了。消除共享數據的不足:若是須要一個對象採集各個線程的信息,或者在線程間傳遞信息,消除了共享對象就沒法實現此目的。
使用線程同步機制:給讀寫操做同時加鎖,使得同時只有一個線程能夠訪問共享數據。若是單單給寫操做加鎖,同時只有一個線程能夠執行寫操做,而讀操做不受限制,容許多線程併發讀取,這時就可能出現不可重複讀的狀況,如一個持續時間比較長的讀線程,相隔較長時間讀取數組同一索引位置的數據,正好在這兩次讀取的時間內,一個線程修改了該索引處的數據,形成該線程從同一索引處先後讀取的數據不一致。是同時給讀寫加鎖,仍是隻給寫加鎖,根據具體需求而定。同步機制的缺點是下降了程序的吞吐量。
創建副本:使用ThreadLocal爲每個線程創建一個變量的副本,各個線程間獨立操做,互不影響。該方式本質上是消除共享數據思想的一種實現。
使用synchronized或lock來完成加鎖處理

16.什麼是cookie,做用是什麼?cookie和session的區別與聯繫
cookie是存在於客戶端(瀏覽器)。
cookie的使用是由瀏覽器按照必定的原則在後臺自動發送給服務器的。瀏覽器檢查全部存儲的cookie,若是某個cookie所聲明的做用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過時時間,路徑和域。其中路徑與域一塊兒構成cookie的做用範圍。若不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失

Session是另外一種記錄客戶狀態的機制,不一樣的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄
  在服務器上。這就是Session。客戶端瀏覽器再次訪問時只須要從該Session中查找該客戶的狀態就能夠了。
  每一個用戶訪問服務器都會創建一個session,那服務器是怎麼標識用戶的惟一身份呢?事實上,用戶與服務器創建鏈接的同時,服務器會自動爲其分配一個SessionId

總結
一、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。
二、cookie不是很安全,別人能夠分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session。
三、session會在必定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie。
四、單個cookie保存的數據不能超過4K,不少瀏覽器都限制一個站點最多保存20個cookie。
五、能夠考慮將登錄信息等重要信息存放爲session,其餘信息若是須要保留,能夠放在cookie中。

17.簡述spring隔離級別與傳播行爲
spring 的事務傳播行爲: 
Spring在TransactionDefinition接口中規定了7種類型的事務傳播行爲,它們規定了事務方法和事務方法發生嵌套調用時事務如何進行傳播:
  PROPAGATION_REQUIRED:若是當前沒有事務,就新建一個事務,若是已經存在一個事務中,加入到這個事務中。這是最多見的選擇。
  PROPAGATION_SUPPORTS:支持當前事務,若是當前沒有事務,就以非事務方式執行。
  PROPAGATION_MANDATORY:使用當前的事務,若是當前沒有事務,就拋出異常。
  PROPAGATION_REQUIRES_NEW:新建事務,若是當前存在事務,把當前事務掛起。
  PROPAGATION_NOT_SUPPORTED:以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
  PROPAGATION_NEVER:以非事務方式執行,若是當前存在事務,則拋出異常。
  PROPAGATION_NESTED:若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則執行與PROPAGATION_REQUIRED相似的操做。

Spring 的隔離級別
SERIALIZABLE:最嚴格的級別,事務串行執行,資源消耗最大;
REPEATABLE_READ:保證了一個事務不會修改已經由另外一個事務讀取但未提交(回滾)的數據。避免了」髒讀取」和」不可重複讀取」的狀況,可是帶來了更多的性能損失。
READ_COMMITTED:大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另外一個並行事務已修改但未提交的數據,避免了」髒讀取」。該級別適用於大多數系統。
Read_UNCOMMITTED:保證了讀取過程當中不會讀取到非法數據

18.簡述常見先後端服務框架
SpringMVC,Spring,Mybatis,Dubbo,RabbitMQ,Redis

19.不使用循環條和件語句實現1+2+3+...n
public static int sum(int n) {
int sum = n;
boolean isContinue = (n > 0) && (sum += sum(--n)) > 0;
return sum;
}

public static void main(String[] args) {
    int result = sum(5);
    System.out.println(result);

}

Linux部分:
1.linux如何查看系統負載,內存.硬盤使用狀況
負載:top -c
內存:free -h
磁盤:df -h

2.linux > 和 >> 的區別,經常使用查看日誌命令

是定向輸出到文件,若是文件不存在,就建立文件;若是文件存在,就將其清空;通常咱們備份清理日誌文件的時候,就是這種方法:先備份日誌,再用>,將日誌文件清空(文件大小變成0字節)。

這個是將輸出內容追加到目標文件中。若是文件不存在,就建立文件;若是文件存在,則將新的內容追加到那個文件的末尾,該文件中的原有內容不受影響。
查看日記命令
tail,head,cat,sed,more,less

Mysql部分:
1.musql5.x默認使用的引擎?對應的鎖機制?
InnoDB做爲默認存儲引擎,InnoDB做爲支持事務的存儲引擎,擁有相關的RDBMS特性:包括ACID事務支持,參考完整性(外健),災難恢復能力等特性
行鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖衝突的機率低,併發度高

2.什麼查詢條件下索引會失效?
若是條件中有or,即便其中有條件帶索引也不會使用(這也是爲何儘可能少用or的緣由)
對於多列索引,不是使用的第一部分,則不會使用索引
like查詢是以%開頭(以%結尾是能夠的)
若是列類型是字符串,那必定要在條件中將數據使用引號引用起來,不然不使用索引
若是mysql估計使用全表掃描要比使用索引快,則不使用索引

3.having和where的區別
「Where」是一個約束聲明,在查詢數據庫的結果返回以前對數據庫中的查詢條件進行約束,即在結果返回以前起做用,且where後面不能使用「聚合函數」;
「Having」是一個過濾聲明,所謂過濾是在查詢數據庫的結果返回以後進行過濾,即在結果返回以後起做用,而且having後面可使用「聚合函數」。

4.union all和 union的區別
union和union all的區別是,union會自動壓縮多個結果集合中的重複結果,而union all則將全部的結果所有顯示出來,無論是否是重複。
Union由於要進行重複值掃描,因此效率低。若是合併無刻意要刪除重複行,那麼就使用Union All

5.什麼是左鏈接?
左鏈接是以左表爲基礎Left join即左鏈接,是以左表爲基礎,根據ON後給出的兩表的條件將兩錶鏈接起來。結果會將左表全部的查詢信息列出,而右表只列出ON後條件與左表知足的部分。左鏈接全稱爲左外鏈接,是外鏈接的一種

6.請用一個sql語句返回兩張表的差集
select * from tab1 where id not in (select id from tab2)

select table1.id from table1 left join table2 on table1.id=table2.id where table2.id is null;

Hadoop部分:
1.一般狀況下集羣模式的瓶頸在哪?
首先,瓶頸通常是指在總體中的關鍵限制因素,磁盤IO是指數據往磁盤讀寫,如今的科技速度最快的屬固態硬盤了,讀的速度很大有1G/秒左右,可是寫入速度最快幾百兆/秒,集羣中數據在cpu和內存之間速度快的能夠忽略,處理速度也能夠忽略,相對這些速度,磁盤讀寫就顯得慢了,旁貸一下如今好一點的數據庫oracle存儲數據都是寫日誌先暫存而後等機器空閒再寫入到磁盤,這些都是爲了提升效率,否則執行一條操做等半天

2.SecondaryNameNode的做用是什麼?
SecondaryNameNode它的職責是合併NameNode的edit logs到fsimage文件中
首先,SecondaryNameNode定時到NameNode去獲取edit logs,並更新到fsimage上。一旦它有了新的fsimage文件,SecondaryNameNode將其拷貝回NameNode中。NameNode在下次重啓時會使用這個新的fsimage文件,從而減小重啓的時間。
Secondary NameNode的整個目的是在HDFS中提供一個檢查點。它只是NameNode的一個助手節點。這也是它在社區內被認爲是檢查點節點的緣由。

3.請用map,reduce實現wordCount?
public class WordCount {
public static class MyMapper extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
@Override
protected void map(Object key, Text value,Context context)
throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
private IntWritable result = new IntWritable();
@Override
protected void reduce(Text key, Iterable values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(MyMapper.class);
job.setCombinerClass(MyReducer.class);
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true)?0:1);
}

}

Spark部分:
1.ElasticSearch如何避免腦裂?
修改集羣中每一個節點的配置文件(elasticsearch.yml)參數 discovery.zen.minimum_master_nodes,這個參數決定了主節點選擇過程當中最少須要多少個 master 節點,默認配置是1。
一個基本原則是這裏須要設置成 N/2+1,N 是集羣中節點的數量。
修改集羣中每一個節點的配置文件(elasticsearch.yml)參數 discovery.zen.ping.timeout,默認值是3,決定節點之間網絡通訊的等待時間。
修改集羣中每一個節點的配置文件(elasticsearch.yml)參數 discovery.zen.ping.unicast.hosts,把集羣中可能成爲主節點的機器節點都配置到這個參數中。

2.ElasticSearch中:match和term區別?
term是表明徹底匹配,也就是精確查詢,搜索前不會再對搜索詞進行分詞,因此搜索詞必須是文檔分詞集合中的一個
match查詢會先對搜索詞進行分詞,分詞完畢後再逐個對分詞結果進行匹配,所以相比於term的精確搜索,match是分詞匹配搜索,match搜索還有兩個類似功能的變種,一個是match_phrase,一個是multi_match

3.kafak在高併發的狀況下,如何避免消息丟失和消息重複? 消息丟失解決方案: 首先對kafka進行限速, 其次啓用重試機制,重試間隔時間設置長一些,最後Kafka設置acks=all,即須要相應的全部處於ISR的分區都確認收到該消息後,纔算發送成功 消息重複解決方案: 消息可使用惟一id標識  生產者(ack=all 表明至少成功發送一次)  消費者 (offset手動提交,業務邏輯成功處理後,提交offset)  落表(主鍵或者惟一索引的方式,避免重複數據)  業務邏輯處理(選擇惟一主鍵存儲到Redis或者mongdb中,先查詢是否存在,若存在則不處理;若不存在,先插入Redis或Mongdb,再進行業務邏輯處理)

相關文章
相關標籤/搜索