Java面試總結(二)


前幾天去了幾家公司面試,果然,基本全部倒在二面上,無語啊。。。不過幸好,到最后拿到了環球易購的offer,打算就這么好好呆着了,學習學習,努力努力,下面講講這幾天的面試吧。
  先是恆大,一個組長面試,答的很一般吧,有些問題是確實不知道題意,如何設計一個多線程,用來表示一個紅綠燈和車流的關系;還有人走迷宮的時候,如何用一個設計模式表示人的多樣性和路的多樣性;還有就是如何大批量向數據庫插入數據,這個之前沒關注過,沒答出來,有點遺憾。還有就是薪資問題,來之前我以為恆大,這么牛逼的公司,要不要提高一下薪資要求,不過為了穩妥還是繼續9-10k,面試官說剛畢業的,這邊只能給到8k左右啊,,,,就這樣,掛了。
  達飛金控一面問的問題真的太基礎,基礎到有點嚇人,差不多也是那種set、list、map區別,抽象和接口什么的,答得一般吧。由於面試官在開會,開到了12點多,然后繼續面試,同時還有另一個面試的在等,二面也聊得還算是蠻順暢,問了如果不小心發送了兩個重復的請求,由於不同機房,數據同步需要時間,那么如何解決這個請求;還有就是在一段文字中找出出現次數最多的字謎,總體上來的還算是一般偏上吧,答得也七七八八,然后就1點了,還有另外一個人在等面試,最后說等消息,到現在也沒消息,又掛了。。。。蛇口那邊的環境確實不錯,面完下樓,好多外國人。還有就是達飛准備招人做風控、電商方面的業務,有需要的可以投一下。
  聯想的有點,,,對着一張紙的題直接說出答案,這個面試官說答的還不錯,然后是手寫sql和上機筆試,sql沒寫對(考察分頁,group by,having),其實不難的,只是平時不注意,上機的題也沒全做出來(考察Java日期類的使用,有點古老),不過還好有個自己的網站二面還是過了,三面,額,可能做得東西跟自己想的不一樣,當我說我想做分布式、高並發、高可用的東西之后,然后還問了部門manager並發量有多大,他說主要是給內部使用的,所以並發量不打,然后說等消息吧,就這么掛了,據說聯想2020年在后海會落成一棟樓,感覺屌屌的,可惜了。。。。
永遠掛在二面的我啊
  深圳想去的公司並且招人的,基本投完了,然后這么多都是倒在了二面,有點不甘心吧。在boss上偶然看到環球易購在招人,而且一直是自己夢寐以求的電商行業,就在boss上找環球易購的那些技術負責人,一個一個問,還好有位大佬理我,雖然不合適,但幫忙推到了另一個組,然后等HR電話,一直沒答來,所以只能一直貫徹自己的方針:成功的三要素是,一堅持,二不要臉,三堅持不要臉,一直請問那位技術大佬,雖然特別不好意思。我們經常說,千里馬常有而伯樂不常有,那么一只不要臉的普通馬就只能自己爭取了23333。
  周一去了環球易購,面試官挺直接的,感覺好像大概知道我實力如何什么的,直接問難度稍微大一點點的問題,有點慌,而且回答的也不是太好,雙親委派還記反了(尷尬),然后是部門經理,這個我回答的更慘,慘不忍睹,問了tomcat如何解析一個請求,意思是tomcat源碼看過沒,,,,真的超級慌,當初看了一會源碼就沒堅持下去直接放棄了。不過還好能HR面了(終於有家公司是HR面了),中間件畢竟是我特別想整的東西。周三接到了offer,開心的一晚睡不着(加上沒工作作息時間混亂),導致今天體檢血壓一直高,,,,現在真是超級累。
  這年頭找工作真的很累,最好不要像我一樣裸辭,找不到工作心里真的很不舒服的,特別容易心態爆炸,有時候覺得自己表現的還不錯,但就是沒過,很離譜的那種,畢竟面試,運氣緣分什么的占比更重。我是因為在上家公司加班太嚴重,而且任務太忙,根本沒時間面試和學習所以裸辭的。
  下面是自己印象深刻的題吧,有面試的可以參考參考,答案不一定准確,因為我自己也是半斤八兩,也歡迎大家幫忙提醒一下。

1.MQ事務,如果消費者消費了,如何回滾

  分布式事務,是我計划下下一階段要看的東西(下一個是分布式鎖),沒想到這么快就被問到了,最初看的不過也就CAP、BASE、2PC、3PC這些,MQ事務真的很少接觸。即使沒學過,那就按自己的理解來吧。假設有三個事務:A、B、C。
(1)如果三個事務之前不需要彼此的依賴,可以執行完A的時候向消息隊列發送一個prepareA,同理,B、C也一樣,如果三個事務在本地都執行成功了,那么發送一次success,然后事務prepareA、prepareB、prepareC開始執行,如果有一個失敗,則直接回滾所有。
(2)如果事務B需要依賴A的結果、C需要依賴B的結果,那么A執行完后再執行B,B執行完再執行C,到最后,其中如果有一個失敗,則回滾重試。
  這一塊是真沒接觸過,即使百度了,感覺也有點抽象,還是先把ZooKeeper的分布式鎖看完再整分布式事務的東西吧。百度的時候看到了一個比較類似的想法,說的比我好,可以看看。

參考:
分布式事務之最終一致的Mq實現
聊聊分布式事務,再說說解決方案

2.主線程如何捕獲子線程的異常

  這道題不是很理解他的意思,try catch不就行了?他說不是這個意思,我說用線程池的話可以用callable異步返回異常結果,他說這個不算吧,一臉懵逼的狀態,事后百度了下發現考點是UncaughtExceptionHandler。。。大概意思就是把線程交給線程組,然后再線程組里重寫異常捕獲方法,即可在主線程捕獲子線程的異常了,例子如下:

public class ThreadExcep extends ThreadGroup {
    private ThreadExcep() {
        super("線程組的名字");
    }
    public void uncaughtException(Thread thread, Throwable exception) {
        System.out.println(thread.getId());
        exception.printStackTrace();//example,   print   stack   trace
    }
    public static void main(String[] args) {
        ThreadExcep excep = new ThreadExcep();
        Thread thread = new Thread(excep, () -> {
            throw new NullPointerException("空指針異常");
        });
        thread.start();
    }
}

結果如下:

11
java.lang.NullPointerException: 空指針一場
	at com.study.exception.ThreadExcep.lambda$main$0(ThreadExcep.java:26)
	at java.lang.Thread.run(Thread.java:748)

  而如果去掉exception.printStackTrace(),程序是不打印報錯信息的。原因可以總結如下:
(1)如果在主線程中創建一個子線程,默認情況下這兩個線程同屬於一個線程組,如果子線程發生異常,主線程可以直接使用try catch捕獲的到。
(2)同樣是在主線程中創建一個子線程,如果聲明了這個子線程是另一個線程組的,即調用了new Thread(ThreadGroup group, Runnable target),則主線程中是無法直接捕獲到子線程的發生的異常的,不過可以通過在聲明一個線程組重寫uncaughtException,然后把子線程放進去。
不管怎么說,在主線程中捕獲子線程的異常一般是不推薦的,線程設計的理念:“線程的問題應該線程自己本身來解決,而不要委托到外部。”
參考:
【Java 多線程】Java中主線程如何捕獲子線程拋出的異常

3.大批量插入數據庫如何優化

  大批量,之前都沒怎么注意過,這個問題確實不會,網上參考了下別人的,大體上是這個意思:合並數據+事務的方法在較小數據量時,性能提高是很明顯的,數據量較大時(1千萬以上),性能會急劇下降,這是由於此時數據量超過了innodb_buffer的容量,每次定位索引涉及較多的磁盤讀寫操作,性能下降較快。而使用合並數據+事務+有序數據的方式在數據量達到千萬級以上表現依舊是良好,在數據量較大時,有序數據索引定位較為方便,不需要頻繁對磁盤進行讀寫操作,所以可以維持較高的性能。

參考:
數據庫大批量SQL插入性能優化

4.Spring Bean的生命周期

  Spring的源碼確實要找個時間好好看看了,下面的是參考自《Spring實戰的》內容。

主要流程如下: (1).Spring對Bean進行實例化(相當於程序中的new Xx()) (2).Spring將值和Bean的引用注入進Bean對應的屬性中 (3).如果Bean實現了BeanNameAware接口,Spring將Bean的ID傳遞給setBeanName()方法(實現BeanNameAware清主要是為了通過Bean的引用來獲得Bean的ID,一般業務中是很少有用到Bean的ID的) (4).如果Bean實現了BeanFactoryAware接口,Spring將調用setBeanDactory(BeanFactory bf)方法並把BeanFactory容器實例作為參數傳入。(實現BeanFactoryAware 主要目的是為了獲取Spring容器,如Bean通過Spring容器發布事件等) (5).如果Bean實現了ApplicationContextAwaer接口,Spring容器將調用setApplicationContext(ApplicationContext ctx)方法,把y應用上下文作為參數傳入.(作用與BeanFactory類似都是為了獲取Spring容器,不同的是Spring容器在調用setApplicationContext方法時會把它自己作為setApplicationContext 的參數傳入,而Spring容器在調用setBeanDactory前需要程序員自己指定(注入)setBeanDactory里的參數BeanFactory ) (6).如果Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessBeforeInitialization(預初始化)方法(作用是在Bean實例創建成功后對進行增強處理,如對Bean進行修改,增加某個功能) (7).如果Bean實現了InitializingBean接口,Spring將調用它們的afterPropertiesSet方法,作用與在配置文件中對Bean使用init-method聲明初始化的作用一樣,都是在Bean的全部屬性設置成功后執行的初始化方法。 (8).如果Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessAfterInitialization(后初始化)方法(作用與6的一樣,只不過6是在Bean初始化前執行的,而這個是在Bean初始化后執行的,時機不同 ) (9).經過以上的工作后,Bean將一直駐留在應用上下文中給應用使用,直到應用上下文被銷毀 (10).如果Bean實現了DispostbleBean接口,Spring將調用它的destory方法,作用與在配置文件中對Bean使用destory-method屬性的作用一樣,都是在Bean實例銷毀前執行的方法。

參考:
1.《Spring實戰》
2.Spring中Bean的生命周期是怎樣的?

5.Tomcat是如何解析一個請求的

萬萬沒想到啊,自己曾經研究過一點點tomcat的源碼,現在卻忘光了,留張圖先吧,之后寫源碼分析的系列。

6.代理模式(Spring)

這題之后看Spring源碼的時候再總結了。

7.Java類里的靜態變量在JVM中哪個區

JDK8之前,靜態成員變量確實存放在方法區;但JDK8之后就取消了“永久代”,取而代之的是“元空間”,永久代中的數據也進行了遷移,靜態成員變量遷移到了堆中(方法區是JVM的規范,永久代是方法區的具體實現)。

8.ORM的好處,為什么使用ORM

驚不驚喜,意不意外,大部分人都在用ORM,但是卻很少關注為什么吧。Object-Relationl Mapping,它的作用是在關系型數據庫和對象之間作一個映射,這樣,我們在具體的操作數據庫的時候,就不需要再去和復雜的SQL語句打交道,只要像平時操作對象一樣操作它就可以了 。
優點
(1)方便的使用面向對象來進行額外的操作,語句清晰
(2)防注入
(3)方便動態構造語句,對於不同的表的相同操作采用多態實現更優雅
(4)一定程度方便重構數據層『比如改表名,字段名等』
缺點
(1)不太容易處理復雜查詢語句
(2)性能較直接用SQL差,畢竟有個轉化過程更。

總結

這些日子的面試過程,有基礎的,有廣度的,也暴露了自己很多很多缺點,2018還得繼續努力,最怕的是比你厲害的人還比你努力吧,不過怎么說,希望各位在求職穩住心態,猥瑣發育,前程似錦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM