1. 程式人生 > >京東面試詳解(渣渣吐血整理版)

京東面試詳解(渣渣吐血整理版)

面試題連結:https://www.nowcoder.com/discuss/91413

3.java與c++的區別,知道多少答多少

JAVA中有異常機制,C++沒有

C++有指標,java沒有

C++建立物件之後,使用完呼叫delete方法將其銷燬,Java通過垃圾回收機制

C++中宣告常量的關鍵字是“const”;java中宣告常量的關鍵字是“final”

Java單繼承,C++多繼承

C++不支援字串,java通過類物件實現字串

C++有goto,Java沒有goto(作為保留字)

4.說幾個自己常用的資料結構

資料結構:

棧:(stack)先進後出,後進先出;一個開口

佇列:(queue)先進先出

二叉樹:每個節點至多隻有兩顆子樹

        儲存結構:

順序儲存結構:用一組地址連續的儲存單元一次從上而下,從左到右儲存完全二叉樹上的結點元素

                                  僅僅適用於完全二叉樹

鏈式儲存結構

遍歷二叉樹:先序遍歷 DLR

                     中序遍歷 LDR

                     後序遍歷 LRD

實質是對一個非線性結構進行線性化的操作,使每個結點(出去第一個和最後一個)在這些線性序列中有且僅有一個直接前驅和直接後繼。時間複雜度和空間複雜度均為O(n)。

當二叉連結串列作為儲存結構時,只能找到結點的左右孩子資訊,不能直接得到結點在任意序列中的前驅和後繼資訊,只有在遍歷的動態過程中才能得到。

線索二叉樹:LTag= 0        lchild域指示結點的左孩子

                              1      lchild 域指示結點的前驅

                     RTag=0        rchild域指示結點的右孩子

                              1      rchild 域指示結點的後驅

以這種結點結構構成的二叉連結串列作為二叉樹的儲存結構,叫線索連結串列,指向結點前驅和後繼的指標叫線索。加上線索的二叉樹叫線索二叉樹。一般用在經常遍歷和利用前驅和後繼查詢結構的情況。

最優二叉樹(赫夫曼樹):是一種帶權路徑長度最短的二叉樹。利用赫夫曼編碼進行壓縮。

動態查詢表

二叉排序樹(二叉查詢樹):①空樹 ②左子樹不空,左結點值均小於根節點;右子樹不空,右結點值均大於根節點;左右子樹均為二叉排序樹。

平衡二叉樹(AVL樹):①空樹 ②左右子樹均為平衡二叉樹,左子樹右子樹深度之差(注意不是節點數之差)的絕對值不超過1。將二叉樹上結點的左子樹深度減去右子樹深度的值稱為平衡因子BF,那麼平衡二叉樹上的所有結點的平衡因子只可能是-1、0和1。只要二叉樹上有一個結點的平衡因子的絕對值大於1,則該二叉樹就是不平衡的。平衡二叉樹很好的解決了二叉查詢樹退化成連結串列的問題,把插入,查詢,刪除的時間複雜度最好情況和最壞情況都維持在O(logN)。

B-樹:一種平衡的多路查詢樹,在檔案系統中很有用。查詢過程和二叉排序樹類似。

B+樹:是應檔案系統所需而出的一種B-樹的變型樹。在B+樹上進行隨機查詢,插入,刪除過程基本和B-樹類似。只是在查詢時,如果終端結點關鍵字不等於給定值,不終止,繼續向下直到葉子結點。

堆(heap):堆是一棵完全二叉樹。大頂堆:根結點(亦稱為堆頂)的關鍵字是堆裡所有結點關鍵字中最大者,稱為大頂堆(大根堆,最大堆);小頂堆正好相反。

紅黑樹:是一種自平衡二叉查詢樹,紅黑樹和AVL樹類似,都是在進行插入和刪除操作時通過特定操作保持二叉查詢樹的平衡,從而獲得較高的查詢效能。

在二叉查詢樹強制一般要求以外,對於任何有效的紅黑樹我們增加了如下的額外要求:

性質1. 節點是紅色或黑色。

性質2. 根節點是黑色。

性質3 每個葉節點(NIL節點,空節點)是黑色的。

性質4 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

性質5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。

插入和刪除利用顏色屬性來保證操作之後樹還是平衡的。查詢,插入和刪除的時間複雜度都是:O(logN)。統計效能比平衡二叉樹好。

Java集合中的TreeSet和TreeMap,C++ STL中的set、map,Linux虛擬記憶體的管理,都是通過紅黑樹去實現的。

5.hashMap原始碼與currenthashmap原始碼,1.7與1.8 的區別

(第二個應該是ConcurrentHashMap吧)

HashMap在Java1.7與1.8中的區別:

JDK1.7中使用一個Entry陣列來儲存資料,用key的hashcode取模來決定key會被放到數組裡的位置,如果hashcode相同,或者hashcode取模後的結果相同(hash collision),那麼這些key會被定位到Entry陣列的同一個格子裡,這些key會形成一個連結串列。在hashcode特別差的情況下,比方說所有key的hashcode都相同,這個連結串列可能會很長,那麼put/get操作都可能需要遍歷這個連結串列。也就是說時間複雜度在最差情況下會退化到O(n)。

JDK1.8中使用一個Node陣列來儲存資料,但這個Node可能是連結串列結構,也可能是紅黑樹結構。如果插入的key的hashcode相同,那麼這些key也會被定位到Node陣列的同一個格子裡。如果同一個格子裡的key不超過8個,使用連結串列結構儲存。如果超過了8個,那麼會呼叫treeifyBin函式,將連結串列轉換為紅黑樹。那麼即使hashcode完全相同,由於紅黑樹的特點,查詢某個特定元素,也只需要O(log n)的開銷。也就是說put/get的操作的時間複雜度最差只有O(log n)。

ConcurrentHashMap在Java1.7與1.8中的區別:

ConcurrentHashMap在jdk1.7中採用Segment + HashEntry的方式進行實現;1.8中放棄了Segment臃腫的設計,取而代之的是採用Node + CAS + Synchronized來保證併發安全進行實現

6.如果將hashmap中的value變成陣列

Map<String, Object> map = new HashMap<String, Object>();

              map.put("a", "tom");

              map.put("b", "jerry");

              Object[] keys =  map.keySet().toArray();

              Object[] values =  map.values().toArray();

7.hashmap在併發情況下,會出現什麼問題

HashMap在多執行緒put後可能導致get無限迴圈; 多執行緒put的時候可能導致元素丟失

如何使用執行緒安全的雜湊表結構呢,這裡列出了幾條建議:

使用Hashtable 類,Hashtable 是執行緒安全的;

使用併發包下的java.util.concurrent.ConcurrentHashMap,ConcurrentHashMap實現了更高階的執行緒安全;

或者使用synchronizedMap() 同步方法包裝 HashMap object,得到執行緒安全的Map,並在此Map上進行操作。

8.給了一個場景題,說怎麼實現每隔一秒在控制檯輸出一句話

造一個繼承於Thread類的匿名類物件,呼叫其start()方法,在大括號內重寫run()方法

public static void main(String[] args) {

        new Thread() {

            public void run() {

                while (true) {

                    System.out.println("要輸出的內容");

                    try {

                        Thread.sleep(1000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }

        }.start();

}

9.java多執行緒怎麼實現的

Java中建立多執行緒有兩種方法,一種是類實現“Runable”介面,一種是類繼承“Thread”類,兩種方法都要對run()函式進行重寫。多執行緒以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:避免點繼承的侷限,一個類可以繼承多個介面。適合於資源的共享。Thread類也是Runnable介面的子類。

Java多執行緒的排程方法有:setPriority(設定優先順序),sleep(睡眠),join(加入),yield(讓步);

Java執行緒同步採用關鍵字“synthronized(鎖的標誌)”,同步程式碼塊的格式為:synthronized(threadname)。

Java多執行緒間實現通訊,需要用到如下3個方法:wait()表示讓當前執行緒進入等待狀態,notify()表示恢復一個等待中的執行緒,notifyAll()恢復所有等待中的執行緒。

10.你還知道當前包下的其他類嗎?(沒太理解問題,自己分析揣測:java.lang.Thread 類在java.lang包下面,問的應該是java.lang包下的其他類)

java.util包含 collection 框架、遺留的 collection 類、事件模型、日期和時間設施、國際化和各種實用工具類(字串標記生成器、隨機數生成器和位陣列;

java.lang提供利用 Java 程式語言進行程式設計的基礎類

11.java虛擬機器的記憶體模式

詳見部落格:https://blog.csdn.net/u014590757/article/details/79927448

12.怎麼打破雙親委派模式

1)自己寫一個類載入器 2)重寫loadclass方法 3)重寫findclass方法

最主要的是重寫loadclass方法,因為雙親委派機制的實現都是通過這個方法實現的,先找父載入器進行載入,如果父載入器無法載入再由自己來進行載入,原始碼裡會直接找到根載入器,重寫了這個方法以後就能自己定義載入的方式了。

雙親委派發生在類載入階段。其作用也就是通過類載入器將class檔案載入到虛擬機器中以備呼叫。

絕大部分Java程式都會使用到以下3種系統提供的類載入器:

啟動類載入器(Bootstrap ClassLoader), 擴充套件類載入器(Extension ClassLoader) ,應用程式類載入器(Application ClassLoader)。

http://img3.tbcdn.cn/L1/461/1/f89d340078fc664863e0690df46dd2e1459a6a47.png

類載入器之間的這種層次關係,稱為類載入器的雙親委派模型。過程:如果一個類載入器收到了類載入請求,它首先不會自己去載入這個類,而是將這個類委託給父載入器去完成,每一層載入器都是如此,因此所有載入請求最終應該傳送到頂層的啟動類載入器中,只有父載入器反饋無法載入時,子載入器才會自己嘗試去載入。

雙親委派機制的作用:保證所有相同的類在各種類載入器環境中都是同一個類,若沒有向上傳遞的過程,由各個類載入器自行去載入的話,系統中會出現多個不同的一個名稱的類 。

13.java虛擬機器怎麼識別是符合標準的class檔案,魔數?,我也不知道

class檔案是由Java編譯器產生的,但是虛擬機器並不知道某個特定的class檔案是如何被建立的,class檔案實質上就是一個位元組序列,所以Java虛擬機器沒有辦法分辨特定的class檔案是由正常的Java編譯器產生的,還有由黑客生成的,所以,所有Java虛擬機器的實現必須有一個class檔案檢驗器,提前對這些class檔案進行驗證,以保證這些定義的型別都可以安全可靠的執行。

14.mysql的索引用過吧?

(本渣表示,阿里巴巴一面也問過14.15.17類似的問題)

15.介紹一下索引?怎麼使用索引的?

索引在MySQL中也叫做“鍵”,是儲存引擎用於快速找到記錄的一種資料結構。索引對於良好的效能非常關鍵,尤其是當表中的資料量越來越大時,索引對於效能的影響愈發重要。

索引優化應該是對查詢效能優化最有效的手段了。索引能夠輕易將查詢效能提高好幾個數量級。本質:通過不斷地縮小想要獲取資料的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查詢方式來鎖定資料。

mysql的索引分為單列索引(主鍵索引,唯一索引,普通索引)和組合索引。

單列索引:一個索引只包含一個列,一個表可以有多個單列索引;組合索引:一個組合索引包含兩個或兩個以上的列。

1.單列索引

1)普通索引,這個是最基本的索引,

其sql格式是 CREATE INDEX IndexName ON `TableName`(`欄位名`(length)) 或者 ALTER TABLE TableName ADD INDEX IndexName(`欄位名`(length))

2)唯一索引,與普通索引類似,但是不同的是唯一索引要求所有的類的值是唯一的,這一點和主鍵索引一樣.但是他允許有空值,

其sql格式是 CREATE UNIQUE INDEX IndexName ON `TableName`(`欄位名`(length)); 或者 ALTER TABLE TableName ADD UNIQUE (column_list)

3)主鍵索引,不允許有空值,(在B+TREE中的InnoDB引擎中,主鍵索引起到了至關重要的地位)

主鍵索引建立的規則是 int優於varchar,一般在建表的時候建立,最好是與表的其他欄位不相關的列或者是業務不相關的列.一般會設為 int 而且是 AUTO_INCREMENT自增型別的

2.組合索引

一個表中含有多個單列索引不代表是組合索引,通俗一點講 組合索引是:包含多個欄位但是隻有索引名稱

其sql格式是 CREATE INDEX IndexName On `TableName`(`欄位名`(length),`欄位名`(length),...);例:

CREATE INDEX nickname_account_createdTime_Index ON `award`(`nickname`, `account`, `created_time`);

16.B樹與B+樹的底層

17.資料庫怎麼實現分庫分表

18.訊息中介軟體用過嗎?主要的作用是什麼?

19.我看你簡歷上面寫了前端,我們來問一下前端的知識,到現在,我有點懵了··

20,js的資料型別有哪些?

字串、數字、布林、陣列、物件、Null、Undefined

21.dom物件與js物件、jQuery的區別

jQuery物件其實是一個JavaScript的陣列。jquery物件就是通過包裝DOM物件後產生的物件。jQuery物件是jQuery獨有的,其可以使用jQuery裡的方法,但是不能使用DOM的方法;反過來Dom物件也不能使用jquery的方法。

22,jQuery物件和js物件之間的互相轉換

js物件轉jQuery物件: $(js物件)

jQuery物件轉換成DOM物件:[index]和.get(index)  例:var v=$v[0]; 或者 var v=$v.get(0);

23.js中事件觸發的流程,怎麼阻止冒泡

在一個物件上觸發某類事件(比如單擊onclick事件),如果此物件定義了此事件的處理程式,那麼此事件就會呼叫這個處理程式,如果沒有定義此事件處理程式或者事件返回true,那麼這個事件會向這個物件的父級物件傳播,從裡到外,直至它被處理(父級物件所有同類事件都將被啟用),或者它到達了物件層次的最頂層,即document物件(有些瀏覽器是window)。 

例:

<body>

  <form id="form1" runat="server">

    <div id="divOne" onclick="alert('我是最外層');">

      <div id="divTwo" onclick="alert('我是中間層')">

        <a id="inner" href="http://www.baidu.com" onclick="alert('我是最裡層')">點選我</a>

      </div>

    </div>

  </form>

</body>

執行頁面,點選“點選我”,會依次彈出:我是最裡層---->我是中間層---->我是最外層---->然後再連結到百度

這就是事件冒泡,本來只點擊ID為inner的標籤,但是確執行了三個alert操作。

阻止冒泡:

  1. event.stopPropagation();

<script type="text/javascript">

        $(function() {

            $("inner").click(function(event) {

                event.stopPropagation();});

        });

<script>

事件處理過程中,阻止了事件冒泡,但不會阻擊預設行為

  1. return false;

將上例中的event.stopPropagation();替換成 return false

事件處理過程中,阻止了事件冒泡,也阻止了預設行為(上例沒有執行超連結的跳轉)

24.怎麼預防使用者的多次點選事件

1) 定義標誌位:

點選觸發請求後,標誌位為false;請求後,標誌位為true。

2)解除安裝及過載繫結事件:

點選觸發請求後,解除安裝點選事件;請求後,重新載入繫結事件。

3) 替換(移除)按鈕DOM

點選觸發請求後,將按鈕DOM物件替換掉(或者將之移除);請求後,給新的按鈕DOM定義點選事件。

25.你用過哪些伺服器

Apache tomcat

26.tomcat的配置檔案,你怎麼配置的。