面試問題1.0

SpringMVC的執行過程

1、 用戶發送請求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到請求調用HandlerMapping處理器映射器。
3、 處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截
器(如果有則生成)一併返回給DispatcherServlet。
4、 DispatcherServlet調用HandlerAdapter處理器適配器。
5、 HandlerAdapter經過適配調用具體的處理器(Controller,也叫後端控制器)。6、 Controller執行完成返回ModelAndView。
7、 HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
8、 DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
9、 ViewReslover解析後返回具體View。
10、DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
11、 DispatcherServlet響應用戶
組件說明:
以下組件通常使用框架提供實現:
DispatcherServlet:作爲前端控制器,整個流程控制的中心,控制其它組件執行,統一調度,降低組件
之間的耦合性,提高每個組件的擴展性
HandlerMapping:通過擴展處理器映射器實現不同的映射方式,例如:配置文件方式,實現接口方
式,註解方式等。
HandlAdapter:通過擴展處理器適配器,支持更多類型的處理器。
ViewResolver:通過擴展視圖解析器,支持更多類型的視圖解析,例如:jsp、freemarker、pdf、
excel等。
組件:
1、前端控制器DispatcherServlet(不需要工程師開發),由框架提供
作用:接收請求,響應結果,相當於轉發器,中央處理器。有了dispatcherServlet減少了其它組件之間
的耦合度。
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的中心,由
它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
2、處理器映射器HandlerMapping(不需要工程師開發),由框架提供
作用:根據請求的url查找Handler
HandlerMapping負責根據用戶請求找到Handler即處理器,springmvc提供了不同的映射器實現不同
的映射方式,例如:配置文件方式,實現接口方式,註解方式等。
3、處理器適配器HandlerAdapter
作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的
處理器進行執行。
4、處理器Handler(需要工程師開發)
注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器纔可以去正確執行Handler
Handler 是繼DispatcherServlet前端控制器的後端控制器,在DispatcherServlet的控制下Handler對具
體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要工程師根據業務需求開發Handler。
5、視圖解析器View resolver(不需要工程師開發),由框架提供
作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即
具體的頁面地址,再生成View視圖對象,最後對View進行渲染將處理結果通過頁面展示給用戶。
springmvc框架提供了很多的View視圖類型,包括:jstlView、freemarkerView、pdfView等。一般情
況下需要通過頁面標籤或頁面模版技術將模型數據通過頁面展示給用戶,需要由工程師根據業務需求開
發具體的頁面。
6、視圖View(需要工程師開發jsp…)
View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf…)核心架構的具體流程步驟如
下:
(1) 首先用戶發送請求——>DispatcherServlet,前端控制器收到請求後自己不進行處理,而是委託給
其他的解析器進行處理,作爲統一訪問點,進行全局的流程控制;
(2) DispatcherServlet——>HandlerMapping, HandlerMapping 將會把請求映射爲
HandlerExecutionChain 對象(包含一個Handler 處理器(頁面控制器)對象、多個
HandlerInterceptor 攔截器)對象,通過這種策略模式,很容易添加新的映射策略;
(3) DispatcherServlet——>HandlerAdapter,HandlerAdapter 將會把處理器包裝爲適配器,從而支
持多種類型的處理器,即適配器設計模式的應用,從而很容易支持很多類型的處理器;
(4) HandlerAdapter——>處理器功能處理方法的調用,HandlerAdapter 將會根據適配的結果調用真
正的處理器的功能處理方法,完成功能處理;並返回一個ModelAndView 對象(包含模型數據、邏輯視
圖名);
(5) ModelAndView的邏輯視圖名——> ViewResolver, ViewResolver 將把邏輯視圖名解析爲具體的
View,通過這種策略模式,很容易更換其他視圖技術;
(6) View——>渲染,View會根據傳進來的Model模型數據進行渲染,此處的Model實際是一個Map數
據結構,因此很容易支持其他視圖技術;
(7) 返回控制權給DispatcherServlet,由DispatcherServlet返回響應給用戶,到此一個流程結束。下邊
兩個組件通常情況下需要開發:
Handler:處理器,即後端控制器用controller表示。
View:視圖,即展示給用戶的界面,視圖中通常需要標籤語言顯示模型數據

Mybatis的執行器有哪些

Mybatis有三種基本的Executor執行器:SimpleExecutor、ReuseExecutor、BatchExecutor。
**SimpleExecutor:**每執行一次update或select,就開啓一個Statement對象,用完立刻關閉Statement對象。
**ReuseExecutor:**執行update或select,以sql作爲key查找Statement對象,存在就使用,不存在就創建,用完後,不關閉Statement對象,而是放置於Map內,供下一次使用。簡言之,就是重複使用Statement對象。
**BatchExecutor:**執行update(沒有select,JDBC批處理不支持select),將所有sql都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象,每個Statement對象都是addBatch()完畢後,等待逐一執行executeBatch()批處理。與JDBC批處理相同。
作用範圍:Executor的這些特點,都嚴格限制在SqlSession生命週期範圍內。

Mybatis中如何指定使用哪一種Executor執行器?

答:在Mybatis配置文件中,可以指定默認的ExecutorType執行器類型,也可以手動給DefaultSqlSessionFactory的創建SqlSession的方法傳遞ExecutorType類型參數。

Mybatis的分頁操作是怎麼實現的

原文地址

一、內存分頁,使用RowBounds類,但這種方式不推薦,基本不用,所以此方式集成省略。
二、自定義實現,代碼量比較少,簡單,比較靈活。以下爲具體的集成步驟:
1、在User.xml中加入select節點,並組裝分頁SQL
2、在IUserOperation.java中加入Mapping對應的方法
3、修改UserController.java中獲取數據的方法,改成分頁方法,並傳入指定參數
三、通過自定義插件的形式實現分頁,也是最好的,也叫做分頁攔截器。實現步驟如下:
插件支持MySQL和Oracle兩種數據庫,通過方法名關鍵字ListPage去匹配,有才進行分頁處理,並且不用在Mapping中寫分頁代碼。
1、在User.xml中添加查詢語句
2、在IUserOperation.java中添加接口
3、以下是插件實現的三個類

pagehelper是怎麼實現的

PageHelper攔截的是org.apache.ibatis.executor.Executorquery方法,其傳參的核心原理是通過ThreadLocal進行的。當我們需要對某個查詢進行分頁查詢時,我們可以在調用Mapper進行查詢前調用一次PageHelper.startPage(..),這樣PageHelper會把分頁信息存入一個ThreadLocal變量中。在攔截到Executorquery方法執行時會從對應的ThreadLocal中獲取分頁信息,獲取到了,則進行分頁處理,處理完了後又會把ThreadLocal中的分頁信息清理掉,以便不影響下一次的查詢操作。所以當我們使用了PageHelper.startPage(..)後,每次將對最近一次的查詢進行分頁查詢,如果下一次查詢還需要進行分頁查詢,需要重新進行一次PageHelper.startPage(..)。這樣就做到了在引入了分頁後可以對原來的查詢代碼沒有任何的侵入性。此外,在進行分頁查詢時,我們的返回結果一般是一個java.util.ListPageHelper分頁查詢後的結果會變成com.github.pagehelper.Page類型,其繼承了java.util.ArrayList,所以不會對我們的方法聲明造成影響。com.github.pagehelper.Page中包含有返回結果的分頁信息,包括總記錄數,總的分頁數等信息,所以一般我們需要把返回結果強轉爲com.github.pagehelper.Page類型

Mybatis的動態SQL是怎麼實現的

MyBatis中用於實現動態SQL的元素主要有:
1、if和where
2、choose(when,otherwise)
3、trim
4、set
5、foreach

Mybatis中的xml如何與接口中的方法進行綁定

接口映射就是在IBatis中任意定義接口,然後把接口裏邊的方法和SQL語句綁定,我們可以直接調用接口方法,比起SqlSession提供的方法我們可以有更加靈活的選擇和設置

線程與進程的關係,線程的狀態、線程裏的方法,

進程:初始、就緒、運行、阻塞、死亡
線程的基本狀態包括:派生,阻塞,激活,調度,結束。
派生(New):線程在進程內派生出來,它即可由進程派生,也可由線程派生。
阻塞(Block):如果一個線程在執行過程中需要等待某個事件發生,則被阻塞。
激活(Unblock):如果阻塞線程的事件發生,則該線程被激活並進入就緒隊列。
調度(Schedule):選擇一個就緒線程進入執行狀態。
結束(Finish):如果一個線程執行結束,它的寄存器上下文以及堆棧內容等將被釋放。

JAVA中線程同步的方法(7種)彙總

一、同步方法
  即有synchronized關鍵字修飾的方法。 由於java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時, 內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。
注: synchronized關鍵字也可以修飾靜態方法,此時如果調用該靜態方法,將會鎖住整個類。
二、同步代碼塊
  即有synchronized關鍵字修飾的語句塊。 被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
三、wait與notify
wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
notifyAll():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭
四、使用特殊域變量(volatile)實現線程同步
五、使用重入鎖實現線程同步
JavaSE5.0中新增了一個java.util.concurrent包來支持同步。
ReentrantLock類是可重入、互斥、實現了Lock接口的鎖,它與使用synchronized方法和快具有相同的基本行爲和語義,並且擴展了其能力。
六、使用局部變量實現線程同步
如果使用ThreadLocal管理變量,則每一個使用該變量的線程都獲得該變量的副本,副本之間相互獨立,這樣每一個線程都可以隨意修改自己的變量副本,而不會對其他線程產生影響。
ThreadLocal 類的常用方法

ThreadLocal() : 創建一個線程本地變量 
get() : 返回此線程局部變量的當前線程副本中的值 
initialValue() : 返回此線程局部變量的當前線程的"初始值" 
set(T value) : 將此線程局部變量的當前線程副本中的值設置爲value

注:ThreadLocal與同步機制
​ a.ThreadLocal與同步機制都是爲了解決多線程中相同變量的訪問衝突問題。
​ b.前者採用以"空間換時間"的方法,後者採用以"時間換空間"的方式
七、使用阻塞隊列實現線程同步

前面5種同步方式都是在底層實現的線程同步,但是我們在實際開發當中,應當儘量遠離底層結構。 使用javaSE5.0版本中新增的java.util.concurrent包將有助於簡化開發。 本小節主要是使用LinkedBlockingQueue來實現線程的同步 LinkedBlockingQueue是一個基於已連接節點的,範圍任意的blocking queue。 隊列是先進先出的順序(FIFO),關於隊列以後會詳細講解~LinkedBlockingQueue 類常用方法 LinkedBlockingQueue() : 創建一個容量爲Integer.MAX_VALUE的LinkedBlockingQueue put(E e) : 在隊尾添加一個元素,如果隊列滿則阻塞 size() : 返回隊列中的元素個數 take() : 移除並返回隊頭元素,如果隊列空則阻塞代碼實例: 實現商家生產商品和買賣商品的同步
注:BlockingQueue定義了阻塞隊列的常用方法,尤其是四種操作元素的方法,我們要多加註意,當隊列滿或空時:
  add()方法會拋出異常

offer()方法返回false

take()方法會阻塞

put()方法會阻塞

notify是誰的方法,notifyall和notify。有什麼區別

notify時Object類的方法, Java提供了兩個方法notify和notifyAll來喚醒在某些條件下等待的線程,你可以使用它們中的任何一個,但是Java中的notify和notifyAll之間存在細微差別,這使得它成爲Java中流行的多線程面試問題之一。當你調用notify時,只有一個等待線程會被喚醒而且它不能保證哪個線程會被喚醒,這取決於線程調度器。雖然如果你調用notifyAll方法,那麼等待該鎖的所有線程都會被喚醒,但是在執行剩餘的代碼之前,所有被喚醒的線程都將爭奪鎖定,這就是爲什麼在循環上調用wait,因爲如果多個線程被喚醒,那麼線程是將獲得鎖定將首先執行,它可能會重置等待條件,這將迫使後續線程等待。因此,notify和notifyAll之間的關鍵區別在於notify()只會喚醒一個線程,而notifyAll方法將喚醒所有線程。

何時在Java中使用notify和notifyAll
如果所有線程都在等待相同的條件,並且一次只有一個線程可以從條件變爲true,則可以使用notify over notifyAll。
在這種情況下,notify是優於notifyAll 因爲喚醒所有這些因爲我們知道只有一個線程會受益而所有其他線程將再次等待,所以調用notifyAll方法只是浪費CPU。
雖然這看起來很合理,但仍有一個警告,即無意中的接收者吞下了關鍵通知。通過使用notifyAll,我們確保所有收件人都會收到通知

什麼是線程安全?怎麼解決線程安全問題

在多個線程併發環境下,多個線程共同訪問同一共享內存資源時,其中一個線程對資源進行寫操作的中途(寫⼊入已經開始,但還沒 結束),其他線程對這個寫了一半的資源進⾏了讀操作,或者對這個寫了一半的資源進⾏了寫操作,導致此資源出現數據錯誤。

  • 保證共享資源在同一時間只能由一個線程進行操作(原子性,有序性)。
  • 將線程操作的結果及時刷新,保證其他線程可以立即獲取到修改後的最新數據(可見性)。
    原文地址
    提供了兩種方式來實現同步互斥訪問:synchronized和Lock。

synchronize 膨脹鎖的過程是什麼樣的?

原文地址

說一說反射,java中可不可以獲取到私有的屬性和方法

可以,使用反射
原文地址

如何去創建一個自定義註解。

原文地址

java的多態是一種什麼機制

多態就是指一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。
因爲在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。
特點:
指向子類的父類引用由於向上轉型了,它只能訪問父類中擁有的方法和屬性,而對於子類中存在而父類中不存在的方法,該引用是不能使用的,儘管是重載該方法。
若子類重寫了父類中的某些方法,在調用該些方法的時候,必定是使用子類中定義的這些方法(動態連接、動態調用)。
Java實現多態有三個必要條件:繼承、重寫、向上轉型。

集合中treeset的概念

TreeSet的構造函數都是通過新建一個TreeMap作爲實際存儲Set元素的容器。因此得出結論: TreeSet的底層實際使用的存儲容器就是TreeMap。
對於TreeMap而言,它採用一種被稱爲”紅黑樹”的排序二叉樹來保存Map中每個Entry。每個Entry被當成”紅黑樹”的一個節點來對待。

1、不能有重複的元素;
2、具有排序功能;
3、TreeSet中的元素必須實現Comparable接口並重寫compareTo()方法,TreeSet判斷元素是否重複 、以及確定元素的順序 靠的都是這個方法;
①對於Java類庫中定義的類,TreeSet可以直接對其進行存儲,如String,Integer等,因爲這些類已經實現了Comparable接口);
②對於自定義類,如果不做適當的處理,TreeSet中只能存儲一個該類型的對象實例,否則無法判斷是否重複。
4、依賴TreeMap。
5、相對HashSet,TreeSet的優勢是有序,劣勢是相對讀取慢。根據不同的場景選擇不同的集合。
原文鏈接

ArrayList和LinkList的區別

Array(數組)是基於索引(index)的數據結構,它使用索引在數組中搜索和讀取數據是很快的。
Array獲取數據的時間複雜度是O(1),但是要刪除數據卻是開銷很大,因爲這需要重排數組中的所有數據,
(因爲刪除數據以後, 需要把後面所有的數據前移)
缺點: 數組初始化必須指定初始化的長度, 否則報錯
例如:
List—是一個有序的集合,可以包含重複的元素,提供了按索引訪問的方式,它繼承Collection。
List有兩個重要的實現類:ArrayList和LinkedList
ArrayList: 可以看作是能夠自動增長容量的數組
ArrayList的toArray方法返回一個數組
ArrayList的asList方法返回一個列表
ArrayList底層的實現是Array, 數組擴容實現
LinkList是一個雙鏈表,在添加和刪除元素時具有比ArrayList更好的性能.但在get與set方面弱於
ArrayList.當然,這些對比都是指數據量很大或者操作很頻繁。

ArrayList底層實現了一個Random access接口,這個接口有什麼作用

原來RandomAccess接口是一個標誌接口(Marker),然而實現這個接口有什麼作用呢?
解答:只要List集合實現這個接口,就能支持快速隨機訪問,然而又有人問,快速隨機訪問是什麼東西?有什麼作用?
最後總結一句話:實現RandomAccess接口的List可以通過for循環來遍歷數據比使用iterator遍歷數據更高效,未實現RandomAccess接口的List可以通過iterator遍歷數據比使用for循環來遍歷數據更高效。

序列化與反序列化的作用

簡單說就是爲了保存在內存中的各種對象的狀態(也就是實例變量,不是方法),並且可以把保存的對
象狀態再讀出來。雖然你可以用你自己的各種各樣的方法來保存object states,但是Java給你提供一種
應該比你自己好的保存對象狀態的機制,那就是序列化。什麼情況下需要序列化:
a)當你想把的內存中的對象狀態保存到一個文件中或者數據庫中時候;
b)當你想用套接字在網絡上傳送對象的時候;
c)當你想通過RMI傳輸對象的時候;

spring中是如何通過反射創建對象的

原文地址

spring中解決線程安全問題

一直有個疑惑,spring是怎麼處理自己的線程安全問題的呢,這裏簡單說明下。

1、介紹兩個概念
有狀態的bean:對象中有實例變量(成員變量),可以保存數據,是非線程安全的。

無狀態的bean:對象中沒有實例變量(成員變量),不能保存數據,可以在多線程環境下共享,是線程安全的。

2、spring的線程安全問題
2.1 我們都知道spring中的bean默認都是單例的,ioc容器中一個類只會存在一個實例對象。這種設計是怎麼保證線程安全的?

一般不會出現線程安全問題。在spring中,絕大部分bean都是無狀態的,因此即使這些bean默認是單例的,也不會出現線程安全問題的。比如controller、service、dao這些類,這些類裏面通常不會含有成員變量,因此它們被設計成單例的。如果這些類中定義了實例變量,就線程不安全了,所以儘量避免定義實例變量。

2.2 對於spring中有狀態的bean,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder,爲什麼也能夠設計成單例的呢?它是怎麼保證線程安全的?

對於有狀態的bean,spring採用ThreadLocal進行處理,使它們成爲線程安全可以共享的對象。

對於有狀態的bean,也可以使用原型模式(prototype),每次使用時都會重新生成一個對象,解決了線程不安全的問題。

ps:無狀態的Bean適合使用不變模式,即單例模式,這樣可以共享實例,提高性能。有狀態的Bean,多線程環境下不安全,適合使用Prototype原型模式。Prototype: 每次對bean的請求都會創建一個新的bean實例。
原文地址

ThreadLocal底層是怎麼實現的

ThreadLocal ,也叫線程本地變量,可能很多朋友都知道ThreadLocal爲變量在每個線程中都創建了所使用的的變量副本。使用起來都是在線程的本地工作內存中操作,並且提供了set和get方法來訪問拷貝過來的變量副本。底層也是封裝了ThreadLocalMap集合類來綁定當前線程和變量副本的關係,各個線程獨立並且訪問安全!

(1) ThreadLocal僅僅是個變量訪問的入口;

(2) 每一個Thread對象都有一個ThreadLocalMap對象,這個ThreadLocalMap持有對象的引用;

(3) ThreadLocalMap以當前的threadLocal對象爲key,以真正的存儲對象爲value。get()方法時通過threadLocal實例就可以找到綁定在當前線程上的副本對象。

ThreadLocal這樣設計有兩個目的:
第一:可以保證當前線程結束時,相關對象可以立即被回收
第二:ThreadLocalMap元素會大大減少,因爲Map過大容易造成哈希衝突而導致性能降低。
應用場景:
​ ThreadLocal對象通常用於房子對可變的單實例變量或全局變量進行共享。例如:由於JDBC的連接對象不是線程安全的,因此,當多個線程應用程序在沒有協同的情況下,使用全局變量時,就是線程不安全的。通過將JDBC的連接對象保存到ThreadLocal中,每個線程都會擁有自己的連接對象副本。
​ ThreadLocal在Spring的事物管理,包括Hibernate管理等都有出現,在web開發中,有事會用來管理用戶回話HttpSession,web交互這種典型的一請求一線程的場景似乎比較適合使用ThreadLocal,但是需要注意的是,由於此時session與線程關聯,而Tomcat這些web服務器多采用線程池機制,也就是說線程是可以複用的,所以在每次進入的時候都需要重新進行set操作,或者使用完畢以後及時remove掉!

Spring如何解決循環依賴

原文地址

MySQL的隔離級別

原文地址

MySQL的搜索引擎,myisam,innodb他們有什麼區別

Innodb引擎概述
Innodb引擎提供了對數據庫ACID事務的支持,並且實現了SQL標準的四種隔離級別。該引擎還提供了行級鎖和外鍵約束,它的設計目標是處理大容量數據庫系統,它本身其實就是基於MySQL後臺的完整數據庫系統,MySQL運行時Innodb會在內存中建立緩衝池,用於緩衝數據和索引。但是該引擎不支持FULLTEXT類型的索引,而且它沒有保存表的行數,當SELECT COUNT() FROM TABLE時需要掃描全表。當需要使用數據庫事務時,該引擎當然是首選。由於鎖的粒度更小,寫操作不會鎖定全表,所以在併發較高時,使用Innodb引擎會提升效率。但是使用行級鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表。
MyISAM引擎概述
MyISAM是MySQL默認的引擎,但是它沒有提供對數據庫事務的支持,也不支持行級鎖和外鍵,因此當INSERT(插入)或UPDATE(更新)數據時即寫操作需要鎖定整個表,效率便會低一些。不過和Innodb不同,MyISAM中存儲了表的行數,於是SELECT COUNT(
) FROM TABLE時只需要直接讀取已經保存好的值而不需要進行全表掃描。如果表的讀操作遠遠多於寫操作且不需要數據庫事務的支持,那麼MyISAM也是很好的選擇。
簡單介紹區別:
1、MyISAM是非事務安全的,而InnoDB是事務安全的

2、MyISAM鎖的粒度是表級的,而InnoDB支持行級鎖

3、MyISAM支持全文類型索引,而InnoDB不支持全文索引

4、MyISAM相對簡單,效率上要優於InnoDB,小型應用可以考慮使用MyISAM

5、MyISAM表保存成文件形式,跨平臺使用更加方便

應用場景:

1、MyISAM管理非事務表,提供高速存儲和檢索以及全文搜索能力,如果再應用中執行大量select操作,應該選擇MyISAM
2、InnoDB用於事務處理,具有ACID事務支持等特性,如果在應用中執行大量insert和update操作,應該選擇InnoDB
原文鏈接:https://blog.csdn.net/printwsl/article/details/80058841

SQL語句的執行過程,語句的執行順序

原文地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章