folder_open

面試雜記

arrow_right
article

面試心得–Thingnario慧景科技

面試心得–Thingnario慧景科技

2023/02/18~2023/02/24【Full Stack / Full Cycle Specialist】未錄取

職缺介紹

#

詳見 Yourator JDopen_in_new

履歷審查

#

  • 個人作品或其他你覺得滿屌的東西等

  • 你為什麼想加入thingnario

    過去比較少有大流量資料的處理經驗,希望可以在 thingnario 補足自己的弱項,也可以把自己過去學過的酷東西整合到 thingnario 的專案裡,跟著團隊及公司一起成長。

問卷填寫 & 線上測驗

#

人資認可履歷之後,首先會寄來問卷和 Coding 測驗題目,問卷鉅細靡遺到會讓人填地很厭煩,需要有心理準備。測驗題目則是放在 Colab 上,沒有限制作答的開始時間及結束時間,只需要在填好問卷、寫完測驗之後回信通知。

測驗題目

#

  1. Bubble sort

    // Problem 1 - Bubble sort
    function bubble_sort(sequence) {
    // Write your bubble sort code here
    }
    assert.deepEqual(bubble_sort([5, 1, 3, 2, 4]), [1, 2, 3, 4, 5])
  2. Find second largest within O(n) complexity

    // Problem 2 - Find second largest within O(n) complexity.
    function find_second_largest(sequence) {
    // Write your algorithm here with O(n) time complexity.
    }
    assert.equal(find_second_largest([3, 3, 2, 1]), 2);
  3. Closure

    // Problem 3 - Closure
    // Write some example(s) about how you take advantage of closure
  4. Hoisting

    // Problem 4 - Hoisting
    // Write some example(s) to explain the concept of hoisting
  5. var, let and const

    // Problem 5 - var, let and const
    // Write some example(s) showing the difference between the above three.
  6. Handling array

    // Probelm 6 - Handling array
    // Given below data, please write code to output all users under 40 years old in below format:
    // 1. Mr. Daniel Deng (age 11)
    // 2. Mrs. Maria Hanington (age 33)
    // ...
    const users = [
    {
    firstName: 'Freddie',
    lastName: 'Hong',
    gender: 'male',
    age: 32,
    married: true,
    },
    {
    firstName: 'Shaquille',
    lastName: 'Fang',
    gender: 'male',
    age: 3,
    married: false,
    },
    {
    firstName: 'Justin',
    lastName: 'Fan',
    gender: 'male',
    age: 42,
    married: true,
    },
    {
    firstName: 'Sophia',
    lastName: 'Liu',
    gender: 'female',
    age: 12,
    married: false,
    },
    {
    firstName: 'Maxwell',
    lastName: 'Jeng',
    gender: 'male',
    age: 43,
    married: false,
    },
    ];
  7. Immutability

    // Probelm 7 - Immutability
    // Write some example(s) to explain the concept of immutability and what's the benefit of it

感謝信

#

Hi ** 您好,

不好意思是我們說的不夠明確,我們請用人主管補充如下:

人選舉的例子很好,也確實是一般 closure 的使用方式,差別只有在於對於 closure 的好處說明的部分。
關於 demo2,人選的說明是: maintain private members without being polluted
而 closure 之於 demo2 的用途,主要在於讓 getCounter 裡面的 count 這個變數,在離開 getCounter 的 scope 之後仍然能夠存取。
一般來說在沒有 closure 的語言,在呼叫 counter1.increment 時,count 的記憶體位址已經被釋放,因此 count++ 的行為是未定義的。
closure 應該只是讓 Javascript function 內的 local variable 可以有跟 private member 一樣的效果,但讓他免於被外面的 scope 污染的主要原因仍然是 lexical scoping。
這裡並沒有要將答案限縮在 practical closures 範圍內的意思,如果我們有誤會人選或 MDN 的意思,還請人選指教。

以上是用人主管的說明,不知道是否有解答到您的疑問。
如果我們有誤會之處,再請您多多包涵並不吝給予我們回饋。
造成您觀感不佳之處還請您見諒。

Cheers,
thinngario HR

Hi ****,

感謝來信告知,但我還是希望多了解一下我的回答有什麼不妥之處,畢竟題目的描述原文是:

Write some example(s) about how you take advantage of closure

我的回答也的確是按照我使用 js 時,實際使用到 closure 的例子及封裝技巧,我非常不解這樣的回答為什麼反而似乎成為扣分的原因?
Closure 的應用有這麼多種,MDN Practical closures 裡面的內容也只是針對 argument binding 示範說明,如果你們只希望以 MDN 為原則,並且限縮在 Practical closures 這個範圍內,請你們下次註明在題目裡吧,不要再浪費下一位面試者的時間了

Hi ** 您好,

用人主管審閱後回覆如下:
第三題對 Closure 的認知比較偏 Lexical Scoping 而非 Closure 本身,建議參考一下 MDN 說明裡面 Practical Closure 這一段:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closuresopen_in_new
人選在其他題目的表現是不錯的,唯獨目前公司在擴展階段,需要人選對使用的程式語言有較深刻的了解,以確保程式品質。

基於上述理由,在此要通知您我們將不繼續後續階段。
也預祝您早日找到更理想的工作 : )

Cheers,
thingnario HR

應徵結果及時程

#

  • 2023/02/18 Yourator投履歷
  • 2023/02/19 收到問卷及前測連結
  • 2023/02/21 完成並送出問卷及前測
  • 2023/02/22 收到人資回應,等候主管審閱
  • 2023/02/24 感謝信

附錄:問卷題目及部分參考回答

#

第一頁

#

  • 請問您為什麼會想要加入新創公司?

    新創的同事都又怪又猛

  • 工作經歷

    麻煩填寫最近三個工作相關資訊(由近到遠);若為應屆畢業生或intern可(選擇性)簡述社團或工讀經驗

    • 工作一(含服務單位、公司規模、起訖期間、職務、離職原因)

      ĒSEN Inc.
      10人
      Mar 2022 - Jan 2023
      Senior Backend Engineer
      Layoff

    • 工作二(含服務單位、公司規模、起訖期間、職務、離職原因)

      OneDegree
      100人
      May 2020 - Mar 2022
      Senior Backend Engineer
      薪資成長不如預期

    • 工作三(含服務單位、公司規模、起訖期間、職務、離職原因)

      Appier
      200人
      Apr 2019 - May 2020
      Frontend Engineer
      職涯轉換

  • 請描述過去的工作經歷中,遇到最大的挑戰為何?扮演的角色或主要工作職責以及當時如何因應面對?歡迎至多填寫3個案例,至少填寫1個案例。

    1. 挑戰:Monolithic 轉換為結合 DDD 的 Microservice,幾乎把整個 code base 翻過一遍;職責:當時為一人工程團隊,無職責分配情況,全部自己扛;應對方式:看書自學
    2. 挑戰:實作可避免 Concurrent 問題的 Reservation System;職責:當時為一人工程團隊,無職責分配情況,全部自己扛;應對方式:Google 搜尋前例,自行摸索及實驗
    3. 挑戰:實作 General-purpose Query API,沒有前例可以效仿;職責:Squad Lead,協助實作工單;應對方式:定義好介面及部分實作細節後,交棒給組員
  • 近幾份工作中,最欣賞的同事在公司擔任什麼角色,為什麼欣賞他?

    Backend Lead,可以一邊寫 code 一邊胡扯、講笑話,但是討論公事的時候卻又不失專業,完美守住自己專業能力之餘還能跟上所有時事

  • 是否擔任過管理職

  • 若有,請問管理過最多人數為多少?所擔任管理職的主要工作內容與貢獻?

    5人,工作內容:架構設計、任務拆分、工程進度匯報、Scrum Master;貢獻:指導組員使其成長

  • 除了主要應徵職務外,你在thingnario會如何定位自己,期許自己能帶來什麼樣的影響?

    團隊裡的開心果、正能量產生器

  • 期待薪資 ( 時薪 / 月薪 / 年薪)

    年薪台幣 2,200,000

  • 請協助留下最近三份工作中,可做為reference check的聯繫人,需包含以下資訊:1. 姓名、2. 聯繫電話、3. 職務/職稱、4.與 您的合作關係,並請麻煩轉告該位同事我們近期內會打電話做reference check (若無工作經驗請留空白)

    ESEN: 謝XX,09********,UI/UX,合作共同專案的設計師
    OneDegree: 劉XX,09********,RD,合作共同模組的工程師組員
    Appier: 吳XX,09********,PM,曾合作共同專案的 PM

  • 若有個人客製化履歷/LinkedIn等,請附上雲端連結

    https://www.cakeresume.com/gocreatingopen_in_new

第二頁

#

共有兩部分:適應測驗及性格測驗,請憑直覺回答即可

  • 適性測驗

    • 在thingnario所有人的薪資都是公開的,是否有意願嘗試?(是/否)

    • 在團隊中表達不同意見是否感到舒適?(是/否)

    • 在團隊中習慣提供想法/做決策嗎?(是/否)

    • 喜歡投注心力於自己的專業領域、還是好奇寶寶任何事務都想試試看(投注心力於自己的專業領域/想試試看不同的事務)

    • 平常都透過什麼管道獲取新知?最近最有印象的內容是什麼?

      網路論壇、Google Now、電子報;土耳其地震

    • 遇到個人意見與團隊意見相左時,傾向於:(直接提出不同想法/觀察一下並尊重多數)

    • 換個位置需要換個腦袋嗎?(是/否)

  • 性向測驗

    • 一、在同事(同學)眼中您是一位?

      1. 積極、熱情、有行動力的人。
      2. 活潑、開朗、風趣幽默的人。
      3. 忠誠、隨和、容易相處的人。
      4. 謹慎、冷靜、注意細節的人。
    • 二、您最喜歡看哪一類型的雜誌?

      1. 管理、財經、趨勢類。
      2. 旅遊、美食、時尚類。
      3. 心靈、散文、家庭類。
      4. 科技、專業、藝術類。
    • 三、您做決策的方式?

      1. 希望能立即有效。
      2. 感覺重於一切。
      3. 有時間考慮或尋求他人意見。
      4. 要有詳細的資料評估。
    • 四、職務上哪種工作是我最擅長的?

      1. 以目標為導向,有不服輸的精神。
      2. 良好的口才,能主動的與人建立友善關係。
      3. 能配合團隊,扮演忠誠的擁護者。
      4. 流程的掌握,注意到細節。
    • 五、當面對壓力時,您會?

      1. 用行動力去面對它,並且克服它。
      2. 希望找人傾吐,獲得認同。
      3. 逆來順受,儘量避免衝突。
      4. 重新思考緣由,必要時做精細的解說。
    • 六、與同事(同學)之間的相處?

      1. 以公事為主,很少談到個人生活。
      2. 重視氣氛,能夠帶動團隊情趣。
      3. 良好的傾聽者,對人態度溫和友善。
      4. 被動,不會主動與人建立關係。
    • 七、您希望別人如何與您溝通?

      1. 直接講重點,不要拐彎抹角。
      2. 輕鬆,不要太嚴肅。
      3. 不要一次說太多,要給予明確的支持。
      4. 凡事說清楚,講明白。
    • 八、要完成一件事情時,您最在意的部份是?

      1. 效果是否有達到。
      2. 過程是否快樂。
      3. 前後是否有改變。
      4. 流程是否正確。
    • 九、什麼事情會讓您恐懼?

      1. 呈現弱點,被人利用。
      2. 失去認同,被人排擠。
      3. 過度變動,讓人無所適從。
      4. 制度不清,標準不一。
    • 十、哪些是您自覺的缺點?

      1. 沒有耐心。
      2. 欠缺細心。
      3. 沒有主見。
      4. 欠缺風趣。
    • 請問您目前人生階段想要完成的目標是什麼呢?

      寫出一個可以創造被動收入的 side project

    • 有什麼其他問題或是想告訴我們的,都歡迎在這裡填寫,我們會儘速回覆您!

附錄:測驗題目參考解答

#

  1. Bubble sort

    // Problem 1 - Bubble sort
    function bubble_sort(sequence) {
    // Write your bubble sort code here
    for (let i = 0; i < sequence.length - 1; i++) {
    for (let j = i + 1; j < sequence.length; j++) {
    if (sequence[i] > sequence[j]) {
    const tmp = sequence[i]
    sequence[i] = sequence[j]
    sequence[j] = tmp
    }
    }
    }
    return sequence
    }
    assert.deepEqual(bubble_sort([5, 1, 3, 2, 4]), [1, 2, 3, 4, 5])
    assert.deepEqual(bubble_sort([1, 2, 3, 4, 5, 6, 7]), [1, 2, 3, 4, 5, 6, 7])
    assert.deepEqual(bubble_sort([7, 6, 5, 4, 3, 2, 1]), [1, 2, 3, 4, 5, 6, 7])
  2. Find second largest within O(n) complexity

    // Problem 2 - Find second largest within O(n) complexity.
    // I will use max-heap instead if the problem is to find k-th largest
    function find_second_largest(sequence) {
    // Write your algorithm here with O(n) time complexity.
    let largest = -Infinity
    for (let n of sequence) {
    largest = Math.max(largest, n)
    }
    let secondLargest = -Infinity
    for (let n of sequence) {
    if (n < largest) {
    secondLargest = Math.max(secondLargest, n)
    }
    }
    if (secondLargest === -Infinity) {
    return null
    }
    return secondLargest
    }
    assert.equal(find_second_largest([3, 3, 2, 1]), 2)
    assert.equal(find_second_largest([3, 3, 3]), null)
    assert.equal(find_second_largest([3, 3, 1]), 1)
    assert.equal(find_second_largest([-1, 3, 3]), -1)
    assert.equal(find_second_largest([3]), null)
  3. Closure

    請讀者特別注意此題參考回答,根據感謝信內容,Thingnario 公司不接受 Lexical Scoping 屬於 Closure,該公司已特此信件指定回答方式請參考 MDN Closures, Sec. Practical closuresopen_in_new

    // Problem 3 - Closure
    // Write some example(s) about how you take advantage of closure
    // 1. create scope for asynchronous usage
    function demo1() {
    for (var i = 0; i < 3; i++) {
    ;(function (i) {
    setTimeout(() => {
    console.log(i)
    })
    })(i)
    }
    }
    demo1()
    // 2. maintain private members without being polluted
    function demo2() {
    function getCounter() {
    let count = 0
    return {
    increment: () => {
    count++
    },
    getCount: () => count,
    }
    }
    const counter1 = getCounter()
    const counter2 = getCounter()
    counter1.increment()
    console.log(counter1.getCount())
    console.log(counter2.getCount())
    }
    demo2()
  4. Hoisting

    // Problem 4 - Hoisting
    // Write some example(s) to explain the concept of hoisting
    function demo1() {
    n = 1 // use variable before declaration
    console.log(n)
    var n
    }
    demo1()
    function demo2() {
    hello() // use function before declaration
    function hello() {
    console.log('hello')
    }
    }
    demo2()
  5. var, let and const

    // Problem 5 - var, let and const
    // Write some example(s) showing the difference between the above three.
    function varDemo() {
    for (var i = 0; i < 3; i++) {
    // i is function-level scope
    setTimeout(() => {
    console.log(i)
    })
    }
    }
    varDemo()
    function letDemo() {
    for (let i = 0; i < 3; i++) {
    // i is block-level scope
    setTimeout(() => {
    console.log(i)
    })
    }
    }
    letDemo()
    function constDemo() {
    const i = 0 // initial value is required
    i = 1 // assign value to a const is invalid
    }
    constDemo()
  6. Handling array

    // Probelm 6 - Handling array
    // Given below data, please write code to output all users under 40 years old in below format:
    // 1. Mr. Daniel Deng (age 11)
    // 2. Mrs. Maria Hanington (age 33)
    // ...
    const users = [
    {
    firstName: 'Freddie',
    lastName: 'Hong',
    gender: 'male',
    age: 32,
    married: true,
    },
    {
    firstName: 'Shaquille',
    lastName: 'Fang',
    gender: 'male',
    age: 3,
    married: false,
    },
    {
    firstName: 'Justin',
    lastName: 'Fan',
    gender: 'male',
    age: 42,
    married: true,
    },
    {
    firstName: 'Sophia',
    lastName: 'Liu',
    gender: 'female',
    age: 12,
    married: false,
    },
    {
    firstName: 'Maxwell',
    lastName: 'Jeng',
    gender: 'male',
    age: 43,
    married: false,
    },
    ]
    function handle(users) {
    return users
    .filter((u) => u.age < 40)
    .map((u, i) => {
    let title
    if (u.gender === 'male') {
    title = 'Mr.'
    } else if (u.married) {
    title = 'Mrs.'
    } else {
    title = 'Ms.'
    }
    return `${i + 1}. ${title} ${u.firstName} ${u.lastName} (age ${u.age})`
    })
    .join('\n')
    }
    console.log(handle(users))
  7. Immutability

    // Probelm 7 - Immutability
    // Write some example(s) to explain the concept of immutability and what's the benefit of it
    // Immutability prevents states from being modified accidentally. That reduces the complexity of tracing bugs and makes development more efficient.
    // 1. Toy Example
    function mutableAppend(arr, item) {
    let result = arr
    result.push(item)
    return result
    }
    function immutableAppend(arr, item) {
    return [...arr, item]
    }
    let mutableArr = [1, 2, 3]
    const mutableResult = mutableAppend(mutableArr, 4)
    console.log(mutableResult)
    console.log(mutableArr) // the input passed into mutable functions may change
    let immutableArr = [1, 2, 3]
    const immutableResult = immutableAppend(immutableArr, 4)
    console.log(immutableResult)
    console.log(immutableArr) // the input passed into immutable functions never change
    // 2. A real world example
    const authRequired = (req, res, next) => {
    const { sessionId } = req.cookies.pop() // this `pop()` mutates the state of `req.cookies`
    // ...
    next()
    }
    app.post('/some/path', authRequired, (req, res) => {
    // ...
    console.log(req.cookies) // and here we dont't know why the `req.cookies` is polluted
    res.status(200).json({})
    })