摘要:網站的面試專題學習筆記非可變性和對象引用輸出為,前后皆有空格。假定??臻g足夠的話,盡管遞歸調用比較難以調試,在語言中實現遞歸調用也是完全可行的。棧遵守規則,因此遞歸調用方法能夠記住調用者并且知道此輪執行結束之返回至當初的被調用位置。
ImportNew 網站的Java面試專題學習筆記
1. 非可變性和對象引用String s = " Hello "; s += " World "; s.trim( ); System.out.println(s);
輸出為“ Hello World ”,前后皆有空格。
字符串是不可變對象。
s.trim()雖然生成了一個新的字符串對象,但是卻沒有變量指向這個心生成的對象,s 仍然指向字符串s += " World "。
下圖說明了,生成對象以及垃圾回收過程。
可用StringBuilder來構造,因為其底層使用的是字符數組,所有操作都直接在字符數組上直接操作,而且他不是一個線程安全的類,執行速度上,相比于StringBuffer要快。
這一點如果深入理解了String的Interning機制,就更好理解了。
Java程序在編譯時,會將所有確定下來的,存在雙引號內的字符串,都存入常量池中,該常量池是類文件(.class)的一部分。常量池中存著許多表,其中 Constant_Utf8_info 表中,記錄著會被初始化為 String 對象的字符串的字面值(iteral)。 在JVM 中,相應的類被加載運行后,常量池對應的映射到 JVM 的運行時常量池(run time constant pool)中。
關于String的intern()方法
當 intern 方法被調用,如果字符串池中已經擁有一個與該 String 的字符串值相等(即 equals()調用后為 true)的 String 對象時,那么池中的那個 String 對象會被返回。否則,池中會增加這個對象,并返回當前這個 String 對象。
現代的 JVM 實現里,考慮到垃圾回收(Garbage Collection)的方便,將 heap 劃分為三部分: young generation 、 tenured generation(old generation)和 permanent generation( permgen )。字符串池是為了解決字符串重復的問題,生命周期長,它存在于 permgen 中。
因此,對于
String str = new String("abc");
JVM會生成兩個字符串,一個是在常量池中,另外一個是new在heap堆中。
2. equals 和 ==Object s1 = new String("Hello"); Object s2 = new String("Hello"); if(s1 == s2) { System.out.println("s1 and s2 are =="); }else if (s1.equals(s2)) { System.out.println("s1 and s2 are equals()"); }
輸出結果為s1 and s2 are equals()
主要考察對equals和==的理解,==比較引用的地址是否相同,equeal比較對象中真正的值。
詳細的過程可見下圖
另外,如果不是用 new關鍵字強制創建字符串對象的話,而是采用==,那么Java會默認采用字符串池,減少對象的創建。
String對象會創建一個字符串池(a pool of string),如果當前準備新創建的字符串對象的值在這個池子中已經存在,那么就不會生成新對象,而是復用池中已有的字符串對象。flyweight 模式的精髓就是對象復用。
重寫發生在子類繼承父類時,子類覆蓋父類的方法時發生,是在運行時發生。
重載是在同一個類中,同一個方法,不同參數時發生,是在編譯期發生。
在Java 5中使用注解@override,來標示方法重寫,如果編譯時發現沒有重寫,則JVM會拋出編譯異常。
4. 迭代和遞歸可重入方法(re-entrant method)是可以安全進入的方法,即使同一個方法正在被執行,深入到同一個線程的調用棧里面也不會影響此次執行的安全性。一個非可重入方法則不是可以安全進入的。例如,加入寫文件或者向文件中寫入日志的方法不是可重入方法時,有可能會毀壞那個文件。
如果一個方法調用了其自身的話,我們稱之為遞歸調用。假定??臻g足夠的話,盡管遞歸調用比較難以調試,在Java語言中實現遞歸調用也是完全可行的。遞歸方法是眾多算法中替代循環的一個不錯選擇。所有的遞歸方法都是可重入的,但是不是所有可重入的方法都是遞歸的。
棧遵守LIFO(Last In First Out)規則,因此遞歸調用方法能夠記住“調用者”并且知道此輪執行結束之返回至當初的被調用位置。遞歸利用系統棧來存儲方法調用的返回地址。 Java是一種基于棧設計的編程語言。
循環的方式可以達到目的,不必采用遞歸。但是在某些情況下采用遞歸方式則代碼會更加簡短易讀。遞歸方法在循環樹結構以及避免丑陋的嵌套循環的情況下是非常好用的。
常規遞歸方法(亦稱,頭遞歸)在上面演示了,這種方式會增加調用棧的大小。每次遞歸,其入口需要被記錄在棧中。方法返回之前需要給countA(input.substring(1)的結果加一個count。因此,最后需要做的事其實是加法運算,而非遞歸本身。
在尾遞歸中,最后要做的是遞歸,加法運算在之前就已經完成了。棧調用減少帶來了內存消耗減少并且程序的性能更好。如下代碼
public class TailRecursiveCall { public int countA(String input) { // exit condition – recursive calls must have an exit condition if (input == null || input.length() == 0) { return 0; } return countA(input, 0) ; } public int countA(String input, int count) { if (input.length() == 0) { return count; } // check first character of the input if (input.substring(0, 1).equals("A")) { count = count + 1; } // recursive call is the last call as the count is cumulative return countA(input.substring(1), count); } public static void main(String[] args) { System.out.println(new TailRecursiveCall().countA("AAA rating")); } }5. 關于ArrayList
ArrayList的大小是如何自動增加的?你能分享一下你的代碼嗎?
使用ensureCapacity, 在進行添加元素時,檢查容量是否足夠,不夠的話,就將容量擴大3/2,并將舊數組中的元素使用Arrays.copyOf拷貝到新數組中。
什么情況下你會使用ArrayList?什么時候你會選擇LinkedList?
ArrayList是在訪問的次數遠大于插入和刪除的次數,使用ArrayList,因為ArrayList底層使用數組,訪問的復雜度為O(1), 但是插入和刪除就得頻繁使用System.arraycopy復制數組。 LinkList主要在訪問次數遠小于插入和刪除的次數時使用,其刪除和插入的復雜度,但訪問元素時幾乎為O(n)。
當傳遞ArrayList到某個方法中,或者某個方法返回ArrayList,什么時候要考慮安全隱患?如何修復安全違規這個問題呢?
當array被當做參數傳遞到某個方法中,如果array在沒有被復制的情況下直接被分配給了成員變量,那么就可能發生這種情況,即當原始的數組被調用的方法改變的時候,傳遞到這個方法中的數組也會改變。
將其副本拷貝出來再進行修改。
如何復制某個ArrayList到另一個ArrayList中去?寫出你的代碼?
使用clone()方法,比如ArrayList newArray = oldArray.clone();
使用ArrayList構造方法,比如:ArrayList myObject = new ArrayList(myTempObject); 使用Collection的copy方法...
注意1和2是淺拷貝(shallow copy),何為淺拷貝?
淺拷貝就比如像引用類型,而深拷貝就比如值類型。淺拷貝是指源對象與拷貝對象共用一份實體,僅僅是引用的變量不同(名稱不同)。對其中任何一個對象的改動都會影響另外一個對象。舉個例子,一個人一開始叫張三,后來改名叫李四了,可是還是同一個人,不管是張三缺胳膊少腿還是李四缺胳膊少腿,都是這個人倒霉。
深拷貝是指源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。舉個例子,一個人名叫張三,后來用他克隆(假設法律允許)了另外一個人,叫李四,不管是張三缺胳膊少腿還是李四缺胳膊少腿都不會影響另外一個人。比較典型的就是Value(值)對象,如預定義類型Int32,Double,以及結構(struct),枚舉(Enum)等。
還可用序列化技術來進行深拷貝,對象實現序列化接口,然后寫入流,并讀出來
// 將對象寫到流里 ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); // 從流里讀出來 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return (oi.readObject());
但是串行化卻很耗時,在一些框架中,我們便可以感受到,它們往往將對象進行串行化后進行傳遞,耗時較多。
在索引中ArrayList的增加或者刪除某個對象的運行過程?效率很低嗎?解釋一下為什么?
頻繁插入和刪除,會頻繁調用System.arrayCopy....效率低
參考地址
-[1] http://www.importnew.com/2228...
-[2] http://www.importnew.com/2223...
-[3] http://www.importnew.com/2217...
-[4] http://www.importnew.com/2329...
-[5] http://www.importnew.com/9928...
-[6] http://www.cnblogs.com/shuaiw...
-[7] http://blog.csdn.net/biaobiao...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64144.html
摘要:網易跨境電商考拉海購在線筆試現場技術面面。如何看待校招面試招聘,對公司而言,是尋找勞動力對員工而言,是尋找未來的同事。 如何準備校招技術面試 標簽 : 面試 [TOC] 2017 年互聯網校招已近尾聲,作為一個非 CS 專業的應屆生,零 ACM 經驗、零期刊論文發表,我通過自己的努力和準備,從找實習到校招一路運氣不錯,面試全部通過,謹以此文記錄我的校招感悟。 寫在前面 寫作動機 ...
摘要:我覺得了解簡歷和面試的技巧可以幫助你更好的去學習重要的知識點以及更好地去準備面試以及面試,說實話,我個人覺得這些東西還挺重要的。在本文里,我將介紹我這段時間里更新簡歷和面試的相關經歷。 分享一篇很不錯的文章!本文作者曾經寫過《Java Web輕量級開發面試教程》和 《Java核心技術及面試指南》這兩本書。我覺得了解簡歷和面試的技巧可以幫助你更好的去學習重要的知識點以及更好地去準備面試以...
摘要:第一個問題阿里面試都問什么這個是讓我最頭疼的一個問題,也是群里的猿友們問的最多的一個問題。我參加的是阿里的社招面試,而社招不同于校招,問題的范圍其實是很隨機的。所以,不妨就這兩個階段,談談社招面試的準備,而不是去把阿里面試的過程背一遍。 引言其實本來真的沒打算寫這篇文章,主要是記憶力不是很好,不像一些記憶力強的人,面試完以后,幾乎能把自己和面試官的對話都給記下來。自己當初面試完以后,除...
摘要:一基礎接口的意義百度規范擴展回調抽象類的意義想不想通過一線互聯網公司面試文檔整理為電子書掘金簡介谷歌求職記我花了八個月準備谷歌面試掘金原文鏈接翻譯者 【面試寶典】從對象深入分析 Java 中實例變量和類變量的區別 - 掘金原創文章,轉載請務必保留原出處為:http://www.54tianzhisheng.cn/... , 歡迎訪問我的站點,閱讀更多有深度的文章。 實例變量 和 類變量...
閱讀 1743·2021-09-22 15:25
閱讀 1307·2019-08-29 12:34
閱讀 1907·2019-08-26 13:57
閱讀 3188·2019-08-26 10:48
閱讀 1443·2019-08-26 10:45
閱讀 792·2019-08-23 18:23
閱讀 733·2019-08-23 18:01
閱讀 1945·2019-08-23 16:07