java中==和equals和hashCode的差別
- ==比較的是記憶體位址。例:兩個字元串對象,盡管内容一模一樣,但記憶體位址是不同的,當你拿==做比較時,得到的結果必然是false。
- equals比較的是對象内容。例:要是想判斷内容是否一樣的話,就得用equals方法。
基本資料類型各占多少位元組數
基本資料類型 | 位元組數 | ||
數值型 | 整數類型 | byte | 1位元組 |
short | 2位元組 | ||
int | 4位元組 | ||
long | 8位元組 | ||
浮點類型 | float | ||
double | |||
字元型 | char | ||
布爾型 | boolean | 至少1位元組 |
int和integer差別
- int則是java的一種基本資料類型,Integer是int的包裝類;
- Integer變量必須執行個體化後才能使用,而int變量不需要;
- Integer實際是對象的引用,當new一個Integer時,實際上是生成一個指針指向此對象;而int則是直接存儲資料值。
- int預設值是0,integer預設值是null。
包裝類作用及基本資料類型的包裝類
- Java中基本資料類型沒有方法和屬性,而包裝類就是讓基本資料類型擁有方法和屬性,實作對象化互動。
- 數值包裝類繼承Number,字元包裝類、布爾包裝類繼承Object
包裝類 | |
Byte | |
Short | |
Integer | |
Long | |
Float | |
Double | |
Character | |
Boolean |
String、StringBuffer以及StringBuilder差別
- String是一個字元串常量,其值是不可變的對象,也就是說在我們每次對String進行更改的時候就會生成一個新的String對象,指針就會指向新的String對象,進而效率就會低下,也浪費了記憶體。
- StringBuffer是一個可變類,并且線程是安全的一個字元串操作類。任何對他指向字元串操作都不會生成一個新的對象,還自帶緩沖區,目前字元串大小沒有超過緩沖容量時,不會自動配置設定,超過後會自動增加容量。适合多線程場合使用。
- StringBuilder也是一個可變類,是一個線程不安全的字元串操作類。StringBuilder相比StringBuffer是沒有對方法加鎖同步的,是以StringBuilder性能比StringBuffer高、安全性比StringBuffer差,适合單線程場合使用。
&&和 || 差別
- &&稱為:短路“與”;&稱為:按位“與”
- || 稱為:短路“或”;| 稱為:按位“或”
- “與”就是并且的意思,多個判斷條件時都得滿足
- “與”和“或”都是邏輯運算符,顧名思義,“短路”在判斷的過程中,一旦目前項為假,就短路了,後面的條件不再進行判斷。“按位”則相反,一直會把所有的條件都判斷完
重載和重寫的差別
- 重載(Override)同一個類中,可以定義多個名字相同的方法,參數、傳回值可以不同。
- 重寫(Override)子類繼承父類,同時也繼承了父類的方法,當父類的方法不能滿足子類需要時,子類可以重寫父類的方法。重寫時方法名、參數以及傳回值類型都必須跟父類一緻。構造方法不能重寫。
Java多态的了解
- 多态是同一個行為具有多個不同表現形式或形态的能力。
- 多态就是同一個接口,使用不同的執行個體而執行不同操作
- 重寫和重載也是多态的一種表現形式
- 多态作為Java的三大特征之一,其目的都是提現Java語言的靈活性、簡化性、可拓展性等。
JVM、JRE、JDK是什麼?
- JVM(Java Virtual Machine)是Java虛拟機,
- JRE(Java Runtime Environment)是Java運作環境,
- JDK(Java Development Kit)是Java開發工具包。
- JVM + 基本類庫 = JRE。
- JRE + 編譯工具 = JDK。
- 是以三者的關系是:JDK > JRE > JVM
Java跨平台原理
- JAVA之是以能跨平台,得益于JAVA虛拟機,在任何作業系統下,都有相應版本的虛拟機,我們把編譯好的class檔案,放在任何一台虛拟機上,都可以正常運作。這樣我們就利用虛拟機屏蔽了作業系統的不同,即達到了一次編寫處處運作的效果。
Exception和Error差別
- Exception和Error都繼承Throwable類。
- Error,是系統中的錯誤,比如系統崩潰、虛拟機錯誤等,我們隻有修改程式配置才能解決。通常Java程式不會捕獲和抛出這類異常。
- Exception分為運作時異常和編譯時異常
- 運作時異常:Java編譯器允許程式不對它們做出處理,而在程式執行的過程中抛出的異常。
- 編譯時異常:Java編譯器要求程式必須通過try catch捕獲或者聲明抛出這種異常
Java序列化的了解
- Java的序列化是指将對象轉換成二進制資料流的一種實作。通過将對象的序列化,可以友善的實作對象的傳輸及儲存。
- 序列化友善傳輸,速度快,還很安全,可以拿到最原始的Java對象,常用于線程間的對象傳輸。
- 序列化友善存儲,可以存成檔案或資料庫都行,下次使用的時候直接反序列化就能拿到對象。
- 想要實作序列化,直接實作Serializeable接口就好,該接口下什麼方法都沒有,隻是一個标記接口。
什麼是内部類,内部類的作用
- 内部類就是定義在另一個類中或方法中的一個類。有四種内部類:
- 成員内部類,靜态内部類,局部(方法)内部類,匿名内部類。
内部類作用:
- 内部類方法可以通路該類定義區域的資料,包括私有有資料。
- 内部類提供了更好的封裝,除了該外圍類,其他的類均不能通路。
- 想要定義一個回調方法時,使用匿名内部類會很友善
接口和抽象類的差別
- 關鍵字差別:接口關鍵字是interface,抽象類關鍵字是abstract;
- 接口是通過implements來實作的,而抽象類是extends來繼承的;
- 接口可以多實作,抽象類隻能單繼承;
- 接口和抽象類都不能被執行個體化;
- 接口成員變量public static final必須複制且不能被更改
- 抽象類成員變量預設default,可以在子類中進行重新定義或指派。抽象方法被abstract修飾,并且不帶方法體,不能被private、static、synchronized等修飾符修飾。隻能用public或protected修飾。
抽象類的意義
- 更好的将設計與實作分離;
- 提高開發效率,便于日後維護;
- 增加代碼規範;
final、finally、finalize差別
- 三個都是Java的關鍵字
- final是一個修飾符,用于修飾類、方法和屬性。修飾的類不能被繼承,修飾的方法不能被重寫,修飾的屬性不可更改;
- finally是異常處理文法結構的一個子產品,此子產品中的内容總是會被執行;
- finalize是object類的一個方法,垃圾回收器執行的時候調用回收對象的方法。
Java泛型的好處
java語言引入泛型的好處是安全和簡單,泛型的好處是在編譯的時候檢查類型安全,并且所有強制類型轉換都是自動的,提高代碼的重用率。
string 轉換成 integer的方式及原理
- 調用Integer.parseInt(String s);方法
- 判斷是否為空
- 判斷第一個字元是不是符号
- 循環周遊每個字元的十進制
- 通過 *= 和 -= 進行拼接
- 判斷是否為負值
- 傳回結果
extends和super差別
- ? 既不能用于入參也不能用于返參。
this和super的差別
- this代表對象本身,是指向目前的對象一個指針。
- this可以區分自身的成員和傳遞過來的參數重名。this.name = name;
- this可以引用本類的構造函數。this(name);
- super是指向自己超類的一個指針,并且是離自己最近的一個父類。
- super可以引用父類的構造函數super(name);
- this和super需放在構造方法的第一行。
- this和super不能出現在同一個構造方法中。
- this和super指向的都是對象,不能出現在static子產品中。
程序和線程的差別
- 程序是程式正在運作的一個執行個體,是系統配置設定資源和排程的一個進本機關。
- 線程是系統運算排程的最小執行機關,被包含在程序中,也被稱作輕量級程序。
- 同一線程共享本程序的位址空間及資源,而程序則之間是獨立的位址空間和資源。
- 程序崩潰後不會影響其他的程序,而線程崩潰後則程序也會随之崩潰。是以程序比線程要健壯些。
- 程序切換時占用資源大,能效高,是以涉及到頻繁切換的時候線程好于程序。
- 執行的時候每個獨立的程序都擁有程式運作的入口,但是線程不能獨立運作,必須依賴于程序之中,由程式提供多個線程執行控制。
- 兩者均可并發執行
線程開啟的三種方式
- 繼承Thread類
- 實作Runnable接口
- 直接建立Thread執行個體
繼承Thread類和實作runnable接口差別
- 繼承是單繼承,實作是多實作。
- 繼承的方式比較簡單,實作的方式稍微複雜。
- 繼承不能實作多線程共享資源,而實作可以。
sleep、wait、yield、join差別
- sleep 方法是屬于 Thread 類中的,sleep 過程中線程不會釋放鎖,隻會阻塞線程,讓出cpu給其他線程,但是他的監控狀态依然保持着,當指定的時間到了又會自動恢複運作狀态,可中斷,sleep 給其他線程運作機會時不考慮線程的優先級,是以會給低優先級的線程以運作的機會。
- wait 方法是屬于 Object 類中的,wait 過程中線程會釋放對象鎖,隻有當其他線程調用 notify 才能喚醒此線程。wait 使用時必須先擷取對象鎖,即必須在 synchronized 修飾的代碼塊中使用,那麼相應的 notify 方法同樣必須在 synchronized 修飾的代碼塊中使用,如果沒有在synchronized 修飾的代碼塊中使用時運作時會抛出IllegalMonitorStateException的異常
- yield和 sleep 一樣都是 Thread 類的方法,都是暫停目前正在執行的線程對象,不會釋放資源鎖,和 sleep 不同的是 yield方法并不會讓線程進入阻塞狀态,而是讓線程重回就緒狀态,它隻需要等待重新擷取CPU執行時間,是以執行yield()的線程有可能在進入到可執行狀态後馬上又被執行。還有一點和 sleep 不同的是 yield 方法隻能使同優先級或更高優先級的線程有執行的機會
- 等待調用join方法的線程結束之後,程式再繼續執行,一般用于等待異步線程執行完結果之後才能繼續運作的場景。例如:主線程建立并啟動了子線程,如果子線程中藥進行大量耗時運算計算某個資料值,而主線程要取得這個資料值才能運作,這時就要用到 join 方法了
線程的運作狀态
- 建立狀态(new)新建立了一個線程對象。
- 就緒狀态(runnable)建立完成後其他線程調用了start()該狀态處于可運作池中,等待擷取CPU使用權。
- 運作狀态(running)就緒狀态的線程獲得了CPU,執行了run()方法。
- 阻塞狀态(blocked)阻塞狀态是因為線程的某種原因放棄CPU使用權,wait()、join()、yelid()、sleep()。
- 死亡狀态(dead)java執行完了或因異常退出了run()方法,結束了線程的生命周期。
什麼是線程池?線程池的作用。
- java.util.concurrent.Executors提供了一個 java.util.concurrent.Executor接口的實作用于建立線程池,多線程技術主要解決處理器單元内多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。
- 線程池作用就是限制系統中執行線程的數量。根據系統的環境情況,可以自動或手動設定線程數量,達到運作的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制線程數量,其他線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待程序,線程池的這一資源處于等待。當一個新任務需要運作時,如果線程池中有等待的工作線程,就可以開始運作了;否則進入等待隊列。
- 減少了建立和銷毀線程的次數,每個工作線程都可以被重複利用,可執行多個任務。
- 可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的記憶體,而把伺服器累趴下(每個線程需要大約1MB記憶體,線程開的越多,消耗的記憶體也就越大,最後當機)。
synchronized 和volatile 關鍵字的差別
- volatile本質的是在告訴jvm目前變量在寄存器中的值是不确定的,需要從主記憶體中讀取。
- synchronized是鎖定目前變量,隻有目前線程可以通路改變量,其他線程被阻塞。
- volatile隻能在變量級别使用,而synchronized可以在變量和方法中使用。
- volatile僅能實作變量的修改可見性,而synchronized則可以保證變量的修改可見性和原子性.
- volatile不會造成線程阻塞,而synchronized會造成線程阻塞。
- 使用volatile而不是synchronized的唯一安全情況是類中隻有一個可變域。
synchronized和Lock差別
- Lock是一個接口,而synchronized是Java的一個關鍵字
- synchronized在發生異常的時候會主動釋放線程占有的鎖,不會導緻死鎖的發生。Lock在發生異常時如果沒有調用unLock()去釋放鎖時就會造成死鎖,是以使用Lock時,得在finally語句塊中釋放鎖。
- Lock可以讓等待的線程中斷,而synchronized不可以。
- 通過Lock可以知道是否擷取到鎖,而synchronized不可以。
- Lock可以提高多個線程讀操作的效率
- 在性能上來說,如果資源競争不激烈,兩者性能都是差不多的,如果競争非常激烈的話,Lock的性能要高于synchronized,是以要視情況選擇。
怎麼終止線程?
- 使用exit标志位方法。
- 使用interrupt()方法
- 使用stop(不推薦使用,線程不安全,過時方法)。
List、Set、Map差別
- Collection接口繼承Iterable接口,而List和Set繼承Collection接口,Map不繼承。
- Map和Collection并列為Java的兩大集合
- List特點:元素有放入順序,元素可重複 ,支援for循環,也就是通過下标來周遊,也可以用疊代器。有兩大繼承類ArrayList和LinkedList。
- Set特點:元素無放入順序,元素不可重複,重複元素會覆寫掉,但是set隻能用疊代,因為他無序,無法用下标來取得想要的值。兩大繼承類:HashSet和TreeSet
- Map是通過鍵值對的方式來存儲資料。兩大繼承類HashMap和TreeMap。
ArrayList和LinkedList差別
- ArrayList和LinkedList都是List下的實作類。
- ArrayList 采用的是數組形式來儲存對象的,這種方式将對象放在連續的位置中,優點是使用索引在數組中搜尋和讀取資料是很快,缺點就是增加删除時非常麻煩。
- LinkedList 是采用雙連結清單形式存儲資料,大量的資料時,增加和删除性能高于ArrayList,但是缺點就是查找非常麻煩要叢第一個索引開始。
集合和數組差別
- 數組的長度是固定的,集合的長度是可變的
- 繼承的父類不同,HashMap是繼承AbstractMap,HashTable繼承Dictionary。
- 線程安全不同,HashMap是線程不安全的,HashTable是線程安全的。
- 周遊方式内部實作不同,HashMap和HashTable都是使用了Iterator,由于曆史原因HashTable還是用Eunmeration方式。
- Hash值不同,HashTable直接使用對象的HashCode,而HashMap會重新計算Hash值。
- MVC是分别通過model(模型)、view(視圖)、controller(控制器)來建立設計的應用程式的一種模式。model層:主要負責處理程式中邏輯部分,比如資料庫的操作。view層:視圖效果,布局頁面。controller控制器:主要負責程式中和使用者互動的部分。從view層擷取顯示及資料,controller層來控制和使用者之間的互動,最後再傳遞給model層。
- MVC的優點:1降低耦合性、2提高複用率、3部署快、4可維護性高
- MVC的缺點:1不适合中小型應用:花大量時間建立此模式再運用于小的程式中就會得不償失。2簡單的界面效率低:簡單的頁面嚴格遵循MVC模式的話,會增加結構的複雜性,進而效率就會降低。3view層對model層通路效率低:模型的操作接口不同,視圖層需要多次調用才能顯示資料。
- MVP是Model-View-Presenter ;MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方Controller/Presenter負責邏輯的處理,Model提供資料,View負責顯示。
- MVP優點:1模型與視圖完全分離,我們可以修改視圖而不影響模型。2可以更高效地使用模型,因為所有的互動都發生在Presenter内部。3可以将一個Presenter用于多個視圖,而不需要改變Presenter的邏輯,因為視圖的變化總是比模型的變化頻繁。4如果我們把邏輯放在Presenter中,那麼我們就可以脫離使用者接口來測試這些邏輯(單元測試)。
- MVP缺點:由于對視圖的渲染放在了Presenter中,是以視圖和Presenter的互動會過于頻繁。如果Presenter過多地渲染了視圖,往往會使得它與特定的視圖的聯系過于緊密。一旦視圖需要變更,那麼Presenter也需要變更了。
- MVC和MVP的差別:在MVP中View并不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進行的,所有的互動都發生在Presenter内部,而在MVC中View會直接從Model中讀取資料而不是通過 Controller。在MVC裡,View是可以直接通路Model的!進而,View裡會包含Model資訊,還要包括一些業務邏輯。 在MVC模型裡,更關注的Model的改變,而同時有多個對Model的不同顯示,即View。是以,在MVC模型裡,Model不依賴于View,但是View是依賴于Model的。
- MVVM是Model-View-ViewModel的簡寫。它本質上就是MVC的改進版。MVVM 就是将其中的View 的狀态和行為抽象化,讓我們将視圖 UI 和業務邏輯分開。在視圖模型中,綁定器在視圖和資料綁定器之間進行通信。
- MVVM優點:低耦合,可重用行:視圖邏輯放在視圖模型中,讓更多的view重用這段邏輯。獨立開發,可測性。
- MVVM和MVP差別:mvvm模式将Presener改名為View Model,基本上與MVP模式完全一緻,唯一的差別是,它采用雙向綁定(data-binding): View的 變動,自動反映在View Model,這樣開發者就不用處理接收事件和View更新的工作,架構已經幫你做好了。