一, 選擇題
-
下列關於棧的描述錯誤的是(B)
A. 棧是先進後出的線性表
B. 棧只能順序存儲
C. 棧具有記憶功能
D. 對棧的插入和刪除操作中,不需要改變棧底指針
首先, 棧是允許在同一端進行插入和刪除操作的特殊的線性表, 是一種數據結構的稱呼
線性結構有兩種不同的存儲結構, 順序存儲結構和鏈式存儲結構
所以, 只要符合在同一端進行插入和刪除操作的特殊的線性表, 我們統稱爲棧
-
對於長度爲 n 的線性表,在最壞的情況下,下列個排序法所對應的比較次數中正確的是(D)
A. 冒泡排序爲n/2
B. 冒泡排序爲n
C. 快速排序爲n
D. 快速排序爲n(n-1)/2
本題主要考查對排序算法的理解。冒泡排序法首先將第一個記錄的關鍵字與第二個記錄的關鍵字進行比較,若逆序則交換,然後比較第二個與第三個,以此類推,直至第n-1個與第n個記錄的關鍵字進行比較。第一趟冒泡排序使最大的關鍵字元素放到最後。以此類推,進行第2~n次冒泡排序。如果在排序過程中不存在逆序,則排序結束。在最壞情況下,冒泡排序中,若初始序列爲“逆序”序列,需要比較n(n-1)/2次。快速排序是對冒泡排序的一種改進。它的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字比另一部分記錄的關鍵字小,然後分別對這兩部分記錄繼續進行排序,最終達到整個記錄有序。對於快速排序,若初始記錄序列按關鍵字有序或基本有序時,快速排序退化冒泡排序,最壞情況下比較次數爲n(n-1)/2。
-
閱讀下列代碼後, 下列正確的說法是(A)
public class Person{ int arr[] = new int[10]; public static void main(String args[ ]){ System.out.println(arr[1]); } }
A 編譯時將產生錯誤
B 編譯時正確,運行時將產生錯誤
C 輸出空
D 輸出0
arr沒有被static修飾, 所以說main方法無法訪問到
-
執行以下程序後輸出的結果是(D)
public class Test { public static void main(String[] args) { StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); operator(a,b); System.out.println(a+","+b); } public static void operator(StringBuffer x,StringBuffer y){ x.append(y); y=x; } }
A. A,A
B. A,B
C. B,B
D. AB,B
public class Test {
public static void main(String args[]) {
//a和b都是引用,分別引用了new在堆中的兩個StringBuffer對象。
StringBuffer a = new StringBuffer(“A”);
StringBuffer b = new StringBuffer(“B”);
Operator(a, b);
System.out.println(a + " " + b);
}public static void Operator(StringBuffer x, StringBuffer y) {
//由於main中調用Operator傳入
//x和main中a引用了同一個在堆中的StringBuffer對象
//y和main中b引用了同一個在堆中的StringBuffer對象
x.append(y);//由於調用了append的作用,堆中的對象被改變。由"A",變"AB"
y = x;//由於=只是讓y引用x引用的對象,此時x,y,a引用同一個"AB",b引用另一個"A"
} -
下列不屬於持久化的是(A)
A. 把對象轉換成爲字符串的形式通過網絡傳輸,在另一端接收到字符串把對象還原出來
B. 把程序數據從數據庫中讀出來
C. 從XML配置文件中讀取程序的配置信息
D. 把程序數據保存爲文件
百度百科:
什麼是持久化: 持久化是將程序數據在持久狀態和瞬時狀態間轉換的機制. 通俗的講, 就是順勢數據(比如內存中的數據, 是不能永久保存的) 持久化爲持久數據(比如持久化之數據庫中, 能夠長久保存)
數據持久化:
數據持久化就是將內存中的數據模型轉換爲存儲模型, 以及將存儲模型轉換成爲內存中的數據模型的統稱. 數據模型可以是任何數據結構或對象模型, 存儲模型可以是關係模型, xml, 二進制流等.
-
下列代碼輸出的結果是(B)
int x= 0; int y=10; do{ y--; ++x; }while(x<5); System.out.println(x+","+y);
A. 5,6
B. 5,5
C. 6,5
D. 6,6
-
下列程序段的輸出結果是:( B )
void complicatedexpression_r(){ int x = 20,y=30; boolean j; j=x>50&&y>60||x>50&&y<-60||x<-50&&y>60||x<-50&&y<-60; System.out.println(j); }
A. true
B. false
C. 1
D. 011
此題考查運算符優先級。
題中符號的優先級排序是:’>’,’<’,’&&’,’||’。
即 b=(x>50&&y>60)||(x>50&&y<-60)||(x<-50&&y>60)||(x<-50&&y<-60);
x>50結果爲false,x<-50結果爲false,所以括號中的表達式結果都爲false,四個false或的結果爲false。
b爲boolean類型,所以輸出爲false。 -
一個棧的輸入序列爲 123,則下列序列中不可能是棧輸出的序列的是(C)
A. 2 3 1
B. 3 2 1
C. 3 1 2
D. 1 2 3
1進棧,1出棧,2進棧,2出棧,3進棧,3出棧,所以是123
1進棧,2進棧,2出棧,1出棧,3進棧,3出棧,所以是213
1進棧,2進棧,2出棧,3進棧,3出棧,1出棧,所以是231
1進棧,2進棧,3進棧,3出棧,2出棧,1出棧,所以是321
輸入序列是123的輸出序列就這4中情況;所以是C! -
當n = 5時, 下列函數的返回值是(D)
int foo(int n){ if(n<2) return n; return foo(n-1)+foo(n-2); }
A. 1
B. 8
C. 7
D. 5
解題思路如下:
當n=0時 f(0)=0
當n=1時 f(1)=1
當n=2時 f(2)=f(1)+f(0)=0+1=1
當n=3時 f(3)=f(2)+f(1)=0+1=2
當n=4時 f(4)=f(3)+f(2)=1+2=3
當n=5時 f(5)=f(4)+f(3)=3+2=5 -
設一個二維數組A[m][n], 假設A[0][0]存放位置在644(10). A[2][2]存放的位置在676(10), 每個元素佔一個空間, 問A[3][3](10)存放在什麼位置?腳註(10)表示用10進製表示( C )
A. 688
B. 678
C. 692
D. 699
解法一: 只看對角線元素 ,A[0][0]和a[1][1]間隔距離設爲x, 那麼A[0][0]和A[2][2] 間隔就爲2x, 按照比例計算x爲(676-644)/2=16, 所以說A[3][3] 的位置爲644+16*3=692
解法二: 對於arr[m][n]而言:
arr[i][j]的地址爲:arr + i*n + j
arr[0][0]的地址爲644
所以,由A[2][2]可得:644 + n*2 + 2 = 676,得n=15 (每行15個元素)
所以A[3][3]的地址爲:644+15*3 + 3 = 692
二, 簡答題
-
解釋以下什麼是Servlet; 說一說Servlet的生命週期
Servlet是一種服務器端的Java應用程序,具有獨立於平臺和協議的特性,可以生成動態的Web頁面。 它擔當客戶請求(Web瀏覽器或其他HTTP客戶程序)與服務器響應(HTTP服務器上的數據庫或應用程序)的中間層。
Servlet是位於Web 服務器內部的服務器端的Java應用程序,與傳統的從命令行啓動的Java應用程序不同,Servlet由Web服務器進行加載,該Web服務器必須包含支持Servlet的Java虛擬機Servlet生命週期可以分成四個階段:加載和實例化、初始化、服務、銷燬。
當客戶第一次請求時,首先判斷是否存在 Servlet 對象,若不存在,則由 Web 容器創建對象,而後調用 init()方法對其初始化,此初始化方法在整個Servlet生命週期中只調用一次。
完成Servlet對象的創建和實例化之後,Web容器會調用Servlet對象的service()方法來處理請求。
當Web容器關閉或者Servlet對象要從容器中被刪除時,會自動調用destory()方法。
-
過濾器有哪些作用和用法?
對於一個 web 應用程序來說,過濾器是處於 web 容器內的一個組件,它會過濾特定請求資源請求信息和響應信息。一個請求來到時,web 容器會判斷是否有過濾器與該信息資源相關聯,如果有則交給過濾器處理,然後再交給目標資源,響應的時候則以相反的順序交給過濾器處理,最後再返回給用戶瀏覽器。
常見的過濾器用途主要包括:對用戶請求進行統一認證、對用戶的訪問請求進行記錄和審覈、對用戶發送的數據進行過濾或替換、轉換圖象格式、對響應內容進行壓縮以減少傳輸量、對請求或響應進行加解密處理、觸發資源訪問事件等。
-
寫出冒泡排序的實現
import java.util.Arrays; public class Test { public static void main(String[] args) { int[] randomArray = getRandomArray(10); System.out.println(Arrays.toString(randomArray)); quickSort(randomArray, 0, randomArray.length - 1); System.out.println(Arrays.toString(randomArray)); } /** * 快速排序 * * @param arr 需要排序的數組 * @param leftBound 左邊界 左邊第一個元素的索引 * @param rightBound 右邊界 右邊第一個元素的索引 */ public static void quickSort(int[] arr, int leftBound, int rightBound) { //避免左右邊界相交越界,定義遞歸算法的遞歸尾 if (leftBound > rightBound) { return; } //左浮標,定義數組做左側的元素索引 int lDrogue = leftBound; //右浮標,定義數組最右側的元素索引 int rDrogue = rightBound; //將數組最左側的原則作爲基準數 int pivot = arr[lDrogue]; //當兩個浮標索引不相等的情況下,持續移動 while (lDrogue != rDrogue) { //右漂浮左移 while (lDrogue < rDrogue && arr[rDrogue] >= pivot) { rDrogue--; } //左浮標右移 while (lDrogue < rDrogue && arr[lDrogue] <= pivot) { lDrogue++; } //當做到這裏的時候說明,左漂浮和右漂浮上的數據已經不滿足條件 //這裏的條件就是左漂浮對應的值大於基準值, 右漂浮對應的值小於基準值 //開始將不符合條件的元素進行交換 swap(arr, lDrogue, rDrogue); } //走到這裏說明兩個漂浮發生了重合,漂浮所在的位置也就是基準值應該放的位置 swap(arr, leftBound, lDrogue); quickSort(arr, leftBound, lDrogue - 1); quickSort(arr, lDrogue + 1, rightBound); } /** * 定義方法用於交換數組中的兩個元素 * * @param arr 數組 * @param a 元素索引 * @param b 元素索引 */ public static void swap(int arr[], int a, int b) { int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } /** * 獲得隨機的數組 * * @param length 生成隨機數組的長度 * @return */ public static int[] getRandomArray(int length) { int[] arr = new int[length]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) (Math.random() * 10000 + 1); } return arr; } }
-
寫出一個單例的實現 ( 懶加載方式)
public class SingletonDemo { //私有化屬性,持有自己的屬性,static修飾,便於對外提供的方法執行創建對象的操作 private static SingletonDemo singletonDemo; //私有化構造器 private SingletonDemo() { } //對外提供方法獲取對象,線程安全 public static synchronized SingletonDemo getInstance() { if (singletonDemo == null) { singletonDemo = new SingletonDemo(); return singletonDemo; } return singletonDemo; } }
三, SQL
Students學生表
sid | number | 學號 |
---|---|---|
sname | varchar2 (50) | 學生姓名 |
sage | number | 年齡 |
ssex | varchar2 (2) | 性別 |
Course課程表
cid | number | 課程編號 |
---|---|---|
cname | varchar2 (50) | 課程名稱 |
tid | number | 教師編號 |
SC成績表
sid | number | 學號 |
---|---|---|
cid | number | 課程編號 |
score | number | 成績 |
-
查詢姓 “張” 的學生名單 (至少兩種方法以上)
select sname from student where sname like '張%'; SELECT * from people where name like '張__' or name like '張_';
-
查詢男生, 女生人數各多少, 且男生年齡大於19歲, 女生年齡小於20歲
select * from (select count(1) as man from student where gender='男' and sage>19) as A , (select count(1) as feman from student where gender='女' and sage<20) as B
-
檢索 “004” 課程分數小於60, 按照分數降序排列的同學學號
select sid from sc where score< 60 and cid = 4 order by score desc;
-
檢索至少選修兩門課程的學生學號 (至少兩種方法以上)
select sid from sc group by sid having count(sid) > 1; select sid from sc group by sid where count(sid) > 1;
-
查詢所選課程的成績 (學生可能選擇 1 門或多門課程) 都在70分以上的學生姓名, 課程名稱和分數
SELECT student.sname,course.cname, sc.score FROM sc, course, student WHERE sc.score >70 AND sc.sid = student.sid AND sc.cid = sc.cid
-
刪除 “002” 同學的 "001"課程的成績
delete from sc where cid = 1 and sid = 2
-
當成績表的數據量達到千萬級別後, 請列舉多種數據優化方式或者思路 (附加題)
附加題參考鏈接: https://mp.weixin.qq.com/s/OZkdf6Wk5W3HNzzH0qMDlA
四, 概念題
-
dubbo事務是如何處理的?🎈
分佈式事務(事務補償機制)
事務補償即在事務鏈中的任何一個正向事物的操作,都必須存在一個完全符合回滾規則的可逆事務.
如果是一個完整的事務鏈, 則必須事物鏈中的每一個業務服務或操作都有對應的可逆服務. 如果按照上面的方式我們需要編寫大量的代碼來處理以保證事務的完整性, 我們可以考慮實現一個通用的事務管理器, 實現事務鏈和事務上下文的管理. 對於事務鏈上的任何一個服務正向和逆向操作均在事務管理和協同器(zookeeper)上註冊
-
solr的增量是如何做到的🎉
solr有全量導入數據和增量導入數據兩種方式, 在數據量較大的時候, 頻繁的更新索引會消耗系統的性能, 但是如果更新效率較低, 則會影響數據的準確性, 在這種情況下, 更新時間的間隔是個很難界定的問題.
增量索引解決了這個問題, 我們可以在較短的時間內只更新那些變化的數據, 這樣就避免了大批量的數據更新, 因爲數據量的小, 因此我們可以設置較短的時間間隔, 以此來提升用戶的體驗度.
1️⃣ 配置數據源
增量索引的關鍵是找到那些修改的數據. 所以我們要在數據庫表上添加一個標識符 (比如updateTime), 數據類型是時間戳(timestamp)
solr本身提供了一個last_index_time, 這個字段記錄每條記錄的導入時間(包括增量導入和全量導入) ,我們只需要將updateTime和last_index_time比較即可得到上一次索引更新以後的變化記錄
2️⃣ 配置data-config.xml文件
全量索引繼續保留, 所以原來的配置不需要更改, 我們只需要添加增量索引的配置. 首先, 我們在索引中用到了updateTime字段, 所以需要添加updateTime; 其次增量索引的關鍵就是找到更新的那些數據, 我們要使用last_index_time字段更新代碼如下
deltaQuery="select id from product where updateTime > '${dataimporter.last_index_time}'"
我們根據上述獲得的id更新索引
deltaImportQuery="select * from product where id='${dih.delta.id}'"
最終配置:
<dataConfig> <dataSource name="jfinal_demo" type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.51.71:3306/demo" user="root" password="123456" batchSize="-1" /> <document name="testDoc"> <entity name="blog" dataSource="jfinal_demo" pk="id" query="select * from product" deltaImportQuery="select * from product where id='${dih.delta.id}'" deltaQuery="select id from product where updateTime > '${dataimporter.last_index_time}'"> <field column="id" name="id"/> <field column="name" name="name"/> <field column="price" name="price"/> <field column="updateTime" name="updateTime"/> </entity> </document> </dataConfig>
3️⃣ 配置schema.xml
<field name="id" type="text_ik" indexed="true" stored="true" /> <field name="name" type="text_ik" indexed="true" stored="true" /> <field name="price" type="text_ik" indexed="true" stored="true" /> <field name="updateTime" type="text_ik" indexed="true" stored="true" />
參考鏈接 :https://blog.csdn.net/u010942465/article/details/51347923
-
如果solr中導入了錯誤的值或者空值, 我們如何獲取這些錯誤條件的搜索結果?✨
正常情況下我們都是按有值的方式去搜索,但是有時候有一些字段爲null,solr中就沒有存儲進去,我們怎麼獲取這個字段不存在爲條件的搜索結果了,我們只需要在搜索字段前加上負號
參考鏈接:
- https://blog.csdn.net/weixin_34195364/article/details/86008270
- https://blog.csdn.net/jiangchao858/article/details/76407937
-
sql索引的優缺點🍔
優點:
大大提高系統的性能
-
通過創建唯一性索引, 可以保證數據庫表中每一行數據的唯一性
-
可以大大加快數據的檢索速度, 這也是創建索引的最主要的原因
-
可以加速表與表之間的聯繫, 特別是在實現數據庫的參考完整性方面特別有意義
參考完整性要求關係中不允許引用不存在的實體. 與實體完整性是關係模型必須滿足的完整性約束條件, 目的是保證數據的一致性. 參照完整性又稱爲引用完整性
-
在使用分組和排序子句進行數據檢索時, 同樣可以顯著減少查詢中排序的時間
-
通過使用索引, 可以在查詢過程中, 使用優化隱藏器, 提高系統的性能
sql的優化隱藏器: https://zhidao.baidu.com/question/39271452.html
缺點:
- 創建索引和維護索引要耗費時間, 這種時間的耗費隨着時間的增加而增加
- 索引需要佔用物理空間, 除了數據庫表佔數據空間之外, 每一個所索引還要佔用一定的物理空間
- 當對錶中的數據進行增加, 刪除和修改的時候, 索引也要動態的維護, 這樣就降低了數據的維護速度
參考鏈接: https://blog.csdn.net/az03100110/article/details/78788980
-
-
事務傳播的特性, 如果a() 調用了b()方法b()拋異常了, 如何確保a()不回滾😡
這裏主要考察的是事務的7種傳播特性
@Transactional(propagation=Propagation.REQUIRED)
序號 傳播行爲 含義 1 REQUIRED 如果存在一個事務,則支持當前事務。如果沒有事務則開啓一個新的事務。 2 SUPPORTS 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行 3 MANDATORY 如果存在一個事務,支持當前事務。如果沒有事務,則非事務的執行 4 NESTED 如果一個活動的事務存在,則運行在一個嵌套的事務中。如果沒有活動事務,則按REQUIRED屬性執行 5 NEVER 總是非事務地執行,如果存在一個活動事務,則拋出異常 6 REQUIRES_NEW 總是開啓一個新的事務。如果一個事務已經存在,則將這個已經存在的事務掛起 7 NOT_SUPPORTED 總是非事務地執行,並掛起任何存在的事務 事務在a()種調用了b()方法的傳播案例
b()的事務配置 a()沒有事務的結果 a()有事務的結果 REQUIRED b()創建自己的事務 b()接受a()的事務 SUPPORTS b()不創建自己的事務 b()接受a()的事務 MANDATORY b()報異常 b()接受a()的事務 NESTED b()創建自己的事務 b()接受a()的事務,成爲a()嵌套的子事務 NEVER b()不創建自己的事務 b()報異常 REQUIRES_NEW b()創建自己的事務 b()不接受a()的事務,b()先執行,內層事務失敗不會影響外層事務 NOT_SUPPORTED b()不創建自己的事務 b()不接受a()的事務,b()先執行 聲明式事務是基於Spring AOP實現的, 將具體的業務邏輯和事務處理解耦, 在SpringAOP的代理下, 只有目標方法由外部調用, 目標方法才由Spring生成的代理對象來管理, 否則會造成子調用的問題.
注意: 同一個類中a()方法沒有@Transactional註解, 在其內部調用@Transactional 註解的方法,有@Transactional 註解的方法b()的事務被忽略,不會發生回滾。
參考鏈接:
- https://blog.csdn.net/u010235716/article/details/90171802
- https://blog.csdn.net/qq_37221991/article/details/90409001
- https://blog.csdn.net/qq_30336433/article/details/83338835
-
manven的jar包衝突如何解決😑
參考右邊的 Maven Projects,找到 Dependencies 選項展開後即可查看項目的依賴樹。進行分析
參考鏈接:
- https://blog.csdn.net/qq_33349750/article/details/75452706
- https://blog.csdn.net/noaman_wgs/article/details/81137893
- https://blog.csdn.net/SmileorSilence/article/details/79065284
-
dubbo都有哪些協議, 講一下zookeeper😂
dubbo有九種協議,但是Dubbo官網是推薦我們使用Dubbo協議的
1️⃣dubbo 協議(默認)
連接個數:單連接 連接方式:長連接 傳輸協議:TCP 傳輸方式:NIO異步傳輸 序列化:Hessian 二進制序列化 適用範圍:傳入傳出參數數據包較小(建議小於100K),消費者比提供者個數多,單一消費者無法壓 滿提供者,儘量不要用dubbo協議傳輸大文件或超大字符串。 適用場景:常規遠程服務方法調用
2️⃣rmi 協議
連接個數:多連接 連接方式:短連接 傳輸協議:TCP 傳輸方式:同步傳輸 序列化:Java標準二進制序列化 適用範圍:傳入傳出參數數據包大小混合,消費者與提供者個數差不多,可傳文件。 適用場景:常規遠程服務方法調用,與原生RMI服務互操作
3️⃣hessian 協議
連接個數:多連接 連接方式:短連接 傳輸協議:HTTP 傳輸方式:同步傳輸 序列化:Hessian二進制序列化 適用範圍:傳入傳出參數數據包較大,提供者比消費者個數多,提供者壓力較大,可傳文件。 適用場景:頁面傳輸,文件傳輸,或與原生hessian服務互操作
4️⃣http 協議
連接個數:多連接 連接方式:短連接 傳輸協議:HTTP 傳輸方式:同步傳輸 序列化:表單序列化 ,即 json 適用範圍:傳入傳出參數數據包大小混合,提供者比消費者個數多,可用瀏覽器查看,可用表單或URL傳入參數,暫不支持傳文件。 適用場景:需同時給應用程序和瀏覽器JS使用的服務。
5️⃣webservice 協議
連接個數:多連接 連接方式:短連接 傳輸協議:HTTP 傳輸方式:同步傳輸 序列化:SOAP文本序列化 適用場景:系統集成,跨語言調用
6️⃣thrift 協議
當前 dubbo 支持的 thrift 協議是對 thrift 原生協議的擴展,在原生協議的基礎上添加了一些額外的頭信息,比如 service name,magic number 等。 使用 dubbo thrift 協議同樣需要使用 thrift 的 idl compiler 編譯生成相應的 java 代碼,後續版本中會在這方面做一些增強。
7️⃣memcached 協議
基於 memcached實現的 RPC 協議。
8️⃣redis 協議
基於 Redis實現的 RPC 協議。
9️⃣rest (RestFull協議)
基於標準的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的簡寫)實現的REST調用支持
參考鏈接:
- https://blog.csdn.net/xiaojin21cen/article/details/79834222
- http://dubbo.apache.org/zh-cn/docs/user/references/protocol/rest.html
zookeeper: 是一款分佈式管理軟件,常常用它作爲註冊中心, (依賴zookeeper的發佈訂閱功能) , 配置文件中心, 分佈式鎖, 集羣管理等.
-
webservice技術🔔
Web Service技術, 能使得運行在不同機器上的不同應用無須藉助附加的、專門的第三方軟件或硬件, 就可相互交換數據或集成。依據Web Service規範實施的應用之間, 無論它們所使用的語言、 平臺或內部協議是什麼, 都可以相互交換數據。
簡單的說,WebService就是一種跨編程語言和跨操作系統平臺的遠程調用技術。所謂跨編程語言和跨操作平臺,就是說服務端程序採用java編寫,客戶端程序則可以採用其他編程語言編寫,反之亦然。跨操作系統平臺則是指服務端程序和客戶端程序可以在不同的操作系統上運行。 遠程調用,就是一臺計算機的應用可以調用其他計算機上的應用。例如:支付寶,支付寶並沒有銀行卡等數據,它只是去調用銀行提供的接口來獲得數據。還有天氣預報等,也是氣象局把自己的系統服務以webservice服務的形式暴露出來,讓第三方網站和程序可以調用這些服務功能。
參考鏈接:
- https://blog.csdn.net/c99463904/article/details/76018436
- https://blog.csdn.net/xiaojin21cen/article/details/79834222
-
mysql的優化代碼級別, 還有分庫和分表如何分💎
參考文獻:
- https://www.cnblogs.com/lonnie/p/10681512.html
- https://blog.csdn.net/qq_33936481/article/details/73691331
-
hibernate 以及mybatis(更加靈活)的異同, 以及應用場景😱
🔵Mybatis的技術特點:
- 通過直接編寫SQL語句,可以直接對SQL進行性能的優化;
- 學習門檻低,學習成本低。只要有SQL基礎,就可以學習mybatis,而且很容易上手;
- 由於直接編寫SQL語句,所以靈活多變,代碼維護性更好。
- 不能支持數據庫無關性,即數據庫發生變更,要寫多套代碼進行支持,移植性不好。
- 需要編寫結果映射。
🔷 Mybatis應用場景:
需求多變的互聯網項目,例如電商項目。
🔴Hibernate技術特點:
- 標準的orm框架,程序員不需要編寫SQL語句。
- 具有良好的數據庫無關性,即數據庫發生變化的話,代碼無需再次編寫。
- 學習門檻高,需要對數據關係模型有良好的基礎,而且在設置OR映射的時候,需要考慮好性能和對象模型的權衡。
- 程序員不能自主的去進行SQL性能優化。
🔺Hibernate應用場景:
需求明確、業務固定的項目,例如OA項目、ERP項目等。