2小時30分鐘|阿里Java一面真題+詳解

2小時30分鐘|阿里Java一面真題+詳解

樓主7-18號投的內推,等了8天之後,昨天中午接到了杭州打來的電話,約了晚上8點視頻一面,然後發來了視頻地址和代碼測評的地址

面了兩個半小時,都趕上人家三面了

樓主雙非學校,本科軟件工程專業,面試官問了本科學的什麼課程,樓主說了說數據結構,計算機組成原理,計算機網絡,操作系統,數據庫概論還有軟件工程。

項目,面試官讓展示一下數據庫表之間的關係

PART/01

基本數據類型在內存中的分佈,每個類型是幾個字節,整形怎麼放浮點型怎麼放(考組成原理,IEEE754)

  • byte 1字節
  • short 2字節
  • int 4字節
  • long 8字節
  • char 2字節(C語言中是1字節)可以存儲一個漢字
  • float 4字節
  • double 8字節
  • boolean false/true(理論上佔用1bit,1/8字節,實際處理按1byte處理)

抽象類接口區別和相同點

PART/01

  • 接口和抽象類都不能實例化
  • 抽象類可以有構造方法,接口中不能有構造方法。
  • 抽象類中可以有普通成員變量,接口中沒有普通成員變量
  • 抽象類中可以包含非抽象的普通方法,接口中的可以有非抽象方法,比如deafult方法
  • 抽象類中的抽象方法的訪問類型可以是public,protected,但接口中的抽象方法只能是public類型的,並且默認即為public abstract類型。
  • 抽象類中可以包含靜態方法,接口中不能包含靜態方法
  • 抽象類和接口中都可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型可以任意,但接口中定義的變量只能是public static final類型,並且默認即為public static final類型。
  • 一個類可以實現多個接口,但只能繼承一個抽象類。

抽象類裡面的方法子類必須全部實現嗎,可不可以有不實現的方法,接口呢?

PART/01

  • 抽象類不一定,子類只會實現父類裡的抽象方法,抽象類裡可以有抽象方法也可以非抽象方法,子類不需要再去實現非抽象方法,如果子類一定要再次實現的話就叫做覆蓋了
  • 接口裡的方法必須全部實現,因為接口裡的方法都是抽象的,默認都是public abstract

抽象類的作用是什麼,什麼時候用到抽象類

PART/01

封裝(隱藏對象的屬性和實現細節,僅對外公開接口)

繼承 JAVA單繼承,接口多實現

多態:多態跟返回值沒關係,跟參數個數,參數類型,參數順序有關係(只跟方法簽名有關係)

進程線程的區別:進程是資源分配的基本單位,線程是處理器調度的基本單位

線程池(看這裡),線程池的四個構造函數,參數,線程池的好處,以及線程池的繼承體系

  • ThreadPoolExecutor繼承了AbstractExecutorService,
  • AbstractExecutorService是一個抽象類,它實現了ExecutorService接口。
  • ExecutorService又是繼承了Executor接口

參數

PART/01

  • corePoolSize, 核心池大小
  • maximumPoolSize, 線程池最大線程數
  • keepAliveTime, 表示線程沒有任務執行時最多保持多久時間會終止
  • TimeUnit 參數keepAliveTime的時間單位,有7種取值
  • BlockingQueue,一個用來存儲等待執行的任務的阻塞隊列,
  • ThreadFactory, 線程工廠,主要用來創建線程
  • RejectedExecutionHandler 表示當拒絕處理任務時的策略

多線程併發,線程不安全會導致什麼問題?怎麼解決併發的問題(鎖機制)

PART/01

  • Synchornized
  • Lock
  • ReentrantLock
  • volatile

HashMap的鏈表成環原因(看這裡)

Spring IOC(控制反轉,將對象交給容器管理)

AOP裡面的名稱(通知,連接點,切入點,代理,目標,織入)

bean 工廠中bean 的生命週期/9項

當您在bean 工廠容器中加載bean時,它經過各種步驟,從它的實例化直到它的銷燬。下圖顯示了bean 工廠容器中bean的生命週期。

2小時30分鐘|阿里Java一面真題+詳解

在bean工廠中bean的生命週期期間執行了以下步驟:

1.實例化: 此步驟中,bean 工廠容器從XML 配置文件中提供的bean 定義實例化bean.

2.填充屬性:在此步驟中,bean 工廠容器按照XML配置文件中所指定的通過DI填充所有bean 屬性。

3.設置bean 名稱: 在此步驟中,在創建bean 的bean工廠中設置bean 的名稱。這是通過將bean 的ID 傳遞給BeanNameAware 接口提供的setBeanName() 方法來完成的。

4.設置bean 工廠: 在此步驟中,為bean 提供對管理它的bean工廠的引用。這是使用BeanFactoryAware 接口的setBeanFactory() 方法來完成的。

5.預初始化: 在此步驟中,您執行在初始化bean 之前需要完成的任務。這是通過在bean類中實現BeanPostProcessor 接口並定義其postProcessBeforeInitialization 方法來完成的。

6.初始化bean: 在此步驟中,您執行某些類型的初始化任務,然後bean 才可供使用。這些任務包括打開文件、打開網絡或數據庫連接以及分配內存。這是通過在bean 類中實現InitiallzingBean接口並定義其afterPropertiesSet ()方法來完成的。

7.初始化後: 在此步驟中,您執行在初始化bean之後需要完成的任務。這是通過在bean 類中實現BeanPostProcessor 接口並定義其postProcessAfterInitialization() 方法來完成的。

8.bean 可供使用: 此時,bean 已準各就緒,可供應用程序使用,將留在bean工廠中,直到應用程序不再需要它。

9.銷燬bean: 在此步驟中,將銷燬bean。如果bean實現DisposableBean 接口,將調用destroy () 方法。然而,如果為bean聲明瞭自定義destroy方法,將調用該方法。

依賴注入的三種方式/設值注入/構造函數注入/接口注入外加集合注入可以注入哪些集合

集合注入可以注入哪些集合(List,Map,Set,面試官問還有沒有了,樓主就注入過這三個,實話實說,不知道還有沒有就不說)

什麼是循環依賴,Spring是怎樣解決循環依賴的(看這裡),為了避免循環依賴最好用什麼注入(接口注入)

構造函數注入能不能和設值注入一塊用?不能(看這裡,牛客原題),有優先級問題。

使用構造函數依賴注入時,Spring保證一個對象所有依賴的對象先實例化後,才實例化這個對象。使用set方法依賴注入時,Spring首先實例化對象,然後才實例化所有依賴的對象。

當設值注入與構造注入同時存在時,先執行設值注入?再執行構造注入:構造注入自動失效。。。。有爭議

事務屬性ACID(acid,酸)

事務具有ACID(四個單詞的首字母)屬性:

PART/01

1) 原子性(Atomicity):事務包含的操作應該作為一個單元執行,要麼都成功、要麼都失敗。

2) 一致性(Consistency):事務完成後,數據應該處於一致的狀態。例如,如果轉賬,則要麼兩個賬戶都更新,要麼,失敗的情況下,兩個賬戶都不更新。

3) 隔離性(Isolation):事務之間應該獨立,不相互影響,併發事務的操作應該隔離開,如如果一個事務在修改數據,一個在讀取相同的數據,則應該保證在修改前或修改後讀取數據,而不可以在修改過程中讀取。

4) 持久性(Durability):事務對數據的修改在系統中永久有效,會保持下去,如對餘額的修改會持久在數據庫中。

事務併發會導致的問題

PART/01

1) 髒讀:如一個事務A正在更新數據,另一個事務B嘗試讀取同一個數據,B在更新期間讀取了數據,但是事務A可能最後回滾了事務,導致事務B讀取的數據不準確,視為髒讀。

2) 更新丟失:兩個事務同時更新同一個數據,導致其中一個的更新丟失,如你修改賬戶,減少了100塊,另一個事務也修改你的賬戶,減少100塊,結果就是你最後發現賬戶少了200塊。

3) 不可重複讀:如一個事務在操作期間兩次讀取同一批數據,結果發現數據不一樣,說明另一個事務在此期間更新了數據,視為不可重複讀。

4) 幻象讀:如一個事務操作期間兩次讀取同一個表的數據,結果發現第二次讀取的數據多了幾條,說明在此期間有其他事務插入數據到該表,跟幻覺一樣,視為幻象讀。

什麼是幻讀(看上面)

事務的隔離級別

PART/01

1)未提交讀取:設置值為1,說明當一個事務修改數據的時候,另一個事務可以讀取數據,這樣會導致髒讀、更新丟失、不可重複讀和幻象讀等問題,所以是最不安全的級別,不太常用。

2)提交讀取:設置值為2:說明當一個事務修改數據的時候,另一個事務必須等待修改完成,才能讀取數據,這樣可以防止髒讀,但依然可能導致更新丟失、不可重複讀和幻象讀等問題。是比較常用的一種隔離級別。

3)重複讀:設置值為4:比提交讀取安全一些,因為限制一個事務修改數據時,另一個事務不能讀取該數據,同時,限制一個事務讀取數據時,其他事務不能修改該數據,從而防止髒讀、更新丟失和不可重複讀的問題,但依然可能出現幻象讀的問題。

4)序列化:設置值為8:,最安全的隔離級別,當一個事務在操作數據時,其他事務不能操作該數據,包括不能插入,從而預防各種併發問題。相當於一個事務用完該數據,另一個數據才能用。

2小時30分鐘|阿里Java一面真題+詳解

JVM的內存分佈以及每個裡面都有什麼

PART/01

程序計數器(指向下一條需要選取的字節碼指令),堆(成員變量,對象),方法區(常量),虛擬機棧(局部變量,方法),本地方法棧,問了每個都是存什麼東西

對象都在堆裡嗎?(不,由於TLAB和逃逸技術的發展,或者在jvm開啟在棧上分配時某些特殊的對象可以存放在棧上)

垃圾收集器都收集那些地方的東西(Eden區,survior區,老年代)

垃圾收集算法(四種,標記清除,標記整理,複製,分代收集)

怎樣判斷哪些是垃圾(可達性分析)

什麼對象可以作為根節點:

PART/01

虛擬機棧中引用的對象

方法區中靜態屬性引用的對象

方法區中常量引用的對象

本地方法棧中JNI引用的對象

異常try-catch-finally中,try和finally中都有return,怎麼返回

結論:

1、不管有木有出現異常,finally塊中代碼都會執行;

2、當try和catch中有return時,finally仍然會執行;

3、finally是在return後面的表達式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值保存起來,不管finally中的代碼怎麼樣,返回的值都不會改變,仍然是之前保存的值),所以函數返回值是在finally執行前確定的;

4、finally中最好不要包含return,否則程序會提前退出,返回值不是try或catch中保存的返回值。

舉例:

情況1:

try {

} catch () {

} finally {

} return;

顯然程序按順序執行。

情況2:

try {

return;

} catch () {

} finally {

} return;

程序執行try塊中return之前(包括return語句中的表達式運算)代碼;再執行finally塊,最後執行try中return;finally塊之後的語句return,因為程序在try中已經return所以不再執行。

情況3:

try {

} catch () {

return;

} finally {

} return;

程序先執行try,如果遇到異常執行catch塊,

有異常:則執行catch中return之前(包括return語句中的表達式運算)代碼,再執行finally語句中全部代碼,最後執行catch塊中return. finally之後的代碼不再執行。無異常:執行完try再finally再return.

情況4:

try {

return;

} catch () {

} finally {

return;

}

程序執行try塊中return之前(包括return語句中的表達式運算)代碼;再執行finally塊,因為finally塊中有return所以提前退出。

情況5:

try {

} catch () {

return;

} finally {

return;

}

程序執行catch塊中return之前(包括return語句中的表達式運算)代碼;再執行finally塊,因為finally塊中有return所以提前退出。

情況6:

try {

return;

} catch () {

return;

} finally {

return;

}

程序執行try塊中return之前(包括return語句中的表達式運算)代碼;有異常:執行catch塊中return之前(包括return語句中的表達式運算)代碼;則再執行finally塊,因為finally塊中有return所以提前退出。無異常:則再執行finally塊,因為finally塊中有return所以提前退出。

最終結論:

任何執行try 或者catch中的return語句之前,如果finally存在的話,都會先執行finally語句。如果finally中有return語句,那麼程序就return了,所以finally中的return是一定會被return的,編譯器把finally中的return實現為一個warning。

問了數據結構有哪些排序算法(說了冒泡,快排和選擇排序,平時用的比較多),沒讓寫

問了二叉樹,翻轉二叉樹(不會),給他講了AVL旋轉

代碼題:

PART/01

1.有N階臺階,我們可以用兩種爬發,一次一步或者兩步,只能進不能退,算算有多少種爬法。

考察點:

a.遞歸;

b.擴展問題:1. 如果每次可以選擇一次走一步到一次走M步,程序應該怎麼改?

2.如何提升遞歸速度?(設置緩存變量例如字典,將遞歸中計算過的值保存下來)

2、找零錢問題:假設只有 1 分、 2 分、五分、 1 角、二角、 五角、 1元的硬幣。在超市結賬時,

如果需要找零錢, 收銀員希望將最少的硬幣數找給顧客。那麼,給定需要找的零錢數目,

如何求得最少的硬幣數呢

public class Main { static int[] arr = {1, 2, 5, 10, 20, 50, 100}; public int f(int N) { int m = N; int c = 0; int a = 0; int count = 0; for (int i = arr.length - 1; i >= 0; i--) {

a = m / arr[i]; c = m % (arr[i]); m = c; count = count + a; } return count; } public static void main(String[] args) {

Main m = new Main(); System.out.println(m.f(188)); }

}

3、小明中午路過一家公共停車場,出於程序員的職業習慣,他很想知道這個停車場上午的最大化利用率有多少。

經與門衛大叔溝通,他獲得了該停車場上午車輛入場時間與出場時間的記錄表(數據格式參考樣例輸入),

你能通過拿到的數據寫一個函數快速的幫小明算出這家停車場,上午最多的時候同時停放了多少輛車嗎?

要求時間複雜度不高於:O(n)*lgN

注意事項:

a、為方便起見,簡化計算,駛入時間和開出時間以整點記錄,如9點,10點。

b、如停車記錄中入場時間晚於出場時間,該停車記錄視為無效,如7,3

c、假定如果有多輛車同時出入場,出場車輛優先。

樣例輸入:

8,9;4,6;3,7;6,8 (車輛以分號分隔,車輛入場和出場時間以逗號分隔)

樣例輸出:

2


分享到:


相關文章: