一、Java基礎部分
1. HashMap和Hashtable各有什么特點,它們有什么區別?(必背題,超級重要)
- HashMap和Hashtable都實現了Map接口,但決定用哪一個之前先要弄清楚它們之間的分別。主要的區別有:線程安全性,同步(synchronization),以及速度。
- HashMap幾乎可以等價於Hashtable,除了HashMap是非synchronized的,並可以接受null(HashMap可以接受為null的鍵值(key)和值(value),而Hashtable則不行)。
- HashMap是非synchronized,而Hashtable是synchronized,這意味着Hashtable是線程安全的,多個線程可以共享一個Hashtable;而如果沒有正確的同步的話,多個線程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的擴展性更好。
- 另一個區別是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它線程改變了HashMap的結構(增加或者移除元素),將會拋出ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會拋出ConcurrentModificationException異常。但這並不是一個一定發生的行為,要看JVM。這條同樣也是Enumeration和Iterator的區別。
- 由於Hashtable是線程安全的也是synchronized,所以在單線程環境下它比HashMap要慢。如果你不需要同步,只需要單一線程,那么使用HashMap性能要好過Hashtable。
- HashMap不能保證隨着時間的推移Map中的元素次序是不變的。
2. HashMap的工作原理?
- HashMap基於hashing原理,我們通過put()和get()方法儲存和獲取對象。當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓后找到bucket位置來儲存值對象。當獲取對象時,通過鍵對象的equals()方法找到正確的鍵值對,然后返回值對象。HashMap使用鏈表來解決碰撞問題,當發生碰撞了,對象將會儲存在鏈表的下一個節點中。 HashMap在每個鏈表節點中儲存鍵值對對象。
- 當兩個不同的鍵對象的hashcode相同時會發生什么? 它們會儲存在同一個bucket位置的鏈表中。鍵對象的equals()方法用來找到鍵值對。
- 1和2參考博客鏈接
- 這里還有許多相關問題的描述,都是比較重要的!建議將其背熟!
3. ArrayList和LinkList各自的特點和區別?
1、ArrayList和LinkedList可想從名字分析,它們一個是Array(動態數組)的數據結構,一個是Link(鏈表)的數據結構,此外,它們兩個都是對List接口的實現。前者是數組隊列,相當於動態數組;后者為雙向鏈表結構,也可當作堆棧、隊列、雙端隊列
2、當隨機訪問List時(get和set操作),ArrayList比LinkedList的效率更高,因為LinkedList是線性的數據存儲方式,所以需要移動指針從前往后依次查找。
3、當對數據進行增加和刪除的操作時(add和remove操作),LinkedList比ArrayList的效率更高,因為ArrayList是數組,所以在其中進行增刪操作時,會對操作點之后所有數據的下標索引造成影響,需要進行數據的移動。
4、從利用效率來看,ArrayList自由性較低,因為它需要手動的設置固定大小的容量,但是它的使用比較方便,只需要創建,然后添加數據,通過調用下標進行使用;而LinkedList自由性較高,能夠動態的隨數據量的變化而變化,但是它不便於使用。
5、ArrayList主要控件開銷在於需要在lList列表預留一定空間;而LinkList主要控件開銷在於需要存儲結點信息以及結點指針信息。
4. RESTFul風格接口的特點?
- 此題是現在做應用開發常問的題目,RestFul風格在現在的應用開發還是比較常用的,所以還是比較重要,建議進行了解:以下是作者自認為不錯的一篇關於RestFul架構風格的博客,推薦!博客·鏈接
5. 面向對象的七種設計原則
面向對象七大設計原則:
1、 開閉原則(OCP:Open Closed Principle)
核心:對擴展開放,對修改關閉。即在設計一個模塊的時候,應當使這個模塊可以在不被修改的前提下被擴展。
- 根據開閉原則,在設計一個軟件系統模塊(類,方法)的時候,應該可以在不修改原有的模塊(修改關閉)的基礎上,能擴展其功能(擴展開放)。
2、 里氏替換原則(LSP:Liskov Substitution Principle)
核心:在任何父類出現的地方都可以用他的子類來替代(子類應當可以替換父類並出現在父類能夠出現的任何地方)
- 1.子類必須完全實現父類的方法。在類中調用其他類是務必要使用父類或接口,如果不能使用父類或接口,則說明類的設計已經違背了LSP原則。
- 2.子類可以有自己的個性。子類當然可以有自己的行為和外觀了,也就是方法和屬性
- 3.覆蓋或實現父類的方法時輸入參數可以被放大。即子類可以重載父類的方法,但輸入參數應比父類方法中的大,這樣在子類代替父類的時候,調用的仍然是父類的方法。即以子類中方法的前置條件必須與超類中被覆蓋的方法的前置條件相同或者更寬松。
- 4.覆蓋或實現父類的方法時輸出結果可以被縮小。
3、 單一職責原則(SRP:Single responsibility principle)
核心:解耦和增強內聚性(高內聚,低耦合)
- 類被修改的幾率很大,因此應該專注於單一的功能。如果你把多個功能放在同一個類中,功能之間就形成了關聯,改變其中一個功能,有可能中止另一個功能,這時就需要新一輪的測試來避免可能出現的問題。
4、 接口隔離原則(ISP:Interface Segregation Principle)
核心思想:不應該強迫客戶程序依賴他們不需要使用的方法。接口分離原則的意思就是:一個接口不需要提供太多的行為,一個接口應該只提供一種對外的功能,不應該把所有的操作都封裝到一個接口當中.
- 分離接口的兩種實現方法:
- 1.使用委托分離接口。(Separation through Delegation)
- 2.使用多重繼承分離接口。(Separation through Multiple Inheritance)
5、 依賴倒置原則(DIP:Dependence Inversion Principle)
核心:要依賴於抽象,不要依賴於具體的實現
- 1.高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象(抽象類或接口)
- 2.抽象不應該依賴細節(具體實現)
- 3.細節(具體實現)應該依賴抽象。
三種實現方式: - 1.通過構造函數傳遞依賴對象
- 2.通過setter方法傳遞依賴對象
- 3.接口聲明實現依賴對象
6、 迪米特原則(最少知識原則)(LOD:Law of Demeter)
核心思想:一個對象應當對其他對象有盡可能少的了解,不和陌生人說話。(類間解耦,低耦合)意思就是降低各個對象之間的耦合,提高系統的可維護性;在模塊之間只通過接口來通信,而不理會模塊的內部工作原理,可以使各個模塊的耦合成都降到最低,促進軟件的復用
注:
- 1.在類的划分上,應該創建有弱耦合的類;
- 2.在類的結構設計上,每一個類都應當盡量降低成員的訪問權限;
- 3.在類的設計上,只要有可能,一個類應當設計成不變;
- 4.在對其他類的引用上,一個對象對其它對象的引用應當降到最低;
- 5.盡量降低類的訪問權限;
- 6.謹慎使用序列化功能;
- 7.不要暴露類成員,而應該提供相應的訪問器(屬性)
7、 組合/聚合復用原則(CRP:Composite Reuse Principle)
核心思想:盡量使用對象組合,而不是繼承來達到復用的目的。該原則就是在一個新的對象里面使用一些已有的對象,使之成為新對象的一部分:新的對象通過向這些對象的委派達到復用已有功能的目的。
復用的種類:
- 1.繼承
- 2.合成聚合
注:在復用時應優先考慮使用合成聚合而不是繼承
6. 談談堆和棧的區別!
a.堆棧空間分配
- 棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
- 堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表
b.堆棧緩存方式
- 棧使用的是一級緩存, 他們通常都是被調用時處於存儲空間中,調用完畢立即釋放。
- 堆則是存放在二級緩存中,生命周期由虛擬機的垃圾回收算法來決定(並不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。
c.堆棧數據結構區別
- 堆(數據結構):堆可以被看成是一棵樹,如:堆排序。
- 棧(數據結構):一種先進后出的數據結構。
7. 談談你所了解的設計模式,並簡單描述其特點和用法,或簡單寫一個某某設計模式!
1. 單例設計模式
2. 工廠設計模式
3. 代理模式
4. 觀察者設計模式
5. 適配器模式
6. 策略模式
7. 門面模式
8. 橋接模式
來一個參考鏈接幾種常用的設計模式參考博客鏈接
注:設計模式有很多,這里列舉幾種常用的!讀者需要自行將這幾種設計模式理解清楚!前五種是常用也是常考的!
8. 熟悉HTTP基本的狀態碼!
一些常見的狀態碼為:
- 200 - 服務器成功返回網頁
- 404 - 請求的網頁不存在
- 503 - 服務不可用
- 具體詳細的可以參考博客 HTTP狀態碼詳細博客鏈接
9. List、Set和Map的特點和區別(重點)
List:
- 1.可以允許重復的對象。
- 2.可以插入多個null元素。
- 3.是一個有序容器,保持了每個元素的插入順序,輸出的順序就是插入的順序。
- 4.常用的實現類有 ArrayList、LinkedList 和 Vector。ArrayList 最為流行,它提供了使用索引的隨意訪問,而 LinkedList 則對於經常需要從 List 中添加或刪除元素的場合更為合適。
Set:
- 1.不允許重復對象
- 2.無序容器,你無法保證每個元素的存儲順序,TreeSet通過 Comparator 或者 Comparable 維護了一個排序順序。
- 3.只允許一個 null 元素
- 4.Set 接口最流行的幾個實現類是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基於 HashMap 實現的 HashSet;TreeSet 還實現了 SortedSet 接口,因此 TreeSet 是一個根據其 compare() 和 compareTo() 的定義進行排序的有序容器。
Map:
- 1.不是collection的子接口或者實現類。Map是一個接口。
- 2.Map 的 每個 Entry 都持有兩個對象,也就是一個鍵一個值,Map 可能會持有相同的值對象但鍵對象必須是唯一的。
- 3.TreeMap 也通過 Comparator 或者 Comparable 維護了一個排序順序。
- 4.Map 里你可以擁有隨意個 null 值但最多只能有一個 null 鍵。
- 5.Map 接口最流行的幾個實現類是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)
10.監聽器、過濾器、攔截器、servlet的區別
- eb.xml 的加載順序是:context- param -> listener -> filter -> servlet
監聽器(listener): - 在request、session、application三個對象創建消亡或者往其中增/刪/改屬性時自動執行指定代碼的功能組件。
- 生命周期:隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷毀。
- 作用:做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者是一些固定的對象等等。
過濾器(filter): - 攔截請求,filter能夠在一個請求到達控制層之前預處理用戶請求,也可以在離開控制層時處理http 響應,進行一些設置以及邏輯判斷,然后再傳入servlet或者struts的 action進行業務邏輯,基於函數回調。
- 生命周期:它是隨你的web應用啟動而啟動的,只初始化一次,以后就可以攔截相關請求,只有當你的web應用停止或重新部署的時候才銷毀。
- 作用:a.對請求或響應(Request、Response)統一設置統一編碼,簡化操作;b.進行邏輯判斷,如用戶是否已經登陸、有沒有權限訪問該頁面等等工作。c.過濾掉非法url
攔截器(interceptor): - 攔截器是在面向切面編程中應用的,基於JAVA的反射機制,在一個業務邏輯(某個方法) 前、后調用另一個方法。
生命周期:
作用:
servlet: - servlet是一種運行服務器端的java應用程序,具有獨立於平台和協議的特性,並且可以動態的生成web頁面,它工作在客戶端請求與服務器響應的中間層。
參考鏈接:參考博客鏈接
11. 當在瀏覽器輸入一個網址,所要經過的全部在過程,請詳細描述!
瀏覽器訪問某地址的詳細過程:
- 在服務器上輸入一個地址:例如www.baidu.com后,回車:瀏覽器會根據輸入的URL到DNS服務器查詢對應的IP地址和域名;返回到客戶端,客戶端再根據所查到的的域名和IP,請求建立TCP連接,連接到對應的百度服務器,向服務器發送HTTP Request(請求),服務端接收到請求包並進行處理,並調用自身服務,返回HTTP Response(響應)。客戶端接到響應的時候開始渲染這個Response包里的主體(body),等接收完所有內容后自動斷開該TCP連接。
- 詳細過程圖:
12. 簡單描述Spring的特點:
- spirng就是一個容器 ,它通過控制反轉IOC和依賴注入(DI)實現高內聚、低耦合的應用。除此之外她還能整合很多第三方框架,它提供了面向切面編程AOP的能力,使其對數據庫事務管理極為方便。
- 簡介:Spring就是一個輕量級的開源的Java SE 和Java EE 的開發應用框架。目的在於簡化企業級應用的開發。
二、數據庫基礎部分
1. 詳細描述幾種你所熟悉的優化數據庫的方式。
1、選取最適用的字段屬性
2、使用連接(JOIN)來代替子查詢(Sub-Queries)
3、使用聯合(UNION)來代替手動創建的臨時表
4、事務
5、鎖定表
6、使用外鍵
7、使用索引
8、優化的查詢語句
參考鏈接:優化數據庫的八種方式詳解
2. 數據庫的視圖和索引都有什么特點,有什么區別?
- 概念:視圖是從一個或多個表中導出來的表,是一種不是一種真正存在的概念。
- 視圖操作sql:
1 //創建視圖: 2 create view viewName(參數列表/可以不寫這樣就是默認和下面的select一樣) as select * from 表名; 3 //例1: 4 create table viewdemo(id int primary key , name char(10),score float); 5 create view view1 6 as select* from viewdemo; 7 create view view2(name,score) as select name ,score from viewdemo; 8 //修改視圖: 9 alter view viewname (columns) as select columns from tableName; 10 //例: 11 alter view view2 (id ,name) as select id,name from viewdemo ; 12 //刪除視圖: 13 drop view if exists view name; 14 //例: 15 drop view view2;
- 概念:可以理解為是一本書的目錄,它記錄了數據在數據庫中存放的位置,就像一本書的目錄,記錄了,某一頁在這本書的那個位置。相同地,索引是一個單獨的、存儲在磁盤上的數據庫結構,它們包含着對數據庫表里所有記錄的引用指針。
- 視圖操作sql:
1 ALTER TABLE table_name ADD [UNIQUE|FULLTEXT] [INDEX|KEY] 2 [inex_name] (col_name [length ] ,...) [ASC|DESC]
1 普通索引: 2 ALTER TABLE book ADD INDEX indexName( bookname(30) ); 3 唯一索引: 4 ALTER TABLE book ADD UNIQUE INDEX UniqueIdx( bookid ); 5 組合索引: 6 ALTER TABLE book ADD INDEX BkAndInfoIdx( authors(20), info(50) ); 7 全文索引: 8 ALTER TABLE t6 ADD FULLTEXT INDEX infiIdx(info);( 9 前提是這個表的存儲引擎為 MyISAM)
使用 create index 創建索引:
語法:
1 CREATE [UNIQUE|FULLTEXT] [INDEX|KEY] INDEX index_name 2 ON table_name ( col_name[ length ] , ... ) [ASC | DESC ] 3 例:在表book的bookname字段上建立名為BkNameIdx的索引。 4 CREATE INDEX BkNameIdx ON book (bookname); 5 例: 在book表的bookId字段上建立唯一索引。 6 CREATE UNIQUE INDEX UniqueIdx ON book (bookId); 7 4、刪除索引: 8 ALTER TABLE table_name DROP INDEX index_name; 9 DROP INDEX index_name ON table_name ;
后續還會有補充,姑且先寫到這吧!
我有一個微信公眾號,經常會分享一些Java技術相關的干貨;
如果你喜歡我的分享,可以用微信搜索“Java團長”或者“javatuanzhang”關注。