畢業那天,你學的東西就被推翻了
最近鴨鴨在脈搏看到一條提問,看完後愣了一下:
“為什麼大學禁止用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就能做到。
核心思路是:
-
建立一個計數為2 的CountDownLatch
-
線程1 先拿到lock1,執行countDown 減一,然後await 等待
-
線程2 先拿到lock2,執行countDown 減一,然後await 等待
-
兩個執行緒都到達await 後,同時被喚醒
-
線程1 想要lock2,但lock2 被線程2 持有
-
線程2 想要lock1,但lock1 被線程1 持有
-
互相等待對方釋放鎖,死鎖必然發生
![]()
程式碼實作:
簡介 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 也可以,但它的重置特性在這裡用不上。
如何偵測並避免死鎖
線上環境如果懷疑發生了死鎖,可以用jstack或jconsole查看執行緒堆疊,JVM 會自動偵測死鎖並在堆疊資訊中標註出來。
避免死鎖的常見手段:
1)加鎖順序一致:所有執行緒依照相同的順序取得多個鎖,例如都先拿lock1 再拿lock2,這樣就不會出現循環等待。
2)嘗試加鎖逾時:用ReentrantLock.tryLock(timeout)替代synchronized,拿不到鎖就放棄已持有的鎖,過一會兒重試。
3)減少鎖粒度:不要一把大鎖鎖住整個方法,盡量縮小鎖的範圍,減少持有鎖的時間。
4)避免嵌套加鎖:如果業務允許,盡量不要在持有一把鎖的情況下再去取得另一把鎖。
篇幅有限,完整答案可以點選下方小程式查閱:
我們精選了近兩年的高頻面試真題,已經有10000 多題目啦,由大廠資深面試官手寫答案,押題命中率超高!
不只傳統八股文,場景題、專案題、系統設計題等等應有盡有,還在不斷更新中!
目前優惠最低特價129 元即永久(限時上架)暢看所有面試問題和答案,正式營運價格為399+,不要錯過這次優惠哈!
並且,現在邀請好友報名成為會員,還可獲得10% 的分傭!詳情請見面試鴨拉新邀請有賞規則(網頁版面試鴨點擊頭像查看)
![]()
網頁端網址:www.mianshiya.com
![]()