大疆是我校招面的第一家公司,从六月份投简历,然后笔试面试到拿到录用意向书,前后用了近四个月,来之不易啊。
因为时间太久,就直接放在一起了。一面是电话面,两个面试官轮流问;二面是视频面,两个技术面试官,一个hr;终面是去的现场面。
1. meta标签
meta标签:提供给页面的一些元信息(名称/值对), 比如针对搜索引擎和更新频度的描述和关键词。
name
:名称/值对中的名称。常用的有author、description、keywords、generator、revised、others。 把 content 属性关联到一个名称。http-equiv
:没有name时,会采用这个属性的值。常用的有content-type、expires、refresh、set-cookie。把content属性关联到http头部。content
: 名称/值对中的值, 可以是任何有效的字符串。 始终要和 name 属性或 http-equiv 属性一起使用。scheme
: 用于指定要用来翻译属性值的方案。2. css哪些属性可以继承
3. css3有哪些新属性
(1)边框:
border-radius
:圆角边框,border-radius:25px;box-shadow
:边框阴影,box-shadow: 10px 10px 5px #888888;border-image
:边框图片,border-image:url(border.png) 30 30 round;(2)背景:
background-size
:规定背景图片的尺寸,background-size:63px 100px;
background-origin
:规定背景图片的定位区域,背景图片可以放置于 content-box、padding-box 或 border-box 区域。background-origin:content-box;
CSS3 允许您为元素使用多个背景图像。background-image:url(bg_flower.gif),url(bg_flower_2.gif);
(3)文本效果:
text-shadow
:向文本应用阴影,可以规定水平阴影、垂直阴影、模糊距离,以及阴影的颜色。text-shadow: 5px 5px 5px #FF0000;
word-wrap
:允许文本进行换行。word-wrap:break-word;
(4)字体:CSS3 @font-face 规则可以自定义字体。
(5)2D 转换(transform
)
translate()
:元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数。 transform: translate(50px,100px);rotate()
:元素顺时针旋转给定的角度。允许负值,元素将逆时针旋转。transform: rotate(30deg);scale()
:元素的尺寸会增加或减少,根据给定的宽度(X 轴)和高度(Y 轴)参数。transform: scale(2,4);skew()
:元素翻转给定的角度,根据给定的水平线(X 轴)和垂直线(Y 轴)参数。transform: skew(30deg,20deg);matrix()
: 把所有 2D 转换方法组合在一起,需要六个参数,包含数学函数,允许您:旋转、缩放、移动以及倾斜元素。transform:matrix(0.866,0.5,-0.5,0.866,0,0);(6)3D 转换
rotateX()
:元素围绕其 X 轴以给定的度数进行旋转。transform: rotateX(120deg);rotateY()
:元素围绕其 Y 轴以给定的度数进行旋转。transform: rotateY(130deg);(7)transition:过渡效果,使页面变化更平滑
transition-property
:执行动画对应的属性,例如 color,background 等,可以使用 all 来指定所有的属性。transition-duration
:过渡动画的一个持续时间。transition-timing-function
:在延续时间段,动画变化的速率,常见的有:ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier 。transition-delay
:延迟多久后开始动画。简写为:transition: [<transition-property> || <transition-duration> || <transition-timing-function> || <transition-delay>];
(8)animation:动画
使用CSS3 @keyframes 规则。
animation-name
: 定义动画名称animation-duration
: 指定元素播放动画所持续的时间长animation-timing-function:ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)
: 指元素根据时间的推进来改变属性值的变换速率,说得简单点就是动画的播放方式。animation-delay
: 指定元素动画开始时间animation-iteration-count:infinite | <number>
:指定元素播放动画的循环次animation-direction: normal | alternate
: 指定元素动画播放的方向,其只有两个值,默认值为normal,如果设置为normal时,动画的每次循环都是向前播放;另一个值是alternate,他的作用是,动画播放在第偶数次向前播放,第奇数次向反方向播放。animation-play-state:running | paused
:控制元素动画的播放状态。简写为: animation:[<animation-name> || <animation-duration> || <animation-timing-function> || <animation-delay> || <animation-iteration-count> || <animation-direction>]
这里只列出了一部分,详情可以去看w3school的CSS3 教程。
4. 闭包是什么,什么时候闭包会消除?
因为作用域链,外部不能访问内部的变量和方法,这时我们就需要通过闭包,返回内部的方法和变量给外部,从而就形成了一个闭包。
JavaScript是一门具有自动垃圾回收机制的编程语言,主要有两种方式:
标记清除
(最常用)垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(可以使用任何标记方式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
引用计数
引用计数(reference counting)的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。
导致问题:会导致循环引用的变量和函数无法回收。
解决:将用完的函数或者变量置为null。
5. 怎么理解js是单线程的
主要说一下异步以及事件循环机制,还有事件队列中的宏任务、微任务。
macrotask
:主代码块,setTimeout,setInterval、setImmediate等。microtask
:process.nextTick(相当于node.js版的setTimeout),Promise 。process.nextTick的优先级高于Promise。更详细可以看这篇博客:这一次,彻底弄懂 JavaScript 执行机制,讲的非常清晰。
6. 有哪些排序算法,时间复杂度是多少?什么时候快排的效率最低?
排序算法 | 最坏事件复杂度 | 平均时间复杂度 | 稳定度 | 空间复杂度
—|— | —|— | —|—
冒泡排序 | O(n^2) | O(n^2) | 稳定 | O(1)
插入排序 | O(n^2) | O(n^2) | 稳定 | O(1)
选择排序 | O(n^2) | O(n^2) | 稳定 | O(1)
快速排序 | O(n^2) | O(nlog2n) | 不稳定 | O(log2n)~O(n)
二叉树排序 | O(n^2) | O(nlog2n) | 不一定 | O(n)
堆排序 | O(nlog2n) | O(nlog2n) | 不稳定 | O(1)
整个序列已经有序或完全倒序时,快排的效率最低。
7. 原生ajax的请求过程
创建全平台兼容的XMLHttpRequest对象:
1 | function getXHR(){ |
Ajax请求数据的过程:
1 | var xhr = getXHR(); |
8. http状态码,cookie字段,cookie一般存的是什么,session怎么存在的?
这部分可以参考我的博客:HTTP协议知识点总结
9. http请求方式有哪些?
10. 怎么用原生js实现一个轮播图,以及滚动滑动
之前我使用轮播图都是用的antd的组件,所以我大致说了一下思路,用定时器去实现,以及如何实现平滑的滚动效果。详情请看: 原生js实现轮播图
11. 用过哪些开源的组件
说了antd和element-ui。
12. 怎么实现上传下载的功能
主要说了下form表单和input标签。
13. react生命周期,以及diff算法,diff算法是对树的深度优先遍历还是广度优先遍历?
是深度优先遍历。 diff的实现
14. 强缓存和协商缓存
参考:HTTP协议知识点总结
15. react-router的原理
react-router就是控制不同的url渲染不同的组件。react-router在history库的基础上,实现了URL与UI的同步。
原理:DOM渲染完成之后,给window添加onhashchange事件监听页面hash的变化,并且在state属性中添加了route属性,代表当前页面的路由。
具体步骤:
16. 怎么用无人机捕获天空上的鸟
这个题目我也不造啊,毕竟我没用过无人机,有知道的大神可以在评论中回答一下~
终面是去的现场,在深圳总部那边,基本就是闲聊了二十来分钟吧,面完还有hr小姐姐给我们介绍和参观了无人机,酷炫~
阿里是提前批,找人内推了菜鸟网络,面了六轮,面的我怀疑人生了,中途四面本来已经挂了,后面三面面试官又捞起来给我加面了一轮,不过最后还是挂在了hr。
1. css选择器,怎么选择相同的类
id、class、标签、伪类、通配符等。可以用getElementsByClassName()选择相同的类。
2. css3有哪些伪类,伪类选择器有哪些
这里要区分一下伪类和伪元素的概念。根本区别在于它们是否创造了新的元素(抽象)。
:link
, :visited
, :hover
, :active
; 以及 :first-child
, :last-child
。:before
,:after
, :first-letter
, :first-line
。css3只新增了一个伪元素 ::selection
(改变用户所选取部分的样式)。参考: CSS3 选择器——伪类选择器
3. OSI七层网络模型
OSI七层模型 | 作用 | 对应协议 | 对应设备 |
---|---|---|---|
应用层 | 它是计算机用户,以及各种应用程序和网络之间的接口 | HTTP, FTP, SMTP, POP3 | 计算机设备 |
表示层 | 信息的语法语义以及它们的关系,如加密解密、转换翻译、压缩解压缩 | IPX, LPP, XDP | |
会话层 | 建立、维护、管理应用程序之间的会话 | SSL, TLS, DAP, LDAP | |
传输层 | 服务点编址,分段与重组、连接控制、流量控制、差错控制 | TCP, UDP | 防火墙 |
网络层 | 为网络设备提供逻辑地址,进行路由选择、分组转发 | IP ARP RARP ICMP IGMP | 路由器 |
数据链路层 | 物理寻址,同时将原始比特流转变为逻辑传输路线 | PPTP, ARP, RARP | 交换机 |
物理层 | 机械、电子、定时接口通道信道上的原始比特流传输 | IEEE 802.2, Ethernet v.2, Internetwork | 网卡 |
参考: 一张非常强大的OSI七层模型图解
4. MVC和MVVM的区别
MVC
将响应机制封装在controller对象中,当用户和你的应用产生交互时,控制器中的事件触发器就开始工作了。
MVVM
把View和Model的同步逻辑自动化了。以前Controller负责的View和Model同步不再手动地进行操作,而是交给框架所提供的数据绑定功能进行负责,只需要告诉它View显示的数据对应的是Model哪一部分即可。也就是双向数据绑定,就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。
5. 用过哪些设计模式
(1)单例模式
定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
实现方法:先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
适用场景:一个单一对象。比如:弹窗,无论点击多少次,弹窗只应该被创建一次。
(2)发布/订阅模式
定义:又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
场景:订阅感兴趣的专栏和公众号。
(3)策略模式
定义:将一个个算法(解决方案)封装在一个个策略类中。
优点:
应用场景:根据不同的员工绩效计算不同的奖金;表单验证中的多种校验规则。
(4)代理模式
定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。
应用场景:图片懒加载(先通过一张loading图占位,然后通过异步的方式加载图片,等图片加载好了再把完成的图片加载到img标签里面。)
(5)中介者模式
定义:通过一个中介者对象,其他所有相关对象都通过该中介者对象来通信,而不是互相引用,当其中的一个对象发生改变时,只要通知中介者对象就可以。可以解除对象与对象之间的紧耦合关系。
应用场景: 例如购物车需求,存在商品选择表单、颜色选择表单、购买数量表单等等,都会触发change事件,那么可以通过中介者来转发处理这些事件,实现各个事件间的解耦,仅仅维护中介者对象即可。
(6)装饰者模式
定义:在不改变对象自身的基础上,在程序运行期间给对象动态的添加方法。
应用场景: 有方法维持不变,在原有方法上再挂载其他方法来满足现有需求;函数的解耦,将函数拆分成多个可复用的函数,再将拆分出来的函数挂载到某个函数上,实现相同的效果但增强了复用性。
参考: JavaScript设计模式
6. Http状态码
7. https怎么加密
参考: HTTP协议知识点总结
8. es6相比es5有哪些优点
大概说一下:let、const,模板字符串,箭头函数,做异步处理的promise、generator、async await,es6模块等。
参考: 阮一峰 —— ECMAScript 6 入门
9. ajax请求过程
不多说,上面有。
10. 有哪些性能优化
参考:
11. 懒加载怎么实现
场景:一个页面中很多图片,但是首屏只出现几张,这时如果一次性把图片都加载出来会影响性能。这时可以使用懒加载,页面滚动到可视区在加载。优化首屏加载。
实现:img标签src属性为空,给一个data-xx属性,里面存放图片真实地址,当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-xx的值赋给src。
优点:页面加载速度快,减轻服务器压力、节约流量,用户体验好。
12. 项目中写过什么组件,组件有哪些功能
主要介绍了下实习项目写过的组件,说了下如何实现的。
1. react框架有哪些设计的好的地方
主要介绍了以下几个部分:
2. react是怎么工作的,怎么提高性能
主要还是说了下react的生命周期,还有shouldComponentUpdate这个函数,以及diff算法。
3. redux有哪些需要改进,你觉得你用的不怎么舒服的地方?
我当时说的是redux的subscribe方法有点麻烦,每次更新数据都要手动的subscribe一下,所以觉得react-redux的api封装的更好,用起来比较简单。
参考:
4. 怎么设计一个类似于antd 的 react 组件库
这个问题把我给问懵了额,我是按照软件工程的生命周期流程来答的。
5. 你做的最自豪的一个项目
这个略过…言之有理即可
6. mysql 的左关联和右关联
左关联:保留左表中所有的元组,右表中没有的属性填充NULL。
右关联:保留右表中所有的元组,左表中没有的属性填充NULL。
7. 有没有折腾过后端
直接说了没有,之前学了点PHP,不过都快忘得差不多了额。
8. 学习方法和未来的学习路线
言之有理即可。
9. 浏览器页面渲染机制
参考: 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
10. XSS和CSRF防范措施
(1)XSS:跨站脚本攻击
攻击方式:在URL或者页面输入框中插入JavaScript代码。
防范:
(2)CSRF:跨站点伪造请求
攻击方式:攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。主要是拿到了用户的登录态。
防范:
这一面基本问的是个人知识沉淀了,如实回答就可以了。
这一面是在杭州菜鸟现场面的,尴尬的是通知我的小姐姐一直强调是hr面,我天真的以为是hr面了,然鹅问了很多技术,当时候想的是阿里的hr都这么厉害了,都能直接问技术了。临走之前,特意问了面试官是hr面么,他说是技术,然后我……大概就知道自己凉了。
1. mysql的索引用的什么,介绍一下b树,b+树,红黑树这些
mysql的索引用的是B+树。
参考: 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
2. Mysql的基本写法
参考: 一千行 MySQL 学习笔记
3. 估算下杭州上空现在有多少架飞机
这个题目,也真的是为难我了额。在网上搜到了个答案,可以参考下:高盛的面试题
4. 两组数据,都存储五亿条url,内存有4G,如何找出相同的两条url
参考: 面试- 阿里-. 大数据题目- 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
5. 如何找到一个字符串中最长的两个字符串
解法:后缀数组。首先生成字符串的所有后缀数组,在进行排序,找出相邻两个最长的公共子串(从第一位开始相同的)
例如:abcdeabc
生成后缀数组:【abcdeabc,bcdeabc,cdeabc,deabc,eabc,abc,bc,c】
再排序:【abcdeabc,abc,bcdeabc,bc,cdeabc,c,deabc,eabc】
找出相邻的最长公共子串:【abc,bc,c】
因此,最长的串是abc。
6. 在白板上画出这个项目的整个架构
画了下项目的功能架构什么的。
7. XSS, CSRF,token 怎么来的,sql 注入知道么
sql注入:
攻击方式:服务器上的数据库运行非法的 SQL 语句,主要通过拼接字符串的形式来完成,改变sql语句本身的语义。通过sql语句实现无账号登陆,甚至篡改数据库。
防御:
8. 怎么设计一个ant的组件
9. 你觉得你实习做的项目有什么改进的地方
10. 你做过印象最深刻的项目
11. 算法了解过吗
就知道一些基本的排序额…
12. Setstate 会发生什么
setState会引发一次组件的更新过程,从而引发页面的重新绘制。主要会涉及以下几个生命周期函数:
13. 平时处理过什么兼容性
参考: web前端兼容性问题总结
14. 了解分布式和负载均衡么
然鹅我并不了解呃。
第四面确实是挂了,没面hr就让我走了,后面过了两天之后,三面面试官又把我捞起来了,说我计算机基础还有数据库基础不怎么好,然后说问我几个简单的,之后给了我机会面了hr,感谢三面面试官让我体验了阿里的整个面试流程,很满足了。
1. 进程和线程的区别
2. 冒泡排序和快速排序的区别
简述了下冒泡和快排的思想,以及冒泡和快排的时间复杂度。
3. OSI七层模型以及作用
上面有写噢,不知道的往上翻。
4. 你有哪些优势,或者打动他的
呃,最怕这种自夸的问题额,然后就是夸了一顿,手动捂脸。
5. 面向对象和非面向对象有什么区别
面向对象三大特性:封装,继承,多态。
面向对象的好处:
6. 设计模式有哪些,说下装饰者模式和代理模式
前面有总结,往前翻。
7. 重载和重写有什么区别
方法重写(overriding):
方法重载(overloading):
重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数。
参考: 方法重载和重写的区别
二面三面都有手写代码的环节,对于我这种动手能力弱的人来说还是挺吃力。当时提前批投递的是深圳百度,总共只招五个前端,没过也很正常。后面正式批笔试过了,但是要去北京面试,也就直接放弃了。
1. 为什么要用flex布局,align-items和justify-content的区别
传统布局基于盒模型,非常依赖 display属性 、position属性 、float属性。而flex布局更灵活,可以简便、完整、响应式地实现各种页面布局,比如水平垂直居中。
align-items:定义在侧轴(纵轴)方向上的对齐方式;
justify-content:定义在主轴(横轴)方向上的对齐方式。
2. webpack是怎么打包的,babel又是什么?
把项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
babel将es6、es7、es8等语法转换成浏览器可识别的es5或es3语法。
3. saas和less不同于普通css的地方
4. es 6模块和其他模块不同的地方
对比了一下es6模块和CommonJS模块:
区别 | CommonJS | es6 |
---|---|---|
加载原理 | 第一次加载模块就会执行整个模块,再次用到时,不会执行该模块,而是到缓存中取值。 | 不会缓存运行结果,动态的去被加载的模块中取值,并且变量总是绑定其所在模块。 |
输出 | 值的拷贝(模块中值的改变不会影响已经加载的值) | 值的引用(静态分析,动态引用,原来模块值改变会改变加载的值) |
加载方式 | 运行时加载(加载整个模块,即模块中的所有接口) | 编译时加载(只加载需要的接口) |
this指向 | 指向当前模块 | 指向undefined |
循环加载 | 只输出已经执行的部分,还未执行的部分不会输出 | 遇到模块加载命令import时不会去执行模块,而是生成一个动态的只读引用,等到真正用到时再去模块中取值。只要引用存在,代码就能执行。 |
5. 有没有用过es6的一些异步处理函数
Promise,generator,async await
6. redux怎么处理异步操作
可以引入Redux-thunk或者redux-promise这种中间件,可以延迟事件的派发。
其中的原理:是因为他们用了applymiddleware()包装了store的dispatch方法,拥有可以处理异步的能力。
7. 为什么reducer要是个纯函数,纯函数是什么?
纯函数:对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环境的状态。
原因:Redux只通过比较新旧两个对象的存储位置来比较新旧两个对象是否相同(浅比较)。如果你在reducer内部直接修改旧的state对象的属性值,那么新的state和旧的state将都指向同一个对象。因此Redux认为没有任何改变,返回的state将为旧的state。两个state相同的话,页面就不会重新渲染了。
因为比较两个Javascript对象所有的属性是否相同的的唯一方法是对它们进行深比较。但是深比较在真实的应用当中代价昂贵,因为通常js的对象都很大,同时需要比较的次数很多。因此一个有效的解决方法是作出一个规定:无论何时发生变化时,开发者都要创建一个新的对象,然后将新对象传递出去。同时,当没有任何变化发生时,开发者发送回旧的对象。也就是说,新的对象代表新的state。
8. 高阶函数是什么,怎么去写一个高阶函数
高阶函数:参数值为函数或者返回值为函数。例如map,reduce,filter,sort方法就是高阶函数。
编写高阶函数,就是让函数的参数能够接收别的函数。
9. vue跟react的区别是什么
没有用过vue,所以就只说了vue具有双向绑定,react是单向数据流。
10. nodejs处理了什么问题
可以处理高并发的I/O,也能与websocket配合,开发长连接的实时交互应用程序。
11. 响应式布局,怎么做移动端适配
使用媒体查询可以实现响应式布局。
移动端适配方案:
(1)meta viewport:让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放。
1 | <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
width=device-width
: 让当前viewport宽度等于设备的宽度user-scalable=no
: 禁止用户缩放initial-scale=1.0
: 设置页面的初始缩放值为不缩放maximum-scale=1.0
: 允许用户的最大缩放值为1.0minimum-scale=1.0
: 允许用户的最小缩放值为1.0
(2)媒体查询(响应式)
(3)动态 rem 方案
参考: 移动端是怎么做适配的?
1. 怎么做一个实时的聊天系统
使用WebSocket和nodejs,《nodejs实战》这本书详细介绍了这个项目。
2. 当消息有延迟的时候,怎么保证消息的正确顺序
每个消息在被创建时,都将被赋予一个全局唯一的、单调递增的、连续的序列号(SerialNumber,SN)。可以通过一个全局计数器来实现这一点。通过比较两个消息的SN,确定其先后顺序。
3. 怎么做一个登陆窗口,input有哪些兼容性
使用form表单。
4. input按钮如何校验
使用正则表达式。
5. 如何实现水平垂直居中,relative、absolute、fixed
我说了三种方式:
(1)使用表格
1 | .container{ |
(2)css3的transform属性
1 | .container{ |
(3)flex布局
1 | .container{ |
6. 写一个函数,1s之后依次输出1,2,3,4,5
直接使用了let和定时器。
1 | for(let i = 1 ; i < 6; i++){ |
7. 事件队列(宏任务、微任务)
8. 如何每隔三个数加一个逗号,还要考虑小数点的情况
这道题就是大疆的笔试题,当时候笔试题也是瞎写的,后面也没仔细看,没想到又成了一道面试题。
1 | function transform(number){ |
9. webpack有配置过吗?原理知道吗
参考前面。
10. 父子组件如何通信,子组件怎么跟父组件通信?
父组件把state作为props传递给子组件进行通信。
父组件写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子组件,子组件调用父组件的函数,同时引起state变化。
11. 简单说一下pwa
面试的这个部门就是做pwa的,所以说了下自己对pwa的理解。
1. 手写indexOf
1 | function indexOf(str, val){ |
2. 实现 JS 的继承
1 | function A () { |
参考: JS实现继承的几种方式
3. 从url输入到页面显示会有哪些步骤
(1)DNS服务器解析域名,找到对应服务器的IP地址;
(2)和服务器建立TCP三次握手连接;
(3)发送HTTP请求,服务器会根据HTTP请求到数据服务器取出相应的资源,并返回给浏览器;
(4)浏览器处理响应
4. method有哪些方法,分别是什么意思?post和put的区别
post:上传资源
put:修改资源
5. https有几次握手
6. http2比http1好的地方
主要是考察http2的几个特性。
参考:HTTP协议知识点总结
7. 页面刷新不出来,是有哪些问题
可以从第三题的每个步骤进行分析,大概是:
8. 上一次系统性的学习是什么时候,怎么学习的
学习react的时候,看文档、博客,照着网上写了点小项目。
9. 你觉得项目中最自豪的是什么
10. 上家公司有哪些不好的地方
网易是在杭州网易大厦面的,一天面完三轮,然后录用排序,择优录取的吧。我投的是网易考拉,哭唧唧,后面被拒了之后还伤心的卸载了考拉。之后正式批投了杭研,过了笔试,要去武汉面,本来海康也是在武汉面的,考虑到还要住一晚上,有点怕怕,就没去了。
1.css3动画
2. flex布局
3. 实现call
1 | Function.prototype.call2 = function (context) { |
4. 图片懒加载data-src
5. Promise异步
6. 水平垂直居中
7. 数组有哪些方法,哪些会改变原数组
改变原数组的方法:pop、push、reverse、shift、sort、splice、unshift,以及两个ES6新增的方法copyWithin 和 fill;
不改变原数组(复制):concat、join、slice、toString、toLocaleString、indexOf、lastIndexOf、未标准的toSource以及ES7新增的方法includes;
循环遍历:forEach、every、some、filter、map、reduce、reduceRight 以及ES6新增的方法entries、find、findIndex、keys、values。
8. 操作dom有哪些方法
创建:
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
添加:appendChild()
移出:removeChild()
替换:replaceChild()
插入:insertBefore()
复制:cloneNode(true)
查找:
getElementsByTagName() //通过标签名称
getElementsByClassName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
9. 左边定宽右边自适应
(1)左盒子左浮动,右盒子width=100%
(2)左盒子左浮动,右盒子margin-left=左盒子宽度
(3)左盒子左浮动,右盒子右浮动,设置calc(100vw-盒子宽度)
(4)父容器设置display=flex,右盒子flex:1
10. 事件代理
利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行。打个比方:一个button对象,本来自己需要监控自身的点击事件,但是自己不来监控这个点击事件,让自己的父节点来监控自己的点击事件。
11. 后端了解么
直接说了不了解,笑哭。
1. 节流和防抖,手写一下代码
(1)防抖:
定义: 合并事件且不会去触发事件,当一定时间内没有触发这个事件时,才真正去触发事件。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
场景: keydown事件上验证用户名,输入法的联想。
实现:
1 | function debounce(fn, delay) { |
(2)节流:
定义: 持续触发事件时,合并一定时间内的事件,在间隔一定时间之后再真正触发事件。每间隔一段时间触发一次。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
场景: resize改变布局时,onscroll滚动加载下面的图片时。
实现:
当触发事件的时候,我们取出当前的时间戳,然后减去之前的时间戳(最一开始值设为0),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于,就不执行。
缺陷:第一次事件会立即执行,停止触发后没办法再激活事件。
1 | function throttle(fn, interval) { |
当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行,直到定时器执行,然后执行函数,清空定时器,这样就可以设置下个定时器。
缺陷:第一次事件会在n秒后执行,停止触发后依然会再执行一次事件。
1 | function throttle(fn, interval) { |
鼠标移入能立刻执行,停止触发的时候还能再执行一次。
1 | var throttle = function(func,delay){ |
2. 知道哪些性能优化
3. react为什么比其他要快,虚拟dom知道吗
4. 写过什么组件
5. 平时怎么学习的
6. node,webpack了解么
7. 模块化,commonjs,es6模块
8. redux怎么实现的
搜狗是内推的,面试也很迷,第一面到第二面中间隔了二十几天,然后二面完了也毫无反馈。
1. 说一下项目,整个网络过程,从前端到后台
2. Ajax 底层实现,readystate 有哪些
0-(未初始化)还没有调用send()方法
1-(载入)已调用send()方法,正在发送请求
2-(载入完成)send()方法执行完成,已经接收到全部响应内容
3-(交互)正在解析响应内容
4-(完成)响应内容解析完成,可以在客户端调用了
3. 状态码有哪些,100,307
4. OSI七层模型
5. TCP三次握手
6. SSL握手过程
7. jQuery 有哪些方法
8. display 有哪些属性,说一下flex的属性
9. Es6的async awiat ,generator
10. Map有哪些方法
Map的方法:set, get, has, delete, clear
遍历方法:
keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。
参考: Set 和 Map 数据结构
11. 正则用过吗?exec, 匹配一个手机号
12. css3动画了解吗,怎么写一个loading动画
13. 怎么实现跨域,cors涉及哪些请求字段
14. 编程: 判断两个网络地址是否属于同一个子网掩码
用与运算符就可以了。当时是在牛客网的面试系统上写的,一直AC不出,也是很迷了额。
15. 怎么上传文件
1. 怎么计算在一个页面上的停留时间
方案1:websocket,前端开个长连接,后台统计长连接时间。
方案2:ajax轮询,隔几秒发一个查询,后台记录第一与最后一个查询间隔时间。
方案3: 关闭窗口或者跳转的时候会触发window.onbeforeunload函数,可以在该函数中做处理(有兼容性问题);统计完数据记录到本地cookies中,一段时间后统一发送。
2. 给你一亿个数,是连续的,怎么找出两个不存在的数
用bitmap就能搞定了,存在为1,不存在为0。
3. 一个搜索框的输入联想,会遇到什么问题?如果第一个请求延迟,第二个请求先到,请问怎么处理?
键盘输入太快,每次输入都去联想,需要多次发送请求,会导致用户体验太差,可以使用防抖优化。
在前端做判断,判断此时的值是否与返回的值相同,不同就丢弃,相同就显示在页面。
4. Http的缓存
5. 二维码怎么工作的,扫描pc端的二维码,怎么让pc端登录?
6. Promise 做什么的,有哪几种状态
异步处理的,有三个状态:resolve,pending,reject。
7. 项目有哪些难点,怎么处理的
8. 遇到过哪些性能优化
当时听说电信对学历要求很高,本科基本都是211起的,想着自己本科太渣,就直接放弃了网上的笔试。之后电信来了学校宣讲会,跟朋友吃完饭看到了,就去说凑凑热闹,刚好有笔试也就做了。做完之后笔试居然考了最高分,比第二名高出二十分,手动捂脸额。一面完分数也挺高的,有95分,运气爆棚。重点是今年电信开的薪资实在太高了,目前还在纠结选哪个。
1. Xhtml和html的区别
2. 遇到过哪些兼容性问题
3. 浏览器内核有哪些,移动端用的是哪个
对于Android手机而言,使用率最高的就是Webkit内核。
4. 怎么实现标签页的通信
5. Cookie、session,localstorage,sessionstorage
6. React 和jquery 之间的区别,哪个好用
7. 怎么实现继承
8. Es6,es7有哪些特性
9. 怎么跨域
10. Commonjs用的js哪个特性?
因为js之前只能在浏览器运行,为了能让js能在服务器上运行,所以设计了commonjs规范,而且js之前没有模块化的概念。
11. 选择器优先级
12. 伪类知道吗,有哪些
13. 块级元素有哪些,怎么转成行内元素
14. 一个完整的http请求,页面渲染过程,js和css文件怎么渲染
一面问的都很常规的,不知道为啥给了这么高的分。二面的时候三个面试官,总共就问了三个问题,然后就说面试结束了,不超过五分钟。
1. TCP怎么工作的
三次握手
2. OSI七层模型,路由器工作在哪一层?
网络层
3. 平时用什么语言,用过哪些框架
深信服给的薪资居然比电信还低,而且加班还严重,就直接拒了。
1. 跨域,同源策略,webpack里面有个跨域的方式知道么
2. 怎么把es6转成es5,babel怎么工作的
3. 反向代理知道么,Nginx
4. 继承有哪些方式
5. 怎么实现一个sleep ,手写一个promise
6. 能写一个二叉树么,怎么去遍历
7. 深拷贝怎么写
(1)var new_arr = JSON.parse( JSON.stringify(arr) );
(2)for in 加递归
1 | function isObj(obj) { |
(3)$.extend()
(4)函数库lodash,提供_.cloneDeep()
8. 在公司除了完成上级交待的任务,还做了什么
9. 怎么实现垂直中间布局
10. Call和apply,哪个性能开销大
在思否上提问了,已有大神回答。
11. 正则写一个手机号,全局匹配是什么
12. 删除一个数组中的某个数
splice方法
13. 模块化介绍一下,什么是编译时优化
14. 有哪些网络安全名词,怎么防范
15. 平时怎么学习
二面小哥哥问了几个问题之后,就一直跟我介绍深信服内部的一些管理、技术氛围、晋升机制什么的,全程都是笑脸额。
1. git push -u 是什么意思
绑定默认提交的远程版本库,加了参数-u后,以后即可直接用git push 代替git push origin master
2. git rebase解释下
有test和dev两个分支,分别有两个commit,此时执行下列命令:
1 | git checkout test |
以dev为基准将test的提交进行回放,挨个的应用到dev上去,然后test的那些提交就会废弃。 等价于git merge dev。
git merge 和git rebase区别:
3. linux命令,怎么打开一个文件
cat abc.txt
4. 你的上级给你review 代码时会提什么建议
5. 怎么看待加班和工作效率
6. get和post分别进行几次数据交互
get请求过程:(2次交互)
post请求过程:(3次交互)
7. 怎么打断点,如何确定一个结果来自于哪个函数
TW是内推的,做了内推作业后,就面了技术和文化面。技术面是在作业的基础上加两个功能,只写出来一个,后面一个没时间写了,然后就只讲了下思路。
文化面面了快一个小时,听说TW不加班,对女程序员还很友好,挺中意的公司,不过最后还是挂了额。
华为的面试就不多说了,基本不问前端的,进去是随机分岗的。华为的面试阵仗是我见过的最大的,听说要招一万人,在万达那里面的,全是人啊,阔怕。现在正泡在offer池里,估计国庆后发正式offer吧。
小米是内推的,电话面了一面,国庆后要我去武汉现场面,那会学校刚好有事应该也不会去了。
1. redux主要做什么的,用过redux的一些中间件吗,简单说一下
2. react生命周期说一下,diff算法说一下
3. setstate时会合并修改,是在哪个函数里修改的?宏事件和微事件
setstate是异步更新的,通过一个队列机制实现state的更新,当执行setState时,会将需要更新的state合并后放入状态队列,而不会立即更新,队列可以高效的批量更新state。
4. let、const、var的区别;如果const定义的是个对象,能够修改对象的属性吗?
const实际上保证的并不是变量的值不得改动,而是变量指向的那个指针不得改动,可以给对象添加属性。如果真的想将对象冻结,应该使用Object.freeze方法。
5. Object.freeze和Object.seal的区别
Object.preventExtension
:禁止对象添加新属性并保留已有属性;
Object.seal
:在一个现有对象上调用 Object.preventExtensions(..) 并把所有现有属性标记为 configurable:false;
Object.freeze
:在一个现有对象上调用 Object.seal(..) 并把所有“数据访问”属性标记为 writable:false。
6. 说一下防抖,应用场景是什么
7. 快速排序算法说下,基点怎么选?如果一个数组是已经排序好的怎么选基点?
8. 算法的稳定性,冒泡、快排
9. lodash,underscore的库了解么?有哪些方法
10. 整个项目的架构,包括前端、后台、运营
11. sort的底层实现机制,看过源码么?
数组长度<=22时采用插入排序,大于22用快排。
12. 怎么调试bug?打过断点么?如果前端代码被压缩,如何去找到相应元素?
chromre控制台下,在 Scripts 面板下面有个 Pretty print 按钮(这种符号 {}),点击会将压缩 js 文件格式化缩进规整的文件,这时候在设定断点可读性就大大提高了。
感谢这一年的学习。另外,公司已签,感谢各位的关注。
这些都是我的学习笔记,也可以参考:
2019届校招陆陆续续开始了,整理了一些高频的面试题。
1. 什么是<!DOCTYPE>?
DOCTYPE是html5标准网页声明,且必须声明在HTML文档的第一行。来告知浏览器的解析器用什么文档标准解析这个文档。
文档解析类型有:
BackCompat
:怪异模式,浏览器使用自己的怪异模式解析渲染页面。(如果没有声明DOCTYPE,默认就是这个模式)CSS1Compat
:标准模式,浏览器使用W3C的标准解析渲染页面。2. meta标签
提供给页面的一些元信息(名称/值对),有助于SEO。
属性值:
name
:名称/值对中的名称。author、description、keywords、generator、revised、others。 把 content 属性关联到一个名称。
http-equiv
:没有name时,会采用这个属性的值。content-type、expires、refresh、set-cookie。把content属性关联到http头部
content
: 名称/值对中的值, 可以是任何有效的字符串。 始终要和 name 属性或 http-equiv 属性一起使用
scheme
: 用于指定要用来翻译属性值的方案
3. HTML语义化
4. 常见的浏览器内核
5. 简单介绍对浏览器内核的理解
主要分成两部分:渲染引擎和JS引擎。
最开始渲染引擎和JS引擎并没有区分得很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
6. HTML5有哪些新特性,移除了哪些元素?如何处理HTML5新标签的浏览器兼容问题?
(1) 用于绘画的canvas元素;
(2) 用于媒介回放的video和audio元素;
(3) 对本地离线存储有更好的支持,localStorage长期存储数据,浏览器关闭后数据不丢失;sessionStorage的数据在浏览器关闭后自动删除;
(4) 语意化更好的内容元素,比如header,nav,section,article,footer;
(5) 新的表单控件:calendar,date,time,email,url,search;
(6) 新的技术webworker,websockt、Geolocation;
(1) 纯表现的元素:basefont,big,center,font,s,strike,tt,u;
(2) 对可用性产生负面影响的元素:frame,frameset,noframes;
IE8/IE7/IE6支持document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。
7. html5哪些标签可以做SEO优化?
title、meta、header、footer、nav、article、aside
8. src和href的区别
src是指向外部资源的位置,指向的内容会嵌入到文档中当前标签所在的位置,在请求src资源时会将其指向的资源下载并应用到文档内,如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,知道将该资源加载、编译、执行完毕,所以一般js脚本会放在底部而不是头部。
href是指网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
9. 渐进增强和优雅降级
渐进增强
:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能,达到更好的用户体验。优雅降级
:一开始就构建完整的功能,然后再针对低版本的浏览器进行兼容。10. defer和async的区别
defer
要等到整个页面在内存中正常渲染结束(DOM结构完全生成,以及其他脚本执行完成),才会执行。多个defer脚本会按照它们在页面出现的顺序加载。==“渲染完再执行”==async
一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。多个async脚本是不能保证加载顺序的。==“下载完就执行”==11. 如何实现浏览器内多个标签页之间的通信?
方法一:调用localstorge
标签页1:
1 | <input id="name"> |
标签页2:
1 | $(function(){ |
方法二:使用cookie+setInterval
将要传递的信息存储在cookie中,每隔一定时间读取cookie信息,即可随时获取要传递的信息。
标签页1:
1 | $(function(){ |
标签页2:
1 | $(function(){ |
1. css盒模型
应用场景:
(1)表单:
表单中有一些input元素其实还是展现的是传统IE盒模型,带有一些默认的样式,而且在不同平台或者浏览器下的表现不一,造成了表单展现的差异。此时我们可以通过box-sizing属性来构建一个风格统一的表单元素。
(2)设置子类元素的margin或者border时,可能会撑破父层元素的尺寸,这时我就需要使用box-sizing: border-box来将border包含进元素的尺寸中,这样就不会存在撑破父层元素的情况了。
2. 行内元素和块级元素的区别?行内块级元素的兼容性使用?(IE8以下)
块级元素
:div,p,h1,form,ul,li(1)各占一行,垂直方向排列;
(2)可以包含其他块级或者行内元素;
(3)高度、行高以及外边距和内边距都可控制;
(4)默认宽度是它本身父容器的100%(和父元素的宽度一致),与内容无关。
行内元素
:span,a,label,input,img,strong,em(1)水平方向排列,不会自动换行;
(2)不可以包含块级元素,但是可以包含其他行内元素或者文本;
(3)行内元素设置width、height无效(可以设置line-height),margin和padding上下无效;
(4)宽度就是它的文字和图片的宽度,不可改变。
1 | div { |
haslayout 是IE7-浏览器的特有属性。hasLayout是一种只读属性,有两种状态:true或false。当其为true时,代表该元素有自己的布局,否则代表该元素的布局继承于父元素。
注意: 通过element.currentStyle.hasLayout可以得出当前元素的hasLayout情况。
3. 页面导入样式时,使用link和@import有什么区别?
(1)link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
(2)link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
(3)link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器(IE5以下)不支持。
(4)link支持使用Javascript控制DOM去改变样式;而@import不支持。
4. 清除浮动有哪些方式?
(1)在浮动元素下方添加一个非浮动元素
1 | <div> |
父容器现在必须考虑非浮动子元素的位置,而后者肯定出现在浮动元素下方,所以显示出来,父容器就把所有子元素都包括进去了。这种方法比较简单,但是要在页面中增加冗余标签,违背了语义网的原则。
(2)将父容器也改成浮动定位
1 | <div style="float:left;"> |
这种方法不用修改HTML代码,但是缺点在于父容器变成浮动以后,会影响到后面元素的定位,而且有时候,父容器是定位死的,无法变成浮动。
(3)父容器设置overflow: hidden或者auto。(开启BFC)
1 | <div style="overflow: hidden;"> |
缺点
:一个是IE6不支持,另一个是一旦子元素的大小超过父容器的大小,就会出显示问题。
(4)利用:after伪选择符,在父容器的尾部自动创建一个子元素 ==(推荐这种)==
1 | .clearfix:after { |
5. 简单介绍BFC和IFC
BFC —— 块级格式化上下文
(1)BFC触发条件:
(2)BFC特性
(3)应用
(4)BFC与hasLayout
IE6-7不支持BFC,而是使用私有属性hasLayout,要用zoom:1触发hasLayout属性。Zoom用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸。
IFC —— 行内格式化上下文
(1)创建方式:
和BFC相比,它的创建方式是被动的、隐式的,是由所包含的子元素来创建:只有在一个区域内仅包含可水平排列的元素时才会生成,这些子元素可以是文本、inline-level元素或inline-block-level元素。
(2)特性:
6. 选择器优先级
!important>行内样式>id选择器>类选择器>标签选择器>通配符>继承
权重算法
:(0,0,0,0) ——> 第一个0对应的是important的个数,第二个0对应的是id选择器的个数,第三个0对应的类选择器的个数,第四个0对应的是标签选择器的个数,合起来就是当前选择器的权重。
比较
:先从第一个0开始比较,如果第一个0大,那么说明这个选择器的权重高,如果第一个相同,比较第二个,依次类推。
7. 怎么实现水平垂直居中
(1)行内元素的水平居中
1 | text-align: center; |
(2)块级元素水平居中
1 | margin: 0 auto; |
(3)已知高度宽度元素的水平垂直居中
利用绝对定位和负边距实现
1 | .container{ |
利用绝对定位和margin
1 | .container{ |
(4)未知高度和宽度元素的水平垂直居中
被居中的元素是inline或者inline-block元素
1 | .container{ |
css3的transform属性
1 | .container{ |
flex布局
1 | .container{ |
最简单的写法:
1 | .container{ |
8. 实现左边定宽,右边自适应布局
(1)左盒子左浮动,右盒子width=100%
(2)左盒子左浮动,右盒子margin-left=左盒子宽度
(3)左盒子左浮动,右盒子右浮动,设置width: calc(100% - 左盒子宽度)
(4)父容器设置display:flex,右盒子flex:1
9. 实现中间自适应宽度,左右两栏固定宽度布局
10. 脱离文档流
(1) 浮动脱离文档流:使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。
(2) 绝对定位脱离文档流:使用absolute: position | fixed 脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。
11. CSS3新特性
12. display:none;与visibility:hidden的区别是什么?
(1) display:none;
HTML元素(对象)的宽高,高度等各种属性值都将“丢失”,视为不存在,而且不加载。
(2) visibility:hidden;
HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在,也即是说它仍然具有高度,宽度等属性值。
13. 响应式布局原理
媒体查询,查询到当前屏幕(媒介媒体)的宽度,针对不同的屏幕宽度设置不同的样式来适应不同屏幕。
14. flex布局
flex布局可以看阮一峰老师的这两篇文章: Flex 布局教程:语法篇 , Flex 布局教程:实例篇 ,讲的非常详细。
(1)设置在容器上的属性
flex-direction:row | row-reverse | column | column-reverse
项目的排列方向flex-wrap:nowrap | wrap | wrap-reverse
是否换行flex-flow:<flex-direction> || <flex-wrap>
flex-direction和 flex-wrap的简写justify-content:flex-start | flex-end | center | space-between | space-around
在水平方向上的对齐方式align-items: flex-start | flex-end | center | baseline | stretch
定义在垂直方向上的对齐方式align-content: flex-start | flex-end | center | space-between | space-around | stretch
定义了多根轴线的对齐方式,如果项目只有一根轴线,那么该属性将不起作用(item有多行时)(2)设置在项目上的属性
order:<number>
定义项目在容器中的排列顺序,数值越小,排列越靠前,默认值为 0flex-basis:<length> | auto
定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间flex-grow: <number>
定义项目的放大比例。默认值为 0,即如果存在剩余空间,也不放大flex-shrink: <number>
定义项目的缩小比例。默认值: 1,即如果空间不足,该项目将缩小,负值对该属性无效。flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
flex-grow, flex-shrink 和 flex-basis的简写 默认值:0 1 auto, 即不放大,可缩小,大小就是项目本身的大小。align-self:auto | flex-start | flex-end | center | baseline | stretch
允许单个项目有与其他项目不一样的对齐方式之后仍会继续更新…
关于HTTP方面的相关知识,可以看我总结的这篇文章: HTTP协议知识点总结
JavaScript相关的基础知识可以看这两篇思维导图: 你不知道的JavaScript(上卷) , 你不知道的JavaScript(中卷)第一部分
中卷第二部分和下卷还在整理中。
首先,我们先定义HTML结构:
1 | <div class='container'> |
再来开始我们的布局,首先给这三个div都给一个float: left,让它们均左浮动。
1 | .middle, .left, .right{ |
接下来是最重要的两个步骤,设置左盒子的margin-left: -100%,把左盒子拉上来,调整左盒子的浮动位置到中间盒子的左侧。
再设置右盒子的margin-left: -右盒子宽度px,把右盒子拉上来,调整右盒子的浮动位置到中间盒子的右侧。
1 | .left{ |
【*】此时的布局基本出来了,但是中间盒子的左右两侧会被左右两个盒子覆盖掉,此时我们要通过相对定位来避免覆盖。给左右盒子position: relative,再分别设置它们的left和right,并且控制父元素的padding来为左右两边留白。
1 | .left{ |
ok!大功告成,圣杯布局已经完成啦~
双飞翼的布局基本和圣杯布局类似,它的HTML结构为:
1 | <div class='container'> |
前面的布局和圣杯完全一致,只是从【*】开始的这一步略微有些差异。
在双飞翼中避免左右盒子被覆盖,是通过设置inner_middle的左右margin来实现的。
1 | .inner_middle{ |
另外,整个布局的左右padding留白也有些差异,直接设置父盒子的padding为左右留白的宽度就可以了。
1 | .container{ |
这里还有第二种实现方式,HTML结构沿用圣杯布局的结构,通过设置左右padding来避免中间盒子内容的覆盖。同时为了避免布局混乱,还有设置box-sizing: border-box,表示width包括border和padding,这样可以保证即使设置右左右padding,它的总宽度也是不变的。
1 | .middle{ |
推荐ProcessOn这个在线绘图网页,绘制思维导图非常方便,而且还是免费的,可以导出pdf、png、xmind等各种格式。
目前这是完成的进度:
相信很多新手朋友们对于React、Redux、React-Redux这三者之间的关系和区别肯定有很多不解和疑惑。这里我们就来详细的剖析一下它们吧。
React
:负责组件的UI界面渲染;Redux
:数据处理中心;React-Redux
:连接组件和数据中心,也就是把React和Redux联系起来。
React主要就是用来实现UI界面的,是一个专注于view层的框架。对于一些小项目,如果数据的交互不是很多,完全可以只使用React就能很好的实现。
在传统的页面开发模式中,需要多次的操作DOM来进行页面的更新,我们都知道对DOM的操作会造成极大的性能问题。而React的提出就是减少对DOM的操作来提升性能,也就是Virtual DOM。
Virtual DOM就相当于一个虚拟空间,React就是基于 Virtual DOM 来工作的。
它的工作过程是:当有数据需要进行更新时,会先计算 Virtual DOM ,并和上一次的 Virtual DOM 做对比,得到DOM结构的区别,然后只会将需要变化的部分批量的更新到真实的DOM上。
说到如何去计算Virtual DOM,在React里面,用到的是react-diff算法。我们都知道传统的diff算法是通过循环递归对每个节点进行依次对比,效率低下,算法复杂度达到了 O(n^3),其中 n 是树中节点的总数。
根据react diff策略:
React 分别对 tree diff、component diff 以及 element diff 进行了算法优化:
tree diff
:对树进行分层比较,两棵树只会对同一层次的节点进行比较component diff
:element diff
:当节点处于同一层级时,React diff 提供了三种节点操作,分别为:插入、移动、删除。这是整个react diff算法的比较流程图:
React总共有10个周期函数(render重复一次),这10个函数可以满足我们所有对组件操作的需求,利用的好可以提高开发效率和组件性能。
一、组件在初始化时会触发5个钩子函数:
getDefaultProps()
设置默认的props,es6中用 static dufaultProps={}
设置组件的默认属性。在整个生命周期只执行一次。
getInitialState()
在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state。此时可以访问this.props。
componentWillMount()
ajax数据的拉取操作,定时器的启动。组件初始化时调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。
render()
React最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
componentDidMount()
动画的启动,输入框自动聚焦组件渲染之后调用,可以通过this.getDOMNode()获取和操作dom节点,只调用一次。
二、在更新时也会触发5个钩子函数:
componentWillReceivePorps(nextProps)
组件初始化时不调用,组件接受新的props时调用。不管父组件传递给子组件的props有没有改变,都会触发。
shouldComponentUpdate(nextProps, nextState)
React性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候。不过调用this.forceUpdate会跳过此步骤。
componentWillUpdate(nextProps, nextState)
组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state
render()
不多说
componentDidUpdate()
组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。
三、卸载钩子函数
componentWillUnmount()
定时器的清除组件将要卸载时调用,一些事件监听和定时器需要在此时清除。
Redux是一种架构模式,是由flux发展而来的。
Redux主要由三部分组成:store,reducer,action。
Redux的核心是store,它由Redux提供的 createStore(reducer, defaultState) 这个方法生成,生成三个方法,getState(),dispatch(),subscrible()。
reducer是一个纯函数,它根据previousState和action计算出新的state。
reducer(previousState,action)
action本质上是一个JavaScript对象,其中必须包含一个type字段来表示将要执行的动作,其他的字段都可以根据需求来自定义。
1 | const ADD_TODO = 'ADD_TODO' |
1 | { |
他们三者之间的交互,可以由下图概括:
Redux 本身和React没有关系,只是数据处理中心,是React-Redux让他们联系在一起。
React-rRedux提供两个方法:connect和Provider。
connect连接React组件和Redux store。connect实际上是一个高阶函数,返回一个新的已与 Redux store 连接的组件类。
1 | const VisibleTodoList = connect( |
TodoList是 UI 组件,VisibleTodoList就是由 react-redux 通过connect方法自动生成的容器组件。
mapStateToProps
:从Redux状态树中提取需要的部分作为props传递给当前的组件。mapDispatchToProps
:将需要绑定的响应事件(action)作为props传递到组件上。Provider实现store的全局访问,将store传给每个组件。
原理:使用React的context,context可以实现跨组件之间的传递。
下图阐述了它们三者之间的工作流程:
]]>这篇文章主要是我平时在学习HTTP过程中看到的一些知识点,现在把他们总结成一篇文章,建立一个自己的知识体系,全是干货。另外,推荐一本非常棒的HTTP书——《图解HTTP》,这本书图文并茂,挺有趣的。
HTTP是基于TCP/IP协议的应用层协议,用于客户端和服务器之间的通信,默认80端口。我们按照他的发展历程的时间顺序开始说。
1990年提出的,是最早期的版本,只有一个命令GET。
1996年5月提出的。
缺点
:每个TCP连接只能发送一个请求。解决方法
:Connection:keep-alive 1997年1月提出,现在使用最广泛的。
长连接
:TCP连接默认不关闭,可以被多个请求复用。对于同一个域名,大多数浏览器允许同时建立6个持久连接。默认开启Connection:keep-alive。
管道机制
:在同一个TCP连接里,可以同时发送多个请求。但是服务器还是要按照请求的顺序进行响应,会造成“队头阻塞”。
HTTP首部分为请求报文和响应报文。它们的格式如下所示:
请求报文:
响应报文:
其中首部字段又分为很多种,我们先看通用首部字段,这是请求报文和响应报文种都会使用的首部。
1、Cache-Control
:操作缓存的工作机制
参数:
- public:明确表明其他用户也可以利用缓存
- private:缓存只给特定的用户
- no-cache:客户端发送这个指令,表示客户端不接收缓存过的响应,必须到服务器取;服务器返回这个指令,指缓存服务器不能对资源进行缓存。其实是不缓存过期资源,要向服务器进行有效期确认后再处理资源。
- no-store:指不进行缓存
- max-age:缓存的有效时间(相对时间)
2、Connection
:
- Connection:keep-Alive (持久连接)
- Connection:不再转发的首部字段名
3、Date
:表明创建http报文的日期和时间
4、Pragma
:兼容http1.0,与Cache-Control:no-cache含义一样。但只用在客户端发送的请求中,告诉所有的中间服务器不返回缓存。形式唯一:Pragma:no-cache
5、Trailer
:会事先说明在报文主体后记录了哪些首部字段,该首部字段可以应用在http1.1版本分块传输编码中。
6、Transfer-Encoding
:chunked (分块传输编码),
规定传输报文主体时采用的编码方式,http1.1的传输编码方式只对分块传输编码有效
7、Upgrade
:升级一个成其他的协议,需要额外指定Connection:Upgrade。服务器可用101状态码作为相应返回。
8、Via
:追踪客户端和服务器之间的请求和响应报文的传输路径。可以避免请求回环发生,所以在经过代理时必须要附加这个字段。
1、Accept:通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级
q表示优先级的权重值,默认为q = 1.0,范围是0~1(可精确到小数点后3位,1为最大值)
当服务器提供多种内容时,会先返回权重值最高的媒体类型
2、Accept-Charset:支持的字符集及字符集的相对优先顺序,跟Accept一样,用q来表示相对优先级。这个字段应用于内容协商机制的服务器驱动协商。
3、Accept-Encoding:支持的内容编码及内容编码的优先级顺序,q表示相对优先级。
内容编码:gzip、compress、deflate、identity(不执行压缩或者不会变化的默认编码格式)。
可以使用*作为通配符,指定任意的编码格式。
4、Accept-Language:能够处理的自然语言集,以及相对优先级。
101 协议升级
,主要用于升级到websocket,也可以用于http2
200 OK
204 No content
,服务器成功处理请求,但是返回的响应报文中不含实体的主体部分
206 Partial Content
,表示客户端像服务器进行了范围请求(Content-Range字段),服务器成功返回指定范围的实体内容
301 永久性重定向
,表示请求的资源已经被分配了新的url,旧地址以后都不能再访问了,服务器会返回location字段,包含的是新的地址。
302 临时性重定向
,表示请求的资源临时移动到一个新地址
注意:尽量使用301跳转,因为302会造成网址劫持,可能被搜索引擎判为可疑转向,甚至认为是作弊。
原因:从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了。
303 See Other
,与302功能相同,但是它明确规定客户端应采用GET方法获取资源
304 未修改
,协商缓存中返回的状态码
307 临时重定向
,与302功能相同,但规定不能从POST变成GET
当301、302、303响应状态码返回时,几乎所有浏览器都会把post改成get,并删除请求报文内的主体,之后请求会自动再次发送。然而301、302标准是禁止将post方法改变成get方法的,但实际使用时大家都会这么做。所以需要307。
400 Bad Request
,表示请求报文中存在语法错误。当错误发生时,需要修改请求的内容再次发送请求
401 unauthorized
,表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。如果之前已经进行过一次请求,表示用户认证失败。
403 禁止
,表示拒绝对请求资源的访问
404 Not Found
,表明服务器上无法找到请求的资源
500 Internet Server Error
,该状态码表示服务器在执行请求时发生了错误
500 Service Unavailable
,表示服务器暂时处于超负荷或者处于停机维护状态,现在无法处理请求
2009年谷歌提出。
SPDY结构
:新增特性
:缺点
:html5新提出来的,是web浏览器与web服务器之间的全双工通信标准。主要是为了解决ajax和comet里的xmlhttprequest附带的缺陷所引起的问题。
(1)推送功能:服务器可直接发送数据,不需要等待客户端的请求;
(2)基于TCP传输协议,并复用HTTP的握手通道;
(3)支持双向通信,用于实时传输消息;
(4)更好的二进制支持;
(5)更灵活,更高效。
1、客户端:发起协议升级请求
1 | GET / HTTP/1.1 `采用HTTP报文格式,只支持get请求` |
2、服务端:响应协议升级
1 | HTTP/1.1 101 Switching Protocols `101表示协议切换==` |
Sec-WebSocket-Key 的加密过程为:
- 将Sec-WebSocket-Key跟258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接。
- 通过SHA1计算出摘要,并转成base64字符串。
3、双方握手成功后,就是全双工的通信了,接下来就是用websocket协议来进行通信了。
1、ajax轮询
让浏览器每隔一定的时间就发送一次请求,询问服务器是否有新信息。
2、长轮询(Long Poll)
采用的阻塞模式。客户端发起连接后,如果没消息,服务器不会马上告诉你没消息,而是将这个请求挂起(pending),直到有消息才返回。返回完成或者客户端主动断开后,客户端再次建立连接,周而复始。Comet就是采用的长轮询。
3、websocket
WebSocket 是类似 Socket 的TCP长连接通讯模式。一旦 WebSocket 连接建立后,后续数据都以帧序列的形式传输。而且浏览器和服务器就可以随时主动发送消息给对方,是全双工通信。
优点:在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。
2015年发布,它是基于SPDY的,以下是它的一些新特性:
1、 二进制分帧
:
http/1.x 是一个超文本协议,而 http2 是一个二进制协议,被称之为二进制分帧。
二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
协议格式为帧,帧由 Frame Header(头信息帧)和 Frame Payload(数据帧)组成,如下所示:
2、头部压缩 HPACK
:
请求和响应首部压缩,客户端和服务端共同维护一张头信息表,所有字段存入这个表,生成一个索引号,通过发送索引号提高速度。HPACK压缩会经过两步:
- 传输的value,会经过一遍Huffman coding来节省资源;
- 为了server和client同步, 两边都需要保留一份Header list, 并且,每次发送请求时,都会检查更新。
3、服务端推送
:
服务端主动向客户端推送数据。如果客户端请求一个html文件,服务端把html文件返回给客户端之后,还会相应的把html文件中的js、css、图片推送给客户端。
4、多路复用
:
只需要建立一个TCP连接,浏览器和服务器可以同时发送多个请求或者回应,而且不需要按照顺序一一对应,避免了“队头阻塞”。
5、数据流
:
当客户端同时向服务端发起多个请求,那么这些请求会被分解成一一个的帧,每个帧都会在一个 TCP 链路中无序的传输,同一个请求的帧的 Stream Identifier 都是一样的。当帧到达服务端之后,就可以根据 Stream Identifier 来重新组合得到完整的请求。
并且规定:客户端发出的数据流ID为奇数,服务器发出的ID为偶数。Stream Identifier (数据流ID)就是用来标识该帧属于哪个请求的。
HTTPS = HTTP+加密+认证+完整性保护
它的加密过程是:
下图是加密过程的图解,可以对照着图片理一遍。
HTTP的缓存分为强缓存和协商缓存(对比缓存)。
强制缓存
在缓存数据未失效的情况下,可以直接使用缓存数据;在没有缓存数据的时候,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中。
Expires:缓存过期时间(HTTP1.0)
缺点:生成的是绝对时间,但是客户端时间可以随意修改,会导致误差。
Cache-Control :HTTP1.1,优先级高于Expires
可设置参数:
private: 客户端可以缓存
public: 客户端和代理服务器都可缓存
max-age=xxx: 缓存的内容将在 xxx 秒后失效
no-cache: 需要使用协商缓存来验证缓存数据(后面介绍)
no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发
Expires和Cache-Control决定了浏览器是否要发送请求到服务器,ETag和Last-Modified决定了服务器是要返回304+空内容还是新的资源文件。
协商缓存
浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。
Last-Modified
:服务器在响应请求时,告诉浏览器资源的最后修改时间。If-Modified-Since
:再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
缺点:Last-Modified 标注的最后修改时间只能精确到秒,如果有些资源在一秒之内被多次修改的话,他就不能准确标注文件的新鲜度了。如果某些资源会被定期生成,当内容没有变化,但 Last-Modified 却改变了,导致文件没使用缓存有可能存在服务器没有准确获取资源修改时间,或者与代理服务器时间不一致的情形。
Etag
:给资源计算得出的一个唯一标志符。If-None-Match
:再次请求服务器时,通过此字段通知服务器客户端缓存数据的唯一标识。
具体过程如下图:
跨域产生的原因,是因为受到同源策略的限制。同源策略指的是协议、域名、端口不相同。这里我将介绍三种跨域的方式:JSONP、CORS(跨域资源共享)、document.domain + iframe。
1. 原理
动态插入script标签(因为script标签不受同源策略的限制),通过插入script标签引入一个js文件,这个js文件加载成功之后会执行我们在url中指定的回调函数,并且会把我们需要的json数据作为参数传入。
2. 实现
(1)原生实现:
1 | var script = document.createElement('script'); |
(2)jquery ajax:
1 | $.ajax({ |
1. 原理
服务器在响应头中设置相应的选项,浏览器如果支持这种方法的话就会将这种跨站资源请求视为合法,进而获取资源。
2. 实现
CORS分为简单请求和复杂请求,简单请求指的是:
(1)请求方法是以下三种方法之一:HEAD、GET、POST;
(2)HTTP的头信息不超出以下几种字段:
Accept、Accept-Language、Content-Language、Last-Event-ID、
Content-Type(只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)。
其他情况就是非简单请求了。
(1)请求头
:
1 | Origin: http://www.domain.com |
(2)响应头
:
1 | Access-Control-Allow-Origin: http://www.domain.com |
(3)另外,ajax请求中
,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名,还要设置以下内容:
1 | var xhr = new XMLHttpRequest(); |
(1)预检请求
:
1 | OPTIONS /cors HTTP/1.1 `OPTIONS请求是用来询问的` |
(2)响应头
:
1 | Access-Control-Allow-Origin: http://www.domain.com |
(3)之后的步骤就同简单请求了
。
这是CORS的整个流程图:
与JSOP的比较:
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
此方案仅限主域相同,子域不同的跨域应用场景。
1.原理
两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
2.实现
(1)父窗口:(www.domain.com/a.html)
1 | <iframe id="iframe" src="http://child.domain.com/b.html"></iframe> |
(2)子窗口:(child.domain.com/b.html)
1 | <script> |
先写这么多,后续我会继续补充的,像cookie,session那些我以后会加进来的。
]]>我是对照着网上别人看过的源码笔记看的,写这篇文章的原因呢,是想总结一下,因为我记性比较差啦,算是做一个笔记,方便以后复习。
redux的源码中,有6个js文件,分别是:
我们一个一个来分析吧~
这里呢没有太多需要讲的,就是暴露了5个核心的api,分别是:
首先,定义初始化的action
1 | export const ActionTypes = { |
这个createStore函数,会传入三个参数和一个返回值,分别是:
1、 @param {Function} reducer
这个reducer是一个函数,这个函数接收state和action,作一系列计算之后返回一个新的state。这里就体现了函数式编程的一些特性:
第一,这个reducer是一个纯函数,纯函数的特点是:对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环境的状态。不理解纯函数的筒子们,可以上网搜索一下。
第二,state是不可变的,我们这里对state作的一些修改和计算,不是直接修改原来的数据,而是返回修改之后的数据,原来的数据是保持不变。这里可以衍生到immutable,可以使用immutable和redux搭配使用。
2、@param {any} [preloadedState]
这是初始化的state,不多说。
3、@param {Function} [enhancer]
这个enhancer其实就是一个中间件,它在redux3.1.0之后才加入的。相当于把store做一些增强处理,让store更强大,功能更丰富,在之后的applyMiddleware那里会详细说的。这里也体现了高阶函数的思想,就像react-redux的connect方法一样,做一些包装处理之后,再返回。
4、@returns {Store}
这是返回的值,返回的是一棵状态树,也就是store啦。
这是做的源码分析,都写在注释里了。createStore返回的最常用的三个api是dispatch,subscribe,getState,一般我们只要传入reducer和preloadedState,就可以直接调用这三个方法,非常方便。
1 | export default function createStore(reducer, preloadedState, enhancer) { |
combineReducers的作用是将之前切分的多个子reducer合并成一个大的reducer,也就是说将很多的小状态树合并到一棵树上,整合成一棵完整的状态树。
这个函数接受一个参数,返回一个函数
1、@param {Object} reducers
这里接收多个reducer,传入的是一个对象
2、@returns {Function}
combineReducers的整个执行过程就是:将所有符合标准的reducer放进一个对象中,当dispatch一个action的时候,就遍历每个reducer,来计算出每个reducer的state值。同时,每遍历一个reducer,就判断新旧state是否发生改变,来决定是返回新state还是旧state,这是做的一个优化处理。
源码分析如下,前面还有一部分是一些error信息和warning信息的处理,就没有放进来了,感兴趣的话可以自己去看一下完整的源码。
1 | export default function combineReducers(reducers) { |
bindActionCreators的作用是:将action与dispatch函数绑定,生成可以直接触发action的函数。
1 | //使用dispatch包装actionCreator方法 |
compose叫做函数组合,是一个柯里化函数,将多个函数合并成一个函数,从右到左执行。这同时也是函数式编程的特性。这个函数会在applyMiddleware中用到
1 | /** |
这一段代码的主要难点是在最后那一句,着重说一下reduce这个方法。这个reduce不是之前的reducer,这里的reduce函数是es5的一个归并数组的方法,是从数组的第一项开始,逐个遍历数组的所有项。
它接收两个参数,一个是在每一项上调用的函数,还有一个可选参数,是作为归并基础的初始值。调用的那个函数又接收四个参数,前一个值,当前值,项的索引,和数组对象。这个函数返回的任何值都会作为第一个参数自动传递给下一项。这样说可能比较抽象,举个例子:
1 | [1,2,3,4,5].reduce((prev, cur) => { |
用reduce就可以很快的求的数组所有值相加的和。另外,还有一个reduceRight()方法,跟reduce是一样的,只不过是从数组的右边开始遍历的。
我们回到源码上面return funcs.reduce((a, b) => (...args) => a(b(...args)))
,这其实就是遍历传入的参数数组(函数),将这些函数合并成一个函数,从右到左的执行。这就是中间件的创造过程,把store用一个函数包装之后,又用另一个函数包装,就形成了这种包菜式的函数。
applyMiddleware是用来扩展redux功能的,主要就是扩展store.dispatch的功能,像logger、redux-thunk就是一些中间件。
它的实现过程是:在dispatch的时候,会按照在applyMiddleware时传入的中间件顺序,依次执行。最后返回一个经过许多中间件包装之后的store.dispatch方法。
如果理解了之前说的compose函数,这一段代码应该也很容易就能看懂啦。
1 | /** |
整个的源码就全部分析完了,我们可以看到,redux的源码很多地方都体现了函数式编程的思想。函数式编程写出来的代码确实很漂亮很简洁,但是理解起来也比较困难。这也只是函数式编程的很小一部分,有兴趣的话可以去了解一下其他的部分。
写到这里也差不多了,希望以后有机会能多看点源码,get一些新的知识,最后感谢宋老师的宝贵意见,bye
]]>