重拾 Java 基礎

引言

最近很久沒有遇到技術瓶頸了,思考得天然少了,天天都是重複性的工做。java

阿里開始招實習,同窗問我要不要去申請阿里的實習,我說不去,我的對阿里的印象很差。程序員

記得去年阿里給我發了郵件,我很認真地回覆,而後他不理我了。(最起碼的尊重都沒有,就算我菜你起碼回覆我一下啊?)算法

這種不尊重人的公司感受去了也不快樂,當程序員最重要的就是快樂,不快樂寫什麼代碼?json

clipboard.png

電話面

同窗很友好地分享了他的阿里電話面經驗。瀏覽器

問的都是看功底的問題,和開發經驗無關(估計寫上個幾年代碼不寫框架應該也不知道這個)。緩存

Java中的HashMaptransientvolatileHTTP301/302、生產者消費者算法。服務器

HashMap都問爛了,問的是HashMap的底層原理,我知道大家本身寫過JDK,請不要再問我HashMap裏的put操做是怎麼實現的了!多線程

問源碼的真的很討厭,有什麼意義嗎?看過的就能答上,沒看過的就答不上。框架

基礎學習

transient

這並非第一次聽到transient這個詞了,以前也用過,當咱們使用YunzhiService進行綜合查詢時,咱們會在實體中構造不映射到數據表的屬性用於查詢。學習

對於這些不映射爲數據表字段的屬性,咱們使用@Transient註解。

Java中被transient修飾又是什麼意思呢?

clipboard.png

爲何要有transientStackOverflow的解釋通俗易懂。

The transient keyword in Java is used to indicate that a field should not be part of the serialization (which means saved, like to a file) process.

Java中的transient關鍵字,意味着該字段不參與序列化,意味着不被保存,例如輸出到文件中。

序列化?fastjson應該用到了這個關鍵字。

clipboard.png

厲害厲害,fastjson開發團隊基本功紮實。

volatile

這個關鍵字也不知道怎麼能給你們通俗的講出來,仍是從實際的小例子出發吧?

你們回憶一下咱們以前的單例模式,單例模式很經常使用,這個是必需要會的。

這是有問題的懶漢模式,多線程的時候就不能保持單例了。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

修正以前的問題

clipboard.png

糾正一下以前博客中的一個問題,以前這樣寫雖然也能實現,可是效率極低,由於每次getInstance的時候都會被synchronized阻塞。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

爲了效率,不能在方法上加鎖,因此須要在新建單例的時候加鎖,保證只要只有一個單例被new出來。

看起來是沒問題的,由於咱們想固然的覺得,一個線程new出來的Singleton,賦值給instance,而後另外一個線程獲取到的instance就必定不是空。實際上呢?

CPU結構

讓咱們來看Youtube上的一張圖:

clipboard.png

CPU內部結構中,thread-1thread-2運行在不一樣的核心上,每一個核心有一個local cache,兩個線程執行時,會將變量從shared cache讀取到local cache

因此thread-1flag內容改變了,可是thread-2獲取的flag仍是從local cache中獲取的,因此仍是true

直到,thread-1flag更新到shared cache,而後再更新到thread-2local cachethread-2才知道flag變了。

因此咱們的單例也同樣,線程A新建了單例,而後其餘線程再獲取的時候,不必定是線程A所建立的單例對象。

拯救世界

volatile來拯救世界了。

private static volatile Singleton instance;

volatile作了兩件事,強制將local cache寫入到shared cache,同時使其餘核心中的local cache對該數據的緩存無效。

因此,完整的單例應該是這樣:

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

真正的單例

上面的講解只是爲了讓你們瞭解Javavolatile的做用,實際的單例並不這樣實現,而是使用私有靜態內部類實現懶漢模式,當訪問getInstance方法時,才加載Holder類,實例化單例。

public class Singleton {

    private static class Holder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {

    }

    public static Singleton getInstance() {
        return Holder.instance;
    }
}

呼,長出了一口氣,兩個晚上了,總算把volatile本身學會而後講明白了,這個應該是發生的機率很小很小,我爲了讓volatile的驗證讓你們都看到,使用JDK自帶的線程池,模擬實際的多線程環境,分別執行本身的測試代碼,但仍是沒出現問題。

HTTP 301/302

去火狐開發者文檔看看:

301 Moved Permanently

永久重定向,請求的資源已經被移動到了由Location頭部指定的url上,搜索引擎會根據該響應修正。

HTTP升級到HTTPS時應該能用到。

302 Found

臨時重定向,請求的資源被暫時的移動到了由Location頭部指定的url上。瀏覽器會重定向到這個url,可是搜索引擎不會對該資源的連接進行更新。

可能會在某個後臺服務癱瘓的時候再轉給別的後臺服務器時用到?

生產者消費者

至於最後的生產者消費者算法問題,我以爲意義不大,畢竟操做系統的課本出自位河北工業大學操做系統教師之手。

clipboard.png

JDK中有阻塞隊列,用的就是生產者消費者模型。用到的時候再說吧。

總結

每一個人都是優秀的人,每一個人都值得尊敬。

軟件生而自由,不受世俗污染,不受凡塵打擾,我祝願每一位軟件工程師都能生活在自由、快樂之中。

相關文章
相關標籤/搜索