java面試中可能常問的幾個技術問題及答案
string和stringBuffer的區別;
a. 常量和變數的區別,string雖然可以在後面增加其他字串,但是增加後就成了另一個物件,所以是個常量,stringBuffer字串改變後;
b. 當字串需要經常改變的時候,一般用StringBuffer,執行效果更快;
c. String中有的api方法,stringbuffer一般都有,但stringbuffer中有的方法,string中不一定有,如append,reverse,insert,delete等方法;
d. StringBuffer可以通過toString方法轉換為String型別。
StringBuffer
a. StringBuffer:執行緒安全的,StringBuilder:執行緒非安全,即多執行緒執行的情況下,可能會執行不正常;
b. 只有一個執行緒執行時,一般StringBuilder不會執行不正常,所以單執行緒情況下字串需要做大量改變行為時,可用stringBuilder,多執行緒執行時,要用StringBuffer。
系統中怎麼上傳檔案;
A. 表單裡有預設的檔案提交元件,把input的type設定為file,然後設定表單的enctype:multipart/form-data,表單上傳的enctype有三種,分別為:
B. 上傳檔案預設enctype為application/x-www-form-urlencoded,會對上傳的檔案內容進行編碼,而進行編碼的檔案將不能進行上傳活動;multipart/form-data不對檔案內容進行編碼,將以二進位制格式上傳檔案,form裡的input值將以二進位制格式傳遞到後臺伺服器,而text/plain將以文字格式傳遞表單裡面的input的值。
mybatis和Hibernate
a. Hibernate是在jdbc上進行的封裝,而mybatis是基於原生jdbc的封裝,所以執行速度上,效能上mybatis會優於hibernate;
b.Hibernate對於表的查詢,是需要將物件中與表關聯的所有屬性都查出來,而mybatis可以選擇性查詢表的欄位,查詢效率較Hibernate高;
二者的其他區別:
hibernate的學習門檻較高,相對於mybatis更復雜,而mybatis是一個比較簡陋的持久層框架;hiberrnate支援物件與表之間的對映,即物件中的屬性,直接與表中的欄位進行關聯,對資料庫表的操作可以直接通過對物件的操作來完成,而mybatis一般是直接在配置檔案中寫sql;快取機制有差別,hebernate有二級快取機制,一級快取在session中可直接設定,二級快取可在sessionFactory體現,而mybatis的快取也有自己的session機制,且可在寫sql的配置檔案中,通過寫cache標籤來對相應資料進行快取。
要是我自己選擇,我會選擇用mybatis框架,嘿嘿。。。
快取機制;
Redis是最常用的快取技術;spring整合了redis,故可以直接用spring整合的redis來開發java所開發系統的快取機制。
Spring的快取機制,redisTemplate類中有關於快取的相關api,一般是將前端經常會進行操作或查詢的資料,放入到spring快取中,然後前端若對這部分資料進行操作,spring可直接從快取中取出,以供使用者查詢或其他操作;
Redis五大型別,分別有redisTemplate的五種方法來對應操作(以下為轉載內容):
Redis五大型別:字串(String)、雜湊/雜湊/字典(Hash)、列表(List)、集合(Set)、有序集合(sorted set)五種
Controller:@Resource RedisTemplate<String, String> redisTemplate;
總括:
redisTemplate.opsForValue();//操作字串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set,
經常被訪問的資料可放在一級快取,一級快取中的資料不允許出現併發問題;
很少被修改,不是很重要的資料,很少用到的資料,可以放到二級快取,可以允許少量的併發問題;
經常被修改的資料,重要的資料,如財務資料,客戶資訊資料,不能放入二級快取,不允許出現併發問題。
java的反射機制(以下為轉載內容)
比較全的解釋了:JAVA反射機制
JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為的反射機制。
Java反射機制主要提供了以下功能:在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。
1. 得到某個物件的屬性
1 public Object getProperty(Object owner, String fieldName) throws Exception {
2 Class ownerClass =owner.getClass();
3
4 Field field = ownerClass.getField(fieldName);
5
6 Object property = field.get(owner);
7
8 return property;
9 }
Class ownerClass = owner.getClass():得到該物件的Class。
Field field = ownerClass.getField(fieldName):通過Class得到類宣告的屬性。
Object property = field.get(owner):通過物件得到該屬性的例項,如果這個屬性是非公有的,這裡會報IllegalAccessException。
2. 得到某個類的靜態屬性
1 public Object getStaticProperty(StringclassName, String fieldName)
2 throws Exception {
3 Class ownerClass = Class.forName(className);
4
5 Field field = ownerClass.getField(fieldName);
6
7 Object property = field.get(ownerClass);
8
9 return property;
10 }
Class ownerClass = Class.forName(className) :首先得到這個類的Class。
Field field = ownerClass.getField(fieldName):和上面一樣,通過Class得到類宣告的屬性。
Object property = field.get(ownerClass) :這裡和上面有些不同,因為該屬性是靜態的,所以直接從類的Class裡取。
3. 執行某物件的方法
1 public Object invokeMethod(Objectowner, String methodName, Object[] args) throws Exception {
2
3 Class ownerClass = owner.getClass();
4
5 Class[] argsClass = new Class[args.length];
6
7 for (int i = 0, j = args.length; i < j; i++) {
8 argsClass[i] = args[i].getClass();
9 }
10
11 Method method =ownerClass.getMethod(methodName, argsClass);
12
13 return method.invoke(owner, args);
14 }
Class owner_class = owner.getClass() :首先還是必須得到這個物件的Class。
5~9行:配置引數的Class陣列,作為尋找Method的條件。
Method method = ownerClass.getMethod(methodName, argsClass):通過Method名和引數的Class陣列得到要執行的Method。
method.invoke(owner, args):執行該Method,invoke方法的引數是執行這個方法的物件,和引數陣列。返回值是Object,也既是該方法的返回值。
4. 執行某個類的靜態方法
1 public ObjectinvokeStaticMethod(String className, String methodName,
2 Object[] args) throws Exception {
3 Class ownerClass = Class.forName(className);
4
5 Class[] argsClass = new Class[args.length];
6
7 for (int i = 0, j = args.length; i < j; i++) {
8 argsClass[i] = args[i].getClass();
9 }
10
11 Method method =ownerClass.getMethod(methodName, argsClass);
12
13 return method.invoke(null, args);
14 }
基本的原理和例項3相同,不同點是最後一行,invoke的一個引數是null,因為這是靜態方法,不需要藉助例項執行。
5. 新建例項
1
2 public Object newInstance(StringclassName, Object[] args) throws Exception {
3 Class newoneClass = Class.forName(className);
4
5 Class[] argsClass = new Class[args.length];
6
7 for (int i = 0, j = args.length; i < j; i++) {
8 argsClass[i] = args[i].getClass();
9 }
10
11 Constructor cons =newoneClass.getConstructor(argsClass);
12
13 return cons.newInstance(args);
14
15 }
這裡說的方法是執行帶引數的建構函式來新建例項的方法。如果不需要引數,可以直接使用newoneClass.newInstance()來實現。
Class newoneClass = Class.forName(className):第一步,得到要構造的例項的Class。第5~第9行:得到引數的Class陣列。
Constructor cons = newoneClass.getConstructor(argsClass):得到構造子。
cons.newInstance(args):新建例項。
6. 判斷是否為某個類的例項
1 public boolean isInstance(Object obj, Class cls) {
2 return cls.isInstance(obj);
3 }
7. 得到陣列中的某個元素
1 public Object getByArray(Object array, int index) {
2 return Array.get(array,index);
3 }
;