2019爲面試總結面試題

1.開發中Java用了比較多的數據結構有哪些?html

 

 

 

java中有幾種經常使用的數據結構,主要分爲Collection和map兩個主要接口(接口只提供方法,並不提供實現),而程序中最終使用的數據結構是繼承自這些接口的數據結構類;java

List

List是有序的Collection,使用此接口可以精確的控制每一個元素插入的位置。用戶可以使用索引(元素在List中的位置,相似於數組下 >標)來訪問List中的元素,這相似於Java的數組。 redis

Vector

基於數組(Array)的List,其實就是封裝了數組所不具有的一些功能方便咱們使用,因此它難易避免數組的限制,同時性能也不可能超越數組。因此,在可能的狀況下,咱們要多運用數組。另外很重要的一點就是Vector是線程同步的(sychronized)的,這也是Vector和ArrayList 的一個的重要區別。數組

ArrayList

同Vector同樣是一個基於數組上的鏈表,可是不一樣的是ArrayList不是同步的。因此在性能上要比Vector好一些,可是當運行到多線程環境中時,可須要本身在管理線程的同步問題。瀏覽器

LinkedList

LinkedList不一樣於前面兩種List,它不是基於數組的,因此不受數組性能的限制。 
它每個節點(Node)都包含兩方面的內容: 
1.節點自己的數據(data); 
2.下一個節點的信息(nextNode)。 
因此當對LinkedList作添加,刪除動做的時候就不用像基於數組的ArrayList同樣,必須進行大量的數據移動。只要更改nextNode的相關信息就能夠實現了,這是LinkedList的優點。緩存

List總結

  • 全部的List中只能容納單個不一樣類型的對象組成的表,而不是Key-Value鍵值對。例如:[ tom,1,c ]
  • 全部的List中能夠有相同的元素,例如Vector中能夠有 [ tom,koo,too,koo ]
  • 全部的List中能夠有null元素,例如[ tom,null,1 ]

     基於Array的List(Vector,ArrayList)適合查詢,而LinkedList 適合添加,刪除操做tomcat

Set(Set是不包含重複元素的Collection)

HashSet

雖然Set同List都實現了Collection接口,可是他們的實現方式卻大不同。List基本上都是以Array爲基礎。可是Set則是在 HashMap的基礎上來實現的,這個就是Set和List的根本區別。HashSet的存儲方式是把HashMap中的Key做爲Set的對應存儲項。看看 HashSet的add(Object obj)方法的實現就能夠一目瞭然了。安全

LinkedHashSet

HashSet的一個子類,一個鏈表。服務器

SortedSet

有序的Set,經過SortedMap來實現的。cookie

Set總結:

1)Set實現的基礎是Map(HashMap)(2)Set中的元素是不能重複的,若是使用add(Object obj)方法添加已經存在的對象,則會覆蓋前面的對象

 

HashMap

API ----基於Hash表的Map  接口實現。此實現提供全部可選的映射操做,並容許  值和    鍵。(  HashMap 類大體至關於Hashtable,除了它是不一樣步的而且容許空值。)這個類不保證地圖的順序; 特別是,它不保證訂單會隨着時間的推移保持不變。  

TreeMap

API ----基於紅黑樹的 NavigableMap  實現。地圖根據 其鍵 天然順序進行排序 ,或者 Comparator  根據使用的構造函數在地圖建立時提供。 
TreeMap則是對鍵按序存放,所以它便有一些擴展的方法,好比firstKey(),lastKey()等,你還能夠從TreeMap中指定一個範圍以取得其子Map。 
鍵和值的關聯很簡單,用put(Object key,Object value)方法便可將一個鍵與一個值對象相關聯。用get(Object key)可獲得與此key對象所對應的值對象。 
 
HashMap:適用於在Map中插入、刪除和定位元素。
Treemap:適用於按天然順序或自定義順序遍歷鍵(key)
 
1、幾個經常使用類的區別 
1.ArrayList: 元素單個,效率高,多用於查詢 
2.Vector: 元素單個,線程安全,多用於查詢 
3.LinkedList:元素單個,多用於插入和刪除 
4.HashMap: 元素成對,元素可爲空 
5.HashTable: 元素成對,線程安全,元素不可爲空 
2、Vector、ArrayList和LinkedList 
大多數狀況下,從性能上來講ArrayList最好,可是當集合內的元素須要頻繁插入、刪除時LinkedList會有比較好的表現,可是它們三個性能都比不上數組,另外Vector是線程同步的。因此: 
若是能用數組的時候(元素類型固定,數組長度固定),請儘可能使用數組來代替List; 
若是沒有頻繁的刪除插入操做,又不用考慮多線程問題,優先選擇ArrayList; 
若是在多線程條件下使用,能夠考慮Vector; 
若是須要頻繁地刪除插入,LinkedList就有了用武之地; 
若是你什麼都不知道,用ArrayList沒錯。 
 
談談你對HashMap的理解,底層原理的基本實現,HashMap怎麼解決碰撞問題的?
https://blog.csdn.net/weixin_37751634/article/details/82882222
 
http協議,get和post的基本區別?
  • get(默認值)是經過URL傳遞表單值,數據追加在action屬性後面。
  • post傳遞的表單值是隱藏到http報文體中,url中看不到。
  • get是經過url傳遞表單值,post經過url看不到表單域的值;
  • get傳遞的數據量是有限的,若是要傳遞大數據量不能用get,好比type=「file」上傳文章、type=「password」傳遞密碼或者<textarea>發表大段文章,post則沒有這個限制。
  • post區別:網址隱藏;只要當前頁面請求是POST請求,那麼刷新就是從新發出POST,部分瀏覽器會提示「是否重複提交」。
  • 只要在地址欄中輸入一個網址回車訪問,那麼就是GET。精確到具體網頁

數據格式。服務端文件名後跟着「?」,因爲客戶端可能向服務器端提交多個鍵值對,鍵值對之間用「&」進行分割,若是URL中有漢字、特殊符號等,則須要對URL進行編碼。

Http協議定義了不少與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用於描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應着對這個資源的查,改,增,刪4個操做。 咱們最多見的就是GET和POST了。GET通常用於獲取/查詢資源信息,而POST通常用於更新資源信息.

咱們看看GET和POST的區別

1. GET提交的數據會放在URL以後,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456.(注意對於用戶登陸來講,get是不安全的,網頁直接顯示你的用戶名和密碼) POST方法是把提交的數據放在HTTP包的Body中.

2. GET提交的數據大小有限制(由於瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.

3. GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值。

4. GET方式提交數據,會帶來安全問題,好比一個登陸頁面,經過GET方式提交數據時,用戶名和密碼將出如今URL上,若是頁面能夠被緩存或者其餘人能夠訪問這臺機器,就能夠從歷史記錄得到該用戶的帳號和密碼.

tcp/ip協議,三次握手,窗口滑動機制:

 https://www.cnblogs.com/wen-ge/articles/5819778.html

悲觀鎖和樂觀鎖問題使用場景?

悲觀鎖:比較適合寫入操做比較頻繁的場景,若是出現大量的讀取操做,每次讀取的時候都會進行加鎖,這樣會增長大量的鎖的開銷,下降了系統的吞吐量。

樂觀鎖:比較適合讀取操做比較頻繁的場景,若是出現大量的寫入操做,數據發生衝突的可能性就會增大,爲了保證數據的一致性,應用層須要不斷的從新獲取數據,這樣會增長大量的查詢操做,下降了系統的吞吐量。

總結:兩種所各有優缺點,讀取頻繁使用樂觀鎖,寫入頻繁使用悲觀鎖。

分佈式session的幾種實現方式

第一種:粘性session

原理:粘性Session是指將用戶鎖定到某一個服務器上,好比上面說的例子,用戶第一次請求時,負載均衡器將用戶的請求轉發到了A服務器上,若是負載均衡器設置了粘性Session的話,那麼用戶之後的每次請求都會轉發到A服務器上,至關於把用戶和A服務器粘到了一塊,這就是粘性Session機制。

優勢:簡單,不須要對session作任何處理。

缺點:缺少容錯性,若是當前訪問的服務器發生故障,用戶被轉移到第二個服務器上時,他的session信息都將失效。

適用場景:發生故障對客戶產生的影響較小;服務器發生故障是低機率事件。

第二種:服務器session複製

原理:任何一個服務器上的session發生改變(增刪改),該節點會把這個 session的全部內容序列化,而後廣播給全部其它節點,無論其餘服務器需不須要session,以此來保證Session同步。

優勢:可容錯,各個服務器間session可以實時響應。

第三種:session共享機制

使用分佈式緩存方案好比memcachedRedis,可是要求Memcached或Redis必須是集羣。

使用Session共享也分兩種機制,兩種狀況以下:

① 粘性session處理方式

原理:不一樣的 tomcat指定訪問不一樣的主memcached。多個Memcached之間信息是同步的,能主從備份和高可用。用戶訪問時首先在tomcat中建立session,而後將session複製一份放到它對應的memcahed上。memcache只起備份做用,讀寫都在tomcat上。當某一個tomcat掛掉後,集羣將用戶的訪問定位到備tomcat上,而後根據cookie中存儲的SessionId找session,找不到時,再去相應的memcached上去session,找到以後將其複製到備tomcat上。

② 非粘性session處理方式

原理:memcached作主從複製,寫入session都往從memcached服務上寫,讀取都從主memcached讀取,tomcat自己不存儲session

缺點:會對網絡負荷形成必定壓力,若是session量大的話可能會形成網絡堵塞,拖慢服務器性能。

JVM老年代和新生代的比例?2:1

JVM虛擬機 YGC和FGC發生的具體場景

一、YGC和FGC是什麼 

   YGC :對新生代堆進行gc。頻率比較高,由於大部分對象的存活壽命較短,在新生代裏被回收。性能耗費較小。

   FGC :全堆範圍的gc。默認堆空間使用到達80%(可調整)的時候會觸發fgc。

二、何時執行YGC和FGC

   一、eden空間不足,執行 young gc

   二、old空間不足,perm空間不足,調用方法System.gc() ,ygc時的悲觀策略, dump live的內存信息時(jmap –dump:live),都會執行full gc

如何保證共享變量修改時的原子性?

使用synchronized(低效,使用悲觀鎖)、volatile修飾符來保證變量的可見性

Jdk5後提出了atomic 原子操做也能夠保證可見性(高效且不須要使用同步,基於CAS)

Volatile和synchronized區別:

Volatile只是保證變量可見性,並不能確保原子性,它是依賴CPU提供的特殊指令內存屏障指令來控制可見性,被Volatile修飾的成員變量在被線程訪問時在讀操做前會強行插入一條內存屏障讀指令強行從主存中讀取(讓高速緩存中的數據失效,從新從主內存加載數據),變量在被線程修改時會在寫指令以後插入寫屏障,讓寫入緩存的最新數據寫回到主內存。

不能確保原子性,是由於若是A線程和B線程同時讀取到變量a值,A線程修改a後將值刷到主存、同時B線程也修改了a的值並刷到主存,這時候B線程就覆蓋了A線程修改操做。

Synchronized是經過對線程加鎖(獨佔鎖)控制線程同步,被Synchronized修飾的內存只容許一個線程訪問

線程池的構造類的方法的5個參數的具體意義?

corePoolSize
核心線程數,核心線程會一直存活,即便沒有任務須要處理。當線程數小於核心線程數時,即便現有的線程空閒,線程池也會優先建立新線程來處理任務,而不是直接交給現有的線程處理。

核心線程在allowCoreThreadTimeout被設置爲true時會超時退出,默認狀況下不會退出。

maxPoolSize
當線程數大於或等於核心線程,且任務隊列已滿時,線程池會建立新的線程,直到線程數量達到maxPoolSize。若是線程數已等於maxPoolSize,且任務隊列已滿,則已超出線程池的處理能力,線程池會拒絕處理任務而拋出異常。
keepAliveTime
當線程空閒時間達到keepAliveTime,該線程會退出,直到線程數量等於corePoolSize。若是allowCoreThreadTimeout設置爲true,則全部線程均會退出直到線程數量爲0。

allowCoreThreadTimeout
是否容許核心線程空閒退出,默認值爲false。

queueCapacity
任務隊列容量。從maxPoolSize的描述上能夠看出,任務隊列的容量會影響到線程的變化,所以任務隊列的長度也須要恰當的設置。

詳細見:https://blog.csdn.net/u011109589/article/details/80532796

單機上一個線程正在處理服務,若是突然斷電了怎麼辦

咱們能夠對正在處理和阻塞隊列的任務作事物管理或者對阻塞隊列中的任務持久化處理,而且當斷電或者系統崩潰,操做沒法繼續下去的時候,能夠經過回溯日誌的方式來撤銷正在處理的已經執行成功的操做。而後從新執行整個阻塞隊列。

阻塞隊列持久化,正在處理事物控制。斷電以後正在處理的回滾,日誌恢復該次操做。服務器重啓後阻塞隊列中的數據再加載

 防止接口重複請求

1.在data裏定義一個初始狀態,設爲false,做爲加載標誌

2.請求以前將狀態變成true,再去請求接口,這時一直是加載狀態

3.當接口響應以後不論是成功仍是失敗都將狀態變成false

4.每次請求以前都判斷一下加載狀態,若是是true直接return

相關文章
相關標籤/搜索