掉進水裏你不會淹死,待在水裏你纔會淹死,只有不斷學習纔不會被前沿淘汰,如下面試題但願對大家有幫助!java
答:在程序設計中有面向過程和麪向對象,C語言是面向過程的,就是一步一步的很是清楚,比較直接高效,而java是面向對象的,更易於重複使用、擴展和維護。程序員
面向過程只會思考這個事情(問題)自己面試
面向對象要將一個事情解拆成一個一個的模塊sql
封裝、繼承、多態 數據庫
內部細節對外部調用透明,外部調用無需修改或者關心內部實現編程
好比:ORM框架 操做數據庫,咱們不須要關心連接是如何創建的、sql是如何執行的,只需要引入mybatis,調方法便可數組
繼承基類的方法,並作出本身的改變和擴展安全
將共性的方法或屬性寫在父類,而不須要本身再定義,只須要擴展本身的個性化 就有點像AOP面向切面編程同樣 在不改變源碼的基礎上添加一些新的功能, 繼承也是在繼承了父類的全部方法和屬性上 子類能夠優化父類的方法和擴展本身的方法數據結構
多態和繼承實際上是一脈相承的 多態有一個條件:要有繼承 要重寫父類的方法 父類引用指向子類對象 mybatis
多態的用法 : 父類類型 變量名 = new 子類對象; 變量名.方法名() ; 調用的方法是子類對象的方法 這就是多態 可是多態有一個弊端 沒法調用子類本身特有的功能 就是子類對象的方法必須是在父類中有
也就是重寫了父類的方法才能被調用 (方法重寫)
JAVA語言有一個很是牛B的特性 就是跨平臺 代碼一次編寫處處運行
跨平臺特性實現:使用JVM(虛擬機)實現 字節碼文件都會放到jvm裏面去運行 針對不一樣的平臺 會生成不一樣的代碼 java虛擬機幫咱們作到的
java虛擬機是JDK的一個組成部分
java虛擬機由那些部分組成:
1:類裝載子系統
2:運行時數據區(內存模型(重點)) 包含堆 棧(線程) 本地方法棧 方法區(元空間) 程序技術器
3:字節碼執行引xin
棧(線程): 官網叫(虛擬機棧) 而我本身想叫它線程棧,爲何呢?只要一個線程開始運行 java虛擬機就會給這個線程分配它一塊本身的專屬內存空間 這個內存空間就叫作線程棧 !爲何分配這個空間?由於在這個線程運行過程當中須要內存空間去存放一些變量 那麼就是放到這個線程棧的
棧幀內存空間:就是線程棧內部爲每一個方法分配的一個內存空間 這個內存空間用來存放這個方法內的局部變量 這就叫(棧幀)!
數據結構裏面有個叫棧的數據結構 有個很是重要的特性FILO 先進後出
線程棧內部放棧幀的數據結構就是FILO結構 先進後出
先調用的方法後結束 後調用的方法先結束 也就是先調用的方法後釋放內存資源 後調用的方法先釋放內存資源
將JAVA文件編譯後的class文件轉換爲方便閱讀的源碼:
棧幀內的操做數棧操做步驟:
當前在內存中執行的代碼行 字節代碼行號從0開始
用處: 多線程 當前線程正在運行時 一個比當前線程優先級高的線程開始執行了 那麼當前線程就會被掛起 後面開始執行的時候就經過這個程序計數器的行號開始執行
程序計數器的值由字節碼執行引擎來進行修改 由於字節碼執行引擎指向着Math.class和程序計數器 當Math.class每行代碼執行完畢時都會修改程序計數器的值
就是一個局部變量表 放當前局部的變量
放操做數的 +-*/操做運算的 臨時存放的一塊內容空間
源碼 牽扯到C語言和C++ 把一些符號引用轉換爲直接引用
符號引用:方法名稱 括號啊 在JVM裏面都有一個名稱 叫符號 當程序真正運行到一行代碼的時候 就將這些符號引用轉換爲直接引用
經過動態連接在方法區(元空間)找到那些要執行的代碼
就是compute方法執行完畢後知道返回到main主函數的第幾行代碼去繼續執行
對象是放在堆區域的
棧和堆的關係就是棧裏面的內存地址經過指針指向堆裏相對應的對象
方法區放:常量+靜態變量+類信息
不論是棧裏面的對象仍是方法區裏的靜態對象 都是經過內存地址指針指向堆裏對應的對象 堆裏就是存放對象的 不論是靜態仍是非靜態的 只要是對象都會存放在堆裏 讓其它地方經過內存地址指針到對應的對象
方法區類信息 字節碼的一些信息會加載到方法區內部
本地方法棧:本地方法分配內存空間 native (nei ti wu) 修飾的方法叫本地方法 本地方法:底層是C和C++實現的 這個本地方法確定有要運行的東西嘛 因此就須要分配一個內存空間
堆:由年輕代和老年代構成 老年代佔3分之2 年輕代佔3分之1
若是一個對象被minor gc(ma lr GC)幹了15次尚未被幹掉 那麼這個對象會被移到老年代
完整對象包含:對象頭、實例數據
調優工具 阿里開源工具: Arthas(啊 sr 死) JDK自帶的:Visual GC
JDK:java開發工具 提供給開發人員來使用的
JRE:java運行時環境 提供給運行java程序的用戶來使用的 誰須要運行java程序就須要安裝JRE
JVM:虛擬機 解析class文件 解析成機器碼(二進制)讓操做系統能夠執行
是class文件是能夠處處運行的 並非JVM能夠處處運行 JVM是將當前class文件解析成當前操做系統能識別的機器碼
在java中有兩塊很重要的內存 棧和堆 堆是存對象 棧是存值
String s = new String() String ss = new String() s=「123」 ss = 「123」
boolean b = s == s?true:false; b的值爲false 由於s和ss在堆裏開闢了不一樣的內存空間
boolean b = s.equals(ss) b的值爲true 由於equals重寫了方法 只是比較了兩個字符串的內容 沒有進行對象比較 只是比較了值 因此能夠理解equals就是比較的值
int a = 1 int b = 1
boolean b = a==b ?true:false; b的值爲true 由於a和b都是在棧中 而且值都是1 因此結果爲true
來一道題:
解析:
str1==str2 false 由於str1和str2 使用== 比較的是棧中的值 棧中str1 str2 都存放的是不一樣的內存地址 是存放在堆中的對象 因此它們的內存對象值不一樣 因此返回爲false
str2==str3 同理
str2==str3 true 由於str3 直接經過賦值運算符取得了str2在棧中的內存地址值 因此str3和str2的內存地址值是一摸同樣的 都指向的是堆裏的那個對象
str1.equals(str2) true equals 對比的是內容 內容都是Hello 確定都是true
本身的理解:final聲明的變量只是爲了局部生成的匿名類或者內部類調用時這個值是一致的 就是面向對象的思想
重載:發生在同一個類中,方法名必須相同,參數類型不一樣,個數不一樣、順序不一樣,方法返回值和訪問修飾符能夠不一樣,發生在編譯時。
重寫:發生在父子類中,方法名、參數列表必須相同,返回值範圍小於等於父類,拋出的異常範圍小於等於父類,訪問修飾符範圍大於等於父類;若是父類方法訪問修飾符爲private則子類就不能重寫該方法
抽象類只能繼承一個,接口能夠實現多個
抽象類能夠存在普通成員函數,而接口中只能存在public abstract方法 接口裏面只能是抽象的方法
抽象類中的成員變量能夠是各類類型的,而接口中的成員變量只能是public static final類型的
初級程序員答:
抽象類除了有抽象方法還有實現了的方法也就是普通成員函數 而接口不能夠 接口裏面的方法必須所有是抽象的
在咱們的抽象類中成員變量是能夠有多種類型的 而接口中的成員變量只能是public static final類型的 接口中的成員變量默認都是常量
抽象類是單繼承 而接口是能夠多實現的
接口的設計目的:它只對類可以提供那些方法 至於這個方法怎麼實現的 它無論
抽象類的設計目的:代碼服用 不一樣的類具備相同的行爲 有共性的東西 這個時候就能夠把這些共同的東西抽取出來寫入道抽象類中 能夠有抽象方法 也能夠有已經實現了的方法
抽象類包含並實現子類的通用特性
抽象類是對類本質的抽象 表達的是is a的關係 好比 BMW is a Car 若是用BMW繼承Car類 就表明BMW是Car
而接口是對行爲的抽象 表達的是like a的關係 是相似 不是直接就是 Bird like a Aircraft Aircraft 接口有一個飛的方法 Bird就能夠去實現Aircraft接口裏的飛的方法
可是Bird(小鳥)不是一個Aircraft(飛行器) 由於Aircraft(飛行器)接口裏面有飛的方法 因此Bird小鳥能夠去實現Aircraft接口飛的方法
使用場景:
當你關注一個事務的本質的時候,用抽象類
當你關注一個操做的時候,用接口
抽象類的功能要遠超過接口 抽象類能夠有實現的方法 也能夠有未實現的方法 可是定義抽象類的代價比較高 抽象類只能實現一個 接口會下降難度:接口能夠實現多個
List和Set:List是有序的 可重複的 可使用迭代器和下表讀取存入的值 set是無需的 不可重複的 只能使用迭代器讀取存入的值
hashcode和equals:
若是兩個對象相等,那麼hashcode必定也是相同的
兩個對象相等,對兩個對象分別調用equals方法都返回true
ArrayList是基於動態數組的 亮點在於擴容機制 老數組和新數組 當使用ArrayList開闢了一個能容納10個值的數組時想插入第11個值的話 那麼擴容機制就來了
擴容機制原理:就是新數組和老數組 開闢一個比老數組要長的新數組 將老數組的值CP到新數組中並將新插入的值插入到新數組中 這就是擴容機制也就是動態數組的機制
它更利於插入不利於查詢 可是 若是將ArrayList使用的恰當是能夠比LinkedList性能要好的 它能夠經過下標和迭代器訪問存入的值
LinkedList是基於鏈表的 它利於插入不利於查詢 只能使用迭代器訪問存入的值 不能經過下標 並且不推薦使用for循環來遍歷 由於LinkedList是基於鏈表的 若是使用for循環去訪問存入的值 那麼每讀取一個值都會從鏈表鏈一次 效率可想而知有多低
HashMap是線程不安全的 HashTable是線程安全的 由於HashTable爲裏面的每一個方法都添加了鎖 而HashMap沒有 它們兩的方法都差很少 可是HashTable效率低 HashMap效率高 能夠根據不一樣的業務來選擇使用
HashMap基於動態數組實現
HashTable基於鏈表實現
實現Runable 或者繼承Thread si wei dr Thread實現了Runable Thread和Runable的實質是繼承關係 ,沒有可比性,Thread是單繼承可是Runable是多實現
在文章的最後做者爲你們整理了不少資料!包括java核心知識點+全套架構師學習資料和視頻+一線大廠面試寶典+面試簡歷模板+阿里美團網易騰訊小米愛奇藝快手嗶哩嗶哩面試題+Spring源碼合集+Java架構實戰電子書等等!
所有免費分享給你們,有須要的朋友歡迎關注公衆號:前程有光,領取!