?歡迎訂閱《大廠面試突擊》專欄,面試10多家中大廠總結出的高頻面試知識,僅前50名免費?
早晨的陽光和傍晚的落日,是你努力奔跑的背景色
前言
哈嘍,大家好,我是一條,
(不好意思,讓大家久等了,本來定周日發的,但感覺有些地方說的不夠通俗易懂,又改了一版)
告訴大家一個訊息,我在7月份又離職了,離職后我開始瘋狂的面試,一共面了百度、位元組、滴滴、美團、陌陌、58同城、汽車之家、元氣森林、猿輔導,掌閱科技,美術寶、moka等10多家中大廠,最多的時候一天4面,

面完之后我發現大廠對于演算法的重視程度非常之高,演算法題沒做出來,基本就不會再往下問了,你“八股文”再溜也沒有展現的機會,
所以我開始刷leetcode,每天一道,放在了《leetcode》專欄里,趁著還沒有收費,大家可以抓緊訂閱一波,
但演算法非一日之功可成,我們的“八股文”也不能落下,
一條根據多家公司的面試檢驗,將高頻面試題分門別類的總結出來,包括java基礎篇、javaweb篇、集合篇、jvm篇、多執行緒篇、框架篇、設計模式篇、資料結構篇、網路篇、作業系統篇、mysql篇、redis篇、kafka篇、ES篇、dubbo篇,Spring cloud篇、企業專案篇,由淺入深,到時有可能還會增加,
所有文章都會放在《大廠面試突擊》專欄里,以后會收費,所以請大家現在抓緊訂閱,
今天是「Java基礎篇」,很多時候基礎都容易被忽略,但是大廠就愛考基礎,萬丈高樓平地起就是這個道理,跟著一條一塊學習吧!
目前一條已經入職新的公司,至于是哪家大家可以猜一下,留個懸念,
目前的作業氛圍和待遇都非常好,新團隊,不卷,有興趣小伙伴也可以私信我,還在招人中,
文章目錄
- 前言
- 題目合集
- JVM、JDK、JRE、JMM什么區別
- JVM
- JDK
- JRE
- JMM
- 位元組碼
- Java有幾種資料型別,占多少位元組?
- float f=3.4; 是否正確
- short s1 = 1; s1 = s1 + 1;有錯嗎?
- short s1 = 1; s1 += 1;有錯嗎
- char可以存盤漢字嗎?
- char和boolean的默認值是多少?
- 基本資料型別和參考資料型別有什么區別?
- ==和equals()有什么區別
- String、StringBuffer、StringBuilder什么區別?
- 位運算
- 運算子優先級
- 訪問修飾符
- 如何理解介面和抽象類?
- 如何理解static關鍵字
- 如何理解final關鍵字
- 重寫和多載
- 構造器是否可被重寫?
- 代碼塊的執行順序?
- 泛型
- 如何理解封裝,繼承,多型?
- 封裝
- 繼承
- 多型
- 如何理解Java反射?
- 反射的意義
- Java8有哪些新特性?
- Lambda運算式
- stream
- 最后
題目合集
相比于逐個知識點的去講解,一條更偏向于用面試題的方式呈現,原因如下:
- 節省時間,有很多朋友都是面試前臨時抱佛腳,從
helloworld開始講,根本來不及好嗎- 重點突出,有些東西面試官是不會問的,也沒法問,暫時就可以不看
- 轉換思維,最重要的一點,有很多時候這個東西你知道,但一問就不會,有沒有,有的評論區扣1
ok,我們看題
JVM、JDK、JRE、JMM什么區別
你要是沒聽過這幾個東西,別說你學過Java
JVM
java虛擬機,可以說是核心的核心,如果你簡歷上敢寫精通jvm,面試官一定把你問的懷疑人生,
其主要是用來執行java位元組碼(二進制的形式)的虛擬計算機,運行在作業系統之上的,與硬體沒有任何關系,我們說Java的跨平臺特性,就是靠它實作的,
關于jvm,有類加載機制,組成結構,垃圾回收,記憶體調優等問題可以問,
JDK
Java Development Kit,我們學java的第一天就要安裝的東西,其包含包括 Java 運行環境(Java Runtime Envirnment,簡稱 JRE),Java 工具(比如 javac、java、javap 等等),以及 Java 基礎類別庫(比如 rt.jar)
JRE
對,就是剛剛提到的jre,他包含運行JAVA程式所必須的環境的集合,包含JVM標準實作及Java核心類別庫,
JMM
Java記憶體模型,一個抽象的概念,主要在并發編程時用到,具有原子性,有序性,一致性,
位元組碼
我們寫好的java代碼需要編譯成位元組碼檔案才能被計算機執行,位元組碼的開頭是CAFFBABE,正好對應Java的圖示,
Java有幾種資料型別,占多少位元組?
出自美術寶、元氣森林
面試官一問這道題你是不是以為他在侮辱你,太簡單了好嗎
但是,千萬不要輕敵,簡單題,我們要回答的流暢,深刻
Java 語言提供了 8 種基本型別,大致分為 4 類(8位=1位元組)
- 整數型
byte- 1位元組short- 2位元組int- 4位元組long- 8位元組,賦值時一般在數字后加上l或L
- 浮點型
float- 4位元組,直接賦值時必須在數字后加上f或Fdouble- 8位元組,賦值時一般在數字后加d或D
- 字符型
char- 2位元組,存盤 Unicode 碼,用單引號賦值
- 布爾型
boolean- 1位元組,只有 true 和 false 兩個取值,一個位元組就夠了
挺簡單哈,回答的不錯,關于這道題,還能追問什么呢?
float f=3.4; 是否正確
不正確,3.4 是雙精度數,將雙精度型(double)賦值給浮點型(float)屬于下轉型(down-casting,也稱為窄化)會造成精度損失,因此需要強制型別轉換float f =(float)3.4; 或者寫成 float f =3.4F;,
short s1 = 1; s1 = s1 + 1;有錯嗎?
對于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 型別,因此 s1+1運算結果也是int型,需要強制轉換型別才能賦值給 short 型,
short s1 = 1; s1 += 1;有錯嗎
short s1 = 1; s1 += 1;可以正確編譯,因為 s1+= 1;相當于s1 = (short(s1 + 1);其中有隱含的強制型別轉換,
char可以存盤漢字嗎?
出自元氣森林
當然是可以的,char型別中存盤的是Unicode編碼,Unicode編碼中是存在中文的,所以char自然可以存盤漢字,但是!僅限于Unicode中存在的漢字,
一個漢字的占兩個位元組,一個Unicode也是占兩個位元組 ,char存盤漢字完全沒有問題,
char和boolean的默認值是多少?
char是'\u0000',可以理解成一個空格,
boolean默認是false,
你都答對了嗎?
基本資料型別和參考資料型別有什么區別?
簡單來說,所有的非基本資料型別都是參考資料型別,除了基本資料型別對應的參考型別外,類、 介面型別、 陣列型別、 列舉型別、 注解型別、 字串型都屬于參考型別,
主要有以下區別:
1、存盤位置
- 基本變數型別在方法中定義的非全域基本資料型別變數的具體內容是存盤在堆疊中的
- 參考資料型別變數其具體內容都是存放在堆中的,而堆疊中存放的是其具體內容所在記憶體的地址
2、傳遞方式
- 基本資料型別是按值傳遞
- 參考資料型別是按參考傳遞
看下面兩段代碼理解
//基本資料型別作為方法引數被呼叫
public class Main{
public static void main(String[] args){
int msg = 100;
System.out.println("呼叫方法前msg的值:\n"+ msg); //100
fun(msg);
System.out.println("呼叫方法后msg的值:\n"+ msg); //100
}
public static void fun(int temp){
temp = 0;
}
}
//參考資料型別作為方法引數被呼叫
class Book{
String name;
double price;
public Book(String name,double price){
this.name = name;
this.price = price;
}
public void getInfo(){
System.out.println("圖書名稱:"+ name + ",價格:" + price);
}
public void setPrice(double price){
this.price = price;
}
}
public class Main{
public static void main(String[] args){
Book book = new Book("一條IT",66.6);
book.getInfo(); //圖書名稱:一條IT,價格:66.6
fun(book);
book.getInfo(); //圖書名稱:一條IT,價格:99.9
}
public static void fun(Book temp){
temp.setPrice(99.9);
}
}
==和equals()有什么區別
出自moka
我們都知道==運算子用來兩個物件的地址是否相同,即是否是指相同一個物件,
equals()比較的兩個物件的值是否相同,不管是不是一個物件,
但其實object類下的equals()和==是一樣的,我們用的都是被重寫之后的,
String、StringBuffer、StringBuilder什么區別?
三者共同之處:
都是final類,不允許被繼承,所以string每次改變值都會新建一個物件,
StringBuffer是執行緒安全,可以不需要額外的同步用于多執行緒中;
StringBuilder是非同步,運行于多執行緒中就需要使用著單獨同步處理,但是速度就比StringBuffer快多了;
StringBuffer與StringBuilder兩者共同之處:可以通過append、indert進行字串的操作,
位運算
這塊可能不會直接問你,但做演算法題會有奇效,所以不能不會,
^(亦或運算) ,針對二進制,相同的為0,不同的為1&(與運算),針對二進制,只要有一個為0,就為0<<(向左位移),針對二進制,轉換成二進制后向左移動3位,后面用0補齊>>(向右位移), 針對二進制,轉換成二進制后向右移動3位>>>(無符號右移) 無符號右移,忽略符號位,空位都以0補齊,>>>與>>唯一的不同是它無論原來的最左邊是什么數,統統都用0填充,正數做>>>運算的時候和>>是一樣的,區別在于負數運算
運算子優先級
一般而言,單目運算子優先級較高,賦值運算子優先級較低,算術運算子優先級較高,關系和邏輯運算子優先級較低,多數運算子具有左結合性,單目運算子、三目運算子、賦值運算子具有右結合性,
其實java一共分為14個優先級,很不好記,也不實用,記住常用的,不確定就加括號,面試官要是追著你問這個,讓他“滾”,我說的,耶穌來了都不行,
| 優先級 | 運算子 | 結合性 |
|---|---|---|
| 1 | ()、[]、{} | 從左向右 |
| 2 | !、+、-、~、++、– | 從右向左 |
| 3 | *、/、% | 從左向右 |
| 4 | +、- | 從左向右 |
| 5 | ?、?、>>> | 從左向右 |
| 6 | <、<=、>、>=、instanceof | 從左向右 |
| 7 | ==、!= | 從左向右 |
| 8 | & | 從左向右 |
| 9 | ^ | 從左向右 |
| 10 | | | 從左向右 |
| 11 | && | 從左向右 |
| 12 | || | 從左向右 |
| 13 | ?: | 從右向左 |
| 14 | =、+=、-=、*=、/=、&=、|=、^=、~=、?=、?=、>>>= | 從右向左 |
訪問修飾符
訪問修飾符就是限制變數的訪問權限的,
比如你有個“賺錢”的方法,誰都不想給用,那就把方法設成private(私有);
后來你有了老婆孩子,你想讓他們也會賺錢,就得設定成default(同一個包);
后來你又有了第二個孩子,但你發現他不會賺錢的方法,為啥呢?因為你被綠了(default不支持不同包的子類);
可為了大局,你還是選擇接受這個孩子,悄悄把方法設定成了proteced(保護子類,即使不同包);
后來你老了,明白了開源才是共贏,就設定成了public(公有的);
不知道你聽懂了嗎,估計看到被那啥了就不想看了吧,沒關系,看圖(也是綠的)

如何理解介面和抽象類?
抽象類:
被abstract修飾的類,不能創建實體物件,
含有抽象方法的類必須定義為抽象類,但抽象類中的方法不必須是抽象的,
抽象類中定義抽象方法必須在子類中實作,如果子類沒有實作抽象父類中的所有抽象方法,那么子類也是抽象類,
介面:
可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的,
介面中的方法定義默認為public abstract型別,介面中的成員變數型別默認為public static final,
區別:
1.抽象類可以有構造方法,介面中不能有構造方法,
2.抽象類中可以有普通成員變數,介面中沒有普通成員變數
3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法,
4.一個類可以實作多個介面,但只能繼承一個抽象類,
具體應用:
介面在系統架構設計方法中發揮著巨大作用,主要用于定義模塊之間的通信契約,
而抽象類在代碼實作方面發揮作用,可以實作代碼的重用,
如何理解static關鍵字
主要意義:
我日常呼叫方法都是物件.方法,static的主要意義就是可以創建獨立于具體物件的域變數或者方法,也就是實作即使沒有創建物件,也能使用屬性和呼叫方法!
另一個比較關鍵的作用就是 用來形成靜態代碼塊以優化程式性能,static塊可以置于類中的任何地方,可以有多個,在類初次被加載的時候,會按照static塊的順序來執行每個static塊,并且只會執行一次,可以用來優化程式性能
通俗理解:
static是一個可以讓你升級的關鍵字,被static修飾,你就不再是你了,
如何理解final關鍵字
final翻譯成中文是“不可更改的,最終的”,顧名思義,他的功能就是不能再修改,不能再繼承,我們常見的String類就是被final修飾的,將類、方法、變數宣告為final能夠提高性能,這樣JVM就有機會進行估計,然后優化,
按照Java代碼慣例,final變數就是常量,而且通常常量名要大寫:
- final關鍵字可以用于成員變數、本地變數、方法以及類,
- final成員變數必須在宣告的時候初始化或者在構造器中初始化,否則就會報編譯錯誤,
- 不能夠對final變數再次賦值,
- final方法不能被重寫,
- final類不能被繼承,
- 介面中宣告的所有變數本身是final的,
- final和abstract這兩個關鍵字是反相關的,final類就不可能是abstract的,
重寫和多載
出自moka
老生常談的問題,除了答出定義,更應該說明他們的區別和應用
方法的多載和重寫都是實作多型的方式,區別在于前者實作的是編譯時的多型性,而后者實作的是運行時的多型性,
多載:發生在同一個類中,方法名相同引數串列不同(引數型別不同、個數不同、順序不同),與方法回傳值和訪問修飾符無關,即多載的方法不能根據回傳型別進行區分
重寫:發生在父子類中,方法名、引數串列必須相同,回傳值小于等于父類,拋出的例外小于等于父類,訪問修飾符大于等于父類(里氏代換原則);如果父類方法訪問修飾符為private則子類中就不是重寫,
構造器是否可被重寫?
構造器不能被繼承,因此不能被重寫,但可以被多載,
代碼塊的執行順序?
基本上代碼塊分為三種:Static靜態代碼塊、構造代碼塊、普通代碼塊
代碼塊執行順序:靜態代碼塊——> 構造代碼塊 ——> 建構式——> 普通代碼塊
繼承中代碼塊執行順序:父類靜態塊——>子類靜態塊——>父類代碼塊——>父類構造器——>子類代碼塊——>子類構造器
泛型
泛”就是寬泛,泛指的意思,所謂泛型就是不指定具體型別,而是作為引數傳遞,
最早接觸泛型是在集合中,我們最常用的集合類之一便是List,假如我們想讓這個List只放Integer型別的元素,可以這樣創建集合類:
List<Integer> list = new ArrayList<Integer>;
List.add(new Integer(11));
我們說Integer是這個集合的泛型,那如果創建一個Double的型別的呢,是不是也是可以的,怎么做到的?
看一些創建時的提示,<E>:型別引數是用來表示自定義識別符號,用來傳遞資料的型別,

泛型的優點:
使用泛型類時指明了資料型別,賦給其他型別的值會拋出例外,既不需要向下轉型,也沒有潛在的風險,
除了定義泛型類,還可以定義泛型介面和泛型方法,使用泛型方法時不必指明引數型別,編譯器會根據傳遞的引數自動查找出具體的型別,
限制泛型的可用型別:
通過 extends 關鍵字可以限制泛型的型別
<T extends Yitiao>
泛型代碼與JVM:
- 虛擬機中沒有泛型,只有普通類和方法,
- 在編譯階段,所有泛型類的型別引數都會被Object或者它們的限定邊界來替換,(型別擦除)
- 在繼承泛型型別的時候,橋方法的合成是為了避免型別變數擦除所帶來的多型災難,
如何理解封裝,繼承,多型?
封裝
1.什么是封裝
封裝又叫隱藏實作,就是只公開代碼單元的對外介面,而隱藏其具體實作,
其實生活中處處都是封裝,手機,電腦,電視這些都是封裝,你只需要知道如何去操作他們,并不需要知道他們里面是怎么構造的,怎么實作這個功能的,
2.如何實作封裝
在程式設計里,封裝往往是通過訪問控制實作的,也就是剛才提到的訪問修飾符,
3.封裝的意義
封裝提高了代碼的安全性,使代碼的修改變的更加容易,代碼以一個個獨立的單元存在,高內聚,低耦合,
好比只要你手機的充電介面不變,無論以后手機怎么更新,你依然可以用同樣的資料線充電或者與其他設備連接,
封裝的設計使使整個軟體開發復雜度大大降低,我只需要使用別人的類,而不必關心其內部邏輯是如何實作的,我能很容易學會使用別人寫好的代碼,這就讓軟體協同開發的難度大大降低,
封裝還避免了命名沖突的問題,
好比你家里有各種各樣的遙控器,但比還是直到哪個是電視的,哪個是空調的,因為一個屬于電視類一個屬于空調類,不同的類中可以有相同名稱的方法和屬性,但不會混淆,
繼承
繼承的主要思想就是將子類的物件作為父類的物件來使用,比如王者榮耀的英雄作為父類,后裔作為子類,后裔有所有英雄共有的屬性,同時也有自己獨特的技能,
多型
多型的定義:
指允許不同類的物件對同一訊息做出回應,即同一訊息可以根據發送物件的不同而采用多種不同的行為方式,(發送訊息就是函式呼叫)
簡單來說,同樣呼叫攻擊這個方法,后裔的普攻和亞瑟的普攻是不一樣的,
多型的條件:
- 要有繼承
- 要有重寫
- 父類參考指向子類物件
多型的好處:
多型對已存在代碼具有可替換性,
多型對代碼具有可擴充性,
它在應用中體現了靈活多樣的操作,提高了使用效率,
多型簡化對應用軟體的代碼撰寫和修改程序,尤其在處理大量物件的運算和操作時,這個特點尤為突出和重要,
Java中多型的實作方式:
-
介面實作
-
繼承父類進行方法重寫
-
同一個類中進行方法多載
如何理解Java反射?
反射之中包含了一個“反”的概念,所以要想解釋反射就必須先從“正”開始解釋,一般而言,當用戶使用一個類的時候,應該先知道這個類,而后通過這個類產生實體化物件,但是“反”指的是通過物件找到類,
代碼如下:
public class test1 {
public static void main(String[] args) {
String yitiao="yitiaoIT";
System.out.println(yitiao.getClass().getName());
}
}
// out:java.lang.String
這就是我們使用反射的一個例子,那么使用反射有什么好處呢?
反射的意義
我們可以通過反射實體化物件,以前都是說物件都是new出來的,現在又有了一種新的方式,
這種方式被廣泛應用于設計模式中,比如工廠模式,代理模式,
Java8有哪些新特性?
Java 8是Java自Java 5(發布于2004年)之后的最重要的版本,這個版本包含語言、編譯器、庫、工具和JVM等方面的十多個新特性,但我們是需要回答常用的兩個就行,
Lambda運算式
它允許我們將函式當成引數傳遞給某個方法,或者把代碼本身當作資料處理,示例:
public class test1 {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.forEach(l-> System.out.println(l));
}
}
更多的使用需要在實際開發中慢慢練習,相信我,你會喜歡用它的,
stream
Java 8 API添加了一個新的抽象稱為流Stream,可以讓你以一種宣告的方式處理資料,
Stream 使用一種類似用 SQL 陳述句從資料庫查詢資料的直觀方式來提供一種對 Java 集合運算和表達的高階抽象,
Stream API可以極大提高Java程式員的生產力,讓程式員寫出高效率、干凈、簡潔的代碼,
這種風格將要處理的元素集合看作一種流, 流在管道中傳輸, 并且可以在管道的節點上進行處理, 比如篩選, 排序,聚合等,
元素流在管道中經過中間操作的處理,最后由最終操作得到前面處理的結果,
比如我們想篩選出工資大于10000的職員
List<Employee> newList = list.stream().filter(item -> {
return item.getSalary().compareTo(new BigDecimal(10000)) > 0 ;
}).collect(Collectors.toList());
以上就是關于Java基礎部分總結出的面試題,如果哪里有問題,歡迎大家交流評論!
最后
?今天是堅持刷題更文的第25/100天
?各位的點贊、關注、收藏、評論、訂閱就是一條創作的最大動力
?更多面試題歡迎關注專欄《大廠面試突擊》
為了回饋各位粉絲,禮尚往來,給大家準備了一條多年積累下來的優質資源,包括 學習視頻、面試資料、珍藏電子書等
關注博主后評論區留言「資料」或私信我就可以領取
一定要先關注哦!不然無法發私信!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/292943.html
標籤:java
