畢業那天,你學的東西就被推翻了
最近鴨鴨在脈脈看到一條提問,看完后愣了一下:
“為什么大學禁止用 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 持有
互相等待對方釋放鎖,死鎖必然發生
![]()
代碼實現:
importjava.util.concurrent.CountDownLatch;
publicclassGuaranteedDeadlock {
privatestaticfinalObjectlock1=newObject();
privatestaticfinalObjectlock2=newObject();
privatestaticfinalCountDownLatchlatch=newCountDownLatch(2);
publicstaticvoidmain(String[] args) {
Threadthread1=newThread(() -> {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock1...");
latch.countDown(); // 讓 thread2 也開始執行
try { latch.await(); } catch (InterruptedExceptione) { e.printStackTrace(); } // 保證兩個線程同時競爭
synchronized (lock2) {
System.out.println("Thread 1: Acquired lock2!");
}
}
});
Threadthread2=newThread(() -> {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock2...");
latch.countDown(); // 讓 thread1 也開始執行
try { latch.await(); } catch (InterruptedExceptione) { e.printStackTrace(); } // 保證兩個線程同時競爭
synchronized (lock1) {
System.out.println("Thread 2: Acquired lock1!");
}
}
});
thread1.start();
thread2.start();
}
}
除了 CountDownLatch,也可以用CyclicBarrier實現同樣的效果。
擴展知識為什么簡單的交叉加鎖無法保證死鎖
很多人第一反應會寫這樣的代碼:
publicclassDeadlockExample {
privatestaticfinalObjectlock1=newObject();
privatestaticfinalObjectlock2=newObject();
publicstaticvoidmain(String[] args) {
Threadthread1=newThread(() -> {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock1...");
// 試圖獲取 lock2
synchronized (lock2) {
System.out.println("Thread 1: Acquired lock2!");
}
}
});
Threadthread2=newThread(() -> {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock2...");
// 試圖獲取 lock1
synchronized (lock1) {
System.out.println("Thread 2: Acquired lock1!");
}
}
});
thread1.start();
thread2.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
![]()
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.