簡單說下什么是java跨平台
由於各種操作系統所支持的指令集不是完全一致,所以在操作系統之上加個虛擬機可以來提供統一接口,屏蔽系統之間的差異。
例如Java程序的運行依賴的是JVM,不同的操作系統有不同版本的JVM,這個就實現了java虛擬機的跨平台性,也稱具有良好的可移植性。
Java有幾種基本數據類型
byte short int long float double char boolean
面向對象的特征
封裝
隱藏對象的實現細節,對外提供公開的訪問接口,通過private 關鍵字進行封裝
繼承
繼承是從已有的類中派生出新的類,新的類能吸收已有類的數據屬性和行為,並能擴展新的能力。
封裝的好處是 可以提高安全性以及重用性
多態
同一對象,在不同時刻具有不同的形態,他是面向對象程序設計的一個重要特征,主要是指同一個對象,在不同時刻,代表的對象不一樣,指的是對象的多種形態。
什么是面向對象?和面向過程有什么不同
面向對象是一種編程的思想,能將復雜的事情簡單化.由執行者變為指揮者,面向對象是基於面向過程而言的.
面向對象強調的是結果,
面向過程強調的是過程
繼承的作用
這種技術使得復用以前的代碼非常容易,能夠大大縮短開發周期,降低開發費用。
本質上就想要提高代碼的復用性,減少代碼的編寫。
多態的作用
一 把把不同的子類對象當成父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,統一調用標准
二 統一調用標准,一切向父類看齊
三 提高了程序的可擴展性和可維護性
抽象類和接口的區別
抽象類本身不能創建對象,但是,為什么會提供構造方法? --- 是為了子類創建對象時調用 !!
-- 相同點:都是抽象層,都不能實例化
-- 不同點:
-- 1、抽象類用abstract關鍵字描述,接口用interface
-- 2、子類和抽象類之間是extends關系,實現類和接口之間是implements關系
-- 3、抽象類中 可以 有構造方法 ,接口里 不能 出現 構造方法
-- 4、抽象類里可以有 變量,接口里沒有變量全都是靜態的常量
-- 5、接口里定義常量的語法:public static final String NAME="jack",會為變量自動拼接public static final
-- 6、抽象類里 可以有普通方法 也可以有 抽象方法,接口都是抽象方法
-- 7、抽象類和子類之間是繼承關系,而且java中,只支持單繼承
-- 8、接口突破了java單繼承的局限性,因為接口可以多繼承也可以多實現,甚至可以繼承的同時多實現
-- 9、接口的復雜用法
-- 多繼承: interface A extends B,C 其中A是子接口,同時擁有自己的和BC的功能
-- 多實現: class AImpl implements M,N,O,P 其中AImpl是實現類,需要同時重寫MNOP的所有抽象方法,否則就是一個抽象類
-- 繼承的同時多實現: class AImpl extends Object implements M,N 一定是先繼承后實現
方法重寫和方法重載
方法重載:
方法重載就是方法名相同,方法的參數不同,返回類型可以相同也可以不同(不是關鍵的)。
每個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型列表。
重載的規則就是 :重載的方法必須修改參數列表(參數的個數,參數的類型,參數的順序)
方法重寫:
方法重寫的前提是要有繼承關系才可以進行方法的重寫
方法的重寫是在子類中實現的,要求重寫的方法必須和父類完全一致,
方法重寫不能拋出比父類范圍更大的異常
方法的重寫和重載是java多態性的不同表現,重寫是父類與子類之間多態性的一種表現,重載可以理解成多態的具體表現形式。
(1)方法重載是一個類中定義了多個方法名相同,而他們的參數的數量不同或數量相同而類型和次序不同,則稱為方法的重載
(2)方法重寫是在子類存在方法與父類的方法的名字相同,而且參數的個數與類型一樣,返回值也一樣的方法,就稱為重寫(
(3)方法重載是一個類的多態性表現,而方法重寫是子類與父類的一種多態性表現。
this關鍵字
this關鍵字的本質就是“創建好的對象的地址”
在構造器的重載中,使用this關鍵字必須寫在第一行
this關鍵字不能存在於static方法中
繼承有什么特點?
使用extends關鍵字
相當於子類把父類的功能復制了一份
Java只支持單繼承
繼承可以傳遞
不能繼承父類中私有的資源
繼承多用於功能的修改,子類可以擁有父類的功能的同時,進行功能擴展
像是is a 的關系
super關鍵字
super關鍵字相當於是父類對象的一個引用
如果出現在構造方法中,則必須寫在第一行
可以在子類中使用父類的功能,通過super關鍵字調用
static關鍵字
可以修飾成員變量,成員方法
隨着類的加載而加載,優先於對象的加載
只加載一次,就會一直存在,不再開辟新的空間
全局唯一,全局共享
可以直接使用類名來調用
靜態的只能調用靜態的,非靜態的可以調用靜態的,但是靜態的不能直接調用非靜態的
static不能和this和super公共,因為有static的時候可能還沒有對象
final關鍵字
Java中的一個關鍵字
final可以修飾變量 ,方法,類
被final修飾的類是最終類,不能進行繼承
被final修飾的變量是常量,一旦定義后就不可以修改
被final修飾的方法,不能進行重寫
final修飾的變量一般大寫,代表常量,為了方便外界的調用,一般也會同時使用static修飾
簡述static和final的用法?
static:修飾屬性,方法,代碼塊
(1)靜態屬性:也可叫類變量 類名.屬性名 來訪問
(共有的類變量與對象無關,只和類有關)
注意:類中的實例變量是在創建對象時被初始化的,被static修飾的屬性,也就是類變量,是在類加載時被創建並進行初始化,類加載的過程是進行一次。也就是類變量只會被創建一次。
(2)靜態方法:類名.方法名 直接訪問
注意:static修飾的方法,不能直接訪問本類中的非靜態(static)成員(包括方法和屬性)
本類的非靜態方法可以訪問本類的靜態成員(包括方法和屬性),可以調用靜態方法。
修飾變量,方法,類
final:修飾變量,類,方法
(1)修飾變量
被fianl修飾的成員變量就是常量(常量名大寫),一旦賦值不能改變
修飾局部變量:修飾基本數據類型 -> 變量的值不能改變
修飾引用 -> 引用只能指向固定的對象
修飾實例變量:默認值不生效,可以再賦值
(2)修飾方法 :不能被子類覆蓋
(3)修飾類:不能被繼承
在一個final類中的所有方法,默認都是final的
注意:final,不能用來修飾構造方法。
多態的特點
前提 : 發生了繼承關系,有方法的重寫
父類引用指向子類對象
編譯的時候看左邊,運行的時候看右邊
接口的使用
接口中沒有構造方法
接口中沒有變量,都是靜態的常量,即使簡寫,也會自動拼接public static final 這些個關鍵字
接口中不能有普通方法
接口中的方法都是抽象的方法
重寫接口里的方法時,要有足夠的權限
寫出冒泡排序的算法
int[] arr = {5,6,9,8,2,1,7};
for(int i = 0; i<arr.length-1;i++){
for(int j = 0; j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
Error和Exception有什么區別? 列出你見過的Exception並簡要說明
error 表示系統級的錯誤和程序不必處理的異常,恢復很難的一種嚴重問題
exception 表示需要捕捉或者需要程序進行處理的異常,是一種設計或實現問題,
創建的異常類型有
空指針異常
類型不能轉換異常
下標索引越界異常
數據格式轉換異常
SQL異常
異常分為運行時異常和檢查時異常
檢查時異常需要在開發的時候對異常進行處理,或者向上拋出或者直接捕獲以后進行處理
運行時異常一般是在程序運行過程中發生的異常,比如空指針異常等。
java中會存在內存泄露嗎?請簡單描述。
Java中會存在內存泄漏
內存泄漏是指系統存在無法回收的內存,有時候會造成內存不足或者系統崩潰,
Java中的內存泄漏指的是:存在無用但是垃圾回收器無法回收的對象
而且即使有內存泄漏問題存在,也不一定會表現出來。
談談java跟你所知道的其它的語言相比,有什么優點??
1、Java是純面向對象的語言。《Java編程思想》中提到Java語言是一種“Everything is object”的語言,它能夠直接反映現實生活中的對象,例如車、動物等,因此通過它編寫程序更容易。
2、平台無關性。Java語言可以“一次編譯,到處執行”。無論是在Windows平台還是在Linux、MacOS等其他平台上對Java程序進行編譯,編譯后的程序在其他平台上都可以運行。由於Java是解釋性語言,編譯器會將Java代碼變成“中間代碼”,然后在Java虛擬機(Java Virtual Machine,JVM)上解釋執行。由於中間代碼與平台無關,因此Java語言可以很好的跨平台執行,具有很好的可移植性。
3、Java提供了很多內置的類庫,通過這些類庫,簡化了開發人員的程序設計工作,同時縮短了項目的開發時間,
4、提供了對Web應用開發的支持。例如,Applet、Servlet和JSP可以用來開發Web應用程序;Socket、RMI可以用來開發分布式應用程序。
5、具有較好的安全性和健壯性。Java語言經常被用在網絡環境中,為了增強程序的安全性,Java語言提供了一個防止惡意代碼攻擊的安全機制(數組邊界檢測和Bytecode校驗等)。Java的強類型機制、垃圾回收器、異常處理和安全檢查機制使得用Java語言編寫的程序具有很好的健壯性。
6、去除了C++語言中難以理解、容易混淆的特性,如頭文件、指針、結構、單元、運算符重載、虛擬基礎類、多重繼承等,使得程序更加嚴謹簡潔。
談談你對面向對象的理解??
有了基本數據類型,為什么還需要包裝類型?
我們知道Java是一個面相對象的編程語言,基本類型並不具有對象的性質,為了讓基本類型也具有對象的特征,就出現了包裝類型(如我們在使用集合類型Collection時就一定要使用包裝類型而非基本類型),它相當於將基本類型“包裝起來”,使得它具有了對象的性質,並且為其添加了屬性和方法,豐富了基本類型的操作。
另外,當需要往ArrayList,HashMap中放東西時,像int,double這種基本類型是放不進去的,因為容器都是裝object的,這是就需要這些基本類型的包裝器類了。
說一下"=="和equals方法究竟有什么區別?
直接使用 == 符號比較的就是值是否相等.地址值也要相等.
當比較的類型是基本類型的時候,比較的就是值是否相等
當比較的類型是引用類型的時候,比較的就是對象的地址值
如果想要比較對象的屬性值是否相等,那么就需要重寫equals方法.
通過重寫equals方法就可以實現對對象的屬性的比較啦,只要屬性值一樣,則比較結果為true.
String ,StringBuilder, StringBuffer的區別
- 首先說運行速度,或者說是執行速度,在這方面運行速度快慢為:StringBuilder > StringBuffer > String
- 再來說線程安全,在線程安全上,StringBuilder是線程不安全的,而StringBuffer是線程安全的
- 數據可變和不可變
String
底層使用一個不可變的字符數組private final char value[];
所以它內容不可變。StringBuffer
和StringBuilder
都繼承了AbstractStringBuilder
底層使用的是可變字符數組:char[] value;
講一下Java中的集合
- Collection下:List系(有序、元素允許重復)和Set系(無序、元素不重復)
set根據equals和hashcode判斷,一個對象要存儲在Set中,必須重寫equals和hashCode方法
-
Map下:HashMap線程不同步;ConcurrentMap線程同步
-
Collection系列和Map系列:Map是對Collection的補充,兩個沒什么關系
ArrayList和LinkedList區別?
- arraylist 集合是有序的,有索引的,元素可以重復的,linkedlist集合是無序的,無索引的,元素不可以重復的
- arraylist底層采用數組的數據結構實現,而linkedlist底層采用鏈表的形式實現。
- 在進行查詢操作的時候,arraylist的效率高,因為linkedlist要移動指針
- 在對集合中的元素進行增刪操作時,linkedlist的效率高,因為arraylist要移動數據
線程創建方式
方法一 繼承Thread類
方法二 實現runable接口
方法三 通過線程池的方式
方法四 實現callable接口
方法五 通過匿名內部類的方式
String s = "hello"和String s = new String("hello");有啥區別,創建了幾個對象?
答案: 一個或者兩個
String s = new String("hello");
可能創建兩個對象也可能創建一個對象。如果常量池中有hello
字符串常量的話,則僅僅在堆中創建一個對象。如果常量池中沒有hello
對象,則堆上和常量池都需要創建。
String s = "hello"
這樣創建的對象,JVM會直接檢查字符串常量池是否已有"hello"字符串對象,如沒有,就分配一個內存存放"hello",如有了,則直接將字符串常量池中的地址返回給棧。(沒有new,沒有堆的操作)
引用類型是占用幾個字節?
hotspot在64位平台上,占8個字節,在32位平台上占4個字節。
兩個對象equals為true,則hashCode也一定相同,對嗎?
答案:如果按照官方設計要求來打代碼的話,hashcode一定相等。但是如果不按官方照設計要求、不重寫hashcode方法,就會出現不相等的情況。
兩個對象的hashCode相同,則equals也一定為true,對嗎?
答案:不對 因為 重寫hashCode的時候
@Override
public int hashCode(){
return 1;
}
某些java類為什么要實現Serializable接口
為了能夠實現序列化操作,在網路上傳輸數據或者持久化數據,保證數據的安全
除了實現Serializable接口還有什么序列化方式
- Json序列化
- FastJson序列化
- ProtoBuff序列化
面向對象六大原則
單一職責原則
開放封閉原則
里氏替換原則
依賴倒置原則
接口分離原則
迪米特法則
如何將字符串反轉?
- 通過 charAt(int index)返回char值進行字符串拼接
- 調用StringBuffer中的reverse方法
Collection 和 Collections 有什么區別?
-
Collection 是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。Collection接口在Java 類庫中有很多具體的實現。Collection接口的意義是為各種具體的集合提供了最大化的統一操作方式。
-
Collections 是一個包裝類,它包含有各種有關集合操作的靜態多態方法。此類不能實例化,就像一個工具類,服務於Java的Collection框架。
Java集合類中的Iterator和ListIterator的區別
對List來說,你也可以通過listIterator()取得其迭代器,兩種迭代器在有些時候是不能通用的,Iterator和ListIterator主要區別在以下方面:
-
iterator()方法在set和list接口中都有定義,但是ListIterator()僅存在於list接口中(或實現類中);
-
ListIterator有add()方法,可以向List中添加對象,而Iterator不能
-
ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向后遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。Iterator就不可以。
-
ListIterator可以定位當前的索引位置,nextIndex()和previousIndex()可以實現。Iterator沒有此功能。
-
都可實現刪除對象,但是ListIterator可以實現對象的修改,set()方法可以實現。Iierator僅能遍歷,不能修改。
sleep() 和 wait() 有什么區別?
- 對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。
- sleep()方法導致了程序暫停執行指定的時間,但是他的監控狀態依然保持,當指定的時間到了又會自動恢復運行狀態。在調用sleep()方法的過程中,線程不會釋放對象鎖。
- 而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法后本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
notify 和 notifyAll 區別
notify 僅僅通知一個線程,並且我們不知道哪個線程會收到通知,然而 notifyAll 會通知所有等待中的線程。換言之,如果只有一個線程在等待一個信號燈,notify和notifyAll都會通知到這個線程。但如果多個線程在等待這個信號燈,那么notify只會通知到其中一個,而其它線程並不會收到任何通知,而notifyAll會喚醒所有等待中的線程。
線程中start()和run()的區別
-
每個線程都有要執行的任務。線程的任務處理邏輯可以在Tread類的run實例方法中直接實現或通過該方法進行調用,因此run()相當於線程的任務處理邏輯的入口方法,它由Java虛擬機在運行相應線程時直接調用,而不是由應用代碼進行調用。
-
而start()的作用是啟動相應的線程。啟動一個線程實際是請求Java虛擬機運行相應的線程,而這個線程何時能夠運行是由線程調度器決定的。start()調用結束並不表示相應線程已經開始運行,這個線程可能稍后運行,也可能永遠也不會運行。
迭代器的優點
如果用的是for循環,就用集合自帶的remove(),而這樣就改變了集合的Size(),循環的時候會出錯。但如果把集合放入迭代器,既iterator迭代可以遍歷並選擇集合中的每個對象而不改變集合的結構,把集合放入迭代器,用迭代器的remove()就不會出現問題。
線程池中 submit()和 execute()方法有什么區別?
-
execute(Runnable x) 沒有返回值。可以執行任務,但無法判斷任務是否成功完成。——實現Runnable接口
-
submit(Runnable x) 返回一個future。可以用這個future來判斷任務是否成功完成。——實現Callable接口
描述Servlet調用過程?
答案:
(1)在瀏覽器輸入地址,瀏覽器先去查找hosts文件,將主機名翻譯為ip地址,如果找不到就再去查詢dns服務器將主機名翻譯成ip地址。
(2)瀏覽器根據ip地址和端口號訪問服務器,組織http請求信息發送給服務器。
(3)服務器收到請求后首先根據Host請求頭判斷當前訪問的是哪台虛擬主機。
(4)服務器根據http請求頭中的請求URI判斷當前訪問的是哪個web應用。
(5)服務器根據http請求頭中的請求URI判斷當前訪問的是web應用中的哪個web資源。
(6)檢查web應用的web.xml文件,如果根據路徑找到具體的servlet處理類的全路徑名交給該servlet處理,如果找不到就交給缺省servlet處理。
(7)這個過程中瀏覽器只知道自己發出來http請求,不久就收到了http響應,瀏覽器不知道也不關心服務器內部是如何處理的。瀏覽器和服務器之間的關系是非常單純的,只有HTTP協議。
(8)解析請求、封裝RequestResponse對象、創建Servlet、調用Service方法都是服務器自動進行的,開發人員只需要寫好Servlet配置進容器中即可,無需操心具體的底層實現。
簡述Servlet生命周期?
答案:
(1)Servlet第一次被訪問到時創建對象,創建出來后立即執行init方法執行初始化的操作。
(2)從此以后該對象一直駐留在內存中為后續的對這個Servlet的請求進行服務。
(3)直到服務器關閉或web應用移除出容器時,隨着web應用的銷毀Servlet對象銷毀掉,在銷毀之前調用destory方法執行善后工作。
(4)在存活期間,每次對Servlet 的調用都會導致Service方法的執行。
什么是http協議?
答案:
HTTP協議就是一套基於tcp/ip協議的應用層協議 。簡單來說,就是一個基於應用層的通信規范,雙方要進行通信,大家都要遵守一個規范,這個規范就是HTTP協議。它規定了客戶端(通常是瀏覽器)和服務器之間的通信方式。
HTTP協議工作原理?
答案:
HTTP協議基於請求響應模型。
一次請求對應一次響應。
首先客戶端發送一個請求(request)給服務器,服務器在接收到這個請求后將生成一個響應(response)返回給客戶端。
HTTP協議的特點是什么 ?
答案:
(1) 它是一個無狀態的協議,服務器端在處理相應請求后不會保留任何客戶端的信息,每次請求都是獨立的
(2) 客戶端與服務器端的每一次數據交互,都要經過一次請求/響應的過程。
(3) 服務器端無法識別能夠出發客戶端請求的方法。
(4) 一個典型的HTTP請求分為 一個請求行 若干請求頭 一個空行 實體內容。
get和post請求的區別?
答案:
(1) get請求用來從服務器上獲得資源,而post是用來向服務器提交數據;
(2) get將表單中數據按照name=value的形式,添加到action 所指向的URL 后面,並且兩者使用"?"連接,而各個變量之間使用"&"連接;post是將表單中的數據放在HTTP協議的請求頭或消息體中,傳遞到action所指向URL;
(3) get傳輸的數據要受到URL長度限制(1024字節);而post可以傳輸大量的數據, POST數據是沒有限制的,上傳文件通常要使用post方式;
(4) 使用get時參數會顯示在地址欄上,如果這些數據不是敏感數據,那么可以使用get;對於敏感數據還是應用使用post;
(5) get使用MIME類型application/x-www-form-urlencoded的URL編碼(也叫百分號編碼)文本的格式傳遞參數,保證被傳送的參數由遵循規范的文本組成,例如一個空格的編碼是"%20"。
(6) Jsp頁面中的FORM標簽里的method屬性為get時調用doGet(),為post時調用doPost()。
請求亂碼產生的原因?
答案:
瀏覽器用什么碼表來打開表單頁面就用什么編碼來發送數據。當前我們的注冊頁面指定了用utf-8來打開。
這就決定了瀏覽器是用utf-8打開的頁面,瀏覽器在提交表單時是用utf-8編碼的。
而tomcat默認情況下會使用iso8859-1來進行解碼。
我們知道全世界的碼表都兼容iso8859-1,所以英文處理是沒有問題的。
但是iso8859-1中並沒有中文,iso8859-1對於無法處理的字節都使用?替代,所以我們看到的都是?。
如何來處理get請求產生的亂碼?
答案:
由於客戶端發送時使用的是utf-8編碼而服務器用iso8859-1解碼造成了亂碼,雖然字符已經亂掉了,但底層的字節仍然是正確的,我們只要將亂碼字符getBytes(“iso8859-1”)轉換為字節,就是正確的字節,再將這些字節new String(bytes,“utf-8”)按照正確的碼表編碼,就可以轉換回正確的字符了。從而解決了亂碼。
Request生命周期
答案:
request對象的生命周期是針對一個客戶端(一個瀏覽器應用程序)的一次請求,當請求完畢之后,request里邊的內容也將被釋放,一個請求開始時創建,請求結束后銷毀。
如何處理響應亂碼?
答案:
通過response.setHeader("Content-Type", "text/html;charset=utf-8")方法,通知服務器發送數據時的碼表;通過response.setCharacterEncoding("utf-8")方法,通知瀏覽器解析時使用的碼表。兩碼相同就不會有亂碼了。
response提供了setContentType("text/html;charset=UTF-8")快捷方法,在它的底層,會同時做上面兩件事,所以可以一行代碼解決response產生的亂碼問題。
簡述ServletContext生命周期?
答案:
ServletContext對象代表當前web應用。當服務器啟動時,服務器在啟動時會依次加載web應用,每一個web應用加載完成后都會創建一個ServletContext對象唯一代表該web應用,這個對象一直存活,直到web應用移除出容器或服務器關閉時,隨着應用銷毀,ServletContext對象跟着銷毀。
轉發與重定向的比較?
答案:
轉發是服務器內部資源跳轉,重定向是通過302+Location實現瀏覽器跳轉訪問。
轉發一次請求一次響應,重定向兩次請求兩次響應。
轉發地址欄不發生變化,重定向地址欄會發生變化。
轉發之前和轉發之后request是一個,重定向之前和之后不是一個request。
Session生命周期?
答案:
當程序第一次調用到request.getSession()代碼時,服務器明確的知道了需要用到session了,此時創建session。
如果session超過30分鍾(可以在web.xml中配置的)沒人使用,服務器認為這個session超時了,銷毀session。
明確的調用session.invalidate(),session立即銷毀。
服務器被非正常關閉或web應用被移除出容器,此時隨着web應用的銷毀session銷毀.如果是正常關閉,session會被鈍化.當下次服務器正常啟動時,沒有超時的session還會被活化回來。
session的原理?
答案:
session的原理:在服務器第一次調用request.getSession()方法的時候,會在內存中創建一個session對象,此對象具有一個獨一無二的id值,此id值將會以cookie(JSESSIONID)的形式發送給瀏覽器,瀏覽器以后每次訪問都會帶着此cookie,服務器就利用此cookie區分瀏覽器找到對應的session空間。
1.15. cookie與session的區別
答案:
cookie數據存放在客戶的瀏覽器上,session數據放在服務器上
cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙,考慮到安全應當使用session
session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用COOKIE
JSP和Servlet是什么關系?
答案:
其實這個問題在上面已經闡述過了,Servlet是一個特殊的Java程序,它運行於服務器的JVM中,能夠依靠服務器的支持向瀏覽器提供顯示內容。JSP本質上是Servlet的一種簡易形式,JSP會被服務器處理成一個類似於Servlet的Java程序,可以簡化頁面內容的生成。Servlet和JSP最主要的不同點在於,Servlet的應用邏輯是在Java文件中,並且完全從表示層中的HTML分離開來。而JSP的情況是Java和HTML可以組合成一個擴展名為.jsp的文件。有人說,Servlet就是在Java中寫HTML,而JSP就是在HTML中寫Java代碼,當然這個說法是很片面且不夠准確的。JSP側重於視圖,Servlet更側重於控制邏輯,在MVC架構模式中,JSP JSP有哪些內置對象?作用分別是什么?
JSP有9個內置對象:
- request:封裝客戶端的請求,其中包含來自GET或POST請求的參數;
- response:封裝服務器對客戶端的響應;
- pageContext:通過該對象可以獲取其他對象;
- session:封裝用戶會話的對象;
- application:封裝服務器運行環境的對象;
- out:輸出服務器響應的輸出流對象;
- config:Web應用的配置對象;
- page:JSP頁面本身(相當於Java程序中的this);
- exception:封裝頁H 面拋出異常的對象。
JSP的九大隱式對象是哪九個
答案:
1:request: 請求對象 在javax.servlet.ServletRequest 作用域為Request來自客服端的請求,如:FORM表單中填寫的信息,常用的方法有getParameter,getParamterName 和getParamterValue通過表用獲取請求對象中包含的參數值。
2:response表示客服端的響應。
3:pageContext對象為頁面的上下文對象,代表當請運行頁面的一些屬性。
4:session:對象代碼服務器與客服端所建立的會話,比如在寫購物,客服軌跡跟蹤,
session”是建立在cookie的基礎之上的。常用方法有getId,getValues等。
5:application對象負責提供應用程序在服務端運行時的一些全局信息,方法有getMimeType等。
6:out:與response不同,通過out對象發送的內容是瀏覽器需要的顯示內容,還可以直接想客服端編寫一個有程序動態生成的HTML的文件。
7:page:page里的變量沒法從index.jsp傳遞到test.jsp。只要頁面跳轉了,就不見了。
8: exception:他是一個列外的對象,當頁面發生了列外,就會會創建該對象。
9:config:是在servlet初始化Servlet的時候,JSP引擎向他傳遞信息用的,此消息包括Servlet初始化時所需要的參數。
如何防止SQL注入攻擊呢?
答案:
SQL注入:就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意)的SQL命令注入到后台數據庫引擎執行的能力,它可以通過在Web表單中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。
防止的方法:
(1) 永遠不要信任用戶的輸入,要對用戶的輸入進行校驗,可以通過正則表達式,或限制長度,對單引號和雙"-"進行轉換等。
(2) 永遠不要使用動態拼裝SQL,可以使用參數化的SQL或者直接使用存儲過程進行數據查詢存取。
(3) 永遠不要使用管理員權限的數據庫連接,為每個應用使用單獨的權限有限的數據庫連接。
(4) 不要把機密信息明文存放,請加密或者hash掉密碼和敏感的信息。
(5) 應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝,把異常信息存放在獨立的表中。
Mysql數據庫優化
答案:
(1)查詢時,能不用* 就不用,盡量寫全字段名。
(2)索引不是越多越好,每個表控制在6個索引以內。范圍where條件的情況下,索引不起作用,比如where value<100
(3)大部分情況連接效率遠大於子查詢,但是有例外。當你對連接查詢的效率都感到不能接受的時候可以試試用子查詢,雖然大部分情況下你會更失望,但總有碰到驚喜的時候不是么...
(4)多用explain 和 profile分析查詢語句
(5)有時候可以1條大的SQL可以分成幾個小SQL順序執行,分了吧,速度會快很多。
(6)每隔一段時間用alter table table_name engine=innodb;優化表
(7)連接時注意:小表 jion 大表的原則
(8)學會用explain 和 profile判斷是什么原因使你的SQL慢
(9)查看慢查詢日志,找出執行時間長的SQL進行優化
(10)盡量避免使用order by
(11)因為where子句后面的條件是執行順序是從右到左,所以盡量把能過濾掉大部分數據的條件放在最后
Filter 的作用是什么?
答案:
init為初始化方法,在Filter對象被創建出來時,Servlet容器會調用該方法對filter進行初始化。
destory為銷毀的方法,在過濾器對象被銷毀之前,服務器會調用這個方法執行善后工作。
doFilter為過濾器中最核心的方法,對訪問的請求和響應進行攔截,當過濾器攔截到對資源的訪問時,服務器會自動調用該方法執行過濾代碼。 我們只需要在這個方法中設計過濾器的邏輯代碼即可。
Filter的生命周期?
答案:
當服務器啟動,web應用加載后,立即創建出這個web應用中的所有過濾器對象,創建出來后立即調用過濾器的init方法執行初始化操作.從此這些過濾器對象駐留在內存中為后續的攔截進行服務.每當攔截到資源時,都會導致dofilter方法執行.最終直到服務器關閉或web應用移除出容器時,隨着web應用的銷毀,過濾器對象銷毀,銷毀之前調用destory方法執行善后工作。
1.22. 什么是數據庫連接池及其工作原理
答案:
對於共享資源,有一個很著名的設計模式:資源池(resource pool)。該模式正是為了解決資源的頻繁分配﹑釋放所造成的問題。為解決上述問題,可以采用數據庫連接池技術。數據庫連接池的基本思想就是為數據庫連接建立一個“緩沖池”。預先在緩沖池中放入一定數量的連接,當需要建立數據庫連接時,只需從“緩沖池”中取出一個,使用完畢之后再放回去。我們可以通過設定連接池最大連接數來防止系統無盡的與數據庫連接。更為重要的是我們可以通過連接池的管理機制監視數據庫的連接的數量﹑使用情況,為系統開發﹑測試及性能調整提供依據。
1.23. 如何自己實現一個數據庫連接池
答案:
思路如下:
1:利用class實現DataSource接口
2:在class的構造器一次性創建指定的鏈接,將鏈接保存LinkedList中
3:實現getConnection從LinkedList返回一個鏈接
4:提供將鏈接放回方法
Public class MyDataSource inplements DataSource{
Private LinkedList<Connection> dataSource=new LinkedList<>();
Public MyDataSource(){
For( int a=0;a<1000;a++){
Try{
DriverManager.registerDriver(new SQLServerDriver());
Connection con=DriverManager.getConnection(“jdbc:sqlserver://localhost:3306;DatabaseName=liming”,”root”,”liming”
}catch(Exception e){
}
}
Public Connection getConnetion(){
FinalConnection conn=dataSource.removeFirst();
}
Public void releasConnection(Connection conn){
dataSource.add(conn);
}
}
}
http和https的區別?
答案:
HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,為了保證這些隱私數據能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。
Servlet的單例問題
答案:
Servlet是一個供其他java程序調用的類,它不能獨立運行,針對客戶端的多次請求,通常狀況下,Servlet只會創建一個Servlet實例對象,一旦創建它就會駐留在內存中,為后續的請求提供服務,直至退出web應用為止,也就是當我們關閉了瀏覽器之后我們的Servlet就終止了。
當Servlet第一次訪問的時候,就被加載到內存中,以后該實例對各個請求服務,沒次情況會調用一次service方法。
這樣會出現什么問題:因為Servlet是單例的,所以會出現線程安全問題
"" 和 null的區別
答案:
如果說str是null,那么內存根本沒創建字符串對像,並由str引用。不能調用object的方法。
如果說str是空串,那么確實存在一個由str引用的字符串對像,只不過這個字符串的值是""。長度為0;
在獲取請求參數的時候為什么要這樣判斷呢?
if(null==str || "".equals(str)){
return "不合法參數";
}
如果我們在表單中什么都不填 接收到的字符串就是null;
如果我們在表單中填“”,接受到的字符串是“”,但是存入數據庫后,查詢出來的就是null;
Servlet的多線程同步問題
答案:
Servlet本身是單實例的,這樣當有多個用戶同時訪問某個Servlet時,會訪問該唯一的Servlet實例中的成員變量,如果對成員變量進行寫入操作,那就會導致Servlet的多線程問題,即數據不一致。
1.解決Servlet多線程同步問題的最好方式:去除實例變量,使用局部變量。
不使用成員變量,而使用局部變量,因為局部變量在每個線程中都有各自的實例。
所以對Servlet來說,如果要對某個變量做寫入操作,一定不要使用成員變量,而要使用局部變量。
2.使用同步代碼塊
synchronized{}
3.Servlet實現javax.serlvet.SingleThreadModel,Servlet2.4中已經廢棄了該接口,此時Servlet容器將保證Servlet實例以單線程方式運行,也就是說,同一時刻,只會有一個線程執行Servlet的service()方法。
request.getParameter()和request.getAttribute()的區別?
答案:
a、request.getParameter()獲取的類型是String;
request.getAttribute()獲取的類型是Object
b、request.getPrameter()獲取的是POST/GET傳遞的參數值和URL中的參數;
request.getAttribute()獲取的是對象容器中的數據值/對象
c、request.setAttribute()和request.getAttribute()可以發送、接收對象;
request.getParamter()只能接收字符串,官方不開放request.setParamter()(也就是沒有這個方法)
setAttribute()和getAttribute()的傳參原理:
setAttribute()是應用服務器把這個對象放在該頁面所對應的一塊內存中去,當你的頁面服務器重定向到另外一個頁面時,
應用服務器會把這塊內存拷貝到另一個頁面所對應的那塊內存中。這個就可以通過getAttribute()獲取到相應的參數值或者對象。
JSP中動態include和靜態include的區別?
答案:
a、靜態include:語法:<%@ include file="文件名" %>,相當於復制,編輯時將對應的文件包含進來,當內容變化時,不會再一次對其編譯,不易維護。
b、動態include:語法:<jsp:include page="文件名">,能夠自動檢查被包含文件,當客戶端對JSP文件進行請求時,會重新將對應的文件包含進來,進行實時的更新。
詳細描述MVC。
答案:
基於java的web應用系統采用MVC設計模型,即用Model(模型)、View(視圖)和Controller(控制)分離設計,這是目前web應用服務系統的主流設置方向。
Model:處理業務邏輯的模塊。
View:負責頁面顯示,顯示Model的處理結果給用戶,主要實現數據到頁面的轉換過程。
Controller:負責每個請求的分發,把Form數據傳遞給Model進行處理,處理完成后,把處理結果返回給相應的View顯示給用戶。
EL表達式的功能,為什么要用EL表達式?(Expression Language)
答案:
功能:
a、從四個域對象中取出數據數據顯示。
b、取出請求參數數據顯示。
原因:
在頁面中用jsp腳本和jsp表達式來獲取數據顯示比較麻煩
a、需要判斷
b、可能需要強轉
如何防止表單重復提交?
答案:
使用session技術:
a、在jsp頁面中生成一個為一個隨機值,將其保存到session中,同時將其保存為表單的隱藏域的值。
b、在處理注冊的請求時,獲取session中的值,獲取請求參數的值,比較兩者是否相同,如果相同說明不是重復提交,請求通過同時刪除session中保存的的值,如果不相同則是重復提交,不能通過。
在數據庫添加唯一字段
在數據庫建表的時候在ID字段添加主鍵約束,賬號,名稱的信息添加唯一性約束。確保數據庫只可以添加一條數據。
什么是web容器?
答案:
給處於其中的應用程序組件(JSP、Servlet)提供一個環境,是JSP、Servlet直接跟容器中的變量交互,不必關注其他系統問題。
主要有web服務器來實現。例如:tomcat、weblogic、sphere、JBoss等。該容器提供的接口嚴格遵守J2EE規范中的web application標准。
我們把遵守以上標准的web服務器叫做J2EE的web容器。
J2EE常用的設計模式?說明工廠模式。
答案:
Java中一共有23中設計模式:
Factory(工廠模式)、Builder(建造模式)、Factory Method(工廠方法模式)、ProtoType(原始模型模式)、Singleton(單例模式)、
Facade(門面模式)、Adapter(適配器模式)、Bridge(橋梁模式)、Composite(合成模式)、Decorator(裝飾模式)、
FlyWeight(享元模式)、Proxy(代理模式)、Command(命令模式)、Interpreter(解釋器模式)、Visitor(訪問者模式)、
Iterator(迭代子模式)、Mediator(調停者模式)、Memento(備忘錄模式)、Observer(觀察者模式)、State(狀態模式)、
Strategy(策略模式)、Template Method(模板方法模式)、Chain Of Responsibility(責任鏈模式)、
工廠模式:工廠模式是一種經常被使用到的模式,根據工廠模式實現的類可以根據提供的數據生成一組類中某個類的實例,通常一組類中有一個公共的抽象父類並且實現了相同的方法,但是這些方法針對不同的數據進行了不同的操作。首先需要定義一個基類,該類的子類通過不同的方法實現了基類中的方法。然后定義一個工廠類,工廠類可以根據條件生成不同的子類實例。當得到子類的實例后,開發人員可以調用基類中的方法而不必考慮到底返回的是哪一個子類的實例。
什么是事務?
答案:
事務時作為一個邏輯單元執行的一系列操作,一個邏輯工作單元必須有四個屬性,稱為ACID(原子性、一致性、隔離性和持久性)屬性,
只有這樣才能成為一個事務:
原子性:事務必須是原子工作單元,對於其數據修改,要么全都執行,要么全都不執行。
一致性:事務在完成時,必須使所有的數據保持一致的狀態。在相關數據庫中,所有規則都必須應用於事務的修改,以保持所有數據的完整性。事務結束時,所有的內部數據結構(如B樹索引或雙向鏈表)都必須是正確的。
隔離性:由並發事務所做的修改必須與任何其他並發事務所做的修改隔離。事務查看數據時數據所處的狀態,要么是另一並發事務修改它之前
的狀態,要么是另一並發事務修改它之后的狀態,事務不會查看中間狀態的數據。這稱為可串行性,因為它能夠重新裝載起始數據,並且重播
一系列事務,以使數據結束時的狀態與原始事務執行的狀態相同。
持久性:事務完成后,它對於系統的影響是永久性的。該修改即使出現系統故障也將一直保持。
數據庫有幾種隔離級別?
答案:
1、Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生
2、Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。
3、Read committed (讀已提交):可避免臟讀的發生。
4、Read uncommitted (讀未提交):最低級別,任何情況都無法保證
簡述web.xml的作用
答案:
屬於部署描述符,在整個JAVA中只要是容器都會存在部署描述符,此部署描述符可以控制整個WEB中各個組件的運行狀態,也可以配置整個窗口的狀態
sql優化:(索引、范式)
答案:
三范式:
第一范式(確保每列保持原子性)最基本范式。數據庫表中所有字段值都是不可分解的原子值,就滿足了第一范式。
第二范式(確保表中的每列都和主鍵相關)在第一范式上更近一層。確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關,也就是說一個表中只能保存一種數據,不可以吧多種數據保存在一張表中。
第三范式:確保每列都和主鍵列直接相關,不是間接相關。
索引:
避免對索引字段進行計算、避免索引在字段上使用not、<>、!=、避免在索引上使用IS NULL和NOT NULL、避免在索引列上出現數據類型轉換、避免索引字段使用函數、避免建立索引的列出現空值
Ajax原理
答案:
Ajax的工作原理相當於在用戶和服務器之間加了—個中間層,使用戶操作與服務器響應異步化。並不是所有的用戶請求都提交給服務器,像—些數據驗證和數據處理等都交給Ajax引擎自己來做, 只有確定需要從服務器讀取新數據時再由Ajax引擎代為向服務器提交請求。
Ajax其核心只有JavaScript、XMLHttpRequest和DOM,在舊的交互方式中,由用戶觸發一個HTTP請求到服務器,服務器對其進行處理后再返回一個新的HTML頁到客戶端, 每當服務器處理客戶端提交的請求時,客戶都只能空閑等待,並且哪怕只是一次很小的交互、只需從服務器端得到很簡單的一個數據,都要返回一個完整的HTML頁,而用戶每次都要浪費時間和帶寬去重新讀取整個頁面。而使用Ajax后用戶從感覺上幾乎所有的操作都會很快響應沒有頁面重載(白屏)的等待。
SQL注入攻擊
答案:
SQL注入是一種將SQL代碼添加到輸入參數中,傳遞到服務器解析並執行的一種攻擊手法。
SQL注入攻擊是輸入參數未經過濾,然后直接拼接到SQL語句當中解析,執行達到預想之外的一種行為,稱之為SQL注入攻擊。
如何防止SQL注入攻擊
答案:
利用新對象PreparedStatement對象完成,先將SQL骨架發送給數據庫服務器,然后再將參數單獨發給服務器,並將參數中的關鍵字當做一個普通字符串來處理,進而起到防止SQL注入的問題
對連接池的理解
答案:
用來提高程序的效率,創建一個容器,容器中存放已經獲取到了的數據庫連接對象,對外提供獲取連接和還回連接的方法,外界需要時就從容器中獲取,用完就還回容器中。
HTML和xml的區別?
答案:
XML是可擴展標記語言,而HTML超文本標記語言。不同之處:
1、語法有所不同。XML語法比較嚴謹而HTML語法比較松散。
2、用途不同。XML主要用於數據格式化存儲而HTML主要用於網頁的編輯。
在JS中== 和 ===的區別?
答案:
簡單來說: == 代表相同, ===代表嚴格相同, 為啥這么說呢,
這么理解: 當進行雙等號比較時候: 先檢查兩個操作數數據類型,如果相同, 則進行 ``=== 比較, 如果不同, 則願意為你進行一次類型轉換, 轉換成相同類型后再進行比較, 而
===`比較時, 如果類型不同,直接就是false.
操作數1 == 操作數2, 操作數1 === 操作數2
比較過程:
雙等號==:
(1)如果兩個值類型相同,再進行三個等號(===)的比較
(2)如果兩個值類型不同,也有可能相等,需根據以下規則進行類型轉換在比較:
1)如果一個是null,一個是undefined,那么相等
2)如果一個是字符串,一個是數值,把字符串轉換成數值之后再進行比較
三等號===:
(1)如果類型不同,就一定不相等
(2)如果兩個都是數值,並且是同一個值,那么相等;如果其中至少一個是NaN,那么不相等。(判斷一個值是否是NaN,只能使用isNaN( ) 來判斷)
(3)如果兩個都是字符串,每個位置的字符都一樣,那么相等,否則不相等。
(4)如果兩個值都是true,或是false,那么相等
(5)如果兩個值都引用同一個對象或是函數,那么相等,否則不相等
(6)如果兩個值都是null,或是undefined,那么相等
SQL優化
答案:
\1. SELECT子句中避免使用‘*’
\2. SQL語句用大寫的
\3. 用IN來替換OR
\4. 查詢語句中不要使用 *
\5. 盡量減少子查詢,使用關聯查詢(left join,right join,inner join)替代
\6. 減少使用IN或者NOT IN ,使用exists,not exists或者關聯查詢語句替代
\7. or 的查詢盡量用 union或者union all 代替
\8. 合理的增加冗余的字段(減少表的聯接查詢)
\9. 增加中間表進行優化(這個主要是在統計報表的場景,
Tomcat配置,部署優化
答案:
\1. 內存優化:Tomcat依賴於JVM,可以配置JVM的內存配置
\2. 最大連接數配置(並發能力)
通常搭配Nginx提升Tomcat的並發性能
自動刷新,定時刷新
答案:
自動刷新不僅可以實現一段時間之后自動跳轉到另一個頁面,還可以實現一段時間之后自動刷新本頁面。Servlet中通過HttpServletResponse對象設置Header屬性實現自動刷新例如:
Response.setHeader("Refresh","1000;URL=http://localhost:8080/servlet/example.htm");
其中1000為時間,單位為毫秒。URL指定就是要跳轉的頁面(如果設置自己的路徑,就會實現每過一秒自動刷新本頁面一次)
BS和CS的區別?
答案:
\1. C/S用戶固定,並且處於相同區域,要求擁有相同的操作系統。B/S要有操作系統和瀏覽器就行。與操作系統平台無關。
\2. C/S客戶端的計算機電腦配置要求較高。B/S客戶端的計算機電腦配置要求較低。
\3. C/S每一個客戶端都必須安裝和配置軟件,客戶端不必安裝,使用瀏覽器訪問,易推廣。B/S最大的優點就是可以在任何地方進行操作而不用安裝任何專門的軟件。
\4. C/S每一個客戶端都要升級程序。可以采用自動升級。BS客戶端不必安裝及維護。
\5. C/S一般面向相對固定的用戶群,程序更加注重流程,它可以對權限進行多層次校驗,提供了更安全的存取模式,對信息安全的控制能力很強。一般高度機密的信息系統采用C/S結構適宜。
說一下HTTP協議,它是哪一層的協議
HTTP協議就是一套基於tcp/ip協議的應用層協議 。簡單來說,就是一個基於應用層的通信規范,雙方要進行通信,大家都要遵守一個規范,這個規范就是HTTP協議。它規定了客戶端(通常是瀏覽器)和服務器之間的通信方式。
它的特點就是一次請求,一次響應。
響應狀態碼你知道哪些?
200 請求已成功,請求所希望的響應頭或數據體將隨此響應返回。出現此狀態碼是表示正常狀態。
404 找不到資源,一般是訪問路徑不對。
500 服務器端出現異常,不能正常響應。
302 請求重定向的時候響應此狀態碼。
400 請求參數有誤,一般是請求的參數不能解析。
網絡的七層協議,五層協議
七層是指OSI七層協議模型,主要是:應用層(Application)、表示層(Presentation)、會話層(Session)、傳輸層(Transport)、網絡層(Network)、數據鏈路層(Data Link)、物理層(Physical)。
五層體系結構包括:應用層、運輸層、網絡層、數據鏈路層和物理層。
ArrayList底層是怎樣的
-
存在於java.util包中。
-
內部用數組存放數據,封裝了數組的操作,每個對象都有下標。
-
內部數組默認初始容量是10。如果不夠會以1.5倍容量增長。
-
查詢快,增刪數據效率會降低。
LinkedList底層實現
LinkedList的底層是通過鏈表來實現的。鏈表是由多個節點構成,每個節點都包含三個部分,頭部指向上一個節點,中部指向該節點,尾部指向下一個節點。
在增刪數據的時候效率比較低
HashMap底層原理
HashMap底層是一個Entry數組,默認大小是16,當存放數據時,會根據hash算法計算出當前數據的位置,算法就是 hash(key)%n.n就是數組的長度,位置就是數組中每個對象所對應的下標。
當計算的位置沒有數據時,就直接存放,當計算的位置有數據的時候,也就是發生hash沖突的時候,那么就會采用鏈表的形式進行存儲,在對應的數組的位置存放鏈表的頭結點,對鏈表而言,新加入的結點會從頭結點接入。當鏈表的長度超過8時,會采用紅黑樹的形式進行存儲。
Object類有哪些方法
equals()
toString()
getClass();
hashCode();
wait();
String 字符常量池
String A=”123”;
String B=new String(“123”);
生成了幾個對象?答案:如果字符串常量池中原來沒有“123”,就生成了兩個對象;
如果原來有,就生成了一個對象。
數據的隔離級別有什么,舉個例子。
1、Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生
2、Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。
3、Read committed (讀已提交):可避免臟讀的發生。
4、Read uncommitted (讀未提交):最低級別,任何情況都無法保證
單例模式了解嗎?寫一個單例模式(建議幾種都寫出來)
單例模式可以說是大多數開發人員在實際中使用最多的,常見的Spring默認創建的bean就是單例模式的。單例模式有很多好處,比如可節約系統內存空間,控制資源的使用。其中單例模式最重要的是確保對象只有一個。簡單來說,保證一個類在內存中的對象就一個。
- 優點:
- 在內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例(比如管理學院首頁頁面緩存)。
- 避免對資源的多重占用(比如寫文件操作)。
- 缺點:
- 沒有接口,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎么樣來實例化。
JDK1.7和1.8的區別是什么?
- 在jdk1.8中取消了永久代,取而代之的是Metaspace,這個空間不占用jvm虛擬機的內存,而是占用物理機的內存
- 如果我們new的小對象,會進去新生代,二如果new的大對象的話,不會進入新生代而是直接進入老年代
線程有哪些狀態,你說一下吧
新建狀態、可運行狀態、運行狀態、終止狀態、阻塞狀態。
nginx是怎么把用戶請求均勻地分發到服務器的?
通過負載均衡實現
每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,能自動剔除。
怎么偵察到宕機的服務器?
通過心跳檢測機制。
是直連數據庫還是用的什么中間件去連接的數據庫?
使用中間件,例如mycat,通過數據庫代理服務器,可以對數據庫進行讀寫分離的配置。
支持讀寫分離,支持Mysql雙主多從,以及一主多從的模式
mybatis里的緩存你知道嗎?
一級緩存
默認開啟
SqlSession級別的緩存,實現在同一個會話中數據的共享
一級緩存的生命周期和SqlSession一致
當有多個SqlSession或者分布式環境下,數據庫寫操作會引起臟數據。
二級緩存
默認不開啟,需手動開啟
SqlSessionFactory級別的緩存,實現不同會話中數據的共享,是一個全局變量
可自定義存儲源,如Ehcache
當開啟緩存后,數據查詢的執行的流程是:二級緩存>一級緩存>數據庫
不同於一級緩存,二級緩存可設置是否允許刷新和刷新頻率實現
實體類實現序列化,在mapper文件中開啟 <cache>
在配置文件中設置cacheEnabled為true
mybatis加這么個緩存的目的是什么?
減少對數據庫直接的訪問頻率,減少對數據庫的訪問壓力。
java 的 Integer 和 int 有什么區別?
int 是 java 內置基本數據類型之一,java 為每個基本類型都提供了一個封裝類,Integer 就是 int 的封裝類(也叫包裝類型);int 變量的默認值為 0,Integer 變量的默認值為 null,所以 Integer 可以區分出未賦值和值為 0 的區別;Integer 類內部提供了一些關於整數操作的方法,例如上文用到的表示整數的最大值和最小值。
重載和重寫的是什么,規則是什么,有什么區別
重載(Overload)是讓類以統一的方式處理不同類型數據的一種手段,實質表現就是多個具有不同的參數個數或者類型的同名函數(返回值類型可隨意,不能以返回類型作為重載函數的區分標准)同時存在於同一個類中,是一個類中多態性的一種表現(調用方法時通過傳遞不同參數個數和參數類型來決定具體使用哪個方法的多態性)。
重寫(Override)是父類與子類之間的多態性,實質是對父類的函數進行重新定義,如果在子類中定義某方法與其父類有相同的名稱和參數則該方法被重寫,不過子類函數的訪問修飾權限不能小於父類的;若子類中的方法與父類中的某一方法具有相同的方法名、返回類型和參數表,則新方法將覆蓋原有的方法,如需父類中原有的方法則可使用 super 關鍵字。
重載規則:必須具有不同的參數列表;可以有不同的返回類型;可以有不同的訪問修飾符;可以拋出不同的異常。
重寫規則:參數列表必須完全與被重寫的方法相同,否則不能稱其為重寫而是重載;返回類型必須一直與被重寫的方法相同,否則不能稱其為重寫而是重載;訪問修飾符的限制一定要大於等於被重寫方法的訪問修飾符;重寫方法一定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常,譬如父類方法聲明了一個檢查異常IOException,在重寫這個方法時就不能拋出 Exception,只能拋出 IOException 的子類異常,可以拋出非檢查異常。
重載與重寫是 Java 多態性的不同表現,重寫是父類與子類之間多態性的表現,在運行時起作用(動態多態性,譬如實現動態綁定),而重載是一個類中多態性的表現,在編譯時起作用(靜態多態性,譬如實現靜態綁定)。
Java構造方法能否被重寫和重載
重寫是子類方法重寫父類的方法,重寫的方法名不變,而類的構造方法名必須與類名一致,假設父類的構造方法如果能夠被子類重寫則子類類名必須與父類類名一致才行,所以 Java 的構造方法是不能被重寫的。而重載是針對同一個的,所以構造方法可以被重載。
Java創建對象的方式有幾種?
常見的創建對象方式主要有 5 種,該題在某些場合下會變着法子問你除過 new 的方式外還可以怎么創建對象,答案都是一樣的,如下。
(1).使用 new 關鍵字(調用構造方法);
(2).使用 Class 類的 newInstance 方法(調用構造方法);
(3).使用 Constructor 類的 newInstance 方法(調用構造方法);
(4).使用 clone 方法(沒有調用構造方法);
(5).使用反序列化(沒有調用構造方法);
Java有哪些訪問修飾符?
Java 的訪問修飾符關鍵字主要有 public、protected、default、private 四個,其決定了緊跟其后被定義的東西可以被誰使用,具體的區別如下所示。
public 訪問權限為當前類、同一個包、同包子類、非同包子類、其他包都可用。
protect 訪問權限為當前類、同一個包、同包子類、非同包子類,其他包下無法訪問到。
default 訪問權限為當前類、同一個包,同包子類、其他包下和非同包子類無法訪問到。
private 訪問權限為當前類,同一個包、同包子類、非同包子類、其他包都無法訪問到。
說說 hashCode() 的返回值和 == 的關系?
若 == 返回 true 則兩邊對象的 hashCode() 返回值必須相等,若 == 返回 false 則兩邊對象的 hashCode() 返回值有可能相等,也有可能不等;因為在 Java 中對象默認的 equals 方法實現就是 == 比較,而Java 對於 eqauls 方法和 hashCode 方法的規定是如果兩個對象 equals 方法相等則它們的 hashCode 值一定要相同,如果兩個對象的 hashCode 相同則它們的 equals 方法並不一定相同,所以可得出上面結論。
什么是緩沖區?有什么作用?
緩沖區就是一段特殊的內存區,應對頻繁操作資源文件時效率變低的問題.
字節流和字符流哪個好?怎么選擇?
緩大多數情況下使用字節流會更好,因為字符流是字節流的包裝,而大多數時候 IO 操作都是直接操作磁盤文件,所以這些流在傳輸時都是以字節的方式進行的(圖片等都是按字節存儲的)。
而如果對於操作需要通過 IO 在內存中頻繁處理字符串的情況使用字符流會好些,因為字符流具備緩沖區,提高了性能。
jsp和servlet有哪些相同點和不同點,他們之間的聯系是什么
聯系:
JSP本質上就是Servlet,JSP經過編譯之后就變成了Servlet
區別:
(1).JSP注重的頁面展示,Servlet注重的是邏輯控制
(2).Servlet中沒有內置對象,JSP中有內置對象(Jsp中的內置對象都是必須通過HttpServletRequest對象,HttpServletResponse對象以及HttpServlet對象得到)
什么是Tomcat
Tomcat是一種web服務器,java編寫的web項目可以部署在上面,用戶在客戶端請求時,都是將請求發到Tomcat上,Tomcat在將請求發到對應的項目上
get和post請求的區別?
(1).get是用來從服務器上獲取數據,而post是用來向服務器傳遞數據
(2).get將表單中數據按照variable=value的形式,添加到action所指向的URL后面,並且兩者用"?"連接,變量之間用"&"連接;而post是將表單中的數據放在form的數據體中,按照變量與值對應的方式,傳遞到action所指定的URL。
(3).get是不安全的,因為在傳輸過程中,數據是被放在請求的URL中;而post的所有操作對用戶來說都是不可見的。
(4).get傳輸的數據量小,這主要因為受url長度限制;而post可以傳輸大量的數據,所有上傳文件只能用post提交。
(5).get限制form表單的數據集必須為ASCII字符;而post支持整個IS01 0646字符集。
(6).get是form表單的默認方法。
什么時候調用doGet()和doPost()?
默認情況是調用doGet()方法,JSP頁面中的Form表單的method屬性設置為post的時候,調用的為doPost()方法;為get的時候,調用deGet()方法。
轉發和重定向的區別
轉發是服務器行為,重定向是客戶端行為.
轉發:客戶端發送一次請求,得到一次響應,地址欄不會發生變化,屬於服務器內部資源的跳轉,只能在同一個WEB應用內部
重定向:客戶端發送兩次請求,得到兩次響應,通過302狀態碼和location響應頭就可以實現請求重定向,地址欄會發生變化,可以訪問不同WEB應用的資源.
什么是MVC?
基於java的web應用系統采用MVC設計模型,即用Model(模型)、View(視圖)和Controller(控制)分離設計,這是目前web應用服務系統的主流設置方向
Model:處理業務邏輯的模塊。
View:負責頁面顯示,顯示Model的處理結果給用戶,主要實現數據到頁面的轉換過程。
Controller:負責每個請求的分發,把Form數據傳遞給Model進行處理,處理完成后,把處理結果返回給相應的View顯示給用戶。
有幾種數據訪問沖突?
臟讀:讀取到其他事務未提交的數據
不可重復讀:一個事務提交的數據,可以被另一個事務立即讀取,可能發生與第一次查詢數據不一致
幻讀:讀取到已經被刪除的數據,讀取不到新插入的數據
Maven是什么?
是一個項目的統一管理構建工具,統一管理jar包和依賴
如何提高系統的性能(響應時間)?
A請求數據傳輸時間
提高帶寬
減少數據傳輸,壓縮數據大小,CDN服務(靜態資源就近部署訪問),添加緩存
B請求數據的處理時間
硬盤,CPU,內存
優化服務架構,數據處理算法
C響應數據的傳輸時間
D響應數據的渲染時間 DOM元素的設計
Mybatis是什么?(談談你對Mybatis框架的理解)
Mybatis是一個持久層的框架,主要負責解決數據持久化以及映射(ORM)操作,是對JDBC操作的封裝和簡化.(半自動的ORM框架,解決對象關系映射問題.如何理解ORM:實現對象以及對象關系的映射)