欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java面試題沖刺第一天--基礎篇1

 更新時間:2021年07月13日 09:38:21   作者:_陳哈哈  
這篇文章主要為大家分享了最有價值的三道java面試題,涵蓋內容全面,包括數(shù)據結構和算法相關的題目、經典面試編程題等,感興趣的小伙伴們可以參考一下

面試題1:Java 中操作字符串都有哪些類?它們之間有什么區(qū)別? 正經回答:

操作字符串的類有:String、StringBufferStringBuilder。

String 和 StringBuffer、StringBuilder 的區(qū)別在于 String 聲明的是不可變的對象,每次操作都會生成新的 String 對象,然后將指針指向新的 String 對象,而 StringBuffer、StringBuilder 可以在原有對象的基礎上進行操作,所以在經常改變字符串內容的情況下最好不要使用 String。

而StringBuffer 和 StringBuilder 最大的區(qū)別在于,StringBuffer 是線程安全的,而 StringBuilder 是非線程安全的,但 StringBuilder 的性能卻高于 StringBuffer,所以在單線程環(huán)境下推薦使用 StringBuilder,多線程環(huán)境下推薦使用 StringBuffer。

String StringBuffer StringBuilder
類是否可變 不可變(Final) 可變 可變
功能介紹 每次對String的操作都會在“常量池”中生成新的String對象 任何對它指向的字符串的操作都不會產生新的對象。每個StringBuffer對象都有一定的緩沖區(qū)容量,字符串大小沒有超過容量時,不會分配新的容量,當字符串大小超過容量時,自動擴容 功能與StringBuffer相同,相比少了同步鎖,執(zhí)行速度更快
線程安全性 線程安全 線程安全 線程不安全
使用場景推薦 單次操作或循環(huán)外操作字符串 多線程操作字符串 單線程操作字符串

深入追問:

追問1:這三者在效率上怎么說?

StringBulider > StringBuffer > String

String <(StringBuffer,StringBuilder)的原因?

  • String:字符串常量
  • StringBuffer:字符串變量(有同步鎖)
  • StringBuilder:字符串變量(無同步鎖)

從上面的名字可以看到,String是"字符串常量",也就是不可改變的對象。源碼如下:

public final class String{}

對于上面這句話的理解你可能會產生這樣一個疑問 ,比如這段代碼:

String str = "唐伯虎";
str = str + "點香煙";
System.out.print(str); // result : "唐伯虎點香煙"

我們明明改變了String型的變量str啊,為什么說是沒有改變呢?我們來看一下這張對String操作時內存變化的圖:

在這里插入圖片描述

我們可以看到,初始String值為"唐伯虎",然后在這個字符串后面加上新的字符串"點香煙",這個過程是需要重新在棧堆內存中開辟內存空間的,最終得到了"唐伯虎點香煙"字符串也相應的需要開辟內存空間,這樣短短的兩個字符串,卻需要開辟三次內存空間,不得不說這是對內存空間的極大浪費,執(zhí)行效率同理。

為了應對經常性操作字符串的場景,Java才提供了其他兩個操作字符串的類 —— StringBuffer、StringBuilder。

他們倆均屬于字符串變量,是可改變的對象,每當我們用它們對字符串做操作時,實際上是在一個對象上操作的,這樣就不會像String一樣創(chuàng)建一些而外的對象進行操作了,速度自然就相對快了。

我們一般在StringBuffer、StringBuild類上的主要操作是 append 和 insert 方法,這些方法允許被重載,以接受任意類型的數(shù)據。每個方法都能有效地將給定的數(shù)據轉換成字符串,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點(index)添加字符。

  1. StringBuilder一個可變的字符序列是JDK1.5新增的。此類提供一個與 StringBuffer 兼容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字符串緩沖區(qū)被單個線程使用的時候(這種情況很普遍)。如果可能,建議優(yōu)先采用S
  2. tringBuilder類,因為在大多數(shù)實現(xiàn)中,它比 StringBuffer 要快。且兩者的方法基本相同。然而在應用程序要求線程安全的情況下,則必須使用 StringBuffer 類。

String 類型和 StringBuffer、 StringBuild類型的主要性能區(qū)別其實在于 String 是不可變的對象(final), 因此在每次對 String 類型進行改變的時候其實都等同于在堆中生成了一個新的 String 對象,然后將指針指向新的 String 對象,這樣不僅效率低下,而且大量浪費有限的內存空間,所以經常改變內容的字符串最好不要用 String 。因為每次生成對象都會對系統(tǒng)性能產生影響,特別是當內存中的無引用對象過多了以后, JVM 的 GC 開始工作,那速度是一定會相當慢的。另外當GC清理速度跟不上new String的速度時,還會導致內存溢出Error,會直接kill掉主程序!報錯如下:

Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

Exception in thread "I/O dispatcher 3797236" java.lang.OutOfMemoryError: GC overhead limit exceeded

追問2:那StringBuffer和StringBuffer線程安全主要差在哪里呢?

StringBuffer和StringBuilder可以算是雙胞胎了,這兩者的方法沒有很大區(qū)別。但在線程安全性方面,StringBuffer允許多線程進行字符操作。這是因為在源代碼中StringBuffer的很多方法都被關鍵字synchronized 修飾了,而StringBuilder沒有。

synchronized的含義:   

每一個類對象都對應一把鎖,當某個線程A調用類對象O中的synchronized方法M時,必須獲得對象O的鎖才能夠執(zhí)行M方法,否則線程A阻塞。一旦線程A開始執(zhí)行M方法,將獨占對象O的鎖。使得其它需要調用O對象的M方法的線程阻塞。只有線程A執(zhí)行完畢,釋放鎖后。那些阻塞線程才有機會重新調用M方法。這就是解決線程同步問題的鎖機制。 >  了解了synchronized的含義以后,大家可能都會有這個感覺。多線程編程中StringBuffer比StringBuilder要安全多了 ,事實確實如此。如果有多個線程需要對同一個字符串緩沖區(qū)進行操作的時候,StringBuffer應該是不二選擇。

注意:是不是String也不安全呢?事實上不存在這個問題,String是不可變的。線程對于堆中指定的一個String對象只能讀取,無法修改。試問:還有什么不安全的呢?

實際應用場景中:

  • 如果不是在循環(huán)體中進行字符串拼接的話,直接使用 String 的 “+” 就好了;
  • 單線程循環(huán)中操作大量字符串數(shù)據 → StringBuilder.append();
  • 多線程循環(huán)中操作大量字符串數(shù)據 → StringBuffer.append();

面試題2:請你說一下Error 和 Exception 區(qū)別是什么?

正經回答:

Error 和 Exception 都是 Throwable 的子類,在Java中只有Throwable類型的實例才可以被拋出或者捕獲,它是異常處理機制的基本類型。

在這里插入圖片描述

  • Exception和Error體現(xiàn)了java平臺設計者對不同異常情況的分類,Exception是程序正常運行中,可以預料的意外情況,可能并且應該被捕獲,進行相應的處理。
  • Error是指正常情況下,不大可能出現(xiàn)的情況,絕大部分的Error都會導致程序處于非正常的、不可恢復的狀態(tài)。既然是非正常情況,不便于也不需要捕獲。常見的比如OutOfMemoryError之類都是Error的子類。
  • Exception又分為可檢查(checked)異常和不可檢查(unchecked)異常??蓹z查異常在源代碼里必須顯式的進行捕獲處理,這是編譯期檢查的一部分。不可檢查時異常是指運行時異常,像NullPointerException、ArrayIndexOutOfBoundsException之類,通常是可以編碼避免的邏輯錯誤,具體根據需要來判斷是否需要捕獲,并不會在編譯期強制要求。

面試題3:== 和 equals 的區(qū)別是什么

正經回答:

  • == : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。(基本數(shù)據類型 == 比較的是值,引用數(shù)據類型 == 比較的是內存地址)
  • equals(): 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:

情況1:類沒有覆蓋 equals() 方法。則通過 equals() 比較該類的兩個對象時,等價于調用了Object類的equals() 方法,也就是通過“==”比較這兩個對象。

// Object類中的equals() 方法
public boolean equals(Object obj) {
    return (this == obj);
}

情況2:類覆蓋了 equals() 方法。一般,我們都會覆蓋 equals() 方法來兩個對象的內容相等;若它們的內容相等,則返回 true (即,認為這兩個對象相等)。

// String類中的equals() 方法,已覆蓋,用于比較內容
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

深入追問:

追問1:如果我們不重寫equals() 方法,會怎么樣?

舉例說明:

重點說明:是否重寫Object類中的equals方法,會對結果造成的影響

public static void main(String[] args) {
    // 字符串比較
    String a = "陳哈哈";
    String b = "陳哈哈";
    if (a == b) {// true  a==b
        System.out.println("a==b");
    }
    if (a.equals(b)) {// true  a.equals(b)
        System.out.println("a.equals(b)");
    }
    // StringBuffer 對象比較,由于StringBuffer沒有重寫Object的equal方法,因此結果出現(xiàn)錯誤
    StringBuffer c = new StringBuffer("陳哈哈");
    StringBuffer d = new StringBuffer("陳哈哈");
    if (c == d) {// false  c != d
        System.out.println("c == d");
    } else {
        System.out.println("c != d");
    }
    if (c.equals(d)) { // false 調用了Object類的equal方法
        System.out.println("StringBuffer equal true");
    }else {
        System.out.println("StringBuffer equal false");
    }
}
  • object的equals方法是比較的對象的內存地址,而String的equals方法比較的是對象的值。
  • 因為String中的equals方法是被重寫過的,而StringBuilder沒有重寫equals方法,從而調用的是Object類的equals方法,也就相當于用了 ==;

追問2:重寫equals的同時,我們需要重寫hashCode()方法么?為什么?

在重寫equals()方法時,也有必要對hashCode()方法進行重寫,尤其是當我們自定義一個類,想把該類的實例存儲在集合中時。  

hashCode方法的常規(guī)約定為:值相同的對象必須有相同的hashCode,也就是equals()結果為相同,那么hashcode也要相同,equals()結果為不相同,那么hashcode也不相同;

當我們使用equals方法比較說明對象相同,但hashCode不同時,就會出現(xiàn)兩個hashcode值,比如在HashMap中,就會認為這是兩個對象,因此會出現(xiàn)矛盾,說明equals方法和hashCode方法應該成對出現(xiàn),當我們對equals方法進行重寫時,也要對hashCode方法進行重寫。

可以通過ide快捷鍵快速生成兩個方法,假設現(xiàn)在有一個學生Student類,其中有 age 和 name 兩個特征。生成代碼如下:

@Override
public boolean equals(Object o){
//首先比較兩個的地址值是否相同,如果相同,那內容也一定相同
	if(this == o) return true;
//如果o為空值或者兩個對象的類型是否相同,如果類型不同或者o為空值則內容一定不同
	if(o == null || getClass() != o.getClass()) return false;
//將object類型的實例強轉為Student類型
  	Student student = (Student)o;
//比較兩個實例的age是否相同
	if(age != student.age) return false;
//在比較name是否相同
	return name != null ? name.equals(student.name ) : student.name == null;
}
@Override
public int hashCode() {
	int result = age;
	result = 31 * result + (name != null ? name.hashCode() : 0);
	return result;
}

總結

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!

相關文章

  • Java緩存框架之Caffeine源碼解析

    Java緩存框架之Caffeine源碼解析

    這篇文章主要介紹了Java緩存框架之Caffeine源碼解析,Caffeine?是一個基于Java?8的高性能本地緩存框架,其結構和?Guava?Cache?基本一樣,api也一樣,基本上很容易就能替換,需要的朋友可以參考下
    2023-11-11
  • Spring依賴注入中的@Resource與@Autowired詳解

    Spring依賴注入中的@Resource與@Autowired詳解

    這篇文章主要介紹了Spring依賴注入中的@Resource與@Autowired詳解,提到Spring依賴注入,大家最先想到應該是@Resource和@Autowired,對于Spring為什么要支持兩個這么類似的注解卻未提到,屬于知其然而不知其所以然,本文就來做詳細講解,需要的朋友可以參考下
    2023-09-09
  • C語言中下標與指針的轉換以及指向指針的指針的例子

    C語言中下標與指針的轉換以及指向指針的指針的例子

    這篇文章主要介紹了C語言中下標與指針的轉換以及指向指針的指針的示例,是C語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-11-11
  • Java實現(xiàn)圖片倒影的源碼實例內容

    Java實現(xiàn)圖片倒影的源碼實例內容

    在本篇文章里小編給大家整理的是關于Java實現(xiàn)圖片倒影的源碼以及相關知識點,有需要的朋友們學習下。
    2019-09-09
  • 這一次搞懂Spring的Bean實例化原理操作

    這一次搞懂Spring的Bean實例化原理操作

    這篇文章主要介紹了這一次搞懂Spring的Bean實例化原理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 深入理解Java中的SPI機制

    深入理解Java中的SPI機制

    這篇文章主要介紹了深入理解Java中的SPI機制,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-02-02
  • SpringBoot中的事務處理問題

    SpringBoot中的事務處理問題

    這篇文章主要介紹了SpringBoot中的事務處理問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java實現(xiàn)輸出文件夾下某個格式的所有文件實例代碼

    java實現(xiàn)輸出文件夾下某個格式的所有文件實例代碼

    這篇文章主要介紹了java實現(xiàn)輸出文件夾下某個格式的所有文件,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • Java使用Zxing二維碼生成的簡單示例

    Java使用Zxing二維碼生成的簡單示例

    ZXing是一個開源的,用Java實現(xiàn)的多種格式的1D/2D條碼圖像處理庫,下面這篇文章主要給大家介紹了關于Java使用Zxing二維碼生成的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • spring cloud gateway轉發(fā)服務報錯的解決

    spring cloud gateway轉發(fā)服務報錯的解決

    這篇文章主要介紹了spring cloud gateway轉發(fā)服務報錯的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論