1. 程式人生 > >Java 程序員 面試前必備知識

Java 程序員 面試前必備知識

XML 短作業優先 sdl session 導致 模型 每次 請求 service

    • 前言
    • 正文
      • 自我介紹
      • 數據結構和算法
      • Java篇
      • Java EE知識點儲備
      • 計算機網絡
      • 操作系統
      • 數據庫相關
      • XML
      • 常識性知識
    • 總結

前言

準備了接近兩個月的面試筆試,現在終於是可以休息下了。真真是應了那句老話“臺上一分鐘, 臺下十年功。”。

人嘛,越努力,才會越幸運。機會總是留給有準備的人的。

下面分享一下我的Java實習生準備所看過的材料,(雖然至今還有些依然看不懂地方。) 希望對這方面的同學有點幫助。

正文

自我介紹

先針對自己的情況寫段自我介紹,真實一些就好了,這方面我倒是沒有什麽其他的建議。我就寫了我自己的真實的情況,比如喜歡寫博客,喜歡學習新技術,做過哪些小工具什麽的。

但是有一點,那就是別作假,否則的話很容易被發現的,而且後果一般會很嚴重。

數據結構和算法

這段時間自己也總結了關於數據結構和算法相關的一些例子。也看了幾本書,總的來說《劍指Offer》挺好,就我不多的面試經驗來看,大部分面試官都是面試的上面的題,所以有時間的同學可以好好參考參考。

原書是使用C++實現的,我又用Python實現了其中大部分的內容,有興趣的話可以參考我的GitHub: https://github.com/guoruibiao/sword-to-offer

由於本人經驗,技術能力有限,有不恰當,不正確的地方還望批評指正。覺得還可以的也可以給我點個star,(^__^) 嘻嘻……

阿裏的那個《技術之瞳》我也看了,裏面內容比較多,但是也比較亂。知識面很廣,但是我感覺深度上還是不太夠。不是很適合我。

其他的類似於Java面試寶典啊這些的,復習的時候認真看一遍,就可以扔一邊了。但是前提是認真看了,因為基礎沒打牢的話,更別提生層建築了。於乎微處見真章。

Java篇

  • Java 虛擬機,這個專欄強烈推薦,講的真的是太好了。

  • 深入Java語言,看這個就夠了

  • 經典面試100題

  • Java面試題匯總

  • Java 面試須知

  • Java面試集錦1

  • Java面試集錦2

  • Java泛型深入理解

  • ThreadLocal底層原理淺析

  • concurrencyHashMap 底層原理,好在哪?
    分段鎖原理,對有競爭的區塊實現同步,區塊內維護hashEntry

  • final and finally


  • 集合詳解

    • 集合類的線程安全總結:
      • 安全的: Vector, Hashtable, concurrentHashMap…
      • 不安全的:HashMap, ArrayList, TreeMap, linkedList,HashSet(底層基於HashMap實現)
    • 容量相關:
      • Vector默認初始容量為10, 自增長量為0。翻倍增長拓展機制。
      • ArrayList:默認為10,最大上限為Integer。MAX_SIZE-8;拓展機制:newCapacity = oldCapacity + (oldCapacity >> 1);
      • Hashtable:默認大小為11, 裝載因子為0.75
      • HashMap: 默認16,裝載因子0.75, 最大上限1<<30

  • Comparator和Comparable的區別
一個類實現了Camparable接口則表明這個類的對象之間是可以相互比較的,這個類對象組成的集合就可以直接使用sort方法排序。 
        Comparator可以看成一種算法的實現,將算法和數據分離,Comparator也可以在下面兩種環境下使用: 
        Comparable 接口以提供自然排序順序。

        對於那些沒有自然順序的類、或者當您想要一個不同於自然順序的順序時,您可以實現 
        Comparator 接口來定義您自己的排序函數。可以將Comparator傳遞給Collections.sort或Arrays.sort。

        Comparator接口 
        當一個類並未實現Comparable,或者不喜歡缺省的Comaparable行為。可以實現Comparator接口
        直接實現Comparator的compare接口完成自定義比較類。
        例:Arrays.sort(results, new Comparator<RepDataQueryResultVO/>() 數組排序 RepDataQueryExecutor
        例:Collections.sort(lst,new Comparator<TaskPrintSchemeVO/>()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

  • Maven, Ant, Grandle之間的區別和聯系

  • Java NIO 相關:

    • Java NIO 詳解
    • select, poll, epoll之間聯系和區別

    • Java NIO BIO AIO相關


  • Java 的instanceof關鍵字底層實現:

    維護了主要超類型(繼承深度)小於7的主數組, 和次要超類型(判斷的時候需要super鏈遍歷查找);在字節碼使用特殊指令對常量池中的相關符號引用進行判斷,來決定true和false。


  • Java內存模型

    • 年輕代,: 伊甸區,兩個存活區(總有一個為空,輪詢轉移)。 (逐級晉升機制)

    • 年老代: 在年輕代中經歷了N次垃圾回收後依然存活的生命期較長的對象。

    • 永久代: 存放靜態文件,如Java類,方法等。持久代對垃圾回收沒有顯著影響。

  • GC 觸發機制:

    • 新生代GC: 在新對象生成且在伊甸區申請空間失敗的時候會觸發一次對伊甸區的GC,把
      存活的對象放置到存活區。通常來說伊甸區的GC會比較頻繁。

    • Full GC: 對整個堆進行整理,速度慢,次數少。觸發的時機: 年輕代被寫滿, 持久代被寫滿,系統GC被調用。


  • GC 回收標準:

    • 引用計數算法: 可能導致循環引用導致GC效果不好,代替方式有引用標記清理方式

    • 根搜索算法: 那些對象可以作為GC Root? 答案是虛擬機棧中引用的對象,方法區中的類靜態屬性引用的對象
      方法區中的常量引用的對象, 本地方法棧中JNI的引用對象

    • 引用狀態:強(被引用著)軟(還有些有那個但不是必須, 二次回收)弱(非必須對象,下次就回收)虛(告知被引用的對象,要被回收啦,作用不大): 程度依次減小,

    • 方法區回收: JVM沒有強調方法區的回收,但是也是非常有用的,對於效率要求較高而言。對於廢棄常量比較好處理
      直接判斷有沒有相關的引用即可。對於無效類對象而言有下面幾種方式。該類的實例都被回收;該類的classLoader被回收;該類對應的字節碼對象Class沒有被任何地方引用,無法在任何地方通過反射來訪問該類的方法。


  • GC 算法:

    • 標記清除算法: 對要進行回收的對象進行標記,在下次GC的時候予以回收。但是碎片化嚴重,對下次的大對象的分配效率不高。

    • 復制算法: 為了解決效率問題而出現,將內存分為可用的兩塊,對於存活的對象

    • 進行復制轉移,碎片化現象減輕。但是代價高啊,可用的只有一半,對於新生代內存區采用比較頻繁,

    • 標記整理算法: 對於老年代對象存活率高,這樣復制算法不適用,而采用標記整理算法。將老年代中存活的對象移動到一側,對另外的區域進行GC。

      綜上所述,對不同的代區采用不同的GC算法,會使得GC的效率得到進一步的提升。


  • 垃圾收集器: 針對比較常用的HotSpot虛擬機而言,支持不同類型的垃圾收集器。
    • Serial收集器。新生代中采用單線程的復制算法的垃圾收集器。Client端默認
    • Parallel收集器。新生代中采用多線程的復制算法的垃圾收集器。Server端默認,高吞吐量。
    • Serial Old收集器,采用單線程的標記-整理算法的垃圾收集器,Client端使用。
    • Parallel Old收集器, 采用多線程的標記-整理算法的垃圾收集器,Server端使用。
    • CMS(Concurrent-Mark-Sweep),以一種獲取最短回收停頓為時間目標的老年代收集器,采用標記-清除算法。
    • G1(Garbage-First),對新生代和老年代不予區分,而是對內存堆空間劃分區塊,分配不同的優先級,使用更有效率的垃圾回收算法。

  • 鎖相關:
    • 樂觀鎖機制
    • CAS(Compare And Swap)方法
    • 悲觀鎖:
      Synchronized就是悲觀鎖的一種,也稱之為獨占鎖,加了synchronized關鍵字的
      代碼基本上就只能以單線程的形式去執行了,它會導致其他需要該資源的線程掛起,直到前面的線程執行完畢釋放所資源。而另外一種樂觀鎖是一種更高效的機制,它的原理就是每次不加鎖去執行某項操作,如果發生沖突則失敗並重試,直到成功為止,其實本 質上不算鎖,所以很多地方也稱之為自旋。

  • HashSet, TreeSet和 LinkedHashSet 之間的區別

  • ClassLoader相關:
    雙親委派模型,以及唯一性的好處。
    有哪些類加載器 (Bootstrap ClassLoader[C語言實現,很底層], Ext.., Application)

  • 一些原則:
    • 小黃鴨測試法
    • happen-before原則
    • fail-fast原則
    • fail-safe原則
    • 開閉原則

Java EE知識點儲備

  • Java EE 知識點儲備

  • Spring中的動態代理實現

  • Spring中 IOC的生命周期:
(<3/>init-method,<1/>intilizingbean接口方法<2/>afterPropertiesSet的先後順序)等。

//詳情參考
Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:  
        1. BeanNameAware‘s setBeanName  
        2. BeanClassLoaderAware‘s setBeanClassLoader  
        3. BeanFactoryAware‘s setBeanFactory  
        4. ResourceLoaderAware‘s setResourceLoader (only applicable when running in an application context)  
        5. ApplicationEventPublisherAware‘s setApplicationEventPublisher (only applicable when running in an application context)  
        6. MessageSourceAware‘s setMessageSource (only applicable when running in an application context)  
        7. ApplicationContextAware‘s setApplicationContext (only applicable when running in an application context)  
        8. ServletContextAware‘s setServletContext (only applicable when running in a web application context)  

        9. postProcessBeforeInitialization methods of BeanPostProcessors  
        10. InitializingBean‘s afterPropertiesSet  
        11. a custom init-method definition  
        12. postProcessAfterInitialization methods of BeanPostProcessors   

        On shutdown of a bean factory, the following lifecycle methods apply:  
        1. DisposableBean‘s destroy  
        2. a custom destroy-method definition  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

大致可以這麽來理解:

bean容器創建–通過反射實現bean開始實例化–通過註入信息設置屬性–可以被調用啦–容器被銷毀/bean中設置的destory-method方法被調用實現bean的銷毀。


  • Spring Servlet Struts處理請求的路徑

我自己的理解如下:

  • Strtus:
    首先是客戶端發起一個指向servlet容器的請求,被容器上一系列的過濾器獲得主要是ActionContextCleanUp
    然後被FilterDispatcher攔截到,經過查詢ActionMapper之後決定調用哪個action
    FilterDispatcher將請求轉發給ActionProxy,ActionMapper內部經過查詢ConfigurationManager找到要調用的Action類
    ActionProxy代理產生一個ActionInvocation實例,回調action的execute方法,通過返回的串調用相關的jsp頁面
    最後反向經過一系列的攔截器,釋放不需要的如ThreadLocal裏面的數據,對象信息。

  • SpringMVC:
    前端管家DispatcherServlet接收來自客戶端的請求,然後通過handlerMapping查找到相應的處理器。轉交給handler處理相應的業務邏輯。處理結束後返回一個ModelAndView,返回給客戶端以響應。

  • Servlet:
    web服務器接收到客戶端請求之後,將請求指向一個與url對應的servlet的class,如果已實例化則調用init,service,destory。如果未創建,則通過查詢ServletConfig獲取到相關的字節碼信息,進行實例化,接著進行上面的操作。


  • Hibernate一二級緩存,以及lazy-load
    • 一級緩存: Hibernate內置,默認,切不可卸載
    • 二級緩存你:指SessionFactory的外部緩存,可配置可更改,可卸載。常用插件
      • EhCache:可作為進程範圍的緩存,存放數據的物理介質可以是內存或硬盤,對Hibernate的查詢緩存提供了支持。
        memcache等。
    • 惰性加載: 通過延遲加載技術可以避免過多的,過早的加載表裏面的數據,從而降低系統的內存開銷。Hibernate中使用代理來實現這一個效果,要想使用在核心配置文件中對lazy-load屬性設值為true即可。

  • Spring AOP解決了什麽問題?怎麽實現的?aop與cglib,與asm的關系。

    • AOP實現了面向切面編程。連接點(可以被增強的方法),切入點(被增強的方法),增強(業務中增強的具體邏輯),切面(將增強應用到切入點的過程)

    • AOP中借助於動態代理或者cglib實現。動態代理需要接口,cglib是子類增強機制,不能增強final類。

    • ASM是一個字節碼操作框架,直接修改產生字節碼數據流,效率高,但是人工需要對字節碼非常的熟悉。

  • Spring中的事務傳播屬性:
    • REQUESTED: 默認,當前不存在則新增一個事務。
    • MANDATORY:沒有事務則失敗
    • NEVER: 有事務則失敗
    • NOT_SUPPORT: 以非事務的形式執行,如果當前存在事務,則掛起
    • SUPPORT: 支持當前事務,如果當前沒有事務,則以非事務形式執行
    • NESTED:支持當前事務,新增savepoint,與當前事務同步提交或者回滾,但是內部事務出現異常時,不會影響當前事務的回滾。簡單來說就是內層操作依賴於外層的事務。

  • Spring中的BeanFactory和FactoryBean的區別:
    • BeanFactory使得管理任何性質的類得以實現,ApplicationContext是BeanFactory的增強。
    • FactoryBean提供一個工廠方法,用來得到其他的bean實例。從FactoryBean上得到的bean與普通的bean的配置不同,因為不是由容器產生,所以不需要提供class屬性。如ProxyFactoryBean用於創建代理(根據advisor生成TargetBean的代理,得以實現增強行為)。

計算機網絡

  • TCP趣文:
    • tcp/ip之大明王朝郵差趣文

  • HTTP協議, http1.0和http2.0區別:

    • http2的二進制壓縮流,完全的多路傳輸。使用報頭壓縮降低了開銷;實現了推送,降低了客戶端多次請求。

    • 報文結構—請求部分:
      請求行:請求方法+空格+URL+空格+協議版本+回車+換行符
      請求頭: 什麽referer,userAgent啦等等
      空行: 回車符+換行符
      請求數據: 來自客戶端的請求的數據。

    • 報文結構—響應部分:
      狀態行:協議版本, 狀態碼啊啥的
      消息報頭:時間, content-type, content-length啥的
      響應正文: 正文數據流。

  • 推送模式:

    • 長連接: 減少了客戶端輪詢的計算,但是對於服務器而言有一定壓力,且服務對象會變少。
    • 輪詢: 可以很快的監聽到數據變化,但是計算代價較高。
    • websocket: 事件隊列模型,解決了上面的問題,服務器和客戶端都可作為主動方。

    但是總的來說有兩大方向: Pull 和 Push; Push對於客戶端而言流量消耗更少;Pull對服務器端而言壓力稍小。


  • WebService淺析:

    • soap:簡單對象訪問協議,基於xm,可以和諸多應用層協議一起工作,成本高,代價大。
    • rest:表屬性狀態轉移,是一個抽象的對於資源訪問的一套設計思路。安全性相比soap較低,但是更流行,成本低。
    • WSDL:web service description language.也就是哪個服務器以什麽方式提供什麽服務的意思,也即服務發現。工作流程:
      根據WSDL構造一條soap語句發給服務器,獲取返回的soap數據並解碼為WSDL,獲取相應服務。

    對二者的思考,就是現在的rest也只是soap模式在rest下的借屍還魂,並沒有徹底的改變,而rest缺少一套標準,實現的方式也比較亂,各大廠商也不一致。需要時間的沈澱。


  • Http常見響應碼及含義

操作系統

  • 分頁和分段:
    操作系統分頁是為了更好的提高利用率,一個系統頁面大小是一定的,不可改變。而分段則是用戶決定的,來方便用戶

  • 頁面置換算法: FIFO, LRU, LRU的二次標記法來給次機會。

    詳參: http://blog.csdn.net/houzuoxin/article/details/38957969


  • 進程調度算法: 短作業優先, 優先級策略, 輪詢, 分級別的整合法。

數據庫相關

  • Memcache和Redis:

    • IO模型:memcache是多線程非阻塞IO,分為主監聽和工作線程;redis則是單線程事件驅動,效率更高一點。
    • 內存分配: memcache是內存預分配,碎片少,但有空間浪費之嫌;
      redis是現場分配,碎片化現象存在,但是非臨時數據不會踢到磁盤,仍會留在內存,素以更適合存儲而不是cache.
    • 數據一致性: memcache采用cas命令可以保證數據一致性;redis使用原子操作保證事務正常運行。
    • 存儲方式: memcache使用key-value; redis除此之外還可以存儲list,map等數據結構。

    總結:
    redis的最佳使用方式時全部數據in-memory.
    redis更多場景是作為memcache的替代品來使用。
    當需要除了key-value之外的數據結構支持的時候,redis更適合。
    當存儲的數據不鞥唄剔除的時候,使用redis更合適。


  • 數據庫事務以及隔離級別:

    • 四大特性: ACID(原子性[要麽都成功,要麽全失敗], 一致性[事務從一個狀態變成另一個一致性的狀態], 隔離性[一個事務中的行為不會影響到另一個事務], 持久性[改變了數據就不能再撤銷了])。

    • 不考慮事務的時候有可能在讀取數據庫時發生如下問題:
      臟讀: 一個事務中讀取了另一個事務中未提交的數據。
      不可重復讀: 相同的sql語句,兩次讀取的結果不一致。
      幻讀: 一個事務讀取到了另一個事務提交後的結果,或者改變了本次事務的數據的結果。也稱為虛讀。

    • 隔離級別:

      • 未提交讀: 最低級別,任何情況都不能保證。
      • 提交讀: 可避免臟讀。
      • 重復讀: 可避免臟讀,不可重復讀(MySQL默認支持!)
      • 序列化: 最強設置。

    事務的隔離級別越高,執行的效率就會越低!在JDBC代碼中可以對connection對象設置相應的隔離級別。

事務及隔離級別 詳解1

事務及隔離級別 詳解2


  • 數據庫數據結構:

      1. mysql存儲引擎中索引的實現機制;使用B-Tree優勢在於出度大,磁盤預讀效果好,與之相比,二叉樹,紅黑樹則不好。理論上來講,出度越大,索引的效率越高。盡量采用自增字段作為索引,因為按頁存儲的時候不需要移動數據塊,而不重復的字段則類似於隨機方式,需要移動數據塊,效率會差點。這就是因為innodb的聚集特性(數據在磁盤上的存儲順序和索引順序一致)決定的。
    • 2.數據庫事務的幾種粒度;表鎖(不會產生死鎖,但是並發度低), 頁鎖(有可能產生死鎖,但是用的不多), 行鎖(並發度高,但是有可能產生死鎖)。

    • 3.行鎖,表鎖;樂觀鎖,悲觀鎖
      悲觀鎖:在讀取數據時鎖住那幾行,其他對這幾行的更新需要等到悲觀鎖結束時才能繼續
      樂觀鎖:讀取數據時不鎖,更新時檢查是否數據已經被更新過,如果是則取消當前更新
      一般在悲觀鎖的等待時間過長而不能接受時我們才會選擇樂觀鎖

  • Mysql是怎麽實現repeable read的,(next-key)?
    • 通過添加鎖機制來實現的,詳解

  • innode的鎖,死鎖和 索引相關的東西。
    • 隔離級別: 未提交讀,提交讀, 重復讀,序列化(一次只有一個人可以操作)
    • innodb默認采用行鎖,對數據采用repeatable read,也就是事務開始後讀取到的結果會一致,這和oracle的committed read(只能讀取提交的事務數據,有可能產生兩次結果不一致的問題)不同。
    • 行鎖並發度高,不易產生死鎖;表級鎖並發度低,不會產生死鎖。
    • 鎖本身又分為讀鎖和寫鎖; 按照共享與否大致分為共享鎖和排它鎖等四個。

  • mysql死鎖: 行級鎖並不是直接鎖行記錄,而是鎖索引(主鍵索引和非主鍵索引)。
    • 一條sql語句如操作了主鍵索引,則會鎖住此主鍵索引;操作了非主鍵索引,則先鎖住非主鍵索引,再鎖住主鍵索引。
    • 在update,delete操作時,mysql還會鎖住where下相鄰的記錄,實現next-key locking.
      可以很好的解決“幻讀”問題。

  • SQL 優化入門
    • 使用內部函數; 避免select*; 使用表的別名,提高效率和準確度; 用[not]exist 代替[not]in; 使用索引;
    • 分表,分庫,精簡表結構,字段結構;等等。
    • SQL 優化詳解

  • 數據庫索引
    • 索引詳解1
    • 索引詳解2

XML

DTD(Document Type Define,文檔定義類型), schema( XSD, XML Schema Document)之間的區別和聯系

  • DTD:采用非XML語法規範,拓展性差。命名沖突不易解決。
  • schema: 采用XML語法規範

常識性知識

  • Tomcat工作原理詳解

  • 秒懂開源協議

  • 查找Linux中占用磁盤最大的文件:

du path -type f -size +NumberG | sort -n -r | head -n 10

找出給定目錄下以G為單位的最大的10個文件,並排序輸出。


  • 海量數據查詢方案

  • 海量數據存儲設計方案

  • 秒殺系統設計

  • 一個大文件4G,裏面一行行的數字,這時內存只有256M,如果做排序?
    http://blog.csdn.net/ztkhhhhhd/article/details/53138631

  • 全局唯一ID問題:

    時間戳,加去中心化,加邏輯分片,機器號等


  • 什麽是布隆過濾器,其實現原理是? False positive指的是?
    • 布隆過濾器就是使用一個很大的數組,根據K個哈希函數得到K個位置,在數組中將這K個位置對應的值設置為1;
    • 查詢的時候,仍舊采用這K個哈希函數對查詢串進行哈希運算,判斷對應的K歌位置是否為1;有可能因為其他的串的
    • 插入導致這K個位置全部為1,導致誤判現象的產生,不過這種情況發生的可能性很小,畢竟要與K個哈希位置都一致。

  • RPC的負載均衡、服務發現怎麽做的
    • 單點LB: 容易出現單點失效問題,且需要配合DNS服務,性能開銷略大
    • LB集成到客戶端: 對於開發成本較大,平臺限制。但是對於服務發現和健康檢查而言,服務器端壓力減小。
    • LB作為主機單進程,相當於將LB進程和服務進程隔離開,一個主機掛了只影響單個主機服務,但是配置較為麻煩,環節多,出錯調試較為困難。

  • Linux使用及問題排查:

    • grep,awk,sed; 是否自己寫過shell腳本;
    • 常見的cpu load過高,us過高,一般是什麽問題。引申出是否用過top,jstat,jstack等。

      可以先ps -aux (或者top, htop)找到占比高的進程號,然後使用ps -Lp 122427 cu找到對應的java進程的每個線程的CPU使用率,追蹤線程內部運行的狀況。
      常見的內存問題一般有哪些。 引申出是否用過free,top, jmap等。

      詳解: http://blog.csdn.net/wisgood/article/details/25343845


總結

林林總總的一萬多字了,但是這還遠遠不能覆蓋全部。而且距離一個合格的Java程序員僅僅知道這些還遠遠不夠,我們能做的就是盡可能的讓自己接近那個標準吧。

上面這些鏈接也好,總結也好,大家還是需要有自己的理解。

“盡信書,則不如無書!”,其實也是這麽個道理,帶著思考來閱讀,效率,效果都可能會更好。

最後,希望大家都能找到自己心儀的offer。

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

Java 程序員 面試前必備知識