2019 上半年前端实习面经

August 09, 2019

面试

前言

坐标杭州,我在上半年陆续找过一些前端实习,记录面经于此,供大家分享,现正在准备秋招。

涂鸦智能

电话面试

Promise 如何实现链式调用

  • Promise.then

实现 Promise2 在 Promise1 之后调用

  • async await
  • Promise.all

for...in 和 for...of 的区别

  • for...in 遍历键名(Key)并转化为字符串,for...of 遍历键值(Value)
  • for...in 语句以任意顺序遍历一个对象自有的、继承的、可枚举的、非 Symbol 的属性
  • for...in 更适合遍历对象,for...of 更适合遍历数组。
for (let i in [1, 2, 3]) {
  console.log(typeof i); // string
  console.log(i); // '1', '2', '3'
}

var triangle = { a: 1, b: 2, c: 3 };

function ColoredTriangle() {
  this.color = "red";
}

ColoredTriangle.prototype = triangle;

var obj = new ColoredTriangle();

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    // 如果去了 hasOwnProperty() 这个约束条件会怎么样?
    console.log(`obj.${prop} = ${obj[prop]}`); // obj.color = red
  }
}

简述 Set 和 Map

  • Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
  • Set 对象允许你存储任何类型的唯一值

Set 有哪些遍历方法

et.prototype.values()
Set.prototype.keys() // 等于 Set.prototype.values()
Set.prototype.entries() // [value, value]数组
Set.prototype.[Symbol.iterator]()
// 以上全部返回一个新的迭代器对象
Set.prototype.forEach()
for ... of

解构赋值失效的情况

let [x = 1] = [undefined];
x; // 1
let [x = 1] = [null];
x; // null

一面

请分别用 CSS、JS、React 实现动画:方块从屏幕左下角运动到右上角

  • CSS:translate + animation
  • JS:requestAnimationFrame / setTimeout
  • React:需要获取 Ref

这里涉及到性能优化层面,首先我需要知道 CSS 的最终表现分为以下四步:

  • Recalculate Style
  • Layout
  • Paint Setup and Paint
  • Composite Layers

由于 transform 是位于 Composite Layers 层,而 width、left、margin 等则是位于 Layout 层,在 Layout 层发生的改变必定导致 Paint Setup and Paint & Composite Layers,所以相对而言使用 transform 实现的动画效果肯定比 position 这些更加流畅。

浏览器也会针对 transform 等开启 GPU 加速。

无限滚动列表的性能优化

  • 设置一个可视区域,超过可视区域,直接删除 DOM

Typescript

  • interface(接口)和 type(类型别名)的区别

    • 都可以互相继承(&,extnds)
    • interface 能够声明合并
    • type 可以声明基本类型别名,联合类型,元组等类型
    • type DiffName = string
    • type Pet = Dog | Cat
  • TS class 相对于 ES6 class 的拓展
  • readOnly 只读属性
  • abstract 抽象类包含抽象方法,必须在子类中实现,且子类使用 extends
  • private、protected

闭包

  • 基本定义和应用
  • 闭包是指有权访问另一个函数作用域中的变量的函数
  • 能够保证一些变量不被回收,持续引用
  • 私有化变量,方法封装
  • 模拟块级作用域

简述防抖和节流,应用场景

说一下 Node 常用的模块

  • path、fs、stream、http、util

实现 EventEmitter,以及应用场景

  • NodeJS 是基于异步事件驱动的架构,需要一个事件调度中心
  • stream、fs、net、http 都继承于 EventEmitter

发布-订阅模式和观察者模式的区别

  • 发布-订阅模式,发布者和订阅者不需要彼此了解,有消息队列的存在
  • 观察者模式主要以同步方式实现,发布-订阅 模式主要以异步方式实现
  • Subject 还保留了 Observers 的记录

如何实现脚手架

  • 思路:通过 process.argv 获取参数,下载 Github 对应的模板,修改模板内容
  • 发布:npm login npm publish

介绍 Redux 的原理和流程

介绍 Mobx 的原理,如何实现数据的监听

  • proxy

Redux 中为什么要直接替换数据源,而不是修改

  • redux 通过比较对象的引用来判断是否同一个对象,如果是,则继续使用旧的 state,所以不会有任何的变化

了解过 immutable.js 吗

Antd 按需加载的原理

    import { Button } from 'antd';
    ReactDOM.render(<Button>xxxx</Button>);

          ↓ ↓ ↓ ↓ ↓ ↓

    var _button = require('antd/lib/button');
    require('antd/lib/button/style');
    ReactDOM.render(<_button>xxxx</_button>);

二面

平常学习前端的途径

  • 书籍(JS 高程,你不知道的 JS 系列、深入浅出 NodeJS…)、Medium、大牛博客、掘金

为什么从事前端

在项目中,如何解决 Bug

谈谈 HTTP

  • OSI 七层
  • 三次握手和四次挥手
  • HTTP 和 HTTPS
  • HTTP2
  • websocket
  • 报文

    • 起始行,首部,实体
  • 缓存
  • 请求方法

    • GET、POST、DELETE、PUT、OPTIONS、HEAD、CONNECT、TRACE、PATCH
  • 状态码
  • 跨域
  • 简单请求和复杂请求
  • HTTP 是无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  • HTTP 是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过 HTTP 发送。客户端以及服务器指定使用适合的 MIME-type 内容类型。
  • HTTP 是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

51 信用卡

电话面试 + 一面

webapck

  • 写过 loader 和 plugin 吗?
  • tree shaking
  • splitChunks

React 的按需加载如何实现

  • 通过 webpack 的动态导入 (dynamic imports)
  • React.Suspense

React 的 HOC

  • 属性代理
  • 渲染劫持
const HOC = WrappedComponent =>
  class extends WrappedComponent {
    render() {
      if (this.props.isRender) {
        return super.render();
      } else {
        return null;
      }
    }
  };

React 怎么和 Redux 结合

  • 通过 react-redux 的 connect 高阶函数

Redux 的 stroe 存储在 React 何处

  • Context

首屏加载时间怎么看

  • DomContentedLoaded
  • DomContentedLoaded 是否和 Raect 生命周期里的 render 同步

路由鉴权

  • 开两个 Tab 页,其中一个 Tab 页更改了权限,怎么保持另一个 Tab 页权限同步

缓存机制

  • 强缓存

    • Expires 表示一个绝对时间,允许客户端在这个时间之前不去检查(发请求)
    • Cache-Control
    • public 客户端和 CDN 代理服务器都可以缓存
    • private 客户端可以缓存
    • max-age=60 缓存内容将在 60 秒后失效
    • no-cache 每次请求都需要经过服务端的协商缓存
    • no-store 禁用缓存 - 返回值
    • 200(from disk/memory cache)
    • 特征

      • 不会发送 HTTP 请求
  • 协商缓存

    • If-Modified-Since/Last-modified 资源的最后修改时间

      • 粒度是秒级,如果在毫秒内更改内容,则无法生效
    • If-None-Match/Etag 根据实体内容生成的一段 hash 字符串
    • 返回值

      • 304 Not Modified
    • 特征

      • 会访问服务器

协商缓存是由服务端决定吗

协商缓存是由服务端返回资源吗

  • 不是,从客户端缓存中读取

如何使 304 中携带 response

  • 放置于 response headers

SPA 应用打包出来的 index.html 是否存在缓存

CDN

  • 什么是 CDN
  • CDN 主要部署什么资源
  • CDN 如何更新资源

移动端机型适配

  • JS + REM
  • VW + VH

如何判断 DRP

  • 浏览器: window.devicePixelRatio
  • CSS:@media -webkit-min-device-pixel-ratio

百应科技

电话面试

React 的生命周期

  • v16.3 之前
  • v16.3 之后,引入 Fiber 架构

简述 Redux 的工作流程

Redux 如何实现异步操作

  • Redux-thunk 是一个允许你编写返回一个函数而不是一个 action 的 actions creators 的中间件。如果满足某个条件,thunk 则可以用来延迟 action 的派发(dispatch),这可以处理异步 action 的派发(dispatch)。

Mobx 如何转化可观察对象为原生数组

  • slice()

一面

说说你对 Koa 洋葱模型的理解

如何加快 webpack 的构建速度

  • DllPlugin、HappyPack

什么是类型声明文件(.d.ts)

你在 TS 中用到哪些语法

  • 装饰器 Decorators

    • 作用于类,指向类的构造函数
    • 作用于方法,参数为实例对象,方法名,属性描述符
  • 泛型
  • 类型约束(type)
  • 类型断言 (as)
  • keyof typeof 操作符
  • 接口
  • 枚举
  • 映射类型(ReadOnly,Partial)
  • 索引签名
  • 类及其继承

二面

你的个人优势是什么

输入一个 URL 发生了什么

了解过动态规划吗

说说时间复杂度和空间复杂度 什么是 IPv4 和 IPv6 ,世界上一共有多少个 IP 地址

简述 OSI 七层模型

简述 HTTPS,什么是对称加密,非对称加密

亲宝宝

笔试

先做了一套笔试题,限时半个小时,比较简单,主要考察基础,还记得的题目有

列出 CSS 选择器的优先级

  • !important > id > 类、伪类、属性 > 元素、伪元素
  • 行内样式 > 内联样式 > 外联样式

介绍 position 的各个属性

  • 不要忘了 static、sticky

display: nonevisibility: hidden 的区别

new Boolean(false) && true 返回什么,并解释

手写代码,找出一个字符串中出现次数最多的那个字符

以下代码段会出现什么内容?

<script>
  alert(typeof a);
</script>
<script>
  function a() {
    a = 3;
  }
</script>

一面

简述 React Hooks

什么是 Virtual DOM

  • React 在 16.8 版本为我们正式带来了 Hooks API。什么是 Hooks?简而言之,就是对 函数式组件 的一些辅助,让我们不必写 class 形式的组件也能使用 state 和其他一些 React 特性。

简述 Diff 算法的实现过程

ES6 class 的 static 属性在构造函数的原型上吗

  • 不是,在构造函数本身上

三次握手,四次挥手

  • ACK:确认序号有效
  • SYN:发起一个新连接
  • FIN:释放一个连接
  • 三次握手,最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的
  • 四次挥手,当 Client 发送 FIN,仅表示 Client 不再发送数据,Server 可能还要发送数据,所以必须把 ACK 和 FIN 分开发送

判断一个对象是否是数组如何判断一个数组

  • instanceOf
  • Array.isArray()
  • Object.prototype.toString.call()

二面

谈谈你对 PV / UV 的理解,该如何去实现

  • PV (page view),即页面浏览量,一个访问者在 24 小时内到底看了你网站几个页面,不重复计算
  • UV (unique visitor),即唯一访问者,指你的网站 24 小时内有多少不同 IP 地址的访问

如何判断页面来源

  • 通过请求头中的 referrer 字段

简述 JWT

  • Header
   {
   "alg": "HS256",
   "typ": "JWT"
   }
  • Payload
  {
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
  }
  • Signature
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret);
  • Header 和 Payload 串型化的算法是 Base64URL。

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。

图片懒加载的实现手段

如何保证懒加载的图片会占据原有空间,不会引起页面重排

未来前端的职业规划


Written by B2D1(包邦东)