Java崗大廠面試百日沖刺【Day53】— 基礎篇4 (日積月累,每日三題)

      網友投稿 670 2025-04-04

      大家好,我是陳哈哈,虎年第一篇,祝虎年大吉,拿個高薪!相信大家和我一樣,都有一個大廠夢,作為一名資深Java選手,深知面試重要性,接下來我準備用100天時間,基于Java崗面試中的高頻面試題,以每日3題的形式,帶你過一遍熱門面試題及恰如其分的解答。

      一路走來,隨著問題加深,發現不會的也愈來愈多。但底氣著實足了不少,相信不少朋友和我一樣,日積月累才是最有效的學習方式!想起高三時一個同學的座右銘:只有沉下去,才能浮上來。共勉(juan)。

      2022年的第一場雪,比以往來得更早一些~

      讓我想到2002年聽到刀郎的那首歌,還記得那時剛上小學,是我買的第一張磁帶。歲月如梭啊。已過二十載!

      車票

      面試題1:String str與new String與有什么區別?

      面試題2:為什么 String 在 Java 中是不可變(final)的?

      面試題3:為什么說 char[] 比 Java 中的 String 更適合存儲密碼?

      每日小結

      本欄目Java開發崗高頻面試題主要出自以下各技術棧:Java基礎知識、集合容器、并發編程、JVM、Spring全家桶、MyBatis等ORMapping框架、MySql數據庫、Redis緩存、RabbitMQ消息隊列、Linux操作技巧等。

      面試題1:String str與new String與有什么區別?

      要說明這兩種字符創創建方式的區別,首先要理解什么是常量池,常量池(constant pool)指的是在編譯期被確定,并被保存在已編譯的.class文件中的一些數據。它包括了關于類、方法、接口等中的常量,也包括字符串常量。

      在常量池中存儲字符串常量的內存空間,即字符串常量池,當需要使用字符串時,先去字符串池中查看該字符串是否已經存在,如果存在,則可以直接使用,如果不存在,初始化,并將該字符串放入字符串常量池中。

      常量池的位置

      JDK1.7以前,常量池(包含字符串常量池)位于方法區

      JDK1.7及以后,字符串常量池移入堆

      常量池的作用

      節省內存空間:所有常量池中相同的常量具有同樣的內存地址

      加快運行速率

      1、String直接賦值(String str = “abc”;):

      創建一個或不創建對象。如果“abc”在字符串池中不存在,會在java字符串池中創建一個String對象(“abc”),然后str指向這個內存地址,無論以后用這種方式創建多少個值為“abc”的字符串對象,始終只有一個內存地址被分配;如果“abc” 在字符串池中存在, str直接指向這個內存地址。

      String str1 = "abc"; String str2 = "abc"; String str3 = "abc"; System.out.println(str1 == str2); // true System.out.println(str1 == str3); // true

      1

      2

      3

      4

      5

      2、使用new String創建字符串(String str = new String(“abc”);):

      創建一個或兩個對象。因為用到new關鍵字,肯定會在堆中創建一個String對象,如果字符池中已經存在”abc”,則不會在字符串池中創建一個String對象,如果不存在,則會在字符串常量池中也創建一個對象。

      String str1 = new String("abc"); String str2 = new String("abc"); String str3 = new String("abc"); System.out.println(str1 == str2);//false System.out.println(str1 == str3);//false

      1

      2

      3

      4

      5

      3、String拼接字符串:

      除了直接使用等號賦值,有時也會用到字符串拼接,字符串拼接又分為變量拼接和已知字符串拼接。

      只要拼接內容存在變量,那么該拼接后的新變量就是在堆內存中新建的一個對象實體。

      String str = "abc"; String str1 = "abcd"; String str2 = str+"d"; // 拼接字符串,此時會在堆中新建一個abcd的對象,因為str2編譯之前是未知的 String str3 = "abc"+"d"; // 拼接之后str3還是abcd,所以還是會指向字符串常量池的內存地址 System.out.println(str1==str2); // false System.out.println(str1==str3); // true

      1

      2

      3

      4

      5

      6

      概括為以下幾點:

      針對 String str="abc" 和 String str=new String("abc"); 產生的對象,前者1或0,后者2或1,先看字符串常量池,如果字符串常量池中沒有,都在常量池中創建一個,如果有,前者直接引用,后者在堆內存中還需創建一個“abc”實例對象。

      對于基礎類型的變量和常量:變量和引用存儲在棧中,常量存儲在常量池中。

      為了提升jvm(JAVA虛擬機)性能和減少內存開銷,避免字符的重復創建 項目中還是不要使用new String去創建字符串,最好使用String直接賦值。

      關于equals()和 “= =” 對于String類簡單來說,equals()就是比較兩字符串的內容是否相等,如果相等返回true;而 “= =” 是比較兩字符串的地址是否相同,也就是是否是同一個字符串的引用,如果是返回true。

      課間休息,又來秀一下來自咱們群里同學的老家,巍巍大別山區,劉鄧大軍根據地。坐標:安徽 太湖。

      面試題2:為什么 String 在 Java 中是不可變(final)的?

      我們先來看一下String類在源碼中的成員變量;在JDK1.7中,String類的主要成員變量主要為以下兩個:

      public final class String implements java.io.Serializable, Comparable, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0

      1

      2

      3

      4

      5

      6

      7

      由以上的代碼可以看出, 在 Java 中,String 類其實就是對字符數組char []的封裝。在JDK7中,只有一個 value 變量,也就是 value 中的所有字符都是屬于 String 這個對象的。除此之外還有一個 hash 成員變量,是該 String 對象的哈希值的緩存,這個成員變量也和本文的討論無關。在Java中,數組也是對象。 所以 value 也只是一個引用,它指向一個真正的數組對象。其實執行了String s = “ABCabc”; 這句代碼之后,真正的內存布局應該是這樣的:

      字符串在 Java 中是不可變的,因為 String 對象緩存在字符串常量池中。由于緩存的字符串在多個客戶之間共享,因此始終存在風險,其中一個客戶的操作會影響所有其他客戶。例如,如果一段代碼將 String “Test” 的值更改為 “TEST”,則所有其他客戶也將看到該值。由于 String 對象的緩存性能是很重要的一方面,因此通過使 String 類不可變來避免這種風險。

      同時,String 是 final 的,因此沒有人可以通過擴展和覆蓋行為來破壞 String 類的不變性、緩存、散列值的計算等。

      String 類不可變的另一個原因可能是由于 HashMap,由于把字符串作為 HashMap 鍵很受歡迎。對于鍵值來說,重要的是它們是不可變的,以便用它們檢索存儲在 HashMap 中的值對象。

      由于 HashMap 的工作原理是散列,因此需要具有相同的值才能正常運行。如果在插入后修改了 String 的內容,可變的 String將在插入和檢索時生成兩個不同的哈希碼,可能會丟失 Map 中的值對象。

      String 作為數據類型,傳輸對象和中間人角色的重要性和流行性也使這個問題在 Java 面試中很常見。

      為什么 String 在 Java 中是不可變的是 Java 中最常被問到的字符串訪問問題之一,它首先討論了什么是 String,Java 中的 String 如何與 C 和 C++ 中的 String 不同,然后轉向在Java中什么是不可變對象,不可變對象有什么好處,為什么要使用它們以及應該使用哪些場景。

      這個問題有時也會問:“為什么 String 在 Java 中是 final 的”。我認為以下幾點解釋了為什么 String 類在 Java 中是不可變的或 final 的:

      1、想象字符串池沒有使字符串不可變的話,是站不住腳的,因為在字符串池的情況下,一個字符串對象/文字,例如 “Test” 已被許多參考變量引用,因此如果其中任何一個更改了值,其他參數將自動受到影響,如下:

      String A="Test"; String B="Test";

      1

      2

      現在字符串 B 調用 “Test”.toUpperCase, 將同一個對象改為“TEST”,所以 A 也是 “TEST”,這肯定是不行的。

      2、字符串已被廣泛用作許多 Java 類的參數,例如,為了打開網絡連接,你可以將主機名和端口號作為字符串傳遞,你可以將數據庫 URL 作為字符串傳遞, 以打開數據庫連接,你可以通過將文件名作為參數傳遞給 File I/O 類來打開 Java 中的任何文件。如果 String 不是不可變的,這將導致嚴重的安全威脅,我的意思是有人可以訪問他有權授權的任何文件,然后可以故意或意外地更改文件名并獲得對該文件的訪問權限。由于不變性,你無需擔心這種威脅。這個原因也說明了,為什么 String 在 Java 中是最終的,通過使 java.lang.String final,Java設計者確保沒有人覆蓋 String 類的任何行為。

      3、由于 String 是不可變的,它可以安全地共享許多線程,這對于多線程編程非常重要,并且避免了 Java 中的同步問題,不變性也使得String 實例在 Java 中是線程安全的,這意味著你不需要從外部同步 String 操作。關于 String 的另一個要點是由截取字符串 SubString 引起的內存泄漏,這不是與線程相關的問題,但也是需要注意的。

      4、為什么 String 在 Java 中是不可變的另一個原因是允許 String 緩存其哈希碼,Java 中的不可變 String 緩存其哈希碼,并且不會在每次調用 String 的 hashcode 方法時重新計算,這使得它在 Java 中的 HashMap 中使用的 HashMap 鍵非常快。簡而言之,因為 String 是不可變的,所以沒有人可以在創建后更改其內容,這保證了 String 的 hashCode 在多次調用時是相同的。

      5、String 不可變的絕對最重要的原因是它被類加載機制使用,因此具有深刻和基本的安全考慮。如果 String 是可變的,加載“java.io.Writer” 的請求可能已被更改為加載 “mil.vogoon.DiskErasingWriter”. 安全性和字符串池是使字符串不可變的主要原因。

      國足新年大禮,15分鐘0:2越南,舒服了!

      面試題3:為什么說 char[] 比 Java 中的 String 更適合存儲密碼?

      這個問題也可以定義為封裝Char[]的String類相比Char數組,對密碼存儲會有哪些不同?,這是最近在 Java 面試中向我的一位朋友詢問的問題。任何與 String 相關的問題都必須對字符串的特殊屬性有一些線索,比如不變性。在這里,我們將探討為什么你應該使用char[]存儲密碼而不是String的一些原因。

      1、由于字符串在 Java 中是不可變的,如果你將密碼存儲為純文本,它將在內存中可用,直到垃圾收集器清除它. 并且為了可重用性,會存在 String 在字符串池中, 它很可能會保留在內存中持續很長時間,從而構成安全威脅。

      由于任何有權訪問內存轉儲的人都可以以明文形式找到密碼,這是另一個原因,你應該始終使用加密密碼而不是純文本。由于字符串是不可變的,所以不能更改字符串的內容,因為任何更改都會產生新的字符串,而如果你使用char[],你就可以將所有元素設置為空白或零。因此,在字符數組中存儲密碼可以明顯降低竊取密碼的安全風險。

      2、Java 本身建議使用 JPasswordField 的 getPassword 方法,該方法返回一個 char[] 和不推薦使用的getTex()方法,該方法以明文形式返回密碼,由于安全原因。應遵循 Java 團隊的建議, 堅持標準而不是反對它。

      3、使用 String 時,總是存在在日志文件或控制臺中打印純文本的風險,但如果使用 Array,則不會打印數組的內容而是打印其內存位置。雖然不是一個真正的原因,但仍然有道理。

      String strPassword =“Unknown”; char [] charPassword = new char [] {'U','n','k','w','o','n'}; System.out.println(“字符密碼:”+ strPassword); System.out.println(“字符密碼:”+ charPassword);

      1

      2

      3

      輸出:

      字符串密碼:Unknown 字符密碼:[C @110b053

      1

      2

      我還建議使用散列或加密的密碼而不是純文本,并在驗證完成后立即從內存中清除它。因此,在Java中,用字符數組用存儲密碼比字符串是更好的選擇。雖然僅使用char[]還不夠,還你需要擦除內容才能更安全。

      Java崗大廠面試百日沖刺【Day53】— 基礎篇4 (日積月累,每日三題)

      每日小結

      今天我們復習了Java基礎知識中??嫉膬蓚€老油條問題,你做到心中有數了么?對了,如果你的朋友也在準備面試,請將這個系列扔給他,如果他認真對待,肯定會感謝你的!!好了,今天就到這里,學廢了的同學,記得在評論區留言:打卡。,給同學們以激勵。

      參考資料

      https://v3.processon.com/view/5ef1a2917d9c0844202f7746

      https://blog.csdn.net/qq_45737068/article/details/107149922

      https://www.cnblogs.com/weirdo-lenovo/p/11418871.html

      HashMap Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel怎么使用vba快速重命名未打開的文件?
      下一篇:如何在XLS表格中直接得到函數公式
      相關文章
      亚洲午夜福利在线视频| 亚洲理论在线观看| 亚洲精品偷拍无码不卡av| 情人伊人久久综合亚洲| 国产亚洲精品美女| 成人亚洲网站www在线观看| 亚洲精品av无码喷奶水糖心 | 亚洲综合激情另类小说区| 亚洲AV日韩AV永久无码绿巨人| 亚洲日韩精品射精日| 相泽亚洲一区中文字幕| 国产精品亚洲玖玖玖在线观看 | 国产亚洲精品美女久久久| 亚洲无人区一区二区三区| 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲精品人成网线在线播放va| 久久久久亚洲Av无码专| 亚洲国产综合专区电影在线| 亚洲国产精品一区二区久久hs | 亚洲一级高清在线中文字幕| 亚洲午夜久久久精品电影院| 亚洲免费一级视频| 亚洲精品国产精品国自产网站 | 久久亚洲2019中文字幕| 亚洲中文字幕无码永久在线| 亚洲无线码一区二区三区| 久久精品国产96精品亚洲| 亚洲激情在线视频| 亚洲精品在线播放| 亚洲一卡2卡4卡5卡6卡在线99| 亚洲国产熟亚洲女视频| 亚洲欧美国产精品专区久久| 最新亚洲精品国偷自产在线| 亚洲人成色77777在线观看| 亚洲AV无码国产一区二区三区| 亚洲人AV永久一区二区三区久久| 国外亚洲成AV人片在线观看| 国产亚洲精品资源在线26u| 亚洲成AV人片在线观看| 久久亚洲精品中文字幕| 亚洲娇小性色xxxx|