HTML 篇
说说 title 和 alt 属性
- 两个属性都是当鼠标滑动到元素上的时候显示
-
alt是img的特有属性,是图片内容的等价描述,图片无法正常显示时候的替代文字。 -
title属性可以用在除了base,basefont,head,html,meta,param,script和title之外的所有标签,是对dom元素的一种类似注释说明,
Html5 有哪些新特性、移除了哪些元素
- 新增元素:
- 绘画
canvas - 用于媒介回放的
video 和 audio元素 - 本地离线存储
localStorage长期存储数据,浏览器关闭后数据不丢失 -
sessionStorage的数据在浏览器关闭后自动删除 - 语义化更好的内容元素,比如
article 、footer、header、nav、section - 表单控件 ,
calendar 、 date 、 time 、 email 、 url 、 search - 新的技术
webworker 、 websocket 、 Geolocation
- 绘画
- 移除的元素:
- 纯表现的元素:
basefont 、 big 、 center 、 font 、 s 、 strike 、 tt 、 u - 对可用性产生负面影响的元素:
frame 、 frameset 、 noframes
- 纯表现的元素:
- 支持 HTML5 新标签:
-
IE8/IE7/IE6支持通过document.createElement方法产生的标签 - 可以利用这一特性让这些浏览器支持
HTML5新标签 - 浏览器支持新标签后,还需要添加标签默认的样式
-
浏览器是怎么对 Html5 的离线储存资源进行管理和加载的呢
如何使用:
- 页面头部像下面一样加入一个
manifest的属性; - 在
cache.manifest文件的编写离线存储的资源 - 在离线状态时,操作
window.applicationCache进行需求实现
在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问 app ,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
iframe有那些缺点?
-
iframe会阻塞主页面的Onload事件 - 搜索引擎的检索程序无法解读这种页面,
不利于 SEO -
iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载 - 使用
iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题
HTML W3C的标准
标签闭合、标签小写、不乱嵌套、使用外链 css 和 js 、结构行为表现的分离
Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
-
<!DOCTYPE>声明位于文档中的最前面,处于html标签之前。告知浏览器的解析器, 用什么文档类型、规范来解析这个文档 - 严格模式的排版和
JS运作模式是 以该浏览器支持的最高标准运行 - 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作
DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现
HTML全局属性(global attribute)有哪些
-
class:为元素设置类标识 -
data-*: 为元素增加自定义属性 -
draggable: 设置元素是否可拖拽 -
id: 元素 id ,文档内唯一 -
lang: 元素内容的的语言 -
style: 行内 css 样式 -
title: 元素相关的建议信息
viewport的content属性作用
<meta name="viewport" content="" />
width viewport的宽度[device-width | pixel_value]width如果直接设置pixel_value数值,大部分的安卓手机不支持,但是ios支持;
height – viewport 的高度 (范围从 223 到 10,000 )
user-scalable [yes | no]是否允许缩放
initial-scale [数值] 初始化比例(范围从 > 0 到 10)
minimum-scale [数值] 允许缩放的最小比例
maximum-scale [数值] 允许缩放的最大比例
target-densitydpi 值有以下(一般推荐设置中等响度密度或者低像素密度,后者设置具体的值dpi_value,另外webkit内核已不准备再支持此属性)
-- dpi_value 一般是70-400//没英寸像素点的个数
-- device-dpi设备默认像素密度
-- high-dpi 高像素密度
-- medium-dpi 中等像素密度
-- low-dpi 低像素密度
复制代码
附带问题:怎样处理 移动端 1px 被 渲染成 2px 问题?
局部处理:
-
mate标签中的viewport属性 ,initial-scale设置为 1 -
rem按照设计稿标准走,外加利用transfrome 的 scale(0.5)缩小一倍即可;
全局处理:
-
mate标签中的viewport属性 ,initial-scale设置为 0.5 -
rem按照设计稿标准走即可
meta 相关
<!DOCTYPE html> <!--H5标准声明,使用 HTML5 doctype,不区分大小写-->
<head lang=”en”> <!--标准的 lang 属性写法-->
<meta charset=’utf-8′> <!--声明文档使用的字符编码-->
<meta http-equiv=”X-UA-Compatible” content=”IE=edge,chrome=1″/> <!--优先使用指定浏览器使用特定的文档模式-->
<meta name=”description” content=”不超过150个字符”/> <!--页面描述-->
<meta name=”keywords” content=””/> <!-- 页面关键词-->
<meta name=”author” content=”name, email@gmail.com”/> <!--网页作者-->
<meta name=”robots” content=”index,follow”/> <!--搜索引擎抓取-->
<meta name=”viewport” content=”initial-scale=1, maximum-scale=3, minimum-sc
<meta name=”apple-mobile-web-app-title” content=”标题”> <!--iOS 设备 begin-->
<meta name=”apple-mobile-web-app-capable” content=”yes”/> <!--添加到主屏后的标
是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏-->
<meta name=”apple-mobile-web-app-status-bar-style” content=”black”/>
<meta name=”renderer” content=”webkit”> <!-- 启用360浏览器的极速模式(webkit)-->
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <!--避免IE使用兼容模式-->
<meta http-equiv=”Cache-Control” content=”no-siteapp” /> <!--不让百度转码-->
<meta name=”HandheldFriendly” content=”true”> <!--针对手持设备优化,主要是针对一些老的不识别viewport的浏览器-->
<meta name=”MobileOptimized” content=”320″> <!--微软的老式浏览器-->
<meta name=”screen-orientation” content=”portrait”> <!--uc强制竖屏-->
<meta name=”x5-orientation” content=”portrait”> <!--QQ强制竖屏-->
<meta name=”full-screen” content=”yes”> <!--UC强制全屏-->
<meta name=”x5-fullscreen” content=”true”> <!--QQ强制全屏-->
<meta name=”browsermode” content=”application”> <!--UC应用模式-->
<meta name=”x5-page-mode” content=”app”> <!-- QQ应用模式-->
<meta name=”msapplication-tap-highlight” content=”no”> <!--windows phone
设置页面不缓存-->
<meta http-equiv=”pragma” content=”no-cache”>
<meta http-equiv=”cache-control” content=”no-cache”>
<meta http-equiv=”expires” content=”0″>
复制代码
div+css的布局较table布局有什么优点
- 改版的时候更方便 只要改
css文件。 - 页面加载速度更快、结构化清晰、页面显示简洁。
- 表现与结构相分离。
- 易于优化
( seo )搜索引擎更友好,排名更容易靠前。
src与href的区别
-
src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。 -
src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素
-
href 是 Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加 -link href="common.css" rel="stylesheet"那么浏览器会识别该文档为css文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用link方式来加载css,而不是使用@import方式
CSS 篇
link 与 @import 的区别
-
link是HTML方式,@import是CSS方式 -
link最大限度支持并行下载,@import过多嵌套导致串行下载,出现 FOUC (文档样式短暂失效) -
link可以通过rel="alternate stylesheet"指定候选样式 - 浏览器对
link支持早于@import,可以使用@import对老浏览器隐藏样式 -
@import必须在样式规则之前,可以在css文件中引用其他文件 - 总体来说:
link优于@import,link优先级也更高
BFC 有什么用
- 创建规则:
- 根元素
- 浮动元素(
float不取值为none) - 绝对定位元素(
position取值为absolute或fixed) -
display取值为inline-block 、 table-cell 、 table-caption 、 flex 、inline-flex之一的元素 -
overflow不取值为visible的元素
- 作用
- 可以包含浮动元素
- 不被浮动元素覆盖
- 阻止父子元素的
margin折叠
清除浮动的几种方式
- 父级
div定义height - 结尾处加空
div标签clear:both - 父级
div定义伪类:after和zoom - 父级
div定义overflow:hidden - 父级
div也浮动,需要定义宽度 - 结尾处加
br标签clear:both
Css3 新增伪类 - 伪元素
-
p:first-of-type选择属于其父元素的首个 <p> 元素的每个 <p> 元素。 -
p:last-of-type选择属于其父元素的最后 <p> 元素的每个 <p> 元素。 -
p:only-of-type选择属于其父元素唯一的 <p> 元素的每个 <p> 元素。 -
p:only-child选择属于其父元素的唯一子元素的每个 <p> 元素。 -
p:nth-child(2)选择属于其父元素的第二个子元素的每个 <p> 元素。 -
:enabled已启用的表单元素。 -
:disabled已禁用的表单元素。 -
:checked单选框或复选框被选中。 -
::before在元素之前添加内容。 -
::after在元素之后添加内容,也可以用来做清除浮动。 -
::first-line添加一行特殊样式到首行。 -
::first-letter添加一个特殊的样式到文本的首字母。
- 伪类语法一个:,它是为了弥补css常规类选择器的不足
- 伪元素语法两个:,它是凭空创建的一个虚拟容器生成的元素
IE盒子模型 、W3C盒子模型
- W3C盒模型: 内容(content)、填充( padding )、边界( margin )、 边框( border );
box-sizing: content-box- width = content width;
- IE盒子模型: IE 的content 部分把 border 和 padding 计算了进去;
box-sizing: border-box- width = border + padding + content width
display:inline-block 什么时候不会显示间隙?
- 移除空格
- 使用
margin负值 - 使用
font-size:0 letter-spacingword-spacing
行内元素float:left后是否变为块级元素?
行内元素设置成浮动之后变得更加像是 inline-block (行内块级元素,设置 成这个属性的元素会同时拥有行内和块级的特性,最明显的不同是它的默认宽度不是 100% ),这时候给行内元素设置 padding-top 和 padding-bottom或者 width 、 height 都是有效果的
如果需要手动写动画,你认为最小时间间隔是多久,为什么?
多数显示器默认频率是 60Hz ,即 1 秒刷新 60 次,所以理论上最小间隔为 1/60*1000ms = 16.7ms
CSS权重,计算规则
-
!important> 内联样式 > ID > 类属性、属性选择器或者伪类选择器 > 标签选择器
CSS REFACTORING中提到了算法的过程,取决于A、B、C、D的值,abcd是什么呢?
| 符号 | 计算方式 |
|---|---|
| A ( 内联样式) | 有内联样式时 A=1 否则0 |
| B(ID选择器出现次数) | 有两层ID选择器 B=2 |
| C (类选择器出现的次数) | 类选择器1个, 属性选择器1个,伪类选择器2个 C=4 |
| D (标签、伪类选择器出现次数) | 标签选择器2个,伪类选择器1个 D=3 |
li /* (0, 0, 0, 1) */
ul li /* (0, 0, 0, 2) */
ul ol+li /* (0, 0, 0, 3) */
ul ol+li /* (0, 0, 0, 3) */
h1 + *[REL=up] /* (0, 0, 1, 1) */
ul ol li.red /* (0, 0, 1, 3) */
li.red.level /* (0, 0, 2, 1) */
a1.a2.a3.a4.a5.a6.a7.a8.a9.a10.a11 /* (0, 0, 11,0) */
#x34y /* (0, 1, 0, 0) */
li:first-child h2 .title /* (0, 0, 2, 2) */
#nav .selected > a:hover /* (0, 1, 2, 1) */
html body #nav .selected > a:hover /* (0, 1, 2, 3) */
复制代码
- 最终从A开始逐层比较,A => B =>C =>D 哪个大优先哪个样式生效,否则后面覆盖前面样式,这也是为什么有的嵌套多层样式可以实现覆盖的原因。
- 样式名称也有就近原则,作用在当前标签的能覆盖继承来的样式
- 最终将这几个条件合并起来就是css的权重问题和计算规则
stylus/sass/less区别
- 均具有“变量”、“混合”、“嵌套”、“继承”、“颜色混合”五大基本特性
-
Sass和LESS语法较为严谨,LESS要求一定要使用大括号“{}”,Sass和Stylus可以通过缩进表示层次与嵌套关系 -
Sass无全局变量的概念,LESS和Stylus有类似于其它语言的作用域概念 -
Sass是基于Ruby语言的,而LESS和Stylus可以基于NodeJS NPM下载相应库后进行编译;这也是为什么安装Sass的时候有时候会报错,需要安装python脚本
优点:就不用我多说了,谁用谁知道,真香。
rgba()和opacity的透明效果有什么不同?
-
rgba()和opacity都能实现透明效果,但最大的不同是opacity作用于元素,以及元素内的所有内容的透明度, - 而
rgba()只作用于元素的颜色或其背景色。(设置 rgba 透明的元素的子元素不会继承透明效果!)
水平居中的方法
- 元素为行内元素,设置父元素
text-align:center - 如果元素宽度固定,可以设置左右
margin 为 auto; - 如果元素为绝对定位,设置父元素
position 为 relative,元素设left:0;right:0;margin:auto; - 使用
flex-box布局,指定justify-content属性为center -
display设置为tabel-ceil
垂直居中的方法
- 将显示方式设置为表格,
display:table-cell,同时设置vertial-align:middle - 使用
flex布局,设置为align-item:center - 绝对定位中设置
bottom:0,top:0,并设置margin:auto - 绝对定位中固定高度时设置
top:50%,margin-top值为高度一半的负值 - 文本垂直居中设置
line-height为height值
浏览器 篇
浏览器内核的理解
- 主要分两个部分:
渲染引擎、js引擎 -
渲染引擎:负责取得网页的内容(html css img ...),以及计算网页的显示方式,然后会输出至显示器或者打印机。浏览器的内核不同对于网页的语法解释也不同,所以渲染的效果也不一样 -
js引擎:解析和执行javascript 来实现网页的动态效果 - 最开始渲染引擎和js引擎并没有区分的很明确,后来js引擎越来越独立,内核就倾向于只值渲染引擎
-
IE : trident内核 -
Firefox : gecko内核 -
Safari : webkit内核 -
Opera:以前是presto内核,Opera现已改用Google - Chrome的Blink内核 -
Chrome:Blink(基于webkit,Google与Opera Software共同开发)
HTTP 的请求方式场景
-
Get方法:获取数据通常(查看数据)-查看 -
POST方法:向服务器提交数据通常(创建数据)-create -
PUT方法:向服务器提交数据通常(更新数据)-update,与POST方法很像,也是提交数据,但PUT制定了资源在服务器上的位置,常用在修改数据 -
HEAD方法:只请求页面的首部信息 -
DELETE方法:删除服务器上的资源 -
OPTIONS方法:用于获取当前URL支持的请求方式 -
TRACE方法:用于激活一个远程的应用层请求消息回路 -
CONNECT方法:把请求链接转换到透明的TCP/IP的通道
HTTP状态码
-
1XX:信息状态码-
100 continue继续,一般在发送 post 请求时,已发送了 http header 之后服务端将返回此信息,表示确认,之后发送具体参数信息
-
-
2XX:成功状态码-
200 ok正常返回信息 -
201 created请求成功并且服务器创建了新资源 -
202 accepted服务器已经接收请求,但尚未处理
-
-
3XX:重定向-
301 move per请求的网页已经永久重定向 -
302 found临时重定向 -
303 see other临时冲重定向,且总是使用get请求新的url -
304 not modified自从上次请求后,请求的网页未修改过
-
-
4XX:客户端错误-
400 bad request服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求 -
401 unauthorized请求未授权 -
403 forbidden禁止访问
-
-
404 not found找不到如何与url匹配的资源 -
5XX:服务器错误-
500 internal server error最常见的服务器端的错误 -
503 service unacailable服务器端暂时无法处理请求(可能是过载活维护)
-
从浏览器地址栏输入URL后发生了什么?
基础版本
- 1.的浏览器根据请求的
URL交给DNS域名解析,找到真实IP,向服务器发起请求; - 2.服务器交给后台处理完成后返回数据,浏览器接收文件
( HTML、JS、CSS 、图象等); - 3.浏览器对加载到的资源
( HTML、JS、CSS 等)进行语法解析,建立相应的内部数据结构(如 HTML 的 DOM ); - 4.载入解析到的资源文件,渲染页面,完成。
详细版
- 1.从浏览器接收
url到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的关系) - 2.开启网络线程到发出一个完整的
HTTP请求(这一部分涉及到dns查询,TCP/IP请求,五层因特网协议栈等知识) - 3.从服务器接收到请求到对应后台接收到请求(这一部分可能涉及到负载均衡,安全拦截以及后台内部的处理等等)
- 4.后台和前台的
HTTP交互(这一部分包括HTTP头部、响应码、报文结构、cookie等知识,可以提下静态资源的cookie优化,以及编码解码,如gzip压缩等) - 5.单独拎出来的缓存问题,
HTTP的缓存(这部分包括http缓存头部,ETag , catchcontrol等) - 6.浏览器接收到
HTTP数据包后的解析流程(解析html-词法分析然后解析成dom树、解析css生成css规则树、合并成render树,然后layout 、 painting渲染、复合图层的合成、GPU绘制、外链资源的处理、loaded 和 DOMContentLoaded等) - 7.
CSS的可视化格式模型(元素的渲染规则,如包含块,控制框,BFC, IFC 等概念) - 8.
JS引擎解析过程(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等) - 9.其它(可以拓展不同的知识模块,如跨域,
web安全,hybrid模式等等内容)
详细升级版
- 1.在浏览器地址栏输入
URL - 2.浏览器查看缓存,如果请求资源在缓存中并且新鲜,跳转到转码步骤
- 2.1 如果资源未缓存,发起新请求
- 2.2 如果已缓存,检验是否足够新鲜,足够新鲜直接提供给客户端,否则与服务器进行验证。
- 2.3 检验新鲜通常有两个
HTTP头进行控制Expires和Cache-Control:- 2.3.1
HTTP1.0提供Expires,值为一个绝对时间表示缓存新鲜日期 - 2.3.2
HTTP1.1增加了Cache-Control: max-age=,值为以秒为单位的最大新鲜时间
- 2.3.1
- 3.浏览器解析
URL获取协议,主机,端口,path - 4.浏览器组装一个
HTTP(GET)请求报文 - 5.浏览器获取主机
ip地址,过程如下:- 5.1 浏览器缓存
- 5.2 本机缓存
- 5.3 hosts文件
- 5.4 路由器缓存
- 5.5 ISP DNS缓存
- 5.6 DNS递归查询(可能存在负载均衡导致每次IP不一致)
- 6.打开一个
socket与目标IP地址,端口建立TCP链接,三次握手如下:- 6.1 客户端发送一个
TCP的SYN=1,Seq=X的包到服务器端口 - 6.2 服务器发回
SYN=1,ACK=x+1,Seq=Y的相应包 - 6.3 客户端发送
ACK=Y+1,Seq=z
- 6.1 客户端发送一个
- 7.
TCP链接建立后发送HTTP请求 - 8.服务器接收请求后解析,将请求转发到服务器程序,如虚拟主机使用
HTTP Host头部判断请求的服务程序 - 9.服务器检测
HTTP请求头是否包含缓存验证信息,如果验证缓存新鲜,返回304等对应状态 - 10.出合理程序读取完整请求并准备
HTTP相应,可能需要查询数据库等操作 - 11.服务器将相应报文通过
TCP链接发送回浏览器 - 12.浏览器接收
HTTP相应,然后根据情况选择关闭TCP链接或者保留重用,关闭TCP链接的四次握手如下:- 12.1 主动方发送
Fin=1,ACK=z,Seq=x报文 - 12.2 被动方发送
ACK=X+1,Seq=Y报文 - 12.3 被动方发送
Fin=1,ACK=X,Seq=Y报文 - 12.4 主动方发送
ACK=Y,Seq=x报文
- 12.1 主动方发送
- 13.浏览器检查相应状态码
- 14.如果资源可缓存,进行缓存
- 15.对相应进行解码
- 16.根据资源类型决定如何处理
- 17.解析
HTML文档,构建DOM树,下载资源,构建CSSOM树,执行js脚本,这些操作每月严格的先后顺序 - 18.构建DOM树:
- 18.1 Tokenizing:根据HTML规范将字符流解析为标记
- 18.2 Lexing:词法分析将标记转换为对象并定义属性和规则
- 18.3 DOM construction:根据HTML标记关系将对象组成DOM树
- 19.解析过程中遇到图片、样式表、js文件,启动下载
- 20.构建
CSSOM树:- 20.1
Tokenizing:字符流转换为标记流 - 20.2
Node:根据标记创建节点 - 20.3
CSSOM:节点创建CSSOM树
- 20.1
-
- 根据
DOM树和CSSOM树构建渲染树
- 21.1 从
DOM树的根节点遍历所有可见节点,不可见节点包括:1)script , meta这样本身不可见的标签。2)被css隐藏的节点,如 display: none - 21.2 对每一个可见节点,找到恰当的
CSSOM规则并应用 - 21.3 发布可视节点的内容和计算样式
- 根据
- 22.js解析如下
- 22.1 浏览器创建
Document对象并解析HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate为loading - 22.2 HTML解析器遇到没有
async和defer的script时,将他们添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用document.write()把文本插入到输入流中。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容 - 22.3 当解析器遇到设置了
async属性的script时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用document.write(),它们可以访问自己script和之前的文档元素 - 22.4 当文档完成解析,
document.readState变成interactive - 22.5 所有
defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用document.write() - 22.6 浏览器在
Document对象上触发DOMContentLoaded事件 - 22.7 此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,
document.readState变为complete,window触发load事件
- 22.1 浏览器创建
- 23.显示页面(HTML解析过程中会逐步显示页面)
cookies , sessionStorage 和 localStorage 的区别
-
cookie是网站为了标示用户身份而储存在用户本地终端上的数据(通常经过加密) -
cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递(优化点) -
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存 - 存储大小:
-
cookie数据大小不能超过4k -
sessionStorage 和 localStorage虽然也有存储大小的限制,但比 cookie 大得多,可以达到5M或更大
-
- 有期时间:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
sessionStorage 数据在当前浏览器窗口关闭后自动删除
cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭
浏览器缓存
- 先根据这个资源的一些
http header判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器; - 当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些
request header验证这个资源是否命中协商缓存,称为http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源; - 强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源; 区别是,强缓存不对发送请求到服务器,但协商缓存会。
- 当协商缓存也没命中时,服务器就会将资源发送回客户端。
- 当
ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存; - 当
f5刷新网页时,跳过强缓存,但是会检查协商缓存;
强缓存-协商缓存:了解更多加入我们前端学习圈
JS 篇
说几条写JavaScript的基本规范
- 不要在同一行声明多个变量
- 请是用 ===/!== 来比较
true/false或者数值 - 使用对象字面量替代
new Array这种形式 - 不要使用全局函数
-
Switch语句必须带有default分支 -
If语句必须使用大括号 -
for-in循环中的变量 应该使用let关键字明确限定作用域,从而避免作用域污染
绕不过去的闭包
- 闭包就是能够读取其他函数内部变量的函数
- 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个
- 函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域
- 闭包的特性:
- 函数内再嵌套函数
- 内部函数可以引用外层的参数和变量
- 参数和变量不会被垃圾回收机制回收
- 优点:能够实现封装和缓存等
- 缺点:消耗内存、使用不当会内存溢出,
- 解决方法:在退出函数之前,将不使用的局部变量全部删除
说说你对作用域链的理解
- 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到
window对象即被终止,作用域链向下访问变量是不被允许的。 - 简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期
JavaScript原型,原型链 ? 有什么特点?
- 每个对象都会在其内部初始化一个属性,就是
prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念 - 关系:
instance.constructor.prototype = instance._*proto*_ - 特点:
JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的,就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到Object内建对象
请解释什么是事件委托/事件代理
- 事件代理
( Event Delegation ),又称之为事件委托。是JavaScript中常用的绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定的事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。使用事件代理的好处是可以提高性能 - 可以大量节省内存占用,减少事件注册,比如在
table上代理所有td 的 click事件就非常棒 - 可以实现当新增子对象时无需再次对其绑定
Javascript如何实现继承?
- 构造继承
- 原型继承
- 实例继承
- 拷贝继承
- 原型
prototype机制或apply 和 call方法去实现较简单,建议使用构造函数与原型混合方式
function Parent(){
this.name = 'wang';
}
function Child(){
this.age = 28;
}
Child.prototype = new Parent();//继承了Parent,通过原型
var demo = new Child();
alert(demo.age);
alert(demo.name);//得到被继承的属性
复制代码
谈谈This对象的理解
-
this总是指向函数的直接调用者(而非间接调用者) - 如果有
new关键字,this指向new出来的那个对象 - 在事件中,
this指向触发这个事件的对象,特殊的是,IE中的attachEvent 中的this总是指向全局对象Window
事件模型
- 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发
- 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发
-
DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件 - 阻止冒泡:在
W3c中,使用stopPropagation()方法;在IE下设置cancelBubble =true - 阻止捕获:阻止事件的默认行为,例如
click - a后的跳转。在W3c中,使用preventDefault()方法,在 IE 下设置window.event.returnValue = false
new操作符具体干了什么呢?
- 创建一个空对象,并且
this变量引用该对象,同时还继承了该函数的原型 - 属性和方法被加入到
this引用的对象中 - 新创建的对象由
this所引用,并且最后隐式的返回this
Ajax原理
-
Ajax的原理简单来说是在用户和服务器之间加了—个中间层( AJAX 引擎),通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。使用户操作与服务器响应异步化。这其中最关键的一步就是从服务器获得请求数据 -
Ajax的过程只涉及JavaScript 、 XMLHttpRequest 和 DOM 。 XMLHttpRequest是ajax的核心机制
如何解决跨域问题?
- 通过
jsonp跨域
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://www.....:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
复制代码
-
document.domain + iframe跨域
//父窗口:(http://www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user = 'admin';
</script>
//子窗口:(http://child.domain.com/b.html)
document.domain = 'domain.com';
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user);
复制代码
-
nginx代理跨域 -
nodejs中间件代理跨域 - 后端在头部信息里面设置安全域名
说说你对AMD和Commonjs的理解
-
CommonJS是服务器端模块的规范,Node.js采用了这个规范。CommonJS规范加载模
块是同步的,也就是说,只有加载完成,才能执行后面的操作。 AMD 规范则是非同步加载 模块,允许指定回调函数
-
AMD推荐的风格通过返回一个对象做为模块对象,CommonJS的风格通过对
module.exports 或 exports 的属性赋值来达到暴露模块对象的目的
js的7种基本数据类型
Undefined 、 Null 、Boolean 、Number 、String 、Bigint 、Symbol 了解更多加入我们前端学习圈
介绍js有哪些内置对象
-
Object是JavaScript中所有对象的父对象 - 数据封装类对象:
Object 、 Array 、 Boolean 、 Number 和 String - 其他对象:
Function 、 Arguments 、 Math 、 Date 、 RegExp 、 Error
JS有哪些方法定义对象
- 对象字面量:
var obj = {}; - 构造函数:
var obj = new Object(); - Object.create():
var obj = Object.create(Object.prototype);
你觉得jQuery源码有哪些写的好的地方
-
jquery源码封装在一个匿名函数的自执行环境中,有助于防止变量的全局污染,然后通过传入window对象参数,可以使window对象作为局部变量使用,好处是当jquery中访问window对象的时候,就不用将作用域链退回到顶层作用域了,从而可以更快的访问window对象。同样,传入undefined参数,可以缩短查找undefined时的作用域链 -
jquery将一些原型属性和方法封装在了jquery.prototype中,为了缩短名称,又赋值给了jquery.fn,这是很形象的写法 - 有一些数组或对象的方法经常能使用到,
jQuery将其保存为局部变量以提高访问速度 -
jquery实现的链式调用可以节约代码,所返回的都是同一个对象,可以提高代码效率
null,undefined 的区别
-
undefined表示不存在这个值。 -
undefined:是一个表示"无"的原始值或者说表示"缺少值",就是此处应该有一个值,但是还没有定义。尝试读取时会返回undefined - 例如变量被声明了,但没有赋值时,就等于
undefined -
null表示一个对象被定义了,值为“空值” -
null: 是一个对象(空对象, 没有任何属性和方法) - 例如作为函数的参数,表示该函数的参数不是对象;
- 在验证
null时,一定要使用 === ,因为 == 无法分别null 和 undefined
谈谈你对ES6的理解
- 新增模板字符串(为
JavaScript提供了简单的字符串插值功能) - 箭头函数
-
for-of(用来遍历数据—例如数组中的值。) -
arguments对象可被不定参数和默认参数完美代替。 -
ES6将promise对象纳入规范,提供了原生的Promise对象。 - 增加了
let 和 const命令,用来声明变量。 - 还有就是引入
module模块的概念
面向对象编程思想
- 基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
- 易维护
- 易扩展
- 开发工作的重用性、继承性高,降低重复工作量。
- 缩短了开发周期
如何通过JS判断一个数组
-
instanceof运算符是用来测试一个对象是否在其原型链原型构造函数的属性
var arr = [];
arr instanceof Array; // true
复制代码
isArray
Array.isArray([]) //true
Array.isArray(1) //false
复制代码
-
constructor属性返回对创建此对象的数组函数的引用,就是返回对象相对应的构造函数
var arr = [];
arr.constructor == Array; //true
复制代码
Object.prototype
Object.prototype.toString.call([]) == '[object Array]'
// 写个方法
var isType = function (obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
//return Object.prototype.toString.apply([obj]).slice(8,-1);
}
isType([]) //Array
复制代码
异步编程的实现方式
- 回调函数
- 优点:简单、容易理解
- 缺点:不利于维护,代码耦合高
- 事件监听(采用时间驱动模式,取决于某个事件是否发生)
- 优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
- 缺点:事件驱动型,流程不够清晰
- 发布/订阅(观察者模式)
- 类似于事件监听,但是可以通过‘消息中心‘,了解现在有多少发布者,多少订阅者
-
Promise对象- 优点:可以利用
then方法,进行链式写法;可以书写错误时的回调函数; - 缺点:编写和理解,相对比较难
- 优点:可以利用
-
Generator函数- 优点:函数体内外的数据交换、错误处理机制
- 缺点:流程管理不方便
-
async函数- 优点:内置执行器、更好的语义、更广的适用性、返回的是
Promise、结构清晰。 - 缺点:错误处理机制
- 优点:内置执行器、更好的语义、更广的适用性、返回的是
对原生Javascript了解方向
数据类型、运算、对象、Function、继承、闭包、作用域、原型链、事件、 RegExp 、JSON 、 Ajax 、 DOM 、 BOM 、内存泄漏、跨域、异步装载、模板引擎、前端MVC 、路由、模块化、 Canvas 、 ECMAScript
sort 快速打乱数组
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(()=> Math.random() - 0.5)
//利用sort return 大于等于0不交换位置,小于0交换位置
// [5, 8, 4, 3, 2, 9, 10, 6, 1, 7]
复制代码
数组去重操作
ES6 Set-
for循环indexOf -
for循环includes sort
JS 原生拖拽节点
- 给需要拖拽的节点绑定
mousedown , mousemove , mouseup事件 -
mousedown事件触发后,开始拖拽 -
mousemove时,需要通过event.clientX 和 clientY获取拖拽位置,并实时更新位置 -
mouseup时,拖拽结束 - 需要注意浏览器边界值,设置拖拽范围
深拷贝、浅拷贝
- 所有的基础数据类型的赋值操作都是深拷贝
- 通常利用上面这点,来对引用数据类型做递归深拷贝
- 浅拷贝:
Object.assign或者 扩展运算符 - 深拷贝:
JSON.parse(JSON.stringify(object))深层递归- 局限性:会忽略 undefined,不能序列化函数,不能解决循环引用的对象
节流防抖
- 节流:每隔一段时间执行一次,通常用在高频率触发的地方,降低频率。--如:鼠标滑动 拖拽
- 防抖:一段时间内连续触发,不执行,直到超出限定时间执行最后一次。--如:
input模糊搜索
变量提升
js b() // call b console.log(a) // undefined var a = 'Hello world' function b() { console.log('call b') }
b() // call b second
function b() {
console.log('call b fist')
}
function b() {
console.log('call b second')
}
var b = 'Hello world'
复制代码
js单线程
- 单线程 - 只有一个线程,只能做一件事
- 原因 - 避免
DOM渲染的冲突- 浏览器需要渲染
DOM -
JS可以修改DOM结构 -
JS执行的时候,浏览器DOM渲染会暂停 - 两段
JS也不能同时执行(都修改DOM就冲突了) -
webworker支持多线程,但是不能访问DOM
- 浏览器需要渲染
- 解决方案 - 异步
说说event loop
描述下this
ajax、axios、fetch区别
ajax:
- 本身是针对
MVC的编程,不符合现在前端MVVM的浪潮 - 基于原生的
XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案 -
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
axios:
- 从浏览器中创建
XMLHttpRequest - 从
node.js发出http请求 - 支持
Promise API - 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换
JSON数据 - 客户端支持防止
CSRF/XSRF
fetch:
- 只对网络请求报错,对 400 , 500 都当做成功的请求,需要封装去处理
- 这里对于
cookie的处理比较特殊,不同浏览器对credentials的默认值不一样,也就使得默认情况下cookie变的不可控。详细前往MDN - 本身无自带
abort,无法超时控制,可以使用AbortController解决取消请求问题。
- 没有办法原生监测请求的进度,而
XHR可以
优化 篇
SEO优化
- 合理的
title 、 description 、 keywords:搜索对着三项的权重逐个减小,title值强调重点即可,重要关键词出现不要超过2次,而且要靠前,不同页面title要有所不同;description把页面内容高度概括,长度合适,不可过分堆砌关键词,不同页面description有所不同;keywords列举出重要关键词即可 - 语义化的
HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页 - 重要内容
HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容一定会被抓取 - 重要内容不要用
js输出:爬虫不会执行js获取内容 - 少用
iframe:搜索引擎不会抓取iframe中的内容 - 非装饰性图片必须加
alt - 提高网站速度:网站速度是搜索引擎排序的一个重要指标
server优化
- 减少
HTTP请求,合并文件、雪碧图 - 减少
DNS查询,使用缓存 - 减少
Dom元素的数量 - 使用
CDN - 配置
ETag,http缓存的手段 - 对组件使用
Gzip压缩 - 减少
cookie的大小
css优化
- 将样式表放在页面顶部
- 使用
less scss表达式 - 使用
link不适用@import引入样式 - 压缩
css - 禁止使用
gif图片实现loading效果(降低 CPU 消耗,提升渲染性能) - 使用
CSS3代码代替JS动画(尽可能避免重绘重排以及回流) - 对于一些小图标,可以使用
base64位编码,以减少网络请求。 - 页面头部的
<style> <script>会阻塞页面;(因为 Renderer进程中 JS 线程和渲染线程是互斥的) - 当需要设置的样式很多时设置
className而不是直接操作style
js方面
- 将脚本放到页面底部
- 将
js外部引入 - 压缩
js - 使用
Eslint语法检测 - 减少
Dom的操作 - 熟练使用设计模式
- 禁止使用
iframe(阻塞父文档onload事件) - 页面中空的
href 和 src会阻塞页面其他资源的加载 - 网页
gzip , CDN托管,data缓存 ,图片服务器
webpack优化点
- 代码压缩插件
UglifyJsPlugin - 服务器启用
gzip压缩 - 按需加载资源文件
require.ensure - 优化
devtool中的source-map - 剥离
css文件,单独打包 - 去除不必要插件,通常就是开发环境与生产环境用同一套配置文件导致
- 开发环境不做无意义的工作如提取
css计算文件hash等 - 配置
devtool - 优化构建时的搜索路径 指明需要构建目录及不需要构建目录
其他优化点
为什么利用多个域名来存储网站资源会更有效?
-
CDN缓存更方便 - 突破浏览器并发限制
- 节约
cookie带宽 - 节约主域名的连接数,优化页面响应速度
- 防止不必要的安全问题
Other 篇
从用户刷新网页开始,一次js请求一般情况下有哪些地方会有缓存处理?
-
dns缓存 -
cdn缓存 - 浏览器缓存
- 服务器缓存
常见web安全及防护原理
-
sql注入原理:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令- 永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双 "-" 进行转换等
- 永远不要使用动态拼装SQL,可以使用参数化的 SQL 或者直接使用存储过程进行数据查询存取
- 永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接
- 不要把机密信息明文存放,请加密或者 hash 掉密码和敏感的信息
-
XSS防范方法:Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点- 首先代码里对用户输入的地方和变量都需要仔细检查长度和对 ”<”,”>”,”;”,”’” 等字符做过滤;其次任何内容写到页面之前都必须加以
encode,避免不小心把html tag弄出来。这一个层面做好,至少可以堵住超过一半的XSS攻击
- 首先代码里对用户输入的地方和变量都需要仔细检查长度和对 ”<”,”>”,”;”,”’” 等字符做过滤;其次任何内容写到页面之前都必须加以
-
XSS与CSRF有什么区别:XSS是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次CSRF攻击,受害者必须依次完成两个步骤,1.登录受信任网站 A ,并在本地生成Cookie。2.在不登出 A 的情况下,访问危险网站 B- 服务端的
CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数 - 通过验证码的方法
- 服务端的
用过哪些设计模式
- 单例模式
- 策略模式
- 代理模式
- 迭代器模式
- 发布—订阅模式
更多设计模式15种了解更多加入我们前端学习圈
Node的应用场景
- 特点
- 它是一个
javascript运行环境 - 依赖于
chrome V8引擎进行代码解释 - 事件驱动
- 非阻塞 I/o
- 单进程,单线程
- 它是一个
- 优点
- 对于文件的读写处理效率极高
- 高并发(
node最重要的优点)
- 缺点
- 只支持单核
CPU,不能充分利用CPU - 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃
- 只支持单核
那些操作会造成内存泄漏?
- 内存泄漏指任何对象在您不再拥有或需要它之后仍然存在
-
setTimeout的第一个参数使用字符串而非函数的话,会引发内存泄漏 - 闭包使用不当
简单介绍下webpack
WebPack 是一个模块打包工具,你可以使用 WebPack 管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包 Web 开发中所用到的 HTML 、 Javascript 、 CSS 以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源, webpack 有对应的模块加载器。 webpack 模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。
谈谈你对gulp的了解
-
gulp是前端开发过程中一种基于流的代码构建工具,是自动化项目的构建利器;它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成 -
gulp的核心概念:流 - 流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具。在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向
-
gulp正是通过流和代码优于配置的策略来尽量简化任务编写的工作 -
Gulp的特点:- 易于使用:通过代码优于配置的策略,
gulp让简单的任务简单,复杂的任务可管理 - 构建快速 利用
Node.js流的威力,你可以快速构建项目并减少频繁的 IO 操作 - 易于学习 通过最少的
API,掌握gulp毫不费力,构建工作尽在掌握:如同一系列流管道
- 易于使用:通过代码优于配置的策略,
渐进增强和优雅降级
- 渐进增强 :针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
- 优雅降级 :一开始就构建完整的功能,然后再针对低版本浏览器进行兼容
谈一谈你理解的函数式编程
- 简单说,"函数式编程"是一种"编程范式"
(programming paradigm),也就是如何编写程序的方法论 - 它具有以下特性:闭包和高阶函数、惰性计算、递归、函数是"第一等公民"、只用"表达式"
想了解更多,移步这里:https://zhuanlan.zhihu.com/p/57708956
Vue的双向绑定数据的原理
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty() 来劫持各个属性的 setter , getter ,在数据变动时发布消息给订阅者,触发相应的监听回调
写个简单Loader
// 定义
module.exports = function(src) {
//src是原文件内容(abcde),下面对内容进行处理,这里是反转
var result = src.split('').reverse().join('');
//返回JavaScript源码,必须是String或者Buffer
return `module.exports = '${result}'`;
}
//使用
{
test: /\.txt$/,
use: [{
'./path/reverse-txt-loader'
}]
},
复制代码
其他问题
- 自我介绍
- 面试完你还有什么问题要问的吗
- 你有什么爱好?
- 你最大的优点和缺点是什么?
- 你为什么会选择这个行业,职位?
- 你觉得你适合从事这个岗位吗?
- 你有什么职业规划?
- 你对工资有什么要求?
- 如何看待前端开发?
- 未来三到五年的规划是怎样的?
- 你的项目中技术难点是什么?遇到了什么问题?你是怎么解决的?
- 你们部门的开发流程是怎样的
- 你认为哪个项目做得最好?
- 说下工作中你做过的一些性能优化处理
- 最近在看哪些前端方面的书?
- 平时是如何学习前端开发的?
- 你最有成就感的一件事
- 你为什么要离开前一家公司?
- 你对加班的看法
- 你希望通过这份工作获得什么?










