淺談 Heap - 1. 介紹與實作

淺談 Heap 資料結構 前言 這個系列會紀錄我在 Leetcode 上複習的一些常見的東西。基本上會跟著探索卡的進度走。雖然這系列應該早就在課堂上學會了,但我就豆腐腦,雖然已經理解了,但是只要一過一段時間,記憶就這樣被回收了,我都懷疑我腦袋有一個GC回收器… 優先佇列 (Priority Queue) 再講 Heap 之前,要先介紹一下優先佇列 Priority Queue: 既然優先佇列的名稱裡都有佇列了,那他肯定跟佇列有關係對吧? 優先佇列就像是普通的先進先出(FIFO)的佇列一樣,但是其每個元素都有優先權(Priority)這個變數,優先佇列的特點就是:優先權較高者的永遠會先被處理,如果對 Heap 有印象的人,看到現在應該知道為什麼要先介紹優先佇列了。 那要怎麼實現 Priority Queue 呢? Priority Queue 就如同佇列一樣有兩個關鍵方法:push()、pull() 如果將元素存放在一個未排序列表中, 那push() 操作正常來說只需要O(1)就能完成,因為只是單純的將元素推到這個列表的最後端,範例如下: func push(n *Node) { unsortedList = append(unsortedList, n) } 但是pull()操作呢? 正常來說需要O(n)時間,也就是需要遍歷完整個列表,範例如下: func pull() *Node { if len(unsortedList) == 0 { return nil } maxIndex, highest := 0, unsortedList[0] for i := 1; i < len(unsortedList); i++ { if highest.Priority < unsortedList[i].Priority { highest = unsortedList[i] maxIndex = i } } // remove highest item unsortedList = append(unsortedList[:maxIndex], unsortedList[maxIndex + 1:]....

February 12, 2022 · 3 min · Aitay

臺中科大 110 學年度行事曆

臺中科大 110 學年度日間部行事曆 今天在校對生成的日曆時,看到110學年度下學期的日曆,不禁有一些感慨,就像是國中升高中,高中升大學,等到意識到要畢業了,才發現自己過去這幾年不知道都在幹啥。 大學生活裡,最後悔的是大一,許多時間都被浪費掉了,現在想想如果善用那些時間,或許可以把自己的程度提升更多。如果有剛入學的大一新生看到這篇文章的話,希望各位可以善用時間去提升自己的能力,不要像我一樣只會耍廢哈哈。 我想抱怨的話就到此結束了吧,時間也都回不去了。 行事曆 以下提供的行事曆都以臺中科大官網為主。 日曆的活動類型都為全天活動,建議設定通知時間 共用連結 110-1臺中科大日間部行事曆 110-2臺中科大日間部行事曆 公開網址 110-1臺中科大日間部行事曆 110-2臺中科大日間部行事曆 iCal 格式公開網址 110-1臺中科大日間部行事曆 110-2臺中科大日間部行事曆 Q&A 我想可能會有人問說:為什麼不開源給其他人自己生成? 這是因為每學年(甚至同一份文件)學校官網提供的pdf文件在格式上都會有一點差異,加上我懶,這份程式碼還停留在兩三年前的版本,不保證在未來一定能夠使用,所以不開源。 給有興趣的人參考,使用語言:Python3,需要安裝的套件:pdfplumber 結語 雖然前幾年都有生成這類型的日曆,但想說最後一年了就分享出來給需要的人,如果有幫助到你們的話,那我花費的時間也會讓我比較心安理得了😂

July 16, 2021 · 1 min · Aitay

Hugo 添加 Google Analytics 4 筆記

Hugo 添加 Google Analytics 4 筆記 前言 最近HUGO更新了0.82.0版本,此版本對比上一版本改進不大,對我來說,最有感的應該是增加了內置Google Analytics 4的支持,也就是可以使用G-開頭的評估ID而不是UA-開頭的追蹤ID,那首先就來回顧一下Universal Analytics(GA3)與Google Analytics 4。 GA4 x GA3 GA3 (Universal Analytics) UA於2012年10月發布,在上一代GA中,主要以網站會話(session)以及網站頁面為主,資料的來源主要從三個管道收集 HTTP請求 瀏覽器/系統資訊 第一方Cookie 其中,我們最容易見到的是帶有utm開頭參數的連結,範例如下 http://example.com/?utm_source=active%20users&utm_medium=email&utm_campaign=feature... 這種分享連結後方都會添加一些utm開頭之參數,這個utm參數會記錄其來源、媒介、名稱,等到使用者造訪網站時,在網站上嵌入的UA會去收集這些參數並發送至Google Analytics,讓網站管理者檢視、分析成效。 上方的範例僅限於使用者是被哪個社群網站、哪個廣告以及從哪個來源(e.g. email、app)吸引而進入網站,那如何去收集使用者在網站內部的活動呢😶? UA擁有許多不同匹配去收集使用者在網站內部的活動,這邊介紹最常見的三種: 網頁瀏覽匹配 使用者載入嵌有UA的頁面時便會觸發此匹配,是最常觸發的操作。 事件匹配 追蹤使用者在網站上特定元素的每次互動,例如:開啟的網址、播放的影片等。 交易匹配 傳送電子商務購買的相關資料,例如:售出的產品、交易ID、庫存計量單位(SKU)等等。 除上述三種之外也有許多其他匹配,像是社交匹配、網頁操作時間匹配等 GA4 (Google Analytics 4) GA4於2020年10月16日發布,在這一代GA中,主要採用以事件(event-based)的方式去收集資料,相較於上一代GA3,GA4提供了更彈性、更智慧、跨平台的數據蒐集方法。 GA4與GA3同樣都使用gtag.js向Google Analytics發送事件數據。 在以往的GA3,如果想要評估App端上的使用數據,必須使用Google Analytics for Firebase或是Google Analytics APP view建立不同的GA資源(Property),想要結合網頁端及App端的使用數據相對來說是較不容易的。 GA4 整合了 Web 端及 APP 端的資料,並可以將其結合在一起進行分析,也可以單獨蒐集網站上的資料。 GA4默認提供了六種增強性評估 網頁瀏覽 捲動 外連點擊 站內搜尋 影片參與 檔案下載 若要詳細了解GA4的功能及比較,可至【一表看懂】新版 GA4 與舊版 GA 差在哪裡?新舊版本功能比較懶人包! TL;DR:新版GA4相較於上一代GA3更彈性、更智慧(後臺方面)、跨平台,但GA3上有的功能並不一定在GA4上可以找到替代品,若是打算由GA3遷移到GA4,可保留GA3和GA4兩者。不過對於Hugo使用者來說,不管是選擇GA3或是GA4都應該可以達成目的。...

March 26, 2021 · 1 min · Aitay

如何將Hugo部落格部署到Github上?

手把手教學: 將Hugo部落格佈署到Github上 前言 最近將以前的部落格從Hexo遷移到Hugo上了,不得不說Hugo在產生靜態頁面的速度比起Hexo來說快了很多,得益於Hexo跟Hugo都是使用Markdown文件的原因,在兩者之間進行遷移是非常容易的,今天就來為自己做個筆記,希望大家看了這篇文章後,沒有部落格的都可以嘗試建立一下自己的部落格。 教學開始 這邊安裝的Hugo版本為hugo v0.81.0,環境為Win10 20H2 x64,使用的工具為git與chocolatey,若是macOS,則可以使用Homebrew,Linux的部分則在這邊下載 第一步,安裝Hugo 這邊主要就照著官方的快速開始建立部落格,因為官方已經寫的足夠清楚了,所以在此處僅寫Windows版本的安裝過程 如果要安裝普通版本的Hugo,請使用以下指令 choco install hugo -confirm 如果要安裝Sass/SCSS版本的,請使用以下指令(有些主題會要求需要hugo-extended版本) choco install hugo-extended -confirm 第二步,建立部落格 安裝完Hugo後,可以使用hugo version確認是否安裝成功。 安裝成功後,在你想要建立部落格的資料夾內打開powershell,並打以下指令即可建立。 hugo new site <資料夾名稱> 出現以下畫面就說明安裝成功了! 第三步,添加主題 接下來到官方的主題網站挑選您喜歡的主題,此範例使用ananke主題。 只需要打以下指令就可以新增主題了 cd <資料夾名稱> git init git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke 接著修改config.toml文件,詳細的設定方式可以參照官網 # 基本設置 baseURL = "<網址>" title = "<標題>" languageCode = "en-us" # 主題設置 theme="ananke" # 連結設置 [permalinks] posts = "/:year/:month/:title/" 第四步,建立第一篇貼文 接著輸入以下指令建立第一篇貼文 hugo new posts/hello-world.md 接著打開Markdown編輯工具(e.g. Visual Studio Code),寫點簡單的文章並存檔。...

March 21, 2021 · 2 min · Aitay

Golang Redis Ratelimiter

令牌桶演算法實現 前言 這幾天將令牌桶限流演算法使用gin + redis實現了,今天主要要來講整個限流過程是如何運作的。 Github連結 主要定義了四個文件 文件名 描述 dto.go 定義及宣告Ratelimiter的基本結構與核心Take()方法 err.go 定義了一些錯誤 ratelimiter.go 存放gin middleware中驗證的邏輯 script.go 存放 lua 腳本及 lua 腳本中輸入變數的結構 我們會將上次更新的時間與剩餘令牌的數量儲存在Redis中,而主要更新的邏輯會寫在script.go,這裡會發現整個操作Redis資料庫的邏輯是使用lua script去實作的,把多個操作Redis的指令包在lua script中,Redis會保證lua script中的多個操作會以Atomic的方式進行,這樣才可以保證每個操作之間不會有競爭情況(Race Condition)發生。 參考資料 程式碼部分 Golang 接下來就進入到程式碼的部分 首先我定義了 RedisRateLimiter 結構 dto.go type RedisRateLimiter struct { context context.Context scriptSHA1 string client *redis.Client } 這邊將RedisRateLimiter的一些必須用到的變數包裝起來,包裝的變數型別包含了Redis客戶端、LUA Script SHA1(後續會使用evalsha調用已經讀進Redis腳本緩存的Lua script)、Goroutine context。 這個Repository實現的演算法是Token Bucket演算法,不過也可以利用上述定義的結構去實現不同算法,例如:Leaky Bucket。 dto.go type TokenBucketRedisRateLimiter struct { RedisRateLimiter identifier string interval time.Duration maxRequest int } func (r *TokenBucketRedisRateLimiter) Take(request TokenBucketLuaRequest) *LimiterResponse { result, err := r....

March 16, 2021 · 3 min · Aitay