发布于 07月25, 2017

【译】Vue, React, AngularJS, and Angular2. 我们对流行JavaScript框架们的选择

原文:http://www.zcfy.cc/article/3668

一个有趣的事实是:IBM发表的2017年最值得学习编程语言名单中,JavaScript榜上有名。正是这位IT巨头指出,JS在网站中惊人地达到94.4%的使用率,而且“不太可能降低”。JavaScript能确保“对用户非常友好的网页,因为它负责整个web界面,包括动画和交互”。不管你怎么看,JavaScript很重要。

这也指明了潜在Web开发人员的方向:如果你深入前端,你不得不在某些时刻面对JavaScript。并且正确的开发指南可能有助于此。

让我们假设你知道JavaScript基础知识。纯JS(不是一无所知)的那种。如果假设是正确的(意思是你了解基础),你可能对现代JavaScript框架们的学习更感兴趣。这些框架通常带有预置的函数和一些构建应用的方法。

JavaScript Frameworks

有些人可能会有局限性的思考,认为世界上大多数开发者更喜欢使用框架(不要将它们与库混淆),因为它们使工作更容易,更快速,在通常情况下更可靠。

好吧!说完这些,是时候该深挖一点儿了。

我们的开发团队准备了他们每天使用的框架清单。虽然周围肯定有更多的JavaScript框架,这些是我们最关注的。

接下来,你会看到我们所爱的技术及其各自特点的简单概述。

大街上的酷小孩-Vue.js。

Vue.js JavaScript framework

这个就像一个还在读高中的超级巨星。它不是一个成熟的技术,所以我们真的无法说,五年后,Vue会发生什么。然而目前,它可能是每个会议议程中最引人注目的话题

如果你决定和JS极客喝两杯,他会谈论Vue。如果Vue是个流行歌星,那么现在它就是最红的。如果...嗯,你明白我的意思。

它由尤雨溪在2014年2月建立。在2016年,Vue.js拥有惊人的89%的开发人员满意度评估,目前是GitHub中star最多的项目之一

虚的说差不多了,来点实际的。什么是Vue.js?首先,它是本文中讨论的所有JavaScript框架中最快最小的。它的语法和原理所需要的学习成本不是很高。此外,它还具有高覆盖率的文档。你想要执行的操作绝大部分情况已被记录在案。此外,如果一个操作没有文档记录,你能在线上找到解决方案的几率很小,因为Vue不如Angular或React更流行。

注意:Vue的发音和“view”一样。

随便挑5个Vue.js的特性说一下:

  • 便于扩展的插件系统。

  • 拥有在使用服务端渲染时的库(Nuxt.js)。

  • 支持范围样式。

  • 有一个CLI工具,允许你通过先进的前端工作流设置,快速构建单页应用。

  • 被加入Laravel5.4的新特性中,用来处理前端模板

就像React一样,Vue.js仅处理视图层。也就是,它让开发人员自己实现他们的业务逻辑。它也有被称为Flux架构实现的Vuex。作为我们的队友,36Kr某员工说:

在我看来,Vuex比React的Redux使用起来更好,更容易。

此外,Vue.js在Chrome中拥有最好的开发者工具,并且Weex也使用Vue的语法,它是一个通过JavaScript构建原生应用的框架,也是React Native的竞争对手。值得注意的是,Weex并不太完善,特别是对于商业项目。目前,它更多的是一个方案而不是一个真正的技术。

对开发者来说,Vue.js的优势在于:

  • 易于学习和理解,能快速开发应用

  • 与Laravel集成,所以具有Vue知识的开发人员对使用Laravel开发应用的后端团队有所补充

  • 拥有非常方便的CLI工具,可以快速启动

  • 有很多额外的模块,如路由器和状态管理工具;虽然不如其他框架那么多

对客户来说,Vue.js的优势在于:

  • 降低前端应用成本,乃至全功能web应用的成本(在使用Laravel和Vue.js的组合时)

  • 在保证稳定性的同时,是一个快速可靠的解决方案

  • 较小的模块很适用,如日历,联系人表单或小部件

开发者满意度最高-React.js

React.js JavaScript framework

React是由Facebook的Jordan Walke创建的,GitHub的最流行框架中排名第5。然而,React.js(以及React Native)最火爆的时间点是在2015年。

State of JS调查显示React的开发者满意度最高,达到92%。Vue跟它在同一个级别。根据调查,React的开发者较平均水平来说,在决定哪个技术配套使用前,会尝试多种其他技术组合。

随便挑5个React.js的特性说一下:

  • 框架只负责"View"层,这意味着其它业务逻辑是完全解耦的,并且能以任何方式来实现。

  • 与框架相关的Redux是一个非常棒的类Flux架构的实现。

  • 模板方面,框架可以使用JSX语法,这个语法在刚上手时可能会有一点点难度。

  • 开发者掌握React.js的知识后,可以直接用于基于React Native的移动客户端开发。

React对VirtualDOM的使用,以及由此获得的高性能广受开发者好评。经常使用框架的开发者也是这与这项技术相关的庞大社群的重要组成部分。React的快速发展,除了 Facebook的维护外,也要感谢开源项目以及第三方的模块。

此外,随着React将会有一个能够向后兼容的重写版React Fiber的消息放出,React的"第二春"很快就会到来。

对开发者来说,React的优势在于:

  • 庞大且活跃的社区

  • 并非一个大而全的框架

  • JSX这种新的JavaScript语法,也是一个不错的优点

  • 相关的开发工具也很不错

  • 强制使用最新的最佳实践

对客户来说,React的优势在于:

  • 大量的开发者熟悉这个框架

  • React Native使得Web应用的逻辑可以复用于移动客户端

  • 有足够多的使用和测试场景来保证框架本身几乎没有bug和错误

智慧长老-AngularJS

AngularJS JavaScript framework

Google在2009年第一次发布了AngularJs框架,鼓励使用声明式编程方法去创建用户界面和连接各种组件,另一方面,指令式的编程用于实现程序的逻辑。

Brat Tech公司的Miško Hevery是这个技术的真正作者,当时,它被创建为在线JSON存储服务背后的软件。但是业务没有搞起来,所以公司放弃了这个想法,并将AngularJs作为一个开源库发布。

AngularJS使用双向数据绑定的方式,适配和扩展了传统的HTML来呈现动态内容。

所有这些可能听起来很有意思,事实是AngularJs已经有点老了 实际上。它是我们描述的框架里最老的了,大ReactJS4岁,Vue.js5岁,比Angular2年长了7岁之多。

尽管如此,他拥有Github上最多的贡献者(1,562个),随后是ReactJS,Angular2,Vue.js。

不可否认,AngularJS有一个陡峭的学习曲线,这个缺点在某种程度上被一个大型社区抵消,保证开发人员可能遇到的大多数问题存在解决方案。

随便说AngularJS的5个特性

  • 仍然有许多项目使用AngularJS,所以了解AngularJS方便你维护这些项目。

  • 为不想使用新的Angular或Ember.js的团队提供可行且稳定的解决方案。

  • 使用脏值检查(digest cycle);与观察者模式相比孰优孰劣取决于你的需求。

  • PlayStation 3上的YouTube应用是用AngularJS开发的。

  • 以HTML为中心。

AngularJS是SPA中最常用的JavaScript框架之一,也是企业级应用的一个很好的选择。但是它确实很老了,大多时候是被老旧的应用采用。

AngularJs对开发者来说的"优"点:

  • 在2017年,如果你还没有使用它,你完全可以忽略他了。

  • 如果您需要更多功能的话,请使用新的Angular或Ember。

AngularJS对用户来说的"优"点:

  • 主要维护尚未准备好或无法获得足够重写的旧应用。

  • 由于框架复杂性,创建更复杂应用的成本很高。

译者注:各种黑,我X

Angular2(或简称Angular)

尽管在不挖掘源代码的前提下,很难完全了解Angular2的概念,它是一个非常强大的框架 内置了相当多的功能。

以AngularJS为基础,使用Typescript重写。与以前的版本相比,它没有scope或controllers的概念。相反,它使用组件层次结构化作为其主要架构概念。支持动态加载,改进了依赖注入,并提供更为简单的路由和异步模板编译机制。

随便说Angular2的5个特性

  • 由TypeScript编写,允许开发人员使用TypeScript,Dart或纯粹的ECMAScript。

  • 组件的模式利用了TS类和装饰器。

  • 陡峭的学习曲线

  • 开发过程很快。

  • 高级的的测试特性。

基本上,Angular可以摆脱AngularJS中存在的不必要的复杂性。然而,许多人认为,即使用CLI,单个开发人员的配置和启动过程仍然可能太长。

我们的开发团队也不太喜欢提供文档,特别是对于JS和Dart。另一方面,他们又喜欢将技术分解成很多模块。

Angular对开发者的优点:

  • 你喜欢TypeScript就开心了

  • 强制规定编写代码的方式,使得它成为与多个开发人员合作的好选择

  • 使用同一个库开发移动和桌面应用

  • 对于具有很多代码的单页应用是个不错的解决方案

Angular对客户来说的优点:

  • 使用该框架构建企业应用可能会降低成本

  • 大量开发人员已经知道如何使用框架

有最好的 Javascript 框架这一说么?

想要一个简单的答案? 没有。这跟公司目标、需求、以及最终的功能都有关系。举例来说,Angular2更像是一个百宝箱,特别适合大型项目。它非常复杂,并且需要花很多时间来全面的学习和掌握(但比AngularJS要简单一些)。但使用以JavaScript为核心的React,开发者就能快速高效得拼凑出一些有用的东西。

每个框架都在以不同的方式以实现适合用于不同场景的Web应用开发,包括MVP、创业公司和商业场景。

因此你应该考虑找到这样一个人,他能帮你选择适用于开发并且能够跟得上业务发展需要的技术。

而我们恰好具备这样的能力。

英文原文:https://insanelab.com/blog/web-development/vue-react-angularjs-angular-javascript-frameworks/?ref=quuu&utm_source=quuu

阅读全文 »

发布于 07月31, 2016

【译】Javascript 中的对象字面量很酷,你觉得呢?

原文:http://www.zcfy.cc/article/986

ECMAScript 2015 之前,Javascript 中的对象字面量(又叫做对象初始化器)是相当简单的,它可以定义2种属性:

  • 成对的静态属性名和值 { name1: value1 }
  • 通过 getters { get name(){..} }setters { set name(val){..} } 定义的动态计算属性值

说来遗憾,一个简单的例子就可以表示对象字面量的所有可能性:

    var myObject = {  
      myString: "value 1",
      get myNumber() {
        return this.myNumber;
      },
      set myNumber(value) {
        this.myNumber = Number(value);
      }
    };
    myObject.myString; // => "value 1"  
    myObject.myNumber = "15";  
    myObject.myNumber; // => 15

JavaScript 是一种基于原型继承的语言,所以啥都是个对象。 所以当处理对象的创建、原型的设置与访问时,它必须提供简单的构造方法。

定义一个对象然后设置它的原型是普遍流程。我常常觉得原型的设置应该能直接在字面量里用一条语句实现。

很不幸,字面量的限制不允许这样简单直接的实现方案。你不得不使用 Object.create() 配合字面量来设置原型:

    var myProto = {  
      propertyExists: function(name) {
        return name in this;    
      }
    };
    var myNumbers = Object.create(myProto);  
    myNumbers["array"] = [1, 6, 7];  
    myNumbers.propertyExists("array");      // => true  
    myNumbers.propertyExists("collection"); // => false

我认为这个方案很不方便。 JavaScript 是基于原型的,为什么设置对象的原型要这么痛苦?

幸运的是 JavaScript 在进化,它许多相当令人不舒服的特性正在一步步的被解决。

这篇文章演示了 ES2015 是如何解决以上描述的难题,并增加了哪些特性来提升对象字面量的能力:

  • 在对象构造函数中设置原型
  • 速写式方法声明
  • 进行 super 调用
  • 可计算的属性名

还有我们可以展望一下将来,看看 (草案2) 里的新提议: 可收集可展开的属性。

Infographic

1. 在对象构造函数中设置原型

正如你已知的,访问已创建对象的原型有一种方式是引用 __proto__ 这个 getter 属性:

    var myObject = {  
      name: "Hello World!"
    };
    myObject.__proto__;                         // => {}  
    myObject.__proto__.isPrototypeOf(myObject); // => true  

`myObject.__proto__` 返回 `myObject` 的原型对象。

好消息是 ES2015 允许使用 __proto__ 在对象字面量 { __proto__: protoObject } 中作为属性名来设置原型。

让我们用 __proto__ 属性为对象初始化,看它是如何改进介绍中描述的不直观方案:

    var myProto = {  
      propertyExists: function(name) {
        return name in this;    
      }
    };
    var myNumbers = {  
      __proto__: myProto,
      array: [1, 6, 7]
    };
    myNumbers.propertyExists("array");      // => true  
    myNumbers.propertyExists("collection"); // => false

myNumbers 是使用了特殊的属性名 __proto__ 创建的对象,它的原型是 myProto 。 这个对象用了一个简单的声明来创建,没有使用类似 Object.create() 的附加函数。

如你所见,使用 __proto__ 非常简洁. 我通常推荐简洁直观的解决方案。

一些题外话,我认为有点奇怪的是简单可扩展的解决方案依赖大量的设计和工作。如果一个方案很简洁,你也许认为它是容易设计的。然而事实完全相反:

  • 让事情变得简单直接很复杂
  • 让事情变得复杂难以理解很容易

如果一些事情看起来很复杂或者很难使用,可能它是没有被充分考虑过。 关于返璞归真,你怎么看?(随意留言评论)

1.1 特殊的情况下 __proto__ 的使用手册

即使 __proto__ 看起来很简洁, 这有一些特定的场景你需要注意到。

Infographic

对象字面量中 __proto__ 只允许使用 一次 。重复使用 JavaScript 会抛出异常:

    var object = {  
      __proto__: {
        toString: function() {
          return "[object Numbers]"
        }
      },
      numbers: [1, 5, 89],
      __proto__: {
        toString: function() {
          return "[object ArrayOfNumbers]"
        }
      }
    };

例子中的对象字面量声明了两个 __proto__ 属性,这是不允许的。这种情况会抛出 SyntaxError: Duplicate __proto__ fields are not allowed in object literals 的语法错误。

JavaScript 有只能使用对象或 null 作为 __proto__ 属性值的约束。任何尝试使用原始类型们 (字符串,数字,布尔值) 乃至 undefined 会被忽略掉,不能改变对象的原型。 让我们看看这个限制的例子:

    var objUndefined = {  
      __proto__: undefined
    };
    Object.getPrototypeOf(objUndefined); // => {}  
    var objNumber = {  
      __proto__: 15
    };
    Object.getPrototypeOf(objNumber);    // => {}

这个对象字面量使用了 undefined 和数字 15 来设置 __proto__ 的值。因为只有对象或 null 允许被当做原型, objUndefinedobjNumber 仍然拥有他们默认的原型: JavaScript 空对象 {}__proto__ 的值被忽略了。

当然,尝试用原始类型去设置对象的原型会挺奇怪。这里的约束符合预期。

2. 速写式方法声明

我们可以在对象字面量中使用一个更短的语法来声明方法,一个能省略掉 function 关键字和 : 符号的方式。它被称之为速写式方法声明。

让我们使用这个新的短模式来定义一些方法吧:

    var collection = {  
      items: [],
      add(item) {
        this.items.push(item);
      },
      get(index) {
        return this.items[index];
      }
    };
    collection.add(15);  
    collection.add(3);  
    collection.get(0); // => 15

add()get()collection 里用这个短模式定义的方法。

这个方法声明的方式还一个好处是它们都是非匿名函数,这在调试的时候会很方便。 上个例子执行 collection.add.name 返回函数名 'add'。 译者注:好像非速写式声明的函数名字也是一样,调用堆栈的表现也都一样,这里不太明白。

3. 进行 super 调用

一个有趣的改进是可以使用 super 关键字来访问原型链中父类的属性。瞧瞧下面的这个例子:

    var calc = {  
      sumArray (items) {
        return items.reduce(function(a, b) {
          return a + b;
        });
      }
    };
    var numbers = {  
      __proto__: calc,
      numbers: [4, 6, 7],
      sumElements() {
        return super.sumArray(this.numbers);
      }
    };
    numbers.sumElements(); // => 17

calcnumbers 对象的原型。在 numberssumElements 方法中可以通过 super 关键字调用原型的 super.sumArray() 方法。

最终, super 是调用对象原型链里父类属性的快捷方式。

上面的例子其实可以直接用 calc.sumArray() 调用它的原型。然而因为 super 基于原型链调用,是一个更推荐的方式。并且它的存在明确得表示了父类属性即将被调用。

3.1 super 的使用限制

super 在对象字面量中 只能在速写式方法声明里 使用。

如果尝试在普通的方法声明 { name: function() {} } 中使用, JavaScript 会抛出异常:

    var calc = {  
      sumArray (items) {
        return items.reduce(function(a, b) {
          return a + b;
        });
      }
    };
    var numbers = {  
      __proto__: calc,
      numbers: [4, 6, 7],
      sumElements: function() {
        return super.sumArray(this.numbers);
      }
    };
    // Throws SyntaxError: "super" keyword unexpected here
    numbers.sumElements();

这个 sumElements 方法是通过属性: sumElements: function() {...} 定义的。 因为 super 只能在速写式方法声明中使用,这种情况下调用会抛出 SyntaxError: 'super' keyword unexpected here 的语法错误。

这个约束不太影响对象字面量的声明方式,多数情况下因为语法更简洁,使用速写式方法声明会更好。

4. 可计算的属性名

在 ES2015 之前, 在对象字面量初始化中,对象的属性名大部分是静态的字符串。为了创建一个经过运算的属性名,你不得不使用访问器函数创建属性。

    function prefix(prefStr, name) {  
       return prefStr + "_" + name;
    }
    var object = {};  
    object[prefix("number", "pi")] = 3.14;  
    object[prefix("bool", "false")] = false;  
    object; // => { number_pi: 3.14, bool_false: false }

很明显,这种方式定义属性有点不那么友好。

可计算的属性名优雅的解决了这个问题。 当你要通过某个表达式计算属性名,在方括号 {[expression]: value} 里替换对应的代码。对应的表达式会把计算结果作为属性名。

我非常喜欢这个语法:简短又简洁。

让我们改进上面的例子:

    function prefix(prefStr, name) {  
       return prefStr + "_" + name;
    }
    var object = {  
      [prefix("number", "pi")]: 3.14,
      [prefix("bool", "false")]: false
    };
    object; // => { number_pi: 3.14, bool_false: false }

[prefix('number', 'pi')] 通过计算 prefix('number', 'pi') 表达式设置了 'number_pi' 这个属性名.
相应的 [prefix('bool', 'false')] 表达式设置了另一个属性名 'bool_false'

4.1 Symbol 作为属性名

Symbols 运算也可以作为可计算的属性名。只需要保证把它们括在括号里: { [Symbol('name')]: 'Prop value' }

举个栗子,让我们用 Symbol.iterator 这个特殊的属性,去遍历对象的自有属性名。如下所示:

    var object = {  
       number1: 14,
       number2: 15,
       string1: "hello",
       string2: "world",
       [Symbol.iterator]: function *() {
         var own = Object.getOwnPropertyNames(this),
           prop;
         while(prop = own.pop()) {
           yield prop;
         }
       }
    }
    [...object]; // => ["number1", "number2", "string1", "string2"]

[Symbol.iterator]: function *() { } 定义了一个属性来遍历对象的自有属性。 展开操作符 [...object] 使用了迭代器来返回自有属性的数组。

5. 对未来的一个展望: 可收集可展开的属性

对象字面量的可收集可展开的属性 目前是草案第二阶段 (stage 2) 中的一个提议,它将被选入下一个 Javascript 版本。

它们等价于展开和收集操作符 ,已经可以在 ECMAScript 2015 中被数组所使用。

可收集的属性 允许收集一个对象在解构赋值后剩下的属性们。 下面这个例子收集了 object 解构后留下的属性:

    var object = {  
      propA: 1,
      propB: 2,
      propC: 3
    };
    let {propA, ...restObject} = object;  
    propA;      // => 1  
    restObject; // => { propB: 2, propC: 3 }

可展开的属性 允许从一个源对象拷贝它的自有属性到另一个对象字面量中。这个例子中对象字面量的其它属性合集是从 source 对象中展开的:

    var source = {  
      propB: 2,
      propC: 3
    };
    var object = {  
      propA: 1,
      ...source
    }
    object; // => { propA: 1, propB: 2, propC: 3 }

6. 总结

JavaScript 正在大步前进。

即使一个相当小的对象字面量改进都会在 ECMAScript 2015 里考虑。以及很多草案里的新特性提议。

你可以在对象初始化时直接通过 __proto__ 属性名设置其原型。比用 Object.create() 简单很多。

现在方法声明有个更简洁的模式,所以你不必输入 function 关键字。而且在速写式声明里,你可以使用 super 关键字,它允许你十分容易得通过对象的原型链访问父类属性。

如果属性名需要在运行时计算,现在你可以用可计算的属性名 [expression] 来初始化对象。

对象字面量现在确实很酷! 你觉得呢?随意留言评论。

英文原文:https://rainsoft.io/why-object-literals-in-javascript-are-cool/

阅读全文 »

发布于 07月25, 2016

[翻译 & 校对] ES6 中 的 var、let 和 const 应该如何选择?

ES6 中 的 var、let 和 const 应该如何选择?

通过学习让事情变得简单这个原则也许是成为更好的开发者途径中最重要的事。这意味着在标识符的上下文中单个标识符应该只被用来表示单一的概念

有时候为了表示一些数据就很容易创建一个标识符,然后使用该标识符作为一个临时的空间去存储一些值作为一个过渡。

举个例子,你可能只为了得到 URL 中的 query string 的某个值,而先创建了一个标识符存储完整 URL ,然后是 query string ,最后才是该值。这种做法应该尽量避免。

如果你对 URL、 query string、 GET 参数的值分别使用不同的标识符,是很容易理解的。

这就是为什么在 ES6 上我喜欢 const 胜过 let 。在JavaScript中,const 意味着该标识符不能被重新赋值。不要被 immutable values 弄糊涂了。不像那些诸如 Immutable.js 与 Mori 产生的真正不可变的数据类型,const声明的对象可以有属性变化。

如果我不需要重新赋值,const 就是我的默认选择 相比 let 要常用的多,因为我想让它在代码中的使用尽可能的清晰。

当我后面需要给一个变量重新赋值时一般使用 let。因为我使用一个变量对应一个东西,现在 let 越来越多的被使用在循环和算法上面。

我在 ES6 中从不使用 var 。例如在一个 for 循环块范围值中,我想不出哪里使用 var 比使用 let 要好。

const 适用于赋值后不会再做修改的情况。

let 适用于赋值后还会修改的情况。例如循环计数,或者是一个算法的值交换过程。它同时标志着这个变量只能被用在所定义的块作用域之中,也就是说它并不总是包含在整个函数中。

var 现在是最坏的选择当你在 JavaScript 中定义一个变量时。 它在定义后可能还会修改,可能会在全局函数中使用,或者说只为块或循环。

警告:

现在在 ES6 中,因为 letconst 的暂时性死区效应,使用 typeof: 来检测标识符已经不再安全了。

译者注:在声明之前对标识符使用 typeof: ,会抛出 ReferenceError。

function foo () {
  typeof bar;
  let bar = ‘baz’;
}

foo(); // ReferenceError: can"t access lexical declaration
       // `bar" before initialization

但是不要紧只要你采用我的方法 “Programming JavaScript Applications”,在你使用它们之前进行标识符初始化。

P.S.

如果你需要通过清除它释放一个值,你可以考虑使用 let 而不是 const。如果你需要对垃圾回收进行微管理,你应该去看“Slay’n the Waste Monster”, 视频链接:

阅读全文 »

发布于 07月05, 2016

面试杂谈(前端)

前言

其实关于面试一直是一个老生常谈的话题,尤其是前端岗位的面试。个人自己的面试和被面试经验来说,大部分情况下的面试者都喜欢问一些知识收集型的问题,比如:

  • 浏览器差异与检测
  • CSS hack
  • 如何解决跨域

当然不是说这类问题不应该问,如果候选人的项目背景有写解决过类似的问题时;

适当追问有多少种不同的解决方案,为什么选择其中某种——能很好的考察候选人在积累知识过程中的深度、广度还有思维模式~

但是对于一些初级岗位的候选人或者毕业不久的校招生,问这类问题无非是增加尴尬。

那么要怎么做

如果非要问初级职位候选人一些知识收集型的题目,推荐问一些比较基础的,比如:

  • HTML5新增了哪些tag,和input类型
  • CSS选择器有多少种,优先级排序
  • JS闭包,浏览器的事件模型

这些问题的最大价值在于考察候选人对这个职位的重视程度。

更好的方式

比起知识收集型问题,推荐问开放式的问题,比如:

  • 大家都熟知的,一个页面从输入 URL 到页面加载完的过程中都发生了什么事情?
  • 谈一下你所知道的(页面)性能优化方法?

关于手写代码

当然相对推崇的方式是考察候选人手写代码的能力,比如:

不过说实话,手写代码个人认为是挺变态的,如果不是当时这道题火了我也不会去做。

如果临场再让我手写,未必能一次性跑过,所以实现一些相当简单的排序算法个人认为会是一个不错的方式~

其它情况

有些情况下,由于初级岗位往往需要先经过一轮电话面试做初筛,没法考察候选人的手写代码能力。

而且对于一些准备充分的题霸,知识收集型问题和开放式问题都不太适用,我会选择问数学题。

举个很简单的例子:x ^ 3 = 3,估算x的值,精确到小数点第1位(^是次方);

其实这是一道非常非常简单的题目,但在实际的面试过程中,不到20%的人能在不提示的状态下快速估算出答案,这个通过率对于初筛还是比较合适的;

先卖个关子,你算出来了吗?

为什么要问这种题目

  1. 能在网上搜到的答案或方案的问题都不能算是好问题,实际工作中我们常常会遇到一些没有现成解决方案的问题,或者说国外有解决方案但是自己水平不够,不能通过快速阅读英文,比如去:google、quora、stackoverflow来找答案解决的问题
  2. 我们都学过根号2 ≈ 1.414,根号3 ≈ 1.732,所以对于这种变种题,往往可以快速判断候选人的应变能力~
  3. 数学是一切学科的根本,尤其是计算机

延伸

上面这道题其实太简单了,觉得没有难度的同学可以算一下类似的一道题:2 ^ x = 10,估算x的值,精确到小数点第1位~

  • 提示思路1:

    1. 3 < x < 4
    2. 2^3.5 ≈ 8*1.414 > 10
  • 提示思路2:

    1. 题目转换为估算 2^x=1.25
    2. 能否估算 2^(1/4) 和 2^(1/3)
  • 提示思路3:

    1. 5/4=1.25
    2. (5/4)^3=125/64=1.953125近似于2
  • 答案:

    1. 2^(1/4) < 1.25 < 2^(1/3) 2.3.25 < x < 3.3333

补充

最近学到另外一种面试技巧,就是不设具体的问题,从对所需候选人能力的一些范畴上定义出,需要一个啥样人的大概框架~

常见的范畴:

  • 代码掌控力
  • 工程化能力
  • 解决问题能力
  • 技术广度
  • 技术敏锐度
  • 技术影响力

把这个框架的目标同步给候选人~然后让他讲述自己的工作经历~并把经历往框架上套,然后说服面试官雇佣自己~

友情链接

常见面试题;

顺便安利一下leetcode,不忙的时候解解各类经典题目

支持多种语言包括js,当场跑case,难易可选,能看通过率、耗时还有解法讨论~

阅读全文 »