1. 程式人生 > >JAVA架構師面試題,如何成為架構師-待完善。。。

JAVA架構師面試題,如何成為架構師-待完善。。。

基礎題目

1.Java執行緒的狀態

1.1、Java中的執行緒的狀態分為6種
  • 初始(NEW):新建立了一個執行緒物件,但還沒有呼叫start()方法。
  • 執行(RUNNABLE):Java執行緒中將就緒(ready)和執行中(running)兩種狀態籠統的成為“執行”。
    執行緒物件建立後,其他執行緒(比如main執行緒)呼叫了該物件的start()方法。該狀態的執行緒位於可執行執行緒池中,等待被執行緒排程選中,獲取cpu 的使用權,此時處於就緒狀態(ready)。就緒狀態的執行緒在獲得cpu 時間片後變為執行中狀態(running)。
  • 阻塞(BLOCKED):表執行緒阻塞於鎖。
  • 等待(WAITING):進入該狀態的執行緒需要等待其他執行緒做出一些特定動作(通知或中斷)。
  • 超時等待(TIME_WAITING):該狀態不同於WAITING,它可以在指定的時間內自行返回。
  • 終止(TERMINATED):表示該執行緒已經執行完畢。
1.2.執行緒的狀態圖

這裡寫圖片描述

1.3、初始狀態

實現Runnable介面或繼承Thread可以得到一個執行緒類,new一個例項出來,執行緒就進入了初始狀態

1.4、就緒狀態
  • 就緒狀態只是說你資格執行,排程程式沒有挑選到你,你就永遠是就緒狀態。
  • 呼叫執行緒的start()方法,此執行緒進入就緒狀態。
  • 當前執行緒sleep()方法結束,其他執行緒join()結束,等待使用者輸入完畢,某個執行緒拿到
  • 物件鎖,這些執行緒也將進入就緒狀態。
  • 當前執行緒時間片用完了,呼叫當前執行緒的yield()方法,當前執行緒進入就緒狀態。
  • 鎖池裡的執行緒拿到物件鎖後,進入就緒狀態。
1.5、執行中狀態

執行緒排程程式從可執行池中選擇一個執行緒作為當前執行緒時執行緒所處的狀態。這也是執行緒進入執行狀態的唯一一種方式

1.6、阻塞狀態

阻塞狀態是執行緒阻塞在進入synchronized關鍵字修飾的方法或程式碼塊(獲取鎖)時的狀態

1.7、終止狀態

當執行緒的run()方法完成時,或者主執行緒的main()方法完成時,我們就認為它終止了。這個執行緒物件也許是活的,但是,它已經不是一個單獨執行的執行緒。執行緒一旦終止了,就不能復生。
在一個終止的執行緒上呼叫start()方法,會丟擲java.lang.IllegalThreadStateException異常。

1.8、等待佇列(本是Object裡的方法,但影響了執行緒)
  • 呼叫obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) 程式碼段內。
  • 與等待佇列相關的步驟和圖
    這裡寫圖片描述
    1.執行緒1獲取物件A的鎖,正在使用物件A。
    2.執行緒1呼叫物件A的wait()方法。
    3.執行緒1釋放物件A的鎖,並馬上進入等待佇列。
    4.鎖池裡面的物件爭搶物件A的鎖。
    5.執行緒5獲得物件A的鎖,進入synchronized塊,使用物件A。
    6.執行緒5呼叫物件A的notifyAll()方法,喚醒所有執行緒,所有執行緒進入同步佇列。若執行緒5呼叫物件A的notify()方法,則喚醒一個執行緒,不知道會喚醒誰,被喚醒的那個執行緒進入同步佇列。
    7.notifyAll()方法所在synchronized結束,執行緒5釋放物件A的鎖。
    8.同步佇列的執行緒爭搶物件鎖,但執行緒1什麼時候能搶到就不知道了。
1.9、同步佇列狀態
  • 當前執行緒想呼叫物件A的同步方法時,發現物件A的鎖被別的執行緒佔有,此時當前執行緒進入同步佇列。簡言之,同步佇列裡面放的都是想爭奪物件鎖的執行緒。
  • 當一個執行緒1被另外一個執行緒2喚醒時,1執行緒進入同步佇列,去爭奪物件鎖。
  • 同步佇列是在同步的環境下才有的概念,一個物件對應一個同步佇列。
1.10、幾個方法的比較
  • Thread.sleep(long
    millis),一定是當前執行緒呼叫此方法,當前執行緒進入TIME_WAITING狀態,但不釋放物件鎖,millis後執行緒自動甦醒進入就緒狀態。作用:給其它執行緒執行機會的最佳方式。
  • Thread.yield(),一定是當前執行緒呼叫此方法,當前執行緒放棄獲取的cpu時間片,由執行狀態變會就緒狀態,讓OS再次選擇執行緒。作用:讓相同優先順序的執行緒輪流執行,但並不保證一定會輪流執行。實際中無法保證yield()達到讓步目的,因為讓步的執行緒還有可能被執行緒排程程式再次選中。Thread.yield()不會導致阻塞。
  • t.join()/t.join(long
    millis),當前執行緒裡呼叫其它執行緒t的join方法,當前執行緒進入TIME_WAITING/TIME_WAITING狀態,當前執行緒不釋放已經持有的物件鎖。執行緒t執行完畢或者millis時間到,當前執行緒進入就緒狀態。
  • obj.wait(),當前執行緒呼叫物件的wait()方法,當前執行緒釋放物件鎖,進入等待佇列。依靠notify()/notifyAll()喚醒或者wait(long
    timeout)timeout時間到自動喚醒。
  • obj.notify()喚醒在此物件監視器上等待的單個執行緒,選擇是任意性的。notifyAll()喚醒在此物件監視器上等待的所有執行緒

參考: https://blog.csdn.net/pange1991/article/details/53860651/

2.程序和執行緒的區別,程序間如何通訊,執行緒間如何通訊

2.1、程序和執行緒的區別

程序:是併發執行的程式在執行過程中分配和管理資源的基本單位,是一個動態概念,競爭計算機系統資源的基本單位。

執行緒:是程序的一個執行單元,是程序內科排程實體。比程序更小的獨立執行的基本單位。執行緒也被稱為輕量級程序。

一個程式至少一個程序,一個程序至少一個執行緒。

2.2、為什麼會有執行緒?

  每個程序都有自己的地址空間,即程序空間,在網路或多使用者換機下,一個伺服器通常需要接收大量不確定數量使用者的併發請求,為每一個請求都建立一個程序顯然行不通(系統開銷大響應使用者請求效率低),因此作業系統中執行緒概念被引進。

執行緒的執行過程是線性的,儘管中間會發生中斷或者暫停,但是程序所擁有的資源只為改線狀執行過程服務,一旦發生執行緒切換,這些資源需要被保護起來。
程序分為單執行緒程序和多執行緒程序,單執行緒程序巨集觀來看也是線性執行過程,微觀上只有單一的執行過程。多執行緒程序巨集觀是線性的,微觀上多個執行操作。
執行緒的改變只代表CPU的執行過程的改變,而沒有發生程序所擁有的資源的變化。 

2.3、程序執行緒的區別:

地址空間:同一程序的執行緒共享本程序的地址空間,而程序之間則是獨立的地址空間。
資源擁有:同一程序內的執行緒共享本程序的資源如記憶體、I/O、cpu等,但是程序之間的資源是獨立的。
     一個程序崩潰後,在保護模式下不會對其他程序產生影響,但是一個執行緒崩潰整個程序都死掉。所以多程序要比多執行緒健壯。

     程序切換時,消耗的資源大,效率高。所以涉及到頻繁的切換時,使用執行緒要好於程序。同樣如果要求同時進行並且又要共享某些變數的併發操作,只能用執行緒不能用程序

執行過程:每個獨立的程序程有一個程式執行的入口、順序執行序列和程式入口。但是執行緒不能獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。
執行緒是處理器排程的基本單位,但是程序不是。
兩者均可併發執行。

2.4、優缺點:

  執行緒執行開銷小,但是不利於資源的管理和保護。執行緒適合在SMP機器(雙CPU系統)上執行。

  程序執行開銷大,但是能夠很好的進行資源管理和保護。程序可以跨機器前移。

2.5、何時使用多程序,何時使用多執行緒?

對資源的管理和保護要求高,不限制開銷和效率時,使用多程序。

要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多執行緒。

2.6、程序間如何通訊

https://blog.csdn.net/younkerjqb/article/details/53635773

2.7、執行緒間如何通訊

https://www.cnblogs.com/efforts-will-be-lucky/p/7199980.html

3.HashMap的資料結構是什麼?如何實現的。和HashTable,ConcurrentHashMap的區別

這裡寫圖片描述
http://www.cnblogs.com/skywang12345/p/3323085.html

4.Cookie和Session的區別

5.索引有什麼用?如何建索引?

6.ArrayList是如何實現的,ArrayList和LinkedList的區別?ArrayList如何實現擴容。

7.equals方法實現

8.面向物件

9.執行緒狀態,BLOCKED和WAITING有什麼區別

10.JVM如何載入位元組碼檔案

11.JVM GC,GC演算法。

12.什麼情況會出現Full GC,什麼情況會出現yong GC。

13.JVM記憶體模型

14.Java執行時資料區

15.事務的實現原理

2、技術深度

1.有沒有看過JDK原始碼,看過的類實現原理是什麼。

2.HTTP協議

3.TCP協議

4.一致性Hash演算法

5.JVM如何載入位元組碼檔案

6.類載入器如何解除安裝位元組碼

7.IO和NIO的區別,NIO優點

8.Java執行緒池的實現原理,keepAliveTime等引數的作用。

9.HTTP連線池實現原理

10.資料庫連線池實現原理

11.資料庫的實現原理

3、技術框架

1.看過哪些開源框架的原始碼

2.為什麼要用Redis,Redis有哪些優缺點?Redis如何實現擴容?

3.Netty是如何使用執行緒池的,為什麼這麼使用

4.為什麼要使用Spring,Spring的優缺點有哪些

5.Spring的IOC容器初始化流程

6.Spring的IOC容器實現原理,為什麼可以通過byName和ByType找到Bean

7.Spring AOP實現原理

8.訊息中介軟體是如何實現的,技術難點有哪些

4、系統架構

1.如何搭建一個高可用系統

2.哪些設計模式可以增加系統的可擴充套件性

3.介紹設計模式,如模板模式,命令模式,策略模式,介面卡模式、橋接模式、裝飾模式,觀察者模式,狀態模式,訪問者模式。

4.抽象能力,怎麼提高研發效率。

5.什麼是高內聚低耦合,請舉例子如何實現

6.什麼情況用介面,什麼情況用訊息

7.如果AB兩個系統互相依賴,如何解除依賴

8.如何寫一篇設計文件,目錄是什麼

9.什麼場景應該拆分系統,什麼場景應該合併系統

10.系統和模組的區別,分別在什麼場景下使用

5、分散式系統

1.分散式事務,兩階段提交。

2.如何實現分散式鎖

3.如何實現分散式Session

4.如何保證訊息的一致性

5.負載均衡

6.正向代理(客戶端代理)和反向代理(伺服器端代理)

7.CDN實現原理

8.怎麼提升系統的QPS和吞吐量

6、實戰能力

有沒有處理過線上問題?出現記憶體洩露,CPU利用率標高,應用無響應時如何處理的。
開發中有沒有遇到什麼技術問題?如何解決的
如果有幾十億的白名單,每天白天需要高併發查詢,晚上需要更新一次,如何設計這個功能。
新浪微博是如何實現把微博推給訂閱者
Google是如何在一秒內把搜尋結果返回給使用者的。
12306網站的訂票系統如何實現,如何保證不會票不被超賣。
如何實現一個秒殺系統,保證只有幾位使用者能買到某件商品。
軟能力

如何學習一項新技術,比如如何學習Java的,重點學習什麼
有關注哪些新的技術
工作任務非常多非常雜時如何處理
專案出現延遲如何處理
和同事的設計思路不一樣怎麼處理
如何保證開發質量
職業規劃是什麼?短期,長期目標是什麼
團隊的規劃是什麼
能介紹下從工作到現在自己的成長在那裡
JAVA架構師的水準:

既然java架構師,首先你要是一個高階java工程師,熟練使用各種框架,並知道它們實現的原理。jvm虛擬機器原理、調優,懂得jvm能讓你寫出效能更好的程式碼;池技術,什麼物件池,連線池,執行緒池…:;java反射技術,寫框架必備的技術,但是有嚴重的效能問題,替代方案java位元組碼技術;nio,沒什麼好說的,值得注意的是”直接記憶體”的特點,使用場景;java多執行緒同步非同步;java各種集合物件的實現原理,瞭解這些可以讓你在解決問題時選擇合適的資料結構,高效的解決問題,比如hashmap的實現原理,好多五年以上經驗的人都弄不清楚,還有為什擴容時有效能問題?不弄清楚這些原理,就寫不出高效的程式碼,還會認為自己做的很對;總之一句話越基礎的東西越重要,很多人認為自己會用它們寫程式碼了,其實僅僅是知道如何呼叫api而已,離會用還差的遠。

熟練使用各種資料結構和演算法,陣列、雜湊、連結串列、排序樹…,一句話要麼是時間換空間要麼是空間換時間,這裡展開可以說一大堆,需要有一定的應用經驗,用於解決各種效能或業務上的問題;有時間再補充。

熟練使用linux作業系統,必備,沒什麼好說的 。

熟悉tcp協議,建立連線三次握手和斷開連線四次握手的整個過程,不瞭解的話,無法對高併發網路應用做優化; 熟悉http協議,尤其是http頭,我發現好多工作五年以上的都弄不清session和cookie的生命週期以及它們之間的關聯。

系統叢集、負載均衡、反向代理、動靜分離,網站靜態化 。

分散式儲存系統nfs,fastdfs,tfs,Hadoop瞭解他們的優缺點,適用場景 。

分散式快取技術memcached,redis,提高系統性能必備,一句話,把硬碟上的內容放到記憶體裡來提速,順便提個演算法一致性hash 。

工具nginx必備技能超級好用,高效能,基本不會掛掉的伺服器,功能多多,解決各種問題。

資料庫的設計能力,mysql必備,最基礎的資料庫工具,免費好用,對它基本的引數優化,慢查詢日誌分析,主從複製的配置,至少要成為半個mysql dba。其他nosql資料庫如mongodb。

還有佇列中介軟體。如訊息推送,可以先把訊息寫入資料庫,推送放佇列伺服器上,由推送伺服器去佇列獲取處理,這樣就可以將訊息放資料庫和佇列裡後直接給使用者反饋,推送過程則由推送伺服器和佇列伺服器完成,好處非同步處理、緩解伺服器壓力,解藕系統。

以上純粹是常用的技術,還有很多自己慢慢去摸索吧;因為要知道的東西很多,所以要成為一名合格的架構師,必須要有強大的自學能力,沒有人會手把手的教給你所有的東西。

想成為架構師不是懂了一大堆技術就可以了,這些是解決問題的基礎、是工具,不懂這些怎麼去提解決方案呢?這是成為架構師的必要條件。

架構師還要針對業務特點、系統的效能要求提出能解決問題成本最低的設計方案才合格,人家一個幾百人使用者的系統,訪問量不大,資料量小,你給人家上叢集、上分散式儲存、上高階伺服器,為了架構而架構,這是最扯淡的,架構師的作用就是第一滿足業務需求,第二最低的硬體網路成本和技術維護成本。

架構師還要根據業務發展階段,提前預見發展到下一個階段系統架構的解決方案,並且設計當前架構時將架構的升級擴充套件考慮進去,做到易於升級;否則等系統瓶頸來了,出問題了再去出方案,或現有架構無法擴充套件直接扔掉重做,或擴充套件麻煩問題一大堆,這會對企業造成損失。

程式設計師應該需要都有自知之明,會就是會,不會就是不會,網際網路發展迅速的時代,只能跟上時代的進步,才不會被淘汰。