1. 程式人生 > >夯實Java基礎系列7:一文讀懂Java 程式碼塊和執行順序

夯實Java基礎系列7:一文讀懂Java 程式碼塊和執行順序

目錄

  • Java中的構造方法
    • 構造方法簡介
    • 構造方法例項
      • 例 1
      • 例 2
  • Java中的幾種構造方法詳解
    • 普通構造方法
    • 預設構造方法
    • 過載構造方法
    • java子類構造方法呼叫父類構造方法
  • Java中的程式碼塊簡介
  • Java程式碼塊使用
    • 區域性程式碼塊
    • 構造程式碼塊
    • 靜態程式碼塊
  • Java程式碼塊、構造方法(包含繼承關係)的執行順序
  • 參考文章
  • 微信公眾號
    • Java技術江湖
    • 個人公眾號:黃小斜

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視

https://github.com/h2pl/Java-Tutorial

喜歡的話麻煩點下Star哈

文章首發於我的個人部落格:

www.how2playlife.com

本文是微信公眾號【Java技術江湖】的《夯實Java基礎系列博文》其中一篇,本文部分內容來源於網路,為了把本文主題講得清晰透徹,也整合了很多我認為不錯的技術部落格內容,引用其中了一些比較好的部落格文章,如有侵權,請聯絡作者。
該系列博文會告訴你如何從入門到進階,一步步地學習Java基礎知識,並上手進行實戰,接著瞭解每個Java知識點背後的實現原理,更完整地瞭解整個Java技術體系,形成自己的知識框架。為了更好地總結和檢驗你的學習成果,本系列文章也會提供每個知識點對應的面試題以及參考答案。

如果對本系列文章有什麼建議,或者是有什麼疑問的話,也可以關注公眾號【Java技術江湖】聯絡作者,歡迎你參與本系列博文的創作和修訂。

Java中的構造方法

構造方法簡介

構造方法是類的一種特殊方法,用來初始化類的一個新的物件。Java 中的每個類都有一個預設的構造方法,它必須具有和類名相同的名稱,而且沒有返回型別。構造方法的預設返回型別就是物件型別本身,並且構造方法不能被 static、final、synchronized、abstract 和 native 修飾。

提示:構造方法用於初始化一個新物件,所以用 static 修飾沒有意義;構造方法不能被子類繼承,所以用 final 和 abstract 修飾沒有意義;多個執行緒不會同時建立記憶體地址相同的同一個物件,所以用 synchronized 修飾沒有必要。

構造方法的語法格式如下:

class class_name
{
    public class_name(){}    //預設無參構造方法
    public ciass_name([paramList]){}    //定義構造方法
    …
    //類主體
}

在一個類中,與類名相同的方法就是構造方法。每個類可以具有多個構造方法,但要求它們各自包含不同的方法引數。

構造方法例項

例 1

構造方法主要有無參構造方法和有參構造方法兩種,示例如下:

public class MyClass
{
    private int m;    //定義私有變數
    MyClass()
    {
        //定義無參的構造方法
        m=0;
    }
    MyCiass(int m)
    {
        //定義有參的構造方法
        this.m=m;
    }
}

該示例定義了兩個構造方法,分別是無參構造方法和有參構造方法。在一個類中定義多個具有不同引數的同名方法,這就是方法的過載。這兩個構造方法的名稱都與類名相同,均為 MyClass。在例項化該類時可以呼叫不同的構造方法進行初始化。

注意:類的構造方法不是要求必須定義的。如果在類中沒有定義任何一個構造方法,則 Java 會自動為該類生成一個預設的構造方法。預設的構造方法不包含任何引數,並且方法體為空。如果類中顯式地定義了一個或多個構造方法,則 Java 不再提供預設構造方法。

例 2

要在不同的條件下使用不同的初始化行為建立類的物件,這時候就需要在一個類中建立多個構造方法。下面通過一個示例來演示構造方法的使用。

(1) 首先在員工類 Worker 中定義兩個構造方法,程式碼如下:

public class Worker
{
    public String name;    //姓名
    private int age;    //年齡
    //定義帶有一個引數的構造方法
    public Worker(String name)
    {
        this.name=name;
    }
    //定義帶有兩個引數的構造方法
    public Worker(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    public String toString()
    {
        return"大家好!我是新來的員工,我叫"+name+",今年"+age+"歲。";
    }
}

在 Worker 類中定義了兩個屬性,其中 name 屬性不可改變。分別定義了帶有一個引數和帶有兩個引數的構造方法,並對其屬性進行初始化。最後定義了該類的 toString() 方法,返回一條新進員工的介紹語句。

提示:Object 類具有一個 toString() 方法,該方法是個特殊的方法,建立的每個類都會繼承該方法,它返回一個 String 型別的字串。如果一個類中定義了該方法,則在呼叫該類物件時,將會自動呼叫該類物件的 toString() 方法返回一個字串,然後使用“System.out.println(物件名)”就可以將返回的字串內容打印出來。

(2) 在 TestWorker 類中建立 main() 方法作為程式的入口處,在 main() 方法中呼叫不同的構造方法例項化 Worker 物件,並對該物件中的屬性進行初始化,程式碼如下:

public class TestWorker
{
    public static void main(String[] args)
    {
        System.out.println("-----------帶有一個引數的構造方法-----------");
        //呼叫帶有一個引數的構造方法,Staff類中的sex和age屬性值不變
        Worker worker1=new Worker("張強");
        System.out.println(worker1);
        System.out.println("-----------帶有兩個引數的構造方法------------");
        //呼叫帶有兩個引數的構造方法,Staff類中的sex屬性值不變
        Worker worker2=new Worker("李麗",25);
        System.out.println(worker2);
    }
}

在上述程式碼中,建立了兩個不同的 Worker 物件:一個是姓名為張強的員工物件,一個是姓名為李麗、年齡為 25 的員工物件。對於第一個 Worker 物件 Worker1,並未指定 age 屬性值,因此程式會將其值採用預設值 0。對於第二個 Worker 物件 Worker2,分別對其指定了 name 屬性值和 age 屬性值,因此程式會將傳遞的引數值重新賦值給 Worker 類中的屬性值。

執行 TestWorker 類,輸出的結果如下:

-----------帶有一個引數的構造方法-----------
大家好!我是新來的員工,我叫張強,今年0歲。
-----------帶有兩個引數的構造方法------------
大家好!我是新來的員工,我叫李麗,今年25歲。

通過呼叫帶引數的構造方法,在建立物件時,一併完成了物件成員的初始化工作,簡化了物件初始化的程式碼。

Java中的幾種構造方法詳解

普通構造方法

方法名與類名相同

無返回型別

子類不能繼承父類的構造方法

不能被static、final、abstract修飾(有final和static修飾的是不能被子類繼承的,abstract修飾的是抽象類,抽象類是不能例項化的,也就是不能new)

可以被private修飾,可以在本類裡面例項化,但是外部不能例項化物件(注意!!!)

public class A{
    int i=0;
    public A(){
        i=2;
    }
    public A(int i){
        this.i=i;
    }
}

預設構造方法

如果沒有任何的構造方法,編譯時系統會自動新增一個預設無參構造方法

隱含的預設構造方法

    public A(){}

顯示的預設構造方法

    public A(){
    System.out.print("顯示的預設構造方法")
    }

過載構造方法

比如原本的類裡的構造方法是一個引數的,現在新建的物件是有三個引數,此時就要過載構造方法

當一個類中有多個構造方法,有可能會出現重複性操作,這時可以用this語句呼叫其他的構造方法。

public class A{
    private int age;
    private String name;
    public A(int age,String name){
        this.age=age;
        this.name=name;
    }
    public A(int age){
        this(age,"無名氏");//呼叫 A(int age,String name)構造方法
    }
    public A(){
        this(1);//呼叫 A(int age)構造方法
    }
    public void setName(String name) {this.name=name;}
    public String getName() {return name;}
    public void setAge(int age) {this.age=age;}
    public int getAge() {return age;}
}

A a=new A(20,"週一");
A b=new A(20);
A c=new A();
String name = a.getName();
String name1 = b.getName();
int age = c.getAge();
System.out.println(name);
System.out.println(name1);
System.out.println(age);

java子類構造方法呼叫父類構造方法

首先父類構造方法是絕對不能被子類繼承的。

子類構造方法呼叫父類的構造方法重點是:子類構造方法無論如何都要呼叫父類的構造方法。

子類構造方法要麼呼叫父類無參構造方法(包括當父類沒有構造方法時。系統預設給的無參構造方法),要麼呼叫父類有參構造方法。當子類構造方法呼叫父類無參構造方法,一般都是預設不寫的,要寫的話就是super(),且要放在構造方法的第一句。當子類構造方法要呼叫父類有引數的構造方法,那麼子類的構造方法中必須要用super(引數)呼叫父類構造方法,且要放在構造方法的第一句。

當子類的構造方法是無參構造方法時,必須呼叫父類無參構造方法。因為系統會自動找父類有沒有無參構造方法,如果沒有的話系統會報錯:說父類沒有定義無參構造方法。

當子類構造方法是有參構造方法時,這時就會有兩種情況。
第一種:子類構造方法沒有寫super,也就是說你預設呼叫父類無參構造方法,這樣的話就和子類是無參構造方法一樣。

第二種:子類構造方法有super(引數)時,就是呼叫父類有參構造方法,系統會找父類有沒有引數一致(引數數量,且型別順序要相同)的有參構造方法,如果沒有的話,同樣也會報錯。

但是這裡會遇到和過載構造方法this一樣問題,一個引數的構造方法可以呼叫多個引數構造方法,沒有的引數給一個自己定義值也是可以的。

Java中的程式碼塊簡介

在java中用{}括起來的稱為程式碼塊,程式碼塊可分為以下四種:

一.簡介

1.普通程式碼塊:

類中方法的方法體

2.構造程式碼塊:

構造塊會在建立物件時被呼叫,每次建立時都會被呼叫,優先於類建構函式執行。

3.靜態程式碼塊:

用static{}包裹起來的程式碼片段,只會執行一次。靜態程式碼塊優先於構造塊執行。

4.同步程式碼塊:

使用synchronized(){}包裹起來的程式碼塊,在多執行緒環境下,對共享資料的讀寫操作是需要互斥進行的,否則會導致資料的不一致性。同步程式碼塊需要寫在方法中。

二.靜態程式碼塊和構造程式碼塊的異同點

相同點:都是JVM載入類後且在建構函式執行之前執行,在類中可定義多個,一般在程式碼塊中對一些static變數進行賦值。

不同點:靜態程式碼塊在非靜態程式碼塊之前執行。靜態程式碼塊只在第一次new時執行一次,之後不在執行。而非靜態程式碼塊每new一次就執行一次。

Java程式碼塊使用

區域性程式碼塊

位置:區域性位置(方法內部)

作用:限定變數的生命週期,儘早釋放,節約記憶體

呼叫:呼叫其所在的方法時執行

 public class 區域性程式碼塊 {
@Test
public void test (){
    B b = new B();
    b.go();
}
}
class B {
    B(){}
    public void go() {
        //方法中的區域性程式碼塊,一般進行一次性地呼叫,呼叫完立刻釋放空間,避免在接下來的呼叫過程中佔用棧空間
        //因為棧空間記憶體是有限的,方法呼叫可能會會生成很多區域性變數導致棧記憶體不足。
        //使用區域性程式碼塊可以避免這樣的情況發生。
        {
            int i = 1;
            ArrayList<Integer> list = new ArrayList<>();
            while (i < 1000) {
                list.add(i ++);
            }
            for (Integer j : list) {
                System.out.println(j);
            }
            System.out.println("gogogo");
        }
        System.out.println("hello");
    }
}

構造程式碼塊

位置:類成員的位置,就是類中方法之外的位置

作用:把多個構造方法共同的部分提取出來,共用構造程式碼塊

呼叫:每次呼叫構造方法時,都會優先於構造方法執行,也就是每次new一個物件時自動呼叫,對 物件的初始化

class A{
    int i = 1;
    int initValue;//成員變數的初始化交給程式碼塊來完成
    {
        //程式碼塊的作用體現於此:在呼叫構造方法之前,用某段程式碼對成員變數進行初始化。
        //而不是在構造方法呼叫時再進行。一般用於將構造方法的相同部分提取出來。
        //
        for (int i = 0;i < 100;i ++) {
            initValue += i;
        }
    }
    {
        System.out.println(initValue);
        System.out.println(i);//此時會列印1
        int i = 2;//程式碼塊裡的變數和成員變數不衝突,但會優先使用程式碼塊的變數
        System.out.println(i);//此時列印2
        //System.out.println(j);//提示非法向後引用,因為此時j的的初始化還沒開始。
        //
    }
    {
        System.out.println("程式碼塊執行");
    }
    int j = 2;
    {
        System.out.println(j);
        System.out.println(i);//程式碼塊中的變數執行後自動釋放,不會影響程式碼塊之外的程式碼
    }
    A(){
        System.out.println("構造方法執行");
    }
}
public class 構造程式碼塊 {
    @Test
    public void test() {
        A a = new A();
    }
}

靜態程式碼塊

 位置:類成員位置,用static修飾的程式碼塊

 作用:對類進行一些初始化  只加載一次,當new多個物件時,只有第一次會呼叫靜態程式碼塊,因為,靜態程式碼塊                  是屬於類的,所有物件共享一份

 呼叫: new 一個物件時自動呼叫

 public class 靜態程式碼塊 {

@Test
public void test() {
    C c1 = new C();
    C c2 = new C();
    //結果,靜態程式碼塊只會呼叫一次,類的所有物件共享該程式碼塊
    //一般用於類的全域性資訊初始化
    //靜態程式碼塊呼叫
    //程式碼塊呼叫
    //構造方法呼叫
    //程式碼塊呼叫
    //構造方法呼叫
}

}
class C{
    C(){
        System.out.println("構造方法呼叫");
    }
    {
        System.out.println("程式碼塊呼叫");
    }
    static {
        System.out.println("靜態程式碼塊呼叫");
    }
}

Java程式碼塊、構造方法(包含繼承關係)的執行順序

這是一道常見的面試題,要回答這個問題,先看看這個例項吧。

一共3個類:A、B、C
其中A是B的父類,C無繼承僅作為輸出

A類:

public class A {

static {
    Log.i("HIDETAG", "A靜態程式碼塊");
}

private static C c = new C("A靜態成員");
private  C c1 = new C("A成員");

{
    Log.i("HIDETAG", "A程式碼塊");
}

static {
    Log.i("HIDETAG", "A靜態程式碼塊2");
}

public A() {
    Log.i("HIDETAG", "A構造方法");
}

}

B類:

public class B extends A {

private static C c1 = new C("B靜態成員");

{
    Log.i("HIDETAG", "B程式碼塊");
}

private C c = new C("B成員");

static {
    Log.i("HIDETAG", "B靜態程式碼塊2");
}

static {
    Log.i("HIDETAG", "B靜態程式碼塊");
}

public B() {
    Log.i("HIDETAG", "B構造方法");

}

}

C類:

public class C {

public C(String str) {
    Log.i("HIDETAG", str + "構造方法");
}
}

執行語句:new B();

輸出結果如下:

 I/HIDETAG: A靜態程式碼塊
 I/HIDETAG: A靜態成員構造方法
 I/HIDETAG: A靜態程式碼塊2
 I/HIDETAG: B靜態成員構造方法
 I/HIDETAG: B靜態程式碼塊2
 I/HIDETAG: B靜態程式碼塊
 I/HIDETAG: A成員構造方法
 I/HIDETAG: A程式碼塊
 I/HIDETAG: A構造方法
 I/HIDETAG: B程式碼塊
 I/HIDETAG: B成員構造方法
 I/HIDETAG: B構造方法

得出結論:

執行順序依次為:
父類的靜態成員和程式碼塊
子類靜態成員和程式碼塊
父類成員初始化和程式碼快
父類構造方法
子類成員初始化和程式碼塊
子類構造方法

注意:可以發現,同一級別的程式碼塊和成員初始化是按照程式碼順序從上到下依次執行

看完上面這個demo,再來看看下面這道題,看看你搞得定嗎?

看下面一段程式碼,求執行順序:

class A {
    public A() {
        System.out.println("1A類的構造方法");
    }
    {
        System.out.println("2A類的構造快");
    }
    static {
        System.out.println("3A類的靜態塊");
    }
}
 
public class B extends A {
    public B() {
        System.out.println("4B類的構造方法");
    }
    {
        System.out.println("5B類的構造快");
    }
    static {
        System.out.println("6B類的靜態塊");
    }
    public static void main(String[] args) {
        System.out.println("7");
        new B();
        new B();
        System.out.println("8");
    }
}

執行順序結果為:367215421548

為什麼呢?

首先我們要知道下面這5點:

每次new都會執行構造方法以及構造塊。
構造塊的內容會在構造方法之前執行。
非主類的靜態塊會在類載入時,構造方法和構造塊之前執行,切只執行一次。
主類(public class)裡的靜態塊會先於main執行。
繼承中,子類例項化,會先執行父類的構造方法,產生父類物件,再呼叫子類構造方法。
所以題目裡,由於主類B繼承A,所以會先載入A,所以第一個執行的是第3句。

從第4點我們知道6會在7之前執行,所以前三句是367。

之後例項化了B兩次,每次都會先例項化他的父類A,然後再例項化B,而根據第1、2、5點,知道順序為2154。

最後執行8

所以順序是367215421548

參考文章

https://blog.csdn.net/likunkun__/article/details/83066062
https://www.jianshu.com/p/6877aae403f7
https://www.jianshu.com/p/49e45af288ea
https://blog.csdn.net/du_du1/article/details/91383128
http://c.biancheng.net/view/976.html
https://blog.csdn.net/evilcry2012/article/details/79499786
https://www.jb51.net/article/129990.htm

微信公眾號

Java技術江湖

如果大家想要實時關注我更新的文章以及分享的乾貨的話,可以關注我的公眾號【Java技術江湖】一位阿里 Java 工程師的技術小站,作者黃小斜,專注 Java 相關技術:SSM、SpringBoot、MySQL、分散式、中介軟體、叢集、Linux、網路、多執行緒,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!

Java工程師必備學習資源: 一些Java工程師常用學習資源,關注公眾號後,後臺回覆關鍵字 “Java” 即可免費無套路獲取。

個人公眾號:黃小斜

作者是 985 碩士,螞蟻金服 JAVA 工程師,專注於 JAVA 後端技術棧:SpringBoot、MySQL、分散式、中介軟體、微服務,同時也懂點投資理財,偶爾講點演算法和計算機理論基礎,堅持學習和寫作,相信終身學習的力量!

程式設計師3T技術學習資源: 一些程式設計師學習技術的資源大禮包,關注公眾號後,後臺回覆關鍵字 “資料” 即可免費無套路獲取。

相關推薦

夯實Java基礎系列7Java 程式碼執行順序

目錄 Java中的構造方法 構造方法簡介 構造方法例項 例 1 例 2 Java中的幾種構造方法詳解 普通構造方法 預設構造方法 過載構造方法 java子類構造方法呼叫父類構造方法 Java中的程式碼塊簡介 Java程式碼塊使用 區域性程式碼塊 構造程式碼塊 靜態程式碼塊 Java程式碼塊、

夯實Java基礎系列22Java序列化反序列化

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視 https://github.com/h2pl/Java-Tutorial 喜歡的話麻煩點下Star哈 文章首發於我的個人部落格: www.how2playlife.com 本文參考 http://www

夯實Java基礎系列19Java集合類框架,以及常見面試題

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視 https://github.com/h2pl/Java-Tutorial 喜歡的話麻煩點下Star哈 文章首發於我的個人部落格: www.how2playlife.com 本文參考 https://ww

夯實Java基礎系列23繼承、封裝、多型的底層實現原理

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到我的倉庫裡檢視 https://github.com/h2pl/Java-Tutorial 喜歡的話麻煩點下Star哈 文章首發於我的個人部落格: www.how2playlife.com 從JVM結構開始談多型 Jav

夯實Java基礎系列6抽象類介面,從基礎到面試題,揭祕其本質區別!

目錄 抽象類介紹 為什麼要用抽象類 一個抽象類小故事 一個抽象類小遊戲 介面介紹 介面與類相似點: 介面與類的區別: 介面特性 抽象類和介面的區別 介面的使用: 介面最佳實踐:設計模式中的工廠模式 介面與抽象類的本質區別是什麼? 基本語法區別 設計思想區別 如何回答面試題:介面和抽象類的區別?

夯實Java基礎系列4了解final關鍵字的特性、使用方法,以及實現原理

目錄 final使用 final變數 final修飾基本資料型別變數和引用 final類 final關鍵字的知識點 final關鍵字的最佳實踐 final的用法 關於空白final final記憶體分配 使用final修飾方法會提高速度和效率嗎 使用final修飾變數會讓變數的值不能被改變嗎; 如何保

人工智慧(7)---人臉識別技術商業應用、產品落地、核心技術、市場規模

一文讀懂人臉識別技術:商業應用、產品落地、核心技術、市場規模 導讀:國際權威市場洞察報告Gen Market Insights近日釋出《全球人臉識別裝置市場研究報告》稱,中國2017年人臉識別產值佔全世界29.29%市場份額,2023年將達到44.59%。報告還提到中國

從HTTP/0.9到HTTP/2HTTP協議的歷史演變設計思路

eight 結果 key 視頻 this sso單點登陸 會有 研究 patch 本文原作者阮一峰,作者博客:ruanyifeng.com。 1、引言 HTTP 協議是最重要的互聯網基礎協議之一,它從最初的僅為瀏覽網頁的目的進化到現在,已經是短連接通信的事實工業標準,最新版

java物件引用

Java物件及其引用  關於物件與引用之間的一些基本概念。         初學Java時,在很長一段時間裡,總覺得基本概念很模糊。後來才知道,在許多Java書中,把物件和物件的引用混為一談。可是,如果我分不清物件與

Java 11的ZGC為何如此高效

導讀:GC是大部分現代語言內建的特性,Java 11 新加入的ZGC號稱可以達到10ms 以下的 GC 停頓,本文作者對這一新功能進行了深入解析。同時還對還對這一新功能帶來的其他可能性做了展望。ZGC是否可以達到該效能目標,請看高可用架構志願者翻譯的文章。 Java 11的

生死時刻Facebook資料洩密始末

上週末Facebook捲入了一宗醜聞,媒體揭露稱一家服務特朗普競選團隊的資料分析公司Cambri

超級乾貨 資料視覺化

前言資料視覺化,是指將相對晦澀的的資料通過可視的、互動的方式進行展示,從而形象、直觀地表達資料蘊

[轉]機器學習科普文章機器學習,大資料/自然語言處理/演算法全有了”

       在本篇文章中,我將對機器學習做個概要的介紹。本文的目的是能讓即便完全不瞭解機器學習的人也能瞭解機器學習,並且上手相關的實 踐。這篇文件也算是EasyPR開發的番外篇,從這裡開始,必須對機器學習瞭解才能進一步介紹EasyPR的核心。當然,本文也面對一般讀者,不會對

深度 | 生成對抗網路初學入門GAN的基本原理(附資源)

選自 Sigmoidal 作者:Roman Trusov 機器之心編譯 參與:Panda 生成對抗網路是現在人工智慧領域的當紅技術之一。近日,Sigmoidal.io 的部落格發表了一篇入門級介紹文章,對 GAN 的原理進行了解釋說明。另外,在該文章的最後還附帶了一些能幫助初學者自己

Java基本功」Java內部類的用法原理

實現接口 tcl 一點 print 定義 做成 這一 system clas 內部類初探 一、什麽是內部類?   內部類是指在一個外部類的內部再定義一個類。內部類作為外部類的一個成員,並且依附於外部類而存在的。內部類可為靜態,可用protected和private修飾(

推薦 R中的探索性資料分析(附R程式碼

作者:Pablo Casas;翻譯:蔣雨暢;校對:車前子;本文約1500字,建議閱讀7分鐘。本文

JAVA 異常處理

jdk 如何 堆棧溢出 細節 fileread 空指針 note handle 優雅 JAVA 異常類型結構Error 和 Exeption受查異常和非受查異常異常的拋出與捕獲直接拋出異常封裝異常並拋出捕獲異常自定義異常try-catch-finallytry-with-r

資料變金礦序列模型(附用例)

作者:TAVISH SRIVASTAVA翻譯:王雨桐校對:丁楠雅本文約3000字,建議閱讀15分

Java GC原理調優

概述 本文介紹GC基礎原理和理論,GC調優方法思路和方法,基於Hotspot jdk1.8,學習之後將瞭解如何對生產系統出現的G

「05」迴歸的誘惑線性迴歸

前言 從這一篇文章開始,就正式進入「美團」演算法工程師帶你入門機器學習系列的正文了,之前的幾篇算是導讀和預熱,想必大家看的並不過癮。從這裡開始,我們將會以線性迴歸為起點,貫通迴歸方法在機器學習演算法中所扮演的角色、具有的功能和使用的方法。 說起迴歸,它是我們在高中時就接觸過的內容。具體的,迴歸(Regress