java基礎面試
java基礎
① final 、finaly、finalize的不同
final 可以用來修飾類、方法、變量,分別有不同的意義,final 修飾的 class 代表不可以繼承擴展,final 的變量是不可以修改的,而 final 的方法也是不可以重寫的(override)。
finally 則是 Java 保證重點代碼一定要被執行的一種機制。我們可以使用 try-finally 或者 try-catch-finally 來進行類似關閉 JDBC 連接、保證 unlock 鎖等動作。
finalize 是基礎類 java.lang.Object 的一個方法,它的設計目的是保證對象在被垃圾收集前完成特定資源的回收。finalize 機制現在已經不推薦使用,並且在 JDK 9 開始被標記為 deprecated(棄用)。
② java數組排序查找
重點冒泡 選擇 二分法查找
1) 冒泡
int[] arr = {23,12,48,56,45}; int temp = -1; for(int i=0;i<arr.length;i++) { for(int j=i+1;j<arr.length;j++) { if(arr[i]>arr[j]) { temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } System.out.println(Arrays.toString(arr)); |
2) 選擇
int[] arr = {23,12,48,56,45}; for(int i=0;i<arr.length;i++) { int tem = i; for(int j=i;j<arr.length;j++) { if(arr[j] < arr[tem]) { tem = j; } } int temp1 = arr[i]; arr[i] = arr[tem]; arr[tem] = temp1; } System.out.println(Arrays.toString(arr)); |
3) 二分
int arr [] = new int [5]; int min = 0; int max = arr.length - 1; int mid = (min + max)/2; //tager是要查找的數 while(true){ if(tager > mid){ min = mid + 1; }else if(tager < mid){ max = mid -1; }else{ return mid; } if(min > max){ return -1; }
mid = (max + min )/2; } |
③ java String 的用法 和內存機制 、其中方法(重點equals(),substring())
我寫一下String的內存機制,其他內容較為簡單,請大家查閱學習。
字符串內存機制:
JVM運行的時候,將內存分為兩個部分,一部分是堆,一部分是棧。堆中存放的是創建對象,而棧中存放的則是方法調用過程中的局部變量或引用。在設計JAVA字符串對象內存實現的時候,在堆中又開辟了一塊很小的內存,稱之為字符串常量池,專門用來存放特定的字符串對象的。
String s1="JavaSE6.0"; //存放在字符串常量池中。性能高 String str = new String("JavaSE6.0"); //存放在堆中
s1==str ; //返回false s1.squals(str); //返回 true 補充:==和String equals()的比較 String equals()重寫了Object中的equals()方法,Object的equals()方法就是==比較,String equals()方法變成內容比較,==比較的是地址hashcode值,簡單的說成是比較對象的地址,如果對象引用的地址相同,那麽相當於對象是同一個對象。
|
題型:
String str=new String(“good”) ;//創建了幾個對象 String str1=”good”;//創建了幾個對象 String str2=new String (“good”);//創建了幾個對象
System.out.println(str==str1);//輸出什麽 System.out.println(str.equals(str2));//輸出什麽 System,out,println(str1==str2);//輸出什麽
① String常量池中查找有沒有字符常量“good”。因為沒有所以創建“good”對象,當執行new String(“good")時,則在Java的堆中創建一個”good”對象,而str是該對象的引用,因此共計創建2個對象。 ② 首先在String常量池中查找有沒有字符串常量“good",有則直接將str1作為String常量池中“good”的一個引用,當你重新聲明一個String型變量為“good”時,將使用串池裏原來的那個“good",而不用重新分配內存,也就是說,str與str1將會指向同一塊內存,因此,此時沒有創建任何對象。 ③ String常量池中查找有沒有字符串常量“good”,有則不進行再次創建,由於這裏用了new關鍵字(有new就有對象),所以在Java堆中又創建了一個“good”對象(地址與第一句在堆中創建的地址不同),而str2則是這個對象的引用,因此執行此句時,創建了1個對象。 ④ “==”是判斷對象的,由於str指向的是Java堆中的“good”對象,而str1指向的是String常量池中的“good”對象,所以返回值為false。 ⑤ 由於String類中的equals判斷的是對象的內容而不是內存地址,由於所有內容都是good,所以返回值為true。 ⑥ “==”是判斷對象的,由於str1指向的是Java堆中的“good”對象,而str2指向的是堆中的“good”對象,但是使用了new關鍵字,說明這兩個對象不是同一個對象,所以返回值為false |
④ 集合分類
connection:
1.list:List裏存放的對象是有序的,同時也是可以重復的。子接口:
1)linkedlist:底層是一個鏈表結構,增刪速度快。線程不是安全的。
2)arraylist:底層是一個數組結構,查詢速度快,線程是不安全的。內有sort
方 法可為arraylist元素自動排序。
3)vector:底層數組結構,在vector的操作方法中加了鎖,所以線程安全。
2.set: Set裏存放的對象是無序,不能重復的,集合中的對象不按特定的方式排
序,只是簡單地把對象加入集合中
1)hashset:底層是一個hashmap結構,非線程安全。
2)treeset:基於 TreeMap 的 NavigableSet 實現。使用元素的自然順序對
元素進行排序,或者根據創建 set 時提供的 Comparator進行排序,具
體取決於使用的構造方法。
map:Map集合中存儲的是鍵值對,鍵不能重復,值可以重復。根據鍵得到值,對map集合遍歷時先得到鍵的set集合,對set集合進行遍歷,得到相應的值。子接口:
hashmap: 數組方式存儲key/value,線程非安全,允許null作為key和value,
key不可以重復,value允許重復,不保證元素叠代順序是按照插入時的順序,
key的hash值是先計算key的hashcode值,然後再進行計算,每次容量擴容會
重新計算所以key的hash值,會消耗資源,要求key必須重寫equals和hashcode
方法
默認初始容量16,加載因子0.75,擴容為舊容量乘2,查找元素快,如果key
一樣則比較value,如果value不一樣,則按照鏈表結構存儲value,就是一個
key後面有多個value;
這裏介紹一下hashmap的子類並且也是map接口的子類。
linkedhashmap: LinkedHashMap可以認為是HashMap+LinkedList,即它既使用
HashMap操作數據結構,又使用LinkedList維護插入元素的先後順序。線程安全這一點是我們選用linkedhashmap而不選用hashmap的主要原因。
大家看一下源碼,內有多種構造方法,這裏不再一一贅述。
集合中有很多方法也是經常問到的,大家自己去分類把握。
再說一下集合的遍歷:
① .對於Arraylist 使用叠代器進行遍歷
ArrayList<String> list=new ArrayList<>(); list.add("jeremy"); list.add("張三"); list.add("李四");
Iterator iterator=list.iterator();//調用Arraylist中的叠代器方法 //返回的是Iterator 類型
while(iterator.hasNext()) { // hasNext() 方法 判斷叠代器中是否有可以叠代的元素 //並將指針下移 Object item=iterator.next(); System.out.println(item);
} |
② .對於set的遍歷
//和list 集合中的遍歷方法一致 區別在於set集合沒有順序 // 不可以根據下標獲得 Set<String > set=new HashSet<>(); set.add("jeremy"); set.add("張三"); set.add("李四");
//使用iterator 遍歷 Iterator< String > iterator=set.iterator(); while(iterator.hasNext()) {
Object object=iterator.next(); System.out.println(object);
}
//可以使用foreach循環遍歷 for(String item:set) { System.out.println(item); } } |
② 對於map的遍歷
map的存儲格式為鍵1----值 1,鍵2-----值2. 可根據get(key)方法 來取得值,key 為鍵
並且map也是一個無序 的集合 ,map沒有自帶的iterator()方法, 要遍歷map,除了使用foreach
我們需要使用一個‘‘中間人‘‘. map中有一個方法為keyset();可以得到鍵,返回一個Set對象.
//創建一個map Map<String, Object> map=new HashMap<>();
//添加數據 map.put("name", "james"); map.put("name1", "張三"); map.put("name3", "李四");
//使用set作為中間人 接收鍵名 Set<String > set=map.keySet();
//調用set中的叠代器 Iterator< String > iterator=set.iterator(); while(iterator.hasNext()) { Object object= iterator.next(); //根據健名獲得鍵值 System.out.println(object+"-----"+map.get(object)); } |
5.java的三大特性
1.繼承
只能單繼承,一個類只能有一個父類,易於管理程序,父類是子類的一般化,子類
是父類的特化(具體化)。
作用:
1) 繼承關系是傳遞的。若類C繼承類B,類B繼承類A(多繼承),則類C既有從
類B那裏繼承下來的屬性與方法,也有從類A那裏繼承下來的屬性與方法,還可以有自己新定義的屬性和方法。繼承來的屬性和方法盡管是隱式的,但仍是類C的屬性和方法。
2) 繼承提供了軟件復用功能。若類B繼承類A,那麽建立類B時只需要再描述與基
類(類A)不同的少量特征(數據成員和成員方法)即可。這種做法能減小代碼和數據的冗余度,大大增加程序的重用性。
2.墮胎:方法的重寫、重載與動態連接構成多態性
向上轉型:
我定義了一個子類Cat,它繼承了Animal類,那麽後者就是前者的父類。我可以通過
Cat c = new Cat(); 例化一個Cat的對象,這個不難理解。
但當我這樣定義時: Animal a = new Cat();
這代表什麽意思呢?
很簡單,它表示我定義了一個Animal類型的引用,指向新建的Cat類型的對象。由於Cat是繼承自它的父類Animal,所以Animal類型的引用是可以指向Cat類型的對象的。那麽這樣做有什麽意義呢?因為子類是對父類的一個改進和擴充,所以一般子類在功能上較父類更強大,屬性較父類更獨特,定義一個父類類型的引用指向一個子類的對象既可以使用子類強大的功能,又可以抽取父類的共性。所以,
父類引用只能調用父類中存在的方法和屬性,不能調用子類的擴展部分;因為父類引用指向的是堆中子類對象繼承的父類;(但是如果強制把超類轉換成子類的話,就可以調用子類中新添加而超類沒有的方法了。)
同時,父類中的一個方法只有在父類中定義而在子類中沒有重寫的情況下,才可以被父類類型的引用調用;
對於父類中定義的方法,如果子類中重寫了該方法,那麽父類類型的引用將會調用子類中的這個方法,這就是動態連接。
向下轉型:
向下轉型的前提是父類對象指向的是子類對象(也就是說,在向下轉型之前,它得先向上轉型)
向下轉型只能轉型為本類對象
3.封裝
封裝就是把同一類事物的共性(包括屬性和方法)歸到同一類中,方便使用。也就是說封裝:封裝也稱信息隱藏,是指利用抽象數據類型把數據和基於數據的操作封裝起來,使其成為一個不可分割的整體,數據隱藏在抽象數據內部,盡可能的隱藏數據細節,只保留一些接口使其與外界發生聯系。也就是說用戶無需知道內部的數據和方法的具體實現細節,只需根據留在外部的接口進行操作就行
實現封裝:通常將類的成員變量聲明為private,在通過public方法來對這個變量來訪問。對一個變量的操作,一般有讀取和賦值2個操作,,我們分別定義2個方法來實現這2個操作,一個是getXX(XX表示要訪問的成員變量的名字)用來讀取這個成員變量,另一個是setXX()用來對這個變量賦值
6.訪問權限範圍控制關鍵字:
1.pubilc 在項目下可訪問
2.default(默認不寫) 本類,本包訪問
3.protect 本類,本包子類訪問
4.private 本類訪問
7.重寫重載的用法和區別
重寫: 在java中有很多的繼承,繼承下來的有變量、方法。在有一些子類要實現的方法中,方法名、傳的參數、返回值跟父類中的方法一樣,但具體實現又跟父類的不一樣,這時候我們就需要重寫父類的方法
重載:重載是在一個類中實現的,有多個同名方法,但參數不一樣,包括參數類型、參數個數、還可以沒有參數,總之每個重載的方法的參數必須不一樣。
區別:
區別點 |
重載 |
重寫 |
參數列表 |
必須不同 |
必須相同 |
返回類型 |
可以不同 |
必須相同 |
異常 |
可以不同 |
不能拋出新的異常或更高的異常 |
訪問 |
可以不同· |
不能有更嚴格的訪問限制 |
8. this和super關鍵字
時間關系,咱們下次再說。
java基礎面試