面試官:你在學校用過AI 嗎?我:禁用,被說學術不端。 。他皺眉:我們這兒規定75% 代碼靠AI,不用才是學術不端。 。

畢業那天,你學的東西就被推翻了

最近鴨鴨在脈搏看到一條提問,看完後愣了一下:

“為什麼大學禁止用AI,而公司要求全用AI?”

發文的是一位前科大訊飛的工程師,問題特別簡單,但底下90 多則評論吵得很兇。鴨鴨把評論區出現頻率最高的幾種說法歸納一下

有人上來就開噴:

“學校連個像樣的AI 課都沒有,畢業了又罵學生不會用AI,這套邏輯我服了。”

也有人替學校說話:

「不讓用是為了你好。你連print 都不會寫,AI 替你寫完,你以為你會了,其實啥也不會。”

還有最戳的一條:

“學校教你做人,公司教你做事。這兩件事在AI 這件事上,正好反過來了。”

最後這句話,鴨鴨看完後特別想拍大腿。

而且這真不是個段子。鴨鴨翻了下這兩個月的新聞:

去年底,復旦大學正式發布《關於在本科畢業論文(設計)中使用AI 工具的規定》,明確六個禁止,情節嚴重的可以撤銷學位(澎湃新聞有專訪報道)。中國傳媒大學、華北電力大學、湖北大學也跟著發了類似通知,學校這邊,AI 幾乎被視為作弊工具。

而企業那邊,4 月初澎湃新聞一篇《大廠“牛馬”,被迫用AI》直接把另一面端出來:有人被統計每天燒多少Token,有人公司發的AI 額度用不完會被回收帳號,有人Leader 直接強制“所有產出都得先讓AI 生成一版”。前兩週,老黃也在英偉達內部發話:全員必須用Codex。

4 月的應屆生,剛交完論文證明這是自己一字一句寫的,5 月初入職第一天,Leader 就問他:你Cursor/Claude/Copliot 裝了嗎?

中間隔的,可能就一張機票的距離。

說實話,鴨鴨一開始也覺得這是教育落後於產業的老問題。但後來想想,沒那麼簡單。

學校和公司在防的,根本不是同一個東西。

學校真正在防的,是身分冒名。老師佈置一篇論文,本質上是在讓你證明這些字、這些代碼、這些推導是你腦子過的,不是別人代筆的。 AI 出現以前,老師防的是抄襲、防的是代寫;AI 出現以後,老師防的是你把腦子外包給了模型。

所以學校的邏輯很清楚:考核的是原創性,AI 在這條線上等同於作弊。

公司真正怕的,是你產出跟不上。它不在乎那段程式碼是Cursor 寫的還是你手敲的,只看一件事,今天能不能上線、今晚能不能修bug。AI 替你寫了80% 還能跑,老闆高興;你自己慢慢敲到深夜,老闆下次績效給你打3.5。

你看,學校在按過程評分,公司在按產出算錢。兩邊的考核函數完全不一樣,AI 的角色當然就反過來了。

更尷尬的是沒人會告訴你這兩套規則的差異。學校老師不會說你畢業後這套規則就作廢了,公司HR 也不會跟你解釋為什麼之前你被罰的事情現在變成了KPI。你只能自己悄悄完成這次切換,並假裝沒發生過任何衝突。

那這種切換裡,誰吃虧最大?

不是不會用AI 的同學,他們工作兩個月就能補上。

是那些把原創性當作信仰的好學生。

那些在大學裡堅持古法程式設計、每篇論文自己讀,把原創性看得比交付速度更重要的同學,進了公司之後,會經歷一段非常痛苦的認知重塑。因為公司不獎勵原創,公司獎勵交付。

鴨鴨自己剛畢業那會兒就是這樣,特別看不上用工具糊弄的同事,結果半年後才發現,那些同事的產出比鴨鴨多三倍,績效比鴨鴨高一檔。

那這件事到底該怎麼辦?鴨鴨不打算給三條客套建議,就說三個真實的轉變:

  • 大學階段,AI 當老師用,不當槍手用。讓AI 跟你講知識點、出測驗題、Review 你寫的程式碼,但別讓它替你寫論文。這樣你畢業不會掛,工作之後也能馬上切換。

  • 找工作面試前,準備好怎麼講清楚自己是如何用AI 的。不要只說會用Cursor,要能說清哪一步讓AI 做、哪一步自己做、為什麼這麼分。這是2026 年應屆生面試的隱藏關卡。

  • 入職後第一周,主動去問老員工團隊的AI 工具棧是什麼。不要等leader 來安排,AI 工具的使用習慣屬於看不見的入職門檻,越早上手,越早擺脫應屆生那個標籤。

最後說一句鴨鴨自己的看法。

學校禁AI 不一定錯,公司逼AI 也不一定對。真正錯的,是沒人幫應屆生處理這中間​​的認知斷層。

你能做的,就是自己提早兩年開始切換。等別人還在為學術不端嚇得不敢碰AI 的時候,你已經在用AI 幫自己刷題、模擬面試、寫履歷、改面經了。

畢業那天的差距,就是這兩年存出來的。

你們怎麼看這事?大學和公司的AI 規則,你覺得到底誰比較對?評論區聊聊。

今天鴨鴨和大家分享一道後端場景題面試題。

【寫一段程式碼,使得這段程式碼必定會產生死鎖,不能使用Thread.sleep() 】

回答重點

關鍵是要確保兩個線程同時持有各自的鎖,然後再去爭搶對方的鎖,這樣就能穩定復現死鎖。

CountDownLatch就能做到。

核心思路是:

  1. 建立一個計數為2 的CountDownLatch

  2. 線程1 先拿到lock1,執行countDown 減一,然後await 等待

  3. 線程2 先拿到lock2,執行countDown 減一,然後await 等待

  4. 兩個執行緒都到達await 後,同時被喚醒

  5. 線程1 想要lock2,但lock2 被線程2 持有

  6. 線程2 想要lock1,但lock1 被線程1 持有

  7. 互相等待對方釋放鎖,死鎖必然發生

程式碼實作:

簡介 java.util.concurrent.CountDownLatch;

publicclassGuaranteedDeadlock {privatestaticfinalObjectlock1=newObject();privatestaticfinalObjectlock2=newObject();privatestaticfinalCountDownLatchlatch=newCountDownLatch(2);

公共靜態voidmain(字串[] 參數){Threadthread1=newThread(() -> {同步(鎖1){System.out.println(“線程1:持有鎖1…”);latch.countDown(); // 讓thread2 也開始執行try { latch.await(); } catch (InterruptedExceptione) { e.printStackTrace(); } // 確保兩個執行緒同時競爭

同步(鎖2){System.out.println(“線程1:獲得鎖2!”);}}});

Threadthread2=newThread(() -> {同步(鎖2){System.out.println(“執行緒2:持有lock2…”);latch.countDown(); // 讓thread1 也開始執行try { latch.await(); } catch (InterruptedExceptione) { e.printStackTrace(); } // 確保兩個執行緒同時競爭

同步(鎖1){System.out.println(“線程2:獲得鎖定1!”);}}});

線程1.start();線程2.start();}}

除了CountDownLatch,也可以用CyclicBarrier實現同樣的效果。

擴展知識為什麼簡單的交叉加鎖無法保證死鎖

很多人第一反應會寫出這樣的程式碼:

publicclassDeadlockExample {privatestaticfinalObjectlock1=newObject();privatestaticfinalObjectlock2=newObject();

公共靜態voidmain(字串[] 參數){Threadthread1=newThread(() -> {同步(鎖1){System.out.println(“線程1:持有鎖1…”);//試圖取得lock2同步(鎖2){System.out.println(“線程1:獲得鎖2!”);}}});

Threadthread2=newThread(() -> {同步(鎖2){System.out.println(“執行緒2:持有lock2…”);// 試圖取得lock1同步(鎖1){System.out.println(“線程2:獲得鎖定1!”);}}});

線程1.start();線程2.start();}}

上面這段程式碼看起來會死鎖,實際上死鎖發生的機率遠遠不是100%。

問題就出在線程調度的不確定性上。

Java 的執行緒調度由作業系統決定,執行順序完全無法預測。

很可能線程1 在線程2 啟動前就已經快速拿到了lock1 和lock2,執行完畢釋放了鎖,線程2 再啟動時不會遇到任何阻塞,壓根就不會死鎖。

想要穩定復現死鎖,必須讓兩個線程先分別持有自己的鎖,然後同時去爭搶對方的鎖。

CountDownLatch 的功能就是控制這個時機,讓兩個執行緒在各自持有鎖之後互相等待,等雙方都準備好了再同時往下執行,這樣就能保證100% 死鎖。

CountDownLatch 和CyclicBarrier 的區別

CountDownLatch 是倒數計時門閂,構造時傳入一個計數值,每次調用countDown()減一,計數歸零時所有調用await()的執行緒同時被喚醒。特點是一次性使用,用完就廢了。

CyclicBarrier 是循環柵欄,構造時傳入一個參與線程數,每個線程調用await()後會阻塞,直到所有線程都到達柵欄位置,然後一起被釋放。特點是可以重複使用,釋放後會重置計數,可以繼續使用。

對於製造死鎖來說,兩者都能用,但CountDownLatch 更直觀,因為它天然就是”等所有人準備好再一起開始”的語義。 CyclicBarrier 也可以,但它的重置特性在這裡用不上。

如何偵測並避免死鎖

線上環境如果懷疑發生了死鎖,可以用jstackjconsole查看執行緒堆疊,JVM 會自動偵測死鎖並在堆疊資訊中標註出來。

避免死鎖的常見手段:

1)加鎖順序一致:所有執行緒依照相同的順序取得多個鎖,例如都先拿lock1 再拿lock2,這樣就不會出現循環等待。

2)嘗試加鎖逾時:用ReentrantLock.tryLock(timeout)替代synchronized,拿不到鎖就放棄已持有的鎖,過一會兒重試。

3)減少鎖粒度:不要一把大鎖鎖住整個方法,盡量縮小鎖的範圍,減少持有鎖的時間。

4)避免嵌套加鎖:如果業務允許,盡量不要在持有一把鎖的情況下再去取得另一把鎖。

篇幅有限,完整答案可以點選下方小程式查閱

我們精選了近兩年的高頻面試真題,已經有10000 多題目啦,由大廠資深面試官手寫答案,押題命中率超高!

不只傳統八股文,場景題、專案題、系統設計題等等應有盡有,還在不斷更新中!

目前優惠最低特價129 元即永久(限時上架)暢看所有面試問題和答案,正式營運價格為399+,不要錯過這次優惠哈!

並且,現在邀請好友報名成為會員,還可獲得10% 的分傭!詳情請見面試鴨拉新邀請有賞規則(網頁版面試鴨點擊頭像查看)

網頁端網址:www.mianshiya.com

分享你的喜愛