一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java面試題沖刺第一天--基礎篇1

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

2021-10-07 11:32_陳哈哈 Java教程

這篇文章主要為大家分享了最有價值的三道java面試題,涵蓋內容全面,包括數據結構和算法相關的題目、經典面試編程題等,感興趣的小伙伴們可以參考一下

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

操作字符串的類有:StringStringBufferStringBuilder

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

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

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

 

 

深入追問:

 

追問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操作時內存變化的圖:

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

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

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

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

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

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

String 類型和 StringBuffer、 StringBuild類型的主要性能區別其實在于 String 是不可變的對象(final), 因此在每次對 String 類型進行改變的時候其實都等同于在堆中生成了一個新的 String 對象,然后將指針指向新的 String 對象,這樣不僅效率低下,而且大量浪費有限的內存空間,所以經常改變內容的字符串最好不要用 String 。因為每次生成對象都會對系統性能產生影響,特別是當內存中的無引用對象過多了以后, 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可以算是雙胞胎了,這兩者的方法沒有很大區別。但在線程安全性方面,StringBuffer允許多線程進行字符操作。這是因為在源代碼中StringBuffer的很多方法都被關鍵字synchronized 修飾了,而StringBuilder沒有。

synchronized的含義:   

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

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

實際應用場景中:

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

 

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

 

 

正經回答:

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

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

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

 

面試題3:== 和 equals 的區別是什么

正經回答:

  • == : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。(基本數據類型 == 比較的是值,引用數據類型 == 比較的是內存地址)
  • 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方法,因此結果出現錯誤
    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方法的常規約定為:值相同的對象必須有相同的hashCode,也就是equals()結果為相同,那么hashcode也要相同,equals()結果為不相同,那么hashcode也不相同;

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

可以通過ide快捷鍵快速生成兩個方法,假設現在有一個學生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;
}

 

總結

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

原文鏈接:https://blog.csdn.net/qq_39390545/article/details/117423180

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
主站蜘蛛池模板: 国产成+人+亚洲+欧美综合 | 青青青在线免费 | 亚洲天堂激情 | 公妇乱淫 | 亚洲成色 | 久见久热 这里只有精品 | 四虎国产精品免费久久麻豆 | 天天做天天爱天天爽综合网 | 国产精品99精品久久免费 | 亚洲一卡2卡三卡4卡5卡组 | 亚洲AV国产国产久青草 | 黑人干亚洲人 | 免费看男女做好爽好硬视频 | 欧美性理论片在线观看片免费 | 国产久视频| 色哟哟哟在线精品观看视频 | 午夜片神马影院福利 | 欧美高清videosex极品 | 国产手机在线αⅴ片无码观看 | 免费一级毛片在线播放放视频 | 506070老熟肥妇bbwxx视频 500第一精品 | uoco福利姬网站 | 三叶草私人研究所 | 亚洲精品一区二区三区在线看 | 茄子视频懂你更多apl | 日本伦理动漫在线观看 | 5g影院天天爽爽 | 精品亚洲国产一区二区 | 国产在视频线在精品 | 日本ccc三级 | tobu8中国在线观看免费视频 | 男人操女人视频 | 精品日韩欧美一区二区三区在线播放 | 欧美日韩精品在线视频 | 91美女在线 | 国产成人h视频在线播放网站 | 国产一区二区在线免费观看 | 精品国产福利一区二区在线 | 农夫69小说小雨与农村老太 | 非洲黑女人性xxxx | 日韩激情视频在线观看 |