A82eb86b06b5950aed79e4325891155d
一年半前端工作经验试水杭州:我是如何拿下网易、阿里和滴滴 offer 的

前言

笔者毕业于东北大学,大学毕业社招进入环球网,前端开发工程师一职。技术栈:React+node,Github 地址

成果

来到杭州的目标非常的明确,大厂。其实就是网易、阿里和滴滴。好在基本三家都拿到了offer。最终决定选择阿里p6。

面试题

大厂流程比较长,比如阿里就面试了将近三周。所以期间也面试了很多别的公司,创业公司or上市公司。这里我把我所被问到的面试题总结梳理一下。简单深入的都有。笔者个人工作经验不丰富,如若回答不好的地方欢迎指正。

HTML && CSS 部分

  • CSS常用布局
    CSS常用布局为盒模型div+css、其中需要注意IE的怪异盒模型,我们通常通过box-sizing解决。传统盒模型布局方式中我们可以细分为文档流布局、浮动布局、定位布局。在ie10+中我们可以使用flex布局,其中我们需要理解最为核心的容器和轴的概念。二维布局中,我们可以使用Grid布局。对于三栏布局,除了浮动实现方式,还有双飞翼布局和圣杯布局。其实双飞翼布局就是对圣杯布局的bug修复,一种改造升级。
  • 了解BFC么?
    BFC即为块级格式化上下文。在普通流的Box属于一种formatting box,类型可以为block或者为inline。但是不能同时为这两者。并且Block boxes在block formatting context里格式化,inline boxes在inline formatting context中格式化,任何被渲染的元素都属于一个box,不是block就是inline。其一般表现规则分为以下几种情况:1、在创建了BFC的元素中,其子元素按照文档流一个接着一个放置。垂直方向上他们的起点是一个包含块的顶部,两者相邻元素的垂直距离取决margin特性。2、在BFC中,每一个元素的左外边与包含块的左边相接触。及时存在浮动也是如此。除非这个元素也创建了一个新的BFC。3、BFC就是页面的一个独立的行政区域。所有浏览器都会将BFC放到浮动元素所在行的剩余空间内。当HTML满足一下任意一个条件即可产生BFC:float不为none、overflow不为hidden、display为table-cell,table-caption,inline-block中的任何一个。Position值不为relative或static。通常我们使用BFC为了不和浮动元素重叠。清除内部浮动元素。解决上下元素相邻时候重叠。
  • 居中方面问题
    分别从水平居中垂直居中两方面回答。水平、垂直居中分为单个元素、多个元素、已知宽高和未知宽高回答
  • session、cookie、sessionStorage、localStorage区别
    从client和Server中区分回答session是什么以及一般session如何使用注意事项以及安全策略,cookie、sessionStorage和localStorage等分别从概念和异同处回答。最后补充项目中的使用情况
  • px/em/rem的区别
    px顾名思义就是我们通常说的像素大小。em和rem都是相对大小,不过em是继承父级元素的字体大小,rem是相对于根元素的大小,这个单位可谓是集相对大小和绝对大小为一身。通过它可以做到只修改根元素即可修改所有字体的大小,又可以避免字体大小逐层复合的连锁反应。当rem相对于浏览器进行缩放,1rem默认为16px。
  • animation和transition使用过么
    写法:animation:name duration timing-function delay iteration-function direction .transition为过渡动画,这种效果可以在事件中触发,并且圆滑的以动画效果改变css的属性值。不同于transform,transform为2D转换(问题非常开放,尽可能多回答你所知道的)
  • css编写注意事项
    这个考验个人平时编码的总结和约束。问题较为开放,可以结合个人开发体验和团队约束来回答。比如0后面不带单位、尽量使用简写、使用子选择器、合理使用id等。

JavaScript部分

  • JavaScript闭包了解么
    闭包即为函数,但是我们通常所说的闭包是指有权访问并操作别的函数作用域中变量的函数。一般表现形式为函数中返回函数。通常我们开发中就会有很多的闭包比如定时器、事件监听、IIFE等。此题是一个借题发挥涨分的题目,我们可以谈谈闭包的高级用法,比如单例模式中的使用、js的节流和防抖甚至可以谈一谈js的运行机制,gc机制。
  • 前端跨域都有哪些解决方案
    js的前端跨域很多,通常我们给出方案并且应该简述优缺点,比如方式有,jsonp、document.domain+iframe、window.name+ifram、location.hash+iframe、postMessage跨域、CORS跨域、websocket跨域、node代理跨域以及NGINX代理等方式。其中对于我们常用的可以张开说明,比如CORS跨域中简单请求和非简单请求的header字段,access-control-allow-origin、access-control-allow-headers、access-control-allow-method等常规head字段说明。
  • JavaScript中的继承
    1、Es6中我们直接可以使用extends关键字去继承,通过重写super完成继承,但是在es5中,才是应该去主要细说的。2.原型继承的核心为父类的实例作为子类的原型。优点:非常纯粹的继承关系、简单易用、父类新增的原型方法原型属性子类都可以访问到。缺点:要为子类新增属性和方法,必须要放到new Animal()之后,不能放到构造器中,来自原型对象的引用类型被所有实力共享,创建子类,无法向构造函数传参。3.构造函数继承核心:使用父类构造函数来增强子类的实例优点:解决了共享引用类型的问题,可以在构造函数里面传参,可以实现多继承。缺点:实例不是父类实例,只能继承父类的属性和方法,不能继承父类原型的方法和属性、无法实现函数的复用。4、组合继承的核心:通过调用父类的构造,继承父类的属性并保留参数的有点,通过父类的实例作为子类原型,实现函数复用。优点:可以继承属性和方法以及原型上的属性和方法、即是子类实例也是父类实例、不存在属性共享的问题、函数可复用。缺点:调用了两次构造函数,生成了两份实例。5、寄生组合继承核心:砍掉父类的实例属性,这样,在调用两次父类的构造时候,就不会初始化两次实例方法和属性,避免组合继承的缺点
    es6 extends继承,ES5中的继承,实质上是先创建子类上的this,然后再将父类方法添加到this上,es6则是先创建父类的实例方法(必须调用super),然后在用子类构造函数修改this。没有调用super,是没有this的。
  • JavaScript中的节流和防抖
    防抖的原理为触发事件的n时间后才执行,如果n时间内事件再次被触发,则以新触发的时间为标准,然后n事件后再执行

    节流的原理为在持续触发事件时候,每隔一段时间执行一次。我们可以使用time line或者定时器来实现,或者二者结合实现。
  • JavaScript中的事件你了解哪些
    这种题目一般为开放性的题目,首先我们可以从事件的阶段来回答,事件冒泡、事件捕获、以及目标阶段。同时我们可以说明下事件委托的使用方式以及浏览器兼容性的问题。
  • setTimeout设置为0发生了什么
    这主要考察js的执行机制,可以从event loop来回答,包括js的单线程以及task queue microtask queue等。
  • 原生ajax请求了解么
  • js判断数据类型的几种方法
    1、最常见的typeof,返回的String格式。能够判断function,但是判断Object比较烦。2、判断已知数据类型可以用instanceof,注意instanceof后面一定是对象类型,并且大小写不能错。3.constructor方式。但是在实现继承的时候回出现错误,需要手动修改。4.通用但是很繁琐的方法为prototype:Object.prototype.toString.call(a)
  • this指向问题
    1、常规为题,从默认绑定、隐含绑定、明确绑定以及new绑定来回答。2、扩展es6中的箭头函数,以及call、apply和bind的区别。
  • 你如何看待JavaScript这门语言
    开放新问题,可以从参考《JavaScript语言精粹》,谈谈自己开发中遇到的各种问题,最重要的不是吐槽而是对鸡肋的解决办法,比如继承的实现、块级作用域、变量提升等。
  • es6用过么?说说promise的实现
    关于es6的知识点这里不再赘述。Promise的实现主要是pub-sub模式。状态和行为相分离的难点。

React部分

  • react组件的生命周期相关
    react组件生命周期最好的提现是使用es5 的编码方式,其中生命线大概分为两条路线,分别为getDefaultProps、getInitialState、componentWillMount、render、componentDidMount、(Running),然后分为两路,componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate以及componentWillUumount。我们一般在getInitialState中初始化组件的状态数据,在componentDidMount或者componentWillMount中进行获取API请求操作等,在shouldComponentUpdate中进行组件的优化。其中可以展开如何优化以及官方推荐的PureRenderMixin等实现方式。以及别的方面扩展结合自己的开发经验。
  • setState是同步的还是异步的
    通常我们的写法都是异步的,但是真正想要我们回答的是当给setState传入函数的时候,其实表现的为同步的。
  • 子组件的componentDidMount和父组件的componentDidMount哪一个先执行?
    必然是子组件的componentDidMount限制性,可以从react组件的生命周期进行分析扩展。
  • react的DIFF算法和virtual dom了解多少?

React的render函数返回的是一个DOM描述,结果仅仅是轻量级的js对象,reactjs在调用setState的时候会更新DOM,而且是先更新virtual dom,然后和实际dom比较,最后更新dom。React厉害的地方不是说他比真实的dom速度快,而是你不敢数据怎么变化,我都以最小的代价来更新视图。方法就是我在内存当中使用新的数据来构建一个virtual dom,然后和旧DOM进行比较,找出差异,然后更新到DOM节点上。当我们修改dom上的一个节点对应的state,react会立即将他标记为“脏状态”,在事件循环的最后才重新渲染所有的脏节点。在实际的代码中,会对新旧两棵树进行一次深度优先遍历,这样每一个节点都会有一个唯一的标记,没遍历到一个节点,就把该节点和新的树进行比较,如果有差异就记录到一个对象中,最后把差异应用到真正的DOM树上。算法实现步骤为:用js对象模拟DOM树,比较两颗虚拟DOM的差异,把差异应用到真正的DOM树上,DOM DIFF采用的是增量更新的方式,类似于打补丁。React需要为节点添加key来保证算法的效率。Key属性可以帮助react定位到正确的节点进行比较。从而大幅度减少DOM操作,提高性能。

top Created with Sketch.