昨日进行了滴滴的视频面试, 大概三个小时吧, 总共三面. 题目总体而言都是考察基础知识, 这一方面并没有太多的疑虑. 虽然说三面的一道手撕代码挂了, 但是还是收获满满. 在面试期间将遇到的题目偷偷写到了纸上, 花几天时间做个总结.
更新
[2019-11-8]
- Initial Release
[2019-11-11]
Added
- 解决问题: 求一个数组的和
- 解决问题: URL 替换
- 解决问题: a.com 和 a.com:8080 是跨域吗
- 解决问题: 一个 HTTP 请求的结构
- 解决问题: 如何解决跨域
- 解决问题: linux 的文件操作命令
- 解决问题: git_fetch 和 git_pull 的区别
- 解决问题: git 回滚操作
- 解决问题: React 的 Hooks 为什么要按照顺序调用
- 解决问题: React 的 Hooks 为什么要写在最外部
- 解决问题: 说说 React 的生命周期
- 解决问题: 分别说下 TS 和 JS 的优点和缺点
[2019-11-13]
Added
- 解决问题: CSS 计算题
- 解决问题: CSS 的大小单位有哪些
- 解决问题: 有了解哪些 redux 的异步中间件
- 解决问题: redux 的原理是什么, 以及它的优势
[2019-11-15]
Added
- 解决问题: TS 中 any 的应用场景有哪些
- 解决问题: 你目前正在参与的开源项目
[2019-11-18]
Added
- 解决问题: 为什么要使用 TS, 它解决了什么问题
[2019-11-25]
Added
- 解决问题: 你为什么要参与开源项目
- 解决问题: VS Code 的插件是你独立开发的吧
- 解决问题: 你对代码质量的要求是怎样的
- 解决问题: 你的职业规划提到了全栈, 那你现在是怎么准备的
Changed
- 更新问题: 分别说下 TS 和 JS 的优缺点
[2019-12-11]
Changed
- 取消置顶
目录
- 一面
- 1. 自我介绍
- 2. 求一个数组的和
- 3. URL 替换
- 4. a.com 和 a.com:8080 是跨域吗
- 5. 一个 HTTP 请求的结构
- 6. 如何解决跨域
- 7. linux 的文件操作命令
- 8. git_fetch 和 git_pull 的区别
- 9. git 回滚操作
- 10. react_hooks 为什么要按照顺序调用
- 11. react_hooks 为什么要写在最外部
- 12. 说说 React 的生命周期
- 13. 说说 NodeJS 的中间件机制
- 14. 分别说下 TS 和 JS 的优点和缺点
- 15. 实现 Promise
- 16. 如何用 setTimeout 来模拟 setInterval?
- 二面
- 三面
一面
1. 自我介绍
略
2. 求一个数组的和
3. URL
替换
3.1 问题描述
给定一个 URL(https://didi.com?a=duan&b=zhao&c=21
), 和一个键数组(['a', 'b']
), 要求从原字符串的参数去掉对应的键, 返回新的 URL(https://didi.com?c=21
).
3.2 问题解决
- 提取
URL
的参数至对象中 - 删除指定的键
- 重新拼接
URL
3.3 参考
4. a.com
和 a.com:8080
是跨域吗?
4.1 问题描述
略
4.2 问题解决
这个问题, 要从两个方面入手:
- 应用层的协议
- 跨域
由于 a.com
的默认端口号为 80|443
, 与 a.com:8080
的端口号不相同, 而同源策略规定了 协议
、域名
、端口号
这三者任一种不相同都会产生跨域, 所以 a.com
和 a.com:8080
是跨域的.
4.3 参考
略
5. 一个 HTTP
请求的结构
5.1 问题描述
略
5.2 问题解决
以 POST
请求为例, 主要包括三个部分:
- 请求行
- 请求头
- 请求体
1 | POST /images/1.png HTTP/1.1 |
5.3 参考
略
6. 如何解决跨域?
6.1 问题描述
略
6.2 问题解决
跨域是什么?
向不同 协议
、域名
、端口号
的其它服务器发起请求时, 会产生跨域
为什么会产生跨域?
由于浏览器的同源策略的限制
怎么解决跨域?
- jsonp
- 通过
js
动态创建script
标签, 利用script
、img
、iframe
、video
等标签不受同源策略限制的特点, 携带一个回调函数, 向指定URL
的服务器发起请求.
- 通过
- CORS
- 服务端设置一个
Access-Control-Allow-Origin
响应头来允许特定的域名的请求
- 服务端设置一个
- Websocket
- Nginx
6.3 参考
略
7. linux
的文件操作命令
7.1 问题描述
linux
创建目录, 使用哪个命令?- 递归创建一个目录, 会创建同名的不存在的目录, 使用哪个命令?
- 查看目录的结构, 使用哪些命令?
7.2 问题解决
1 | # 创建目录 |
7.3 参考
略
8. git fetch
和 git pull
的区别?
8.1 问题描述
略
8.2 问题解决
git pull
=git fetch
+git merge
git pull
拉取远程分支到本地, 并自动合并, 而git fetch
则不会自动合并, 需要手动git diff
, 再合并
8.3 参考
略
9. git
回滚操作
9.1 问题描述
我想回退到某个古老的 commit
版本, 我该怎么做?
9.2 问题解决
1 | # 1. 查看当前分支的 commit 记录 |
上述的 操作二
会将 HEAD
指针指向指定的 commit
. 此时, 如果我后悔了, 想回到最新的 commit
, 应该怎么做?
1 | # 1. 查看当前仓库所有的 commit 记录 |
9.3 参考
10. React
的 Hooks
为什么要按照顺序调用?
10.1 问题描述
略
10.2 问题解决
Hooks
以 单链表
的形式存储于函数组件的 Fiber.memorizedState
属性上, 在源码种, 通过 workInProgressHook
这个变量来指向对应的 Hook
对象.
我们可能在一个函数组件内部, 声明多个同类型的 Hooks
, 比如:
1 | import React from 'react'; |
在上面的示例代码中, 我声明了两个 useState
, 两者互不影响. 这是怎么做到的?
事实上, React
内部维护了一个名为 workInProgressHook
的变量, 代码执行的过程中, 每遇到一个 Hooks
, 都会移动指针, 使得组件中定义的 Hoooks
与 Fiber
上存储的 Hooks
一一对应.
这也引申出了一个问题: React 的 Hooks 为什么要写在最外部?
假如有这样一段代码:
1 | import React from 'react'; |
useState
被包裹在判断语句内, 假设该 if
语句成立, 则 Hooks
会以正常的模式渲染; 反之, 就会报错, 因为此时代码已经执行到了流程四(useEffect
), 但是 workInProgressHook
依然指向流程三对应的 Hooks
.
10.3 参考
11. React
的 Hooks
为什么要写在最外部?
12. 说说 React
的生命周期
12.1 问题描述
略
12.2 问题解决
1 | // React-v16.4 |
12.3 参考
略
13. 说说 NodeJS
的中间件机制
14. 分别说下 TS
和 JS
的优点和缺点
14.1 问题描述
略
14.2 问题解决
TS 的优势
- TS 可以看作是
Type + ES
, 它是一个静态类型的语言, 提供了相对完善的静态类型检查, 与传统的 ES 相比, 可以在编写代码时很方便的发现错误, 而 ES 则需要在执行时才能发现 - 与传统的
ES + Flow
模式相比, 避免了编写大量繁杂的函数注释, 更加适合大型应用. 我在阅读 React 源码的过程中, 有接触到 Flow, 但是给我的感觉是体验极差, 并不能跳转到对应的类型定义处 - 最重要的一点就是, TS 在 ES 的基础上, 完善了类的概念, 包括
private
、protected
、public
, 同时也提出了一些新的概念, 比如接口等
14.3 参考
略
15. 实现 Promise
16. 如何用 setTimeout
来模拟 setInterval
?
二面
17. 自我介绍
略
18. 你的职业规划提到了全栈, 那你现在是怎么准备的?
19. 你为什么要参与开源项目?
20. 为什么要使用 TS
, 它解决了什么问题?
20.1 问题描述
略
20.2 问题解决
其实这个问题, 一面的时候已经问到了, 个人认为, 使用 TS
主要有三个方面的优势:
TS
是一个静态类型语言, 拥有较为完整的静态类型检查机制, 在编写代码时就可以发现潜在的错误, 而反观传统的ES
, 则需要在代码编译执行时才能揪出存在的错误.- 实际上, 使用
ES + Flow
可以提供简单的类型检查, 但我个人认为这种方式是具有一定缺陷的——比如我在阅读React
源码的过程中, 注意到React
源码中有使用到了Flow
, 但是给我的感觉就是——用户体验很差, 不能跳转到类型声明的地方. TS
最大的优势在于, 它既继承了传统ES
的诸多优秀特性, 又推出了一些新的特性(接口
)等.
20.3 参考
略
21. VS Code
的插件是你独立开发的吧?
21.1 问题描述
略
21.2 问题解决
灵感来源
起初在 VS Code
的 repo
看到了国外开发者提的一个 issue
, 原意就是他需要在 VS Code
的某个工作区文件夹内快速查找一个文件.
需求分析
实际上, VS Code
已经集成了查找文件的功能, 但是是有明显的缺陷的, 它只能在所有工作区文件夹内查找, 而我只需要在特定的文件夹内查找文件.
潜在问题
之前写过一个初始版本, 但是是存在一些问题的, 比如:
- 不能输入提示
- 无法处理回退时产生的问题
一直有一个重构插件的计划, 但是由于电脑使用过代理, 导致 VS Code
的插件开发服务器无法正常启动, 进而该计划一直被搁置, 目前仍未解决.
21.3 参考
略
22. 你目前正在参与的开源项目
23. TS
在什么情况下使用 any
?
23.1 问题描述
略
23.2 问题解决
场景一: 工具函数
any
, 顾名思义, 就是 任意
的意思. 当一个函数, 需要接收任意类型的参数的时候, 可以使用它:
1 | // 获取值的类型 |
23.3 参考
略
24. 有了解哪些 redux
的异步中间件?
24.1 问题描述
略
24.2 问题解决
由于最早接触的是 redux-thunk
, 其实也有很多优秀地数据管理库, 比如: redux-saga
、redux-promise
…
对于 redux-thunk
, 有必要了解下它的原理, 正所谓知其然知其所以然.
24.3 参考
略
25. redux-thunk
的原理是什么, 它的优势在哪里?
25.1 问题描述
略
25.2 问题解决
原生 dispatch 的劣势
redux
通过 dispatch
来派发一个 action
来操作数据, 那么假如我需要记录每次 dispatch
的记录, 应该怎么做? 最简单的方法应该是:
1 | console.log('dispatch...', action); |
但是这样会产生大量的重复代码, 所以需要对于原生的 dispatch
进行一层封装, 需要用到 applyMiddleware
applyMiddleware
redux
通过暴露出 applyMiddleware
方法, 使得开发者可以很方便的自定义 dispatch
.
redux-thunk
redux-thunk
的原理很简单, 改造 dispatch
, 返回一个接收 store
作为对象的函数, 在异步任务执行完成的时候再进行 dispatch
.
redux-thunk 的优势
就一个词: 简单易用, 很容易理解
25.3 参考
26. 你对代码质量的要求是怎样的?
27. CSS
的大小单位有哪些?
28. 使用 CSS
在不占用多余空间的情况下画一个三角形
29. CSS 计算题
29.1 问题描述
给定一个容器 div(width: 100, height: 200
) 和一个子代 div(width: 20, height: 10, padding: 10%
), 求子代 div
元素的宽度.
1 | <div class="parent"> |
1 | .parent { |
29.2 问题解决
坑点一: 盒子模型
- IE 盒模型: 元素的宽度 = width + padding + border
- W3C 盒模型: 元素的宽度 = width
坑点二: 百分比 margin/padding
元素的 margin
或者 padding
属性, 如果设置为 百分比, 则会以其父级的 width
来计算.
结果
- IE 盒模型: div 宽度 = 20
- W3C 盒模型: div 宽度 = 20 + 100 * 10% * 2 = 40