×
Press M for TOC
Press -> (next arrow key) for next posting
Press <- (previous arrow key) previous posting
Advertisement
Backend, Fullstack

Các câu hỏi khi đi phỏng vấn lập trình viên Javascript tại công ty Google

Javascript – tôi là một kỹ sư phần mềm có hơn 4 năm kinh nghiệm. Với đam mê chia sẻ kiến ​​thức của mình, nhất là trong việc chia sẻ những mẹo và thủ thuật hay nhất khi tham gia một cuộc phỏng vấn nào đó hoặc cách nâng cao khả năng code. Hôm nay tôi sẽ chia sẻ với anh em một bài toán được Google sử dụng để phỏng vấn ứng viên Javascript.

Bài toán Javascript

Viết một class, EventEmitter có ba phương thức: on, emitremoveListener.

  • on ("eventName", callbackFn) – là hàm lấy eventNamecallbackFn, sẽ lưu lại callbackFn khi event eventName được emit (phát ra).
  • emit ("eventName", data) – là hàm lấy eventName và đối tượng data, nên hàm callbackFn được liên kết với event đó và truyền cho chúng đối tượng data.
  • removeListener ("eventName", callbackFn) – là hàm lấy eventNamecallbackFn, rồi xóa callbackFn đó khỏi event.

Ví dụ

let superbowl = new EventEmitter()

const cheer = function (eventData) {
  console.log('RAAAAAHHHH!!!! Go ' + eventData.scoringTeam)
}

const jeer = function (eventData) {
  console.log('BOOOOOO ' + eventData.scoringTeam)
}

superbowl.on('touchdown', cheer)
superbowl.on('touchdown', jeer)

superbowl.emit('touchdown', { scoringTeam: 'Patriots' }) // Both cheer and jeer should have been called with data

superbowl.removeListener('touchdown', jeer)

superbowl.emit('touchdown', { scoringTeam: 'Seahawks' }); // Only cheer should have been called

Giải pháp:

Đây là một cơ hội tuyệt vời để sử dụng các class trong ES6. Trong trường hợp bạn chưa từng sử dụng chúng trước đây, hãy xem cú pháp của chúng dưới đây. Chúng ta sẽ bắt đầu với một cấu trúc cơ bản cho class EventEmitter và khởi tạo nó bằng một đối tượng event mà chúng ta sẽ sử dụng để theo dõi các event của mình.

class EventEmitter {
  constructor () {
    this.events = {}
  }
}

On

Nào ta bắt đầu thôi. Đầu tiên là on. Đây là đoạn code của nó:

on (eventName, callbackFn) {
  if (!this.events[eventName])  {
    this.events[eventName] = []
  }
  this.events[eventName].push(callbackFn)
}

Vì đây là các hàm first class objects trong Javascript, về cơ bản chúng có thể được lưu trữ trong một biến (variable), một đối tượng (object) hoặc một mảng (array), nên chúng ta chỉ có thể đẩy hàm gọi lại (callback) đến một mảng được lưu trữ tại khóa eventName trong event object của chúng ta.

Emit

Bây giờ, tới lượt hàm emit.

emit (eventName, eventData) {
    if (!this.events[eventName]) return
    this.events[eventName].forEach(fn => fn(eventData))  
  }

Giải pháp này tận dụng lợi thế của cái được gọi là closure trong Javascript. Nếu bạn đang viết code bằng Javascript trong cuộc phỏng vấn của mình, việc hiểu về closure có thể rất quan trọng. Closure về cơ bản là khi một hàm có tham chiếu đến các state xung quanh hoặc lexical environment (nơi chúng ta viết code của mình đặt biến, hằng, hàm) của nó. Bạn cũng có thể coi đây là một closure cho phép bạn truy cập vào một hàm cha (outer function) từ bên trong một hàm con (inner function). Sử dụng các biến toàn cục (global variable) là một ví dụ đơn giản tuyệt vời về closure.

Ở đây, có một ví dụ tuyệt vời khác về việc sử dụng closure để theo dõi số lần hàm được gọi.

function tracker (fn) {
  let numTimesCalled = 0
  return function () {
    numTimesCalled++
    console.log('I was called', numTimesCalled)
    return fn()
  }
}

function hello () {
  console.log('hello')
}

const trackedHello = tracker(hello)

Hàm con được trả về trong tracker nằm trong biến numTimesCalled và duy trì một tham chiếu đến nó trong vòng đời của hàm trackedHello. Nhìn ngầu ha.

RemoveListener

Phương thức removeListener có lẽ là dễ nhất trong ba cái này. Đây là hướng giải quyết.

removeListener (eventName, callbackFn) {
  const idx = this.events[eventName].indexOf(callbackFn)
  if (idx === -1) return
  this.events[eventName].splice(idx, 1)
}

Vậy là chúng ta đã xong! Qua đây chúng ta có thể thấy, nếu nắm rõ được các phương thức bổ sung sẽ là cách vượt qua các cuộc phỏng vấn tốt nhất. Chúc các bạn may mắn.

Leave a Reply

Your email address will not be published. Required fields are marked *

Advertisement