/ 4 分鐘 / -- VIEWS

AlgoLab 開發紀錄:在瀏覽器裡一步一步看 Python 跑

從 ZeroJudge 練題卡關出發,做一個能貼上自己的 Python 程式、逐步看資料結構與指標變化的演算法視覺化工具,並整理 AlgoLab 的技術架構、核心功能與開發挑戰。

在還沒有深入接觸演算法之前,我一直認為寫程式就是使用 for、if...else、function 等基本語法來完成各種功能,甚至曾經覺得程式設計還能有多困難、多有趣?直到最近開始認真學習資料結構與演算法,我才發現自己以前的想法太簡單了。

原來,學會程式語法只是認識工具,真正重要的是能夠熟練運用這些工具,透過資料結構與演算法有效率地解決問題。這也讓我重新思考,自己距離成為一名真正具備獨立解題能力的軟體工程師,還有哪些能力需要加強。

為了提升自己的程式能力,我開始在 ZeroJudge 練習 Python 解題。剛開始才發現自己的解題能力還有很大的進步空間,有時候連基礎題目都需要花上一、兩個小時才能解出來。並不是不會寫語法,而是以前很少用演算法的思維去分析問題。

雖然學習過程並不輕鬆,但我反而覺得演算法非常有趣。尤其是理解某個解題方法後,發現原本複雜的問題竟然能透過巧妙的思路有效率地解決,這種感覺很有成就感。

後來我也調整了學習方式,從一開始長時間自己摸索,改成先分析題目,再透過 AI 理解演算法的解題思路,最後不看答案重新實作。這樣不僅提升了學習效率,也減少了長時間卡關的挫折感。

不過,在學習的過程中,我發現有些演算法光看程式碼或文字解釋,還是不容易理解,尤其是資料結構的變化、指標移動,以及程式每一步的執行過程。因此,我決定自行開發 AlgoLab(演算法實驗室),希望讓原本抽象的演算法變得更加直觀。

我希望 AlgoLab 不只是展示幾種固定演算法的動畫,而是能讓使用者直接貼上自己的 Python 程式碼,再將執行過程一步一步視覺化。這樣不論是學習新演算法,還是檢查自己寫的程式哪裡出了問題,都能更清楚地觀察程式的運作方式。

目前 AlgoLab 已經基本完成並部署上線。雖然還有許多功能與限制可以持續改善,但能夠把自己學習時遇到的困難,轉化成一個真正可以使用的工具,我覺得非常有意義。

這次開發也讓我體會到,學習程式設計不只是學會使用現有工具,也可以試著創造工具來解決自己遇到的問題。 未來我希望持續精進演算法能力,同時逐步改善 AlgoLab,讓它不只幫助自己,也能幫助其他正在學習演算法的人。

技術架構

Nuxt 4(Vue)+ CodeMirror 編輯器
  ↕ 限定來源的訊息
runner iframe(獨立來源、sandbox)
  ↕ 每次執行建立新的 Web Worker
Pyodide(瀏覽器裡的 CPython)→ sys.settrace 逐行記錄 → 主站回放
  • Pyodide:Python 直接在使用者的瀏覽器執行,不需要後端,也不靠外部 CDN。
  • tracer:用 sys.settrace 在每一行記錄變數、陣列與呼叫堆疊,整理成快照交給主站。
  • 主站:驗證收到的紀錄,再畫成陣列、矩陣、dict、堆疊、佇列、堆積樹等畫面。
  • 部署:Cloudflare Pages,主站與 runner 分開提供。

核心功能

AlgoLab 工作區:二分搜尋程式逐步執行,陣列上標出 mid 指標與 [lo, hi] 區間
AlgoLab 工作區 / 二分搜尋第 11 步,區間縮到索引 4 到 6
  • 貼上自己的程式:單檔 Python,可以用 input() 讀標準輸入;內建二分搜尋、滑動視窗、BFS、DP 等範例。
  • 逐步回放:上一步、下一步、拖曳時間軸跳到任一步,行號、變數和資料結構會同步更新。
  • 指標與區間:nums[i] 這類索引自動畫成箭頭,切片 nums[left:right] 畫成半開區間,標出哪些元素進入、離開。
  • 多種資料結構:一維 list 可以切換陣列、堆疊、佇列、堆積樹畫法,也支援二維 list、dict、set、deque、heapq。
  • 中文步驟說明:列出這一步和前一步相比實際改變了什麼,例如「left 從 0 變成 1,區間左界向右移動」。

開發挑戰與解決方式

執行使用者貼上的程式要安全。 程式跑在獨立來源的 iframe 裡,再放進每次重建的 Web Worker;搭配 CSP 封鎖對外連線,超時就由主站強制終止。限制可用語法只是「支援範圍」,真正的隔離靠的是來源分開。

追蹤資料很容易爆量。 一個迴圈就可能產生上千個步驟,所以我訂了上限:執行 5 秒、2,000 個事件、8 MiB 紀錄。超過時保留已經收到的部分,並清楚標示停在哪裡,不假裝執行成功。

區間沒辦法從程式可靠判斷。 同樣是 left、right 兩個變數,可能是閉區間也可能是半開區間。有切片 nums[a:b] 當證據時,直接畫成半開區間;沒有證據時只列成「區間候選」,讓使用者自己選,不替程式猜意圖。

相關作品 · Live AlgoLab 演算法視覺化實驗室・貼上 Python 程式碼,透過逐步執行、變數追蹤與資料結構視覺化,幫助理解程式邏輯與演算法原理,並能自由控制執行步驟,讓抽象的演算法變得更直觀。

點下去看看會發生什麼事 →

留言 / 想法

有疑問、建議或不同看法?歡迎在下方留言(需要 GitHub 帳號)。