JAVA基礎
-
JDK和JRE的區別
- JDK爲開發工具包提供Java的開發環境和運行環境
- JRE爲java運行環境
- 運行JAVA程序,安裝JRE即可;編寫JAVA程序需要JDK
-
==和equals()的區別
- ==對於基本類型來說是值比較,對於引用類型來說比較的是引用
- equals()默認情況下是引用比較,但是很多類從寫了equals()方法例如String,integer把它變成了值比較
-
兩個對象的hashCode()相同,equals()一定爲ture嗎?
- 不對,在散列表中,hashCode()相同即爲兩個鍵值對的哈希值相等,然而哈希值相等鍵值對並不一定相等
-
final的作用
- final修飾類,不能被繼承
- final修飾的方法不能被重寫
- final修飾的變量叫常量,不能被修改,必須初始化
-
Math.round(11.5)和Math.round(-11.5)的區別
- Math類中提供了三個與取整有關的方法:ceil,floor,round,這些方法的作用於它們的英文名稱的含義相對應,例如:ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果爲12,Math.ceil(-11.6)的結果爲-11;floor的英文是地板,該方法就表示向下取整,Math.floor(11.6)的結果是11,Math.floor(-11.4)的結果-12;最難掌握的是round方法,他表示“四捨五入”,算法爲Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,所以,Math.round(11.5)的結果是12,Math.round(-11.5)的結果爲-11.Math.round( )符合這樣的規律:小數點後大於5全部加,等於5正數加,小於5全不加。
-
String屬於基本類型嗎
- 不屬於,屬於對象(short,byte,long,char,int,float,double,boolean)
-
操作字符串的都有哪些類
- String:聲明的是不可變對象,每次操作都會生成新的String對象
- StringBuffer:線程安全,性能略低,多線程推薦
- StringBuilder:線程不安全,性能略高,單線程推薦
-
String str ="i"和 Stirng str = new String(“i”)一樣嗎
- 不一樣,一個在常量池,一個分配新堆內存
-
如將字符串反轉
- StringBuilder和StringBuffer的reverse()方法
-
String常用方法
- indexOf(),charAt(),replace(),trim(),split(),getBytes()
- length(),toLowerCase(),toUpperCase(),substring(),equals()
-
抽象類一定要有抽象方法嗎
- 不一定,可有可無
-
普通類和抽象類的區別
- 普通類不能包含抽象方法,直接實例化
- 抽象可以有抽象方法也可以有普通方法,不能直接實例化
-
抽象類能用final修飾嗎
- 不能,抽象類就是讓其他類繼承,與final的本意矛盾
-
接口和抽象類的區別
- inplements/extends
- 單繼承,多實現
-
IO流分幾種
- 功能:輸出流(output),輸入流(input)
- 類型:字節流,字符流
-
BIO/NIO/AIO
- BIO,同步阻塞式IO
- NIO,同步非阻塞IO
- AIO,異步非阻塞IO
-
Files常用方法
- Files.exists() 是否存在
- Files.creatrFile() 創建文件
- Files.createDiectory() 創建文件夾
- Files.delete() 刪除文件
- Files.copy() 複製文件
- Files.move() 移動文件
- Files.size() 文件大小
- Files.read() 讀取文件
- Files.write() 寫入文件
-
Conection和Map
- Conection:List/ArrayList/LinkedList/set/hashSet/TreeSet
- Map:HashMap/LinkedHashMap/TreeMap/Hashtable/ConcurrentHashMap
-
Conection和Conllentions的區別
- Conection是一個集合接口
- Conections是一個工具類
-
List,Set,Map的區別
- list:有序,允許重複
- set
- HashSet :無序,不允許重複
- TreeSet:有序,不允許重複(二叉樹排序)
- Map:
- HashMap :無序,key唯一,value可重複
- TreeMap:有序,key唯一,value可重複(二叉樹排序)
-
HashMap和Hashtable的區別
- 存儲:HashMap允許key,value爲null,HashTable不允許
- 線程安全:Hashtable 線程安全,HashMap線程不安全
- 單線程推薦實用HashMap,多線程推薦使用ConcurrentHashMap(HashTable爲保留類不建議使用)
-
HashMap的實現原理
- 基於Hash算法實現,我們通過put(key,value)存儲,get(key)來獲取,當傳入key時,HashMap會根據key.hashCode()計算出hash值,過呢局hash值將value保存在bucket裏,當計算出的hash值相同時,我們稱之爲hash衝突,HashMap的做法是用鏈表和紅黑樹儲存hash相同的hash值的value,當hash衝突的個數較少時,實用鏈表否則實用紅黑樹
-
ArrayList和LinkedList的區別
- 數據結構實現:ArrayList是動態數組的數據結構實現,LinkedList是雙向鏈表
- 隨機訪問效率:ArrayList爲動態數組,訪問效率較高
- 增刪改效率: 在非首尾的增刪操作,Linked List要比ArrayList效率高
-
如何實現數組和list的互轉
- 數組轉List:Arrays.asList(array)
- List轉數組:實用List自帶頭Array()
-
Array和ArrayList的區別
- Array:儲存基本類型和對象,固定大小
- ArrayList:存儲對象,自定擴展
-
哪些集合類是縣城安全的
- Vector,Hshtable,Stack都是線程安全的,在JDK1.5後HashMap又有了自己對應的線程安全類:ConcurrentHashMap
-
Iterator迭代器是什麼?
- Iterator接口提供遍歷任何Conection的接口,我們可以從一個Collection中迭代器的方法獲取迭代器實例
- 迭代器取代了java集合框架的Enumeration,迭代器允許調用者在迭代過程中移除元素
-
Iterator的實用,有什麼特點
-
Iterator的特點時更加安全,因爲它可以確保,在當前遍歷的集合元素被更改的時候,就會拋出異常
-
List<String>list = new ArrayList<>(); Iterator<String>it = list.iterator(); while(it.hasNext()){ String obj = it.next(); System.out.println(obj); }
-
-
Iterator和ListIterator有什麼區別
- Iterator可以遍歷Set和List集合,單向遍歷
- ListIterator只能遍歷List,雙向遍歷,比Iterator新添加額外的功能(心添,替換)
-
如何確保一個集合不被修改
-
List<String> list = new ArrayList<>(); list.add("a"); //設置爲只讀,不能被修改 Collection<String> strings = Collections.unmodifiableCollection(list); strings.add("1");//運行報錯
多線程
-
-
併發和並行
- 兩個隊列和一個咖啡機
- 兩個隊列和兩個咖啡機
-
進程和線程
- 一個程序下至少一個進程,一個進程至少一個線程,也可以有多個來增加執行速度
-
守護線程是什麼
- 守護線程時運在後臺的一種特殊進程,他獨立於控制終端並且中期行執行某種任務,例如java垃圾回收線程
-
創建線程的方式
- 繼承Thread重寫run方法
- 實現Runnable接口(無返回值)
- 實現Callable接口(有返回值)
-
sleep()和wait()的區別
- 類不同:sleep()來自Thread,wait來自Obgect
- 釋放鎖:sleep()不釋放鎖,wait()釋放鎖
- 用法不同:sleep()到期自動恢復,wait()可以使用notify/notifyAll()直接喚醒
-
notify/notifyAll()的區別
- notifyAll()會喚醒所有線程,將全部線程由等待池移到鎖池,參與鎖的競爭
- notify()只會喚醒一個,具體喚醒哪一個有虛擬機控制
-
線程的run()和start()有什麼區別
- start()用戶啓動線程,只能調用一次
- run()用於執行線程的運行時代碼,可重複調用
-
創建線程池有幾種方式
- newSingleThreadExecutor():特點在於工作線程數目爲1,操作一個無界的工作隊列,所以他保證所有的任務都會順序進行,最多有一個任務處於活動狀態
- newCachedThreadExecutor():一種用來處理大量段時間工作任務的線程池,具有幾個鮮明特點,他會試圖緩存線程並重用,當無緩存線程可用,就會創建新的工作線程,如果線程閒置超過60秒,則被終止並移除緩存,長時間閒置,這種線程池不會消耗資源,其內部使用SynchronousQueue作爲工作隊列
- newFixedThreadPool:重用指定數目的線程,其背後使用的無界隊列任何時候最多有NThread個工作線程是活動的,這就意味着,如果任務數量超過了活動隊列的數據,將在工作隊列中等待空閒線程,如果有工作線程推出,將會有限的工作線程被創建,補足指定數目的Nthreads
- newWorkStralingPool:java8才新添加的創建方法,其內部會構建ForkJoinPool,利用Work-Straling算法,並行地處理任務,不保正處理順序
- ThreadPoolExecutor:最原始的線程創建方式
-
線程池的狀態
- RUNNING:接受新任務,處理等待隊列任務
- SHUDOWN:不接受新任務,處理等待隊列任務
- STOP:不接受新任務,不處理等待隊列任務
- TIDYING:所有任務銷燬,自動轉爲TIDYING狀態,執行terminated()方法
- TERMINATED:執行terminated()方法,線程池狀態
-
線程池submit()和execute()區別
- execute():只執行Runnable類型任務
- submit():可以執行Runnable和Callable類型任務
-
如何保證線程安全
-
使用安全類 concurrent下的
-
使用自動鎖 synchronized
-
使用手的鎖 Lock
-
//手動鎖 Lock lock = new ReentrantLock(); lock.lock(); try{ Sysetm.out.println("獲得鎖"); }catch(Exception e){ }finally{ Sysetm.out.println("釋放鎖"); lock.unlock(); }
-
-
多線程中Synchronized鎖升級的原理是什麼
- 在鎖對象的對象裏有一個threadid字段,在第一次訪問的時候,他爲空,jvm讓其持有偏向鎖,並將次字段設置爲線程id,再次進入的時候會判斷此字段於線程id是否相同,如果一致,使用此對象,如果不一致,則升級爲輕量鎖,通過自身循環一定次數來獲取鎖,執行一定次數後,還沒有想要時候用的對象,此時就把鎖升級爲重量鎖
- 爲了降低鎖帶來的性能消耗
-
什麼是死鎖
- 當線程A持有獨佔鎖a,並嘗試去獲取獨佔鎖b的同時,線程B持有獨佔鎖b,並嘗試獲取獨佔鎖a的情況下,就會發生AB兩個線程由於互持對方所需要的鎖,而發生的阻塞現象
-
怎麼防止死鎖
- 儘量設置超時時間TryLock(long time ,TimeUnit unit)
- 儘量使用concurrent併發類代替自己手寫鎖
- 儘量降低鎖的使用粒度,不要幾個功能用同一把鎖
- 儘量減少同步代碼快
-
ThreadLocal是什麼,實用場景是什麼
- 爲每個使用該變量的線程提供獨立的變量副本
- 數據庫連接和session管理
-
synchronized的底層實現
- 由一對monitorenter/monitorexit指令實現,monitor對象是同步的基本實現單元
- 偏向鎖,輕量鎖,重量鎖
-
synchronized和volatile的區別
- volatile:變量修飾符,不能保證原子性,不會造成線程堵塞
- synchronized:修飾方法,類,代碼段,能保證原子性,可能會造成堵塞
-
synchronized和Lock的區別
- synchronized可以給類,方法,代碼塊加鎖,不需要手動去獲取釋放鎖,不會造成死鎖,不知道有沒有成功獲取到鎖
- Lock:只能給代碼塊加鎖,需要手動獲取和釋放鎖,會造成死鎖(使用不當沒有實用unLock()釋放的話)
-
atomic的原理
- atomic主要利用CAS和volatile和native方法來保證原子操作,從而避免synchronized的高開銷
反射
-
什麼是反射
- 反射是運行狀態中,任意一個類,都能夠知道這個類的所有屬性和方法,對於任意一個對象都能調用他的任意方法和屬性
-
什麼是Java序列化,什麼情況下需要序列化
- 序列化是爲了保存各種對象在內存中的狀態,並且可以把保存的對象狀態在讀出來
- 一下情況需要序列化
- 想把內存中的對象狀態保存到一個文件中或者數據庫中
- 想用套接字在網絡上傳送對象
- 想通過RMI遠程方法調用傳輸對象的時候
-
動態代理
- JDK的原生動態代理(基於接口實現)和cglib動態代理(繼承當前類的子類實現)
JavaWeb
-
JSP和Servlet的區別
- JSP是servlet技術的擴展,本質就是servlet,主要的不同是servlet應用在java文件用於控制邏輯,JSP側重於試圖
-
JSP的內置對象
- request:封裝客戶端的請求,其中保護趕來get或者post的請求參數
- reponse:封裝服務器對客戶端的響應
- pageContext:通過該對象客氣獲取其他對象
- session: 封裝用戶繪畫的對象
- application:封裝服務器運行環境的對象
- out:輸出服務器相應的輸出流對象
- confi:web應用的配置對象
- page:jsp頁面本身
- exception:封裝頁面拋出的異常對象
-
jsp的4中域
- page:代表與一個頁面相關的對象和屬性
- request:代表與客戶端發出一個請求相關的對象和屬性,一個請求可能跨多個頁面,涉及多個web組件,需要在頁面顯示的臨時數據可以置於此作用域
- session:代表與某個用戶與服務器建立的一次繪畫相關的對象和屬性,跟某個用戶相關的數據應該放在用戶自己的session中
- application:代表與整個web應用程序相關的對象和屬性,它是指就是跨越整個web應用程序,包含多個頁面,請求和會話的一個全局作用域