最近在忙着准备找实习, 所以没有更新之前的文章.
不过所幸功夫不负有心人, 我拿到了腾讯的 offer.
这里分享一下面试的经验.
简介
本人双非本科, 普通学生一枚.
面的是腾讯的 web 前端开发.
整个面试一共有四轮, 分为: 一面(笔试 \ 初试) 二面(技术 \ 复试) 三面(项目 \ 复试) 四面(HR \ 终面)
一面
我是在五月份的时候收到的初试的消息
第一面的形式是远程视频面试, 在牛客网上进行.
面试首先肯定是一个自我介绍, 这里我就不赘述了
聊了一下我的大概情况过后, 然后就开始面试了
第一个问题:
怎么判断一个对象是不是数组?
首先可以用 ES5 提供的 isArray 方法进行判断, 这个方法应该是最官方的
可以使用 instanceof Array 来判断, 不过这种方式存在问题, 比如当存在多个全局对象(如使用 ifream), 那么这个窗口的 Array 对象对另一个窗口使用 instanceof 就会判断失败
这里是我当时给的答案(在 JS 高级编程一书中有), 通过 toString 来进行判断
- function isArray(value){
- return Object.prototype.toString.call(value) === "[object Array]";
- }
第二个问题:
了解深拷贝与浅拷贝吗? 你能实现一下深拷贝吗?
这个问题首先我们要知道深拷贝浅拷贝的区别, 我们知道 JS 的值分为基础类型和引用类型, 也就是说在进行赋值操作时引用类型赋值的实际上只是将地址进行赋值
也就是两个变量指向了同一个地址, 浅拷贝呢就是正常的赋值操作, 而深拷贝则希望是一个新的独立的值, 而不是仅仅拷贝地址
由此我们可以给出以下拷贝函数(这里给的代码只是一个示意, 并不是最佳实践)
- function deepClone(obj){
- let objClone = Array.isArray(obj)?[]:{};
- if(obj && typeof obj==="object"){
- for(key in obj){
- if(obj.hasOwnProperty(key)){
- // 判断 ojb 子元素是否为对象, 如果是, 递归复制
- if(obj[key]&&typeof obj[key] ==="object"){
- objClone[key] = deepClone(obj[key]);
- }else{
- // 如果不是, 简单复制
- objClone[key] = obj[key];
- }
- }
- }
- }
- return objClone;
- }
第三个问题:
知道继承吗? 实现一下?
这里的话我问了一下面试官, 使用 ES6 的 class 实现, 还是使用原生 JS 实现?
面试官说都可以, 我就用的原生 JS 写的, 用的组合继承的方式
- function SuperType(){
- this.property = true;
- }
- SuperType.prototype.getSuperValue = function(){
- return this.property;
- };
- // 创建一个新的构造函数
- function SubType(){
- // 调用父类的构造函数
- SuperType.applay(this,arguments);
- this.subprototype = false;
- }
- // 重写这个构造函数的原型对象让其指向 SuperType 的实例
- SubType.prototype = new SuperType();
- // 修改 constructor 让其指向正确地构造函数
- SubType.prototype.constructor = SubType;
- // 添加这个新构造函数的自身的方法
- SubtType.prototype.getSubValue = funtion(){
- return this.subproperty;
- }
- var instance = new SubType();
- alert(instance.getSuperValue()); // true 可以访问到原型对象上的方法和属性
到这里视频面试在线打代码的部分就完成了, 后面就问了一些前端方面的问题
第四个问题:
你了解 XSS 和 CSRF 吗?
回答了解, 之后就会详细问了.
首先 XSS 分为以下三种
反射型 XSS: 在 url 上拼接攻击代码, 访问 get 请求的接口, 来注入 XSS 代码
MXSS:DomXSS 在 dom 元素的 title , name 等属性注入
存储型 XSS: 通过表单 (一般是评论区等地方) 提交 XSS 数据, 等后台从数据库中读取返给前端页面时生效
CSRF 的攻击方式则是, 当用户登录过 A 网站通过 A 网站的合法性身份校验过后, B 网站通过钓鱼链接等形式获取用户在 A 网站的合法身份来进行攻击
两者的区别:
最大的区别在于 CSRF 需要用户完成合法性验证后才能进行, 而 XSS 则不需要
防御:
XSS 的主要防御手段是通过前后端的数据过滤来实现, 对一些 html 的特殊字符进行转义
CSRF 的主要防御手段则是通过使用 token 验证来验证用户身份的合法性
一面的主要内容就是上述几个问题, 整个过程 45 分钟, 我在打代码的时候当时有个逻辑写反了, 找了很久都没有找到问题, 最后是被面试官指出了, 所以在面试官那落了个马虎大意的不良印象.
不过最后还是顺利通过了初试. 在第二天的晚上面试状态就变为了复试.
二面
在面试状态变更后的一个礼拜后预约了复试的时间(因为中间过了个端午)
同样的首先是自我介绍, 然后就进入正题.
第一个问题:
浏览器输入网址后到页面显示的整个过程?
DNS 解析
TCP 连接建立(三次握手, 四次挥手)
加载文件(HTML,JS,CSS)
渲染页面(生成 DOMtree,CSSrule, 结合成 render tree , 页面布局, 元素绘制)
第二个问题:
HTTPS 和 HTTP 的区别? 采用的加密算法?
http 使用明文传输, https 采用加密方式传输
具体加密过程如下:
客户端向服务器发起 HTTPS 请求, 连接到服务器的 443 端口(默认)
服务器端有一个密钥对, 即公钥和私钥, 是用来进行非对称加密使用的, 服务器端保存着私钥, 不能将其泄露, 公钥可以发送给任何人
服务器将自己的公钥发送给客户端, 客户端收到服务器端的公钥之后, 会对公钥进行检查, 验证其合法性, 如果发现发现公钥有问题, 那么 HTTPS 传输就无法继续. 严格的说, 这里应该是验证服务器发送的数字证书的合法性, 关于客户端如何验证数字证书的合法性. 如果公钥合格, 那么客户端会生成一个随机值, 这个随机值就是用于进行对称加密的密钥, 我们将该密钥称之为 client key, 即客户端密钥, 这样在概念上和服务器端的密钥容易进行区分. 然后用服务器的公钥对客户端密钥进行非对称加密, 这样客户端密钥就变成密文了, 至此, HTTPS 中的第一次 HTTP 请求结束
客户端会发起 HTTPS 中的第二个 HTTP 请求, 将加密之后的客户端密钥发送给服务器
服务器接收到客户端发来的密文之后, 会用自己的私钥对其进行非对称解密, 解密之后的明文就是客户端密钥, 然后用客户端密钥对数据进行对称加密, 这样数据就变成了密文
然后服务器将加密后的密文发送给客户端
客户端收到服务器发送来的密文, 用客户端密钥对其进行对称解密, 得到服务器发送的数据. 这样 HTTPS 中的第二个 HTTP 请求结束, 整个 HTTPS 传输完成
对称加密: DES
非对称加密: RSA
第三个问题:
cookie 的作用? cookie 的安全? cookie 与 webstorage 的区别?
cookie 的作用:
cookie 可以跟踪会话, 弥补 HTTP 无状态协议的不足
判断用户是否登陆过网站, 以便下次登录时能够实现自动登录(或者记住密码). 如果我们删除 cookie, 则每次登录必须从新填写登录的相关信息
保存上次登录的时间等信息
这里面试官就问我, 使用 Cookie 来做状态保持是否安全? 怎么解决?
首先 Cookie 是不安全的, 可以通过脚本获取, 也能被中间人截取
解决方案:
Cookie 内容加密
设置 HttpOnly 头(无法使用 JS 获取 Cookie)
Secure:true (只有在 HTTPS 时才发送 Cookie)
设置过期时间
Cookie 与 Webstorage (H5 提出的用于替代 Cookie 的解决方案)的区别:
生命周期: localStorage:localStorage 的生命周期是永久的, 关闭页面或浏览器之后 localStorage 中的数据也不会消失. localStorage 除非主动删除数据, 否则数据永远不会消失. sessionStorage 的生命周期是在仅在当前会话下有效. sessionStorage 引入了一个 "浏览器窗口" 的概念, sessionStorage 是在同源的窗口中始终存在的数据. 只要这个浏览器窗口没有关闭, 即使刷新页面或者进入同源另一个页面, 数据依然存在. 但是 sessionStorage 在关闭了浏览器窗口后就会被销毁. 同时独立的打开同一个窗口同一个页面, sessionStorage 也是不一样的
存储大小: localStorage 和 sessionStorage 的存储数据大小一般都是: 5MB
存储位置: localStorage 和 sessionStorage 都保存在客户端, 不与服务器进行交互通信
存储内容类型: localStorage 和 sessionStorage 只能存储字符串类型, 对于复杂的对象可以使用 ECMAScript 提供的 JSON 对象的 stringify 和 parse 来处理
应用场景: localStoragese: 常用于长期登录(+ 判断用户是否已登录), 适合长期保存在本地的数据. sessionStorage: 敏感账号一次性登录
相比 Cookie 的优点:
存储空间更大: cookie 为 4KB, 而 WebStorage 是 5MB
节省网络流量: WebStorage 不会传送到服务器, 存储在本地的数据可以直接获取, 也不会像 cookie 一样每次请求都会传送到服务器, 所以减少了客户端和服务器端的交互, 节省了网络流量
快速显示: 有的数据存储在 WebStorage 上, 再加上浏览器本身的缓存. 获取数据时可以从本地获取会比从服务器端获取快得多, 所以速度更快
安全性: WebStorage 不会随着 HTTP header 发送到服务器端, 所以安全性相对于 cookie 来说比较高一些, 不会担心截获, 但是仍然存在伪造问题
WebStorage 提供了一些方法, 数据操作比 cookie 方便
第四个问题:
前端性能优化的手段?
网络加载
减少 HTTP 资源请求数: 合并静态资源, 构建工具合并雪碧图 \ 避免重复资源
减少 HTTP 请求大小: 对文件进行压缩优化, 使用 gzip 传输压缩内容 \ 移除代码注释压缩代码
将 CSS,JS 放到外部文件: HTML 引用外部资源可以有效利用浏览器静态资源缓存
避免空的 href 和 src
指定 Cache-Control 或 Expires
合理设置 Etag 和 Last-Modified
减少页面重定向
静态资源分域存放增加下载并行数
静态资源 CDN 来存储文件
CDN Combo 下载传输内容
缓存 Ajax cache 属性设置为 true
使用 Get Ajax 的速度比 POST 请求快
减少 Cookie 大小进行 Cookie 隔离(分域存放静态资源)
异步 JS
避免 CSS import 加载 CSS
页面渲染
CSS 资源放到页面顶部
JS 放到页面底部
不在 HTML 中缩放图片
减少 DOM 元素数量和深度
避免使用 < table><ifream > 等慢元素, 这些元素会整个渲染完成后再绘制到页面上
避免使用 CSS 表达式或 CSS 滤镜
第五个问题:
前端性能检测?
Performance Timing API\ 浏览器 Profile 工具 \ 页面埋点 \ 资源加载时序图 用于获取页面加载的性能
如果是远程监控用户的页面性能则需要将相关数据上传到服务器存储
第六个问题:
你了解算法吗?
我: 了解一点
你知道堆排序和快排的区别吗?
我: 数据结构不同, 堆排是一种树状结构, 时间复杂度都是(nlogn 最好)
他们的时间复杂度一样, 为什么平常更多使用快排, 而不是堆排?
堆排的时间常量要大于快排, 也就是执行交换操作的性能不同, 在性能上快排的性能略优于堆排, 并且使用场景中快排效率最坏的情况的概率比较小
快排: 数组中交换数据, 在数据量不是特别大, 而且离散程度较高的情况下效率很高
堆排序: 创建堆, 数据交换, 调整堆的时间均很多
所以在实际应用中, 我们用快排会更多一点
平时学习的方式?
我: 前端掘金社区, GitHub , infoq, 博客, 书籍
大概多长时间看完一本书?
我: 第一遍通看一个星期, 完全掌握差不多要一个多月.
有没有对书上的内容进行实践?
我: 能够实践的部分会做一些 demo, 不好实践的部分则会分享一些自己的学习笔记在博客上
你的博客在外网能够访问吗?
我: 可以, 然后给了链接
然后二面的内容就差不多了, 期间问了一些简历上的项目, 这里因人而异所以我就不再多说了, 整个过程大概 65 分钟.
这里到三面有一个小插曲, 我看见我官网上的面试流程变灰了, 我以为挂掉了, 还郁闷了几天
不过三天后告诉我约了下一场面试.
三面
首先仍是万年不变的自我介绍:
然后面试官问了:
你觉得简历的哪个项目对你来说最有挑战性?
中间遇到什么困难?
你是怎么解决的?
如果让你继续开发你觉得有什么改进的?
你觉得你的项目市场前景如何?
你在项目中负责的工作?
你是怎么做的?
你的职业规划?
你的目标?
你最近在看什么书?
你看过的书中哪一本对你影响最大? 为什么?
这一面主要就是问你简历的项目了, 回答项目的时候从
背景
目标
行动
结果
的顺序来答就好, 至于其它的问题就只能看你自己的临场发挥了
在两天的焦急等待后, 收到了 HR 面的通知
终面
终面的 HR 是个女 HR, 我之前一度以为我去的部门只有汉子
简单的自我介绍过后就开始聊人生
问题:
你为什么要来实习?
你大学参加的这么多比赛里面哪一个让你印象深刻? 为什么?
你是怎么改进的?
你有没有面试其他的互联网公司?
你为什么选择要来面腾讯?
HR 面的话, 问题就和技术没啥关系了, 感觉主要考察的就是你的意愿强不强烈
你的为人处世, 性格等方面
我当时对于这些问题, 就一直表示十分希望能够进入腾讯
如果看过我早期的文章的同学, 应该知道我在去年就投过腾讯的实习, 然后在一面就光荣的挂掉了
所以在 HR 问我最后问题的时候我的原话是这样的:
"我十分希望能够进入腾讯, 您那边可能也知道我在去年就投过咱们公司, 当时确实是因为自己的能力达不到咱们公司的要求, 不过这一年我一直都在努力提升自己, 这次面试才走到了现在, 就算这次我或许没有达到要求, 没有机会到咱们公司实习, 但是我认为只要我一直努力早晚能够达到咱们公司的要求."
到这里 HR 就笑了, 说她没有什么问题要问我的了, offer 的话后面有人会联系你.
我当时都惊了, 我看其它大佬的面经的时候都是回去等通知, 没有直接说 offer 的事情的.
我也不知道, 在面试中我哪一点吸引了面试官, 不过最终还是如愿以偿地拿到了 offer
结语
这里的话我想说, 面试的话很多时候最后我们都可能拿不到我们心仪的 offer, 面试确实是一个比较看运气的事情
但是面试就算结果不太理想, 但是确实是一个发现自己不足的很好的机会.
我从今年的 3 月开始准备面试, 期间面了 阿里, 京东, 字节跳动, 美团, 腾讯(offer 之前面的一次腾讯三面被刷)
就通过这些面试找到自己知识点的不足, 然后面完过后就去查, 弥补这些不足, 最后终于如愿.
感谢昨天的自己的努力, 不忘初心, 方得始终.
希望大家都能拿到自己心仪公司的 offer.
来源: https://www.cnblogs.com/lhyxq/p/11050299.html