一些出的不錯的Java面試題(一)

前言

本文包含多家公司的面試題,問題的答案純屬我的意見,並不表明標準答案,若有錯誤歡迎在評論區指正面試

本文涉及的面試問題不包括算法問題求解(篇幅過小且內容侷限性太大)以及分佈式系統架構(過於理論和公式化,說白了你們問的都是老掉牙的問題,而架構的原理涉及的太深很差展開),只挑選了部分我我的以爲還有點意思或者有點深度的問題,若是有人感興趣的話我再接着寫幾篇算法

函數式編程有什麼特色?

  • 函數和變量的地位相同,能夠做爲參數和返回值
  • 支持閉包和高階函數,可讓對象像函數同樣操做
  • 支持惰性計算,能夠等到須要求值的時候再進行計算
  • 只使用表達式,不使用語句,全部的代碼都是單純的運算過程,全部的操做都是用於處理運算
  • 沒有反作用,全部的功能均返回一個新的值,不會改變外部變量的狀態和值

CgLib是如何提升調用代理方法的效率的?

採用了FastClass機制,具體內容以下:spring

  1. 爲全部的方法創建索引
  2. 調用前根據方法信息查找索引
  3. 調用時根據索引直接匹配相應的方法直接進行調用

講一個隨機選擇算法(從集合A中隨機選擇m個元素)

算法步驟:sql

  1. 取m個元素放在集合B中
  2. 對於第i個元素(i > m,i起始爲m+1),讓這一元素在m/i的機率下,等機率隨機替換B中的任一元素
  3. 重複上述操做,直到遍歷集合結束
  4. 返回B集合

證實:數據庫

  1. 遍歷到第m+1個元素時,該元素被保存在B中的機率爲m/(m+1),B中元素沒有被替換的機率爲1-(m/(m+1) * 1/m) = m/(m+1)
  2. 遍歷到第i個元素時,前i-1個元素被保存在B中的機率爲m/(i-1),第i個元素被保存在B中的機率爲m/i,前i-1個元素,每一個留在B中的機率爲m/i
  3. 當i等於n時,即遍歷到第n個元素時,前n-1個元素,每一個留在B中的機率爲m/n,第n個元素被替換到B中的機率也爲m/n,因此每一個元素被保存在B中的機率均爲m/n

說一下JMM

JMM,即Java Memory Model,即Java內存模型,定義了虛擬機在內存中的工做方式編程

JMM是隸屬於JVM的,從抽象角度看,JMM定義了線程主內存之間的抽象關係:後端

  • 線程的共享變量存儲在主內存
  • 每一個線程擁有本身的私有的本地內存,本地內存保存了共享變量的副本

本地內存是JMM的抽象概念,並非真實存在的,它覆蓋了緩存、寫緩衝區、寄存器瀏覽器

用最簡單的話來介紹一下各類範式

  • 1NF:每一列都是不可分割的數據項
  • 2NF:在1NF的基礎上,消除部分依賴
  • 3NF:在2NF的基礎上,消除非主屬性傳遞依賴
  • BCNF:在1NF的基礎上,保證任意依賴的決定因素必須包含
  • 4NF:在3NF的基礎上,消除多值依賴
  • 5NF:在4NF的基礎上,保證表不能再分解

廣義上的線程阻塞狀態能夠分爲三種,講一下是哪三種

無限期等待(Waiting):處於該狀態的線程不會被cpu分配時間片,須要等待其餘線程顯式喚醒spring-mvc

  • obj[1].wait()
  • thread.join()
  • LockSupport.park()

有限期等待(Timed Waiting):處於該狀態的線程也不會被其餘線程也不會被cpu分配時間片,可是除了被其餘線程顯式喚醒以外,在等待超時後能夠自行喚醒緩存

  • Thread.sleep(millis)
  • obj.wait(timeout)
  • thread.join(millis)
  • LockSupport.parkNanos(nanos)
  • LockSupport.parkUntil(deadline)

阻塞(Blocked):線程會等待獲取某一個鎖,在期間會被阻塞

  • 進入synchronized修飾的方法或代碼塊中,且線程沒有擁有對應的鎖

線程若是發生異常,其餘線程會怎麼辦?

當前線程方法的異常語句以後的代碼無效,不影響其餘線程的執行

park和wait方法有什麼區別?

  • wait方法經過對象的互斥鎖實現線程同步,park是經過一個二元信號量實現線程同步的
  • wait方法會讓線程放棄當前持有的鎖,park方法則不會
  • 在wait方法調用前notify是無效的,但能夠經過提早調用unpark方法,來讓接下來調用park方法的線程提早獲取許可

TCP和UDP的具體應用場景有哪些?

TCP:對通訊質量有要求

  • 瀏覽器協議:http
  • 文件傳輸協議:ftp
  • 郵件協議:smtp、pop
  • 遠程登錄標準協議:Telnet

UDP:對通訊速度有要求

  • 簡單文件傳輸協議:tftp
  • 域名系統:dns(也使用了tcp協議,若是發送的報文超過512個字節,會使用tcp發送)
  • 語音和視頻

Spring的單例模式是如何實現的?

是經過單例註冊表的方式實現的,在AbstractBeanFactory的父類DefaultSigletonBeanRegistry中,有一個ConcurrentHashMap類型的成員變量singletonObjects,保存了beanName => bean對象的映射關係

當須要建立單例對象時,會檢查這個對象(註冊表)是否已存在映射,若是已存在則直接從表中返回

新生代對象進入老年代有哪幾種狀況?

  • Eden區滿,進行Minor GC,若是存活的對象仍然沒法放到新生代,則提早轉移到老年代
  • 若是須要建立的對象太大,則直接將對象分配到老年代
  • 新生代中存活超過必定代數的對象(默認爲15代)
  • 若是某年齡的對象超過Survivor區的一半,則超過此年齡的對象提早轉移到老年代(動態年齡判斷)

MVVM和MVC有什麼區別?

MVVM是Model-View-ViewModel的縮寫,將MVC中View的狀態和行爲抽象化,同時將視圖UI業務邏輯分離開,實現了後端數據、模板頁面和控制器的分離

MVC中Controller的一部分職責被拆分出由ViewModel負責,實現了Model和View的自同步,下降了業務和頁面的耦合

TCP優化技術你知道的有哪些?

Nalge算法

目的是解決大量小數據傳輸致使效率降低的問題,實現原理是使鏈路上永遠只有一個小於MSS(最大報文段)的待肯定包,儘量發送大塊的數據

只有當如下狀況時才容許發送:

  • 包長度達到MSS(最大報文段長度)
  • 包含有FIN
  • 設置了TCP_NODELAY選項
  • 未設置了TCP_CORK選項時,但全部發送的小數據包(長度小於MSS)均被確認
  • 上述條件均未知足時,發生超時

雖然避免了網絡擁塞,可是網絡的整體利用率很低,也下降了實時性

Delay ACK(延時確認機制)

目的是減小網絡中傳輸大量的小報文數,實現原理是經過新數據來將ACK捎帶過去

具體實現以下:

  • 收到數據時,不立刻ACK,而是等待一段時間後再進行ACK
  • 若是連續收到兩個數據包,仍然須要立刻ACK

操做系統的內碎片和外碎片的概念講一下

  • 內碎片:已經被分配出去的內存空間大於請求所需的內存空間,致使進程擁有的地址空間中有一部分沒有使用到,最終白白浪費
  • 外碎片:尚未被分配出去,可是因爲過小沒法被申請的其餘進程使用,最終白白浪費

單例模式比起靜態方法有什麼優勢?

  • 單例類的方法支持覆寫
  • 單例類能夠被延遲實例化
  • 單例類能夠被用於多態,不須要關注全局的狀態

Mysql性能優化有哪些方案?

sql優化

  • 避免全表掃描:具體的操做太多了,不一一列舉了
  • 避免沒必要要的操做:略,理由同上

表結構優化

選擇合適的數據類型

系統性能優化

  • 增大innodb_buffer_pool_size的值,避免常常性從磁盤中讀取數據
  • 在數據庫啓動前,執行預熱腳本進行數據預熱,將磁盤上的數據緩存到內存中
  • 使用足夠大的innodb_log_file_size(寫入緩存),建議調整爲innodb_log_file_size的0.25倍
  • 增長max_connections,提升容許同時鏈接的用戶數
  • 增長key_buffer_size的值,提升用於索引塊的緩衝區大小
  • 增長thread_cache_size的值,提升可複用的線程數量

結構優化

  • 分庫:基於主從架構的讀寫分離
  • 分表:水平/垂直分表 其餘 啓用緩存

適配器模式有哪些應用場景?

抽象場景

  • 須要使用某個類,可是這個類的接口不符合系統須要
  • 須要將一些彼此沒有太大關聯的類聯繫起來,使其能夠一塊兒工做
  • 須要爲一些類提供一個統一的輸出接口

具體場景

  • spring-aop:將不一樣的通知類型適配到統一的適配器接口AdvisorAdapter中,能夠經過具體的適配器類來獲取對應通知的攔截器
  • spring-mvc:使用HandlerAdapter來適配具體的Controller,實現了DispatcherServletController之間的統一接口對接

跨表查詢有那些優化思路?

  • 能用join的不用where
  • on中的條件儘量多
  • 左鏈接保證右表字段索引,右鏈接保證左表字段索引,內鏈接保證任一表字段索引
  • group by的列來自join的第一個表
  • group by的列添加索引,避免產生臨時表(存疑)

你會怎麼實現微信裏「附近的人」算法

  1. 將地圖按照必定的經緯度距離切分紅方格,每一個方格又能夠進一步切分出更小的方格
  2. 爲每個格子使用gohash算法[2]進行編號,編號按照最左匹配,能夠表示不一樣精度範圍的方格
  3. 當打開「附近的人」功能時,系統根據設備的定位信息獲得用戶所在的方格編號
  4. 按照選定的精度範圍,匹配方格編號的前n位,而後從數據庫中搜索方格編號前n位與其一致的用戶
  5. 能夠經過按方格分庫分表加快查詢速度

  1. obj泛指普通的對象,下文的thread泛指任意線程對象 ↩︎

  2. 將經緯度按照二分區間的形式不斷細分,若是落在左半邊就標記爲0,不然標記爲1 ↩︎

相關文章
相關標籤/搜索