1. 什么是向上轉型,向下轉型?
向上轉型:父類引用指向子類對象。
向下轉型:子類對象指向父類引用(強轉),先向上轉型,在向下轉型,沒有經過向上轉型,會提示編譯錯誤。
2.什么是數組,有什么特點?
數組是一種容器,可以同時存放多個類型相同的數據。
數組是一種引用數據類型,當有多個數據類型必須統一,數組長度在運行期間不可改變長度在創建時給定。
3.什么是集合,和數組的區別?
是Java中提供的一種容器,用來存儲多個數據。
數組的長度是固定的,集合的長度是可變的;數組中存儲的是同一類型的元素,集合存儲的類型可以不一致;
4.你所知道的List有哪些,特點分別是什么?
ArrayList:底層的數據結構是數組,所以查詢快,增刪慢,線程不安全
LinkedList:底層的數據結構是鏈表,所以查詢慢,增刪快,線程不安全
Vector:底層的數據結構是數組,查詢快,增刪慢,線程安全
5.TreeSet是如何排序的?
實現Comparable接口,覆寫compareTo()方法,只能對該類的對象進行比較
匿名內部類比較器,Comparator重寫compare方法,相當於一個外部比較器
6.Queue有哪些,各有什么特點?
高性能隊列ConcurrentLinkedQueue:使用於高並發場景的隊列,基於鏈接結點的無界線程安全隊列,先進先出,不允許有null元素
阻塞隊列BlockingQueue分為以下五種:
-
ArrayBlockingQueue:基於數組的阻塞隊列,也叫有界隊列
-
LinkedBlockingQueue:基於鏈表的阻塞隊列,無界隊列
-
PriorityBlockingQueue:基於優先級的阻塞隊列,優先級的判斷通過構造器傳入的比較器來決定,是一個無界隊列
-
DelayQueue:帶有延遲時間的隊列,是一個沒有大小的隊列
-
SynchronousQueue:一種沒有緩沖的隊列
7.Hashtable和HashMap的區別?
HashTable繼承自Dirctionary(一個抽象類,用來存儲鍵值對,作用和map類相似,字典類),HashMap繼承自AbstractMap,兩者均實現了Map接口;
HashTable線程安全,key和value都不能為空;,HashMap線程不安全,key和value都可以為空;
遍歷:HashTable和HashMap兩者都實現了Iterator,但是HashTable還是用了Enumeration;
哈希值:HashTable是直接使用對象的hashCode,HashMap是重新計算hash值
8.Vector和ArrayList的區別?
Vector是線程安全的,ArrayList是線程不安全的;
ArrayList在底層數組不夠用時在原來的基礎上擴展0.5倍,Vector是擴展1倍;
9.說出幾個IO流對象,各有什么特點?
File:文件類
InputStream:抽象類,字節輸入流
OutputStream:抽象類,字節輸出流
Reader:抽象類,字符輸入流
Writer:抽象類,字符輸出流
文件字節輸入輸出流:FileInputStream,FileOutputStream
文件字符輸入輸出流:FileReader,File
字節輸入輸出緩沖流:BufferedInputStream,BufferedOutputStream
字符輸入輸出緩沖流:BufferedReader,BufferedWriter
10.線程和進程的關系和區別?
線程是進程的基本執行單元,一個進程的所有任務都在線程中執行,進程如果想要執行任務,必須要有線程,進程至少要有一條線程,進程是指在系統中正在運行的一個應用程序,每個進程之間是獨立的,同一進程的線程共享本進程的地址空間、資源。
11.線程池有哪些,各有什么特點?
newCachedThreadPool:可緩存線程池,線程數量不定
newFixedThreadPool:定長線程池,線程數量固定,當處於閑置狀態也不會被回收
newScheduledThreadPool:周期性執行任務的線程池,核心線程數是固定的,非核心線程數是沒有限制的,非核心線程閑置時會被立即回收
newSingleThreadExecutor:單線程化的線程池,只有一個核心線程,以無界隊列方式來執行該線程,這使得這些任務之間不需要處理線程同步的問題,它確保所有的任務都在同一個線程中按順序中執行,並且可以在任意給定的時間不會有多個線程是活動的。
12.為什么要使用數據庫連接池?
如果沒有用連接池,每次發起SQL查詢時首先通過TCP協議的三次握手和數據庫服務建立連接,然后發送賬號密碼,驗證過后才提交SQL語句執行,執行完畢后再TCP四次揮手最后完成關閉。如果執行多個SQL就會頻繁的建立連接然后關閉,如果用連接池就是用空間換時間思想,系統啟動預先創建多個數據庫連接對象,雖然會占用一定的內存空間,但是可以省去每次SQL查詢時創建連接和關閉連接所消耗的時間。
常用的數據庫連接池:DBCP,C3P0,阿里的DRUID
13.Socket用的是什么協議,四層協議分別是什么?
TCP/IP協議,Socket用於通信,因此需要可靠的網絡協議,UDP是不可靠協議,
應用層:HTTP應用程序間溝通的層
傳輸層:TCP、UDP這一層負責數據格式化,數據確認和丟失重傳(傳送數據,並且確定數據已經被送達並接收)
互聯網絡層:IP負責提供基本的數據封包傳送功能,讓每一塊數據包都能夠到達目的主機(郵件的地址)
網絡接口層:接收IP數據包並進行傳輸(送郵件的車)
14.詳細說一下三次握手和四次揮手的過程?
所謂的“三次握手”:為了對每次發送的數據量進行跟蹤與協商,確保數據段的發送和接收同步,根據所接收到的數據量而確認數據發送、接收完畢后何時撤消聯系,並建立虛連接。
為了提供可靠的傳送,TCP在發送新的數據之前,以特定的順序將數據包的序號,並需要這些包傳送給目標機之后的確認消息。TCP總是用來發送大批量的數據。當應用程序在收到數據后要做出確認時也要用到TCP。
第一次握手:客戶端向服務端發起建立連接請求,客戶端會隨機生成一個起始序列號x,客戶端向服務端發送的字段中包含標志位SYN=1,序列號seq=x。第一次握手前客戶端的狀態為CLOSE,第一次握手后客戶端的狀態為SYN-SENT。此時服務端的狀態為LISTEN
第二次握手:服務端在收到客戶端發來的報文后,會隨機生成一個服務端的起始序列號y,然后給客戶端回復一段報文,其中包括標志位SYN=1,ACK=1,序列號seq=y,確認號ack=x+1。第二次握手前服務端的狀態為LISTEN,第二次握手后服務端的狀態為SYN-RCVD,此時客戶端的狀態為SYN-SENT。(其中SYN=1表示要和客戶端建立一個連接,ACK=1表示確認序號有效)
第三次握手:客戶端收到服務端發來的報文后,會再向服務端發送報文,其中包含標志位ACK=1,序列號seq=x+1,確認號ack=y+1。第三次握手前客戶端的狀態為SYN-SENT,第三次握手后客戶端和服務端的狀態都為ESTABLISHED。
四次揮手:
第一次揮手:客戶端向服務端發送的數據完成后,向服務端發起釋放連接報文,報文包含標志位FIN=1,序列號seq=u。此時客戶端只能接收數據,不能向服務端發送數據。
第二次揮手:服務端收到客戶端的釋放連接報文后,向客戶端發送確認報文,包含標志位ACK=1,序列號seq=v,確認號ack=u+1。此時客戶端到服務端的連接已經釋放掉,客戶端不能像服務端發送數據,服務端也不能向客戶端發送數據。但服務端到客戶端的單向連接還能正常傳輸數據。
第三次揮手:服務端發送完數據后向客戶端發出連接釋放報文,報文包含標志位FIN=1,標志位ACK=1,序列號seq=w,確認號ack=u+1。
第四次揮手:客戶端收到服務端發送的釋放連接請求,向服務端發送確認報文,包含標志位ACK=1,序列號seq=u+1,確認號ack=w+1。
為什么TCP連接的時候是3次,兩次是否可以:
-
假設建立TCP連接僅需要兩次握手,那么如果第二次握手時,服務端返回給客戶端的確認報文丟失了,客戶端這邊認為服務端沒有和他建立連接,而服務端卻以為已經和客戶端建立了連接,並且可能向服務端已經開始向客戶端發送數據,但客戶端並不會接收這些數據,浪費了資源。如果是三次握手,不會出現雙方連接還未完全建立成功就開始發送數據的情況。
-
如果服務端接收到了一個早已失效的來自客戶端的連接請求報文,會向客戶端發送確認報文同意建立TCP連接。但因為客戶端並不需要向服務端發送數據,所以此次TCP連接沒有意義並且浪費了資源。
為什么TCP連接的時候是3次,關閉的時候是4次
因為需要確保通信雙方都能通知對方釋放連接,假設客服端發送完數據向服務端發送釋放連接請求,當客服端並不知道,服務端是否已經發送完數據,所以此次斷開的是客服端到服務端的單向連接,服務端返回給客戶端確認報文后,服務端還能繼續單向給客戶端發送數據。當服務端發送完數據后還需要向客戶端發送釋放連接請求,客戶端返回確認報文,TCP連接徹底關閉。所以斷開TCP連接需要客戶端和服務端分別通知對方並分別收到確認報文,一共需要四次。
15.想要讓SQL查詢效率高,可以做哪些工作?
explain的用法:explain+sql語句,例如:explain select * from securityprice order by index
可以模擬MySQL優化器執行SQL語句,可以很好的分析SQL語句的性能
-
應盡量避免全表掃描,首先考慮在where及order by涉及的列上建立索引
-
應盡量避免在where子句中對字段進行null值判斷,否則將導致引擎放棄使用索引而進行全表掃描
-
應盡量避免在where子句中使用!=或<>操作符,否則引擎將放棄使用索引而進行全表掃描
-
應盡量避免在where子句中使用or來連接條件,否則引擎將放棄使用索引而進行全表掃描
-
in和not in也要慎用
-
用exists代替in
-
模糊查詢不要使用%查詢數據%的格式,最前面最好直接是查詢數據
-
避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描
-
不要在where子句中的=左邊進行函數、算數運算或其他表達式,否則系統將可能無法正確使用索引
-
索引不是越多越好,索引固然可以提高select的效率,但是同時也降低了insert及update的效率
-
盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。因為引擎在處理查詢和連接對象時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了
-
用varchar代替char,因為變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些
-
任何地方都不要使用select * from t,用具體字段列表代替*
-
盡量避免大事務操作,提高系統並發能力
-
避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理
16.什么是游標,有哪些分類?
用來存儲多條查詢數據的一種數據結構(數據集),它有一個指針,從上往下移動,從而能夠遍歷每條記錄。游標就是位於內存中的數據集,加快對數據的操作。犧牲內存,提高sql執行效率
系統游標(隱式游標):系統定義好的游標,一般在做DML操作時自動觸發,一般用於看影響行數
用戶游標(顯式游標):
- 靜態游標:創建游標的SQL語句是固定的
- 動態游標:創建游標的SQL語句是動態的,帶有參數或變量
17.GET方式和POST方式有哪些區別?
-
GET在瀏覽器回退時是無害的,POST會在次提交請求
-
GET請求產生的URL地址可以被看到,而POST不可以
-
GET請求會被瀏覽器主動緩存,而POST不會,除非主動設置
-
GET請求只能進行url編碼,而POST支持多種編碼方式
-
GET請求參數會被完整保留在瀏覽器歷史記錄里,而POST中的參數不會被保留
-
GET請求在URL中傳送的參數是有長度限制的,而POST沒有
-
對參數的數據類型,GET只接受ASCII字符,而POST沒有限制
-
GET比POST更不安全,因為參數直接暴露在URL上,所以不能用來傳遞敏感信息
-
GET參數通過URL傳遞,POST放在Request body中
-
GEt和POST請求是HTTP協議中的兩種請求的方法,底層是TCP/IP。GET產生一個TCP數據包,POST產生兩個TCP數據包。對於GET請求瀏覽器會把http header和data一並發送出去;POST請求會先發送header,服務器響應100 continue,瀏覽器在發送data;注:據研究,在網絡環境好的情況下,發一次包的時間和發兩次包的時間差別基本可以無視。而在網絡環境差的情況下,兩次包的TCP在驗證數據包完整性上,有非常大的優點。並不是所有瀏覽器都會在POST中發送兩次包,Firefox就只發送一次。
18.CSS選擇器有哪些?
標簽選擇器
ID選擇器
類選擇器
組選擇器
通配符選擇器
后代選擇器
子元素選擇器
兄弟選擇器
相鄰選擇器
屬性選擇器
偽類選擇器
19.什么是盒子模型的坍塌?
父子坍塌:父親沒有設置padding border內容時,子元素垂直方向的margin會賦給父親,父親最終垂直方向的margin為父子中最大的margin值,並非相加
解決方法:把兒子的margin裝換成父親的padding;或給父元素增加position:absolute
並列元素坍塌:垂直方向相遇的盒子模型,會發生margin坍塌,現象就是元素兩者之間的距離並非之和,而是二者之間最大的
解決方法:給第一個元素只設置margin
20.去掉元素的浮動怎么做?
-
為父元素添加overflow:hidden
-
clear:both
-
floatfix類
21.接口和抽象類的區別?
-
都不能被實例化,但是抽象類里可以有構造方法,接口里不能有構造方法
-
接口只有定義,不能有方法的實現,java1.8中可以定義default方法體,而抽象類可以有定義與實現,方法可以在抽象類中實現
-
接口強調特定功能的實現,而抽象類強調所屬關系
-
接口成員變量默認為public static final,必須賦值,不能被修改,其所有的成員方法都是public abstract的,抽象類中成員變量默認default,可在子類中被重新定義,也可被重新賦值,
抽象方法被abstract修飾,不能被private、static、synchrornized和native等修飾。
22.什么是DI和IoC?什么是AOP?
23.什么是本地線程,有什么好處?
線程類Thread有個變量叫做threadLocals,它的類型就是ThreadLocal.ThreadLocalMap類型,key是當前線程的ThreadLocal對象,值就是要保存的數據。每個線程自己的本地變量,在每個線程里面對變量單獨記錄保存。
在多線程並發執行時,有時需要進行數據共享,所以有了volatile變量解決多線程間的數據可見性,也有了鎖的同步機制,使變量或代碼在某一時刻,只能被一個線程訪問,確保數據共享的正確性。有時不需要數據共享,讓每個線程都有自己獨立的變量,ThreadLocal就是用於線程間的數據隔離的。
24.數據庫事務有哪些特點?
-
原子性:指事務包含的所有操作要么全部成功,要么全部失敗回滾
-
一致性:事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態
-
隔離性:當多個用戶並發訪問數據庫時,不能被其他事務的操作所干擾
-
持久性:一個事務一旦被提交了,對數據庫中的數據的改變就是永久性的
-
臟讀:一個事務處理過程中,讀取了另一個未提交的事務中的數據
-
不可重復讀:對於數據庫中的某一條數據在一個事務范圍內,多次查詢卻返回了不同的數據值
-
幻讀:事務非獨立執行時發生的一種現象,例如事務T1對一個表中所有的行的某個數據項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行數據項,而這個數據項的數值還是為“1”並且提交給數據庫。而操作事務T1的用戶如果再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺一樣,這就是發生了幻讀。
25.數據庫有哪些鎖?
為了保證數據的一致性,MySQL各存儲引擎使用了三種類型的鎖機制:表級鎖定,行級鎖定和頁級鎖定
-
表級鎖:一次會將整個表鎖定,可以避免死鎖問題,鎖定力度大,鎖沖突概率高,並發度底,開銷小,獲取鎖和釋放鎖的速度很快,適用於查詢為主,少量更新
-
行級鎖:鎖定對象的力度小,發生鎖沖突概率低,並發度高,但是開銷大,加鎖慢,行級鎖容易發生死鎖。適用於對事務完整性要求較高的系統。
InnoDB行級鎖類型
- 共享鎖:讀鎖,多個事務對同一數據進行共享一把鎖,都能訪問到數據,但是只能讀不能修改
- 排它鎖:寫鎖,排他鎖指的是一個事務在一行數據加上排他鎖后,其他事務不能再在其上加其他的鎖。但可以直接通過select ...from...查詢數據,因為普通查詢沒有任何鎖機制。
- 意向鎖是InnoDB自動加的,不需用戶干預,意向鎖不會與行級的共享/排它鎖互斥
- 頁面鎖:介於行級鎖和表級鎖之間,會發生死鎖,鎖定的數據資源比行鎖要多,因為一個業種可以有多個行記錄,我們使用頁鎖的時候,會出現數據浪費的現象。
26.什么是視圖,視圖有什么作用?
存儲的查詢語句,當調用的時候,產生結果集,視圖充當的是虛擬表的角色。
簡單:使用視圖的用戶完全不需要關心后面對應的表的結構,關聯條件和篩選條件對用戶來說已經是過濾好的復合條件的結果集
安全:使用視圖的用戶只能訪問他們被允許查詢的結果集,對表的權限管理並不能限制到某個行,某個列,但是通過視圖就可以簡單的實現。
數據獨立:一旦視圖的結構確認了,可以屏蔽表結構變化對用戶的影響,源表增加列對視圖沒有影響,源表修改列名,則可以通過修改視圖來解決,不會造成對訪問者的影響
綜上,使用視圖的大部分情況是為了保障數據安全性,提高查詢效率
27.Servlet是單例還是多例,是否線程安全?如何解決安全問題?
servlet是單例的,嚴格地說是一個ServletMapping對應一個單例實例(如果一個Servlet被映射了兩個URL地址,會生成兩個實例)。線程不安全。維護Servlet線程安全通常是使用同步塊(或方法)來保護共享數據,其次可以是volatile、Lock一些鎖機制,還可以使用ThreadLocal來打通安全通道,另外還有原子操作也是用來保護數據安全
28.Spring是單例還是多例?如何配置?
spring生成的對象默認是單例的,通過scope="prototype"可以更改為多例
29. 常見的Linux命令
30. 閉包
讀取其他函數內部變量的函數,只有函數內部的子函數才能讀取局部變量,可以理解為:定義在一個函數內部的函數。本質上,閉包是將函數內部和函數外部連接起來的橋梁。
31. 分布式
計算機的一種算法,一個大型的系統往往被分為幾個子系統來做,一個子系統可以部署在一台機器的多個JVM上,也可以部署在多台機器上,但是每一個系統不是獨立的,不是完全獨立的。需要相互通信,共同實現業務功能。一句話來說:分布式就是通過計算機網絡將后端工作分布到多台主機上,多個主機一起協同完成工作。
32. 過濾器(Filter)和攔截器(Interceptor)的區別
實現原理不同:過濾器是基於函數回調的,攔截器是基於Java的反射機制(動態代理)實現的。
適用范圍不同:過濾器實現的是java.servlet.Filter接口,這個接口是在Servlet規范中定義的,也就是說過濾器Filter的使用要依賴於Tomcat等容器,導致只能在web程序中使用;攔截器是一個Spring組件,並由Spring容器管理,並不依賴Tomcat等容器,是可以單獨使用。
觸發時機不同:過濾器是在請求進入容器后,但是在進入servlet之前進行預處理,請求結果是在servlet處理完成以后;攔截器是在請求進入servlet后,在進入Controller之前進行預處理,Controller中渲染了對應的視圖之后請求結束。
攔截的請求范圍不同:過濾器幾乎可以對所有進入容器的請求起作用,而攔截器只會對Controller中請求或訪問static目錄下的資源請求起作用
33. 創建對象的五種方式
使用new關鍵字創建對象(調用了構造函數)
使用Class類的newInstance方法(調用了構造函數)
使用Constructor類的newInstance方法(調用的構造函數)
使用了clone方法(沒有調用構造函數)
使用了反序列化(沒有調用構造函數)