在3月1號投完簡歷,作好測評之後,我是一直等啊等,始終期待着一面的到來。html
好不容易在3月8號這天中午12點10左右接到了來自阿里的面試電話。面試
剛開始,我是一臉的懵逼啊,面試官問我:「你是否是面過了???」我是一臉黑臉問號.jpg。Excuse me?在我一番解釋後,終於進入了正題。算法
首先仍是自我介紹。而後下面是問題清單:spring
一、平時在項目中主要負責哪塊技術啊?(我回答數據庫方面的代碼)好,那麼請問,你所知道的數據庫方面所須要注意的地方有什麼?怎麼優化數據庫?數據庫
引伸出來之後,他又我問了我關於left join與right join的區別,(我回答了出來),而後,他又問我那inner join呢?(我當時是忘記了,一臉懵逼啊,絕望放棄回答)?用不少join好嗎,有什麼 缺點?(效率下降)編程
關於索引:後端
應該建索引的字段:
1.常常做爲查詢條件的字段
2.外鍵
3.常常須要排序的字段
4.分組排序的字段安全
應該少建或者不建索引的字段有:
1.表記錄太少
2.常常須要插入,刪除,修改的表,
3.表中數據重複且分佈平均的字段bash
二、HTTP的特色,TCP/UDP特色以及區別?服務器
1.支持客戶/服務器模式。
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
3.靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4.無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。
三、HashMap、HashTable、ConCurrentHasgMap的區別以及實現原理?
ConCurrentHasgMap調用get()方法的時候有鎖嗎?
對於put和remove操做,是使用鎖同步來進行的,不過是用的ReentrantLock而不是synchronized,性能上要更高一些。它們的實現前文都已經提到過,就沒什麼可分析的了。
咱們還須要知道一點,ConcurrentHashMap的迭代器不是Fast-Fail的方式,因此在迭代的過程當中別其餘線程添加/刪除了元素,不會拋出異常,也不能體現出元素的改動。但也沒有關係,由於每一個entry的成員除了value都是final修飾的,暴漏出去也不會對其餘元素形成影響。
友情連接:深刻理解HashMap(及hash函數的真正巧妙之處)
四、怎麼實現併發編程?請詳細描述?
鎖機制(Lock)、CAS無鎖算法、Synchronized區別
五、類加載機制(若是本身寫幾個Jar包,應該放哪裏?)
六、String、StringBuffer、StringBuilder的區別?
若是StringBuilder後增長一個字符串常量,而且這時候是多線程運行,那這時候StringBuilder是線程安全的嗎?
字符串常量就是不能改變該對象,然後者是但是改變的字符串對象,他不像String同樣,須要每次建立,後二者是在原有的字符串對象進行操做的。
七、JDK七、8的區別?
在JMM方面的區別:
永久代
在JDK8以前的HotSpot實現中,類的元數據如方法數據、方法信息(字節碼,棧和變量大小)、運行時常量池、已肯定的符號引用和虛方法表等被保存在永久代中,32位默認永久代的大小爲64M,64位默認爲85M,能夠經過參數-XX:MaxPermSize進行設置,一旦類的元數據超過了永久代大小,就會拋出OOM異常。
虛擬機團隊在JDK8的HotSpot中,把永久代從Java堆中移除了,並把類的元數據直接保存在本地內存區域(堆外內存),稱之爲元空間。
這樣作有什麼好處?
有經驗的同窗會發現,對永久代的調優過程很是困難,永久代的大小很難肯定,其中涉及到太多因素,如類的總數、常量池大小和方法數量等,並且永久代的數據可能會隨着每一次Full GC而發生移動。
而在JDK8中,類的元數據保存在本地內存中,元空間的最大可分配空間就是系統可用內存空間,能夠避免永久代的內存溢出問題,不過須要監控內存的消耗狀況,一旦發生內存泄漏,會佔用大量的本地內存。
ps:JDK7以前的HotSpot,字符串常量池的字符串被存儲在永久代中,所以可能致使一系列的性能問題和內存溢出錯誤。在JDK8中,字符串常量池中只保存字符串的引用。
八、JMM在初始化堆內存時,新生代與老年代的默認比例是多少?
永久代不屬於堆內存,堆內存只包含新生代和老年代。
默認的,新生代 ( Young ) 與老年代 ( Old ) 的比例的值爲 1:2 ( 該值能夠經過參數 –XX:NewRatio 來指定 ),即:新生代 ( Young ) = 1/3 的堆空間大小。
老年代 ( Old ) = 2/3 的堆空間大小。其中,新生代 ( Young ) 被細分爲 Eden 和 兩個 Survivor 區域,這兩個 Survivor 區域分別被命名爲 from 和 to,以示區分。
默認的,Edem : from : to = 8 : 1 : 1 ( 能夠經過參數 –XX:SurvivorRatio 來設定 ),即: Eden = 8/10 的新生代空間大小,from = to = 1/10 的新生代空間大小。
JVM 每次只會使用 Eden 和其中的一塊 Survivor 區域來爲對象服務,因此不管何時,老是有一塊 Survivor 區域是空閒着的。
所以,新生代實際可用的內存空間爲 9/10 ( 即90% )的新生代空間。
九、Spring中控制反轉定義?相比於建立對象的好處?AOP編程的優勢?
友情連接:三大框架的原理及優缺點
原來咱們的程序咱們控制的是具體的實現,寫程序直接寫實現,如今咱們控制的是它的接口它的抽象,原來咱們依賴的是它的實現,如今咱們依賴的是它的抽象。從具體的實現反轉到抽象的概念上,咱們針對的是接口編程。
1)下降組件之間的耦合度,實現軟件各層之間的解耦。
Controller——>Service——>DAO
2)可使用容器提供的衆多服務,如:事務管理服務、消息服務等等。當咱們使用容器管理事務時,開發人員就再也不須要手工控制事務.也不需處理複雜的事務傳播。
3)容器提供單例模式支持,開發人員再也不須要本身編寫實現代碼。
4)容器提供了AOP技術,利用它很容易實現如權限攔截、運行期監控等功能。
5)容器提供的衆多輔做類,使用這些類可以加快應用的開發,如: JdbcTemplate、 HibernateTemplate。
6)Spring對於主流的應用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,這樣更便於應用的開發。
7) 使用spring容器能夠提供的服務:事務管理服務,JMS服務,Spring Core核心服務,持久化服務等。
8)若是使用Spring, 咱們就再也不須要手工控制事務,例如在Hibernate中控制事務的語句 session.beginTransaction();session.getTransaction().commit();
9)使用Spring,再也不須要咱們處理複雜的事務傳播行爲。
十、SpringMVC中動態代理的實現機制,源碼?
友情連接:Spring AOP動態代理原理與實現方式 (轉)
友情連接:Java中動態代理實現機制
十一、讀過哪些源碼,請詳細描述一個你最熟悉的?(我回答ArrayList)
十二、JVM虛擬機?請詳細描述?
1三、Java GC回收機制?請詳細描述?
1四、問了兩道智力題!!!!!
(1)有8個產品,其中有一個次品(有可能偏重,有可能偏輕),那麼如何用天平秤三次找出那個次品?
(2)忘記了。。。。關於買賣問題
1五、看過GitHub上的開放源碼嗎(好比阿里,騰訊優秀團隊的)?
1六、使用過哪些代碼管理工具?(Git,Maven)熟練使用嗎?會不會使用GitHub上傳代碼?
1七、使用過哪些寫代碼的工具?(Myeclipse和IDE),列出你經常使用的快捷鍵?
1八、學習編程的方法、渠道?(看博客,網站)?上哪些網站?
1九、說說本身的優缺點?學習時間的分配?
20、漏了一個問題,怎麼實現讓兩個線程交替執行?(用代碼實現?)
通常來講線程鎖能夠用:Synchronized、Lock。
這個題目的難點不在於同步塊,而在於怎麼樣設計這個兩個線程的交替實現。因爲線程爭用cpu的隨機性,就須要A線,B線程執行,在B執行完一次進入等待以前喚醒A,如此往復,那麼這裏就要用上notify和wait了。
public class Thread1 {
public static void main(String args[]) {
final Bussiness business = new Bussiness();
Thread a=new Thread(new Runnable(){
@Override
public void run(){
business.SubThread();
}
});
Thread b=new Thread((new Runnable() {
@Override
public void run() {
business.MainThread();
}
}));
a.start();
b.start();
}
}
class Bussiness {
private static Object LOCK = new Object();
volatile boolean bShouldSub = true;//這裏至關於定義了控制該誰執行的一個信號燈
public void MainThread() {
for (int i = 0; i < 50; i++) {
synchronized (LOCK) {//notify和wait的對象必定要和synchronized的對象保持一致
for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + "+MainThread:i=" + i + ",j=" + j);
}
if (bShouldSub) {
bShouldSub = false;
LOCK.notify();
if(i<49){
try {
LOCK.wait();
}catch (InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
}
}
public void SubThread() {
for (int i = 0; i < 50; i++) {
synchronized (LOCK){
for (int j = 0; j < 5; j++) {
System.out.println(Thread.currentThread().getName() + "+SubThread:i=" + i + ",j=" + j);
}
if (!bShouldSub) {
bShouldSub = true;
LOCK.notify();
if(i<49){
try {
LOCK.wait();
} catch (InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
}
}
}複製代碼
各類容器的初始化長度是多少?
使用ArrayList初始化時注意事項?(自動擴充機制方面,原理實現)?
好了,一面到此結束,歷時一個半小時,淚崩,懵逼!(關鍵下午還有課!!!遲到了!!!)
總結一點,閱讀源碼很重要!(Spring+SpringMVC+Mybatis)
上面題目的部分答案,歡迎前往歷年阿里面試題彙總(2017年不斷更新中)、各大公司Java後端開發面試題總結查閱
更多內容,可關注個人我的公衆號