mysql sycho_Java面试题 - osc_p1rj1z8j的个人空间 - OSCHINA - 中文开源技术交流社区
1.Java有幾種數據類型?分別是什么?
Java有8種數據類型:
字符類型:char(16位)
布爾類型:boolean(true/false)
數值類型:
整數類型:byte(8位),short(16位),int(32位),long(64位)
浮點數類型:float(32位,直接賦值必須在數字后加f/F),double(64位賦值在數字 后加d/D/不加)
簡單數據類型對應的封裝類:
boolean? ? byte? ? char? ? ? ? ? ? ?short? ? int? ? ? ? ? ?long? ? float? ? ?double? ?void
Boolean? ? Byte? ? Character? ?Short? ? Integer? ?Long? ?Flolat? ?Double? ?Void
Java有5中引用類型(對象類型):
類,接口,數組,枚舉,標注
Jvm的內存空間:
堆空間:分配對象:new Student()
棧空間:臨時變量:Student stu
代碼區:類的定義,靜態資源 Student.class
2.String、StringBuilder、StringBuffer的區別?和各自應用場景?
String str1=”hello”;
String str2=”hello”;
String str3=new String(“hello”);
String str4=new String(“hello”);
str1=str2???? true
str2=str3???? false
str3=str4???? false
str4.equals(str1)?? True? ?//equals方法默認比較的是內存地址,String類重寫了equals方法,比較內容是否一致
String str=“hello”這種方式創建字符串的時候,jvm會首先檢查字符串常量池中是否存在該字符串對象,如果已存在,那么就不會在字符串常量池中再創建了,直接返回給該字符串? ? ?在字符串常量池中內存地址。如果該字符串還不存在該常量池中。那么就會在字符串常量池中先創建該字符串的對象,然后返回。 new String(“hello”)這種方式創建字符串對象的
時候,首先會檢查字符串常量池中是否存在該字符串對象,如果已存在,那么就不會在字符串常量池中再創建了,如果還沒存在,那么就會在字符串常量池中創建“hello”字符串對? ? ?象,然后還會到對內存中再創建一份字符串的對象,把字符串常量池中的“hello”字符串拷貝到內存中的字符串對象,然后返回堆內存中字符串對象的內存地址
筆試題:new String(“abc”);創建了幾個對象?答:兩個對象,一個對象位于字符串常量池中,一個位于堆內存中
使用字節數組或字符數組都可以構建一個字符串對象如
byte[] buf={97,98,99};
str= new String(buf); //輸出abc char[] arr={‘明’,‘天’};
str= new String(arr); //輸出明天
字符串特點:字符串值是常量,它的值在創建后不能修改,字符串的內容一旦發生改變,那么馬上會創建一個新的對象。
注意:字符串的內容不適宜頻繁修改,因為一旦修改馬上創建一個新的對象,如果需要頻繁修改字符串的內容,建議使用字符串緩沖類(StringBuffer) StringBuffer實際上是一? ? ? ? ?個存儲字符的容器,StringBuffer底層是依賴了一個字符數組才能存儲數據的,該字符數組默認的初始容量長度是16,如果初始容量的長度不夠,則自動增加1倍
StringBuffer與StringBuilder的相同點與不同點:
相同點:
1. 兩個類都是字符串緩沖類
2. 兩個類的方法都是一致的
不同點:
1. StringBuffer是線程安全的,操作效率低;StringBuilder是線程非安全的,操作效率 高
2. StringBuffer是jdk1.0出現的,StringBuilder是jdk1.5出現的 推薦使用StringBuilder,因為操作效率高
3.Object類下有哪些方法?
Object clone() 創建并返回此對象的一個副本
boolean equals(Object obj)指示其他某個對象是否與此對象相等
protected void finalize()垃圾回收器確定不存在對該對象的更多引用時。有對象的垃圾回收器調用此方法
Class> getClass()返回此Object的運行時類
int hashCode()返回該對象的哈希嗎值
void notify()喚醒在此對象監視器上等待的單個線程
void notifyAll()喚醒在此對象監視器上等待的所有線程
String toString()返回該對象的字符串表示
void wait()在其他線程調用此對象的notify()方法或notifyAll()方法前,導致當前線程等待
void wait(long timeout)在其他線程調用此對象的notify()或notifyAll()方法,或者 超過制定的時間前,導致當前線程等待
void wait(long timeout,int nanos)在其他線程調用此對象的notify()或notifyAll() 方法,或者其他某個線程中斷當前線程,后者已超出某個實際時間量前,導致當前線程等待。
補充問題:wait和sleep的區別是什么?
1)wait和notify在線程問題中實組合使用的
2)wait方法執行前會釋放鎖,而sleep不會
4.面向對象的特點有哪些?重寫和重載的區別是什么?
面向對象的特地點:繼承、封裝、多態
函數的重寫:在繼承中,子類可以定義和父類相同名稱且參數列表一致的函數,將這種函數稱之為函數的重寫。當子類調用該函數,一定是調用重寫后的函數,可以通過super關鍵字進行父類的重寫函數的調用
注意:
函數名必須相同
參數列表必須相同
子類重寫父類的函數的時候,函數的訪問權限必須大于父類的函數的訪問權限
子類重寫父類的函數的時候,返回值的類型必須是父類函數類型或返回值類型的子類。不能返回比父類更大的數據類型;
函數的重載:
在同一個類中,有一個以上的同名函數,只要函數的參數列表或參數類型不一樣即可,與返回值無關。函數重載存在的原因:為了增強方法的閱讀性,優化了程序設計。
5.接口和抽象類有什么區別?
抽象類的特點:
有抽象函數的類一定是抽象類
抽象類中不一定有抽象函數
抽象類不能創建對象
抽象類主要為了提高代碼的復用性,讓子類繼承去使用
編譯器強制子類實現抽象類父類的未實現的方法(可以不實現,前提是子類也要聲明為抽象的)
抽象類一定有構造函數。主要是為了初始化抽象類中的屬性,通常由子類實現
抽象類可以繼承普通類和抽象類
final與abstract不能共存
static與abstract不能共存
private不能修飾抽象類
接口的特點:
類實現接口可以通過implements實現,實現接口的時候必須把接口中的所有方法實現,一個類可以實現多個接口
接口定義的所有的屬性默認是public static final的,即靜態常量既然是常量,那么定義的時候必須賦值
接口中定義的方法不能有方法體,接口中定義的方法默認添加public abstract
有抽象函數的不一定是抽象類,也可以是接口類
由于接口中的方法默認是抽象的,所以不能實例化
對于接口而言,可以使用子類來實現接口中未被實現的功能函數
如果實現類中要訪問接口中的成員,不能使用super關鍵字,因為兩者之間沒有顯示的繼承關系,況且接口中的成員屬性是靜態的,可以使用接口名直接訪問
接口沒有構造方法
一個類可以實現多個接口,只能繼承一個類。一個接口可繼承多個接口
6.ArrayList和LinkedList的實現原理是什么?各有什么優缺點?
ArrayList底層采用數組實現,默認10,每次增長60%,查詢塊,增刪慢
LinkList底層采用鏈表實現,增刪塊,查詢慢
---|Collection: 單列集合
---|List: 有存儲順序, 可重復
---|ArrayList:?? 數組實現, 查找快, 增刪慢? ? 由于是數組實現, 在增和刪的時候會牽扯到數組增容, 以及拷貝元素. 所以慢。數組是可以直接按索引查找, 所以查找時較快
---|LinkedList:? 鏈表實現, 增刪快, 查找慢? ?由于鏈表實現, 增加時只要讓前一個元素記住自己就可以, 刪除時讓前一個元素記住后一個元素, 后一個元素記住前一個元素. 這樣的增刪效率較高但查詢時需要一個一個的遍歷, 所以效率較低
---|Vector:?? 和ArrayList原理相同, 但線程安全, 效率略低? ?和ArrayList實現方式相同, 但考慮了線程安全問題, 所以效率略
---|Set: 無存儲順序, 不可重復
---|HashSet
---|TreeSet
---|LinkedHashSet
---| Map: 鍵值對
---|HashMap
---|TreeMap
---|HashTable
---|LinkedHashMap
什么時候該使用什么樣的集合
Collection 我們需要保存若干個對象的時候使用集合。
List?? 如果我們需要保留存儲順序, 并且保留重復元素, 使用List.如果查詢較多, 那么使用ArrayList如果存取較多, 那么使用LinkedList如果需要線程安全, 那么使用Vector
Set? 如果我們不需要保留存儲順序, 并且需要去掉重復元素, 使用Set.如果我們需要將元素排序, 那么使用TreeSet如果我們不需要排序, 使用HashSet, HashSet比TreeSet效率高.如果我們需要保留存儲順序, 又要過濾重復元素, 那么使用LinkedHashSet
7.HashMap 的數據結構,如何解決hash沖突問題?何時發生reHash操作?reHash過程是怎么樣的?
HashMap的數據結構是數組+鏈表的形式,底層采用的是數組,數組中每一項采用的是鏈表。
若發生hash沖突問題,即在同一hash位置有一個以上元素,此時元素應以鏈表的方式依次往后排放,以此來解決hash沖突問題。
當數組中元素大于hashMap的極限容量(容量*負載因子,負載因子默認為0.75,初始容量默認為16),此時會發生rehash操作。
rehash操作的過程是開辟一個新的數組空間,然后將所有元素重新使用hash算法
解決hash沖突問題的方法是擴容,當數組中元素大于hashMap點的極限容量(容量*負載因子),負載因子默認為0.75,初始容量默認為16,此時會發生rehash操作。
rehash操作的方式是開辟一個新的數組空間,然后將所有元素進行重新使用hash算法算出位置后以新的排序方式放在新的數組中。
8.hashMap是線程安全的嗎?hashMap和hashTable的區別是什么?
hashMap是線程不安全的,而hashTable是線程安全的
hashMap是不同步的,而hashTable是同步的
hashMap的效率比hashTable高
hashMap允許NULL鍵和NULL值,hashTable不允許
擴容方式不一樣:hashMap:原始容量=16, 擴容后:2*原始容量
hashTable:原始容量=11, 擴容后:2*原始容量+1
9.ConcurrentHanshMap的特點是什么?它比hashTable效率高的原因是什么?
ConcurrentHanshMap的特點是:它的同步機制是基于lock操作的,保證同步的時候,鎖住的不是整個對象,而是某一個segment;
hashtable是基于sychonized操作的,鎖住的是整個對象,所以效率低。
10.volatile關鍵字的作用是什么?
volatile可以保證可見性和有序性。
volatile被設計用來修飾被不同線程訪問和修改的變量。被volatile類型定義的變量,系統每次用到它都是直接從內存當中取,而不會利用緩存。在使用了volatile修飾成員變量后,所有線程在任何時候所看到的變量的值都是相同的。保證了可見性。但是volatile會阻止編譯器對代碼的優化,降低程序的執行效率,所以,除非迫不得已,盡量不使用volatile。
11.static關鍵字的作用是什么?
static關鍵字的作用主要是為了實現對象之間重復屬性的數據共享
static的使用:
主要用于修飾類的成員
成員變量:①非靜態成員變量:需要通過創建對象來訪問
②靜態成員變量:使用類名直接調用,也可以通過對象訪問
成員方法:①靜態函數中不能訪問非靜態成員變量,只能訪問靜態變量
②靜態方法不可以定義this,super關鍵字
③非靜態函數:非靜態函數中可以訪問靜態成員變量
12.final關鍵字的作用是什么?
final關鍵字主要用于修飾類、類成員、方法、以及方法的形參
①final修飾成員屬性,說明該成員屬性是常量,不能被修改。(常量名必須大寫)
②基本數據類型,final使其值不變;對象引用:final使其引用恒定不變,無法讓其
指向一個新的對象,但是對象自身卻可以被修改;該關鍵字一般和static組合使用
(常量可優先加載,不必等到創建對象的時候再初始化);final和static可互換位
置;常量一般final修飾
③final修飾類:該類是最終類,不能被繼承
④final修飾方法:該方法是最終方法,不能被重寫(如果一個類中的函數都被修飾為final時,可以將類定義為final)
13.synchronized關鍵字的作用是什么?synchronized有幾種用法?
synchronized是給同步代碼塊或同步函數加鎖,有兩種用法:
方式1:同步代碼塊:
Synchronized(“鎖對象”){
需要同步的代碼塊
}
方式2:同步函數:
函數使用synchronized修飾
14.synchronized和lock的區別:
1)synchronized在成功完成功能或者拋出異常時,虛擬機會自動釋放線程占有的鎖; 而Lock對象在發生異常時,如果沒有主動調用unLock()方法去釋放鎖,則鎖對象會一直持有,因此使用Lock時需要在finally塊中釋放鎖;
2)lock接口鎖可以通過多種方法來嘗試獲取鎖包括立即返回是否成功的tryLock(),以及一直嘗試獲取的lock()方法和嘗試等待指定時間長度獲取的方法,比synchronized相對靈活了許多
3)通過在讀多,寫少的高并發情況下,我們用ReentrantRead,WriteLock分別獲取讀鎖和寫鎖來提高系統的性能,因為讀鎖是共享鎖,即可以同時有多個線程讀取共享資源,而寫鎖則保證了對共享資源的修改只能是單線程的。
補充:
關于線程:
1.一個java應用程序至少有兩個線程,一個是主線程,負責main方法代碼的執行,一個是垃圾回收器線程,負責回收垃圾
2.多線程的好處:①解決了一個進程能同時執行多個任務的問題②提高了資源利用率
3.多線程弊端:①增加CPU的負擔②降低了一個進程中線程的執行概率③引發了線程安全問題④出現了死鎖現象
4.創建線程的方式有2種
方式一:①自定義一個類繼承Thread類②重寫Thread的run()方法,自定義線程就寫在run()方法中③創建Thread的子類對象,并且調用start方法開啟線程
方式二:①自定義一個類實現Runable接口②實現Runable的run方法,把自定義線程的任務定義在run方法上③創建Runable實現類對象④創建Thread類的對象,并且把
Runable實現類的對象作為實參傳遞⑤調用Thread類的start方法開啟線程
推薦使用第二種,原因:因為java是單繼承多實現的
5.出現線程安全問題的根本原因:①存在兩個或兩個以上線程對象,且線程之間共享了同一資源②有多個語句操作者同一資源
6.線程安全問題的解決方式:java線程同步機制:
方式1:同步代碼塊:
Synchronized(“鎖對象”){
需要同步的代碼塊
}
同步代碼塊要注意的事項:
①任意一個對象都可以作為鎖對象
②在同步代碼塊中調用了sleep方法不釋放鎖對象
③只有真正存在線程安全問題的時候才使用同步代碼塊,否則會降低相率
④多線程操作的鎖對象必須是唯一共享的。否則無效
方式二:同步函數:
函數使用synchronized修飾
注意:
①如果是一個非靜態的同步函數的鎖對象是this對象,如果是靜態的同步函數的鎖對象是當前函數所屬類的字節碼文件(class對象)
②同步函數的鎖對象是固定的,不能由你來指定
推薦使用同步代碼塊
①同步代碼塊的鎖對象可以由我們隨意指定,同步函數不行
②同步代碼塊可以很方便控制需要被同步代碼的范圍,同步函數必須是整個函數的代碼塊被同步了
15.死鎖現象:
死鎖現象出現的根本原因:
出現兩個或兩個以上的線程
出現兩個或兩個以上的共享資源
死鎖現象的解決方案:沒有方案,只能盡量避免
16.wait與notify方法要注意的事項:
wait方法與notify方法是屬于Object對象的,因為任意對象都可作為鎖對象
wait方法與notify方法必須要在同步代碼塊或者是同步函數中才能使用
wait方法與notify方法必須要由鎖對象調用
17.線程的停止:
停止一個線程,我們一般都會通過一個變量去控制
如果需要停止一個等待狀態下的線程,我們需要通過變量配合niotify()和interrupt()來使用
18.守護線程(后臺線程):在一個進程中,如果只剩下守護線程,那么守護線程也會死亡。
一個線程默認都不是守護線程,使用d.setDaemon(true),設置是否為守護線程,true為是,false為非守護線程
一個線程如果執行join()語句,那么就有新的線程加入,執行該語句的線程必須要讓步給新的線程完成任務,然后才能執行
19.MQ原理:
消息隊列,工作方式是不同步的
20.hashMap與ConcurrentHashMap的區別
HashMap---hashTable
首先hashMap的是線程不安全的,但是效率比較高,而hashTable是線程安全的,但效率有很低,若要在保證線程安全的前提下有較高的效率,可考慮使用
concurrentHashMap。
HashTable—ConCurrentHashMap
concurrentHashMap和HashTable一樣都是有加了鎖操作的,都是線程安全的,然而它們的鎖機制不一樣,所以concurrentHashMap比HashTable的效率高。
concurrentHashMap是基于lock機制的,有16把鎖分別鎖住concurrentHashMap的16的部分,而HashTable鎖住的是整個HashTable對象。
21.Java注解的原理、作用是什么?
原理:從java源碼到class字節碼是由編譯器完成的,編譯器會對java源碼進行解析并生成class文件,而注解也是在編譯時由編譯器進行處理,編譯器會對注解符號處理并附加到class結構中,根據jvm規范,class文件結構是嚴格有序的格式,唯一可以附加信息到class結構中的方式就是保存到class結構的attributes屬性中。我們知道對于類、字段、方法,在class結構中都有自己特定的表結構,而且各自都有自己的屬性,而對于注解,作用的范圍也可以不同,可以作用在類上,也可以作用在字段或方法上,這時編譯器會對應將注解信息存放到類、字段、方法自己的屬性上。在我們的AnnotationTest類被編譯后,在對應的AnnotationTest.class文件中會包含一個
RuntimeVisibleAnnotations屬性,由于這個注解是作用在類上,所以此屬性被添加到類的屬性集上。即Test注解的鍵值對value=test會被記錄起來。而當JVM加載
AnnotationTest.class文件字節碼時,就會將RuntimeVisibleAnnotations屬性值保存到AnnotationTest的Class對象中,于是就可以通過
AnnotationTest.class.getAnnotation(Test.class)獲取到Test注解對象,進而再通過Test注解對象獲取到Test里面的屬性值。這里可能會有疑問,Test注解對象是什么?其實
注解被編譯后的本質就是一個繼承Annotation接口的接口,所以@Test其實就是“public interface Test extends Annotation”,當我們通過
AnnotationTest.class.getAnnotation(Test.class)調用時,JDK會通過動態代理生成一個實現了Test接口的對象,并把將RuntimeVisibleAnnotations屬性值設置進此對象中,? ? 此對象即為Test注解對象,通過它的value()方法就可以獲取到注解值。Java注解實現機制的整個過程如上面所示,它的實現需要編譯器和JVM一起配合
作用:·
1)生成文檔。這是最常見的,也是java 最早提供的注解。常用的有@see @param @return 等·
2)跟蹤代碼依賴性,實現替代配置文件功能。比較常見的是spring 2.5 開始的基 于注解配置。作用就是減少配置。現在的框架基本都使用了這種配置來減少配 置文件的數量。
3)在編譯時進行格式檢查。如@Override?放在方法前,如果你這個方法并不是覆蓋了超類方法,則編譯時就能檢查出。
22.Java反射機制是什么?通過反射可以做什么?Class類下主要的方法有哪些?
類字節碼文件是在硬盤上存儲的,是一個個的.class文件。我們在new一個對象時,JVM會先把字節碼文件的信息讀出來放到內存中,第二次用時,就不用在加載了,而是直接使用之前緩存的這個字節碼信息。字節碼的信息包括:類名、聲明的方法、聲明的字段等信息。在Java中“萬物皆對象”,這些信息當然也需要封裝一個對象,這就是Class類、Method類、Field類。?通過Class類、Method類、Field類等等類可以得到這個類型的一些信息,甚至可以不用new關鍵字就創建一個實例,可以執行一個對象中的方法,設置或獲取字段的值,這就是反射技術。
Class類的方法有:
1)獲取class類的三種方式:
①Class.forName();
// 方式一
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
②類名.class
// 方式二
Class clazz2 = Person.class;
③對象名.getClass();
// 方式三
Person p1 = new Person();
Class clazz3 = p1.getClass();
2)通過class類獲取類型的一些信息
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
①getName()類的名稱(全名,全限定名)
// 獲取類的名稱
String name = clazz1.getName();
②getSimpleName()類的的簡單名稱(不帶包名)
// 獲取類的簡單名稱
System.out.println(clazz1.getSimpleName());
③getModifiers(); 類的的修飾符
// 獲取類的修飾符
int modifiers = clazz1.getModifiers();
④創建對象
無參數構造創建對象
newInstance()
// 構建對象(默認調用無參數構造.)
Object ins = clazz1.newInstance();
Person p = (Person) ins;
⑤獲取指定參數的構造器對象,并可以使用Constructor對象創建一個實例
Constructor getConstructor(Class>... parameterTypes)
// 獲取指定參數的構造函數
Constructor> con = clazz1.getConstructor(String.class, int.class);
// 使用Constructor創建對象.
Object p1 = con.newInstance("jack", 28);
System.out.println(((Person) p1).getName());
3)通過class類獲取類型中方法的信息
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
①獲取公共方法包括繼承的父類的方法
getMethods()返回一個數組,元素類型是Method
// 1.獲取非私用方法(包括父類繼承的方法)
Method[] methods = clazz1.getMethods();
System.out.println(methods.length);
for (Method m : methods) {
// System.out.println(m.getName());
if ("eat".equals(m.getName())) {
m.invoke(clazz1.newInstance(), null);
②獲取指定參數的公共方法
getMethod("setName", String.class);
③獲得所有的方法,包括私有
Method[] getDeclaredMethods()
④獲得指定參數的方法,包括私有
Method getDeclaredMethod(String name, Class>... parameterTypes)
/** * 獲取公有方法. * @throws Exception * */
private static void test3() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
// 1.獲取非私用方法(包括父類繼承的方法)
Method[] methods = clazz1.getMethods();
System.out.println(methods.length);
for (Method m : methods) {
// System.out.println(m.getName());
if ("eat".equals(m.getName())) {
m.invoke(clazz1.newInstance(), null);
}
}
}
/** * 獲取指定方法簽名的方法 * * @throws Exception * */
private static void test4() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
// 獲取指定名稱的函數
Method method1 = clazz1.getMethod("eat", null);
method1.invoke(new Person(), null); }
/** * 獲取指定方法名且有參數的方法 * * @throws Exception * */
private static void test5() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
Method method = clazz1.getMethod("eat", String.class);
method.invoke(new Person(), "包子");
}
/** * 獲取指定方法名,參數列表為空的方法. * * @throws Exception * */
private static void test4() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
// 獲取指定名稱的函數
Method method1 = clazz1.getMethod("eat", null);
method1.invoke(new Person(), null); }
/** * 反射靜態方法 * @throws Exception * */
private static void test7() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
Method method = clazz1.getMethod("play", null);
method.invoke(null, null);
}
/** * 訪問私有方法 暴力反射 * @throws Exception * */
private static void test6() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person");
Method method = clazz1.getDeclaredMethod("movie", String.class);
method.setAccessible(true);
method.invoke(new Person(), "小明");
}
4)通過Class類獲取類型中的字段的信息
①獲取公共字段
Field[] getFields()
②獲取指定參數的公共字段
Field getField(String name)
③獲取所有的字段
Field[] getDeclaredFields()
④獲取指定參數的字段,包括私用
Field getDeclaredField(String name)
23.MySQL增刪改查的基本命令是什么?熟記
http://www.cnblogs.com/mercuryji/p/mysql_operate.html
24.SPring中@Autowried、@Resource、@Component、@Service、@Controller、@PostConstruct注解的含義、作用是什么?
@Component 指定把一個對象加入IOC容器
@Repository 作用同@Component; 在持久層使用
@Service 作用同@Component; 在業務邏輯層使用
@Controller 作用同@Component; 在控制層使用,用于指示Spring類的實例是一個控制器
@Resource 屬性注入(多例時,要確保同一類型只有同一變量)是J2EE自帶的注解,可以按name和type匹配,默認按類型匹配
@Autowried 屬性注入,默認按名臣匹配
@postConstruct 被該注解修飾的方法會在服務器加載servlet的時候運行,并且只會被服務器調用一次,類似于servlet的init()方法。被@PostContruct修飾的方法會在構造函數只會,init()之前運行。
總結
以上是生活随笔為你收集整理的mysql sycho_Java面试题 - osc_p1rj1z8j的个人空间 - OSCHINA - 中文开源技术交流社区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浏览器本地mysql_IndexedDB
- 下一篇: mysql5.6cmd中代码_Mysql