坐标杭州,我在上半年陆续找过一些前端实习,记录面经(只记录技术面,不记录HR面)于此,供大家分享,只记得其中一些问题了,见谅。
现正在准备秋招,大家一同加油吧!
涂鸦智能
电话面试
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
有哪些遍历方法-
Set.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 // 注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。
一面
- 请分别用
CSS、JS、React
实现动画:方块从屏幕左下角运动到右上角- CSS:
translate + animation
position + top/left + transition
- 这里涉及到性能优化层面,首先我需要知道
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
实现的动画效果肯定比left
这些更加流畅。 - 浏览器也会针对
transform
等开启GPU加速。
- 这里涉及到性能优化层面,首先我需要知道
- JS:
requestAnimationFrame / setTimeout
- React:需要获取
Ref
- CSS:
- 无限滚动列表的性能优化
- 设置一个可视区域,超过可视区域,直接删除
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
,以及应用场景- 基本方法:
emit
on
NodeJS
是基于异步事件驱动的架构,需要一个事件调度中心stream
fs
net
http
都继承EventEmitter
- 基本方法:
-
发布-订阅
模式和观察者
模式的区别发布-订阅
模式,发布者和订阅者不需要彼此了解,有消息队列的存在观察者
模式主要以同步方式实现,发布-订阅
模式主要以异步方式实现Subject
还保留了Observers
的记录
-
如何实现脚手架
- 思路:通过
process.argv
获取参数,下载 Github 对应的模板
,修改模板内容
- 发布:
npm login
npm publish
- 思路:通过
-
- React
- 介绍
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协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
cookie
token
- HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
- HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
51信用卡
电话面试 + 一面
- webapck
- 写过
loader
和plugin
吗 tree shaking
splitChunks
- 写过
React
的按需加载如何实现- 通过
webpack
的动态导入 (dynamic imports) React.lazy 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:none
和visibility:hidden
的区别 new Boolean(false) && true
返回什么,并解释- 手写代码,找出一个字符串中出现次数最多的那个字符
-
<script> alert(typeof a); </script> <script> function a() { a = 3; } </script> // 会出现什么内容?
一面
- 简述
React Hooks
- 什么是
Virturl 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 算法。
-
-
图片懒加载,怎么保证未加载的图片占据空间
-
未来前端的职业规划