不知道哪里来的资料,这么齐全,反正我是被他征服了,这个资料在闯客网技术论坛可以下载,可能属于有生之年系列吧,适合小白系统性学习,也适合大神进阶型学习,简直不要太齐全的资料,具体看目录吧
下载链接:https://bbs.usoftchina.com/thread-210623-1-1.html
以下是书籍目录:
│ ├── 设计模式:可复用面向对象软件的基础.机械工业出版社.扫描版.zip
│ ├── 设计模式解析.pdf
│ ├── 深入浅出设计模式.pdf
│ ├── 事务处理原理 第2版.zip
│ ├── 数据结构(C语言版严蔚敏著).pdf
│ ├── 算法导论中文版.zip
│ ├── 我编程,我快乐——程序员职业规划之道.zip
│ ├── 现代操作系统.zip
│ ├── 修改代码的艺术.pdf
│ ├── 重构改善既有代码的设计.pdf
│ ├── 重构与模式.pdf
│ ├── 卓有成效的程序员(中文版).zip
│ └── 最后期限.pdf
├── Java/
│ ├── java十大经典书籍/
│ │ ├── Java编程系列书籍/
│ │ │ ├── JAVA2核心技术卷1:基础知识(原书第7版).pdf
│ │ │ ├── JAVA2核心技术卷2:高级特性(原书第7版).pdf
│ │ │ ├── Java编程思想(第4版).pdf
│ │ │ ├── Java并发编程实战(中文版).pdf
│ │ │ ├── 《Effective Java中文版 第2版》.(Joshua Bloch).[PDF]&ckook.pdf
│ │ │ ├── 疯狂Java:突破程序员基本功的16课.pdf
│ │ │ └── 深入java虚拟机(原书第2版).pdf
│ │ ├── 程序员提升系列书籍/
│ │ │ ├── Head First Java.第二版.中文完整高清版.pdf
│ │ │ ├── 程序员自我修养.pdf
│ │ │ ├── 大话数据结构_.pdf
│ │ │ └── 鸟哥的Linux私房菜 基础学习篇(第三版).pdf
│ ├── Flex+白皮书.pdf
│ ├── Flex3高级图表开发指南.pdf
│ ├── Head First Java 中文高清版.pdf
│ ├── Head First Servlet JSP(清晰中文版).PDF
│ ├── Head First 设计模式.pdf
│ ├── HttpClient入门.pdf
│ ├── ibatis开发指南.pdf
│ ├── Java EE 7平台:走进云计算.pdf
│ ├── Java.Servlets.编程指南.pdf
│ ├── Java2参考大全(第四版)解密.pdf
│ ├── Java2网络协议技术内幕.pdf
│ ├── Java案例开发.pdf
│ ├── Java并发程序设计教程.pdf
│ ├── Java解惑(中文).pdf
│ ├── Java设计模式之抽象工厂模式.pdf
│ ├── Java数据结构和算法.pdf
│ ├── Java数据结构和算法中文第二版.pdf
│ ├── Java线程.pdf
│ ├── Java夜未眠_程序员的心声.pdf
│ ├── JAVA优化编程.pdf
│ ├── Java语言编码规范.PDF
│ ├── JBPM工作流开发指南 .pdf
│ ├── JDK1.5的泛型实现.pdf
│ ├── JSTL标签.pdf
│ ├── Spring基础教程.pdf
│ ├── SPRING开发指南.pdf
│ ├── spring框架,技术详解及使用指导.pdf
│ ├── SQL完全手册.pdf
│ ├── Struts 2 in Action.pdf
│ ├── struts2权威指南.pdf
│ ├── Struts中文手册.pdf
│ ├── [Flex.3实战].(美)艾哈迈德,(美)赫希,(美)阿比德.扫描版.pdf
│ ├── [大家网]Java2核心技术II卷.高级特性7th.pdf
│ ├── [大家网]Java2核心技术第I卷.基础知识7th.pdf
│ ├── [代码大全2中文版(完整清晰版)].pdf
│ ├── 大话设计模式.pdf
│ ├── 高效程序员的45个习惯:敏捷开发修炼之道.pdf
│ ├── 黑客入门(超级详细版).pdf
│ ├── 经典查询练手.pdf
│ ├── 精通JavaScript(中文清晰优化版).pdf
│ ├── 精通spring - Mastering Spring.pdf
│ ├── 精通Struts基于MVC的Java Web设计与开发.pdf
│ ├── 罗时飞.精通spring.pdf
│ ├── 设计模式:Java语言中的应用.pdf
│ ├── 深入JAVA虚拟机.pdf
│ ├── 深入JAVA虚拟机第二版.pdf
│ ├── 深入学习:JFC SWING—JAVA 基础类组件集.pdf
│ └── 重构-改善既有代码的设计.pdf
├── Linux/
│ ├── Linux_操作系统-基础操作-教学.doc
│ ├── LINUX内核设计与实现.pdf
│ ├── linux内核深入剖析基于0.11.pdf
│ ├── Linux系统命令及其使用详解.doc
│ ├── Ubuntu_Linux从入门到精通.pdf
│ └── ubuntu安装教程.doc
├── PHP/
│ ├── PHP安全编程.pdf
│ └── 高性能PHP应用开发_itsrcs.com.pdf
├── TCP-IP/
│ ├── TCP-IP详解卷1:协议.pdf
│ ├── TCP-IP详解卷3:TCP事务协议,HTTP,NNTP和UNIX域协议.pdf
│ ├── TCP-IP详解卷三:TCP事务协议,HTTP,NNTP和UNIX域协议.rar
│ └── TCP-IP详解卷2:实现.rar
├── Unix/
│ ├── Unix编程艺术.pdf
│ ├── UNIX环境高级编程第二版.pdf
│ └── UNIX网络编程第2卷.pdf
├── VC/
│ ├── MFC.Programming.with.Visual.C.6.Unleashed.chm
│ ├── MFC类库详解.chm
│ ├── vc++6.0_调试详细教程.doc
│ ├── VC++动态链接库(DLL)编程深入浅出(全).pdf
│ ├── VC.深入详解(孙鑫).pdf
│ ├── VC_命名规范.doc
│ ├── VC调试方法.doc
│ ├── VC技术内幕.pdf
│ ├── Visual_C++MFC入门教程(免费版).doc
│ ├── 侯俊杰《深入浅出MFC》简体版第二版(PDF全).rar
│ ├── 深入浅出 MFC_华中理 工_简体版.pdf
│ ├── 深入浅出MFC.pdf
│ ├── 深入浅出MFC_简体中文版_侯捷.pdf
│ └── 用VC集成开发环境编译HelloDDK.doc
├── 标准文档/
│ ├── C99RationaleV5.10.pdf
│ ├── C99规范.pdf
│ ├── Intel.pdf
│ ├── ISO IEC 14882 2003 (C++03).pdf
│ ├── ISO IEC 14882 2011 (C++11).pdf
│ ├── ISO IEC 9899 1999 (C99).pdf
│ ├── Nasm手册.pdf
│ ├── The C89 Draft.html
│ └── yacc.ps
├── 操作系统/
│ ├── DOS命令.doc
│ ├── DOS命令大全.pdf
│ ├── Grub_多系统引导.doc
│ ├── MS-DOS命令大全.doc
│ ├── [操作系统概念.(操作系统恐龙书)].Silberschatz.Galvin.Operating.System.Concepts.7th.ED.pdf
│ ├── 多系统启动引导的研究.pdf
│ ├── 多系统启动引导原理.pdf
│ ├── 深入理解计算机系统.pdf
│ └── 现代操作系统第3版英文.pdf
├── 程序员/
│ ├── php基础教程-绝对推荐.ppt
│ ├── 编程高手箴言.pdf
│ ├── 超越对手:大项目售前售后的30种实战技巧.pdf
│ ├── 程序员必备技能.doc
│ ├── 程序员的自我修养—链接、装载与库.pdf
│ ├── 程序员面试宝典(PDF完整版).pdf
│ ├── 程序员修炼之道 从小工到专家.pdf
│ ├── 程序员之路探究.pdf
│ ├── 计算机科学导论 侯惠芳.pdf
│ ├── 蓝宝书Addison.Wesley.OpenGL.SuperBible.4th.Edition.Jun.2007.eBook-BBL.pdf
│ ├── 林锐-软件工程思想.pdf
│ ├── 马云给新人的一封信.pdf
│ ├── 企业家宣言(华丽重排版).pdf
│ ├── 清华大学计算机全套教程 加精.torrent
│ └── 腾讯-以用户为中心的互联网运营体系.pdf
├── 多线程/
│ ├── 多线程编程指南.pdf
│ └── 多线程的那点儿事.doc
├── 汇编语言/
│ ├── 汇编系列教程(第二季)/
│ │ ├── 39.寄存器与内存寻址.rar
│ │ ├── 40.数据容器.rar
│ │ ├── 41.数据访问宽度.rar
│ │ ├── 42.乘法与除法指令.rar
│ │ ├── 43.伪指令db,dw,dd.rar
│ │ ├── 44.操作符DUP.rar
│ │ ├── 45.操作符OFFSET.rar
│ │ ├── 46.JMP指令.rar
│ │ ├── 47.JMP指令段间转移.rar
│ │ ├── 48.JMP指令转移地址.rar
│ │ ├── 49.JCXZ指令.rar
│ │ ├── 50.位移超界.rar
│ │ ├── 51.RET与RETF指令.rar
│ │ ├── 52.CALL指令.rar
│ │ ├── 53.CALL指令与段间转移.rar
│ │ ├── 54.CALL指令与寄存器.rar
│ │ ├── 55.CALL指令与内存.rar
│ │ ├── 56.模块化程序设计.rar
│ │ ├── 57.子程序数据传递.rar
│ │ ├── 58.子程序安全调用.rar
│ │ ├── 59.标志寄存器.rar
│ │ ├── 60.ZF标志寄存器.rar
│ │ ├── 61.PF标志寄存器.rar
│ │ ├── 62.补码.rar
│ │ ├── 63.补码符号扩展.rar
│ │ ├── 64.补码加减运算.rar
│ │ ├── 65.SF标志寄存器.rar
│ │ ├── 66.CF标志寄存器.rar
│ │ ├── 67.OF标志寄存器.rar
│ │ ├── 68.ADC指令.rar
│ │ ├── 69.SBB指令.rar
│ │ ├── 70.CMP指令.rar
│ │ ├── 71.条件转移指令.rar
│ │ ├── 72.DF标志寄存器.rar
│ │ ├── 73.串传送指令.rar
│ │ ├── 74.标志寄存器与栈.rar
│ │ ├── 75.中断.rar
│ │ ├── 76.中断向量表.rar
│ │ ├── 77.INT指令.rar
│ │ ├── 78.BIOS中断例程.rar
│ │ ├── 79.DOS中断例程.rar
│ │ └── 80.端口.rar
│ ├── IBM_PC汇编语言程序设计__绪论.ppt
│ ├── 汇编语言王爽着.pdf
│ └── 汇编指令大全1.doc
├── 其他/
│ ├── Addison Wesley - 2001 - Knuth - The Art of Computer Programming VolI II III IV.rar
│ ├── AutoCAD 2004三维设计基础教程.pdf
│ ├── AutoCAD建筑制图技术与实践 2007版.pdf
│ ├── DirectX_9.0_3D_游戏开发编程基础.pdf
│ ├── DirectX教程.pdf
│ ├── ege.pdf
│ ├── Fedora14安装与软件配置完美方案.pdf
│ ├── GDI+编程.pdf
│ ├── GDI+参考.pdf
│ ├── GDI.txt
│ ├── ISO IEC 14882 2003 (C++03).pdf
│ ├── ISO IEC 9899 1999 (C99).pdf
│ ├── MSDN_1.5_SETUP.exe
│ ├── opengl读3ds文件格式.txt
│ ├── OpenGL教程.pdf
│ ├── OpenGL游戏编程.pdf
│ ├── WampServer2.1a-x32.rar
│ ├── win cmd.txt
│ ├── [SQL基础教程.第3版].(冯宇晖&贾文峰).扫描版.pdf
│ ├── [数字逻辑与计算机设计基础].刘真.文字版.pdf
│ ├── 编程珠玑2.pdf
│ ├── 编译原理中文版.pdf
│ ├── 泛型编程与STL.pdf
│ ├── 零基础学SQL.pdf
│ ├── 敏捷软件开发:原则、模式与实践.pdf
│ ├── 圈圈教你玩USB1.pdf
│ ├── 人工智能(AI)程序设计(面向对象语言).pdf
│ └── 设计模式-可复用面向对象软件的基础.pdf
├── 数据库与数据结构/
│ ├── C数据结构.pdf
│ ├── Win32+API函数库.chm
│ ├── 编译原理中文版.pdf
│ ├── 大话设计模式.pdf
│ ├── 大话设计模式(带目录完整版)[中文PDF+源代码].zip
│ ├── 大话数据结构.pdf
│ ├── 敏捷软件开发:原则、模式与实践.pdf
│ ├── 设计模式-可复用面向对象软件的基础.pdf
│ ├── 数据结构(Java版).pdf
│ ├── 数据结构课件.ppt
│ ├── 数据结构试题库答案.doc
│ ├── 数据结构习题解答与考试指导.pdf
│ ├── 数据结构习题解析 用面向对象方法与C++语言描述.pdf
│ ├── 数据结构与算法-面向对象的C++设计模式.pdf
│ ├── 数据结构与算法C++版.pdf
│ ├── 数据结构与算法分析C++描述第三版中文.pdf
│ ├── 数据结构与算法综合资料库.CHM
│ ├── 数据库系统概论.pdf
│ └── 殷人昆:数据结构(用面向对象方法和C++描述).pdf
├── 算法/
│ ├── Introduction to Algorithms(算法导论).pdf
│ ├── 编程之美.zip
│ ├── 经典算法大全.pdf
│ ├── 算法导论中文版+算法导论中文版.pdf
│ ├── 算法导论中文版.pdf
│ └── 现代计算机常用数据结构与算法.pdf
BaiduPCS-Go:/ 第四相思不相忆$
言
本文主要给大家带来一些我面试的经历和经验,希望对正在求职的同学有所帮助。我先大致说下面试之前的个人情况:2017年7月正式入职海康威视数字技术股份有限公司,使用Vue.js技术栈。
我写的篇幅可能有点长,如果只想看成功的面试请直接从阿里企业智能事业部(一面)开始,大家见谅哈。
关于阿里
Hi,大家好,我们是阿里巴巴新成立的BU,目前还有大量的Web前端职位空缺,机会难得,希望正在找工作的同学们可以来试试:
真的机会难得哦,如果想更多了解我们BU以及找我内推的同事加我钉钉或者微信(纯粹找我了解或者沟通技术也行,啊哈哈):18768107826
简历
我的简历只是简单的用MD做了一份,大致包含了以下几个部分:
小提示:在基本资料里一定要填写正确的邮箱地址,我在前期面试的时候都没有打开邮箱查看面试情况,导致一些面试的时间点和面试结果都不清楚(一直以为会发短信通知)。
如果去现场面试,一定要记得带上笔和简历。一方面你给面试官的简历必定是最新的(在不断面试的过程中你必定会修改简历),另一方面这也会给面试官一种非常舒心的感觉。
对于简历这里提一点,在写自己的专业技能和项目经历时尽量不要给自己挖坑,这里展示一下我的专业技能(我会的不多):
切忌写一大堆让人感觉花里胡哨的技能,尤其是一些很浅显的技能(基本技能除外)。如果你有一些别人很难替代的技能,那这些技能就是亮点了,我这里就没什么亮点技能。有些技能你会但是不熟练,你可以适当的在你的项目经历中体现出来。对于项目经历尽量挑自己觉得非常有技术含量的项目进行说明(宁缺毋滥),对于自己参加过但不是特别熟悉的项目尽量不要填写,防止给自己挖坑。
小提示:这里附上的我的面试简历供大家参考。感谢jsliang的文章2019 面试系列 - 简历,大家制作简历时也可以参考这篇文章。
在投递简历时大家千万不要被招聘信息中的要求吓到,记得有一次投递简历时我对招聘者说自身不太符合要求,招聘者当时说要求都是唬人的,觉得有兴趣就投,有些招聘要求可能正是你未来学习或者深入的领域。
面试
简历制作完后我大概投了四家公司:有赞、滴滴、51信用卡和阿里。其中有赞挂在二面,滴滴挂在一面,51信用卡挂在一面,阿里两个部门挂在一面,一个部门面试成功。很多面试者的经历可能都是像我这样,在一次次的面试失败中不断的总结进步,最终拿到理想的Offer。
小提示:建议大家在投递简历时可以先投递一些试水的小公司,先检验一下自己是不是可以胜任这些公司的面试。同时在每一次面试完后记得把面试官提问的问题记录下来,对于没有答上来的问题还是要好好搞懂或者实践一下,因为很有可能下一家的面试官会问同样的问题。
在面试的过程中,这里我给出几点意见:
接下来我会按照面试顺序给出面试题以及自己理解的一些答案:
有赞(一面)
说说CSS选择器以及这些选择器的优先级
你知道什么是BFC么
小提示:这个问题重点是BFC是什么,BFC触发的条件有哪些,BFC可以干什么。这里我试着讲解了一下Boostrap的清除浮动(display:table创建匿名table-cell间接触发BFC),如果有看到别的场景使用或者自身有使用的场景可以尝试讲解一下使用技巧。这样可以让面试官觉得你不仅仅知道他问的东西是什么,你还能很好的使用它。
什么是BFC
BFC 全称为块级格式化上下文 (Block Formatting Context) 。BFC是 W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行定位以及与其他元素的关系和相互作用,当涉及到可视化布局的时候,Block Formatting Context提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。一个环境中的元素不会影响到其它环境中的布局。比如浮动元素会形成BFC,浮动元素内部子元素的主要受该浮动元素影响,两个浮动元素之间是互不影响的。这里有点类似一个BFC就是一个独立的行政单位的意思。可以说BFC就是一个作用范围,把它理解成是一个独立的容器,并且这个容器里box的布局与这个容器外的box毫不相干。
触发BFC的条件
BFC的约束规则
BFC可以解决的问题
了解盒模型么
包括内容区域、内边距区域、边框区域和外边距区域。
box-sizing: content-box(W3C盒子模型):元素的宽高大小表现为内容的大小。box-sizing: border-box(IE盒子模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。
IE5.x和IE6在怪异模式中使用非标准的盒子模型,这些浏览器的width属性不是内容的宽度,而是内容、内边距和边框的宽度的总和。
如何实现左侧宽度固定,右侧宽度自适应的布局
小提示:这个问题面试官会要求说出几种解决方法。
DOM结构
<divclass="box"><divclass="box-left"></div><divclass="box-right"></div></div>
利用float + margin实现
.box { height: 200px; } .box > div { height: 100%; } .box-left { width: 200px; float: left; background-color: blue; } .box-right { margin-left: 200px; background-color: red; }
利用calc计算宽度
.box { height: 200px; } .box > div { height: 100%; } .box-left { width: 200px; float: left; background-color: blue; } .box-right { width: calc(100% - 200px); float: right; background-color: red; }
利用float + overflow实现
.box { height: 200px; } .box > div { height: 100%; } .box-left { width: 200px; float: left; background-color: blue; } .box-right { overflow: hidden; background-color: red; }
利用flex实现
这里不是最佳答案,应该是使用flex-basis实现更合理
.box { height: 200px; display: flex; } .box > div { height: 100%; } .box-left { width: 200px; background-color: blue; } .box-right { flex: 1; // 设置flex-grow属性为1,默认为0 overflow: hidden; background-color: red; }
了解跨域吗,一般什么情况下会导致跨域
小提示:如果平常自身有使用场景可结合使用场景进行讲解,比如我在这里使用过的场景是CORS和Nginx反向代理。
跨域行为
JSONP
小提示:如果你提到JSONP,面试官肯定会问你整个详细的实现过程,所以一定要搞懂JSONP的实现原理,如果不是很理解可以自己起一个Express服务实践一下。
Web前端事先定义一个用于获取跨域响应数据的回调函数,并通过没有同源策略限制的script标签发起一个请求(将回调函数的名称放到这个请求的query参数里),然后服务端返回这个回调函数的执行,并将需要响应的数据放到回调函数的参数里,前端的script标签请求到这个执行的回调函数后会立马执行,于是就拿到了执行的响应数据。
缺点:JSONP只能发起GET请求
如何实现一个JSONP
这里给出几个链接:
JSONP安全性问题
CSRF攻击
前端构造一个恶意页面,请求JSONP接口,收集服务端的敏感信息。如果JSONP接口还涉及一些敏感操作或信息(比如登录、删除等操作),那就更不安全了。
解决方法:验证JSONP的调用来源(Referer),服务端判断Referer是否是白名单,或者部署随机Token来防御。
XSS漏洞
不严谨的 content-type导致的 XSS 漏洞,想象一下 JSONP 就是你请求 http://youdomain.com?callback=douniwan, 然后返回 douniwan({ data }),那假如请求 http://youdomain.com?callback=<script>alert(1)</script> 不就返回 <script>alert(1)</script>({ data })了吗,如果没有严格定义好 Content-Type( Content-Type: application/json ),再加上没有过滤 callback 参数,直接当 html 解析了,就是一个赤裸裸的 XSS 了。
解决方法:严格定义 Content-Type: application/json,然后严格过滤 callback 后的参数并且限制长度(进行字符转义,例如<换成<,>换成>)等,这样返回的脚本内容会变成文本格式,脚本将不会执行。
服务器被黑,返回一串恶意执行的代码
可以将执行的代码转发到服务端进行校验JSONP内容校验,再返回校验结果。
CORS(跨域资款共享)
小提示:如果你回答跨域解决方案CORS,那么面试官一定会问你实现CORS的响应头信息Access-Control-Allow-Origin。
什么是CORS
CORS(跨域资源共享 Cross-origin resource sharing)允许浏览器向跨域服务器发出XMLHttpRequest请求,从而克服跨域问题,它需要浏览器和服务器的同时支持。
简单请求
请求方法是以下三种方法之一:
HTTP的请求头信息不超出以下几种字段:
后端的响应头信息:
非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。
Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。
如果浏览器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。
JSONP和CORS的对比
其他跨域解决方案
HTTP2和HTTP1有什么区别
相对于HTTP1.0,HTTP1.1的优化:
相对于HTTP1.1,HTTP2的优化:
你能说说缓存么
小提示:如果平常有遇到过缓存的坑或者很好的利用缓存,可以讲解一下自己的使用场景。如果没有使用注意过缓存问题你也可以尝试讲解一下和我们息息相关的Webpack构建(每一次构建静态资源名称的hash值都会变化),它其实就跟缓存相关。有兴趣的同学可以查看张云龙的博客大公司里怎样开发和部署前端代码?。
缓存分为强缓存和协商缓存。强缓存不过服务器,协商缓存需要过服务器,协商缓存返回的状态码是304。两类缓存机制可以同时存在,强缓存的优先级高于协商缓存。当执行强缓存时,如若缓存命中,则直接使用缓存数据库中的数据,不再进行缓存协商。
强缓存
Expires(HTTP1.0):Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差。另一方面,Expires是HTTP1.0的产物,故现在大多数使用Cache-Control替代。
缺点:使用的是绝对时间,如果服务端和客户端的时间产生偏差,那么会导致命中缓存产生偏差。
Pragma(HTTP1.0):HTTP1.0时的遗留字段,当值为"no-cache"时强制验证缓存,Pragma禁用缓存,如果又给Expires定义一个还未到期的时间,那么Pragma字段的优先级会更高。服务端响应添加'Pragma': 'no-cache',浏览器表现行为和刷新(F5)类似。
Cache-Control(HTTP1.1):有很多属性,不同的属性代表的意义也不同:
请注意no-cache指令很多人误以为是不缓存,这是不准确的,no-cache的意思是可以缓存,但每次用应该去想服务器验证缓存是否可用。no-store才是不缓存内容。当在首部字段Cache-Control 有指定 max-age 指令时,比起首部字段 Expires,会优先处理 max-age 指令。命中强缓存的表现形式:Firefox浏览器表现为一个灰色的200状态码。Chrome浏览器状态码表现为200 (from disk cache)或是200 OK (from memory cache)。
协商缓存
协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。
Last-Modified:服务器在响应请求时,会告诉浏览器资源的最后修改时间。
if-Modified-Since:浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。
if-Unmodified-Since: 从某个时间点算起, 是否文件没有被修改,使用的是相对时间,不需要关心客户端和服务端的时间偏差。
这两个的区别是一个是修改了才下载一个是没修改才下载。如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。为了解决这个问题,HTTP1.1推出了Etag。
Etag:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)
If-Match:条件请求,携带上一次请求中资源的ETag,服务器根据这个字段判断文件是否有新的修改
If-None-Match:再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。
但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了。
缓存场景
对于大部分的场景都可以使用强缓存配合协商缓存解决,但是在一些特殊的地方可能需要选择特殊的缓存策略
能说说首屏加载优化有哪些方案么
小提示:如果做过类似优化的同学,可能就比较好回答,没有做过类似优化的同学可以重点讲解一下懒加载(当然我这里被面试官追问过懒加载的Webpack配置问题)。同时不知道使用Vue技术栈的同学们有没有仔细观察过Vue CLI 3构建的html文件中的link标签的rel属性。
如何在Node端配置路径别名(类似于Webpack中的alias配置)
参考
这种问题还是附上参考链接
谈谈你对作用域链的理解
小提示:同类型的问题还可以是原型链、继承、闭包等,这种概念性的问题你肯定不是一句两句能说清楚的,建议在理解之后自己尝试总结一下,如何把重要的知识点用简短的话语说明白。
了解作用域链之前我们要知道一下几个概念:
函数的生命周期:
创建:JS解析引擎进行预解析,会将函数声明提前,同时将该函数放到全局作用域中或当前函数的上一级函数的局部作用域中。
执行:JS引擎会将当前函数的局部变量和内部函数进行声明提前,然后再执行业务代码,当函数执行完退出时,释放该函数的执行上下文,并注销该函数的局部变量。
变量和函数的声明:如果变量名和函数名声明时相同,函数优先声明。
Activetion Object(AO)、Variable Object(VO):
VO对应的是函数创建阶段,JS解析引擎进行预解析时,所有的变量和函数的声明,统称为Variable Object。该变量与执行上下文相关,知道自己的数据存储在哪里,并且知道如何访问。VO是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:
AO对应的是函数执行阶段,当函数被调用执行时,会建立一个执行上下文,该执行上下文包含了函数所需的所有变量,该变量共同组成了一个新的对象就是Activetion Object。该对象包含了:
作用域链:
当代码在一个环境中创建时,会创建变量对象的一个作用域链(scope chain)来保证对执行环境有权访问的变量和函数。作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)。如果是函数执行阶段,那么将其activation object(AO)作为作用域链第一个对象,第二个对象是上级函数的执行上下文AO,下一个对象依次类推。
在《JavaScript深入之变量对象》中讲到,当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。
你知道null和undefined有什么区别么
闭包有什么作用
Vue响应式原理
小提示:如果面试者使用的是Vue技术栈,那么响应式原理是一个必问的问题,同时面试官经常也会问Vue 3.0在响应式原理上的优化方案。
如果对于响应式原理不是很清楚可以查看我之前写的文章基于Vue实现一个简易MVVM/数据劫持的实现。
了解Event Loop么
小提示:这个题目问到的概率还是蛮大的,这里面试官询问了我浏览器端和Node端的Event Loop有什么不同点。如果想要知道更多浏览器端的Event Loop机制可以查看我之前写的文章你真的理解$nextTick么/JS引擎线程和事件触发线程/事件循环机制。
事件触发线程管理的任务队列是如何产生的呢?事实上这些任务就是从JS引擎线程本身产生的,主线程在运行时会产生执行栈,栈中的代码调用某些异步API时会在任务队列中添加事件,栈中的代码执行完毕后,就会读取任务队列中的事件,去执行事件对应的回调函数,如此循环往复,形成事件循环机制。JS中有两种任务类型:微任务(microtask)和宏任务(macrotask),在ES6中,microtask称为 jobs,macrotask称为 task:
Node.js中Event Loop和浏览器中Event Loop有什么区别
┌───────────────────────┐ ┌─>│ timers │<————— 执行 setTimeout()、setInterval() 的回调 │ └──────────┬────────────┘ | |<-- 执行所有 NextTickQueue 以及 MicroTaskQueue 的回调 │ ┌──────────┴────────────┐ │ │ pendingcallbacks │<————— 执行由上一个 Tick 延迟下来的 I/O 回调(待完善,可忽略) │ └──────────┬────────────┘ | |<-- 执行所有 NextTickQueue 以及 MicroTaskQueue 的回调 │ ┌──────────┴────────────┐ │ │ idle, prepare │<————— 内部调用(可忽略) │ └──────────┬────────────┘ | |<-- 执行所有 NextTickQueue 以及 MicroTaskQueue 的回调 | | ┌───────────────┐ │ ┌──────────┴────────────┐ │ incoming: │ - (执行几乎所有的回调,除了 closecallbacks、timers、setImmediate) │ │ poll │<─────┤ connections, │ │ └──────────┬────────────┘ │ data, etc. │ │ | | | | | └───────────────┘ | |<-- 执行所有 NextTickQueue 以及 MicroTaskQueue 的回调 | ┌──────────┴────────────┐ │ │ check │<————— setImmediate() 的回调将会在这个阶段执行 │ └──────────┬────────────┘ | |<-- 执行所有 NextTickQueue 以及 MicroTaskQueue 的回调 │ ┌──────────┴────────────┐ └──┤ closecallbacks │<————— socket.on('close', ...) └───────────────────────┘
Node.js中宏任务分成了几种类型,并且放在了不同的task queue里。不同的task queue在执行顺序上也有区别,微任务放在了每个task queue的末尾:
如何避免回流和重绘
浏览器渲染过程
浏览器渲染过程如下:
何时触发回流和重绘
何时发生回流:
何时发生重绘(回流一定会触发重绘):
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流。现代浏览器会对频繁的回流或重绘操作进行优化,浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。你访问以下属性或方法时,浏览器会立刻清空队列:
以上属性和方法都需要返回最新的布局信息,因此浏览器不得不清空队列,触发回流重绘来返回正确的值。因此,我们在修改样式的时候,**最好避免使用上面列出的属性,他们都会刷新渲染队列。**如果要使用它们,最好将值缓存起来。
如何避免触发回流和重绘
CSS:
JavaScript:
有赞(二面)
小提示:进入现场面试需要注意好好准备自己的简历,面试官一般会根据项目进行问答。
笔试题环节
一开始面试官就发了两张笔试题试卷,总共四道题目,大致考了以下知识点:
项目问答环节
答完试卷面试官就开始问简历上的一些项目,我记得其中几个问题如下(事实上他问的一些问题和简历不是很相关):
我当场就感受到了面试官问的问题很敷衍,可能他觉得我的简历不够好,又或者觉得我能力不行,接下来面试官又让我做了一道算法题...
算法题环节
当时没做出来,非科班出身可能做这些确实有些困难,也没有系统的学习,面试官看我很困难的样子,就换了一道题。
这道题还是做出来了,毕竟比较简单,然后面试官说今天先到这里,面试结果会在一星期内通知,然后回来的那天晚上就收到了面试没过的通知。
小结
还是蛮感谢这次现场面试的经历,让我知道如果自身不够硬,到哪里都会很被动。面试的好处不仅仅在于检验自己到底有多少能力,更应该发现自身的不足,同时不断的去弥补这些不足。于是我再次捧起之前搁置的《算法导论》,并且创建了一个算法学习演示文档I-Algorithms,希望可以简化《算法导论》的一些理论知识,使大家对于算法的学习可以变得更加系统全面和简单,也希望通过这个学习使得算法面试会变得更加得心应手,希望感兴趣的同学可以star一下。
滴滴(一面)
你知道哪些安全问题,如何避免
小提示:这里我简单讲解了一下Vue中的v-html防范XSS攻击。
XSS(跨站脚本攻击)
XSS,即 Cross Site Script,中译是跨站脚本攻击;其原本缩写是 CSS,但为了和层叠样式表(Cascading Style Sheet)有所区分,因而在安全领域叫做 XSS。
XSS 攻击是指攻击者在网站上注入恶意的客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。
攻击者对客户端网页注入的恶意脚本一般包括 JavaScript,有时也会包含 HTML 和 Flash。有很多种方式进行 XSS 攻击,但它们的共同点为:将一些隐私数据像 cookie、session 发送给攻击者,将受害者重定向到一个由攻击者控制的网站,在受害者的机器上进行一些恶意操作。
XSS攻击可以分为3类:反射型(非持久型)、存储型(持久型)、基于DOM。
反射型
反射型 XSS 只是简单地把用户输入的数据 “反射” 给浏览器,这种攻击方式往往需要攻击者诱使用户点击一个恶意链接(攻击者可以将恶意链接直接发送给受信任用户,发送的方式有很多种,比如 email, 网站的私信、评论等,攻击者可以购买存在漏洞网站的广告,将恶意链接插入在广告的链接中),或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。最简单的示例是访问一个链接,服务端返回一个可执行脚本:
const http = require('http'); functionhandleReequest(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'}); res.write('<script>alert("反射型 XSS 攻击")</script>'); res.end(); } const server = new http.Server(); server.listen(8001, '127.0.0.1'); server.on('request', handleReequest);
存储型
存储型 XSS 会把用户输入的数据 "存储" 在服务器端,当浏览器请求数据时,脚本从服务器上传回并执行。这种 XSS 攻击具有很强的稳定性。比较常见的一个场景是攻击者在社区或论坛上写下一篇包含恶意 JavaScript 代码的文章或评论,文章或评论发表后,所有访问该文章或评论的用户,都会在他们的浏览器中执行这段恶意的 JavaScript 代码:
// 例如在评论中输入以下留言 // 如果请求这段留言的时候服务端不做转义处理,请求之后页面会执行这段恶意代码 <script>alert('xss 攻击')</script>
基于DOM
基于 DOM 的 XSS 攻击是指通过恶意脚本修改页面的 DOM 结构,是纯粹发生在客户端的攻击:
<h2>XSS: </h2> <input type="text" id="input"> <buttonid="btn">Submit</button> <div id="div"></div> <script> const input = document.getElementById('input'); const btn = document.getElementById('btn'); const div = document.getElementById('div'); let val; input.addEventListener('change', (e) => { val = e.target.value; }, false); btn.addEventListener('click', () => { div.innerHTML = `<a href=${val}>testLink</a>` }, false); </script>
点击 Submit 按钮后,会在当前页面插入一个链接,其地址为用户的输入内容。如果用户在输入时构造了如下内容:
onclick=alert(/xss/)
用户提交之后,页面代码就变成了:
<a href onlick="alert(/xss/)">testLink</a>
此时,用户点击生成的链接,就会执行对应的脚本。
XSS攻击防范
HttpOnly 防止劫取 Cookie:HttpOnly 最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的Javascript 访问带有 HttpOnly 属性的Cookie。上文有说到,攻击者可以通过注入恶意脚本获取用户的 Cookie 信息。通常 Cookie 中都包含了用户的登录凭证信息,攻击者在获取到 Cookie 之后,则可以发起 Cookie 劫持攻击。所以,严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 Cookie 劫持攻击。
输入检查:不要相信用户的任何输入。对于用户的任何输入要进行检查、过滤和转义。建立可信任的字符和 HTML 标签白名单,对于不在白名单之列的字符或者标签进行过滤或编码。在 XSS 防御中,输入检查一般是检查用户输入的数据中是否包含 <,> 等特殊字符,如果存在,则对特殊字符进行过滤或编码,这种方式也称为 XSS Filter。而在一些前端框架中,都会有一份 decodingMap, 用于对用户输入所包含的特殊字符或标签进行编码或过滤,如 <,>,script,防止 XSS 攻击:
// vuejs 中的 decodingMap// 在 vuejs 中,如果输入带 script 标签的内容,会直接过滤掉const decodingMap = { '<': '<', '>': '>', '"': '"', '&': '&', ' ': '\n' }
输出检查:用户的输入会存在问题,服务端的输出也会存在问题。一般来说,除富文本的输出外,在变量输出到 HTML 页面时,可以使用编码或转义的方式来防御 XSS 攻击。例如利用 sanitize-html 对输出内容进行有规则的过滤之后再输出到页面中。
CSRF/XSRF(跨站请求伪造)
CSRF,即 Cross Site Request Forgery,中译是跨站请求伪造,是一种劫持受信任用户向服务器发送非预期请求的攻击方式。通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。
Cookie
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。Cookie 主要用于以下三个方面:
而浏览器所持有的 Cookie 分为两种:
res.setHeader('Set-Cookie', ['mycookie=222', 'test=3333; expires=Sat, 21 Jul 2018 00:00:00 GMT;']);
上述代码创建了两个 Cookie:mycookie 和 test,前者属于会话期 Cookie,后者则属于持久性 Cookie。
CSRF攻击
使登录用户访问攻击者的网站,发起一个请求,由于 Cookie 中包含了用户的认证信息,当用户访问攻击者准备的攻击环境时,攻击者就可以对服务器发起 CSRF 攻击。
在这个攻击过程中,攻击者借助受害者的 Cookie 骗取服务器的信任,但并不能拿到 Cookie,也看不到 Cookie 的内容。而对于服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析。(攻击者的网站虽然是跨域的,但是他构造的链接是源网站的,跟源网站是同源的,所以能够携带cookie发起访问)。
但是攻击者无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。例如删除数据、修改数据,新增数据等,无法获取数据。
CSRF攻击防范
验证码:验证码被认为是对抗 CSRF 攻击最简洁而有效的防御方法。从上述示例中可以看出,CSRF 攻击往往是在用户不知情的情况下构造了网络请求。而验证码会强制用户必须与应用进行交互,才能完成最终请求。因为通常情况下,验证码能够很好地遏制 CSRF 攻击。但验证码并不是万能的,因为出于用户考虑,不能给网站所有的操作都加上验证码。因此,验证码只能作为防御 CSRF 的一种辅助手段,而不能作为最主要的解决方案。
Referer Check:根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。通过 Referer Check,可以检查请求是否来自合法的"源"。
添加token验证:要抵御 CSRF,关键在于在请求中放入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
介绍一下Graphql
小提示:这道题是给自己挖了一个坑,抱着学习的心态尝试使用Graphql技术,却没有好好理解是在什么场景下为了解决什么问题才应该使用,也没有好好准备如何描述新技术,往往这种不熟悉的技术自己在简历中应该留存一些心眼,尽量不要提,否则答不上来会很尴尬,让面试官怀疑你的项目成分。
什么是Graphql
GraphQL是一种API查询语言。API接口的返回值可以从静态变为动态,即调用者来声明接口返回什么数据,可以进一步解耦前后端。在Graphal中,预先定义Schema和声明Type来达到动态获取接口数据的目的:
为什么要使用Graphql:
Type(数据模型的抽象)
Type简单可以分为两种,一种叫做Scalar Type(标量类型),另一种叫做Object Type(对象类型):
Scalar Type(标量类型):内建的标量包含,String、Int、Float、Boolean、Enum
Object Type(对象类型):感觉类似于TypeScript的接口类型
Type Modifier(类型修饰符):用于表明是否必填等
Schema(模式)
定义了字段的类型、数据的结构,描述了接口数据请求的规则
Query(查询、操作类型)
查询类型:query(查询)、mutation(更改)和subscription(订阅)
Resolver(解析函数)
提供相关Query所返回数据的逻辑。Query和与之对应的Resolver是同名的,这样在GraphQL才能把它们对应起来。解析的过程可能是递归的,只要遇到非标量类型,会尝试继续解析,如果遇到标量类型,那么解析完成,这个过程叫做解析链。
说说Vue中$nextTick的实现原理
小提示:如果面试者使用的是Vue技术栈,那么$nextTick的原理是一个高频问题,面试者借此可以追问的东西较多,例如浏览器的Event Loop、微任务和宏任务、Node.js的Event Loop、异步更新DOM(响应式的数据for循环改变了1000次为什么视图只更新了一次)、$nextTick历史版本问题等等。
这个如果不是很清楚的具体可查看我之前写的文章你真的理解$nextTick么。
Vue响应式原理
谈谈对闭包的理解
JSONP的实现原理
CSS中的BFC
如何实现居中
水平居中
// flex容器 <div class="box"> // flex项目 <div class="box-center"> </div> </div> .box { width: 200px; height: 200px; display: flex; // 使内部的flex项目水平居中 justify-content: center; background-color: pink; } /* .box-center { width: 50%; background-color: greenyellow; } */
.box { width: 200px; height: 200px; position: relative; background-color: pink; } .box-center { position: absolute; left:50%; // width: 50%; height: 100%; // 通过 translate() 方法,元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数: // translate(x,y) 定义 2D 转换。 // translateX(x) 定义转换,只是用 X 轴的值。 // translateY(y) 定义转换,只是用 Y 轴的值。 // left: 50% 先整体向父容器的左侧偏移50%,此时是不能居中的,因为元素本身有大小 // 接着使用transform使用百分比向左偏移本身的宽度的一半实现水平居中(这里的百分比以元素本身的宽高为基准) transform:translate(-50%,0); background-color: greenyellow; }
.box { width: 200px; height: 200px; position: relative; background-color: pink; } .box-center { position: absolute; left:50%; height: 100%; // 类似于transform// width: 50%;// margin-left: -25%; width: 100px; margin-left: -50px; background-color: greenyellow; }
垂直居中
.box { height: 100px; } .box::after, .box-center{ display:inline-block; vertical-align:middle; } .box::after{ content:''; height:100%; }
居中元素高度不定
.box { height: 100px; display: table; } .box-center{ display: table-cell; vertical-align:middle; }
.box { height: 100px; display: flex; align-items: center; }
优点:内容块的宽高任意, 优雅的溢出. 可用于更复杂高级的布局技术中. 缺点:IE8/IE9不支持、需要浏览器厂商前缀、渲染上可能会有一些问题。
.box { height: 100px; position: relative; background-color: pink; } .box-center { position: absolute; top: 50%; transform: translate(0, -50%); background-color: greenyellow; }
缺点:IE8不支持, 属性需要追加浏览器厂商前缀,可能干扰其他 transform 效果,某些情形下会出现文本或元素边界渲染模糊的现象。
居中元素高度固定
.box { position:relative; height: 100px; background-color: pink; } .box-center{ position:absolute; top:50%; // 注意不能使用百分比// margin的百分比计算是相对于父容器的width来计算的,甚至包括margin-top和margin-bottom height: 50px; margin-top: -25px; }
.box { position:relative; width: 200px; height: 200px; background-color: pink; } .box-center{ position:absolute; top: 0; bottom: 0; margin: auto 0; height: 100px; background-color: greenyellow; }
水平垂直居中
.box { display: flex; width: 100px; height: 100px; background-color: pink; } .box-center{ margin: auto; background-color: greenyellow; } ```css - Flex布局 ```css .box { display: flex; width: 100px; height: 100px; background-color: pink; justify-content: center; align-items: center; } .box-center{ background-color: greenyellow; }
.box { position: relative; height: 100px; width: 100px; background-color: pink; } .box-center{ position: absolute; left: 0; right: 0; bottom: 0; top: 0; margin: auto; width: 50px; height: 50px; background-color: greenyellow; }
用过Flex么,能简单介绍一下么
小提示:如果在项目中使用过,可简单介绍一下自己使用Flex解决过什么问题,这里我在项目中印象比较深刻的是使用Flex解决上面内容高度不固定,下面内容高度自动撑满父容器剩余高度的问题。
如果不是很清楚Flex,可以查看阮一峰的文章Flex 布局教程:语法篇。面试官追问,那么除了Flex,你还知道Grid么?这个由于兼容性问题,我一直没有好好研究过,这里可查看阮一峰的文章CSS Grid网格布局教程。
bind的源码实现
小提示:这里我回答使用函数柯里化加上apply或者call可实现bind,面试官追问了一些具体的实现细节。
后来我自己粗糙的实现了一下,仅供参考:
Function.prototype.myCall = function (obj) { obj.fn = thislet args = [...arguments].splice(1) let result = obj.fn(...args) delete obj.fn return result } Function.prototype.myApply = function (obj) { obj.fn = thislet args = arguments[1] let result if (args) { result = obj.fn(...args) } else { result = obj.fn() } delete obj.fn return result } Function.prototype.myBind = function (obj) { let context = obj || windowlet _this = thislet _args = [...arguments].splice(1) returnfunction () { let args = arguments// 产生副作用// return obj.fn(..._args, ...args)return _this.apply(context, [..._args, ...args]) } } functionmyFun (argumentA, argumentB) { console.log(this.value) console.log(argumentA) console.log(argumentB) returnthis.value } let obj = { value: 'ziyi2' } console.log(myFun.myCall(obj, 11, 22)) console.log(myFun.myApply(obj, [11, 22])) console.log(myFun.myBind(obj, 33)(11, 22))
伪类和伪元素的区别
小提示:这个问题我当时懵了一下,一下子没反应过来面试官想要问什么,就答了这两者在CSS优先级上有区别,然后由于遇到不会的问题有些紧张就多说了一些废话,但显然这不是面试官想要的答案并且消耗了面试官面试的耐心,说他问的不是这个。这里再次提示大家,如果你感觉你说不清楚,但是你又知道一点,我建议你说不知道,不要纠结,面试官不会因为你不知道一个问题就PASS你,相反你说了一些无关紧要的废话,反而在消耗面试官的耐性,增加负面印象。
伪类和伪元素是用来修饰不在文档树中的部分,比如,一句话中的第一个字母,或者是列表中的第一个元素。下面分别对伪类和伪元素进行解释:
伪类用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的。比如说,当用户悬停在指定的元素时,我们可以通过:hover来描述这个元素的状态。虽然它和普通的css类相似,可以为已有的元素添加样式,但是它只有处于dom树无法描述的状态下才能为元素添加样式,所以将其称为伪类。
伪元素用于创建一些不在文档树中的元素,并为其添加样式。比如说,我们可以通过:before来在一个元素前增加一些文本,并为这些文本添加样式。虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。
区别
伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树外的元素。因此,伪类与伪元素的区别在于:有没有创建一个文档树之外的元素。
CSS3规范中的要求使用双冒号(::)表示伪元素,以此来区分伪元素和伪类,比如::before和::after等伪元素使用双冒号(::),:hover和:active等伪类使用单冒号(:)。除了一些低于IE8版本的浏览器外,大部分浏览器都支持伪元素的双冒号(::)表示方法。
小结
对于滴滴的这次面试,我感觉到自己准备的不是很充分,尤其是自己简历上的项目技术Graphql。同时对于自己不会的题目强行做了一些解释说明,其实应该简洁明了的告诉面试官不会。
51信用卡(一面)
说说DOM事件流
在ES5中如何实现继承
小提示:这里我说了很多,从借用构造函数到组合继承到寄生组合继承,但面试官其实最想听到的是寄生组合继承。面试官还追问我具体要如何实现寄生组合继承。当然这里其实问的问题还可以很多,比如ES6的类继承和ES5中的继承有什么区别。
如果对于继承以及继承的区别不是很清楚的,可以随便看看我之前写的大笔记js类和继承。
绝对定位
小提示:这个建议大家好好回忆一下,例如子元素是相对父元素的padding、border还是content进行定位之类的,当时面试官问的就这么细。
消抖和节流
小提示:面试官只是问了一下具体的使用场景,没有问实现原理。
简单消抖
functiondebounce (fn, wait = 1000) { let timeOutId returnfunction () { let context = thisif (timeOutId) { clearTimeout(timeOutId) } timeOutId = setTimeout(() => { fn.apply(context, arguments) }, wait) } }
带立即执行参数的消抖
functiondebounceImmediate (fn, wait = 1000, immediate) { let timeOutId, context, args const later = (immediate) => setTimeout(() => { if (!immediate) { fn.apply(context, args) timeOutId = context = args = null } }, wait) returnfunction () { if (!timeOutId) { timeOutId = later(true) if (immediate) { fn.apply(this, arguments) } context = this args = arguments } else { clearTimeout(timeOutId) timeOutId = later(false) } } }
节流
functionthrottle (fn, wait) { let timeoutId = nullreturnfunction () { let context = thisif (!timeoutId) { timeoutId = setTimeout(() => { fn.apply(context, arguments) timeoutId = null }, wait) } } }
Vue中的computed实现原理
小提示:这个问题面试官问的很细,绝对是想问你是否阅读过源码。他首先问computed的实现原理,其次问了这样一个问题:现在有两个computed计算值,其中一个computed计算值为什么可以依赖另外一个computed计算值。这里顺便将watch的实现原理也贴上。
watch的实现原理
watch的分类:
watch实现过程:
computed运行原理
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { returnthis.firstName + ' ' + this.lastName } } })
由于 this.firstName 和 this.lastName (上面是Vue官方示例)都是响应式变量,因此会触发它们的 getter,根据我们之前的分析,它们会把自身持有的 dep 添加到当前正在计算的 watcher 中,这个时候Dep.target就是这个 computed watcher,具体步骤如下:
通过以上的分析,我们知道计算属性本质上就是一个 computed watcher,也了解了它的创建过程和被访问触发 getter 以及依赖更新的过程,其实这是最新的计算属性的实现,之所以这么设计是因为 Vue 想确保不仅仅是计算属性依赖的值发生变化,而是当计算属性最终计算的值发生变化才会触发渲染 watcher 重新渲染,本质上是一种优化。
computed计算值为什么还可以依赖另外一个computed计算值
小提示:这个问题当时完全不知道,哎,官方源码的套路太深了......
这里希望有大神可以补充说明一下。
周期函数有哪些(beforeCreated和created中间都做了什么
)
初始化 data、props、computed、watcher、provide。官方源码具体位置src/core/instance/init.js:
callHook(vm, 'beforeCreate') initInjections(vm) // resolve injections before data/props initState(vm) initProvide(vm) // resolve provide after data/props callHook(vm, 'created')
小结
51信用卡的这次面试其实面试官考察的点还是蛮深入的,问了一些Vue底层源码的实现,总体感觉自己回答的还可以,但是面试官说:你应该去阿里...
阿里部门未知(一面)
说说Webpack的实现原理
小提示:这个直接回答不知道,问题较大,我这里猜测一下是类似Babel和AST抽象语法树相关,有空去看下源码。
这个问题希望同学可以补充一下。
首屏优化有哪些解决方案
小提示:这个问题在回答懒加载的过程中,面试官追问懒加载的Webpack配置,我说了和代码切割相关。
关于懒加载,这里推荐一篇非常好的文章:Webpack 大法之 Code Splitting。
Node.js的加载机制(require和module.exports)
小提示:这个问题其实是非常常见的问题,建议大家阅读一下源码,有些也可能会问一下比较简单的问题,例如module.exports和exports的区别,或者也可能问CommonJS引入和ES6引入的区别。
你觉得你最擅长什么
小提示:这个问题是个大坑阿,我这里直接回答我什么都不擅长,这样回答显然面试官是不会不满意的,建议大家在面试前好好想想自己到底擅长啥。
React和Vue的区别
小提示:这里React真的好久没用了,几乎忘记了,大致说了下单向数据流、双向数据绑定、数据监听方式、JSX以及Vue的单文件组件、函数式编程、Vue的指令之类的。
这个问题希望同时熟悉React和Vue的同学可以补充一下。
React、Vue和JQuery在什么场景下怎么选型
这个问题希望同学可以补充一下。
Vue的响应式原理
什么情况下会阻塞DOM渲染
小提示:面试官这里应该想问DOM渲染的过程中可能有哪些情况会阻塞渲染。我当时回答不知道。
这个问题希望同学可以补充一下。
有哪些异步函数
小提示:回答了宏任务和微任务。
讲讲MVVM,说说与MVC有什么区别
小提示:这个问题我专门发了一篇掘金文章,但是很多人好像都不是很感兴趣的样子,但是面试官真的就问了这样一个问题。
这里推荐我之前写的掘金文章基于Vue实现一个简易MVVM/MV*设计模式的演变历史,一开始重点讲解了MVC、MVP以及MVVM的演变过程和区别。
阿里CBU技术部(一面)
说说z-index有什么需要注意的地方
小提示:真的忘记的差不多了,就简单说了只能在同一层叠上下文中进行z-index值比较、和绝对定位的关系,z-index值不需要设置过大,只需要理清楚层级关系即可。面试官追问了z-index值和background的覆盖关系,还追问了绝对定位元素以及后来居上的准则。面试官还问了z-index默认值是什么,0和auto有没有区别?真的对于CSS可能平常就用的不多,所以这个问题答的不是很好。
可能面试官最想知道的是下面这张图:
这里附上张鑫旭的文章深入理解CSS中的层叠上下文和层叠顺序。
这里由于回答了定位,面试官追问固定定位的元素是相对于什么进行定位?相对定位会脱离正常文档流么?绝对定位是相对于什么元素进行定位?
熟悉CSS3动画么
小提示:CSS3动画硬件加速?CSS3动画的性能问题(重绘和重流,是否需要脱离正常文档流)?这个我当时答不知道,确实平常用的很少,如果熟悉Vue过渡动画的同学可以讲讲过渡动画?
有没有做过什么可视化的项目
小提示:我的回答:地图算么?基于OpenLayers设计过地图的Vue组件库。
对于可视化希望同学可以补充一下。
你觉得你最擅长的是什么
小提示:这个问题简直就是给人挖坑。
Flex实现两列布局
这里简单实现一下(其实应该使用flex-basis属性):
<divclass="box"><divclass="box-left"></div><divclass="box-right"></div></div> .box { height: 200px; display: flex; } .box > div { height: 100%; } .box-left { width: 200px; background-color: blue; } .box-right { flex: 1; // 设置flex-grow属性为1,默认为0 overflow: hidden; background-color: red; }
ES6/ES7/ES8的特性
说说DOM事件流
小提示:面试官追问事件委托有什么优点(起码两个以上)、target/currentTarget/relateTarget具体指向什么目标。
你觉得你有做过推动流程或者改善流程的事件么,举例说明
小提示:这个如果做过什么规范或者开发工具之类的,应该比较好回答。
小结
总体来说这次面试面得很细,有些知识点已经忘记,建议大家面试前把一些感觉不是很熟悉的原生知识点回忆起来,尤其是在开发中都不怎么会使用一些CSS样式设计的童鞋(现在很多都是组件库的设计方案,样式早已经封装掉了)。
阿里企业智能事业部(一面)
Event Loop
Webpack的loader和plugins的区别
小提示:当时直接回答不知道,确实Webpack我只会用,还没了解过内部的实现原理和构成。这个后续无论如何都要好好理解一下原理。
这个问题希望同学可以补充一下。
HTTP状态码206是干什么的
小提示:工作中没有遇到过需要上传下载大型文件,所以这个问题当时老老实实回答不知道。具体应该和断点续传相关,可能也需要回答一些range的头部信息等。
React高阶组件的作用有哪些
小提示:好久没用过React了,大致只知道Racct是单向数据流的,利用高阶组件可以实现类似于Vue的双向数据绑定。
这个问题希望同学可以补充一下。
React和Vue的区别
Service Worker有哪些作用
小提示:当时怕说错,老老实实回答不知道。后来查了一下应该和缓存以及HTTP请求拦截相关。
这个问题希望同学可以补充一下。
跨域
文件上传的二进制具体是怎么处理的
小提示:只知道上传的头信息是application/x-www-form-urlencoded,也可以对上传的文件的数据进行拦截处理,例如对上传文件的信息进行加密处理。
这个问题希望同学可以补充一下。
Vue响应式原理
首屏加载性能优化
小结
其实这一次面试自己感觉面试的不是很好(尽管面试官问的确实比我上面列出的问题多),因为有好几个问题自己确实不清楚。这里再次建议大家不知道就是回答不知道,这样不会对面试官造成一些负面印象。这一次面试能够通过运气占了很大一部分。
阿里企业智能事业部(二面)
computed的实现原理
Vue的整个实现原理
小提示:当时面试官问的蛮好玩的,他问从开始写一个.vue文件开始到DOM渲染到页面上,Vue做了哪些工作。然后我当时没理解面试官是要问vue-loader?DOM树的渲染过程?来来回回试探性的问了面试官几次,才理解原来面试官想知道Vue源码的整个实现过程。
大家如果想了解Vue源码实现的整个粗略过程,可以看下之前写的文章基于Vue实现一个简易MVVM/Vue的运行机制简述。
通讯
小提示:由于这边涉及到一些海康的设备(上下位机通信),面试官问我如何知道上位机软件给下位机设备发送了5次信息。这个其实大部分Web前端开发在工作上很难遇到类似的问题,辛亏我以前毕业设计中做过上下位机的TCP通讯。后来我从Leader面那里了解到二面面试官应该是做iot物联网开发这一块的。
请求帧数据结构如下:
Chrome插件如何屏蔽广告
小提示:这个问题当时回答不知道,其实后面想想最简单的办法是先找出广告元素的一些通用特性,然后在Chrome插件中通过注入脚本的形式将这些广告元素隐藏掉。
这里不知道有没有更好的其他方式,例如不知道Service Work对请求拦截处理是否可以有效屏蔽广告等,这个问题希望同学可以补充一下。
如何判断两个变量相等
小提示:这里需要分基本类型和引用类型,面试官在这里具体想问的是Object.is的实现原理。这是面试官问我的第一个问题,当时直接回答不知道,内心都觉得接下来要凉凉了。
Watch的运行原理
Vue的数据为什么频繁变化但只会更新一次
小提示:这里问的是Vue源码对于视图更新的优化。我这里的回答是乱糟糟的,希望有同学能够给出一个精准并且简短的回答。
Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
另外,关于waiting变量,这是很重要的一个标志位,它保证flushSchedulerQueue回调($nextTick中执行)允许被置入callbacks一次。
因为Vue的事件机制是通过事件队列来调度执行,会等主进程执行空闲后进行调度,所以先会去等待所有的同步代码执行完成之后再去一次更新。这样的性能优势很明显,比如:
现在有这样的一种情况,mounted的时候test的值会被循环执行++1000次。每次++时,都会根据响应式触发setter->Dep->Watcher->update->run。如果这时候没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。所以Vue实现了一个queue队列,在下一个tick(或者是当前tick的微任务阶段)统一执行queue中Watcher的run。同时,拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对的DOM的0变成1000。保证更新视图操作DOM的动作是在当前栈执行完以后下一个tick(或者是当前tick的微任务阶段)的时候调用,大大优化了性能。
执行顺序update -> queueWatcher -> 维护观察者队列(重复id的Watcher处理) -> waiting标志位处理(保证需要更新DOM或者Watcher视图更新的方法flushSchedulerQueue只会被推入异步执行的$nextTick回调数组一次) -> 处理$nextTick(在为微任务或者宏任务中异步更新DOM)->
由于VUE的数据驱动视图更新是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。在同一事件循环中的数据变化后,DOM完成更新,立即执行nextTick(callback)内的回调。
vue和react一样,对dom的修改都是异步的。它会在队列里记录你对dom的操作并进行diff操作,后一个操作会覆盖前一个,然后更新dom。
Event Loop
除了Flex还可以用什么进行布局
小提示:我猜这里面试官想问的是Grid,当时说不知道。
绝对定位、固定定位和z-index
小提示:感谢CBU技术部的面试官。
绝对定位
属性介绍
浮动、绝对定位和固定定位会脱离文档流,相对定位不会脱离文档流,绝对定位相对于该元素最近的已定位的祖先元素,如果没有一个祖先元素设置定位,那么参照物是body层。
绝对定位相对于包含块的起始位置:
问答题:
小结
这一次面试官问我的第一个问题Object.is就没答上来,不过面试官显然没有因为开头答的不好就否定面试者。大家如果在面试时第一个问题就答不上来,不要慌,要保持良好的心态,把接下来能答的问题好好答上来。可能很多同学会疑问,好像还有好几个问题感觉没答上来,但是可能只要有一个问题答的非常出彩,仍然可以弥补那些没答上来的问题(这里面试官当时说Vue源码的实现过程我说的比较清楚,还没有一个面试者答的比我更清楚的)。
阿里企业智能事业部(Leader面)
三面是Leader现场面,我当时特别担心有赞二面的情况发生,冷不丁又给你来一道算法题,这些真是我最不擅长的点。因为有点心虚我就问了下在阿里的师兄(师兄可能也做招聘工作,当时还怪我没有找他内推...),他说现场面其实最主要的是好好准备简历上的内容,面试官一般都会根据简历进行问答,还说他当时面试阿里时会让他画一些框架层次图(这个我当时没在意,结果面试官确实让我根据其中某个项目画一个框架层次图)。Leader面的时候在场的有两个面试官和一个HR。
Leader(一)面试
先是进来一个气场很足的Leader,看起来很权威,但是问问题还蛮随意的,就简单的让我介绍一下自己做的项目,然后翻看了我做的一些东西。感觉他好像有点心不在焉,翻看的很随意,我在回答问题的时候用余光关注了一下大佬的表情,感觉他在我项目经历那一块停留了非常长的时间。
Leader(二)面试
我正回答着自己的项目经历,Leader二和HR进来了,等我回答完Leader一就让Leader二开始面我。Leader二就问了我其中的两个项目。问我的第一个项目是自己做的公司内部的工具,他问这个平台有什么可以衡量的数据表明公司内部人员的使用情况。我回答当时因为领导觉得没必要做,就没有做数据统计这一块,告诉了他数据库里的一些真实数据情况。然后他问PV、UV应该怎么统计(我当时还厚脸皮的问他PV和UV是什么)?如果访问的页面出不来PV怎么统计?页面有没有做什么行为监测?页面访问量过大怎么处理?我大致讲了一些我的思路。
接着问我第二个项目(Low Code相关),我就回答了这个项目的技术体系,从以前做了什么到现在做到什么程度,到未来需要做成什么样,统统仔细的说了一遍。Leader二就问我未来做成什么样能不能思考一下怎么做,给了我5分钟的时间(这期间他一直反复的在翻阅我的简历)。然后我就假装思考了5分钟左右,其实脑子里一片空白,当时对于未来要做成什么样还只是个构思。然后Leader二还是很体贴的,他说你可以在墙上画一画(墙上可以写字),我就大致画了画,Leader二问我能不能画一画这个项目的框架层次图,我就简单的画了画...最后Leader二直接说你们做的太Low了,这个(Low Code)在我们这里已经是两年前的技术了...(这个我还是要解释下,我所在的部门从开始用Vue到目前只有短短的两年时间,在这两年时间里技术体系还是飞速的在沉淀和发展,我离开之前已经构思并实现了部分Vue技术栈的Low Code解决方案,如果这方面感兴趣的同学也可以找我沟通)。
Leader二还蛮好玩的,他说Low Code如果真的做出来了,都没前端什么事情了,那你干嘛去?顺着这个问题他还问我未来的前端应该怎么发展?未来前端有哪些可以挖掘的点?我回答了一些Graphql、可视化等,我还说了一个特别搞笑的回答,我说从以往的发展来看,前端应该抢占后端的资源,把后端限制我们的事情让前端也能做,让前端更加解放。Leader二当场就进行了反驳,说是要有价值才做,而不是为了能做而做,吓得我不轻...然后Leader二还详细的跟我解释了未来发展这个问题他希望得到什么回答,当时还是觉得Leader二蛮亲切的。
HR面试
Leader二问完以后HR就接着问我了以下几个问题:
然后Leader一顺着HR问了一个小问题:
最后问我还有什么想问的,我当时已经被三个人问的有点迷迷糊糊了,然后想了想说没有。
小结
这次现场面其实我感觉自己面得不是很好,总感觉自己要挂了。总共面了将近1个半小时左右,尤其是Leader二的问题很多不是他想要的答案,但是最终居然过了。智能事业部(HR面)
企业智能事业部Leader面后又收到了HR面的面试通知,这一轮面试大致问了以下问题:
小提示:这里HR会问的其实不止这些问题,例如你为什么喜欢Web前端这个岗位、你未来的职业规划、你觉得你的优点和缺点有哪些、为什么选择阿里巴巴、对之前几个面试官做下评价、你用过阿里的哪些产品顺便谈谈这些产品的优缺点、你对于互联网是怎么理解的...
小结
对于HR面还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等),你觉得你做的最有成就感的一件事(你要是说个简单的,HR会觉得你工作能力不强),你一般解决问题的方法有哪些(HR当然也想考察你解决问题的能力,你要是说什么百度啊之类的HR当然会觉得你解决问题的能力不强),你期望的薪资待遇是多少(你要是不喜欢这家公司,可以期望高一些,你要是很喜欢这家公司面试过程很愉快上浮个30%左右,面试过程一般上浮个20%左右)。
在学习新技术时,会先在网上找相关领域大牛的技术博客去看,了解整个技术的大概脉络。
以下只是我在学习算法时的一些资料整理,(后续)算法结合实际工作中的应用
1.http://blog.csdn.net/v_july_v?viewmode=contents(博客专注面试、算法、机器学习)
2.oRbIt 的专栏(CSDN著名算法博主)
3.http://www.raychase.net/2763(四火、amazon程序员、LeetCode算法题目解答汇总)
1.Welcome to Hangzhou Dianzi University Online Judge HDU - 杭电
2.http://poj.org/(北大)
3.https://vjudge.net/;jsessionid=B324C4F2C1E429645E825D3A85A10D09(华中科技大学)
4.http://ac.jobdu.com/problemset.php(九度)
1.https://leetcode.com/
2.http://www.acmerblog.com/Acm之家,专业的ACM学习网站
3.http://www.wutianqi.com/sfzt.htmlTanky Woo算法专题
1.http://open.163.com/special/opencourse/algorithms.html麻省理工学院公开课:算法导论
2.http://www.wutianqi.com/?p=2403《算法导论》学习总结
学习算法怎么能不了解数据结构呢,以下是我看到过的最浅显易懂的教程
算法 - 标签 - Vamei
1.算法(第4版)
2.啊哈!算法
3.《算法导论》
•《算法》图示清晰易懂:随便翻开这本书的一页,你会看到什么?图,图,还是图。这本书是从实用角度出发来看待算法的、不会像《算法导论》全书都是证明。亚马逊五星级好书,值得推荐。
•《啊哈!算法》没有枯燥的描述,没有难懂的公式,一切以实际应用为出发点,通过幽默的语言配以可爱的插图来讲解算法。
•《算法导论》算法的权威著作、工具书
以上提到的都是学习算法的工具、把它们利用好,就会少走很多弯路、相当于站在了巨人的肩膀上。但是只是把这些网站收藏起来、书籍买下来,然后压箱底,这我可就白说那么多了
更多文章请看个人博客:www.51heichan.com
*请认真填写需求信息,我们会在24小时内与您取得联系。