1. 程式人生 > >面試必備系列-Java基礎相關(一)

面試必備系列-Java基礎相關(一)

目前網上的面試題氾濫成災,真正有價值的很少,往往是爛大街的問題,同時也沒有給出正確的解決方案 , 本文旨在整理一一系列對面試者有幫助的文章,後續會持續更新。

String 類為什麼是final的

答案是為了 “效率”和安全,

安全: 由於String類被final修飾符修飾,那麼他就是不可被繼承,創建出來的物件之後也就是不可以被改變的。加上String字串有常量池的概念,如果沒有被final修飾符修飾,那麼建立之後的物件是不可以保證的,容易產生安全性問題。同時,在String類使用非常廣泛的情況下,這種設計是非常必要的。效率: 設計成final,JVM才不用對相關方法在虛擬函式表中查詢,而直接定位到String類的相關方法上,提高了執行效率。 (涉及到了JVM的實現細節,在此筆者也不是很懂,在此分享給大家,有興趣的可以詳細瞭解)

HashMap的底層實現, jdk1.8有何變化

HashMap底層是通過資料+連結串列的形式實現的, HashMap初始化的時候,會預設建立長度為16的陣列,put的時候通過HashCode求餘的方式來確定KEY的位置,如果HashCode相同,那麼相同hashCode的值會放在一個連結串列上面。 如此可見,當放入HashMap中的key的HashCode衝突比較大時,當嚴重影響效率。

JDK1.8之後,當連結串列數量達到8個以上時,會採用紅黑樹來實現。

HashSet集合實現原理是什麼

HashSet底層採用的是雜湊表來實現的,其原理和HashMap一致,只是對HashMap的API做了一層封裝有點類似於value為null的hashMap

Java中的佇列有哪些,有何區別

在此列出幾個常用的佇列。

阻塞佇列

  • ArrayBlockingQueue :一個由陣列支援的有界佇列,阻塞佇列,讀寫共享一把鎖

  • LinkedBlockingQueue :一個由連結節點支援的可選有界佇列,阻塞佇列 , 讀寫分別採用的是不同的鎖。

  • DelayQueue :基於時間的排程佇列,比如說往這個佇列中新增一個元素,同時指定3秒鐘,那麼只有過了3秒鐘之後,才能夠從該佇列中取到這個元素

非阻塞佇列

  • ConcurrentLinkedQueue

是一個基於連結節點無界安全的佇列,基於CAS操作保證佇列裡面資料的一致性 , 該佇列的size()方法是會遍歷整個佇列的,因此及其耗費效能,通常使用isEmpty()來判斷集合是否為空。

ConcurrentHashMap實現原理

採用分段鎖的概念, ConcurrentHashMap在初始化時,預設會產生16個段(Segment),每個段內部又是一個數組,陣列中的每個元素又是一個連結串列,說的通俗一點,Segment的結構有點類似於HashMap . 
當有元素需要新增進來的時候,首先進行一次Hash , 計算出該元素會被分配到哪個段裡面,  確定好在哪個段裡面之後,進行第二次Hash, 確定在段的陣列中哪個位置,第二次Hash來確定在陣列中哪個位置,和HashMap的原理一致。

ConcurrentHashMap 大量的採用volatile, CAS,final,lock等技術,減少鎖的競爭對效能產生的影響、

異常的結構,執行時異常和非執行時異常,各舉個例子

異常的結構:

Thorwable 是所有異常和錯誤的基類。

Error 和Exception .

Error : 是JVM執行產生的錯誤,是不可以感知的,當發生時,會導致程式中斷,應用程式無法捕獲

Exception : 程式可以捕獲的異常,應用程式可以處理的異常資訊,分為執行時異常和非執行時異常

非執行時異常 : 程式必須要處理的異常,否則不能編譯通過,如: IOException, SQLException

執行時異常 :程式在執行過程中可能產生的異常,這個不強制要求處理。 如: RuntimeException

弱引用, 軟引用 的概念和使用方式。

軟引用:當JVM記憶體不夠時,會強制回收軟引用,如果回收了之後,還不能滿足當前的記憶體需求,則會報記憶體溢位的錯誤,通常用於本地快取的使用。

弱引用: 通過 WeakReference 標識這是一個弱引用,生命週期比較短,當系統觸發垃圾回收的時候,如果一個物件只具有弱引用,那麼就會被回收 , 比如:ThreadLocal中引用的ThreadLocalMap中的Entry就是一個弱引用,大家有時間可以取看一下。

volatile的理解

volatile是在多執行緒的環境中,對於變數的一個修飾符。

場景:

大家都知道,每個程式有主記憶體, 每個執行緒都有自己的工作記憶體, 執行緒工作記憶體之中的資料是不

共享的,在這裡舉個例子;

Thread A  查詢  int  x   ,此時主記憶體中的x = 0 ,那麼Thread A  通過read ,load 的操作將變數x載入到自己的工作記憶體當中,同時修改x = 1 , 這個時候主記憶體當中的x 還是等於0  ,所以當另外一個執行緒Thread B 過來載入x 的時候,獲取到的還是0 。那麼volatile的作用是什麼呢? 該關鍵字主要是保證執行緒之間變數的可見性。 按照上面的例子,如果volatile int x = 0 , 然後被Thread A載入到他的工作記憶體中修改為了1 ,那麼他在修改的同時,會將
x = 1 ,推送到主記憶體,修改主記憶體裡面的值。

總而言之: volatile保證變數的可見性,但不保證原子性。

CAS是什麼

CAS是CPU底層的原子命令 , 裡面有三個概念,一定要記住

記憶體值,預期值,更新值

當: 記憶體值==預期值  的時候,才會將記憶體值修改為 更新值, 否則不做任何操作

AtomicInteger有用過嗎? 通常用於什麼場景? 基於什麼原理實現的。

用過, 在專案當中一般用於高併發場景,主要用於計數的功能 。 該類是通過CAS的方式來保證執行緒安全的。

i++為什麼不是執行緒安全的

因為在多執行緒的環境下, i++本身就不是一個原子操作,i++的執行過程過下,

Thread從主記憶體中讀取i = 1 到執行緒的工作記憶體, 線上程中使用完畢之後,執行  i = i+1 , 這個變數i 並沒有同步到主記憶體中區,Thread B又來讀取了,這個時候讀取到的還是 1  ,想到這裡大家應該都明白了,在多執行緒的情況下,i++是會造成資料錯誤的

解決方式:

  1. 使用synchronized同步,但是比較耗費效能。不推薦

  2. 使用AtomicInteger , 其是通過CAS原子操作來保證資料的安全行的,推薦使用

SimpleDateFormat是執行緒安全的嗎?

不是, SimpleDateFormat的內部都是使用Calendar這個物件來操作時間的,如果SimpleDateFormat是靜態的,那麼在多執行緒環境下,多個執行緒操作一個物件,是會有執行緒安全問題的。

下面是SimpleDateFormat的parse方法

Date parse() {

  calendar.clear(); // 清理calendar

  ... // 執行一些操作, 設定 calendar 的日期什麼的

  calendar.getTime(); // 獲取calendar的時間

}

這裡會導致的問題就是, 如果 執行緒A 呼叫了 sdf.parse(), 並且進行了 calendar.clear()後還未執行calendar.getTime()的時候,執行緒B又呼叫了sdf.parse(), 這時候執行緒B也執行了sdf.clear()方法, 這樣就導致執行緒A的的calendar資料被清空了(實際上A,B的同時被清空了). 又或者當 A 執行了calendar.clear()後被掛起, 這時候B 開始呼叫sdf.parse()並順利i結束, 這樣 A 的 calendar記憶體儲的的date 變成了後來B設定的calendar的date

解決方案:

  1. 每次使用之前,建立一個SimpleDateFormat 物件  ,在高併發的情況下,每次都要建立和銷燬該物件是非常耗費效能的,因此不推薦使用。

  2. 使用同步程式碼塊synchronized,同步區域性程式碼。

  3. 使用TheadLocal儲存日期物件,為每個執行緒建立自己的SimpleDateFormat 物件,這樣在高併發的情況對效能影響較小。

  4. 使用第三方的時間轉換的庫

PS: 以上是筆者自己的理解,如果有什麼地方錯誤了,請留言告知我,  我馬上修改 , 大家在面試過程中遇到過哪些奇葩問題? 快快留言告訴我,我整理出來分享給大家。

感興趣的可以關注一下本人的公眾號,大量技術乾貨分享

sharedCode原始碼交流群,歡迎喜歡閱讀原始碼的朋友加群,新增下面的微信, 備註”加群“ 。 

相關推薦

面試必備系列-Java基礎相關

目前網上的面試題氾濫成災,真正有價值的很少,往往是爛大街的問題,同時也沒有給出正確的解決方案 , 本文旨在整理一一系列對面試者有幫助的文章,後續會持續更新。 String 類為什麼是final的 答案是為了 “效率”和安全, 安全: 由於String類被final修飾符

JAVA面試必備的知識寶典

java相關概念面向對象的三個特征封裝,繼承,多態.這個應該是人人皆知.有時候也會加上抽象.多態的好處允許不同類對象對同一消息做出響應,即同一消息可以根據發送對象的不同而采用多種不同的行為方式(發送消息就是函數調用).主要有以下優點:可替換性:多態對已存在代碼具有可替換性.可擴充性:增加新的子類不影響已經存在

java基礎——Servlet

.get protected pre exc 規範 直接下載 程序 新建 路徑 一.Servlet簡介 Servlet(Server Applet)是Java Servlet的簡稱,稱為小服務程序或服務連接器,用Java編寫的服務器端程序,主要功能在於交互式地瀏覽和修改數據

C#系列基礎知識點

命名規則 系列 字符 註釋 編輯器 小數類型 智能 規則 解釋 知識點一:VS啟動方法 第一種:雙擊圖標 第二種:window+R——調出cmd,輸入devenu properties 屬性的意思 知識點二:後綴名解釋 .sln 解決方案文件:包含整個解決方案的信息 .

Java基礎摘要

引用 rom col 精確 發送 邏輯 內部數據 保留 實例 三大特性 封裝   所謂封裝,也就是把客觀事物封裝成抽象的類,並且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。封裝是面向對象的特征之一,是對象和類概念的主要特性。簡單的說,一個類就

Java基礎語法

*********************************成員變數***************************** 定義在類體內,方法體外的變數..... public class Hello{ //一.成員變數 //1.靜態變數 //static int a = 10; //2

JAVA基礎複習小細節

1、區別大小寫;小寫字母命名變數和方法,多個單詞,第一個單詞字母小寫,其餘首字母大寫;類名每個首字母大寫;常量所有字母大寫,單詞間使用下劃線連線;$用於機器自動產生的原始碼中。 2、%的計算,只有當被除數是負數時,餘數才是負數 3、整型預設int,浮點預設double,long追加L,flo

java基礎記錄:開發環境的配置

一、JDK的安裝與環境變數配置   1.jdk下載與安裝。 jdk1.8.0_192下載地址 下載完成後,雙擊執行安裝檔案。可以選擇你要安裝的位置或者直接下一步,等待安裝完成,最後關閉。 2.配置環境變數。 選中我的電腦右鍵-->屬性-->高階系統設定-->環境變數,

JAVA基礎回顧

1.面向物件和麵向過程的區別 面向過程: 優點:效能要高於面向物件,面向物件中的類在呼叫的時候需要例項化,中間需要載入的資源比較多(微控制器、嵌入式開發、linux一般使用面向過程的思想進行開發) 缺點:不易維護,不易複用,不易擴充套件 面向物件: 優點:易於維護,易於複用,易於

java基礎-中級【集合】

目錄   1、集合 1.1 集合框架          1.1.1 集合介面          1.1.2 集合實現類      

java基礎-初級java的基本語法】

目錄 1、java的基本語法 1、java的基本語法        關鍵字、註釋、運算子、變數、常量、進位制和進位制轉換、語句、資料型別和資料轉換、識別符號。 關鍵字:關鍵字是電腦語言中事先預定好的有意義的識別符號,又叫保留關鍵字

Java基礎鞏固-資料型別

Java基本型別哪些,所佔位元組和範圍 Java語言提供了八種基本型別。六種數字型別(四個整數型,兩個浮點型),一種字元型別,還有一種布林型。 1.byte: byte 資料型別是8位、有符號的,以二進位制補碼錶示的整數; 最小值是 -128(-2^7); 最大值是 127(2^

Java基礎--- 資料型別、函式、控制符

基本資料型別 1.整數型別: byte(1 位元組 ), short(2 位元組 ), int(4 位元組 ), long(8 位元組 ) 1位元組=8位,而每一個數的第一位為符號位,並且-0(負零)用-128表示,所以byte的範圍為:-2^(位元組8-1) --> 2^(位元組

Java基礎——集合——集合體系、Collection集合

一、集合概述          Java是一種面嚮物件語言,如果我們要針對多個物件進行操作,就必須對多個物件進行儲存。而陣列長度固定,不能滿足變化的要求。所以,java提供了集合。          特點                 1.        長度可以發生改變

Java基礎學習資料結構

基礎問題  1. 幾類資料結構的定義和區別是什麼? 2. 容器的資料結構底層是怎麼實現的?怎麼進行擴容? 3. 容器的執行緒安全怎麼實現? 一、List容器 資料有序,允許重複資料,執行緒不安全。 1. linkedList  底層用雙向連結串列實現,操作速度快,可以在頭、尾、[n]操作資料。 2. Arr

Java基礎總結物件,類,屬性,方法

物件,類,屬性,方法的解析: 以人為例。 類:人可以看作一個類。 物件:具體到什麼人(黃種人,白種人,黑種人,中國人等等)這就可以看作是物件,可以根據需求繼續往下區分,比如 男人 女人。 屬性:比如說黃種人的特點:黃面板,黑頭髮,黑眼睛等等,這些就是黃

是時候複習一下Java基礎

寫了很久的程式碼,但是今天突然發現Java的很多基礎知識都漸漸變得模糊了。所以來從頭複習一下。 Java面向物件的理解 主要是面向物件的四大特徵(也有人說是三大特徵) 抽象 抽象就是尋找事物的共性,注意力放在目標相關的方面而忽略與其無關的方面。包括資料的

java集合系列——java集合概述

在JDK中集合是很重要的,學習java那麼一定要好好的去了解一下集合的原始碼以及一些集合實現的思想! 一:集合的UML類圖(網上下載的圖片) Java集合工具包位置是java.util.* 二:集合工具的分析 1:Java集合是java提

Java基礎語法識別符號,關鍵字,註釋,常量,變數,基本資料型別

1.識別符號 Java中識別符號就是給程式中的變數,類,方法名命名的符號。     規則:1.可以又字母、數字、下劃線(_)和美元符號($)組成,但是                2.不能是java

黑馬程式設計師--Java基礎--集合

------- android培訓、java培訓、期待與您交流! ---------- 第一部分:集合框架概述 集合的由來:物件用於封裝特有資料,物件多了需要儲存;如果物件的個數不確定,就使用集合容器進行儲存。 Java中有兩種儲存物件:陣列和集合。 它們的區別在於: