J2EE是一套全然不同于傳統(tǒng)應(yīng)用開發(fā)的技術(shù)架構(gòu)抛寝,包含許多組件涨颜,主要可簡化且規(guī)范應(yīng)用系統(tǒng)的開發(fā)與部署,進(jìn)而提高可移植性依沮、安全與再用價(jià)值涯贞。
J2EE核心是一組技術(shù)規(guī)范與指南枪狂,其中所包含的各類組件、服務(wù)架構(gòu)及技術(shù)層次宋渔,均有共同的標(biāo)準(zhǔn)及規(guī)格州疾,讓各種依循J2EE架構(gòu)的不同平臺(tái)之間,存在良好的兼容性皇拣,解決過去企業(yè)后端使用的信息產(chǎn)品彼此之間無法兼容严蓖,企業(yè)內(nèi)部或外部難以互通的窘境。
J2EE組件和“標(biāo)準(zhǔn)的” Java類的不同點(diǎn)在于:它被裝配在一個(gè)J2EE應(yīng)用中审磁,具有固定的格式并遵守J2EE規(guī)范,由J2EE服務(wù)器對(duì)其進(jìn)行管理岂座。J2EE規(guī)范是這樣定義J2EE組件的:客戶端應(yīng)用程序和applet是運(yùn)行在客戶端的組件态蒂;Java Servlet和Java Server Pages (JSP) 是運(yùn)行在服務(wù)器端的Web組件;Enterprise Java Bean (EJB )組件是運(yùn)行在服務(wù)器端的業(yè)務(wù)組件费什。
學(xué)習(xí)整理:
-
learn表有kc(課程)钾恢、student_id(學(xué)生編號(hào))、grade(分?jǐn)?shù))等字段鸳址,求:1.每門課程分?jǐn)?shù)最高的兩個(gè)同學(xué) 2.每門課程分?jǐn)?shù)在31~40名的同學(xué) 3.出現(xiàn)過4次以上的課程瘩蚪,并按出現(xiàn)次數(shù)降序排列。
- 主要是用到子查詢稿黍,考慮同課程下分?jǐn)?shù)比該學(xué)生高的人數(shù)小于2
SELECT *
FROM learn a
WHERE (SELECT COUNT(*) FROM learn b WHERE a.kc = b.kc AND a.grade < b.grade) < 2
ORDER BY a.kc,a.grade DESC
- 與上題類似疹瘦,以1的方法找30名開外和40名以內(nèi)的同學(xué)。
SELECT *
FROM learn a
WHERE (SELECT COUNT(*) FROM learn b WHERE a.kc = b.kc AND a.grade < b.grade) > 30
AND (SELECT COUNT(*) FROM learn b WHERE a.kc = b.kc AND a.grade < b.grade) < 40
ORDER BY a.kc,a.grade DESC
- 比較簡單巡球,主要是sql中g(shù)roup by言沐, having,聚合函數(shù)的使用酣栈。
SELECT COUNT(kc) kc_count,student_id
FROM learn a
GROUP BY student_id
HAVING kc_count >= 4
ORDER BY kc_count DESC
-
java線程中sleep()和wait()的區(qū)別险胰?
- 資源占用和釋放上的不同:
每個(gè)對(duì)象都有一個(gè)鎖來控制同步訪問,Synchronized關(guān)鍵字可以和對(duì)象的鎖交互矿筝,來實(shí)現(xiàn)同步方法或同步塊起便。
每個(gè)對(duì)象都有一個(gè)鎖來控制同步訪問,Synchronized關(guān)鍵字可以和對(duì)象的鎖交互窖维,來實(shí)現(xiàn)同步方法或同步塊榆综。
sleep()方法正在執(zhí)行的線程主動(dòng)讓出CPU(然后CPU就可以去執(zhí)行其他任務(wù)),在sleep指定時(shí)間后CPU再回到該線程繼續(xù)往下執(zhí)行(注意:sleep方法只讓出了CPU铸史,而并不會(huì)釋放同步資源鎖=蹦辍!沛贪!)陋守;
wait()方法則是指當(dāng)前線程讓自己暫時(shí)退讓出同步資源鎖震贵,以便其他正在等待該資源的線程得到該資源進(jìn)而運(yùn)行,只有調(diào)用了notify()方法水评,之前調(diào)用wait()的線程才會(huì)解除wait狀態(tài)猩系,可以去參與競爭同步資源鎖,進(jìn)而得到執(zhí)行中燥。
注意:notify的作用相當(dāng)于叫醒睡著的人寇甸,而并不會(huì)給他分配任務(wù),就是說notify只是讓之前調(diào)用wait的線程有權(quán)利重新參與線程的調(diào)度疗涉;
- 程序中出現(xiàn)的位置不同:
- sleep()方法可以在任何地方使用拿霉;
- wait()方法則只能在同步方法或同步塊中使用;
- 隸屬于不同的對(duì)象:
- sleep()是線程類(Thread)的方法咱扣,調(diào)用會(huì)暫停此線程指定的時(shí)間绽淘,但監(jiān)控依然保持,不會(huì)釋放對(duì)象鎖闹伪,到時(shí)間自動(dòng)恢復(fù)沪铭;
- wait()是Object的方法,調(diào)用會(huì)放棄對(duì)象鎖偏瓤,進(jìn)入等待隊(duì)列杀怠,待調(diào)用notify()/notifyAll()喚醒指定的線程或者所有線程,才會(huì)進(jìn)入鎖池厅克,不再次獲得對(duì)象鎖才會(huì)進(jìn)入運(yùn)行狀態(tài)赔退;
參見:
Java中sleep()與wait()區(qū)別:https://blog.csdn.net/u012050154/article/details/50903326
-
java線程不建議使用suspend()和resume(),為什么证舟?
首先先來知道suspend和resume是干什么用的离钝。
- suspend將線程掛起,運(yùn)行->阻塞褪储;調(diào)用后并不釋放所占用的鎖
- resume將線程解掛卵渴,阻塞->就緒
那為什么不建議使用呢,兩點(diǎn)原因:
- 獨(dú)占:因?yàn)閟uspend在調(diào)用過程中不會(huì)釋放所占用的鎖鲤竹,所以如果使用不當(dāng)會(huì)造成對(duì)公共對(duì)象的獨(dú)占浪读,使得其他線程無法訪問公共對(duì)象,嚴(yán)重的話造成死鎖辛藻。
- 不同步:容易出現(xiàn)因線程暫停導(dǎo)致的數(shù)據(jù)不同步
參見:
suspend和resume弊端:https://blog.csdn.net/u012813201/article/details/64932172
-
j2ee標(biāo)準(zhǔn)有哪些碘橘?
J2EE是一套全然不同于傳統(tǒng)應(yīng)用開發(fā)的技術(shù)架構(gòu),包含許多組件吱肌,主要可簡化且規(guī)范應(yīng)用系統(tǒng)的開發(fā)與部署痘拆,進(jìn)而提高可移植性、安全與再用價(jià)值氮墨。
J2EE 十三個(gè)規(guī)范:
- JDBC(Java Database Connectivity)
JDBC API為訪問不同數(shù)據(jù)庫提供了統(tǒng)一的路徑,像ODBC一樣,JDBC開發(fā)者屏蔽了一些細(xì)節(jié)問題,另外,JDBC對(duì)數(shù)據(jù)庫的訪問也具有平臺(tái)無關(guān)性.
- JNDI(Java Name and Directory Interface)
JNDI API被用于執(zhí)行名字和目錄服務(wù)纺蛆。它提供了一致的模型來存取和操作企業(yè)級(jí)的資源如DNS和LDAP吐葵,本地文件系統(tǒng),或應(yīng)用服務(wù)器中的對(duì)象。
- EJB(Enterprise JavaBean)
J2EE技術(shù)之所以贏得廣泛重視的原因之一就是EJB.它提供了一個(gè)框架來開發(fā)和實(shí)施分布式商務(wù)邏輯,由此很顯著的簡化了具有可伸縮性和高度復(fù)雜的企業(yè)級(jí)應(yīng)用程序的開發(fā).EJB規(guī)范定義了EJB組件在何時(shí)如何與它們的容器進(jìn)行交互作用.容器負(fù)責(zé)提供公用的服務(wù),例如目錄服務(wù),事務(wù)管理,安全性,資源緩沖池以及容錯(cuò)性.但這里值得注意的是,EJB并不是實(shí)現(xiàn)J2EE的唯一路徑.正是由于J2EE的開放性,使得所有的廠商能夠以一種和EJB平行的方式來達(dá)到同樣的目地
- RMI(Remote Method Invoke)
遠(yuǎn)程方法請求,RMI協(xié)議調(diào)用遠(yuǎn)程對(duì)象上的方法.它使用了序列化的方式在客戶端和服務(wù)器之間傳遞數(shù)據(jù).RMI是一種被EJB使用的更底層的協(xié)議.
- Java IDL/CORBA(通用對(duì)象請求代理架構(gòu)是軟件構(gòu)建的一個(gè)標(biāo)準(zhǔn) )
在Java IDL的支持下,開發(fā)人員可以將Java和CORBA集成在一起浑度。他們可以創(chuàng)建Java對(duì)象并使之可在CORBA ORB中展開, 或者他們還可以創(chuàng)建Java類并作為和其它ORB一起展開的CORBA對(duì)象的客戶。后一種方法提供了另外一種途徑凤藏,通過它Java可以被用于將你的新的應(yīng)用和舊的系統(tǒng)相集成。- JSP(Java Server Pages)
JSP頁面由HTML代碼和嵌入其中的Java代碼所組成堕伪。服務(wù)器在頁面被客戶端所請求以后對(duì)這些Java代碼進(jìn)行處理揖庄,然后將生成的HTML頁面返回給客戶端的瀏覽器。- Java Servlet
Servlet是一種小型的Java程序欠雌,它擴(kuò)展了Web服務(wù)器的功能蹄梢。作為一種服務(wù)器端的應(yīng)用,當(dāng)被請求時(shí)開始執(zhí)行桨昙,這和CGI Perl腳本很相似检号。Servlet提供的功能大多與JSP類似腌歉,不過實(shí)現(xiàn)的方式不同蛙酪。JSP通常是大多數(shù)HTML代碼中嵌入少量的Java代碼,而servlets全部由Java寫成并且生成HTML翘盖。- XML(Extensible Markup Language)
XML是一種可以用來定義其它標(biāo)記語言的語言桂塞。它被用來在不同的商務(wù)過程中共享數(shù)據(jù)。
XML的發(fā)展和Java是相互獨(dú)立的馍驯,但是阁危,它和Java具有的相同目標(biāo)正是平臺(tái)獨(dú)立性。通過將Java和XML的組合汰瘫,您可以得到一個(gè)完美的具有平臺(tái)獨(dú)立性的解決方案狂打。- JMS(Java Message Service)
MS是用于和面向消息的中間件相互通信的應(yīng)用程序接口(API)。它既支持點(diǎn)對(duì)點(diǎn)的域混弥,有支持發(fā)布/訂閱(publish/subscribe)類型的域趴乡,并且提供對(duì)下列類型的支持:經(jīng)認(rèn)可的消息傳遞,事務(wù)型消息的傳遞,一致性消息和具有持久性的訂閱者支持蝗拿。JMS還提供了另一種方式來對(duì)您的應(yīng)用與舊的后臺(tái)系統(tǒng)相集成晾捏。- JTA(Java Transaction Architecture)
JTA定義了一種標(biāo)準(zhǔn)的API,應(yīng)用系統(tǒng)由此可以訪問各種事務(wù)監(jiān)控哀托。- JTS(Java Transaction Service):
JTS是CORBA OTS事務(wù)監(jiān)控的基本的實(shí)現(xiàn)惦辛。JTS規(guī)定了事務(wù)管理器的實(shí)現(xiàn)方式。該事務(wù)管理器是在高層支持Java Transaction API (JTA)規(guī)范仓手,并且在較底層實(shí)現(xiàn)OMG OTS specification的Java映像胖齐。JTS事務(wù)管理器為應(yīng)用服務(wù)器玻淑、資源管理器、獨(dú)立的應(yīng)用以及通信資源管理器提供了事務(wù)服務(wù)市怎。- JavaMail
JavaMail是用于存取郵件服務(wù)器的API岁忘,它提供了一套郵件服務(wù)器的抽象類。不僅支持SMTP服務(wù)器区匠,也支持IMAP服務(wù)器干像。- JAF(JavaBeans Activation Framework)
JavaMail利用JAF來處理MIME編碼的郵件附件。MIME的字節(jié)流可以被轉(zhuǎn)換成Java對(duì)象驰弄,或者轉(zhuǎn)換自Java對(duì)象麻汰。大多數(shù)應(yīng)用都可以不需要直接使用JAF。
參見:
百度百科(J2EE技術(shù)):https://baike.baidu.com/item/J2EE%E6%8A%80%E6%9C%AF
J2EE的十三個(gè)標(biāo)準(zhǔn):
https://blog.csdn.net/cwl421/article/details/50992558
-
Data Source和Driver manager 獲取connector方式的區(qū)別戚篙?
在JDBC2.0或JDBC3.0中五鲫,所有的數(shù)據(jù)庫驅(qū)動(dòng)程序提供商必須提供一個(gè)實(shí)現(xiàn)了DataSource接口的類,要使用數(shù)據(jù)源必須首先在JNDI中注冊該數(shù)據(jù)源對(duì)象岔擂。
如果在JNDI中注冊了數(shù)據(jù)源對(duì)象位喂,將會(huì)比起使用DriverManager來具有兩個(gè)方面的優(yōu)勢:
- 程序不需要像使用DriverManager一樣對(duì)加載的數(shù)據(jù)庫驅(qū)動(dòng)程序信息進(jìn)行硬編碼,程序員可以選擇先在JNDI中注冊這個(gè)數(shù)據(jù)源對(duì)象乱灵,然后在程序中使用一個(gè)邏輯名稱來引用它塑崖,JNDI會(huì)自動(dòng)根據(jù)你給出的名稱找到與這個(gè)名稱綁定的DataSource對(duì)象。然后就可以使用這個(gè)DataSource對(duì)象來建立和具體數(shù)據(jù)庫的連接了痛倚。
- 使用實(shí)現(xiàn)了DataSource接口的類所具有的第二個(gè)優(yōu)勢體現(xiàn)在連接池和分布式事務(wù)上规婆。連接池通過對(duì)連接的復(fù)用而不是新建一個(gè)物理連接來顯著地提高程序的效率。從而適用于任務(wù)繁忙蝉稳、負(fù)擔(dān)繁重的企業(yè)級(jí)分布式事務(wù)抒蚜。
數(shù)據(jù)庫連接池的基本原理
傳統(tǒng)的數(shù)據(jù)庫連接方式(指通過DriverManager和基本實(shí)現(xiàn)DataSource進(jìn)行連接)中,一個(gè)數(shù)據(jù)庫連接對(duì)象均對(duì)應(yīng)一個(gè)物理數(shù)據(jù)庫連接耘戚,數(shù)據(jù)庫連接的建立以及關(guān)閉對(duì)系統(tǒng)而言是耗費(fèi)系統(tǒng)資源的操作嗡髓,在多層結(jié)構(gòu)的應(yīng)用程序環(huán)境中這種耗費(fèi)資源的動(dòng)作對(duì)系統(tǒng)的性能影響尤為明顯。
在多層結(jié)構(gòu)的應(yīng)用程序中通過連接池(connection pooling)技術(shù)可以使系統(tǒng)的性能明顯得到提到收津,連接池意味著當(dāng)應(yīng)用程序需要調(diào)用一個(gè)數(shù)據(jù)庫連接的時(shí)饿这,數(shù)據(jù)庫相關(guān)的接口通過返回一個(gè)通過重用數(shù)據(jù)庫連接來代替重新創(chuàng)建一個(gè)數(shù)據(jù)庫連接。
通過這種方式朋截,應(yīng)用程序可以減少對(duì)數(shù)據(jù)庫連接操作蛹稍,尤其在多層環(huán)境中多個(gè)客戶端可以通過共享少量的物理數(shù)據(jù)庫連接來滿足系統(tǒng)需求。
通過連接池技術(shù)Java應(yīng)用程序不僅可以提高系統(tǒng)性能同時(shí)也為系統(tǒng)提高了可測量性部服。
再來對(duì)比下兩種方法的使用:
- DriverManager
Class.forName(driverClass);
conn = DriverManager.getConnection(url, username, password);
相關(guān)數(shù)據(jù)庫的操作唆姐;
con.close();
- DataSource
一個(gè)DataSource對(duì)象通常注冊在JNDI命名服務(wù)上,應(yīng)用程序可以通過標(biāo)準(zhǔn)的方式獲得到注冊在JNDI服務(wù)上的DataSource對(duì)象廓八。 代碼如下:
Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("jdbc/openbase");
如果當(dāng)前DataSource不支持?jǐn)?shù)據(jù)庫連接池奉芦,應(yīng)用程序?qū)@得一個(gè)和物理數(shù)據(jù)庫連接對(duì)應(yīng)的Connection對(duì)象赵抢。
而如果當(dāng)前的DataSource對(duì)象支持?jǐn)?shù)據(jù)庫連接池,應(yīng)用程序自動(dòng)獲得重用的數(shù)據(jù)庫連接而不用創(chuàng)建新的數(shù)據(jù)庫連接声功。
重用的數(shù)據(jù)庫連接和新建立連接的數(shù)據(jù)庫連接使用上沒有任何不同烦却。應(yīng)用程序可以通過重用的連接正常的訪問數(shù)據(jù)庫,進(jìn)行訪問數(shù)據(jù)的操作先巴,完成操作后應(yīng)顯式的調(diào)用close()關(guān)閉數(shù)據(jù)庫連接其爵。
Connection con = ds.getConnection("User", "Pwd"); 相關(guān)數(shù)據(jù)庫的操作; con.close();
當(dāng)關(guān)閉數(shù)據(jù)連接后伸蚯,當(dāng)前使用的數(shù)據(jù)庫連接將不會(huì)被物理關(guān)閉摩渺,而是放回到數(shù)據(jù)庫連接池中進(jìn)行重用。
參見:
DataSource跟DriverManager區(qū)別及聯(lián)系:https://blog.csdn.net/laorer/article/details/1827007
-
servlet中dopost剂邮、doget摇幻、dodelete、service都有什么區(qū)別挥萌?
首先servlet是單實(shí)例多線程的绰姻,然后來看看這些名詞的區(qū)別。
- servlet接口中需要實(shí)現(xiàn)三大生命周期方法:init引瀑,service狂芋,destroy
- void init(ServletConfig):出生之后(1次)
在Servlet被創(chuàng)建后,服務(wù)器會(huì)馬上調(diào)用Servlet的void init(ServletConfig)方法伤疙。請記住银酗, Servlet出生后馬上就會(huì)調(diào)用init()方法辆影,而且一個(gè)Servlet的一生徒像,這個(gè)方法只會(huì)被調(diào)用一次。我們可以把一些對(duì)Servlet的初始化工作放到init方法中蛙讥!
- void service(ServletRequest request, ServletResponse response):每次處理請求時(shí)都會(huì)被調(diào)用锯蛀;
當(dāng)服務(wù)器每次接收到請求時(shí),都會(huì)去調(diào)用Servlet的service()方法來處理請求次慢。服務(wù)器接收到一次請求旁涤,就會(huì)調(diào)用service() 方法一次,所以service()方法是會(huì)被調(diào)用多次的迫像。正因?yàn)槿绱伺蓿晕覀儾判枰烟幚碚埱蟮拇a寫到service()方法中!
- void destroy():臨死之前(1次)
Servlet是不會(huì)輕易離去的闻妓,通常都是在服務(wù)器關(guān)閉時(shí)Servlet才會(huì)離去菌羽!在服務(wù)器被關(guān)閉時(shí),服務(wù)器會(huì)去銷毀Servlet由缆,在銷毀Servlet之前服務(wù)器會(huì)先去調(diào)用Servlet的destroy()方法注祖,我們可以把Servlet的臨終遺言放到destroy()方法中猾蒂,例如對(duì)某些資源的釋放等代碼放到destroy()方法中。
- GenericServlet是Servlet接口的實(shí)現(xiàn)類是晨,我們可以通過繼承GenericServlet來編寫自己的Servlet肚菠。
在GenericServlet中,定義了一個(gè)ServletConfig config實(shí)例變量罩缴,并在init(ServletConfig)方法中把參數(shù)ServletConfig賦給了實(shí)例變量蚊逢。然后在該類的很多方法中使用了實(shí)例變量config。
如果子類覆蓋了GenericServlet的init(StringConfig)方法箫章,那么this.config=config這一條語句就會(huì)被覆蓋了时捌,也就是說GenericServlet的實(shí)例變量config的值為null,那么所有依賴config的方法都不能使用了炉抒。如果真的希望完成一些初始化操作奢讨,那么去覆蓋GenericServlet提供的init()方法,它是沒有參數(shù)的init()方法焰薄,它會(huì)在init(ServletConfig)方法中被調(diào)用拿诸。
GenericServlet還實(shí)現(xiàn)了ServletConfig接口,所以可以直接調(diào)用getInitParameter()塞茅、getServletContext()等ServletConfig的方法亩码。
- HttpServlet(從事javaweb開發(fā)的重點(diǎn)),上面說了servlet接口和GenericServlet都只是httpservlet的父類和父接口
- HttpServlet覆蓋了service()方法
HttpServlet類中提供service(HttpServletRequest,HttpServletResponse)方法野瘦,這個(gè)方法是HttpServlet自己的方法描沟,不是從Servlet繼承來的。
在HttpServlet的service(ServletRequest,ServletResponse)方法中會(huì)把ServletRequest和ServletResponse強(qiáng)轉(zhuǎn)成HttpServletRequest和HttpServletResponse鞭光,然后調(diào)用service(HttpServletRequest,HttpServletResponse)方法吏廉,這說明子類可以去覆蓋service(HttpServletRequest,HttpServletResponse)方法即可,這就不用自己去強(qiáng)轉(zhuǎn)請求和響應(yīng)對(duì)象了惰许。
- doGet()和doPost()
在HttpServlet的service(HttpServletRequest,HttpServletResponse)方法會(huì)去判斷當(dāng)前請求是GET還是POST席覆,如果是GET請求,那么會(huì)去調(diào)用本類的doGet()方法汹买,如果是POST請求會(huì)去調(diào)用doPost()方法佩伤,這說明我們在子類中去覆蓋doGet()或doPost()方法即可。
- JavaWeb的四大域?qū)ο?br> 四個(gè)域的作用域范圍大小:PageContext (page域) < request < session < servletContext(application域)
- ServletContext
生命周期:當(dāng)Web應(yīng)用被加載進(jìn)容器時(shí)創(chuàng)建代表整個(gè)web應(yīng)用的ServletContext對(duì)象晦毙,當(dāng)服務(wù)器關(guān)閉或Web應(yīng)用被移除時(shí)生巡,ServletContext對(duì)象跟著銷毀。
作用范圍:整個(gè)Web應(yīng)用见妒。
作用:a) 在不同Servlet 之間轉(zhuǎn)發(fā) b) 讀取資源文件孤荣。
- Request 域
生命周期:在service 方法調(diào)用前由服務(wù)器創(chuàng)建,傳入service方法。整個(gè)請求結(jié)束垃环,request生命結(jié)束邀层。
作用范圍:整個(gè)請求鏈(請求轉(zhuǎn)發(fā)也存在)。
作用: 在整個(gè)請求鏈中共享數(shù)據(jù)遂庄。
- Session 域
生命周期:在第一次調(diào)用 request.getSession() 方法時(shí)寥院,服務(wù)器會(huì)檢查是否已經(jīng)有對(duì)應(yīng)的session,如果沒有就在內(nèi)存 中創(chuàng)建一個(gè)session并返回。當(dāng)一段時(shí)間內(nèi)session沒有被使用(默認(rèn)為30分鐘)涛目,則服務(wù)器會(huì)銷毀該session秸谢。如果服務(wù)器非正常關(guān)閉(強(qiáng)行關(guān)閉),沒有到期的session也會(huì)跟著銷毀霹肝。如果調(diào)用session提供的invalidate()估蹄,可以立即銷毀session。
作用范圍:一次會(huì)話沫换。
- PageContext 域
生命周期:當(dāng)對(duì)JSP的請求時(shí)開始臭蚁,當(dāng)響應(yīng)結(jié)束時(shí)銷毀。
作用范圍:整個(gè)JSP頁面讯赏,是四大作用域中最小的一個(gè)垮兑,即超過這個(gè)頁面就不能夠使用了。(所以使用pageContext對(duì)象向其它頁面?zhèn)鬟f參數(shù)是不可能的.)
作用:(1)獲取其它八大隱式對(duì)象漱挎,可以認(rèn)為是一個(gè)入口對(duì)象系枪。
(2)獲取其所有域中的數(shù)據(jù)
- HTTP協(xié)議六種請求方法
- GET:GET可以說是最常見的了,它本質(zhì)就是發(fā)送一個(gè)請求來取得服務(wù)器上的某一資源磕谅。資源通過一組HTTP頭和呈現(xiàn)據(jù)(如HTML文本私爷,或者圖片或者視頻等)返回給客戶端。GET請求中膊夹,永遠(yuǎn)不會(huì)包含呈現(xiàn)數(shù)據(jù)衬浑。
- HEAD:HEAD和GET本質(zhì)是一樣的,區(qū)別在于HEAD不含有呈現(xiàn)數(shù)據(jù)割疾,而僅僅是HTTP頭信息嚎卫。有的人可能覺得這個(gè)方法沒什么用嘉栓,其實(shí)不是這樣的宏榕。想象一個(gè)業(yè)務(wù)情景:欲判斷某個(gè)資源是否存在,我們通常使用GET侵佃,但這里用HEAD則意義更加明確麻昼。
- PUT:這個(gè)方法比較少見。HTML表單也不支持這個(gè)馋辈。本質(zhì)上來講抚芦, PUT和POST極為相似,都是向服務(wù)器發(fā)送數(shù)據(jù),但它們之間有一個(gè)重要區(qū)別叉抡,PUT通常指定了資源的存放位置尔崔,而POST則沒有,POST的數(shù)據(jù)存放位置由服務(wù)器自己決定褥民。
- DELETE:刪除某一個(gè)資源季春。基本上這個(gè)也很少見消返,不過還是有一些地方比如amazon的S3云服務(wù)里面就用的這個(gè)方法來刪除資源载弄。
- POST:向服務(wù)器提交數(shù)據(jù)。這個(gè)方法用途廣泛撵颊,幾乎目前所有的提交操作都是靠這個(gè)完成宇攻。
- OPTIONS:這個(gè)方法很有趣,但極少使用倡勇。它用于獲取當(dāng)前URL所支持的方法逞刷。若請求成功,則它會(huì)在HTTP頭中包含一個(gè)名為“Allow”的頭妻熊,值是所支持的方法亲桥,如“GET, POST”。
- TRACE:RACE方法被用于激發(fā)一個(gè)遠(yuǎn)程的固耘,應(yīng)用層的請求消息回路(譯注:TRACE方法讓客戶端測試到服務(wù)器的網(wǎng)絡(luò)通路题篷,回路的意思如發(fā)送一個(gè)請返回一個(gè)響應(yīng),這就是一個(gè)請求響應(yīng)回路)
- CONNECT:HTTP1.1協(xié)議規(guī)范保留了CONNECT方法厅目,此方法是為了能用于能動(dòng)態(tài)切換到隧道的代理服務(wù)器(proxy番枚,譯注:可以為代理,也可以是代理服務(wù)器)损敷。
以上方法葫笼,我們可以跟數(shù)據(jù)庫的CRUD增刪改查操作對(duì)應(yīng)起來: CREATE :PUT READ:GET UPDATE:POST DELETE:DELETE 這樣一來就實(shí)現(xiàn)了HTTP和數(shù)據(jù)庫操作(其實(shí)不光是數(shù)據(jù)庫,任何數(shù)據(jù)如文件圖表都是這樣)的完美統(tǒng)一拗馒,這也是REST的精髓之一
- JavaWeb三大組件
avaWeb三大組件指的是:Servlet路星、Filter、Listener
- Servlet
Servlet是用來處理客戶端請求的動(dòng)態(tài)資源诱桂,也就是當(dāng)我們在瀏覽器中鍵入一個(gè)地址回車跳轉(zhuǎn)后洋丐,請求就會(huì)被發(fā)送到對(duì)應(yīng)的Servlet上進(jìn)行處理挥等。- Filter
Filter與servlet在很多的方面極其相似,但是也有不同肝劲,例如filter和servlet一樣都又三個(gè)生命周期方法郭宝,同時(shí)他們在web.xml中的配置文件也是差不多的掷漱、 但是servlet主要負(fù)責(zé)處理請求,而filter主要負(fù)責(zé)攔截請求育特,和放行先朦。
filter四種攔截方式:
- REQUEST:直接訪問目標(biāo)資源時(shí)執(zhí)行過濾器缰冤。包括:在地址欄中直接訪問、表單提交喳魏、超鏈接棉浸、重定向,只要在地址欄中可以看到目標(biāo)資源的路徑刺彩,就是REQUEST迷郑;
- FORWARD:轉(zhuǎn)發(fā)訪問執(zhí)行過濾器。包括RequestDispatcher#forward()方法创倔、< jsp:forward>標(biāo)簽都是轉(zhuǎn)發(fā)訪問嗡害;
- INCLUDE:包含訪問執(zhí)行過濾器。包括RequestDispatcher#include()方法畦攘、< jsp:include>標(biāo)簽都是包含訪問霸妹;
- ERROR:當(dāng)目標(biāo)資源在web.xml中配置為< error-page>中時(shí),并且真的出現(xiàn)了異常知押,轉(zhuǎn)發(fā)到目標(biāo)資源時(shí)叹螟,會(huì)執(zhí)行過濾器。
- Listener
Listener就是監(jiān)聽器台盯,我們在JavaSE開發(fā)或者Android開發(fā)時(shí)罢绽,經(jīng)常會(huì)給按鈕加監(jiān)聽器,當(dāng)點(diǎn)擊這個(gè)按鈕就會(huì)觸發(fā)監(jiān)聽事件静盅,調(diào)用onClick方法良价,本質(zhì)是方法回調(diào)。在JavaWeb的Listener也是這么個(gè)原理蒿叠,但是它監(jiān)聽的內(nèi)容不同明垢,它可以監(jiān)聽Application、Session栈虚、Request對(duì)象魂务,當(dāng)這些對(duì)象發(fā)生變化就會(huì)調(diào)用對(duì)應(yīng)的監(jiān)聽方法鬓照。
- ServletContext(監(jiān)聽Application)
//生命周期監(jiān)聽:ServletContextListener void contextInitialized(ServletContextEvent sce):創(chuàng)建Servletcontext時(shí) void contextDestroyed(ServletContextEvent sce):銷毀Servletcontext時(shí) //屬性監(jiān)聽:ServletContextAttributeListener void attributeAdded(ServletContextAttributeEvent event):添加屬性時(shí)豺裆; void attributeReplaced(ServletContextAttributeEvent event):替換屬性時(shí)臭猜; void attributeRemoved(ServletContextAttributeEvent event):移除屬性時(shí)蔑歌;
- HttpSession(監(jiān)聽Session)
//生命周期監(jiān)聽:HttpSessionListener void sessionCreated(HttpSessionEvent se):創(chuàng)建session時(shí) void sessionDestroyed(HttpSessionEvent se):銷毀session時(shí) //屬性監(jiān)聽:HttpSessioniAttributeListener void attributeAdded(HttpSessionBindingEvent event):添加屬性時(shí)次屠; void attributeReplaced(HttpSessionBindingEvent event):替換屬性時(shí) void attributeRemoved(HttpSessionBindingEvent event):移除屬性時(shí)
- ServletRequest(監(jiān)聽Request)
//生命周期監(jiān)聽:ServletRequestListener void requestInitialized(ServletRequestEvent sre):創(chuàng)建request時(shí) void requestDestroyed(ServletRequestEvent sre):銷毀request時(shí) //屬性監(jiān)聽:ServletRequestAttributeListener void attributeAdded(ServletRequestAttributeEvent srae):添加屬性時(shí) void attributeReplaced(ServletRequestAttributeEvent srae):替換屬性時(shí) void attributeRemoved(ServletRequestAttributeEvent srae):移除屬性時(shí)
- 感知Session監(jiān)聽
- HttpSessionBindingListener監(jiān)聽
- 在需要監(jiān)聽的實(shí)體類實(shí)現(xiàn)HttpSessionBindingListener接口;
- 重寫valueBound()方法本昏,這方法是在當(dāng)該實(shí)體類被放到Session中時(shí)凛俱,觸發(fā)該方法蒲犬;
- 重寫valueUnbound()方法原叮,這方法是在當(dāng)該實(shí)體類從Session中被移除時(shí)奋隶,觸發(fā)該方法 唯欣。
- HttpSessionActivationListener監(jiān)聽
- 在需要監(jiān)聽的實(shí)體類實(shí)現(xiàn)HttpSessionActivationListener接口 ;
- 重寫sessionWillPassivate()方法境氢,這方法是在當(dāng)該實(shí)體類被序列化時(shí)萍聊,觸發(fā)該方法 ;
- 重寫sessionDidActivate()方法寿桨,這方法是在當(dāng)該實(shí)體類被反序列化時(shí)亭螟,觸發(fā)該方法预烙。
參見:
servlet詳解(第一篇):https://blog.csdn.net/qq_28483283/article/details/51220749
servlet詳解(第二篇):
https://blog.csdn.net/qq_28483283/article/details/51223735
解析HTTP協(xié)議六種請求方法,get,head,put,delete,post有什么區(qū)別:
https://blog.csdn.net/u010529455/article/details/42918639
JavaWeb三大組件(Servlet欢嘿、Filter炼蹦、Listener):
https://blog.csdn.net/xiaojie119120/article/details/73274759
-
說出你所知的線程同步方法掐隐。
同步主要是為了解決多線程訪問指定數(shù)據(jù)塊時(shí)不同線程間相互影響所導(dǎo)致的結(jié)果混亂虑省,網(wǎng)上自己找資料學(xué)習(xí)了下探颈,線程同步方法主要有6種:
1.synchronized修飾符伪节,java每個(gè)對(duì)象都會(huì)有一個(gè)內(nèi)置鎖怀大,調(diào)用方法前需要獲得鎖化借,否則會(huì)進(jìn)入阻塞態(tài)蓖康。synchronized修飾符可以作用于static靜態(tài)方法(等于鎖住整個(gè)類)钓瞭,但同步性能開銷會(huì)比較大山涡,一般建議鎖住方法中的一部分代碼塊鸭丛。
2.volatile關(guān)鍵字鳞溉,volatile修飾后會(huì)告訴虛擬機(jī)該變量可能會(huì)被多個(gè)線程訪問熟菲,所以系統(tǒng)在使用帶有volatile關(guān)鍵的變量的時(shí)候會(huì)重新計(jì)算該變量抄罕,而不是直接使用寄存器中的值呆贿。需要注意的是此關(guān)鍵字不能和final關(guān)鍵字連用做入。
3.使用重入鎖竟块,java5提供了java.util.concurrent包來支持同步浪秘,ReentrantLock類便是其中l(wèi)ock接口的一個(gè)可重入互斥實(shí)現(xiàn)類秫逝。常用方法有:ReentrantLock() 創(chuàng)建實(shí)例违帆、lock()獲得鎖刷后、unlock()釋放鎖尝胆。注意,使用后及時(shí)釋放鎖含衔,不然會(huì)出現(xiàn)死鎖的現(xiàn)象贪染,一般將鎖釋放放到finally中杭隙。
4.使用局部變量痰憎,ThreadLocal變量铣耘,該變量會(huì)讓每個(gè)使用該變量的線程都獲得一個(gè)副本涡拘,從而隔絕了因?yàn)榇俗兞慷a(chǎn)生的相互影響,是一種用空間換時(shí)間的方法(synchronized是以時(shí)間換空間)跷车。常用方法:ThreadLocal()創(chuàng)建本地變量朽缴,get()返回當(dāng)前線程此局部變量值密强,initialValue()當(dāng)前線程此局部變量初始化值或渤,set(value)設(shè)置當(dāng)前線程此局部變量值薪鹦。
5.使用阻塞隊(duì)列池磁,java5的java.util.concurrent中有LinkedBlockingQueue<E>類地熄,一種先進(jìn)先出的隊(duì)列端考。常用方法:LinkedBlockQueue()創(chuàng)建本地變量跛梗;put(E e)隊(duì)尾添加元素核偿,滿則阻塞漾岳;size()隊(duì)列中元素個(gè)數(shù)尼荆;take()移除并返回隊(duì)首元素捅儒。
6.使用原子變量巧还,java.util.atomic包中提供了多種原子類型變量(如AtomicInteger)麸祷,使用它們可以簡化同步操作阶牍。
-
short s1 = 1走孽; s1 = s1 +1;是否正確?short s1 = 1算撮;s1 += 1;是否正確倒彰?
這是個(gè)主要是涉及一些類型轉(zhuǎn)換的問題待讳,對(duì)于short s1 = 1创淡; s1 = s1 + 1琳彩,因?yàn)? 會(huì)被被系統(tǒng)默認(rèn)為int露乏,所以s1 + 1 結(jié)果會(huì)向上對(duì)齊被存為 int瘟仿, s1 = s1 + 1 的時(shí)候劳较,需要將s1 + 1的int結(jié)果轉(zhuǎn)換為s1的short類型观蜗,而系統(tǒng)沒有從int到short的隱式轉(zhuǎn)換嫂便,所以編譯會(huì)報(bào)錯(cuò),需要強(qiáng)制轉(zhuǎn)換践樱。
然而對(duì)于s1=1拷邢;s1 += 1編譯是沒有問題的忽洛,軟件邏輯雖然是一樣的欲虚,但為什么這樣就不用強(qiáng)轉(zhuǎn)呢复哆?
0 iconst_1
1 istore_1
2 iload_1
3 iconst_1
4 iadd
5 i2s
6 istore_1
7 return
分析下字節(jié)碼梯找,我們會(huì)看偏移量5有i2s字樣(int to short)锈锤,也就是說使用+=的時(shí)候臼隔,編譯器主動(dòng)添加了轉(zhuǎn)換操作,故第二種情況不會(huì)報(bào)錯(cuò)丁寄。
補(bǔ)充一些知識(shí):上述情況對(duì)于 char伊磺、byte屑埋、short都適用摘能,特別是對(duì)于char团搞、byte逻恐、short在棧內(nèi)作為操作數(shù)操作時(shí)都是存為int拨匆,會(huì)自動(dòng)補(bǔ)齊位數(shù)(帶符號(hào))拓展到一個(gè)字長涮雷。int轉(zhuǎn)char洪鸭、byte览爵、short的時(shí)候會(huì)先按短類型將int截?cái)囹阎瘢缓髱Х?hào)壓棧為int俱济,而char蛛碌、byte蔚携、short轉(zhuǎn)int的時(shí)候因?yàn)楸緛砭褪寝D(zhuǎn)int再壓棧,故無需過多轉(zhuǎn)換矾湃。
常見的轉(zhuǎn)換字節(jié)碼有:i2l霉咨,i2s躯护,i2c棺滞,i2b.....等等。
-
HashMap枉证、HashTable室谚、ConcurrentMap的區(qū)別秒赤?
網(wǎng)上看了一下入篮,大概說一下吧:
1.HashMap和HashTable潮售,底層實(shí)現(xiàn)都是數(shù)組+鏈表的形式酥诽,但由于HashTable實(shí)現(xiàn)了同步肮帐,所以變得線程安全了(反之泪姨,HashMap沒有實(shí)現(xiàn)同步故并不線程安全)
2.在使用方面,HashMap對(duì)數(shù)據(jù)沒那么嚴(yán)格袋坑,key和value均可為空枣宫,而HashTable一旦有key為null的情況也颤,立馬拋出NullPointerException異常翅娶。
所以對(duì)于HashMap來說判斷是否有key應(yīng)該用containskey方法(因?yàn)橛胓et方法竭沫,null值可能代表值為null蜕提,也可能代表沒有該值)谎势。
3.最后說說ConcurrentMap脏榆,ConcurrentMap是java 5中提供的對(duì)HashMap進(jìn)行加強(qiáng)的Concurrent實(shí)現(xiàn)類姐霍,實(shí)現(xiàn)了同步镊折,并引入了segment的概念(即分桶)骂因,不同于HashTable的synchronized同步會(huì)鎖住整張表寒波,ConcurrentMap通過lock操作俄烁,鎖定每一個(gè)Segment页屠,而一個(gè)表可以有很多segment辰企,故對(duì)于多線程來說牢贸,擁有更好的并發(fā)性。
-
兩個(gè)對(duì)象值相同(x.equals(y) == true),但卻可有不同的hashcode,這句話對(duì)不對(duì)帮辟?為什么由驹?
這個(gè)問題涉及到equals和hashcode的關(guān)系蔓榄,按理說這兩個(gè)并沒有什么聯(lián)系甥郑,一個(gè)默認(rèn)是比較兩者存儲(chǔ)地址伍俘,一個(gè)是通過hash算法計(jì)算在散列表中的位置癌瘾,但由于很多繼承ojbect類的子類有自己重寫equals方法(有不少會(huì)加入hashcode作為比較條件之一)妨退,所以產(chǎn)生了聯(lián)系。也就是說我們稍微改寫下equals方法便可以讓問題中的情況發(fā)生轻掩,故這句話對(duì)的逝变。
再補(bǔ)充一個(gè)對(duì) “==“ 號(hào)的理解,“==”號(hào)對(duì)于兩個(gè)對(duì)象而言就是比較存儲(chǔ)地址弥臼,是否是同一個(gè)引用径缅。
-
abstract的方法是否可以同時(shí)是static纳猪,是否可同時(shí)是native沙绝,是否可同時(shí)是synchronized鼠锈?為什么购笆?
首先來理解一下這些個(gè)概念:
abstract 抽象類的標(biāo)簽样傍,標(biāo)明該類為抽象類衫哥,目的是申明一些不用馬上實(shí)現(xiàn)的方法炕檩,具體實(shí)現(xiàn)是交由子類完成笛质。
static 靜態(tài)標(biāo)簽,從屬于類而被實(shí)例共享的方法或?qū)傩郧没簦S著類的創(chuàng)建而生成肩杈。
native 本地化標(biāo)簽,是指java中的一部分方法交由操作系統(tǒng)本地的類庫去實(shí)現(xiàn)解寝,看成java語言和其他語言的一種交互手段扩然。
synchronized 同步標(biāo)簽,用于鎖住變量聋伦、方法或者一段代碼夫偶,線程同步鎖界睁。
1.abstract和static,我們知道abstract是指抽象類兵拢,是為了被子類覆蓋而產(chǎn)生多態(tài)访惜,而static 是靜態(tài)的阳柔,方法能被子類繼承而不能被子類重寫暑椰,一方面abstract需要子類覆蓋來實(shí)現(xiàn)多態(tài),而另一方面static又要求不能改寫,設(shè)計(jì)上明顯沖突。
2.abstract和native,abstract要求方法在子類實(shí)現(xiàn),而native表示方法交由操作系統(tǒng)實(shí)現(xiàn)渔扎,不太可能統(tǒng)一愧旦,故沖突。
3.abstract和synchronized遭庶,這一點(diǎn)理解的不是很好,但主要是考慮synchronized同步鎖需要指定具體的同步范圍,如果不知道具體的方法實(shí)現(xiàn)就談不上同步內(nèi)容是什么转捕,根據(jù)語言的設(shè)計(jì)思路和實(shí)際測試,不能同時(shí)使用。
-
請簡述Error、Exception的區(qū)別,你通常如何處理他們?
Error、Exception都共同繼承自Throwable寝衫,Exception還要分RuntimeException和CheckedException事富,Error和RuntimeException組成UncheckedException贱勃。
Error主要用于描述java虛擬機(jī)相關(guān)的錯(cuò)誤(如:系統(tǒng)崩潰纹坐、內(nèi)存溢出等)球切,這類錯(cuò)誤靠程序無法恢復(fù)解決,所以編譯器不會(huì)去檢查焚鹊,遇到這類錯(cuò)誤直接建議終止程序。
RuntimeException一般是程序設(shè)計(jì)引起的一些錯(cuò)誤(如:除零绘证、數(shù)據(jù)越界、空指針等)蚌斩,編譯器不會(huì)去檢查這類錯(cuò)誤盏阶,可處理也可不處理坑律,一般不處理浪蹂。
UncheckedException很多是指外部的一些錯(cuò)誤(如:IO錯(cuò)誤灿渴、文件找不到误续,文件尾后讀數(shù)據(jù)等)恋脚,程序無法避免见间,對(duì)于這類錯(cuò)誤應(yīng)該加以妥善處理,試程序繼續(xù)運(yùn)行宙枷。
在多說一嘴自定義異常:
自定義異常有助于我們將問題細(xì)化贤笆,針對(duì)不同的問題采取不同的手段(如io異常也要分連接斷開飞袋,表不存在,文件損壞等多種不同的情況)夜赵,一般通過繼承Exception實(shí)現(xiàn),使用自定義異常能使系統(tǒng)的魯棒性更好茴肥,使用時(shí)注意結(jié)合業(yè)務(wù),并理解其含義财破。
補(bǔ)充一點(diǎn):
關(guān)于try趟薄,catch妥曲,finally的知識(shí),當(dāng)出現(xiàn)try-catch-finally結(jié)構(gòu)的時(shí)候漫雕,其運(yùn)行順序應(yīng)該是,try中return(若有exception,則發(fā)生excpetion位置)之前的代碼->catch中return之前的代碼(若有exception)->finally中的代碼->catch中的return(若有exception)->try中的return(若無exception)
-
請問springMVC中的DispatcherServlet會(huì)生成幾個(gè)實(shí)例襟己?
其實(shí)這個(gè)問題是坑唤冈,因?yàn)閟pringMVC下的對(duì)象基本都是單實(shí)例的模孩,DispatcherServlet 也不列外崎场。但如果你回答正確說是單實(shí)例的螃宙,面試官又會(huì)接著問你那單實(shí)例的話怎么處理并發(fā)訪問呢燕酷?這種問題對(duì)于互聯(lián)網(wǎng)公司特別愛問彼乌,因?yàn)榛ヂ?lián)公司的并行訪問量一般都比較大耕漱。那對(duì)于這個(gè)問題捧灰,我們先要清楚淆九,servlet 的工作原理是單實(shí)列多線程,因?yàn)橛衧pringMVC和tomcat為我們處理好了多線程的訪問毛俏,所以這方面基本不是問題了炭庙。
當(dāng)然,需要補(bǔ)充的是煌寇,DispathcerServlet可以根據(jù)業(yè)務(wù)需求配置多個(gè)焕蹄,所以也有多個(gè)實(shí)例的情況,但屬于不同的Servlet類阀溶,回答的時(shí)候注意面試官表達(dá)的意思腻脏。
-
hibernate面對(duì)復(fù)雜數(shù)據(jù)應(yīng)該怎樣處理?
自己在網(wǎng)上找了很多银锻,也看了很多永品,比較突出的幾點(diǎn)就是:
- 使用hibernate自帶的sql支持或者直接使用jdbc。
- 從分利用hibernate框架的懶加載击纬。
- 注意控制hibernate中依賴關(guān)系的深度鼎姐。
- 調(diào)節(jié)各種參數(shù)的配置以提高性能與數(shù)據(jù)庫交互的性能。
-
springMVC是怎樣完成一次頁面請求的?
主要是需要注意到springMVC中的dispatcher實(shí)質(zhì)上也是一個(gè)servlet炕桨。
具體流程如下:前端通過ajax傳過來命令和數(shù)據(jù)饭尝,dispatcherservlet 分析它的url或者根據(jù)其他信息分發(fā)到不同的controller下面,controller接著將數(shù)據(jù)傳向下層service谋作,service層再往下傳到dao層芋肠,而dao層一般就是mybatis或者h(yuǎn)ibernate框架與mysql數(shù)據(jù)庫進(jìn)行交互并更新或得到數(shù)據(jù),數(shù)據(jù)得到后反向通過dao遵蚜、service到controller層帖池,controller將數(shù)據(jù)封裝成合適的格式調(diào)用servlet的response返回到前端頁面。
TO BE CONTINUED ......