面試踩過的坑

1、?“==”和equals 的區別

  • “==”是運算符,如果是基本數據類型,則比較存儲的值;如果是引用數據類型,則比較所指向對象的地址值
  • equals是Object的方法,比較的是所指向的對象的地址值,一般情況下,重寫之后比較的是對象的值

ps:問的是:int a = 3;if(a==3){},比較的是值還是內存地址。這個忘了,想到另一個概念整數常量池,是自己想多了,和整數常量池的問題記混了,看到a==3,就想著3不會在內存中新建。傻了,這里再說下在方法中int a = 3。a和3(基本類型)都是保存在棧中的,引用類型對象才會在棧中存堆的內存地址。所以==比較基本類型時只能比較值,沒有什么內存地址給你比較。

下面代碼

Integer a = 3;//自動裝箱:等價于 Integer.valueOf(3)
System.out.println(a==3);
Integer b = new Integer(4);
System.out.println(b==4);

結果是true ,true,雖然Integer是個整數對象,不是基本類型,按理說要比較內存地址,這里應該比較內存了,但是Integer和int一起運算時會拆包成基本類型,所以比的還是值。

Integer p = new Integer(5);
Integer q = new Integer(5);
System.out.println(p == q);  // 輸出 false(顯式創建新對象)

這里比較的都是引用類型,比較就是內存地址了。?

2、整數常量池

Integer  i = 123;
Integer  i2 = 123;
System.out.println(i==i2);Integer  i3 = 129;
Integer  i4 = 129;
System.out.println(i3==i4);

輸出結果:

true
false

解釋如下:

整數常量池的作用場景

  1. 自動裝箱(Autoboxing)

    • 當將基本類型?int?轉換為包裝類?Integer?時(比如賦值給?Integer?變量,或存入集合類),Java 會嘗試復用常量池中已緩存的?Integer?對象,而不是每次都創建新對象。

    • 例如:

      Integer a = 100; // 自動裝箱,使用常量池中的對象 Integer b = 100; System.out.println(a == b); // 輸出 true(同一對象)

  2. 手動創建?Integer?對象

    • 如果直接通過?new Integer()?創建對象,會強制生成新實例,繞過常量池:

      Integer c = new Integer(100); Integer d = new Integer(100); System.out.println(c == d); // 輸出 false(不同對象)
      
  3. 超出緩存范圍的情況

  4. 當數值超出?-128~127?范圍時,即使通過自動裝箱,也會生成新對象:

    Integer e = 200;

    Integer f = 200;

    System.out.println(e == f); // 輸出 false(超出緩存范圍)

?整數常量池的實現原理

Java 在?Integer?類中通過靜態內部類?IntegerCache?實現緩存

private static class IntegerCache {
? ? static final int low = -128;
? ? static final int high; // 默認 127,可通過 JVM 參數調整
? ? static final Integer[] cache;
? ??
? ? static {
? ? ? ? // 初始化緩存數組
? ? ? ? high = 127;
? ? ? ? cache = new Integer[(high - low) + 1];
? ? ? ? for (int i = 0; i < cache.length; i++) {
? ? ? ? ? ? cache[i] = new Integer(i - 128);
? ? ? ? }
? ? }
}

通過?Integer.valueOf(int)?方法獲取?Integer?對象時,會優先從緩存中取:

public static Integer valueOf(int i) {
? ? if (i >= IntegerCache.low && i <= IntegerCache.high)
? ? ? ? return IntegerCache.cache[i + 128];
? ? return new Integer(i);
}

3 整數塞入map后怎么存放值的

Stdent zzw = new Stdent("zzw", 15);
Map<String ,Object> map = new HashMap<>();
map.put("stu", zzw);
Integer i =new Integer(22);
map.put("size",i);
System.out.println(map);
i =new Integer(33);
zzw.age =20;
System.out.println(map);
static class Stdent{public String name ;public int age ;public Stdent(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Stdent{" +"name='" + name + '\'' +", age=" + age +'}';}
}

結果:

{size=22, stu=Stdent{name='zzw', age=15}}
{size=22, stu=Stdent{name='zzw', age=20}}

這里為什么age變了,size沒有變?

標下每個變量在內存中怎么存的

關鍵解釋

  1. 對象存儲位置

    • new Stdent("zzw", 15)?和?new Integer(22)?是對象實例,存儲在堆中。

    • 它們的地址分別是?0x100?和?0x200(假設的內存地址)。

  2. 引用變量存儲位置

    • zzw?和?i?是引用變量,存儲在棧中。

    • 它們的值是堆中對象的地址(如?zzw = 0x100)。

  3. put?操作存儲的內容

    • map.put("stu", zzw)?和?map.put("size", i)?存入的是?堆中對象的地址(即?0x100?和?0x200),而不是變量?zzw?或?i?的棧地址。

    • Map?的鍵值對中存儲的是實際對象的引用。

然后后面改變值的時候,zzw.age =20 ,只是改變stu對象里的值,map的引用并不變,就是stu存的還是student對象在堆中的內存地址,所以后面打印的會變。那為什么map中的size的輸出不變呢。因為Intger對象是final修飾的,這個對象不可以修改,i =new Integer(33);后面半句會在堆中建一個新的內存地址,然后前半句把i在棧中存的內存地址換成這個新的,但是map里存的還是之前對象的地址。所以不會輸出不會變。

4、map的操作都是深拷貝還是淺拷貝?

上個例子其實可以看出來,zzw.age=20,然后map里的stu里的age也跟著變了,所以map的put方法是個淺拷貝,問了下deepseek告訴我map的操作幾乎都是淺拷貝,那我想putall也是了?

Stdent zzw = new Stdent("zzw", 15);
Map<String ,Object> map = new HashMap<>();
map.put("stu", zzw);
map.put("size",22);
Map<String ,Object> map2 = new HashMap<>();
map2.putAll(map);
map.clear();
System.out.println(map);
System.out.println(map2);

結果是

{}
{size=22, stu=Stdent{name='zzw', age=15}}?

?deepseek給的解釋

3.?map2.putAll(map)

ok,所以clear只是清除map在堆中的信息,切斷了這個map和stu和整數對象的引用。

但是map2還是沒有變,不是說淺拷貝,map2和map就指向同一個內存地址.

Stdent zzw = new Stdent("zzw", 15);
Map<String ,Object> map = new HashMap<>();
map.put("stu", zzw);
map.put("size",22);
Map<String ,Object> map2 = map;
map.clear();
System.out.println(map);
System.out.println(map2);

結果:

{}
{}

再看一個

Stdent zzw = new Stdent("zzw", 15);
Map<String ,Object> map = new HashMap<>();
map.put("stu", zzw);
map.put("size",22);
Map<String ,Object> map2 = new HashMap<>();
map2.putAll(map);
Stdent zzw2 = new Stdent("zzw2", 30);
map.put("stu", zzw2);
map.put("size", 32);
System.out.println(map);
System.out.println(map2);

?結果:

{size=32, stu=Stdent{name='zzw2', age=30}}
{size=22, stu=Stdent{name='zzw', age=15}}

所以結論就是

Map<String ,Object> map2 = new HashMap<>();
map2.putAll(map);

這里有個2個關鍵點,1:這里我new了一個map,在堆中新建了內存地址,和之前map不是同一個了,但是2:map里面的對象沒有重新new一個新的,還是復用,只是大家(map和map2)都指向這些對象的內存地址。

然后clear只是清空這個map在堆中的內容,他存的對象不回清理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78436.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78436.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78436.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

專業軟件開發全流程實踐指南

作為一家擁有十余年行業積淀的專業軟件開發服務提供商&#xff0c;我們見證了太多項目從無到有的全過程。今天&#xff0c;我們就用最樸實的語言&#xff0c;跟大家聊聊一個軟件產品從構思到上線的完整歷程。這些經驗不僅適用于自建技術團隊的企業&#xff0c;對正在尋找軟件外…

聊透多線程編程-線程互斥與同步-12. C# Monitor類實現線程互斥

目錄 一、什么是臨界區&#xff1f; 二、Monitor類的用途 三、Monitor的基本用法 四、Monitor的工作原理 五、使用示例1-保護共享變量 解釋&#xff1a; 六、使用示例2-線程間信號傳遞 解釋&#xff1a; 七、注意事項 八、總結 在多線程編程中&#xff0c;線程之間的…

第R4周:LSTM-火災溫度預測

文章目錄 一、前期準備工作1.導入數據2. 數據集可視化 二、構建數據集1. 數據集預處理2. 設置X, y3. 劃分數據集 三、模型訓練1. 構建模型2. 定義訓練函數3. 定義測試函數4. 正式訓練模型 四、模型評估1. Loss圖片2. 調用模型進行預測3. R2值評估 總結&#xff1a; &#x1f36…

toCharArray作用

toCharArray() 是 Java 中 String 類的一個方法&#xff0c;其作用是將字符串對象轉換為一個字符數組。下面為你詳細介紹其用法、原理和示例。 方法定義 toCharArray() 方法在 java.lang.String 類里被定義&#xff0c;方法簽名如下 public char[] toCharArray() 此方法沒有…

STM32八股【6】-----CortexM3的雙堆棧(MSP、PSP)設計

STM32的線程模式&#xff08;Thread Mode&#xff09;和內核模式&#xff08;Handler Mode&#xff09;以及其對應的權級和堆棧指針 線程模式&#xff1a; 正常代碼執行時的模式&#xff08;如 main 函數、FreeRTOS任務&#xff09; 可以是特權級&#xff08;使用MSP&#xff…

驅動支持的最高CUDA版本與實際安裝的Runtime版本

查看電腦上安裝的CUDA版本的多種方法&#xff0c;適用于不同系統和場景。 方法一&#xff1a;通過命令行工具 1. 查看CUDA Driver API版本&#xff08;顯卡驅動支持的CUDA版本&#xff09; 命令&#xff1a;nvidia-smi操作&#xff1a; 打開終端&#xff08;Windows為CMD/Pow…

Python CT圖像預處理——基于ITK-SNAP

Python CT圖像預處理——nii格式讀取、重采樣、窗寬窗位設置_python讀取nii-CSDN博客 基于原文指出以下幾個問題&#xff1a;文件路徑設置模糊&#xff1b;nilabel里面使用的get_data() 方法已經過時&#xff1b;需要導入scikit-image&#xff0c;還要導入一個matplotlib。 一…

【MQ篇】RabbitMQ之消息持久化!

目錄 一、 交換機持久化 (Exchange Persistence)二、 隊列持久化 (Queue Persistence)三、 消息持久化 (Message Persistence)四、 持久化的“黃金三角” &#x1f531;&#xff1a;三者缺一不可&#xff01;五、 來&#xff0c;完整的代碼示例&#xff08;整合持久化和確認機制…

[AI技術(二)]JSONRPC協議MCPRAGAgent

Agent概述(一) AI技術基礎(一) JSON-RPC 2.0 協議詳解 JSON-RPC 2.0 是一種基于 JSON 的輕量級遠程過程調用(RPC)協議,旨在簡化跨語言、跨平臺的遠程通信。以下從協議特性、核心結構、錯誤處理、批量請求等角度進行詳細解析: 一、協議概述 1. 設計原則 ? 簡單性:…

LeetCode238_除自身以外數組的乘積

LeetCode238_除自身以外數組的乘積 標簽&#xff1a;#數組 #前綴和Ⅰ. 題目Ⅱ. 示例0. 個人方法一&#xff1a;暴力循環嵌套0. 個人方法二&#xff1a;前綴和后綴分別求積 標簽&#xff1a;#數組 #前綴和 Ⅰ. 題目 給你一個整數數組 nums&#xff0c;返回 數組 answer &#…

算法筆記.spfa算法(bellman-ford算法的改進)

題目&#xff1a;&#xff08;來源于AcWing&#xff09; 給定一個 n 個點 m 條邊的有向圖&#xff0c;圖中可能存在重邊和自環&#xff0c; 邊權可能為負數。 請你求出 1 號點到 n 號點的最短距離&#xff0c;如果無法從 1 號點走到 n 號點&#xff0c;則輸出 impossible。 …

07 Python 字符串全解析

文章目錄 一. 字符串的定義二. 字符串的基本用法1. 訪問字符串中的字符2. 字符串切片3. 字符串拼接4. 字符串重復5.字符串比較6.字符串成員運算 三. 字符串的常用方法1. len() 函數2. upper() 和 lower() 方法3. strip() 方法4. replace() 方法5. split() 方法 四. 字符串的進階…

Java集成Zxing和OpenCV實現二維碼生成與識別工具類

Java集成Zxing和OpenCV實現二維碼生成與識別工具類 本文將介紹如何使用Java集成Zxing和OpenCV庫&#xff0c;實現二維碼的生成和識別功能。識別方法支持多種輸入形式&#xff0c;包括File對象、文件路徑和Base64編碼。 一、環境準備 添加Maven依賴 <dependencies><…

【專題刷題】二分查找(二)

&#x1f4dd;前言說明&#xff1a; 本專欄主要記錄本人的基礎算法學習以及LeetCode刷題記錄&#xff0c;按專題劃分每題主要記錄&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代碼&#xff1b;&#xff08;2&#xff09;優質解法 優質代碼&#xff1b;&#xff…

Java—ThreadLocal底層實現原理

首先&#xff0c;ThreadLocal 本身并不提供存儲數據的功能&#xff0c;當我們操作 ThreadLocal 的時候&#xff0c;實際上操作線程對象的一個名為 threadLocals 成員變量。這個成員變量的類型是 ThreadLocal 的一個內部類 ThreadLocalMap&#xff0c;它是真正用來存儲數據的容器…

Elasticsearch(ES)中的腳本(Script)

文章目錄 一. 腳本是什么&#xff1f;1. lang&#xff08;腳本語言&#xff09;2. source&#xff08;腳本代碼&#xff09;3. params&#xff08;參數&#xff09;4. id&#xff08;存儲腳本的標識符&#xff09;5. stored&#xff08;是否為存儲腳本&#xff09;6. script 的…

客戶聯絡中心能力與客戶匹配方式

在數字化時代&#xff0c;客戶聯絡中心作為企業與客戶溝通的核心樞紐&#xff0c;其服務能力與客戶需求的精準匹配至關重要。隨著客戶期望的不斷提升&#xff0c;傳統的“一刀切”服務模式已難以滿足個性化需求&#xff0c;如何通過智能化的手段實現服務能力與客戶的高效匹配&a…

深入理解網絡原理:UDP協議詳解

在計算機網絡中&#xff0c;數據的傳輸是通過各種協議實現的&#xff0c;其中用戶數據報協議&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;作為一種重要的傳輸層協議&#xff0c;廣泛應用于實時通信、視頻流、在線游戲等場景。本文將深入探討UDP協議的特性、…

vscode切換Python環境

跑深度學習項目通常需要切換python環境&#xff0c;下面介紹如何在vscode切換python環境&#xff1a; 1.點擊vscode界面左上角 2.在彈出框選擇對應kernel

【MCP Node.js SDK 全棧進階指南】中級篇(4):MCP錯誤處理與日志系統

前言 隨著MCP應用的規模和復雜性增長,錯誤處理與日志系統的重要性也日益凸顯。一個健壯的錯誤處理策略和高效的日志系統不僅可以幫助開發者快速定位和解決問題,還能提高應用的可靠性和可維護性。本文作為中級篇的第四篇,將深入探討MCP TypeScript-SDK中的錯誤處理與日志系統…