成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 面試題 [1]

AWang / 2532人閱讀

摘要:對(duì)于方法,用戶一般不會(huì)去調(diào)用,相當(dāng)于根據(jù)一定的規(guī)則將與對(duì)象相關(guān)的信息映射為一個(gè)數(shù)值,稱為散列值。一般在在覆蓋方法的同時(shí)也要覆蓋方法,否則將會(huì)違反的通用約定,從而導(dǎo)致該類無(wú)法與所有基于散列值的集合類結(jié)合在一起正常工作。

1. Java中如何比較兩個(gè)Long對(duì)象是否相等?

如果Long的值在[-127,128]之間,用“==”判斷是否相等是沒(méi)問(wèn)題的,如果不在這個(gè)區(qū)間,是不能用“==”的,原因如下源碼解釋:

public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

如果不在[-127,128]之間,則會(huì)new一個(gè)新對(duì)象,自然“==”兩個(gè)不同的對(duì)象,其結(jié)果必然是false了。

解決辦法:
a. : 使用Long中的longValue()進(jìn)行轉(zhuǎn)換

Long a = 128l;
Long b = 128l;
a.longValue() == b.longValue() //true

b. : Long中的equals()

public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
}
2.Java中進(jìn)程和線程的區(qū)別

https://blog.csdn.net/QQ1608731824/article/details/81461269
進(jìn)程是資源分配的最小單位,線程是CPU調(diào)度的最小單位

地址空間和其它資源:進(jìn)程間相互獨(dú)立,同一進(jìn)程的各線程間共享。某進(jìn)程內(nèi)的線程在其它進(jìn)程不可見。

通信:進(jìn)程間通信IPC,線程間可以直接讀寫進(jìn)程數(shù)據(jù)段(如全局變量)來(lái)進(jìn)行通信——需要進(jìn)程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性。

調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多。

在多線程OS中,進(jìn)程不是一個(gè)可執(zhí)行的實(shí)體。

線程之間如何實(shí)現(xiàn)資源共享:

將要共享的數(shù)據(jù)封裝成另外一個(gè)對(duì)象,對(duì)這個(gè)對(duì)象進(jìn)行操作

將Runnable作為一個(gè)內(nèi)部類,并在外部類中定義要共享的成員變量

3. 重寫equals為什么要重寫hashcode()?

對(duì)于==:如果作用于基本數(shù)據(jù)類型的變量,則直接比較其存儲(chǔ)的 “值”是否相等;
如果作用于引用類型的變量,則比較的是所指向的對(duì)象的地址

對(duì)于equals方法:注意:equals方法不能作用于基本數(shù)據(jù)類型的變量
如果沒(méi)有對(duì)equals方法進(jìn)行重寫,則比較的是引用類型的變量所指向的對(duì)象的地址;
諸如String、Date等類對(duì)equals方法進(jìn)行了重寫的話,比較的是所指向的對(duì)象的內(nèi)容。

hashCode()方法:Object類中的本地方法,也用來(lái)判斷兩個(gè)對(duì)象是否相等。
如果沒(méi)有重寫hashCode()方法,該方法返回的是對(duì)象在內(nèi)存中的地址轉(zhuǎn)換成的int值,因此,任何對(duì)象的hashCode()方法值是不相等的。

equals()方法也是判斷兩個(gè)對(duì)象是否相等,但是與hashCode()方法有區(qū)別。一般來(lái)講,equals()方法是給用戶調(diào)用的,依據(jù)情況可以選擇重寫或者不重寫。對(duì)于hashCode()方法,用戶一般不會(huì)去調(diào)用,hashCode相當(dāng)于根據(jù)一定的規(guī)則將與對(duì)象相關(guān)的信息映射為一個(gè)數(shù)值,稱為散列值。一般在在覆蓋equals()方法的同時(shí)也要覆蓋hashCode()方法,否則將會(huì)違反Object hashCode的通用約定,從而導(dǎo)致該類無(wú)法與所有基于散列值的集合類結(jié)合在一起正常工作。

Object hashCode()方法的通用約定:

如果x.equals(y)返回true,那么這兩個(gè)對(duì)象的hashCode()方法必須產(chǎn)生同樣的整數(shù)結(jié)果;

如果x.equals(y)返回false,那么這兩個(gè)對(duì)象的hashCode()方法產(chǎn)生的結(jié)果也可能相等,也可能不想等;

如果兩個(gè)對(duì)象的hashCode()方法返回值不相等,則x.equals(y)一定為false

如果兩個(gè)對(duì)象的hashCode()方法返回值相等,則x.equals(y)可能為true,可能為false。

4. Java的淺拷貝和深拷貝

淺拷貝:使用一個(gè)已知實(shí)例對(duì)新創(chuàng)建實(shí)例的成員變量逐個(gè)賦值,這個(gè)方式被稱為淺拷貝。
深拷貝:當(dāng)一個(gè)類的拷貝構(gòu)造方法,不僅要復(fù)制對(duì)象的所有非引用成員變量值,還要為引用類型的成員變量創(chuàng)建新的實(shí)例,并且初始化為形式參數(shù)實(shí)例值。

也就是說(shuō)淺拷貝只復(fù)制一個(gè)對(duì)象,傳遞引用,不能復(fù)制實(shí)例。而深拷貝對(duì)對(duì)象內(nèi)部的引用均復(fù)制,它是創(chuàng)建一個(gè)新的實(shí)例,并且復(fù)制實(shí)例。對(duì)于淺拷貝當(dāng)對(duì)象的成員變量是基本數(shù)據(jù)類型時(shí),兩個(gè)對(duì)象的成員變量已有存儲(chǔ)空間,賦值運(yùn)算傳遞值,所以淺拷貝能夠復(fù)制實(shí)例。但是當(dāng)對(duì)象的成員變量是引用數(shù)據(jù)類型時(shí),就不能實(shí)現(xiàn)對(duì)象的復(fù)制了

5. 為什么String被設(shè)計(jì)成不可變

String 構(gòu)成:

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
    ...

源碼我們可以知道String底層是由char 數(shù)組構(gòu)成的,我們創(chuàng)建一個(gè)字符串對(duì)象的時(shí)候,其實(shí)是將字符串保存在char數(shù)組中,因?yàn)閿?shù)組是引用對(duì)象,為了防止數(shù)組可變,jdk加了final修飾,加了final修飾的數(shù)組只是代表了引用不可變,不代表數(shù)組的內(nèi)容不可變,因此jdk為了真正防止不可變,又加了一個(gè)private修飾符。

說(shuō)到String 不得不提字符串常量池,這個(gè)常量池主要存儲(chǔ)在方法區(qū)中,當(dāng)一個(gè)字符串被創(chuàng)建的時(shí)候,首先會(huì)去常量池中查找,如果找到了就返回對(duì)改字符串的引用,如果沒(méi)找到就創(chuàng)建這個(gè)字符串并塞到常量池中。

下面代碼只會(huì)在:

String s1 ="abc";
String s2 ="abc";

試想一下如果String是可變的,當(dāng)兩個(gè)引用指向指向同一個(gè)字符串時(shí),對(duì)其中一個(gè)做修改就會(huì)影響另外一個(gè)。
5.1 什么是不可變?

對(duì)于Java而言,除了基本類型(即int, long, double等),其余的都是對(duì)象。
對(duì)于何為不可變對(duì)象,《java concurrency in practice》一書給出了一個(gè)粗略的定義:對(duì)象一旦創(chuàng)建后,其狀態(tài)不可修改,則該對(duì)象為不可變對(duì)象。

一般一個(gè)對(duì)象滿足以下三點(diǎn),則可以稱為是不可變對(duì)象:

其狀態(tài)不能在創(chuàng)建后再修改;

所有域都是final類型;

其構(gòu)造函數(shù)構(gòu)造對(duì)象期間,this引用沒(méi)有泄露。

這里重點(diǎn)說(shuō)明一下第2點(diǎn),一個(gè)對(duì)象其所有域都是final類型,該對(duì)象也可能是可變對(duì)象。因?yàn)閒inal關(guān)鍵字只是限制對(duì)象的域的引用不可變,但無(wú)法限制通過(guò)該引用去修改其對(duì)應(yīng)域的內(nèi)部狀態(tài)。因此,嚴(yán)格意義上的不可變對(duì)象,其final關(guān)鍵字修飾的域應(yīng)該也是不可變對(duì)象和primitive type值。

從技術(shù)上講,不可變對(duì)象內(nèi)部域并不一定全都聲明為final類型,String類型即是如此。在String對(duì)象的內(nèi)部我們可以看到有一個(gè)名為hash的域并不是final類型,這是因?yàn)镾tring類型惰性計(jì)算hashcode并存儲(chǔ)在hash域中(這是通過(guò)其他final類型域來(lái)保證每次的hashcode計(jì)算結(jié)果必定是相同的)。除此之外,String對(duì)象的不可變是由于對(duì)String類型的所有改變內(nèi)部存儲(chǔ)結(jié)構(gòu)的操作都會(huì)new出一個(gè)新的String對(duì)象。
5.2 不可變帶來(lái)的好處(1):安全性

1、多線程安全性因?yàn)镾tring是不可變的,因此在多線程操作下,它是安全的,我們看下如下代碼:

public String get(String str){
    str +="aaa";
    return str;
}

試想一下如果String是可變的,那么get方法內(nèi)部改變了str的值,方法外部str也會(huì)隨之改變。

2、類加載中體現(xiàn)的安全性類加載器要用到字符串,不可變性提供了安全性,以便正確的類被加載。
譬如你想加載java.sql. Connection類,而這個(gè)值被改成了hacked.Connection,那么會(huì)對(duì)你的數(shù)據(jù)庫(kù)造成不可知的破壞。

5.3 不可變帶來(lái)的好處(2): 使用常量池節(jié)省空間

只有當(dāng)字符串是不可變的,字符串池才有可能實(shí)現(xiàn)。字符串池的實(shí)現(xiàn)可以在運(yùn)行時(shí)節(jié)約很多heap空間,因?yàn)椴煌淖址兞慷贾赶虺刂械耐粋€(gè)字符串。但如果字符串是可變的,那么String interning將不能實(shí)現(xiàn)(String interning是指對(duì)不同的字符串僅僅只保存一個(gè),即不會(huì)保存多個(gè)相同的字符串),因?yàn)檫@樣的話,如果變量改變了它的值,那么其它指向這個(gè)值的變量的值也會(huì)一起改變

5.4 不可變帶來(lái)的好處(3): 緩存hashcode

因?yàn)樽址遣豢勺兊?,所以在它?chuàng)建的時(shí)候hashcode就被緩存了,不需要重新計(jì)算。這就使得字符串很適合作為Map中的鍵,字符串的處理速度要快過(guò)其它的鍵對(duì)象。這就是HashMap中的鍵往往都使用字符串。我們可以看到String中有如下代碼:

private int hash;//this is used to cache hash code.

以上代碼中hash變量中就保存了一個(gè)String對(duì)象的hashcode,因?yàn)镾tring類不可變,所以一旦對(duì)象被創(chuàng)建,該hash值也無(wú)法改變。所以,每次想要使用該對(duì)象的hashcode的時(shí)候,直接返回即可。

5.5 不可變帶來(lái)的缺點(diǎn)

不可變對(duì)象也有一個(gè)缺點(diǎn)就是會(huì)制造大量垃圾,由于他們不能被重用而且對(duì)于它們的使用就是”用“然后”扔“,字符串就是一個(gè)典型的例子,它會(huì)創(chuàng)造很多的垃圾,給垃圾收集帶來(lái)很大的麻煩。當(dāng)然這只是個(gè)極端的例子,合理的使用不可變對(duì)象會(huì)創(chuàng)造很大的價(jià)值。

密碼應(yīng)該存放在字符數(shù)組中而不是String中

由于String在Java中是不可變的,如果你將密碼以明文的形式保存成字符串,那么它將一直留在內(nèi)存中,直到垃圾收集器把它清除。而由于字符串被放在字符串緩沖池中以方便重復(fù)使用,所以它就可能在內(nèi)存中被保留很長(zhǎng)時(shí)間,而這將導(dǎo)致安全隱患,因?yàn)槿魏文軌蛟L問(wèn)內(nèi)存(memorydump內(nèi)存轉(zhuǎn)儲(chǔ))的人都能清晰的看到文本中的密碼,這也是為什么你應(yīng)該總是使用加密的形式而不是明文來(lái)保存密碼。由于字符串是不可變的,所以沒(méi)有任何方式可以修改字符串的值,因?yàn)槊看涡薷亩紝a(chǎn)生新的字符串,然而如果你使用char[]來(lái)保存密碼,你仍然可以將其中所有的元素都設(shè)置為空或者零。所以將密碼保存到字符數(shù)組中很明顯的降低了密碼被竊取的風(fēng)險(xiǎn)。當(dāng)然只使用字符數(shù)組也是不夠的,為了更安全你需要將數(shù)組內(nèi)容進(jìn)行轉(zhuǎn)化。建議使用哈希的或者是加密過(guò)的密碼而不是明文,然后一旦完成驗(yàn)證,就將它從內(nèi)存中清除掉

6. String 字符串常量,StringBuffer 字符串變量(線程安全),StringBuilder 字符串變量(非線程安全)

一旦一個(gè)string對(duì)象在內(nèi)存(堆)中被創(chuàng)建出來(lái),他就無(wú)法被修改。特別要注意的是,String類的所有方法都沒(méi)有改變字符串本身的值,都是返回了一個(gè)新的對(duì)象。
如果你需要一個(gè)可修改的字符串,應(yīng)該使用StringBuffer或者StringBuilder。否則會(huì)有大量時(shí)間浪費(fèi)在垃圾回收上,因?yàn)槊看卧噲D修改都有新的string對(duì)象被創(chuàng)建出來(lái)。

6.1 定義

查看API會(huì)發(fā)現(xiàn),String、StringBuffer、StringBuilder都實(shí)現(xiàn)了 CharSequence接口,雖然它們都與字符串相關(guān),但是其處理機(jī)制不同。
String:是不可改變的量,也就是創(chuàng)建后就不能在修改了。
StringBuffer:是一個(gè)可變字符串序列,它與String一樣,在內(nèi)存中保存的都是一個(gè)有序的字符串序列(char類型的數(shù)組),不同點(diǎn)是StringBuffer對(duì)象的值是可變的。
StringBuilder:與StringBuffer類基本相同,都是可變字符串序列,不同點(diǎn)是StringBuffer是線程安全的,StringBuilder是線程不安全的。 在性能方面,由于String類的操作是產(chǎn)生新的String對(duì)象,而StringBuilder和StringBuffer只是一個(gè)字符數(shù)組的擴(kuò)容而已,所以String類的操作要遠(yuǎn)慢于StringBuffer和StringBuilder。

6.2 使用場(chǎng)景

使用String類的場(chǎng)景:在字符串不經(jīng)常變化的場(chǎng)景中可以使用String類,例如常量的聲明、少量的變量運(yùn)算。共享的場(chǎng)合
使用StringBuffer類的場(chǎng)景:在頻繁進(jìn)行字符串運(yùn)算(如拼接、替換、刪除等),并且運(yùn)行在多線程環(huán)境中,則可以考慮使用StringBuffer,例如XML解析、HTTP參數(shù)解析和封裝。
使用StringBuilder類的場(chǎng)景:在頻繁進(jìn)行字符串運(yùn)算(如拼接、替換、和刪除等),并且運(yùn)行在單線程的環(huán)境中,則可以考慮使用StringBuilder,如SQL語(yǔ)句的拼裝、JSON封裝等。

6.3 分析

簡(jiǎn)要的說(shuō),String 類型和 StringBuffer 類型的主要性能區(qū)別其實(shí)在于 String 是不可變的對(duì)象, 因此在每次對(duì) String 類型進(jìn)行改變的時(shí)候其實(shí)都等同于生成了一個(gè)新的 String 對(duì)象,然后將指針指向新的 String 對(duì)象。所以經(jīng)常改變內(nèi)容的字符串最好不要用 String,因?yàn)槊看紊蓪?duì)象都會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無(wú)引用對(duì)象多了以后,JVM 的 GC 就會(huì)開始工作,那速度是一定會(huì)相當(dāng)慢的。

而如果是使用StringBuffer類則結(jié)果就不一樣了,每次結(jié)果都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象,再改變對(duì)象引用。所以在一般情況下我們推薦使用 StringBuffer,特別是字符串對(duì)象經(jīng)常改變的情況下。

在某些特別情況下, String 對(duì)象的字符串拼接其實(shí)是被 JVM 解釋成了 StringBuffer 對(duì)象的拼接,所以這些時(shí)候 String 對(duì)象的速度并不會(huì)比 StringBuffer 對(duì)象慢,而特別是以下的字符串對(duì)象生成中, String 效率是遠(yuǎn)要比 StringBuffer 快的:

String S1 = "This is only a" + "simple" + "test";
StringBuffer Sb =new StringBuilder(“This is only a").append("simple").append(" test");

你會(huì)很驚訝的發(fā)現(xiàn),生成 String S1 對(duì)象的速度簡(jiǎn)直太快了,而這個(gè)時(shí)候 StringBuffer 居然速度上根本一點(diǎn)都不占優(yōu)勢(shì)。其實(shí)這是 JVM 的一個(gè)把戲,在 JVM 眼里,這個(gè)

String S1 = “This is only a" + “ simple" + “test"; 

其實(shí)就是:String S1 = “This is only a simple test";
所以當(dāng)然不需要太多的時(shí)間了。但大家這里要注意的是,如果你的字符串是來(lái)自另外的 String 對(duì)象的話,速度就沒(méi)那么快了,譬如:

String S2 = "This is only a";
String S3 = "simple";
String S4 = "test";
String S1 = S2 +S3 + S4;

這時(shí)候 JVM 會(huì)規(guī)規(guī)矩矩的按照原來(lái)的方式去做。

6.4 總結(jié)

在大部分情況下 StringBuffer > String
Java.lang.StringBuffer是線程安全的可變字符序列。一個(gè)類似于 String 的字符串緩沖區(qū),但不能修改。雖然在任意時(shí)間點(diǎn)上它都包含某種特定的字符序列,但通過(guò)某些方法調(diào)用可以改變?cè)撔蛄械拈L(zhǎng)度和內(nèi)容。在程序中可將字符串緩沖區(qū)安全地用于多線程。而且在必要時(shí)可以對(duì)這些方法進(jìn)行同步,因此任意特定實(shí)例上的所有操作就好像是以串行順序發(fā)生的,該順序與所涉及的每個(gè)線程進(jìn)行的方法調(diào)用順序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的數(shù)據(jù)。每個(gè)方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點(diǎn)添加字符。

例如,如果 z 引用一個(gè)當(dāng)前內(nèi)容是“start”的字符串緩沖區(qū)對(duì)象,則此方法調(diào)用 z.append(“l(fā)e”) 會(huì)使字符串緩沖區(qū)包含“startle”(累加);而 z.insert(4, “l(fā)e”) 將更改字符串緩沖區(qū),使之包含“starlet”。

在大部分情況下 StringBuilder > StringBuffer

java.lang.StringBuilder是一個(gè)可變的字符序列,是JAVA 5.0新增的。此類提供一個(gè)與 StringBuffer 兼容的 API,但不保證同步,所以使用場(chǎng)景是單線程。該類被設(shè)計(jì)用作 StringBuffer 的一個(gè)簡(jiǎn)易替換,用在字符串緩沖區(qū)被單個(gè)線程使用的時(shí)候(這種情況很普遍)。如果可能,建議優(yōu)先采用該類,因?yàn)樵诖蠖鄶?shù)實(shí)現(xiàn)中,它比 StringBuffer 要快。兩者的使用方法基本相同。

7. 序列化和反序列化 7.1 什么是序列化和反序列化

Java序列化是指把Java對(duì)象保存為二進(jìn)制字節(jié)碼的過(guò)程,Java反序列化是指把二進(jìn)制碼重新轉(zhuǎn)換成Java對(duì)象的過(guò)程。

7.2 為什么要序列化?

1.java對(duì)象的生命周期要比java虛擬機(jī)短,實(shí)際應(yīng)用中希望虛擬機(jī)停止運(yùn)行之后能夠持久化指定的對(duì)象,此時(shí)可以將對(duì)象序列化保存;
2.java對(duì)象通過(guò)網(wǎng)絡(luò)傳輸?shù)臅r(shí)候,因?yàn)閿?shù)據(jù)只能以二進(jìn)制的形式在網(wǎng)絡(luò)中進(jìn)行傳輸,因此當(dāng)對(duì)象通過(guò)網(wǎng)絡(luò)發(fā)送出去之前,需要先序列化為二進(jìn)制數(shù)據(jù),在接收端收到二進(jìn)制數(shù)據(jù)之后反序列化成二進(jìn)制對(duì)象。

7.3 如何實(shí)現(xiàn)序列化 1.實(shí)現(xiàn) java.io.Serializable 接口,就可以被序列化。

在序列化的時(shí)候使用默認(rèn)的方式來(lái)進(jìn)行序列化,這種序列化方式僅僅對(duì)對(duì)象的非transient的實(shí)例變量進(jìn)行序列化,而不會(huì)序列化對(duì)象的transient的實(shí)例變量,也不會(huì)序列化靜態(tài)變量,所以我們對(duì)不想持久化的變量可以加上transient關(guān)鍵字。注意使用默認(rèn)機(jī)制,在序列化對(duì)象時(shí),不僅會(huì)序列化當(dāng)前對(duì)象本身,還會(huì)對(duì)該對(duì)象引用的其它對(duì)象也進(jìn)行序列化,同樣地,這些其它對(duì)象引用的另外對(duì)象也將被序列化,以此類推。所以,如果一個(gè)對(duì)象包含的成員變量是容器類對(duì)象,而這些容器所含有的元素也是容器類對(duì)象,那么這個(gè)序列化的過(guò)程就會(huì)較復(fù)雜,開銷也較大。如果需要實(shí)現(xiàn)自定義序列化和反序列化,那么需要重寫writeObject()方法和readObject()方法。在序列化過(guò)程中,如果被序列化的類中定義了writeObject 和 readObject 方法,將會(huì)使用反射的方式調(diào)用自定義的 writeObject 和 readObject 方法,進(jìn)行用戶自定義的序列化和反序列化。

2.實(shí)現(xiàn)Externalizable接口也可以完成自定義序列化,必須實(shí)現(xiàn)writeExternal()方法和readExternal()方法。 7.4 Serializable 和 Externalizable 的區(qū)別

Serializable既可以采用默認(rèn)的序列化和反序列化方式,也可以使用用戶自定義的序列化和反序列化的方式。
Externalizable序列化,雖然Externalizable接口繼承自Serializable接口,但是需要序列化類繼承此接口的話,Serializable所有序列化機(jī)制全部失效。Externalizable序列化的過(guò)程:使用Externalizable序列化時(shí),在進(jìn)行反序列化的時(shí)候,會(huì)重新實(shí)例化一個(gè)對(duì)象,然后再將被反序列化的對(duì)象的狀態(tài)全部復(fù)制到這個(gè)新的實(shí)例化對(duì)象當(dāng)中去,因此必須有一個(gè)無(wú)參構(gòu)造方法供其調(diào)用,并且權(quán)限是public。

7.5 序列化和反序列化的實(shí)現(xiàn)原理

Java序列化和反序列化本質(zhì)上是將對(duì)象信息生成一串二進(jìn)制字節(jié)碼和從二進(jìn)制字節(jié)碼解析的過(guò)程。序列化算法:
1)當(dāng)前類的描述
2)當(dāng)前類屬性的描述
3)父類描述
4)父類屬性描述
5)父類屬性值描述
6)子類屬性值描述

類描述是從下到上,類屬性描述是從上到下。
8. 如何理解面向?qū)ο?/b>

面向?qū)ο蟮娜齻€(gè)特征:封裝、繼承、多態(tài)
封裝:封裝是將客觀事物抽象成類,每個(gè)類都包含自身的數(shù)據(jù)以及操作,不必需要其他的類來(lái)完成操作。類內(nèi)部的實(shí)現(xiàn)可以自由的修改;具有清晰的對(duì)外接口。良好的封裝能夠減少耦合;
繼承:繼承是從已有的類中派生出新的類稱為子類,子類繼承父類的屬性和行為,并能夠根據(jù)自己的需求擴(kuò)展新的行為,提供了代碼的復(fù)用性。
多態(tài):多態(tài)允許不同類的對(duì)象對(duì)同一消息做出響應(yīng)。提供繼承關(guān)系,子類重寫父類的方法;父類的引用執(zhí)行子類的對(duì)象;在調(diào)用父類的方法是實(shí)際上表現(xiàn)的是子類的狀態(tài)。

9. for循環(huán)和while循環(huán)兩者之間有什么區(qū)別?

從內(nèi)存角度考慮:

局部變量在棧內(nèi)存中存在,當(dāng)for循環(huán)語(yǔ)句結(jié)束,那么變量會(huì)及時(shí)被gc(垃圾回收器)及時(shí)的釋放掉,不浪費(fèi)空間

如果使用循環(huán)之后還想去訪問(wèn)循環(huán)語(yǔ)句中控制那個(gè)變量,使用while循環(huán)

從應(yīng)用場(chǎng)景角度考慮:

如果一個(gè)需求明確循環(huán)的次數(shù),那么使用for循環(huán)(開發(fā)中使用for循環(huán)的幾率大于while循環(huán))

如果一個(gè)需求,不知道循環(huán)了多少次,使用while循環(huán)

10. Servlet的生命周期、Servlet是否線程安全

在servlet容器啟動(dòng)時(shí)初始化。在web.xml 中配置 1表示在容器啟動(dòng)時(shí)初始化。默認(rèn)沒(méi)有此值

servlet在第一次被訪問(wèn)時(shí)初始化。即創(chuàng)建唯一的servlet實(shí)例。(單例多線程下面會(huì)說(shuō))

當(dāng)有請(qǐng)求訪問(wèn)該servlet是,servlet容器就會(huì)創(chuàng)建針對(duì)于這個(gè)請(qǐng)求的servletRequest于servletResponse,然后servlet的service方法被調(diào)用。當(dāng)容器把servlet生成的響應(yīng)結(jié)果發(fā)送給客戶,容器就會(huì)銷毀request和response對(duì)象

容器在銷毀該實(shí)例前調(diào)用servlet的destroy方法(釋放servlet所占用的資源,如關(guān)閉流和數(shù)據(jù)庫(kù)連接),此外還會(huì)銷毀與servlet對(duì)象關(guān)聯(lián)的ServletConfig對(duì)象。

servlet類只創(chuàng)建一個(gè)實(shí)例,對(duì)于可與客戶端的并發(fā)訪問(wèn),它是線程不安全的。

servlet的處理方式是,每次訪問(wèn)時(shí)重新起一線程執(zhí)行service方法。所以要想保證servlet的線程安全,不應(yīng)該在servlet中定義實(shí)例變量。

當(dāng)然完全可以通過(guò)加鎖保證線程安全,但對(duì)于成千上萬(wàn)的并發(fā)訪問(wèn),性能下降。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76706.html

相關(guān)文章

  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    BicycleWarrior 評(píng)論0 收藏0
  • 【推薦】最新200篇:技術(shù)文章整理

    摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...

    tommego 評(píng)論0 收藏0
  • Android-Java面試

    摘要:好不容易在月號(hào)這天中午點(diǎn)左右接到了來(lái)自阿里的面試電話。這里會(huì)不斷收集和更新基礎(chǔ)相關(guān)的面試題,目前已收集題。面試重難點(diǎn)的和的打包過(guò)程多線程機(jī)制機(jī)制系統(tǒng)啟動(dòng)過(guò)程,啟動(dòng)過(guò)程等等掃清面試障礙最新面試經(jīng)驗(yàn)分享,此為第一篇,開篇。 2016 年末,騰訊,百度,華為,搜狗和滴滴面試題匯總 2016 年未,騰訊,百度,華為,搜狗和滴滴面試題匯總 各大公司 Java 后端開發(fā)面試題總結(jié) 各大公司 Jav...

    TalkingData 評(píng)論0 收藏0
  • 墻裂推薦:搜云庫(kù)技術(shù)團(tuán)隊(duì),面試必備的技術(shù)干貨

    摘要:今天整理了一下近大半年以來(lái)的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過(guò)了,這個(gè)記錄的過(guò)程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 今天整理了一下近大半年以來(lái)的一些文章,和我的預(yù)期一樣,很多文章我都忘記自己曾經(jīng)寫過(guò)了,這個(gè)記錄的過(guò)程讓我也有了新的理解。希望大家,收藏,點(diǎn)贊,加轉(zhuǎn)發(fā)。 面試必備 面試必備:深入Spring MVC DispatchServlet 源碼...

    SegmentFault 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<