tpai
6/20/2016 - 5:32 PM

Interview questions

Interview questions

Redux

  • 定義明確的資料 state
  • 集中用戶的行為 actions
  • 對應資料的變更 reducer

繼承有哪些缺陷

  • 繼承樹一旦深,相對地了解困難。
  • 容易覆寫重要方法。

Angular.js

Angular is TypeScript based JavaScript framework.

  • Two Way Data Binding
  • Routing
  • Form Validation

React.js

React is a JavaScript library for building user interfaces.

React.js 是被設計來解決大型應用在呈現資料的過程當中,由於資料經常變動而 browser 一直重新 render HTML 所造成的效能低落。

Virtual DOM 的原理是預先生成一個 DOM Tree,存有各節點的資料值及型態,再 render 我們所見到的 HTML。而當資料本身發生變動時,vDOM 將會做 diffing,藉此得知變動節點的位置,最後只會更動 HTML 上的該節點,並不會全部重新 render。

JSX 是以 JS XML 為基礎所開發的,其允許在 JS 中撰寫 HTML。

Relay & GraphQL: https://www.youtube.com/watch?v=9sc8Pyc51uU

Performance Comparison(react, ng, knockout, raw): http://chrisharrington.github.io/demos/performance/

Vue.js

Vue is a MVVM JavaScript framework.

可以採用 Template & Module 分離的方式開發,適合情境在於合作對象有懂 HTML5 & SCSS 的 Designer,另外也可以以 Component 的方式實作,適合情境為設計部分採用 CSS Framework 在只有 F2E 的情況下。

Flux vs MVC

  • Store = Model
  • View = View
  • Dispatcher + Action != Controller

差異:

  • 資料變更的主被動不同,Model 被動讓 Controller 變更,Store 中的 State 主動根據 Action 做出變化。
  • 追蹤資料變更的觸發點,MVC 的 View 容易被多個 Model 甚至 Controller 影響,Flux 只要追著 State 的流向就可以得知觸發點和其所造成的變化。

相較於 Redux:

  • Redux 是 Single Store
  • Flux 是 Multiple Store

Single Store vs Multiple Store

  • 實作 Server Render 時,hydrate state 較簡單。
  • 保證所有 subscription 只在 dispatch 結束後執行,Multiple Store 需要使用 waitFor。

Ref: https://stackoverflow.com/a/33633850

Redux 是 Immutable Data,Action 會先進 Middleware 然後再到 Reducer。

Flux 是 Mutable Data,Dispatcher 會透過 Callback 將 Action 丟給有註冊的 Store。

Immutable vs Mutable

  • 資料一致性:Mutable 無法避免 Concurrent State。
  • 效能可優化:Mutable 會導致 componentWillReceiveProps componentShouldUpdate 無效。
  • 資料可預測:Mutable 容易被 Side Effects 影響。

What happens when...

當輸入 google.com 在網址列時會發生哪些事?

Type 'g' => Trigger auto-complete => 'google.com' [Enter] => Query DNS to retrieve record => Open socket to IP address => TLS handshake (1.2, 1.3) => HTTP request (1.1, 2) => Server handle request => Response HTML => Download CSS, JS => Construct DOM tree => Construct render tree => Layout => Paint
  • TLS 1.3: 在 client hello 階段 share client key,減少溝通耗時。
  • HTTP 2.0:單一 TCP 連線,多工請求資源並支援優先級。

Ref:

Event Loop(JS 如何實作非同步)

一般的 code 進 call stack 採堆疊之先進後出機制,像 xhr、setTimeout 或是 click event 等 web api 則會在 request 完成或 times up 的時候進入採先進先出機制的 callback queue 等待,此時 event loop 就會去檢查 call stack 是否為 empty,如果是則從 callback queue 將 callback 移入 call stack 執行,如此重複直至結束。

Event bubbling

body>form>input

一旦 input 觸發 onClick,form 跟 body 也會依序觸發 onClick。

http://jsfiddle.net/jensbits/Lrrys/

  • stopPropagation: 阻擋 Event Bubbling
  • preventDefualt: 阻擋原生事件觸發

Object Oriented Programming

  • Classical: Java, C++, PHP, C#
  • Prototypal: Javascript

JS Syntax

  • OOP: {}, this
  • prototypal: bind

Prototypal Inheritance

// Obj B {...}
var B = {
  b: 1,
  m: function() { return this.b + 1; }
};

console.log(B.m()); // 2

// Obj A {} ---> Obj B {...}
var A = Object.create(B);
A.b = 10;
console.log(A.m()); // 11
// When A.m is called, 'this' refers to A.
// So when A inherits the function m of B,
// 'this.b' means A.b, the own property 'b' of A

// A ---> Object.prototype
var A = { b: 1 };

// B ---> Array.prototype ---> Object.prototype
var B = ["hey", "guys"];

// C ---> Function.prototype ---> Object.prototype
function C() {
  return 1;
}

Closure

當 A 函數內部的 B 函數被外部變數引用時就會形成 Closure。

閉包的作用就是在 A 執行完並返回後,閉包使得JS Garbage Collection 不會收回 A 所占用的資源,因為 A 的內部函數 B 的執行需要依賴 A 中的變數。

function A() {
  var counter = 0;
  return function B() {
    console.log(++counter);
  }   
}
var Counter = A();
Counter(); // 1
Counter(); // 2
Counter(); // 3

Scoping

https://codepen.io/somethingkindawierd/post/es6-arrow-functions-this

var obj = {
  foo: function() {
    console.log(this);
  },
  bar: () => {
    console.log(this);
  },
  baz: function() {
    (function (){console.log(this);})();
  },
  qux: function() {
    console.log((() => this)());
  },
  quux: () => {
    console.log((() => this)());
  }
};

obj.foo(); // obj
obj.bar(); // window
obj.baz(); // window
obj.qux(); // obj
obj.quux(); // window

var obj2 = {};
obj2.foo = obj.foo.bind(obj2);

console.log(o2.foo()); // obj2

// browser
window

// node
global

Apply, call, and bind

https://gist.github.com/tpai/45b0b34755ef838faacbd7512f9b2582#method-borrowing-and-binding

Async/await and promises

@uchiha_madara: Async functions are NOT a replacement for promises, they're sugar on top of them, to handle specific cases where you have many sequential asynchronous actions. http://stackoverflow.com/a/34740033

@bluepnume: every async function you write will return a promise, and every single thing you await will ordinarily be a promise. https://medium.com/@bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8

return function (dispatch) {
  return fetch(...)
    .then(res => res.json())
    .then(json => {
      dispatch(action(json))
    })
    .catch(err => {
      console.log(err);
    })
}

write in async/await

return async dispatch => {
  try {
    const res = await fetch(...);
    const json = await res.json();
    dispatch(action(json));
  } catch(err) {
    console.log(err);
  }
}

Variable and function hoisting

// Outputs: undefined
console.log(declaredLater);

var declaredLater = "Now it's defined!";

// Outputs: "Now it's defined!"
console.log(declaredLater);

equivalent to this:

var declaredLater;

// Outputs: undefined
console.log(declaredLater);

declaredLater = "Now it's defined!";

// Outputs: "Now it's defined!"
console.log(declaredLater);

Inner and outer scope

var name = "Baggins";

(function () {
    // Outputs: "Original name was undefined"
    console.log("Original name was " + name);

    var name = "Underhill";

    // Outputs: "New name is Underhill"
    console.log("New name is " + name);
})();
window.name = "Baggins";

(function () {
    // Outputs: "Original name was Baggins"
    console.log("Original name was " + this.name);

    var name = "Underhill";

    // Outputs: "New name is Underhill"
    console.log("New name is " + name);
})();

Currying

定義一個函數接受參數的同時返回一個函數,藉此達成閉包的條件將參數紀錄起來,在第二次呼叫該函數時便可調用以該參數定義好的功能。

https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch4.html

function add(n) { return function(m) { return m + n; } }
add(3)(4); // 7

// inject dispatch into component
// https://github.com/reactjs/react-redux/blob/master/docs/api.md#examples
import { connect } from 'react-redux';
export default connect(mapStateToProps)(Container);

High Order Function

Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions.

const formula = f => m => `${m} squared = ${f(m)}`;
const squared = formula(m => m * m);
squared(3);

Pure Function

  • Same input, same output.
  • No side effects.
  • No external mutable state.

Impure Function

  • current time
  • random number
  • http request
  • I/O
  • etc...

Uncontrolled/Controlled Element

  • Uncontrolled: 未使用 state 儲存欄位狀態,直接從欄位本身取出資料。
  • Controlled: 使用 state 管理欄位狀態,並透過 onChange 這一類的方法變更欄位資料。
// Uncontrolled
class Form extends Component {
  handleSubmit = () => {
    const name = this._name.value;
    console.log(`submit name=${name}`);
  }
  render() {
    return (
      <div>
        <input type="text" ref={input => this._name = input} />
        <button onClick={this.handleSubmit}>Sign up</button>
      </div>
    );
  }
}

// Controlled
class Form extends Component {
  handleSubmit = () => {
    const { name } = this.state;
    console.log(`submit name=${name}`);
  }
  onNameChange = e => {
    this.setState({ name: e.target.value });
  }
  render() {
    return (
      <div>
        <input type="text" value={name} onChange={this.onNameChange} />
        <button onClick={this.handleSubmit}>Sign up</button>
      </div>
    );
  }
}