工作一年多,技術增長緩慢,近期面試總結出兩道經典高頻題:Git 版本回退衝突處理、單向鏈表無頭指針刪除當前節點。記錄思路與標準答案,供後續複盤。
提交歷史:A → B → C(當前 HEAD)。需回退到版本 A,並推送到遠程倉庫,其他開發者已拉取 C 版本。
# 1. 本地硬回退到版本 A git reset --hard <commit-id-of-A> # 2. 強制推送到遠程(覆蓋歷史) git push -f origin <branch-name>
現象:其他開發者再次 git pull 時會報錯,提示「非快進」或歷史分歧。
原因:遠程歷史被重寫,本地仍有 C 提交,Git 拒絕合併不相關歷史。
解決方案(由團隊協商統一):
git fetch origin && git reset --hard origin/<branch>,強制同步遠程歷史,丟棄本地未推送提交。git pull --rebase 或手動 cherry-pick 自己未推送的提交到新基線上。git revert <commit-id-of-C> ... <commit-id-of-B> 創建反向提交,歷史不重寫,無衝突風險。reset --soft/mixed/hard 對工作區、暫存區、HEAD 的影響。push -f 風險:團隊協作中嚴禁對公共分支強推,除非協同清理。reflog 可恢復誤操作的提交。給定單向鏈表節點 B(非尾節點),無法訪問頭節點 A,僅持有 B 的引用,如何刪除 B?

嘗試修改 A 的 next 指向 C。但無法訪問 A,不可行。
核心思想:將下一節點 C 的數據複製到 B,然後刪除 C。邏輯上等價於刪除 B。
public void deleteNode(ListNode node) {
// 前提:node 非尾節點
ListNode next = node.next;
node.val = next.val; // 複製數據
node.next = next.next; // 跳過 next
// next 成為垃圾對象,等待 GC
}

最終鏈表:A → B'(原C數據) → D。原 B 數據被覆蓋,原 C 節點被跳過。
== 比較、作為 Map Key),會出現邏輯錯誤。直接操作 node.prev.next = node.next; node.next.prev = node.prev;,O(1) 且無數據複製副作用。