1、數據庫中表的別名不能用as;
2、ORACLE中左連接的sql語法:
SELECT a.id,a.name from 表名 a left join 表名 b where a.id = b.id;
3、多表查詢並求平均值
select ix.id,ix.xmmc,ip.* from INFO_XMXX ix left join (select xmid,avg(PFFZ) PJZ from INFO_PFXX group by xmid) ip on ix.id = ip.xmid;
4、JDK源碼中對於String中的equals的理解;
重寫了Object的equals的方法,先判斷兩個對象內存地址是否相等,再判斷兩個值是否相等
public boolean equals(Object anObject){
if(this == anObject){
return true;
}
if(anObject instanceOf String){
String anotherString = (String)anObject;
int n = value.length;
if(n = anotherString.value.length){
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while(n-- != 0){
if(v1[i] != v2[i]){
return false;
i ++;
}
return true;
}
}
}
return false;
}
instanceOf通過返回一個boolean值來指出,這個對象是否是這個特定類或其子類的一個實例
5、java compareTo()方法(指定的數與參數必須是同一類型)
public int compareTo(UnmberSubClass refenceName);
refenceName參數的類型是Byte、Double、Integer、Folat、Long或short類型的參數
若指定的數與參數相等則返回0;
若指定的數小於參數則返回-1;
若指定的數大於參數則返回1;
1 public class Test{ 2 Integer a = 6; 3 System.out.println(a.compareTo(6)); //0 4 System.out.println(a.compareTo(3)); //-1 5 System.out.println(a.compareTo(9)); //1 6 }
6、關於Arrays.copyOfRange()方法
Arrays.copyOfRange(T[] original,int form int to)
將一個原始數組original,從下標form開始復制,一直到下標to,生成一個新的數組
注:該新的數組包括form的下標但不包括to的下標
7、split(String regex)和split(String regex,int limit)的區別
limit > 0 則pattern(模式)應用n-1次
String str = "a,b,c": String[] c1 = str.split(",",2); System.out.println(c1.length); //2 System.out.println(Arrays.toString(c1)); //{"a","b,c"}
limit = 0 則pattern(模式)應用無限次並且省略末尾的空字符串
String str = "a,b,c,,"; String[] c2 = str.split(",",0); System.out.println(c2.lengtg); //3 System.out.println(Arrays.toString(c2)); //{"a","b","c"}
limit < 0 則pattern(模式)應用無限次
String str = "a,b,c,,"; String c3 = str.split(",",-1); System.out.println(c3.length); //5 System.out.println(Arrays.toString(c3)); //{"a","b","c","",""}
8、數據庫設計三大范式
<1> 第一范式(每一列的屬性都是不可再分的屬性值,確保每一列的原子性)
當關系模式R的所有屬性都不能再分解為更基本的數據單位時,稱R是滿足第一范式的,簡記為INF,滿足第一范式是關系模式規范化的第一要求,否則,將有很多基本操作在這樣的關系模式中實現不了。
<2>第二范式(每一行的數據都只能與其中一列相關,即一行數據只做一件事,表中的所有列都必須依賴於主鍵,而不能有任何一列與主鍵沒有關系)
如果關系模式R滿足第一范式,並且R的所有主非屬性都完全依賴於R的每一個候選關鍵屬性,稱R滿足第二范式,簡記為2NF。
<3>第三范式(數據不能存在傳遞關系,即每個屬性都與主鍵有直接關系而不是間接關系)
稱R是一個滿足第一范式條件的關系模式,X是R的任意屬性集,如果X非傳遞依賴於R的任意一個候選關鍵字,稱R滿足第三范式,簡記為3NF。
9、char類型可以存放兩個漢字嗎?
可以。因為char類型是16位,一個漢字是2個字節,一個字節是8位,所以char類型剛好可以存放兩個漢字。
10、java基本數據類型
byte | Boolean | char | int | short | float | double | long |
8位 | 1位 | 16位 | 32位 | 16位 | 32位 | 64位 |
64位 |
11、在Oracle SQL Developer中如何設置給表ID自增:
1>建序列
數據庫名——>序列——>新建序列——>
2>創建觸發器
該序列名與上面創建時的序列名一致;
3>啟動觸發器
12、ArrayList和LinkedList的區別:
對比1:
1>ArrayList與LinkedLIst的比較:
1、ArrayList是實現了基於數組的動態數據結構,因為地址連續,一旦存儲好了,查詢的效率會非常高(在內存中是連着放的)。
2、因為地址連續,插入和刪除時ArrayList需要移動數據,所以插入和刪除效率低。
3、LinkedList是基於鏈表的數據結構,地址是任意的,所以在開辟內存空間的時候不需要等一個連續的地址,對於新增和刪除操作,LinkedList效率較高。
4、因為linkedList要移動指針,所以查詢效率較低。
2>適用場景分析:
當需要對數據進行訪問的時候用ArrayList的效率比較高,當對數據進行新增和刪除的操作時,用LinkedList效率比較高。
對比二:
1>ArrayList與Vector的比較:
1、Vector的方法是同步的,都是線程安全的,而ArrayList不是,所以ArrayList的性能比Vector好。
2、當Vector或ArrayList中的元素超過它的初始大小時,Vector擴容是原來的一倍,而ArrayList則是原來的50%,所以ArrayList比Vector節約空間。
3、大多數情況不使用Vector,因為其性能不好,但其支持線程同步。
4、Vector可以設置增長因子,而ArrayList不可以。
2>使用場景
1、Vector是線程同步,所以是線程安全的,而ArrayList是線程異步的,在不考慮線程同步的情況下,建議使用ArrayList。
2、如果集合中的元素數目大於目前集合數組的長度時,在集合中使用數據量比較大的數據,Vector的優勢更大一些。
對比三:
1>HashSet與TreeSet的比較:
1、TreeSet是二叉樹實現的,其中的數據都是排好序的,所以不允許放入null值。
2、HashSet是哈希表實現的,其中的數據是無序的,可以放入null值,但只能放入一個null值,且HashSet與TreeSet中的值都不能重復。
3、HashSet要求放入的對象必須實現HashCode()方法,因為放入的對象,是以HashCode碼作為標示的,而具有相同內容的String對象,其HashCode是一樣的,所以放入的內容不能重復,但同一個類的對象可以放入不同的實例。
2>適用場景:
HashSet是基於Hash算法實現的,其性能通常由於TreeSet,所以我們通常都適用HashSet,但在做排序功能時,TreeSet的優勢大於HashSet.
對比四:
1>HashMap與concurrentHashMap的比較:
1、HashMap不是線程安全的,而concurrentHashMap是線程安全的。
2、concurrentHashMap采用鎖分段技術,將整個Hash桶進行了分段segment,也就是將這個大的數組分成了幾個小的片段segment,而且每個小的片段segment上面都有鎖存在,那么在插入元素的時候就需要先找到應該插入到哪一個分段segment,然后再在這個分段上面進行插入,而且這里還需要獲得segment鎖。
3、concurrentHashMap讓鎖的力度更精細一些,並發性能更好。
對比五:
1>HashTable與concurrentHashMap的比較:
他們都可以用於多線程的環境,但是當HashTable增加到一定的時候,性能就會急劇下降,因為迭代時需要被鎖定很長時間。而concurrentHashMap引入了分割(segmentation),無論它變得多么大,僅僅需要鎖定map的某個部分,而其他線程不需要等到迭代完成才能訪問map,性能會比HashTable好。
對比六:
1>String、StringBuffer、StringBuilder的區別:
1、運行速度對比:StringBuilder>StringBuffer>String.
2、線程安全上,StringBuffer是線程安全的,StringBuilder是線程不安全的。
2>適用場景:
1、String:適用於少量字符串操作的情況。
2、StringBuffer:適用於多線程下在字符串緩沖區進行大量操作的情況。
3、StringBuffer:適用於單線程下在字符串緩沖區進行大量操作的情況。
對比七:
1>sleep與wait的區別:
1、sleep()方法屬於Thread類,而wait()方法屬於Object類。
2、sleep()方法導致了程序直通執行指定的時間,讓出cpu給其他線程,但是它的監控狀態依然保持着,當指定的時間到了又會自動恢復運行狀態。所以在調用sleep()方法的過程中,線程不會釋放對象鎖。
3、調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()后本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態,
13、JVM的內存結構:
根據JVM規范,JVM內存共分為虛擬機棧、堆、方法區、程序計數器、本地方法棧五個部分。
1、java虛擬機棧:
線程私有;每個方法在執行的時候創新一個棧幀,存儲了局部變量表,操作數棧,動態連接,方法返回地址等;每個方法從調用到執行完畢,對應每一個棧幀在虛擬機棧中的入棧和出棧。
2、堆:
線程共享;被所有線程共享的一塊內存區域;在虛擬機啟動時創建,用於存放對象實例。
3、方法區:
線程共享;被所有線程共享的一塊內存區域;用於存儲已被虛擬機加載的類消息,常亮,靜態變量等。
4、程序計數器:
線程私有;是當前線程所執行的字節碼的行號的指示器,每條線程都有一個獨立的程序計數器,這類內存也成為"線程私有"的內存。
5、本地方法棧:
線程私有;主要為虛擬機使用到的native方法服務。
14、強引用、弱引用和軟引用的區別:
1>強引用:
只有這個對象被釋放之后,對象才會被釋放掉,只要引用存在,垃圾回收器永遠不會回收,這是常見的new出來的對象。
2>軟引用:
內存溢出之前通過代碼回收的引用。軟引用主要是用戶實現類似緩存的功能,在內存足夠的情況下直接通過軟引用取值,無需從繁忙的真實來源查詢數據,提升速度;當內存不足時,自動刪除這部分緩存數據,從真正的來源查詢數據。
3>弱引用:
第二次垃圾回收是回收的引用,短時間內通過弱引用取對應的數據,可以取到,當執行過第二次垃圾回收時,將返回null。弱引用主要用於監控對象是否已經被垃圾回收器標記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回對象是否被垃圾回收器標記。
15、GIT與SVN的區別:
1>GIT是分布式的,SVN不是。
2>GIT把內容按元數據方式儲存,SVN是按文件方式存儲。
3>GIT的分支和SVN分支不同。
4>GIT沒有一個全局的版本號,而SVN有。
5>GIT的內容完整性要優於SVN。
16、棧溢出和堆溢出的代碼:
遞歸調用可以導致棧溢出;
不斷創建對象可以導致堆溢出;
1 public class Test{ 2 public void testHeap(){ 3 for(;;){ 4 ArrayList list = new ArrayList(20000); 5 } 6 } 7 int num = 1; 8 public void testStack(){ 9 num ++; 10 this.testStack(); 11 } 12 public static void main(String[] args){ 13 Test t = new Test(); 14 t.testHeap(); 15 t.testStack(); 16 } 17 }
17、BIO、NIO和AIO的區別:
Java BIO:同步並阻塞,服務器實現模式為一個連接一個線程,即客戶端有連接請求時服務器就會啟動一個線程進行處理,如果這個連接不做任何事情就會造成不必要的線程開銷,當然可以通過線程池機制改善。
Java NIO:同步非阻塞,服務器實現模式為一個請求一個線程,即客戶端發送的連接請求都會注冊到多路復用器上,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。
Java AIO:異步非阻塞,服務器實現迷失為一個有效請求一個連接,客戶端的I/O請求都是由OS先完成了再通知服務器應用啟動線程進行處理。
NIO比BIO的改善之處是把一些無效的連接擋在了啟動線程之前,減少了這部分資源的浪費(沒創建一個線程,就要為這個線程分配一定的內存空間)
AIO比NIO的進一步改善之處是將一些暫時可能無效的連接擋在了啟動線程之前,比如在NIO的處理方式中,當一個請求來的話,開啟線程進行處理,但這個請求所需要的資源還沒有就緒,此時必須等待后端的應用資源,這時線程就阻塞了。
使用場景分析:
BIO方式適用於連接數目比較小且固定的架構,這種方式對服務器資源要求比較高,並發局限於應用中,JDK1.4以前的唯一選擇,但程序只管簡單易理解,如之前在Apache中使用。
NIO方式適用於連接數目比較多且連接比較短(輕操作)的架構,比如聊天服務器,並發局限於應用中,編程比較復雜,JK1.4開始支持,如在Nginx、Netty中使用。
AIO方式適用於鏈接數目多且連接比較長(重操作)的架構,比如相冊服務器,充分調用OS參與並發操作,編程比較復雜,JDK7開始支持,在成長中,Netty曾經使用過,后來放棄。
18、Java中的堆和棧
棧是一種具有后進先出的數據結構;
堆是一種經過排序的樹形數據結構,每個節點都有一個值。通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根節點的值是最小(或最大),且跟節點的兩個子樹也是一個堆。由於堆的這個特性,常用來實現優先隊列,堆的存取是隨意的。
為什么要划分堆和棧:
1>從軟件設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰。
2>堆與棧的分離,使得堆中的數據可以被多個棧共享,一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間。
3>棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的划分。由於棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象時可以根據需要動態增長的,因此棧和堆的拆分,使得動態增長成為可能,相應棧中只需記住堆中的一個地址即可。
4>體現了Java面向對象這一核心特點。
19、為什么要用線程池:
線程池是指在初始化一個多線程應用程序過程中創建的一個線程集合,然后在需要執行新的任何時重用這些線程而不是新建一個線程。
使用線程池的好處:
1>線程池改進了一個應用程序的響應時間。由於線程池中的線程已經准備好且等待被分配任務,應用程序可以直接拿來使用而不用新建一個線程。
2>線程池節省了CLR為每個短生命周期任務創建一個完整的線程的開銷並可以在任務完成后回收資源。
3>線程池根據當前在系統中運行的進程來優化線程時間片。
4>線程池允許我們開啟多個任務而不用我們為每個線程設置屬性。
5>線程池允許我們為正在執行的任務的程序參數傳遞一個包含狀態信息的對象引用。
6>線程池可以用來解決處理一個請求最大線程數量限制問題。
20、MySQL優化:
1>對查詢進行優化,應盡量避免全表掃描,首先應考慮在where及order by涉及的列上建立索引。
2>應盡量避免在where子句中使用!=或<>操作符,否則引擎將放棄索引而使用全表掃描。
3>盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接會逐個比較字符串中的每一個字符,而對於數字型而言只需呀比較一次就夠了。
4>任何地方都不要使用select * from t,用具體的字段列表代表"*",不要返回用不到的任何字段。
5>避免重復創建和刪除臨時表,以減少系統表資源的消耗。
21、樂觀鎖和悲觀鎖的區別以及實現方法:
悲觀鎖:一段執行邏輯加上悲觀鎖,不同線程同時執行時,只能有一個線程執行,其他線程在入口處等待,直到鎖被釋放。
樂觀鎖:一段執行邏輯加上樂觀鎖,不同線程同時執行時,可以同時進入執行,在最后更新數據時要檢查這些數據是否被其他線程修改(版本和執行初是否相同),沒有修改則進行更新,否則放棄本次操作。
22、sqls語句中的NVL用法
(1) NVL(表達式1,表達式2)
如果表達式1為空值,nvl返回值為表達式2的值,否則返回表達式1的值。表達式可以為字符型、數字型和日期型,但表達式1與表達式2的數值類型必須一致。
(2)NVL(表達式1,表達式2,表達式3)
如果表達式1為空值,則返回表達式3的值,如果表達式1不為空,則返回表達式2的值(有點類型3元表達式)
23、如何在java類中獲取javax包下的HttpServletRequest實例
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
syn(request );