---
# System prepended metadata

title: 資訊科技產業專案設計課程作業 3

---

# 資訊科技產業專案設計課程作業 3

## Mock interview

Interviewer: :dog: 
Interviewee: :cat:


## [Backend Engineer, Golang, NVIDIA](https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite/job/Backend-Engineer_JR1962842)

:dog: 可以幫我先自我介紹一下
> :cat: 我曾經做過不少專案，例如說在 Jserv 的書、課程專案，還有包括學校的 Final project 做額外的擴充，跟學弟妹分享時備課的教材拓展成比較完整的框架。過去也在團段合作的過程中我們是如何溝通彼此有衝突的意見。還有在我前一份工作，我從 onbourd 開始計算，5 個小時就對公司貢獻第一筆 commit。也在我們的 scrum meeting 裡面，team members 所有人認為應該要花 20 小時的情況下，我評估預期工時只需要 3 小時，結果也如預期在三小時完成。

:dog: 好，那。先來看一下你的工作經驗的部分。你可以講解一下你在裡面負責的任務，以及你有沒有一些印象深刻的成就，或者是專案。
> :cat: 我負責的任務跟印象深刻的成就跟專案。嗯，我想是我想是這樣子就是說，因為我們的公司的產品呢？會服務3個平臺，包括 Windows，Linux 及 Mac OS，那我第一開始剛剛講說我馬上能夠提出那個PR。
> :cat: 那是我們的 base library, 就是可以跨3個平臺共用的share library的部分，那，這是當然，可能就是我們的 team leader 會希望說能夠先試試看，說我這個人的程度大概到哪邊，那也希望能夠快速的去比較了解這個公司產品 infra 的部分，以利後來後續維護。
> :cat: 接下來第二個階段就是，我去幫忙開發、解決了一個問題：公司有個客戶要掃描的可疑檔案非常多，可能十幾萬筆20萬筆；但是在公司原本的程式模型，producer consumer 模型，上面會有超出記憶體使用，炸掉的情況。
> :cat: 我提出了一個我自己的解決方案，讓這個問題呢是絕對不會再發生。也可以保證原本的程式效率，不會有 starvation 的情況發生。

:dog: 你可以再細講一下你的 producer consumer 的那部分的改善該怎麼做？
> :cat: 原本的做法，是 producer consumer 共享 global queue，有一個 producer 配上很多個 consumer。我每個 consumer 做完會重新去跟 producer 要資料，他們就不再是共享同一個 Queue 也不會去不會讓 producer 不斷的產生：可能瞬間瞬間好幾10萬筆的data放在記憶體裡面去，讓 consumer 沒有辦法去消化。
> :cat: 而是說我在 consumer 在 100% loading 的情況下，當 consumer 做完再去跟 producer pull 新的資料下來。

:dog: 那你剛剛提到就是你把那個 global queue 給移除了，但這樣其實就已經造成某種程度的 dependent，
> :cat: 哦，對。
:dog: 那這個部分後面有造成什麼維護上的難題嘛？
> :cat: 後續維護上的難題好，我必須先承認的就是說這個目前這個情況是還沒有遇到的。
> :cat: 對那我這個地方除了改善就是 Queue 的 dependence 的問題的話，我把原本大概1000多行的程式碼，把它模組化，把它移到下一層；就是說OK，這個 producer 跟這個 consumer，他們就是一對，那他們這他們這一對就在自己的範圍。他們自己的scope裡面去做操作就好，就不要讓外層來去做，所以讓裡面那個偶合度非常高的一個互動模式，在外界不會去打擾他的情況下。我認為不會遇到太多的狀況。

:dog: 那，不過在這個模型下面，每次一定都是 producer 要活著的情況下，你的功能才有辦法運作。萬一 producer 死掉的話就沒有辦法運作了？因為原本是放在一個 global queue 裡面，producer 死掉，東西還可以被 consumer 做處理。
> :cat: 對，如果是 producer 只有一個，那他如果意外 crush，我會怎麼做？好極了，這個不在，畢竟他沒有做 HA。我想我可以試著用其他方法來解決這樣的問題...
> :cat: 如果是這個問題的話，我們原本的產品是也是也是會有，也是會有這樣的問題是說一個 producer，然後呢？大量的去產生資料，然後塞在global Queue 假設是無限大可以可以放上去的話，那 producer 爛掉... 吶。確實是不會，哎，對，確實是不會對這個系統造成影響，因為他已經放在 global Q 上面去了，對。
> :cat: 可是這樣即使我把它變成擴張成 multiple producer。這樣子。會有比較好嗎？這樣我會有雞生蛋蛋生機的問題耶，因為變成，我會區要先再有一個 producer-producer 去生產檔案給 producer 去派發任務給 consumer... 這樣並沒有解決問題。

> :cat: 還是說我就騙騙使用者說你會用 producer 的狀況去處理，但是現在找不到 producer，請你重新開啟這個應用程式？

:dog: 確實，一般通常比較常用是另外多 supervisor，他如果掛掉的話就是 restart，對，不過因為這個是在分散式系統上比較方便的做法，如果是在客戶端的一般機器上，我其實也沒有類似的這個經驗。

:dog: 嗯？那我們提到有對的房的門透露竟有兩倍的效能優化，可以再講一下這個細節？
> :cat: OK，其實我們公司在拼這個快速的市占率的情況下，會有蠻多的需求，是我快速能夠先把程式碼先出來，然後以至於後續要做優化的部分再來做處理這樣子，而且更何況就是說其實防毒軟體掃描半小時跟掃描一小時。其實一模一樣的事情。
> :cat: 對，所以我對在這邊做了當初沒有寫的優化。那個情境是：我們在客戶上面會有方塊字，意思就是說那個 cjk 就是 Chinese Japanese跟 Korean。會用到的寬字型，而不是傳統 C++ 上面的那個一個一個byte就可以表達出。以至於呢，我上面所有的都在產生一個寬字型的部分的時候，要麼就是要麼就是複製一遍，要麼就說一開始就是保持一致性。
> :cat: 而我所作到的改進，第一個就是保持一致性的部分就盡量減少它的沒有必要的轉換。那第二個部分就是說他在傳 parameter 的時候呢，當初的寫法可能沒有考慮到說可以傳這個，而這個屬於比較 C++ 進階的內容，他是傳可以傳的是 rvalue reference 進來對那就不需要去額外的負擔。
> :cat: Copy 成本讓原本就已經在 stack 或是在 heap 的物件，在進入這個 function 的時候又要再產生一次。那我透過網路上 Quick C++ Benchmarks 來評估我改善的 basic routine 是比原本的原本的函數效能快兩倍。

:dog: 這樣那你這兩倍的優化有時什麼 trade-off 嗎？
> :cat: 他唯一最最最大最大的問題是，它 ABI 不 compatible。也就是說，沒有辦法讓新版的程式碼去連結到相對應的函式，但是因為這是內部的函式庫，每次在 release 的時候都會重新 compile，所以實際上是感受不到差異的。

:dog: 剛好看到應該是在xxx的實習經驗，那你可不可以簡單講一下最令你印象深刻的事情？
> :cat: 因為那是我第一次實習，那時我花兩個禮拜，就做完了整個實習兩個月的工作。這算是我印象最深刻的事情。

:dog: 那可以請你描述更多細節？
> :cat: 那時候要做的內容是對 Andoird 應用程式做相關的安全分析。因為這算是苦力活，但是因為分析惡意或是不安全的樣本對資安研究員是相當耗時的，那我就透過 shell script 整合相關分析工具，幫我自動化的做分析。而後我才根據這些分析結果進行審核。
> :cat: 相對於其它工程師，或許我最擅長的就是使用 shell script 幫我把需要重複處理的事項，交給機器幫我完成。

:dog: 那你這邊提到你的分析工具，我好奇他背後的原理是怎麼做？
> :cat: 是，我們是靜態。我先用 dex2jar 等相關工具把APK檔做反編譯變成Java byte code，才去給 language server 做分析。

:dog: 嗯，那你覺得這個工具如果哪天那個 Java 的 import 升級 Java 版本之後，你的工具還可以正常運作嗎？
> :cat: OK，因為我們這個是在這個 Android 的環境上面，所以第一個就是說，即使你把 Java 的環境做升級，我 compile 出來的 Java 的那個版本會怎麼樣？
> :cat: 因為他是背後跑的那個 ART 就是 Android runtime 是一樣的 Fundamental Byte code，所以你的Java的升級。不會影響到我這個這個城市的分析，因為他們畢竟生出來要跑在不同手機上的。
> :cat: 再來就是 Armv7 跟 Armv8 在最近過渡期的關係，在 64 位元跟 32 位元會有不相容的問題。但是在這邊值得慶幸的是因為現在是過度期，所以編譯出來的 APK 通常都會有兩種 for Armv7 跟 Armv8 的 library，所以不會影響到我們的分析。

:dog: 你可不可以講一下你 Facebooc 在 GitHub Pipeline 上面做哪些事情？
> :cat: 抱歉我需要確認一下，印象中我在上面做的第一見事情是 formatting 檢查，還有就是 cppcheck 對 C 語言的靜態分析。對了，還有一個東西是我試圖要加入的那個unit test跟integration test的部分，那因為這個部分呢？團隊人手還不沒有相當足夠的關係，所以我只有把對這個test的部分留下一個框架，讓後續的開發者能夠新增對他的函式以及就有函式的 testing 補完這樣。

:dog: 我看你的 Makrfile，好 ...
> :cat: 對，沒有加 .PHONY
:dog: 看起來沒爆跟CI，還蠻中規中矩。這網路我就不穩了，因為。因為我也不太會。

:dog: 那你這邊有一個 binary staged build...恩，你可以大概描述一下 Docker 跟 VM 的區別是什麼？
> :cat: Okay, 基本上 Docker 是 container 麻，那 container 就是我們可以把它想像成就是所謂的 namespace，加上 chroot。
> :cat: 過去我在實做自己的 container 的時候，確實就是這樣讓 container 內部環境跟外部做隔離。至於那個 Cgroup 對於單純 container 的觀念就不太重要，因為那是 for load balancing 的。然後 seccomp 的話也是因為 security 的部份才加進去。
> :cat: 所以簡而言之，所以單純就我只是如果只是，就想要把一個東西封裝起來，在那個東西裡面的話，就是主要就兩個：chroot 跟 namespace。

:dog: 哦，那你這邊有提到你對 container 做編排的時候要用到 docker swarm 跟 docker-compose。嗯是，欸那想問一下這兩個工具的差別？
> :cat: Docker swarm 的話，就是告訴說我的 host 說這邊有這個 container 你可以跨裝置調度，中間走 URI 形式。而 docker-compose 的話就是這個 container 的環境要怎麼去跑起來。
> :cat: 一時間忘記他的是 docker swarm 的 master 術語叫什麼東西...？
:dog: 我不知道，我沒用過 docker swarm。
> :cat: OK，他就是我會有是要先把這個 docker routine 變成一個 node 節點，然後每個都是一個節點，然後你在這些節點是用人工的方式選出： OK，我哪個節點是 master，或者是說哪個節點是最主要的，那個節點是 slave，然後再去對就它做控制。因為 Docker 跑在 systemd 底下是一個 service 麻，所以可以假設所有 slave 機器上面都有 Docker socket。可以走 URI 形式反向代理到。

:dog: 哦。那你今天有提到誒，你可以設置 5000 個 client。
> :cat: 對

:dog: 那你這個 5000 的時候呢？他還是不斷的在查找VPN的，應該說他他不斷在傳送流量嗎？還是說他就只是掛著而已？
> :cat: 好，這是我們比較特殊的做法，她呢其實上是事實上是掛著的。當初我的測試方式是寫 shell script 不斷幫我建連線，我再去做操作。
:dog: 沒有啦，你今天如果要應徵網路，你如果應徵網管，你可以這樣形容。但是如果你今天要來 backend，你不可以這樣寫。
> :cat: 恩對，確實這邊應該做改進。

:dog: 然後VPN又是一個那個秘密存取量非常大量的服務的情況下，這個是會不會沒有辦法那麼有效率運行？因為一個一筆一筆經過加密的資料進來，我始終來說先解密，在在拉出來再送出去，所以這不能靠別的成本非常高，所以在memory上面，這個成本是符合不了的。而且他分散出不同的系統出來，然後分散在不同的這個那個 Matrix 上面，才能做到這樣事情，那你的這個 High scalability 是？
> :cat: Ok, 我需要簡介一下當初的情境。

:dog: 好喔
> :cat: 這原本是要 propose 給我們學校，學校原本的解法是：你需要一些新的VPN服務，他就新買一臺機器，然後重新設定整台 vpn server，然後去公告說我們多一臺機器，請學生自己連上去，而不是說我有一個統一的介面，然後就是說OK，我現在後面到底有多少機器不重要，這樣得一層虛擬化。

:dog: 那你怎麼做虛擬化？
> :cat: SSO 是綁學校的，所以他當然他可能會有那個 buttleneck 在 SSO 上面，畢竟我們不應該 cache 學生的帳號密碼。而在我拿到 SSO 認證的資料之後，我會配給你一台 VPN Server，讓你拿 key pair 直接跟 VPN server 互動。我中間統一界面就不再介入互動。

:dog: 那你這邊有用到普羅米修斯。去監測所有的container，他們當下的CPU負載量。你普羅米修斯是架設在哪裡？
> :cat: 在那個一次性的server上面，因為它需要知道需要配發出去的 end point 當下情況怎麼樣，而且監控這的開銷沒有到很大，所以就放在這機器上。
> 
:dog: 開銷不大？那你會怎麼解決普羅米修斯是 time series data 他的資料量不斷上漲這個硬碟開銷問題？
> :cat: 確實當初是沒有考慮到這問題，沒錯，對，那如果是我現在要解決。資料量世界時間上漲的問題的話，我會比照我過去寫 init.d 的作法，把舊有的 log 做壓縮存放，只 keep 住近期的 log，可能 30 天或是幾天。如果有需要的話，非常久的 log 也可以另外保存。只是我沒有試過普羅米修斯這樣的 api ，或許可以找找看。

:dog: 如果你今天要設計關於這種 distributed system。那你會怎麼設計的東西？都有哪些指標來判斷你這個 VPN 的健康狀態？
> :cat: 這種 VPN 的情況，主要是 CPU 跟 memory 之間的 bandwidth 不夠。我要怎麼知道說他當前的情況？就是。當他沒有辦法在上升的時候就是它 congestion 的時候。那我可以去看這個 throughput 然後取一個接近的最大值，就是曾經出現過的最大值，然後算這個percentage 現在到多少了。

:dog: 就這樣嗎？

> :cat: 恩，我得理解釋這樣，那想問問你覺得怎麼設計會比較好？

:dog: 通常我自己在設計來選上大概會分層。分成5層吧。最下面一層當然就是系統性，就是 cpu memory，然後 io 還有那些底層東西，因為這些東西掛了，你上面都不用講。
:dog: 然後再上面一層就是 application，應該說 programming language runtime，像是 Python 跟 Go 管理記憶體也方式不一樣。對然後還有 Go 觸發 gc 的時候，他 stop the world，一下就佔了幾百毫秒。然後 Python generation 3 個時代到底有多少？他是一直沒有講到。
:dog: 然後再往上一層，會是像是API。那就是哪些 end point 或是說哪些 gRPC 的 function 被 call 了多少次。然後他 return state 是多少？或者 exception rate 到底有多少，然後還有呢，它response time到底是？那一個API特別慢，然後我們會覺察到
:dog: 第4層是 external dependency，其實我們要怎麼去確認，像是你現在如果有擋一些CDN，cloudflare 之類的，你要去監控它，就如果 cloudflare 下去了。那妳有監控他，你就比較及早知道是他們下去，而不是你們的問題。
:dog: 第5層是是商業邏輯方面，像是你今天有個使用者上來，然後連線，那它連線成功率是多少？如果一般藏在狀態下，基本上應該要99趴以上連線成功，那今天如果掉到97趴是有哪裡不對勁？
:dog: 大概會分成這五層。

> :cat: 可是我們要怎麼知道說使用者的連線成功率有多少？

:dog: 自己寫吧，註冊還是什麼？這的話通常就是一個長期的，像是滾動平均數，對，就是只要有使用的嘗試，連你的服務你就記錄一次。她連線的成功很失敗。所以會需要一個統一的介面，然後讓他去monitor說到底使用者做了什麼樣的事情？你的普羅米修斯應該是透過一些 client side 來為整合。而你只是透過你的這個 service 去 export 一些 matrix 給他跑這個設備 supports，你可以去研究一下普羅米修斯不同程式語言的 client，它裡面會有更豐富的的 matrix 可以使用。

:dog: 那接下來問一下 Multi-Tenancy 的問題，如果你的5000個 client 中，其中一個流量是其他人的100萬倍，那你覺得服務應該怎么做調節才不會被一個卡按把所有單位吃光？
> :cat: 我能把 DoS 情況 kill 掉嗎？

:dog: 那這個人貢獻你公司 30% 的營收，你不能把他殺掉怎麼辦？
> :cat: 如果是 Wireguard 的 VPN service 的話，理論上不可能做到欸。因為 client-server 的 key pair 相關 config 都寫死了，只能派送一個更新請它重新連線到新的機器，請它自己連過去。

:dog: OK好，那接下來再問一下，如果你今天整個 VPN server 倒站，你覺得你要花多少時間才能 recovery？
> :cat: 怎麼樣的倒站？

:dog: 好，比如說機房直接備斷電。
> :cat: 那我有辦法讀取到硬碟內部的資料嗎？我有備份嗎？

:dog: 可以，你可以讀或有備份。
> :cat: 因為我們的服務是用 container 部屬的，除了 VPN key-pair 的部份其他是軟體定義。所以可以直接在複製到需要去搬移的目標上面繼續運行。

:dog: 那大概要多久？你有想過這個時間嗎？
> :cat: 好吧，這是一個蠻重要的問題，但是我沒有試過，沒辦法估計。

:dog: 對，需要 server Down time 有多少？應該說有一個概念叫 service level agreement，對它是由 service level objective 這個比較偏 SRE 的概念，通常你會承諾你的客戶說你一個月之內有 99.99% 的時間，你的系統要是啊。當你對於每一每一次不同層級災害發生的機率跟你所需要的 recovery time 去做計算，這算出來就是你能承諾客戶百分之多少啪的 uptime 的一個數字。嗯，這個會使你如果需要商業化，你的系統會需要算。
> :cat: 確實是個蠻重要的問題。

:dog: 那剛剛提到商業化，如果你今天你要把你的服務商轉，那你會怎麼設計收費模式？
> :cat: 有沒有相關的所有收費模式可以參考，因為畢竟我對。這個東西沒有概念的話，就算回答也沒辦法特別評估出什麼東西。

:dog: 目前比較常見的就就你在 YouTube 上可能看到廣告那個。可能就是一般流量一下就一般普普流量的你就等下就沒有對吧？然後流量大一點，或者說你要確保它穩定度的話，你可能就給他一個 premium。所以說免費版友每30分鐘段它連線一次之類的。
> :cat: 那可能這還要再討論看看。

:dog: 最後你有沒有看過 Python 3.11？
> :cat: 我有看到說他他在那個效能提升上面非常顯著，但我忘記具體數字多少? 60%?

:dog: 對，10% 到 60%，那他是怎麼達到？
> :cat: 我有瀏覽過 release note 看到過，可是我忘記了。

:dog: 就是稍微說一下，就是它大概是怎麼樣提升？因為我確實也忘記了。那我們直接找那個 release note。
> :cat: 他有提到 frozen import，這影響應該不大吧？

:dog: 我覺得是 python runtime 影響比較大。

> :cat: 我記得每個語言對於 string 的優化方式不一樣，比如說 Javascript 會用 string interning 的方式

:dog: Python 也有這樣的東西
> :cat: 可是我記得 Python 的 str 是會重新 new 一塊出來

:dog: Python 的 pymalloc 會在你的 str 小於 20 的時候，自動用 global interning 的方式，它就是一個 singleton object，如果是 20 以上的話，他不會重新利用 immutable str 他是其他記憶體區段。因為 Python 的記憶體配置會是 4 byte, 8 byte, 16 byte ... 一個 pool。這樣是沒有辦法做拼接的。
> :cat: 可是 8 byte pool 內部可以互相拼接嗎？

:dog: 不行，這樣 gc 會有問題。因為你拼接的話就會讓它多很多莫名奇妙的 reference count。
:dog: 那大概就這樣吧！
> :cat: 謝謝

### 檢討
1.  STAR method interview 不要流水帳
2.  直接告訴面試官，我準備可以回答 xxx yyy zzz 等幾個方向，你要哪一個方向？
3.  履歷資訊密度要高，盡量壓在一頁，多點數字


## [C/C++ Engineer, NVIDIA](https://nvidia.wd5.myworkdayjobs.com/en-US/NVIDIAExternalCareerSite/job/C-C---Engineer_JR1962904)

:dog: 你好，因為我們這個 position 有高度的 concurrent performance 需求，所以在你自我介紹之後我會問你關於 concurrency 的問題。這樣可以嗎？
> :cat: 好的，沒問題。

:dog: 那就先請你自我介紹一下看看吧
:cat: 我是一個 RD，平常興趣真的就是寫程式。上班的時候寫C++ 寫3個作業系統上的資安產品。
:cat: 那其他平常時候，我手邊業餘會寫的程式有：
:cat: 比如說，最近要回去學校對學弟妹分享的東西是一個網站的前後端，透過C++做撰寫。那會去處理一些後端的邏輯以及前端的算繪。語法是 Django 可是呢那只是語法，其中我要拿來做重新 parsing 的語言是用C++，也就是說，一個的 Django 的 C++ renderer。
:cat: 然後我平常也有在寫其他的APP，比如說，做 real time 的藍牙控制 IoT 設備，其中包括我要克服的問題會有跨平臺的問題，有的 client 機器有那個 Linux 機器也有 macOS 機器。
:cat: 那再來就是說，我前陣子有在寫這個 Faceboo"C"，也就是說用C語言寫出來的 Facebook 專案。
:cat: 過去也有跟 Jserv 一起貢獻 contribute 一些書，比如說 Linux kernel module programming guide，還有 LKSI 就是Linux kernel schedule internal 這兩本書。平常也會去對那個開源社群做貢獻，比如說 OPass。
:cat: 也有貢獻過 Debian。
:cat: 寫網頁的話，也有碰過 vue.js, Python 的 Flask, Golang，或者是 C 語言直接透過透碰 raw socket 的方式，去寫我們過去社群的產品開發。
:cat: 總之，非常多各式各樣的開發經驗，那看你會想要問哪個方向；然後當然也有跟團隊成員意見不同的時候，我們該如何溝通協調的經驗。

:dog: 好，了解。所以你平常對電腦就很有興趣，然後也會做開源貢獻這樣子？
:cat: 是的，因為過去從至少從 2016 年到現在 2022，每年都會參加各大社群、研討會。

:dog: 了解。那平常所在工司的專案大概有哪一些就是有你有興趣的部分？然後可能像或是自己想要改進自己的技術部分？
:cat: 