很多面試官相信的謠言,作為面試者,你該發聲了!一道題角色逆轉

2020-12-12 酷扯兒

本文轉載自【微信公眾號:小碼逆襲,ID:gh_7c5a039380a0】經微信公眾號授權轉載,如需轉載與原文作者聯繫

情景再現

今天一個學妹跟我分享她今天的面試過程,她面試的是java開發崗,跟我說了面試官大概問了哪些問題,基本都是一些常規的基本知識,其中涉及到多線程的部分有這樣一個問題。

面試官:(一臉嚴肅)說一下Thread和Runable有什麼區別吧。學妹:(心裡美滋滋,這個我在博客上看過,我會)Thread和Runable有2點區別,1.Thread有單繼承的問題;2.Runnable便於實現資源共享,而Thread不能。舉個例子,火車站賣票...balabala...面試官點了點頭....(面試了好幾個問題,終於笑了)。學妹心裡覺得發揮的不錯。

我們先不評論學妹的面試是好是壞,回到「Thread和Runable有什麼區別?」這個問題本身,我覺的一個java基本功,底子厚的面試官就不會問這個問題。為什麼這麼說,你馬上就知道了,今天我們從兩個方面來證明我的觀點,不要再被一些實力並不強的面試官蒙蔽了。

大家都這麼寫不代表一定正確

網絡上流傳的最大的一個錯誤結論:Runnable更容易可以實現多個線程間的資源共享,而Thread不可以!

我在網上隨便搜了一下上面的問題,大家都認為他是對的,其實這是很不科學的,網上的例子就是學妹面試的時候說的那個例子:火車站賣票。我隨便一篇博客中截取了這個例子,我們一起來看一下。

繼承Thread類的方法

//例1

public class MyThreadWithExtends extends Thread {

private int tickets = 10;

@Override

public void run() {

for (int i = 0; i <= 100; i++) {

if(tickets>0){

System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--);

}

}

}

public static void main(String[] args) {

MyThreadWithExtends thread1 = new MyThreadWithExtends();

MyThreadWithExtends thread2 = new MyThreadWithExtends();

MyThreadWithExtends thread3 = new MyThreadWithExtends();

thread1.start();

thread2.start();

thread3.start();

}

}

運行結果:

Thread-0--賣出票:10

Thread-2--賣出票:10

Thread-1--賣出票:10

Thread-2--賣出票:9

Thread-0--賣出票:9

Thread-2--賣出票:8

Thread-1--賣出票:9

Thread-2--賣出票:7

Thread-0--賣出票:8

Thread-2--賣出票:6

Thread-2--賣出票:5

Thread-2--賣出票:4

Thread-1--賣出票:8

Thread-2--賣出票:3

Thread-0--賣出票:7

Thread-2--賣出票:2

Thread-2--賣出票:1

Thread-1--賣出票:7

Thread-0--賣出票:6

Thread-1--賣出票:6

Thread-0--賣出票:5

Thread-0--賣出票:4

Thread-1--賣出票:5

Thread-0--賣出票:3

Thread-1--賣出票:4

Thread-1--賣出票:3

Thread-1--賣出票:2

Thread-0--賣出票:2

Thread-1--賣出票:1

Thread-0--賣出票:1

得出的結論是:每個線程都獨立,不共享資源,每個線程都賣出了10張票,總共賣出了30張。如果真賣票,就有問題了。

實現Runnable接口方式

//例2

public class MyThreadWithImplements implements Runnable {

MyThreadWithImplements myRunnable = new MyThreadWithImplements();

Thread thread1 = new Thread(myRunnable, "窗口一");

Thread thread2 = new Thread(myRunnable, "窗口二");

Thread thread3 = new Thread(myRunnable, "窗口三");

窗口二--賣出票:10

窗口三--賣出票:9

窗口一--賣出票:8

窗口三--賣出票:6

窗口三--賣出票:4

窗口三--賣出票:3

窗口三--賣出票:2

窗口三--賣出票:1

窗口二--賣出票:7

窗口一--賣出票:5

得出的結論是:每個線程共享了對象myRunnable的資源,賣出的總票數是對的 我把這個結論用刪除線標記,因為這句話是大錯特錯!不要再鄭重其事的跟別人講了。

看了上面的例子,你有沒有想是對是錯呢?

例一這個例子結果多賣兩倍票的原因根本不是因為Runnable和Thread的區別,看其中這三行代碼:

MyThreadWithExtends thread1 = new MyThreadWithExtends();

MyThreadWithExtends thread3 = new MyThreadWithExtends();

創建了三個MyThreadWithExtends對象,每個對象都有自己的ticket成員變量,當然會多賣1倍。如果把ticket定義為static類型,就離正確結果又近了一步(因為是多線程同時訪問一個變量會有同步問題,加上鎖才是最終正確的代碼,這裡就不多提了)。

例二的代碼:

MyThreadWithImplements myRunnable = MyThreadWithImplements(); Thread thread3 = new Thread(myRunnable, "窗口三");只創建了一個Runnable對象,肯定只賣一倍票(但也會有多線程同步問題,同樣需要加鎖),根本不是Runnable和Thread的區別造成的。那么正確的寫法是什麼樣的呢?

public class Test extends Thread {

//十張票

private int ticket = 10;

public void run(){

for(int i =0;i<10;i++){

synchronized (this){

if(this.ticket>0){

try {

Thread.sleep(10);

System.out.println(Thread.currentThread().getName()+"賣票---->"+(this.ticket--));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

public static void main(String[] arg){

Test t = new Test();

new Thread(t,"線程1").start();

new Thread(t,"線程2").start();

}

線程1賣票---->10

線程1賣票---->9

線程1賣票---->8

線程1賣票---->7

線程1賣票---->6

線程1賣票---->5

線程1賣票---->4

線程1賣票---->3

線程1賣票---->2

線程1賣票---->1

看到了嗎,只創建了一個Thread對象,效果是不是跟Runable一樣呢,synchronized這個關鍵字是必須的,否則會出現同步問題,至於鎖的問題在這裡就不詳述了。

所以我們得出真正的結論:Thread和Runnable沒有根本的沒區別,只是寫法不同罷了,事實是Thread和Runnable沒有本質的區別,這才是正確的結論,和自以為是的大神所說的Runnable更容易實現資源共享,沒有半點關係!

Thread和Runable到底有什麼區別呢?

我們從源碼來看,上源碼:

public interface Runnable {

/**

* When an object implementing interface <code>Runnable</code> is used

* to create a thread, starting the thread causes the object's

* <code>run</code> method to be called in that separately executing

* thread.

* <p>

* The general contract of the method <code>run</code> is that it may

* take any action whatsoever.

*

* @see java.lang.Thread#run()

*/

public abstract void run();

public class Thread implements Runnable {

/* Make sure registerNatives is the first thing <clinit> does. */

private static native void registerNatives();

static {

registerNatives();

}

private volatile String name;

private int priority;

private Thread threadQ;

private long eetop;

/* Whether or not to single_step this thread. */

private boolean single_step;

/* Whether or not the thread is a daemon thread. */

private boolean daemon = false;

/* JVM state */

private boolean stillborn = false;

/* What will be run. */

private Runnable target;

/* The group of this thread */

private ThreadGroup group;

/* The context ClassLoader for this thread */

private ClassLoader contextClassLoader;

/* The inherited AccessControlContext of this thread */

private AccessControlContext inheritedAccessControlContext;

/* For autonumbering anonymous threads. */

private static int threadInitNumber;

private static synchronized int nextThreadNum() {

return threadInitNumber++;

/* ThreadLocal values pertaining to this thread. This map is maintained

* by the ThreadLocal class. */

ThreadLocal.ThreadLocalMap threadLocals = null;

/*

* InheritableThreadLocal values pertaining to this thread. This map is

* maintained by the InheritableThreadLocal class.

ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

* The requested stack size for this thread, or 0 if the creator did

* not specify a stack size. It is up to the VM to do whatever it

* likes with this number; some VMs will ignore it.

private long stackSize;

* JVM-private state that persists after native thread termination.

private long nativeParkEventPointer;

* Thread ID

private long tid;

/* For generating thread ID */

private static long threadSeqNumber;

/* Java thread status for tools,

* initialized to indicate thread 'not yet started'

private volatile int threadStatus = 0;

/**

* If this thread was constructed using a separate

* <code>Runnable</code> run object, then that

* <code>Runnable</code> object's <code>run</code> method is called;

* otherwise, this method does nothing and returns.

* Subclasses of <code>Thread</code> should override this method.

* @see #start()

* @see #stop()

* @see #Thread(ThreadGroup, Runnable, String)

@Override

public void run() {

if (target != null) {

target.run();

''''''''此處省略眾多方法和屬性。

從上面的源碼可以看出:Thread實現了Runnable接口,提供了更多的可用方法和成員而已。

總結

Runable是一個接口,Thread是其實現類,只是具有很多自己獨特的屬性和方法。二者談區別沒有可比性。無論使用Runnable還是Thread,都會new Thread,然後執行run方法。用法上,如果有複雜的線程操作需求,那就選擇繼承Thread,如果只是簡單的執行一個任務,那就實現runnable。如果面試官問到你這個問題,把真相告訴他,你想看面試官目瞪口呆嗎?

相關焦點

  • 你怎麼給超人和蝙蝠俠勸架?面試官再問奇葩問題,就這樣回答他
    朋友大周跟我說,六月初自己去一個做軟體的公司面試的時候,HR問了自己一個奇葩問題:你相信中醫嗎?大周以為自己聽錯了,心想自己面試的公司是做軟體的,怎麼跟中醫扯上關係了,一時走了神,不知該怎麼回答。見大周有點愣神,HR又問了一遍:你相信中醫嗎?
  • 騰訊面試題:怎樣把剃鬚刀賣給張飛?專業答案不如網友
    騰訊公司曾經有一道很出名的面試題,聽說這道題最近又重出江湖,又有公司開始使用這道題。這個面試題說的是:如何把剃鬚刀賣給張飛。看起來這是一道銷售題目或者創意題,實際上,考察的是面試者是否有創新思維和思考的能力。
  • 面試官:「立」字加一筆是啥字?美女巧妙回答,贏得全場最佳
    很多人看人標準是:邪正看鼻眼,真假看嘴唇,功名看器宇,事業看精神,主意看腳跟,若要看條理,全在言語中。HR們深知古人的智慧,在面試時選拔人才的時候,也會通過提問來觀察面試者各個方面的表現,最終才決定是否錄取。
  • 面試官:三橫三豎三撇三捺是什麼字?本科生3秒回答,被錄取
    本科生3秒回答,被錄取現在面試者認為:只要自己專業知識過關就可以被公司錄取上班了,這樣想未必太單純了一點,因為現在面試者那麼多,面試官肯定不止從專業知識上考試,還會從其他地方測試你的臨場發揮能力、邏輯思維判斷能力、情商等等一系列的問題,來選擇適合公司的優秀人才。所以面試者千萬不要粗心大意,有可能就是一道智力測試題就會把你拒之門外,比如今天的一道面試題:三橫三豎三撇三捺是什麼字?
  • 面試官:「葉」字加一筆,你能想到什麼字?回答吐字的全被淘汰
    相信大家都知道,進入職場的必須要經歷面試這一關,面試說嚴格又不是很嚴格,只要你腦子靈活,懂得隨機應變面試不是問題,畢竟每個公司都需要人。事實上,如今五花八門的面試形式以及面試官的一些「費盡心思」問題,給面試場上帶來了許多有趣的事情,今天就給大家分享一個面試場上的故事。這是一家上市網際網路的招聘故事:這一天,許多人收到了上市公司面試的邀請,前來面試。面試官們剛開始只是問了一些和其他公相類似的問題,求職者們各個都巧舌如簧,滔滔不絕。
  • 面試怎麼面,才會讓你事半功倍?站在面試官的角度,給你幾條建議
    今天,木辛君為你請教擁有十幾年招聘經驗的HR招聘達人,為你總結要讓面試官「相中你」幾個面試方向:搞清楚面試官每一個行為背後的用意,面試才能一擊即中在說具體方法之前,我先來介紹一下我的這位前輩,作為HR界的老油條,他擁有十五年面試經驗。前段時間因為公司有招聘任務,我也有幸與他組成面試團去進行校招,從中學到不少的經驗。
  • 女面試官:「八」字加一筆,變成什麼字?博士生高情商回答被錄取
    在面試時,面試官都會向應聘者發問,以此考察面試者的軟硬實力。商場如戰場,現在社會,職業競爭非常激烈。因此,不少公司的面試也是嚴格把關,只為找到更好的人才。所以,很多面試官,通常會準備一個終極武器,出一道奇葩面試題來考驗面試者。
  • 面試官:杯子裡水滿了,你想對我說什麼?小夥的舉動被當場錄用!
    得到一份工作的第一道坎就是要通過面試,對於面試很多剛剛步入社會的面試者常常以為,面試官會提問專業方面的知識,或者讓你做些試卷,如果面試者是這個想法的話那就大錯特錯了,現在的面試官都是喜歡出怪招,老是從各個方面出問題考你。
  • 面試官:「個」字添一筆,是什麼字?小夥高情商回答,最終被錄取
    就拿求職面試這件事來說,很多面試官,現在面試的一些套路真的是別出心裁,各種各樣的問題,簡直能問到你懷疑人生。HR們深知古人的智慧,在面試時選拔人才的時候,也會通過提問來觀察面試者各個方面的表現,最終才決定是否錄取。這是某著名公司面試高級營銷人才的現場,女面試官是位30出頭、氣質極佳的職場精英。
  • 面試官:給隻字多加一筆,變成什麼字?九成面試者被難倒
    01遇到旗鼓相當的面試者,HR竟然這麼做很多人都經歷過面試,而每個人遇到的面試機會也不同,不同的考官更是會出不同的問題來考驗應聘者。在面試的過程中,我們也時常會遇到旗鼓相當的對手,面試官常常會在這些人中選擇更優的人。這個時候就會需要一個特殊的問題,讓面試官更了解你。
  • 面試官:布和紙最怕什麼?小夥神回復徵服面試官
    進入社會要受到許多的磨練,才能成為別人眼中的職場精英,但是在這之前最主要的便是通過公司的面試,無論是國企或者私企,面試都是衡量一個人能力的重要前提,很多面試者在應聘之前會提前了解一下公司,準備一下常規類型的面試題,但是不乏有一些公司,在面試的過程中會出一些奇葩的面試題來考驗他們的臨場反應能力,而有的面試者可能會被這種奇葩問題搞得不知所措,最終淘汰。
  • 女面試官:「只」字加一筆會是什麼字?大學生的回答很機智!
    面試是進入職場的第一步,也是初步決定求職者能獲得什麼樣的工作。當今社會,一企業為了招聘到更好的員工,面試的時候,一些奇葩的問題也是屢出不窮,面試官考驗的,更多的是你在臨場的時候應變能力夠不夠強。其實一個人專業能力在好,也不能代表這個人就非常的適合這份工作,面試官的作用是去考察每一位面試者的各個方面,在眾多的人才中挑出適合人。這是某著名公司面試高級營銷人才的現場,女面試官是位30出頭、氣質極佳的職場精英。為了考核在場3位求職者的臨場應變能力,便給他們出了這樣一道面試考核題:「「只」字加一筆,會是什麼字?」
  • 女面試官:「王」字加一筆是什麼字?回答主字和玉字,都沒有錄用
    面試過程中,面試官會向應聘者發問,用來考察面試者的軟硬實力,如果面試者的實力強大,面試官則會讓面試者留在公司,如果面試者畏畏縮縮,面試官只能讓面試者退出面試室了!但有時候,面試者實力並非懸殊到能夠一眼看出來的局面,面試官則會拿出殺手武器,出一道奇葩面試題考察面試者的實力!
  • 面試官:60秒跑10千米,行嗎?小夥機智回答:我只要1秒
    相信很多求職者都有這樣一個經歷,那就是好不容易到了面試環節,但是由於面試官的提問太過刁鑽,讓很多人都失去了這份工作,然而,面試官出題絕不是隨便出的,而是經過深思熟慮,出的都是能夠直接考察你能力的題目,所以如果你三心二意的回答或者是不重視,就很有可能被淘汰的!
  • 面試官:「午」字加一筆是什麼字?回答牛字的全被淘汰
    當然,面試官也想得非常的周全,他們之所以出這樣的題,其實就是能夠快速的看清一個人的能力。畢竟現在找工作的人特別的多,而很多公司,也都進入了自動化,對人員的把控也相當的提高了。王鵬是今年剛畢業的大學生,經過一番投遞簡歷,終於收到一家公司的考試邀請。經過了筆試的選拔,王鵬和幾個人一起去到了面試場。面試官是一位中年的男老師。
  • 女面試官:「米」字加一筆,是什麼字?研究生回答「採」卻被淘汰
    相信,很多人在找工作面試過程中,多少都會遇到一些挫折。畢竟每年的大學生都那麼多,所以企業對求職者越來越嚴格,大部分面試官在面試時,都會出些我們想不到的題,其實這些都是為了考核求職者們在沒有任何準備情況下,如何展示自己的才能和處理方法。
  • 面試官:「口」字去一橫,是什麼字?大專生機智回答被當場錄取
    當然這裡不是說對學習有歧視,只是這名牌大學的畢業生,樣樣都是優秀,卻被這樣一道奇葩題給難住了,還輸給了一個沒有上過大學的大專生,心裡很是不服氣。今天我們一起來看看周偉遇到的這個奇葩題目吧!經過了兩輪的專業考核後,最後面試官給他們出了一道題:「口」字去掉一橫是什麼字?
  • 面試官:一隻螃蟹8條腿,100隻呢?回答800條的,當場出局
    在如今的面試中,面試者們往往會被問到各種各樣奇怪的問題,只是因為找工作的競爭越來越激烈,往往一個崗位會有很多的人同時競爭,所以面試官要用儘量省時省力的方式來考察人才,因此就會選擇這樣的方式。
  • 面試官:3,3,8,8怎麼算出24?小夥立刻被錄用
    如今的面試官會竭盡全力為公司的合適職位選擇合適的人選。他們不滿足於簡單的出題,而是另闢蹊徑,希望用最簡單的方式考查考生的綜合能力。我們今天要討論的是面試官會問的一個奇怪的問題:你如何用3,3,8,8來算出24?你有答案嗎?我們一起看吧。
  • 面試官:木字多一筆,是啥字?小夥機智作答,面試官紛紛鼓掌
    但實際上,現在的學歷早就不是面試官衡量這個人能力的唯一標準了。面試官會專門設計一些話題來考驗你的綜合素質,以及情商和思維變通能力。小王是一名剛剛畢業的大學生,小王的學歷雖然不是很高,只是一般的本科,但是腦子很機靈,是一個聰明人。在參加一家公司的面試的時候,經過幾輪的專業知識測試和面試,進入最後一關的只有4個人。