坐标杭州,我在上半年陆续找过一些前端实习,记录面经(只记录技术面,不记录HR面)于此,供大家分享,只记得其中一些问题了,见谅。
现正在准备秋招,大家一同加油吧!
涂鸦智能
电话面试
Promise如何实现链式调用Promise.then
- 实现
Promise2在Promise1之后调用async awaitPromise.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 + animationposition + 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抽象类包含抽象方法,必须在子类中实现,且子类使用extendsprivateprotected
- 闭包
- 基本定义和应用
- 闭包是指有权访问另一个函数作用域中的变量的函数
- 能够保证一些变量不被回收,持续引用
- 私有化变量,方法封装
- 模拟块级作用域
- 简述防抖和节流,应用场景
- 基本定义和应用
- Node
-
说一下常用的模块
pathfsstreamhttputil
-
实现
EventEmitter,以及应用场景- 基本方法:
emiton NodeJS是基于异步事件驱动的架构,需要一个事件调度中心streamfsnethttp都继承EventEmitter
- 基本方法:
-
发布-订阅模式和观察者模式的区别发布-订阅模式,发布者和订阅者不需要彼此了解,有消息队列的存在观察者模式主要以同步方式实现,发布-订阅模式主要以异步方式实现Subject还保留了Observers的记录
-
如何实现脚手架
- 思路:通过
process.argv获取参数,下载 Github 对应的模板,修改模板内容 - 发布:
npm loginnpm 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
- 谈谈
HTTPOSI七层- 三次握手和四次挥手
HTTP和HTTPSHTTP2websocket- 报文
- 起始行,首部,实体
- 缓存
- 请求方法
GET POST DELETE PUT OPTIONS HEAD CONNECT TRACE PATCH
- 状态码
- 跨域
- 简单请求和复杂请求
- HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
cookietoken
- HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
- HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
51信用卡
电话面试 + 一面
- webapck
- 写过
loader和plugin吗 tree shakingsplitChunks
- 写过
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
- 首屏加载时间怎么看
DomContentedLoadedDomContentedLoaded是否和Raect生命周期里的render同步- 不同步
- 路由鉴权
- 开两个
tab页,其中一个tab页更改了权限,怎么保持另一个tab页权限同步
- 开两个
- 缓存机制
- 简述强缓存和协商缓存
- 强缓存
Expires表示一个绝对时间,允许客户端在这个时间之前不去检查(发请求)Cache-Controlpublic客户端和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 + REMVW + 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)
keyoftypeof操作符- 接口
- 枚举
- 映射类型(ReadOnly,Partial)
- 索引签名
- 类及其继承
- 装饰器
二面
- 你的个人优势是什么
- 输入一个
URL发生了什么 - 了解过动态规划吗
- 说说时间复杂度和空间复杂度
- 什么是 IPv4 和 IPv6 ,世界上一共有多少个 IP 地址
- 简述
OSI七层模型 - 简述
HTTPS,什么是对称加密,非对称加密
亲宝宝
笔试
先做了一套笔试题,限时半个小时,比较简单,主要考察基础,还记得的题目有
- 列出
CSS选择器的优先级- !important > id > 类、伪类、属性 > 元素、伪元素
- 行内样式 > 内联样式 > 外联样式
- 介绍
position的各个属性- 不要忘了
staticsticky
- 不要忘了
- 写出
display:none和visibility:hidden的区别 new Boolean(false) && true返回什么,并解释- 手写代码,找出一个字符串中出现次数最多的那个字符
-
<script> alert(typeof a); </script> <script> function a() { a = 3; } </script> // 会出现什么内容?
一面
- 简述
React Hooks - 什么是
Virturl DOMReact在 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 } -
SignatureHMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Header 和 Payload 串型化的算法是
Base64URLJWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。 -
-
图片懒加载,怎么保证未加载的图片占据空间
-
未来前端的职业规划