Java程式設計師最全技術面試題:阿里11面試+百度+美團
網路程式設計
文末有答案解析以及阿里架構師精講視訊資料。
-
ISO模型與協議
-
http1.0:需要使用keep-alive引數來告知伺服器端要建立一個長連線
-
http1.1:預設長連線。支援只發送header資訊,可以用作許可權請求。支援Host域。
-
http2.0:多路複用的技術,做到同一個連線併發處理多個請求。HTTP2.0使用HPACK演算法對header的資料進行壓縮。支援HTTP2.0的web server請求資料的時候,伺服器會順便把一些客戶端需要的資源一起推送到客戶端,免得客戶端再次建立連線傳送請求到伺服器端獲取。這種方式非常合適載入靜態資源。
-
會話層:負責管理主機之間的會話程序,負責建立、管理、終止程序之間的會話。
-
傳輸層:將上層資料分段並提供端到端的、可靠的或不可靠的傳輸,還要處理端到端的差錯控制和流量控制問題。協議TCP、UDP、SPX
-
網路層:對子網間的資料包進行路由選擇。此外,網路層還可以實現擁塞控制、網際互連等功能。協議IP、IPX、RIP、OSPF
-
資料鏈路層:在不可靠的物理介質上提供可靠的傳輸。該層的作用包括:實體地址定址、資料的成幀、流量控制、資料的檢錯、重發等。協議SDLC、HDLC、PPP、STP、幀中繼
-
TCPIP模型與協議
-
應用層:單位是資料段,協議有FTP、TELNET、HTTP、SMTP、SNMP、TFTP、NTP、DNS
-
運輸層:單位是資料包,協議有TCP、UDP
-
網路層:單位是資料幀,協議有IP
-
網路介面層:單位是位元,ARP、RARP
-
三次握手與四次揮手
-
BIO NIO AIO
-
BIO:同步阻塞IO,每個請求都要一個執行緒來處理。
-
NIO:同步非阻塞IO,一個執行緒可以處理多個請求,適用於短連線、小資料。
-
AIO:非同步非阻塞IO,一個執行緒處理多個請求,使用回撥函式實現,適用於長連線、大資料。
-
DDOS攻擊原理與防禦方式
-
HTTP Get Flood:傳送大量會產生sql查詢的連線,使得資料庫負載很高。
-
CSRF跨站請求偽造原理攻擊者盜用了你的身份,以你的名義傳送惡意請求。
-
CSRF攻擊是源於WEB的隱式身份驗證機制!WEB的身份驗證機制雖然可以保證一個請求是來自於某個使用者的瀏覽器,但卻無法保證該請求是使用者批准傳送的!
-
防禦方式:1.驗證碼;2. 後臺生成token,讓前端請求攜帶。3.使用對稱加密,後端隨機給前端一個金鑰,前端進行加密,後端解密。
-
會話劫持通過暴力破解、 預測、竊取(通過XSS攻擊)等方式獲取到使用者session
-
XSS攻擊XSS攻擊是Web攻擊中最常見的攻擊方法之一,它是通過對網頁注入可執行程式碼且成功地被瀏覽器執行,達到攻擊的目的,形成了一次有效XSS攻擊,一旦攻擊成功,它可以獲取使用者的聯絡人列表,然後向聯絡人傳送虛假詐騙資訊,可以刪除使用者的日誌等等,有時候還和其他攻擊方式同時實施比如SQL注入攻擊伺服器和資料庫、Click劫持、相對連結劫持等實施釣魚,它帶來的危害是巨大的,是web安全的頭號大敵。
-
XSS反射型攻擊,惡意程式碼並沒有儲存在目標網站,通過引誘使用者點選一個連結到目標網站的惡意連結來實施攻擊的。
-
XSS儲存型攻擊,惡意程式碼被儲存到目標網站的伺服器中,這種攻擊具有較強的穩定性和永續性,比較常見場景是在部落格,論壇等社交網站上,但OA系統,和CRM系統上也能看到它身影,比如:某CRM系統的客戶投訴功能上存在XSS儲存型漏洞,黑客提交了惡意攻擊程式碼,當系統管理員檢視投訴資訊時惡意程式碼執行,竊取了客戶的資料,然而管理員毫不知情,這就是典型的XSS儲存型攻擊。
-
解決方法
-
在表單提交或者url引數傳遞前,對需要的引數進行過濾
-
過濾使用者輸入。檢查使用者輸入的內容中是否有非法內容。如<>(尖括號)、”(引號)、 ‘(單引號)、%(百分比符號)、;(分號)、()(括號)、&(& 符號)、+(加號)等
28.RPC與HTTP服務的區別
多執行緒
-
synchronized、CAS
-
Collections
-
支援高併發的資料結構,如ConcurrentHashMap
-
基於AQS實現的鎖、訊號量、計數器原理
-
Runnable與Callable的區別
-
執行緒池
-
作用
-
減少在建立和銷燬執行緒上所花的時間以及系統資源的開銷 。
-
當前任務與主執行緒隔離,能實現和主執行緒的非同步執行,特別是很多可以分開重複執行的任務。
8.阻塞佇列
9.threadlocal
Spring框架
-
IOC/DI
-
Core、Beans、Context、Expression Language
-
JDBC、ORM、OXM、JMS、Transaction
-
AOP
-
Web
-
Test
-
@Autowired原理
-
工廠模式
-
反射
-
自動配置@ConfigurationProperties(prefix = "hello"):讀取以hello為開頭的配置,屬性類使用
-
@Configuration:指名當前類為配置類
-
@EnableConfigurationProperties(Properties):指名配置屬性類
-
@ConditionalOnClass(Condition.class):條件類,只有Condition.class存在,當前配置類才生效
-
Spring Boot在spring.factories配置了很多全限定名的配置類。
Redis
核心原理
-
常用資料型別String:二進位制安全,可以存任何資料,比如序列化的圖片。最大長度位512M.
-
Hash:是KV對集合,本質是String型別的KV對映,適合儲存物件。
-
List:簡單字串連結串列,可以在left、right兩邊插入,本質是雙向連結串列。緩衝區也是用這個實現。
-
Set:String型別的無序集合,內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。
-
zset:有序集合,每個元素會關聯一個double型別的score,然後根據score進行排序。注意:元素不能重複,但是score是可以重複的。使用HashMap和跳躍表(SkipList)來保證資料的儲存和有序,HashMap裡放的是成員到score的對映,而跳躍表裡存放的是所有的成員,排序依據是HashMap裡存的score.
-
pub/sub:在Redis中,你可以設定對某一個key值進行訊息釋出及訊息訂閱,當一個key值上進行了訊息釋出後,所有訂閱它的客戶端都會收到相應的訊息。
持久化
-
RDB:一種是手動執行持久化命令來持久化快照;另一種是在配置檔案中配置策略,來自動持久化。持久化命令有save、bgsave兩種,bgsave會呼叫fork命令,產生子程序來進行持久化,而父程序繼續處理資料,但是持久化的快照是fork那一刻的快照,因此這種策略可能會丟失一部分資料。特點:每次都記錄所有資料,恢復快,子程序不影響父程序效能。
-
AOF:append only file,將每條操作命令都記錄到appendonly.aof檔案中,但是不會立馬寫入硬碟,我們可以配置always(每有一個命令,都同步)、everysec(每秒同步一次)、no(沒30秒同步一次)。往往everysec就夠了。aof資料損失要比RDB小。特點:有序記錄所有操作,資料丟失更少,會對操作做壓縮優化,bgrewriteaof也會fork子程序,不影響父程序效能
事務
-
Transactions:不是嚴格的ACID的事務,但是這個Transactions還是提供了基本的命令打包執行的功能(在伺服器不出問題的情況下,可以保證一連串的命令是順序在一起執行的,中間有會有其它客戶端命令插進來執行)。
-
Redis還提供了一個Watch功能,你可以對一個key進行Watch,然後再執行Transactions,在這過程中,如果這個Watched的值進行了修改,那麼這個Transactions會發現並拒絕執行。
KafKA
-
topic
-
broker
-
partition
-
consumer
-
producer
-
stream
-
儲存機制
-
網路模型
-
注意:partition之間是無序的
-
訊息佇列的生產者消費者中消費者沒有收到訊息怎麼辦,訊息有順序比如1.2.3但是收到的卻是1.3.2怎麼辦?訊息發過來的過程中損壞或者出錯怎麼辦
Spring security
-
攔截器棧
-
@PreAuthorize
-
@PostAuthorize
-
支援Expression Language
jvm原理
記憶體模型、垃圾收集器、CMS與G1是重點
垃圾收集演算法
-
標記-清除(CMS)容易產生碎片,當碎片太多會提前觸發Full GC
-
複製(年輕代基本用這個演算法)會浪費一半的可能感覺
-
標記-整理(serial Old、Parallel Old)
-
Serial:採用單執行緒stop-the-world的方式進行收集。當記憶體不足時,序列GC設定停頓標識,待所有執行緒都進入安全點(Safepoint)時,應用執行緒暫停,序列GC開始工作,採用單執行緒方式回收空間並整理記憶體。序列收集器特別適合堆記憶體不高、單核甚至雙核CPU的場合。
-
ParNew
-
Parallel Scavenge
CMS:
-
初始標記(stop of world)
-
並行標記、預清理
-
重新標記(stop of world)
-
並行清理
G1
將堆分成很多region,可以同時堆年輕代與老年代進行收集
-
初始標記(stop of world):初始標記(Initial Mark)負責標記所有能被直接可達的根物件(原生棧物件、全域性物件、JNI物件)
-
並行標記:
-
重新標記(stop of world):
-
清理(stop of world):
-
重置
gc觸發條件
-
從年輕代分割槽拷貝存活物件時,無法找到可用的空閒分割槽,會觸發Minor GC
-
從老年代分割槽轉移存活物件時,無法找到可用的空閒分割槽,會觸發Major GC
-
分配巨型物件時在老年代無法找到足夠的連續分割槽,會觸發Major GC
-
可達性分析:通過檢查一塊記憶體空間能否被root達到,來判斷是否對其進行回收。
jdk不同版本新增的部分特性
jvm調優
-
VisualVM:JDK自帶JVM視覺化工具,能過對記憶體、gc、cpu、thread、class、變數等等資訊進行視覺化。
設計模式
-
單例雙重檢查
-
觀察者模式
-
裝飾者模式:jdk中輸入輸出流用到了該模式
-
介面卡模式:jdk中Reader、writer用到了該模式
-
代理模式
-
靜態代理
-
JDK動態代理
-
Cglib到動態代理
-
生產者消費者模式
-
工廠模式
專案管理與運維工具
-
git+Jenkins
-
maven
-
K8Spod:Pod是所有業務型別的基礎,所有的容器均在Pod中執行,它是一個或多個容器的組合。每一個Pod都會被指派一個唯一的Ip地址,在Pod中的每一個容器共享網路名稱空間,包括Ip地址和網路埠。Pod能夠被指定共享儲存卷的集合,在Pod中所有的容器能夠訪問共享儲存卷,允許這些容器共享資料。
-
kubelet:kubelet負責管理pods和它們上面的容器,images映象、volumes、etc。
-
ingress,用於負載均衡
-
docker
-
docker與虛擬機器的區別
資料結構
-
平衡二叉樹AVL
-
高度log(n)
-
插入時間複雜度log(n)
-
紅黑樹
-
插入時間複雜度log(n)
-
查詢時間複雜度log(n)
-
在查詢是,紅黑樹雖然複雜度也是log(n),但是從效率上比要略低於AVL。但是其優勢在於插入元素的時候,不會像AVL那樣頻繁地旋轉。
-
B+Tree:只有葉子節點存值,非葉子節點只存key和child,因此同樣大小的物理頁上能存放更多的節點。每一層的節點數量越多,意味著層次越少,也就意味著IO次數越少,因此非常適合資料庫以及檔案系統。
-
大根堆:採用陣列儲存樹,是一個完全樹。先插入到陣列最後的位置上,然後採用上浮的思想,將該元素與比它小的父元素調換,直到parent>target,浮到root;然後將root與未排序的最後一個元素交換位置;重複以上步驟,直到所有元素都有序。插入如查詢的複雜度都是log(n)。
-
優先佇列PriorityQueue,Java中使用小根堆實現,非執行緒安全。
-
優先阻塞佇列PriorityBlockQueue,執行緒安全。
演算法
-
快排
-
時間複雜度O(nlog(n))
-
空間複雜度O(log(n))
-
堆排序
-
時間複雜度O(nlog(n))
-
空間複雜度O(1)
-
歸併排序
-
時間複雜度O(nlog(n))
-
空間複雜度O(n)
-
跳錶時間複雜度O(log(n))
-
空間複雜度O(2n)
-
高度O(log(n))
分散式
cap理論
-
可用性
-
一致性
-
分割槽容忍性:對網路斷開的容忍度,有點像魯棒性
-
拜占庭將軍問題
Raft 演算法
-
有leader、follower、candidate
同步流程
-
由客戶端提交資料到Leader節點。
-
由Leader節點把資料複製到叢集內所有的Follower節點。如果一次複製失敗,會不斷進行重試。
-
Follower節點們接收到複製的資料,會反饋給Leader節點。
-
如果Leader節點接收到超過半數的Follower反饋,表明複製成功。於是提交自己的資料,並通知客戶端資料提交成功。
-
由Leader節點通知叢集內所有的Follower節點提交資料,從而完成資料同步流程。
zookeeper
-
Zab(Zookeeper Atomic Broadcast)協議,有兩種模式:
-
它們分別是:恢復模式(選主)和廣播模式(同步)。
-
有兩種演算法:1. basic paxos;2. fast paxos(預設)
-
檔案系統:zookeeper的通知機制、分散式鎖、佇列管理、配置管理都是基於檔案系統的。
-
分散式鎖:有了zookeeper的一致性檔案系統,鎖的問題變得容易。鎖服務可以分為兩類,一個是保持獨佔,另一個是控制時序。
-
獨佔鎖:將zookeeper上的一個znode看作是一把鎖,通過createznode的方式來實現。所有客戶端都去建立 /distribute_lock 節點,最終成功建立的那個客戶端也即擁有了這把鎖。用完刪除掉自己建立的distribute_lock 節點就釋放出鎖。
-
控制時序鎖:/distribute_lock 已經預先存在,所有客戶端在它下面建立臨時順序編號目錄節點,和選master一樣,編號最小的獲得鎖,用完刪除。
-
佇列管理,分為同步佇列、非同步佇列
-
資料複製的好處
-
容錯:一個節點出錯,不致於讓整個系統停止工作,別的節點可以接管它的工作;
-
提高系統的擴充套件能力 :把負載分佈到多個節點上,或者增加節點來提高系統的負載能力;
-
提高效能:讓客戶端本地訪問就近的節點,提高使用者訪問速度。
5.一致性hash演算法原理
微服務
Spring cloud
-
閘道器:zuul
-
分散式版本化配置 config
-
服務註冊和發現:Eureka,配置時需要注意多久重新整理列表一次,多久監測心跳等。
-
service-to-service 呼叫
-
負載均衡:Ribbon;在生成RestTemplate的bean時,通過@LoadBalanced註解可以使得RestTemplate的呼叫
-
斷路器:Hystrix
-
監控:spring admin。在啟動類上加@EnableAdminServer註解。
其它
-
bitmap,大檔案交集
-
Elasticsearch索引原理
-
從記憶體到螢幕經歷了啥
-
高併發場景的限流,你怎麼來確定限流限多少,模擬場景和實際場景有區別怎麼解決,
百度面試
-
說一下redis與kafka,redis持久化策略
-
git中rebase與merge區別
-
docker底層原理,依賴作業系統的什麼
-
ls -l | grep xxx的執行過程,儘可能的細,是多程序還是單程序?
-
兩個有序陣列求中位數
-
演算法 3Sum、中序遍歷非遞迴實現、迴圈列印矩陣
-
final、finally、finanize
-
jvm記憶體模型
-
垃圾回收器
-
Spring特點介紹下
-
Synchronize與ReentrantLock的區別、使用場景
-
CAS使用場景
-
聊了下git+jekins+K8S+docker實現自動化部署
-
innodb原理,使用場景,與MYISAM在場景上的區別
-
weakReference、softReference等
-
Hbase的原理,LSM Tree
-
Linux中,哪種程序可以使用管道
美團
-
許可權模型
-
介紹下執行緒池,阻塞佇列的用法,無界佇列真的無界嗎?
-
說一下redis
-
kafka儲存模型與網路模型
-
zookeeper與redis實現分散式鎖
-
樂觀鎖與悲觀鎖
-
演算法:有n個人,給你ai與aj的身高關係,如ai比aj高,進行身高排序,如果條件不滿足,則輸出“不滿足”
-
Spring boot的特性
BAT面試常見答案解析
針對以上學習方向我們有自己的高清思維方向導圖以及阿里架構師講解的架構視訊分享(包括高可用,高併發,spring原始碼,mybatis原始碼,JVM,大資料,Netty等多個技術知識的架構視訊資料和各種電子書籍閱讀)視訊資料獲取方式加入Java進階之路即可獲取:878249276。
1.面向物件和麵向過程的區別
面向過程
優點:效能比面向物件高,因為類呼叫時需要例項化,開銷比較大,比較消耗資源;比如微控制器、嵌入式開發、Linux/Unix等一般採用面向過程開發,效能是最重要的因素。
缺點:沒有面向物件易維護、易複用、易擴充套件
面向物件
優點:易維護、易複用、易擴充套件,由於面向物件有封裝、繼承、多型性的特性,可以設計出低耦合的系統,使系統更加靈活、更加易於維護
缺點:效能比面向過程低
2.Java的四個基本特性(抽象、封裝、繼承,多型)
抽象:就是把現實生活中的某一類東西提取出來,用程式程式碼表示,我們通常叫做類或者介面。抽象包括兩個方面:一個是資料抽象,一個是過程抽象。資料抽象也就是物件的屬性。過程抽象是物件的行為特徵。
封裝:把客觀事物封裝成抽象的類,並且類可以把自己的資料和方法只讓可信的類或者物件操作,對不可信的進行封裝隱藏。封裝分為屬性的封裝和方法的封裝。
繼承:是對有著共同特性的多類事物,進行再抽象成一個類。這個類就是多類事物的父類。父類的意義在於抽取多類事物的共性。
多型:允許不同類的物件對同一訊息做出響應。方法的過載、類的覆蓋正體現了多型。
3.過載和重寫的區別
過載:發生在同一個類中,方法名必須相同,引數型別不同、個數不同、順序不同,方法返回值和訪問修飾符可以不同,發生在編譯時。
重寫:發生在父子類中,方法名、引數列表必須相同,返回值小於等於父類,丟擲的異常小於等於父類,訪問修飾符大於等於父類;如果父類方法訪問修飾符為private則子類中就不是重寫。
4.構造器Constructor是否可被override
構造器不能被重寫,不能用static修飾構造器,只能用public
private protected這三個許可權修飾符,且不能有返回語句。
5.訪問控制符public,protected,private,以及預設的區別
private只有在本類中才能訪問;
public在任何地方都能訪問;
protected在同包內的類及包外的子類能訪問;
預設不寫在同包內能訪問。
6是否可以繼承String類#
String類是final類故不可以繼承,一切由final修飾過的都不能繼承。
7.String和StringBuffer、StringBuilder的區別
可變性
String類中使用字元陣列儲存字串,private
final char value[],所以string物件是不可變的。StringBuilder與StringBuffer都繼承自AbstractStringBuilder類,在AbstractStringBuilder中也是使用字元陣列儲存字串,char[]
value,這兩種物件都是可變的。
執行緒安全性
String中的物件是不可變的,也就可以理解為常量,執行緒安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類,定義了一些字串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對方法加了同步鎖或者對呼叫的方法加了同步鎖,所以是執行緒安全的。StringBuilder並沒有對方法進行加同步鎖,所以是非執行緒安全的。
效能
每次對String 型別進行改變的時候,都會生成一個新的String 物件,然後將指標指向新的String 物件。StringBuffer每次都會對
StringBuffer 物件本身進行操作,而不是生成新的物件並改變物件引用。相同情況下使用
StirngBuilder 相比使用
StringBuffer 僅能獲得10%~15% 左右的效能提升,但卻要冒多執行緒不安全的風險。
8.hashCode和equals方法的關係
equals相等,hashcode必相等;hashcode相等,equals可能不相等。
9.抽象類和介面的區別
語法層次
抽象類和介面分別給出了不同的語法定義。
設計層次
抽象層次不同,抽象類是對類抽象,而介面是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類區域性(行為)進行抽象。抽象類是自底向上抽象而來的,介面是自頂向下設計出來的。
跨域不同
抽象類所體現的是一種繼承關係,要想使得繼承關係合理,父類和派生類之間必須存在"is-a"
關係,即父類和派生類在概念本質上應該是相同的。對於介面則不然,並不要求介面的實現者和介面定義在概念本質上是一致的,僅僅是實現了介面定義的契約而已,"like-a"的關係。
10.自動裝箱與拆箱
裝箱:將基本型別用它們對應的引用型別包裝起來;
拆箱:將包裝型別轉換為基本資料型別;
Java使用自動裝箱和拆箱機制,節省了常用數值的記憶體開銷和建立物件的開銷,提高了效率,由編譯器來完成,編譯器會在編譯期根據語法決定是否進行裝箱和拆箱動作。
下面是阿里架構師精講視訊資料分享(包括高可用,高併發,spring原始碼,mybatis原始碼,JVM,大資料,Netty等多個技術知識的架構視訊資料和各種電子書籍閱讀)加入Java進階之路即可領取:878249276。