我真的太后知后觉了..., 本来觉得实习是大四的事情, 暑假安心在家里摸鱼, 三月初某天和一样是17级的同窗聊天时, 忽然知晓对方已经到了字节跳动前端终面, 顿时一惊, 问了才知道原来有暑假实习这个东西! 并且还仅限大三(研二)! 因而火速开始复习前端基础以及复盘以前的项目. 当时的规划大概是这样色的:html
GraphQL
的BFF, CI/CD/Docker/Serverless/错误监控/埋点都有实践..., 重点准备并做为简历亮点(后来事实证实这一块真的挺重要).肯定了规划以后我就开始8107的准备了, 大概在3-18投出了简历, 经历20天5轮技术+1轮HR成功上岸.前端
这一面主要问了基础部分, 一部分题目我会带上提示html5
TCP 三次握手/四次挥手/等待2MSL意义/创建链接但客户端故障webpack
我这里还提了握手失败/泛洪攻击/RST包等ios
TCP 慢启动/拥塞控制, 快速重传/快速恢复, 这也是我准备比较多的, 毕竟以前没接触过.git
TCP UDP QUIC(QUIC是Http3的底层协议)程序员
Http2相对于Http1.1新增了哪些东西, 主要是信道复用之类的.github
浏览器渲染过程, 注意只是渲染过程, 就是从解析DOM树到展现在屏幕这个过程web
主要是 令牌化/建树/收集样式表/布局渲染树/绘制列表/栅格化/绘制图块/...这些过程, 推荐阅读浏览器的工做原理:新式网络浏览器幕后揭秘面试
强缓存与协商缓存, 主要讲了下E-Tag
和Last-Modified
以及对应的标识, 强缓存方案与协商缓存方案的场景, 好比index.html
该用哪一个?
CSS的水平居中与垂直居中, 这个因为我平时CSS写的很少, 一般是在UI库基础上作微调, 只回答了以前记录的方案.
移动端1px, 老问题啦.
Git操做, 主要是revert与reset, 咱们工做室使用的是Git Flow, 而且区分Master和Dev分支这种, 小哥说了一个Git Flow没法handle的场景, 即一个feature还未合并到Master, 可是后面的一个feature已经经过提测要并进主干, 这时要如何处理?
React: 新旧生命周期的问题, 为何要废弃旧版的(约束开发者以及Fiber
架构可能会将其打断), 新版的有什么特色(getDerivedStateFromProps(nextProps, prevState)
, 这个方法是静态方法, 也就说你没法在里面获取到this, 还有就是入参为prevState
, 这样就保证state
和props
之间更隔离). 还有就是我以为很好玩的getDerivedStateFromErrors
和componentDidCatch
的协做.
React: PureComponent, 浅比较, 关于浅比较这个我在本身以前一篇讲useSelector的文章中提到过. 放一下shouldComponentUpdate
中shallowEuqal
的源码:
const hasOwn = Object.prototype.hasOwnProperty;
function is(x, y) {
if (x === y) {
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
return x !== x && y !== y;
}
}
export default function shallowEqual(objA, objB) {
if (is(objA, objB)) return true;
if (
typeof objA !== "object" ||
objA === null ||
typeof objB !== "object" ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) return false;
for (let i = 0; i < keysA.length; i++) {
if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
}
return true;
}
复制代码
React: setState以后发生的, 这个当时没怎么看, 只是回答了一下批量更新, 还有在合成事件与原生异步事件中的不一样表现, 我我的认为其本质仍是同步的哈.
屡次setState的合并与获取最新的state, 其实这俩个是同一处代码(好像是particalState
), 内部对参数的Object
类型和Function
类型作了不一样的处理, 为函数的状况下, 会在setState调用完成而且组件开始rerender的时候被调用.
Node: stream和Buffer, 面试前不久刚写过流式的文件上传因此记忆犹新, 回答了四种流(可写/可读/可写可读/可转换), 以及经常使用的几个pipe方法.
Buffer的话主要提了一下它是堆外内存(V8的常驻内存由代码区/栈/堆/堆外内存组成)啥的.
Node: 内存管理, 这个也是面试前看到过经过启动命令更改堆内存上限的文章因此了解的多了一下, 主要关键词有 新生代/老生代假说, Scavenge算法(采用复制实现内存回收, 典型的牺牲空间换时间), From/To空间, 标记清除, 标记整理, 增量标记(将标记阶段拆分为控制在5ms内的小步骤, 每隔一段时间执行, 提升程序流畅性.)
一面主要问的都是基础, 面试官给个人感受就像学长同样! 还给我解答了一哈回答得很差的问题. 一面时间大概一个多小时, 感受问题都问到我心坎上了? 就是没有问到不太会的问题.
X-XSRF-TOKEN
机制. 惋惜是在面试后才看到冴羽大大的预测最近面试会考 Cookie 的 SameSite 属性, 否则还能加一波分?可能由于简历上写的工程化比较多, 二三四面都问了比较多工程化的东西.
微信小程序, 这个是二面的重点提问之一, 包括如下几个方面:
sessionKey
生成token, openid做为主键入数据库, 再返回自定义的登陆态标识.@Penumbra/cli, 这是我本身写的一个思路相似Feflow
的脚手架, 也是 脚手架核心+模板插件包+构建器 的一个组合, 模板插件包的话, 前端包含 Webpack
/Parcel
+ TypeScript
/JavaScript
的组合, 后端包含Koa
/Egg
+ RESTFul
/GraphQL
的组合. 主要问了这些问题:
Parcel
, 这个主要是由于一些小项目小demo用Parcel
是真的简单, 好比这个我本身搭的一个Parcel-Tsx-Template, 真-开箱即用, 真-零配置. 可是要写什么正式项目的话, 仍是老老实实Webpack.Parcel和Webpack, 由上面的展开问的, 说了一下两者的差别(内置HMR与代码分割, 预置配置), 还有就是Parcel
其实也有Loader
和Plugin
, 以前翻了一下源码, 叫@Parcel/transformer-xxx
这种. 还有就是Parcel
打包前会作资源树分析优化, 而且过于黑盒, 内部写死了一套配置(好像叫config.json
).
还顺便提了下Umi, 由于简历上有个Umi
+ Dva
+ Antd Pro
的项目, 分析了下Umi
啥的: 我我的以为Umi是"框架的框架", 即在Webpack
的基础上作了一套性能调优到极限的配置和知足大部分开发需求的生态(插件)等等.
错误监控, 咱们目前使用的方式是Sentry
以及Release时上传Source-Map
文件的方式. 本身实现的话, React的思路主要是一个最外层的<ErrorBoundry />
组件, 借助getDerivedStateFromError
与componentDidCatch
来捕获错误.
Https加密机制
Git Rebase 与 Git Merge
Flutter 与 React Native底层, 我只讲到Skia引擎, 毕竟Flutter还没写过完整项目...
Serverless, 这一块我主要讲了FaaS
以及BaaS
, 还有Serverless
对前端意义, 这个问题千人千面, 我本身的理解不必定是对的, 就不展开来说了.
二面主要针对项目进行发问, 不得不说果真是前辈, 不少项目死角都被揪出来了, 还好的确以前花了时间思考了下也答上来了. 建议复盘项目能够找个有经验的同窗来帮你想一想这个项目会从哪些角度被提问, 毕竟当局者迷嘛.
三面和四面发问的角度和提出的问题比较相似, 所以就放在一块儿讲了.
介绍项目, 我一般会问面试官是对业务型项目仍是设施型项目比较感兴趣, 业务型的话就介绍小程序, 设施型就介绍@Penumbra/cli
.
小程序因为 UI/交互/先后端都是本身搞的, 因此能讲的真的蛮多, 可是一般会更聚焦于这个小程序的业务场景(图书资源整合), 这也是在介绍项目时我以为比较好的一种方式:
不要东扯一点西扯一点, 以 技术栈 -> 业务场景 -> 亮点 -> 难点 -> 提炼总结 -> 自我提高 这几个步骤来叙述会更加条理清晰, 其中亮点/难点以STAR
法则介绍最佳.
@Penumbra/cli
这个, 上面已经介绍过, 就再也不赘述. 主要为了体现 新工程目录创建繁琐 -> 应当成员之间统一目录结构 这个意识.
GraphQL, 可贵遇到会问这个的, 要知道我但是把这个做为简历亮点的, 可是却无人问津..., 主要介绍了这些:
GraphQL
做为应用的主API(除非出现了为图式查询而生的数据库, 至于FB和GitHub的GraphQL API我以为是其内部有自研的方案), 也就是让后端同窗来搞, 大部分场景应该仍是后端同窗搞微服务, 而后前端同窗本身来写一个BFF层作接口的聚合/清洗/鉴权等等, 也就是说并不会"这个世界充满了对后端的压迫, 后端何时才能站起来, 气抖冷"hhhh. 既然让前端写, 那确定是用Node了, 这个时候Apollo
这些方案就真的很香了(下面会多介绍下.)Apollo-Server
& TypeGraphQL
& Apollo-Rest-Datasource
, 至于它们是什么感兴趣同窗能够去查查. Apollo不只提供了服务端支持, 也提供了客户端支持, 即Apollo-Client
, 同时使用Server
和Client
来构建应用真的能起到1+1>2的效果, 由于两者就像是一体的.Webpack性能调优, 我从 打包速率 / 打包大小 / 交互友好 三个方面入手的, 这里能够稍微列举一些我以为比较好用/有趣的Plugin:
VuePress
就用的这个)至于从配置入手的话, 主要是减小查找文件时间和减小build代码体积, 前者能够经过resolve
字段中配置extension
, loader中配置exclude
, 后者的话则主要是Tree-Shaking(注意, CSS也能够作摇树优化), 代码分割(动态加载以及Lodash/Antd这种庞大的模块), Source-Map模式, 压缩代码等等.
React函数式组件, 我以为之后会是主流?
React Hooks:
useState
useEffect, 不传dep与传入[], 分别对标类组件的哪一个生命周期.
useLayoutEffect
useRef, 还有useImperativeHandle与forwardRef, 摘抄一下以前的笔记, 也可参考[译]React高级话题之Forwarding Refs
useRef,使函数式组件也可以享受到获取 DOM 元素或者自定义组件,父组件获取子组件引用然后调用子组件方法,如 focus 等。
forwardRef,能够获取父组件的 ref 实例做为子组件的参数(与 props 同级),而后再把这个 ref 绑定到本身内部节点,就能够实现 ref 的透传了!
useImperativeHandle,常与 forwardRef 搭配使用,能够控制向父组件暴露的属性以及方法,第一个参数即为 forwardRef 包裹后获得的父组件 ref 实例。
useMemo与useCallback
其余的没怎么用到过就老实交代不记得了.
Hooks思想, 好比Vue3的新API, 社区React生态也在纷纷拥抱Hooks思想, 好比上面提到的的React-Redux
的useSelector和useDispatch
, React-Use
还有Umi-Hooks
等等.
Node的Cluster模块, 主从模式, 底层的Libuv.
CI/CD, 咱们工做室的流程仍是挺完善的, 包括commitlint -> Husky + Lint-Staged + Code Review*n + ZEIT/now测试环境, 而后才是Gitlab pipeline到OSS.
埋点, 这一块我以前调研过, 能够读读我以前写的这篇关于埋点的一些思考, 主要是以GA为表明的一键式埋点方案, 以MixAlpha/神策数据为表明的可视化埋点等.
测试, Jest/Enzyme/Puppeteer编写单元/集成/E2E测试. 稍微问了下单测覆盖率, 很没底气的说了可能就50%不到hhh.
Flutter, 感受这种不是比较熟练的技术放到简历上不太好, 好比我用Flutter只能写写简单的Widget和页面这种, 因而就没问得太多.
五面的面试官可能比较忙, 所以整个面试过程大概就二十分钟左右. 也是介绍了一下小程序与脚手架, 面试官应该是高P, 主要关注我在团队中的角色, 我对本身的定义集中在 参与前端技术栈选型&推进新的前端架构&参与对新人培训指导等, 这一块的话也是以本身的经历为主, 若是你是独行侠, 也能够讲一讲本身在社区的贡献等等, 不要直接说你喜欢独来独往一我的全干.
这一面就是常见的问题啦:
这些问题比较主观, 为了不误导我就不放本身答案了.
只能说面试真的是很玄学的东西, 若是每一面都能碰见和你至关match的面试官, 那整个面试流程真的会很轻松愉快. 春招逐渐接近尾声, 也但愿你们都能拿到本身满意的offer, 还在面试的同窗能够读读我整理的前端基础, 感受有用的话就点个⭐吧~
对将来前端的展望是二面问到的问题, 我我的的想法主要分这么三点:
Rax
或者Taro
, 真正的一次编写到处运行. 固然理想是好的, 在它还未乘着七彩祥云到来前, 仍是专心学好每一端吧~Serverless
无疑是前端仔的下一个风口, 它给予了咱们向后端进发的能力, 让咱们"本身和本身联调", 也无需操心本身写的服务被流量打爆掉. 后端同窗则可以解放出来, 去作一些更有意义的事情.(真的不是抢饭吃)