部分參考html
http://www.importnew.com/22083.html前端
面向對象的四個特徵java
抽象,封裝,繼承,多態ajax
抽象:能夠說他是把一類事務的共同特徵總結出構造工程包括數據抽象和行爲抽象,抽象只關心對象有哪些屬性和行爲正則表達式
封裝:封裝也就是說把客觀的事務分裝成抽象的類,而且類只讓本身可信的類進行訪問對不可信的類進行信息隱藏算法
繼承:只一個類的所用功能,不須要去從新編寫的狀況下對這些功能進行擴展,經過繼承建立的類爲子類,被繼承的類爲父類,繼承也就是從通常到特殊的過程。sql
多態:簡單的來講一樣的對象引用一樣的方法卻作了不一樣的事情數據庫
生活中多態的例子編程
打印機 打印機又能夠分爲彩色打印機和黑白打印機,那麼他們都是打印機可是實現的功能不同json
多態的體現形式
接口和接口的實現 類和類的繼承 重寫 重載
Java的基本數據類型
Byte,Shot,int,long,float,double,char,boolean
String屬於類類型 被Final修飾String類不能夠被繼承。
int 和 Integer 有什麼區別?
int 是基本類型32位長度的整數
Integer 是類類型,是int的封裝類
int和Integer之間能夠經過自動裝箱 自動拆箱 互相轉換
GET與POST區別
GET和POST都屬於HTTP的交互協議
傳值方面來講:GET傳遞消息時會將咱們的數據按照明文的形式去添加到URL地址中 GET方式提交的話數據信息會被瀏覽器緩存,而POST是將數據放在HTTP的消息體中。正由於這樣咱們的POST的安全性能就要高於GET
GET傳輸量小通常都會受限制,而POST傳輸量通常不受限制,但從執行效率上來講GET效率會高於POST
String StringBuffer StringBuilder區別
String是個常量因此對於每次+=賦值都會產生一個新的對象,StringBuffer和StringBuilder是都是可變的,當進行字符串拼接時都會採用Append方法,在原來的基礎上進行追加因此從性能上來講比String要好。
String適合少許的字符串進行操做
StringBuffer 適合多線程下對字符緩存區下對大量字符串進行操做
StringBuilder 適合單線程下對字符緩存區下對大量字符串進行操做
HashMap與Hashtable
HashMap能夠看作HashTable的一個輕量級的實現HashMap和HashTable都是Map下的一個接口區別在於HashMap是非線程安全的因此他容許鍵值爲空而HashTable是線程安全的因此他不容許鍵值爲空,從效率上來講HashMap的執行效率高於HashTable。HashTable繼承於Dictionary,而HashMap是JAVA2引進來的一個Map接口的實現。Hashtable的方法是被Synchronized修飾的,而HashMap不是,因此多個線程訪問Hashtable時,不須要本身爲它的方法實現同步,而HashMap 就必須爲之提供外同(Collections.synchronizedMap)。
ConcurrentHashMap固然能夠代替HashTable,可是HashTable提供更強的線程安全性。
HashMap原理實現
HashMap其實是一個數組和鏈表的結合體。
HashMap 在底層將 key-value 當成一個總體進行處理,這個總體就是一個 Entry 對象。HashMap 底層採用一個 Entry[] 數組來保存全部的 key-value 對,當須要存儲一個 Entry 對象時,會根據 hash 算法來決定其在數組中的存儲位置,在根據 equals 方法決定其在該數組位置上的鏈表中的存儲位置;當須要取出一個Entry 時,也會根據 hash 算法找到其在數組中的存儲位置,再根據 equals 方法從該位置上的鏈表中取出該Entry。
GET操做的原理就比較簡單,只須要根據key
的hashcode
算出元素在數組中的下標,以後遍歷Entry
對象鏈表,直到找到元素爲止。
構造器是否可以被重寫?
答:構造器不可以被繼承,所以不能被重寫,但能夠被重載。
解釋堆棧
棧裏面通常存放的變量,對象的引用,而堆裏面存放的是new出來的對象也就是對象的實例,還有構造器都是放在堆中。棧空間操做起來最快可是棧很小,那麼一般存放對象的堆空間理論上整個內存沒有被其餘的進程使用的空間或者是硬盤上的虛擬機內存均可以當作堆空間使用
堆會自動增長大小的,因此不須要指定大小,可是存取相對較慢
棧是固定大小的,而且是FILO 先入後出的順序,而且存取速度比較快
進程與線程
進程是具備必定獨立功能的程序,能夠說他是一個有關於某個集合上的一次運動,是操做系統進行資源分配和調度的一個獨立單位,線程能夠說是進程的一個實體,一個進程能夠擁有多個線程,是比進程更小的可以去獨立運行的基本單位。進程在執行時一般都會擁有獨立的內存單元。而線程之間能夠共享數據和內存,那麼對於多線程編程可以給用戶帶來更好的體驗,可是並非線程越多就越好,由於線程之間的切換可能會佔用大量的CPU的時間。
髒讀,不可重複讀,幻讀
髒讀:A事務讀取B事務還沒有提交數據並在此基礎上進行操做,而B事務執行回滾,那麼A事務讀取到的數據就是髒數據
不可重複讀:事務A從新讀取到過的數據,發現該數據已經被另外一個事務B修改過了
幻讀:事務A從新執行一個查詢,返回一系列符合條件的查詢的行,發現其中插入的數據被事務B提交的行
JVM加載Class文件的原理
Java中的類是有Java虛擬機中的類加載器和他的子類來實現的,Java的類加載器是Java的很重要的一個很重要的運行時組件,他負責在運行時查找和裝入類文件中的類,因爲Java的跨平臺性編譯後的Java源文件並非一個能夠直接運行的程序,而是多個類文件,那麼當咱們的Java的程序須要某個類時,Java的虛擬機就要確保這個類被加載,鏈接,而且初始化過。類加載是把類文件的數據讀取到內存中,Java虛擬機一般會去建立一個字節數組來去讀取類文件,而後去產生對應的類對象,這時類還不可用。當類加載以後就會進入鏈接階段,這一階段包括驗證,準備和解析,最後虛擬機會對類進行初始化
類的加載是由類加載器完成的,類加載器包括:根加載器,擴展加載器,系統自帶的加載器和用戶自定義的加載器,JAVA2開始那麼就採用了父類委託的機制(PDM),PDM可以更好的保證Java的安全性類加載器首先請求父類加載器加載,父類加載器無能爲力時才由其子類加載器自行加載。
數據類型轉換
字符串互轉基本數據類型
調用parseXXX(String)或者是ValueOf(String)便可返回相應的基本類型
抽象類和接口有什麼異同abstract / interface
抽象類和接口都不可以去被實例化,可是能夠定義接口的類型的引用,一個類若是繼承了抽象類和接口即必須都要去把他們的抽象方法所有實現.不然這個類必須繼續聲明爲抽象類,接口比抽象類更加的抽象,由於抽象類中能夠定義構造器,能夠有抽象的方法,能夠是Private,默認,protected,public,而接口中的成員都是public,接口中定義的成員變量實際上都是常量,有抽象方法的類必須聲明爲抽象類,而抽象類未必有抽象方法。
重載和重寫的區別,重載的方法可否根據返回類型的區分
方法的重載和重寫都是實現多態的方式,區別在於重載實現的是編譯時多態性,然後者實現的是運行時的多態性,重載發生同一個類中,同名的方法若是有不一樣的參數列表則視爲重載,重寫發生在子類與父類之間,重寫要求子類被重寫方法與父類有相同的返回類型,子類比父類重寫方法更好的訪問,不能比父類重寫方法聲明更多的異常,重載對返回類型沒有特殊的要求。
Java中會存在內存泄漏嗎?
理論上來講Java有GC的機制不會存在內存泄漏的問題,但在實際開發中可能會達到一種無用但可達的現象,這些對象不會被GC回收,所以也會致使內存泄漏,例如Hibernate的session緩存中對象屬於持久化狀態,那麼垃圾回收器不會去回收這些對象,然而這些對象就會存在無用的垃圾對象,若是不及時的關閉或者是清空,就可能致使內存泄漏。
GC是垃圾回收的意思,Java提供了自動回收的機制能夠自動的監測對象是否超過做用域歷來達到內存回收的效果。System.gc();
JSP9大隱式做用域對象
request:封裝客戶端的請求,包括GET/POST請求參數
response:封裝服務器對客戶端的一個響應;
pageContext:經過該對象能夠獲取其餘對象
session:封裝用戶會話對象
application:封裝服務器的運行環境
out:輸出服務器響應的輸出流的對象
config:WEB應用的配置對象
Page:JSP頁面自己
Exception:錯誤異常對象
JSP四大做用域
包括 Page,Request,Application,Session
做用域從大到小application--request--session--page
application全局做用域範圍,session會話做用域,request請求做用域,page一個JSP頁面
ForWard和Redirect區別
Forward是容器中的控制權的轉向,是服務器請求資源,服務器之間訪問目標地址URL,把那個響應的URL內容讀取出來而後再發送給瀏覽器,瀏覽器不知道這個地址從哪裏來因此地址仍是原來的那個地址,Redirect是服務器端根據邏輯發送一個狀態碼,告訴瀏覽器去請求那個地址,因此瀏覽器會去看到那個請求地址的連接地址,很明顯redirect沒法訪問到服務器保護起來的資源,可是能夠從一個網站轉跳到另外一個網站。可是我認爲forward更高效一點,由於經過調用getRequestDispatch()方法得到這樣的話有助於隱藏實際的地址,那麼在有些狀況下好比須要訪問一個其餘服務器上的資源就必須使用重定向。
定義文檔有幾種形式?本質區別在哪裏?解析XML文檔有哪幾種方式
XML文檔定義爲DTD和Schema兩種形式,均可以去對XML語法進行約束,其本質上的區別在於Schema自己也是XML文件,能夠被XML解析,並且能夠爲XML承載的數據定義類型,約束的能力比DTD大一些。
對XML主要有DOM,SAX,DOM解析方式必須在解析以前把整個文檔都裝入內存中適合對XML隨機訪問,SAX是事件驅動型的XML解析方式,SAX是按照順序去讀取,不須要一次性所有加載這個文件處理的方式會更加靈活一些
XML主要做用
XML主要做用有兩個方面:數據交互和信息配置,在作數據交互時,XML將數據用標籤組裝起來,而後壓縮打包加密後經過網絡傳輸傳給接收者,接收者解密後再從XML文件還原相關的配置信息。不過如今被JSON代替,固然目前不少軟件仍是在使用XML,咱們在作項目的時候也會將配置信息做爲硬代碼寫入在XML中
JSON一種輕量級的交互格式,他有助於建立一種自描述,獨立的,以輕的方式呈現交互數據,容易轉換成JavaScript(腳本語言)
XML和JSON相同點
都是數據傳輸的載體而且具備垮平臺語言的特性,區別在於XML的傳輸量比JSON要大。
實現會話跟蹤技術
因爲HTTP協議自己是無狀態的,服務器爲了區分不一樣的用戶,就須要對用戶的會話進行跟蹤,簡單的說爲了用戶進行登記,爲用戶分配一個惟一的ID,那麼用戶下一次用戶在請求中就會包含此ID,服務器就能夠去判斷究竟是哪個用戶
4種方式 cookie,session,Url重寫,設置隱藏域的表單
URL重寫:在URL中去添加用戶會話的信息做爲請求參數,或者是將惟一的會話ID添加到URL結尾以標識一個會話
設置隱藏域的表單:將和會話跟蹤相關的字段添加到表單中,這些信息不會在瀏覽器中顯示可是在提交表單的時候會提交給服務器
cookie:cookie有兩種會話cookie和持久化cookie,會話cookie的生命週期是和瀏覽器是一致的,瀏覽器關閉了那麼cookie中存儲的信息也就消失了,持久化cookie是將信息存儲到臨時文件夾中或者是硬盤中而且能夠設置一個保存的時間,當用戶與服務器創建一次鏈接會話後,會話ID的信息就會被記錄下來,那就意味着只要時間沒有超時那麼這個會話ID又會提交給服務器讓服務器識別身份。那麼cookie對於一些敏感的信息就不適合保存。cookie的容量有限一個cookie大概可以存放4k左右。
session:session與三種方式不一樣,session會把用戶的信息存儲到到服務器中,那麼從安全的性能上來講,session安全級別很是的高,可是不能存儲過多內容,那麼存儲過的信息就會勢必影響服務器的性能。session能夠經過調用getSession的方法獲取session的值經過session的setAttribute方法能夠將一個值放在session中,同時傳入屬性名既能夠獲取到保存在session中內容。
final finally finalize區別
- final:修飾符(關鍵字)有三種用法:若是一個類被聲明爲final,意味着它不能再派生出新的子類,即不能被繼承,所以它和abstract是反義詞。將變量聲明爲final,能夠保證它們在使用中不被改變,被聲明爲final的變量必須在聲明時給定初值,而在之後的引用中只能讀取不可修改。被聲明爲final的方法也一樣只能使用,不能在子類中被重寫。
- finally:一般放在try…catch…的後面構造老是執行代碼塊,這就意味着程序不管正常執行仍是發生異常,這裏的代碼只要JVM不關閉都能執行,能夠將釋放外部資源的代碼寫在finally塊中。
- finalize:Object類中定義的方法,Java中容許使用finalize()方法在垃圾收集器將對象從內存中清除出去以前作必要的清理工做。這個方法是由垃圾收集器在銷燬對象時調用的,經過重寫finalize()方法能夠整理系統資源或者執行其餘清理工做。
List,Set,Collection,Collections
List,Set都是Collection下的一個實現List是一個線性結構的容器而容許有重複的值 Set存儲的零散的元素且不容許有重複元素 Collections一個封裝了衆多工具類包括對容器的排序,搜索以及線程安全
ArrayList 和Vector都是使用數組方式存儲數據此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector中的方法因爲添加了synchronized修飾,所以Vector是線程安全的容器,但性能上較ArrayList差,LinkedList使用雙向鏈表實現存儲按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。
Ajax-
Ajax全稱是異步JavaScript及XML
工做原理:至關於在用戶和服務器加了一箇中間層,使用戶操做與服務器之間異步化並非全部的用戶請求到會發送到瀏覽器中去,好比數據驗證和數據的一些處理都是有Ajax本身去處理,只有肯定從服務器調用數據時,纔會去請求服務器讀取新數據由Ajax引擎提交請求。Ajax並非一個新的語言而是一種基於標準化的並被普遍支持的技術,使用Ajax能使咱們的程序不用重載頁面的狀況下去與服務器進行交互。也可使咱們客戶端和服務器之間使用異步傳輸的方式來進行HTTP的請求,請求少許信息減輕服務器壓力,提高網站的性能。
ajax出現請求跨域錯誤問題,主要緣由是由於瀏覽器的「同源策略」
解決問題
JSONP,CORS,代理請求的方式
在JS中,咱們直接用XMLHttpRequest請求不一樣域上的數據時,是不能夠的。可是,在頁面上引入不一樣域上的js腳本文件倒是能夠的,Jsonp正是利用這個特性來實現的。經過script標籤引入一個js文件,這個js文件載入成功後會執行咱們在url參數中指定的函數,而且會把咱們須要的json數據做爲參數傳入。因此jsonp是須要服務器端的頁面進行相應的配合的。
Error和Exception區別
Error是系統級別的錯誤和程序沒必要須處理的錯誤,通常發生了就不可逆的錯誤,好比說內存泄漏,線程死亡,程序本身也不會去處理的錯誤,Exception表示須要去捕捉的或者須要程序去拋出異常的,是一種設計或者是思想上的錯誤,若是程序可以運行,那麼就不會發生。Exception分爲運行時異常和非運行時異常
運行時異常包括IndexOutofBoundsException NullPointerException,ArrayOutOfBoundsException,ClassNotFoundException
非運行時異常包括SQLException,IOException,FileNotFound
兩種常見的回收機制:
1. 定時回收
每隔30分鐘進行一次回收,這種機制的弊端是若是垃圾產生的比較快,有可能30分鐘以內垃圾已經把內存佔用光了,致使性能變慢
2. 當垃圾佔到某個百分比的時候,進行回收
好比,當垃圾佔到70%的時候,進行回收。 這種機制的弊端是,若是垃圾產生的頻率很快,那麼JVM就必須高頻率的進行垃圾回收。 而在垃圾回收的過程當中, JVM會停頓下來,只作垃圾回收,而影響業務功能的正常運行。通常說來 JVM會採用兩種機制結合的方式進行垃圾回收。
java中有幾種類型的流?
Java中全部的流都是基於字節流,因此最基本的流是
輸入輸出字節流
InputStream
OutputStream
在字節流的基礎上,封裝了字符流
Reader
Writer
進一步,又封裝了緩存流
BufferedReader
PrintWriter
以及數據流
DataInputStream
DataOutputStream
對象流
ObjectInputStream
ObjectOutputStream
sleep() 和 wait() 有什麼區別?
sleep 是Thread類的方法,指的是當前線程暫停。
wait 是Object類的方法, 指的佔用當前對象的線程臨時釋放對當前對象的佔用,以使得其餘線程有機會佔用當前對象。 因此調用wait方法必定是在synchronized 中進行
死鎖
死鎖是指多個進程因競爭資源而形成的一種僵局,若無外力這些進程都將沒法向前推動
Lock是一個接口,而synchronized是Java中的關鍵字,synchronized是內置的語言實現,Lock是代碼層面的實現
Lock能夠選擇性的獲取鎖,若是一段時間獲取不到,能夠放棄。synchronized不行,會一根筋一直獲取下去。 藉助Lock的這個特性,就可以規避死鎖,synchronized必須經過謹慎和良好的設計,才能減小死鎖的發生。
synchronized在發生異常和同步塊結束的時候,會自動釋放鎖。而Lock必須手動釋放, 因此若是忘記了釋放鎖,同樣會形成死鎖。
Thread類的sleep()方法和對象的wait()方法均可以讓線程暫停執行,它們有什麼區別?
答:sleep()方法(休眠)是線程類(Thread)的靜態方法,調用此方法會讓當前線程暫停執行指定的時間,將執行機會(CPU)讓給其餘線程,可是對象的鎖依然保持,所以休眠時間結束後會自動恢復
線程的sleep()方法和yield()方法有什麼區別?
答:
① sleep()方法給其餘線程運行機會時不考慮線程的優先級,所以會給低優先級的線程以運行的機會;yield()方法只會給相同優先級或更高優先級的線程以運行的機會;
② 線程執行sleep()方法後轉入阻塞(blocked)狀態,而執行yield()方法後轉入就緒(ready)狀態;
③ sleep()方法聲明拋出InterruptedException,而yield()方法沒有聲明任何異常;
④ sleep()方法比yield()方法(跟操做系統CPU調度相關)具備更好的可移植性。
請說出與線程同步以及線程調度相關的方法。
答:
- wait():使一個線程處於等待(阻塞)狀態,而且釋放所持有的對象的鎖;
- sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要處理InterruptedException異常;
- notify():喚醒一個處於等待狀態的線程,固然在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定喚醒哪一個線程,並且與優先級無關;
- notityAll():喚醒全部處於等待狀態的線程,該方法並非將對象的鎖給全部線程,而是讓它們競爭,只有得到鎖的線程才能進入就緒狀態;
Java中如何實現序列化,有什麼意義?
答:序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決對象流讀寫操做時可能引起的問題
Java中有幾種類型的流?
答:字節流和字符流。字節流繼承於InputStream、OutputStream,字符流繼承於Reader、Writer。在java.io 包中還有許多其餘的流,主要是爲了提升性能和使用方便。關於Java的I/O須要注意的有兩點:一是兩種對稱性(輸入和輸出的對稱性,字節和字符的對稱性);二是兩種設計模式(適配器模式和裝潢模式)。另外Java中的流不一樣於C#的是它只有一個維度一個方向。
Statement和PreparedStatement有什麼區別?哪一個性能更好?
答:與Statement相比,①PreparedStatement接口表明預編譯的語句,它主要的優點在於能夠減小SQL的編譯錯誤並增長SQL的安全性(減小SQL注射攻擊的可能性);②PreparedStatement中的SQL語句是能夠帶參數的,避免了用字符串鏈接拼接SQL語句的麻煩和不安全;③當批量處理SQL或頻繁執行相同的查詢時,PreparedStatement有明顯的性能上的優點,因爲數據庫能夠將編譯優化後的SQL語句緩存起來,下次執行相同結構的語句時就會很快(不用再次編譯和生成執行計劃)
什麼是DAO模式?
答:DAO(Data Access Object)顧名思義是一個爲數據庫或其餘持久化機制提供了抽象接口的對象,在不暴露底層持久化方案實現細節的前提下提供了各類數據訪問操做。在實際的開發中,應該將全部對數據源的訪問操做進行抽象化後封裝在一個公共API中。用程序設計語言來講,就是創建一個接口,接口中定義了此應用程序中將會用到的全部事務方法。在這個應用程序中,當須要和數據源進行交互的時候則使用這個接口,而且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,然後者要解決的是如何用對象封裝數據。
事務的ACID是指什麼?
答:
- 原子性(Atomic):事務中各項操做,要麼全作要麼全不作,任何一項操做的失敗都會致使整個事務的失敗;
- 一致性(Consistent):事務結束後系統狀態是一致的;
- 隔離性(Isolated):併發執行的事務彼此沒法看到對方的中間狀態;
- 持久性(Durable):事務完成後所作的改動都會被持久化,即便發生災難性的失敗。經過日誌和同步備份能夠在故障發生後重建數據。
事務隔離級別和數據訪問的併發性是對立的,事務隔離級別越高併發性就越差。因此要根據具體的應用來肯定合適的事務隔離級別,這個地方沒有萬能的原則。
爲此數據庫爲用戶提供了自動鎖機制,只要用戶指定會話的事務隔離級別,數據庫就會經過分析SQL語句而後爲事務訪問的資源加上合適的鎖
單例模式
public
class
Singleton {
private
Singleton(){}
private
static
Singleton instance =
new
Singleton();
public
static
Singleton getInstance(){
return
instance;
}
}
談一下攔截器和過濾器的區別。
答:攔截器和過濾器均可以用來實現橫切關注功能,其區別主要在於:
①攔截器是基於Java反射機制的,而過濾器是基於接口回調的。
②過濾器依賴於Servlet容器,而攔截器不依賴於Servlet容器。
③攔截器只能對Action請求起做用,而過濾器能夠對全部請求起做用。
④攔截器能夠訪問Action上下文、值棧裏的對象,而過濾器不能。
SessionFactory是線程安全的嗎?Session是線程安全的嗎,兩個線程可以共享同一個Session嗎?
答:SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,能夠被多個線程併發訪問。SessionFactory通常只會在啓動的時候構建。對於應用程序,最好將SessionFactory經過單例的模式進行封裝以便於訪問。Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數據庫進行交互的一個工做單元。Session是由SessionFactory建立的,在任務完成以後它會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫鏈接(也就是在須要的時候纔會獲取)。爲了不建立太多的session,可使用ThreadLocal來取得當前的session,不管你調用多少次getCurrentSession()方法,返回的都是同一個session。
鎖機制有什麼用?簡述Hibernate的悲觀鎖和樂觀鎖機制。
答:有些業務邏輯在執行過程當中每每須要保證數據訪問的排他性,因而須要經過一些機制保證在此過程當中數據被鎖住不會被外界修改,這就是所謂的鎖機制。
Hibernate支持悲觀鎖和樂觀鎖兩種鎖機制。悲觀鎖,顧名思義,它悲觀的認爲在數據處理過程當中必定存在修改數據的併發事務(包括本系統的其餘事務或來自外部系統的事務),因而將處理的數據設置爲鎖定狀態。悲觀鎖必須依賴數據庫自己的鎖機制才能真正保證數據訪問的排他性。樂觀鎖,顧名思義,對併發事務持樂觀態度(認爲對數據的併發操做不多發生),經過更加寬鬆的鎖機制解決悲觀鎖排他的數據訪問對系統性能形成的嚴重影響。最多見的樂觀鎖是經過數據版本標識來實現的,讀取數據時得到數據的版本號,更新數據時將此版本號加1,而後和數據庫表對應記錄的當前版本號進行比較,若是提交的數據版本號大於數據庫中此記錄的當前版本號則更新數據,不然認爲是過時數據。
你使用過的應用服務器優化技術有哪些?
答:
① 分佈式緩存:緩存的本質就是內存中的哈希表,若是設計一個優質的哈希函數,那麼理論上哈希表讀寫的漸近時間複雜度爲O(1)。緩存主要用來存放那些讀寫比很高、變化不多的數據,這樣應用程序讀取數據時先到緩存中讀取,若是沒有或者數據已經失效再去訪問數據庫或文件系統,並根據擬定的規則將數據寫入緩存。對網站數據的訪問也符合二八定律(Pareto分佈,冪律分佈),即80%的訪問都集中在20%的數據上,若是可以將這20%的數據緩存起來,那麼系統的性能將獲得顯著的改善。固然,使用緩存須要解決如下幾個問題:
- 頻繁修改的數據;
- 數據不一致與髒讀;
- 緩存雪崩(能夠採用分佈式緩存服務器集羣加以解決,memcached是普遍採用的解決方案);
- 緩存預熱;
- 緩存穿透(惡意持續請求不存在的數據)。
② 異步操做:可使用消息隊列將調用異步化,經過異步處理將短期高併發產生的事件消息存儲在消息隊列中,從而起到削峯做用。電商網站在進行促銷活動時,能夠將用戶的訂單請求存入消息隊列,這樣能夠抵禦大量的併發訂單請求對系統和數據庫的衝擊。目前,絕大多數的電商網站即使不進行促銷活動,訂單系統都採用了消息隊列來處理。
③ 使用集羣。
④ 代碼優化:
- 多線程:基於Java的Web開發基本上都經過多線程的方式響應用戶的併發請求,使用多線程技術在編程上要解決線程安全問題,主要能夠考慮如下幾個方面:A. 將對象設計爲無狀態對象(這和麪向對象的編程觀點是矛盾的,在面向對象的世界中被視爲不良設計),這樣就不會存在併發訪問時對象狀態不一致的問題。B. 在方法內部建立對象,這樣對象由進入方法的線程建立,不會出現多個線程訪問同一對象的問題。使用ThreadLocal將對象與線程綁定也是很好的作法,這一點在前面已經探討過了。C. 對資源進行併發訪問時應當使用合理的鎖機制。
- 非阻塞I/O: 使用單線程和非阻塞I/O是目前公認的比多線程的方式更能充分發揮服務器性能的應用模式,基於Node.js構建的服務器就採用了這樣的方式。Java在JDK 1.4中就引入了NIO(Non-blocking I/O),在Servlet 3規範中又引入了異步Servlet的概念,這些都爲在服務器端採用非阻塞I/O提供了必要的基礎。
- 資源複用:資源複用主要有兩種方式,一是單例,二是對象池,咱們使用的數據庫鏈接池、線程池都是對象池化技術,這是典型的用空間換取時間的策略,另外一方面也實現對資源的複用,從而避免了沒必要要的建立和釋放資源所帶來的開銷。
16八、什麼是XSS攻擊?什麼是SQL注入攻擊?什麼是CSRF攻擊?
答:
- XSS(Cross Site Script,跨站腳本攻擊)是向網頁中注入惡意腳本在用戶瀏覽網頁時在用戶瀏覽器中執行惡意腳本的攻擊方式。跨站腳本攻擊分有兩種形式:反射型攻擊(誘使用戶點擊一個嵌入惡意腳本的連接以達到攻擊的目標,目前有不少攻擊者利用論壇、微博發佈含有惡意腳本的URL就屬於這種方式)和持久型攻擊(將惡意腳本提交到被攻擊網站的數據庫中,用戶瀏覽網頁時,惡意腳本從數據庫中被加載到頁面執行,QQ郵箱的早期版本就曾經被利用做爲持久型跨站腳本攻擊的平臺)。XSS雖然不是什麼新鮮玩意,可是攻擊的手法卻不斷翻新,防範XSS主要有兩方面:消毒(對危險字符進行轉義)和HttpOnly(防範XSS攻擊者竊取Cookie數據)。
- SQL注入攻擊是注入攻擊最多見的形式(此外還有OS注入攻擊(Struts 2的高危漏洞就是經過OGNL實施OS注入攻擊致使的)),當服務器使用請求參數構造SQL語句時,惡意的SQL被嵌入到SQL中交給數據庫執行。SQL注入攻擊須要攻擊者對數據庫結構有所瞭解才能進行,攻擊者想要得到表結構有多種方式:(1)若是使用開源系統搭建網站,數據庫結構也是公開的(目前有不少現成的系統能夠直接搭建論壇,電商網站,雖然方便快捷可是風險是必需要認真評估的);(2)錯誤回顯(若是將服務器的錯誤信息直接顯示在頁面上,攻擊者能夠經過非法參數引起頁面錯誤從而經過錯誤信息瞭解數據庫結構,Web應用應當設置友好的錯誤頁,一方面符合最小驚訝原則,一方面屏蔽掉可能給系統帶來危險的錯誤回顯信息);(3)盲注。防範SQL注入攻擊也能夠採用消毒的方式,經過正則表達式對請求參數進行驗證,此外,參數綁定也是很好的手段,這樣惡意的SQL會被當作SQL的參數而不是命令被執行,JDBC中的PreparedStatement就是支持參數綁定的語句對象,從性能和安全性上都明顯優於Statement。
- CSRF攻擊(Cross Site Request Forgery,跨站請求僞造)是攻擊者經過跨站請求,以合法的用戶身份進行非法操做(如轉帳或發帖等)。CSRF的原理是利用瀏覽器的Cookie或服務器的Session,盜取用戶身份,其原理以下圖所示。防範CSRF的主要手段是識別請求者的身份,主要有如下幾種方式:(1)在表單中添加令牌(token);(2)驗證碼;(3)檢查請求頭中的Referer(前面提到防圖片盜連接也是用的這種方式)。令牌和驗證都具備一次消費性的特徵,所以在原理上一致的,可是驗證碼是一種糟糕的用戶體驗,不是必要的狀況下不要輕易使用驗證碼,目前不少網站的作法是若是在短期內屢次提交一個表單未得到成功後纔要求提供驗證碼,這樣會得到較好的用戶體驗。
什麼是ORM?
答:對象關係映射(Object-Relational Mapping,簡稱ORM)是一種爲了解決程序的面向對象模型與數據庫的關係模型互不匹配問題的技術;簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據(在Java中能夠用XML或者是註解),將程序中的對象自動持久化到關係數據庫中或者將關係數據庫表中的行轉換成Java對象,其本質上就是將數據從一種形式轉換到另一種形式。
MyBatis的一級緩存和二級緩存
Mybatis首先去緩存中查詢結果集,若是沒有則查詢數據庫,若是有則從緩存取出返回結果集就不走數據庫。Mybatis內部存儲緩存使用一個HashMap,key爲hashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象
Mybatis的二級緩存即查詢緩存,它的做用域是一個mapper的namespace,即在同一個namespace中查詢sql能夠從緩存中獲取數據。二級緩存是能夠跨SqlSession的。
什麼是Spring
Spring是一個開源的,輕量級的應用開發的框架,其目的是用於簡化企業級應用的開發,減小侵入。Spring的核心是IOC容器,DI依賴注入。Spring發明的主要目的可以使咱們使JavaEE更容易使用
Spring工做流程(異步爲例)
整個請求從HTTP開始,HTTP找到前端的總控制器DispatchServlet,而後根據DispatchServlet找到HandlerMapping處理器映射(HandlerMapping主要負責請求和處理對應的關係)而後找到對應的Controller處理器返回數據對象@ResponseBody使用Gson/Jackson工具包,將對象轉換成JSON字符串並響應輸出JSON字符串,由Ajax回調函數,最後顯示給用戶
Spring功能的主要作用
SpringIOC
能夠這樣說IOC並非一種技術,能夠絕不猶豫的說他是一種編程的思想,一個重要的面向對象的編程法則。那麼沒有使用Spring以前咱們一般在類中建立依賴的對象,這樣的話不利於咱們Java編程的思想,Java編程在必定程度上追求的是「高內聚,低耦合」,那麼在類中自主的建立依賴對象很明顯的是不知足的,SpringIOC出現就解決了這一問題,咱們就能夠把建立和查找的權限都交給了咱們的IOC容器進行注入,那麼類和類之間的話減小了依賴關係,更好爲咱們提供了測試環境,也能夠方便的爲咱們對代碼的維護和可擴展性。那麼對於整個程序來講由於有了SpringIOC整個體系都顯得很是的靈活,IOC對於咱們編程來講最大的改變不是在技術上而是在思想上。程序原本爲主須要什麼內容主動去獲取。那麼如今有了IOC/DI,咱們的程序就變得被動起來,須要去等待咱們的IOC/DI去建立而且注入程序自己須要的資源
IOC的類型 基於特定的接口 基於SET方法 基於構造器
SpringAOP
SpringAOP面向切面編程,那麼他的出現就是更好的幫助Java的OOP思想(面向對象編程)更好的補充和完善
那麼AOP出現爲何說是對OOP思想的完善和補充呢,OOP引入了封裝,多態,繼承等概念性的東西對象層次結構的東西,OOP容許你定義上下關係 而對於左右沒可以很好的完善例如日誌功能。日誌代碼每每水平地散佈在全部對象層次中,而與它所散佈到的對象的核心功能毫無關係。那麼可能致使重複的代碼增長不利於代碼的重用性。也加深了各個模塊之間的依賴,那麼SpringAOP就利用了這一橫切的技術解決了這一問題去剖開咱們對象的內部,而且把那些那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減小系統的重複代碼,下降模塊間的耦合度,並有利於將來的可操做性和可維護性。
Spring中Bean的做用域有哪些?
答:在Spring的早期版本中,僅有兩個做用域:singleton和prototype,前者表示Bean以單例的方式存在;後者表示每次從容器中調用Bean時,都會返回一個新的實例,prototype一般翻譯爲原型。
你是如何理解」橫切關注」這個概念的?
答:」橫切關注」是會影響到整個應用程序的關注功能,它跟正常的業務邏輯是正交的,沒有必然的聯繫,可是幾乎全部的業務邏輯都會涉及到這些關注功能。一般,事務、日誌、安全性等關注就是應用中的橫切關注功能。
Spring支持的事務管理類型有哪些?你在項目中使用哪一種方式?
答:Spring支持編程式事務管理和聲明式事務管理。許多Spring框架的用戶選擇聲明式事務管理,由於這種方式和應用程序的關聯較少,所以更加符合輕量級容器的概念。聲明式事務管理要優於編程式事務管理,儘管在靈活性方面它弱於編程式事務管理,由於編程式事務容許你經過代碼控制業務。
事務分爲全局事務和局部事務。全局事務由應用服務器管理,須要底層服務器JTA支持(如WebLogic、WildFly等)。局部事務和底層採用的持久化方案有關,例如使用JDBC進行持久化時,須要使用Connetion對象來操做事務;而採用Hibernate進行持久化時,須要使用Session對象來操做事務。
大型網站在架構上應當考慮哪些問題?
答:
- 分層:分層是處理任何複雜系統最多見的手段之一,將系統橫向切分紅若干個層面,每一個層面只承擔單一的職責,而後經過下層爲上層提供的基礎設施和服務以及上層對下層的調用來造成一個完整的複雜的系統。計算機網絡的開放系統互聯參考模型(OSI/RM)和Internet的TCP/IP模型都是分層結構,大型網站的軟件系統也可使用分層的理念將其分爲持久層(提供數據存儲和訪問服務)、業務層(處理業務邏輯,系統中最核心的部分)和表示層(系統交互、視圖展現)。須要指出的是:(1)分層是邏輯上的劃分,在物理上能夠位於同一設備上也能夠在不一樣的設備上部署不一樣的功能模塊,這樣可使用更多的計算資源來應對用戶的併發訪問;(2)層與層之間應當有清晰的邊界,這樣分層纔有意義,才更利於軟件的開發和維護。
- 分割:分割是對軟件的縱向切分。咱們能夠將大型網站的不一樣功能和服務分割開,造成高內聚低耦合的功能模塊(單元)。在設計初期能夠作一個粗粒度的分割,將網站分割爲若干個功能模塊,後期還能夠進一步對每一個模塊進行細粒度的分割,這樣一方面有助於軟件的開發和維護,另外一方面有助於分佈式的部署,提供網站的併發處理能力和功能的擴展。
- 分佈式:除了上面提到的內容,網站的靜態資源(JavaScript、CSS、圖片等)也能夠採用獨立分佈式部署並採用獨立的域名,這樣能夠減輕應用服務器的負載壓力,也使得瀏覽器對資源的加載更快。數據的存取也應該是分佈式的,傳統的商業級關係型數據庫產品基本上都支持分佈式部署,而新生的NoSQL產品幾乎都是分佈式的。固然,網站後臺的業務處理也要使用分佈式技術,例如查詢索引的構建、數據分析等,這些業務計算規模龐大,可使用Hadoop以及MapReduce分佈式計算框架來處理。
- 集羣:集羣使得有更多的服務器提供相同的服務,能夠更好的提供對併發的支持。
- 緩存:所謂緩存就是用空間換取時間的技術,將數據儘量放在距離計算最近的位置。使用緩存是網站優化的第必定律。咱們一般說的CDN、反向代理、熱點數據都是對緩存技術的使用。
- 異步:異步是實現軟件實體之間解耦合的又一重要手段。異步架構是典型的生產者消費者模式,兩者之間沒有直接的調用關係,只要保持數據結構不變,彼此功能實現能夠隨意變化而不互相影響,這對網站的擴展很是有利。使用異步處理還能夠提升系統可用性,加快網站的響應速度(用Ajax加載數據就是一種異步技術),同時還能夠起到削峯做用(應對瞬時高併發)。";能推遲處理的都要推遲處理」是網站優化的第二定律,而異步是踐行網站優化第二定律的重要手段。
- 冗餘:各類服務器都要提供相應的冗餘服務器以便在某臺或某些服務器宕機時還能保證網站能夠正常工做,同時也提供了災難恢復的可能性。冗餘是網站高可用性的重要保證。
你使用過的應用服務器優化技術有哪些?
答:
① 分佈式緩存:緩存的本質就是內存中的哈希表,若是設計一個優質的哈希函數,那麼理論上哈希表讀寫的漸近時間複雜度爲O(1)。緩存主要用來存放那些讀寫比很高、變化不多的數據,這樣應用程序讀取數據時先到緩存中讀取,若是沒有或者數據已經失效再去訪問數據庫或文件系統,並根據擬定的規則將數據寫入緩存。對網站數據的訪問也符合二八定律(Pareto分佈,冪律分佈),即80%的訪問都集中在20%的數據上,若是可以將這20%的數據緩存起來,那麼系統的性能將獲得顯著的改善。固然,使用緩存須要解決如下幾個問題:
- 頻繁修改的數據;
- 數據不一致與髒讀;
- 緩存雪崩(能夠採用分佈式緩存服務器集羣加以解決,Redis是普遍採用的解決方案);
- 緩存預熱;
- 緩存穿透(惡意持續請求不存在的數據)。
② 異步操做:可使用消息隊列將調用異步化,經過異步處理將短期高併發產生的事件消息存儲在消息隊列中,從而起到削峯做用。電商網站在進行促銷活動時,能夠將用戶的訂單請求存入消息隊列,這樣能夠抵禦大量的併發訂單請求對系統和數據庫的衝擊。目前,絕大多數的電商網站即使不進行促銷活動,訂單系統都採用了消息隊列來處理。
③ 使用集羣。
④ 代碼優化:
- 多線程:基於Java的Web開發基本上都經過多線程的方式響應用戶的併發請求,使用多線程技術在編程上要解決線程安全問題,主要能夠考慮如下幾個方面:A. 將對象設計爲無狀態對象(這和麪向對象的編程觀點是矛盾的,在面向對象的世界中被視爲不良設計),這樣就不會存在併發訪問時對象狀態不一致的問題。B. 在方法內部建立對象,這樣對象由進入方法的線程建立,不會出現多個線程訪問同一對象的問題。使用ThreadLocal將對象與線程綁定也是很好的作法,這一點在前面已經探討過了。C. 對資源進行併發訪問時應當使用合理的鎖機制。
- 非阻塞I/O: 使用單線程和非阻塞I/O是目前公認的比多線程的方式更能充分發揮服務器性能的應用模式,基於Node.js構建的服務器就採用了這樣的方式。Java在JDK 1.4中就引入了NIO(Non-blocking I/O),在Servlet 3規範中又引入了異步Servlet的概念,這些都爲在服務器端採用非阻塞I/O提供了必要的基礎。
- 資源複用:資源複用主要有兩種方式,一是單例,二是對象池,咱們使用的數據庫鏈接池、線程池都是對象池化技術,這是典型的用空間換取時間的策略,另外一方面也實現對資源的複用,從而避免了沒必要要的建立和釋放資源所帶來的開銷。
16八、什麼是XSS攻擊?什麼是SQL注入攻擊?什麼是CSRF攻擊?答:- XSS(Cross Site Script,跨站腳本攻擊)是向網頁中注入惡意腳本在用戶瀏覽網頁時在用戶瀏覽器中執行惡意腳本的攻擊方式。跨站腳本攻擊分有兩種形式:反射型攻擊(誘使用戶點擊一個嵌入惡意腳本的連接以達到攻擊的目標,目前有不少攻擊者利用論壇、微博發佈含有惡意腳本的URL就屬於這種方式)和持久型攻擊(將惡意腳本提交到被攻擊網站的數據庫中,用戶瀏覽網頁時,惡意腳本從數據庫中被加載到頁面執行,QQ郵箱的早期版本就曾經被利用做爲持久型跨站腳本攻擊的平臺)。XSS雖然不是什麼新鮮玩意,可是攻擊的手法卻不斷翻新,防範XSS主要有兩方面:消毒(對危險字符進行轉義)和HttpOnly(防範XSS攻擊者竊取Cookie數據)。- SQL注入攻擊是注入攻擊最多見的形式(此外還有OS注入攻擊(Struts 2的高危漏洞就是經過OGNL實施OS注入攻擊致使的)),當服務器使用請求參數構造SQL語句時,惡意的SQL被嵌入到SQL中交給數據庫執行。SQL注入攻擊須要攻擊者對數據庫結構有所瞭解才能進行,攻擊者想要得到表結構有多種方式:(1)若是使用開源系統搭建網站,數據庫結構也是公開的(目前有不少現成的系統能夠直接搭建論壇,電商網站,雖然方便快捷可是風險是必需要認真評估的);(2)錯誤回顯(若是將服務器的錯誤信息直接顯示在頁面上,攻擊者能夠經過非法參數引起頁面錯誤從而經過錯誤信息瞭解數據庫結構,Web應用應當設置友好的錯誤頁,一方面符合最小驚訝原則,一方面屏蔽掉可能給系統帶來危險的錯誤回顯信息);(3)盲注。防範SQL注入攻擊也能夠採用消毒的方式,經過正則表達式對請求參數進行驗證,此外,參數綁定也是很好的手段,這樣惡意的SQL會被當作SQL的參數而不是命令被執行,JDBC中的PreparedStatement就是支持參數綁定的語句對象,從性能和安全性上都明顯優於Statement。- CSRF攻擊(Cross Site Request Forgery,跨站請求僞造)是攻擊者經過跨站請求,以合法的用戶身份進行非法操做(如轉帳或發帖等)。CSRF的原理是利用瀏覽器的Cookie或服務器的Session,盜取用戶身份,其原理以下圖所示。防範CSRF的主要手段是識別請求者的身份,主要有如下幾種方式:(1)在表單中添加令牌(token);(2)驗證碼;(3)檢查請求頭中的Referer(前面提到防圖片盜連接也是用的這種方式)。令牌和驗證都具備一次消費性的特徵,所以在原理上一致的,可是驗證碼是一種糟糕的用戶體驗,不是必要的狀況下不要輕易使用驗證碼,目前不少網站的作法是若是在短期內屢次提交一個表單未得到成功後纔要求提供驗證碼,這樣會得到較好的用戶體驗。