面試試題【1】
Java語言基礎部分
1 swtich語句支援的型別
byte 、short 、char 、int、 以及這幾個基本型別的包裝型別 、enum、 String(java7之後,需要1.7的編譯器才可以,而且String的值都不可以為null,因為底層使用的是”xx”.hashcode()方法)(不支援long)
2 char型變數中能不能存貯一箇中文漢字?為什麼?
當然可以,char就是表示一個字元,而一個漢字是一個字元,當然可以儲存
(這裡和一個漢字在記憶體中佔兩個位元組,而字母佔一個位元組。 不要搞混了)
3 例項初始化時,執行順序
父類靜態程式碼塊
子類靜態程式碼塊
父類非靜態程式碼塊
父類建構函式
子類非靜態程式碼塊
子類建構函式
Person p = new Person();
就是上面的順序 自己可以測試測試
Java常用類庫部分
1 String s = new String(“abc”); 這就程式碼建立了幾個物件
答:建立了兩個字串物件。程式遇到”abc”時會建立一個String物件並放入常量池,new String()又會建立一個,總共兩個
2 可以自己寫個類也叫做java.lang.String嗎?
答:當然可以,只不過不能直接使用,因為java的類載入器不會去載入你的String類
1.String類 可以繼承嗎?
答:當然不可以,因為String類是final修飾的,是終態類,不可以在有子類啦。
3 Calendar和日期格式轉換類SimpleDateFormat
Calendar是日曆類,SimpleDateFormat是日期的格式化類,他們的用途相似,但SimpleDateFormat更靈活更強大
Date date = new Date();
SimpleDateFormat format =
newSimpleDateFormat("yyyy/MM/dd");
String formatDate = format.format(date);
System.out.println(formatDate);// 2016/07/29
異常部分
1 error和exception有什麼區別?
error 表示嚴重的出錯問題,比如記憶體溢位,一般和程式碼沒有關係,即使程式碼邏輯正確也可能發生,此時程式設計師是無能為力的
exception 是可預知可控制的異常,通常發生這類異常時,程式設計師可以編碼控制是繼續執行還是結束程式
IO部分
1 說說java序列化
(1)java序列化可以把java在記憶體中的物件按照一定的格式以位元組流的方式傳輸到別的地方,如儲存到硬碟的檔案裡,或者通過網路傳輸到另一臺電腦的記憶體中
(2)java反序列化和序列化的過程相反
(3)並不是所有的java類都允許進行序列化操作,只有那些實現了Serializable介面的類才可以進行序列化操作,此介面只是一個標記介面,不提供任何方法
(4)為了解決類修改後可能產生的資料錯亂等問題,應該給實現Serializable介面的類宣告一個序列號,以標記不同版本的類,如:privatestatic final long serialVersionUID = 1L;
在配置hibernate二級快取的時候 經常會使用到。
2 說說java的IO
IO:就是指對檔案的輸入(I)、 輸出(O)的操作,javaIO流有位元組流和字元流 位元組流通過IO裝置以位元組資料的方式讀入(適合對圖片、音視訊檔案操作),而字元流則是通過位元組流讀入資料內部轉換為字元流。在Java中對這些操作都提供了相應的封裝類:
如InputStream 、OutputStream 、Reader、Writer 、BufferReader 、BufferWriter 這些都是常用的一些類。
3 你瞭解NIO嗎
Java NIO(new IO)是從java1.4版本開始引入的一個新的IO API,可以替代標準的Java IO API 。
建議大家上網查查資料,稍微瞭解一下就可以,可等工作後再去研究
集合部分
1 ArrayList和Vector的區別
主要從執行緒安全和效率上講:
Vector的方法都是同步的,是執行緒安全的,而ArrayList的方法不是,由於執行緒的同步必然會影響程式的效率,所以使用ArrayList的效能會比Vector高。
當ArrayList和Vector儲存的元素超過預定義的數量時,ArrayList會以50%的方式增長,Vector則會翻倍增長。
2 Set裡面的元素不能重複,用什麼方法判斷元素是否重複,==還是equals,有什麼區別
在set中使用equals方法去判斷(如果是自定義的類 就要重寫 equals 和hashCode 方法),
Equals會比較物件的內容,而“==” 則是比較雙方的在記憶體中的地址
3 Comparable和Comparator的區別
Comparable和Comparator都是用來實現集合中元素的比較、排序的
它們所在的包不同Comparable:java.lang Comparator:java.util
Comparable(是表明元素自身的排序規則),是在集合內部定義的方法實現的排序,Comparator是在集合外部實現的排序。 Comparator使用起來更加靈活,當對新增到集合中的元素重新指定了新的規則,不需要操作該元素中的已定義的程式碼,這時候我們可以使用Comparator比較器來改變 配合Treeset使用。 Comparable和元素有關係,而Comparator和元素沒有關係
4 TreeSet要新增一批元素,其中有父類還有子類,那新增父類的時候,呼叫的是父類的compareTo方法還是子類的,還是丟擲異常
答:當然是新增的哪個元素就呼叫哪個元素的compareTo方法,至於會不會丟擲異常,那就看程式碼怎麼實現
5 HashMap和HashTable的區別
答:父類不同
HashTable的方法是同步的(synchronized),執行緒安全的,不接受value==null,key會呼叫hashCode方法 所以 key == null 有異常
HashMap 的方法是非同步的, 效率高與HashTable key == null value ==null是允許的,
6 List和Map的區別
List是儲存元素單列方式,Map是儲存元素是鍵值對方式
List是可以儲存重複元素,而Map是不可以的
List存入元素時的順序和遍歷時的順序一致,而Map是無序的(LinkedHashMap是連結串列和map的結合體,存入和遍歷順序一致)
7 List、Set和Map,存取元素時,各有什麼特點
List 存:元素可重複、存入順序和遍歷順序一致 取:支援索引操作,速度也不慢
Set 存: 元素不可重複、存入順序和遍歷順序不一致 取:速度很快
Map 存:key不可重複、存入順序和遍歷順序不一致 取:速度很快
8 Collection和Collections的區別
作用不同,Collection表示集合,用來存取操作元素資料;Collections是工具類,提供一些工具方法操作Collection物件,完成一些特定操作,如排序、查詢、填充等
多執行緒部分
1 執行緒和程序的區別
程序是作業系統獨立呼叫的單元, 一個程序包含一個或多個執行緒,執行緒之間共享該程序中的資源,可以併發執行該程序。
執行緒是cpu直接排程的基本單位,不擁有系統資源,只是執行時候用一些必要資源暫存器 和程式計數器,棧。
2 說說socket的通訊細節
連線建立在TCP/IP協議之上
伺服器端持續監聽客戶端發來的連線請求,收到連線請求後建立連線
獲取連線的輸入流和輸出流,然後就可以進行資料交換,即通訊
關閉資源,即關閉流、socket連線
3 stop()和suspend()方法為什麼不推薦使用
答:stop()是用來直接終止執行緒,那麼如果run方法還沒有執行結束,也是會被強制結束了,應該執行的程式碼沒有被執行,導致諸多問題
suspend()掛起該執行緒直到另一個執行緒resume,但是仍然會持鎖,很容易造成死鎖。
4 Java中有幾種方法可以實現一個執行緒
在Java中提供了兩種方式:繼承Thread類、實現Runnable介面。視情況而定使用哪一種方式建立一個執行緒。
5 sleep()和wait()的區別
wait() 當前執行緒在某個鎖物件上等待一直到被notify,同時釋放同步鎖。
sleep() 當前執行緒休眠(固定時間), 但不釋放同步鎖。當休眠時間到後,就進入就緒態
6 同步和非同步有什麼區別
答:其實同步和非同步沒有關係。同步是用來保證資料供多個執行緒訪問時的安全的(資料不錯亂),而非同步通常是指瀏覽器向伺服器傳送一個請求時,不用等待伺服器的響應就可以接著做其他事,可以提高使用者的體驗(AJAX典型的運用)
7 同步有幾種實現方式
答:兩種,
(1)synchronized同步方法或同步程式碼塊,用來實現簡單的同步需求
(2)synchronized +wait()/notify() 可以實現較複雜的同步需求,比如需要多個執行緒相互配合(相互制約)的同步需求 —— 生產者消費者
8 說說Thread類的run()方法和start()方法
答:當自定義類繼承了Thread類之後,就要重寫run()方法,該方法中就是執行緒執行入口,即就是執行緒體。
start 方法用來開啟一個執行緒,之後該執行緒就進入了就緒態。
9 當執行緒A進入一個物件O1的synchronized方法後,其他執行緒是否可以進入該物件的其他方法
答:
(1)如果A執行緒沒有呼叫wait方法的話,則其他執行緒不可以進入物件O1的非靜態synchronized方法
(2)其他情況都可以
10 編碼題:設計4個執行緒,其中兩個執行緒每次對i增加1,另外兩個執行緒每次對i減少1
package com.rupeng;
public class TestThread {
public static void main(String[] args) {
Resource resource = new Resource();// 指定資源 方便共享
for (int i = 0; i < 2; i++) {
Thread incThread = new Thread(newIncrement(resource));
incThread.start();
Thread decThread = new Thread(newDecrement(resource));
decThread.start();
}
}
}
class Resource {
private int i;
public int getI() {
return i;
}
public synchronized void inc() {
i++;
}
public synchronized void dec() {
i--;
}
}
class Increment implements Runnable {
private Resource resource;
public Increment(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true) {
this.resource.inc();
}
}
}
class Decrement implements Runnable {
private Resource resource;
public Decrement(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true) {
this.resource.dec();
}
}
}
11 編碼題:有一個子執行緒和一個主執行緒,子執行緒先對i自增10次,然後主執行緒對i自增100此;接著又回到子執行緒對i自增10此...如此迴圈50次
package com.rupeng;
public class TestThread2 {
publicstatic int time = 50;
//剛開始讓子執行緒走
publicstatic void main(String[] args) {
Resource1resource1 = new Resource1();
MainThreadmain = new MainThread(resource1);
SubThreadsub = new SubThread(resource1);
ThreadmainThread = new Thread(main);
ThreadsubThread = new Thread(sub);
mainThread.start();
subThread.start();
}
}
class Resource1 {
boolean flag = false;
int i ;
}
class MainThread implements Runnable{
privateResource1 resource1;
publicMainThread(Resource1 resource1){
this.resource1= resource1;
}
@Override
publicvoid run() {
while(TestThread2.time> 0){
synchronized(resource1) {
if(!resource1.flag){
try{
resource1.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
for(intj=0;j<100;j++){
resource1.i++;
System.out.println("main"+resource1.i);
}
TestThread2.time--;
resource1.flag= false;
resource1.notify();
}
}
}
}
class SubThread implements Runnable{
privateResource1 resource1;
publicSubThread(Resource1 resource1){
this.resource1= resource1;
}
@Override
publicvoid run() {
synchronized(resource1) {
while(true){
if(resource1.flag){
try{
resource1.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
for(inti=0;i<10;i++){
resource1.i++;
System.out.println("sub"+resource1.i++);
}
TestThread2.time--;
resource1.flag= true;
resource1.notify();
}
}
}
}
12 如何給執行緒物件傳遞引數
(1)定義一個final區域性變數,讓匿名的Thread類物件訪問
(2)定義Thread子類,提供有引數的建構函式
13 如何中斷執行中的執行緒
(1)stop() 該方法已經被標註為過時方法 不建議使用,不安全
(2)run()方法執行結束,執行緒就停止了
在多執行緒程式設計時,很多都迴圈執行某個操作,只要把迴圈結束run方法很快也就結束了。可以定義一個flag來控制while迴圈,while(flag) 想結束時,將flag賦值為false,但是這樣有一個問題,如果在while迴圈體中進入了阻塞狀態,比如執行了wait方法,但是沒有呼叫notify方法來喚醒,則即使改變flag的值也無法結束執行緒,在這種情況下,就可以呼叫interrupt方法,強制性的把它從阻塞狀態 轉變為 可執行態,該方法會使wait丟擲異常,在異常處理中將flag改為false就可以結束執行緒了
(3)interrupt(): 如果說當前執行緒處於阻塞狀態,強制性的把它從阻塞狀態 轉變為 可執行態
反射和內省部分
1 說說反射的具體用法
java中一切皆物件的思想將 一個類分為Class、Constructor、Field、Method 物件
首先獲得類Class物件:Class.forName()、 Person.class 和person.getClass()
獲得所有的構造方法:Constructor[] constrs = c.getDeclaredConstructors()
建立物件 Class c = Class.forName(); c.newInstance();利用無引數構造方法
獲得所有屬性的寫法:Field[] fields = c.getDeclaredFields();
獲得指定屬性的寫法:Field idField =c.getDeclaredFields(“id”);
給指定物件的屬性賦值:Object o = c.newInstance();idField.setAccessible(true); idField.set(o,’1’); //set方法
獲得所有方法:c.getDeclaredMethods()
二進位制部分
1 用最高效的方式計算2乘以8的積
答:2 << 3 cpu可以很快的作出左移運算。
垃圾回收
1 GC是什麼?為什麼要有GC?
答:GC 是指垃圾回收,JVM中有專門的執行緒負責垃圾回收。我們建立的物件儲存在堆記憶體中,Java有多套規則可以判斷一個物件是否是垃圾,是否應該被回收
Java中的垃圾回收可以讓程式設計師專注於業務邏輯程式碼,而不用考慮資料回收等繁瑣問題
2 Java的垃圾回收可以馬上回收記憶體嗎,有什麼方法通知虛擬機器進行垃圾回收
答:Java使用專門的執行緒進行垃圾回收,執行緒的排程決定了一個物件變為垃圾後不會立馬就被回收
Java中提供了System.gc() 方法來通知JVM儘快回收,但也不是立馬回收
Java記憶體
1 Java中會存在記憶體洩露嗎
答:存在。
記憶體洩露指的是:沒用的記憶體不被回收導致記憶體的浪費。雖然說GC會幫我們釋放無用物件佔用的記憶體,但是GC只會釋放沒有任何引用的物件,如果一個物件已經沒用了,但是由於我們程式碼的問題導致整個物件一直被引用,它佔據的記憶體就遲遲不能被回收,就會造成記憶體洩露了。
資料庫部分
1 資料庫儲存過程的關鍵字是什麼
答:procedure
2 有students學生表如下,
id name age salary
1 yzk 80 1000
2 yzk 80 2000
3 tom 20 20000
4 tom 20 20000
5 im 20 20000
(1)查詢學生的資訊, 若有姓名、年齡重複的記錄,則保留Id最大的一條(常考!!!)
(2)刪除多餘的記錄(姓名,年齡重複),保留id最大的記錄
(3)查詢salary最高的前3人
答:
(1)
select * from students
where id in
(
select max(id)
from students
group by name,age
)
思路:根據姓名、年齡分組,取出每組的Id最大值,然後將Id最大值之外的排除。最後按照id查詢出來就可以了。
(2)
delete from Persons
where id not in
( select max(id)
from Persons
group by name,age
)
上面的方法不在mysql中不支援;可以使用折中的方法
CREATE TABLE tmp AS SELECT MAX(id) ASid FROM students GROUP BY NAME ,age
DELETE FROM students WHERE id NOT IN(SELECT id FROM tmp)
3 left join、rightjoin、inner join 的區別
答:左連線:以左表為參照表,最終結果是含有左表所有的 如果右表沒有對應的則結果中為null
右連線相反
等值連線:匹配兩個表中的相等條件的那些記錄。
4 delete與truncate的區別
答:
delete 後面可以寫where條件刪除一部分資料;truncate不可以加where條件,只能刪除所有資料;
在事務中,如果rollback,delete的資料是可以回滾的,而truncate的資料無法回滾。
delete會執行觸發器,truncate不會執行觸發器;
truncate執行速度比delete快
5 簡單說說資料庫三正規化
(1)第一正規化(1NF):欄位不可再分,這是關係型資料庫最基本的要求
(2)第二正規化(2NF):要求表要有主鍵,每一行都是唯一的
(3)第三正規化(3NF):一張表引用另外一張表的時候引用這張表的主鍵
6 union和unionall 的區別
答:union會自動合併多個結果集合中的重複結果,而union all則將所有的結果全部顯示出來,不管是不是重複。
7 有一張成績表grade( studentId, courseId, score ) ,查詢出每門課程都大於80分的學生的學號
只要最小的大於80 就可以了:
select studentId from grade group bystudentId having min(score) >=80
select studentId from grade group bystudentId having studentId not in (
select studentId from grade where score < 80
)
8 sql面試
表employees的結構:
create table employees (
employee_id int primary key,
first_name varchar(25),
last_name varchar(25),
salary double,
hired_date date,
department_id int
)
表departments的結構
create table departments (
department_id int primary key,
department_name varchar(25)
)
(1)查詢出工資在[1000,2000]之間,或者員工姓名(last_name)以'Tim'打頭的員工的全部個人資訊。
select * from employees
where (salary between 1000 and 2000)or (last_name like 'Tim%');
(2)查詢出部門平均工資大於1800元的部門的所有員工,列出這些員工的全部個人資訊。
(思路:先把平均工資大於1800的部門查出來 , 再看員工的部門是否在其中)
select * from employees
where department_id in (
select department_id
from employees
group by department_id
having avg(salary) > 1800
)
select * from e where deid in
select depareid avg(salr) from e group by deid having avg() > 1800
(3)查詢出個人工資高於其所在部門平均工資的員工,列出這些員工的全部個人資訊。
select e1.*
from employees as e1
where e1.salary >(
select AVG(e2.salary)
from employees as e2
where e1.department_id=e2.department_id
)
select * from e where di in
select did,avg(salary) from e group bydid having
avg(sary) < s
(4) 基於上述employees 表寫出查詢:查出個人工資高於其所在部門平均工資的員工,列出這些員工的全部個人資訊及該員工工資高出部門平均工資百分比。
select e1.* , (e1.salary-tmp.avgsalary)*100/tmp.avgsalaryas "高出平均工資百分比"
from employees as e1, (
select department_id, avg(salary) avgsalary
from employees
group by department_id ) as tmp
where e1.salary > tmp.avgsalary ande1.department_id=tmp.department_id
9 如何把sql語句寫的美觀漂亮
答:合理縮排。統一關鍵字,適當註釋
10
(1) 某工廠產品價格單價在不同的訂單下價格可能不同,一個訂單包含若干產品,與如鵬客戶成交有若干訂單。
要求 以表格的方式畫出相應的資料庫表結構,並寫出查詢與該客戶成交的所有訂單和每個訂單的總價的sql語句
(2)寫出一個JDBC程式,對訂單表批量插入3條記錄
package com.rupeng;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException,SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
PreparedStatement ps = null;
try {
conn =DriverManager.getConnection("jdbc:mysql://localhost/study1?characterEncoding=UTF8","root", "root");
conn.setAutoCommit(false);
ps =conn.prepareStatement("INSERT into orders (ordersId,customerId,ordertime)values(?,?,?)");
for (int i = 0; i < 3; i++) {
ps.clearParameters();
ps.setString(1,"orders" + i);
ps.setString(2,"customer" + i);
ps.setInt(3, 10);
ps.addBatch();
}
ps.executeBatch();
conn.commit();
} finally {
// 關閉資源的操作
}
}
}
11 mysql和oracle分頁上有什麼區別?
mysql : 使用limitindex,len 從index開始取一共取len個
oracle:使用rownum偽列方式
12 oracle常用的函式
sysdate、to_char()、 to_date() 、LOWER 、UPPER、 SUBSTR 、REPLACE、TRIM 、ROUND 、NVL將空值轉換成一個已知的值
13 dual 是一個‘偽表’,可以用來測試函式和表示式,試舉例說明
select 1+1 sum from dual;
select sum1(1,2) from dual;
14 說說資料庫優化方面的經驗
儘量不要使用select *
儘可能把多條sql合併成一條
儘可能多的使用between and
把可以過濾大量資料的where條件放在後面
使用帶有佔位符的sql語句
前端web部分
1 HTML 的 form 提交之前如何驗證數值文字框的內容不空且全部為數字? 否則的話提示使用者並終止提交?
答:
<scripttype="text/javascript">
document.getElementById("form01").onsubmit=function(){
var value = document.getElementById("phone").value;
//如果value為空
if(!value){
alert("手機號不能為空");
return false;
}
for(vari=0;i<value.length;i++){
var ch = value.charAt(i);
//字串直接比較時是按字典順序進行比較的
if(ch<"0" ||ch>"9"){
alert("只能輸入數字");
return false;
}
}
}
</script>
2 用js動態建立一個元素,不用jquery
答:
<scripttype="text/javascript">
window.onload=function(){
var divObj =document.createElement("div");
divObj.innerHTML="hello";
document.body.appendChild(divObj);
}
</script>
3 jquery獲取文字框的內容用什麼,獲取span的內容用什麼
答:
文字框內容是文字框value屬性的值,使用val()函式獲取
span內容是是span標籤體的內容,使用html()函式獲取
4 ajax不用jquery的建立方式怎麼建立?
答:
<scripttype="text/javascript">
var xmlHttp;
if( window.XMLHttpRequest ){
xmlHttp = new XMLHttpRequest();
}else{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var data = xmlHttp.responseText;
//...
}
}
xmlHttp.open("GET","url",true);
xmlHttp.send("name=rupeng");
</script>
5 js如何建立一個物件
(1)使用new關鍵字建立
new String("abc");
newFunction("x","alert(x)");
new Object();
(2)使用JSON語法建立
var obj = { };
6 ajax都有什麼請求方式
有get和post
7 jQuery中如何獲得你想要操作的元素
(1)使用jQuery的選擇器
(2)使用jQuery函式,如next()、nextAll()、prev()、siblings()
Javaweb部分
1 說說servlet工作的原理
答:
(1)伺服器啟動時解析web.xml,把servlet的虛擬路徑管理起來
(2)伺服器收到瀏覽器的請求後,就把請求解析為request物件,同時建立一個response物件
(3)伺服器根據請求路徑找到匹配的servlet,呼叫servlet對應的doGet或者doPost方法,同時把request和response傳遞給該方法
(4)servlet就開始對請求進行處理,處理完成後生成響應傳送到瀏覽器
2 GET和POST提交方式的區別
答:
(1)GET方式的請求把請求引數拼接在請求路徑後面,在有些時候(如超連結上)特別方便,但這種方式所能攜帶的資料量有限,並且可以被直接看到,不太安全
(2)POST方式把請求引數放在請求體中,可以攜帶大量資料,並且安全性相對較高
7 request.getAttribute()和request.getParameter()有何區別?
答:第一種是獲得程式單獨存放在reuqest中的值
第二種是獲得請求引數的值
8 jsp有哪些內建物件?作用分別是什麼?分別有什麼主要方法?
答:JSP共有以下9個內建的物件:
request 請求物件,包含所有客戶端請求資訊
response 響應物件
pageContext 頁面上下文物件,可以通過該物件獲取其他內建物件
session session物件
application ServletContext物件
out 輸出流物件,用來把響應輸出到客戶端
config ServletConfig物件
page JSP頁面本身,即this
exception 異常物件,如果此JSP頁面被設定為錯誤頁面,則此物件可用,表示發生的異常
9 JSP的常用指令
語法: <%@ 指令名稱 屬性名稱="值" 屬性名稱="值"... %>
page 指令整個jsp頁面配置
include 指令 包含目標資源
taglib 指令 標籤庫使用指令
<%@ taglib uri=”/struts-tags”prefix=”s” %>
10 JSP和Servlet有哪些相同點和不同點,他們之間的聯絡是什麼?
答:
JSP本質是就是Servlet(JSP會被編譯成Servlet),但分工不同。Servlet負責處理業務邏輯,生成處理結果,JSP負責生成頁面,把處理結果顯示給使用者
11 對JSP熟悉嗎?能說一些他的優缺點嗎?
答:
JSP本質上是Servlet,但專門用來生成頁面,把Servlet處理結果顯示給使用者。要說優點的話就是可以配合EL和自定義標籤,非常方便就可以生成頁面,缺點的話就是不方便除錯吧,但JSP中的邏輯簡單,一般不會出錯
12 MVC的各個部分都有些技術來實現?如何實現
答:MVC是Model--View-Controller簡寫
Model指資料模型,用來攜帶資料以及操作資料庫,但在javaweb中已經弱化了Model
View表示檢視,用來把資料展示給使用者,在javaweb中使用JSP作為View
Controller表示控制器,控制業務邏輯,在javaweb中使用Servlet作為Controller
13 說出資料連線池的工作機制是什麼?
答:
(1)程式啟動時連線池就建立好若干資料庫連線並儲存起來
(2)當用戶需要連線時,直接從連線池中獲取連線
(3)當用戶本次使用連線完畢後,就把連線歸還給連線池
(4)假設在沒有空閒連線時使用者A來獲取連線,如果當前連線數小於最大連線數,則連線池建立新的連線並交給A;如果當前連線數達到最大連線數,則連線池不再建立新的連線,而是等待其他使用者歸還連線,再把歸還的連線交給A
14 購物車和訂單的具體實現
答:
(1)購物車資訊儲存在session中,包含若干個購物車項資訊,每個購物車項就是使用者購買的某個商品的資訊以及購買數量
(2)訂單資訊根據購物車生成,再加上收貨地址等資訊。訂單中包含若干訂單項,訂單項即對應購物車中的購物車項,也是使用者購買的商品資訊以及數量
SSH部分
1、談談你對struts2的理解。
(1) strust2的優缺點
優點:
把一般的處理流程步驟化:引數自動型別轉換、引數值有效性檢驗、處理結果導航
有比el表示式更強大的ognl表示式,再配合struts的自定義標籤,使得頁面資料顯示非常方便
提供了強大的攔截器,可以定製個性化的需求處理流程
執行緒安全,因為每次請求都會產生一個action物件以及和action相關的物件
耦合度低,降低編碼複雜度
缺點:
由於太過強大和典型,一般的小白玩不轉,所以對於水平不高的程式設計師來說太過複雜,控制不了,屬於重量級框架。
(2)struts2請求處理流程
客戶端傳送請求到伺服器後, 請求被struts2核心過濾器”捕獲”
請求經過一系列攔截器的攔截處理最終到達匹配的action
action呼叫業務邏輯層執行業務,完成後返回一個字串
struts2引擎根據配置資訊和字串 , 把請求導航到某個資源生成響應
你對struts可能還有自己的應用方面的經驗,那也要一併說出來。
2 談談你對hibernate的理解。
(1)java是面向物件的,操作的習慣是直接對 物件進行操作;現在主流的資料庫是關係型的,操作的習慣是對關係表進行操作。Java程式碼要想訪問資料庫獲取或者儲存資料,就需要使用一箇中間媒介:JDBC。由於是java通過JDBC去操作資料庫,所以JDBC程式設計時程式碼的風格並不是面向物件的風格,這樣就會導致JDBC的程式碼量很多而且很複雜不方便。這對於中小型專案來說勉強可以接受,但對於大型專案能把程式設計師逼瘋。
(2)一個新技術的出現往往是解決現有技術的缺點,hibernate就屬於這樣。Hibernate通過封裝JDBC,使用orm思想把程式對物件的操作自動的對映成對關係資料庫的操作,從而使java訪問資料庫的編碼更符合面向物件的操作習慣,而且簡化了很多複雜操作
(3)hibernate對資料庫操作的封裝十分完善,從而功能異常強大,但這也不得不增加hibernate自身的複雜度,也就增加了學習的成本。一般來說很多程式設計師很難很好的掌握hibernate,所以現在很多企業使用hibernate時主要使用hibernate管理物件和表之間的對映,而表和表之間的各種關聯關係特別是多對多關係則用的很少,而是使用普通的JDBC方式去解決表和表之間的關聯關係
(4)使用Hibernate的基本流程是:配置核心hibernate.cfg.xml核心配置檔案、配置物件和表之間的對映檔案xxx.hbm.xml、建立SessionFactory核心物件、建立session物件,啟動事務,完成CRUD操作,提交事務,關閉session。
(5)還需要特別說一下的就是hibernate的快取,有session級別的一級快取還有sessionfactory級別的二級快取。可以很好的提高訪問資料庫的效率
3 為什麼要用ORM? 和 JDBC 有何不一樣?
答:因為現在主流的資料庫都是面向關係型的,對於使用java操作起來很不方便,這樣就把Class類和資料庫中的表進行了關聯,一個物件對應一條記錄,這樣我們就能夠以面向物件的程式設計思想去操作資料庫,這就是ORM。
JDBC是面向sql的連線資料庫技術,操作起來不方便。
ORM是對JDBC進行了封裝,我們只需使用該框架提供的介面程式設計。
4 hibernate中的update()和saveOrUpdate()的區別,session的load()和get()的區別。
答:update()只能執行更新的操作,而使用saveOrUpdate()的時候,如果該domain物件中含 有id,那麼就是執行更新操作,否則即使插入操作。
session中load()方法,當資料庫中不存在與OID對應的記錄時,load丟擲異常,而get()返回null
5 簡述hibernate 和 JDBC 的優缺點?
(1)hibernate是JDBC的重量級封裝,用來解決JDBC程式設計時的缺點,比如JDBC操作是非面向物件風格的,JDBC編碼是很複雜等
(2)既然hibernate是對JDBC的封裝,那hibernate的開發效率很高,而且方便管理維護。但操作資料庫的效率就沒有JDBC高了,不過hibernate提供了兩級快取,也很可觀的提高了操作資料庫的效率
6 簡單說說hibernate和JDBC的相同點和不同點
相同點:
(1)兩者都是JAVA的資料庫操作中介軟體。
(2)兩者對於資料庫進行直接操作的物件都不是執行緒安全的,都需要及時關閉。
(3)兩者都可以對資料庫的更新操作進行顯式的事務處理。
不同點:
(1)使用的SQL語言不同:JDBC使用的是基於關係型資料庫的標準SQL語言,而hibernate既可以直接操作物件,也可以使用HQL(Hibernate querylanguage)語言,也可以使用sql語言
(2)操作的東西不同:JDBC操作的是基本資料,hibernate操作的java物件
(3)資料狀態不同:JDBC操作的資料是“瞬時”的,變數的值無法與資料庫中的值保持一致,而hibernate操作的資料是可持久的,即持久化物件的資料屬性的值是可以跟資料庫中的值保持一致的。
7 寫hibernate的一對多和多對一雙向關聯的orm配置?
答:
1、在一段的domain中定義Set型別(a) 儲存多端集合物件元素,同時在一端hbm.xml中配置
<set name=”a” inverse=”true”cascade=”all” lazy=”false” >
<keycolumn=”idkey”></key>
<one-to-many class=”全路徑多端類” />
</set>
2、
在多端的domain中定義一端型別(b),同時在多端hbm.xml中配置
<many-to-one name=”b” class=”全路徑一端類” column=” idkey”></many-to-one>
8 hibernate的inverse屬性的作用?
答:inverse是hibernate雙向關係中的基本概念。inverse的真正作用就是指定由哪一方來維護之間的關聯關係。當一方中指定了“inverse=false”(預設),那麼那一方就有責任負責之間的關聯關係,說白了就是hibernate如何生成Sql來維護關聯的記錄
補充:inverse與cascade 的比較:
inverse:負責控制關係,預設為false,也就是關係的兩端都能控制,但這樣會造成一些問題,更新的時候會因為兩端都控制關係,於是重複更新。一般來說有一端要設為true。
cascade:負責控制關聯物件的級聯操作,包括更新、刪除等,也就是說對一個物件進行更新、刪除時,其它物件也受影響,比如我刪除一個物件,那麼跟它是多對一關係的物件也全部被刪除。
例如刪除“一”那一端一個物件O的時候,如果“多”的那一端的Inverse設為true,則把“多”的那一端所有與O相關聯的物件外來鍵清空;如果“多”的那一端的Cascade設為Delete,則把“多”的那一端所有與O相關聯的物件全部刪除。
9 hibernate進行多表查詢每個表中各取幾個欄位,也就是說查詢出來的結果集沒有一個實體類與之對應如何解決;
(這裡說的並不是把這些資料都封裝到一個物件裡面)
解決方案一,按照Object[]資料取出資料,然後自己組bean
解決方案二,對每個表的bean寫建構函式,比如表一要查出field1,field2兩個欄位,那麼有一個建構函式就是Bean(type1filed1,type2 field2) ,然後在hql裡面就可以直接生成這個bean了
10 hibernate load和get什麼區別?
get和load的根本區別,一句話,hibernate對於load方法認為該資料在資料庫中一定存在,可以放心的使用代理來延遲載入,如果在使用過程中發現了問題,只能拋異常;而對於get方法,hibernate一定要獲取到真實的資料,否則返回null
11 介紹一下Hibernate的二級快取
按照以下思路來回答:(1)首先說清楚什麼是快取,(2)再說有了hibernate的Session就是一級快取,即有了一級快取,為什麼還要有二級快取,(3)最後再說如何配置Hibernate的二級快取。
(1)快取就是把以前從資料庫中查詢出來和使用過的物件儲存在記憶體中(一個數據結構中),這個資料結構通常是或類似Hashmap,當以後要使用某個物件時,先查詢快取中是否有這個物件,如果有則使用快取中的物件,如果沒有則去查詢資料庫,並將查詢出來的物件儲存在快取中,以便下次使用。下面是快取的虛擬碼:
(2)hibernate的session裡面有快取,我們通常將之稱為一級快取。當想使用session從資料庫中查詢出一個物件時,session先從自己內部檢視是否存在這個物件,存在則直接返回,不存在才去訪問資料庫,並將查詢的結果儲存在自己內部。由於session代表一次會話過程,一個session與一個數據庫連線相關連,所以session最好不要長時間保持開啟,通常僅用於一個事務當中,在事務結束時就應關閉。並且session是執行緒不安全的,被多個執行緒共享時容易出現問題。通常只有那種全域性意義上的快取才是真正的快取應用,才有較大的快取價值,因此,hibernate的session這一級快取的快取作用並不明顯,應用價值不大。hibernate的二級快取就是要為hibernate配置一種全域性快取,讓多個執行緒和多個事務都可以共享這個快取。我們希望的是一個人使用過,其他人也可以使用,session沒有這種效果。