2023/02/03~【Backend Engineer】未錄取
薪資範圍:~1.8M / 13 mth + bonus
主要產品為手搖飲料自動化機器人。以 Node.js 為主。共有三個產品,每個產品各有一位 FE 及 BE,另外所有產品共享 QA * 2、TPM * 1、UI/UX * 2。
第一題考列舉質數:
Q1. Return prime numbers <= n.
Followup 會請你分析時間複雜度、如何優化、怎麼進行單元測試。另外面試官有追問對於 Node.js 的熟悉程度,像是 與 的差異。
這一關包含系統設計類考題以及 Culture Fit 問題。
此面試階段結束前筆者有反問為什麼有現在這個職缺,面試官的回應是擴編並增加備援人力,會加入 Cloud 的產品線。另外詢問了目前開發遇到的難處,得到的回應是市場上找不到前例可以作為參考。
開頭先從概念性的問題交流:
接著是兩題 Live Coding,限定 Node.js,必須執行以驗證結果,過程中可以查詢輔助資源,但要分享螢幕畫面讓面試官看得到操作過程。
紅綠燈
Create traffic light function.Red light for 3 secondsGreen light for 2 secondsYellow light for 1 second
括號排列組合
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.Example 1:Input: n = 3Output: ["((()))","(()())","(())()","()(())","()()()"]
Example 2:Input: n = 1Output: ["()"]
Constraints:1 <= n <= 8
這題雖然可以使用 Recursion 快速滿足功能性,但是 Followup 被要求按照題目中的順序輸出結果。
function isPrime(m) {  if (m % 2 === 0) {    return false  }  // 2, 3, … m-1  for (let p = 3; p*p < m; p += 2) {    if (m % p === 0) {      return false    }  }  return true}
function findPrimeNumbers(n) {  if (n < 2) {    return []  }
  // m = 6, p = 3  let ans = [] // let, const  for (let k = 2; k <= n; k++) {    If (isPrime(k)) {      ans.push(k)    }  }  return ans}
function testIsPrime() {  assertEqual(isPrime(2), true)  assertEqual(isPrime(3), true)  assertEqual(isPrime(4), false)  for (let i = 4; i <= 16; i += 2) {    assertEqual(isPrime(i), false, 'even numbers ...')  }  assertEqual(isPrime(-1), ?)  assertEqual(isPrime(0), ?)  assertEqual(isPrime(1), ?)}
function testFindPrimeNumbers() {  assertEqual(testFindPrimeNumbers(5), [2, 3])  assertEqual(testFindPrimeNumbers(100), [2, 3, 5, ...])}
Followup 優化方式:
數學運算
檢查某個數字 是否為質數時,因數可以只檢查小於 的奇數即可,當然 這個數字本身要例外處理。
Lookup Table
假設 有上限,那麼只要空間足夠,其實可以用空間換時間,直接預算答案。
async function trafficLight() {    async function sleep(s) {        return new Promise(r => setTimeout(r, s * 1000));    }    console.log('Red')    await sleep(3)    console.log('Greed')    await sleep(2)    console.log('Yellow')    await sleep(1)}
trafficLight()
本題為 LeetCode 22. Generate Parenthesesopen_in_new。
function combinations(n) {    if (n === 1) {        return ["()"]    }    let result = new Set()    const combs = combinations(n - 1)    for (let comb of combs) {        result.add(`(${comb})`)        result.add(`${comb}()`)        result.add(`()${comb}`)    }    return Array.from(result)}console.log(combinations(1))console.log(combinations(2))console.log(combinations(3))
Followup:請按照題目中的順序輸出結果。
最後僅寫出屍體:
function combinations(n) {    let output = []    function backtracking(current, remainingRight) {        if (remainingRight == 0) {            output.push(current.padEnd(n*2-current.length, ')'))            return        }        backtracking(`(${current}`, remainingRight - 1)        backtracking(`${current}(`, remainingRight - 1)        backtracking(`${current}()`, remainingRight - 1)    }    backtracking("", n)    return output}
後來在 LeetCode 上面重刷,使用 Backtracking AC:
class Solution:    def generateParenthesis(self, n: int) -> List[str]:        output = []        def bt(current, remainingLeft, remainingRight):            if len(current) == n * 2:                output.append(current)                return            if remainingLeft > 0:                bt(f"{current}(", remainingLeft - 1, remainingRight)            if remainingLeft < remainingRight:                bt(f"{current})", remainingLeft, remainingRight - 1)        bt("", n, n)        return output面試心得–Botrista 百睿達有限公司
面試心得–Botrista 百睿達有限公司