03.01 java面試流程

JAVA就業課程

1、 面試整體流程

1.1 簡單的自我介紹

我是xxxx,工作xxx年.我先後在xxxx公司、yyyy公司工作。先後做個xxxx項目、yyyy項目。

1.2 你簡單介紹一下xxxx項目

為了解決xxxx問題,開發了一套xxxx系統,該系統主要有那些部分組成。簡單介紹項目的整體架構。參與某個模塊的開發。就要求你說一下這個模塊的業務及設計。

1.3 會問一下JAVA的專業技能

後面詳細講解

1.4你還有什麼需要詢問我的嗎

公司要做的項目?項目中會使用一下什麼技術?


注意:經歷了多輪面試後,對於你的自我介紹和項目項目經驗面試官就不太關心了。

你說一下你最擅長的什麼?你簡單說一下?

最終技術面試完成後,都會讓你回家等消息,或者等hr來和你談薪資和福利。

2、 java的專業技能

2.1 java的基礎部分

2.1.1 簡單講一下java的跨平臺原理

由於各操作系統(windows,liunx等)支持的指令集,不是完全一致的。就會讓我們的程序在不同的操作系統上要執行不同程序代碼。Java開發了適用於不同操作系統及位數的java虛擬機來屏蔽個系統之間的差異,提供統一的接口。對於我們java開發者而言,你只需要在不同的系統上安裝對應的不同java虛擬機、這時你的java程序只要遵循java規範,就可以在所有的操作系統上面運行java程序了。


Java通過不同的系統、不同版本、不同位數的java虛擬機(jvm),來屏蔽不同的系統指令集差異而對外體統統一的接口(java API),對於我們普通的java開發者而言,只需要按照接口開發即可。如果我係統需要部署到不同的環境時,只需在系統上面按照對應版本的虛擬機即可。

java面試流程

2.2.2 搭建一個java開發環境的步驟

Java開發環境需要些什麼?


1、 適用於我們開發環境的jdk

2、 對應開發環境eclipse

3、 還需要web服務器(tomcat)


1、 下載對應組件

2、 安裝

Jdk,安裝正常流程安裝即可,配置我們的JAVA_HOME,因為後面的eclispe和tomcat會依賴於這個變量.

Eclispe正常解壓就ok,設置workspace的默認編碼

Tomcat 正常解壓就ok,把tomcat集成到eclispe中,安裝插件就OK。

.......

Svn/git


2.1.3講一下java中int數據佔幾個字節

Java中有幾種基本數據類型?8種

java面試流程


Int佔 4個字節,32位

Boolean 1位


2.1.4 面向對象的特徵有哪些方面

有四大基本特徵:封裝、抽象、繼承、多態

面向對象的封裝性,即將對象封裝成一個高度自治和相對封閉的個體,對象狀態(屬性)由這個對象自己的行為(方法)來讀取和改變。

張三這個人,他的姓名等屬性,要有自己提供的獲取或改變的方法來操作。private name setName getName

抽象就是找出一些事物的相似和共性之處,然後將這些事物歸為一個類,這個類只考慮這些事物的相似和共性之處,並且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。 就是把現實生活中的對象,抽象為類。

在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,並可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。遺產繼承

多態是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時並不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。


Object obj = new xxx();

UserDao userDao = new UserDaoJdbcImpl();

UserDao userDao = new UserDaoHibernateImpl();

靠的是父類或接口定義的引用變量可以指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。


原則:回答比較抽象問題的時候,要舉例說明


2.1.5有了基本數據類型,為什麼還需要包裝類型?

基本數據類型,java中提供了8中基本的數據類型。boolean int float等


包裝類型:每一個基本的數據類型都會一一對應一個包裝類型。

boolean ----->Boolean

Int -------->Integer


裝箱和拆箱

裝箱:把基本的數據類型轉換成對應的包裝類型.

Integer .valueOf(1)

Integer i = 1;自動裝箱,實際上在編譯時會調用Integer .valueOf方法來裝箱

拆箱:就是把包裝類型轉換為基本數據類型.基本數據類型 名稱 = 對應的包裝類型。

Integer i = 1;

int j = i;//自動拆箱//int j = i=intValue();手動拆箱

自動拆箱:實際上會在編譯調用intValue


Java是一個面向對象的語言,而基本的數據類型,不具備面向對象的特性。

null Integer--->null int---->0 用Integer和int分別表示Person這個類的ID

Max 最大值

min 最小值

緩存值:對象緩存,Integer i=1; integer j= 1;i ==j


2.1.6、說一下"=="和equals方法究竟有什麼區別?

非常經典的一個面試題?先說清楚一個,再來說另一個?

==用來判斷兩個變量之間的的值是否相等。變量就可以分為基本數據類型變量,引用類型。

如果是基本數據類型的變量直接比較值而引用類型要比較對應的引用的內存的首地址。

java面試流程


equals 用來比較兩個對象長得是否一樣。判斷兩個對象的某些特徵是否一樣。實際上就是調用對象的equals方法進行比較。


2.1.7講一下String和StringBuilder的區別(final)?StringBuffer和StringBuilder的區別?


1.在java中提供三個類String StringBuillder StringBuffer來表示和操作字符串。字符串就是多個字符的集合。

String是內容不可變的字符串。String底層使用了一個不可變的字符數組(final char[])

java面試流程

String str =new String("bbbb");

而StringBuillder StringBuffer,是內容可以改變的字符串。StringBuillder StringBuffer底層使用的可變的字符數組(沒有使用final來修飾)

java面試流程


2.最經典就是拼接字符串。

1、 String進行拼接.String c = "a"+"b";

2、 StringBuilder或者StringBuffer

StringBuilder sb = new StringBuilder(); sb.apend("a").apend("b")


拼接字符串不能使用String進行拼接,要使用StringBuilder或者StringBuffer


3.StringBuilder是線程不安全的,效率較高.而StringBuffer是線程安全的,效率較低。


2.1.8、講一下java中的集合?

Java中的集合分為value,key--vale(Conllection Map)兩種。

存儲值有分為List 和Set.

List是有序的,可以重複的。

Set是無序的,不可以重複的。根據equals和hashcode判斷,也就是如果

一個對象要存儲在Set中,必須重寫equals和hashCode方法。

存儲key-value的為map.


8、 ArrayList和LinkedList的區別?

List常用的ArrayList和LinkedList。區別和使用場景?

ArrayList底層使用時數組。LinkedList使用的是鏈表。

數組查詢具有所有查詢特定元素比較快。而插入和刪除和修改比較慢(數組在內存中是一塊連續的內存,如果插入或刪除是需要移動內存)。

鏈表不要求內存是連續的,在當前元素中存放下一個或上一個元素的地址。查詢時需要從頭部開始,一個一個的找。所以查詢效率低。插入時不需要移動內存,只需改變引用指向即可。所以插入或者刪除的效率高。


ArrayList使用在查詢比較多,但是插入和刪除比較少的情況,而LinkedList使用在查詢比較少而插入和刪除比較多的情況。


2.1.9講一下HashMap哈HashTable的區別?HashTable和ConcurrentHashMap的區別?

相同點:HashMap和HasheTalbe都可以使用來存儲key--value的數據。

區別:

1、 HashMap是可以把null作為key或者value的,而HashTable是不可以的。

2、 HashMap是線程不安全的,效率較高。而HashTalbe是線程安全的,效率較低。


?我想線程安全但是我又想效率高?

通過把整個Map分為N個Segment(類似HashTable),可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。


2.1.10、實現一個拷貝文件的工具類使用字節流還是字符流?

我們拷貝的文件不確定是隻包含字符流,有可以能有字節流(圖片、聲音、圖像等),為考慮到通用性,要使用字節流。


2.1.11、講一下線程的幾種實現方式?啟動方式?區分方式?

①實現方式

1、 通過繼承Thread類實現一個線程

2、 通過實現Runnable接口實現一個線程

繼承擴展性不強,java總只支持單繼承,如果一個類繼承Thread就不能繼承其他的類了。

②怎麼啟動?

Thread thread = new Thread(繼承了Thread的對象/實現了Runnable的對象)

thread.setName("設置一個線程名稱");

thread.start();

啟動線程使用start方法,而啟動了以後執行的是run方法。

③怎麼區分線程?在一個系統中有很多線程,每個線程都會打印日誌,我想區分是哪個線程打印的怎麼辦?

thread.setName("設置一個線程名稱"); 這是一種規範,在創建線程完成後,都需要設置名稱。


2.1.12有沒有使用過線程併發庫?

簡單瞭解過?

JDK5中增加了Doug Lea的併發庫,這一引進給Java線程的管理和使用提供了強大的便利性。 java.util.current包中提供了對線程優化、管理的各項操作,使得線程的使用變得的心應手。該包提供了線程的運行,線程池的創建,線程生命週期的控制.


Java通過Executors提供四個靜態方法創建四種線程池,分別為:

newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。

newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。

newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。

newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行


2.1.13線程池的作用?

1、 限定線程的個數,不會導致由於線程過多導致系統運行緩慢或崩潰

2、 線程池不需要每次都去創建或銷燬,節約了資源、

3、 線程池不需要每次都去創建,響應時間更快。

連接池也是一樣?


2.1.14講一下什麼是設計模式?常用的設計模式有哪些?

設計模式就是經過前人無數次的實踐總結出的,設計過程中可以反覆使用的、可以解決特定問題的設計方法。


單例(飽漢模式、飢漢模式)

1、 構造方法私有化,讓出了自己類中能創建外其他地方都不能創建

2、在自己的類中創建一個單實例(飽漢模式是一出來就創建創建單實例,而飢漢模式需要的時候才創建)

3、提供一個方法獲取該實例對象(創建時需要進行方法同步)

工廠模式:Spring IOC就是使用了工廠模式.

對象的創建交給一個工廠去創建。

代理模式:Spring AOP就是使用的動態代理。


2.2 java web部分

2.2.1講一下http get和post請求的區別?


GET和POST請求都是http的請求方式,用戶通過不同的http的請求方式完成對資源(url)的不同操作。GET,POST,PUT,DELETE就對應著對這個資源的查 ,改 ,增 ,刪 4個操作,具體點來講GET一般用於獲取/查詢資源信息,而POST一般用於更新資源信息


1、Get請求提交的數據會在地址欄顯示出來,而post請求不會再地址欄顯示出來.

GET提交,請求的數據會附在URL之後(就是把數據放置在HTTP協議頭中),以?分割URL和傳輸數據,多個參數用&連接;POST提交:把提交的數據放置在是HTTP包的包體中。 因此,GET提交的數據會在地址欄中顯示出來,而POST提交,地址欄不會改變

2、傳輸數據的大小

http Get請求由於瀏覽器對地址長度的限制而導致傳輸的數據有限制。而POST請求不會因為地址長度限制而導致傳輸數據限制。

3、安全性,POST的安全性要比GET的安全性高。由於數據是會在地址中呈現,所以可以通過歷史記錄找到密碼等關鍵信息。

2.2.2 說一下你對servlet的理解?或者servlet是什麼?

Servlet(Server Applet),全稱Java Servlet, 是用Java編寫的服務器端程序。而這些Sevlet都要實現Servlet這個藉口。其主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。Servlet運行於支持Java的應用服務器中。


HttpServlet 重寫doGet和doPost方法或者你也可以重寫service方法完成對get和post請求的響應

2.2.3簡單說一下servlet的生命週期?

servlet有良好的生存期的定義,包括加載和實例化、初始化、處理請求以及服務結束。這個生存期由javax.servlet.Servlet接口的init,service和destroy方法表達。


加載Servlet的class---->實例化Servlet----->調用Servlet的init完成初始化---->響應請求(Servlet的service方法)----->Servlet容器關閉時(Servlet的destory方法)


Servlet啟動時,開始加載servlet生命週期開始。Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX方法(doGet,doPost)等,當服務器決定將實例銷燬的時候(服務器關閉)調用其destroy方法。


2.2.4 Servlet API中forward() 與redirect()的區別?

1、 forward是服務器端的轉向而redirect是客戶端的跳轉。

2、 使用forward瀏覽器的地址不會發生改變。而redirect會發生改變。

3、 Forward是一次請求中完成。而redirect是重新發起請求。

4、 Forward是在服務器端完成,而不用客戶端重新發起請求,效率較高。


2.2.5 JSP和Servlet有哪些相同點和不同點?

JSP是Servlet技術的擴展,所有的jsp文件都會被翻譯為一個繼承HttpServlet的類。也就是jsp最終也是一個Servlet.這個Servlet對外提供服務。

java面試流程

Servlet和JSP最主要的不同點在於JSP側重於視圖,Servlet主要用於控制邏輯。


Servlet如果要實現html的功能,必須使用Writer輸出對應的html,比較麻煩。而JSP的情況是Java和HTML可以組合成一個擴展名為.jsp的文件,做界面展示比較方便而嵌入邏輯比較複雜。


2.2.6 jsp有哪些內置對象?作用分別是什麼?

9個內置的對象:

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

response 網頁傳回用戶端的回應

pageContext 網頁的屬性是在這裡管理

session 與請求有關的會話期

application servlet正在執行的內容

out 用來傳送回應的輸出

config servlet的構架部件

page JSP網頁本身

exception 針對錯誤網頁,未捕捉的例外

四大作用域:pageContext request session application 可以通過jstl從四大作用域中取值.

Jsp傳遞值request session application cookie也能傳值


2.2.7說一下session和cookie的區別?你在項目中都有哪些地方使用了?

Session和cookie都是會話(Seesion)跟蹤技術。Cookie通過在客戶端記錄信息確定用戶身份,Session通過在服務器端記錄信息確定用戶身份。但是Session的實現依賴於Cookie,sessionId(session的唯一標識需要存放在客戶端).

cookie 和session 的區別:

1、cookie數據存放在客戶的瀏覽器上,session數據放在服務器上。

2、cookie不是很安全,別人可以分析存放在本地的COOKIE並進行COOKIE欺騙 考慮到安全應當使用session。

3、session會在一定時間內保存在服務器上。當訪問增多,會比較佔用你服務器的性能,考慮到減輕服務器性能方面,應當使用COOKIE。

4、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。

5、所以個人建議: 將登陸信息等重要信息存放為SESSION 其他信息如果需要保留,可以放在COOKIE中,比如購物車


購物車最好使用cookie,但是cookie是可以在客戶端禁用的,這時候我們要使用cookie+數據庫的方式實現,當從cookie中不能取出數據時,就從數據庫獲取。


2.2.8、MVC的各個部分都有那些技術來實現?

M(Model) 模型 javabean

V(View) 視圖 html jsp volicity freemaker

C(Control) 控制器 Servlet,Action


Jsp+Servlet+javabean 最經典mvc模式,實際上就是model2的實現方式,就是把視圖和邏輯隔離開來

Model1的方式 jsp+service+dao

MOdel2的方式 jsp+servlet+service+dao


使用struts2和springmvc這樣的mvc框架後,jsp+核心控制器+action+javabean


2.3數據庫部分

2.3.1數據庫的分類及常用的數據庫

數據庫分為:關係型數據庫和非關係型數據庫

關係型:mysql oracle sqlserver等

非關係型:redis,memcache,mogodb,hadoop等

2.3.2簡單介紹一下關係數據庫三範式?

範式就是規範,就是關係型數據庫在設計表時,要遵循的三個規範。

要想滿足第二範式必須先滿足第一範式,要滿足第三範式必須先滿足第二範式。


<code>第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。列數據的不可分割/<code>
<code>二範式(2NF)要求數據庫表中的每個行必須可以被唯一地區分。為實現區分通常需要為表加上一個列,以存儲各個實例的唯一標識。(主鍵) 滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。(外鍵)反三範式,有的時候為了效率,可以設置重複或者可以推導出的字段.        訂單(總價)和訂單項(單價)2.3.3事務四個基本特徵或 ACID 特性。事務是併發控制的單位,是用戶定義的一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。一個轉賬必須 A賬號扣錢成功,B賬號加錢成功,才算正真的轉賬成功。  事務必須滿足四大特徵:原子性,一致性,隔離性持久性/持續性 原子性:表示事務內操作不可分割。要麼都成功、要麼都是失敗. 一致性:要麼都成功、要麼都是失敗.後面的失敗了要對前面的操作進行回滾。 隔離性:一個事務開始後,不能後其他事務干擾。 持久性/持續性:表示事務開始了,就不能終止。2.3.4 mysql數據庫的默認的最大連接數?100  為什麼需要最大連接數?特定服務器上面的數據庫只能支持一定數目同時連接,這時候我們一般都會設置最大連接數(最多同時服務多少連接)。在數據庫安裝時都會有一個默認的最大連接數為1002.3.5說一下msyql的分頁?Oracle的分頁?為什麼需要分頁?在很多數據是,不可能完全顯示數據。進行分段顯示.Mysql是使用關鍵字limit來進行分頁的 limit offset,size 表示從多少索引去多少位.Oracle的分頁,大部分情況下,我們是記不住了。說思路,要使用三層嵌套查詢。   Oracle的分頁有點兒記不住了,只記得一些大概。是使用了三層嵌套查詢。如果在工作中使用了,可以到原來的項目中拷貝或上網查詢。mysql:  \tString sql = \t"select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;\toracle: \tString sql = \t "select * from " +  \t (select *,rownum rid from (select * from students order by postime desc) where rid<=" + pagesize*pagenumber + ") as t" + \t "where t>" + pageSize*(pageNumber-1);2.3.6簡單講一下數據庫的觸發器的使用場景?觸發器,需要有觸發條件,當條件滿足以後做什麼操作。觸發器用處還是很多的,比如校內網、開心網、Facebook,你發一個日誌,自動通知好友,其實就是在增加日誌時做一個後觸發,再向通知表中寫入條目。因為觸發器效率高。而UCH沒有用觸發器,效率和數據處理能力都很低。每插入一個帖子,都希望將版面表中的最後發帖時間,帖子總數字段進行同步更新,用觸發器做效率就很高。\t2.3.7 簡單講一下數據庫的存儲過程的使用場景?數據庫存儲過程具有如下優點:1、存儲過程只在創建時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般 SQL 語句每執行一次就編譯一次,因此使用存儲過程可以大大提高數據庫執行速度。2、通常,複雜的業務邏輯需要多條 SQL 語句。這些語句要分別地從客戶機發送到服務器,當客戶機和服務器之間的操作很多時,將產生大量的網絡傳輸。如果將這些操作放在一個存儲過程中,那麼客戶機和服務器之間的網絡傳輸就會大大減少,降低了網絡負載。3、存儲過程創建一次便可以重複使用,從而可以減少數據庫開發人員的工作量。4、安全性高,存儲過程可以屏蔽對底層數據庫對象的直接訪問,使用 EXECUTE 權限調用存儲過程,無需擁有訪問底層數據庫對象的顯式權限。正是由於存儲過程的上述優點,目前常用的數據庫都支持存儲過程,例如 IBM DB2,Microsoft SQL Server,Oracle,Access 等,開源數據庫系統 MySQL 也在 5.0 的時候實現了對存儲過程的支持。定義存儲過程:\t2.3.8 用jdbc怎麼調用存儲過程?賈璉欲執事加載驅動獲取連接設置參數執行釋放連接package com.huawei.interview.lym;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Types;public class JdbcTest {\t/**\t * @param args\t */\tpublic static void main(String[] args) {\t\t// TODO Auto-generated method stub\t\tConnection cn = null;\t\tCallableStatement cstmt = null;\t\t\t\ttry {\t\t\t//這裡最好不要這麼幹,因為驅動名寫死在程序中了\t\t\tClass.forName("com.mysql.jdbc.Driver");\t\t\t//實際項目中,這裡應用DataSource數據,如果用框架,\t\t\t//這個數據源不需要我們編碼創建,我們只需Datasource ds = context.lookup()\t\t\t//cn = ds.getConnection();\t\t\t\t\t\tcn = DriverManager.getConnection("jdbc:mysql:///test","root","root");\t\t\tcstmt = cn.prepareCall("{call insert_Student(?,?,?)}");\t\t\tcstmt.registerOutParameter(3,Types.INTEGER);\t\t\tcstmt.setString(1, "wangwu");\t\t\tcstmt.setInt(2, 25);\t\t\tcstmt.execute();\t\t\t//get第幾個,不同的數據庫不一樣,建議不寫\t\t\tSystem.out.println(cstmt.getString(3));\t\t} catch (Exception e) {\t\t\t// TODO Auto-generated catch block\t\t\te.printStackTrace();\t\t}\t\tfinally\t\t{\t\t\t/*try{cstmt.close();}catch(Exception e){}\t\t\ttry{cn.close();}catch(Exception e){}*/\t\t\ttry {\t\t\t\tif(cstmt != null)\t\t\t\t\tcstmt.close();\t\t\t\tif(cn != null)\t\t\t\t\t\t\t\t\tcn.close();\t\t\t} catch (SQLException e) {\t\t\t\t// TODO Auto-generated catch block\t\t\t\te.printStackTrace();\t\t\t}\t\t}\t}2.3.9常用SQL略2.3.10簡單說一下你對jdbc的理解?Java database connection java數據庫連接.數據庫管理系統(mysql oracle等)是很多,每個數據庫管理系統支持的命令是不一樣的。Java只定義接口,讓數據庫廠商自己實現接口,對於我們者而言。只需要導入對應廠商開發的實現即可。然後以接口方式進行調用.(mysql + mysql驅動(實現)+jdbc)2.3.11 寫一個簡單的jdbc的程序。寫一個訪問oracle數據的jdbc程序?賈璉欲執事加載驅動(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)獲取連接(DriverManager.getConnection(url,usernam,passord))設置參數  Statement PreparedStatement            cstmt.setXXX(index, value);執行   executeQuery executeUpdate釋放連接(是否連接要從小到大,必須放到finnaly)2.3.12 JDBC中的PreparedStatement相比Statement的好處大多數我們都使用PreparedStatement代替Statement1:PreparedStatement是預編譯的,比Statement速度快 2:代碼的可讀性和可維護性雖然用PreparedStatement來代替Statement會使代碼多出幾行,但這樣的代碼無論從可讀性還是可維護性上來說.都比直接用Statement的代碼高很多檔次:stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')"); perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");perstmt.setString(1,var1);perstmt.setString(2,var2);perstmt.setString(3,var3);perstmt.setString(4,var4);perstmt.executeUpdate();不用我多說,對於第一種方法,別說其他人去讀你的代碼,就是你自己過一段時間再去讀,都會覺得傷心。 3:安全性PreparedStatement可以防止SQL注入攻擊,而Statement卻不能。比如說:String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";如果我們把[' or '1' = '1]作為varpasswd傳入進來.用戶名隨意,看看會成為什麼?select * from tb_name = '隨意' and passwd = '' or '1' = '1';因為'1'='1'肯定成立,所以可以任何通過驗證,更有甚者:把[';drop table tb_name;]作為varpasswd傳入進來,則:select * from tb_name = '隨意' and passwd = '';drop table tb_name;有些數據庫是不會讓你成功的,但也有很多數據庫就可以使這些語句得到執行。而如果你使用預編譯語句你傳入的任何內容就不會和原來的語句發生任何匹配的關係,只要全使用預編譯語句你就用不著對傳入的數據做任何過慮。而如果使用普通的statement,有可能要對drop等做費盡心機的判斷和過慮。2.3.13 數據庫連接池作用1、限定數據庫的個數,不會導致由於數據庫連接過多導致系統運行緩慢或崩潰2、數據庫連接不需要每次都去創建或銷燬,節約了資源3、數據庫連接不需要每次都去創建,響應時間更快。2.4 前端部分2.4.1簡單說一下html,css,javascript在網頁開發中的定位?HTML 超文本標記語言 定義網頁的結構CSS 層疊樣式表,用來美化頁面JavaScript主要用來驗證表單,做動態交互(其中ajax)2.4.2簡單介紹一下Ajax?  什麼是Ajax? 異步的javascript和xml  作用是什麼?通過AJAX與服務器進行數據交換,AJAX可以使網頁實現佈局更新。\t      這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。  怎麼來實現Ajax XmlHttpRequest對象,使用這個對象可以異步向服務器發送請求,獲取獲取響應,完成局部更新。Open send responseText/responseXML 局部響應.  使用場景 登陸失敗時不跳轉頁面,註冊時提示用戶名是否存在,二級聯動等等使用場景2.4.3 js和jQuery的關係?  jQuery是一個js框架,封裝了js的屬性和方法。讓用戶使用起來更加便利。,並且增強了js的功能.使用原生js是要處理很多兼容性的問題(註冊事件等),由jQuery封裝了底層,就不用處理兼容性問題。原生的js的dom和事件綁定和Ajax等操作非常麻煩,jQuery封裝以後操作非常方便。2.4.4 jQuery的常用選擇器?ID選擇器   通過ID獲取一個元素Class選擇器 通過類(css)獲取元素標籤選擇器 通過標籤獲取元素通用選擇器(*) 獲取所以的元素div.myCls  獲取有myCls這個類的div層次選擇器     兒子選擇器 > 獲取下面的子元素     後代選擇器 空格 獲取下面後代,包括兒子、孫子等後代屬性選擇器    Tag[attrName='test'] 獲取有屬性名為xxxx並且屬性的值為test的所有xxx標籤     吃飯 

睡覺
Input[name='hobby'],表示獲取屬性名為name並且name屬性值為hobby的的所有input標籤元素 2.4.5 jQuery的頁面加載完畢事件? 很多時候我們需要獲取元素,但是必須等到該元素被加載完成後才能獲取。我們可以把js代碼放到該元素的後面,但是這樣就會造成js在我們的body中存在不好管理。所有頁面加載完畢後所有的元素當然已經加載完畢。一般獲取元素做操作都要在頁面加載完畢後操作。\t\t\t2.4.6 Jquery的Ajax和原生Js實現Ajax有什麼關係?jQuery中的Ajax也是通過原生的js封裝的。封裝完成後讓我們使用起來更加便利,不用考慮底層實現或兼容性等處理。如果採用原生js實現Ajax是非常麻煩的,並且每次都是一樣的。如果我們不使用jQuery我們也要封裝Ajax對象的方法和屬性。有像jQuery這些已經封裝完成,並經過很多企業實際的框架,比較可靠並且開源。我們就不需要封裝,直接使用成熟的框架(jQuery)即可.2.4.7簡單說一下html5?你對現在的那些新技術有了解?Html5是最新版本的html,是在原來html4的基礎上增強了一些標籤。Html增加一些像畫板、聲音、視頻、web存儲等高級功能。但是html5有一個不好的地方,那就是html5太強調語義了,導致開發中都不知道要選擇那個標籤。 在做頁面佈局是,無論頭部、主題、導航等模塊都使用div來表示,但是html5的規範,需要使用不同的標籤來表示。(header footer等)你對現在的那些新技術有了解Html5 css3等2.4.8 簡單說一下css3? Css3是最新版本的css,是對原理css2的功能增強。 Css3中提供一些原來css2中實現起來比較困難或者不能實現的功能。 1、盒子圓角邊框 2、盒子和文字的陰影 3、漸變 4、轉換 移動、縮放、旋轉等 5、過渡、動畫都可以使用動畫。 6、可以使用媒體查詢實現響應式網站。 Css3最大缺點就是要根據不同的瀏覽器處理兼容性。對應有一些處理兼容性的工具。不用擔心.2.4.9 bootstrap是什麼?BootStrap是一個移動設備優先的UI框架。我們可以不用謝任何css,js代碼就能實現比較漂亮的有交互性的頁面。我們程序員對頁面的編寫是有硬傷的,所有要自己寫頁面的話就要使用類似於bootstrap這樣的UI框架。平時用得很多的:1、 模態框2、 表單,表單項3、 佈局4、 刪格系統2.5 框架部分2.5.1什麼是框架? 框架(Framework)是一個框子——指其約束性,也是一個架子——指其支撐性。 IT語境中的框架,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構。在此結構上可以根據具體問題擴展、安插更多的組成部分,從而更迅速和方便地構建完整的解決問題的方案。1)框架本身一般不完整到可以解決特定問題,但是可以幫助您快速解決特定問題; 沒有框架所有的工作都從零開始做,有了框架,為我們提供了一定的功能,我們就可以在框 架的基礎上開發,極大的解放了生產力。不同的框架,是為了解決不同領域的問題。一定要為了解決問題才去學習框架。2)框架天生就是為擴展而設計的;3)框架裡面可以為後續擴展的組件提供很多輔助性、支撐性的方便易用的實用工具(utilities),也就是說框架時常配套了一些幫助解決某類問題的庫(libraries)或工具(tools)。 java中就是一系列的jar包,其本質就是對jdk功能的擴展.2.5.2 MVC模式 MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典範,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件裡面,在改進和個性化定製界面及用戶交互的同時,不需要重新編寫業務邏輯。最簡單的、最經典就是Jsp(view) +Servlet(controller) + JavaBean(model)1、 當控制器收到來自用戶的請求2、 控制器調用JavaBean完成業務3、 完成業務後通過控制器跳轉JSP頁面的方式給用戶反饋信息4、 Jsp個 用戶做出響應。 控制器都是核心2.5.3 MVC框架什麼是MVC框架? 是為了解決傳統MVC模式(Jsp + Servlet + JavaBean)的一些問題而出現的框架。傳統MVC模式問題1、 所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大,並且不能實現模塊化管理。2、 Servlet的主要功能就是接受參數、調用邏輯、跳轉頁面,比如像其他字符編碼、文件上傳等功能也要寫在Servlet中,不能讓Servlet主要功能而需要做處理一下特例。3、接受參數比較麻煩(String name = request.getParameter("name"),User user=new User user.setName(name)),不能通過model接收,只能單個接收,接收完成後轉換封裝model.4、跳轉頁面方式比較單一(forword,redirect),並且當我的頁面名稱發生改變時需要修改Servlet源代碼.現在比較常用的MVC框架有: struts webwork Struts2 Spring MVC2.5.4 簡單講一下struts2的執行流程?Struts2的原理?一個請求在Struts2框架中的處理大概分為以下幾個步驟:1、客戶端瀏覽器發送請求2、這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對於Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin);3、接著FilterDispatcher(StrutsPrepareAndExecuteFilter)被調用,FilterDispatcher(StrutsPrepareAndExecuteFilter)詢問ActionMapper來決定這個請求是否需要調用某個Action;4、 如果ActionMapper決定需要調用某個Action,FilterDispatcher (StrutsPrepareAndExecuteFilter)把請求的處理交給ActionProxy;5、ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類;6、ActionProxy創建一個ActionInvocation的實例。7、ActionInvocation實例使用命名模式來調用,在調用Action的過程前後,涉及到相關攔截器(Intercepter)的調用。8、一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2框架中繼承的標籤。在這個過程中需要涉及到ActionMapper。面試:1、 瀏覽器發送請求,經過一系列的過濾器後,到達核心過濾器(StrutsPrepareAndExecuteFilter).2、 StrutsPrepareAndExecuteFilter通過ActionMapper判斷當前的請求是否需要某個Action處理,如果不需要,則走原來的流程。如果需要則把請求交給ActionProxy來處理3、 ActionProxy通過Configuration Manager詢問框架的配置文件(Struts.xml),找到需要調用的Action類;4、 創建一個ActionInvocation實例,來調用Action的對應方法來獲取結果集的name,在調用前後會執行相關攔截器。5、 通過結果集的Name知道對應的結果集來對瀏覽器進行響應。攔截、判斷、尋找、執行、響應2.5.5 Struts2中的攔截器,你都用它幹什麼?\tjava裡的攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行,同時也提供了一種可以提取action中可重用部分的方式。\t在AOP(Aspect-Oriented Programming)中攔截器用於在某個方法或字段被訪問之前,進行攔截然後在之前或之後加入某些操作。面試: struts2中的的功能(參數處理、文件上傳、字符編碼等)都是通過系統攔截器實現的。如果業務需要,當然我們也可以自定義攔截器,進行可插拔配置,在執行Action的方法前後、加入相關邏輯完成業務。使用場景:1、 用戶登錄判斷,在執行Action的前面判斷是否已經登錄,如果沒有登錄的跳轉到登錄頁面。2、 用戶權限判斷,在執行Action的前面判斷是否具有,如果沒有權限就給出提示信息。3、 操作日誌...... 4、......2.5.6 簡單講一下SpringMVC的執行流程?  1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;  2. DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然後根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回; 3. DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附註:如果成功獲得HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法)   4.  提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,根據你的配置,Spring將幫你做一些額外的工作:      HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息      數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等      數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等      數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中      5.  Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;      6.  根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;      7. ViewResolver 結合Model和View,來渲染視圖      8. 將渲染結果返回給客戶端。面試:1、 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲(捕獲)2、 DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然後根據該URI,調用HandlerMapping獲得該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;(查找handler)3、 DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller), Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象(執行handler)4、DispatcherServlet 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver) (選擇ViewResolver)5、通過ViewResolver 結合Model和View,來渲染視圖,DispatcherServlet 將渲染結果返回給客戶端。(渲染返回)快速記憶技巧:核心控制器捕獲請求、查找Handler、執行Handler、選擇ViewResolver,通過ViewResolver渲染視圖並返回2.5.7 說一下struts2和springMVC有什麼不同?目前企業中使用SpringMvc的比例已經遠遠超過Struts2,那麼兩者到底有什麼區別,是很多初學者比較關注的問題,下面我們就來對SpringMvc和Struts2進行各方面的比較:1. 核 心控制器(前端控制器、預處理控制器):對於使用過mvc框架的人來說這個詞應該不會陌生,核心控制器的主要用途是處理所有的請求,然後對那些特殊的請求 (控制器)統一的進行處理(字符編碼、文件上傳、參數接受、異常處理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。2.控制器實例:Spring Mvc會比Struts快一些(理論上)。Spring Mvc是基於方法設計,而Sturts是基於對象,每次發一次請求都會實例一個action,每個action都會被注入 屬性,而Spring更像Servlet一樣,只有一個實例,每次請求執行對應的方法即可(注意:由於是單例實例,所以應當避免全局變量的修改,這樣會產生線程安全問題)。3. 管理方式:大部分的公司的核心架構中,就會使用到spring,而spring mvc又是spring中的一個模塊,所以spring對於spring mvc的控制器管理更加簡單方便,而且提供了全 註解方式進行管理,各種功能的註解都比較全面,使用簡單,而struts2需要採用XML很多的配置參數來管理(雖然也可以採用註解,但是幾乎沒有公司那 樣使用)。4.參數傳遞:Struts2中自身提供多種參數接受,其實都是通過(ValueStack)進行傳遞和賦值,而SpringMvc是通過方法的參數進行接收。5.學習難度:Struts更加很多新的技術點,比如攔截器、值棧及OGNL表達式,學習成本較高,springmvc 比較簡單,很較少的時間都能上手。6.intercepter 的實現機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現restful url。struts2是類級別的攔截,一個類對應一個request上下文;實現restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共享,這也就無法用註解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼,讀程序時帶來麻煩。7. spring mvc處理ajax請求,直接通過返回數據,方法中使用註解@ResponseBody,spring mvc自動幫我們對象轉換為JSON數據。而struts2是通過插件的方式進行處理在SpringMVC流行起來之前,Struts2在MVC框架中佔核心地位,隨著SpringMVC的出現,SpringMVC慢慢的取代struts2,但是很多企業都是原來搭建的框架,使用Struts2較多。2.5.8 說一下Spring中的兩大核心?Spring是什麼?spring是J2EE應用程序框架,是輕量級的IoC和AOP的容器框架(相對於重量級的EJB),主要是針對javaBean的生命週期進行管理的輕量級容器,可以單獨使用,也可以和Struts框架,ibatis框架等組合使用。1、 IOC(Inversion of Control )或DI(Dependency Injection) IOC控制權反轉 原來:我的Service需要調用DAO,Service就需要創建DAO Spring:Spring發現你Service依賴於dao,就給你注入. 核心原理:就是配置文件+反射(工廠也可以)+容器(map) 2、 AOP:面向切面編程 核心原理:使用動態代理的設計模式在執行方法前後或出現異常做加入相關邏輯。 我們主要使用AOP來做: 1、事務處理 2、權限判斷 3、日誌 4、.... 2.5.9 AOP是什麼?你都拿它做什麼?\t3、 AOP:面向切面編程 核心原理:使用動態代理的設計模式在執行方法前後或出現異常做加入相關邏輯。 我們主要使用AOP來做: 1、事務處理 執行方法前,開啟事務、執行完成後關閉事務、出現異常後回滾事務 2、權限判斷 在執行方法前,判斷是否具有權限 3、日誌 在執行前進行日誌處理 4、....2.5.10講一下Spring的事務傳播特性多個事務存在是怎麼處理的策略1. PROPAGATION_REQUIRED: 如果存在一個事務,則支持當前事務。如果沒有事務則開啟2. PROPAGATION_SUPPORTS: 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行3. PROPAGATION_MANDATORY: 如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。4. PROPAGATION_REQUIRES_NEW: 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。5. PROPAGATION_NOT_SUPPORTED: 總是非事務地執行,並掛起任何存在的事務。6. PROPAGATION_NEVER: 總是非事務地執行,如果存在一個活動事務,則拋出異常7. PROPAGATION_NESTED:如果一個活動的事務存在,則運行在一個嵌套的事務中. 如果沒有活動事務, 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執行PropagationRequired 需要 如果存在一個事務,則支持當前事務。如果沒有事務則開啟Supports 支持 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行Mandatory 必要的 如果已經存在一個事務,支持當前事務。如果沒有一個活動的事務,則拋出異常。required_new 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。Not_support 總是非事務地執行,並掛起任何存在的事務。Never 絕不 總是非事務地執行,如果存在一個活動事務,則拋出異常Nested 嵌套的 如果有就嵌套、沒有就開啟事務2.5.11 Spring事務的隔離級別1. ISOLATION_DEFAULT: 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別.另外四個與JDBC的隔離級別相對應2. ISOLATION_READ_UNCOMMITTED: 這是事務最低的隔離級別,它充許令外一個事務可以看到這個事務未提交的數據。      這種隔離級別會產生髒讀,不可重複讀和幻像讀。3. ISOLATION_READ_COMMITTED: 保證一個事務修改的數據提交後才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的數據4. ISOLATION_REPEATABLE_READ: 這種事務隔離級別可以防止髒讀,不可重複讀。但是可能出現幻像讀。      它除了保證一個事務不能讀取另一個事務未提交的數據外,還保證了避免下面的情況產生(不可重複讀)。5. ISOLATION_SERIALIZABLE 這是花費最高代價但是最可靠的事務隔離級別。事務被處理為順序執行。除了防止髒讀,不可重複讀外,還避免了幻像讀。其中的一些概念的說明:  髒讀: 指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。因為這個數據是還沒有提交的數據, 那麼另外一 個事務讀到的這個數據是髒數據,依據髒數據所做的操作可能是不正確的。不可重複讀: 指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。 那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麼第一個事務兩次讀到的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重複讀。 幻覺讀: 指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及 到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。2.5.12 什麼是ORM? 對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向對象與關係數據庫存在的互不匹配的現象的技術。簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中。那麼,到底如何實現持久化呢?一種簡單的方案是採用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪問操作提供單獨的方法。這種方案存在以下不足: 1.持久化層缺乏彈性。一旦出現業務需求的變更,就必須修改持久化層的接口 2.持久化層同時與域模型與關係數據庫模型綁定,不管域模型還是關係數據庫模型發生變化,都要修改持久化曾的相關程序代碼,增加了軟件的維護難度。 ORM提供了實現持久化層的另一種模式,它採用映射元數據來描述對象關係的映射,使得ORM中間件能在任何一個應用的業務邏輯層和數據庫層之間充當橋樑。Java典型的ORM框架有:Hibernate,ibatis(mybatis),speedframework。 ORM的方法論基於三個核心原則:    簡單:以最基本的形式建模數據。    傳達性:數據庫結構被任何人都能理解的語言文檔化。    精確性:基於數據模型創建正確標準化了的結構。 對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向對象與關係數據庫存在的互不匹配的現象的技術。可以簡單的方案是採用硬編碼方式(jdbc操作sql方式),為每一種可能的數據庫訪問操作提供單獨的方法。這種方法存在很多缺陷,使用使用ORM框架(為了解決解決面向對象與關係數據庫存在的互不匹配的現象的框架)來解決. Hibernate,ibatis(mybatis),2.5.13 iBatis(mybatis)與Hibernate有什麼不同?相同點: 都是java中orm框架、屏蔽jdbc api的底層訪問細節,使用我們不用與jdbc api打交道,就可以完成對數據庫的持久化操作。jdbc api編程流程固定,還將sql語句與java代碼混雜在了一起,經常需要拼湊sql語句,細節很繁瑣。 ibatis的好處:屏蔽jdbc api的底層訪問細節;將sql語句與java代碼進行分離;提供了將結果集自動封裝稱為實體對象和對象的集合的功能.queryForList返回對象集合,用queryForObject返回單個對象;提供了自動將實體對象的屬性傳遞給sql語句的參數。 Hibername的好處:Hibernate是一個全自動的orm映射工具,它可以自動生成sql語句,並執行並返回java結果。不同點: 1、hibernate要比ibatis功能強大很多。因為hibernate自動生成sql語句。 2、ibatis需要我們自己在xml配置文件中寫sql語句,hibernate我們無法直接控制該語句,我們就無法去寫特定的高效率的sql。對於一些不太複雜的sql查詢,hibernate可以很好幫我們完成,但是,對於特別複雜的查詢,hibernate就很難適應了,這時候用ibatis就是不錯的選擇,因為ibatis還是由我們自己寫sql語句。 ibatis可以出來複雜語句,而hibernate不能。 3、ibatis要比hibernate簡單的多。ibatis是面向sql的,不同考慮對象間一些複雜的映射關係。2.5.14 Hibernate映射對象的狀態臨時狀態/瞬時狀態(transient):剛剛用new語句創建,沒有被持久化\t不處於session中(沒有使用session的方法去操作臨時對象)。該對象成為臨時對象持久化狀態/託管狀態(persistent):已經被持久化,加入到session的緩存中。session是沒有關閉該狀態的對象為持久化對象。遊離狀態/脫管狀態(detached):已經被持久化,但不處於session中。\t該狀態的對象為遊離對象。刪除狀態(removed):對象有關聯的ID,並且在Session管理下,但是已經被計劃(事務提交的時候,commit())刪除。如果沒有事務就不能刪除相互轉換2.5.15 介紹一下Hibernate的緩存?一、why(為什麼要用Hibernate緩存?)Hibernate是一個持久層框架,經常訪問物理數據庫。為了降低應用程序對物理數據源訪問的頻次,從而提高應用程序的運行性能。緩存內的數據是對物理數據源中的數據的複製,應用程序在運行時從緩存讀寫數據,在特定的時刻或事件會同步緩存和物理數據源的數據。為了提供訪問速度,把磁盤或數據庫訪問變成內存訪問。 二、what(Hibernate緩存原理是怎樣的?)Hibernate緩存包括兩大類:Hibernate一級緩存和Hibernate二級緩存。1.Hibernate一級緩存又稱為"Session的緩存"。Session緩存內置不能被卸載,Session的緩存是事務範圍的緩存(Session對象的生命週期通常對應一個數據庫事務或者一個應用事務)。一級緩存中,持久化類的每個實例都具有唯一的OID。2.Hibernate二級緩存又稱為"SessionFactory的緩存"。由於SessionFactory對象的生命週期和應用程序的整個過程對應,因此Hibernate二級緩存是進程範圍或者集群範圍的緩存,有可能出現併發問題,因此需要採用適當的併發訪問策略,該策略為被緩存的數據提供了事務隔離級別。第二級緩存是可選的,是一個可配置的插件,默認下SessionFactory不會啟用這個插件。Hibernate提供了org.hibernate.cache.CacheProvider接口,它充當緩存插件與Hibernate之間的適配器。面試: Hibernate中的緩存分一級緩存和二級緩存。 一級緩存就是Session級別的緩存,在事務範圍內有效是,內置的不能被卸載。二級緩存是SesionFactory級別的緩存,從應用啟動到應用結束有效。是可選的,默認沒有二級緩存,需要手動開啟。 保存數據庫後,在內存中保存一份,如果更新了數據庫就要同步更新。 什麼樣的數據適合存放到第二級緩存中?   1) 很少被修改的數據  帖子的最後回覆時間 2) 經常被查詢的數據 電商的地點2) 不是很重要的數據,允許出現偶爾併發的數據   3) 不會被併發訪問的數據   4) 常量數據 擴展:hibernate的二級緩存默認是不支持分佈式緩存的。使用memcahe,redis等中央緩存來代替二級緩存。    2.5.16 簡單講一下webservice使用的場景?webservice是一個SOA(面向服務的編程)的架構,它是不依賴於語言,不依賴於平臺,可以實現不同的語言間的相互調用,通過Internet進行基於Http協議的網絡應用間的交互。1、 異構系統(不同語言)的整合2、 不同客戶端的整合 瀏覽器、手機端(android,ios.塞班)、微信單、PC端等終端來訪問3、 實實在在的列子: 天氣預報:可以通過實現webservice客戶端調用遠程天氣服務實現的。 單點登錄:一個服務是所有系統的登錄2.5.17 簡單介紹一下activiti? Activiti是一個業務流程管理(BPM)和工作流系統,適用於開發人員和系統管理員。其核心是超快速,穩定的BPMN2流程引擎。它易於與 Spring集成使用。主要要在OA中,把線下流程放到線上。 把現實生活中一些流程固話定義到系統中,然後通過輸入表單數據完成業務。他可用在OA系統的流程管理中:請假流程 小於三天,一級主管審批,大於三天二級才能審批。報銷流程 1000 2000 3000>....如果你想找專門這方面的工作,要下去複習。2.6 高級部分2.6.1 有沒有用過linux?你都用它來做什麼?Linux是一個長時間運行比較穩定的操作系統,所有我們一般會拿它作為服務器(web,db,app等)。Linux本身具有C的編譯環境、我們的一些軟件是沒有軟件包(redis、nginx等)的,需要在Linux的C編譯環境編譯得到軟件包.2.6.2 說一下linux下面的一下常用命令?常用:Pwd 獲取當前路徑Cd 跳轉到目錄Su -u 切換到管理員Ls ls 列舉目錄文件操作命令:文件 tail 查看 rm -rf vi文件夾 mkdir rm -r2.6.3 你是使用什麼來連接遠程的Linux服務器的?需要依賴於Linux服務器安裝ssh服務端,一般這個ssh服務的端口22.需要依賴於Linux服務器安裝sftp服務端,一般這個sftp服務的端口25.使用ssh客戶端連接linux服務器,就有點兒像windows下面的遠程連接。但是linux通過ssh連接上以後是沒有圖形界面,全是命令行。PuttyXshell使用sftp客戶端來連接sftp服務端,來上傳和下載文件.(上傳安裝包,修改了配置文件上傳。)Winscpxftp企業中常用的兩種組合: putty+winscp Xshell+xftp=xmanager面試:使用xshell、putty等ssh客戶端來連接服務器,使用xftp、winscp等sftp客戶端來上傳和現在文件。連接和上傳、下載必須依賴於服務器的ssh、sftp服務,也就是linux服務器需要啟動這兩個服務。2.6.4 有沒有使用過雲主機?使用過,在原來的公司,我們沒有使用自己的服務器,而是租用阿里的雲主機。沒有使用過,但是有所瞭解。雲主機就是一些雲服務運營商(阿里、華為、西部數碼、新浪等),提供的遠程的服務器功能,我們開發者或者企業只需按需付費就可以租用對應的服務器。使用ssh和sftp來進行操作。2.6.5 有沒有做過數據庫優化方面的事情? 做過mysql數據庫的優化、其他數據庫類似定位:查找、定位慢查詢優化手段:a) 創建索引:創建合適的索引,我們就可以現在索引中查詢,查詢到以後直接找對應的記錄。b) 分表 :當一張表的數據比較多或者一張表的某些字段的值比較多並且很少使用時,採用水平分表和垂直分表來優化c) 讀寫分離:當一臺服務器不能滿足需求時,採用讀寫分離的方式進行集群。d) 緩存:使用redis來進行緩存e) 一些常用優化技巧 2.6.6 查找慢查詢並定位慢查詢? 在項目自驗項目轉測試之前,在啟動mysql數據庫時開啟慢查詢,並且把執行慢的語句寫到日誌中,在運行一定時間後。通過查看日誌找到慢查詢語句。要找出項目中的慢Sql時1、關閉數據庫服務器(關閉服務)2、把慢查詢記錄到日誌中3、 設置慢查詢時間4、找出日誌中的慢查詢SQL 使用explain 慢查詢語句,來詳細分析語句的問題.2.6.6 數據庫優化之遵循範式? 數據庫表設計時需要遵循方式 表的範式,是首先符合1NF, 才能滿足2NF , 進一步滿足3NF1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要數據庫是關係型數據庫(mysql/oracle/db2/sysbase/sql server),就自動的滿足1NF.關係型數據庫中是不允許分割列的。2NF:表中的記錄是唯一的.通常我們設計一個主鍵來實現3NF:即表中不要有冗餘數據, 就是說,表的信息,如果能夠被推導出來,就不應該單獨的設計一個字段來存放.(外鍵)反3NF :沒有冗餘的數據庫未必是最好的數據庫,有時為了提高運行效率,就必須降低範式標準,適當保留冗餘數據。具體做法是: 在概念數據模型設計時遵守第三範式,降低範式標準的工作放到物理數據模型設計時考慮。降低範式就是增加字段,允許冗餘。 訂單和訂單項、相冊瀏覽次數和照片的瀏覽次數2.6.7 選擇合適的存儲引擎在開發中,我們經常使用的存儲引擎 myisam / innodb/ memoryMyISAM存儲引擎如果表對事務要求不高,同時是以查詢和添加為主的,我們考慮使用myisam存儲引擎. 比如 bbs 中的 發帖表,回覆表.INNODB存儲引擎: 對事務要求高,保存的數據都是重要數據,我們建議使用INNODB,比如訂單表,賬號表.Memory 存儲\t我們數據變化頻繁,不需要入庫,同時又頻繁的查詢和修改,我們考慮使用memory, 速度極快.問 MyISAM 和 INNODB的區別(主要)1. 事務安全 myisam不支持事務而innodb支持2. 查詢和添加速度 myisam不用支持事務就不用考慮同步鎖,查找和添加和添加的速度快3. 支持全文索引 myisam支持innodb不支持4. 鎖機制 myisam支持表鎖而innodb支持行鎖(事務)5. 外鍵 MyISAM 不支持外鍵, INNODB支持外鍵. (通常不設置外鍵,通常是在程序中保證數據的一致)2.6.8 數據庫優化之創建合適的索引?索引(Index)是幫助DBMS高效獲取數據的數據結構。分類:普通索引/唯一索引/主鍵索引/全文索引普通索引:允許重複的值出現唯一索引:除了不能有重複的記錄外,其它和普通索引一樣(用戶名、用戶身份證、email,tel)主鍵索引:是隨著設定主鍵而創建的,也就是把某個列設為主鍵的時候,數據庫就會給改列創建索引。這就是主鍵索引.唯一且沒有null值全文索引:用來對錶中的文本域(char,varchar,text)進行索引, 全文索引針對MyIsamexplain select * from articles where match(title,body) against('database');【會使用全文索引】2.6.9 索引使用小技巧?*****索引弊端1.佔用磁盤空間。2.對dml(插入、修改、刪除)操作有影響,變慢。使用場景:a: 肯定在where條件經常使用,如果不做查詢就沒有意義b: 該字段的內容不是唯一的幾個值(sex) c: 字段內容不是頻繁變化.具體技巧:1. 對於創建的多列索引(複合索引),不是使用的第一部分就不會使用索引。alter table dept add index my_ind (dname,loc); // dname 左邊的列,loc就是右邊的列explain select * from dept where dname='aaa'\\G 會使用到索引explain select * from dept where loc='aaa'\\G 就不會使用到索引2. 對於使用like的查詢,查詢如果是'%aaa'不會使用到索引而'aaa%'會使用到索引。 explain select * from dept where dname like '%aaa'\\G不能使用索引 explain select * from dept where dname like 'aaa%'\\G使用索引.所以在like查詢時,'關鍵字'的最前面不能使用 % 或者 _這樣的字符.,如果一定要前面有變化的值,則考慮使用 全文索引->sphinx.3. 如果條件中有or,有條件沒有使用索引,即使其中有條件帶索引也不會使用。換言之,就是要求使用的所有字段,都必須單獨使用時能使用索引. 4. 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來。否則不使用索引。expain select * from dept where dname='111';expain select * from dept where dname=111;(數值自動轉字符串)expain select * from dept where dname=qqq;報錯也就是,如果列是字符串類型,無論是不是字符串數字就一定要用 '' 把它包括起來.5. 如果mysql估計使用全表掃描要比使用索引快,則不使用索引。 表裡面只有一條記錄2.6.10 數據庫優化之分表?分表分為水平(按行)分表和垂直(按列)分表根據經驗,Mysql表數據一般達到百萬級別,查詢效率會很低,容易造成表鎖,甚至堆積很多連接,直接掛掉;水平分表能夠很大程度較少這些壓力。按行數據進行分表。如果一張表中某個字段值非常多(長文本、二進制等),而且只有在很少的情況下會查詢。這時候就可以把字段多個單獨放到一個表,通過外鍵關聯起來。 考試詳情,一般我們只關注分數,不關注詳情。水平分表策略:1.按時間分表這種分表方式有一定的侷限性,當數據有較強的實效性,如微博發送記錄、微信消息記錄等,這種數據很少有用戶會查詢幾個月前的數據,如就可以按月分表。2.按區間範圍分表一般在有嚴格的自增id需求上,如按照user_id水平分表:table_1 user_id從1~100w table_2 user_id從101~200w table_3 user_id從201~300w 3.hash分表*****通過一個原始目標的ID或者名稱通過一定的hash算法計算出數據存儲表的表名,然後訪問相應的表。2.6.11 數據庫優化之讀寫分離一臺數據庫支持的最大併發連接數是有限的,如果用戶併發訪問太多。一臺服務器滿足不要要求是就可以集群處理。Mysql的集群處理技術最常用的就是讀寫分離。\t主從同步數據庫最終會把數據持久化到磁盤,如果集群必須確保每個數據庫服務器的數據是一直的。能改變數據庫數據的操作都往主數據庫去寫,而其他的數據庫從主數據庫上同步數據。讀寫分離 使用負載均衡來實現寫的操作都往主數據去,而讀的操作往從服務器去。2.6.12 數據庫優化之緩存 \t在持久層(dao)和數據庫(db)之間添加一個緩存層,如果用戶訪問的數據已經緩存起來時,在用戶訪問時直接從緩存中獲取,不用訪問數據庫。而緩存是在操作內存級,訪問速度快。作用:減少數據庫服務器壓力,減少訪問時間。Java中常用的緩存有, 1、hibernate的二級緩存。該緩存不能完成分佈式緩存。2、 可以使用redis(memcahe等)來作為中央緩存。 對緩存的數據進行集中處理2.6.13 語句優化小技巧DDL優化:1 、通過禁用索引來提供導入數據性能 。 這個操作主要針對有數據庫的表,追加數據//去除鍵alter table test3 DISABLE keys;//批量插入數據insert into test3 select * from test;//恢復鍵alter table test3 ENABLE keys;2、 關閉唯一校驗set unique_checks=0 關閉set unique_checks=1 開啟3、修改事務提交方式(導入)(變多次提交為一次)set autocommit=0 關閉//批量插入set autocommit=1 開啟DML優化(變多次提交為一次)\tinsert into test values(1,2);insert into test values(1,3);insert into test values(1,4);//合併多條為一條insert into test values(1,2),(1,3),(1,4)DQL優化Order by優化 \t\t1、多用索引排序2、 普通結果排序(非索引排序)Filesort group by優化 是使用order by null,取消默認排序 子查詢優化在客戶列表找到不在支付列表的客戶#在客戶列表找到不在"支付列表"的客戶 , 查詢沒買過東西的客戶explainselect * from customer where customer_id not in (select DISTINCT customer_id from payment); #子查詢 -- 這種是基於func外鏈explain select * from customer c left join payment p on(c.customer_id=p.customer_id) where p.customer_id is null -- 這種是基於"索引"外鏈 Or優化在兩個獨立索引上使用or的性能優於 1、 or兩邊都是用索引字段做判斷,性能好!!2、 or兩邊,有一邊不用,性能差3、 如果employee表的name和email這兩列是一個複合索引,但是如果是 :name='A' OR email='B' 這種方式,不會用到索引! limit優化select film_id,description from film order by title limit 50,5;select a.film_id,a.description from film a inner join (select film_id from film order by title limit 50,5)b on a.film_id=b.film_id2.6.14 jdbc批量插入幾百萬數據怎麼實現?*****1、變多次提交為一次3、使用批量操作省出的時間可觀。像這樣的批量插入操作能不使用代碼操作就不使用,可以使用存儲過程來實現。2.6.15 有沒有使用過redis? Redis是什麼 Redis是一個key-value的nosql數據庫.先存到內存中,會根據一定的策略持久化到磁盤,即使斷電也不會丟失數據。支持的數據類型比較多。主要用來做緩存數據庫的數據和web集群時當做中央緩存存放seesion2.4.15 Redis和memche的比較? 1、 Redis和Memcache都是將數據存放在內存中,都是內存數據庫。不過memcache還可用於緩存其他東西,例如圖片、視頻等等。2、Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,hash等數據結構的存儲。3、虛擬內存--Redis當物理內存用完時,可以將一些很久沒用到的value 交換到磁盤 2.6.16 簡單說一下redis的使用場景?\t緩存:把經常需要查詢的、很少修改數據,放到讀速度很快的空間(內存),以便下次訪問減少時間。減輕壓力,減少訪問時間.計數器: redis中的計數器是原子性的內存操作。\t 可以解決庫存溢出問題.進銷存系統庫存溢出。\t\tsession緩存服務器:web集群時作為session緩存服務器緩存隊列等2.6.17 redis對象保存方式?Json字符串:需要把對象轉換為json字符串,當做字符串處理。直接使用set get來設置或者或。優點:設置和獲取比較簡單缺點:沒有提供專門的方法,需要把把對象轉換為json。(jsonlib)字節: 需要做序列號,就是把對象序列化為字節保存。如果是擔心JSON轉對象會消耗資源的情況,這個問題需要考量幾個地方,第一點:就是使用的JSON轉換lib是否就會存在性能問題。第二點:就是數據的數據量級別,如果是存儲百萬級的大數據對象,建議採用存儲序列化對象方式。如果是少量的數據級對象,或者是數據對象字段不多,還是建議採用JSON轉換成String方式。畢竟redis對存儲字符類型這部分優化的非常好。具體採用的方式與方法,還要看你所使用的場景。2.6.18 Redis數據淘汰機制在 redis 中,允許用戶設置最大使用內存大小 server.maxmemory,在內存限定的情況下是很有用的。譬如,在一臺 8G 機子上部署了 4 個 redis 服務點,每一個服務點分配 1.5G 的內存大小,減少內存緊張的情況,由此獲取更為穩健的服務。內存大小有限,需要保存有效的數據?redis 內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。redis 提供 6種數據淘汰策略:volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰no-enviction(驅逐):禁止驅逐數據2.6.19 Java訪問Redis1、使用jedis java客戶端來訪問redis服務器,有點類似通過jdbc訪問mysql一樣。2、當然如果是spring進行集成時,可以使用spring data來訪問redis,spring data只是對jedis的二次封裝。jdbcTemplate jdbc關係一樣2.6.20 Redis集群當一臺數據無法滿足要求,可以使用reids集群來處理,類似於mysql的讀寫分離。2.6.21簡單介紹一下微信公共號的分類? 公眾號:個人和企業都能申請 服務號:企業才能申請 企業號:企業才能申請2.6.22 微信開發原理微信公眾平臺開發者,通過接入認證的方式,讓我們的服務器能處理來自微信服務器轉發的微信用戶的請求,處理完成後返回給微信服務器,有微信服務器對用戶響應。2.6.23怎麼把微信和業務平臺綁定?微信用戶和註冊用戶綁定?讓微信用戶也能完成註冊用戶的功能。用戶註冊實體中包含一個微信號的字段,當我進行綁定時就是修改用戶的微信號字段。當然我們在進行菜單跳轉到頁面後,我們是無法直接獲取微信號的。要通過微信網頁授權來獲取微信號。第一步:用戶同意授權,獲取codehttps://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示"該鏈接無法訪問",請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域權限。 第二步:通過code換取網頁授權openId也就是我們微信號獲取code後,請求以下鏈接獲取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } 2.7 項目和業務部分 2.7.1項目分類在公司中做的項目可以分為兩種產品、項目.項目:就是給一些公司接的項目,項目開發完成後。就交互,後面這個項目代碼就不在維護了產品:充分考慮擴展性和基本業務,來做一個產品。在這個產品上可以進行定製開發。\t2.7.2 項目參與者 產品經理?PM?架構師(SE)?(開發PL? MDE?可能會有多個) (測試PL ? TSE可能會有多個) UI 資料開發團隊:開始代碼能完成需求測試團隊:測試功能UI:負責界面設計、靜態代碼的編寫資料:負責界面的文字描述。QA\t:通過項目質量監控,和PM,SE同級開發和UI和資料,協同設計和開發,開發完成後轉測試(測試策略)交給測試團隊進行測試,測試完成後會出一個測試報告。2.7.3 項目流程 可行性分析和立項和開工會 需求分析 需求設計 項目開發(多個迭代) 迭代開工會 迭代設計 \t\t迭代開發 \t\t迭代測試 \t\t集成測試 \t\t迭代發佈 迭代總結 ....不斷迭代 項目驗收 項目總結 2.7.4 業務注意事項1、 不要多個項目都說你同一個模塊。如果要說,就說後面是進行改進。 在pss,crm,shopping都寫權限模塊2、多寫點業務 /<code>


分享到:


相關文章: