Java面試3

7忱详、寫一個 Singleton 出來。

第一種:飽漢模式

public classSingleTon {

private SingleTon(){

}

//實(shí)例化放在靜態(tài)代碼塊里可提高程序的執(zhí)行效率挠进,但也可能更占用空間

private final static SingleTon instance =new SingleTon();

public static SingleTon getInstance(){

return instance;

}

}

第二種:饑漢模式

public classSingleTon {

private SingleTon(){}

private static instance = null;//newSingleTon();

public static synchronized SingleTongetInstance(){

if(instance == null)

instance = new SingleTon();

return instance;

}

}

第三種:用枚舉

public enum SingleTon{

ONE;

}

第三:更實(shí)際的應(yīng)用(在什么情況用單例)

public classSequenceGenerator{

//下面是該類自身的業(yè)務(wù)功能代碼

private int count = 0;

public synchronized int getSequence(){

++count;

}

//下面是把該類變成單例的代碼

private SequenceGenerator(){}

private final static instance = newSequenceGenerator();

public static SingleTon getInstance(){

return instance;

}

}

第四:

public class MemoryDao

{

private HashMap map = new HashMap();

publicvoid add(Student stu1){

map.put(SequenceGenerator.getInstance().getSequence(),stu1);

}?

//把 MemoryDao 變成單例

}

Singleton 模式主要作用是保證在 Java 應(yīng)用程序中,一個類 Class 只有一個實(shí)例存在唯笙。

一般 Singleton 模式通常有幾種種形式:

第一種形式: 定義一個類姜凄,它的構(gòu)造函數(shù)為 private 的,它有一個 static 的 private 的該類變

量坛芽,在類初始化時實(shí)例話留储,通過一個 public 的 getInstance 方法獲取對它的引用,繼而調(diào)用其

中的方法翼抠。

public class Singleton {

private Singleton(){}

//在自己內(nèi)部定義自己一個實(shí)例,是不是很奇怪获讳?

//注意這是 private 只供內(nèi)部調(diào)用

private staticSingleton instance = new Singleton();

//這里提供了一個供外部訪問本 class 的靜態(tài)方法阴颖,可以直接訪問

public staticSingleton getInstance() {

return instance;

}

}

第二種形式:

public class Singleton {

private static Singleton instance = null;

public static synchronized Singleton getInstance() {

//這個方法比上面有所改進(jìn),不用每次都進(jìn)行生成對象丐膝,只是第一次

//使用時生成實(shí)例量愧,提高了效率!

if (instance==null)

instance=new Singleton();

return instance;

}

}

其他形式:

定義一個類帅矗,它的構(gòu)造函數(shù)為 private 的偎肃,所有方法為 static 的。

一般認(rèn)為第一種形式要更加安全些

8浑此、遞歸算法題 1

一個整數(shù)累颂,大于0,不用循環(huán)和本地變量尤勋,按照 n喘落,2n,4n最冰,8n 的順序遞增瘦棋,當(dāng)值大于5000

時,把值按照指定順序輸出來暖哨。

例:n=1237

則輸出為:

1237赌朋,

2474,

4948篇裁,

9896沛慢,

9896,

4948达布,

2474团甲,

1237,

提示:寫程序時黍聂,先致謝按遞增方式的代碼躺苦,寫好遞增的以后,再增加考慮遞減部分产还。

public static void doubleNum(int n)

{

System.out.println(n);

if(n<=5000)

doubleNum(n*2);

System.out.println(n);

}

Gaibaota(N) = Gaibaota(N-1) + n

9匹厘、遞歸算法題 2

第1個人10,第2個比第1個人大2歲脐区,依次遞推愈诚,請用遞歸方式計算出第8個人多大?

package cn.itcast;

import java.util.Date;

publicclass A1 {

public static voidmain(String [] args)

{

System.out.println(computeAge(8));

}

public static int computeAge(intn)

{

if(n==1)return 10;

returncomputeAge(n-1) + 2;

}

}

public static voidtoBinary(int n,StringBuffer result)

{

if(n/2 != 0)

toBinary(n/2,result);

result.append(n%2);

}

10、排序都有哪幾種方法炕柔?請列舉酌泰。用 JAVA 實(shí)現(xiàn)一個快速排序。

本人只研究過冒泡排序汗唱、選擇排序和快速排序宫莱,下面是快速排序的代碼:

public class QuickSort {

/**

* 快速排序

* @param strDate

* @param left

* @param right

*/

public void quickSort(String[] strDate,int left,int right){

String middle,tempDate;

int i,j;

i=left;

j=right;

middle=strDate[(i+j)/2];

do{

while(strDate[i].compareTo(middle)<0&& i<right)

i++; //找出左邊比中間值大的數(shù)

while(strDate[j].compareTo(middle)>0&& j>left)

j--; //找出右邊比中間值小的數(shù)

if(i<=j){ //將左邊大的數(shù)和右邊小的數(shù)進(jìn)行替換

tempDate=strDate[i];

strDate[i]=strDate[j];

strDate[j]=tempDate;

i++;

j--;

}

}while(i<=j); //當(dāng)兩者交錯時停止

if(i<right){

quickSort(strDate,i,right);//從

}

if(j>left){

quickSort(strDate,left,j);

}

}

/**

* @param args

*/

public static void main(String[] args){

String[] strVoid=newString[]{"11","66","22","0","55","22","0","32"};

QuickSort sort=new QuickSort();

sort.quickSort(strVoid,0,strVoid.length-1);

for(int i=0;i<strVoid.length;i++){

System.out.println(strVoid[i]+" ");

}

}

}

11丈攒、有數(shù)組 a[n]哩罪,用 java 代碼將數(shù)組元素順序顛倒

//用下面的也可以

//for(inti=0,int j=a.length-1;i<j;i++,j--)是否等效于 for(int i=0;i<a.length/2;i++)呢?

importjava.util.Arrays;

public classSwapDemo{

public static void main(String[] args){

int [] a = new int[]{

(int)(Math.random() *1000),

(int)(Math.random() * 1000),

(int)(Math.random() *1000),

(int)(Math.random() *1000),

(int)(Math.random() * 1000)

};

System.out.println(a);

System.out.println(Arrays.toString(a));

swap(a);

System.out.println(Arrays.toString(a));

}

public static void swap(int a[]){

int len = a.length;

for(int i=0;i<len/2;i++){

int tmp = a[i];

a[i] = a[len-1-i];

a[len-1-i] = tmp;

}

}

}

12.金額轉(zhuǎn)換巡验,阿拉伯?dāng)?shù)字的金額轉(zhuǎn)換成中國傳統(tǒng)的形式如:(¥1011)->(一

千零一拾一元整)輸出际插。

去零的代碼:

returnsb.reverse().toString().replaceAll("零[拾佰仟]","零").replaceAll("零+萬","萬

").replaceAll("零+元","元").replaceAll("零+","零");

public class RenMingBi {

/**

* @param args add by zxx ,Nov 29, 2008

*/

private static finalchar[] data = new char[]{

'零','壹','貳','叁','肆','伍','陸','柒','捌','玖'

};

private static finalchar[] units = new char[]{

'元','拾','佰','仟','萬','拾','佰','仟','億'

};

public static voidmain(String[] args) {

// TODOAuto-generated method stub

System.out.println(

convert(135689123));

}

public static Stringconvert(int money)

{

StringBuffersbf = new StringBuffer();

int unit = 0;

while(money!=0)

{

sbf.insert(0,units[unit++]);

intnumber = money%10;

sbf.insert(0,data[number]);

money/= 10;

}

returnsbf.toString();

}

}

三. html&JavaScript&ajax 部分

1. 判斷第二個日期比第一個日期大

如何用腳本判斷用戶輸入的的字符串是下面的時間格式2004-11-21必須要保證用戶

的輸入是此格式,并且是時間显设,比如說月份不大于12等等框弛,另外我需要用戶輸入兩個,并

且后一個要比前一個晚捕捂,只允許用 JAVASCRIPT瑟枫,請詳細(xì)幫助作答,,

//這里可用正則表達(dá)式判斷提前判斷一下格式指攒,然后按下提取各時間字段內(nèi)容

<script type="text/javascript">

window.onload =function()

{

//這么寫是為了實(shí)現(xiàn) js 代碼與 html 代碼的分離慷妙,當(dāng)我修改 js 時,不能影響 html 代

碼允悦。

document.getElementById("frm1").onsubmit=

function(){

vard1 = this.d1.value;

vard2 = this.d2.value;

if(!verifyDate(d1)) {alert("第一個日期格式不對");return false;}

if(!verifyDate(d2)) {alert("第二個日期格式不對");return false;}

if(!compareDate(d1,d2)){alert("第二個日期比第一日期小");return

false;}

};

}

functioncompareDate(d1,d2)

{

var arrayD1= d1.split("-");

var date1 =new Date(arrayD1[0],arrayD1[1],arrayD1[2]);

var arrayD2= d2.split("-");

var date2 =new Date(arrayD2[0],arrayD2[1],arrayD2[2]);

if(date1> date2) return false;

return true;

}

functionverifyDate(d)

{

vardatePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/;

returndatePattern.test(d);

}

</script>

<form id="frm1" action="xxx.html">

<input type="text" name="d1" />

<input type="text" name="d2" />

<input type="submit"/>

</form>

2. 用 table 顯示 n 條記錄膝擂,每 3 行換一次顏色,即 1隙弛,2架馋,3 用紅色字體,4全闷,5叉寂,

6 用綠色字體,7总珠,8屏鳍,9 用紅顏色字體。

<body>

<table id="tbl">

<tr><td>1</td></tr>

<tr><td>2</td></tr>

<tr><td>3</td></tr>

<tr><td>4</td></tr>

<tr><td>5</td></tr>

<tr><td>6</td></tr>

<tr><td>7</td></tr>

<tr><td>8</td></tr>

<tr><td>9</td></tr>

<tr><td>10</td></tr>

</table>

</body>

<script type="text/javascript">

window.onload=function()

{

var tbl =document.getElementById("tbl");

rows =tbl.getElementsByTagName("tr");

for(i=0;i<rows.length;i++)

{

var j= parseInt(i/3);

if(j%2==0)rows[i].style.backgroundColor="#f00";

else rows[i].style.backgroundColor="#0f0";

}

}?

</script>

3姚淆、HTML 的 form 提交之前如何驗(yàn)證數(shù)值文本框的內(nèi)容全部為數(shù)字?否則的話

提示用戶并終止提交?

<form onsubmit=’return chkForm(this)’>

<input type="text" name="d1"/>

<input type="submit"/>

</form>

<script type=”text/javascript” />

function chkForm(this)

{

var value = thist.d1.value;

var len =value.length;

for(vari=0;i<len;i++)

{

if(value.charAt(i)>"9"|| value.charAt(i)<"0")

{

alert("含有非數(shù)字字符");

returnfalse;

}

}

return true;

}

</script>

4孕蝉、請寫出用于校驗(yàn) HTML 文本框中輸入的內(nèi)容全部為數(shù)字的 javascript 代碼

<input type="text" id="d1" onblur=" chkNumber(this)"/>

<script type=”text/javascript” />

function chkNumber(eleText)

{?

var value =eleText.value;

var len =value.length;

for(vari=0;i<len;i++)

{

if(value.charAt(i)>"9"|| value.charAt(i)<"0")

{

alert("含有非數(shù)字字符");

eleText.focus();

break;

}

}

}

</script>

除了寫完代碼,還應(yīng)該在網(wǎng)頁上寫出實(shí)驗(yàn)步驟和在代碼中加入實(shí)現(xiàn)思路腌逢,讓面試官一看就明

白你的意圖和檢查你的結(jié)果降淮。

5、說說你用過那些 ajax 技術(shù)和框架,說說它們的區(qū)別

四. Java web 部分

1佳鳖、Tomcat 的優(yōu)化經(jīng)驗(yàn)

答:去掉對 web.xml 的監(jiān)視霍殴,把 jsp 提前編輯成 Servlet。

有富余物理內(nèi)存的情況系吩,加大 tomcat 使用的 jvm 的內(nèi)存

2来庭、HTTP 請求的 GET 與 POST 方式的區(qū)別

答:servlet 有良好的生存期的定義,包括加載和實(shí)例化穿挨、初始化月弛、處理請求以及服務(wù)結(jié)束。

這個生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表達(dá)科盛。

3帽衙、解釋一下什么是 servlet;

答:servlet 有良好的生存期的定義,包括加載和實(shí)例化贞绵、初始化厉萝、處理請求以及服務(wù)結(jié)束。

這個生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表達(dá)榨崩。

4谴垫、說一說 Servlet 的生命周期?

答:servlet 有良好的生存期的定義,包括加載和實(shí)例化母蛛、初始化翩剪、處理請求以及服務(wù)結(jié)束。

這個生存期由 javax.servlet.Servlet 接口的 init,service 和 destroy 方法表達(dá)溯祸。

Servlet 被服務(wù)器實(shí)例化后肢专,容器運(yùn)行其 init 方法,請求到達(dá)時運(yùn)行其 service 方法焦辅,service

方法自動派遣運(yùn)行與請求對應(yīng)的 doXXX 方法(doGet博杖,doPost)等,當(dāng)服務(wù)器決定將實(shí)例

銷毀的時候調(diào)用其 destroy 方法筷登。

web 容器加載 servlet剃根,生命周期開始。通過調(diào)用 servlet 的 init()方法進(jìn)行 servlet 的初始化前方。

通過調(diào)用 service()方法實(shí)現(xiàn)狈醉,根據(jù)請求的不同調(diào)用不同的 do***()方法。結(jié)束服務(wù)惠险,web 容

器調(diào)用 servlet 的 destroy()方法苗傅。

5、Servlet 的基本架構(gòu)

public class ServletName extends HttpServlet {

public void doPost(HttpServletRequest request,HttpServletResponse response) throws

ServletException, IOException {

}

public void doGet(HttpServletRequest request,HttpServletResponse response) throws

ServletException, IOException {

}

}

6班巩、SERVLET API 中 forward()與 redirect()的區(qū)別渣慕?

答:前者僅是容器中控制權(quán)的轉(zhuǎn)向,在客戶端瀏覽器地址欄中不會顯示出轉(zhuǎn)向后的地址;后

者則是完全的跳轉(zhuǎn)逊桦,瀏覽器將會得到跳轉(zhuǎn)的地址眨猎,并重新發(fā)送請求鏈接。這樣强经,從瀏覽器的

地址欄中可以看到跳轉(zhuǎn)后的鏈接地址睡陪。所以,前者更加高效匿情,在前者可以滿足需要時兰迫,盡量

使用 forward()方法,并且码秉,這樣也有助于隱藏實(shí)際的鏈接逮矛。在有些情況下,比如转砖,需要跳

轉(zhuǎn)到一個其它服務(wù)器上的資源,則必須使用

sendRedirect()方法鲸伴。

7府蔗、什么情況下調(diào)用 doGet()和 doPost()?

Jsp 頁面中的 FORM 標(biāo)簽里的 method 屬性為 get 時調(diào)用 doGet()汞窗,為 post 時調(diào)用 doPost()姓赤。

8、Request 對象的主要方法:

setAttribute(String name,Object):設(shè)置名字為 name 的 request 的參數(shù)值

getAttribute(String name):返回由 name 指定的屬性值

getAttributeNames():返回 request 對象所有屬性的名字集合仲吏,結(jié)果是一個枚舉的實(shí)例

getCookies():返回客戶端的所有 Cookie 對象不铆,結(jié)果是一個 Cookie 數(shù)組

getCharacterEncoding():返回請求中的字符編碼方式

getContentLength():返回請求的 Body 的長度

getHeader(String name):獲得 HTTP 協(xié)議定義的文件頭信息

getHeaders(String name):返回指定名字的 request Header 的所有值,結(jié)果是一個枚舉的

實(shí)例

getHeaderNames():返回所以 request Header 的名字裹唆,結(jié)果是一個枚舉的實(shí)例

getInputStream():返回請求的輸入流誓斥,用于獲得請求中的數(shù)據(jù)

getMethod():獲得客戶端向服務(wù)器端傳送數(shù)據(jù)的方法

getParameter(String name):獲得客戶端傳送給服務(wù)器端的有 name 指定的參數(shù)值

getParameterNames():獲得客戶端傳送給服務(wù)器端的所有參數(shù)的名字,結(jié)果是一個枚舉的

實(shí)例

getParametervalues(String name):獲得有 name 指定的參數(shù)的所有值

getProtocol():獲取客戶端向服務(wù)器端傳送數(shù)據(jù)所依據(jù)的協(xié)議名稱

getQueryString():獲得查詢字符串

getRequestURI():獲取發(fā)出請求字符串的客戶端地址

getRemoteAddr():獲取客戶端的 IP 地址

getRemoteHost():獲取客戶端的名字

getSession([Boolean create]):返回和請求相關(guān) Session

getServerName():獲取服務(wù)器的名字

getServletPath():獲取客戶端所請求的腳本文件的路徑

getServerPort():獲取服務(wù)器的端口號

removeAttribute(String name):刪除請求中的一個屬性

9许帐、forward 和 redirect 的區(qū)別

forward 是服務(wù)器請求資源劳坑,服務(wù)器直接訪問目標(biāo)地址的 URL,把那個 URL 的響應(yīng)內(nèi)容讀

取過來成畦,然后把這些內(nèi)容再發(fā)給瀏覽器距芬,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,

所以它的地址欄中還是原來的地址循帐。

redirect 就是服務(wù)端根據(jù)邏輯,發(fā)送一個狀態(tài)碼,告訴瀏覽器重新去請求那個地址框仔,一般來

說瀏覽器會用剛才請求的所有參數(shù)重新請求,所以 session,request 參數(shù)都可以獲取拄养。

10离斩、request.getAttribute()和 request.getParameter()有何區(qū)別?

getParameter 得到的都是 String 類型的。或者是 http://a.jsp?id=123 中的 123捐腿,或者是某個表

單提交過去的數(shù)據(jù)纵朋。

getAttribute 則可以是對象。

getParameter()是獲取 POST/GET 傳遞的參數(shù)值茄袖;

getAttribute()是獲取對象容器中的數(shù)據(jù)值操软;

getParameter:用于客戶端重定向時,即點(diǎn)擊了鏈接或提交按扭時傳值用宪祥,即用于在用表單

或 url 重定向傳值時接收數(shù)據(jù)用聂薪。

getAttribute:用于服務(wù)器端重定向時,即在 sevlet 中使用了 forward 函數(shù),或 struts 中使用了

mapping.findForward蝗羊。getAttribute 只能收到程序用 setAttribute 傳過來的值藏澳。

getParameter()是獲取 POST/GET 傳遞的參數(shù)值;

getAttribute()是獲取 SESSION 的值耀找;

另外翔悠,可以用 setAttribute,getAttribute 發(fā)送接收對象.而 getParameter 顯然只能傳字符串。

setAttribute 是應(yīng)用服務(wù)器把這個對象放在該頁面所對應(yīng)的一塊內(nèi)存中去野芒,當(dāng)你的頁面服務(wù)器

重定向到另一個頁面時蓄愁,應(yīng)用服務(wù)器會把這塊內(nèi)存拷貝另一個頁面所對應(yīng)的內(nèi)存中。這樣

getAttribute 就能取得你所設(shè)下的值狞悲,當(dāng)然這種方法可以傳對象撮抓。session 也一樣,只是對象

在內(nèi)存中的生命周期不一樣而已摇锋。getParameter 只是應(yīng)用服務(wù)器在分析你送上來的 request

頁面的文本時丹拯,取得你設(shè)在表單或 url 重定向時的值。

getParameter 返回的是 String, 用于讀取提交的表單中的值;

getAttribute 返回的是 Object荸恕,需進(jìn)行轉(zhuǎn)換,可用 setAttribute 設(shè)置成任意對象乖酬,使用很靈活,

可隨時用戚炫;

11. jsp 有哪些內(nèi)置對象?作用分別是什么?分別有什么方法剑刑?

答:JSP 共有以下9個內(nèi)置的對象:

request 用戶端請求,此請求會包含來自 GET/POST 請求的參數(shù)

response 網(wǎng)頁傳回用戶端的回應(yīng)

pageContext 網(wǎng)頁的屬性是在這里管理

session 與請求有關(guān)的會話期

application servlet 正在執(zhí)行的內(nèi)容

out 用來傳送回應(yīng)的輸出

config servlet 的構(gòu)架部件

page JSP 網(wǎng)頁本身

exception 針對錯誤網(wǎng)頁双肤,未捕捉的例外

request 表示 HttpServletRequest 對象施掏。它包含了有關(guān)瀏覽器請求的信息,并且提供了幾個

用于獲取 cookie, header,和 session 數(shù)據(jù)的有用的方法茅糜。

response 表示 HttpServletResponse 對象七芭,并提供了幾個用于設(shè)置送回瀏覽器的響應(yīng)的

方法(如 cookies,頭信息等)

out 對象是 javax.jsp.JspWriter 的一個實(shí)例,并提供了幾個方法使你能用于向?yàn)g覽器回送

輸出結(jié)果蔑赘。

pageContext 表示一個 javax.servlet.jsp.PageContext 對象狸驳。它是用于方便存取各種范

圍的名字空間预明、servlet 相關(guān)的對象的 API,并且包裝了通用的 servlet 相關(guān)功能的方法耙箍。

session 表示一個請求的 javax.servlet.http.HttpSession 對象撰糠。Session 可以存貯用戶的

狀態(tài)信息

applicaton 表示一個 javax.servle.ServletContext 對象。這有助于查找有關(guān) servlet 引擎

和 servlet 環(huán)境的信息

config 表示一個 javax.servlet.ServletConfig 對象辩昆。該對象用于存取 servlet 實(shí)例的初始

化參數(shù)阅酪。

page 表示從該頁面產(chǎn)生的一個 servlet 實(shí)例

12. jsp 有哪些動作?作用分別是什么?

(這個問題似乎不重要,不明白為何有此題)

答:JSP 共有以下6種基本動作

jsp:include:在頁面被請求的時候引入一個文件汁针。

jsp:useBean:尋找或者實(shí)例化一個 JavaBean术辐。

jsp:setProperty:設(shè)置 JavaBean 的屬性。

jsp:getProperty:輸出某個 JavaBean 的屬性施无。

jsp:forward:把請求轉(zhuǎn)到一個新的頁面辉词。

jsp:plugin:根據(jù)瀏覽器類型為 Java 插件生成 OBJECT 或 EMBED 標(biāo)記

13、JSP 的常用指令

isErrorPage(是否能使用 Exception 對象)猾骡,isELIgnored(是否忽略表達(dá)式)

14. JSP 中動態(tài) INCLUDE 與靜態(tài) INCLUDE 的區(qū)別瑞躺?

答:動態(tài) INCLUDE 用 jsp:include 動作實(shí)現(xiàn)

<jsp:include page=included.jsp flush=true />它總是會檢查所含文件中的變化,適合用于包

含動態(tài)頁面卓练,并且可以帶參數(shù) 靜態(tài) INCLUDE 用 include 偽碼實(shí)現(xiàn),定不會檢查所含文件的

變化隘蝎,適用于包含靜態(tài)頁面 <%@include file=included.htm %>

15、兩種跳轉(zhuǎn)方式分別是什么?有什么區(qū)別?

(下面的回答嚴(yán)重錯誤襟企,應(yīng)該是想問 forward 和 sendRedirect 的區(qū)別,畢竟出題的人不是

專業(yè)搞文字藝術(shù)的人狮含,可能表達(dá)能力并不見得很強(qiáng)顽悼,用詞不一定精準(zhǔn),加之其自身的技術(shù)面

也可能存在一些問題几迄,不一定真正將他的意思表達(dá)清楚了蔚龙,嚴(yán)格意思上來講,一些題目可能

根本就無人能答映胁,所以木羹,答題時要掌握主動,只要把自己知道的表達(dá)清楚就夠了解孙,而不要去

推敲原始題目的具體含義是什么坑填,不要一味想著是在答題)

答:有兩種,分別為:

<jsp:include page=included.jsp flush=true>

<jsp:forward page= nextpage.jsp/>

前者頁面不會轉(zhuǎn)向 include 所指的頁面弛姜,只是顯示該頁的結(jié)果脐瑰,主頁面還是原來的頁面。執(zhí)

行完后還會回來廷臼,相當(dāng)于函數(shù)調(diào)用苍在。并且可以帶參數(shù).后者完全轉(zhuǎn)向新頁面绝页,不會再回來。

相當(dāng)于 go to 語句寂恬。

16续誉、頁面間對象傳遞的方法

request,session初肉,application酷鸦,cookie 等

17、JSP 和 Servlet 有哪些相同點(diǎn)和不同點(diǎn)朴译,他們之間的聯(lián)系是什么井佑?

JSP 是 Servlet 技術(shù)的擴(kuò)展,本質(zhì)上是 Servlet 的簡易方式眠寿,更強(qiáng)調(diào)應(yīng)用的外表表達(dá)躬翁。JSP

編譯后是"類 servlet"。Servlet 和 JSP 最主要的不同點(diǎn)在于盯拱,Servlet 的應(yīng)用邏輯是在 Java

文件中盒发,并且完全從表示層中的 HTML 里分離開來。而 JSP 的情況是 Java 和 HTML 可以

組合成一個擴(kuò)展名為.jsp 的文件狡逢。JSP 側(cè)重于視圖宁舰,Servlet 主要用于控制邏輯。

18奢浑、MVC 的各個部分都有那些技術(shù)來實(shí)現(xiàn)?如何實(shí)現(xiàn)?

答:MVC 是 Model-View-Controller 的簡寫蛮艰。Model 代表的是應(yīng)用的業(yè)務(wù)邏輯(通過

JavaBean,EJB 組件實(shí)現(xiàn))雀彼,View 是應(yīng)用的表示面(由 JSP 頁面產(chǎn)生)壤蚜,Controller 是提供

應(yīng)用的處理過程控制(一般是一個 Servlet),通過這種設(shè)計模型把應(yīng)用邏輯徊哑,處理過程和顯

示邏輯分成不同的組件實(shí)現(xiàn)袜刷。這些組件可以進(jìn)行交互和重用。

19莺丑、我們在 web 應(yīng)用開發(fā)過程中經(jīng)常遇到輸出某種編碼的字符著蟹,如 iso8859-1

等,如何輸出一個某種編碼的字符串梢莽?

Public String translate(String str) {

String tempStr ="";

try {

tempStr = newString(str.getBytes("ISO-8859-1"), "GBK");

tempStr =tempStr.trim();

}

catch (Exception e) {

System.err.println(e.getMessage());

}

return tempStr;

}

20萧豆、現(xiàn)在輸入 n 個數(shù)字,以逗號蟹漓,分開炕横;然后可選擇升或者降序排序;按提交

鍵就在另一頁面顯示按什么排序葡粒,結(jié)果為份殿,提供 reset

五.數(shù)據(jù)庫部分

1膜钓、用兩種方式根據(jù)部門號從高到低,工資從低到高列出每個員工的信息卿嘲。

employee:

eid,ename,salary,deptid;

select * from employeeorder by deptid desc,salary

2颂斜、列出各個部門中工資高于本部門的平均工資的員工數(shù)和部門號,并按部門號

排序

創(chuàng)建表:

mysql> createtable employee921(id int primary key auto_increment,name

varchar(5

0),salary bigint,deptid int);

插入實(shí)驗(yàn)數(shù)據(jù):

mysql> insert into employee921values(null,'zs',1000,1),(null,'ls',1100,1),(null,'ww',1100,1),(null,'zl',900,1) ,(null,'zl',1000,2), (null,'zl',900,2),(null,'zl',1000,2) , (null,'zl',1100,2);

編寫 sql 語句:

()select avg(salary) from employee921 group by deptid;

()mysql>

selectemployee921.id,employee921.name,employee921.salary,employee921.dep

tid tid from employee921where salary > (select avg(salary) from employee921 where

deptid = tid);

效率低的一個語句拾枣,僅供學(xué)習(xí)參考使用(在 group by 之后不能使用 where沃疮,只能使用

having,在 group by 之前可以使用 where梅肤,即表示對過濾后的結(jié)果分組):

mysql>

selectemployee921.id,employee921.name,employee921.salary,employee921.dep

tid tid from employee921where salary > (select avg(salary) from employee921 group by

deptid havingdeptid = tid);

()select count(*) ,tid

from (

selectemployee921.id,employee921.name,employee921.salary,employee921.deptid tid

from employee921

where salary>

(selectavg(salary) from employee921 where deptid = tid)

) as t

group by tid ;

另外一種方式:關(guān)聯(lián)查詢

select a.ename,a.salary,a.deptid

from emp a,

(selectdeptd,avg(salary) avgsal from emp group by deptid ) b

where a.deptid=b.deptidand a.salary>b.avgsal;

3司蔬、存儲過程與觸發(fā)器必須講,經(jīng)常被面試到?

create procedure insert_Student (_name varchar(50),_age int ,out_id int)

begin

insert into studentvalue(null,_name,_age);

select max(stuId)into _id from student;

end;

call insert_Student('wfz',23,@id);

select @id;

mysql> create trigger update_Student BEFORE update on studentFOR EACH ROW

-> select * from student;

觸發(fā)器不允許返回結(jié)果

create trigger update_StudentBEFORE update on student FOR EACH ROW

insert into student value(null,'zxx',28);

mysql 的觸發(fā)器目前不能對當(dāng)前表進(jìn)行操作

create trigger update_StudentBEFORE update on student FOR EACH ROW

delete from articles where id=8;

這個例子不是很好姨蝴,最好是用刪除一個用戶時俊啼,順帶刪除該用戶的所有帖子

這里要注意使用 OLD.id

觸發(fā)器用處還是很多的,比如校內(nèi)網(wǎng)左医、開心網(wǎng)授帕、Facebook,你發(fā)一個日志浮梢,自動通知好友跛十,

其實(shí)就是在增加日志時做一個后觸發(fā),再向通知表中寫入條目秕硝。因?yàn)橛|發(fā)器效率高芥映。而 UCH

沒有用觸發(fā)器沥潭,效率和數(shù)據(jù)處理能力都很低腥泥。

存儲過程的實(shí)驗(yàn)步驟:

mysql> delimiter |

mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out

pId int)

-> begin

-> insert into article1value(null,pTitle,pBid);

-> select max(id) into pId fromarticle1;

-> end;

-> |

Query OK, 0 rows affected (0.05sec)

mysql> callinsertArticle_Procedure('傳智播客',1,@pid);

-> |

Query OK, 0 rows affected (0.00sec)

mysql> delimiter ;

mysql> select @pid;

+------+

| @pid |

+------+

| 3 |

+------+

1 row in set (0.00 sec)

mysql> select * fromarticle1;

+----+--------------+------+

| id | title | bid |

+----+--------------+------+

| 1 | test | 1 |

| 2 | chuanzhiboke | 1 |

| 3 | 傳智播客 | 1 |

+----+--------------+------+

3 rows in set (0.00 sec)

觸發(fā)器的實(shí)驗(yàn)步驟:

create table board1(id intprimary key auto_increment,name varchar(50),articleCount int);

create table article1(id intprimary key auto_increment,title varchar(50)

,bid int referencesboard1(id));

delimiter |

create triggerinsertArticle_Trigger after insert on article1 for each ro

w begin

-> update board1 setarticleCount=articleCount+1 where id= NEW.bid;

-> end;

-> |

delimiter ;

insert into board1 value(null,'test',0);

insert into article1value(null,'test',1);

還有岸夯,每插入一個帖子竹宋,都希望將版面表中的最后發(fā)帖時間,帖子總數(shù)字段進(jìn)行同步更新敏弃,

用觸發(fā)器做效率就很高。下次課設(shè)計這樣一個案例,寫觸發(fā)器時榛做,對于最后發(fā)帖時間可能需

要用 declare 方式聲明一個變量,或者是用 NEW.posttime 來生成内狸。

4检眯、數(shù)據(jù)庫三范式是什么?

第一范式(1NF):字段具有原子性,不可再分。所有關(guān)系型數(shù)據(jù)庫系統(tǒng)都滿足第一范式)

數(shù)據(jù)庫表中的字段都是單一屬性的昆淡,不可再分锰瘸。例如,姓名字段昂灵,其中的姓和名必

須作為一個整體避凝,無法區(qū)分哪部分是姓舞萄,哪部分是名,如果要區(qū)分出姓和名管削,必須設(shè)計成兩

個獨(dú)立的字段倒脓。

第二范式(2NF):

第二范式(2NF)是在第一范式(1NF)的基礎(chǔ)上建立起來的,即滿足第二范式(2NF)必

須先滿足第一范式(1NF)含思。

要求數(shù)據(jù)庫表中的每個實(shí)例或行必須可以被惟一地區(qū)分崎弃。通常需要為表加上一個列,以存儲

各個實(shí)例的惟一標(biāo)識含潘。這個惟一屬性列被稱為主關(guān)鍵字或主鍵饲做。

第二范式(2NF)要求實(shí)體的屬性完全依賴于主關(guān)鍵字。所謂完全依賴是指不能存在僅依賴

主關(guān)鍵字一部分的屬性遏弱,如果存在盆均,那么這個屬性和主關(guān)鍵字的這一部分應(yīng)該分離出來形成

一個新的實(shí)體,新實(shí)體與原實(shí)體之間是一對多的關(guān)系腾窝。為實(shí)現(xiàn)區(qū)分通常需要為表加上一個列缀踪,

以存儲各個實(shí)例的惟一標(biāo)識。簡而言之虹脯,第二范式就是非主屬性非部分依賴于主關(guān)鍵字驴娃。

第三范式的要求如下:

滿足第三范式(3NF)必須先滿足第二范式(2NF)。簡而言之循集,第三范式(3NF)要求一

個數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字信息唇敞。

所以第三范式具有如下特征:

1,每一列只有一個值

2咒彤,每一行都能區(qū)分疆柔。

3,每一個表都不包含其他表已經(jīng)包含的非主關(guān)鍵字信息镶柱。

例如旷档,帖子表中只能出現(xiàn)發(fā)帖人的 id,而不能出現(xiàn)發(fā)帖人的 id歇拆,還同時出現(xiàn)發(fā)帖人姓名鞋屈,

否則,只要出現(xiàn)同一發(fā)帖人 id 的所有記錄故觅,它們中的姓名部分都必須嚴(yán)格保持一致厂庇,這就

是數(shù)據(jù)冗余。

5输吏、說出一些數(shù)據(jù)庫優(yōu)化方面的經(jīng)驗(yàn)?

用 PreparedStatement 一般來說比 Statement 性能高:一個 sql 發(fā)給服務(wù)器去執(zhí)行权旷,涉及步

驟:語法檢查、語義分析贯溅,編譯拄氯,緩存

“inert into user values(1,1,1)”-à 二進(jìn)制

“inert into user values(2,2,2)”-à 二進(jìn)制

“inert into user values(?,?,?)”-à 二進(jìn)制

有外鍵約束會影響插入和刪除性能躲查,如果程序能夠保證數(shù)據(jù)的完整性,那在設(shè)計數(shù)據(jù)庫時就

去掉外鍵坤邪。(比喻:就好比免檢產(chǎn)品熙含,就是為了提高效率,充分相信產(chǎn)品的制造商)

(對于 hibernate 來說艇纺,就應(yīng)該有一個變化:empleyee->Deptment 對象怎静,現(xiàn)在設(shè)計時就成

了 employeeàdeptid)看 mysql 幫助文檔子查詢章節(jié)的最后部分,例如黔衡,根據(jù)掃描的原理蚓聘,下面的子查詢語句要

比第二條關(guān)聯(lián)查詢的效率高:

1. select e.name,e.salarywhere e.managerid=(select id from employee where

name='zxx');

2. select e.name,e.salary,m.name,m.salary fromemployees e,employees m where

e.managerid = m.id andm.name='zxx';

表中允許適當(dāng)冗余,譬如盟劫,主題帖的回復(fù)數(shù)量和最后回復(fù)時間等

將姓名和密碼單獨(dú)從用戶表中獨(dú)立出來夜牡。這可以是非常好的一對一的案例喲!

sql 語句全部大寫侣签,特別是列名和表名都大寫塘装。特別是 sql 命令的緩存功能,更加需要統(tǒng)一

大小寫影所,sql 語句 à 發(fā)給 oracle 服務(wù)器 à 語法檢查和編譯成為內(nèi)部指令 à 緩存和執(zhí)行指令蹦肴。

根據(jù)緩存的特點(diǎn),不要拼湊條件猴娩,而是用?和 PreparedStatment

還有索引對查詢性能的改進(jìn)也是值得關(guān)注的阴幌。

備注:下面是關(guān)于性能的討論舉例

4航班 3個城市

m*n

select * from flight,city where flight.startcityid=city.cityidand city.name='beijing';

m + n

select * from flight where startcityid = (select cityid fromcity where cityname='beijing');

select flight.id,'beijing',flight.flightTime from flight wherestartcityid = (select cityid from city

where cityname='beijing')

6、union 和 union all 有什么不同?

假設(shè)我們有一個表 Student卷中,包括以下字段與數(shù)據(jù):

drop table student;

create table student

(

id int primary key,

name nvarchar2(50) not null,

score number not null

);

insert into student values(1,'Aaron',78);

insert into student values(2,'Bill',76);

insert into student values(3,'Cindy',89);

insert into student values(4,'Damon',90);

insert into student values(5,'Ella',73);

insert into student values(6,'Frado',61);

insert into student values(7,'Gill',99);

insert into student values(8,'Hellen',56);

insert into student values(9,'Ivan',93);

insert into student values(10,'Jay',90);

commit;

Union 和 Union All 的區(qū)別矛双。

select *

from student

where id < 4

union

select *

from student

where id > 2 and id < 6

結(jié)果將是

1 Aaron 78

2 Bill 76

3 Cindy 89

4 Damon 90

5 Ella 73

如果換成 Union All 連接兩個結(jié)果集,則返回結(jié)果是:

1 Aaron 78

2 Bill 76

3 Cindy 89

3 Cindy 89

4 Damon 90

5 Ella 73

可以看到蟆豫,Union 和 Union All 的區(qū)別之一在于對重復(fù)結(jié)果的處理议忽。

UNION 在進(jìn)行表鏈接后會篩選掉重復(fù)的記錄,所以在表鏈接后會對所產(chǎn)生的結(jié)果集進(jìn)行排

序運(yùn)算十减,刪除重復(fù)的記錄再返回結(jié)果徙瓶。實(shí)際大部分應(yīng)用中是不會產(chǎn)生重復(fù)的記錄,最常見的

是過程表與歷史表 UNION嫉称。如:

select * from gc_dfys

union

select * from ls_jg_dfys

這個 SQL 在運(yùn)行時先取出兩個表的結(jié)果,再用排序空間進(jìn)行排序刪除重復(fù)的記錄灵疮,最

后返回結(jié)果集织阅,如果表數(shù)據(jù)量大的話可能會導(dǎo)致用磁盤進(jìn)行排序。

而 UNION ALL 只是簡單的將兩個結(jié)果合并后就返回震捣。這樣荔棉,如果返回的兩個結(jié)果集中有

重復(fù)的數(shù)據(jù)闹炉,那么返回的結(jié)果集就會包含重復(fù)的數(shù)據(jù)了。

從效率上說润樱,UNION ALL 要比 UNION 快很多渣触,所以,如果可以確認(rèn)合并的兩個結(jié)果集

中不包含重復(fù)的數(shù)據(jù)的話壹若,那么就使用 UNION ALL嗅钻,

7.分頁語句

取出 sql 表中第31到40的記錄(以自動增長 ID 為主鍵)

sql server 方案1:

selecttop 10 * from t where id not in (select top 30 id from t order by id ) orde byid

sql server 方案2:

selecttop 10 * from t where id in (select top 40 id from t order by id) order by iddesc

mysql 方案:select * from t order by idlimit 30,10

oracle 方案:select * from (select rownum r,* from t where r<=40) wherer>30

--------------------待整理進(jìn)去的內(nèi)容-------------------------------------

pageSize=20;

pageNo = 5;

1.分頁技術(shù)1(直接利用 sql 語句進(jìn)行分頁,效率最高和最推薦的)

mysql:sql = "select * from articles limit " +(pageNo-1)*pageSize + "," + pageSize;

oracle: sql = "select * from " +

"(selectrownum r,* from " +

"(select* from

articles order by postime desc)" +

"whererownum<= " +

pageNo*pageSize +") tmp " +

"wherer>" +

(pageNo-1)*pageSize;

注釋:第7行保證 rownum 的順序是確定的店展,因?yàn)?oracle 的索引會造成 rownum 返回不同的

簡洋提示:沒有 order by 時养篓,rownum 按順序輸出,一旦有了 order by赂蕴,rownum 不按順序

輸出了柳弄,這說明 rownum 是排序前的編號。如果對 order by 從句中的字段建立了索引概说,那

么碧注,rownum 也是按順序輸出的,因?yàn)檫@時候生成原始的查詢結(jié)果集時會參照索引表的順序

來構(gòu)建糖赔。

sqlserver:sql = "select top 10 * from id not id(select top" + (pageNo-1)*pageSize + "id from

articles)"

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive

PreparedStatement pstmt = cn.prepareSatement(sql);

ResultSet rs = pstmt.executeQuery()

while(rs.next())

{

out.println(rs.getString(1));

}

2.不可滾動的游標(biāo)

pageSize=20;

pageNo = 5;

cn = null

stmt = null;

rs = null;

try

{

sqlserver:sql = "select * from articles";

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive

PreparedStatement pstmt = cn.prepareSatement(sql);

ResultSet rs = pstmt.executeQuery()

for(int j=0;j<(pageNo-1)*pageSize;j++)

{

rs.next();

}

int i=0;

while(rs.next() && i<10)

{

i++;

out.println(rs.getString(1));

}

}

cacth(){}

finnaly

{

if(rs!=null)try{rs.close();}catch(Exceptione){}

if(stm.........

if(cn............

}

3.可滾動的游標(biāo)

pageSize=20;

pageNo = 5;

cn = null

stmt = null;

rs = null;

try

{

sqlserver:sql = "select * from articles";

DataSource ds = new InitialContext().lookup(jndiurl);

Connection cn = ds.getConnection();

//"select * from user where id=?" --->binary directive

PreparedStatement pstmt =

cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...);

//根據(jù)上面這行代碼的異常 SQLFeatureNotSupportedException萍丐,就可判斷驅(qū)動是否支持可

滾動游標(biāo)

ResultSet rs = pstmt.executeQuery()

rs.absolute((pageNo-1)*pageSize)

int i=0;

while(rs.next() && i<10)

{

i++;

out.println(rs.getString(1));

}

}

cacth(){}

finnaly

{

if(rs!=null)try{rs.close();}catch(Exceptione){}

if(stm.........

if(cn............

}

8.用一條 SQL 語句查詢出每門課都大于 80 分的學(xué)生姓名

name kecheng fenshu

張三 語文 81

張三 數(shù)學(xué) 75

李四 語文 76

李四 數(shù)學(xué) 90

王五 語文 81

王五 數(shù)學(xué) 100

王五 英語 90

準(zhǔn)備數(shù)據(jù)的 sql 代碼:

create table score(id int primary key auto_increment,namevarchar(20),subject

varchar(20),score int);

insert into score values

(null,'張三','語文',81),

(null,'張三','數(shù)學(xué)',75),

(null,'李四','語文',76),

(null,'李四','數(shù)學(xué)',90),

(null,'王五','語文',81),

(null,'王五','數(shù)學(xué)',100),

(null,'王五 ','英語',90);

提示:當(dāng)百思不得其解時,請理想思維挂捻,把小變成大做碉纺,把大變成小做,

答案:

A: select distinct name from score where name not in (selectdistinct name from score

where score<=80)

B:select distince name t1 from score where 80< all (selectscore from score where

name=t1);

9.所有部門之間的比賽組合

一個叫 department 的表刻撒,里面只有一個字段 name,一共有4條紀(jì)錄骨田,分別是 a,b,c,d,對應(yīng)四

個球?qū)ΓF(xiàn)在四個球?qū)M(jìn)行比賽声怔,用一條 sql 語句顯示所有可能的比賽組合.

答:select a.name,b.name

from team a, team b

where a.name < b.name

10.每個月份的發(fā)生額都比 101 科目多的科目

請用 SQL 語句實(shí)現(xiàn):從 TestDB 數(shù)據(jù)表中查詢出所有月份的發(fā)生額都比101科目相應(yīng)月份的

發(fā)生額高的科目态贤。請注意:TestDB 中有很多科目,都有1-12月份的發(fā)生額醋火。

AccID:科目代碼悠汽,Occmonth:發(fā)生額月份,DebitOccur:發(fā)生額芥驳。

數(shù)據(jù)庫名:JcyAudit柿冲,數(shù)據(jù)集:Select * from TestDB

準(zhǔn)備數(shù)據(jù)的 sql 代碼:

drop table if exists TestDB;

create table TestDB(id int primary key auto_increment,AccIDvarchar(20), Occmonth date,

DebitOccur bigint);

insert into TestDB values

(null,'101','1988-1-1',100),

(null,'101','1988-2-1',110),

(null,'101','1988-3-1',120),

(null,'101','1988-4-1',100),

(null,'101','1988-5-1',100),

(null,'101','1988-6-1',100),

(null,'101','1988-7-1',100),

(null,'101','1988-8-1',100);

--復(fù)制上面的數(shù)據(jù),故意把第一個月份的發(fā)生額數(shù)字改小一點(diǎn)

insert into TestDB values

(null,'102','1988-1-1',90),

(null,'102','1988-2-1',110),

(null,'102','1988-3-1',120),

(null,'102','1988-4-1',100),

(null,'102','1988-5-1',100),

(null,'102','1988-6-1',100),

(null,'102','1988-7-1',100),

(null,'102','1988-8-1',100);

--復(fù)制最上面的數(shù)據(jù)兆旬,故意把所有發(fā)生額數(shù)字改大一點(diǎn)

insert into TestDB values

(null,'103','1988-1-1',150),

(null,'103','1988-2-1',160),

(null,'103','1988-3-1',180),

(null,'103','1988-4-1',120),

(null,'103','1988-5-1',120),

(null,'103','1988-6-1',120),

(null,'103','1988-7-1',120),

(null,'103','1988-8-1',120);

--復(fù)制最上面的數(shù)據(jù)假抄,故意把所有發(fā)生額數(shù)字改大一點(diǎn)

insert into TestDB values

(null,'104','1988-1-1',130),

(null,'104','1988-2-1',130),

(null,'104','1988-3-1',140),

(null,'104','1988-4-1',150),

(null,'104','1988-5-1',160),

(null,'104','1988-6-1',170),

(null,'104','1988-7-1',180),

(null,'104','1988-8-1',140);

--復(fù)制最上面的數(shù)據(jù),故意把第二個月份的發(fā)生額數(shù)字改小一點(diǎn)

insert into TestDB values

(null,'105','1988-1-1',100),

(null,'105','1988-2-1',80),

(null,'105','1988-3-1',120),

(null,'105','1988-4-1',100),

(null,'105','1988-5-1',100),

(null,'105','1988-6-1',100),

(null,'105','1988-7-1',100),

(null,'105','1988-8-1',100);

答案:

select distinct AccID from TestDB

where AccID not in

(selectTestDB.AccIDfrom TestDB,

(select * from TestDB where AccID='101') asdb101

whereTestDB.Occmonth=db101.Occmonth and

TestDB.DebitOccur<=db101.DebitOccur

);

11.統(tǒng)計每年每月的信息

year monthamount

1991 1 1.1

1991 2 1.2

1991 3 1.3

1991 4 1.4

1992 1 2.1

1992 2 2.2

1992 3 2.3

1992 4 2.4

查成這樣一個結(jié)果

year m1 m2 m3 m4

1991 1.1 1.2 1.3 1.4

1992 2.1 2.2 2.3 2.4

提示:這個與工資條非常類似,與學(xué)生的科目成績也很相似宿饱。

準(zhǔn)備 sql 語句:

drop table if existssales;

create table sales(idint auto_increment primary key,year varchar(10), month varchar(10),

amountfloat(2,1));

insert into salesvalues

(null,'1991','1',1.1),

(null,'1991','2',1.2),

(null,'1991','3',1.3),

(null,'1991','4',1.4),

(null,'1992','1',2.1),

(null,'1992','2',2.2),

(null,'1992','3',2.3),

(null,'1992','4',2.4);

答案一熏瞄、

select sales.year ,

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '1',

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '2',

(select t.amount fromsales t where t.month='1' and t.year= sales.year) '3',

(select t.amount fromsales t where t.month='1' and t.year= sales.year) as '4'

from sales group by year;

12.顯示文章標(biāo)題,發(fā)帖人谬以、最后回復(fù)時間

表:id,title,postuser,postdate,parentid

準(zhǔn)備 sql 語句:

drop table if exists articles;

create table articles(id int auto_increment primary key,titlevarchar(50), postuser

varchar(10), postdate datetime,parentid int referencesarticles(id));

insert into articles values

(null,'第一條','張三','1998-10-10 12:32:32',null),

(null,'第二條','張三','1998-10-10 12:34:32',null),

(null,'第一條回復(fù)1','李四','1998-10-10 12:35:32',1),

(null,'第二條回復(fù)1','李四','1998-10-10 12:36:32',2),

(null,'第一條回復(fù)2','王五','1998-10-10 12:37:32',1),

(null,'第一條回復(fù)3','李四','1998-10-10 12:38:32',1),

(null,'第二條回復(fù)2','李四','1998-10-10 12:39:32',2),

(null,'第一條回復(fù)4','王五','1998-10-10 12:39:40',1);

答案:

select a.title,a.postuser,

(selectmax(postdate) from articles where parentid=a.id) reply

from articles a where a.parentid is null;

注釋:子查詢可以用在選擇列中强饮,也可用于 where 的比較條件中,還可以用于 from 從句中为黎。

13.刪除除了 id 號不同,其他都相同的學(xué)生冗余信息

2.學(xué)生表如下:

id 號 學(xué)號 姓名課程編號課程名稱分?jǐn)?shù)

1 2005001 張三 0001 數(shù)學(xué) 69

2 2005002 李四 0001 數(shù)學(xué) 89

3 2005001 張三 0001 數(shù)學(xué) 69

A: delete from tablename where id 號 not in(select min(id 號) from tablename group by 學(xué)號,姓名,課程編號,課程名稱,分?jǐn)?shù))?

實(shí)驗(yàn):

create table student2(id int auto_increment primary key,codevarchar(20),name

varchar(20));

insert into student2 values(null,'2005001','張三'),(null,'2005002','李四'),(null,'2005001','張

三');

//如下語句邮丰,mysql 報告錯誤,可能刪除依賴后面統(tǒng)計語句碍舍,而刪除又導(dǎo)致統(tǒng)計語句結(jié)果不

一致柠座。

delete from student2 where id not in(select min(id) fromstudent2 group by name);

//但是,如下語句沒有問題:

select * from student2where id not in(select min(id) from student2 group by name);

//于是片橡,我想先把分組的結(jié)果做成虛表妈经,然后從虛表中選出結(jié)果,最后再將結(jié)果作為刪除的

條件數(shù)據(jù)捧书。

delete from student2 where id not in(select mid from (selectmin(id) mid

from student2 group by name) as t);

或者:

delete from student2 where id not in(select min(id) from (select* from s

tudent2) as t group by t.name);

注:出自糯蹬荩客網(wǎng)-程序員筆試面試題庫,程序員求職備考網(wǎng)站 http://www.nowcoder.com”经瓷,學(xué)習(xí)分享爆哑,侵刪!S咚薄揭朝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市色冀,隨后出現(xiàn)的幾起案子潭袱,更是在濱河造成了極大的恐慌,老刑警劉巖锋恬,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屯换,死亡現(xiàn)場離奇詭異,居然都是意外死亡与学,警方通過查閱死者的電腦和手機(jī)彤悔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來索守,“玉大人晕窑,你說我怎么就攤上這事÷逊穑” “怎么了幕屹?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵蓝丙,是天一觀的道長。 經(jīng)常有香客問我望拖,道長,這世上最難降的妖魔是什么挫鸽? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任说敏,我火速辦了婚禮,結(jié)果婚禮上丢郊,老公的妹妹穿的比我還像新娘盔沫。我一直安慰自己,他們只是感情好枫匾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布架诞。 她就那樣靜靜地躺著,像睡著了一般干茉。 火紅的嫁衣襯著肌膚如雪谴忧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天角虫,我揣著相機(jī)與錄音沾谓,去河邊找鬼。 笑死戳鹅,一個胖子當(dāng)著我的面吹牛均驶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枫虏,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼妇穴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了隶债?” 一聲冷哼從身側(cè)響起腾它,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎燃异,沒想到半個月后携狭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡回俐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年逛腿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仅颇。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡单默,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忘瓦,到底是詐尸還是另有隱情搁廓,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站境蜕,受9級特大地震影響蝙场,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粱年,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一售滤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧台诗,春花似錦完箩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至粱快,卻和暖如春秩彤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皆尔。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工呐舔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慷蠕。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓珊拼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親流炕。 傳聞我的和親對象是個殘疾皇子澎现,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容