Java面試-數據庫篇(一)
阿新 • • 發佈:2017-09-21
t對象 計時 具體類 分離 根據 變化 第二範式 類加載 關系
1、用兩種方式根據部門號從高到低,工資從低到高列出每個員工的信息。
1 employee:
2
3 eid,ename,salary,deptid;
4
5 select * from employeeorder by deptid desc,salary asc;
2、數據庫三範式是什麽?
第一範式(1NF):字段具有原子性,不可再分。所有關系型數據庫系統都滿足第一範式)數據庫表中的字段都是單一屬性的,不可再分。
例如,姓名字段,其中的姓和名必須作為一個整體,無法區分哪部分是姓,哪部分是名,如果要區分出姓和名,必須設計成兩個獨立的字段。
第二範式(2NF):
第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。
要求數據庫表中的每個實例或行必須可以被惟一地區分。通常需要為表加上一個列,以存儲各個實例的惟一標識。這個惟一屬性列被稱為主關鍵字或主鍵。
第二範式(2NF)要求實體的屬性完全依賴於主關鍵字。所謂完全依賴是指不能存在僅依賴主關鍵字一部分的屬性,如果存在,那麽這個屬性和主關鍵字
的這一部分應該分離出來形成一個新的實體,新實體與原實體之間是一對多的關系。為實現區分通常需要為表加上一個列,以存儲各個實例的惟一標識。
簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。
第三範式的要求如下:
滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。
所以第三範式具有如下特征:
1,每一列只有一個值
2,每一行都能區分。
3,每一個表都不包含其他表已經包含的非主關鍵字信息。
3、說出一些數據庫優化方面的經驗?
用PreparedStatement 一般來說比Statement性能高:一個sql 發給服務器去執行,涉及步驟:語法檢查、語義分析, 編譯,緩存 有外鍵約束會影響插入和刪除性能,如果程序能夠保證數據的完整性,那在設計數據庫時就去掉外鍵。(比喻:就好比免檢產品,就是為了提高效率,充分相信產品的制造商) (對於hibernate來說,就應該有一個變化:empleyee->Deptment對象,現在設計時就成了employeeàdeptid) 看mysql幫助文檔子查詢章節的最後部分,例如,根據掃描的原理,下面的子查詢語句要比第二條關聯查詢的效率高: 1.select e.name,e.salary where e.managerid=(select id from employee where name=‘zxx‘); 2.select e.name,e.salary,m.name,m.salary from employees e,employees m where e.managerid = m.id and m.name=‘zxx‘; 表中允許適當冗余,譬如,主題帖的回復數量和最後回復時間等 將姓名和密碼單獨從用戶表中獨立出來。這可以是非常好的一對一的案例喲! sql語句全部大寫,特別是列名和表名都大寫。特別是sql命令的緩存功能,更加需要統一大小寫,sql語句,發給oracle服務器,語法檢查和編譯成為內部指令,緩存和執行指令。
根據緩存的特點,不要拼湊條件,而是用?和PreparedStatment. 還有索引對查詢性能的改進也是值得關註的。
4、union和 union all有什麽不同?
UNION 在進行表鏈接後會篩選掉重復的記錄,所以在表鏈接後會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。實際大部分應用中是不會產生重復的記錄.
5、Class.forName的作用?為什麽要用?
按參數中指定的字符串形式的類名去搜索並加載相應的類,如果該類字節碼已經被加載過,則返回代表該字節碼的Class 實例對象,
否則,按類加載器的委托機制去搜索和加載該類,如果所有的類加載器都無法加載到該類,則拋出ClassNotFoundException。
加載完這個Class 字節碼後,接著就可以使用Class 字節碼的newInstance 方法去創建該類的實例對象了。 有時候,我們程序中所有使用的具體類名在設計時(即開發時)無法確定,只有程序運行時 才能確定,這時候就需要使用Class.forName 去動態加載該類,這個類名通常是在配置文 件中配置的,例如,spring 的ioc 中每次依賴註入的具體類就是這樣配置的,jdbc 的驅動類名
通常也是通過配置文件來配置的,以便在產品交付使用後不用修改源程序就可以更換驅動類名。
6、大數據量下的分頁解決方法。
最好的辦法是利用sql 語句進行分頁,這樣每次查詢出的結果集中就只包含某頁的數據內容。再sql 語句無法實現分頁的情況下,可以考慮對大的結果集通過遊標定位方式來獲取某頁的數據。
1 sql 語句分頁,不同的數據庫下的分頁方案各不一樣,下面是主流的三種數據庫的分頁sql:
2
3 sql server:
4
5 String sql ="select top" + pageSize + " * from students where id not in" +"(select top "+ pageSize * (pageNumber-1) + " id from students order by id)" +"order by id";
6
7 mysql:
8
9 String sql ="select * from students order by id limit " + pageSize*(pageNumber-1) + ","+pageSize;
10
11 oracle:
12
13 String sql ="select * from " +(select *,rownum rid from (select * from students order by postime desc) where rid<=" + pagesize*pagenumber +") as t" +
14
15 "where t>" +pageSize*(pageNumber-1);
7、用 JDBC查詢學生成績單,把主要代碼寫出來
1 Connection cn=null; 2 PreparedStatement pstmt=null; 3 ResultSet rs=null; 4 try{ 5 Class.forName(driver.ClassName); 6 cn=DriverManager.getConnection(url,username,password); 7 pstmt=cn.prepareStatement(“select score,* from score,student”+ 8 “where score.stuid=student.id and student.name=?”); 9 pstmt.setString(1,studentName); 10 11 ResultSet rs=pstmt.executeQuery(); 12 13 while(rs.next()){ 14 system.out.println(rs.getInt(“subject”) + “ ” +rs.getFloat(“score”) ); 15 } 16 }catch(Exception e){e.printStackTrace();} 17 finally 18 { 19 if(rs != null) 20 try{rs.close() }catch(exception e){} 21 if(pstmt != null) 22 try{pstmt.close()}catch(exception e){} 23 if(cn != null) 24 try{cn.close() }catch(exception e){} 25 }
8、說出數據連接池的工作機制是什麽?
J2EE 服務器啟動時會建立一定數量的池連接,並一直維持不少於此數目的池連接。客戶端程序需要連接時,池驅動程序會返回一個未使用的池連接並將其表記為忙。
如果當前沒有空閑連接,池驅動程序就新建一定數量的連接,新建連接的數量有配置參數決定。當使用的池連接調用完成後,池驅動程序將此連接表記為空閑,
其他調用就可以使用這個連接。
實現方式,返回的Connection 是原始Connection 的代理,代理Connection 的close 方法,不是真正關連接,而是把它代理的Connection 對象還回到連接池中。
9、為什麽要用ORM?和JDBC有何不一樣?
orm 是一種思想,就是把object 轉變成數據庫中的記錄,或者把數據庫中的記錄轉變成objecdt,我們可以用jdbc 來實現這種思想,
其實,如果我們的項目是嚴格按照oop 方式編寫的話,我們的jdbc 程序不管是有意還是無意,就已經在實現orm 的工作了。
現在有許多orm 工具,它們底層調用jdbc 來實現了orm 工作,我們直接使用這些工具,就省去了直接使用jdbc 的繁瑣細節,
提高了開發效率,現在用的較多的orm 工具是hibernate。也聽說一些其他orm 工具,如toplink,ojb 等。
Java面試-數據庫篇(一)