激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

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

Java面試題沖刺第一天--基礎(chǔ)篇1

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

這篇文章主要為大家分享了最有價值的三道java面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下

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

操作字符串的類有:StringStringBufferStringBuilder

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

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

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

 

 

深入追問:

 

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

StringBulider > StringBuffer > String

String <(StringBuffer,StringBuilder)的原因?

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

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

public final class String{}

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

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

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

Java面試題沖刺第一天--基礎(chǔ)篇1

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

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

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

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

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

String 類型和 StringBuffer、 StringBuild類型的主要性能區(qū)別其實在于 String 是不可變的對象(final), 因此在每次對 String 類型進行改變的時候其實都等同于在堆中生成了一個新的 String 對象,然后將指針指向新的 String 對象,這樣不僅效率低下,而且大量浪費有限的內(nèi)存空間,所以經(jīng)常改變內(nèi)容的字符串最好不要用 String 。因為每次生成對象都會對系統(tǒng)性能產(chǎn)生影響,特別是當(dāng)內(nèi)存中的無引用對象過多了以后, JVM 的 GC 開始工作,那速度是一定會相當(dāng)慢的。另外當(dāng)GC清理速度跟不上new String的速度時,還會導(dǎo)致內(nèi)存溢出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的很多方法都被關(guān)鍵字synchronized 修飾了,而StringBuilder沒有。

synchronized的含義:   

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

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

實際應(yīng)用場景中:

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

 

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

 

 

正經(jīng)回答:

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

Java面試題沖刺第一天--基礎(chǔ)篇1

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

 

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

正經(jīng)回答:

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

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

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

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

// String類中的equals() 方法,已覆蓋,用于比較內(nèi)容
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方法,會對結(jié)果造成的影響

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方法,因此結(jié)果出現(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 調(diào)用了Object類的equal方法
        System.out.println("StringBuffer equal true");
    }else {
        System.out.println("StringBuffer equal false");
    }
}
  • object的equals方法是比較的對象的內(nèi)存地址,而String的equals方法比較的是對象的值。
  • 因為String中的equals方法是被重寫過的,而StringBuilder沒有重寫equals方法,從而調(diào)用的是Object類的equals方法,也就相當(dāng)于用了 ==;

 

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

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

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

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

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

@Override
public boolean equals(Object o){
//首先比較兩個的地址值是否相同,如果相同,那內(nèi)容也一定相同
	if(this == o) return true;
//如果o為空值或者兩個對象的類型是否相同,如果類型不同或者o為空值則內(nèi)容一定不同
	if(o == null || getClass() != o.getClass()) return false;
//將object類型的實例強轉(zhuǎn)為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;
}

 

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!

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

延伸 · 閱讀

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

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

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

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

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

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

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

    Java使用SAX解析xml的示例

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

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

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

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

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

    小米推送Java代碼

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

    富貴穩(wěn)中求8032021-07-12
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

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

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉(zhuǎn)換詳解

    xml與Java對象的轉(zhuǎn)換詳解

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

    Java教程網(wǎng)2942020-09-17
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

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

    littleschemer13532021-05-16
主站蜘蛛池模板: 久久精品视频在线看99 | 久久免费激情视频 | 国产91一区二区三区 | 羞羞视频免费观看网站 | 成人免费看视频 | 久久精品亚洲欧美日韩精品中文字幕 | 91看片www| 亚洲精品一区二区三区在线看 | 91短视频版高清在线观看www | 在线观看第一区 | 亚洲影院久久久av天天蜜桃臀 | 爽妇网国产精品 | 欧美a黄 | 精品亚洲免费 | 91av资源在线 | 国产1区2 | 精品国产一区二区久久 | 好吊色欧美一区二区三区四区 | 88xx成人永久免费观看 | 精品国产高清一区二区三区 | 性高跟鞋xxxxhd4kvideos | 亚洲人成网站在e线播放 | 91重口视频 | 日本欧美一区二区三区视频麻豆 | 亚洲欧美日韩一区二区三区在线观看 | 久久久久中精品中文字幕19 | 日本免费一区二区三区四区 | 噜噜噜躁狠狠躁狠狠精品视频 | 精品一区二区久久久久久久网精 | 免费久久精品 | 92看片淫黄大片一级 | 欧美精品久久久久久久久久 | wankzhd| 九草在线| 亚洲午夜激情网 | 色综合一区二区 | 伦理三区| 久久精品日产第一区二区三区 | 人人玩人人爽 | 黄色片网站在线看 | 久久精品无码一区二区三区 |