2023 後端面試心得


公開看到這文章,代表的一件事就是:我終於找到工作啦!

從七月以來為期好幾個月的面試過程,面到我都開始懷疑人生了…

以下是我這次的面試一些想法記錄,多半是一些自己的反省

[閱讀全文]

redis-py 源碼分析筆記

這次來研究 redis-py 這個 Python 庫,redis-py 主要功用是提供 Redis 客戶端的介面讓使用者操作 Redis


範例程式碼


先來看看教學文件裡的範例程式碼

>>> import redis
>>> r = redis.Redis(host='localhost', port=6379, db=0)
>>> r.set('foo', 'bar')
True
>>> r.get('foo')
b'bar'

使用者使用 redis.Redis 物件來對 Redis 服務下指令

[閱讀全文]

Pytube 源碼分析筆記

源碼分析筆記系列的文章我想找一些程式碼不算多且有名的 Github Repo,研究其程式碼架構和設計,希望能從中學到一些設計想法,提升自己的能力

不過我不可能記下全部細節,所以只會寫下我覺得有趣的地方

這次找的是 Pytube 這個 Python 庫,Pytube 的功用是用來下載 Youtube 影片

[閱讀全文]

資料庫的 Index 重點筆記

重要名詞

  • Table

    • 邏輯表
  • Row_id

    • 內部系統維護
    • 在某些系統 mysql innoDB 是同 primary key,但在 Postgres 是有個系統欄位 rowid (tuple id)
    • PostgreSQL 的 rowid 正確名稱是叫 ctid,形式是 tuple
  • Page

    • 多筆 row 會存在一個 Logical Page 中
    • 資料庫不是讀單列,而是讀一個或多個 page,在一次 IO 中取得多筆列資料
    • Postgres Page 的大小為 8KB,MySQL Page 的大小為 16KB
[閱讀全文]

Python 的 bit 級操作

在研究一些網路協定時,不乏有許多封包包裝定義,要實作勢必要使用到 bit 級的操作

雖然我工作上多有熟成的工具直接套用,所以都沒什機會用到這類操作,但總覺得還是要熟練一下 bit 操作,然後能自組封包內容,因此有了這篇筆記


Big-Endian v.s. Little-Endian


位元組順序 (Endianness) 分成兩種:

  • Big-Endian 大端序
  • Little-Endian 小端序

大端序最高位元組會存在最低的記憶體位址處,以 0x0A0B0C0D 的 32-bit int 值來說,0x0A byte 會存在記憶體較低的位置,0x0D byte 則會存在較高位置

[閱讀全文]

試使用 gdb 來查看卡住的 Python 程式

如題,此篇文章記錄我如何使用 gdb 來查看一個卡住的 python 程式

過去工作時還真有遇過某段 python 程式碼卡住,然後看了半天看不出個所以然

當時會 debug 卡這麼久,有一個原因是我真的沒想到會卡在寫 log 的地方,如果馬上懷疑是寫 log 的程式碼卡住,大概 Google 一下就會查到這篇文章了吧:https://stackoverflow.com/questions/24509650/deadlock-with-logging-multiprocess-multithread-python-script

簡述一下卡住的原因: 這段程式碼是跑 multithread ,在 thread 上又做了 spawn process 的動作 假設現在有 t1, t2 兩個 thread,當中 t1 fork 生成 child process,若剛好此時 t2 在運行 logging.Handler.handle() critical section,t1 fork 出來的 child process 會複製到鎖住的 log handler lock 狀態,所以這個 child process 一旦要寫 log 就會卡住,因為 handler lock 的狀態是被占用的,而這狀態永遠不會被釋放,程式就這樣卡住了

[閱讀全文]

簡述 HTTP/1 到 HTTP/3 的差異

HTTP 的演化史:

HTTP/1 -> HTTP/1.1 -> HTTP/2 -> HTTP/3


HTTP/1 v.s. HTTP/1.1


HTTP/1 在每一次的請求都必須重新建立 TCP 連線,既費時且耗頻寬,HTTP/1.1 則默認使用 Keep-alive 持久連線,可重複使用同一個 TCP 連線發送 HTTP 請求

HTTP/1 主要使用標頭中的 If-Modified-Since、Expires 來做為緩存的判斷標準,HTTP/1.1 則引入更多緩存控制機制,例如:Etag、If-Unmodified-Since、If-Match、If-None-Match,透過這些可以更優化緩存的實現

HTTP/1 客戶端發送一個請求給伺服器端,需等待伺服器回應後,才可發送第二筆請求,HTTP/1.1 新增 HTTP pipeline 機制,允許讓客戶端傳送多個 HTTP 請求,不用等待之前的請求回覆,如此能讓網頁載入速度變快,但伺服器端必須按照客戶端傳送的請求順序來回覆請求,要維持先進先出的規則,所以有可能發生隊頭阻塞(HOL blocking)的狀況,即因前一筆請求回應耗時,後面的請求都必須延遲回應,另外因為先進先出的規則嚴格難實作,許多瀏覽器都是預設關閉此功能的 (瀏覽器實踐上,為了維持一定的載入速度,會創建多個 TCP 連線來達到平行載入,瀏覽器通常會限制對一個域名同時只能有一定數量的 TCP 連線)

[閱讀全文]

網路安全筆記 (2) 用戶端的漏洞


Corss-Site scripting (XSS)


跨站腳本漏洞通常允許攻擊者偽裝成受害用戶,執行用戶能夠執行的行動並訪問用戶的任何數據

跨站腳本的工作原理是操控一個有漏洞的網站,使其向用戶返回惡意的 JS,當惡意代碼在受害者的瀏覽器中執行時,攻擊者可以操控破壞他與應用程序的互動

有三種 XSS 攻擊

  • Reflected XSS:惡意腳本來自當前的 HTTP 請求
  • Stored XSS:惡意腳本來自網站的資料庫
  • DOM-based XSS:漏洞存在於客戶端程式碼非服務器端程式碼
[閱讀全文]

asycio 工作原理淺談

asyncio 是 Python 內建的module,在 Python 3.4 時加入

是一種單 thread 的設計,它靠著 cooperative multitasking (協同運作式多工) 讓我們能多個工作併發處理 (concurrent)

協同運作式多工相對於搶佔式多工(Preemptive multitasking),協作式多工要求每一個運行中的程式,定時放棄自己的執行權利,告知作業系統可讓下一個程式執行

多線程採用的是搶佔式多工,多線程是由作業系統做排程,線程執行任務途中會被外力(作業系統)中斷改排其他線程執行,而協同運作式多工不由作業系統排程,在任務執行時遇到需要等待回應的狀況,會放棄執行權,改執行別的任務,而原任務在等到回應後再繼續執行

這篇文章主要是大概介紹 asyncio是如何做到 cooperative multitasking

[閱讀全文]